Merge branch 'linus' into tracing/ftrace
[linux-2.6] / drivers / media / video / v4l1-compat.c
1 /*
2  *
3  *      Video for Linux Two
4  *      Backward Compatibility Layer
5  *
6  *      Support subroutines for providing V4L2 drivers with backward
7  *      compatibility with applications using the old API.
8  *
9  *      This program is free software; you can redistribute it and/or
10  *      modify it under the terms of the GNU General Public License
11  *      as published by the Free Software Foundation; either version
12  *      2 of the License, or (at your option) any later version.
13  *
14  * Author:      Bill Dirks <bill@thedirks.org>
15  *              et al.
16  *
17  */
18
19
20 #include <linux/init.h>
21 #include <linux/module.h>
22 #include <linux/types.h>
23 #include <linux/kernel.h>
24 #include <linux/sched.h>
25 #include <linux/mm.h>
26 #include <linux/fs.h>
27 #include <linux/file.h>
28 #include <linux/string.h>
29 #include <linux/errno.h>
30 #include <linux/slab.h>
31 #include <linux/videodev.h>
32 #include <media/v4l2-common.h>
33
34 #include <asm/uaccess.h>
35 #include <asm/system.h>
36 #include <asm/pgtable.h>
37
38 #ifdef CONFIG_KMOD
39 #include <linux/kmod.h>
40 #endif
41
42 static unsigned int debug;
43 module_param(debug, int, 0644);
44 MODULE_PARM_DESC(debug, "enable debug messages");
45 MODULE_AUTHOR("Bill Dirks");
46 MODULE_DESCRIPTION("v4l(1) compatibility layer for v4l2 drivers.");
47 MODULE_LICENSE("GPL");
48
49 #define dprintk(fmt, arg...) \
50         do { \
51                 if (debug) \
52                         printk(KERN_DEBUG "v4l1-compat: " fmt , ## arg);\
53         } while (0)
54
55 /*
56  *      I O C T L   T R A N S L A T I O N
57  *
58  *      From here on down is the code for translating the numerous
59  *      ioctl commands from the old API to the new API.
60  */
61
62 static int
63 get_v4l_control(struct inode            *inode,
64                 struct file             *file,
65                 int                     cid,
66                 v4l2_kioctl             drv)
67 {
68         struct v4l2_queryctrl   qctrl2;
69         struct v4l2_control     ctrl2;
70         int                     err;
71
72         qctrl2.id = cid;
73         err = drv(inode, file, VIDIOC_QUERYCTRL, &qctrl2);
74         if (err < 0)
75                 dprintk("VIDIOC_QUERYCTRL: %d\n", err);
76         if (err == 0 && !(qctrl2.flags & V4L2_CTRL_FLAG_DISABLED)) {
77                 ctrl2.id = qctrl2.id;
78                 err = drv(inode, file, VIDIOC_G_CTRL, &ctrl2);
79                 if (err < 0) {
80                         dprintk("VIDIOC_G_CTRL: %d\n", err);
81                         return 0;
82                 }
83                 return ((ctrl2.value - qctrl2.minimum) * 65535
84                          + (qctrl2.maximum - qctrl2.minimum) / 2)
85                         / (qctrl2.maximum - qctrl2.minimum);
86         }
87         return 0;
88 }
89
90 static int
91 set_v4l_control(struct inode            *inode,
92                 struct file             *file,
93                 int                     cid,
94                 int                     value,
95                 v4l2_kioctl             drv)
96 {
97         struct v4l2_queryctrl   qctrl2;
98         struct v4l2_control     ctrl2;
99         int                     err;
100
101         qctrl2.id = cid;
102         err = drv(inode, file, VIDIOC_QUERYCTRL, &qctrl2);
103         if (err < 0)
104                 dprintk("VIDIOC_QUERYCTRL: %d\n", err);
105         if (err == 0 &&
106             !(qctrl2.flags & V4L2_CTRL_FLAG_DISABLED) &&
107             !(qctrl2.flags & V4L2_CTRL_FLAG_GRABBED)) {
108                 if (value < 0)
109                         value = 0;
110                 if (value > 65535)
111                         value = 65535;
112                 if (value && qctrl2.type == V4L2_CTRL_TYPE_BOOLEAN)
113                         value = 65535;
114                 ctrl2.id = qctrl2.id;
115                 ctrl2.value =
116                         (value * (qctrl2.maximum - qctrl2.minimum)
117                          + 32767)
118                         / 65535;
119                 ctrl2.value += qctrl2.minimum;
120                 err = drv(inode, file, VIDIOC_S_CTRL, &ctrl2);
121                 if (err < 0)
122                         dprintk("VIDIOC_S_CTRL: %d\n", err);
123         }
124         return 0;
125 }
126
127 /* ----------------------------------------------------------------- */
128
129 static const unsigned int palette2pixelformat[] = {
130         [VIDEO_PALETTE_GREY]    = V4L2_PIX_FMT_GREY,
131         [VIDEO_PALETTE_RGB555]  = V4L2_PIX_FMT_RGB555,
132         [VIDEO_PALETTE_RGB565]  = V4L2_PIX_FMT_RGB565,
133         [VIDEO_PALETTE_RGB24]   = V4L2_PIX_FMT_BGR24,
134         [VIDEO_PALETTE_RGB32]   = V4L2_PIX_FMT_BGR32,
135         /* yuv packed pixel */
136         [VIDEO_PALETTE_YUYV]    = V4L2_PIX_FMT_YUYV,
137         [VIDEO_PALETTE_YUV422]  = V4L2_PIX_FMT_YUYV,
138         [VIDEO_PALETTE_UYVY]    = V4L2_PIX_FMT_UYVY,
139         /* yuv planar */
140         [VIDEO_PALETTE_YUV410P] = V4L2_PIX_FMT_YUV410,
141         [VIDEO_PALETTE_YUV420]  = V4L2_PIX_FMT_YUV420,
142         [VIDEO_PALETTE_YUV420P] = V4L2_PIX_FMT_YUV420,
143         [VIDEO_PALETTE_YUV411P] = V4L2_PIX_FMT_YUV411P,
144         [VIDEO_PALETTE_YUV422P] = V4L2_PIX_FMT_YUV422P,
145 };
146
147 static unsigned int __pure
148 palette_to_pixelformat(unsigned int palette)
149 {
150         if (palette < ARRAY_SIZE(palette2pixelformat))
151                 return palette2pixelformat[palette];
152         else
153                 return 0;
154 }
155
156 static unsigned int __attribute_const__
157 pixelformat_to_palette(unsigned int pixelformat)
158 {
159         int     palette = 0;
160         switch (pixelformat) {
161         case V4L2_PIX_FMT_GREY:
162                 palette = VIDEO_PALETTE_GREY;
163                 break;
164         case V4L2_PIX_FMT_RGB555:
165                 palette = VIDEO_PALETTE_RGB555;
166                 break;
167         case V4L2_PIX_FMT_RGB565:
168                 palette = VIDEO_PALETTE_RGB565;
169                 break;
170         case V4L2_PIX_FMT_BGR24:
171                 palette = VIDEO_PALETTE_RGB24;
172                 break;
173         case V4L2_PIX_FMT_BGR32:
174                 palette = VIDEO_PALETTE_RGB32;
175                 break;
176         /* yuv packed pixel */
177         case V4L2_PIX_FMT_YUYV:
178                 palette = VIDEO_PALETTE_YUYV;
179                 break;
180         case V4L2_PIX_FMT_UYVY:
181                 palette = VIDEO_PALETTE_UYVY;
182                 break;
183         /* yuv planar */
184         case V4L2_PIX_FMT_YUV410:
185                 palette = VIDEO_PALETTE_YUV420;
186                 break;
187         case V4L2_PIX_FMT_YUV420:
188                 palette = VIDEO_PALETTE_YUV420;
189                 break;
190         case V4L2_PIX_FMT_YUV411P:
191                 palette = VIDEO_PALETTE_YUV411P;
192                 break;
193         case V4L2_PIX_FMT_YUV422P:
194                 palette = VIDEO_PALETTE_YUV422P;
195                 break;
196         }
197         return palette;
198 }
199
200 /* ----------------------------------------------------------------- */
201
202 static int poll_one(struct file *file, struct poll_wqueues *pwq)
203 {
204         int retval = 1;
205         poll_table *table;
206
207         poll_initwait(pwq);
208         table = &pwq->pt;
209         for (;;) {
210                 int mask;
211                 set_current_state(TASK_INTERRUPTIBLE);
212                 mask = file->f_op->poll(file, table);
213                 if (mask & POLLIN)
214                         break;
215                 table = NULL;
216                 if (signal_pending(current)) {
217                         retval = -ERESTARTSYS;
218                         break;
219                 }
220                 schedule();
221         }
222         set_current_state(TASK_RUNNING);
223         poll_freewait(pwq);
224         return retval;
225 }
226
227 static int count_inputs(
228                         struct inode *inode,
229                         struct file *file,
230                         v4l2_kioctl drv)
231 {
232         struct v4l2_input input2;
233         int i;
234
235         for (i = 0;; i++) {
236                 memset(&input2, 0, sizeof(input2));
237                 input2.index = i;
238                 if (0 != drv(inode, file, VIDIOC_ENUMINPUT, &input2))
239                         break;
240         }
241         return i;
242 }
243
244 static int check_size(
245                 struct inode *inode,
246                 struct file *file,
247                 v4l2_kioctl drv,
248                 int *maxw,
249                 int *maxh)
250 {
251         struct v4l2_fmtdesc desc2;
252         struct v4l2_format  fmt2;
253
254         memset(&desc2, 0, sizeof(desc2));
255         memset(&fmt2, 0, sizeof(fmt2));
256
257         desc2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
258         if (0 != drv(inode, file, VIDIOC_ENUM_FMT, &desc2))
259                 goto done;
260
261         fmt2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
262         fmt2.fmt.pix.width       = 10000;
263         fmt2.fmt.pix.height      = 10000;
264         fmt2.fmt.pix.pixelformat = desc2.pixelformat;
265         if (0 != drv(inode, file, VIDIOC_TRY_FMT, &fmt2))
266                 goto done;
267
268         *maxw = fmt2.fmt.pix.width;
269         *maxh = fmt2.fmt.pix.height;
270
271 done:
272         return 0;
273 }
274
275 /* ----------------------------------------------------------------- */
276
277 static noinline int v4l1_compat_get_capabilities(
278                                         struct video_capability *cap,
279                                         struct inode *inode,
280                                         struct file *file,
281                                         v4l2_kioctl drv)
282 {
283         int err;
284         struct v4l2_framebuffer fbuf;
285         struct v4l2_capability *cap2;
286
287         cap2 = kzalloc(sizeof(*cap2), GFP_KERNEL);
288         if (!cap2) {
289                 err = -ENOMEM;
290                 return err;
291         }
292         memset(cap, 0, sizeof(*cap));
293         memset(&fbuf, 0, sizeof(fbuf));
294
295         err = drv(inode, file, VIDIOC_QUERYCAP, cap2);
296         if (err < 0) {
297                 dprintk("VIDIOCGCAP / VIDIOC_QUERYCAP: %d\n", err);
298                 goto done;
299         }
300         if (cap2->capabilities & V4L2_CAP_VIDEO_OVERLAY) {
301                 err = drv(inode, file, VIDIOC_G_FBUF, &fbuf);
302                 if (err < 0) {
303                         dprintk("VIDIOCGCAP / VIDIOC_G_FBUF: %d\n", err);
304                         memset(&fbuf, 0, sizeof(fbuf));
305                 }
306                 err = 0;
307         }
308
309         memcpy(cap->name, cap2->card,
310                min(sizeof(cap->name), sizeof(cap2->card)));
311         cap->name[sizeof(cap->name) - 1] = 0;
312         if (cap2->capabilities & V4L2_CAP_VIDEO_CAPTURE)
313                 cap->type |= VID_TYPE_CAPTURE;
314         if (cap2->capabilities & V4L2_CAP_TUNER)
315                 cap->type |= VID_TYPE_TUNER;
316         if (cap2->capabilities & V4L2_CAP_VBI_CAPTURE)
317                 cap->type |= VID_TYPE_TELETEXT;
318         if (cap2->capabilities & V4L2_CAP_VIDEO_OVERLAY)
319                 cap->type |= VID_TYPE_OVERLAY;
320         if (fbuf.capability & V4L2_FBUF_CAP_LIST_CLIPPING)
321                 cap->type |= VID_TYPE_CLIPPING;
322
323         cap->channels  = count_inputs(inode, file, drv);
324         check_size(inode, file, drv,
325                    &cap->maxwidth, &cap->maxheight);
326         cap->audios    =  0; /* FIXME */
327         cap->minwidth  = 48; /* FIXME */
328         cap->minheight = 32; /* FIXME */
329
330 done:
331         kfree(cap2);
332         return err;
333 }
334
335 static noinline int v4l1_compat_get_frame_buffer(
336                                         struct video_buffer *buffer,
337                                         struct inode *inode,
338                                         struct file *file,
339                                         v4l2_kioctl drv)
340 {
341         int err;
342         struct v4l2_framebuffer fbuf;
343
344         memset(buffer, 0, sizeof(*buffer));
345         memset(&fbuf, 0, sizeof(fbuf));
346
347         err = drv(inode, file, VIDIOC_G_FBUF, &fbuf);
348         if (err < 0) {
349                 dprintk("VIDIOCGFBUF / VIDIOC_G_FBUF: %d\n", err);
350                 goto done;
351         }
352         buffer->base   = fbuf.base;
353         buffer->height = fbuf.fmt.height;
354         buffer->width  = fbuf.fmt.width;
355
356         switch (fbuf.fmt.pixelformat) {
357         case V4L2_PIX_FMT_RGB332:
358                 buffer->depth = 8;
359                 break;
360         case V4L2_PIX_FMT_RGB555:
361                 buffer->depth = 15;
362                 break;
363         case V4L2_PIX_FMT_RGB565:
364                 buffer->depth = 16;
365                 break;
366         case V4L2_PIX_FMT_BGR24:
367                 buffer->depth = 24;
368                 break;
369         case V4L2_PIX_FMT_BGR32:
370                 buffer->depth = 32;
371                 break;
372         default:
373                 buffer->depth = 0;
374         }
375         if (fbuf.fmt.bytesperline) {
376                 buffer->bytesperline = fbuf.fmt.bytesperline;
377                 if (!buffer->depth && buffer->width)
378                         buffer->depth   = ((fbuf.fmt.bytesperline<<3)
379                                           + (buffer->width-1))
380                                           / buffer->width;
381         } else {
382                 buffer->bytesperline =
383                         (buffer->width * buffer->depth + 7) & 7;
384                 buffer->bytesperline >>= 3;
385         }
386 done:
387         return err;
388 }
389
390 static noinline int v4l1_compat_set_frame_buffer(
391                                         struct video_buffer *buffer,
392                                         struct inode *inode,
393                                         struct file *file,
394                                         v4l2_kioctl drv)
395 {
396         int err;
397         struct v4l2_framebuffer fbuf;
398
399         memset(&fbuf, 0, sizeof(fbuf));
400         fbuf.base       = buffer->base;
401         fbuf.fmt.height = buffer->height;
402         fbuf.fmt.width  = buffer->width;
403         switch (buffer->depth) {
404         case 8:
405                 fbuf.fmt.pixelformat = V4L2_PIX_FMT_RGB332;
406                 break;
407         case 15:
408                 fbuf.fmt.pixelformat = V4L2_PIX_FMT_RGB555;
409                 break;
410         case 16:
411                 fbuf.fmt.pixelformat = V4L2_PIX_FMT_RGB565;
412                 break;
413         case 24:
414                 fbuf.fmt.pixelformat = V4L2_PIX_FMT_BGR24;
415                 break;
416         case 32:
417                 fbuf.fmt.pixelformat = V4L2_PIX_FMT_BGR32;
418                 break;
419         }
420         fbuf.fmt.bytesperline = buffer->bytesperline;
421         err = drv(inode, file, VIDIOC_S_FBUF, &fbuf);
422         if (err < 0)
423                 dprintk("VIDIOCSFBUF / VIDIOC_S_FBUF: %d\n", err);
424         return err;
425 }
426
427 static noinline int v4l1_compat_get_win_cap_dimensions(
428                                         struct video_window *win,
429                                         struct inode *inode,
430                                         struct file *file,
431                                         v4l2_kioctl drv)
432 {
433         int err;
434         struct v4l2_format *fmt;
435
436         fmt = kzalloc(sizeof(*fmt), GFP_KERNEL);
437         if (!fmt) {
438                 err = -ENOMEM;
439                 return err;
440         }
441         memset(win, 0, sizeof(*win));
442
443         fmt->type = V4L2_BUF_TYPE_VIDEO_OVERLAY;
444         err = drv(inode, file, VIDIOC_G_FMT, fmt);
445         if (err < 0)
446                 dprintk("VIDIOCGWIN / VIDIOC_G_WIN: %d\n", err);
447         if (err == 0) {
448                 win->x         = fmt->fmt.win.w.left;
449                 win->y         = fmt->fmt.win.w.top;
450                 win->width     = fmt->fmt.win.w.width;
451                 win->height    = fmt->fmt.win.w.height;
452                 win->chromakey = fmt->fmt.win.chromakey;
453                 win->clips     = NULL;
454                 win->clipcount = 0;
455                 goto done;
456         }
457
458         fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
459         err = drv(inode, file, VIDIOC_G_FMT, fmt);
460         if (err < 0) {
461                 dprintk("VIDIOCGWIN / VIDIOC_G_FMT: %d\n", err);
462                 goto done;
463         }
464         win->x         = 0;
465         win->y         = 0;
466         win->width     = fmt->fmt.pix.width;
467         win->height    = fmt->fmt.pix.height;
468         win->chromakey = 0;
469         win->clips     = NULL;
470         win->clipcount = 0;
471 done:
472         kfree(fmt);
473         return err;
474 }
475
476 static noinline int v4l1_compat_set_win_cap_dimensions(
477                                         struct video_window *win,
478                                         struct inode *inode,
479                                         struct file *file,
480                                         v4l2_kioctl drv)
481 {
482         int err, err1, err2;
483         struct v4l2_format *fmt;
484
485         fmt = kzalloc(sizeof(*fmt), GFP_KERNEL);
486         if (!fmt) {
487                 err = -ENOMEM;
488                 return err;
489         }
490         fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
491         drv(inode, file, VIDIOC_STREAMOFF, &fmt->type);
492         err1 = drv(inode, file, VIDIOC_G_FMT, fmt);
493         if (err1 < 0)
494                 dprintk("VIDIOCSWIN / VIDIOC_G_FMT: %d\n", err1);
495         if (err1 == 0) {
496                 fmt->fmt.pix.width  = win->width;
497                 fmt->fmt.pix.height = win->height;
498                 fmt->fmt.pix.field  = V4L2_FIELD_ANY;
499                 fmt->fmt.pix.bytesperline = 0;
500                 err = drv(inode, file, VIDIOC_S_FMT, fmt);
501                 if (err < 0)
502                         dprintk("VIDIOCSWIN / VIDIOC_S_FMT #1: %d\n",
503                                 err);
504                 win->width  = fmt->fmt.pix.width;
505                 win->height = fmt->fmt.pix.height;
506         }
507
508         memset(fmt, 0, sizeof(*fmt));
509         fmt->type = V4L2_BUF_TYPE_VIDEO_OVERLAY;
510         fmt->fmt.win.w.left    = win->x;
511         fmt->fmt.win.w.top     = win->y;
512         fmt->fmt.win.w.width   = win->width;
513         fmt->fmt.win.w.height  = win->height;
514         fmt->fmt.win.chromakey = win->chromakey;
515         fmt->fmt.win.clips     = (void __user *)win->clips;
516         fmt->fmt.win.clipcount = win->clipcount;
517         err2 = drv(inode, file, VIDIOC_S_FMT, fmt);
518         if (err2 < 0)
519                 dprintk("VIDIOCSWIN / VIDIOC_S_FMT #2: %d\n", err2);
520
521         if (err1 != 0 && err2 != 0)
522                 err = err1;
523         else
524                 err = 0;
525         kfree(fmt);
526         return err;
527 }
528
529 static noinline int v4l1_compat_turn_preview_on_off(
530                                         int *on,
531                                         struct inode *inode,
532                                         struct file *file,
533                                         v4l2_kioctl drv)
534 {
535         int err;
536         enum v4l2_buf_type captype = V4L2_BUF_TYPE_VIDEO_CAPTURE;
537
538         if (0 == *on) {
539                 /* dirty hack time.  But v4l1 has no STREAMOFF
540                  * equivalent in the API, and this one at
541                  * least comes close ... */
542                 drv(inode, file, VIDIOC_STREAMOFF, &captype);
543         }
544         err = drv(inode, file, VIDIOC_OVERLAY, on);
545         if (err < 0)
546                 dprintk("VIDIOCCAPTURE / VIDIOC_PREVIEW: %d\n", err);
547         return err;
548 }
549
550 static noinline int v4l1_compat_get_input_info(
551                                         struct video_channel *chan,
552                                         struct inode *inode,
553                                         struct file *file,
554                                         v4l2_kioctl drv)
555 {
556         int err;
557         struct v4l2_input       input2;
558         v4l2_std_id             sid;
559
560         memset(&input2, 0, sizeof(input2));
561         input2.index = chan->channel;
562         err = drv(inode, file, VIDIOC_ENUMINPUT, &input2);
563         if (err < 0) {
564                 dprintk("VIDIOCGCHAN / VIDIOC_ENUMINPUT: "
565                         "channel=%d err=%d\n", chan->channel, err);
566                 goto done;
567         }
568         chan->channel = input2.index;
569         memcpy(chan->name, input2.name,
570                min(sizeof(chan->name), sizeof(input2.name)));
571         chan->name[sizeof(chan->name) - 1] = 0;
572         chan->tuners = (input2.type == V4L2_INPUT_TYPE_TUNER) ? 1 : 0;
573         chan->flags = (chan->tuners) ? VIDEO_VC_TUNER : 0;
574         switch (input2.type) {
575         case V4L2_INPUT_TYPE_TUNER:
576                 chan->type = VIDEO_TYPE_TV;
577                 break;
578         default:
579         case V4L2_INPUT_TYPE_CAMERA:
580                 chan->type = VIDEO_TYPE_CAMERA;
581                 break;
582         }
583         chan->norm = 0;
584         err = drv(inode, file, VIDIOC_G_STD, &sid);
585         if (err < 0)
586                 dprintk("VIDIOCGCHAN / VIDIOC_G_STD: %d\n", err);
587         if (err == 0) {
588                 if (sid & V4L2_STD_PAL)
589                         chan->norm = VIDEO_MODE_PAL;
590                 if (sid & V4L2_STD_NTSC)
591                         chan->norm = VIDEO_MODE_NTSC;
592                 if (sid & V4L2_STD_SECAM)
593                         chan->norm = VIDEO_MODE_SECAM;
594         }
595 done:
596         return err;
597 }
598
599 static noinline int v4l1_compat_set_input(
600                                         struct video_channel *chan,
601                                         struct inode *inode,
602                                         struct file *file,
603                                         v4l2_kioctl drv)
604 {
605         int err;
606         v4l2_std_id sid = 0;
607
608         err = drv(inode, file, VIDIOC_S_INPUT, &chan->channel);
609         if (err < 0)
610                 dprintk("VIDIOCSCHAN / VIDIOC_S_INPUT: %d\n", err);
611         switch (chan->norm) {
612         case VIDEO_MODE_PAL:
613                 sid = V4L2_STD_PAL;
614                 break;
615         case VIDEO_MODE_NTSC:
616                 sid = V4L2_STD_NTSC;
617                 break;
618         case VIDEO_MODE_SECAM:
619                 sid = V4L2_STD_SECAM;
620                 break;
621         }
622         if (0 != sid) {
623                 err = drv(inode, file, VIDIOC_S_STD, &sid);
624                 if (err < 0)
625                         dprintk("VIDIOCSCHAN / VIDIOC_S_STD: %d\n", err);
626         }
627         return err;
628 }
629
630 static noinline int v4l1_compat_get_picture(
631                                         struct video_picture *pict,
632                                         struct inode *inode,
633                                         struct file *file,
634                                         v4l2_kioctl drv)
635 {
636         int err;
637         struct v4l2_format *fmt;
638
639         fmt = kzalloc(sizeof(*fmt), GFP_KERNEL);
640         if (!fmt) {
641                 err = -ENOMEM;
642                 return err;
643         }
644
645         pict->brightness = get_v4l_control(inode, file,
646                                            V4L2_CID_BRIGHTNESS, drv);
647         pict->hue = get_v4l_control(inode, file,
648                                     V4L2_CID_HUE, drv);
649         pict->contrast = get_v4l_control(inode, file,
650                                          V4L2_CID_CONTRAST, drv);
651         pict->colour = get_v4l_control(inode, file,
652                                        V4L2_CID_SATURATION, drv);
653         pict->whiteness = get_v4l_control(inode, file,
654                                           V4L2_CID_WHITENESS, drv);
655
656         fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
657         err = drv(inode, file, VIDIOC_G_FMT, fmt);
658         if (err < 0) {
659                 dprintk("VIDIOCGPICT / VIDIOC_G_FMT: %d\n", err);
660                 goto done;
661         }
662
663         pict->depth   = ((fmt->fmt.pix.bytesperline << 3)
664                          + (fmt->fmt.pix.width - 1))
665                          / fmt->fmt.pix.width;
666         pict->palette = pixelformat_to_palette(
667                 fmt->fmt.pix.pixelformat);
668 done:
669         kfree(fmt);
670         return err;
671 }
672
673 static noinline int v4l1_compat_set_picture(
674                                         struct video_picture *pict,
675                                         struct inode *inode,
676                                         struct file *file,
677                                         v4l2_kioctl drv)
678 {
679         int err;
680         struct v4l2_framebuffer fbuf;
681         int mem_err = 0, ovl_err = 0;
682         struct v4l2_format *fmt;
683
684         fmt = kzalloc(sizeof(*fmt), GFP_KERNEL);
685         if (!fmt) {
686                 err = -ENOMEM;
687                 return err;
688         }
689         memset(&fbuf, 0, sizeof(fbuf));
690
691         set_v4l_control(inode, file,
692                         V4L2_CID_BRIGHTNESS, pict->brightness, drv);
693         set_v4l_control(inode, file,
694                         V4L2_CID_HUE, pict->hue, drv);
695         set_v4l_control(inode, file,
696                         V4L2_CID_CONTRAST, pict->contrast, drv);
697         set_v4l_control(inode, file,
698                         V4L2_CID_SATURATION, pict->colour, drv);
699         set_v4l_control(inode, file,
700                         V4L2_CID_WHITENESS, pict->whiteness, drv);
701         /*
702          * V4L1 uses this ioctl to set both memory capture and overlay
703          * pixel format, while V4L2 has two different ioctls for this.
704          * Some cards may not support one or the other, and may support
705          * different pixel formats for memory vs overlay.
706          */
707
708         fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
709         err = drv(inode, file, VIDIOC_G_FMT, fmt);
710         /* If VIDIOC_G_FMT failed, then the driver likely doesn't
711            support memory capture.  Trying to set the memory capture
712            parameters would be pointless.  */
713         if (err < 0) {
714                 dprintk("VIDIOCSPICT / VIDIOC_G_FMT: %d\n", err);
715                 mem_err = -1000;  /* didn't even try */
716         } else if (fmt->fmt.pix.pixelformat !=
717                  palette_to_pixelformat(pict->palette)) {
718                 fmt->fmt.pix.pixelformat = palette_to_pixelformat(
719                         pict->palette);
720                 mem_err = drv(inode, file, VIDIOC_S_FMT, fmt);
721                 if (mem_err < 0)
722                         dprintk("VIDIOCSPICT / VIDIOC_S_FMT: %d\n",
723                                 mem_err);
724         }
725
726         err = drv(inode, file, VIDIOC_G_FBUF, &fbuf);
727         /* If VIDIOC_G_FBUF failed, then the driver likely doesn't
728            support overlay.  Trying to set the overlay parameters
729            would be quite pointless.  */
730         if (err < 0) {
731                 dprintk("VIDIOCSPICT / VIDIOC_G_FBUF: %d\n", err);
732                 ovl_err = -1000;  /* didn't even try */
733         } else if (fbuf.fmt.pixelformat !=
734                  palette_to_pixelformat(pict->palette)) {
735                 fbuf.fmt.pixelformat = palette_to_pixelformat(
736                         pict->palette);
737                 ovl_err = drv(inode, file, VIDIOC_S_FBUF, &fbuf);
738                 if (ovl_err < 0)
739                         dprintk("VIDIOCSPICT / VIDIOC_S_FBUF: %d\n",
740                                 ovl_err);
741         }
742         if (ovl_err < 0 && mem_err < 0) {
743                 /* ioctl failed, couldn't set either parameter */
744                 if (mem_err != -1000)
745                         err = mem_err;
746                 else if (ovl_err == -EPERM)
747                         err = 0;
748                 else
749                         err = ovl_err;
750         } else
751                 err = 0;
752         kfree(fmt);
753         return err;
754 }
755
756 static noinline int v4l1_compat_get_tuner(
757                                         struct video_tuner *tun,
758                                         struct inode *inode,
759                                         struct file *file,
760                                         v4l2_kioctl drv)
761 {
762         int err, i;
763         struct v4l2_tuner       tun2;
764         struct v4l2_standard    std2;
765         v4l2_std_id             sid;
766
767         memset(&tun2, 0, sizeof(tun2));
768         err = drv(inode, file, VIDIOC_G_TUNER, &tun2);
769         if (err < 0) {
770                 dprintk("VIDIOCGTUNER / VIDIOC_G_TUNER: %d\n", err);
771                 goto done;
772         }
773         memcpy(tun->name, tun2.name,
774                min(sizeof(tun->name), sizeof(tun2.name)));
775         tun->name[sizeof(tun->name) - 1] = 0;
776         tun->rangelow = tun2.rangelow;
777         tun->rangehigh = tun2.rangehigh;
778         tun->flags = 0;
779         tun->mode = VIDEO_MODE_AUTO;
780
781         for (i = 0; i < 64; i++) {
782                 memset(&std2, 0, sizeof(std2));
783                 std2.index = i;
784                 if (0 != drv(inode, file, VIDIOC_ENUMSTD, &std2))
785                         break;
786                 if (std2.id & V4L2_STD_PAL)
787                         tun->flags |= VIDEO_TUNER_PAL;
788                 if (std2.id & V4L2_STD_NTSC)
789                         tun->flags |= VIDEO_TUNER_NTSC;
790                 if (std2.id & V4L2_STD_SECAM)
791                         tun->flags |= VIDEO_TUNER_SECAM;
792         }
793
794         err = drv(inode, file, VIDIOC_G_STD, &sid);
795         if (err < 0)
796                 dprintk("VIDIOCGTUNER / VIDIOC_G_STD: %d\n", err);
797         if (err == 0) {
798                 if (sid & V4L2_STD_PAL)
799                         tun->mode = VIDEO_MODE_PAL;
800                 if (sid & V4L2_STD_NTSC)
801                         tun->mode = VIDEO_MODE_NTSC;
802                 if (sid & V4L2_STD_SECAM)
803                         tun->mode = VIDEO_MODE_SECAM;
804         }
805
806         if (tun2.capability & V4L2_TUNER_CAP_LOW)
807                 tun->flags |= VIDEO_TUNER_LOW;
808         if (tun2.rxsubchans & V4L2_TUNER_SUB_STEREO)
809                 tun->flags |= VIDEO_TUNER_STEREO_ON;
810         tun->signal = tun2.signal;
811 done:
812         return err;
813 }
814
815 static noinline int v4l1_compat_select_tuner(
816                                         struct video_tuner *tun,
817                                         struct inode *inode,
818                                         struct file *file,
819                                         v4l2_kioctl drv)
820 {
821         int err;
822         struct v4l2_tuner       t;/*84 bytes on x86_64*/
823         memset(&t, 0, sizeof(t));
824
825         t.index = tun->tuner;
826
827         err = drv(inode, file, VIDIOC_S_INPUT, &t);
828         if (err < 0)
829                 dprintk("VIDIOCSTUNER / VIDIOC_S_INPUT: %d\n", err);
830         return err;
831 }
832
833 static noinline int v4l1_compat_get_frequency(
834                                         unsigned long *freq,
835                                         struct inode *inode,
836                                         struct file *file,
837                                         v4l2_kioctl drv)
838 {
839         int err;
840         struct v4l2_frequency   freq2;
841         memset(&freq2, 0, sizeof(freq2));
842
843         freq2.tuner = 0;
844         err = drv(inode, file, VIDIOC_G_FREQUENCY, &freq2);
845         if (err < 0)
846                 dprintk("VIDIOCGFREQ / VIDIOC_G_FREQUENCY: %d\n", err);
847         if (0 == err)
848                 *freq = freq2.frequency;
849         return err;
850 }
851
852 static noinline int v4l1_compat_set_frequency(
853                                         unsigned long *freq,
854                                         struct inode *inode,
855                                         struct file *file,
856                                         v4l2_kioctl drv)
857 {
858         int err;
859         struct v4l2_frequency   freq2;
860         memset(&freq2, 0, sizeof(freq2));
861
862         drv(inode, file, VIDIOC_G_FREQUENCY, &freq2);
863         freq2.frequency = *freq;
864         err = drv(inode, file, VIDIOC_S_FREQUENCY, &freq2);
865         if (err < 0)
866                 dprintk("VIDIOCSFREQ / VIDIOC_S_FREQUENCY: %d\n", err);
867         return err;
868 }
869
870 static noinline int v4l1_compat_get_audio(
871                                         struct video_audio *aud,
872                                         struct inode *inode,
873                                         struct file *file,
874                                         v4l2_kioctl drv)
875 {
876         int err, i;
877         struct v4l2_queryctrl   qctrl2;
878         struct v4l2_audio       aud2;
879         struct v4l2_tuner       tun2;
880         memset(&aud2, 0, sizeof(aud2));
881
882         err = drv(inode, file, VIDIOC_G_AUDIO, &aud2);
883         if (err < 0) {
884                 dprintk("VIDIOCGAUDIO / VIDIOC_G_AUDIO: %d\n", err);
885                 goto done;
886         }
887         memcpy(aud->name, aud2.name,
888                min(sizeof(aud->name), sizeof(aud2.name)));
889         aud->name[sizeof(aud->name) - 1] = 0;
890         aud->audio = aud2.index;
891         aud->flags = 0;
892         i = get_v4l_control(inode, file, V4L2_CID_AUDIO_VOLUME, drv);
893         if (i >= 0) {
894                 aud->volume = i;
895                 aud->flags |= VIDEO_AUDIO_VOLUME;
896         }
897         i = get_v4l_control(inode, file, V4L2_CID_AUDIO_BASS, drv);
898         if (i >= 0) {
899                 aud->bass = i;
900                 aud->flags |= VIDEO_AUDIO_BASS;
901         }
902         i = get_v4l_control(inode, file, V4L2_CID_AUDIO_TREBLE, drv);
903         if (i >= 0) {
904                 aud->treble = i;
905                 aud->flags |= VIDEO_AUDIO_TREBLE;
906         }
907         i = get_v4l_control(inode, file, V4L2_CID_AUDIO_BALANCE, drv);
908         if (i >= 0) {
909                 aud->balance = i;
910                 aud->flags |= VIDEO_AUDIO_BALANCE;
911         }
912         i = get_v4l_control(inode, file, V4L2_CID_AUDIO_MUTE, drv);
913         if (i >= 0) {
914                 if (i)
915                         aud->flags |= VIDEO_AUDIO_MUTE;
916                 aud->flags |= VIDEO_AUDIO_MUTABLE;
917         }
918         aud->step = 1;
919         qctrl2.id = V4L2_CID_AUDIO_VOLUME;
920         if (drv(inode, file, VIDIOC_QUERYCTRL, &qctrl2) == 0 &&
921             !(qctrl2.flags & V4L2_CTRL_FLAG_DISABLED))
922                 aud->step = qctrl2.step;
923         aud->mode = 0;
924
925         memset(&tun2, 0, sizeof(tun2));
926         err = drv(inode, file, VIDIOC_G_TUNER, &tun2);
927         if (err < 0) {
928                 dprintk("VIDIOCGAUDIO / VIDIOC_G_TUNER: %d\n", err);
929                 err = 0;
930                 goto done;
931         }
932
933         if (tun2.rxsubchans & V4L2_TUNER_SUB_LANG2)
934                 aud->mode = VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
935         else if (tun2.rxsubchans & V4L2_TUNER_SUB_STEREO)
936                 aud->mode = VIDEO_SOUND_STEREO;
937         else if (tun2.rxsubchans & V4L2_TUNER_SUB_MONO)
938                 aud->mode = VIDEO_SOUND_MONO;
939 done:
940         return err;
941 }
942
943 static noinline int v4l1_compat_set_audio(
944                                         struct video_audio *aud,
945                                         struct inode *inode,
946                                         struct file *file,
947                                         v4l2_kioctl drv)
948 {
949         int err;
950         struct v4l2_audio       aud2;
951         struct v4l2_tuner       tun2;
952
953         memset(&aud2, 0, sizeof(aud2));
954         memset(&tun2, 0, sizeof(tun2));
955
956         aud2.index = aud->audio;
957         err = drv(inode, file, VIDIOC_S_AUDIO, &aud2);
958         if (err < 0) {
959                 dprintk("VIDIOCSAUDIO / VIDIOC_S_AUDIO: %d\n", err);
960                 goto done;
961         }
962
963         set_v4l_control(inode, file, V4L2_CID_AUDIO_VOLUME,
964                         aud->volume, drv);
965         set_v4l_control(inode, file, V4L2_CID_AUDIO_BASS,
966                         aud->bass, drv);
967         set_v4l_control(inode, file, V4L2_CID_AUDIO_TREBLE,
968                         aud->treble, drv);
969         set_v4l_control(inode, file, V4L2_CID_AUDIO_BALANCE,
970                         aud->balance, drv);
971         set_v4l_control(inode, file, V4L2_CID_AUDIO_MUTE,
972                         !!(aud->flags & VIDEO_AUDIO_MUTE), drv);
973
974         err = drv(inode, file, VIDIOC_G_TUNER, &tun2);
975         if (err < 0)
976                 dprintk("VIDIOCSAUDIO / VIDIOC_G_TUNER: %d\n", err);
977         if (err == 0) {
978                 switch (aud->mode) {
979                 default:
980                 case VIDEO_SOUND_MONO:
981                 case VIDEO_SOUND_LANG1:
982                         tun2.audmode = V4L2_TUNER_MODE_MONO;
983                         break;
984                 case VIDEO_SOUND_STEREO:
985                         tun2.audmode = V4L2_TUNER_MODE_STEREO;
986                         break;
987                 case VIDEO_SOUND_LANG2:
988                         tun2.audmode = V4L2_TUNER_MODE_LANG2;
989                         break;
990                 }
991                 err = drv(inode, file, VIDIOC_S_TUNER, &tun2);
992                 if (err < 0)
993                         dprintk("VIDIOCSAUDIO / VIDIOC_S_TUNER: %d\n", err);
994         }
995         err = 0;
996 done:
997         return err;
998 }
999
1000 static noinline int v4l1_compat_capture_frame(
1001                                         struct video_mmap *mm,
1002                                         struct inode *inode,
1003                                         struct file *file,
1004                                         v4l2_kioctl drv)
1005 {
1006         int err;
1007         enum v4l2_buf_type      captype = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1008         struct v4l2_buffer      buf;
1009         struct v4l2_format      *fmt;
1010
1011         fmt = kzalloc(sizeof(*fmt), GFP_KERNEL);
1012         if (!fmt) {
1013                 err = -ENOMEM;
1014                 return err;
1015         }
1016         memset(&buf, 0, sizeof(buf));
1017
1018         fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1019         err = drv(inode, file, VIDIOC_G_FMT, fmt);
1020         if (err < 0) {
1021                 dprintk("VIDIOCMCAPTURE / VIDIOC_G_FMT: %d\n", err);
1022                 goto done;
1023         }
1024         if (mm->width   != fmt->fmt.pix.width  ||
1025             mm->height  != fmt->fmt.pix.height ||
1026             palette_to_pixelformat(mm->format) !=
1027             fmt->fmt.pix.pixelformat) {
1028                 /* New capture format...  */
1029                 fmt->fmt.pix.width = mm->width;
1030                 fmt->fmt.pix.height = mm->height;
1031                 fmt->fmt.pix.pixelformat =
1032                         palette_to_pixelformat(mm->format);
1033                 fmt->fmt.pix.field = V4L2_FIELD_ANY;
1034                 fmt->fmt.pix.bytesperline = 0;
1035                 err = drv(inode, file, VIDIOC_S_FMT, fmt);
1036                 if (err < 0) {
1037                         dprintk("VIDIOCMCAPTURE / VIDIOC_S_FMT: %d\n", err);
1038                         goto done;
1039                 }
1040         }
1041         buf.index = mm->frame;
1042         buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1043         err = drv(inode, file, VIDIOC_QUERYBUF, &buf);
1044         if (err < 0) {
1045                 dprintk("VIDIOCMCAPTURE / VIDIOC_QUERYBUF: %d\n", err);
1046                 goto done;
1047         }
1048         err = drv(inode, file, VIDIOC_QBUF, &buf);
1049         if (err < 0) {
1050                 dprintk("VIDIOCMCAPTURE / VIDIOC_QBUF: %d\n", err);
1051                 goto done;
1052         }
1053         err = drv(inode, file, VIDIOC_STREAMON, &captype);
1054         if (err < 0)
1055                 dprintk("VIDIOCMCAPTURE / VIDIOC_STREAMON: %d\n", err);
1056 done:
1057         kfree(fmt);
1058         return err;
1059 }
1060
1061 static noinline int v4l1_compat_sync(
1062                                 int *i,
1063                                 struct inode *inode,
1064                                 struct file *file,
1065                                 v4l2_kioctl drv)
1066 {
1067         int err;
1068         enum v4l2_buf_type captype = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1069         struct v4l2_buffer buf;
1070         struct poll_wqueues *pwq;
1071
1072         memset(&buf, 0, sizeof(buf));
1073         buf.index = *i;
1074         buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1075         err = drv(inode, file, VIDIOC_QUERYBUF, &buf);
1076         if (err < 0) {
1077                 /*  No such buffer */
1078                 dprintk("VIDIOCSYNC / VIDIOC_QUERYBUF: %d\n", err);
1079                 goto done;
1080         }
1081         if (!(buf.flags & V4L2_BUF_FLAG_MAPPED)) {
1082                 /* Buffer is not mapped  */
1083                 err = -EINVAL;
1084                 goto done;
1085         }
1086
1087         /* make sure capture actually runs so we don't block forever */
1088         err = drv(inode, file, VIDIOC_STREAMON, &captype);
1089         if (err < 0) {
1090                 dprintk("VIDIOCSYNC / VIDIOC_STREAMON: %d\n", err);
1091                 goto done;
1092         }
1093
1094         pwq = kmalloc(sizeof(*pwq), GFP_KERNEL);
1095         /*  Loop as long as the buffer is queued, but not done  */
1096         while ((buf.flags & (V4L2_BUF_FLAG_QUEUED | V4L2_BUF_FLAG_DONE))
1097                                                 == V4L2_BUF_FLAG_QUEUED) {
1098                 err = poll_one(file, pwq);
1099                 if (err < 0 ||  /* error or sleep was interrupted  */
1100                     err == 0)   /* timeout? Shouldn't occur.  */
1101                         break;
1102                 err = drv(inode, file, VIDIOC_QUERYBUF, &buf);
1103                 if (err < 0)
1104                         dprintk("VIDIOCSYNC / VIDIOC_QUERYBUF: %d\n", err);
1105         }
1106         kfree(pwq);
1107         if (!(buf.flags & V4L2_BUF_FLAG_DONE)) /* not done */
1108                 goto done;
1109         do {
1110                 err = drv(inode, file, VIDIOC_DQBUF, &buf);
1111                 if (err < 0)
1112                         dprintk("VIDIOCSYNC / VIDIOC_DQBUF: %d\n", err);
1113         } while (err == 0 && buf.index != *i);
1114 done:
1115         return err;
1116 }
1117
1118 static noinline int v4l1_compat_get_vbi_format(
1119                                 struct vbi_format *fmt,
1120                                 struct inode *inode,
1121                                 struct file *file,
1122                                 v4l2_kioctl drv)
1123 {
1124         int err;
1125         struct v4l2_format *fmt2;
1126
1127         fmt2 = kzalloc(sizeof(*fmt2), GFP_KERNEL);
1128         if (!fmt2) {
1129                 err = -ENOMEM;
1130                 return err;
1131         }
1132         fmt2->type = V4L2_BUF_TYPE_VBI_CAPTURE;
1133
1134         err = drv(inode, file, VIDIOC_G_FMT, fmt2);
1135         if (err < 0) {
1136                 dprintk("VIDIOCGVBIFMT / VIDIOC_G_FMT: %d\n", err);
1137                 goto done;
1138         }
1139         if (fmt2->fmt.vbi.sample_format != V4L2_PIX_FMT_GREY) {
1140                 err = -EINVAL;
1141                 goto done;
1142         }
1143         memset(fmt, 0, sizeof(*fmt));
1144         fmt->samples_per_line = fmt2->fmt.vbi.samples_per_line;
1145         fmt->sampling_rate    = fmt2->fmt.vbi.sampling_rate;
1146         fmt->sample_format    = VIDEO_PALETTE_RAW;
1147         fmt->start[0]         = fmt2->fmt.vbi.start[0];
1148         fmt->count[0]         = fmt2->fmt.vbi.count[0];
1149         fmt->start[1]         = fmt2->fmt.vbi.start[1];
1150         fmt->count[1]         = fmt2->fmt.vbi.count[1];
1151         fmt->flags            = fmt2->fmt.vbi.flags & 0x03;
1152 done:
1153         kfree(fmt2);
1154         return err;
1155 }
1156
1157 static noinline int v4l1_compat_set_vbi_format(
1158                                 struct vbi_format *fmt,
1159                                 struct inode *inode,
1160                                 struct file *file,
1161                                 v4l2_kioctl drv)
1162 {
1163         int err;
1164         struct v4l2_format      *fmt2 = NULL;
1165
1166         if (VIDEO_PALETTE_RAW != fmt->sample_format) {
1167                 err = -EINVAL;
1168                 return err;
1169         }
1170
1171         fmt2 = kzalloc(sizeof(*fmt2), GFP_KERNEL);
1172         if (!fmt2) {
1173                 err = -ENOMEM;
1174                 return err;
1175         }
1176         fmt2->type = V4L2_BUF_TYPE_VBI_CAPTURE;
1177         fmt2->fmt.vbi.samples_per_line = fmt->samples_per_line;
1178         fmt2->fmt.vbi.sampling_rate    = fmt->sampling_rate;
1179         fmt2->fmt.vbi.sample_format    = V4L2_PIX_FMT_GREY;
1180         fmt2->fmt.vbi.start[0]         = fmt->start[0];
1181         fmt2->fmt.vbi.count[0]         = fmt->count[0];
1182         fmt2->fmt.vbi.start[1]         = fmt->start[1];
1183         fmt2->fmt.vbi.count[1]         = fmt->count[1];
1184         fmt2->fmt.vbi.flags            = fmt->flags;
1185         err = drv(inode, file, VIDIOC_TRY_FMT, fmt2);
1186         if (err < 0) {
1187                 dprintk("VIDIOCSVBIFMT / VIDIOC_TRY_FMT: %d\n", err);
1188                 goto done;
1189         }
1190
1191         if (fmt2->fmt.vbi.samples_per_line != fmt->samples_per_line ||
1192             fmt2->fmt.vbi.sampling_rate    != fmt->sampling_rate    ||
1193             fmt2->fmt.vbi.sample_format    != V4L2_PIX_FMT_GREY     ||
1194             fmt2->fmt.vbi.start[0]         != fmt->start[0]         ||
1195             fmt2->fmt.vbi.count[0]         != fmt->count[0]         ||
1196             fmt2->fmt.vbi.start[1]         != fmt->start[1]         ||
1197             fmt2->fmt.vbi.count[1]         != fmt->count[1]         ||
1198             fmt2->fmt.vbi.flags            != fmt->flags) {
1199                 err = -EINVAL;
1200                 goto done;
1201         }
1202         err = drv(inode, file, VIDIOC_S_FMT, fmt2);
1203         if (err < 0)
1204                 dprintk("VIDIOCSVBIFMT / VIDIOC_S_FMT: %d\n", err);
1205 done:
1206         kfree(fmt2);
1207         return err;
1208 }
1209
1210 /*
1211  *      This function is exported.
1212  */
1213 int
1214 v4l_compat_translate_ioctl(struct inode         *inode,
1215                            struct file          *file,
1216                            int                  cmd,
1217                            void                 *arg,
1218                            v4l2_kioctl          drv)
1219 {
1220         int err;
1221
1222         switch (cmd) {
1223         case VIDIOCGCAP:        /* capability */
1224                 err = v4l1_compat_get_capabilities(arg, inode, file, drv);
1225                 break;
1226         case VIDIOCGFBUF: /*  get frame buffer  */
1227                 err = v4l1_compat_get_frame_buffer(arg, inode, file, drv);
1228                 break;
1229         case VIDIOCSFBUF: /*  set frame buffer  */
1230                 err = v4l1_compat_set_frame_buffer(arg, inode, file, drv);
1231                 break;
1232         case VIDIOCGWIN: /*  get window or capture dimensions  */
1233                 err = v4l1_compat_get_win_cap_dimensions(arg, inode, file, drv);
1234                 break;
1235         case VIDIOCSWIN: /*  set window and/or capture dimensions  */
1236                 err = v4l1_compat_set_win_cap_dimensions(arg, inode, file, drv);
1237                 break;
1238         case VIDIOCCAPTURE: /*  turn on/off preview  */
1239                 err = v4l1_compat_turn_preview_on_off(arg, inode, file, drv);
1240                 break;
1241         case VIDIOCGCHAN: /*  get input information  */
1242                 err = v4l1_compat_get_input_info(arg, inode, file, drv);
1243                 break;
1244         case VIDIOCSCHAN: /*  set input  */
1245                 err = v4l1_compat_set_input(arg, inode, file, drv);
1246                 break;
1247         case VIDIOCGPICT: /*  get tone controls & partial capture format  */
1248                 err = v4l1_compat_get_picture(arg, inode, file, drv);
1249                 break;
1250         case VIDIOCSPICT: /*  set tone controls & partial capture format  */
1251                 err = v4l1_compat_set_picture(arg, inode, file, drv);
1252                 break;
1253         case VIDIOCGTUNER: /*  get tuner information  */
1254                 err = v4l1_compat_get_tuner(arg, inode, file, drv);
1255                 break;
1256         case VIDIOCSTUNER: /*  select a tuner input  */
1257                 err = v4l1_compat_select_tuner(arg, inode, file, drv);
1258                 break;
1259         case VIDIOCGFREQ: /*  get frequency  */
1260                 err = v4l1_compat_get_frequency(arg, inode, file, drv);
1261                 break;
1262         case VIDIOCSFREQ: /*  set frequency  */
1263                 err = v4l1_compat_set_frequency(arg, inode, file, drv);
1264                 break;
1265         case VIDIOCGAUDIO: /*  get audio properties/controls  */
1266                 err = v4l1_compat_get_audio(arg, inode, file, drv);
1267                 break;
1268         case VIDIOCSAUDIO: /*  set audio controls  */
1269                 err = v4l1_compat_set_audio(arg, inode, file, drv);
1270                 break;
1271         case VIDIOCMCAPTURE: /*  capture a frame  */
1272                 err = v4l1_compat_capture_frame(arg, inode, file, drv);
1273                 break;
1274         case VIDIOCSYNC: /*  wait for a frame  */
1275                 err = v4l1_compat_sync(arg, inode, file, drv);
1276                 break;
1277         case VIDIOCGVBIFMT: /* query VBI data capture format */
1278                 err = v4l1_compat_get_vbi_format(arg, inode, file, drv);
1279                 break;
1280         case VIDIOCSVBIFMT:
1281                 err = v4l1_compat_set_vbi_format(arg, inode, file, drv);
1282                 break;
1283         default:
1284                 err = -ENOIOCTLCMD;
1285                 break;
1286         }
1287
1288         return err;
1289 }
1290 EXPORT_SYMBOL(v4l_compat_translate_ioctl);
1291
1292 /*
1293  * Local variables:
1294  * c-basic-offset: 8
1295  * End:
1296  */