Committer: Michael Beasley <mike@snafu.setup>
[mikesnafu-overlay.git] / drivers / media / video / videodev.c
blob0d9b63762a48fd42aaaad60054d2a961dd1e83af
1 /*
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...) \
20 if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) { \
21 printk (KERN_DEBUG "%s: ", vfd->name); \
22 v4l_printk_ioctl(cmd); \
23 printk (KERN_DEBUG "%s: " fmt, vfd->name, ## arg); \
26 #define dbgarg2(fmt, arg...) \
27 if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) \
28 printk (KERN_DEBUG "%s: " fmt, vfd->name, ## arg);
30 #include <linux/module.h>
31 #include <linux/types.h>
32 #include <linux/kernel.h>
33 #include <linux/mm.h>
34 #include <linux/string.h>
35 #include <linux/errno.h>
36 #include <linux/init.h>
37 #include <linux/kmod.h>
38 #include <linux/slab.h>
39 #include <asm/uaccess.h>
40 #include <asm/system.h>
42 #define __OLD_VIDIOC_ /* To allow fixing old calls*/
43 #include <linux/videodev2.h>
45 #ifdef CONFIG_VIDEO_V4L1
46 #include <linux/videodev.h>
47 #endif
48 #include <media/v4l2-common.h>
49 #include <linux/video_decoder.h>
51 #define VIDEO_NUM_DEVICES 256
52 #define VIDEO_NAME "video4linux"
54 /* video4linux standard ID conversion to standard name
56 char *v4l2_norm_to_name(v4l2_std_id id)
58 char *name;
59 u32 myid = id;
61 /* HACK: ppc32 architecture doesn't have __ucmpdi2 function to handle
62 64 bit comparations. So, on that architecture, with some gcc
63 variants, compilation fails. Currently, the max value is 30bit wide.
65 BUG_ON(myid != id);
67 switch (myid) {
68 case V4L2_STD_PAL:
69 name = "PAL";
70 break;
71 case V4L2_STD_PAL_BG:
72 name = "PAL-BG";
73 break;
74 case V4L2_STD_PAL_DK:
75 name = "PAL-DK";
76 break;
77 case V4L2_STD_PAL_B:
78 name = "PAL-B";
79 break;
80 case V4L2_STD_PAL_B1:
81 name = "PAL-B1";
82 break;
83 case V4L2_STD_PAL_G:
84 name = "PAL-G";
85 break;
86 case V4L2_STD_PAL_H:
87 name = "PAL-H";
88 break;
89 case V4L2_STD_PAL_I:
90 name = "PAL-I";
91 break;
92 case V4L2_STD_PAL_D:
93 name = "PAL-D";
94 break;
95 case V4L2_STD_PAL_D1:
96 name = "PAL-D1";
97 break;
98 case V4L2_STD_PAL_K:
99 name = "PAL-K";
100 break;
101 case V4L2_STD_PAL_M:
102 name = "PAL-M";
103 break;
104 case V4L2_STD_PAL_N:
105 name = "PAL-N";
106 break;
107 case V4L2_STD_PAL_Nc:
108 name = "PAL-Nc";
109 break;
110 case V4L2_STD_PAL_60:
111 name = "PAL-60";
112 break;
113 case V4L2_STD_NTSC:
114 name = "NTSC";
115 break;
116 case V4L2_STD_NTSC_M:
117 name = "NTSC-M";
118 break;
119 case V4L2_STD_NTSC_M_JP:
120 name = "NTSC-M-JP";
121 break;
122 case V4L2_STD_NTSC_443:
123 name = "NTSC-443";
124 break;
125 case V4L2_STD_NTSC_M_KR:
126 name = "NTSC-M-KR";
127 break;
128 case V4L2_STD_SECAM:
129 name = "SECAM";
130 break;
131 case V4L2_STD_SECAM_DK:
132 name = "SECAM-DK";
133 break;
134 case V4L2_STD_SECAM_B:
135 name = "SECAM-B";
136 break;
137 case V4L2_STD_SECAM_D:
138 name = "SECAM-D";
139 break;
140 case V4L2_STD_SECAM_G:
141 name = "SECAM-G";
142 break;
143 case V4L2_STD_SECAM_H:
144 name = "SECAM-H";
145 break;
146 case V4L2_STD_SECAM_K:
147 name = "SECAM-K";
148 break;
149 case V4L2_STD_SECAM_K1:
150 name = "SECAM-K1";
151 break;
152 case V4L2_STD_SECAM_L:
153 name = "SECAM-L";
154 break;
155 case V4L2_STD_SECAM_LC:
156 name = "SECAM-LC";
157 break;
158 default:
159 name = "Unknown";
160 break;
163 return name;
165 EXPORT_SYMBOL(v4l2_norm_to_name);
167 /* Fill in the fields of a v4l2_standard structure according to the
168 'id' and 'transmission' parameters. Returns negative on error. */
169 int v4l2_video_std_construct(struct v4l2_standard *vs,
170 int id, char *name)
172 u32 index = vs->index;
174 memset(vs, 0, sizeof(struct v4l2_standard));
175 vs->index = index;
176 vs->id = id;
177 if (id & V4L2_STD_525_60) {
178 vs->frameperiod.numerator = 1001;
179 vs->frameperiod.denominator = 30000;
180 vs->framelines = 525;
181 } else {
182 vs->frameperiod.numerator = 1;
183 vs->frameperiod.denominator = 25;
184 vs->framelines = 625;
186 strlcpy(vs->name, name, sizeof(vs->name));
187 return 0;
189 EXPORT_SYMBOL(v4l2_video_std_construct);
191 /* ----------------------------------------------------------------- */
192 /* some arrays for pretty-printing debug messages of enum types */
194 char *v4l2_field_names[] = {
195 [V4L2_FIELD_ANY] = "any",
196 [V4L2_FIELD_NONE] = "none",
197 [V4L2_FIELD_TOP] = "top",
198 [V4L2_FIELD_BOTTOM] = "bottom",
199 [V4L2_FIELD_INTERLACED] = "interlaced",
200 [V4L2_FIELD_SEQ_TB] = "seq-tb",
201 [V4L2_FIELD_SEQ_BT] = "seq-bt",
202 [V4L2_FIELD_ALTERNATE] = "alternate",
203 [V4L2_FIELD_INTERLACED_TB] = "interlaced-tb",
204 [V4L2_FIELD_INTERLACED_BT] = "interlaced-bt",
206 EXPORT_SYMBOL(v4l2_field_names);
208 char *v4l2_type_names[] = {
209 [V4L2_BUF_TYPE_VIDEO_CAPTURE] = "video-cap",
210 [V4L2_BUF_TYPE_VIDEO_OVERLAY] = "video-over",
211 [V4L2_BUF_TYPE_VIDEO_OUTPUT] = "video-out",
212 [V4L2_BUF_TYPE_VBI_CAPTURE] = "vbi-cap",
213 [V4L2_BUF_TYPE_VBI_OUTPUT] = "vbi-out",
214 [V4L2_BUF_TYPE_SLICED_VBI_CAPTURE] = "sliced-vbi-cap",
215 [V4L2_BUF_TYPE_SLICED_VBI_OUTPUT] = "sliced-vbi-out",
216 [V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY] = "video-out-over",
218 EXPORT_SYMBOL(v4l2_type_names);
220 static char *v4l2_memory_names[] = {
221 [V4L2_MEMORY_MMAP] = "mmap",
222 [V4L2_MEMORY_USERPTR] = "userptr",
223 [V4L2_MEMORY_OVERLAY] = "overlay",
226 #define prt_names(a, arr) ((((a) >= 0) && ((a) < ARRAY_SIZE(arr))) ? \
227 arr[a] : "unknown")
229 /* ------------------------------------------------------------------ */
230 /* debug help functions */
232 #ifdef CONFIG_VIDEO_V4L1_COMPAT
233 static const char *v4l1_ioctls[] = {
234 [_IOC_NR(VIDIOCGCAP)] = "VIDIOCGCAP",
235 [_IOC_NR(VIDIOCGCHAN)] = "VIDIOCGCHAN",
236 [_IOC_NR(VIDIOCSCHAN)] = "VIDIOCSCHAN",
237 [_IOC_NR(VIDIOCGTUNER)] = "VIDIOCGTUNER",
238 [_IOC_NR(VIDIOCSTUNER)] = "VIDIOCSTUNER",
239 [_IOC_NR(VIDIOCGPICT)] = "VIDIOCGPICT",
240 [_IOC_NR(VIDIOCSPICT)] = "VIDIOCSPICT",
241 [_IOC_NR(VIDIOCCAPTURE)] = "VIDIOCCAPTURE",
242 [_IOC_NR(VIDIOCGWIN)] = "VIDIOCGWIN",
243 [_IOC_NR(VIDIOCSWIN)] = "VIDIOCSWIN",
244 [_IOC_NR(VIDIOCGFBUF)] = "VIDIOCGFBUF",
245 [_IOC_NR(VIDIOCSFBUF)] = "VIDIOCSFBUF",
246 [_IOC_NR(VIDIOCKEY)] = "VIDIOCKEY",
247 [_IOC_NR(VIDIOCGFREQ)] = "VIDIOCGFREQ",
248 [_IOC_NR(VIDIOCSFREQ)] = "VIDIOCSFREQ",
249 [_IOC_NR(VIDIOCGAUDIO)] = "VIDIOCGAUDIO",
250 [_IOC_NR(VIDIOCSAUDIO)] = "VIDIOCSAUDIO",
251 [_IOC_NR(VIDIOCSYNC)] = "VIDIOCSYNC",
252 [_IOC_NR(VIDIOCMCAPTURE)] = "VIDIOCMCAPTURE",
253 [_IOC_NR(VIDIOCGMBUF)] = "VIDIOCGMBUF",
254 [_IOC_NR(VIDIOCGUNIT)] = "VIDIOCGUNIT",
255 [_IOC_NR(VIDIOCGCAPTURE)] = "VIDIOCGCAPTURE",
256 [_IOC_NR(VIDIOCSCAPTURE)] = "VIDIOCSCAPTURE",
257 [_IOC_NR(VIDIOCSPLAYMODE)] = "VIDIOCSPLAYMODE",
258 [_IOC_NR(VIDIOCSWRITEMODE)] = "VIDIOCSWRITEMODE",
259 [_IOC_NR(VIDIOCGPLAYINFO)] = "VIDIOCGPLAYINFO",
260 [_IOC_NR(VIDIOCSMICROCODE)] = "VIDIOCSMICROCODE",
261 [_IOC_NR(VIDIOCGVBIFMT)] = "VIDIOCGVBIFMT",
262 [_IOC_NR(VIDIOCSVBIFMT)] = "VIDIOCSVBIFMT"
264 #define V4L1_IOCTLS ARRAY_SIZE(v4l1_ioctls)
265 #endif
267 static const char *v4l2_ioctls[] = {
268 [_IOC_NR(VIDIOC_QUERYCAP)] = "VIDIOC_QUERYCAP",
269 [_IOC_NR(VIDIOC_RESERVED)] = "VIDIOC_RESERVED",
270 [_IOC_NR(VIDIOC_ENUM_FMT)] = "VIDIOC_ENUM_FMT",
271 [_IOC_NR(VIDIOC_G_FMT)] = "VIDIOC_G_FMT",
272 [_IOC_NR(VIDIOC_S_FMT)] = "VIDIOC_S_FMT",
273 [_IOC_NR(VIDIOC_REQBUFS)] = "VIDIOC_REQBUFS",
274 [_IOC_NR(VIDIOC_QUERYBUF)] = "VIDIOC_QUERYBUF",
275 [_IOC_NR(VIDIOC_G_FBUF)] = "VIDIOC_G_FBUF",
276 [_IOC_NR(VIDIOC_S_FBUF)] = "VIDIOC_S_FBUF",
277 [_IOC_NR(VIDIOC_OVERLAY)] = "VIDIOC_OVERLAY",
278 [_IOC_NR(VIDIOC_QBUF)] = "VIDIOC_QBUF",
279 [_IOC_NR(VIDIOC_DQBUF)] = "VIDIOC_DQBUF",
280 [_IOC_NR(VIDIOC_STREAMON)] = "VIDIOC_STREAMON",
281 [_IOC_NR(VIDIOC_STREAMOFF)] = "VIDIOC_STREAMOFF",
282 [_IOC_NR(VIDIOC_G_PARM)] = "VIDIOC_G_PARM",
283 [_IOC_NR(VIDIOC_S_PARM)] = "VIDIOC_S_PARM",
284 [_IOC_NR(VIDIOC_G_STD)] = "VIDIOC_G_STD",
285 [_IOC_NR(VIDIOC_S_STD)] = "VIDIOC_S_STD",
286 [_IOC_NR(VIDIOC_ENUMSTD)] = "VIDIOC_ENUMSTD",
287 [_IOC_NR(VIDIOC_ENUMINPUT)] = "VIDIOC_ENUMINPUT",
288 [_IOC_NR(VIDIOC_G_CTRL)] = "VIDIOC_G_CTRL",
289 [_IOC_NR(VIDIOC_S_CTRL)] = "VIDIOC_S_CTRL",
290 [_IOC_NR(VIDIOC_G_TUNER)] = "VIDIOC_G_TUNER",
291 [_IOC_NR(VIDIOC_S_TUNER)] = "VIDIOC_S_TUNER",
292 [_IOC_NR(VIDIOC_G_AUDIO)] = "VIDIOC_G_AUDIO",
293 [_IOC_NR(VIDIOC_S_AUDIO)] = "VIDIOC_S_AUDIO",
294 [_IOC_NR(VIDIOC_QUERYCTRL)] = "VIDIOC_QUERYCTRL",
295 [_IOC_NR(VIDIOC_QUERYMENU)] = "VIDIOC_QUERYMENU",
296 [_IOC_NR(VIDIOC_G_INPUT)] = "VIDIOC_G_INPUT",
297 [_IOC_NR(VIDIOC_S_INPUT)] = "VIDIOC_S_INPUT",
298 [_IOC_NR(VIDIOC_G_OUTPUT)] = "VIDIOC_G_OUTPUT",
299 [_IOC_NR(VIDIOC_S_OUTPUT)] = "VIDIOC_S_OUTPUT",
300 [_IOC_NR(VIDIOC_ENUMOUTPUT)] = "VIDIOC_ENUMOUTPUT",
301 [_IOC_NR(VIDIOC_G_AUDOUT)] = "VIDIOC_G_AUDOUT",
302 [_IOC_NR(VIDIOC_S_AUDOUT)] = "VIDIOC_S_AUDOUT",
303 [_IOC_NR(VIDIOC_G_MODULATOR)] = "VIDIOC_G_MODULATOR",
304 [_IOC_NR(VIDIOC_S_MODULATOR)] = "VIDIOC_S_MODULATOR",
305 [_IOC_NR(VIDIOC_G_FREQUENCY)] = "VIDIOC_G_FREQUENCY",
306 [_IOC_NR(VIDIOC_S_FREQUENCY)] = "VIDIOC_S_FREQUENCY",
307 [_IOC_NR(VIDIOC_CROPCAP)] = "VIDIOC_CROPCAP",
308 [_IOC_NR(VIDIOC_G_CROP)] = "VIDIOC_G_CROP",
309 [_IOC_NR(VIDIOC_S_CROP)] = "VIDIOC_S_CROP",
310 [_IOC_NR(VIDIOC_G_JPEGCOMP)] = "VIDIOC_G_JPEGCOMP",
311 [_IOC_NR(VIDIOC_S_JPEGCOMP)] = "VIDIOC_S_JPEGCOMP",
312 [_IOC_NR(VIDIOC_QUERYSTD)] = "VIDIOC_QUERYSTD",
313 [_IOC_NR(VIDIOC_TRY_FMT)] = "VIDIOC_TRY_FMT",
314 [_IOC_NR(VIDIOC_ENUMAUDIO)] = "VIDIOC_ENUMAUDIO",
315 [_IOC_NR(VIDIOC_ENUMAUDOUT)] = "VIDIOC_ENUMAUDOUT",
316 [_IOC_NR(VIDIOC_G_PRIORITY)] = "VIDIOC_G_PRIORITY",
317 [_IOC_NR(VIDIOC_S_PRIORITY)] = "VIDIOC_S_PRIORITY",
318 [_IOC_NR(VIDIOC_G_SLICED_VBI_CAP)] = "VIDIOC_G_SLICED_VBI_CAP",
319 [_IOC_NR(VIDIOC_LOG_STATUS)] = "VIDIOC_LOG_STATUS",
320 [_IOC_NR(VIDIOC_G_EXT_CTRLS)] = "VIDIOC_G_EXT_CTRLS",
321 [_IOC_NR(VIDIOC_S_EXT_CTRLS)] = "VIDIOC_S_EXT_CTRLS",
322 [_IOC_NR(VIDIOC_TRY_EXT_CTRLS)] = "VIDIOC_TRY_EXT_CTRLS",
323 #if 1
324 [_IOC_NR(VIDIOC_ENUM_FRAMESIZES)] = "VIDIOC_ENUM_FRAMESIZES",
325 [_IOC_NR(VIDIOC_ENUM_FRAMEINTERVALS)] = "VIDIOC_ENUM_FRAMEINTERVALS",
326 [_IOC_NR(VIDIOC_G_ENC_INDEX)] = "VIDIOC_G_ENC_INDEX",
327 [_IOC_NR(VIDIOC_ENCODER_CMD)] = "VIDIOC_ENCODER_CMD",
328 [_IOC_NR(VIDIOC_TRY_ENCODER_CMD)] = "VIDIOC_TRY_ENCODER_CMD",
330 [_IOC_NR(VIDIOC_DBG_S_REGISTER)] = "VIDIOC_DBG_S_REGISTER",
331 [_IOC_NR(VIDIOC_DBG_G_REGISTER)] = "VIDIOC_DBG_G_REGISTER",
333 [_IOC_NR(VIDIOC_G_CHIP_IDENT)] = "VIDIOC_G_CHIP_IDENT",
334 #endif
336 #define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
338 static const char *v4l2_int_ioctls[] = {
339 #ifdef CONFIG_VIDEO_V4L1_COMPAT
340 [_IOC_NR(DECODER_GET_CAPABILITIES)] = "DECODER_GET_CAPABILITIES",
341 [_IOC_NR(DECODER_GET_STATUS)] = "DECODER_GET_STATUS",
342 [_IOC_NR(DECODER_SET_NORM)] = "DECODER_SET_NORM",
343 [_IOC_NR(DECODER_SET_INPUT)] = "DECODER_SET_INPUT",
344 [_IOC_NR(DECODER_SET_OUTPUT)] = "DECODER_SET_OUTPUT",
345 [_IOC_NR(DECODER_ENABLE_OUTPUT)] = "DECODER_ENABLE_OUTPUT",
346 [_IOC_NR(DECODER_SET_PICTURE)] = "DECODER_SET_PICTURE",
347 [_IOC_NR(DECODER_SET_GPIO)] = "DECODER_SET_GPIO",
348 [_IOC_NR(DECODER_INIT)] = "DECODER_INIT",
349 [_IOC_NR(DECODER_SET_VBI_BYPASS)] = "DECODER_SET_VBI_BYPASS",
350 [_IOC_NR(DECODER_DUMP)] = "DECODER_DUMP",
351 #endif
352 [_IOC_NR(AUDC_SET_RADIO)] = "AUDC_SET_RADIO",
354 [_IOC_NR(TUNER_SET_TYPE_ADDR)] = "TUNER_SET_TYPE_ADDR",
355 [_IOC_NR(TUNER_SET_STANDBY)] = "TUNER_SET_STANDBY",
356 [_IOC_NR(TUNER_SET_CONFIG)] = "TUNER_SET_CONFIG",
358 [_IOC_NR(VIDIOC_INT_S_TUNER_MODE)] = "VIDIOC_INT_S_TUNER_MODE",
359 [_IOC_NR(VIDIOC_INT_RESET)] = "VIDIOC_INT_RESET",
360 [_IOC_NR(VIDIOC_INT_AUDIO_CLOCK_FREQ)] = "VIDIOC_INT_AUDIO_CLOCK_FREQ",
361 [_IOC_NR(VIDIOC_INT_DECODE_VBI_LINE)] = "VIDIOC_INT_DECODE_VBI_LINE",
362 [_IOC_NR(VIDIOC_INT_S_VBI_DATA)] = "VIDIOC_INT_S_VBI_DATA",
363 [_IOC_NR(VIDIOC_INT_G_VBI_DATA)] = "VIDIOC_INT_G_VBI_DATA",
364 [_IOC_NR(VIDIOC_INT_I2S_CLOCK_FREQ)] = "VIDIOC_INT_I2S_CLOCK_FREQ",
365 [_IOC_NR(VIDIOC_INT_S_STANDBY)] = "VIDIOC_INT_S_STANDBY",
366 [_IOC_NR(VIDIOC_INT_S_AUDIO_ROUTING)] = "VIDIOC_INT_S_AUDIO_ROUTING",
367 [_IOC_NR(VIDIOC_INT_G_AUDIO_ROUTING)] = "VIDIOC_INT_G_AUDIO_ROUTING",
368 [_IOC_NR(VIDIOC_INT_S_VIDEO_ROUTING)] = "VIDIOC_INT_S_VIDEO_ROUTING",
369 [_IOC_NR(VIDIOC_INT_G_VIDEO_ROUTING)] = "VIDIOC_INT_G_VIDEO_ROUTING",
370 [_IOC_NR(VIDIOC_INT_S_CRYSTAL_FREQ)] = "VIDIOC_INT_S_CRYSTAL_FREQ",
371 [_IOC_NR(VIDIOC_INT_INIT)] = "VIDIOC_INT_INIT",
372 [_IOC_NR(VIDIOC_INT_G_STD_OUTPUT)] = "VIDIOC_INT_G_STD_OUTPUT",
373 [_IOC_NR(VIDIOC_INT_S_STD_OUTPUT)] = "VIDIOC_INT_S_STD_OUTPUT",
375 #define V4L2_INT_IOCTLS ARRAY_SIZE(v4l2_int_ioctls)
377 /* Common ioctl debug function. This function can be used by
378 external ioctl messages as well as internal V4L ioctl */
379 void v4l_printk_ioctl(unsigned int cmd)
381 char *dir;
383 switch (_IOC_DIR(cmd)) {
384 case _IOC_NONE: dir = "--"; break;
385 case _IOC_READ: dir = "r-"; break;
386 case _IOC_WRITE: dir = "-w"; break;
387 case _IOC_READ | _IOC_WRITE: dir = "rw"; break;
388 default: dir = "*ERR*"; break;
390 switch (_IOC_TYPE(cmd)) {
391 case 'd':
392 printk("v4l2_int ioctl %s, dir=%s (0x%08x)\n",
393 (_IOC_NR(cmd) < V4L2_INT_IOCTLS) ?
394 v4l2_int_ioctls[_IOC_NR(cmd)] : "UNKNOWN", dir, cmd);
395 break;
396 #ifdef CONFIG_VIDEO_V4L1_COMPAT
397 case 'v':
398 printk("v4l1 ioctl %s, dir=%s (0x%08x)\n",
399 (_IOC_NR(cmd) < V4L1_IOCTLS) ?
400 v4l1_ioctls[_IOC_NR(cmd)] : "UNKNOWN", dir, cmd);
401 break;
402 #endif
403 case 'V':
404 printk("v4l2 ioctl %s, dir=%s (0x%08x)\n",
405 (_IOC_NR(cmd) < V4L2_IOCTLS) ?
406 v4l2_ioctls[_IOC_NR(cmd)] : "UNKNOWN", dir, cmd);
407 break;
409 default:
410 printk("unknown ioctl '%c', dir=%s, #%d (0x%08x)\n",
411 _IOC_TYPE(cmd), dir, _IOC_NR(cmd), cmd);
414 EXPORT_SYMBOL(v4l_printk_ioctl);
417 * sysfs stuff
420 static ssize_t show_name(struct device *cd,
421 struct device_attribute *attr, char *buf)
423 struct video_device *vfd = container_of(cd, struct video_device,
424 class_dev);
425 return sprintf(buf, "%.*s\n", (int)sizeof(vfd->name), vfd->name);
428 struct video_device *video_device_alloc(void)
430 struct video_device *vfd;
432 vfd = kzalloc(sizeof(*vfd),GFP_KERNEL);
433 return vfd;
435 EXPORT_SYMBOL(video_device_alloc);
437 void video_device_release(struct video_device *vfd)
439 kfree(vfd);
441 EXPORT_SYMBOL(video_device_release);
443 static void video_release(struct device *cd)
445 struct video_device *vfd = container_of(cd, struct video_device,
446 class_dev);
448 #if 1
449 /* needed until all drivers are fixed */
450 if (!vfd->release)
451 return;
452 #endif
453 vfd->release(vfd);
456 static struct device_attribute video_device_attrs[] = {
457 __ATTR(name, S_IRUGO, show_name, NULL),
458 __ATTR_NULL
461 static struct class video_class = {
462 .name = VIDEO_NAME,
463 .dev_attrs = video_device_attrs,
464 .dev_release = video_release,
468 * Active devices
471 static struct video_device *video_device[VIDEO_NUM_DEVICES];
472 static DEFINE_MUTEX(videodev_lock);
474 struct video_device* video_devdata(struct file *file)
476 return video_device[iminor(file->f_path.dentry->d_inode)];
478 EXPORT_SYMBOL(video_devdata);
481 * Open a video device - FIXME: Obsoleted
483 static int video_open(struct inode *inode, struct file *file)
485 unsigned int minor = iminor(inode);
486 int err = 0;
487 struct video_device *vfl;
488 const struct file_operations *old_fops;
490 if(minor>=VIDEO_NUM_DEVICES)
491 return -ENODEV;
492 mutex_lock(&videodev_lock);
493 vfl=video_device[minor];
494 if(vfl==NULL) {
495 mutex_unlock(&videodev_lock);
496 request_module("char-major-%d-%d", VIDEO_MAJOR, minor);
497 mutex_lock(&videodev_lock);
498 vfl=video_device[minor];
499 if (vfl==NULL) {
500 mutex_unlock(&videodev_lock);
501 return -ENODEV;
504 old_fops = file->f_op;
505 file->f_op = fops_get(vfl->fops);
506 if(file->f_op->open)
507 err = file->f_op->open(inode,file);
508 if (err) {
509 fops_put(file->f_op);
510 file->f_op = fops_get(old_fops);
512 fops_put(old_fops);
513 mutex_unlock(&videodev_lock);
514 return err;
518 * helper function -- handles userspace copying for ioctl arguments
521 #ifdef __OLD_VIDIOC_
522 static unsigned int
523 video_fix_command(unsigned int cmd)
525 switch (cmd) {
526 case VIDIOC_OVERLAY_OLD:
527 cmd = VIDIOC_OVERLAY;
528 break;
529 case VIDIOC_S_PARM_OLD:
530 cmd = VIDIOC_S_PARM;
531 break;
532 case VIDIOC_S_CTRL_OLD:
533 cmd = VIDIOC_S_CTRL;
534 break;
535 case VIDIOC_G_AUDIO_OLD:
536 cmd = VIDIOC_G_AUDIO;
537 break;
538 case VIDIOC_G_AUDOUT_OLD:
539 cmd = VIDIOC_G_AUDOUT;
540 break;
541 case VIDIOC_CROPCAP_OLD:
542 cmd = VIDIOC_CROPCAP;
543 break;
545 return cmd;
547 #endif
550 * Obsolete usercopy function - Should be removed soon
553 video_usercopy(struct inode *inode, struct file *file,
554 unsigned int cmd, unsigned long arg,
555 int (*func)(struct inode *inode, struct file *file,
556 unsigned int cmd, void *arg))
558 char sbuf[128];
559 void *mbuf = NULL;
560 void *parg = NULL;
561 int err = -EINVAL;
562 int is_ext_ctrl;
563 size_t ctrls_size = 0;
564 void __user *user_ptr = NULL;
566 #ifdef __OLD_VIDIOC_
567 cmd = video_fix_command(cmd);
568 #endif
569 is_ext_ctrl = (cmd == VIDIOC_S_EXT_CTRLS || cmd == VIDIOC_G_EXT_CTRLS ||
570 cmd == VIDIOC_TRY_EXT_CTRLS);
572 /* Copy arguments into temp kernel buffer */
573 switch (_IOC_DIR(cmd)) {
574 case _IOC_NONE:
575 parg = NULL;
576 break;
577 case _IOC_READ:
578 case _IOC_WRITE:
579 case (_IOC_WRITE | _IOC_READ):
580 if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
581 parg = sbuf;
582 } else {
583 /* too big to allocate from stack */
584 mbuf = kmalloc(_IOC_SIZE(cmd),GFP_KERNEL);
585 if (NULL == mbuf)
586 return -ENOMEM;
587 parg = mbuf;
590 err = -EFAULT;
591 if (_IOC_DIR(cmd) & _IOC_WRITE)
592 if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd)))
593 goto out;
594 break;
596 if (is_ext_ctrl) {
597 struct v4l2_ext_controls *p = parg;
599 /* In case of an error, tell the caller that it wasn't
600 a specific control that caused it. */
601 p->error_idx = p->count;
602 user_ptr = (void __user *)p->controls;
603 if (p->count) {
604 ctrls_size = sizeof(struct v4l2_ext_control) * p->count;
605 /* Note: v4l2_ext_controls fits in sbuf[] so mbuf is still NULL. */
606 mbuf = kmalloc(ctrls_size, GFP_KERNEL);
607 err = -ENOMEM;
608 if (NULL == mbuf)
609 goto out_ext_ctrl;
610 err = -EFAULT;
611 if (copy_from_user(mbuf, user_ptr, ctrls_size))
612 goto out_ext_ctrl;
613 p->controls = mbuf;
617 /* call driver */
618 err = func(inode, file, cmd, parg);
619 if (err == -ENOIOCTLCMD)
620 err = -EINVAL;
621 if (is_ext_ctrl) {
622 struct v4l2_ext_controls *p = parg;
624 p->controls = (void *)user_ptr;
625 if (p->count && err == 0 && copy_to_user(user_ptr, mbuf, ctrls_size))
626 err = -EFAULT;
627 goto out_ext_ctrl;
629 if (err < 0)
630 goto out;
632 out_ext_ctrl:
633 /* Copy results into user buffer */
634 switch (_IOC_DIR(cmd))
636 case _IOC_READ:
637 case (_IOC_WRITE | _IOC_READ):
638 if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd)))
639 err = -EFAULT;
640 break;
643 out:
644 kfree(mbuf);
645 return err;
647 EXPORT_SYMBOL(video_usercopy);
650 * open/release helper functions -- handle exclusive opens
651 * Should be removed soon
653 int video_exclusive_open(struct inode *inode, struct file *file)
655 struct video_device *vfl = video_devdata(file);
656 int retval = 0;
658 mutex_lock(&vfl->lock);
659 if (vfl->users) {
660 retval = -EBUSY;
661 } else {
662 vfl->users++;
664 mutex_unlock(&vfl->lock);
665 return retval;
667 EXPORT_SYMBOL(video_exclusive_open);
669 int video_exclusive_release(struct inode *inode, struct file *file)
671 struct video_device *vfl = video_devdata(file);
673 vfl->users--;
674 return 0;
676 EXPORT_SYMBOL(video_exclusive_release);
678 static void dbgbuf(unsigned int cmd, struct video_device *vfd,
679 struct v4l2_buffer *p)
681 struct v4l2_timecode *tc=&p->timecode;
683 dbgarg (cmd, "%02ld:%02d:%02d.%08ld index=%d, type=%s, "
684 "bytesused=%d, flags=0x%08d, "
685 "field=%0d, sequence=%d, memory=%s, offset/userptr=0x%08lx, length=%d\n",
686 (p->timestamp.tv_sec/3600),
687 (int)(p->timestamp.tv_sec/60)%60,
688 (int)(p->timestamp.tv_sec%60),
689 p->timestamp.tv_usec,
690 p->index,
691 prt_names(p->type, v4l2_type_names),
692 p->bytesused, p->flags,
693 p->field, p->sequence,
694 prt_names(p->memory, v4l2_memory_names),
695 p->m.userptr, p->length);
696 dbgarg2 ("timecode= %02d:%02d:%02d type=%d, "
697 "flags=0x%08d, frames=%d, userbits=0x%08x\n",
698 tc->hours,tc->minutes,tc->seconds,
699 tc->type, tc->flags, tc->frames, *(__u32 *) tc->userbits);
702 static inline void dbgrect(struct video_device *vfd, char *s,
703 struct v4l2_rect *r)
705 dbgarg2 ("%sRect start at %dx%d, size= %dx%d\n", s, r->left, r->top,
706 r->width, r->height);
709 static inline void v4l_print_pix_fmt (struct video_device *vfd,
710 struct v4l2_pix_format *fmt)
712 dbgarg2 ("width=%d, height=%d, format=%c%c%c%c, field=%s, "
713 "bytesperline=%d sizeimage=%d, colorspace=%d\n",
714 fmt->width,fmt->height,
715 (fmt->pixelformat & 0xff),
716 (fmt->pixelformat >> 8) & 0xff,
717 (fmt->pixelformat >> 16) & 0xff,
718 (fmt->pixelformat >> 24) & 0xff,
719 prt_names(fmt->field, v4l2_field_names),
720 fmt->bytesperline, fmt->sizeimage, fmt->colorspace);
724 static int check_fmt (struct video_device *vfd, enum v4l2_buf_type type)
726 switch (type) {
727 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
728 if (vfd->vidioc_try_fmt_cap)
729 return (0);
730 break;
731 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
732 if (vfd->vidioc_try_fmt_overlay)
733 return (0);
734 break;
735 case V4L2_BUF_TYPE_VBI_CAPTURE:
736 if (vfd->vidioc_try_fmt_vbi)
737 return (0);
738 break;
739 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
740 if (vfd->vidioc_try_fmt_vbi_output)
741 return (0);
742 break;
743 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
744 if (vfd->vidioc_try_fmt_vbi_capture)
745 return (0);
746 break;
747 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
748 if (vfd->vidioc_try_fmt_video_output)
749 return (0);
750 break;
751 case V4L2_BUF_TYPE_VBI_OUTPUT:
752 if (vfd->vidioc_try_fmt_vbi_output)
753 return (0);
754 break;
755 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
756 if (vfd->vidioc_try_fmt_output_overlay)
757 return (0);
758 break;
759 case V4L2_BUF_TYPE_PRIVATE:
760 if (vfd->vidioc_try_fmt_type_private)
761 return (0);
762 break;
764 return (-EINVAL);
767 static int __video_do_ioctl(struct inode *inode, struct file *file,
768 unsigned int cmd, void *arg)
770 struct video_device *vfd = video_devdata(file);
771 void *fh = file->private_data;
772 int ret = -EINVAL;
774 if ( (vfd->debug & V4L2_DEBUG_IOCTL) &&
775 !(vfd->debug & V4L2_DEBUG_IOCTL_ARG)) {
776 v4l_print_ioctl(vfd->name, cmd);
779 #ifdef CONFIG_VIDEO_V4L1_COMPAT
780 /***********************************************************
781 Handles calls to the obsoleted V4L1 API
782 Due to the nature of VIDIOCGMBUF, each driver that supports
783 V4L1 should implement its own handler for this ioctl.
784 ***********************************************************/
786 /* --- streaming capture ------------------------------------- */
787 if (cmd == VIDIOCGMBUF) {
788 struct video_mbuf *p=arg;
790 memset(p, 0, sizeof(*p));
792 if (!vfd->vidiocgmbuf)
793 return ret;
794 ret=vfd->vidiocgmbuf(file, fh, p);
795 if (!ret)
796 dbgarg (cmd, "size=%d, frames=%d, offsets=0x%08lx\n",
797 p->size, p->frames,
798 (unsigned long)p->offsets);
799 return ret;
802 /********************************************************
803 All other V4L1 calls are handled by v4l1_compat module.
804 Those calls will be translated into V4L2 calls, and
805 __video_do_ioctl will be called again, with one or more
806 V4L2 ioctls.
807 ********************************************************/
808 if (_IOC_TYPE(cmd)=='v')
809 return v4l_compat_translate_ioctl(inode,file,cmd,arg,
810 __video_do_ioctl);
811 #endif
813 switch(cmd) {
814 /* --- capabilities ------------------------------------------ */
815 case VIDIOC_QUERYCAP:
817 struct v4l2_capability *cap = (struct v4l2_capability*)arg;
818 memset(cap, 0, sizeof(*cap));
820 if (!vfd->vidioc_querycap)
821 break;
823 ret=vfd->vidioc_querycap(file, fh, cap);
824 if (!ret)
825 dbgarg (cmd, "driver=%s, card=%s, bus=%s, "
826 "version=0x%08x, "
827 "capabilities=0x%08x\n",
828 cap->driver,cap->card,cap->bus_info,
829 cap->version,
830 cap->capabilities);
831 break;
834 /* --- priority ------------------------------------------ */
835 case VIDIOC_G_PRIORITY:
837 enum v4l2_priority *p=arg;
839 if (!vfd->vidioc_g_priority)
840 break;
841 ret=vfd->vidioc_g_priority(file, fh, p);
842 if (!ret)
843 dbgarg(cmd, "priority is %d\n", *p);
844 break;
846 case VIDIOC_S_PRIORITY:
848 enum v4l2_priority *p=arg;
850 if (!vfd->vidioc_s_priority)
851 break;
852 dbgarg(cmd, "setting priority to %d\n", *p);
853 ret=vfd->vidioc_s_priority(file, fh, *p);
854 break;
857 /* --- capture ioctls ---------------------------------------- */
858 case VIDIOC_ENUM_FMT:
860 struct v4l2_fmtdesc *f = arg;
861 enum v4l2_buf_type type;
862 unsigned int index;
864 index = f->index;
865 type = f->type;
866 memset(f,0,sizeof(*f));
867 f->index = index;
868 f->type = type;
870 switch (type) {
871 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
872 if (vfd->vidioc_enum_fmt_cap)
873 ret=vfd->vidioc_enum_fmt_cap(file, fh, f);
874 break;
875 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
876 if (vfd->vidioc_enum_fmt_overlay)
877 ret=vfd->vidioc_enum_fmt_overlay(file, fh, f);
878 break;
879 case V4L2_BUF_TYPE_VBI_CAPTURE:
880 if (vfd->vidioc_enum_fmt_vbi)
881 ret=vfd->vidioc_enum_fmt_vbi(file, fh, f);
882 break;
883 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
884 if (vfd->vidioc_enum_fmt_vbi_output)
885 ret=vfd->vidioc_enum_fmt_vbi_output(file,
886 fh, f);
887 break;
888 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
889 if (vfd->vidioc_enum_fmt_vbi_capture)
890 ret=vfd->vidioc_enum_fmt_vbi_capture(file,
891 fh, f);
892 break;
893 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
894 if (vfd->vidioc_enum_fmt_video_output)
895 ret=vfd->vidioc_enum_fmt_video_output(file,
896 fh, f);
897 break;
898 case V4L2_BUF_TYPE_VBI_OUTPUT:
899 if (vfd->vidioc_enum_fmt_vbi_output)
900 ret=vfd->vidioc_enum_fmt_vbi_output(file,
901 fh, f);
902 break;
903 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
904 if (vfd->vidioc_enum_fmt_output_overlay)
905 ret=vfd->vidioc_enum_fmt_output_overlay(file, fh, f);
906 break;
907 case V4L2_BUF_TYPE_PRIVATE:
908 if (vfd->vidioc_enum_fmt_type_private)
909 ret=vfd->vidioc_enum_fmt_type_private(file,
910 fh, f);
911 break;
913 if (!ret)
914 dbgarg (cmd, "index=%d, type=%d, flags=%d, "
915 "pixelformat=%c%c%c%c, description='%s'\n",
916 f->index, f->type, f->flags,
917 (f->pixelformat & 0xff),
918 (f->pixelformat >> 8) & 0xff,
919 (f->pixelformat >> 16) & 0xff,
920 (f->pixelformat >> 24) & 0xff,
921 f->description);
922 break;
924 case VIDIOC_G_FMT:
926 struct v4l2_format *f = (struct v4l2_format *)arg;
927 enum v4l2_buf_type type=f->type;
929 memset(&f->fmt.pix,0,sizeof(f->fmt.pix));
930 f->type=type;
932 /* FIXME: Should be one dump per type */
933 dbgarg (cmd, "type=%s\n", prt_names(type,
934 v4l2_type_names));
936 switch (type) {
937 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
938 if (vfd->vidioc_g_fmt_cap)
939 ret=vfd->vidioc_g_fmt_cap(file, fh, f);
940 if (!ret)
941 v4l_print_pix_fmt(vfd,&f->fmt.pix);
942 break;
943 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
944 if (vfd->vidioc_g_fmt_overlay)
945 ret=vfd->vidioc_g_fmt_overlay(file, fh, f);
946 break;
947 case V4L2_BUF_TYPE_VBI_CAPTURE:
948 if (vfd->vidioc_g_fmt_vbi)
949 ret=vfd->vidioc_g_fmt_vbi(file, fh, f);
950 break;
951 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
952 if (vfd->vidioc_g_fmt_vbi_output)
953 ret=vfd->vidioc_g_fmt_vbi_output(file, fh, f);
954 break;
955 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
956 if (vfd->vidioc_g_fmt_vbi_capture)
957 ret=vfd->vidioc_g_fmt_vbi_capture(file, fh, f);
958 break;
959 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
960 if (vfd->vidioc_g_fmt_video_output)
961 ret=vfd->vidioc_g_fmt_video_output(file,
962 fh, f);
963 break;
964 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
965 if (vfd->vidioc_g_fmt_output_overlay)
966 ret=vfd->vidioc_g_fmt_output_overlay(file, fh, f);
967 break;
968 case V4L2_BUF_TYPE_VBI_OUTPUT:
969 if (vfd->vidioc_g_fmt_vbi_output)
970 ret=vfd->vidioc_g_fmt_vbi_output(file, fh, f);
971 break;
972 case V4L2_BUF_TYPE_PRIVATE:
973 if (vfd->vidioc_g_fmt_type_private)
974 ret=vfd->vidioc_g_fmt_type_private(file,
975 fh, f);
976 break;
979 break;
981 case VIDIOC_S_FMT:
983 struct v4l2_format *f = (struct v4l2_format *)arg;
985 /* FIXME: Should be one dump per type */
986 dbgarg (cmd, "type=%s\n", prt_names(f->type,
987 v4l2_type_names));
989 switch (f->type) {
990 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
991 v4l_print_pix_fmt(vfd,&f->fmt.pix);
992 if (vfd->vidioc_s_fmt_cap)
993 ret=vfd->vidioc_s_fmt_cap(file, fh, f);
994 break;
995 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
996 if (vfd->vidioc_s_fmt_overlay)
997 ret=vfd->vidioc_s_fmt_overlay(file, fh, f);
998 break;
999 case V4L2_BUF_TYPE_VBI_CAPTURE:
1000 if (vfd->vidioc_s_fmt_vbi)
1001 ret=vfd->vidioc_s_fmt_vbi(file, fh, f);
1002 break;
1003 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
1004 if (vfd->vidioc_s_fmt_vbi_output)
1005 ret=vfd->vidioc_s_fmt_vbi_output(file, fh, f);
1006 break;
1007 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
1008 if (vfd->vidioc_s_fmt_vbi_capture)
1009 ret=vfd->vidioc_s_fmt_vbi_capture(file, fh, f);
1010 break;
1011 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
1012 if (vfd->vidioc_s_fmt_video_output)
1013 ret=vfd->vidioc_s_fmt_video_output(file,
1014 fh, f);
1015 break;
1016 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
1017 if (vfd->vidioc_s_fmt_output_overlay)
1018 ret=vfd->vidioc_s_fmt_output_overlay(file, fh, f);
1019 break;
1020 case V4L2_BUF_TYPE_VBI_OUTPUT:
1021 if (vfd->vidioc_s_fmt_vbi_output)
1022 ret=vfd->vidioc_s_fmt_vbi_output(file,
1023 fh, f);
1024 break;
1025 case V4L2_BUF_TYPE_PRIVATE:
1026 if (vfd->vidioc_s_fmt_type_private)
1027 ret=vfd->vidioc_s_fmt_type_private(file,
1028 fh, f);
1029 break;
1031 break;
1033 case VIDIOC_TRY_FMT:
1035 struct v4l2_format *f = (struct v4l2_format *)arg;
1037 /* FIXME: Should be one dump per type */
1038 dbgarg (cmd, "type=%s\n", prt_names(f->type,
1039 v4l2_type_names));
1040 switch (f->type) {
1041 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1042 if (vfd->vidioc_try_fmt_cap)
1043 ret=vfd->vidioc_try_fmt_cap(file, fh, f);
1044 if (!ret)
1045 v4l_print_pix_fmt(vfd,&f->fmt.pix);
1046 break;
1047 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
1048 if (vfd->vidioc_try_fmt_overlay)
1049 ret=vfd->vidioc_try_fmt_overlay(file, fh, f);
1050 break;
1051 case V4L2_BUF_TYPE_VBI_CAPTURE:
1052 if (vfd->vidioc_try_fmt_vbi)
1053 ret=vfd->vidioc_try_fmt_vbi(file, fh, f);
1054 break;
1055 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
1056 if (vfd->vidioc_try_fmt_vbi_output)
1057 ret=vfd->vidioc_try_fmt_vbi_output(file,
1058 fh, f);
1059 break;
1060 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
1061 if (vfd->vidioc_try_fmt_vbi_capture)
1062 ret=vfd->vidioc_try_fmt_vbi_capture(file,
1063 fh, f);
1064 break;
1065 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
1066 if (vfd->vidioc_try_fmt_video_output)
1067 ret=vfd->vidioc_try_fmt_video_output(file,
1068 fh, f);
1069 break;
1070 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
1071 if (vfd->vidioc_try_fmt_output_overlay)
1072 ret=vfd->vidioc_try_fmt_output_overlay(file, fh, f);
1073 break;
1074 case V4L2_BUF_TYPE_VBI_OUTPUT:
1075 if (vfd->vidioc_try_fmt_vbi_output)
1076 ret=vfd->vidioc_try_fmt_vbi_output(file,
1077 fh, f);
1078 break;
1079 case V4L2_BUF_TYPE_PRIVATE:
1080 if (vfd->vidioc_try_fmt_type_private)
1081 ret=vfd->vidioc_try_fmt_type_private(file,
1082 fh, f);
1083 break;
1086 break;
1088 /* FIXME: Those buf reqs could be handled here,
1089 with some changes on videobuf to allow its header to be included at
1090 videodev2.h or being merged at videodev2.
1092 case VIDIOC_REQBUFS:
1094 struct v4l2_requestbuffers *p=arg;
1096 if (!vfd->vidioc_reqbufs)
1097 break;
1098 ret = check_fmt (vfd, p->type);
1099 if (ret)
1100 break;
1102 ret=vfd->vidioc_reqbufs(file, fh, p);
1103 dbgarg (cmd, "count=%d, type=%s, memory=%s\n",
1104 p->count,
1105 prt_names(p->type, v4l2_type_names),
1106 prt_names(p->memory, v4l2_memory_names));
1107 break;
1109 case VIDIOC_QUERYBUF:
1111 struct v4l2_buffer *p=arg;
1113 if (!vfd->vidioc_querybuf)
1114 break;
1115 ret = check_fmt (vfd, p->type);
1116 if (ret)
1117 break;
1119 ret=vfd->vidioc_querybuf(file, fh, p);
1120 if (!ret)
1121 dbgbuf(cmd,vfd,p);
1122 break;
1124 case VIDIOC_QBUF:
1126 struct v4l2_buffer *p=arg;
1128 if (!vfd->vidioc_qbuf)
1129 break;
1130 ret = check_fmt (vfd, p->type);
1131 if (ret)
1132 break;
1134 ret=vfd->vidioc_qbuf(file, fh, p);
1135 if (!ret)
1136 dbgbuf(cmd,vfd,p);
1137 break;
1139 case VIDIOC_DQBUF:
1141 struct v4l2_buffer *p=arg;
1142 if (!vfd->vidioc_dqbuf)
1143 break;
1144 ret = check_fmt (vfd, p->type);
1145 if (ret)
1146 break;
1148 ret=vfd->vidioc_dqbuf(file, fh, p);
1149 if (!ret)
1150 dbgbuf(cmd,vfd,p);
1151 break;
1153 case VIDIOC_OVERLAY:
1155 int *i = arg;
1157 if (!vfd->vidioc_overlay)
1158 break;
1159 dbgarg (cmd, "value=%d\n",*i);
1160 ret=vfd->vidioc_overlay(file, fh, *i);
1161 break;
1163 case VIDIOC_G_FBUF:
1165 struct v4l2_framebuffer *p=arg;
1166 if (!vfd->vidioc_g_fbuf)
1167 break;
1168 ret=vfd->vidioc_g_fbuf(file, fh, arg);
1169 if (!ret) {
1170 dbgarg (cmd, "capability=%d, flags=%d, base=0x%08lx\n",
1171 p->capability,p->flags,
1172 (unsigned long)p->base);
1173 v4l_print_pix_fmt (vfd, &p->fmt);
1175 break;
1177 case VIDIOC_S_FBUF:
1179 struct v4l2_framebuffer *p=arg;
1180 if (!vfd->vidioc_s_fbuf)
1181 break;
1183 dbgarg (cmd, "capability=%d, flags=%d, base=0x%08lx\n",
1184 p->capability,p->flags,(unsigned long)p->base);
1185 v4l_print_pix_fmt (vfd, &p->fmt);
1186 ret=vfd->vidioc_s_fbuf(file, fh, arg);
1188 break;
1190 case VIDIOC_STREAMON:
1192 enum v4l2_buf_type i = *(int *)arg;
1193 if (!vfd->vidioc_streamon)
1194 break;
1195 dbgarg(cmd, "type=%s\n", prt_names(i, v4l2_type_names));
1196 ret=vfd->vidioc_streamon(file, fh,i);
1197 break;
1199 case VIDIOC_STREAMOFF:
1201 enum v4l2_buf_type i = *(int *)arg;
1203 if (!vfd->vidioc_streamoff)
1204 break;
1205 dbgarg(cmd, "type=%s\n", prt_names(i, v4l2_type_names));
1206 ret=vfd->vidioc_streamoff(file, fh, i);
1207 break;
1209 /* ---------- tv norms ---------- */
1210 case VIDIOC_ENUMSTD:
1212 struct v4l2_standard *p = arg;
1213 v4l2_std_id id = vfd->tvnorms,curr_id=0;
1214 unsigned int index = p->index,i;
1216 if (index<0) {
1217 ret=-EINVAL;
1218 break;
1221 /* Return norm array on a canonical way */
1222 for (i=0;i<= index && id; i++) {
1223 if ( (id & V4L2_STD_PAL) == V4L2_STD_PAL) {
1224 curr_id = V4L2_STD_PAL;
1225 } else if ( (id & V4L2_STD_PAL_BG) == V4L2_STD_PAL_BG) {
1226 curr_id = V4L2_STD_PAL_BG;
1227 } else if ( (id & V4L2_STD_PAL_DK) == V4L2_STD_PAL_DK) {
1228 curr_id = V4L2_STD_PAL_DK;
1229 } else if ( (id & V4L2_STD_PAL_B) == V4L2_STD_PAL_B) {
1230 curr_id = V4L2_STD_PAL_B;
1231 } else if ( (id & V4L2_STD_PAL_B1) == V4L2_STD_PAL_B1) {
1232 curr_id = V4L2_STD_PAL_B1;
1233 } else if ( (id & V4L2_STD_PAL_G) == V4L2_STD_PAL_G) {
1234 curr_id = V4L2_STD_PAL_G;
1235 } else if ( (id & V4L2_STD_PAL_H) == V4L2_STD_PAL_H) {
1236 curr_id = V4L2_STD_PAL_H;
1237 } else if ( (id & V4L2_STD_PAL_I) == V4L2_STD_PAL_I) {
1238 curr_id = V4L2_STD_PAL_I;
1239 } else if ( (id & V4L2_STD_PAL_D) == V4L2_STD_PAL_D) {
1240 curr_id = V4L2_STD_PAL_D;
1241 } else if ( (id & V4L2_STD_PAL_D1) == V4L2_STD_PAL_D1) {
1242 curr_id = V4L2_STD_PAL_D1;
1243 } else if ( (id & V4L2_STD_PAL_K) == V4L2_STD_PAL_K) {
1244 curr_id = V4L2_STD_PAL_K;
1245 } else if ( (id & V4L2_STD_PAL_M) == V4L2_STD_PAL_M) {
1246 curr_id = V4L2_STD_PAL_M;
1247 } else if ( (id & V4L2_STD_PAL_N) == V4L2_STD_PAL_N) {
1248 curr_id = V4L2_STD_PAL_N;
1249 } else if ( (id & V4L2_STD_PAL_Nc) == V4L2_STD_PAL_Nc) {
1250 curr_id = V4L2_STD_PAL_Nc;
1251 } else if ( (id & V4L2_STD_PAL_60) == V4L2_STD_PAL_60) {
1252 curr_id = V4L2_STD_PAL_60;
1253 } else if ( (id & V4L2_STD_NTSC) == V4L2_STD_NTSC) {
1254 curr_id = V4L2_STD_NTSC;
1255 } else if ( (id & V4L2_STD_NTSC_M) == V4L2_STD_NTSC_M) {
1256 curr_id = V4L2_STD_NTSC_M;
1257 } else if ( (id & V4L2_STD_NTSC_M_JP) == V4L2_STD_NTSC_M_JP) {
1258 curr_id = V4L2_STD_NTSC_M_JP;
1259 } else if ( (id & V4L2_STD_NTSC_443) == V4L2_STD_NTSC_443) {
1260 curr_id = V4L2_STD_NTSC_443;
1261 } else if ( (id & V4L2_STD_NTSC_M_KR) == V4L2_STD_NTSC_M_KR) {
1262 curr_id = V4L2_STD_NTSC_M_KR;
1263 } else if ( (id & V4L2_STD_SECAM) == V4L2_STD_SECAM) {
1264 curr_id = V4L2_STD_SECAM;
1265 } else if ( (id & V4L2_STD_SECAM_DK) == V4L2_STD_SECAM_DK) {
1266 curr_id = V4L2_STD_SECAM_DK;
1267 } else if ( (id & V4L2_STD_SECAM_B) == V4L2_STD_SECAM_B) {
1268 curr_id = V4L2_STD_SECAM_B;
1269 } else if ( (id & V4L2_STD_SECAM_D) == V4L2_STD_SECAM_D) {
1270 curr_id = V4L2_STD_SECAM_D;
1271 } else if ( (id & V4L2_STD_SECAM_G) == V4L2_STD_SECAM_G) {
1272 curr_id = V4L2_STD_SECAM_G;
1273 } else if ( (id & V4L2_STD_SECAM_H) == V4L2_STD_SECAM_H) {
1274 curr_id = V4L2_STD_SECAM_H;
1275 } else if ( (id & V4L2_STD_SECAM_K) == V4L2_STD_SECAM_K) {
1276 curr_id = V4L2_STD_SECAM_K;
1277 } else if ( (id & V4L2_STD_SECAM_K1) == V4L2_STD_SECAM_K1) {
1278 curr_id = V4L2_STD_SECAM_K1;
1279 } else if ( (id & V4L2_STD_SECAM_L) == V4L2_STD_SECAM_L) {
1280 curr_id = V4L2_STD_SECAM_L;
1281 } else if ( (id & V4L2_STD_SECAM_LC) == V4L2_STD_SECAM_LC) {
1282 curr_id = V4L2_STD_SECAM_LC;
1283 } else {
1284 break;
1286 id &= ~curr_id;
1288 if (i<=index)
1289 return -EINVAL;
1291 v4l2_video_std_construct(p, curr_id,v4l2_norm_to_name(curr_id));
1292 p->index = index;
1294 dbgarg (cmd, "index=%d, id=%Ld, name=%s, fps=%d/%d, "
1295 "framelines=%d\n", p->index,
1296 (unsigned long long)p->id, p->name,
1297 p->frameperiod.numerator,
1298 p->frameperiod.denominator,
1299 p->framelines);
1301 ret=0;
1302 break;
1304 case VIDIOC_G_STD:
1306 v4l2_std_id *id = arg;
1308 *id = vfd->current_norm;
1310 dbgarg (cmd, "value=%08Lx\n", (long long unsigned) *id);
1312 ret=0;
1313 break;
1315 case VIDIOC_S_STD:
1317 v4l2_std_id *id = arg,norm;
1319 dbgarg (cmd, "value=%08Lx\n", (long long unsigned) *id);
1321 norm = (*id) & vfd->tvnorms;
1322 if ( vfd->tvnorms && !norm) /* Check if std is supported */
1323 break;
1325 /* Calls the specific handler */
1326 if (vfd->vidioc_s_std)
1327 ret=vfd->vidioc_s_std(file, fh, &norm);
1328 else
1329 ret=-EINVAL;
1331 /* Updates standard information */
1332 if (ret>=0)
1333 vfd->current_norm=norm;
1335 break;
1337 case VIDIOC_QUERYSTD:
1339 v4l2_std_id *p=arg;
1341 if (!vfd->vidioc_querystd)
1342 break;
1343 ret=vfd->vidioc_querystd(file, fh, arg);
1344 if (!ret)
1345 dbgarg (cmd, "detected std=%08Lx\n",
1346 (unsigned long long)*p);
1347 break;
1349 /* ------ input switching ---------- */
1350 /* FIXME: Inputs can be handled inside videodev2 */
1351 case VIDIOC_ENUMINPUT:
1353 struct v4l2_input *p=arg;
1354 int i=p->index;
1356 if (!vfd->vidioc_enum_input)
1357 break;
1358 memset(p, 0, sizeof(*p));
1359 p->index=i;
1361 ret=vfd->vidioc_enum_input(file, fh, p);
1362 if (!ret)
1363 dbgarg (cmd, "index=%d, name=%s, type=%d, "
1364 "audioset=%d, "
1365 "tuner=%d, std=%08Lx, status=%d\n",
1366 p->index,p->name,p->type,p->audioset,
1367 p->tuner,
1368 (unsigned long long)p->std,
1369 p->status);
1370 break;
1372 case VIDIOC_G_INPUT:
1374 unsigned int *i = arg;
1376 if (!vfd->vidioc_g_input)
1377 break;
1378 ret=vfd->vidioc_g_input(file, fh, i);
1379 if (!ret)
1380 dbgarg (cmd, "value=%d\n",*i);
1381 break;
1383 case VIDIOC_S_INPUT:
1385 unsigned int *i = arg;
1387 if (!vfd->vidioc_s_input)
1388 break;
1389 dbgarg (cmd, "value=%d\n",*i);
1390 ret=vfd->vidioc_s_input(file, fh, *i);
1391 break;
1394 /* ------ output switching ---------- */
1395 case VIDIOC_G_OUTPUT:
1397 unsigned int *i = arg;
1399 if (!vfd->vidioc_g_output)
1400 break;
1401 ret=vfd->vidioc_g_output(file, fh, i);
1402 if (!ret)
1403 dbgarg (cmd, "value=%d\n",*i);
1404 break;
1406 case VIDIOC_S_OUTPUT:
1408 unsigned int *i = arg;
1410 if (!vfd->vidioc_s_output)
1411 break;
1412 dbgarg (cmd, "value=%d\n",*i);
1413 ret=vfd->vidioc_s_output(file, fh, *i);
1414 break;
1417 /* --- controls ---------------------------------------------- */
1418 case VIDIOC_QUERYCTRL:
1420 struct v4l2_queryctrl *p=arg;
1422 if (!vfd->vidioc_queryctrl)
1423 break;
1424 ret=vfd->vidioc_queryctrl(file, fh, p);
1426 if (!ret)
1427 dbgarg (cmd, "id=%d, type=%d, name=%s, "
1428 "min/max=%d/%d,"
1429 " step=%d, default=%d, flags=0x%08x\n",
1430 p->id,p->type,p->name,p->minimum,
1431 p->maximum,p->step,p->default_value,
1432 p->flags);
1433 break;
1435 case VIDIOC_G_CTRL:
1437 struct v4l2_control *p = arg;
1439 if (!vfd->vidioc_g_ctrl)
1440 break;
1441 dbgarg(cmd, "Enum for index=%d\n", p->id);
1443 ret=vfd->vidioc_g_ctrl(file, fh, p);
1444 if (!ret)
1445 dbgarg2 ( "id=%d, value=%d\n", p->id, p->value);
1446 break;
1448 case VIDIOC_S_CTRL:
1450 struct v4l2_control *p = arg;
1452 if (!vfd->vidioc_s_ctrl)
1453 break;
1454 dbgarg (cmd, "id=%d, value=%d\n", p->id, p->value);
1456 ret=vfd->vidioc_s_ctrl(file, fh, p);
1457 break;
1459 case VIDIOC_G_EXT_CTRLS:
1461 struct v4l2_ext_controls *p = arg;
1463 if (vfd->vidioc_g_ext_ctrls) {
1464 dbgarg(cmd, "count=%d\n", p->count);
1466 ret=vfd->vidioc_g_ext_ctrls(file, fh, p);
1468 break;
1470 case VIDIOC_S_EXT_CTRLS:
1472 struct v4l2_ext_controls *p = arg;
1474 if (vfd->vidioc_s_ext_ctrls) {
1475 dbgarg(cmd, "count=%d\n", p->count);
1477 ret=vfd->vidioc_s_ext_ctrls(file, fh, p);
1479 break;
1481 case VIDIOC_TRY_EXT_CTRLS:
1483 struct v4l2_ext_controls *p = arg;
1485 if (vfd->vidioc_try_ext_ctrls) {
1486 dbgarg(cmd, "count=%d\n", p->count);
1488 ret=vfd->vidioc_try_ext_ctrls(file, fh, p);
1490 break;
1492 case VIDIOC_QUERYMENU:
1494 struct v4l2_querymenu *p=arg;
1495 if (!vfd->vidioc_querymenu)
1496 break;
1497 ret=vfd->vidioc_querymenu(file, fh, p);
1498 if (!ret)
1499 dbgarg (cmd, "id=%d, index=%d, name=%s\n",
1500 p->id,p->index,p->name);
1501 break;
1503 /* --- audio ---------------------------------------------- */
1504 case VIDIOC_ENUMAUDIO:
1506 struct v4l2_audio *p=arg;
1508 if (!vfd->vidioc_enumaudio)
1509 break;
1510 dbgarg(cmd, "Enum for index=%d\n", p->index);
1511 ret=vfd->vidioc_enumaudio(file, fh, p);
1512 if (!ret)
1513 dbgarg2("index=%d, name=%s, capability=%d, "
1514 "mode=%d\n",p->index,p->name,
1515 p->capability, p->mode);
1516 break;
1518 case VIDIOC_G_AUDIO:
1520 struct v4l2_audio *p=arg;
1521 __u32 index=p->index;
1523 if (!vfd->vidioc_g_audio)
1524 break;
1526 memset(p,0,sizeof(*p));
1527 p->index=index;
1528 dbgarg(cmd, "Get for index=%d\n", p->index);
1529 ret=vfd->vidioc_g_audio(file, fh, p);
1530 if (!ret)
1531 dbgarg2("index=%d, name=%s, capability=%d, "
1532 "mode=%d\n",p->index,
1533 p->name,p->capability, p->mode);
1534 break;
1536 case VIDIOC_S_AUDIO:
1538 struct v4l2_audio *p=arg;
1540 if (!vfd->vidioc_s_audio)
1541 break;
1542 dbgarg(cmd, "index=%d, name=%s, capability=%d, "
1543 "mode=%d\n", p->index, p->name,
1544 p->capability, p->mode);
1545 ret=vfd->vidioc_s_audio(file, fh, p);
1546 break;
1548 case VIDIOC_ENUMAUDOUT:
1550 struct v4l2_audioout *p=arg;
1552 if (!vfd->vidioc_enumaudout)
1553 break;
1554 dbgarg(cmd, "Enum for index=%d\n", p->index);
1555 ret=vfd->vidioc_enumaudout(file, fh, p);
1556 if (!ret)
1557 dbgarg2("index=%d, name=%s, capability=%d, "
1558 "mode=%d\n", p->index, p->name,
1559 p->capability,p->mode);
1560 break;
1562 case VIDIOC_G_AUDOUT:
1564 struct v4l2_audioout *p=arg;
1566 if (!vfd->vidioc_g_audout)
1567 break;
1568 dbgarg(cmd, "Enum for index=%d\n", p->index);
1569 ret=vfd->vidioc_g_audout(file, fh, p);
1570 if (!ret)
1571 dbgarg2("index=%d, name=%s, capability=%d, "
1572 "mode=%d\n", p->index, p->name,
1573 p->capability,p->mode);
1574 break;
1576 case VIDIOC_S_AUDOUT:
1578 struct v4l2_audioout *p=arg;
1580 if (!vfd->vidioc_s_audout)
1581 break;
1582 dbgarg(cmd, "index=%d, name=%s, capability=%d, "
1583 "mode=%d\n", p->index, p->name,
1584 p->capability,p->mode);
1586 ret=vfd->vidioc_s_audout(file, fh, p);
1587 break;
1589 case VIDIOC_G_MODULATOR:
1591 struct v4l2_modulator *p=arg;
1592 if (!vfd->vidioc_g_modulator)
1593 break;
1594 ret=vfd->vidioc_g_modulator(file, fh, p);
1595 if (!ret)
1596 dbgarg(cmd, "index=%d, name=%s, "
1597 "capability=%d, rangelow=%d,"
1598 " rangehigh=%d, txsubchans=%d\n",
1599 p->index, p->name,p->capability,
1600 p->rangelow, p->rangehigh,
1601 p->txsubchans);
1602 break;
1604 case VIDIOC_S_MODULATOR:
1606 struct v4l2_modulator *p=arg;
1607 if (!vfd->vidioc_s_modulator)
1608 break;
1609 dbgarg(cmd, "index=%d, name=%s, capability=%d, "
1610 "rangelow=%d, rangehigh=%d, txsubchans=%d\n",
1611 p->index, p->name,p->capability,p->rangelow,
1612 p->rangehigh,p->txsubchans);
1613 ret=vfd->vidioc_s_modulator(file, fh, p);
1614 break;
1616 case VIDIOC_G_CROP:
1618 struct v4l2_crop *p=arg;
1619 if (!vfd->vidioc_g_crop)
1620 break;
1621 ret=vfd->vidioc_g_crop(file, fh, p);
1622 if (!ret) {
1623 dbgarg(cmd, "type=%d\n", p->type);
1624 dbgrect(vfd, "", &p->c);
1626 break;
1628 case VIDIOC_S_CROP:
1630 struct v4l2_crop *p=arg;
1631 if (!vfd->vidioc_s_crop)
1632 break;
1633 dbgarg(cmd, "type=%d\n", p->type);
1634 dbgrect(vfd, "", &p->c);
1635 ret=vfd->vidioc_s_crop(file, fh, p);
1636 break;
1638 case VIDIOC_CROPCAP:
1640 struct v4l2_cropcap *p=arg;
1641 /*FIXME: Should also show v4l2_fract pixelaspect */
1642 if (!vfd->vidioc_cropcap)
1643 break;
1644 dbgarg(cmd, "type=%d\n", p->type);
1645 dbgrect(vfd, "bounds ", &p->bounds);
1646 dbgrect(vfd, "defrect ", &p->defrect);
1647 ret=vfd->vidioc_cropcap(file, fh, p);
1648 break;
1650 case VIDIOC_G_JPEGCOMP:
1652 struct v4l2_jpegcompression *p=arg;
1653 if (!vfd->vidioc_g_jpegcomp)
1654 break;
1655 ret=vfd->vidioc_g_jpegcomp(file, fh, p);
1656 if (!ret)
1657 dbgarg (cmd, "quality=%d, APPn=%d, "
1658 "APP_len=%d, COM_len=%d, "
1659 "jpeg_markers=%d\n",
1660 p->quality,p->APPn,p->APP_len,
1661 p->COM_len,p->jpeg_markers);
1662 break;
1664 case VIDIOC_S_JPEGCOMP:
1666 struct v4l2_jpegcompression *p=arg;
1667 if (!vfd->vidioc_g_jpegcomp)
1668 break;
1669 dbgarg (cmd, "quality=%d, APPn=%d, APP_len=%d, "
1670 "COM_len=%d, jpeg_markers=%d\n",
1671 p->quality,p->APPn,p->APP_len,
1672 p->COM_len,p->jpeg_markers);
1673 ret=vfd->vidioc_s_jpegcomp(file, fh, p);
1674 break;
1676 case VIDIOC_G_ENC_INDEX:
1678 struct v4l2_enc_idx *p=arg;
1680 if (!vfd->vidioc_g_enc_index)
1681 break;
1682 ret=vfd->vidioc_g_enc_index(file, fh, p);
1683 if (!ret)
1684 dbgarg (cmd, "entries=%d, entries_cap=%d\n",
1685 p->entries,p->entries_cap);
1686 break;
1688 case VIDIOC_ENCODER_CMD:
1690 struct v4l2_encoder_cmd *p=arg;
1692 if (!vfd->vidioc_encoder_cmd)
1693 break;
1694 ret=vfd->vidioc_encoder_cmd(file, fh, p);
1695 if (!ret)
1696 dbgarg (cmd, "cmd=%d, flags=%d\n",
1697 p->cmd,p->flags);
1698 break;
1700 case VIDIOC_TRY_ENCODER_CMD:
1702 struct v4l2_encoder_cmd *p=arg;
1704 if (!vfd->vidioc_try_encoder_cmd)
1705 break;
1706 ret=vfd->vidioc_try_encoder_cmd(file, fh, p);
1707 if (!ret)
1708 dbgarg (cmd, "cmd=%d, flags=%d\n",
1709 p->cmd,p->flags);
1710 break;
1712 case VIDIOC_G_PARM:
1714 struct v4l2_streamparm *p=arg;
1715 __u32 type=p->type;
1717 memset(p,0,sizeof(*p));
1718 p->type=type;
1720 if (vfd->vidioc_g_parm) {
1721 ret=vfd->vidioc_g_parm(file, fh, p);
1722 } else {
1723 struct v4l2_standard s;
1725 if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1726 return -EINVAL;
1728 v4l2_video_std_construct(&s, vfd->current_norm,
1729 v4l2_norm_to_name(vfd->current_norm));
1731 p->parm.capture.timeperframe = s.frameperiod;
1732 ret=0;
1735 dbgarg (cmd, "type=%d\n", p->type);
1736 break;
1738 case VIDIOC_S_PARM:
1740 struct v4l2_streamparm *p=arg;
1741 if (!vfd->vidioc_s_parm)
1742 break;
1743 dbgarg (cmd, "type=%d\n", p->type);
1744 ret=vfd->vidioc_s_parm(file, fh, p);
1745 break;
1747 case VIDIOC_G_TUNER:
1749 struct v4l2_tuner *p=arg;
1750 __u32 index=p->index;
1752 if (!vfd->vidioc_g_tuner)
1753 break;
1755 memset(p,0,sizeof(*p));
1756 p->index=index;
1758 ret=vfd->vidioc_g_tuner(file, fh, p);
1759 if (!ret)
1760 dbgarg (cmd, "index=%d, name=%s, type=%d, "
1761 "capability=%d, rangelow=%d, "
1762 "rangehigh=%d, signal=%d, afc=%d, "
1763 "rxsubchans=%d, audmode=%d\n",
1764 p->index, p->name, p->type,
1765 p->capability, p->rangelow,
1766 p->rangehigh, p->rxsubchans,
1767 p->audmode, p->signal, p->afc);
1768 break;
1770 case VIDIOC_S_TUNER:
1772 struct v4l2_tuner *p=arg;
1773 if (!vfd->vidioc_s_tuner)
1774 break;
1775 dbgarg (cmd, "index=%d, name=%s, type=%d, "
1776 "capability=%d, rangelow=%d, rangehigh=%d, "
1777 "signal=%d, afc=%d, rxsubchans=%d, "
1778 "audmode=%d\n",p->index, p->name, p->type,
1779 p->capability, p->rangelow,p->rangehigh,
1780 p->rxsubchans, p->audmode, p->signal,
1781 p->afc);
1782 ret=vfd->vidioc_s_tuner(file, fh, p);
1783 break;
1785 case VIDIOC_G_FREQUENCY:
1787 struct v4l2_frequency *p=arg;
1788 if (!vfd->vidioc_g_frequency)
1789 break;
1791 memset(p,0,sizeof(*p));
1793 ret=vfd->vidioc_g_frequency(file, fh, p);
1794 if (!ret)
1795 dbgarg (cmd, "tuner=%d, type=%d, frequency=%d\n",
1796 p->tuner,p->type,p->frequency);
1797 break;
1799 case VIDIOC_S_FREQUENCY:
1801 struct v4l2_frequency *p=arg;
1802 if (!vfd->vidioc_s_frequency)
1803 break;
1804 dbgarg (cmd, "tuner=%d, type=%d, frequency=%d\n",
1805 p->tuner,p->type,p->frequency);
1806 ret=vfd->vidioc_s_frequency(file, fh, p);
1807 break;
1809 case VIDIOC_G_SLICED_VBI_CAP:
1811 struct v4l2_sliced_vbi_cap *p=arg;
1812 if (!vfd->vidioc_g_sliced_vbi_cap)
1813 break;
1814 ret=vfd->vidioc_g_sliced_vbi_cap(file, fh, p);
1815 if (!ret)
1816 dbgarg (cmd, "service_set=%d\n", p->service_set);
1817 break;
1819 case VIDIOC_LOG_STATUS:
1821 if (!vfd->vidioc_log_status)
1822 break;
1823 ret=vfd->vidioc_log_status(file, fh);
1824 break;
1826 #ifdef CONFIG_VIDEO_ADV_DEBUG
1827 case VIDIOC_DBG_G_REGISTER:
1829 struct v4l2_register *p=arg;
1830 if (!capable(CAP_SYS_ADMIN))
1831 ret=-EPERM;
1832 else if (vfd->vidioc_g_register)
1833 ret=vfd->vidioc_g_register(file, fh, p);
1834 break;
1836 case VIDIOC_DBG_S_REGISTER:
1838 struct v4l2_register *p=arg;
1839 if (!capable(CAP_SYS_ADMIN))
1840 ret=-EPERM;
1841 else if (vfd->vidioc_s_register)
1842 ret=vfd->vidioc_s_register(file, fh, p);
1843 break;
1845 #endif
1846 case VIDIOC_G_CHIP_IDENT:
1848 struct v4l2_chip_ident *p=arg;
1849 if (!vfd->vidioc_g_chip_ident)
1850 break;
1851 ret=vfd->vidioc_g_chip_ident(file, fh, p);
1852 if (!ret)
1853 dbgarg (cmd, "chip_ident=%u, revision=0x%x\n", p->ident, p->revision);
1854 break;
1856 } /* switch */
1858 if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) {
1859 if (ret<0) {
1860 printk ("%s: err:\n", vfd->name);
1861 v4l_print_ioctl(vfd->name, cmd);
1865 return ret;
1868 int video_ioctl2 (struct inode *inode, struct file *file,
1869 unsigned int cmd, unsigned long arg)
1871 char sbuf[128];
1872 void *mbuf = NULL;
1873 void *parg = NULL;
1874 int err = -EINVAL;
1875 int is_ext_ctrl;
1876 size_t ctrls_size = 0;
1877 void __user *user_ptr = NULL;
1879 #ifdef __OLD_VIDIOC_
1880 cmd = video_fix_command(cmd);
1881 #endif
1882 is_ext_ctrl = (cmd == VIDIOC_S_EXT_CTRLS || cmd == VIDIOC_G_EXT_CTRLS ||
1883 cmd == VIDIOC_TRY_EXT_CTRLS);
1885 /* Copy arguments into temp kernel buffer */
1886 switch (_IOC_DIR(cmd)) {
1887 case _IOC_NONE:
1888 parg = NULL;
1889 break;
1890 case _IOC_READ:
1891 case _IOC_WRITE:
1892 case (_IOC_WRITE | _IOC_READ):
1893 if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
1894 parg = sbuf;
1895 } else {
1896 /* too big to allocate from stack */
1897 mbuf = kmalloc(_IOC_SIZE(cmd),GFP_KERNEL);
1898 if (NULL == mbuf)
1899 return -ENOMEM;
1900 parg = mbuf;
1903 err = -EFAULT;
1904 if (_IOC_DIR(cmd) & _IOC_WRITE)
1905 if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd)))
1906 goto out;
1907 break;
1910 if (is_ext_ctrl) {
1911 struct v4l2_ext_controls *p = parg;
1913 /* In case of an error, tell the caller that it wasn't
1914 a specific control that caused it. */
1915 p->error_idx = p->count;
1916 user_ptr = (void __user *)p->controls;
1917 if (p->count) {
1918 ctrls_size = sizeof(struct v4l2_ext_control) * p->count;
1919 /* Note: v4l2_ext_controls fits in sbuf[] so mbuf is still NULL. */
1920 mbuf = kmalloc(ctrls_size, GFP_KERNEL);
1921 err = -ENOMEM;
1922 if (NULL == mbuf)
1923 goto out_ext_ctrl;
1924 err = -EFAULT;
1925 if (copy_from_user(mbuf, user_ptr, ctrls_size))
1926 goto out_ext_ctrl;
1927 p->controls = mbuf;
1931 /* Handles IOCTL */
1932 err = __video_do_ioctl(inode, file, cmd, parg);
1933 if (err == -ENOIOCTLCMD)
1934 err = -EINVAL;
1935 if (is_ext_ctrl) {
1936 struct v4l2_ext_controls *p = parg;
1938 p->controls = (void *)user_ptr;
1939 if (p->count && err == 0 && copy_to_user(user_ptr, mbuf, ctrls_size))
1940 err = -EFAULT;
1941 goto out_ext_ctrl;
1943 if (err < 0)
1944 goto out;
1946 out_ext_ctrl:
1947 /* Copy results into user buffer */
1948 switch (_IOC_DIR(cmd))
1950 case _IOC_READ:
1951 case (_IOC_WRITE | _IOC_READ):
1952 if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd)))
1953 err = -EFAULT;
1954 break;
1957 out:
1958 kfree(mbuf);
1959 return err;
1961 EXPORT_SYMBOL(video_ioctl2);
1963 static const struct file_operations video_fops;
1966 * video_register_device - register video4linux devices
1967 * @vfd: video device structure we want to register
1968 * @type: type of device to register
1969 * @nr: which device number (0 == /dev/video0, 1 == /dev/video1, ...
1970 * -1 == first free)
1972 * The registration code assigns minor numbers based on the type
1973 * requested. -ENFILE is returned in all the device slots for this
1974 * category are full. If not then the minor field is set and the
1975 * driver initialize function is called (if non %NULL).
1977 * Zero is returned on success.
1979 * Valid types are
1981 * %VFL_TYPE_GRABBER - A frame grabber
1983 * %VFL_TYPE_VTX - A teletext device
1985 * %VFL_TYPE_VBI - Vertical blank data (undecoded)
1987 * %VFL_TYPE_RADIO - A radio card
1990 int video_register_device(struct video_device *vfd, int type, int nr)
1992 int i=0;
1993 int base;
1994 int end;
1995 int ret;
1996 char *name_base;
1998 switch(type)
2000 case VFL_TYPE_GRABBER:
2001 base=MINOR_VFL_TYPE_GRABBER_MIN;
2002 end=MINOR_VFL_TYPE_GRABBER_MAX+1;
2003 name_base = "video";
2004 break;
2005 case VFL_TYPE_VTX:
2006 base=MINOR_VFL_TYPE_VTX_MIN;
2007 end=MINOR_VFL_TYPE_VTX_MAX+1;
2008 name_base = "vtx";
2009 break;
2010 case VFL_TYPE_VBI:
2011 base=MINOR_VFL_TYPE_VBI_MIN;
2012 end=MINOR_VFL_TYPE_VBI_MAX+1;
2013 name_base = "vbi";
2014 break;
2015 case VFL_TYPE_RADIO:
2016 base=MINOR_VFL_TYPE_RADIO_MIN;
2017 end=MINOR_VFL_TYPE_RADIO_MAX+1;
2018 name_base = "radio";
2019 break;
2020 default:
2021 printk(KERN_ERR "%s called with unknown type: %d\n",
2022 __FUNCTION__, type);
2023 return -1;
2026 /* pick a minor number */
2027 mutex_lock(&videodev_lock);
2028 if (nr >= 0 && nr < end-base) {
2029 /* use the one the driver asked for */
2030 i = base+nr;
2031 if (NULL != video_device[i]) {
2032 mutex_unlock(&videodev_lock);
2033 return -ENFILE;
2035 } else {
2036 /* use first free */
2037 for(i=base;i<end;i++)
2038 if (NULL == video_device[i])
2039 break;
2040 if (i == end) {
2041 mutex_unlock(&videodev_lock);
2042 return -ENFILE;
2045 video_device[i]=vfd;
2046 vfd->minor=i;
2047 mutex_unlock(&videodev_lock);
2048 mutex_init(&vfd->lock);
2050 /* sysfs class */
2051 memset(&vfd->class_dev, 0x00, sizeof(vfd->class_dev));
2052 if (vfd->dev)
2053 vfd->class_dev.parent = vfd->dev;
2054 vfd->class_dev.class = &video_class;
2055 vfd->class_dev.devt = MKDEV(VIDEO_MAJOR, vfd->minor);
2056 sprintf(vfd->class_dev.bus_id, "%s%d", name_base, i - base);
2057 ret = device_register(&vfd->class_dev);
2058 if (ret < 0) {
2059 printk(KERN_ERR "%s: device_register failed\n",
2060 __FUNCTION__);
2061 goto fail_minor;
2064 #if 1
2065 /* needed until all drivers are fixed */
2066 if (!vfd->release)
2067 printk(KERN_WARNING "videodev: \"%s\" has no release callback. "
2068 "Please fix your driver for proper sysfs support, see "
2069 "http://lwn.net/Articles/36850/\n", vfd->name);
2070 #endif
2071 return 0;
2073 fail_minor:
2074 mutex_lock(&videodev_lock);
2075 video_device[vfd->minor] = NULL;
2076 vfd->minor = -1;
2077 mutex_unlock(&videodev_lock);
2078 return ret;
2080 EXPORT_SYMBOL(video_register_device);
2083 * video_unregister_device - unregister a video4linux device
2084 * @vfd: the device to unregister
2086 * This unregisters the passed device and deassigns the minor
2087 * number. Future open calls will be met with errors.
2090 void video_unregister_device(struct video_device *vfd)
2092 mutex_lock(&videodev_lock);
2093 if(video_device[vfd->minor]!=vfd)
2094 panic("videodev: bad unregister");
2096 video_device[vfd->minor]=NULL;
2097 device_unregister(&vfd->class_dev);
2098 mutex_unlock(&videodev_lock);
2100 EXPORT_SYMBOL(video_unregister_device);
2103 * Video fs operations
2105 static const struct file_operations video_fops=
2107 .owner = THIS_MODULE,
2108 .llseek = no_llseek,
2109 .open = video_open,
2113 * Initialise video for linux
2116 static int __init videodev_init(void)
2118 int ret;
2120 printk(KERN_INFO "Linux video capture interface: v2.00\n");
2121 if (register_chrdev(VIDEO_MAJOR, VIDEO_NAME, &video_fops)) {
2122 printk(KERN_WARNING "video_dev: unable to get major %d\n", VIDEO_MAJOR);
2123 return -EIO;
2126 ret = class_register(&video_class);
2127 if (ret < 0) {
2128 unregister_chrdev(VIDEO_MAJOR, VIDEO_NAME);
2129 printk(KERN_WARNING "video_dev: class_register failed\n");
2130 return -EIO;
2133 return 0;
2136 static void __exit videodev_exit(void)
2138 class_unregister(&video_class);
2139 unregister_chrdev(VIDEO_MAJOR, VIDEO_NAME);
2142 module_init(videodev_init)
2143 module_exit(videodev_exit)
2145 MODULE_AUTHOR("Alan Cox, Mauro Carvalho Chehab <mchehab@infradead.org>");
2146 MODULE_DESCRIPTION("Device registrar for Video4Linux drivers v2");
2147 MODULE_LICENSE("GPL");
2151 * Local variables:
2152 * c-basic-offset: 8
2153 * End: