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