Pull platform-drivers into test branch
[linux-2.6/x86.git] / drivers / media / video / videodev.c
blob6a0e8ca7294803056cf29d11716d7ed175b35e5f
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/sched.h>
34 #include <linux/smp_lock.h>
35 #include <linux/mm.h>
36 #include <linux/string.h>
37 #include <linux/errno.h>
38 #include <linux/init.h>
39 #include <linux/kmod.h>
40 #include <linux/slab.h>
41 #include <asm/uaccess.h>
42 #include <asm/system.h>
44 #define __OLD_VIDIOC_ /* To allow fixing old calls*/
45 #include <linux/videodev2.h>
47 #ifdef CONFIG_VIDEO_V4L1
48 #include <linux/videodev.h>
49 #endif
50 #include <media/v4l2-common.h>
52 #define VIDEO_NUM_DEVICES 256
53 #define VIDEO_NAME "video4linux"
56 * sysfs stuff
59 static ssize_t show_name(struct class_device *cd, char *buf)
61 struct video_device *vfd = container_of(cd, struct video_device,
62 class_dev);
63 return sprintf(buf,"%.*s\n",(int)sizeof(vfd->name),vfd->name);
66 static CLASS_DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
68 struct video_device *video_device_alloc(void)
70 struct video_device *vfd;
72 vfd = kzalloc(sizeof(*vfd),GFP_KERNEL);
73 return vfd;
76 void video_device_release(struct video_device *vfd)
78 kfree(vfd);
81 static void video_release(struct class_device *cd)
83 struct video_device *vfd = container_of(cd, struct video_device,
84 class_dev);
86 #if 1
87 /* needed until all drivers are fixed */
88 if (!vfd->release)
89 return;
90 #endif
91 vfd->release(vfd);
94 static struct class video_class = {
95 .name = VIDEO_NAME,
96 .release = video_release,
100 * Active devices
103 static struct video_device *video_device[VIDEO_NUM_DEVICES];
104 static DEFINE_MUTEX(videodev_lock);
106 struct video_device* video_devdata(struct file *file)
108 return video_device[iminor(file->f_path.dentry->d_inode)];
112 * Open a video device - FIXME: Obsoleted
114 static int video_open(struct inode *inode, struct file *file)
116 unsigned int minor = iminor(inode);
117 int err = 0;
118 struct video_device *vfl;
119 const struct file_operations *old_fops;
121 if(minor>=VIDEO_NUM_DEVICES)
122 return -ENODEV;
123 mutex_lock(&videodev_lock);
124 vfl=video_device[minor];
125 if(vfl==NULL) {
126 mutex_unlock(&videodev_lock);
127 request_module("char-major-%d-%d", VIDEO_MAJOR, minor);
128 mutex_lock(&videodev_lock);
129 vfl=video_device[minor];
130 if (vfl==NULL) {
131 mutex_unlock(&videodev_lock);
132 return -ENODEV;
135 old_fops = file->f_op;
136 file->f_op = fops_get(vfl->fops);
137 if(file->f_op->open)
138 err = file->f_op->open(inode,file);
139 if (err) {
140 fops_put(file->f_op);
141 file->f_op = fops_get(old_fops);
143 fops_put(old_fops);
144 mutex_unlock(&videodev_lock);
145 return err;
149 * helper function -- handles userspace copying for ioctl arguments
152 #ifdef __OLD_VIDIOC_
153 static unsigned int
154 video_fix_command(unsigned int cmd)
156 switch (cmd) {
157 case VIDIOC_OVERLAY_OLD:
158 cmd = VIDIOC_OVERLAY;
159 break;
160 case VIDIOC_S_PARM_OLD:
161 cmd = VIDIOC_S_PARM;
162 break;
163 case VIDIOC_S_CTRL_OLD:
164 cmd = VIDIOC_S_CTRL;
165 break;
166 case VIDIOC_G_AUDIO_OLD:
167 cmd = VIDIOC_G_AUDIO;
168 break;
169 case VIDIOC_G_AUDOUT_OLD:
170 cmd = VIDIOC_G_AUDOUT;
171 break;
172 case VIDIOC_CROPCAP_OLD:
173 cmd = VIDIOC_CROPCAP;
174 break;
176 return cmd;
178 #endif
181 * Obsolete usercopy function - Should be removed soon
184 video_usercopy(struct inode *inode, struct file *file,
185 unsigned int cmd, unsigned long arg,
186 int (*func)(struct inode *inode, struct file *file,
187 unsigned int cmd, void *arg))
189 char sbuf[128];
190 void *mbuf = NULL;
191 void *parg = NULL;
192 int err = -EINVAL;
193 int is_ext_ctrl;
194 size_t ctrls_size = 0;
195 void __user *user_ptr = NULL;
197 #ifdef __OLD_VIDIOC_
198 cmd = video_fix_command(cmd);
199 #endif
200 is_ext_ctrl = (cmd == VIDIOC_S_EXT_CTRLS || cmd == VIDIOC_G_EXT_CTRLS ||
201 cmd == VIDIOC_TRY_EXT_CTRLS);
203 /* Copy arguments into temp kernel buffer */
204 switch (_IOC_DIR(cmd)) {
205 case _IOC_NONE:
206 parg = NULL;
207 break;
208 case _IOC_READ:
209 case _IOC_WRITE:
210 case (_IOC_WRITE | _IOC_READ):
211 if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
212 parg = sbuf;
213 } else {
214 /* too big to allocate from stack */
215 mbuf = kmalloc(_IOC_SIZE(cmd),GFP_KERNEL);
216 if (NULL == mbuf)
217 return -ENOMEM;
218 parg = mbuf;
221 err = -EFAULT;
222 if (_IOC_DIR(cmd) & _IOC_WRITE)
223 if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd)))
224 goto out;
225 break;
227 if (is_ext_ctrl) {
228 struct v4l2_ext_controls *p = parg;
230 /* In case of an error, tell the caller that it wasn't
231 a specific control that caused it. */
232 p->error_idx = p->count;
233 user_ptr = (void __user *)p->controls;
234 if (p->count) {
235 ctrls_size = sizeof(struct v4l2_ext_control) * p->count;
236 /* Note: v4l2_ext_controls fits in sbuf[] so mbuf is still NULL. */
237 mbuf = kmalloc(ctrls_size, GFP_KERNEL);
238 err = -ENOMEM;
239 if (NULL == mbuf)
240 goto out_ext_ctrl;
241 err = -EFAULT;
242 if (copy_from_user(mbuf, user_ptr, ctrls_size))
243 goto out_ext_ctrl;
244 p->controls = mbuf;
248 /* call driver */
249 err = func(inode, file, cmd, parg);
250 if (err == -ENOIOCTLCMD)
251 err = -EINVAL;
252 if (is_ext_ctrl) {
253 struct v4l2_ext_controls *p = parg;
255 p->controls = (void *)user_ptr;
256 if (p->count && err == 0 && copy_to_user(user_ptr, mbuf, ctrls_size))
257 err = -EFAULT;
258 goto out_ext_ctrl;
260 if (err < 0)
261 goto out;
263 out_ext_ctrl:
264 /* Copy results into user buffer */
265 switch (_IOC_DIR(cmd))
267 case _IOC_READ:
268 case (_IOC_WRITE | _IOC_READ):
269 if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd)))
270 err = -EFAULT;
271 break;
274 out:
275 kfree(mbuf);
276 return err;
280 * open/release helper functions -- handle exclusive opens
281 * Should be removed soon
283 int video_exclusive_open(struct inode *inode, struct file *file)
285 struct video_device *vfl = video_devdata(file);
286 int retval = 0;
288 mutex_lock(&vfl->lock);
289 if (vfl->users) {
290 retval = -EBUSY;
291 } else {
292 vfl->users++;
294 mutex_unlock(&vfl->lock);
295 return retval;
298 int video_exclusive_release(struct inode *inode, struct file *file)
300 struct video_device *vfl = video_devdata(file);
302 vfl->users--;
303 return 0;
306 static char *v4l2_memory_names[] = {
307 [V4L2_MEMORY_MMAP] = "mmap",
308 [V4L2_MEMORY_USERPTR] = "userptr",
309 [V4L2_MEMORY_OVERLAY] = "overlay",
313 /* FIXME: Those stuff are replicated also on v4l2-common.c */
314 static char *v4l2_type_names_FIXME[] = {
315 [V4L2_BUF_TYPE_VIDEO_CAPTURE] = "video-cap",
316 [V4L2_BUF_TYPE_VIDEO_OVERLAY] = "video-over",
317 [V4L2_BUF_TYPE_VIDEO_OUTPUT] = "video-out",
318 [V4L2_BUF_TYPE_VBI_CAPTURE] = "vbi-cap",
319 [V4L2_BUF_TYPE_VBI_OUTPUT] = "vbi-out",
320 [V4L2_BUF_TYPE_SLICED_VBI_OUTPUT] = "sliced-vbi-out",
321 [V4L2_BUF_TYPE_SLICED_VBI_CAPTURE] = "sliced-vbi-capture",
322 [V4L2_BUF_TYPE_PRIVATE] = "private",
325 static char *v4l2_field_names_FIXME[] = {
326 [V4L2_FIELD_ANY] = "any",
327 [V4L2_FIELD_NONE] = "none",
328 [V4L2_FIELD_TOP] = "top",
329 [V4L2_FIELD_BOTTOM] = "bottom",
330 [V4L2_FIELD_INTERLACED] = "interlaced",
331 [V4L2_FIELD_SEQ_TB] = "seq-tb",
332 [V4L2_FIELD_SEQ_BT] = "seq-bt",
333 [V4L2_FIELD_ALTERNATE] = "alternate",
336 #define prt_names(a,arr) (((a)>=0)&&((a)<ARRAY_SIZE(arr)))?arr[a]:"unknown"
338 static void dbgbuf(unsigned int cmd, struct video_device *vfd,
339 struct v4l2_buffer *p)
341 struct v4l2_timecode *tc=&p->timecode;
343 dbgarg (cmd, "%02ld:%02d:%02d.%08ld index=%d, type=%s, "
344 "bytesused=%d, flags=0x%08d, "
345 "field=%0d, sequence=%d, memory=%s, offset/userptr=0x%08lx, length=%d\n",
346 (p->timestamp.tv_sec/3600),
347 (int)(p->timestamp.tv_sec/60)%60,
348 (int)(p->timestamp.tv_sec%60),
349 p->timestamp.tv_usec,
350 p->index,
351 prt_names(p->type,v4l2_type_names_FIXME),
352 p->bytesused,p->flags,
353 p->field,p->sequence,
354 prt_names(p->memory,v4l2_memory_names),
355 p->m.userptr, p->length);
356 dbgarg2 ("timecode= %02d:%02d:%02d type=%d, "
357 "flags=0x%08d, frames=%d, userbits=0x%08x\n",
358 tc->hours,tc->minutes,tc->seconds,
359 tc->type, tc->flags, tc->frames, *(__u32 *) tc->userbits);
362 static inline void dbgrect(struct video_device *vfd, char *s,
363 struct v4l2_rect *r)
365 dbgarg2 ("%sRect start at %dx%d, size= %dx%d\n", s, r->left, r->top,
366 r->width, r->height);
369 static inline void v4l_print_pix_fmt (struct video_device *vfd,
370 struct v4l2_pix_format *fmt)
372 dbgarg2 ("width=%d, height=%d, format=%c%c%c%c, field=%s, "
373 "bytesperline=%d sizeimage=%d, colorspace=%d\n",
374 fmt->width,fmt->height,
375 (fmt->pixelformat & 0xff),
376 (fmt->pixelformat >> 8) & 0xff,
377 (fmt->pixelformat >> 16) & 0xff,
378 (fmt->pixelformat >> 24) & 0xff,
379 prt_names(fmt->field,v4l2_field_names_FIXME),
380 fmt->bytesperline,fmt->sizeimage,fmt->colorspace);
384 static int check_fmt (struct video_device *vfd, enum v4l2_buf_type type)
386 switch (type) {
387 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
388 if (vfd->vidioc_try_fmt_cap)
389 return (0);
390 break;
391 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
392 if (vfd->vidioc_try_fmt_overlay)
393 return (0);
394 break;
395 case V4L2_BUF_TYPE_VBI_CAPTURE:
396 if (vfd->vidioc_try_fmt_vbi)
397 return (0);
398 break;
399 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
400 if (vfd->vidioc_try_fmt_vbi_output)
401 return (0);
402 break;
403 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
404 if (vfd->vidioc_try_fmt_vbi_capture)
405 return (0);
406 break;
407 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
408 if (vfd->vidioc_try_fmt_video_output)
409 return (0);
410 break;
411 case V4L2_BUF_TYPE_VBI_OUTPUT:
412 if (vfd->vidioc_try_fmt_vbi_output)
413 return (0);
414 break;
415 case V4L2_BUF_TYPE_PRIVATE:
416 if (vfd->vidioc_try_fmt_type_private)
417 return (0);
418 break;
420 return (-EINVAL);
423 static int __video_do_ioctl(struct inode *inode, struct file *file,
424 unsigned int cmd, void *arg)
426 struct video_device *vfd = video_devdata(file);
427 void *fh = file->private_data;
428 int ret = -EINVAL;
430 if ( (vfd->debug & V4L2_DEBUG_IOCTL) &&
431 !(vfd->debug | V4L2_DEBUG_IOCTL_ARG)) {
432 v4l_print_ioctl(vfd->name, cmd);
435 if (_IOC_TYPE(cmd)=='v')
436 return v4l_compat_translate_ioctl(inode,file,cmd,arg,
437 __video_do_ioctl);
439 switch(cmd) {
440 /* --- capabilities ------------------------------------------ */
441 case VIDIOC_QUERYCAP:
443 struct v4l2_capability *cap = (struct v4l2_capability*)arg;
444 memset(cap, 0, sizeof(*cap));
446 if (!vfd->vidioc_querycap)
447 break;
449 ret=vfd->vidioc_querycap(file, fh, cap);
450 if (!ret)
451 dbgarg (cmd, "driver=%s, card=%s, bus=%s, "
452 "version=0x%08x, "
453 "capabilities=0x%08x\n",
454 cap->driver,cap->card,cap->bus_info,
455 cap->version,
456 cap->capabilities);
457 break;
460 /* --- priority ------------------------------------------ */
461 case VIDIOC_G_PRIORITY:
463 enum v4l2_priority *p=arg;
465 if (!vfd->vidioc_g_priority)
466 break;
467 ret=vfd->vidioc_g_priority(file, fh, p);
468 if (!ret)
469 dbgarg(cmd, "priority is %d\n", *p);
470 break;
472 case VIDIOC_S_PRIORITY:
474 enum v4l2_priority *p=arg;
476 if (!vfd->vidioc_s_priority)
477 break;
478 dbgarg(cmd, "setting priority to %d\n", *p);
479 ret=vfd->vidioc_s_priority(file, fh, *p);
480 break;
483 /* --- capture ioctls ---------------------------------------- */
484 case VIDIOC_ENUM_FMT:
486 struct v4l2_fmtdesc *f = arg;
487 enum v4l2_buf_type type;
488 unsigned int index;
490 index = f->index;
491 type = f->type;
492 memset(f,0,sizeof(*f));
493 f->index = index;
494 f->type = type;
496 switch (type) {
497 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
498 if (vfd->vidioc_enum_fmt_cap)
499 ret=vfd->vidioc_enum_fmt_cap(file, fh, f);
500 break;
501 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
502 if (vfd->vidioc_enum_fmt_overlay)
503 ret=vfd->vidioc_enum_fmt_overlay(file, fh, f);
504 break;
505 case V4L2_BUF_TYPE_VBI_CAPTURE:
506 if (vfd->vidioc_enum_fmt_vbi)
507 ret=vfd->vidioc_enum_fmt_vbi(file, fh, f);
508 break;
509 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
510 if (vfd->vidioc_enum_fmt_vbi_output)
511 ret=vfd->vidioc_enum_fmt_vbi_output(file,
512 fh, f);
513 break;
514 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
515 if (vfd->vidioc_enum_fmt_vbi_capture)
516 ret=vfd->vidioc_enum_fmt_vbi_capture(file,
517 fh, f);
518 break;
519 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
520 if (vfd->vidioc_enum_fmt_video_output)
521 ret=vfd->vidioc_enum_fmt_video_output(file,
522 fh, f);
523 break;
524 case V4L2_BUF_TYPE_VBI_OUTPUT:
525 if (vfd->vidioc_enum_fmt_vbi_output)
526 ret=vfd->vidioc_enum_fmt_vbi_output(file,
527 fh, f);
528 break;
529 case V4L2_BUF_TYPE_PRIVATE:
530 if (vfd->vidioc_enum_fmt_type_private)
531 ret=vfd->vidioc_enum_fmt_type_private(file,
532 fh, f);
533 break;
535 if (!ret)
536 dbgarg (cmd, "index=%d, type=%d, flags=%d, "
537 "pixelformat=%c%c%c%c, description='%s'\n",
538 f->index, f->type, f->flags,
539 (f->pixelformat & 0xff),
540 (f->pixelformat >> 8) & 0xff,
541 (f->pixelformat >> 16) & 0xff,
542 (f->pixelformat >> 24) & 0xff,
543 f->description);
544 break;
546 case VIDIOC_G_FMT:
548 struct v4l2_format *f = (struct v4l2_format *)arg;
549 enum v4l2_buf_type type=f->type;
551 memset(&f->fmt.pix,0,sizeof(f->fmt.pix));
552 f->type=type;
554 /* FIXME: Should be one dump per type */
555 dbgarg (cmd, "type=%s\n", prt_names(type,
556 v4l2_type_names_FIXME));
558 switch (type) {
559 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
560 if (vfd->vidioc_g_fmt_cap)
561 ret=vfd->vidioc_g_fmt_cap(file, fh, f);
562 if (!ret)
563 v4l_print_pix_fmt(vfd,&f->fmt.pix);
564 break;
565 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
566 if (vfd->vidioc_g_fmt_overlay)
567 ret=vfd->vidioc_g_fmt_overlay(file, fh, f);
568 break;
569 case V4L2_BUF_TYPE_VBI_CAPTURE:
570 if (vfd->vidioc_g_fmt_vbi)
571 ret=vfd->vidioc_g_fmt_vbi(file, fh, f);
572 break;
573 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
574 if (vfd->vidioc_g_fmt_vbi_output)
575 ret=vfd->vidioc_g_fmt_vbi_output(file, fh, f);
576 break;
577 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
578 if (vfd->vidioc_g_fmt_vbi_capture)
579 ret=vfd->vidioc_g_fmt_vbi_capture(file, fh, f);
580 break;
581 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
582 if (vfd->vidioc_g_fmt_video_output)
583 ret=vfd->vidioc_g_fmt_video_output(file,
584 fh, f);
585 break;
586 case V4L2_BUF_TYPE_VBI_OUTPUT:
587 if (vfd->vidioc_g_fmt_vbi_output)
588 ret=vfd->vidioc_g_fmt_vbi_output(file, fh, f);
589 break;
590 case V4L2_BUF_TYPE_PRIVATE:
591 if (vfd->vidioc_g_fmt_type_private)
592 ret=vfd->vidioc_g_fmt_type_private(file,
593 fh, f);
594 break;
597 break;
599 case VIDIOC_S_FMT:
601 struct v4l2_format *f = (struct v4l2_format *)arg;
603 /* FIXME: Should be one dump per type */
604 dbgarg (cmd, "type=%s\n", prt_names(f->type,
605 v4l2_type_names_FIXME));
607 switch (f->type) {
608 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
609 v4l_print_pix_fmt(vfd,&f->fmt.pix);
610 if (vfd->vidioc_s_fmt_cap)
611 ret=vfd->vidioc_s_fmt_cap(file, fh, f);
612 break;
613 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
614 if (vfd->vidioc_s_fmt_overlay)
615 ret=vfd->vidioc_s_fmt_overlay(file, fh, f);
616 break;
617 case V4L2_BUF_TYPE_VBI_CAPTURE:
618 if (vfd->vidioc_s_fmt_vbi)
619 ret=vfd->vidioc_s_fmt_vbi(file, fh, f);
620 break;
621 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
622 if (vfd->vidioc_s_fmt_vbi_output)
623 ret=vfd->vidioc_s_fmt_vbi_output(file, fh, f);
624 break;
625 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
626 if (vfd->vidioc_s_fmt_vbi_capture)
627 ret=vfd->vidioc_s_fmt_vbi_capture(file, fh, f);
628 break;
629 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
630 if (vfd->vidioc_s_fmt_video_output)
631 ret=vfd->vidioc_s_fmt_video_output(file,
632 fh, f);
633 break;
634 case V4L2_BUF_TYPE_VBI_OUTPUT:
635 if (vfd->vidioc_s_fmt_vbi_output)
636 ret=vfd->vidioc_s_fmt_vbi_output(file,
637 fh, f);
638 break;
639 case V4L2_BUF_TYPE_PRIVATE:
640 if (vfd->vidioc_s_fmt_type_private)
641 ret=vfd->vidioc_s_fmt_type_private(file,
642 fh, f);
643 break;
645 break;
647 case VIDIOC_TRY_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));
654 switch (f->type) {
655 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
656 if (vfd->vidioc_try_fmt_cap)
657 ret=vfd->vidioc_try_fmt_cap(file, fh, f);
658 if (!ret)
659 v4l_print_pix_fmt(vfd,&f->fmt.pix);
660 break;
661 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
662 if (vfd->vidioc_try_fmt_overlay)
663 ret=vfd->vidioc_try_fmt_overlay(file, fh, f);
664 break;
665 case V4L2_BUF_TYPE_VBI_CAPTURE:
666 if (vfd->vidioc_try_fmt_vbi)
667 ret=vfd->vidioc_try_fmt_vbi(file, fh, f);
668 break;
669 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
670 if (vfd->vidioc_try_fmt_vbi_output)
671 ret=vfd->vidioc_try_fmt_vbi_output(file,
672 fh, f);
673 break;
674 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
675 if (vfd->vidioc_try_fmt_vbi_capture)
676 ret=vfd->vidioc_try_fmt_vbi_capture(file,
677 fh, f);
678 break;
679 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
680 if (vfd->vidioc_try_fmt_video_output)
681 ret=vfd->vidioc_try_fmt_video_output(file,
682 fh, f);
683 break;
684 case V4L2_BUF_TYPE_VBI_OUTPUT:
685 if (vfd->vidioc_try_fmt_vbi_output)
686 ret=vfd->vidioc_try_fmt_vbi_output(file,
687 fh, f);
688 break;
689 case V4L2_BUF_TYPE_PRIVATE:
690 if (vfd->vidioc_try_fmt_type_private)
691 ret=vfd->vidioc_try_fmt_type_private(file,
692 fh, f);
693 break;
696 break;
698 /* FIXME: Those buf reqs could be handled here,
699 with some changes on videobuf to allow its header to be included at
700 videodev2.h or being merged at videodev2.
702 case VIDIOC_REQBUFS:
704 struct v4l2_requestbuffers *p=arg;
706 if (!vfd->vidioc_reqbufs)
707 break;
708 ret = check_fmt (vfd, p->type);
709 if (ret)
710 break;
712 ret=vfd->vidioc_reqbufs(file, fh, p);
713 dbgarg (cmd, "count=%d, type=%s, memory=%s\n",
714 p->count,
715 prt_names(p->type,v4l2_type_names_FIXME),
716 prt_names(p->memory,v4l2_memory_names));
717 break;
719 case VIDIOC_QUERYBUF:
721 struct v4l2_buffer *p=arg;
723 if (!vfd->vidioc_querybuf)
724 break;
725 ret = check_fmt (vfd, p->type);
726 if (ret)
727 break;
729 ret=vfd->vidioc_querybuf(file, fh, p);
730 if (!ret)
731 dbgbuf(cmd,vfd,p);
732 break;
734 case VIDIOC_QBUF:
736 struct v4l2_buffer *p=arg;
738 if (!vfd->vidioc_qbuf)
739 break;
740 ret = check_fmt (vfd, p->type);
741 if (ret)
742 break;
744 ret=vfd->vidioc_qbuf(file, fh, p);
745 if (!ret)
746 dbgbuf(cmd,vfd,p);
747 break;
749 case VIDIOC_DQBUF:
751 struct v4l2_buffer *p=arg;
752 if (!vfd->vidioc_dqbuf)
753 break;
754 ret = check_fmt (vfd, p->type);
755 if (ret)
756 break;
758 ret=vfd->vidioc_dqbuf(file, fh, p);
759 if (!ret)
760 dbgbuf(cmd,vfd,p);
761 break;
763 case VIDIOC_OVERLAY:
765 int *i = arg;
767 if (!vfd->vidioc_overlay)
768 break;
769 dbgarg (cmd, "value=%d\n",*i);
770 ret=vfd->vidioc_overlay(file, fh, *i);
771 break;
773 #ifdef CONFIG_VIDEO_V4L1_COMPAT
774 /* --- streaming capture ------------------------------------- */
775 case VIDIOCGMBUF:
777 struct video_mbuf *p=arg;
779 memset(p,0,sizeof(p));
781 if (!vfd->vidiocgmbuf)
782 break;
783 ret=vfd->vidiocgmbuf(file, fh, p);
784 if (!ret)
785 dbgarg (cmd, "size=%d, frames=%d, offsets=0x%08lx\n",
786 p->size, p->frames,
787 (unsigned long)p->offsets);
788 break;
790 #endif
791 case VIDIOC_G_FBUF:
793 struct v4l2_framebuffer *p=arg;
794 if (!vfd->vidioc_g_fbuf)
795 break;
796 ret=vfd->vidioc_g_fbuf(file, fh, arg);
797 if (!ret) {
798 dbgarg (cmd, "capability=%d, flags=%d, base=0x%08lx\n",
799 p->capability,p->flags,
800 (unsigned long)p->base);
801 v4l_print_pix_fmt (vfd, &p->fmt);
803 break;
805 case VIDIOC_S_FBUF:
807 struct v4l2_framebuffer *p=arg;
808 if (!vfd->vidioc_s_fbuf)
809 break;
811 dbgarg (cmd, "capability=%d, flags=%d, base=0x%08lx\n",
812 p->capability,p->flags,(unsigned long)p->base);
813 v4l_print_pix_fmt (vfd, &p->fmt);
814 ret=vfd->vidioc_s_fbuf(file, fh, arg);
816 break;
818 case VIDIOC_STREAMON:
820 enum v4l2_buf_type i = *(int *)arg;
821 if (!vfd->vidioc_streamon)
822 break;
823 dbgarg (cmd, "type=%s\n", prt_names(i,v4l2_type_names_FIXME));
824 ret=vfd->vidioc_streamon(file, fh,i);
825 break;
827 case VIDIOC_STREAMOFF:
829 enum v4l2_buf_type i = *(int *)arg;
831 if (!vfd->vidioc_streamoff)
832 break;
833 dbgarg (cmd, "type=%s\n", prt_names(i,v4l2_type_names_FIXME));
834 ret=vfd->vidioc_streamoff(file, fh, i);
835 break;
837 /* ---------- tv norms ---------- */
838 case VIDIOC_ENUMSTD:
840 struct v4l2_standard *p = arg;
841 v4l2_std_id id = vfd->tvnorms,curr_id=0;
842 unsigned int index = p->index,i;
844 if (index<0) {
845 ret=-EINVAL;
846 break;
849 /* Return norm array on a canonical way */
850 for (i=0;i<= index && id; i++) {
851 if ( (id & V4L2_STD_PAL) == V4L2_STD_PAL) {
852 curr_id = V4L2_STD_PAL;
853 } else if ( (id & V4L2_STD_PAL_BG) == V4L2_STD_PAL_BG) {
854 curr_id = V4L2_STD_PAL_BG;
855 } else if ( (id & V4L2_STD_PAL_DK) == V4L2_STD_PAL_DK) {
856 curr_id = V4L2_STD_PAL_DK;
857 } else if ( (id & V4L2_STD_PAL_B) == V4L2_STD_PAL_B) {
858 curr_id = V4L2_STD_PAL_B;
859 } else if ( (id & V4L2_STD_PAL_B1) == V4L2_STD_PAL_B1) {
860 curr_id = V4L2_STD_PAL_B1;
861 } else if ( (id & V4L2_STD_PAL_G) == V4L2_STD_PAL_G) {
862 curr_id = V4L2_STD_PAL_G;
863 } else if ( (id & V4L2_STD_PAL_H) == V4L2_STD_PAL_H) {
864 curr_id = V4L2_STD_PAL_H;
865 } else if ( (id & V4L2_STD_PAL_I) == V4L2_STD_PAL_I) {
866 curr_id = V4L2_STD_PAL_I;
867 } else if ( (id & V4L2_STD_PAL_D) == V4L2_STD_PAL_D) {
868 curr_id = V4L2_STD_PAL_D;
869 } else if ( (id & V4L2_STD_PAL_D1) == V4L2_STD_PAL_D1) {
870 curr_id = V4L2_STD_PAL_D1;
871 } else if ( (id & V4L2_STD_PAL_K) == V4L2_STD_PAL_K) {
872 curr_id = V4L2_STD_PAL_K;
873 } else if ( (id & V4L2_STD_PAL_M) == V4L2_STD_PAL_M) {
874 curr_id = V4L2_STD_PAL_M;
875 } else if ( (id & V4L2_STD_PAL_N) == V4L2_STD_PAL_N) {
876 curr_id = V4L2_STD_PAL_N;
877 } else if ( (id & V4L2_STD_PAL_Nc) == V4L2_STD_PAL_Nc) {
878 curr_id = V4L2_STD_PAL_Nc;
879 } else if ( (id & V4L2_STD_PAL_60) == V4L2_STD_PAL_60) {
880 curr_id = V4L2_STD_PAL_60;
881 } else if ( (id & V4L2_STD_NTSC) == V4L2_STD_NTSC) {
882 curr_id = V4L2_STD_NTSC;
883 } else if ( (id & V4L2_STD_NTSC_M) == V4L2_STD_NTSC_M) {
884 curr_id = V4L2_STD_NTSC_M;
885 } else if ( (id & V4L2_STD_NTSC_M_JP) == V4L2_STD_NTSC_M_JP) {
886 curr_id = V4L2_STD_NTSC_M_JP;
887 } else if ( (id & V4L2_STD_NTSC_443) == V4L2_STD_NTSC_443) {
888 curr_id = V4L2_STD_NTSC_443;
889 } else if ( (id & V4L2_STD_NTSC_M_KR) == V4L2_STD_NTSC_M_KR) {
890 curr_id = V4L2_STD_NTSC_M_KR;
891 } else if ( (id & V4L2_STD_SECAM) == V4L2_STD_SECAM) {
892 curr_id = V4L2_STD_SECAM;
893 } else if ( (id & V4L2_STD_SECAM_DK) == V4L2_STD_SECAM_DK) {
894 curr_id = V4L2_STD_SECAM_DK;
895 } else if ( (id & V4L2_STD_SECAM_B) == V4L2_STD_SECAM_B) {
896 curr_id = V4L2_STD_SECAM_B;
897 } else if ( (id & V4L2_STD_SECAM_D) == V4L2_STD_SECAM_D) {
898 curr_id = V4L2_STD_SECAM_D;
899 } else if ( (id & V4L2_STD_SECAM_G) == V4L2_STD_SECAM_G) {
900 curr_id = V4L2_STD_SECAM_G;
901 } else if ( (id & V4L2_STD_SECAM_H) == V4L2_STD_SECAM_H) {
902 curr_id = V4L2_STD_SECAM_H;
903 } else if ( (id & V4L2_STD_SECAM_K) == V4L2_STD_SECAM_K) {
904 curr_id = V4L2_STD_SECAM_K;
905 } else if ( (id & V4L2_STD_SECAM_K1) == V4L2_STD_SECAM_K1) {
906 curr_id = V4L2_STD_SECAM_K1;
907 } else if ( (id & V4L2_STD_SECAM_L) == V4L2_STD_SECAM_L) {
908 curr_id = V4L2_STD_SECAM_L;
909 } else if ( (id & V4L2_STD_SECAM_LC) == V4L2_STD_SECAM_LC) {
910 curr_id = V4L2_STD_SECAM_LC;
911 } else {
912 break;
914 id &= ~curr_id;
916 if (i<=index)
917 return -EINVAL;
919 v4l2_video_std_construct(p, curr_id,v4l2_norm_to_name(curr_id));
920 p->index = index;
922 dbgarg (cmd, "index=%d, id=%Ld, name=%s, fps=%d/%d, "
923 "framelines=%d\n", p->index,
924 (unsigned long long)p->id, p->name,
925 p->frameperiod.numerator,
926 p->frameperiod.denominator,
927 p->framelines);
929 ret=0;
930 break;
932 case VIDIOC_G_STD:
934 v4l2_std_id *id = arg;
936 *id = vfd->current_norm;
938 dbgarg (cmd, "value=%Lu\n", (long long unsigned) *id);
940 ret=0;
941 break;
943 case VIDIOC_S_STD:
945 v4l2_std_id *id = arg,norm;
947 dbgarg (cmd, "value=%Lu\n", (long long unsigned) *id);
949 norm = (*id) & vfd->tvnorms;
950 if ( vfd->tvnorms && !norm) /* Check if std is supported */
951 break;
953 /* Calls the specific handler */
954 if (vfd->vidioc_s_std)
955 ret=vfd->vidioc_s_std(file, fh, &norm);
956 else
957 ret=-EINVAL;
959 /* Updates standard information */
960 if (ret>=0)
961 vfd->current_norm=norm;
963 break;
965 case VIDIOC_QUERYSTD:
967 v4l2_std_id *p=arg;
969 if (!vfd->vidioc_querystd)
970 break;
971 ret=vfd->vidioc_querystd(file, fh, arg);
972 if (!ret)
973 dbgarg (cmd, "detected std=%Lu\n",
974 (unsigned long long)*p);
975 break;
977 /* ------ input switching ---------- */
978 /* FIXME: Inputs can be handled inside videodev2 */
979 case VIDIOC_ENUMINPUT:
981 struct v4l2_input *p=arg;
982 int i=p->index;
984 if (!vfd->vidioc_enum_input)
985 break;
986 memset(p, 0, sizeof(*p));
987 p->index=i;
989 ret=vfd->vidioc_enum_input(file, fh, p);
990 if (!ret)
991 dbgarg (cmd, "index=%d, name=%s, type=%d, "
992 "audioset=%d, "
993 "tuner=%d, std=%Ld, status=%d\n",
994 p->index,p->name,p->type,p->audioset,
995 p->tuner,
996 (unsigned long long)p->std,
997 p->status);
998 break;
1000 case VIDIOC_G_INPUT:
1002 unsigned int *i = arg;
1004 if (!vfd->vidioc_g_input)
1005 break;
1006 ret=vfd->vidioc_g_input(file, fh, i);
1007 if (!ret)
1008 dbgarg (cmd, "value=%d\n",*i);
1009 break;
1011 case VIDIOC_S_INPUT:
1013 unsigned int *i = arg;
1015 if (!vfd->vidioc_s_input)
1016 break;
1017 dbgarg (cmd, "value=%d\n",*i);
1018 ret=vfd->vidioc_s_input(file, fh, *i);
1019 break;
1022 /* ------ output switching ---------- */
1023 case VIDIOC_G_OUTPUT:
1025 unsigned int *i = arg;
1027 if (!vfd->vidioc_g_output)
1028 break;
1029 ret=vfd->vidioc_g_output(file, fh, i);
1030 if (!ret)
1031 dbgarg (cmd, "value=%d\n",*i);
1032 break;
1034 case VIDIOC_S_OUTPUT:
1036 unsigned int *i = arg;
1038 if (!vfd->vidioc_s_output)
1039 break;
1040 dbgarg (cmd, "value=%d\n",*i);
1041 ret=vfd->vidioc_s_output(file, fh, *i);
1042 break;
1045 /* --- controls ---------------------------------------------- */
1046 case VIDIOC_QUERYCTRL:
1048 struct v4l2_queryctrl *p=arg;
1050 if (!vfd->vidioc_queryctrl)
1051 break;
1052 ret=vfd->vidioc_queryctrl(file, fh, p);
1054 if (!ret)
1055 dbgarg (cmd, "id=%d, type=%d, name=%s, "
1056 "min/max=%d/%d,"
1057 " step=%d, default=%d, flags=0x%08x\n",
1058 p->id,p->type,p->name,p->minimum,
1059 p->maximum,p->step,p->default_value,
1060 p->flags);
1061 break;
1063 case VIDIOC_G_CTRL:
1065 struct v4l2_control *p = arg;
1067 if (!vfd->vidioc_g_ctrl)
1068 break;
1069 dbgarg(cmd, "Enum for index=%d\n", p->id);
1071 ret=vfd->vidioc_g_ctrl(file, fh, p);
1072 if (!ret)
1073 dbgarg2 ( "id=%d, value=%d\n", p->id, p->value);
1074 break;
1076 case VIDIOC_S_CTRL:
1078 struct v4l2_control *p = arg;
1080 if (!vfd->vidioc_s_ctrl)
1081 break;
1082 dbgarg (cmd, "id=%d, value=%d\n", p->id, p->value);
1084 ret=vfd->vidioc_s_ctrl(file, fh, p);
1085 break;
1087 case VIDIOC_G_EXT_CTRLS:
1089 struct v4l2_ext_controls *p = arg;
1091 if (vfd->vidioc_g_ext_ctrls) {
1092 dbgarg(cmd, "count=%d\n", p->count);
1094 ret=vfd->vidioc_g_ext_ctrls(file, fh, p);
1096 break;
1098 case VIDIOC_S_EXT_CTRLS:
1100 struct v4l2_ext_controls *p = arg;
1102 if (vfd->vidioc_s_ext_ctrls) {
1103 dbgarg(cmd, "count=%d\n", p->count);
1105 ret=vfd->vidioc_s_ext_ctrls(file, fh, p);
1107 break;
1109 case VIDIOC_TRY_EXT_CTRLS:
1111 struct v4l2_ext_controls *p = arg;
1113 if (vfd->vidioc_try_ext_ctrls) {
1114 dbgarg(cmd, "count=%d\n", p->count);
1116 ret=vfd->vidioc_try_ext_ctrls(file, fh, p);
1118 break;
1120 case VIDIOC_QUERYMENU:
1122 struct v4l2_querymenu *p=arg;
1123 if (!vfd->vidioc_querymenu)
1124 break;
1125 ret=vfd->vidioc_querymenu(file, fh, p);
1126 if (!ret)
1127 dbgarg (cmd, "id=%d, index=%d, name=%s\n",
1128 p->id,p->index,p->name);
1129 break;
1131 /* --- audio ---------------------------------------------- */
1132 case VIDIOC_ENUMAUDIO:
1134 struct v4l2_audio *p=arg;
1136 if (!vfd->vidioc_enumaudio)
1137 break;
1138 dbgarg(cmd, "Enum for index=%d\n", p->index);
1139 ret=vfd->vidioc_enumaudio(file, fh, p);
1140 if (!ret)
1141 dbgarg2("index=%d, name=%s, capability=%d, "
1142 "mode=%d\n",p->index,p->name,
1143 p->capability, p->mode);
1144 break;
1146 case VIDIOC_G_AUDIO:
1148 struct v4l2_audio *p=arg;
1149 __u32 index=p->index;
1151 if (!vfd->vidioc_g_audio)
1152 break;
1154 memset(p,0,sizeof(*p));
1155 p->index=index;
1156 dbgarg(cmd, "Get for index=%d\n", p->index);
1157 ret=vfd->vidioc_g_audio(file, fh, p);
1158 if (!ret)
1159 dbgarg2("index=%d, name=%s, capability=%d, "
1160 "mode=%d\n",p->index,
1161 p->name,p->capability, p->mode);
1162 break;
1164 case VIDIOC_S_AUDIO:
1166 struct v4l2_audio *p=arg;
1168 if (!vfd->vidioc_s_audio)
1169 break;
1170 dbgarg(cmd, "index=%d, name=%s, capability=%d, "
1171 "mode=%d\n", p->index, p->name,
1172 p->capability, p->mode);
1173 ret=vfd->vidioc_s_audio(file, fh, p);
1174 break;
1176 case VIDIOC_ENUMAUDOUT:
1178 struct v4l2_audioout *p=arg;
1180 if (!vfd->vidioc_enumaudout)
1181 break;
1182 dbgarg(cmd, "Enum for index=%d\n", p->index);
1183 ret=vfd->vidioc_enumaudout(file, fh, p);
1184 if (!ret)
1185 dbgarg2("index=%d, name=%s, capability=%d, "
1186 "mode=%d\n", p->index, p->name,
1187 p->capability,p->mode);
1188 break;
1190 case VIDIOC_G_AUDOUT:
1192 struct v4l2_audioout *p=arg;
1194 if (!vfd->vidioc_g_audout)
1195 break;
1196 dbgarg(cmd, "Enum for index=%d\n", p->index);
1197 ret=vfd->vidioc_g_audout(file, fh, p);
1198 if (!ret)
1199 dbgarg2("index=%d, name=%s, capability=%d, "
1200 "mode=%d\n", p->index, p->name,
1201 p->capability,p->mode);
1202 break;
1204 case VIDIOC_S_AUDOUT:
1206 struct v4l2_audioout *p=arg;
1208 if (!vfd->vidioc_s_audout)
1209 break;
1210 dbgarg(cmd, "index=%d, name=%s, capability=%d, "
1211 "mode=%d\n", p->index, p->name,
1212 p->capability,p->mode);
1214 ret=vfd->vidioc_s_audout(file, fh, p);
1215 break;
1217 case VIDIOC_G_MODULATOR:
1219 struct v4l2_modulator *p=arg;
1220 if (!vfd->vidioc_g_modulator)
1221 break;
1222 ret=vfd->vidioc_g_modulator(file, fh, p);
1223 if (!ret)
1224 dbgarg(cmd, "index=%d, name=%s, "
1225 "capability=%d, rangelow=%d,"
1226 " rangehigh=%d, txsubchans=%d\n",
1227 p->index, p->name,p->capability,
1228 p->rangelow, p->rangehigh,
1229 p->txsubchans);
1230 break;
1232 case VIDIOC_S_MODULATOR:
1234 struct v4l2_modulator *p=arg;
1235 if (!vfd->vidioc_s_modulator)
1236 break;
1237 dbgarg(cmd, "index=%d, name=%s, capability=%d, "
1238 "rangelow=%d, rangehigh=%d, txsubchans=%d\n",
1239 p->index, p->name,p->capability,p->rangelow,
1240 p->rangehigh,p->txsubchans);
1241 ret=vfd->vidioc_s_modulator(file, fh, p);
1242 break;
1244 case VIDIOC_G_CROP:
1246 struct v4l2_crop *p=arg;
1247 if (!vfd->vidioc_g_crop)
1248 break;
1249 ret=vfd->vidioc_g_crop(file, fh, p);
1250 if (!ret) {
1251 dbgarg(cmd, "type=%d\n", p->type);
1252 dbgrect(vfd, "", &p->c);
1254 break;
1256 case VIDIOC_S_CROP:
1258 struct v4l2_crop *p=arg;
1259 if (!vfd->vidioc_s_crop)
1260 break;
1261 dbgarg(cmd, "type=%d\n", p->type);
1262 dbgrect(vfd, "", &p->c);
1263 ret=vfd->vidioc_s_crop(file, fh, p);
1264 break;
1266 case VIDIOC_CROPCAP:
1268 struct v4l2_cropcap *p=arg;
1269 /*FIXME: Should also show v4l2_fract pixelaspect */
1270 if (!vfd->vidioc_cropcap)
1271 break;
1272 dbgarg(cmd, "type=%d\n", p->type);
1273 dbgrect(vfd, "bounds ", &p->bounds);
1274 dbgrect(vfd, "defrect ", &p->defrect);
1275 ret=vfd->vidioc_cropcap(file, fh, p);
1276 break;
1278 case VIDIOC_G_MPEGCOMP:
1280 struct v4l2_mpeg_compression *p=arg;
1282 /*FIXME: Several fields not shown */
1283 if (!vfd->vidioc_g_mpegcomp)
1284 break;
1285 ret=vfd->vidioc_g_mpegcomp(file, fh, p);
1286 if (!ret)
1287 dbgarg (cmd, "ts_pid_pmt=%d, ts_pid_audio=%d,"
1288 " ts_pid_video=%d, ts_pid_pcr=%d, "
1289 "ps_size=%d, au_sample_rate=%d, "
1290 "au_pesid=%c, vi_frame_rate=%d, "
1291 "vi_frames_per_gop=%d, "
1292 "vi_bframes_count=%d, vi_pesid=%c\n",
1293 p->ts_pid_pmt,p->ts_pid_audio,
1294 p->ts_pid_video,p->ts_pid_pcr,
1295 p->ps_size, p->au_sample_rate,
1296 p->au_pesid, p->vi_frame_rate,
1297 p->vi_frames_per_gop,
1298 p->vi_bframes_count, p->vi_pesid);
1299 break;
1301 case VIDIOC_S_MPEGCOMP:
1303 struct v4l2_mpeg_compression *p=arg;
1304 /*FIXME: Several fields not shown */
1305 if (!vfd->vidioc_s_mpegcomp)
1306 break;
1307 dbgarg (cmd, "ts_pid_pmt=%d, ts_pid_audio=%d, "
1308 "ts_pid_video=%d, ts_pid_pcr=%d, ps_size=%d, "
1309 "au_sample_rate=%d, au_pesid=%c, "
1310 "vi_frame_rate=%d, vi_frames_per_gop=%d, "
1311 "vi_bframes_count=%d, vi_pesid=%c\n",
1312 p->ts_pid_pmt,p->ts_pid_audio, p->ts_pid_video,
1313 p->ts_pid_pcr, p->ps_size, p->au_sample_rate,
1314 p->au_pesid, p->vi_frame_rate,
1315 p->vi_frames_per_gop, p->vi_bframes_count,
1316 p->vi_pesid);
1317 ret=vfd->vidioc_s_mpegcomp(file, fh, p);
1318 break;
1320 case VIDIOC_G_JPEGCOMP:
1322 struct v4l2_jpegcompression *p=arg;
1323 if (!vfd->vidioc_g_jpegcomp)
1324 break;
1325 ret=vfd->vidioc_g_jpegcomp(file, fh, p);
1326 if (!ret)
1327 dbgarg (cmd, "quality=%d, APPn=%d, "
1328 "APP_len=%d, COM_len=%d, "
1329 "jpeg_markers=%d\n",
1330 p->quality,p->APPn,p->APP_len,
1331 p->COM_len,p->jpeg_markers);
1332 break;
1334 case VIDIOC_S_JPEGCOMP:
1336 struct v4l2_jpegcompression *p=arg;
1337 if (!vfd->vidioc_g_jpegcomp)
1338 break;
1339 dbgarg (cmd, "quality=%d, APPn=%d, APP_len=%d, "
1340 "COM_len=%d, jpeg_markers=%d\n",
1341 p->quality,p->APPn,p->APP_len,
1342 p->COM_len,p->jpeg_markers);
1343 ret=vfd->vidioc_s_jpegcomp(file, fh, p);
1344 break;
1346 case VIDIOC_G_PARM:
1348 struct v4l2_streamparm *p=arg;
1349 if (vfd->vidioc_g_parm) {
1350 ret=vfd->vidioc_g_parm(file, fh, p);
1351 } else {
1352 struct v4l2_standard s;
1354 if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1355 return -EINVAL;
1357 v4l2_video_std_construct(&s, vfd->current_norm,
1358 v4l2_norm_to_name(vfd->current_norm));
1360 memset(p,0,sizeof(*p));
1362 p->parm.capture.timeperframe = s.frameperiod;
1363 ret=0;
1366 dbgarg (cmd, "type=%d\n", p->type);
1367 break;
1369 case VIDIOC_S_PARM:
1371 struct v4l2_streamparm *p=arg;
1372 if (!vfd->vidioc_s_parm)
1373 break;
1374 dbgarg (cmd, "type=%d\n", p->type);
1375 ret=vfd->vidioc_s_parm(file, fh, p);
1376 break;
1378 case VIDIOC_G_TUNER:
1380 struct v4l2_tuner *p=arg;
1381 __u32 index=p->index;
1383 if (!vfd->vidioc_g_tuner)
1384 break;
1386 memset(p,0,sizeof(*p));
1387 p->index=index;
1389 ret=vfd->vidioc_g_tuner(file, fh, p);
1390 if (!ret)
1391 dbgarg (cmd, "index=%d, name=%s, type=%d, "
1392 "capability=%d, rangelow=%d, "
1393 "rangehigh=%d, signal=%d, afc=%d, "
1394 "rxsubchans=%d, audmode=%d\n",
1395 p->index, p->name, p->type,
1396 p->capability, p->rangelow,
1397 p->rangehigh, p->rxsubchans,
1398 p->audmode, p->signal, p->afc);
1399 break;
1401 case VIDIOC_S_TUNER:
1403 struct v4l2_tuner *p=arg;
1404 if (!vfd->vidioc_s_tuner)
1405 break;
1406 dbgarg (cmd, "index=%d, name=%s, type=%d, "
1407 "capability=%d, rangelow=%d, rangehigh=%d, "
1408 "signal=%d, afc=%d, rxsubchans=%d, "
1409 "audmode=%d\n",p->index, p->name, p->type,
1410 p->capability, p->rangelow,p->rangehigh,
1411 p->rxsubchans, p->audmode, p->signal,
1412 p->afc);
1413 ret=vfd->vidioc_s_tuner(file, fh, p);
1414 break;
1416 case VIDIOC_G_FREQUENCY:
1418 struct v4l2_frequency *p=arg;
1419 if (!vfd->vidioc_g_frequency)
1420 break;
1422 memset(p,0,sizeof(*p));
1424 ret=vfd->vidioc_g_frequency(file, fh, p);
1425 if (!ret)
1426 dbgarg (cmd, "tuner=%d, type=%d, frequency=%d\n",
1427 p->tuner,p->type,p->frequency);
1428 break;
1430 case VIDIOC_S_FREQUENCY:
1432 struct v4l2_frequency *p=arg;
1433 if (!vfd->vidioc_s_frequency)
1434 break;
1435 dbgarg (cmd, "tuner=%d, type=%d, frequency=%d\n",
1436 p->tuner,p->type,p->frequency);
1437 ret=vfd->vidioc_s_frequency(file, fh, p);
1438 break;
1440 case VIDIOC_G_SLICED_VBI_CAP:
1442 struct v4l2_sliced_vbi_cap *p=arg;
1443 if (!vfd->vidioc_g_sliced_vbi_cap)
1444 break;
1445 ret=vfd->vidioc_g_sliced_vbi_cap(file, fh, p);
1446 if (!ret)
1447 dbgarg (cmd, "service_set=%d\n", p->service_set);
1448 break;
1450 case VIDIOC_LOG_STATUS:
1452 if (!vfd->vidioc_log_status)
1453 break;
1454 ret=vfd->vidioc_log_status(file, fh);
1455 break;
1457 } /* switch */
1459 if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) {
1460 if (ret<0) {
1461 printk ("%s: err:\n", vfd->name);
1462 v4l_print_ioctl(vfd->name, cmd);
1466 return ret;
1469 int video_ioctl2 (struct inode *inode, struct file *file,
1470 unsigned int cmd, unsigned long arg)
1472 char sbuf[128];
1473 void *mbuf = NULL;
1474 void *parg = NULL;
1475 int err = -EINVAL;
1476 int is_ext_ctrl;
1477 size_t ctrls_size = 0;
1478 void __user *user_ptr = NULL;
1480 #ifdef __OLD_VIDIOC_
1481 cmd = video_fix_command(cmd);
1482 #endif
1483 is_ext_ctrl = (cmd == VIDIOC_S_EXT_CTRLS || cmd == VIDIOC_G_EXT_CTRLS ||
1484 cmd == VIDIOC_TRY_EXT_CTRLS);
1486 /* Copy arguments into temp kernel buffer */
1487 switch (_IOC_DIR(cmd)) {
1488 case _IOC_NONE:
1489 parg = NULL;
1490 break;
1491 case _IOC_READ:
1492 case _IOC_WRITE:
1493 case (_IOC_WRITE | _IOC_READ):
1494 if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
1495 parg = sbuf;
1496 } else {
1497 /* too big to allocate from stack */
1498 mbuf = kmalloc(_IOC_SIZE(cmd),GFP_KERNEL);
1499 if (NULL == mbuf)
1500 return -ENOMEM;
1501 parg = mbuf;
1504 err = -EFAULT;
1505 if (_IOC_DIR(cmd) & _IOC_WRITE)
1506 if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd)))
1507 goto out;
1508 break;
1511 if (is_ext_ctrl) {
1512 struct v4l2_ext_controls *p = parg;
1514 /* In case of an error, tell the caller that it wasn't
1515 a specific control that caused it. */
1516 p->error_idx = p->count;
1517 user_ptr = (void __user *)p->controls;
1518 if (p->count) {
1519 ctrls_size = sizeof(struct v4l2_ext_control) * p->count;
1520 /* Note: v4l2_ext_controls fits in sbuf[] so mbuf is still NULL. */
1521 mbuf = kmalloc(ctrls_size, GFP_KERNEL);
1522 err = -ENOMEM;
1523 if (NULL == mbuf)
1524 goto out_ext_ctrl;
1525 err = -EFAULT;
1526 if (copy_from_user(mbuf, user_ptr, ctrls_size))
1527 goto out_ext_ctrl;
1528 p->controls = mbuf;
1532 /* Handles IOCTL */
1533 err = __video_do_ioctl(inode, file, cmd, parg);
1534 if (err == -ENOIOCTLCMD)
1535 err = -EINVAL;
1536 if (is_ext_ctrl) {
1537 struct v4l2_ext_controls *p = parg;
1539 p->controls = (void *)user_ptr;
1540 if (p->count && err == 0 && copy_to_user(user_ptr, mbuf, ctrls_size))
1541 err = -EFAULT;
1542 goto out_ext_ctrl;
1544 if (err < 0)
1545 goto out;
1547 out_ext_ctrl:
1548 /* Copy results into user buffer */
1549 switch (_IOC_DIR(cmd))
1551 case _IOC_READ:
1552 case (_IOC_WRITE | _IOC_READ):
1553 if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd)))
1554 err = -EFAULT;
1555 break;
1558 out:
1559 kfree(mbuf);
1560 return err;
1564 static struct file_operations video_fops;
1567 * video_register_device - register video4linux devices
1568 * @vfd: video device structure we want to register
1569 * @type: type of device to register
1570 * @nr: which device number (0 == /dev/video0, 1 == /dev/video1, ...
1571 * -1 == first free)
1573 * The registration code assigns minor numbers based on the type
1574 * requested. -ENFILE is returned in all the device slots for this
1575 * category are full. If not then the minor field is set and the
1576 * driver initialize function is called (if non %NULL).
1578 * Zero is returned on success.
1580 * Valid types are
1582 * %VFL_TYPE_GRABBER - A frame grabber
1584 * %VFL_TYPE_VTX - A teletext device
1586 * %VFL_TYPE_VBI - Vertical blank data (undecoded)
1588 * %VFL_TYPE_RADIO - A radio card
1591 int video_register_device(struct video_device *vfd, int type, int nr)
1593 int i=0;
1594 int base;
1595 int end;
1596 int ret;
1597 char *name_base;
1599 switch(type)
1601 case VFL_TYPE_GRABBER:
1602 base=MINOR_VFL_TYPE_GRABBER_MIN;
1603 end=MINOR_VFL_TYPE_GRABBER_MAX+1;
1604 name_base = "video";
1605 break;
1606 case VFL_TYPE_VTX:
1607 base=MINOR_VFL_TYPE_VTX_MIN;
1608 end=MINOR_VFL_TYPE_VTX_MAX+1;
1609 name_base = "vtx";
1610 break;
1611 case VFL_TYPE_VBI:
1612 base=MINOR_VFL_TYPE_VBI_MIN;
1613 end=MINOR_VFL_TYPE_VBI_MAX+1;
1614 name_base = "vbi";
1615 break;
1616 case VFL_TYPE_RADIO:
1617 base=MINOR_VFL_TYPE_RADIO_MIN;
1618 end=MINOR_VFL_TYPE_RADIO_MAX+1;
1619 name_base = "radio";
1620 break;
1621 default:
1622 printk(KERN_ERR "%s called with unknown type: %d\n",
1623 __FUNCTION__, type);
1624 return -1;
1627 /* pick a minor number */
1628 mutex_lock(&videodev_lock);
1629 if (nr >= 0 && nr < end-base) {
1630 /* use the one the driver asked for */
1631 i = base+nr;
1632 if (NULL != video_device[i]) {
1633 mutex_unlock(&videodev_lock);
1634 return -ENFILE;
1636 } else {
1637 /* use first free */
1638 for(i=base;i<end;i++)
1639 if (NULL == video_device[i])
1640 break;
1641 if (i == end) {
1642 mutex_unlock(&videodev_lock);
1643 return -ENFILE;
1646 video_device[i]=vfd;
1647 vfd->minor=i;
1648 mutex_unlock(&videodev_lock);
1649 mutex_init(&vfd->lock);
1651 /* sysfs class */
1652 memset(&vfd->class_dev, 0x00, sizeof(vfd->class_dev));
1653 if (vfd->dev)
1654 vfd->class_dev.dev = vfd->dev;
1655 vfd->class_dev.class = &video_class;
1656 vfd->class_dev.devt = MKDEV(VIDEO_MAJOR, vfd->minor);
1657 sprintf(vfd->class_dev.class_id, "%s%d", name_base, i - base);
1658 ret = class_device_register(&vfd->class_dev);
1659 if (ret < 0) {
1660 printk(KERN_ERR "%s: class_device_register failed\n",
1661 __FUNCTION__);
1662 goto fail_minor;
1664 ret = class_device_create_file(&vfd->class_dev, &class_device_attr_name);
1665 if (ret < 0) {
1666 printk(KERN_ERR "%s: class_device_create_file 'name' failed\n",
1667 __FUNCTION__);
1668 goto fail_classdev;
1671 #if 1
1672 /* needed until all drivers are fixed */
1673 if (!vfd->release)
1674 printk(KERN_WARNING "videodev: \"%s\" has no release callback. "
1675 "Please fix your driver for proper sysfs support, see "
1676 "http://lwn.net/Articles/36850/\n", vfd->name);
1677 #endif
1678 return 0;
1680 fail_classdev:
1681 class_device_unregister(&vfd->class_dev);
1682 fail_minor:
1683 mutex_lock(&videodev_lock);
1684 video_device[vfd->minor] = NULL;
1685 vfd->minor = -1;
1686 mutex_unlock(&videodev_lock);
1687 return ret;
1691 * video_unregister_device - unregister a video4linux device
1692 * @vfd: the device to unregister
1694 * This unregisters the passed device and deassigns the minor
1695 * number. Future open calls will be met with errors.
1698 void video_unregister_device(struct video_device *vfd)
1700 mutex_lock(&videodev_lock);
1701 if(video_device[vfd->minor]!=vfd)
1702 panic("videodev: bad unregister");
1704 video_device[vfd->minor]=NULL;
1705 class_device_unregister(&vfd->class_dev);
1706 mutex_unlock(&videodev_lock);
1710 * Video fs operations
1712 static struct file_operations video_fops=
1714 .owner = THIS_MODULE,
1715 .llseek = no_llseek,
1716 .open = video_open,
1720 * Initialise video for linux
1723 static int __init videodev_init(void)
1725 int ret;
1727 printk(KERN_INFO "Linux video capture interface: v2.00\n");
1728 if (register_chrdev(VIDEO_MAJOR, VIDEO_NAME, &video_fops)) {
1729 printk(KERN_WARNING "video_dev: unable to get major %d\n", VIDEO_MAJOR);
1730 return -EIO;
1733 ret = class_register(&video_class);
1734 if (ret < 0) {
1735 unregister_chrdev(VIDEO_MAJOR, VIDEO_NAME);
1736 printk(KERN_WARNING "video_dev: class_register failed\n");
1737 return -EIO;
1740 return 0;
1743 static void __exit videodev_exit(void)
1745 class_unregister(&video_class);
1746 unregister_chrdev(VIDEO_MAJOR, VIDEO_NAME);
1749 module_init(videodev_init)
1750 module_exit(videodev_exit)
1752 EXPORT_SYMBOL(video_register_device);
1753 EXPORT_SYMBOL(video_unregister_device);
1754 EXPORT_SYMBOL(video_devdata);
1755 EXPORT_SYMBOL(video_usercopy);
1756 EXPORT_SYMBOL(video_exclusive_open);
1757 EXPORT_SYMBOL(video_exclusive_release);
1758 EXPORT_SYMBOL(video_ioctl2);
1759 EXPORT_SYMBOL(video_device_alloc);
1760 EXPORT_SYMBOL(video_device_release);
1762 MODULE_AUTHOR("Alan Cox, Mauro Carvalho Chehab <mchehab@infradead.org>");
1763 MODULE_DESCRIPTION("Device registrar for Video4Linux drivers v2");
1764 MODULE_LICENSE("GPL");
1768 * Local variables:
1769 * c-basic-offset: 8
1770 * End: