[IPSEC]: Ensure that state inner family is set
[firewire-audio.git] / drivers / media / video / videodev.c
blobb876aca69c73673fadb42f5e9388488d030c3eb4
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 class_device *cd, char *buf)
59 struct video_device *vfd = container_of(cd, struct video_device,
60 class_dev);
61 return sprintf(buf,"%.*s\n",(int)sizeof(vfd->name),vfd->name);
64 static CLASS_DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
66 struct video_device *video_device_alloc(void)
68 struct video_device *vfd;
70 vfd = kzalloc(sizeof(*vfd),GFP_KERNEL);
71 return vfd;
74 void video_device_release(struct video_device *vfd)
76 kfree(vfd);
79 static void video_release(struct class_device *cd)
81 struct video_device *vfd = container_of(cd, struct video_device,
82 class_dev);
84 #if 1
85 /* needed until all drivers are fixed */
86 if (!vfd->release)
87 return;
88 #endif
89 vfd->release(vfd);
92 static struct class video_class = {
93 .name = VIDEO_NAME,
94 .release = video_release,
98 * Active devices
101 static struct video_device *video_device[VIDEO_NUM_DEVICES];
102 static DEFINE_MUTEX(videodev_lock);
104 struct video_device* video_devdata(struct file *file)
106 return video_device[iminor(file->f_path.dentry->d_inode)];
110 * Open a video device - FIXME: Obsoleted
112 static int video_open(struct inode *inode, struct file *file)
114 unsigned int minor = iminor(inode);
115 int err = 0;
116 struct video_device *vfl;
117 const struct file_operations *old_fops;
119 if(minor>=VIDEO_NUM_DEVICES)
120 return -ENODEV;
121 mutex_lock(&videodev_lock);
122 vfl=video_device[minor];
123 if(vfl==NULL) {
124 mutex_unlock(&videodev_lock);
125 request_module("char-major-%d-%d", VIDEO_MAJOR, minor);
126 mutex_lock(&videodev_lock);
127 vfl=video_device[minor];
128 if (vfl==NULL) {
129 mutex_unlock(&videodev_lock);
130 return -ENODEV;
133 old_fops = file->f_op;
134 file->f_op = fops_get(vfl->fops);
135 if(file->f_op->open)
136 err = file->f_op->open(inode,file);
137 if (err) {
138 fops_put(file->f_op);
139 file->f_op = fops_get(old_fops);
141 fops_put(old_fops);
142 mutex_unlock(&videodev_lock);
143 return err;
147 * helper function -- handles userspace copying for ioctl arguments
150 #ifdef __OLD_VIDIOC_
151 static unsigned int
152 video_fix_command(unsigned int cmd)
154 switch (cmd) {
155 case VIDIOC_OVERLAY_OLD:
156 cmd = VIDIOC_OVERLAY;
157 break;
158 case VIDIOC_S_PARM_OLD:
159 cmd = VIDIOC_S_PARM;
160 break;
161 case VIDIOC_S_CTRL_OLD:
162 cmd = VIDIOC_S_CTRL;
163 break;
164 case VIDIOC_G_AUDIO_OLD:
165 cmd = VIDIOC_G_AUDIO;
166 break;
167 case VIDIOC_G_AUDOUT_OLD:
168 cmd = VIDIOC_G_AUDOUT;
169 break;
170 case VIDIOC_CROPCAP_OLD:
171 cmd = VIDIOC_CROPCAP;
172 break;
174 return cmd;
176 #endif
179 * Obsolete usercopy function - Should be removed soon
182 video_usercopy(struct inode *inode, struct file *file,
183 unsigned int cmd, unsigned long arg,
184 int (*func)(struct inode *inode, struct file *file,
185 unsigned int cmd, void *arg))
187 char sbuf[128];
188 void *mbuf = NULL;
189 void *parg = NULL;
190 int err = -EINVAL;
191 int is_ext_ctrl;
192 size_t ctrls_size = 0;
193 void __user *user_ptr = NULL;
195 #ifdef __OLD_VIDIOC_
196 cmd = video_fix_command(cmd);
197 #endif
198 is_ext_ctrl = (cmd == VIDIOC_S_EXT_CTRLS || cmd == VIDIOC_G_EXT_CTRLS ||
199 cmd == VIDIOC_TRY_EXT_CTRLS);
201 /* Copy arguments into temp kernel buffer */
202 switch (_IOC_DIR(cmd)) {
203 case _IOC_NONE:
204 parg = NULL;
205 break;
206 case _IOC_READ:
207 case _IOC_WRITE:
208 case (_IOC_WRITE | _IOC_READ):
209 if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
210 parg = sbuf;
211 } else {
212 /* too big to allocate from stack */
213 mbuf = kmalloc(_IOC_SIZE(cmd),GFP_KERNEL);
214 if (NULL == mbuf)
215 return -ENOMEM;
216 parg = mbuf;
219 err = -EFAULT;
220 if (_IOC_DIR(cmd) & _IOC_WRITE)
221 if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd)))
222 goto out;
223 break;
225 if (is_ext_ctrl) {
226 struct v4l2_ext_controls *p = parg;
228 /* In case of an error, tell the caller that it wasn't
229 a specific control that caused it. */
230 p->error_idx = p->count;
231 user_ptr = (void __user *)p->controls;
232 if (p->count) {
233 ctrls_size = sizeof(struct v4l2_ext_control) * p->count;
234 /* Note: v4l2_ext_controls fits in sbuf[] so mbuf is still NULL. */
235 mbuf = kmalloc(ctrls_size, GFP_KERNEL);
236 err = -ENOMEM;
237 if (NULL == mbuf)
238 goto out_ext_ctrl;
239 err = -EFAULT;
240 if (copy_from_user(mbuf, user_ptr, ctrls_size))
241 goto out_ext_ctrl;
242 p->controls = mbuf;
246 /* call driver */
247 err = func(inode, file, cmd, parg);
248 if (err == -ENOIOCTLCMD)
249 err = -EINVAL;
250 if (is_ext_ctrl) {
251 struct v4l2_ext_controls *p = parg;
253 p->controls = (void *)user_ptr;
254 if (p->count && err == 0 && copy_to_user(user_ptr, mbuf, ctrls_size))
255 err = -EFAULT;
256 goto out_ext_ctrl;
258 if (err < 0)
259 goto out;
261 out_ext_ctrl:
262 /* Copy results into user buffer */
263 switch (_IOC_DIR(cmd))
265 case _IOC_READ:
266 case (_IOC_WRITE | _IOC_READ):
267 if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd)))
268 err = -EFAULT;
269 break;
272 out:
273 kfree(mbuf);
274 return err;
278 * open/release helper functions -- handle exclusive opens
279 * Should be removed soon
281 int video_exclusive_open(struct inode *inode, struct file *file)
283 struct video_device *vfl = video_devdata(file);
284 int retval = 0;
286 mutex_lock(&vfl->lock);
287 if (vfl->users) {
288 retval = -EBUSY;
289 } else {
290 vfl->users++;
292 mutex_unlock(&vfl->lock);
293 return retval;
296 int video_exclusive_release(struct inode *inode, struct file *file)
298 struct video_device *vfl = video_devdata(file);
300 vfl->users--;
301 return 0;
304 static char *v4l2_memory_names[] = {
305 [V4L2_MEMORY_MMAP] = "mmap",
306 [V4L2_MEMORY_USERPTR] = "userptr",
307 [V4L2_MEMORY_OVERLAY] = "overlay",
311 /* FIXME: Those stuff are replicated also on v4l2-common.c */
312 static char *v4l2_type_names_FIXME[] = {
313 [V4L2_BUF_TYPE_VIDEO_CAPTURE] = "video-cap",
314 [V4L2_BUF_TYPE_VIDEO_OVERLAY] = "video-over",
315 [V4L2_BUF_TYPE_VIDEO_OUTPUT] = "video-out",
316 [V4L2_BUF_TYPE_VBI_CAPTURE] = "vbi-cap",
317 [V4L2_BUF_TYPE_VBI_OUTPUT] = "vbi-out",
318 [V4L2_BUF_TYPE_SLICED_VBI_OUTPUT] = "sliced-vbi-out",
319 [V4L2_BUF_TYPE_SLICED_VBI_CAPTURE] = "sliced-vbi-capture",
320 [V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY] = "video-out-over",
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",
333 [V4L2_FIELD_INTERLACED_TB] = "interlaced-tb",
334 [V4L2_FIELD_INTERLACED_BT] = "interlaced-bt",
337 #define prt_names(a,arr) (((a)>=0)&&((a)<ARRAY_SIZE(arr)))?arr[a]:"unknown"
339 static void dbgbuf(unsigned int cmd, struct video_device *vfd,
340 struct v4l2_buffer *p)
342 struct v4l2_timecode *tc=&p->timecode;
344 dbgarg (cmd, "%02ld:%02d:%02d.%08ld index=%d, type=%s, "
345 "bytesused=%d, flags=0x%08d, "
346 "field=%0d, sequence=%d, memory=%s, offset/userptr=0x%08lx, length=%d\n",
347 (p->timestamp.tv_sec/3600),
348 (int)(p->timestamp.tv_sec/60)%60,
349 (int)(p->timestamp.tv_sec%60),
350 p->timestamp.tv_usec,
351 p->index,
352 prt_names(p->type,v4l2_type_names_FIXME),
353 p->bytesused,p->flags,
354 p->field,p->sequence,
355 prt_names(p->memory,v4l2_memory_names),
356 p->m.userptr, p->length);
357 dbgarg2 ("timecode= %02d:%02d:%02d type=%d, "
358 "flags=0x%08d, frames=%d, userbits=0x%08x\n",
359 tc->hours,tc->minutes,tc->seconds,
360 tc->type, tc->flags, tc->frames, *(__u32 *) tc->userbits);
363 static inline void dbgrect(struct video_device *vfd, char *s,
364 struct v4l2_rect *r)
366 dbgarg2 ("%sRect start at %dx%d, size= %dx%d\n", s, r->left, r->top,
367 r->width, r->height);
370 static inline void v4l_print_pix_fmt (struct video_device *vfd,
371 struct v4l2_pix_format *fmt)
373 dbgarg2 ("width=%d, height=%d, format=%c%c%c%c, field=%s, "
374 "bytesperline=%d sizeimage=%d, colorspace=%d\n",
375 fmt->width,fmt->height,
376 (fmt->pixelformat & 0xff),
377 (fmt->pixelformat >> 8) & 0xff,
378 (fmt->pixelformat >> 16) & 0xff,
379 (fmt->pixelformat >> 24) & 0xff,
380 prt_names(fmt->field,v4l2_field_names_FIXME),
381 fmt->bytesperline,fmt->sizeimage,fmt->colorspace);
385 static int check_fmt (struct video_device *vfd, enum v4l2_buf_type type)
387 switch (type) {
388 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
389 if (vfd->vidioc_try_fmt_cap)
390 return (0);
391 break;
392 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
393 if (vfd->vidioc_try_fmt_overlay)
394 return (0);
395 break;
396 case V4L2_BUF_TYPE_VBI_CAPTURE:
397 if (vfd->vidioc_try_fmt_vbi)
398 return (0);
399 break;
400 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
401 if (vfd->vidioc_try_fmt_vbi_output)
402 return (0);
403 break;
404 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
405 if (vfd->vidioc_try_fmt_vbi_capture)
406 return (0);
407 break;
408 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
409 if (vfd->vidioc_try_fmt_video_output)
410 return (0);
411 break;
412 case V4L2_BUF_TYPE_VBI_OUTPUT:
413 if (vfd->vidioc_try_fmt_vbi_output)
414 return (0);
415 break;
416 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
417 if (vfd->vidioc_try_fmt_output_overlay)
418 return (0);
419 break;
420 case V4L2_BUF_TYPE_PRIVATE:
421 if (vfd->vidioc_try_fmt_type_private)
422 return (0);
423 break;
425 return (-EINVAL);
428 static int __video_do_ioctl(struct inode *inode, struct file *file,
429 unsigned int cmd, void *arg)
431 struct video_device *vfd = video_devdata(file);
432 void *fh = file->private_data;
433 int ret = -EINVAL;
435 if ( (vfd->debug & V4L2_DEBUG_IOCTL) &&
436 !(vfd->debug & V4L2_DEBUG_IOCTL_ARG)) {
437 v4l_print_ioctl(vfd->name, cmd);
440 #ifdef CONFIG_VIDEO_V4L1_COMPAT
441 /***********************************************************
442 Handles calls to the obsoleted V4L1 API
443 Due to the nature of VIDIOCGMBUF, each driver that supports
444 V4L1 should implement its own handler for this ioctl.
445 ***********************************************************/
447 /* --- streaming capture ------------------------------------- */
448 if (cmd == VIDIOCGMBUF) {
449 struct video_mbuf *p=arg;
451 memset(p,0,sizeof(p));
453 if (!vfd->vidiocgmbuf)
454 return ret;
455 ret=vfd->vidiocgmbuf(file, fh, p);
456 if (!ret)
457 dbgarg (cmd, "size=%d, frames=%d, offsets=0x%08lx\n",
458 p->size, p->frames,
459 (unsigned long)p->offsets);
460 return ret;
463 /********************************************************
464 All other V4L1 calls are handled by v4l1_compat module.
465 Those calls will be translated into V4L2 calls, and
466 __video_do_ioctl will be called again, with one or more
467 V4L2 ioctls.
468 ********************************************************/
469 if (_IOC_TYPE(cmd)=='v')
470 return v4l_compat_translate_ioctl(inode,file,cmd,arg,
471 __video_do_ioctl);
472 #endif
474 switch(cmd) {
475 /* --- capabilities ------------------------------------------ */
476 case VIDIOC_QUERYCAP:
478 struct v4l2_capability *cap = (struct v4l2_capability*)arg;
479 memset(cap, 0, sizeof(*cap));
481 if (!vfd->vidioc_querycap)
482 break;
484 ret=vfd->vidioc_querycap(file, fh, cap);
485 if (!ret)
486 dbgarg (cmd, "driver=%s, card=%s, bus=%s, "
487 "version=0x%08x, "
488 "capabilities=0x%08x\n",
489 cap->driver,cap->card,cap->bus_info,
490 cap->version,
491 cap->capabilities);
492 break;
495 /* --- priority ------------------------------------------ */
496 case VIDIOC_G_PRIORITY:
498 enum v4l2_priority *p=arg;
500 if (!vfd->vidioc_g_priority)
501 break;
502 ret=vfd->vidioc_g_priority(file, fh, p);
503 if (!ret)
504 dbgarg(cmd, "priority is %d\n", *p);
505 break;
507 case VIDIOC_S_PRIORITY:
509 enum v4l2_priority *p=arg;
511 if (!vfd->vidioc_s_priority)
512 break;
513 dbgarg(cmd, "setting priority to %d\n", *p);
514 ret=vfd->vidioc_s_priority(file, fh, *p);
515 break;
518 /* --- capture ioctls ---------------------------------------- */
519 case VIDIOC_ENUM_FMT:
521 struct v4l2_fmtdesc *f = arg;
522 enum v4l2_buf_type type;
523 unsigned int index;
525 index = f->index;
526 type = f->type;
527 memset(f,0,sizeof(*f));
528 f->index = index;
529 f->type = type;
531 switch (type) {
532 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
533 if (vfd->vidioc_enum_fmt_cap)
534 ret=vfd->vidioc_enum_fmt_cap(file, fh, f);
535 break;
536 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
537 if (vfd->vidioc_enum_fmt_overlay)
538 ret=vfd->vidioc_enum_fmt_overlay(file, fh, f);
539 break;
540 case V4L2_BUF_TYPE_VBI_CAPTURE:
541 if (vfd->vidioc_enum_fmt_vbi)
542 ret=vfd->vidioc_enum_fmt_vbi(file, fh, f);
543 break;
544 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
545 if (vfd->vidioc_enum_fmt_vbi_output)
546 ret=vfd->vidioc_enum_fmt_vbi_output(file,
547 fh, f);
548 break;
549 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
550 if (vfd->vidioc_enum_fmt_vbi_capture)
551 ret=vfd->vidioc_enum_fmt_vbi_capture(file,
552 fh, f);
553 break;
554 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
555 if (vfd->vidioc_enum_fmt_video_output)
556 ret=vfd->vidioc_enum_fmt_video_output(file,
557 fh, f);
558 break;
559 case V4L2_BUF_TYPE_VBI_OUTPUT:
560 if (vfd->vidioc_enum_fmt_vbi_output)
561 ret=vfd->vidioc_enum_fmt_vbi_output(file,
562 fh, f);
563 break;
564 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
565 if (vfd->vidioc_enum_fmt_output_overlay)
566 ret=vfd->vidioc_enum_fmt_output_overlay(file, fh, f);
567 break;
568 case V4L2_BUF_TYPE_PRIVATE:
569 if (vfd->vidioc_enum_fmt_type_private)
570 ret=vfd->vidioc_enum_fmt_type_private(file,
571 fh, f);
572 break;
574 if (!ret)
575 dbgarg (cmd, "index=%d, type=%d, flags=%d, "
576 "pixelformat=%c%c%c%c, description='%s'\n",
577 f->index, f->type, f->flags,
578 (f->pixelformat & 0xff),
579 (f->pixelformat >> 8) & 0xff,
580 (f->pixelformat >> 16) & 0xff,
581 (f->pixelformat >> 24) & 0xff,
582 f->description);
583 break;
585 case VIDIOC_G_FMT:
587 struct v4l2_format *f = (struct v4l2_format *)arg;
588 enum v4l2_buf_type type=f->type;
590 memset(&f->fmt.pix,0,sizeof(f->fmt.pix));
591 f->type=type;
593 /* FIXME: Should be one dump per type */
594 dbgarg (cmd, "type=%s\n", prt_names(type,
595 v4l2_type_names_FIXME));
597 switch (type) {
598 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
599 if (vfd->vidioc_g_fmt_cap)
600 ret=vfd->vidioc_g_fmt_cap(file, fh, f);
601 if (!ret)
602 v4l_print_pix_fmt(vfd,&f->fmt.pix);
603 break;
604 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
605 if (vfd->vidioc_g_fmt_overlay)
606 ret=vfd->vidioc_g_fmt_overlay(file, fh, f);
607 break;
608 case V4L2_BUF_TYPE_VBI_CAPTURE:
609 if (vfd->vidioc_g_fmt_vbi)
610 ret=vfd->vidioc_g_fmt_vbi(file, fh, f);
611 break;
612 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
613 if (vfd->vidioc_g_fmt_vbi_output)
614 ret=vfd->vidioc_g_fmt_vbi_output(file, fh, f);
615 break;
616 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
617 if (vfd->vidioc_g_fmt_vbi_capture)
618 ret=vfd->vidioc_g_fmt_vbi_capture(file, fh, f);
619 break;
620 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
621 if (vfd->vidioc_g_fmt_video_output)
622 ret=vfd->vidioc_g_fmt_video_output(file,
623 fh, f);
624 break;
625 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
626 if (vfd->vidioc_g_fmt_output_overlay)
627 ret=vfd->vidioc_g_fmt_output_overlay(file, fh, f);
628 break;
629 case V4L2_BUF_TYPE_VBI_OUTPUT:
630 if (vfd->vidioc_g_fmt_vbi_output)
631 ret=vfd->vidioc_g_fmt_vbi_output(file, fh, f);
632 break;
633 case V4L2_BUF_TYPE_PRIVATE:
634 if (vfd->vidioc_g_fmt_type_private)
635 ret=vfd->vidioc_g_fmt_type_private(file,
636 fh, f);
637 break;
640 break;
642 case VIDIOC_S_FMT:
644 struct v4l2_format *f = (struct v4l2_format *)arg;
646 /* FIXME: Should be one dump per type */
647 dbgarg (cmd, "type=%s\n", prt_names(f->type,
648 v4l2_type_names_FIXME));
650 switch (f->type) {
651 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
652 v4l_print_pix_fmt(vfd,&f->fmt.pix);
653 if (vfd->vidioc_s_fmt_cap)
654 ret=vfd->vidioc_s_fmt_cap(file, fh, f);
655 break;
656 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
657 if (vfd->vidioc_s_fmt_overlay)
658 ret=vfd->vidioc_s_fmt_overlay(file, fh, f);
659 break;
660 case V4L2_BUF_TYPE_VBI_CAPTURE:
661 if (vfd->vidioc_s_fmt_vbi)
662 ret=vfd->vidioc_s_fmt_vbi(file, fh, f);
663 break;
664 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
665 if (vfd->vidioc_s_fmt_vbi_output)
666 ret=vfd->vidioc_s_fmt_vbi_output(file, fh, f);
667 break;
668 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
669 if (vfd->vidioc_s_fmt_vbi_capture)
670 ret=vfd->vidioc_s_fmt_vbi_capture(file, fh, f);
671 break;
672 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
673 if (vfd->vidioc_s_fmt_video_output)
674 ret=vfd->vidioc_s_fmt_video_output(file,
675 fh, f);
676 break;
677 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
678 if (vfd->vidioc_s_fmt_output_overlay)
679 ret=vfd->vidioc_s_fmt_output_overlay(file, fh, f);
680 break;
681 case V4L2_BUF_TYPE_VBI_OUTPUT:
682 if (vfd->vidioc_s_fmt_vbi_output)
683 ret=vfd->vidioc_s_fmt_vbi_output(file,
684 fh, f);
685 break;
686 case V4L2_BUF_TYPE_PRIVATE:
687 if (vfd->vidioc_s_fmt_type_private)
688 ret=vfd->vidioc_s_fmt_type_private(file,
689 fh, f);
690 break;
692 break;
694 case VIDIOC_TRY_FMT:
696 struct v4l2_format *f = (struct v4l2_format *)arg;
698 /* FIXME: Should be one dump per type */
699 dbgarg (cmd, "type=%s\n", prt_names(f->type,
700 v4l2_type_names_FIXME));
701 switch (f->type) {
702 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
703 if (vfd->vidioc_try_fmt_cap)
704 ret=vfd->vidioc_try_fmt_cap(file, fh, f);
705 if (!ret)
706 v4l_print_pix_fmt(vfd,&f->fmt.pix);
707 break;
708 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
709 if (vfd->vidioc_try_fmt_overlay)
710 ret=vfd->vidioc_try_fmt_overlay(file, fh, f);
711 break;
712 case V4L2_BUF_TYPE_VBI_CAPTURE:
713 if (vfd->vidioc_try_fmt_vbi)
714 ret=vfd->vidioc_try_fmt_vbi(file, fh, f);
715 break;
716 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
717 if (vfd->vidioc_try_fmt_vbi_output)
718 ret=vfd->vidioc_try_fmt_vbi_output(file,
719 fh, f);
720 break;
721 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
722 if (vfd->vidioc_try_fmt_vbi_capture)
723 ret=vfd->vidioc_try_fmt_vbi_capture(file,
724 fh, f);
725 break;
726 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
727 if (vfd->vidioc_try_fmt_video_output)
728 ret=vfd->vidioc_try_fmt_video_output(file,
729 fh, f);
730 break;
731 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
732 if (vfd->vidioc_try_fmt_output_overlay)
733 ret=vfd->vidioc_try_fmt_output_overlay(file, fh, f);
734 break;
735 case V4L2_BUF_TYPE_VBI_OUTPUT:
736 if (vfd->vidioc_try_fmt_vbi_output)
737 ret=vfd->vidioc_try_fmt_vbi_output(file,
738 fh, f);
739 break;
740 case V4L2_BUF_TYPE_PRIVATE:
741 if (vfd->vidioc_try_fmt_type_private)
742 ret=vfd->vidioc_try_fmt_type_private(file,
743 fh, f);
744 break;
747 break;
749 /* FIXME: Those buf reqs could be handled here,
750 with some changes on videobuf to allow its header to be included at
751 videodev2.h or being merged at videodev2.
753 case VIDIOC_REQBUFS:
755 struct v4l2_requestbuffers *p=arg;
757 if (!vfd->vidioc_reqbufs)
758 break;
759 ret = check_fmt (vfd, p->type);
760 if (ret)
761 break;
763 ret=vfd->vidioc_reqbufs(file, fh, p);
764 dbgarg (cmd, "count=%d, type=%s, memory=%s\n",
765 p->count,
766 prt_names(p->type,v4l2_type_names_FIXME),
767 prt_names(p->memory,v4l2_memory_names));
768 break;
770 case VIDIOC_QUERYBUF:
772 struct v4l2_buffer *p=arg;
774 if (!vfd->vidioc_querybuf)
775 break;
776 ret = check_fmt (vfd, p->type);
777 if (ret)
778 break;
780 ret=vfd->vidioc_querybuf(file, fh, p);
781 if (!ret)
782 dbgbuf(cmd,vfd,p);
783 break;
785 case VIDIOC_QBUF:
787 struct v4l2_buffer *p=arg;
789 if (!vfd->vidioc_qbuf)
790 break;
791 ret = check_fmt (vfd, p->type);
792 if (ret)
793 break;
795 ret=vfd->vidioc_qbuf(file, fh, p);
796 if (!ret)
797 dbgbuf(cmd,vfd,p);
798 break;
800 case VIDIOC_DQBUF:
802 struct v4l2_buffer *p=arg;
803 if (!vfd->vidioc_dqbuf)
804 break;
805 ret = check_fmt (vfd, p->type);
806 if (ret)
807 break;
809 ret=vfd->vidioc_dqbuf(file, fh, p);
810 if (!ret)
811 dbgbuf(cmd,vfd,p);
812 break;
814 case VIDIOC_OVERLAY:
816 int *i = arg;
818 if (!vfd->vidioc_overlay)
819 break;
820 dbgarg (cmd, "value=%d\n",*i);
821 ret=vfd->vidioc_overlay(file, fh, *i);
822 break;
824 case VIDIOC_G_FBUF:
826 struct v4l2_framebuffer *p=arg;
827 if (!vfd->vidioc_g_fbuf)
828 break;
829 ret=vfd->vidioc_g_fbuf(file, fh, arg);
830 if (!ret) {
831 dbgarg (cmd, "capability=%d, flags=%d, base=0x%08lx\n",
832 p->capability,p->flags,
833 (unsigned long)p->base);
834 v4l_print_pix_fmt (vfd, &p->fmt);
836 break;
838 case VIDIOC_S_FBUF:
840 struct v4l2_framebuffer *p=arg;
841 if (!vfd->vidioc_s_fbuf)
842 break;
844 dbgarg (cmd, "capability=%d, flags=%d, base=0x%08lx\n",
845 p->capability,p->flags,(unsigned long)p->base);
846 v4l_print_pix_fmt (vfd, &p->fmt);
847 ret=vfd->vidioc_s_fbuf(file, fh, arg);
849 break;
851 case VIDIOC_STREAMON:
853 enum v4l2_buf_type i = *(int *)arg;
854 if (!vfd->vidioc_streamon)
855 break;
856 dbgarg (cmd, "type=%s\n", prt_names(i,v4l2_type_names_FIXME));
857 ret=vfd->vidioc_streamon(file, fh,i);
858 break;
860 case VIDIOC_STREAMOFF:
862 enum v4l2_buf_type i = *(int *)arg;
864 if (!vfd->vidioc_streamoff)
865 break;
866 dbgarg (cmd, "type=%s\n", prt_names(i,v4l2_type_names_FIXME));
867 ret=vfd->vidioc_streamoff(file, fh, i);
868 break;
870 /* ---------- tv norms ---------- */
871 case VIDIOC_ENUMSTD:
873 struct v4l2_standard *p = arg;
874 v4l2_std_id id = vfd->tvnorms,curr_id=0;
875 unsigned int index = p->index,i;
877 if (index<0) {
878 ret=-EINVAL;
879 break;
882 /* Return norm array on a canonical way */
883 for (i=0;i<= index && id; i++) {
884 if ( (id & V4L2_STD_PAL) == V4L2_STD_PAL) {
885 curr_id = V4L2_STD_PAL;
886 } else if ( (id & V4L2_STD_PAL_BG) == V4L2_STD_PAL_BG) {
887 curr_id = V4L2_STD_PAL_BG;
888 } else if ( (id & V4L2_STD_PAL_DK) == V4L2_STD_PAL_DK) {
889 curr_id = V4L2_STD_PAL_DK;
890 } else if ( (id & V4L2_STD_PAL_B) == V4L2_STD_PAL_B) {
891 curr_id = V4L2_STD_PAL_B;
892 } else if ( (id & V4L2_STD_PAL_B1) == V4L2_STD_PAL_B1) {
893 curr_id = V4L2_STD_PAL_B1;
894 } else if ( (id & V4L2_STD_PAL_G) == V4L2_STD_PAL_G) {
895 curr_id = V4L2_STD_PAL_G;
896 } else if ( (id & V4L2_STD_PAL_H) == V4L2_STD_PAL_H) {
897 curr_id = V4L2_STD_PAL_H;
898 } else if ( (id & V4L2_STD_PAL_I) == V4L2_STD_PAL_I) {
899 curr_id = V4L2_STD_PAL_I;
900 } else if ( (id & V4L2_STD_PAL_D) == V4L2_STD_PAL_D) {
901 curr_id = V4L2_STD_PAL_D;
902 } else if ( (id & V4L2_STD_PAL_D1) == V4L2_STD_PAL_D1) {
903 curr_id = V4L2_STD_PAL_D1;
904 } else if ( (id & V4L2_STD_PAL_K) == V4L2_STD_PAL_K) {
905 curr_id = V4L2_STD_PAL_K;
906 } else if ( (id & V4L2_STD_PAL_M) == V4L2_STD_PAL_M) {
907 curr_id = V4L2_STD_PAL_M;
908 } else if ( (id & V4L2_STD_PAL_N) == V4L2_STD_PAL_N) {
909 curr_id = V4L2_STD_PAL_N;
910 } else if ( (id & V4L2_STD_PAL_Nc) == V4L2_STD_PAL_Nc) {
911 curr_id = V4L2_STD_PAL_Nc;
912 } else if ( (id & V4L2_STD_PAL_60) == V4L2_STD_PAL_60) {
913 curr_id = V4L2_STD_PAL_60;
914 } else if ( (id & V4L2_STD_NTSC) == V4L2_STD_NTSC) {
915 curr_id = V4L2_STD_NTSC;
916 } else if ( (id & V4L2_STD_NTSC_M) == V4L2_STD_NTSC_M) {
917 curr_id = V4L2_STD_NTSC_M;
918 } else if ( (id & V4L2_STD_NTSC_M_JP) == V4L2_STD_NTSC_M_JP) {
919 curr_id = V4L2_STD_NTSC_M_JP;
920 } else if ( (id & V4L2_STD_NTSC_443) == V4L2_STD_NTSC_443) {
921 curr_id = V4L2_STD_NTSC_443;
922 } else if ( (id & V4L2_STD_NTSC_M_KR) == V4L2_STD_NTSC_M_KR) {
923 curr_id = V4L2_STD_NTSC_M_KR;
924 } else if ( (id & V4L2_STD_SECAM) == V4L2_STD_SECAM) {
925 curr_id = V4L2_STD_SECAM;
926 } else if ( (id & V4L2_STD_SECAM_DK) == V4L2_STD_SECAM_DK) {
927 curr_id = V4L2_STD_SECAM_DK;
928 } else if ( (id & V4L2_STD_SECAM_B) == V4L2_STD_SECAM_B) {
929 curr_id = V4L2_STD_SECAM_B;
930 } else if ( (id & V4L2_STD_SECAM_D) == V4L2_STD_SECAM_D) {
931 curr_id = V4L2_STD_SECAM_D;
932 } else if ( (id & V4L2_STD_SECAM_G) == V4L2_STD_SECAM_G) {
933 curr_id = V4L2_STD_SECAM_G;
934 } else if ( (id & V4L2_STD_SECAM_H) == V4L2_STD_SECAM_H) {
935 curr_id = V4L2_STD_SECAM_H;
936 } else if ( (id & V4L2_STD_SECAM_K) == V4L2_STD_SECAM_K) {
937 curr_id = V4L2_STD_SECAM_K;
938 } else if ( (id & V4L2_STD_SECAM_K1) == V4L2_STD_SECAM_K1) {
939 curr_id = V4L2_STD_SECAM_K1;
940 } else if ( (id & V4L2_STD_SECAM_L) == V4L2_STD_SECAM_L) {
941 curr_id = V4L2_STD_SECAM_L;
942 } else if ( (id & V4L2_STD_SECAM_LC) == V4L2_STD_SECAM_LC) {
943 curr_id = V4L2_STD_SECAM_LC;
944 } else {
945 break;
947 id &= ~curr_id;
949 if (i<=index)
950 return -EINVAL;
952 v4l2_video_std_construct(p, curr_id,v4l2_norm_to_name(curr_id));
953 p->index = index;
955 dbgarg (cmd, "index=%d, id=%Ld, name=%s, fps=%d/%d, "
956 "framelines=%d\n", p->index,
957 (unsigned long long)p->id, p->name,
958 p->frameperiod.numerator,
959 p->frameperiod.denominator,
960 p->framelines);
962 ret=0;
963 break;
965 case VIDIOC_G_STD:
967 v4l2_std_id *id = arg;
969 *id = vfd->current_norm;
971 dbgarg (cmd, "value=%Lu\n", (long long unsigned) *id);
973 ret=0;
974 break;
976 case VIDIOC_S_STD:
978 v4l2_std_id *id = arg,norm;
980 dbgarg (cmd, "value=%Lu\n", (long long unsigned) *id);
982 norm = (*id) & vfd->tvnorms;
983 if ( vfd->tvnorms && !norm) /* Check if std is supported */
984 break;
986 /* Calls the specific handler */
987 if (vfd->vidioc_s_std)
988 ret=vfd->vidioc_s_std(file, fh, &norm);
989 else
990 ret=-EINVAL;
992 /* Updates standard information */
993 if (ret>=0)
994 vfd->current_norm=norm;
996 break;
998 case VIDIOC_QUERYSTD:
1000 v4l2_std_id *p=arg;
1002 if (!vfd->vidioc_querystd)
1003 break;
1004 ret=vfd->vidioc_querystd(file, fh, arg);
1005 if (!ret)
1006 dbgarg (cmd, "detected std=%Lu\n",
1007 (unsigned long long)*p);
1008 break;
1010 /* ------ input switching ---------- */
1011 /* FIXME: Inputs can be handled inside videodev2 */
1012 case VIDIOC_ENUMINPUT:
1014 struct v4l2_input *p=arg;
1015 int i=p->index;
1017 if (!vfd->vidioc_enum_input)
1018 break;
1019 memset(p, 0, sizeof(*p));
1020 p->index=i;
1022 ret=vfd->vidioc_enum_input(file, fh, p);
1023 if (!ret)
1024 dbgarg (cmd, "index=%d, name=%s, type=%d, "
1025 "audioset=%d, "
1026 "tuner=%d, std=%Ld, status=%d\n",
1027 p->index,p->name,p->type,p->audioset,
1028 p->tuner,
1029 (unsigned long long)p->std,
1030 p->status);
1031 break;
1033 case VIDIOC_G_INPUT:
1035 unsigned int *i = arg;
1037 if (!vfd->vidioc_g_input)
1038 break;
1039 ret=vfd->vidioc_g_input(file, fh, i);
1040 if (!ret)
1041 dbgarg (cmd, "value=%d\n",*i);
1042 break;
1044 case VIDIOC_S_INPUT:
1046 unsigned int *i = arg;
1048 if (!vfd->vidioc_s_input)
1049 break;
1050 dbgarg (cmd, "value=%d\n",*i);
1051 ret=vfd->vidioc_s_input(file, fh, *i);
1052 break;
1055 /* ------ output switching ---------- */
1056 case VIDIOC_G_OUTPUT:
1058 unsigned int *i = arg;
1060 if (!vfd->vidioc_g_output)
1061 break;
1062 ret=vfd->vidioc_g_output(file, fh, i);
1063 if (!ret)
1064 dbgarg (cmd, "value=%d\n",*i);
1065 break;
1067 case VIDIOC_S_OUTPUT:
1069 unsigned int *i = arg;
1071 if (!vfd->vidioc_s_output)
1072 break;
1073 dbgarg (cmd, "value=%d\n",*i);
1074 ret=vfd->vidioc_s_output(file, fh, *i);
1075 break;
1078 /* --- controls ---------------------------------------------- */
1079 case VIDIOC_QUERYCTRL:
1081 struct v4l2_queryctrl *p=arg;
1083 if (!vfd->vidioc_queryctrl)
1084 break;
1085 ret=vfd->vidioc_queryctrl(file, fh, p);
1087 if (!ret)
1088 dbgarg (cmd, "id=%d, type=%d, name=%s, "
1089 "min/max=%d/%d,"
1090 " step=%d, default=%d, flags=0x%08x\n",
1091 p->id,p->type,p->name,p->minimum,
1092 p->maximum,p->step,p->default_value,
1093 p->flags);
1094 break;
1096 case VIDIOC_G_CTRL:
1098 struct v4l2_control *p = arg;
1100 if (!vfd->vidioc_g_ctrl)
1101 break;
1102 dbgarg(cmd, "Enum for index=%d\n", p->id);
1104 ret=vfd->vidioc_g_ctrl(file, fh, p);
1105 if (!ret)
1106 dbgarg2 ( "id=%d, value=%d\n", p->id, p->value);
1107 break;
1109 case VIDIOC_S_CTRL:
1111 struct v4l2_control *p = arg;
1113 if (!vfd->vidioc_s_ctrl)
1114 break;
1115 dbgarg (cmd, "id=%d, value=%d\n", p->id, p->value);
1117 ret=vfd->vidioc_s_ctrl(file, fh, p);
1118 break;
1120 case VIDIOC_G_EXT_CTRLS:
1122 struct v4l2_ext_controls *p = arg;
1124 if (vfd->vidioc_g_ext_ctrls) {
1125 dbgarg(cmd, "count=%d\n", p->count);
1127 ret=vfd->vidioc_g_ext_ctrls(file, fh, p);
1129 break;
1131 case VIDIOC_S_EXT_CTRLS:
1133 struct v4l2_ext_controls *p = arg;
1135 if (vfd->vidioc_s_ext_ctrls) {
1136 dbgarg(cmd, "count=%d\n", p->count);
1138 ret=vfd->vidioc_s_ext_ctrls(file, fh, p);
1140 break;
1142 case VIDIOC_TRY_EXT_CTRLS:
1144 struct v4l2_ext_controls *p = arg;
1146 if (vfd->vidioc_try_ext_ctrls) {
1147 dbgarg(cmd, "count=%d\n", p->count);
1149 ret=vfd->vidioc_try_ext_ctrls(file, fh, p);
1151 break;
1153 case VIDIOC_QUERYMENU:
1155 struct v4l2_querymenu *p=arg;
1156 if (!vfd->vidioc_querymenu)
1157 break;
1158 ret=vfd->vidioc_querymenu(file, fh, p);
1159 if (!ret)
1160 dbgarg (cmd, "id=%d, index=%d, name=%s\n",
1161 p->id,p->index,p->name);
1162 break;
1164 /* --- audio ---------------------------------------------- */
1165 case VIDIOC_ENUMAUDIO:
1167 struct v4l2_audio *p=arg;
1169 if (!vfd->vidioc_enumaudio)
1170 break;
1171 dbgarg(cmd, "Enum for index=%d\n", p->index);
1172 ret=vfd->vidioc_enumaudio(file, fh, p);
1173 if (!ret)
1174 dbgarg2("index=%d, name=%s, capability=%d, "
1175 "mode=%d\n",p->index,p->name,
1176 p->capability, p->mode);
1177 break;
1179 case VIDIOC_G_AUDIO:
1181 struct v4l2_audio *p=arg;
1182 __u32 index=p->index;
1184 if (!vfd->vidioc_g_audio)
1185 break;
1187 memset(p,0,sizeof(*p));
1188 p->index=index;
1189 dbgarg(cmd, "Get for index=%d\n", p->index);
1190 ret=vfd->vidioc_g_audio(file, fh, p);
1191 if (!ret)
1192 dbgarg2("index=%d, name=%s, capability=%d, "
1193 "mode=%d\n",p->index,
1194 p->name,p->capability, p->mode);
1195 break;
1197 case VIDIOC_S_AUDIO:
1199 struct v4l2_audio *p=arg;
1201 if (!vfd->vidioc_s_audio)
1202 break;
1203 dbgarg(cmd, "index=%d, name=%s, capability=%d, "
1204 "mode=%d\n", p->index, p->name,
1205 p->capability, p->mode);
1206 ret=vfd->vidioc_s_audio(file, fh, p);
1207 break;
1209 case VIDIOC_ENUMAUDOUT:
1211 struct v4l2_audioout *p=arg;
1213 if (!vfd->vidioc_enumaudout)
1214 break;
1215 dbgarg(cmd, "Enum for index=%d\n", p->index);
1216 ret=vfd->vidioc_enumaudout(file, fh, p);
1217 if (!ret)
1218 dbgarg2("index=%d, name=%s, capability=%d, "
1219 "mode=%d\n", p->index, p->name,
1220 p->capability,p->mode);
1221 break;
1223 case VIDIOC_G_AUDOUT:
1225 struct v4l2_audioout *p=arg;
1227 if (!vfd->vidioc_g_audout)
1228 break;
1229 dbgarg(cmd, "Enum for index=%d\n", p->index);
1230 ret=vfd->vidioc_g_audout(file, fh, p);
1231 if (!ret)
1232 dbgarg2("index=%d, name=%s, capability=%d, "
1233 "mode=%d\n", p->index, p->name,
1234 p->capability,p->mode);
1235 break;
1237 case VIDIOC_S_AUDOUT:
1239 struct v4l2_audioout *p=arg;
1241 if (!vfd->vidioc_s_audout)
1242 break;
1243 dbgarg(cmd, "index=%d, name=%s, capability=%d, "
1244 "mode=%d\n", p->index, p->name,
1245 p->capability,p->mode);
1247 ret=vfd->vidioc_s_audout(file, fh, p);
1248 break;
1250 case VIDIOC_G_MODULATOR:
1252 struct v4l2_modulator *p=arg;
1253 if (!vfd->vidioc_g_modulator)
1254 break;
1255 ret=vfd->vidioc_g_modulator(file, fh, p);
1256 if (!ret)
1257 dbgarg(cmd, "index=%d, name=%s, "
1258 "capability=%d, rangelow=%d,"
1259 " rangehigh=%d, txsubchans=%d\n",
1260 p->index, p->name,p->capability,
1261 p->rangelow, p->rangehigh,
1262 p->txsubchans);
1263 break;
1265 case VIDIOC_S_MODULATOR:
1267 struct v4l2_modulator *p=arg;
1268 if (!vfd->vidioc_s_modulator)
1269 break;
1270 dbgarg(cmd, "index=%d, name=%s, capability=%d, "
1271 "rangelow=%d, rangehigh=%d, txsubchans=%d\n",
1272 p->index, p->name,p->capability,p->rangelow,
1273 p->rangehigh,p->txsubchans);
1274 ret=vfd->vidioc_s_modulator(file, fh, p);
1275 break;
1277 case VIDIOC_G_CROP:
1279 struct v4l2_crop *p=arg;
1280 if (!vfd->vidioc_g_crop)
1281 break;
1282 ret=vfd->vidioc_g_crop(file, fh, p);
1283 if (!ret) {
1284 dbgarg(cmd, "type=%d\n", p->type);
1285 dbgrect(vfd, "", &p->c);
1287 break;
1289 case VIDIOC_S_CROP:
1291 struct v4l2_crop *p=arg;
1292 if (!vfd->vidioc_s_crop)
1293 break;
1294 dbgarg(cmd, "type=%d\n", p->type);
1295 dbgrect(vfd, "", &p->c);
1296 ret=vfd->vidioc_s_crop(file, fh, p);
1297 break;
1299 case VIDIOC_CROPCAP:
1301 struct v4l2_cropcap *p=arg;
1302 /*FIXME: Should also show v4l2_fract pixelaspect */
1303 if (!vfd->vidioc_cropcap)
1304 break;
1305 dbgarg(cmd, "type=%d\n", p->type);
1306 dbgrect(vfd, "bounds ", &p->bounds);
1307 dbgrect(vfd, "defrect ", &p->defrect);
1308 ret=vfd->vidioc_cropcap(file, fh, p);
1309 break;
1311 case VIDIOC_G_MPEGCOMP:
1313 struct v4l2_mpeg_compression *p=arg;
1315 /*FIXME: Several fields not shown */
1316 if (!vfd->vidioc_g_mpegcomp)
1317 break;
1318 ret=vfd->vidioc_g_mpegcomp(file, fh, p);
1319 if (!ret)
1320 dbgarg (cmd, "ts_pid_pmt=%d, ts_pid_audio=%d,"
1321 " ts_pid_video=%d, ts_pid_pcr=%d, "
1322 "ps_size=%d, au_sample_rate=%d, "
1323 "au_pesid=%c, vi_frame_rate=%d, "
1324 "vi_frames_per_gop=%d, "
1325 "vi_bframes_count=%d, vi_pesid=%c\n",
1326 p->ts_pid_pmt,p->ts_pid_audio,
1327 p->ts_pid_video,p->ts_pid_pcr,
1328 p->ps_size, p->au_sample_rate,
1329 p->au_pesid, p->vi_frame_rate,
1330 p->vi_frames_per_gop,
1331 p->vi_bframes_count, p->vi_pesid);
1332 break;
1334 case VIDIOC_S_MPEGCOMP:
1336 struct v4l2_mpeg_compression *p=arg;
1337 /*FIXME: Several fields not shown */
1338 if (!vfd->vidioc_s_mpegcomp)
1339 break;
1340 dbgarg (cmd, "ts_pid_pmt=%d, ts_pid_audio=%d, "
1341 "ts_pid_video=%d, ts_pid_pcr=%d, ps_size=%d, "
1342 "au_sample_rate=%d, au_pesid=%c, "
1343 "vi_frame_rate=%d, vi_frames_per_gop=%d, "
1344 "vi_bframes_count=%d, vi_pesid=%c\n",
1345 p->ts_pid_pmt,p->ts_pid_audio, p->ts_pid_video,
1346 p->ts_pid_pcr, p->ps_size, p->au_sample_rate,
1347 p->au_pesid, p->vi_frame_rate,
1348 p->vi_frames_per_gop, p->vi_bframes_count,
1349 p->vi_pesid);
1350 ret=vfd->vidioc_s_mpegcomp(file, fh, p);
1351 break;
1353 case VIDIOC_G_JPEGCOMP:
1355 struct v4l2_jpegcompression *p=arg;
1356 if (!vfd->vidioc_g_jpegcomp)
1357 break;
1358 ret=vfd->vidioc_g_jpegcomp(file, fh, p);
1359 if (!ret)
1360 dbgarg (cmd, "quality=%d, APPn=%d, "
1361 "APP_len=%d, COM_len=%d, "
1362 "jpeg_markers=%d\n",
1363 p->quality,p->APPn,p->APP_len,
1364 p->COM_len,p->jpeg_markers);
1365 break;
1367 case VIDIOC_S_JPEGCOMP:
1369 struct v4l2_jpegcompression *p=arg;
1370 if (!vfd->vidioc_g_jpegcomp)
1371 break;
1372 dbgarg (cmd, "quality=%d, APPn=%d, APP_len=%d, "
1373 "COM_len=%d, jpeg_markers=%d\n",
1374 p->quality,p->APPn,p->APP_len,
1375 p->COM_len,p->jpeg_markers);
1376 ret=vfd->vidioc_s_jpegcomp(file, fh, p);
1377 break;
1379 case VIDIOC_G_ENC_INDEX:
1381 struct v4l2_enc_idx *p=arg;
1383 if (!vfd->vidioc_g_enc_index)
1384 break;
1385 ret=vfd->vidioc_g_enc_index(file, fh, p);
1386 if (!ret)
1387 dbgarg (cmd, "entries=%d, entries_cap=%d\n",
1388 p->entries,p->entries_cap);
1389 break;
1391 case VIDIOC_ENCODER_CMD:
1393 struct v4l2_encoder_cmd *p=arg;
1395 if (!vfd->vidioc_encoder_cmd)
1396 break;
1397 ret=vfd->vidioc_encoder_cmd(file, fh, p);
1398 if (!ret)
1399 dbgarg (cmd, "cmd=%d, flags=%d\n",
1400 p->cmd,p->flags);
1401 break;
1403 case VIDIOC_TRY_ENCODER_CMD:
1405 struct v4l2_encoder_cmd *p=arg;
1407 if (!vfd->vidioc_try_encoder_cmd)
1408 break;
1409 ret=vfd->vidioc_try_encoder_cmd(file, fh, p);
1410 if (!ret)
1411 dbgarg (cmd, "cmd=%d, flags=%d\n",
1412 p->cmd,p->flags);
1413 break;
1415 case VIDIOC_G_PARM:
1417 struct v4l2_streamparm *p=arg;
1418 __u32 type=p->type;
1420 memset(p,0,sizeof(*p));
1421 p->type=type;
1423 if (vfd->vidioc_g_parm) {
1424 ret=vfd->vidioc_g_parm(file, fh, p);
1425 } else {
1426 struct v4l2_standard s;
1428 if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1429 return -EINVAL;
1431 v4l2_video_std_construct(&s, vfd->current_norm,
1432 v4l2_norm_to_name(vfd->current_norm));
1434 p->parm.capture.timeperframe = s.frameperiod;
1435 ret=0;
1438 dbgarg (cmd, "type=%d\n", p->type);
1439 break;
1441 case VIDIOC_S_PARM:
1443 struct v4l2_streamparm *p=arg;
1444 if (!vfd->vidioc_s_parm)
1445 break;
1446 dbgarg (cmd, "type=%d\n", p->type);
1447 ret=vfd->vidioc_s_parm(file, fh, p);
1448 break;
1450 case VIDIOC_G_TUNER:
1452 struct v4l2_tuner *p=arg;
1453 __u32 index=p->index;
1455 if (!vfd->vidioc_g_tuner)
1456 break;
1458 memset(p,0,sizeof(*p));
1459 p->index=index;
1461 ret=vfd->vidioc_g_tuner(file, fh, p);
1462 if (!ret)
1463 dbgarg (cmd, "index=%d, name=%s, type=%d, "
1464 "capability=%d, rangelow=%d, "
1465 "rangehigh=%d, signal=%d, afc=%d, "
1466 "rxsubchans=%d, audmode=%d\n",
1467 p->index, p->name, p->type,
1468 p->capability, p->rangelow,
1469 p->rangehigh, p->rxsubchans,
1470 p->audmode, p->signal, p->afc);
1471 break;
1473 case VIDIOC_S_TUNER:
1475 struct v4l2_tuner *p=arg;
1476 if (!vfd->vidioc_s_tuner)
1477 break;
1478 dbgarg (cmd, "index=%d, name=%s, type=%d, "
1479 "capability=%d, rangelow=%d, rangehigh=%d, "
1480 "signal=%d, afc=%d, rxsubchans=%d, "
1481 "audmode=%d\n",p->index, p->name, p->type,
1482 p->capability, p->rangelow,p->rangehigh,
1483 p->rxsubchans, p->audmode, p->signal,
1484 p->afc);
1485 ret=vfd->vidioc_s_tuner(file, fh, p);
1486 break;
1488 case VIDIOC_G_FREQUENCY:
1490 struct v4l2_frequency *p=arg;
1491 if (!vfd->vidioc_g_frequency)
1492 break;
1494 memset(p,0,sizeof(*p));
1496 ret=vfd->vidioc_g_frequency(file, fh, p);
1497 if (!ret)
1498 dbgarg (cmd, "tuner=%d, type=%d, frequency=%d\n",
1499 p->tuner,p->type,p->frequency);
1500 break;
1502 case VIDIOC_S_FREQUENCY:
1504 struct v4l2_frequency *p=arg;
1505 if (!vfd->vidioc_s_frequency)
1506 break;
1507 dbgarg (cmd, "tuner=%d, type=%d, frequency=%d\n",
1508 p->tuner,p->type,p->frequency);
1509 ret=vfd->vidioc_s_frequency(file, fh, p);
1510 break;
1512 case VIDIOC_G_SLICED_VBI_CAP:
1514 struct v4l2_sliced_vbi_cap *p=arg;
1515 if (!vfd->vidioc_g_sliced_vbi_cap)
1516 break;
1517 ret=vfd->vidioc_g_sliced_vbi_cap(file, fh, p);
1518 if (!ret)
1519 dbgarg (cmd, "service_set=%d\n", p->service_set);
1520 break;
1522 case VIDIOC_LOG_STATUS:
1524 if (!vfd->vidioc_log_status)
1525 break;
1526 ret=vfd->vidioc_log_status(file, fh);
1527 break;
1529 #ifdef CONFIG_VIDEO_ADV_DEBUG
1530 case VIDIOC_DBG_G_REGISTER:
1532 struct v4l2_register *p=arg;
1533 if (!capable(CAP_SYS_ADMIN))
1534 ret=-EPERM;
1535 else if (vfd->vidioc_g_register)
1536 ret=vfd->vidioc_g_register(file, fh, p);
1537 break;
1539 case VIDIOC_DBG_S_REGISTER:
1541 struct v4l2_register *p=arg;
1542 if (!capable(CAP_SYS_ADMIN))
1543 ret=-EPERM;
1544 else if (vfd->vidioc_s_register)
1545 ret=vfd->vidioc_s_register(file, fh, p);
1546 break;
1548 #endif
1549 case VIDIOC_G_CHIP_IDENT:
1551 struct v4l2_chip_ident *p=arg;
1552 if (!vfd->vidioc_g_chip_ident)
1553 break;
1554 ret=vfd->vidioc_g_chip_ident(file, fh, p);
1555 if (!ret)
1556 dbgarg (cmd, "chip_ident=%u, revision=0x%x\n", p->ident, p->revision);
1557 break;
1559 } /* switch */
1561 if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) {
1562 if (ret<0) {
1563 printk ("%s: err:\n", vfd->name);
1564 v4l_print_ioctl(vfd->name, cmd);
1568 return ret;
1571 int video_ioctl2 (struct inode *inode, struct file *file,
1572 unsigned int cmd, unsigned long arg)
1574 char sbuf[128];
1575 void *mbuf = NULL;
1576 void *parg = NULL;
1577 int err = -EINVAL;
1578 int is_ext_ctrl;
1579 size_t ctrls_size = 0;
1580 void __user *user_ptr = NULL;
1582 #ifdef __OLD_VIDIOC_
1583 cmd = video_fix_command(cmd);
1584 #endif
1585 is_ext_ctrl = (cmd == VIDIOC_S_EXT_CTRLS || cmd == VIDIOC_G_EXT_CTRLS ||
1586 cmd == VIDIOC_TRY_EXT_CTRLS);
1588 /* Copy arguments into temp kernel buffer */
1589 switch (_IOC_DIR(cmd)) {
1590 case _IOC_NONE:
1591 parg = NULL;
1592 break;
1593 case _IOC_READ:
1594 case _IOC_WRITE:
1595 case (_IOC_WRITE | _IOC_READ):
1596 if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
1597 parg = sbuf;
1598 } else {
1599 /* too big to allocate from stack */
1600 mbuf = kmalloc(_IOC_SIZE(cmd),GFP_KERNEL);
1601 if (NULL == mbuf)
1602 return -ENOMEM;
1603 parg = mbuf;
1606 err = -EFAULT;
1607 if (_IOC_DIR(cmd) & _IOC_WRITE)
1608 if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd)))
1609 goto out;
1610 break;
1613 if (is_ext_ctrl) {
1614 struct v4l2_ext_controls *p = parg;
1616 /* In case of an error, tell the caller that it wasn't
1617 a specific control that caused it. */
1618 p->error_idx = p->count;
1619 user_ptr = (void __user *)p->controls;
1620 if (p->count) {
1621 ctrls_size = sizeof(struct v4l2_ext_control) * p->count;
1622 /* Note: v4l2_ext_controls fits in sbuf[] so mbuf is still NULL. */
1623 mbuf = kmalloc(ctrls_size, GFP_KERNEL);
1624 err = -ENOMEM;
1625 if (NULL == mbuf)
1626 goto out_ext_ctrl;
1627 err = -EFAULT;
1628 if (copy_from_user(mbuf, user_ptr, ctrls_size))
1629 goto out_ext_ctrl;
1630 p->controls = mbuf;
1634 /* Handles IOCTL */
1635 err = __video_do_ioctl(inode, file, cmd, parg);
1636 if (err == -ENOIOCTLCMD)
1637 err = -EINVAL;
1638 if (is_ext_ctrl) {
1639 struct v4l2_ext_controls *p = parg;
1641 p->controls = (void *)user_ptr;
1642 if (p->count && err == 0 && copy_to_user(user_ptr, mbuf, ctrls_size))
1643 err = -EFAULT;
1644 goto out_ext_ctrl;
1646 if (err < 0)
1647 goto out;
1649 out_ext_ctrl:
1650 /* Copy results into user buffer */
1651 switch (_IOC_DIR(cmd))
1653 case _IOC_READ:
1654 case (_IOC_WRITE | _IOC_READ):
1655 if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd)))
1656 err = -EFAULT;
1657 break;
1660 out:
1661 kfree(mbuf);
1662 return err;
1666 static const struct file_operations video_fops;
1669 * video_register_device - register video4linux devices
1670 * @vfd: video device structure we want to register
1671 * @type: type of device to register
1672 * @nr: which device number (0 == /dev/video0, 1 == /dev/video1, ...
1673 * -1 == first free)
1675 * The registration code assigns minor numbers based on the type
1676 * requested. -ENFILE is returned in all the device slots for this
1677 * category are full. If not then the minor field is set and the
1678 * driver initialize function is called (if non %NULL).
1680 * Zero is returned on success.
1682 * Valid types are
1684 * %VFL_TYPE_GRABBER - A frame grabber
1686 * %VFL_TYPE_VTX - A teletext device
1688 * %VFL_TYPE_VBI - Vertical blank data (undecoded)
1690 * %VFL_TYPE_RADIO - A radio card
1693 int video_register_device(struct video_device *vfd, int type, int nr)
1695 int i=0;
1696 int base;
1697 int end;
1698 int ret;
1699 char *name_base;
1701 switch(type)
1703 case VFL_TYPE_GRABBER:
1704 base=MINOR_VFL_TYPE_GRABBER_MIN;
1705 end=MINOR_VFL_TYPE_GRABBER_MAX+1;
1706 name_base = "video";
1707 break;
1708 case VFL_TYPE_VTX:
1709 base=MINOR_VFL_TYPE_VTX_MIN;
1710 end=MINOR_VFL_TYPE_VTX_MAX+1;
1711 name_base = "vtx";
1712 break;
1713 case VFL_TYPE_VBI:
1714 base=MINOR_VFL_TYPE_VBI_MIN;
1715 end=MINOR_VFL_TYPE_VBI_MAX+1;
1716 name_base = "vbi";
1717 break;
1718 case VFL_TYPE_RADIO:
1719 base=MINOR_VFL_TYPE_RADIO_MIN;
1720 end=MINOR_VFL_TYPE_RADIO_MAX+1;
1721 name_base = "radio";
1722 break;
1723 default:
1724 printk(KERN_ERR "%s called with unknown type: %d\n",
1725 __FUNCTION__, type);
1726 return -1;
1729 /* pick a minor number */
1730 mutex_lock(&videodev_lock);
1731 if (nr >= 0 && nr < end-base) {
1732 /* use the one the driver asked for */
1733 i = base+nr;
1734 if (NULL != video_device[i]) {
1735 mutex_unlock(&videodev_lock);
1736 return -ENFILE;
1738 } else {
1739 /* use first free */
1740 for(i=base;i<end;i++)
1741 if (NULL == video_device[i])
1742 break;
1743 if (i == end) {
1744 mutex_unlock(&videodev_lock);
1745 return -ENFILE;
1748 video_device[i]=vfd;
1749 vfd->minor=i;
1750 mutex_unlock(&videodev_lock);
1751 mutex_init(&vfd->lock);
1753 /* sysfs class */
1754 memset(&vfd->class_dev, 0x00, sizeof(vfd->class_dev));
1755 if (vfd->dev)
1756 vfd->class_dev.dev = vfd->dev;
1757 vfd->class_dev.class = &video_class;
1758 vfd->class_dev.devt = MKDEV(VIDEO_MAJOR, vfd->minor);
1759 sprintf(vfd->class_dev.class_id, "%s%d", name_base, i - base);
1760 ret = class_device_register(&vfd->class_dev);
1761 if (ret < 0) {
1762 printk(KERN_ERR "%s: class_device_register failed\n",
1763 __FUNCTION__);
1764 goto fail_minor;
1766 ret = class_device_create_file(&vfd->class_dev, &class_device_attr_name);
1767 if (ret < 0) {
1768 printk(KERN_ERR "%s: class_device_create_file 'name' failed\n",
1769 __FUNCTION__);
1770 goto fail_classdev;
1773 #if 1
1774 /* needed until all drivers are fixed */
1775 if (!vfd->release)
1776 printk(KERN_WARNING "videodev: \"%s\" has no release callback. "
1777 "Please fix your driver for proper sysfs support, see "
1778 "http://lwn.net/Articles/36850/\n", vfd->name);
1779 #endif
1780 return 0;
1782 fail_classdev:
1783 class_device_unregister(&vfd->class_dev);
1784 fail_minor:
1785 mutex_lock(&videodev_lock);
1786 video_device[vfd->minor] = NULL;
1787 vfd->minor = -1;
1788 mutex_unlock(&videodev_lock);
1789 return ret;
1793 * video_unregister_device - unregister a video4linux device
1794 * @vfd: the device to unregister
1796 * This unregisters the passed device and deassigns the minor
1797 * number. Future open calls will be met with errors.
1800 void video_unregister_device(struct video_device *vfd)
1802 mutex_lock(&videodev_lock);
1803 if(video_device[vfd->minor]!=vfd)
1804 panic("videodev: bad unregister");
1806 video_device[vfd->minor]=NULL;
1807 class_device_unregister(&vfd->class_dev);
1808 mutex_unlock(&videodev_lock);
1812 * Video fs operations
1814 static const struct file_operations video_fops=
1816 .owner = THIS_MODULE,
1817 .llseek = no_llseek,
1818 .open = video_open,
1822 * Initialise video for linux
1825 static int __init videodev_init(void)
1827 int ret;
1829 printk(KERN_INFO "Linux video capture interface: v2.00\n");
1830 if (register_chrdev(VIDEO_MAJOR, VIDEO_NAME, &video_fops)) {
1831 printk(KERN_WARNING "video_dev: unable to get major %d\n", VIDEO_MAJOR);
1832 return -EIO;
1835 ret = class_register(&video_class);
1836 if (ret < 0) {
1837 unregister_chrdev(VIDEO_MAJOR, VIDEO_NAME);
1838 printk(KERN_WARNING "video_dev: class_register failed\n");
1839 return -EIO;
1842 return 0;
1845 static void __exit videodev_exit(void)
1847 class_unregister(&video_class);
1848 unregister_chrdev(VIDEO_MAJOR, VIDEO_NAME);
1851 module_init(videodev_init)
1852 module_exit(videodev_exit)
1854 EXPORT_SYMBOL(video_register_device);
1855 EXPORT_SYMBOL(video_unregister_device);
1856 EXPORT_SYMBOL(video_devdata);
1857 EXPORT_SYMBOL(video_usercopy);
1858 EXPORT_SYMBOL(video_exclusive_open);
1859 EXPORT_SYMBOL(video_exclusive_release);
1860 EXPORT_SYMBOL(video_ioctl2);
1861 EXPORT_SYMBOL(video_device_alloc);
1862 EXPORT_SYMBOL(video_device_release);
1864 MODULE_AUTHOR("Alan Cox, Mauro Carvalho Chehab <mchehab@infradead.org>");
1865 MODULE_DESCRIPTION("Device registrar for Video4Linux drivers v2");
1866 MODULE_LICENSE("GPL");
1870 * Local variables:
1871 * c-basic-offset: 8
1872 * End: