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_VIDEO_OUTPUT_OVERLAY] = "video-out-over",
322 [V4L2_BUF_TYPE_PRIVATE] = "private",
325 static char *v4l2_field_names_FIXME[] = {
326 [V4L2_FIELD_ANY] = "any",
327 [V4L2_FIELD_NONE] = "none",
328 [V4L2_FIELD_TOP] = "top",
329 [V4L2_FIELD_BOTTOM] = "bottom",
330 [V4L2_FIELD_INTERLACED] = "interlaced",
331 [V4L2_FIELD_SEQ_TB] = "seq-tb",
332 [V4L2_FIELD_SEQ_BT] = "seq-bt",
333 [V4L2_FIELD_ALTERNATE] = "alternate",
334 [V4L2_FIELD_INTERLACED_TB] = "interlaced-tb",
335 [V4L2_FIELD_INTERLACED_BT] = "interlaced-bt",
338 #define prt_names(a,arr) (((a)>=0)&&((a)<ARRAY_SIZE(arr)))?arr[a]:"unknown"
340 static void dbgbuf(unsigned int cmd, struct video_device *vfd,
341 struct v4l2_buffer *p)
343 struct v4l2_timecode *tc=&p->timecode;
345 dbgarg (cmd, "%02ld:%02d:%02d.%08ld index=%d, type=%s, "
346 "bytesused=%d, flags=0x%08d, "
347 "field=%0d, sequence=%d, memory=%s, offset/userptr=0x%08lx, length=%d\n",
348 (p->timestamp.tv_sec/3600),
349 (int)(p->timestamp.tv_sec/60)%60,
350 (int)(p->timestamp.tv_sec%60),
351 p->timestamp.tv_usec,
353 prt_names(p->type,v4l2_type_names_FIXME),
354 p->bytesused,p->flags,
355 p->field,p->sequence,
356 prt_names(p->memory,v4l2_memory_names),
357 p->m.userptr, p->length);
358 dbgarg2 ("timecode= %02d:%02d:%02d type=%d, "
359 "flags=0x%08d, frames=%d, userbits=0x%08x\n",
360 tc->hours,tc->minutes,tc->seconds,
361 tc->type, tc->flags, tc->frames, *(__u32 *) tc->userbits);
364 static inline void dbgrect(struct video_device *vfd, char *s,
367 dbgarg2 ("%sRect start at %dx%d, size= %dx%d\n", s, r->left, r->top,
368 r->width, r->height);
371 static inline void v4l_print_pix_fmt (struct video_device *vfd,
372 struct v4l2_pix_format *fmt)
374 dbgarg2 ("width=%d, height=%d, format=%c%c%c%c, field=%s, "
375 "bytesperline=%d sizeimage=%d, colorspace=%d\n",
376 fmt->width,fmt->height,
377 (fmt->pixelformat & 0xff),
378 (fmt->pixelformat >> 8) & 0xff,
379 (fmt->pixelformat >> 16) & 0xff,
380 (fmt->pixelformat >> 24) & 0xff,
381 prt_names(fmt->field,v4l2_field_names_FIXME),
382 fmt->bytesperline,fmt->sizeimage,fmt->colorspace);
386 static int check_fmt (struct video_device *vfd, enum v4l2_buf_type type)
389 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
390 if (vfd->vidioc_try_fmt_cap)
393 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
394 if (vfd->vidioc_try_fmt_overlay)
397 case V4L2_BUF_TYPE_VBI_CAPTURE:
398 if (vfd->vidioc_try_fmt_vbi)
401 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
402 if (vfd->vidioc_try_fmt_vbi_output)
405 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
406 if (vfd->vidioc_try_fmt_vbi_capture)
409 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
410 if (vfd->vidioc_try_fmt_video_output)
413 case V4L2_BUF_TYPE_VBI_OUTPUT:
414 if (vfd->vidioc_try_fmt_vbi_output)
417 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
418 if (vfd->vidioc_try_fmt_output_overlay)
421 case V4L2_BUF_TYPE_PRIVATE:
422 if (vfd->vidioc_try_fmt_type_private)
429 static int __video_do_ioctl(struct inode *inode, struct file *file,
430 unsigned int cmd, void *arg)
432 struct video_device *vfd = video_devdata(file);
433 void *fh = file->private_data;
436 if ( (vfd->debug & V4L2_DEBUG_IOCTL) &&
437 !(vfd->debug | V4L2_DEBUG_IOCTL_ARG)) {
438 v4l_print_ioctl(vfd->name, cmd);
441 if (_IOC_TYPE(cmd)=='v')
442 return v4l_compat_translate_ioctl(inode,file,cmd,arg,
446 /* --- capabilities ------------------------------------------ */
447 case VIDIOC_QUERYCAP:
449 struct v4l2_capability *cap = (struct v4l2_capability*)arg;
450 memset(cap, 0, sizeof(*cap));
452 if (!vfd->vidioc_querycap)
455 ret=vfd->vidioc_querycap(file, fh, cap);
457 dbgarg (cmd, "driver=%s, card=%s, bus=%s, "
459 "capabilities=0x%08x\n",
460 cap->driver,cap->card,cap->bus_info,
466 /* --- priority ------------------------------------------ */
467 case VIDIOC_G_PRIORITY:
469 enum v4l2_priority *p=arg;
471 if (!vfd->vidioc_g_priority)
473 ret=vfd->vidioc_g_priority(file, fh, p);
475 dbgarg(cmd, "priority is %d\n", *p);
478 case VIDIOC_S_PRIORITY:
480 enum v4l2_priority *p=arg;
482 if (!vfd->vidioc_s_priority)
484 dbgarg(cmd, "setting priority to %d\n", *p);
485 ret=vfd->vidioc_s_priority(file, fh, *p);
489 /* --- capture ioctls ---------------------------------------- */
490 case VIDIOC_ENUM_FMT:
492 struct v4l2_fmtdesc *f = arg;
493 enum v4l2_buf_type type;
498 memset(f,0,sizeof(*f));
503 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
504 if (vfd->vidioc_enum_fmt_cap)
505 ret=vfd->vidioc_enum_fmt_cap(file, fh, f);
507 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
508 if (vfd->vidioc_enum_fmt_overlay)
509 ret=vfd->vidioc_enum_fmt_overlay(file, fh, f);
511 case V4L2_BUF_TYPE_VBI_CAPTURE:
512 if (vfd->vidioc_enum_fmt_vbi)
513 ret=vfd->vidioc_enum_fmt_vbi(file, fh, f);
515 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
516 if (vfd->vidioc_enum_fmt_vbi_output)
517 ret=vfd->vidioc_enum_fmt_vbi_output(file,
520 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
521 if (vfd->vidioc_enum_fmt_vbi_capture)
522 ret=vfd->vidioc_enum_fmt_vbi_capture(file,
525 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
526 if (vfd->vidioc_enum_fmt_video_output)
527 ret=vfd->vidioc_enum_fmt_video_output(file,
530 case V4L2_BUF_TYPE_VBI_OUTPUT:
531 if (vfd->vidioc_enum_fmt_vbi_output)
532 ret=vfd->vidioc_enum_fmt_vbi_output(file,
535 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
536 if (vfd->vidioc_enum_fmt_output_overlay)
537 ret=vfd->vidioc_enum_fmt_output_overlay(file, fh, f);
539 case V4L2_BUF_TYPE_PRIVATE:
540 if (vfd->vidioc_enum_fmt_type_private)
541 ret=vfd->vidioc_enum_fmt_type_private(file,
546 dbgarg (cmd, "index=%d, type=%d, flags=%d, "
547 "pixelformat=%c%c%c%c, description='%s'\n",
548 f->index, f->type, f->flags,
549 (f->pixelformat & 0xff),
550 (f->pixelformat >> 8) & 0xff,
551 (f->pixelformat >> 16) & 0xff,
552 (f->pixelformat >> 24) & 0xff,
558 struct v4l2_format *f = (struct v4l2_format *)arg;
559 enum v4l2_buf_type type=f->type;
561 memset(&f->fmt.pix,0,sizeof(f->fmt.pix));
564 /* FIXME: Should be one dump per type */
565 dbgarg (cmd, "type=%s\n", prt_names(type,
566 v4l2_type_names_FIXME));
569 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
570 if (vfd->vidioc_g_fmt_cap)
571 ret=vfd->vidioc_g_fmt_cap(file, fh, f);
573 v4l_print_pix_fmt(vfd,&f->fmt.pix);
575 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
576 if (vfd->vidioc_g_fmt_overlay)
577 ret=vfd->vidioc_g_fmt_overlay(file, fh, f);
579 case V4L2_BUF_TYPE_VBI_CAPTURE:
580 if (vfd->vidioc_g_fmt_vbi)
581 ret=vfd->vidioc_g_fmt_vbi(file, fh, f);
583 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
584 if (vfd->vidioc_g_fmt_vbi_output)
585 ret=vfd->vidioc_g_fmt_vbi_output(file, fh, f);
587 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
588 if (vfd->vidioc_g_fmt_vbi_capture)
589 ret=vfd->vidioc_g_fmt_vbi_capture(file, fh, f);
591 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
592 if (vfd->vidioc_g_fmt_video_output)
593 ret=vfd->vidioc_g_fmt_video_output(file,
596 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
597 if (vfd->vidioc_g_fmt_output_overlay)
598 ret=vfd->vidioc_g_fmt_output_overlay(file, fh, f);
600 case V4L2_BUF_TYPE_VBI_OUTPUT:
601 if (vfd->vidioc_g_fmt_vbi_output)
602 ret=vfd->vidioc_g_fmt_vbi_output(file, fh, f);
604 case V4L2_BUF_TYPE_PRIVATE:
605 if (vfd->vidioc_g_fmt_type_private)
606 ret=vfd->vidioc_g_fmt_type_private(file,
615 struct v4l2_format *f = (struct v4l2_format *)arg;
617 /* FIXME: Should be one dump per type */
618 dbgarg (cmd, "type=%s\n", prt_names(f->type,
619 v4l2_type_names_FIXME));
622 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
623 v4l_print_pix_fmt(vfd,&f->fmt.pix);
624 if (vfd->vidioc_s_fmt_cap)
625 ret=vfd->vidioc_s_fmt_cap(file, fh, f);
627 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
628 if (vfd->vidioc_s_fmt_overlay)
629 ret=vfd->vidioc_s_fmt_overlay(file, fh, f);
631 case V4L2_BUF_TYPE_VBI_CAPTURE:
632 if (vfd->vidioc_s_fmt_vbi)
633 ret=vfd->vidioc_s_fmt_vbi(file, fh, f);
635 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
636 if (vfd->vidioc_s_fmt_vbi_output)
637 ret=vfd->vidioc_s_fmt_vbi_output(file, fh, f);
639 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
640 if (vfd->vidioc_s_fmt_vbi_capture)
641 ret=vfd->vidioc_s_fmt_vbi_capture(file, fh, f);
643 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
644 if (vfd->vidioc_s_fmt_video_output)
645 ret=vfd->vidioc_s_fmt_video_output(file,
648 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
649 if (vfd->vidioc_s_fmt_output_overlay)
650 ret=vfd->vidioc_s_fmt_output_overlay(file, fh, f);
652 case V4L2_BUF_TYPE_VBI_OUTPUT:
653 if (vfd->vidioc_s_fmt_vbi_output)
654 ret=vfd->vidioc_s_fmt_vbi_output(file,
657 case V4L2_BUF_TYPE_PRIVATE:
658 if (vfd->vidioc_s_fmt_type_private)
659 ret=vfd->vidioc_s_fmt_type_private(file,
667 struct v4l2_format *f = (struct v4l2_format *)arg;
669 /* FIXME: Should be one dump per type */
670 dbgarg (cmd, "type=%s\n", prt_names(f->type,
671 v4l2_type_names_FIXME));
673 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
674 if (vfd->vidioc_try_fmt_cap)
675 ret=vfd->vidioc_try_fmt_cap(file, fh, f);
677 v4l_print_pix_fmt(vfd,&f->fmt.pix);
679 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
680 if (vfd->vidioc_try_fmt_overlay)
681 ret=vfd->vidioc_try_fmt_overlay(file, fh, f);
683 case V4L2_BUF_TYPE_VBI_CAPTURE:
684 if (vfd->vidioc_try_fmt_vbi)
685 ret=vfd->vidioc_try_fmt_vbi(file, fh, f);
687 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
688 if (vfd->vidioc_try_fmt_vbi_output)
689 ret=vfd->vidioc_try_fmt_vbi_output(file,
692 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
693 if (vfd->vidioc_try_fmt_vbi_capture)
694 ret=vfd->vidioc_try_fmt_vbi_capture(file,
697 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
698 if (vfd->vidioc_try_fmt_video_output)
699 ret=vfd->vidioc_try_fmt_video_output(file,
702 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
703 if (vfd->vidioc_try_fmt_output_overlay)
704 ret=vfd->vidioc_try_fmt_output_overlay(file, fh, f);
706 case V4L2_BUF_TYPE_VBI_OUTPUT:
707 if (vfd->vidioc_try_fmt_vbi_output)
708 ret=vfd->vidioc_try_fmt_vbi_output(file,
711 case V4L2_BUF_TYPE_PRIVATE:
712 if (vfd->vidioc_try_fmt_type_private)
713 ret=vfd->vidioc_try_fmt_type_private(file,
720 /* FIXME: Those buf reqs could be handled here,
721 with some changes on videobuf to allow its header to be included at
722 videodev2.h or being merged at videodev2.
726 struct v4l2_requestbuffers *p=arg;
728 if (!vfd->vidioc_reqbufs)
730 ret = check_fmt (vfd, p->type);
734 ret=vfd->vidioc_reqbufs(file, fh, p);
735 dbgarg (cmd, "count=%d, type=%s, memory=%s\n",
737 prt_names(p->type,v4l2_type_names_FIXME),
738 prt_names(p->memory,v4l2_memory_names));
741 case VIDIOC_QUERYBUF:
743 struct v4l2_buffer *p=arg;
745 if (!vfd->vidioc_querybuf)
747 ret = check_fmt (vfd, p->type);
751 ret=vfd->vidioc_querybuf(file, fh, p);
758 struct v4l2_buffer *p=arg;
760 if (!vfd->vidioc_qbuf)
762 ret = check_fmt (vfd, p->type);
766 ret=vfd->vidioc_qbuf(file, fh, p);
773 struct v4l2_buffer *p=arg;
774 if (!vfd->vidioc_dqbuf)
776 ret = check_fmt (vfd, p->type);
780 ret=vfd->vidioc_dqbuf(file, fh, p);
789 if (!vfd->vidioc_overlay)
791 dbgarg (cmd, "value=%d\n",*i);
792 ret=vfd->vidioc_overlay(file, fh, *i);
795 #ifdef CONFIG_VIDEO_V4L1_COMPAT
796 /* --- streaming capture ------------------------------------- */
799 struct video_mbuf *p=arg;
801 memset(p,0,sizeof(p));
803 if (!vfd->vidiocgmbuf)
805 ret=vfd->vidiocgmbuf(file, fh, p);
807 dbgarg (cmd, "size=%d, frames=%d, offsets=0x%08lx\n",
809 (unsigned long)p->offsets);
815 struct v4l2_framebuffer *p=arg;
816 if (!vfd->vidioc_g_fbuf)
818 ret=vfd->vidioc_g_fbuf(file, fh, arg);
820 dbgarg (cmd, "capability=%d, flags=%d, base=0x%08lx\n",
821 p->capability,p->flags,
822 (unsigned long)p->base);
823 v4l_print_pix_fmt (vfd, &p->fmt);
829 struct v4l2_framebuffer *p=arg;
830 if (!vfd->vidioc_s_fbuf)
833 dbgarg (cmd, "capability=%d, flags=%d, base=0x%08lx\n",
834 p->capability,p->flags,(unsigned long)p->base);
835 v4l_print_pix_fmt (vfd, &p->fmt);
836 ret=vfd->vidioc_s_fbuf(file, fh, arg);
840 case VIDIOC_STREAMON:
842 enum v4l2_buf_type i = *(int *)arg;
843 if (!vfd->vidioc_streamon)
845 dbgarg (cmd, "type=%s\n", prt_names(i,v4l2_type_names_FIXME));
846 ret=vfd->vidioc_streamon(file, fh,i);
849 case VIDIOC_STREAMOFF:
851 enum v4l2_buf_type i = *(int *)arg;
853 if (!vfd->vidioc_streamoff)
855 dbgarg (cmd, "type=%s\n", prt_names(i,v4l2_type_names_FIXME));
856 ret=vfd->vidioc_streamoff(file, fh, i);
859 /* ---------- tv norms ---------- */
862 struct v4l2_standard *p = arg;
863 v4l2_std_id id = vfd->tvnorms,curr_id=0;
864 unsigned int index = p->index,i;
871 /* Return norm array on a canonical way */
872 for (i=0;i<= index && id; i++) {
873 if ( (id & V4L2_STD_PAL) == V4L2_STD_PAL) {
874 curr_id = V4L2_STD_PAL;
875 } else if ( (id & V4L2_STD_PAL_BG) == V4L2_STD_PAL_BG) {
876 curr_id = V4L2_STD_PAL_BG;
877 } else if ( (id & V4L2_STD_PAL_DK) == V4L2_STD_PAL_DK) {
878 curr_id = V4L2_STD_PAL_DK;
879 } else if ( (id & V4L2_STD_PAL_B) == V4L2_STD_PAL_B) {
880 curr_id = V4L2_STD_PAL_B;
881 } else if ( (id & V4L2_STD_PAL_B1) == V4L2_STD_PAL_B1) {
882 curr_id = V4L2_STD_PAL_B1;
883 } else if ( (id & V4L2_STD_PAL_G) == V4L2_STD_PAL_G) {
884 curr_id = V4L2_STD_PAL_G;
885 } else if ( (id & V4L2_STD_PAL_H) == V4L2_STD_PAL_H) {
886 curr_id = V4L2_STD_PAL_H;
887 } else if ( (id & V4L2_STD_PAL_I) == V4L2_STD_PAL_I) {
888 curr_id = V4L2_STD_PAL_I;
889 } else if ( (id & V4L2_STD_PAL_D) == V4L2_STD_PAL_D) {
890 curr_id = V4L2_STD_PAL_D;
891 } else if ( (id & V4L2_STD_PAL_D1) == V4L2_STD_PAL_D1) {
892 curr_id = V4L2_STD_PAL_D1;
893 } else if ( (id & V4L2_STD_PAL_K) == V4L2_STD_PAL_K) {
894 curr_id = V4L2_STD_PAL_K;
895 } else if ( (id & V4L2_STD_PAL_M) == V4L2_STD_PAL_M) {
896 curr_id = V4L2_STD_PAL_M;
897 } else if ( (id & V4L2_STD_PAL_N) == V4L2_STD_PAL_N) {
898 curr_id = V4L2_STD_PAL_N;
899 } else if ( (id & V4L2_STD_PAL_Nc) == V4L2_STD_PAL_Nc) {
900 curr_id = V4L2_STD_PAL_Nc;
901 } else if ( (id & V4L2_STD_PAL_60) == V4L2_STD_PAL_60) {
902 curr_id = V4L2_STD_PAL_60;
903 } else if ( (id & V4L2_STD_NTSC) == V4L2_STD_NTSC) {
904 curr_id = V4L2_STD_NTSC;
905 } else if ( (id & V4L2_STD_NTSC_M) == V4L2_STD_NTSC_M) {
906 curr_id = V4L2_STD_NTSC_M;
907 } else if ( (id & V4L2_STD_NTSC_M_JP) == V4L2_STD_NTSC_M_JP) {
908 curr_id = V4L2_STD_NTSC_M_JP;
909 } else if ( (id & V4L2_STD_NTSC_443) == V4L2_STD_NTSC_443) {
910 curr_id = V4L2_STD_NTSC_443;
911 } else if ( (id & V4L2_STD_NTSC_M_KR) == V4L2_STD_NTSC_M_KR) {
912 curr_id = V4L2_STD_NTSC_M_KR;
913 } else if ( (id & V4L2_STD_SECAM) == V4L2_STD_SECAM) {
914 curr_id = V4L2_STD_SECAM;
915 } else if ( (id & V4L2_STD_SECAM_DK) == V4L2_STD_SECAM_DK) {
916 curr_id = V4L2_STD_SECAM_DK;
917 } else if ( (id & V4L2_STD_SECAM_B) == V4L2_STD_SECAM_B) {
918 curr_id = V4L2_STD_SECAM_B;
919 } else if ( (id & V4L2_STD_SECAM_D) == V4L2_STD_SECAM_D) {
920 curr_id = V4L2_STD_SECAM_D;
921 } else if ( (id & V4L2_STD_SECAM_G) == V4L2_STD_SECAM_G) {
922 curr_id = V4L2_STD_SECAM_G;
923 } else if ( (id & V4L2_STD_SECAM_H) == V4L2_STD_SECAM_H) {
924 curr_id = V4L2_STD_SECAM_H;
925 } else if ( (id & V4L2_STD_SECAM_K) == V4L2_STD_SECAM_K) {
926 curr_id = V4L2_STD_SECAM_K;
927 } else if ( (id & V4L2_STD_SECAM_K1) == V4L2_STD_SECAM_K1) {
928 curr_id = V4L2_STD_SECAM_K1;
929 } else if ( (id & V4L2_STD_SECAM_L) == V4L2_STD_SECAM_L) {
930 curr_id = V4L2_STD_SECAM_L;
931 } else if ( (id & V4L2_STD_SECAM_LC) == V4L2_STD_SECAM_LC) {
932 curr_id = V4L2_STD_SECAM_LC;
941 v4l2_video_std_construct(p, curr_id,v4l2_norm_to_name(curr_id));
944 dbgarg (cmd, "index=%d, id=%Ld, name=%s, fps=%d/%d, "
945 "framelines=%d\n", p->index,
946 (unsigned long long)p->id, p->name,
947 p->frameperiod.numerator,
948 p->frameperiod.denominator,
956 v4l2_std_id *id = arg;
958 *id = vfd->current_norm;
960 dbgarg (cmd, "value=%Lu\n", (long long unsigned) *id);
967 v4l2_std_id *id = arg,norm;
969 dbgarg (cmd, "value=%Lu\n", (long long unsigned) *id);
971 norm = (*id) & vfd->tvnorms;
972 if ( vfd->tvnorms && !norm) /* Check if std is supported */
975 /* Calls the specific handler */
976 if (vfd->vidioc_s_std)
977 ret=vfd->vidioc_s_std(file, fh, &norm);
981 /* Updates standard information */
983 vfd->current_norm=norm;
987 case VIDIOC_QUERYSTD:
991 if (!vfd->vidioc_querystd)
993 ret=vfd->vidioc_querystd(file, fh, arg);
995 dbgarg (cmd, "detected std=%Lu\n",
996 (unsigned long long)*p);
999 /* ------ input switching ---------- */
1000 /* FIXME: Inputs can be handled inside videodev2 */
1001 case VIDIOC_ENUMINPUT:
1003 struct v4l2_input *p=arg;
1006 if (!vfd->vidioc_enum_input)
1008 memset(p, 0, sizeof(*p));
1011 ret=vfd->vidioc_enum_input(file, fh, p);
1013 dbgarg (cmd, "index=%d, name=%s, type=%d, "
1015 "tuner=%d, std=%Ld, status=%d\n",
1016 p->index,p->name,p->type,p->audioset,
1018 (unsigned long long)p->std,
1022 case VIDIOC_G_INPUT:
1024 unsigned int *i = arg;
1026 if (!vfd->vidioc_g_input)
1028 ret=vfd->vidioc_g_input(file, fh, i);
1030 dbgarg (cmd, "value=%d\n",*i);
1033 case VIDIOC_S_INPUT:
1035 unsigned int *i = arg;
1037 if (!vfd->vidioc_s_input)
1039 dbgarg (cmd, "value=%d\n",*i);
1040 ret=vfd->vidioc_s_input(file, fh, *i);
1044 /* ------ output switching ---------- */
1045 case VIDIOC_G_OUTPUT:
1047 unsigned int *i = arg;
1049 if (!vfd->vidioc_g_output)
1051 ret=vfd->vidioc_g_output(file, fh, i);
1053 dbgarg (cmd, "value=%d\n",*i);
1056 case VIDIOC_S_OUTPUT:
1058 unsigned int *i = arg;
1060 if (!vfd->vidioc_s_output)
1062 dbgarg (cmd, "value=%d\n",*i);
1063 ret=vfd->vidioc_s_output(file, fh, *i);
1067 /* --- controls ---------------------------------------------- */
1068 case VIDIOC_QUERYCTRL:
1070 struct v4l2_queryctrl *p=arg;
1072 if (!vfd->vidioc_queryctrl)
1074 ret=vfd->vidioc_queryctrl(file, fh, p);
1077 dbgarg (cmd, "id=%d, type=%d, name=%s, "
1079 " step=%d, default=%d, flags=0x%08x\n",
1080 p->id,p->type,p->name,p->minimum,
1081 p->maximum,p->step,p->default_value,
1087 struct v4l2_control *p = arg;
1089 if (!vfd->vidioc_g_ctrl)
1091 dbgarg(cmd, "Enum for index=%d\n", p->id);
1093 ret=vfd->vidioc_g_ctrl(file, fh, p);
1095 dbgarg2 ( "id=%d, value=%d\n", p->id, p->value);
1100 struct v4l2_control *p = arg;
1102 if (!vfd->vidioc_s_ctrl)
1104 dbgarg (cmd, "id=%d, value=%d\n", p->id, p->value);
1106 ret=vfd->vidioc_s_ctrl(file, fh, p);
1109 case VIDIOC_G_EXT_CTRLS:
1111 struct v4l2_ext_controls *p = arg;
1113 if (vfd->vidioc_g_ext_ctrls) {
1114 dbgarg(cmd, "count=%d\n", p->count);
1116 ret=vfd->vidioc_g_ext_ctrls(file, fh, p);
1120 case VIDIOC_S_EXT_CTRLS:
1122 struct v4l2_ext_controls *p = arg;
1124 if (vfd->vidioc_s_ext_ctrls) {
1125 dbgarg(cmd, "count=%d\n", p->count);
1127 ret=vfd->vidioc_s_ext_ctrls(file, fh, p);
1131 case VIDIOC_TRY_EXT_CTRLS:
1133 struct v4l2_ext_controls *p = arg;
1135 if (vfd->vidioc_try_ext_ctrls) {
1136 dbgarg(cmd, "count=%d\n", p->count);
1138 ret=vfd->vidioc_try_ext_ctrls(file, fh, p);
1142 case VIDIOC_QUERYMENU:
1144 struct v4l2_querymenu *p=arg;
1145 if (!vfd->vidioc_querymenu)
1147 ret=vfd->vidioc_querymenu(file, fh, p);
1149 dbgarg (cmd, "id=%d, index=%d, name=%s\n",
1150 p->id,p->index,p->name);
1153 /* --- audio ---------------------------------------------- */
1154 case VIDIOC_ENUMAUDIO:
1156 struct v4l2_audio *p=arg;
1158 if (!vfd->vidioc_enumaudio)
1160 dbgarg(cmd, "Enum for index=%d\n", p->index);
1161 ret=vfd->vidioc_enumaudio(file, fh, p);
1163 dbgarg2("index=%d, name=%s, capability=%d, "
1164 "mode=%d\n",p->index,p->name,
1165 p->capability, p->mode);
1168 case VIDIOC_G_AUDIO:
1170 struct v4l2_audio *p=arg;
1171 __u32 index=p->index;
1173 if (!vfd->vidioc_g_audio)
1176 memset(p,0,sizeof(*p));
1178 dbgarg(cmd, "Get for index=%d\n", p->index);
1179 ret=vfd->vidioc_g_audio(file, fh, p);
1181 dbgarg2("index=%d, name=%s, capability=%d, "
1182 "mode=%d\n",p->index,
1183 p->name,p->capability, p->mode);
1186 case VIDIOC_S_AUDIO:
1188 struct v4l2_audio *p=arg;
1190 if (!vfd->vidioc_s_audio)
1192 dbgarg(cmd, "index=%d, name=%s, capability=%d, "
1193 "mode=%d\n", p->index, p->name,
1194 p->capability, p->mode);
1195 ret=vfd->vidioc_s_audio(file, fh, p);
1198 case VIDIOC_ENUMAUDOUT:
1200 struct v4l2_audioout *p=arg;
1202 if (!vfd->vidioc_enumaudout)
1204 dbgarg(cmd, "Enum for index=%d\n", p->index);
1205 ret=vfd->vidioc_enumaudout(file, fh, p);
1207 dbgarg2("index=%d, name=%s, capability=%d, "
1208 "mode=%d\n", p->index, p->name,
1209 p->capability,p->mode);
1212 case VIDIOC_G_AUDOUT:
1214 struct v4l2_audioout *p=arg;
1216 if (!vfd->vidioc_g_audout)
1218 dbgarg(cmd, "Enum for index=%d\n", p->index);
1219 ret=vfd->vidioc_g_audout(file, fh, p);
1221 dbgarg2("index=%d, name=%s, capability=%d, "
1222 "mode=%d\n", p->index, p->name,
1223 p->capability,p->mode);
1226 case VIDIOC_S_AUDOUT:
1228 struct v4l2_audioout *p=arg;
1230 if (!vfd->vidioc_s_audout)
1232 dbgarg(cmd, "index=%d, name=%s, capability=%d, "
1233 "mode=%d\n", p->index, p->name,
1234 p->capability,p->mode);
1236 ret=vfd->vidioc_s_audout(file, fh, p);
1239 case VIDIOC_G_MODULATOR:
1241 struct v4l2_modulator *p=arg;
1242 if (!vfd->vidioc_g_modulator)
1244 ret=vfd->vidioc_g_modulator(file, fh, p);
1246 dbgarg(cmd, "index=%d, name=%s, "
1247 "capability=%d, rangelow=%d,"
1248 " rangehigh=%d, txsubchans=%d\n",
1249 p->index, p->name,p->capability,
1250 p->rangelow, p->rangehigh,
1254 case VIDIOC_S_MODULATOR:
1256 struct v4l2_modulator *p=arg;
1257 if (!vfd->vidioc_s_modulator)
1259 dbgarg(cmd, "index=%d, name=%s, capability=%d, "
1260 "rangelow=%d, rangehigh=%d, txsubchans=%d\n",
1261 p->index, p->name,p->capability,p->rangelow,
1262 p->rangehigh,p->txsubchans);
1263 ret=vfd->vidioc_s_modulator(file, fh, p);
1268 struct v4l2_crop *p=arg;
1269 if (!vfd->vidioc_g_crop)
1271 ret=vfd->vidioc_g_crop(file, fh, p);
1273 dbgarg(cmd, "type=%d\n", p->type);
1274 dbgrect(vfd, "", &p->c);
1280 struct v4l2_crop *p=arg;
1281 if (!vfd->vidioc_s_crop)
1283 dbgarg(cmd, "type=%d\n", p->type);
1284 dbgrect(vfd, "", &p->c);
1285 ret=vfd->vidioc_s_crop(file, fh, p);
1288 case VIDIOC_CROPCAP:
1290 struct v4l2_cropcap *p=arg;
1291 /*FIXME: Should also show v4l2_fract pixelaspect */
1292 if (!vfd->vidioc_cropcap)
1294 dbgarg(cmd, "type=%d\n", p->type);
1295 dbgrect(vfd, "bounds ", &p->bounds);
1296 dbgrect(vfd, "defrect ", &p->defrect);
1297 ret=vfd->vidioc_cropcap(file, fh, p);
1300 case VIDIOC_G_MPEGCOMP:
1302 struct v4l2_mpeg_compression *p=arg;
1304 /*FIXME: Several fields not shown */
1305 if (!vfd->vidioc_g_mpegcomp)
1307 ret=vfd->vidioc_g_mpegcomp(file, fh, p);
1309 dbgarg (cmd, "ts_pid_pmt=%d, ts_pid_audio=%d,"
1310 " ts_pid_video=%d, ts_pid_pcr=%d, "
1311 "ps_size=%d, au_sample_rate=%d, "
1312 "au_pesid=%c, vi_frame_rate=%d, "
1313 "vi_frames_per_gop=%d, "
1314 "vi_bframes_count=%d, vi_pesid=%c\n",
1315 p->ts_pid_pmt,p->ts_pid_audio,
1316 p->ts_pid_video,p->ts_pid_pcr,
1317 p->ps_size, p->au_sample_rate,
1318 p->au_pesid, p->vi_frame_rate,
1319 p->vi_frames_per_gop,
1320 p->vi_bframes_count, p->vi_pesid);
1323 case VIDIOC_S_MPEGCOMP:
1325 struct v4l2_mpeg_compression *p=arg;
1326 /*FIXME: Several fields not shown */
1327 if (!vfd->vidioc_s_mpegcomp)
1329 dbgarg (cmd, "ts_pid_pmt=%d, ts_pid_audio=%d, "
1330 "ts_pid_video=%d, ts_pid_pcr=%d, ps_size=%d, "
1331 "au_sample_rate=%d, au_pesid=%c, "
1332 "vi_frame_rate=%d, vi_frames_per_gop=%d, "
1333 "vi_bframes_count=%d, vi_pesid=%c\n",
1334 p->ts_pid_pmt,p->ts_pid_audio, p->ts_pid_video,
1335 p->ts_pid_pcr, p->ps_size, p->au_sample_rate,
1336 p->au_pesid, p->vi_frame_rate,
1337 p->vi_frames_per_gop, p->vi_bframes_count,
1339 ret=vfd->vidioc_s_mpegcomp(file, fh, p);
1342 case VIDIOC_G_JPEGCOMP:
1344 struct v4l2_jpegcompression *p=arg;
1345 if (!vfd->vidioc_g_jpegcomp)
1347 ret=vfd->vidioc_g_jpegcomp(file, fh, p);
1349 dbgarg (cmd, "quality=%d, APPn=%d, "
1350 "APP_len=%d, COM_len=%d, "
1351 "jpeg_markers=%d\n",
1352 p->quality,p->APPn,p->APP_len,
1353 p->COM_len,p->jpeg_markers);
1356 case VIDIOC_S_JPEGCOMP:
1358 struct v4l2_jpegcompression *p=arg;
1359 if (!vfd->vidioc_g_jpegcomp)
1361 dbgarg (cmd, "quality=%d, APPn=%d, APP_len=%d, "
1362 "COM_len=%d, jpeg_markers=%d\n",
1363 p->quality,p->APPn,p->APP_len,
1364 p->COM_len,p->jpeg_markers);
1365 ret=vfd->vidioc_s_jpegcomp(file, fh, p);
1368 case VIDIOC_G_ENC_INDEX:
1370 struct v4l2_enc_idx *p=arg;
1372 if (!vfd->vidioc_g_enc_index)
1374 ret=vfd->vidioc_g_enc_index(file, fh, p);
1376 dbgarg (cmd, "entries=%d, entries_cap=%d\n",
1377 p->entries,p->entries_cap);
1380 case VIDIOC_ENCODER_CMD:
1382 struct v4l2_encoder_cmd *p=arg;
1384 if (!vfd->vidioc_encoder_cmd)
1386 ret=vfd->vidioc_encoder_cmd(file, fh, p);
1388 dbgarg (cmd, "cmd=%d, flags=%d\n",
1392 case VIDIOC_TRY_ENCODER_CMD:
1394 struct v4l2_encoder_cmd *p=arg;
1396 if (!vfd->vidioc_try_encoder_cmd)
1398 ret=vfd->vidioc_try_encoder_cmd(file, fh, p);
1400 dbgarg (cmd, "cmd=%d, flags=%d\n",
1406 struct v4l2_streamparm *p=arg;
1409 memset(p,0,sizeof(*p));
1412 if (vfd->vidioc_g_parm) {
1413 ret=vfd->vidioc_g_parm(file, fh, p);
1415 struct v4l2_standard s;
1417 if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1420 v4l2_video_std_construct(&s, vfd->current_norm,
1421 v4l2_norm_to_name(vfd->current_norm));
1423 p->parm.capture.timeperframe = s.frameperiod;
1427 dbgarg (cmd, "type=%d\n", p->type);
1432 struct v4l2_streamparm *p=arg;
1433 if (!vfd->vidioc_s_parm)
1435 dbgarg (cmd, "type=%d\n", p->type);
1436 ret=vfd->vidioc_s_parm(file, fh, p);
1439 case VIDIOC_G_TUNER:
1441 struct v4l2_tuner *p=arg;
1442 __u32 index=p->index;
1444 if (!vfd->vidioc_g_tuner)
1447 memset(p,0,sizeof(*p));
1450 ret=vfd->vidioc_g_tuner(file, fh, p);
1452 dbgarg (cmd, "index=%d, name=%s, type=%d, "
1453 "capability=%d, rangelow=%d, "
1454 "rangehigh=%d, signal=%d, afc=%d, "
1455 "rxsubchans=%d, audmode=%d\n",
1456 p->index, p->name, p->type,
1457 p->capability, p->rangelow,
1458 p->rangehigh, p->rxsubchans,
1459 p->audmode, p->signal, p->afc);
1462 case VIDIOC_S_TUNER:
1464 struct v4l2_tuner *p=arg;
1465 if (!vfd->vidioc_s_tuner)
1467 dbgarg (cmd, "index=%d, name=%s, type=%d, "
1468 "capability=%d, rangelow=%d, rangehigh=%d, "
1469 "signal=%d, afc=%d, rxsubchans=%d, "
1470 "audmode=%d\n",p->index, p->name, p->type,
1471 p->capability, p->rangelow,p->rangehigh,
1472 p->rxsubchans, p->audmode, p->signal,
1474 ret=vfd->vidioc_s_tuner(file, fh, p);
1477 case VIDIOC_G_FREQUENCY:
1479 struct v4l2_frequency *p=arg;
1480 if (!vfd->vidioc_g_frequency)
1483 memset(p,0,sizeof(*p));
1485 ret=vfd->vidioc_g_frequency(file, fh, p);
1487 dbgarg (cmd, "tuner=%d, type=%d, frequency=%d\n",
1488 p->tuner,p->type,p->frequency);
1491 case VIDIOC_S_FREQUENCY:
1493 struct v4l2_frequency *p=arg;
1494 if (!vfd->vidioc_s_frequency)
1496 dbgarg (cmd, "tuner=%d, type=%d, frequency=%d\n",
1497 p->tuner,p->type,p->frequency);
1498 ret=vfd->vidioc_s_frequency(file, fh, p);
1501 case VIDIOC_G_SLICED_VBI_CAP:
1503 struct v4l2_sliced_vbi_cap *p=arg;
1504 if (!vfd->vidioc_g_sliced_vbi_cap)
1506 ret=vfd->vidioc_g_sliced_vbi_cap(file, fh, p);
1508 dbgarg (cmd, "service_set=%d\n", p->service_set);
1511 case VIDIOC_LOG_STATUS:
1513 if (!vfd->vidioc_log_status)
1515 ret=vfd->vidioc_log_status(file, fh);
1518 #ifdef CONFIG_VIDEO_ADV_DEBUG
1519 case VIDIOC_DBG_G_REGISTER:
1521 struct v4l2_register *p=arg;
1522 if (!capable(CAP_SYS_ADMIN))
1524 else if (vfd->vidioc_g_register)
1525 ret=vfd->vidioc_g_register(file, fh, p);
1528 case VIDIOC_DBG_S_REGISTER:
1530 struct v4l2_register *p=arg;
1531 if (!capable(CAP_SYS_ADMIN))
1533 else if (vfd->vidioc_s_register)
1534 ret=vfd->vidioc_s_register(file, fh, p);
1538 case VIDIOC_G_CHIP_IDENT:
1540 struct v4l2_chip_ident *p=arg;
1541 if (!vfd->vidioc_g_chip_ident)
1543 ret=vfd->vidioc_g_chip_ident(file, fh, p);
1545 dbgarg (cmd, "chip_ident=%u, revision=0x%x\n", p->ident, p->revision);
1550 if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) {
1552 printk ("%s: err:\n", vfd->name);
1553 v4l_print_ioctl(vfd->name, cmd);
1560 int video_ioctl2 (struct inode *inode, struct file *file,
1561 unsigned int cmd, unsigned long arg)
1568 size_t ctrls_size = 0;
1569 void __user *user_ptr = NULL;
1571 #ifdef __OLD_VIDIOC_
1572 cmd = video_fix_command(cmd);
1574 is_ext_ctrl = (cmd == VIDIOC_S_EXT_CTRLS || cmd == VIDIOC_G_EXT_CTRLS ||
1575 cmd == VIDIOC_TRY_EXT_CTRLS);
1577 /* Copy arguments into temp kernel buffer */
1578 switch (_IOC_DIR(cmd)) {
1584 case (_IOC_WRITE | _IOC_READ):
1585 if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
1588 /* too big to allocate from stack */
1589 mbuf = kmalloc(_IOC_SIZE(cmd),GFP_KERNEL);
1596 if (_IOC_DIR(cmd) & _IOC_WRITE)
1597 if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd)))
1603 struct v4l2_ext_controls *p = parg;
1605 /* In case of an error, tell the caller that it wasn't
1606 a specific control that caused it. */
1607 p->error_idx = p->count;
1608 user_ptr = (void __user *)p->controls;
1610 ctrls_size = sizeof(struct v4l2_ext_control) * p->count;
1611 /* Note: v4l2_ext_controls fits in sbuf[] so mbuf is still NULL. */
1612 mbuf = kmalloc(ctrls_size, GFP_KERNEL);
1617 if (copy_from_user(mbuf, user_ptr, ctrls_size))
1624 err = __video_do_ioctl(inode, file, cmd, parg);
1625 if (err == -ENOIOCTLCMD)
1628 struct v4l2_ext_controls *p = parg;
1630 p->controls = (void *)user_ptr;
1631 if (p->count && err == 0 && copy_to_user(user_ptr, mbuf, ctrls_size))
1639 /* Copy results into user buffer */
1640 switch (_IOC_DIR(cmd))
1643 case (_IOC_WRITE | _IOC_READ):
1644 if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd)))
1655 static const struct file_operations video_fops;
1658 * video_register_device - register video4linux devices
1659 * @vfd: video device structure we want to register
1660 * @type: type of device to register
1661 * @nr: which device number (0 == /dev/video0, 1 == /dev/video1, ...
1664 * The registration code assigns minor numbers based on the type
1665 * requested. -ENFILE is returned in all the device slots for this
1666 * category are full. If not then the minor field is set and the
1667 * driver initialize function is called (if non %NULL).
1669 * Zero is returned on success.
1673 * %VFL_TYPE_GRABBER - A frame grabber
1675 * %VFL_TYPE_VTX - A teletext device
1677 * %VFL_TYPE_VBI - Vertical blank data (undecoded)
1679 * %VFL_TYPE_RADIO - A radio card
1682 int video_register_device(struct video_device *vfd, int type, int nr)
1692 case VFL_TYPE_GRABBER:
1693 base=MINOR_VFL_TYPE_GRABBER_MIN;
1694 end=MINOR_VFL_TYPE_GRABBER_MAX+1;
1695 name_base = "video";
1698 base=MINOR_VFL_TYPE_VTX_MIN;
1699 end=MINOR_VFL_TYPE_VTX_MAX+1;
1703 base=MINOR_VFL_TYPE_VBI_MIN;
1704 end=MINOR_VFL_TYPE_VBI_MAX+1;
1707 case VFL_TYPE_RADIO:
1708 base=MINOR_VFL_TYPE_RADIO_MIN;
1709 end=MINOR_VFL_TYPE_RADIO_MAX+1;
1710 name_base = "radio";
1713 printk(KERN_ERR "%s called with unknown type: %d\n",
1714 __FUNCTION__, type);
1718 /* pick a minor number */
1719 mutex_lock(&videodev_lock);
1720 if (nr >= 0 && nr < end-base) {
1721 /* use the one the driver asked for */
1723 if (NULL != video_device[i]) {
1724 mutex_unlock(&videodev_lock);
1728 /* use first free */
1729 for(i=base;i<end;i++)
1730 if (NULL == video_device[i])
1733 mutex_unlock(&videodev_lock);
1737 video_device[i]=vfd;
1739 mutex_unlock(&videodev_lock);
1740 mutex_init(&vfd->lock);
1743 memset(&vfd->class_dev, 0x00, sizeof(vfd->class_dev));
1745 vfd->class_dev.dev = vfd->dev;
1746 vfd->class_dev.class = &video_class;
1747 vfd->class_dev.devt = MKDEV(VIDEO_MAJOR, vfd->minor);
1748 sprintf(vfd->class_dev.class_id, "%s%d", name_base, i - base);
1749 ret = class_device_register(&vfd->class_dev);
1751 printk(KERN_ERR "%s: class_device_register failed\n",
1755 ret = class_device_create_file(&vfd->class_dev, &class_device_attr_name);
1757 printk(KERN_ERR "%s: class_device_create_file 'name' failed\n",
1763 /* needed until all drivers are fixed */
1765 printk(KERN_WARNING "videodev: \"%s\" has no release callback. "
1766 "Please fix your driver for proper sysfs support, see "
1767 "http://lwn.net/Articles/36850/\n", vfd->name);
1772 class_device_unregister(&vfd->class_dev);
1774 mutex_lock(&videodev_lock);
1775 video_device[vfd->minor] = NULL;
1777 mutex_unlock(&videodev_lock);
1782 * video_unregister_device - unregister a video4linux device
1783 * @vfd: the device to unregister
1785 * This unregisters the passed device and deassigns the minor
1786 * number. Future open calls will be met with errors.
1789 void video_unregister_device(struct video_device *vfd)
1791 mutex_lock(&videodev_lock);
1792 if(video_device[vfd->minor]!=vfd)
1793 panic("videodev: bad unregister");
1795 video_device[vfd->minor]=NULL;
1796 class_device_unregister(&vfd->class_dev);
1797 mutex_unlock(&videodev_lock);
1801 * Video fs operations
1803 static const struct file_operations video_fops=
1805 .owner = THIS_MODULE,
1806 .llseek = no_llseek,
1811 * Initialise video for linux
1814 static int __init videodev_init(void)
1818 printk(KERN_INFO "Linux video capture interface: v2.00\n");
1819 if (register_chrdev(VIDEO_MAJOR, VIDEO_NAME, &video_fops)) {
1820 printk(KERN_WARNING "video_dev: unable to get major %d\n", VIDEO_MAJOR);
1824 ret = class_register(&video_class);
1826 unregister_chrdev(VIDEO_MAJOR, VIDEO_NAME);
1827 printk(KERN_WARNING "video_dev: class_register failed\n");
1834 static void __exit videodev_exit(void)
1836 class_unregister(&video_class);
1837 unregister_chrdev(VIDEO_MAJOR, VIDEO_NAME);
1840 module_init(videodev_init)
1841 module_exit(videodev_exit)
1843 EXPORT_SYMBOL(video_register_device);
1844 EXPORT_SYMBOL(video_unregister_device);
1845 EXPORT_SYMBOL(video_devdata);
1846 EXPORT_SYMBOL(video_usercopy);
1847 EXPORT_SYMBOL(video_exclusive_open);
1848 EXPORT_SYMBOL(video_exclusive_release);
1849 EXPORT_SYMBOL(video_ioctl2);
1850 EXPORT_SYMBOL(video_device_alloc);
1851 EXPORT_SYMBOL(video_device_release);
1853 MODULE_AUTHOR("Alan Cox, Mauro Carvalho Chehab <mchehab@infradead.org>");
1854 MODULE_DESCRIPTION("Device registrar for Video4Linux drivers v2");
1855 MODULE_LICENSE("GPL");