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