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 class_device *cd, char *buf)
59 struct video_device *vfd = container_of(cd, struct video_device,
61 return sprintf(buf,"%.*s\n",(int)sizeof(vfd->name),vfd->name);
64 static CLASS_DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
66 struct video_device *video_device_alloc(void)
68 struct video_device *vfd;
70 vfd = kzalloc(sizeof(*vfd),GFP_KERNEL);
74 void video_device_release(struct video_device *vfd)
79 static void video_release(struct class_device *cd)
81 struct video_device *vfd = container_of(cd, struct video_device,
85 /* needed until all drivers are fixed */
92 static struct class video_class = {
94 .release = video_release,
101 static struct video_device *video_device[VIDEO_NUM_DEVICES];
102 static DEFINE_MUTEX(videodev_lock);
104 struct video_device* video_devdata(struct file *file)
106 return video_device[iminor(file->f_path.dentry->d_inode)];
110 * Open a video device - FIXME: Obsoleted
112 static int video_open(struct inode *inode, struct file *file)
114 unsigned int minor = iminor(inode);
116 struct video_device *vfl;
117 const struct file_operations *old_fops;
119 if(minor>=VIDEO_NUM_DEVICES)
121 mutex_lock(&videodev_lock);
122 vfl=video_device[minor];
124 mutex_unlock(&videodev_lock);
125 request_module("char-major-%d-%d", VIDEO_MAJOR, minor);
126 mutex_lock(&videodev_lock);
127 vfl=video_device[minor];
129 mutex_unlock(&videodev_lock);
133 old_fops = file->f_op;
134 file->f_op = fops_get(vfl->fops);
136 err = file->f_op->open(inode,file);
138 fops_put(file->f_op);
139 file->f_op = fops_get(old_fops);
142 mutex_unlock(&videodev_lock);
147 * helper function -- handles userspace copying for ioctl arguments
152 video_fix_command(unsigned int cmd)
155 case VIDIOC_OVERLAY_OLD:
156 cmd = VIDIOC_OVERLAY;
158 case VIDIOC_S_PARM_OLD:
161 case VIDIOC_S_CTRL_OLD:
164 case VIDIOC_G_AUDIO_OLD:
165 cmd = VIDIOC_G_AUDIO;
167 case VIDIOC_G_AUDOUT_OLD:
168 cmd = VIDIOC_G_AUDOUT;
170 case VIDIOC_CROPCAP_OLD:
171 cmd = VIDIOC_CROPCAP;
179 * Obsolete usercopy function - Should be removed soon
182 video_usercopy(struct inode *inode, struct file *file,
183 unsigned int cmd, unsigned long arg,
184 int (*func)(struct inode *inode, struct file *file,
185 unsigned int cmd, void *arg))
192 size_t ctrls_size = 0;
193 void __user *user_ptr = NULL;
196 cmd = video_fix_command(cmd);
198 is_ext_ctrl = (cmd == VIDIOC_S_EXT_CTRLS || cmd == VIDIOC_G_EXT_CTRLS ||
199 cmd == VIDIOC_TRY_EXT_CTRLS);
201 /* Copy arguments into temp kernel buffer */
202 switch (_IOC_DIR(cmd)) {
208 case (_IOC_WRITE | _IOC_READ):
209 if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
212 /* too big to allocate from stack */
213 mbuf = kmalloc(_IOC_SIZE(cmd),GFP_KERNEL);
220 if (_IOC_DIR(cmd) & _IOC_WRITE)
221 if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd)))
226 struct v4l2_ext_controls *p = parg;
228 /* In case of an error, tell the caller that it wasn't
229 a specific control that caused it. */
230 p->error_idx = p->count;
231 user_ptr = (void __user *)p->controls;
233 ctrls_size = sizeof(struct v4l2_ext_control) * p->count;
234 /* Note: v4l2_ext_controls fits in sbuf[] so mbuf is still NULL. */
235 mbuf = kmalloc(ctrls_size, GFP_KERNEL);
240 if (copy_from_user(mbuf, user_ptr, ctrls_size))
247 err = func(inode, file, cmd, parg);
248 if (err == -ENOIOCTLCMD)
251 struct v4l2_ext_controls *p = parg;
253 p->controls = (void *)user_ptr;
254 if (p->count && err == 0 && copy_to_user(user_ptr, mbuf, ctrls_size))
262 /* Copy results into user buffer */
263 switch (_IOC_DIR(cmd))
266 case (_IOC_WRITE | _IOC_READ):
267 if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd)))
278 * open/release helper functions -- handle exclusive opens
279 * Should be removed soon
281 int video_exclusive_open(struct inode *inode, struct file *file)
283 struct video_device *vfl = video_devdata(file);
286 mutex_lock(&vfl->lock);
292 mutex_unlock(&vfl->lock);
296 int video_exclusive_release(struct inode *inode, struct file *file)
298 struct video_device *vfl = video_devdata(file);
304 static char *v4l2_memory_names[] = {
305 [V4L2_MEMORY_MMAP] = "mmap",
306 [V4L2_MEMORY_USERPTR] = "userptr",
307 [V4L2_MEMORY_OVERLAY] = "overlay",
311 /* FIXME: Those stuff are replicated also on v4l2-common.c */
312 static char *v4l2_type_names_FIXME[] = {
313 [V4L2_BUF_TYPE_VIDEO_CAPTURE] = "video-cap",
314 [V4L2_BUF_TYPE_VIDEO_OVERLAY] = "video-over",
315 [V4L2_BUF_TYPE_VIDEO_OUTPUT] = "video-out",
316 [V4L2_BUF_TYPE_VBI_CAPTURE] = "vbi-cap",
317 [V4L2_BUF_TYPE_VBI_OUTPUT] = "vbi-out",
318 [V4L2_BUF_TYPE_SLICED_VBI_OUTPUT] = "sliced-vbi-out",
319 [V4L2_BUF_TYPE_SLICED_VBI_CAPTURE] = "sliced-vbi-capture",
320 [V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY] = "video-out-over",
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",
333 [V4L2_FIELD_INTERLACED_TB] = "interlaced-tb",
334 [V4L2_FIELD_INTERLACED_BT] = "interlaced-bt",
337 #define prt_names(a,arr) (((a)>=0)&&((a)<ARRAY_SIZE(arr)))?arr[a]:"unknown"
339 static void dbgbuf(unsigned int cmd, struct video_device *vfd,
340 struct v4l2_buffer *p)
342 struct v4l2_timecode *tc=&p->timecode;
344 dbgarg (cmd, "%02ld:%02d:%02d.%08ld index=%d, type=%s, "
345 "bytesused=%d, flags=0x%08d, "
346 "field=%0d, sequence=%d, memory=%s, offset/userptr=0x%08lx, length=%d\n",
347 (p->timestamp.tv_sec/3600),
348 (int)(p->timestamp.tv_sec/60)%60,
349 (int)(p->timestamp.tv_sec%60),
350 p->timestamp.tv_usec,
352 prt_names(p->type,v4l2_type_names_FIXME),
353 p->bytesused,p->flags,
354 p->field,p->sequence,
355 prt_names(p->memory,v4l2_memory_names),
356 p->m.userptr, p->length);
357 dbgarg2 ("timecode= %02d:%02d:%02d type=%d, "
358 "flags=0x%08d, frames=%d, userbits=0x%08x\n",
359 tc->hours,tc->minutes,tc->seconds,
360 tc->type, tc->flags, tc->frames, *(__u32 *) tc->userbits);
363 static inline void dbgrect(struct video_device *vfd, char *s,
366 dbgarg2 ("%sRect start at %dx%d, size= %dx%d\n", s, r->left, r->top,
367 r->width, r->height);
370 static inline void v4l_print_pix_fmt (struct video_device *vfd,
371 struct v4l2_pix_format *fmt)
373 dbgarg2 ("width=%d, height=%d, format=%c%c%c%c, field=%s, "
374 "bytesperline=%d sizeimage=%d, colorspace=%d\n",
375 fmt->width,fmt->height,
376 (fmt->pixelformat & 0xff),
377 (fmt->pixelformat >> 8) & 0xff,
378 (fmt->pixelformat >> 16) & 0xff,
379 (fmt->pixelformat >> 24) & 0xff,
380 prt_names(fmt->field,v4l2_field_names_FIXME),
381 fmt->bytesperline,fmt->sizeimage,fmt->colorspace);
385 static int check_fmt (struct video_device *vfd, enum v4l2_buf_type type)
388 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
389 if (vfd->vidioc_try_fmt_cap)
392 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
393 if (vfd->vidioc_try_fmt_overlay)
396 case V4L2_BUF_TYPE_VBI_CAPTURE:
397 if (vfd->vidioc_try_fmt_vbi)
400 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
401 if (vfd->vidioc_try_fmt_vbi_output)
404 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
405 if (vfd->vidioc_try_fmt_vbi_capture)
408 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
409 if (vfd->vidioc_try_fmt_video_output)
412 case V4L2_BUF_TYPE_VBI_OUTPUT:
413 if (vfd->vidioc_try_fmt_vbi_output)
416 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
417 if (vfd->vidioc_try_fmt_output_overlay)
420 case V4L2_BUF_TYPE_PRIVATE:
421 if (vfd->vidioc_try_fmt_type_private)
428 static int __video_do_ioctl(struct inode *inode, struct file *file,
429 unsigned int cmd, void *arg)
431 struct video_device *vfd = video_devdata(file);
432 void *fh = file->private_data;
435 if ( (vfd->debug & V4L2_DEBUG_IOCTL) &&
436 !(vfd->debug | V4L2_DEBUG_IOCTL_ARG)) {
437 v4l_print_ioctl(vfd->name, cmd);
440 if (_IOC_TYPE(cmd)=='v')
441 return v4l_compat_translate_ioctl(inode,file,cmd,arg,
445 /* --- capabilities ------------------------------------------ */
446 case VIDIOC_QUERYCAP:
448 struct v4l2_capability *cap = (struct v4l2_capability*)arg;
449 memset(cap, 0, sizeof(*cap));
451 if (!vfd->vidioc_querycap)
454 ret=vfd->vidioc_querycap(file, fh, cap);
456 dbgarg (cmd, "driver=%s, card=%s, bus=%s, "
458 "capabilities=0x%08x\n",
459 cap->driver,cap->card,cap->bus_info,
465 /* --- priority ------------------------------------------ */
466 case VIDIOC_G_PRIORITY:
468 enum v4l2_priority *p=arg;
470 if (!vfd->vidioc_g_priority)
472 ret=vfd->vidioc_g_priority(file, fh, p);
474 dbgarg(cmd, "priority is %d\n", *p);
477 case VIDIOC_S_PRIORITY:
479 enum v4l2_priority *p=arg;
481 if (!vfd->vidioc_s_priority)
483 dbgarg(cmd, "setting priority to %d\n", *p);
484 ret=vfd->vidioc_s_priority(file, fh, *p);
488 /* --- capture ioctls ---------------------------------------- */
489 case VIDIOC_ENUM_FMT:
491 struct v4l2_fmtdesc *f = arg;
492 enum v4l2_buf_type type;
497 memset(f,0,sizeof(*f));
502 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
503 if (vfd->vidioc_enum_fmt_cap)
504 ret=vfd->vidioc_enum_fmt_cap(file, fh, f);
506 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
507 if (vfd->vidioc_enum_fmt_overlay)
508 ret=vfd->vidioc_enum_fmt_overlay(file, fh, f);
510 case V4L2_BUF_TYPE_VBI_CAPTURE:
511 if (vfd->vidioc_enum_fmt_vbi)
512 ret=vfd->vidioc_enum_fmt_vbi(file, fh, f);
514 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
515 if (vfd->vidioc_enum_fmt_vbi_output)
516 ret=vfd->vidioc_enum_fmt_vbi_output(file,
519 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
520 if (vfd->vidioc_enum_fmt_vbi_capture)
521 ret=vfd->vidioc_enum_fmt_vbi_capture(file,
524 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
525 if (vfd->vidioc_enum_fmt_video_output)
526 ret=vfd->vidioc_enum_fmt_video_output(file,
529 case V4L2_BUF_TYPE_VBI_OUTPUT:
530 if (vfd->vidioc_enum_fmt_vbi_output)
531 ret=vfd->vidioc_enum_fmt_vbi_output(file,
534 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
535 if (vfd->vidioc_enum_fmt_output_overlay)
536 ret=vfd->vidioc_enum_fmt_output_overlay(file, fh, f);
538 case V4L2_BUF_TYPE_PRIVATE:
539 if (vfd->vidioc_enum_fmt_type_private)
540 ret=vfd->vidioc_enum_fmt_type_private(file,
545 dbgarg (cmd, "index=%d, type=%d, flags=%d, "
546 "pixelformat=%c%c%c%c, description='%s'\n",
547 f->index, f->type, f->flags,
548 (f->pixelformat & 0xff),
549 (f->pixelformat >> 8) & 0xff,
550 (f->pixelformat >> 16) & 0xff,
551 (f->pixelformat >> 24) & 0xff,
557 struct v4l2_format *f = (struct v4l2_format *)arg;
558 enum v4l2_buf_type type=f->type;
560 memset(&f->fmt.pix,0,sizeof(f->fmt.pix));
563 /* FIXME: Should be one dump per type */
564 dbgarg (cmd, "type=%s\n", prt_names(type,
565 v4l2_type_names_FIXME));
568 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
569 if (vfd->vidioc_g_fmt_cap)
570 ret=vfd->vidioc_g_fmt_cap(file, fh, f);
572 v4l_print_pix_fmt(vfd,&f->fmt.pix);
574 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
575 if (vfd->vidioc_g_fmt_overlay)
576 ret=vfd->vidioc_g_fmt_overlay(file, fh, f);
578 case V4L2_BUF_TYPE_VBI_CAPTURE:
579 if (vfd->vidioc_g_fmt_vbi)
580 ret=vfd->vidioc_g_fmt_vbi(file, fh, f);
582 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
583 if (vfd->vidioc_g_fmt_vbi_output)
584 ret=vfd->vidioc_g_fmt_vbi_output(file, fh, f);
586 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
587 if (vfd->vidioc_g_fmt_vbi_capture)
588 ret=vfd->vidioc_g_fmt_vbi_capture(file, fh, f);
590 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
591 if (vfd->vidioc_g_fmt_video_output)
592 ret=vfd->vidioc_g_fmt_video_output(file,
595 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
596 if (vfd->vidioc_g_fmt_output_overlay)
597 ret=vfd->vidioc_g_fmt_output_overlay(file, fh, f);
599 case V4L2_BUF_TYPE_VBI_OUTPUT:
600 if (vfd->vidioc_g_fmt_vbi_output)
601 ret=vfd->vidioc_g_fmt_vbi_output(file, fh, f);
603 case V4L2_BUF_TYPE_PRIVATE:
604 if (vfd->vidioc_g_fmt_type_private)
605 ret=vfd->vidioc_g_fmt_type_private(file,
614 struct v4l2_format *f = (struct v4l2_format *)arg;
616 /* FIXME: Should be one dump per type */
617 dbgarg (cmd, "type=%s\n", prt_names(f->type,
618 v4l2_type_names_FIXME));
621 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
622 v4l_print_pix_fmt(vfd,&f->fmt.pix);
623 if (vfd->vidioc_s_fmt_cap)
624 ret=vfd->vidioc_s_fmt_cap(file, fh, f);
626 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
627 if (vfd->vidioc_s_fmt_overlay)
628 ret=vfd->vidioc_s_fmt_overlay(file, fh, f);
630 case V4L2_BUF_TYPE_VBI_CAPTURE:
631 if (vfd->vidioc_s_fmt_vbi)
632 ret=vfd->vidioc_s_fmt_vbi(file, fh, f);
634 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
635 if (vfd->vidioc_s_fmt_vbi_output)
636 ret=vfd->vidioc_s_fmt_vbi_output(file, fh, f);
638 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
639 if (vfd->vidioc_s_fmt_vbi_capture)
640 ret=vfd->vidioc_s_fmt_vbi_capture(file, fh, f);
642 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
643 if (vfd->vidioc_s_fmt_video_output)
644 ret=vfd->vidioc_s_fmt_video_output(file,
647 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
648 if (vfd->vidioc_s_fmt_output_overlay)
649 ret=vfd->vidioc_s_fmt_output_overlay(file, fh, f);
651 case V4L2_BUF_TYPE_VBI_OUTPUT:
652 if (vfd->vidioc_s_fmt_vbi_output)
653 ret=vfd->vidioc_s_fmt_vbi_output(file,
656 case V4L2_BUF_TYPE_PRIVATE:
657 if (vfd->vidioc_s_fmt_type_private)
658 ret=vfd->vidioc_s_fmt_type_private(file,
666 struct v4l2_format *f = (struct v4l2_format *)arg;
668 /* FIXME: Should be one dump per type */
669 dbgarg (cmd, "type=%s\n", prt_names(f->type,
670 v4l2_type_names_FIXME));
672 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
673 if (vfd->vidioc_try_fmt_cap)
674 ret=vfd->vidioc_try_fmt_cap(file, fh, f);
676 v4l_print_pix_fmt(vfd,&f->fmt.pix);
678 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
679 if (vfd->vidioc_try_fmt_overlay)
680 ret=vfd->vidioc_try_fmt_overlay(file, fh, f);
682 case V4L2_BUF_TYPE_VBI_CAPTURE:
683 if (vfd->vidioc_try_fmt_vbi)
684 ret=vfd->vidioc_try_fmt_vbi(file, fh, f);
686 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
687 if (vfd->vidioc_try_fmt_vbi_output)
688 ret=vfd->vidioc_try_fmt_vbi_output(file,
691 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
692 if (vfd->vidioc_try_fmt_vbi_capture)
693 ret=vfd->vidioc_try_fmt_vbi_capture(file,
696 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
697 if (vfd->vidioc_try_fmt_video_output)
698 ret=vfd->vidioc_try_fmt_video_output(file,
701 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
702 if (vfd->vidioc_try_fmt_output_overlay)
703 ret=vfd->vidioc_try_fmt_output_overlay(file, fh, f);
705 case V4L2_BUF_TYPE_VBI_OUTPUT:
706 if (vfd->vidioc_try_fmt_vbi_output)
707 ret=vfd->vidioc_try_fmt_vbi_output(file,
710 case V4L2_BUF_TYPE_PRIVATE:
711 if (vfd->vidioc_try_fmt_type_private)
712 ret=vfd->vidioc_try_fmt_type_private(file,
719 /* FIXME: Those buf reqs could be handled here,
720 with some changes on videobuf to allow its header to be included at
721 videodev2.h or being merged at videodev2.
725 struct v4l2_requestbuffers *p=arg;
727 if (!vfd->vidioc_reqbufs)
729 ret = check_fmt (vfd, p->type);
733 ret=vfd->vidioc_reqbufs(file, fh, p);
734 dbgarg (cmd, "count=%d, type=%s, memory=%s\n",
736 prt_names(p->type,v4l2_type_names_FIXME),
737 prt_names(p->memory,v4l2_memory_names));
740 case VIDIOC_QUERYBUF:
742 struct v4l2_buffer *p=arg;
744 if (!vfd->vidioc_querybuf)
746 ret = check_fmt (vfd, p->type);
750 ret=vfd->vidioc_querybuf(file, fh, p);
757 struct v4l2_buffer *p=arg;
759 if (!vfd->vidioc_qbuf)
761 ret = check_fmt (vfd, p->type);
765 ret=vfd->vidioc_qbuf(file, fh, p);
772 struct v4l2_buffer *p=arg;
773 if (!vfd->vidioc_dqbuf)
775 ret = check_fmt (vfd, p->type);
779 ret=vfd->vidioc_dqbuf(file, fh, p);
788 if (!vfd->vidioc_overlay)
790 dbgarg (cmd, "value=%d\n",*i);
791 ret=vfd->vidioc_overlay(file, fh, *i);
794 #ifdef CONFIG_VIDEO_V4L1_COMPAT
795 /* --- streaming capture ------------------------------------- */
798 struct video_mbuf *p=arg;
800 memset(p,0,sizeof(p));
802 if (!vfd->vidiocgmbuf)
804 ret=vfd->vidiocgmbuf(file, fh, p);
806 dbgarg (cmd, "size=%d, frames=%d, offsets=0x%08lx\n",
808 (unsigned long)p->offsets);
814 struct v4l2_framebuffer *p=arg;
815 if (!vfd->vidioc_g_fbuf)
817 ret=vfd->vidioc_g_fbuf(file, fh, arg);
819 dbgarg (cmd, "capability=%d, flags=%d, base=0x%08lx\n",
820 p->capability,p->flags,
821 (unsigned long)p->base);
822 v4l_print_pix_fmt (vfd, &p->fmt);
828 struct v4l2_framebuffer *p=arg;
829 if (!vfd->vidioc_s_fbuf)
832 dbgarg (cmd, "capability=%d, flags=%d, base=0x%08lx\n",
833 p->capability,p->flags,(unsigned long)p->base);
834 v4l_print_pix_fmt (vfd, &p->fmt);
835 ret=vfd->vidioc_s_fbuf(file, fh, arg);
839 case VIDIOC_STREAMON:
841 enum v4l2_buf_type i = *(int *)arg;
842 if (!vfd->vidioc_streamon)
844 dbgarg (cmd, "type=%s\n", prt_names(i,v4l2_type_names_FIXME));
845 ret=vfd->vidioc_streamon(file, fh,i);
848 case VIDIOC_STREAMOFF:
850 enum v4l2_buf_type i = *(int *)arg;
852 if (!vfd->vidioc_streamoff)
854 dbgarg (cmd, "type=%s\n", prt_names(i,v4l2_type_names_FIXME));
855 ret=vfd->vidioc_streamoff(file, fh, i);
858 /* ---------- tv norms ---------- */
861 struct v4l2_standard *p = arg;
862 v4l2_std_id id = vfd->tvnorms,curr_id=0;
863 unsigned int index = p->index,i;
870 /* Return norm array on a canonical way */
871 for (i=0;i<= index && id; i++) {
872 if ( (id & V4L2_STD_PAL) == V4L2_STD_PAL) {
873 curr_id = V4L2_STD_PAL;
874 } else if ( (id & V4L2_STD_PAL_BG) == V4L2_STD_PAL_BG) {
875 curr_id = V4L2_STD_PAL_BG;
876 } else if ( (id & V4L2_STD_PAL_DK) == V4L2_STD_PAL_DK) {
877 curr_id = V4L2_STD_PAL_DK;
878 } else if ( (id & V4L2_STD_PAL_B) == V4L2_STD_PAL_B) {
879 curr_id = V4L2_STD_PAL_B;
880 } else if ( (id & V4L2_STD_PAL_B1) == V4L2_STD_PAL_B1) {
881 curr_id = V4L2_STD_PAL_B1;
882 } else if ( (id & V4L2_STD_PAL_G) == V4L2_STD_PAL_G) {
883 curr_id = V4L2_STD_PAL_G;
884 } else if ( (id & V4L2_STD_PAL_H) == V4L2_STD_PAL_H) {
885 curr_id = V4L2_STD_PAL_H;
886 } else if ( (id & V4L2_STD_PAL_I) == V4L2_STD_PAL_I) {
887 curr_id = V4L2_STD_PAL_I;
888 } else if ( (id & V4L2_STD_PAL_D) == V4L2_STD_PAL_D) {
889 curr_id = V4L2_STD_PAL_D;
890 } else if ( (id & V4L2_STD_PAL_D1) == V4L2_STD_PAL_D1) {
891 curr_id = V4L2_STD_PAL_D1;
892 } else if ( (id & V4L2_STD_PAL_K) == V4L2_STD_PAL_K) {
893 curr_id = V4L2_STD_PAL_K;
894 } else if ( (id & V4L2_STD_PAL_M) == V4L2_STD_PAL_M) {
895 curr_id = V4L2_STD_PAL_M;
896 } else if ( (id & V4L2_STD_PAL_N) == V4L2_STD_PAL_N) {
897 curr_id = V4L2_STD_PAL_N;
898 } else if ( (id & V4L2_STD_PAL_Nc) == V4L2_STD_PAL_Nc) {
899 curr_id = V4L2_STD_PAL_Nc;
900 } else if ( (id & V4L2_STD_PAL_60) == V4L2_STD_PAL_60) {
901 curr_id = V4L2_STD_PAL_60;
902 } else if ( (id & V4L2_STD_NTSC) == V4L2_STD_NTSC) {
903 curr_id = V4L2_STD_NTSC;
904 } else if ( (id & V4L2_STD_NTSC_M) == V4L2_STD_NTSC_M) {
905 curr_id = V4L2_STD_NTSC_M;
906 } else if ( (id & V4L2_STD_NTSC_M_JP) == V4L2_STD_NTSC_M_JP) {
907 curr_id = V4L2_STD_NTSC_M_JP;
908 } else if ( (id & V4L2_STD_NTSC_443) == V4L2_STD_NTSC_443) {
909 curr_id = V4L2_STD_NTSC_443;
910 } else if ( (id & V4L2_STD_NTSC_M_KR) == V4L2_STD_NTSC_M_KR) {
911 curr_id = V4L2_STD_NTSC_M_KR;
912 } else if ( (id & V4L2_STD_SECAM) == V4L2_STD_SECAM) {
913 curr_id = V4L2_STD_SECAM;
914 } else if ( (id & V4L2_STD_SECAM_DK) == V4L2_STD_SECAM_DK) {
915 curr_id = V4L2_STD_SECAM_DK;
916 } else if ( (id & V4L2_STD_SECAM_B) == V4L2_STD_SECAM_B) {
917 curr_id = V4L2_STD_SECAM_B;
918 } else if ( (id & V4L2_STD_SECAM_D) == V4L2_STD_SECAM_D) {
919 curr_id = V4L2_STD_SECAM_D;
920 } else if ( (id & V4L2_STD_SECAM_G) == V4L2_STD_SECAM_G) {
921 curr_id = V4L2_STD_SECAM_G;
922 } else if ( (id & V4L2_STD_SECAM_H) == V4L2_STD_SECAM_H) {
923 curr_id = V4L2_STD_SECAM_H;
924 } else if ( (id & V4L2_STD_SECAM_K) == V4L2_STD_SECAM_K) {
925 curr_id = V4L2_STD_SECAM_K;
926 } else if ( (id & V4L2_STD_SECAM_K1) == V4L2_STD_SECAM_K1) {
927 curr_id = V4L2_STD_SECAM_K1;
928 } else if ( (id & V4L2_STD_SECAM_L) == V4L2_STD_SECAM_L) {
929 curr_id = V4L2_STD_SECAM_L;
930 } else if ( (id & V4L2_STD_SECAM_LC) == V4L2_STD_SECAM_LC) {
931 curr_id = V4L2_STD_SECAM_LC;
940 v4l2_video_std_construct(p, curr_id,v4l2_norm_to_name(curr_id));
943 dbgarg (cmd, "index=%d, id=%Ld, name=%s, fps=%d/%d, "
944 "framelines=%d\n", p->index,
945 (unsigned long long)p->id, p->name,
946 p->frameperiod.numerator,
947 p->frameperiod.denominator,
955 v4l2_std_id *id = arg;
957 *id = vfd->current_norm;
959 dbgarg (cmd, "value=%Lu\n", (long long unsigned) *id);
966 v4l2_std_id *id = arg,norm;
968 dbgarg (cmd, "value=%Lu\n", (long long unsigned) *id);
970 norm = (*id) & vfd->tvnorms;
971 if ( vfd->tvnorms && !norm) /* Check if std is supported */
974 /* Calls the specific handler */
975 if (vfd->vidioc_s_std)
976 ret=vfd->vidioc_s_std(file, fh, &norm);
980 /* Updates standard information */
982 vfd->current_norm=norm;
986 case VIDIOC_QUERYSTD:
990 if (!vfd->vidioc_querystd)
992 ret=vfd->vidioc_querystd(file, fh, arg);
994 dbgarg (cmd, "detected std=%Lu\n",
995 (unsigned long long)*p);
998 /* ------ input switching ---------- */
999 /* FIXME: Inputs can be handled inside videodev2 */
1000 case VIDIOC_ENUMINPUT:
1002 struct v4l2_input *p=arg;
1005 if (!vfd->vidioc_enum_input)
1007 memset(p, 0, sizeof(*p));
1010 ret=vfd->vidioc_enum_input(file, fh, p);
1012 dbgarg (cmd, "index=%d, name=%s, type=%d, "
1014 "tuner=%d, std=%Ld, status=%d\n",
1015 p->index,p->name,p->type,p->audioset,
1017 (unsigned long long)p->std,
1021 case VIDIOC_G_INPUT:
1023 unsigned int *i = arg;
1025 if (!vfd->vidioc_g_input)
1027 ret=vfd->vidioc_g_input(file, fh, i);
1029 dbgarg (cmd, "value=%d\n",*i);
1032 case VIDIOC_S_INPUT:
1034 unsigned int *i = arg;
1036 if (!vfd->vidioc_s_input)
1038 dbgarg (cmd, "value=%d\n",*i);
1039 ret=vfd->vidioc_s_input(file, fh, *i);
1043 /* ------ output switching ---------- */
1044 case VIDIOC_G_OUTPUT:
1046 unsigned int *i = arg;
1048 if (!vfd->vidioc_g_output)
1050 ret=vfd->vidioc_g_output(file, fh, i);
1052 dbgarg (cmd, "value=%d\n",*i);
1055 case VIDIOC_S_OUTPUT:
1057 unsigned int *i = arg;
1059 if (!vfd->vidioc_s_output)
1061 dbgarg (cmd, "value=%d\n",*i);
1062 ret=vfd->vidioc_s_output(file, fh, *i);
1066 /* --- controls ---------------------------------------------- */
1067 case VIDIOC_QUERYCTRL:
1069 struct v4l2_queryctrl *p=arg;
1071 if (!vfd->vidioc_queryctrl)
1073 ret=vfd->vidioc_queryctrl(file, fh, p);
1076 dbgarg (cmd, "id=%d, type=%d, name=%s, "
1078 " step=%d, default=%d, flags=0x%08x\n",
1079 p->id,p->type,p->name,p->minimum,
1080 p->maximum,p->step,p->default_value,
1086 struct v4l2_control *p = arg;
1088 if (!vfd->vidioc_g_ctrl)
1090 dbgarg(cmd, "Enum for index=%d\n", p->id);
1092 ret=vfd->vidioc_g_ctrl(file, fh, p);
1094 dbgarg2 ( "id=%d, value=%d\n", p->id, p->value);
1099 struct v4l2_control *p = arg;
1101 if (!vfd->vidioc_s_ctrl)
1103 dbgarg (cmd, "id=%d, value=%d\n", p->id, p->value);
1105 ret=vfd->vidioc_s_ctrl(file, fh, p);
1108 case VIDIOC_G_EXT_CTRLS:
1110 struct v4l2_ext_controls *p = arg;
1112 if (vfd->vidioc_g_ext_ctrls) {
1113 dbgarg(cmd, "count=%d\n", p->count);
1115 ret=vfd->vidioc_g_ext_ctrls(file, fh, p);
1119 case VIDIOC_S_EXT_CTRLS:
1121 struct v4l2_ext_controls *p = arg;
1123 if (vfd->vidioc_s_ext_ctrls) {
1124 dbgarg(cmd, "count=%d\n", p->count);
1126 ret=vfd->vidioc_s_ext_ctrls(file, fh, p);
1130 case VIDIOC_TRY_EXT_CTRLS:
1132 struct v4l2_ext_controls *p = arg;
1134 if (vfd->vidioc_try_ext_ctrls) {
1135 dbgarg(cmd, "count=%d\n", p->count);
1137 ret=vfd->vidioc_try_ext_ctrls(file, fh, p);
1141 case VIDIOC_QUERYMENU:
1143 struct v4l2_querymenu *p=arg;
1144 if (!vfd->vidioc_querymenu)
1146 ret=vfd->vidioc_querymenu(file, fh, p);
1148 dbgarg (cmd, "id=%d, index=%d, name=%s\n",
1149 p->id,p->index,p->name);
1152 /* --- audio ---------------------------------------------- */
1153 case VIDIOC_ENUMAUDIO:
1155 struct v4l2_audio *p=arg;
1157 if (!vfd->vidioc_enumaudio)
1159 dbgarg(cmd, "Enum for index=%d\n", p->index);
1160 ret=vfd->vidioc_enumaudio(file, fh, p);
1162 dbgarg2("index=%d, name=%s, capability=%d, "
1163 "mode=%d\n",p->index,p->name,
1164 p->capability, p->mode);
1167 case VIDIOC_G_AUDIO:
1169 struct v4l2_audio *p=arg;
1170 __u32 index=p->index;
1172 if (!vfd->vidioc_g_audio)
1175 memset(p,0,sizeof(*p));
1177 dbgarg(cmd, "Get for index=%d\n", p->index);
1178 ret=vfd->vidioc_g_audio(file, fh, p);
1180 dbgarg2("index=%d, name=%s, capability=%d, "
1181 "mode=%d\n",p->index,
1182 p->name,p->capability, p->mode);
1185 case VIDIOC_S_AUDIO:
1187 struct v4l2_audio *p=arg;
1189 if (!vfd->vidioc_s_audio)
1191 dbgarg(cmd, "index=%d, name=%s, capability=%d, "
1192 "mode=%d\n", p->index, p->name,
1193 p->capability, p->mode);
1194 ret=vfd->vidioc_s_audio(file, fh, p);
1197 case VIDIOC_ENUMAUDOUT:
1199 struct v4l2_audioout *p=arg;
1201 if (!vfd->vidioc_enumaudout)
1203 dbgarg(cmd, "Enum for index=%d\n", p->index);
1204 ret=vfd->vidioc_enumaudout(file, fh, p);
1206 dbgarg2("index=%d, name=%s, capability=%d, "
1207 "mode=%d\n", p->index, p->name,
1208 p->capability,p->mode);
1211 case VIDIOC_G_AUDOUT:
1213 struct v4l2_audioout *p=arg;
1215 if (!vfd->vidioc_g_audout)
1217 dbgarg(cmd, "Enum for index=%d\n", p->index);
1218 ret=vfd->vidioc_g_audout(file, fh, p);
1220 dbgarg2("index=%d, name=%s, capability=%d, "
1221 "mode=%d\n", p->index, p->name,
1222 p->capability,p->mode);
1225 case VIDIOC_S_AUDOUT:
1227 struct v4l2_audioout *p=arg;
1229 if (!vfd->vidioc_s_audout)
1231 dbgarg(cmd, "index=%d, name=%s, capability=%d, "
1232 "mode=%d\n", p->index, p->name,
1233 p->capability,p->mode);
1235 ret=vfd->vidioc_s_audout(file, fh, p);
1238 case VIDIOC_G_MODULATOR:
1240 struct v4l2_modulator *p=arg;
1241 if (!vfd->vidioc_g_modulator)
1243 ret=vfd->vidioc_g_modulator(file, fh, p);
1245 dbgarg(cmd, "index=%d, name=%s, "
1246 "capability=%d, rangelow=%d,"
1247 " rangehigh=%d, txsubchans=%d\n",
1248 p->index, p->name,p->capability,
1249 p->rangelow, p->rangehigh,
1253 case VIDIOC_S_MODULATOR:
1255 struct v4l2_modulator *p=arg;
1256 if (!vfd->vidioc_s_modulator)
1258 dbgarg(cmd, "index=%d, name=%s, capability=%d, "
1259 "rangelow=%d, rangehigh=%d, txsubchans=%d\n",
1260 p->index, p->name,p->capability,p->rangelow,
1261 p->rangehigh,p->txsubchans);
1262 ret=vfd->vidioc_s_modulator(file, fh, p);
1267 struct v4l2_crop *p=arg;
1268 if (!vfd->vidioc_g_crop)
1270 ret=vfd->vidioc_g_crop(file, fh, p);
1272 dbgarg(cmd, "type=%d\n", p->type);
1273 dbgrect(vfd, "", &p->c);
1279 struct v4l2_crop *p=arg;
1280 if (!vfd->vidioc_s_crop)
1282 dbgarg(cmd, "type=%d\n", p->type);
1283 dbgrect(vfd, "", &p->c);
1284 ret=vfd->vidioc_s_crop(file, fh, p);
1287 case VIDIOC_CROPCAP:
1289 struct v4l2_cropcap *p=arg;
1290 /*FIXME: Should also show v4l2_fract pixelaspect */
1291 if (!vfd->vidioc_cropcap)
1293 dbgarg(cmd, "type=%d\n", p->type);
1294 dbgrect(vfd, "bounds ", &p->bounds);
1295 dbgrect(vfd, "defrect ", &p->defrect);
1296 ret=vfd->vidioc_cropcap(file, fh, p);
1299 case VIDIOC_G_MPEGCOMP:
1301 struct v4l2_mpeg_compression *p=arg;
1303 /*FIXME: Several fields not shown */
1304 if (!vfd->vidioc_g_mpegcomp)
1306 ret=vfd->vidioc_g_mpegcomp(file, fh, p);
1308 dbgarg (cmd, "ts_pid_pmt=%d, ts_pid_audio=%d,"
1309 " ts_pid_video=%d, ts_pid_pcr=%d, "
1310 "ps_size=%d, au_sample_rate=%d, "
1311 "au_pesid=%c, vi_frame_rate=%d, "
1312 "vi_frames_per_gop=%d, "
1313 "vi_bframes_count=%d, vi_pesid=%c\n",
1314 p->ts_pid_pmt,p->ts_pid_audio,
1315 p->ts_pid_video,p->ts_pid_pcr,
1316 p->ps_size, p->au_sample_rate,
1317 p->au_pesid, p->vi_frame_rate,
1318 p->vi_frames_per_gop,
1319 p->vi_bframes_count, p->vi_pesid);
1322 case VIDIOC_S_MPEGCOMP:
1324 struct v4l2_mpeg_compression *p=arg;
1325 /*FIXME: Several fields not shown */
1326 if (!vfd->vidioc_s_mpegcomp)
1328 dbgarg (cmd, "ts_pid_pmt=%d, ts_pid_audio=%d, "
1329 "ts_pid_video=%d, ts_pid_pcr=%d, ps_size=%d, "
1330 "au_sample_rate=%d, au_pesid=%c, "
1331 "vi_frame_rate=%d, vi_frames_per_gop=%d, "
1332 "vi_bframes_count=%d, vi_pesid=%c\n",
1333 p->ts_pid_pmt,p->ts_pid_audio, p->ts_pid_video,
1334 p->ts_pid_pcr, p->ps_size, p->au_sample_rate,
1335 p->au_pesid, p->vi_frame_rate,
1336 p->vi_frames_per_gop, p->vi_bframes_count,
1338 ret=vfd->vidioc_s_mpegcomp(file, fh, p);
1341 case VIDIOC_G_JPEGCOMP:
1343 struct v4l2_jpegcompression *p=arg;
1344 if (!vfd->vidioc_g_jpegcomp)
1346 ret=vfd->vidioc_g_jpegcomp(file, fh, p);
1348 dbgarg (cmd, "quality=%d, APPn=%d, "
1349 "APP_len=%d, COM_len=%d, "
1350 "jpeg_markers=%d\n",
1351 p->quality,p->APPn,p->APP_len,
1352 p->COM_len,p->jpeg_markers);
1355 case VIDIOC_S_JPEGCOMP:
1357 struct v4l2_jpegcompression *p=arg;
1358 if (!vfd->vidioc_g_jpegcomp)
1360 dbgarg (cmd, "quality=%d, APPn=%d, APP_len=%d, "
1361 "COM_len=%d, jpeg_markers=%d\n",
1362 p->quality,p->APPn,p->APP_len,
1363 p->COM_len,p->jpeg_markers);
1364 ret=vfd->vidioc_s_jpegcomp(file, fh, p);
1367 case VIDIOC_G_ENC_INDEX:
1369 struct v4l2_enc_idx *p=arg;
1371 if (!vfd->vidioc_g_enc_index)
1373 ret=vfd->vidioc_g_enc_index(file, fh, p);
1375 dbgarg (cmd, "entries=%d, entries_cap=%d\n",
1376 p->entries,p->entries_cap);
1379 case VIDIOC_ENCODER_CMD:
1381 struct v4l2_encoder_cmd *p=arg;
1383 if (!vfd->vidioc_encoder_cmd)
1385 ret=vfd->vidioc_encoder_cmd(file, fh, p);
1387 dbgarg (cmd, "cmd=%d, flags=%d\n",
1391 case VIDIOC_TRY_ENCODER_CMD:
1393 struct v4l2_encoder_cmd *p=arg;
1395 if (!vfd->vidioc_try_encoder_cmd)
1397 ret=vfd->vidioc_try_encoder_cmd(file, fh, p);
1399 dbgarg (cmd, "cmd=%d, flags=%d\n",
1405 struct v4l2_streamparm *p=arg;
1408 memset(p,0,sizeof(*p));
1411 if (vfd->vidioc_g_parm) {
1412 ret=vfd->vidioc_g_parm(file, fh, p);
1414 struct v4l2_standard s;
1416 if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1419 v4l2_video_std_construct(&s, vfd->current_norm,
1420 v4l2_norm_to_name(vfd->current_norm));
1422 p->parm.capture.timeperframe = s.frameperiod;
1426 dbgarg (cmd, "type=%d\n", p->type);
1431 struct v4l2_streamparm *p=arg;
1432 if (!vfd->vidioc_s_parm)
1434 dbgarg (cmd, "type=%d\n", p->type);
1435 ret=vfd->vidioc_s_parm(file, fh, p);
1438 case VIDIOC_G_TUNER:
1440 struct v4l2_tuner *p=arg;
1441 __u32 index=p->index;
1443 if (!vfd->vidioc_g_tuner)
1446 memset(p,0,sizeof(*p));
1449 ret=vfd->vidioc_g_tuner(file, fh, p);
1451 dbgarg (cmd, "index=%d, name=%s, type=%d, "
1452 "capability=%d, rangelow=%d, "
1453 "rangehigh=%d, signal=%d, afc=%d, "
1454 "rxsubchans=%d, audmode=%d\n",
1455 p->index, p->name, p->type,
1456 p->capability, p->rangelow,
1457 p->rangehigh, p->rxsubchans,
1458 p->audmode, p->signal, p->afc);
1461 case VIDIOC_S_TUNER:
1463 struct v4l2_tuner *p=arg;
1464 if (!vfd->vidioc_s_tuner)
1466 dbgarg (cmd, "index=%d, name=%s, type=%d, "
1467 "capability=%d, rangelow=%d, rangehigh=%d, "
1468 "signal=%d, afc=%d, rxsubchans=%d, "
1469 "audmode=%d\n",p->index, p->name, p->type,
1470 p->capability, p->rangelow,p->rangehigh,
1471 p->rxsubchans, p->audmode, p->signal,
1473 ret=vfd->vidioc_s_tuner(file, fh, p);
1476 case VIDIOC_G_FREQUENCY:
1478 struct v4l2_frequency *p=arg;
1479 if (!vfd->vidioc_g_frequency)
1482 memset(p,0,sizeof(*p));
1484 ret=vfd->vidioc_g_frequency(file, fh, p);
1486 dbgarg (cmd, "tuner=%d, type=%d, frequency=%d\n",
1487 p->tuner,p->type,p->frequency);
1490 case VIDIOC_S_FREQUENCY:
1492 struct v4l2_frequency *p=arg;
1493 if (!vfd->vidioc_s_frequency)
1495 dbgarg (cmd, "tuner=%d, type=%d, frequency=%d\n",
1496 p->tuner,p->type,p->frequency);
1497 ret=vfd->vidioc_s_frequency(file, fh, p);
1500 case VIDIOC_G_SLICED_VBI_CAP:
1502 struct v4l2_sliced_vbi_cap *p=arg;
1503 if (!vfd->vidioc_g_sliced_vbi_cap)
1505 ret=vfd->vidioc_g_sliced_vbi_cap(file, fh, p);
1507 dbgarg (cmd, "service_set=%d\n", p->service_set);
1510 case VIDIOC_LOG_STATUS:
1512 if (!vfd->vidioc_log_status)
1514 ret=vfd->vidioc_log_status(file, fh);
1517 #ifdef CONFIG_VIDEO_ADV_DEBUG
1518 case VIDIOC_DBG_G_REGISTER:
1520 struct v4l2_register *p=arg;
1521 if (!capable(CAP_SYS_ADMIN))
1523 else if (vfd->vidioc_g_register)
1524 ret=vfd->vidioc_g_register(file, fh, p);
1527 case VIDIOC_DBG_S_REGISTER:
1529 struct v4l2_register *p=arg;
1530 if (!capable(CAP_SYS_ADMIN))
1532 else if (vfd->vidioc_s_register)
1533 ret=vfd->vidioc_s_register(file, fh, p);
1537 case VIDIOC_G_CHIP_IDENT:
1539 struct v4l2_chip_ident *p=arg;
1540 if (!vfd->vidioc_g_chip_ident)
1542 ret=vfd->vidioc_g_chip_ident(file, fh, p);
1544 dbgarg (cmd, "chip_ident=%u, revision=0x%x\n", p->ident, p->revision);
1549 if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) {
1551 printk ("%s: err:\n", vfd->name);
1552 v4l_print_ioctl(vfd->name, cmd);
1559 int video_ioctl2 (struct inode *inode, struct file *file,
1560 unsigned int cmd, unsigned long arg)
1567 size_t ctrls_size = 0;
1568 void __user *user_ptr = NULL;
1570 #ifdef __OLD_VIDIOC_
1571 cmd = video_fix_command(cmd);
1573 is_ext_ctrl = (cmd == VIDIOC_S_EXT_CTRLS || cmd == VIDIOC_G_EXT_CTRLS ||
1574 cmd == VIDIOC_TRY_EXT_CTRLS);
1576 /* Copy arguments into temp kernel buffer */
1577 switch (_IOC_DIR(cmd)) {
1583 case (_IOC_WRITE | _IOC_READ):
1584 if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
1587 /* too big to allocate from stack */
1588 mbuf = kmalloc(_IOC_SIZE(cmd),GFP_KERNEL);
1595 if (_IOC_DIR(cmd) & _IOC_WRITE)
1596 if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd)))
1602 struct v4l2_ext_controls *p = parg;
1604 /* In case of an error, tell the caller that it wasn't
1605 a specific control that caused it. */
1606 p->error_idx = p->count;
1607 user_ptr = (void __user *)p->controls;
1609 ctrls_size = sizeof(struct v4l2_ext_control) * p->count;
1610 /* Note: v4l2_ext_controls fits in sbuf[] so mbuf is still NULL. */
1611 mbuf = kmalloc(ctrls_size, GFP_KERNEL);
1616 if (copy_from_user(mbuf, user_ptr, ctrls_size))
1623 err = __video_do_ioctl(inode, file, cmd, parg);
1624 if (err == -ENOIOCTLCMD)
1627 struct v4l2_ext_controls *p = parg;
1629 p->controls = (void *)user_ptr;
1630 if (p->count && err == 0 && copy_to_user(user_ptr, mbuf, ctrls_size))
1638 /* Copy results into user buffer */
1639 switch (_IOC_DIR(cmd))
1642 case (_IOC_WRITE | _IOC_READ):
1643 if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd)))
1654 static const struct file_operations video_fops;
1657 * video_register_device - register video4linux devices
1658 * @vfd: video device structure we want to register
1659 * @type: type of device to register
1660 * @nr: which device number (0 == /dev/video0, 1 == /dev/video1, ...
1663 * The registration code assigns minor numbers based on the type
1664 * requested. -ENFILE is returned in all the device slots for this
1665 * category are full. If not then the minor field is set and the
1666 * driver initialize function is called (if non %NULL).
1668 * Zero is returned on success.
1672 * %VFL_TYPE_GRABBER - A frame grabber
1674 * %VFL_TYPE_VTX - A teletext device
1676 * %VFL_TYPE_VBI - Vertical blank data (undecoded)
1678 * %VFL_TYPE_RADIO - A radio card
1681 int video_register_device(struct video_device *vfd, int type, int nr)
1691 case VFL_TYPE_GRABBER:
1692 base=MINOR_VFL_TYPE_GRABBER_MIN;
1693 end=MINOR_VFL_TYPE_GRABBER_MAX+1;
1694 name_base = "video";
1697 base=MINOR_VFL_TYPE_VTX_MIN;
1698 end=MINOR_VFL_TYPE_VTX_MAX+1;
1702 base=MINOR_VFL_TYPE_VBI_MIN;
1703 end=MINOR_VFL_TYPE_VBI_MAX+1;
1706 case VFL_TYPE_RADIO:
1707 base=MINOR_VFL_TYPE_RADIO_MIN;
1708 end=MINOR_VFL_TYPE_RADIO_MAX+1;
1709 name_base = "radio";
1712 printk(KERN_ERR "%s called with unknown type: %d\n",
1713 __FUNCTION__, type);
1717 /* pick a minor number */
1718 mutex_lock(&videodev_lock);
1719 if (nr >= 0 && nr < end-base) {
1720 /* use the one the driver asked for */
1722 if (NULL != video_device[i]) {
1723 mutex_unlock(&videodev_lock);
1727 /* use first free */
1728 for(i=base;i<end;i++)
1729 if (NULL == video_device[i])
1732 mutex_unlock(&videodev_lock);
1736 video_device[i]=vfd;
1738 mutex_unlock(&videodev_lock);
1739 mutex_init(&vfd->lock);
1742 memset(&vfd->class_dev, 0x00, sizeof(vfd->class_dev));
1744 vfd->class_dev.dev = vfd->dev;
1745 vfd->class_dev.class = &video_class;
1746 vfd->class_dev.devt = MKDEV(VIDEO_MAJOR, vfd->minor);
1747 sprintf(vfd->class_dev.class_id, "%s%d", name_base, i - base);
1748 ret = class_device_register(&vfd->class_dev);
1750 printk(KERN_ERR "%s: class_device_register failed\n",
1754 ret = class_device_create_file(&vfd->class_dev, &class_device_attr_name);
1756 printk(KERN_ERR "%s: class_device_create_file 'name' failed\n",
1762 /* needed until all drivers are fixed */
1764 printk(KERN_WARNING "videodev: \"%s\" has no release callback. "
1765 "Please fix your driver for proper sysfs support, see "
1766 "http://lwn.net/Articles/36850/\n", vfd->name);
1771 class_device_unregister(&vfd->class_dev);
1773 mutex_lock(&videodev_lock);
1774 video_device[vfd->minor] = NULL;
1776 mutex_unlock(&videodev_lock);
1781 * video_unregister_device - unregister a video4linux device
1782 * @vfd: the device to unregister
1784 * This unregisters the passed device and deassigns the minor
1785 * number. Future open calls will be met with errors.
1788 void video_unregister_device(struct video_device *vfd)
1790 mutex_lock(&videodev_lock);
1791 if(video_device[vfd->minor]!=vfd)
1792 panic("videodev: bad unregister");
1794 video_device[vfd->minor]=NULL;
1795 class_device_unregister(&vfd->class_dev);
1796 mutex_unlock(&videodev_lock);
1800 * Video fs operations
1802 static const struct file_operations video_fops=
1804 .owner = THIS_MODULE,
1805 .llseek = no_llseek,
1810 * Initialise video for linux
1813 static int __init videodev_init(void)
1817 printk(KERN_INFO "Linux video capture interface: v2.00\n");
1818 if (register_chrdev(VIDEO_MAJOR, VIDEO_NAME, &video_fops)) {
1819 printk(KERN_WARNING "video_dev: unable to get major %d\n", VIDEO_MAJOR);
1823 ret = class_register(&video_class);
1825 unregister_chrdev(VIDEO_MAJOR, VIDEO_NAME);
1826 printk(KERN_WARNING "video_dev: class_register failed\n");
1833 static void __exit videodev_exit(void)
1835 class_unregister(&video_class);
1836 unregister_chrdev(VIDEO_MAJOR, VIDEO_NAME);
1839 module_init(videodev_init)
1840 module_exit(videodev_exit)
1842 EXPORT_SYMBOL(video_register_device);
1843 EXPORT_SYMBOL(video_unregister_device);
1844 EXPORT_SYMBOL(video_devdata);
1845 EXPORT_SYMBOL(video_usercopy);
1846 EXPORT_SYMBOL(video_exclusive_open);
1847 EXPORT_SYMBOL(video_exclusive_release);
1848 EXPORT_SYMBOL(video_ioctl2);
1849 EXPORT_SYMBOL(video_device_alloc);
1850 EXPORT_SYMBOL(video_device_release);
1852 MODULE_AUTHOR("Alan Cox, Mauro Carvalho Chehab <mchehab@infradead.org>");
1853 MODULE_DESCRIPTION("Device registrar for Video4Linux drivers v2");
1854 MODULE_LICENSE("GPL");