2 * Video capture interface for Linux version 2
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 * Authors: Alan Cox, <alan@redhat.com> (version 1)
13 * Mauro Carvalho Chehab <mchehab@infradead.org> (version 2)
15 * Fixes: 20000516 Claudio Matsuoka <claudio@conectiva.com>
16 * - Added procfs support
19 #define dbgarg(cmd, fmt, arg...) \
21 if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) { \
22 printk(KERN_DEBUG "%s: ", vfd->name); \
23 v4l_printk_ioctl(cmd); \
24 printk(" " fmt, ## arg); \
28 #define dbgarg2(fmt, arg...) \
30 if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) \
31 printk(KERN_DEBUG "%s: " fmt, vfd->name, ## arg);\
34 #include <linux/module.h>
35 #include <linux/types.h>
36 #include <linux/kernel.h>
38 #include <linux/string.h>
39 #include <linux/errno.h>
40 #include <linux/init.h>
41 #include <linux/kmod.h>
42 #include <linux/slab.h>
43 #include <linux/smp_lock.h>
44 #include <asm/uaccess.h>
45 #include <asm/system.h>
47 #define __OLD_VIDIOC_ /* To allow fixing old calls*/
48 #include <linux/videodev2.h>
50 #ifdef CONFIG_VIDEO_V4L1
51 #include <linux/videodev.h>
53 #include <media/v4l2-common.h>
54 #include <linux/video_decoder.h>
56 #define VIDEO_NUM_DEVICES 256
57 #define VIDEO_NAME "video4linux"
64 static const struct std_descr standards[] = {
65 { V4L2_STD_NTSC, "NTSC" },
66 { V4L2_STD_NTSC_M, "NTSC-M" },
67 { V4L2_STD_NTSC_M_JP, "NTSC-M-JP" },
68 { V4L2_STD_NTSC_M_KR, "NTSC-M-KR" },
69 { V4L2_STD_NTSC_443, "NTSC-443" },
70 { V4L2_STD_PAL, "PAL" },
71 { V4L2_STD_PAL_BG, "PAL-BG" },
72 { V4L2_STD_PAL_B, "PAL-B" },
73 { V4L2_STD_PAL_B1, "PAL-B1" },
74 { V4L2_STD_PAL_G, "PAL-G" },
75 { V4L2_STD_PAL_H, "PAL-H" },
76 { V4L2_STD_PAL_I, "PAL-I" },
77 { V4L2_STD_PAL_DK, "PAL-DK" },
78 { V4L2_STD_PAL_D, "PAL-D" },
79 { V4L2_STD_PAL_D1, "PAL-D1" },
80 { V4L2_STD_PAL_K, "PAL-K" },
81 { V4L2_STD_PAL_M, "PAL-M" },
82 { V4L2_STD_PAL_N, "PAL-N" },
83 { V4L2_STD_PAL_Nc, "PAL-Nc" },
84 { V4L2_STD_PAL_60, "PAL-60" },
85 { V4L2_STD_SECAM, "SECAM" },
86 { V4L2_STD_SECAM_B, "SECAM-B" },
87 { V4L2_STD_SECAM_G, "SECAM-G" },
88 { V4L2_STD_SECAM_H, "SECAM-H" },
89 { V4L2_STD_SECAM_DK, "SECAM-DK" },
90 { V4L2_STD_SECAM_D, "SECAM-D" },
91 { V4L2_STD_SECAM_K, "SECAM-K" },
92 { V4L2_STD_SECAM_K1, "SECAM-K1" },
93 { V4L2_STD_SECAM_L, "SECAM-L" },
94 { V4L2_STD_SECAM_LC, "SECAM-Lc" },
98 /* video4linux standard ID conversion to standard name
100 const char *v4l2_norm_to_name(v4l2_std_id id)
105 /* HACK: ppc32 architecture doesn't have __ucmpdi2 function to handle
106 64 bit comparations. So, on that architecture, with some gcc
107 variants, compilation fails. Currently, the max value is 30bit wide.
111 for (i = 0; standards[i].std; i++)
112 if (myid == standards[i].std)
114 return standards[i].descr;
116 EXPORT_SYMBOL(v4l2_norm_to_name);
118 /* Fill in the fields of a v4l2_standard structure according to the
119 'id' and 'transmission' parameters. Returns negative on error. */
120 int v4l2_video_std_construct(struct v4l2_standard *vs,
121 int id, const char *name)
123 u32 index = vs->index;
125 memset(vs, 0, sizeof(struct v4l2_standard));
128 if (id & V4L2_STD_525_60) {
129 vs->frameperiod.numerator = 1001;
130 vs->frameperiod.denominator = 30000;
131 vs->framelines = 525;
133 vs->frameperiod.numerator = 1;
134 vs->frameperiod.denominator = 25;
135 vs->framelines = 625;
137 strlcpy(vs->name, name, sizeof(vs->name));
140 EXPORT_SYMBOL(v4l2_video_std_construct);
142 /* ----------------------------------------------------------------- */
143 /* some arrays for pretty-printing debug messages of enum types */
145 const char *v4l2_field_names[] = {
146 [V4L2_FIELD_ANY] = "any",
147 [V4L2_FIELD_NONE] = "none",
148 [V4L2_FIELD_TOP] = "top",
149 [V4L2_FIELD_BOTTOM] = "bottom",
150 [V4L2_FIELD_INTERLACED] = "interlaced",
151 [V4L2_FIELD_SEQ_TB] = "seq-tb",
152 [V4L2_FIELD_SEQ_BT] = "seq-bt",
153 [V4L2_FIELD_ALTERNATE] = "alternate",
154 [V4L2_FIELD_INTERLACED_TB] = "interlaced-tb",
155 [V4L2_FIELD_INTERLACED_BT] = "interlaced-bt",
157 EXPORT_SYMBOL(v4l2_field_names);
159 const char *v4l2_type_names[] = {
160 [V4L2_BUF_TYPE_VIDEO_CAPTURE] = "vid-cap",
161 [V4L2_BUF_TYPE_VIDEO_OVERLAY] = "vid-overlay",
162 [V4L2_BUF_TYPE_VIDEO_OUTPUT] = "vid-out",
163 [V4L2_BUF_TYPE_VBI_CAPTURE] = "vbi-cap",
164 [V4L2_BUF_TYPE_VBI_OUTPUT] = "vbi-out",
165 [V4L2_BUF_TYPE_SLICED_VBI_CAPTURE] = "sliced-vbi-cap",
166 [V4L2_BUF_TYPE_SLICED_VBI_OUTPUT] = "sliced-vbi-out",
167 [V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY] = "vid-out-overlay",
169 EXPORT_SYMBOL(v4l2_type_names);
171 static const char *v4l2_memory_names[] = {
172 [V4L2_MEMORY_MMAP] = "mmap",
173 [V4L2_MEMORY_USERPTR] = "userptr",
174 [V4L2_MEMORY_OVERLAY] = "overlay",
177 #define prt_names(a, arr) ((((a) >= 0) && ((a) < ARRAY_SIZE(arr))) ? \
180 /* ------------------------------------------------------------------ */
181 /* debug help functions */
183 #ifdef CONFIG_VIDEO_V4L1_COMPAT
184 static const char *v4l1_ioctls[] = {
185 [_IOC_NR(VIDIOCGCAP)] = "VIDIOCGCAP",
186 [_IOC_NR(VIDIOCGCHAN)] = "VIDIOCGCHAN",
187 [_IOC_NR(VIDIOCSCHAN)] = "VIDIOCSCHAN",
188 [_IOC_NR(VIDIOCGTUNER)] = "VIDIOCGTUNER",
189 [_IOC_NR(VIDIOCSTUNER)] = "VIDIOCSTUNER",
190 [_IOC_NR(VIDIOCGPICT)] = "VIDIOCGPICT",
191 [_IOC_NR(VIDIOCSPICT)] = "VIDIOCSPICT",
192 [_IOC_NR(VIDIOCCAPTURE)] = "VIDIOCCAPTURE",
193 [_IOC_NR(VIDIOCGWIN)] = "VIDIOCGWIN",
194 [_IOC_NR(VIDIOCSWIN)] = "VIDIOCSWIN",
195 [_IOC_NR(VIDIOCGFBUF)] = "VIDIOCGFBUF",
196 [_IOC_NR(VIDIOCSFBUF)] = "VIDIOCSFBUF",
197 [_IOC_NR(VIDIOCKEY)] = "VIDIOCKEY",
198 [_IOC_NR(VIDIOCGFREQ)] = "VIDIOCGFREQ",
199 [_IOC_NR(VIDIOCSFREQ)] = "VIDIOCSFREQ",
200 [_IOC_NR(VIDIOCGAUDIO)] = "VIDIOCGAUDIO",
201 [_IOC_NR(VIDIOCSAUDIO)] = "VIDIOCSAUDIO",
202 [_IOC_NR(VIDIOCSYNC)] = "VIDIOCSYNC",
203 [_IOC_NR(VIDIOCMCAPTURE)] = "VIDIOCMCAPTURE",
204 [_IOC_NR(VIDIOCGMBUF)] = "VIDIOCGMBUF",
205 [_IOC_NR(VIDIOCGUNIT)] = "VIDIOCGUNIT",
206 [_IOC_NR(VIDIOCGCAPTURE)] = "VIDIOCGCAPTURE",
207 [_IOC_NR(VIDIOCSCAPTURE)] = "VIDIOCSCAPTURE",
208 [_IOC_NR(VIDIOCSPLAYMODE)] = "VIDIOCSPLAYMODE",
209 [_IOC_NR(VIDIOCSWRITEMODE)] = "VIDIOCSWRITEMODE",
210 [_IOC_NR(VIDIOCGPLAYINFO)] = "VIDIOCGPLAYINFO",
211 [_IOC_NR(VIDIOCSMICROCODE)] = "VIDIOCSMICROCODE",
212 [_IOC_NR(VIDIOCGVBIFMT)] = "VIDIOCGVBIFMT",
213 [_IOC_NR(VIDIOCSVBIFMT)] = "VIDIOCSVBIFMT"
215 #define V4L1_IOCTLS ARRAY_SIZE(v4l1_ioctls)
218 static const char *v4l2_ioctls[] = {
219 [_IOC_NR(VIDIOC_QUERYCAP)] = "VIDIOC_QUERYCAP",
220 [_IOC_NR(VIDIOC_RESERVED)] = "VIDIOC_RESERVED",
221 [_IOC_NR(VIDIOC_ENUM_FMT)] = "VIDIOC_ENUM_FMT",
222 [_IOC_NR(VIDIOC_G_FMT)] = "VIDIOC_G_FMT",
223 [_IOC_NR(VIDIOC_S_FMT)] = "VIDIOC_S_FMT",
224 [_IOC_NR(VIDIOC_REQBUFS)] = "VIDIOC_REQBUFS",
225 [_IOC_NR(VIDIOC_QUERYBUF)] = "VIDIOC_QUERYBUF",
226 [_IOC_NR(VIDIOC_G_FBUF)] = "VIDIOC_G_FBUF",
227 [_IOC_NR(VIDIOC_S_FBUF)] = "VIDIOC_S_FBUF",
228 [_IOC_NR(VIDIOC_OVERLAY)] = "VIDIOC_OVERLAY",
229 [_IOC_NR(VIDIOC_QBUF)] = "VIDIOC_QBUF",
230 [_IOC_NR(VIDIOC_DQBUF)] = "VIDIOC_DQBUF",
231 [_IOC_NR(VIDIOC_STREAMON)] = "VIDIOC_STREAMON",
232 [_IOC_NR(VIDIOC_STREAMOFF)] = "VIDIOC_STREAMOFF",
233 [_IOC_NR(VIDIOC_G_PARM)] = "VIDIOC_G_PARM",
234 [_IOC_NR(VIDIOC_S_PARM)] = "VIDIOC_S_PARM",
235 [_IOC_NR(VIDIOC_G_STD)] = "VIDIOC_G_STD",
236 [_IOC_NR(VIDIOC_S_STD)] = "VIDIOC_S_STD",
237 [_IOC_NR(VIDIOC_ENUMSTD)] = "VIDIOC_ENUMSTD",
238 [_IOC_NR(VIDIOC_ENUMINPUT)] = "VIDIOC_ENUMINPUT",
239 [_IOC_NR(VIDIOC_G_CTRL)] = "VIDIOC_G_CTRL",
240 [_IOC_NR(VIDIOC_S_CTRL)] = "VIDIOC_S_CTRL",
241 [_IOC_NR(VIDIOC_G_TUNER)] = "VIDIOC_G_TUNER",
242 [_IOC_NR(VIDIOC_S_TUNER)] = "VIDIOC_S_TUNER",
243 [_IOC_NR(VIDIOC_G_AUDIO)] = "VIDIOC_G_AUDIO",
244 [_IOC_NR(VIDIOC_S_AUDIO)] = "VIDIOC_S_AUDIO",
245 [_IOC_NR(VIDIOC_QUERYCTRL)] = "VIDIOC_QUERYCTRL",
246 [_IOC_NR(VIDIOC_QUERYMENU)] = "VIDIOC_QUERYMENU",
247 [_IOC_NR(VIDIOC_G_INPUT)] = "VIDIOC_G_INPUT",
248 [_IOC_NR(VIDIOC_S_INPUT)] = "VIDIOC_S_INPUT",
249 [_IOC_NR(VIDIOC_G_OUTPUT)] = "VIDIOC_G_OUTPUT",
250 [_IOC_NR(VIDIOC_S_OUTPUT)] = "VIDIOC_S_OUTPUT",
251 [_IOC_NR(VIDIOC_ENUMOUTPUT)] = "VIDIOC_ENUMOUTPUT",
252 [_IOC_NR(VIDIOC_G_AUDOUT)] = "VIDIOC_G_AUDOUT",
253 [_IOC_NR(VIDIOC_S_AUDOUT)] = "VIDIOC_S_AUDOUT",
254 [_IOC_NR(VIDIOC_G_MODULATOR)] = "VIDIOC_G_MODULATOR",
255 [_IOC_NR(VIDIOC_S_MODULATOR)] = "VIDIOC_S_MODULATOR",
256 [_IOC_NR(VIDIOC_G_FREQUENCY)] = "VIDIOC_G_FREQUENCY",
257 [_IOC_NR(VIDIOC_S_FREQUENCY)] = "VIDIOC_S_FREQUENCY",
258 [_IOC_NR(VIDIOC_CROPCAP)] = "VIDIOC_CROPCAP",
259 [_IOC_NR(VIDIOC_G_CROP)] = "VIDIOC_G_CROP",
260 [_IOC_NR(VIDIOC_S_CROP)] = "VIDIOC_S_CROP",
261 [_IOC_NR(VIDIOC_G_JPEGCOMP)] = "VIDIOC_G_JPEGCOMP",
262 [_IOC_NR(VIDIOC_S_JPEGCOMP)] = "VIDIOC_S_JPEGCOMP",
263 [_IOC_NR(VIDIOC_QUERYSTD)] = "VIDIOC_QUERYSTD",
264 [_IOC_NR(VIDIOC_TRY_FMT)] = "VIDIOC_TRY_FMT",
265 [_IOC_NR(VIDIOC_ENUMAUDIO)] = "VIDIOC_ENUMAUDIO",
266 [_IOC_NR(VIDIOC_ENUMAUDOUT)] = "VIDIOC_ENUMAUDOUT",
267 [_IOC_NR(VIDIOC_G_PRIORITY)] = "VIDIOC_G_PRIORITY",
268 [_IOC_NR(VIDIOC_S_PRIORITY)] = "VIDIOC_S_PRIORITY",
269 [_IOC_NR(VIDIOC_G_SLICED_VBI_CAP)] = "VIDIOC_G_SLICED_VBI_CAP",
270 [_IOC_NR(VIDIOC_LOG_STATUS)] = "VIDIOC_LOG_STATUS",
271 [_IOC_NR(VIDIOC_G_EXT_CTRLS)] = "VIDIOC_G_EXT_CTRLS",
272 [_IOC_NR(VIDIOC_S_EXT_CTRLS)] = "VIDIOC_S_EXT_CTRLS",
273 [_IOC_NR(VIDIOC_TRY_EXT_CTRLS)] = "VIDIOC_TRY_EXT_CTRLS",
275 [_IOC_NR(VIDIOC_ENUM_FRAMESIZES)] = "VIDIOC_ENUM_FRAMESIZES",
276 [_IOC_NR(VIDIOC_ENUM_FRAMEINTERVALS)] = "VIDIOC_ENUM_FRAMEINTERVALS",
277 [_IOC_NR(VIDIOC_G_ENC_INDEX)] = "VIDIOC_G_ENC_INDEX",
278 [_IOC_NR(VIDIOC_ENCODER_CMD)] = "VIDIOC_ENCODER_CMD",
279 [_IOC_NR(VIDIOC_TRY_ENCODER_CMD)] = "VIDIOC_TRY_ENCODER_CMD",
281 [_IOC_NR(VIDIOC_DBG_S_REGISTER)] = "VIDIOC_DBG_S_REGISTER",
282 [_IOC_NR(VIDIOC_DBG_G_REGISTER)] = "VIDIOC_DBG_G_REGISTER",
284 [_IOC_NR(VIDIOC_G_CHIP_IDENT)] = "VIDIOC_G_CHIP_IDENT",
285 [_IOC_NR(VIDIOC_S_HW_FREQ_SEEK)] = "VIDIOC_S_HW_FREQ_SEEK",
288 #define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
290 static const char *v4l2_int_ioctls[] = {
291 #ifdef CONFIG_VIDEO_V4L1_COMPAT
292 [_IOC_NR(DECODER_GET_CAPABILITIES)] = "DECODER_GET_CAPABILITIES",
293 [_IOC_NR(DECODER_GET_STATUS)] = "DECODER_GET_STATUS",
294 [_IOC_NR(DECODER_SET_NORM)] = "DECODER_SET_NORM",
295 [_IOC_NR(DECODER_SET_INPUT)] = "DECODER_SET_INPUT",
296 [_IOC_NR(DECODER_SET_OUTPUT)] = "DECODER_SET_OUTPUT",
297 [_IOC_NR(DECODER_ENABLE_OUTPUT)] = "DECODER_ENABLE_OUTPUT",
298 [_IOC_NR(DECODER_SET_PICTURE)] = "DECODER_SET_PICTURE",
299 [_IOC_NR(DECODER_SET_GPIO)] = "DECODER_SET_GPIO",
300 [_IOC_NR(DECODER_INIT)] = "DECODER_INIT",
301 [_IOC_NR(DECODER_SET_VBI_BYPASS)] = "DECODER_SET_VBI_BYPASS",
302 [_IOC_NR(DECODER_DUMP)] = "DECODER_DUMP",
304 [_IOC_NR(AUDC_SET_RADIO)] = "AUDC_SET_RADIO",
306 [_IOC_NR(TUNER_SET_TYPE_ADDR)] = "TUNER_SET_TYPE_ADDR",
307 [_IOC_NR(TUNER_SET_STANDBY)] = "TUNER_SET_STANDBY",
308 [_IOC_NR(TUNER_SET_CONFIG)] = "TUNER_SET_CONFIG",
310 [_IOC_NR(VIDIOC_INT_S_TUNER_MODE)] = "VIDIOC_INT_S_TUNER_MODE",
311 [_IOC_NR(VIDIOC_INT_RESET)] = "VIDIOC_INT_RESET",
312 [_IOC_NR(VIDIOC_INT_AUDIO_CLOCK_FREQ)] = "VIDIOC_INT_AUDIO_CLOCK_FREQ",
313 [_IOC_NR(VIDIOC_INT_DECODE_VBI_LINE)] = "VIDIOC_INT_DECODE_VBI_LINE",
314 [_IOC_NR(VIDIOC_INT_S_VBI_DATA)] = "VIDIOC_INT_S_VBI_DATA",
315 [_IOC_NR(VIDIOC_INT_G_VBI_DATA)] = "VIDIOC_INT_G_VBI_DATA",
316 [_IOC_NR(VIDIOC_INT_I2S_CLOCK_FREQ)] = "VIDIOC_INT_I2S_CLOCK_FREQ",
317 [_IOC_NR(VIDIOC_INT_S_STANDBY)] = "VIDIOC_INT_S_STANDBY",
318 [_IOC_NR(VIDIOC_INT_S_AUDIO_ROUTING)] = "VIDIOC_INT_S_AUDIO_ROUTING",
319 [_IOC_NR(VIDIOC_INT_G_AUDIO_ROUTING)] = "VIDIOC_INT_G_AUDIO_ROUTING",
320 [_IOC_NR(VIDIOC_INT_S_VIDEO_ROUTING)] = "VIDIOC_INT_S_VIDEO_ROUTING",
321 [_IOC_NR(VIDIOC_INT_G_VIDEO_ROUTING)] = "VIDIOC_INT_G_VIDEO_ROUTING",
322 [_IOC_NR(VIDIOC_INT_S_CRYSTAL_FREQ)] = "VIDIOC_INT_S_CRYSTAL_FREQ",
323 [_IOC_NR(VIDIOC_INT_INIT)] = "VIDIOC_INT_INIT",
324 [_IOC_NR(VIDIOC_INT_G_STD_OUTPUT)] = "VIDIOC_INT_G_STD_OUTPUT",
325 [_IOC_NR(VIDIOC_INT_S_STD_OUTPUT)] = "VIDIOC_INT_S_STD_OUTPUT",
327 #define V4L2_INT_IOCTLS ARRAY_SIZE(v4l2_int_ioctls)
329 /* Common ioctl debug function. This function can be used by
330 external ioctl messages as well as internal V4L ioctl */
331 void v4l_printk_ioctl(unsigned int cmd)
335 switch (_IOC_TYPE(cmd)) {
337 if (_IOC_NR(cmd) >= V4L2_INT_IOCTLS) {
341 printk("%s", v4l2_int_ioctls[_IOC_NR(cmd)]);
343 #ifdef CONFIG_VIDEO_V4L1_COMPAT
345 if (_IOC_NR(cmd) >= V4L1_IOCTLS) {
349 printk("%s", v4l1_ioctls[_IOC_NR(cmd)]);
353 if (_IOC_NR(cmd) >= V4L2_IOCTLS) {
357 printk("%s", v4l2_ioctls[_IOC_NR(cmd)]);
363 switch (_IOC_DIR(cmd)) {
364 case _IOC_NONE: dir = "--"; break;
365 case _IOC_READ: dir = "r-"; break;
366 case _IOC_WRITE: dir = "-w"; break;
367 case _IOC_READ | _IOC_WRITE: dir = "rw"; break;
368 default: dir = "*ERR*"; break;
370 printk("%s ioctl '%c', dir=%s, #%d (0x%08x)",
371 type, _IOC_TYPE(cmd), dir, _IOC_NR(cmd), cmd);
373 EXPORT_SYMBOL(v4l_printk_ioctl);
379 static ssize_t show_index(struct device *cd,
380 struct device_attribute *attr, char *buf)
382 struct video_device *vfd = container_of(cd, struct video_device,
384 return sprintf(buf, "%i\n", vfd->index);
387 static ssize_t show_name(struct device *cd,
388 struct device_attribute *attr, char *buf)
390 struct video_device *vfd = container_of(cd, struct video_device,
392 return sprintf(buf, "%.*s\n", (int)sizeof(vfd->name), vfd->name);
395 struct video_device *video_device_alloc(void)
397 struct video_device *vfd;
399 vfd = kzalloc(sizeof(*vfd),GFP_KERNEL);
402 EXPORT_SYMBOL(video_device_alloc);
404 void video_device_release(struct video_device *vfd)
408 EXPORT_SYMBOL(video_device_release);
410 static void video_release(struct device *cd)
412 struct video_device *vfd = container_of(cd, struct video_device,
416 /* needed until all drivers are fixed */
423 static struct device_attribute video_device_attrs[] = {
424 __ATTR(name, S_IRUGO, show_name, NULL),
425 __ATTR(index, S_IRUGO, show_index, NULL),
429 static struct class video_class = {
431 .dev_attrs = video_device_attrs,
432 .dev_release = video_release,
439 static struct video_device *video_device[VIDEO_NUM_DEVICES];
440 static DEFINE_MUTEX(videodev_lock);
442 struct video_device* video_devdata(struct file *file)
444 return video_device[iminor(file->f_path.dentry->d_inode)];
446 EXPORT_SYMBOL(video_devdata);
449 * Open a video device - FIXME: Obsoleted
451 static int video_open(struct inode *inode, struct file *file)
453 unsigned int minor = iminor(inode);
455 struct video_device *vfl;
456 const struct file_operations *old_fops;
458 if(minor>=VIDEO_NUM_DEVICES)
461 mutex_lock(&videodev_lock);
462 vfl=video_device[minor];
464 mutex_unlock(&videodev_lock);
465 request_module("char-major-%d-%d", VIDEO_MAJOR, minor);
466 mutex_lock(&videodev_lock);
467 vfl=video_device[minor];
469 mutex_unlock(&videodev_lock);
474 old_fops = file->f_op;
475 file->f_op = fops_get(vfl->fops);
477 err = file->f_op->open(inode,file);
479 fops_put(file->f_op);
480 file->f_op = fops_get(old_fops);
483 mutex_unlock(&videodev_lock);
489 * helper function -- handles userspace copying for ioctl arguments
494 video_fix_command(unsigned int cmd)
497 case VIDIOC_OVERLAY_OLD:
498 cmd = VIDIOC_OVERLAY;
500 case VIDIOC_S_PARM_OLD:
503 case VIDIOC_S_CTRL_OLD:
506 case VIDIOC_G_AUDIO_OLD:
507 cmd = VIDIOC_G_AUDIO;
509 case VIDIOC_G_AUDOUT_OLD:
510 cmd = VIDIOC_G_AUDOUT;
512 case VIDIOC_CROPCAP_OLD:
513 cmd = VIDIOC_CROPCAP;
521 * Obsolete usercopy function - Should be removed soon
524 video_usercopy(struct inode *inode, struct file *file,
525 unsigned int cmd, unsigned long arg,
526 int (*func)(struct inode *inode, struct file *file,
527 unsigned int cmd, void *arg))
534 size_t ctrls_size = 0;
535 void __user *user_ptr = NULL;
538 cmd = video_fix_command(cmd);
540 is_ext_ctrl = (cmd == VIDIOC_S_EXT_CTRLS || cmd == VIDIOC_G_EXT_CTRLS ||
541 cmd == VIDIOC_TRY_EXT_CTRLS);
543 /* Copy arguments into temp kernel buffer */
544 switch (_IOC_DIR(cmd)) {
550 case (_IOC_WRITE | _IOC_READ):
551 if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
554 /* too big to allocate from stack */
555 mbuf = kmalloc(_IOC_SIZE(cmd),GFP_KERNEL);
562 if (_IOC_DIR(cmd) & _IOC_WRITE)
563 if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd)))
568 struct v4l2_ext_controls *p = parg;
570 /* In case of an error, tell the caller that it wasn't
571 a specific control that caused it. */
572 p->error_idx = p->count;
573 user_ptr = (void __user *)p->controls;
575 ctrls_size = sizeof(struct v4l2_ext_control) * p->count;
576 /* Note: v4l2_ext_controls fits in sbuf[] so mbuf is still NULL. */
577 mbuf = kmalloc(ctrls_size, GFP_KERNEL);
582 if (copy_from_user(mbuf, user_ptr, ctrls_size))
589 err = func(inode, file, cmd, parg);
590 if (err == -ENOIOCTLCMD)
593 struct v4l2_ext_controls *p = parg;
595 p->controls = (void *)user_ptr;
596 if (p->count && err == 0 && copy_to_user(user_ptr, mbuf, ctrls_size))
604 /* Copy results into user buffer */
605 switch (_IOC_DIR(cmd))
608 case (_IOC_WRITE | _IOC_READ):
609 if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd)))
618 EXPORT_SYMBOL(video_usercopy);
621 * open/release helper functions -- handle exclusive opens
622 * Should be removed soon
624 int video_exclusive_open(struct inode *inode, struct file *file)
626 struct video_device *vfl = video_devdata(file);
629 mutex_lock(&vfl->lock);
635 mutex_unlock(&vfl->lock);
638 EXPORT_SYMBOL(video_exclusive_open);
640 int video_exclusive_release(struct inode *inode, struct file *file)
642 struct video_device *vfl = video_devdata(file);
647 EXPORT_SYMBOL(video_exclusive_release);
649 static void dbgbuf(unsigned int cmd, struct video_device *vfd,
650 struct v4l2_buffer *p)
652 struct v4l2_timecode *tc=&p->timecode;
654 dbgarg (cmd, "%02ld:%02d:%02d.%08ld index=%d, type=%s, "
655 "bytesused=%d, flags=0x%08d, "
656 "field=%0d, sequence=%d, memory=%s, offset/userptr=0x%08lx, length=%d\n",
657 (p->timestamp.tv_sec/3600),
658 (int)(p->timestamp.tv_sec/60)%60,
659 (int)(p->timestamp.tv_sec%60),
660 p->timestamp.tv_usec,
662 prt_names(p->type, v4l2_type_names),
663 p->bytesused, p->flags,
664 p->field, p->sequence,
665 prt_names(p->memory, v4l2_memory_names),
666 p->m.userptr, p->length);
667 dbgarg2("timecode=%02d:%02d:%02d type=%d, "
668 "flags=0x%08d, frames=%d, userbits=0x%08x\n",
669 tc->hours,tc->minutes,tc->seconds,
670 tc->type, tc->flags, tc->frames, *(__u32 *) tc->userbits);
673 static inline void dbgrect(struct video_device *vfd, char *s,
676 dbgarg2("%sRect start at %dx%d, size=%dx%d\n", s, r->left, r->top,
677 r->width, r->height);
680 static inline void v4l_print_pix_fmt (struct video_device *vfd,
681 struct v4l2_pix_format *fmt)
683 dbgarg2 ("width=%d, height=%d, format=%c%c%c%c, field=%s, "
684 "bytesperline=%d sizeimage=%d, colorspace=%d\n",
685 fmt->width,fmt->height,
686 (fmt->pixelformat & 0xff),
687 (fmt->pixelformat >> 8) & 0xff,
688 (fmt->pixelformat >> 16) & 0xff,
689 (fmt->pixelformat >> 24) & 0xff,
690 prt_names(fmt->field, v4l2_field_names),
691 fmt->bytesperline, fmt->sizeimage, fmt->colorspace);
694 static inline void v4l_print_ext_ctrls(unsigned int cmd,
695 struct video_device *vfd, struct v4l2_ext_controls *c, int show_vals)
699 if (!(vfd->debug & V4L2_DEBUG_IOCTL_ARG))
702 printk(KERN_CONT "class=0x%x", c->ctrl_class);
703 for (i = 0; i < c->count; i++) {
705 printk(KERN_CONT " id/val=0x%x/0x%x",
706 c->controls[i].id, c->controls[i].value);
708 printk(KERN_CONT " id=0x%x", c->controls[i].id);
710 printk(KERN_CONT "\n");
714 static int check_fmt (struct video_device *vfd, enum v4l2_buf_type type)
717 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
718 if (vfd->vidioc_try_fmt_vid_cap)
721 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
722 if (vfd->vidioc_try_fmt_vid_overlay)
725 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
726 if (vfd->vidioc_try_fmt_vid_out)
729 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
730 if (vfd->vidioc_try_fmt_vid_out_overlay)
733 case V4L2_BUF_TYPE_VBI_CAPTURE:
734 if (vfd->vidioc_try_fmt_vbi_cap)
737 case V4L2_BUF_TYPE_VBI_OUTPUT:
738 if (vfd->vidioc_try_fmt_vbi_out)
741 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
742 if (vfd->vidioc_try_fmt_sliced_vbi_cap)
745 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
746 if (vfd->vidioc_try_fmt_sliced_vbi_out)
749 case V4L2_BUF_TYPE_PRIVATE:
750 if (vfd->vidioc_try_fmt_type_private)
757 static int __video_do_ioctl(struct inode *inode, struct file *file,
758 unsigned int cmd, void *arg)
760 struct video_device *vfd = video_devdata(file);
761 void *fh = file->private_data;
764 if ( (vfd->debug & V4L2_DEBUG_IOCTL) &&
765 !(vfd->debug & V4L2_DEBUG_IOCTL_ARG)) {
766 v4l_print_ioctl(vfd->name, cmd);
770 #ifdef CONFIG_VIDEO_V4L1_COMPAT
771 /***********************************************************
772 Handles calls to the obsoleted V4L1 API
773 Due to the nature of VIDIOCGMBUF, each driver that supports
774 V4L1 should implement its own handler for this ioctl.
775 ***********************************************************/
777 /* --- streaming capture ------------------------------------- */
778 if (cmd == VIDIOCGMBUF) {
779 struct video_mbuf *p=arg;
781 memset(p, 0, sizeof(*p));
783 if (!vfd->vidiocgmbuf)
785 ret=vfd->vidiocgmbuf(file, fh, p);
787 dbgarg (cmd, "size=%d, frames=%d, offsets=0x%08lx\n",
789 (unsigned long)p->offsets);
793 /********************************************************
794 All other V4L1 calls are handled by v4l1_compat module.
795 Those calls will be translated into V4L2 calls, and
796 __video_do_ioctl will be called again, with one or more
798 ********************************************************/
799 if (_IOC_TYPE(cmd)=='v')
800 return v4l_compat_translate_ioctl(inode,file,cmd,arg,
805 /* --- capabilities ------------------------------------------ */
806 case VIDIOC_QUERYCAP:
808 struct v4l2_capability *cap = (struct v4l2_capability*)arg;
809 memset(cap, 0, sizeof(*cap));
811 if (!vfd->vidioc_querycap)
814 ret=vfd->vidioc_querycap(file, fh, cap);
816 dbgarg (cmd, "driver=%s, card=%s, bus=%s, "
818 "capabilities=0x%08x\n",
819 cap->driver,cap->card,cap->bus_info,
825 /* --- priority ------------------------------------------ */
826 case VIDIOC_G_PRIORITY:
828 enum v4l2_priority *p=arg;
830 if (!vfd->vidioc_g_priority)
832 ret=vfd->vidioc_g_priority(file, fh, p);
834 dbgarg(cmd, "priority is %d\n", *p);
837 case VIDIOC_S_PRIORITY:
839 enum v4l2_priority *p=arg;
841 if (!vfd->vidioc_s_priority)
843 dbgarg(cmd, "setting priority to %d\n", *p);
844 ret=vfd->vidioc_s_priority(file, fh, *p);
848 /* --- capture ioctls ---------------------------------------- */
849 case VIDIOC_ENUM_FMT:
851 struct v4l2_fmtdesc *f = arg;
852 enum v4l2_buf_type type;
857 memset(f,0,sizeof(*f));
862 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
863 if (vfd->vidioc_enum_fmt_vid_cap)
864 ret = vfd->vidioc_enum_fmt_vid_cap(file, fh, f);
866 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
867 if (vfd->vidioc_enum_fmt_vid_overlay)
868 ret = vfd->vidioc_enum_fmt_vid_overlay(file,
872 /* V4L2_BUF_TYPE_VBI_CAPTURE should not support VIDIOC_ENUM_FMT
873 * according to the spec. The bttv and saa7134 drivers support
874 * it though, so just warn that this is deprecated and will be
875 * removed in the near future. */
876 case V4L2_BUF_TYPE_VBI_CAPTURE:
877 if (vfd->vidioc_enum_fmt_vbi_cap) {
878 printk(KERN_WARNING "vidioc_enum_fmt_vbi_cap will be removed in 2.6.28!\n");
879 ret = vfd->vidioc_enum_fmt_vbi_cap(file, fh, f);
883 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
884 if (vfd->vidioc_enum_fmt_vid_out)
885 ret = vfd->vidioc_enum_fmt_vid_out(file, fh, f);
887 case V4L2_BUF_TYPE_PRIVATE:
888 if (vfd->vidioc_enum_fmt_type_private)
889 ret = vfd->vidioc_enum_fmt_type_private(file,
896 dbgarg (cmd, "index=%d, type=%d, flags=%d, "
897 "pixelformat=%c%c%c%c, description='%s'\n",
898 f->index, f->type, f->flags,
899 (f->pixelformat & 0xff),
900 (f->pixelformat >> 8) & 0xff,
901 (f->pixelformat >> 16) & 0xff,
902 (f->pixelformat >> 24) & 0xff,
908 struct v4l2_format *f = (struct v4l2_format *)arg;
910 memset(f->fmt.raw_data, 0, sizeof(f->fmt.raw_data));
912 /* FIXME: Should be one dump per type */
913 dbgarg(cmd, "type=%s\n", prt_names(f->type, v4l2_type_names));
916 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
917 if (vfd->vidioc_g_fmt_vid_cap)
918 ret = vfd->vidioc_g_fmt_vid_cap(file, fh, f);
920 v4l_print_pix_fmt(vfd, &f->fmt.pix);
922 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
923 if (vfd->vidioc_g_fmt_vid_overlay)
924 ret = vfd->vidioc_g_fmt_vid_overlay(file,
927 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
928 if (vfd->vidioc_g_fmt_vid_out)
929 ret = vfd->vidioc_g_fmt_vid_out(file, fh, f);
931 v4l_print_pix_fmt(vfd, &f->fmt.pix);
933 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
934 if (vfd->vidioc_g_fmt_vid_out_overlay)
935 ret = vfd->vidioc_g_fmt_vid_out_overlay(file,
938 case V4L2_BUF_TYPE_VBI_CAPTURE:
939 if (vfd->vidioc_g_fmt_vbi_cap)
940 ret = vfd->vidioc_g_fmt_vbi_cap(file, fh, f);
942 case V4L2_BUF_TYPE_VBI_OUTPUT:
943 if (vfd->vidioc_g_fmt_vbi_out)
944 ret = vfd->vidioc_g_fmt_vbi_out(file, fh, f);
946 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
947 if (vfd->vidioc_g_fmt_sliced_vbi_cap)
948 ret = vfd->vidioc_g_fmt_sliced_vbi_cap(file,
951 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
952 if (vfd->vidioc_g_fmt_sliced_vbi_out)
953 ret = vfd->vidioc_g_fmt_sliced_vbi_out(file,
956 case V4L2_BUF_TYPE_PRIVATE:
957 if (vfd->vidioc_g_fmt_type_private)
958 ret = vfd->vidioc_g_fmt_type_private(file,
967 struct v4l2_format *f = (struct v4l2_format *)arg;
969 /* FIXME: Should be one dump per type */
970 dbgarg(cmd, "type=%s\n", prt_names(f->type, v4l2_type_names));
973 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
974 v4l_print_pix_fmt(vfd, &f->fmt.pix);
975 if (vfd->vidioc_s_fmt_vid_cap)
976 ret = vfd->vidioc_s_fmt_vid_cap(file, fh, f);
978 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
979 if (vfd->vidioc_s_fmt_vid_overlay)
980 ret = vfd->vidioc_s_fmt_vid_overlay(file,
983 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
984 v4l_print_pix_fmt(vfd, &f->fmt.pix);
985 if (vfd->vidioc_s_fmt_vid_out)
986 ret = vfd->vidioc_s_fmt_vid_out(file, fh, f);
988 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
989 if (vfd->vidioc_s_fmt_vid_out_overlay)
990 ret = vfd->vidioc_s_fmt_vid_out_overlay(file,
993 case V4L2_BUF_TYPE_VBI_CAPTURE:
994 if (vfd->vidioc_s_fmt_vbi_cap)
995 ret = vfd->vidioc_s_fmt_vbi_cap(file, fh, f);
997 case V4L2_BUF_TYPE_VBI_OUTPUT:
998 if (vfd->vidioc_s_fmt_vbi_out)
999 ret = vfd->vidioc_s_fmt_vbi_out(file, fh, f);
1001 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
1002 if (vfd->vidioc_s_fmt_sliced_vbi_cap)
1003 ret = vfd->vidioc_s_fmt_sliced_vbi_cap(file,
1006 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
1007 if (vfd->vidioc_s_fmt_sliced_vbi_out)
1008 ret = vfd->vidioc_s_fmt_sliced_vbi_out(file,
1011 case V4L2_BUF_TYPE_PRIVATE:
1012 if (vfd->vidioc_s_fmt_type_private)
1013 ret = vfd->vidioc_s_fmt_type_private(file,
1019 case VIDIOC_TRY_FMT:
1021 struct v4l2_format *f = (struct v4l2_format *)arg;
1023 /* FIXME: Should be one dump per type */
1024 dbgarg (cmd, "type=%s\n", prt_names(f->type,
1027 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1028 if (vfd->vidioc_try_fmt_vid_cap)
1029 ret = vfd->vidioc_try_fmt_vid_cap(file, fh, f);
1031 v4l_print_pix_fmt(vfd, &f->fmt.pix);
1033 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
1034 if (vfd->vidioc_try_fmt_vid_overlay)
1035 ret = vfd->vidioc_try_fmt_vid_overlay(file,
1038 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
1039 if (vfd->vidioc_try_fmt_vid_out)
1040 ret = vfd->vidioc_try_fmt_vid_out(file, fh, f);
1042 v4l_print_pix_fmt(vfd, &f->fmt.pix);
1044 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
1045 if (vfd->vidioc_try_fmt_vid_out_overlay)
1046 ret = vfd->vidioc_try_fmt_vid_out_overlay(file,
1049 case V4L2_BUF_TYPE_VBI_CAPTURE:
1050 if (vfd->vidioc_try_fmt_vbi_cap)
1051 ret = vfd->vidioc_try_fmt_vbi_cap(file, fh, f);
1053 case V4L2_BUF_TYPE_VBI_OUTPUT:
1054 if (vfd->vidioc_try_fmt_vbi_out)
1055 ret = vfd->vidioc_try_fmt_vbi_out(file, fh, f);
1057 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
1058 if (vfd->vidioc_try_fmt_sliced_vbi_cap)
1059 ret = vfd->vidioc_try_fmt_sliced_vbi_cap(file,
1062 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
1063 if (vfd->vidioc_try_fmt_sliced_vbi_out)
1064 ret = vfd->vidioc_try_fmt_sliced_vbi_out(file,
1067 case V4L2_BUF_TYPE_PRIVATE:
1068 if (vfd->vidioc_try_fmt_type_private)
1069 ret = vfd->vidioc_try_fmt_type_private(file,
1076 /* FIXME: Those buf reqs could be handled here,
1077 with some changes on videobuf to allow its header to be included at
1078 videodev2.h or being merged at videodev2.
1080 case VIDIOC_REQBUFS:
1082 struct v4l2_requestbuffers *p=arg;
1084 if (!vfd->vidioc_reqbufs)
1086 ret = check_fmt (vfd, p->type);
1090 ret=vfd->vidioc_reqbufs(file, fh, p);
1091 dbgarg (cmd, "count=%d, type=%s, memory=%s\n",
1093 prt_names(p->type, v4l2_type_names),
1094 prt_names(p->memory, v4l2_memory_names));
1097 case VIDIOC_QUERYBUF:
1099 struct v4l2_buffer *p=arg;
1101 if (!vfd->vidioc_querybuf)
1103 ret = check_fmt (vfd, p->type);
1107 ret=vfd->vidioc_querybuf(file, fh, p);
1114 struct v4l2_buffer *p=arg;
1116 if (!vfd->vidioc_qbuf)
1118 ret = check_fmt (vfd, p->type);
1122 ret=vfd->vidioc_qbuf(file, fh, p);
1129 struct v4l2_buffer *p=arg;
1130 if (!vfd->vidioc_dqbuf)
1132 ret = check_fmt (vfd, p->type);
1136 ret=vfd->vidioc_dqbuf(file, fh, p);
1141 case VIDIOC_OVERLAY:
1145 if (!vfd->vidioc_overlay)
1147 dbgarg (cmd, "value=%d\n",*i);
1148 ret=vfd->vidioc_overlay(file, fh, *i);
1153 struct v4l2_framebuffer *p = arg;
1155 if (!vfd->vidioc_g_fbuf)
1157 ret = vfd->vidioc_g_fbuf(file, fh, arg);
1159 dbgarg(cmd, "capability=0x%x, flags=%d, base=0x%08lx\n",
1160 p->capability, p->flags,
1161 (unsigned long)p->base);
1162 v4l_print_pix_fmt(vfd, &p->fmt);
1168 struct v4l2_framebuffer *p = arg;
1170 if (!vfd->vidioc_s_fbuf)
1172 dbgarg(cmd, "capability=0x%x, flags=%d, base=0x%08lx\n",
1173 p->capability, p->flags, (unsigned long)p->base);
1174 v4l_print_pix_fmt(vfd, &p->fmt);
1175 ret = vfd->vidioc_s_fbuf(file, fh, arg);
1178 case VIDIOC_STREAMON:
1180 enum v4l2_buf_type i = *(int *)arg;
1181 if (!vfd->vidioc_streamon)
1183 dbgarg(cmd, "type=%s\n", prt_names(i, v4l2_type_names));
1184 ret=vfd->vidioc_streamon(file, fh,i);
1187 case VIDIOC_STREAMOFF:
1189 enum v4l2_buf_type i = *(int *)arg;
1191 if (!vfd->vidioc_streamoff)
1193 dbgarg(cmd, "type=%s\n", prt_names(i, v4l2_type_names));
1194 ret=vfd->vidioc_streamoff(file, fh, i);
1197 /* ---------- tv norms ---------- */
1198 case VIDIOC_ENUMSTD:
1200 struct v4l2_standard *p = arg;
1201 v4l2_std_id id = vfd->tvnorms, curr_id = 0;
1202 unsigned int index = p->index, i, j = 0;
1203 const char *descr = "";
1205 /* Return norm array in a canonical way */
1206 for (i = 0; i <= index && id; i++) {
1207 /* last std value in the standards array is 0, so this
1208 while always ends there since (id & 0) == 0. */
1209 while ((id & standards[j].std) != standards[j].std)
1211 curr_id = standards[j].std;
1212 descr = standards[j].descr;
1216 if (curr_id != V4L2_STD_PAL &&
1217 curr_id != V4L2_STD_SECAM &&
1218 curr_id != V4L2_STD_NTSC)
1224 v4l2_video_std_construct(p, curr_id, descr);
1227 dbgarg(cmd, "index=%d, id=0x%Lx, name=%s, fps=%d/%d, "
1228 "framelines=%d\n", p->index,
1229 (unsigned long long)p->id, p->name,
1230 p->frameperiod.numerator,
1231 p->frameperiod.denominator,
1239 v4l2_std_id *id = arg;
1242 /* Calls the specific handler */
1243 if (vfd->vidioc_g_std)
1244 ret = vfd->vidioc_g_std(file, fh, id);
1246 *id = vfd->current_norm;
1249 dbgarg(cmd, "std=0x%08Lx\n", (long long unsigned)*id);
1254 v4l2_std_id *id = arg,norm;
1256 dbgarg(cmd, "std=%08Lx\n", (long long unsigned)*id);
1258 norm = (*id) & vfd->tvnorms;
1259 if ( vfd->tvnorms && !norm) /* Check if std is supported */
1262 /* Calls the specific handler */
1263 if (vfd->vidioc_s_std)
1264 ret=vfd->vidioc_s_std(file, fh, &norm);
1268 /* Updates standard information */
1270 vfd->current_norm=norm;
1274 case VIDIOC_QUERYSTD:
1278 if (!vfd->vidioc_querystd)
1280 ret=vfd->vidioc_querystd(file, fh, arg);
1282 dbgarg (cmd, "detected std=%08Lx\n",
1283 (unsigned long long)*p);
1286 /* ------ input switching ---------- */
1287 /* FIXME: Inputs can be handled inside videodev2 */
1288 case VIDIOC_ENUMINPUT:
1290 struct v4l2_input *p=arg;
1293 if (!vfd->vidioc_enum_input)
1295 memset(p, 0, sizeof(*p));
1298 ret=vfd->vidioc_enum_input(file, fh, p);
1300 dbgarg (cmd, "index=%d, name=%s, type=%d, "
1302 "tuner=%d, std=%08Lx, status=%d\n",
1303 p->index,p->name,p->type,p->audioset,
1305 (unsigned long long)p->std,
1309 case VIDIOC_G_INPUT:
1311 unsigned int *i = arg;
1313 if (!vfd->vidioc_g_input)
1315 ret=vfd->vidioc_g_input(file, fh, i);
1317 dbgarg (cmd, "value=%d\n",*i);
1320 case VIDIOC_S_INPUT:
1322 unsigned int *i = arg;
1324 if (!vfd->vidioc_s_input)
1326 dbgarg (cmd, "value=%d\n",*i);
1327 ret=vfd->vidioc_s_input(file, fh, *i);
1331 /* ------ output switching ---------- */
1332 case VIDIOC_ENUMOUTPUT:
1334 struct v4l2_output *p = arg;
1337 if (!vfd->vidioc_enum_output)
1339 memset(p, 0, sizeof(*p));
1342 ret = vfd->vidioc_enum_output(file, fh, p);
1344 dbgarg(cmd, "index=%d, name=%s, type=%d, "
1346 "modulator=%d, std=0x%08Lx\n",
1347 p->index, p->name, p->type, p->audioset,
1348 p->modulator, (unsigned long long)p->std);
1351 case VIDIOC_G_OUTPUT:
1353 unsigned int *i = arg;
1355 if (!vfd->vidioc_g_output)
1357 ret=vfd->vidioc_g_output(file, fh, i);
1359 dbgarg (cmd, "value=%d\n",*i);
1362 case VIDIOC_S_OUTPUT:
1364 unsigned int *i = arg;
1366 if (!vfd->vidioc_s_output)
1368 dbgarg (cmd, "value=%d\n",*i);
1369 ret=vfd->vidioc_s_output(file, fh, *i);
1373 /* --- controls ---------------------------------------------- */
1374 case VIDIOC_QUERYCTRL:
1376 struct v4l2_queryctrl *p = arg;
1378 if (!vfd->vidioc_queryctrl)
1380 ret = vfd->vidioc_queryctrl(file, fh, p);
1382 dbgarg(cmd, "id=0x%x, type=%d, name=%s, min/max=%d/%d, "
1383 "step=%d, default=%d, flags=0x%08x\n",
1384 p->id, p->type, p->name,
1385 p->minimum, p->maximum,
1386 p->step, p->default_value, p->flags);
1388 dbgarg(cmd, "id=0x%x\n", p->id);
1393 struct v4l2_control *p = arg;
1395 if (!vfd->vidioc_g_ctrl)
1398 ret = vfd->vidioc_g_ctrl(file, fh, p);
1400 dbgarg(cmd, "id=0x%x, value=%d\n", p->id, p->value);
1402 dbgarg(cmd, "id=0x%x\n", p->id);
1407 struct v4l2_control *p = arg;
1409 if (!vfd->vidioc_s_ctrl)
1411 dbgarg(cmd, "id=0x%x, value=%d\n", p->id, p->value);
1413 ret = vfd->vidioc_s_ctrl(file, fh, p);
1416 case VIDIOC_G_EXT_CTRLS:
1418 struct v4l2_ext_controls *p = arg;
1420 if (!vfd->vidioc_g_ext_ctrls)
1422 ret = vfd->vidioc_g_ext_ctrls(file, fh, p);
1423 v4l_print_ext_ctrls(cmd, vfd, p, !ret);
1426 case VIDIOC_S_EXT_CTRLS:
1428 struct v4l2_ext_controls *p = arg;
1430 if (vfd->vidioc_s_ext_ctrls) {
1431 v4l_print_ext_ctrls(cmd, vfd, p, 1);
1433 ret = vfd->vidioc_s_ext_ctrls(file, fh, p);
1437 case VIDIOC_TRY_EXT_CTRLS:
1439 struct v4l2_ext_controls *p = arg;
1441 if (vfd->vidioc_try_ext_ctrls) {
1442 v4l_print_ext_ctrls(cmd, vfd, p, 1);
1444 ret = vfd->vidioc_try_ext_ctrls(file, fh, p);
1448 case VIDIOC_QUERYMENU:
1450 struct v4l2_querymenu *p = arg;
1452 if (!vfd->vidioc_querymenu)
1454 ret = vfd->vidioc_querymenu(file, fh, p);
1456 dbgarg(cmd, "id=0x%x, index=%d, name=%s\n",
1457 p->id, p->index, p->name);
1459 dbgarg(cmd, "id=0x%x, index=%d\n",
1463 /* --- audio ---------------------------------------------- */
1464 case VIDIOC_ENUMAUDIO:
1466 struct v4l2_audio *p = arg;
1468 if (!vfd->vidioc_enumaudio)
1470 ret = vfd->vidioc_enumaudio(file, fh, p);
1472 dbgarg(cmd, "index=%d, name=%s, capability=0x%x, "
1473 "mode=0x%x\n", p->index, p->name,
1474 p->capability, p->mode);
1476 dbgarg(cmd, "index=%d\n", p->index);
1479 case VIDIOC_G_AUDIO:
1481 struct v4l2_audio *p = arg;
1482 __u32 index = p->index;
1484 if (!vfd->vidioc_g_audio)
1487 memset(p, 0, sizeof(*p));
1489 ret = vfd->vidioc_g_audio(file, fh, p);
1491 dbgarg(cmd, "index=%d, name=%s, capability=0x%x, "
1492 "mode=0x%x\n", p->index,
1493 p->name, p->capability, p->mode);
1495 dbgarg(cmd, "index=%d\n", p->index);
1498 case VIDIOC_S_AUDIO:
1500 struct v4l2_audio *p = arg;
1502 if (!vfd->vidioc_s_audio)
1504 dbgarg(cmd, "index=%d, name=%s, capability=0x%x, "
1505 "mode=0x%x\n", p->index, p->name,
1506 p->capability, p->mode);
1507 ret = vfd->vidioc_s_audio(file, fh, p);
1510 case VIDIOC_ENUMAUDOUT:
1512 struct v4l2_audioout *p=arg;
1514 if (!vfd->vidioc_enumaudout)
1516 dbgarg(cmd, "Enum for index=%d\n", p->index);
1517 ret=vfd->vidioc_enumaudout(file, fh, p);
1519 dbgarg2("index=%d, name=%s, capability=%d, "
1520 "mode=%d\n", p->index, p->name,
1521 p->capability,p->mode);
1524 case VIDIOC_G_AUDOUT:
1526 struct v4l2_audioout *p=arg;
1528 if (!vfd->vidioc_g_audout)
1530 dbgarg(cmd, "Enum for index=%d\n", p->index);
1531 ret=vfd->vidioc_g_audout(file, fh, p);
1533 dbgarg2("index=%d, name=%s, capability=%d, "
1534 "mode=%d\n", p->index, p->name,
1535 p->capability,p->mode);
1538 case VIDIOC_S_AUDOUT:
1540 struct v4l2_audioout *p=arg;
1542 if (!vfd->vidioc_s_audout)
1544 dbgarg(cmd, "index=%d, name=%s, capability=%d, "
1545 "mode=%d\n", p->index, p->name,
1546 p->capability,p->mode);
1548 ret=vfd->vidioc_s_audout(file, fh, p);
1551 case VIDIOC_G_MODULATOR:
1553 struct v4l2_modulator *p=arg;
1554 if (!vfd->vidioc_g_modulator)
1556 ret=vfd->vidioc_g_modulator(file, fh, p);
1558 dbgarg(cmd, "index=%d, name=%s, "
1559 "capability=%d, rangelow=%d,"
1560 " rangehigh=%d, txsubchans=%d\n",
1561 p->index, p->name,p->capability,
1562 p->rangelow, p->rangehigh,
1566 case VIDIOC_S_MODULATOR:
1568 struct v4l2_modulator *p=arg;
1569 if (!vfd->vidioc_s_modulator)
1571 dbgarg(cmd, "index=%d, name=%s, capability=%d, "
1572 "rangelow=%d, rangehigh=%d, txsubchans=%d\n",
1573 p->index, p->name,p->capability,p->rangelow,
1574 p->rangehigh,p->txsubchans);
1575 ret=vfd->vidioc_s_modulator(file, fh, p);
1580 struct v4l2_crop *p=arg;
1581 if (!vfd->vidioc_g_crop)
1583 dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names));
1584 ret=vfd->vidioc_g_crop(file, fh, p);
1586 dbgrect(vfd, "", &p->c);
1592 struct v4l2_crop *p=arg;
1593 if (!vfd->vidioc_s_crop)
1595 dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names));
1596 dbgrect(vfd, "", &p->c);
1597 ret=vfd->vidioc_s_crop(file, fh, p);
1600 case VIDIOC_CROPCAP:
1602 struct v4l2_cropcap *p = arg;
1604 /*FIXME: Should also show v4l2_fract pixelaspect */
1605 if (!vfd->vidioc_cropcap)
1607 dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names));
1608 ret = vfd->vidioc_cropcap(file, fh, p);
1610 dbgrect(vfd, "bounds ", &p->bounds);
1611 dbgrect(vfd, "defrect ", &p->defrect);
1615 case VIDIOC_G_JPEGCOMP:
1617 struct v4l2_jpegcompression *p=arg;
1618 if (!vfd->vidioc_g_jpegcomp)
1620 ret=vfd->vidioc_g_jpegcomp(file, fh, p);
1622 dbgarg (cmd, "quality=%d, APPn=%d, "
1623 "APP_len=%d, COM_len=%d, "
1624 "jpeg_markers=%d\n",
1625 p->quality,p->APPn,p->APP_len,
1626 p->COM_len,p->jpeg_markers);
1629 case VIDIOC_S_JPEGCOMP:
1631 struct v4l2_jpegcompression *p=arg;
1632 if (!vfd->vidioc_g_jpegcomp)
1634 dbgarg (cmd, "quality=%d, APPn=%d, APP_len=%d, "
1635 "COM_len=%d, jpeg_markers=%d\n",
1636 p->quality,p->APPn,p->APP_len,
1637 p->COM_len,p->jpeg_markers);
1638 ret=vfd->vidioc_s_jpegcomp(file, fh, p);
1641 case VIDIOC_G_ENC_INDEX:
1643 struct v4l2_enc_idx *p=arg;
1645 if (!vfd->vidioc_g_enc_index)
1647 ret=vfd->vidioc_g_enc_index(file, fh, p);
1649 dbgarg (cmd, "entries=%d, entries_cap=%d\n",
1650 p->entries,p->entries_cap);
1653 case VIDIOC_ENCODER_CMD:
1655 struct v4l2_encoder_cmd *p = arg;
1657 if (!vfd->vidioc_encoder_cmd)
1659 memset(&p->raw, 0, sizeof(p->raw));
1660 ret = vfd->vidioc_encoder_cmd(file, fh, p);
1662 dbgarg(cmd, "cmd=%d, flags=%x\n", p->cmd, p->flags);
1665 case VIDIOC_TRY_ENCODER_CMD:
1667 struct v4l2_encoder_cmd *p = arg;
1669 if (!vfd->vidioc_try_encoder_cmd)
1671 memset(&p->raw, 0, sizeof(p->raw));
1672 ret = vfd->vidioc_try_encoder_cmd(file, fh, p);
1674 dbgarg(cmd, "cmd=%d, flags=%x\n", p->cmd, p->flags);
1679 struct v4l2_streamparm *p=arg;
1682 memset(p,0,sizeof(*p));
1685 if (vfd->vidioc_g_parm) {
1686 ret=vfd->vidioc_g_parm(file, fh, p);
1688 struct v4l2_standard s;
1690 if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1693 v4l2_video_std_construct(&s, vfd->current_norm,
1694 v4l2_norm_to_name(vfd->current_norm));
1696 p->parm.capture.timeperframe = s.frameperiod;
1700 dbgarg (cmd, "type=%d\n", p->type);
1705 struct v4l2_streamparm *p=arg;
1706 if (!vfd->vidioc_s_parm)
1708 dbgarg (cmd, "type=%d\n", p->type);
1709 ret=vfd->vidioc_s_parm(file, fh, p);
1712 case VIDIOC_G_TUNER:
1714 struct v4l2_tuner *p = arg;
1715 __u32 index = p->index;
1717 if (!vfd->vidioc_g_tuner)
1720 memset(p, 0, sizeof(*p));
1723 ret = vfd->vidioc_g_tuner(file, fh, p);
1725 dbgarg(cmd, "index=%d, name=%s, type=%d, "
1726 "capability=0x%x, rangelow=%d, "
1727 "rangehigh=%d, signal=%d, afc=%d, "
1728 "rxsubchans=0x%x, audmode=%d\n",
1729 p->index, p->name, p->type,
1730 p->capability, p->rangelow,
1731 p->rangehigh, p->signal, p->afc,
1732 p->rxsubchans, p->audmode);
1735 case VIDIOC_S_TUNER:
1737 struct v4l2_tuner *p = arg;
1739 if (!vfd->vidioc_s_tuner)
1741 dbgarg(cmd, "index=%d, name=%s, type=%d, "
1742 "capability=0x%x, rangelow=%d, "
1743 "rangehigh=%d, signal=%d, afc=%d, "
1744 "rxsubchans=0x%x, audmode=%d\n",
1745 p->index, p->name, p->type,
1746 p->capability, p->rangelow,
1747 p->rangehigh, p->signal, p->afc,
1748 p->rxsubchans, p->audmode);
1749 ret = vfd->vidioc_s_tuner(file, fh, p);
1752 case VIDIOC_G_FREQUENCY:
1754 struct v4l2_frequency *p = arg;
1756 if (!vfd->vidioc_g_frequency)
1759 memset(p->reserved, 0, sizeof(p->reserved));
1761 ret = vfd->vidioc_g_frequency(file, fh, p);
1763 dbgarg(cmd, "tuner=%d, type=%d, frequency=%d\n",
1764 p->tuner, p->type, p->frequency);
1767 case VIDIOC_S_FREQUENCY:
1769 struct v4l2_frequency *p=arg;
1770 if (!vfd->vidioc_s_frequency)
1772 dbgarg (cmd, "tuner=%d, type=%d, frequency=%d\n",
1773 p->tuner,p->type,p->frequency);
1774 ret=vfd->vidioc_s_frequency(file, fh, p);
1777 case VIDIOC_G_SLICED_VBI_CAP:
1779 struct v4l2_sliced_vbi_cap *p = arg;
1780 __u32 type = p->type;
1782 if (!vfd->vidioc_g_sliced_vbi_cap)
1784 memset(p, 0, sizeof(*p));
1786 dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names));
1787 ret = vfd->vidioc_g_sliced_vbi_cap(file, fh, p);
1789 dbgarg2("service_set=%d\n", p->service_set);
1792 case VIDIOC_LOG_STATUS:
1794 if (!vfd->vidioc_log_status)
1796 ret=vfd->vidioc_log_status(file, fh);
1799 #ifdef CONFIG_VIDEO_ADV_DEBUG
1800 case VIDIOC_DBG_G_REGISTER:
1802 struct v4l2_register *p=arg;
1803 if (!capable(CAP_SYS_ADMIN))
1805 else if (vfd->vidioc_g_register)
1806 ret=vfd->vidioc_g_register(file, fh, p);
1809 case VIDIOC_DBG_S_REGISTER:
1811 struct v4l2_register *p=arg;
1812 if (!capable(CAP_SYS_ADMIN))
1814 else if (vfd->vidioc_s_register)
1815 ret=vfd->vidioc_s_register(file, fh, p);
1819 case VIDIOC_G_CHIP_IDENT:
1821 struct v4l2_chip_ident *p=arg;
1822 if (!vfd->vidioc_g_chip_ident)
1824 ret=vfd->vidioc_g_chip_ident(file, fh, p);
1826 dbgarg (cmd, "chip_ident=%u, revision=0x%x\n", p->ident, p->revision);
1831 if (!vfd->vidioc_default)
1833 ret = vfd->vidioc_default(file, fh, cmd, arg);
1836 case VIDIOC_S_HW_FREQ_SEEK:
1838 struct v4l2_hw_freq_seek *p = arg;
1839 if (!vfd->vidioc_s_hw_freq_seek)
1842 "tuner=%d, type=%d, seek_upward=%d, wrap_around=%d\n",
1843 p->tuner, p->type, p->seek_upward, p->wrap_around);
1844 ret = vfd->vidioc_s_hw_freq_seek(file, fh, p);
1849 if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) {
1851 v4l_print_ioctl(vfd->name, cmd);
1852 printk(KERN_CONT " error %d\n", ret);
1859 int video_ioctl2 (struct inode *inode, struct file *file,
1860 unsigned int cmd, unsigned long arg)
1867 size_t ctrls_size = 0;
1868 void __user *user_ptr = NULL;
1870 #ifdef __OLD_VIDIOC_
1871 cmd = video_fix_command(cmd);
1873 is_ext_ctrl = (cmd == VIDIOC_S_EXT_CTRLS || cmd == VIDIOC_G_EXT_CTRLS ||
1874 cmd == VIDIOC_TRY_EXT_CTRLS);
1876 /* Copy arguments into temp kernel buffer */
1877 switch (_IOC_DIR(cmd)) {
1883 case (_IOC_WRITE | _IOC_READ):
1884 if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
1887 /* too big to allocate from stack */
1888 mbuf = kmalloc(_IOC_SIZE(cmd),GFP_KERNEL);
1895 if (_IOC_DIR(cmd) & _IOC_WRITE)
1896 if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd)))
1902 struct v4l2_ext_controls *p = parg;
1904 /* In case of an error, tell the caller that it wasn't
1905 a specific control that caused it. */
1906 p->error_idx = p->count;
1907 user_ptr = (void __user *)p->controls;
1909 ctrls_size = sizeof(struct v4l2_ext_control) * p->count;
1910 /* Note: v4l2_ext_controls fits in sbuf[] so mbuf is still NULL. */
1911 mbuf = kmalloc(ctrls_size, GFP_KERNEL);
1916 if (copy_from_user(mbuf, user_ptr, ctrls_size))
1923 err = __video_do_ioctl(inode, file, cmd, parg);
1924 if (err == -ENOIOCTLCMD)
1927 struct v4l2_ext_controls *p = parg;
1929 p->controls = (void *)user_ptr;
1930 if (p->count && err == 0 && copy_to_user(user_ptr, mbuf, ctrls_size))
1938 /* Copy results into user buffer */
1939 switch (_IOC_DIR(cmd))
1942 case (_IOC_WRITE | _IOC_READ):
1943 if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd)))
1952 EXPORT_SYMBOL(video_ioctl2);
1956 unsigned int used[VIDEO_NUM_DEVICES];
1959 static int __fill_index_info(struct device *cd, void *data)
1961 struct index_info *info = data;
1962 struct video_device *vfd = container_of(cd, struct video_device,
1965 if (info->dev == vfd->dev)
1966 info->used[vfd->index] = 1;
1972 * assign_index - assign stream number based on parent device
1973 * @vdev: video_device to assign index number to, vdev->dev should be assigned
1974 * @num: -1 if auto assign, requested number otherwise
1977 * returns -ENFILE if num is already in use, a free index number if
1980 static int get_index(struct video_device *vdev, int num)
1982 struct index_info *info;
1986 if (num >= VIDEO_NUM_DEVICES)
1989 info = kzalloc(sizeof(*info), GFP_KERNEL);
1993 info->dev = vdev->dev;
1995 ret = class_for_each_device(&video_class, info,
2002 if (!info->used[num])
2010 for (i = 0; i < VIDEO_NUM_DEVICES; i++) {
2022 static const struct file_operations video_fops;
2024 int video_register_device(struct video_device *vfd, int type, int nr)
2026 return video_register_device_index(vfd, type, nr, -1);
2028 EXPORT_SYMBOL(video_register_device);
2031 * video_register_device - register video4linux devices
2032 * @vfd: video device structure we want to register
2033 * @type: type of device to register
2034 * @nr: which device number (0 == /dev/video0, 1 == /dev/video1, ...
2037 * The registration code assigns minor numbers based on the type
2038 * requested. -ENFILE is returned in all the device slots for this
2039 * category are full. If not then the minor field is set and the
2040 * driver initialize function is called (if non %NULL).
2042 * Zero is returned on success.
2046 * %VFL_TYPE_GRABBER - A frame grabber
2048 * %VFL_TYPE_VTX - A teletext device
2050 * %VFL_TYPE_VBI - Vertical blank data (undecoded)
2052 * %VFL_TYPE_RADIO - A radio card
2055 int video_register_device_index(struct video_device *vfd, int type, int nr,
2066 case VFL_TYPE_GRABBER:
2067 base=MINOR_VFL_TYPE_GRABBER_MIN;
2068 end=MINOR_VFL_TYPE_GRABBER_MAX+1;
2069 name_base = "video";
2072 base=MINOR_VFL_TYPE_VTX_MIN;
2073 end=MINOR_VFL_TYPE_VTX_MAX+1;
2077 base=MINOR_VFL_TYPE_VBI_MIN;
2078 end=MINOR_VFL_TYPE_VBI_MAX+1;
2081 case VFL_TYPE_RADIO:
2082 base=MINOR_VFL_TYPE_RADIO_MIN;
2083 end=MINOR_VFL_TYPE_RADIO_MAX+1;
2084 name_base = "radio";
2087 printk(KERN_ERR "%s called with unknown type: %d\n",
2092 /* pick a minor number */
2093 mutex_lock(&videodev_lock);
2094 if (nr >= 0 && nr < end-base) {
2095 /* use the one the driver asked for */
2097 if (NULL != video_device[i]) {
2098 mutex_unlock(&videodev_lock);
2102 /* use first free */
2103 for(i=base;i<end;i++)
2104 if (NULL == video_device[i])
2107 mutex_unlock(&videodev_lock);
2111 video_device[i]=vfd;
2114 ret = get_index(vfd, index);
2116 printk(KERN_ERR "%s: get_index failed\n",
2123 mutex_unlock(&videodev_lock);
2124 mutex_init(&vfd->lock);
2127 memset(&vfd->class_dev, 0x00, sizeof(vfd->class_dev));
2129 vfd->class_dev.parent = vfd->dev;
2130 vfd->class_dev.class = &video_class;
2131 vfd->class_dev.devt = MKDEV(VIDEO_MAJOR, vfd->minor);
2132 sprintf(vfd->class_dev.bus_id, "%s%d", name_base, i - base);
2133 ret = device_register(&vfd->class_dev);
2135 printk(KERN_ERR "%s: device_register failed\n",
2141 /* needed until all drivers are fixed */
2143 printk(KERN_WARNING "videodev: \"%s\" has no release callback. "
2144 "Please fix your driver for proper sysfs support, see "
2145 "http://lwn.net/Articles/36850/\n", vfd->name);
2150 mutex_lock(&videodev_lock);
2151 video_device[vfd->minor] = NULL;
2153 mutex_unlock(&videodev_lock);
2156 EXPORT_SYMBOL(video_register_device_index);
2159 * video_unregister_device - unregister a video4linux device
2160 * @vfd: the device to unregister
2162 * This unregisters the passed device and deassigns the minor
2163 * number. Future open calls will be met with errors.
2166 void video_unregister_device(struct video_device *vfd)
2168 mutex_lock(&videodev_lock);
2169 if(video_device[vfd->minor]!=vfd)
2170 panic("videodev: bad unregister");
2172 video_device[vfd->minor]=NULL;
2173 device_unregister(&vfd->class_dev);
2174 mutex_unlock(&videodev_lock);
2176 EXPORT_SYMBOL(video_unregister_device);
2179 * Video fs operations
2181 static const struct file_operations video_fops=
2183 .owner = THIS_MODULE,
2184 .llseek = no_llseek,
2189 * Initialise video for linux
2192 static int __init videodev_init(void)
2196 printk(KERN_INFO "Linux video capture interface: v2.00\n");
2197 if (register_chrdev(VIDEO_MAJOR, VIDEO_NAME, &video_fops)) {
2198 printk(KERN_WARNING "video_dev: unable to get major %d\n", VIDEO_MAJOR);
2202 ret = class_register(&video_class);
2204 unregister_chrdev(VIDEO_MAJOR, VIDEO_NAME);
2205 printk(KERN_WARNING "video_dev: class_register failed\n");
2212 static void __exit videodev_exit(void)
2214 class_unregister(&video_class);
2215 unregister_chrdev(VIDEO_MAJOR, VIDEO_NAME);
2218 module_init(videodev_init)
2219 module_exit(videodev_exit)
2221 MODULE_AUTHOR("Alan Cox, Mauro Carvalho Chehab <mchehab@infradead.org>");
2222 MODULE_DESCRIPTION("Device registrar for Video4Linux drivers v2");
2223 MODULE_LICENSE("GPL");