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