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>
34 #include <linux/string.h>
35 #include <linux/errno.h>
36 #include <linux/init.h>
37 #include <linux/kmod.h>
38 #include <linux/slab.h>
39 #include <asm/uaccess.h>
40 #include <asm/system.h>
42 #define __OLD_VIDIOC_ /* To allow fixing old calls*/
43 #include <linux/videodev2.h>
45 #ifdef CONFIG_VIDEO_V4L1
46 #include <linux/videodev.h>
48 #include <media/v4l2-common.h>
50 #define VIDEO_NUM_DEVICES 256
51 #define VIDEO_NAME "video4linux"
57 static ssize_t show_name(struct device *cd,
58 struct device_attribute *attr, 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 struct video_device *video_device_alloc(void)
67 struct video_device *vfd;
69 vfd = kzalloc(sizeof(*vfd),GFP_KERNEL);
73 void video_device_release(struct video_device *vfd)
78 static void video_release(struct device *cd)
80 struct video_device *vfd = container_of(cd, struct video_device,
84 /* needed until all drivers are fixed */
91 static struct device_attribute video_device_attrs[] = {
92 __ATTR(name, S_IRUGO, show_name, NULL),
96 static struct class video_class = {
98 .dev_attrs = video_device_attrs,
99 .dev_release = video_release,
106 static struct video_device *video_device[VIDEO_NUM_DEVICES];
107 static DEFINE_MUTEX(videodev_lock);
109 struct video_device* video_devdata(struct file *file)
111 return video_device[iminor(file->f_path.dentry->d_inode)];
115 * Open a video device - FIXME: Obsoleted
117 static int video_open(struct inode *inode, struct file *file)
119 unsigned int minor = iminor(inode);
121 struct video_device *vfl;
122 const struct file_operations *old_fops;
124 if(minor>=VIDEO_NUM_DEVICES)
126 mutex_lock(&videodev_lock);
127 vfl=video_device[minor];
129 mutex_unlock(&videodev_lock);
130 request_module("char-major-%d-%d", VIDEO_MAJOR, minor);
131 mutex_lock(&videodev_lock);
132 vfl=video_device[minor];
134 mutex_unlock(&videodev_lock);
138 old_fops = file->f_op;
139 file->f_op = fops_get(vfl->fops);
141 err = file->f_op->open(inode,file);
143 fops_put(file->f_op);
144 file->f_op = fops_get(old_fops);
147 mutex_unlock(&videodev_lock);
152 * helper function -- handles userspace copying for ioctl arguments
157 video_fix_command(unsigned int cmd)
160 case VIDIOC_OVERLAY_OLD:
161 cmd = VIDIOC_OVERLAY;
163 case VIDIOC_S_PARM_OLD:
166 case VIDIOC_S_CTRL_OLD:
169 case VIDIOC_G_AUDIO_OLD:
170 cmd = VIDIOC_G_AUDIO;
172 case VIDIOC_G_AUDOUT_OLD:
173 cmd = VIDIOC_G_AUDOUT;
175 case VIDIOC_CROPCAP_OLD:
176 cmd = VIDIOC_CROPCAP;
184 * Obsolete usercopy function - Should be removed soon
187 video_usercopy(struct inode *inode, struct file *file,
188 unsigned int cmd, unsigned long arg,
189 int (*func)(struct inode *inode, struct file *file,
190 unsigned int cmd, void *arg))
197 size_t ctrls_size = 0;
198 void __user *user_ptr = NULL;
201 cmd = video_fix_command(cmd);
203 is_ext_ctrl = (cmd == VIDIOC_S_EXT_CTRLS || cmd == VIDIOC_G_EXT_CTRLS ||
204 cmd == VIDIOC_TRY_EXT_CTRLS);
206 /* Copy arguments into temp kernel buffer */
207 switch (_IOC_DIR(cmd)) {
213 case (_IOC_WRITE | _IOC_READ):
214 if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
217 /* too big to allocate from stack */
218 mbuf = kmalloc(_IOC_SIZE(cmd),GFP_KERNEL);
225 if (_IOC_DIR(cmd) & _IOC_WRITE)
226 if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd)))
231 struct v4l2_ext_controls *p = parg;
233 /* In case of an error, tell the caller that it wasn't
234 a specific control that caused it. */
235 p->error_idx = p->count;
236 user_ptr = (void __user *)p->controls;
238 ctrls_size = sizeof(struct v4l2_ext_control) * p->count;
239 /* Note: v4l2_ext_controls fits in sbuf[] so mbuf is still NULL. */
240 mbuf = kmalloc(ctrls_size, GFP_KERNEL);
245 if (copy_from_user(mbuf, user_ptr, ctrls_size))
252 err = func(inode, file, cmd, parg);
253 if (err == -ENOIOCTLCMD)
256 struct v4l2_ext_controls *p = parg;
258 p->controls = (void *)user_ptr;
259 if (p->count && err == 0 && copy_to_user(user_ptr, mbuf, ctrls_size))
267 /* Copy results into user buffer */
268 switch (_IOC_DIR(cmd))
271 case (_IOC_WRITE | _IOC_READ):
272 if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd)))
283 * open/release helper functions -- handle exclusive opens
284 * Should be removed soon
286 int video_exclusive_open(struct inode *inode, struct file *file)
288 struct video_device *vfl = video_devdata(file);
291 mutex_lock(&vfl->lock);
297 mutex_unlock(&vfl->lock);
301 int video_exclusive_release(struct inode *inode, struct file *file)
303 struct video_device *vfl = video_devdata(file);
309 static char *v4l2_memory_names[] = {
310 [V4L2_MEMORY_MMAP] = "mmap",
311 [V4L2_MEMORY_USERPTR] = "userptr",
312 [V4L2_MEMORY_OVERLAY] = "overlay",
316 /* FIXME: Those stuff are replicated also on v4l2-common.c */
317 static char *v4l2_type_names_FIXME[] = {
318 [V4L2_BUF_TYPE_VIDEO_CAPTURE] = "video-cap",
319 [V4L2_BUF_TYPE_VIDEO_OVERLAY] = "video-over",
320 [V4L2_BUF_TYPE_VIDEO_OUTPUT] = "video-out",
321 [V4L2_BUF_TYPE_VBI_CAPTURE] = "vbi-cap",
322 [V4L2_BUF_TYPE_VBI_OUTPUT] = "vbi-out",
323 [V4L2_BUF_TYPE_SLICED_VBI_OUTPUT] = "sliced-vbi-out",
324 [V4L2_BUF_TYPE_SLICED_VBI_CAPTURE] = "sliced-vbi-capture",
325 [V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY] = "video-out-over",
326 [V4L2_BUF_TYPE_PRIVATE] = "private",
329 static char *v4l2_field_names_FIXME[] = {
330 [V4L2_FIELD_ANY] = "any",
331 [V4L2_FIELD_NONE] = "none",
332 [V4L2_FIELD_TOP] = "top",
333 [V4L2_FIELD_BOTTOM] = "bottom",
334 [V4L2_FIELD_INTERLACED] = "interlaced",
335 [V4L2_FIELD_SEQ_TB] = "seq-tb",
336 [V4L2_FIELD_SEQ_BT] = "seq-bt",
337 [V4L2_FIELD_ALTERNATE] = "alternate",
338 [V4L2_FIELD_INTERLACED_TB] = "interlaced-tb",
339 [V4L2_FIELD_INTERLACED_BT] = "interlaced-bt",
342 #define prt_names(a,arr) (((a)>=0)&&((a)<ARRAY_SIZE(arr)))?arr[a]:"unknown"
344 static void dbgbuf(unsigned int cmd, struct video_device *vfd,
345 struct v4l2_buffer *p)
347 struct v4l2_timecode *tc=&p->timecode;
349 dbgarg (cmd, "%02ld:%02d:%02d.%08ld index=%d, type=%s, "
350 "bytesused=%d, flags=0x%08d, "
351 "field=%0d, sequence=%d, memory=%s, offset/userptr=0x%08lx, length=%d\n",
352 (p->timestamp.tv_sec/3600),
353 (int)(p->timestamp.tv_sec/60)%60,
354 (int)(p->timestamp.tv_sec%60),
355 p->timestamp.tv_usec,
357 prt_names(p->type,v4l2_type_names_FIXME),
358 p->bytesused,p->flags,
359 p->field,p->sequence,
360 prt_names(p->memory,v4l2_memory_names),
361 p->m.userptr, p->length);
362 dbgarg2 ("timecode= %02d:%02d:%02d type=%d, "
363 "flags=0x%08d, frames=%d, userbits=0x%08x\n",
364 tc->hours,tc->minutes,tc->seconds,
365 tc->type, tc->flags, tc->frames, *(__u32 *) tc->userbits);
368 static inline void dbgrect(struct video_device *vfd, char *s,
371 dbgarg2 ("%sRect start at %dx%d, size= %dx%d\n", s, r->left, r->top,
372 r->width, r->height);
375 static inline void v4l_print_pix_fmt (struct video_device *vfd,
376 struct v4l2_pix_format *fmt)
378 dbgarg2 ("width=%d, height=%d, format=%c%c%c%c, field=%s, "
379 "bytesperline=%d sizeimage=%d, colorspace=%d\n",
380 fmt->width,fmt->height,
381 (fmt->pixelformat & 0xff),
382 (fmt->pixelformat >> 8) & 0xff,
383 (fmt->pixelformat >> 16) & 0xff,
384 (fmt->pixelformat >> 24) & 0xff,
385 prt_names(fmt->field,v4l2_field_names_FIXME),
386 fmt->bytesperline,fmt->sizeimage,fmt->colorspace);
390 static int check_fmt (struct video_device *vfd, enum v4l2_buf_type type)
393 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
394 if (vfd->vidioc_try_fmt_cap)
397 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
398 if (vfd->vidioc_try_fmt_overlay)
401 case V4L2_BUF_TYPE_VBI_CAPTURE:
402 if (vfd->vidioc_try_fmt_vbi)
405 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
406 if (vfd->vidioc_try_fmt_vbi_output)
409 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
410 if (vfd->vidioc_try_fmt_vbi_capture)
413 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
414 if (vfd->vidioc_try_fmt_video_output)
417 case V4L2_BUF_TYPE_VBI_OUTPUT:
418 if (vfd->vidioc_try_fmt_vbi_output)
421 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
422 if (vfd->vidioc_try_fmt_output_overlay)
425 case V4L2_BUF_TYPE_PRIVATE:
426 if (vfd->vidioc_try_fmt_type_private)
433 static int __video_do_ioctl(struct inode *inode, struct file *file,
434 unsigned int cmd, void *arg)
436 struct video_device *vfd = video_devdata(file);
437 void *fh = file->private_data;
440 if ( (vfd->debug & V4L2_DEBUG_IOCTL) &&
441 !(vfd->debug & V4L2_DEBUG_IOCTL_ARG)) {
442 v4l_print_ioctl(vfd->name, cmd);
445 #ifdef CONFIG_VIDEO_V4L1_COMPAT
446 /***********************************************************
447 Handles calls to the obsoleted V4L1 API
448 Due to the nature of VIDIOCGMBUF, each driver that supports
449 V4L1 should implement its own handler for this ioctl.
450 ***********************************************************/
452 /* --- streaming capture ------------------------------------- */
453 if (cmd == VIDIOCGMBUF) {
454 struct video_mbuf *p=arg;
456 memset(p, 0, sizeof(*p));
458 if (!vfd->vidiocgmbuf)
460 ret=vfd->vidiocgmbuf(file, fh, p);
462 dbgarg (cmd, "size=%d, frames=%d, offsets=0x%08lx\n",
464 (unsigned long)p->offsets);
468 /********************************************************
469 All other V4L1 calls are handled by v4l1_compat module.
470 Those calls will be translated into V4L2 calls, and
471 __video_do_ioctl will be called again, with one or more
473 ********************************************************/
474 if (_IOC_TYPE(cmd)=='v')
475 return v4l_compat_translate_ioctl(inode,file,cmd,arg,
480 /* --- capabilities ------------------------------------------ */
481 case VIDIOC_QUERYCAP:
483 struct v4l2_capability *cap = (struct v4l2_capability*)arg;
484 memset(cap, 0, sizeof(*cap));
486 if (!vfd->vidioc_querycap)
489 ret=vfd->vidioc_querycap(file, fh, cap);
491 dbgarg (cmd, "driver=%s, card=%s, bus=%s, "
493 "capabilities=0x%08x\n",
494 cap->driver,cap->card,cap->bus_info,
500 /* --- priority ------------------------------------------ */
501 case VIDIOC_G_PRIORITY:
503 enum v4l2_priority *p=arg;
505 if (!vfd->vidioc_g_priority)
507 ret=vfd->vidioc_g_priority(file, fh, p);
509 dbgarg(cmd, "priority is %d\n", *p);
512 case VIDIOC_S_PRIORITY:
514 enum v4l2_priority *p=arg;
516 if (!vfd->vidioc_s_priority)
518 dbgarg(cmd, "setting priority to %d\n", *p);
519 ret=vfd->vidioc_s_priority(file, fh, *p);
523 /* --- capture ioctls ---------------------------------------- */
524 case VIDIOC_ENUM_FMT:
526 struct v4l2_fmtdesc *f = arg;
527 enum v4l2_buf_type type;
532 memset(f,0,sizeof(*f));
537 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
538 if (vfd->vidioc_enum_fmt_cap)
539 ret=vfd->vidioc_enum_fmt_cap(file, fh, f);
541 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
542 if (vfd->vidioc_enum_fmt_overlay)
543 ret=vfd->vidioc_enum_fmt_overlay(file, fh, f);
545 case V4L2_BUF_TYPE_VBI_CAPTURE:
546 if (vfd->vidioc_enum_fmt_vbi)
547 ret=vfd->vidioc_enum_fmt_vbi(file, fh, f);
549 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
550 if (vfd->vidioc_enum_fmt_vbi_output)
551 ret=vfd->vidioc_enum_fmt_vbi_output(file,
554 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
555 if (vfd->vidioc_enum_fmt_vbi_capture)
556 ret=vfd->vidioc_enum_fmt_vbi_capture(file,
559 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
560 if (vfd->vidioc_enum_fmt_video_output)
561 ret=vfd->vidioc_enum_fmt_video_output(file,
564 case V4L2_BUF_TYPE_VBI_OUTPUT:
565 if (vfd->vidioc_enum_fmt_vbi_output)
566 ret=vfd->vidioc_enum_fmt_vbi_output(file,
569 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
570 if (vfd->vidioc_enum_fmt_output_overlay)
571 ret=vfd->vidioc_enum_fmt_output_overlay(file, fh, f);
573 case V4L2_BUF_TYPE_PRIVATE:
574 if (vfd->vidioc_enum_fmt_type_private)
575 ret=vfd->vidioc_enum_fmt_type_private(file,
580 dbgarg (cmd, "index=%d, type=%d, flags=%d, "
581 "pixelformat=%c%c%c%c, description='%s'\n",
582 f->index, f->type, f->flags,
583 (f->pixelformat & 0xff),
584 (f->pixelformat >> 8) & 0xff,
585 (f->pixelformat >> 16) & 0xff,
586 (f->pixelformat >> 24) & 0xff,
592 struct v4l2_format *f = (struct v4l2_format *)arg;
593 enum v4l2_buf_type type=f->type;
595 memset(&f->fmt.pix,0,sizeof(f->fmt.pix));
598 /* FIXME: Should be one dump per type */
599 dbgarg (cmd, "type=%s\n", prt_names(type,
600 v4l2_type_names_FIXME));
603 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
604 if (vfd->vidioc_g_fmt_cap)
605 ret=vfd->vidioc_g_fmt_cap(file, fh, f);
607 v4l_print_pix_fmt(vfd,&f->fmt.pix);
609 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
610 if (vfd->vidioc_g_fmt_overlay)
611 ret=vfd->vidioc_g_fmt_overlay(file, fh, f);
613 case V4L2_BUF_TYPE_VBI_CAPTURE:
614 if (vfd->vidioc_g_fmt_vbi)
615 ret=vfd->vidioc_g_fmt_vbi(file, fh, f);
617 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
618 if (vfd->vidioc_g_fmt_vbi_output)
619 ret=vfd->vidioc_g_fmt_vbi_output(file, fh, f);
621 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
622 if (vfd->vidioc_g_fmt_vbi_capture)
623 ret=vfd->vidioc_g_fmt_vbi_capture(file, fh, f);
625 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
626 if (vfd->vidioc_g_fmt_video_output)
627 ret=vfd->vidioc_g_fmt_video_output(file,
630 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
631 if (vfd->vidioc_g_fmt_output_overlay)
632 ret=vfd->vidioc_g_fmt_output_overlay(file, fh, f);
634 case V4L2_BUF_TYPE_VBI_OUTPUT:
635 if (vfd->vidioc_g_fmt_vbi_output)
636 ret=vfd->vidioc_g_fmt_vbi_output(file, fh, f);
638 case V4L2_BUF_TYPE_PRIVATE:
639 if (vfd->vidioc_g_fmt_type_private)
640 ret=vfd->vidioc_g_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));
656 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
657 v4l_print_pix_fmt(vfd,&f->fmt.pix);
658 if (vfd->vidioc_s_fmt_cap)
659 ret=vfd->vidioc_s_fmt_cap(file, fh, f);
661 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
662 if (vfd->vidioc_s_fmt_overlay)
663 ret=vfd->vidioc_s_fmt_overlay(file, fh, f);
665 case V4L2_BUF_TYPE_VBI_CAPTURE:
666 if (vfd->vidioc_s_fmt_vbi)
667 ret=vfd->vidioc_s_fmt_vbi(file, fh, f);
669 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
670 if (vfd->vidioc_s_fmt_vbi_output)
671 ret=vfd->vidioc_s_fmt_vbi_output(file, fh, f);
673 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
674 if (vfd->vidioc_s_fmt_vbi_capture)
675 ret=vfd->vidioc_s_fmt_vbi_capture(file, fh, f);
677 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
678 if (vfd->vidioc_s_fmt_video_output)
679 ret=vfd->vidioc_s_fmt_video_output(file,
682 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
683 if (vfd->vidioc_s_fmt_output_overlay)
684 ret=vfd->vidioc_s_fmt_output_overlay(file, fh, f);
686 case V4L2_BUF_TYPE_VBI_OUTPUT:
687 if (vfd->vidioc_s_fmt_vbi_output)
688 ret=vfd->vidioc_s_fmt_vbi_output(file,
691 case V4L2_BUF_TYPE_PRIVATE:
692 if (vfd->vidioc_s_fmt_type_private)
693 ret=vfd->vidioc_s_fmt_type_private(file,
701 struct v4l2_format *f = (struct v4l2_format *)arg;
703 /* FIXME: Should be one dump per type */
704 dbgarg (cmd, "type=%s\n", prt_names(f->type,
705 v4l2_type_names_FIXME));
707 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
708 if (vfd->vidioc_try_fmt_cap)
709 ret=vfd->vidioc_try_fmt_cap(file, fh, f);
711 v4l_print_pix_fmt(vfd,&f->fmt.pix);
713 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
714 if (vfd->vidioc_try_fmt_overlay)
715 ret=vfd->vidioc_try_fmt_overlay(file, fh, f);
717 case V4L2_BUF_TYPE_VBI_CAPTURE:
718 if (vfd->vidioc_try_fmt_vbi)
719 ret=vfd->vidioc_try_fmt_vbi(file, fh, f);
721 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
722 if (vfd->vidioc_try_fmt_vbi_output)
723 ret=vfd->vidioc_try_fmt_vbi_output(file,
726 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
727 if (vfd->vidioc_try_fmt_vbi_capture)
728 ret=vfd->vidioc_try_fmt_vbi_capture(file,
731 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
732 if (vfd->vidioc_try_fmt_video_output)
733 ret=vfd->vidioc_try_fmt_video_output(file,
736 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
737 if (vfd->vidioc_try_fmt_output_overlay)
738 ret=vfd->vidioc_try_fmt_output_overlay(file, fh, f);
740 case V4L2_BUF_TYPE_VBI_OUTPUT:
741 if (vfd->vidioc_try_fmt_vbi_output)
742 ret=vfd->vidioc_try_fmt_vbi_output(file,
745 case V4L2_BUF_TYPE_PRIVATE:
746 if (vfd->vidioc_try_fmt_type_private)
747 ret=vfd->vidioc_try_fmt_type_private(file,
754 /* FIXME: Those buf reqs could be handled here,
755 with some changes on videobuf to allow its header to be included at
756 videodev2.h or being merged at videodev2.
760 struct v4l2_requestbuffers *p=arg;
762 if (!vfd->vidioc_reqbufs)
764 ret = check_fmt (vfd, p->type);
768 ret=vfd->vidioc_reqbufs(file, fh, p);
769 dbgarg (cmd, "count=%d, type=%s, memory=%s\n",
771 prt_names(p->type,v4l2_type_names_FIXME),
772 prt_names(p->memory,v4l2_memory_names));
775 case VIDIOC_QUERYBUF:
777 struct v4l2_buffer *p=arg;
779 if (!vfd->vidioc_querybuf)
781 ret = check_fmt (vfd, p->type);
785 ret=vfd->vidioc_querybuf(file, fh, p);
792 struct v4l2_buffer *p=arg;
794 if (!vfd->vidioc_qbuf)
796 ret = check_fmt (vfd, p->type);
800 ret=vfd->vidioc_qbuf(file, fh, p);
807 struct v4l2_buffer *p=arg;
808 if (!vfd->vidioc_dqbuf)
810 ret = check_fmt (vfd, p->type);
814 ret=vfd->vidioc_dqbuf(file, fh, p);
823 if (!vfd->vidioc_overlay)
825 dbgarg (cmd, "value=%d\n",*i);
826 ret=vfd->vidioc_overlay(file, fh, *i);
831 struct v4l2_framebuffer *p=arg;
832 if (!vfd->vidioc_g_fbuf)
834 ret=vfd->vidioc_g_fbuf(file, fh, arg);
836 dbgarg (cmd, "capability=%d, flags=%d, base=0x%08lx\n",
837 p->capability,p->flags,
838 (unsigned long)p->base);
839 v4l_print_pix_fmt (vfd, &p->fmt);
845 struct v4l2_framebuffer *p=arg;
846 if (!vfd->vidioc_s_fbuf)
849 dbgarg (cmd, "capability=%d, flags=%d, base=0x%08lx\n",
850 p->capability,p->flags,(unsigned long)p->base);
851 v4l_print_pix_fmt (vfd, &p->fmt);
852 ret=vfd->vidioc_s_fbuf(file, fh, arg);
856 case VIDIOC_STREAMON:
858 enum v4l2_buf_type i = *(int *)arg;
859 if (!vfd->vidioc_streamon)
861 dbgarg (cmd, "type=%s\n", prt_names(i,v4l2_type_names_FIXME));
862 ret=vfd->vidioc_streamon(file, fh,i);
865 case VIDIOC_STREAMOFF:
867 enum v4l2_buf_type i = *(int *)arg;
869 if (!vfd->vidioc_streamoff)
871 dbgarg (cmd, "type=%s\n", prt_names(i,v4l2_type_names_FIXME));
872 ret=vfd->vidioc_streamoff(file, fh, i);
875 /* ---------- tv norms ---------- */
878 struct v4l2_standard *p = arg;
879 v4l2_std_id id = vfd->tvnorms,curr_id=0;
880 unsigned int index = p->index,i;
887 /* Return norm array on a canonical way */
888 for (i=0;i<= index && id; i++) {
889 if ( (id & V4L2_STD_PAL) == V4L2_STD_PAL) {
890 curr_id = V4L2_STD_PAL;
891 } else if ( (id & V4L2_STD_PAL_BG) == V4L2_STD_PAL_BG) {
892 curr_id = V4L2_STD_PAL_BG;
893 } else if ( (id & V4L2_STD_PAL_DK) == V4L2_STD_PAL_DK) {
894 curr_id = V4L2_STD_PAL_DK;
895 } else if ( (id & V4L2_STD_PAL_B) == V4L2_STD_PAL_B) {
896 curr_id = V4L2_STD_PAL_B;
897 } else if ( (id & V4L2_STD_PAL_B1) == V4L2_STD_PAL_B1) {
898 curr_id = V4L2_STD_PAL_B1;
899 } else if ( (id & V4L2_STD_PAL_G) == V4L2_STD_PAL_G) {
900 curr_id = V4L2_STD_PAL_G;
901 } else if ( (id & V4L2_STD_PAL_H) == V4L2_STD_PAL_H) {
902 curr_id = V4L2_STD_PAL_H;
903 } else if ( (id & V4L2_STD_PAL_I) == V4L2_STD_PAL_I) {
904 curr_id = V4L2_STD_PAL_I;
905 } else if ( (id & V4L2_STD_PAL_D) == V4L2_STD_PAL_D) {
906 curr_id = V4L2_STD_PAL_D;
907 } else if ( (id & V4L2_STD_PAL_D1) == V4L2_STD_PAL_D1) {
908 curr_id = V4L2_STD_PAL_D1;
909 } else if ( (id & V4L2_STD_PAL_K) == V4L2_STD_PAL_K) {
910 curr_id = V4L2_STD_PAL_K;
911 } else if ( (id & V4L2_STD_PAL_M) == V4L2_STD_PAL_M) {
912 curr_id = V4L2_STD_PAL_M;
913 } else if ( (id & V4L2_STD_PAL_N) == V4L2_STD_PAL_N) {
914 curr_id = V4L2_STD_PAL_N;
915 } else if ( (id & V4L2_STD_PAL_Nc) == V4L2_STD_PAL_Nc) {
916 curr_id = V4L2_STD_PAL_Nc;
917 } else if ( (id & V4L2_STD_PAL_60) == V4L2_STD_PAL_60) {
918 curr_id = V4L2_STD_PAL_60;
919 } else if ( (id & V4L2_STD_NTSC) == V4L2_STD_NTSC) {
920 curr_id = V4L2_STD_NTSC;
921 } else if ( (id & V4L2_STD_NTSC_M) == V4L2_STD_NTSC_M) {
922 curr_id = V4L2_STD_NTSC_M;
923 } else if ( (id & V4L2_STD_NTSC_M_JP) == V4L2_STD_NTSC_M_JP) {
924 curr_id = V4L2_STD_NTSC_M_JP;
925 } else if ( (id & V4L2_STD_NTSC_443) == V4L2_STD_NTSC_443) {
926 curr_id = V4L2_STD_NTSC_443;
927 } else if ( (id & V4L2_STD_NTSC_M_KR) == V4L2_STD_NTSC_M_KR) {
928 curr_id = V4L2_STD_NTSC_M_KR;
929 } else if ( (id & V4L2_STD_SECAM) == V4L2_STD_SECAM) {
930 curr_id = V4L2_STD_SECAM;
931 } else if ( (id & V4L2_STD_SECAM_DK) == V4L2_STD_SECAM_DK) {
932 curr_id = V4L2_STD_SECAM_DK;
933 } else if ( (id & V4L2_STD_SECAM_B) == V4L2_STD_SECAM_B) {
934 curr_id = V4L2_STD_SECAM_B;
935 } else if ( (id & V4L2_STD_SECAM_D) == V4L2_STD_SECAM_D) {
936 curr_id = V4L2_STD_SECAM_D;
937 } else if ( (id & V4L2_STD_SECAM_G) == V4L2_STD_SECAM_G) {
938 curr_id = V4L2_STD_SECAM_G;
939 } else if ( (id & V4L2_STD_SECAM_H) == V4L2_STD_SECAM_H) {
940 curr_id = V4L2_STD_SECAM_H;
941 } else if ( (id & V4L2_STD_SECAM_K) == V4L2_STD_SECAM_K) {
942 curr_id = V4L2_STD_SECAM_K;
943 } else if ( (id & V4L2_STD_SECAM_K1) == V4L2_STD_SECAM_K1) {
944 curr_id = V4L2_STD_SECAM_K1;
945 } else if ( (id & V4L2_STD_SECAM_L) == V4L2_STD_SECAM_L) {
946 curr_id = V4L2_STD_SECAM_L;
947 } else if ( (id & V4L2_STD_SECAM_LC) == V4L2_STD_SECAM_LC) {
948 curr_id = V4L2_STD_SECAM_LC;
957 v4l2_video_std_construct(p, curr_id,v4l2_norm_to_name(curr_id));
960 dbgarg (cmd, "index=%d, id=%Ld, name=%s, fps=%d/%d, "
961 "framelines=%d\n", p->index,
962 (unsigned long long)p->id, p->name,
963 p->frameperiod.numerator,
964 p->frameperiod.denominator,
972 v4l2_std_id *id = arg;
974 *id = vfd->current_norm;
976 dbgarg (cmd, "value=%Lu\n", (long long unsigned) *id);
983 v4l2_std_id *id = arg,norm;
985 dbgarg (cmd, "value=%Lu\n", (long long unsigned) *id);
987 norm = (*id) & vfd->tvnorms;
988 if ( vfd->tvnorms && !norm) /* Check if std is supported */
991 /* Calls the specific handler */
992 if (vfd->vidioc_s_std)
993 ret=vfd->vidioc_s_std(file, fh, &norm);
997 /* Updates standard information */
999 vfd->current_norm=norm;
1003 case VIDIOC_QUERYSTD:
1007 if (!vfd->vidioc_querystd)
1009 ret=vfd->vidioc_querystd(file, fh, arg);
1011 dbgarg (cmd, "detected std=%Lu\n",
1012 (unsigned long long)*p);
1015 /* ------ input switching ---------- */
1016 /* FIXME: Inputs can be handled inside videodev2 */
1017 case VIDIOC_ENUMINPUT:
1019 struct v4l2_input *p=arg;
1022 if (!vfd->vidioc_enum_input)
1024 memset(p, 0, sizeof(*p));
1027 ret=vfd->vidioc_enum_input(file, fh, p);
1029 dbgarg (cmd, "index=%d, name=%s, type=%d, "
1031 "tuner=%d, std=%Ld, status=%d\n",
1032 p->index,p->name,p->type,p->audioset,
1034 (unsigned long long)p->std,
1038 case VIDIOC_G_INPUT:
1040 unsigned int *i = arg;
1042 if (!vfd->vidioc_g_input)
1044 ret=vfd->vidioc_g_input(file, fh, i);
1046 dbgarg (cmd, "value=%d\n",*i);
1049 case VIDIOC_S_INPUT:
1051 unsigned int *i = arg;
1053 if (!vfd->vidioc_s_input)
1055 dbgarg (cmd, "value=%d\n",*i);
1056 ret=vfd->vidioc_s_input(file, fh, *i);
1060 /* ------ output switching ---------- */
1061 case VIDIOC_G_OUTPUT:
1063 unsigned int *i = arg;
1065 if (!vfd->vidioc_g_output)
1067 ret=vfd->vidioc_g_output(file, fh, i);
1069 dbgarg (cmd, "value=%d\n",*i);
1072 case VIDIOC_S_OUTPUT:
1074 unsigned int *i = arg;
1076 if (!vfd->vidioc_s_output)
1078 dbgarg (cmd, "value=%d\n",*i);
1079 ret=vfd->vidioc_s_output(file, fh, *i);
1083 /* --- controls ---------------------------------------------- */
1084 case VIDIOC_QUERYCTRL:
1086 struct v4l2_queryctrl *p=arg;
1088 if (!vfd->vidioc_queryctrl)
1090 ret=vfd->vidioc_queryctrl(file, fh, p);
1093 dbgarg (cmd, "id=%d, type=%d, name=%s, "
1095 " step=%d, default=%d, flags=0x%08x\n",
1096 p->id,p->type,p->name,p->minimum,
1097 p->maximum,p->step,p->default_value,
1103 struct v4l2_control *p = arg;
1105 if (!vfd->vidioc_g_ctrl)
1107 dbgarg(cmd, "Enum for index=%d\n", p->id);
1109 ret=vfd->vidioc_g_ctrl(file, fh, p);
1111 dbgarg2 ( "id=%d, value=%d\n", p->id, p->value);
1116 struct v4l2_control *p = arg;
1118 if (!vfd->vidioc_s_ctrl)
1120 dbgarg (cmd, "id=%d, value=%d\n", p->id, p->value);
1122 ret=vfd->vidioc_s_ctrl(file, fh, p);
1125 case VIDIOC_G_EXT_CTRLS:
1127 struct v4l2_ext_controls *p = arg;
1129 if (vfd->vidioc_g_ext_ctrls) {
1130 dbgarg(cmd, "count=%d\n", p->count);
1132 ret=vfd->vidioc_g_ext_ctrls(file, fh, p);
1136 case VIDIOC_S_EXT_CTRLS:
1138 struct v4l2_ext_controls *p = arg;
1140 if (vfd->vidioc_s_ext_ctrls) {
1141 dbgarg(cmd, "count=%d\n", p->count);
1143 ret=vfd->vidioc_s_ext_ctrls(file, fh, p);
1147 case VIDIOC_TRY_EXT_CTRLS:
1149 struct v4l2_ext_controls *p = arg;
1151 if (vfd->vidioc_try_ext_ctrls) {
1152 dbgarg(cmd, "count=%d\n", p->count);
1154 ret=vfd->vidioc_try_ext_ctrls(file, fh, p);
1158 case VIDIOC_QUERYMENU:
1160 struct v4l2_querymenu *p=arg;
1161 if (!vfd->vidioc_querymenu)
1163 ret=vfd->vidioc_querymenu(file, fh, p);
1165 dbgarg (cmd, "id=%d, index=%d, name=%s\n",
1166 p->id,p->index,p->name);
1169 /* --- audio ---------------------------------------------- */
1170 case VIDIOC_ENUMAUDIO:
1172 struct v4l2_audio *p=arg;
1174 if (!vfd->vidioc_enumaudio)
1176 dbgarg(cmd, "Enum for index=%d\n", p->index);
1177 ret=vfd->vidioc_enumaudio(file, fh, p);
1179 dbgarg2("index=%d, name=%s, capability=%d, "
1180 "mode=%d\n",p->index,p->name,
1181 p->capability, p->mode);
1184 case VIDIOC_G_AUDIO:
1186 struct v4l2_audio *p=arg;
1187 __u32 index=p->index;
1189 if (!vfd->vidioc_g_audio)
1192 memset(p,0,sizeof(*p));
1194 dbgarg(cmd, "Get for index=%d\n", p->index);
1195 ret=vfd->vidioc_g_audio(file, fh, p);
1197 dbgarg2("index=%d, name=%s, capability=%d, "
1198 "mode=%d\n",p->index,
1199 p->name,p->capability, p->mode);
1202 case VIDIOC_S_AUDIO:
1204 struct v4l2_audio *p=arg;
1206 if (!vfd->vidioc_s_audio)
1208 dbgarg(cmd, "index=%d, name=%s, capability=%d, "
1209 "mode=%d\n", p->index, p->name,
1210 p->capability, p->mode);
1211 ret=vfd->vidioc_s_audio(file, fh, p);
1214 case VIDIOC_ENUMAUDOUT:
1216 struct v4l2_audioout *p=arg;
1218 if (!vfd->vidioc_enumaudout)
1220 dbgarg(cmd, "Enum for index=%d\n", p->index);
1221 ret=vfd->vidioc_enumaudout(file, fh, p);
1223 dbgarg2("index=%d, name=%s, capability=%d, "
1224 "mode=%d\n", p->index, p->name,
1225 p->capability,p->mode);
1228 case VIDIOC_G_AUDOUT:
1230 struct v4l2_audioout *p=arg;
1232 if (!vfd->vidioc_g_audout)
1234 dbgarg(cmd, "Enum for index=%d\n", p->index);
1235 ret=vfd->vidioc_g_audout(file, fh, p);
1237 dbgarg2("index=%d, name=%s, capability=%d, "
1238 "mode=%d\n", p->index, p->name,
1239 p->capability,p->mode);
1242 case VIDIOC_S_AUDOUT:
1244 struct v4l2_audioout *p=arg;
1246 if (!vfd->vidioc_s_audout)
1248 dbgarg(cmd, "index=%d, name=%s, capability=%d, "
1249 "mode=%d\n", p->index, p->name,
1250 p->capability,p->mode);
1252 ret=vfd->vidioc_s_audout(file, fh, p);
1255 case VIDIOC_G_MODULATOR:
1257 struct v4l2_modulator *p=arg;
1258 if (!vfd->vidioc_g_modulator)
1260 ret=vfd->vidioc_g_modulator(file, fh, p);
1262 dbgarg(cmd, "index=%d, name=%s, "
1263 "capability=%d, rangelow=%d,"
1264 " rangehigh=%d, txsubchans=%d\n",
1265 p->index, p->name,p->capability,
1266 p->rangelow, p->rangehigh,
1270 case VIDIOC_S_MODULATOR:
1272 struct v4l2_modulator *p=arg;
1273 if (!vfd->vidioc_s_modulator)
1275 dbgarg(cmd, "index=%d, name=%s, capability=%d, "
1276 "rangelow=%d, rangehigh=%d, txsubchans=%d\n",
1277 p->index, p->name,p->capability,p->rangelow,
1278 p->rangehigh,p->txsubchans);
1279 ret=vfd->vidioc_s_modulator(file, fh, p);
1284 struct v4l2_crop *p=arg;
1285 if (!vfd->vidioc_g_crop)
1287 ret=vfd->vidioc_g_crop(file, fh, p);
1289 dbgarg(cmd, "type=%d\n", p->type);
1290 dbgrect(vfd, "", &p->c);
1296 struct v4l2_crop *p=arg;
1297 if (!vfd->vidioc_s_crop)
1299 dbgarg(cmd, "type=%d\n", p->type);
1300 dbgrect(vfd, "", &p->c);
1301 ret=vfd->vidioc_s_crop(file, fh, p);
1304 case VIDIOC_CROPCAP:
1306 struct v4l2_cropcap *p=arg;
1307 /*FIXME: Should also show v4l2_fract pixelaspect */
1308 if (!vfd->vidioc_cropcap)
1310 dbgarg(cmd, "type=%d\n", p->type);
1311 dbgrect(vfd, "bounds ", &p->bounds);
1312 dbgrect(vfd, "defrect ", &p->defrect);
1313 ret=vfd->vidioc_cropcap(file, fh, p);
1316 case VIDIOC_G_MPEGCOMP:
1318 struct v4l2_mpeg_compression *p=arg;
1320 /*FIXME: Several fields not shown */
1321 if (!vfd->vidioc_g_mpegcomp)
1323 ret=vfd->vidioc_g_mpegcomp(file, fh, p);
1325 dbgarg (cmd, "ts_pid_pmt=%d, ts_pid_audio=%d,"
1326 " ts_pid_video=%d, ts_pid_pcr=%d, "
1327 "ps_size=%d, au_sample_rate=%d, "
1328 "au_pesid=%c, vi_frame_rate=%d, "
1329 "vi_frames_per_gop=%d, "
1330 "vi_bframes_count=%d, vi_pesid=%c\n",
1331 p->ts_pid_pmt,p->ts_pid_audio,
1332 p->ts_pid_video,p->ts_pid_pcr,
1333 p->ps_size, p->au_sample_rate,
1334 p->au_pesid, p->vi_frame_rate,
1335 p->vi_frames_per_gop,
1336 p->vi_bframes_count, p->vi_pesid);
1339 case VIDIOC_S_MPEGCOMP:
1341 struct v4l2_mpeg_compression *p=arg;
1342 /*FIXME: Several fields not shown */
1343 if (!vfd->vidioc_s_mpegcomp)
1345 dbgarg (cmd, "ts_pid_pmt=%d, ts_pid_audio=%d, "
1346 "ts_pid_video=%d, ts_pid_pcr=%d, ps_size=%d, "
1347 "au_sample_rate=%d, au_pesid=%c, "
1348 "vi_frame_rate=%d, vi_frames_per_gop=%d, "
1349 "vi_bframes_count=%d, vi_pesid=%c\n",
1350 p->ts_pid_pmt,p->ts_pid_audio, p->ts_pid_video,
1351 p->ts_pid_pcr, p->ps_size, p->au_sample_rate,
1352 p->au_pesid, p->vi_frame_rate,
1353 p->vi_frames_per_gop, p->vi_bframes_count,
1355 ret=vfd->vidioc_s_mpegcomp(file, fh, p);
1358 case VIDIOC_G_JPEGCOMP:
1360 struct v4l2_jpegcompression *p=arg;
1361 if (!vfd->vidioc_g_jpegcomp)
1363 ret=vfd->vidioc_g_jpegcomp(file, fh, p);
1365 dbgarg (cmd, "quality=%d, APPn=%d, "
1366 "APP_len=%d, COM_len=%d, "
1367 "jpeg_markers=%d\n",
1368 p->quality,p->APPn,p->APP_len,
1369 p->COM_len,p->jpeg_markers);
1372 case VIDIOC_S_JPEGCOMP:
1374 struct v4l2_jpegcompression *p=arg;
1375 if (!vfd->vidioc_g_jpegcomp)
1377 dbgarg (cmd, "quality=%d, APPn=%d, APP_len=%d, "
1378 "COM_len=%d, jpeg_markers=%d\n",
1379 p->quality,p->APPn,p->APP_len,
1380 p->COM_len,p->jpeg_markers);
1381 ret=vfd->vidioc_s_jpegcomp(file, fh, p);
1384 case VIDIOC_G_ENC_INDEX:
1386 struct v4l2_enc_idx *p=arg;
1388 if (!vfd->vidioc_g_enc_index)
1390 ret=vfd->vidioc_g_enc_index(file, fh, p);
1392 dbgarg (cmd, "entries=%d, entries_cap=%d\n",
1393 p->entries,p->entries_cap);
1396 case VIDIOC_ENCODER_CMD:
1398 struct v4l2_encoder_cmd *p=arg;
1400 if (!vfd->vidioc_encoder_cmd)
1402 ret=vfd->vidioc_encoder_cmd(file, fh, p);
1404 dbgarg (cmd, "cmd=%d, flags=%d\n",
1408 case VIDIOC_TRY_ENCODER_CMD:
1410 struct v4l2_encoder_cmd *p=arg;
1412 if (!vfd->vidioc_try_encoder_cmd)
1414 ret=vfd->vidioc_try_encoder_cmd(file, fh, p);
1416 dbgarg (cmd, "cmd=%d, flags=%d\n",
1422 struct v4l2_streamparm *p=arg;
1425 memset(p,0,sizeof(*p));
1428 if (vfd->vidioc_g_parm) {
1429 ret=vfd->vidioc_g_parm(file, fh, p);
1431 struct v4l2_standard s;
1433 if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1436 v4l2_video_std_construct(&s, vfd->current_norm,
1437 v4l2_norm_to_name(vfd->current_norm));
1439 p->parm.capture.timeperframe = s.frameperiod;
1443 dbgarg (cmd, "type=%d\n", p->type);
1448 struct v4l2_streamparm *p=arg;
1449 if (!vfd->vidioc_s_parm)
1451 dbgarg (cmd, "type=%d\n", p->type);
1452 ret=vfd->vidioc_s_parm(file, fh, p);
1455 case VIDIOC_G_TUNER:
1457 struct v4l2_tuner *p=arg;
1458 __u32 index=p->index;
1460 if (!vfd->vidioc_g_tuner)
1463 memset(p,0,sizeof(*p));
1466 ret=vfd->vidioc_g_tuner(file, fh, p);
1468 dbgarg (cmd, "index=%d, name=%s, type=%d, "
1469 "capability=%d, rangelow=%d, "
1470 "rangehigh=%d, signal=%d, afc=%d, "
1471 "rxsubchans=%d, audmode=%d\n",
1472 p->index, p->name, p->type,
1473 p->capability, p->rangelow,
1474 p->rangehigh, p->rxsubchans,
1475 p->audmode, p->signal, p->afc);
1478 case VIDIOC_S_TUNER:
1480 struct v4l2_tuner *p=arg;
1481 if (!vfd->vidioc_s_tuner)
1483 dbgarg (cmd, "index=%d, name=%s, type=%d, "
1484 "capability=%d, rangelow=%d, rangehigh=%d, "
1485 "signal=%d, afc=%d, rxsubchans=%d, "
1486 "audmode=%d\n",p->index, p->name, p->type,
1487 p->capability, p->rangelow,p->rangehigh,
1488 p->rxsubchans, p->audmode, p->signal,
1490 ret=vfd->vidioc_s_tuner(file, fh, p);
1493 case VIDIOC_G_FREQUENCY:
1495 struct v4l2_frequency *p=arg;
1496 if (!vfd->vidioc_g_frequency)
1499 memset(p,0,sizeof(*p));
1501 ret=vfd->vidioc_g_frequency(file, fh, p);
1503 dbgarg (cmd, "tuner=%d, type=%d, frequency=%d\n",
1504 p->tuner,p->type,p->frequency);
1507 case VIDIOC_S_FREQUENCY:
1509 struct v4l2_frequency *p=arg;
1510 if (!vfd->vidioc_s_frequency)
1512 dbgarg (cmd, "tuner=%d, type=%d, frequency=%d\n",
1513 p->tuner,p->type,p->frequency);
1514 ret=vfd->vidioc_s_frequency(file, fh, p);
1517 case VIDIOC_G_SLICED_VBI_CAP:
1519 struct v4l2_sliced_vbi_cap *p=arg;
1520 if (!vfd->vidioc_g_sliced_vbi_cap)
1522 ret=vfd->vidioc_g_sliced_vbi_cap(file, fh, p);
1524 dbgarg (cmd, "service_set=%d\n", p->service_set);
1527 case VIDIOC_LOG_STATUS:
1529 if (!vfd->vidioc_log_status)
1531 ret=vfd->vidioc_log_status(file, fh);
1534 #ifdef CONFIG_VIDEO_ADV_DEBUG
1535 case VIDIOC_DBG_G_REGISTER:
1537 struct v4l2_register *p=arg;
1538 if (!capable(CAP_SYS_ADMIN))
1540 else if (vfd->vidioc_g_register)
1541 ret=vfd->vidioc_g_register(file, fh, p);
1544 case VIDIOC_DBG_S_REGISTER:
1546 struct v4l2_register *p=arg;
1547 if (!capable(CAP_SYS_ADMIN))
1549 else if (vfd->vidioc_s_register)
1550 ret=vfd->vidioc_s_register(file, fh, p);
1554 case VIDIOC_G_CHIP_IDENT:
1556 struct v4l2_chip_ident *p=arg;
1557 if (!vfd->vidioc_g_chip_ident)
1559 ret=vfd->vidioc_g_chip_ident(file, fh, p);
1561 dbgarg (cmd, "chip_ident=%u, revision=0x%x\n", p->ident, p->revision);
1566 if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) {
1568 printk ("%s: err:\n", vfd->name);
1569 v4l_print_ioctl(vfd->name, cmd);
1576 int video_ioctl2 (struct inode *inode, struct file *file,
1577 unsigned int cmd, unsigned long arg)
1584 size_t ctrls_size = 0;
1585 void __user *user_ptr = NULL;
1587 #ifdef __OLD_VIDIOC_
1588 cmd = video_fix_command(cmd);
1590 is_ext_ctrl = (cmd == VIDIOC_S_EXT_CTRLS || cmd == VIDIOC_G_EXT_CTRLS ||
1591 cmd == VIDIOC_TRY_EXT_CTRLS);
1593 /* Copy arguments into temp kernel buffer */
1594 switch (_IOC_DIR(cmd)) {
1600 case (_IOC_WRITE | _IOC_READ):
1601 if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
1604 /* too big to allocate from stack */
1605 mbuf = kmalloc(_IOC_SIZE(cmd),GFP_KERNEL);
1612 if (_IOC_DIR(cmd) & _IOC_WRITE)
1613 if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd)))
1619 struct v4l2_ext_controls *p = parg;
1621 /* In case of an error, tell the caller that it wasn't
1622 a specific control that caused it. */
1623 p->error_idx = p->count;
1624 user_ptr = (void __user *)p->controls;
1626 ctrls_size = sizeof(struct v4l2_ext_control) * p->count;
1627 /* Note: v4l2_ext_controls fits in sbuf[] so mbuf is still NULL. */
1628 mbuf = kmalloc(ctrls_size, GFP_KERNEL);
1633 if (copy_from_user(mbuf, user_ptr, ctrls_size))
1640 err = __video_do_ioctl(inode, file, cmd, parg);
1641 if (err == -ENOIOCTLCMD)
1644 struct v4l2_ext_controls *p = parg;
1646 p->controls = (void *)user_ptr;
1647 if (p->count && err == 0 && copy_to_user(user_ptr, mbuf, ctrls_size))
1655 /* Copy results into user buffer */
1656 switch (_IOC_DIR(cmd))
1659 case (_IOC_WRITE | _IOC_READ):
1660 if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd)))
1671 static const struct file_operations video_fops;
1674 * video_register_device - register video4linux devices
1675 * @vfd: video device structure we want to register
1676 * @type: type of device to register
1677 * @nr: which device number (0 == /dev/video0, 1 == /dev/video1, ...
1680 * The registration code assigns minor numbers based on the type
1681 * requested. -ENFILE is returned in all the device slots for this
1682 * category are full. If not then the minor field is set and the
1683 * driver initialize function is called (if non %NULL).
1685 * Zero is returned on success.
1689 * %VFL_TYPE_GRABBER - A frame grabber
1691 * %VFL_TYPE_VTX - A teletext device
1693 * %VFL_TYPE_VBI - Vertical blank data (undecoded)
1695 * %VFL_TYPE_RADIO - A radio card
1698 int video_register_device(struct video_device *vfd, int type, int nr)
1708 case VFL_TYPE_GRABBER:
1709 base=MINOR_VFL_TYPE_GRABBER_MIN;
1710 end=MINOR_VFL_TYPE_GRABBER_MAX+1;
1711 name_base = "video";
1714 base=MINOR_VFL_TYPE_VTX_MIN;
1715 end=MINOR_VFL_TYPE_VTX_MAX+1;
1719 base=MINOR_VFL_TYPE_VBI_MIN;
1720 end=MINOR_VFL_TYPE_VBI_MAX+1;
1723 case VFL_TYPE_RADIO:
1724 base=MINOR_VFL_TYPE_RADIO_MIN;
1725 end=MINOR_VFL_TYPE_RADIO_MAX+1;
1726 name_base = "radio";
1729 printk(KERN_ERR "%s called with unknown type: %d\n",
1730 __FUNCTION__, type);
1734 /* pick a minor number */
1735 mutex_lock(&videodev_lock);
1736 if (nr >= 0 && nr < end-base) {
1737 /* use the one the driver asked for */
1739 if (NULL != video_device[i]) {
1740 mutex_unlock(&videodev_lock);
1744 /* use first free */
1745 for(i=base;i<end;i++)
1746 if (NULL == video_device[i])
1749 mutex_unlock(&videodev_lock);
1753 video_device[i]=vfd;
1755 mutex_unlock(&videodev_lock);
1756 mutex_init(&vfd->lock);
1759 memset(&vfd->class_dev, 0x00, sizeof(vfd->class_dev));
1761 vfd->class_dev.parent = vfd->dev;
1762 vfd->class_dev.class = &video_class;
1763 vfd->class_dev.devt = MKDEV(VIDEO_MAJOR, vfd->minor);
1764 sprintf(vfd->class_dev.bus_id, "%s%d", name_base, i - base);
1765 ret = device_register(&vfd->class_dev);
1767 printk(KERN_ERR "%s: device_register failed\n",
1773 /* needed until all drivers are fixed */
1775 printk(KERN_WARNING "videodev: \"%s\" has no release callback. "
1776 "Please fix your driver for proper sysfs support, see "
1777 "http://lwn.net/Articles/36850/\n", vfd->name);
1782 mutex_lock(&videodev_lock);
1783 video_device[vfd->minor] = NULL;
1785 mutex_unlock(&videodev_lock);
1790 * video_unregister_device - unregister a video4linux device
1791 * @vfd: the device to unregister
1793 * This unregisters the passed device and deassigns the minor
1794 * number. Future open calls will be met with errors.
1797 void video_unregister_device(struct video_device *vfd)
1799 mutex_lock(&videodev_lock);
1800 if(video_device[vfd->minor]!=vfd)
1801 panic("videodev: bad unregister");
1803 video_device[vfd->minor]=NULL;
1804 device_unregister(&vfd->class_dev);
1805 mutex_unlock(&videodev_lock);
1809 * Video fs operations
1811 static const struct file_operations video_fops=
1813 .owner = THIS_MODULE,
1814 .llseek = no_llseek,
1819 * Initialise video for linux
1822 static int __init videodev_init(void)
1826 printk(KERN_INFO "Linux video capture interface: v2.00\n");
1827 if (register_chrdev(VIDEO_MAJOR, VIDEO_NAME, &video_fops)) {
1828 printk(KERN_WARNING "video_dev: unable to get major %d\n", VIDEO_MAJOR);
1832 ret = class_register(&video_class);
1834 unregister_chrdev(VIDEO_MAJOR, VIDEO_NAME);
1835 printk(KERN_WARNING "video_dev: class_register failed\n");
1842 static void __exit videodev_exit(void)
1844 class_unregister(&video_class);
1845 unregister_chrdev(VIDEO_MAJOR, VIDEO_NAME);
1848 module_init(videodev_init)
1849 module_exit(videodev_exit)
1851 EXPORT_SYMBOL(video_register_device);
1852 EXPORT_SYMBOL(video_unregister_device);
1853 EXPORT_SYMBOL(video_devdata);
1854 EXPORT_SYMBOL(video_usercopy);
1855 EXPORT_SYMBOL(video_exclusive_open);
1856 EXPORT_SYMBOL(video_exclusive_release);
1857 EXPORT_SYMBOL(video_ioctl2);
1858 EXPORT_SYMBOL(video_device_alloc);
1859 EXPORT_SYMBOL(video_device_release);
1861 MODULE_AUTHOR("Alan Cox, Mauro Carvalho Chehab <mchehab@infradead.org>");
1862 MODULE_DESCRIPTION("Device registrar for Video4Linux drivers v2");
1863 MODULE_LICENSE("GPL");