blob: adc2147fcff7f7eacf43ad8ecfdbfb02c1b6690c [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",
Stanimir Varbanov15d6e912016-08-16 06:09:42 -0300364 "Stereo High",
Kamil Debski064f5092011-06-14 10:46:22 -0300365 "Multiview High",
366 NULL,
367 };
368 static const char * const vui_sar_idc[] = {
369 "Unspecified",
370 "1:1",
371 "12:11",
372 "10:11",
373 "16:11",
374 "40:33",
375 "24:11",
376 "20:11",
377 "32:11",
378 "80:33",
379 "18:11",
380 "15:11",
381 "64:33",
382 "160:99",
383 "4:3",
384 "3:2",
385 "2:1",
386 "Extended SAR",
387 NULL,
388 };
Arun Kumar K2e81dde2012-10-03 22:19:06 -0300389 static const char * const h264_fp_arrangement_type[] = {
390 "Checkerboard",
391 "Column",
392 "Row",
393 "Side by Side",
394 "Top Bottom",
395 "Temporal",
396 NULL,
397 };
398 static const char * const h264_fmo_map_type[] = {
399 "Interleaved Slices",
400 "Scattered Slices",
401 "Foreground with Leftover",
402 "Box Out",
403 "Raster Scan",
404 "Wipe Scan",
405 "Explicit",
406 NULL,
407 };
Kamil Debski064f5092011-06-14 10:46:22 -0300408 static const char * const mpeg_mpeg4_level[] = {
409 "0",
410 "0b",
411 "1",
412 "2",
413 "3",
414 "3b",
415 "4",
416 "5",
417 NULL,
418 };
419 static const char * const mpeg4_profile[] = {
420 "Simple",
Hans Verkuilf769c262012-03-02 04:20:19 -0300421 "Advanced Simple",
Kamil Debski064f5092011-06-14 10:46:22 -0300422 "Core",
423 "Simple Scalable",
Jonathan McCrohan39c1cb22013-10-20 21:34:01 -0300424 "Advanced Coding Efficiency",
Kamil Debski064f5092011-06-14 10:46:22 -0300425 NULL,
426 };
427
Arun Kumar Kbc9028e2013-07-09 01:24:41 -0300428 static const char * const vpx_golden_frame_sel[] = {
429 "Use Previous Frame",
430 "Use Previous Specific Frame",
431 NULL,
432 };
433
Sakari Ailus0b159ac2011-03-21 12:52:51 -0300434 static const char * const flash_led_mode[] = {
435 "Off",
436 "Flash",
437 "Torch",
438 NULL,
439 };
440 static const char * const flash_strobe_source[] = {
441 "Software",
442 "External",
443 NULL,
444 };
Hans Verkuil09965172010-08-01 14:32:42 -0300445
Sylwester Nawrockic7361ae2012-01-20 15:37:44 -0300446 static const char * const jpeg_chroma_subsampling[] = {
447 "4:4:4",
448 "4:2:2",
449 "4:2:0",
450 "4:1:1",
451 "4:1:0",
452 "Gray",
453 NULL,
454 };
Hans Verkuil977ebec2012-07-03 06:14:37 -0300455 static const char * const dv_tx_mode[] = {
456 "DVI-D",
457 "HDMI",
458 NULL,
459 };
460 static const char * const dv_rgb_range[] = {
461 "Automatic",
462 "RGB limited range (16-235)",
463 "RGB full range (0-255)",
464 NULL,
465 };
Hans Verkuil45cc29a2016-01-27 11:31:39 -0200466 static const char * const dv_it_content_type[] = {
467 "Graphics",
468 "Photo",
469 "Cinema",
470 "Game",
471 "No IT Content",
472 NULL,
473 };
Hans Verkuila77b4fc2014-03-28 13:00:08 -0300474 static const char * const detect_md_mode[] = {
475 "Disabled",
476 "Global",
477 "Threshold Grid",
478 "Region Grid",
479 NULL,
480 };
Hans Verkuil977ebec2012-07-03 06:14:37 -0300481
Sylwester Nawrockic7361ae2012-01-20 15:37:44 -0300482
Hans Verkuil09965172010-08-01 14:32:42 -0300483 switch (id) {
484 case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
485 return mpeg_audio_sampling_freq;
486 case V4L2_CID_MPEG_AUDIO_ENCODING:
487 return mpeg_audio_encoding;
488 case V4L2_CID_MPEG_AUDIO_L1_BITRATE:
489 return mpeg_audio_l1_bitrate;
490 case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
491 return mpeg_audio_l2_bitrate;
492 case V4L2_CID_MPEG_AUDIO_L3_BITRATE:
493 return mpeg_audio_l3_bitrate;
494 case V4L2_CID_MPEG_AUDIO_AC3_BITRATE:
495 return mpeg_audio_ac3_bitrate;
496 case V4L2_CID_MPEG_AUDIO_MODE:
497 return mpeg_audio_mode;
498 case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION:
499 return mpeg_audio_mode_extension;
500 case V4L2_CID_MPEG_AUDIO_EMPHASIS:
501 return mpeg_audio_emphasis;
502 case V4L2_CID_MPEG_AUDIO_CRC:
503 return mpeg_audio_crc;
Hans Verkuil24c19a22011-12-15 10:46:16 -0300504 case V4L2_CID_MPEG_AUDIO_DEC_PLAYBACK:
505 case V4L2_CID_MPEG_AUDIO_DEC_MULTILINGUAL_PLAYBACK:
506 return mpeg_audio_dec_playback;
Hans Verkuil09965172010-08-01 14:32:42 -0300507 case V4L2_CID_MPEG_VIDEO_ENCODING:
508 return mpeg_video_encoding;
509 case V4L2_CID_MPEG_VIDEO_ASPECT:
510 return mpeg_video_aspect;
511 case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
512 return mpeg_video_bitrate_mode;
513 case V4L2_CID_MPEG_STREAM_TYPE:
514 return mpeg_stream_type;
515 case V4L2_CID_MPEG_STREAM_VBI_FMT:
516 return mpeg_stream_vbi_fmt;
517 case V4L2_CID_POWER_LINE_FREQUENCY:
518 return camera_power_line_frequency;
519 case V4L2_CID_EXPOSURE_AUTO:
520 return camera_exposure_auto;
Sylwester Nawrockicf072132012-04-30 04:34:10 -0300521 case V4L2_CID_EXPOSURE_METERING:
522 return camera_exposure_metering;
Sylwester Nawrocki2272ab62012-05-11 06:37:03 -0300523 case V4L2_CID_AUTO_FOCUS_RANGE:
524 return camera_auto_focus_range;
Hans Verkuil09965172010-08-01 14:32:42 -0300525 case V4L2_CID_COLORFX:
526 return colorfx;
Sylwester Nawrockie40a0572012-03-06 07:04:26 -0300527 case V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE:
528 return auto_n_preset_white_balance;
Sylwester Nawrocki7f84ad82012-05-01 17:39:45 -0300529 case V4L2_CID_ISO_SENSITIVITY_AUTO:
530 return camera_iso_sensitivity_auto;
Sylwester Nawrocki0bf6b7d2012-04-16 10:45:44 -0300531 case V4L2_CID_SCENE_MODE:
532 return scene_mode;
Hans Verkuil09965172010-08-01 14:32:42 -0300533 case V4L2_CID_TUNE_PREEMPHASIS:
Andrey Smirnovaec330a2013-03-26 22:47:23 -0300534 return tune_emphasis;
535 case V4L2_CID_TUNE_DEEMPHASIS:
536 return tune_emphasis;
Sakari Ailus0b159ac2011-03-21 12:52:51 -0300537 case V4L2_CID_FLASH_LED_MODE:
538 return flash_led_mode;
539 case V4L2_CID_FLASH_STROBE_SOURCE:
540 return flash_strobe_source;
Kamil Debski064f5092011-06-14 10:46:22 -0300541 case V4L2_CID_MPEG_VIDEO_HEADER_MODE:
542 return header_mode;
543 case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE:
544 return multi_slice;
545 case V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE:
546 return entropy_mode;
547 case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
548 return mpeg_h264_level;
549 case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE:
550 return h264_loop_filter;
551 case V4L2_CID_MPEG_VIDEO_H264_PROFILE:
552 return h264_profile;
553 case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC:
554 return vui_sar_idc;
Arun Kumar K2e81dde2012-10-03 22:19:06 -0300555 case V4L2_CID_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE:
556 return h264_fp_arrangement_type;
557 case V4L2_CID_MPEG_VIDEO_H264_FMO_MAP_TYPE:
558 return h264_fmo_map_type;
Kamil Debski064f5092011-06-14 10:46:22 -0300559 case V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL:
560 return mpeg_mpeg4_level;
561 case V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE:
562 return mpeg4_profile;
Arun Kumar Kbc9028e2013-07-09 01:24:41 -0300563 case V4L2_CID_MPEG_VIDEO_VPX_GOLDEN_FRAME_SEL:
564 return vpx_golden_frame_sel;
Sylwester Nawrockic7361ae2012-01-20 15:37:44 -0300565 case V4L2_CID_JPEG_CHROMA_SUBSAMPLING:
566 return jpeg_chroma_subsampling;
Hans Verkuil977ebec2012-07-03 06:14:37 -0300567 case V4L2_CID_DV_TX_MODE:
568 return dv_tx_mode;
569 case V4L2_CID_DV_TX_RGB_RANGE:
570 case V4L2_CID_DV_RX_RGB_RANGE:
571 return dv_rgb_range;
Hans Verkuil45cc29a2016-01-27 11:31:39 -0200572 case V4L2_CID_DV_TX_IT_CONTENT_TYPE:
573 case V4L2_CID_DV_RX_IT_CONTENT_TYPE:
574 return dv_it_content_type;
Hans Verkuila77b4fc2014-03-28 13:00:08 -0300575 case V4L2_CID_DETECT_MD_MODE:
576 return detect_md_mode;
Sylwester Nawrockic7361ae2012-01-20 15:37:44 -0300577
Hans Verkuil09965172010-08-01 14:32:42 -0300578 default:
579 return NULL;
580 }
581}
582EXPORT_SYMBOL(v4l2_ctrl_get_menu);
583
Arun Kumar Kbc9028e2013-07-09 01:24:41 -0300584#define __v4l2_qmenu_int_len(arr, len) ({ *(len) = ARRAY_SIZE(arr); arr; })
Sylwester Nawrockid1e9b7c2013-07-09 01:24:40 -0300585/*
586 * Returns NULL or an s64 type array containing the menu for given
587 * control ID. The total number of the menu items is returned in @len.
588 */
Sylwester Nawrocki4eed9b32013-10-14 20:08:03 -0300589const s64 *v4l2_ctrl_get_int_menu(u32 id, u32 *len)
Sylwester Nawrockid1e9b7c2013-07-09 01:24:40 -0300590{
Sylwester Nawrocki4eed9b32013-10-14 20:08:03 -0300591 static const s64 qmenu_int_vpx_num_partitions[] = {
Arun Kumar Kbc9028e2013-07-09 01:24:41 -0300592 1, 2, 4, 8,
593 };
594
Sylwester Nawrocki4eed9b32013-10-14 20:08:03 -0300595 static const s64 qmenu_int_vpx_num_ref_frames[] = {
Arun Kumar Kbc9028e2013-07-09 01:24:41 -0300596 1, 2, 3,
597 };
598
Sylwester Nawrockid1e9b7c2013-07-09 01:24:40 -0300599 switch (id) {
Arun Kumar Kbc9028e2013-07-09 01:24:41 -0300600 case V4L2_CID_MPEG_VIDEO_VPX_NUM_PARTITIONS:
601 return __v4l2_qmenu_int_len(qmenu_int_vpx_num_partitions, len);
602 case V4L2_CID_MPEG_VIDEO_VPX_NUM_REF_FRAMES:
603 return __v4l2_qmenu_int_len(qmenu_int_vpx_num_ref_frames, len);
Sylwester Nawrockid1e9b7c2013-07-09 01:24:40 -0300604 default:
605 *len = 0;
606 return NULL;
Joe Perches2028c712013-10-08 20:29:08 -0300607 }
Sylwester Nawrockid1e9b7c2013-07-09 01:24:40 -0300608}
609EXPORT_SYMBOL(v4l2_ctrl_get_int_menu);
610
Hans Verkuil09965172010-08-01 14:32:42 -0300611/* Return the control name. */
612const char *v4l2_ctrl_get_name(u32 id)
613{
614 switch (id) {
615 /* USER controls */
Hans Verkuil59253f22014-01-27 11:03:34 -0300616 /* Keep the order of the 'case's the same as in v4l2-controls.h! */
Mauro Carvalho Chehab6dd5aff2010-08-06 09:57:02 -0300617 case V4L2_CID_USER_CLASS: return "User Controls";
618 case V4L2_CID_BRIGHTNESS: return "Brightness";
619 case V4L2_CID_CONTRAST: return "Contrast";
620 case V4L2_CID_SATURATION: return "Saturation";
621 case V4L2_CID_HUE: return "Hue";
622 case V4L2_CID_AUDIO_VOLUME: return "Volume";
623 case V4L2_CID_AUDIO_BALANCE: return "Balance";
624 case V4L2_CID_AUDIO_BASS: return "Bass";
625 case V4L2_CID_AUDIO_TREBLE: return "Treble";
626 case V4L2_CID_AUDIO_MUTE: return "Mute";
627 case V4L2_CID_AUDIO_LOUDNESS: return "Loudness";
Hans Verkuil09965172010-08-01 14:32:42 -0300628 case V4L2_CID_BLACK_LEVEL: return "Black Level";
629 case V4L2_CID_AUTO_WHITE_BALANCE: return "White Balance, Automatic";
630 case V4L2_CID_DO_WHITE_BALANCE: return "Do White Balance";
631 case V4L2_CID_RED_BALANCE: return "Red Balance";
632 case V4L2_CID_BLUE_BALANCE: return "Blue Balance";
633 case V4L2_CID_GAMMA: return "Gamma";
634 case V4L2_CID_EXPOSURE: return "Exposure";
635 case V4L2_CID_AUTOGAIN: return "Gain, Automatic";
636 case V4L2_CID_GAIN: return "Gain";
637 case V4L2_CID_HFLIP: return "Horizontal Flip";
638 case V4L2_CID_VFLIP: return "Vertical Flip";
Hans Verkuil09965172010-08-01 14:32:42 -0300639 case V4L2_CID_POWER_LINE_FREQUENCY: return "Power Line Frequency";
640 case V4L2_CID_HUE_AUTO: return "Hue, Automatic";
641 case V4L2_CID_WHITE_BALANCE_TEMPERATURE: return "White Balance Temperature";
642 case V4L2_CID_SHARPNESS: return "Sharpness";
643 case V4L2_CID_BACKLIGHT_COMPENSATION: return "Backlight Compensation";
644 case V4L2_CID_CHROMA_AGC: return "Chroma AGC";
Hans Verkuil09965172010-08-01 14:32:42 -0300645 case V4L2_CID_COLOR_KILLER: return "Color Killer";
646 case V4L2_CID_COLORFX: return "Color Effects";
647 case V4L2_CID_AUTOBRIGHTNESS: return "Brightness, Automatic";
648 case V4L2_CID_BAND_STOP_FILTER: return "Band-Stop Filter";
649 case V4L2_CID_ROTATE: return "Rotate";
650 case V4L2_CID_BG_COLOR: return "Background Color";
Hans Verkuil6c8d6112010-04-25 19:21:00 -0300651 case V4L2_CID_CHROMA_GAIN: return "Chroma Gain";
Jean-François Moine008d35f2010-09-13 07:04:49 -0300652 case V4L2_CID_ILLUMINATORS_1: return "Illuminator 1";
653 case V4L2_CID_ILLUMINATORS_2: return "Illuminator 2";
Hans Verkuilf08aacf2012-01-16 12:27:15 -0300654 case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE: return "Min Number of Capture Buffers";
655 case V4L2_CID_MIN_BUFFERS_FOR_OUTPUT: return "Min Number of Output Buffers";
Sylwester Nawrockicc1d3272011-11-14 08:48:18 -0300656 case V4L2_CID_ALPHA_COMPONENT: return "Alpha Component";
Sylwester Nawrocki6491d1a2012-04-02 06:40:19 -0300657 case V4L2_CID_COLORFX_CBCR: return "Color Effects, CbCr";
Hans Verkuil09965172010-08-01 14:32:42 -0300658
Arun Kumar Kbc9028e2013-07-09 01:24:41 -0300659 /* Codec controls */
660 /* The MPEG controls are applicable to all codec controls
661 * and the 'MPEG' part of the define is historical */
Hans Verkuil6c8d6112010-04-25 19:21:00 -0300662 /* Keep the order of the 'case's the same as in videodev2.h! */
Arun Kumar Kbc9028e2013-07-09 01:24:41 -0300663 case V4L2_CID_MPEG_CLASS: return "Codec Controls";
Mauro Carvalho Chehab6dd5aff2010-08-06 09:57:02 -0300664 case V4L2_CID_MPEG_STREAM_TYPE: return "Stream Type";
665 case V4L2_CID_MPEG_STREAM_PID_PMT: return "Stream PMT Program ID";
666 case V4L2_CID_MPEG_STREAM_PID_AUDIO: return "Stream Audio Program ID";
667 case V4L2_CID_MPEG_STREAM_PID_VIDEO: return "Stream Video Program ID";
668 case V4L2_CID_MPEG_STREAM_PID_PCR: return "Stream PCR Program ID";
Hans Verkuil6c8d6112010-04-25 19:21:00 -0300669 case V4L2_CID_MPEG_STREAM_PES_ID_AUDIO: return "Stream PES Audio ID";
670 case V4L2_CID_MPEG_STREAM_PES_ID_VIDEO: return "Stream PES Video ID";
671 case V4L2_CID_MPEG_STREAM_VBI_FMT: return "Stream VBI Format";
Hans Verkuil09965172010-08-01 14:32:42 -0300672 case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ: return "Audio Sampling Frequency";
Mauro Carvalho Chehab6dd5aff2010-08-06 09:57:02 -0300673 case V4L2_CID_MPEG_AUDIO_ENCODING: return "Audio Encoding";
674 case V4L2_CID_MPEG_AUDIO_L1_BITRATE: return "Audio Layer I Bitrate";
675 case V4L2_CID_MPEG_AUDIO_L2_BITRATE: return "Audio Layer II Bitrate";
676 case V4L2_CID_MPEG_AUDIO_L3_BITRATE: return "Audio Layer III Bitrate";
677 case V4L2_CID_MPEG_AUDIO_MODE: return "Audio Stereo Mode";
Hans Verkuil09965172010-08-01 14:32:42 -0300678 case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION: return "Audio Stereo Mode Extension";
Mauro Carvalho Chehab6dd5aff2010-08-06 09:57:02 -0300679 case V4L2_CID_MPEG_AUDIO_EMPHASIS: return "Audio Emphasis";
680 case V4L2_CID_MPEG_AUDIO_CRC: return "Audio CRC";
681 case V4L2_CID_MPEG_AUDIO_MUTE: return "Audio Mute";
682 case V4L2_CID_MPEG_AUDIO_AAC_BITRATE: return "Audio AAC Bitrate";
683 case V4L2_CID_MPEG_AUDIO_AC3_BITRATE: return "Audio AC-3 Bitrate";
Hans Verkuil24c19a22011-12-15 10:46:16 -0300684 case V4L2_CID_MPEG_AUDIO_DEC_PLAYBACK: return "Audio Playback";
685 case V4L2_CID_MPEG_AUDIO_DEC_MULTILINGUAL_PLAYBACK: return "Audio Multilingual Playback";
Mauro Carvalho Chehab6dd5aff2010-08-06 09:57:02 -0300686 case V4L2_CID_MPEG_VIDEO_ENCODING: return "Video Encoding";
687 case V4L2_CID_MPEG_VIDEO_ASPECT: return "Video Aspect";
688 case V4L2_CID_MPEG_VIDEO_B_FRAMES: return "Video B Frames";
689 case V4L2_CID_MPEG_VIDEO_GOP_SIZE: return "Video GOP Size";
690 case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE: return "Video GOP Closure";
691 case V4L2_CID_MPEG_VIDEO_PULLDOWN: return "Video Pulldown";
692 case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: return "Video Bitrate Mode";
693 case V4L2_CID_MPEG_VIDEO_BITRATE: return "Video Bitrate";
694 case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK: return "Video Peak Bitrate";
Hans Verkuil09965172010-08-01 14:32:42 -0300695 case V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION: return "Video Temporal Decimation";
Mauro Carvalho Chehab6dd5aff2010-08-06 09:57:02 -0300696 case V4L2_CID_MPEG_VIDEO_MUTE: return "Video Mute";
Hans Verkuil09965172010-08-01 14:32:42 -0300697 case V4L2_CID_MPEG_VIDEO_MUTE_YUV: return "Video Mute YUV";
Kamil Debski064f5092011-06-14 10:46:22 -0300698 case V4L2_CID_MPEG_VIDEO_DECODER_SLICE_INTERFACE: return "Decoder Slice Interface";
699 case V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER: return "MPEG4 Loop Filter Enable";
Hans Verkuilf08aacf2012-01-16 12:27:15 -0300700 case V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB: return "Number of Intra Refresh MBs";
Kamil Debski064f5092011-06-14 10:46:22 -0300701 case V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE: return "Frame Level Rate Control Enable";
702 case V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE: return "H264 MB Level Rate Control";
703 case V4L2_CID_MPEG_VIDEO_HEADER_MODE: return "Sequence Header Mode";
Hans Verkuilf08aacf2012-01-16 12:27:15 -0300704 case V4L2_CID_MPEG_VIDEO_MAX_REF_PIC: return "Max Number of Reference Pics";
Kamil Debski064f5092011-06-14 10:46:22 -0300705 case V4L2_CID_MPEG_VIDEO_H263_I_FRAME_QP: return "H263 I-Frame QP Value";
Hans Verkuilf08aacf2012-01-16 12:27:15 -0300706 case V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP: return "H263 P-Frame QP Value";
707 case V4L2_CID_MPEG_VIDEO_H263_B_FRAME_QP: return "H263 B-Frame QP Value";
Kamil Debski064f5092011-06-14 10:46:22 -0300708 case V4L2_CID_MPEG_VIDEO_H263_MIN_QP: return "H263 Minimum QP Value";
709 case V4L2_CID_MPEG_VIDEO_H263_MAX_QP: return "H263 Maximum QP Value";
710 case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP: return "H264 I-Frame QP Value";
Hans Verkuilf08aacf2012-01-16 12:27:15 -0300711 case V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP: return "H264 P-Frame QP Value";
712 case V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP: return "H264 B-Frame QP Value";
Kamil Debski064f5092011-06-14 10:46:22 -0300713 case V4L2_CID_MPEG_VIDEO_H264_MAX_QP: return "H264 Maximum QP Value";
714 case V4L2_CID_MPEG_VIDEO_H264_MIN_QP: return "H264 Minimum QP Value";
715 case V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM: return "H264 8x8 Transform Enable";
716 case V4L2_CID_MPEG_VIDEO_H264_CPB_SIZE: return "H264 CPB Buffer Size";
Hans Verkuilf08aacf2012-01-16 12:27:15 -0300717 case V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE: return "H264 Entropy Mode";
718 case V4L2_CID_MPEG_VIDEO_H264_I_PERIOD: return "H264 I-Frame Period";
Kamil Debski064f5092011-06-14 10:46:22 -0300719 case V4L2_CID_MPEG_VIDEO_H264_LEVEL: return "H264 Level";
720 case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA: return "H264 Loop Filter Alpha Offset";
721 case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA: return "H264 Loop Filter Beta Offset";
722 case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE: return "H264 Loop Filter Mode";
723 case V4L2_CID_MPEG_VIDEO_H264_PROFILE: return "H264 Profile";
724 case V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_HEIGHT: return "Vertical Size of SAR";
725 case V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_WIDTH: return "Horizontal Size of SAR";
726 case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_ENABLE: return "Aspect Ratio VUI Enable";
727 case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC: return "VUI Aspect Ratio IDC";
Arun Kumar K2e81dde2012-10-03 22:19:06 -0300728 case V4L2_CID_MPEG_VIDEO_H264_SEI_FRAME_PACKING: return "H264 Enable Frame Packing SEI";
729 case V4L2_CID_MPEG_VIDEO_H264_SEI_FP_CURRENT_FRAME_0: return "H264 Set Curr. Frame as Frame0";
730 case V4L2_CID_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE: return "H264 FP Arrangement Type";
731 case V4L2_CID_MPEG_VIDEO_H264_FMO: return "H264 Flexible MB Ordering";
732 case V4L2_CID_MPEG_VIDEO_H264_FMO_MAP_TYPE: return "H264 Map Type for FMO";
733 case V4L2_CID_MPEG_VIDEO_H264_FMO_SLICE_GROUP: return "H264 FMO Number of Slice Groups";
734 case V4L2_CID_MPEG_VIDEO_H264_FMO_CHANGE_DIRECTION: return "H264 FMO Direction of Change";
735 case V4L2_CID_MPEG_VIDEO_H264_FMO_CHANGE_RATE: return "H264 FMO Size of 1st Slice Grp";
736 case V4L2_CID_MPEG_VIDEO_H264_FMO_RUN_LENGTH: return "H264 FMO No. of Consecutive MBs";
737 case V4L2_CID_MPEG_VIDEO_H264_ASO: return "H264 Arbitrary Slice Ordering";
738 case V4L2_CID_MPEG_VIDEO_H264_ASO_SLICE_ORDER: return "H264 ASO Slice Order";
739 case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING: return "Enable H264 Hierarchical Coding";
740 case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_TYPE: return "H264 Hierarchical Coding Type";
741 case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER:return "H264 Number of HC Layers";
742 case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_QP:
743 return "H264 Set QP Value for HC Layers";
Kamil Debski064f5092011-06-14 10:46:22 -0300744 case V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP: return "MPEG4 I-Frame QP Value";
Hans Verkuilf08aacf2012-01-16 12:27:15 -0300745 case V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP: return "MPEG4 P-Frame QP Value";
746 case V4L2_CID_MPEG_VIDEO_MPEG4_B_FRAME_QP: return "MPEG4 B-Frame QP Value";
Kamil Debski064f5092011-06-14 10:46:22 -0300747 case V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP: return "MPEG4 Minimum QP Value";
748 case V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP: return "MPEG4 Maximum QP Value";
749 case V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL: return "MPEG4 Level";
750 case V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE: return "MPEG4 Profile";
751 case V4L2_CID_MPEG_VIDEO_MPEG4_QPEL: return "Quarter Pixel Search Enable";
Hans Verkuilf08aacf2012-01-16 12:27:15 -0300752 case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES: return "Maximum Bytes in a Slice";
753 case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB: return "Number of MBs in a Slice";
754 case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE: return "Slice Partitioning Method";
Kamil Debski064f5092011-06-14 10:46:22 -0300755 case V4L2_CID_MPEG_VIDEO_VBV_SIZE: return "VBV Buffer Size";
Hans Verkuil24c19a22011-12-15 10:46:16 -0300756 case V4L2_CID_MPEG_VIDEO_DEC_PTS: return "Video Decoder PTS";
757 case V4L2_CID_MPEG_VIDEO_DEC_FRAME: return "Video Decoder Frame Count";
Arun Kumar K2e81dde2012-10-03 22:19:06 -0300758 case V4L2_CID_MPEG_VIDEO_VBV_DELAY: return "Initial Delay for VBV Control";
Amit Groverbf0bedd2014-02-04 06:59:58 -0300759 case V4L2_CID_MPEG_VIDEO_MV_H_SEARCH_RANGE: return "Horizontal MV Search Range";
760 case V4L2_CID_MPEG_VIDEO_MV_V_SEARCH_RANGE: return "Vertical MV Search Range";
Hans Verkuil9ca54702013-03-17 10:34:04 -0300761 case V4L2_CID_MPEG_VIDEO_REPEAT_SEQ_HEADER: return "Repeat Sequence Header";
Wu-Cheng Licedc1212016-01-19 05:07:09 -0200762 case V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME: return "Force Key Frame";
Hans Verkuil09965172010-08-01 14:32:42 -0300763
Arun Kumar Kbc9028e2013-07-09 01:24:41 -0300764 /* VPX controls */
765 case V4L2_CID_MPEG_VIDEO_VPX_NUM_PARTITIONS: return "VPX Number of Partitions";
766 case V4L2_CID_MPEG_VIDEO_VPX_IMD_DISABLE_4X4: return "VPX Intra Mode Decision Disable";
767 case V4L2_CID_MPEG_VIDEO_VPX_NUM_REF_FRAMES: return "VPX No. of Refs for P Frame";
768 case V4L2_CID_MPEG_VIDEO_VPX_FILTER_LEVEL: return "VPX Loop Filter Level Range";
769 case V4L2_CID_MPEG_VIDEO_VPX_FILTER_SHARPNESS: return "VPX Deblocking Effect Control";
770 case V4L2_CID_MPEG_VIDEO_VPX_GOLDEN_FRAME_REF_PERIOD: return "VPX Golden Frame Refresh Period";
771 case V4L2_CID_MPEG_VIDEO_VPX_GOLDEN_FRAME_SEL: return "VPX Golden Frame Indicator";
Arun Kumar K4773ab92013-11-15 02:29:22 -0300772 case V4L2_CID_MPEG_VIDEO_VPX_MIN_QP: return "VPX Minimum QP Value";
773 case V4L2_CID_MPEG_VIDEO_VPX_MAX_QP: return "VPX Maximum QP Value";
774 case V4L2_CID_MPEG_VIDEO_VPX_I_FRAME_QP: return "VPX I-Frame QP Value";
775 case V4L2_CID_MPEG_VIDEO_VPX_P_FRAME_QP: return "VPX P-Frame QP Value";
Kiran AVNDbbd8f3f2013-12-16 06:40:42 -0300776 case V4L2_CID_MPEG_VIDEO_VPX_PROFILE: return "VPX Profile";
Arun Kumar Kbc9028e2013-07-09 01:24:41 -0300777
Hans Verkuil09965172010-08-01 14:32:42 -0300778 /* CAMERA controls */
Hans Verkuil59253f22014-01-27 11:03:34 -0300779 /* Keep the order of the 'case's the same as in v4l2-controls.h! */
Hans Verkuil09965172010-08-01 14:32:42 -0300780 case V4L2_CID_CAMERA_CLASS: return "Camera Controls";
781 case V4L2_CID_EXPOSURE_AUTO: return "Auto Exposure";
782 case V4L2_CID_EXPOSURE_ABSOLUTE: return "Exposure Time, Absolute";
783 case V4L2_CID_EXPOSURE_AUTO_PRIORITY: return "Exposure, Dynamic Framerate";
784 case V4L2_CID_PAN_RELATIVE: return "Pan, Relative";
785 case V4L2_CID_TILT_RELATIVE: return "Tilt, Relative";
786 case V4L2_CID_PAN_RESET: return "Pan, Reset";
787 case V4L2_CID_TILT_RESET: return "Tilt, Reset";
788 case V4L2_CID_PAN_ABSOLUTE: return "Pan, Absolute";
789 case V4L2_CID_TILT_ABSOLUTE: return "Tilt, Absolute";
790 case V4L2_CID_FOCUS_ABSOLUTE: return "Focus, Absolute";
791 case V4L2_CID_FOCUS_RELATIVE: return "Focus, Relative";
Sylwester Nawrocki2272ab62012-05-11 06:37:03 -0300792 case V4L2_CID_FOCUS_AUTO: return "Focus, Automatic Continuous";
Hans Verkuil09965172010-08-01 14:32:42 -0300793 case V4L2_CID_ZOOM_ABSOLUTE: return "Zoom, Absolute";
794 case V4L2_CID_ZOOM_RELATIVE: return "Zoom, Relative";
795 case V4L2_CID_ZOOM_CONTINUOUS: return "Zoom, Continuous";
796 case V4L2_CID_PRIVACY: return "Privacy";
Hans Verkuil6c8d6112010-04-25 19:21:00 -0300797 case V4L2_CID_IRIS_ABSOLUTE: return "Iris, Absolute";
798 case V4L2_CID_IRIS_RELATIVE: return "Iris, Relative";
Sylwester Nawrockid58083c2012-03-06 07:06:55 -0300799 case V4L2_CID_AUTO_EXPOSURE_BIAS: return "Auto Exposure, Bias";
Sylwester Nawrockie40a0572012-03-06 07:04:26 -0300800 case V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE: return "White Balance, Auto & Preset";
Sylwester Nawrocki44d44a12012-03-06 07:05:45 -0300801 case V4L2_CID_WIDE_DYNAMIC_RANGE: return "Wide Dynamic Range";
Sylwester Nawrocki82b30562012-05-01 17:38:09 -0300802 case V4L2_CID_IMAGE_STABILIZATION: return "Image Stabilization";
Sylwester Nawrocki7f84ad82012-05-01 17:39:45 -0300803 case V4L2_CID_ISO_SENSITIVITY: return "ISO Sensitivity";
804 case V4L2_CID_ISO_SENSITIVITY_AUTO: return "ISO Sensitivity, Auto";
Sylwester Nawrockicf072132012-04-30 04:34:10 -0300805 case V4L2_CID_EXPOSURE_METERING: return "Exposure, Metering Mode";
Sylwester Nawrocki0bf6b7d2012-04-16 10:45:44 -0300806 case V4L2_CID_SCENE_MODE: return "Scene Mode";
Sylwester Nawrockifc162a02012-05-02 06:24:33 -0300807 case V4L2_CID_3A_LOCK: return "3A Lock";
Sylwester Nawrocki2272ab62012-05-11 06:37:03 -0300808 case V4L2_CID_AUTO_FOCUS_START: return "Auto Focus, Start";
809 case V4L2_CID_AUTO_FOCUS_STOP: return "Auto Focus, Stop";
810 case V4L2_CID_AUTO_FOCUS_STATUS: return "Auto Focus, Status";
811 case V4L2_CID_AUTO_FOCUS_RANGE: return "Auto Focus, Range";
Vincent Palatine3d6eb12014-09-03 16:38:39 -0300812 case V4L2_CID_PAN_SPEED: return "Pan, Speed";
813 case V4L2_CID_TILT_SPEED: return "Tilt, Speed";
Hans Verkuil09965172010-08-01 14:32:42 -0300814
Hans Verkuil59253f22014-01-27 11:03:34 -0300815 /* FM Radio Modulator controls */
816 /* Keep the order of the 'case's the same as in v4l2-controls.h! */
Hans Verkuil09965172010-08-01 14:32:42 -0300817 case V4L2_CID_FM_TX_CLASS: return "FM Radio Modulator Controls";
818 case V4L2_CID_RDS_TX_DEVIATION: return "RDS Signal Deviation";
819 case V4L2_CID_RDS_TX_PI: return "RDS Program ID";
820 case V4L2_CID_RDS_TX_PTY: return "RDS Program Type";
821 case V4L2_CID_RDS_TX_PS_NAME: return "RDS PS Name";
822 case V4L2_CID_RDS_TX_RADIO_TEXT: return "RDS Radio Text";
Hans Verkuil811c5082014-07-21 10:45:37 -0300823 case V4L2_CID_RDS_TX_MONO_STEREO: return "RDS Stereo";
824 case V4L2_CID_RDS_TX_ARTIFICIAL_HEAD: return "RDS Artificial Head";
825 case V4L2_CID_RDS_TX_COMPRESSED: return "RDS Compressed";
826 case V4L2_CID_RDS_TX_DYNAMIC_PTY: return "RDS Dynamic PTY";
827 case V4L2_CID_RDS_TX_TRAFFIC_ANNOUNCEMENT: return "RDS Traffic Announcement";
828 case V4L2_CID_RDS_TX_TRAFFIC_PROGRAM: return "RDS Traffic Program";
829 case V4L2_CID_RDS_TX_MUSIC_SPEECH: return "RDS Music";
830 case V4L2_CID_RDS_TX_ALT_FREQS_ENABLE: return "RDS Enable Alt Frequencies";
831 case V4L2_CID_RDS_TX_ALT_FREQS: return "RDS Alternate Frequencies";
Hans Verkuil09965172010-08-01 14:32:42 -0300832 case V4L2_CID_AUDIO_LIMITER_ENABLED: return "Audio Limiter Feature Enabled";
833 case V4L2_CID_AUDIO_LIMITER_RELEASE_TIME: return "Audio Limiter Release Time";
834 case V4L2_CID_AUDIO_LIMITER_DEVIATION: return "Audio Limiter Deviation";
Hans Verkuilf08aacf2012-01-16 12:27:15 -0300835 case V4L2_CID_AUDIO_COMPRESSION_ENABLED: return "Audio Compression Enabled";
Hans Verkuil09965172010-08-01 14:32:42 -0300836 case V4L2_CID_AUDIO_COMPRESSION_GAIN: return "Audio Compression Gain";
837 case V4L2_CID_AUDIO_COMPRESSION_THRESHOLD: return "Audio Compression Threshold";
838 case V4L2_CID_AUDIO_COMPRESSION_ATTACK_TIME: return "Audio Compression Attack Time";
839 case V4L2_CID_AUDIO_COMPRESSION_RELEASE_TIME: return "Audio Compression Release Time";
840 case V4L2_CID_PILOT_TONE_ENABLED: return "Pilot Tone Feature Enabled";
841 case V4L2_CID_PILOT_TONE_DEVIATION: return "Pilot Tone Deviation";
842 case V4L2_CID_PILOT_TONE_FREQUENCY: return "Pilot Tone Frequency";
Hans Verkuilf08aacf2012-01-16 12:27:15 -0300843 case V4L2_CID_TUNE_PREEMPHASIS: return "Pre-Emphasis";
Hans Verkuil09965172010-08-01 14:32:42 -0300844 case V4L2_CID_TUNE_POWER_LEVEL: return "Tune Power Level";
845 case V4L2_CID_TUNE_ANTENNA_CAPACITOR: return "Tune Antenna Capacitor";
846
Sakari Ailus0b159ac2011-03-21 12:52:51 -0300847 /* Flash controls */
Hans Verkuil59253f22014-01-27 11:03:34 -0300848 /* Keep the order of the 'case's the same as in v4l2-controls.h! */
Hans Verkuilf08aacf2012-01-16 12:27:15 -0300849 case V4L2_CID_FLASH_CLASS: return "Flash Controls";
850 case V4L2_CID_FLASH_LED_MODE: return "LED Mode";
851 case V4L2_CID_FLASH_STROBE_SOURCE: return "Strobe Source";
Sakari Ailus0b159ac2011-03-21 12:52:51 -0300852 case V4L2_CID_FLASH_STROBE: return "Strobe";
Hans Verkuilf08aacf2012-01-16 12:27:15 -0300853 case V4L2_CID_FLASH_STROBE_STOP: return "Stop Strobe";
854 case V4L2_CID_FLASH_STROBE_STATUS: return "Strobe Status";
855 case V4L2_CID_FLASH_TIMEOUT: return "Strobe Timeout";
856 case V4L2_CID_FLASH_INTENSITY: return "Intensity, Flash Mode";
857 case V4L2_CID_FLASH_TORCH_INTENSITY: return "Intensity, Torch Mode";
858 case V4L2_CID_FLASH_INDICATOR_INTENSITY: return "Intensity, Indicator";
Sakari Ailus0b159ac2011-03-21 12:52:51 -0300859 case V4L2_CID_FLASH_FAULT: return "Faults";
860 case V4L2_CID_FLASH_CHARGE: return "Charge";
Hans Verkuilf08aacf2012-01-16 12:27:15 -0300861 case V4L2_CID_FLASH_READY: return "Ready to Strobe";
Sakari Ailus0b159ac2011-03-21 12:52:51 -0300862
Sylwester Nawrockic7361ae2012-01-20 15:37:44 -0300863 /* JPEG encoder controls */
Hans Verkuil59253f22014-01-27 11:03:34 -0300864 /* Keep the order of the 'case's the same as in v4l2-controls.h! */
Sylwester Nawrockic7361ae2012-01-20 15:37:44 -0300865 case V4L2_CID_JPEG_CLASS: return "JPEG Compression Controls";
866 case V4L2_CID_JPEG_CHROMA_SUBSAMPLING: return "Chroma Subsampling";
867 case V4L2_CID_JPEG_RESTART_INTERVAL: return "Restart Interval";
868 case V4L2_CID_JPEG_COMPRESSION_QUALITY: return "Compression Quality";
869 case V4L2_CID_JPEG_ACTIVE_MARKER: return "Active Markers";
870
Sakari Ailus8c9d2362011-10-04 08:20:05 -0300871 /* Image source controls */
Hans Verkuil59253f22014-01-27 11:03:34 -0300872 /* Keep the order of the 'case's the same as in v4l2-controls.h! */
Sakari Ailus8c9d2362011-10-04 08:20:05 -0300873 case V4L2_CID_IMAGE_SOURCE_CLASS: return "Image Source Controls";
874 case V4L2_CID_VBLANK: return "Vertical Blanking";
875 case V4L2_CID_HBLANK: return "Horizontal Blanking";
876 case V4L2_CID_ANALOGUE_GAIN: return "Analogue Gain";
Sakari Ailus0fc87862014-05-28 09:38:21 -0300877 case V4L2_CID_TEST_PATTERN_RED: return "Red Pixel Value";
878 case V4L2_CID_TEST_PATTERN_GREENR: return "Green (Red) Pixel Value";
879 case V4L2_CID_TEST_PATTERN_BLUE: return "Blue Pixel Value";
880 case V4L2_CID_TEST_PATTERN_GREENB: return "Green (Blue) Pixel Value";
Sakari Ailus8c9d2362011-10-04 08:20:05 -0300881
Sakari Ailusc643ee12012-02-02 20:17:54 -0300882 /* Image processing controls */
Hans Verkuil59253f22014-01-27 11:03:34 -0300883 /* Keep the order of the 'case's the same as in v4l2-controls.h! */
Sakari Ailusc643ee12012-02-02 20:17:54 -0300884 case V4L2_CID_IMAGE_PROC_CLASS: return "Image Processing Controls";
885 case V4L2_CID_LINK_FREQ: return "Link Frequency";
886 case V4L2_CID_PIXEL_RATE: return "Pixel Rate";
Lad, Prabhakar5ebef0f2012-10-01 08:17:36 -0300887 case V4L2_CID_TEST_PATTERN: return "Test Pattern";
Sakari Ailusc643ee12012-02-02 20:17:54 -0300888
Hans Verkuil977ebec2012-07-03 06:14:37 -0300889 /* DV controls */
Hans Verkuil59253f22014-01-27 11:03:34 -0300890 /* Keep the order of the 'case's the same as in v4l2-controls.h! */
Hans Verkuil977ebec2012-07-03 06:14:37 -0300891 case V4L2_CID_DV_CLASS: return "Digital Video Controls";
892 case V4L2_CID_DV_TX_HOTPLUG: return "Hotplug Present";
893 case V4L2_CID_DV_TX_RXSENSE: return "RxSense Present";
894 case V4L2_CID_DV_TX_EDID_PRESENT: return "EDID Present";
895 case V4L2_CID_DV_TX_MODE: return "Transmit Mode";
896 case V4L2_CID_DV_TX_RGB_RANGE: return "Tx RGB Quantization Range";
Hans Verkuil45cc29a2016-01-27 11:31:39 -0200897 case V4L2_CID_DV_TX_IT_CONTENT_TYPE: return "Tx IT Content Type";
Hans Verkuil977ebec2012-07-03 06:14:37 -0300898 case V4L2_CID_DV_RX_POWER_PRESENT: return "Power Present";
899 case V4L2_CID_DV_RX_RGB_RANGE: return "Rx RGB Quantization Range";
Hans Verkuil45cc29a2016-01-27 11:31:39 -0200900 case V4L2_CID_DV_RX_IT_CONTENT_TYPE: return "Rx IT Content Type";
Hans Verkuil977ebec2012-07-03 06:14:37 -0300901
Andrey Smirnovaec330a2013-03-26 22:47:23 -0300902 case V4L2_CID_FM_RX_CLASS: return "FM Radio Receiver Controls";
903 case V4L2_CID_TUNE_DEEMPHASIS: return "De-Emphasis";
904 case V4L2_CID_RDS_RECEPTION: return "RDS Reception";
Antti Palosaari80807fa2014-01-24 23:44:26 -0300905 case V4L2_CID_RF_TUNER_CLASS: return "RF Tuner Controls";
Antti Palosaari41018cb2015-10-10 13:50:58 -0300906 case V4L2_CID_RF_TUNER_RF_GAIN: return "RF Gain";
Antti Palosaari80807fa2014-01-24 23:44:26 -0300907 case V4L2_CID_RF_TUNER_LNA_GAIN_AUTO: return "LNA Gain, Auto";
908 case V4L2_CID_RF_TUNER_LNA_GAIN: return "LNA Gain";
909 case V4L2_CID_RF_TUNER_MIXER_GAIN_AUTO: return "Mixer Gain, Auto";
910 case V4L2_CID_RF_TUNER_MIXER_GAIN: return "Mixer Gain";
911 case V4L2_CID_RF_TUNER_IF_GAIN_AUTO: return "IF Gain, Auto";
912 case V4L2_CID_RF_TUNER_IF_GAIN: return "IF Gain";
Antti Palosaari3ce569f2014-01-31 23:36:13 -0300913 case V4L2_CID_RF_TUNER_BANDWIDTH_AUTO: return "Bandwidth, Auto";
914 case V4L2_CID_RF_TUNER_BANDWIDTH: return "Bandwidth";
Antti Palosaari9aa43572014-02-07 02:46:16 -0300915 case V4L2_CID_RF_TUNER_PLL_LOCK: return "PLL Lock";
Hans Verkuil9570a142014-07-21 10:45:40 -0300916 case V4L2_CID_RDS_RX_PTY: return "RDS Program Type";
917 case V4L2_CID_RDS_RX_PS_NAME: return "RDS PS Name";
918 case V4L2_CID_RDS_RX_RADIO_TEXT: return "RDS Radio Text";
919 case V4L2_CID_RDS_RX_TRAFFIC_ANNOUNCEMENT: return "RDS Traffic Announcement";
920 case V4L2_CID_RDS_RX_TRAFFIC_PROGRAM: return "RDS Traffic Program";
921 case V4L2_CID_RDS_RX_MUSIC_SPEECH: return "RDS Music";
Hans Verkuila77b4fc2014-03-28 13:00:08 -0300922
923 /* Detection controls */
924 /* Keep the order of the 'case's the same as in v4l2-controls.h! */
925 case V4L2_CID_DETECT_CLASS: return "Detection Controls";
926 case V4L2_CID_DETECT_MD_MODE: return "Motion Detection Mode";
927 case V4L2_CID_DETECT_MD_GLOBAL_THRESHOLD: return "MD Global Threshold";
928 case V4L2_CID_DETECT_MD_THRESHOLD_GRID: return "MD Threshold Grid";
929 case V4L2_CID_DETECT_MD_REGION_GRID: return "MD Region Grid";
Hans Verkuil09965172010-08-01 14:32:42 -0300930 default:
931 return NULL;
932 }
933}
934EXPORT_SYMBOL(v4l2_ctrl_get_name);
935
936void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
Hans Verkuil0ba2aeb2014-04-16 09:41:25 -0300937 s64 *min, s64 *max, u64 *step, s64 *def, u32 *flags)
Hans Verkuil09965172010-08-01 14:32:42 -0300938{
939 *name = v4l2_ctrl_get_name(id);
940 *flags = 0;
941
942 switch (id) {
943 case V4L2_CID_AUDIO_MUTE:
944 case V4L2_CID_AUDIO_LOUDNESS:
945 case V4L2_CID_AUTO_WHITE_BALANCE:
946 case V4L2_CID_AUTOGAIN:
947 case V4L2_CID_HFLIP:
948 case V4L2_CID_VFLIP:
949 case V4L2_CID_HUE_AUTO:
950 case V4L2_CID_CHROMA_AGC:
951 case V4L2_CID_COLOR_KILLER:
Hans de Goedea2f8b842012-07-01 11:26:13 -0300952 case V4L2_CID_AUTOBRIGHTNESS:
Hans Verkuil09965172010-08-01 14:32:42 -0300953 case V4L2_CID_MPEG_AUDIO_MUTE:
954 case V4L2_CID_MPEG_VIDEO_MUTE:
955 case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
956 case V4L2_CID_MPEG_VIDEO_PULLDOWN:
957 case V4L2_CID_EXPOSURE_AUTO_PRIORITY:
958 case V4L2_CID_FOCUS_AUTO:
959 case V4L2_CID_PRIVACY:
960 case V4L2_CID_AUDIO_LIMITER_ENABLED:
961 case V4L2_CID_AUDIO_COMPRESSION_ENABLED:
962 case V4L2_CID_PILOT_TONE_ENABLED:
Jean-François Moine008d35f2010-09-13 07:04:49 -0300963 case V4L2_CID_ILLUMINATORS_1:
964 case V4L2_CID_ILLUMINATORS_2:
Sakari Ailus0b159ac2011-03-21 12:52:51 -0300965 case V4L2_CID_FLASH_STROBE_STATUS:
966 case V4L2_CID_FLASH_CHARGE:
967 case V4L2_CID_FLASH_READY:
Kamil Debski064f5092011-06-14 10:46:22 -0300968 case V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER:
969 case V4L2_CID_MPEG_VIDEO_DECODER_SLICE_INTERFACE:
970 case V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE:
971 case V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE:
972 case V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM:
973 case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_ENABLE:
974 case V4L2_CID_MPEG_VIDEO_MPEG4_QPEL:
Hans Verkuil9ca54702013-03-17 10:34:04 -0300975 case V4L2_CID_MPEG_VIDEO_REPEAT_SEQ_HEADER:
Sylwester Nawrocki44d44a12012-03-06 07:05:45 -0300976 case V4L2_CID_WIDE_DYNAMIC_RANGE:
Sylwester Nawrocki82b30562012-05-01 17:38:09 -0300977 case V4L2_CID_IMAGE_STABILIZATION:
Andrey Smirnovaec330a2013-03-26 22:47:23 -0300978 case V4L2_CID_RDS_RECEPTION:
Antti Palosaari80807fa2014-01-24 23:44:26 -0300979 case V4L2_CID_RF_TUNER_LNA_GAIN_AUTO:
980 case V4L2_CID_RF_TUNER_MIXER_GAIN_AUTO:
981 case V4L2_CID_RF_TUNER_IF_GAIN_AUTO:
Antti Palosaari3ce569f2014-01-31 23:36:13 -0300982 case V4L2_CID_RF_TUNER_BANDWIDTH_AUTO:
Antti Palosaari9aa43572014-02-07 02:46:16 -0300983 case V4L2_CID_RF_TUNER_PLL_LOCK:
Hans Verkuil811c5082014-07-21 10:45:37 -0300984 case V4L2_CID_RDS_TX_MONO_STEREO:
985 case V4L2_CID_RDS_TX_ARTIFICIAL_HEAD:
986 case V4L2_CID_RDS_TX_COMPRESSED:
987 case V4L2_CID_RDS_TX_DYNAMIC_PTY:
988 case V4L2_CID_RDS_TX_TRAFFIC_ANNOUNCEMENT:
989 case V4L2_CID_RDS_TX_TRAFFIC_PROGRAM:
990 case V4L2_CID_RDS_TX_MUSIC_SPEECH:
991 case V4L2_CID_RDS_TX_ALT_FREQS_ENABLE:
Hans Verkuil9570a142014-07-21 10:45:40 -0300992 case V4L2_CID_RDS_RX_TRAFFIC_ANNOUNCEMENT:
993 case V4L2_CID_RDS_RX_TRAFFIC_PROGRAM:
994 case V4L2_CID_RDS_RX_MUSIC_SPEECH:
Hans Verkuil09965172010-08-01 14:32:42 -0300995 *type = V4L2_CTRL_TYPE_BOOLEAN;
996 *min = 0;
997 *max = *step = 1;
998 break;
Amit Groverbf0bedd2014-02-04 06:59:58 -0300999 case V4L2_CID_MPEG_VIDEO_MV_H_SEARCH_RANGE:
1000 case V4L2_CID_MPEG_VIDEO_MV_V_SEARCH_RANGE:
1001 *type = V4L2_CTRL_TYPE_INTEGER;
1002 break;
Wu-Cheng Licedc1212016-01-19 05:07:09 -02001003 case V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME:
Hans Verkuil09965172010-08-01 14:32:42 -03001004 case V4L2_CID_PAN_RESET:
1005 case V4L2_CID_TILT_RESET:
Sakari Ailus0b159ac2011-03-21 12:52:51 -03001006 case V4L2_CID_FLASH_STROBE:
1007 case V4L2_CID_FLASH_STROBE_STOP:
Sylwester Nawrocki2272ab62012-05-11 06:37:03 -03001008 case V4L2_CID_AUTO_FOCUS_START:
1009 case V4L2_CID_AUTO_FOCUS_STOP:
Hans Verkuil09965172010-08-01 14:32:42 -03001010 *type = V4L2_CTRL_TYPE_BUTTON;
Ricardo Ribaldaef66c0c2015-03-20 11:21:28 -03001011 *flags |= V4L2_CTRL_FLAG_WRITE_ONLY |
1012 V4L2_CTRL_FLAG_EXECUTE_ON_WRITE;
Hans Verkuil09965172010-08-01 14:32:42 -03001013 *min = *max = *step = *def = 0;
1014 break;
1015 case V4L2_CID_POWER_LINE_FREQUENCY:
1016 case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
1017 case V4L2_CID_MPEG_AUDIO_ENCODING:
1018 case V4L2_CID_MPEG_AUDIO_L1_BITRATE:
1019 case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
1020 case V4L2_CID_MPEG_AUDIO_L3_BITRATE:
1021 case V4L2_CID_MPEG_AUDIO_AC3_BITRATE:
1022 case V4L2_CID_MPEG_AUDIO_MODE:
1023 case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION:
1024 case V4L2_CID_MPEG_AUDIO_EMPHASIS:
1025 case V4L2_CID_MPEG_AUDIO_CRC:
Hans Verkuil24c19a22011-12-15 10:46:16 -03001026 case V4L2_CID_MPEG_AUDIO_DEC_PLAYBACK:
1027 case V4L2_CID_MPEG_AUDIO_DEC_MULTILINGUAL_PLAYBACK:
Hans Verkuil09965172010-08-01 14:32:42 -03001028 case V4L2_CID_MPEG_VIDEO_ENCODING:
1029 case V4L2_CID_MPEG_VIDEO_ASPECT:
1030 case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
1031 case V4L2_CID_MPEG_STREAM_TYPE:
1032 case V4L2_CID_MPEG_STREAM_VBI_FMT:
1033 case V4L2_CID_EXPOSURE_AUTO:
Sylwester Nawrocki2272ab62012-05-11 06:37:03 -03001034 case V4L2_CID_AUTO_FOCUS_RANGE:
Hans Verkuil09965172010-08-01 14:32:42 -03001035 case V4L2_CID_COLORFX:
Sylwester Nawrockie40a0572012-03-06 07:04:26 -03001036 case V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE:
Hans Verkuil09965172010-08-01 14:32:42 -03001037 case V4L2_CID_TUNE_PREEMPHASIS:
Sakari Ailus0b159ac2011-03-21 12:52:51 -03001038 case V4L2_CID_FLASH_LED_MODE:
1039 case V4L2_CID_FLASH_STROBE_SOURCE:
Kamil Debski064f5092011-06-14 10:46:22 -03001040 case V4L2_CID_MPEG_VIDEO_HEADER_MODE:
1041 case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE:
1042 case V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE:
1043 case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
1044 case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE:
1045 case V4L2_CID_MPEG_VIDEO_H264_PROFILE:
1046 case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC:
Arun Kumar K2e81dde2012-10-03 22:19:06 -03001047 case V4L2_CID_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE:
1048 case V4L2_CID_MPEG_VIDEO_H264_FMO_MAP_TYPE:
Kamil Debski064f5092011-06-14 10:46:22 -03001049 case V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL:
1050 case V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE:
Sylwester Nawrockic7361ae2012-01-20 15:37:44 -03001051 case V4L2_CID_JPEG_CHROMA_SUBSAMPLING:
Sylwester Nawrocki7f84ad82012-05-01 17:39:45 -03001052 case V4L2_CID_ISO_SENSITIVITY_AUTO:
Sylwester Nawrockicf072132012-04-30 04:34:10 -03001053 case V4L2_CID_EXPOSURE_METERING:
Sylwester Nawrocki0bf6b7d2012-04-16 10:45:44 -03001054 case V4L2_CID_SCENE_MODE:
Hans Verkuil977ebec2012-07-03 06:14:37 -03001055 case V4L2_CID_DV_TX_MODE:
1056 case V4L2_CID_DV_TX_RGB_RANGE:
Hans Verkuil45cc29a2016-01-27 11:31:39 -02001057 case V4L2_CID_DV_TX_IT_CONTENT_TYPE:
Hans Verkuil977ebec2012-07-03 06:14:37 -03001058 case V4L2_CID_DV_RX_RGB_RANGE:
Hans Verkuil45cc29a2016-01-27 11:31:39 -02001059 case V4L2_CID_DV_RX_IT_CONTENT_TYPE:
Lad, Prabhakar5ebef0f2012-10-01 08:17:36 -03001060 case V4L2_CID_TEST_PATTERN:
Andrey Smirnovaec330a2013-03-26 22:47:23 -03001061 case V4L2_CID_TUNE_DEEMPHASIS:
Arun Kumar Kbc9028e2013-07-09 01:24:41 -03001062 case V4L2_CID_MPEG_VIDEO_VPX_GOLDEN_FRAME_SEL:
Hans Verkuila77b4fc2014-03-28 13:00:08 -03001063 case V4L2_CID_DETECT_MD_MODE:
Hans Verkuil09965172010-08-01 14:32:42 -03001064 *type = V4L2_CTRL_TYPE_MENU;
1065 break;
Sakari Ailusc643ee12012-02-02 20:17:54 -03001066 case V4L2_CID_LINK_FREQ:
1067 *type = V4L2_CTRL_TYPE_INTEGER_MENU;
1068 break;
Hans Verkuil09965172010-08-01 14:32:42 -03001069 case V4L2_CID_RDS_TX_PS_NAME:
1070 case V4L2_CID_RDS_TX_RADIO_TEXT:
Hans Verkuil9570a142014-07-21 10:45:40 -03001071 case V4L2_CID_RDS_RX_PS_NAME:
1072 case V4L2_CID_RDS_RX_RADIO_TEXT:
Hans Verkuil09965172010-08-01 14:32:42 -03001073 *type = V4L2_CTRL_TYPE_STRING;
1074 break;
Sylwester Nawrocki7f84ad82012-05-01 17:39:45 -03001075 case V4L2_CID_ISO_SENSITIVITY:
Sylwester Nawrockid58083c2012-03-06 07:06:55 -03001076 case V4L2_CID_AUTO_EXPOSURE_BIAS:
Arun Kumar Kbc9028e2013-07-09 01:24:41 -03001077 case V4L2_CID_MPEG_VIDEO_VPX_NUM_PARTITIONS:
1078 case V4L2_CID_MPEG_VIDEO_VPX_NUM_REF_FRAMES:
Sylwester Nawrockid58083c2012-03-06 07:06:55 -03001079 *type = V4L2_CTRL_TYPE_INTEGER_MENU;
1080 break;
Hans Verkuil09965172010-08-01 14:32:42 -03001081 case V4L2_CID_USER_CLASS:
1082 case V4L2_CID_CAMERA_CLASS:
1083 case V4L2_CID_MPEG_CLASS:
1084 case V4L2_CID_FM_TX_CLASS:
Sakari Ailus0b159ac2011-03-21 12:52:51 -03001085 case V4L2_CID_FLASH_CLASS:
Sylwester Nawrockic7361ae2012-01-20 15:37:44 -03001086 case V4L2_CID_JPEG_CLASS:
Sakari Ailus8c9d2362011-10-04 08:20:05 -03001087 case V4L2_CID_IMAGE_SOURCE_CLASS:
Sakari Ailusc643ee12012-02-02 20:17:54 -03001088 case V4L2_CID_IMAGE_PROC_CLASS:
Hans Verkuil977ebec2012-07-03 06:14:37 -03001089 case V4L2_CID_DV_CLASS:
Andrey Smirnovaec330a2013-03-26 22:47:23 -03001090 case V4L2_CID_FM_RX_CLASS:
Antti Palosaari80807fa2014-01-24 23:44:26 -03001091 case V4L2_CID_RF_TUNER_CLASS:
Hans Verkuila77b4fc2014-03-28 13:00:08 -03001092 case V4L2_CID_DETECT_CLASS:
Hans Verkuil09965172010-08-01 14:32:42 -03001093 *type = V4L2_CTRL_TYPE_CTRL_CLASS;
1094 /* You can neither read not write these */
1095 *flags |= V4L2_CTRL_FLAG_READ_ONLY | V4L2_CTRL_FLAG_WRITE_ONLY;
1096 *min = *max = *step = *def = 0;
1097 break;
1098 case V4L2_CID_BG_COLOR:
1099 *type = V4L2_CTRL_TYPE_INTEGER;
1100 *step = 1;
1101 *min = 0;
1102 /* Max is calculated as RGB888 that is 2^24 */
1103 *max = 0xFFFFFF;
1104 break;
Sakari Ailus0b159ac2011-03-21 12:52:51 -03001105 case V4L2_CID_FLASH_FAULT:
Sylwester Nawrockic7361ae2012-01-20 15:37:44 -03001106 case V4L2_CID_JPEG_ACTIVE_MARKER:
Sylwester Nawrockifc162a02012-05-02 06:24:33 -03001107 case V4L2_CID_3A_LOCK:
Sylwester Nawrocki2272ab62012-05-11 06:37:03 -03001108 case V4L2_CID_AUTO_FOCUS_STATUS:
Hans Verkuil977ebec2012-07-03 06:14:37 -03001109 case V4L2_CID_DV_TX_HOTPLUG:
1110 case V4L2_CID_DV_TX_RXSENSE:
1111 case V4L2_CID_DV_TX_EDID_PRESENT:
1112 case V4L2_CID_DV_RX_POWER_PRESENT:
Sakari Ailus0b159ac2011-03-21 12:52:51 -03001113 *type = V4L2_CTRL_TYPE_BITMASK;
1114 break;
Kamil Debski064f5092011-06-14 10:46:22 -03001115 case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE:
1116 case V4L2_CID_MIN_BUFFERS_FOR_OUTPUT:
1117 *type = V4L2_CTRL_TYPE_INTEGER;
1118 *flags |= V4L2_CTRL_FLAG_READ_ONLY;
1119 break;
Hans Verkuil24c19a22011-12-15 10:46:16 -03001120 case V4L2_CID_MPEG_VIDEO_DEC_PTS:
Hans Verkuil0ba2aeb2014-04-16 09:41:25 -03001121 *type = V4L2_CTRL_TYPE_INTEGER64;
1122 *flags |= V4L2_CTRL_FLAG_VOLATILE | V4L2_CTRL_FLAG_READ_ONLY;
1123 *min = *def = 0;
1124 *max = 0x1ffffffffLL;
1125 *step = 1;
1126 break;
1127 case V4L2_CID_MPEG_VIDEO_DEC_FRAME:
1128 *type = V4L2_CTRL_TYPE_INTEGER64;
1129 *flags |= V4L2_CTRL_FLAG_VOLATILE | V4L2_CTRL_FLAG_READ_ONLY;
1130 *min = *def = 0;
1131 *max = 0x7fffffffffffffffLL;
1132 *step = 1;
1133 break;
Sakari Ailusc643ee12012-02-02 20:17:54 -03001134 case V4L2_CID_PIXEL_RATE:
Hans Verkuil24c19a22011-12-15 10:46:16 -03001135 *type = V4L2_CTRL_TYPE_INTEGER64;
Sakari Ailusc643ee12012-02-02 20:17:54 -03001136 *flags |= V4L2_CTRL_FLAG_READ_ONLY;
Hans Verkuil24c19a22011-12-15 10:46:16 -03001137 break;
Hans Verkuila77b4fc2014-03-28 13:00:08 -03001138 case V4L2_CID_DETECT_MD_REGION_GRID:
1139 *type = V4L2_CTRL_TYPE_U8;
1140 break;
1141 case V4L2_CID_DETECT_MD_THRESHOLD_GRID:
1142 *type = V4L2_CTRL_TYPE_U16;
1143 break;
Hans Verkuil811c5082014-07-21 10:45:37 -03001144 case V4L2_CID_RDS_TX_ALT_FREQS:
1145 *type = V4L2_CTRL_TYPE_U32;
1146 break;
Hans Verkuil09965172010-08-01 14:32:42 -03001147 default:
1148 *type = V4L2_CTRL_TYPE_INTEGER;
1149 break;
1150 }
1151 switch (id) {
1152 case V4L2_CID_MPEG_AUDIO_ENCODING:
1153 case V4L2_CID_MPEG_AUDIO_MODE:
1154 case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
1155 case V4L2_CID_MPEG_VIDEO_B_FRAMES:
1156 case V4L2_CID_MPEG_STREAM_TYPE:
1157 *flags |= V4L2_CTRL_FLAG_UPDATE;
1158 break;
1159 case V4L2_CID_AUDIO_VOLUME:
1160 case V4L2_CID_AUDIO_BALANCE:
1161 case V4L2_CID_AUDIO_BASS:
1162 case V4L2_CID_AUDIO_TREBLE:
1163 case V4L2_CID_BRIGHTNESS:
1164 case V4L2_CID_CONTRAST:
1165 case V4L2_CID_SATURATION:
1166 case V4L2_CID_HUE:
1167 case V4L2_CID_RED_BALANCE:
1168 case V4L2_CID_BLUE_BALANCE:
1169 case V4L2_CID_GAMMA:
1170 case V4L2_CID_SHARPNESS:
1171 case V4L2_CID_CHROMA_GAIN:
1172 case V4L2_CID_RDS_TX_DEVIATION:
1173 case V4L2_CID_AUDIO_LIMITER_RELEASE_TIME:
1174 case V4L2_CID_AUDIO_LIMITER_DEVIATION:
1175 case V4L2_CID_AUDIO_COMPRESSION_GAIN:
1176 case V4L2_CID_AUDIO_COMPRESSION_THRESHOLD:
1177 case V4L2_CID_AUDIO_COMPRESSION_ATTACK_TIME:
1178 case V4L2_CID_AUDIO_COMPRESSION_RELEASE_TIME:
1179 case V4L2_CID_PILOT_TONE_DEVIATION:
1180 case V4L2_CID_PILOT_TONE_FREQUENCY:
1181 case V4L2_CID_TUNE_POWER_LEVEL:
1182 case V4L2_CID_TUNE_ANTENNA_CAPACITOR:
Antti Palosaari41018cb2015-10-10 13:50:58 -03001183 case V4L2_CID_RF_TUNER_RF_GAIN:
Antti Palosaari80807fa2014-01-24 23:44:26 -03001184 case V4L2_CID_RF_TUNER_LNA_GAIN:
1185 case V4L2_CID_RF_TUNER_MIXER_GAIN:
1186 case V4L2_CID_RF_TUNER_IF_GAIN:
Antti Palosaari3ce569f2014-01-31 23:36:13 -03001187 case V4L2_CID_RF_TUNER_BANDWIDTH:
Hans Verkuila77b4fc2014-03-28 13:00:08 -03001188 case V4L2_CID_DETECT_MD_GLOBAL_THRESHOLD:
Hans Verkuil09965172010-08-01 14:32:42 -03001189 *flags |= V4L2_CTRL_FLAG_SLIDER;
1190 break;
1191 case V4L2_CID_PAN_RELATIVE:
1192 case V4L2_CID_TILT_RELATIVE:
1193 case V4L2_CID_FOCUS_RELATIVE:
1194 case V4L2_CID_IRIS_RELATIVE:
1195 case V4L2_CID_ZOOM_RELATIVE:
Ricardo Ribaldaef66c0c2015-03-20 11:21:28 -03001196 *flags |= V4L2_CTRL_FLAG_WRITE_ONLY |
1197 V4L2_CTRL_FLAG_EXECUTE_ON_WRITE;
Hans Verkuil09965172010-08-01 14:32:42 -03001198 break;
Sakari Ailus0b159ac2011-03-21 12:52:51 -03001199 case V4L2_CID_FLASH_STROBE_STATUS:
Sylwester Nawrocki2272ab62012-05-11 06:37:03 -03001200 case V4L2_CID_AUTO_FOCUS_STATUS:
Sakari Ailus0b159ac2011-03-21 12:52:51 -03001201 case V4L2_CID_FLASH_READY:
Hans Verkuil977ebec2012-07-03 06:14:37 -03001202 case V4L2_CID_DV_TX_HOTPLUG:
1203 case V4L2_CID_DV_TX_RXSENSE:
1204 case V4L2_CID_DV_TX_EDID_PRESENT:
1205 case V4L2_CID_DV_RX_POWER_PRESENT:
Hans Verkuil45cc29a2016-01-27 11:31:39 -02001206 case V4L2_CID_DV_RX_IT_CONTENT_TYPE:
Hans Verkuil9570a142014-07-21 10:45:40 -03001207 case V4L2_CID_RDS_RX_PTY:
1208 case V4L2_CID_RDS_RX_PS_NAME:
1209 case V4L2_CID_RDS_RX_RADIO_TEXT:
1210 case V4L2_CID_RDS_RX_TRAFFIC_ANNOUNCEMENT:
1211 case V4L2_CID_RDS_RX_TRAFFIC_PROGRAM:
1212 case V4L2_CID_RDS_RX_MUSIC_SPEECH:
Sakari Ailus0b159ac2011-03-21 12:52:51 -03001213 *flags |= V4L2_CTRL_FLAG_READ_ONLY;
1214 break;
Antti Palosaari9aa43572014-02-07 02:46:16 -03001215 case V4L2_CID_RF_TUNER_PLL_LOCK:
1216 *flags |= V4L2_CTRL_FLAG_VOLATILE;
1217 break;
Hans Verkuil09965172010-08-01 14:32:42 -03001218 }
1219}
1220EXPORT_SYMBOL(v4l2_ctrl_fill);
1221
Hans Verkuil6e239392011-06-07 11:13:44 -03001222static void fill_event(struct v4l2_event *ev, struct v4l2_ctrl *ctrl, u32 changes)
1223{
1224 memset(ev->reserved, 0, sizeof(ev->reserved));
1225 ev->type = V4L2_EVENT_CTRL;
1226 ev->id = ctrl->id;
1227 ev->u.ctrl.changes = changes;
1228 ev->u.ctrl.type = ctrl->type;
1229 ev->u.ctrl.flags = ctrl->flags;
Hans Verkuild9a25472014-06-12 07:54:16 -03001230 if (ctrl->is_ptr)
Hans Verkuil6e239392011-06-07 11:13:44 -03001231 ev->u.ctrl.value64 = 0;
1232 else
Hans Verkuil2a9ec372014-04-27 03:38:13 -03001233 ev->u.ctrl.value64 = *ctrl->p_cur.p_s64;
Hans Verkuil6e239392011-06-07 11:13:44 -03001234 ev->u.ctrl.minimum = ctrl->minimum;
1235 ev->u.ctrl.maximum = ctrl->maximum;
Sakari Ailusce580fe2011-08-04 13:51:11 -03001236 if (ctrl->type == V4L2_CTRL_TYPE_MENU
1237 || ctrl->type == V4L2_CTRL_TYPE_INTEGER_MENU)
Hans Verkuil6e239392011-06-07 11:13:44 -03001238 ev->u.ctrl.step = 1;
1239 else
1240 ev->u.ctrl.step = ctrl->step;
1241 ev->u.ctrl.default_value = ctrl->default_value;
1242}
1243
1244static void send_event(struct v4l2_fh *fh, struct v4l2_ctrl *ctrl, u32 changes)
1245{
1246 struct v4l2_event ev;
Hans Verkuil77068d32011-06-13 18:55:58 -03001247 struct v4l2_subscribed_event *sev;
Hans Verkuil6e239392011-06-07 11:13:44 -03001248
Hans Verkuil77068d32011-06-13 18:55:58 -03001249 if (list_empty(&ctrl->ev_subs))
Hans Verkuil3f66f0e2011-06-20 11:56:24 -03001250 return;
Hans Verkuil6e239392011-06-07 11:13:44 -03001251 fill_event(&ev, ctrl, changes);
1252
Hans Verkuil77068d32011-06-13 18:55:58 -03001253 list_for_each_entry(sev, &ctrl->ev_subs, node)
Hans de Goedee3e72f392011-10-26 05:52:47 -03001254 if (sev->fh != fh ||
1255 (sev->flags & V4L2_EVENT_SUB_FL_ALLOW_FEEDBACK))
Hans Verkuil77068d32011-06-13 18:55:58 -03001256 v4l2_event_queue_fh(sev->fh, &ev);
Hans Verkuil6e239392011-06-07 11:13:44 -03001257}
1258
Hans Verkuil998e7652014-06-10 07:55:00 -03001259static bool std_equal(const struct v4l2_ctrl *ctrl, u32 idx,
Hans Verkuil01760772014-04-27 03:22:17 -03001260 union v4l2_ctrl_ptr ptr1,
1261 union v4l2_ctrl_ptr ptr2)
1262{
1263 switch (ctrl->type) {
1264 case V4L2_CTRL_TYPE_BUTTON:
1265 return false;
1266 case V4L2_CTRL_TYPE_STRING:
Hans Verkuil265c7f82014-01-05 11:06:05 -03001267 idx *= ctrl->elem_size;
Hans Verkuil01760772014-04-27 03:22:17 -03001268 /* strings are always 0-terminated */
Hans Verkuil265c7f82014-01-05 11:06:05 -03001269 return !strcmp(ptr1.p_char + idx, ptr2.p_char + idx);
Hans Verkuil01760772014-04-27 03:22:17 -03001270 case V4L2_CTRL_TYPE_INTEGER64:
Hans Verkuil265c7f82014-01-05 11:06:05 -03001271 return ptr1.p_s64[idx] == ptr2.p_s64[idx];
Hans Verkuildda4a4d2014-06-10 07:30:04 -03001272 case V4L2_CTRL_TYPE_U8:
1273 return ptr1.p_u8[idx] == ptr2.p_u8[idx];
1274 case V4L2_CTRL_TYPE_U16:
1275 return ptr1.p_u16[idx] == ptr2.p_u16[idx];
Hans Verkuil811c5082014-07-21 10:45:37 -03001276 case V4L2_CTRL_TYPE_U32:
1277 return ptr1.p_u32[idx] == ptr2.p_u32[idx];
Hans Verkuil01760772014-04-27 03:22:17 -03001278 default:
Hans Verkuil265c7f82014-01-05 11:06:05 -03001279 if (ctrl->is_int)
1280 return ptr1.p_s32[idx] == ptr2.p_s32[idx];
1281 idx *= ctrl->elem_size;
1282 return !memcmp(ptr1.p + idx, ptr2.p + idx, ctrl->elem_size);
Hans Verkuil01760772014-04-27 03:22:17 -03001283 }
1284}
1285
Hans Verkuil998e7652014-06-10 07:55:00 -03001286static void std_init(const struct v4l2_ctrl *ctrl, u32 idx,
Hans Verkuil01760772014-04-27 03:22:17 -03001287 union v4l2_ctrl_ptr ptr)
1288{
1289 switch (ctrl->type) {
1290 case V4L2_CTRL_TYPE_STRING:
Hans Verkuil265c7f82014-01-05 11:06:05 -03001291 idx *= ctrl->elem_size;
1292 memset(ptr.p_char + idx, ' ', ctrl->minimum);
1293 ptr.p_char[idx + ctrl->minimum] = '\0';
Hans Verkuil01760772014-04-27 03:22:17 -03001294 break;
1295 case V4L2_CTRL_TYPE_INTEGER64:
Hans Verkuil265c7f82014-01-05 11:06:05 -03001296 ptr.p_s64[idx] = ctrl->default_value;
Hans Verkuil01760772014-04-27 03:22:17 -03001297 break;
1298 case V4L2_CTRL_TYPE_INTEGER:
1299 case V4L2_CTRL_TYPE_INTEGER_MENU:
1300 case V4L2_CTRL_TYPE_MENU:
1301 case V4L2_CTRL_TYPE_BITMASK:
1302 case V4L2_CTRL_TYPE_BOOLEAN:
Hans Verkuil265c7f82014-01-05 11:06:05 -03001303 ptr.p_s32[idx] = ctrl->default_value;
Hans Verkuil01760772014-04-27 03:22:17 -03001304 break;
Hans Verkuildda4a4d2014-06-10 07:30:04 -03001305 case V4L2_CTRL_TYPE_U8:
1306 ptr.p_u8[idx] = ctrl->default_value;
1307 break;
1308 case V4L2_CTRL_TYPE_U16:
1309 ptr.p_u16[idx] = ctrl->default_value;
1310 break;
Hans Verkuil811c5082014-07-21 10:45:37 -03001311 case V4L2_CTRL_TYPE_U32:
1312 ptr.p_u32[idx] = ctrl->default_value;
1313 break;
Hans Verkuil01760772014-04-27 03:22:17 -03001314 default:
Hans Verkuil302ab7c2014-06-10 07:06:50 -03001315 idx *= ctrl->elem_size;
1316 memset(ptr.p + idx, 0, ctrl->elem_size);
Hans Verkuil01760772014-04-27 03:22:17 -03001317 break;
1318 }
1319}
1320
1321static void std_log(const struct v4l2_ctrl *ctrl)
1322{
1323 union v4l2_ctrl_ptr ptr = ctrl->p_cur;
1324
Hans Verkuil998e7652014-06-10 07:55:00 -03001325 if (ctrl->is_array) {
1326 unsigned i;
1327
1328 for (i = 0; i < ctrl->nr_of_dims; i++)
1329 pr_cont("[%u]", ctrl->dims[i]);
1330 pr_cont(" ");
1331 }
1332
Hans Verkuil01760772014-04-27 03:22:17 -03001333 switch (ctrl->type) {
1334 case V4L2_CTRL_TYPE_INTEGER:
1335 pr_cont("%d", *ptr.p_s32);
1336 break;
1337 case V4L2_CTRL_TYPE_BOOLEAN:
1338 pr_cont("%s", *ptr.p_s32 ? "true" : "false");
1339 break;
1340 case V4L2_CTRL_TYPE_MENU:
1341 pr_cont("%s", ctrl->qmenu[*ptr.p_s32]);
1342 break;
1343 case V4L2_CTRL_TYPE_INTEGER_MENU:
1344 pr_cont("%lld", ctrl->qmenu_int[*ptr.p_s32]);
1345 break;
1346 case V4L2_CTRL_TYPE_BITMASK:
1347 pr_cont("0x%08x", *ptr.p_s32);
1348 break;
1349 case V4L2_CTRL_TYPE_INTEGER64:
1350 pr_cont("%lld", *ptr.p_s64);
1351 break;
1352 case V4L2_CTRL_TYPE_STRING:
1353 pr_cont("%s", ptr.p_char);
1354 break;
Hans Verkuildda4a4d2014-06-10 07:30:04 -03001355 case V4L2_CTRL_TYPE_U8:
1356 pr_cont("%u", (unsigned)*ptr.p_u8);
1357 break;
1358 case V4L2_CTRL_TYPE_U16:
1359 pr_cont("%u", (unsigned)*ptr.p_u16);
1360 break;
Hans Verkuil811c5082014-07-21 10:45:37 -03001361 case V4L2_CTRL_TYPE_U32:
1362 pr_cont("%u", (unsigned)*ptr.p_u32);
1363 break;
Hans Verkuil01760772014-04-27 03:22:17 -03001364 default:
1365 pr_cont("unknown type %d", ctrl->type);
1366 break;
1367 }
1368}
1369
Hans Verkuil958c7c72014-07-18 05:15:21 -03001370/*
1371 * Round towards the closest legal value. Be careful when we are
1372 * close to the maximum range of the control type to prevent
1373 * wrap-arounds.
1374 */
Hans Verkuil01760772014-04-27 03:22:17 -03001375#define ROUND_TO_RANGE(val, offset_type, ctrl) \
1376({ \
1377 offset_type offset; \
Hans Verkuil958c7c72014-07-18 05:15:21 -03001378 if ((ctrl)->maximum >= 0 && \
Hans Verkuil9c9cb1f2014-07-26 13:02:59 -03001379 val >= (ctrl)->maximum - (s32)((ctrl)->step / 2)) \
Hans Verkuil958c7c72014-07-18 05:15:21 -03001380 val = (ctrl)->maximum; \
1381 else \
Hans Verkuil9c9cb1f2014-07-26 13:02:59 -03001382 val += (s32)((ctrl)->step / 2); \
Hans Verkuil01760772014-04-27 03:22:17 -03001383 val = clamp_t(typeof(val), val, \
1384 (ctrl)->minimum, (ctrl)->maximum); \
1385 offset = (val) - (ctrl)->minimum; \
Hans Verkuil9c9cb1f2014-07-26 13:02:59 -03001386 offset = (ctrl)->step * (offset / (u32)(ctrl)->step); \
Hans Verkuil01760772014-04-27 03:22:17 -03001387 val = (ctrl)->minimum + offset; \
1388 0; \
1389})
1390
1391/* Validate a new control */
Hans Verkuil998e7652014-06-10 07:55:00 -03001392static int std_validate(const struct v4l2_ctrl *ctrl, u32 idx,
Hans Verkuil01760772014-04-27 03:22:17 -03001393 union v4l2_ctrl_ptr ptr)
1394{
1395 size_t len;
Hans Verkuil0d5e8c42014-07-17 12:31:23 -03001396 u64 offset;
1397 s64 val;
Hans Verkuil01760772014-04-27 03:22:17 -03001398
1399 switch (ctrl->type) {
1400 case V4L2_CTRL_TYPE_INTEGER:
Hans Verkuil265c7f82014-01-05 11:06:05 -03001401 return ROUND_TO_RANGE(ptr.p_s32[idx], u32, ctrl);
Hans Verkuil01760772014-04-27 03:22:17 -03001402 case V4L2_CTRL_TYPE_INTEGER64:
Hans Verkuil0d5e8c42014-07-17 12:31:23 -03001403 /*
1404 * We can't use the ROUND_TO_RANGE define here due to
1405 * the u64 divide that needs special care.
1406 */
1407 val = ptr.p_s64[idx];
Hans Verkuil9c9cb1f2014-07-26 13:02:59 -03001408 if (ctrl->maximum >= 0 && val >= ctrl->maximum - (s64)(ctrl->step / 2))
Hans Verkuil958c7c72014-07-18 05:15:21 -03001409 val = ctrl->maximum;
1410 else
Hans Verkuil9c9cb1f2014-07-26 13:02:59 -03001411 val += (s64)(ctrl->step / 2);
Hans Verkuil0d5e8c42014-07-17 12:31:23 -03001412 val = clamp_t(s64, val, ctrl->minimum, ctrl->maximum);
1413 offset = val - ctrl->minimum;
1414 do_div(offset, ctrl->step);
1415 ptr.p_s64[idx] = ctrl->minimum + offset * ctrl->step;
1416 return 0;
Hans Verkuildda4a4d2014-06-10 07:30:04 -03001417 case V4L2_CTRL_TYPE_U8:
1418 return ROUND_TO_RANGE(ptr.p_u8[idx], u8, ctrl);
1419 case V4L2_CTRL_TYPE_U16:
1420 return ROUND_TO_RANGE(ptr.p_u16[idx], u16, ctrl);
Hans Verkuil811c5082014-07-21 10:45:37 -03001421 case V4L2_CTRL_TYPE_U32:
1422 return ROUND_TO_RANGE(ptr.p_u32[idx], u32, ctrl);
Hans Verkuil01760772014-04-27 03:22:17 -03001423
1424 case V4L2_CTRL_TYPE_BOOLEAN:
Hans Verkuil265c7f82014-01-05 11:06:05 -03001425 ptr.p_s32[idx] = !!ptr.p_s32[idx];
Hans Verkuil01760772014-04-27 03:22:17 -03001426 return 0;
1427
1428 case V4L2_CTRL_TYPE_MENU:
1429 case V4L2_CTRL_TYPE_INTEGER_MENU:
Hans Verkuil265c7f82014-01-05 11:06:05 -03001430 if (ptr.p_s32[idx] < ctrl->minimum || ptr.p_s32[idx] > ctrl->maximum)
Hans Verkuil01760772014-04-27 03:22:17 -03001431 return -ERANGE;
Hans Verkuil265c7f82014-01-05 11:06:05 -03001432 if (ctrl->menu_skip_mask & (1 << ptr.p_s32[idx]))
Hans Verkuil01760772014-04-27 03:22:17 -03001433 return -EINVAL;
1434 if (ctrl->type == V4L2_CTRL_TYPE_MENU &&
Hans Verkuil265c7f82014-01-05 11:06:05 -03001435 ctrl->qmenu[ptr.p_s32[idx]][0] == '\0')
Hans Verkuil01760772014-04-27 03:22:17 -03001436 return -EINVAL;
1437 return 0;
1438
1439 case V4L2_CTRL_TYPE_BITMASK:
Hans Verkuil265c7f82014-01-05 11:06:05 -03001440 ptr.p_s32[idx] &= ctrl->maximum;
Hans Verkuil01760772014-04-27 03:22:17 -03001441 return 0;
1442
1443 case V4L2_CTRL_TYPE_BUTTON:
1444 case V4L2_CTRL_TYPE_CTRL_CLASS:
Hans Verkuil265c7f82014-01-05 11:06:05 -03001445 ptr.p_s32[idx] = 0;
Hans Verkuil01760772014-04-27 03:22:17 -03001446 return 0;
1447
1448 case V4L2_CTRL_TYPE_STRING:
Hans Verkuil265c7f82014-01-05 11:06:05 -03001449 idx *= ctrl->elem_size;
1450 len = strlen(ptr.p_char + idx);
Hans Verkuil01760772014-04-27 03:22:17 -03001451 if (len < ctrl->minimum)
1452 return -ERANGE;
Hans Verkuil0d5e8c42014-07-17 12:31:23 -03001453 if ((len - (u32)ctrl->minimum) % (u32)ctrl->step)
Hans Verkuil01760772014-04-27 03:22:17 -03001454 return -ERANGE;
1455 return 0;
1456
1457 default:
1458 return -EINVAL;
1459 }
1460}
1461
1462static const struct v4l2_ctrl_type_ops std_type_ops = {
1463 .equal = std_equal,
1464 .init = std_init,
1465 .log = std_log,
1466 .validate = std_validate,
1467};
1468
Hans Verkuil000e4f92014-04-27 03:26:30 -03001469/* Helper function: copy the given control value back to the caller */
1470static int ptr_to_user(struct v4l2_ext_control *c,
1471 struct v4l2_ctrl *ctrl,
1472 union v4l2_ctrl_ptr ptr)
Hans Verkuil09965172010-08-01 14:32:42 -03001473{
1474 u32 len;
1475
Hans Verkuild9a25472014-06-12 07:54:16 -03001476 if (ctrl->is_ptr && !ctrl->is_string)
Hans Verkuil40265bb2014-06-10 07:07:38 -03001477 return copy_to_user(c->ptr, ptr.p, c->size) ?
1478 -EFAULT : 0;
Hans Verkuild9a25472014-06-12 07:54:16 -03001479
Hans Verkuil09965172010-08-01 14:32:42 -03001480 switch (ctrl->type) {
1481 case V4L2_CTRL_TYPE_STRING:
Hans Verkuil000e4f92014-04-27 03:26:30 -03001482 len = strlen(ptr.p_char);
Hans Verkuil09965172010-08-01 14:32:42 -03001483 if (c->size < len + 1) {
Hans Verkuilc336f752014-01-18 06:06:01 -03001484 c->size = ctrl->elem_size;
Hans Verkuil09965172010-08-01 14:32:42 -03001485 return -ENOSPC;
1486 }
Hans Verkuil000e4f92014-04-27 03:26:30 -03001487 return copy_to_user(c->string, ptr.p_char, len + 1) ?
Hans Verkuil40265bb2014-06-10 07:07:38 -03001488 -EFAULT : 0;
Hans Verkuil09965172010-08-01 14:32:42 -03001489 case V4L2_CTRL_TYPE_INTEGER64:
Hans Verkuil000e4f92014-04-27 03:26:30 -03001490 c->value64 = *ptr.p_s64;
Hans Verkuil09965172010-08-01 14:32:42 -03001491 break;
1492 default:
Hans Verkuil000e4f92014-04-27 03:26:30 -03001493 c->value = *ptr.p_s32;
1494 break;
1495 }
1496 return 0;
1497}
1498
1499/* Helper function: copy the current control value back to the caller */
1500static int cur_to_user(struct v4l2_ext_control *c,
1501 struct v4l2_ctrl *ctrl)
1502{
1503 return ptr_to_user(c, ctrl, ctrl->p_cur);
1504}
1505
1506/* Helper function: copy the new control value back to the caller */
1507static int new_to_user(struct v4l2_ext_control *c,
1508 struct v4l2_ctrl *ctrl)
1509{
1510 return ptr_to_user(c, ctrl, ctrl->p_new);
1511}
1512
Ricardo Ribalda953eae52015-10-29 08:10:29 -02001513/* Helper function: copy the initial control value back to the caller */
1514static int def_to_user(struct v4l2_ext_control *c, struct v4l2_ctrl *ctrl)
1515{
1516 int idx;
1517
1518 for (idx = 0; idx < ctrl->elems; idx++)
1519 ctrl->type_ops->init(ctrl, idx, ctrl->p_new);
1520
1521 return ptr_to_user(c, ctrl, ctrl->p_new);
1522}
1523
Hans Verkuil000e4f92014-04-27 03:26:30 -03001524/* Helper function: copy the caller-provider value to the given control value */
1525static int user_to_ptr(struct v4l2_ext_control *c,
1526 struct v4l2_ctrl *ctrl,
1527 union v4l2_ctrl_ptr ptr)
1528{
1529 int ret;
1530 u32 size;
1531
1532 ctrl->is_new = 1;
Hans Verkuil302ab7c2014-06-10 07:06:50 -03001533 if (ctrl->is_ptr && !ctrl->is_string) {
1534 unsigned idx;
1535
Hans Verkuil40265bb2014-06-10 07:07:38 -03001536 ret = copy_from_user(ptr.p, c->ptr, c->size) ? -EFAULT : 0;
Hans Verkuil302ab7c2014-06-10 07:06:50 -03001537 if (ret || !ctrl->is_array)
1538 return ret;
1539 for (idx = c->size / ctrl->elem_size; idx < ctrl->elems; idx++)
1540 ctrl->type_ops->init(ctrl, idx, ptr);
1541 return 0;
1542 }
Hans Verkuil000e4f92014-04-27 03:26:30 -03001543
1544 switch (ctrl->type) {
1545 case V4L2_CTRL_TYPE_INTEGER64:
1546 *ptr.p_s64 = c->value64;
1547 break;
1548 case V4L2_CTRL_TYPE_STRING:
1549 size = c->size;
1550 if (size == 0)
1551 return -ERANGE;
1552 if (size > ctrl->maximum + 1)
1553 size = ctrl->maximum + 1;
Hans Verkuil40265bb2014-06-10 07:07:38 -03001554 ret = copy_from_user(ptr.p_char, c->string, size) ? -EFAULT : 0;
Hans Verkuil000e4f92014-04-27 03:26:30 -03001555 if (!ret) {
1556 char last = ptr.p_char[size - 1];
1557
1558 ptr.p_char[size - 1] = 0;
1559 /* If the string was longer than ctrl->maximum,
1560 then return an error. */
1561 if (strlen(ptr.p_char) == ctrl->maximum && last)
1562 return -ERANGE;
1563 }
Hans Verkuil40265bb2014-06-10 07:07:38 -03001564 return ret;
Hans Verkuil000e4f92014-04-27 03:26:30 -03001565 default:
1566 *ptr.p_s32 = c->value;
Hans Verkuil09965172010-08-01 14:32:42 -03001567 break;
1568 }
1569 return 0;
1570}
1571
1572/* Helper function: copy the caller-provider value as the new control value */
1573static int user_to_new(struct v4l2_ext_control *c,
1574 struct v4l2_ctrl *ctrl)
1575{
Hans Verkuil000e4f92014-04-27 03:26:30 -03001576 return user_to_ptr(c, ctrl, ctrl->p_new);
Hans Verkuil09965172010-08-01 14:32:42 -03001577}
1578
Hans Verkuil000e4f92014-04-27 03:26:30 -03001579/* Copy the one value to another. */
1580static void ptr_to_ptr(struct v4l2_ctrl *ctrl,
1581 union v4l2_ctrl_ptr from, union v4l2_ctrl_ptr to)
Hans Verkuil09965172010-08-01 14:32:42 -03001582{
Hans Verkuil000e4f92014-04-27 03:26:30 -03001583 if (ctrl == NULL)
1584 return;
Hans Verkuil302ab7c2014-06-10 07:06:50 -03001585 memcpy(to.p, from.p, ctrl->elems * ctrl->elem_size);
Hans Verkuil09965172010-08-01 14:32:42 -03001586}
1587
1588/* Copy the new value to the current value. */
Sylwester Nawrocki2ccbe772013-01-19 15:51:55 -03001589static void new_to_cur(struct v4l2_fh *fh, struct v4l2_ctrl *ctrl, u32 ch_flags)
Hans Verkuil09965172010-08-01 14:32:42 -03001590{
Hans Verkuil000e4f92014-04-27 03:26:30 -03001591 bool changed;
Hans Verkuil6e239392011-06-07 11:13:44 -03001592
Hans Verkuil09965172010-08-01 14:32:42 -03001593 if (ctrl == NULL)
1594 return;
Hans Verkuil9ea1b7a2014-01-17 08:25:26 -03001595
1596 /* has_changed is set by cluster_changed */
1597 changed = ctrl->has_changed;
1598 if (changed)
1599 ptr_to_ptr(ctrl, ctrl->p_new, ctrl->p_cur);
Hans Verkuild9a25472014-06-12 07:54:16 -03001600
Sylwester Nawrocki2ccbe772013-01-19 15:51:55 -03001601 if (ch_flags & V4L2_EVENT_CTRL_CH_FLAGS) {
1602 /* Note: CH_FLAGS is only set for auto clusters. */
Hans Verkuil5626b8c2011-08-26 07:53:53 -03001603 ctrl->flags &=
1604 ~(V4L2_CTRL_FLAG_INACTIVE | V4L2_CTRL_FLAG_VOLATILE);
1605 if (!is_cur_manual(ctrl->cluster[0])) {
Hans Verkuil72d877c2011-06-10 05:44:36 -03001606 ctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
Hans Verkuil5626b8c2011-08-26 07:53:53 -03001607 if (ctrl->cluster[0]->has_volatiles)
1608 ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
1609 }
Hans de Goede1249a3a2011-10-31 11:16:44 -03001610 fh = NULL;
Hans Verkuil72d877c2011-06-10 05:44:36 -03001611 }
Sylwester Nawrocki2ccbe772013-01-19 15:51:55 -03001612 if (changed || ch_flags) {
Hans Verkuil639884a2011-07-05 07:09:26 -03001613 /* If a control was changed that was not one of the controls
1614 modified by the application, then send the event to all. */
1615 if (!ctrl->is_new)
1616 fh = NULL;
Hans Verkuil6e239392011-06-07 11:13:44 -03001617 send_event(fh, ctrl,
Sylwester Nawrocki2ccbe772013-01-19 15:51:55 -03001618 (changed ? V4L2_EVENT_CTRL_CH_VALUE : 0) | ch_flags);
Hans Verkuil8ac7a942012-09-07 04:46:39 -03001619 if (ctrl->call_notify && changed && ctrl->handler->notify)
1620 ctrl->handler->notify(ctrl, ctrl->handler->notify_priv);
Hans Verkuil639884a2011-07-05 07:09:26 -03001621 }
Hans Verkuil09965172010-08-01 14:32:42 -03001622}
1623
1624/* Copy the current value to the new value */
1625static void cur_to_new(struct v4l2_ctrl *ctrl)
1626{
1627 if (ctrl == NULL)
1628 return;
Hans Verkuil000e4f92014-04-27 03:26:30 -03001629 ptr_to_ptr(ctrl, ctrl->p_cur, ctrl->p_new);
Hans Verkuil09965172010-08-01 14:32:42 -03001630}
1631
1632/* Return non-zero if one or more of the controls in the cluster has a new
1633 value that differs from the current value. */
1634static int cluster_changed(struct v4l2_ctrl *master)
1635{
Hans Verkuil9ea1b7a2014-01-17 08:25:26 -03001636 bool changed = false;
Hans Verkuil302ab7c2014-06-10 07:06:50 -03001637 unsigned idx;
Hans Verkuil09965172010-08-01 14:32:42 -03001638 int i;
1639
Hans Verkuil9ea1b7a2014-01-17 08:25:26 -03001640 for (i = 0; i < master->ncontrols; i++) {
Hans Verkuil09965172010-08-01 14:32:42 -03001641 struct v4l2_ctrl *ctrl = master->cluster[i];
Hans Verkuil302ab7c2014-06-10 07:06:50 -03001642 bool ctrl_changed = false;
Hans Verkuil09965172010-08-01 14:32:42 -03001643
1644 if (ctrl == NULL)
1645 continue;
Ricardo Ribalda45f014c5262015-03-20 10:55:37 -03001646
1647 if (ctrl->flags & V4L2_CTRL_FLAG_EXECUTE_ON_WRITE)
1648 changed = ctrl_changed = true;
1649
Ricardo Ribaldab08d8d22015-03-20 10:30:46 -03001650 /*
1651 * Set has_changed to false to avoid generating
1652 * the event V4L2_EVENT_CTRL_CH_VALUE
1653 */
1654 if (ctrl->flags & V4L2_CTRL_FLAG_VOLATILE) {
1655 ctrl->has_changed = false;
1656 continue;
1657 }
1658
Hans Verkuil302ab7c2014-06-10 07:06:50 -03001659 for (idx = 0; !ctrl_changed && idx < ctrl->elems; idx++)
1660 ctrl_changed = !ctrl->type_ops->equal(ctrl, idx,
Hans Verkuil998e7652014-06-10 07:55:00 -03001661 ctrl->p_cur, ctrl->p_new);
Hans Verkuil302ab7c2014-06-10 07:06:50 -03001662 ctrl->has_changed = ctrl_changed;
Hans Verkuil9ea1b7a2014-01-17 08:25:26 -03001663 changed |= ctrl->has_changed;
Hans Verkuil09965172010-08-01 14:32:42 -03001664 }
Hans Verkuil9ea1b7a2014-01-17 08:25:26 -03001665 return changed;
Hans Verkuil09965172010-08-01 14:32:42 -03001666}
1667
Sylwester Nawrocki2ccbe772013-01-19 15:51:55 -03001668/* Control range checking */
1669static int check_range(enum v4l2_ctrl_type type,
Hans Verkuil0ba2aeb2014-04-16 09:41:25 -03001670 s64 min, s64 max, u64 step, s64 def)
Sylwester Nawrocki2ccbe772013-01-19 15:51:55 -03001671{
1672 switch (type) {
1673 case V4L2_CTRL_TYPE_BOOLEAN:
1674 if (step != 1 || max > 1 || min < 0)
1675 return -ERANGE;
1676 /* fall through */
Hans Verkuildda4a4d2014-06-10 07:30:04 -03001677 case V4L2_CTRL_TYPE_U8:
1678 case V4L2_CTRL_TYPE_U16:
Hans Verkuil811c5082014-07-21 10:45:37 -03001679 case V4L2_CTRL_TYPE_U32:
Sylwester Nawrocki2ccbe772013-01-19 15:51:55 -03001680 case V4L2_CTRL_TYPE_INTEGER:
Hans Verkuil0ba2aeb2014-04-16 09:41:25 -03001681 case V4L2_CTRL_TYPE_INTEGER64:
1682 if (step == 0 || min > max || def < min || def > max)
Sylwester Nawrocki2ccbe772013-01-19 15:51:55 -03001683 return -ERANGE;
1684 return 0;
1685 case V4L2_CTRL_TYPE_BITMASK:
1686 if (step || min || !max || (def & ~max))
1687 return -ERANGE;
1688 return 0;
1689 case V4L2_CTRL_TYPE_MENU:
1690 case V4L2_CTRL_TYPE_INTEGER_MENU:
1691 if (min > max || def < min || def > max)
1692 return -ERANGE;
1693 /* Note: step == menu_skip_mask for menu controls.
1694 So here we check if the default value is masked out. */
1695 if (step && ((1 << def) & step))
1696 return -EINVAL;
1697 return 0;
1698 case V4L2_CTRL_TYPE_STRING:
1699 if (min > max || min < 0 || step < 1 || def)
1700 return -ERANGE;
1701 return 0;
1702 default:
1703 return 0;
1704 }
1705}
1706
Laurent Pinchart03d52852012-07-23 09:15:21 -03001707/* Validate a new control */
Hans Verkuil7a7f1ab2014-09-22 11:08:55 -03001708static int validate_new(const struct v4l2_ctrl *ctrl, union v4l2_ctrl_ptr p_new)
Hans Verkuil09965172010-08-01 14:32:42 -03001709{
Hans Verkuil302ab7c2014-06-10 07:06:50 -03001710 unsigned idx;
1711 int err = 0;
Hans Verkuil09965172010-08-01 14:32:42 -03001712
Hans Verkuil7a7f1ab2014-09-22 11:08:55 -03001713 for (idx = 0; !err && idx < ctrl->elems; idx++)
1714 err = ctrl->type_ops->validate(ctrl, idx, p_new);
Hans Verkuil302ab7c2014-06-10 07:06:50 -03001715 return err;
Hans Verkuil09965172010-08-01 14:32:42 -03001716}
1717
1718static inline u32 node2id(struct list_head *node)
1719{
1720 return list_entry(node, struct v4l2_ctrl_ref, node)->ctrl->id;
1721}
1722
1723/* Set the handler's error code if it wasn't set earlier already */
1724static inline int handler_set_err(struct v4l2_ctrl_handler *hdl, int err)
1725{
1726 if (hdl->error == 0)
1727 hdl->error = err;
1728 return err;
1729}
1730
1731/* Initialize the handler */
Andy Walls6cd247e2013-03-09 05:55:11 -03001732int v4l2_ctrl_handler_init_class(struct v4l2_ctrl_handler *hdl,
1733 unsigned nr_of_controls_hint,
1734 struct lock_class_key *key, const char *name)
Hans Verkuil09965172010-08-01 14:32:42 -03001735{
Sakari Ailus77e7c4e2012-01-24 21:05:34 -03001736 hdl->lock = &hdl->_lock;
1737 mutex_init(hdl->lock);
Andy Walls6cd247e2013-03-09 05:55:11 -03001738 lockdep_set_class_and_name(hdl->lock, key, name);
Hans Verkuil09965172010-08-01 14:32:42 -03001739 INIT_LIST_HEAD(&hdl->ctrls);
1740 INIT_LIST_HEAD(&hdl->ctrl_refs);
1741 hdl->nr_of_buckets = 1 + nr_of_controls_hint / 8;
Thomas Meyer9884d7b2011-11-29 17:08:00 -03001742 hdl->buckets = kcalloc(hdl->nr_of_buckets, sizeof(hdl->buckets[0]),
1743 GFP_KERNEL);
Hans Verkuil09965172010-08-01 14:32:42 -03001744 hdl->error = hdl->buckets ? 0 : -ENOMEM;
1745 return hdl->error;
1746}
Andy Walls6cd247e2013-03-09 05:55:11 -03001747EXPORT_SYMBOL(v4l2_ctrl_handler_init_class);
Hans Verkuil09965172010-08-01 14:32:42 -03001748
1749/* Free all controls and control refs */
1750void v4l2_ctrl_handler_free(struct v4l2_ctrl_handler *hdl)
1751{
1752 struct v4l2_ctrl_ref *ref, *next_ref;
1753 struct v4l2_ctrl *ctrl, *next_ctrl;
Hans Verkuil77068d32011-06-13 18:55:58 -03001754 struct v4l2_subscribed_event *sev, *next_sev;
Hans Verkuil09965172010-08-01 14:32:42 -03001755
1756 if (hdl == NULL || hdl->buckets == NULL)
1757 return;
1758
Sakari Ailus77e7c4e2012-01-24 21:05:34 -03001759 mutex_lock(hdl->lock);
Hans Verkuil09965172010-08-01 14:32:42 -03001760 /* Free all nodes */
1761 list_for_each_entry_safe(ref, next_ref, &hdl->ctrl_refs, node) {
1762 list_del(&ref->node);
1763 kfree(ref);
1764 }
1765 /* Free all controls owned by the handler */
1766 list_for_each_entry_safe(ctrl, next_ctrl, &hdl->ctrls, node) {
1767 list_del(&ctrl->node);
Hans Verkuil77068d32011-06-13 18:55:58 -03001768 list_for_each_entry_safe(sev, next_sev, &ctrl->ev_subs, node)
1769 list_del(&sev->node);
Hans Verkuil09965172010-08-01 14:32:42 -03001770 kfree(ctrl);
1771 }
1772 kfree(hdl->buckets);
1773 hdl->buckets = NULL;
1774 hdl->cached = NULL;
1775 hdl->error = 0;
Sakari Ailus77e7c4e2012-01-24 21:05:34 -03001776 mutex_unlock(hdl->lock);
Hans Verkuil09965172010-08-01 14:32:42 -03001777}
1778EXPORT_SYMBOL(v4l2_ctrl_handler_free);
1779
1780/* For backwards compatibility: V4L2_CID_PRIVATE_BASE should no longer
1781 be used except in G_CTRL, S_CTRL, QUERYCTRL and QUERYMENU when dealing
1782 with applications that do not use the NEXT_CTRL flag.
1783
1784 We just find the n-th private user control. It's O(N), but that should not
1785 be an issue in this particular case. */
1786static struct v4l2_ctrl_ref *find_private_ref(
1787 struct v4l2_ctrl_handler *hdl, u32 id)
1788{
1789 struct v4l2_ctrl_ref *ref;
1790
1791 id -= V4L2_CID_PRIVATE_BASE;
1792 list_for_each_entry(ref, &hdl->ctrl_refs, node) {
1793 /* Search for private user controls that are compatible with
1794 VIDIOC_G/S_CTRL. */
Ricardo Ribalda0f8017b2015-10-29 08:10:28 -02001795 if (V4L2_CTRL_ID2WHICH(ref->ctrl->id) == V4L2_CTRL_CLASS_USER &&
Hans Verkuil09965172010-08-01 14:32:42 -03001796 V4L2_CTRL_DRIVER_PRIV(ref->ctrl->id)) {
Hans Verkuild9a25472014-06-12 07:54:16 -03001797 if (!ref->ctrl->is_int)
Hans Verkuil09965172010-08-01 14:32:42 -03001798 continue;
1799 if (id == 0)
1800 return ref;
1801 id--;
1802 }
1803 }
1804 return NULL;
1805}
1806
1807/* Find a control with the given ID. */
1808static struct v4l2_ctrl_ref *find_ref(struct v4l2_ctrl_handler *hdl, u32 id)
1809{
1810 struct v4l2_ctrl_ref *ref;
1811 int bucket;
1812
1813 id &= V4L2_CTRL_ID_MASK;
1814
1815 /* Old-style private controls need special handling */
1816 if (id >= V4L2_CID_PRIVATE_BASE)
1817 return find_private_ref(hdl, id);
1818 bucket = id % hdl->nr_of_buckets;
1819
1820 /* Simple optimization: cache the last control found */
1821 if (hdl->cached && hdl->cached->ctrl->id == id)
1822 return hdl->cached;
1823
1824 /* Not in cache, search the hash */
1825 ref = hdl->buckets ? hdl->buckets[bucket] : NULL;
1826 while (ref && ref->ctrl->id != id)
1827 ref = ref->next;
1828
1829 if (ref)
1830 hdl->cached = ref; /* cache it! */
1831 return ref;
1832}
1833
1834/* Find a control with the given ID. Take the handler's lock first. */
1835static struct v4l2_ctrl_ref *find_ref_lock(
1836 struct v4l2_ctrl_handler *hdl, u32 id)
1837{
1838 struct v4l2_ctrl_ref *ref = NULL;
1839
1840 if (hdl) {
Sakari Ailus77e7c4e2012-01-24 21:05:34 -03001841 mutex_lock(hdl->lock);
Hans Verkuil09965172010-08-01 14:32:42 -03001842 ref = find_ref(hdl, id);
Sakari Ailus77e7c4e2012-01-24 21:05:34 -03001843 mutex_unlock(hdl->lock);
Hans Verkuil09965172010-08-01 14:32:42 -03001844 }
1845 return ref;
1846}
1847
1848/* Find a control with the given ID. */
1849struct v4l2_ctrl *v4l2_ctrl_find(struct v4l2_ctrl_handler *hdl, u32 id)
1850{
1851 struct v4l2_ctrl_ref *ref = find_ref_lock(hdl, id);
1852
1853 return ref ? ref->ctrl : NULL;
1854}
1855EXPORT_SYMBOL(v4l2_ctrl_find);
1856
1857/* Allocate a new v4l2_ctrl_ref and hook it into the handler. */
1858static int handler_new_ref(struct v4l2_ctrl_handler *hdl,
1859 struct v4l2_ctrl *ctrl)
1860{
1861 struct v4l2_ctrl_ref *ref;
1862 struct v4l2_ctrl_ref *new_ref;
1863 u32 id = ctrl->id;
Ricardo Ribalda0f8017b2015-10-29 08:10:28 -02001864 u32 class_ctrl = V4L2_CTRL_ID2WHICH(id) | 1;
Hans Verkuil09965172010-08-01 14:32:42 -03001865 int bucket = id % hdl->nr_of_buckets; /* which bucket to use */
1866
Hans Verkuild9a25472014-06-12 07:54:16 -03001867 /*
1868 * Automatically add the control class if it is not yet present and
1869 * the new control is not a compound control.
1870 */
1871 if (ctrl->type < V4L2_CTRL_COMPOUND_TYPES &&
1872 id != class_ctrl && find_ref_lock(hdl, class_ctrl) == NULL)
Hans Verkuil09965172010-08-01 14:32:42 -03001873 if (!v4l2_ctrl_new_std(hdl, NULL, class_ctrl, 0, 0, 0, 0))
1874 return hdl->error;
1875
1876 if (hdl->error)
1877 return hdl->error;
1878
1879 new_ref = kzalloc(sizeof(*new_ref), GFP_KERNEL);
1880 if (!new_ref)
1881 return handler_set_err(hdl, -ENOMEM);
1882 new_ref->ctrl = ctrl;
1883 if (ctrl->handler == hdl) {
1884 /* By default each control starts in a cluster of its own.
1885 new_ref->ctrl is basically a cluster array with one
1886 element, so that's perfect to use as the cluster pointer.
1887 But only do this for the handler that owns the control. */
1888 ctrl->cluster = &new_ref->ctrl;
1889 ctrl->ncontrols = 1;
1890 }
1891
1892 INIT_LIST_HEAD(&new_ref->node);
1893
Sakari Ailus77e7c4e2012-01-24 21:05:34 -03001894 mutex_lock(hdl->lock);
Hans Verkuil09965172010-08-01 14:32:42 -03001895
1896 /* Add immediately at the end of the list if the list is empty, or if
1897 the last element in the list has a lower ID.
1898 This ensures that when elements are added in ascending order the
1899 insertion is an O(1) operation. */
1900 if (list_empty(&hdl->ctrl_refs) || id > node2id(hdl->ctrl_refs.prev)) {
1901 list_add_tail(&new_ref->node, &hdl->ctrl_refs);
1902 goto insert_in_hash;
1903 }
1904
1905 /* Find insert position in sorted list */
1906 list_for_each_entry(ref, &hdl->ctrl_refs, node) {
1907 if (ref->ctrl->id < id)
1908 continue;
1909 /* Don't add duplicates */
1910 if (ref->ctrl->id == id) {
1911 kfree(new_ref);
1912 goto unlock;
1913 }
1914 list_add(&new_ref->node, ref->node.prev);
1915 break;
1916 }
1917
1918insert_in_hash:
1919 /* Insert the control node in the hash */
1920 new_ref->next = hdl->buckets[bucket];
1921 hdl->buckets[bucket] = new_ref;
1922
1923unlock:
Sakari Ailus77e7c4e2012-01-24 21:05:34 -03001924 mutex_unlock(hdl->lock);
Hans Verkuil09965172010-08-01 14:32:42 -03001925 return 0;
1926}
1927
1928/* Add a new control */
1929static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl,
1930 const struct v4l2_ctrl_ops *ops,
Hans Verkuil01760772014-04-27 03:22:17 -03001931 const struct v4l2_ctrl_type_ops *type_ops,
Hans Verkuil09965172010-08-01 14:32:42 -03001932 u32 id, const char *name, enum v4l2_ctrl_type type,
Hans Verkuil0ba2aeb2014-04-16 09:41:25 -03001933 s64 min, s64 max, u64 step, s64 def,
Hans Verkuil20d88ee2014-06-12 07:55:21 -03001934 const u32 dims[V4L2_CTRL_MAX_DIMS], u32 elem_size,
Sakari Ailusce580fe2011-08-04 13:51:11 -03001935 u32 flags, const char * const *qmenu,
1936 const s64 *qmenu_int, void *priv)
Hans Verkuil09965172010-08-01 14:32:42 -03001937{
1938 struct v4l2_ctrl *ctrl;
Hans Verkuild9a25472014-06-12 07:54:16 -03001939 unsigned sz_extra;
Hans Verkuil20d88ee2014-06-12 07:55:21 -03001940 unsigned nr_of_dims = 0;
1941 unsigned elems = 1;
Hans Verkuil998e7652014-06-10 07:55:00 -03001942 bool is_array;
1943 unsigned tot_ctrl_size;
Hans Verkuil302ab7c2014-06-10 07:06:50 -03001944 unsigned idx;
Hans Verkuild9a25472014-06-12 07:54:16 -03001945 void *data;
Sylwester Nawrocki2ccbe772013-01-19 15:51:55 -03001946 int err;
Hans Verkuil09965172010-08-01 14:32:42 -03001947
1948 if (hdl->error)
1949 return NULL;
1950
Hans Verkuil20d88ee2014-06-12 07:55:21 -03001951 while (dims && dims[nr_of_dims]) {
1952 elems *= dims[nr_of_dims];
1953 nr_of_dims++;
1954 if (nr_of_dims == V4L2_CTRL_MAX_DIMS)
1955 break;
1956 }
Hans Verkuil998e7652014-06-10 07:55:00 -03001957 is_array = nr_of_dims > 0;
Hans Verkuil20d88ee2014-06-12 07:55:21 -03001958
Hans Verkuildda4a4d2014-06-10 07:30:04 -03001959 /* Prefill elem_size for all types handled by std_type_ops */
1960 switch (type) {
1961 case V4L2_CTRL_TYPE_INTEGER64:
Hans Verkuild9a25472014-06-12 07:54:16 -03001962 elem_size = sizeof(s64);
Hans Verkuildda4a4d2014-06-10 07:30:04 -03001963 break;
1964 case V4L2_CTRL_TYPE_STRING:
Hans Verkuild9a25472014-06-12 07:54:16 -03001965 elem_size = max + 1;
Hans Verkuildda4a4d2014-06-10 07:30:04 -03001966 break;
1967 case V4L2_CTRL_TYPE_U8:
1968 elem_size = sizeof(u8);
1969 break;
1970 case V4L2_CTRL_TYPE_U16:
1971 elem_size = sizeof(u16);
1972 break;
Hans Verkuil811c5082014-07-21 10:45:37 -03001973 case V4L2_CTRL_TYPE_U32:
1974 elem_size = sizeof(u32);
1975 break;
Hans Verkuildda4a4d2014-06-10 07:30:04 -03001976 default:
1977 if (type < V4L2_CTRL_COMPOUND_TYPES)
1978 elem_size = sizeof(s32);
1979 break;
1980 }
Hans Verkuil998e7652014-06-10 07:55:00 -03001981 tot_ctrl_size = elem_size * elems;
Hans Verkuild9a25472014-06-12 07:54:16 -03001982
Hans Verkuil09965172010-08-01 14:32:42 -03001983 /* Sanity checks */
Hans Verkuil998e7652014-06-10 07:55:00 -03001984 if (id == 0 || name == NULL || !elem_size ||
1985 id >= V4L2_CID_PRIVATE_BASE ||
Hans Verkuil09965172010-08-01 14:32:42 -03001986 (type == V4L2_CTRL_TYPE_MENU && qmenu == NULL) ||
Sylwester Nawrocki2ccbe772013-01-19 15:51:55 -03001987 (type == V4L2_CTRL_TYPE_INTEGER_MENU && qmenu_int == NULL)) {
Hans Verkuil09965172010-08-01 14:32:42 -03001988 handler_set_err(hdl, -ERANGE);
1989 return NULL;
1990 }
Sylwester Nawrocki2ccbe772013-01-19 15:51:55 -03001991 err = check_range(type, min, max, step, def);
1992 if (err) {
1993 handler_set_err(hdl, err);
Hans Verkuil02ac0482010-12-29 14:27:05 -03001994 return NULL;
1995 }
Hans Verkuilfa4d7092011-05-23 04:07:05 -03001996 if (type == V4L2_CTRL_TYPE_BITMASK && ((def & ~max) || min || step)) {
1997 handler_set_err(hdl, -ERANGE);
1998 return NULL;
1999 }
Hans Verkuil998e7652014-06-10 07:55:00 -03002000 if (is_array &&
2001 (type == V4L2_CTRL_TYPE_BUTTON ||
2002 type == V4L2_CTRL_TYPE_CTRL_CLASS)) {
2003 handler_set_err(hdl, -EINVAL);
2004 return NULL;
2005 }
Hans Verkuil09965172010-08-01 14:32:42 -03002006
Hans Verkuild9a25472014-06-12 07:54:16 -03002007 sz_extra = 0;
Hans Verkuil09965172010-08-01 14:32:42 -03002008 if (type == V4L2_CTRL_TYPE_BUTTON)
Ricardo Ribaldaef66c0c2015-03-20 11:21:28 -03002009 flags |= V4L2_CTRL_FLAG_WRITE_ONLY |
2010 V4L2_CTRL_FLAG_EXECUTE_ON_WRITE;
Hans Verkuil09965172010-08-01 14:32:42 -03002011 else if (type == V4L2_CTRL_TYPE_CTRL_CLASS)
2012 flags |= V4L2_CTRL_FLAG_READ_ONLY;
Hans Verkuil2a9ec372014-04-27 03:38:13 -03002013 else if (type == V4L2_CTRL_TYPE_INTEGER64 ||
2014 type == V4L2_CTRL_TYPE_STRING ||
Hans Verkuil998e7652014-06-10 07:55:00 -03002015 type >= V4L2_CTRL_COMPOUND_TYPES ||
2016 is_array)
2017 sz_extra += 2 * tot_ctrl_size;
Hans Verkuil09965172010-08-01 14:32:42 -03002018
2019 ctrl = kzalloc(sizeof(*ctrl) + sz_extra, GFP_KERNEL);
2020 if (ctrl == NULL) {
2021 handler_set_err(hdl, -ENOMEM);
2022 return NULL;
2023 }
2024
2025 INIT_LIST_HEAD(&ctrl->node);
Hans Verkuil77068d32011-06-13 18:55:58 -03002026 INIT_LIST_HEAD(&ctrl->ev_subs);
Hans Verkuil09965172010-08-01 14:32:42 -03002027 ctrl->handler = hdl;
2028 ctrl->ops = ops;
Hans Verkuil01760772014-04-27 03:22:17 -03002029 ctrl->type_ops = type_ops ? type_ops : &std_type_ops;
Hans Verkuil09965172010-08-01 14:32:42 -03002030 ctrl->id = id;
2031 ctrl->name = name;
2032 ctrl->type = type;
2033 ctrl->flags = flags;
2034 ctrl->minimum = min;
2035 ctrl->maximum = max;
2036 ctrl->step = step;
Hans Verkuild9a25472014-06-12 07:54:16 -03002037 ctrl->default_value = def;
Hans Verkuil998e7652014-06-10 07:55:00 -03002038 ctrl->is_string = !is_array && type == V4L2_CTRL_TYPE_STRING;
2039 ctrl->is_ptr = is_array || type >= V4L2_CTRL_COMPOUND_TYPES || ctrl->is_string;
Hans Verkuild9a25472014-06-12 07:54:16 -03002040 ctrl->is_int = !ctrl->is_ptr && type != V4L2_CTRL_TYPE_INTEGER64;
Hans Verkuil998e7652014-06-10 07:55:00 -03002041 ctrl->is_array = is_array;
Hans Verkuil20d88ee2014-06-12 07:55:21 -03002042 ctrl->elems = elems;
2043 ctrl->nr_of_dims = nr_of_dims;
2044 if (nr_of_dims)
2045 memcpy(ctrl->dims, dims, nr_of_dims * sizeof(dims[0]));
Hans Verkuild9a25472014-06-12 07:54:16 -03002046 ctrl->elem_size = elem_size;
Sakari Ailusce580fe2011-08-04 13:51:11 -03002047 if (type == V4L2_CTRL_TYPE_MENU)
2048 ctrl->qmenu = qmenu;
2049 else if (type == V4L2_CTRL_TYPE_INTEGER_MENU)
2050 ctrl->qmenu_int = qmenu_int;
Hans Verkuil09965172010-08-01 14:32:42 -03002051 ctrl->priv = priv;
Hans Verkuild9a25472014-06-12 07:54:16 -03002052 ctrl->cur.val = ctrl->val = def;
Hans Verkuil2a9ec372014-04-27 03:38:13 -03002053 data = &ctrl[1];
Hans Verkuil09965172010-08-01 14:32:42 -03002054
Hans Verkuil2a9ec372014-04-27 03:38:13 -03002055 if (!ctrl->is_int) {
2056 ctrl->p_new.p = data;
Hans Verkuil998e7652014-06-10 07:55:00 -03002057 ctrl->p_cur.p = data + tot_ctrl_size;
Hans Verkuil01760772014-04-27 03:22:17 -03002058 } else {
2059 ctrl->p_new.p = &ctrl->val;
2060 ctrl->p_cur.p = &ctrl->cur.val;
Hans Verkuil09965172010-08-01 14:32:42 -03002061 }
Hans Verkuil302ab7c2014-06-10 07:06:50 -03002062 for (idx = 0; idx < elems; idx++) {
2063 ctrl->type_ops->init(ctrl, idx, ctrl->p_cur);
2064 ctrl->type_ops->init(ctrl, idx, ctrl->p_new);
2065 }
Hans Verkuil01760772014-04-27 03:22:17 -03002066
Hans Verkuil09965172010-08-01 14:32:42 -03002067 if (handler_new_ref(hdl, ctrl)) {
2068 kfree(ctrl);
2069 return NULL;
2070 }
Sakari Ailus77e7c4e2012-01-24 21:05:34 -03002071 mutex_lock(hdl->lock);
Hans Verkuil09965172010-08-01 14:32:42 -03002072 list_add_tail(&ctrl->node, &hdl->ctrls);
Sakari Ailus77e7c4e2012-01-24 21:05:34 -03002073 mutex_unlock(hdl->lock);
Hans Verkuil09965172010-08-01 14:32:42 -03002074 return ctrl;
2075}
2076
2077struct v4l2_ctrl *v4l2_ctrl_new_custom(struct v4l2_ctrl_handler *hdl,
2078 const struct v4l2_ctrl_config *cfg, void *priv)
2079{
2080 bool is_menu;
2081 struct v4l2_ctrl *ctrl;
2082 const char *name = cfg->name;
Hans Verkuil513521e2010-12-29 14:25:52 -03002083 const char * const *qmenu = cfg->qmenu;
Sakari Ailusce580fe2011-08-04 13:51:11 -03002084 const s64 *qmenu_int = cfg->qmenu_int;
Hans Verkuil09965172010-08-01 14:32:42 -03002085 enum v4l2_ctrl_type type = cfg->type;
2086 u32 flags = cfg->flags;
Hans Verkuil0ba2aeb2014-04-16 09:41:25 -03002087 s64 min = cfg->min;
2088 s64 max = cfg->max;
2089 u64 step = cfg->step;
2090 s64 def = cfg->def;
Hans Verkuil09965172010-08-01 14:32:42 -03002091
2092 if (name == NULL)
2093 v4l2_ctrl_fill(cfg->id, &name, &type, &min, &max, &step,
2094 &def, &flags);
2095
Sakari Ailusce580fe2011-08-04 13:51:11 -03002096 is_menu = (cfg->type == V4L2_CTRL_TYPE_MENU ||
2097 cfg->type == V4L2_CTRL_TYPE_INTEGER_MENU);
Hans Verkuil09965172010-08-01 14:32:42 -03002098 if (is_menu)
2099 WARN_ON(step);
2100 else
2101 WARN_ON(cfg->menu_skip_mask);
Sakari Ailusce580fe2011-08-04 13:51:11 -03002102 if (cfg->type == V4L2_CTRL_TYPE_MENU && qmenu == NULL)
Hans Verkuil09965172010-08-01 14:32:42 -03002103 qmenu = v4l2_ctrl_get_menu(cfg->id);
Sakari Ailusce580fe2011-08-04 13:51:11 -03002104 else if (cfg->type == V4L2_CTRL_TYPE_INTEGER_MENU &&
2105 qmenu_int == NULL) {
2106 handler_set_err(hdl, -EINVAL);
2107 return NULL;
2108 }
Hans Verkuil09965172010-08-01 14:32:42 -03002109
Hans Verkuil01760772014-04-27 03:22:17 -03002110 ctrl = v4l2_ctrl_new(hdl, cfg->ops, cfg->type_ops, cfg->id, name,
Hans Verkuil09965172010-08-01 14:32:42 -03002111 type, min, max,
Hans Verkuil20d88ee2014-06-12 07:55:21 -03002112 is_menu ? cfg->menu_skip_mask : step, def,
2113 cfg->dims, cfg->elem_size,
Hans Verkuild9a25472014-06-12 07:54:16 -03002114 flags, qmenu, qmenu_int, priv);
Hans Verkuil88365102011-08-26 07:35:14 -03002115 if (ctrl)
Hans Verkuil09965172010-08-01 14:32:42 -03002116 ctrl->is_private = cfg->is_private;
Hans Verkuil09965172010-08-01 14:32:42 -03002117 return ctrl;
2118}
2119EXPORT_SYMBOL(v4l2_ctrl_new_custom);
2120
2121/* Helper function for standard non-menu controls */
2122struct v4l2_ctrl *v4l2_ctrl_new_std(struct v4l2_ctrl_handler *hdl,
2123 const struct v4l2_ctrl_ops *ops,
Hans Verkuil0ba2aeb2014-04-16 09:41:25 -03002124 u32 id, s64 min, s64 max, u64 step, s64 def)
Hans Verkuil09965172010-08-01 14:32:42 -03002125{
2126 const char *name;
2127 enum v4l2_ctrl_type type;
2128 u32 flags;
2129
2130 v4l2_ctrl_fill(id, &name, &type, &min, &max, &step, &def, &flags);
Hans Verkuild9a25472014-06-12 07:54:16 -03002131 if (type == V4L2_CTRL_TYPE_MENU ||
2132 type == V4L2_CTRL_TYPE_INTEGER_MENU ||
2133 type >= V4L2_CTRL_COMPOUND_TYPES) {
Hans Verkuil09965172010-08-01 14:32:42 -03002134 handler_set_err(hdl, -EINVAL);
2135 return NULL;
2136 }
Hans Verkuil01760772014-04-27 03:22:17 -03002137 return v4l2_ctrl_new(hdl, ops, NULL, id, name, type,
Hans Verkuil20d88ee2014-06-12 07:55:21 -03002138 min, max, step, def, NULL, 0,
Hans Verkuild9a25472014-06-12 07:54:16 -03002139 flags, NULL, NULL, NULL);
Hans Verkuil09965172010-08-01 14:32:42 -03002140}
2141EXPORT_SYMBOL(v4l2_ctrl_new_std);
2142
2143/* Helper function for standard menu controls */
2144struct v4l2_ctrl *v4l2_ctrl_new_std_menu(struct v4l2_ctrl_handler *hdl,
2145 const struct v4l2_ctrl_ops *ops,
Hans Verkuil0ba2aeb2014-04-16 09:41:25 -03002146 u32 id, u8 _max, u64 mask, u8 _def)
Hans Verkuil09965172010-08-01 14:32:42 -03002147{
Sylwester Nawrockid1e9b7c2013-07-09 01:24:40 -03002148 const char * const *qmenu = NULL;
2149 const s64 *qmenu_int = NULL;
Sylwester Nawrockifbbb29a2013-08-18 16:05:19 -03002150 unsigned int qmenu_int_len = 0;
Hans Verkuil09965172010-08-01 14:32:42 -03002151 const char *name;
2152 enum v4l2_ctrl_type type;
Hans Verkuil0ba2aeb2014-04-16 09:41:25 -03002153 s64 min;
2154 s64 max = _max;
2155 s64 def = _def;
2156 u64 step;
Hans Verkuil09965172010-08-01 14:32:42 -03002157 u32 flags;
2158
2159 v4l2_ctrl_fill(id, &name, &type, &min, &max, &step, &def, &flags);
Sylwester Nawrockid1e9b7c2013-07-09 01:24:40 -03002160
2161 if (type == V4L2_CTRL_TYPE_MENU)
2162 qmenu = v4l2_ctrl_get_menu(id);
2163 else if (type == V4L2_CTRL_TYPE_INTEGER_MENU)
2164 qmenu_int = v4l2_ctrl_get_int_menu(id, &qmenu_int_len);
2165
2166 if ((!qmenu && !qmenu_int) || (qmenu_int && max > qmenu_int_len)) {
Hans Verkuil09965172010-08-01 14:32:42 -03002167 handler_set_err(hdl, -EINVAL);
2168 return NULL;
2169 }
Hans Verkuil01760772014-04-27 03:22:17 -03002170 return v4l2_ctrl_new(hdl, ops, NULL, id, name, type,
Hans Verkuil20d88ee2014-06-12 07:55:21 -03002171 0, max, mask, def, NULL, 0,
Hans Verkuild9a25472014-06-12 07:54:16 -03002172 flags, qmenu, qmenu_int, NULL);
Hans Verkuil09965172010-08-01 14:32:42 -03002173}
2174EXPORT_SYMBOL(v4l2_ctrl_new_std_menu);
2175
Lad, Prabhakar117a7112012-09-18 15:54:38 -03002176/* Helper function for standard menu controls with driver defined menu */
2177struct v4l2_ctrl *v4l2_ctrl_new_std_menu_items(struct v4l2_ctrl_handler *hdl,
Hans Verkuil0ba2aeb2014-04-16 09:41:25 -03002178 const struct v4l2_ctrl_ops *ops, u32 id, u8 _max,
2179 u64 mask, u8 _def, const char * const *qmenu)
Lad, Prabhakar117a7112012-09-18 15:54:38 -03002180{
2181 enum v4l2_ctrl_type type;
2182 const char *name;
2183 u32 flags;
Hans Verkuil0ba2aeb2014-04-16 09:41:25 -03002184 u64 step;
2185 s64 min;
2186 s64 max = _max;
2187 s64 def = _def;
Lad, Prabhakar117a7112012-09-18 15:54:38 -03002188
2189 /* v4l2_ctrl_new_std_menu_items() should only be called for
2190 * standard controls without a standard menu.
2191 */
2192 if (v4l2_ctrl_get_menu(id)) {
2193 handler_set_err(hdl, -EINVAL);
2194 return NULL;
2195 }
2196
2197 v4l2_ctrl_fill(id, &name, &type, &min, &max, &step, &def, &flags);
2198 if (type != V4L2_CTRL_TYPE_MENU || qmenu == NULL) {
2199 handler_set_err(hdl, -EINVAL);
2200 return NULL;
2201 }
Hans Verkuil01760772014-04-27 03:22:17 -03002202 return v4l2_ctrl_new(hdl, ops, NULL, id, name, type,
Hans Verkuil20d88ee2014-06-12 07:55:21 -03002203 0, max, mask, def, NULL, 0,
2204 flags, qmenu, NULL, NULL);
Lad, Prabhakar117a7112012-09-18 15:54:38 -03002205
2206}
2207EXPORT_SYMBOL(v4l2_ctrl_new_std_menu_items);
2208
Sylwester Nawrocki515f3282012-05-06 15:30:44 -03002209/* Helper function for standard integer menu controls */
2210struct v4l2_ctrl *v4l2_ctrl_new_int_menu(struct v4l2_ctrl_handler *hdl,
2211 const struct v4l2_ctrl_ops *ops,
Hans Verkuil0ba2aeb2014-04-16 09:41:25 -03002212 u32 id, u8 _max, u8 _def, const s64 *qmenu_int)
Sylwester Nawrocki515f3282012-05-06 15:30:44 -03002213{
2214 const char *name;
2215 enum v4l2_ctrl_type type;
Hans Verkuil0ba2aeb2014-04-16 09:41:25 -03002216 s64 min;
2217 u64 step;
2218 s64 max = _max;
2219 s64 def = _def;
Sylwester Nawrocki515f3282012-05-06 15:30:44 -03002220 u32 flags;
2221
2222 v4l2_ctrl_fill(id, &name, &type, &min, &max, &step, &def, &flags);
2223 if (type != V4L2_CTRL_TYPE_INTEGER_MENU) {
2224 handler_set_err(hdl, -EINVAL);
2225 return NULL;
2226 }
Hans Verkuil01760772014-04-27 03:22:17 -03002227 return v4l2_ctrl_new(hdl, ops, NULL, id, name, type,
Hans Verkuil20d88ee2014-06-12 07:55:21 -03002228 0, max, 0, def, NULL, 0,
Hans Verkuild9a25472014-06-12 07:54:16 -03002229 flags, NULL, qmenu_int, NULL);
Sylwester Nawrocki515f3282012-05-06 15:30:44 -03002230}
2231EXPORT_SYMBOL(v4l2_ctrl_new_int_menu);
2232
Hans Verkuil09965172010-08-01 14:32:42 -03002233/* Add the controls from another handler to our own. */
2234int v4l2_ctrl_add_handler(struct v4l2_ctrl_handler *hdl,
Hans Verkuil34a6b7d2012-09-14 07:15:03 -03002235 struct v4l2_ctrl_handler *add,
2236 bool (*filter)(const struct v4l2_ctrl *ctrl))
Hans Verkuil09965172010-08-01 14:32:42 -03002237{
Hans Verkuil072e6602012-03-02 12:41:25 -03002238 struct v4l2_ctrl_ref *ref;
Hans Verkuil09965172010-08-01 14:32:42 -03002239 int ret = 0;
2240
2241 /* Do nothing if either handler is NULL or if they are the same */
2242 if (!hdl || !add || hdl == add)
2243 return 0;
2244 if (hdl->error)
2245 return hdl->error;
Sakari Ailus77e7c4e2012-01-24 21:05:34 -03002246 mutex_lock(add->lock);
Hans Verkuil072e6602012-03-02 12:41:25 -03002247 list_for_each_entry(ref, &add->ctrl_refs, node) {
2248 struct v4l2_ctrl *ctrl = ref->ctrl;
2249
Hans Verkuil09965172010-08-01 14:32:42 -03002250 /* Skip handler-private controls. */
2251 if (ctrl->is_private)
2252 continue;
Hans Verkuil6e239392011-06-07 11:13:44 -03002253 /* And control classes */
2254 if (ctrl->type == V4L2_CTRL_TYPE_CTRL_CLASS)
2255 continue;
Hans Verkuil34a6b7d2012-09-14 07:15:03 -03002256 /* Filter any unwanted controls */
2257 if (filter && !filter(ctrl))
2258 continue;
Hans Verkuil09965172010-08-01 14:32:42 -03002259 ret = handler_new_ref(hdl, ctrl);
2260 if (ret)
2261 break;
2262 }
Sakari Ailus77e7c4e2012-01-24 21:05:34 -03002263 mutex_unlock(add->lock);
Hans Verkuil09965172010-08-01 14:32:42 -03002264 return ret;
2265}
2266EXPORT_SYMBOL(v4l2_ctrl_add_handler);
2267
Hans Verkuil34a6b7d2012-09-14 07:15:03 -03002268bool v4l2_ctrl_radio_filter(const struct v4l2_ctrl *ctrl)
2269{
Ricardo Ribalda0f8017b2015-10-29 08:10:28 -02002270 if (V4L2_CTRL_ID2WHICH(ctrl->id) == V4L2_CTRL_CLASS_FM_TX)
Hans Verkuil34a6b7d2012-09-14 07:15:03 -03002271 return true;
Ricardo Ribalda0f8017b2015-10-29 08:10:28 -02002272 if (V4L2_CTRL_ID2WHICH(ctrl->id) == V4L2_CTRL_CLASS_FM_RX)
Hans Verkuil3963d4f2013-06-02 07:55:59 -03002273 return true;
Hans Verkuil34a6b7d2012-09-14 07:15:03 -03002274 switch (ctrl->id) {
2275 case V4L2_CID_AUDIO_MUTE:
2276 case V4L2_CID_AUDIO_VOLUME:
2277 case V4L2_CID_AUDIO_BALANCE:
2278 case V4L2_CID_AUDIO_BASS:
2279 case V4L2_CID_AUDIO_TREBLE:
2280 case V4L2_CID_AUDIO_LOUDNESS:
2281 return true;
2282 default:
2283 break;
2284 }
2285 return false;
2286}
2287EXPORT_SYMBOL(v4l2_ctrl_radio_filter);
2288
Hans Verkuil09965172010-08-01 14:32:42 -03002289/* Cluster controls */
2290void v4l2_ctrl_cluster(unsigned ncontrols, struct v4l2_ctrl **controls)
2291{
Hans Verkuil5626b8c2011-08-26 07:53:53 -03002292 bool has_volatiles = false;
Hans Verkuil09965172010-08-01 14:32:42 -03002293 int i;
2294
2295 /* The first control is the master control and it must not be NULL */
Hans Verkuilc817d922014-02-21 06:16:32 -03002296 if (WARN_ON(ncontrols == 0 || controls[0] == NULL))
2297 return;
Hans Verkuil09965172010-08-01 14:32:42 -03002298
2299 for (i = 0; i < ncontrols; i++) {
2300 if (controls[i]) {
2301 controls[i]->cluster = controls;
2302 controls[i]->ncontrols = ncontrols;
Hans Verkuil5626b8c2011-08-26 07:53:53 -03002303 if (controls[i]->flags & V4L2_CTRL_FLAG_VOLATILE)
2304 has_volatiles = true;
Hans Verkuil09965172010-08-01 14:32:42 -03002305 }
2306 }
Hans Verkuil5626b8c2011-08-26 07:53:53 -03002307 controls[0]->has_volatiles = has_volatiles;
Hans Verkuil09965172010-08-01 14:32:42 -03002308}
2309EXPORT_SYMBOL(v4l2_ctrl_cluster);
2310
Hans Verkuil72d877c2011-06-10 05:44:36 -03002311void v4l2_ctrl_auto_cluster(unsigned ncontrols, struct v4l2_ctrl **controls,
2312 u8 manual_val, bool set_volatile)
2313{
2314 struct v4l2_ctrl *master = controls[0];
Hans Verkuil5626b8c2011-08-26 07:53:53 -03002315 u32 flag = 0;
Hans Verkuil72d877c2011-06-10 05:44:36 -03002316 int i;
2317
2318 v4l2_ctrl_cluster(ncontrols, controls);
2319 WARN_ON(ncontrols <= 1);
Hans Verkuil82a7c042011-06-28 10:43:13 -03002320 WARN_ON(manual_val < master->minimum || manual_val > master->maximum);
Hans Verkuil5626b8c2011-08-26 07:53:53 -03002321 WARN_ON(set_volatile && !has_op(master, g_volatile_ctrl));
Hans Verkuil72d877c2011-06-10 05:44:36 -03002322 master->is_auto = true;
Hans Verkuil5626b8c2011-08-26 07:53:53 -03002323 master->has_volatiles = set_volatile;
Hans Verkuil72d877c2011-06-10 05:44:36 -03002324 master->manual_mode_value = manual_val;
2325 master->flags |= V4L2_CTRL_FLAG_UPDATE;
Hans Verkuil5626b8c2011-08-26 07:53:53 -03002326
2327 if (!is_cur_manual(master))
2328 flag = V4L2_CTRL_FLAG_INACTIVE |
2329 (set_volatile ? V4L2_CTRL_FLAG_VOLATILE : 0);
Hans Verkuil72d877c2011-06-10 05:44:36 -03002330
2331 for (i = 1; i < ncontrols; i++)
Hans Verkuil88365102011-08-26 07:35:14 -03002332 if (controls[i])
Hans Verkuil72d877c2011-06-10 05:44:36 -03002333 controls[i]->flags |= flag;
Hans Verkuil72d877c2011-06-10 05:44:36 -03002334}
2335EXPORT_SYMBOL(v4l2_ctrl_auto_cluster);
2336
Hans Verkuil09965172010-08-01 14:32:42 -03002337/* Activate/deactivate a control. */
2338void v4l2_ctrl_activate(struct v4l2_ctrl *ctrl, bool active)
2339{
Hans Verkuil6e239392011-06-07 11:13:44 -03002340 /* invert since the actual flag is called 'inactive' */
2341 bool inactive = !active;
2342 bool old;
2343
Hans Verkuil09965172010-08-01 14:32:42 -03002344 if (ctrl == NULL)
2345 return;
2346
Hans Verkuil6e239392011-06-07 11:13:44 -03002347 if (inactive)
Hans Verkuil09965172010-08-01 14:32:42 -03002348 /* set V4L2_CTRL_FLAG_INACTIVE */
Hans Verkuil6e239392011-06-07 11:13:44 -03002349 old = test_and_set_bit(4, &ctrl->flags);
Hans Verkuil09965172010-08-01 14:32:42 -03002350 else
2351 /* clear V4L2_CTRL_FLAG_INACTIVE */
Hans Verkuil6e239392011-06-07 11:13:44 -03002352 old = test_and_clear_bit(4, &ctrl->flags);
2353 if (old != inactive)
2354 send_event(NULL, ctrl, V4L2_EVENT_CTRL_CH_FLAGS);
Hans Verkuil09965172010-08-01 14:32:42 -03002355}
2356EXPORT_SYMBOL(v4l2_ctrl_activate);
2357
2358/* Grab/ungrab a control.
2359 Typically used when streaming starts and you want to grab controls,
2360 preventing the user from changing them.
2361
2362 Just call this and the framework will block any attempts to change
2363 these controls. */
2364void v4l2_ctrl_grab(struct v4l2_ctrl *ctrl, bool grabbed)
2365{
Hans Verkuil6e239392011-06-07 11:13:44 -03002366 bool old;
2367
Hans Verkuil09965172010-08-01 14:32:42 -03002368 if (ctrl == NULL)
2369 return;
2370
Hans Verkuil6e239392011-06-07 11:13:44 -03002371 v4l2_ctrl_lock(ctrl);
Hans Verkuil09965172010-08-01 14:32:42 -03002372 if (grabbed)
2373 /* set V4L2_CTRL_FLAG_GRABBED */
Hans Verkuil6e239392011-06-07 11:13:44 -03002374 old = test_and_set_bit(1, &ctrl->flags);
Hans Verkuil09965172010-08-01 14:32:42 -03002375 else
2376 /* clear V4L2_CTRL_FLAG_GRABBED */
Hans Verkuil6e239392011-06-07 11:13:44 -03002377 old = test_and_clear_bit(1, &ctrl->flags);
2378 if (old != grabbed)
2379 send_event(NULL, ctrl, V4L2_EVENT_CTRL_CH_FLAGS);
2380 v4l2_ctrl_unlock(ctrl);
Hans Verkuil09965172010-08-01 14:32:42 -03002381}
2382EXPORT_SYMBOL(v4l2_ctrl_grab);
2383
2384/* Log the control name and value */
2385static void log_ctrl(const struct v4l2_ctrl *ctrl,
2386 const char *prefix, const char *colon)
2387{
Hans Verkuil09965172010-08-01 14:32:42 -03002388 if (ctrl->flags & (V4L2_CTRL_FLAG_DISABLED | V4L2_CTRL_FLAG_WRITE_ONLY))
2389 return;
2390 if (ctrl->type == V4L2_CTRL_TYPE_CTRL_CLASS)
2391 return;
2392
Hans Verkuil7eafbce2013-12-16 10:12:17 -03002393 pr_info("%s%s%s: ", prefix, colon, ctrl->name);
Hans Verkuil09965172010-08-01 14:32:42 -03002394
Hans Verkuil01760772014-04-27 03:22:17 -03002395 ctrl->type_ops->log(ctrl);
2396
Hans Verkuil88365102011-08-26 07:35:14 -03002397 if (ctrl->flags & (V4L2_CTRL_FLAG_INACTIVE |
2398 V4L2_CTRL_FLAG_GRABBED |
2399 V4L2_CTRL_FLAG_VOLATILE)) {
2400 if (ctrl->flags & V4L2_CTRL_FLAG_INACTIVE)
Hans Verkuil7eafbce2013-12-16 10:12:17 -03002401 pr_cont(" inactive");
Hans Verkuil88365102011-08-26 07:35:14 -03002402 if (ctrl->flags & V4L2_CTRL_FLAG_GRABBED)
Hans Verkuil7eafbce2013-12-16 10:12:17 -03002403 pr_cont(" grabbed");
Hans Verkuil88365102011-08-26 07:35:14 -03002404 if (ctrl->flags & V4L2_CTRL_FLAG_VOLATILE)
Hans Verkuil7eafbce2013-12-16 10:12:17 -03002405 pr_cont(" volatile");
Hans Verkuil88365102011-08-26 07:35:14 -03002406 }
Hans Verkuil7eafbce2013-12-16 10:12:17 -03002407 pr_cont("\n");
Hans Verkuil09965172010-08-01 14:32:42 -03002408}
2409
2410/* Log all controls owned by the handler */
2411void v4l2_ctrl_handler_log_status(struct v4l2_ctrl_handler *hdl,
2412 const char *prefix)
2413{
2414 struct v4l2_ctrl *ctrl;
2415 const char *colon = "";
2416 int len;
2417
2418 if (hdl == NULL)
2419 return;
2420 if (prefix == NULL)
2421 prefix = "";
2422 len = strlen(prefix);
2423 if (len && prefix[len - 1] != ' ')
2424 colon = ": ";
Sakari Ailus77e7c4e2012-01-24 21:05:34 -03002425 mutex_lock(hdl->lock);
Hans Verkuil09965172010-08-01 14:32:42 -03002426 list_for_each_entry(ctrl, &hdl->ctrls, node)
2427 if (!(ctrl->flags & V4L2_CTRL_FLAG_DISABLED))
2428 log_ctrl(ctrl, prefix, colon);
Sakari Ailus77e7c4e2012-01-24 21:05:34 -03002429 mutex_unlock(hdl->lock);
Hans Verkuil09965172010-08-01 14:32:42 -03002430}
2431EXPORT_SYMBOL(v4l2_ctrl_handler_log_status);
2432
Sylwester Nawrockiffa9b9f2013-01-22 19:01:02 -03002433int v4l2_ctrl_subdev_log_status(struct v4l2_subdev *sd)
2434{
2435 v4l2_ctrl_handler_log_status(sd->ctrl_handler, sd->name);
2436 return 0;
2437}
2438EXPORT_SYMBOL(v4l2_ctrl_subdev_log_status);
2439
Hans Verkuil09965172010-08-01 14:32:42 -03002440/* Call s_ctrl for all controls owned by the handler */
2441int v4l2_ctrl_handler_setup(struct v4l2_ctrl_handler *hdl)
2442{
2443 struct v4l2_ctrl *ctrl;
2444 int ret = 0;
2445
2446 if (hdl == NULL)
2447 return 0;
Sakari Ailus77e7c4e2012-01-24 21:05:34 -03002448 mutex_lock(hdl->lock);
Hans Verkuil09965172010-08-01 14:32:42 -03002449 list_for_each_entry(ctrl, &hdl->ctrls, node)
2450 ctrl->done = false;
2451
2452 list_for_each_entry(ctrl, &hdl->ctrls, node) {
2453 struct v4l2_ctrl *master = ctrl->cluster[0];
2454 int i;
2455
2456 /* Skip if this control was already handled by a cluster. */
Hans Verkuil71c6c4c2011-06-14 11:01:52 -03002457 /* Skip button controls and read-only controls. */
2458 if (ctrl->done || ctrl->type == V4L2_CTRL_TYPE_BUTTON ||
2459 (ctrl->flags & V4L2_CTRL_FLAG_READ_ONLY))
Hans Verkuil09965172010-08-01 14:32:42 -03002460 continue;
2461
Hans Verkuil2a863792011-01-11 14:45:03 -03002462 for (i = 0; i < master->ncontrols; i++) {
2463 if (master->cluster[i]) {
2464 cur_to_new(master->cluster[i]);
2465 master->cluster[i]->is_new = 1;
Hans Verkuil71c6c4c2011-06-14 11:01:52 -03002466 master->cluster[i]->done = true;
Hans Verkuil2a863792011-01-11 14:45:03 -03002467 }
2468 }
Hans Verkuil54c911e2011-05-25 06:04:58 -03002469 ret = call_op(master, s_ctrl);
Hans Verkuil09965172010-08-01 14:32:42 -03002470 if (ret)
2471 break;
Hans Verkuil09965172010-08-01 14:32:42 -03002472 }
Sakari Ailus77e7c4e2012-01-24 21:05:34 -03002473 mutex_unlock(hdl->lock);
Hans Verkuil09965172010-08-01 14:32:42 -03002474 return ret;
2475}
2476EXPORT_SYMBOL(v4l2_ctrl_handler_setup);
2477
Hans Verkuild9a25472014-06-12 07:54:16 -03002478/* Implement VIDIOC_QUERY_EXT_CTRL */
2479int v4l2_query_ext_ctrl(struct v4l2_ctrl_handler *hdl, struct v4l2_query_ext_ctrl *qc)
Hans Verkuil09965172010-08-01 14:32:42 -03002480{
Hans Verkuild9a25472014-06-12 07:54:16 -03002481 const unsigned next_flags = V4L2_CTRL_FLAG_NEXT_CTRL | V4L2_CTRL_FLAG_NEXT_COMPOUND;
Hans Verkuil09965172010-08-01 14:32:42 -03002482 u32 id = qc->id & V4L2_CTRL_ID_MASK;
2483 struct v4l2_ctrl_ref *ref;
2484 struct v4l2_ctrl *ctrl;
2485
2486 if (hdl == NULL)
2487 return -EINVAL;
2488
Sakari Ailus77e7c4e2012-01-24 21:05:34 -03002489 mutex_lock(hdl->lock);
Hans Verkuil09965172010-08-01 14:32:42 -03002490
2491 /* Try to find it */
2492 ref = find_ref(hdl, id);
2493
Hans Verkuild9a25472014-06-12 07:54:16 -03002494 if ((qc->id & next_flags) && !list_empty(&hdl->ctrl_refs)) {
2495 bool is_compound;
2496 /* Match any control that is not hidden */
2497 unsigned mask = 1;
2498 bool match = false;
2499
2500 if ((qc->id & next_flags) == V4L2_CTRL_FLAG_NEXT_COMPOUND) {
2501 /* Match any hidden control */
2502 match = true;
2503 } else if ((qc->id & next_flags) == next_flags) {
2504 /* Match any control, compound or not */
2505 mask = 0;
2506 }
2507
Hans Verkuil09965172010-08-01 14:32:42 -03002508 /* Find the next control with ID > qc->id */
2509
2510 /* Did we reach the end of the control list? */
2511 if (id >= node2id(hdl->ctrl_refs.prev)) {
2512 ref = NULL; /* Yes, so there is no next control */
2513 } else if (ref) {
2514 /* We found a control with the given ID, so just get
Hans Verkuild9a25472014-06-12 07:54:16 -03002515 the next valid one in the list. */
2516 list_for_each_entry_continue(ref, &hdl->ctrl_refs, node) {
Hans Verkuil35204e22015-09-21 06:14:16 -03002517 is_compound = ref->ctrl->is_array ||
Hans Verkuild9a25472014-06-12 07:54:16 -03002518 ref->ctrl->type >= V4L2_CTRL_COMPOUND_TYPES;
2519 if (id < ref->ctrl->id &&
2520 (is_compound & mask) == match)
2521 break;
2522 }
2523 if (&ref->node == &hdl->ctrl_refs)
2524 ref = NULL;
Hans Verkuil09965172010-08-01 14:32:42 -03002525 } else {
2526 /* No control with the given ID exists, so start
2527 searching for the next largest ID. We know there
2528 is one, otherwise the first 'if' above would have
2529 been true. */
Hans Verkuild9a25472014-06-12 07:54:16 -03002530 list_for_each_entry(ref, &hdl->ctrl_refs, node) {
Hans Verkuil35204e22015-09-21 06:14:16 -03002531 is_compound = ref->ctrl->is_array ||
Hans Verkuild9a25472014-06-12 07:54:16 -03002532 ref->ctrl->type >= V4L2_CTRL_COMPOUND_TYPES;
2533 if (id < ref->ctrl->id &&
2534 (is_compound & mask) == match)
Hans Verkuil09965172010-08-01 14:32:42 -03002535 break;
Hans Verkuild9a25472014-06-12 07:54:16 -03002536 }
2537 if (&ref->node == &hdl->ctrl_refs)
2538 ref = NULL;
Hans Verkuil09965172010-08-01 14:32:42 -03002539 }
2540 }
Sakari Ailus77e7c4e2012-01-24 21:05:34 -03002541 mutex_unlock(hdl->lock);
Hans Verkuild9a25472014-06-12 07:54:16 -03002542
Hans Verkuil09965172010-08-01 14:32:42 -03002543 if (!ref)
2544 return -EINVAL;
2545
2546 ctrl = ref->ctrl;
2547 memset(qc, 0, sizeof(*qc));
Hans Verkuil829fb2d2011-01-16 11:21:40 -03002548 if (id >= V4L2_CID_PRIVATE_BASE)
2549 qc->id = id;
2550 else
2551 qc->id = ctrl->id;
Hans Verkuil09965172010-08-01 14:32:42 -03002552 strlcpy(qc->name, ctrl->name, sizeof(qc->name));
Hans Verkuild9a25472014-06-12 07:54:16 -03002553 qc->flags = ctrl->flags;
2554 qc->type = ctrl->type;
2555 if (ctrl->is_ptr)
2556 qc->flags |= V4L2_CTRL_FLAG_HAS_PAYLOAD;
2557 qc->elem_size = ctrl->elem_size;
Hans Verkuil20d88ee2014-06-12 07:55:21 -03002558 qc->elems = ctrl->elems;
2559 qc->nr_of_dims = ctrl->nr_of_dims;
2560 memcpy(qc->dims, ctrl->dims, qc->nr_of_dims * sizeof(qc->dims[0]));
Hans Verkuil09965172010-08-01 14:32:42 -03002561 qc->minimum = ctrl->minimum;
2562 qc->maximum = ctrl->maximum;
2563 qc->default_value = ctrl->default_value;
Sakari Ailusce580fe2011-08-04 13:51:11 -03002564 if (ctrl->type == V4L2_CTRL_TYPE_MENU
2565 || ctrl->type == V4L2_CTRL_TYPE_INTEGER_MENU)
Hans Verkuil09965172010-08-01 14:32:42 -03002566 qc->step = 1;
2567 else
2568 qc->step = ctrl->step;
Hans Verkuild9a25472014-06-12 07:54:16 -03002569 return 0;
2570}
2571EXPORT_SYMBOL(v4l2_query_ext_ctrl);
2572
2573/* Implement VIDIOC_QUERYCTRL */
2574int v4l2_queryctrl(struct v4l2_ctrl_handler *hdl, struct v4l2_queryctrl *qc)
2575{
2576 struct v4l2_query_ext_ctrl qec = { qc->id };
2577 int rc;
2578
2579 rc = v4l2_query_ext_ctrl(hdl, &qec);
2580 if (rc)
2581 return rc;
2582
2583 qc->id = qec.id;
2584 qc->type = qec.type;
2585 qc->flags = qec.flags;
2586 strlcpy(qc->name, qec.name, sizeof(qc->name));
2587 switch (qc->type) {
2588 case V4L2_CTRL_TYPE_INTEGER:
2589 case V4L2_CTRL_TYPE_BOOLEAN:
2590 case V4L2_CTRL_TYPE_MENU:
2591 case V4L2_CTRL_TYPE_INTEGER_MENU:
2592 case V4L2_CTRL_TYPE_STRING:
2593 case V4L2_CTRL_TYPE_BITMASK:
2594 qc->minimum = qec.minimum;
2595 qc->maximum = qec.maximum;
2596 qc->step = qec.step;
2597 qc->default_value = qec.default_value;
2598 break;
2599 default:
2600 qc->minimum = 0;
2601 qc->maximum = 0;
2602 qc->step = 0;
2603 qc->default_value = 0;
2604 break;
2605 }
Hans Verkuil09965172010-08-01 14:32:42 -03002606 return 0;
2607}
2608EXPORT_SYMBOL(v4l2_queryctrl);
2609
Hans Verkuil09965172010-08-01 14:32:42 -03002610/* Implement VIDIOC_QUERYMENU */
2611int v4l2_querymenu(struct v4l2_ctrl_handler *hdl, struct v4l2_querymenu *qm)
2612{
2613 struct v4l2_ctrl *ctrl;
2614 u32 i = qm->index;
2615
2616 ctrl = v4l2_ctrl_find(hdl, qm->id);
2617 if (!ctrl)
2618 return -EINVAL;
2619
2620 qm->reserved = 0;
2621 /* Sanity checks */
Sakari Ailusce580fe2011-08-04 13:51:11 -03002622 switch (ctrl->type) {
2623 case V4L2_CTRL_TYPE_MENU:
2624 if (ctrl->qmenu == NULL)
2625 return -EINVAL;
2626 break;
2627 case V4L2_CTRL_TYPE_INTEGER_MENU:
2628 if (ctrl->qmenu_int == NULL)
2629 return -EINVAL;
2630 break;
2631 default:
Hans Verkuil09965172010-08-01 14:32:42 -03002632 return -EINVAL;
Sakari Ailusce580fe2011-08-04 13:51:11 -03002633 }
2634
2635 if (i < ctrl->minimum || i > ctrl->maximum)
2636 return -EINVAL;
2637
Hans Verkuil09965172010-08-01 14:32:42 -03002638 /* Use mask to see if this menu item should be skipped */
2639 if (ctrl->menu_skip_mask & (1 << i))
2640 return -EINVAL;
2641 /* Empty menu items should also be skipped */
Sakari Ailusce580fe2011-08-04 13:51:11 -03002642 if (ctrl->type == V4L2_CTRL_TYPE_MENU) {
2643 if (ctrl->qmenu[i] == NULL || ctrl->qmenu[i][0] == '\0')
2644 return -EINVAL;
2645 strlcpy(qm->name, ctrl->qmenu[i], sizeof(qm->name));
2646 } else {
2647 qm->value = ctrl->qmenu_int[i];
2648 }
Hans Verkuil09965172010-08-01 14:32:42 -03002649 return 0;
2650}
2651EXPORT_SYMBOL(v4l2_querymenu);
2652
Hans Verkuil09965172010-08-01 14:32:42 -03002653
2654/* Some general notes on the atomic requirements of VIDIOC_G/TRY/S_EXT_CTRLS:
2655
2656 It is not a fully atomic operation, just best-effort only. After all, if
2657 multiple controls have to be set through multiple i2c writes (for example)
2658 then some initial writes may succeed while others fail. Thus leaving the
2659 system in an inconsistent state. The question is how much effort you are
2660 willing to spend on trying to make something atomic that really isn't.
2661
2662 From the point of view of an application the main requirement is that
2663 when you call VIDIOC_S_EXT_CTRLS and some values are invalid then an
2664 error should be returned without actually affecting any controls.
2665
2666 If all the values are correct, then it is acceptable to just give up
2667 in case of low-level errors.
2668
2669 It is important though that the application can tell when only a partial
2670 configuration was done. The way we do that is through the error_idx field
2671 of struct v4l2_ext_controls: if that is equal to the count field then no
2672 controls were affected. Otherwise all controls before that index were
2673 successful in performing their 'get' or 'set' operation, the control at
2674 the given index failed, and you don't know what happened with the controls
2675 after the failed one. Since if they were part of a control cluster they
2676 could have been successfully processed (if a cluster member was encountered
2677 at index < error_idx), they could have failed (if a cluster member was at
2678 error_idx), or they may not have been processed yet (if the first cluster
2679 member appeared after error_idx).
2680
2681 It is all fairly theoretical, though. In practice all you can do is to
2682 bail out. If error_idx == count, then it is an application bug. If
2683 error_idx < count then it is only an application bug if the error code was
2684 EBUSY. That usually means that something started streaming just when you
2685 tried to set the controls. In all other cases it is a driver/hardware
2686 problem and all you can do is to retry or bail out.
2687
2688 Note that these rules do not apply to VIDIOC_TRY_EXT_CTRLS: since that
2689 never modifies controls the error_idx is just set to whatever control
2690 has an invalid value.
2691 */
2692
2693/* Prepare for the extended g/s/try functions.
2694 Find the controls in the control array and do some basic checks. */
2695static int prepare_ext_ctrls(struct v4l2_ctrl_handler *hdl,
2696 struct v4l2_ext_controls *cs,
Hans Verkuild9a25472014-06-12 07:54:16 -03002697 struct v4l2_ctrl_helper *helpers,
2698 bool get)
Hans Verkuil09965172010-08-01 14:32:42 -03002699{
Hans Verkuileb5b16e2011-06-14 10:04:06 -03002700 struct v4l2_ctrl_helper *h;
2701 bool have_clusters = false;
Hans Verkuil09965172010-08-01 14:32:42 -03002702 u32 i;
2703
Hans Verkuileb5b16e2011-06-14 10:04:06 -03002704 for (i = 0, h = helpers; i < cs->count; i++, h++) {
Hans Verkuil09965172010-08-01 14:32:42 -03002705 struct v4l2_ext_control *c = &cs->controls[i];
Hans Verkuileb5b16e2011-06-14 10:04:06 -03002706 struct v4l2_ctrl_ref *ref;
Hans Verkuil09965172010-08-01 14:32:42 -03002707 struct v4l2_ctrl *ctrl;
2708 u32 id = c->id & V4L2_CTRL_ID_MASK;
2709
Hans Verkuil37cd3b72011-06-07 04:40:04 -03002710 cs->error_idx = i;
Hans Verkuil09965172010-08-01 14:32:42 -03002711
Ricardo Ribalda953eae52015-10-29 08:10:29 -02002712 if (cs->which &&
2713 cs->which != V4L2_CTRL_WHICH_DEF_VAL &&
2714 V4L2_CTRL_ID2WHICH(id) != cs->which)
Hans Verkuil09965172010-08-01 14:32:42 -03002715 return -EINVAL;
2716
2717 /* Old-style private controls are not allowed for
2718 extended controls */
2719 if (id >= V4L2_CID_PRIVATE_BASE)
2720 return -EINVAL;
Hans Verkuileb5b16e2011-06-14 10:04:06 -03002721 ref = find_ref_lock(hdl, id);
2722 if (ref == NULL)
Hans Verkuil09965172010-08-01 14:32:42 -03002723 return -EINVAL;
Hans Verkuileb5b16e2011-06-14 10:04:06 -03002724 ctrl = ref->ctrl;
Hans Verkuil09965172010-08-01 14:32:42 -03002725 if (ctrl->flags & V4L2_CTRL_FLAG_DISABLED)
2726 return -EINVAL;
2727
Hans Verkuileb5b16e2011-06-14 10:04:06 -03002728 if (ctrl->cluster[0]->ncontrols > 1)
2729 have_clusters = true;
2730 if (ctrl->cluster[0] != ctrl)
2731 ref = find_ref_lock(hdl, ctrl->cluster[0]->id);
Hans Verkuil302ab7c2014-06-10 07:06:50 -03002732 if (ctrl->is_ptr && !ctrl->is_string) {
2733 unsigned tot_size = ctrl->elems * ctrl->elem_size;
2734
2735 if (c->size < tot_size) {
2736 if (get) {
2737 c->size = tot_size;
2738 return -ENOSPC;
2739 }
2740 return -EFAULT;
Hans Verkuild9a25472014-06-12 07:54:16 -03002741 }
Hans Verkuil302ab7c2014-06-10 07:06:50 -03002742 c->size = tot_size;
Hans Verkuild9a25472014-06-12 07:54:16 -03002743 }
Hans Verkuileb5b16e2011-06-14 10:04:06 -03002744 /* Store the ref to the master control of the cluster */
2745 h->mref = ref;
2746 h->ctrl = ctrl;
2747 /* Initially set next to 0, meaning that there is no other
2748 control in this helper array belonging to the same
2749 cluster */
2750 h->next = 0;
Hans Verkuil09965172010-08-01 14:32:42 -03002751 }
Hans Verkuileb5b16e2011-06-14 10:04:06 -03002752
2753 /* We are done if there were no controls that belong to a multi-
2754 control cluster. */
2755 if (!have_clusters)
2756 return 0;
2757
2758 /* The code below figures out in O(n) time which controls in the list
2759 belong to the same cluster. */
2760
2761 /* This has to be done with the handler lock taken. */
Sakari Ailus77e7c4e2012-01-24 21:05:34 -03002762 mutex_lock(hdl->lock);
Hans Verkuileb5b16e2011-06-14 10:04:06 -03002763
2764 /* First zero the helper field in the master control references */
2765 for (i = 0; i < cs->count; i++)
Sachin Kamatc0822662012-07-10 07:14:46 -03002766 helpers[i].mref->helper = NULL;
Hans Verkuileb5b16e2011-06-14 10:04:06 -03002767 for (i = 0, h = helpers; i < cs->count; i++, h++) {
2768 struct v4l2_ctrl_ref *mref = h->mref;
2769
2770 /* If the mref->helper is set, then it points to an earlier
2771 helper that belongs to the same cluster. */
2772 if (mref->helper) {
2773 /* Set the next field of mref->helper to the current
2774 index: this means that that earlier helper now
2775 points to the next helper in the same cluster. */
2776 mref->helper->next = i;
2777 /* mref should be set only for the first helper in the
2778 cluster, clear the others. */
2779 h->mref = NULL;
2780 }
2781 /* Point the mref helper to the current helper struct. */
2782 mref->helper = h;
2783 }
Sakari Ailus77e7c4e2012-01-24 21:05:34 -03002784 mutex_unlock(hdl->lock);
Hans Verkuil09965172010-08-01 14:32:42 -03002785 return 0;
2786}
2787
Hans Verkuil09965172010-08-01 14:32:42 -03002788/* Handles the corner case where cs->count == 0. It checks whether the
2789 specified control class exists. If that class ID is 0, then it checks
2790 whether there are any controls at all. */
Ricardo Ribalda0f8017b2015-10-29 08:10:28 -02002791static int class_check(struct v4l2_ctrl_handler *hdl, u32 which)
Hans Verkuil09965172010-08-01 14:32:42 -03002792{
Ricardo Ribalda953eae52015-10-29 08:10:29 -02002793 if (which == 0 || which == V4L2_CTRL_WHICH_DEF_VAL)
Hans Verkuil09965172010-08-01 14:32:42 -03002794 return list_empty(&hdl->ctrl_refs) ? -EINVAL : 0;
Ricardo Ribalda0f8017b2015-10-29 08:10:28 -02002795 return find_ref_lock(hdl, which | 1) ? 0 : -EINVAL;
Hans Verkuil09965172010-08-01 14:32:42 -03002796}
2797
2798
2799
2800/* Get extended controls. Allocates the helpers array if needed. */
2801int v4l2_g_ext_ctrls(struct v4l2_ctrl_handler *hdl, struct v4l2_ext_controls *cs)
2802{
Hans Verkuileb5b16e2011-06-14 10:04:06 -03002803 struct v4l2_ctrl_helper helper[4];
2804 struct v4l2_ctrl_helper *helpers = helper;
Hans Verkuil09965172010-08-01 14:32:42 -03002805 int ret;
Hans Verkuilddac5c12011-06-10 05:43:34 -03002806 int i, j;
Ricardo Ribalda953eae52015-10-29 08:10:29 -02002807 bool def_value;
2808
2809 def_value = (cs->which == V4L2_CTRL_WHICH_DEF_VAL);
Hans Verkuil09965172010-08-01 14:32:42 -03002810
2811 cs->error_idx = cs->count;
Ricardo Ribalda0f8017b2015-10-29 08:10:28 -02002812 cs->which = V4L2_CTRL_ID2WHICH(cs->which);
Hans Verkuil09965172010-08-01 14:32:42 -03002813
2814 if (hdl == NULL)
2815 return -EINVAL;
2816
2817 if (cs->count == 0)
Ricardo Ribalda0f8017b2015-10-29 08:10:28 -02002818 return class_check(hdl, cs->which);
Hans Verkuil09965172010-08-01 14:32:42 -03002819
2820 if (cs->count > ARRAY_SIZE(helper)) {
Xi Wang5f0049b2012-04-06 09:32:36 -03002821 helpers = kmalloc_array(cs->count, sizeof(helper[0]),
2822 GFP_KERNEL);
Hans Verkuil09965172010-08-01 14:32:42 -03002823 if (helpers == NULL)
2824 return -ENOMEM;
2825 }
2826
Hans Verkuild9a25472014-06-12 07:54:16 -03002827 ret = prepare_ext_ctrls(hdl, cs, helpers, true);
Hans Verkuil37cd3b72011-06-07 04:40:04 -03002828 cs->error_idx = cs->count;
Hans Verkuil09965172010-08-01 14:32:42 -03002829
2830 for (i = 0; !ret && i < cs->count; i++)
2831 if (helpers[i].ctrl->flags & V4L2_CTRL_FLAG_WRITE_ONLY)
2832 ret = -EACCES;
2833
2834 for (i = 0; !ret && i < cs->count; i++) {
Hans Verkuileb5b16e2011-06-14 10:04:06 -03002835 int (*ctrl_to_user)(struct v4l2_ext_control *c,
Ricardo Ribalda953eae52015-10-29 08:10:29 -02002836 struct v4l2_ctrl *ctrl);
Hans Verkuileb5b16e2011-06-14 10:04:06 -03002837 struct v4l2_ctrl *master;
Hans Verkuil09965172010-08-01 14:32:42 -03002838
Ricardo Ribalda953eae52015-10-29 08:10:29 -02002839 ctrl_to_user = def_value ? def_to_user : cur_to_user;
2840
Hans Verkuileb5b16e2011-06-14 10:04:06 -03002841 if (helpers[i].mref == NULL)
Hans Verkuil09965172010-08-01 14:32:42 -03002842 continue;
2843
Hans Verkuileb5b16e2011-06-14 10:04:06 -03002844 master = helpers[i].mref->ctrl;
Hans Verkuil09965172010-08-01 14:32:42 -03002845 cs->error_idx = i;
2846
2847 v4l2_ctrl_lock(master);
Hans Verkuilddac5c12011-06-10 05:43:34 -03002848
2849 /* g_volatile_ctrl will update the new control values */
Ricardo Ribalda953eae52015-10-29 08:10:29 -02002850 if (!def_value &&
2851 ((master->flags & V4L2_CTRL_FLAG_VOLATILE) ||
2852 (master->has_volatiles && !is_cur_manual(master)))) {
Hans Verkuilddac5c12011-06-10 05:43:34 -03002853 for (j = 0; j < master->ncontrols; j++)
2854 cur_to_new(master->cluster[j]);
Hans Verkuil54c911e2011-05-25 06:04:58 -03002855 ret = call_op(master, g_volatile_ctrl);
Hans Verkuileb5b16e2011-06-14 10:04:06 -03002856 ctrl_to_user = new_to_user;
Hans Verkuilddac5c12011-06-10 05:43:34 -03002857 }
2858 /* If OK, then copy the current (for non-volatile controls)
2859 or the new (for volatile controls) control values to the
2860 caller */
Hans Verkuileb5b16e2011-06-14 10:04:06 -03002861 if (!ret) {
2862 u32 idx = i;
2863
2864 do {
2865 ret = ctrl_to_user(cs->controls + idx,
2866 helpers[idx].ctrl);
2867 idx = helpers[idx].next;
2868 } while (!ret && idx);
2869 }
Hans Verkuil09965172010-08-01 14:32:42 -03002870 v4l2_ctrl_unlock(master);
Hans Verkuil09965172010-08-01 14:32:42 -03002871 }
2872
2873 if (cs->count > ARRAY_SIZE(helper))
2874 kfree(helpers);
2875 return ret;
2876}
2877EXPORT_SYMBOL(v4l2_g_ext_ctrls);
2878
Hans Verkuil09965172010-08-01 14:32:42 -03002879/* Helper function to get a single control */
Laurent Pinchart03d52852012-07-23 09:15:21 -03002880static int get_ctrl(struct v4l2_ctrl *ctrl, struct v4l2_ext_control *c)
Hans Verkuil09965172010-08-01 14:32:42 -03002881{
2882 struct v4l2_ctrl *master = ctrl->cluster[0];
2883 int ret = 0;
Hans Verkuilddac5c12011-06-10 05:43:34 -03002884 int i;
Hans Verkuil09965172010-08-01 14:32:42 -03002885
Hans Verkuild9a25472014-06-12 07:54:16 -03002886 /* Compound controls are not supported. The new_to_user() and
Laurent Pinchart03d52852012-07-23 09:15:21 -03002887 * cur_to_user() calls below would need to be modified not to access
2888 * userspace memory when called from get_ctrl().
2889 */
Benoit Parrota8077732015-09-21 13:03:21 -03002890 if (!ctrl->is_int && ctrl->type != V4L2_CTRL_TYPE_INTEGER64)
Laurent Pinchart03d52852012-07-23 09:15:21 -03002891 return -EINVAL;
2892
Hans Verkuil09965172010-08-01 14:32:42 -03002893 if (ctrl->flags & V4L2_CTRL_FLAG_WRITE_ONLY)
2894 return -EACCES;
2895
2896 v4l2_ctrl_lock(master);
2897 /* g_volatile_ctrl will update the current control values */
Hans Verkuil5626b8c2011-08-26 07:53:53 -03002898 if (ctrl->flags & V4L2_CTRL_FLAG_VOLATILE) {
Hans Verkuilddac5c12011-06-10 05:43:34 -03002899 for (i = 0; i < master->ncontrols; i++)
2900 cur_to_new(master->cluster[i]);
Hans Verkuil54c911e2011-05-25 06:04:58 -03002901 ret = call_op(master, g_volatile_ctrl);
Laurent Pinchart03d52852012-07-23 09:15:21 -03002902 new_to_user(c, ctrl);
Hans Verkuilddac5c12011-06-10 05:43:34 -03002903 } else {
Laurent Pinchart03d52852012-07-23 09:15:21 -03002904 cur_to_user(c, ctrl);
Hans Verkuilddac5c12011-06-10 05:43:34 -03002905 }
Hans Verkuil09965172010-08-01 14:32:42 -03002906 v4l2_ctrl_unlock(master);
2907 return ret;
2908}
2909
2910int v4l2_g_ctrl(struct v4l2_ctrl_handler *hdl, struct v4l2_control *control)
2911{
2912 struct v4l2_ctrl *ctrl = v4l2_ctrl_find(hdl, control->id);
Laurent Pinchart03d52852012-07-23 09:15:21 -03002913 struct v4l2_ext_control c;
2914 int ret;
Hans Verkuil09965172010-08-01 14:32:42 -03002915
Hans Verkuild9a25472014-06-12 07:54:16 -03002916 if (ctrl == NULL || !ctrl->is_int)
Hans Verkuil09965172010-08-01 14:32:42 -03002917 return -EINVAL;
Laurent Pinchart03d52852012-07-23 09:15:21 -03002918 ret = get_ctrl(ctrl, &c);
2919 control->value = c.value;
2920 return ret;
Hans Verkuil09965172010-08-01 14:32:42 -03002921}
2922EXPORT_SYMBOL(v4l2_g_ctrl);
2923
Hans Verkuil09965172010-08-01 14:32:42 -03002924s32 v4l2_ctrl_g_ctrl(struct v4l2_ctrl *ctrl)
2925{
Laurent Pinchart03d52852012-07-23 09:15:21 -03002926 struct v4l2_ext_control c;
Hans Verkuil09965172010-08-01 14:32:42 -03002927
2928 /* It's a driver bug if this happens. */
Hans Verkuild9a25472014-06-12 07:54:16 -03002929 WARN_ON(!ctrl->is_int);
Laurent Pinchart03d52852012-07-23 09:15:21 -03002930 c.value = 0;
2931 get_ctrl(ctrl, &c);
2932 return c.value;
Hans Verkuil09965172010-08-01 14:32:42 -03002933}
2934EXPORT_SYMBOL(v4l2_ctrl_g_ctrl);
2935
Laurent Pinchart03d52852012-07-23 09:15:21 -03002936s64 v4l2_ctrl_g_ctrl_int64(struct v4l2_ctrl *ctrl)
2937{
2938 struct v4l2_ext_control c;
2939
2940 /* It's a driver bug if this happens. */
Hans Verkuil998e7652014-06-10 07:55:00 -03002941 WARN_ON(ctrl->is_ptr || ctrl->type != V4L2_CTRL_TYPE_INTEGER64);
Benoit Parrota8077732015-09-21 13:03:21 -03002942 c.value64 = 0;
Laurent Pinchart03d52852012-07-23 09:15:21 -03002943 get_ctrl(ctrl, &c);
Benoit Parrota8077732015-09-21 13:03:21 -03002944 return c.value64;
Laurent Pinchart03d52852012-07-23 09:15:21 -03002945}
2946EXPORT_SYMBOL(v4l2_ctrl_g_ctrl_int64);
2947
Hans Verkuil09965172010-08-01 14:32:42 -03002948
2949/* Core function that calls try/s_ctrl and ensures that the new value is
2950 copied to the current value on a set.
2951 Must be called with ctrl->handler->lock held. */
Sylwester Nawrocki2ccbe772013-01-19 15:51:55 -03002952static int try_or_set_cluster(struct v4l2_fh *fh, struct v4l2_ctrl *master,
2953 bool set, u32 ch_flags)
Hans Verkuil09965172010-08-01 14:32:42 -03002954{
Hans Verkuil72d877c2011-06-10 05:44:36 -03002955 bool update_flag;
Hans Verkuileb5b16e2011-06-14 10:04:06 -03002956 int ret;
Hans Verkuil09965172010-08-01 14:32:42 -03002957 int i;
2958
2959 /* Go through the cluster and either validate the new value or
2960 (if no new value was set), copy the current value to the new
2961 value, ensuring a consistent view for the control ops when
2962 called. */
Hans Verkuileb5b16e2011-06-14 10:04:06 -03002963 for (i = 0; i < master->ncontrols; i++) {
Hans Verkuil09965172010-08-01 14:32:42 -03002964 struct v4l2_ctrl *ctrl = master->cluster[i];
2965
2966 if (ctrl == NULL)
2967 continue;
2968
Hans Verkuileb5b16e2011-06-14 10:04:06 -03002969 if (!ctrl->is_new) {
2970 cur_to_new(ctrl);
Hans Verkuil09965172010-08-01 14:32:42 -03002971 continue;
2972 }
Hans Verkuileb5b16e2011-06-14 10:04:06 -03002973 /* Check again: it may have changed since the
2974 previous check in try_or_set_ext_ctrls(). */
2975 if (set && (ctrl->flags & V4L2_CTRL_FLAG_GRABBED))
2976 return -EBUSY;
Hans Verkuil09965172010-08-01 14:32:42 -03002977 }
2978
Hans Verkuileb5b16e2011-06-14 10:04:06 -03002979 ret = call_op(master, try_ctrl);
Hans Verkuil09965172010-08-01 14:32:42 -03002980
2981 /* Don't set if there is no change */
Hans Verkuil72d877c2011-06-10 05:44:36 -03002982 if (ret || !set || !cluster_changed(master))
2983 return ret;
2984 ret = call_op(master, s_ctrl);
Hans Verkuil72d877c2011-06-10 05:44:36 -03002985 if (ret)
2986 return ret;
2987
Hans Verkuileb5b16e2011-06-14 10:04:06 -03002988 /* If OK, then make the new values permanent. */
Hans Verkuil72d877c2011-06-10 05:44:36 -03002989 update_flag = is_cur_manual(master) != is_new_manual(master);
2990 for (i = 0; i < master->ncontrols; i++)
Sylwester Nawrocki2ccbe772013-01-19 15:51:55 -03002991 new_to_cur(fh, master->cluster[i], ch_flags |
2992 ((update_flag && i > 0) ? V4L2_EVENT_CTRL_CH_FLAGS : 0));
Hans Verkuil72d877c2011-06-10 05:44:36 -03002993 return 0;
Hans Verkuil09965172010-08-01 14:32:42 -03002994}
2995
Hans Verkuile6402582011-06-14 10:56:42 -03002996/* Validate controls. */
2997static int validate_ctrls(struct v4l2_ext_controls *cs,
2998 struct v4l2_ctrl_helper *helpers, bool set)
Hans Verkuil09965172010-08-01 14:32:42 -03002999{
Hans Verkuile6402582011-06-14 10:56:42 -03003000 unsigned i;
Hans Verkuil09965172010-08-01 14:32:42 -03003001 int ret = 0;
3002
Hans Verkuileb5b16e2011-06-14 10:04:06 -03003003 cs->error_idx = cs->count;
Hans Verkuil09965172010-08-01 14:32:42 -03003004 for (i = 0; i < cs->count; i++) {
3005 struct v4l2_ctrl *ctrl = helpers[i].ctrl;
Hans Verkuil7a7f1ab2014-09-22 11:08:55 -03003006 union v4l2_ctrl_ptr p_new;
Hans Verkuil09965172010-08-01 14:32:42 -03003007
Hans Verkuile6402582011-06-14 10:56:42 -03003008 cs->error_idx = i;
Hans Verkuil09965172010-08-01 14:32:42 -03003009
3010 if (ctrl->flags & V4L2_CTRL_FLAG_READ_ONLY)
3011 return -EACCES;
3012 /* This test is also done in try_set_control_cluster() which
3013 is called in atomic context, so that has the final say,
3014 but it makes sense to do an up-front check as well. Once
3015 an error occurs in try_set_control_cluster() some other
3016 controls may have been set already and we want to do a
3017 best-effort to avoid that. */
3018 if (set && (ctrl->flags & V4L2_CTRL_FLAG_GRABBED))
3019 return -EBUSY;
Hans Verkuil7a7f1ab2014-09-22 11:08:55 -03003020 /*
3021 * Skip validation for now if the payload needs to be copied
3022 * from userspace into kernelspace. We'll validate those later.
3023 */
3024 if (ctrl->is_ptr)
3025 continue;
3026 if (ctrl->type == V4L2_CTRL_TYPE_INTEGER64)
3027 p_new.p_s64 = &cs->controls[i].value64;
3028 else
3029 p_new.p_s32 = &cs->controls[i].value;
3030 ret = validate_new(ctrl, p_new);
Hans Verkuileb5b16e2011-06-14 10:04:06 -03003031 if (ret)
3032 return ret;
Hans Verkuil09965172010-08-01 14:32:42 -03003033 }
Hans Verkuile6402582011-06-14 10:56:42 -03003034 return 0;
3035}
Hans Verkuil09965172010-08-01 14:32:42 -03003036
Hans Verkuil5626b8c2011-08-26 07:53:53 -03003037/* Obtain the current volatile values of an autocluster and mark them
3038 as new. */
3039static void update_from_auto_cluster(struct v4l2_ctrl *master)
3040{
3041 int i;
3042
Antonio Ospite759b26a2015-10-14 10:57:32 -03003043 for (i = 1; i < master->ncontrols; i++)
Hans Verkuil5626b8c2011-08-26 07:53:53 -03003044 cur_to_new(master->cluster[i]);
3045 if (!call_op(master, g_volatile_ctrl))
3046 for (i = 1; i < master->ncontrols; i++)
3047 if (master->cluster[i])
3048 master->cluster[i]->is_new = 1;
3049}
3050
Hans Verkuile6402582011-06-14 10:56:42 -03003051/* Try or try-and-set controls */
3052static int try_set_ext_ctrls(struct v4l2_fh *fh, struct v4l2_ctrl_handler *hdl,
3053 struct v4l2_ext_controls *cs,
3054 bool set)
3055{
3056 struct v4l2_ctrl_helper helper[4];
3057 struct v4l2_ctrl_helper *helpers = helper;
3058 unsigned i, j;
3059 int ret;
3060
3061 cs->error_idx = cs->count;
Ricardo Ribalda953eae52015-10-29 08:10:29 -02003062
3063 /* Default value cannot be changed */
3064 if (cs->which == V4L2_CTRL_WHICH_DEF_VAL)
3065 return -EINVAL;
3066
Ricardo Ribalda0f8017b2015-10-29 08:10:28 -02003067 cs->which = V4L2_CTRL_ID2WHICH(cs->which);
Hans Verkuile6402582011-06-14 10:56:42 -03003068
3069 if (hdl == NULL)
3070 return -EINVAL;
3071
3072 if (cs->count == 0)
Ricardo Ribalda0f8017b2015-10-29 08:10:28 -02003073 return class_check(hdl, cs->which);
Hans Verkuile6402582011-06-14 10:56:42 -03003074
3075 if (cs->count > ARRAY_SIZE(helper)) {
Xi Wang0a3475e2012-04-06 09:32:37 -03003076 helpers = kmalloc_array(cs->count, sizeof(helper[0]),
3077 GFP_KERNEL);
Hans Verkuile6402582011-06-14 10:56:42 -03003078 if (!helpers)
3079 return -ENOMEM;
3080 }
Hans Verkuild9a25472014-06-12 07:54:16 -03003081 ret = prepare_ext_ctrls(hdl, cs, helpers, false);
Hans Verkuile6402582011-06-14 10:56:42 -03003082 if (!ret)
3083 ret = validate_ctrls(cs, helpers, set);
3084 if (ret && set)
3085 cs->error_idx = cs->count;
Hans Verkuil09965172010-08-01 14:32:42 -03003086 for (i = 0; !ret && i < cs->count; i++) {
Hans Verkuileb5b16e2011-06-14 10:04:06 -03003087 struct v4l2_ctrl *master;
3088 u32 idx = i;
Hans Verkuil09965172010-08-01 14:32:42 -03003089
Hans Verkuileb5b16e2011-06-14 10:04:06 -03003090 if (helpers[i].mref == NULL)
Hans Verkuil09965172010-08-01 14:32:42 -03003091 continue;
3092
Hans Verkuil37cd3b72011-06-07 04:40:04 -03003093 cs->error_idx = i;
Hans Verkuileb5b16e2011-06-14 10:04:06 -03003094 master = helpers[i].mref->ctrl;
3095 v4l2_ctrl_lock(master);
Hans Verkuil09965172010-08-01 14:32:42 -03003096
Hans Verkuil2a863792011-01-11 14:45:03 -03003097 /* Reset the 'is_new' flags of the cluster */
Hans Verkuil09965172010-08-01 14:32:42 -03003098 for (j = 0; j < master->ncontrols; j++)
3099 if (master->cluster[j])
Hans Verkuil2a863792011-01-11 14:45:03 -03003100 master->cluster[j]->is_new = 0;
Hans Verkuil09965172010-08-01 14:32:42 -03003101
Hans Verkuil5626b8c2011-08-26 07:53:53 -03003102 /* For volatile autoclusters that are currently in auto mode
3103 we need to discover if it will be set to manual mode.
3104 If so, then we have to copy the current volatile values
3105 first since those will become the new manual values (which
3106 may be overwritten by explicit new values from this set
3107 of controls). */
3108 if (master->is_auto && master->has_volatiles &&
3109 !is_cur_manual(master)) {
3110 /* Pick an initial non-manual value */
3111 s32 new_auto_val = master->manual_mode_value + 1;
3112 u32 tmp_idx = idx;
3113
3114 do {
3115 /* Check if the auto control is part of the
3116 list, and remember the new value. */
3117 if (helpers[tmp_idx].ctrl == master)
3118 new_auto_val = cs->controls[tmp_idx].value;
3119 tmp_idx = helpers[tmp_idx].next;
3120 } while (tmp_idx);
3121 /* If the new value == the manual value, then copy
3122 the current volatile values. */
3123 if (new_auto_val == master->manual_mode_value)
3124 update_from_auto_cluster(master);
3125 }
3126
Hans Verkuil09965172010-08-01 14:32:42 -03003127 /* Copy the new caller-supplied control values.
Hans Verkuil2a863792011-01-11 14:45:03 -03003128 user_to_new() sets 'is_new' to 1. */
Hans Verkuileb5b16e2011-06-14 10:04:06 -03003129 do {
Hans Verkuil7a7f1ab2014-09-22 11:08:55 -03003130 struct v4l2_ctrl *ctrl = helpers[idx].ctrl;
3131
3132 ret = user_to_new(cs->controls + idx, ctrl);
3133 if (!ret && ctrl->is_ptr)
3134 ret = validate_new(ctrl, ctrl->p_new);
Hans Verkuileb5b16e2011-06-14 10:04:06 -03003135 idx = helpers[idx].next;
3136 } while (!ret && idx);
Hans Verkuil09965172010-08-01 14:32:42 -03003137
3138 if (!ret)
Sylwester Nawrocki2ccbe772013-01-19 15:51:55 -03003139 ret = try_or_set_cluster(fh, master, set, 0);
Hans Verkuil09965172010-08-01 14:32:42 -03003140
3141 /* Copy the new values back to userspace. */
Hans Verkuileb5b16e2011-06-14 10:04:06 -03003142 if (!ret) {
3143 idx = i;
3144 do {
Hans Verkuiladf41b92011-07-05 06:56:37 -03003145 ret = new_to_user(cs->controls + idx,
Hans Verkuile6402582011-06-14 10:56:42 -03003146 helpers[idx].ctrl);
Hans Verkuileb5b16e2011-06-14 10:04:06 -03003147 idx = helpers[idx].next;
3148 } while (!ret && idx);
3149 }
3150 v4l2_ctrl_unlock(master);
Hans Verkuil09965172010-08-01 14:32:42 -03003151 }
Hans Verkuil09965172010-08-01 14:32:42 -03003152
Hans Verkuil09965172010-08-01 14:32:42 -03003153 if (cs->count > ARRAY_SIZE(helper))
3154 kfree(helpers);
3155 return ret;
3156}
3157
3158int v4l2_try_ext_ctrls(struct v4l2_ctrl_handler *hdl, struct v4l2_ext_controls *cs)
3159{
Hans Verkuilab892ba2011-06-07 06:47:18 -03003160 return try_set_ext_ctrls(NULL, hdl, cs, false);
Hans Verkuil09965172010-08-01 14:32:42 -03003161}
3162EXPORT_SYMBOL(v4l2_try_ext_ctrls);
3163
Hans Verkuilab892ba2011-06-07 06:47:18 -03003164int v4l2_s_ext_ctrls(struct v4l2_fh *fh, struct v4l2_ctrl_handler *hdl,
3165 struct v4l2_ext_controls *cs)
Hans Verkuil09965172010-08-01 14:32:42 -03003166{
Hans Verkuilab892ba2011-06-07 06:47:18 -03003167 return try_set_ext_ctrls(fh, hdl, cs, true);
Hans Verkuil09965172010-08-01 14:32:42 -03003168}
3169EXPORT_SYMBOL(v4l2_s_ext_ctrls);
3170
Hans Verkuil09965172010-08-01 14:32:42 -03003171/* Helper function for VIDIOC_S_CTRL compatibility */
Hans Verkuil7a7f1ab2014-09-22 11:08:55 -03003172static int set_ctrl(struct v4l2_fh *fh, struct v4l2_ctrl *ctrl, u32 ch_flags)
Hans Verkuil09965172010-08-01 14:32:42 -03003173{
3174 struct v4l2_ctrl *master = ctrl->cluster[0];
Hans Verkuil7a7f1ab2014-09-22 11:08:55 -03003175 int ret;
Hans Verkuil09965172010-08-01 14:32:42 -03003176 int i;
3177
Hans Verkuil2a863792011-01-11 14:45:03 -03003178 /* Reset the 'is_new' flags of the cluster */
Hans Verkuil09965172010-08-01 14:32:42 -03003179 for (i = 0; i < master->ncontrols; i++)
3180 if (master->cluster[i])
Hans Verkuil2a863792011-01-11 14:45:03 -03003181 master->cluster[i]->is_new = 0;
Hans Verkuil09965172010-08-01 14:32:42 -03003182
Hans Verkuil7a7f1ab2014-09-22 11:08:55 -03003183 ret = validate_new(ctrl, ctrl->p_new);
3184 if (ret)
3185 return ret;
Hans Verkuil5d0360a2014-07-21 10:45:42 -03003186
Hans Verkuil5626b8c2011-08-26 07:53:53 -03003187 /* For autoclusters with volatiles that are switched from auto to
3188 manual mode we have to update the current volatile values since
3189 those will become the initial manual values after such a switch. */
3190 if (master->is_auto && master->has_volatiles && ctrl == master &&
Hans Verkuil5d0360a2014-07-21 10:45:42 -03003191 !is_cur_manual(master) && ctrl->val == master->manual_mode_value)
Hans Verkuil5626b8c2011-08-26 07:53:53 -03003192 update_from_auto_cluster(master);
Laurent Pinchart03d52852012-07-23 09:15:21 -03003193
Hans Verkuil5d0360a2014-07-21 10:45:42 -03003194 ctrl->is_new = 1;
Sylwester Nawrocki2ccbe772013-01-19 15:51:55 -03003195 return try_or_set_cluster(fh, master, true, ch_flags);
3196}
Laurent Pinchart03d52852012-07-23 09:15:21 -03003197
Sylwester Nawrocki2ccbe772013-01-19 15:51:55 -03003198/* Helper function for VIDIOC_S_CTRL compatibility */
3199static int set_ctrl_lock(struct v4l2_fh *fh, struct v4l2_ctrl *ctrl,
3200 struct v4l2_ext_control *c)
3201{
Hans Verkuil7a7f1ab2014-09-22 11:08:55 -03003202 int ret;
Sylwester Nawrocki2ccbe772013-01-19 15:51:55 -03003203
Hans Verkuil7a7f1ab2014-09-22 11:08:55 -03003204 v4l2_ctrl_lock(ctrl);
3205 user_to_new(c, ctrl);
3206 ret = set_ctrl(fh, ctrl, 0);
3207 if (!ret)
3208 cur_to_user(c, ctrl);
3209 v4l2_ctrl_unlock(ctrl);
Hans Verkuil09965172010-08-01 14:32:42 -03003210 return ret;
3211}
3212
Hans Verkuilab892ba2011-06-07 06:47:18 -03003213int v4l2_s_ctrl(struct v4l2_fh *fh, struct v4l2_ctrl_handler *hdl,
3214 struct v4l2_control *control)
Hans Verkuil09965172010-08-01 14:32:42 -03003215{
3216 struct v4l2_ctrl *ctrl = v4l2_ctrl_find(hdl, control->id);
Hans Verkuil7a7f1ab2014-09-22 11:08:55 -03003217 struct v4l2_ext_control c = { control->id };
Laurent Pinchart03d52852012-07-23 09:15:21 -03003218 int ret;
Hans Verkuil09965172010-08-01 14:32:42 -03003219
Hans Verkuild9a25472014-06-12 07:54:16 -03003220 if (ctrl == NULL || !ctrl->is_int)
Hans Verkuil09965172010-08-01 14:32:42 -03003221 return -EINVAL;
3222
Hans Verkuil7ebbc392011-06-07 04:50:31 -03003223 if (ctrl->flags & V4L2_CTRL_FLAG_READ_ONLY)
3224 return -EACCES;
3225
Laurent Pinchart03d52852012-07-23 09:15:21 -03003226 c.value = control->value;
Sylwester Nawrocki2ccbe772013-01-19 15:51:55 -03003227 ret = set_ctrl_lock(fh, ctrl, &c);
Laurent Pinchart03d52852012-07-23 09:15:21 -03003228 control->value = c.value;
3229 return ret;
Hans Verkuil09965172010-08-01 14:32:42 -03003230}
3231EXPORT_SYMBOL(v4l2_s_ctrl);
3232
Sakari Ailus0c4348a2014-06-12 13:09:42 -03003233int __v4l2_ctrl_s_ctrl(struct v4l2_ctrl *ctrl, s32 val)
Hans Verkuil09965172010-08-01 14:32:42 -03003234{
Sakari Ailus0c4348a2014-06-12 13:09:42 -03003235 lockdep_assert_held(ctrl->handler->lock);
Laurent Pinchart03d52852012-07-23 09:15:21 -03003236
Hans Verkuil09965172010-08-01 14:32:42 -03003237 /* It's a driver bug if this happens. */
Hans Verkuild9a25472014-06-12 07:54:16 -03003238 WARN_ON(!ctrl->is_int);
Hans Verkuil5d0360a2014-07-21 10:45:42 -03003239 ctrl->val = val;
Hans Verkuil7a7f1ab2014-09-22 11:08:55 -03003240 return set_ctrl(NULL, ctrl, 0);
Sakari Ailus0c4348a2014-06-12 13:09:42 -03003241}
3242EXPORT_SYMBOL(__v4l2_ctrl_s_ctrl);
3243
3244int __v4l2_ctrl_s_ctrl_int64(struct v4l2_ctrl *ctrl, s64 val)
Laurent Pinchart03d52852012-07-23 09:15:21 -03003245{
Sakari Ailus0c4348a2014-06-12 13:09:42 -03003246 lockdep_assert_held(ctrl->handler->lock);
Laurent Pinchart03d52852012-07-23 09:15:21 -03003247
3248 /* It's a driver bug if this happens. */
Hans Verkuil998e7652014-06-10 07:55:00 -03003249 WARN_ON(ctrl->is_ptr || ctrl->type != V4L2_CTRL_TYPE_INTEGER64);
Hans Verkuil5d0360a2014-07-21 10:45:42 -03003250 *ctrl->p_new.p_s64 = val;
Hans Verkuil7a7f1ab2014-09-22 11:08:55 -03003251 return set_ctrl(NULL, ctrl, 0);
Laurent Pinchart03d52852012-07-23 09:15:21 -03003252}
Sakari Ailus0c4348a2014-06-12 13:09:42 -03003253EXPORT_SYMBOL(__v4l2_ctrl_s_ctrl_int64);
Laurent Pinchart03d52852012-07-23 09:15:21 -03003254
Hans Verkuil5d0360a2014-07-21 10:45:42 -03003255int __v4l2_ctrl_s_ctrl_string(struct v4l2_ctrl *ctrl, const char *s)
3256{
3257 lockdep_assert_held(ctrl->handler->lock);
3258
3259 /* It's a driver bug if this happens. */
3260 WARN_ON(ctrl->type != V4L2_CTRL_TYPE_STRING);
3261 strlcpy(ctrl->p_new.p_char, s, ctrl->maximum + 1);
Hans Verkuil7a7f1ab2014-09-22 11:08:55 -03003262 return set_ctrl(NULL, ctrl, 0);
Hans Verkuil5d0360a2014-07-21 10:45:42 -03003263}
3264EXPORT_SYMBOL(__v4l2_ctrl_s_ctrl_string);
3265
Hans Verkuil8ac7a942012-09-07 04:46:39 -03003266void v4l2_ctrl_notify(struct v4l2_ctrl *ctrl, v4l2_ctrl_notify_fnc notify, void *priv)
3267{
3268 if (ctrl == NULL)
3269 return;
3270 if (notify == NULL) {
3271 ctrl->call_notify = 0;
3272 return;
3273 }
3274 if (WARN_ON(ctrl->handler->notify && ctrl->handler->notify != notify))
3275 return;
3276 ctrl->handler->notify = notify;
3277 ctrl->handler->notify_priv = priv;
3278 ctrl->call_notify = 1;
3279}
3280EXPORT_SYMBOL(v4l2_ctrl_notify);
3281
Sakari Ailus5a573922014-06-12 13:09:40 -03003282int __v4l2_ctrl_modify_range(struct v4l2_ctrl *ctrl,
Hans Verkuil0ba2aeb2014-04-16 09:41:25 -03003283 s64 min, s64 max, u64 step, s64 def)
Sylwester Nawrocki2ccbe772013-01-19 15:51:55 -03003284{
Ricardo Ribalda95ad7ff2015-11-11 09:58:34 -02003285 bool value_changed;
3286 bool range_changed = false;
Hans Verkuil302ab7c2014-06-10 07:06:50 -03003287 int ret;
Sylwester Nawrocki2ccbe772013-01-19 15:51:55 -03003288
Sakari Ailus5a573922014-06-12 13:09:40 -03003289 lockdep_assert_held(ctrl->handler->lock);
3290
Sylwester Nawrocki2ccbe772013-01-19 15:51:55 -03003291 switch (ctrl->type) {
3292 case V4L2_CTRL_TYPE_INTEGER:
Hans Verkuil0ba2aeb2014-04-16 09:41:25 -03003293 case V4L2_CTRL_TYPE_INTEGER64:
Sylwester Nawrocki2ccbe772013-01-19 15:51:55 -03003294 case V4L2_CTRL_TYPE_BOOLEAN:
3295 case V4L2_CTRL_TYPE_MENU:
3296 case V4L2_CTRL_TYPE_INTEGER_MENU:
3297 case V4L2_CTRL_TYPE_BITMASK:
Hans Verkuildda4a4d2014-06-10 07:30:04 -03003298 case V4L2_CTRL_TYPE_U8:
3299 case V4L2_CTRL_TYPE_U16:
Hans Verkuil811c5082014-07-21 10:45:37 -03003300 case V4L2_CTRL_TYPE_U32:
Hans Verkuil302ab7c2014-06-10 07:06:50 -03003301 if (ctrl->is_array)
3302 return -EINVAL;
3303 ret = check_range(ctrl->type, min, max, step, def);
Sylwester Nawrocki2ccbe772013-01-19 15:51:55 -03003304 if (ret)
3305 return ret;
3306 break;
3307 default:
3308 return -EINVAL;
3309 }
Ricardo Ribalda95ad7ff2015-11-11 09:58:34 -02003310 if ((ctrl->minimum != min) || (ctrl->maximum != max) ||
3311 (ctrl->step != step) || ctrl->default_value != def) {
3312 range_changed = true;
3313 ctrl->minimum = min;
3314 ctrl->maximum = max;
3315 ctrl->step = step;
3316 ctrl->default_value = def;
3317 }
Hans Verkuil7a7f1ab2014-09-22 11:08:55 -03003318 cur_to_new(ctrl);
3319 if (validate_new(ctrl, ctrl->p_new)) {
3320 if (ctrl->type == V4L2_CTRL_TYPE_INTEGER64)
3321 *ctrl->p_new.p_s64 = def;
3322 else
3323 *ctrl->p_new.p_s32 = def;
3324 }
3325
3326 if (ctrl->type == V4L2_CTRL_TYPE_INTEGER64)
Ricardo Ribalda95ad7ff2015-11-11 09:58:34 -02003327 value_changed = *ctrl->p_new.p_s64 != *ctrl->p_cur.p_s64;
Hans Verkuil7a7f1ab2014-09-22 11:08:55 -03003328 else
Ricardo Ribalda95ad7ff2015-11-11 09:58:34 -02003329 value_changed = *ctrl->p_new.p_s32 != *ctrl->p_cur.p_s32;
3330 if (value_changed)
Hans Verkuil7a7f1ab2014-09-22 11:08:55 -03003331 ret = set_ctrl(NULL, ctrl, V4L2_EVENT_CTRL_CH_RANGE);
Ricardo Ribalda95ad7ff2015-11-11 09:58:34 -02003332 else if (range_changed)
Sylwester Nawrocki2ccbe772013-01-19 15:51:55 -03003333 send_event(NULL, ctrl, V4L2_EVENT_CTRL_CH_RANGE);
Sylwester Nawrocki2ccbe772013-01-19 15:51:55 -03003334 return ret;
3335}
Sakari Ailus5a573922014-06-12 13:09:40 -03003336EXPORT_SYMBOL(__v4l2_ctrl_modify_range);
Sylwester Nawrocki2ccbe772013-01-19 15:51:55 -03003337
Hans Verkuil6e6d76c2012-05-07 16:53:20 -03003338static int v4l2_ctrl_add_event(struct v4l2_subscribed_event *sev, unsigned elems)
Hans Verkuil6e239392011-06-07 11:13:44 -03003339{
Hans de Goede3e3661492012-04-08 12:59:47 -03003340 struct v4l2_ctrl *ctrl = v4l2_ctrl_find(sev->fh->ctrl_handler, sev->id);
3341
3342 if (ctrl == NULL)
3343 return -EINVAL;
3344
Hans Verkuil6e239392011-06-07 11:13:44 -03003345 v4l2_ctrl_lock(ctrl);
Hans Verkuil77068d32011-06-13 18:55:58 -03003346 list_add_tail(&sev->node, &ctrl->ev_subs);
Hans Verkuil6e239392011-06-07 11:13:44 -03003347 if (ctrl->type != V4L2_CTRL_TYPE_CTRL_CLASS &&
Hans Verkuil77068d32011-06-13 18:55:58 -03003348 (sev->flags & V4L2_EVENT_SUB_FL_SEND_INITIAL)) {
Hans Verkuil6e239392011-06-07 11:13:44 -03003349 struct v4l2_event ev;
Hans Verkuilc12fcfd2011-06-14 02:42:45 -03003350 u32 changes = V4L2_EVENT_CTRL_CH_FLAGS;
Hans Verkuil6e239392011-06-07 11:13:44 -03003351
Hans Verkuilc12fcfd2011-06-14 02:42:45 -03003352 if (!(ctrl->flags & V4L2_CTRL_FLAG_WRITE_ONLY))
3353 changes |= V4L2_EVENT_CTRL_CH_VALUE;
3354 fill_event(&ev, ctrl, changes);
Hans Verkuil6e6d76c2012-05-07 16:53:20 -03003355 /* Mark the queue as active, allowing this initial
3356 event to be accepted. */
3357 sev->elems = elems;
Hans Verkuil77068d32011-06-13 18:55:58 -03003358 v4l2_event_queue_fh(sev->fh, &ev);
Hans Verkuil6e239392011-06-07 11:13:44 -03003359 }
3360 v4l2_ctrl_unlock(ctrl);
Hans de Goede3e3661492012-04-08 12:59:47 -03003361 return 0;
Hans Verkuil6e239392011-06-07 11:13:44 -03003362}
Hans Verkuil6e239392011-06-07 11:13:44 -03003363
Hans de Goede3e3661492012-04-08 12:59:47 -03003364static void v4l2_ctrl_del_event(struct v4l2_subscribed_event *sev)
Hans Verkuil6e239392011-06-07 11:13:44 -03003365{
Hans de Goede3e3661492012-04-08 12:59:47 -03003366 struct v4l2_ctrl *ctrl = v4l2_ctrl_find(sev->fh->ctrl_handler, sev->id);
3367
Hans Verkuil6e239392011-06-07 11:13:44 -03003368 v4l2_ctrl_lock(ctrl);
Hans Verkuil77068d32011-06-13 18:55:58 -03003369 list_del(&sev->node);
Hans Verkuil6e239392011-06-07 11:13:44 -03003370 v4l2_ctrl_unlock(ctrl);
3371}
Hans de Goede3e3661492012-04-08 12:59:47 -03003372
3373void v4l2_ctrl_replace(struct v4l2_event *old, const struct v4l2_event *new)
3374{
3375 u32 old_changes = old->u.ctrl.changes;
3376
3377 old->u.ctrl = new->u.ctrl;
3378 old->u.ctrl.changes |= old_changes;
3379}
3380EXPORT_SYMBOL(v4l2_ctrl_replace);
3381
3382void v4l2_ctrl_merge(const struct v4l2_event *old, struct v4l2_event *new)
3383{
3384 new->u.ctrl.changes |= old->u.ctrl.changes;
3385}
3386EXPORT_SYMBOL(v4l2_ctrl_merge);
3387
3388const struct v4l2_subscribed_event_ops v4l2_ctrl_sub_ev_ops = {
3389 .add = v4l2_ctrl_add_event,
3390 .del = v4l2_ctrl_del_event,
3391 .replace = v4l2_ctrl_replace,
3392 .merge = v4l2_ctrl_merge,
3393};
3394EXPORT_SYMBOL(v4l2_ctrl_sub_ev_ops);
Hans Verkuile2ecb252012-02-02 08:20:53 -03003395
3396int v4l2_ctrl_log_status(struct file *file, void *fh)
3397{
3398 struct video_device *vfd = video_devdata(file);
3399 struct v4l2_fh *vfh = file->private_data;
3400
3401 if (test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) && vfd->v4l2_dev)
3402 v4l2_ctrl_handler_log_status(vfh->ctrl_handler,
3403 vfd->v4l2_dev->name);
3404 return 0;
3405}
3406EXPORT_SYMBOL(v4l2_ctrl_log_status);
Hans Verkuila26243b2012-01-27 16:18:42 -03003407
3408int v4l2_ctrl_subscribe_event(struct v4l2_fh *fh,
Hans Verkuil85f5fe32012-09-04 11:46:09 -03003409 const struct v4l2_event_subscription *sub)
Hans Verkuila26243b2012-01-27 16:18:42 -03003410{
3411 if (sub->type == V4L2_EVENT_CTRL)
Hans de Goede3e3661492012-04-08 12:59:47 -03003412 return v4l2_event_subscribe(fh, sub, 0, &v4l2_ctrl_sub_ev_ops);
Hans Verkuila26243b2012-01-27 16:18:42 -03003413 return -EINVAL;
3414}
3415EXPORT_SYMBOL(v4l2_ctrl_subscribe_event);
3416
Sylwester Nawrocki22fa4272013-01-22 19:00:23 -03003417int v4l2_ctrl_subdev_subscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
3418 struct v4l2_event_subscription *sub)
3419{
3420 if (!sd->ctrl_handler)
3421 return -EINVAL;
3422 return v4l2_ctrl_subscribe_event(fh, sub);
3423}
3424EXPORT_SYMBOL(v4l2_ctrl_subdev_subscribe_event);
3425
Hans Verkuila26243b2012-01-27 16:18:42 -03003426unsigned int v4l2_ctrl_poll(struct file *file, struct poll_table_struct *wait)
3427{
3428 struct v4l2_fh *fh = file->private_data;
3429
3430 if (v4l2_event_pending(fh))
3431 return POLLPRI;
3432 poll_wait(file, &fh->wait, wait);
3433 return 0;
3434}
3435EXPORT_SYMBOL(v4l2_ctrl_poll);