blob: fdc8871f631ea5093aa7ac54b4adeb5ca2399cb6 [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 *
Alan Coxd9b01442008-10-27 15:13:47 -030031 * Author: Alan Cox, <alan@lxorguk.ukuu.org.uk>
Linus Torvalds1da177e2005-04-16 15:20:36 -070032 *
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
Jan Engelhardt96de0e22007-10-19 23:21:04 +020040 * Iñaki García Etxebarria <garetxe@euskalnet.net>
Linus Torvalds1da177e2005-04-16 15:20:36 -070041 * 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/mm.h>
51#include <linux/string.h>
52#include <linux/errno.h>
Hans Verkuilf3d092b2007-02-23 20:55:14 -030053#include <linux/i2c.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070054#include <asm/uaccess.h>
55#include <asm/system.h>
56#include <asm/pgtable.h>
57#include <asm/io.h>
58#include <asm/div64.h>
Mauro Carvalho Chehab401998f2006-06-04 10:06:18 -030059#define __OLD_VIDIOC_ /* To allow fixing old calls*/
Michael Krufky5e453dc2006-01-09 15:32:31 -020060#include <media/v4l2-common.h>
Hans Verkuil3434eb72007-04-27 12:31:08 -030061#include <media/v4l2-chip-ident.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070062
Hans Verkuil33b687c2008-07-25 05:32:50 -030063#include <linux/videodev2.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070064
65MODULE_AUTHOR("Bill Dirks, Justin Schoeman, Gerd Knorr");
66MODULE_DESCRIPTION("misc helper functions for v4l2 device drivers");
67MODULE_LICENSE("GPL");
68
69/*
70 *
71 * V 4 L 2 D R I V E R H E L P E R A P I
72 *
73 */
74
75/*
76 * Video Standard Operations (contributed by Michael Schimek)
77 */
78
Linus Torvalds1da177e2005-04-16 15:20:36 -070079
Linus Torvalds1da177e2005-04-16 15:20:36 -070080/* ----------------------------------------------------------------- */
81/* priority handling */
82
83#define V4L2_PRIO_VALID(val) (val == V4L2_PRIORITY_BACKGROUND || \
84 val == V4L2_PRIORITY_INTERACTIVE || \
85 val == V4L2_PRIORITY_RECORD)
86
87int v4l2_prio_init(struct v4l2_prio_state *global)
88{
89 memset(global,0,sizeof(*global));
90 return 0;
91}
Mauro Carvalho Chehab057596e2008-02-02 11:25:31 -030092EXPORT_SYMBOL(v4l2_prio_init);
Linus Torvalds1da177e2005-04-16 15:20:36 -070093
94int v4l2_prio_change(struct v4l2_prio_state *global, enum v4l2_priority *local,
95 enum v4l2_priority new)
96{
97 if (!V4L2_PRIO_VALID(new))
98 return -EINVAL;
99 if (*local == new)
100 return 0;
101
102 atomic_inc(&global->prios[new]);
103 if (V4L2_PRIO_VALID(*local))
104 atomic_dec(&global->prios[*local]);
105 *local = new;
106 return 0;
107}
Mauro Carvalho Chehab057596e2008-02-02 11:25:31 -0300108EXPORT_SYMBOL(v4l2_prio_change);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700109
110int v4l2_prio_open(struct v4l2_prio_state *global, enum v4l2_priority *local)
111{
112 return v4l2_prio_change(global,local,V4L2_PRIORITY_DEFAULT);
113}
Mauro Carvalho Chehab057596e2008-02-02 11:25:31 -0300114EXPORT_SYMBOL(v4l2_prio_open);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700115
116int v4l2_prio_close(struct v4l2_prio_state *global, enum v4l2_priority *local)
117{
118 if (V4L2_PRIO_VALID(*local))
119 atomic_dec(&global->prios[*local]);
120 return 0;
121}
Mauro Carvalho Chehab057596e2008-02-02 11:25:31 -0300122EXPORT_SYMBOL(v4l2_prio_close);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700123
124enum v4l2_priority v4l2_prio_max(struct v4l2_prio_state *global)
125{
126 if (atomic_read(&global->prios[V4L2_PRIORITY_RECORD]) > 0)
127 return V4L2_PRIORITY_RECORD;
128 if (atomic_read(&global->prios[V4L2_PRIORITY_INTERACTIVE]) > 0)
129 return V4L2_PRIORITY_INTERACTIVE;
130 if (atomic_read(&global->prios[V4L2_PRIORITY_BACKGROUND]) > 0)
131 return V4L2_PRIORITY_BACKGROUND;
132 return V4L2_PRIORITY_UNSET;
133}
Mauro Carvalho Chehab057596e2008-02-02 11:25:31 -0300134EXPORT_SYMBOL(v4l2_prio_max);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700135
136int v4l2_prio_check(struct v4l2_prio_state *global, enum v4l2_priority *local)
137{
138 if (*local < v4l2_prio_max(global))
139 return -EBUSY;
140 return 0;
141}
Mauro Carvalho Chehab057596e2008-02-02 11:25:31 -0300142EXPORT_SYMBOL(v4l2_prio_check);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700143
144/* ----------------------------------------------------------------- */
145
Hans Verkuil9cb23182006-06-18 14:11:08 -0300146/* Helper functions for control handling */
147
148/* Check for correctness of the ctrl's value based on the data from
149 struct v4l2_queryctrl and the available menu items. Note that
150 menu_items may be NULL, in that case it is ignored. */
151int v4l2_ctrl_check(struct v4l2_ext_control *ctrl, struct v4l2_queryctrl *qctrl,
152 const char **menu_items)
153{
154 if (qctrl->flags & V4L2_CTRL_FLAG_DISABLED)
155 return -EINVAL;
156 if (qctrl->flags & V4L2_CTRL_FLAG_GRABBED)
157 return -EBUSY;
158 if (qctrl->type == V4L2_CTRL_TYPE_BUTTON ||
159 qctrl->type == V4L2_CTRL_TYPE_INTEGER64 ||
160 qctrl->type == V4L2_CTRL_TYPE_CTRL_CLASS)
161 return 0;
162 if (ctrl->value < qctrl->minimum || ctrl->value > qctrl->maximum)
163 return -ERANGE;
164 if (qctrl->type == V4L2_CTRL_TYPE_MENU && menu_items != NULL) {
165 if (menu_items[ctrl->value] == NULL ||
166 menu_items[ctrl->value][0] == '\0')
167 return -EINVAL;
168 }
169 return 0;
170}
Mauro Carvalho Chehab057596e2008-02-02 11:25:31 -0300171EXPORT_SYMBOL(v4l2_ctrl_check);
Hans Verkuil9cb23182006-06-18 14:11:08 -0300172
173/* Returns NULL or a character pointer array containing the menu for
174 the given control ID. The pointer array ends with a NULL pointer.
175 An empty string signifies a menu entry that is invalid. This allows
176 drivers to disable certain options if it is not supported. */
177const char **v4l2_ctrl_get_menu(u32 id)
178{
179 static const char *mpeg_audio_sampling_freq[] = {
180 "44.1 kHz",
181 "48 kHz",
182 "32 kHz",
183 NULL
184 };
185 static const char *mpeg_audio_encoding[] = {
Hans Verkuile6b5da82008-08-08 07:38:07 -0300186 "MPEG-1/2 Layer I",
187 "MPEG-1/2 Layer II",
188 "MPEG-1/2 Layer III",
189 "MPEG-2/4 AAC",
190 "AC-3",
Hans Verkuil9cb23182006-06-18 14:11:08 -0300191 NULL
192 };
193 static const char *mpeg_audio_l1_bitrate[] = {
194 "32 kbps",
195 "64 kbps",
196 "96 kbps",
197 "128 kbps",
198 "160 kbps",
199 "192 kbps",
200 "224 kbps",
201 "256 kbps",
202 "288 kbps",
203 "320 kbps",
204 "352 kbps",
205 "384 kbps",
206 "416 kbps",
207 "448 kbps",
208 NULL
209 };
210 static const char *mpeg_audio_l2_bitrate[] = {
211 "32 kbps",
212 "48 kbps",
213 "56 kbps",
214 "64 kbps",
215 "80 kbps",
216 "96 kbps",
217 "112 kbps",
218 "128 kbps",
219 "160 kbps",
220 "192 kbps",
221 "224 kbps",
222 "256 kbps",
223 "320 kbps",
224 "384 kbps",
225 NULL
226 };
227 static const char *mpeg_audio_l3_bitrate[] = {
228 "32 kbps",
229 "40 kbps",
230 "48 kbps",
231 "56 kbps",
232 "64 kbps",
233 "80 kbps",
234 "96 kbps",
235 "112 kbps",
236 "128 kbps",
237 "160 kbps",
238 "192 kbps",
239 "224 kbps",
240 "256 kbps",
241 "320 kbps",
242 NULL
243 };
Hans Verkuile6b5da82008-08-08 07:38:07 -0300244 static const char *mpeg_audio_ac3_bitrate[] = {
245 "32 kbps",
246 "40 kbps",
247 "48 kbps",
248 "56 kbps",
249 "64 kbps",
250 "80 kbps",
251 "96 kbps",
252 "112 kbps",
253 "128 kbps",
254 "160 kbps",
255 "192 kbps",
256 "224 kbps",
257 "256 kbps",
258 "320 kbps",
259 "384 kbps",
260 "448 kbps",
261 "512 kbps",
262 "576 kbps",
263 "640 kbps",
264 NULL
265 };
Hans Verkuil9cb23182006-06-18 14:11:08 -0300266 static const char *mpeg_audio_mode[] = {
267 "Stereo",
268 "Joint Stereo",
269 "Dual",
270 "Mono",
271 NULL
272 };
273 static const char *mpeg_audio_mode_extension[] = {
274 "Bound 4",
275 "Bound 8",
276 "Bound 12",
277 "Bound 16",
278 NULL
279 };
280 static const char *mpeg_audio_emphasis[] = {
281 "No Emphasis",
282 "50/15 us",
283 "CCITT J17",
284 NULL
285 };
286 static const char *mpeg_audio_crc[] = {
287 "No CRC",
288 "16-bit CRC",
289 NULL
290 };
291 static const char *mpeg_video_encoding[] = {
292 "MPEG-1",
293 "MPEG-2",
Janne Grunau188919a2008-08-08 07:21:00 -0300294 "MPEG-4 AVC",
Hans Verkuil9cb23182006-06-18 14:11:08 -0300295 NULL
296 };
297 static const char *mpeg_video_aspect[] = {
298 "1x1",
299 "4x3",
300 "16x9",
301 "2.21x1",
302 NULL
303 };
304 static const char *mpeg_video_bitrate_mode[] = {
305 "Variable Bitrate",
306 "Constant Bitrate",
307 NULL
308 };
309 static const char *mpeg_stream_type[] = {
310 "MPEG-2 Program Stream",
311 "MPEG-2 Transport Stream",
312 "MPEG-1 System Stream",
313 "MPEG-2 DVD-compatible Stream",
314 "MPEG-1 VCD-compatible Stream",
315 "MPEG-2 SVCD-compatible Stream",
316 NULL
317 };
Hans Verkuil8cbde942006-06-24 14:36:02 -0300318 static const char *mpeg_stream_vbi_fmt[] = {
319 "No VBI",
Hans Verkuil99523512006-06-25 11:18:54 -0300320 "Private packet, IVTV format",
Hans Verkuil8cbde942006-06-24 14:36:02 -0300321 NULL
322 };
Hans Verkuil9cb23182006-06-18 14:11:08 -0300323
324 switch (id) {
325 case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
326 return mpeg_audio_sampling_freq;
327 case V4L2_CID_MPEG_AUDIO_ENCODING:
328 return mpeg_audio_encoding;
329 case V4L2_CID_MPEG_AUDIO_L1_BITRATE:
330 return mpeg_audio_l1_bitrate;
331 case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
332 return mpeg_audio_l2_bitrate;
333 case V4L2_CID_MPEG_AUDIO_L3_BITRATE:
334 return mpeg_audio_l3_bitrate;
Hans Verkuile6b5da82008-08-08 07:38:07 -0300335 case V4L2_CID_MPEG_AUDIO_AC3_BITRATE:
336 return mpeg_audio_ac3_bitrate;
Hans Verkuil9cb23182006-06-18 14:11:08 -0300337 case V4L2_CID_MPEG_AUDIO_MODE:
338 return mpeg_audio_mode;
339 case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION:
340 return mpeg_audio_mode_extension;
341 case V4L2_CID_MPEG_AUDIO_EMPHASIS:
342 return mpeg_audio_emphasis;
343 case V4L2_CID_MPEG_AUDIO_CRC:
344 return mpeg_audio_crc;
345 case V4L2_CID_MPEG_VIDEO_ENCODING:
346 return mpeg_video_encoding;
347 case V4L2_CID_MPEG_VIDEO_ASPECT:
348 return mpeg_video_aspect;
349 case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
350 return mpeg_video_bitrate_mode;
351 case V4L2_CID_MPEG_STREAM_TYPE:
352 return mpeg_stream_type;
Hans Verkuil8cbde942006-06-24 14:36:02 -0300353 case V4L2_CID_MPEG_STREAM_VBI_FMT:
354 return mpeg_stream_vbi_fmt;
Hans Verkuil9cb23182006-06-18 14:11:08 -0300355 default:
356 return NULL;
357 }
358}
Mauro Carvalho Chehab057596e2008-02-02 11:25:31 -0300359EXPORT_SYMBOL(v4l2_ctrl_get_menu);
Hans Verkuil9cb23182006-06-18 14:11:08 -0300360
Hans Verkuil69028d72008-08-08 07:55:00 -0300361/* Return the control name. */
362const char *v4l2_ctrl_get_name(u32 id)
363{
364 switch (id) {
365 /* USER controls */
366 case V4L2_CID_USER_CLASS: return "User Controls";
367 case V4L2_CID_AUDIO_VOLUME: return "Volume";
368 case V4L2_CID_AUDIO_MUTE: return "Mute";
369 case V4L2_CID_AUDIO_BALANCE: return "Balance";
370 case V4L2_CID_AUDIO_BASS: return "Bass";
371 case V4L2_CID_AUDIO_TREBLE: return "Treble";
372 case V4L2_CID_AUDIO_LOUDNESS: return "Loudness";
373 case V4L2_CID_BRIGHTNESS: return "Brightness";
374 case V4L2_CID_CONTRAST: return "Contrast";
375 case V4L2_CID_SATURATION: return "Saturation";
376 case V4L2_CID_HUE: return "Hue";
377
378 /* MPEG controls */
379 case V4L2_CID_MPEG_CLASS: return "MPEG Encoder Controls";
380 case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ: return "Audio Sampling Frequency";
381 case V4L2_CID_MPEG_AUDIO_ENCODING: return "Audio Encoding";
382 case V4L2_CID_MPEG_AUDIO_L1_BITRATE: return "Audio Layer I Bitrate";
383 case V4L2_CID_MPEG_AUDIO_L2_BITRATE: return "Audio Layer II Bitrate";
384 case V4L2_CID_MPEG_AUDIO_L3_BITRATE: return "Audio Layer III Bitrate";
Hans Verkuilf723af12008-08-09 10:35:29 -0300385 case V4L2_CID_MPEG_AUDIO_AAC_BITRATE: return "Audio AAC Bitrate";
Hans Verkuil69028d72008-08-08 07:55:00 -0300386 case V4L2_CID_MPEG_AUDIO_AC3_BITRATE: return "Audio AC-3 Bitrate";
387 case V4L2_CID_MPEG_AUDIO_MODE: return "Audio Stereo Mode";
388 case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION: return "Audio Stereo Mode Extension";
389 case V4L2_CID_MPEG_AUDIO_EMPHASIS: return "Audio Emphasis";
390 case V4L2_CID_MPEG_AUDIO_CRC: return "Audio CRC";
391 case V4L2_CID_MPEG_AUDIO_MUTE: return "Audio Mute";
392 case V4L2_CID_MPEG_VIDEO_ENCODING: return "Video Encoding";
393 case V4L2_CID_MPEG_VIDEO_ASPECT: return "Video Aspect";
394 case V4L2_CID_MPEG_VIDEO_B_FRAMES: return "Video B Frames";
395 case V4L2_CID_MPEG_VIDEO_GOP_SIZE: return "Video GOP Size";
396 case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE: return "Video GOP Closure";
397 case V4L2_CID_MPEG_VIDEO_PULLDOWN: return "Video Pulldown";
398 case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: return "Video Bitrate Mode";
399 case V4L2_CID_MPEG_VIDEO_BITRATE: return "Video Bitrate";
400 case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK: return "Video Peak Bitrate";
401 case V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION: return "Video Temporal Decimation";
402 case V4L2_CID_MPEG_VIDEO_MUTE: return "Video Mute";
403 case V4L2_CID_MPEG_VIDEO_MUTE_YUV: return "Video Mute YUV";
404 case V4L2_CID_MPEG_STREAM_TYPE: return "Stream Type";
405 case V4L2_CID_MPEG_STREAM_PID_PMT: return "Stream PMT Program ID";
406 case V4L2_CID_MPEG_STREAM_PID_AUDIO: return "Stream Audio Program ID";
407 case V4L2_CID_MPEG_STREAM_PID_VIDEO: return "Stream Video Program ID";
408 case V4L2_CID_MPEG_STREAM_PID_PCR: return "Stream PCR Program ID";
409 case V4L2_CID_MPEG_STREAM_PES_ID_AUDIO: return "Stream PES Audio ID";
410 case V4L2_CID_MPEG_STREAM_PES_ID_VIDEO: return "Stream PES Video ID";
411 case V4L2_CID_MPEG_STREAM_VBI_FMT: return "Stream VBI Format";
412
413 default:
414 return NULL;
415 }
416}
417EXPORT_SYMBOL(v4l2_ctrl_get_name);
418
Hans Verkuil9cb23182006-06-18 14:11:08 -0300419/* Fill in a struct v4l2_queryctrl */
420int v4l2_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 min, s32 max, s32 step, s32 def)
421{
Hans Verkuil69028d72008-08-08 07:55:00 -0300422 const char *name = v4l2_ctrl_get_name(qctrl->id);
Hans Verkuil9cb23182006-06-18 14:11:08 -0300423
424 qctrl->flags = 0;
Hans Verkuil69028d72008-08-08 07:55:00 -0300425 if (name == NULL)
Hans Verkuil9cb23182006-06-18 14:11:08 -0300426 return -EINVAL;
Hans Verkuil69028d72008-08-08 07:55:00 -0300427
Hans Verkuil9cb23182006-06-18 14:11:08 -0300428 switch (qctrl->id) {
429 case V4L2_CID_AUDIO_MUTE:
430 case V4L2_CID_AUDIO_LOUDNESS:
Hans Verkuil5eee72e2007-04-27 12:31:00 -0300431 case V4L2_CID_MPEG_AUDIO_MUTE:
Hans Verkuil01f1e442007-08-21 18:32:42 -0300432 case V4L2_CID_MPEG_VIDEO_MUTE:
Hans Verkuil9cb23182006-06-18 14:11:08 -0300433 case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
434 case V4L2_CID_MPEG_VIDEO_PULLDOWN:
435 qctrl->type = V4L2_CTRL_TYPE_BOOLEAN;
436 min = 0;
437 max = step = 1;
438 break;
439 case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
440 case V4L2_CID_MPEG_AUDIO_ENCODING:
441 case V4L2_CID_MPEG_AUDIO_L1_BITRATE:
442 case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
443 case V4L2_CID_MPEG_AUDIO_L3_BITRATE:
Hans Verkuile6b5da82008-08-08 07:38:07 -0300444 case V4L2_CID_MPEG_AUDIO_AC3_BITRATE:
Hans Verkuil9cb23182006-06-18 14:11:08 -0300445 case V4L2_CID_MPEG_AUDIO_MODE:
446 case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION:
447 case V4L2_CID_MPEG_AUDIO_EMPHASIS:
448 case V4L2_CID_MPEG_AUDIO_CRC:
449 case V4L2_CID_MPEG_VIDEO_ENCODING:
450 case V4L2_CID_MPEG_VIDEO_ASPECT:
451 case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
452 case V4L2_CID_MPEG_STREAM_TYPE:
Hans Verkuil8cbde942006-06-24 14:36:02 -0300453 case V4L2_CID_MPEG_STREAM_VBI_FMT:
Hans Verkuil9cb23182006-06-18 14:11:08 -0300454 qctrl->type = V4L2_CTRL_TYPE_MENU;
455 step = 1;
456 break;
457 case V4L2_CID_USER_CLASS:
458 case V4L2_CID_MPEG_CLASS:
459 qctrl->type = V4L2_CTRL_TYPE_CTRL_CLASS;
460 qctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
461 min = max = step = def = 0;
462 break;
463 default:
464 qctrl->type = V4L2_CTRL_TYPE_INTEGER;
465 break;
466 }
467 switch (qctrl->id) {
468 case V4L2_CID_MPEG_AUDIO_ENCODING:
469 case V4L2_CID_MPEG_AUDIO_MODE:
470 case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
471 case V4L2_CID_MPEG_VIDEO_B_FRAMES:
472 case V4L2_CID_MPEG_STREAM_TYPE:
473 qctrl->flags |= V4L2_CTRL_FLAG_UPDATE;
474 break;
475 case V4L2_CID_AUDIO_VOLUME:
476 case V4L2_CID_AUDIO_BALANCE:
477 case V4L2_CID_AUDIO_BASS:
478 case V4L2_CID_AUDIO_TREBLE:
479 case V4L2_CID_BRIGHTNESS:
480 case V4L2_CID_CONTRAST:
481 case V4L2_CID_SATURATION:
482 case V4L2_CID_HUE:
483 qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
484 break;
485 }
486 qctrl->minimum = min;
487 qctrl->maximum = max;
488 qctrl->step = step;
489 qctrl->default_value = def;
490 qctrl->reserved[0] = qctrl->reserved[1] = 0;
491 snprintf(qctrl->name, sizeof(qctrl->name), name);
492 return 0;
493}
Mauro Carvalho Chehab057596e2008-02-02 11:25:31 -0300494EXPORT_SYMBOL(v4l2_ctrl_query_fill);
Hans Verkuil9cb23182006-06-18 14:11:08 -0300495
496/* Fill in a struct v4l2_queryctrl with standard values based on
497 the control ID. */
498int v4l2_ctrl_query_fill_std(struct v4l2_queryctrl *qctrl)
499{
500 switch (qctrl->id) {
501 /* USER controls */
502 case V4L2_CID_USER_CLASS:
503 case V4L2_CID_MPEG_CLASS:
504 return v4l2_ctrl_query_fill(qctrl, 0, 0, 0, 0);
505 case V4L2_CID_AUDIO_VOLUME:
506 return v4l2_ctrl_query_fill(qctrl, 0, 65535, 65535 / 100, 58880);
507 case V4L2_CID_AUDIO_MUTE:
508 case V4L2_CID_AUDIO_LOUDNESS:
509 return v4l2_ctrl_query_fill(qctrl, 0, 1, 1, 0);
510 case V4L2_CID_AUDIO_BALANCE:
511 case V4L2_CID_AUDIO_BASS:
512 case V4L2_CID_AUDIO_TREBLE:
513 return v4l2_ctrl_query_fill(qctrl, 0, 65535, 65535 / 100, 32768);
514 case V4L2_CID_BRIGHTNESS:
515 return v4l2_ctrl_query_fill(qctrl, 0, 255, 1, 128);
516 case V4L2_CID_CONTRAST:
517 case V4L2_CID_SATURATION:
518 return v4l2_ctrl_query_fill(qctrl, 0, 127, 1, 64);
519 case V4L2_CID_HUE:
520 return v4l2_ctrl_query_fill(qctrl, -128, 127, 1, 0);
521
522 /* MPEG controls */
523 case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
524 return v4l2_ctrl_query_fill(qctrl,
525 V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100,
526 V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000, 1,
527 V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000);
528 case V4L2_CID_MPEG_AUDIO_ENCODING:
529 return v4l2_ctrl_query_fill(qctrl,
530 V4L2_MPEG_AUDIO_ENCODING_LAYER_1,
Hans Verkuile6b5da82008-08-08 07:38:07 -0300531 V4L2_MPEG_AUDIO_ENCODING_AC3, 1,
Hans Verkuil9cb23182006-06-18 14:11:08 -0300532 V4L2_MPEG_AUDIO_ENCODING_LAYER_2);
533 case V4L2_CID_MPEG_AUDIO_L1_BITRATE:
534 return v4l2_ctrl_query_fill(qctrl,
535 V4L2_MPEG_AUDIO_L1_BITRATE_32K,
536 V4L2_MPEG_AUDIO_L1_BITRATE_448K, 1,
537 V4L2_MPEG_AUDIO_L1_BITRATE_256K);
538 case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
539 return v4l2_ctrl_query_fill(qctrl,
540 V4L2_MPEG_AUDIO_L2_BITRATE_32K,
541 V4L2_MPEG_AUDIO_L2_BITRATE_384K, 1,
542 V4L2_MPEG_AUDIO_L2_BITRATE_224K);
543 case V4L2_CID_MPEG_AUDIO_L3_BITRATE:
544 return v4l2_ctrl_query_fill(qctrl,
545 V4L2_MPEG_AUDIO_L3_BITRATE_32K,
546 V4L2_MPEG_AUDIO_L3_BITRATE_320K, 1,
547 V4L2_MPEG_AUDIO_L3_BITRATE_192K);
Hans Verkuilf723af12008-08-09 10:35:29 -0300548 case V4L2_CID_MPEG_AUDIO_AAC_BITRATE:
549 return v4l2_ctrl_query_fill(qctrl, 0, 6400, 1, 3200000);
Hans Verkuile6b5da82008-08-08 07:38:07 -0300550 case V4L2_CID_MPEG_AUDIO_AC3_BITRATE:
551 return v4l2_ctrl_query_fill(qctrl,
552 V4L2_MPEG_AUDIO_AC3_BITRATE_32K,
553 V4L2_MPEG_AUDIO_AC3_BITRATE_640K, 1,
554 V4L2_MPEG_AUDIO_AC3_BITRATE_384K);
Hans Verkuil9cb23182006-06-18 14:11:08 -0300555 case V4L2_CID_MPEG_AUDIO_MODE:
556 return v4l2_ctrl_query_fill(qctrl,
557 V4L2_MPEG_AUDIO_MODE_STEREO,
558 V4L2_MPEG_AUDIO_MODE_MONO, 1,
559 V4L2_MPEG_AUDIO_MODE_STEREO);
560 case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION:
561 return v4l2_ctrl_query_fill(qctrl,
562 V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4,
563 V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_16, 1,
564 V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4);
565 case V4L2_CID_MPEG_AUDIO_EMPHASIS:
566 return v4l2_ctrl_query_fill(qctrl,
567 V4L2_MPEG_AUDIO_EMPHASIS_NONE,
568 V4L2_MPEG_AUDIO_EMPHASIS_CCITT_J17, 1,
569 V4L2_MPEG_AUDIO_EMPHASIS_NONE);
570 case V4L2_CID_MPEG_AUDIO_CRC:
571 return v4l2_ctrl_query_fill(qctrl,
572 V4L2_MPEG_AUDIO_CRC_NONE,
573 V4L2_MPEG_AUDIO_CRC_CRC16, 1,
574 V4L2_MPEG_AUDIO_CRC_NONE);
Hans Verkuil5eee72e2007-04-27 12:31:00 -0300575 case V4L2_CID_MPEG_AUDIO_MUTE:
576 return v4l2_ctrl_query_fill(qctrl, 0, 1, 1, 0);
Hans Verkuil9cb23182006-06-18 14:11:08 -0300577 case V4L2_CID_MPEG_VIDEO_ENCODING:
578 return v4l2_ctrl_query_fill(qctrl,
579 V4L2_MPEG_VIDEO_ENCODING_MPEG_1,
Janne Grunau188919a2008-08-08 07:21:00 -0300580 V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC, 1,
Hans Verkuil9cb23182006-06-18 14:11:08 -0300581 V4L2_MPEG_VIDEO_ENCODING_MPEG_2);
582 case V4L2_CID_MPEG_VIDEO_ASPECT:
583 return v4l2_ctrl_query_fill(qctrl,
584 V4L2_MPEG_VIDEO_ASPECT_1x1,
585 V4L2_MPEG_VIDEO_ASPECT_221x100, 1,
586 V4L2_MPEG_VIDEO_ASPECT_4x3);
587 case V4L2_CID_MPEG_VIDEO_B_FRAMES:
588 return v4l2_ctrl_query_fill(qctrl, 0, 33, 1, 2);
589 case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
590 return v4l2_ctrl_query_fill(qctrl, 1, 34, 1, 12);
591 case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
592 return v4l2_ctrl_query_fill(qctrl, 0, 1, 1, 1);
593 case V4L2_CID_MPEG_VIDEO_PULLDOWN:
594 return v4l2_ctrl_query_fill(qctrl, 0, 1, 1, 0);
595 case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
596 return v4l2_ctrl_query_fill(qctrl,
597 V4L2_MPEG_VIDEO_BITRATE_MODE_VBR,
598 V4L2_MPEG_VIDEO_BITRATE_MODE_CBR, 1,
599 V4L2_MPEG_VIDEO_BITRATE_MODE_VBR);
600 case V4L2_CID_MPEG_VIDEO_BITRATE:
601 return v4l2_ctrl_query_fill(qctrl, 0, 27000000, 1, 6000000);
602 case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
603 return v4l2_ctrl_query_fill(qctrl, 0, 27000000, 1, 8000000);
604 case V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION:
605 return v4l2_ctrl_query_fill(qctrl, 0, 255, 1, 0);
Hans Verkuil5eee72e2007-04-27 12:31:00 -0300606 case V4L2_CID_MPEG_VIDEO_MUTE:
607 return v4l2_ctrl_query_fill(qctrl, 0, 1, 1, 0);
608 case V4L2_CID_MPEG_VIDEO_MUTE_YUV: /* Init YUV (really YCbCr) to black */
609 return v4l2_ctrl_query_fill(qctrl, 0, 0xffffff, 1, 0x008080);
Hans Verkuil9cb23182006-06-18 14:11:08 -0300610 case V4L2_CID_MPEG_STREAM_TYPE:
611 return v4l2_ctrl_query_fill(qctrl,
612 V4L2_MPEG_STREAM_TYPE_MPEG2_PS,
613 V4L2_MPEG_STREAM_TYPE_MPEG2_SVCD, 1,
614 V4L2_MPEG_STREAM_TYPE_MPEG2_PS);
615 case V4L2_CID_MPEG_STREAM_PID_PMT:
616 return v4l2_ctrl_query_fill(qctrl, 0, (1 << 14) - 1, 1, 16);
617 case V4L2_CID_MPEG_STREAM_PID_AUDIO:
618 return v4l2_ctrl_query_fill(qctrl, 0, (1 << 14) - 1, 1, 260);
619 case V4L2_CID_MPEG_STREAM_PID_VIDEO:
620 return v4l2_ctrl_query_fill(qctrl, 0, (1 << 14) - 1, 1, 256);
621 case V4L2_CID_MPEG_STREAM_PID_PCR:
622 return v4l2_ctrl_query_fill(qctrl, 0, (1 << 14) - 1, 1, 259);
623 case V4L2_CID_MPEG_STREAM_PES_ID_AUDIO:
624 return v4l2_ctrl_query_fill(qctrl, 0, 255, 1, 0);
625 case V4L2_CID_MPEG_STREAM_PES_ID_VIDEO:
626 return v4l2_ctrl_query_fill(qctrl, 0, 255, 1, 0);
Hans Verkuil8cbde942006-06-24 14:36:02 -0300627 case V4L2_CID_MPEG_STREAM_VBI_FMT:
628 return v4l2_ctrl_query_fill(qctrl,
629 V4L2_MPEG_STREAM_VBI_FMT_NONE,
630 V4L2_MPEG_STREAM_VBI_FMT_IVTV, 1,
631 V4L2_MPEG_STREAM_VBI_FMT_NONE);
Hans Verkuil9cb23182006-06-18 14:11:08 -0300632 default:
633 return -EINVAL;
634 }
635}
Mauro Carvalho Chehab057596e2008-02-02 11:25:31 -0300636EXPORT_SYMBOL(v4l2_ctrl_query_fill_std);
Hans Verkuil9cb23182006-06-18 14:11:08 -0300637
638/* Fill in a struct v4l2_querymenu based on the struct v4l2_queryctrl and
Hans Verkuile281db582008-08-08 12:43:59 -0300639 the menu. The qctrl pointer may be NULL, in which case it is ignored.
640 If menu_items is NULL, then the menu items are retrieved using
641 v4l2_ctrl_get_menu. */
Hans Verkuil9cb23182006-06-18 14:11:08 -0300642int v4l2_ctrl_query_menu(struct v4l2_querymenu *qmenu, struct v4l2_queryctrl *qctrl,
643 const char **menu_items)
644{
645 int i;
646
Hans Verkuil1e551262008-08-08 08:34:19 -0300647 qmenu->reserved = 0;
Hans Verkuile281db582008-08-08 12:43:59 -0300648 if (menu_items == NULL)
649 menu_items = v4l2_ctrl_get_menu(qmenu->id);
Hans Verkuil9cb23182006-06-18 14:11:08 -0300650 if (menu_items == NULL ||
651 (qctrl && (qmenu->index < qctrl->minimum || qmenu->index > qctrl->maximum)))
652 return -EINVAL;
653 for (i = 0; i < qmenu->index && menu_items[i]; i++) ;
654 if (menu_items[i] == NULL || menu_items[i][0] == '\0')
655 return -EINVAL;
656 snprintf(qmenu->name, sizeof(qmenu->name), menu_items[qmenu->index]);
Hans Verkuil9cb23182006-06-18 14:11:08 -0300657 return 0;
658}
Mauro Carvalho Chehab057596e2008-02-02 11:25:31 -0300659EXPORT_SYMBOL(v4l2_ctrl_query_menu);
Hans Verkuil9cb23182006-06-18 14:11:08 -0300660
Hans Verkuil1e551262008-08-08 08:34:19 -0300661/* Fill in a struct v4l2_querymenu based on the specified array of valid
662 menu items (terminated by V4L2_CTRL_MENU_IDS_END).
663 Use this if there are 'holes' in the list of valid menu items. */
664int v4l2_ctrl_query_menu_valid_items(struct v4l2_querymenu *qmenu, const u32 *ids)
665{
666 const char **menu_items = v4l2_ctrl_get_menu(qmenu->id);
667
668 qmenu->reserved = 0;
669 if (menu_items == NULL || ids == NULL)
670 return -EINVAL;
671 while (*ids != V4L2_CTRL_MENU_IDS_END) {
672 if (*ids++ == qmenu->index) {
673 snprintf(qmenu->name, sizeof(qmenu->name),
674 menu_items[qmenu->index]);
675 return 0;
676 }
677 }
678 return -EINVAL;
679}
680EXPORT_SYMBOL(v4l2_ctrl_query_menu_valid_items);
681
Hans Verkuil9cb23182006-06-18 14:11:08 -0300682/* ctrl_classes points to an array of u32 pointers, the last element is
683 a NULL pointer. Each u32 array is a 0-terminated array of control IDs.
684 Each array must be sorted low to high and belong to the same control
685 class. The array of u32 pointer must also be sorted, from low class IDs
686 to high class IDs.
687
688 This function returns the first ID that follows after the given ID.
689 When no more controls are available 0 is returned. */
690u32 v4l2_ctrl_next(const u32 * const * ctrl_classes, u32 id)
691{
Hans Verkuila46c5fb2007-07-19 04:53:36 -0300692 u32 ctrl_class = V4L2_CTRL_ID2CLASS(id);
Hans Verkuil9cb23182006-06-18 14:11:08 -0300693 const u32 *pctrl;
694
Hans Verkuil9cb23182006-06-18 14:11:08 -0300695 if (ctrl_classes == NULL)
696 return 0;
Hans Verkuila46c5fb2007-07-19 04:53:36 -0300697
698 /* if no query is desired, then check if the ID is part of ctrl_classes */
699 if ((id & V4L2_CTRL_FLAG_NEXT_CTRL) == 0) {
700 /* find class */
701 while (*ctrl_classes && V4L2_CTRL_ID2CLASS(**ctrl_classes) != ctrl_class)
702 ctrl_classes++;
703 if (*ctrl_classes == NULL)
704 return 0;
705 pctrl = *ctrl_classes;
706 /* find control ID */
707 while (*pctrl && *pctrl != id) pctrl++;
708 return *pctrl ? id : 0;
709 }
Hans Verkuil9cb23182006-06-18 14:11:08 -0300710 id &= V4L2_CTRL_ID_MASK;
Hans Verkuil9cb23182006-06-18 14:11:08 -0300711 id++; /* select next control */
712 /* find first class that matches (or is greater than) the class of
713 the ID */
714 while (*ctrl_classes && V4L2_CTRL_ID2CLASS(**ctrl_classes) < ctrl_class)
715 ctrl_classes++;
716 /* no more classes */
717 if (*ctrl_classes == NULL)
718 return 0;
719 pctrl = *ctrl_classes;
720 /* find first ctrl within the class that is >= ID */
721 while (*pctrl && *pctrl < id) pctrl++;
722 if (*pctrl)
723 return *pctrl;
724 /* we are at the end of the controls of the current class. */
725 /* continue with next class if available */
726 ctrl_classes++;
727 if (*ctrl_classes == NULL)
728 return 0;
729 return **ctrl_classes;
730}
Mauro Carvalho Chehab057596e2008-02-02 11:25:31 -0300731EXPORT_SYMBOL(v4l2_ctrl_next);
Hans Verkuil9cb23182006-06-18 14:11:08 -0300732
Mauro Carvalho Chehaba9254472008-01-29 18:32:35 -0300733int v4l2_chip_match_host(u32 match_type, u32 match_chip)
734{
735 switch (match_type) {
736 case V4L2_CHIP_MATCH_HOST:
737 return match_chip == 0;
738 default:
739 return 0;
740 }
741}
742EXPORT_SYMBOL(v4l2_chip_match_host);
743
744#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
Hans Verkuilf3d092b2007-02-23 20:55:14 -0300745int v4l2_chip_match_i2c_client(struct i2c_client *c, u32 match_type, u32 match_chip)
746{
747 switch (match_type) {
Hans Verkuilf3d092b2007-02-23 20:55:14 -0300748 case V4L2_CHIP_MATCH_I2C_DRIVER:
749 return (c != NULL && c->driver != NULL && c->driver->id == match_chip);
750 case V4L2_CHIP_MATCH_I2C_ADDR:
751 return (c != NULL && c->addr == match_chip);
752 default:
753 return 0;
754 }
755}
Mauro Carvalho Chehaba9254472008-01-29 18:32:35 -0300756EXPORT_SYMBOL(v4l2_chip_match_i2c_client);
Hans Verkuilf3d092b2007-02-23 20:55:14 -0300757
Hans Verkuil3434eb72007-04-27 12:31:08 -0300758int v4l2_chip_ident_i2c_client(struct i2c_client *c, struct v4l2_chip_ident *chip,
759 u32 ident, u32 revision)
760{
761 if (!v4l2_chip_match_i2c_client(c, chip->match_type, chip->match_chip))
762 return 0;
763 if (chip->ident == V4L2_IDENT_NONE) {
764 chip->ident = ident;
765 chip->revision = revision;
766 }
767 else {
768 chip->ident = V4L2_IDENT_AMBIGUOUS;
769 chip->revision = 0;
770 }
771 return 0;
772}
Mauro Carvalho Chehaba9254472008-01-29 18:32:35 -0300773EXPORT_SYMBOL(v4l2_chip_ident_i2c_client);
Hans Verkuilf3d092b2007-02-23 20:55:14 -0300774
Hans Verkuil9cb23182006-06-18 14:11:08 -0300775/* ----------------------------------------------------------------- */
776
Hans Verkuil8ffbc652007-09-12 08:32:50 -0300777/* Helper function for I2C legacy drivers */
778
779int v4l2_i2c_attach(struct i2c_adapter *adapter, int address, struct i2c_driver *driver,
Jean Delvared2653e92008-04-29 23:11:39 +0200780 const char *name,
781 int (*probe)(struct i2c_client *, const struct i2c_device_id *))
Hans Verkuil8ffbc652007-09-12 08:32:50 -0300782{
783 struct i2c_client *client;
784 int err;
785
786 client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
Harvey Harrisona6a3a172008-04-28 16:50:03 -0700787 if (!client)
Hans Verkuil8ffbc652007-09-12 08:32:50 -0300788 return -ENOMEM;
789
790 client->addr = address;
791 client->adapter = adapter;
792 client->driver = driver;
Hans Verkuil393bf552007-09-18 03:22:32 -0300793 strlcpy(client->name, name, sizeof(client->name));
Hans Verkuil8ffbc652007-09-12 08:32:50 -0300794
Jean Delvared2653e92008-04-29 23:11:39 +0200795 err = probe(client, NULL);
Hans Verkuil8ffbc652007-09-12 08:32:50 -0300796 if (err == 0) {
797 i2c_attach_client(client);
Hans Verkuil393bf552007-09-18 03:22:32 -0300798 } else {
Hans Verkuil8ffbc652007-09-12 08:32:50 -0300799 kfree(client);
800 }
Hans Verkuil188f3452007-09-16 10:47:15 -0300801 return err != -ENOMEM ? 0 : err;
Hans Verkuil8ffbc652007-09-12 08:32:50 -0300802}
Mauro Carvalho Chehaba9254472008-01-29 18:32:35 -0300803EXPORT_SYMBOL(v4l2_i2c_attach);
804#endif