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