blob: bed04b1fdd0aed71da899842eee84ae72918035a [file] [log] [blame]
Hans Verkuil09965172010-08-01 14:32:42 -03001/*
2 V4L2 controls framework implementation.
3
4 Copyright (C) 2010 Hans Verkuil <hverkuil@xs4all.nl>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include <linux/ctype.h>
Randy Dunlap2b801632010-08-09 14:56:35 -030022#include <linux/slab.h>
Paul Gortmaker35a24632011-08-01 15:26:38 -040023#include <linux/export.h>
Hans Verkuil09965172010-08-01 14:32:42 -030024#include <media/v4l2-ioctl.h>
25#include <media/v4l2-device.h>
26#include <media/v4l2-ctrls.h>
Hans Verkuil6e239392011-06-07 11:13:44 -030027#include <media/v4l2-event.h>
Hans Verkuil09965172010-08-01 14:32:42 -030028#include <media/v4l2-dev.h>
29
Hans Verkuilddac5c12011-06-10 05:43:34 -030030#define has_op(master, op) \
31 (master->ops && master->ops->op)
Hans Verkuil54c911e2011-05-25 06:04:58 -030032#define call_op(master, op) \
Hans Verkuilddac5c12011-06-10 05:43:34 -030033 (has_op(master, op) ? master->ops->op(master) : 0)
Hans Verkuil54c911e2011-05-25 06:04:58 -030034
Hans Verkuil09965172010-08-01 14:32:42 -030035/* Internal temporary helper struct, one for each v4l2_ext_control */
Hans Verkuileb5b16e2011-06-14 10:04:06 -030036struct v4l2_ctrl_helper {
37 /* Pointer to the control reference of the master control */
38 struct v4l2_ctrl_ref *mref;
Hans Verkuil09965172010-08-01 14:32:42 -030039 /* The control corresponding to the v4l2_ext_control ID field. */
40 struct v4l2_ctrl *ctrl;
Hans Verkuileb5b16e2011-06-14 10:04:06 -030041 /* v4l2_ext_control index of the next control belonging to the
42 same cluster, or 0 if there isn't any. */
43 u32 next;
Hans Verkuil09965172010-08-01 14:32:42 -030044};
45
Hans Verkuil72d877c2011-06-10 05:44:36 -030046/* Small helper function to determine if the autocluster is set to manual
Hans Verkuil88365102011-08-26 07:35:14 -030047 mode. */
Hans Verkuil72d877c2011-06-10 05:44:36 -030048static bool is_cur_manual(const struct v4l2_ctrl *master)
49{
50 return master->is_auto && master->cur.val == master->manual_mode_value;
51}
52
53/* Same as above, but this checks the against the new value instead of the
54 current value. */
55static bool is_new_manual(const struct v4l2_ctrl *master)
56{
57 return master->is_auto && master->val == master->manual_mode_value;
58}
59
Hans Verkuil09965172010-08-01 14:32:42 -030060/* Returns NULL or a character pointer array containing the menu for
61 the given control ID. The pointer array ends with a NULL pointer.
62 An empty string signifies a menu entry that is invalid. This allows
63 drivers to disable certain options if it is not supported. */
Hans Verkuil513521e2010-12-29 14:25:52 -030064const char * const *v4l2_ctrl_get_menu(u32 id)
Hans Verkuil09965172010-08-01 14:32:42 -030065{
Hans Verkuil513521e2010-12-29 14:25:52 -030066 static const char * const mpeg_audio_sampling_freq[] = {
Hans Verkuil09965172010-08-01 14:32:42 -030067 "44.1 kHz",
68 "48 kHz",
69 "32 kHz",
70 NULL
71 };
Hans Verkuil513521e2010-12-29 14:25:52 -030072 static const char * const mpeg_audio_encoding[] = {
Hans Verkuil09965172010-08-01 14:32:42 -030073 "MPEG-1/2 Layer I",
74 "MPEG-1/2 Layer II",
75 "MPEG-1/2 Layer III",
76 "MPEG-2/4 AAC",
77 "AC-3",
78 NULL
79 };
Hans Verkuil513521e2010-12-29 14:25:52 -030080 static const char * const mpeg_audio_l1_bitrate[] = {
Hans Verkuil09965172010-08-01 14:32:42 -030081 "32 kbps",
82 "64 kbps",
83 "96 kbps",
84 "128 kbps",
85 "160 kbps",
86 "192 kbps",
87 "224 kbps",
88 "256 kbps",
89 "288 kbps",
90 "320 kbps",
91 "352 kbps",
92 "384 kbps",
93 "416 kbps",
94 "448 kbps",
95 NULL
96 };
Hans Verkuil513521e2010-12-29 14:25:52 -030097 static const char * const mpeg_audio_l2_bitrate[] = {
Hans Verkuil09965172010-08-01 14:32:42 -030098 "32 kbps",
99 "48 kbps",
100 "56 kbps",
101 "64 kbps",
102 "80 kbps",
103 "96 kbps",
104 "112 kbps",
105 "128 kbps",
106 "160 kbps",
107 "192 kbps",
108 "224 kbps",
109 "256 kbps",
110 "320 kbps",
111 "384 kbps",
112 NULL
113 };
Hans Verkuil513521e2010-12-29 14:25:52 -0300114 static const char * const mpeg_audio_l3_bitrate[] = {
Hans Verkuil09965172010-08-01 14:32:42 -0300115 "32 kbps",
116 "40 kbps",
117 "48 kbps",
118 "56 kbps",
119 "64 kbps",
120 "80 kbps",
121 "96 kbps",
122 "112 kbps",
123 "128 kbps",
124 "160 kbps",
125 "192 kbps",
126 "224 kbps",
127 "256 kbps",
128 "320 kbps",
129 NULL
130 };
Hans Verkuil513521e2010-12-29 14:25:52 -0300131 static const char * const mpeg_audio_ac3_bitrate[] = {
Hans Verkuil09965172010-08-01 14:32:42 -0300132 "32 kbps",
133 "40 kbps",
134 "48 kbps",
135 "56 kbps",
136 "64 kbps",
137 "80 kbps",
138 "96 kbps",
139 "112 kbps",
140 "128 kbps",
141 "160 kbps",
142 "192 kbps",
143 "224 kbps",
144 "256 kbps",
145 "320 kbps",
146 "384 kbps",
147 "448 kbps",
148 "512 kbps",
149 "576 kbps",
150 "640 kbps",
151 NULL
152 };
Hans Verkuil513521e2010-12-29 14:25:52 -0300153 static const char * const mpeg_audio_mode[] = {
Hans Verkuil09965172010-08-01 14:32:42 -0300154 "Stereo",
155 "Joint Stereo",
156 "Dual",
157 "Mono",
158 NULL
159 };
Hans Verkuil513521e2010-12-29 14:25:52 -0300160 static const char * const mpeg_audio_mode_extension[] = {
Hans Verkuil09965172010-08-01 14:32:42 -0300161 "Bound 4",
162 "Bound 8",
163 "Bound 12",
164 "Bound 16",
165 NULL
166 };
Hans Verkuil513521e2010-12-29 14:25:52 -0300167 static const char * const mpeg_audio_emphasis[] = {
Hans Verkuil09965172010-08-01 14:32:42 -0300168 "No Emphasis",
169 "50/15 us",
170 "CCITT J17",
171 NULL
172 };
Hans Verkuil513521e2010-12-29 14:25:52 -0300173 static const char * const mpeg_audio_crc[] = {
Hans Verkuil09965172010-08-01 14:32:42 -0300174 "No CRC",
175 "16-bit CRC",
176 NULL
177 };
Hans Verkuil24c19a22011-12-15 10:46:16 -0300178 static const char * const mpeg_audio_dec_playback[] = {
179 "Auto",
180 "Stereo",
181 "Left",
182 "Right",
183 "Mono",
184 "Swapped Stereo",
185 NULL
186 };
Hans Verkuil513521e2010-12-29 14:25:52 -0300187 static const char * const mpeg_video_encoding[] = {
Hans Verkuil09965172010-08-01 14:32:42 -0300188 "MPEG-1",
189 "MPEG-2",
190 "MPEG-4 AVC",
191 NULL
192 };
Hans Verkuil513521e2010-12-29 14:25:52 -0300193 static const char * const mpeg_video_aspect[] = {
Hans Verkuil09965172010-08-01 14:32:42 -0300194 "1x1",
195 "4x3",
196 "16x9",
197 "2.21x1",
198 NULL
199 };
Hans Verkuil513521e2010-12-29 14:25:52 -0300200 static const char * const mpeg_video_bitrate_mode[] = {
Hans Verkuil09965172010-08-01 14:32:42 -0300201 "Variable Bitrate",
202 "Constant Bitrate",
203 NULL
204 };
Hans Verkuil513521e2010-12-29 14:25:52 -0300205 static const char * const mpeg_stream_type[] = {
Hans Verkuil09965172010-08-01 14:32:42 -0300206 "MPEG-2 Program Stream",
207 "MPEG-2 Transport Stream",
208 "MPEG-1 System Stream",
209 "MPEG-2 DVD-compatible Stream",
210 "MPEG-1 VCD-compatible Stream",
211 "MPEG-2 SVCD-compatible Stream",
212 NULL
213 };
Hans Verkuil513521e2010-12-29 14:25:52 -0300214 static const char * const mpeg_stream_vbi_fmt[] = {
Hans Verkuil09965172010-08-01 14:32:42 -0300215 "No VBI",
Kamil Debski064f5092011-06-14 10:46:22 -0300216 "Private Packet, IVTV Format",
Hans Verkuil09965172010-08-01 14:32:42 -0300217 NULL
218 };
Hans Verkuil513521e2010-12-29 14:25:52 -0300219 static const char * const camera_power_line_frequency[] = {
Hans Verkuil09965172010-08-01 14:32:42 -0300220 "Disabled",
221 "50 Hz",
222 "60 Hz",
Sylwester Nawrockid26a6632011-09-04 19:08:54 -0300223 "Auto",
Hans Verkuil09965172010-08-01 14:32:42 -0300224 NULL
225 };
Hans Verkuil513521e2010-12-29 14:25:52 -0300226 static const char * const camera_exposure_auto[] = {
Hans Verkuil09965172010-08-01 14:32:42 -0300227 "Auto Mode",
228 "Manual Mode",
229 "Shutter Priority Mode",
230 "Aperture Priority Mode",
231 NULL
232 };
Sylwester Nawrockicf072132012-04-30 04:34:10 -0300233 static const char * const camera_exposure_metering[] = {
234 "Average",
235 "Center Weighted",
236 "Spot",
Sylwester Nawrockifc39f462013-03-14 07:01:24 -0300237 "Matrix",
Sylwester Nawrockicf072132012-04-30 04:34:10 -0300238 NULL
239 };
Sylwester Nawrocki2272ab62012-05-11 06:37:03 -0300240 static const char * const camera_auto_focus_range[] = {
241 "Auto",
242 "Normal",
243 "Macro",
244 "Infinity",
245 NULL
246 };
Hans Verkuil513521e2010-12-29 14:25:52 -0300247 static const char * const colorfx[] = {
Hans Verkuil09965172010-08-01 14:32:42 -0300248 "None",
249 "Black & White",
250 "Sepia",
251 "Negative",
252 "Emboss",
253 "Sketch",
Kamil Debski064f5092011-06-14 10:46:22 -0300254 "Sky Blue",
255 "Grass Green",
256 "Skin Whiten",
Hans Verkuil09965172010-08-01 14:32:42 -0300257 "Vivid",
Sylwester Nawrocki6491d1a2012-04-02 06:40:19 -0300258 "Aqua",
259 "Art Freeze",
260 "Silhouette",
261 "Solarization",
262 "Antique",
263 "Set Cb/Cr",
Hans Verkuil09965172010-08-01 14:32:42 -0300264 NULL
265 };
Sylwester Nawrockie40a0572012-03-06 07:04:26 -0300266 static const char * const auto_n_preset_white_balance[] = {
267 "Manual",
268 "Auto",
269 "Incandescent",
270 "Fluorescent",
271 "Fluorescent H",
272 "Horizon",
273 "Daylight",
274 "Flash",
275 "Cloudy",
276 "Shade",
277 NULL,
278 };
Sylwester Nawrocki7f84ad82012-05-01 17:39:45 -0300279 static const char * const camera_iso_sensitivity_auto[] = {
280 "Manual",
281 "Auto",
282 NULL
283 };
Sylwester Nawrocki0bf6b7d2012-04-16 10:45:44 -0300284 static const char * const scene_mode[] = {
285 "None",
286 "Backlight",
287 "Beach/Snow",
288 "Candle Light",
289 "Dusk/Dawn",
290 "Fall Colors",
291 "Fireworks",
292 "Landscape",
293 "Night",
294 "Party/Indoor",
295 "Portrait",
296 "Sports",
297 "Sunset",
298 "Text",
299 NULL
300 };
Andrey Smirnovaec330a2013-03-26 22:47:23 -0300301 static const char * const tune_emphasis[] = {
302 "None",
Hans Verkuilf769c262012-03-02 04:20:19 -0300303 "50 Microseconds",
304 "75 Microseconds",
Hans Verkuil09965172010-08-01 14:32:42 -0300305 NULL,
306 };
Kamil Debski064f5092011-06-14 10:46:22 -0300307 static const char * const header_mode[] = {
308 "Separate Buffer",
309 "Joined With 1st Frame",
310 NULL,
311 };
312 static const char * const multi_slice[] = {
313 "Single",
314 "Max Macroblocks",
315 "Max Bytes",
316 NULL,
317 };
318 static const char * const entropy_mode[] = {
319 "CAVLC",
320 "CABAC",
321 NULL,
322 };
323 static const char * const mpeg_h264_level[] = {
324 "1",
325 "1b",
326 "1.1",
327 "1.2",
328 "1.3",
329 "2",
330 "2.1",
331 "2.2",
332 "3",
333 "3.1",
334 "3.2",
335 "4",
336 "4.1",
337 "4.2",
338 "5",
339 "5.1",
340 NULL,
341 };
342 static const char * const h264_loop_filter[] = {
343 "Enabled",
344 "Disabled",
345 "Disabled at Slice Boundary",
346 NULL,
347 };
348 static const char * const h264_profile[] = {
349 "Baseline",
350 "Constrained Baseline",
351 "Main",
352 "Extended",
353 "High",
354 "High 10",
355 "High 422",
356 "High 444 Predictive",
357 "High 10 Intra",
358 "High 422 Intra",
359 "High 444 Intra",
360 "CAVLC 444 Intra",
361 "Scalable Baseline",
362 "Scalable High",
363 "Scalable High Intra",
364 "Multiview High",
365 NULL,
366 };
367 static const char * const vui_sar_idc[] = {
368 "Unspecified",
369 "1:1",
370 "12:11",
371 "10:11",
372 "16:11",
373 "40:33",
374 "24:11",
375 "20:11",
376 "32:11",
377 "80:33",
378 "18:11",
379 "15:11",
380 "64:33",
381 "160:99",
382 "4:3",
383 "3:2",
384 "2:1",
385 "Extended SAR",
386 NULL,
387 };
Arun Kumar K2e81dde2012-10-03 22:19:06 -0300388 static const char * const h264_fp_arrangement_type[] = {
389 "Checkerboard",
390 "Column",
391 "Row",
392 "Side by Side",
393 "Top Bottom",
394 "Temporal",
395 NULL,
396 };
397 static const char * const h264_fmo_map_type[] = {
398 "Interleaved Slices",
399 "Scattered Slices",
400 "Foreground with Leftover",
401 "Box Out",
402 "Raster Scan",
403 "Wipe Scan",
404 "Explicit",
405 NULL,
406 };
Kamil Debski064f5092011-06-14 10:46:22 -0300407 static const char * const mpeg_mpeg4_level[] = {
408 "0",
409 "0b",
410 "1",
411 "2",
412 "3",
413 "3b",
414 "4",
415 "5",
416 NULL,
417 };
418 static const char * const mpeg4_profile[] = {
419 "Simple",
Hans Verkuilf769c262012-03-02 04:20:19 -0300420 "Advanced Simple",
Kamil Debski064f5092011-06-14 10:46:22 -0300421 "Core",
422 "Simple Scalable",
Jonathan McCrohan39c1cb22013-10-20 21:34:01 -0300423 "Advanced Coding Efficiency",
Kamil Debski064f5092011-06-14 10:46:22 -0300424 NULL,
425 };
426
Arun Kumar Kbc9028e2013-07-09 01:24:41 -0300427 static const char * const vpx_golden_frame_sel[] = {
428 "Use Previous Frame",
429 "Use Previous Specific Frame",
430 NULL,
431 };
432
Sakari Ailus0b159ac2011-03-21 12:52:51 -0300433 static const char * const flash_led_mode[] = {
434 "Off",
435 "Flash",
436 "Torch",
437 NULL,
438 };
439 static const char * const flash_strobe_source[] = {
440 "Software",
441 "External",
442 NULL,
443 };
Hans Verkuil09965172010-08-01 14:32:42 -0300444
Sylwester Nawrockic7361ae2012-01-20 15:37:44 -0300445 static const char * const jpeg_chroma_subsampling[] = {
446 "4:4:4",
447 "4:2:2",
448 "4:2:0",
449 "4:1:1",
450 "4:1:0",
451 "Gray",
452 NULL,
453 };
Hans Verkuil977ebec2012-07-03 06:14:37 -0300454 static const char * const dv_tx_mode[] = {
455 "DVI-D",
456 "HDMI",
457 NULL,
458 };
459 static const char * const dv_rgb_range[] = {
460 "Automatic",
461 "RGB limited range (16-235)",
462 "RGB full range (0-255)",
463 NULL,
464 };
Hans Verkuil45cc29a2016-01-27 11:31:39 -0200465 static const char * const dv_it_content_type[] = {
466 "Graphics",
467 "Photo",
468 "Cinema",
469 "Game",
470 "No IT Content",
471 NULL,
472 };
Hans Verkuila77b4fc2014-03-28 13:00:08 -0300473 static const char * const detect_md_mode[] = {
474 "Disabled",
475 "Global",
476 "Threshold Grid",
477 "Region Grid",
478 NULL,
479 };
Hans Verkuil977ebec2012-07-03 06:14:37 -0300480
Sylwester Nawrockic7361ae2012-01-20 15:37:44 -0300481
Hans Verkuil09965172010-08-01 14:32:42 -0300482 switch (id) {
483 case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
484 return mpeg_audio_sampling_freq;
485 case V4L2_CID_MPEG_AUDIO_ENCODING:
486 return mpeg_audio_encoding;
487 case V4L2_CID_MPEG_AUDIO_L1_BITRATE:
488 return mpeg_audio_l1_bitrate;
489 case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
490 return mpeg_audio_l2_bitrate;
491 case V4L2_CID_MPEG_AUDIO_L3_BITRATE:
492 return mpeg_audio_l3_bitrate;
493 case V4L2_CID_MPEG_AUDIO_AC3_BITRATE:
494 return mpeg_audio_ac3_bitrate;
495 case V4L2_CID_MPEG_AUDIO_MODE:
496 return mpeg_audio_mode;
497 case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION:
498 return mpeg_audio_mode_extension;
499 case V4L2_CID_MPEG_AUDIO_EMPHASIS:
500 return mpeg_audio_emphasis;
501 case V4L2_CID_MPEG_AUDIO_CRC:
502 return mpeg_audio_crc;
Hans Verkuil24c19a22011-12-15 10:46:16 -0300503 case V4L2_CID_MPEG_AUDIO_DEC_PLAYBACK:
504 case V4L2_CID_MPEG_AUDIO_DEC_MULTILINGUAL_PLAYBACK:
505 return mpeg_audio_dec_playback;
Hans Verkuil09965172010-08-01 14:32:42 -0300506 case V4L2_CID_MPEG_VIDEO_ENCODING:
507 return mpeg_video_encoding;
508 case V4L2_CID_MPEG_VIDEO_ASPECT:
509 return mpeg_video_aspect;
510 case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
511 return mpeg_video_bitrate_mode;
512 case V4L2_CID_MPEG_STREAM_TYPE:
513 return mpeg_stream_type;
514 case V4L2_CID_MPEG_STREAM_VBI_FMT:
515 return mpeg_stream_vbi_fmt;
516 case V4L2_CID_POWER_LINE_FREQUENCY:
517 return camera_power_line_frequency;
518 case V4L2_CID_EXPOSURE_AUTO:
519 return camera_exposure_auto;
Sylwester Nawrockicf072132012-04-30 04:34:10 -0300520 case V4L2_CID_EXPOSURE_METERING:
521 return camera_exposure_metering;
Sylwester Nawrocki2272ab62012-05-11 06:37:03 -0300522 case V4L2_CID_AUTO_FOCUS_RANGE:
523 return camera_auto_focus_range;
Hans Verkuil09965172010-08-01 14:32:42 -0300524 case V4L2_CID_COLORFX:
525 return colorfx;
Sylwester Nawrockie40a0572012-03-06 07:04:26 -0300526 case V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE:
527 return auto_n_preset_white_balance;
Sylwester Nawrocki7f84ad82012-05-01 17:39:45 -0300528 case V4L2_CID_ISO_SENSITIVITY_AUTO:
529 return camera_iso_sensitivity_auto;
Sylwester Nawrocki0bf6b7d2012-04-16 10:45:44 -0300530 case V4L2_CID_SCENE_MODE:
531 return scene_mode;
Hans Verkuil09965172010-08-01 14:32:42 -0300532 case V4L2_CID_TUNE_PREEMPHASIS:
Andrey Smirnovaec330a2013-03-26 22:47:23 -0300533 return tune_emphasis;
534 case V4L2_CID_TUNE_DEEMPHASIS:
535 return tune_emphasis;
Sakari Ailus0b159ac2011-03-21 12:52:51 -0300536 case V4L2_CID_FLASH_LED_MODE:
537 return flash_led_mode;
538 case V4L2_CID_FLASH_STROBE_SOURCE:
539 return flash_strobe_source;
Kamil Debski064f5092011-06-14 10:46:22 -0300540 case V4L2_CID_MPEG_VIDEO_HEADER_MODE:
541 return header_mode;
542 case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE:
543 return multi_slice;
544 case V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE:
545 return entropy_mode;
546 case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
547 return mpeg_h264_level;
548 case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE:
549 return h264_loop_filter;
550 case V4L2_CID_MPEG_VIDEO_H264_PROFILE:
551 return h264_profile;
552 case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC:
553 return vui_sar_idc;
Arun Kumar K2e81dde2012-10-03 22:19:06 -0300554 case V4L2_CID_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE:
555 return h264_fp_arrangement_type;
556 case V4L2_CID_MPEG_VIDEO_H264_FMO_MAP_TYPE:
557 return h264_fmo_map_type;
Kamil Debski064f5092011-06-14 10:46:22 -0300558 case V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL:
559 return mpeg_mpeg4_level;
560 case V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE:
561 return mpeg4_profile;
Arun Kumar Kbc9028e2013-07-09 01:24:41 -0300562 case V4L2_CID_MPEG_VIDEO_VPX_GOLDEN_FRAME_SEL:
563 return vpx_golden_frame_sel;
Sylwester Nawrockic7361ae2012-01-20 15:37:44 -0300564 case V4L2_CID_JPEG_CHROMA_SUBSAMPLING:
565 return jpeg_chroma_subsampling;
Hans Verkuil977ebec2012-07-03 06:14:37 -0300566 case V4L2_CID_DV_TX_MODE:
567 return dv_tx_mode;
568 case V4L2_CID_DV_TX_RGB_RANGE:
569 case V4L2_CID_DV_RX_RGB_RANGE:
570 return dv_rgb_range;
Hans Verkuil45cc29a2016-01-27 11:31:39 -0200571 case V4L2_CID_DV_TX_IT_CONTENT_TYPE:
572 case V4L2_CID_DV_RX_IT_CONTENT_TYPE:
573 return dv_it_content_type;
Hans Verkuila77b4fc2014-03-28 13:00:08 -0300574 case V4L2_CID_DETECT_MD_MODE:
575 return detect_md_mode;
Sylwester Nawrockic7361ae2012-01-20 15:37:44 -0300576
Hans Verkuil09965172010-08-01 14:32:42 -0300577 default:
578 return NULL;
579 }
580}
581EXPORT_SYMBOL(v4l2_ctrl_get_menu);
582
Arun Kumar Kbc9028e2013-07-09 01:24:41 -0300583#define __v4l2_qmenu_int_len(arr, len) ({ *(len) = ARRAY_SIZE(arr); arr; })
Sylwester Nawrockid1e9b7c2013-07-09 01:24:40 -0300584/*
585 * Returns NULL or an s64 type array containing the menu for given
586 * control ID. The total number of the menu items is returned in @len.
587 */
Sylwester Nawrocki4eed9b32013-10-14 20:08:03 -0300588const s64 *v4l2_ctrl_get_int_menu(u32 id, u32 *len)
Sylwester Nawrockid1e9b7c2013-07-09 01:24:40 -0300589{
Sylwester Nawrocki4eed9b32013-10-14 20:08:03 -0300590 static const s64 qmenu_int_vpx_num_partitions[] = {
Arun Kumar Kbc9028e2013-07-09 01:24:41 -0300591 1, 2, 4, 8,
592 };
593
Sylwester Nawrocki4eed9b32013-10-14 20:08:03 -0300594 static const s64 qmenu_int_vpx_num_ref_frames[] = {
Arun Kumar Kbc9028e2013-07-09 01:24:41 -0300595 1, 2, 3,
596 };
597
Sylwester Nawrockid1e9b7c2013-07-09 01:24:40 -0300598 switch (id) {
Arun Kumar Kbc9028e2013-07-09 01:24:41 -0300599 case V4L2_CID_MPEG_VIDEO_VPX_NUM_PARTITIONS:
600 return __v4l2_qmenu_int_len(qmenu_int_vpx_num_partitions, len);
601 case V4L2_CID_MPEG_VIDEO_VPX_NUM_REF_FRAMES:
602 return __v4l2_qmenu_int_len(qmenu_int_vpx_num_ref_frames, len);
Sylwester Nawrockid1e9b7c2013-07-09 01:24:40 -0300603 default:
604 *len = 0;
605 return NULL;
Joe Perches2028c712013-10-08 20:29:08 -0300606 }
Sylwester Nawrockid1e9b7c2013-07-09 01:24:40 -0300607}
608EXPORT_SYMBOL(v4l2_ctrl_get_int_menu);
609
Hans Verkuil09965172010-08-01 14:32:42 -0300610/* Return the control name. */
611const char *v4l2_ctrl_get_name(u32 id)
612{
613 switch (id) {
614 /* USER controls */
Hans Verkuil59253f22014-01-27 11:03:34 -0300615 /* Keep the order of the 'case's the same as in v4l2-controls.h! */
Mauro Carvalho Chehab6dd5aff2010-08-06 09:57:02 -0300616 case V4L2_CID_USER_CLASS: return "User Controls";
617 case V4L2_CID_BRIGHTNESS: return "Brightness";
618 case V4L2_CID_CONTRAST: return "Contrast";
619 case V4L2_CID_SATURATION: return "Saturation";
620 case V4L2_CID_HUE: return "Hue";
621 case V4L2_CID_AUDIO_VOLUME: return "Volume";
622 case V4L2_CID_AUDIO_BALANCE: return "Balance";
623 case V4L2_CID_AUDIO_BASS: return "Bass";
624 case V4L2_CID_AUDIO_TREBLE: return "Treble";
625 case V4L2_CID_AUDIO_MUTE: return "Mute";
626 case V4L2_CID_AUDIO_LOUDNESS: return "Loudness";
Hans Verkuil09965172010-08-01 14:32:42 -0300627 case V4L2_CID_BLACK_LEVEL: return "Black Level";
628 case V4L2_CID_AUTO_WHITE_BALANCE: return "White Balance, Automatic";
629 case V4L2_CID_DO_WHITE_BALANCE: return "Do White Balance";
630 case V4L2_CID_RED_BALANCE: return "Red Balance";
631 case V4L2_CID_BLUE_BALANCE: return "Blue Balance";
632 case V4L2_CID_GAMMA: return "Gamma";
633 case V4L2_CID_EXPOSURE: return "Exposure";
634 case V4L2_CID_AUTOGAIN: return "Gain, Automatic";
635 case V4L2_CID_GAIN: return "Gain";
636 case V4L2_CID_HFLIP: return "Horizontal Flip";
637 case V4L2_CID_VFLIP: return "Vertical Flip";
Hans Verkuil09965172010-08-01 14:32:42 -0300638 case V4L2_CID_POWER_LINE_FREQUENCY: return "Power Line Frequency";
639 case V4L2_CID_HUE_AUTO: return "Hue, Automatic";
640 case V4L2_CID_WHITE_BALANCE_TEMPERATURE: return "White Balance Temperature";
641 case V4L2_CID_SHARPNESS: return "Sharpness";
642 case V4L2_CID_BACKLIGHT_COMPENSATION: return "Backlight Compensation";
643 case V4L2_CID_CHROMA_AGC: return "Chroma AGC";
Hans Verkuil09965172010-08-01 14:32:42 -0300644 case V4L2_CID_COLOR_KILLER: return "Color Killer";
645 case V4L2_CID_COLORFX: return "Color Effects";
646 case V4L2_CID_AUTOBRIGHTNESS: return "Brightness, Automatic";
647 case V4L2_CID_BAND_STOP_FILTER: return "Band-Stop Filter";
648 case V4L2_CID_ROTATE: return "Rotate";
649 case V4L2_CID_BG_COLOR: return "Background Color";
Hans Verkuil6c8d6112010-04-25 19:21:00 -0300650 case V4L2_CID_CHROMA_GAIN: return "Chroma Gain";
Jean-François Moine008d35f2010-09-13 07:04:49 -0300651 case V4L2_CID_ILLUMINATORS_1: return "Illuminator 1";
652 case V4L2_CID_ILLUMINATORS_2: return "Illuminator 2";
Hans Verkuilf08aacf2012-01-16 12:27:15 -0300653 case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE: return "Min Number of Capture Buffers";
654 case V4L2_CID_MIN_BUFFERS_FOR_OUTPUT: return "Min Number of Output Buffers";
Sylwester Nawrockicc1d3272011-11-14 08:48:18 -0300655 case V4L2_CID_ALPHA_COMPONENT: return "Alpha Component";
Sylwester Nawrocki6491d1a2012-04-02 06:40:19 -0300656 case V4L2_CID_COLORFX_CBCR: return "Color Effects, CbCr";
Hans Verkuil09965172010-08-01 14:32:42 -0300657
Arun Kumar Kbc9028e2013-07-09 01:24:41 -0300658 /* Codec controls */
659 /* The MPEG controls are applicable to all codec controls
660 * and the 'MPEG' part of the define is historical */
Hans Verkuil6c8d6112010-04-25 19:21:00 -0300661 /* Keep the order of the 'case's the same as in videodev2.h! */
Arun Kumar Kbc9028e2013-07-09 01:24:41 -0300662 case V4L2_CID_MPEG_CLASS: return "Codec Controls";
Mauro Carvalho Chehab6dd5aff2010-08-06 09:57:02 -0300663 case V4L2_CID_MPEG_STREAM_TYPE: return "Stream Type";
664 case V4L2_CID_MPEG_STREAM_PID_PMT: return "Stream PMT Program ID";
665 case V4L2_CID_MPEG_STREAM_PID_AUDIO: return "Stream Audio Program ID";
666 case V4L2_CID_MPEG_STREAM_PID_VIDEO: return "Stream Video Program ID";
667 case V4L2_CID_MPEG_STREAM_PID_PCR: return "Stream PCR Program ID";
Hans Verkuil6c8d6112010-04-25 19:21:00 -0300668 case V4L2_CID_MPEG_STREAM_PES_ID_AUDIO: return "Stream PES Audio ID";
669 case V4L2_CID_MPEG_STREAM_PES_ID_VIDEO: return "Stream PES Video ID";
670 case V4L2_CID_MPEG_STREAM_VBI_FMT: return "Stream VBI Format";
Hans Verkuil09965172010-08-01 14:32:42 -0300671 case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ: return "Audio Sampling Frequency";
Mauro Carvalho Chehab6dd5aff2010-08-06 09:57:02 -0300672 case V4L2_CID_MPEG_AUDIO_ENCODING: return "Audio Encoding";
673 case V4L2_CID_MPEG_AUDIO_L1_BITRATE: return "Audio Layer I Bitrate";
674 case V4L2_CID_MPEG_AUDIO_L2_BITRATE: return "Audio Layer II Bitrate";
675 case V4L2_CID_MPEG_AUDIO_L3_BITRATE: return "Audio Layer III Bitrate";
676 case V4L2_CID_MPEG_AUDIO_MODE: return "Audio Stereo Mode";
Hans Verkuil09965172010-08-01 14:32:42 -0300677 case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION: return "Audio Stereo Mode Extension";
Mauro Carvalho Chehab6dd5aff2010-08-06 09:57:02 -0300678 case V4L2_CID_MPEG_AUDIO_EMPHASIS: return "Audio Emphasis";
679 case V4L2_CID_MPEG_AUDIO_CRC: return "Audio CRC";
680 case V4L2_CID_MPEG_AUDIO_MUTE: return "Audio Mute";
681 case V4L2_CID_MPEG_AUDIO_AAC_BITRATE: return "Audio AAC Bitrate";
682 case V4L2_CID_MPEG_AUDIO_AC3_BITRATE: return "Audio AC-3 Bitrate";
Hans Verkuil24c19a22011-12-15 10:46:16 -0300683 case V4L2_CID_MPEG_AUDIO_DEC_PLAYBACK: return "Audio Playback";
684 case V4L2_CID_MPEG_AUDIO_DEC_MULTILINGUAL_PLAYBACK: return "Audio Multilingual Playback";
Mauro Carvalho Chehab6dd5aff2010-08-06 09:57:02 -0300685 case V4L2_CID_MPEG_VIDEO_ENCODING: return "Video Encoding";
686 case V4L2_CID_MPEG_VIDEO_ASPECT: return "Video Aspect";
687 case V4L2_CID_MPEG_VIDEO_B_FRAMES: return "Video B Frames";
688 case V4L2_CID_MPEG_VIDEO_GOP_SIZE: return "Video GOP Size";
689 case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE: return "Video GOP Closure";
690 case V4L2_CID_MPEG_VIDEO_PULLDOWN: return "Video Pulldown";
691 case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: return "Video Bitrate Mode";
692 case V4L2_CID_MPEG_VIDEO_BITRATE: return "Video Bitrate";
693 case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK: return "Video Peak Bitrate";
Hans Verkuil09965172010-08-01 14:32:42 -0300694 case V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION: return "Video Temporal Decimation";
Mauro Carvalho Chehab6dd5aff2010-08-06 09:57:02 -0300695 case V4L2_CID_MPEG_VIDEO_MUTE: return "Video Mute";
Hans Verkuil09965172010-08-01 14:32:42 -0300696 case V4L2_CID_MPEG_VIDEO_MUTE_YUV: return "Video Mute YUV";
Kamil Debski064f5092011-06-14 10:46:22 -0300697 case V4L2_CID_MPEG_VIDEO_DECODER_SLICE_INTERFACE: return "Decoder Slice Interface";
698 case V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER: return "MPEG4 Loop Filter Enable";
Hans Verkuilf08aacf2012-01-16 12:27:15 -0300699 case V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB: return "Number of Intra Refresh MBs";
Kamil Debski064f5092011-06-14 10:46:22 -0300700 case V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE: return "Frame Level Rate Control Enable";
701 case V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE: return "H264 MB Level Rate Control";
702 case V4L2_CID_MPEG_VIDEO_HEADER_MODE: return "Sequence Header Mode";
Hans Verkuilf08aacf2012-01-16 12:27:15 -0300703 case V4L2_CID_MPEG_VIDEO_MAX_REF_PIC: return "Max Number of Reference Pics";
Kamil Debski064f5092011-06-14 10:46:22 -0300704 case V4L2_CID_MPEG_VIDEO_H263_I_FRAME_QP: return "H263 I-Frame QP Value";
Hans Verkuilf08aacf2012-01-16 12:27:15 -0300705 case V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP: return "H263 P-Frame QP Value";
706 case V4L2_CID_MPEG_VIDEO_H263_B_FRAME_QP: return "H263 B-Frame QP Value";
Kamil Debski064f5092011-06-14 10:46:22 -0300707 case V4L2_CID_MPEG_VIDEO_H263_MIN_QP: return "H263 Minimum QP Value";
708 case V4L2_CID_MPEG_VIDEO_H263_MAX_QP: return "H263 Maximum QP Value";
709 case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP: return "H264 I-Frame QP Value";
Hans Verkuilf08aacf2012-01-16 12:27:15 -0300710 case V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP: return "H264 P-Frame QP Value";
711 case V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP: return "H264 B-Frame QP Value";
Kamil Debski064f5092011-06-14 10:46:22 -0300712 case V4L2_CID_MPEG_VIDEO_H264_MAX_QP: return "H264 Maximum QP Value";
713 case V4L2_CID_MPEG_VIDEO_H264_MIN_QP: return "H264 Minimum QP Value";
714 case V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM: return "H264 8x8 Transform Enable";
715 case V4L2_CID_MPEG_VIDEO_H264_CPB_SIZE: return "H264 CPB Buffer Size";
Hans Verkuilf08aacf2012-01-16 12:27:15 -0300716 case V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE: return "H264 Entropy Mode";
717 case V4L2_CID_MPEG_VIDEO_H264_I_PERIOD: return "H264 I-Frame Period";
Kamil Debski064f5092011-06-14 10:46:22 -0300718 case V4L2_CID_MPEG_VIDEO_H264_LEVEL: return "H264 Level";
719 case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA: return "H264 Loop Filter Alpha Offset";
720 case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA: return "H264 Loop Filter Beta Offset";
721 case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE: return "H264 Loop Filter Mode";
722 case V4L2_CID_MPEG_VIDEO_H264_PROFILE: return "H264 Profile";
723 case V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_HEIGHT: return "Vertical Size of SAR";
724 case V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_WIDTH: return "Horizontal Size of SAR";
725 case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_ENABLE: return "Aspect Ratio VUI Enable";
726 case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC: return "VUI Aspect Ratio IDC";
Arun Kumar K2e81dde2012-10-03 22:19:06 -0300727 case V4L2_CID_MPEG_VIDEO_H264_SEI_FRAME_PACKING: return "H264 Enable Frame Packing SEI";
728 case V4L2_CID_MPEG_VIDEO_H264_SEI_FP_CURRENT_FRAME_0: return "H264 Set Curr. Frame as Frame0";
729 case V4L2_CID_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE: return "H264 FP Arrangement Type";
730 case V4L2_CID_MPEG_VIDEO_H264_FMO: return "H264 Flexible MB Ordering";
731 case V4L2_CID_MPEG_VIDEO_H264_FMO_MAP_TYPE: return "H264 Map Type for FMO";
732 case V4L2_CID_MPEG_VIDEO_H264_FMO_SLICE_GROUP: return "H264 FMO Number of Slice Groups";
733 case V4L2_CID_MPEG_VIDEO_H264_FMO_CHANGE_DIRECTION: return "H264 FMO Direction of Change";
734 case V4L2_CID_MPEG_VIDEO_H264_FMO_CHANGE_RATE: return "H264 FMO Size of 1st Slice Grp";
735 case V4L2_CID_MPEG_VIDEO_H264_FMO_RUN_LENGTH: return "H264 FMO No. of Consecutive MBs";
736 case V4L2_CID_MPEG_VIDEO_H264_ASO: return "H264 Arbitrary Slice Ordering";
737 case V4L2_CID_MPEG_VIDEO_H264_ASO_SLICE_ORDER: return "H264 ASO Slice Order";
738 case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING: return "Enable H264 Hierarchical Coding";
739 case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_TYPE: return "H264 Hierarchical Coding Type";
740 case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER:return "H264 Number of HC Layers";
741 case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_QP:
742 return "H264 Set QP Value for HC Layers";
Kamil Debski064f5092011-06-14 10:46:22 -0300743 case V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP: return "MPEG4 I-Frame QP Value";
Hans Verkuilf08aacf2012-01-16 12:27:15 -0300744 case V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP: return "MPEG4 P-Frame QP Value";
745 case V4L2_CID_MPEG_VIDEO_MPEG4_B_FRAME_QP: return "MPEG4 B-Frame QP Value";
Kamil Debski064f5092011-06-14 10:46:22 -0300746 case V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP: return "MPEG4 Minimum QP Value";
747 case V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP: return "MPEG4 Maximum QP Value";
748 case V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL: return "MPEG4 Level";
749 case V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE: return "MPEG4 Profile";
750 case V4L2_CID_MPEG_VIDEO_MPEG4_QPEL: return "Quarter Pixel Search Enable";
Hans Verkuilf08aacf2012-01-16 12:27:15 -0300751 case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES: return "Maximum Bytes in a Slice";
752 case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB: return "Number of MBs in a Slice";
753 case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE: return "Slice Partitioning Method";
Kamil Debski064f5092011-06-14 10:46:22 -0300754 case V4L2_CID_MPEG_VIDEO_VBV_SIZE: return "VBV Buffer Size";
Hans Verkuil24c19a22011-12-15 10:46:16 -0300755 case V4L2_CID_MPEG_VIDEO_DEC_PTS: return "Video Decoder PTS";
756 case V4L2_CID_MPEG_VIDEO_DEC_FRAME: return "Video Decoder Frame Count";
Arun Kumar K2e81dde2012-10-03 22:19:06 -0300757 case V4L2_CID_MPEG_VIDEO_VBV_DELAY: return "Initial Delay for VBV Control";
Amit Groverbf0bedd2014-02-04 06:59:58 -0300758 case V4L2_CID_MPEG_VIDEO_MV_H_SEARCH_RANGE: return "Horizontal MV Search Range";
759 case V4L2_CID_MPEG_VIDEO_MV_V_SEARCH_RANGE: return "Vertical MV Search Range";
Hans Verkuil9ca54702013-03-17 10:34:04 -0300760 case V4L2_CID_MPEG_VIDEO_REPEAT_SEQ_HEADER: return "Repeat Sequence Header";
Hans Verkuil09965172010-08-01 14:32:42 -0300761
Arun Kumar Kbc9028e2013-07-09 01:24:41 -0300762 /* VPX controls */
763 case V4L2_CID_MPEG_VIDEO_VPX_NUM_PARTITIONS: return "VPX Number of Partitions";
764 case V4L2_CID_MPEG_VIDEO_VPX_IMD_DISABLE_4X4: return "VPX Intra Mode Decision Disable";
765 case V4L2_CID_MPEG_VIDEO_VPX_NUM_REF_FRAMES: return "VPX No. of Refs for P Frame";
766 case V4L2_CID_MPEG_VIDEO_VPX_FILTER_LEVEL: return "VPX Loop Filter Level Range";
767 case V4L2_CID_MPEG_VIDEO_VPX_FILTER_SHARPNESS: return "VPX Deblocking Effect Control";
768 case V4L2_CID_MPEG_VIDEO_VPX_GOLDEN_FRAME_REF_PERIOD: return "VPX Golden Frame Refresh Period";
769 case V4L2_CID_MPEG_VIDEO_VPX_GOLDEN_FRAME_SEL: return "VPX Golden Frame Indicator";
Arun Kumar K4773ab92013-11-15 02:29:22 -0300770 case V4L2_CID_MPEG_VIDEO_VPX_MIN_QP: return "VPX Minimum QP Value";
771 case V4L2_CID_MPEG_VIDEO_VPX_MAX_QP: return "VPX Maximum QP Value";
772 case V4L2_CID_MPEG_VIDEO_VPX_I_FRAME_QP: return "VPX I-Frame QP Value";
773 case V4L2_CID_MPEG_VIDEO_VPX_P_FRAME_QP: return "VPX P-Frame QP Value";
Kiran AVNDbbd8f3f2013-12-16 06:40:42 -0300774 case V4L2_CID_MPEG_VIDEO_VPX_PROFILE: return "VPX Profile";
Arun Kumar Kbc9028e2013-07-09 01:24:41 -0300775
Hans Verkuil09965172010-08-01 14:32:42 -0300776 /* CAMERA controls */
Hans Verkuil59253f22014-01-27 11:03:34 -0300777 /* Keep the order of the 'case's the same as in v4l2-controls.h! */
Hans Verkuil09965172010-08-01 14:32:42 -0300778 case V4L2_CID_CAMERA_CLASS: return "Camera Controls";
779 case V4L2_CID_EXPOSURE_AUTO: return "Auto Exposure";
780 case V4L2_CID_EXPOSURE_ABSOLUTE: return "Exposure Time, Absolute";
781 case V4L2_CID_EXPOSURE_AUTO_PRIORITY: return "Exposure, Dynamic Framerate";
782 case V4L2_CID_PAN_RELATIVE: return "Pan, Relative";
783 case V4L2_CID_TILT_RELATIVE: return "Tilt, Relative";
784 case V4L2_CID_PAN_RESET: return "Pan, Reset";
785 case V4L2_CID_TILT_RESET: return "Tilt, Reset";
786 case V4L2_CID_PAN_ABSOLUTE: return "Pan, Absolute";
787 case V4L2_CID_TILT_ABSOLUTE: return "Tilt, Absolute";
788 case V4L2_CID_FOCUS_ABSOLUTE: return "Focus, Absolute";
789 case V4L2_CID_FOCUS_RELATIVE: return "Focus, Relative";
Sylwester Nawrocki2272ab62012-05-11 06:37:03 -0300790 case V4L2_CID_FOCUS_AUTO: return "Focus, Automatic Continuous";
Hans Verkuil09965172010-08-01 14:32:42 -0300791 case V4L2_CID_ZOOM_ABSOLUTE: return "Zoom, Absolute";
792 case V4L2_CID_ZOOM_RELATIVE: return "Zoom, Relative";
793 case V4L2_CID_ZOOM_CONTINUOUS: return "Zoom, Continuous";
794 case V4L2_CID_PRIVACY: return "Privacy";
Hans Verkuil6c8d6112010-04-25 19:21:00 -0300795 case V4L2_CID_IRIS_ABSOLUTE: return "Iris, Absolute";
796 case V4L2_CID_IRIS_RELATIVE: return "Iris, Relative";
Sylwester Nawrockid58083c2012-03-06 07:06:55 -0300797 case V4L2_CID_AUTO_EXPOSURE_BIAS: return "Auto Exposure, Bias";
Sylwester Nawrockie40a0572012-03-06 07:04:26 -0300798 case V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE: return "White Balance, Auto & Preset";
Sylwester Nawrocki44d44a12012-03-06 07:05:45 -0300799 case V4L2_CID_WIDE_DYNAMIC_RANGE: return "Wide Dynamic Range";
Sylwester Nawrocki82b30562012-05-01 17:38:09 -0300800 case V4L2_CID_IMAGE_STABILIZATION: return "Image Stabilization";
Sylwester Nawrocki7f84ad82012-05-01 17:39:45 -0300801 case V4L2_CID_ISO_SENSITIVITY: return "ISO Sensitivity";
802 case V4L2_CID_ISO_SENSITIVITY_AUTO: return "ISO Sensitivity, Auto";
Sylwester Nawrockicf072132012-04-30 04:34:10 -0300803 case V4L2_CID_EXPOSURE_METERING: return "Exposure, Metering Mode";
Sylwester Nawrocki0bf6b7d2012-04-16 10:45:44 -0300804 case V4L2_CID_SCENE_MODE: return "Scene Mode";
Sylwester Nawrockifc162a02012-05-02 06:24:33 -0300805 case V4L2_CID_3A_LOCK: return "3A Lock";
Sylwester Nawrocki2272ab62012-05-11 06:37:03 -0300806 case V4L2_CID_AUTO_FOCUS_START: return "Auto Focus, Start";
807 case V4L2_CID_AUTO_FOCUS_STOP: return "Auto Focus, Stop";
808 case V4L2_CID_AUTO_FOCUS_STATUS: return "Auto Focus, Status";
809 case V4L2_CID_AUTO_FOCUS_RANGE: return "Auto Focus, Range";
Vincent Palatine3d6eb12014-09-03 16:38:39 -0300810 case V4L2_CID_PAN_SPEED: return "Pan, Speed";
811 case V4L2_CID_TILT_SPEED: return "Tilt, Speed";
Hans Verkuil09965172010-08-01 14:32:42 -0300812
Hans Verkuil59253f22014-01-27 11:03:34 -0300813 /* FM Radio Modulator controls */
814 /* Keep the order of the 'case's the same as in v4l2-controls.h! */
Hans Verkuil09965172010-08-01 14:32:42 -0300815 case V4L2_CID_FM_TX_CLASS: return "FM Radio Modulator Controls";
816 case V4L2_CID_RDS_TX_DEVIATION: return "RDS Signal Deviation";
817 case V4L2_CID_RDS_TX_PI: return "RDS Program ID";
818 case V4L2_CID_RDS_TX_PTY: return "RDS Program Type";
819 case V4L2_CID_RDS_TX_PS_NAME: return "RDS PS Name";
820 case V4L2_CID_RDS_TX_RADIO_TEXT: return "RDS Radio Text";
Hans Verkuil811c5082014-07-21 10:45:37 -0300821 case V4L2_CID_RDS_TX_MONO_STEREO: return "RDS Stereo";
822 case V4L2_CID_RDS_TX_ARTIFICIAL_HEAD: return "RDS Artificial Head";
823 case V4L2_CID_RDS_TX_COMPRESSED: return "RDS Compressed";
824 case V4L2_CID_RDS_TX_DYNAMIC_PTY: return "RDS Dynamic PTY";
825 case V4L2_CID_RDS_TX_TRAFFIC_ANNOUNCEMENT: return "RDS Traffic Announcement";
826 case V4L2_CID_RDS_TX_TRAFFIC_PROGRAM: return "RDS Traffic Program";
827 case V4L2_CID_RDS_TX_MUSIC_SPEECH: return "RDS Music";
828 case V4L2_CID_RDS_TX_ALT_FREQS_ENABLE: return "RDS Enable Alt Frequencies";
829 case V4L2_CID_RDS_TX_ALT_FREQS: return "RDS Alternate Frequencies";
Hans Verkuil09965172010-08-01 14:32:42 -0300830 case V4L2_CID_AUDIO_LIMITER_ENABLED: return "Audio Limiter Feature Enabled";
831 case V4L2_CID_AUDIO_LIMITER_RELEASE_TIME: return "Audio Limiter Release Time";
832 case V4L2_CID_AUDIO_LIMITER_DEVIATION: return "Audio Limiter Deviation";
Hans Verkuilf08aacf2012-01-16 12:27:15 -0300833 case V4L2_CID_AUDIO_COMPRESSION_ENABLED: return "Audio Compression Enabled";
Hans Verkuil09965172010-08-01 14:32:42 -0300834 case V4L2_CID_AUDIO_COMPRESSION_GAIN: return "Audio Compression Gain";
835 case V4L2_CID_AUDIO_COMPRESSION_THRESHOLD: return "Audio Compression Threshold";
836 case V4L2_CID_AUDIO_COMPRESSION_ATTACK_TIME: return "Audio Compression Attack Time";
837 case V4L2_CID_AUDIO_COMPRESSION_RELEASE_TIME: return "Audio Compression Release Time";
838 case V4L2_CID_PILOT_TONE_ENABLED: return "Pilot Tone Feature Enabled";
839 case V4L2_CID_PILOT_TONE_DEVIATION: return "Pilot Tone Deviation";
840 case V4L2_CID_PILOT_TONE_FREQUENCY: return "Pilot Tone Frequency";
Hans Verkuilf08aacf2012-01-16 12:27:15 -0300841 case V4L2_CID_TUNE_PREEMPHASIS: return "Pre-Emphasis";
Hans Verkuil09965172010-08-01 14:32:42 -0300842 case V4L2_CID_TUNE_POWER_LEVEL: return "Tune Power Level";
843 case V4L2_CID_TUNE_ANTENNA_CAPACITOR: return "Tune Antenna Capacitor";
844
Sakari Ailus0b159ac2011-03-21 12:52:51 -0300845 /* Flash controls */
Hans Verkuil59253f22014-01-27 11:03:34 -0300846 /* Keep the order of the 'case's the same as in v4l2-controls.h! */
Hans Verkuilf08aacf2012-01-16 12:27:15 -0300847 case V4L2_CID_FLASH_CLASS: return "Flash Controls";
848 case V4L2_CID_FLASH_LED_MODE: return "LED Mode";
849 case V4L2_CID_FLASH_STROBE_SOURCE: return "Strobe Source";
Sakari Ailus0b159ac2011-03-21 12:52:51 -0300850 case V4L2_CID_FLASH_STROBE: return "Strobe";
Hans Verkuilf08aacf2012-01-16 12:27:15 -0300851 case V4L2_CID_FLASH_STROBE_STOP: return "Stop Strobe";
852 case V4L2_CID_FLASH_STROBE_STATUS: return "Strobe Status";
853 case V4L2_CID_FLASH_TIMEOUT: return "Strobe Timeout";
854 case V4L2_CID_FLASH_INTENSITY: return "Intensity, Flash Mode";
855 case V4L2_CID_FLASH_TORCH_INTENSITY: return "Intensity, Torch Mode";
856 case V4L2_CID_FLASH_INDICATOR_INTENSITY: return "Intensity, Indicator";
Sakari Ailus0b159ac2011-03-21 12:52:51 -0300857 case V4L2_CID_FLASH_FAULT: return "Faults";
858 case V4L2_CID_FLASH_CHARGE: return "Charge";
Hans Verkuilf08aacf2012-01-16 12:27:15 -0300859 case V4L2_CID_FLASH_READY: return "Ready to Strobe";
Sakari Ailus0b159ac2011-03-21 12:52:51 -0300860
Sylwester Nawrockic7361ae2012-01-20 15:37:44 -0300861 /* JPEG encoder controls */
Hans Verkuil59253f22014-01-27 11:03:34 -0300862 /* Keep the order of the 'case's the same as in v4l2-controls.h! */
Sylwester Nawrockic7361ae2012-01-20 15:37:44 -0300863 case V4L2_CID_JPEG_CLASS: return "JPEG Compression Controls";
864 case V4L2_CID_JPEG_CHROMA_SUBSAMPLING: return "Chroma Subsampling";
865 case V4L2_CID_JPEG_RESTART_INTERVAL: return "Restart Interval";
866 case V4L2_CID_JPEG_COMPRESSION_QUALITY: return "Compression Quality";
867 case V4L2_CID_JPEG_ACTIVE_MARKER: return "Active Markers";
868
Sakari Ailus8c9d2362011-10-04 08:20:05 -0300869 /* Image source controls */
Hans Verkuil59253f22014-01-27 11:03:34 -0300870 /* Keep the order of the 'case's the same as in v4l2-controls.h! */
Sakari Ailus8c9d2362011-10-04 08:20:05 -0300871 case V4L2_CID_IMAGE_SOURCE_CLASS: return "Image Source Controls";
872 case V4L2_CID_VBLANK: return "Vertical Blanking";
873 case V4L2_CID_HBLANK: return "Horizontal Blanking";
874 case V4L2_CID_ANALOGUE_GAIN: return "Analogue Gain";
Sakari Ailus0fc87862014-05-28 09:38:21 -0300875 case V4L2_CID_TEST_PATTERN_RED: return "Red Pixel Value";
876 case V4L2_CID_TEST_PATTERN_GREENR: return "Green (Red) Pixel Value";
877 case V4L2_CID_TEST_PATTERN_BLUE: return "Blue Pixel Value";
878 case V4L2_CID_TEST_PATTERN_GREENB: return "Green (Blue) Pixel Value";
Sakari Ailus8c9d2362011-10-04 08:20:05 -0300879
Sakari Ailusc643ee12012-02-02 20:17:54 -0300880 /* Image processing controls */
Hans Verkuil59253f22014-01-27 11:03:34 -0300881 /* Keep the order of the 'case's the same as in v4l2-controls.h! */
Sakari Ailusc643ee12012-02-02 20:17:54 -0300882 case V4L2_CID_IMAGE_PROC_CLASS: return "Image Processing Controls";
883 case V4L2_CID_LINK_FREQ: return "Link Frequency";
884 case V4L2_CID_PIXEL_RATE: return "Pixel Rate";
Lad, Prabhakar5ebef0f2012-10-01 08:17:36 -0300885 case V4L2_CID_TEST_PATTERN: return "Test Pattern";
Sakari Ailusc643ee12012-02-02 20:17:54 -0300886
Hans Verkuil977ebec2012-07-03 06:14:37 -0300887 /* DV controls */
Hans Verkuil59253f22014-01-27 11:03:34 -0300888 /* Keep the order of the 'case's the same as in v4l2-controls.h! */
Hans Verkuil977ebec2012-07-03 06:14:37 -0300889 case V4L2_CID_DV_CLASS: return "Digital Video Controls";
890 case V4L2_CID_DV_TX_HOTPLUG: return "Hotplug Present";
891 case V4L2_CID_DV_TX_RXSENSE: return "RxSense Present";
892 case V4L2_CID_DV_TX_EDID_PRESENT: return "EDID Present";
893 case V4L2_CID_DV_TX_MODE: return "Transmit Mode";
894 case V4L2_CID_DV_TX_RGB_RANGE: return "Tx RGB Quantization Range";
Hans Verkuil45cc29a2016-01-27 11:31:39 -0200895 case V4L2_CID_DV_TX_IT_CONTENT_TYPE: return "Tx IT Content Type";
Hans Verkuil977ebec2012-07-03 06:14:37 -0300896 case V4L2_CID_DV_RX_POWER_PRESENT: return "Power Present";
897 case V4L2_CID_DV_RX_RGB_RANGE: return "Rx RGB Quantization Range";
Hans Verkuil45cc29a2016-01-27 11:31:39 -0200898 case V4L2_CID_DV_RX_IT_CONTENT_TYPE: return "Rx IT Content Type";
Hans Verkuil977ebec2012-07-03 06:14:37 -0300899
Andrey Smirnovaec330a2013-03-26 22:47:23 -0300900 case V4L2_CID_FM_RX_CLASS: return "FM Radio Receiver Controls";
901 case V4L2_CID_TUNE_DEEMPHASIS: return "De-Emphasis";
902 case V4L2_CID_RDS_RECEPTION: return "RDS Reception";
Antti Palosaari80807fa2014-01-24 23:44:26 -0300903 case V4L2_CID_RF_TUNER_CLASS: return "RF Tuner Controls";
Antti Palosaari41018cb2015-10-10 13:50:58 -0300904 case V4L2_CID_RF_TUNER_RF_GAIN: return "RF Gain";
Antti Palosaari80807fa2014-01-24 23:44:26 -0300905 case V4L2_CID_RF_TUNER_LNA_GAIN_AUTO: return "LNA Gain, Auto";
906 case V4L2_CID_RF_TUNER_LNA_GAIN: return "LNA Gain";
907 case V4L2_CID_RF_TUNER_MIXER_GAIN_AUTO: return "Mixer Gain, Auto";
908 case V4L2_CID_RF_TUNER_MIXER_GAIN: return "Mixer Gain";
909 case V4L2_CID_RF_TUNER_IF_GAIN_AUTO: return "IF Gain, Auto";
910 case V4L2_CID_RF_TUNER_IF_GAIN: return "IF Gain";
Antti Palosaari3ce569f2014-01-31 23:36:13 -0300911 case V4L2_CID_RF_TUNER_BANDWIDTH_AUTO: return "Bandwidth, Auto";
912 case V4L2_CID_RF_TUNER_BANDWIDTH: return "Bandwidth";
Antti Palosaari9aa43572014-02-07 02:46:16 -0300913 case V4L2_CID_RF_TUNER_PLL_LOCK: return "PLL Lock";
Hans Verkuil9570a142014-07-21 10:45:40 -0300914 case V4L2_CID_RDS_RX_PTY: return "RDS Program Type";
915 case V4L2_CID_RDS_RX_PS_NAME: return "RDS PS Name";
916 case V4L2_CID_RDS_RX_RADIO_TEXT: return "RDS Radio Text";
917 case V4L2_CID_RDS_RX_TRAFFIC_ANNOUNCEMENT: return "RDS Traffic Announcement";
918 case V4L2_CID_RDS_RX_TRAFFIC_PROGRAM: return "RDS Traffic Program";
919 case V4L2_CID_RDS_RX_MUSIC_SPEECH: return "RDS Music";
Hans Verkuila77b4fc2014-03-28 13:00:08 -0300920
921 /* Detection controls */
922 /* Keep the order of the 'case's the same as in v4l2-controls.h! */
923 case V4L2_CID_DETECT_CLASS: return "Detection Controls";
924 case V4L2_CID_DETECT_MD_MODE: return "Motion Detection Mode";
925 case V4L2_CID_DETECT_MD_GLOBAL_THRESHOLD: return "MD Global Threshold";
926 case V4L2_CID_DETECT_MD_THRESHOLD_GRID: return "MD Threshold Grid";
927 case V4L2_CID_DETECT_MD_REGION_GRID: return "MD Region Grid";
Hans Verkuil09965172010-08-01 14:32:42 -0300928 default:
929 return NULL;
930 }
931}
932EXPORT_SYMBOL(v4l2_ctrl_get_name);
933
934void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
Hans Verkuil0ba2aeb2014-04-16 09:41:25 -0300935 s64 *min, s64 *max, u64 *step, s64 *def, u32 *flags)
Hans Verkuil09965172010-08-01 14:32:42 -0300936{
937 *name = v4l2_ctrl_get_name(id);
938 *flags = 0;
939
940 switch (id) {
941 case V4L2_CID_AUDIO_MUTE:
942 case V4L2_CID_AUDIO_LOUDNESS:
943 case V4L2_CID_AUTO_WHITE_BALANCE:
944 case V4L2_CID_AUTOGAIN:
945 case V4L2_CID_HFLIP:
946 case V4L2_CID_VFLIP:
947 case V4L2_CID_HUE_AUTO:
948 case V4L2_CID_CHROMA_AGC:
949 case V4L2_CID_COLOR_KILLER:
Hans de Goedea2f8b842012-07-01 11:26:13 -0300950 case V4L2_CID_AUTOBRIGHTNESS:
Hans Verkuil09965172010-08-01 14:32:42 -0300951 case V4L2_CID_MPEG_AUDIO_MUTE:
952 case V4L2_CID_MPEG_VIDEO_MUTE:
953 case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
954 case V4L2_CID_MPEG_VIDEO_PULLDOWN:
955 case V4L2_CID_EXPOSURE_AUTO_PRIORITY:
956 case V4L2_CID_FOCUS_AUTO:
957 case V4L2_CID_PRIVACY:
958 case V4L2_CID_AUDIO_LIMITER_ENABLED:
959 case V4L2_CID_AUDIO_COMPRESSION_ENABLED:
960 case V4L2_CID_PILOT_TONE_ENABLED:
Jean-François Moine008d35f2010-09-13 07:04:49 -0300961 case V4L2_CID_ILLUMINATORS_1:
962 case V4L2_CID_ILLUMINATORS_2:
Sakari Ailus0b159ac2011-03-21 12:52:51 -0300963 case V4L2_CID_FLASH_STROBE_STATUS:
964 case V4L2_CID_FLASH_CHARGE:
965 case V4L2_CID_FLASH_READY:
Kamil Debski064f5092011-06-14 10:46:22 -0300966 case V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER:
967 case V4L2_CID_MPEG_VIDEO_DECODER_SLICE_INTERFACE:
968 case V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE:
969 case V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE:
970 case V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM:
971 case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_ENABLE:
972 case V4L2_CID_MPEG_VIDEO_MPEG4_QPEL:
Hans Verkuil9ca54702013-03-17 10:34:04 -0300973 case V4L2_CID_MPEG_VIDEO_REPEAT_SEQ_HEADER:
Sylwester Nawrocki44d44a12012-03-06 07:05:45 -0300974 case V4L2_CID_WIDE_DYNAMIC_RANGE:
Sylwester Nawrocki82b30562012-05-01 17:38:09 -0300975 case V4L2_CID_IMAGE_STABILIZATION:
Andrey Smirnovaec330a2013-03-26 22:47:23 -0300976 case V4L2_CID_RDS_RECEPTION:
Antti Palosaari80807fa2014-01-24 23:44:26 -0300977 case V4L2_CID_RF_TUNER_LNA_GAIN_AUTO:
978 case V4L2_CID_RF_TUNER_MIXER_GAIN_AUTO:
979 case V4L2_CID_RF_TUNER_IF_GAIN_AUTO:
Antti Palosaari3ce569f2014-01-31 23:36:13 -0300980 case V4L2_CID_RF_TUNER_BANDWIDTH_AUTO:
Antti Palosaari9aa43572014-02-07 02:46:16 -0300981 case V4L2_CID_RF_TUNER_PLL_LOCK:
Hans Verkuil811c5082014-07-21 10:45:37 -0300982 case V4L2_CID_RDS_TX_MONO_STEREO:
983 case V4L2_CID_RDS_TX_ARTIFICIAL_HEAD:
984 case V4L2_CID_RDS_TX_COMPRESSED:
985 case V4L2_CID_RDS_TX_DYNAMIC_PTY:
986 case V4L2_CID_RDS_TX_TRAFFIC_ANNOUNCEMENT:
987 case V4L2_CID_RDS_TX_TRAFFIC_PROGRAM:
988 case V4L2_CID_RDS_TX_MUSIC_SPEECH:
989 case V4L2_CID_RDS_TX_ALT_FREQS_ENABLE:
Hans Verkuil9570a142014-07-21 10:45:40 -0300990 case V4L2_CID_RDS_RX_TRAFFIC_ANNOUNCEMENT:
991 case V4L2_CID_RDS_RX_TRAFFIC_PROGRAM:
992 case V4L2_CID_RDS_RX_MUSIC_SPEECH:
Hans Verkuil09965172010-08-01 14:32:42 -0300993 *type = V4L2_CTRL_TYPE_BOOLEAN;
994 *min = 0;
995 *max = *step = 1;
996 break;
Amit Groverbf0bedd2014-02-04 06:59:58 -0300997 case V4L2_CID_MPEG_VIDEO_MV_H_SEARCH_RANGE:
998 case V4L2_CID_MPEG_VIDEO_MV_V_SEARCH_RANGE:
999 *type = V4L2_CTRL_TYPE_INTEGER;
1000 break;
Hans Verkuil09965172010-08-01 14:32:42 -03001001 case V4L2_CID_PAN_RESET:
1002 case V4L2_CID_TILT_RESET:
Sakari Ailus0b159ac2011-03-21 12:52:51 -03001003 case V4L2_CID_FLASH_STROBE:
1004 case V4L2_CID_FLASH_STROBE_STOP:
Sylwester Nawrocki2272ab62012-05-11 06:37:03 -03001005 case V4L2_CID_AUTO_FOCUS_START:
1006 case V4L2_CID_AUTO_FOCUS_STOP:
Hans Verkuil09965172010-08-01 14:32:42 -03001007 *type = V4L2_CTRL_TYPE_BUTTON;
Ricardo Ribaldaef66c0c2015-03-20 11:21:28 -03001008 *flags |= V4L2_CTRL_FLAG_WRITE_ONLY |
1009 V4L2_CTRL_FLAG_EXECUTE_ON_WRITE;
Hans Verkuil09965172010-08-01 14:32:42 -03001010 *min = *max = *step = *def = 0;
1011 break;
1012 case V4L2_CID_POWER_LINE_FREQUENCY:
1013 case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
1014 case V4L2_CID_MPEG_AUDIO_ENCODING:
1015 case V4L2_CID_MPEG_AUDIO_L1_BITRATE:
1016 case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
1017 case V4L2_CID_MPEG_AUDIO_L3_BITRATE:
1018 case V4L2_CID_MPEG_AUDIO_AC3_BITRATE:
1019 case V4L2_CID_MPEG_AUDIO_MODE:
1020 case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION:
1021 case V4L2_CID_MPEG_AUDIO_EMPHASIS:
1022 case V4L2_CID_MPEG_AUDIO_CRC:
Hans Verkuil24c19a22011-12-15 10:46:16 -03001023 case V4L2_CID_MPEG_AUDIO_DEC_PLAYBACK:
1024 case V4L2_CID_MPEG_AUDIO_DEC_MULTILINGUAL_PLAYBACK:
Hans Verkuil09965172010-08-01 14:32:42 -03001025 case V4L2_CID_MPEG_VIDEO_ENCODING:
1026 case V4L2_CID_MPEG_VIDEO_ASPECT:
1027 case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
1028 case V4L2_CID_MPEG_STREAM_TYPE:
1029 case V4L2_CID_MPEG_STREAM_VBI_FMT:
1030 case V4L2_CID_EXPOSURE_AUTO:
Sylwester Nawrocki2272ab62012-05-11 06:37:03 -03001031 case V4L2_CID_AUTO_FOCUS_RANGE:
Hans Verkuil09965172010-08-01 14:32:42 -03001032 case V4L2_CID_COLORFX:
Sylwester Nawrockie40a0572012-03-06 07:04:26 -03001033 case V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE:
Hans Verkuil09965172010-08-01 14:32:42 -03001034 case V4L2_CID_TUNE_PREEMPHASIS:
Sakari Ailus0b159ac2011-03-21 12:52:51 -03001035 case V4L2_CID_FLASH_LED_MODE:
1036 case V4L2_CID_FLASH_STROBE_SOURCE:
Kamil Debski064f5092011-06-14 10:46:22 -03001037 case V4L2_CID_MPEG_VIDEO_HEADER_MODE:
1038 case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE:
1039 case V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE:
1040 case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
1041 case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE:
1042 case V4L2_CID_MPEG_VIDEO_H264_PROFILE:
1043 case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC:
Arun Kumar K2e81dde2012-10-03 22:19:06 -03001044 case V4L2_CID_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE:
1045 case V4L2_CID_MPEG_VIDEO_H264_FMO_MAP_TYPE:
Kamil Debski064f5092011-06-14 10:46:22 -03001046 case V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL:
1047 case V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE:
Sylwester Nawrockic7361ae2012-01-20 15:37:44 -03001048 case V4L2_CID_JPEG_CHROMA_SUBSAMPLING:
Sylwester Nawrocki7f84ad82012-05-01 17:39:45 -03001049 case V4L2_CID_ISO_SENSITIVITY_AUTO:
Sylwester Nawrockicf072132012-04-30 04:34:10 -03001050 case V4L2_CID_EXPOSURE_METERING:
Sylwester Nawrocki0bf6b7d2012-04-16 10:45:44 -03001051 case V4L2_CID_SCENE_MODE:
Hans Verkuil977ebec2012-07-03 06:14:37 -03001052 case V4L2_CID_DV_TX_MODE:
1053 case V4L2_CID_DV_TX_RGB_RANGE:
Hans Verkuil45cc29a2016-01-27 11:31:39 -02001054 case V4L2_CID_DV_TX_IT_CONTENT_TYPE:
Hans Verkuil977ebec2012-07-03 06:14:37 -03001055 case V4L2_CID_DV_RX_RGB_RANGE:
Hans Verkuil45cc29a2016-01-27 11:31:39 -02001056 case V4L2_CID_DV_RX_IT_CONTENT_TYPE:
Lad, Prabhakar5ebef0f2012-10-01 08:17:36 -03001057 case V4L2_CID_TEST_PATTERN:
Andrey Smirnovaec330a2013-03-26 22:47:23 -03001058 case V4L2_CID_TUNE_DEEMPHASIS:
Arun Kumar Kbc9028e2013-07-09 01:24:41 -03001059 case V4L2_CID_MPEG_VIDEO_VPX_GOLDEN_FRAME_SEL:
Hans Verkuila77b4fc2014-03-28 13:00:08 -03001060 case V4L2_CID_DETECT_MD_MODE:
Hans Verkuil09965172010-08-01 14:32:42 -03001061 *type = V4L2_CTRL_TYPE_MENU;
1062 break;
Sakari Ailusc643ee12012-02-02 20:17:54 -03001063 case V4L2_CID_LINK_FREQ:
1064 *type = V4L2_CTRL_TYPE_INTEGER_MENU;
1065 break;
Hans Verkuil09965172010-08-01 14:32:42 -03001066 case V4L2_CID_RDS_TX_PS_NAME:
1067 case V4L2_CID_RDS_TX_RADIO_TEXT:
Hans Verkuil9570a142014-07-21 10:45:40 -03001068 case V4L2_CID_RDS_RX_PS_NAME:
1069 case V4L2_CID_RDS_RX_RADIO_TEXT:
Hans Verkuil09965172010-08-01 14:32:42 -03001070 *type = V4L2_CTRL_TYPE_STRING;
1071 break;
Sylwester Nawrocki7f84ad82012-05-01 17:39:45 -03001072 case V4L2_CID_ISO_SENSITIVITY:
Sylwester Nawrockid58083c2012-03-06 07:06:55 -03001073 case V4L2_CID_AUTO_EXPOSURE_BIAS:
Arun Kumar Kbc9028e2013-07-09 01:24:41 -03001074 case V4L2_CID_MPEG_VIDEO_VPX_NUM_PARTITIONS:
1075 case V4L2_CID_MPEG_VIDEO_VPX_NUM_REF_FRAMES:
Sylwester Nawrockid58083c2012-03-06 07:06:55 -03001076 *type = V4L2_CTRL_TYPE_INTEGER_MENU;
1077 break;
Hans Verkuil09965172010-08-01 14:32:42 -03001078 case V4L2_CID_USER_CLASS:
1079 case V4L2_CID_CAMERA_CLASS:
1080 case V4L2_CID_MPEG_CLASS:
1081 case V4L2_CID_FM_TX_CLASS:
Sakari Ailus0b159ac2011-03-21 12:52:51 -03001082 case V4L2_CID_FLASH_CLASS:
Sylwester Nawrockic7361ae2012-01-20 15:37:44 -03001083 case V4L2_CID_JPEG_CLASS:
Sakari Ailus8c9d2362011-10-04 08:20:05 -03001084 case V4L2_CID_IMAGE_SOURCE_CLASS:
Sakari Ailusc643ee12012-02-02 20:17:54 -03001085 case V4L2_CID_IMAGE_PROC_CLASS:
Hans Verkuil977ebec2012-07-03 06:14:37 -03001086 case V4L2_CID_DV_CLASS:
Andrey Smirnovaec330a2013-03-26 22:47:23 -03001087 case V4L2_CID_FM_RX_CLASS:
Antti Palosaari80807fa2014-01-24 23:44:26 -03001088 case V4L2_CID_RF_TUNER_CLASS:
Hans Verkuila77b4fc2014-03-28 13:00:08 -03001089 case V4L2_CID_DETECT_CLASS:
Hans Verkuil09965172010-08-01 14:32:42 -03001090 *type = V4L2_CTRL_TYPE_CTRL_CLASS;
1091 /* You can neither read not write these */
1092 *flags |= V4L2_CTRL_FLAG_READ_ONLY | V4L2_CTRL_FLAG_WRITE_ONLY;
1093 *min = *max = *step = *def = 0;
1094 break;
1095 case V4L2_CID_BG_COLOR:
1096 *type = V4L2_CTRL_TYPE_INTEGER;
1097 *step = 1;
1098 *min = 0;
1099 /* Max is calculated as RGB888 that is 2^24 */
1100 *max = 0xFFFFFF;
1101 break;
Sakari Ailus0b159ac2011-03-21 12:52:51 -03001102 case V4L2_CID_FLASH_FAULT:
Sylwester Nawrockic7361ae2012-01-20 15:37:44 -03001103 case V4L2_CID_JPEG_ACTIVE_MARKER:
Sylwester Nawrockifc162a02012-05-02 06:24:33 -03001104 case V4L2_CID_3A_LOCK:
Sylwester Nawrocki2272ab62012-05-11 06:37:03 -03001105 case V4L2_CID_AUTO_FOCUS_STATUS:
Hans Verkuil977ebec2012-07-03 06:14:37 -03001106 case V4L2_CID_DV_TX_HOTPLUG:
1107 case V4L2_CID_DV_TX_RXSENSE:
1108 case V4L2_CID_DV_TX_EDID_PRESENT:
1109 case V4L2_CID_DV_RX_POWER_PRESENT:
Sakari Ailus0b159ac2011-03-21 12:52:51 -03001110 *type = V4L2_CTRL_TYPE_BITMASK;
1111 break;
Kamil Debski064f5092011-06-14 10:46:22 -03001112 case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE:
1113 case V4L2_CID_MIN_BUFFERS_FOR_OUTPUT:
1114 *type = V4L2_CTRL_TYPE_INTEGER;
1115 *flags |= V4L2_CTRL_FLAG_READ_ONLY;
1116 break;
Hans Verkuil24c19a22011-12-15 10:46:16 -03001117 case V4L2_CID_MPEG_VIDEO_DEC_PTS:
Hans Verkuil0ba2aeb2014-04-16 09:41:25 -03001118 *type = V4L2_CTRL_TYPE_INTEGER64;
1119 *flags |= V4L2_CTRL_FLAG_VOLATILE | V4L2_CTRL_FLAG_READ_ONLY;
1120 *min = *def = 0;
1121 *max = 0x1ffffffffLL;
1122 *step = 1;
1123 break;
1124 case V4L2_CID_MPEG_VIDEO_DEC_FRAME:
1125 *type = V4L2_CTRL_TYPE_INTEGER64;
1126 *flags |= V4L2_CTRL_FLAG_VOLATILE | V4L2_CTRL_FLAG_READ_ONLY;
1127 *min = *def = 0;
1128 *max = 0x7fffffffffffffffLL;
1129 *step = 1;
1130 break;
Sakari Ailusc643ee12012-02-02 20:17:54 -03001131 case V4L2_CID_PIXEL_RATE:
Hans Verkuil24c19a22011-12-15 10:46:16 -03001132 *type = V4L2_CTRL_TYPE_INTEGER64;
Sakari Ailusc643ee12012-02-02 20:17:54 -03001133 *flags |= V4L2_CTRL_FLAG_READ_ONLY;
Hans Verkuil24c19a22011-12-15 10:46:16 -03001134 break;
Hans Verkuila77b4fc2014-03-28 13:00:08 -03001135 case V4L2_CID_DETECT_MD_REGION_GRID:
1136 *type = V4L2_CTRL_TYPE_U8;
1137 break;
1138 case V4L2_CID_DETECT_MD_THRESHOLD_GRID:
1139 *type = V4L2_CTRL_TYPE_U16;
1140 break;
Hans Verkuil811c5082014-07-21 10:45:37 -03001141 case V4L2_CID_RDS_TX_ALT_FREQS:
1142 *type = V4L2_CTRL_TYPE_U32;
1143 break;
Hans Verkuil09965172010-08-01 14:32:42 -03001144 default:
1145 *type = V4L2_CTRL_TYPE_INTEGER;
1146 break;
1147 }
1148 switch (id) {
1149 case V4L2_CID_MPEG_AUDIO_ENCODING:
1150 case V4L2_CID_MPEG_AUDIO_MODE:
1151 case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
1152 case V4L2_CID_MPEG_VIDEO_B_FRAMES:
1153 case V4L2_CID_MPEG_STREAM_TYPE:
1154 *flags |= V4L2_CTRL_FLAG_UPDATE;
1155 break;
1156 case V4L2_CID_AUDIO_VOLUME:
1157 case V4L2_CID_AUDIO_BALANCE:
1158 case V4L2_CID_AUDIO_BASS:
1159 case V4L2_CID_AUDIO_TREBLE:
1160 case V4L2_CID_BRIGHTNESS:
1161 case V4L2_CID_CONTRAST:
1162 case V4L2_CID_SATURATION:
1163 case V4L2_CID_HUE:
1164 case V4L2_CID_RED_BALANCE:
1165 case V4L2_CID_BLUE_BALANCE:
1166 case V4L2_CID_GAMMA:
1167 case V4L2_CID_SHARPNESS:
1168 case V4L2_CID_CHROMA_GAIN:
1169 case V4L2_CID_RDS_TX_DEVIATION:
1170 case V4L2_CID_AUDIO_LIMITER_RELEASE_TIME:
1171 case V4L2_CID_AUDIO_LIMITER_DEVIATION:
1172 case V4L2_CID_AUDIO_COMPRESSION_GAIN:
1173 case V4L2_CID_AUDIO_COMPRESSION_THRESHOLD:
1174 case V4L2_CID_AUDIO_COMPRESSION_ATTACK_TIME:
1175 case V4L2_CID_AUDIO_COMPRESSION_RELEASE_TIME:
1176 case V4L2_CID_PILOT_TONE_DEVIATION:
1177 case V4L2_CID_PILOT_TONE_FREQUENCY:
1178 case V4L2_CID_TUNE_POWER_LEVEL:
1179 case V4L2_CID_TUNE_ANTENNA_CAPACITOR:
Antti Palosaari41018cb2015-10-10 13:50:58 -03001180 case V4L2_CID_RF_TUNER_RF_GAIN:
Antti Palosaari80807fa2014-01-24 23:44:26 -03001181 case V4L2_CID_RF_TUNER_LNA_GAIN:
1182 case V4L2_CID_RF_TUNER_MIXER_GAIN:
1183 case V4L2_CID_RF_TUNER_IF_GAIN:
Antti Palosaari3ce569f2014-01-31 23:36:13 -03001184 case V4L2_CID_RF_TUNER_BANDWIDTH:
Hans Verkuila77b4fc2014-03-28 13:00:08 -03001185 case V4L2_CID_DETECT_MD_GLOBAL_THRESHOLD:
Hans Verkuil09965172010-08-01 14:32:42 -03001186 *flags |= V4L2_CTRL_FLAG_SLIDER;
1187 break;
1188 case V4L2_CID_PAN_RELATIVE:
1189 case V4L2_CID_TILT_RELATIVE:
1190 case V4L2_CID_FOCUS_RELATIVE:
1191 case V4L2_CID_IRIS_RELATIVE:
1192 case V4L2_CID_ZOOM_RELATIVE:
Ricardo Ribaldaef66c0c2015-03-20 11:21:28 -03001193 *flags |= V4L2_CTRL_FLAG_WRITE_ONLY |
1194 V4L2_CTRL_FLAG_EXECUTE_ON_WRITE;
Hans Verkuil09965172010-08-01 14:32:42 -03001195 break;
Sakari Ailus0b159ac2011-03-21 12:52:51 -03001196 case V4L2_CID_FLASH_STROBE_STATUS:
Sylwester Nawrocki2272ab62012-05-11 06:37:03 -03001197 case V4L2_CID_AUTO_FOCUS_STATUS:
Sakari Ailus0b159ac2011-03-21 12:52:51 -03001198 case V4L2_CID_FLASH_READY:
Hans Verkuil977ebec2012-07-03 06:14:37 -03001199 case V4L2_CID_DV_TX_HOTPLUG:
1200 case V4L2_CID_DV_TX_RXSENSE:
1201 case V4L2_CID_DV_TX_EDID_PRESENT:
1202 case V4L2_CID_DV_RX_POWER_PRESENT:
Hans Verkuil45cc29a2016-01-27 11:31:39 -02001203 case V4L2_CID_DV_RX_IT_CONTENT_TYPE:
Hans Verkuil9570a142014-07-21 10:45:40 -03001204 case V4L2_CID_RDS_RX_PTY:
1205 case V4L2_CID_RDS_RX_PS_NAME:
1206 case V4L2_CID_RDS_RX_RADIO_TEXT:
1207 case V4L2_CID_RDS_RX_TRAFFIC_ANNOUNCEMENT:
1208 case V4L2_CID_RDS_RX_TRAFFIC_PROGRAM:
1209 case V4L2_CID_RDS_RX_MUSIC_SPEECH:
Sakari Ailus0b159ac2011-03-21 12:52:51 -03001210 *flags |= V4L2_CTRL_FLAG_READ_ONLY;
1211 break;
Antti Palosaari9aa43572014-02-07 02:46:16 -03001212 case V4L2_CID_RF_TUNER_PLL_LOCK:
1213 *flags |= V4L2_CTRL_FLAG_VOLATILE;
1214 break;
Hans Verkuil09965172010-08-01 14:32:42 -03001215 }
1216}
1217EXPORT_SYMBOL(v4l2_ctrl_fill);
1218
Hans Verkuil6e239392011-06-07 11:13:44 -03001219static void fill_event(struct v4l2_event *ev, struct v4l2_ctrl *ctrl, u32 changes)
1220{
1221 memset(ev->reserved, 0, sizeof(ev->reserved));
1222 ev->type = V4L2_EVENT_CTRL;
1223 ev->id = ctrl->id;
1224 ev->u.ctrl.changes = changes;
1225 ev->u.ctrl.type = ctrl->type;
1226 ev->u.ctrl.flags = ctrl->flags;
Hans Verkuild9a25472014-06-12 07:54:16 -03001227 if (ctrl->is_ptr)
Hans Verkuil6e239392011-06-07 11:13:44 -03001228 ev->u.ctrl.value64 = 0;
1229 else
Hans Verkuil2a9ec372014-04-27 03:38:13 -03001230 ev->u.ctrl.value64 = *ctrl->p_cur.p_s64;
Hans Verkuil6e239392011-06-07 11:13:44 -03001231 ev->u.ctrl.minimum = ctrl->minimum;
1232 ev->u.ctrl.maximum = ctrl->maximum;
Sakari Ailusce580fe2011-08-04 13:51:11 -03001233 if (ctrl->type == V4L2_CTRL_TYPE_MENU
1234 || ctrl->type == V4L2_CTRL_TYPE_INTEGER_MENU)
Hans Verkuil6e239392011-06-07 11:13:44 -03001235 ev->u.ctrl.step = 1;
1236 else
1237 ev->u.ctrl.step = ctrl->step;
1238 ev->u.ctrl.default_value = ctrl->default_value;
1239}
1240
1241static void send_event(struct v4l2_fh *fh, struct v4l2_ctrl *ctrl, u32 changes)
1242{
1243 struct v4l2_event ev;
Hans Verkuil77068d32011-06-13 18:55:58 -03001244 struct v4l2_subscribed_event *sev;
Hans Verkuil6e239392011-06-07 11:13:44 -03001245
Hans Verkuil77068d32011-06-13 18:55:58 -03001246 if (list_empty(&ctrl->ev_subs))
Hans Verkuil3f66f0e2011-06-20 11:56:24 -03001247 return;
Hans Verkuil6e239392011-06-07 11:13:44 -03001248 fill_event(&ev, ctrl, changes);
1249
Hans Verkuil77068d32011-06-13 18:55:58 -03001250 list_for_each_entry(sev, &ctrl->ev_subs, node)
Hans de Goedee3e72f392011-10-26 05:52:47 -03001251 if (sev->fh != fh ||
1252 (sev->flags & V4L2_EVENT_SUB_FL_ALLOW_FEEDBACK))
Hans Verkuil77068d32011-06-13 18:55:58 -03001253 v4l2_event_queue_fh(sev->fh, &ev);
Hans Verkuil6e239392011-06-07 11:13:44 -03001254}
1255
Hans Verkuil998e7652014-06-10 07:55:00 -03001256static bool std_equal(const struct v4l2_ctrl *ctrl, u32 idx,
Hans Verkuil01760772014-04-27 03:22:17 -03001257 union v4l2_ctrl_ptr ptr1,
1258 union v4l2_ctrl_ptr ptr2)
1259{
1260 switch (ctrl->type) {
1261 case V4L2_CTRL_TYPE_BUTTON:
1262 return false;
1263 case V4L2_CTRL_TYPE_STRING:
Hans Verkuil265c7f82014-01-05 11:06:05 -03001264 idx *= ctrl->elem_size;
Hans Verkuil01760772014-04-27 03:22:17 -03001265 /* strings are always 0-terminated */
Hans Verkuil265c7f82014-01-05 11:06:05 -03001266 return !strcmp(ptr1.p_char + idx, ptr2.p_char + idx);
Hans Verkuil01760772014-04-27 03:22:17 -03001267 case V4L2_CTRL_TYPE_INTEGER64:
Hans Verkuil265c7f82014-01-05 11:06:05 -03001268 return ptr1.p_s64[idx] == ptr2.p_s64[idx];
Hans Verkuildda4a4d2014-06-10 07:30:04 -03001269 case V4L2_CTRL_TYPE_U8:
1270 return ptr1.p_u8[idx] == ptr2.p_u8[idx];
1271 case V4L2_CTRL_TYPE_U16:
1272 return ptr1.p_u16[idx] == ptr2.p_u16[idx];
Hans Verkuil811c5082014-07-21 10:45:37 -03001273 case V4L2_CTRL_TYPE_U32:
1274 return ptr1.p_u32[idx] == ptr2.p_u32[idx];
Hans Verkuil01760772014-04-27 03:22:17 -03001275 default:
Hans Verkuil265c7f82014-01-05 11:06:05 -03001276 if (ctrl->is_int)
1277 return ptr1.p_s32[idx] == ptr2.p_s32[idx];
1278 idx *= ctrl->elem_size;
1279 return !memcmp(ptr1.p + idx, ptr2.p + idx, ctrl->elem_size);
Hans Verkuil01760772014-04-27 03:22:17 -03001280 }
1281}
1282
Hans Verkuil998e7652014-06-10 07:55:00 -03001283static void std_init(const struct v4l2_ctrl *ctrl, u32 idx,
Hans Verkuil01760772014-04-27 03:22:17 -03001284 union v4l2_ctrl_ptr ptr)
1285{
1286 switch (ctrl->type) {
1287 case V4L2_CTRL_TYPE_STRING:
Hans Verkuil265c7f82014-01-05 11:06:05 -03001288 idx *= ctrl->elem_size;
1289 memset(ptr.p_char + idx, ' ', ctrl->minimum);
1290 ptr.p_char[idx + ctrl->minimum] = '\0';
Hans Verkuil01760772014-04-27 03:22:17 -03001291 break;
1292 case V4L2_CTRL_TYPE_INTEGER64:
Hans Verkuil265c7f82014-01-05 11:06:05 -03001293 ptr.p_s64[idx] = ctrl->default_value;
Hans Verkuil01760772014-04-27 03:22:17 -03001294 break;
1295 case V4L2_CTRL_TYPE_INTEGER:
1296 case V4L2_CTRL_TYPE_INTEGER_MENU:
1297 case V4L2_CTRL_TYPE_MENU:
1298 case V4L2_CTRL_TYPE_BITMASK:
1299 case V4L2_CTRL_TYPE_BOOLEAN:
Hans Verkuil265c7f82014-01-05 11:06:05 -03001300 ptr.p_s32[idx] = ctrl->default_value;
Hans Verkuil01760772014-04-27 03:22:17 -03001301 break;
Hans Verkuildda4a4d2014-06-10 07:30:04 -03001302 case V4L2_CTRL_TYPE_U8:
1303 ptr.p_u8[idx] = ctrl->default_value;
1304 break;
1305 case V4L2_CTRL_TYPE_U16:
1306 ptr.p_u16[idx] = ctrl->default_value;
1307 break;
Hans Verkuil811c5082014-07-21 10:45:37 -03001308 case V4L2_CTRL_TYPE_U32:
1309 ptr.p_u32[idx] = ctrl->default_value;
1310 break;
Hans Verkuil01760772014-04-27 03:22:17 -03001311 default:
Hans Verkuil302ab7c2014-06-10 07:06:50 -03001312 idx *= ctrl->elem_size;
1313 memset(ptr.p + idx, 0, ctrl->elem_size);
Hans Verkuil01760772014-04-27 03:22:17 -03001314 break;
1315 }
1316}
1317
1318static void std_log(const struct v4l2_ctrl *ctrl)
1319{
1320 union v4l2_ctrl_ptr ptr = ctrl->p_cur;
1321
Hans Verkuil998e7652014-06-10 07:55:00 -03001322 if (ctrl->is_array) {
1323 unsigned i;
1324
1325 for (i = 0; i < ctrl->nr_of_dims; i++)
1326 pr_cont("[%u]", ctrl->dims[i]);
1327 pr_cont(" ");
1328 }
1329
Hans Verkuil01760772014-04-27 03:22:17 -03001330 switch (ctrl->type) {
1331 case V4L2_CTRL_TYPE_INTEGER:
1332 pr_cont("%d", *ptr.p_s32);
1333 break;
1334 case V4L2_CTRL_TYPE_BOOLEAN:
1335 pr_cont("%s", *ptr.p_s32 ? "true" : "false");
1336 break;
1337 case V4L2_CTRL_TYPE_MENU:
1338 pr_cont("%s", ctrl->qmenu[*ptr.p_s32]);
1339 break;
1340 case V4L2_CTRL_TYPE_INTEGER_MENU:
1341 pr_cont("%lld", ctrl->qmenu_int[*ptr.p_s32]);
1342 break;
1343 case V4L2_CTRL_TYPE_BITMASK:
1344 pr_cont("0x%08x", *ptr.p_s32);
1345 break;
1346 case V4L2_CTRL_TYPE_INTEGER64:
1347 pr_cont("%lld", *ptr.p_s64);
1348 break;
1349 case V4L2_CTRL_TYPE_STRING:
1350 pr_cont("%s", ptr.p_char);
1351 break;
Hans Verkuildda4a4d2014-06-10 07:30:04 -03001352 case V4L2_CTRL_TYPE_U8:
1353 pr_cont("%u", (unsigned)*ptr.p_u8);
1354 break;
1355 case V4L2_CTRL_TYPE_U16:
1356 pr_cont("%u", (unsigned)*ptr.p_u16);
1357 break;
Hans Verkuil811c5082014-07-21 10:45:37 -03001358 case V4L2_CTRL_TYPE_U32:
1359 pr_cont("%u", (unsigned)*ptr.p_u32);
1360 break;
Hans Verkuil01760772014-04-27 03:22:17 -03001361 default:
1362 pr_cont("unknown type %d", ctrl->type);
1363 break;
1364 }
1365}
1366
Hans Verkuil958c7c72014-07-18 05:15:21 -03001367/*
1368 * Round towards the closest legal value. Be careful when we are
1369 * close to the maximum range of the control type to prevent
1370 * wrap-arounds.
1371 */
Hans Verkuil01760772014-04-27 03:22:17 -03001372#define ROUND_TO_RANGE(val, offset_type, ctrl) \
1373({ \
1374 offset_type offset; \
Hans Verkuil958c7c72014-07-18 05:15:21 -03001375 if ((ctrl)->maximum >= 0 && \
Hans Verkuil9c9cb1f2014-07-26 13:02:59 -03001376 val >= (ctrl)->maximum - (s32)((ctrl)->step / 2)) \
Hans Verkuil958c7c72014-07-18 05:15:21 -03001377 val = (ctrl)->maximum; \
1378 else \
Hans Verkuil9c9cb1f2014-07-26 13:02:59 -03001379 val += (s32)((ctrl)->step / 2); \
Hans Verkuil01760772014-04-27 03:22:17 -03001380 val = clamp_t(typeof(val), val, \
1381 (ctrl)->minimum, (ctrl)->maximum); \
1382 offset = (val) - (ctrl)->minimum; \
Hans Verkuil9c9cb1f2014-07-26 13:02:59 -03001383 offset = (ctrl)->step * (offset / (u32)(ctrl)->step); \
Hans Verkuil01760772014-04-27 03:22:17 -03001384 val = (ctrl)->minimum + offset; \
1385 0; \
1386})
1387
1388/* Validate a new control */
Hans Verkuil998e7652014-06-10 07:55:00 -03001389static int std_validate(const struct v4l2_ctrl *ctrl, u32 idx,
Hans Verkuil01760772014-04-27 03:22:17 -03001390 union v4l2_ctrl_ptr ptr)
1391{
1392 size_t len;
Hans Verkuil0d5e8c42014-07-17 12:31:23 -03001393 u64 offset;
1394 s64 val;
Hans Verkuil01760772014-04-27 03:22:17 -03001395
1396 switch (ctrl->type) {
1397 case V4L2_CTRL_TYPE_INTEGER:
Hans Verkuil265c7f82014-01-05 11:06:05 -03001398 return ROUND_TO_RANGE(ptr.p_s32[idx], u32, ctrl);
Hans Verkuil01760772014-04-27 03:22:17 -03001399 case V4L2_CTRL_TYPE_INTEGER64:
Hans Verkuil0d5e8c42014-07-17 12:31:23 -03001400 /*
1401 * We can't use the ROUND_TO_RANGE define here due to
1402 * the u64 divide that needs special care.
1403 */
1404 val = ptr.p_s64[idx];
Hans Verkuil9c9cb1f2014-07-26 13:02:59 -03001405 if (ctrl->maximum >= 0 && val >= ctrl->maximum - (s64)(ctrl->step / 2))
Hans Verkuil958c7c72014-07-18 05:15:21 -03001406 val = ctrl->maximum;
1407 else
Hans Verkuil9c9cb1f2014-07-26 13:02:59 -03001408 val += (s64)(ctrl->step / 2);
Hans Verkuil0d5e8c42014-07-17 12:31:23 -03001409 val = clamp_t(s64, val, ctrl->minimum, ctrl->maximum);
1410 offset = val - ctrl->minimum;
1411 do_div(offset, ctrl->step);
1412 ptr.p_s64[idx] = ctrl->minimum + offset * ctrl->step;
1413 return 0;
Hans Verkuildda4a4d2014-06-10 07:30:04 -03001414 case V4L2_CTRL_TYPE_U8:
1415 return ROUND_TO_RANGE(ptr.p_u8[idx], u8, ctrl);
1416 case V4L2_CTRL_TYPE_U16:
1417 return ROUND_TO_RANGE(ptr.p_u16[idx], u16, ctrl);
Hans Verkuil811c5082014-07-21 10:45:37 -03001418 case V4L2_CTRL_TYPE_U32:
1419 return ROUND_TO_RANGE(ptr.p_u32[idx], u32, ctrl);
Hans Verkuil01760772014-04-27 03:22:17 -03001420
1421 case V4L2_CTRL_TYPE_BOOLEAN:
Hans Verkuil265c7f82014-01-05 11:06:05 -03001422 ptr.p_s32[idx] = !!ptr.p_s32[idx];
Hans Verkuil01760772014-04-27 03:22:17 -03001423 return 0;
1424
1425 case V4L2_CTRL_TYPE_MENU:
1426 case V4L2_CTRL_TYPE_INTEGER_MENU:
Hans Verkuil265c7f82014-01-05 11:06:05 -03001427 if (ptr.p_s32[idx] < ctrl->minimum || ptr.p_s32[idx] > ctrl->maximum)
Hans Verkuil01760772014-04-27 03:22:17 -03001428 return -ERANGE;
Hans Verkuil265c7f82014-01-05 11:06:05 -03001429 if (ctrl->menu_skip_mask & (1 << ptr.p_s32[idx]))
Hans Verkuil01760772014-04-27 03:22:17 -03001430 return -EINVAL;
1431 if (ctrl->type == V4L2_CTRL_TYPE_MENU &&
Hans Verkuil265c7f82014-01-05 11:06:05 -03001432 ctrl->qmenu[ptr.p_s32[idx]][0] == '\0')
Hans Verkuil01760772014-04-27 03:22:17 -03001433 return -EINVAL;
1434 return 0;
1435
1436 case V4L2_CTRL_TYPE_BITMASK:
Hans Verkuil265c7f82014-01-05 11:06:05 -03001437 ptr.p_s32[idx] &= ctrl->maximum;
Hans Verkuil01760772014-04-27 03:22:17 -03001438 return 0;
1439
1440 case V4L2_CTRL_TYPE_BUTTON:
1441 case V4L2_CTRL_TYPE_CTRL_CLASS:
Hans Verkuil265c7f82014-01-05 11:06:05 -03001442 ptr.p_s32[idx] = 0;
Hans Verkuil01760772014-04-27 03:22:17 -03001443 return 0;
1444
1445 case V4L2_CTRL_TYPE_STRING:
Hans Verkuil265c7f82014-01-05 11:06:05 -03001446 idx *= ctrl->elem_size;
1447 len = strlen(ptr.p_char + idx);
Hans Verkuil01760772014-04-27 03:22:17 -03001448 if (len < ctrl->minimum)
1449 return -ERANGE;
Hans Verkuil0d5e8c42014-07-17 12:31:23 -03001450 if ((len - (u32)ctrl->minimum) % (u32)ctrl->step)
Hans Verkuil01760772014-04-27 03:22:17 -03001451 return -ERANGE;
1452 return 0;
1453
1454 default:
1455 return -EINVAL;
1456 }
1457}
1458
1459static const struct v4l2_ctrl_type_ops std_type_ops = {
1460 .equal = std_equal,
1461 .init = std_init,
1462 .log = std_log,
1463 .validate = std_validate,
1464};
1465
Hans Verkuil000e4f92014-04-27 03:26:30 -03001466/* Helper function: copy the given control value back to the caller */
1467static int ptr_to_user(struct v4l2_ext_control *c,
1468 struct v4l2_ctrl *ctrl,
1469 union v4l2_ctrl_ptr ptr)
Hans Verkuil09965172010-08-01 14:32:42 -03001470{
1471 u32 len;
1472
Hans Verkuild9a25472014-06-12 07:54:16 -03001473 if (ctrl->is_ptr && !ctrl->is_string)
Hans Verkuil40265bb2014-06-10 07:07:38 -03001474 return copy_to_user(c->ptr, ptr.p, c->size) ?
1475 -EFAULT : 0;
Hans Verkuild9a25472014-06-12 07:54:16 -03001476
Hans Verkuil09965172010-08-01 14:32:42 -03001477 switch (ctrl->type) {
1478 case V4L2_CTRL_TYPE_STRING:
Hans Verkuil000e4f92014-04-27 03:26:30 -03001479 len = strlen(ptr.p_char);
Hans Verkuil09965172010-08-01 14:32:42 -03001480 if (c->size < len + 1) {
Hans Verkuilc336f752014-01-18 06:06:01 -03001481 c->size = ctrl->elem_size;
Hans Verkuil09965172010-08-01 14:32:42 -03001482 return -ENOSPC;
1483 }
Hans Verkuil000e4f92014-04-27 03:26:30 -03001484 return copy_to_user(c->string, ptr.p_char, len + 1) ?
Hans Verkuil40265bb2014-06-10 07:07:38 -03001485 -EFAULT : 0;
Hans Verkuil09965172010-08-01 14:32:42 -03001486 case V4L2_CTRL_TYPE_INTEGER64:
Hans Verkuil000e4f92014-04-27 03:26:30 -03001487 c->value64 = *ptr.p_s64;
Hans Verkuil09965172010-08-01 14:32:42 -03001488 break;
1489 default:
Hans Verkuil000e4f92014-04-27 03:26:30 -03001490 c->value = *ptr.p_s32;
1491 break;
1492 }
1493 return 0;
1494}
1495
1496/* Helper function: copy the current control value back to the caller */
1497static int cur_to_user(struct v4l2_ext_control *c,
1498 struct v4l2_ctrl *ctrl)
1499{
1500 return ptr_to_user(c, ctrl, ctrl->p_cur);
1501}
1502
1503/* Helper function: copy the new control value back to the caller */
1504static int new_to_user(struct v4l2_ext_control *c,
1505 struct v4l2_ctrl *ctrl)
1506{
1507 return ptr_to_user(c, ctrl, ctrl->p_new);
1508}
1509
Ricardo Ribalda953eae52015-10-29 08:10:29 -02001510/* Helper function: copy the initial control value back to the caller */
1511static int def_to_user(struct v4l2_ext_control *c, struct v4l2_ctrl *ctrl)
1512{
1513 int idx;
1514
1515 for (idx = 0; idx < ctrl->elems; idx++)
1516 ctrl->type_ops->init(ctrl, idx, ctrl->p_new);
1517
1518 return ptr_to_user(c, ctrl, ctrl->p_new);
1519}
1520
Hans Verkuil000e4f92014-04-27 03:26:30 -03001521/* Helper function: copy the caller-provider value to the given control value */
1522static int user_to_ptr(struct v4l2_ext_control *c,
1523 struct v4l2_ctrl *ctrl,
1524 union v4l2_ctrl_ptr ptr)
1525{
1526 int ret;
1527 u32 size;
1528
1529 ctrl->is_new = 1;
Hans Verkuil302ab7c2014-06-10 07:06:50 -03001530 if (ctrl->is_ptr && !ctrl->is_string) {
1531 unsigned idx;
1532
Hans Verkuil40265bb2014-06-10 07:07:38 -03001533 ret = copy_from_user(ptr.p, c->ptr, c->size) ? -EFAULT : 0;
Hans Verkuil302ab7c2014-06-10 07:06:50 -03001534 if (ret || !ctrl->is_array)
1535 return ret;
1536 for (idx = c->size / ctrl->elem_size; idx < ctrl->elems; idx++)
1537 ctrl->type_ops->init(ctrl, idx, ptr);
1538 return 0;
1539 }
Hans Verkuil000e4f92014-04-27 03:26:30 -03001540
1541 switch (ctrl->type) {
1542 case V4L2_CTRL_TYPE_INTEGER64:
1543 *ptr.p_s64 = c->value64;
1544 break;
1545 case V4L2_CTRL_TYPE_STRING:
1546 size = c->size;
1547 if (size == 0)
1548 return -ERANGE;
1549 if (size > ctrl->maximum + 1)
1550 size = ctrl->maximum + 1;
Hans Verkuil40265bb2014-06-10 07:07:38 -03001551 ret = copy_from_user(ptr.p_char, c->string, size) ? -EFAULT : 0;
Hans Verkuil000e4f92014-04-27 03:26:30 -03001552 if (!ret) {
1553 char last = ptr.p_char[size - 1];
1554
1555 ptr.p_char[size - 1] = 0;
1556 /* If the string was longer than ctrl->maximum,
1557 then return an error. */
1558 if (strlen(ptr.p_char) == ctrl->maximum && last)
1559 return -ERANGE;
1560 }
Hans Verkuil40265bb2014-06-10 07:07:38 -03001561 return ret;
Hans Verkuil000e4f92014-04-27 03:26:30 -03001562 default:
1563 *ptr.p_s32 = c->value;
Hans Verkuil09965172010-08-01 14:32:42 -03001564 break;
1565 }
1566 return 0;
1567}
1568
1569/* Helper function: copy the caller-provider value as the new control value */
1570static int user_to_new(struct v4l2_ext_control *c,
1571 struct v4l2_ctrl *ctrl)
1572{
Hans Verkuil000e4f92014-04-27 03:26:30 -03001573 return user_to_ptr(c, ctrl, ctrl->p_new);
Hans Verkuil09965172010-08-01 14:32:42 -03001574}
1575
Hans Verkuil000e4f92014-04-27 03:26:30 -03001576/* Copy the one value to another. */
1577static void ptr_to_ptr(struct v4l2_ctrl *ctrl,
1578 union v4l2_ctrl_ptr from, union v4l2_ctrl_ptr to)
Hans Verkuil09965172010-08-01 14:32:42 -03001579{
Hans Verkuil000e4f92014-04-27 03:26:30 -03001580 if (ctrl == NULL)
1581 return;
Hans Verkuil302ab7c2014-06-10 07:06:50 -03001582 memcpy(to.p, from.p, ctrl->elems * ctrl->elem_size);
Hans Verkuil09965172010-08-01 14:32:42 -03001583}
1584
1585/* Copy the new value to the current value. */
Sylwester Nawrocki2ccbe772013-01-19 15:51:55 -03001586static void new_to_cur(struct v4l2_fh *fh, struct v4l2_ctrl *ctrl, u32 ch_flags)
Hans Verkuil09965172010-08-01 14:32:42 -03001587{
Hans Verkuil000e4f92014-04-27 03:26:30 -03001588 bool changed;
Hans Verkuil6e239392011-06-07 11:13:44 -03001589
Hans Verkuil09965172010-08-01 14:32:42 -03001590 if (ctrl == NULL)
1591 return;
Hans Verkuil9ea1b7a2014-01-17 08:25:26 -03001592
1593 /* has_changed is set by cluster_changed */
1594 changed = ctrl->has_changed;
1595 if (changed)
1596 ptr_to_ptr(ctrl, ctrl->p_new, ctrl->p_cur);
Hans Verkuild9a25472014-06-12 07:54:16 -03001597
Sylwester Nawrocki2ccbe772013-01-19 15:51:55 -03001598 if (ch_flags & V4L2_EVENT_CTRL_CH_FLAGS) {
1599 /* Note: CH_FLAGS is only set for auto clusters. */
Hans Verkuil5626b8c2011-08-26 07:53:53 -03001600 ctrl->flags &=
1601 ~(V4L2_CTRL_FLAG_INACTIVE | V4L2_CTRL_FLAG_VOLATILE);
1602 if (!is_cur_manual(ctrl->cluster[0])) {
Hans Verkuil72d877c2011-06-10 05:44:36 -03001603 ctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
Hans Verkuil5626b8c2011-08-26 07:53:53 -03001604 if (ctrl->cluster[0]->has_volatiles)
1605 ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
1606 }
Hans de Goede1249a3a2011-10-31 11:16:44 -03001607 fh = NULL;
Hans Verkuil72d877c2011-06-10 05:44:36 -03001608 }
Sylwester Nawrocki2ccbe772013-01-19 15:51:55 -03001609 if (changed || ch_flags) {
Hans Verkuil639884a2011-07-05 07:09:26 -03001610 /* If a control was changed that was not one of the controls
1611 modified by the application, then send the event to all. */
1612 if (!ctrl->is_new)
1613 fh = NULL;
Hans Verkuil6e239392011-06-07 11:13:44 -03001614 send_event(fh, ctrl,
Sylwester Nawrocki2ccbe772013-01-19 15:51:55 -03001615 (changed ? V4L2_EVENT_CTRL_CH_VALUE : 0) | ch_flags);
Hans Verkuil8ac7a942012-09-07 04:46:39 -03001616 if (ctrl->call_notify && changed && ctrl->handler->notify)
1617 ctrl->handler->notify(ctrl, ctrl->handler->notify_priv);
Hans Verkuil639884a2011-07-05 07:09:26 -03001618 }
Hans Verkuil09965172010-08-01 14:32:42 -03001619}
1620
1621/* Copy the current value to the new value */
1622static void cur_to_new(struct v4l2_ctrl *ctrl)
1623{
1624 if (ctrl == NULL)
1625 return;
Hans Verkuil000e4f92014-04-27 03:26:30 -03001626 ptr_to_ptr(ctrl, ctrl->p_cur, ctrl->p_new);
Hans Verkuil09965172010-08-01 14:32:42 -03001627}
1628
1629/* Return non-zero if one or more of the controls in the cluster has a new
1630 value that differs from the current value. */
1631static int cluster_changed(struct v4l2_ctrl *master)
1632{
Hans Verkuil9ea1b7a2014-01-17 08:25:26 -03001633 bool changed = false;
Hans Verkuil302ab7c2014-06-10 07:06:50 -03001634 unsigned idx;
Hans Verkuil09965172010-08-01 14:32:42 -03001635 int i;
1636
Hans Verkuil9ea1b7a2014-01-17 08:25:26 -03001637 for (i = 0; i < master->ncontrols; i++) {
Hans Verkuil09965172010-08-01 14:32:42 -03001638 struct v4l2_ctrl *ctrl = master->cluster[i];
Hans Verkuil302ab7c2014-06-10 07:06:50 -03001639 bool ctrl_changed = false;
Hans Verkuil09965172010-08-01 14:32:42 -03001640
1641 if (ctrl == NULL)
1642 continue;
Ricardo Ribalda45f014c5262015-03-20 10:55:37 -03001643
1644 if (ctrl->flags & V4L2_CTRL_FLAG_EXECUTE_ON_WRITE)
1645 changed = ctrl_changed = true;
1646
Ricardo Ribaldab08d8d22015-03-20 10:30:46 -03001647 /*
1648 * Set has_changed to false to avoid generating
1649 * the event V4L2_EVENT_CTRL_CH_VALUE
1650 */
1651 if (ctrl->flags & V4L2_CTRL_FLAG_VOLATILE) {
1652 ctrl->has_changed = false;
1653 continue;
1654 }
1655
Hans Verkuil302ab7c2014-06-10 07:06:50 -03001656 for (idx = 0; !ctrl_changed && idx < ctrl->elems; idx++)
1657 ctrl_changed = !ctrl->type_ops->equal(ctrl, idx,
Hans Verkuil998e7652014-06-10 07:55:00 -03001658 ctrl->p_cur, ctrl->p_new);
Hans Verkuil302ab7c2014-06-10 07:06:50 -03001659 ctrl->has_changed = ctrl_changed;
Hans Verkuil9ea1b7a2014-01-17 08:25:26 -03001660 changed |= ctrl->has_changed;
Hans Verkuil09965172010-08-01 14:32:42 -03001661 }
Hans Verkuil9ea1b7a2014-01-17 08:25:26 -03001662 return changed;
Hans Verkuil09965172010-08-01 14:32:42 -03001663}
1664
Sylwester Nawrocki2ccbe772013-01-19 15:51:55 -03001665/* Control range checking */
1666static int check_range(enum v4l2_ctrl_type type,
Hans Verkuil0ba2aeb2014-04-16 09:41:25 -03001667 s64 min, s64 max, u64 step, s64 def)
Sylwester Nawrocki2ccbe772013-01-19 15:51:55 -03001668{
1669 switch (type) {
1670 case V4L2_CTRL_TYPE_BOOLEAN:
1671 if (step != 1 || max > 1 || min < 0)
1672 return -ERANGE;
1673 /* fall through */
Hans Verkuildda4a4d2014-06-10 07:30:04 -03001674 case V4L2_CTRL_TYPE_U8:
1675 case V4L2_CTRL_TYPE_U16:
Hans Verkuil811c5082014-07-21 10:45:37 -03001676 case V4L2_CTRL_TYPE_U32:
Sylwester Nawrocki2ccbe772013-01-19 15:51:55 -03001677 case V4L2_CTRL_TYPE_INTEGER:
Hans Verkuil0ba2aeb2014-04-16 09:41:25 -03001678 case V4L2_CTRL_TYPE_INTEGER64:
1679 if (step == 0 || min > max || def < min || def > max)
Sylwester Nawrocki2ccbe772013-01-19 15:51:55 -03001680 return -ERANGE;
1681 return 0;
1682 case V4L2_CTRL_TYPE_BITMASK:
1683 if (step || min || !max || (def & ~max))
1684 return -ERANGE;
1685 return 0;
1686 case V4L2_CTRL_TYPE_MENU:
1687 case V4L2_CTRL_TYPE_INTEGER_MENU:
1688 if (min > max || def < min || def > max)
1689 return -ERANGE;
1690 /* Note: step == menu_skip_mask for menu controls.
1691 So here we check if the default value is masked out. */
1692 if (step && ((1 << def) & step))
1693 return -EINVAL;
1694 return 0;
1695 case V4L2_CTRL_TYPE_STRING:
1696 if (min > max || min < 0 || step < 1 || def)
1697 return -ERANGE;
1698 return 0;
1699 default:
1700 return 0;
1701 }
1702}
1703
Laurent Pinchart03d52852012-07-23 09:15:21 -03001704/* Validate a new control */
Hans Verkuil7a7f1ab2014-09-22 11:08:55 -03001705static int validate_new(const struct v4l2_ctrl *ctrl, union v4l2_ctrl_ptr p_new)
Hans Verkuil09965172010-08-01 14:32:42 -03001706{
Hans Verkuil302ab7c2014-06-10 07:06:50 -03001707 unsigned idx;
1708 int err = 0;
Hans Verkuil09965172010-08-01 14:32:42 -03001709
Hans Verkuil7a7f1ab2014-09-22 11:08:55 -03001710 for (idx = 0; !err && idx < ctrl->elems; idx++)
1711 err = ctrl->type_ops->validate(ctrl, idx, p_new);
Hans Verkuil302ab7c2014-06-10 07:06:50 -03001712 return err;
Hans Verkuil09965172010-08-01 14:32:42 -03001713}
1714
1715static inline u32 node2id(struct list_head *node)
1716{
1717 return list_entry(node, struct v4l2_ctrl_ref, node)->ctrl->id;
1718}
1719
1720/* Set the handler's error code if it wasn't set earlier already */
1721static inline int handler_set_err(struct v4l2_ctrl_handler *hdl, int err)
1722{
1723 if (hdl->error == 0)
1724 hdl->error = err;
1725 return err;
1726}
1727
1728/* Initialize the handler */
Andy Walls6cd247e2013-03-09 05:55:11 -03001729int v4l2_ctrl_handler_init_class(struct v4l2_ctrl_handler *hdl,
1730 unsigned nr_of_controls_hint,
1731 struct lock_class_key *key, const char *name)
Hans Verkuil09965172010-08-01 14:32:42 -03001732{
Sakari Ailus77e7c4e2012-01-24 21:05:34 -03001733 hdl->lock = &hdl->_lock;
1734 mutex_init(hdl->lock);
Andy Walls6cd247e2013-03-09 05:55:11 -03001735 lockdep_set_class_and_name(hdl->lock, key, name);
Hans Verkuil09965172010-08-01 14:32:42 -03001736 INIT_LIST_HEAD(&hdl->ctrls);
1737 INIT_LIST_HEAD(&hdl->ctrl_refs);
1738 hdl->nr_of_buckets = 1 + nr_of_controls_hint / 8;
Thomas Meyer9884d7b2011-11-29 17:08:00 -03001739 hdl->buckets = kcalloc(hdl->nr_of_buckets, sizeof(hdl->buckets[0]),
1740 GFP_KERNEL);
Hans Verkuil09965172010-08-01 14:32:42 -03001741 hdl->error = hdl->buckets ? 0 : -ENOMEM;
1742 return hdl->error;
1743}
Andy Walls6cd247e2013-03-09 05:55:11 -03001744EXPORT_SYMBOL(v4l2_ctrl_handler_init_class);
Hans Verkuil09965172010-08-01 14:32:42 -03001745
1746/* Free all controls and control refs */
1747void v4l2_ctrl_handler_free(struct v4l2_ctrl_handler *hdl)
1748{
1749 struct v4l2_ctrl_ref *ref, *next_ref;
1750 struct v4l2_ctrl *ctrl, *next_ctrl;
Hans Verkuil77068d32011-06-13 18:55:58 -03001751 struct v4l2_subscribed_event *sev, *next_sev;
Hans Verkuil09965172010-08-01 14:32:42 -03001752
1753 if (hdl == NULL || hdl->buckets == NULL)
1754 return;
1755
Sakari Ailus77e7c4e2012-01-24 21:05:34 -03001756 mutex_lock(hdl->lock);
Hans Verkuil09965172010-08-01 14:32:42 -03001757 /* Free all nodes */
1758 list_for_each_entry_safe(ref, next_ref, &hdl->ctrl_refs, node) {
1759 list_del(&ref->node);
1760 kfree(ref);
1761 }
1762 /* Free all controls owned by the handler */
1763 list_for_each_entry_safe(ctrl, next_ctrl, &hdl->ctrls, node) {
1764 list_del(&ctrl->node);
Hans Verkuil77068d32011-06-13 18:55:58 -03001765 list_for_each_entry_safe(sev, next_sev, &ctrl->ev_subs, node)
1766 list_del(&sev->node);
Hans Verkuil09965172010-08-01 14:32:42 -03001767 kfree(ctrl);
1768 }
1769 kfree(hdl->buckets);
1770 hdl->buckets = NULL;
1771 hdl->cached = NULL;
1772 hdl->error = 0;
Sakari Ailus77e7c4e2012-01-24 21:05:34 -03001773 mutex_unlock(hdl->lock);
Hans Verkuil09965172010-08-01 14:32:42 -03001774}
1775EXPORT_SYMBOL(v4l2_ctrl_handler_free);
1776
1777/* For backwards compatibility: V4L2_CID_PRIVATE_BASE should no longer
1778 be used except in G_CTRL, S_CTRL, QUERYCTRL and QUERYMENU when dealing
1779 with applications that do not use the NEXT_CTRL flag.
1780
1781 We just find the n-th private user control. It's O(N), but that should not
1782 be an issue in this particular case. */
1783static struct v4l2_ctrl_ref *find_private_ref(
1784 struct v4l2_ctrl_handler *hdl, u32 id)
1785{
1786 struct v4l2_ctrl_ref *ref;
1787
1788 id -= V4L2_CID_PRIVATE_BASE;
1789 list_for_each_entry(ref, &hdl->ctrl_refs, node) {
1790 /* Search for private user controls that are compatible with
1791 VIDIOC_G/S_CTRL. */
Ricardo Ribalda0f8017b2015-10-29 08:10:28 -02001792 if (V4L2_CTRL_ID2WHICH(ref->ctrl->id) == V4L2_CTRL_CLASS_USER &&
Hans Verkuil09965172010-08-01 14:32:42 -03001793 V4L2_CTRL_DRIVER_PRIV(ref->ctrl->id)) {
Hans Verkuild9a25472014-06-12 07:54:16 -03001794 if (!ref->ctrl->is_int)
Hans Verkuil09965172010-08-01 14:32:42 -03001795 continue;
1796 if (id == 0)
1797 return ref;
1798 id--;
1799 }
1800 }
1801 return NULL;
1802}
1803
1804/* Find a control with the given ID. */
1805static struct v4l2_ctrl_ref *find_ref(struct v4l2_ctrl_handler *hdl, u32 id)
1806{
1807 struct v4l2_ctrl_ref *ref;
1808 int bucket;
1809
1810 id &= V4L2_CTRL_ID_MASK;
1811
1812 /* Old-style private controls need special handling */
1813 if (id >= V4L2_CID_PRIVATE_BASE)
1814 return find_private_ref(hdl, id);
1815 bucket = id % hdl->nr_of_buckets;
1816
1817 /* Simple optimization: cache the last control found */
1818 if (hdl->cached && hdl->cached->ctrl->id == id)
1819 return hdl->cached;
1820
1821 /* Not in cache, search the hash */
1822 ref = hdl->buckets ? hdl->buckets[bucket] : NULL;
1823 while (ref && ref->ctrl->id != id)
1824 ref = ref->next;
1825
1826 if (ref)
1827 hdl->cached = ref; /* cache it! */
1828 return ref;
1829}
1830
1831/* Find a control with the given ID. Take the handler's lock first. */
1832static struct v4l2_ctrl_ref *find_ref_lock(
1833 struct v4l2_ctrl_handler *hdl, u32 id)
1834{
1835 struct v4l2_ctrl_ref *ref = NULL;
1836
1837 if (hdl) {
Sakari Ailus77e7c4e2012-01-24 21:05:34 -03001838 mutex_lock(hdl->lock);
Hans Verkuil09965172010-08-01 14:32:42 -03001839 ref = find_ref(hdl, id);
Sakari Ailus77e7c4e2012-01-24 21:05:34 -03001840 mutex_unlock(hdl->lock);
Hans Verkuil09965172010-08-01 14:32:42 -03001841 }
1842 return ref;
1843}
1844
1845/* Find a control with the given ID. */
1846struct v4l2_ctrl *v4l2_ctrl_find(struct v4l2_ctrl_handler *hdl, u32 id)
1847{
1848 struct v4l2_ctrl_ref *ref = find_ref_lock(hdl, id);
1849
1850 return ref ? ref->ctrl : NULL;
1851}
1852EXPORT_SYMBOL(v4l2_ctrl_find);
1853
1854/* Allocate a new v4l2_ctrl_ref and hook it into the handler. */
1855static int handler_new_ref(struct v4l2_ctrl_handler *hdl,
1856 struct v4l2_ctrl *ctrl)
1857{
1858 struct v4l2_ctrl_ref *ref;
1859 struct v4l2_ctrl_ref *new_ref;
1860 u32 id = ctrl->id;
Ricardo Ribalda0f8017b2015-10-29 08:10:28 -02001861 u32 class_ctrl = V4L2_CTRL_ID2WHICH(id) | 1;
Hans Verkuil09965172010-08-01 14:32:42 -03001862 int bucket = id % hdl->nr_of_buckets; /* which bucket to use */
1863
Hans Verkuild9a25472014-06-12 07:54:16 -03001864 /*
1865 * Automatically add the control class if it is not yet present and
1866 * the new control is not a compound control.
1867 */
1868 if (ctrl->type < V4L2_CTRL_COMPOUND_TYPES &&
1869 id != class_ctrl && find_ref_lock(hdl, class_ctrl) == NULL)
Hans Verkuil09965172010-08-01 14:32:42 -03001870 if (!v4l2_ctrl_new_std(hdl, NULL, class_ctrl, 0, 0, 0, 0))
1871 return hdl->error;
1872
1873 if (hdl->error)
1874 return hdl->error;
1875
1876 new_ref = kzalloc(sizeof(*new_ref), GFP_KERNEL);
1877 if (!new_ref)
1878 return handler_set_err(hdl, -ENOMEM);
1879 new_ref->ctrl = ctrl;
1880 if (ctrl->handler == hdl) {
1881 /* By default each control starts in a cluster of its own.
1882 new_ref->ctrl is basically a cluster array with one
1883 element, so that's perfect to use as the cluster pointer.
1884 But only do this for the handler that owns the control. */
1885 ctrl->cluster = &new_ref->ctrl;
1886 ctrl->ncontrols = 1;
1887 }
1888
1889 INIT_LIST_HEAD(&new_ref->node);
1890
Sakari Ailus77e7c4e2012-01-24 21:05:34 -03001891 mutex_lock(hdl->lock);
Hans Verkuil09965172010-08-01 14:32:42 -03001892
1893 /* Add immediately at the end of the list if the list is empty, or if
1894 the last element in the list has a lower ID.
1895 This ensures that when elements are added in ascending order the
1896 insertion is an O(1) operation. */
1897 if (list_empty(&hdl->ctrl_refs) || id > node2id(hdl->ctrl_refs.prev)) {
1898 list_add_tail(&new_ref->node, &hdl->ctrl_refs);
1899 goto insert_in_hash;
1900 }
1901
1902 /* Find insert position in sorted list */
1903 list_for_each_entry(ref, &hdl->ctrl_refs, node) {
1904 if (ref->ctrl->id < id)
1905 continue;
1906 /* Don't add duplicates */
1907 if (ref->ctrl->id == id) {
1908 kfree(new_ref);
1909 goto unlock;
1910 }
1911 list_add(&new_ref->node, ref->node.prev);
1912 break;
1913 }
1914
1915insert_in_hash:
1916 /* Insert the control node in the hash */
1917 new_ref->next = hdl->buckets[bucket];
1918 hdl->buckets[bucket] = new_ref;
1919
1920unlock:
Sakari Ailus77e7c4e2012-01-24 21:05:34 -03001921 mutex_unlock(hdl->lock);
Hans Verkuil09965172010-08-01 14:32:42 -03001922 return 0;
1923}
1924
1925/* Add a new control */
1926static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl,
1927 const struct v4l2_ctrl_ops *ops,
Hans Verkuil01760772014-04-27 03:22:17 -03001928 const struct v4l2_ctrl_type_ops *type_ops,
Hans Verkuil09965172010-08-01 14:32:42 -03001929 u32 id, const char *name, enum v4l2_ctrl_type type,
Hans Verkuil0ba2aeb2014-04-16 09:41:25 -03001930 s64 min, s64 max, u64 step, s64 def,
Hans Verkuil20d88ee2014-06-12 07:55:21 -03001931 const u32 dims[V4L2_CTRL_MAX_DIMS], u32 elem_size,
Sakari Ailusce580fe2011-08-04 13:51:11 -03001932 u32 flags, const char * const *qmenu,
1933 const s64 *qmenu_int, void *priv)
Hans Verkuil09965172010-08-01 14:32:42 -03001934{
1935 struct v4l2_ctrl *ctrl;
Hans Verkuild9a25472014-06-12 07:54:16 -03001936 unsigned sz_extra;
Hans Verkuil20d88ee2014-06-12 07:55:21 -03001937 unsigned nr_of_dims = 0;
1938 unsigned elems = 1;
Hans Verkuil998e7652014-06-10 07:55:00 -03001939 bool is_array;
1940 unsigned tot_ctrl_size;
Hans Verkuil302ab7c2014-06-10 07:06:50 -03001941 unsigned idx;
Hans Verkuild9a25472014-06-12 07:54:16 -03001942 void *data;
Sylwester Nawrocki2ccbe772013-01-19 15:51:55 -03001943 int err;
Hans Verkuil09965172010-08-01 14:32:42 -03001944
1945 if (hdl->error)
1946 return NULL;
1947
Hans Verkuil20d88ee2014-06-12 07:55:21 -03001948 while (dims && dims[nr_of_dims]) {
1949 elems *= dims[nr_of_dims];
1950 nr_of_dims++;
1951 if (nr_of_dims == V4L2_CTRL_MAX_DIMS)
1952 break;
1953 }
Hans Verkuil998e7652014-06-10 07:55:00 -03001954 is_array = nr_of_dims > 0;
Hans Verkuil20d88ee2014-06-12 07:55:21 -03001955
Hans Verkuildda4a4d2014-06-10 07:30:04 -03001956 /* Prefill elem_size for all types handled by std_type_ops */
1957 switch (type) {
1958 case V4L2_CTRL_TYPE_INTEGER64:
Hans Verkuild9a25472014-06-12 07:54:16 -03001959 elem_size = sizeof(s64);
Hans Verkuildda4a4d2014-06-10 07:30:04 -03001960 break;
1961 case V4L2_CTRL_TYPE_STRING:
Hans Verkuild9a25472014-06-12 07:54:16 -03001962 elem_size = max + 1;
Hans Verkuildda4a4d2014-06-10 07:30:04 -03001963 break;
1964 case V4L2_CTRL_TYPE_U8:
1965 elem_size = sizeof(u8);
1966 break;
1967 case V4L2_CTRL_TYPE_U16:
1968 elem_size = sizeof(u16);
1969 break;
Hans Verkuil811c5082014-07-21 10:45:37 -03001970 case V4L2_CTRL_TYPE_U32:
1971 elem_size = sizeof(u32);
1972 break;
Hans Verkuildda4a4d2014-06-10 07:30:04 -03001973 default:
1974 if (type < V4L2_CTRL_COMPOUND_TYPES)
1975 elem_size = sizeof(s32);
1976 break;
1977 }
Hans Verkuil998e7652014-06-10 07:55:00 -03001978 tot_ctrl_size = elem_size * elems;
Hans Verkuild9a25472014-06-12 07:54:16 -03001979
Hans Verkuil09965172010-08-01 14:32:42 -03001980 /* Sanity checks */
Hans Verkuil998e7652014-06-10 07:55:00 -03001981 if (id == 0 || name == NULL || !elem_size ||
1982 id >= V4L2_CID_PRIVATE_BASE ||
Hans Verkuil09965172010-08-01 14:32:42 -03001983 (type == V4L2_CTRL_TYPE_MENU && qmenu == NULL) ||
Sylwester Nawrocki2ccbe772013-01-19 15:51:55 -03001984 (type == V4L2_CTRL_TYPE_INTEGER_MENU && qmenu_int == NULL)) {
Hans Verkuil09965172010-08-01 14:32:42 -03001985 handler_set_err(hdl, -ERANGE);
1986 return NULL;
1987 }
Sylwester Nawrocki2ccbe772013-01-19 15:51:55 -03001988 err = check_range(type, min, max, step, def);
1989 if (err) {
1990 handler_set_err(hdl, err);
Hans Verkuil02ac0482010-12-29 14:27:05 -03001991 return NULL;
1992 }
Hans Verkuilfa4d7092011-05-23 04:07:05 -03001993 if (type == V4L2_CTRL_TYPE_BITMASK && ((def & ~max) || min || step)) {
1994 handler_set_err(hdl, -ERANGE);
1995 return NULL;
1996 }
Hans Verkuil998e7652014-06-10 07:55:00 -03001997 if (is_array &&
1998 (type == V4L2_CTRL_TYPE_BUTTON ||
1999 type == V4L2_CTRL_TYPE_CTRL_CLASS)) {
2000 handler_set_err(hdl, -EINVAL);
2001 return NULL;
2002 }
Hans Verkuil09965172010-08-01 14:32:42 -03002003
Hans Verkuild9a25472014-06-12 07:54:16 -03002004 sz_extra = 0;
Hans Verkuil09965172010-08-01 14:32:42 -03002005 if (type == V4L2_CTRL_TYPE_BUTTON)
Ricardo Ribaldaef66c0c2015-03-20 11:21:28 -03002006 flags |= V4L2_CTRL_FLAG_WRITE_ONLY |
2007 V4L2_CTRL_FLAG_EXECUTE_ON_WRITE;
Hans Verkuil09965172010-08-01 14:32:42 -03002008 else if (type == V4L2_CTRL_TYPE_CTRL_CLASS)
2009 flags |= V4L2_CTRL_FLAG_READ_ONLY;
Hans Verkuil2a9ec372014-04-27 03:38:13 -03002010 else if (type == V4L2_CTRL_TYPE_INTEGER64 ||
2011 type == V4L2_CTRL_TYPE_STRING ||
Hans Verkuil998e7652014-06-10 07:55:00 -03002012 type >= V4L2_CTRL_COMPOUND_TYPES ||
2013 is_array)
2014 sz_extra += 2 * tot_ctrl_size;
Hans Verkuil09965172010-08-01 14:32:42 -03002015
2016 ctrl = kzalloc(sizeof(*ctrl) + sz_extra, GFP_KERNEL);
2017 if (ctrl == NULL) {
2018 handler_set_err(hdl, -ENOMEM);
2019 return NULL;
2020 }
2021
2022 INIT_LIST_HEAD(&ctrl->node);
Hans Verkuil77068d32011-06-13 18:55:58 -03002023 INIT_LIST_HEAD(&ctrl->ev_subs);
Hans Verkuil09965172010-08-01 14:32:42 -03002024 ctrl->handler = hdl;
2025 ctrl->ops = ops;
Hans Verkuil01760772014-04-27 03:22:17 -03002026 ctrl->type_ops = type_ops ? type_ops : &std_type_ops;
Hans Verkuil09965172010-08-01 14:32:42 -03002027 ctrl->id = id;
2028 ctrl->name = name;
2029 ctrl->type = type;
2030 ctrl->flags = flags;
2031 ctrl->minimum = min;
2032 ctrl->maximum = max;
2033 ctrl->step = step;
Hans Verkuild9a25472014-06-12 07:54:16 -03002034 ctrl->default_value = def;
Hans Verkuil998e7652014-06-10 07:55:00 -03002035 ctrl->is_string = !is_array && type == V4L2_CTRL_TYPE_STRING;
2036 ctrl->is_ptr = is_array || type >= V4L2_CTRL_COMPOUND_TYPES || ctrl->is_string;
Hans Verkuild9a25472014-06-12 07:54:16 -03002037 ctrl->is_int = !ctrl->is_ptr && type != V4L2_CTRL_TYPE_INTEGER64;
Hans Verkuil998e7652014-06-10 07:55:00 -03002038 ctrl->is_array = is_array;
Hans Verkuil20d88ee2014-06-12 07:55:21 -03002039 ctrl->elems = elems;
2040 ctrl->nr_of_dims = nr_of_dims;
2041 if (nr_of_dims)
2042 memcpy(ctrl->dims, dims, nr_of_dims * sizeof(dims[0]));
Hans Verkuild9a25472014-06-12 07:54:16 -03002043 ctrl->elem_size = elem_size;
Sakari Ailusce580fe2011-08-04 13:51:11 -03002044 if (type == V4L2_CTRL_TYPE_MENU)
2045 ctrl->qmenu = qmenu;
2046 else if (type == V4L2_CTRL_TYPE_INTEGER_MENU)
2047 ctrl->qmenu_int = qmenu_int;
Hans Verkuil09965172010-08-01 14:32:42 -03002048 ctrl->priv = priv;
Hans Verkuild9a25472014-06-12 07:54:16 -03002049 ctrl->cur.val = ctrl->val = def;
Hans Verkuil2a9ec372014-04-27 03:38:13 -03002050 data = &ctrl[1];
Hans Verkuil09965172010-08-01 14:32:42 -03002051
Hans Verkuil2a9ec372014-04-27 03:38:13 -03002052 if (!ctrl->is_int) {
2053 ctrl->p_new.p = data;
Hans Verkuil998e7652014-06-10 07:55:00 -03002054 ctrl->p_cur.p = data + tot_ctrl_size;
Hans Verkuil01760772014-04-27 03:22:17 -03002055 } else {
2056 ctrl->p_new.p = &ctrl->val;
2057 ctrl->p_cur.p = &ctrl->cur.val;
Hans Verkuil09965172010-08-01 14:32:42 -03002058 }
Hans Verkuil302ab7c2014-06-10 07:06:50 -03002059 for (idx = 0; idx < elems; idx++) {
2060 ctrl->type_ops->init(ctrl, idx, ctrl->p_cur);
2061 ctrl->type_ops->init(ctrl, idx, ctrl->p_new);
2062 }
Hans Verkuil01760772014-04-27 03:22:17 -03002063
Hans Verkuil09965172010-08-01 14:32:42 -03002064 if (handler_new_ref(hdl, ctrl)) {
2065 kfree(ctrl);
2066 return NULL;
2067 }
Sakari Ailus77e7c4e2012-01-24 21:05:34 -03002068 mutex_lock(hdl->lock);
Hans Verkuil09965172010-08-01 14:32:42 -03002069 list_add_tail(&ctrl->node, &hdl->ctrls);
Sakari Ailus77e7c4e2012-01-24 21:05:34 -03002070 mutex_unlock(hdl->lock);
Hans Verkuil09965172010-08-01 14:32:42 -03002071 return ctrl;
2072}
2073
2074struct v4l2_ctrl *v4l2_ctrl_new_custom(struct v4l2_ctrl_handler *hdl,
2075 const struct v4l2_ctrl_config *cfg, void *priv)
2076{
2077 bool is_menu;
2078 struct v4l2_ctrl *ctrl;
2079 const char *name = cfg->name;
Hans Verkuil513521e2010-12-29 14:25:52 -03002080 const char * const *qmenu = cfg->qmenu;
Sakari Ailusce580fe2011-08-04 13:51:11 -03002081 const s64 *qmenu_int = cfg->qmenu_int;
Hans Verkuil09965172010-08-01 14:32:42 -03002082 enum v4l2_ctrl_type type = cfg->type;
2083 u32 flags = cfg->flags;
Hans Verkuil0ba2aeb2014-04-16 09:41:25 -03002084 s64 min = cfg->min;
2085 s64 max = cfg->max;
2086 u64 step = cfg->step;
2087 s64 def = cfg->def;
Hans Verkuil09965172010-08-01 14:32:42 -03002088
2089 if (name == NULL)
2090 v4l2_ctrl_fill(cfg->id, &name, &type, &min, &max, &step,
2091 &def, &flags);
2092
Sakari Ailusce580fe2011-08-04 13:51:11 -03002093 is_menu = (cfg->type == V4L2_CTRL_TYPE_MENU ||
2094 cfg->type == V4L2_CTRL_TYPE_INTEGER_MENU);
Hans Verkuil09965172010-08-01 14:32:42 -03002095 if (is_menu)
2096 WARN_ON(step);
2097 else
2098 WARN_ON(cfg->menu_skip_mask);
Sakari Ailusce580fe2011-08-04 13:51:11 -03002099 if (cfg->type == V4L2_CTRL_TYPE_MENU && qmenu == NULL)
Hans Verkuil09965172010-08-01 14:32:42 -03002100 qmenu = v4l2_ctrl_get_menu(cfg->id);
Sakari Ailusce580fe2011-08-04 13:51:11 -03002101 else if (cfg->type == V4L2_CTRL_TYPE_INTEGER_MENU &&
2102 qmenu_int == NULL) {
2103 handler_set_err(hdl, -EINVAL);
2104 return NULL;
2105 }
Hans Verkuil09965172010-08-01 14:32:42 -03002106
Hans Verkuil01760772014-04-27 03:22:17 -03002107 ctrl = v4l2_ctrl_new(hdl, cfg->ops, cfg->type_ops, cfg->id, name,
Hans Verkuil09965172010-08-01 14:32:42 -03002108 type, min, max,
Hans Verkuil20d88ee2014-06-12 07:55:21 -03002109 is_menu ? cfg->menu_skip_mask : step, def,
2110 cfg->dims, cfg->elem_size,
Hans Verkuild9a25472014-06-12 07:54:16 -03002111 flags, qmenu, qmenu_int, priv);
Hans Verkuil88365102011-08-26 07:35:14 -03002112 if (ctrl)
Hans Verkuil09965172010-08-01 14:32:42 -03002113 ctrl->is_private = cfg->is_private;
Hans Verkuil09965172010-08-01 14:32:42 -03002114 return ctrl;
2115}
2116EXPORT_SYMBOL(v4l2_ctrl_new_custom);
2117
2118/* Helper function for standard non-menu controls */
2119struct v4l2_ctrl *v4l2_ctrl_new_std(struct v4l2_ctrl_handler *hdl,
2120 const struct v4l2_ctrl_ops *ops,
Hans Verkuil0ba2aeb2014-04-16 09:41:25 -03002121 u32 id, s64 min, s64 max, u64 step, s64 def)
Hans Verkuil09965172010-08-01 14:32:42 -03002122{
2123 const char *name;
2124 enum v4l2_ctrl_type type;
2125 u32 flags;
2126
2127 v4l2_ctrl_fill(id, &name, &type, &min, &max, &step, &def, &flags);
Hans Verkuild9a25472014-06-12 07:54:16 -03002128 if (type == V4L2_CTRL_TYPE_MENU ||
2129 type == V4L2_CTRL_TYPE_INTEGER_MENU ||
2130 type >= V4L2_CTRL_COMPOUND_TYPES) {
Hans Verkuil09965172010-08-01 14:32:42 -03002131 handler_set_err(hdl, -EINVAL);
2132 return NULL;
2133 }
Hans Verkuil01760772014-04-27 03:22:17 -03002134 return v4l2_ctrl_new(hdl, ops, NULL, id, name, type,
Hans Verkuil20d88ee2014-06-12 07:55:21 -03002135 min, max, step, def, NULL, 0,
Hans Verkuild9a25472014-06-12 07:54:16 -03002136 flags, NULL, NULL, NULL);
Hans Verkuil09965172010-08-01 14:32:42 -03002137}
2138EXPORT_SYMBOL(v4l2_ctrl_new_std);
2139
2140/* Helper function for standard menu controls */
2141struct v4l2_ctrl *v4l2_ctrl_new_std_menu(struct v4l2_ctrl_handler *hdl,
2142 const struct v4l2_ctrl_ops *ops,
Hans Verkuil0ba2aeb2014-04-16 09:41:25 -03002143 u32 id, u8 _max, u64 mask, u8 _def)
Hans Verkuil09965172010-08-01 14:32:42 -03002144{
Sylwester Nawrockid1e9b7c2013-07-09 01:24:40 -03002145 const char * const *qmenu = NULL;
2146 const s64 *qmenu_int = NULL;
Sylwester Nawrockifbbb29a2013-08-18 16:05:19 -03002147 unsigned int qmenu_int_len = 0;
Hans Verkuil09965172010-08-01 14:32:42 -03002148 const char *name;
2149 enum v4l2_ctrl_type type;
Hans Verkuil0ba2aeb2014-04-16 09:41:25 -03002150 s64 min;
2151 s64 max = _max;
2152 s64 def = _def;
2153 u64 step;
Hans Verkuil09965172010-08-01 14:32:42 -03002154 u32 flags;
2155
2156 v4l2_ctrl_fill(id, &name, &type, &min, &max, &step, &def, &flags);
Sylwester Nawrockid1e9b7c2013-07-09 01:24:40 -03002157
2158 if (type == V4L2_CTRL_TYPE_MENU)
2159 qmenu = v4l2_ctrl_get_menu(id);
2160 else if (type == V4L2_CTRL_TYPE_INTEGER_MENU)
2161 qmenu_int = v4l2_ctrl_get_int_menu(id, &qmenu_int_len);
2162
2163 if ((!qmenu && !qmenu_int) || (qmenu_int && max > qmenu_int_len)) {
Hans Verkuil09965172010-08-01 14:32:42 -03002164 handler_set_err(hdl, -EINVAL);
2165 return NULL;
2166 }
Hans Verkuil01760772014-04-27 03:22:17 -03002167 return v4l2_ctrl_new(hdl, ops, NULL, id, name, type,
Hans Verkuil20d88ee2014-06-12 07:55:21 -03002168 0, max, mask, def, NULL, 0,
Hans Verkuild9a25472014-06-12 07:54:16 -03002169 flags, qmenu, qmenu_int, NULL);
Hans Verkuil09965172010-08-01 14:32:42 -03002170}
2171EXPORT_SYMBOL(v4l2_ctrl_new_std_menu);
2172
Lad, Prabhakar117a7112012-09-18 15:54:38 -03002173/* Helper function for standard menu controls with driver defined menu */
2174struct v4l2_ctrl *v4l2_ctrl_new_std_menu_items(struct v4l2_ctrl_handler *hdl,
Hans Verkuil0ba2aeb2014-04-16 09:41:25 -03002175 const struct v4l2_ctrl_ops *ops, u32 id, u8 _max,
2176 u64 mask, u8 _def, const char * const *qmenu)
Lad, Prabhakar117a7112012-09-18 15:54:38 -03002177{
2178 enum v4l2_ctrl_type type;
2179 const char *name;
2180 u32 flags;
Hans Verkuil0ba2aeb2014-04-16 09:41:25 -03002181 u64 step;
2182 s64 min;
2183 s64 max = _max;
2184 s64 def = _def;
Lad, Prabhakar117a7112012-09-18 15:54:38 -03002185
2186 /* v4l2_ctrl_new_std_menu_items() should only be called for
2187 * standard controls without a standard menu.
2188 */
2189 if (v4l2_ctrl_get_menu(id)) {
2190 handler_set_err(hdl, -EINVAL);
2191 return NULL;
2192 }
2193
2194 v4l2_ctrl_fill(id, &name, &type, &min, &max, &step, &def, &flags);
2195 if (type != V4L2_CTRL_TYPE_MENU || qmenu == NULL) {
2196 handler_set_err(hdl, -EINVAL);
2197 return NULL;
2198 }
Hans Verkuil01760772014-04-27 03:22:17 -03002199 return v4l2_ctrl_new(hdl, ops, NULL, id, name, type,
Hans Verkuil20d88ee2014-06-12 07:55:21 -03002200 0, max, mask, def, NULL, 0,
2201 flags, qmenu, NULL, NULL);
Lad, Prabhakar117a7112012-09-18 15:54:38 -03002202
2203}
2204EXPORT_SYMBOL(v4l2_ctrl_new_std_menu_items);
2205
Sylwester Nawrocki515f3282012-05-06 15:30:44 -03002206/* Helper function for standard integer menu controls */
2207struct v4l2_ctrl *v4l2_ctrl_new_int_menu(struct v4l2_ctrl_handler *hdl,
2208 const struct v4l2_ctrl_ops *ops,
Hans Verkuil0ba2aeb2014-04-16 09:41:25 -03002209 u32 id, u8 _max, u8 _def, const s64 *qmenu_int)
Sylwester Nawrocki515f3282012-05-06 15:30:44 -03002210{
2211 const char *name;
2212 enum v4l2_ctrl_type type;
Hans Verkuil0ba2aeb2014-04-16 09:41:25 -03002213 s64 min;
2214 u64 step;
2215 s64 max = _max;
2216 s64 def = _def;
Sylwester Nawrocki515f3282012-05-06 15:30:44 -03002217 u32 flags;
2218
2219 v4l2_ctrl_fill(id, &name, &type, &min, &max, &step, &def, &flags);
2220 if (type != V4L2_CTRL_TYPE_INTEGER_MENU) {
2221 handler_set_err(hdl, -EINVAL);
2222 return NULL;
2223 }
Hans Verkuil01760772014-04-27 03:22:17 -03002224 return v4l2_ctrl_new(hdl, ops, NULL, id, name, type,
Hans Verkuil20d88ee2014-06-12 07:55:21 -03002225 0, max, 0, def, NULL, 0,
Hans Verkuild9a25472014-06-12 07:54:16 -03002226 flags, NULL, qmenu_int, NULL);
Sylwester Nawrocki515f3282012-05-06 15:30:44 -03002227}
2228EXPORT_SYMBOL(v4l2_ctrl_new_int_menu);
2229
Hans Verkuil09965172010-08-01 14:32:42 -03002230/* Add a control from another handler to this handler */
2231struct v4l2_ctrl *v4l2_ctrl_add_ctrl(struct v4l2_ctrl_handler *hdl,
2232 struct v4l2_ctrl *ctrl)
2233{
2234 if (hdl == NULL || hdl->error)
2235 return NULL;
2236 if (ctrl == NULL) {
2237 handler_set_err(hdl, -EINVAL);
2238 return NULL;
2239 }
2240 if (ctrl->handler == hdl)
2241 return ctrl;
2242 return handler_new_ref(hdl, ctrl) ? NULL : ctrl;
2243}
2244EXPORT_SYMBOL(v4l2_ctrl_add_ctrl);
2245
2246/* Add the controls from another handler to our own. */
2247int v4l2_ctrl_add_handler(struct v4l2_ctrl_handler *hdl,
Hans Verkuil34a6b7d2012-09-14 07:15:03 -03002248 struct v4l2_ctrl_handler *add,
2249 bool (*filter)(const struct v4l2_ctrl *ctrl))
Hans Verkuil09965172010-08-01 14:32:42 -03002250{
Hans Verkuil072e6602012-03-02 12:41:25 -03002251 struct v4l2_ctrl_ref *ref;
Hans Verkuil09965172010-08-01 14:32:42 -03002252 int ret = 0;
2253
2254 /* Do nothing if either handler is NULL or if they are the same */
2255 if (!hdl || !add || hdl == add)
2256 return 0;
2257 if (hdl->error)
2258 return hdl->error;
Sakari Ailus77e7c4e2012-01-24 21:05:34 -03002259 mutex_lock(add->lock);
Hans Verkuil072e6602012-03-02 12:41:25 -03002260 list_for_each_entry(ref, &add->ctrl_refs, node) {
2261 struct v4l2_ctrl *ctrl = ref->ctrl;
2262
Hans Verkuil09965172010-08-01 14:32:42 -03002263 /* Skip handler-private controls. */
2264 if (ctrl->is_private)
2265 continue;
Hans Verkuil6e239392011-06-07 11:13:44 -03002266 /* And control classes */
2267 if (ctrl->type == V4L2_CTRL_TYPE_CTRL_CLASS)
2268 continue;
Hans Verkuil34a6b7d2012-09-14 07:15:03 -03002269 /* Filter any unwanted controls */
2270 if (filter && !filter(ctrl))
2271 continue;
Hans Verkuil09965172010-08-01 14:32:42 -03002272 ret = handler_new_ref(hdl, ctrl);
2273 if (ret)
2274 break;
2275 }
Sakari Ailus77e7c4e2012-01-24 21:05:34 -03002276 mutex_unlock(add->lock);
Hans Verkuil09965172010-08-01 14:32:42 -03002277 return ret;
2278}
2279EXPORT_SYMBOL(v4l2_ctrl_add_handler);
2280
Hans Verkuil34a6b7d2012-09-14 07:15:03 -03002281bool v4l2_ctrl_radio_filter(const struct v4l2_ctrl *ctrl)
2282{
Ricardo Ribalda0f8017b2015-10-29 08:10:28 -02002283 if (V4L2_CTRL_ID2WHICH(ctrl->id) == V4L2_CTRL_CLASS_FM_TX)
Hans Verkuil34a6b7d2012-09-14 07:15:03 -03002284 return true;
Ricardo Ribalda0f8017b2015-10-29 08:10:28 -02002285 if (V4L2_CTRL_ID2WHICH(ctrl->id) == V4L2_CTRL_CLASS_FM_RX)
Hans Verkuil3963d4f2013-06-02 07:55:59 -03002286 return true;
Hans Verkuil34a6b7d2012-09-14 07:15:03 -03002287 switch (ctrl->id) {
2288 case V4L2_CID_AUDIO_MUTE:
2289 case V4L2_CID_AUDIO_VOLUME:
2290 case V4L2_CID_AUDIO_BALANCE:
2291 case V4L2_CID_AUDIO_BASS:
2292 case V4L2_CID_AUDIO_TREBLE:
2293 case V4L2_CID_AUDIO_LOUDNESS:
2294 return true;
2295 default:
2296 break;
2297 }
2298 return false;
2299}
2300EXPORT_SYMBOL(v4l2_ctrl_radio_filter);
2301
Hans Verkuil09965172010-08-01 14:32:42 -03002302/* Cluster controls */
2303void v4l2_ctrl_cluster(unsigned ncontrols, struct v4l2_ctrl **controls)
2304{
Hans Verkuil5626b8c2011-08-26 07:53:53 -03002305 bool has_volatiles = false;
Hans Verkuil09965172010-08-01 14:32:42 -03002306 int i;
2307
2308 /* The first control is the master control and it must not be NULL */
Hans Verkuilc817d922014-02-21 06:16:32 -03002309 if (WARN_ON(ncontrols == 0 || controls[0] == NULL))
2310 return;
Hans Verkuil09965172010-08-01 14:32:42 -03002311
2312 for (i = 0; i < ncontrols; i++) {
2313 if (controls[i]) {
2314 controls[i]->cluster = controls;
2315 controls[i]->ncontrols = ncontrols;
Hans Verkuil5626b8c2011-08-26 07:53:53 -03002316 if (controls[i]->flags & V4L2_CTRL_FLAG_VOLATILE)
2317 has_volatiles = true;
Hans Verkuil09965172010-08-01 14:32:42 -03002318 }
2319 }
Hans Verkuil5626b8c2011-08-26 07:53:53 -03002320 controls[0]->has_volatiles = has_volatiles;
Hans Verkuil09965172010-08-01 14:32:42 -03002321}
2322EXPORT_SYMBOL(v4l2_ctrl_cluster);
2323
Hans Verkuil72d877c2011-06-10 05:44:36 -03002324void v4l2_ctrl_auto_cluster(unsigned ncontrols, struct v4l2_ctrl **controls,
2325 u8 manual_val, bool set_volatile)
2326{
2327 struct v4l2_ctrl *master = controls[0];
Hans Verkuil5626b8c2011-08-26 07:53:53 -03002328 u32 flag = 0;
Hans Verkuil72d877c2011-06-10 05:44:36 -03002329 int i;
2330
2331 v4l2_ctrl_cluster(ncontrols, controls);
2332 WARN_ON(ncontrols <= 1);
Hans Verkuil82a7c042011-06-28 10:43:13 -03002333 WARN_ON(manual_val < master->minimum || manual_val > master->maximum);
Hans Verkuil5626b8c2011-08-26 07:53:53 -03002334 WARN_ON(set_volatile && !has_op(master, g_volatile_ctrl));
Hans Verkuil72d877c2011-06-10 05:44:36 -03002335 master->is_auto = true;
Hans Verkuil5626b8c2011-08-26 07:53:53 -03002336 master->has_volatiles = set_volatile;
Hans Verkuil72d877c2011-06-10 05:44:36 -03002337 master->manual_mode_value = manual_val;
2338 master->flags |= V4L2_CTRL_FLAG_UPDATE;
Hans Verkuil5626b8c2011-08-26 07:53:53 -03002339
2340 if (!is_cur_manual(master))
2341 flag = V4L2_CTRL_FLAG_INACTIVE |
2342 (set_volatile ? V4L2_CTRL_FLAG_VOLATILE : 0);
Hans Verkuil72d877c2011-06-10 05:44:36 -03002343
2344 for (i = 1; i < ncontrols; i++)
Hans Verkuil88365102011-08-26 07:35:14 -03002345 if (controls[i])
Hans Verkuil72d877c2011-06-10 05:44:36 -03002346 controls[i]->flags |= flag;
Hans Verkuil72d877c2011-06-10 05:44:36 -03002347}
2348EXPORT_SYMBOL(v4l2_ctrl_auto_cluster);
2349
Hans Verkuil09965172010-08-01 14:32:42 -03002350/* Activate/deactivate a control. */
2351void v4l2_ctrl_activate(struct v4l2_ctrl *ctrl, bool active)
2352{
Hans Verkuil6e239392011-06-07 11:13:44 -03002353 /* invert since the actual flag is called 'inactive' */
2354 bool inactive = !active;
2355 bool old;
2356
Hans Verkuil09965172010-08-01 14:32:42 -03002357 if (ctrl == NULL)
2358 return;
2359
Hans Verkuil6e239392011-06-07 11:13:44 -03002360 if (inactive)
Hans Verkuil09965172010-08-01 14:32:42 -03002361 /* set V4L2_CTRL_FLAG_INACTIVE */
Hans Verkuil6e239392011-06-07 11:13:44 -03002362 old = test_and_set_bit(4, &ctrl->flags);
Hans Verkuil09965172010-08-01 14:32:42 -03002363 else
2364 /* clear V4L2_CTRL_FLAG_INACTIVE */
Hans Verkuil6e239392011-06-07 11:13:44 -03002365 old = test_and_clear_bit(4, &ctrl->flags);
2366 if (old != inactive)
2367 send_event(NULL, ctrl, V4L2_EVENT_CTRL_CH_FLAGS);
Hans Verkuil09965172010-08-01 14:32:42 -03002368}
2369EXPORT_SYMBOL(v4l2_ctrl_activate);
2370
2371/* Grab/ungrab a control.
2372 Typically used when streaming starts and you want to grab controls,
2373 preventing the user from changing them.
2374
2375 Just call this and the framework will block any attempts to change
2376 these controls. */
2377void v4l2_ctrl_grab(struct v4l2_ctrl *ctrl, bool grabbed)
2378{
Hans Verkuil6e239392011-06-07 11:13:44 -03002379 bool old;
2380
Hans Verkuil09965172010-08-01 14:32:42 -03002381 if (ctrl == NULL)
2382 return;
2383
Hans Verkuil6e239392011-06-07 11:13:44 -03002384 v4l2_ctrl_lock(ctrl);
Hans Verkuil09965172010-08-01 14:32:42 -03002385 if (grabbed)
2386 /* set V4L2_CTRL_FLAG_GRABBED */
Hans Verkuil6e239392011-06-07 11:13:44 -03002387 old = test_and_set_bit(1, &ctrl->flags);
Hans Verkuil09965172010-08-01 14:32:42 -03002388 else
2389 /* clear V4L2_CTRL_FLAG_GRABBED */
Hans Verkuil6e239392011-06-07 11:13:44 -03002390 old = test_and_clear_bit(1, &ctrl->flags);
2391 if (old != grabbed)
2392 send_event(NULL, ctrl, V4L2_EVENT_CTRL_CH_FLAGS);
2393 v4l2_ctrl_unlock(ctrl);
Hans Verkuil09965172010-08-01 14:32:42 -03002394}
2395EXPORT_SYMBOL(v4l2_ctrl_grab);
2396
2397/* Log the control name and value */
2398static void log_ctrl(const struct v4l2_ctrl *ctrl,
2399 const char *prefix, const char *colon)
2400{
Hans Verkuil09965172010-08-01 14:32:42 -03002401 if (ctrl->flags & (V4L2_CTRL_FLAG_DISABLED | V4L2_CTRL_FLAG_WRITE_ONLY))
2402 return;
2403 if (ctrl->type == V4L2_CTRL_TYPE_CTRL_CLASS)
2404 return;
2405
Hans Verkuil7eafbce2013-12-16 10:12:17 -03002406 pr_info("%s%s%s: ", prefix, colon, ctrl->name);
Hans Verkuil09965172010-08-01 14:32:42 -03002407
Hans Verkuil01760772014-04-27 03:22:17 -03002408 ctrl->type_ops->log(ctrl);
2409
Hans Verkuil88365102011-08-26 07:35:14 -03002410 if (ctrl->flags & (V4L2_CTRL_FLAG_INACTIVE |
2411 V4L2_CTRL_FLAG_GRABBED |
2412 V4L2_CTRL_FLAG_VOLATILE)) {
2413 if (ctrl->flags & V4L2_CTRL_FLAG_INACTIVE)
Hans Verkuil7eafbce2013-12-16 10:12:17 -03002414 pr_cont(" inactive");
Hans Verkuil88365102011-08-26 07:35:14 -03002415 if (ctrl->flags & V4L2_CTRL_FLAG_GRABBED)
Hans Verkuil7eafbce2013-12-16 10:12:17 -03002416 pr_cont(" grabbed");
Hans Verkuil88365102011-08-26 07:35:14 -03002417 if (ctrl->flags & V4L2_CTRL_FLAG_VOLATILE)
Hans Verkuil7eafbce2013-12-16 10:12:17 -03002418 pr_cont(" volatile");
Hans Verkuil88365102011-08-26 07:35:14 -03002419 }
Hans Verkuil7eafbce2013-12-16 10:12:17 -03002420 pr_cont("\n");
Hans Verkuil09965172010-08-01 14:32:42 -03002421}
2422
2423/* Log all controls owned by the handler */
2424void v4l2_ctrl_handler_log_status(struct v4l2_ctrl_handler *hdl,
2425 const char *prefix)
2426{
2427 struct v4l2_ctrl *ctrl;
2428 const char *colon = "";
2429 int len;
2430
2431 if (hdl == NULL)
2432 return;
2433 if (prefix == NULL)
2434 prefix = "";
2435 len = strlen(prefix);
2436 if (len && prefix[len - 1] != ' ')
2437 colon = ": ";
Sakari Ailus77e7c4e2012-01-24 21:05:34 -03002438 mutex_lock(hdl->lock);
Hans Verkuil09965172010-08-01 14:32:42 -03002439 list_for_each_entry(ctrl, &hdl->ctrls, node)
2440 if (!(ctrl->flags & V4L2_CTRL_FLAG_DISABLED))
2441 log_ctrl(ctrl, prefix, colon);
Sakari Ailus77e7c4e2012-01-24 21:05:34 -03002442 mutex_unlock(hdl->lock);
Hans Verkuil09965172010-08-01 14:32:42 -03002443}
2444EXPORT_SYMBOL(v4l2_ctrl_handler_log_status);
2445
Sylwester Nawrockiffa9b9f2013-01-22 19:01:02 -03002446int v4l2_ctrl_subdev_log_status(struct v4l2_subdev *sd)
2447{
2448 v4l2_ctrl_handler_log_status(sd->ctrl_handler, sd->name);
2449 return 0;
2450}
2451EXPORT_SYMBOL(v4l2_ctrl_subdev_log_status);
2452
Hans Verkuil09965172010-08-01 14:32:42 -03002453/* Call s_ctrl for all controls owned by the handler */
2454int v4l2_ctrl_handler_setup(struct v4l2_ctrl_handler *hdl)
2455{
2456 struct v4l2_ctrl *ctrl;
2457 int ret = 0;
2458
2459 if (hdl == NULL)
2460 return 0;
Sakari Ailus77e7c4e2012-01-24 21:05:34 -03002461 mutex_lock(hdl->lock);
Hans Verkuil09965172010-08-01 14:32:42 -03002462 list_for_each_entry(ctrl, &hdl->ctrls, node)
2463 ctrl->done = false;
2464
2465 list_for_each_entry(ctrl, &hdl->ctrls, node) {
2466 struct v4l2_ctrl *master = ctrl->cluster[0];
2467 int i;
2468
2469 /* Skip if this control was already handled by a cluster. */
Hans Verkuil71c6c4c2011-06-14 11:01:52 -03002470 /* Skip button controls and read-only controls. */
2471 if (ctrl->done || ctrl->type == V4L2_CTRL_TYPE_BUTTON ||
2472 (ctrl->flags & V4L2_CTRL_FLAG_READ_ONLY))
Hans Verkuil09965172010-08-01 14:32:42 -03002473 continue;
2474
Hans Verkuil2a863792011-01-11 14:45:03 -03002475 for (i = 0; i < master->ncontrols; i++) {
2476 if (master->cluster[i]) {
2477 cur_to_new(master->cluster[i]);
2478 master->cluster[i]->is_new = 1;
Hans Verkuil71c6c4c2011-06-14 11:01:52 -03002479 master->cluster[i]->done = true;
Hans Verkuil2a863792011-01-11 14:45:03 -03002480 }
2481 }
Hans Verkuil54c911e2011-05-25 06:04:58 -03002482 ret = call_op(master, s_ctrl);
Hans Verkuil09965172010-08-01 14:32:42 -03002483 if (ret)
2484 break;
Hans Verkuil09965172010-08-01 14:32:42 -03002485 }
Sakari Ailus77e7c4e2012-01-24 21:05:34 -03002486 mutex_unlock(hdl->lock);
Hans Verkuil09965172010-08-01 14:32:42 -03002487 return ret;
2488}
2489EXPORT_SYMBOL(v4l2_ctrl_handler_setup);
2490
Hans Verkuild9a25472014-06-12 07:54:16 -03002491/* Implement VIDIOC_QUERY_EXT_CTRL */
2492int v4l2_query_ext_ctrl(struct v4l2_ctrl_handler *hdl, struct v4l2_query_ext_ctrl *qc)
Hans Verkuil09965172010-08-01 14:32:42 -03002493{
Hans Verkuild9a25472014-06-12 07:54:16 -03002494 const unsigned next_flags = V4L2_CTRL_FLAG_NEXT_CTRL | V4L2_CTRL_FLAG_NEXT_COMPOUND;
Hans Verkuil09965172010-08-01 14:32:42 -03002495 u32 id = qc->id & V4L2_CTRL_ID_MASK;
2496 struct v4l2_ctrl_ref *ref;
2497 struct v4l2_ctrl *ctrl;
2498
2499 if (hdl == NULL)
2500 return -EINVAL;
2501
Sakari Ailus77e7c4e2012-01-24 21:05:34 -03002502 mutex_lock(hdl->lock);
Hans Verkuil09965172010-08-01 14:32:42 -03002503
2504 /* Try to find it */
2505 ref = find_ref(hdl, id);
2506
Hans Verkuild9a25472014-06-12 07:54:16 -03002507 if ((qc->id & next_flags) && !list_empty(&hdl->ctrl_refs)) {
2508 bool is_compound;
2509 /* Match any control that is not hidden */
2510 unsigned mask = 1;
2511 bool match = false;
2512
2513 if ((qc->id & next_flags) == V4L2_CTRL_FLAG_NEXT_COMPOUND) {
2514 /* Match any hidden control */
2515 match = true;
2516 } else if ((qc->id & next_flags) == next_flags) {
2517 /* Match any control, compound or not */
2518 mask = 0;
2519 }
2520
Hans Verkuil09965172010-08-01 14:32:42 -03002521 /* Find the next control with ID > qc->id */
2522
2523 /* Did we reach the end of the control list? */
2524 if (id >= node2id(hdl->ctrl_refs.prev)) {
2525 ref = NULL; /* Yes, so there is no next control */
2526 } else if (ref) {
2527 /* We found a control with the given ID, so just get
Hans Verkuild9a25472014-06-12 07:54:16 -03002528 the next valid one in the list. */
2529 list_for_each_entry_continue(ref, &hdl->ctrl_refs, node) {
Hans Verkuil35204e22015-09-21 06:14:16 -03002530 is_compound = ref->ctrl->is_array ||
Hans Verkuild9a25472014-06-12 07:54:16 -03002531 ref->ctrl->type >= V4L2_CTRL_COMPOUND_TYPES;
2532 if (id < ref->ctrl->id &&
2533 (is_compound & mask) == match)
2534 break;
2535 }
2536 if (&ref->node == &hdl->ctrl_refs)
2537 ref = NULL;
Hans Verkuil09965172010-08-01 14:32:42 -03002538 } else {
2539 /* No control with the given ID exists, so start
2540 searching for the next largest ID. We know there
2541 is one, otherwise the first 'if' above would have
2542 been true. */
Hans Verkuild9a25472014-06-12 07:54:16 -03002543 list_for_each_entry(ref, &hdl->ctrl_refs, node) {
Hans Verkuil35204e22015-09-21 06:14:16 -03002544 is_compound = ref->ctrl->is_array ||
Hans Verkuild9a25472014-06-12 07:54:16 -03002545 ref->ctrl->type >= V4L2_CTRL_COMPOUND_TYPES;
2546 if (id < ref->ctrl->id &&
2547 (is_compound & mask) == match)
Hans Verkuil09965172010-08-01 14:32:42 -03002548 break;
Hans Verkuild9a25472014-06-12 07:54:16 -03002549 }
2550 if (&ref->node == &hdl->ctrl_refs)
2551 ref = NULL;
Hans Verkuil09965172010-08-01 14:32:42 -03002552 }
2553 }
Sakari Ailus77e7c4e2012-01-24 21:05:34 -03002554 mutex_unlock(hdl->lock);
Hans Verkuild9a25472014-06-12 07:54:16 -03002555
Hans Verkuil09965172010-08-01 14:32:42 -03002556 if (!ref)
2557 return -EINVAL;
2558
2559 ctrl = ref->ctrl;
2560 memset(qc, 0, sizeof(*qc));
Hans Verkuil829fb2d2011-01-16 11:21:40 -03002561 if (id >= V4L2_CID_PRIVATE_BASE)
2562 qc->id = id;
2563 else
2564 qc->id = ctrl->id;
Hans Verkuil09965172010-08-01 14:32:42 -03002565 strlcpy(qc->name, ctrl->name, sizeof(qc->name));
Hans Verkuild9a25472014-06-12 07:54:16 -03002566 qc->flags = ctrl->flags;
2567 qc->type = ctrl->type;
2568 if (ctrl->is_ptr)
2569 qc->flags |= V4L2_CTRL_FLAG_HAS_PAYLOAD;
2570 qc->elem_size = ctrl->elem_size;
Hans Verkuil20d88ee2014-06-12 07:55:21 -03002571 qc->elems = ctrl->elems;
2572 qc->nr_of_dims = ctrl->nr_of_dims;
2573 memcpy(qc->dims, ctrl->dims, qc->nr_of_dims * sizeof(qc->dims[0]));
Hans Verkuil09965172010-08-01 14:32:42 -03002574 qc->minimum = ctrl->minimum;
2575 qc->maximum = ctrl->maximum;
2576 qc->default_value = ctrl->default_value;
Sakari Ailusce580fe2011-08-04 13:51:11 -03002577 if (ctrl->type == V4L2_CTRL_TYPE_MENU
2578 || ctrl->type == V4L2_CTRL_TYPE_INTEGER_MENU)
Hans Verkuil09965172010-08-01 14:32:42 -03002579 qc->step = 1;
2580 else
2581 qc->step = ctrl->step;
Hans Verkuild9a25472014-06-12 07:54:16 -03002582 return 0;
2583}
2584EXPORT_SYMBOL(v4l2_query_ext_ctrl);
2585
2586/* Implement VIDIOC_QUERYCTRL */
2587int v4l2_queryctrl(struct v4l2_ctrl_handler *hdl, struct v4l2_queryctrl *qc)
2588{
2589 struct v4l2_query_ext_ctrl qec = { qc->id };
2590 int rc;
2591
2592 rc = v4l2_query_ext_ctrl(hdl, &qec);
2593 if (rc)
2594 return rc;
2595
2596 qc->id = qec.id;
2597 qc->type = qec.type;
2598 qc->flags = qec.flags;
2599 strlcpy(qc->name, qec.name, sizeof(qc->name));
2600 switch (qc->type) {
2601 case V4L2_CTRL_TYPE_INTEGER:
2602 case V4L2_CTRL_TYPE_BOOLEAN:
2603 case V4L2_CTRL_TYPE_MENU:
2604 case V4L2_CTRL_TYPE_INTEGER_MENU:
2605 case V4L2_CTRL_TYPE_STRING:
2606 case V4L2_CTRL_TYPE_BITMASK:
2607 qc->minimum = qec.minimum;
2608 qc->maximum = qec.maximum;
2609 qc->step = qec.step;
2610 qc->default_value = qec.default_value;
2611 break;
2612 default:
2613 qc->minimum = 0;
2614 qc->maximum = 0;
2615 qc->step = 0;
2616 qc->default_value = 0;
2617 break;
2618 }
Hans Verkuil09965172010-08-01 14:32:42 -03002619 return 0;
2620}
2621EXPORT_SYMBOL(v4l2_queryctrl);
2622
2623int v4l2_subdev_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
2624{
Hans Verkuild9a25472014-06-12 07:54:16 -03002625 if (qc->id & (V4L2_CTRL_FLAG_NEXT_CTRL | V4L2_CTRL_FLAG_NEXT_COMPOUND))
Hans Verkuil87a0c942011-02-22 12:31:07 -03002626 return -EINVAL;
Hans Verkuil09965172010-08-01 14:32:42 -03002627 return v4l2_queryctrl(sd->ctrl_handler, qc);
2628}
2629EXPORT_SYMBOL(v4l2_subdev_queryctrl);
2630
2631/* Implement VIDIOC_QUERYMENU */
2632int v4l2_querymenu(struct v4l2_ctrl_handler *hdl, struct v4l2_querymenu *qm)
2633{
2634 struct v4l2_ctrl *ctrl;
2635 u32 i = qm->index;
2636
2637 ctrl = v4l2_ctrl_find(hdl, qm->id);
2638 if (!ctrl)
2639 return -EINVAL;
2640
2641 qm->reserved = 0;
2642 /* Sanity checks */
Sakari Ailusce580fe2011-08-04 13:51:11 -03002643 switch (ctrl->type) {
2644 case V4L2_CTRL_TYPE_MENU:
2645 if (ctrl->qmenu == NULL)
2646 return -EINVAL;
2647 break;
2648 case V4L2_CTRL_TYPE_INTEGER_MENU:
2649 if (ctrl->qmenu_int == NULL)
2650 return -EINVAL;
2651 break;
2652 default:
Hans Verkuil09965172010-08-01 14:32:42 -03002653 return -EINVAL;
Sakari Ailusce580fe2011-08-04 13:51:11 -03002654 }
2655
2656 if (i < ctrl->minimum || i > ctrl->maximum)
2657 return -EINVAL;
2658
Hans Verkuil09965172010-08-01 14:32:42 -03002659 /* Use mask to see if this menu item should be skipped */
2660 if (ctrl->menu_skip_mask & (1 << i))
2661 return -EINVAL;
2662 /* Empty menu items should also be skipped */
Sakari Ailusce580fe2011-08-04 13:51:11 -03002663 if (ctrl->type == V4L2_CTRL_TYPE_MENU) {
2664 if (ctrl->qmenu[i] == NULL || ctrl->qmenu[i][0] == '\0')
2665 return -EINVAL;
2666 strlcpy(qm->name, ctrl->qmenu[i], sizeof(qm->name));
2667 } else {
2668 qm->value = ctrl->qmenu_int[i];
2669 }
Hans Verkuil09965172010-08-01 14:32:42 -03002670 return 0;
2671}
2672EXPORT_SYMBOL(v4l2_querymenu);
2673
2674int v4l2_subdev_querymenu(struct v4l2_subdev *sd, struct v4l2_querymenu *qm)
2675{
2676 return v4l2_querymenu(sd->ctrl_handler, qm);
2677}
2678EXPORT_SYMBOL(v4l2_subdev_querymenu);
2679
2680
2681
2682/* Some general notes on the atomic requirements of VIDIOC_G/TRY/S_EXT_CTRLS:
2683
2684 It is not a fully atomic operation, just best-effort only. After all, if
2685 multiple controls have to be set through multiple i2c writes (for example)
2686 then some initial writes may succeed while others fail. Thus leaving the
2687 system in an inconsistent state. The question is how much effort you are
2688 willing to spend on trying to make something atomic that really isn't.
2689
2690 From the point of view of an application the main requirement is that
2691 when you call VIDIOC_S_EXT_CTRLS and some values are invalid then an
2692 error should be returned without actually affecting any controls.
2693
2694 If all the values are correct, then it is acceptable to just give up
2695 in case of low-level errors.
2696
2697 It is important though that the application can tell when only a partial
2698 configuration was done. The way we do that is through the error_idx field
2699 of struct v4l2_ext_controls: if that is equal to the count field then no
2700 controls were affected. Otherwise all controls before that index were
2701 successful in performing their 'get' or 'set' operation, the control at
2702 the given index failed, and you don't know what happened with the controls
2703 after the failed one. Since if they were part of a control cluster they
2704 could have been successfully processed (if a cluster member was encountered
2705 at index < error_idx), they could have failed (if a cluster member was at
2706 error_idx), or they may not have been processed yet (if the first cluster
2707 member appeared after error_idx).
2708
2709 It is all fairly theoretical, though. In practice all you can do is to
2710 bail out. If error_idx == count, then it is an application bug. If
2711 error_idx < count then it is only an application bug if the error code was
2712 EBUSY. That usually means that something started streaming just when you
2713 tried to set the controls. In all other cases it is a driver/hardware
2714 problem and all you can do is to retry or bail out.
2715
2716 Note that these rules do not apply to VIDIOC_TRY_EXT_CTRLS: since that
2717 never modifies controls the error_idx is just set to whatever control
2718 has an invalid value.
2719 */
2720
2721/* Prepare for the extended g/s/try functions.
2722 Find the controls in the control array and do some basic checks. */
2723static int prepare_ext_ctrls(struct v4l2_ctrl_handler *hdl,
2724 struct v4l2_ext_controls *cs,
Hans Verkuild9a25472014-06-12 07:54:16 -03002725 struct v4l2_ctrl_helper *helpers,
2726 bool get)
Hans Verkuil09965172010-08-01 14:32:42 -03002727{
Hans Verkuileb5b16e2011-06-14 10:04:06 -03002728 struct v4l2_ctrl_helper *h;
2729 bool have_clusters = false;
Hans Verkuil09965172010-08-01 14:32:42 -03002730 u32 i;
2731
Hans Verkuileb5b16e2011-06-14 10:04:06 -03002732 for (i = 0, h = helpers; i < cs->count; i++, h++) {
Hans Verkuil09965172010-08-01 14:32:42 -03002733 struct v4l2_ext_control *c = &cs->controls[i];
Hans Verkuileb5b16e2011-06-14 10:04:06 -03002734 struct v4l2_ctrl_ref *ref;
Hans Verkuil09965172010-08-01 14:32:42 -03002735 struct v4l2_ctrl *ctrl;
2736 u32 id = c->id & V4L2_CTRL_ID_MASK;
2737
Hans Verkuil37cd3b72011-06-07 04:40:04 -03002738 cs->error_idx = i;
Hans Verkuil09965172010-08-01 14:32:42 -03002739
Ricardo Ribalda953eae52015-10-29 08:10:29 -02002740 if (cs->which &&
2741 cs->which != V4L2_CTRL_WHICH_DEF_VAL &&
2742 V4L2_CTRL_ID2WHICH(id) != cs->which)
Hans Verkuil09965172010-08-01 14:32:42 -03002743 return -EINVAL;
2744
2745 /* Old-style private controls are not allowed for
2746 extended controls */
2747 if (id >= V4L2_CID_PRIVATE_BASE)
2748 return -EINVAL;
Hans Verkuileb5b16e2011-06-14 10:04:06 -03002749 ref = find_ref_lock(hdl, id);
2750 if (ref == NULL)
Hans Verkuil09965172010-08-01 14:32:42 -03002751 return -EINVAL;
Hans Verkuileb5b16e2011-06-14 10:04:06 -03002752 ctrl = ref->ctrl;
Hans Verkuil09965172010-08-01 14:32:42 -03002753 if (ctrl->flags & V4L2_CTRL_FLAG_DISABLED)
2754 return -EINVAL;
2755
Hans Verkuileb5b16e2011-06-14 10:04:06 -03002756 if (ctrl->cluster[0]->ncontrols > 1)
2757 have_clusters = true;
2758 if (ctrl->cluster[0] != ctrl)
2759 ref = find_ref_lock(hdl, ctrl->cluster[0]->id);
Hans Verkuil302ab7c2014-06-10 07:06:50 -03002760 if (ctrl->is_ptr && !ctrl->is_string) {
2761 unsigned tot_size = ctrl->elems * ctrl->elem_size;
2762
2763 if (c->size < tot_size) {
2764 if (get) {
2765 c->size = tot_size;
2766 return -ENOSPC;
2767 }
2768 return -EFAULT;
Hans Verkuild9a25472014-06-12 07:54:16 -03002769 }
Hans Verkuil302ab7c2014-06-10 07:06:50 -03002770 c->size = tot_size;
Hans Verkuild9a25472014-06-12 07:54:16 -03002771 }
Hans Verkuileb5b16e2011-06-14 10:04:06 -03002772 /* Store the ref to the master control of the cluster */
2773 h->mref = ref;
2774 h->ctrl = ctrl;
2775 /* Initially set next to 0, meaning that there is no other
2776 control in this helper array belonging to the same
2777 cluster */
2778 h->next = 0;
Hans Verkuil09965172010-08-01 14:32:42 -03002779 }
Hans Verkuileb5b16e2011-06-14 10:04:06 -03002780
2781 /* We are done if there were no controls that belong to a multi-
2782 control cluster. */
2783 if (!have_clusters)
2784 return 0;
2785
2786 /* The code below figures out in O(n) time which controls in the list
2787 belong to the same cluster. */
2788
2789 /* This has to be done with the handler lock taken. */
Sakari Ailus77e7c4e2012-01-24 21:05:34 -03002790 mutex_lock(hdl->lock);
Hans Verkuileb5b16e2011-06-14 10:04:06 -03002791
2792 /* First zero the helper field in the master control references */
2793 for (i = 0; i < cs->count; i++)
Sachin Kamatc0822662012-07-10 07:14:46 -03002794 helpers[i].mref->helper = NULL;
Hans Verkuileb5b16e2011-06-14 10:04:06 -03002795 for (i = 0, h = helpers; i < cs->count; i++, h++) {
2796 struct v4l2_ctrl_ref *mref = h->mref;
2797
2798 /* If the mref->helper is set, then it points to an earlier
2799 helper that belongs to the same cluster. */
2800 if (mref->helper) {
2801 /* Set the next field of mref->helper to the current
2802 index: this means that that earlier helper now
2803 points to the next helper in the same cluster. */
2804 mref->helper->next = i;
2805 /* mref should be set only for the first helper in the
2806 cluster, clear the others. */
2807 h->mref = NULL;
2808 }
2809 /* Point the mref helper to the current helper struct. */
2810 mref->helper = h;
2811 }
Sakari Ailus77e7c4e2012-01-24 21:05:34 -03002812 mutex_unlock(hdl->lock);
Hans Verkuil09965172010-08-01 14:32:42 -03002813 return 0;
2814}
2815
Hans Verkuil09965172010-08-01 14:32:42 -03002816/* Handles the corner case where cs->count == 0. It checks whether the
2817 specified control class exists. If that class ID is 0, then it checks
2818 whether there are any controls at all. */
Ricardo Ribalda0f8017b2015-10-29 08:10:28 -02002819static int class_check(struct v4l2_ctrl_handler *hdl, u32 which)
Hans Verkuil09965172010-08-01 14:32:42 -03002820{
Ricardo Ribalda953eae52015-10-29 08:10:29 -02002821 if (which == 0 || which == V4L2_CTRL_WHICH_DEF_VAL)
Hans Verkuil09965172010-08-01 14:32:42 -03002822 return list_empty(&hdl->ctrl_refs) ? -EINVAL : 0;
Ricardo Ribalda0f8017b2015-10-29 08:10:28 -02002823 return find_ref_lock(hdl, which | 1) ? 0 : -EINVAL;
Hans Verkuil09965172010-08-01 14:32:42 -03002824}
2825
2826
2827
2828/* Get extended controls. Allocates the helpers array if needed. */
2829int v4l2_g_ext_ctrls(struct v4l2_ctrl_handler *hdl, struct v4l2_ext_controls *cs)
2830{
Hans Verkuileb5b16e2011-06-14 10:04:06 -03002831 struct v4l2_ctrl_helper helper[4];
2832 struct v4l2_ctrl_helper *helpers = helper;
Hans Verkuil09965172010-08-01 14:32:42 -03002833 int ret;
Hans Verkuilddac5c12011-06-10 05:43:34 -03002834 int i, j;
Ricardo Ribalda953eae52015-10-29 08:10:29 -02002835 bool def_value;
2836
2837 def_value = (cs->which == V4L2_CTRL_WHICH_DEF_VAL);
Hans Verkuil09965172010-08-01 14:32:42 -03002838
2839 cs->error_idx = cs->count;
Ricardo Ribalda0f8017b2015-10-29 08:10:28 -02002840 cs->which = V4L2_CTRL_ID2WHICH(cs->which);
Hans Verkuil09965172010-08-01 14:32:42 -03002841
2842 if (hdl == NULL)
2843 return -EINVAL;
2844
2845 if (cs->count == 0)
Ricardo Ribalda0f8017b2015-10-29 08:10:28 -02002846 return class_check(hdl, cs->which);
Hans Verkuil09965172010-08-01 14:32:42 -03002847
2848 if (cs->count > ARRAY_SIZE(helper)) {
Xi Wang5f0049b2012-04-06 09:32:36 -03002849 helpers = kmalloc_array(cs->count, sizeof(helper[0]),
2850 GFP_KERNEL);
Hans Verkuil09965172010-08-01 14:32:42 -03002851 if (helpers == NULL)
2852 return -ENOMEM;
2853 }
2854
Hans Verkuild9a25472014-06-12 07:54:16 -03002855 ret = prepare_ext_ctrls(hdl, cs, helpers, true);
Hans Verkuil37cd3b72011-06-07 04:40:04 -03002856 cs->error_idx = cs->count;
Hans Verkuil09965172010-08-01 14:32:42 -03002857
2858 for (i = 0; !ret && i < cs->count; i++)
2859 if (helpers[i].ctrl->flags & V4L2_CTRL_FLAG_WRITE_ONLY)
2860 ret = -EACCES;
2861
2862 for (i = 0; !ret && i < cs->count; i++) {
Hans Verkuileb5b16e2011-06-14 10:04:06 -03002863 int (*ctrl_to_user)(struct v4l2_ext_control *c,
Ricardo Ribalda953eae52015-10-29 08:10:29 -02002864 struct v4l2_ctrl *ctrl);
Hans Verkuileb5b16e2011-06-14 10:04:06 -03002865 struct v4l2_ctrl *master;
Hans Verkuil09965172010-08-01 14:32:42 -03002866
Ricardo Ribalda953eae52015-10-29 08:10:29 -02002867 ctrl_to_user = def_value ? def_to_user : cur_to_user;
2868
Hans Verkuileb5b16e2011-06-14 10:04:06 -03002869 if (helpers[i].mref == NULL)
Hans Verkuil09965172010-08-01 14:32:42 -03002870 continue;
2871
Hans Verkuileb5b16e2011-06-14 10:04:06 -03002872 master = helpers[i].mref->ctrl;
Hans Verkuil09965172010-08-01 14:32:42 -03002873 cs->error_idx = i;
2874
2875 v4l2_ctrl_lock(master);
Hans Verkuilddac5c12011-06-10 05:43:34 -03002876
2877 /* g_volatile_ctrl will update the new control values */
Ricardo Ribalda953eae52015-10-29 08:10:29 -02002878 if (!def_value &&
2879 ((master->flags & V4L2_CTRL_FLAG_VOLATILE) ||
2880 (master->has_volatiles && !is_cur_manual(master)))) {
Hans Verkuilddac5c12011-06-10 05:43:34 -03002881 for (j = 0; j < master->ncontrols; j++)
2882 cur_to_new(master->cluster[j]);
Hans Verkuil54c911e2011-05-25 06:04:58 -03002883 ret = call_op(master, g_volatile_ctrl);
Hans Verkuileb5b16e2011-06-14 10:04:06 -03002884 ctrl_to_user = new_to_user;
Hans Verkuilddac5c12011-06-10 05:43:34 -03002885 }
2886 /* If OK, then copy the current (for non-volatile controls)
2887 or the new (for volatile controls) control values to the
2888 caller */
Hans Verkuileb5b16e2011-06-14 10:04:06 -03002889 if (!ret) {
2890 u32 idx = i;
2891
2892 do {
2893 ret = ctrl_to_user(cs->controls + idx,
2894 helpers[idx].ctrl);
2895 idx = helpers[idx].next;
2896 } while (!ret && idx);
2897 }
Hans Verkuil09965172010-08-01 14:32:42 -03002898 v4l2_ctrl_unlock(master);
Hans Verkuil09965172010-08-01 14:32:42 -03002899 }
2900
2901 if (cs->count > ARRAY_SIZE(helper))
2902 kfree(helpers);
2903 return ret;
2904}
2905EXPORT_SYMBOL(v4l2_g_ext_ctrls);
2906
2907int v4l2_subdev_g_ext_ctrls(struct v4l2_subdev *sd, struct v4l2_ext_controls *cs)
2908{
2909 return v4l2_g_ext_ctrls(sd->ctrl_handler, cs);
2910}
2911EXPORT_SYMBOL(v4l2_subdev_g_ext_ctrls);
2912
2913/* Helper function to get a single control */
Laurent Pinchart03d52852012-07-23 09:15:21 -03002914static int get_ctrl(struct v4l2_ctrl *ctrl, struct v4l2_ext_control *c)
Hans Verkuil09965172010-08-01 14:32:42 -03002915{
2916 struct v4l2_ctrl *master = ctrl->cluster[0];
2917 int ret = 0;
Hans Verkuilddac5c12011-06-10 05:43:34 -03002918 int i;
Hans Verkuil09965172010-08-01 14:32:42 -03002919
Hans Verkuild9a25472014-06-12 07:54:16 -03002920 /* Compound controls are not supported. The new_to_user() and
Laurent Pinchart03d52852012-07-23 09:15:21 -03002921 * cur_to_user() calls below would need to be modified not to access
2922 * userspace memory when called from get_ctrl().
2923 */
Benoit Parrota8077732015-09-21 13:03:21 -03002924 if (!ctrl->is_int && ctrl->type != V4L2_CTRL_TYPE_INTEGER64)
Laurent Pinchart03d52852012-07-23 09:15:21 -03002925 return -EINVAL;
2926
Hans Verkuil09965172010-08-01 14:32:42 -03002927 if (ctrl->flags & V4L2_CTRL_FLAG_WRITE_ONLY)
2928 return -EACCES;
2929
2930 v4l2_ctrl_lock(master);
2931 /* g_volatile_ctrl will update the current control values */
Hans Verkuil5626b8c2011-08-26 07:53:53 -03002932 if (ctrl->flags & V4L2_CTRL_FLAG_VOLATILE) {
Hans Verkuilddac5c12011-06-10 05:43:34 -03002933 for (i = 0; i < master->ncontrols; i++)
2934 cur_to_new(master->cluster[i]);
Hans Verkuil54c911e2011-05-25 06:04:58 -03002935 ret = call_op(master, g_volatile_ctrl);
Laurent Pinchart03d52852012-07-23 09:15:21 -03002936 new_to_user(c, ctrl);
Hans Verkuilddac5c12011-06-10 05:43:34 -03002937 } else {
Laurent Pinchart03d52852012-07-23 09:15:21 -03002938 cur_to_user(c, ctrl);
Hans Verkuilddac5c12011-06-10 05:43:34 -03002939 }
Hans Verkuil09965172010-08-01 14:32:42 -03002940 v4l2_ctrl_unlock(master);
2941 return ret;
2942}
2943
2944int v4l2_g_ctrl(struct v4l2_ctrl_handler *hdl, struct v4l2_control *control)
2945{
2946 struct v4l2_ctrl *ctrl = v4l2_ctrl_find(hdl, control->id);
Laurent Pinchart03d52852012-07-23 09:15:21 -03002947 struct v4l2_ext_control c;
2948 int ret;
Hans Verkuil09965172010-08-01 14:32:42 -03002949
Hans Verkuild9a25472014-06-12 07:54:16 -03002950 if (ctrl == NULL || !ctrl->is_int)
Hans Verkuil09965172010-08-01 14:32:42 -03002951 return -EINVAL;
Laurent Pinchart03d52852012-07-23 09:15:21 -03002952 ret = get_ctrl(ctrl, &c);
2953 control->value = c.value;
2954 return ret;
Hans Verkuil09965172010-08-01 14:32:42 -03002955}
2956EXPORT_SYMBOL(v4l2_g_ctrl);
2957
2958int v4l2_subdev_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *control)
2959{
2960 return v4l2_g_ctrl(sd->ctrl_handler, control);
2961}
2962EXPORT_SYMBOL(v4l2_subdev_g_ctrl);
2963
2964s32 v4l2_ctrl_g_ctrl(struct v4l2_ctrl *ctrl)
2965{
Laurent Pinchart03d52852012-07-23 09:15:21 -03002966 struct v4l2_ext_control c;
Hans Verkuil09965172010-08-01 14:32:42 -03002967
2968 /* It's a driver bug if this happens. */
Hans Verkuild9a25472014-06-12 07:54:16 -03002969 WARN_ON(!ctrl->is_int);
Laurent Pinchart03d52852012-07-23 09:15:21 -03002970 c.value = 0;
2971 get_ctrl(ctrl, &c);
2972 return c.value;
Hans Verkuil09965172010-08-01 14:32:42 -03002973}
2974EXPORT_SYMBOL(v4l2_ctrl_g_ctrl);
2975
Laurent Pinchart03d52852012-07-23 09:15:21 -03002976s64 v4l2_ctrl_g_ctrl_int64(struct v4l2_ctrl *ctrl)
2977{
2978 struct v4l2_ext_control c;
2979
2980 /* It's a driver bug if this happens. */
Hans Verkuil998e7652014-06-10 07:55:00 -03002981 WARN_ON(ctrl->is_ptr || ctrl->type != V4L2_CTRL_TYPE_INTEGER64);
Benoit Parrota8077732015-09-21 13:03:21 -03002982 c.value64 = 0;
Laurent Pinchart03d52852012-07-23 09:15:21 -03002983 get_ctrl(ctrl, &c);
Benoit Parrota8077732015-09-21 13:03:21 -03002984 return c.value64;
Laurent Pinchart03d52852012-07-23 09:15:21 -03002985}
2986EXPORT_SYMBOL(v4l2_ctrl_g_ctrl_int64);
2987
Hans Verkuil09965172010-08-01 14:32:42 -03002988
2989/* Core function that calls try/s_ctrl and ensures that the new value is
2990 copied to the current value on a set.
2991 Must be called with ctrl->handler->lock held. */
Sylwester Nawrocki2ccbe772013-01-19 15:51:55 -03002992static int try_or_set_cluster(struct v4l2_fh *fh, struct v4l2_ctrl *master,
2993 bool set, u32 ch_flags)
Hans Verkuil09965172010-08-01 14:32:42 -03002994{
Hans Verkuil72d877c2011-06-10 05:44:36 -03002995 bool update_flag;
Hans Verkuileb5b16e2011-06-14 10:04:06 -03002996 int ret;
Hans Verkuil09965172010-08-01 14:32:42 -03002997 int i;
2998
2999 /* Go through the cluster and either validate the new value or
3000 (if no new value was set), copy the current value to the new
3001 value, ensuring a consistent view for the control ops when
3002 called. */
Hans Verkuileb5b16e2011-06-14 10:04:06 -03003003 for (i = 0; i < master->ncontrols; i++) {
Hans Verkuil09965172010-08-01 14:32:42 -03003004 struct v4l2_ctrl *ctrl = master->cluster[i];
3005
3006 if (ctrl == NULL)
3007 continue;
3008
Hans Verkuileb5b16e2011-06-14 10:04:06 -03003009 if (!ctrl->is_new) {
3010 cur_to_new(ctrl);
Hans Verkuil09965172010-08-01 14:32:42 -03003011 continue;
3012 }
Hans Verkuileb5b16e2011-06-14 10:04:06 -03003013 /* Check again: it may have changed since the
3014 previous check in try_or_set_ext_ctrls(). */
3015 if (set && (ctrl->flags & V4L2_CTRL_FLAG_GRABBED))
3016 return -EBUSY;
Hans Verkuil09965172010-08-01 14:32:42 -03003017 }
3018
Hans Verkuileb5b16e2011-06-14 10:04:06 -03003019 ret = call_op(master, try_ctrl);
Hans Verkuil09965172010-08-01 14:32:42 -03003020
3021 /* Don't set if there is no change */
Hans Verkuil72d877c2011-06-10 05:44:36 -03003022 if (ret || !set || !cluster_changed(master))
3023 return ret;
3024 ret = call_op(master, s_ctrl);
Hans Verkuil72d877c2011-06-10 05:44:36 -03003025 if (ret)
3026 return ret;
3027
Hans Verkuileb5b16e2011-06-14 10:04:06 -03003028 /* If OK, then make the new values permanent. */
Hans Verkuil72d877c2011-06-10 05:44:36 -03003029 update_flag = is_cur_manual(master) != is_new_manual(master);
3030 for (i = 0; i < master->ncontrols; i++)
Sylwester Nawrocki2ccbe772013-01-19 15:51:55 -03003031 new_to_cur(fh, master->cluster[i], ch_flags |
3032 ((update_flag && i > 0) ? V4L2_EVENT_CTRL_CH_FLAGS : 0));
Hans Verkuil72d877c2011-06-10 05:44:36 -03003033 return 0;
Hans Verkuil09965172010-08-01 14:32:42 -03003034}
3035
Hans Verkuile6402582011-06-14 10:56:42 -03003036/* Validate controls. */
3037static int validate_ctrls(struct v4l2_ext_controls *cs,
3038 struct v4l2_ctrl_helper *helpers, bool set)
Hans Verkuil09965172010-08-01 14:32:42 -03003039{
Hans Verkuile6402582011-06-14 10:56:42 -03003040 unsigned i;
Hans Verkuil09965172010-08-01 14:32:42 -03003041 int ret = 0;
3042
Hans Verkuileb5b16e2011-06-14 10:04:06 -03003043 cs->error_idx = cs->count;
Hans Verkuil09965172010-08-01 14:32:42 -03003044 for (i = 0; i < cs->count; i++) {
3045 struct v4l2_ctrl *ctrl = helpers[i].ctrl;
Hans Verkuil7a7f1ab2014-09-22 11:08:55 -03003046 union v4l2_ctrl_ptr p_new;
Hans Verkuil09965172010-08-01 14:32:42 -03003047
Hans Verkuile6402582011-06-14 10:56:42 -03003048 cs->error_idx = i;
Hans Verkuil09965172010-08-01 14:32:42 -03003049
3050 if (ctrl->flags & V4L2_CTRL_FLAG_READ_ONLY)
3051 return -EACCES;
3052 /* This test is also done in try_set_control_cluster() which
3053 is called in atomic context, so that has the final say,
3054 but it makes sense to do an up-front check as well. Once
3055 an error occurs in try_set_control_cluster() some other
3056 controls may have been set already and we want to do a
3057 best-effort to avoid that. */
3058 if (set && (ctrl->flags & V4L2_CTRL_FLAG_GRABBED))
3059 return -EBUSY;
Hans Verkuil7a7f1ab2014-09-22 11:08:55 -03003060 /*
3061 * Skip validation for now if the payload needs to be copied
3062 * from userspace into kernelspace. We'll validate those later.
3063 */
3064 if (ctrl->is_ptr)
3065 continue;
3066 if (ctrl->type == V4L2_CTRL_TYPE_INTEGER64)
3067 p_new.p_s64 = &cs->controls[i].value64;
3068 else
3069 p_new.p_s32 = &cs->controls[i].value;
3070 ret = validate_new(ctrl, p_new);
Hans Verkuileb5b16e2011-06-14 10:04:06 -03003071 if (ret)
3072 return ret;
Hans Verkuil09965172010-08-01 14:32:42 -03003073 }
Hans Verkuile6402582011-06-14 10:56:42 -03003074 return 0;
3075}
Hans Verkuil09965172010-08-01 14:32:42 -03003076
Hans Verkuil5626b8c2011-08-26 07:53:53 -03003077/* Obtain the current volatile values of an autocluster and mark them
3078 as new. */
3079static void update_from_auto_cluster(struct v4l2_ctrl *master)
3080{
3081 int i;
3082
Antonio Ospite759b26a2015-10-14 10:57:32 -03003083 for (i = 1; i < master->ncontrols; i++)
Hans Verkuil5626b8c2011-08-26 07:53:53 -03003084 cur_to_new(master->cluster[i]);
3085 if (!call_op(master, g_volatile_ctrl))
3086 for (i = 1; i < master->ncontrols; i++)
3087 if (master->cluster[i])
3088 master->cluster[i]->is_new = 1;
3089}
3090
Hans Verkuile6402582011-06-14 10:56:42 -03003091/* Try or try-and-set controls */
3092static int try_set_ext_ctrls(struct v4l2_fh *fh, struct v4l2_ctrl_handler *hdl,
3093 struct v4l2_ext_controls *cs,
3094 bool set)
3095{
3096 struct v4l2_ctrl_helper helper[4];
3097 struct v4l2_ctrl_helper *helpers = helper;
3098 unsigned i, j;
3099 int ret;
3100
3101 cs->error_idx = cs->count;
Ricardo Ribalda953eae52015-10-29 08:10:29 -02003102
3103 /* Default value cannot be changed */
3104 if (cs->which == V4L2_CTRL_WHICH_DEF_VAL)
3105 return -EINVAL;
3106
Ricardo Ribalda0f8017b2015-10-29 08:10:28 -02003107 cs->which = V4L2_CTRL_ID2WHICH(cs->which);
Hans Verkuile6402582011-06-14 10:56:42 -03003108
3109 if (hdl == NULL)
3110 return -EINVAL;
3111
3112 if (cs->count == 0)
Ricardo Ribalda0f8017b2015-10-29 08:10:28 -02003113 return class_check(hdl, cs->which);
Hans Verkuile6402582011-06-14 10:56:42 -03003114
3115 if (cs->count > ARRAY_SIZE(helper)) {
Xi Wang0a3475e2012-04-06 09:32:37 -03003116 helpers = kmalloc_array(cs->count, sizeof(helper[0]),
3117 GFP_KERNEL);
Hans Verkuile6402582011-06-14 10:56:42 -03003118 if (!helpers)
3119 return -ENOMEM;
3120 }
Hans Verkuild9a25472014-06-12 07:54:16 -03003121 ret = prepare_ext_ctrls(hdl, cs, helpers, false);
Hans Verkuile6402582011-06-14 10:56:42 -03003122 if (!ret)
3123 ret = validate_ctrls(cs, helpers, set);
3124 if (ret && set)
3125 cs->error_idx = cs->count;
Hans Verkuil09965172010-08-01 14:32:42 -03003126 for (i = 0; !ret && i < cs->count; i++) {
Hans Verkuileb5b16e2011-06-14 10:04:06 -03003127 struct v4l2_ctrl *master;
3128 u32 idx = i;
Hans Verkuil09965172010-08-01 14:32:42 -03003129
Hans Verkuileb5b16e2011-06-14 10:04:06 -03003130 if (helpers[i].mref == NULL)
Hans Verkuil09965172010-08-01 14:32:42 -03003131 continue;
3132
Hans Verkuil37cd3b72011-06-07 04:40:04 -03003133 cs->error_idx = i;
Hans Verkuileb5b16e2011-06-14 10:04:06 -03003134 master = helpers[i].mref->ctrl;
3135 v4l2_ctrl_lock(master);
Hans Verkuil09965172010-08-01 14:32:42 -03003136
Hans Verkuil2a863792011-01-11 14:45:03 -03003137 /* Reset the 'is_new' flags of the cluster */
Hans Verkuil09965172010-08-01 14:32:42 -03003138 for (j = 0; j < master->ncontrols; j++)
3139 if (master->cluster[j])
Hans Verkuil2a863792011-01-11 14:45:03 -03003140 master->cluster[j]->is_new = 0;
Hans Verkuil09965172010-08-01 14:32:42 -03003141
Hans Verkuil5626b8c2011-08-26 07:53:53 -03003142 /* For volatile autoclusters that are currently in auto mode
3143 we need to discover if it will be set to manual mode.
3144 If so, then we have to copy the current volatile values
3145 first since those will become the new manual values (which
3146 may be overwritten by explicit new values from this set
3147 of controls). */
3148 if (master->is_auto && master->has_volatiles &&
3149 !is_cur_manual(master)) {
3150 /* Pick an initial non-manual value */
3151 s32 new_auto_val = master->manual_mode_value + 1;
3152 u32 tmp_idx = idx;
3153
3154 do {
3155 /* Check if the auto control is part of the
3156 list, and remember the new value. */
3157 if (helpers[tmp_idx].ctrl == master)
3158 new_auto_val = cs->controls[tmp_idx].value;
3159 tmp_idx = helpers[tmp_idx].next;
3160 } while (tmp_idx);
3161 /* If the new value == the manual value, then copy
3162 the current volatile values. */
3163 if (new_auto_val == master->manual_mode_value)
3164 update_from_auto_cluster(master);
3165 }
3166
Hans Verkuil09965172010-08-01 14:32:42 -03003167 /* Copy the new caller-supplied control values.
Hans Verkuil2a863792011-01-11 14:45:03 -03003168 user_to_new() sets 'is_new' to 1. */
Hans Verkuileb5b16e2011-06-14 10:04:06 -03003169 do {
Hans Verkuil7a7f1ab2014-09-22 11:08:55 -03003170 struct v4l2_ctrl *ctrl = helpers[idx].ctrl;
3171
3172 ret = user_to_new(cs->controls + idx, ctrl);
3173 if (!ret && ctrl->is_ptr)
3174 ret = validate_new(ctrl, ctrl->p_new);
Hans Verkuileb5b16e2011-06-14 10:04:06 -03003175 idx = helpers[idx].next;
3176 } while (!ret && idx);
Hans Verkuil09965172010-08-01 14:32:42 -03003177
3178 if (!ret)
Sylwester Nawrocki2ccbe772013-01-19 15:51:55 -03003179 ret = try_or_set_cluster(fh, master, set, 0);
Hans Verkuil09965172010-08-01 14:32:42 -03003180
3181 /* Copy the new values back to userspace. */
Hans Verkuileb5b16e2011-06-14 10:04:06 -03003182 if (!ret) {
3183 idx = i;
3184 do {
Hans Verkuiladf41b92011-07-05 06:56:37 -03003185 ret = new_to_user(cs->controls + idx,
Hans Verkuile6402582011-06-14 10:56:42 -03003186 helpers[idx].ctrl);
Hans Verkuileb5b16e2011-06-14 10:04:06 -03003187 idx = helpers[idx].next;
3188 } while (!ret && idx);
3189 }
3190 v4l2_ctrl_unlock(master);
Hans Verkuil09965172010-08-01 14:32:42 -03003191 }
Hans Verkuil09965172010-08-01 14:32:42 -03003192
Hans Verkuil09965172010-08-01 14:32:42 -03003193 if (cs->count > ARRAY_SIZE(helper))
3194 kfree(helpers);
3195 return ret;
3196}
3197
3198int v4l2_try_ext_ctrls(struct v4l2_ctrl_handler *hdl, struct v4l2_ext_controls *cs)
3199{
Hans Verkuilab892ba2011-06-07 06:47:18 -03003200 return try_set_ext_ctrls(NULL, hdl, cs, false);
Hans Verkuil09965172010-08-01 14:32:42 -03003201}
3202EXPORT_SYMBOL(v4l2_try_ext_ctrls);
3203
Hans Verkuilab892ba2011-06-07 06:47:18 -03003204int v4l2_s_ext_ctrls(struct v4l2_fh *fh, struct v4l2_ctrl_handler *hdl,
3205 struct v4l2_ext_controls *cs)
Hans Verkuil09965172010-08-01 14:32:42 -03003206{
Hans Verkuilab892ba2011-06-07 06:47:18 -03003207 return try_set_ext_ctrls(fh, hdl, cs, true);
Hans Verkuil09965172010-08-01 14:32:42 -03003208}
3209EXPORT_SYMBOL(v4l2_s_ext_ctrls);
3210
3211int v4l2_subdev_try_ext_ctrls(struct v4l2_subdev *sd, struct v4l2_ext_controls *cs)
3212{
Hans Verkuilab892ba2011-06-07 06:47:18 -03003213 return try_set_ext_ctrls(NULL, sd->ctrl_handler, cs, false);
Hans Verkuil09965172010-08-01 14:32:42 -03003214}
3215EXPORT_SYMBOL(v4l2_subdev_try_ext_ctrls);
3216
3217int v4l2_subdev_s_ext_ctrls(struct v4l2_subdev *sd, struct v4l2_ext_controls *cs)
3218{
Hans Verkuilab892ba2011-06-07 06:47:18 -03003219 return try_set_ext_ctrls(NULL, sd->ctrl_handler, cs, true);
Hans Verkuil09965172010-08-01 14:32:42 -03003220}
3221EXPORT_SYMBOL(v4l2_subdev_s_ext_ctrls);
3222
3223/* Helper function for VIDIOC_S_CTRL compatibility */
Hans Verkuil7a7f1ab2014-09-22 11:08:55 -03003224static int set_ctrl(struct v4l2_fh *fh, struct v4l2_ctrl *ctrl, u32 ch_flags)
Hans Verkuil09965172010-08-01 14:32:42 -03003225{
3226 struct v4l2_ctrl *master = ctrl->cluster[0];
Hans Verkuil7a7f1ab2014-09-22 11:08:55 -03003227 int ret;
Hans Verkuil09965172010-08-01 14:32:42 -03003228 int i;
3229
Hans Verkuil2a863792011-01-11 14:45:03 -03003230 /* Reset the 'is_new' flags of the cluster */
Hans Verkuil09965172010-08-01 14:32:42 -03003231 for (i = 0; i < master->ncontrols; i++)
3232 if (master->cluster[i])
Hans Verkuil2a863792011-01-11 14:45:03 -03003233 master->cluster[i]->is_new = 0;
Hans Verkuil09965172010-08-01 14:32:42 -03003234
Hans Verkuil7a7f1ab2014-09-22 11:08:55 -03003235 ret = validate_new(ctrl, ctrl->p_new);
3236 if (ret)
3237 return ret;
Hans Verkuil5d0360a2014-07-21 10:45:42 -03003238
Hans Verkuil5626b8c2011-08-26 07:53:53 -03003239 /* For autoclusters with volatiles that are switched from auto to
3240 manual mode we have to update the current volatile values since
3241 those will become the initial manual values after such a switch. */
3242 if (master->is_auto && master->has_volatiles && ctrl == master &&
Hans Verkuil5d0360a2014-07-21 10:45:42 -03003243 !is_cur_manual(master) && ctrl->val == master->manual_mode_value)
Hans Verkuil5626b8c2011-08-26 07:53:53 -03003244 update_from_auto_cluster(master);
Laurent Pinchart03d52852012-07-23 09:15:21 -03003245
Hans Verkuil5d0360a2014-07-21 10:45:42 -03003246 ctrl->is_new = 1;
Sylwester Nawrocki2ccbe772013-01-19 15:51:55 -03003247 return try_or_set_cluster(fh, master, true, ch_flags);
3248}
Laurent Pinchart03d52852012-07-23 09:15:21 -03003249
Sylwester Nawrocki2ccbe772013-01-19 15:51:55 -03003250/* Helper function for VIDIOC_S_CTRL compatibility */
3251static int set_ctrl_lock(struct v4l2_fh *fh, struct v4l2_ctrl *ctrl,
3252 struct v4l2_ext_control *c)
3253{
Hans Verkuil7a7f1ab2014-09-22 11:08:55 -03003254 int ret;
Sylwester Nawrocki2ccbe772013-01-19 15:51:55 -03003255
Hans Verkuil7a7f1ab2014-09-22 11:08:55 -03003256 v4l2_ctrl_lock(ctrl);
3257 user_to_new(c, ctrl);
3258 ret = set_ctrl(fh, ctrl, 0);
3259 if (!ret)
3260 cur_to_user(c, ctrl);
3261 v4l2_ctrl_unlock(ctrl);
Hans Verkuil09965172010-08-01 14:32:42 -03003262 return ret;
3263}
3264
Hans Verkuilab892ba2011-06-07 06:47:18 -03003265int v4l2_s_ctrl(struct v4l2_fh *fh, struct v4l2_ctrl_handler *hdl,
3266 struct v4l2_control *control)
Hans Verkuil09965172010-08-01 14:32:42 -03003267{
3268 struct v4l2_ctrl *ctrl = v4l2_ctrl_find(hdl, control->id);
Hans Verkuil7a7f1ab2014-09-22 11:08:55 -03003269 struct v4l2_ext_control c = { control->id };
Laurent Pinchart03d52852012-07-23 09:15:21 -03003270 int ret;
Hans Verkuil09965172010-08-01 14:32:42 -03003271
Hans Verkuild9a25472014-06-12 07:54:16 -03003272 if (ctrl == NULL || !ctrl->is_int)
Hans Verkuil09965172010-08-01 14:32:42 -03003273 return -EINVAL;
3274
Hans Verkuil7ebbc392011-06-07 04:50:31 -03003275 if (ctrl->flags & V4L2_CTRL_FLAG_READ_ONLY)
3276 return -EACCES;
3277
Laurent Pinchart03d52852012-07-23 09:15:21 -03003278 c.value = control->value;
Sylwester Nawrocki2ccbe772013-01-19 15:51:55 -03003279 ret = set_ctrl_lock(fh, ctrl, &c);
Laurent Pinchart03d52852012-07-23 09:15:21 -03003280 control->value = c.value;
3281 return ret;
Hans Verkuil09965172010-08-01 14:32:42 -03003282}
3283EXPORT_SYMBOL(v4l2_s_ctrl);
3284
3285int v4l2_subdev_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *control)
3286{
Hans Verkuilab892ba2011-06-07 06:47:18 -03003287 return v4l2_s_ctrl(NULL, sd->ctrl_handler, control);
Hans Verkuil09965172010-08-01 14:32:42 -03003288}
3289EXPORT_SYMBOL(v4l2_subdev_s_ctrl);
3290
Sakari Ailus0c4348a2014-06-12 13:09:42 -03003291int __v4l2_ctrl_s_ctrl(struct v4l2_ctrl *ctrl, s32 val)
Hans Verkuil09965172010-08-01 14:32:42 -03003292{
Sakari Ailus0c4348a2014-06-12 13:09:42 -03003293 lockdep_assert_held(ctrl->handler->lock);
Laurent Pinchart03d52852012-07-23 09:15:21 -03003294
Hans Verkuil09965172010-08-01 14:32:42 -03003295 /* It's a driver bug if this happens. */
Hans Verkuild9a25472014-06-12 07:54:16 -03003296 WARN_ON(!ctrl->is_int);
Hans Verkuil5d0360a2014-07-21 10:45:42 -03003297 ctrl->val = val;
Hans Verkuil7a7f1ab2014-09-22 11:08:55 -03003298 return set_ctrl(NULL, ctrl, 0);
Sakari Ailus0c4348a2014-06-12 13:09:42 -03003299}
3300EXPORT_SYMBOL(__v4l2_ctrl_s_ctrl);
3301
3302int __v4l2_ctrl_s_ctrl_int64(struct v4l2_ctrl *ctrl, s64 val)
Laurent Pinchart03d52852012-07-23 09:15:21 -03003303{
Sakari Ailus0c4348a2014-06-12 13:09:42 -03003304 lockdep_assert_held(ctrl->handler->lock);
Laurent Pinchart03d52852012-07-23 09:15:21 -03003305
3306 /* It's a driver bug if this happens. */
Hans Verkuil998e7652014-06-10 07:55:00 -03003307 WARN_ON(ctrl->is_ptr || ctrl->type != V4L2_CTRL_TYPE_INTEGER64);
Hans Verkuil5d0360a2014-07-21 10:45:42 -03003308 *ctrl->p_new.p_s64 = val;
Hans Verkuil7a7f1ab2014-09-22 11:08:55 -03003309 return set_ctrl(NULL, ctrl, 0);
Laurent Pinchart03d52852012-07-23 09:15:21 -03003310}
Sakari Ailus0c4348a2014-06-12 13:09:42 -03003311EXPORT_SYMBOL(__v4l2_ctrl_s_ctrl_int64);
Laurent Pinchart03d52852012-07-23 09:15:21 -03003312
Hans Verkuil5d0360a2014-07-21 10:45:42 -03003313int __v4l2_ctrl_s_ctrl_string(struct v4l2_ctrl *ctrl, const char *s)
3314{
3315 lockdep_assert_held(ctrl->handler->lock);
3316
3317 /* It's a driver bug if this happens. */
3318 WARN_ON(ctrl->type != V4L2_CTRL_TYPE_STRING);
3319 strlcpy(ctrl->p_new.p_char, s, ctrl->maximum + 1);
Hans Verkuil7a7f1ab2014-09-22 11:08:55 -03003320 return set_ctrl(NULL, ctrl, 0);
Hans Verkuil5d0360a2014-07-21 10:45:42 -03003321}
3322EXPORT_SYMBOL(__v4l2_ctrl_s_ctrl_string);
3323
Hans Verkuil8ac7a942012-09-07 04:46:39 -03003324void v4l2_ctrl_notify(struct v4l2_ctrl *ctrl, v4l2_ctrl_notify_fnc notify, void *priv)
3325{
3326 if (ctrl == NULL)
3327 return;
3328 if (notify == NULL) {
3329 ctrl->call_notify = 0;
3330 return;
3331 }
3332 if (WARN_ON(ctrl->handler->notify && ctrl->handler->notify != notify))
3333 return;
3334 ctrl->handler->notify = notify;
3335 ctrl->handler->notify_priv = priv;
3336 ctrl->call_notify = 1;
3337}
3338EXPORT_SYMBOL(v4l2_ctrl_notify);
3339
Sakari Ailus5a573922014-06-12 13:09:40 -03003340int __v4l2_ctrl_modify_range(struct v4l2_ctrl *ctrl,
Hans Verkuil0ba2aeb2014-04-16 09:41:25 -03003341 s64 min, s64 max, u64 step, s64 def)
Sylwester Nawrocki2ccbe772013-01-19 15:51:55 -03003342{
Ricardo Ribalda95ad7ff2015-11-11 09:58:34 -02003343 bool value_changed;
3344 bool range_changed = false;
Hans Verkuil302ab7c2014-06-10 07:06:50 -03003345 int ret;
Sylwester Nawrocki2ccbe772013-01-19 15:51:55 -03003346
Sakari Ailus5a573922014-06-12 13:09:40 -03003347 lockdep_assert_held(ctrl->handler->lock);
3348
Sylwester Nawrocki2ccbe772013-01-19 15:51:55 -03003349 switch (ctrl->type) {
3350 case V4L2_CTRL_TYPE_INTEGER:
Hans Verkuil0ba2aeb2014-04-16 09:41:25 -03003351 case V4L2_CTRL_TYPE_INTEGER64:
Sylwester Nawrocki2ccbe772013-01-19 15:51:55 -03003352 case V4L2_CTRL_TYPE_BOOLEAN:
3353 case V4L2_CTRL_TYPE_MENU:
3354 case V4L2_CTRL_TYPE_INTEGER_MENU:
3355 case V4L2_CTRL_TYPE_BITMASK:
Hans Verkuildda4a4d2014-06-10 07:30:04 -03003356 case V4L2_CTRL_TYPE_U8:
3357 case V4L2_CTRL_TYPE_U16:
Hans Verkuil811c5082014-07-21 10:45:37 -03003358 case V4L2_CTRL_TYPE_U32:
Hans Verkuil302ab7c2014-06-10 07:06:50 -03003359 if (ctrl->is_array)
3360 return -EINVAL;
3361 ret = check_range(ctrl->type, min, max, step, def);
Sylwester Nawrocki2ccbe772013-01-19 15:51:55 -03003362 if (ret)
3363 return ret;
3364 break;
3365 default:
3366 return -EINVAL;
3367 }
Ricardo Ribalda95ad7ff2015-11-11 09:58:34 -02003368 if ((ctrl->minimum != min) || (ctrl->maximum != max) ||
3369 (ctrl->step != step) || ctrl->default_value != def) {
3370 range_changed = true;
3371 ctrl->minimum = min;
3372 ctrl->maximum = max;
3373 ctrl->step = step;
3374 ctrl->default_value = def;
3375 }
Hans Verkuil7a7f1ab2014-09-22 11:08:55 -03003376 cur_to_new(ctrl);
3377 if (validate_new(ctrl, ctrl->p_new)) {
3378 if (ctrl->type == V4L2_CTRL_TYPE_INTEGER64)
3379 *ctrl->p_new.p_s64 = def;
3380 else
3381 *ctrl->p_new.p_s32 = def;
3382 }
3383
3384 if (ctrl->type == V4L2_CTRL_TYPE_INTEGER64)
Ricardo Ribalda95ad7ff2015-11-11 09:58:34 -02003385 value_changed = *ctrl->p_new.p_s64 != *ctrl->p_cur.p_s64;
Hans Verkuil7a7f1ab2014-09-22 11:08:55 -03003386 else
Ricardo Ribalda95ad7ff2015-11-11 09:58:34 -02003387 value_changed = *ctrl->p_new.p_s32 != *ctrl->p_cur.p_s32;
3388 if (value_changed)
Hans Verkuil7a7f1ab2014-09-22 11:08:55 -03003389 ret = set_ctrl(NULL, ctrl, V4L2_EVENT_CTRL_CH_RANGE);
Ricardo Ribalda95ad7ff2015-11-11 09:58:34 -02003390 else if (range_changed)
Sylwester Nawrocki2ccbe772013-01-19 15:51:55 -03003391 send_event(NULL, ctrl, V4L2_EVENT_CTRL_CH_RANGE);
Sylwester Nawrocki2ccbe772013-01-19 15:51:55 -03003392 return ret;
3393}
Sakari Ailus5a573922014-06-12 13:09:40 -03003394EXPORT_SYMBOL(__v4l2_ctrl_modify_range);
Sylwester Nawrocki2ccbe772013-01-19 15:51:55 -03003395
Hans Verkuil6e6d76c2012-05-07 16:53:20 -03003396static int v4l2_ctrl_add_event(struct v4l2_subscribed_event *sev, unsigned elems)
Hans Verkuil6e239392011-06-07 11:13:44 -03003397{
Hans de Goede3e3661492012-04-08 12:59:47 -03003398 struct v4l2_ctrl *ctrl = v4l2_ctrl_find(sev->fh->ctrl_handler, sev->id);
3399
3400 if (ctrl == NULL)
3401 return -EINVAL;
3402
Hans Verkuil6e239392011-06-07 11:13:44 -03003403 v4l2_ctrl_lock(ctrl);
Hans Verkuil77068d32011-06-13 18:55:58 -03003404 list_add_tail(&sev->node, &ctrl->ev_subs);
Hans Verkuil6e239392011-06-07 11:13:44 -03003405 if (ctrl->type != V4L2_CTRL_TYPE_CTRL_CLASS &&
Hans Verkuil77068d32011-06-13 18:55:58 -03003406 (sev->flags & V4L2_EVENT_SUB_FL_SEND_INITIAL)) {
Hans Verkuil6e239392011-06-07 11:13:44 -03003407 struct v4l2_event ev;
Hans Verkuilc12fcfd2011-06-14 02:42:45 -03003408 u32 changes = V4L2_EVENT_CTRL_CH_FLAGS;
Hans Verkuil6e239392011-06-07 11:13:44 -03003409
Hans Verkuilc12fcfd2011-06-14 02:42:45 -03003410 if (!(ctrl->flags & V4L2_CTRL_FLAG_WRITE_ONLY))
3411 changes |= V4L2_EVENT_CTRL_CH_VALUE;
3412 fill_event(&ev, ctrl, changes);
Hans Verkuil6e6d76c2012-05-07 16:53:20 -03003413 /* Mark the queue as active, allowing this initial
3414 event to be accepted. */
3415 sev->elems = elems;
Hans Verkuil77068d32011-06-13 18:55:58 -03003416 v4l2_event_queue_fh(sev->fh, &ev);
Hans Verkuil6e239392011-06-07 11:13:44 -03003417 }
3418 v4l2_ctrl_unlock(ctrl);
Hans de Goede3e3661492012-04-08 12:59:47 -03003419 return 0;
Hans Verkuil6e239392011-06-07 11:13:44 -03003420}
Hans Verkuil6e239392011-06-07 11:13:44 -03003421
Hans de Goede3e3661492012-04-08 12:59:47 -03003422static void v4l2_ctrl_del_event(struct v4l2_subscribed_event *sev)
Hans Verkuil6e239392011-06-07 11:13:44 -03003423{
Hans de Goede3e3661492012-04-08 12:59:47 -03003424 struct v4l2_ctrl *ctrl = v4l2_ctrl_find(sev->fh->ctrl_handler, sev->id);
3425
Hans Verkuil6e239392011-06-07 11:13:44 -03003426 v4l2_ctrl_lock(ctrl);
Hans Verkuil77068d32011-06-13 18:55:58 -03003427 list_del(&sev->node);
Hans Verkuil6e239392011-06-07 11:13:44 -03003428 v4l2_ctrl_unlock(ctrl);
3429}
Hans de Goede3e3661492012-04-08 12:59:47 -03003430
3431void v4l2_ctrl_replace(struct v4l2_event *old, const struct v4l2_event *new)
3432{
3433 u32 old_changes = old->u.ctrl.changes;
3434
3435 old->u.ctrl = new->u.ctrl;
3436 old->u.ctrl.changes |= old_changes;
3437}
3438EXPORT_SYMBOL(v4l2_ctrl_replace);
3439
3440void v4l2_ctrl_merge(const struct v4l2_event *old, struct v4l2_event *new)
3441{
3442 new->u.ctrl.changes |= old->u.ctrl.changes;
3443}
3444EXPORT_SYMBOL(v4l2_ctrl_merge);
3445
3446const struct v4l2_subscribed_event_ops v4l2_ctrl_sub_ev_ops = {
3447 .add = v4l2_ctrl_add_event,
3448 .del = v4l2_ctrl_del_event,
3449 .replace = v4l2_ctrl_replace,
3450 .merge = v4l2_ctrl_merge,
3451};
3452EXPORT_SYMBOL(v4l2_ctrl_sub_ev_ops);
Hans Verkuile2ecb252012-02-02 08:20:53 -03003453
3454int v4l2_ctrl_log_status(struct file *file, void *fh)
3455{
3456 struct video_device *vfd = video_devdata(file);
3457 struct v4l2_fh *vfh = file->private_data;
3458
3459 if (test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) && vfd->v4l2_dev)
3460 v4l2_ctrl_handler_log_status(vfh->ctrl_handler,
3461 vfd->v4l2_dev->name);
3462 return 0;
3463}
3464EXPORT_SYMBOL(v4l2_ctrl_log_status);
Hans Verkuila26243b2012-01-27 16:18:42 -03003465
3466int v4l2_ctrl_subscribe_event(struct v4l2_fh *fh,
Hans Verkuil85f5fe32012-09-04 11:46:09 -03003467 const struct v4l2_event_subscription *sub)
Hans Verkuila26243b2012-01-27 16:18:42 -03003468{
3469 if (sub->type == V4L2_EVENT_CTRL)
Hans de Goede3e3661492012-04-08 12:59:47 -03003470 return v4l2_event_subscribe(fh, sub, 0, &v4l2_ctrl_sub_ev_ops);
Hans Verkuila26243b2012-01-27 16:18:42 -03003471 return -EINVAL;
3472}
3473EXPORT_SYMBOL(v4l2_ctrl_subscribe_event);
3474
Sylwester Nawrocki22fa4272013-01-22 19:00:23 -03003475int v4l2_ctrl_subdev_subscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
3476 struct v4l2_event_subscription *sub)
3477{
3478 if (!sd->ctrl_handler)
3479 return -EINVAL;
3480 return v4l2_ctrl_subscribe_event(fh, sub);
3481}
3482EXPORT_SYMBOL(v4l2_ctrl_subdev_subscribe_event);
3483
Hans Verkuila26243b2012-01-27 16:18:42 -03003484unsigned int v4l2_ctrl_poll(struct file *file, struct poll_table_struct *wait)
3485{
3486 struct v4l2_fh *fh = file->private_data;
3487
3488 if (v4l2_event_pending(fh))
3489 return POLLPRI;
3490 poll_wait(file, &fh->wait, wait);
3491 return 0;
3492}
3493EXPORT_SYMBOL(v4l2_ctrl_poll);