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

source code of linux/drivers/media/test-drivers/vivid/vivid-ctrls.c