V4L/DVB (6805): video std is a bitmask. Better to print in hexa
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / media / video / videodev.c
blob28655f8983c6949386d6bdc6465613256e369423
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=%08Lx\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=%08Lx\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=%08Lx\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=%08Lx, 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_JPEGCOMP:
1318 struct v4l2_jpegcompression *p=arg;
1319 if (!vfd->vidioc_g_jpegcomp)
1320 break;
1321 ret=vfd->vidioc_g_jpegcomp(file, fh, p);
1322 if (!ret)
1323 dbgarg (cmd, "quality=%d, APPn=%d, "
1324 "APP_len=%d, COM_len=%d, "
1325 "jpeg_markers=%d\n",
1326 p->quality,p->APPn,p->APP_len,
1327 p->COM_len,p->jpeg_markers);
1328 break;
1330 case VIDIOC_S_JPEGCOMP:
1332 struct v4l2_jpegcompression *p=arg;
1333 if (!vfd->vidioc_g_jpegcomp)
1334 break;
1335 dbgarg (cmd, "quality=%d, APPn=%d, APP_len=%d, "
1336 "COM_len=%d, jpeg_markers=%d\n",
1337 p->quality,p->APPn,p->APP_len,
1338 p->COM_len,p->jpeg_markers);
1339 ret=vfd->vidioc_s_jpegcomp(file, fh, p);
1340 break;
1342 case VIDIOC_G_ENC_INDEX:
1344 struct v4l2_enc_idx *p=arg;
1346 if (!vfd->vidioc_g_enc_index)
1347 break;
1348 ret=vfd->vidioc_g_enc_index(file, fh, p);
1349 if (!ret)
1350 dbgarg (cmd, "entries=%d, entries_cap=%d\n",
1351 p->entries,p->entries_cap);
1352 break;
1354 case VIDIOC_ENCODER_CMD:
1356 struct v4l2_encoder_cmd *p=arg;
1358 if (!vfd->vidioc_encoder_cmd)
1359 break;
1360 ret=vfd->vidioc_encoder_cmd(file, fh, p);
1361 if (!ret)
1362 dbgarg (cmd, "cmd=%d, flags=%d\n",
1363 p->cmd,p->flags);
1364 break;
1366 case VIDIOC_TRY_ENCODER_CMD:
1368 struct v4l2_encoder_cmd *p=arg;
1370 if (!vfd->vidioc_try_encoder_cmd)
1371 break;
1372 ret=vfd->vidioc_try_encoder_cmd(file, fh, p);
1373 if (!ret)
1374 dbgarg (cmd, "cmd=%d, flags=%d\n",
1375 p->cmd,p->flags);
1376 break;
1378 case VIDIOC_G_PARM:
1380 struct v4l2_streamparm *p=arg;
1381 __u32 type=p->type;
1383 memset(p,0,sizeof(*p));
1384 p->type=type;
1386 if (vfd->vidioc_g_parm) {
1387 ret=vfd->vidioc_g_parm(file, fh, p);
1388 } else {
1389 struct v4l2_standard s;
1391 if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1392 return -EINVAL;
1394 v4l2_video_std_construct(&s, vfd->current_norm,
1395 v4l2_norm_to_name(vfd->current_norm));
1397 p->parm.capture.timeperframe = s.frameperiod;
1398 ret=0;
1401 dbgarg (cmd, "type=%d\n", p->type);
1402 break;
1404 case VIDIOC_S_PARM:
1406 struct v4l2_streamparm *p=arg;
1407 if (!vfd->vidioc_s_parm)
1408 break;
1409 dbgarg (cmd, "type=%d\n", p->type);
1410 ret=vfd->vidioc_s_parm(file, fh, p);
1411 break;
1413 case VIDIOC_G_TUNER:
1415 struct v4l2_tuner *p=arg;
1416 __u32 index=p->index;
1418 if (!vfd->vidioc_g_tuner)
1419 break;
1421 memset(p,0,sizeof(*p));
1422 p->index=index;
1424 ret=vfd->vidioc_g_tuner(file, fh, p);
1425 if (!ret)
1426 dbgarg (cmd, "index=%d, name=%s, type=%d, "
1427 "capability=%d, rangelow=%d, "
1428 "rangehigh=%d, signal=%d, afc=%d, "
1429 "rxsubchans=%d, audmode=%d\n",
1430 p->index, p->name, p->type,
1431 p->capability, p->rangelow,
1432 p->rangehigh, p->rxsubchans,
1433 p->audmode, p->signal, p->afc);
1434 break;
1436 case VIDIOC_S_TUNER:
1438 struct v4l2_tuner *p=arg;
1439 if (!vfd->vidioc_s_tuner)
1440 break;
1441 dbgarg (cmd, "index=%d, name=%s, type=%d, "
1442 "capability=%d, rangelow=%d, rangehigh=%d, "
1443 "signal=%d, afc=%d, rxsubchans=%d, "
1444 "audmode=%d\n",p->index, p->name, p->type,
1445 p->capability, p->rangelow,p->rangehigh,
1446 p->rxsubchans, p->audmode, p->signal,
1447 p->afc);
1448 ret=vfd->vidioc_s_tuner(file, fh, p);
1449 break;
1451 case VIDIOC_G_FREQUENCY:
1453 struct v4l2_frequency *p=arg;
1454 if (!vfd->vidioc_g_frequency)
1455 break;
1457 memset(p,0,sizeof(*p));
1459 ret=vfd->vidioc_g_frequency(file, fh, p);
1460 if (!ret)
1461 dbgarg (cmd, "tuner=%d, type=%d, frequency=%d\n",
1462 p->tuner,p->type,p->frequency);
1463 break;
1465 case VIDIOC_S_FREQUENCY:
1467 struct v4l2_frequency *p=arg;
1468 if (!vfd->vidioc_s_frequency)
1469 break;
1470 dbgarg (cmd, "tuner=%d, type=%d, frequency=%d\n",
1471 p->tuner,p->type,p->frequency);
1472 ret=vfd->vidioc_s_frequency(file, fh, p);
1473 break;
1475 case VIDIOC_G_SLICED_VBI_CAP:
1477 struct v4l2_sliced_vbi_cap *p=arg;
1478 if (!vfd->vidioc_g_sliced_vbi_cap)
1479 break;
1480 ret=vfd->vidioc_g_sliced_vbi_cap(file, fh, p);
1481 if (!ret)
1482 dbgarg (cmd, "service_set=%d\n", p->service_set);
1483 break;
1485 case VIDIOC_LOG_STATUS:
1487 if (!vfd->vidioc_log_status)
1488 break;
1489 ret=vfd->vidioc_log_status(file, fh);
1490 break;
1492 #ifdef CONFIG_VIDEO_ADV_DEBUG
1493 case VIDIOC_DBG_G_REGISTER:
1495 struct v4l2_register *p=arg;
1496 if (!capable(CAP_SYS_ADMIN))
1497 ret=-EPERM;
1498 else if (vfd->vidioc_g_register)
1499 ret=vfd->vidioc_g_register(file, fh, p);
1500 break;
1502 case VIDIOC_DBG_S_REGISTER:
1504 struct v4l2_register *p=arg;
1505 if (!capable(CAP_SYS_ADMIN))
1506 ret=-EPERM;
1507 else if (vfd->vidioc_s_register)
1508 ret=vfd->vidioc_s_register(file, fh, p);
1509 break;
1511 #endif
1512 case VIDIOC_G_CHIP_IDENT:
1514 struct v4l2_chip_ident *p=arg;
1515 if (!vfd->vidioc_g_chip_ident)
1516 break;
1517 ret=vfd->vidioc_g_chip_ident(file, fh, p);
1518 if (!ret)
1519 dbgarg (cmd, "chip_ident=%u, revision=0x%x\n", p->ident, p->revision);
1520 break;
1522 } /* switch */
1524 if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) {
1525 if (ret<0) {
1526 printk ("%s: err:\n", vfd->name);
1527 v4l_print_ioctl(vfd->name, cmd);
1531 return ret;
1534 int video_ioctl2 (struct inode *inode, struct file *file,
1535 unsigned int cmd, unsigned long arg)
1537 char sbuf[128];
1538 void *mbuf = NULL;
1539 void *parg = NULL;
1540 int err = -EINVAL;
1541 int is_ext_ctrl;
1542 size_t ctrls_size = 0;
1543 void __user *user_ptr = NULL;
1545 #ifdef __OLD_VIDIOC_
1546 cmd = video_fix_command(cmd);
1547 #endif
1548 is_ext_ctrl = (cmd == VIDIOC_S_EXT_CTRLS || cmd == VIDIOC_G_EXT_CTRLS ||
1549 cmd == VIDIOC_TRY_EXT_CTRLS);
1551 /* Copy arguments into temp kernel buffer */
1552 switch (_IOC_DIR(cmd)) {
1553 case _IOC_NONE:
1554 parg = NULL;
1555 break;
1556 case _IOC_READ:
1557 case _IOC_WRITE:
1558 case (_IOC_WRITE | _IOC_READ):
1559 if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
1560 parg = sbuf;
1561 } else {
1562 /* too big to allocate from stack */
1563 mbuf = kmalloc(_IOC_SIZE(cmd),GFP_KERNEL);
1564 if (NULL == mbuf)
1565 return -ENOMEM;
1566 parg = mbuf;
1569 err = -EFAULT;
1570 if (_IOC_DIR(cmd) & _IOC_WRITE)
1571 if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd)))
1572 goto out;
1573 break;
1576 if (is_ext_ctrl) {
1577 struct v4l2_ext_controls *p = parg;
1579 /* In case of an error, tell the caller that it wasn't
1580 a specific control that caused it. */
1581 p->error_idx = p->count;
1582 user_ptr = (void __user *)p->controls;
1583 if (p->count) {
1584 ctrls_size = sizeof(struct v4l2_ext_control) * p->count;
1585 /* Note: v4l2_ext_controls fits in sbuf[] so mbuf is still NULL. */
1586 mbuf = kmalloc(ctrls_size, GFP_KERNEL);
1587 err = -ENOMEM;
1588 if (NULL == mbuf)
1589 goto out_ext_ctrl;
1590 err = -EFAULT;
1591 if (copy_from_user(mbuf, user_ptr, ctrls_size))
1592 goto out_ext_ctrl;
1593 p->controls = mbuf;
1597 /* Handles IOCTL */
1598 err = __video_do_ioctl(inode, file, cmd, parg);
1599 if (err == -ENOIOCTLCMD)
1600 err = -EINVAL;
1601 if (is_ext_ctrl) {
1602 struct v4l2_ext_controls *p = parg;
1604 p->controls = (void *)user_ptr;
1605 if (p->count && err == 0 && copy_to_user(user_ptr, mbuf, ctrls_size))
1606 err = -EFAULT;
1607 goto out_ext_ctrl;
1609 if (err < 0)
1610 goto out;
1612 out_ext_ctrl:
1613 /* Copy results into user buffer */
1614 switch (_IOC_DIR(cmd))
1616 case _IOC_READ:
1617 case (_IOC_WRITE | _IOC_READ):
1618 if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd)))
1619 err = -EFAULT;
1620 break;
1623 out:
1624 kfree(mbuf);
1625 return err;
1629 static const struct file_operations video_fops;
1632 * video_register_device - register video4linux devices
1633 * @vfd: video device structure we want to register
1634 * @type: type of device to register
1635 * @nr: which device number (0 == /dev/video0, 1 == /dev/video1, ...
1636 * -1 == first free)
1638 * The registration code assigns minor numbers based on the type
1639 * requested. -ENFILE is returned in all the device slots for this
1640 * category are full. If not then the minor field is set and the
1641 * driver initialize function is called (if non %NULL).
1643 * Zero is returned on success.
1645 * Valid types are
1647 * %VFL_TYPE_GRABBER - A frame grabber
1649 * %VFL_TYPE_VTX - A teletext device
1651 * %VFL_TYPE_VBI - Vertical blank data (undecoded)
1653 * %VFL_TYPE_RADIO - A radio card
1656 int video_register_device(struct video_device *vfd, int type, int nr)
1658 int i=0;
1659 int base;
1660 int end;
1661 int ret;
1662 char *name_base;
1664 switch(type)
1666 case VFL_TYPE_GRABBER:
1667 base=MINOR_VFL_TYPE_GRABBER_MIN;
1668 end=MINOR_VFL_TYPE_GRABBER_MAX+1;
1669 name_base = "video";
1670 break;
1671 case VFL_TYPE_VTX:
1672 base=MINOR_VFL_TYPE_VTX_MIN;
1673 end=MINOR_VFL_TYPE_VTX_MAX+1;
1674 name_base = "vtx";
1675 break;
1676 case VFL_TYPE_VBI:
1677 base=MINOR_VFL_TYPE_VBI_MIN;
1678 end=MINOR_VFL_TYPE_VBI_MAX+1;
1679 name_base = "vbi";
1680 break;
1681 case VFL_TYPE_RADIO:
1682 base=MINOR_VFL_TYPE_RADIO_MIN;
1683 end=MINOR_VFL_TYPE_RADIO_MAX+1;
1684 name_base = "radio";
1685 break;
1686 default:
1687 printk(KERN_ERR "%s called with unknown type: %d\n",
1688 __FUNCTION__, type);
1689 return -1;
1692 /* pick a minor number */
1693 mutex_lock(&videodev_lock);
1694 if (nr >= 0 && nr < end-base) {
1695 /* use the one the driver asked for */
1696 i = base+nr;
1697 if (NULL != video_device[i]) {
1698 mutex_unlock(&videodev_lock);
1699 return -ENFILE;
1701 } else {
1702 /* use first free */
1703 for(i=base;i<end;i++)
1704 if (NULL == video_device[i])
1705 break;
1706 if (i == end) {
1707 mutex_unlock(&videodev_lock);
1708 return -ENFILE;
1711 video_device[i]=vfd;
1712 vfd->minor=i;
1713 mutex_unlock(&videodev_lock);
1714 mutex_init(&vfd->lock);
1716 /* sysfs class */
1717 memset(&vfd->class_dev, 0x00, sizeof(vfd->class_dev));
1718 if (vfd->dev)
1719 vfd->class_dev.parent = vfd->dev;
1720 vfd->class_dev.class = &video_class;
1721 vfd->class_dev.devt = MKDEV(VIDEO_MAJOR, vfd->minor);
1722 sprintf(vfd->class_dev.bus_id, "%s%d", name_base, i - base);
1723 ret = device_register(&vfd->class_dev);
1724 if (ret < 0) {
1725 printk(KERN_ERR "%s: device_register failed\n",
1726 __FUNCTION__);
1727 goto fail_minor;
1730 #if 1
1731 /* needed until all drivers are fixed */
1732 if (!vfd->release)
1733 printk(KERN_WARNING "videodev: \"%s\" has no release callback. "
1734 "Please fix your driver for proper sysfs support, see "
1735 "http://lwn.net/Articles/36850/\n", vfd->name);
1736 #endif
1737 return 0;
1739 fail_minor:
1740 mutex_lock(&videodev_lock);
1741 video_device[vfd->minor] = NULL;
1742 vfd->minor = -1;
1743 mutex_unlock(&videodev_lock);
1744 return ret;
1748 * video_unregister_device - unregister a video4linux device
1749 * @vfd: the device to unregister
1751 * This unregisters the passed device and deassigns the minor
1752 * number. Future open calls will be met with errors.
1755 void video_unregister_device(struct video_device *vfd)
1757 mutex_lock(&videodev_lock);
1758 if(video_device[vfd->minor]!=vfd)
1759 panic("videodev: bad unregister");
1761 video_device[vfd->minor]=NULL;
1762 device_unregister(&vfd->class_dev);
1763 mutex_unlock(&videodev_lock);
1767 * Video fs operations
1769 static const struct file_operations video_fops=
1771 .owner = THIS_MODULE,
1772 .llseek = no_llseek,
1773 .open = video_open,
1777 * Initialise video for linux
1780 static int __init videodev_init(void)
1782 int ret;
1784 printk(KERN_INFO "Linux video capture interface: v2.00\n");
1785 if (register_chrdev(VIDEO_MAJOR, VIDEO_NAME, &video_fops)) {
1786 printk(KERN_WARNING "video_dev: unable to get major %d\n", VIDEO_MAJOR);
1787 return -EIO;
1790 ret = class_register(&video_class);
1791 if (ret < 0) {
1792 unregister_chrdev(VIDEO_MAJOR, VIDEO_NAME);
1793 printk(KERN_WARNING "video_dev: class_register failed\n");
1794 return -EIO;
1797 return 0;
1800 static void __exit videodev_exit(void)
1802 class_unregister(&video_class);
1803 unregister_chrdev(VIDEO_MAJOR, VIDEO_NAME);
1806 module_init(videodev_init)
1807 module_exit(videodev_exit)
1809 EXPORT_SYMBOL(video_register_device);
1810 EXPORT_SYMBOL(video_unregister_device);
1811 EXPORT_SYMBOL(video_devdata);
1812 EXPORT_SYMBOL(video_usercopy);
1813 EXPORT_SYMBOL(video_exclusive_open);
1814 EXPORT_SYMBOL(video_exclusive_release);
1815 EXPORT_SYMBOL(video_ioctl2);
1816 EXPORT_SYMBOL(video_device_alloc);
1817 EXPORT_SYMBOL(video_device_release);
1819 MODULE_AUTHOR("Alan Cox, Mauro Carvalho Chehab <mchehab@infradead.org>");
1820 MODULE_DESCRIPTION("Device registrar for Video4Linux drivers v2");
1821 MODULE_LICENSE("GPL");
1825 * Local variables:
1826 * c-basic-offset: 8
1827 * End: