[media] include/media: move driver interface headers to a separate dir
[sfrench/cifs-2.6.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_format *fmt = NULL;
394         unsigned long flags;
395         unsigned int resource;
396         u32 dmas = 0;
397         DEB_EE("dev:%p, fh:%p\n", dev, fh);
398
399         if ((vv->video_status & STATUS_CAPTURE) != STATUS_CAPTURE) {
400                 DEB_S("not capturing\n");
401                 return 0;
402         }
403
404         if (vv->video_fh != fh) {
405                 DEB_S("capturing, but in another open\n");
406                 return -EBUSY;
407         }
408
409         fmt = saa7146_format_by_fourcc(dev, vv->video_fmt.pixelformat);
410         /* we need to have a valid format set here */
411         BUG_ON(NULL == fmt);
412
413         if (0 != (fmt->flags & FORMAT_IS_PLANAR)) {
414                 resource = RESOURCE_DMA1_HPS|RESOURCE_DMA2_CLP|RESOURCE_DMA3_BRS;
415                 dmas = MASK_22 | MASK_21 | MASK_20;
416         } else {
417                 resource = RESOURCE_DMA1_HPS;
418                 dmas = MASK_22;
419         }
420         spin_lock_irqsave(&dev->slock,flags);
421
422         /* disable rps0  */
423         saa7146_write(dev, MC1, MASK_28);
424
425         /* disable rps0 irqs */
426         SAA7146_IER_DISABLE(dev, MASK_27);
427
428         /* shut down all used video dma transfers */
429         saa7146_write(dev, MC1, dmas);
430
431         spin_unlock_irqrestore(&dev->slock, flags);
432
433         vv->video_fh = NULL;
434         vv->video_status = 0;
435
436         saa7146_res_free(fh, resource);
437
438         if (vv->ov_suspend != NULL) {
439                 saa7146_start_preview(vv->ov_suspend);
440                 vv->ov_suspend = NULL;
441         }
442
443         return 0;
444 }
445
446 static int vidioc_querycap(struct file *file, void *fh, struct v4l2_capability *cap)
447 {
448         struct video_device *vdev = video_devdata(file);
449         struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
450
451         strcpy((char *)cap->driver, "saa7146 v4l2");
452         strlcpy((char *)cap->card, dev->ext->name, sizeof(cap->card));
453         sprintf((char *)cap->bus_info, "PCI:%s", pci_name(dev->pci));
454         cap->device_caps =
455                 V4L2_CAP_VIDEO_CAPTURE |
456                 V4L2_CAP_VIDEO_OVERLAY |
457                 V4L2_CAP_READWRITE |
458                 V4L2_CAP_STREAMING;
459         cap->device_caps |= dev->ext_vv_data->capabilities;
460         cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
461         if (vdev->vfl_type == VFL_TYPE_GRABBER)
462                 cap->device_caps &=
463                         ~(V4L2_CAP_VBI_CAPTURE | V4L2_CAP_SLICED_VBI_OUTPUT);
464         else
465                 cap->device_caps &=
466                         ~(V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OVERLAY | V4L2_CAP_AUDIO);
467         return 0;
468 }
469
470 static int vidioc_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb)
471 {
472         struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
473         struct saa7146_vv *vv = dev->vv_data;
474
475         *fb = vv->ov_fb;
476         fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING;
477         fb->flags = V4L2_FBUF_FLAG_PRIMARY;
478         return 0;
479 }
480
481 static int vidioc_s_fbuf(struct file *file, void *fh, const struct v4l2_framebuffer *fb)
482 {
483         struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
484         struct saa7146_vv *vv = dev->vv_data;
485         struct saa7146_format *fmt;
486
487         DEB_EE("VIDIOC_S_FBUF\n");
488
489         if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RAWIO))
490                 return -EPERM;
491
492         /* check args */
493         fmt = saa7146_format_by_fourcc(dev, fb->fmt.pixelformat);
494         if (NULL == fmt)
495                 return -EINVAL;
496
497         /* planar formats are not allowed for overlay video, clipping and video dma would clash */
498         if (fmt->flags & FORMAT_IS_PLANAR)
499                 DEB_S("planar pixelformat '%4.4s' not allowed for overlay\n",
500                       (char *)&fmt->pixelformat);
501
502         /* check if overlay is running */
503         if (IS_OVERLAY_ACTIVE(fh) != 0) {
504                 if (vv->video_fh != fh) {
505                         DEB_D("refusing to change framebuffer informations while overlay is active in another open\n");
506                         return -EBUSY;
507                 }
508         }
509
510         /* ok, accept it */
511         vv->ov_fb = *fb;
512         vv->ov_fmt = fmt;
513
514         if (vv->ov_fb.fmt.bytesperline < vv->ov_fb.fmt.width) {
515                 vv->ov_fb.fmt.bytesperline = vv->ov_fb.fmt.width * fmt->depth / 8;
516                 DEB_D("setting bytesperline to %d\n", vv->ov_fb.fmt.bytesperline);
517         }
518         return 0;
519 }
520
521 static int vidioc_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *f)
522 {
523         if (f->index >= NUM_FORMATS)
524                 return -EINVAL;
525         strlcpy((char *)f->description, formats[f->index].name,
526                         sizeof(f->description));
527         f->pixelformat = formats[f->index].pixelformat;
528         return 0;
529 }
530
531 int saa7146_s_ctrl(struct v4l2_ctrl *ctrl)
532 {
533         struct saa7146_dev *dev = container_of(ctrl->handler,
534                                 struct saa7146_dev, ctrl_handler);
535         struct saa7146_vv *vv = dev->vv_data;
536         u32 val;
537
538         switch (ctrl->id) {
539         case V4L2_CID_BRIGHTNESS:
540                 val = saa7146_read(dev, BCS_CTRL);
541                 val &= 0x00ffffff;
542                 val |= (ctrl->val << 24);
543                 saa7146_write(dev, BCS_CTRL, val);
544                 saa7146_write(dev, MC2, MASK_22 | MASK_06);
545                 break;
546
547         case V4L2_CID_CONTRAST:
548                 val = saa7146_read(dev, BCS_CTRL);
549                 val &= 0xff00ffff;
550                 val |= (ctrl->val << 16);
551                 saa7146_write(dev, BCS_CTRL, val);
552                 saa7146_write(dev, MC2, MASK_22 | MASK_06);
553                 break;
554
555         case V4L2_CID_SATURATION:
556                 val = saa7146_read(dev, BCS_CTRL);
557                 val &= 0xffffff00;
558                 val |= (ctrl->val << 0);
559                 saa7146_write(dev, BCS_CTRL, val);
560                 saa7146_write(dev, MC2, MASK_22 | MASK_06);
561                 break;
562
563         case V4L2_CID_HFLIP:
564                 /* fixme: we can support changing VFLIP and HFLIP here... */
565                 if ((vv->video_status & STATUS_CAPTURE))
566                         return -EBUSY;
567                 vv->hflip = ctrl->val;
568                 break;
569
570         case V4L2_CID_VFLIP:
571                 if ((vv->video_status & STATUS_CAPTURE))
572                         return -EBUSY;
573                 vv->vflip = ctrl->val;
574                 break;
575
576         default:
577                 return -EINVAL;
578         }
579
580         if ((vv->video_status & STATUS_OVERLAY) != 0) { /* CHECK: && (vv->video_fh == fh)) */
581                 struct saa7146_fh *fh = vv->video_fh;
582
583                 saa7146_stop_preview(fh);
584                 saa7146_start_preview(fh);
585         }
586         return 0;
587 }
588
589 static int vidioc_g_parm(struct file *file, void *fh,
590                 struct v4l2_streamparm *parm)
591 {
592         struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
593         struct saa7146_vv *vv = dev->vv_data;
594
595         if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
596                 return -EINVAL;
597         parm->parm.capture.readbuffers = 1;
598         v4l2_video_std_frame_period(vv->standard->id,
599                                     &parm->parm.capture.timeperframe);
600         return 0;
601 }
602
603 static int vidioc_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f)
604 {
605         struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
606         struct saa7146_vv *vv = dev->vv_data;
607
608         f->fmt.pix = vv->video_fmt;
609         return 0;
610 }
611
612 static int vidioc_g_fmt_vid_overlay(struct file *file, void *fh, struct v4l2_format *f)
613 {
614         struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
615         struct saa7146_vv *vv = dev->vv_data;
616
617         f->fmt.win = vv->ov.win;
618         return 0;
619 }
620
621 static int vidioc_g_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *f)
622 {
623         struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
624         struct saa7146_vv *vv = dev->vv_data;
625
626         f->fmt.vbi = vv->vbi_fmt;
627         return 0;
628 }
629
630 static int vidioc_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f)
631 {
632         struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
633         struct saa7146_vv *vv = dev->vv_data;
634         struct saa7146_format *fmt;
635         enum v4l2_field field;
636         int maxw, maxh;
637         int calc_bpl;
638
639         DEB_EE("V4L2_BUF_TYPE_VIDEO_CAPTURE: dev:%p, fh:%p\n", dev, fh);
640
641         fmt = saa7146_format_by_fourcc(dev, f->fmt.pix.pixelformat);
642         if (NULL == fmt)
643                 return -EINVAL;
644
645         field = f->fmt.pix.field;
646         maxw  = vv->standard->h_max_out;
647         maxh  = vv->standard->v_max_out;
648
649         if (V4L2_FIELD_ANY == field) {
650                 field = (f->fmt.pix.height > maxh / 2)
651                         ? V4L2_FIELD_INTERLACED
652                         : V4L2_FIELD_BOTTOM;
653         }
654         switch (field) {
655         case V4L2_FIELD_ALTERNATE:
656                 vv->last_field = V4L2_FIELD_TOP;
657                 maxh = maxh / 2;
658                 break;
659         case V4L2_FIELD_TOP:
660         case V4L2_FIELD_BOTTOM:
661                 vv->last_field = V4L2_FIELD_INTERLACED;
662                 maxh = maxh / 2;
663                 break;
664         case V4L2_FIELD_INTERLACED:
665                 vv->last_field = V4L2_FIELD_INTERLACED;
666                 break;
667         default:
668                 DEB_D("no known field mode '%d'\n", field);
669                 return -EINVAL;
670         }
671
672         f->fmt.pix.field = field;
673         f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
674         if (f->fmt.pix.width > maxw)
675                 f->fmt.pix.width = maxw;
676         if (f->fmt.pix.height > maxh)
677                 f->fmt.pix.height = maxh;
678
679         calc_bpl = (f->fmt.pix.width * fmt->depth) / 8;
680
681         if (f->fmt.pix.bytesperline < calc_bpl)
682                 f->fmt.pix.bytesperline = calc_bpl;
683
684         if (f->fmt.pix.bytesperline > (2 * PAGE_SIZE * fmt->depth) / 8) /* arbitrary constraint */
685                 f->fmt.pix.bytesperline = calc_bpl;
686
687         f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * f->fmt.pix.height;
688         DEB_D("w:%d, h:%d, bytesperline:%d, sizeimage:%d\n",
689               f->fmt.pix.width, f->fmt.pix.height,
690               f->fmt.pix.bytesperline, f->fmt.pix.sizeimage);
691
692         return 0;
693 }
694
695
696 static int vidioc_try_fmt_vid_overlay(struct file *file, void *fh, struct v4l2_format *f)
697 {
698         struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
699         struct saa7146_vv *vv = dev->vv_data;
700         struct v4l2_window *win = &f->fmt.win;
701         enum v4l2_field field;
702         int maxw, maxh;
703
704         DEB_EE("dev:%p\n", dev);
705
706         if (NULL == vv->ov_fb.base) {
707                 DEB_D("no fb base set\n");
708                 return -EINVAL;
709         }
710         if (NULL == vv->ov_fmt) {
711                 DEB_D("no fb fmt set\n");
712                 return -EINVAL;
713         }
714         if (win->w.width < 48 || win->w.height < 32) {
715                 DEB_D("min width/height. (%d,%d)\n",
716                       win->w.width, win->w.height);
717                 return -EINVAL;
718         }
719         if (win->clipcount > 16) {
720                 DEB_D("clipcount too big\n");
721                 return -EINVAL;
722         }
723
724         field = win->field;
725         maxw  = vv->standard->h_max_out;
726         maxh  = vv->standard->v_max_out;
727
728         if (V4L2_FIELD_ANY == field) {
729                 field = (win->w.height > maxh / 2)
730                         ? V4L2_FIELD_INTERLACED
731                         : V4L2_FIELD_TOP;
732                 }
733         switch (field) {
734         case V4L2_FIELD_TOP:
735         case V4L2_FIELD_BOTTOM:
736         case V4L2_FIELD_ALTERNATE:
737                 maxh = maxh / 2;
738                 break;
739         case V4L2_FIELD_INTERLACED:
740                 break;
741         default:
742                 DEB_D("no known field mode '%d'\n", field);
743                 return -EINVAL;
744         }
745
746         win->field = field;
747         if (win->w.width > maxw)
748                 win->w.width = maxw;
749         if (win->w.height > maxh)
750                 win->w.height = maxh;
751
752         return 0;
753 }
754
755 static int vidioc_s_fmt_vid_cap(struct file *file, void *__fh, struct v4l2_format *f)
756 {
757         struct saa7146_fh *fh = __fh;
758         struct saa7146_dev *dev = fh->dev;
759         struct saa7146_vv *vv = dev->vv_data;
760         int err;
761
762         DEB_EE("V4L2_BUF_TYPE_VIDEO_CAPTURE: dev:%p, fh:%p\n", dev, fh);
763         if (IS_CAPTURE_ACTIVE(fh) != 0) {
764                 DEB_EE("streaming capture is active\n");
765                 return -EBUSY;
766         }
767         err = vidioc_try_fmt_vid_cap(file, fh, f);
768         if (0 != err)
769                 return err;
770         vv->video_fmt = f->fmt.pix;
771         DEB_EE("set to pixelformat '%4.4s'\n",
772                (char *)&vv->video_fmt.pixelformat);
773         return 0;
774 }
775
776 static int vidioc_s_fmt_vid_overlay(struct file *file, void *__fh, struct v4l2_format *f)
777 {
778         struct saa7146_fh *fh = __fh;
779         struct saa7146_dev *dev = fh->dev;
780         struct saa7146_vv *vv = dev->vv_data;
781         int err;
782
783         DEB_EE("V4L2_BUF_TYPE_VIDEO_OVERLAY: dev:%p, fh:%p\n", dev, fh);
784         err = vidioc_try_fmt_vid_overlay(file, fh, f);
785         if (0 != err)
786                 return err;
787         vv->ov.win    = f->fmt.win;
788         vv->ov.nclips = f->fmt.win.clipcount;
789         if (vv->ov.nclips > 16)
790                 vv->ov.nclips = 16;
791         if (copy_from_user(vv->ov.clips, f->fmt.win.clips,
792                                 sizeof(struct v4l2_clip) * vv->ov.nclips)) {
793                 return -EFAULT;
794         }
795
796         /* vv->ov.fh is used to indicate that we have valid overlay informations, too */
797         vv->ov.fh = fh;
798
799         /* check if our current overlay is active */
800         if (IS_OVERLAY_ACTIVE(fh) != 0) {
801                 saa7146_stop_preview(fh);
802                 saa7146_start_preview(fh);
803         }
804         return 0;
805 }
806
807 static int vidioc_g_std(struct file *file, void *fh, v4l2_std_id *norm)
808 {
809         struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
810         struct saa7146_vv *vv = dev->vv_data;
811
812         *norm = vv->standard->id;
813         return 0;
814 }
815
816         /* the saa7146 supfhrts (used in conjunction with the saa7111a for example)
817            PAL / NTSC / SECAM. if your hardware does not (or does more)
818            -- override this function in your extension */
819 /*
820         case VIDIOC_ENUMSTD:
821         {
822                 struct v4l2_standard *e = arg;
823                 if (e->index < 0 )
824                         return -EINVAL;
825                 if( e->index < dev->ext_vv_data->num_stds ) {
826                         DEB_EE("VIDIOC_ENUMSTD: index:%d\n", e->index);
827                         v4l2_video_std_construct(e, dev->ext_vv_data->stds[e->index].id, dev->ext_vv_data->stds[e->index].name);
828                         return 0;
829                 }
830                 return -EINVAL;
831         }
832         */
833
834 static int vidioc_s_std(struct file *file, void *fh, v4l2_std_id id)
835 {
836         struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
837         struct saa7146_vv *vv = dev->vv_data;
838         int found = 0;
839         int err, i;
840
841         DEB_EE("VIDIOC_S_STD\n");
842
843         if ((vv->video_status & STATUS_CAPTURE) == STATUS_CAPTURE) {
844                 DEB_D("cannot change video standard while streaming capture is active\n");
845                 return -EBUSY;
846         }
847
848         if ((vv->video_status & STATUS_OVERLAY) != 0) {
849                 vv->ov_suspend = vv->video_fh;
850                 err = saa7146_stop_preview(vv->video_fh); /* side effect: video_status is now 0, video_fh is NULL */
851                 if (0 != err) {
852                         DEB_D("suspending video failed. aborting\n");
853                         return err;
854                 }
855         }
856
857         for (i = 0; i < dev->ext_vv_data->num_stds; i++)
858                 if (id & dev->ext_vv_data->stds[i].id)
859                         break;
860         if (i != dev->ext_vv_data->num_stds) {
861                 vv->standard = &dev->ext_vv_data->stds[i];
862                 if (NULL != dev->ext_vv_data->std_callback)
863                         dev->ext_vv_data->std_callback(dev, vv->standard);
864                 found = 1;
865         }
866
867         if (vv->ov_suspend != NULL) {
868                 saa7146_start_preview(vv->ov_suspend);
869                 vv->ov_suspend = NULL;
870         }
871
872         if (!found) {
873                 DEB_EE("VIDIOC_S_STD: standard not found\n");
874                 return -EINVAL;
875         }
876
877         DEB_EE("VIDIOC_S_STD: set to standard to '%s'\n", vv->standard->name);
878         return 0;
879 }
880
881 static int vidioc_overlay(struct file *file, void *fh, unsigned int on)
882 {
883         int err;
884
885         DEB_D("VIDIOC_OVERLAY on:%d\n", on);
886         if (on)
887                 err = saa7146_start_preview(fh);
888         else
889                 err = saa7146_stop_preview(fh);
890         return err;
891 }
892
893 static int vidioc_reqbufs(struct file *file, void *__fh, struct v4l2_requestbuffers *b)
894 {
895         struct saa7146_fh *fh = __fh;
896
897         if (b->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
898                 return videobuf_reqbufs(&fh->video_q, b);
899         if (b->type == V4L2_BUF_TYPE_VBI_CAPTURE)
900                 return videobuf_reqbufs(&fh->vbi_q, b);
901         return -EINVAL;
902 }
903
904 static int vidioc_querybuf(struct file *file, void *__fh, struct v4l2_buffer *buf)
905 {
906         struct saa7146_fh *fh = __fh;
907
908         if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
909                 return videobuf_querybuf(&fh->video_q, buf);
910         if (buf->type == V4L2_BUF_TYPE_VBI_CAPTURE)
911                 return videobuf_querybuf(&fh->vbi_q, buf);
912         return -EINVAL;
913 }
914
915 static int vidioc_qbuf(struct file *file, void *__fh, struct v4l2_buffer *buf)
916 {
917         struct saa7146_fh *fh = __fh;
918
919         if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
920                 return videobuf_qbuf(&fh->video_q, buf);
921         if (buf->type == V4L2_BUF_TYPE_VBI_CAPTURE)
922                 return videobuf_qbuf(&fh->vbi_q, buf);
923         return -EINVAL;
924 }
925
926 static int vidioc_dqbuf(struct file *file, void *__fh, struct v4l2_buffer *buf)
927 {
928         struct saa7146_fh *fh = __fh;
929
930         if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
931                 return videobuf_dqbuf(&fh->video_q, buf, file->f_flags & O_NONBLOCK);
932         if (buf->type == V4L2_BUF_TYPE_VBI_CAPTURE)
933                 return videobuf_dqbuf(&fh->vbi_q, buf, file->f_flags & O_NONBLOCK);
934         return -EINVAL;
935 }
936
937 static int vidioc_streamon(struct file *file, void *__fh, enum v4l2_buf_type type)
938 {
939         struct saa7146_fh *fh = __fh;
940         int err;
941
942         DEB_D("VIDIOC_STREAMON, type:%d\n", type);
943
944         err = video_begin(fh);
945         if (err)
946                 return err;
947         if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
948                 return videobuf_streamon(&fh->video_q);
949         if (type == V4L2_BUF_TYPE_VBI_CAPTURE)
950                 return videobuf_streamon(&fh->vbi_q);
951         return -EINVAL;
952 }
953
954 static int vidioc_streamoff(struct file *file, void *__fh, enum v4l2_buf_type type)
955 {
956         struct saa7146_fh *fh = __fh;
957         struct saa7146_dev *dev = fh->dev;
958         struct saa7146_vv *vv = dev->vv_data;
959         int err;
960
961         DEB_D("VIDIOC_STREAMOFF, type:%d\n", type);
962
963         /* ugly: we need to copy some checks from video_end(),
964            because videobuf_streamoff() relies on the capture running.
965            check and fix this */
966         if ((vv->video_status & STATUS_CAPTURE) != STATUS_CAPTURE) {
967                 DEB_S("not capturing\n");
968                 return 0;
969         }
970
971         if (vv->video_fh != fh) {
972                 DEB_S("capturing, but in another open\n");
973                 return -EBUSY;
974         }
975
976         err = -EINVAL;
977         if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
978                 err = videobuf_streamoff(&fh->video_q);
979         else if (type == V4L2_BUF_TYPE_VBI_CAPTURE)
980                 err = videobuf_streamoff(&fh->vbi_q);
981         if (0 != err) {
982                 DEB_D("warning: videobuf_streamoff() failed\n");
983                 video_end(fh, file);
984         } else {
985                 err = video_end(fh, file);
986         }
987         return err;
988 }
989
990 const struct v4l2_ioctl_ops saa7146_video_ioctl_ops = {
991         .vidioc_querycap             = vidioc_querycap,
992         .vidioc_enum_fmt_vid_cap     = vidioc_enum_fmt_vid_cap,
993         .vidioc_enum_fmt_vid_overlay = vidioc_enum_fmt_vid_cap,
994         .vidioc_g_fmt_vid_cap        = vidioc_g_fmt_vid_cap,
995         .vidioc_try_fmt_vid_cap      = vidioc_try_fmt_vid_cap,
996         .vidioc_s_fmt_vid_cap        = vidioc_s_fmt_vid_cap,
997         .vidioc_g_fmt_vid_overlay    = vidioc_g_fmt_vid_overlay,
998         .vidioc_try_fmt_vid_overlay  = vidioc_try_fmt_vid_overlay,
999         .vidioc_s_fmt_vid_overlay    = vidioc_s_fmt_vid_overlay,
1000
1001         .vidioc_overlay              = vidioc_overlay,
1002         .vidioc_g_fbuf               = vidioc_g_fbuf,
1003         .vidioc_s_fbuf               = vidioc_s_fbuf,
1004         .vidioc_reqbufs              = vidioc_reqbufs,
1005         .vidioc_querybuf             = vidioc_querybuf,
1006         .vidioc_qbuf                 = vidioc_qbuf,
1007         .vidioc_dqbuf                = vidioc_dqbuf,
1008         .vidioc_g_std                = vidioc_g_std,
1009         .vidioc_s_std                = vidioc_s_std,
1010         .vidioc_streamon             = vidioc_streamon,
1011         .vidioc_streamoff            = vidioc_streamoff,
1012         .vidioc_g_parm               = vidioc_g_parm,
1013         .vidioc_subscribe_event      = v4l2_ctrl_subscribe_event,
1014         .vidioc_unsubscribe_event    = v4l2_event_unsubscribe,
1015 };
1016
1017 const struct v4l2_ioctl_ops saa7146_vbi_ioctl_ops = {
1018         .vidioc_querycap             = vidioc_querycap,
1019         .vidioc_g_fmt_vbi_cap        = vidioc_g_fmt_vbi_cap,
1020
1021         .vidioc_reqbufs              = vidioc_reqbufs,
1022         .vidioc_querybuf             = vidioc_querybuf,
1023         .vidioc_qbuf                 = vidioc_qbuf,
1024         .vidioc_dqbuf                = vidioc_dqbuf,
1025         .vidioc_g_std                = vidioc_g_std,
1026         .vidioc_s_std                = vidioc_s_std,
1027         .vidioc_streamon             = vidioc_streamon,
1028         .vidioc_streamoff            = vidioc_streamoff,
1029         .vidioc_g_parm               = vidioc_g_parm,
1030         .vidioc_subscribe_event      = v4l2_ctrl_subscribe_event,
1031         .vidioc_unsubscribe_event    = v4l2_event_unsubscribe,
1032 };
1033
1034 /*********************************************************************************/
1035 /* buffer handling functions                                                  */
1036
1037 static int buffer_activate (struct saa7146_dev *dev,
1038                      struct saa7146_buf *buf,
1039                      struct saa7146_buf *next)
1040 {
1041         struct saa7146_vv *vv = dev->vv_data;
1042
1043         buf->vb.state = VIDEOBUF_ACTIVE;
1044         saa7146_set_capture(dev,buf,next);
1045
1046         mod_timer(&vv->video_dmaq.timeout, jiffies+BUFFER_TIMEOUT);
1047         return 0;
1048 }
1049
1050 static void release_all_pagetables(struct saa7146_dev *dev, struct saa7146_buf *buf)
1051 {
1052         saa7146_pgtable_free(dev->pci, &buf->pt[0]);
1053         saa7146_pgtable_free(dev->pci, &buf->pt[1]);
1054         saa7146_pgtable_free(dev->pci, &buf->pt[2]);
1055 }
1056
1057 static int buffer_prepare(struct videobuf_queue *q,
1058                           struct videobuf_buffer *vb, enum v4l2_field field)
1059 {
1060         struct file *file = q->priv_data;
1061         struct saa7146_fh *fh = file->private_data;
1062         struct saa7146_dev *dev = fh->dev;
1063         struct saa7146_vv *vv = dev->vv_data;
1064         struct saa7146_buf *buf = (struct saa7146_buf *)vb;
1065         int size,err = 0;
1066
1067         DEB_CAP("vbuf:%p\n", vb);
1068
1069         /* sanity checks */
1070         if (vv->video_fmt.width  < 48 ||
1071             vv->video_fmt.height < 32 ||
1072             vv->video_fmt.width  > vv->standard->h_max_out ||
1073             vv->video_fmt.height > vv->standard->v_max_out) {
1074                 DEB_D("w (%d) / h (%d) out of bounds\n",
1075                       vv->video_fmt.width, vv->video_fmt.height);
1076                 return -EINVAL;
1077         }
1078
1079         size = vv->video_fmt.sizeimage;
1080         if (0 != buf->vb.baddr && buf->vb.bsize < size) {
1081                 DEB_D("size mismatch\n");
1082                 return -EINVAL;
1083         }
1084
1085         DEB_CAP("buffer_prepare [size=%dx%d,bytes=%d,fields=%s]\n",
1086                 vv->video_fmt.width, vv->video_fmt.height,
1087                 size, v4l2_field_names[vv->video_fmt.field]);
1088         if (buf->vb.width  != vv->video_fmt.width  ||
1089             buf->vb.bytesperline != vv->video_fmt.bytesperline ||
1090             buf->vb.height != vv->video_fmt.height ||
1091             buf->vb.size   != size ||
1092             buf->vb.field  != field      ||
1093             buf->vb.field  != vv->video_fmt.field  ||
1094             buf->fmt       != &vv->video_fmt) {
1095                 saa7146_dma_free(dev,q,buf);
1096         }
1097
1098         if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
1099                 struct saa7146_format *sfmt;
1100
1101                 buf->vb.bytesperline  = vv->video_fmt.bytesperline;
1102                 buf->vb.width  = vv->video_fmt.width;
1103                 buf->vb.height = vv->video_fmt.height;
1104                 buf->vb.size   = size;
1105                 buf->vb.field  = field;
1106                 buf->fmt       = &vv->video_fmt;
1107                 buf->vb.field  = vv->video_fmt.field;
1108
1109                 sfmt = saa7146_format_by_fourcc(dev,buf->fmt->pixelformat);
1110
1111                 release_all_pagetables(dev, buf);
1112                 if( 0 != IS_PLANAR(sfmt->trans)) {
1113                         saa7146_pgtable_alloc(dev->pci, &buf->pt[0]);
1114                         saa7146_pgtable_alloc(dev->pci, &buf->pt[1]);
1115                         saa7146_pgtable_alloc(dev->pci, &buf->pt[2]);
1116                 } else {
1117                         saa7146_pgtable_alloc(dev->pci, &buf->pt[0]);
1118                 }
1119
1120                 err = videobuf_iolock(q,&buf->vb, &vv->ov_fb);
1121                 if (err)
1122                         goto oops;
1123                 err = saa7146_pgtable_build(dev,buf);
1124                 if (err)
1125                         goto oops;
1126         }
1127         buf->vb.state = VIDEOBUF_PREPARED;
1128         buf->activate = buffer_activate;
1129
1130         return 0;
1131
1132  oops:
1133         DEB_D("error out\n");
1134         saa7146_dma_free(dev,q,buf);
1135
1136         return err;
1137 }
1138
1139 static int buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size)
1140 {
1141         struct file *file = q->priv_data;
1142         struct saa7146_fh *fh = file->private_data;
1143         struct saa7146_vv *vv = fh->dev->vv_data;
1144
1145         if (0 == *count || *count > MAX_SAA7146_CAPTURE_BUFFERS)
1146                 *count = MAX_SAA7146_CAPTURE_BUFFERS;
1147
1148         *size = vv->video_fmt.sizeimage;
1149
1150         /* check if we exceed the "max_memory" parameter */
1151         if( (*count * *size) > (max_memory*1048576) ) {
1152                 *count = (max_memory*1048576) / *size;
1153         }
1154
1155         DEB_CAP("%d buffers, %d bytes each\n", *count, *size);
1156
1157         return 0;
1158 }
1159
1160 static void buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
1161 {
1162         struct file *file = q->priv_data;
1163         struct saa7146_fh *fh = file->private_data;
1164         struct saa7146_dev *dev = fh->dev;
1165         struct saa7146_vv *vv = dev->vv_data;
1166         struct saa7146_buf *buf = (struct saa7146_buf *)vb;
1167
1168         DEB_CAP("vbuf:%p\n", vb);
1169         saa7146_buffer_queue(fh->dev, &vv->video_dmaq, buf);
1170 }
1171
1172 static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
1173 {
1174         struct file *file = q->priv_data;
1175         struct saa7146_fh *fh = file->private_data;
1176         struct saa7146_dev *dev = fh->dev;
1177         struct saa7146_buf *buf = (struct saa7146_buf *)vb;
1178
1179         DEB_CAP("vbuf:%p\n", vb);
1180
1181         saa7146_dma_free(dev,q,buf);
1182
1183         release_all_pagetables(dev, buf);
1184 }
1185
1186 static struct videobuf_queue_ops video_qops = {
1187         .buf_setup    = buffer_setup,
1188         .buf_prepare  = buffer_prepare,
1189         .buf_queue    = buffer_queue,
1190         .buf_release  = buffer_release,
1191 };
1192
1193 /********************************************************************************/
1194 /* file operations */
1195
1196 static void video_init(struct saa7146_dev *dev, struct saa7146_vv *vv)
1197 {
1198         INIT_LIST_HEAD(&vv->video_dmaq.queue);
1199
1200         init_timer(&vv->video_dmaq.timeout);
1201         vv->video_dmaq.timeout.function = saa7146_buffer_timeout;
1202         vv->video_dmaq.timeout.data     = (unsigned long)(&vv->video_dmaq);
1203         vv->video_dmaq.dev              = dev;
1204
1205         /* set some default values */
1206         vv->standard = &dev->ext_vv_data->stds[0];
1207
1208         /* FIXME: what's this? */
1209         vv->current_hps_source = SAA7146_HPS_SOURCE_PORT_A;
1210         vv->current_hps_sync = SAA7146_HPS_SYNC_PORT_A;
1211 }
1212
1213
1214 static int video_open(struct saa7146_dev *dev, struct file *file)
1215 {
1216         struct saa7146_fh *fh = file->private_data;
1217
1218         videobuf_queue_sg_init(&fh->video_q, &video_qops,
1219                             &dev->pci->dev, &dev->slock,
1220                             V4L2_BUF_TYPE_VIDEO_CAPTURE,
1221                             V4L2_FIELD_INTERLACED,
1222                             sizeof(struct saa7146_buf),
1223                             file, &dev->v4l2_lock);
1224
1225         return 0;
1226 }
1227
1228
1229 static void video_close(struct saa7146_dev *dev, struct file *file)
1230 {
1231         struct saa7146_fh *fh = file->private_data;
1232         struct saa7146_vv *vv = dev->vv_data;
1233         struct videobuf_queue *q = &fh->video_q;
1234
1235         if (IS_CAPTURE_ACTIVE(fh) != 0)
1236                 video_end(fh, file);
1237         else if (IS_OVERLAY_ACTIVE(fh) != 0)
1238                 saa7146_stop_preview(fh);
1239
1240         videobuf_stop(q);
1241         /* hmm, why is this function declared void? */
1242 }
1243
1244
1245 static void video_irq_done(struct saa7146_dev *dev, unsigned long st)
1246 {
1247         struct saa7146_vv *vv = dev->vv_data;
1248         struct saa7146_dmaqueue *q = &vv->video_dmaq;
1249
1250         spin_lock(&dev->slock);
1251         DEB_CAP("called\n");
1252
1253         /* only finish the buffer if we have one... */
1254         if( NULL != q->curr ) {
1255                 saa7146_buffer_finish(dev,q,VIDEOBUF_DONE);
1256         }
1257         saa7146_buffer_next(dev,q,0);
1258
1259         spin_unlock(&dev->slock);
1260 }
1261
1262 static ssize_t video_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
1263 {
1264         struct saa7146_fh *fh = file->private_data;
1265         struct saa7146_dev *dev = fh->dev;
1266         struct saa7146_vv *vv = dev->vv_data;
1267         ssize_t ret = 0;
1268
1269         DEB_EE("called\n");
1270
1271         if ((vv->video_status & STATUS_CAPTURE) != 0) {
1272                 /* fixme: should we allow read() captures while streaming capture? */
1273                 if (vv->video_fh == fh) {
1274                         DEB_S("already capturing\n");
1275                         return -EBUSY;
1276                 }
1277                 DEB_S("already capturing in another open\n");
1278                 return -EBUSY;
1279         }
1280
1281         ret = video_begin(fh);
1282         if( 0 != ret) {
1283                 goto out;
1284         }
1285
1286         ret = videobuf_read_one(&fh->video_q , data, count, ppos,
1287                                 file->f_flags & O_NONBLOCK);
1288         if (ret != 0) {
1289                 video_end(fh, file);
1290         } else {
1291                 ret = video_end(fh, file);
1292         }
1293 out:
1294         /* restart overlay if it was active before */
1295         if (vv->ov_suspend != NULL) {
1296                 saa7146_start_preview(vv->ov_suspend);
1297                 vv->ov_suspend = NULL;
1298         }
1299
1300         return ret;
1301 }
1302
1303 struct saa7146_use_ops saa7146_video_uops = {
1304         .init = video_init,
1305         .open = video_open,
1306         .release = video_close,
1307         .irq_done = video_irq_done,
1308         .read = video_read,
1309 };