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/smp_lock.h>
35 #include <linux/string.h>
36 #include <linux/errno.h>
37 #include <linux/init.h>
38 #include <linux/kmod.h>
39 #include <linux/slab.h>
40 #include <asm/uaccess.h>
41 #include <asm/system.h>
43 #define __OLD_VIDIOC_ /* To allow fixing old calls*/
44 #include <linux/videodev2.h>
46 #ifdef CONFIG_VIDEO_V4L1
47 #include <linux/videodev.h>
49 #include <media/v4l2-common.h>
51 #define VIDEO_NUM_DEVICES 256
52 #define VIDEO_NAME "video4linux"
58 static ssize_t show_name(struct class_device *cd, char *buf)
60 struct video_device *vfd = container_of(cd, struct video_device,
62 return sprintf(buf,"%.*s\n",(int)sizeof(vfd->name),vfd->name);
65 static CLASS_DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
67 struct video_device *video_device_alloc(void)
69 struct video_device *vfd;
71 vfd = kzalloc(sizeof(*vfd),GFP_KERNEL);
75 void video_device_release(struct video_device *vfd)
80 static void video_release(struct class_device *cd)
82 struct video_device *vfd = container_of(cd, struct video_device,
86 /* needed until all drivers are fixed */
93 static struct class video_class = {
95 .release = video_release,
102 static struct video_device *video_device[VIDEO_NUM_DEVICES];
103 static DEFINE_MUTEX(videodev_lock);
105 struct video_device* video_devdata(struct file *file)
107 return video_device[iminor(file->f_path.dentry->d_inode)];
111 * Open a video device - FIXME: Obsoleted
113 static int video_open(struct inode *inode, struct file *file)
115 unsigned int minor = iminor(inode);
117 struct video_device *vfl;
118 const struct file_operations *old_fops;
120 if(minor>=VIDEO_NUM_DEVICES)
122 mutex_lock(&videodev_lock);
123 vfl=video_device[minor];
125 mutex_unlock(&videodev_lock);
126 request_module("char-major-%d-%d", VIDEO_MAJOR, minor);
127 mutex_lock(&videodev_lock);
128 vfl=video_device[minor];
130 mutex_unlock(&videodev_lock);
134 old_fops = file->f_op;
135 file->f_op = fops_get(vfl->fops);
137 err = file->f_op->open(inode,file);
139 fops_put(file->f_op);
140 file->f_op = fops_get(old_fops);
143 mutex_unlock(&videodev_lock);
148 * helper function -- handles userspace copying for ioctl arguments
153 video_fix_command(unsigned int cmd)
156 case VIDIOC_OVERLAY_OLD:
157 cmd = VIDIOC_OVERLAY;
159 case VIDIOC_S_PARM_OLD:
162 case VIDIOC_S_CTRL_OLD:
165 case VIDIOC_G_AUDIO_OLD:
166 cmd = VIDIOC_G_AUDIO;
168 case VIDIOC_G_AUDOUT_OLD:
169 cmd = VIDIOC_G_AUDOUT;
171 case VIDIOC_CROPCAP_OLD:
172 cmd = VIDIOC_CROPCAP;
180 * Obsolete usercopy function - Should be removed soon
183 video_usercopy(struct inode *inode, struct file *file,
184 unsigned int cmd, unsigned long arg,
185 int (*func)(struct inode *inode, struct file *file,
186 unsigned int cmd, void *arg))
193 size_t ctrls_size = 0;
194 void __user *user_ptr = NULL;
197 cmd = video_fix_command(cmd);
199 is_ext_ctrl = (cmd == VIDIOC_S_EXT_CTRLS || cmd == VIDIOC_G_EXT_CTRLS ||
200 cmd == VIDIOC_TRY_EXT_CTRLS);
202 /* Copy arguments into temp kernel buffer */
203 switch (_IOC_DIR(cmd)) {
209 case (_IOC_WRITE | _IOC_READ):
210 if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
213 /* too big to allocate from stack */
214 mbuf = kmalloc(_IOC_SIZE(cmd),GFP_KERNEL);
221 if (_IOC_DIR(cmd) & _IOC_WRITE)
222 if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd)))
227 struct v4l2_ext_controls *p = parg;
229 /* In case of an error, tell the caller that it wasn't
230 a specific control that caused it. */
231 p->error_idx = p->count;
232 user_ptr = (void __user *)p->controls;
234 ctrls_size = sizeof(struct v4l2_ext_control) * p->count;
235 /* Note: v4l2_ext_controls fits in sbuf[] so mbuf is still NULL. */
236 mbuf = kmalloc(ctrls_size, GFP_KERNEL);
241 if (copy_from_user(mbuf, user_ptr, ctrls_size))
248 err = func(inode, file, cmd, parg);
249 if (err == -ENOIOCTLCMD)
252 struct v4l2_ext_controls *p = parg;
254 p->controls = (void *)user_ptr;
255 if (p->count && err == 0 && copy_to_user(user_ptr, mbuf, ctrls_size))
263 /* Copy results into user buffer */
264 switch (_IOC_DIR(cmd))
267 case (_IOC_WRITE | _IOC_READ):
268 if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd)))
279 * open/release helper functions -- handle exclusive opens
280 * Should be removed soon
282 int video_exclusive_open(struct inode *inode, struct file *file)
284 struct video_device *vfl = video_devdata(file);
287 mutex_lock(&vfl->lock);
293 mutex_unlock(&vfl->lock);
297 int video_exclusive_release(struct inode *inode, struct file *file)
299 struct video_device *vfl = video_devdata(file);
305 static char *v4l2_memory_names[] = {
306 [V4L2_MEMORY_MMAP] = "mmap",
307 [V4L2_MEMORY_USERPTR] = "userptr",
308 [V4L2_MEMORY_OVERLAY] = "overlay",
312 /* FIXME: Those stuff are replicated also on v4l2-common.c */
313 static char *v4l2_type_names_FIXME[] = {
314 [V4L2_BUF_TYPE_VIDEO_CAPTURE] = "video-cap",
315 [V4L2_BUF_TYPE_VIDEO_OVERLAY] = "video-over",
316 [V4L2_BUF_TYPE_VIDEO_OUTPUT] = "video-out",
317 [V4L2_BUF_TYPE_VBI_CAPTURE] = "vbi-cap",
318 [V4L2_BUF_TYPE_VBI_OUTPUT] = "vbi-out",
319 [V4L2_BUF_TYPE_SLICED_VBI_OUTPUT] = "sliced-vbi-out",
320 [V4L2_BUF_TYPE_SLICED_VBI_CAPTURE] = "sliced-vbi-capture",
321 [V4L2_BUF_TYPE_PRIVATE] = "private",
324 static char *v4l2_field_names_FIXME[] = {
325 [V4L2_FIELD_ANY] = "any",
326 [V4L2_FIELD_NONE] = "none",
327 [V4L2_FIELD_TOP] = "top",
328 [V4L2_FIELD_BOTTOM] = "bottom",
329 [V4L2_FIELD_INTERLACED] = "interlaced",
330 [V4L2_FIELD_SEQ_TB] = "seq-tb",
331 [V4L2_FIELD_SEQ_BT] = "seq-bt",
332 [V4L2_FIELD_ALTERNATE] = "alternate",
335 #define prt_names(a,arr) (((a)>=0)&&((a)<ARRAY_SIZE(arr)))?arr[a]:"unknown"
337 static void dbgbuf(unsigned int cmd, struct video_device *vfd,
338 struct v4l2_buffer *p)
340 struct v4l2_timecode *tc=&p->timecode;
342 dbgarg (cmd, "%02ld:%02d:%02d.%08ld index=%d, type=%s, "
343 "bytesused=%d, flags=0x%08d, "
344 "field=%0d, sequence=%d, memory=%s, offset/userptr=0x%08lx, length=%d\n",
345 (p->timestamp.tv_sec/3600),
346 (int)(p->timestamp.tv_sec/60)%60,
347 (int)(p->timestamp.tv_sec%60),
348 p->timestamp.tv_usec,
350 prt_names(p->type,v4l2_type_names_FIXME),
351 p->bytesused,p->flags,
352 p->field,p->sequence,
353 prt_names(p->memory,v4l2_memory_names),
354 p->m.userptr, p->length);
355 dbgarg2 ("timecode= %02d:%02d:%02d type=%d, "
356 "flags=0x%08d, frames=%d, userbits=0x%08x\n",
357 tc->hours,tc->minutes,tc->seconds,
358 tc->type, tc->flags, tc->frames, *(__u32 *) tc->userbits);
361 static inline void dbgrect(struct video_device *vfd, char *s,
364 dbgarg2 ("%sRect start at %dx%d, size= %dx%d\n", s, r->left, r->top,
365 r->width, r->height);
368 static inline void v4l_print_pix_fmt (struct video_device *vfd,
369 struct v4l2_pix_format *fmt)
371 dbgarg2 ("width=%d, height=%d, format=%c%c%c%c, field=%s, "
372 "bytesperline=%d sizeimage=%d, colorspace=%d\n",
373 fmt->width,fmt->height,
374 (fmt->pixelformat & 0xff),
375 (fmt->pixelformat >> 8) & 0xff,
376 (fmt->pixelformat >> 16) & 0xff,
377 (fmt->pixelformat >> 24) & 0xff,
378 prt_names(fmt->field,v4l2_field_names_FIXME),
379 fmt->bytesperline,fmt->sizeimage,fmt->colorspace);
383 static int check_fmt (struct video_device *vfd, enum v4l2_buf_type type)
386 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
387 if (vfd->vidioc_try_fmt_cap)
390 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
391 if (vfd->vidioc_try_fmt_overlay)
394 case V4L2_BUF_TYPE_VBI_CAPTURE:
395 if (vfd->vidioc_try_fmt_vbi)
398 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
399 if (vfd->vidioc_try_fmt_vbi_output)
402 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
403 if (vfd->vidioc_try_fmt_vbi_capture)
406 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
407 if (vfd->vidioc_try_fmt_video_output)
410 case V4L2_BUF_TYPE_VBI_OUTPUT:
411 if (vfd->vidioc_try_fmt_vbi_output)
414 case V4L2_BUF_TYPE_PRIVATE:
415 if (vfd->vidioc_try_fmt_type_private)
422 static int __video_do_ioctl(struct inode *inode, struct file *file,
423 unsigned int cmd, void *arg)
425 struct video_device *vfd = video_devdata(file);
426 void *fh = file->private_data;
429 if ( (vfd->debug & V4L2_DEBUG_IOCTL) &&
430 !(vfd->debug | V4L2_DEBUG_IOCTL_ARG)) {
431 v4l_print_ioctl(vfd->name, cmd);
434 if (_IOC_TYPE(cmd)=='v')
435 return v4l_compat_translate_ioctl(inode,file,cmd,arg,
439 /* --- capabilities ------------------------------------------ */
440 case VIDIOC_QUERYCAP:
442 struct v4l2_capability *cap = (struct v4l2_capability*)arg;
443 memset(cap, 0, sizeof(*cap));
445 if (!vfd->vidioc_querycap)
448 ret=vfd->vidioc_querycap(file, fh, cap);
450 dbgarg (cmd, "driver=%s, card=%s, bus=%s, "
452 "capabilities=0x%08x\n",
453 cap->driver,cap->card,cap->bus_info,
459 /* --- priority ------------------------------------------ */
460 case VIDIOC_G_PRIORITY:
462 enum v4l2_priority *p=arg;
464 if (!vfd->vidioc_g_priority)
466 ret=vfd->vidioc_g_priority(file, fh, p);
468 dbgarg(cmd, "priority is %d\n", *p);
471 case VIDIOC_S_PRIORITY:
473 enum v4l2_priority *p=arg;
475 if (!vfd->vidioc_s_priority)
477 dbgarg(cmd, "setting priority to %d\n", *p);
478 ret=vfd->vidioc_s_priority(file, fh, *p);
482 /* --- capture ioctls ---------------------------------------- */
483 case VIDIOC_ENUM_FMT:
485 struct v4l2_fmtdesc *f = arg;
486 enum v4l2_buf_type type;
491 memset(f,0,sizeof(*f));
496 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
497 if (vfd->vidioc_enum_fmt_cap)
498 ret=vfd->vidioc_enum_fmt_cap(file, fh, f);
500 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
501 if (vfd->vidioc_enum_fmt_overlay)
502 ret=vfd->vidioc_enum_fmt_overlay(file, fh, f);
504 case V4L2_BUF_TYPE_VBI_CAPTURE:
505 if (vfd->vidioc_enum_fmt_vbi)
506 ret=vfd->vidioc_enum_fmt_vbi(file, fh, f);
508 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
509 if (vfd->vidioc_enum_fmt_vbi_output)
510 ret=vfd->vidioc_enum_fmt_vbi_output(file,
513 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
514 if (vfd->vidioc_enum_fmt_vbi_capture)
515 ret=vfd->vidioc_enum_fmt_vbi_capture(file,
518 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
519 if (vfd->vidioc_enum_fmt_video_output)
520 ret=vfd->vidioc_enum_fmt_video_output(file,
523 case V4L2_BUF_TYPE_VBI_OUTPUT:
524 if (vfd->vidioc_enum_fmt_vbi_output)
525 ret=vfd->vidioc_enum_fmt_vbi_output(file,
528 case V4L2_BUF_TYPE_PRIVATE:
529 if (vfd->vidioc_enum_fmt_type_private)
530 ret=vfd->vidioc_enum_fmt_type_private(file,
535 dbgarg (cmd, "index=%d, type=%d, flags=%d, "
536 "pixelformat=%c%c%c%c, description='%s'\n",
537 f->index, f->type, f->flags,
538 (f->pixelformat & 0xff),
539 (f->pixelformat >> 8) & 0xff,
540 (f->pixelformat >> 16) & 0xff,
541 (f->pixelformat >> 24) & 0xff,
547 struct v4l2_format *f = (struct v4l2_format *)arg;
548 enum v4l2_buf_type type=f->type;
550 memset(&f->fmt.pix,0,sizeof(f->fmt.pix));
553 /* FIXME: Should be one dump per type */
554 dbgarg (cmd, "type=%s\n", prt_names(type,
555 v4l2_type_names_FIXME));
558 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
559 if (vfd->vidioc_g_fmt_cap)
560 ret=vfd->vidioc_g_fmt_cap(file, fh, f);
562 v4l_print_pix_fmt(vfd,&f->fmt.pix);
564 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
565 if (vfd->vidioc_g_fmt_overlay)
566 ret=vfd->vidioc_g_fmt_overlay(file, fh, f);
568 case V4L2_BUF_TYPE_VBI_CAPTURE:
569 if (vfd->vidioc_g_fmt_vbi)
570 ret=vfd->vidioc_g_fmt_vbi(file, fh, f);
572 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
573 if (vfd->vidioc_g_fmt_vbi_output)
574 ret=vfd->vidioc_g_fmt_vbi_output(file, fh, f);
576 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
577 if (vfd->vidioc_g_fmt_vbi_capture)
578 ret=vfd->vidioc_g_fmt_vbi_capture(file, fh, f);
580 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
581 if (vfd->vidioc_g_fmt_video_output)
582 ret=vfd->vidioc_g_fmt_video_output(file,
585 case V4L2_BUF_TYPE_VBI_OUTPUT:
586 if (vfd->vidioc_g_fmt_vbi_output)
587 ret=vfd->vidioc_g_fmt_vbi_output(file, fh, f);
589 case V4L2_BUF_TYPE_PRIVATE:
590 if (vfd->vidioc_g_fmt_type_private)
591 ret=vfd->vidioc_g_fmt_type_private(file,
600 struct v4l2_format *f = (struct v4l2_format *)arg;
602 /* FIXME: Should be one dump per type */
603 dbgarg (cmd, "type=%s\n", prt_names(f->type,
604 v4l2_type_names_FIXME));
607 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
608 v4l_print_pix_fmt(vfd,&f->fmt.pix);
609 if (vfd->vidioc_s_fmt_cap)
610 ret=vfd->vidioc_s_fmt_cap(file, fh, f);
612 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
613 if (vfd->vidioc_s_fmt_overlay)
614 ret=vfd->vidioc_s_fmt_overlay(file, fh, f);
616 case V4L2_BUF_TYPE_VBI_CAPTURE:
617 if (vfd->vidioc_s_fmt_vbi)
618 ret=vfd->vidioc_s_fmt_vbi(file, fh, f);
620 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
621 if (vfd->vidioc_s_fmt_vbi_output)
622 ret=vfd->vidioc_s_fmt_vbi_output(file, fh, f);
624 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
625 if (vfd->vidioc_s_fmt_vbi_capture)
626 ret=vfd->vidioc_s_fmt_vbi_capture(file, fh, f);
628 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
629 if (vfd->vidioc_s_fmt_video_output)
630 ret=vfd->vidioc_s_fmt_video_output(file,
633 case V4L2_BUF_TYPE_VBI_OUTPUT:
634 if (vfd->vidioc_s_fmt_vbi_output)
635 ret=vfd->vidioc_s_fmt_vbi_output(file,
638 case V4L2_BUF_TYPE_PRIVATE:
639 if (vfd->vidioc_s_fmt_type_private)
640 ret=vfd->vidioc_s_fmt_type_private(file,
648 struct v4l2_format *f = (struct v4l2_format *)arg;
650 /* FIXME: Should be one dump per type */
651 dbgarg (cmd, "type=%s\n", prt_names(f->type,
652 v4l2_type_names_FIXME));
654 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
655 if (vfd->vidioc_try_fmt_cap)
656 ret=vfd->vidioc_try_fmt_cap(file, fh, f);
658 v4l_print_pix_fmt(vfd,&f->fmt.pix);
660 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
661 if (vfd->vidioc_try_fmt_overlay)
662 ret=vfd->vidioc_try_fmt_overlay(file, fh, f);
664 case V4L2_BUF_TYPE_VBI_CAPTURE:
665 if (vfd->vidioc_try_fmt_vbi)
666 ret=vfd->vidioc_try_fmt_vbi(file, fh, f);
668 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
669 if (vfd->vidioc_try_fmt_vbi_output)
670 ret=vfd->vidioc_try_fmt_vbi_output(file,
673 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
674 if (vfd->vidioc_try_fmt_vbi_capture)
675 ret=vfd->vidioc_try_fmt_vbi_capture(file,
678 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
679 if (vfd->vidioc_try_fmt_video_output)
680 ret=vfd->vidioc_try_fmt_video_output(file,
683 case V4L2_BUF_TYPE_VBI_OUTPUT:
684 if (vfd->vidioc_try_fmt_vbi_output)
685 ret=vfd->vidioc_try_fmt_vbi_output(file,
688 case V4L2_BUF_TYPE_PRIVATE:
689 if (vfd->vidioc_try_fmt_type_private)
690 ret=vfd->vidioc_try_fmt_type_private(file,
697 /* FIXME: Those buf reqs could be handled here,
698 with some changes on videobuf to allow its header to be included at
699 videodev2.h or being merged at videodev2.
703 struct v4l2_requestbuffers *p=arg;
705 if (!vfd->vidioc_reqbufs)
707 ret = check_fmt (vfd, p->type);
711 ret=vfd->vidioc_reqbufs(file, fh, p);
712 dbgarg (cmd, "count=%d, type=%s, memory=%s\n",
714 prt_names(p->type,v4l2_type_names_FIXME),
715 prt_names(p->memory,v4l2_memory_names));
718 case VIDIOC_QUERYBUF:
720 struct v4l2_buffer *p=arg;
722 if (!vfd->vidioc_querybuf)
724 ret = check_fmt (vfd, p->type);
728 ret=vfd->vidioc_querybuf(file, fh, p);
735 struct v4l2_buffer *p=arg;
737 if (!vfd->vidioc_qbuf)
739 ret = check_fmt (vfd, p->type);
743 ret=vfd->vidioc_qbuf(file, fh, p);
750 struct v4l2_buffer *p=arg;
751 if (!vfd->vidioc_dqbuf)
753 ret = check_fmt (vfd, p->type);
757 ret=vfd->vidioc_dqbuf(file, fh, p);
766 if (!vfd->vidioc_overlay)
768 dbgarg (cmd, "value=%d\n",*i);
769 ret=vfd->vidioc_overlay(file, fh, *i);
772 #ifdef CONFIG_VIDEO_V4L1_COMPAT
773 /* --- streaming capture ------------------------------------- */
776 struct video_mbuf *p=arg;
778 memset(p,0,sizeof(p));
780 if (!vfd->vidiocgmbuf)
782 ret=vfd->vidiocgmbuf(file, fh, p);
784 dbgarg (cmd, "size=%d, frames=%d, offsets=0x%08lx\n",
786 (unsigned long)p->offsets);
792 struct v4l2_framebuffer *p=arg;
793 if (!vfd->vidioc_g_fbuf)
795 ret=vfd->vidioc_g_fbuf(file, fh, arg);
797 dbgarg (cmd, "capability=%d, flags=%d, base=0x%08lx\n",
798 p->capability,p->flags,
799 (unsigned long)p->base);
800 v4l_print_pix_fmt (vfd, &p->fmt);
806 struct v4l2_framebuffer *p=arg;
807 if (!vfd->vidioc_s_fbuf)
810 dbgarg (cmd, "capability=%d, flags=%d, base=0x%08lx\n",
811 p->capability,p->flags,(unsigned long)p->base);
812 v4l_print_pix_fmt (vfd, &p->fmt);
813 ret=vfd->vidioc_s_fbuf(file, fh, arg);
817 case VIDIOC_STREAMON:
819 enum v4l2_buf_type i = *(int *)arg;
820 if (!vfd->vidioc_streamon)
822 dbgarg (cmd, "type=%s\n", prt_names(i,v4l2_type_names_FIXME));
823 ret=vfd->vidioc_streamon(file, fh,i);
826 case VIDIOC_STREAMOFF:
828 enum v4l2_buf_type i = *(int *)arg;
830 if (!vfd->vidioc_streamoff)
832 dbgarg (cmd, "type=%s\n", prt_names(i,v4l2_type_names_FIXME));
833 ret=vfd->vidioc_streamoff(file, fh, i);
836 /* ---------- tv norms ---------- */
839 struct v4l2_standard *p = arg;
840 v4l2_std_id id = vfd->tvnorms,curr_id=0;
841 unsigned int index = p->index,i;
848 /* Return norm array on a canonical way */
849 for (i=0;i<= index && id; i++) {
850 if ( (id & V4L2_STD_PAL) == V4L2_STD_PAL) {
851 curr_id = V4L2_STD_PAL;
852 } else if ( (id & V4L2_STD_PAL_BG) == V4L2_STD_PAL_BG) {
853 curr_id = V4L2_STD_PAL_BG;
854 } else if ( (id & V4L2_STD_PAL_DK) == V4L2_STD_PAL_DK) {
855 curr_id = V4L2_STD_PAL_DK;
856 } else if ( (id & V4L2_STD_PAL_B) == V4L2_STD_PAL_B) {
857 curr_id = V4L2_STD_PAL_B;
858 } else if ( (id & V4L2_STD_PAL_B1) == V4L2_STD_PAL_B1) {
859 curr_id = V4L2_STD_PAL_B1;
860 } else if ( (id & V4L2_STD_PAL_G) == V4L2_STD_PAL_G) {
861 curr_id = V4L2_STD_PAL_G;
862 } else if ( (id & V4L2_STD_PAL_H) == V4L2_STD_PAL_H) {
863 curr_id = V4L2_STD_PAL_H;
864 } else if ( (id & V4L2_STD_PAL_I) == V4L2_STD_PAL_I) {
865 curr_id = V4L2_STD_PAL_I;
866 } else if ( (id & V4L2_STD_PAL_D) == V4L2_STD_PAL_D) {
867 curr_id = V4L2_STD_PAL_D;
868 } else if ( (id & V4L2_STD_PAL_D1) == V4L2_STD_PAL_D1) {
869 curr_id = V4L2_STD_PAL_D1;
870 } else if ( (id & V4L2_STD_PAL_K) == V4L2_STD_PAL_K) {
871 curr_id = V4L2_STD_PAL_K;
872 } else if ( (id & V4L2_STD_PAL_M) == V4L2_STD_PAL_M) {
873 curr_id = V4L2_STD_PAL_M;
874 } else if ( (id & V4L2_STD_PAL_N) == V4L2_STD_PAL_N) {
875 curr_id = V4L2_STD_PAL_N;
876 } else if ( (id & V4L2_STD_PAL_Nc) == V4L2_STD_PAL_Nc) {
877 curr_id = V4L2_STD_PAL_Nc;
878 } else if ( (id & V4L2_STD_PAL_60) == V4L2_STD_PAL_60) {
879 curr_id = V4L2_STD_PAL_60;
880 } else if ( (id & V4L2_STD_NTSC) == V4L2_STD_NTSC) {
881 curr_id = V4L2_STD_NTSC;
882 } else if ( (id & V4L2_STD_NTSC_M) == V4L2_STD_NTSC_M) {
883 curr_id = V4L2_STD_NTSC_M;
884 } else if ( (id & V4L2_STD_NTSC_M_JP) == V4L2_STD_NTSC_M_JP) {
885 curr_id = V4L2_STD_NTSC_M_JP;
886 } else if ( (id & V4L2_STD_NTSC_443) == V4L2_STD_NTSC_443) {
887 curr_id = V4L2_STD_NTSC_443;
888 } else if ( (id & V4L2_STD_NTSC_M_KR) == V4L2_STD_NTSC_M_KR) {
889 curr_id = V4L2_STD_NTSC_M_KR;
890 } else if ( (id & V4L2_STD_SECAM) == V4L2_STD_SECAM) {
891 curr_id = V4L2_STD_SECAM;
892 } else if ( (id & V4L2_STD_SECAM_DK) == V4L2_STD_SECAM_DK) {
893 curr_id = V4L2_STD_SECAM_DK;
894 } else if ( (id & V4L2_STD_SECAM_B) == V4L2_STD_SECAM_B) {
895 curr_id = V4L2_STD_SECAM_B;
896 } else if ( (id & V4L2_STD_SECAM_D) == V4L2_STD_SECAM_D) {
897 curr_id = V4L2_STD_SECAM_D;
898 } else if ( (id & V4L2_STD_SECAM_G) == V4L2_STD_SECAM_G) {
899 curr_id = V4L2_STD_SECAM_G;
900 } else if ( (id & V4L2_STD_SECAM_H) == V4L2_STD_SECAM_H) {
901 curr_id = V4L2_STD_SECAM_H;
902 } else if ( (id & V4L2_STD_SECAM_K) == V4L2_STD_SECAM_K) {
903 curr_id = V4L2_STD_SECAM_K;
904 } else if ( (id & V4L2_STD_SECAM_K1) == V4L2_STD_SECAM_K1) {
905 curr_id = V4L2_STD_SECAM_K1;
906 } else if ( (id & V4L2_STD_SECAM_L) == V4L2_STD_SECAM_L) {
907 curr_id = V4L2_STD_SECAM_L;
908 } else if ( (id & V4L2_STD_SECAM_LC) == V4L2_STD_SECAM_LC) {
909 curr_id = V4L2_STD_SECAM_LC;
918 v4l2_video_std_construct(p, curr_id,v4l2_norm_to_name(curr_id));
921 dbgarg (cmd, "index=%d, id=%Ld, name=%s, fps=%d/%d, "
922 "framelines=%d\n", p->index,
923 (unsigned long long)p->id, p->name,
924 p->frameperiod.numerator,
925 p->frameperiod.denominator,
933 v4l2_std_id *id = arg;
935 *id = vfd->current_norm;
937 dbgarg (cmd, "value=%Lu\n", (long long unsigned) *id);
944 v4l2_std_id *id = arg,norm;
946 dbgarg (cmd, "value=%Lu\n", (long long unsigned) *id);
948 norm = (*id) & vfd->tvnorms;
949 if ( vfd->tvnorms && !norm) /* Check if std is supported */
952 /* Calls the specific handler */
953 if (vfd->vidioc_s_std)
954 ret=vfd->vidioc_s_std(file, fh, &norm);
958 /* Updates standard information */
960 vfd->current_norm=norm;
964 case VIDIOC_QUERYSTD:
968 if (!vfd->vidioc_querystd)
970 ret=vfd->vidioc_querystd(file, fh, arg);
972 dbgarg (cmd, "detected std=%Lu\n",
973 (unsigned long long)*p);
976 /* ------ input switching ---------- */
977 /* FIXME: Inputs can be handled inside videodev2 */
978 case VIDIOC_ENUMINPUT:
980 struct v4l2_input *p=arg;
983 if (!vfd->vidioc_enum_input)
985 memset(p, 0, sizeof(*p));
988 ret=vfd->vidioc_enum_input(file, fh, p);
990 dbgarg (cmd, "index=%d, name=%s, type=%d, "
992 "tuner=%d, std=%Ld, status=%d\n",
993 p->index,p->name,p->type,p->audioset,
995 (unsigned long long)p->std,
1001 unsigned int *i = arg;
1003 if (!vfd->vidioc_g_input)
1005 ret=vfd->vidioc_g_input(file, fh, i);
1007 dbgarg (cmd, "value=%d\n",*i);
1010 case VIDIOC_S_INPUT:
1012 unsigned int *i = arg;
1014 if (!vfd->vidioc_s_input)
1016 dbgarg (cmd, "value=%d\n",*i);
1017 ret=vfd->vidioc_s_input(file, fh, *i);
1021 /* ------ output switching ---------- */
1022 case VIDIOC_G_OUTPUT:
1024 unsigned int *i = arg;
1026 if (!vfd->vidioc_g_output)
1028 ret=vfd->vidioc_g_output(file, fh, i);
1030 dbgarg (cmd, "value=%d\n",*i);
1033 case VIDIOC_S_OUTPUT:
1035 unsigned int *i = arg;
1037 if (!vfd->vidioc_s_output)
1039 dbgarg (cmd, "value=%d\n",*i);
1040 ret=vfd->vidioc_s_output(file, fh, *i);
1044 /* --- controls ---------------------------------------------- */
1045 case VIDIOC_QUERYCTRL:
1047 struct v4l2_queryctrl *p=arg;
1049 if (!vfd->vidioc_queryctrl)
1051 ret=vfd->vidioc_queryctrl(file, fh, p);
1054 dbgarg (cmd, "id=%d, type=%d, name=%s, "
1056 " step=%d, default=%d, flags=0x%08x\n",
1057 p->id,p->type,p->name,p->minimum,
1058 p->maximum,p->step,p->default_value,
1064 struct v4l2_control *p = arg;
1066 if (!vfd->vidioc_g_ctrl)
1068 dbgarg(cmd, "Enum for index=%d\n", p->id);
1070 ret=vfd->vidioc_g_ctrl(file, fh, p);
1072 dbgarg2 ( "id=%d, value=%d\n", p->id, p->value);
1077 struct v4l2_control *p = arg;
1079 if (!vfd->vidioc_s_ctrl)
1081 dbgarg (cmd, "id=%d, value=%d\n", p->id, p->value);
1083 ret=vfd->vidioc_s_ctrl(file, fh, p);
1086 case VIDIOC_G_EXT_CTRLS:
1088 struct v4l2_ext_controls *p = arg;
1090 if (vfd->vidioc_g_ext_ctrls) {
1091 dbgarg(cmd, "count=%d\n", p->count);
1093 ret=vfd->vidioc_g_ext_ctrls(file, fh, p);
1097 case VIDIOC_S_EXT_CTRLS:
1099 struct v4l2_ext_controls *p = arg;
1101 if (vfd->vidioc_s_ext_ctrls) {
1102 dbgarg(cmd, "count=%d\n", p->count);
1104 ret=vfd->vidioc_s_ext_ctrls(file, fh, p);
1108 case VIDIOC_TRY_EXT_CTRLS:
1110 struct v4l2_ext_controls *p = arg;
1112 if (vfd->vidioc_try_ext_ctrls) {
1113 dbgarg(cmd, "count=%d\n", p->count);
1115 ret=vfd->vidioc_try_ext_ctrls(file, fh, p);
1119 case VIDIOC_QUERYMENU:
1121 struct v4l2_querymenu *p=arg;
1122 if (!vfd->vidioc_querymenu)
1124 ret=vfd->vidioc_querymenu(file, fh, p);
1126 dbgarg (cmd, "id=%d, index=%d, name=%s\n",
1127 p->id,p->index,p->name);
1130 /* --- audio ---------------------------------------------- */
1131 case VIDIOC_ENUMAUDIO:
1133 struct v4l2_audio *p=arg;
1135 if (!vfd->vidioc_enumaudio)
1137 dbgarg(cmd, "Enum for index=%d\n", p->index);
1138 ret=vfd->vidioc_enumaudio(file, fh, p);
1140 dbgarg2("index=%d, name=%s, capability=%d, "
1141 "mode=%d\n",p->index,p->name,
1142 p->capability, p->mode);
1145 case VIDIOC_G_AUDIO:
1147 struct v4l2_audio *p=arg;
1148 __u32 index=p->index;
1150 if (!vfd->vidioc_g_audio)
1153 memset(p,0,sizeof(*p));
1155 dbgarg(cmd, "Get for index=%d\n", p->index);
1156 ret=vfd->vidioc_g_audio(file, fh, p);
1158 dbgarg2("index=%d, name=%s, capability=%d, "
1159 "mode=%d\n",p->index,
1160 p->name,p->capability, p->mode);
1163 case VIDIOC_S_AUDIO:
1165 struct v4l2_audio *p=arg;
1167 if (!vfd->vidioc_s_audio)
1169 dbgarg(cmd, "index=%d, name=%s, capability=%d, "
1170 "mode=%d\n", p->index, p->name,
1171 p->capability, p->mode);
1172 ret=vfd->vidioc_s_audio(file, fh, p);
1175 case VIDIOC_ENUMAUDOUT:
1177 struct v4l2_audioout *p=arg;
1179 if (!vfd->vidioc_enumaudout)
1181 dbgarg(cmd, "Enum for index=%d\n", p->index);
1182 ret=vfd->vidioc_enumaudout(file, fh, p);
1184 dbgarg2("index=%d, name=%s, capability=%d, "
1185 "mode=%d\n", p->index, p->name,
1186 p->capability,p->mode);
1189 case VIDIOC_G_AUDOUT:
1191 struct v4l2_audioout *p=arg;
1193 if (!vfd->vidioc_g_audout)
1195 dbgarg(cmd, "Enum for index=%d\n", p->index);
1196 ret=vfd->vidioc_g_audout(file, fh, p);
1198 dbgarg2("index=%d, name=%s, capability=%d, "
1199 "mode=%d\n", p->index, p->name,
1200 p->capability,p->mode);
1203 case VIDIOC_S_AUDOUT:
1205 struct v4l2_audioout *p=arg;
1207 if (!vfd->vidioc_s_audout)
1209 dbgarg(cmd, "index=%d, name=%s, capability=%d, "
1210 "mode=%d\n", p->index, p->name,
1211 p->capability,p->mode);
1213 ret=vfd->vidioc_s_audout(file, fh, p);
1216 case VIDIOC_G_MODULATOR:
1218 struct v4l2_modulator *p=arg;
1219 if (!vfd->vidioc_g_modulator)
1221 ret=vfd->vidioc_g_modulator(file, fh, p);
1223 dbgarg(cmd, "index=%d, name=%s, "
1224 "capability=%d, rangelow=%d,"
1225 " rangehigh=%d, txsubchans=%d\n",
1226 p->index, p->name,p->capability,
1227 p->rangelow, p->rangehigh,
1231 case VIDIOC_S_MODULATOR:
1233 struct v4l2_modulator *p=arg;
1234 if (!vfd->vidioc_s_modulator)
1236 dbgarg(cmd, "index=%d, name=%s, capability=%d, "
1237 "rangelow=%d, rangehigh=%d, txsubchans=%d\n",
1238 p->index, p->name,p->capability,p->rangelow,
1239 p->rangehigh,p->txsubchans);
1240 ret=vfd->vidioc_s_modulator(file, fh, p);
1245 struct v4l2_crop *p=arg;
1246 if (!vfd->vidioc_g_crop)
1248 ret=vfd->vidioc_g_crop(file, fh, p);
1250 dbgarg(cmd, "type=%d\n", p->type);
1251 dbgrect(vfd, "", &p->c);
1257 struct v4l2_crop *p=arg;
1258 if (!vfd->vidioc_s_crop)
1260 dbgarg(cmd, "type=%d\n", p->type);
1261 dbgrect(vfd, "", &p->c);
1262 ret=vfd->vidioc_s_crop(file, fh, p);
1265 case VIDIOC_CROPCAP:
1267 struct v4l2_cropcap *p=arg;
1268 /*FIXME: Should also show v4l2_fract pixelaspect */
1269 if (!vfd->vidioc_cropcap)
1271 dbgarg(cmd, "type=%d\n", p->type);
1272 dbgrect(vfd, "bounds ", &p->bounds);
1273 dbgrect(vfd, "defrect ", &p->defrect);
1274 ret=vfd->vidioc_cropcap(file, fh, p);
1277 case VIDIOC_G_MPEGCOMP:
1279 struct v4l2_mpeg_compression *p=arg;
1281 /*FIXME: Several fields not shown */
1282 if (!vfd->vidioc_g_mpegcomp)
1284 ret=vfd->vidioc_g_mpegcomp(file, fh, p);
1286 dbgarg (cmd, "ts_pid_pmt=%d, ts_pid_audio=%d,"
1287 " ts_pid_video=%d, ts_pid_pcr=%d, "
1288 "ps_size=%d, au_sample_rate=%d, "
1289 "au_pesid=%c, vi_frame_rate=%d, "
1290 "vi_frames_per_gop=%d, "
1291 "vi_bframes_count=%d, vi_pesid=%c\n",
1292 p->ts_pid_pmt,p->ts_pid_audio,
1293 p->ts_pid_video,p->ts_pid_pcr,
1294 p->ps_size, p->au_sample_rate,
1295 p->au_pesid, p->vi_frame_rate,
1296 p->vi_frames_per_gop,
1297 p->vi_bframes_count, p->vi_pesid);
1300 case VIDIOC_S_MPEGCOMP:
1302 struct v4l2_mpeg_compression *p=arg;
1303 /*FIXME: Several fields not shown */
1304 if (!vfd->vidioc_s_mpegcomp)
1306 dbgarg (cmd, "ts_pid_pmt=%d, ts_pid_audio=%d, "
1307 "ts_pid_video=%d, ts_pid_pcr=%d, ps_size=%d, "
1308 "au_sample_rate=%d, au_pesid=%c, "
1309 "vi_frame_rate=%d, vi_frames_per_gop=%d, "
1310 "vi_bframes_count=%d, vi_pesid=%c\n",
1311 p->ts_pid_pmt,p->ts_pid_audio, p->ts_pid_video,
1312 p->ts_pid_pcr, p->ps_size, p->au_sample_rate,
1313 p->au_pesid, p->vi_frame_rate,
1314 p->vi_frames_per_gop, p->vi_bframes_count,
1316 ret=vfd->vidioc_s_mpegcomp(file, fh, p);
1319 case VIDIOC_G_JPEGCOMP:
1321 struct v4l2_jpegcompression *p=arg;
1322 if (!vfd->vidioc_g_jpegcomp)
1324 ret=vfd->vidioc_g_jpegcomp(file, fh, p);
1326 dbgarg (cmd, "quality=%d, APPn=%d, "
1327 "APP_len=%d, COM_len=%d, "
1328 "jpeg_markers=%d\n",
1329 p->quality,p->APPn,p->APP_len,
1330 p->COM_len,p->jpeg_markers);
1333 case VIDIOC_S_JPEGCOMP:
1335 struct v4l2_jpegcompression *p=arg;
1336 if (!vfd->vidioc_g_jpegcomp)
1338 dbgarg (cmd, "quality=%d, APPn=%d, APP_len=%d, "
1339 "COM_len=%d, jpeg_markers=%d\n",
1340 p->quality,p->APPn,p->APP_len,
1341 p->COM_len,p->jpeg_markers);
1342 ret=vfd->vidioc_s_jpegcomp(file, fh, p);
1347 struct v4l2_streamparm *p=arg;
1348 if (vfd->vidioc_g_parm) {
1349 ret=vfd->vidioc_g_parm(file, fh, p);
1351 struct v4l2_standard s;
1353 if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1356 v4l2_video_std_construct(&s, vfd->current_norm,
1357 v4l2_norm_to_name(vfd->current_norm));
1359 memset(p,0,sizeof(*p));
1361 p->parm.capture.timeperframe = s.frameperiod;
1365 dbgarg (cmd, "type=%d\n", p->type);
1370 struct v4l2_streamparm *p=arg;
1371 if (!vfd->vidioc_s_parm)
1373 dbgarg (cmd, "type=%d\n", p->type);
1374 ret=vfd->vidioc_s_parm(file, fh, p);
1377 case VIDIOC_G_TUNER:
1379 struct v4l2_tuner *p=arg;
1380 __u32 index=p->index;
1382 if (!vfd->vidioc_g_tuner)
1385 memset(p,0,sizeof(*p));
1388 ret=vfd->vidioc_g_tuner(file, fh, p);
1390 dbgarg (cmd, "index=%d, name=%s, type=%d, "
1391 "capability=%d, rangelow=%d, "
1392 "rangehigh=%d, signal=%d, afc=%d, "
1393 "rxsubchans=%d, audmode=%d\n",
1394 p->index, p->name, p->type,
1395 p->capability, p->rangelow,
1396 p->rangehigh, p->rxsubchans,
1397 p->audmode, p->signal, p->afc);
1400 case VIDIOC_S_TUNER:
1402 struct v4l2_tuner *p=arg;
1403 if (!vfd->vidioc_s_tuner)
1405 dbgarg (cmd, "index=%d, name=%s, type=%d, "
1406 "capability=%d, rangelow=%d, rangehigh=%d, "
1407 "signal=%d, afc=%d, rxsubchans=%d, "
1408 "audmode=%d\n",p->index, p->name, p->type,
1409 p->capability, p->rangelow,p->rangehigh,
1410 p->rxsubchans, p->audmode, p->signal,
1412 ret=vfd->vidioc_s_tuner(file, fh, p);
1415 case VIDIOC_G_FREQUENCY:
1417 struct v4l2_frequency *p=arg;
1418 if (!vfd->vidioc_g_frequency)
1421 memset(p,0,sizeof(*p));
1423 ret=vfd->vidioc_g_frequency(file, fh, p);
1425 dbgarg (cmd, "tuner=%d, type=%d, frequency=%d\n",
1426 p->tuner,p->type,p->frequency);
1429 case VIDIOC_S_FREQUENCY:
1431 struct v4l2_frequency *p=arg;
1432 if (!vfd->vidioc_s_frequency)
1434 dbgarg (cmd, "tuner=%d, type=%d, frequency=%d\n",
1435 p->tuner,p->type,p->frequency);
1436 ret=vfd->vidioc_s_frequency(file, fh, p);
1439 case VIDIOC_G_SLICED_VBI_CAP:
1441 struct v4l2_sliced_vbi_cap *p=arg;
1442 if (!vfd->vidioc_g_sliced_vbi_cap)
1444 ret=vfd->vidioc_g_sliced_vbi_cap(file, fh, p);
1446 dbgarg (cmd, "service_set=%d\n", p->service_set);
1449 case VIDIOC_LOG_STATUS:
1451 if (!vfd->vidioc_log_status)
1453 ret=vfd->vidioc_log_status(file, fh);
1458 if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) {
1460 printk ("%s: err:\n", vfd->name);
1461 v4l_print_ioctl(vfd->name, cmd);
1468 int video_ioctl2 (struct inode *inode, struct file *file,
1469 unsigned int cmd, unsigned long arg)
1476 size_t ctrls_size = 0;
1477 void __user *user_ptr = NULL;
1479 #ifdef __OLD_VIDIOC_
1480 cmd = video_fix_command(cmd);
1482 is_ext_ctrl = (cmd == VIDIOC_S_EXT_CTRLS || cmd == VIDIOC_G_EXT_CTRLS ||
1483 cmd == VIDIOC_TRY_EXT_CTRLS);
1485 /* Copy arguments into temp kernel buffer */
1486 switch (_IOC_DIR(cmd)) {
1492 case (_IOC_WRITE | _IOC_READ):
1493 if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
1496 /* too big to allocate from stack */
1497 mbuf = kmalloc(_IOC_SIZE(cmd),GFP_KERNEL);
1504 if (_IOC_DIR(cmd) & _IOC_WRITE)
1505 if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd)))
1511 struct v4l2_ext_controls *p = parg;
1513 /* In case of an error, tell the caller that it wasn't
1514 a specific control that caused it. */
1515 p->error_idx = p->count;
1516 user_ptr = (void __user *)p->controls;
1518 ctrls_size = sizeof(struct v4l2_ext_control) * p->count;
1519 /* Note: v4l2_ext_controls fits in sbuf[] so mbuf is still NULL. */
1520 mbuf = kmalloc(ctrls_size, GFP_KERNEL);
1525 if (copy_from_user(mbuf, user_ptr, ctrls_size))
1532 err = __video_do_ioctl(inode, file, cmd, parg);
1533 if (err == -ENOIOCTLCMD)
1536 struct v4l2_ext_controls *p = parg;
1538 p->controls = (void *)user_ptr;
1539 if (p->count && err == 0 && copy_to_user(user_ptr, mbuf, ctrls_size))
1547 /* Copy results into user buffer */
1548 switch (_IOC_DIR(cmd))
1551 case (_IOC_WRITE | _IOC_READ):
1552 if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd)))
1563 static const struct file_operations video_fops;
1566 * video_register_device - register video4linux devices
1567 * @vfd: video device structure we want to register
1568 * @type: type of device to register
1569 * @nr: which device number (0 == /dev/video0, 1 == /dev/video1, ...
1572 * The registration code assigns minor numbers based on the type
1573 * requested. -ENFILE is returned in all the device slots for this
1574 * category are full. If not then the minor field is set and the
1575 * driver initialize function is called (if non %NULL).
1577 * Zero is returned on success.
1581 * %VFL_TYPE_GRABBER - A frame grabber
1583 * %VFL_TYPE_VTX - A teletext device
1585 * %VFL_TYPE_VBI - Vertical blank data (undecoded)
1587 * %VFL_TYPE_RADIO - A radio card
1590 int video_register_device(struct video_device *vfd, int type, int nr)
1600 case VFL_TYPE_GRABBER:
1601 base=MINOR_VFL_TYPE_GRABBER_MIN;
1602 end=MINOR_VFL_TYPE_GRABBER_MAX+1;
1603 name_base = "video";
1606 base=MINOR_VFL_TYPE_VTX_MIN;
1607 end=MINOR_VFL_TYPE_VTX_MAX+1;
1611 base=MINOR_VFL_TYPE_VBI_MIN;
1612 end=MINOR_VFL_TYPE_VBI_MAX+1;
1615 case VFL_TYPE_RADIO:
1616 base=MINOR_VFL_TYPE_RADIO_MIN;
1617 end=MINOR_VFL_TYPE_RADIO_MAX+1;
1618 name_base = "radio";
1621 printk(KERN_ERR "%s called with unknown type: %d\n",
1622 __FUNCTION__, type);
1626 /* pick a minor number */
1627 mutex_lock(&videodev_lock);
1628 if (nr >= 0 && nr < end-base) {
1629 /* use the one the driver asked for */
1631 if (NULL != video_device[i]) {
1632 mutex_unlock(&videodev_lock);
1636 /* use first free */
1637 for(i=base;i<end;i++)
1638 if (NULL == video_device[i])
1641 mutex_unlock(&videodev_lock);
1645 video_device[i]=vfd;
1647 mutex_unlock(&videodev_lock);
1648 mutex_init(&vfd->lock);
1651 memset(&vfd->class_dev, 0x00, sizeof(vfd->class_dev));
1653 vfd->class_dev.dev = vfd->dev;
1654 vfd->class_dev.class = &video_class;
1655 vfd->class_dev.devt = MKDEV(VIDEO_MAJOR, vfd->minor);
1656 sprintf(vfd->class_dev.class_id, "%s%d", name_base, i - base);
1657 ret = class_device_register(&vfd->class_dev);
1659 printk(KERN_ERR "%s: class_device_register failed\n",
1663 ret = class_device_create_file(&vfd->class_dev, &class_device_attr_name);
1665 printk(KERN_ERR "%s: class_device_create_file 'name' failed\n",
1671 /* needed until all drivers are fixed */
1673 printk(KERN_WARNING "videodev: \"%s\" has no release callback. "
1674 "Please fix your driver for proper sysfs support, see "
1675 "http://lwn.net/Articles/36850/\n", vfd->name);
1680 class_device_unregister(&vfd->class_dev);
1682 mutex_lock(&videodev_lock);
1683 video_device[vfd->minor] = NULL;
1685 mutex_unlock(&videodev_lock);
1690 * video_unregister_device - unregister a video4linux device
1691 * @vfd: the device to unregister
1693 * This unregisters the passed device and deassigns the minor
1694 * number. Future open calls will be met with errors.
1697 void video_unregister_device(struct video_device *vfd)
1699 mutex_lock(&videodev_lock);
1700 if(video_device[vfd->minor]!=vfd)
1701 panic("videodev: bad unregister");
1703 video_device[vfd->minor]=NULL;
1704 class_device_unregister(&vfd->class_dev);
1705 mutex_unlock(&videodev_lock);
1709 * Video fs operations
1711 static const struct file_operations video_fops=
1713 .owner = THIS_MODULE,
1714 .llseek = no_llseek,
1719 * Initialise video for linux
1722 static int __init videodev_init(void)
1726 printk(KERN_INFO "Linux video capture interface: v2.00\n");
1727 if (register_chrdev(VIDEO_MAJOR, VIDEO_NAME, &video_fops)) {
1728 printk(KERN_WARNING "video_dev: unable to get major %d\n", VIDEO_MAJOR);
1732 ret = class_register(&video_class);
1734 unregister_chrdev(VIDEO_MAJOR, VIDEO_NAME);
1735 printk(KERN_WARNING "video_dev: class_register failed\n");
1742 static void __exit videodev_exit(void)
1744 class_unregister(&video_class);
1745 unregister_chrdev(VIDEO_MAJOR, VIDEO_NAME);
1748 module_init(videodev_init)
1749 module_exit(videodev_exit)
1751 EXPORT_SYMBOL(video_register_device);
1752 EXPORT_SYMBOL(video_unregister_device);
1753 EXPORT_SYMBOL(video_devdata);
1754 EXPORT_SYMBOL(video_usercopy);
1755 EXPORT_SYMBOL(video_exclusive_open);
1756 EXPORT_SYMBOL(video_exclusive_release);
1757 EXPORT_SYMBOL(video_ioctl2);
1758 EXPORT_SYMBOL(video_device_alloc);
1759 EXPORT_SYMBOL(video_device_release);
1761 MODULE_AUTHOR("Alan Cox, Mauro Carvalho Chehab <mchehab@infradead.org>");
1762 MODULE_DESCRIPTION("Device registrar for Video4Linux drivers v2");
1763 MODULE_LICENSE("GPL");