KVM: Cleanup mark_page_dirty
[linux-2.6/btrfs-unstable.git] / drivers / media / video / videodev.c
blob8d8e517b344f1a46ec3b30db7a4cdad1d9334413
1 /*
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/mm.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>
47 #endif
48 #include <media/v4l2-common.h>
50 #define VIDEO_NUM_DEVICES 256
51 #define VIDEO_NAME "video4linux"
54 * sysfs stuff
57 static ssize_t show_name(struct device *cd,
58 struct device_attribute *attr, char *buf)
60 struct video_device *vfd = container_of(cd, struct video_device,
61 class_dev);
62 return sprintf(buf, "%.*s\n", (int)sizeof(vfd->name), vfd->name);
65 struct video_device *video_device_alloc(void)
67 struct video_device *vfd;
69 vfd = kzalloc(sizeof(*vfd),GFP_KERNEL);
70 return vfd;
73 void video_device_release(struct video_device *vfd)
75 kfree(vfd);
78 static void video_release(struct device *cd)
80 struct video_device *vfd = container_of(cd, struct video_device,
81 class_dev);
83 #if 1
84 /* needed until all drivers are fixed */
85 if (!vfd->release)
86 return;
87 #endif
88 vfd->release(vfd);
91 static struct device_attribute video_device_attrs[] = {
92 __ATTR(name, S_IRUGO, show_name, NULL),
93 __ATTR_NULL
96 static struct class video_class = {
97 .name = VIDEO_NAME,
98 .dev_attrs = video_device_attrs,
99 .dev_release = video_release,
103 * Active devices
106 static struct video_device *video_device[VIDEO_NUM_DEVICES];
107 static DEFINE_MUTEX(videodev_lock);
109 struct video_device* video_devdata(struct file *file)
111 return video_device[iminor(file->f_path.dentry->d_inode)];
115 * Open a video device - FIXME: Obsoleted
117 static int video_open(struct inode *inode, struct file *file)
119 unsigned int minor = iminor(inode);
120 int err = 0;
121 struct video_device *vfl;
122 const struct file_operations *old_fops;
124 if(minor>=VIDEO_NUM_DEVICES)
125 return -ENODEV;
126 mutex_lock(&videodev_lock);
127 vfl=video_device[minor];
128 if(vfl==NULL) {
129 mutex_unlock(&videodev_lock);
130 request_module("char-major-%d-%d", VIDEO_MAJOR, minor);
131 mutex_lock(&videodev_lock);
132 vfl=video_device[minor];
133 if (vfl==NULL) {
134 mutex_unlock(&videodev_lock);
135 return -ENODEV;
138 old_fops = file->f_op;
139 file->f_op = fops_get(vfl->fops);
140 if(file->f_op->open)
141 err = file->f_op->open(inode,file);
142 if (err) {
143 fops_put(file->f_op);
144 file->f_op = fops_get(old_fops);
146 fops_put(old_fops);
147 mutex_unlock(&videodev_lock);
148 return err;
152 * helper function -- handles userspace copying for ioctl arguments
155 #ifdef __OLD_VIDIOC_
156 static unsigned int
157 video_fix_command(unsigned int cmd)
159 switch (cmd) {
160 case VIDIOC_OVERLAY_OLD:
161 cmd = VIDIOC_OVERLAY;
162 break;
163 case VIDIOC_S_PARM_OLD:
164 cmd = VIDIOC_S_PARM;
165 break;
166 case VIDIOC_S_CTRL_OLD:
167 cmd = VIDIOC_S_CTRL;
168 break;
169 case VIDIOC_G_AUDIO_OLD:
170 cmd = VIDIOC_G_AUDIO;
171 break;
172 case VIDIOC_G_AUDOUT_OLD:
173 cmd = VIDIOC_G_AUDOUT;
174 break;
175 case VIDIOC_CROPCAP_OLD:
176 cmd = VIDIOC_CROPCAP;
177 break;
179 return cmd;
181 #endif
184 * Obsolete usercopy function - Should be removed soon
187 video_usercopy(struct inode *inode, struct file *file,
188 unsigned int cmd, unsigned long arg,
189 int (*func)(struct inode *inode, struct file *file,
190 unsigned int cmd, void *arg))
192 char sbuf[128];
193 void *mbuf = NULL;
194 void *parg = NULL;
195 int err = -EINVAL;
196 int is_ext_ctrl;
197 size_t ctrls_size = 0;
198 void __user *user_ptr = NULL;
200 #ifdef __OLD_VIDIOC_
201 cmd = video_fix_command(cmd);
202 #endif
203 is_ext_ctrl = (cmd == VIDIOC_S_EXT_CTRLS || cmd == VIDIOC_G_EXT_CTRLS ||
204 cmd == VIDIOC_TRY_EXT_CTRLS);
206 /* Copy arguments into temp kernel buffer */
207 switch (_IOC_DIR(cmd)) {
208 case _IOC_NONE:
209 parg = NULL;
210 break;
211 case _IOC_READ:
212 case _IOC_WRITE:
213 case (_IOC_WRITE | _IOC_READ):
214 if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
215 parg = sbuf;
216 } else {
217 /* too big to allocate from stack */
218 mbuf = kmalloc(_IOC_SIZE(cmd),GFP_KERNEL);
219 if (NULL == mbuf)
220 return -ENOMEM;
221 parg = mbuf;
224 err = -EFAULT;
225 if (_IOC_DIR(cmd) & _IOC_WRITE)
226 if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd)))
227 goto out;
228 break;
230 if (is_ext_ctrl) {
231 struct v4l2_ext_controls *p = parg;
233 /* In case of an error, tell the caller that it wasn't
234 a specific control that caused it. */
235 p->error_idx = p->count;
236 user_ptr = (void __user *)p->controls;
237 if (p->count) {
238 ctrls_size = sizeof(struct v4l2_ext_control) * p->count;
239 /* Note: v4l2_ext_controls fits in sbuf[] so mbuf is still NULL. */
240 mbuf = kmalloc(ctrls_size, GFP_KERNEL);
241 err = -ENOMEM;
242 if (NULL == mbuf)
243 goto out_ext_ctrl;
244 err = -EFAULT;
245 if (copy_from_user(mbuf, user_ptr, ctrls_size))
246 goto out_ext_ctrl;
247 p->controls = mbuf;
251 /* call driver */
252 err = func(inode, file, cmd, parg);
253 if (err == -ENOIOCTLCMD)
254 err = -EINVAL;
255 if (is_ext_ctrl) {
256 struct v4l2_ext_controls *p = parg;
258 p->controls = (void *)user_ptr;
259 if (p->count && err == 0 && copy_to_user(user_ptr, mbuf, ctrls_size))
260 err = -EFAULT;
261 goto out_ext_ctrl;
263 if (err < 0)
264 goto out;
266 out_ext_ctrl:
267 /* Copy results into user buffer */
268 switch (_IOC_DIR(cmd))
270 case _IOC_READ:
271 case (_IOC_WRITE | _IOC_READ):
272 if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd)))
273 err = -EFAULT;
274 break;
277 out:
278 kfree(mbuf);
279 return err;
283 * open/release helper functions -- handle exclusive opens
284 * Should be removed soon
286 int video_exclusive_open(struct inode *inode, struct file *file)
288 struct video_device *vfl = video_devdata(file);
289 int retval = 0;
291 mutex_lock(&vfl->lock);
292 if (vfl->users) {
293 retval = -EBUSY;
294 } else {
295 vfl->users++;
297 mutex_unlock(&vfl->lock);
298 return retval;
301 int video_exclusive_release(struct inode *inode, struct file *file)
303 struct video_device *vfl = video_devdata(file);
305 vfl->users--;
306 return 0;
309 static char *v4l2_memory_names[] = {
310 [V4L2_MEMORY_MMAP] = "mmap",
311 [V4L2_MEMORY_USERPTR] = "userptr",
312 [V4L2_MEMORY_OVERLAY] = "overlay",
316 /* FIXME: Those stuff are replicated also on v4l2-common.c */
317 static char *v4l2_type_names_FIXME[] = {
318 [V4L2_BUF_TYPE_VIDEO_CAPTURE] = "video-cap",
319 [V4L2_BUF_TYPE_VIDEO_OVERLAY] = "video-over",
320 [V4L2_BUF_TYPE_VIDEO_OUTPUT] = "video-out",
321 [V4L2_BUF_TYPE_VBI_CAPTURE] = "vbi-cap",
322 [V4L2_BUF_TYPE_VBI_OUTPUT] = "vbi-out",
323 [V4L2_BUF_TYPE_SLICED_VBI_OUTPUT] = "sliced-vbi-out",
324 [V4L2_BUF_TYPE_SLICED_VBI_CAPTURE] = "sliced-vbi-capture",
325 [V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY] = "video-out-over",
326 [V4L2_BUF_TYPE_PRIVATE] = "private",
329 static char *v4l2_field_names_FIXME[] = {
330 [V4L2_FIELD_ANY] = "any",
331 [V4L2_FIELD_NONE] = "none",
332 [V4L2_FIELD_TOP] = "top",
333 [V4L2_FIELD_BOTTOM] = "bottom",
334 [V4L2_FIELD_INTERLACED] = "interlaced",
335 [V4L2_FIELD_SEQ_TB] = "seq-tb",
336 [V4L2_FIELD_SEQ_BT] = "seq-bt",
337 [V4L2_FIELD_ALTERNATE] = "alternate",
338 [V4L2_FIELD_INTERLACED_TB] = "interlaced-tb",
339 [V4L2_FIELD_INTERLACED_BT] = "interlaced-bt",
342 #define prt_names(a,arr) (((a)>=0)&&((a)<ARRAY_SIZE(arr)))?arr[a]:"unknown"
344 static void dbgbuf(unsigned int cmd, struct video_device *vfd,
345 struct v4l2_buffer *p)
347 struct v4l2_timecode *tc=&p->timecode;
349 dbgarg (cmd, "%02ld:%02d:%02d.%08ld index=%d, type=%s, "
350 "bytesused=%d, flags=0x%08d, "
351 "field=%0d, sequence=%d, memory=%s, offset/userptr=0x%08lx, length=%d\n",
352 (p->timestamp.tv_sec/3600),
353 (int)(p->timestamp.tv_sec/60)%60,
354 (int)(p->timestamp.tv_sec%60),
355 p->timestamp.tv_usec,
356 p->index,
357 prt_names(p->type,v4l2_type_names_FIXME),
358 p->bytesused,p->flags,
359 p->field,p->sequence,
360 prt_names(p->memory,v4l2_memory_names),
361 p->m.userptr, p->length);
362 dbgarg2 ("timecode= %02d:%02d:%02d type=%d, "
363 "flags=0x%08d, frames=%d, userbits=0x%08x\n",
364 tc->hours,tc->minutes,tc->seconds,
365 tc->type, tc->flags, tc->frames, *(__u32 *) tc->userbits);
368 static inline void dbgrect(struct video_device *vfd, char *s,
369 struct v4l2_rect *r)
371 dbgarg2 ("%sRect start at %dx%d, size= %dx%d\n", s, r->left, r->top,
372 r->width, r->height);
375 static inline void v4l_print_pix_fmt (struct video_device *vfd,
376 struct v4l2_pix_format *fmt)
378 dbgarg2 ("width=%d, height=%d, format=%c%c%c%c, field=%s, "
379 "bytesperline=%d sizeimage=%d, colorspace=%d\n",
380 fmt->width,fmt->height,
381 (fmt->pixelformat & 0xff),
382 (fmt->pixelformat >> 8) & 0xff,
383 (fmt->pixelformat >> 16) & 0xff,
384 (fmt->pixelformat >> 24) & 0xff,
385 prt_names(fmt->field,v4l2_field_names_FIXME),
386 fmt->bytesperline,fmt->sizeimage,fmt->colorspace);
390 static int check_fmt (struct video_device *vfd, enum v4l2_buf_type type)
392 switch (type) {
393 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
394 if (vfd->vidioc_try_fmt_cap)
395 return (0);
396 break;
397 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
398 if (vfd->vidioc_try_fmt_overlay)
399 return (0);
400 break;
401 case V4L2_BUF_TYPE_VBI_CAPTURE:
402 if (vfd->vidioc_try_fmt_vbi)
403 return (0);
404 break;
405 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
406 if (vfd->vidioc_try_fmt_vbi_output)
407 return (0);
408 break;
409 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
410 if (vfd->vidioc_try_fmt_vbi_capture)
411 return (0);
412 break;
413 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
414 if (vfd->vidioc_try_fmt_video_output)
415 return (0);
416 break;
417 case V4L2_BUF_TYPE_VBI_OUTPUT:
418 if (vfd->vidioc_try_fmt_vbi_output)
419 return (0);
420 break;
421 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
422 if (vfd->vidioc_try_fmt_output_overlay)
423 return (0);
424 break;
425 case V4L2_BUF_TYPE_PRIVATE:
426 if (vfd->vidioc_try_fmt_type_private)
427 return (0);
428 break;
430 return (-EINVAL);
433 static int __video_do_ioctl(struct inode *inode, struct file *file,
434 unsigned int cmd, void *arg)
436 struct video_device *vfd = video_devdata(file);
437 void *fh = file->private_data;
438 int ret = -EINVAL;
440 if ( (vfd->debug & V4L2_DEBUG_IOCTL) &&
441 !(vfd->debug & V4L2_DEBUG_IOCTL_ARG)) {
442 v4l_print_ioctl(vfd->name, cmd);
445 #ifdef CONFIG_VIDEO_V4L1_COMPAT
446 /***********************************************************
447 Handles calls to the obsoleted V4L1 API
448 Due to the nature of VIDIOCGMBUF, each driver that supports
449 V4L1 should implement its own handler for this ioctl.
450 ***********************************************************/
452 /* --- streaming capture ------------------------------------- */
453 if (cmd == VIDIOCGMBUF) {
454 struct video_mbuf *p=arg;
456 memset(p, 0, sizeof(*p));
458 if (!vfd->vidiocgmbuf)
459 return ret;
460 ret=vfd->vidiocgmbuf(file, fh, p);
461 if (!ret)
462 dbgarg (cmd, "size=%d, frames=%d, offsets=0x%08lx\n",
463 p->size, p->frames,
464 (unsigned long)p->offsets);
465 return ret;
468 /********************************************************
469 All other V4L1 calls are handled by v4l1_compat module.
470 Those calls will be translated into V4L2 calls, and
471 __video_do_ioctl will be called again, with one or more
472 V4L2 ioctls.
473 ********************************************************/
474 if (_IOC_TYPE(cmd)=='v')
475 return v4l_compat_translate_ioctl(inode,file,cmd,arg,
476 __video_do_ioctl);
477 #endif
479 switch(cmd) {
480 /* --- capabilities ------------------------------------------ */
481 case VIDIOC_QUERYCAP:
483 struct v4l2_capability *cap = (struct v4l2_capability*)arg;
484 memset(cap, 0, sizeof(*cap));
486 if (!vfd->vidioc_querycap)
487 break;
489 ret=vfd->vidioc_querycap(file, fh, cap);
490 if (!ret)
491 dbgarg (cmd, "driver=%s, card=%s, bus=%s, "
492 "version=0x%08x, "
493 "capabilities=0x%08x\n",
494 cap->driver,cap->card,cap->bus_info,
495 cap->version,
496 cap->capabilities);
497 break;
500 /* --- priority ------------------------------------------ */
501 case VIDIOC_G_PRIORITY:
503 enum v4l2_priority *p=arg;
505 if (!vfd->vidioc_g_priority)
506 break;
507 ret=vfd->vidioc_g_priority(file, fh, p);
508 if (!ret)
509 dbgarg(cmd, "priority is %d\n", *p);
510 break;
512 case VIDIOC_S_PRIORITY:
514 enum v4l2_priority *p=arg;
516 if (!vfd->vidioc_s_priority)
517 break;
518 dbgarg(cmd, "setting priority to %d\n", *p);
519 ret=vfd->vidioc_s_priority(file, fh, *p);
520 break;
523 /* --- capture ioctls ---------------------------------------- */
524 case VIDIOC_ENUM_FMT:
526 struct v4l2_fmtdesc *f = arg;
527 enum v4l2_buf_type type;
528 unsigned int index;
530 index = f->index;
531 type = f->type;
532 memset(f,0,sizeof(*f));
533 f->index = index;
534 f->type = type;
536 switch (type) {
537 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
538 if (vfd->vidioc_enum_fmt_cap)
539 ret=vfd->vidioc_enum_fmt_cap(file, fh, f);
540 break;
541 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
542 if (vfd->vidioc_enum_fmt_overlay)
543 ret=vfd->vidioc_enum_fmt_overlay(file, fh, f);
544 break;
545 case V4L2_BUF_TYPE_VBI_CAPTURE:
546 if (vfd->vidioc_enum_fmt_vbi)
547 ret=vfd->vidioc_enum_fmt_vbi(file, fh, f);
548 break;
549 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
550 if (vfd->vidioc_enum_fmt_vbi_output)
551 ret=vfd->vidioc_enum_fmt_vbi_output(file,
552 fh, f);
553 break;
554 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
555 if (vfd->vidioc_enum_fmt_vbi_capture)
556 ret=vfd->vidioc_enum_fmt_vbi_capture(file,
557 fh, f);
558 break;
559 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
560 if (vfd->vidioc_enum_fmt_video_output)
561 ret=vfd->vidioc_enum_fmt_video_output(file,
562 fh, f);
563 break;
564 case V4L2_BUF_TYPE_VBI_OUTPUT:
565 if (vfd->vidioc_enum_fmt_vbi_output)
566 ret=vfd->vidioc_enum_fmt_vbi_output(file,
567 fh, f);
568 break;
569 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
570 if (vfd->vidioc_enum_fmt_output_overlay)
571 ret=vfd->vidioc_enum_fmt_output_overlay(file, fh, f);
572 break;
573 case V4L2_BUF_TYPE_PRIVATE:
574 if (vfd->vidioc_enum_fmt_type_private)
575 ret=vfd->vidioc_enum_fmt_type_private(file,
576 fh, f);
577 break;
579 if (!ret)
580 dbgarg (cmd, "index=%d, type=%d, flags=%d, "
581 "pixelformat=%c%c%c%c, description='%s'\n",
582 f->index, f->type, f->flags,
583 (f->pixelformat & 0xff),
584 (f->pixelformat >> 8) & 0xff,
585 (f->pixelformat >> 16) & 0xff,
586 (f->pixelformat >> 24) & 0xff,
587 f->description);
588 break;
590 case VIDIOC_G_FMT:
592 struct v4l2_format *f = (struct v4l2_format *)arg;
593 enum v4l2_buf_type type=f->type;
595 memset(&f->fmt.pix,0,sizeof(f->fmt.pix));
596 f->type=type;
598 /* FIXME: Should be one dump per type */
599 dbgarg (cmd, "type=%s\n", prt_names(type,
600 v4l2_type_names_FIXME));
602 switch (type) {
603 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
604 if (vfd->vidioc_g_fmt_cap)
605 ret=vfd->vidioc_g_fmt_cap(file, fh, f);
606 if (!ret)
607 v4l_print_pix_fmt(vfd,&f->fmt.pix);
608 break;
609 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
610 if (vfd->vidioc_g_fmt_overlay)
611 ret=vfd->vidioc_g_fmt_overlay(file, fh, f);
612 break;
613 case V4L2_BUF_TYPE_VBI_CAPTURE:
614 if (vfd->vidioc_g_fmt_vbi)
615 ret=vfd->vidioc_g_fmt_vbi(file, fh, f);
616 break;
617 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
618 if (vfd->vidioc_g_fmt_vbi_output)
619 ret=vfd->vidioc_g_fmt_vbi_output(file, fh, f);
620 break;
621 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
622 if (vfd->vidioc_g_fmt_vbi_capture)
623 ret=vfd->vidioc_g_fmt_vbi_capture(file, fh, f);
624 break;
625 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
626 if (vfd->vidioc_g_fmt_video_output)
627 ret=vfd->vidioc_g_fmt_video_output(file,
628 fh, f);
629 break;
630 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
631 if (vfd->vidioc_g_fmt_output_overlay)
632 ret=vfd->vidioc_g_fmt_output_overlay(file, fh, f);
633 break;
634 case V4L2_BUF_TYPE_VBI_OUTPUT:
635 if (vfd->vidioc_g_fmt_vbi_output)
636 ret=vfd->vidioc_g_fmt_vbi_output(file, fh, f);
637 break;
638 case V4L2_BUF_TYPE_PRIVATE:
639 if (vfd->vidioc_g_fmt_type_private)
640 ret=vfd->vidioc_g_fmt_type_private(file,
641 fh, f);
642 break;
645 break;
647 case VIDIOC_S_FMT:
649 struct v4l2_format *f = (struct v4l2_format *)arg;
651 /* FIXME: Should be one dump per type */
652 dbgarg (cmd, "type=%s\n", prt_names(f->type,
653 v4l2_type_names_FIXME));
655 switch (f->type) {
656 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
657 v4l_print_pix_fmt(vfd,&f->fmt.pix);
658 if (vfd->vidioc_s_fmt_cap)
659 ret=vfd->vidioc_s_fmt_cap(file, fh, f);
660 break;
661 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
662 if (vfd->vidioc_s_fmt_overlay)
663 ret=vfd->vidioc_s_fmt_overlay(file, fh, f);
664 break;
665 case V4L2_BUF_TYPE_VBI_CAPTURE:
666 if (vfd->vidioc_s_fmt_vbi)
667 ret=vfd->vidioc_s_fmt_vbi(file, fh, f);
668 break;
669 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
670 if (vfd->vidioc_s_fmt_vbi_output)
671 ret=vfd->vidioc_s_fmt_vbi_output(file, fh, f);
672 break;
673 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
674 if (vfd->vidioc_s_fmt_vbi_capture)
675 ret=vfd->vidioc_s_fmt_vbi_capture(file, fh, f);
676 break;
677 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
678 if (vfd->vidioc_s_fmt_video_output)
679 ret=vfd->vidioc_s_fmt_video_output(file,
680 fh, f);
681 break;
682 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
683 if (vfd->vidioc_s_fmt_output_overlay)
684 ret=vfd->vidioc_s_fmt_output_overlay(file, fh, f);
685 break;
686 case V4L2_BUF_TYPE_VBI_OUTPUT:
687 if (vfd->vidioc_s_fmt_vbi_output)
688 ret=vfd->vidioc_s_fmt_vbi_output(file,
689 fh, f);
690 break;
691 case V4L2_BUF_TYPE_PRIVATE:
692 if (vfd->vidioc_s_fmt_type_private)
693 ret=vfd->vidioc_s_fmt_type_private(file,
694 fh, f);
695 break;
697 break;
699 case VIDIOC_TRY_FMT:
701 struct v4l2_format *f = (struct v4l2_format *)arg;
703 /* FIXME: Should be one dump per type */
704 dbgarg (cmd, "type=%s\n", prt_names(f->type,
705 v4l2_type_names_FIXME));
706 switch (f->type) {
707 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
708 if (vfd->vidioc_try_fmt_cap)
709 ret=vfd->vidioc_try_fmt_cap(file, fh, f);
710 if (!ret)
711 v4l_print_pix_fmt(vfd,&f->fmt.pix);
712 break;
713 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
714 if (vfd->vidioc_try_fmt_overlay)
715 ret=vfd->vidioc_try_fmt_overlay(file, fh, f);
716 break;
717 case V4L2_BUF_TYPE_VBI_CAPTURE:
718 if (vfd->vidioc_try_fmt_vbi)
719 ret=vfd->vidioc_try_fmt_vbi(file, fh, f);
720 break;
721 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
722 if (vfd->vidioc_try_fmt_vbi_output)
723 ret=vfd->vidioc_try_fmt_vbi_output(file,
724 fh, f);
725 break;
726 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
727 if (vfd->vidioc_try_fmt_vbi_capture)
728 ret=vfd->vidioc_try_fmt_vbi_capture(file,
729 fh, f);
730 break;
731 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
732 if (vfd->vidioc_try_fmt_video_output)
733 ret=vfd->vidioc_try_fmt_video_output(file,
734 fh, f);
735 break;
736 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
737 if (vfd->vidioc_try_fmt_output_overlay)
738 ret=vfd->vidioc_try_fmt_output_overlay(file, fh, f);
739 break;
740 case V4L2_BUF_TYPE_VBI_OUTPUT:
741 if (vfd->vidioc_try_fmt_vbi_output)
742 ret=vfd->vidioc_try_fmt_vbi_output(file,
743 fh, f);
744 break;
745 case V4L2_BUF_TYPE_PRIVATE:
746 if (vfd->vidioc_try_fmt_type_private)
747 ret=vfd->vidioc_try_fmt_type_private(file,
748 fh, f);
749 break;
752 break;
754 /* FIXME: Those buf reqs could be handled here,
755 with some changes on videobuf to allow its header to be included at
756 videodev2.h or being merged at videodev2.
758 case VIDIOC_REQBUFS:
760 struct v4l2_requestbuffers *p=arg;
762 if (!vfd->vidioc_reqbufs)
763 break;
764 ret = check_fmt (vfd, p->type);
765 if (ret)
766 break;
768 ret=vfd->vidioc_reqbufs(file, fh, p);
769 dbgarg (cmd, "count=%d, type=%s, memory=%s\n",
770 p->count,
771 prt_names(p->type,v4l2_type_names_FIXME),
772 prt_names(p->memory,v4l2_memory_names));
773 break;
775 case VIDIOC_QUERYBUF:
777 struct v4l2_buffer *p=arg;
779 if (!vfd->vidioc_querybuf)
780 break;
781 ret = check_fmt (vfd, p->type);
782 if (ret)
783 break;
785 ret=vfd->vidioc_querybuf(file, fh, p);
786 if (!ret)
787 dbgbuf(cmd,vfd,p);
788 break;
790 case VIDIOC_QBUF:
792 struct v4l2_buffer *p=arg;
794 if (!vfd->vidioc_qbuf)
795 break;
796 ret = check_fmt (vfd, p->type);
797 if (ret)
798 break;
800 ret=vfd->vidioc_qbuf(file, fh, p);
801 if (!ret)
802 dbgbuf(cmd,vfd,p);
803 break;
805 case VIDIOC_DQBUF:
807 struct v4l2_buffer *p=arg;
808 if (!vfd->vidioc_dqbuf)
809 break;
810 ret = check_fmt (vfd, p->type);
811 if (ret)
812 break;
814 ret=vfd->vidioc_dqbuf(file, fh, p);
815 if (!ret)
816 dbgbuf(cmd,vfd,p);
817 break;
819 case VIDIOC_OVERLAY:
821 int *i = arg;
823 if (!vfd->vidioc_overlay)
824 break;
825 dbgarg (cmd, "value=%d\n",*i);
826 ret=vfd->vidioc_overlay(file, fh, *i);
827 break;
829 case VIDIOC_G_FBUF:
831 struct v4l2_framebuffer *p=arg;
832 if (!vfd->vidioc_g_fbuf)
833 break;
834 ret=vfd->vidioc_g_fbuf(file, fh, arg);
835 if (!ret) {
836 dbgarg (cmd, "capability=%d, flags=%d, base=0x%08lx\n",
837 p->capability,p->flags,
838 (unsigned long)p->base);
839 v4l_print_pix_fmt (vfd, &p->fmt);
841 break;
843 case VIDIOC_S_FBUF:
845 struct v4l2_framebuffer *p=arg;
846 if (!vfd->vidioc_s_fbuf)
847 break;
849 dbgarg (cmd, "capability=%d, flags=%d, base=0x%08lx\n",
850 p->capability,p->flags,(unsigned long)p->base);
851 v4l_print_pix_fmt (vfd, &p->fmt);
852 ret=vfd->vidioc_s_fbuf(file, fh, arg);
854 break;
856 case VIDIOC_STREAMON:
858 enum v4l2_buf_type i = *(int *)arg;
859 if (!vfd->vidioc_streamon)
860 break;
861 dbgarg (cmd, "type=%s\n", prt_names(i,v4l2_type_names_FIXME));
862 ret=vfd->vidioc_streamon(file, fh,i);
863 break;
865 case VIDIOC_STREAMOFF:
867 enum v4l2_buf_type i = *(int *)arg;
869 if (!vfd->vidioc_streamoff)
870 break;
871 dbgarg (cmd, "type=%s\n", prt_names(i,v4l2_type_names_FIXME));
872 ret=vfd->vidioc_streamoff(file, fh, i);
873 break;
875 /* ---------- tv norms ---------- */
876 case VIDIOC_ENUMSTD:
878 struct v4l2_standard *p = arg;
879 v4l2_std_id id = vfd->tvnorms,curr_id=0;
880 unsigned int index = p->index,i;
882 if (index<0) {
883 ret=-EINVAL;
884 break;
887 /* Return norm array on a canonical way */
888 for (i=0;i<= index && id; i++) {
889 if ( (id & V4L2_STD_PAL) == V4L2_STD_PAL) {
890 curr_id = V4L2_STD_PAL;
891 } else if ( (id & V4L2_STD_PAL_BG) == V4L2_STD_PAL_BG) {
892 curr_id = V4L2_STD_PAL_BG;
893 } else if ( (id & V4L2_STD_PAL_DK) == V4L2_STD_PAL_DK) {
894 curr_id = V4L2_STD_PAL_DK;
895 } else if ( (id & V4L2_STD_PAL_B) == V4L2_STD_PAL_B) {
896 curr_id = V4L2_STD_PAL_B;
897 } else if ( (id & V4L2_STD_PAL_B1) == V4L2_STD_PAL_B1) {
898 curr_id = V4L2_STD_PAL_B1;
899 } else if ( (id & V4L2_STD_PAL_G) == V4L2_STD_PAL_G) {
900 curr_id = V4L2_STD_PAL_G;
901 } else if ( (id & V4L2_STD_PAL_H) == V4L2_STD_PAL_H) {
902 curr_id = V4L2_STD_PAL_H;
903 } else if ( (id & V4L2_STD_PAL_I) == V4L2_STD_PAL_I) {
904 curr_id = V4L2_STD_PAL_I;
905 } else if ( (id & V4L2_STD_PAL_D) == V4L2_STD_PAL_D) {
906 curr_id = V4L2_STD_PAL_D;
907 } else if ( (id & V4L2_STD_PAL_D1) == V4L2_STD_PAL_D1) {
908 curr_id = V4L2_STD_PAL_D1;
909 } else if ( (id & V4L2_STD_PAL_K) == V4L2_STD_PAL_K) {
910 curr_id = V4L2_STD_PAL_K;
911 } else if ( (id & V4L2_STD_PAL_M) == V4L2_STD_PAL_M) {
912 curr_id = V4L2_STD_PAL_M;
913 } else if ( (id & V4L2_STD_PAL_N) == V4L2_STD_PAL_N) {
914 curr_id = V4L2_STD_PAL_N;
915 } else if ( (id & V4L2_STD_PAL_Nc) == V4L2_STD_PAL_Nc) {
916 curr_id = V4L2_STD_PAL_Nc;
917 } else if ( (id & V4L2_STD_PAL_60) == V4L2_STD_PAL_60) {
918 curr_id = V4L2_STD_PAL_60;
919 } else if ( (id & V4L2_STD_NTSC) == V4L2_STD_NTSC) {
920 curr_id = V4L2_STD_NTSC;
921 } else if ( (id & V4L2_STD_NTSC_M) == V4L2_STD_NTSC_M) {
922 curr_id = V4L2_STD_NTSC_M;
923 } else if ( (id & V4L2_STD_NTSC_M_JP) == V4L2_STD_NTSC_M_JP) {
924 curr_id = V4L2_STD_NTSC_M_JP;
925 } else if ( (id & V4L2_STD_NTSC_443) == V4L2_STD_NTSC_443) {
926 curr_id = V4L2_STD_NTSC_443;
927 } else if ( (id & V4L2_STD_NTSC_M_KR) == V4L2_STD_NTSC_M_KR) {
928 curr_id = V4L2_STD_NTSC_M_KR;
929 } else if ( (id & V4L2_STD_SECAM) == V4L2_STD_SECAM) {
930 curr_id = V4L2_STD_SECAM;
931 } else if ( (id & V4L2_STD_SECAM_DK) == V4L2_STD_SECAM_DK) {
932 curr_id = V4L2_STD_SECAM_DK;
933 } else if ( (id & V4L2_STD_SECAM_B) == V4L2_STD_SECAM_B) {
934 curr_id = V4L2_STD_SECAM_B;
935 } else if ( (id & V4L2_STD_SECAM_D) == V4L2_STD_SECAM_D) {
936 curr_id = V4L2_STD_SECAM_D;
937 } else if ( (id & V4L2_STD_SECAM_G) == V4L2_STD_SECAM_G) {
938 curr_id = V4L2_STD_SECAM_G;
939 } else if ( (id & V4L2_STD_SECAM_H) == V4L2_STD_SECAM_H) {
940 curr_id = V4L2_STD_SECAM_H;
941 } else if ( (id & V4L2_STD_SECAM_K) == V4L2_STD_SECAM_K) {
942 curr_id = V4L2_STD_SECAM_K;
943 } else if ( (id & V4L2_STD_SECAM_K1) == V4L2_STD_SECAM_K1) {
944 curr_id = V4L2_STD_SECAM_K1;
945 } else if ( (id & V4L2_STD_SECAM_L) == V4L2_STD_SECAM_L) {
946 curr_id = V4L2_STD_SECAM_L;
947 } else if ( (id & V4L2_STD_SECAM_LC) == V4L2_STD_SECAM_LC) {
948 curr_id = V4L2_STD_SECAM_LC;
949 } else {
950 break;
952 id &= ~curr_id;
954 if (i<=index)
955 return -EINVAL;
957 v4l2_video_std_construct(p, curr_id,v4l2_norm_to_name(curr_id));
958 p->index = index;
960 dbgarg (cmd, "index=%d, id=%Ld, name=%s, fps=%d/%d, "
961 "framelines=%d\n", p->index,
962 (unsigned long long)p->id, p->name,
963 p->frameperiod.numerator,
964 p->frameperiod.denominator,
965 p->framelines);
967 ret=0;
968 break;
970 case VIDIOC_G_STD:
972 v4l2_std_id *id = arg;
974 *id = vfd->current_norm;
976 dbgarg (cmd, "value=%Lu\n", (long long unsigned) *id);
978 ret=0;
979 break;
981 case VIDIOC_S_STD:
983 v4l2_std_id *id = arg,norm;
985 dbgarg (cmd, "value=%Lu\n", (long long unsigned) *id);
987 norm = (*id) & vfd->tvnorms;
988 if ( vfd->tvnorms && !norm) /* Check if std is supported */
989 break;
991 /* Calls the specific handler */
992 if (vfd->vidioc_s_std)
993 ret=vfd->vidioc_s_std(file, fh, &norm);
994 else
995 ret=-EINVAL;
997 /* Updates standard information */
998 if (ret>=0)
999 vfd->current_norm=norm;
1001 break;
1003 case VIDIOC_QUERYSTD:
1005 v4l2_std_id *p=arg;
1007 if (!vfd->vidioc_querystd)
1008 break;
1009 ret=vfd->vidioc_querystd(file, fh, arg);
1010 if (!ret)
1011 dbgarg (cmd, "detected std=%Lu\n",
1012 (unsigned long long)*p);
1013 break;
1015 /* ------ input switching ---------- */
1016 /* FIXME: Inputs can be handled inside videodev2 */
1017 case VIDIOC_ENUMINPUT:
1019 struct v4l2_input *p=arg;
1020 int i=p->index;
1022 if (!vfd->vidioc_enum_input)
1023 break;
1024 memset(p, 0, sizeof(*p));
1025 p->index=i;
1027 ret=vfd->vidioc_enum_input(file, fh, p);
1028 if (!ret)
1029 dbgarg (cmd, "index=%d, name=%s, type=%d, "
1030 "audioset=%d, "
1031 "tuner=%d, std=%Ld, status=%d\n",
1032 p->index,p->name,p->type,p->audioset,
1033 p->tuner,
1034 (unsigned long long)p->std,
1035 p->status);
1036 break;
1038 case VIDIOC_G_INPUT:
1040 unsigned int *i = arg;
1042 if (!vfd->vidioc_g_input)
1043 break;
1044 ret=vfd->vidioc_g_input(file, fh, i);
1045 if (!ret)
1046 dbgarg (cmd, "value=%d\n",*i);
1047 break;
1049 case VIDIOC_S_INPUT:
1051 unsigned int *i = arg;
1053 if (!vfd->vidioc_s_input)
1054 break;
1055 dbgarg (cmd, "value=%d\n",*i);
1056 ret=vfd->vidioc_s_input(file, fh, *i);
1057 break;
1060 /* ------ output switching ---------- */
1061 case VIDIOC_G_OUTPUT:
1063 unsigned int *i = arg;
1065 if (!vfd->vidioc_g_output)
1066 break;
1067 ret=vfd->vidioc_g_output(file, fh, i);
1068 if (!ret)
1069 dbgarg (cmd, "value=%d\n",*i);
1070 break;
1072 case VIDIOC_S_OUTPUT:
1074 unsigned int *i = arg;
1076 if (!vfd->vidioc_s_output)
1077 break;
1078 dbgarg (cmd, "value=%d\n",*i);
1079 ret=vfd->vidioc_s_output(file, fh, *i);
1080 break;
1083 /* --- controls ---------------------------------------------- */
1084 case VIDIOC_QUERYCTRL:
1086 struct v4l2_queryctrl *p=arg;
1088 if (!vfd->vidioc_queryctrl)
1089 break;
1090 ret=vfd->vidioc_queryctrl(file, fh, p);
1092 if (!ret)
1093 dbgarg (cmd, "id=%d, type=%d, name=%s, "
1094 "min/max=%d/%d,"
1095 " step=%d, default=%d, flags=0x%08x\n",
1096 p->id,p->type,p->name,p->minimum,
1097 p->maximum,p->step,p->default_value,
1098 p->flags);
1099 break;
1101 case VIDIOC_G_CTRL:
1103 struct v4l2_control *p = arg;
1105 if (!vfd->vidioc_g_ctrl)
1106 break;
1107 dbgarg(cmd, "Enum for index=%d\n", p->id);
1109 ret=vfd->vidioc_g_ctrl(file, fh, p);
1110 if (!ret)
1111 dbgarg2 ( "id=%d, value=%d\n", p->id, p->value);
1112 break;
1114 case VIDIOC_S_CTRL:
1116 struct v4l2_control *p = arg;
1118 if (!vfd->vidioc_s_ctrl)
1119 break;
1120 dbgarg (cmd, "id=%d, value=%d\n", p->id, p->value);
1122 ret=vfd->vidioc_s_ctrl(file, fh, p);
1123 break;
1125 case VIDIOC_G_EXT_CTRLS:
1127 struct v4l2_ext_controls *p = arg;
1129 if (vfd->vidioc_g_ext_ctrls) {
1130 dbgarg(cmd, "count=%d\n", p->count);
1132 ret=vfd->vidioc_g_ext_ctrls(file, fh, p);
1134 break;
1136 case VIDIOC_S_EXT_CTRLS:
1138 struct v4l2_ext_controls *p = arg;
1140 if (vfd->vidioc_s_ext_ctrls) {
1141 dbgarg(cmd, "count=%d\n", p->count);
1143 ret=vfd->vidioc_s_ext_ctrls(file, fh, p);
1145 break;
1147 case VIDIOC_TRY_EXT_CTRLS:
1149 struct v4l2_ext_controls *p = arg;
1151 if (vfd->vidioc_try_ext_ctrls) {
1152 dbgarg(cmd, "count=%d\n", p->count);
1154 ret=vfd->vidioc_try_ext_ctrls(file, fh, p);
1156 break;
1158 case VIDIOC_QUERYMENU:
1160 struct v4l2_querymenu *p=arg;
1161 if (!vfd->vidioc_querymenu)
1162 break;
1163 ret=vfd->vidioc_querymenu(file, fh, p);
1164 if (!ret)
1165 dbgarg (cmd, "id=%d, index=%d, name=%s\n",
1166 p->id,p->index,p->name);
1167 break;
1169 /* --- audio ---------------------------------------------- */
1170 case VIDIOC_ENUMAUDIO:
1172 struct v4l2_audio *p=arg;
1174 if (!vfd->vidioc_enumaudio)
1175 break;
1176 dbgarg(cmd, "Enum for index=%d\n", p->index);
1177 ret=vfd->vidioc_enumaudio(file, fh, p);
1178 if (!ret)
1179 dbgarg2("index=%d, name=%s, capability=%d, "
1180 "mode=%d\n",p->index,p->name,
1181 p->capability, p->mode);
1182 break;
1184 case VIDIOC_G_AUDIO:
1186 struct v4l2_audio *p=arg;
1187 __u32 index=p->index;
1189 if (!vfd->vidioc_g_audio)
1190 break;
1192 memset(p,0,sizeof(*p));
1193 p->index=index;
1194 dbgarg(cmd, "Get for index=%d\n", p->index);
1195 ret=vfd->vidioc_g_audio(file, fh, p);
1196 if (!ret)
1197 dbgarg2("index=%d, name=%s, capability=%d, "
1198 "mode=%d\n",p->index,
1199 p->name,p->capability, p->mode);
1200 break;
1202 case VIDIOC_S_AUDIO:
1204 struct v4l2_audio *p=arg;
1206 if (!vfd->vidioc_s_audio)
1207 break;
1208 dbgarg(cmd, "index=%d, name=%s, capability=%d, "
1209 "mode=%d\n", p->index, p->name,
1210 p->capability, p->mode);
1211 ret=vfd->vidioc_s_audio(file, fh, p);
1212 break;
1214 case VIDIOC_ENUMAUDOUT:
1216 struct v4l2_audioout *p=arg;
1218 if (!vfd->vidioc_enumaudout)
1219 break;
1220 dbgarg(cmd, "Enum for index=%d\n", p->index);
1221 ret=vfd->vidioc_enumaudout(file, fh, p);
1222 if (!ret)
1223 dbgarg2("index=%d, name=%s, capability=%d, "
1224 "mode=%d\n", p->index, p->name,
1225 p->capability,p->mode);
1226 break;
1228 case VIDIOC_G_AUDOUT:
1230 struct v4l2_audioout *p=arg;
1232 if (!vfd->vidioc_g_audout)
1233 break;
1234 dbgarg(cmd, "Enum for index=%d\n", p->index);
1235 ret=vfd->vidioc_g_audout(file, fh, p);
1236 if (!ret)
1237 dbgarg2("index=%d, name=%s, capability=%d, "
1238 "mode=%d\n", p->index, p->name,
1239 p->capability,p->mode);
1240 break;
1242 case VIDIOC_S_AUDOUT:
1244 struct v4l2_audioout *p=arg;
1246 if (!vfd->vidioc_s_audout)
1247 break;
1248 dbgarg(cmd, "index=%d, name=%s, capability=%d, "
1249 "mode=%d\n", p->index, p->name,
1250 p->capability,p->mode);
1252 ret=vfd->vidioc_s_audout(file, fh, p);
1253 break;
1255 case VIDIOC_G_MODULATOR:
1257 struct v4l2_modulator *p=arg;
1258 if (!vfd->vidioc_g_modulator)
1259 break;
1260 ret=vfd->vidioc_g_modulator(file, fh, p);
1261 if (!ret)
1262 dbgarg(cmd, "index=%d, name=%s, "
1263 "capability=%d, rangelow=%d,"
1264 " rangehigh=%d, txsubchans=%d\n",
1265 p->index, p->name,p->capability,
1266 p->rangelow, p->rangehigh,
1267 p->txsubchans);
1268 break;
1270 case VIDIOC_S_MODULATOR:
1272 struct v4l2_modulator *p=arg;
1273 if (!vfd->vidioc_s_modulator)
1274 break;
1275 dbgarg(cmd, "index=%d, name=%s, capability=%d, "
1276 "rangelow=%d, rangehigh=%d, txsubchans=%d\n",
1277 p->index, p->name,p->capability,p->rangelow,
1278 p->rangehigh,p->txsubchans);
1279 ret=vfd->vidioc_s_modulator(file, fh, p);
1280 break;
1282 case VIDIOC_G_CROP:
1284 struct v4l2_crop *p=arg;
1285 if (!vfd->vidioc_g_crop)
1286 break;
1287 ret=vfd->vidioc_g_crop(file, fh, p);
1288 if (!ret) {
1289 dbgarg(cmd, "type=%d\n", p->type);
1290 dbgrect(vfd, "", &p->c);
1292 break;
1294 case VIDIOC_S_CROP:
1296 struct v4l2_crop *p=arg;
1297 if (!vfd->vidioc_s_crop)
1298 break;
1299 dbgarg(cmd, "type=%d\n", p->type);
1300 dbgrect(vfd, "", &p->c);
1301 ret=vfd->vidioc_s_crop(file, fh, p);
1302 break;
1304 case VIDIOC_CROPCAP:
1306 struct v4l2_cropcap *p=arg;
1307 /*FIXME: Should also show v4l2_fract pixelaspect */
1308 if (!vfd->vidioc_cropcap)
1309 break;
1310 dbgarg(cmd, "type=%d\n", p->type);
1311 dbgrect(vfd, "bounds ", &p->bounds);
1312 dbgrect(vfd, "defrect ", &p->defrect);
1313 ret=vfd->vidioc_cropcap(file, fh, p);
1314 break;
1316 case VIDIOC_G_MPEGCOMP:
1318 struct v4l2_mpeg_compression *p=arg;
1320 /*FIXME: Several fields not shown */
1321 if (!vfd->vidioc_g_mpegcomp)
1322 break;
1323 ret=vfd->vidioc_g_mpegcomp(file, fh, p);
1324 if (!ret)
1325 dbgarg (cmd, "ts_pid_pmt=%d, ts_pid_audio=%d,"
1326 " ts_pid_video=%d, ts_pid_pcr=%d, "
1327 "ps_size=%d, au_sample_rate=%d, "
1328 "au_pesid=%c, vi_frame_rate=%d, "
1329 "vi_frames_per_gop=%d, "
1330 "vi_bframes_count=%d, vi_pesid=%c\n",
1331 p->ts_pid_pmt,p->ts_pid_audio,
1332 p->ts_pid_video,p->ts_pid_pcr,
1333 p->ps_size, p->au_sample_rate,
1334 p->au_pesid, p->vi_frame_rate,
1335 p->vi_frames_per_gop,
1336 p->vi_bframes_count, p->vi_pesid);
1337 break;
1339 case VIDIOC_S_MPEGCOMP:
1341 struct v4l2_mpeg_compression *p=arg;
1342 /*FIXME: Several fields not shown */
1343 if (!vfd->vidioc_s_mpegcomp)
1344 break;
1345 dbgarg (cmd, "ts_pid_pmt=%d, ts_pid_audio=%d, "
1346 "ts_pid_video=%d, ts_pid_pcr=%d, ps_size=%d, "
1347 "au_sample_rate=%d, au_pesid=%c, "
1348 "vi_frame_rate=%d, vi_frames_per_gop=%d, "
1349 "vi_bframes_count=%d, vi_pesid=%c\n",
1350 p->ts_pid_pmt,p->ts_pid_audio, p->ts_pid_video,
1351 p->ts_pid_pcr, p->ps_size, p->au_sample_rate,
1352 p->au_pesid, p->vi_frame_rate,
1353 p->vi_frames_per_gop, p->vi_bframes_count,
1354 p->vi_pesid);
1355 ret=vfd->vidioc_s_mpegcomp(file, fh, p);
1356 break;
1358 case VIDIOC_G_JPEGCOMP:
1360 struct v4l2_jpegcompression *p=arg;
1361 if (!vfd->vidioc_g_jpegcomp)
1362 break;
1363 ret=vfd->vidioc_g_jpegcomp(file, fh, p);
1364 if (!ret)
1365 dbgarg (cmd, "quality=%d, APPn=%d, "
1366 "APP_len=%d, COM_len=%d, "
1367 "jpeg_markers=%d\n",
1368 p->quality,p->APPn,p->APP_len,
1369 p->COM_len,p->jpeg_markers);
1370 break;
1372 case VIDIOC_S_JPEGCOMP:
1374 struct v4l2_jpegcompression *p=arg;
1375 if (!vfd->vidioc_g_jpegcomp)
1376 break;
1377 dbgarg (cmd, "quality=%d, APPn=%d, APP_len=%d, "
1378 "COM_len=%d, jpeg_markers=%d\n",
1379 p->quality,p->APPn,p->APP_len,
1380 p->COM_len,p->jpeg_markers);
1381 ret=vfd->vidioc_s_jpegcomp(file, fh, p);
1382 break;
1384 case VIDIOC_G_ENC_INDEX:
1386 struct v4l2_enc_idx *p=arg;
1388 if (!vfd->vidioc_g_enc_index)
1389 break;
1390 ret=vfd->vidioc_g_enc_index(file, fh, p);
1391 if (!ret)
1392 dbgarg (cmd, "entries=%d, entries_cap=%d\n",
1393 p->entries,p->entries_cap);
1394 break;
1396 case VIDIOC_ENCODER_CMD:
1398 struct v4l2_encoder_cmd *p=arg;
1400 if (!vfd->vidioc_encoder_cmd)
1401 break;
1402 ret=vfd->vidioc_encoder_cmd(file, fh, p);
1403 if (!ret)
1404 dbgarg (cmd, "cmd=%d, flags=%d\n",
1405 p->cmd,p->flags);
1406 break;
1408 case VIDIOC_TRY_ENCODER_CMD:
1410 struct v4l2_encoder_cmd *p=arg;
1412 if (!vfd->vidioc_try_encoder_cmd)
1413 break;
1414 ret=vfd->vidioc_try_encoder_cmd(file, fh, p);
1415 if (!ret)
1416 dbgarg (cmd, "cmd=%d, flags=%d\n",
1417 p->cmd,p->flags);
1418 break;
1420 case VIDIOC_G_PARM:
1422 struct v4l2_streamparm *p=arg;
1423 __u32 type=p->type;
1425 memset(p,0,sizeof(*p));
1426 p->type=type;
1428 if (vfd->vidioc_g_parm) {
1429 ret=vfd->vidioc_g_parm(file, fh, p);
1430 } else {
1431 struct v4l2_standard s;
1433 if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1434 return -EINVAL;
1436 v4l2_video_std_construct(&s, vfd->current_norm,
1437 v4l2_norm_to_name(vfd->current_norm));
1439 p->parm.capture.timeperframe = s.frameperiod;
1440 ret=0;
1443 dbgarg (cmd, "type=%d\n", p->type);
1444 break;
1446 case VIDIOC_S_PARM:
1448 struct v4l2_streamparm *p=arg;
1449 if (!vfd->vidioc_s_parm)
1450 break;
1451 dbgarg (cmd, "type=%d\n", p->type);
1452 ret=vfd->vidioc_s_parm(file, fh, p);
1453 break;
1455 case VIDIOC_G_TUNER:
1457 struct v4l2_tuner *p=arg;
1458 __u32 index=p->index;
1460 if (!vfd->vidioc_g_tuner)
1461 break;
1463 memset(p,0,sizeof(*p));
1464 p->index=index;
1466 ret=vfd->vidioc_g_tuner(file, fh, p);
1467 if (!ret)
1468 dbgarg (cmd, "index=%d, name=%s, type=%d, "
1469 "capability=%d, rangelow=%d, "
1470 "rangehigh=%d, signal=%d, afc=%d, "
1471 "rxsubchans=%d, audmode=%d\n",
1472 p->index, p->name, p->type,
1473 p->capability, p->rangelow,
1474 p->rangehigh, p->rxsubchans,
1475 p->audmode, p->signal, p->afc);
1476 break;
1478 case VIDIOC_S_TUNER:
1480 struct v4l2_tuner *p=arg;
1481 if (!vfd->vidioc_s_tuner)
1482 break;
1483 dbgarg (cmd, "index=%d, name=%s, type=%d, "
1484 "capability=%d, rangelow=%d, rangehigh=%d, "
1485 "signal=%d, afc=%d, rxsubchans=%d, "
1486 "audmode=%d\n",p->index, p->name, p->type,
1487 p->capability, p->rangelow,p->rangehigh,
1488 p->rxsubchans, p->audmode, p->signal,
1489 p->afc);
1490 ret=vfd->vidioc_s_tuner(file, fh, p);
1491 break;
1493 case VIDIOC_G_FREQUENCY:
1495 struct v4l2_frequency *p=arg;
1496 if (!vfd->vidioc_g_frequency)
1497 break;
1499 memset(p,0,sizeof(*p));
1501 ret=vfd->vidioc_g_frequency(file, fh, p);
1502 if (!ret)
1503 dbgarg (cmd, "tuner=%d, type=%d, frequency=%d\n",
1504 p->tuner,p->type,p->frequency);
1505 break;
1507 case VIDIOC_S_FREQUENCY:
1509 struct v4l2_frequency *p=arg;
1510 if (!vfd->vidioc_s_frequency)
1511 break;
1512 dbgarg (cmd, "tuner=%d, type=%d, frequency=%d\n",
1513 p->tuner,p->type,p->frequency);
1514 ret=vfd->vidioc_s_frequency(file, fh, p);
1515 break;
1517 case VIDIOC_G_SLICED_VBI_CAP:
1519 struct v4l2_sliced_vbi_cap *p=arg;
1520 if (!vfd->vidioc_g_sliced_vbi_cap)
1521 break;
1522 ret=vfd->vidioc_g_sliced_vbi_cap(file, fh, p);
1523 if (!ret)
1524 dbgarg (cmd, "service_set=%d\n", p->service_set);
1525 break;
1527 case VIDIOC_LOG_STATUS:
1529 if (!vfd->vidioc_log_status)
1530 break;
1531 ret=vfd->vidioc_log_status(file, fh);
1532 break;
1534 #ifdef CONFIG_VIDEO_ADV_DEBUG
1535 case VIDIOC_DBG_G_REGISTER:
1537 struct v4l2_register *p=arg;
1538 if (!capable(CAP_SYS_ADMIN))
1539 ret=-EPERM;
1540 else if (vfd->vidioc_g_register)
1541 ret=vfd->vidioc_g_register(file, fh, p);
1542 break;
1544 case VIDIOC_DBG_S_REGISTER:
1546 struct v4l2_register *p=arg;
1547 if (!capable(CAP_SYS_ADMIN))
1548 ret=-EPERM;
1549 else if (vfd->vidioc_s_register)
1550 ret=vfd->vidioc_s_register(file, fh, p);
1551 break;
1553 #endif
1554 case VIDIOC_G_CHIP_IDENT:
1556 struct v4l2_chip_ident *p=arg;
1557 if (!vfd->vidioc_g_chip_ident)
1558 break;
1559 ret=vfd->vidioc_g_chip_ident(file, fh, p);
1560 if (!ret)
1561 dbgarg (cmd, "chip_ident=%u, revision=0x%x\n", p->ident, p->revision);
1562 break;
1564 } /* switch */
1566 if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) {
1567 if (ret<0) {
1568 printk ("%s: err:\n", vfd->name);
1569 v4l_print_ioctl(vfd->name, cmd);
1573 return ret;
1576 int video_ioctl2 (struct inode *inode, struct file *file,
1577 unsigned int cmd, unsigned long arg)
1579 char sbuf[128];
1580 void *mbuf = NULL;
1581 void *parg = NULL;
1582 int err = -EINVAL;
1583 int is_ext_ctrl;
1584 size_t ctrls_size = 0;
1585 void __user *user_ptr = NULL;
1587 #ifdef __OLD_VIDIOC_
1588 cmd = video_fix_command(cmd);
1589 #endif
1590 is_ext_ctrl = (cmd == VIDIOC_S_EXT_CTRLS || cmd == VIDIOC_G_EXT_CTRLS ||
1591 cmd == VIDIOC_TRY_EXT_CTRLS);
1593 /* Copy arguments into temp kernel buffer */
1594 switch (_IOC_DIR(cmd)) {
1595 case _IOC_NONE:
1596 parg = NULL;
1597 break;
1598 case _IOC_READ:
1599 case _IOC_WRITE:
1600 case (_IOC_WRITE | _IOC_READ):
1601 if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
1602 parg = sbuf;
1603 } else {
1604 /* too big to allocate from stack */
1605 mbuf = kmalloc(_IOC_SIZE(cmd),GFP_KERNEL);
1606 if (NULL == mbuf)
1607 return -ENOMEM;
1608 parg = mbuf;
1611 err = -EFAULT;
1612 if (_IOC_DIR(cmd) & _IOC_WRITE)
1613 if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd)))
1614 goto out;
1615 break;
1618 if (is_ext_ctrl) {
1619 struct v4l2_ext_controls *p = parg;
1621 /* In case of an error, tell the caller that it wasn't
1622 a specific control that caused it. */
1623 p->error_idx = p->count;
1624 user_ptr = (void __user *)p->controls;
1625 if (p->count) {
1626 ctrls_size = sizeof(struct v4l2_ext_control) * p->count;
1627 /* Note: v4l2_ext_controls fits in sbuf[] so mbuf is still NULL. */
1628 mbuf = kmalloc(ctrls_size, GFP_KERNEL);
1629 err = -ENOMEM;
1630 if (NULL == mbuf)
1631 goto out_ext_ctrl;
1632 err = -EFAULT;
1633 if (copy_from_user(mbuf, user_ptr, ctrls_size))
1634 goto out_ext_ctrl;
1635 p->controls = mbuf;
1639 /* Handles IOCTL */
1640 err = __video_do_ioctl(inode, file, cmd, parg);
1641 if (err == -ENOIOCTLCMD)
1642 err = -EINVAL;
1643 if (is_ext_ctrl) {
1644 struct v4l2_ext_controls *p = parg;
1646 p->controls = (void *)user_ptr;
1647 if (p->count && err == 0 && copy_to_user(user_ptr, mbuf, ctrls_size))
1648 err = -EFAULT;
1649 goto out_ext_ctrl;
1651 if (err < 0)
1652 goto out;
1654 out_ext_ctrl:
1655 /* Copy results into user buffer */
1656 switch (_IOC_DIR(cmd))
1658 case _IOC_READ:
1659 case (_IOC_WRITE | _IOC_READ):
1660 if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd)))
1661 err = -EFAULT;
1662 break;
1665 out:
1666 kfree(mbuf);
1667 return err;
1671 static const struct file_operations video_fops;
1674 * video_register_device - register video4linux devices
1675 * @vfd: video device structure we want to register
1676 * @type: type of device to register
1677 * @nr: which device number (0 == /dev/video0, 1 == /dev/video1, ...
1678 * -1 == first free)
1680 * The registration code assigns minor numbers based on the type
1681 * requested. -ENFILE is returned in all the device slots for this
1682 * category are full. If not then the minor field is set and the
1683 * driver initialize function is called (if non %NULL).
1685 * Zero is returned on success.
1687 * Valid types are
1689 * %VFL_TYPE_GRABBER - A frame grabber
1691 * %VFL_TYPE_VTX - A teletext device
1693 * %VFL_TYPE_VBI - Vertical blank data (undecoded)
1695 * %VFL_TYPE_RADIO - A radio card
1698 int video_register_device(struct video_device *vfd, int type, int nr)
1700 int i=0;
1701 int base;
1702 int end;
1703 int ret;
1704 char *name_base;
1706 switch(type)
1708 case VFL_TYPE_GRABBER:
1709 base=MINOR_VFL_TYPE_GRABBER_MIN;
1710 end=MINOR_VFL_TYPE_GRABBER_MAX+1;
1711 name_base = "video";
1712 break;
1713 case VFL_TYPE_VTX:
1714 base=MINOR_VFL_TYPE_VTX_MIN;
1715 end=MINOR_VFL_TYPE_VTX_MAX+1;
1716 name_base = "vtx";
1717 break;
1718 case VFL_TYPE_VBI:
1719 base=MINOR_VFL_TYPE_VBI_MIN;
1720 end=MINOR_VFL_TYPE_VBI_MAX+1;
1721 name_base = "vbi";
1722 break;
1723 case VFL_TYPE_RADIO:
1724 base=MINOR_VFL_TYPE_RADIO_MIN;
1725 end=MINOR_VFL_TYPE_RADIO_MAX+1;
1726 name_base = "radio";
1727 break;
1728 default:
1729 printk(KERN_ERR "%s called with unknown type: %d\n",
1730 __FUNCTION__, type);
1731 return -1;
1734 /* pick a minor number */
1735 mutex_lock(&videodev_lock);
1736 if (nr >= 0 && nr < end-base) {
1737 /* use the one the driver asked for */
1738 i = base+nr;
1739 if (NULL != video_device[i]) {
1740 mutex_unlock(&videodev_lock);
1741 return -ENFILE;
1743 } else {
1744 /* use first free */
1745 for(i=base;i<end;i++)
1746 if (NULL == video_device[i])
1747 break;
1748 if (i == end) {
1749 mutex_unlock(&videodev_lock);
1750 return -ENFILE;
1753 video_device[i]=vfd;
1754 vfd->minor=i;
1755 mutex_unlock(&videodev_lock);
1756 mutex_init(&vfd->lock);
1758 /* sysfs class */
1759 memset(&vfd->class_dev, 0x00, sizeof(vfd->class_dev));
1760 if (vfd->dev)
1761 vfd->class_dev.parent = vfd->dev;
1762 vfd->class_dev.class = &video_class;
1763 vfd->class_dev.devt = MKDEV(VIDEO_MAJOR, vfd->minor);
1764 sprintf(vfd->class_dev.bus_id, "%s%d", name_base, i - base);
1765 ret = device_register(&vfd->class_dev);
1766 if (ret < 0) {
1767 printk(KERN_ERR "%s: device_register failed\n",
1768 __FUNCTION__);
1769 goto fail_minor;
1772 #if 1
1773 /* needed until all drivers are fixed */
1774 if (!vfd->release)
1775 printk(KERN_WARNING "videodev: \"%s\" has no release callback. "
1776 "Please fix your driver for proper sysfs support, see "
1777 "http://lwn.net/Articles/36850/\n", vfd->name);
1778 #endif
1779 return 0;
1781 fail_minor:
1782 mutex_lock(&videodev_lock);
1783 video_device[vfd->minor] = NULL;
1784 vfd->minor = -1;
1785 mutex_unlock(&videodev_lock);
1786 return ret;
1790 * video_unregister_device - unregister a video4linux device
1791 * @vfd: the device to unregister
1793 * This unregisters the passed device and deassigns the minor
1794 * number. Future open calls will be met with errors.
1797 void video_unregister_device(struct video_device *vfd)
1799 mutex_lock(&videodev_lock);
1800 if(video_device[vfd->minor]!=vfd)
1801 panic("videodev: bad unregister");
1803 video_device[vfd->minor]=NULL;
1804 device_unregister(&vfd->class_dev);
1805 mutex_unlock(&videodev_lock);
1809 * Video fs operations
1811 static const struct file_operations video_fops=
1813 .owner = THIS_MODULE,
1814 .llseek = no_llseek,
1815 .open = video_open,
1819 * Initialise video for linux
1822 static int __init videodev_init(void)
1824 int ret;
1826 printk(KERN_INFO "Linux video capture interface: v2.00\n");
1827 if (register_chrdev(VIDEO_MAJOR, VIDEO_NAME, &video_fops)) {
1828 printk(KERN_WARNING "video_dev: unable to get major %d\n", VIDEO_MAJOR);
1829 return -EIO;
1832 ret = class_register(&video_class);
1833 if (ret < 0) {
1834 unregister_chrdev(VIDEO_MAJOR, VIDEO_NAME);
1835 printk(KERN_WARNING "video_dev: class_register failed\n");
1836 return -EIO;
1839 return 0;
1842 static void __exit videodev_exit(void)
1844 class_unregister(&video_class);
1845 unregister_chrdev(VIDEO_MAJOR, VIDEO_NAME);
1848 module_init(videodev_init)
1849 module_exit(videodev_exit)
1851 EXPORT_SYMBOL(video_register_device);
1852 EXPORT_SYMBOL(video_unregister_device);
1853 EXPORT_SYMBOL(video_devdata);
1854 EXPORT_SYMBOL(video_usercopy);
1855 EXPORT_SYMBOL(video_exclusive_open);
1856 EXPORT_SYMBOL(video_exclusive_release);
1857 EXPORT_SYMBOL(video_ioctl2);
1858 EXPORT_SYMBOL(video_device_alloc);
1859 EXPORT_SYMBOL(video_device_release);
1861 MODULE_AUTHOR("Alan Cox, Mauro Carvalho Chehab <mchehab@infradead.org>");
1862 MODULE_DESCRIPTION("Device registrar for Video4Linux drivers v2");
1863 MODULE_LICENSE("GPL");
1867 * Local variables:
1868 * c-basic-offset: 8
1869 * End: