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