Merge git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc
[linux-2.6] / drivers / media / video / videodev.c
1 /*
2  * Video capture interface for Linux version 2
3  *
4  *      A generic video device interface for the LINUX operating system
5  *      using a set of device structures/vectors for low level operations.
6  *
7  *      This program is free software; you can redistribute it and/or
8  *      modify it under the terms of the GNU General Public License
9  *      as published by the Free Software Foundation; either version
10  *      2 of the License, or (at your option) any later version.
11  *
12  * Authors:     Alan Cox, <alan@redhat.com> (version 1)
13  *              Mauro Carvalho Chehab <mchehab@infradead.org> (version 2)
14  *
15  * Fixes:       20000516  Claudio Matsuoka <claudio@conectiva.com>
16  *              - Added procfs support
17  */
18
19 #define dbgarg(cmd, fmt, arg...) \
20                 if (vfd->debug & V4L2_DEBUG_IOCTL_ARG)                  \
21                         printk (KERN_DEBUG "%s: ",  vfd->name);         \
22                         v4l_printk_ioctl(cmd);                          \
23                         printk (KERN_DEBUG "%s: " fmt, vfd->name, ## arg);
24
25 #define dbgarg2(fmt, arg...) \
26                 if (vfd->debug & V4L2_DEBUG_IOCTL_ARG)                  \
27                         printk (KERN_DEBUG "%s: " fmt, vfd->name, ## arg);
28
29 #include <linux/module.h>
30 #include <linux/types.h>
31 #include <linux/kernel.h>
32 #include <linux/sched.h>
33 #include <linux/smp_lock.h>
34 #include <linux/mm.h>
35 #include <linux/string.h>
36 #include <linux/errno.h>
37 #include <linux/init.h>
38 #include <linux/kmod.h>
39 #include <linux/slab.h>
40 #include <asm/uaccess.h>
41 #include <asm/system.h>
42
43 #define __OLD_VIDIOC_ /* To allow fixing old calls*/
44 #include <linux/videodev2.h>
45
46 #ifdef CONFIG_VIDEO_V4L1
47 #include <linux/videodev.h>
48 #endif
49 #include <media/v4l2-common.h>
50
51 #define VIDEO_NUM_DEVICES       256
52 #define VIDEO_NAME              "video4linux"
53
54 /*
55  *      sysfs stuff
56  */
57
58 static ssize_t show_name(struct class_device *cd, char *buf)
59 {
60         struct video_device *vfd = container_of(cd, struct video_device,
61                                                                 class_dev);
62         return sprintf(buf,"%.*s\n",(int)sizeof(vfd->name),vfd->name);
63 }
64
65 static CLASS_DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
66
67 struct video_device *video_device_alloc(void)
68 {
69         struct video_device *vfd;
70
71         vfd = kzalloc(sizeof(*vfd),GFP_KERNEL);
72         return vfd;
73 }
74
75 void video_device_release(struct video_device *vfd)
76 {
77         kfree(vfd);
78 }
79
80 static void video_release(struct class_device *cd)
81 {
82         struct video_device *vfd = container_of(cd, struct video_device,
83                                                                 class_dev);
84
85 #if 1
86         /* needed until all drivers are fixed */
87         if (!vfd->release)
88                 return;
89 #endif
90         vfd->release(vfd);
91 }
92
93 static struct class video_class = {
94         .name    = VIDEO_NAME,
95         .release = video_release,
96 };
97
98 /*
99  *      Active devices
100  */
101
102 static struct video_device *video_device[VIDEO_NUM_DEVICES];
103 static DEFINE_MUTEX(videodev_lock);
104
105 struct video_device* video_devdata(struct file *file)
106 {
107         return video_device[iminor(file->f_dentry->d_inode)];
108 }
109
110 /*
111  *      Open a video device - FIXME: Obsoleted
112  */
113 static int video_open(struct inode *inode, struct file *file)
114 {
115         unsigned int minor = iminor(inode);
116         int err = 0;
117         struct video_device *vfl;
118         const struct file_operations *old_fops;
119
120         if(minor>=VIDEO_NUM_DEVICES)
121                 return -ENODEV;
122         mutex_lock(&videodev_lock);
123         vfl=video_device[minor];
124         if(vfl==NULL) {
125                 mutex_unlock(&videodev_lock);
126                 request_module("char-major-%d-%d", VIDEO_MAJOR, minor);
127                 mutex_lock(&videodev_lock);
128                 vfl=video_device[minor];
129                 if (vfl==NULL) {
130                         mutex_unlock(&videodev_lock);
131                         return -ENODEV;
132                 }
133         }
134         old_fops = file->f_op;
135         file->f_op = fops_get(vfl->fops);
136         if(file->f_op->open)
137                 err = file->f_op->open(inode,file);
138         if (err) {
139                 fops_put(file->f_op);
140                 file->f_op = fops_get(old_fops);
141         }
142         fops_put(old_fops);
143         mutex_unlock(&videodev_lock);
144         return err;
145 }
146
147 /*
148  * helper function -- handles userspace copying for ioctl arguments
149  */
150
151 #ifdef __OLD_VIDIOC_
152 static unsigned int
153 video_fix_command(unsigned int cmd)
154 {
155         switch (cmd) {
156         case VIDIOC_OVERLAY_OLD:
157                 cmd = VIDIOC_OVERLAY;
158                 break;
159         case VIDIOC_S_PARM_OLD:
160                 cmd = VIDIOC_S_PARM;
161                 break;
162         case VIDIOC_S_CTRL_OLD:
163                 cmd = VIDIOC_S_CTRL;
164                 break;
165         case VIDIOC_G_AUDIO_OLD:
166                 cmd = VIDIOC_G_AUDIO;
167                 break;
168         case VIDIOC_G_AUDOUT_OLD:
169                 cmd = VIDIOC_G_AUDOUT;
170                 break;
171         case VIDIOC_CROPCAP_OLD:
172                 cmd = VIDIOC_CROPCAP;
173                 break;
174         }
175         return cmd;
176 }
177 #endif
178
179 /*
180  * Obsolete usercopy function - Should be removed soon
181  */
182 int
183 video_usercopy(struct inode *inode, struct file *file,
184                unsigned int cmd, unsigned long arg,
185                int (*func)(struct inode *inode, struct file *file,
186                            unsigned int cmd, void *arg))
187 {
188         char    sbuf[128];
189         void    *mbuf = NULL;
190         void    *parg = NULL;
191         int     err  = -EINVAL;
192         int     is_ext_ctrl;
193         size_t  ctrls_size = 0;
194         void __user *user_ptr = NULL;
195
196 #ifdef __OLD_VIDIOC_
197         cmd = video_fix_command(cmd);
198 #endif
199         is_ext_ctrl = (cmd == VIDIOC_S_EXT_CTRLS || cmd == VIDIOC_G_EXT_CTRLS ||
200                        cmd == VIDIOC_TRY_EXT_CTRLS);
201
202         /*  Copy arguments into temp kernel buffer  */
203         switch (_IOC_DIR(cmd)) {
204         case _IOC_NONE:
205                 parg = NULL;
206                 break;
207         case _IOC_READ:
208         case _IOC_WRITE:
209         case (_IOC_WRITE | _IOC_READ):
210                 if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
211                         parg = sbuf;
212                 } else {
213                         /* too big to allocate from stack */
214                         mbuf = kmalloc(_IOC_SIZE(cmd),GFP_KERNEL);
215                         if (NULL == mbuf)
216                                 return -ENOMEM;
217                         parg = mbuf;
218                 }
219
220                 err = -EFAULT;
221                 if (_IOC_DIR(cmd) & _IOC_WRITE)
222                         if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd)))
223                                 goto out;
224                 break;
225         }
226         if (is_ext_ctrl) {
227                 struct v4l2_ext_controls *p = parg;
228
229                 /* In case of an error, tell the caller that it wasn't
230                    a specific control that caused it. */
231                 p->error_idx = p->count;
232                 user_ptr = (void __user *)p->controls;
233                 if (p->count) {
234                         ctrls_size = sizeof(struct v4l2_ext_control) * p->count;
235                         /* Note: v4l2_ext_controls fits in sbuf[] so mbuf is still NULL. */
236                         mbuf = kmalloc(ctrls_size, GFP_KERNEL);
237                         err = -ENOMEM;
238                         if (NULL == mbuf)
239                                 goto out_ext_ctrl;
240                         err = -EFAULT;
241                         if (copy_from_user(mbuf, user_ptr, ctrls_size))
242                                 goto out_ext_ctrl;
243                         p->controls = mbuf;
244                 }
245         }
246
247         /* call driver */
248         err = func(inode, file, cmd, parg);
249         if (err == -ENOIOCTLCMD)
250                 err = -EINVAL;
251         if (is_ext_ctrl) {
252                 struct v4l2_ext_controls *p = parg;
253
254                 p->controls = (void *)user_ptr;
255                 if (p->count && err == 0 && copy_to_user(user_ptr, mbuf, ctrls_size))
256                         err = -EFAULT;
257                 goto out_ext_ctrl;
258         }
259         if (err < 0)
260                 goto out;
261
262 out_ext_ctrl:
263         /*  Copy results into user buffer  */
264         switch (_IOC_DIR(cmd))
265         {
266         case _IOC_READ:
267         case (_IOC_WRITE | _IOC_READ):
268                 if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd)))
269                         err = -EFAULT;
270                 break;
271         }
272
273 out:
274         kfree(mbuf);
275         return err;
276 }
277
278 /*
279  * open/release helper functions -- handle exclusive opens
280  * Should be removed soon
281  */
282 int video_exclusive_open(struct inode *inode, struct file *file)
283 {
284         struct  video_device *vfl = video_devdata(file);
285         int retval = 0;
286
287         mutex_lock(&vfl->lock);
288         if (vfl->users) {
289                 retval = -EBUSY;
290         } else {
291                 vfl->users++;
292         }
293         mutex_unlock(&vfl->lock);
294         return retval;
295 }
296
297 int video_exclusive_release(struct inode *inode, struct file *file)
298 {
299         struct  video_device *vfl = video_devdata(file);
300
301         vfl->users--;
302         return 0;
303 }
304
305 static char *v4l2_memory_names[] = {
306         [V4L2_MEMORY_MMAP]    = "mmap",
307         [V4L2_MEMORY_USERPTR] = "userptr",
308         [V4L2_MEMORY_OVERLAY] = "overlay",
309 };
310
311
312 /* FIXME: Those stuff are replicated also on v4l2-common.c */
313 static char *v4l2_type_names_FIXME[] = {
314         [V4L2_BUF_TYPE_VIDEO_CAPTURE]      = "video-cap",
315         [V4L2_BUF_TYPE_VIDEO_OVERLAY]      = "video-over",
316         [V4L2_BUF_TYPE_VIDEO_OUTPUT]       = "video-out",
317         [V4L2_BUF_TYPE_VBI_CAPTURE]        = "vbi-cap",
318         [V4L2_BUF_TYPE_VBI_OUTPUT]         = "vbi-out",
319         [V4L2_BUF_TYPE_SLICED_VBI_OUTPUT]  = "sliced-vbi-out",
320         [V4L2_BUF_TYPE_SLICED_VBI_CAPTURE] = "sliced-vbi-capture",
321         [V4L2_BUF_TYPE_PRIVATE]            = "private",
322 };
323
324 static char *v4l2_field_names_FIXME[] = {
325         [V4L2_FIELD_ANY]        = "any",
326         [V4L2_FIELD_NONE]       = "none",
327         [V4L2_FIELD_TOP]        = "top",
328         [V4L2_FIELD_BOTTOM]     = "bottom",
329         [V4L2_FIELD_INTERLACED] = "interlaced",
330         [V4L2_FIELD_SEQ_TB]     = "seq-tb",
331         [V4L2_FIELD_SEQ_BT]     = "seq-bt",
332         [V4L2_FIELD_ALTERNATE]  = "alternate",
333 };
334
335 #define prt_names(a,arr) (((a)>=0)&&((a)<ARRAY_SIZE(arr)))?arr[a]:"unknown"
336
337 static void dbgbuf(unsigned int cmd, struct video_device *vfd,
338                                         struct v4l2_buffer *p)
339 {
340         struct v4l2_timecode *tc=&p->timecode;
341
342         dbgarg (cmd, "%02ld:%02d:%02d.%08ld index=%d, type=%s, "
343                 "bytesused=%d, flags=0x%08d, "
344                 "field=%0d, sequence=%d, memory=%s, offset/userptr=0x%08lx\n",
345                         (p->timestamp.tv_sec/3600),
346                         (int)(p->timestamp.tv_sec/60)%60,
347                         (int)(p->timestamp.tv_sec%60),
348                         p->timestamp.tv_usec,
349                         p->index,
350                         prt_names(p->type,v4l2_type_names_FIXME),
351                         p->bytesused,p->flags,
352                         p->field,p->sequence,
353                         prt_names(p->memory,v4l2_memory_names),
354                         p->m.userptr);
355         dbgarg2 ("timecode= %02d:%02d:%02d type=%d, "
356                 "flags=0x%08d, frames=%d, userbits=0x%08x\n",
357                         tc->hours,tc->minutes,tc->seconds,
358                         tc->type, tc->flags, tc->frames, *(__u32 *) tc->userbits);
359 }
360
361 static inline void dbgrect(struct video_device *vfd, char *s,
362                                                         struct v4l2_rect *r)
363 {
364         dbgarg2 ("%sRect start at %dx%d, size= %dx%d\n", s, r->left, r->top,
365                                                 r->width, r->height);
366 };
367
368 static inline void v4l_print_pix_fmt (struct video_device *vfd,
369                                                 struct v4l2_pix_format *fmt)
370 {
371         dbgarg2 ("width=%d, height=%d, format=0x%08x, field=%s, "
372                 "bytesperline=%d sizeimage=%d, colorspace=%d\n",
373                 fmt->width,fmt->height,fmt->pixelformat,
374                 prt_names(fmt->field,v4l2_field_names_FIXME),
375                 fmt->bytesperline,fmt->sizeimage,fmt->colorspace);
376 };
377
378
379 static int check_fmt (struct video_device *vfd, enum v4l2_buf_type type)
380 {
381         switch (type) {
382         case V4L2_BUF_TYPE_VIDEO_CAPTURE:
383                 if (vfd->vidioc_try_fmt_cap)
384                         return (0);
385                 break;
386         case V4L2_BUF_TYPE_VIDEO_OVERLAY:
387                 if (vfd->vidioc_try_fmt_overlay)
388                         return (0);
389                 break;
390         case V4L2_BUF_TYPE_VBI_CAPTURE:
391                 if (vfd->vidioc_try_fmt_vbi)
392                         return (0);
393                 break;
394         case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
395                 if (vfd->vidioc_try_fmt_vbi_output)
396                         return (0);
397                 break;
398         case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
399                 if (vfd->vidioc_try_fmt_vbi_capture)
400                         return (0);
401                 break;
402         case V4L2_BUF_TYPE_VIDEO_OUTPUT:
403                 if (vfd->vidioc_try_fmt_video_output)
404                         return (0);
405                 break;
406         case V4L2_BUF_TYPE_VBI_OUTPUT:
407                 if (vfd->vidioc_try_fmt_vbi_output)
408                         return (0);
409                 break;
410         case V4L2_BUF_TYPE_PRIVATE:
411                 if (vfd->vidioc_try_fmt_type_private)
412                         return (0);
413                 break;
414         }
415         return (-EINVAL);
416 }
417
418 static int __video_do_ioctl(struct inode *inode, struct file *file,
419                 unsigned int cmd, void *arg)
420 {
421         struct video_device *vfd = video_devdata(file);
422         void                 *fh = file->private_data;
423         int                  ret = -EINVAL;
424
425         if ( (vfd->debug & V4L2_DEBUG_IOCTL) &&
426                                 !(vfd->debug | V4L2_DEBUG_IOCTL_ARG)) {
427                 v4l_print_ioctl(vfd->name, cmd);
428         }
429
430         switch(cmd) {
431         /* --- capabilities ------------------------------------------ */
432         case VIDIOC_QUERYCAP:
433         {
434                 struct v4l2_capability *cap = (struct v4l2_capability*)arg;
435                 memset(cap, 0, sizeof(*cap));
436
437                 if (!vfd->vidioc_querycap)
438                         break;
439
440                 ret=vfd->vidioc_querycap(file, fh, cap);
441                 if (!ret)
442                         dbgarg (cmd, "driver=%s, card=%s, bus=%s, "
443                                         "version=0x%08x, "
444                                         "capabilities=0x%08x\n",
445                                         cap->driver,cap->card,cap->bus_info,
446                                         cap->version,
447                                         cap->capabilities);
448                 break;
449         }
450
451         /* --- priority ------------------------------------------ */
452         case VIDIOC_G_PRIORITY:
453         {
454                 enum v4l2_priority *p=arg;
455
456                 if (!vfd->vidioc_g_priority)
457                         break;
458                 ret=vfd->vidioc_g_priority(file, fh, p);
459                 if (!ret)
460                         dbgarg(cmd, "priority is %d\n", *p);
461                 break;
462         }
463         case VIDIOC_S_PRIORITY:
464         {
465                 enum v4l2_priority *p=arg;
466
467                 if (!vfd->vidioc_s_priority)
468                         break;
469                 dbgarg(cmd, "setting priority to %d\n", *p);
470                 ret=vfd->vidioc_s_priority(file, fh, *p);
471                 break;
472         }
473
474         /* --- capture ioctls ---------------------------------------- */
475         case VIDIOC_ENUM_FMT:
476         {
477                 struct v4l2_fmtdesc *f = arg;
478                 enum v4l2_buf_type type;
479                 unsigned int index;
480
481                 index = f->index;
482                 type  = f->type;
483                 memset(f,0,sizeof(*f));
484                 f->index = index;
485                 f->type  = type;
486
487                 switch (type) {
488                 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
489                         if (vfd->vidioc_enum_fmt_cap)
490                                 ret=vfd->vidioc_enum_fmt_cap(file, fh, f);
491                         break;
492                 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
493                         if (vfd->vidioc_enum_fmt_overlay)
494                                 ret=vfd->vidioc_enum_fmt_overlay(file, fh, f);
495                         break;
496                 case V4L2_BUF_TYPE_VBI_CAPTURE:
497                         if (vfd->vidioc_enum_fmt_vbi)
498                                 ret=vfd->vidioc_enum_fmt_vbi(file, fh, f);
499                         break;
500                 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
501                         if (vfd->vidioc_enum_fmt_vbi_output)
502                                 ret=vfd->vidioc_enum_fmt_vbi_output(file,
503                                                                 fh, f);
504                         break;
505                 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
506                         if (vfd->vidioc_enum_fmt_vbi_capture)
507                                 ret=vfd->vidioc_enum_fmt_vbi_capture(file,
508                                                                 fh, f);
509                         break;
510                 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
511                         if (vfd->vidioc_enum_fmt_video_output)
512                                 ret=vfd->vidioc_enum_fmt_video_output(file,
513                                                                 fh, f);
514                         break;
515                 case V4L2_BUF_TYPE_VBI_OUTPUT:
516                         if (vfd->vidioc_enum_fmt_vbi_output)
517                                 ret=vfd->vidioc_enum_fmt_vbi_output(file,
518                                                                 fh, f);
519                         break;
520                 case V4L2_BUF_TYPE_PRIVATE:
521                         if (vfd->vidioc_enum_fmt_type_private)
522                                 ret=vfd->vidioc_enum_fmt_type_private(file,
523                                                                 fh, f);
524                         break;
525                 }
526                 if (!ret)
527                         dbgarg (cmd, "index=%d, type=%d, flags=%d, "
528                                         "description=%s,"
529                                         " pixelformat=0x%8x\n",
530                                         f->index, f->type, f->flags,
531                                         f->description,
532                                         f->pixelformat);
533
534                 break;
535         }
536         case VIDIOC_G_FMT:
537         {
538                 struct v4l2_format *f = (struct v4l2_format *)arg;
539                 enum v4l2_buf_type type=f->type;
540
541                 memset(&f->fmt.pix,0,sizeof(f->fmt.pix));
542                 f->type=type;
543
544                 /* FIXME: Should be one dump per type */
545                 dbgarg (cmd, "type=%s\n", prt_names(type,
546                                         v4l2_type_names_FIXME));
547
548                 switch (type) {
549                 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
550                         if (vfd->vidioc_g_fmt_cap)
551                                 ret=vfd->vidioc_g_fmt_cap(file, fh, f);
552                         if (!ret)
553                                 v4l_print_pix_fmt(vfd,&f->fmt.pix);
554                         break;
555                 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
556                         if (vfd->vidioc_g_fmt_overlay)
557                                 ret=vfd->vidioc_g_fmt_overlay(file, fh, f);
558                         break;
559                 case V4L2_BUF_TYPE_VBI_CAPTURE:
560                         if (vfd->vidioc_g_fmt_vbi)
561                                 ret=vfd->vidioc_g_fmt_vbi(file, fh, f);
562                         break;
563                 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
564                         if (vfd->vidioc_g_fmt_vbi_output)
565                                 ret=vfd->vidioc_g_fmt_vbi_output(file, fh, f);
566                         break;
567                 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
568                         if (vfd->vidioc_g_fmt_vbi_capture)
569                                 ret=vfd->vidioc_g_fmt_vbi_capture(file, fh, f);
570                         break;
571                 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
572                         if (vfd->vidioc_g_fmt_video_output)
573                                 ret=vfd->vidioc_g_fmt_video_output(file,
574                                                                 fh, f);
575                         break;
576                 case V4L2_BUF_TYPE_VBI_OUTPUT:
577                         if (vfd->vidioc_g_fmt_vbi_output)
578                                 ret=vfd->vidioc_g_fmt_vbi_output(file, fh, f);
579                         break;
580                 case V4L2_BUF_TYPE_PRIVATE:
581                         if (vfd->vidioc_g_fmt_type_private)
582                                 ret=vfd->vidioc_g_fmt_type_private(file,
583                                                                 fh, f);
584                         break;
585                 }
586
587                 break;
588         }
589         case VIDIOC_S_FMT:
590         {
591                 struct v4l2_format *f = (struct v4l2_format *)arg;
592
593                 /* FIXME: Should be one dump per type */
594                 dbgarg (cmd, "type=%s\n", prt_names(f->type,
595                                         v4l2_type_names_FIXME));
596
597                 switch (f->type) {
598                 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
599                         v4l_print_pix_fmt(vfd,&f->fmt.pix);
600                         if (vfd->vidioc_s_fmt_cap)
601                                 ret=vfd->vidioc_s_fmt_cap(file, fh, f);
602                         break;
603                 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
604                         if (vfd->vidioc_s_fmt_overlay)
605                                 ret=vfd->vidioc_s_fmt_overlay(file, fh, f);
606                         break;
607                 case V4L2_BUF_TYPE_VBI_CAPTURE:
608                         if (vfd->vidioc_s_fmt_vbi)
609                                 ret=vfd->vidioc_s_fmt_vbi(file, fh, f);
610                         break;
611                 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
612                         if (vfd->vidioc_s_fmt_vbi_output)
613                                 ret=vfd->vidioc_s_fmt_vbi_output(file, fh, f);
614                         break;
615                 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
616                         if (vfd->vidioc_s_fmt_vbi_capture)
617                                 ret=vfd->vidioc_s_fmt_vbi_capture(file, fh, f);
618                         break;
619                 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
620                         if (vfd->vidioc_s_fmt_video_output)
621                                 ret=vfd->vidioc_s_fmt_video_output(file,
622                                                                 fh, f);
623                         break;
624                 case V4L2_BUF_TYPE_VBI_OUTPUT:
625                         if (vfd->vidioc_s_fmt_vbi_output)
626                                 ret=vfd->vidioc_s_fmt_vbi_output(file,
627                                                                 fh, f);
628                         break;
629                 case V4L2_BUF_TYPE_PRIVATE:
630                         if (vfd->vidioc_s_fmt_type_private)
631                                 ret=vfd->vidioc_s_fmt_type_private(file,
632                                                                 fh, f);
633                         break;
634                 }
635                 break;
636         }
637         case VIDIOC_TRY_FMT:
638         {
639                 struct v4l2_format *f = (struct v4l2_format *)arg;
640
641                 /* FIXME: Should be one dump per type */
642                 dbgarg (cmd, "type=%s\n", prt_names(f->type,
643                                                 v4l2_type_names_FIXME));
644                 switch (f->type) {
645                 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
646                         if (vfd->vidioc_try_fmt_cap)
647                                 ret=vfd->vidioc_try_fmt_cap(file, fh, f);
648                         if (!ret)
649                                 v4l_print_pix_fmt(vfd,&f->fmt.pix);
650                         break;
651                 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
652                         if (vfd->vidioc_try_fmt_overlay)
653                                 ret=vfd->vidioc_try_fmt_overlay(file, fh, f);
654                         break;
655                 case V4L2_BUF_TYPE_VBI_CAPTURE:
656                         if (vfd->vidioc_try_fmt_vbi)
657                                 ret=vfd->vidioc_try_fmt_vbi(file, fh, f);
658                         break;
659                 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
660                         if (vfd->vidioc_try_fmt_vbi_output)
661                                 ret=vfd->vidioc_try_fmt_vbi_output(file,
662                                                                 fh, f);
663                         break;
664                 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
665                         if (vfd->vidioc_try_fmt_vbi_capture)
666                                 ret=vfd->vidioc_try_fmt_vbi_capture(file,
667                                                                 fh, f);
668                         break;
669                 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
670                         if (vfd->vidioc_try_fmt_video_output)
671                                 ret=vfd->vidioc_try_fmt_video_output(file,
672                                                                 fh, f);
673                         break;
674                 case V4L2_BUF_TYPE_VBI_OUTPUT:
675                         if (vfd->vidioc_try_fmt_vbi_output)
676                                 ret=vfd->vidioc_try_fmt_vbi_output(file,
677                                                                 fh, f);
678                         break;
679                 case V4L2_BUF_TYPE_PRIVATE:
680                         if (vfd->vidioc_try_fmt_type_private)
681                                 ret=vfd->vidioc_try_fmt_type_private(file,
682                                                                 fh, f);
683                         break;
684                 }
685
686                 break;
687         }
688         /* FIXME: Those buf reqs could be handled here,
689            with some changes on videobuf to allow its header to be included at
690            videodev2.h or being merged at videodev2.
691          */
692         case VIDIOC_REQBUFS:
693         {
694                 struct v4l2_requestbuffers *p=arg;
695
696                 if (!vfd->vidioc_reqbufs)
697                         break;
698                 ret = check_fmt (vfd, p->type);
699                 if (ret)
700                         break;
701
702                 ret=vfd->vidioc_reqbufs(file, fh, p);
703                 dbgarg (cmd, "count=%d, type=%s, memory=%s\n",
704                                 p->count,
705                                 prt_names(p->type,v4l2_type_names_FIXME),
706                                 prt_names(p->memory,v4l2_memory_names));
707                 break;
708         }
709         case VIDIOC_QUERYBUF:
710         {
711                 struct v4l2_buffer *p=arg;
712
713                 if (!vfd->vidioc_querybuf)
714                         break;
715                 ret = check_fmt (vfd, p->type);
716                 if (ret)
717                         break;
718
719                 ret=vfd->vidioc_querybuf(file, fh, p);
720                 if (!ret)
721                         dbgbuf(cmd,vfd,p);
722                 break;
723         }
724         case VIDIOC_QBUF:
725         {
726                 struct v4l2_buffer *p=arg;
727
728                 if (!vfd->vidioc_qbuf)
729                         break;
730                 ret = check_fmt (vfd, p->type);
731                 if (ret)
732                         break;
733
734                 ret=vfd->vidioc_qbuf(file, fh, p);
735                 if (!ret)
736                         dbgbuf(cmd,vfd,p);
737                 break;
738         }
739         case VIDIOC_DQBUF:
740         {
741                 struct v4l2_buffer *p=arg;
742                 if (!vfd->vidioc_dqbuf)
743                         break;
744                 ret = check_fmt (vfd, p->type);
745                 if (ret)
746                         break;
747
748                 ret=vfd->vidioc_dqbuf(file, fh, p);
749                 if (!ret)
750                         dbgbuf(cmd,vfd,p);
751                 break;
752         }
753         case VIDIOC_OVERLAY:
754         {
755                 int *i = arg;
756
757                 if (!vfd->vidioc_overlay)
758                         break;
759                 dbgarg (cmd, "value=%d\n",*i);
760                 ret=vfd->vidioc_overlay(file, fh, *i);
761                 break;
762         }
763 #ifdef CONFIG_VIDEO_V4L1_COMPAT
764         /* --- streaming capture ------------------------------------- */
765         case VIDIOCGMBUF:
766         {
767                 struct video_mbuf *p=arg;
768
769                 memset(p,0,sizeof(p));
770
771                 if (!vfd->vidiocgmbuf)
772                         break;
773                 ret=vfd->vidiocgmbuf(file, fh, p);
774                 if (!ret)
775                         dbgarg (cmd, "size=%d, frames=%d, offsets=0x%08lx\n",
776                                                 p->size, p->frames,
777                                                 (unsigned long)p->offsets);
778                 break;
779         }
780 #endif
781         case VIDIOC_G_FBUF:
782         {
783                 struct v4l2_framebuffer *p=arg;
784                 if (!vfd->vidioc_g_fbuf)
785                         break;
786                 ret=vfd->vidioc_g_fbuf(file, fh, arg);
787                 if (!ret) {
788                         dbgarg (cmd, "capability=%d, flags=%d, base=0x%08lx\n",
789                                         p->capability,p->flags,
790                                         (unsigned long)p->base);
791                         v4l_print_pix_fmt (vfd, &p->fmt);
792                 }
793                 break;
794         }
795         case VIDIOC_S_FBUF:
796         {
797                 struct v4l2_framebuffer *p=arg;
798                 if (!vfd->vidioc_s_fbuf)
799                         break;
800
801                 dbgarg (cmd, "capability=%d, flags=%d, base=0x%08lx\n",
802                                 p->capability,p->flags,(unsigned long)p->base);
803                 v4l_print_pix_fmt (vfd, &p->fmt);
804                 ret=vfd->vidioc_s_fbuf(file, fh, arg);
805
806                 break;
807         }
808         case VIDIOC_STREAMON:
809         {
810                 enum v4l2_buf_type i = *(int *)arg;
811                 if (!vfd->vidioc_streamon)
812                         break;
813                 dbgarg (cmd, "type=%s\n", prt_names(i,v4l2_type_names_FIXME));
814                 ret=vfd->vidioc_streamon(file, fh,i);
815                 break;
816         }
817         case VIDIOC_STREAMOFF:
818         {
819                 enum v4l2_buf_type i = *(int *)arg;
820
821                 if (!vfd->vidioc_streamoff)
822                         break;
823                 dbgarg (cmd, "type=%s\n", prt_names(i,v4l2_type_names_FIXME));
824                 ret=vfd->vidioc_streamoff(file, fh, i);
825                 break;
826         }
827         /* ---------- tv norms ---------- */
828         case VIDIOC_ENUMSTD:
829         {
830                 struct v4l2_standard *p = arg;
831                 unsigned int index = p->index;
832
833                 if (!vfd->tvnormsize) {
834                         printk (KERN_WARNING "%s: no TV norms defined!\n",
835                                                 vfd->name);
836                         break;
837                 }
838
839                 if (index<0 || index >= vfd->tvnormsize) {
840                         ret=-EINVAL;
841                         break;
842                 }
843                 v4l2_video_std_construct(p, vfd->tvnorms[p->index].id,
844                                          vfd->tvnorms[p->index].name);
845                 p->index = index;
846
847                 dbgarg (cmd, "index=%d, id=%Ld, name=%s, fps=%d/%d, "
848                                 "framelines=%d\n", p->index,
849                                 (unsigned long long)p->id, p->name,
850                                 p->frameperiod.numerator,
851                                 p->frameperiod.denominator,
852                                 p->framelines);
853
854                 ret=0;
855                 break;
856         }
857         case VIDIOC_G_STD:
858         {
859                 v4l2_std_id *id = arg;
860
861                 *id = vfd->current_norm;
862
863                 dbgarg (cmd, "value=%Lu\n", (long long unsigned) *id);
864
865                 ret=0;
866                 break;
867         }
868         case VIDIOC_S_STD:
869         {
870                 v4l2_std_id *id = arg;
871                 unsigned int i;
872
873                 if (!vfd->tvnormsize) {
874                         printk (KERN_WARNING "%s: no TV norms defined!\n",
875                                                 vfd->name);
876                         break;
877                 }
878
879                 dbgarg (cmd, "value=%Lu\n", (long long unsigned) *id);
880
881                 /* First search for exact match */
882                 for (i = 0; i < vfd->tvnormsize; i++)
883                         if (*id == vfd->tvnorms[i].id)
884                                 break;
885                 /* Then for a generic video std that contains desired std */
886                 if (i == vfd->tvnormsize)
887                         for (i = 0; i < vfd->tvnormsize; i++)
888                                 if (*id & vfd->tvnorms[i].id)
889                                         break;
890                 if (i == vfd->tvnormsize) {
891                         break;
892                 }
893
894                 /* Calls the specific handler */
895                 if (vfd->vidioc_s_std)
896                         ret=vfd->vidioc_s_std(file, fh, i);
897                 else
898                         ret=-EINVAL;
899
900                 /* Updates standard information */
901                 if (!ret)
902                         vfd->current_norm=*id;
903
904                 break;
905         }
906         case VIDIOC_QUERYSTD:
907         {
908                 v4l2_std_id *p=arg;
909
910                 if (!vfd->vidioc_querystd)
911                         break;
912                 ret=vfd->vidioc_querystd(file, fh, arg);
913                 if (!ret)
914                         dbgarg (cmd, "detected std=%Lu\n",
915                                                 (unsigned long long)*p);
916                 break;
917         }
918         /* ------ input switching ---------- */
919         /* FIXME: Inputs can be handled inside videodev2 */
920         case VIDIOC_ENUMINPUT:
921         {
922                 struct v4l2_input *p=arg;
923                 int i=p->index;
924
925                 if (!vfd->vidioc_enum_input)
926                         break;
927                 memset(p, 0, sizeof(*p));
928                 p->index=i;
929
930                 ret=vfd->vidioc_enum_input(file, fh, p);
931                 if (!ret)
932                         dbgarg (cmd, "index=%d, name=%s, type=%d, "
933                                         "audioset=%d, "
934                                         "tuner=%d, std=%Ld, status=%d\n",
935                                         p->index,p->name,p->type,p->audioset,
936                                         p->tuner,
937                                         (unsigned long long)p->std,
938                                         p->status);
939                 break;
940         }
941         case VIDIOC_G_INPUT:
942         {
943                 unsigned int *i = arg;
944
945                 if (!vfd->vidioc_g_input)
946                         break;
947                 ret=vfd->vidioc_g_input(file, fh, i);
948                 if (!ret)
949                         dbgarg (cmd, "value=%d\n",*i);
950                 break;
951         }
952         case VIDIOC_S_INPUT:
953         {
954                 unsigned int *i = arg;
955
956                 if (!vfd->vidioc_s_input)
957                         break;
958                 dbgarg (cmd, "value=%d\n",*i);
959                 ret=vfd->vidioc_s_input(file, fh, *i);
960                 break;
961         }
962
963         /* ------ output switching ---------- */
964         case VIDIOC_G_OUTPUT:
965         {
966                 unsigned int *i = arg;
967
968                 if (!vfd->vidioc_g_output)
969                         break;
970                 ret=vfd->vidioc_g_output(file, fh, i);
971                 if (!ret)
972                         dbgarg (cmd, "value=%d\n",*i);
973                 break;
974         }
975         case VIDIOC_S_OUTPUT:
976         {
977                 unsigned int *i = arg;
978
979                 if (!vfd->vidioc_s_output)
980                         break;
981                 dbgarg (cmd, "value=%d\n",*i);
982                 ret=vfd->vidioc_s_output(file, fh, *i);
983                 break;
984         }
985
986         /* --- controls ---------------------------------------------- */
987         case VIDIOC_QUERYCTRL:
988         {
989                 struct v4l2_queryctrl *p=arg;
990
991                 if (!vfd->vidioc_queryctrl)
992                         break;
993                 ret=vfd->vidioc_queryctrl(file, fh, p);
994
995                 if (!ret)
996                         dbgarg (cmd, "id=%d, type=%d, name=%s, "
997                                         "min/max=%d/%d,"
998                                         " step=%d, default=%d, flags=0x%08x\n",
999                                         p->id,p->type,p->name,p->minimum,
1000                                         p->maximum,p->step,p->default_value,
1001                                         p->flags);
1002                 break;
1003         }
1004         case VIDIOC_G_CTRL:
1005         {
1006                 struct v4l2_control *p = arg;
1007
1008                 if (!vfd->vidioc_g_ctrl)
1009                         break;
1010                 dbgarg(cmd, "Enum for index=%d\n", p->id);
1011
1012                 ret=vfd->vidioc_g_ctrl(file, fh, p);
1013                 if (!ret)
1014                         dbgarg2 ( "id=%d, value=%d\n", p->id, p->value);
1015                 break;
1016         }
1017         case VIDIOC_S_CTRL:
1018         {
1019                 struct v4l2_control *p = arg;
1020
1021                 if (!vfd->vidioc_s_ctrl)
1022                         break;
1023                 dbgarg (cmd, "id=%d, value=%d\n", p->id, p->value);
1024
1025                 ret=vfd->vidioc_s_ctrl(file, fh, p);
1026                 break;
1027         }
1028         case VIDIOC_G_EXT_CTRLS:
1029         {
1030                 struct v4l2_ext_controls *p = arg;
1031
1032                 if (vfd->vidioc_g_ext_ctrls) {
1033                         dbgarg(cmd, "count=%d\n", p->count);
1034
1035                         ret=vfd->vidioc_g_ext_ctrls(file, fh, p);
1036                 }
1037                 break;
1038         }
1039         case VIDIOC_S_EXT_CTRLS:
1040         {
1041                 struct v4l2_ext_controls *p = arg;
1042
1043                 if (vfd->vidioc_s_ext_ctrls) {
1044                         dbgarg(cmd, "count=%d\n", p->count);
1045
1046                         ret=vfd->vidioc_s_ext_ctrls(file, fh, p);
1047                 }
1048                 break;
1049         }
1050         case VIDIOC_TRY_EXT_CTRLS:
1051         {
1052                 struct v4l2_ext_controls *p = arg;
1053
1054                 if (vfd->vidioc_try_ext_ctrls) {
1055                         dbgarg(cmd, "count=%d\n", p->count);
1056
1057                         ret=vfd->vidioc_try_ext_ctrls(file, fh, p);
1058                 }
1059                 break;
1060         }
1061         case VIDIOC_QUERYMENU:
1062         {
1063                 struct v4l2_querymenu *p=arg;
1064                 if (!vfd->vidioc_querymenu)
1065                         break;
1066                 ret=vfd->vidioc_querymenu(file, fh, p);
1067                 if (!ret)
1068                         dbgarg (cmd, "id=%d, index=%d, name=%s\n",
1069                                                 p->id,p->index,p->name);
1070                 break;
1071         }
1072         /* --- audio ---------------------------------------------- */
1073         case VIDIOC_ENUMAUDIO:
1074         {
1075                 struct v4l2_audio *p=arg;
1076
1077                 if (!vfd->vidioc_enumaudio)
1078                         break;
1079                 dbgarg(cmd, "Enum for index=%d\n", p->index);
1080                 ret=vfd->vidioc_enumaudio(file, fh, p);
1081                 if (!ret)
1082                         dbgarg2("index=%d, name=%s, capability=%d, "
1083                                         "mode=%d\n",p->index,p->name,
1084                                         p->capability, p->mode);
1085                 break;
1086         }
1087         case VIDIOC_G_AUDIO:
1088         {
1089                 struct v4l2_audio *p=arg;
1090
1091                 if (!vfd->vidioc_g_audio)
1092                         break;
1093                 dbgarg(cmd, "Get for index=%d\n", p->index);
1094                 ret=vfd->vidioc_g_audio(file, fh, p);
1095                 if (!ret)
1096                         dbgarg2("index=%d, name=%s, capability=%d, "
1097                                         "mode=%d\n",p->index,
1098                                         p->name,p->capability, p->mode);
1099                 break;
1100         }
1101         case VIDIOC_S_AUDIO:
1102         {
1103                 struct v4l2_audio *p=arg;
1104
1105                 if (!vfd->vidioc_s_audio)
1106                         break;
1107                 dbgarg(cmd, "index=%d, name=%s, capability=%d, "
1108                                         "mode=%d\n", p->index, p->name,
1109                                         p->capability, p->mode);
1110                 ret=vfd->vidioc_s_audio(file, fh, p);
1111                 break;
1112         }
1113         case VIDIOC_ENUMAUDOUT:
1114         {
1115                 struct v4l2_audioout *p=arg;
1116
1117                 if (!vfd->vidioc_enumaudout)
1118                         break;
1119                 dbgarg(cmd, "Enum for index=%d\n", p->index);
1120                 ret=vfd->vidioc_enumaudout(file, fh, p);
1121                 if (!ret)
1122                         dbgarg2("index=%d, name=%s, capability=%d, "
1123                                         "mode=%d\n", p->index, p->name,
1124                                         p->capability,p->mode);
1125                 break;
1126         }
1127         case VIDIOC_G_AUDOUT:
1128         {
1129                 struct v4l2_audioout *p=arg;
1130
1131                 if (!vfd->vidioc_g_audout)
1132                         break;
1133                 dbgarg(cmd, "Enum for index=%d\n", p->index);
1134                 ret=vfd->vidioc_g_audout(file, fh, p);
1135                 if (!ret)
1136                         dbgarg2("index=%d, name=%s, capability=%d, "
1137                                         "mode=%d\n", p->index, p->name,
1138                                         p->capability,p->mode);
1139                 break;
1140         }
1141         case VIDIOC_S_AUDOUT:
1142         {
1143                 struct v4l2_audioout *p=arg;
1144
1145                 if (!vfd->vidioc_s_audout)
1146                         break;
1147                 dbgarg(cmd, "index=%d, name=%s, capability=%d, "
1148                                         "mode=%d\n", p->index, p->name,
1149                                         p->capability,p->mode);
1150
1151                 ret=vfd->vidioc_s_audout(file, fh, p);
1152                 break;
1153         }
1154         case VIDIOC_G_MODULATOR:
1155         {
1156                 struct v4l2_modulator *p=arg;
1157                 if (!vfd->vidioc_g_modulator)
1158                         break;
1159                 ret=vfd->vidioc_g_modulator(file, fh, p);
1160                 if (!ret)
1161                         dbgarg(cmd, "index=%d, name=%s, "
1162                                         "capability=%d, rangelow=%d,"
1163                                         " rangehigh=%d, txsubchans=%d\n",
1164                                         p->index, p->name,p->capability,
1165                                         p->rangelow, p->rangehigh,
1166                                         p->txsubchans);
1167                 break;
1168         }
1169         case VIDIOC_S_MODULATOR:
1170         {
1171                 struct v4l2_modulator *p=arg;
1172                 if (!vfd->vidioc_s_modulator)
1173                         break;
1174                 dbgarg(cmd, "index=%d, name=%s, capability=%d, "
1175                                 "rangelow=%d, rangehigh=%d, txsubchans=%d\n",
1176                                 p->index, p->name,p->capability,p->rangelow,
1177                                 p->rangehigh,p->txsubchans);
1178                         ret=vfd->vidioc_s_modulator(file, fh, p);
1179                 break;
1180         }
1181         case VIDIOC_G_CROP:
1182         {
1183                 struct v4l2_crop *p=arg;
1184                 if (!vfd->vidioc_g_crop)
1185                         break;
1186                 ret=vfd->vidioc_g_crop(file, fh, p);
1187                 if (!ret) {
1188                         dbgarg(cmd, "type=%d\n", p->type);
1189                         dbgrect(vfd, "", &p->c);
1190                 }
1191                 break;
1192         }
1193         case VIDIOC_S_CROP:
1194         {
1195                 struct v4l2_crop *p=arg;
1196                 if (!vfd->vidioc_s_crop)
1197                         break;
1198                 dbgarg(cmd, "type=%d\n", p->type);
1199                 dbgrect(vfd, "", &p->c);
1200                 ret=vfd->vidioc_s_crop(file, fh, p);
1201                 break;
1202         }
1203         case VIDIOC_CROPCAP:
1204         {
1205                 struct v4l2_cropcap *p=arg;
1206                 /*FIXME: Should also show v4l2_fract pixelaspect */
1207                 if (!vfd->vidioc_cropcap)
1208                         break;
1209                 dbgarg(cmd, "type=%d\n", p->type);
1210                 dbgrect(vfd, "bounds ", &p->bounds);
1211                 dbgrect(vfd, "defrect ", &p->defrect);
1212                 ret=vfd->vidioc_cropcap(file, fh, p);
1213                 break;
1214         }
1215         case VIDIOC_G_MPEGCOMP:
1216         {
1217                 struct v4l2_mpeg_compression *p=arg;
1218
1219                 /*FIXME: Several fields not shown */
1220                 if (!vfd->vidioc_g_mpegcomp)
1221                         break;
1222                 ret=vfd->vidioc_g_mpegcomp(file, fh, p);
1223                 if (!ret)
1224                         dbgarg (cmd, "ts_pid_pmt=%d, ts_pid_audio=%d,"
1225                                         " ts_pid_video=%d, ts_pid_pcr=%d, "
1226                                         "ps_size=%d, au_sample_rate=%d, "
1227                                         "au_pesid=%c, vi_frame_rate=%d, "
1228                                         "vi_frames_per_gop=%d, "
1229                                         "vi_bframes_count=%d, vi_pesid=%c\n",
1230                                         p->ts_pid_pmt,p->ts_pid_audio,
1231                                         p->ts_pid_video,p->ts_pid_pcr,
1232                                         p->ps_size, p->au_sample_rate,
1233                                         p->au_pesid, p->vi_frame_rate,
1234                                         p->vi_frames_per_gop,
1235                                         p->vi_bframes_count, p->vi_pesid);
1236                 break;
1237         }
1238         case VIDIOC_S_MPEGCOMP:
1239         {
1240                 struct v4l2_mpeg_compression *p=arg;
1241                 /*FIXME: Several fields not shown */
1242                 if (!vfd->vidioc_s_mpegcomp)
1243                         break;
1244                 dbgarg (cmd, "ts_pid_pmt=%d, ts_pid_audio=%d, "
1245                                 "ts_pid_video=%d, ts_pid_pcr=%d, ps_size=%d, "
1246                                 "au_sample_rate=%d, au_pesid=%c, "
1247                                 "vi_frame_rate=%d, vi_frames_per_gop=%d, "
1248                                 "vi_bframes_count=%d, vi_pesid=%c\n",
1249                                 p->ts_pid_pmt,p->ts_pid_audio, p->ts_pid_video,
1250                                 p->ts_pid_pcr, p->ps_size, p->au_sample_rate,
1251                                 p->au_pesid, p->vi_frame_rate,
1252                                 p->vi_frames_per_gop, p->vi_bframes_count,
1253                                 p->vi_pesid);
1254                 ret=vfd->vidioc_s_mpegcomp(file, fh, p);
1255                 break;
1256         }
1257         case VIDIOC_G_JPEGCOMP:
1258         {
1259                 struct v4l2_jpegcompression *p=arg;
1260                 if (!vfd->vidioc_g_jpegcomp)
1261                         break;
1262                 ret=vfd->vidioc_g_jpegcomp(file, fh, p);
1263                 if (!ret)
1264                         dbgarg (cmd, "quality=%d, APPn=%d, "
1265                                                 "APP_len=%d, COM_len=%d, "
1266                                                 "jpeg_markers=%d\n",
1267                                                 p->quality,p->APPn,p->APP_len,
1268                                                 p->COM_len,p->jpeg_markers);
1269                 break;
1270         }
1271         case VIDIOC_S_JPEGCOMP:
1272         {
1273                 struct v4l2_jpegcompression *p=arg;
1274                 if (!vfd->vidioc_g_jpegcomp)
1275                         break;
1276                 dbgarg (cmd, "quality=%d, APPn=%d, APP_len=%d, "
1277                                         "COM_len=%d, jpeg_markers=%d\n",
1278                                         p->quality,p->APPn,p->APP_len,
1279                                         p->COM_len,p->jpeg_markers);
1280                         ret=vfd->vidioc_s_jpegcomp(file, fh, p);
1281                 break;
1282         }
1283         case VIDIOC_G_PARM:
1284         {
1285                 struct v4l2_streamparm *p=arg;
1286                 if (vfd->vidioc_g_parm) {
1287                         ret=vfd->vidioc_g_parm(file, fh, p);
1288                 } else {
1289                         struct v4l2_standard s;
1290
1291                         if (!vfd->tvnormsize) {
1292                                 printk (KERN_WARNING "%s: no TV norms defined!\n",
1293                                                         vfd->name);
1294                                 break;
1295                         }
1296
1297                         if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1298                                 return -EINVAL;
1299
1300                         v4l2_video_std_construct(&s, vfd->tvnorms[vfd->current_norm].id,
1301                                                  vfd->tvnorms[vfd->current_norm].name);
1302
1303                         memset(p,0,sizeof(*p));
1304
1305                         p->parm.capture.timeperframe = s.frameperiod;
1306                         ret=0;
1307                 }
1308
1309                 dbgarg (cmd, "type=%d\n", p->type);
1310                 break;
1311         }
1312         case VIDIOC_S_PARM:
1313         {
1314                 struct v4l2_streamparm *p=arg;
1315                 if (!vfd->vidioc_s_parm)
1316                         break;
1317                 dbgarg (cmd, "type=%d\n", p->type);
1318                 ret=vfd->vidioc_s_parm(file, fh, p);
1319                 break;
1320         }
1321         case VIDIOC_G_TUNER:
1322         {
1323                 struct v4l2_tuner *p=arg;
1324                 if (!vfd->vidioc_g_tuner)
1325                         break;
1326                 ret=vfd->vidioc_g_tuner(file, fh, p);
1327                 if (!ret)
1328                         dbgarg (cmd, "index=%d, name=%s, type=%d, "
1329                                         "capability=%d, rangelow=%d, "
1330                                         "rangehigh=%d, signal=%d, afc=%d, "
1331                                         "rxsubchans=%d, audmode=%d\n",
1332                                         p->index, p->name, p->type,
1333                                         p->capability, p->rangelow,
1334                                         p->rangehigh, p->rxsubchans,
1335                                         p->audmode, p->signal, p->afc);
1336                 break;
1337         }
1338         case VIDIOC_S_TUNER:
1339         {
1340                 struct v4l2_tuner *p=arg;
1341                 if (!vfd->vidioc_s_tuner)
1342                         break;
1343                 dbgarg (cmd, "index=%d, name=%s, type=%d, "
1344                                 "capability=%d, rangelow=%d, rangehigh=%d, "
1345                                 "signal=%d, afc=%d, rxsubchans=%d, "
1346                                 "audmode=%d\n",p->index, p->name, p->type,
1347                                 p->capability, p->rangelow,p->rangehigh,
1348                                 p->rxsubchans, p->audmode, p->signal,
1349                                 p->afc);
1350                 ret=vfd->vidioc_s_tuner(file, fh, p);
1351                 break;
1352         }
1353         case VIDIOC_G_FREQUENCY:
1354         {
1355                 struct v4l2_frequency *p=arg;
1356                 if (!vfd->vidioc_g_frequency)
1357                         break;
1358                 ret=vfd->vidioc_g_frequency(file, fh, p);
1359                 if (!ret)
1360                         dbgarg (cmd, "tuner=%d, type=%d, frequency=%d\n",
1361                                                 p->tuner,p->type,p->frequency);
1362                 break;
1363         }
1364         case VIDIOC_S_FREQUENCY:
1365         {
1366                 struct v4l2_frequency *p=arg;
1367                 if (!vfd->vidioc_s_frequency)
1368                         break;
1369                 dbgarg (cmd, "tuner=%d, type=%d, frequency=%d\n",
1370                                 p->tuner,p->type,p->frequency);
1371                 ret=vfd->vidioc_s_frequency(file, fh, p);
1372                 break;
1373         }
1374         case VIDIOC_G_SLICED_VBI_CAP:
1375         {
1376                 struct v4l2_sliced_vbi_cap *p=arg;
1377                 if (!vfd->vidioc_g_sliced_vbi_cap)
1378                         break;
1379                 ret=vfd->vidioc_g_sliced_vbi_cap(file, fh, p);
1380                 if (!ret)
1381                         dbgarg (cmd, "service_set=%d\n", p->service_set);
1382                 break;
1383         }
1384         case VIDIOC_LOG_STATUS:
1385         {
1386                 if (!vfd->vidioc_log_status)
1387                         break;
1388                 ret=vfd->vidioc_log_status(file, fh);
1389                 break;
1390         }
1391
1392         /* --- Others --------------------------------------------- */
1393
1394         default:
1395                 ret=v4l_compat_translate_ioctl(inode,file,cmd,arg,__video_do_ioctl);
1396         }
1397
1398         if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) {
1399                 if (ret<0) {
1400                         printk ("%s: err:\n", vfd->name);
1401                         v4l_print_ioctl(vfd->name, cmd);
1402                 }
1403         }
1404
1405         return ret;
1406 }
1407
1408 int video_ioctl2 (struct inode *inode, struct file *file,
1409                unsigned int cmd, unsigned long arg)
1410 {
1411         char    sbuf[128];
1412         void    *mbuf = NULL;
1413         void    *parg = NULL;
1414         int     err  = -EINVAL;
1415         int     is_ext_ctrl;
1416         size_t  ctrls_size = 0;
1417         void __user *user_ptr = NULL;
1418
1419 #ifdef __OLD_VIDIOC_
1420         cmd = video_fix_command(cmd);
1421 #endif
1422         is_ext_ctrl = (cmd == VIDIOC_S_EXT_CTRLS || cmd == VIDIOC_G_EXT_CTRLS ||
1423                        cmd == VIDIOC_TRY_EXT_CTRLS);
1424
1425         /*  Copy arguments into temp kernel buffer  */
1426         switch (_IOC_DIR(cmd)) {
1427         case _IOC_NONE:
1428                 parg = NULL;
1429                 break;
1430         case _IOC_READ:
1431         case _IOC_WRITE:
1432         case (_IOC_WRITE | _IOC_READ):
1433                 if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
1434                         parg = sbuf;
1435                 } else {
1436                         /* too big to allocate from stack */
1437                         mbuf = kmalloc(_IOC_SIZE(cmd),GFP_KERNEL);
1438                         if (NULL == mbuf)
1439                                 return -ENOMEM;
1440                         parg = mbuf;
1441                 }
1442
1443                 err = -EFAULT;
1444                 if (_IOC_DIR(cmd) & _IOC_WRITE)
1445                         if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd)))
1446                                 goto out;
1447                 break;
1448         }
1449
1450         if (is_ext_ctrl) {
1451                 struct v4l2_ext_controls *p = parg;
1452
1453                 /* In case of an error, tell the caller that it wasn't
1454                    a specific control that caused it. */
1455                 p->error_idx = p->count;
1456                 user_ptr = (void __user *)p->controls;
1457                 if (p->count) {
1458                         ctrls_size = sizeof(struct v4l2_ext_control) * p->count;
1459                         /* Note: v4l2_ext_controls fits in sbuf[] so mbuf is still NULL. */
1460                         mbuf = kmalloc(ctrls_size, GFP_KERNEL);
1461                         err = -ENOMEM;
1462                         if (NULL == mbuf)
1463                                 goto out_ext_ctrl;
1464                         err = -EFAULT;
1465                         if (copy_from_user(mbuf, user_ptr, ctrls_size))
1466                                 goto out_ext_ctrl;
1467                         p->controls = mbuf;
1468                 }
1469         }
1470
1471         /* Handles IOCTL */
1472         err = __video_do_ioctl(inode, file, cmd, parg);
1473         if (err == -ENOIOCTLCMD)
1474                 err = -EINVAL;
1475         if (is_ext_ctrl) {
1476                 struct v4l2_ext_controls *p = parg;
1477
1478                 p->controls = (void *)user_ptr;
1479                 if (p->count && err == 0 && copy_to_user(user_ptr, mbuf, ctrls_size))
1480                         err = -EFAULT;
1481                 goto out_ext_ctrl;
1482         }
1483         if (err < 0)
1484                 goto out;
1485
1486 out_ext_ctrl:
1487         /*  Copy results into user buffer  */
1488         switch (_IOC_DIR(cmd))
1489         {
1490         case _IOC_READ:
1491         case (_IOC_WRITE | _IOC_READ):
1492                 if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd)))
1493                         err = -EFAULT;
1494                 break;
1495         }
1496
1497 out:
1498         kfree(mbuf);
1499         return err;
1500 }
1501
1502
1503 static struct file_operations video_fops;
1504
1505 /**
1506  *      video_register_device - register video4linux devices
1507  *      @vfd:  video device structure we want to register
1508  *      @type: type of device to register
1509  *      @nr:   which device number (0 == /dev/video0, 1 == /dev/video1, ...
1510  *             -1 == first free)
1511  *
1512  *      The registration code assigns minor numbers based on the type
1513  *      requested. -ENFILE is returned in all the device slots for this
1514  *      category are full. If not then the minor field is set and the
1515  *      driver initialize function is called (if non %NULL).
1516  *
1517  *      Zero is returned on success.
1518  *
1519  *      Valid types are
1520  *
1521  *      %VFL_TYPE_GRABBER - A frame grabber
1522  *
1523  *      %VFL_TYPE_VTX - A teletext device
1524  *
1525  *      %VFL_TYPE_VBI - Vertical blank data (undecoded)
1526  *
1527  *      %VFL_TYPE_RADIO - A radio card
1528  */
1529
1530 int video_register_device(struct video_device *vfd, int type, int nr)
1531 {
1532         int i=0;
1533         int base;
1534         int end;
1535         int ret;
1536         char *name_base;
1537
1538         switch(type)
1539         {
1540                 case VFL_TYPE_GRABBER:
1541                         base=MINOR_VFL_TYPE_GRABBER_MIN;
1542                         end=MINOR_VFL_TYPE_GRABBER_MAX+1;
1543                         name_base = "video";
1544                         break;
1545                 case VFL_TYPE_VTX:
1546                         base=MINOR_VFL_TYPE_VTX_MIN;
1547                         end=MINOR_VFL_TYPE_VTX_MAX+1;
1548                         name_base = "vtx";
1549                         break;
1550                 case VFL_TYPE_VBI:
1551                         base=MINOR_VFL_TYPE_VBI_MIN;
1552                         end=MINOR_VFL_TYPE_VBI_MAX+1;
1553                         name_base = "vbi";
1554                         break;
1555                 case VFL_TYPE_RADIO:
1556                         base=MINOR_VFL_TYPE_RADIO_MIN;
1557                         end=MINOR_VFL_TYPE_RADIO_MAX+1;
1558                         name_base = "radio";
1559                         break;
1560                 default:
1561                         printk(KERN_ERR "%s called with unknown type: %d\n",
1562                                __FUNCTION__, type);
1563                         return -1;
1564         }
1565
1566         /* pick a minor number */
1567         mutex_lock(&videodev_lock);
1568         if (nr >= 0  &&  nr < end-base) {
1569                 /* use the one the driver asked for */
1570                 i = base+nr;
1571                 if (NULL != video_device[i]) {
1572                         mutex_unlock(&videodev_lock);
1573                         return -ENFILE;
1574                 }
1575         } else {
1576                 /* use first free */
1577                 for(i=base;i<end;i++)
1578                         if (NULL == video_device[i])
1579                                 break;
1580                 if (i == end) {
1581                         mutex_unlock(&videodev_lock);
1582                         return -ENFILE;
1583                 }
1584         }
1585         video_device[i]=vfd;
1586         vfd->minor=i;
1587         mutex_unlock(&videodev_lock);
1588         mutex_init(&vfd->lock);
1589
1590         /* sysfs class */
1591         memset(&vfd->class_dev, 0x00, sizeof(vfd->class_dev));
1592         if (vfd->dev)
1593                 vfd->class_dev.dev = vfd->dev;
1594         vfd->class_dev.class       = &video_class;
1595         vfd->class_dev.devt        = MKDEV(VIDEO_MAJOR, vfd->minor);
1596         sprintf(vfd->class_dev.class_id, "%s%d", name_base, i - base);
1597         ret = class_device_register(&vfd->class_dev);
1598         if (ret < 0) {
1599                 printk(KERN_ERR "%s: class_device_register failed\n",
1600                        __FUNCTION__);
1601                 goto fail_minor;
1602         }
1603         ret = class_device_create_file(&vfd->class_dev, &class_device_attr_name);
1604         if (ret < 0) {
1605                 printk(KERN_ERR "%s: class_device_create_file 'name' failed\n",
1606                        __FUNCTION__);
1607                 goto fail_classdev;
1608         }
1609
1610 #if 1
1611         /* needed until all drivers are fixed */
1612         if (!vfd->release)
1613                 printk(KERN_WARNING "videodev: \"%s\" has no release callback. "
1614                        "Please fix your driver for proper sysfs support, see "
1615                        "http://lwn.net/Articles/36850/\n", vfd->name);
1616 #endif
1617         return 0;
1618
1619 fail_classdev:
1620         class_device_unregister(&vfd->class_dev);
1621 fail_minor:
1622         mutex_lock(&videodev_lock);
1623         video_device[vfd->minor] = NULL;
1624         vfd->minor = -1;
1625         mutex_unlock(&videodev_lock);
1626         return ret;
1627 }
1628
1629 /**
1630  *      video_unregister_device - unregister a video4linux device
1631  *      @vfd: the device to unregister
1632  *
1633  *      This unregisters the passed device and deassigns the minor
1634  *      number. Future open calls will be met with errors.
1635  */
1636
1637 void video_unregister_device(struct video_device *vfd)
1638 {
1639         mutex_lock(&videodev_lock);
1640         if(video_device[vfd->minor]!=vfd)
1641                 panic("videodev: bad unregister");
1642
1643         video_device[vfd->minor]=NULL;
1644         class_device_unregister(&vfd->class_dev);
1645         mutex_unlock(&videodev_lock);
1646 }
1647
1648 /*
1649  * Video fs operations
1650  */
1651 static struct file_operations video_fops=
1652 {
1653         .owner          = THIS_MODULE,
1654         .llseek         = no_llseek,
1655         .open           = video_open,
1656 };
1657
1658 /*
1659  *      Initialise video for linux
1660  */
1661
1662 static int __init videodev_init(void)
1663 {
1664         int ret;
1665
1666         printk(KERN_INFO "Linux video capture interface: v2.00\n");
1667         if (register_chrdev(VIDEO_MAJOR, VIDEO_NAME, &video_fops)) {
1668                 printk(KERN_WARNING "video_dev: unable to get major %d\n", VIDEO_MAJOR);
1669                 return -EIO;
1670         }
1671
1672         ret = class_register(&video_class);
1673         if (ret < 0) {
1674                 unregister_chrdev(VIDEO_MAJOR, VIDEO_NAME);
1675                 printk(KERN_WARNING "video_dev: class_register failed\n");
1676                 return -EIO;
1677         }
1678
1679         return 0;
1680 }
1681
1682 static void __exit videodev_exit(void)
1683 {
1684         class_unregister(&video_class);
1685         unregister_chrdev(VIDEO_MAJOR, VIDEO_NAME);
1686 }
1687
1688 module_init(videodev_init)
1689 module_exit(videodev_exit)
1690
1691 EXPORT_SYMBOL(video_register_device);
1692 EXPORT_SYMBOL(video_unregister_device);
1693 EXPORT_SYMBOL(video_devdata);
1694 EXPORT_SYMBOL(video_usercopy);
1695 EXPORT_SYMBOL(video_exclusive_open);
1696 EXPORT_SYMBOL(video_exclusive_release);
1697 EXPORT_SYMBOL(video_ioctl2);
1698 EXPORT_SYMBOL(video_device_alloc);
1699 EXPORT_SYMBOL(video_device_release);
1700
1701 MODULE_AUTHOR("Alan Cox, Mauro Carvalho Chehab <mchehab@infradead.org>");
1702 MODULE_DESCRIPTION("Device registrar for Video4Linux drivers v2");
1703 MODULE_LICENSE("GPL");
1704
1705
1706 /*
1707  * Local variables:
1708  * c-basic-offset: 8
1709  * End:
1710  */