* add p cc
[mascara-docs.git] / i386 / linux / linux-2.3.21 / drivers / char / videodev.c
blobeb76d446ddd972dd35511b1fdfbf4dcba7aa7830
1 /*
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:
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>
23 #include <linux/mm.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>
30 #endif
31 #include <asm/system.h>
33 #include <linux/kmod.h>
36 #define VIDEO_NUM_DEVICES 256
39 * Active devices
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 *);
47 #endif
48 #ifdef CONFIG_VIDEO_SAA5249
49 extern int init_saa_5249(struct video_init *);
50 #endif
51 #ifdef CONFIG_VIDEO_CQCAM
52 extern int init_colour_qcams(struct video_init *);
53 #endif
54 #ifdef CONFIG_VIDEO_BWQCAM
55 extern int init_bw_qcams(struct video_init *);
56 #endif
57 #ifdef CONFIG_VIDEO_PLANB
58 extern int init_planbs(struct video_init *);
59 #endif
60 #ifdef CONFIG_RADIO_RTRACK2
61 extern int rtrack2_init(struct video_init *);
62 #endif
63 #ifdef CONFIG_RADIO_SF16FMI
64 extern int fmi_init(struct video_init *);
65 #endif
66 #ifdef CONFIG_RADIO_TYPHOON
67 extern int typhoon_init(struct video_init *);
68 #endif
69 #ifdef CONFIG_RADIO_CADET
70 extern int cadet_init(struct video_init *);
71 #endif
72 #ifdef CONFIG_RADIO_TERRATEC
73 extern int terratec_init(struct video_init *);
74 #endif
75 #ifdef CONFIG_VIDEO_ZORAN
76 extern int init_zoran_cards(struct video_init *);
77 #endif
79 static struct video_init video_init_list[]={
80 #ifdef CONFIG_VIDEO_BT848
81 {"i2c-tuner", i2c_tuner_init},
82 {"bttv", init_bttv_cards},
83 #endif
84 #ifdef CONFIG_VIDEO_SAA5249
85 {"saa5249", init_saa_5249},
86 #endif
87 #ifdef CONFIG_VIDEO_CQCAM
88 {"c-qcam", init_colour_qcams},
89 #endif
90 #ifdef CONFIG_VIDEO_BWQCAM
91 {"bw-qcam", init_bw_qcams},
92 #endif
93 #ifdef CONFIG_VIDEO_PLANB
94 {"planb", init_planbs},
95 #endif
96 #ifdef CONFIG_RADIO_RTRACK2
97 {"RTrack2", rtrack2_init},
98 #endif
99 #ifdef CONFIG_RADIO_SF16FMI
100 {"SF16FMI", fmi_init},
101 #endif
102 #ifdef CONFIG_RADIO_CADET
103 {"Cadet", cadet_init},
104 #endif
105 #ifdef CONFIG_RADIO_TYPHOON
106 {"radio-typhoon", typhoon_init},
107 #endif
108 #ifdef CONFIG_RADIO_TERRATEC
109 {"radio-terratec", terratec_init},
110 #endif
111 #ifdef CONFIG_VIDEO_ZORAN
112 {"zoran", init_zoran_cards},
113 #endif
114 {"end", NULL}
118 * Read will do some smarts later on. Buffer pin etc.
121 static ssize_t video_read(struct file *file,
122 char *buf, size_t count, loff_t *ppos)
124 struct video_device *vfl=video_device[MINOR(file->f_dentry->d_inode->i_rdev)];
125 if(vfl->read)
126 return vfl->read(vfl, buf, count, file->f_flags&O_NONBLOCK);
127 else
128 return -EINVAL;
133 * Write for now does nothing. No reason it shouldnt do overlay setting
134 * for some boards I guess..
137 static ssize_t video_write(struct file *file, const char *buf,
138 size_t count, loff_t *ppos)
140 struct video_device *vfl=video_device[MINOR(file->f_dentry->d_inode->i_rdev)];
141 if(vfl->write)
142 return vfl->write(vfl, buf, count, file->f_flags&O_NONBLOCK);
143 else
144 return 0;
148 * Poll to see if we're readable, can probably be used for timing on incoming
149 * frames, etc..
152 static unsigned int video_poll(struct file *file, poll_table * wait)
154 struct video_device *vfl=video_device[MINOR(file->f_dentry->d_inode->i_rdev)];
155 if(vfl->poll)
156 return vfl->poll(vfl, file, wait);
157 else
158 return 0;
163 * Open a video device.
166 static int video_open(struct inode *inode, struct file *file)
168 unsigned int minor = MINOR(inode->i_rdev);
169 int err;
170 struct video_device *vfl;
172 if(minor>=VIDEO_NUM_DEVICES)
173 return -ENODEV;
175 vfl=video_device[minor];
176 if(vfl==NULL) {
177 char modname[20];
179 sprintf (modname, "char-major-%d-%d", VIDEO_MAJOR, minor);
180 request_module(modname);
181 vfl=video_device[minor];
182 if (vfl==NULL)
183 return -ENODEV;
185 if(vfl->busy)
186 return -EBUSY;
187 vfl->busy=1; /* In case vfl->open sleeps */
189 if(vfl->open)
191 err=vfl->open(vfl,0); /* Tell the device it is open */
192 if(err)
194 vfl->busy=0;
195 return err;
198 return 0;
202 * Last close of a video for Linux device
205 static int video_release(struct inode *inode, struct file *file)
207 struct video_device *vfl=video_device[MINOR(inode->i_rdev)];
208 if(vfl->close)
209 vfl->close(vfl);
210 vfl->busy=0;
211 return 0;
215 * Question: Should we be able to capture and then seek around the
216 * image ?
219 #if LINUX_VERSION_CODE >= 0x020100
220 static long long video_lseek(struct file * file,
221 long long offset, int origin)
223 return -ESPIPE;
225 #else
226 static long long video_lseek(struct inode *inode, struct file * file,
227 long long offset, int origin)
229 return -ESPIPE;
231 #endif
234 static int video_ioctl(struct inode *inode, struct file *file,
235 unsigned int cmd, unsigned long arg)
237 struct video_device *vfl=video_device[MINOR(inode->i_rdev)];
238 int err=vfl->ioctl(vfl, cmd, (void *)arg);
240 if(err!=-ENOIOCTLCMD)
241 return err;
243 switch(cmd)
245 default:
246 return -EINVAL;
251 * We need to do MMAP support
255 #if LINUX_VERSION_CODE >= 0x020100
256 int video_mmap(struct file *file, struct vm_area_struct *vma)
258 struct video_device *vfl=video_device[MINOR(file->f_dentry->d_inode->i_rdev)];
259 #else
260 static int video_mmap(struct inode * ino, struct file * file,
261 struct vm_area_struct * vma)
263 struct video_device *vfl=video_device[MINOR(ino->i_rdev)];
264 #endif
265 if(vfl->mmap)
266 return vfl->mmap(vfl, (char *)vma->vm_start,
267 (unsigned long)(vma->vm_end-vma->vm_start));
268 return -EINVAL;
272 * Video For Linux device drivers request registration here.
275 int video_register_device(struct video_device *vfd, int type)
277 int i=0;
278 int base;
279 int err;
280 int end;
282 switch(type)
284 case VFL_TYPE_GRABBER:
285 base=0;
286 end=64;
287 break;
288 case VFL_TYPE_VTX:
289 base=192;
290 end=224;
291 break;
292 case VFL_TYPE_VBI:
293 base=224;
294 end=240;
295 break;
296 case VFL_TYPE_RADIO:
297 base=64;
298 end=128;
299 break;
300 default:
301 return -1;
304 for(i=base;i<end;i++)
306 if(video_device[i]==NULL)
308 video_device[i]=vfd;
309 vfd->minor=i;
310 /* The init call may sleep so we book the slot out
311 then call */
312 MOD_INC_USE_COUNT;
313 if(vfd->initialize)
315 err=vfd->initialize(vfd);
316 if(err<0)
318 video_device[i]=NULL;
319 MOD_DEC_USE_COUNT;
320 return err;
323 return 0;
326 return -ENFILE;
330 * Unregister an unused video for linux device
333 void video_unregister_device(struct video_device *vfd)
335 if(video_device[vfd->minor]!=vfd)
336 panic("vfd: bad unregister");
337 video_device[vfd->minor]=NULL;
338 MOD_DEC_USE_COUNT;
342 static struct file_operations video_fops=
344 video_lseek,
345 video_read,
346 video_write,
347 NULL, /* readdir */
348 #if LINUX_VERSION_CODE >= 0x020100
349 video_poll, /* poll */
350 #else
351 NULL,
352 #endif
353 video_ioctl,
354 video_mmap,
355 video_open,
356 #if LINUX_VERSION_CODE >= 0x020100
357 NULL, /* flush */
358 #endif
359 video_release
363 * Initialise video for linux
366 int videodev_init(void)
368 struct video_init *vfli = video_init_list;
370 printk(KERN_INFO "Linux video capture interface: v1.00\n");
371 if(register_chrdev(VIDEO_MAJOR,"video_capture", &video_fops))
373 printk("video_dev: unable to get major %d\n", VIDEO_MAJOR);
374 return -EIO;
378 * Init kernel installed video drivers
381 while(vfli->init!=NULL)
383 vfli->init(vfli);
384 vfli++;
386 return 0;
389 #ifdef MODULE
390 int init_module(void)
392 return videodev_init();
395 void cleanup_module(void)
397 unregister_chrdev(VIDEO_MAJOR, "video_capture");
406 #endif
408 #if LINUX_VERSION_CODE >= 0x020100
409 EXPORT_SYMBOL(video_register_device);
410 EXPORT_SYMBOL(video_unregister_device);
411 #endif