[PATCH] remove many unneeded #includes of sched.h
[linux-2.6/linux-2.6-openrd.git] / drivers / media / video / videodev.c
bloba786c1f5b9601a98474f70073cb107df1ff9e0bc
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/smp_lock.h>
34 #include <linux/mm.h>
35 #include <linux/string.h>
36 #include <linux/errno.h>
37 #include <linux/init.h>
38 #include <linux/kmod.h>
39 #include <linux/slab.h>
40 #include <asm/uaccess.h>
41 #include <asm/system.h>
43 #define __OLD_VIDIOC_ /* To allow fixing old calls*/
44 #include <linux/videodev2.h>
46 #ifdef CONFIG_VIDEO_V4L1
47 #include <linux/videodev.h>
48 #endif
49 #include <media/v4l2-common.h>
51 #define VIDEO_NUM_DEVICES 256
52 #define VIDEO_NAME "video4linux"
55 * sysfs stuff
58 static ssize_t show_name(struct class_device *cd, 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 static CLASS_DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
67 struct video_device *video_device_alloc(void)
69 struct video_device *vfd;
71 vfd = kzalloc(sizeof(*vfd),GFP_KERNEL);
72 return vfd;
75 void video_device_release(struct video_device *vfd)
77 kfree(vfd);
80 static void video_release(struct class_device *cd)
82 struct video_device *vfd = container_of(cd, struct video_device,
83 class_dev);
85 #if 1
86 /* needed until all drivers are fixed */
87 if (!vfd->release)
88 return;
89 #endif
90 vfd->release(vfd);
93 static struct class video_class = {
94 .name = VIDEO_NAME,
95 .release = video_release,
99 * Active devices
102 static struct video_device *video_device[VIDEO_NUM_DEVICES];
103 static DEFINE_MUTEX(videodev_lock);
105 struct video_device* video_devdata(struct file *file)
107 return video_device[iminor(file->f_path.dentry->d_inode)];
111 * Open a video device - FIXME: Obsoleted
113 static int video_open(struct inode *inode, struct file *file)
115 unsigned int minor = iminor(inode);
116 int err = 0;
117 struct video_device *vfl;
118 const struct file_operations *old_fops;
120 if(minor>=VIDEO_NUM_DEVICES)
121 return -ENODEV;
122 mutex_lock(&videodev_lock);
123 vfl=video_device[minor];
124 if(vfl==NULL) {
125 mutex_unlock(&videodev_lock);
126 request_module("char-major-%d-%d", VIDEO_MAJOR, minor);
127 mutex_lock(&videodev_lock);
128 vfl=video_device[minor];
129 if (vfl==NULL) {
130 mutex_unlock(&videodev_lock);
131 return -ENODEV;
134 old_fops = file->f_op;
135 file->f_op = fops_get(vfl->fops);
136 if(file->f_op->open)
137 err = file->f_op->open(inode,file);
138 if (err) {
139 fops_put(file->f_op);
140 file->f_op = fops_get(old_fops);
142 fops_put(old_fops);
143 mutex_unlock(&videodev_lock);
144 return err;
148 * helper function -- handles userspace copying for ioctl arguments
151 #ifdef __OLD_VIDIOC_
152 static unsigned int
153 video_fix_command(unsigned int cmd)
155 switch (cmd) {
156 case VIDIOC_OVERLAY_OLD:
157 cmd = VIDIOC_OVERLAY;
158 break;
159 case VIDIOC_S_PARM_OLD:
160 cmd = VIDIOC_S_PARM;
161 break;
162 case VIDIOC_S_CTRL_OLD:
163 cmd = VIDIOC_S_CTRL;
164 break;
165 case VIDIOC_G_AUDIO_OLD:
166 cmd = VIDIOC_G_AUDIO;
167 break;
168 case VIDIOC_G_AUDOUT_OLD:
169 cmd = VIDIOC_G_AUDOUT;
170 break;
171 case VIDIOC_CROPCAP_OLD:
172 cmd = VIDIOC_CROPCAP;
173 break;
175 return cmd;
177 #endif
180 * Obsolete usercopy function - Should be removed soon
183 video_usercopy(struct inode *inode, struct file *file,
184 unsigned int cmd, unsigned long arg,
185 int (*func)(struct inode *inode, struct file *file,
186 unsigned int cmd, void *arg))
188 char sbuf[128];
189 void *mbuf = NULL;
190 void *parg = NULL;
191 int err = -EINVAL;
192 int is_ext_ctrl;
193 size_t ctrls_size = 0;
194 void __user *user_ptr = NULL;
196 #ifdef __OLD_VIDIOC_
197 cmd = video_fix_command(cmd);
198 #endif
199 is_ext_ctrl = (cmd == VIDIOC_S_EXT_CTRLS || cmd == VIDIOC_G_EXT_CTRLS ||
200 cmd == VIDIOC_TRY_EXT_CTRLS);
202 /* Copy arguments into temp kernel buffer */
203 switch (_IOC_DIR(cmd)) {
204 case _IOC_NONE:
205 parg = NULL;
206 break;
207 case _IOC_READ:
208 case _IOC_WRITE:
209 case (_IOC_WRITE | _IOC_READ):
210 if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
211 parg = sbuf;
212 } else {
213 /* too big to allocate from stack */
214 mbuf = kmalloc(_IOC_SIZE(cmd),GFP_KERNEL);
215 if (NULL == mbuf)
216 return -ENOMEM;
217 parg = mbuf;
220 err = -EFAULT;
221 if (_IOC_DIR(cmd) & _IOC_WRITE)
222 if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd)))
223 goto out;
224 break;
226 if (is_ext_ctrl) {
227 struct v4l2_ext_controls *p = parg;
229 /* In case of an error, tell the caller that it wasn't
230 a specific control that caused it. */
231 p->error_idx = p->count;
232 user_ptr = (void __user *)p->controls;
233 if (p->count) {
234 ctrls_size = sizeof(struct v4l2_ext_control) * p->count;
235 /* Note: v4l2_ext_controls fits in sbuf[] so mbuf is still NULL. */
236 mbuf = kmalloc(ctrls_size, GFP_KERNEL);
237 err = -ENOMEM;
238 if (NULL == mbuf)
239 goto out_ext_ctrl;
240 err = -EFAULT;
241 if (copy_from_user(mbuf, user_ptr, ctrls_size))
242 goto out_ext_ctrl;
243 p->controls = mbuf;
247 /* call driver */
248 err = func(inode, file, cmd, parg);
249 if (err == -ENOIOCTLCMD)
250 err = -EINVAL;
251 if (is_ext_ctrl) {
252 struct v4l2_ext_controls *p = parg;
254 p->controls = (void *)user_ptr;
255 if (p->count && err == 0 && copy_to_user(user_ptr, mbuf, ctrls_size))
256 err = -EFAULT;
257 goto out_ext_ctrl;
259 if (err < 0)
260 goto out;
262 out_ext_ctrl:
263 /* Copy results into user buffer */
264 switch (_IOC_DIR(cmd))
266 case _IOC_READ:
267 case (_IOC_WRITE | _IOC_READ):
268 if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd)))
269 err = -EFAULT;
270 break;
273 out:
274 kfree(mbuf);
275 return err;
279 * open/release helper functions -- handle exclusive opens
280 * Should be removed soon
282 int video_exclusive_open(struct inode *inode, struct file *file)
284 struct video_device *vfl = video_devdata(file);
285 int retval = 0;
287 mutex_lock(&vfl->lock);
288 if (vfl->users) {
289 retval = -EBUSY;
290 } else {
291 vfl->users++;
293 mutex_unlock(&vfl->lock);
294 return retval;
297 int video_exclusive_release(struct inode *inode, struct file *file)
299 struct video_device *vfl = video_devdata(file);
301 vfl->users--;
302 return 0;
305 static char *v4l2_memory_names[] = {
306 [V4L2_MEMORY_MMAP] = "mmap",
307 [V4L2_MEMORY_USERPTR] = "userptr",
308 [V4L2_MEMORY_OVERLAY] = "overlay",
312 /* FIXME: Those stuff are replicated also on v4l2-common.c */
313 static char *v4l2_type_names_FIXME[] = {
314 [V4L2_BUF_TYPE_VIDEO_CAPTURE] = "video-cap",
315 [V4L2_BUF_TYPE_VIDEO_OVERLAY] = "video-over",
316 [V4L2_BUF_TYPE_VIDEO_OUTPUT] = "video-out",
317 [V4L2_BUF_TYPE_VBI_CAPTURE] = "vbi-cap",
318 [V4L2_BUF_TYPE_VBI_OUTPUT] = "vbi-out",
319 [V4L2_BUF_TYPE_SLICED_VBI_OUTPUT] = "sliced-vbi-out",
320 [V4L2_BUF_TYPE_SLICED_VBI_CAPTURE] = "sliced-vbi-capture",
321 [V4L2_BUF_TYPE_PRIVATE] = "private",
324 static char *v4l2_field_names_FIXME[] = {
325 [V4L2_FIELD_ANY] = "any",
326 [V4L2_FIELD_NONE] = "none",
327 [V4L2_FIELD_TOP] = "top",
328 [V4L2_FIELD_BOTTOM] = "bottom",
329 [V4L2_FIELD_INTERLACED] = "interlaced",
330 [V4L2_FIELD_SEQ_TB] = "seq-tb",
331 [V4L2_FIELD_SEQ_BT] = "seq-bt",
332 [V4L2_FIELD_ALTERNATE] = "alternate",
335 #define prt_names(a,arr) (((a)>=0)&&((a)<ARRAY_SIZE(arr)))?arr[a]:"unknown"
337 static void dbgbuf(unsigned int cmd, struct video_device *vfd,
338 struct v4l2_buffer *p)
340 struct v4l2_timecode *tc=&p->timecode;
342 dbgarg (cmd, "%02ld:%02d:%02d.%08ld index=%d, type=%s, "
343 "bytesused=%d, flags=0x%08d, "
344 "field=%0d, sequence=%d, memory=%s, offset/userptr=0x%08lx, length=%d\n",
345 (p->timestamp.tv_sec/3600),
346 (int)(p->timestamp.tv_sec/60)%60,
347 (int)(p->timestamp.tv_sec%60),
348 p->timestamp.tv_usec,
349 p->index,
350 prt_names(p->type,v4l2_type_names_FIXME),
351 p->bytesused,p->flags,
352 p->field,p->sequence,
353 prt_names(p->memory,v4l2_memory_names),
354 p->m.userptr, p->length);
355 dbgarg2 ("timecode= %02d:%02d:%02d type=%d, "
356 "flags=0x%08d, frames=%d, userbits=0x%08x\n",
357 tc->hours,tc->minutes,tc->seconds,
358 tc->type, tc->flags, tc->frames, *(__u32 *) tc->userbits);
361 static inline void dbgrect(struct video_device *vfd, char *s,
362 struct v4l2_rect *r)
364 dbgarg2 ("%sRect start at %dx%d, size= %dx%d\n", s, r->left, r->top,
365 r->width, r->height);
368 static inline void v4l_print_pix_fmt (struct video_device *vfd,
369 struct v4l2_pix_format *fmt)
371 dbgarg2 ("width=%d, height=%d, format=%c%c%c%c, field=%s, "
372 "bytesperline=%d sizeimage=%d, colorspace=%d\n",
373 fmt->width,fmt->height,
374 (fmt->pixelformat & 0xff),
375 (fmt->pixelformat >> 8) & 0xff,
376 (fmt->pixelformat >> 16) & 0xff,
377 (fmt->pixelformat >> 24) & 0xff,
378 prt_names(fmt->field,v4l2_field_names_FIXME),
379 fmt->bytesperline,fmt->sizeimage,fmt->colorspace);
383 static int check_fmt (struct video_device *vfd, enum v4l2_buf_type type)
385 switch (type) {
386 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
387 if (vfd->vidioc_try_fmt_cap)
388 return (0);
389 break;
390 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
391 if (vfd->vidioc_try_fmt_overlay)
392 return (0);
393 break;
394 case V4L2_BUF_TYPE_VBI_CAPTURE:
395 if (vfd->vidioc_try_fmt_vbi)
396 return (0);
397 break;
398 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
399 if (vfd->vidioc_try_fmt_vbi_output)
400 return (0);
401 break;
402 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
403 if (vfd->vidioc_try_fmt_vbi_capture)
404 return (0);
405 break;
406 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
407 if (vfd->vidioc_try_fmt_video_output)
408 return (0);
409 break;
410 case V4L2_BUF_TYPE_VBI_OUTPUT:
411 if (vfd->vidioc_try_fmt_vbi_output)
412 return (0);
413 break;
414 case V4L2_BUF_TYPE_PRIVATE:
415 if (vfd->vidioc_try_fmt_type_private)
416 return (0);
417 break;
419 return (-EINVAL);
422 static int __video_do_ioctl(struct inode *inode, struct file *file,
423 unsigned int cmd, void *arg)
425 struct video_device *vfd = video_devdata(file);
426 void *fh = file->private_data;
427 int ret = -EINVAL;
429 if ( (vfd->debug & V4L2_DEBUG_IOCTL) &&
430 !(vfd->debug | V4L2_DEBUG_IOCTL_ARG)) {
431 v4l_print_ioctl(vfd->name, cmd);
434 if (_IOC_TYPE(cmd)=='v')
435 return v4l_compat_translate_ioctl(inode,file,cmd,arg,
436 __video_do_ioctl);
438 switch(cmd) {
439 /* --- capabilities ------------------------------------------ */
440 case VIDIOC_QUERYCAP:
442 struct v4l2_capability *cap = (struct v4l2_capability*)arg;
443 memset(cap, 0, sizeof(*cap));
445 if (!vfd->vidioc_querycap)
446 break;
448 ret=vfd->vidioc_querycap(file, fh, cap);
449 if (!ret)
450 dbgarg (cmd, "driver=%s, card=%s, bus=%s, "
451 "version=0x%08x, "
452 "capabilities=0x%08x\n",
453 cap->driver,cap->card,cap->bus_info,
454 cap->version,
455 cap->capabilities);
456 break;
459 /* --- priority ------------------------------------------ */
460 case VIDIOC_G_PRIORITY:
462 enum v4l2_priority *p=arg;
464 if (!vfd->vidioc_g_priority)
465 break;
466 ret=vfd->vidioc_g_priority(file, fh, p);
467 if (!ret)
468 dbgarg(cmd, "priority is %d\n", *p);
469 break;
471 case VIDIOC_S_PRIORITY:
473 enum v4l2_priority *p=arg;
475 if (!vfd->vidioc_s_priority)
476 break;
477 dbgarg(cmd, "setting priority to %d\n", *p);
478 ret=vfd->vidioc_s_priority(file, fh, *p);
479 break;
482 /* --- capture ioctls ---------------------------------------- */
483 case VIDIOC_ENUM_FMT:
485 struct v4l2_fmtdesc *f = arg;
486 enum v4l2_buf_type type;
487 unsigned int index;
489 index = f->index;
490 type = f->type;
491 memset(f,0,sizeof(*f));
492 f->index = index;
493 f->type = type;
495 switch (type) {
496 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
497 if (vfd->vidioc_enum_fmt_cap)
498 ret=vfd->vidioc_enum_fmt_cap(file, fh, f);
499 break;
500 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
501 if (vfd->vidioc_enum_fmt_overlay)
502 ret=vfd->vidioc_enum_fmt_overlay(file, fh, f);
503 break;
504 case V4L2_BUF_TYPE_VBI_CAPTURE:
505 if (vfd->vidioc_enum_fmt_vbi)
506 ret=vfd->vidioc_enum_fmt_vbi(file, fh, f);
507 break;
508 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
509 if (vfd->vidioc_enum_fmt_vbi_output)
510 ret=vfd->vidioc_enum_fmt_vbi_output(file,
511 fh, f);
512 break;
513 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
514 if (vfd->vidioc_enum_fmt_vbi_capture)
515 ret=vfd->vidioc_enum_fmt_vbi_capture(file,
516 fh, f);
517 break;
518 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
519 if (vfd->vidioc_enum_fmt_video_output)
520 ret=vfd->vidioc_enum_fmt_video_output(file,
521 fh, f);
522 break;
523 case V4L2_BUF_TYPE_VBI_OUTPUT:
524 if (vfd->vidioc_enum_fmt_vbi_output)
525 ret=vfd->vidioc_enum_fmt_vbi_output(file,
526 fh, f);
527 break;
528 case V4L2_BUF_TYPE_PRIVATE:
529 if (vfd->vidioc_enum_fmt_type_private)
530 ret=vfd->vidioc_enum_fmt_type_private(file,
531 fh, f);
532 break;
534 if (!ret)
535 dbgarg (cmd, "index=%d, type=%d, flags=%d, "
536 "pixelformat=%c%c%c%c, description='%s'\n",
537 f->index, f->type, f->flags,
538 (f->pixelformat & 0xff),
539 (f->pixelformat >> 8) & 0xff,
540 (f->pixelformat >> 16) & 0xff,
541 (f->pixelformat >> 24) & 0xff,
542 f->description);
543 break;
545 case VIDIOC_G_FMT:
547 struct v4l2_format *f = (struct v4l2_format *)arg;
548 enum v4l2_buf_type type=f->type;
550 memset(&f->fmt.pix,0,sizeof(f->fmt.pix));
551 f->type=type;
553 /* FIXME: Should be one dump per type */
554 dbgarg (cmd, "type=%s\n", prt_names(type,
555 v4l2_type_names_FIXME));
557 switch (type) {
558 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
559 if (vfd->vidioc_g_fmt_cap)
560 ret=vfd->vidioc_g_fmt_cap(file, fh, f);
561 if (!ret)
562 v4l_print_pix_fmt(vfd,&f->fmt.pix);
563 break;
564 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
565 if (vfd->vidioc_g_fmt_overlay)
566 ret=vfd->vidioc_g_fmt_overlay(file, fh, f);
567 break;
568 case V4L2_BUF_TYPE_VBI_CAPTURE:
569 if (vfd->vidioc_g_fmt_vbi)
570 ret=vfd->vidioc_g_fmt_vbi(file, fh, f);
571 break;
572 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
573 if (vfd->vidioc_g_fmt_vbi_output)
574 ret=vfd->vidioc_g_fmt_vbi_output(file, fh, f);
575 break;
576 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
577 if (vfd->vidioc_g_fmt_vbi_capture)
578 ret=vfd->vidioc_g_fmt_vbi_capture(file, fh, f);
579 break;
580 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
581 if (vfd->vidioc_g_fmt_video_output)
582 ret=vfd->vidioc_g_fmt_video_output(file,
583 fh, f);
584 break;
585 case V4L2_BUF_TYPE_VBI_OUTPUT:
586 if (vfd->vidioc_g_fmt_vbi_output)
587 ret=vfd->vidioc_g_fmt_vbi_output(file, fh, f);
588 break;
589 case V4L2_BUF_TYPE_PRIVATE:
590 if (vfd->vidioc_g_fmt_type_private)
591 ret=vfd->vidioc_g_fmt_type_private(file,
592 fh, f);
593 break;
596 break;
598 case VIDIOC_S_FMT:
600 struct v4l2_format *f = (struct v4l2_format *)arg;
602 /* FIXME: Should be one dump per type */
603 dbgarg (cmd, "type=%s\n", prt_names(f->type,
604 v4l2_type_names_FIXME));
606 switch (f->type) {
607 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
608 v4l_print_pix_fmt(vfd,&f->fmt.pix);
609 if (vfd->vidioc_s_fmt_cap)
610 ret=vfd->vidioc_s_fmt_cap(file, fh, f);
611 break;
612 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
613 if (vfd->vidioc_s_fmt_overlay)
614 ret=vfd->vidioc_s_fmt_overlay(file, fh, f);
615 break;
616 case V4L2_BUF_TYPE_VBI_CAPTURE:
617 if (vfd->vidioc_s_fmt_vbi)
618 ret=vfd->vidioc_s_fmt_vbi(file, fh, f);
619 break;
620 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
621 if (vfd->vidioc_s_fmt_vbi_output)
622 ret=vfd->vidioc_s_fmt_vbi_output(file, fh, f);
623 break;
624 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
625 if (vfd->vidioc_s_fmt_vbi_capture)
626 ret=vfd->vidioc_s_fmt_vbi_capture(file, fh, f);
627 break;
628 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
629 if (vfd->vidioc_s_fmt_video_output)
630 ret=vfd->vidioc_s_fmt_video_output(file,
631 fh, f);
632 break;
633 case V4L2_BUF_TYPE_VBI_OUTPUT:
634 if (vfd->vidioc_s_fmt_vbi_output)
635 ret=vfd->vidioc_s_fmt_vbi_output(file,
636 fh, f);
637 break;
638 case V4L2_BUF_TYPE_PRIVATE:
639 if (vfd->vidioc_s_fmt_type_private)
640 ret=vfd->vidioc_s_fmt_type_private(file,
641 fh, f);
642 break;
644 break;
646 case VIDIOC_TRY_FMT:
648 struct v4l2_format *f = (struct v4l2_format *)arg;
650 /* FIXME: Should be one dump per type */
651 dbgarg (cmd, "type=%s\n", prt_names(f->type,
652 v4l2_type_names_FIXME));
653 switch (f->type) {
654 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
655 if (vfd->vidioc_try_fmt_cap)
656 ret=vfd->vidioc_try_fmt_cap(file, fh, f);
657 if (!ret)
658 v4l_print_pix_fmt(vfd,&f->fmt.pix);
659 break;
660 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
661 if (vfd->vidioc_try_fmt_overlay)
662 ret=vfd->vidioc_try_fmt_overlay(file, fh, f);
663 break;
664 case V4L2_BUF_TYPE_VBI_CAPTURE:
665 if (vfd->vidioc_try_fmt_vbi)
666 ret=vfd->vidioc_try_fmt_vbi(file, fh, f);
667 break;
668 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
669 if (vfd->vidioc_try_fmt_vbi_output)
670 ret=vfd->vidioc_try_fmt_vbi_output(file,
671 fh, f);
672 break;
673 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
674 if (vfd->vidioc_try_fmt_vbi_capture)
675 ret=vfd->vidioc_try_fmt_vbi_capture(file,
676 fh, f);
677 break;
678 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
679 if (vfd->vidioc_try_fmt_video_output)
680 ret=vfd->vidioc_try_fmt_video_output(file,
681 fh, f);
682 break;
683 case V4L2_BUF_TYPE_VBI_OUTPUT:
684 if (vfd->vidioc_try_fmt_vbi_output)
685 ret=vfd->vidioc_try_fmt_vbi_output(file,
686 fh, f);
687 break;
688 case V4L2_BUF_TYPE_PRIVATE:
689 if (vfd->vidioc_try_fmt_type_private)
690 ret=vfd->vidioc_try_fmt_type_private(file,
691 fh, f);
692 break;
695 break;
697 /* FIXME: Those buf reqs could be handled here,
698 with some changes on videobuf to allow its header to be included at
699 videodev2.h or being merged at videodev2.
701 case VIDIOC_REQBUFS:
703 struct v4l2_requestbuffers *p=arg;
705 if (!vfd->vidioc_reqbufs)
706 break;
707 ret = check_fmt (vfd, p->type);
708 if (ret)
709 break;
711 ret=vfd->vidioc_reqbufs(file, fh, p);
712 dbgarg (cmd, "count=%d, type=%s, memory=%s\n",
713 p->count,
714 prt_names(p->type,v4l2_type_names_FIXME),
715 prt_names(p->memory,v4l2_memory_names));
716 break;
718 case VIDIOC_QUERYBUF:
720 struct v4l2_buffer *p=arg;
722 if (!vfd->vidioc_querybuf)
723 break;
724 ret = check_fmt (vfd, p->type);
725 if (ret)
726 break;
728 ret=vfd->vidioc_querybuf(file, fh, p);
729 if (!ret)
730 dbgbuf(cmd,vfd,p);
731 break;
733 case VIDIOC_QBUF:
735 struct v4l2_buffer *p=arg;
737 if (!vfd->vidioc_qbuf)
738 break;
739 ret = check_fmt (vfd, p->type);
740 if (ret)
741 break;
743 ret=vfd->vidioc_qbuf(file, fh, p);
744 if (!ret)
745 dbgbuf(cmd,vfd,p);
746 break;
748 case VIDIOC_DQBUF:
750 struct v4l2_buffer *p=arg;
751 if (!vfd->vidioc_dqbuf)
752 break;
753 ret = check_fmt (vfd, p->type);
754 if (ret)
755 break;
757 ret=vfd->vidioc_dqbuf(file, fh, p);
758 if (!ret)
759 dbgbuf(cmd,vfd,p);
760 break;
762 case VIDIOC_OVERLAY:
764 int *i = arg;
766 if (!vfd->vidioc_overlay)
767 break;
768 dbgarg (cmd, "value=%d\n",*i);
769 ret=vfd->vidioc_overlay(file, fh, *i);
770 break;
772 #ifdef CONFIG_VIDEO_V4L1_COMPAT
773 /* --- streaming capture ------------------------------------- */
774 case VIDIOCGMBUF:
776 struct video_mbuf *p=arg;
778 memset(p,0,sizeof(p));
780 if (!vfd->vidiocgmbuf)
781 break;
782 ret=vfd->vidiocgmbuf(file, fh, p);
783 if (!ret)
784 dbgarg (cmd, "size=%d, frames=%d, offsets=0x%08lx\n",
785 p->size, p->frames,
786 (unsigned long)p->offsets);
787 break;
789 #endif
790 case VIDIOC_G_FBUF:
792 struct v4l2_framebuffer *p=arg;
793 if (!vfd->vidioc_g_fbuf)
794 break;
795 ret=vfd->vidioc_g_fbuf(file, fh, arg);
796 if (!ret) {
797 dbgarg (cmd, "capability=%d, flags=%d, base=0x%08lx\n",
798 p->capability,p->flags,
799 (unsigned long)p->base);
800 v4l_print_pix_fmt (vfd, &p->fmt);
802 break;
804 case VIDIOC_S_FBUF:
806 struct v4l2_framebuffer *p=arg;
807 if (!vfd->vidioc_s_fbuf)
808 break;
810 dbgarg (cmd, "capability=%d, flags=%d, base=0x%08lx\n",
811 p->capability,p->flags,(unsigned long)p->base);
812 v4l_print_pix_fmt (vfd, &p->fmt);
813 ret=vfd->vidioc_s_fbuf(file, fh, arg);
815 break;
817 case VIDIOC_STREAMON:
819 enum v4l2_buf_type i = *(int *)arg;
820 if (!vfd->vidioc_streamon)
821 break;
822 dbgarg (cmd, "type=%s\n", prt_names(i,v4l2_type_names_FIXME));
823 ret=vfd->vidioc_streamon(file, fh,i);
824 break;
826 case VIDIOC_STREAMOFF:
828 enum v4l2_buf_type i = *(int *)arg;
830 if (!vfd->vidioc_streamoff)
831 break;
832 dbgarg (cmd, "type=%s\n", prt_names(i,v4l2_type_names_FIXME));
833 ret=vfd->vidioc_streamoff(file, fh, i);
834 break;
836 /* ---------- tv norms ---------- */
837 case VIDIOC_ENUMSTD:
839 struct v4l2_standard *p = arg;
840 v4l2_std_id id = vfd->tvnorms,curr_id=0;
841 unsigned int index = p->index,i;
843 if (index<0) {
844 ret=-EINVAL;
845 break;
848 /* Return norm array on a canonical way */
849 for (i=0;i<= index && id; i++) {
850 if ( (id & V4L2_STD_PAL) == V4L2_STD_PAL) {
851 curr_id = V4L2_STD_PAL;
852 } else if ( (id & V4L2_STD_PAL_BG) == V4L2_STD_PAL_BG) {
853 curr_id = V4L2_STD_PAL_BG;
854 } else if ( (id & V4L2_STD_PAL_DK) == V4L2_STD_PAL_DK) {
855 curr_id = V4L2_STD_PAL_DK;
856 } else if ( (id & V4L2_STD_PAL_B) == V4L2_STD_PAL_B) {
857 curr_id = V4L2_STD_PAL_B;
858 } else if ( (id & V4L2_STD_PAL_B1) == V4L2_STD_PAL_B1) {
859 curr_id = V4L2_STD_PAL_B1;
860 } else if ( (id & V4L2_STD_PAL_G) == V4L2_STD_PAL_G) {
861 curr_id = V4L2_STD_PAL_G;
862 } else if ( (id & V4L2_STD_PAL_H) == V4L2_STD_PAL_H) {
863 curr_id = V4L2_STD_PAL_H;
864 } else if ( (id & V4L2_STD_PAL_I) == V4L2_STD_PAL_I) {
865 curr_id = V4L2_STD_PAL_I;
866 } else if ( (id & V4L2_STD_PAL_D) == V4L2_STD_PAL_D) {
867 curr_id = V4L2_STD_PAL_D;
868 } else if ( (id & V4L2_STD_PAL_D1) == V4L2_STD_PAL_D1) {
869 curr_id = V4L2_STD_PAL_D1;
870 } else if ( (id & V4L2_STD_PAL_K) == V4L2_STD_PAL_K) {
871 curr_id = V4L2_STD_PAL_K;
872 } else if ( (id & V4L2_STD_PAL_M) == V4L2_STD_PAL_M) {
873 curr_id = V4L2_STD_PAL_M;
874 } else if ( (id & V4L2_STD_PAL_N) == V4L2_STD_PAL_N) {
875 curr_id = V4L2_STD_PAL_N;
876 } else if ( (id & V4L2_STD_PAL_Nc) == V4L2_STD_PAL_Nc) {
877 curr_id = V4L2_STD_PAL_Nc;
878 } else if ( (id & V4L2_STD_PAL_60) == V4L2_STD_PAL_60) {
879 curr_id = V4L2_STD_PAL_60;
880 } else if ( (id & V4L2_STD_NTSC) == V4L2_STD_NTSC) {
881 curr_id = V4L2_STD_NTSC;
882 } else if ( (id & V4L2_STD_NTSC_M) == V4L2_STD_NTSC_M) {
883 curr_id = V4L2_STD_NTSC_M;
884 } else if ( (id & V4L2_STD_NTSC_M_JP) == V4L2_STD_NTSC_M_JP) {
885 curr_id = V4L2_STD_NTSC_M_JP;
886 } else if ( (id & V4L2_STD_NTSC_443) == V4L2_STD_NTSC_443) {
887 curr_id = V4L2_STD_NTSC_443;
888 } else if ( (id & V4L2_STD_NTSC_M_KR) == V4L2_STD_NTSC_M_KR) {
889 curr_id = V4L2_STD_NTSC_M_KR;
890 } else if ( (id & V4L2_STD_SECAM) == V4L2_STD_SECAM) {
891 curr_id = V4L2_STD_SECAM;
892 } else if ( (id & V4L2_STD_SECAM_DK) == V4L2_STD_SECAM_DK) {
893 curr_id = V4L2_STD_SECAM_DK;
894 } else if ( (id & V4L2_STD_SECAM_B) == V4L2_STD_SECAM_B) {
895 curr_id = V4L2_STD_SECAM_B;
896 } else if ( (id & V4L2_STD_SECAM_D) == V4L2_STD_SECAM_D) {
897 curr_id = V4L2_STD_SECAM_D;
898 } else if ( (id & V4L2_STD_SECAM_G) == V4L2_STD_SECAM_G) {
899 curr_id = V4L2_STD_SECAM_G;
900 } else if ( (id & V4L2_STD_SECAM_H) == V4L2_STD_SECAM_H) {
901 curr_id = V4L2_STD_SECAM_H;
902 } else if ( (id & V4L2_STD_SECAM_K) == V4L2_STD_SECAM_K) {
903 curr_id = V4L2_STD_SECAM_K;
904 } else if ( (id & V4L2_STD_SECAM_K1) == V4L2_STD_SECAM_K1) {
905 curr_id = V4L2_STD_SECAM_K1;
906 } else if ( (id & V4L2_STD_SECAM_L) == V4L2_STD_SECAM_L) {
907 curr_id = V4L2_STD_SECAM_L;
908 } else if ( (id & V4L2_STD_SECAM_LC) == V4L2_STD_SECAM_LC) {
909 curr_id = V4L2_STD_SECAM_LC;
910 } else {
911 break;
913 id &= ~curr_id;
915 if (i<=index)
916 return -EINVAL;
918 v4l2_video_std_construct(p, curr_id,v4l2_norm_to_name(curr_id));
919 p->index = index;
921 dbgarg (cmd, "index=%d, id=%Ld, name=%s, fps=%d/%d, "
922 "framelines=%d\n", p->index,
923 (unsigned long long)p->id, p->name,
924 p->frameperiod.numerator,
925 p->frameperiod.denominator,
926 p->framelines);
928 ret=0;
929 break;
931 case VIDIOC_G_STD:
933 v4l2_std_id *id = arg;
935 *id = vfd->current_norm;
937 dbgarg (cmd, "value=%Lu\n", (long long unsigned) *id);
939 ret=0;
940 break;
942 case VIDIOC_S_STD:
944 v4l2_std_id *id = arg,norm;
946 dbgarg (cmd, "value=%Lu\n", (long long unsigned) *id);
948 norm = (*id) & vfd->tvnorms;
949 if ( vfd->tvnorms && !norm) /* Check if std is supported */
950 break;
952 /* Calls the specific handler */
953 if (vfd->vidioc_s_std)
954 ret=vfd->vidioc_s_std(file, fh, &norm);
955 else
956 ret=-EINVAL;
958 /* Updates standard information */
959 if (ret>=0)
960 vfd->current_norm=norm;
962 break;
964 case VIDIOC_QUERYSTD:
966 v4l2_std_id *p=arg;
968 if (!vfd->vidioc_querystd)
969 break;
970 ret=vfd->vidioc_querystd(file, fh, arg);
971 if (!ret)
972 dbgarg (cmd, "detected std=%Lu\n",
973 (unsigned long long)*p);
974 break;
976 /* ------ input switching ---------- */
977 /* FIXME: Inputs can be handled inside videodev2 */
978 case VIDIOC_ENUMINPUT:
980 struct v4l2_input *p=arg;
981 int i=p->index;
983 if (!vfd->vidioc_enum_input)
984 break;
985 memset(p, 0, sizeof(*p));
986 p->index=i;
988 ret=vfd->vidioc_enum_input(file, fh, p);
989 if (!ret)
990 dbgarg (cmd, "index=%d, name=%s, type=%d, "
991 "audioset=%d, "
992 "tuner=%d, std=%Ld, status=%d\n",
993 p->index,p->name,p->type,p->audioset,
994 p->tuner,
995 (unsigned long long)p->std,
996 p->status);
997 break;
999 case VIDIOC_G_INPUT:
1001 unsigned int *i = arg;
1003 if (!vfd->vidioc_g_input)
1004 break;
1005 ret=vfd->vidioc_g_input(file, fh, i);
1006 if (!ret)
1007 dbgarg (cmd, "value=%d\n",*i);
1008 break;
1010 case VIDIOC_S_INPUT:
1012 unsigned int *i = arg;
1014 if (!vfd->vidioc_s_input)
1015 break;
1016 dbgarg (cmd, "value=%d\n",*i);
1017 ret=vfd->vidioc_s_input(file, fh, *i);
1018 break;
1021 /* ------ output switching ---------- */
1022 case VIDIOC_G_OUTPUT:
1024 unsigned int *i = arg;
1026 if (!vfd->vidioc_g_output)
1027 break;
1028 ret=vfd->vidioc_g_output(file, fh, i);
1029 if (!ret)
1030 dbgarg (cmd, "value=%d\n",*i);
1031 break;
1033 case VIDIOC_S_OUTPUT:
1035 unsigned int *i = arg;
1037 if (!vfd->vidioc_s_output)
1038 break;
1039 dbgarg (cmd, "value=%d\n",*i);
1040 ret=vfd->vidioc_s_output(file, fh, *i);
1041 break;
1044 /* --- controls ---------------------------------------------- */
1045 case VIDIOC_QUERYCTRL:
1047 struct v4l2_queryctrl *p=arg;
1049 if (!vfd->vidioc_queryctrl)
1050 break;
1051 ret=vfd->vidioc_queryctrl(file, fh, p);
1053 if (!ret)
1054 dbgarg (cmd, "id=%d, type=%d, name=%s, "
1055 "min/max=%d/%d,"
1056 " step=%d, default=%d, flags=0x%08x\n",
1057 p->id,p->type,p->name,p->minimum,
1058 p->maximum,p->step,p->default_value,
1059 p->flags);
1060 break;
1062 case VIDIOC_G_CTRL:
1064 struct v4l2_control *p = arg;
1066 if (!vfd->vidioc_g_ctrl)
1067 break;
1068 dbgarg(cmd, "Enum for index=%d\n", p->id);
1070 ret=vfd->vidioc_g_ctrl(file, fh, p);
1071 if (!ret)
1072 dbgarg2 ( "id=%d, value=%d\n", p->id, p->value);
1073 break;
1075 case VIDIOC_S_CTRL:
1077 struct v4l2_control *p = arg;
1079 if (!vfd->vidioc_s_ctrl)
1080 break;
1081 dbgarg (cmd, "id=%d, value=%d\n", p->id, p->value);
1083 ret=vfd->vidioc_s_ctrl(file, fh, p);
1084 break;
1086 case VIDIOC_G_EXT_CTRLS:
1088 struct v4l2_ext_controls *p = arg;
1090 if (vfd->vidioc_g_ext_ctrls) {
1091 dbgarg(cmd, "count=%d\n", p->count);
1093 ret=vfd->vidioc_g_ext_ctrls(file, fh, p);
1095 break;
1097 case VIDIOC_S_EXT_CTRLS:
1099 struct v4l2_ext_controls *p = arg;
1101 if (vfd->vidioc_s_ext_ctrls) {
1102 dbgarg(cmd, "count=%d\n", p->count);
1104 ret=vfd->vidioc_s_ext_ctrls(file, fh, p);
1106 break;
1108 case VIDIOC_TRY_EXT_CTRLS:
1110 struct v4l2_ext_controls *p = arg;
1112 if (vfd->vidioc_try_ext_ctrls) {
1113 dbgarg(cmd, "count=%d\n", p->count);
1115 ret=vfd->vidioc_try_ext_ctrls(file, fh, p);
1117 break;
1119 case VIDIOC_QUERYMENU:
1121 struct v4l2_querymenu *p=arg;
1122 if (!vfd->vidioc_querymenu)
1123 break;
1124 ret=vfd->vidioc_querymenu(file, fh, p);
1125 if (!ret)
1126 dbgarg (cmd, "id=%d, index=%d, name=%s\n",
1127 p->id,p->index,p->name);
1128 break;
1130 /* --- audio ---------------------------------------------- */
1131 case VIDIOC_ENUMAUDIO:
1133 struct v4l2_audio *p=arg;
1135 if (!vfd->vidioc_enumaudio)
1136 break;
1137 dbgarg(cmd, "Enum for index=%d\n", p->index);
1138 ret=vfd->vidioc_enumaudio(file, fh, p);
1139 if (!ret)
1140 dbgarg2("index=%d, name=%s, capability=%d, "
1141 "mode=%d\n",p->index,p->name,
1142 p->capability, p->mode);
1143 break;
1145 case VIDIOC_G_AUDIO:
1147 struct v4l2_audio *p=arg;
1148 __u32 index=p->index;
1150 if (!vfd->vidioc_g_audio)
1151 break;
1153 memset(p,0,sizeof(*p));
1154 p->index=index;
1155 dbgarg(cmd, "Get for index=%d\n", p->index);
1156 ret=vfd->vidioc_g_audio(file, fh, p);
1157 if (!ret)
1158 dbgarg2("index=%d, name=%s, capability=%d, "
1159 "mode=%d\n",p->index,
1160 p->name,p->capability, p->mode);
1161 break;
1163 case VIDIOC_S_AUDIO:
1165 struct v4l2_audio *p=arg;
1167 if (!vfd->vidioc_s_audio)
1168 break;
1169 dbgarg(cmd, "index=%d, name=%s, capability=%d, "
1170 "mode=%d\n", p->index, p->name,
1171 p->capability, p->mode);
1172 ret=vfd->vidioc_s_audio(file, fh, p);
1173 break;
1175 case VIDIOC_ENUMAUDOUT:
1177 struct v4l2_audioout *p=arg;
1179 if (!vfd->vidioc_enumaudout)
1180 break;
1181 dbgarg(cmd, "Enum for index=%d\n", p->index);
1182 ret=vfd->vidioc_enumaudout(file, fh, p);
1183 if (!ret)
1184 dbgarg2("index=%d, name=%s, capability=%d, "
1185 "mode=%d\n", p->index, p->name,
1186 p->capability,p->mode);
1187 break;
1189 case VIDIOC_G_AUDOUT:
1191 struct v4l2_audioout *p=arg;
1193 if (!vfd->vidioc_g_audout)
1194 break;
1195 dbgarg(cmd, "Enum for index=%d\n", p->index);
1196 ret=vfd->vidioc_g_audout(file, fh, p);
1197 if (!ret)
1198 dbgarg2("index=%d, name=%s, capability=%d, "
1199 "mode=%d\n", p->index, p->name,
1200 p->capability,p->mode);
1201 break;
1203 case VIDIOC_S_AUDOUT:
1205 struct v4l2_audioout *p=arg;
1207 if (!vfd->vidioc_s_audout)
1208 break;
1209 dbgarg(cmd, "index=%d, name=%s, capability=%d, "
1210 "mode=%d\n", p->index, p->name,
1211 p->capability,p->mode);
1213 ret=vfd->vidioc_s_audout(file, fh, p);
1214 break;
1216 case VIDIOC_G_MODULATOR:
1218 struct v4l2_modulator *p=arg;
1219 if (!vfd->vidioc_g_modulator)
1220 break;
1221 ret=vfd->vidioc_g_modulator(file, fh, p);
1222 if (!ret)
1223 dbgarg(cmd, "index=%d, name=%s, "
1224 "capability=%d, rangelow=%d,"
1225 " rangehigh=%d, txsubchans=%d\n",
1226 p->index, p->name,p->capability,
1227 p->rangelow, p->rangehigh,
1228 p->txsubchans);
1229 break;
1231 case VIDIOC_S_MODULATOR:
1233 struct v4l2_modulator *p=arg;
1234 if (!vfd->vidioc_s_modulator)
1235 break;
1236 dbgarg(cmd, "index=%d, name=%s, capability=%d, "
1237 "rangelow=%d, rangehigh=%d, txsubchans=%d\n",
1238 p->index, p->name,p->capability,p->rangelow,
1239 p->rangehigh,p->txsubchans);
1240 ret=vfd->vidioc_s_modulator(file, fh, p);
1241 break;
1243 case VIDIOC_G_CROP:
1245 struct v4l2_crop *p=arg;
1246 if (!vfd->vidioc_g_crop)
1247 break;
1248 ret=vfd->vidioc_g_crop(file, fh, p);
1249 if (!ret) {
1250 dbgarg(cmd, "type=%d\n", p->type);
1251 dbgrect(vfd, "", &p->c);
1253 break;
1255 case VIDIOC_S_CROP:
1257 struct v4l2_crop *p=arg;
1258 if (!vfd->vidioc_s_crop)
1259 break;
1260 dbgarg(cmd, "type=%d\n", p->type);
1261 dbgrect(vfd, "", &p->c);
1262 ret=vfd->vidioc_s_crop(file, fh, p);
1263 break;
1265 case VIDIOC_CROPCAP:
1267 struct v4l2_cropcap *p=arg;
1268 /*FIXME: Should also show v4l2_fract pixelaspect */
1269 if (!vfd->vidioc_cropcap)
1270 break;
1271 dbgarg(cmd, "type=%d\n", p->type);
1272 dbgrect(vfd, "bounds ", &p->bounds);
1273 dbgrect(vfd, "defrect ", &p->defrect);
1274 ret=vfd->vidioc_cropcap(file, fh, p);
1275 break;
1277 case VIDIOC_G_MPEGCOMP:
1279 struct v4l2_mpeg_compression *p=arg;
1281 /*FIXME: Several fields not shown */
1282 if (!vfd->vidioc_g_mpegcomp)
1283 break;
1284 ret=vfd->vidioc_g_mpegcomp(file, fh, p);
1285 if (!ret)
1286 dbgarg (cmd, "ts_pid_pmt=%d, ts_pid_audio=%d,"
1287 " ts_pid_video=%d, ts_pid_pcr=%d, "
1288 "ps_size=%d, au_sample_rate=%d, "
1289 "au_pesid=%c, vi_frame_rate=%d, "
1290 "vi_frames_per_gop=%d, "
1291 "vi_bframes_count=%d, vi_pesid=%c\n",
1292 p->ts_pid_pmt,p->ts_pid_audio,
1293 p->ts_pid_video,p->ts_pid_pcr,
1294 p->ps_size, p->au_sample_rate,
1295 p->au_pesid, p->vi_frame_rate,
1296 p->vi_frames_per_gop,
1297 p->vi_bframes_count, p->vi_pesid);
1298 break;
1300 case VIDIOC_S_MPEGCOMP:
1302 struct v4l2_mpeg_compression *p=arg;
1303 /*FIXME: Several fields not shown */
1304 if (!vfd->vidioc_s_mpegcomp)
1305 break;
1306 dbgarg (cmd, "ts_pid_pmt=%d, ts_pid_audio=%d, "
1307 "ts_pid_video=%d, ts_pid_pcr=%d, ps_size=%d, "
1308 "au_sample_rate=%d, au_pesid=%c, "
1309 "vi_frame_rate=%d, vi_frames_per_gop=%d, "
1310 "vi_bframes_count=%d, vi_pesid=%c\n",
1311 p->ts_pid_pmt,p->ts_pid_audio, p->ts_pid_video,
1312 p->ts_pid_pcr, p->ps_size, p->au_sample_rate,
1313 p->au_pesid, p->vi_frame_rate,
1314 p->vi_frames_per_gop, p->vi_bframes_count,
1315 p->vi_pesid);
1316 ret=vfd->vidioc_s_mpegcomp(file, fh, p);
1317 break;
1319 case VIDIOC_G_JPEGCOMP:
1321 struct v4l2_jpegcompression *p=arg;
1322 if (!vfd->vidioc_g_jpegcomp)
1323 break;
1324 ret=vfd->vidioc_g_jpegcomp(file, fh, p);
1325 if (!ret)
1326 dbgarg (cmd, "quality=%d, APPn=%d, "
1327 "APP_len=%d, COM_len=%d, "
1328 "jpeg_markers=%d\n",
1329 p->quality,p->APPn,p->APP_len,
1330 p->COM_len,p->jpeg_markers);
1331 break;
1333 case VIDIOC_S_JPEGCOMP:
1335 struct v4l2_jpegcompression *p=arg;
1336 if (!vfd->vidioc_g_jpegcomp)
1337 break;
1338 dbgarg (cmd, "quality=%d, APPn=%d, APP_len=%d, "
1339 "COM_len=%d, jpeg_markers=%d\n",
1340 p->quality,p->APPn,p->APP_len,
1341 p->COM_len,p->jpeg_markers);
1342 ret=vfd->vidioc_s_jpegcomp(file, fh, p);
1343 break;
1345 case VIDIOC_G_PARM:
1347 struct v4l2_streamparm *p=arg;
1348 if (vfd->vidioc_g_parm) {
1349 ret=vfd->vidioc_g_parm(file, fh, p);
1350 } else {
1351 struct v4l2_standard s;
1353 if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1354 return -EINVAL;
1356 v4l2_video_std_construct(&s, vfd->current_norm,
1357 v4l2_norm_to_name(vfd->current_norm));
1359 memset(p,0,sizeof(*p));
1361 p->parm.capture.timeperframe = s.frameperiod;
1362 ret=0;
1365 dbgarg (cmd, "type=%d\n", p->type);
1366 break;
1368 case VIDIOC_S_PARM:
1370 struct v4l2_streamparm *p=arg;
1371 if (!vfd->vidioc_s_parm)
1372 break;
1373 dbgarg (cmd, "type=%d\n", p->type);
1374 ret=vfd->vidioc_s_parm(file, fh, p);
1375 break;
1377 case VIDIOC_G_TUNER:
1379 struct v4l2_tuner *p=arg;
1380 __u32 index=p->index;
1382 if (!vfd->vidioc_g_tuner)
1383 break;
1385 memset(p,0,sizeof(*p));
1386 p->index=index;
1388 ret=vfd->vidioc_g_tuner(file, fh, p);
1389 if (!ret)
1390 dbgarg (cmd, "index=%d, name=%s, type=%d, "
1391 "capability=%d, rangelow=%d, "
1392 "rangehigh=%d, signal=%d, afc=%d, "
1393 "rxsubchans=%d, audmode=%d\n",
1394 p->index, p->name, p->type,
1395 p->capability, p->rangelow,
1396 p->rangehigh, p->rxsubchans,
1397 p->audmode, p->signal, p->afc);
1398 break;
1400 case VIDIOC_S_TUNER:
1402 struct v4l2_tuner *p=arg;
1403 if (!vfd->vidioc_s_tuner)
1404 break;
1405 dbgarg (cmd, "index=%d, name=%s, type=%d, "
1406 "capability=%d, rangelow=%d, rangehigh=%d, "
1407 "signal=%d, afc=%d, rxsubchans=%d, "
1408 "audmode=%d\n",p->index, p->name, p->type,
1409 p->capability, p->rangelow,p->rangehigh,
1410 p->rxsubchans, p->audmode, p->signal,
1411 p->afc);
1412 ret=vfd->vidioc_s_tuner(file, fh, p);
1413 break;
1415 case VIDIOC_G_FREQUENCY:
1417 struct v4l2_frequency *p=arg;
1418 if (!vfd->vidioc_g_frequency)
1419 break;
1421 memset(p,0,sizeof(*p));
1423 ret=vfd->vidioc_g_frequency(file, fh, p);
1424 if (!ret)
1425 dbgarg (cmd, "tuner=%d, type=%d, frequency=%d\n",
1426 p->tuner,p->type,p->frequency);
1427 break;
1429 case VIDIOC_S_FREQUENCY:
1431 struct v4l2_frequency *p=arg;
1432 if (!vfd->vidioc_s_frequency)
1433 break;
1434 dbgarg (cmd, "tuner=%d, type=%d, frequency=%d\n",
1435 p->tuner,p->type,p->frequency);
1436 ret=vfd->vidioc_s_frequency(file, fh, p);
1437 break;
1439 case VIDIOC_G_SLICED_VBI_CAP:
1441 struct v4l2_sliced_vbi_cap *p=arg;
1442 if (!vfd->vidioc_g_sliced_vbi_cap)
1443 break;
1444 ret=vfd->vidioc_g_sliced_vbi_cap(file, fh, p);
1445 if (!ret)
1446 dbgarg (cmd, "service_set=%d\n", p->service_set);
1447 break;
1449 case VIDIOC_LOG_STATUS:
1451 if (!vfd->vidioc_log_status)
1452 break;
1453 ret=vfd->vidioc_log_status(file, fh);
1454 break;
1456 } /* switch */
1458 if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) {
1459 if (ret<0) {
1460 printk ("%s: err:\n", vfd->name);
1461 v4l_print_ioctl(vfd->name, cmd);
1465 return ret;
1468 int video_ioctl2 (struct inode *inode, struct file *file,
1469 unsigned int cmd, unsigned long arg)
1471 char sbuf[128];
1472 void *mbuf = NULL;
1473 void *parg = NULL;
1474 int err = -EINVAL;
1475 int is_ext_ctrl;
1476 size_t ctrls_size = 0;
1477 void __user *user_ptr = NULL;
1479 #ifdef __OLD_VIDIOC_
1480 cmd = video_fix_command(cmd);
1481 #endif
1482 is_ext_ctrl = (cmd == VIDIOC_S_EXT_CTRLS || cmd == VIDIOC_G_EXT_CTRLS ||
1483 cmd == VIDIOC_TRY_EXT_CTRLS);
1485 /* Copy arguments into temp kernel buffer */
1486 switch (_IOC_DIR(cmd)) {
1487 case _IOC_NONE:
1488 parg = NULL;
1489 break;
1490 case _IOC_READ:
1491 case _IOC_WRITE:
1492 case (_IOC_WRITE | _IOC_READ):
1493 if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
1494 parg = sbuf;
1495 } else {
1496 /* too big to allocate from stack */
1497 mbuf = kmalloc(_IOC_SIZE(cmd),GFP_KERNEL);
1498 if (NULL == mbuf)
1499 return -ENOMEM;
1500 parg = mbuf;
1503 err = -EFAULT;
1504 if (_IOC_DIR(cmd) & _IOC_WRITE)
1505 if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd)))
1506 goto out;
1507 break;
1510 if (is_ext_ctrl) {
1511 struct v4l2_ext_controls *p = parg;
1513 /* In case of an error, tell the caller that it wasn't
1514 a specific control that caused it. */
1515 p->error_idx = p->count;
1516 user_ptr = (void __user *)p->controls;
1517 if (p->count) {
1518 ctrls_size = sizeof(struct v4l2_ext_control) * p->count;
1519 /* Note: v4l2_ext_controls fits in sbuf[] so mbuf is still NULL. */
1520 mbuf = kmalloc(ctrls_size, GFP_KERNEL);
1521 err = -ENOMEM;
1522 if (NULL == mbuf)
1523 goto out_ext_ctrl;
1524 err = -EFAULT;
1525 if (copy_from_user(mbuf, user_ptr, ctrls_size))
1526 goto out_ext_ctrl;
1527 p->controls = mbuf;
1531 /* Handles IOCTL */
1532 err = __video_do_ioctl(inode, file, cmd, parg);
1533 if (err == -ENOIOCTLCMD)
1534 err = -EINVAL;
1535 if (is_ext_ctrl) {
1536 struct v4l2_ext_controls *p = parg;
1538 p->controls = (void *)user_ptr;
1539 if (p->count && err == 0 && copy_to_user(user_ptr, mbuf, ctrls_size))
1540 err = -EFAULT;
1541 goto out_ext_ctrl;
1543 if (err < 0)
1544 goto out;
1546 out_ext_ctrl:
1547 /* Copy results into user buffer */
1548 switch (_IOC_DIR(cmd))
1550 case _IOC_READ:
1551 case (_IOC_WRITE | _IOC_READ):
1552 if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd)))
1553 err = -EFAULT;
1554 break;
1557 out:
1558 kfree(mbuf);
1559 return err;
1563 static const struct file_operations video_fops;
1566 * video_register_device - register video4linux devices
1567 * @vfd: video device structure we want to register
1568 * @type: type of device to register
1569 * @nr: which device number (0 == /dev/video0, 1 == /dev/video1, ...
1570 * -1 == first free)
1572 * The registration code assigns minor numbers based on the type
1573 * requested. -ENFILE is returned in all the device slots for this
1574 * category are full. If not then the minor field is set and the
1575 * driver initialize function is called (if non %NULL).
1577 * Zero is returned on success.
1579 * Valid types are
1581 * %VFL_TYPE_GRABBER - A frame grabber
1583 * %VFL_TYPE_VTX - A teletext device
1585 * %VFL_TYPE_VBI - Vertical blank data (undecoded)
1587 * %VFL_TYPE_RADIO - A radio card
1590 int video_register_device(struct video_device *vfd, int type, int nr)
1592 int i=0;
1593 int base;
1594 int end;
1595 int ret;
1596 char *name_base;
1598 switch(type)
1600 case VFL_TYPE_GRABBER:
1601 base=MINOR_VFL_TYPE_GRABBER_MIN;
1602 end=MINOR_VFL_TYPE_GRABBER_MAX+1;
1603 name_base = "video";
1604 break;
1605 case VFL_TYPE_VTX:
1606 base=MINOR_VFL_TYPE_VTX_MIN;
1607 end=MINOR_VFL_TYPE_VTX_MAX+1;
1608 name_base = "vtx";
1609 break;
1610 case VFL_TYPE_VBI:
1611 base=MINOR_VFL_TYPE_VBI_MIN;
1612 end=MINOR_VFL_TYPE_VBI_MAX+1;
1613 name_base = "vbi";
1614 break;
1615 case VFL_TYPE_RADIO:
1616 base=MINOR_VFL_TYPE_RADIO_MIN;
1617 end=MINOR_VFL_TYPE_RADIO_MAX+1;
1618 name_base = "radio";
1619 break;
1620 default:
1621 printk(KERN_ERR "%s called with unknown type: %d\n",
1622 __FUNCTION__, type);
1623 return -1;
1626 /* pick a minor number */
1627 mutex_lock(&videodev_lock);
1628 if (nr >= 0 && nr < end-base) {
1629 /* use the one the driver asked for */
1630 i = base+nr;
1631 if (NULL != video_device[i]) {
1632 mutex_unlock(&videodev_lock);
1633 return -ENFILE;
1635 } else {
1636 /* use first free */
1637 for(i=base;i<end;i++)
1638 if (NULL == video_device[i])
1639 break;
1640 if (i == end) {
1641 mutex_unlock(&videodev_lock);
1642 return -ENFILE;
1645 video_device[i]=vfd;
1646 vfd->minor=i;
1647 mutex_unlock(&videodev_lock);
1648 mutex_init(&vfd->lock);
1650 /* sysfs class */
1651 memset(&vfd->class_dev, 0x00, sizeof(vfd->class_dev));
1652 if (vfd->dev)
1653 vfd->class_dev.dev = vfd->dev;
1654 vfd->class_dev.class = &video_class;
1655 vfd->class_dev.devt = MKDEV(VIDEO_MAJOR, vfd->minor);
1656 sprintf(vfd->class_dev.class_id, "%s%d", name_base, i - base);
1657 ret = class_device_register(&vfd->class_dev);
1658 if (ret < 0) {
1659 printk(KERN_ERR "%s: class_device_register failed\n",
1660 __FUNCTION__);
1661 goto fail_minor;
1663 ret = class_device_create_file(&vfd->class_dev, &class_device_attr_name);
1664 if (ret < 0) {
1665 printk(KERN_ERR "%s: class_device_create_file 'name' failed\n",
1666 __FUNCTION__);
1667 goto fail_classdev;
1670 #if 1
1671 /* needed until all drivers are fixed */
1672 if (!vfd->release)
1673 printk(KERN_WARNING "videodev: \"%s\" has no release callback. "
1674 "Please fix your driver for proper sysfs support, see "
1675 "http://lwn.net/Articles/36850/\n", vfd->name);
1676 #endif
1677 return 0;
1679 fail_classdev:
1680 class_device_unregister(&vfd->class_dev);
1681 fail_minor:
1682 mutex_lock(&videodev_lock);
1683 video_device[vfd->minor] = NULL;
1684 vfd->minor = -1;
1685 mutex_unlock(&videodev_lock);
1686 return ret;
1690 * video_unregister_device - unregister a video4linux device
1691 * @vfd: the device to unregister
1693 * This unregisters the passed device and deassigns the minor
1694 * number. Future open calls will be met with errors.
1697 void video_unregister_device(struct video_device *vfd)
1699 mutex_lock(&videodev_lock);
1700 if(video_device[vfd->minor]!=vfd)
1701 panic("videodev: bad unregister");
1703 video_device[vfd->minor]=NULL;
1704 class_device_unregister(&vfd->class_dev);
1705 mutex_unlock(&videodev_lock);
1709 * Video fs operations
1711 static const struct file_operations video_fops=
1713 .owner = THIS_MODULE,
1714 .llseek = no_llseek,
1715 .open = video_open,
1719 * Initialise video for linux
1722 static int __init videodev_init(void)
1724 int ret;
1726 printk(KERN_INFO "Linux video capture interface: v2.00\n");
1727 if (register_chrdev(VIDEO_MAJOR, VIDEO_NAME, &video_fops)) {
1728 printk(KERN_WARNING "video_dev: unable to get major %d\n", VIDEO_MAJOR);
1729 return -EIO;
1732 ret = class_register(&video_class);
1733 if (ret < 0) {
1734 unregister_chrdev(VIDEO_MAJOR, VIDEO_NAME);
1735 printk(KERN_WARNING "video_dev: class_register failed\n");
1736 return -EIO;
1739 return 0;
1742 static void __exit videodev_exit(void)
1744 class_unregister(&video_class);
1745 unregister_chrdev(VIDEO_MAJOR, VIDEO_NAME);
1748 module_init(videodev_init)
1749 module_exit(videodev_exit)
1751 EXPORT_SYMBOL(video_register_device);
1752 EXPORT_SYMBOL(video_unregister_device);
1753 EXPORT_SYMBOL(video_devdata);
1754 EXPORT_SYMBOL(video_usercopy);
1755 EXPORT_SYMBOL(video_exclusive_open);
1756 EXPORT_SYMBOL(video_exclusive_release);
1757 EXPORT_SYMBOL(video_ioctl2);
1758 EXPORT_SYMBOL(video_device_alloc);
1759 EXPORT_SYMBOL(video_device_release);
1761 MODULE_AUTHOR("Alan Cox, Mauro Carvalho Chehab <mchehab@infradead.org>");
1762 MODULE_DESCRIPTION("Device registrar for Video4Linux drivers v2");
1763 MODULE_LICENSE("GPL");
1767 * Local variables:
1768 * c-basic-offset: 8
1769 * End: