1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * vivid-ctrls.c - control support functions.
4 *
5 * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
6 */
7
8 #include <linux/errno.h>
9 #include <linux/kernel.h>
10 #include <linux/videodev2.h>
11 #include <media/v4l2-event.h>
12 #include <media/v4l2-common.h>
13
14 #include "vivid-core.h"
15 #include "vivid-vid-cap.h"
16 #include "vivid-vid-out.h"
17 #include "vivid-vid-common.h"
18 #include "vivid-radio-common.h"
19 #include "vivid-osd.h"
20 #include "vivid-ctrls.h"
21 #include "vivid-cec.h"
22
23 #define VIVID_CID_CUSTOM_BASE (V4L2_CID_USER_BASE | 0xf000)
24 #define VIVID_CID_BUTTON (VIVID_CID_CUSTOM_BASE + 0)
25 #define VIVID_CID_BOOLEAN (VIVID_CID_CUSTOM_BASE + 1)
26 #define VIVID_CID_INTEGER (VIVID_CID_CUSTOM_BASE + 2)
27 #define VIVID_CID_INTEGER64 (VIVID_CID_CUSTOM_BASE + 3)
28 #define VIVID_CID_MENU (VIVID_CID_CUSTOM_BASE + 4)
29 #define VIVID_CID_STRING (VIVID_CID_CUSTOM_BASE + 5)
30 #define VIVID_CID_BITMASK (VIVID_CID_CUSTOM_BASE + 6)
31 #define VIVID_CID_INTMENU (VIVID_CID_CUSTOM_BASE + 7)
32 #define VIVID_CID_U32_ARRAY (VIVID_CID_CUSTOM_BASE + 8)
33 #define VIVID_CID_U16_MATRIX (VIVID_CID_CUSTOM_BASE + 9)
34 #define VIVID_CID_U8_4D_ARRAY (VIVID_CID_CUSTOM_BASE + 10)
35 #define VIVID_CID_AREA (VIVID_CID_CUSTOM_BASE + 11)
36
37 #define VIVID_CID_VIVID_BASE (0x00f00000 | 0xf000)
38 #define VIVID_CID_VIVID_CLASS (0x00f00000 | 1)
39 #define VIVID_CID_TEST_PATTERN (VIVID_CID_VIVID_BASE + 0)
40 #define VIVID_CID_OSD_TEXT_MODE (VIVID_CID_VIVID_BASE + 1)
41 #define VIVID_CID_HOR_MOVEMENT (VIVID_CID_VIVID_BASE + 2)
42 #define VIVID_CID_VERT_MOVEMENT (VIVID_CID_VIVID_BASE + 3)
43 #define VIVID_CID_SHOW_BORDER (VIVID_CID_VIVID_BASE + 4)
44 #define VIVID_CID_SHOW_SQUARE (VIVID_CID_VIVID_BASE + 5)
45 #define VIVID_CID_INSERT_SAV (VIVID_CID_VIVID_BASE + 6)
46 #define VIVID_CID_INSERT_EAV (VIVID_CID_VIVID_BASE + 7)
47 #define VIVID_CID_VBI_CAP_INTERLACED (VIVID_CID_VIVID_BASE + 8)
48
49 #define VIVID_CID_HFLIP (VIVID_CID_VIVID_BASE + 20)
50 #define VIVID_CID_VFLIP (VIVID_CID_VIVID_BASE + 21)
51 #define VIVID_CID_STD_ASPECT_RATIO (VIVID_CID_VIVID_BASE + 22)
52 #define VIVID_CID_DV_TIMINGS_ASPECT_RATIO (VIVID_CID_VIVID_BASE + 23)
53 #define VIVID_CID_TSTAMP_SRC (VIVID_CID_VIVID_BASE + 24)
54 #define VIVID_CID_COLORSPACE (VIVID_CID_VIVID_BASE + 25)
55 #define VIVID_CID_XFER_FUNC (VIVID_CID_VIVID_BASE + 26)
56 #define VIVID_CID_YCBCR_ENC (VIVID_CID_VIVID_BASE + 27)
57 #define VIVID_CID_QUANTIZATION (VIVID_CID_VIVID_BASE + 28)
58 #define VIVID_CID_LIMITED_RGB_RANGE (VIVID_CID_VIVID_BASE + 29)
59 #define VIVID_CID_ALPHA_MODE (VIVID_CID_VIVID_BASE + 30)
60 #define VIVID_CID_HAS_CROP_CAP (VIVID_CID_VIVID_BASE + 31)
61 #define VIVID_CID_HAS_COMPOSE_CAP (VIVID_CID_VIVID_BASE + 32)
62 #define VIVID_CID_HAS_SCALER_CAP (VIVID_CID_VIVID_BASE + 33)
63 #define VIVID_CID_HAS_CROP_OUT (VIVID_CID_VIVID_BASE + 34)
64 #define VIVID_CID_HAS_COMPOSE_OUT (VIVID_CID_VIVID_BASE + 35)
65 #define VIVID_CID_HAS_SCALER_OUT (VIVID_CID_VIVID_BASE + 36)
66 #define VIVID_CID_LOOP_VIDEO (VIVID_CID_VIVID_BASE + 37)
67 #define VIVID_CID_SEQ_WRAP (VIVID_CID_VIVID_BASE + 38)
68 #define VIVID_CID_TIME_WRAP (VIVID_CID_VIVID_BASE + 39)
69 #define VIVID_CID_MAX_EDID_BLOCKS (VIVID_CID_VIVID_BASE + 40)
70 #define VIVID_CID_PERCENTAGE_FILL (VIVID_CID_VIVID_BASE + 41)
71 #define VIVID_CID_REDUCED_FPS (VIVID_CID_VIVID_BASE + 42)
72 #define VIVID_CID_HSV_ENC (VIVID_CID_VIVID_BASE + 43)
73 #define VIVID_CID_DISPLAY_PRESENT (VIVID_CID_VIVID_BASE + 44)
74
75 #define VIVID_CID_STD_SIGNAL_MODE (VIVID_CID_VIVID_BASE + 60)
76 #define VIVID_CID_STANDARD (VIVID_CID_VIVID_BASE + 61)
77 #define VIVID_CID_DV_TIMINGS_SIGNAL_MODE (VIVID_CID_VIVID_BASE + 62)
78 #define VIVID_CID_DV_TIMINGS (VIVID_CID_VIVID_BASE + 63)
79 #define VIVID_CID_PERC_DROPPED (VIVID_CID_VIVID_BASE + 64)
80 #define VIVID_CID_DISCONNECT (VIVID_CID_VIVID_BASE + 65)
81 #define VIVID_CID_DQBUF_ERROR (VIVID_CID_VIVID_BASE + 66)
82 #define VIVID_CID_QUEUE_SETUP_ERROR (VIVID_CID_VIVID_BASE + 67)
83 #define VIVID_CID_BUF_PREPARE_ERROR (VIVID_CID_VIVID_BASE + 68)
84 #define VIVID_CID_START_STR_ERROR (VIVID_CID_VIVID_BASE + 69)
85 #define VIVID_CID_QUEUE_ERROR (VIVID_CID_VIVID_BASE + 70)
86 #define VIVID_CID_CLEAR_FB (VIVID_CID_VIVID_BASE + 71)
87 #define VIVID_CID_REQ_VALIDATE_ERROR (VIVID_CID_VIVID_BASE + 72)
88
89 #define VIVID_CID_RADIO_SEEK_MODE (VIVID_CID_VIVID_BASE + 90)
90 #define VIVID_CID_RADIO_SEEK_PROG_LIM (VIVID_CID_VIVID_BASE + 91)
91 #define VIVID_CID_RADIO_RX_RDS_RBDS (VIVID_CID_VIVID_BASE + 92)
92 #define VIVID_CID_RADIO_RX_RDS_BLOCKIO (VIVID_CID_VIVID_BASE + 93)
93
94 #define VIVID_CID_RADIO_TX_RDS_BLOCKIO (VIVID_CID_VIVID_BASE + 94)
95
96 #define VIVID_CID_SDR_CAP_FM_DEVIATION (VIVID_CID_VIVID_BASE + 110)
97
98 #define VIVID_CID_META_CAP_GENERATE_PTS (VIVID_CID_VIVID_BASE + 111)
99 #define VIVID_CID_META_CAP_GENERATE_SCR (VIVID_CID_VIVID_BASE + 112)
100
101 /* General User Controls */
102
vivid_user_gen_s_ctrl(struct v4l2_ctrl * ctrl)103 static int vivid_user_gen_s_ctrl(struct v4l2_ctrl *ctrl)
104 {
105 struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_user_gen);
106
107 switch (ctrl->id) {
108 case VIVID_CID_DISCONNECT:
109 v4l2_info(&dev->v4l2_dev, "disconnect\n");
110 clear_bit(V4L2_FL_REGISTERED, &dev->vid_cap_dev.flags);
111 clear_bit(V4L2_FL_REGISTERED, &dev->vid_out_dev.flags);
112 clear_bit(V4L2_FL_REGISTERED, &dev->vbi_cap_dev.flags);
113 clear_bit(V4L2_FL_REGISTERED, &dev->vbi_out_dev.flags);
114 clear_bit(V4L2_FL_REGISTERED, &dev->sdr_cap_dev.flags);
115 clear_bit(V4L2_FL_REGISTERED, &dev->radio_rx_dev.flags);
116 clear_bit(V4L2_FL_REGISTERED, &dev->radio_tx_dev.flags);
117 clear_bit(V4L2_FL_REGISTERED, &dev->meta_cap_dev.flags);
118 break;
119 case VIVID_CID_BUTTON:
120 dev->button_pressed = 30;
121 break;
122 }
123 return 0;
124 }
125
126 static const struct v4l2_ctrl_ops vivid_user_gen_ctrl_ops = {
127 .s_ctrl = vivid_user_gen_s_ctrl,
128 };
129
130 static const struct v4l2_ctrl_config vivid_ctrl_button = {
131 .ops = &vivid_user_gen_ctrl_ops,
132 .id = VIVID_CID_BUTTON,
133 .name = "Button",
134 .type = V4L2_CTRL_TYPE_BUTTON,
135 };
136
137 static const struct v4l2_ctrl_config vivid_ctrl_boolean = {
138 .ops = &vivid_user_gen_ctrl_ops,
139 .id = VIVID_CID_BOOLEAN,
140 .name = "Boolean",
141 .type = V4L2_CTRL_TYPE_BOOLEAN,
142 .min = 0,
143 .max = 1,
144 .step = 1,
145 .def = 1,
146 };
147
148 static const struct v4l2_ctrl_config vivid_ctrl_int32 = {
149 .ops = &vivid_user_gen_ctrl_ops,
150 .id = VIVID_CID_INTEGER,
151 .name = "Integer 32 Bits",
152 .type = V4L2_CTRL_TYPE_INTEGER,
153 .min = 0xffffffff80000000ULL,
154 .max = 0x7fffffff,
155 .step = 1,
156 };
157
158 static const struct v4l2_ctrl_config vivid_ctrl_int64 = {
159 .ops = &vivid_user_gen_ctrl_ops,
160 .id = VIVID_CID_INTEGER64,
161 .name = "Integer 64 Bits",
162 .type = V4L2_CTRL_TYPE_INTEGER64,
163 .min = 0x8000000000000000ULL,
164 .max = 0x7fffffffffffffffLL,
165 .step = 1,
166 };
167
168 static const struct v4l2_ctrl_config vivid_ctrl_u32_array = {
169 .ops = &vivid_user_gen_ctrl_ops,
170 .id = VIVID_CID_U32_ARRAY,
171 .name = "U32 1 Element Array",
172 .type = V4L2_CTRL_TYPE_U32,
173 .def = 0x18,
174 .min = 0x10,
175 .max = 0x20000,
176 .step = 1,
177 .dims = { 1 },
178 };
179
180 static const struct v4l2_ctrl_config vivid_ctrl_u16_matrix = {
181 .ops = &vivid_user_gen_ctrl_ops,
182 .id = VIVID_CID_U16_MATRIX,
183 .name = "U16 8x16 Matrix",
184 .type = V4L2_CTRL_TYPE_U16,
185 .def = 0x18,
186 .min = 0x10,
187 .max = 0x2000,
188 .step = 1,
189 .dims = { 8, 16 },
190 };
191
192 static const struct v4l2_ctrl_config vivid_ctrl_u8_4d_array = {
193 .ops = &vivid_user_gen_ctrl_ops,
194 .id = VIVID_CID_U8_4D_ARRAY,
195 .name = "U8 2x3x4x5 Array",
196 .type = V4L2_CTRL_TYPE_U8,
197 .def = 0x18,
198 .min = 0x10,
199 .max = 0x20,
200 .step = 1,
201 .dims = { 2, 3, 4, 5 },
202 };
203
204 static const char * const vivid_ctrl_menu_strings[] = {
205 "Menu Item 0 (Skipped)",
206 "Menu Item 1",
207 "Menu Item 2 (Skipped)",
208 "Menu Item 3",
209 "Menu Item 4",
210 "Menu Item 5 (Skipped)",
211 NULL,
212 };
213
214 static const struct v4l2_ctrl_config vivid_ctrl_menu = {
215 .ops = &vivid_user_gen_ctrl_ops,
216 .id = VIVID_CID_MENU,
217 .name = "Menu",
218 .type = V4L2_CTRL_TYPE_MENU,
219 .min = 1,
220 .max = 4,
221 .def = 3,
222 .menu_skip_mask = 0x04,
223 .qmenu = vivid_ctrl_menu_strings,
224 };
225
226 static const struct v4l2_ctrl_config vivid_ctrl_string = {
227 .ops = &vivid_user_gen_ctrl_ops,
228 .id = VIVID_CID_STRING,
229 .name = "String",
230 .type = V4L2_CTRL_TYPE_STRING,
231 .min = 2,
232 .max = 4,
233 .step = 1,
234 };
235
236 static const struct v4l2_ctrl_config vivid_ctrl_bitmask = {
237 .ops = &vivid_user_gen_ctrl_ops,
238 .id = VIVID_CID_BITMASK,
239 .name = "Bitmask",
240 .type = V4L2_CTRL_TYPE_BITMASK,
241 .def = 0x80002000,
242 .min = 0,
243 .max = 0x80402010,
244 .step = 0,
245 };
246
247 static const s64 vivid_ctrl_int_menu_values[] = {
248 1, 1, 2, 3, 5, 8, 13, 21, 42,
249 };
250
251 static const struct v4l2_ctrl_config vivid_ctrl_int_menu = {
252 .ops = &vivid_user_gen_ctrl_ops,
253 .id = VIVID_CID_INTMENU,
254 .name = "Integer Menu",
255 .type = V4L2_CTRL_TYPE_INTEGER_MENU,
256 .min = 1,
257 .max = 8,
258 .def = 4,
259 .menu_skip_mask = 0x02,
260 .qmenu_int = vivid_ctrl_int_menu_values,
261 };
262
263 static const struct v4l2_ctrl_config vivid_ctrl_disconnect = {
264 .ops = &vivid_user_gen_ctrl_ops,
265 .id = VIVID_CID_DISCONNECT,
266 .name = "Disconnect",
267 .type = V4L2_CTRL_TYPE_BUTTON,
268 };
269
270 static const struct v4l2_area area = {
271 .width = 1000,
272 .height = 2000,
273 };
274
275 static const struct v4l2_ctrl_config vivid_ctrl_area = {
276 .ops = &vivid_user_gen_ctrl_ops,
277 .id = VIVID_CID_AREA,
278 .name = "Area",
279 .type = V4L2_CTRL_TYPE_AREA,
280 .p_def.p_const = &area,
281 };
282
283 /* Framebuffer Controls */
284
vivid_fb_s_ctrl(struct v4l2_ctrl * ctrl)285 static int vivid_fb_s_ctrl(struct v4l2_ctrl *ctrl)
286 {
287 struct vivid_dev *dev = container_of(ctrl->handler,
288 struct vivid_dev, ctrl_hdl_fb);
289
290 switch (ctrl->id) {
291 case VIVID_CID_CLEAR_FB:
292 vivid_clear_fb(dev);
293 break;
294 }
295 return 0;
296 }
297
298 static const struct v4l2_ctrl_ops vivid_fb_ctrl_ops = {
299 .s_ctrl = vivid_fb_s_ctrl,
300 };
301
302 static const struct v4l2_ctrl_config vivid_ctrl_clear_fb = {
303 .ops = &vivid_fb_ctrl_ops,
304 .id = VIVID_CID_CLEAR_FB,
305 .name = "Clear Framebuffer",
306 .type = V4L2_CTRL_TYPE_BUTTON,
307 };
308
309
310 /* Video User Controls */
311
vivid_user_vid_g_volatile_ctrl(struct v4l2_ctrl * ctrl)312 static int vivid_user_vid_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
313 {
314 struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_user_vid);
315
316 switch (ctrl->id) {
317 case V4L2_CID_AUTOGAIN:
318 dev->gain->val = (jiffies_to_msecs(jiffies) / 1000) & 0xff;
319 break;
320 }
321 return 0;
322 }
323
vivid_user_vid_s_ctrl(struct v4l2_ctrl * ctrl)324 static int vivid_user_vid_s_ctrl(struct v4l2_ctrl *ctrl)
325 {
326 struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_user_vid);
327
328 switch (ctrl->id) {
329 case V4L2_CID_BRIGHTNESS:
330 dev->input_brightness[dev->input] = ctrl->val - dev->input * 128;
331 tpg_s_brightness(&dev->tpg, dev->input_brightness[dev->input]);
332 break;
333 case V4L2_CID_CONTRAST:
334 tpg_s_contrast(&dev->tpg, ctrl->val);
335 break;
336 case V4L2_CID_SATURATION:
337 tpg_s_saturation(&dev->tpg, ctrl->val);
338 break;
339 case V4L2_CID_HUE:
340 tpg_s_hue(&dev->tpg, ctrl->val);
341 break;
342 case V4L2_CID_HFLIP:
343 dev->hflip = ctrl->val;
344 tpg_s_hflip(&dev->tpg, dev->sensor_hflip ^ dev->hflip);
345 break;
346 case V4L2_CID_VFLIP:
347 dev->vflip = ctrl->val;
348 tpg_s_vflip(&dev->tpg, dev->sensor_vflip ^ dev->vflip);
349 break;
350 case V4L2_CID_ALPHA_COMPONENT:
351 tpg_s_alpha_component(&dev->tpg, ctrl->val);
352 break;
353 }
354 return 0;
355 }
356
357 static const struct v4l2_ctrl_ops vivid_user_vid_ctrl_ops = {
358 .g_volatile_ctrl = vivid_user_vid_g_volatile_ctrl,
359 .s_ctrl = vivid_user_vid_s_ctrl,
360 };
361
362
363 /* Video Capture Controls */
364
vivid_vid_cap_s_ctrl(struct v4l2_ctrl * ctrl)365 static int vivid_vid_cap_s_ctrl(struct v4l2_ctrl *ctrl)
366 {
367 static const u32 colorspaces[] = {
368 V4L2_COLORSPACE_SMPTE170M,
369 V4L2_COLORSPACE_REC709,
370 V4L2_COLORSPACE_SRGB,
371 V4L2_COLORSPACE_OPRGB,
372 V4L2_COLORSPACE_BT2020,
373 V4L2_COLORSPACE_DCI_P3,
374 V4L2_COLORSPACE_SMPTE240M,
375 V4L2_COLORSPACE_470_SYSTEM_M,
376 V4L2_COLORSPACE_470_SYSTEM_BG,
377 };
378 struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_vid_cap);
379 unsigned int i, j;
380
381 switch (ctrl->id) {
382 case VIVID_CID_TEST_PATTERN:
383 vivid_update_quality(dev);
384 tpg_s_pattern(&dev->tpg, ctrl->val);
385 break;
386 case VIVID_CID_COLORSPACE:
387 tpg_s_colorspace(&dev->tpg, colorspaces[ctrl->val]);
388 vivid_send_source_change(dev, TV);
389 vivid_send_source_change(dev, SVID);
390 vivid_send_source_change(dev, HDMI);
391 vivid_send_source_change(dev, WEBCAM);
392 break;
393 case VIVID_CID_XFER_FUNC:
394 tpg_s_xfer_func(&dev->tpg, ctrl->val);
395 vivid_send_source_change(dev, TV);
396 vivid_send_source_change(dev, SVID);
397 vivid_send_source_change(dev, HDMI);
398 vivid_send_source_change(dev, WEBCAM);
399 break;
400 case VIVID_CID_YCBCR_ENC:
401 tpg_s_ycbcr_enc(&dev->tpg, ctrl->val);
402 vivid_send_source_change(dev, TV);
403 vivid_send_source_change(dev, SVID);
404 vivid_send_source_change(dev, HDMI);
405 vivid_send_source_change(dev, WEBCAM);
406 break;
407 case VIVID_CID_HSV_ENC:
408 tpg_s_hsv_enc(&dev->tpg, ctrl->val ? V4L2_HSV_ENC_256 :
409 V4L2_HSV_ENC_180);
410 vivid_send_source_change(dev, TV);
411 vivid_send_source_change(dev, SVID);
412 vivid_send_source_change(dev, HDMI);
413 vivid_send_source_change(dev, WEBCAM);
414 break;
415 case VIVID_CID_QUANTIZATION:
416 tpg_s_quantization(&dev->tpg, ctrl->val);
417 vivid_send_source_change(dev, TV);
418 vivid_send_source_change(dev, SVID);
419 vivid_send_source_change(dev, HDMI);
420 vivid_send_source_change(dev, WEBCAM);
421 break;
422 case V4L2_CID_DV_RX_RGB_RANGE:
423 if (!vivid_is_hdmi_cap(dev))
424 break;
425 tpg_s_rgb_range(&dev->tpg, ctrl->val);
426 break;
427 case VIVID_CID_LIMITED_RGB_RANGE:
428 tpg_s_real_rgb_range(&dev->tpg, ctrl->val ?
429 V4L2_DV_RGB_RANGE_LIMITED : V4L2_DV_RGB_RANGE_FULL);
430 break;
431 case VIVID_CID_ALPHA_MODE:
432 tpg_s_alpha_mode(&dev->tpg, ctrl->val);
433 break;
434 case VIVID_CID_HOR_MOVEMENT:
435 tpg_s_mv_hor_mode(&dev->tpg, ctrl->val);
436 break;
437 case VIVID_CID_VERT_MOVEMENT:
438 tpg_s_mv_vert_mode(&dev->tpg, ctrl->val);
439 break;
440 case VIVID_CID_OSD_TEXT_MODE:
441 dev->osd_mode = ctrl->val;
442 break;
443 case VIVID_CID_PERCENTAGE_FILL:
444 tpg_s_perc_fill(&dev->tpg, ctrl->val);
445 for (i = 0; i < VIDEO_MAX_FRAME; i++)
446 dev->must_blank[i] = ctrl->val < 100;
447 break;
448 case VIVID_CID_INSERT_SAV:
449 tpg_s_insert_sav(&dev->tpg, ctrl->val);
450 break;
451 case VIVID_CID_INSERT_EAV:
452 tpg_s_insert_eav(&dev->tpg, ctrl->val);
453 break;
454 case VIVID_CID_HFLIP:
455 dev->sensor_hflip = ctrl->val;
456 tpg_s_hflip(&dev->tpg, dev->sensor_hflip ^ dev->hflip);
457 break;
458 case VIVID_CID_VFLIP:
459 dev->sensor_vflip = ctrl->val;
460 tpg_s_vflip(&dev->tpg, dev->sensor_vflip ^ dev->vflip);
461 break;
462 case VIVID_CID_REDUCED_FPS:
463 dev->reduced_fps = ctrl->val;
464 vivid_update_format_cap(dev, true);
465 break;
466 case VIVID_CID_HAS_CROP_CAP:
467 dev->has_crop_cap = ctrl->val;
468 vivid_update_format_cap(dev, true);
469 break;
470 case VIVID_CID_HAS_COMPOSE_CAP:
471 dev->has_compose_cap = ctrl->val;
472 vivid_update_format_cap(dev, true);
473 break;
474 case VIVID_CID_HAS_SCALER_CAP:
475 dev->has_scaler_cap = ctrl->val;
476 vivid_update_format_cap(dev, true);
477 break;
478 case VIVID_CID_SHOW_BORDER:
479 tpg_s_show_border(&dev->tpg, ctrl->val);
480 break;
481 case VIVID_CID_SHOW_SQUARE:
482 tpg_s_show_square(&dev->tpg, ctrl->val);
483 break;
484 case VIVID_CID_STD_ASPECT_RATIO:
485 dev->std_aspect_ratio[dev->input] = ctrl->val;
486 tpg_s_video_aspect(&dev->tpg, vivid_get_video_aspect(dev));
487 break;
488 case VIVID_CID_DV_TIMINGS_SIGNAL_MODE:
489 dev->dv_timings_signal_mode[dev->input] =
490 dev->ctrl_dv_timings_signal_mode->val;
491 dev->query_dv_timings[dev->input] = dev->ctrl_dv_timings->val;
492
493 dev->power_present = 0;
494 for (i = 0, j = 0;
495 i < ARRAY_SIZE(dev->dv_timings_signal_mode);
496 i++)
497 if (dev->input_type[i] == HDMI) {
498 if (dev->dv_timings_signal_mode[i] != NO_SIGNAL)
499 dev->power_present |= (1 << j);
500 j++;
501 }
502 __v4l2_ctrl_s_ctrl(dev->ctrl_rx_power_present,
503 dev->power_present);
504
505 v4l2_ctrl_activate(dev->ctrl_dv_timings,
506 dev->dv_timings_signal_mode[dev->input] ==
507 SELECTED_DV_TIMINGS);
508
509 vivid_update_quality(dev);
510 vivid_send_source_change(dev, HDMI);
511 break;
512 case VIVID_CID_DV_TIMINGS_ASPECT_RATIO:
513 dev->dv_timings_aspect_ratio[dev->input] = ctrl->val;
514 tpg_s_video_aspect(&dev->tpg, vivid_get_video_aspect(dev));
515 break;
516 case VIVID_CID_TSTAMP_SRC:
517 dev->tstamp_src_is_soe = ctrl->val;
518 dev->vb_vid_cap_q.timestamp_flags &= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
519 if (dev->tstamp_src_is_soe)
520 dev->vb_vid_cap_q.timestamp_flags |= V4L2_BUF_FLAG_TSTAMP_SRC_SOE;
521 break;
522 case VIVID_CID_MAX_EDID_BLOCKS:
523 dev->edid_max_blocks = ctrl->val;
524 if (dev->edid_blocks > dev->edid_max_blocks)
525 dev->edid_blocks = dev->edid_max_blocks;
526 break;
527 }
528 return 0;
529 }
530
531 static const struct v4l2_ctrl_ops vivid_vid_cap_ctrl_ops = {
532 .s_ctrl = vivid_vid_cap_s_ctrl,
533 };
534
535 static const char * const vivid_ctrl_hor_movement_strings[] = {
536 "Move Left Fast",
537 "Move Left",
538 "Move Left Slow",
539 "No Movement",
540 "Move Right Slow",
541 "Move Right",
542 "Move Right Fast",
543 NULL,
544 };
545
546 static const struct v4l2_ctrl_config vivid_ctrl_hor_movement = {
547 .ops = &vivid_vid_cap_ctrl_ops,
548 .id = VIVID_CID_HOR_MOVEMENT,
549 .name = "Horizontal Movement",
550 .type = V4L2_CTRL_TYPE_MENU,
551 .max = TPG_MOVE_POS_FAST,
552 .def = TPG_MOVE_NONE,
553 .qmenu = vivid_ctrl_hor_movement_strings,
554 };
555
556 static const char * const vivid_ctrl_vert_movement_strings[] = {
557 "Move Up Fast",
558 "Move Up",
559 "Move Up Slow",
560 "No Movement",
561 "Move Down Slow",
562 "Move Down",
563 "Move Down Fast",
564 NULL,
565 };
566
567 static const struct v4l2_ctrl_config vivid_ctrl_vert_movement = {
568 .ops = &vivid_vid_cap_ctrl_ops,
569 .id = VIVID_CID_VERT_MOVEMENT,
570 .name = "Vertical Movement",
571 .type = V4L2_CTRL_TYPE_MENU,
572 .max = TPG_MOVE_POS_FAST,
573 .def = TPG_MOVE_NONE,
574 .qmenu = vivid_ctrl_vert_movement_strings,
575 };
576
577 static const struct v4l2_ctrl_config vivid_ctrl_show_border = {
578 .ops = &vivid_vid_cap_ctrl_ops,
579 .id = VIVID_CID_SHOW_BORDER,
580 .name = "Show Border",
581 .type = V4L2_CTRL_TYPE_BOOLEAN,
582 .max = 1,
583 .step = 1,
584 };
585
586 static const struct v4l2_ctrl_config vivid_ctrl_show_square = {
587 .ops = &vivid_vid_cap_ctrl_ops,
588 .id = VIVID_CID_SHOW_SQUARE,
589 .name = "Show Square",
590 .type = V4L2_CTRL_TYPE_BOOLEAN,
591 .max = 1,
592 .step = 1,
593 };
594
595 static const char * const vivid_ctrl_osd_mode_strings[] = {
596 "All",
597 "Counters Only",
598 "None",
599 NULL,
600 };
601
602 static const struct v4l2_ctrl_config vivid_ctrl_osd_mode = {
603 .ops = &vivid_vid_cap_ctrl_ops,
604 .id = VIVID_CID_OSD_TEXT_MODE,
605 .name = "OSD Text Mode",
606 .type = V4L2_CTRL_TYPE_MENU,
607 .max = ARRAY_SIZE(vivid_ctrl_osd_mode_strings) - 2,
608 .qmenu = vivid_ctrl_osd_mode_strings,
609 };
610
611 static const struct v4l2_ctrl_config vivid_ctrl_perc_fill = {
612 .ops = &vivid_vid_cap_ctrl_ops,
613 .id = VIVID_CID_PERCENTAGE_FILL,
614 .name = "Fill Percentage of Frame",
615 .type = V4L2_CTRL_TYPE_INTEGER,
616 .min = 0,
617 .max = 100,
618 .def = 100,
619 .step = 1,
620 };
621
622 static const struct v4l2_ctrl_config vivid_ctrl_insert_sav = {
623 .ops = &vivid_vid_cap_ctrl_ops,
624 .id = VIVID_CID_INSERT_SAV,
625 .name = "Insert SAV Code in Image",
626 .type = V4L2_CTRL_TYPE_BOOLEAN,
627 .max = 1,
628 .step = 1,
629 };
630
631 static const struct v4l2_ctrl_config vivid_ctrl_insert_eav = {
632 .ops = &vivid_vid_cap_ctrl_ops,
633 .id = VIVID_CID_INSERT_EAV,
634 .name = "Insert EAV Code in Image",
635 .type = V4L2_CTRL_TYPE_BOOLEAN,
636 .max = 1,
637 .step = 1,
638 };
639
640 static const struct v4l2_ctrl_config vivid_ctrl_hflip = {
641 .ops = &vivid_vid_cap_ctrl_ops,
642 .id = VIVID_CID_HFLIP,
643 .name = "Sensor Flipped Horizontally",
644 .type = V4L2_CTRL_TYPE_BOOLEAN,
645 .max = 1,
646 .step = 1,
647 };
648
649 static const struct v4l2_ctrl_config vivid_ctrl_vflip = {
650 .ops = &vivid_vid_cap_ctrl_ops,
651 .id = VIVID_CID_VFLIP,
652 .name = "Sensor Flipped Vertically",
653 .type = V4L2_CTRL_TYPE_BOOLEAN,
654 .max = 1,
655 .step = 1,
656 };
657
658 static const struct v4l2_ctrl_config vivid_ctrl_reduced_fps = {
659 .ops = &vivid_vid_cap_ctrl_ops,
660 .id = VIVID_CID_REDUCED_FPS,
661 .name = "Reduced Framerate",
662 .type = V4L2_CTRL_TYPE_BOOLEAN,
663 .max = 1,
664 .step = 1,
665 };
666
667 static const struct v4l2_ctrl_config vivid_ctrl_has_crop_cap = {
668 .ops = &vivid_vid_cap_ctrl_ops,
669 .id = VIVID_CID_HAS_CROP_CAP,
670 .name = "Enable Capture Cropping",
671 .type = V4L2_CTRL_TYPE_BOOLEAN,
672 .max = 1,
673 .def = 1,
674 .step = 1,
675 };
676
677 static const struct v4l2_ctrl_config vivid_ctrl_has_compose_cap = {
678 .ops = &vivid_vid_cap_ctrl_ops,
679 .id = VIVID_CID_HAS_COMPOSE_CAP,
680 .name = "Enable Capture Composing",
681 .type = V4L2_CTRL_TYPE_BOOLEAN,
682 .max = 1,
683 .def = 1,
684 .step = 1,
685 };
686
687 static const struct v4l2_ctrl_config vivid_ctrl_has_scaler_cap = {
688 .ops = &vivid_vid_cap_ctrl_ops,
689 .id = VIVID_CID_HAS_SCALER_CAP,
690 .name = "Enable Capture Scaler",
691 .type = V4L2_CTRL_TYPE_BOOLEAN,
692 .max = 1,
693 .def = 1,
694 .step = 1,
695 };
696
697 static const char * const vivid_ctrl_tstamp_src_strings[] = {
698 "End of Frame",
699 "Start of Exposure",
700 NULL,
701 };
702
703 static const struct v4l2_ctrl_config vivid_ctrl_tstamp_src = {
704 .ops = &vivid_vid_cap_ctrl_ops,
705 .id = VIVID_CID_TSTAMP_SRC,
706 .name = "Timestamp Source",
707 .type = V4L2_CTRL_TYPE_MENU,
708 .max = ARRAY_SIZE(vivid_ctrl_tstamp_src_strings) - 2,
709 .qmenu = vivid_ctrl_tstamp_src_strings,
710 };
711
712 static const struct v4l2_ctrl_config vivid_ctrl_std_aspect_ratio = {
713 .ops = &vivid_vid_cap_ctrl_ops,
714 .id = VIVID_CID_STD_ASPECT_RATIO,
715 .name = "Standard Aspect Ratio",
716 .type = V4L2_CTRL_TYPE_MENU,
717 .min = 1,
718 .max = 4,
719 .def = 1,
720 .qmenu = tpg_aspect_strings,
721 };
722
723 static const char * const vivid_ctrl_dv_timings_signal_mode_strings[] = {
724 "Current DV Timings",
725 "No Signal",
726 "No Lock",
727 "Out of Range",
728 "Selected DV Timings",
729 "Cycle Through All DV Timings",
730 "Custom DV Timings",
731 NULL,
732 };
733
734 static const struct v4l2_ctrl_config vivid_ctrl_dv_timings_signal_mode = {
735 .ops = &vivid_vid_cap_ctrl_ops,
736 .id = VIVID_CID_DV_TIMINGS_SIGNAL_MODE,
737 .name = "DV Timings Signal Mode",
738 .type = V4L2_CTRL_TYPE_MENU,
739 .max = 5,
740 .qmenu = vivid_ctrl_dv_timings_signal_mode_strings,
741 };
742
743 static const struct v4l2_ctrl_config vivid_ctrl_dv_timings_aspect_ratio = {
744 .ops = &vivid_vid_cap_ctrl_ops,
745 .id = VIVID_CID_DV_TIMINGS_ASPECT_RATIO,
746 .name = "DV Timings Aspect Ratio",
747 .type = V4L2_CTRL_TYPE_MENU,
748 .max = 3,
749 .qmenu = tpg_aspect_strings,
750 };
751
752 static const struct v4l2_ctrl_config vivid_ctrl_max_edid_blocks = {
753 .ops = &vivid_vid_cap_ctrl_ops,
754 .id = VIVID_CID_MAX_EDID_BLOCKS,
755 .name = "Maximum EDID Blocks",
756 .type = V4L2_CTRL_TYPE_INTEGER,
757 .min = 1,
758 .max = 256,
759 .def = 2,
760 .step = 1,
761 };
762
763 static const char * const vivid_ctrl_colorspace_strings[] = {
764 "SMPTE 170M",
765 "Rec. 709",
766 "sRGB",
767 "opRGB",
768 "BT.2020",
769 "DCI-P3",
770 "SMPTE 240M",
771 "470 System M",
772 "470 System BG",
773 NULL,
774 };
775
776 static const struct v4l2_ctrl_config vivid_ctrl_colorspace = {
777 .ops = &vivid_vid_cap_ctrl_ops,
778 .id = VIVID_CID_COLORSPACE,
779 .name = "Colorspace",
780 .type = V4L2_CTRL_TYPE_MENU,
781 .max = ARRAY_SIZE(vivid_ctrl_colorspace_strings) - 2,
782 .def = 2,
783 .qmenu = vivid_ctrl_colorspace_strings,
784 };
785
786 static const char * const vivid_ctrl_xfer_func_strings[] = {
787 "Default",
788 "Rec. 709",
789 "sRGB",
790 "opRGB",
791 "SMPTE 240M",
792 "None",
793 "DCI-P3",
794 "SMPTE 2084",
795 NULL,
796 };
797
798 static const struct v4l2_ctrl_config vivid_ctrl_xfer_func = {
799 .ops = &vivid_vid_cap_ctrl_ops,
800 .id = VIVID_CID_XFER_FUNC,
801 .name = "Transfer Function",
802 .type = V4L2_CTRL_TYPE_MENU,
803 .max = ARRAY_SIZE(vivid_ctrl_xfer_func_strings) - 2,
804 .qmenu = vivid_ctrl_xfer_func_strings,
805 };
806
807 static const char * const vivid_ctrl_ycbcr_enc_strings[] = {
808 "Default",
809 "ITU-R 601",
810 "Rec. 709",
811 "xvYCC 601",
812 "xvYCC 709",
813 "",
814 "BT.2020",
815 "BT.2020 Constant Luminance",
816 "SMPTE 240M",
817 NULL,
818 };
819
820 static const struct v4l2_ctrl_config vivid_ctrl_ycbcr_enc = {
821 .ops = &vivid_vid_cap_ctrl_ops,
822 .id = VIVID_CID_YCBCR_ENC,
823 .name = "Y'CbCr Encoding",
824 .type = V4L2_CTRL_TYPE_MENU,
825 .menu_skip_mask = 1 << 5,
826 .max = ARRAY_SIZE(vivid_ctrl_ycbcr_enc_strings) - 2,
827 .qmenu = vivid_ctrl_ycbcr_enc_strings,
828 };
829
830 static const char * const vivid_ctrl_hsv_enc_strings[] = {
831 "Hue 0-179",
832 "Hue 0-256",
833 NULL,
834 };
835
836 static const struct v4l2_ctrl_config vivid_ctrl_hsv_enc = {
837 .ops = &vivid_vid_cap_ctrl_ops,
838 .id = VIVID_CID_HSV_ENC,
839 .name = "HSV Encoding",
840 .type = V4L2_CTRL_TYPE_MENU,
841 .max = ARRAY_SIZE(vivid_ctrl_hsv_enc_strings) - 2,
842 .qmenu = vivid_ctrl_hsv_enc_strings,
843 };
844
845 static const char * const vivid_ctrl_quantization_strings[] = {
846 "Default",
847 "Full Range",
848 "Limited Range",
849 NULL,
850 };
851
852 static const struct v4l2_ctrl_config vivid_ctrl_quantization = {
853 .ops = &vivid_vid_cap_ctrl_ops,
854 .id = VIVID_CID_QUANTIZATION,
855 .name = "Quantization",
856 .type = V4L2_CTRL_TYPE_MENU,
857 .max = ARRAY_SIZE(vivid_ctrl_quantization_strings) - 2,
858 .qmenu = vivid_ctrl_quantization_strings,
859 };
860
861 static const struct v4l2_ctrl_config vivid_ctrl_alpha_mode = {
862 .ops = &vivid_vid_cap_ctrl_ops,
863 .id = VIVID_CID_ALPHA_MODE,
864 .name = "Apply Alpha To Red Only",
865 .type = V4L2_CTRL_TYPE_BOOLEAN,
866 .max = 1,
867 .step = 1,
868 };
869
870 static const struct v4l2_ctrl_config vivid_ctrl_limited_rgb_range = {
871 .ops = &vivid_vid_cap_ctrl_ops,
872 .id = VIVID_CID_LIMITED_RGB_RANGE,
873 .name = "Limited RGB Range (16-235)",
874 .type = V4L2_CTRL_TYPE_BOOLEAN,
875 .max = 1,
876 .step = 1,
877 };
878
879
880 /* Video Loop Control */
881
vivid_loop_cap_s_ctrl(struct v4l2_ctrl * ctrl)882 static int vivid_loop_cap_s_ctrl(struct v4l2_ctrl *ctrl)
883 {
884 struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_loop_cap);
885
886 switch (ctrl->id) {
887 case VIVID_CID_LOOP_VIDEO:
888 dev->loop_video = ctrl->val;
889 vivid_update_quality(dev);
890 vivid_send_source_change(dev, SVID);
891 vivid_send_source_change(dev, HDMI);
892 break;
893 }
894 return 0;
895 }
896
897 static const struct v4l2_ctrl_ops vivid_loop_cap_ctrl_ops = {
898 .s_ctrl = vivid_loop_cap_s_ctrl,
899 };
900
901 static const struct v4l2_ctrl_config vivid_ctrl_loop_video = {
902 .ops = &vivid_loop_cap_ctrl_ops,
903 .id = VIVID_CID_LOOP_VIDEO,
904 .name = "Loop Video",
905 .type = V4L2_CTRL_TYPE_BOOLEAN,
906 .max = 1,
907 .step = 1,
908 };
909
910
911 /* VBI Capture Control */
912
vivid_vbi_cap_s_ctrl(struct v4l2_ctrl * ctrl)913 static int vivid_vbi_cap_s_ctrl(struct v4l2_ctrl *ctrl)
914 {
915 struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_vbi_cap);
916
917 switch (ctrl->id) {
918 case VIVID_CID_VBI_CAP_INTERLACED:
919 dev->vbi_cap_interlaced = ctrl->val;
920 break;
921 }
922 return 0;
923 }
924
925 static const struct v4l2_ctrl_ops vivid_vbi_cap_ctrl_ops = {
926 .s_ctrl = vivid_vbi_cap_s_ctrl,
927 };
928
929 static const struct v4l2_ctrl_config vivid_ctrl_vbi_cap_interlaced = {
930 .ops = &vivid_vbi_cap_ctrl_ops,
931 .id = VIVID_CID_VBI_CAP_INTERLACED,
932 .name = "Interlaced VBI Format",
933 .type = V4L2_CTRL_TYPE_BOOLEAN,
934 .max = 1,
935 .step = 1,
936 };
937
938
939 /* Video Output Controls */
940
vivid_vid_out_s_ctrl(struct v4l2_ctrl * ctrl)941 static int vivid_vid_out_s_ctrl(struct v4l2_ctrl *ctrl)
942 {
943 struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_vid_out);
944 struct v4l2_bt_timings *bt = &dev->dv_timings_out.bt;
945 u32 display_present = 0;
946 unsigned int i, j, bus_idx;
947
948 switch (ctrl->id) {
949 case VIVID_CID_HAS_CROP_OUT:
950 dev->has_crop_out = ctrl->val;
951 vivid_update_format_out(dev);
952 break;
953 case VIVID_CID_HAS_COMPOSE_OUT:
954 dev->has_compose_out = ctrl->val;
955 vivid_update_format_out(dev);
956 break;
957 case VIVID_CID_HAS_SCALER_OUT:
958 dev->has_scaler_out = ctrl->val;
959 vivid_update_format_out(dev);
960 break;
961 case V4L2_CID_DV_TX_MODE:
962 dev->dvi_d_out = ctrl->val == V4L2_DV_TX_MODE_DVI_D;
963 if (!vivid_is_hdmi_out(dev))
964 break;
965 if (!dev->dvi_d_out && (bt->flags & V4L2_DV_FL_IS_CE_VIDEO)) {
966 if (bt->width == 720 && bt->height <= 576)
967 dev->colorspace_out = V4L2_COLORSPACE_SMPTE170M;
968 else
969 dev->colorspace_out = V4L2_COLORSPACE_REC709;
970 dev->quantization_out = V4L2_QUANTIZATION_DEFAULT;
971 } else {
972 dev->colorspace_out = V4L2_COLORSPACE_SRGB;
973 dev->quantization_out = dev->dvi_d_out ?
974 V4L2_QUANTIZATION_LIM_RANGE :
975 V4L2_QUANTIZATION_DEFAULT;
976 }
977 if (dev->loop_video)
978 vivid_send_source_change(dev, HDMI);
979 break;
980 case VIVID_CID_DISPLAY_PRESENT:
981 if (dev->output_type[dev->output] != HDMI)
982 break;
983
984 dev->display_present[dev->output] = ctrl->val;
985 for (i = 0, j = 0; i < dev->num_outputs; i++)
986 if (dev->output_type[i] == HDMI)
987 display_present |=
988 dev->display_present[i] << j++;
989
990 __v4l2_ctrl_s_ctrl(dev->ctrl_tx_rxsense, display_present);
991
992 if (dev->edid_blocks) {
993 __v4l2_ctrl_s_ctrl(dev->ctrl_tx_edid_present,
994 display_present);
995 __v4l2_ctrl_s_ctrl(dev->ctrl_tx_hotplug,
996 display_present);
997 }
998
999 bus_idx = dev->cec_output2bus_map[dev->output];
1000 if (!dev->cec_tx_adap[bus_idx])
1001 break;
1002
1003 if (ctrl->val && dev->edid_blocks)
1004 cec_s_phys_addr(dev->cec_tx_adap[bus_idx],
1005 dev->cec_tx_adap[bus_idx]->phys_addr,
1006 false);
1007 else
1008 cec_phys_addr_invalidate(dev->cec_tx_adap[bus_idx]);
1009
1010 break;
1011 }
1012 return 0;
1013 }
1014
1015 static const struct v4l2_ctrl_ops vivid_vid_out_ctrl_ops = {
1016 .s_ctrl = vivid_vid_out_s_ctrl,
1017 };
1018
1019 static const struct v4l2_ctrl_config vivid_ctrl_has_crop_out = {
1020 .ops = &vivid_vid_out_ctrl_ops,
1021 .id = VIVID_CID_HAS_CROP_OUT,
1022 .name = "Enable Output Cropping",
1023 .type = V4L2_CTRL_TYPE_BOOLEAN,
1024 .max = 1,
1025 .def = 1,
1026 .step = 1,
1027 };
1028
1029 static const struct v4l2_ctrl_config vivid_ctrl_has_compose_out = {
1030 .ops = &vivid_vid_out_ctrl_ops,
1031 .id = VIVID_CID_HAS_COMPOSE_OUT,
1032 .name = "Enable Output Composing",
1033 .type = V4L2_CTRL_TYPE_BOOLEAN,
1034 .max = 1,
1035 .def = 1,
1036 .step = 1,
1037 };
1038
1039 static const struct v4l2_ctrl_config vivid_ctrl_has_scaler_out = {
1040 .ops = &vivid_vid_out_ctrl_ops,
1041 .id = VIVID_CID_HAS_SCALER_OUT,
1042 .name = "Enable Output Scaler",
1043 .type = V4L2_CTRL_TYPE_BOOLEAN,
1044 .max = 1,
1045 .def = 1,
1046 .step = 1,
1047 };
1048
1049 static const struct v4l2_ctrl_config vivid_ctrl_display_present = {
1050 .ops = &vivid_vid_out_ctrl_ops,
1051 .id = VIVID_CID_DISPLAY_PRESENT,
1052 .name = "Display Present",
1053 .type = V4L2_CTRL_TYPE_BOOLEAN,
1054 .max = 1,
1055 .def = 1,
1056 .step = 1,
1057 };
1058
1059 /* Streaming Controls */
1060
vivid_streaming_s_ctrl(struct v4l2_ctrl * ctrl)1061 static int vivid_streaming_s_ctrl(struct v4l2_ctrl *ctrl)
1062 {
1063 struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_streaming);
1064 u64 rem;
1065
1066 switch (ctrl->id) {
1067 case VIVID_CID_DQBUF_ERROR:
1068 dev->dqbuf_error = true;
1069 break;
1070 case VIVID_CID_PERC_DROPPED:
1071 dev->perc_dropped_buffers = ctrl->val;
1072 break;
1073 case VIVID_CID_QUEUE_SETUP_ERROR:
1074 dev->queue_setup_error = true;
1075 break;
1076 case VIVID_CID_BUF_PREPARE_ERROR:
1077 dev->buf_prepare_error = true;
1078 break;
1079 case VIVID_CID_START_STR_ERROR:
1080 dev->start_streaming_error = true;
1081 break;
1082 case VIVID_CID_REQ_VALIDATE_ERROR:
1083 dev->req_validate_error = true;
1084 break;
1085 case VIVID_CID_QUEUE_ERROR:
1086 if (vb2_start_streaming_called(&dev->vb_vid_cap_q))
1087 vb2_queue_error(&dev->vb_vid_cap_q);
1088 if (vb2_start_streaming_called(&dev->vb_vbi_cap_q))
1089 vb2_queue_error(&dev->vb_vbi_cap_q);
1090 if (vb2_start_streaming_called(&dev->vb_vid_out_q))
1091 vb2_queue_error(&dev->vb_vid_out_q);
1092 if (vb2_start_streaming_called(&dev->vb_vbi_out_q))
1093 vb2_queue_error(&dev->vb_vbi_out_q);
1094 if (vb2_start_streaming_called(&dev->vb_sdr_cap_q))
1095 vb2_queue_error(&dev->vb_sdr_cap_q);
1096 break;
1097 case VIVID_CID_SEQ_WRAP:
1098 dev->seq_wrap = ctrl->val;
1099 break;
1100 case VIVID_CID_TIME_WRAP:
1101 dev->time_wrap = ctrl->val;
1102 if (ctrl->val == 0) {
1103 dev->time_wrap_offset = 0;
1104 break;
1105 }
1106 /*
1107 * We want to set the time 16 seconds before the 32 bit tv_sec
1108 * value of struct timeval would wrap around. So first we
1109 * calculate ktime_get_ns() % ((1 << 32) * NSEC_PER_SEC), and
1110 * then we set the offset to ((1 << 32) - 16) * NSEC_PER_SEC).
1111 */
1112 div64_u64_rem(ktime_get_ns(),
1113 0x100000000ULL * NSEC_PER_SEC, &rem);
1114 dev->time_wrap_offset =
1115 (0x100000000ULL - 16) * NSEC_PER_SEC - rem;
1116 break;
1117 }
1118 return 0;
1119 }
1120
1121 static const struct v4l2_ctrl_ops vivid_streaming_ctrl_ops = {
1122 .s_ctrl = vivid_streaming_s_ctrl,
1123 };
1124
1125 static const struct v4l2_ctrl_config vivid_ctrl_dqbuf_error = {
1126 .ops = &vivid_streaming_ctrl_ops,
1127 .id = VIVID_CID_DQBUF_ERROR,
1128 .name = "Inject V4L2_BUF_FLAG_ERROR",
1129 .type = V4L2_CTRL_TYPE_BUTTON,
1130 };
1131
1132 static const struct v4l2_ctrl_config vivid_ctrl_perc_dropped = {
1133 .ops = &vivid_streaming_ctrl_ops,
1134 .id = VIVID_CID_PERC_DROPPED,
1135 .name = "Percentage of Dropped Buffers",
1136 .type = V4L2_CTRL_TYPE_INTEGER,
1137 .min = 0,
1138 .max = 100,
1139 .step = 1,
1140 };
1141
1142 static const struct v4l2_ctrl_config vivid_ctrl_queue_setup_error = {
1143 .ops = &vivid_streaming_ctrl_ops,
1144 .id = VIVID_CID_QUEUE_SETUP_ERROR,
1145 .name = "Inject VIDIOC_REQBUFS Error",
1146 .type = V4L2_CTRL_TYPE_BUTTON,
1147 };
1148
1149 static const struct v4l2_ctrl_config vivid_ctrl_buf_prepare_error = {
1150 .ops = &vivid_streaming_ctrl_ops,
1151 .id = VIVID_CID_BUF_PREPARE_ERROR,
1152 .name = "Inject VIDIOC_QBUF Error",
1153 .type = V4L2_CTRL_TYPE_BUTTON,
1154 };
1155
1156 static const struct v4l2_ctrl_config vivid_ctrl_start_streaming_error = {
1157 .ops = &vivid_streaming_ctrl_ops,
1158 .id = VIVID_CID_START_STR_ERROR,
1159 .name = "Inject VIDIOC_STREAMON Error",
1160 .type = V4L2_CTRL_TYPE_BUTTON,
1161 };
1162
1163 static const struct v4l2_ctrl_config vivid_ctrl_queue_error = {
1164 .ops = &vivid_streaming_ctrl_ops,
1165 .id = VIVID_CID_QUEUE_ERROR,
1166 .name = "Inject Fatal Streaming Error",
1167 .type = V4L2_CTRL_TYPE_BUTTON,
1168 };
1169
1170 #ifdef CONFIG_MEDIA_CONTROLLER
1171 static const struct v4l2_ctrl_config vivid_ctrl_req_validate_error = {
1172 .ops = &vivid_streaming_ctrl_ops,
1173 .id = VIVID_CID_REQ_VALIDATE_ERROR,
1174 .name = "Inject req_validate() Error",
1175 .type = V4L2_CTRL_TYPE_BUTTON,
1176 };
1177 #endif
1178
1179 static const struct v4l2_ctrl_config vivid_ctrl_seq_wrap = {
1180 .ops = &vivid_streaming_ctrl_ops,
1181 .id = VIVID_CID_SEQ_WRAP,
1182 .name = "Wrap Sequence Number",
1183 .type = V4L2_CTRL_TYPE_BOOLEAN,
1184 .max = 1,
1185 .step = 1,
1186 };
1187
1188 static const struct v4l2_ctrl_config vivid_ctrl_time_wrap = {
1189 .ops = &vivid_streaming_ctrl_ops,
1190 .id = VIVID_CID_TIME_WRAP,
1191 .name = "Wrap Timestamp",
1192 .type = V4L2_CTRL_TYPE_BOOLEAN,
1193 .max = 1,
1194 .step = 1,
1195 };
1196
1197
1198 /* SDTV Capture Controls */
1199
vivid_sdtv_cap_s_ctrl(struct v4l2_ctrl * ctrl)1200 static int vivid_sdtv_cap_s_ctrl(struct v4l2_ctrl *ctrl)
1201 {
1202 struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_sdtv_cap);
1203
1204 switch (ctrl->id) {
1205 case VIVID_CID_STD_SIGNAL_MODE:
1206 dev->std_signal_mode[dev->input] =
1207 dev->ctrl_std_signal_mode->val;
1208 if (dev->std_signal_mode[dev->input] == SELECTED_STD)
1209 dev->query_std[dev->input] =
1210 vivid_standard[dev->ctrl_standard->val];
1211 v4l2_ctrl_activate(dev->ctrl_standard,
1212 dev->std_signal_mode[dev->input] ==
1213 SELECTED_STD);
1214 vivid_update_quality(dev);
1215 vivid_send_source_change(dev, TV);
1216 vivid_send_source_change(dev, SVID);
1217 break;
1218 }
1219 return 0;
1220 }
1221
1222 static const struct v4l2_ctrl_ops vivid_sdtv_cap_ctrl_ops = {
1223 .s_ctrl = vivid_sdtv_cap_s_ctrl,
1224 };
1225
1226 static const char * const vivid_ctrl_std_signal_mode_strings[] = {
1227 "Current Standard",
1228 "No Signal",
1229 "No Lock",
1230 "",
1231 "Selected Standard",
1232 "Cycle Through All Standards",
1233 NULL,
1234 };
1235
1236 static const struct v4l2_ctrl_config vivid_ctrl_std_signal_mode = {
1237 .ops = &vivid_sdtv_cap_ctrl_ops,
1238 .id = VIVID_CID_STD_SIGNAL_MODE,
1239 .name = "Standard Signal Mode",
1240 .type = V4L2_CTRL_TYPE_MENU,
1241 .max = ARRAY_SIZE(vivid_ctrl_std_signal_mode_strings) - 2,
1242 .menu_skip_mask = 1 << 3,
1243 .qmenu = vivid_ctrl_std_signal_mode_strings,
1244 };
1245
1246 static const struct v4l2_ctrl_config vivid_ctrl_standard = {
1247 .ops = &vivid_sdtv_cap_ctrl_ops,
1248 .id = VIVID_CID_STANDARD,
1249 .name = "Standard",
1250 .type = V4L2_CTRL_TYPE_MENU,
1251 .max = 14,
1252 .qmenu = vivid_ctrl_standard_strings,
1253 };
1254
1255
1256
1257 /* Radio Receiver Controls */
1258
vivid_radio_rx_s_ctrl(struct v4l2_ctrl * ctrl)1259 static int vivid_radio_rx_s_ctrl(struct v4l2_ctrl *ctrl)
1260 {
1261 struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_radio_rx);
1262
1263 switch (ctrl->id) {
1264 case VIVID_CID_RADIO_SEEK_MODE:
1265 dev->radio_rx_hw_seek_mode = ctrl->val;
1266 break;
1267 case VIVID_CID_RADIO_SEEK_PROG_LIM:
1268 dev->radio_rx_hw_seek_prog_lim = ctrl->val;
1269 break;
1270 case VIVID_CID_RADIO_RX_RDS_RBDS:
1271 dev->rds_gen.use_rbds = ctrl->val;
1272 break;
1273 case VIVID_CID_RADIO_RX_RDS_BLOCKIO:
1274 dev->radio_rx_rds_controls = ctrl->val;
1275 dev->radio_rx_caps &= ~V4L2_CAP_READWRITE;
1276 dev->radio_rx_rds_use_alternates = false;
1277 if (!dev->radio_rx_rds_controls) {
1278 dev->radio_rx_caps |= V4L2_CAP_READWRITE;
1279 __v4l2_ctrl_s_ctrl(dev->radio_rx_rds_pty, 0);
1280 __v4l2_ctrl_s_ctrl(dev->radio_rx_rds_ta, 0);
1281 __v4l2_ctrl_s_ctrl(dev->radio_rx_rds_tp, 0);
1282 __v4l2_ctrl_s_ctrl(dev->radio_rx_rds_ms, 0);
1283 __v4l2_ctrl_s_ctrl_string(dev->radio_rx_rds_psname, "");
1284 __v4l2_ctrl_s_ctrl_string(dev->radio_rx_rds_radiotext, "");
1285 }
1286 v4l2_ctrl_activate(dev->radio_rx_rds_pty, dev->radio_rx_rds_controls);
1287 v4l2_ctrl_activate(dev->radio_rx_rds_psname, dev->radio_rx_rds_controls);
1288 v4l2_ctrl_activate(dev->radio_rx_rds_radiotext, dev->radio_rx_rds_controls);
1289 v4l2_ctrl_activate(dev->radio_rx_rds_ta, dev->radio_rx_rds_controls);
1290 v4l2_ctrl_activate(dev->radio_rx_rds_tp, dev->radio_rx_rds_controls);
1291 v4l2_ctrl_activate(dev->radio_rx_rds_ms, dev->radio_rx_rds_controls);
1292 dev->radio_rx_dev.device_caps = dev->radio_rx_caps;
1293 break;
1294 case V4L2_CID_RDS_RECEPTION:
1295 dev->radio_rx_rds_enabled = ctrl->val;
1296 break;
1297 }
1298 return 0;
1299 }
1300
1301 static const struct v4l2_ctrl_ops vivid_radio_rx_ctrl_ops = {
1302 .s_ctrl = vivid_radio_rx_s_ctrl,
1303 };
1304
1305 static const char * const vivid_ctrl_radio_rds_mode_strings[] = {
1306 "Block I/O",
1307 "Controls",
1308 NULL,
1309 };
1310
1311 static const struct v4l2_ctrl_config vivid_ctrl_radio_rx_rds_blockio = {
1312 .ops = &vivid_radio_rx_ctrl_ops,
1313 .id = VIVID_CID_RADIO_RX_RDS_BLOCKIO,
1314 .name = "RDS Rx I/O Mode",
1315 .type = V4L2_CTRL_TYPE_MENU,
1316 .qmenu = vivid_ctrl_radio_rds_mode_strings,
1317 .max = 1,
1318 };
1319
1320 static const struct v4l2_ctrl_config vivid_ctrl_radio_rx_rds_rbds = {
1321 .ops = &vivid_radio_rx_ctrl_ops,
1322 .id = VIVID_CID_RADIO_RX_RDS_RBDS,
1323 .name = "Generate RBDS Instead of RDS",
1324 .type = V4L2_CTRL_TYPE_BOOLEAN,
1325 .max = 1,
1326 .step = 1,
1327 };
1328
1329 static const char * const vivid_ctrl_radio_hw_seek_mode_strings[] = {
1330 "Bounded",
1331 "Wrap Around",
1332 "Both",
1333 NULL,
1334 };
1335
1336 static const struct v4l2_ctrl_config vivid_ctrl_radio_hw_seek_mode = {
1337 .ops = &vivid_radio_rx_ctrl_ops,
1338 .id = VIVID_CID_RADIO_SEEK_MODE,
1339 .name = "Radio HW Seek Mode",
1340 .type = V4L2_CTRL_TYPE_MENU,
1341 .max = 2,
1342 .qmenu = vivid_ctrl_radio_hw_seek_mode_strings,
1343 };
1344
1345 static const struct v4l2_ctrl_config vivid_ctrl_radio_hw_seek_prog_lim = {
1346 .ops = &vivid_radio_rx_ctrl_ops,
1347 .id = VIVID_CID_RADIO_SEEK_PROG_LIM,
1348 .name = "Radio Programmable HW Seek",
1349 .type = V4L2_CTRL_TYPE_BOOLEAN,
1350 .max = 1,
1351 .step = 1,
1352 };
1353
1354
1355 /* Radio Transmitter Controls */
1356
vivid_radio_tx_s_ctrl(struct v4l2_ctrl * ctrl)1357 static int vivid_radio_tx_s_ctrl(struct v4l2_ctrl *ctrl)
1358 {
1359 struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_radio_tx);
1360
1361 switch (ctrl->id) {
1362 case VIVID_CID_RADIO_TX_RDS_BLOCKIO:
1363 dev->radio_tx_rds_controls = ctrl->val;
1364 dev->radio_tx_caps &= ~V4L2_CAP_READWRITE;
1365 if (!dev->radio_tx_rds_controls)
1366 dev->radio_tx_caps |= V4L2_CAP_READWRITE;
1367 dev->radio_tx_dev.device_caps = dev->radio_tx_caps;
1368 break;
1369 case V4L2_CID_RDS_TX_PTY:
1370 if (dev->radio_rx_rds_controls)
1371 v4l2_ctrl_s_ctrl(dev->radio_rx_rds_pty, ctrl->val);
1372 break;
1373 case V4L2_CID_RDS_TX_PS_NAME:
1374 if (dev->radio_rx_rds_controls)
1375 v4l2_ctrl_s_ctrl_string(dev->radio_rx_rds_psname, ctrl->p_new.p_char);
1376 break;
1377 case V4L2_CID_RDS_TX_RADIO_TEXT:
1378 if (dev->radio_rx_rds_controls)
1379 v4l2_ctrl_s_ctrl_string(dev->radio_rx_rds_radiotext, ctrl->p_new.p_char);
1380 break;
1381 case V4L2_CID_RDS_TX_TRAFFIC_ANNOUNCEMENT:
1382 if (dev->radio_rx_rds_controls)
1383 v4l2_ctrl_s_ctrl(dev->radio_rx_rds_ta, ctrl->val);
1384 break;
1385 case V4L2_CID_RDS_TX_TRAFFIC_PROGRAM:
1386 if (dev->radio_rx_rds_controls)
1387 v4l2_ctrl_s_ctrl(dev->radio_rx_rds_tp, ctrl->val);
1388 break;
1389 case V4L2_CID_RDS_TX_MUSIC_SPEECH:
1390 if (dev->radio_rx_rds_controls)
1391 v4l2_ctrl_s_ctrl(dev->radio_rx_rds_ms, ctrl->val);
1392 break;
1393 }
1394 return 0;
1395 }
1396
1397 static const struct v4l2_ctrl_ops vivid_radio_tx_ctrl_ops = {
1398 .s_ctrl = vivid_radio_tx_s_ctrl,
1399 };
1400
1401 static const struct v4l2_ctrl_config vivid_ctrl_radio_tx_rds_blockio = {
1402 .ops = &vivid_radio_tx_ctrl_ops,
1403 .id = VIVID_CID_RADIO_TX_RDS_BLOCKIO,
1404 .name = "RDS Tx I/O Mode",
1405 .type = V4L2_CTRL_TYPE_MENU,
1406 .qmenu = vivid_ctrl_radio_rds_mode_strings,
1407 .max = 1,
1408 .def = 1,
1409 };
1410
1411
1412 /* SDR Capture Controls */
1413
vivid_sdr_cap_s_ctrl(struct v4l2_ctrl * ctrl)1414 static int vivid_sdr_cap_s_ctrl(struct v4l2_ctrl *ctrl)
1415 {
1416 struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_sdr_cap);
1417
1418 switch (ctrl->id) {
1419 case VIVID_CID_SDR_CAP_FM_DEVIATION:
1420 dev->sdr_fm_deviation = ctrl->val;
1421 break;
1422 }
1423 return 0;
1424 }
1425
1426 static const struct v4l2_ctrl_ops vivid_sdr_cap_ctrl_ops = {
1427 .s_ctrl = vivid_sdr_cap_s_ctrl,
1428 };
1429
1430 static const struct v4l2_ctrl_config vivid_ctrl_sdr_cap_fm_deviation = {
1431 .ops = &vivid_sdr_cap_ctrl_ops,
1432 .id = VIVID_CID_SDR_CAP_FM_DEVIATION,
1433 .name = "FM Deviation",
1434 .type = V4L2_CTRL_TYPE_INTEGER,
1435 .min = 100,
1436 .max = 200000,
1437 .def = 75000,
1438 .step = 1,
1439 };
1440
1441 /* Metadata Capture Control */
1442
vivid_meta_cap_s_ctrl(struct v4l2_ctrl * ctrl)1443 static int vivid_meta_cap_s_ctrl(struct v4l2_ctrl *ctrl)
1444 {
1445 struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev,
1446 ctrl_hdl_meta_cap);
1447
1448 switch (ctrl->id) {
1449 case VIVID_CID_META_CAP_GENERATE_PTS:
1450 dev->meta_pts = ctrl->val;
1451 break;
1452 case VIVID_CID_META_CAP_GENERATE_SCR:
1453 dev->meta_scr = ctrl->val;
1454 break;
1455 }
1456 return 0;
1457 }
1458
1459 static const struct v4l2_ctrl_ops vivid_meta_cap_ctrl_ops = {
1460 .s_ctrl = vivid_meta_cap_s_ctrl,
1461 };
1462
1463 static const struct v4l2_ctrl_config vivid_ctrl_meta_has_pts = {
1464 .ops = &vivid_meta_cap_ctrl_ops,
1465 .id = VIVID_CID_META_CAP_GENERATE_PTS,
1466 .name = "Generate PTS",
1467 .type = V4L2_CTRL_TYPE_BOOLEAN,
1468 .max = 1,
1469 .def = 1,
1470 .step = 1,
1471 };
1472
1473 static const struct v4l2_ctrl_config vivid_ctrl_meta_has_src_clk = {
1474 .ops = &vivid_meta_cap_ctrl_ops,
1475 .id = VIVID_CID_META_CAP_GENERATE_SCR,
1476 .name = "Generate SCR",
1477 .type = V4L2_CTRL_TYPE_BOOLEAN,
1478 .max = 1,
1479 .def = 1,
1480 .step = 1,
1481 };
1482
1483 static const struct v4l2_ctrl_config vivid_ctrl_class = {
1484 .ops = &vivid_user_gen_ctrl_ops,
1485 .flags = V4L2_CTRL_FLAG_READ_ONLY | V4L2_CTRL_FLAG_WRITE_ONLY,
1486 .id = VIVID_CID_VIVID_CLASS,
1487 .name = "Vivid Controls",
1488 .type = V4L2_CTRL_TYPE_CTRL_CLASS,
1489 };
1490
vivid_create_controls(struct vivid_dev * dev,bool show_ccs_cap,bool show_ccs_out,bool no_error_inj,bool has_sdtv,bool has_hdmi)1491 int vivid_create_controls(struct vivid_dev *dev, bool show_ccs_cap,
1492 bool show_ccs_out, bool no_error_inj,
1493 bool has_sdtv, bool has_hdmi)
1494 {
1495 struct v4l2_ctrl_handler *hdl_user_gen = &dev->ctrl_hdl_user_gen;
1496 struct v4l2_ctrl_handler *hdl_user_vid = &dev->ctrl_hdl_user_vid;
1497 struct v4l2_ctrl_handler *hdl_user_aud = &dev->ctrl_hdl_user_aud;
1498 struct v4l2_ctrl_handler *hdl_streaming = &dev->ctrl_hdl_streaming;
1499 struct v4l2_ctrl_handler *hdl_sdtv_cap = &dev->ctrl_hdl_sdtv_cap;
1500 struct v4l2_ctrl_handler *hdl_loop_cap = &dev->ctrl_hdl_loop_cap;
1501 struct v4l2_ctrl_handler *hdl_fb = &dev->ctrl_hdl_fb;
1502 struct v4l2_ctrl_handler *hdl_vid_cap = &dev->ctrl_hdl_vid_cap;
1503 struct v4l2_ctrl_handler *hdl_vid_out = &dev->ctrl_hdl_vid_out;
1504 struct v4l2_ctrl_handler *hdl_vbi_cap = &dev->ctrl_hdl_vbi_cap;
1505 struct v4l2_ctrl_handler *hdl_vbi_out = &dev->ctrl_hdl_vbi_out;
1506 struct v4l2_ctrl_handler *hdl_radio_rx = &dev->ctrl_hdl_radio_rx;
1507 struct v4l2_ctrl_handler *hdl_radio_tx = &dev->ctrl_hdl_radio_tx;
1508 struct v4l2_ctrl_handler *hdl_sdr_cap = &dev->ctrl_hdl_sdr_cap;
1509 struct v4l2_ctrl_handler *hdl_meta_cap = &dev->ctrl_hdl_meta_cap;
1510 struct v4l2_ctrl_handler *hdl_meta_out = &dev->ctrl_hdl_meta_out;
1511 struct v4l2_ctrl_handler *hdl_tch_cap = &dev->ctrl_hdl_touch_cap;
1512
1513 struct v4l2_ctrl_config vivid_ctrl_dv_timings = {
1514 .ops = &vivid_vid_cap_ctrl_ops,
1515 .id = VIVID_CID_DV_TIMINGS,
1516 .name = "DV Timings",
1517 .type = V4L2_CTRL_TYPE_MENU,
1518 };
1519 int i;
1520
1521 v4l2_ctrl_handler_init(hdl_user_gen, 10);
1522 v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_class, NULL);
1523 v4l2_ctrl_handler_init(hdl_user_vid, 9);
1524 v4l2_ctrl_new_custom(hdl_user_vid, &vivid_ctrl_class, NULL);
1525 v4l2_ctrl_handler_init(hdl_user_aud, 2);
1526 v4l2_ctrl_new_custom(hdl_user_aud, &vivid_ctrl_class, NULL);
1527 v4l2_ctrl_handler_init(hdl_streaming, 8);
1528 v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_class, NULL);
1529 v4l2_ctrl_handler_init(hdl_sdtv_cap, 2);
1530 v4l2_ctrl_new_custom(hdl_sdtv_cap, &vivid_ctrl_class, NULL);
1531 v4l2_ctrl_handler_init(hdl_loop_cap, 1);
1532 v4l2_ctrl_new_custom(hdl_loop_cap, &vivid_ctrl_class, NULL);
1533 v4l2_ctrl_handler_init(hdl_fb, 1);
1534 v4l2_ctrl_new_custom(hdl_fb, &vivid_ctrl_class, NULL);
1535 v4l2_ctrl_handler_init(hdl_vid_cap, 55);
1536 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_class, NULL);
1537 v4l2_ctrl_handler_init(hdl_vid_out, 26);
1538 if (!no_error_inj || dev->has_fb || dev->num_hdmi_outputs)
1539 v4l2_ctrl_new_custom(hdl_vid_out, &vivid_ctrl_class, NULL);
1540 v4l2_ctrl_handler_init(hdl_vbi_cap, 21);
1541 v4l2_ctrl_new_custom(hdl_vbi_cap, &vivid_ctrl_class, NULL);
1542 v4l2_ctrl_handler_init(hdl_vbi_out, 19);
1543 if (!no_error_inj)
1544 v4l2_ctrl_new_custom(hdl_vbi_out, &vivid_ctrl_class, NULL);
1545 v4l2_ctrl_handler_init(hdl_radio_rx, 17);
1546 v4l2_ctrl_new_custom(hdl_radio_rx, &vivid_ctrl_class, NULL);
1547 v4l2_ctrl_handler_init(hdl_radio_tx, 17);
1548 v4l2_ctrl_new_custom(hdl_radio_tx, &vivid_ctrl_class, NULL);
1549 v4l2_ctrl_handler_init(hdl_sdr_cap, 19);
1550 v4l2_ctrl_new_custom(hdl_sdr_cap, &vivid_ctrl_class, NULL);
1551 v4l2_ctrl_handler_init(hdl_meta_cap, 2);
1552 v4l2_ctrl_new_custom(hdl_meta_cap, &vivid_ctrl_class, NULL);
1553 v4l2_ctrl_handler_init(hdl_meta_out, 2);
1554 v4l2_ctrl_new_custom(hdl_meta_out, &vivid_ctrl_class, NULL);
1555 v4l2_ctrl_handler_init(hdl_tch_cap, 2);
1556 v4l2_ctrl_new_custom(hdl_tch_cap, &vivid_ctrl_class, NULL);
1557
1558 /* User Controls */
1559 dev->volume = v4l2_ctrl_new_std(hdl_user_aud, NULL,
1560 V4L2_CID_AUDIO_VOLUME, 0, 255, 1, 200);
1561 dev->mute = v4l2_ctrl_new_std(hdl_user_aud, NULL,
1562 V4L2_CID_AUDIO_MUTE, 0, 1, 1, 0);
1563 if (dev->has_vid_cap) {
1564 dev->brightness = v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops,
1565 V4L2_CID_BRIGHTNESS, 0, 255, 1, 128);
1566 for (i = 0; i < MAX_INPUTS; i++)
1567 dev->input_brightness[i] = 128;
1568 dev->contrast = v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops,
1569 V4L2_CID_CONTRAST, 0, 255, 1, 128);
1570 dev->saturation = v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops,
1571 V4L2_CID_SATURATION, 0, 255, 1, 128);
1572 dev->hue = v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops,
1573 V4L2_CID_HUE, -128, 128, 1, 0);
1574 v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops,
1575 V4L2_CID_HFLIP, 0, 1, 1, 0);
1576 v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops,
1577 V4L2_CID_VFLIP, 0, 1, 1, 0);
1578 dev->autogain = v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops,
1579 V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
1580 dev->gain = v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops,
1581 V4L2_CID_GAIN, 0, 255, 1, 100);
1582 dev->alpha = v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops,
1583 V4L2_CID_ALPHA_COMPONENT, 0, 255, 1, 0);
1584 }
1585 dev->button = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_button, NULL);
1586 dev->int32 = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_int32, NULL);
1587 dev->int64 = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_int64, NULL);
1588 dev->boolean = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_boolean, NULL);
1589 dev->menu = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_menu, NULL);
1590 dev->string = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_string, NULL);
1591 dev->bitmask = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_bitmask, NULL);
1592 dev->int_menu = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_int_menu, NULL);
1593 v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_area, NULL);
1594 v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_u32_array, NULL);
1595 v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_u16_matrix, NULL);
1596 v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_u8_4d_array, NULL);
1597
1598 if (dev->has_vid_cap) {
1599 /* Image Processing Controls */
1600 struct v4l2_ctrl_config vivid_ctrl_test_pattern = {
1601 .ops = &vivid_vid_cap_ctrl_ops,
1602 .id = VIVID_CID_TEST_PATTERN,
1603 .name = "Test Pattern",
1604 .type = V4L2_CTRL_TYPE_MENU,
1605 .max = TPG_PAT_NOISE,
1606 .qmenu = tpg_pattern_strings,
1607 };
1608
1609 dev->test_pattern = v4l2_ctrl_new_custom(hdl_vid_cap,
1610 &vivid_ctrl_test_pattern, NULL);
1611 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_perc_fill, NULL);
1612 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_hor_movement, NULL);
1613 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_vert_movement, NULL);
1614 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_osd_mode, NULL);
1615 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_show_border, NULL);
1616 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_show_square, NULL);
1617 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_hflip, NULL);
1618 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_vflip, NULL);
1619 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_insert_sav, NULL);
1620 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_insert_eav, NULL);
1621 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_reduced_fps, NULL);
1622 if (show_ccs_cap) {
1623 dev->ctrl_has_crop_cap = v4l2_ctrl_new_custom(hdl_vid_cap,
1624 &vivid_ctrl_has_crop_cap, NULL);
1625 dev->ctrl_has_compose_cap = v4l2_ctrl_new_custom(hdl_vid_cap,
1626 &vivid_ctrl_has_compose_cap, NULL);
1627 dev->ctrl_has_scaler_cap = v4l2_ctrl_new_custom(hdl_vid_cap,
1628 &vivid_ctrl_has_scaler_cap, NULL);
1629 }
1630
1631 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_tstamp_src, NULL);
1632 dev->colorspace = v4l2_ctrl_new_custom(hdl_vid_cap,
1633 &vivid_ctrl_colorspace, NULL);
1634 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_xfer_func, NULL);
1635 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_ycbcr_enc, NULL);
1636 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_hsv_enc, NULL);
1637 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_quantization, NULL);
1638 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_alpha_mode, NULL);
1639 }
1640
1641 if (dev->has_vid_out && show_ccs_out) {
1642 dev->ctrl_has_crop_out = v4l2_ctrl_new_custom(hdl_vid_out,
1643 &vivid_ctrl_has_crop_out, NULL);
1644 dev->ctrl_has_compose_out = v4l2_ctrl_new_custom(hdl_vid_out,
1645 &vivid_ctrl_has_compose_out, NULL);
1646 dev->ctrl_has_scaler_out = v4l2_ctrl_new_custom(hdl_vid_out,
1647 &vivid_ctrl_has_scaler_out, NULL);
1648 }
1649
1650 /*
1651 * Testing this driver with v4l2-compliance will trigger the error
1652 * injection controls, and after that nothing will work as expected.
1653 * So we have a module option to drop these error injecting controls
1654 * allowing us to run v4l2_compliance again.
1655 */
1656 if (!no_error_inj) {
1657 v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_disconnect, NULL);
1658 v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_dqbuf_error, NULL);
1659 v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_perc_dropped, NULL);
1660 v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_queue_setup_error, NULL);
1661 v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_buf_prepare_error, NULL);
1662 v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_start_streaming_error, NULL);
1663 v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_queue_error, NULL);
1664 #ifdef CONFIG_MEDIA_CONTROLLER
1665 v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_req_validate_error, NULL);
1666 #endif
1667 v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_seq_wrap, NULL);
1668 v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_time_wrap, NULL);
1669 }
1670
1671 if (has_sdtv && (dev->has_vid_cap || dev->has_vbi_cap)) {
1672 if (dev->has_vid_cap)
1673 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_std_aspect_ratio, NULL);
1674 dev->ctrl_std_signal_mode = v4l2_ctrl_new_custom(hdl_sdtv_cap,
1675 &vivid_ctrl_std_signal_mode, NULL);
1676 dev->ctrl_standard = v4l2_ctrl_new_custom(hdl_sdtv_cap,
1677 &vivid_ctrl_standard, NULL);
1678 if (dev->ctrl_std_signal_mode)
1679 v4l2_ctrl_cluster(2, &dev->ctrl_std_signal_mode);
1680 if (dev->has_raw_vbi_cap)
1681 v4l2_ctrl_new_custom(hdl_vbi_cap, &vivid_ctrl_vbi_cap_interlaced, NULL);
1682 }
1683
1684 if (dev->num_hdmi_inputs) {
1685 s64 hdmi_input_mask = GENMASK(dev->num_hdmi_inputs - 1, 0);
1686
1687 dev->ctrl_dv_timings_signal_mode = v4l2_ctrl_new_custom(hdl_vid_cap,
1688 &vivid_ctrl_dv_timings_signal_mode, NULL);
1689
1690 vivid_ctrl_dv_timings.max = dev->query_dv_timings_size - 1;
1691 vivid_ctrl_dv_timings.qmenu =
1692 (const char * const *)dev->query_dv_timings_qmenu;
1693 dev->ctrl_dv_timings = v4l2_ctrl_new_custom(hdl_vid_cap,
1694 &vivid_ctrl_dv_timings, NULL);
1695 if (dev->ctrl_dv_timings_signal_mode)
1696 v4l2_ctrl_cluster(2, &dev->ctrl_dv_timings_signal_mode);
1697
1698 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_dv_timings_aspect_ratio, NULL);
1699 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_max_edid_blocks, NULL);
1700 dev->real_rgb_range_cap = v4l2_ctrl_new_custom(hdl_vid_cap,
1701 &vivid_ctrl_limited_rgb_range, NULL);
1702 dev->rgb_range_cap = v4l2_ctrl_new_std_menu(hdl_vid_cap,
1703 &vivid_vid_cap_ctrl_ops,
1704 V4L2_CID_DV_RX_RGB_RANGE, V4L2_DV_RGB_RANGE_FULL,
1705 0, V4L2_DV_RGB_RANGE_AUTO);
1706 dev->ctrl_rx_power_present = v4l2_ctrl_new_std(hdl_vid_cap,
1707 NULL, V4L2_CID_DV_RX_POWER_PRESENT, 0, hdmi_input_mask,
1708 0, hdmi_input_mask);
1709
1710 }
1711 if (dev->num_hdmi_outputs) {
1712 s64 hdmi_output_mask = GENMASK(dev->num_hdmi_outputs - 1, 0);
1713
1714 /*
1715 * We aren't doing anything with this at the moment, but
1716 * HDMI outputs typically have this controls.
1717 */
1718 dev->ctrl_tx_rgb_range = v4l2_ctrl_new_std_menu(hdl_vid_out, NULL,
1719 V4L2_CID_DV_TX_RGB_RANGE, V4L2_DV_RGB_RANGE_FULL,
1720 0, V4L2_DV_RGB_RANGE_AUTO);
1721 dev->ctrl_tx_mode = v4l2_ctrl_new_std_menu(hdl_vid_out, NULL,
1722 V4L2_CID_DV_TX_MODE, V4L2_DV_TX_MODE_HDMI,
1723 0, V4L2_DV_TX_MODE_HDMI);
1724 dev->ctrl_display_present = v4l2_ctrl_new_custom(hdl_vid_out,
1725 &vivid_ctrl_display_present, NULL);
1726 dev->ctrl_tx_hotplug = v4l2_ctrl_new_std(hdl_vid_out,
1727 NULL, V4L2_CID_DV_TX_HOTPLUG, 0, hdmi_output_mask,
1728 0, hdmi_output_mask);
1729 dev->ctrl_tx_rxsense = v4l2_ctrl_new_std(hdl_vid_out,
1730 NULL, V4L2_CID_DV_TX_RXSENSE, 0, hdmi_output_mask,
1731 0, hdmi_output_mask);
1732 dev->ctrl_tx_edid_present = v4l2_ctrl_new_std(hdl_vid_out,
1733 NULL, V4L2_CID_DV_TX_EDID_PRESENT, 0, hdmi_output_mask,
1734 0, hdmi_output_mask);
1735 }
1736 if ((dev->has_vid_cap && dev->has_vid_out) ||
1737 (dev->has_vbi_cap && dev->has_vbi_out))
1738 v4l2_ctrl_new_custom(hdl_loop_cap, &vivid_ctrl_loop_video, NULL);
1739
1740 if (dev->has_fb)
1741 v4l2_ctrl_new_custom(hdl_fb, &vivid_ctrl_clear_fb, NULL);
1742
1743 if (dev->has_radio_rx) {
1744 v4l2_ctrl_new_custom(hdl_radio_rx, &vivid_ctrl_radio_hw_seek_mode, NULL);
1745 v4l2_ctrl_new_custom(hdl_radio_rx, &vivid_ctrl_radio_hw_seek_prog_lim, NULL);
1746 v4l2_ctrl_new_custom(hdl_radio_rx, &vivid_ctrl_radio_rx_rds_blockio, NULL);
1747 v4l2_ctrl_new_custom(hdl_radio_rx, &vivid_ctrl_radio_rx_rds_rbds, NULL);
1748 v4l2_ctrl_new_std(hdl_radio_rx, &vivid_radio_rx_ctrl_ops,
1749 V4L2_CID_RDS_RECEPTION, 0, 1, 1, 1);
1750 dev->radio_rx_rds_pty = v4l2_ctrl_new_std(hdl_radio_rx,
1751 &vivid_radio_rx_ctrl_ops,
1752 V4L2_CID_RDS_RX_PTY, 0, 31, 1, 0);
1753 dev->radio_rx_rds_psname = v4l2_ctrl_new_std(hdl_radio_rx,
1754 &vivid_radio_rx_ctrl_ops,
1755 V4L2_CID_RDS_RX_PS_NAME, 0, 8, 8, 0);
1756 dev->radio_rx_rds_radiotext = v4l2_ctrl_new_std(hdl_radio_rx,
1757 &vivid_radio_rx_ctrl_ops,
1758 V4L2_CID_RDS_RX_RADIO_TEXT, 0, 64, 64, 0);
1759 dev->radio_rx_rds_ta = v4l2_ctrl_new_std(hdl_radio_rx,
1760 &vivid_radio_rx_ctrl_ops,
1761 V4L2_CID_RDS_RX_TRAFFIC_ANNOUNCEMENT, 0, 1, 1, 0);
1762 dev->radio_rx_rds_tp = v4l2_ctrl_new_std(hdl_radio_rx,
1763 &vivid_radio_rx_ctrl_ops,
1764 V4L2_CID_RDS_RX_TRAFFIC_PROGRAM, 0, 1, 1, 0);
1765 dev->radio_rx_rds_ms = v4l2_ctrl_new_std(hdl_radio_rx,
1766 &vivid_radio_rx_ctrl_ops,
1767 V4L2_CID_RDS_RX_MUSIC_SPEECH, 0, 1, 1, 1);
1768 }
1769 if (dev->has_radio_tx) {
1770 v4l2_ctrl_new_custom(hdl_radio_tx,
1771 &vivid_ctrl_radio_tx_rds_blockio, NULL);
1772 dev->radio_tx_rds_pi = v4l2_ctrl_new_std(hdl_radio_tx,
1773 &vivid_radio_tx_ctrl_ops,
1774 V4L2_CID_RDS_TX_PI, 0, 0xffff, 1, 0x8088);
1775 dev->radio_tx_rds_pty = v4l2_ctrl_new_std(hdl_radio_tx,
1776 &vivid_radio_tx_ctrl_ops,
1777 V4L2_CID_RDS_TX_PTY, 0, 31, 1, 3);
1778 dev->radio_tx_rds_psname = v4l2_ctrl_new_std(hdl_radio_tx,
1779 &vivid_radio_tx_ctrl_ops,
1780 V4L2_CID_RDS_TX_PS_NAME, 0, 8, 8, 0);
1781 if (dev->radio_tx_rds_psname)
1782 v4l2_ctrl_s_ctrl_string(dev->radio_tx_rds_psname, "VIVID-TX");
1783 dev->radio_tx_rds_radiotext = v4l2_ctrl_new_std(hdl_radio_tx,
1784 &vivid_radio_tx_ctrl_ops,
1785 V4L2_CID_RDS_TX_RADIO_TEXT, 0, 64 * 2, 64, 0);
1786 if (dev->radio_tx_rds_radiotext)
1787 v4l2_ctrl_s_ctrl_string(dev->radio_tx_rds_radiotext,
1788 "This is a VIVID default Radio Text template text, change at will");
1789 dev->radio_tx_rds_mono_stereo = v4l2_ctrl_new_std(hdl_radio_tx,
1790 &vivid_radio_tx_ctrl_ops,
1791 V4L2_CID_RDS_TX_MONO_STEREO, 0, 1, 1, 1);
1792 dev->radio_tx_rds_art_head = v4l2_ctrl_new_std(hdl_radio_tx,
1793 &vivid_radio_tx_ctrl_ops,
1794 V4L2_CID_RDS_TX_ARTIFICIAL_HEAD, 0, 1, 1, 0);
1795 dev->radio_tx_rds_compressed = v4l2_ctrl_new_std(hdl_radio_tx,
1796 &vivid_radio_tx_ctrl_ops,
1797 V4L2_CID_RDS_TX_COMPRESSED, 0, 1, 1, 0);
1798 dev->radio_tx_rds_dyn_pty = v4l2_ctrl_new_std(hdl_radio_tx,
1799 &vivid_radio_tx_ctrl_ops,
1800 V4L2_CID_RDS_TX_DYNAMIC_PTY, 0, 1, 1, 0);
1801 dev->radio_tx_rds_ta = v4l2_ctrl_new_std(hdl_radio_tx,
1802 &vivid_radio_tx_ctrl_ops,
1803 V4L2_CID_RDS_TX_TRAFFIC_ANNOUNCEMENT, 0, 1, 1, 0);
1804 dev->radio_tx_rds_tp = v4l2_ctrl_new_std(hdl_radio_tx,
1805 &vivid_radio_tx_ctrl_ops,
1806 V4L2_CID_RDS_TX_TRAFFIC_PROGRAM, 0, 1, 1, 1);
1807 dev->radio_tx_rds_ms = v4l2_ctrl_new_std(hdl_radio_tx,
1808 &vivid_radio_tx_ctrl_ops,
1809 V4L2_CID_RDS_TX_MUSIC_SPEECH, 0, 1, 1, 1);
1810 }
1811 if (dev->has_sdr_cap) {
1812 v4l2_ctrl_new_custom(hdl_sdr_cap,
1813 &vivid_ctrl_sdr_cap_fm_deviation, NULL);
1814 }
1815 if (dev->has_meta_cap) {
1816 v4l2_ctrl_new_custom(hdl_meta_cap,
1817 &vivid_ctrl_meta_has_pts, NULL);
1818 v4l2_ctrl_new_custom(hdl_meta_cap,
1819 &vivid_ctrl_meta_has_src_clk, NULL);
1820 }
1821
1822 if (hdl_user_gen->error)
1823 return hdl_user_gen->error;
1824 if (hdl_user_vid->error)
1825 return hdl_user_vid->error;
1826 if (hdl_user_aud->error)
1827 return hdl_user_aud->error;
1828 if (hdl_streaming->error)
1829 return hdl_streaming->error;
1830 if (hdl_sdr_cap->error)
1831 return hdl_sdr_cap->error;
1832 if (hdl_loop_cap->error)
1833 return hdl_loop_cap->error;
1834
1835 if (dev->autogain)
1836 v4l2_ctrl_auto_cluster(2, &dev->autogain, 0, true);
1837
1838 if (dev->has_vid_cap) {
1839 v4l2_ctrl_add_handler(hdl_vid_cap, hdl_user_gen, NULL, false);
1840 v4l2_ctrl_add_handler(hdl_vid_cap, hdl_user_vid, NULL, false);
1841 v4l2_ctrl_add_handler(hdl_vid_cap, hdl_user_aud, NULL, false);
1842 v4l2_ctrl_add_handler(hdl_vid_cap, hdl_streaming, NULL, false);
1843 v4l2_ctrl_add_handler(hdl_vid_cap, hdl_sdtv_cap, NULL, false);
1844 v4l2_ctrl_add_handler(hdl_vid_cap, hdl_loop_cap, NULL, false);
1845 v4l2_ctrl_add_handler(hdl_vid_cap, hdl_fb, NULL, false);
1846 if (hdl_vid_cap->error)
1847 return hdl_vid_cap->error;
1848 dev->vid_cap_dev.ctrl_handler = hdl_vid_cap;
1849 }
1850 if (dev->has_vid_out) {
1851 v4l2_ctrl_add_handler(hdl_vid_out, hdl_user_gen, NULL, false);
1852 v4l2_ctrl_add_handler(hdl_vid_out, hdl_user_aud, NULL, false);
1853 v4l2_ctrl_add_handler(hdl_vid_out, hdl_streaming, NULL, false);
1854 v4l2_ctrl_add_handler(hdl_vid_out, hdl_fb, NULL, false);
1855 if (hdl_vid_out->error)
1856 return hdl_vid_out->error;
1857 dev->vid_out_dev.ctrl_handler = hdl_vid_out;
1858 }
1859 if (dev->has_vbi_cap) {
1860 v4l2_ctrl_add_handler(hdl_vbi_cap, hdl_user_gen, NULL, false);
1861 v4l2_ctrl_add_handler(hdl_vbi_cap, hdl_streaming, NULL, false);
1862 v4l2_ctrl_add_handler(hdl_vbi_cap, hdl_sdtv_cap, NULL, false);
1863 v4l2_ctrl_add_handler(hdl_vbi_cap, hdl_loop_cap, NULL, false);
1864 if (hdl_vbi_cap->error)
1865 return hdl_vbi_cap->error;
1866 dev->vbi_cap_dev.ctrl_handler = hdl_vbi_cap;
1867 }
1868 if (dev->has_vbi_out) {
1869 v4l2_ctrl_add_handler(hdl_vbi_out, hdl_user_gen, NULL, false);
1870 v4l2_ctrl_add_handler(hdl_vbi_out, hdl_streaming, NULL, false);
1871 if (hdl_vbi_out->error)
1872 return hdl_vbi_out->error;
1873 dev->vbi_out_dev.ctrl_handler = hdl_vbi_out;
1874 }
1875 if (dev->has_radio_rx) {
1876 v4l2_ctrl_add_handler(hdl_radio_rx, hdl_user_gen, NULL, false);
1877 v4l2_ctrl_add_handler(hdl_radio_rx, hdl_user_aud, NULL, false);
1878 if (hdl_radio_rx->error)
1879 return hdl_radio_rx->error;
1880 dev->radio_rx_dev.ctrl_handler = hdl_radio_rx;
1881 }
1882 if (dev->has_radio_tx) {
1883 v4l2_ctrl_add_handler(hdl_radio_tx, hdl_user_gen, NULL, false);
1884 v4l2_ctrl_add_handler(hdl_radio_tx, hdl_user_aud, NULL, false);
1885 if (hdl_radio_tx->error)
1886 return hdl_radio_tx->error;
1887 dev->radio_tx_dev.ctrl_handler = hdl_radio_tx;
1888 }
1889 if (dev->has_sdr_cap) {
1890 v4l2_ctrl_add_handler(hdl_sdr_cap, hdl_user_gen, NULL, false);
1891 v4l2_ctrl_add_handler(hdl_sdr_cap, hdl_streaming, NULL, false);
1892 if (hdl_sdr_cap->error)
1893 return hdl_sdr_cap->error;
1894 dev->sdr_cap_dev.ctrl_handler = hdl_sdr_cap;
1895 }
1896 if (dev->has_meta_cap) {
1897 v4l2_ctrl_add_handler(hdl_meta_cap, hdl_user_gen, NULL, false);
1898 v4l2_ctrl_add_handler(hdl_meta_cap, hdl_streaming, NULL, false);
1899 if (hdl_meta_cap->error)
1900 return hdl_meta_cap->error;
1901 dev->meta_cap_dev.ctrl_handler = hdl_meta_cap;
1902 }
1903 if (dev->has_meta_out) {
1904 v4l2_ctrl_add_handler(hdl_meta_out, hdl_user_gen, NULL, false);
1905 v4l2_ctrl_add_handler(hdl_meta_out, hdl_streaming, NULL, false);
1906 if (hdl_meta_out->error)
1907 return hdl_meta_out->error;
1908 dev->meta_out_dev.ctrl_handler = hdl_meta_out;
1909 }
1910 if (dev->has_touch_cap) {
1911 v4l2_ctrl_add_handler(hdl_tch_cap, hdl_user_gen, NULL, false);
1912 v4l2_ctrl_add_handler(hdl_tch_cap, hdl_streaming, NULL, false);
1913 if (hdl_tch_cap->error)
1914 return hdl_tch_cap->error;
1915 dev->touch_cap_dev.ctrl_handler = hdl_tch_cap;
1916 }
1917 return 0;
1918 }
1919
vivid_free_controls(struct vivid_dev * dev)1920 void vivid_free_controls(struct vivid_dev *dev)
1921 {
1922 v4l2_ctrl_handler_free(&dev->ctrl_hdl_vid_cap);
1923 v4l2_ctrl_handler_free(&dev->ctrl_hdl_vid_out);
1924 v4l2_ctrl_handler_free(&dev->ctrl_hdl_vbi_cap);
1925 v4l2_ctrl_handler_free(&dev->ctrl_hdl_vbi_out);
1926 v4l2_ctrl_handler_free(&dev->ctrl_hdl_radio_rx);
1927 v4l2_ctrl_handler_free(&dev->ctrl_hdl_radio_tx);
1928 v4l2_ctrl_handler_free(&dev->ctrl_hdl_sdr_cap);
1929 v4l2_ctrl_handler_free(&dev->ctrl_hdl_user_gen);
1930 v4l2_ctrl_handler_free(&dev->ctrl_hdl_user_vid);
1931 v4l2_ctrl_handler_free(&dev->ctrl_hdl_user_aud);
1932 v4l2_ctrl_handler_free(&dev->ctrl_hdl_streaming);
1933 v4l2_ctrl_handler_free(&dev->ctrl_hdl_sdtv_cap);
1934 v4l2_ctrl_handler_free(&dev->ctrl_hdl_loop_cap);
1935 v4l2_ctrl_handler_free(&dev->ctrl_hdl_fb);
1936 v4l2_ctrl_handler_free(&dev->ctrl_hdl_meta_cap);
1937 v4l2_ctrl_handler_free(&dev->ctrl_hdl_meta_out);
1938 v4l2_ctrl_handler_free(&dev->ctrl_hdl_touch_cap);
1939 }
1940