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>
17 #include <linux/config.h>
18 #include <linux/version.h>
19 #include <linux/module.h>
20 #include <linux/types.h>
21 #include <linux/kernel.h>
22 #include <linux/sched.h>
24 #include <linux/string.h>
25 #include <linux/errno.h>
26 #include <linux/videodev.h>
28 #if LINUX_VERSION_CODE >= 0x020100
29 #include <asm/uaccess.h>
31 #include <asm/system.h>
33 #include <linux/kmod.h>
36 #define VIDEO_NUM_DEVICES 256
42 static struct video_device
*video_device
[VIDEO_NUM_DEVICES
];
44 #ifdef CONFIG_VIDEO_BT848
45 extern int init_bttv_cards(struct video_init
*);
46 extern int i2c_tuner_init(struct video_init
*);
48 #ifdef CONFIG_VIDEO_SAA5249
49 extern int init_saa_5249(struct video_init
*);
51 #ifdef CONFIG_VIDEO_CQCAM
52 extern int init_colour_qcams(struct video_init
*);
54 #ifdef CONFIG_VIDEO_BWQCAM
55 extern int init_bw_qcams(struct video_init
*);
57 #ifdef CONFIG_VIDEO_PLANB
58 extern int init_planbs(struct video_init
*);
60 #ifdef CONFIG_RADIO_AZTECH
61 extern int aztech_init(struct video_init
*);
63 #ifdef CONFIG_RADIO_RTRACK
64 extern int rtrack_init(struct video_init
*);
66 #ifdef CONFIG_RADIO_SF16FMI
67 extern int fmi_init(struct video_init
*);
69 #ifdef CONFIG_RADIO_MIROPCM20
70 extern int pcm20_init(struct video_init
*);
72 #ifdef CONFIG_RADIO_GEMTEK
73 extern int gemtek_init(struct video_init
*);
75 #ifdef CONFIG_RADIO_TYPHOON
76 extern int typhoon_init(struct video_init
*);
78 #ifdef CONFIG_RADIO_CADET
79 extern int cadet_init(struct video_init
*);
81 #ifdef CONFIG_VIDEO_PMS
82 extern int init_pms_cards(struct video_init
*);
85 static struct video_init video_init_list
[]={
86 #ifdef CONFIG_VIDEO_BT848
87 {"i2c-tuner", i2c_tuner_init
},
88 {"bttv", init_bttv_cards
},
90 #ifdef CONFIG_VIDEO_SAA5249
91 {"saa5249", init_saa_5249
},
93 #ifdef CONFIG_VIDEO_CQCAM
94 {"c-qcam", init_colour_qcams
},
96 #ifdef CONFIG_VIDEO_BWQCAM
97 {"bw-qcam", init_bw_qcams
},
99 #ifdef CONFIG_VIDEO_PMS
100 {"PMS", init_pms_cards
},
102 #ifdef CONFIG_VIDEO_PLANB
103 {"planb", init_planbs
},
105 #ifdef CONFIG_RADIO_AZTECH
106 {"Aztech", aztech_init
},
108 #ifdef CONFIG_RADIO_RTRACK
109 {"RTrack", rtrack_init
},
111 #ifdef CONFIG_RADIO_SF16FMI
112 {"SF16FMI", fmi_init
},
114 #ifdef CONFIG_RADIO_MIROPCM20
115 {"PCM20", pcm20_init
},
117 #ifdef CONFIG_RADIO_CADET
118 {"Cadet", cadet_init
},
120 #ifdef CONFIG_RADIO_GEMTEK
121 {"GemTek", gemtek_init
},
123 #ifdef CONFIG_RADIO_TYPHOON
124 {"radio-typhoon", typhoon_init
},
129 #if LINUX_VERSION_CODE >= 0x020100
131 * Read will do some smarts later on. Buffer pin etc.
134 static ssize_t
video_read(struct file
*file
,
135 char *buf
, size_t count
, loff_t
*ppos
)
137 struct video_device
*vfl
=video_device
[MINOR(file
->f_dentry
->d_inode
->i_rdev
)];
139 return vfl
->read(vfl
, buf
, count
, file
->f_flags
&O_NONBLOCK
);
147 * Write for now does nothing. No reason it shouldnt do overlay setting
148 * for some boards I guess..
151 static ssize_t
video_write(struct file
*file
, const char *buf
,
152 size_t count
, loff_t
*ppos
)
154 struct video_device
*vfl
=video_device
[MINOR(file
->f_dentry
->d_inode
->i_rdev
)];
156 return vfl
->write(vfl
, buf
, count
, file
->f_flags
&O_NONBLOCK
);
162 * Poll to see if we're readable, can probably be used for timing on incoming
166 static unsigned int video_poll(struct file
*file
, poll_table
* wait
)
168 struct video_device
*vfl
=video_device
[MINOR(file
->f_dentry
->d_inode
->i_rdev
)];
170 return vfl
->poll(vfl
, file
, wait
);
177 static int video_read(struct inode
*ino
,struct file
*file
,
178 char *buf
, int count
)
181 struct video_device
*vfl
=video_device
[MINOR(ino
->i_rdev
)];
183 return vfl
->read(vfl
, buf
, count
, file
->f_flags
&O_NONBLOCK
);
188 static int video_write(struct inode
*ino
,struct file
*file
, const char *buf
,
192 struct video_device
*vfl
=video_device
[MINOR(ino
->i_rdev
)];
194 return vfl
->write(vfl
, buf
, count
, file
->f_flags
&O_NONBLOCK
);
202 * Open a video device.
205 static int video_open(struct inode
*inode
, struct file
*file
)
207 unsigned int minor
= MINOR(inode
->i_rdev
);
209 struct video_device
*vfl
;
211 if(minor
>=VIDEO_NUM_DEVICES
)
214 vfl
=video_device
[minor
];
218 sprintf (modname
, "char-major-%d-%d", VIDEO_MAJOR
, minor
);
219 request_module(modname
);
220 vfl
=video_device
[minor
];
226 vfl
->busy
=1; /* In case vfl->open sleeps */
230 err
=vfl
->open(vfl
,0); /* Tell the device it is open */
241 * Last close of a video for Linux device
244 static int video_release(struct inode
*inode
, struct file
*file
)
246 struct video_device
*vfl
=video_device
[MINOR(inode
->i_rdev
)];
254 * Question: Should we be able to capture and then seek around the
258 #if LINUX_VERSION_CODE >= 0x020100
259 static long long video_lseek(struct file
* file
,
260 long long offset
, int origin
)
265 static long long video_lseek(struct inode
*inode
, struct file
* file
,
266 long long offset
, int origin
)
273 static int video_ioctl(struct inode
*inode
, struct file
*file
,
274 unsigned int cmd
, unsigned long arg
)
276 struct video_device
*vfl
=video_device
[MINOR(inode
->i_rdev
)];
277 int err
=vfl
->ioctl(vfl
, cmd
, (void *)arg
);
279 if(err
!=-ENOIOCTLCMD
)
290 * We need to do MMAP support
294 #if LINUX_VERSION_CODE >= 0x020100
295 int video_mmap(struct file
*file
, struct vm_area_struct
*vma
)
297 struct video_device
*vfl
=video_device
[MINOR(file
->f_dentry
->d_inode
->i_rdev
)];
299 static int video_mmap(struct inode
* ino
, struct file
* file
,
300 struct vm_area_struct
* vma
)
302 struct video_device
*vfl
=video_device
[MINOR(ino
->i_rdev
)];
305 return vfl
->mmap(vfl
, (char *)vma
->vm_start
,
306 (unsigned long)(vma
->vm_end
-vma
->vm_start
));
311 * Video For Linux device drivers request registration here.
314 int video_register_device(struct video_device
*vfd
, int type
)
323 case VFL_TYPE_GRABBER
:
343 for(i
=base
;i
<end
;i
++)
345 if(video_device
[i
]==NULL
)
349 /* The init call may sleep so we book the slot out
354 err
=vfd
->initialize(vfd
);
357 video_device
[i
]=NULL
;
369 * Unregister an unused video for linux device
372 void video_unregister_device(struct video_device
*vfd
)
374 if(video_device
[vfd
->minor
]!=vfd
)
375 panic("vfd: bad unregister");
376 video_device
[vfd
->minor
]=NULL
;
381 static struct file_operations video_fops
=
387 #if LINUX_VERSION_CODE >= 0x020100
388 video_poll
, /* poll */
395 #if LINUX_VERSION_CODE >= 0x020100
402 * Initialise video for linux
405 int videodev_init(void)
407 struct video_init
*vfli
= video_init_list
;
409 printk(KERN_INFO
"Linux video capture interface: v1.00\n");
410 if(register_chrdev(VIDEO_MAJOR
,"video_capture", &video_fops
))
412 printk("video_dev: unable to get major %d\n", VIDEO_MAJOR
);
417 * Init kernel installed video drivers
420 while(vfli
->init
!=NULL
)
429 int init_module(void)
431 return videodev_init();
434 void cleanup_module(void)
436 unregister_chrdev(VIDEO_MAJOR
, "video_capture");
447 #if LINUX_VERSION_CODE >= 0x020100
448 EXPORT_SYMBOL(video_register_device
);
449 EXPORT_SYMBOL(video_unregister_device
);