Import 2.1.118
[davej-history.git] / drivers / char / videodev.c
blob2ba0bd030ee366f7125caca64250495e36d8f09f
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@cymru.net>
14 * Fixes:
17 #include <linux/config.h>
18 #include <linux/module.h>
19 #include <linux/types.h>
20 #include <linux/kernel.h>
21 #include <linux/sched.h>
22 #include <linux/mm.h>
23 #include <linux/string.h>
24 #include <linux/errno.h>
25 #include <linux/videodev.h>
27 #include <asm/uaccess.h>
28 #include <asm/system.h>
30 #ifdef CONFIG_KMOD
31 #include <linux/kmod.h>
32 #endif
35 #define VIDEO_NUM_DEVICES 256
38 * Active devices
41 static struct video_device *video_device[VIDEO_NUM_DEVICES];
43 #ifdef CONFIG_VIDEO_BT848
44 extern int init_bttv_cards(struct video_init *);
45 extern int i2c_tuner_init(struct video_init *);
46 #endif
47 #ifdef CONFIG_VIDEO_SAA5249
48 extern int init_saa_5249(struct video_init *);
49 #endif
50 #ifdef CONFIG_VIDEO_CQCAM
51 extern int init_colour_qcams(struct video_init *);
52 #endif
53 #ifdef CONFIG_VIDEO_BWQCAM
54 extern int init_bw_qcams(struct video_init *);
55 #endif
56 #ifdef CONFIG_RADIO_AZTECH
57 extern int aztech_init(struct video_init *);
58 #endif
59 #ifdef CONFIG_RADIO_RTRACK
60 extern int rtrack_init(struct video_init *);
61 #endif
62 #ifdef CONFIG_RADIO_SF16FMI
63 extern int fmi_init(struct video_init *);
64 #endif
65 #ifdef CONFIG_RADIO_MIROPCM20
66 extern int pcm20_init(struct video_init *);
67 #endif
69 static struct video_init video_init_list[]={
70 #ifdef CONFIG_VIDEO_BT848
71 {"i2c-tuner", i2c_tuner_init},
72 {"bttv", init_bttv_cards},
73 #endif
74 #ifdef CONFIG_VIDEO_SAA5249
75 {"saa5249", init_saa_5249},
76 #endif
77 #ifdef CONFIG_VIDEO_CQCAM
78 {"c-qcam", init_colour_qcams},
79 #endif
80 #ifdef CONFIG_VIDEO_BWQCAM
81 {"bw-qcam", init_bw_qcams},
82 #endif
83 #ifdef CONFIG_VIDEO_PMS
84 {"PMS", init_pms_cards},
85 #endif
86 #ifdef CONFIG_RADIO_AZTECH
87 {"Aztech", aztech_init},
88 #endif
89 #ifdef CONFIG_RADIO_RTRACK
90 {"RTrack", rtrack_init},
91 #endif
92 #ifdef CONFIG_RADIO_SF16FMI
93 {"SF16FMI", fmi_init},
94 #endif
95 #ifdef CONFIG_RADIO_MIROPCM20
96 {"PCM20", pcm20_init},
97 #endif
98 {"end", NULL}
103 * Read will do some smarts later on. Buffer pin etc.
106 static ssize_t video_read(struct file *file,
107 char *buf, size_t count, loff_t *ppos)
109 struct video_device *vfl=video_device[MINOR(file->f_dentry->d_inode->i_rdev)];
110 if(vfl->read)
111 return vfl->read(vfl, buf, count, file->f_flags&O_NONBLOCK);
112 else
113 return -EINVAL;
118 * Write for now does nothing. No reason it shouldnt do overlay setting
119 * for some boards I guess..
122 static ssize_t video_write(struct file *file, const char *buf,
123 size_t count, loff_t *ppos)
125 struct video_device *vfl=video_device[MINOR(file->f_dentry->d_inode->i_rdev)];
126 if(vfl->write)
127 return vfl->write(vfl, buf, count, file->f_flags&O_NONBLOCK);
128 else
129 return 0;
134 * Poll to see if we're readable, can probably be used for timing on incoming
135 * frames, etc..
138 static unsigned int video_poll(struct file *file, poll_table * wait)
140 struct video_device *vfl=video_device[MINOR(file->f_dentry->d_inode->i_rdev)];
141 if(vfl->poll)
142 return vfl->poll(vfl, file, wait);
143 else
144 return 0;
148 * Open a video device.
151 static int video_open(struct inode *inode, struct file *file)
153 unsigned int minor = MINOR(inode->i_rdev);
154 int err;
155 struct video_device *vfl;
157 if(minor>=VIDEO_NUM_DEVICES)
158 return -ENODEV;
160 vfl=video_device[minor];
161 if(vfl==NULL) {
162 #ifdef CONFIG_KMOD
163 char modname[20];
165 sprintf (modname, "char-major-%d-%d", VIDEO_MAJOR, minor);
166 request_module(modname);
167 vfl=video_device[minor];
168 if (vfl==NULL)
169 #endif
170 return -ENODEV;
172 if(vfl->busy)
173 return -EBUSY;
174 vfl->busy=1; /* In case vfl->open sleeps */
176 if(vfl->open)
178 err=vfl->open(vfl,0); /* Tell the device it is open */
179 if(err)
181 vfl->busy=0;
182 return err;
185 return 0;
189 * Last close of a video for Linux device
192 static int video_release(struct inode *inode, struct file *file)
194 struct video_device *vfl=video_device[MINOR(inode->i_rdev)];
195 if(vfl->close)
196 vfl->close(vfl);
197 vfl->busy=0;
198 return 0;
202 * Question: Should we be able to capture and then seek around the
203 * image ?
206 static long long video_lseek(struct file * file,
207 long long offset, int origin)
209 return -ESPIPE;
213 static int video_ioctl(struct inode *inode, struct file *file,
214 unsigned int cmd, unsigned long arg)
216 struct video_device *vfl=video_device[MINOR(inode->i_rdev)];
217 int err=vfl->ioctl(vfl, cmd, (void *)arg);
219 if(err!=-ENOIOCTLCMD)
220 return err;
222 switch(cmd)
224 default:
225 return -EINVAL;
230 * We need to do MMAP support
234 int video_mmap(struct file *file, struct vm_area_struct *vma)
236 struct video_device *vfl=video_device[MINOR(file->f_dentry->d_inode->i_rdev)];
237 if(vfl->mmap)
238 return vfl->mmap(vfl, (char *)vma->vm_start,
239 (unsigned long)(vma->vm_end-vma->vm_start));
240 return -EINVAL;
244 * Video For Linux device drivers request registration here.
247 int video_register_device(struct video_device *vfd, int type)
249 int i=0;
250 int base;
251 int err;
252 int end;
254 switch(type)
256 case VFL_TYPE_GRABBER:
257 base=0;
258 end=64;
259 break;
260 case VFL_TYPE_VTX:
261 base=192;
262 end=224;
263 break;
264 case VFL_TYPE_VBI:
265 base=224;
266 end=240;
267 break;
268 case VFL_TYPE_RADIO:
269 base=64;
270 end=128;
271 break;
272 default:
273 return -1;
276 for(i=base;i<end;i++)
278 if(video_device[i]==NULL)
280 video_device[i]=vfd;
281 vfd->minor=i;
282 /* The init call may sleep so we book the slot out
283 then call */
284 MOD_INC_USE_COUNT;
285 if(vfd->initialize)
287 err=vfd->initialize(vfd);
288 if(err<0)
290 video_device[i]=NULL;
291 MOD_DEC_USE_COUNT;
292 return err;
295 return 0;
298 return -ENFILE;
302 * Unregister an unused video for linux device
305 void video_unregister_device(struct video_device *vfd)
307 if(video_device[vfd->minor]!=vfd)
308 panic("vfd: bad unregister");
309 video_device[vfd->minor]=NULL;
310 MOD_DEC_USE_COUNT;
314 static struct file_operations video_fops=
316 video_lseek,
317 video_read,
318 video_write,
319 NULL, /* readdir */
320 video_poll, /* poll */
321 video_ioctl,
322 video_mmap,
323 video_open,
324 NULL, /* flush */
325 video_release
329 * Initialise video for linux
332 int videodev_init(void)
334 struct video_init *vfli = video_init_list;
336 printk(KERN_INFO "Linux video capture interface: v0.01 ALPHA\n");
337 if(register_chrdev(VIDEO_MAJOR,"video_capture", &video_fops))
339 printk("video_dev: unable to get major %d\n", VIDEO_MAJOR);
340 return -EIO;
344 * Init kernel installed video drivers
347 while(vfli->init!=NULL)
349 vfli->init(vfli);
350 vfli++;
352 return 0;
355 #ifdef MODULE
356 int init_module(void)
358 return videodev_init();
361 void cleanup_module(void)
363 unregister_chrdev(VIDEO_MAJOR, "video_capture");
366 #endif
368 EXPORT_SYMBOL(video_register_device);
369 EXPORT_SYMBOL(video_unregister_device);