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, length=%d\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),
355 p->m.userptr, p->length);
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=%c%c%c%c, field=%s, "
373 "bytesperline=%d sizeimage=%d, colorspace=%d\n",
374 fmt->width,fmt->height,
375 (fmt->pixelformat & 0xff),
376 (fmt->pixelformat >> 8) & 0xff,
377 (fmt->pixelformat >> 16) & 0xff,
378 (fmt->pixelformat >> 24) & 0xff,
379 prt_names(fmt->field,v4l2_field_names_FIXME),
380 fmt->bytesperline,fmt->sizeimage,fmt->colorspace);
384 static int check_fmt (struct video_device *vfd, enum v4l2_buf_type type)
387 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
388 if (vfd->vidioc_try_fmt_cap)
391 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
392 if (vfd->vidioc_try_fmt_overlay)
395 case V4L2_BUF_TYPE_VBI_CAPTURE:
396 if (vfd->vidioc_try_fmt_vbi)
399 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
400 if (vfd->vidioc_try_fmt_vbi_output)
403 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
404 if (vfd->vidioc_try_fmt_vbi_capture)
407 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
408 if (vfd->vidioc_try_fmt_video_output)
411 case V4L2_BUF_TYPE_VBI_OUTPUT:
412 if (vfd->vidioc_try_fmt_vbi_output)
415 case V4L2_BUF_TYPE_PRIVATE:
416 if (vfd->vidioc_try_fmt_type_private)
423 static int __video_do_ioctl(struct inode *inode, struct file *file,
424 unsigned int cmd, void *arg)
426 struct video_device *vfd = video_devdata(file);
427 void *fh = file->private_data;
430 if ( (vfd->debug & V4L2_DEBUG_IOCTL) &&
431 !(vfd->debug | V4L2_DEBUG_IOCTL_ARG)) {
432 v4l_print_ioctl(vfd->name, cmd);
435 if (_IOC_TYPE(cmd)=='v')
436 return v4l_compat_translate_ioctl(inode,file,cmd,arg,
440 /* --- capabilities ------------------------------------------ */
441 case VIDIOC_QUERYCAP:
443 struct v4l2_capability *cap = (struct v4l2_capability*)arg;
444 memset(cap, 0, sizeof(*cap));
446 if (!vfd->vidioc_querycap)
449 ret=vfd->vidioc_querycap(file, fh, cap);
451 dbgarg (cmd, "driver=%s, card=%s, bus=%s, "
453 "capabilities=0x%08x\n",
454 cap->driver,cap->card,cap->bus_info,
460 /* --- priority ------------------------------------------ */
461 case VIDIOC_G_PRIORITY:
463 enum v4l2_priority *p=arg;
465 if (!vfd->vidioc_g_priority)
467 ret=vfd->vidioc_g_priority(file, fh, p);
469 dbgarg(cmd, "priority is %d\n", *p);
472 case VIDIOC_S_PRIORITY:
474 enum v4l2_priority *p=arg;
476 if (!vfd->vidioc_s_priority)
478 dbgarg(cmd, "setting priority to %d\n", *p);
479 ret=vfd->vidioc_s_priority(file, fh, *p);
483 /* --- capture ioctls ---------------------------------------- */
484 case VIDIOC_ENUM_FMT:
486 struct v4l2_fmtdesc *f = arg;
487 enum v4l2_buf_type type;
492 memset(f,0,sizeof(*f));
497 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
498 if (vfd->vidioc_enum_fmt_cap)
499 ret=vfd->vidioc_enum_fmt_cap(file, fh, f);
501 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
502 if (vfd->vidioc_enum_fmt_overlay)
503 ret=vfd->vidioc_enum_fmt_overlay(file, fh, f);
505 case V4L2_BUF_TYPE_VBI_CAPTURE:
506 if (vfd->vidioc_enum_fmt_vbi)
507 ret=vfd->vidioc_enum_fmt_vbi(file, fh, f);
509 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
510 if (vfd->vidioc_enum_fmt_vbi_output)
511 ret=vfd->vidioc_enum_fmt_vbi_output(file,
514 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
515 if (vfd->vidioc_enum_fmt_vbi_capture)
516 ret=vfd->vidioc_enum_fmt_vbi_capture(file,
519 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
520 if (vfd->vidioc_enum_fmt_video_output)
521 ret=vfd->vidioc_enum_fmt_video_output(file,
524 case V4L2_BUF_TYPE_VBI_OUTPUT:
525 if (vfd->vidioc_enum_fmt_vbi_output)
526 ret=vfd->vidioc_enum_fmt_vbi_output(file,
529 case V4L2_BUF_TYPE_PRIVATE:
530 if (vfd->vidioc_enum_fmt_type_private)
531 ret=vfd->vidioc_enum_fmt_type_private(file,
536 dbgarg (cmd, "index=%d, type=%d, flags=%d, "
537 "pixelformat=%c%c%c%c, description='%s'\n",
538 f->index, f->type, f->flags,
539 (f->pixelformat & 0xff),
540 (f->pixelformat >> 8) & 0xff,
541 (f->pixelformat >> 16) & 0xff,
542 (f->pixelformat >> 24) & 0xff,
548 struct v4l2_format *f = (struct v4l2_format *)arg;
549 enum v4l2_buf_type type=f->type;
551 memset(&f->fmt.pix,0,sizeof(f->fmt.pix));
554 /* FIXME: Should be one dump per type */
555 dbgarg (cmd, "type=%s\n", prt_names(type,
556 v4l2_type_names_FIXME));
559 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
560 if (vfd->vidioc_g_fmt_cap)
561 ret=vfd->vidioc_g_fmt_cap(file, fh, f);
563 v4l_print_pix_fmt(vfd,&f->fmt.pix);
565 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
566 if (vfd->vidioc_g_fmt_overlay)
567 ret=vfd->vidioc_g_fmt_overlay(file, fh, f);
569 case V4L2_BUF_TYPE_VBI_CAPTURE:
570 if (vfd->vidioc_g_fmt_vbi)
571 ret=vfd->vidioc_g_fmt_vbi(file, fh, f);
573 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
574 if (vfd->vidioc_g_fmt_vbi_output)
575 ret=vfd->vidioc_g_fmt_vbi_output(file, fh, f);
577 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
578 if (vfd->vidioc_g_fmt_vbi_capture)
579 ret=vfd->vidioc_g_fmt_vbi_capture(file, fh, f);
581 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
582 if (vfd->vidioc_g_fmt_video_output)
583 ret=vfd->vidioc_g_fmt_video_output(file,
586 case V4L2_BUF_TYPE_VBI_OUTPUT:
587 if (vfd->vidioc_g_fmt_vbi_output)
588 ret=vfd->vidioc_g_fmt_vbi_output(file, fh, f);
590 case V4L2_BUF_TYPE_PRIVATE:
591 if (vfd->vidioc_g_fmt_type_private)
592 ret=vfd->vidioc_g_fmt_type_private(file,
601 struct v4l2_format *f = (struct v4l2_format *)arg;
603 /* FIXME: Should be one dump per type */
604 dbgarg (cmd, "type=%s\n", prt_names(f->type,
605 v4l2_type_names_FIXME));
608 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
609 v4l_print_pix_fmt(vfd,&f->fmt.pix);
610 if (vfd->vidioc_s_fmt_cap)
611 ret=vfd->vidioc_s_fmt_cap(file, fh, f);
613 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
614 if (vfd->vidioc_s_fmt_overlay)
615 ret=vfd->vidioc_s_fmt_overlay(file, fh, f);
617 case V4L2_BUF_TYPE_VBI_CAPTURE:
618 if (vfd->vidioc_s_fmt_vbi)
619 ret=vfd->vidioc_s_fmt_vbi(file, fh, f);
621 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
622 if (vfd->vidioc_s_fmt_vbi_output)
623 ret=vfd->vidioc_s_fmt_vbi_output(file, fh, f);
625 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
626 if (vfd->vidioc_s_fmt_vbi_capture)
627 ret=vfd->vidioc_s_fmt_vbi_capture(file, fh, f);
629 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
630 if (vfd->vidioc_s_fmt_video_output)
631 ret=vfd->vidioc_s_fmt_video_output(file,
634 case V4L2_BUF_TYPE_VBI_OUTPUT:
635 if (vfd->vidioc_s_fmt_vbi_output)
636 ret=vfd->vidioc_s_fmt_vbi_output(file,
639 case V4L2_BUF_TYPE_PRIVATE:
640 if (vfd->vidioc_s_fmt_type_private)
641 ret=vfd->vidioc_s_fmt_type_private(file,
649 struct v4l2_format *f = (struct v4l2_format *)arg;
651 /* FIXME: Should be one dump per type */
652 dbgarg (cmd, "type=%s\n", prt_names(f->type,
653 v4l2_type_names_FIXME));
655 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
656 if (vfd->vidioc_try_fmt_cap)
657 ret=vfd->vidioc_try_fmt_cap(file, fh, f);
659 v4l_print_pix_fmt(vfd,&f->fmt.pix);
661 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
662 if (vfd->vidioc_try_fmt_overlay)
663 ret=vfd->vidioc_try_fmt_overlay(file, fh, f);
665 case V4L2_BUF_TYPE_VBI_CAPTURE:
666 if (vfd->vidioc_try_fmt_vbi)
667 ret=vfd->vidioc_try_fmt_vbi(file, fh, f);
669 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
670 if (vfd->vidioc_try_fmt_vbi_output)
671 ret=vfd->vidioc_try_fmt_vbi_output(file,
674 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
675 if (vfd->vidioc_try_fmt_vbi_capture)
676 ret=vfd->vidioc_try_fmt_vbi_capture(file,
679 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
680 if (vfd->vidioc_try_fmt_video_output)
681 ret=vfd->vidioc_try_fmt_video_output(file,
684 case V4L2_BUF_TYPE_VBI_OUTPUT:
685 if (vfd->vidioc_try_fmt_vbi_output)
686 ret=vfd->vidioc_try_fmt_vbi_output(file,
689 case V4L2_BUF_TYPE_PRIVATE:
690 if (vfd->vidioc_try_fmt_type_private)
691 ret=vfd->vidioc_try_fmt_type_private(file,
698 /* FIXME: Those buf reqs could be handled here,
699 with some changes on videobuf to allow its header to be included at
700 videodev2.h or being merged at videodev2.
704 struct v4l2_requestbuffers *p=arg;
706 if (!vfd->vidioc_reqbufs)
708 ret = check_fmt (vfd, p->type);
712 ret=vfd->vidioc_reqbufs(file, fh, p);
713 dbgarg (cmd, "count=%d, type=%s, memory=%s\n",
715 prt_names(p->type,v4l2_type_names_FIXME),
716 prt_names(p->memory,v4l2_memory_names));
719 case VIDIOC_QUERYBUF:
721 struct v4l2_buffer *p=arg;
723 if (!vfd->vidioc_querybuf)
725 ret = check_fmt (vfd, p->type);
729 ret=vfd->vidioc_querybuf(file, fh, p);
736 struct v4l2_buffer *p=arg;
738 if (!vfd->vidioc_qbuf)
740 ret = check_fmt (vfd, p->type);
744 ret=vfd->vidioc_qbuf(file, fh, p);
751 struct v4l2_buffer *p=arg;
752 if (!vfd->vidioc_dqbuf)
754 ret = check_fmt (vfd, p->type);
758 ret=vfd->vidioc_dqbuf(file, fh, p);
767 if (!vfd->vidioc_overlay)
769 dbgarg (cmd, "value=%d\n",*i);
770 ret=vfd->vidioc_overlay(file, fh, *i);
773 #ifdef CONFIG_VIDEO_V4L1_COMPAT
774 /* --- streaming capture ------------------------------------- */
777 struct video_mbuf *p=arg;
779 memset(p,0,sizeof(p));
781 if (!vfd->vidiocgmbuf)
783 ret=vfd->vidiocgmbuf(file, fh, p);
785 dbgarg (cmd, "size=%d, frames=%d, offsets=0x%08lx\n",
787 (unsigned long)p->offsets);
793 struct v4l2_framebuffer *p=arg;
794 if (!vfd->vidioc_g_fbuf)
796 ret=vfd->vidioc_g_fbuf(file, fh, arg);
798 dbgarg (cmd, "capability=%d, flags=%d, base=0x%08lx\n",
799 p->capability,p->flags,
800 (unsigned long)p->base);
801 v4l_print_pix_fmt (vfd, &p->fmt);
807 struct v4l2_framebuffer *p=arg;
808 if (!vfd->vidioc_s_fbuf)
811 dbgarg (cmd, "capability=%d, flags=%d, base=0x%08lx\n",
812 p->capability,p->flags,(unsigned long)p->base);
813 v4l_print_pix_fmt (vfd, &p->fmt);
814 ret=vfd->vidioc_s_fbuf(file, fh, arg);
818 case VIDIOC_STREAMON:
820 enum v4l2_buf_type i = *(int *)arg;
821 if (!vfd->vidioc_streamon)
823 dbgarg (cmd, "type=%s\n", prt_names(i,v4l2_type_names_FIXME));
824 ret=vfd->vidioc_streamon(file, fh,i);
827 case VIDIOC_STREAMOFF:
829 enum v4l2_buf_type i = *(int *)arg;
831 if (!vfd->vidioc_streamoff)
833 dbgarg (cmd, "type=%s\n", prt_names(i,v4l2_type_names_FIXME));
834 ret=vfd->vidioc_streamoff(file, fh, i);
837 /* ---------- tv norms ---------- */
840 struct v4l2_standard *p = arg;
841 v4l2_std_id id = vfd->tvnorms,curr_id=0;
842 unsigned int index = p->index,i;
849 /* Return norm array on a canonical way */
850 for (i=0;i<= index && id; i++) {
851 if ( (id & V4L2_STD_PAL) == V4L2_STD_PAL) {
852 curr_id = V4L2_STD_PAL;
853 } else if ( (id & V4L2_STD_PAL_BG) == V4L2_STD_PAL_BG) {
854 curr_id = V4L2_STD_PAL_BG;
855 } else if ( (id & V4L2_STD_PAL_DK) == V4L2_STD_PAL_DK) {
856 curr_id = V4L2_STD_PAL_DK;
857 } else if ( (id & V4L2_STD_PAL_B) == V4L2_STD_PAL_B) {
858 curr_id = V4L2_STD_PAL_B;
859 } else if ( (id & V4L2_STD_PAL_B1) == V4L2_STD_PAL_B1) {
860 curr_id = V4L2_STD_PAL_B1;
861 } else if ( (id & V4L2_STD_PAL_G) == V4L2_STD_PAL_G) {
862 curr_id = V4L2_STD_PAL_G;
863 } else if ( (id & V4L2_STD_PAL_H) == V4L2_STD_PAL_H) {
864 curr_id = V4L2_STD_PAL_H;
865 } else if ( (id & V4L2_STD_PAL_I) == V4L2_STD_PAL_I) {
866 curr_id = V4L2_STD_PAL_I;
867 } else if ( (id & V4L2_STD_PAL_D) == V4L2_STD_PAL_D) {
868 curr_id = V4L2_STD_PAL_D;
869 } else if ( (id & V4L2_STD_PAL_D1) == V4L2_STD_PAL_D1) {
870 curr_id = V4L2_STD_PAL_D1;
871 } else if ( (id & V4L2_STD_PAL_K) == V4L2_STD_PAL_K) {
872 curr_id = V4L2_STD_PAL_K;
873 } else if ( (id & V4L2_STD_PAL_M) == V4L2_STD_PAL_M) {
874 curr_id = V4L2_STD_PAL_M;
875 } else if ( (id & V4L2_STD_PAL_N) == V4L2_STD_PAL_N) {
876 curr_id = V4L2_STD_PAL_N;
877 } else if ( (id & V4L2_STD_PAL_Nc) == V4L2_STD_PAL_Nc) {
878 curr_id = V4L2_STD_PAL_Nc;
879 } else if ( (id & V4L2_STD_PAL_60) == V4L2_STD_PAL_60) {
880 curr_id = V4L2_STD_PAL_60;
881 } else if ( (id & V4L2_STD_NTSC) == V4L2_STD_NTSC) {
882 curr_id = V4L2_STD_NTSC;
883 } else if ( (id & V4L2_STD_NTSC_M) == V4L2_STD_NTSC_M) {
884 curr_id = V4L2_STD_NTSC_M;
885 } else if ( (id & V4L2_STD_NTSC_M_JP) == V4L2_STD_NTSC_M_JP) {
886 curr_id = V4L2_STD_NTSC_M_JP;
887 } else if ( (id & V4L2_STD_NTSC_443) == V4L2_STD_NTSC_443) {
888 curr_id = V4L2_STD_NTSC_443;
889 } else if ( (id & V4L2_STD_NTSC_M_KR) == V4L2_STD_NTSC_M_KR) {
890 curr_id = V4L2_STD_NTSC_M_KR;
891 } else if ( (id & V4L2_STD_SECAM) == V4L2_STD_SECAM) {
892 curr_id = V4L2_STD_SECAM;
893 } else if ( (id & V4L2_STD_SECAM_DK) == V4L2_STD_SECAM_DK) {
894 curr_id = V4L2_STD_SECAM_DK;
895 } else if ( (id & V4L2_STD_SECAM_B) == V4L2_STD_SECAM_B) {
896 curr_id = V4L2_STD_SECAM_B;
897 } else if ( (id & V4L2_STD_SECAM_D) == V4L2_STD_SECAM_D) {
898 curr_id = V4L2_STD_SECAM_D;
899 } else if ( (id & V4L2_STD_SECAM_G) == V4L2_STD_SECAM_G) {
900 curr_id = V4L2_STD_SECAM_G;
901 } else if ( (id & V4L2_STD_SECAM_H) == V4L2_STD_SECAM_H) {
902 curr_id = V4L2_STD_SECAM_H;
903 } else if ( (id & V4L2_STD_SECAM_K) == V4L2_STD_SECAM_K) {
904 curr_id = V4L2_STD_SECAM_K;
905 } else if ( (id & V4L2_STD_SECAM_K1) == V4L2_STD_SECAM_K1) {
906 curr_id = V4L2_STD_SECAM_K1;
907 } else if ( (id & V4L2_STD_SECAM_L) == V4L2_STD_SECAM_L) {
908 curr_id = V4L2_STD_SECAM_L;
909 } else if ( (id & V4L2_STD_SECAM_LC) == V4L2_STD_SECAM_LC) {
910 curr_id = V4L2_STD_SECAM_LC;
919 v4l2_video_std_construct(p, curr_id,v4l2_norm_to_name(curr_id));
922 dbgarg (cmd, "index=%d, id=%Ld, name=%s, fps=%d/%d, "
923 "framelines=%d\n", p->index,
924 (unsigned long long)p->id, p->name,
925 p->frameperiod.numerator,
926 p->frameperiod.denominator,
934 v4l2_std_id *id = arg;
936 *id = vfd->current_norm;
938 dbgarg (cmd, "value=%Lu\n", (long long unsigned) *id);
945 v4l2_std_id *id = arg,norm;
947 dbgarg (cmd, "value=%Lu\n", (long long unsigned) *id);
949 norm = (*id) & vfd->tvnorms;
950 if ( vfd->tvnorms && !norm) /* Check if std is supported */
953 /* Calls the specific handler */
954 if (vfd->vidioc_s_std)
955 ret=vfd->vidioc_s_std(file, fh, &norm);
959 /* Updates standard information */
961 vfd->current_norm=norm;
965 case VIDIOC_QUERYSTD:
969 if (!vfd->vidioc_querystd)
971 ret=vfd->vidioc_querystd(file, fh, arg);
973 dbgarg (cmd, "detected std=%Lu\n",
974 (unsigned long long)*p);
977 /* ------ input switching ---------- */
978 /* FIXME: Inputs can be handled inside videodev2 */
979 case VIDIOC_ENUMINPUT:
981 struct v4l2_input *p=arg;
984 if (!vfd->vidioc_enum_input)
986 memset(p, 0, sizeof(*p));
989 ret=vfd->vidioc_enum_input(file, fh, p);
991 dbgarg (cmd, "index=%d, name=%s, type=%d, "
993 "tuner=%d, std=%Ld, status=%d\n",
994 p->index,p->name,p->type,p->audioset,
996 (unsigned long long)p->std,
1000 case VIDIOC_G_INPUT:
1002 unsigned int *i = arg;
1004 if (!vfd->vidioc_g_input)
1006 ret=vfd->vidioc_g_input(file, fh, i);
1008 dbgarg (cmd, "value=%d\n",*i);
1011 case VIDIOC_S_INPUT:
1013 unsigned int *i = arg;
1015 if (!vfd->vidioc_s_input)
1017 dbgarg (cmd, "value=%d\n",*i);
1018 ret=vfd->vidioc_s_input(file, fh, *i);
1022 /* ------ output switching ---------- */
1023 case VIDIOC_G_OUTPUT:
1025 unsigned int *i = arg;
1027 if (!vfd->vidioc_g_output)
1029 ret=vfd->vidioc_g_output(file, fh, i);
1031 dbgarg (cmd, "value=%d\n",*i);
1034 case VIDIOC_S_OUTPUT:
1036 unsigned int *i = arg;
1038 if (!vfd->vidioc_s_output)
1040 dbgarg (cmd, "value=%d\n",*i);
1041 ret=vfd->vidioc_s_output(file, fh, *i);
1045 /* --- controls ---------------------------------------------- */
1046 case VIDIOC_QUERYCTRL:
1048 struct v4l2_queryctrl *p=arg;
1050 if (!vfd->vidioc_queryctrl)
1052 ret=vfd->vidioc_queryctrl(file, fh, p);
1055 dbgarg (cmd, "id=%d, type=%d, name=%s, "
1057 " step=%d, default=%d, flags=0x%08x\n",
1058 p->id,p->type,p->name,p->minimum,
1059 p->maximum,p->step,p->default_value,
1065 struct v4l2_control *p = arg;
1067 if (!vfd->vidioc_g_ctrl)
1069 dbgarg(cmd, "Enum for index=%d\n", p->id);
1071 ret=vfd->vidioc_g_ctrl(file, fh, p);
1073 dbgarg2 ( "id=%d, value=%d\n", p->id, p->value);
1078 struct v4l2_control *p = arg;
1080 if (!vfd->vidioc_s_ctrl)
1082 dbgarg (cmd, "id=%d, value=%d\n", p->id, p->value);
1084 ret=vfd->vidioc_s_ctrl(file, fh, p);
1087 case VIDIOC_G_EXT_CTRLS:
1089 struct v4l2_ext_controls *p = arg;
1091 if (vfd->vidioc_g_ext_ctrls) {
1092 dbgarg(cmd, "count=%d\n", p->count);
1094 ret=vfd->vidioc_g_ext_ctrls(file, fh, p);
1098 case VIDIOC_S_EXT_CTRLS:
1100 struct v4l2_ext_controls *p = arg;
1102 if (vfd->vidioc_s_ext_ctrls) {
1103 dbgarg(cmd, "count=%d\n", p->count);
1105 ret=vfd->vidioc_s_ext_ctrls(file, fh, p);
1109 case VIDIOC_TRY_EXT_CTRLS:
1111 struct v4l2_ext_controls *p = arg;
1113 if (vfd->vidioc_try_ext_ctrls) {
1114 dbgarg(cmd, "count=%d\n", p->count);
1116 ret=vfd->vidioc_try_ext_ctrls(file, fh, p);
1120 case VIDIOC_QUERYMENU:
1122 struct v4l2_querymenu *p=arg;
1123 if (!vfd->vidioc_querymenu)
1125 ret=vfd->vidioc_querymenu(file, fh, p);
1127 dbgarg (cmd, "id=%d, index=%d, name=%s\n",
1128 p->id,p->index,p->name);
1131 /* --- audio ---------------------------------------------- */
1132 case VIDIOC_ENUMAUDIO:
1134 struct v4l2_audio *p=arg;
1136 if (!vfd->vidioc_enumaudio)
1138 dbgarg(cmd, "Enum for index=%d\n", p->index);
1139 ret=vfd->vidioc_enumaudio(file, fh, p);
1141 dbgarg2("index=%d, name=%s, capability=%d, "
1142 "mode=%d\n",p->index,p->name,
1143 p->capability, p->mode);
1146 case VIDIOC_G_AUDIO:
1148 struct v4l2_audio *p=arg;
1149 __u32 index=p->index;
1151 if (!vfd->vidioc_g_audio)
1154 memset(p,0,sizeof(*p));
1156 dbgarg(cmd, "Get for index=%d\n", p->index);
1157 ret=vfd->vidioc_g_audio(file, fh, p);
1159 dbgarg2("index=%d, name=%s, capability=%d, "
1160 "mode=%d\n",p->index,
1161 p->name,p->capability, p->mode);
1164 case VIDIOC_S_AUDIO:
1166 struct v4l2_audio *p=arg;
1168 if (!vfd->vidioc_s_audio)
1170 dbgarg(cmd, "index=%d, name=%s, capability=%d, "
1171 "mode=%d\n", p->index, p->name,
1172 p->capability, p->mode);
1173 ret=vfd->vidioc_s_audio(file, fh, p);
1176 case VIDIOC_ENUMAUDOUT:
1178 struct v4l2_audioout *p=arg;
1180 if (!vfd->vidioc_enumaudout)
1182 dbgarg(cmd, "Enum for index=%d\n", p->index);
1183 ret=vfd->vidioc_enumaudout(file, fh, p);
1185 dbgarg2("index=%d, name=%s, capability=%d, "
1186 "mode=%d\n", p->index, p->name,
1187 p->capability,p->mode);
1190 case VIDIOC_G_AUDOUT:
1192 struct v4l2_audioout *p=arg;
1194 if (!vfd->vidioc_g_audout)
1196 dbgarg(cmd, "Enum for index=%d\n", p->index);
1197 ret=vfd->vidioc_g_audout(file, fh, p);
1199 dbgarg2("index=%d, name=%s, capability=%d, "
1200 "mode=%d\n", p->index, p->name,
1201 p->capability,p->mode);
1204 case VIDIOC_S_AUDOUT:
1206 struct v4l2_audioout *p=arg;
1208 if (!vfd->vidioc_s_audout)
1210 dbgarg(cmd, "index=%d, name=%s, capability=%d, "
1211 "mode=%d\n", p->index, p->name,
1212 p->capability,p->mode);
1214 ret=vfd->vidioc_s_audout(file, fh, p);
1217 case VIDIOC_G_MODULATOR:
1219 struct v4l2_modulator *p=arg;
1220 if (!vfd->vidioc_g_modulator)
1222 ret=vfd->vidioc_g_modulator(file, fh, p);
1224 dbgarg(cmd, "index=%d, name=%s, "
1225 "capability=%d, rangelow=%d,"
1226 " rangehigh=%d, txsubchans=%d\n",
1227 p->index, p->name,p->capability,
1228 p->rangelow, p->rangehigh,
1232 case VIDIOC_S_MODULATOR:
1234 struct v4l2_modulator *p=arg;
1235 if (!vfd->vidioc_s_modulator)
1237 dbgarg(cmd, "index=%d, name=%s, capability=%d, "
1238 "rangelow=%d, rangehigh=%d, txsubchans=%d\n",
1239 p->index, p->name,p->capability,p->rangelow,
1240 p->rangehigh,p->txsubchans);
1241 ret=vfd->vidioc_s_modulator(file, fh, p);
1246 struct v4l2_crop *p=arg;
1247 if (!vfd->vidioc_g_crop)
1249 ret=vfd->vidioc_g_crop(file, fh, p);
1251 dbgarg(cmd, "type=%d\n", p->type);
1252 dbgrect(vfd, "", &p->c);
1258 struct v4l2_crop *p=arg;
1259 if (!vfd->vidioc_s_crop)
1261 dbgarg(cmd, "type=%d\n", p->type);
1262 dbgrect(vfd, "", &p->c);
1263 ret=vfd->vidioc_s_crop(file, fh, p);
1266 case VIDIOC_CROPCAP:
1268 struct v4l2_cropcap *p=arg;
1269 /*FIXME: Should also show v4l2_fract pixelaspect */
1270 if (!vfd->vidioc_cropcap)
1272 dbgarg(cmd, "type=%d\n", p->type);
1273 dbgrect(vfd, "bounds ", &p->bounds);
1274 dbgrect(vfd, "defrect ", &p->defrect);
1275 ret=vfd->vidioc_cropcap(file, fh, p);
1278 case VIDIOC_G_MPEGCOMP:
1280 struct v4l2_mpeg_compression *p=arg;
1282 /*FIXME: Several fields not shown */
1283 if (!vfd->vidioc_g_mpegcomp)
1285 ret=vfd->vidioc_g_mpegcomp(file, fh, p);
1287 dbgarg (cmd, "ts_pid_pmt=%d, ts_pid_audio=%d,"
1288 " ts_pid_video=%d, ts_pid_pcr=%d, "
1289 "ps_size=%d, au_sample_rate=%d, "
1290 "au_pesid=%c, vi_frame_rate=%d, "
1291 "vi_frames_per_gop=%d, "
1292 "vi_bframes_count=%d, vi_pesid=%c\n",
1293 p->ts_pid_pmt,p->ts_pid_audio,
1294 p->ts_pid_video,p->ts_pid_pcr,
1295 p->ps_size, p->au_sample_rate,
1296 p->au_pesid, p->vi_frame_rate,
1297 p->vi_frames_per_gop,
1298 p->vi_bframes_count, p->vi_pesid);
1301 case VIDIOC_S_MPEGCOMP:
1303 struct v4l2_mpeg_compression *p=arg;
1304 /*FIXME: Several fields not shown */
1305 if (!vfd->vidioc_s_mpegcomp)
1307 dbgarg (cmd, "ts_pid_pmt=%d, ts_pid_audio=%d, "
1308 "ts_pid_video=%d, ts_pid_pcr=%d, ps_size=%d, "
1309 "au_sample_rate=%d, au_pesid=%c, "
1310 "vi_frame_rate=%d, vi_frames_per_gop=%d, "
1311 "vi_bframes_count=%d, vi_pesid=%c\n",
1312 p->ts_pid_pmt,p->ts_pid_audio, p->ts_pid_video,
1313 p->ts_pid_pcr, p->ps_size, p->au_sample_rate,
1314 p->au_pesid, p->vi_frame_rate,
1315 p->vi_frames_per_gop, p->vi_bframes_count,
1317 ret=vfd->vidioc_s_mpegcomp(file, fh, p);
1320 case VIDIOC_G_JPEGCOMP:
1322 struct v4l2_jpegcompression *p=arg;
1323 if (!vfd->vidioc_g_jpegcomp)
1325 ret=vfd->vidioc_g_jpegcomp(file, fh, p);
1327 dbgarg (cmd, "quality=%d, APPn=%d, "
1328 "APP_len=%d, COM_len=%d, "
1329 "jpeg_markers=%d\n",
1330 p->quality,p->APPn,p->APP_len,
1331 p->COM_len,p->jpeg_markers);
1334 case VIDIOC_S_JPEGCOMP:
1336 struct v4l2_jpegcompression *p=arg;
1337 if (!vfd->vidioc_g_jpegcomp)
1339 dbgarg (cmd, "quality=%d, APPn=%d, APP_len=%d, "
1340 "COM_len=%d, jpeg_markers=%d\n",
1341 p->quality,p->APPn,p->APP_len,
1342 p->COM_len,p->jpeg_markers);
1343 ret=vfd->vidioc_s_jpegcomp(file, fh, p);
1348 struct v4l2_streamparm *p=arg;
1349 if (vfd->vidioc_g_parm) {
1350 ret=vfd->vidioc_g_parm(file, fh, p);
1352 struct v4l2_standard s;
1354 if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1357 v4l2_video_std_construct(&s, vfd->current_norm,
1358 v4l2_norm_to_name(vfd->current_norm));
1360 memset(p,0,sizeof(*p));
1362 p->parm.capture.timeperframe = s.frameperiod;
1366 dbgarg (cmd, "type=%d\n", p->type);
1371 struct v4l2_streamparm *p=arg;
1372 if (!vfd->vidioc_s_parm)
1374 dbgarg (cmd, "type=%d\n", p->type);
1375 ret=vfd->vidioc_s_parm(file, fh, p);
1378 case VIDIOC_G_TUNER:
1380 struct v4l2_tuner *p=arg;
1381 __u32 index=p->index;
1383 if (!vfd->vidioc_g_tuner)
1386 memset(p,0,sizeof(*p));
1389 ret=vfd->vidioc_g_tuner(file, fh, p);
1391 dbgarg (cmd, "index=%d, name=%s, type=%d, "
1392 "capability=%d, rangelow=%d, "
1393 "rangehigh=%d, signal=%d, afc=%d, "
1394 "rxsubchans=%d, audmode=%d\n",
1395 p->index, p->name, p->type,
1396 p->capability, p->rangelow,
1397 p->rangehigh, p->rxsubchans,
1398 p->audmode, p->signal, p->afc);
1401 case VIDIOC_S_TUNER:
1403 struct v4l2_tuner *p=arg;
1404 if (!vfd->vidioc_s_tuner)
1406 dbgarg (cmd, "index=%d, name=%s, type=%d, "
1407 "capability=%d, rangelow=%d, rangehigh=%d, "
1408 "signal=%d, afc=%d, rxsubchans=%d, "
1409 "audmode=%d\n",p->index, p->name, p->type,
1410 p->capability, p->rangelow,p->rangehigh,
1411 p->rxsubchans, p->audmode, p->signal,
1413 ret=vfd->vidioc_s_tuner(file, fh, p);
1416 case VIDIOC_G_FREQUENCY:
1418 struct v4l2_frequency *p=arg;
1419 if (!vfd->vidioc_g_frequency)
1422 memset(p,0,sizeof(*p));
1424 ret=vfd->vidioc_g_frequency(file, fh, p);
1426 dbgarg (cmd, "tuner=%d, type=%d, frequency=%d\n",
1427 p->tuner,p->type,p->frequency);
1430 case VIDIOC_S_FREQUENCY:
1432 struct v4l2_frequency *p=arg;
1433 if (!vfd->vidioc_s_frequency)
1435 dbgarg (cmd, "tuner=%d, type=%d, frequency=%d\n",
1436 p->tuner,p->type,p->frequency);
1437 ret=vfd->vidioc_s_frequency(file, fh, p);
1440 case VIDIOC_G_SLICED_VBI_CAP:
1442 struct v4l2_sliced_vbi_cap *p=arg;
1443 if (!vfd->vidioc_g_sliced_vbi_cap)
1445 ret=vfd->vidioc_g_sliced_vbi_cap(file, fh, p);
1447 dbgarg (cmd, "service_set=%d\n", p->service_set);
1450 case VIDIOC_LOG_STATUS:
1452 if (!vfd->vidioc_log_status)
1454 ret=vfd->vidioc_log_status(file, fh);
1459 if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) {
1461 printk ("%s: err:\n", vfd->name);
1462 v4l_print_ioctl(vfd->name, cmd);
1469 int video_ioctl2 (struct inode *inode, struct file *file,
1470 unsigned int cmd, unsigned long arg)
1477 size_t ctrls_size = 0;
1478 void __user *user_ptr = NULL;
1480 #ifdef __OLD_VIDIOC_
1481 cmd = video_fix_command(cmd);
1483 is_ext_ctrl = (cmd == VIDIOC_S_EXT_CTRLS || cmd == VIDIOC_G_EXT_CTRLS ||
1484 cmd == VIDIOC_TRY_EXT_CTRLS);
1486 /* Copy arguments into temp kernel buffer */
1487 switch (_IOC_DIR(cmd)) {
1493 case (_IOC_WRITE | _IOC_READ):
1494 if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
1497 /* too big to allocate from stack */
1498 mbuf = kmalloc(_IOC_SIZE(cmd),GFP_KERNEL);
1505 if (_IOC_DIR(cmd) & _IOC_WRITE)
1506 if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd)))
1512 struct v4l2_ext_controls *p = parg;
1514 /* In case of an error, tell the caller that it wasn't
1515 a specific control that caused it. */
1516 p->error_idx = p->count;
1517 user_ptr = (void __user *)p->controls;
1519 ctrls_size = sizeof(struct v4l2_ext_control) * p->count;
1520 /* Note: v4l2_ext_controls fits in sbuf[] so mbuf is still NULL. */
1521 mbuf = kmalloc(ctrls_size, GFP_KERNEL);
1526 if (copy_from_user(mbuf, user_ptr, ctrls_size))
1533 err = __video_do_ioctl(inode, file, cmd, parg);
1534 if (err == -ENOIOCTLCMD)
1537 struct v4l2_ext_controls *p = parg;
1539 p->controls = (void *)user_ptr;
1540 if (p->count && err == 0 && copy_to_user(user_ptr, mbuf, ctrls_size))
1548 /* Copy results into user buffer */
1549 switch (_IOC_DIR(cmd))
1552 case (_IOC_WRITE | _IOC_READ):
1553 if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd)))
1564 static struct file_operations video_fops;
1567 * video_register_device - register video4linux devices
1568 * @vfd: video device structure we want to register
1569 * @type: type of device to register
1570 * @nr: which device number (0 == /dev/video0, 1 == /dev/video1, ...
1573 * The registration code assigns minor numbers based on the type
1574 * requested. -ENFILE is returned in all the device slots for this
1575 * category are full. If not then the minor field is set and the
1576 * driver initialize function is called (if non %NULL).
1578 * Zero is returned on success.
1582 * %VFL_TYPE_GRABBER - A frame grabber
1584 * %VFL_TYPE_VTX - A teletext device
1586 * %VFL_TYPE_VBI - Vertical blank data (undecoded)
1588 * %VFL_TYPE_RADIO - A radio card
1591 int video_register_device(struct video_device *vfd, int type, int nr)
1601 case VFL_TYPE_GRABBER:
1602 base=MINOR_VFL_TYPE_GRABBER_MIN;
1603 end=MINOR_VFL_TYPE_GRABBER_MAX+1;
1604 name_base = "video";
1607 base=MINOR_VFL_TYPE_VTX_MIN;
1608 end=MINOR_VFL_TYPE_VTX_MAX+1;
1612 base=MINOR_VFL_TYPE_VBI_MIN;
1613 end=MINOR_VFL_TYPE_VBI_MAX+1;
1616 case VFL_TYPE_RADIO:
1617 base=MINOR_VFL_TYPE_RADIO_MIN;
1618 end=MINOR_VFL_TYPE_RADIO_MAX+1;
1619 name_base = "radio";
1622 printk(KERN_ERR "%s called with unknown type: %d\n",
1623 __FUNCTION__, type);
1627 /* pick a minor number */
1628 mutex_lock(&videodev_lock);
1629 if (nr >= 0 && nr < end-base) {
1630 /* use the one the driver asked for */
1632 if (NULL != video_device[i]) {
1633 mutex_unlock(&videodev_lock);
1637 /* use first free */
1638 for(i=base;i<end;i++)
1639 if (NULL == video_device[i])
1642 mutex_unlock(&videodev_lock);
1646 video_device[i]=vfd;
1648 mutex_unlock(&videodev_lock);
1649 mutex_init(&vfd->lock);
1652 memset(&vfd->class_dev, 0x00, sizeof(vfd->class_dev));
1654 vfd->class_dev.dev = vfd->dev;
1655 vfd->class_dev.class = &video_class;
1656 vfd->class_dev.devt = MKDEV(VIDEO_MAJOR, vfd->minor);
1657 sprintf(vfd->class_dev.class_id, "%s%d", name_base, i - base);
1658 ret = class_device_register(&vfd->class_dev);
1660 printk(KERN_ERR "%s: class_device_register failed\n",
1664 ret = class_device_create_file(&vfd->class_dev, &class_device_attr_name);
1666 printk(KERN_ERR "%s: class_device_create_file 'name' failed\n",
1672 /* needed until all drivers are fixed */
1674 printk(KERN_WARNING "videodev: \"%s\" has no release callback. "
1675 "Please fix your driver for proper sysfs support, see "
1676 "http://lwn.net/Articles/36850/\n", vfd->name);
1681 class_device_unregister(&vfd->class_dev);
1683 mutex_lock(&videodev_lock);
1684 video_device[vfd->minor] = NULL;
1686 mutex_unlock(&videodev_lock);
1691 * video_unregister_device - unregister a video4linux device
1692 * @vfd: the device to unregister
1694 * This unregisters the passed device and deassigns the minor
1695 * number. Future open calls will be met with errors.
1698 void video_unregister_device(struct video_device *vfd)
1700 mutex_lock(&videodev_lock);
1701 if(video_device[vfd->minor]!=vfd)
1702 panic("videodev: bad unregister");
1704 video_device[vfd->minor]=NULL;
1705 class_device_unregister(&vfd->class_dev);
1706 mutex_unlock(&videodev_lock);
1710 * Video fs operations
1712 static struct file_operations video_fops=
1714 .owner = THIS_MODULE,
1715 .llseek = no_llseek,
1720 * Initialise video for linux
1723 static int __init videodev_init(void)
1727 printk(KERN_INFO "Linux video capture interface: v2.00\n");
1728 if (register_chrdev(VIDEO_MAJOR, VIDEO_NAME, &video_fops)) {
1729 printk(KERN_WARNING "video_dev: unable to get major %d\n", VIDEO_MAJOR);
1733 ret = class_register(&video_class);
1735 unregister_chrdev(VIDEO_MAJOR, VIDEO_NAME);
1736 printk(KERN_WARNING "video_dev: class_register failed\n");
1743 static void __exit videodev_exit(void)
1745 class_unregister(&video_class);
1746 unregister_chrdev(VIDEO_MAJOR, VIDEO_NAME);
1749 module_init(videodev_init)
1750 module_exit(videodev_exit)
1752 EXPORT_SYMBOL(video_register_device);
1753 EXPORT_SYMBOL(video_unregister_device);
1754 EXPORT_SYMBOL(video_devdata);
1755 EXPORT_SYMBOL(video_usercopy);
1756 EXPORT_SYMBOL(video_exclusive_open);
1757 EXPORT_SYMBOL(video_exclusive_release);
1758 EXPORT_SYMBOL(video_ioctl2);
1759 EXPORT_SYMBOL(video_device_alloc);
1760 EXPORT_SYMBOL(video_device_release);
1762 MODULE_AUTHOR("Alan Cox, Mauro Carvalho Chehab <mchehab@infradead.org>");
1763 MODULE_DESCRIPTION("Device registrar for Video4Linux drivers v2");
1764 MODULE_LICENSE("GPL");