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;
1407 if (vfd->vidioc_g_parm) {
1408 ret=vfd->vidioc_g_parm(file, fh, p);
1410 struct v4l2_standard s;
1412 if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1415 v4l2_video_std_construct(&s, vfd->current_norm,
1416 v4l2_norm_to_name(vfd->current_norm));
1418 memset(p,0,sizeof(*p));
1420 p->parm.capture.timeperframe = s.frameperiod;
1424 dbgarg (cmd, "type=%d\n", p->type);
1429 struct v4l2_streamparm *p=arg;
1430 if (!vfd->vidioc_s_parm)
1432 dbgarg (cmd, "type=%d\n", p->type);
1433 ret=vfd->vidioc_s_parm(file, fh, p);
1436 case VIDIOC_G_TUNER:
1438 struct v4l2_tuner *p=arg;
1439 __u32 index=p->index;
1441 if (!vfd->vidioc_g_tuner)
1444 memset(p,0,sizeof(*p));
1447 ret=vfd->vidioc_g_tuner(file, fh, p);
1449 dbgarg (cmd, "index=%d, name=%s, type=%d, "
1450 "capability=%d, rangelow=%d, "
1451 "rangehigh=%d, signal=%d, afc=%d, "
1452 "rxsubchans=%d, audmode=%d\n",
1453 p->index, p->name, p->type,
1454 p->capability, p->rangelow,
1455 p->rangehigh, p->rxsubchans,
1456 p->audmode, p->signal, p->afc);
1459 case VIDIOC_S_TUNER:
1461 struct v4l2_tuner *p=arg;
1462 if (!vfd->vidioc_s_tuner)
1464 dbgarg (cmd, "index=%d, name=%s, type=%d, "
1465 "capability=%d, rangelow=%d, rangehigh=%d, "
1466 "signal=%d, afc=%d, rxsubchans=%d, "
1467 "audmode=%d\n",p->index, p->name, p->type,
1468 p->capability, p->rangelow,p->rangehigh,
1469 p->rxsubchans, p->audmode, p->signal,
1471 ret=vfd->vidioc_s_tuner(file, fh, p);
1474 case VIDIOC_G_FREQUENCY:
1476 struct v4l2_frequency *p=arg;
1477 if (!vfd->vidioc_g_frequency)
1480 memset(p,0,sizeof(*p));
1482 ret=vfd->vidioc_g_frequency(file, fh, p);
1484 dbgarg (cmd, "tuner=%d, type=%d, frequency=%d\n",
1485 p->tuner,p->type,p->frequency);
1488 case VIDIOC_S_FREQUENCY:
1490 struct v4l2_frequency *p=arg;
1491 if (!vfd->vidioc_s_frequency)
1493 dbgarg (cmd, "tuner=%d, type=%d, frequency=%d\n",
1494 p->tuner,p->type,p->frequency);
1495 ret=vfd->vidioc_s_frequency(file, fh, p);
1498 case VIDIOC_G_SLICED_VBI_CAP:
1500 struct v4l2_sliced_vbi_cap *p=arg;
1501 if (!vfd->vidioc_g_sliced_vbi_cap)
1503 ret=vfd->vidioc_g_sliced_vbi_cap(file, fh, p);
1505 dbgarg (cmd, "service_set=%d\n", p->service_set);
1508 case VIDIOC_LOG_STATUS:
1510 if (!vfd->vidioc_log_status)
1512 ret=vfd->vidioc_log_status(file, fh);
1515 #ifdef CONFIG_VIDEO_ADV_DEBUG
1516 case VIDIOC_DBG_G_REGISTER:
1518 struct v4l2_register *p=arg;
1519 if (!capable(CAP_SYS_ADMIN))
1521 else if (vfd->vidioc_g_register)
1522 ret=vfd->vidioc_g_register(file, fh, p);
1525 case VIDIOC_DBG_S_REGISTER:
1527 struct v4l2_register *p=arg;
1528 if (!capable(CAP_SYS_ADMIN))
1530 else if (vfd->vidioc_s_register)
1531 ret=vfd->vidioc_s_register(file, fh, p);
1535 case VIDIOC_G_CHIP_IDENT:
1537 struct v4l2_chip_ident *p=arg;
1538 if (!vfd->vidioc_g_chip_ident)
1540 ret=vfd->vidioc_g_chip_ident(file, fh, p);
1542 dbgarg (cmd, "chip_ident=%u, revision=0x%x\n", p->ident, p->revision);
1547 if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) {
1549 printk ("%s: err:\n", vfd->name);
1550 v4l_print_ioctl(vfd->name, cmd);
1557 int video_ioctl2 (struct inode *inode, struct file *file,
1558 unsigned int cmd, unsigned long arg)
1565 size_t ctrls_size = 0;
1566 void __user *user_ptr = NULL;
1568 #ifdef __OLD_VIDIOC_
1569 cmd = video_fix_command(cmd);
1571 is_ext_ctrl = (cmd == VIDIOC_S_EXT_CTRLS || cmd == VIDIOC_G_EXT_CTRLS ||
1572 cmd == VIDIOC_TRY_EXT_CTRLS);
1574 /* Copy arguments into temp kernel buffer */
1575 switch (_IOC_DIR(cmd)) {
1581 case (_IOC_WRITE | _IOC_READ):
1582 if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
1585 /* too big to allocate from stack */
1586 mbuf = kmalloc(_IOC_SIZE(cmd),GFP_KERNEL);
1593 if (_IOC_DIR(cmd) & _IOC_WRITE)
1594 if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd)))
1600 struct v4l2_ext_controls *p = parg;
1602 /* In case of an error, tell the caller that it wasn't
1603 a specific control that caused it. */
1604 p->error_idx = p->count;
1605 user_ptr = (void __user *)p->controls;
1607 ctrls_size = sizeof(struct v4l2_ext_control) * p->count;
1608 /* Note: v4l2_ext_controls fits in sbuf[] so mbuf is still NULL. */
1609 mbuf = kmalloc(ctrls_size, GFP_KERNEL);
1614 if (copy_from_user(mbuf, user_ptr, ctrls_size))
1621 err = __video_do_ioctl(inode, file, cmd, parg);
1622 if (err == -ENOIOCTLCMD)
1625 struct v4l2_ext_controls *p = parg;
1627 p->controls = (void *)user_ptr;
1628 if (p->count && err == 0 && copy_to_user(user_ptr, mbuf, ctrls_size))
1636 /* Copy results into user buffer */
1637 switch (_IOC_DIR(cmd))
1640 case (_IOC_WRITE | _IOC_READ):
1641 if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd)))
1652 static const struct file_operations video_fops;
1655 * video_register_device - register video4linux devices
1656 * @vfd: video device structure we want to register
1657 * @type: type of device to register
1658 * @nr: which device number (0 == /dev/video0, 1 == /dev/video1, ...
1661 * The registration code assigns minor numbers based on the type
1662 * requested. -ENFILE is returned in all the device slots for this
1663 * category are full. If not then the minor field is set and the
1664 * driver initialize function is called (if non %NULL).
1666 * Zero is returned on success.
1670 * %VFL_TYPE_GRABBER - A frame grabber
1672 * %VFL_TYPE_VTX - A teletext device
1674 * %VFL_TYPE_VBI - Vertical blank data (undecoded)
1676 * %VFL_TYPE_RADIO - A radio card
1679 int video_register_device(struct video_device *vfd, int type, int nr)
1689 case VFL_TYPE_GRABBER:
1690 base=MINOR_VFL_TYPE_GRABBER_MIN;
1691 end=MINOR_VFL_TYPE_GRABBER_MAX+1;
1692 name_base = "video";
1695 base=MINOR_VFL_TYPE_VTX_MIN;
1696 end=MINOR_VFL_TYPE_VTX_MAX+1;
1700 base=MINOR_VFL_TYPE_VBI_MIN;
1701 end=MINOR_VFL_TYPE_VBI_MAX+1;
1704 case VFL_TYPE_RADIO:
1705 base=MINOR_VFL_TYPE_RADIO_MIN;
1706 end=MINOR_VFL_TYPE_RADIO_MAX+1;
1707 name_base = "radio";
1710 printk(KERN_ERR "%s called with unknown type: %d\n",
1711 __FUNCTION__, type);
1715 /* pick a minor number */
1716 mutex_lock(&videodev_lock);
1717 if (nr >= 0 && nr < end-base) {
1718 /* use the one the driver asked for */
1720 if (NULL != video_device[i]) {
1721 mutex_unlock(&videodev_lock);
1725 /* use first free */
1726 for(i=base;i<end;i++)
1727 if (NULL == video_device[i])
1730 mutex_unlock(&videodev_lock);
1734 video_device[i]=vfd;
1736 mutex_unlock(&videodev_lock);
1737 mutex_init(&vfd->lock);
1740 memset(&vfd->class_dev, 0x00, sizeof(vfd->class_dev));
1742 vfd->class_dev.dev = vfd->dev;
1743 vfd->class_dev.class = &video_class;
1744 vfd->class_dev.devt = MKDEV(VIDEO_MAJOR, vfd->minor);
1745 sprintf(vfd->class_dev.class_id, "%s%d", name_base, i - base);
1746 ret = class_device_register(&vfd->class_dev);
1748 printk(KERN_ERR "%s: class_device_register failed\n",
1752 ret = class_device_create_file(&vfd->class_dev, &class_device_attr_name);
1754 printk(KERN_ERR "%s: class_device_create_file 'name' failed\n",
1760 /* needed until all drivers are fixed */
1762 printk(KERN_WARNING "videodev: \"%s\" has no release callback. "
1763 "Please fix your driver for proper sysfs support, see "
1764 "http://lwn.net/Articles/36850/\n", vfd->name);
1769 class_device_unregister(&vfd->class_dev);
1771 mutex_lock(&videodev_lock);
1772 video_device[vfd->minor] = NULL;
1774 mutex_unlock(&videodev_lock);
1779 * video_unregister_device - unregister a video4linux device
1780 * @vfd: the device to unregister
1782 * This unregisters the passed device and deassigns the minor
1783 * number. Future open calls will be met with errors.
1786 void video_unregister_device(struct video_device *vfd)
1788 mutex_lock(&videodev_lock);
1789 if(video_device[vfd->minor]!=vfd)
1790 panic("videodev: bad unregister");
1792 video_device[vfd->minor]=NULL;
1793 class_device_unregister(&vfd->class_dev);
1794 mutex_unlock(&videodev_lock);
1798 * Video fs operations
1800 static const struct file_operations video_fops=
1802 .owner = THIS_MODULE,
1803 .llseek = no_llseek,
1808 * Initialise video for linux
1811 static int __init videodev_init(void)
1815 printk(KERN_INFO "Linux video capture interface: v2.00\n");
1816 if (register_chrdev(VIDEO_MAJOR, VIDEO_NAME, &video_fops)) {
1817 printk(KERN_WARNING "video_dev: unable to get major %d\n", VIDEO_MAJOR);
1821 ret = class_register(&video_class);
1823 unregister_chrdev(VIDEO_MAJOR, VIDEO_NAME);
1824 printk(KERN_WARNING "video_dev: class_register failed\n");
1831 static void __exit videodev_exit(void)
1833 class_unregister(&video_class);
1834 unregister_chrdev(VIDEO_MAJOR, VIDEO_NAME);
1837 module_init(videodev_init)
1838 module_exit(videodev_exit)
1840 EXPORT_SYMBOL(video_register_device);
1841 EXPORT_SYMBOL(video_unregister_device);
1842 EXPORT_SYMBOL(video_devdata);
1843 EXPORT_SYMBOL(video_usercopy);
1844 EXPORT_SYMBOL(video_exclusive_open);
1845 EXPORT_SYMBOL(video_exclusive_release);
1846 EXPORT_SYMBOL(video_ioctl2);
1847 EXPORT_SYMBOL(video_device_alloc);
1848 EXPORT_SYMBOL(video_device_release);
1850 MODULE_AUTHOR("Alan Cox, Mauro Carvalho Chehab <mchehab@infradead.org>");
1851 MODULE_DESCRIPTION("Device registrar for Video4Linux drivers v2");
1852 MODULE_LICENSE("GPL");