blob: ddfd80c5618bcb6b74665e78c73a3996b0a6e3dd [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * Video for Linux Two
3 *
4 * A generic video device interface for the LINUX operating system
5 * using a set of device structures/vectors for low level operations.
6 *
7 * This file replaces the videodev.c file that comes with the
8 * regular kernel distribution.
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version
13 * 2 of the License, or (at your option) any later version.
14 *
Mauro Carvalho Chehab43db48d2007-01-09 11:20:59 -030015 * Author: Bill Dirks <bill@thedirks.org>
Linus Torvalds1da177e2005-04-16 15:20:36 -070016 * based on code by Alan Cox, <alan@cymru.net>
17 *
18 */
19
20/*
21 * Video capture interface for Linux
22 *
23 * A generic video device interface for the LINUX operating system
24 * using a set of device structures/vectors for low level operations.
25 *
26 * This program is free software; you can redistribute it and/or
27 * modify it under the terms of the GNU General Public License
28 * as published by the Free Software Foundation; either version
29 * 2 of the License, or (at your option) any later version.
30 *
31 * Author: Alan Cox, <alan@redhat.com>
32 *
33 * Fixes:
34 */
35
36/*
37 * Video4linux 1/2 integration by Justin Schoeman
38 * <justin@suntiger.ee.up.ac.za>
39 * 2.4 PROCFS support ported from 2.4 kernels by
40 * Iñaki García Etxebarria <garetxe@euskalnet.net>
41 * Makefile fix by "W. Michael Petullo" <mike@flyn.org>
42 * 2.4 devfs support ported from 2.4 kernels by
43 * Dan Merillat <dan@merillat.org>
44 * Added Gerd Knorrs v4l1 enhancements (Justin Schoeman)
45 */
46
Linus Torvalds1da177e2005-04-16 15:20:36 -070047#include <linux/module.h>
48#include <linux/types.h>
49#include <linux/kernel.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070050#include <linux/smp_lock.h>
51#include <linux/mm.h>
52#include <linux/string.h>
53#include <linux/errno.h>
54#include <asm/uaccess.h>
55#include <asm/system.h>
56#include <asm/pgtable.h>
57#include <asm/io.h>
58#include <asm/div64.h>
Michael Krufky5e453dc2006-01-09 15:32:31 -020059#include <linux/video_decoder.h>
Mauro Carvalho Chehab401998f2006-06-04 10:06:18 -030060#define __OLD_VIDIOC_ /* To allow fixing old calls*/
Michael Krufky5e453dc2006-01-09 15:32:31 -020061#include <media/v4l2-common.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070062
63#ifdef CONFIG_KMOD
64#include <linux/kmod.h>
65#endif
66
67#if defined(CONFIG_UST) || defined(CONFIG_UST_MODULE)
68#include <linux/ust.h>
69#endif
70
71
72#include <linux/videodev.h>
73
74MODULE_AUTHOR("Bill Dirks, Justin Schoeman, Gerd Knorr");
75MODULE_DESCRIPTION("misc helper functions for v4l2 device drivers");
76MODULE_LICENSE("GPL");
77
78/*
79 *
80 * V 4 L 2 D R I V E R H E L P E R A P I
81 *
82 */
83
84/*
85 * Video Standard Operations (contributed by Michael Schimek)
86 */
87
Linus Torvalds1da177e2005-04-16 15:20:36 -070088
Mauro Carvalho Chehabe75f9ce2006-11-20 13:19:20 -030089char *v4l2_norm_to_name(v4l2_std_id id)
90{
91 char *name;
Mauro Carvalho Chehab412297d32007-01-07 08:51:05 -030092 u32 myid = id;
Mauro Carvalho Chehabe75f9ce2006-11-20 13:19:20 -030093
Mauro Carvalho Chehab412297d32007-01-07 08:51:05 -030094 /* HACK: ppc32 architecture doesn't have __ucmpdi2 function to handle
95 64 bit comparations. So, on that architecture, with some gcc variants,
96 compilation fails. Currently, the max value is 30bit wide.
97 */
98 BUG_ON(myid != id);
99
100 switch (myid) {
Mauro Carvalho Chehabe75f9ce2006-11-20 13:19:20 -0300101 case V4L2_STD_PAL:
102 name="PAL"; break;
103 case V4L2_STD_PAL_BG:
104 name="PAL-BG"; break;
105 case V4L2_STD_PAL_DK:
106 name="PAL-DK"; break;
107 case V4L2_STD_PAL_B:
108 name="PAL-B"; break;
109 case V4L2_STD_PAL_B1:
110 name="PAL-B1"; break;
111 case V4L2_STD_PAL_G:
112 name="PAL-G"; break;
113 case V4L2_STD_PAL_H:
114 name="PAL-H"; break;
115 case V4L2_STD_PAL_I:
116 name="PAL-I"; break;
117 case V4L2_STD_PAL_D:
118 name="PAL-D"; break;
119 case V4L2_STD_PAL_D1:
120 name="PAL-D1"; break;
121 case V4L2_STD_PAL_K:
122 name="PAL-K"; break;
123 case V4L2_STD_PAL_M:
124 name="PAL-M"; break;
125 case V4L2_STD_PAL_N:
126 name="PAL-N"; break;
127 case V4L2_STD_PAL_Nc:
128 name="PAL-Nc"; break;
129 case V4L2_STD_PAL_60:
130 name="PAL-60"; break;
131 case V4L2_STD_NTSC:
132 name="NTSC"; break;
133 case V4L2_STD_NTSC_M:
134 name="NTSC-M"; break;
135 case V4L2_STD_NTSC_M_JP:
136 name="NTSC-M-JP"; break;
137 case V4L2_STD_NTSC_443:
138 name="NTSC-443"; break;
139 case V4L2_STD_NTSC_M_KR:
140 name="NTSC-M-KR"; break;
141 case V4L2_STD_SECAM:
142 name="SECAM"; break;
143 case V4L2_STD_SECAM_DK:
144 name="SECAM-DK"; break;
145 case V4L2_STD_SECAM_B:
146 name="SECAM-B"; break;
147 case V4L2_STD_SECAM_D:
148 name="SECAM-D"; break;
149 case V4L2_STD_SECAM_G:
150 name="SECAM-G"; break;
151 case V4L2_STD_SECAM_H:
152 name="SECAM-H"; break;
153 case V4L2_STD_SECAM_K:
154 name="SECAM-K"; break;
155 case V4L2_STD_SECAM_K1:
156 name="SECAM-K1"; break;
157 case V4L2_STD_SECAM_L:
158 name="SECAM-L"; break;
159 case V4L2_STD_SECAM_LC:
160 name="SECAM-LC"; break;
161 default:
162 name="Unknown"; break;
163 }
164
165 return name;
166}
167
Linus Torvalds1da177e2005-04-16 15:20:36 -0700168/* Fill in the fields of a v4l2_standard structure according to the
169 'id' and 'transmission' parameters. Returns negative on error. */
170int v4l2_video_std_construct(struct v4l2_standard *vs,
171 int id, char *name)
172{
173 u32 index = vs->index;
174
175 memset(vs, 0, sizeof(struct v4l2_standard));
176 vs->index = index;
177 vs->id = id;
Mauro Carvalho Chehab3ed33c32006-02-27 00:08:52 -0300178 if (id & V4L2_STD_525_60) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700179 vs->frameperiod.numerator = 1001;
180 vs->frameperiod.denominator = 30000;
181 vs->framelines = 525;
182 } else {
183 vs->frameperiod.numerator = 1;
184 vs->frameperiod.denominator = 25;
185 vs->framelines = 625;
186 }
187 strlcpy(vs->name,name,sizeof(vs->name));
188 return 0;
189}
190
Linus Torvalds1da177e2005-04-16 15:20:36 -0700191/* ----------------------------------------------------------------- */
192/* priority handling */
193
194#define V4L2_PRIO_VALID(val) (val == V4L2_PRIORITY_BACKGROUND || \
195 val == V4L2_PRIORITY_INTERACTIVE || \
196 val == V4L2_PRIORITY_RECORD)
197
198int v4l2_prio_init(struct v4l2_prio_state *global)
199{
200 memset(global,0,sizeof(*global));
201 return 0;
202}
203
204int v4l2_prio_change(struct v4l2_prio_state *global, enum v4l2_priority *local,
205 enum v4l2_priority new)
206{
207 if (!V4L2_PRIO_VALID(new))
208 return -EINVAL;
209 if (*local == new)
210 return 0;
211
212 atomic_inc(&global->prios[new]);
213 if (V4L2_PRIO_VALID(*local))
214 atomic_dec(&global->prios[*local]);
215 *local = new;
216 return 0;
217}
218
219int v4l2_prio_open(struct v4l2_prio_state *global, enum v4l2_priority *local)
220{
221 return v4l2_prio_change(global,local,V4L2_PRIORITY_DEFAULT);
222}
223
224int v4l2_prio_close(struct v4l2_prio_state *global, enum v4l2_priority *local)
225{
226 if (V4L2_PRIO_VALID(*local))
227 atomic_dec(&global->prios[*local]);
228 return 0;
229}
230
231enum v4l2_priority v4l2_prio_max(struct v4l2_prio_state *global)
232{
233 if (atomic_read(&global->prios[V4L2_PRIORITY_RECORD]) > 0)
234 return V4L2_PRIORITY_RECORD;
235 if (atomic_read(&global->prios[V4L2_PRIORITY_INTERACTIVE]) > 0)
236 return V4L2_PRIORITY_INTERACTIVE;
237 if (atomic_read(&global->prios[V4L2_PRIORITY_BACKGROUND]) > 0)
238 return V4L2_PRIORITY_BACKGROUND;
239 return V4L2_PRIORITY_UNSET;
240}
241
242int v4l2_prio_check(struct v4l2_prio_state *global, enum v4l2_priority *local)
243{
244 if (*local < v4l2_prio_max(global))
245 return -EBUSY;
246 return 0;
247}
248
249
250/* ----------------------------------------------------------------- */
Mauro Carvalho Chehab2e0d4472006-02-27 00:08:58 -0300251/* some arrays for pretty-printing debug messages of enum types */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700252
253char *v4l2_field_names[] = {
254 [V4L2_FIELD_ANY] = "any",
255 [V4L2_FIELD_NONE] = "none",
256 [V4L2_FIELD_TOP] = "top",
257 [V4L2_FIELD_BOTTOM] = "bottom",
258 [V4L2_FIELD_INTERLACED] = "interlaced",
259 [V4L2_FIELD_SEQ_TB] = "seq-tb",
260 [V4L2_FIELD_SEQ_BT] = "seq-bt",
261 [V4L2_FIELD_ALTERNATE] = "alternate",
262};
263
264char *v4l2_type_names[] = {
Mauro Carvalho Chehabed580142006-11-16 11:02:28 -0300265 [V4L2_BUF_TYPE_VIDEO_CAPTURE] = "video-cap",
266 [V4L2_BUF_TYPE_VIDEO_OVERLAY] = "video-over",
267 [V4L2_BUF_TYPE_VIDEO_OUTPUT] = "video-out",
268 [V4L2_BUF_TYPE_VBI_CAPTURE] = "vbi-cap",
269 [V4L2_BUF_TYPE_VBI_OUTPUT] = "vbi-out",
270 [V4L2_BUF_TYPE_SLICED_VBI_CAPTURE] = "sliced-vbi-cap",
271 [V4L2_BUF_TYPE_SLICED_VBI_OUTPUT] = "slicec-vbi-out",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700272};
273
Mauro Carvalho Chehab2e0d4472006-02-27 00:08:58 -0300274
275#define prt_names(a,arr) (((a)>=0)&&((a)<ARRAY_SIZE(arr)))?arr[a]:"unknown"
276
Michael Krufky5e453dc2006-01-09 15:32:31 -0200277/* ------------------------------------------------------------------ */
278/* debug help functions */
279
Mauro Carvalho Chehab0dfa9ab2006-08-08 09:10:10 -0300280#ifdef CONFIG_VIDEO_V4L1_COMPAT
Michael Krufky5e453dc2006-01-09 15:32:31 -0200281static const char *v4l1_ioctls[] = {
282 [_IOC_NR(VIDIOCGCAP)] = "VIDIOCGCAP",
283 [_IOC_NR(VIDIOCGCHAN)] = "VIDIOCGCHAN",
284 [_IOC_NR(VIDIOCSCHAN)] = "VIDIOCSCHAN",
285 [_IOC_NR(VIDIOCGTUNER)] = "VIDIOCGTUNER",
286 [_IOC_NR(VIDIOCSTUNER)] = "VIDIOCSTUNER",
287 [_IOC_NR(VIDIOCGPICT)] = "VIDIOCGPICT",
288 [_IOC_NR(VIDIOCSPICT)] = "VIDIOCSPICT",
289 [_IOC_NR(VIDIOCCAPTURE)] = "VIDIOCCAPTURE",
290 [_IOC_NR(VIDIOCGWIN)] = "VIDIOCGWIN",
291 [_IOC_NR(VIDIOCSWIN)] = "VIDIOCSWIN",
292 [_IOC_NR(VIDIOCGFBUF)] = "VIDIOCGFBUF",
293 [_IOC_NR(VIDIOCSFBUF)] = "VIDIOCSFBUF",
294 [_IOC_NR(VIDIOCKEY)] = "VIDIOCKEY",
295 [_IOC_NR(VIDIOCGFREQ)] = "VIDIOCGFREQ",
296 [_IOC_NR(VIDIOCSFREQ)] = "VIDIOCSFREQ",
297 [_IOC_NR(VIDIOCGAUDIO)] = "VIDIOCGAUDIO",
298 [_IOC_NR(VIDIOCSAUDIO)] = "VIDIOCSAUDIO",
299 [_IOC_NR(VIDIOCSYNC)] = "VIDIOCSYNC",
300 [_IOC_NR(VIDIOCMCAPTURE)] = "VIDIOCMCAPTURE",
301 [_IOC_NR(VIDIOCGMBUF)] = "VIDIOCGMBUF",
302 [_IOC_NR(VIDIOCGUNIT)] = "VIDIOCGUNIT",
303 [_IOC_NR(VIDIOCGCAPTURE)] = "VIDIOCGCAPTURE",
304 [_IOC_NR(VIDIOCSCAPTURE)] = "VIDIOCSCAPTURE",
305 [_IOC_NR(VIDIOCSPLAYMODE)] = "VIDIOCSPLAYMODE",
306 [_IOC_NR(VIDIOCSWRITEMODE)] = "VIDIOCSWRITEMODE",
307 [_IOC_NR(VIDIOCGPLAYINFO)] = "VIDIOCGPLAYINFO",
308 [_IOC_NR(VIDIOCSMICROCODE)] = "VIDIOCSMICROCODE",
309 [_IOC_NR(VIDIOCGVBIFMT)] = "VIDIOCGVBIFMT",
310 [_IOC_NR(VIDIOCSVBIFMT)] = "VIDIOCSVBIFMT"
Linus Torvalds1da177e2005-04-16 15:20:36 -0700311};
Michael Krufky5e453dc2006-01-09 15:32:31 -0200312#define V4L1_IOCTLS ARRAY_SIZE(v4l1_ioctls)
313#endif
314
315static const char *v4l2_ioctls[] = {
316 [_IOC_NR(VIDIOC_QUERYCAP)] = "VIDIOC_QUERYCAP",
317 [_IOC_NR(VIDIOC_RESERVED)] = "VIDIOC_RESERVED",
318 [_IOC_NR(VIDIOC_ENUM_FMT)] = "VIDIOC_ENUM_FMT",
319 [_IOC_NR(VIDIOC_G_FMT)] = "VIDIOC_G_FMT",
320 [_IOC_NR(VIDIOC_S_FMT)] = "VIDIOC_S_FMT",
321 [_IOC_NR(VIDIOC_G_MPEGCOMP)] = "VIDIOC_G_MPEGCOMP",
322 [_IOC_NR(VIDIOC_S_MPEGCOMP)] = "VIDIOC_S_MPEGCOMP",
323 [_IOC_NR(VIDIOC_REQBUFS)] = "VIDIOC_REQBUFS",
324 [_IOC_NR(VIDIOC_QUERYBUF)] = "VIDIOC_QUERYBUF",
325 [_IOC_NR(VIDIOC_G_FBUF)] = "VIDIOC_G_FBUF",
326 [_IOC_NR(VIDIOC_S_FBUF)] = "VIDIOC_S_FBUF",
327 [_IOC_NR(VIDIOC_OVERLAY)] = "VIDIOC_OVERLAY",
328 [_IOC_NR(VIDIOC_QBUF)] = "VIDIOC_QBUF",
329 [_IOC_NR(VIDIOC_DQBUF)] = "VIDIOC_DQBUF",
330 [_IOC_NR(VIDIOC_STREAMON)] = "VIDIOC_STREAMON",
331 [_IOC_NR(VIDIOC_STREAMOFF)] = "VIDIOC_STREAMOFF",
332 [_IOC_NR(VIDIOC_G_PARM)] = "VIDIOC_G_PARM",
333 [_IOC_NR(VIDIOC_S_PARM)] = "VIDIOC_S_PARM",
334 [_IOC_NR(VIDIOC_G_STD)] = "VIDIOC_G_STD",
335 [_IOC_NR(VIDIOC_S_STD)] = "VIDIOC_S_STD",
336 [_IOC_NR(VIDIOC_ENUMSTD)] = "VIDIOC_ENUMSTD",
337 [_IOC_NR(VIDIOC_ENUMINPUT)] = "VIDIOC_ENUMINPUT",
338 [_IOC_NR(VIDIOC_G_CTRL)] = "VIDIOC_G_CTRL",
339 [_IOC_NR(VIDIOC_S_CTRL)] = "VIDIOC_S_CTRL",
340 [_IOC_NR(VIDIOC_G_TUNER)] = "VIDIOC_G_TUNER",
341 [_IOC_NR(VIDIOC_S_TUNER)] = "VIDIOC_S_TUNER",
342 [_IOC_NR(VIDIOC_G_AUDIO)] = "VIDIOC_G_AUDIO",
343 [_IOC_NR(VIDIOC_S_AUDIO)] = "VIDIOC_S_AUDIO",
344 [_IOC_NR(VIDIOC_QUERYCTRL)] = "VIDIOC_QUERYCTRL",
345 [_IOC_NR(VIDIOC_QUERYMENU)] = "VIDIOC_QUERYMENU",
346 [_IOC_NR(VIDIOC_G_INPUT)] = "VIDIOC_G_INPUT",
347 [_IOC_NR(VIDIOC_S_INPUT)] = "VIDIOC_S_INPUT",
348 [_IOC_NR(VIDIOC_G_OUTPUT)] = "VIDIOC_G_OUTPUT",
349 [_IOC_NR(VIDIOC_S_OUTPUT)] = "VIDIOC_S_OUTPUT",
350 [_IOC_NR(VIDIOC_ENUMOUTPUT)] = "VIDIOC_ENUMOUTPUT",
351 [_IOC_NR(VIDIOC_G_AUDOUT)] = "VIDIOC_G_AUDOUT",
352 [_IOC_NR(VIDIOC_S_AUDOUT)] = "VIDIOC_S_AUDOUT",
353 [_IOC_NR(VIDIOC_G_MODULATOR)] = "VIDIOC_G_MODULATOR",
354 [_IOC_NR(VIDIOC_S_MODULATOR)] = "VIDIOC_S_MODULATOR",
355 [_IOC_NR(VIDIOC_G_FREQUENCY)] = "VIDIOC_G_FREQUENCY",
356 [_IOC_NR(VIDIOC_S_FREQUENCY)] = "VIDIOC_S_FREQUENCY",
357 [_IOC_NR(VIDIOC_CROPCAP)] = "VIDIOC_CROPCAP",
358 [_IOC_NR(VIDIOC_G_CROP)] = "VIDIOC_G_CROP",
359 [_IOC_NR(VIDIOC_S_CROP)] = "VIDIOC_S_CROP",
360 [_IOC_NR(VIDIOC_G_JPEGCOMP)] = "VIDIOC_G_JPEGCOMP",
361 [_IOC_NR(VIDIOC_S_JPEGCOMP)] = "VIDIOC_S_JPEGCOMP",
362 [_IOC_NR(VIDIOC_QUERYSTD)] = "VIDIOC_QUERYSTD",
363 [_IOC_NR(VIDIOC_TRY_FMT)] = "VIDIOC_TRY_FMT",
364 [_IOC_NR(VIDIOC_ENUMAUDIO)] = "VIDIOC_ENUMAUDIO",
365 [_IOC_NR(VIDIOC_ENUMAUDOUT)] = "VIDIOC_ENUMAUDOUT",
366 [_IOC_NR(VIDIOC_G_PRIORITY)] = "VIDIOC_G_PRIORITY",
367 [_IOC_NR(VIDIOC_S_PRIORITY)] = "VIDIOC_S_PRIORITY",
368#if 1
369 [_IOC_NR(VIDIOC_G_SLICED_VBI_CAP)] = "VIDIOC_G_SLICED_VBI_CAP",
370#endif
Hans Verkuil9cb23182006-06-18 14:11:08 -0300371 [_IOC_NR(VIDIOC_LOG_STATUS)] = "VIDIOC_LOG_STATUS",
372 [_IOC_NR(VIDIOC_G_EXT_CTRLS)] = "VIDIOC_G_EXT_CTRLS",
373 [_IOC_NR(VIDIOC_S_EXT_CTRLS)] = "VIDIOC_S_EXT_CTRLS",
374 [_IOC_NR(VIDIOC_TRY_EXT_CTRLS)] = "VIDIOC_TRY_EXT_CTRLS"
Michael Krufky5e453dc2006-01-09 15:32:31 -0200375};
376#define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
377
378static const char *v4l2_int_ioctls[] = {
Mauro Carvalho Chehab0dfa9ab2006-08-08 09:10:10 -0300379#ifdef CONFIG_VIDEO_V4L1_COMPAT
Michael Krufky5e453dc2006-01-09 15:32:31 -0200380 [_IOC_NR(DECODER_GET_CAPABILITIES)] = "DECODER_GET_CAPABILITIES",
381 [_IOC_NR(DECODER_GET_STATUS)] = "DECODER_GET_STATUS",
382 [_IOC_NR(DECODER_SET_NORM)] = "DECODER_SET_NORM",
383 [_IOC_NR(DECODER_SET_INPUT)] = "DECODER_SET_INPUT",
384 [_IOC_NR(DECODER_SET_OUTPUT)] = "DECODER_SET_OUTPUT",
385 [_IOC_NR(DECODER_ENABLE_OUTPUT)] = "DECODER_ENABLE_OUTPUT",
386 [_IOC_NR(DECODER_SET_PICTURE)] = "DECODER_SET_PICTURE",
387 [_IOC_NR(DECODER_SET_GPIO)] = "DECODER_SET_GPIO",
388 [_IOC_NR(DECODER_INIT)] = "DECODER_INIT",
389 [_IOC_NR(DECODER_SET_VBI_BYPASS)] = "DECODER_SET_VBI_BYPASS",
390 [_IOC_NR(DECODER_DUMP)] = "DECODER_DUMP",
391#endif
392 [_IOC_NR(AUDC_SET_RADIO)] = "AUDC_SET_RADIO",
Michael Krufky5e453dc2006-01-09 15:32:31 -0200393
394 [_IOC_NR(TUNER_SET_TYPE_ADDR)] = "TUNER_SET_TYPE_ADDR",
395 [_IOC_NR(TUNER_SET_STANDBY)] = "TUNER_SET_STANDBY",
396 [_IOC_NR(TDA9887_SET_CONFIG)] = "TDA9887_SET_CONFIG",
397
Trent Piepho52ebc762007-01-23 22:38:13 -0300398 [_IOC_NR(VIDIOC_DBG_S_REGISTER)] = "VIDIOC_DBG_S_REGISTER",
399 [_IOC_NR(VIDIOC_DBG_G_REGISTER)] = "VIDIOC_DBG_G_REGISTER",
400
Hans Verkuil3bbe5a82006-04-01 15:27:52 -0300401 [_IOC_NR(VIDIOC_INT_S_TUNER_MODE)] = "VIDIOC_INT_S_TUNER_MODE",
Michael Krufky5e453dc2006-01-09 15:32:31 -0200402 [_IOC_NR(VIDIOC_INT_RESET)] = "VIDIOC_INT_RESET",
403 [_IOC_NR(VIDIOC_INT_AUDIO_CLOCK_FREQ)] = "VIDIOC_INT_AUDIO_CLOCK_FREQ",
404 [_IOC_NR(VIDIOC_INT_DECODE_VBI_LINE)] = "VIDIOC_INT_DECODE_VBI_LINE",
405 [_IOC_NR(VIDIOC_INT_S_VBI_DATA)] = "VIDIOC_INT_S_VBI_DATA",
406 [_IOC_NR(VIDIOC_INT_G_VBI_DATA)] = "VIDIOC_INT_G_VBI_DATA",
407 [_IOC_NR(VIDIOC_INT_G_CHIP_IDENT)] = "VIDIOC_INT_G_CHIP_IDENT",
Hans Verkuil3bbe5a82006-04-01 15:27:52 -0300408 [_IOC_NR(VIDIOC_INT_I2S_CLOCK_FREQ)] = "VIDIOC_INT_I2S_CLOCK_FREQ",
409 [_IOC_NR(VIDIOC_INT_S_STANDBY)] = "VIDIOC_INT_S_STANDBY",
410 [_IOC_NR(VIDIOC_INT_S_AUDIO_ROUTING)] = "VIDIOC_INT_S_AUDIO_ROUTING",
411 [_IOC_NR(VIDIOC_INT_G_AUDIO_ROUTING)] = "VIDIOC_INT_G_AUDIO_ROUTING",
412 [_IOC_NR(VIDIOC_INT_S_VIDEO_ROUTING)] = "VIDIOC_INT_S_VIDEO_ROUTING",
Hans Verkuilb7f82922006-04-02 12:50:42 -0300413 [_IOC_NR(VIDIOC_INT_G_VIDEO_ROUTING)] = "VIDIOC_INT_G_VIDEO_ROUTING",
414 [_IOC_NR(VIDIOC_INT_S_CRYSTAL_FREQ)] = "VIDIOC_INT_S_CRYSTAL_FREQ"
Michael Krufky5e453dc2006-01-09 15:32:31 -0200415};
416#define V4L2_INT_IOCTLS ARRAY_SIZE(v4l2_int_ioctls)
417
Mauro Carvalho Chehab0bbb9c12006-02-27 00:08:55 -0300418
Michael Krufky5e453dc2006-01-09 15:32:31 -0200419/* Common ioctl debug function. This function can be used by
420 external ioctl messages as well as internal V4L ioctl */
421void v4l_printk_ioctl(unsigned int cmd)
422{
423 char *dir;
424
425 switch (_IOC_DIR(cmd)) {
426 case _IOC_NONE: dir = "--"; break;
427 case _IOC_READ: dir = "r-"; break;
428 case _IOC_WRITE: dir = "-w"; break;
429 case _IOC_READ | _IOC_WRITE: dir = "rw"; break;
430 default: dir = "*ERR*"; break;
431 }
432 switch (_IOC_TYPE(cmd)) {
433 case 'd':
434 printk("v4l2_int ioctl %s, dir=%s (0x%08x)\n",
435 (_IOC_NR(cmd) < V4L2_INT_IOCTLS) ?
436 v4l2_int_ioctls[_IOC_NR(cmd)] : "UNKNOWN", dir, cmd);
437 break;
Mauro Carvalho Chehab0dfa9ab2006-08-08 09:10:10 -0300438#ifdef CONFIG_VIDEO_V4L1_COMPAT
Michael Krufky5e453dc2006-01-09 15:32:31 -0200439 case 'v':
440 printk("v4l1 ioctl %s, dir=%s (0x%08x)\n",
441 (_IOC_NR(cmd) < V4L1_IOCTLS) ?
442 v4l1_ioctls[_IOC_NR(cmd)] : "UNKNOWN", dir, cmd);
443 break;
444#endif
445 case 'V':
446 printk("v4l2 ioctl %s, dir=%s (0x%08x)\n",
447 (_IOC_NR(cmd) < V4L2_IOCTLS) ?
448 v4l2_ioctls[_IOC_NR(cmd)] : "UNKNOWN", dir, cmd);
449 break;
450
451 default:
452 printk("unknown ioctl '%c', dir=%s, #%d (0x%08x)\n",
453 _IOC_TYPE(cmd), dir, _IOC_NR(cmd), cmd);
454 }
455}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700456
Mauro Carvalho Chehab41f38b42006-02-27 00:08:49 -0300457
Linus Torvalds1da177e2005-04-16 15:20:36 -0700458/* ----------------------------------------------------------------- */
459
Hans Verkuil9cb23182006-06-18 14:11:08 -0300460/* Helper functions for control handling */
461
462/* Check for correctness of the ctrl's value based on the data from
463 struct v4l2_queryctrl and the available menu items. Note that
464 menu_items may be NULL, in that case it is ignored. */
465int v4l2_ctrl_check(struct v4l2_ext_control *ctrl, struct v4l2_queryctrl *qctrl,
466 const char **menu_items)
467{
468 if (qctrl->flags & V4L2_CTRL_FLAG_DISABLED)
469 return -EINVAL;
470 if (qctrl->flags & V4L2_CTRL_FLAG_GRABBED)
471 return -EBUSY;
472 if (qctrl->type == V4L2_CTRL_TYPE_BUTTON ||
473 qctrl->type == V4L2_CTRL_TYPE_INTEGER64 ||
474 qctrl->type == V4L2_CTRL_TYPE_CTRL_CLASS)
475 return 0;
476 if (ctrl->value < qctrl->minimum || ctrl->value > qctrl->maximum)
477 return -ERANGE;
478 if (qctrl->type == V4L2_CTRL_TYPE_MENU && menu_items != NULL) {
479 if (menu_items[ctrl->value] == NULL ||
480 menu_items[ctrl->value][0] == '\0')
481 return -EINVAL;
482 }
483 return 0;
484}
485
486/* Returns NULL or a character pointer array containing the menu for
487 the given control ID. The pointer array ends with a NULL pointer.
488 An empty string signifies a menu entry that is invalid. This allows
489 drivers to disable certain options if it is not supported. */
490const char **v4l2_ctrl_get_menu(u32 id)
491{
492 static const char *mpeg_audio_sampling_freq[] = {
493 "44.1 kHz",
494 "48 kHz",
495 "32 kHz",
496 NULL
497 };
498 static const char *mpeg_audio_encoding[] = {
499 "Layer I",
500 "Layer II",
501 "Layer III",
502 NULL
503 };
504 static const char *mpeg_audio_l1_bitrate[] = {
505 "32 kbps",
506 "64 kbps",
507 "96 kbps",
508 "128 kbps",
509 "160 kbps",
510 "192 kbps",
511 "224 kbps",
512 "256 kbps",
513 "288 kbps",
514 "320 kbps",
515 "352 kbps",
516 "384 kbps",
517 "416 kbps",
518 "448 kbps",
519 NULL
520 };
521 static const char *mpeg_audio_l2_bitrate[] = {
522 "32 kbps",
523 "48 kbps",
524 "56 kbps",
525 "64 kbps",
526 "80 kbps",
527 "96 kbps",
528 "112 kbps",
529 "128 kbps",
530 "160 kbps",
531 "192 kbps",
532 "224 kbps",
533 "256 kbps",
534 "320 kbps",
535 "384 kbps",
536 NULL
537 };
538 static const char *mpeg_audio_l3_bitrate[] = {
539 "32 kbps",
540 "40 kbps",
541 "48 kbps",
542 "56 kbps",
543 "64 kbps",
544 "80 kbps",
545 "96 kbps",
546 "112 kbps",
547 "128 kbps",
548 "160 kbps",
549 "192 kbps",
550 "224 kbps",
551 "256 kbps",
552 "320 kbps",
553 NULL
554 };
555 static const char *mpeg_audio_mode[] = {
556 "Stereo",
557 "Joint Stereo",
558 "Dual",
559 "Mono",
560 NULL
561 };
562 static const char *mpeg_audio_mode_extension[] = {
563 "Bound 4",
564 "Bound 8",
565 "Bound 12",
566 "Bound 16",
567 NULL
568 };
569 static const char *mpeg_audio_emphasis[] = {
570 "No Emphasis",
571 "50/15 us",
572 "CCITT J17",
573 NULL
574 };
575 static const char *mpeg_audio_crc[] = {
576 "No CRC",
577 "16-bit CRC",
578 NULL
579 };
580 static const char *mpeg_video_encoding[] = {
581 "MPEG-1",
582 "MPEG-2",
583 NULL
584 };
585 static const char *mpeg_video_aspect[] = {
586 "1x1",
587 "4x3",
588 "16x9",
589 "2.21x1",
590 NULL
591 };
592 static const char *mpeg_video_bitrate_mode[] = {
593 "Variable Bitrate",
594 "Constant Bitrate",
595 NULL
596 };
597 static const char *mpeg_stream_type[] = {
598 "MPEG-2 Program Stream",
599 "MPEG-2 Transport Stream",
600 "MPEG-1 System Stream",
601 "MPEG-2 DVD-compatible Stream",
602 "MPEG-1 VCD-compatible Stream",
603 "MPEG-2 SVCD-compatible Stream",
604 NULL
605 };
Hans Verkuil8cbde942006-06-24 14:36:02 -0300606 static const char *mpeg_stream_vbi_fmt[] = {
607 "No VBI",
Hans Verkuil99523512006-06-25 11:18:54 -0300608 "Private packet, IVTV format",
Hans Verkuil8cbde942006-06-24 14:36:02 -0300609 NULL
610 };
Hans Verkuil9cb23182006-06-18 14:11:08 -0300611
612 switch (id) {
613 case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
614 return mpeg_audio_sampling_freq;
615 case V4L2_CID_MPEG_AUDIO_ENCODING:
616 return mpeg_audio_encoding;
617 case V4L2_CID_MPEG_AUDIO_L1_BITRATE:
618 return mpeg_audio_l1_bitrate;
619 case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
620 return mpeg_audio_l2_bitrate;
621 case V4L2_CID_MPEG_AUDIO_L3_BITRATE:
622 return mpeg_audio_l3_bitrate;
623 case V4L2_CID_MPEG_AUDIO_MODE:
624 return mpeg_audio_mode;
625 case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION:
626 return mpeg_audio_mode_extension;
627 case V4L2_CID_MPEG_AUDIO_EMPHASIS:
628 return mpeg_audio_emphasis;
629 case V4L2_CID_MPEG_AUDIO_CRC:
630 return mpeg_audio_crc;
631 case V4L2_CID_MPEG_VIDEO_ENCODING:
632 return mpeg_video_encoding;
633 case V4L2_CID_MPEG_VIDEO_ASPECT:
634 return mpeg_video_aspect;
635 case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
636 return mpeg_video_bitrate_mode;
637 case V4L2_CID_MPEG_STREAM_TYPE:
638 return mpeg_stream_type;
Hans Verkuil8cbde942006-06-24 14:36:02 -0300639 case V4L2_CID_MPEG_STREAM_VBI_FMT:
640 return mpeg_stream_vbi_fmt;
Hans Verkuil9cb23182006-06-18 14:11:08 -0300641 default:
642 return NULL;
643 }
644}
645
646/* Fill in a struct v4l2_queryctrl */
647int v4l2_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 min, s32 max, s32 step, s32 def)
648{
649 const char *name;
650
651 qctrl->flags = 0;
652 switch (qctrl->id) {
653 /* USER controls */
654 case V4L2_CID_USER_CLASS: name = "User Controls"; break;
655 case V4L2_CID_AUDIO_VOLUME: name = "Volume"; break;
656 case V4L2_CID_AUDIO_MUTE: name = "Mute"; break;
657 case V4L2_CID_AUDIO_BALANCE: name = "Balance"; break;
658 case V4L2_CID_AUDIO_BASS: name = "Bass"; break;
659 case V4L2_CID_AUDIO_TREBLE: name = "Treble"; break;
660 case V4L2_CID_AUDIO_LOUDNESS: name = "Loudness"; break;
661 case V4L2_CID_BRIGHTNESS: name = "Brightness"; break;
662 case V4L2_CID_CONTRAST: name = "Contrast"; break;
663 case V4L2_CID_SATURATION: name = "Saturation"; break;
664 case V4L2_CID_HUE: name = "Hue"; break;
665
666 /* MPEG controls */
667 case V4L2_CID_MPEG_CLASS: name = "MPEG Encoder Controls"; break;
668 case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ: name = "Audio Sampling Frequency"; break;
669 case V4L2_CID_MPEG_AUDIO_ENCODING: name = "Audio Encoding Layer"; break;
670 case V4L2_CID_MPEG_AUDIO_L1_BITRATE: name = "Audio Layer I Bitrate"; break;
671 case V4L2_CID_MPEG_AUDIO_L2_BITRATE: name = "Audio Layer II Bitrate"; break;
672 case V4L2_CID_MPEG_AUDIO_L3_BITRATE: name = "Audio Layer III Bitrate"; break;
673 case V4L2_CID_MPEG_AUDIO_MODE: name = "Audio Stereo Mode"; break;
674 case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION: name = "Audio Stereo Mode Extension"; break;
675 case V4L2_CID_MPEG_AUDIO_EMPHASIS: name = "Audio Emphasis"; break;
676 case V4L2_CID_MPEG_AUDIO_CRC: name = "Audio CRC"; break;
677 case V4L2_CID_MPEG_VIDEO_ENCODING: name = "Video Encoding"; break;
678 case V4L2_CID_MPEG_VIDEO_ASPECT: name = "Video Aspect"; break;
679 case V4L2_CID_MPEG_VIDEO_B_FRAMES: name = "Video B Frames"; break;
680 case V4L2_CID_MPEG_VIDEO_GOP_SIZE: name = "Video GOP Size"; break;
681 case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE: name = "Video GOP Closure"; break;
682 case V4L2_CID_MPEG_VIDEO_PULLDOWN: name = "Video Pulldown"; break;
683 case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: name = "Video Bitrate Mode"; break;
684 case V4L2_CID_MPEG_VIDEO_BITRATE: name = "Video Bitrate"; break;
685 case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK: name = "Video Peak Bitrate"; break;
686 case V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION: name = "Video Temporal Decimation"; break;
687 case V4L2_CID_MPEG_STREAM_TYPE: name = "Stream Type"; break;
688 case V4L2_CID_MPEG_STREAM_PID_PMT: name = "Stream PMT Program ID"; break;
689 case V4L2_CID_MPEG_STREAM_PID_AUDIO: name = "Stream Audio Program ID"; break;
690 case V4L2_CID_MPEG_STREAM_PID_VIDEO: name = "Stream Video Program ID"; break;
691 case V4L2_CID_MPEG_STREAM_PID_PCR: name = "Stream PCR Program ID"; break;
692 case V4L2_CID_MPEG_STREAM_PES_ID_AUDIO: name = "Stream PES Audio ID"; break;
693 case V4L2_CID_MPEG_STREAM_PES_ID_VIDEO: name = "Stream PES Video ID"; break;
Hans Verkuil8cbde942006-06-24 14:36:02 -0300694 case V4L2_CID_MPEG_STREAM_VBI_FMT: name = "Stream VBI Format"; break;
Hans Verkuil9cb23182006-06-18 14:11:08 -0300695
696 default:
697 return -EINVAL;
698 }
699 switch (qctrl->id) {
700 case V4L2_CID_AUDIO_MUTE:
701 case V4L2_CID_AUDIO_LOUDNESS:
702 case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
703 case V4L2_CID_MPEG_VIDEO_PULLDOWN:
704 qctrl->type = V4L2_CTRL_TYPE_BOOLEAN;
705 min = 0;
706 max = step = 1;
707 break;
708 case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
709 case V4L2_CID_MPEG_AUDIO_ENCODING:
710 case V4L2_CID_MPEG_AUDIO_L1_BITRATE:
711 case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
712 case V4L2_CID_MPEG_AUDIO_L3_BITRATE:
713 case V4L2_CID_MPEG_AUDIO_MODE:
714 case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION:
715 case V4L2_CID_MPEG_AUDIO_EMPHASIS:
716 case V4L2_CID_MPEG_AUDIO_CRC:
717 case V4L2_CID_MPEG_VIDEO_ENCODING:
718 case V4L2_CID_MPEG_VIDEO_ASPECT:
719 case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
720 case V4L2_CID_MPEG_STREAM_TYPE:
Hans Verkuil8cbde942006-06-24 14:36:02 -0300721 case V4L2_CID_MPEG_STREAM_VBI_FMT:
Hans Verkuil9cb23182006-06-18 14:11:08 -0300722 qctrl->type = V4L2_CTRL_TYPE_MENU;
723 step = 1;
724 break;
725 case V4L2_CID_USER_CLASS:
726 case V4L2_CID_MPEG_CLASS:
727 qctrl->type = V4L2_CTRL_TYPE_CTRL_CLASS;
728 qctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
729 min = max = step = def = 0;
730 break;
731 default:
732 qctrl->type = V4L2_CTRL_TYPE_INTEGER;
733 break;
734 }
735 switch (qctrl->id) {
736 case V4L2_CID_MPEG_AUDIO_ENCODING:
737 case V4L2_CID_MPEG_AUDIO_MODE:
738 case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
739 case V4L2_CID_MPEG_VIDEO_B_FRAMES:
740 case V4L2_CID_MPEG_STREAM_TYPE:
741 qctrl->flags |= V4L2_CTRL_FLAG_UPDATE;
742 break;
743 case V4L2_CID_AUDIO_VOLUME:
744 case V4L2_CID_AUDIO_BALANCE:
745 case V4L2_CID_AUDIO_BASS:
746 case V4L2_CID_AUDIO_TREBLE:
747 case V4L2_CID_BRIGHTNESS:
748 case V4L2_CID_CONTRAST:
749 case V4L2_CID_SATURATION:
750 case V4L2_CID_HUE:
751 qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
752 break;
753 }
754 qctrl->minimum = min;
755 qctrl->maximum = max;
756 qctrl->step = step;
757 qctrl->default_value = def;
758 qctrl->reserved[0] = qctrl->reserved[1] = 0;
759 snprintf(qctrl->name, sizeof(qctrl->name), name);
760 return 0;
761}
762
763/* Fill in a struct v4l2_queryctrl with standard values based on
764 the control ID. */
765int v4l2_ctrl_query_fill_std(struct v4l2_queryctrl *qctrl)
766{
767 switch (qctrl->id) {
768 /* USER controls */
769 case V4L2_CID_USER_CLASS:
770 case V4L2_CID_MPEG_CLASS:
771 return v4l2_ctrl_query_fill(qctrl, 0, 0, 0, 0);
772 case V4L2_CID_AUDIO_VOLUME:
773 return v4l2_ctrl_query_fill(qctrl, 0, 65535, 65535 / 100, 58880);
774 case V4L2_CID_AUDIO_MUTE:
775 case V4L2_CID_AUDIO_LOUDNESS:
776 return v4l2_ctrl_query_fill(qctrl, 0, 1, 1, 0);
777 case V4L2_CID_AUDIO_BALANCE:
778 case V4L2_CID_AUDIO_BASS:
779 case V4L2_CID_AUDIO_TREBLE:
780 return v4l2_ctrl_query_fill(qctrl, 0, 65535, 65535 / 100, 32768);
781 case V4L2_CID_BRIGHTNESS:
782 return v4l2_ctrl_query_fill(qctrl, 0, 255, 1, 128);
783 case V4L2_CID_CONTRAST:
784 case V4L2_CID_SATURATION:
785 return v4l2_ctrl_query_fill(qctrl, 0, 127, 1, 64);
786 case V4L2_CID_HUE:
787 return v4l2_ctrl_query_fill(qctrl, -128, 127, 1, 0);
788
789 /* MPEG controls */
790 case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
791 return v4l2_ctrl_query_fill(qctrl,
792 V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100,
793 V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000, 1,
794 V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000);
795 case V4L2_CID_MPEG_AUDIO_ENCODING:
796 return v4l2_ctrl_query_fill(qctrl,
797 V4L2_MPEG_AUDIO_ENCODING_LAYER_1,
798 V4L2_MPEG_AUDIO_ENCODING_LAYER_3, 1,
799 V4L2_MPEG_AUDIO_ENCODING_LAYER_2);
800 case V4L2_CID_MPEG_AUDIO_L1_BITRATE:
801 return v4l2_ctrl_query_fill(qctrl,
802 V4L2_MPEG_AUDIO_L1_BITRATE_32K,
803 V4L2_MPEG_AUDIO_L1_BITRATE_448K, 1,
804 V4L2_MPEG_AUDIO_L1_BITRATE_256K);
805 case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
806 return v4l2_ctrl_query_fill(qctrl,
807 V4L2_MPEG_AUDIO_L2_BITRATE_32K,
808 V4L2_MPEG_AUDIO_L2_BITRATE_384K, 1,
809 V4L2_MPEG_AUDIO_L2_BITRATE_224K);
810 case V4L2_CID_MPEG_AUDIO_L3_BITRATE:
811 return v4l2_ctrl_query_fill(qctrl,
812 V4L2_MPEG_AUDIO_L3_BITRATE_32K,
813 V4L2_MPEG_AUDIO_L3_BITRATE_320K, 1,
814 V4L2_MPEG_AUDIO_L3_BITRATE_192K);
815 case V4L2_CID_MPEG_AUDIO_MODE:
816 return v4l2_ctrl_query_fill(qctrl,
817 V4L2_MPEG_AUDIO_MODE_STEREO,
818 V4L2_MPEG_AUDIO_MODE_MONO, 1,
819 V4L2_MPEG_AUDIO_MODE_STEREO);
820 case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION:
821 return v4l2_ctrl_query_fill(qctrl,
822 V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4,
823 V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_16, 1,
824 V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4);
825 case V4L2_CID_MPEG_AUDIO_EMPHASIS:
826 return v4l2_ctrl_query_fill(qctrl,
827 V4L2_MPEG_AUDIO_EMPHASIS_NONE,
828 V4L2_MPEG_AUDIO_EMPHASIS_CCITT_J17, 1,
829 V4L2_MPEG_AUDIO_EMPHASIS_NONE);
830 case V4L2_CID_MPEG_AUDIO_CRC:
831 return v4l2_ctrl_query_fill(qctrl,
832 V4L2_MPEG_AUDIO_CRC_NONE,
833 V4L2_MPEG_AUDIO_CRC_CRC16, 1,
834 V4L2_MPEG_AUDIO_CRC_NONE);
835 case V4L2_CID_MPEG_VIDEO_ENCODING:
836 return v4l2_ctrl_query_fill(qctrl,
837 V4L2_MPEG_VIDEO_ENCODING_MPEG_1,
838 V4L2_MPEG_VIDEO_ENCODING_MPEG_2, 1,
839 V4L2_MPEG_VIDEO_ENCODING_MPEG_2);
840 case V4L2_CID_MPEG_VIDEO_ASPECT:
841 return v4l2_ctrl_query_fill(qctrl,
842 V4L2_MPEG_VIDEO_ASPECT_1x1,
843 V4L2_MPEG_VIDEO_ASPECT_221x100, 1,
844 V4L2_MPEG_VIDEO_ASPECT_4x3);
845 case V4L2_CID_MPEG_VIDEO_B_FRAMES:
846 return v4l2_ctrl_query_fill(qctrl, 0, 33, 1, 2);
847 case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
848 return v4l2_ctrl_query_fill(qctrl, 1, 34, 1, 12);
849 case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
850 return v4l2_ctrl_query_fill(qctrl, 0, 1, 1, 1);
851 case V4L2_CID_MPEG_VIDEO_PULLDOWN:
852 return v4l2_ctrl_query_fill(qctrl, 0, 1, 1, 0);
853 case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
854 return v4l2_ctrl_query_fill(qctrl,
855 V4L2_MPEG_VIDEO_BITRATE_MODE_VBR,
856 V4L2_MPEG_VIDEO_BITRATE_MODE_CBR, 1,
857 V4L2_MPEG_VIDEO_BITRATE_MODE_VBR);
858 case V4L2_CID_MPEG_VIDEO_BITRATE:
859 return v4l2_ctrl_query_fill(qctrl, 0, 27000000, 1, 6000000);
860 case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
861 return v4l2_ctrl_query_fill(qctrl, 0, 27000000, 1, 8000000);
862 case V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION:
863 return v4l2_ctrl_query_fill(qctrl, 0, 255, 1, 0);
864 case V4L2_CID_MPEG_STREAM_TYPE:
865 return v4l2_ctrl_query_fill(qctrl,
866 V4L2_MPEG_STREAM_TYPE_MPEG2_PS,
867 V4L2_MPEG_STREAM_TYPE_MPEG2_SVCD, 1,
868 V4L2_MPEG_STREAM_TYPE_MPEG2_PS);
869 case V4L2_CID_MPEG_STREAM_PID_PMT:
870 return v4l2_ctrl_query_fill(qctrl, 0, (1 << 14) - 1, 1, 16);
871 case V4L2_CID_MPEG_STREAM_PID_AUDIO:
872 return v4l2_ctrl_query_fill(qctrl, 0, (1 << 14) - 1, 1, 260);
873 case V4L2_CID_MPEG_STREAM_PID_VIDEO:
874 return v4l2_ctrl_query_fill(qctrl, 0, (1 << 14) - 1, 1, 256);
875 case V4L2_CID_MPEG_STREAM_PID_PCR:
876 return v4l2_ctrl_query_fill(qctrl, 0, (1 << 14) - 1, 1, 259);
877 case V4L2_CID_MPEG_STREAM_PES_ID_AUDIO:
878 return v4l2_ctrl_query_fill(qctrl, 0, 255, 1, 0);
879 case V4L2_CID_MPEG_STREAM_PES_ID_VIDEO:
880 return v4l2_ctrl_query_fill(qctrl, 0, 255, 1, 0);
Hans Verkuil8cbde942006-06-24 14:36:02 -0300881 case V4L2_CID_MPEG_STREAM_VBI_FMT:
882 return v4l2_ctrl_query_fill(qctrl,
883 V4L2_MPEG_STREAM_VBI_FMT_NONE,
884 V4L2_MPEG_STREAM_VBI_FMT_IVTV, 1,
885 V4L2_MPEG_STREAM_VBI_FMT_NONE);
Hans Verkuil9cb23182006-06-18 14:11:08 -0300886 default:
887 return -EINVAL;
888 }
889}
890
891/* Fill in a struct v4l2_querymenu based on the struct v4l2_queryctrl and
892 the menu. The qctrl pointer may be NULL, in which case it is ignored. */
893int v4l2_ctrl_query_menu(struct v4l2_querymenu *qmenu, struct v4l2_queryctrl *qctrl,
894 const char **menu_items)
895{
896 int i;
897
898 if (menu_items == NULL ||
899 (qctrl && (qmenu->index < qctrl->minimum || qmenu->index > qctrl->maximum)))
900 return -EINVAL;
901 for (i = 0; i < qmenu->index && menu_items[i]; i++) ;
902 if (menu_items[i] == NULL || menu_items[i][0] == '\0')
903 return -EINVAL;
904 snprintf(qmenu->name, sizeof(qmenu->name), menu_items[qmenu->index]);
905 qmenu->reserved = 0;
906 return 0;
907}
908
909/* ctrl_classes points to an array of u32 pointers, the last element is
910 a NULL pointer. Each u32 array is a 0-terminated array of control IDs.
911 Each array must be sorted low to high and belong to the same control
912 class. The array of u32 pointer must also be sorted, from low class IDs
913 to high class IDs.
914
915 This function returns the first ID that follows after the given ID.
916 When no more controls are available 0 is returned. */
917u32 v4l2_ctrl_next(const u32 * const * ctrl_classes, u32 id)
918{
919 u32 ctrl_class;
920 const u32 *pctrl;
921
922 /* if no query is desired, then just return the control ID */
923 if ((id & V4L2_CTRL_FLAG_NEXT_CTRL) == 0)
924 return id;
925 if (ctrl_classes == NULL)
926 return 0;
927 id &= V4L2_CTRL_ID_MASK;
928 ctrl_class = V4L2_CTRL_ID2CLASS(id);
929 id++; /* select next control */
930 /* find first class that matches (or is greater than) the class of
931 the ID */
932 while (*ctrl_classes && V4L2_CTRL_ID2CLASS(**ctrl_classes) < ctrl_class)
933 ctrl_classes++;
934 /* no more classes */
935 if (*ctrl_classes == NULL)
936 return 0;
937 pctrl = *ctrl_classes;
938 /* find first ctrl within the class that is >= ID */
939 while (*pctrl && *pctrl < id) pctrl++;
940 if (*pctrl)
941 return *pctrl;
942 /* we are at the end of the controls of the current class. */
943 /* continue with next class if available */
944 ctrl_classes++;
945 if (*ctrl_classes == NULL)
946 return 0;
947 return **ctrl_classes;
948}
949
950/* ----------------------------------------------------------------- */
951
Mauro Carvalho Chehabe75f9ce2006-11-20 13:19:20 -0300952EXPORT_SYMBOL(v4l2_norm_to_name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700953EXPORT_SYMBOL(v4l2_video_std_construct);
954
955EXPORT_SYMBOL(v4l2_prio_init);
956EXPORT_SYMBOL(v4l2_prio_change);
957EXPORT_SYMBOL(v4l2_prio_open);
958EXPORT_SYMBOL(v4l2_prio_close);
959EXPORT_SYMBOL(v4l2_prio_max);
960EXPORT_SYMBOL(v4l2_prio_check);
961
962EXPORT_SYMBOL(v4l2_field_names);
963EXPORT_SYMBOL(v4l2_type_names);
Michael Krufky5e453dc2006-01-09 15:32:31 -0200964EXPORT_SYMBOL(v4l_printk_ioctl);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700965
Hans Verkuil9cb23182006-06-18 14:11:08 -0300966EXPORT_SYMBOL(v4l2_ctrl_next);
967EXPORT_SYMBOL(v4l2_ctrl_check);
968EXPORT_SYMBOL(v4l2_ctrl_get_menu);
969EXPORT_SYMBOL(v4l2_ctrl_query_menu);
970EXPORT_SYMBOL(v4l2_ctrl_query_fill);
971EXPORT_SYMBOL(v4l2_ctrl_query_fill_std);
972
Linus Torvalds1da177e2005-04-16 15:20:36 -0700973/*
974 * Local variables:
975 * c-basic-offset: 8
976 * End:
977 */