2 * Video capture interface for Linux
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 * Author: Alan Cox, <alan@redhat.com>
14 * Fixes: 20000516 Claudio Matsuoka <claudio@conectiva.com>
15 * - Added procfs support
18 #include <linux/config.h>
19 #include <linux/version.h>
20 #include <linux/module.h>
21 #include <linux/types.h>
22 #include <linux/kernel.h>
23 #include <linux/sched.h>
24 #include <linux/smp_lock.h>
26 #include <linux/string.h>
27 #include <linux/errno.h>
28 #include <linux/videodev.h>
29 #include <linux/init.h>
31 #include <asm/uaccess.h>
32 #include <asm/system.h>
34 #include <linux/kmod.h>
37 #define VIDEO_NUM_DEVICES 256
43 static struct video_device
*video_device
[VIDEO_NUM_DEVICES
];
46 #if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
48 #include <linux/proc_fs.h>
50 struct videodev_proc_data
{
51 struct list_head proc_list
;
53 struct video_device
*vdev
;
54 struct proc_dir_entry
*proc_entry
;
57 static struct proc_dir_entry
*video_dev_proc_entry
= NULL
;
58 struct proc_dir_entry
*video_proc_entry
= NULL
;
59 EXPORT_SYMBOL(video_proc_entry
);
60 LIST_HEAD(videodev_proc_list
);
62 #endif /* CONFIG_PROC_FS && CONFIG_VIDEO_PROC_FS */
65 #ifdef CONFIG_VIDEO_BWQCAM
66 extern int init_bw_qcams(struct video_init
*);
68 #ifdef CONFIG_VIDEO_CPIA
69 extern int cpia_init(struct video_init
*);
71 #ifdef CONFIG_VIDEO_PLANB
72 extern int init_planbs(struct video_init
*);
74 #ifdef CONFIG_VIDEO_ZORAN
75 extern int init_zoran_cards(struct video_init
*);
78 static struct video_init video_init_list
[]={
79 #ifdef CONFIG_VIDEO_BWQCAM
80 {"bw-qcam", init_bw_qcams
},
82 #ifdef CONFIG_VIDEO_CPIA
85 #ifdef CONFIG_VIDEO_PLANB
86 {"planb", init_planbs
},
88 #ifdef CONFIG_VIDEO_ZORAN
89 {"zoran", init_zoran_cards
},
95 * Read will do some smarts later on. Buffer pin etc.
98 static ssize_t
video_read(struct file
*file
,
99 char *buf
, size_t count
, loff_t
*ppos
)
101 struct video_device
*vfl
=video_device
[MINOR(file
->f_dentry
->d_inode
->i_rdev
)];
103 return vfl
->read(vfl
, buf
, count
, file
->f_flags
&O_NONBLOCK
);
110 * Write for now does nothing. No reason it shouldnt do overlay setting
111 * for some boards I guess..
114 static ssize_t
video_write(struct file
*file
, const char *buf
,
115 size_t count
, loff_t
*ppos
)
117 struct video_device
*vfl
=video_device
[MINOR(file
->f_dentry
->d_inode
->i_rdev
)];
119 return vfl
->write(vfl
, buf
, count
, file
->f_flags
&O_NONBLOCK
);
125 * Poll to see if we're readable, can probably be used for timing on incoming
129 static unsigned int video_poll(struct file
*file
, poll_table
* wait
)
131 struct video_device
*vfl
=video_device
[MINOR(file
->f_dentry
->d_inode
->i_rdev
)];
133 return vfl
->poll(vfl
, file
, wait
);
140 * Open a video device.
143 static int video_open(struct inode
*inode
, struct file
*file
)
145 unsigned int minor
= MINOR(inode
->i_rdev
);
147 struct video_device
*vfl
;
149 if(minor
>=VIDEO_NUM_DEVICES
)
152 vfl
=video_device
[minor
];
156 sprintf (modname
, "char-major-%d-%d", VIDEO_MAJOR
, minor
);
157 request_module(modname
);
158 vfl
=video_device
[minor
];
164 vfl
->busy
=1; /* In case vfl->open sleeps */
168 err
=vfl
->open(vfl
,0); /* Tell the device it is open */
179 * Last close of a video for Linux device
182 static int video_release(struct inode
*inode
, struct file
*file
)
184 struct video_device
*vfl
;
186 vfl
=video_device
[MINOR(inode
->i_rdev
)];
195 * Question: Should we be able to capture and then seek around the
199 static long long video_lseek(struct file
* file
,
200 long long offset
, int origin
)
205 static int video_ioctl(struct inode
*inode
, struct file
*file
,
206 unsigned int cmd
, unsigned long arg
)
208 struct video_device
*vfl
=video_device
[MINOR(inode
->i_rdev
)];
209 int err
=vfl
->ioctl(vfl
, cmd
, (void *)arg
);
211 if(err
!=-ENOIOCTLCMD
)
222 * We need to do MMAP support
226 int video_mmap(struct file
*file
, struct vm_area_struct
*vma
)
229 struct video_device
*vfl
=video_device
[MINOR(file
->f_dentry
->d_inode
->i_rdev
)];
232 ret
= vfl
->mmap(vfl
, (char *)vma
->vm_start
,
233 (unsigned long)(vma
->vm_end
-vma
->vm_start
));
243 #if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
245 /* Hmm... i'd like to see video_capability information here, but
246 * how can I access it (without changing the other drivers? -claudio
248 static int videodev_proc_read(char *page
, char **start
, off_t off
,
249 int count
, int *eof
, void *data
)
252 struct video_device
*vfd
= data
;
253 struct videodev_proc_data
*d
;
254 struct list_head
*tmp
;
258 list_for_each (tmp
, &videodev_proc_list
) {
259 d
= list_entry(tmp
, struct videodev_proc_data
, proc_list
);
265 if (tmp
== &videodev_proc_list
)
268 #define PRINT_VID_TYPE(x) do { if (vfd->type & x) \
269 out += sprintf (out, "%c%s", c, #x); c='|';} while (0)
271 out
+= sprintf (out
, "name : %s\n", vfd
->name
);
272 out
+= sprintf (out
, "type :");
273 PRINT_VID_TYPE(VID_TYPE_CAPTURE
);
274 PRINT_VID_TYPE(VID_TYPE_TUNER
);
275 PRINT_VID_TYPE(VID_TYPE_TELETEXT
);
276 PRINT_VID_TYPE(VID_TYPE_OVERLAY
);
277 PRINT_VID_TYPE(VID_TYPE_CHROMAKEY
);
278 PRINT_VID_TYPE(VID_TYPE_CLIPPING
);
279 PRINT_VID_TYPE(VID_TYPE_FRAMERAM
);
280 PRINT_VID_TYPE(VID_TYPE_SCALES
);
281 PRINT_VID_TYPE(VID_TYPE_MONOCHROME
);
282 PRINT_VID_TYPE(VID_TYPE_SUBCAPTURE
);
283 PRINT_VID_TYPE(VID_TYPE_MPEG_DECODER
);
284 PRINT_VID_TYPE(VID_TYPE_MPEG_ENCODER
);
285 PRINT_VID_TYPE(VID_TYPE_MJPEG_DECODER
);
286 PRINT_VID_TYPE(VID_TYPE_MJPEG_ENCODER
);
287 out
+= sprintf (out
, "\n");
288 out
+= sprintf (out
, "hardware : 0x%x\n", vfd
->hardware
);
290 out
+= sprintf (out
, "channels : %d\n", d
->vcap
.channels
);
291 out
+= sprintf (out
, "audios : %d\n", d
->vcap
.audios
);
292 out
+= sprintf (out
, "maxwidth : %d\n", d
->vcap
.maxwidth
);
293 out
+= sprintf (out
, "maxheight : %d\n", d
->vcap
.maxheight
);
294 out
+= sprintf (out
, "minwidth : %d\n", d
->vcap
.minwidth
);
295 out
+= sprintf (out
, "minheight : %d\n", d
->vcap
.minheight
);
313 static void videodev_proc_create(void)
315 video_proc_entry
= create_proc_entry("video", S_IFDIR
, &proc_root
);
317 if (video_proc_entry
== NULL
) {
318 printk("video_dev: unable to initialise /proc/video\n");
322 video_proc_entry
->owner
= THIS_MODULE
;
323 video_dev_proc_entry
= create_proc_entry("dev", S_IFDIR
, video_proc_entry
);
325 if (video_dev_proc_entry
== NULL
) {
326 printk("video_dev: unable to initialise /proc/video/dev\n");
330 video_dev_proc_entry
->owner
= THIS_MODULE
;
334 #if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
335 static void videodev_proc_destroy(void)
337 if (video_dev_proc_entry
!= NULL
)
338 remove_proc_entry("dev", video_proc_entry
);
340 if (video_proc_entry
!= NULL
)
341 remove_proc_entry("video", &proc_root
);
346 static void videodev_proc_create_dev (struct video_device
*vfd
, char *name
)
348 struct videodev_proc_data
*d
;
349 struct proc_dir_entry
*p
;
351 if (video_dev_proc_entry
== NULL
)
354 d
= kmalloc (sizeof (struct videodev_proc_data
), GFP_KERNEL
);
358 p
= create_proc_entry(name
, S_IFREG
|S_IRUGO
|S_IWUSR
, video_dev_proc_entry
);
360 p
->read_proc
= videodev_proc_read
;
364 strcpy (d
->name
, name
);
366 /* How can I get capability information ? */
368 list_add (&d
->proc_list
, &videodev_proc_list
);
371 static void videodev_proc_destroy_dev (struct video_device
*vfd
)
373 struct list_head
*tmp
;
374 struct videodev_proc_data
*d
;
376 list_for_each (tmp
, &videodev_proc_list
) {
377 d
= list_entry(tmp
, struct videodev_proc_data
, proc_list
);
378 if (vfd
== d
->vdev
) {
379 remove_proc_entry(d
->name
, video_dev_proc_entry
);
380 list_del (&d
->proc_list
);
387 #endif /* CONFIG_VIDEO_PROC_FS */
389 extern struct file_operations video_fops
;
392 * video_register_device - register video4linux devices
393 * @vfd: video device structure we want to register
394 * @type: type of device to register
395 * FIXME: needs a semaphore on 2.3.x
397 * The registration code assigns minor numbers based on the type
398 * requested. -ENFILE is returned in all the device slots for this
399 * category are full. If not then the minor field is set and the
400 * driver initialize function is called (if non %NULL).
402 * Zero is returned on success.
406 * %VFL_TYPE_GRABBER - A frame grabber
408 * %VFL_TYPE_VTX - A teletext device
410 * %VFL_TYPE_VBI - Vertical blank data (undecoded)
412 * %VFL_TYPE_RADIO - A radio card
415 int video_register_device(struct video_device
*vfd
, int type
)
425 case VFL_TYPE_GRABBER
:
449 for(i
=base
;i
<end
;i
++)
451 if(video_device
[i
]==NULL
)
457 /* The init call may sleep so we book the slot out
462 err
=vfd
->initialize(vfd
);
465 video_device
[i
]=NULL
;
470 sprintf (name
, "v4l/%s%d", name_base
, i
- base
);
472 * Start the device root only. Anything else
473 * has serious privacy issues.
476 devfs_register (NULL
, name
, DEVFS_FL_DEFAULT
,
477 VIDEO_MAJOR
, vfd
->minor
,
478 S_IFCHR
| S_IRUSR
| S_IWUSR
,
481 #if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
482 sprintf (name
, "%s%d", name_base
, i
- base
);
483 videodev_proc_create_dev (vfd
, name
);
494 * video_unregister_device - unregister a video4linux device
495 * @vfd: the device to unregister
497 * This unregisters the passed device and deassigns the minor
498 * number. Future open calls will be met with errors.
501 void video_unregister_device(struct video_device
*vfd
)
503 if(video_device
[vfd
->minor
]!=vfd
)
504 panic("vfd: bad unregister");
506 #if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
507 videodev_proc_destroy_dev (vfd
);
510 devfs_unregister (vfd
->devfs_handle
);
511 video_device
[vfd
->minor
]=NULL
;
516 static struct file_operations video_fops
=
525 release
: video_release
,
530 * Initialise video for linux
533 int __init
videodev_init(void)
535 struct video_init
*vfli
= video_init_list
;
537 printk(KERN_INFO
"Linux video capture interface: v1.00\n");
538 if(devfs_register_chrdev(VIDEO_MAJOR
,"video_capture", &video_fops
))
540 printk("video_dev: unable to get major %d\n", VIDEO_MAJOR
);
545 * Init kernel installed video drivers
548 #if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
549 videodev_proc_create ();
552 while(vfli
->init
!=NULL
)
561 int init_module(void)
563 return videodev_init();
566 void cleanup_module(void)
568 #if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
569 videodev_proc_destroy ();
572 devfs_unregister_chrdev(VIDEO_MAJOR
, "video_capture");
577 EXPORT_SYMBOL(video_register_device
);
578 EXPORT_SYMBOL(video_unregister_device
);
580 MODULE_AUTHOR("Alan Cox");
581 MODULE_DESCRIPTION("Device registrar for Video4Linux drivers");