1 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 2 3 #include <media/drv-intf/saa7146_vv.h> 4 #include <media/v4l2-event.h> 5 #include <media/v4l2-ctrls.h> 6 #include <linux/module.h> 7 #include <linux/kernel.h> 8 9 /* format descriptions for capture and preview */ 10 static struct saa7146_format formats[] = { 11 { 12 .pixelformat = V4L2_PIX_FMT_RGB332, 13 .trans = RGB08_COMPOSED, 14 .depth = 8, 15 .flags = 0, 16 }, { 17 .pixelformat = V4L2_PIX_FMT_RGB565, 18 .trans = RGB16_COMPOSED, 19 .depth = 16, 20 .flags = 0, 21 }, { 22 .pixelformat = V4L2_PIX_FMT_BGR24, 23 .trans = RGB24_COMPOSED, 24 .depth = 24, 25 .flags = 0, 26 }, { 27 .pixelformat = V4L2_PIX_FMT_BGR32, 28 .trans = RGB32_COMPOSED, 29 .depth = 32, 30 .flags = 0, 31 }, { 32 .pixelformat = V4L2_PIX_FMT_RGB32, 33 .trans = RGB32_COMPOSED, 34 .depth = 32, 35 .flags = 0, 36 .swap = 0x2, 37 }, { 38 .pixelformat = V4L2_PIX_FMT_GREY, 39 .trans = Y8, 40 .depth = 8, 41 .flags = 0, 42 }, { 43 .pixelformat = V4L2_PIX_FMT_YUV422P, 44 .trans = YUV422_DECOMPOSED, 45 .depth = 16, 46 .flags = FORMAT_IS_PLANAR, 47 }, { 48 .pixelformat = V4L2_PIX_FMT_YVU420, 49 .trans = YUV420_DECOMPOSED, 50 .depth = 12, 51 .flags = FORMAT_BYTE_SWAP|FORMAT_IS_PLANAR, 52 }, { 53 .pixelformat = V4L2_PIX_FMT_YUV420, 54 .trans = YUV420_DECOMPOSED, 55 .depth = 12, 56 .flags = FORMAT_IS_PLANAR, 57 }, { 58 .pixelformat = V4L2_PIX_FMT_UYVY, 59 .trans = YUV422_COMPOSED, 60 .depth = 16, 61 .flags = 0, 62 } 63 }; 64 65 /* unfortunately, the saa7146 contains a bug which prevents it from doing on-the-fly byte swaps. 66 due to this, it's impossible to provide additional *packed* formats, which are simply byte swapped 67 (like V4L2_PIX_FMT_YUYV) ... 8-( */ 68 69 struct saa7146_format* saa7146_format_by_fourcc(struct saa7146_dev *dev, int fourcc) 70 { 71 int i; 72 73 for (i = 0; i < ARRAY_SIZE(formats); i++) { 74 if (formats[i].pixelformat == fourcc) { 75 return formats+i; 76 } 77 } 78 79 DEB_D("unknown pixelformat:'%4.4s'\n", (char *)&fourcc); 80 return NULL; 81 } 82 83 /********************************************************************************/ 84 /* common pagetable functions */ 85 86 static int saa7146_pgtable_build(struct saa7146_dev *dev, struct saa7146_buf *buf) 87 { 88 struct saa7146_vv *vv = dev->vv_data; 89 struct pci_dev *pci = dev->pci; 90 struct sg_table *sgt = vb2_dma_sg_plane_desc(&buf->vb.vb2_buf, 0); 91 struct scatterlist *list = sgt->sgl; 92 int length = sgt->nents; 93 struct v4l2_pix_format *pix = &vv->video_fmt; 94 struct saa7146_format *sfmt = saa7146_format_by_fourcc(dev, pix->pixelformat); 95 96 DEB_EE("dev:%p, buf:%p, sg_len:%d\n", dev, buf, length); 97 98 if( 0 != IS_PLANAR(sfmt->trans)) { 99 struct saa7146_pgtable *pt1 = &buf->pt[0]; 100 struct saa7146_pgtable *pt2 = &buf->pt[1]; 101 struct saa7146_pgtable *pt3 = &buf->pt[2]; 102 struct sg_dma_page_iter dma_iter; 103 __le32 *ptr1, *ptr2, *ptr3; 104 __le32 fill; 105 106 int size = pix->width * pix->height; 107 int i, m1, m2, m3, o1, o2; 108 109 switch( sfmt->depth ) { 110 case 12: { 111 /* create some offsets inside the page table */ 112 m1 = ((size + PAGE_SIZE) / PAGE_SIZE) - 1; 113 m2 = ((size + (size / 4) + PAGE_SIZE) / PAGE_SIZE) - 1; 114 m3 = ((size + (size / 2) + PAGE_SIZE) / PAGE_SIZE) - 1; 115 o1 = size % PAGE_SIZE; 116 o2 = (size + (size / 4)) % PAGE_SIZE; 117 DEB_CAP("size:%d, m1:%d, m2:%d, m3:%d, o1:%d, o2:%d\n", 118 size, m1, m2, m3, o1, o2); 119 break; 120 } 121 case 16: { 122 /* create some offsets inside the page table */ 123 m1 = ((size + PAGE_SIZE) / PAGE_SIZE) - 1; 124 m2 = ((size + (size / 2) + PAGE_SIZE) / PAGE_SIZE) - 1; 125 m3 = ((2 * size + PAGE_SIZE) / PAGE_SIZE) - 1; 126 o1 = size % PAGE_SIZE; 127 o2 = (size + (size / 2)) % PAGE_SIZE; 128 DEB_CAP("size:%d, m1:%d, m2:%d, m3:%d, o1:%d, o2:%d\n", 129 size, m1, m2, m3, o1, o2); 130 break; 131 } 132 default: { 133 return -1; 134 } 135 } 136 137 ptr1 = pt1->cpu; 138 ptr2 = pt2->cpu; 139 ptr3 = pt3->cpu; 140 141 for_each_sg_dma_page(list, &dma_iter, length, 0) 142 *ptr1++ = cpu_to_le32(sg_page_iter_dma_address(&dma_iter) - list->offset); 143 144 /* if we have a user buffer, the first page may not be 145 aligned to a page boundary. */ 146 pt1->offset = sgt->sgl->offset; 147 pt2->offset = pt1->offset + o1; 148 pt3->offset = pt1->offset + o2; 149 150 /* create video-dma2 page table */ 151 ptr1 = pt1->cpu; 152 for (i = m1; i <= m2; i++, ptr2++) 153 *ptr2 = ptr1[i]; 154 fill = *(ptr2 - 1); 155 for (; i < 1024; i++, ptr2++) 156 *ptr2 = fill; 157 /* create video-dma3 page table */ 158 ptr1 = pt1->cpu; 159 for (i = m2; i <= m3; i++, ptr3++) 160 *ptr3 = ptr1[i]; 161 fill = *(ptr3 - 1); 162 for (; i < 1024; i++, ptr3++) 163 *ptr3 = fill; 164 /* finally: finish up video-dma1 page table */ 165 ptr1 = pt1->cpu + m1; 166 fill = pt1->cpu[m1]; 167 for (i = m1; i < 1024; i++, ptr1++) 168 *ptr1 = fill; 169 } else { 170 struct saa7146_pgtable *pt = &buf->pt[0]; 171 172 return saa7146_pgtable_build_single(pci, pt, list, length); 173 } 174 175 return 0; 176 } 177 178 179 /********************************************************************************/ 180 /* file operations */ 181 182 static int video_begin(struct saa7146_dev *dev) 183 { 184 struct saa7146_vv *vv = dev->vv_data; 185 struct saa7146_format *fmt = NULL; 186 unsigned int resource; 187 int ret = 0; 188 189 DEB_EE("dev:%p\n", dev); 190 191 fmt = saa7146_format_by_fourcc(dev, vv->video_fmt.pixelformat); 192 /* we need to have a valid format set here */ 193 if (!fmt) 194 return -EINVAL; 195 196 if (0 != (fmt->flags & FORMAT_IS_PLANAR)) { 197 resource = RESOURCE_DMA1_HPS|RESOURCE_DMA2_CLP|RESOURCE_DMA3_BRS; 198 } else { 199 resource = RESOURCE_DMA1_HPS; 200 } 201 202 ret = saa7146_res_get(dev, resource); 203 if (0 == ret) { 204 DEB_S("cannot get capture resource %d\n", resource); 205 return -EBUSY; 206 } 207 208 /* clear out beginning of streaming bit (rps register 0)*/ 209 saa7146_write(dev, MC2, MASK_27 ); 210 211 /* enable rps0 irqs */ 212 SAA7146_IER_ENABLE(dev, MASK_27); 213 214 return 0; 215 } 216 217 static void video_end(struct saa7146_dev *dev) 218 { 219 struct saa7146_vv *vv = dev->vv_data; 220 struct saa7146_format *fmt = NULL; 221 unsigned long flags; 222 unsigned int resource; 223 u32 dmas = 0; 224 DEB_EE("dev:%p\n", dev); 225 226 fmt = saa7146_format_by_fourcc(dev, vv->video_fmt.pixelformat); 227 /* we need to have a valid format set here */ 228 if (!fmt) 229 return; 230 231 if (0 != (fmt->flags & FORMAT_IS_PLANAR)) { 232 resource = RESOURCE_DMA1_HPS|RESOURCE_DMA2_CLP|RESOURCE_DMA3_BRS; 233 dmas = MASK_22 | MASK_21 | MASK_20; 234 } else { 235 resource = RESOURCE_DMA1_HPS; 236 dmas = MASK_22; 237 } 238 spin_lock_irqsave(&dev->slock,flags); 239 240 /* disable rps0 */ 241 saa7146_write(dev, MC1, MASK_28); 242 243 /* disable rps0 irqs */ 244 SAA7146_IER_DISABLE(dev, MASK_27); 245 246 /* shut down all used video dma transfers */ 247 saa7146_write(dev, MC1, dmas); 248 249 spin_unlock_irqrestore(&dev->slock, flags); 250 251 saa7146_res_free(dev, resource); 252 } 253 254 static int vidioc_querycap(struct file *file, void *fh, struct v4l2_capability *cap) 255 { 256 struct saa7146_dev *dev = video_drvdata(file); 257 258 strscpy((char *)cap->driver, "saa7146 v4l2", sizeof(cap->driver)); 259 strscpy((char *)cap->card, dev->ext->name, sizeof(cap->card)); 260 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | 261 V4L2_CAP_READWRITE | V4L2_CAP_STREAMING | 262 V4L2_CAP_DEVICE_CAPS; 263 cap->capabilities |= dev->ext_vv_data->capabilities; 264 return 0; 265 } 266 267 static int vidioc_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *f) 268 { 269 if (f->index >= ARRAY_SIZE(formats)) 270 return -EINVAL; 271 f->pixelformat = formats[f->index].pixelformat; 272 return 0; 273 } 274 275 int saa7146_s_ctrl(struct v4l2_ctrl *ctrl) 276 { 277 struct saa7146_dev *dev = container_of(ctrl->handler, 278 struct saa7146_dev, ctrl_handler); 279 struct saa7146_vv *vv = dev->vv_data; 280 u32 val; 281 282 switch (ctrl->id) { 283 case V4L2_CID_BRIGHTNESS: 284 val = saa7146_read(dev, BCS_CTRL); 285 val &= 0x00ffffff; 286 val |= (ctrl->val << 24); 287 saa7146_write(dev, BCS_CTRL, val); 288 saa7146_write(dev, MC2, MASK_22 | MASK_06); 289 break; 290 291 case V4L2_CID_CONTRAST: 292 val = saa7146_read(dev, BCS_CTRL); 293 val &= 0xff00ffff; 294 val |= (ctrl->val << 16); 295 saa7146_write(dev, BCS_CTRL, val); 296 saa7146_write(dev, MC2, MASK_22 | MASK_06); 297 break; 298 299 case V4L2_CID_SATURATION: 300 val = saa7146_read(dev, BCS_CTRL); 301 val &= 0xffffff00; 302 val |= (ctrl->val << 0); 303 saa7146_write(dev, BCS_CTRL, val); 304 saa7146_write(dev, MC2, MASK_22 | MASK_06); 305 break; 306 307 case V4L2_CID_HFLIP: 308 /* fixme: we can support changing VFLIP and HFLIP here... */ 309 if (vb2_is_busy(&vv->video_dmaq.q)) 310 return -EBUSY; 311 vv->hflip = ctrl->val; 312 break; 313 314 case V4L2_CID_VFLIP: 315 if (vb2_is_busy(&vv->video_dmaq.q)) 316 return -EBUSY; 317 vv->vflip = ctrl->val; 318 break; 319 320 default: 321 return -EINVAL; 322 } 323 return 0; 324 } 325 326 static int vidioc_g_parm(struct file *file, void *fh, 327 struct v4l2_streamparm *parm) 328 { 329 struct saa7146_dev *dev = video_drvdata(file); 330 struct saa7146_vv *vv = dev->vv_data; 331 332 if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 333 return -EINVAL; 334 parm->parm.capture.readbuffers = 1; 335 v4l2_video_std_frame_period(vv->standard->id, 336 &parm->parm.capture.timeperframe); 337 return 0; 338 } 339 340 static int vidioc_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f) 341 { 342 struct saa7146_dev *dev = video_drvdata(file); 343 struct saa7146_vv *vv = dev->vv_data; 344 345 f->fmt.pix = vv->video_fmt; 346 return 0; 347 } 348 349 static int vidioc_g_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *f) 350 { 351 struct saa7146_dev *dev = video_drvdata(file); 352 struct saa7146_vv *vv = dev->vv_data; 353 354 f->fmt.vbi = vv->vbi_fmt; 355 return 0; 356 } 357 358 static int vidioc_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f) 359 { 360 struct saa7146_dev *dev = video_drvdata(file); 361 struct saa7146_vv *vv = dev->vv_data; 362 struct saa7146_format *fmt; 363 enum v4l2_field field; 364 int maxw, maxh; 365 int calc_bpl; 366 367 DEB_EE("V4L2_BUF_TYPE_VIDEO_CAPTURE: dev:%p, fh:%p\n", dev, fh); 368 369 fmt = saa7146_format_by_fourcc(dev, f->fmt.pix.pixelformat); 370 if (NULL == fmt) 371 return -EINVAL; 372 373 field = f->fmt.pix.field; 374 maxw = vv->standard->h_max_out; 375 maxh = vv->standard->v_max_out; 376 377 if (V4L2_FIELD_ANY == field) { 378 field = (f->fmt.pix.height > maxh / 2) 379 ? V4L2_FIELD_INTERLACED 380 : V4L2_FIELD_BOTTOM; 381 } 382 switch (field) { 383 case V4L2_FIELD_ALTERNATE: 384 case V4L2_FIELD_TOP: 385 case V4L2_FIELD_BOTTOM: 386 maxh = maxh / 2; 387 break; 388 default: 389 field = V4L2_FIELD_INTERLACED; 390 break; 391 } 392 393 f->fmt.pix.field = field; 394 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; 395 if (f->fmt.pix.width < 48) 396 f->fmt.pix.width = 48; 397 if (f->fmt.pix.height < 32) 398 f->fmt.pix.height = 32; 399 if (f->fmt.pix.width > maxw) 400 f->fmt.pix.width = maxw; 401 if (f->fmt.pix.height > maxh) 402 f->fmt.pix.height = maxh; 403 404 calc_bpl = (f->fmt.pix.width * fmt->depth) / 8; 405 406 if (f->fmt.pix.bytesperline < calc_bpl) 407 f->fmt.pix.bytesperline = calc_bpl; 408 409 if (f->fmt.pix.bytesperline > (2 * PAGE_SIZE * fmt->depth) / 8) /* arbitrary constraint */ 410 f->fmt.pix.bytesperline = calc_bpl; 411 412 f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * f->fmt.pix.height; 413 DEB_D("w:%d, h:%d, bytesperline:%d, sizeimage:%d\n", 414 f->fmt.pix.width, f->fmt.pix.height, 415 f->fmt.pix.bytesperline, f->fmt.pix.sizeimage); 416 417 return 0; 418 } 419 420 static int vidioc_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f) 421 { 422 struct saa7146_dev *dev = video_drvdata(file); 423 struct saa7146_vv *vv = dev->vv_data; 424 int err; 425 426 DEB_EE("V4L2_BUF_TYPE_VIDEO_CAPTURE: dev:%p\n", dev); 427 if (vb2_is_busy(&vv->video_dmaq.q)) { 428 DEB_EE("streaming capture is active\n"); 429 return -EBUSY; 430 } 431 err = vidioc_try_fmt_vid_cap(file, fh, f); 432 if (0 != err) 433 return err; 434 switch (f->fmt.pix.field) { 435 case V4L2_FIELD_ALTERNATE: 436 vv->last_field = V4L2_FIELD_TOP; 437 break; 438 default: 439 vv->last_field = V4L2_FIELD_INTERLACED; 440 break; 441 } 442 vv->video_fmt = f->fmt.pix; 443 DEB_EE("set to pixelformat '%4.4s'\n", 444 (char *)&vv->video_fmt.pixelformat); 445 return 0; 446 } 447 448 static int vidioc_g_std(struct file *file, void *fh, v4l2_std_id *norm) 449 { 450 struct saa7146_dev *dev = video_drvdata(file); 451 struct saa7146_vv *vv = dev->vv_data; 452 453 *norm = vv->standard->id; 454 return 0; 455 } 456 457 static int vidioc_s_std(struct file *file, void *fh, v4l2_std_id id) 458 { 459 struct saa7146_dev *dev = video_drvdata(file); 460 struct saa7146_vv *vv = dev->vv_data; 461 int found = 0; 462 int i; 463 464 DEB_EE("VIDIOC_S_STD\n"); 465 466 for (i = 0; i < dev->ext_vv_data->num_stds; i++) 467 if (id & dev->ext_vv_data->stds[i].id) 468 break; 469 470 if (i != dev->ext_vv_data->num_stds && 471 vv->standard == &dev->ext_vv_data->stds[i]) 472 return 0; 473 474 if (vb2_is_busy(&vv->video_dmaq.q) || vb2_is_busy(&vv->vbi_dmaq.q)) { 475 DEB_D("cannot change video standard while streaming capture is active\n"); 476 return -EBUSY; 477 } 478 479 if (i != dev->ext_vv_data->num_stds) { 480 vv->standard = &dev->ext_vv_data->stds[i]; 481 if (NULL != dev->ext_vv_data->std_callback) 482 dev->ext_vv_data->std_callback(dev, vv->standard); 483 found = 1; 484 } 485 486 if (!found) { 487 DEB_EE("VIDIOC_S_STD: standard not found\n"); 488 return -EINVAL; 489 } 490 491 DEB_EE("VIDIOC_S_STD: set to standard to '%s'\n", vv->standard->name); 492 return 0; 493 } 494 495 const struct v4l2_ioctl_ops saa7146_video_ioctl_ops = { 496 .vidioc_querycap = vidioc_querycap, 497 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, 498 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, 499 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, 500 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, 501 .vidioc_g_std = vidioc_g_std, 502 .vidioc_s_std = vidioc_s_std, 503 .vidioc_g_parm = vidioc_g_parm, 504 .vidioc_reqbufs = vb2_ioctl_reqbufs, 505 .vidioc_create_bufs = vb2_ioctl_create_bufs, 506 .vidioc_querybuf = vb2_ioctl_querybuf, 507 .vidioc_qbuf = vb2_ioctl_qbuf, 508 .vidioc_dqbuf = vb2_ioctl_dqbuf, 509 .vidioc_streamon = vb2_ioctl_streamon, 510 .vidioc_streamoff = vb2_ioctl_streamoff, 511 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, 512 .vidioc_unsubscribe_event = v4l2_event_unsubscribe, 513 }; 514 515 const struct v4l2_ioctl_ops saa7146_vbi_ioctl_ops = { 516 .vidioc_querycap = vidioc_querycap, 517 .vidioc_g_fmt_vbi_cap = vidioc_g_fmt_vbi_cap, 518 .vidioc_try_fmt_vbi_cap = vidioc_g_fmt_vbi_cap, 519 .vidioc_s_fmt_vbi_cap = vidioc_g_fmt_vbi_cap, 520 .vidioc_g_std = vidioc_g_std, 521 .vidioc_s_std = vidioc_s_std, 522 .vidioc_g_parm = vidioc_g_parm, 523 .vidioc_reqbufs = vb2_ioctl_reqbufs, 524 .vidioc_create_bufs = vb2_ioctl_create_bufs, 525 .vidioc_querybuf = vb2_ioctl_querybuf, 526 .vidioc_qbuf = vb2_ioctl_qbuf, 527 .vidioc_dqbuf = vb2_ioctl_dqbuf, 528 .vidioc_streamon = vb2_ioctl_streamon, 529 .vidioc_streamoff = vb2_ioctl_streamoff, 530 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, 531 .vidioc_unsubscribe_event = v4l2_event_unsubscribe, 532 }; 533 534 /*********************************************************************************/ 535 /* buffer handling functions */ 536 537 static int buffer_activate (struct saa7146_dev *dev, 538 struct saa7146_buf *buf, 539 struct saa7146_buf *next) 540 { 541 struct saa7146_vv *vv = dev->vv_data; 542 543 saa7146_set_capture(dev,buf,next); 544 545 mod_timer(&vv->video_dmaq.timeout, jiffies+BUFFER_TIMEOUT); 546 return 0; 547 } 548 549 static void release_all_pagetables(struct saa7146_dev *dev, struct saa7146_buf *buf) 550 { 551 saa7146_pgtable_free(dev->pci, &buf->pt[0]); 552 saa7146_pgtable_free(dev->pci, &buf->pt[1]); 553 saa7146_pgtable_free(dev->pci, &buf->pt[2]); 554 } 555 556 static int queue_setup(struct vb2_queue *q, 557 unsigned int *num_buffers, unsigned int *num_planes, 558 unsigned int sizes[], struct device *alloc_devs[]) 559 { 560 struct saa7146_dev *dev = vb2_get_drv_priv(q); 561 unsigned int size = dev->vv_data->video_fmt.sizeimage; 562 563 if (*num_planes) 564 return sizes[0] < size ? -EINVAL : 0; 565 *num_planes = 1; 566 sizes[0] = size; 567 568 return 0; 569 } 570 571 static void buf_queue(struct vb2_buffer *vb) 572 { 573 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); 574 struct vb2_queue *vq = vb->vb2_queue; 575 struct saa7146_dev *dev = vb2_get_drv_priv(vq); 576 struct saa7146_buf *buf = container_of(vbuf, struct saa7146_buf, vb); 577 unsigned long flags; 578 579 spin_lock_irqsave(&dev->slock, flags); 580 581 saa7146_buffer_queue(dev, &dev->vv_data->video_dmaq, buf); 582 spin_unlock_irqrestore(&dev->slock, flags); 583 } 584 585 static int buf_init(struct vb2_buffer *vb) 586 { 587 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); 588 struct saa7146_buf *buf = container_of(vbuf, struct saa7146_buf, vb); 589 struct vb2_queue *vq = vb->vb2_queue; 590 struct saa7146_dev *dev = vb2_get_drv_priv(vq); 591 struct saa7146_vv *vv = dev->vv_data; 592 struct saa7146_format *sfmt; 593 int ret; 594 595 buf->activate = buffer_activate; 596 sfmt = saa7146_format_by_fourcc(dev, vv->video_fmt.pixelformat); 597 598 if (IS_PLANAR(sfmt->trans)) { 599 saa7146_pgtable_alloc(dev->pci, &buf->pt[0]); 600 saa7146_pgtable_alloc(dev->pci, &buf->pt[1]); 601 saa7146_pgtable_alloc(dev->pci, &buf->pt[2]); 602 } else { 603 saa7146_pgtable_alloc(dev->pci, &buf->pt[0]); 604 } 605 606 ret = saa7146_pgtable_build(dev, buf); 607 if (ret) 608 release_all_pagetables(dev, buf); 609 return ret; 610 } 611 612 static int buf_prepare(struct vb2_buffer *vb) 613 { 614 struct vb2_queue *vq = vb->vb2_queue; 615 struct saa7146_dev *dev = vb2_get_drv_priv(vq); 616 struct saa7146_vv *vv = dev->vv_data; 617 unsigned int size = vv->video_fmt.sizeimage; 618 619 if (vb2_plane_size(vb, 0) < size) 620 return -EINVAL; 621 vb2_set_plane_payload(vb, 0, size); 622 return 0; 623 } 624 625 static void buf_cleanup(struct vb2_buffer *vb) 626 { 627 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); 628 struct saa7146_buf *buf = container_of(vbuf, struct saa7146_buf, vb); 629 struct vb2_queue *vq = vb->vb2_queue; 630 struct saa7146_dev *dev = vb2_get_drv_priv(vq); 631 632 release_all_pagetables(dev, buf); 633 } 634 635 static void return_buffers(struct vb2_queue *q, int state) 636 { 637 struct saa7146_dev *dev = vb2_get_drv_priv(q); 638 struct saa7146_dmaqueue *dq = &dev->vv_data->video_dmaq; 639 struct saa7146_buf *buf; 640 641 if (dq->curr) { 642 buf = dq->curr; 643 dq->curr = NULL; 644 vb2_buffer_done(&buf->vb.vb2_buf, state); 645 } 646 while (!list_empty(&dq->queue)) { 647 buf = list_entry(dq->queue.next, struct saa7146_buf, list); 648 list_del(&buf->list); 649 vb2_buffer_done(&buf->vb.vb2_buf, state); 650 } 651 } 652 653 static int start_streaming(struct vb2_queue *q, unsigned int count) 654 { 655 struct saa7146_dev *dev = vb2_get_drv_priv(q); 656 int ret; 657 658 if (!vb2_is_streaming(&dev->vv_data->video_dmaq.q)) 659 dev->vv_data->seqnr = 0; 660 ret = video_begin(dev); 661 if (ret) 662 return_buffers(q, VB2_BUF_STATE_QUEUED); 663 return ret; 664 } 665 666 static void stop_streaming(struct vb2_queue *q) 667 { 668 struct saa7146_dev *dev = vb2_get_drv_priv(q); 669 struct saa7146_dmaqueue *dq = &dev->vv_data->video_dmaq; 670 671 del_timer(&dq->timeout); 672 video_end(dev); 673 return_buffers(q, VB2_BUF_STATE_ERROR); 674 } 675 676 const struct vb2_ops video_qops = { 677 .queue_setup = queue_setup, 678 .buf_queue = buf_queue, 679 .buf_init = buf_init, 680 .buf_prepare = buf_prepare, 681 .buf_cleanup = buf_cleanup, 682 .start_streaming = start_streaming, 683 .stop_streaming = stop_streaming, 684 .wait_prepare = vb2_ops_wait_prepare, 685 .wait_finish = vb2_ops_wait_finish, 686 }; 687 688 /********************************************************************************/ 689 /* file operations */ 690 691 static void video_init(struct saa7146_dev *dev, struct saa7146_vv *vv) 692 { 693 INIT_LIST_HEAD(&vv->video_dmaq.queue); 694 695 timer_setup(&vv->video_dmaq.timeout, saa7146_buffer_timeout, 0); 696 vv->video_dmaq.dev = dev; 697 698 /* set some default values */ 699 vv->standard = &dev->ext_vv_data->stds[0]; 700 701 /* FIXME: what's this? */ 702 vv->current_hps_source = SAA7146_HPS_SOURCE_PORT_A; 703 vv->current_hps_sync = SAA7146_HPS_SYNC_PORT_A; 704 } 705 706 static void video_irq_done(struct saa7146_dev *dev, unsigned long st) 707 { 708 struct saa7146_vv *vv = dev->vv_data; 709 struct saa7146_dmaqueue *q = &vv->video_dmaq; 710 711 spin_lock(&dev->slock); 712 DEB_CAP("called\n"); 713 714 /* only finish the buffer if we have one... */ 715 if (q->curr) 716 saa7146_buffer_finish(dev, q, VB2_BUF_STATE_DONE); 717 saa7146_buffer_next(dev,q,0); 718 719 spin_unlock(&dev->slock); 720 } 721 722 const struct saa7146_use_ops saa7146_video_uops = { 723 .init = video_init, 724 .irq_done = video_irq_done, 725 }; 726