Merge branch 'slub-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/christoph/vm
[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  = 0;
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...)    if (debug) \
50         printk(KERN_DEBUG "v4l1-compat: " fmt , ## arg)
51
52 /*
53  *      I O C T L   T R A N S L A T I O N
54  *
55  *      From here on down is the code for translating the numerous
56  *      ioctl commands from the old API to the new API.
57  */
58
59 static int
60 get_v4l_control(struct inode            *inode,
61                 struct file             *file,
62                 int                     cid,
63                 v4l2_kioctl             drv)
64 {
65         struct v4l2_queryctrl   qctrl2;
66         struct v4l2_control     ctrl2;
67         int                     err;
68
69         qctrl2.id = cid;
70         err = drv(inode, file, VIDIOC_QUERYCTRL, &qctrl2);
71         if (err < 0)
72                 dprintk("VIDIOC_QUERYCTRL: %d\n",err);
73         if (err == 0 &&
74             !(qctrl2.flags & V4L2_CTRL_FLAG_DISABLED))
75         {
76                 ctrl2.id = qctrl2.id;
77                 err = drv(inode, file, VIDIOC_G_CTRL, &ctrl2);
78                 if (err < 0) {
79                         dprintk("VIDIOC_G_CTRL: %d\n",err);
80                         return 0;
81                 }
82                 return ((ctrl2.value - qctrl2.minimum) * 65535
83                          + (qctrl2.maximum - qctrl2.minimum) / 2)
84                         / (qctrl2.maximum - qctrl2.minimum);
85         }
86         return 0;
87 }
88
89 static int
90 set_v4l_control(struct inode            *inode,
91                 struct file             *file,
92                 int                     cid,
93                 int                     value,
94                 v4l2_kioctl             drv)
95 {
96         struct v4l2_queryctrl   qctrl2;
97         struct v4l2_control     ctrl2;
98         int                     err;
99
100         qctrl2.id = cid;
101         err = drv(inode, file, VIDIOC_QUERYCTRL, &qctrl2);
102         if (err < 0)
103                 dprintk("VIDIOC_QUERYCTRL: %d\n",err);
104         if (err == 0 &&
105             !(qctrl2.flags & V4L2_CTRL_FLAG_DISABLED) &&
106             !(qctrl2.flags & V4L2_CTRL_FLAG_GRABBED))
107         {
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 const static 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         {
162         case V4L2_PIX_FMT_GREY:
163                 palette = VIDEO_PALETTE_GREY;
164                 break;
165         case V4L2_PIX_FMT_RGB555:
166                 palette = VIDEO_PALETTE_RGB555;
167                 break;
168         case V4L2_PIX_FMT_RGB565:
169                 palette = VIDEO_PALETTE_RGB565;
170                 break;
171         case V4L2_PIX_FMT_BGR24:
172                 palette = VIDEO_PALETTE_RGB24;
173                 break;
174         case V4L2_PIX_FMT_BGR32:
175                 palette = VIDEO_PALETTE_RGB32;
176                 break;
177         /* yuv packed pixel */
178         case V4L2_PIX_FMT_YUYV:
179                 palette = VIDEO_PALETTE_YUYV;
180                 break;
181         case V4L2_PIX_FMT_UYVY:
182                 palette = VIDEO_PALETTE_UYVY;
183                 break;
184         /* yuv planar */
185         case V4L2_PIX_FMT_YUV410:
186                 palette = VIDEO_PALETTE_YUV420;
187                 break;
188         case V4L2_PIX_FMT_YUV420:
189                 palette = VIDEO_PALETTE_YUV420;
190                 break;
191         case V4L2_PIX_FMT_YUV411P:
192                 palette = VIDEO_PALETTE_YUV411P;
193                 break;
194         case V4L2_PIX_FMT_YUV422P:
195                 palette = VIDEO_PALETTE_YUV422P;
196                 break;
197         }
198         return palette;
199 }
200
201 /* ----------------------------------------------------------------- */
202
203 static int poll_one(struct file *file)
204 {
205         int retval = 1;
206         poll_table *table;
207         struct poll_wqueues pwq;
208
209         poll_initwait(&pwq);
210         table = &pwq.pt;
211         for (;;) {
212                 int mask;
213                 set_current_state(TASK_INTERRUPTIBLE);
214                 mask = file->f_op->poll(file, table);
215                 if (mask & POLLIN)
216                         break;
217                 table = NULL;
218                 if (signal_pending(current)) {
219                         retval = -ERESTARTSYS;
220                         break;
221                 }
222                 schedule();
223         }
224         set_current_state(TASK_RUNNING);
225         poll_freewait(&pwq);
226         return retval;
227 }
228
229 static int count_inputs(struct inode         *inode,
230                         struct file          *file,
231                         v4l2_kioctl          drv)
232 {
233         struct v4l2_input input2;
234         int i;
235
236         for (i = 0;; i++) {
237                 memset(&input2,0,sizeof(input2));
238                 input2.index = i;
239                 if (0 != drv(inode,file,VIDIOC_ENUMINPUT, &input2))
240                         break;
241         }
242         return i;
243 }
244
245 static int check_size(struct inode         *inode,
246                       struct file          *file,
247                       v4l2_kioctl          drv,
248                       int *maxw, int *maxh)
249 {
250         struct v4l2_fmtdesc desc2;
251         struct v4l2_format  fmt2;
252
253         memset(&desc2,0,sizeof(desc2));
254         memset(&fmt2,0,sizeof(fmt2));
255
256         desc2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
257         if (0 != drv(inode,file,VIDIOC_ENUM_FMT, &desc2))
258                 goto done;
259
260         fmt2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
261         fmt2.fmt.pix.width       = 10000;
262         fmt2.fmt.pix.height      = 10000;
263         fmt2.fmt.pix.pixelformat = desc2.pixelformat;
264         if (0 != drv(inode,file,VIDIOC_TRY_FMT, &fmt2))
265                 goto done;
266
267         *maxw = fmt2.fmt.pix.width;
268         *maxh = fmt2.fmt.pix.height;
269
270  done:
271         return 0;
272 }
273
274 /* ----------------------------------------------------------------- */
275
276 /*
277  *      This function is exported.
278  */
279 int
280 v4l_compat_translate_ioctl(struct inode         *inode,
281                            struct file          *file,
282                            int                  cmd,
283                            void                 *arg,
284                            v4l2_kioctl          drv)
285 {
286         struct v4l2_capability  *cap2 = NULL;
287         struct v4l2_format      *fmt2 = NULL;
288         enum v4l2_buf_type      captype = V4L2_BUF_TYPE_VIDEO_CAPTURE;
289
290         struct v4l2_framebuffer fbuf2;
291         struct v4l2_input       input2;
292         struct v4l2_tuner       tun2;
293         struct v4l2_standard    std2;
294         struct v4l2_frequency   freq2;
295         struct v4l2_audio       aud2;
296         struct v4l2_queryctrl   qctrl2;
297         struct v4l2_buffer      buf2;
298         v4l2_std_id             sid;
299         int i, err = 0;
300
301         switch (cmd) {
302         case VIDIOCGCAP:        /* capability */
303         {
304                 struct video_capability *cap = arg;
305
306                 cap2 = kzalloc(sizeof(*cap2),GFP_KERNEL);
307                 memset(cap, 0, sizeof(*cap));
308                 memset(&fbuf2, 0, sizeof(fbuf2));
309
310                 err = drv(inode, file, VIDIOC_QUERYCAP, cap2);
311                 if (err < 0) {
312                         dprintk("VIDIOCGCAP / VIDIOC_QUERYCAP: %d\n",err);
313                         break;
314                 }
315                 if (cap2->capabilities & V4L2_CAP_VIDEO_OVERLAY) {
316                         err = drv(inode, file, VIDIOC_G_FBUF, &fbuf2);
317                         if (err < 0) {
318                                 dprintk("VIDIOCGCAP / VIDIOC_G_FBUF: %d\n",err);
319                                 memset(&fbuf2, 0, sizeof(fbuf2));
320                         }
321                         err = 0;
322                 }
323
324                 memcpy(cap->name, cap2->card,
325                        min(sizeof(cap->name), sizeof(cap2->card)));
326                 cap->name[sizeof(cap->name) - 1] = 0;
327                 if (cap2->capabilities & V4L2_CAP_VIDEO_CAPTURE)
328                         cap->type |= VID_TYPE_CAPTURE;
329                 if (cap2->capabilities & V4L2_CAP_TUNER)
330                         cap->type |= VID_TYPE_TUNER;
331                 if (cap2->capabilities & V4L2_CAP_VBI_CAPTURE)
332                         cap->type |= VID_TYPE_TELETEXT;
333                 if (cap2->capabilities & V4L2_CAP_VIDEO_OVERLAY)
334                         cap->type |= VID_TYPE_OVERLAY;
335                 if (fbuf2.capability & V4L2_FBUF_CAP_LIST_CLIPPING)
336                         cap->type |= VID_TYPE_CLIPPING;
337
338                 cap->channels  = count_inputs(inode,file,drv);
339                 check_size(inode,file,drv,
340                            &cap->maxwidth,&cap->maxheight);
341                 cap->audios    =  0; /* FIXME */
342                 cap->minwidth  = 48; /* FIXME */
343                 cap->minheight = 32; /* FIXME */
344                 break;
345         }
346         case VIDIOCGFBUF: /*  get frame buffer  */
347         {
348                 struct video_buffer     *buffer = arg;
349
350                 memset(buffer, 0, sizeof(*buffer));
351                 memset(&fbuf2, 0, sizeof(fbuf2));
352
353                 err = drv(inode, file, VIDIOC_G_FBUF, &fbuf2);
354                 if (err < 0) {
355                         dprintk("VIDIOCGFBUF / VIDIOC_G_FBUF: %d\n",err);
356                         break;
357                 }
358                 buffer->base   = fbuf2.base;
359                 buffer->height = fbuf2.fmt.height;
360                 buffer->width  = fbuf2.fmt.width;
361
362                 switch (fbuf2.fmt.pixelformat) {
363                 case V4L2_PIX_FMT_RGB332:
364                         buffer->depth = 8;
365                         break;
366                 case V4L2_PIX_FMT_RGB555:
367                         buffer->depth = 15;
368                         break;
369                 case V4L2_PIX_FMT_RGB565:
370                         buffer->depth = 16;
371                         break;
372                 case V4L2_PIX_FMT_BGR24:
373                         buffer->depth = 24;
374                         break;
375                 case V4L2_PIX_FMT_BGR32:
376                         buffer->depth = 32;
377                         break;
378                 default:
379                         buffer->depth = 0;
380                 }
381                 if (fbuf2.fmt.bytesperline) {
382                         buffer->bytesperline = fbuf2.fmt.bytesperline;
383                         if (!buffer->depth && buffer->width)
384                                 buffer->depth   = ((fbuf2.fmt.bytesperline<<3)
385                                                   + (buffer->width-1) )
386                                                   /buffer->width;
387                 } else {
388                         buffer->bytesperline =
389                                 (buffer->width * buffer->depth + 7) & 7;
390                         buffer->bytesperline >>= 3;
391                 }
392                 break;
393         }
394         case VIDIOCSFBUF: /*  set frame buffer  */
395         {
396                 struct video_buffer     *buffer = arg;
397
398                 memset(&fbuf2, 0, sizeof(fbuf2));
399                 fbuf2.base       = buffer->base;
400                 fbuf2.fmt.height = buffer->height;
401                 fbuf2.fmt.width  = buffer->width;
402                 switch (buffer->depth) {
403                 case 8:
404                         fbuf2.fmt.pixelformat = V4L2_PIX_FMT_RGB332;
405                         break;
406                 case 15:
407                         fbuf2.fmt.pixelformat = V4L2_PIX_FMT_RGB555;
408                         break;
409                 case 16:
410                         fbuf2.fmt.pixelformat = V4L2_PIX_FMT_RGB565;
411                         break;
412                 case 24:
413                         fbuf2.fmt.pixelformat = V4L2_PIX_FMT_BGR24;
414                         break;
415                 case 32:
416                         fbuf2.fmt.pixelformat = V4L2_PIX_FMT_BGR32;
417                         break;
418                 }
419                 fbuf2.fmt.bytesperline = buffer->bytesperline;
420                 err = drv(inode, file, VIDIOC_S_FBUF, &fbuf2);
421                 if (err < 0)
422                         dprintk("VIDIOCSFBUF / VIDIOC_S_FBUF: %d\n",err);
423                 break;
424         }
425         case VIDIOCGWIN: /*  get window or capture dimensions  */
426         {
427                 struct video_window     *win = arg;
428
429                 fmt2 = kzalloc(sizeof(*fmt2),GFP_KERNEL);
430                 memset(win,0,sizeof(*win));
431
432                 fmt2->type = V4L2_BUF_TYPE_VIDEO_OVERLAY;
433                 err = drv(inode, file, VIDIOC_G_FMT, fmt2);
434                 if (err < 0)
435                         dprintk("VIDIOCGWIN / VIDIOC_G_WIN: %d\n",err);
436                 if (err == 0) {
437                         win->x         = fmt2->fmt.win.w.left;
438                         win->y         = fmt2->fmt.win.w.top;
439                         win->width     = fmt2->fmt.win.w.width;
440                         win->height    = fmt2->fmt.win.w.height;
441                         win->chromakey = fmt2->fmt.win.chromakey;
442                         win->clips     = NULL;
443                         win->clipcount = 0;
444                         break;
445                 }
446
447                 fmt2->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
448                 err = drv(inode, file, VIDIOC_G_FMT, fmt2);
449                 if (err < 0) {
450                         dprintk("VIDIOCGWIN / VIDIOC_G_FMT: %d\n",err);
451                         break;
452                 }
453                 win->x         = 0;
454                 win->y         = 0;
455                 win->width     = fmt2->fmt.pix.width;
456                 win->height    = fmt2->fmt.pix.height;
457                 win->chromakey = 0;
458                 win->clips     = NULL;
459                 win->clipcount = 0;
460                 break;
461         }
462         case VIDIOCSWIN: /*  set window and/or capture dimensions  */
463         {
464                 struct video_window     *win = arg;
465                 int err1,err2;
466
467                 fmt2 = kzalloc(sizeof(*fmt2),GFP_KERNEL);
468                 fmt2->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
469                 drv(inode, file, VIDIOC_STREAMOFF, &fmt2->type);
470                 err1 = drv(inode, file, VIDIOC_G_FMT, fmt2);
471                 if (err1 < 0)
472                         dprintk("VIDIOCSWIN / VIDIOC_G_FMT: %d\n",err);
473                 if (err1 == 0) {
474                         fmt2->fmt.pix.width  = win->width;
475                         fmt2->fmt.pix.height = win->height;
476                         fmt2->fmt.pix.field  = V4L2_FIELD_ANY;
477                         fmt2->fmt.pix.bytesperline = 0;
478                         err = drv(inode, file, VIDIOC_S_FMT, fmt2);
479                         if (err < 0)
480                                 dprintk("VIDIOCSWIN / VIDIOC_S_FMT #1: %d\n",
481                                         err);
482                         win->width  = fmt2->fmt.pix.width;
483                         win->height = fmt2->fmt.pix.height;
484                 }
485
486                 memset(fmt2,0,sizeof(*fmt2));
487                 fmt2->type = V4L2_BUF_TYPE_VIDEO_OVERLAY;
488                 fmt2->fmt.win.w.left    = win->x;
489                 fmt2->fmt.win.w.top     = win->y;
490                 fmt2->fmt.win.w.width   = win->width;
491                 fmt2->fmt.win.w.height  = win->height;
492                 fmt2->fmt.win.chromakey = win->chromakey;
493                 fmt2->fmt.win.clips     = (void __user *)win->clips;
494                 fmt2->fmt.win.clipcount = win->clipcount;
495                 err2 = drv(inode, file, VIDIOC_S_FMT, fmt2);
496                 if (err2 < 0)
497                         dprintk("VIDIOCSWIN / VIDIOC_S_FMT #2: %d\n",err);
498
499                 if (err1 != 0 && err2 != 0)
500                         err = err1;
501                 break;
502         }
503         case VIDIOCCAPTURE: /*  turn on/off preview  */
504         {
505                 int *on = arg;
506
507                 if (0 == *on) {
508                         /* dirty hack time.  But v4l1 has no STREAMOFF
509                          * equivalent in the API, and this one at
510                          * least comes close ... */
511                         drv(inode, file, VIDIOC_STREAMOFF, &captype);
512                 }
513                 err = drv(inode, file, VIDIOC_OVERLAY, arg);
514                 if (err < 0)
515                         dprintk("VIDIOCCAPTURE / VIDIOC_PREVIEW: %d\n",err);
516                 break;
517         }
518         case VIDIOCGCHAN: /*  get input information  */
519         {
520                 struct video_channel    *chan = arg;
521
522                 memset(&input2,0,sizeof(input2));
523                 input2.index = chan->channel;
524                 err = drv(inode, file, VIDIOC_ENUMINPUT, &input2);
525                 if (err < 0) {
526                         dprintk("VIDIOCGCHAN / VIDIOC_ENUMINPUT: "
527                                 "channel=%d err=%d\n",chan->channel,err);
528                         break;
529                 }
530                 chan->channel = input2.index;
531                 memcpy(chan->name, input2.name,
532                        min(sizeof(chan->name), sizeof(input2.name)));
533                 chan->name[sizeof(chan->name) - 1] = 0;
534                 chan->tuners = (input2.type == V4L2_INPUT_TYPE_TUNER) ? 1 : 0;
535                 chan->flags = (chan->tuners) ? VIDEO_VC_TUNER : 0;
536                 switch (input2.type) {
537                 case V4L2_INPUT_TYPE_TUNER:
538                         chan->type = VIDEO_TYPE_TV;
539                         break;
540                 default:
541                 case V4L2_INPUT_TYPE_CAMERA:
542                         chan->type = VIDEO_TYPE_CAMERA;
543                         break;
544                 }
545                 chan->norm = 0;
546                 err = drv(inode, file, VIDIOC_G_STD, &sid);
547                 if (err < 0)
548                         dprintk("VIDIOCGCHAN / VIDIOC_G_STD: %d\n",err);
549                 if (err == 0) {
550                         if (sid & V4L2_STD_PAL)
551                                 chan->norm = VIDEO_MODE_PAL;
552                         if (sid & V4L2_STD_NTSC)
553                                 chan->norm = VIDEO_MODE_NTSC;
554                         if (sid & V4L2_STD_SECAM)
555                                 chan->norm = VIDEO_MODE_SECAM;
556                 }
557                 break;
558         }
559         case VIDIOCSCHAN: /*  set input  */
560         {
561                 struct video_channel *chan = arg;
562
563                 sid = 0;
564                 err = drv(inode, file, VIDIOC_S_INPUT, &chan->channel);
565                 if (err < 0)
566                         dprintk("VIDIOCSCHAN / VIDIOC_S_INPUT: %d\n",err);
567                 switch (chan->norm) {
568                 case VIDEO_MODE_PAL:
569                         sid = V4L2_STD_PAL;
570                         break;
571                 case VIDEO_MODE_NTSC:
572                         sid = V4L2_STD_NTSC;
573                         break;
574                 case VIDEO_MODE_SECAM:
575                         sid = V4L2_STD_SECAM;
576                         break;
577                 }
578                 if (0 != sid) {
579                         err = drv(inode, file, VIDIOC_S_STD, &sid);
580                         if (err < 0)
581                                 dprintk("VIDIOCSCHAN / VIDIOC_S_STD: %d\n",err);
582                 }
583                 break;
584         }
585         case VIDIOCGPICT: /*  get tone controls & partial capture format  */
586         {
587                 struct video_picture    *pict = arg;
588
589                 pict->brightness = get_v4l_control(inode, file,
590                                                    V4L2_CID_BRIGHTNESS,drv);
591                 pict->hue = get_v4l_control(inode, file,
592                                             V4L2_CID_HUE, drv);
593                 pict->contrast = get_v4l_control(inode, file,
594                                                  V4L2_CID_CONTRAST, drv);
595                 pict->colour = get_v4l_control(inode, file,
596                                                V4L2_CID_SATURATION, drv);
597                 pict->whiteness = get_v4l_control(inode, file,
598                                                   V4L2_CID_WHITENESS, drv);
599
600                 fmt2 = kzalloc(sizeof(*fmt2),GFP_KERNEL);
601                 fmt2->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
602                 err = drv(inode, file, VIDIOC_G_FMT, fmt2);
603                 if (err < 0) {
604                         dprintk("VIDIOCGPICT / VIDIOC_G_FMT: %d\n",err);
605                         break;
606                 }
607
608                 pict->depth   = ((fmt2->fmt.pix.bytesperline<<3)
609                                  + (fmt2->fmt.pix.width-1) )
610                                  /fmt2->fmt.pix.width;
611                 pict->palette = pixelformat_to_palette(
612                         fmt2->fmt.pix.pixelformat);
613                 break;
614         }
615         case VIDIOCSPICT: /*  set tone controls & partial capture format  */
616         {
617                 struct video_picture    *pict = arg;
618                 int mem_err = 0, ovl_err = 0;
619
620                 memset(&fbuf2, 0, sizeof(fbuf2));
621
622                 set_v4l_control(inode, file,
623                                 V4L2_CID_BRIGHTNESS, pict->brightness, drv);
624                 set_v4l_control(inode, file,
625                                 V4L2_CID_HUE, pict->hue, drv);
626                 set_v4l_control(inode, file,
627                                 V4L2_CID_CONTRAST, pict->contrast, drv);
628                 set_v4l_control(inode, file,
629                                 V4L2_CID_SATURATION, pict->colour, drv);
630                 set_v4l_control(inode, file,
631                                 V4L2_CID_WHITENESS, pict->whiteness, drv);
632                 /*
633                  * V4L1 uses this ioctl to set both memory capture and overlay
634                  * pixel format, while V4L2 has two different ioctls for this.
635                  * Some cards may not support one or the other, and may support
636                  * different pixel formats for memory vs overlay.
637                  */
638
639                 fmt2 = kzalloc(sizeof(*fmt2),GFP_KERNEL);
640                 fmt2->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
641                 err = drv(inode, file, VIDIOC_G_FMT, fmt2);
642                 /* If VIDIOC_G_FMT failed, then the driver likely doesn't
643                    support memory capture.  Trying to set the memory capture
644                    parameters would be pointless.  */
645                 if (err < 0) {
646                         dprintk("VIDIOCSPICT / VIDIOC_G_FMT: %d\n",err);
647                         mem_err = -1000;  /* didn't even try */
648                 } else if (fmt2->fmt.pix.pixelformat !=
649                          palette_to_pixelformat(pict->palette)) {
650                         fmt2->fmt.pix.pixelformat = palette_to_pixelformat(
651                                 pict->palette);
652                         mem_err = drv(inode, file, VIDIOC_S_FMT, fmt2);
653                         if (mem_err < 0)
654                                 dprintk("VIDIOCSPICT / VIDIOC_S_FMT: %d\n",
655                                         mem_err);
656                 }
657
658                 err = drv(inode, file, VIDIOC_G_FBUF, &fbuf2);
659                 /* If VIDIOC_G_FBUF failed, then the driver likely doesn't
660                    support overlay.  Trying to set the overlay parameters
661                    would be quite pointless.  */
662                 if (err < 0) {
663                         dprintk("VIDIOCSPICT / VIDIOC_G_FBUF: %d\n",err);
664                         ovl_err = -1000;  /* didn't even try */
665                 } else if (fbuf2.fmt.pixelformat !=
666                          palette_to_pixelformat(pict->palette)) {
667                         fbuf2.fmt.pixelformat = palette_to_pixelformat(
668                                 pict->palette);
669                         ovl_err = drv(inode, file, VIDIOC_S_FBUF, &fbuf2);
670                         if (ovl_err < 0)
671                                 dprintk("VIDIOCSPICT / VIDIOC_S_FBUF: %d\n",
672                                         ovl_err);
673                 }
674                 if (ovl_err < 0 && mem_err < 0)
675                         /* ioctl failed, couldn't set either parameter */
676                         if (mem_err != -1000) {
677                             err = mem_err;
678                         } else if (ovl_err == -EPERM) {
679                             err = 0;
680                         } else {
681                             err = ovl_err;
682                         }
683                 else
684                         err = 0;
685                 break;
686         }
687         case VIDIOCGTUNER: /*  get tuner information  */
688         {
689                 struct video_tuner      *tun = arg;
690
691                 memset(&tun2,0,sizeof(tun2));
692                 err = drv(inode, file, VIDIOC_G_TUNER, &tun2);
693                 if (err < 0) {
694                         dprintk("VIDIOCGTUNER / VIDIOC_G_TUNER: %d\n",err);
695                         break;
696                 }
697                 memcpy(tun->name, tun2.name,
698                        min(sizeof(tun->name), sizeof(tun2.name)));
699                 tun->name[sizeof(tun->name) - 1] = 0;
700                 tun->rangelow = tun2.rangelow;
701                 tun->rangehigh = tun2.rangehigh;
702                 tun->flags = 0;
703                 tun->mode = VIDEO_MODE_AUTO;
704
705                 for (i = 0; i < 64; i++) {
706                         memset(&std2,0,sizeof(std2));
707                         std2.index = i;
708                         if (0 != drv(inode, file, VIDIOC_ENUMSTD, &std2))
709                                 break;
710                         if (std2.id & V4L2_STD_PAL)
711                                 tun->flags |= VIDEO_TUNER_PAL;
712                         if (std2.id & V4L2_STD_NTSC)
713                                 tun->flags |= VIDEO_TUNER_NTSC;
714                         if (std2.id & V4L2_STD_SECAM)
715                                 tun->flags |= VIDEO_TUNER_SECAM;
716                 }
717
718                 err = drv(inode, file, VIDIOC_G_STD, &sid);
719                 if (err < 0)
720                         dprintk("VIDIOCGTUNER / VIDIOC_G_STD: %d\n",err);
721                 if (err == 0) {
722                         if (sid & V4L2_STD_PAL)
723                                 tun->mode = VIDEO_MODE_PAL;
724                         if (sid & V4L2_STD_NTSC)
725                                 tun->mode = VIDEO_MODE_NTSC;
726                         if (sid & V4L2_STD_SECAM)
727                                 tun->mode = VIDEO_MODE_SECAM;
728                 }
729
730                 if (tun2.capability & V4L2_TUNER_CAP_LOW)
731                         tun->flags |= VIDEO_TUNER_LOW;
732                 if (tun2.rxsubchans & V4L2_TUNER_SUB_STEREO)
733                         tun->flags |= VIDEO_TUNER_STEREO_ON;
734                 tun->signal = tun2.signal;
735                 break;
736         }
737         case VIDIOCSTUNER: /*  select a tuner input  */
738         {
739                 struct video_tuner      *tun = arg;
740                 struct v4l2_tuner       t;
741                 memset(&t,0,sizeof(t));
742
743                 t.index=tun->tuner;
744
745                 err = drv(inode, file, VIDIOC_S_INPUT, &t);
746                 if (err < 0)
747                         dprintk("VIDIOCSTUNER / VIDIOC_S_INPUT: %d\n",err);
748
749                 break;
750         }
751         case VIDIOCGFREQ: /*  get frequency  */
752         {
753                 unsigned long *freq = arg;
754                 memset(&freq2,0,sizeof(freq2));
755
756                 freq2.tuner = 0;
757                 err = drv(inode, file, VIDIOC_G_FREQUENCY, &freq2);
758                 if (err < 0)
759                         dprintk("VIDIOCGFREQ / VIDIOC_G_FREQUENCY: %d\n",err);
760                 if (0 == err)
761                         *freq = freq2.frequency;
762                 break;
763         }
764         case VIDIOCSFREQ: /*  set frequency  */
765         {
766                 unsigned long *freq = arg;
767                 memset(&freq2,0,sizeof(freq2));
768
769                 drv(inode, file, VIDIOC_G_FREQUENCY, &freq2);
770                 freq2.frequency = *freq;
771                 err = drv(inode, file, VIDIOC_S_FREQUENCY, &freq2);
772                 if (err < 0)
773                         dprintk("VIDIOCSFREQ / VIDIOC_S_FREQUENCY: %d\n",err);
774                 break;
775         }
776         case VIDIOCGAUDIO: /*  get audio properties/controls  */
777         {
778                 struct video_audio      *aud = arg;
779                 memset(&aud2,0,sizeof(aud2));
780
781                 err = drv(inode, file, VIDIOC_G_AUDIO, &aud2);
782                 if (err < 0) {
783                         dprintk("VIDIOCGAUDIO / VIDIOC_G_AUDIO: %d\n",err);
784                         break;
785                 }
786                 memcpy(aud->name, aud2.name,
787                        min(sizeof(aud->name), sizeof(aud2.name)));
788                 aud->name[sizeof(aud->name) - 1] = 0;
789                 aud->audio = aud2.index;
790                 aud->flags = 0;
791                 i = get_v4l_control(inode, file, V4L2_CID_AUDIO_VOLUME, drv);
792                 if (i >= 0) {
793                         aud->volume = i;
794                         aud->flags |= VIDEO_AUDIO_VOLUME;
795                 }
796                 i = get_v4l_control(inode, file, V4L2_CID_AUDIO_BASS, drv);
797                 if (i >= 0) {
798                         aud->bass = i;
799                         aud->flags |= VIDEO_AUDIO_BASS;
800                 }
801                 i = get_v4l_control(inode, file, V4L2_CID_AUDIO_TREBLE, drv);
802                 if (i >= 0) {
803                         aud->treble = i;
804                         aud->flags |= VIDEO_AUDIO_TREBLE;
805                 }
806                 i = get_v4l_control(inode, file, V4L2_CID_AUDIO_BALANCE, drv);
807                 if (i >= 0) {
808                         aud->balance = i;
809                         aud->flags |= VIDEO_AUDIO_BALANCE;
810                 }
811                 i = get_v4l_control(inode, file, V4L2_CID_AUDIO_MUTE, drv);
812                 if (i >= 0) {
813                         if (i)
814                                 aud->flags |= VIDEO_AUDIO_MUTE;
815                         aud->flags |= VIDEO_AUDIO_MUTABLE;
816                 }
817                 aud->step = 1;
818                 qctrl2.id = V4L2_CID_AUDIO_VOLUME;
819                 if (drv(inode, file, VIDIOC_QUERYCTRL, &qctrl2) == 0 &&
820                     !(qctrl2.flags & V4L2_CTRL_FLAG_DISABLED))
821                         aud->step = qctrl2.step;
822                 aud->mode = 0;
823
824                 memset(&tun2,0,sizeof(tun2));
825                 err = drv(inode, file, VIDIOC_G_TUNER, &tun2);
826                 if (err < 0) {
827                         dprintk("VIDIOCGAUDIO / VIDIOC_G_TUNER: %d\n",err);
828                         err = 0;
829                         break;
830                 }
831
832                 if (tun2.rxsubchans & V4L2_TUNER_SUB_LANG2)
833                         aud->mode = VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
834                 else if (tun2.rxsubchans & V4L2_TUNER_SUB_STEREO)
835                         aud->mode = VIDEO_SOUND_STEREO;
836                 else if (tun2.rxsubchans & V4L2_TUNER_SUB_MONO)
837                         aud->mode = VIDEO_SOUND_MONO;
838                 break;
839         }
840         case VIDIOCSAUDIO: /*  set audio controls  */
841         {
842                 struct video_audio      *aud = arg;
843
844                 memset(&aud2,0,sizeof(aud2));
845                 memset(&tun2,0,sizeof(tun2));
846
847                 aud2.index = aud->audio;
848                 err = drv(inode, file, VIDIOC_S_AUDIO, &aud2);
849                 if (err < 0) {
850                         dprintk("VIDIOCSAUDIO / VIDIOC_S_AUDIO: %d\n",err);
851                         break;
852                 }
853
854                 set_v4l_control(inode, file, V4L2_CID_AUDIO_VOLUME,
855                                 aud->volume, drv);
856                 set_v4l_control(inode, file, V4L2_CID_AUDIO_BASS,
857                                 aud->bass, drv);
858                 set_v4l_control(inode, file, V4L2_CID_AUDIO_TREBLE,
859                                 aud->treble, drv);
860                 set_v4l_control(inode, file, V4L2_CID_AUDIO_BALANCE,
861                                 aud->balance, drv);
862                 set_v4l_control(inode, file, V4L2_CID_AUDIO_MUTE,
863                                 !!(aud->flags & VIDEO_AUDIO_MUTE), drv);
864
865                 err = drv(inode, file, VIDIOC_G_TUNER, &tun2);
866                 if (err < 0)
867                         dprintk("VIDIOCSAUDIO / VIDIOC_G_TUNER: %d\n",err);
868                 if (err == 0) {
869                         switch (aud->mode) {
870                         default:
871                         case VIDEO_SOUND_MONO:
872                         case VIDEO_SOUND_LANG1:
873                                 tun2.audmode = V4L2_TUNER_MODE_MONO;
874                                 break;
875                         case VIDEO_SOUND_STEREO:
876                                 tun2.audmode = V4L2_TUNER_MODE_STEREO;
877                                 break;
878                         case VIDEO_SOUND_LANG2:
879                                 tun2.audmode = V4L2_TUNER_MODE_LANG2;
880                                 break;
881                         }
882                         err = drv(inode, file, VIDIOC_S_TUNER, &tun2);
883                         if (err < 0)
884                                 dprintk("VIDIOCSAUDIO / VIDIOC_S_TUNER: %d\n",err);
885                 }
886                 err = 0;
887                 break;
888         }
889         case VIDIOCMCAPTURE: /*  capture a frame  */
890         {
891                 struct video_mmap       *mm = arg;
892
893                 fmt2 = kzalloc(sizeof(*fmt2),GFP_KERNEL);
894                 memset(&buf2,0,sizeof(buf2));
895
896                 fmt2->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
897                 err = drv(inode, file, VIDIOC_G_FMT, fmt2);
898                 if (err < 0) {
899                         dprintk("VIDIOCMCAPTURE / VIDIOC_G_FMT: %d\n",err);
900                         break;
901                 }
902                 if (mm->width   != fmt2->fmt.pix.width  ||
903                     mm->height  != fmt2->fmt.pix.height ||
904                     palette_to_pixelformat(mm->format) !=
905                     fmt2->fmt.pix.pixelformat)
906                 {/* New capture format...  */
907                         fmt2->fmt.pix.width = mm->width;
908                         fmt2->fmt.pix.height = mm->height;
909                         fmt2->fmt.pix.pixelformat =
910                                 palette_to_pixelformat(mm->format);
911                         fmt2->fmt.pix.field = V4L2_FIELD_ANY;
912                         fmt2->fmt.pix.bytesperline = 0;
913                         err = drv(inode, file, VIDIOC_S_FMT, fmt2);
914                         if (err < 0) {
915                                 dprintk("VIDIOCMCAPTURE / VIDIOC_S_FMT: %d\n",err);
916                                 break;
917                         }
918                 }
919                 buf2.index = mm->frame;
920                 buf2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
921                 err = drv(inode, file, VIDIOC_QUERYBUF, &buf2);
922                 if (err < 0) {
923                         dprintk("VIDIOCMCAPTURE / VIDIOC_QUERYBUF: %d\n",err);
924                         break;
925                 }
926                 err = drv(inode, file, VIDIOC_QBUF, &buf2);
927                 if (err < 0) {
928                         dprintk("VIDIOCMCAPTURE / VIDIOC_QBUF: %d\n",err);
929                         break;
930                 }
931                 err = drv(inode, file, VIDIOC_STREAMON, &captype);
932                 if (err < 0)
933                         dprintk("VIDIOCMCAPTURE / VIDIOC_STREAMON: %d\n",err);
934                 break;
935         }
936         case VIDIOCSYNC: /*  wait for a frame  */
937         {
938                 int                     *i = arg;
939
940                 memset(&buf2,0,sizeof(buf2));
941                 buf2.index = *i;
942                 buf2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
943                 err = drv(inode, file, VIDIOC_QUERYBUF, &buf2);
944                 if (err < 0) {
945                         /*  No such buffer */
946                         dprintk("VIDIOCSYNC / VIDIOC_QUERYBUF: %d\n",err);
947                         break;
948                 }
949                 if (!(buf2.flags & V4L2_BUF_FLAG_MAPPED)) {
950                         /* Buffer is not mapped  */
951                         err = -EINVAL;
952                         break;
953                 }
954
955                 /* make sure capture actually runs so we don't block forever */
956                 err = drv(inode, file, VIDIOC_STREAMON, &captype);
957                 if (err < 0) {
958                         dprintk("VIDIOCSYNC / VIDIOC_STREAMON: %d\n",err);
959                         break;
960                 }
961
962                 /*  Loop as long as the buffer is queued, but not done  */
963                 while ((buf2.flags &
964                         (V4L2_BUF_FLAG_QUEUED | V4L2_BUF_FLAG_DONE))
965                        == V4L2_BUF_FLAG_QUEUED)
966                 {
967                         err = poll_one(file);
968                         if (err < 0 ||  /* error or sleep was interrupted  */
969                             err == 0)   /* timeout? Shouldn't occur.  */
970                                 break;
971                         err = drv(inode, file, VIDIOC_QUERYBUF, &buf2);
972                         if (err < 0)
973                                 dprintk("VIDIOCSYNC / VIDIOC_QUERYBUF: %d\n",err);
974                 }
975                 if (!(buf2.flags & V4L2_BUF_FLAG_DONE)) /* not done */
976                         break;
977                 do {
978                         err = drv(inode, file, VIDIOC_DQBUF, &buf2);
979                         if (err < 0)
980                                 dprintk("VIDIOCSYNC / VIDIOC_DQBUF: %d\n",err);
981                 } while (err == 0 && buf2.index != *i);
982                 break;
983         }
984
985         case VIDIOCGVBIFMT: /* query VBI data capture format */
986         {
987                 struct vbi_format      *fmt = arg;
988
989                 fmt2 = kzalloc(sizeof(*fmt2),GFP_KERNEL);
990                 fmt2->type = V4L2_BUF_TYPE_VBI_CAPTURE;
991
992                 err = drv(inode, file, VIDIOC_G_FMT, fmt2);
993                 if (err < 0) {
994                         dprintk("VIDIOCGVBIFMT / VIDIOC_G_FMT: %d\n", err);
995                         break;
996                 }
997                 if (fmt2->fmt.vbi.sample_format != V4L2_PIX_FMT_GREY) {
998                         err = -EINVAL;
999                         break;
1000                 }
1001                 memset(fmt, 0, sizeof(*fmt));
1002                 fmt->samples_per_line = fmt2->fmt.vbi.samples_per_line;
1003                 fmt->sampling_rate    = fmt2->fmt.vbi.sampling_rate;
1004                 fmt->sample_format    = VIDEO_PALETTE_RAW;
1005                 fmt->start[0]         = fmt2->fmt.vbi.start[0];
1006                 fmt->count[0]         = fmt2->fmt.vbi.count[0];
1007                 fmt->start[1]         = fmt2->fmt.vbi.start[1];
1008                 fmt->count[1]         = fmt2->fmt.vbi.count[1];
1009                 fmt->flags            = fmt2->fmt.vbi.flags & 0x03;
1010                 break;
1011         }
1012         case VIDIOCSVBIFMT:
1013         {
1014                 struct vbi_format      *fmt = arg;
1015
1016                 if (VIDEO_PALETTE_RAW != fmt->sample_format) {
1017                         err = -EINVAL;
1018                         break;
1019                 }
1020
1021                 fmt2 = kzalloc(sizeof(*fmt2),GFP_KERNEL);
1022
1023                 fmt2->type = V4L2_BUF_TYPE_VBI_CAPTURE;
1024                 fmt2->fmt.vbi.samples_per_line = fmt->samples_per_line;
1025                 fmt2->fmt.vbi.sampling_rate    = fmt->sampling_rate;
1026                 fmt2->fmt.vbi.sample_format    = V4L2_PIX_FMT_GREY;
1027                 fmt2->fmt.vbi.start[0]         = fmt->start[0];
1028                 fmt2->fmt.vbi.count[0]         = fmt->count[0];
1029                 fmt2->fmt.vbi.start[1]         = fmt->start[1];
1030                 fmt2->fmt.vbi.count[1]         = fmt->count[1];
1031                 fmt2->fmt.vbi.flags            = fmt->flags;
1032                 err = drv(inode, file, VIDIOC_TRY_FMT, fmt2);
1033                 if (err < 0) {
1034                         dprintk("VIDIOCSVBIFMT / VIDIOC_TRY_FMT: %d\n", err);
1035                         break;
1036                 }
1037
1038                 if (fmt2->fmt.vbi.samples_per_line != fmt->samples_per_line ||
1039                     fmt2->fmt.vbi.sampling_rate    != fmt->sampling_rate    ||
1040                     fmt2->fmt.vbi.sample_format    != V4L2_PIX_FMT_GREY     ||
1041                     fmt2->fmt.vbi.start[0]         != fmt->start[0]         ||
1042                     fmt2->fmt.vbi.count[0]         != fmt->count[0]         ||
1043                     fmt2->fmt.vbi.start[1]         != fmt->start[1]         ||
1044                     fmt2->fmt.vbi.count[1]         != fmt->count[1]         ||
1045                     fmt2->fmt.vbi.flags            != fmt->flags) {
1046                         err = -EINVAL;
1047                         break;
1048                 }
1049                 err = drv(inode, file, VIDIOC_S_FMT, fmt2);
1050                 if (err < 0)
1051                         dprintk("VIDIOCSVBIFMT / VIDIOC_S_FMT: %d\n", err);
1052                 break;
1053         }
1054
1055         default:
1056                 err = -ENOIOCTLCMD;
1057                 break;
1058         }
1059
1060         kfree(cap2);
1061         kfree(fmt2);
1062         return err;
1063 }
1064
1065 EXPORT_SYMBOL(v4l_compat_translate_ioctl);
1066
1067 /*
1068  * Local variables:
1069  * c-basic-offset: 8
1070  * End:
1071  */