1 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
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>
9 /* format descriptions for capture and preview */
10 static struct saa7146_format formats
[] = {
12 .pixelformat
= V4L2_PIX_FMT_RGB332
,
13 .trans
= RGB08_COMPOSED
,
17 .pixelformat
= V4L2_PIX_FMT_RGB565
,
18 .trans
= RGB16_COMPOSED
,
22 .pixelformat
= V4L2_PIX_FMT_BGR24
,
23 .trans
= RGB24_COMPOSED
,
27 .pixelformat
= V4L2_PIX_FMT_BGR32
,
28 .trans
= RGB32_COMPOSED
,
32 .pixelformat
= V4L2_PIX_FMT_RGB32
,
33 .trans
= RGB32_COMPOSED
,
38 .pixelformat
= V4L2_PIX_FMT_GREY
,
43 .pixelformat
= V4L2_PIX_FMT_YUV422P
,
44 .trans
= YUV422_DECOMPOSED
,
46 .flags
= FORMAT_IS_PLANAR
,
48 .pixelformat
= V4L2_PIX_FMT_YVU420
,
49 .trans
= YUV420_DECOMPOSED
,
51 .flags
= FORMAT_BYTE_SWAP
|FORMAT_IS_PLANAR
,
53 .pixelformat
= V4L2_PIX_FMT_YUV420
,
54 .trans
= YUV420_DECOMPOSED
,
56 .flags
= FORMAT_IS_PLANAR
,
58 .pixelformat
= V4L2_PIX_FMT_UYVY
,
59 .trans
= YUV422_COMPOSED
,
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-( */
69 struct saa7146_format
* saa7146_format_by_fourcc(struct saa7146_dev
*dev
, int fourcc
)
73 for (i
= 0; i
< ARRAY_SIZE(formats
); i
++) {
74 if (formats
[i
].pixelformat
== fourcc
) {
79 DEB_D("unknown pixelformat:'%4.4s'\n", (char *)&fourcc
);
83 /********************************************************************************/
84 /* common pagetable functions */
86 static int saa7146_pgtable_build(struct saa7146_dev
*dev
, struct saa7146_buf
*buf
)
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
);
96 DEB_EE("dev:%p, buf:%p, sg_len:%d\n", dev
, buf
, length
);
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
;
106 int size
= pix
->width
* pix
->height
;
107 int i
, m1
, m2
, m3
, o1
, o2
;
109 switch( sfmt
->depth
) {
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
);
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
);
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
);
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
;
150 /* create video-dma2 page table */
152 for (i
= m1
; i
<= m2
; i
++, ptr2
++)
155 for (; i
< 1024; i
++, ptr2
++)
157 /* create video-dma3 page table */
159 for (i
= m2
; i
<= m3
; i
++, ptr3
++)
162 for (; i
< 1024; i
++, ptr3
++)
164 /* finally: finish up video-dma1 page table */
165 ptr1
= pt1
->cpu
+ m1
;
167 for (i
= m1
; i
< 1024; i
++, ptr1
++)
170 struct saa7146_pgtable
*pt
= &buf
->pt
[0];
172 return saa7146_pgtable_build_single(pci
, pt
, list
, length
);
179 /********************************************************************************/
180 /* file operations */
182 static int video_begin(struct saa7146_dev
*dev
)
184 struct saa7146_vv
*vv
= dev
->vv_data
;
185 struct saa7146_format
*fmt
= NULL
;
186 unsigned int resource
;
189 DEB_EE("dev:%p\n", dev
);
191 fmt
= saa7146_format_by_fourcc(dev
, vv
->video_fmt
.pixelformat
);
192 /* we need to have a valid format set here */
196 if (0 != (fmt
->flags
& FORMAT_IS_PLANAR
)) {
197 resource
= RESOURCE_DMA1_HPS
|RESOURCE_DMA2_CLP
|RESOURCE_DMA3_BRS
;
199 resource
= RESOURCE_DMA1_HPS
;
202 ret
= saa7146_res_get(dev
, resource
);
204 DEB_S("cannot get capture resource %d\n", resource
);
208 /* clear out beginning of streaming bit (rps register 0)*/
209 saa7146_write(dev
, MC2
, MASK_27
);
211 /* enable rps0 irqs */
212 SAA7146_IER_ENABLE(dev
, MASK_27
);
217 static void video_end(struct saa7146_dev
*dev
)
219 struct saa7146_vv
*vv
= dev
->vv_data
;
220 struct saa7146_format
*fmt
= NULL
;
222 unsigned int resource
;
224 DEB_EE("dev:%p\n", dev
);
226 fmt
= saa7146_format_by_fourcc(dev
, vv
->video_fmt
.pixelformat
);
227 /* we need to have a valid format set here */
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
;
235 resource
= RESOURCE_DMA1_HPS
;
238 spin_lock_irqsave(&dev
->slock
,flags
);
241 saa7146_write(dev
, MC1
, MASK_28
);
243 /* disable rps0 irqs */
244 SAA7146_IER_DISABLE(dev
, MASK_27
);
246 /* shut down all used video dma transfers */
247 saa7146_write(dev
, MC1
, dmas
);
249 spin_unlock_irqrestore(&dev
->slock
, flags
);
251 saa7146_res_free(dev
, resource
);
254 static int vidioc_querycap(struct file
*file
, void *fh
, struct v4l2_capability
*cap
)
256 struct saa7146_dev
*dev
= video_drvdata(file
);
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
;
267 static int vidioc_enum_fmt_vid_cap(struct file
*file
, void *fh
, struct v4l2_fmtdesc
*f
)
269 if (f
->index
>= ARRAY_SIZE(formats
))
271 f
->pixelformat
= formats
[f
->index
].pixelformat
;
275 int saa7146_s_ctrl(struct v4l2_ctrl
*ctrl
)
277 struct saa7146_dev
*dev
= container_of(ctrl
->handler
,
278 struct saa7146_dev
, ctrl_handler
);
279 struct saa7146_vv
*vv
= dev
->vv_data
;
283 case V4L2_CID_BRIGHTNESS
:
284 val
= saa7146_read(dev
, BCS_CTRL
);
286 val
|= (ctrl
->val
<< 24);
287 saa7146_write(dev
, BCS_CTRL
, val
);
288 saa7146_write(dev
, MC2
, MASK_22
| MASK_06
);
291 case V4L2_CID_CONTRAST
:
292 val
= saa7146_read(dev
, BCS_CTRL
);
294 val
|= (ctrl
->val
<< 16);
295 saa7146_write(dev
, BCS_CTRL
, val
);
296 saa7146_write(dev
, MC2
, MASK_22
| MASK_06
);
299 case V4L2_CID_SATURATION
:
300 val
= saa7146_read(dev
, BCS_CTRL
);
302 val
|= (ctrl
->val
<< 0);
303 saa7146_write(dev
, BCS_CTRL
, val
);
304 saa7146_write(dev
, MC2
, MASK_22
| MASK_06
);
308 /* fixme: we can support changing VFLIP and HFLIP here... */
309 if (vb2_is_busy(&vv
->video_dmaq
.q
))
311 vv
->hflip
= ctrl
->val
;
315 if (vb2_is_busy(&vv
->video_dmaq
.q
))
317 vv
->vflip
= ctrl
->val
;
326 static int vidioc_g_parm(struct file
*file
, void *fh
,
327 struct v4l2_streamparm
*parm
)
329 struct saa7146_dev
*dev
= video_drvdata(file
);
330 struct saa7146_vv
*vv
= dev
->vv_data
;
332 if (parm
->type
!= V4L2_BUF_TYPE_VIDEO_CAPTURE
)
334 parm
->parm
.capture
.readbuffers
= 1;
335 v4l2_video_std_frame_period(vv
->standard
->id
,
336 &parm
->parm
.capture
.timeperframe
);
340 static int vidioc_g_fmt_vid_cap(struct file
*file
, void *fh
, struct v4l2_format
*f
)
342 struct saa7146_dev
*dev
= video_drvdata(file
);
343 struct saa7146_vv
*vv
= dev
->vv_data
;
345 f
->fmt
.pix
= vv
->video_fmt
;
349 static int vidioc_g_fmt_vbi_cap(struct file
*file
, void *fh
, struct v4l2_format
*f
)
351 struct saa7146_dev
*dev
= video_drvdata(file
);
352 struct saa7146_vv
*vv
= dev
->vv_data
;
354 f
->fmt
.vbi
= vv
->vbi_fmt
;
358 static int vidioc_try_fmt_vid_cap(struct file
*file
, void *fh
, struct v4l2_format
*f
)
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
;
367 DEB_EE("V4L2_BUF_TYPE_VIDEO_CAPTURE: dev:%p, fh:%p\n", dev
, fh
);
369 fmt
= saa7146_format_by_fourcc(dev
, f
->fmt
.pix
.pixelformat
);
373 field
= f
->fmt
.pix
.field
;
374 maxw
= vv
->standard
->h_max_out
;
375 maxh
= vv
->standard
->v_max_out
;
377 if (V4L2_FIELD_ANY
== field
) {
378 field
= (f
->fmt
.pix
.height
> maxh
/ 2)
379 ? V4L2_FIELD_INTERLACED
383 case V4L2_FIELD_ALTERNATE
:
385 case V4L2_FIELD_BOTTOM
:
389 field
= V4L2_FIELD_INTERLACED
;
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
;
404 calc_bpl
= (f
->fmt
.pix
.width
* fmt
->depth
) / 8;
406 if (f
->fmt
.pix
.bytesperline
< calc_bpl
)
407 f
->fmt
.pix
.bytesperline
= calc_bpl
;
409 if (f
->fmt
.pix
.bytesperline
> (2 * PAGE_SIZE
* fmt
->depth
) / 8) /* arbitrary constraint */
410 f
->fmt
.pix
.bytesperline
= calc_bpl
;
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
);
420 static int vidioc_s_fmt_vid_cap(struct file
*file
, void *fh
, struct v4l2_format
*f
)
422 struct saa7146_dev
*dev
= video_drvdata(file
);
423 struct saa7146_vv
*vv
= dev
->vv_data
;
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");
431 err
= vidioc_try_fmt_vid_cap(file
, fh
, f
);
434 switch (f
->fmt
.pix
.field
) {
435 case V4L2_FIELD_ALTERNATE
:
436 vv
->last_field
= V4L2_FIELD_TOP
;
439 vv
->last_field
= V4L2_FIELD_INTERLACED
;
442 vv
->video_fmt
= f
->fmt
.pix
;
443 DEB_EE("set to pixelformat '%4.4s'\n",
444 (char *)&vv
->video_fmt
.pixelformat
);
448 static int vidioc_g_std(struct file
*file
, void *fh
, v4l2_std_id
*norm
)
450 struct saa7146_dev
*dev
= video_drvdata(file
);
451 struct saa7146_vv
*vv
= dev
->vv_data
;
453 *norm
= vv
->standard
->id
;
457 static int vidioc_s_std(struct file
*file
, void *fh
, v4l2_std_id id
)
459 struct saa7146_dev
*dev
= video_drvdata(file
);
460 struct saa7146_vv
*vv
= dev
->vv_data
;
464 DEB_EE("VIDIOC_S_STD\n");
466 for (i
= 0; i
< dev
->ext_vv_data
->num_stds
; i
++)
467 if (id
& dev
->ext_vv_data
->stds
[i
].id
)
470 if (i
!= dev
->ext_vv_data
->num_stds
&&
471 vv
->standard
== &dev
->ext_vv_data
->stds
[i
])
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");
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
);
487 DEB_EE("VIDIOC_S_STD: standard not found\n");
491 DEB_EE("VIDIOC_S_STD: set to standard to '%s'\n", vv
->standard
->name
);
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
,
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
,
534 /*********************************************************************************/
535 /* buffer handling functions */
537 static int buffer_activate (struct saa7146_dev
*dev
,
538 struct saa7146_buf
*buf
,
539 struct saa7146_buf
*next
)
541 struct saa7146_vv
*vv
= dev
->vv_data
;
543 saa7146_set_capture(dev
,buf
,next
);
545 mod_timer(&vv
->video_dmaq
.timeout
, jiffies
+BUFFER_TIMEOUT
);
549 static void release_all_pagetables(struct saa7146_dev
*dev
, struct saa7146_buf
*buf
)
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]);
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
[])
560 struct saa7146_dev
*dev
= vb2_get_drv_priv(q
);
561 unsigned int size
= dev
->vv_data
->video_fmt
.sizeimage
;
564 return sizes
[0] < size
? -EINVAL
: 0;
571 static void buf_queue(struct vb2_buffer
*vb
)
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
);
579 spin_lock_irqsave(&dev
->slock
, flags
);
581 saa7146_buffer_queue(dev
, &dev
->vv_data
->video_dmaq
, buf
);
582 spin_unlock_irqrestore(&dev
->slock
, flags
);
585 static int buf_init(struct vb2_buffer
*vb
)
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
;
595 buf
->activate
= buffer_activate
;
596 sfmt
= saa7146_format_by_fourcc(dev
, vv
->video_fmt
.pixelformat
);
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]);
603 saa7146_pgtable_alloc(dev
->pci
, &buf
->pt
[0]);
606 ret
= saa7146_pgtable_build(dev
, buf
);
608 release_all_pagetables(dev
, buf
);
612 static int buf_prepare(struct vb2_buffer
*vb
)
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
;
619 if (vb2_plane_size(vb
, 0) < size
)
621 vb2_set_plane_payload(vb
, 0, size
);
625 static void buf_cleanup(struct vb2_buffer
*vb
)
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
);
632 release_all_pagetables(dev
, buf
);
635 static void return_buffers(struct vb2_queue
*q
, int state
)
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
;
644 vb2_buffer_done(&buf
->vb
.vb2_buf
, state
);
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
);
653 static int start_streaming(struct vb2_queue
*q
, unsigned int count
)
655 struct saa7146_dev
*dev
= vb2_get_drv_priv(q
);
658 if (!vb2_is_streaming(&dev
->vv_data
->video_dmaq
.q
))
659 dev
->vv_data
->seqnr
= 0;
660 ret
= video_begin(dev
);
662 return_buffers(q
, VB2_BUF_STATE_QUEUED
);
666 static void stop_streaming(struct vb2_queue
*q
)
668 struct saa7146_dev
*dev
= vb2_get_drv_priv(q
);
669 struct saa7146_dmaqueue
*dq
= &dev
->vv_data
->video_dmaq
;
671 del_timer(&dq
->timeout
);
673 return_buffers(q
, VB2_BUF_STATE_ERROR
);
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
,
686 /********************************************************************************/
687 /* file operations */
689 static void video_init(struct saa7146_dev
*dev
, struct saa7146_vv
*vv
)
691 INIT_LIST_HEAD(&vv
->video_dmaq
.queue
);
693 timer_setup(&vv
->video_dmaq
.timeout
, saa7146_buffer_timeout
, 0);
694 vv
->video_dmaq
.dev
= dev
;
696 /* set some default values */
697 vv
->standard
= &dev
->ext_vv_data
->stds
[0];
699 /* FIXME: what's this? */
700 vv
->current_hps_source
= SAA7146_HPS_SOURCE_PORT_A
;
701 vv
->current_hps_sync
= SAA7146_HPS_SYNC_PORT_A
;
704 static void video_irq_done(struct saa7146_dev
*dev
, unsigned long st
)
706 struct saa7146_vv
*vv
= dev
->vv_data
;
707 struct saa7146_dmaqueue
*q
= &vv
->video_dmaq
;
709 spin_lock(&dev
->slock
);
712 /* only finish the buffer if we have one... */
714 saa7146_buffer_finish(dev
, q
, VB2_BUF_STATE_DONE
);
715 saa7146_buffer_next(dev
,q
,0);
717 spin_unlock(&dev
->slock
);
720 const struct saa7146_use_ops saa7146_video_uops
= {
722 .irq_done
= video_irq_done
,