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