1 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 2 3 #include <media/saa7146_vv.h> 4 #include <media/v4l2-chip-ident.h> 5 #include <media/v4l2-event.h> 6 #include <media/v4l2-ctrls.h> 7 #include <linux/module.h> 8 9 static int max_memory = 32; 10 11 module_param(max_memory, int, 0644); 12 MODULE_PARM_DESC(max_memory, "maximum memory usage for capture buffers (default: 32Mb)"); 13 14 #define IS_CAPTURE_ACTIVE(fh) \ 15 (((vv->video_status & STATUS_CAPTURE) != 0) && (vv->video_fh == fh)) 16 17 #define IS_OVERLAY_ACTIVE(fh) \ 18 (((vv->video_status & STATUS_OVERLAY) != 0) && (vv->video_fh == fh)) 19 20 /* format descriptions for capture and preview */ 21 static struct saa7146_format formats[] = { 22 { 23 .name = "RGB-8 (3-3-2)", 24 .pixelformat = V4L2_PIX_FMT_RGB332, 25 .trans = RGB08_COMPOSED, 26 .depth = 8, 27 .flags = 0, 28 }, { 29 .name = "RGB-16 (5/B-6/G-5/R)", 30 .pixelformat = V4L2_PIX_FMT_RGB565, 31 .trans = RGB16_COMPOSED, 32 .depth = 16, 33 .flags = 0, 34 }, { 35 .name = "RGB-24 (B-G-R)", 36 .pixelformat = V4L2_PIX_FMT_BGR24, 37 .trans = RGB24_COMPOSED, 38 .depth = 24, 39 .flags = 0, 40 }, { 41 .name = "RGB-32 (B-G-R)", 42 .pixelformat = V4L2_PIX_FMT_BGR32, 43 .trans = RGB32_COMPOSED, 44 .depth = 32, 45 .flags = 0, 46 }, { 47 .name = "RGB-32 (R-G-B)", 48 .pixelformat = V4L2_PIX_FMT_RGB32, 49 .trans = RGB32_COMPOSED, 50 .depth = 32, 51 .flags = 0, 52 .swap = 0x2, 53 }, { 54 .name = "Greyscale-8", 55 .pixelformat = V4L2_PIX_FMT_GREY, 56 .trans = Y8, 57 .depth = 8, 58 .flags = 0, 59 }, { 60 .name = "YUV 4:2:2 planar (Y-Cb-Cr)", 61 .pixelformat = V4L2_PIX_FMT_YUV422P, 62 .trans = YUV422_DECOMPOSED, 63 .depth = 16, 64 .flags = FORMAT_BYTE_SWAP|FORMAT_IS_PLANAR, 65 }, { 66 .name = "YVU 4:2:0 planar (Y-Cb-Cr)", 67 .pixelformat = V4L2_PIX_FMT_YVU420, 68 .trans = YUV420_DECOMPOSED, 69 .depth = 12, 70 .flags = FORMAT_BYTE_SWAP|FORMAT_IS_PLANAR, 71 }, { 72 .name = "YUV 4:2:0 planar (Y-Cb-Cr)", 73 .pixelformat = V4L2_PIX_FMT_YUV420, 74 .trans = YUV420_DECOMPOSED, 75 .depth = 12, 76 .flags = FORMAT_IS_PLANAR, 77 }, { 78 .name = "YUV 4:2:2 (U-Y-V-Y)", 79 .pixelformat = V4L2_PIX_FMT_UYVY, 80 .trans = YUV422_COMPOSED, 81 .depth = 16, 82 .flags = 0, 83 } 84 }; 85 86 /* unfortunately, the saa7146 contains a bug which prevents it from doing on-the-fly byte swaps. 87 due to this, it's impossible to provide additional *packed* formats, which are simply byte swapped 88 (like V4L2_PIX_FMT_YUYV) ... 8-( */ 89 90 static int NUM_FORMATS = sizeof(formats)/sizeof(struct saa7146_format); 91 92 struct saa7146_format* saa7146_format_by_fourcc(struct saa7146_dev *dev, int fourcc) 93 { 94 int i, j = NUM_FORMATS; 95 96 for (i = 0; i < j; i++) { 97 if (formats[i].pixelformat == fourcc) { 98 return formats+i; 99 } 100 } 101 102 DEB_D("unknown pixelformat:'%4.4s'\n", (char *)&fourcc); 103 return NULL; 104 } 105 106 static int vidioc_try_fmt_vid_overlay(struct file *file, void *fh, struct v4l2_format *f); 107 108 int saa7146_start_preview(struct saa7146_fh *fh) 109 { 110 struct saa7146_dev *dev = fh->dev; 111 struct saa7146_vv *vv = dev->vv_data; 112 struct v4l2_format fmt; 113 int ret = 0, err = 0; 114 115 DEB_EE("dev:%p, fh:%p\n", dev, fh); 116 117 /* check if we have overlay information */ 118 if (vv->ov.fh == NULL) { 119 DEB_D("no overlay data available. try S_FMT first.\n"); 120 return -EAGAIN; 121 } 122 123 /* check if streaming capture is running */ 124 if (IS_CAPTURE_ACTIVE(fh) != 0) { 125 DEB_D("streaming capture is active\n"); 126 return -EBUSY; 127 } 128 129 /* check if overlay is running */ 130 if (IS_OVERLAY_ACTIVE(fh) != 0) { 131 if (vv->video_fh == fh) { 132 DEB_D("overlay is already active\n"); 133 return 0; 134 } 135 DEB_D("overlay is already active in another open\n"); 136 return -EBUSY; 137 } 138 139 if (0 == saa7146_res_get(fh, RESOURCE_DMA1_HPS|RESOURCE_DMA2_CLP)) { 140 DEB_D("cannot get necessary overlay resources\n"); 141 return -EBUSY; 142 } 143 144 fmt.fmt.win = vv->ov.win; 145 err = vidioc_try_fmt_vid_overlay(NULL, fh, &fmt); 146 if (0 != err) { 147 saa7146_res_free(vv->video_fh, RESOURCE_DMA1_HPS|RESOURCE_DMA2_CLP); 148 return -EBUSY; 149 } 150 vv->ov.win = fmt.fmt.win; 151 152 DEB_D("%dx%d+%d+%d %s field=%s\n", 153 vv->ov.win.w.width, vv->ov.win.w.height, 154 vv->ov.win.w.left, vv->ov.win.w.top, 155 vv->ov_fmt->name, v4l2_field_names[vv->ov.win.field]); 156 157 if (0 != (ret = saa7146_enable_overlay(fh))) { 158 DEB_D("enabling overlay failed: %d\n", ret); 159 saa7146_res_free(vv->video_fh, RESOURCE_DMA1_HPS|RESOURCE_DMA2_CLP); 160 return ret; 161 } 162 163 vv->video_status = STATUS_OVERLAY; 164 vv->video_fh = fh; 165 166 return 0; 167 } 168 EXPORT_SYMBOL_GPL(saa7146_start_preview); 169 170 int saa7146_stop_preview(struct saa7146_fh *fh) 171 { 172 struct saa7146_dev *dev = fh->dev; 173 struct saa7146_vv *vv = dev->vv_data; 174 175 DEB_EE("dev:%p, fh:%p\n", dev, fh); 176 177 /* check if streaming capture is running */ 178 if (IS_CAPTURE_ACTIVE(fh) != 0) { 179 DEB_D("streaming capture is active\n"); 180 return -EBUSY; 181 } 182 183 /* check if overlay is running at all */ 184 if ((vv->video_status & STATUS_OVERLAY) == 0) { 185 DEB_D("no active overlay\n"); 186 return 0; 187 } 188 189 if (vv->video_fh != fh) { 190 DEB_D("overlay is active, but in another open\n"); 191 return -EBUSY; 192 } 193 194 vv->video_status = 0; 195 vv->video_fh = NULL; 196 197 saa7146_disable_overlay(fh); 198 199 saa7146_res_free(fh, RESOURCE_DMA1_HPS|RESOURCE_DMA2_CLP); 200 201 return 0; 202 } 203 EXPORT_SYMBOL_GPL(saa7146_stop_preview); 204 205 /********************************************************************************/ 206 /* common pagetable functions */ 207 208 static int saa7146_pgtable_build(struct saa7146_dev *dev, struct saa7146_buf *buf) 209 { 210 struct pci_dev *pci = dev->pci; 211 struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb); 212 struct scatterlist *list = dma->sglist; 213 int length = dma->sglen; 214 struct saa7146_format *sfmt = saa7146_format_by_fourcc(dev,buf->fmt->pixelformat); 215 216 DEB_EE("dev:%p, buf:%p, sg_len:%d\n", dev, buf, length); 217 218 if( 0 != IS_PLANAR(sfmt->trans)) { 219 struct saa7146_pgtable *pt1 = &buf->pt[0]; 220 struct saa7146_pgtable *pt2 = &buf->pt[1]; 221 struct saa7146_pgtable *pt3 = &buf->pt[2]; 222 __le32 *ptr1, *ptr2, *ptr3; 223 __le32 fill; 224 225 int size = buf->fmt->width*buf->fmt->height; 226 int i,p,m1,m2,m3,o1,o2; 227 228 switch( sfmt->depth ) { 229 case 12: { 230 /* create some offsets inside the page table */ 231 m1 = ((size+PAGE_SIZE)/PAGE_SIZE)-1; 232 m2 = ((size+(size/4)+PAGE_SIZE)/PAGE_SIZE)-1; 233 m3 = ((size+(size/2)+PAGE_SIZE)/PAGE_SIZE)-1; 234 o1 = size%PAGE_SIZE; 235 o2 = (size+(size/4))%PAGE_SIZE; 236 DEB_CAP("size:%d, m1:%d, m2:%d, m3:%d, o1:%d, o2:%d\n", 237 size, m1, m2, m3, o1, o2); 238 break; 239 } 240 case 16: { 241 /* create some offsets inside the page table */ 242 m1 = ((size+PAGE_SIZE)/PAGE_SIZE)-1; 243 m2 = ((size+(size/2)+PAGE_SIZE)/PAGE_SIZE)-1; 244 m3 = ((2*size+PAGE_SIZE)/PAGE_SIZE)-1; 245 o1 = size%PAGE_SIZE; 246 o2 = (size+(size/2))%PAGE_SIZE; 247 DEB_CAP("size:%d, m1:%d, m2:%d, m3:%d, o1:%d, o2:%d\n", 248 size, m1, m2, m3, o1, o2); 249 break; 250 } 251 default: { 252 return -1; 253 } 254 } 255 256 ptr1 = pt1->cpu; 257 ptr2 = pt2->cpu; 258 ptr3 = pt3->cpu; 259 260 /* walk all pages, copy all page addresses to ptr1 */ 261 for (i = 0; i < length; i++, list++) { 262 for (p = 0; p * 4096 < list->length; p++, ptr1++) { 263 *ptr1 = cpu_to_le32(sg_dma_address(list) - list->offset); 264 } 265 } 266 /* 267 ptr1 = pt1->cpu; 268 for(j=0;j<40;j++) { 269 printk("ptr1 %d: 0x%08x\n",j,ptr1[j]); 270 } 271 */ 272 273 /* if we have a user buffer, the first page may not be 274 aligned to a page boundary. */ 275 pt1->offset = dma->sglist->offset; 276 pt2->offset = pt1->offset+o1; 277 pt3->offset = pt1->offset+o2; 278 279 /* create video-dma2 page table */ 280 ptr1 = pt1->cpu; 281 for(i = m1; i <= m2 ; i++, ptr2++) { 282 *ptr2 = ptr1[i]; 283 } 284 fill = *(ptr2-1); 285 for(;i<1024;i++,ptr2++) { 286 *ptr2 = fill; 287 } 288 /* create video-dma3 page table */ 289 ptr1 = pt1->cpu; 290 for(i = m2; i <= m3; i++,ptr3++) { 291 *ptr3 = ptr1[i]; 292 } 293 fill = *(ptr3-1); 294 for(;i<1024;i++,ptr3++) { 295 *ptr3 = fill; 296 } 297 /* finally: finish up video-dma1 page table */ 298 ptr1 = pt1->cpu+m1; 299 fill = pt1->cpu[m1]; 300 for(i=m1;i<1024;i++,ptr1++) { 301 *ptr1 = fill; 302 } 303 /* 304 ptr1 = pt1->cpu; 305 ptr2 = pt2->cpu; 306 ptr3 = pt3->cpu; 307 for(j=0;j<40;j++) { 308 printk("ptr1 %d: 0x%08x\n",j,ptr1[j]); 309 } 310 for(j=0;j<40;j++) { 311 printk("ptr2 %d: 0x%08x\n",j,ptr2[j]); 312 } 313 for(j=0;j<40;j++) { 314 printk("ptr3 %d: 0x%08x\n",j,ptr3[j]); 315 } 316 */ 317 } else { 318 struct saa7146_pgtable *pt = &buf->pt[0]; 319 return saa7146_pgtable_build_single(pci, pt, list, length); 320 } 321 322 return 0; 323 } 324 325 326 /********************************************************************************/ 327 /* file operations */ 328 329 static int video_begin(struct saa7146_fh *fh) 330 { 331 struct saa7146_dev *dev = fh->dev; 332 struct saa7146_vv *vv = dev->vv_data; 333 struct saa7146_format *fmt = NULL; 334 unsigned int resource; 335 int ret = 0, err = 0; 336 337 DEB_EE("dev:%p, fh:%p\n", dev, fh); 338 339 if ((vv->video_status & STATUS_CAPTURE) != 0) { 340 if (vv->video_fh == fh) { 341 DEB_S("already capturing\n"); 342 return 0; 343 } 344 DEB_S("already capturing in another open\n"); 345 return -EBUSY; 346 } 347 348 if ((vv->video_status & STATUS_OVERLAY) != 0) { 349 DEB_S("warning: suspending overlay video for streaming capture\n"); 350 vv->ov_suspend = vv->video_fh; 351 err = saa7146_stop_preview(vv->video_fh); /* side effect: video_status is now 0, video_fh is NULL */ 352 if (0 != err) { 353 DEB_D("suspending video failed. aborting\n"); 354 return err; 355 } 356 } 357 358 fmt = saa7146_format_by_fourcc(dev, vv->video_fmt.pixelformat); 359 /* we need to have a valid format set here */ 360 BUG_ON(NULL == fmt); 361 362 if (0 != (fmt->flags & FORMAT_IS_PLANAR)) { 363 resource = RESOURCE_DMA1_HPS|RESOURCE_DMA2_CLP|RESOURCE_DMA3_BRS; 364 } else { 365 resource = RESOURCE_DMA1_HPS; 366 } 367 368 ret = saa7146_res_get(fh, resource); 369 if (0 == ret) { 370 DEB_S("cannot get capture resource %d\n", resource); 371 if (vv->ov_suspend != NULL) { 372 saa7146_start_preview(vv->ov_suspend); 373 vv->ov_suspend = NULL; 374 } 375 return -EBUSY; 376 } 377 378 /* clear out beginning of streaming bit (rps register 0)*/ 379 saa7146_write(dev, MC2, MASK_27 ); 380 381 /* enable rps0 irqs */ 382 SAA7146_IER_ENABLE(dev, MASK_27); 383 384 vv->video_fh = fh; 385 vv->video_status = STATUS_CAPTURE; 386 387 return 0; 388 } 389 390 static int video_end(struct saa7146_fh *fh, struct file *file) 391 { 392 struct saa7146_dev *dev = fh->dev; 393 struct saa7146_vv *vv = dev->vv_data; 394 struct saa7146_format *fmt = NULL; 395 unsigned long flags; 396 unsigned int resource; 397 u32 dmas = 0; 398 DEB_EE("dev:%p, fh:%p\n", dev, fh); 399 400 if ((vv->video_status & STATUS_CAPTURE) != STATUS_CAPTURE) { 401 DEB_S("not capturing\n"); 402 return 0; 403 } 404 405 if (vv->video_fh != fh) { 406 DEB_S("capturing, but in another open\n"); 407 return -EBUSY; 408 } 409 410 fmt = saa7146_format_by_fourcc(dev, vv->video_fmt.pixelformat); 411 /* we need to have a valid format set here */ 412 BUG_ON(NULL == fmt); 413 414 if (0 != (fmt->flags & FORMAT_IS_PLANAR)) { 415 resource = RESOURCE_DMA1_HPS|RESOURCE_DMA2_CLP|RESOURCE_DMA3_BRS; 416 dmas = MASK_22 | MASK_21 | MASK_20; 417 } else { 418 resource = RESOURCE_DMA1_HPS; 419 dmas = MASK_22; 420 } 421 spin_lock_irqsave(&dev->slock,flags); 422 423 /* disable rps0 */ 424 saa7146_write(dev, MC1, MASK_28); 425 426 /* disable rps0 irqs */ 427 SAA7146_IER_DISABLE(dev, MASK_27); 428 429 /* shut down all used video dma transfers */ 430 saa7146_write(dev, MC1, dmas); 431 432 spin_unlock_irqrestore(&dev->slock, flags); 433 434 vv->video_fh = NULL; 435 vv->video_status = 0; 436 437 saa7146_res_free(fh, resource); 438 439 if (vv->ov_suspend != NULL) { 440 saa7146_start_preview(vv->ov_suspend); 441 vv->ov_suspend = NULL; 442 } 443 444 return 0; 445 } 446 447 static int vidioc_querycap(struct file *file, void *fh, struct v4l2_capability *cap) 448 { 449 struct video_device *vdev = video_devdata(file); 450 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; 451 452 strcpy((char *)cap->driver, "saa7146 v4l2"); 453 strlcpy((char *)cap->card, dev->ext->name, sizeof(cap->card)); 454 sprintf((char *)cap->bus_info, "PCI:%s", pci_name(dev->pci)); 455 cap->device_caps = 456 V4L2_CAP_VIDEO_CAPTURE | 457 V4L2_CAP_VIDEO_OVERLAY | 458 V4L2_CAP_READWRITE | 459 V4L2_CAP_STREAMING; 460 cap->device_caps |= dev->ext_vv_data->capabilities; 461 cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; 462 if (vdev->vfl_type == VFL_TYPE_GRABBER) 463 cap->device_caps &= 464 ~(V4L2_CAP_VBI_CAPTURE | V4L2_CAP_SLICED_VBI_OUTPUT); 465 else 466 cap->device_caps &= 467 ~(V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OVERLAY | V4L2_CAP_AUDIO); 468 return 0; 469 } 470 471 static int vidioc_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb) 472 { 473 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; 474 struct saa7146_vv *vv = dev->vv_data; 475 476 *fb = vv->ov_fb; 477 fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING; 478 fb->flags = V4L2_FBUF_FLAG_PRIMARY; 479 return 0; 480 } 481 482 static int vidioc_s_fbuf(struct file *file, void *fh, const struct v4l2_framebuffer *fb) 483 { 484 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; 485 struct saa7146_vv *vv = dev->vv_data; 486 struct saa7146_format *fmt; 487 488 DEB_EE("VIDIOC_S_FBUF\n"); 489 490 if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RAWIO)) 491 return -EPERM; 492 493 /* check args */ 494 fmt = saa7146_format_by_fourcc(dev, fb->fmt.pixelformat); 495 if (NULL == fmt) 496 return -EINVAL; 497 498 /* planar formats are not allowed for overlay video, clipping and video dma would clash */ 499 if (fmt->flags & FORMAT_IS_PLANAR) 500 DEB_S("planar pixelformat '%4.4s' not allowed for overlay\n", 501 (char *)&fmt->pixelformat); 502 503 /* check if overlay is running */ 504 if (IS_OVERLAY_ACTIVE(fh) != 0) { 505 if (vv->video_fh != fh) { 506 DEB_D("refusing to change framebuffer informations while overlay is active in another open\n"); 507 return -EBUSY; 508 } 509 } 510 511 /* ok, accept it */ 512 vv->ov_fb = *fb; 513 vv->ov_fmt = fmt; 514 515 if (vv->ov_fb.fmt.bytesperline < vv->ov_fb.fmt.width) { 516 vv->ov_fb.fmt.bytesperline = vv->ov_fb.fmt.width * fmt->depth / 8; 517 DEB_D("setting bytesperline to %d\n", vv->ov_fb.fmt.bytesperline); 518 } 519 return 0; 520 } 521 522 static int vidioc_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *f) 523 { 524 if (f->index >= NUM_FORMATS) 525 return -EINVAL; 526 strlcpy((char *)f->description, formats[f->index].name, 527 sizeof(f->description)); 528 f->pixelformat = formats[f->index].pixelformat; 529 return 0; 530 } 531 532 int saa7146_s_ctrl(struct v4l2_ctrl *ctrl) 533 { 534 struct saa7146_dev *dev = container_of(ctrl->handler, 535 struct saa7146_dev, ctrl_handler); 536 struct saa7146_vv *vv = dev->vv_data; 537 u32 val; 538 539 switch (ctrl->id) { 540 case V4L2_CID_BRIGHTNESS: 541 val = saa7146_read(dev, BCS_CTRL); 542 val &= 0x00ffffff; 543 val |= (ctrl->val << 24); 544 saa7146_write(dev, BCS_CTRL, val); 545 saa7146_write(dev, MC2, MASK_22 | MASK_06); 546 break; 547 548 case V4L2_CID_CONTRAST: 549 val = saa7146_read(dev, BCS_CTRL); 550 val &= 0xff00ffff; 551 val |= (ctrl->val << 16); 552 saa7146_write(dev, BCS_CTRL, val); 553 saa7146_write(dev, MC2, MASK_22 | MASK_06); 554 break; 555 556 case V4L2_CID_SATURATION: 557 val = saa7146_read(dev, BCS_CTRL); 558 val &= 0xffffff00; 559 val |= (ctrl->val << 0); 560 saa7146_write(dev, BCS_CTRL, val); 561 saa7146_write(dev, MC2, MASK_22 | MASK_06); 562 break; 563 564 case V4L2_CID_HFLIP: 565 /* fixme: we can support changing VFLIP and HFLIP here... */ 566 if ((vv->video_status & STATUS_CAPTURE)) 567 return -EBUSY; 568 vv->hflip = ctrl->val; 569 break; 570 571 case V4L2_CID_VFLIP: 572 if ((vv->video_status & STATUS_CAPTURE)) 573 return -EBUSY; 574 vv->vflip = ctrl->val; 575 break; 576 577 default: 578 return -EINVAL; 579 } 580 581 if ((vv->video_status & STATUS_OVERLAY) != 0) { /* CHECK: && (vv->video_fh == fh)) */ 582 struct saa7146_fh *fh = vv->video_fh; 583 584 saa7146_stop_preview(fh); 585 saa7146_start_preview(fh); 586 } 587 return 0; 588 } 589 590 static int vidioc_g_parm(struct file *file, void *fh, 591 struct v4l2_streamparm *parm) 592 { 593 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; 594 struct saa7146_vv *vv = dev->vv_data; 595 596 if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 597 return -EINVAL; 598 parm->parm.capture.readbuffers = 1; 599 v4l2_video_std_frame_period(vv->standard->id, 600 &parm->parm.capture.timeperframe); 601 return 0; 602 } 603 604 static int vidioc_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f) 605 { 606 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; 607 struct saa7146_vv *vv = dev->vv_data; 608 609 f->fmt.pix = vv->video_fmt; 610 return 0; 611 } 612 613 static int vidioc_g_fmt_vid_overlay(struct file *file, void *fh, struct v4l2_format *f) 614 { 615 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; 616 struct saa7146_vv *vv = dev->vv_data; 617 618 f->fmt.win = vv->ov.win; 619 return 0; 620 } 621 622 static int vidioc_g_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *f) 623 { 624 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; 625 struct saa7146_vv *vv = dev->vv_data; 626 627 f->fmt.vbi = vv->vbi_fmt; 628 return 0; 629 } 630 631 static int vidioc_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f) 632 { 633 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; 634 struct saa7146_vv *vv = dev->vv_data; 635 struct saa7146_format *fmt; 636 enum v4l2_field field; 637 int maxw, maxh; 638 int calc_bpl; 639 640 DEB_EE("V4L2_BUF_TYPE_VIDEO_CAPTURE: dev:%p, fh:%p\n", dev, fh); 641 642 fmt = saa7146_format_by_fourcc(dev, f->fmt.pix.pixelformat); 643 if (NULL == fmt) 644 return -EINVAL; 645 646 field = f->fmt.pix.field; 647 maxw = vv->standard->h_max_out; 648 maxh = vv->standard->v_max_out; 649 650 if (V4L2_FIELD_ANY == field) { 651 field = (f->fmt.pix.height > maxh / 2) 652 ? V4L2_FIELD_INTERLACED 653 : V4L2_FIELD_BOTTOM; 654 } 655 switch (field) { 656 case V4L2_FIELD_ALTERNATE: 657 vv->last_field = V4L2_FIELD_TOP; 658 maxh = maxh / 2; 659 break; 660 case V4L2_FIELD_TOP: 661 case V4L2_FIELD_BOTTOM: 662 vv->last_field = V4L2_FIELD_INTERLACED; 663 maxh = maxh / 2; 664 break; 665 case V4L2_FIELD_INTERLACED: 666 vv->last_field = V4L2_FIELD_INTERLACED; 667 break; 668 default: 669 DEB_D("no known field mode '%d'\n", field); 670 return -EINVAL; 671 } 672 673 f->fmt.pix.field = field; 674 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; 675 if (f->fmt.pix.width > maxw) 676 f->fmt.pix.width = maxw; 677 if (f->fmt.pix.height > maxh) 678 f->fmt.pix.height = maxh; 679 680 calc_bpl = (f->fmt.pix.width * fmt->depth) / 8; 681 682 if (f->fmt.pix.bytesperline < calc_bpl) 683 f->fmt.pix.bytesperline = calc_bpl; 684 685 if (f->fmt.pix.bytesperline > (2 * PAGE_SIZE * fmt->depth) / 8) /* arbitrary constraint */ 686 f->fmt.pix.bytesperline = calc_bpl; 687 688 f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * f->fmt.pix.height; 689 DEB_D("w:%d, h:%d, bytesperline:%d, sizeimage:%d\n", 690 f->fmt.pix.width, f->fmt.pix.height, 691 f->fmt.pix.bytesperline, f->fmt.pix.sizeimage); 692 693 return 0; 694 } 695 696 697 static int vidioc_try_fmt_vid_overlay(struct file *file, void *fh, struct v4l2_format *f) 698 { 699 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; 700 struct saa7146_vv *vv = dev->vv_data; 701 struct v4l2_window *win = &f->fmt.win; 702 enum v4l2_field field; 703 int maxw, maxh; 704 705 DEB_EE("dev:%p\n", dev); 706 707 if (NULL == vv->ov_fb.base) { 708 DEB_D("no fb base set\n"); 709 return -EINVAL; 710 } 711 if (NULL == vv->ov_fmt) { 712 DEB_D("no fb fmt set\n"); 713 return -EINVAL; 714 } 715 if (win->w.width < 48 || win->w.height < 32) { 716 DEB_D("min width/height. (%d,%d)\n", 717 win->w.width, win->w.height); 718 return -EINVAL; 719 } 720 if (win->clipcount > 16) { 721 DEB_D("clipcount too big\n"); 722 return -EINVAL; 723 } 724 725 field = win->field; 726 maxw = vv->standard->h_max_out; 727 maxh = vv->standard->v_max_out; 728 729 if (V4L2_FIELD_ANY == field) { 730 field = (win->w.height > maxh / 2) 731 ? V4L2_FIELD_INTERLACED 732 : V4L2_FIELD_TOP; 733 } 734 switch (field) { 735 case V4L2_FIELD_TOP: 736 case V4L2_FIELD_BOTTOM: 737 case V4L2_FIELD_ALTERNATE: 738 maxh = maxh / 2; 739 break; 740 case V4L2_FIELD_INTERLACED: 741 break; 742 default: 743 DEB_D("no known field mode '%d'\n", field); 744 return -EINVAL; 745 } 746 747 win->field = field; 748 if (win->w.width > maxw) 749 win->w.width = maxw; 750 if (win->w.height > maxh) 751 win->w.height = maxh; 752 753 return 0; 754 } 755 756 static int vidioc_s_fmt_vid_cap(struct file *file, void *__fh, struct v4l2_format *f) 757 { 758 struct saa7146_fh *fh = __fh; 759 struct saa7146_dev *dev = fh->dev; 760 struct saa7146_vv *vv = dev->vv_data; 761 int err; 762 763 DEB_EE("V4L2_BUF_TYPE_VIDEO_CAPTURE: dev:%p, fh:%p\n", dev, fh); 764 if (IS_CAPTURE_ACTIVE(fh) != 0) { 765 DEB_EE("streaming capture is active\n"); 766 return -EBUSY; 767 } 768 err = vidioc_try_fmt_vid_cap(file, fh, f); 769 if (0 != err) 770 return err; 771 vv->video_fmt = f->fmt.pix; 772 DEB_EE("set to pixelformat '%4.4s'\n", 773 (char *)&vv->video_fmt.pixelformat); 774 return 0; 775 } 776 777 static int vidioc_s_fmt_vid_overlay(struct file *file, void *__fh, struct v4l2_format *f) 778 { 779 struct saa7146_fh *fh = __fh; 780 struct saa7146_dev *dev = fh->dev; 781 struct saa7146_vv *vv = dev->vv_data; 782 int err; 783 784 DEB_EE("V4L2_BUF_TYPE_VIDEO_OVERLAY: dev:%p, fh:%p\n", dev, fh); 785 err = vidioc_try_fmt_vid_overlay(file, fh, f); 786 if (0 != err) 787 return err; 788 vv->ov.win = f->fmt.win; 789 vv->ov.nclips = f->fmt.win.clipcount; 790 if (vv->ov.nclips > 16) 791 vv->ov.nclips = 16; 792 if (copy_from_user(vv->ov.clips, f->fmt.win.clips, 793 sizeof(struct v4l2_clip) * vv->ov.nclips)) { 794 return -EFAULT; 795 } 796 797 /* vv->ov.fh is used to indicate that we have valid overlay informations, too */ 798 vv->ov.fh = fh; 799 800 /* check if our current overlay is active */ 801 if (IS_OVERLAY_ACTIVE(fh) != 0) { 802 saa7146_stop_preview(fh); 803 saa7146_start_preview(fh); 804 } 805 return 0; 806 } 807 808 static int vidioc_g_std(struct file *file, void *fh, v4l2_std_id *norm) 809 { 810 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; 811 struct saa7146_vv *vv = dev->vv_data; 812 813 *norm = vv->standard->id; 814 return 0; 815 } 816 817 /* the saa7146 supfhrts (used in conjunction with the saa7111a for example) 818 PAL / NTSC / SECAM. if your hardware does not (or does more) 819 -- override this function in your extension */ 820 /* 821 case VIDIOC_ENUMSTD: 822 { 823 struct v4l2_standard *e = arg; 824 if (e->index < 0 ) 825 return -EINVAL; 826 if( e->index < dev->ext_vv_data->num_stds ) { 827 DEB_EE("VIDIOC_ENUMSTD: index:%d\n", e->index); 828 v4l2_video_std_construct(e, dev->ext_vv_data->stds[e->index].id, dev->ext_vv_data->stds[e->index].name); 829 return 0; 830 } 831 return -EINVAL; 832 } 833 */ 834 835 static int vidioc_s_std(struct file *file, void *fh, v4l2_std_id *id) 836 { 837 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; 838 struct saa7146_vv *vv = dev->vv_data; 839 int found = 0; 840 int err, i; 841 842 DEB_EE("VIDIOC_S_STD\n"); 843 844 if ((vv->video_status & STATUS_CAPTURE) == STATUS_CAPTURE) { 845 DEB_D("cannot change video standard while streaming capture is active\n"); 846 return -EBUSY; 847 } 848 849 if ((vv->video_status & STATUS_OVERLAY) != 0) { 850 vv->ov_suspend = vv->video_fh; 851 err = saa7146_stop_preview(vv->video_fh); /* side effect: video_status is now 0, video_fh is NULL */ 852 if (0 != err) { 853 DEB_D("suspending video failed. aborting\n"); 854 return err; 855 } 856 } 857 858 for (i = 0; i < dev->ext_vv_data->num_stds; i++) 859 if (*id & dev->ext_vv_data->stds[i].id) 860 break; 861 if (i != dev->ext_vv_data->num_stds) { 862 vv->standard = &dev->ext_vv_data->stds[i]; 863 if (NULL != dev->ext_vv_data->std_callback) 864 dev->ext_vv_data->std_callback(dev, vv->standard); 865 found = 1; 866 } 867 868 if (vv->ov_suspend != NULL) { 869 saa7146_start_preview(vv->ov_suspend); 870 vv->ov_suspend = NULL; 871 } 872 873 if (!found) { 874 DEB_EE("VIDIOC_S_STD: standard not found\n"); 875 return -EINVAL; 876 } 877 878 DEB_EE("VIDIOC_S_STD: set to standard to '%s'\n", vv->standard->name); 879 return 0; 880 } 881 882 static int vidioc_overlay(struct file *file, void *fh, unsigned int on) 883 { 884 int err; 885 886 DEB_D("VIDIOC_OVERLAY on:%d\n", on); 887 if (on) 888 err = saa7146_start_preview(fh); 889 else 890 err = saa7146_stop_preview(fh); 891 return err; 892 } 893 894 static int vidioc_reqbufs(struct file *file, void *__fh, struct v4l2_requestbuffers *b) 895 { 896 struct saa7146_fh *fh = __fh; 897 898 if (b->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) 899 return videobuf_reqbufs(&fh->video_q, b); 900 if (b->type == V4L2_BUF_TYPE_VBI_CAPTURE) 901 return videobuf_reqbufs(&fh->vbi_q, b); 902 return -EINVAL; 903 } 904 905 static int vidioc_querybuf(struct file *file, void *__fh, struct v4l2_buffer *buf) 906 { 907 struct saa7146_fh *fh = __fh; 908 909 if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) 910 return videobuf_querybuf(&fh->video_q, buf); 911 if (buf->type == V4L2_BUF_TYPE_VBI_CAPTURE) 912 return videobuf_querybuf(&fh->vbi_q, buf); 913 return -EINVAL; 914 } 915 916 static int vidioc_qbuf(struct file *file, void *__fh, struct v4l2_buffer *buf) 917 { 918 struct saa7146_fh *fh = __fh; 919 920 if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) 921 return videobuf_qbuf(&fh->video_q, buf); 922 if (buf->type == V4L2_BUF_TYPE_VBI_CAPTURE) 923 return videobuf_qbuf(&fh->vbi_q, buf); 924 return -EINVAL; 925 } 926 927 static int vidioc_dqbuf(struct file *file, void *__fh, struct v4l2_buffer *buf) 928 { 929 struct saa7146_fh *fh = __fh; 930 931 if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) 932 return videobuf_dqbuf(&fh->video_q, buf, file->f_flags & O_NONBLOCK); 933 if (buf->type == V4L2_BUF_TYPE_VBI_CAPTURE) 934 return videobuf_dqbuf(&fh->vbi_q, buf, file->f_flags & O_NONBLOCK); 935 return -EINVAL; 936 } 937 938 static int vidioc_streamon(struct file *file, void *__fh, enum v4l2_buf_type type) 939 { 940 struct saa7146_fh *fh = __fh; 941 int err; 942 943 DEB_D("VIDIOC_STREAMON, type:%d\n", type); 944 945 err = video_begin(fh); 946 if (err) 947 return err; 948 if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE) 949 return videobuf_streamon(&fh->video_q); 950 if (type == V4L2_BUF_TYPE_VBI_CAPTURE) 951 return videobuf_streamon(&fh->vbi_q); 952 return -EINVAL; 953 } 954 955 static int vidioc_streamoff(struct file *file, void *__fh, enum v4l2_buf_type type) 956 { 957 struct saa7146_fh *fh = __fh; 958 struct saa7146_dev *dev = fh->dev; 959 struct saa7146_vv *vv = dev->vv_data; 960 int err; 961 962 DEB_D("VIDIOC_STREAMOFF, type:%d\n", type); 963 964 /* ugly: we need to copy some checks from video_end(), 965 because videobuf_streamoff() relies on the capture running. 966 check and fix this */ 967 if ((vv->video_status & STATUS_CAPTURE) != STATUS_CAPTURE) { 968 DEB_S("not capturing\n"); 969 return 0; 970 } 971 972 if (vv->video_fh != fh) { 973 DEB_S("capturing, but in another open\n"); 974 return -EBUSY; 975 } 976 977 err = -EINVAL; 978 if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE) 979 err = videobuf_streamoff(&fh->video_q); 980 else if (type == V4L2_BUF_TYPE_VBI_CAPTURE) 981 err = videobuf_streamoff(&fh->vbi_q); 982 if (0 != err) { 983 DEB_D("warning: videobuf_streamoff() failed\n"); 984 video_end(fh, file); 985 } else { 986 err = video_end(fh, file); 987 } 988 return err; 989 } 990 991 static int vidioc_g_chip_ident(struct file *file, void *__fh, 992 struct v4l2_dbg_chip_ident *chip) 993 { 994 struct saa7146_fh *fh = __fh; 995 struct saa7146_dev *dev = fh->dev; 996 997 chip->ident = V4L2_IDENT_NONE; 998 chip->revision = 0; 999 if (chip->match.type == V4L2_CHIP_MATCH_HOST) { 1000 if (v4l2_chip_match_host(&chip->match)) 1001 chip->ident = V4L2_IDENT_SAA7146; 1002 return 0; 1003 } 1004 if (chip->match.type != V4L2_CHIP_MATCH_I2C_DRIVER && 1005 chip->match.type != V4L2_CHIP_MATCH_I2C_ADDR) 1006 return -EINVAL; 1007 return v4l2_device_call_until_err(&dev->v4l2_dev, 0, 1008 core, g_chip_ident, chip); 1009 } 1010 1011 const struct v4l2_ioctl_ops saa7146_video_ioctl_ops = { 1012 .vidioc_querycap = vidioc_querycap, 1013 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, 1014 .vidioc_enum_fmt_vid_overlay = vidioc_enum_fmt_vid_cap, 1015 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, 1016 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, 1017 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, 1018 .vidioc_g_fmt_vid_overlay = vidioc_g_fmt_vid_overlay, 1019 .vidioc_try_fmt_vid_overlay = vidioc_try_fmt_vid_overlay, 1020 .vidioc_s_fmt_vid_overlay = vidioc_s_fmt_vid_overlay, 1021 .vidioc_g_chip_ident = vidioc_g_chip_ident, 1022 1023 .vidioc_overlay = vidioc_overlay, 1024 .vidioc_g_fbuf = vidioc_g_fbuf, 1025 .vidioc_s_fbuf = vidioc_s_fbuf, 1026 .vidioc_reqbufs = vidioc_reqbufs, 1027 .vidioc_querybuf = vidioc_querybuf, 1028 .vidioc_qbuf = vidioc_qbuf, 1029 .vidioc_dqbuf = vidioc_dqbuf, 1030 .vidioc_g_std = vidioc_g_std, 1031 .vidioc_s_std = vidioc_s_std, 1032 .vidioc_streamon = vidioc_streamon, 1033 .vidioc_streamoff = vidioc_streamoff, 1034 .vidioc_g_parm = vidioc_g_parm, 1035 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, 1036 .vidioc_unsubscribe_event = v4l2_event_unsubscribe, 1037 }; 1038 1039 const struct v4l2_ioctl_ops saa7146_vbi_ioctl_ops = { 1040 .vidioc_querycap = vidioc_querycap, 1041 .vidioc_g_fmt_vbi_cap = vidioc_g_fmt_vbi_cap, 1042 .vidioc_g_chip_ident = vidioc_g_chip_ident, 1043 1044 .vidioc_reqbufs = vidioc_reqbufs, 1045 .vidioc_querybuf = vidioc_querybuf, 1046 .vidioc_qbuf = vidioc_qbuf, 1047 .vidioc_dqbuf = vidioc_dqbuf, 1048 .vidioc_g_std = vidioc_g_std, 1049 .vidioc_s_std = vidioc_s_std, 1050 .vidioc_streamon = vidioc_streamon, 1051 .vidioc_streamoff = vidioc_streamoff, 1052 .vidioc_g_parm = vidioc_g_parm, 1053 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, 1054 .vidioc_unsubscribe_event = v4l2_event_unsubscribe, 1055 }; 1056 1057 /*********************************************************************************/ 1058 /* buffer handling functions */ 1059 1060 static int buffer_activate (struct saa7146_dev *dev, 1061 struct saa7146_buf *buf, 1062 struct saa7146_buf *next) 1063 { 1064 struct saa7146_vv *vv = dev->vv_data; 1065 1066 buf->vb.state = VIDEOBUF_ACTIVE; 1067 saa7146_set_capture(dev,buf,next); 1068 1069 mod_timer(&vv->video_dmaq.timeout, jiffies+BUFFER_TIMEOUT); 1070 return 0; 1071 } 1072 1073 static void release_all_pagetables(struct saa7146_dev *dev, struct saa7146_buf *buf) 1074 { 1075 saa7146_pgtable_free(dev->pci, &buf->pt[0]); 1076 saa7146_pgtable_free(dev->pci, &buf->pt[1]); 1077 saa7146_pgtable_free(dev->pci, &buf->pt[2]); 1078 } 1079 1080 static int buffer_prepare(struct videobuf_queue *q, 1081 struct videobuf_buffer *vb, enum v4l2_field field) 1082 { 1083 struct file *file = q->priv_data; 1084 struct saa7146_fh *fh = file->private_data; 1085 struct saa7146_dev *dev = fh->dev; 1086 struct saa7146_vv *vv = dev->vv_data; 1087 struct saa7146_buf *buf = (struct saa7146_buf *)vb; 1088 int size,err = 0; 1089 1090 DEB_CAP("vbuf:%p\n", vb); 1091 1092 /* sanity checks */ 1093 if (vv->video_fmt.width < 48 || 1094 vv->video_fmt.height < 32 || 1095 vv->video_fmt.width > vv->standard->h_max_out || 1096 vv->video_fmt.height > vv->standard->v_max_out) { 1097 DEB_D("w (%d) / h (%d) out of bounds\n", 1098 vv->video_fmt.width, vv->video_fmt.height); 1099 return -EINVAL; 1100 } 1101 1102 size = vv->video_fmt.sizeimage; 1103 if (0 != buf->vb.baddr && buf->vb.bsize < size) { 1104 DEB_D("size mismatch\n"); 1105 return -EINVAL; 1106 } 1107 1108 DEB_CAP("buffer_prepare [size=%dx%d,bytes=%d,fields=%s]\n", 1109 vv->video_fmt.width, vv->video_fmt.height, 1110 size, v4l2_field_names[vv->video_fmt.field]); 1111 if (buf->vb.width != vv->video_fmt.width || 1112 buf->vb.bytesperline != vv->video_fmt.bytesperline || 1113 buf->vb.height != vv->video_fmt.height || 1114 buf->vb.size != size || 1115 buf->vb.field != field || 1116 buf->vb.field != vv->video_fmt.field || 1117 buf->fmt != &vv->video_fmt) { 1118 saa7146_dma_free(dev,q,buf); 1119 } 1120 1121 if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { 1122 struct saa7146_format *sfmt; 1123 1124 buf->vb.bytesperline = vv->video_fmt.bytesperline; 1125 buf->vb.width = vv->video_fmt.width; 1126 buf->vb.height = vv->video_fmt.height; 1127 buf->vb.size = size; 1128 buf->vb.field = field; 1129 buf->fmt = &vv->video_fmt; 1130 buf->vb.field = vv->video_fmt.field; 1131 1132 sfmt = saa7146_format_by_fourcc(dev,buf->fmt->pixelformat); 1133 1134 release_all_pagetables(dev, buf); 1135 if( 0 != IS_PLANAR(sfmt->trans)) { 1136 saa7146_pgtable_alloc(dev->pci, &buf->pt[0]); 1137 saa7146_pgtable_alloc(dev->pci, &buf->pt[1]); 1138 saa7146_pgtable_alloc(dev->pci, &buf->pt[2]); 1139 } else { 1140 saa7146_pgtable_alloc(dev->pci, &buf->pt[0]); 1141 } 1142 1143 err = videobuf_iolock(q,&buf->vb, &vv->ov_fb); 1144 if (err) 1145 goto oops; 1146 err = saa7146_pgtable_build(dev,buf); 1147 if (err) 1148 goto oops; 1149 } 1150 buf->vb.state = VIDEOBUF_PREPARED; 1151 buf->activate = buffer_activate; 1152 1153 return 0; 1154 1155 oops: 1156 DEB_D("error out\n"); 1157 saa7146_dma_free(dev,q,buf); 1158 1159 return err; 1160 } 1161 1162 static int buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size) 1163 { 1164 struct file *file = q->priv_data; 1165 struct saa7146_fh *fh = file->private_data; 1166 struct saa7146_vv *vv = fh->dev->vv_data; 1167 1168 if (0 == *count || *count > MAX_SAA7146_CAPTURE_BUFFERS) 1169 *count = MAX_SAA7146_CAPTURE_BUFFERS; 1170 1171 *size = vv->video_fmt.sizeimage; 1172 1173 /* check if we exceed the "max_memory" parameter */ 1174 if( (*count * *size) > (max_memory*1048576) ) { 1175 *count = (max_memory*1048576) / *size; 1176 } 1177 1178 DEB_CAP("%d buffers, %d bytes each\n", *count, *size); 1179 1180 return 0; 1181 } 1182 1183 static void buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb) 1184 { 1185 struct file *file = q->priv_data; 1186 struct saa7146_fh *fh = file->private_data; 1187 struct saa7146_dev *dev = fh->dev; 1188 struct saa7146_vv *vv = dev->vv_data; 1189 struct saa7146_buf *buf = (struct saa7146_buf *)vb; 1190 1191 DEB_CAP("vbuf:%p\n", vb); 1192 saa7146_buffer_queue(fh->dev, &vv->video_dmaq, buf); 1193 } 1194 1195 static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb) 1196 { 1197 struct file *file = q->priv_data; 1198 struct saa7146_fh *fh = file->private_data; 1199 struct saa7146_dev *dev = fh->dev; 1200 struct saa7146_buf *buf = (struct saa7146_buf *)vb; 1201 1202 DEB_CAP("vbuf:%p\n", vb); 1203 1204 saa7146_dma_free(dev,q,buf); 1205 1206 release_all_pagetables(dev, buf); 1207 } 1208 1209 static struct videobuf_queue_ops video_qops = { 1210 .buf_setup = buffer_setup, 1211 .buf_prepare = buffer_prepare, 1212 .buf_queue = buffer_queue, 1213 .buf_release = buffer_release, 1214 }; 1215 1216 /********************************************************************************/ 1217 /* file operations */ 1218 1219 static void video_init(struct saa7146_dev *dev, struct saa7146_vv *vv) 1220 { 1221 INIT_LIST_HEAD(&vv->video_dmaq.queue); 1222 1223 init_timer(&vv->video_dmaq.timeout); 1224 vv->video_dmaq.timeout.function = saa7146_buffer_timeout; 1225 vv->video_dmaq.timeout.data = (unsigned long)(&vv->video_dmaq); 1226 vv->video_dmaq.dev = dev; 1227 1228 /* set some default values */ 1229 vv->standard = &dev->ext_vv_data->stds[0]; 1230 1231 /* FIXME: what's this? */ 1232 vv->current_hps_source = SAA7146_HPS_SOURCE_PORT_A; 1233 vv->current_hps_sync = SAA7146_HPS_SYNC_PORT_A; 1234 } 1235 1236 1237 static int video_open(struct saa7146_dev *dev, struct file *file) 1238 { 1239 struct saa7146_fh *fh = file->private_data; 1240 1241 videobuf_queue_sg_init(&fh->video_q, &video_qops, 1242 &dev->pci->dev, &dev->slock, 1243 V4L2_BUF_TYPE_VIDEO_CAPTURE, 1244 V4L2_FIELD_INTERLACED, 1245 sizeof(struct saa7146_buf), 1246 file, &dev->v4l2_lock); 1247 1248 return 0; 1249 } 1250 1251 1252 static void video_close(struct saa7146_dev *dev, struct file *file) 1253 { 1254 struct saa7146_fh *fh = file->private_data; 1255 struct saa7146_vv *vv = dev->vv_data; 1256 struct videobuf_queue *q = &fh->video_q; 1257 1258 if (IS_CAPTURE_ACTIVE(fh) != 0) 1259 video_end(fh, file); 1260 else if (IS_OVERLAY_ACTIVE(fh) != 0) 1261 saa7146_stop_preview(fh); 1262 1263 videobuf_stop(q); 1264 /* hmm, why is this function declared void? */ 1265 } 1266 1267 1268 static void video_irq_done(struct saa7146_dev *dev, unsigned long st) 1269 { 1270 struct saa7146_vv *vv = dev->vv_data; 1271 struct saa7146_dmaqueue *q = &vv->video_dmaq; 1272 1273 spin_lock(&dev->slock); 1274 DEB_CAP("called\n"); 1275 1276 /* only finish the buffer if we have one... */ 1277 if( NULL != q->curr ) { 1278 saa7146_buffer_finish(dev,q,VIDEOBUF_DONE); 1279 } 1280 saa7146_buffer_next(dev,q,0); 1281 1282 spin_unlock(&dev->slock); 1283 } 1284 1285 static ssize_t video_read(struct file *file, char __user *data, size_t count, loff_t *ppos) 1286 { 1287 struct saa7146_fh *fh = file->private_data; 1288 struct saa7146_dev *dev = fh->dev; 1289 struct saa7146_vv *vv = dev->vv_data; 1290 ssize_t ret = 0; 1291 1292 DEB_EE("called\n"); 1293 1294 if ((vv->video_status & STATUS_CAPTURE) != 0) { 1295 /* fixme: should we allow read() captures while streaming capture? */ 1296 if (vv->video_fh == fh) { 1297 DEB_S("already capturing\n"); 1298 return -EBUSY; 1299 } 1300 DEB_S("already capturing in another open\n"); 1301 return -EBUSY; 1302 } 1303 1304 ret = video_begin(fh); 1305 if( 0 != ret) { 1306 goto out; 1307 } 1308 1309 ret = videobuf_read_one(&fh->video_q , data, count, ppos, 1310 file->f_flags & O_NONBLOCK); 1311 if (ret != 0) { 1312 video_end(fh, file); 1313 } else { 1314 ret = video_end(fh, file); 1315 } 1316 out: 1317 /* restart overlay if it was active before */ 1318 if (vv->ov_suspend != NULL) { 1319 saa7146_start_preview(vv->ov_suspend); 1320 vv->ov_suspend = NULL; 1321 } 1322 1323 return ret; 1324 } 1325 1326 struct saa7146_use_ops saa7146_video_uops = { 1327 .init = video_init, 1328 .open = video_open, 1329 .release = video_close, 1330 .irq_done = video_irq_done, 1331 .read = video_read, 1332 }; 1333