Import 2.1.81
[davej-history.git] / drivers / char / videodev.c
blob9fd8b17f16025398977c9fd34f63f985a3484c50
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>
31 #define VIDEO_NUM_DEVICES 256
34 * Active devices
37 static struct video_device *video_device[VIDEO_NUM_DEVICES];
39 #ifdef CONFIG_VIDEO_BT848
40 extern int init_bttv_cards(struct video_init *);
41 #endif
42 #ifdef CONFIG_VIDEO_CQCAM
43 extern int init_colour_qcams(struct video_init *);
44 #endif
45 #ifdef CONFIG_VIDEO_BWQCAM
46 extern int init_bw_qcams(struct video_init *);
47 #endif
49 static struct video_init video_init_list[]={
50 #ifdef CONFIG_VIDEO_BT848
51 {"bttv", init_bttv_cards},
52 #endif
53 #ifdef CONFIG_VIDEO_CQCAM
54 {"c-qcam", init_colour_qcams},
55 #endif
56 #ifdef CONFIG_VIDEO_BWQCAM
57 {"bw-qcam", init_bw_qcams},
58 #endif
59 #ifdef CONFIG_VIDEO_PMS
60 {"PMS", init_pms_cards}, /* not defined anywhere */
61 #endif
62 {"end", NULL}
67 * Read will do some smarts later on. Buffer pin etc.
70 static ssize_t video_read(struct file *file,
71 char *buf, size_t count, loff_t *ppos)
73 struct video_device *vfl=video_device[MINOR(file->f_dentry->d_inode->i_rdev)];
74 return vfl->read(vfl, buf, count, file->f_flags&O_NONBLOCK);
78 * Write for now does nothing. No reason it shouldnt do overlay setting
79 * for some boards I guess..
82 static ssize_t video_write(struct file *file, const char *buf,
83 size_t count, loff_t *ppos)
85 struct video_device *vfl=video_device[MINOR(file->f_dentry->d_inode->i_rdev)];
86 return vfl->write(vfl, buf, count, file->f_flags&O_NONBLOCK);
90 * Open a video device.
93 static int video_open(struct inode *inode, struct file *file)
95 unsigned int minor = MINOR(inode->i_rdev);
96 int err;
97 struct video_device *vfl;
99 if(minor>=VIDEO_NUM_DEVICES)
100 return -ENODEV;
102 vfl=video_device[minor];
103 if(vfl==NULL)
104 return -ENODEV;
105 if(vfl->busy)
106 return -EBUSY;
107 vfl->busy=1; /* In case vfl->open sleeps */
109 if(vfl->open)
111 err=vfl->open(vfl,0); /* Tell the device it is open */
112 if(err)
114 vfl->busy=0;
115 return err;
118 return 0;
122 * Last close of a video for Linux device
125 static int video_release(struct inode *inode, struct file *file)
127 struct video_device *vfl=video_device[MINOR(inode->i_rdev)];
128 if(vfl->close)
129 vfl->close(vfl);
130 vfl->busy=0;
131 return 0;
135 * Question: Should we be able to capture and then seek around the
136 * image ?
139 static long long video_lseek(struct file * file,
140 long long offset, int origin)
142 return -ESPIPE;
146 static int video_ioctl(struct inode *inode, struct file *file,
147 unsigned int cmd, unsigned long arg)
149 struct video_device *vfl=video_device[MINOR(inode->i_rdev)];
150 int err=vfl->ioctl(vfl, cmd, (void *)arg);
152 if(err!=-ENOIOCTLCMD)
153 return err;
155 switch(cmd)
157 default:
158 return -EINVAL;
163 * We need to do MMAP support
167 * Video For Linux device drivers request registration here.
170 int video_register_device(struct video_device *vfd)
172 int i=0;
173 int base=0;
174 int err;
176 for(i=base;i<base+VIDEO_NUM_DEVICES;i++)
178 if(video_device[i]==NULL)
180 video_device[i]=vfd;
181 vfd->minor=i;
182 /* The init call may sleep so we book the slot out
183 then call */
184 MOD_INC_USE_COUNT;
185 err=vfd->initialize(vfd);
186 if(err<0)
188 video_device[i]=NULL;
189 MOD_DEC_USE_COUNT;
190 return err;
192 return 0;
195 return -ENFILE;
199 * Unregister an unused video for linux device
202 void video_unregister_device(struct video_device *vfd)
204 if(video_device[vfd->minor]!=vfd)
205 panic("vfd: bad unregister");
206 video_device[vfd->minor]=NULL;
207 MOD_DEC_USE_COUNT;
211 static struct file_operations video_fops=
213 video_lseek,
214 video_read,
215 video_write,
216 NULL, /* readdir */
217 NULL, /* poll */
218 video_ioctl,
219 NULL, /* mmap */
220 video_open,
221 video_release
225 * Initialise video for linux
228 int videodev_init(void)
230 struct video_init *vfli = video_init_list;
232 printk(KERN_INFO "Linux video capture interface: v0.01 ALPHA\n");
233 if(register_chrdev(VIDEO_MAJOR,"video_capture", &video_fops))
235 printk("video_dev: unable to get major %d\n", VIDEO_MAJOR);
236 return -EIO;
240 * Init kernel installed video drivers
243 while(vfli->init!=NULL)
245 vfli->init(vfli);
246 vfli++;
248 return 0;
251 #ifdef MODULE
252 int init_module(void)
254 return videodev_init();
257 void cleanup_module(void)
259 unregister_chrdev(VIDEO_MAJOR, "video_capture");
262 #endif
264 EXPORT_SYMBOL(video_register_device);
265 EXPORT_SYMBOL(video_unregister_device);