2 * Video capture interface for Linux version 2
4 * A generic video device interface for the LINUX operating system
5 * using a set of device structures/vectors for low level operations.
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.
12 * Authors: Alan Cox, <alan@redhat.com> (version 1)
13 * Mauro Carvalho Chehab <mchehab@infradead.org> (version 2)
15 * Fixes: 20000516 Claudio Matsuoka <claudio@conectiva.com>
16 * - Added procfs support
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); \
26 #define dbgarg2(fmt, arg...) \
27 if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) \
28 printk (KERN_DEBUG "%s: " fmt, vfd->name, ## arg);
30 #include <linux/module.h>
31 #include <linux/types.h>
32 #include <linux/kernel.h>
33 #include <linux/sched.h>
34 #include <linux/smp_lock.h>
36 #include <linux/string.h>
37 #include <linux/errno.h>
38 #include <linux/init.h>
39 #include <linux/kmod.h>
40 #include <linux/slab.h>
41 #include <asm/uaccess.h>
42 #include <asm/system.h>
44 #define __OLD_VIDIOC_ /* To allow fixing old calls*/
45 #include <linux/videodev2.h>
47 #ifdef CONFIG_VIDEO_V4L1
48 #include <linux/videodev.h>
50 #include <media/v4l2-common.h>
52 #define VIDEO_NUM_DEVICES 256
53 #define VIDEO_NAME "video4linux"
59 static ssize_t show_name(struct class_device *cd, char *buf)
61 struct video_device *vfd = container_of(cd, struct video_device,
63 return sprintf(buf,"%.*s\n",(int)sizeof(vfd->name),vfd->name);
66 static CLASS_DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
68 struct video_device *video_device_alloc(void)
70 struct video_device *vfd;
72 vfd = kzalloc(sizeof(*vfd),GFP_KERNEL);
76 void video_device_release(struct video_device *vfd)
81 static void video_release(struct class_device *cd)
83 struct video_device *vfd = container_of(cd, struct video_device,
87 /* needed until all drivers are fixed */
94 static struct class video_class = {
96 .release = video_release,
103 static struct video_device *video_device[VIDEO_NUM_DEVICES];
104 static DEFINE_MUTEX(videodev_lock);
106 struct video_device* video_devdata(struct file *file)
108 return video_device[iminor(file->f_path.dentry->d_inode)];
112 * Open a video device - FIXME: Obsoleted
114 static int video_open(struct inode *inode, struct file *file)
116 unsigned int minor = iminor(inode);
118 struct video_device *vfl;
119 const struct file_operations *old_fops;
121 if(minor>=VIDEO_NUM_DEVICES)
123 mutex_lock(&videodev_lock);
124 vfl=video_device[minor];
126 mutex_unlock(&videodev_lock);
127 request_module("char-major-%d-%d", VIDEO_MAJOR, minor);
128 mutex_lock(&videodev_lock);
129 vfl=video_device[minor];
131 mutex_unlock(&videodev_lock);
135 old_fops = file->f_op;
136 file->f_op = fops_get(vfl->fops);
138 err = file->f_op->open(inode,file);
140 fops_put(file->f_op);
141 file->f_op = fops_get(old_fops);
144 mutex_unlock(&videodev_lock);
149 * helper function -- handles userspace copying for ioctl arguments
154 video_fix_command(unsigned int cmd)
157 case VIDIOC_OVERLAY_OLD:
158 cmd = VIDIOC_OVERLAY;
160 case VIDIOC_S_PARM_OLD:
163 case VIDIOC_S_CTRL_OLD:
166 case VIDIOC_G_AUDIO_OLD:
167 cmd = VIDIOC_G_AUDIO;
169 case VIDIOC_G_AUDOUT_OLD:
170 cmd = VIDIOC_G_AUDOUT;
172 case VIDIOC_CROPCAP_OLD:
173 cmd = VIDIOC_CROPCAP;
181 * Obsolete usercopy function - Should be removed soon
184 video_usercopy(struct inode *inode, struct file *file,
185 unsigned int cmd, unsigned long arg,
186 int (*func)(struct inode *inode, struct file *file,
187 unsigned int cmd, void *arg))
194 size_t ctrls_size = 0;
195 void __user *user_ptr = NULL;
198 cmd = video_fix_command(cmd);
200 is_ext_ctrl = (cmd == VIDIOC_S_EXT_CTRLS || cmd == VIDIOC_G_EXT_CTRLS ||
201 cmd == VIDIOC_TRY_EXT_CTRLS);
203 /* Copy arguments into temp kernel buffer */
204 switch (_IOC_DIR(cmd)) {
210 case (_IOC_WRITE | _IOC_READ):
211 if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
214 /* too big to allocate from stack */
215 mbuf = kmalloc(_IOC_SIZE(cmd),GFP_KERNEL);
222 if (_IOC_DIR(cmd) & _IOC_WRITE)
223 if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd)))
228 struct v4l2_ext_controls *p = parg;
230 /* In case of an error, tell the caller that it wasn't
231 a specific control that caused it. */
232 p->error_idx = p->count;
233 user_ptr = (void __user *)p->controls;
235 ctrls_size = sizeof(struct v4l2_ext_control) * p->count;
236 /* Note: v4l2_ext_controls fits in sbuf[] so mbuf is still NULL. */
237 mbuf = kmalloc(ctrls_size, GFP_KERNEL);
242 if (copy_from_user(mbuf, user_ptr, ctrls_size))
249 err = func(inode, file, cmd, parg);
250 if (err == -ENOIOCTLCMD)
253 struct v4l2_ext_controls *p = parg;
255 p->controls = (void *)user_ptr;
256 if (p->count && err == 0 && copy_to_user(user_ptr, mbuf, ctrls_size))
264 /* Copy results into user buffer */
265 switch (_IOC_DIR(cmd))
268 case (_IOC_WRITE | _IOC_READ):
269 if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd)))
280 * open/release helper functions -- handle exclusive opens
281 * Should be removed soon
283 int video_exclusive_open(struct inode *inode, struct file *file)
285 struct video_device *vfl = video_devdata(file);
288 mutex_lock(&vfl->lock);
294 mutex_unlock(&vfl->lock);
298 int video_exclusive_release(struct inode *inode, struct file *file)
300 struct video_device *vfl = video_devdata(file);
306 static char *v4l2_memory_names[] = {
307 [V4L2_MEMORY_MMAP] = "mmap",
308 [V4L2_MEMORY_USERPTR] = "userptr",
309 [V4L2_MEMORY_OVERLAY] = "overlay",
313 /* FIXME: Those stuff are replicated also on v4l2-common.c */
314 static char *v4l2_type_names_FIXME[] = {
315 [V4L2_BUF_TYPE_VIDEO_CAPTURE] = "video-cap",
316 [V4L2_BUF_TYPE_VIDEO_OVERLAY] = "video-over",
317 [V4L2_BUF_TYPE_VIDEO_OUTPUT] = "video-out",
318 [V4L2_BUF_TYPE_VBI_CAPTURE] = "vbi-cap",
319 [V4L2_BUF_TYPE_VBI_OUTPUT] = "vbi-out",
320 [V4L2_BUF_TYPE_SLICED_VBI_OUTPUT] = "sliced-vbi-out",
321 [V4L2_BUF_TYPE_SLICED_VBI_CAPTURE] = "sliced-vbi-capture",
322 [V4L2_BUF_TYPE_PRIVATE] = "private",
325 static char *v4l2_field_names_FIXME[] = {
326 [V4L2_FIELD_ANY] = "any",
327 [V4L2_FIELD_NONE] = "none",
328 [V4L2_FIELD_TOP] = "top",
329 [V4L2_FIELD_BOTTOM] = "bottom",
330 [V4L2_FIELD_INTERLACED] = "interlaced",
331 [V4L2_FIELD_SEQ_TB] = "seq-tb",
332 [V4L2_FIELD_SEQ_BT] = "seq-bt",
333 [V4L2_FIELD_ALTERNATE] = "alternate",
336 #define prt_names(a,arr) (((a)>=0)&&((a)<ARRAY_SIZE(arr)))?arr[a]:"unknown"
338 static void dbgbuf(unsigned int cmd, struct video_device *vfd,
339 struct v4l2_buffer *p)
341 struct v4l2_timecode *tc=&p->timecode;
343 dbgarg (cmd, "%02ld:%02d:%02d.%08ld index=%d, type=%s, "
344 "bytesused=%d, flags=0x%08d, "
345 "field=%0d, sequence=%d, memory=%s, offset/userptr=0x%08lx\n",
346 (p->timestamp.tv_sec/3600),
347 (int)(p->timestamp.tv_sec/60)%60,
348 (int)(p->timestamp.tv_sec%60),
349 p->timestamp.tv_usec,
351 prt_names(p->type,v4l2_type_names_FIXME),
352 p->bytesused,p->flags,
353 p->field,p->sequence,
354 prt_names(p->memory,v4l2_memory_names),
356 dbgarg2 ("timecode= %02d:%02d:%02d type=%d, "
357 "flags=0x%08d, frames=%d, userbits=0x%08x\n",
358 tc->hours,tc->minutes,tc->seconds,
359 tc->type, tc->flags, tc->frames, *(__u32 *) tc->userbits);
362 static inline void dbgrect(struct video_device *vfd, char *s,
365 dbgarg2 ("%sRect start at %dx%d, size= %dx%d\n", s, r->left, r->top,
366 r->width, r->height);
369 static inline void v4l_print_pix_fmt (struct video_device *vfd,
370 struct v4l2_pix_format *fmt)
372 dbgarg2 ("width=%d, height=%d, format=0x%08x, field=%s, "
373 "bytesperline=%d sizeimage=%d, colorspace=%d\n",
374 fmt->width,fmt->height,fmt->pixelformat,
375 prt_names(fmt->field,v4l2_field_names_FIXME),
376 fmt->bytesperline,fmt->sizeimage,fmt->colorspace);
380 static int check_fmt (struct video_device *vfd, enum v4l2_buf_type type)
383 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
384 if (vfd->vidioc_try_fmt_cap)
387 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
388 if (vfd->vidioc_try_fmt_overlay)
391 case V4L2_BUF_TYPE_VBI_CAPTURE:
392 if (vfd->vidioc_try_fmt_vbi)
395 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
396 if (vfd->vidioc_try_fmt_vbi_output)
399 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
400 if (vfd->vidioc_try_fmt_vbi_capture)
403 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
404 if (vfd->vidioc_try_fmt_video_output)
407 case V4L2_BUF_TYPE_VBI_OUTPUT:
408 if (vfd->vidioc_try_fmt_vbi_output)
411 case V4L2_BUF_TYPE_PRIVATE:
412 if (vfd->vidioc_try_fmt_type_private)
419 static int __video_do_ioctl(struct inode *inode, struct file *file,
420 unsigned int cmd, void *arg)
422 struct video_device *vfd = video_devdata(file);
423 void *fh = file->private_data;
426 if ( (vfd->debug & V4L2_DEBUG_IOCTL) &&
427 !(vfd->debug | V4L2_DEBUG_IOCTL_ARG)) {
428 v4l_print_ioctl(vfd->name, cmd);
431 if (_IOC_TYPE(cmd)=='v')
432 return v4l_compat_translate_ioctl(inode,file,cmd,arg,
436 /* --- capabilities ------------------------------------------ */
437 case VIDIOC_QUERYCAP:
439 struct v4l2_capability *cap = (struct v4l2_capability*)arg;
440 memset(cap, 0, sizeof(*cap));
442 if (!vfd->vidioc_querycap)
445 ret=vfd->vidioc_querycap(file, fh, cap);
447 dbgarg (cmd, "driver=%s, card=%s, bus=%s, "
449 "capabilities=0x%08x\n",
450 cap->driver,cap->card,cap->bus_info,
456 /* --- priority ------------------------------------------ */
457 case VIDIOC_G_PRIORITY:
459 enum v4l2_priority *p=arg;
461 if (!vfd->vidioc_g_priority)
463 ret=vfd->vidioc_g_priority(file, fh, p);
465 dbgarg(cmd, "priority is %d\n", *p);
468 case VIDIOC_S_PRIORITY:
470 enum v4l2_priority *p=arg;
472 if (!vfd->vidioc_s_priority)
474 dbgarg(cmd, "setting priority to %d\n", *p);
475 ret=vfd->vidioc_s_priority(file, fh, *p);
479 /* --- capture ioctls ---------------------------------------- */
480 case VIDIOC_ENUM_FMT:
482 struct v4l2_fmtdesc *f = arg;
483 enum v4l2_buf_type type;
488 memset(f,0,sizeof(*f));
493 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
494 if (vfd->vidioc_enum_fmt_cap)
495 ret=vfd->vidioc_enum_fmt_cap(file, fh, f);
497 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
498 if (vfd->vidioc_enum_fmt_overlay)
499 ret=vfd->vidioc_enum_fmt_overlay(file, fh, f);
501 case V4L2_BUF_TYPE_VBI_CAPTURE:
502 if (vfd->vidioc_enum_fmt_vbi)
503 ret=vfd->vidioc_enum_fmt_vbi(file, fh, f);
505 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
506 if (vfd->vidioc_enum_fmt_vbi_output)
507 ret=vfd->vidioc_enum_fmt_vbi_output(file,
510 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
511 if (vfd->vidioc_enum_fmt_vbi_capture)
512 ret=vfd->vidioc_enum_fmt_vbi_capture(file,
515 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
516 if (vfd->vidioc_enum_fmt_video_output)
517 ret=vfd->vidioc_enum_fmt_video_output(file,
520 case V4L2_BUF_TYPE_VBI_OUTPUT:
521 if (vfd->vidioc_enum_fmt_vbi_output)
522 ret=vfd->vidioc_enum_fmt_vbi_output(file,
525 case V4L2_BUF_TYPE_PRIVATE:
526 if (vfd->vidioc_enum_fmt_type_private)
527 ret=vfd->vidioc_enum_fmt_type_private(file,
532 dbgarg (cmd, "index=%d, type=%d, flags=%d, "
534 " pixelformat=0x%8x\n",
535 f->index, f->type, f->flags,
543 struct v4l2_format *f = (struct v4l2_format *)arg;
544 enum v4l2_buf_type type=f->type;
546 memset(&f->fmt.pix,0,sizeof(f->fmt.pix));
549 /* FIXME: Should be one dump per type */
550 dbgarg (cmd, "type=%s\n", prt_names(type,
551 v4l2_type_names_FIXME));
554 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
555 if (vfd->vidioc_g_fmt_cap)
556 ret=vfd->vidioc_g_fmt_cap(file, fh, f);
558 v4l_print_pix_fmt(vfd,&f->fmt.pix);
560 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
561 if (vfd->vidioc_g_fmt_overlay)
562 ret=vfd->vidioc_g_fmt_overlay(file, fh, f);
564 case V4L2_BUF_TYPE_VBI_CAPTURE:
565 if (vfd->vidioc_g_fmt_vbi)
566 ret=vfd->vidioc_g_fmt_vbi(file, fh, f);
568 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
569 if (vfd->vidioc_g_fmt_vbi_output)
570 ret=vfd->vidioc_g_fmt_vbi_output(file, fh, f);
572 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
573 if (vfd->vidioc_g_fmt_vbi_capture)
574 ret=vfd->vidioc_g_fmt_vbi_capture(file, fh, f);
576 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
577 if (vfd->vidioc_g_fmt_video_output)
578 ret=vfd->vidioc_g_fmt_video_output(file,
581 case V4L2_BUF_TYPE_VBI_OUTPUT:
582 if (vfd->vidioc_g_fmt_vbi_output)
583 ret=vfd->vidioc_g_fmt_vbi_output(file, fh, f);
585 case V4L2_BUF_TYPE_PRIVATE:
586 if (vfd->vidioc_g_fmt_type_private)
587 ret=vfd->vidioc_g_fmt_type_private(file,
596 struct v4l2_format *f = (struct v4l2_format *)arg;
598 /* FIXME: Should be one dump per type */
599 dbgarg (cmd, "type=%s\n", prt_names(f->type,
600 v4l2_type_names_FIXME));
603 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
604 v4l_print_pix_fmt(vfd,&f->fmt.pix);
605 if (vfd->vidioc_s_fmt_cap)
606 ret=vfd->vidioc_s_fmt_cap(file, fh, f);
608 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
609 if (vfd->vidioc_s_fmt_overlay)
610 ret=vfd->vidioc_s_fmt_overlay(file, fh, f);
612 case V4L2_BUF_TYPE_VBI_CAPTURE:
613 if (vfd->vidioc_s_fmt_vbi)
614 ret=vfd->vidioc_s_fmt_vbi(file, fh, f);
616 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
617 if (vfd->vidioc_s_fmt_vbi_output)
618 ret=vfd->vidioc_s_fmt_vbi_output(file, fh, f);
620 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
621 if (vfd->vidioc_s_fmt_vbi_capture)
622 ret=vfd->vidioc_s_fmt_vbi_capture(file, fh, f);
624 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
625 if (vfd->vidioc_s_fmt_video_output)
626 ret=vfd->vidioc_s_fmt_video_output(file,
629 case V4L2_BUF_TYPE_VBI_OUTPUT:
630 if (vfd->vidioc_s_fmt_vbi_output)
631 ret=vfd->vidioc_s_fmt_vbi_output(file,
634 case V4L2_BUF_TYPE_PRIVATE:
635 if (vfd->vidioc_s_fmt_type_private)
636 ret=vfd->vidioc_s_fmt_type_private(file,
644 struct v4l2_format *f = (struct v4l2_format *)arg;
646 /* FIXME: Should be one dump per type */
647 dbgarg (cmd, "type=%s\n", prt_names(f->type,
648 v4l2_type_names_FIXME));
650 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
651 if (vfd->vidioc_try_fmt_cap)
652 ret=vfd->vidioc_try_fmt_cap(file, fh, f);
654 v4l_print_pix_fmt(vfd,&f->fmt.pix);
656 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
657 if (vfd->vidioc_try_fmt_overlay)
658 ret=vfd->vidioc_try_fmt_overlay(file, fh, f);
660 case V4L2_BUF_TYPE_VBI_CAPTURE:
661 if (vfd->vidioc_try_fmt_vbi)
662 ret=vfd->vidioc_try_fmt_vbi(file, fh, f);
664 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
665 if (vfd->vidioc_try_fmt_vbi_output)
666 ret=vfd->vidioc_try_fmt_vbi_output(file,
669 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
670 if (vfd->vidioc_try_fmt_vbi_capture)
671 ret=vfd->vidioc_try_fmt_vbi_capture(file,
674 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
675 if (vfd->vidioc_try_fmt_video_output)
676 ret=vfd->vidioc_try_fmt_video_output(file,
679 case V4L2_BUF_TYPE_VBI_OUTPUT:
680 if (vfd->vidioc_try_fmt_vbi_output)
681 ret=vfd->vidioc_try_fmt_vbi_output(file,
684 case V4L2_BUF_TYPE_PRIVATE:
685 if (vfd->vidioc_try_fmt_type_private)
686 ret=vfd->vidioc_try_fmt_type_private(file,
693 /* FIXME: Those buf reqs could be handled here,
694 with some changes on videobuf to allow its header to be included at
695 videodev2.h or being merged at videodev2.
699 struct v4l2_requestbuffers *p=arg;
701 if (!vfd->vidioc_reqbufs)
703 ret = check_fmt (vfd, p->type);
707 ret=vfd->vidioc_reqbufs(file, fh, p);
708 dbgarg (cmd, "count=%d, type=%s, memory=%s\n",
710 prt_names(p->type,v4l2_type_names_FIXME),
711 prt_names(p->memory,v4l2_memory_names));
714 case VIDIOC_QUERYBUF:
716 struct v4l2_buffer *p=arg;
718 if (!vfd->vidioc_querybuf)
720 ret = check_fmt (vfd, p->type);
724 ret=vfd->vidioc_querybuf(file, fh, p);
731 struct v4l2_buffer *p=arg;
733 if (!vfd->vidioc_qbuf)
735 ret = check_fmt (vfd, p->type);
739 ret=vfd->vidioc_qbuf(file, fh, p);
746 struct v4l2_buffer *p=arg;
747 if (!vfd->vidioc_dqbuf)
749 ret = check_fmt (vfd, p->type);
753 ret=vfd->vidioc_dqbuf(file, fh, p);
762 if (!vfd->vidioc_overlay)
764 dbgarg (cmd, "value=%d\n",*i);
765 ret=vfd->vidioc_overlay(file, fh, *i);
768 #ifdef CONFIG_VIDEO_V4L1_COMPAT
769 /* --- streaming capture ------------------------------------- */
772 struct video_mbuf *p=arg;
774 memset(p,0,sizeof(p));
776 if (!vfd->vidiocgmbuf)
778 ret=vfd->vidiocgmbuf(file, fh, p);
780 dbgarg (cmd, "size=%d, frames=%d, offsets=0x%08lx\n",
782 (unsigned long)p->offsets);
788 struct v4l2_framebuffer *p=arg;
789 if (!vfd->vidioc_g_fbuf)
791 ret=vfd->vidioc_g_fbuf(file, fh, arg);
793 dbgarg (cmd, "capability=%d, flags=%d, base=0x%08lx\n",
794 p->capability,p->flags,
795 (unsigned long)p->base);
796 v4l_print_pix_fmt (vfd, &p->fmt);
802 struct v4l2_framebuffer *p=arg;
803 if (!vfd->vidioc_s_fbuf)
806 dbgarg (cmd, "capability=%d, flags=%d, base=0x%08lx\n",
807 p->capability,p->flags,(unsigned long)p->base);
808 v4l_print_pix_fmt (vfd, &p->fmt);
809 ret=vfd->vidioc_s_fbuf(file, fh, arg);
813 case VIDIOC_STREAMON:
815 enum v4l2_buf_type i = *(int *)arg;
816 if (!vfd->vidioc_streamon)
818 dbgarg (cmd, "type=%s\n", prt_names(i,v4l2_type_names_FIXME));
819 ret=vfd->vidioc_streamon(file, fh,i);
822 case VIDIOC_STREAMOFF:
824 enum v4l2_buf_type i = *(int *)arg;
826 if (!vfd->vidioc_streamoff)
828 dbgarg (cmd, "type=%s\n", prt_names(i,v4l2_type_names_FIXME));
829 ret=vfd->vidioc_streamoff(file, fh, i);
832 /* ---------- tv norms ---------- */
835 struct v4l2_standard *p = arg;
836 unsigned int index = p->index;
838 if (!vfd->tvnormsize) {
839 printk (KERN_WARNING "%s: no TV norms defined!\n",
844 if (index<0 || index >= vfd->tvnormsize) {
848 v4l2_video_std_construct(p, vfd->tvnorms[p->index].id,
849 vfd->tvnorms[p->index].name);
852 dbgarg (cmd, "index=%d, id=%Ld, name=%s, fps=%d/%d, "
853 "framelines=%d\n", p->index,
854 (unsigned long long)p->id, p->name,
855 p->frameperiod.numerator,
856 p->frameperiod.denominator,
864 v4l2_std_id *id = arg;
866 *id = vfd->current_norm;
868 dbgarg (cmd, "value=%Lu\n", (long long unsigned) *id);
875 v4l2_std_id *id = arg;
878 if (!vfd->tvnormsize) {
879 printk (KERN_WARNING "%s: no TV norms defined!\n",
884 dbgarg (cmd, "value=%Lu\n", (long long unsigned) *id);
886 /* First search for exact match */
887 for (i = 0; i < vfd->tvnormsize; i++)
888 if (*id == vfd->tvnorms[i].id)
890 /* Then for a generic video std that contains desired std */
891 if (i == vfd->tvnormsize)
892 for (i = 0; i < vfd->tvnormsize; i++)
893 if (*id & vfd->tvnorms[i].id)
895 if (i == vfd->tvnormsize) {
899 /* Calls the specific handler */
900 if (vfd->vidioc_s_std)
901 ret=vfd->vidioc_s_std(file, fh, i);
905 /* Updates standard information */
907 vfd->current_norm=*id;
911 case VIDIOC_QUERYSTD:
915 if (!vfd->vidioc_querystd)
917 ret=vfd->vidioc_querystd(file, fh, arg);
919 dbgarg (cmd, "detected std=%Lu\n",
920 (unsigned long long)*p);
923 /* ------ input switching ---------- */
924 /* FIXME: Inputs can be handled inside videodev2 */
925 case VIDIOC_ENUMINPUT:
927 struct v4l2_input *p=arg;
930 if (!vfd->vidioc_enum_input)
932 memset(p, 0, sizeof(*p));
935 ret=vfd->vidioc_enum_input(file, fh, p);
937 dbgarg (cmd, "index=%d, name=%s, type=%d, "
939 "tuner=%d, std=%Ld, status=%d\n",
940 p->index,p->name,p->type,p->audioset,
942 (unsigned long long)p->std,
948 unsigned int *i = arg;
950 if (!vfd->vidioc_g_input)
952 ret=vfd->vidioc_g_input(file, fh, i);
954 dbgarg (cmd, "value=%d\n",*i);
959 unsigned int *i = arg;
961 if (!vfd->vidioc_s_input)
963 dbgarg (cmd, "value=%d\n",*i);
964 ret=vfd->vidioc_s_input(file, fh, *i);
968 /* ------ output switching ---------- */
969 case VIDIOC_G_OUTPUT:
971 unsigned int *i = arg;
973 if (!vfd->vidioc_g_output)
975 ret=vfd->vidioc_g_output(file, fh, i);
977 dbgarg (cmd, "value=%d\n",*i);
980 case VIDIOC_S_OUTPUT:
982 unsigned int *i = arg;
984 if (!vfd->vidioc_s_output)
986 dbgarg (cmd, "value=%d\n",*i);
987 ret=vfd->vidioc_s_output(file, fh, *i);
991 /* --- controls ---------------------------------------------- */
992 case VIDIOC_QUERYCTRL:
994 struct v4l2_queryctrl *p=arg;
996 if (!vfd->vidioc_queryctrl)
998 ret=vfd->vidioc_queryctrl(file, fh, p);
1001 dbgarg (cmd, "id=%d, type=%d, name=%s, "
1003 " step=%d, default=%d, flags=0x%08x\n",
1004 p->id,p->type,p->name,p->minimum,
1005 p->maximum,p->step,p->default_value,
1011 struct v4l2_control *p = arg;
1013 if (!vfd->vidioc_g_ctrl)
1015 dbgarg(cmd, "Enum for index=%d\n", p->id);
1017 ret=vfd->vidioc_g_ctrl(file, fh, p);
1019 dbgarg2 ( "id=%d, value=%d\n", p->id, p->value);
1024 struct v4l2_control *p = arg;
1026 if (!vfd->vidioc_s_ctrl)
1028 dbgarg (cmd, "id=%d, value=%d\n", p->id, p->value);
1030 ret=vfd->vidioc_s_ctrl(file, fh, p);
1033 case VIDIOC_G_EXT_CTRLS:
1035 struct v4l2_ext_controls *p = arg;
1037 if (vfd->vidioc_g_ext_ctrls) {
1038 dbgarg(cmd, "count=%d\n", p->count);
1040 ret=vfd->vidioc_g_ext_ctrls(file, fh, p);
1044 case VIDIOC_S_EXT_CTRLS:
1046 struct v4l2_ext_controls *p = arg;
1048 if (vfd->vidioc_s_ext_ctrls) {
1049 dbgarg(cmd, "count=%d\n", p->count);
1051 ret=vfd->vidioc_s_ext_ctrls(file, fh, p);
1055 case VIDIOC_TRY_EXT_CTRLS:
1057 struct v4l2_ext_controls *p = arg;
1059 if (vfd->vidioc_try_ext_ctrls) {
1060 dbgarg(cmd, "count=%d\n", p->count);
1062 ret=vfd->vidioc_try_ext_ctrls(file, fh, p);
1066 case VIDIOC_QUERYMENU:
1068 struct v4l2_querymenu *p=arg;
1069 if (!vfd->vidioc_querymenu)
1071 ret=vfd->vidioc_querymenu(file, fh, p);
1073 dbgarg (cmd, "id=%d, index=%d, name=%s\n",
1074 p->id,p->index,p->name);
1077 /* --- audio ---------------------------------------------- */
1078 case VIDIOC_ENUMAUDIO:
1080 struct v4l2_audio *p=arg;
1082 if (!vfd->vidioc_enumaudio)
1084 dbgarg(cmd, "Enum for index=%d\n", p->index);
1085 ret=vfd->vidioc_enumaudio(file, fh, p);
1087 dbgarg2("index=%d, name=%s, capability=%d, "
1088 "mode=%d\n",p->index,p->name,
1089 p->capability, p->mode);
1092 case VIDIOC_G_AUDIO:
1094 struct v4l2_audio *p=arg;
1095 __u32 index=p->index;
1097 if (!vfd->vidioc_g_audio)
1100 memset(p,0,sizeof(*p));
1102 dbgarg(cmd, "Get for index=%d\n", p->index);
1103 ret=vfd->vidioc_g_audio(file, fh, p);
1105 dbgarg2("index=%d, name=%s, capability=%d, "
1106 "mode=%d\n",p->index,
1107 p->name,p->capability, p->mode);
1110 case VIDIOC_S_AUDIO:
1112 struct v4l2_audio *p=arg;
1114 if (!vfd->vidioc_s_audio)
1116 dbgarg(cmd, "index=%d, name=%s, capability=%d, "
1117 "mode=%d\n", p->index, p->name,
1118 p->capability, p->mode);
1119 ret=vfd->vidioc_s_audio(file, fh, p);
1122 case VIDIOC_ENUMAUDOUT:
1124 struct v4l2_audioout *p=arg;
1126 if (!vfd->vidioc_enumaudout)
1128 dbgarg(cmd, "Enum for index=%d\n", p->index);
1129 ret=vfd->vidioc_enumaudout(file, fh, p);
1131 dbgarg2("index=%d, name=%s, capability=%d, "
1132 "mode=%d\n", p->index, p->name,
1133 p->capability,p->mode);
1136 case VIDIOC_G_AUDOUT:
1138 struct v4l2_audioout *p=arg;
1140 if (!vfd->vidioc_g_audout)
1142 dbgarg(cmd, "Enum for index=%d\n", p->index);
1143 ret=vfd->vidioc_g_audout(file, fh, p);
1145 dbgarg2("index=%d, name=%s, capability=%d, "
1146 "mode=%d\n", p->index, p->name,
1147 p->capability,p->mode);
1150 case VIDIOC_S_AUDOUT:
1152 struct v4l2_audioout *p=arg;
1154 if (!vfd->vidioc_s_audout)
1156 dbgarg(cmd, "index=%d, name=%s, capability=%d, "
1157 "mode=%d\n", p->index, p->name,
1158 p->capability,p->mode);
1160 ret=vfd->vidioc_s_audout(file, fh, p);
1163 case VIDIOC_G_MODULATOR:
1165 struct v4l2_modulator *p=arg;
1166 if (!vfd->vidioc_g_modulator)
1168 ret=vfd->vidioc_g_modulator(file, fh, p);
1170 dbgarg(cmd, "index=%d, name=%s, "
1171 "capability=%d, rangelow=%d,"
1172 " rangehigh=%d, txsubchans=%d\n",
1173 p->index, p->name,p->capability,
1174 p->rangelow, p->rangehigh,
1178 case VIDIOC_S_MODULATOR:
1180 struct v4l2_modulator *p=arg;
1181 if (!vfd->vidioc_s_modulator)
1183 dbgarg(cmd, "index=%d, name=%s, capability=%d, "
1184 "rangelow=%d, rangehigh=%d, txsubchans=%d\n",
1185 p->index, p->name,p->capability,p->rangelow,
1186 p->rangehigh,p->txsubchans);
1187 ret=vfd->vidioc_s_modulator(file, fh, p);
1192 struct v4l2_crop *p=arg;
1193 if (!vfd->vidioc_g_crop)
1195 ret=vfd->vidioc_g_crop(file, fh, p);
1197 dbgarg(cmd, "type=%d\n", p->type);
1198 dbgrect(vfd, "", &p->c);
1204 struct v4l2_crop *p=arg;
1205 if (!vfd->vidioc_s_crop)
1207 dbgarg(cmd, "type=%d\n", p->type);
1208 dbgrect(vfd, "", &p->c);
1209 ret=vfd->vidioc_s_crop(file, fh, p);
1212 case VIDIOC_CROPCAP:
1214 struct v4l2_cropcap *p=arg;
1215 /*FIXME: Should also show v4l2_fract pixelaspect */
1216 if (!vfd->vidioc_cropcap)
1218 dbgarg(cmd, "type=%d\n", p->type);
1219 dbgrect(vfd, "bounds ", &p->bounds);
1220 dbgrect(vfd, "defrect ", &p->defrect);
1221 ret=vfd->vidioc_cropcap(file, fh, p);
1224 case VIDIOC_G_MPEGCOMP:
1226 struct v4l2_mpeg_compression *p=arg;
1228 /*FIXME: Several fields not shown */
1229 if (!vfd->vidioc_g_mpegcomp)
1231 ret=vfd->vidioc_g_mpegcomp(file, fh, p);
1233 dbgarg (cmd, "ts_pid_pmt=%d, ts_pid_audio=%d,"
1234 " ts_pid_video=%d, ts_pid_pcr=%d, "
1235 "ps_size=%d, au_sample_rate=%d, "
1236 "au_pesid=%c, vi_frame_rate=%d, "
1237 "vi_frames_per_gop=%d, "
1238 "vi_bframes_count=%d, vi_pesid=%c\n",
1239 p->ts_pid_pmt,p->ts_pid_audio,
1240 p->ts_pid_video,p->ts_pid_pcr,
1241 p->ps_size, p->au_sample_rate,
1242 p->au_pesid, p->vi_frame_rate,
1243 p->vi_frames_per_gop,
1244 p->vi_bframes_count, p->vi_pesid);
1247 case VIDIOC_S_MPEGCOMP:
1249 struct v4l2_mpeg_compression *p=arg;
1250 /*FIXME: Several fields not shown */
1251 if (!vfd->vidioc_s_mpegcomp)
1253 dbgarg (cmd, "ts_pid_pmt=%d, ts_pid_audio=%d, "
1254 "ts_pid_video=%d, ts_pid_pcr=%d, ps_size=%d, "
1255 "au_sample_rate=%d, au_pesid=%c, "
1256 "vi_frame_rate=%d, vi_frames_per_gop=%d, "
1257 "vi_bframes_count=%d, vi_pesid=%c\n",
1258 p->ts_pid_pmt,p->ts_pid_audio, p->ts_pid_video,
1259 p->ts_pid_pcr, p->ps_size, p->au_sample_rate,
1260 p->au_pesid, p->vi_frame_rate,
1261 p->vi_frames_per_gop, p->vi_bframes_count,
1263 ret=vfd->vidioc_s_mpegcomp(file, fh, p);
1266 case VIDIOC_G_JPEGCOMP:
1268 struct v4l2_jpegcompression *p=arg;
1269 if (!vfd->vidioc_g_jpegcomp)
1271 ret=vfd->vidioc_g_jpegcomp(file, fh, p);
1273 dbgarg (cmd, "quality=%d, APPn=%d, "
1274 "APP_len=%d, COM_len=%d, "
1275 "jpeg_markers=%d\n",
1276 p->quality,p->APPn,p->APP_len,
1277 p->COM_len,p->jpeg_markers);
1280 case VIDIOC_S_JPEGCOMP:
1282 struct v4l2_jpegcompression *p=arg;
1283 if (!vfd->vidioc_g_jpegcomp)
1285 dbgarg (cmd, "quality=%d, APPn=%d, APP_len=%d, "
1286 "COM_len=%d, jpeg_markers=%d\n",
1287 p->quality,p->APPn,p->APP_len,
1288 p->COM_len,p->jpeg_markers);
1289 ret=vfd->vidioc_s_jpegcomp(file, fh, p);
1294 struct v4l2_streamparm *p=arg;
1295 if (vfd->vidioc_g_parm) {
1296 ret=vfd->vidioc_g_parm(file, fh, p);
1298 struct v4l2_standard s;
1301 if (!vfd->tvnormsize) {
1302 printk (KERN_WARNING "%s: no TV norms defined!\n",
1307 if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1310 for (i = 0; i < vfd->tvnormsize; i++)
1311 if (vfd->tvnorms[i].id == vfd->current_norm)
1313 if (i >= vfd->tvnormsize)
1316 v4l2_video_std_construct(&s, vfd->current_norm,
1317 vfd->tvnorms[i].name);
1319 memset(p,0,sizeof(*p));
1321 p->parm.capture.timeperframe = s.frameperiod;
1325 dbgarg (cmd, "type=%d\n", p->type);
1330 struct v4l2_streamparm *p=arg;
1331 if (!vfd->vidioc_s_parm)
1333 dbgarg (cmd, "type=%d\n", p->type);
1334 ret=vfd->vidioc_s_parm(file, fh, p);
1337 case VIDIOC_G_TUNER:
1339 struct v4l2_tuner *p=arg;
1340 __u32 index=p->index;
1342 if (!vfd->vidioc_g_tuner)
1345 memset(p,0,sizeof(*p));
1348 ret=vfd->vidioc_g_tuner(file, fh, p);
1350 dbgarg (cmd, "index=%d, name=%s, type=%d, "
1351 "capability=%d, rangelow=%d, "
1352 "rangehigh=%d, signal=%d, afc=%d, "
1353 "rxsubchans=%d, audmode=%d\n",
1354 p->index, p->name, p->type,
1355 p->capability, p->rangelow,
1356 p->rangehigh, p->rxsubchans,
1357 p->audmode, p->signal, p->afc);
1360 case VIDIOC_S_TUNER:
1362 struct v4l2_tuner *p=arg;
1363 if (!vfd->vidioc_s_tuner)
1365 dbgarg (cmd, "index=%d, name=%s, type=%d, "
1366 "capability=%d, rangelow=%d, rangehigh=%d, "
1367 "signal=%d, afc=%d, rxsubchans=%d, "
1368 "audmode=%d\n",p->index, p->name, p->type,
1369 p->capability, p->rangelow,p->rangehigh,
1370 p->rxsubchans, p->audmode, p->signal,
1372 ret=vfd->vidioc_s_tuner(file, fh, p);
1375 case VIDIOC_G_FREQUENCY:
1377 struct v4l2_frequency *p=arg;
1378 if (!vfd->vidioc_g_frequency)
1381 memset(p,0,sizeof(*p));
1383 ret=vfd->vidioc_g_frequency(file, fh, p);
1385 dbgarg (cmd, "tuner=%d, type=%d, frequency=%d\n",
1386 p->tuner,p->type,p->frequency);
1389 case VIDIOC_S_FREQUENCY:
1391 struct v4l2_frequency *p=arg;
1392 if (!vfd->vidioc_s_frequency)
1394 dbgarg (cmd, "tuner=%d, type=%d, frequency=%d\n",
1395 p->tuner,p->type,p->frequency);
1396 ret=vfd->vidioc_s_frequency(file, fh, p);
1399 case VIDIOC_G_SLICED_VBI_CAP:
1401 struct v4l2_sliced_vbi_cap *p=arg;
1402 if (!vfd->vidioc_g_sliced_vbi_cap)
1404 ret=vfd->vidioc_g_sliced_vbi_cap(file, fh, p);
1406 dbgarg (cmd, "service_set=%d\n", p->service_set);
1409 case VIDIOC_LOG_STATUS:
1411 if (!vfd->vidioc_log_status)
1413 ret=vfd->vidioc_log_status(file, fh);
1418 if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) {
1420 printk ("%s: err:\n", vfd->name);
1421 v4l_print_ioctl(vfd->name, cmd);
1428 int video_ioctl2 (struct inode *inode, struct file *file,
1429 unsigned int cmd, unsigned long arg)
1436 size_t ctrls_size = 0;
1437 void __user *user_ptr = NULL;
1439 #ifdef __OLD_VIDIOC_
1440 cmd = video_fix_command(cmd);
1442 is_ext_ctrl = (cmd == VIDIOC_S_EXT_CTRLS || cmd == VIDIOC_G_EXT_CTRLS ||
1443 cmd == VIDIOC_TRY_EXT_CTRLS);
1445 /* Copy arguments into temp kernel buffer */
1446 switch (_IOC_DIR(cmd)) {
1452 case (_IOC_WRITE | _IOC_READ):
1453 if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
1456 /* too big to allocate from stack */
1457 mbuf = kmalloc(_IOC_SIZE(cmd),GFP_KERNEL);
1464 if (_IOC_DIR(cmd) & _IOC_WRITE)
1465 if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd)))
1471 struct v4l2_ext_controls *p = parg;
1473 /* In case of an error, tell the caller that it wasn't
1474 a specific control that caused it. */
1475 p->error_idx = p->count;
1476 user_ptr = (void __user *)p->controls;
1478 ctrls_size = sizeof(struct v4l2_ext_control) * p->count;
1479 /* Note: v4l2_ext_controls fits in sbuf[] so mbuf is still NULL. */
1480 mbuf = kmalloc(ctrls_size, GFP_KERNEL);
1485 if (copy_from_user(mbuf, user_ptr, ctrls_size))
1492 err = __video_do_ioctl(inode, file, cmd, parg);
1493 if (err == -ENOIOCTLCMD)
1496 struct v4l2_ext_controls *p = parg;
1498 p->controls = (void *)user_ptr;
1499 if (p->count && err == 0 && copy_to_user(user_ptr, mbuf, ctrls_size))
1507 /* Copy results into user buffer */
1508 switch (_IOC_DIR(cmd))
1511 case (_IOC_WRITE | _IOC_READ):
1512 if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd)))
1523 static struct file_operations video_fops;
1526 * video_register_device - register video4linux devices
1527 * @vfd: video device structure we want to register
1528 * @type: type of device to register
1529 * @nr: which device number (0 == /dev/video0, 1 == /dev/video1, ...
1532 * The registration code assigns minor numbers based on the type
1533 * requested. -ENFILE is returned in all the device slots for this
1534 * category are full. If not then the minor field is set and the
1535 * driver initialize function is called (if non %NULL).
1537 * Zero is returned on success.
1541 * %VFL_TYPE_GRABBER - A frame grabber
1543 * %VFL_TYPE_VTX - A teletext device
1545 * %VFL_TYPE_VBI - Vertical blank data (undecoded)
1547 * %VFL_TYPE_RADIO - A radio card
1550 int video_register_device(struct video_device *vfd, int type, int nr)
1560 case VFL_TYPE_GRABBER:
1561 base=MINOR_VFL_TYPE_GRABBER_MIN;
1562 end=MINOR_VFL_TYPE_GRABBER_MAX+1;
1563 name_base = "video";
1566 base=MINOR_VFL_TYPE_VTX_MIN;
1567 end=MINOR_VFL_TYPE_VTX_MAX+1;
1571 base=MINOR_VFL_TYPE_VBI_MIN;
1572 end=MINOR_VFL_TYPE_VBI_MAX+1;
1575 case VFL_TYPE_RADIO:
1576 base=MINOR_VFL_TYPE_RADIO_MIN;
1577 end=MINOR_VFL_TYPE_RADIO_MAX+1;
1578 name_base = "radio";
1581 printk(KERN_ERR "%s called with unknown type: %d\n",
1582 __FUNCTION__, type);
1586 /* pick a minor number */
1587 mutex_lock(&videodev_lock);
1588 if (nr >= 0 && nr < end-base) {
1589 /* use the one the driver asked for */
1591 if (NULL != video_device[i]) {
1592 mutex_unlock(&videodev_lock);
1596 /* use first free */
1597 for(i=base;i<end;i++)
1598 if (NULL == video_device[i])
1601 mutex_unlock(&videodev_lock);
1605 video_device[i]=vfd;
1607 mutex_unlock(&videodev_lock);
1608 mutex_init(&vfd->lock);
1611 memset(&vfd->class_dev, 0x00, sizeof(vfd->class_dev));
1613 vfd->class_dev.dev = vfd->dev;
1614 vfd->class_dev.class = &video_class;
1615 vfd->class_dev.devt = MKDEV(VIDEO_MAJOR, vfd->minor);
1616 sprintf(vfd->class_dev.class_id, "%s%d", name_base, i - base);
1617 ret = class_device_register(&vfd->class_dev);
1619 printk(KERN_ERR "%s: class_device_register failed\n",
1623 ret = class_device_create_file(&vfd->class_dev, &class_device_attr_name);
1625 printk(KERN_ERR "%s: class_device_create_file 'name' failed\n",
1631 /* needed until all drivers are fixed */
1633 printk(KERN_WARNING "videodev: \"%s\" has no release callback. "
1634 "Please fix your driver for proper sysfs support, see "
1635 "http://lwn.net/Articles/36850/\n", vfd->name);
1640 class_device_unregister(&vfd->class_dev);
1642 mutex_lock(&videodev_lock);
1643 video_device[vfd->minor] = NULL;
1645 mutex_unlock(&videodev_lock);
1650 * video_unregister_device - unregister a video4linux device
1651 * @vfd: the device to unregister
1653 * This unregisters the passed device and deassigns the minor
1654 * number. Future open calls will be met with errors.
1657 void video_unregister_device(struct video_device *vfd)
1659 mutex_lock(&videodev_lock);
1660 if(video_device[vfd->minor]!=vfd)
1661 panic("videodev: bad unregister");
1663 video_device[vfd->minor]=NULL;
1664 class_device_unregister(&vfd->class_dev);
1665 mutex_unlock(&videodev_lock);
1669 * Video fs operations
1671 static struct file_operations video_fops=
1673 .owner = THIS_MODULE,
1674 .llseek = no_llseek,
1679 * Initialise video for linux
1682 static int __init videodev_init(void)
1686 printk(KERN_INFO "Linux video capture interface: v2.00\n");
1687 if (register_chrdev(VIDEO_MAJOR, VIDEO_NAME, &video_fops)) {
1688 printk(KERN_WARNING "video_dev: unable to get major %d\n", VIDEO_MAJOR);
1692 ret = class_register(&video_class);
1694 unregister_chrdev(VIDEO_MAJOR, VIDEO_NAME);
1695 printk(KERN_WARNING "video_dev: class_register failed\n");
1702 static void __exit videodev_exit(void)
1704 class_unregister(&video_class);
1705 unregister_chrdev(VIDEO_MAJOR, VIDEO_NAME);
1708 module_init(videodev_init)
1709 module_exit(videodev_exit)
1711 EXPORT_SYMBOL(video_register_device);
1712 EXPORT_SYMBOL(video_unregister_device);
1713 EXPORT_SYMBOL(video_devdata);
1714 EXPORT_SYMBOL(video_usercopy);
1715 EXPORT_SYMBOL(video_exclusive_open);
1716 EXPORT_SYMBOL(video_exclusive_release);
1717 EXPORT_SYMBOL(video_ioctl2);
1718 EXPORT_SYMBOL(video_device_alloc);
1719 EXPORT_SYMBOL(video_device_release);
1721 MODULE_AUTHOR("Alan Cox, Mauro Carvalho Chehab <mchehab@infradead.org>");
1722 MODULE_DESCRIPTION("Device registrar for Video4Linux drivers v2");
1723 MODULE_LICENSE("GPL");