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