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 */
10static 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
69struct 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
86static 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
182static 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
217static 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
254static 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
267static 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
275int 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
326static 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
340static 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
349static 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
358static 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
420static 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
448static 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
457static 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
495const 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
515const 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
537static 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
549static 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
556static 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
571static 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
585static 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
612static 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
625static 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
635static 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
653static 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
666static 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
676const 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
691static 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
706static 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
722const struct saa7146_use_ops saa7146_video_uops = {
723	.init = video_init,
724	.irq_done = video_irq_done,
725};
726