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