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