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