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);
1345 case VIDIOC_G_ENC_INDEX:
1347 struct v4l2_enc_idx *p=arg;
1349 if (!vfd->vidioc_g_enc_index)
1351 ret=vfd->vidioc_g_enc_index(file, fh, p);
1353 dbgarg (cmd, "entries=%d, entries_cap=%d\n",
1354 p->entries,p->entries_cap);
1359 struct v4l2_streamparm *p=arg;
1360 if (vfd->vidioc_g_parm) {
1361 ret=vfd->vidioc_g_parm(file, fh, p);
1363 struct v4l2_standard s;
1365 if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1368 v4l2_video_std_construct(&s, vfd->current_norm,
1369 v4l2_norm_to_name(vfd->current_norm));
1371 memset(p,0,sizeof(*p));
1373 p->parm.capture.timeperframe = s.frameperiod;
1377 dbgarg (cmd, "type=%d\n", p->type);
1382 struct v4l2_streamparm *p=arg;
1383 if (!vfd->vidioc_s_parm)
1385 dbgarg (cmd, "type=%d\n", p->type);
1386 ret=vfd->vidioc_s_parm(file, fh, p);
1389 case VIDIOC_G_TUNER:
1391 struct v4l2_tuner *p=arg;
1392 __u32 index=p->index;
1394 if (!vfd->vidioc_g_tuner)
1397 memset(p,0,sizeof(*p));
1400 ret=vfd->vidioc_g_tuner(file, fh, p);
1402 dbgarg (cmd, "index=%d, name=%s, type=%d, "
1403 "capability=%d, rangelow=%d, "
1404 "rangehigh=%d, signal=%d, afc=%d, "
1405 "rxsubchans=%d, audmode=%d\n",
1406 p->index, p->name, p->type,
1407 p->capability, p->rangelow,
1408 p->rangehigh, p->rxsubchans,
1409 p->audmode, p->signal, p->afc);
1412 case VIDIOC_S_TUNER:
1414 struct v4l2_tuner *p=arg;
1415 if (!vfd->vidioc_s_tuner)
1417 dbgarg (cmd, "index=%d, name=%s, type=%d, "
1418 "capability=%d, rangelow=%d, rangehigh=%d, "
1419 "signal=%d, afc=%d, rxsubchans=%d, "
1420 "audmode=%d\n",p->index, p->name, p->type,
1421 p->capability, p->rangelow,p->rangehigh,
1422 p->rxsubchans, p->audmode, p->signal,
1424 ret=vfd->vidioc_s_tuner(file, fh, p);
1427 case VIDIOC_G_FREQUENCY:
1429 struct v4l2_frequency *p=arg;
1430 if (!vfd->vidioc_g_frequency)
1433 memset(p,0,sizeof(*p));
1435 ret=vfd->vidioc_g_frequency(file, fh, p);
1437 dbgarg (cmd, "tuner=%d, type=%d, frequency=%d\n",
1438 p->tuner,p->type,p->frequency);
1441 case VIDIOC_S_FREQUENCY:
1443 struct v4l2_frequency *p=arg;
1444 if (!vfd->vidioc_s_frequency)
1446 dbgarg (cmd, "tuner=%d, type=%d, frequency=%d\n",
1447 p->tuner,p->type,p->frequency);
1448 ret=vfd->vidioc_s_frequency(file, fh, p);
1451 case VIDIOC_G_SLICED_VBI_CAP:
1453 struct v4l2_sliced_vbi_cap *p=arg;
1454 if (!vfd->vidioc_g_sliced_vbi_cap)
1456 ret=vfd->vidioc_g_sliced_vbi_cap(file, fh, p);
1458 dbgarg (cmd, "service_set=%d\n", p->service_set);
1461 case VIDIOC_LOG_STATUS:
1463 if (!vfd->vidioc_log_status)
1465 ret=vfd->vidioc_log_status(file, fh);
1468 #ifdef CONFIG_VIDEO_ADV_DEBUG
1469 case VIDIOC_DBG_G_REGISTER:
1471 struct v4l2_register *p=arg;
1472 if (!capable(CAP_SYS_ADMIN))
1474 else if (vfd->vidioc_g_register)
1475 ret=vfd->vidioc_g_register(file, fh, p);
1478 case VIDIOC_DBG_S_REGISTER:
1480 struct v4l2_register *p=arg;
1481 if (!capable(CAP_SYS_ADMIN))
1483 else if (vfd->vidioc_s_register)
1484 ret=vfd->vidioc_s_register(file, fh, p);
1490 if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) {
1492 printk ("%s: err:\n", vfd->name);
1493 v4l_print_ioctl(vfd->name, cmd);
1500 int video_ioctl2 (struct inode *inode, struct file *file,
1501 unsigned int cmd, unsigned long arg)
1508 size_t ctrls_size = 0;
1509 void __user *user_ptr = NULL;
1511 #ifdef __OLD_VIDIOC_
1512 cmd = video_fix_command(cmd);
1514 is_ext_ctrl = (cmd == VIDIOC_S_EXT_CTRLS || cmd == VIDIOC_G_EXT_CTRLS ||
1515 cmd == VIDIOC_TRY_EXT_CTRLS);
1517 /* Copy arguments into temp kernel buffer */
1518 switch (_IOC_DIR(cmd)) {
1524 case (_IOC_WRITE | _IOC_READ):
1525 if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
1528 /* too big to allocate from stack */
1529 mbuf = kmalloc(_IOC_SIZE(cmd),GFP_KERNEL);
1536 if (_IOC_DIR(cmd) & _IOC_WRITE)
1537 if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd)))
1543 struct v4l2_ext_controls *p = parg;
1545 /* In case of an error, tell the caller that it wasn't
1546 a specific control that caused it. */
1547 p->error_idx = p->count;
1548 user_ptr = (void __user *)p->controls;
1550 ctrls_size = sizeof(struct v4l2_ext_control) * p->count;
1551 /* Note: v4l2_ext_controls fits in sbuf[] so mbuf is still NULL. */
1552 mbuf = kmalloc(ctrls_size, GFP_KERNEL);
1557 if (copy_from_user(mbuf, user_ptr, ctrls_size))
1564 err = __video_do_ioctl(inode, file, cmd, parg);
1565 if (err == -ENOIOCTLCMD)
1568 struct v4l2_ext_controls *p = parg;
1570 p->controls = (void *)user_ptr;
1571 if (p->count && err == 0 && copy_to_user(user_ptr, mbuf, ctrls_size))
1579 /* Copy results into user buffer */
1580 switch (_IOC_DIR(cmd))
1583 case (_IOC_WRITE | _IOC_READ):
1584 if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd)))
1595 static const struct file_operations video_fops;
1598 * video_register_device - register video4linux devices
1599 * @vfd: video device structure we want to register
1600 * @type: type of device to register
1601 * @nr: which device number (0 == /dev/video0, 1 == /dev/video1, ...
1604 * The registration code assigns minor numbers based on the type
1605 * requested. -ENFILE is returned in all the device slots for this
1606 * category are full. If not then the minor field is set and the
1607 * driver initialize function is called (if non %NULL).
1609 * Zero is returned on success.
1613 * %VFL_TYPE_GRABBER - A frame grabber
1615 * %VFL_TYPE_VTX - A teletext device
1617 * %VFL_TYPE_VBI - Vertical blank data (undecoded)
1619 * %VFL_TYPE_RADIO - A radio card
1622 int video_register_device(struct video_device *vfd, int type, int nr)
1632 case VFL_TYPE_GRABBER:
1633 base=MINOR_VFL_TYPE_GRABBER_MIN;
1634 end=MINOR_VFL_TYPE_GRABBER_MAX+1;
1635 name_base = "video";
1638 base=MINOR_VFL_TYPE_VTX_MIN;
1639 end=MINOR_VFL_TYPE_VTX_MAX+1;
1643 base=MINOR_VFL_TYPE_VBI_MIN;
1644 end=MINOR_VFL_TYPE_VBI_MAX+1;
1647 case VFL_TYPE_RADIO:
1648 base=MINOR_VFL_TYPE_RADIO_MIN;
1649 end=MINOR_VFL_TYPE_RADIO_MAX+1;
1650 name_base = "radio";
1653 printk(KERN_ERR "%s called with unknown type: %d\n",
1654 __FUNCTION__, type);
1658 /* pick a minor number */
1659 mutex_lock(&videodev_lock);
1660 if (nr >= 0 && nr < end-base) {
1661 /* use the one the driver asked for */
1663 if (NULL != video_device[i]) {
1664 mutex_unlock(&videodev_lock);
1668 /* use first free */
1669 for(i=base;i<end;i++)
1670 if (NULL == video_device[i])
1673 mutex_unlock(&videodev_lock);
1677 video_device[i]=vfd;
1679 mutex_unlock(&videodev_lock);
1680 mutex_init(&vfd->lock);
1683 memset(&vfd->class_dev, 0x00, sizeof(vfd->class_dev));
1685 vfd->class_dev.dev = vfd->dev;
1686 vfd->class_dev.class = &video_class;
1687 vfd->class_dev.devt = MKDEV(VIDEO_MAJOR, vfd->minor);
1688 sprintf(vfd->class_dev.class_id, "%s%d", name_base, i - base);
1689 ret = class_device_register(&vfd->class_dev);
1691 printk(KERN_ERR "%s: class_device_register failed\n",
1695 ret = class_device_create_file(&vfd->class_dev, &class_device_attr_name);
1697 printk(KERN_ERR "%s: class_device_create_file 'name' failed\n",
1703 /* needed until all drivers are fixed */
1705 printk(KERN_WARNING "videodev: \"%s\" has no release callback. "
1706 "Please fix your driver for proper sysfs support, see "
1707 "http://lwn.net/Articles/36850/\n", vfd->name);
1712 class_device_unregister(&vfd->class_dev);
1714 mutex_lock(&videodev_lock);
1715 video_device[vfd->minor] = NULL;
1717 mutex_unlock(&videodev_lock);
1722 * video_unregister_device - unregister a video4linux device
1723 * @vfd: the device to unregister
1725 * This unregisters the passed device and deassigns the minor
1726 * number. Future open calls will be met with errors.
1729 void video_unregister_device(struct video_device *vfd)
1731 mutex_lock(&videodev_lock);
1732 if(video_device[vfd->minor]!=vfd)
1733 panic("videodev: bad unregister");
1735 video_device[vfd->minor]=NULL;
1736 class_device_unregister(&vfd->class_dev);
1737 mutex_unlock(&videodev_lock);
1741 * Video fs operations
1743 static const struct file_operations video_fops=
1745 .owner = THIS_MODULE,
1746 .llseek = no_llseek,
1751 * Initialise video for linux
1754 static int __init videodev_init(void)
1758 printk(KERN_INFO "Linux video capture interface: v2.00\n");
1759 if (register_chrdev(VIDEO_MAJOR, VIDEO_NAME, &video_fops)) {
1760 printk(KERN_WARNING "video_dev: unable to get major %d\n", VIDEO_MAJOR);
1764 ret = class_register(&video_class);
1766 unregister_chrdev(VIDEO_MAJOR, VIDEO_NAME);
1767 printk(KERN_WARNING "video_dev: class_register failed\n");
1774 static void __exit videodev_exit(void)
1776 class_unregister(&video_class);
1777 unregister_chrdev(VIDEO_MAJOR, VIDEO_NAME);
1780 module_init(videodev_init)
1781 module_exit(videodev_exit)
1783 EXPORT_SYMBOL(video_register_device);
1784 EXPORT_SYMBOL(video_unregister_device);
1785 EXPORT_SYMBOL(video_devdata);
1786 EXPORT_SYMBOL(video_usercopy);
1787 EXPORT_SYMBOL(video_exclusive_open);
1788 EXPORT_SYMBOL(video_exclusive_release);
1789 EXPORT_SYMBOL(video_ioctl2);
1790 EXPORT_SYMBOL(video_device_alloc);
1791 EXPORT_SYMBOL(video_device_release);
1793 MODULE_AUTHOR("Alan Cox, Mauro Carvalho Chehab <mchehab@infradead.org>");
1794 MODULE_DESCRIPTION("Device registrar for Video4Linux drivers v2");
1795 MODULE_LICENSE("GPL");