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