1 // SPDX-License-Identifier: GPL-2.0-only
3 * vivid-ctrls.c - control support functions.
5 * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
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>
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"
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)
37 #define VIVID_CID_VIVID_BASE (0x00f00000 | 0xf000)
38 #define VIVID_CID_VIVID_CLASS (0x00f00000 | 1)
39 #define VIVID_CID_TEST_PATTERN (VIVID_CID_VIVID_BASE + 0)
40 #define VIVID_CID_OSD_TEXT_MODE (VIVID_CID_VIVID_BASE + 1)
41 #define VIVID_CID_HOR_MOVEMENT (VIVID_CID_VIVID_BASE + 2)
42 #define VIVID_CID_VERT_MOVEMENT (VIVID_CID_VIVID_BASE + 3)
43 #define VIVID_CID_SHOW_BORDER (VIVID_CID_VIVID_BASE + 4)
44 #define VIVID_CID_SHOW_SQUARE (VIVID_CID_VIVID_BASE + 5)
45 #define VIVID_CID_INSERT_SAV (VIVID_CID_VIVID_BASE + 6)
46 #define VIVID_CID_INSERT_EAV (VIVID_CID_VIVID_BASE + 7)
47 #define VIVID_CID_VBI_CAP_INTERLACED (VIVID_CID_VIVID_BASE + 8)
49 #define VIVID_CID_HFLIP (VIVID_CID_VIVID_BASE + 20)
50 #define VIVID_CID_VFLIP (VIVID_CID_VIVID_BASE + 21)
51 #define VIVID_CID_STD_ASPECT_RATIO (VIVID_CID_VIVID_BASE + 22)
52 #define VIVID_CID_DV_TIMINGS_ASPECT_RATIO (VIVID_CID_VIVID_BASE + 23)
53 #define VIVID_CID_TSTAMP_SRC (VIVID_CID_VIVID_BASE + 24)
54 #define VIVID_CID_COLORSPACE (VIVID_CID_VIVID_BASE + 25)
55 #define VIVID_CID_XFER_FUNC (VIVID_CID_VIVID_BASE + 26)
56 #define VIVID_CID_YCBCR_ENC (VIVID_CID_VIVID_BASE + 27)
57 #define VIVID_CID_QUANTIZATION (VIVID_CID_VIVID_BASE + 28)
58 #define VIVID_CID_LIMITED_RGB_RANGE (VIVID_CID_VIVID_BASE + 29)
59 #define VIVID_CID_ALPHA_MODE (VIVID_CID_VIVID_BASE + 30)
60 #define VIVID_CID_HAS_CROP_CAP (VIVID_CID_VIVID_BASE + 31)
61 #define VIVID_CID_HAS_COMPOSE_CAP (VIVID_CID_VIVID_BASE + 32)
62 #define VIVID_CID_HAS_SCALER_CAP (VIVID_CID_VIVID_BASE + 33)
63 #define VIVID_CID_HAS_CROP_OUT (VIVID_CID_VIVID_BASE + 34)
64 #define VIVID_CID_HAS_COMPOSE_OUT (VIVID_CID_VIVID_BASE + 35)
65 #define VIVID_CID_HAS_SCALER_OUT (VIVID_CID_VIVID_BASE + 36)
66 #define VIVID_CID_LOOP_VIDEO (VIVID_CID_VIVID_BASE + 37)
67 #define VIVID_CID_SEQ_WRAP (VIVID_CID_VIVID_BASE + 38)
68 #define VIVID_CID_TIME_WRAP (VIVID_CID_VIVID_BASE + 39)
69 #define VIVID_CID_MAX_EDID_BLOCKS (VIVID_CID_VIVID_BASE + 40)
70 #define VIVID_CID_PERCENTAGE_FILL (VIVID_CID_VIVID_BASE + 41)
71 #define VIVID_CID_REDUCED_FPS (VIVID_CID_VIVID_BASE + 42)
72 #define VIVID_CID_HSV_ENC (VIVID_CID_VIVID_BASE + 43)
73 #define VIVID_CID_DISPLAY_PRESENT (VIVID_CID_VIVID_BASE + 44)
75 #define VIVID_CID_STD_SIGNAL_MODE (VIVID_CID_VIVID_BASE + 60)
76 #define VIVID_CID_STANDARD (VIVID_CID_VIVID_BASE + 61)
77 #define VIVID_CID_DV_TIMINGS_SIGNAL_MODE (VIVID_CID_VIVID_BASE + 62)
78 #define VIVID_CID_DV_TIMINGS (VIVID_CID_VIVID_BASE + 63)
79 #define VIVID_CID_PERC_DROPPED (VIVID_CID_VIVID_BASE + 64)
80 #define VIVID_CID_DISCONNECT (VIVID_CID_VIVID_BASE + 65)
81 #define VIVID_CID_DQBUF_ERROR (VIVID_CID_VIVID_BASE + 66)
82 #define VIVID_CID_QUEUE_SETUP_ERROR (VIVID_CID_VIVID_BASE + 67)
83 #define VIVID_CID_BUF_PREPARE_ERROR (VIVID_CID_VIVID_BASE + 68)
84 #define VIVID_CID_START_STR_ERROR (VIVID_CID_VIVID_BASE + 69)
85 #define VIVID_CID_QUEUE_ERROR (VIVID_CID_VIVID_BASE + 70)
86 #define VIVID_CID_CLEAR_FB (VIVID_CID_VIVID_BASE + 71)
87 #define VIVID_CID_REQ_VALIDATE_ERROR (VIVID_CID_VIVID_BASE + 72)
89 #define VIVID_CID_RADIO_SEEK_MODE (VIVID_CID_VIVID_BASE + 90)
90 #define VIVID_CID_RADIO_SEEK_PROG_LIM (VIVID_CID_VIVID_BASE + 91)
91 #define VIVID_CID_RADIO_RX_RDS_RBDS (VIVID_CID_VIVID_BASE + 92)
92 #define VIVID_CID_RADIO_RX_RDS_BLOCKIO (VIVID_CID_VIVID_BASE + 93)
94 #define VIVID_CID_RADIO_TX_RDS_BLOCKIO (VIVID_CID_VIVID_BASE + 94)
96 #define VIVID_CID_SDR_CAP_FM_DEVIATION (VIVID_CID_VIVID_BASE + 110)
98 #define VIVID_CID_META_CAP_GENERATE_PTS (VIVID_CID_VIVID_BASE + 111)
99 #define VIVID_CID_META_CAP_GENERATE_SCR (VIVID_CID_VIVID_BASE + 112)
101 /* General User Controls */
103 static int vivid_user_gen_s_ctrl(struct v4l2_ctrl *ctrl)
105 struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_user_gen);
108 case VIVID_CID_DISCONNECT:
109 v4l2_info(&dev->v4l2_dev, "disconnect\n");
110 clear_bit(V4L2_FL_REGISTERED, &dev->vid_cap_dev.flags);
111 clear_bit(V4L2_FL_REGISTERED, &dev->vid_out_dev.flags);
112 clear_bit(V4L2_FL_REGISTERED, &dev->vbi_cap_dev.flags);
113 clear_bit(V4L2_FL_REGISTERED, &dev->vbi_out_dev.flags);
114 clear_bit(V4L2_FL_REGISTERED, &dev->sdr_cap_dev.flags);
115 clear_bit(V4L2_FL_REGISTERED, &dev->radio_rx_dev.flags);
116 clear_bit(V4L2_FL_REGISTERED, &dev->radio_tx_dev.flags);
117 clear_bit(V4L2_FL_REGISTERED, &dev->meta_cap_dev.flags);
119 case VIVID_CID_BUTTON:
120 dev->button_pressed = 30;
126 static const struct v4l2_ctrl_ops vivid_user_gen_ctrl_ops = {
127 .s_ctrl = vivid_user_gen_s_ctrl,
130 static const struct v4l2_ctrl_config vivid_ctrl_button = {
131 .ops = &vivid_user_gen_ctrl_ops,
132 .id = VIVID_CID_BUTTON,
134 .type = V4L2_CTRL_TYPE_BUTTON,
137 static const struct v4l2_ctrl_config vivid_ctrl_boolean = {
138 .ops = &vivid_user_gen_ctrl_ops,
139 .id = VIVID_CID_BOOLEAN,
141 .type = V4L2_CTRL_TYPE_BOOLEAN,
148 static const struct v4l2_ctrl_config vivid_ctrl_int32 = {
149 .ops = &vivid_user_gen_ctrl_ops,
150 .id = VIVID_CID_INTEGER,
151 .name = "Integer 32 Bits",
152 .type = V4L2_CTRL_TYPE_INTEGER,
153 .min = 0xffffffff80000000ULL,
158 static const struct v4l2_ctrl_config vivid_ctrl_int64 = {
159 .ops = &vivid_user_gen_ctrl_ops,
160 .id = VIVID_CID_INTEGER64,
161 .name = "Integer 64 Bits",
162 .type = V4L2_CTRL_TYPE_INTEGER64,
163 .min = 0x8000000000000000ULL,
164 .max = 0x7fffffffffffffffLL,
168 static const struct v4l2_ctrl_config vivid_ctrl_u32_array = {
169 .ops = &vivid_user_gen_ctrl_ops,
170 .id = VIVID_CID_U32_ARRAY,
171 .name = "U32 1 Element Array",
172 .type = V4L2_CTRL_TYPE_U32,
180 static const struct v4l2_ctrl_config vivid_ctrl_u16_matrix = {
181 .ops = &vivid_user_gen_ctrl_ops,
182 .id = VIVID_CID_U16_MATRIX,
183 .name = "U16 8x16 Matrix",
184 .type = V4L2_CTRL_TYPE_U16,
192 static const struct v4l2_ctrl_config vivid_ctrl_u8_4d_array = {
193 .ops = &vivid_user_gen_ctrl_ops,
194 .id = VIVID_CID_U8_4D_ARRAY,
195 .name = "U8 2x3x4x5 Array",
196 .type = V4L2_CTRL_TYPE_U8,
201 .dims = { 2, 3, 4, 5 },
204 static const char * const vivid_ctrl_menu_strings[] = {
205 "Menu Item 0 (Skipped)",
207 "Menu Item 2 (Skipped)",
210 "Menu Item 5 (Skipped)",
214 static const struct v4l2_ctrl_config vivid_ctrl_menu = {
215 .ops = &vivid_user_gen_ctrl_ops,
216 .id = VIVID_CID_MENU,
218 .type = V4L2_CTRL_TYPE_MENU,
222 .menu_skip_mask = 0x04,
223 .qmenu = vivid_ctrl_menu_strings,
226 static const struct v4l2_ctrl_config vivid_ctrl_string = {
227 .ops = &vivid_user_gen_ctrl_ops,
228 .id = VIVID_CID_STRING,
230 .type = V4L2_CTRL_TYPE_STRING,
236 static const struct v4l2_ctrl_config vivid_ctrl_bitmask = {
237 .ops = &vivid_user_gen_ctrl_ops,
238 .id = VIVID_CID_BITMASK,
240 .type = V4L2_CTRL_TYPE_BITMASK,
247 static const s64 vivid_ctrl_int_menu_values[] = {
248 1, 1, 2, 3, 5, 8, 13, 21, 42,
251 static const struct v4l2_ctrl_config vivid_ctrl_int_menu = {
252 .ops = &vivid_user_gen_ctrl_ops,
253 .id = VIVID_CID_INTMENU,
254 .name = "Integer Menu",
255 .type = V4L2_CTRL_TYPE_INTEGER_MENU,
259 .menu_skip_mask = 0x02,
260 .qmenu_int = vivid_ctrl_int_menu_values,
263 static const struct v4l2_ctrl_config vivid_ctrl_disconnect = {
264 .ops = &vivid_user_gen_ctrl_ops,
265 .id = VIVID_CID_DISCONNECT,
266 .name = "Disconnect",
267 .type = V4L2_CTRL_TYPE_BUTTON,
270 static const struct v4l2_area area = {
275 static const struct v4l2_ctrl_config vivid_ctrl_area = {
276 .ops = &vivid_user_gen_ctrl_ops,
277 .id = VIVID_CID_AREA,
279 .type = V4L2_CTRL_TYPE_AREA,
280 .p_def.p_const = &area,
283 /* Framebuffer Controls */
285 static int vivid_fb_s_ctrl(struct v4l2_ctrl *ctrl)
287 struct vivid_dev *dev = container_of(ctrl->handler,
288 struct vivid_dev, ctrl_hdl_fb);
291 case VIVID_CID_CLEAR_FB:
298 static const struct v4l2_ctrl_ops vivid_fb_ctrl_ops = {
299 .s_ctrl = vivid_fb_s_ctrl,
302 static const struct v4l2_ctrl_config vivid_ctrl_clear_fb = {
303 .ops = &vivid_fb_ctrl_ops,
304 .id = VIVID_CID_CLEAR_FB,
305 .name = "Clear Framebuffer",
306 .type = V4L2_CTRL_TYPE_BUTTON,
310 /* Video User Controls */
312 static int vivid_user_vid_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
314 struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_user_vid);
317 case V4L2_CID_AUTOGAIN:
318 dev->gain->val = (jiffies_to_msecs(jiffies) / 1000) & 0xff;
324 static int vivid_user_vid_s_ctrl(struct v4l2_ctrl *ctrl)
326 struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_user_vid);
329 case V4L2_CID_BRIGHTNESS:
330 dev->input_brightness[dev->input] = ctrl->val - dev->input * 128;
331 tpg_s_brightness(&dev->tpg, dev->input_brightness[dev->input]);
333 case V4L2_CID_CONTRAST:
334 tpg_s_contrast(&dev->tpg, ctrl->val);
336 case V4L2_CID_SATURATION:
337 tpg_s_saturation(&dev->tpg, ctrl->val);
340 tpg_s_hue(&dev->tpg, ctrl->val);
343 dev->hflip = ctrl->val;
344 tpg_s_hflip(&dev->tpg, dev->sensor_hflip ^ dev->hflip);
347 dev->vflip = ctrl->val;
348 tpg_s_vflip(&dev->tpg, dev->sensor_vflip ^ dev->vflip);
350 case V4L2_CID_ALPHA_COMPONENT:
351 tpg_s_alpha_component(&dev->tpg, ctrl->val);
357 static const struct v4l2_ctrl_ops vivid_user_vid_ctrl_ops = {
358 .g_volatile_ctrl = vivid_user_vid_g_volatile_ctrl,
359 .s_ctrl = vivid_user_vid_s_ctrl,
363 /* Video Capture Controls */
365 static int vivid_vid_cap_s_ctrl(struct v4l2_ctrl *ctrl)
367 static const u32 colorspaces[] = {
368 V4L2_COLORSPACE_SMPTE170M,
369 V4L2_COLORSPACE_REC709,
370 V4L2_COLORSPACE_SRGB,
371 V4L2_COLORSPACE_OPRGB,
372 V4L2_COLORSPACE_BT2020,
373 V4L2_COLORSPACE_DCI_P3,
374 V4L2_COLORSPACE_SMPTE240M,
375 V4L2_COLORSPACE_470_SYSTEM_M,
376 V4L2_COLORSPACE_470_SYSTEM_BG,
378 struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_vid_cap);
382 case VIVID_CID_TEST_PATTERN:
383 vivid_update_quality(dev);
384 tpg_s_pattern(&dev->tpg, ctrl->val);
386 case VIVID_CID_COLORSPACE:
387 tpg_s_colorspace(&dev->tpg, colorspaces[ctrl->val]);
388 vivid_send_source_change(dev, TV);
389 vivid_send_source_change(dev, SVID);
390 vivid_send_source_change(dev, HDMI);
391 vivid_send_source_change(dev, WEBCAM);
393 case VIVID_CID_XFER_FUNC:
394 tpg_s_xfer_func(&dev->tpg, ctrl->val);
395 vivid_send_source_change(dev, TV);
396 vivid_send_source_change(dev, SVID);
397 vivid_send_source_change(dev, HDMI);
398 vivid_send_source_change(dev, WEBCAM);
400 case VIVID_CID_YCBCR_ENC:
401 tpg_s_ycbcr_enc(&dev->tpg, ctrl->val);
402 vivid_send_source_change(dev, TV);
403 vivid_send_source_change(dev, SVID);
404 vivid_send_source_change(dev, HDMI);
405 vivid_send_source_change(dev, WEBCAM);
407 case VIVID_CID_HSV_ENC:
408 tpg_s_hsv_enc(&dev->tpg, ctrl->val ? V4L2_HSV_ENC_256 :
410 vivid_send_source_change(dev, TV);
411 vivid_send_source_change(dev, SVID);
412 vivid_send_source_change(dev, HDMI);
413 vivid_send_source_change(dev, WEBCAM);
415 case VIVID_CID_QUANTIZATION:
416 tpg_s_quantization(&dev->tpg, ctrl->val);
417 vivid_send_source_change(dev, TV);
418 vivid_send_source_change(dev, SVID);
419 vivid_send_source_change(dev, HDMI);
420 vivid_send_source_change(dev, WEBCAM);
422 case V4L2_CID_DV_RX_RGB_RANGE:
423 if (!vivid_is_hdmi_cap(dev))
425 tpg_s_rgb_range(&dev->tpg, ctrl->val);
427 case VIVID_CID_LIMITED_RGB_RANGE:
428 tpg_s_real_rgb_range(&dev->tpg, ctrl->val ?
429 V4L2_DV_RGB_RANGE_LIMITED : V4L2_DV_RGB_RANGE_FULL);
431 case VIVID_CID_ALPHA_MODE:
432 tpg_s_alpha_mode(&dev->tpg, ctrl->val);
434 case VIVID_CID_HOR_MOVEMENT:
435 tpg_s_mv_hor_mode(&dev->tpg, ctrl->val);
437 case VIVID_CID_VERT_MOVEMENT:
438 tpg_s_mv_vert_mode(&dev->tpg, ctrl->val);
440 case VIVID_CID_OSD_TEXT_MODE:
441 dev->osd_mode = ctrl->val;
443 case VIVID_CID_PERCENTAGE_FILL:
444 tpg_s_perc_fill(&dev->tpg, ctrl->val);
445 for (i = 0; i < VIDEO_MAX_FRAME; i++)
446 dev->must_blank[i] = ctrl->val < 100;
448 case VIVID_CID_INSERT_SAV:
449 tpg_s_insert_sav(&dev->tpg, ctrl->val);
451 case VIVID_CID_INSERT_EAV:
452 tpg_s_insert_eav(&dev->tpg, ctrl->val);
454 case VIVID_CID_HFLIP:
455 dev->sensor_hflip = ctrl->val;
456 tpg_s_hflip(&dev->tpg, dev->sensor_hflip ^ dev->hflip);
458 case VIVID_CID_VFLIP:
459 dev->sensor_vflip = ctrl->val;
460 tpg_s_vflip(&dev->tpg, dev->sensor_vflip ^ dev->vflip);
462 case VIVID_CID_REDUCED_FPS:
463 dev->reduced_fps = ctrl->val;
464 vivid_update_format_cap(dev, true);
466 case VIVID_CID_HAS_CROP_CAP:
467 dev->has_crop_cap = ctrl->val;
468 vivid_update_format_cap(dev, true);
470 case VIVID_CID_HAS_COMPOSE_CAP:
471 dev->has_compose_cap = ctrl->val;
472 vivid_update_format_cap(dev, true);
474 case VIVID_CID_HAS_SCALER_CAP:
475 dev->has_scaler_cap = ctrl->val;
476 vivid_update_format_cap(dev, true);
478 case VIVID_CID_SHOW_BORDER:
479 tpg_s_show_border(&dev->tpg, ctrl->val);
481 case VIVID_CID_SHOW_SQUARE:
482 tpg_s_show_square(&dev->tpg, ctrl->val);
484 case VIVID_CID_STD_ASPECT_RATIO:
485 dev->std_aspect_ratio[dev->input] = ctrl->val;
486 tpg_s_video_aspect(&dev->tpg, vivid_get_video_aspect(dev));
488 case VIVID_CID_DV_TIMINGS_SIGNAL_MODE:
489 dev->dv_timings_signal_mode[dev->input] =
490 dev->ctrl_dv_timings_signal_mode->val;
491 dev->query_dv_timings[dev->input] = dev->ctrl_dv_timings->val;
493 dev->power_present = 0;
495 i < ARRAY_SIZE(dev->dv_timings_signal_mode);
497 if (dev->input_type[i] == HDMI) {
498 if (dev->dv_timings_signal_mode[i] != NO_SIGNAL)
499 dev->power_present |= (1 << j);
502 __v4l2_ctrl_s_ctrl(dev->ctrl_rx_power_present,
505 v4l2_ctrl_activate(dev->ctrl_dv_timings,
506 dev->dv_timings_signal_mode[dev->input] ==
507 SELECTED_DV_TIMINGS);
509 vivid_update_quality(dev);
510 vivid_send_source_change(dev, HDMI);
512 case VIVID_CID_DV_TIMINGS_ASPECT_RATIO:
513 dev->dv_timings_aspect_ratio[dev->input] = ctrl->val;
514 tpg_s_video_aspect(&dev->tpg, vivid_get_video_aspect(dev));
516 case VIVID_CID_TSTAMP_SRC:
517 dev->tstamp_src_is_soe = ctrl->val;
518 dev->vb_vid_cap_q.timestamp_flags &= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
519 if (dev->tstamp_src_is_soe)
520 dev->vb_vid_cap_q.timestamp_flags |= V4L2_BUF_FLAG_TSTAMP_SRC_SOE;
522 case VIVID_CID_MAX_EDID_BLOCKS:
523 dev->edid_max_blocks = ctrl->val;
524 if (dev->edid_blocks > dev->edid_max_blocks)
525 dev->edid_blocks = dev->edid_max_blocks;
531 static const struct v4l2_ctrl_ops vivid_vid_cap_ctrl_ops = {
532 .s_ctrl = vivid_vid_cap_s_ctrl,
535 static const char * const vivid_ctrl_hor_movement_strings[] = {
546 static const struct v4l2_ctrl_config vivid_ctrl_hor_movement = {
547 .ops = &vivid_vid_cap_ctrl_ops,
548 .id = VIVID_CID_HOR_MOVEMENT,
549 .name = "Horizontal Movement",
550 .type = V4L2_CTRL_TYPE_MENU,
551 .max = TPG_MOVE_POS_FAST,
552 .def = TPG_MOVE_NONE,
553 .qmenu = vivid_ctrl_hor_movement_strings,
556 static const char * const vivid_ctrl_vert_movement_strings[] = {
567 static const struct v4l2_ctrl_config vivid_ctrl_vert_movement = {
568 .ops = &vivid_vid_cap_ctrl_ops,
569 .id = VIVID_CID_VERT_MOVEMENT,
570 .name = "Vertical Movement",
571 .type = V4L2_CTRL_TYPE_MENU,
572 .max = TPG_MOVE_POS_FAST,
573 .def = TPG_MOVE_NONE,
574 .qmenu = vivid_ctrl_vert_movement_strings,
577 static const struct v4l2_ctrl_config vivid_ctrl_show_border = {
578 .ops = &vivid_vid_cap_ctrl_ops,
579 .id = VIVID_CID_SHOW_BORDER,
580 .name = "Show Border",
581 .type = V4L2_CTRL_TYPE_BOOLEAN,
586 static const struct v4l2_ctrl_config vivid_ctrl_show_square = {
587 .ops = &vivid_vid_cap_ctrl_ops,
588 .id = VIVID_CID_SHOW_SQUARE,
589 .name = "Show Square",
590 .type = V4L2_CTRL_TYPE_BOOLEAN,
595 static const char * const vivid_ctrl_osd_mode_strings[] = {
602 static const struct v4l2_ctrl_config vivid_ctrl_osd_mode = {
603 .ops = &vivid_vid_cap_ctrl_ops,
604 .id = VIVID_CID_OSD_TEXT_MODE,
605 .name = "OSD Text Mode",
606 .type = V4L2_CTRL_TYPE_MENU,
607 .max = ARRAY_SIZE(vivid_ctrl_osd_mode_strings) - 2,
608 .qmenu = vivid_ctrl_osd_mode_strings,
611 static const struct v4l2_ctrl_config vivid_ctrl_perc_fill = {
612 .ops = &vivid_vid_cap_ctrl_ops,
613 .id = VIVID_CID_PERCENTAGE_FILL,
614 .name = "Fill Percentage of Frame",
615 .type = V4L2_CTRL_TYPE_INTEGER,
622 static const struct v4l2_ctrl_config vivid_ctrl_insert_sav = {
623 .ops = &vivid_vid_cap_ctrl_ops,
624 .id = VIVID_CID_INSERT_SAV,
625 .name = "Insert SAV Code in Image",
626 .type = V4L2_CTRL_TYPE_BOOLEAN,
631 static const struct v4l2_ctrl_config vivid_ctrl_insert_eav = {
632 .ops = &vivid_vid_cap_ctrl_ops,
633 .id = VIVID_CID_INSERT_EAV,
634 .name = "Insert EAV Code in Image",
635 .type = V4L2_CTRL_TYPE_BOOLEAN,
640 static const struct v4l2_ctrl_config vivid_ctrl_hflip = {
641 .ops = &vivid_vid_cap_ctrl_ops,
642 .id = VIVID_CID_HFLIP,
643 .name = "Sensor Flipped Horizontally",
644 .type = V4L2_CTRL_TYPE_BOOLEAN,
649 static const struct v4l2_ctrl_config vivid_ctrl_vflip = {
650 .ops = &vivid_vid_cap_ctrl_ops,
651 .id = VIVID_CID_VFLIP,
652 .name = "Sensor Flipped Vertically",
653 .type = V4L2_CTRL_TYPE_BOOLEAN,
658 static const struct v4l2_ctrl_config vivid_ctrl_reduced_fps = {
659 .ops = &vivid_vid_cap_ctrl_ops,
660 .id = VIVID_CID_REDUCED_FPS,
661 .name = "Reduced Framerate",
662 .type = V4L2_CTRL_TYPE_BOOLEAN,
667 static const struct v4l2_ctrl_config vivid_ctrl_has_crop_cap = {
668 .ops = &vivid_vid_cap_ctrl_ops,
669 .id = VIVID_CID_HAS_CROP_CAP,
670 .name = "Enable Capture Cropping",
671 .type = V4L2_CTRL_TYPE_BOOLEAN,
677 static const struct v4l2_ctrl_config vivid_ctrl_has_compose_cap = {
678 .ops = &vivid_vid_cap_ctrl_ops,
679 .id = VIVID_CID_HAS_COMPOSE_CAP,
680 .name = "Enable Capture Composing",
681 .type = V4L2_CTRL_TYPE_BOOLEAN,
687 static const struct v4l2_ctrl_config vivid_ctrl_has_scaler_cap = {
688 .ops = &vivid_vid_cap_ctrl_ops,
689 .id = VIVID_CID_HAS_SCALER_CAP,
690 .name = "Enable Capture Scaler",
691 .type = V4L2_CTRL_TYPE_BOOLEAN,
697 static const char * const vivid_ctrl_tstamp_src_strings[] = {
703 static const struct v4l2_ctrl_config vivid_ctrl_tstamp_src = {
704 .ops = &vivid_vid_cap_ctrl_ops,
705 .id = VIVID_CID_TSTAMP_SRC,
706 .name = "Timestamp Source",
707 .type = V4L2_CTRL_TYPE_MENU,
708 .max = ARRAY_SIZE(vivid_ctrl_tstamp_src_strings) - 2,
709 .qmenu = vivid_ctrl_tstamp_src_strings,
712 static const struct v4l2_ctrl_config vivid_ctrl_std_aspect_ratio = {
713 .ops = &vivid_vid_cap_ctrl_ops,
714 .id = VIVID_CID_STD_ASPECT_RATIO,
715 .name = "Standard Aspect Ratio",
716 .type = V4L2_CTRL_TYPE_MENU,
720 .qmenu = tpg_aspect_strings,
723 static const char * const vivid_ctrl_dv_timings_signal_mode_strings[] = {
724 "Current DV Timings",
728 "Selected DV Timings",
729 "Cycle Through All DV Timings",
734 static const struct v4l2_ctrl_config vivid_ctrl_dv_timings_signal_mode = {
735 .ops = &vivid_vid_cap_ctrl_ops,
736 .id = VIVID_CID_DV_TIMINGS_SIGNAL_MODE,
737 .name = "DV Timings Signal Mode",
738 .type = V4L2_CTRL_TYPE_MENU,
740 .qmenu = vivid_ctrl_dv_timings_signal_mode_strings,
743 static const struct v4l2_ctrl_config vivid_ctrl_dv_timings_aspect_ratio = {
744 .ops = &vivid_vid_cap_ctrl_ops,
745 .id = VIVID_CID_DV_TIMINGS_ASPECT_RATIO,
746 .name = "DV Timings Aspect Ratio",
747 .type = V4L2_CTRL_TYPE_MENU,
749 .qmenu = tpg_aspect_strings,
752 static const struct v4l2_ctrl_config vivid_ctrl_max_edid_blocks = {
753 .ops = &vivid_vid_cap_ctrl_ops,
754 .id = VIVID_CID_MAX_EDID_BLOCKS,
755 .name = "Maximum EDID Blocks",
756 .type = V4L2_CTRL_TYPE_INTEGER,
763 static const char * const vivid_ctrl_colorspace_strings[] = {
776 static const struct v4l2_ctrl_config vivid_ctrl_colorspace = {
777 .ops = &vivid_vid_cap_ctrl_ops,
778 .id = VIVID_CID_COLORSPACE,
779 .name = "Colorspace",
780 .type = V4L2_CTRL_TYPE_MENU,
781 .max = ARRAY_SIZE(vivid_ctrl_colorspace_strings) - 2,
783 .qmenu = vivid_ctrl_colorspace_strings,
786 static const char * const vivid_ctrl_xfer_func_strings[] = {
798 static const struct v4l2_ctrl_config vivid_ctrl_xfer_func = {
799 .ops = &vivid_vid_cap_ctrl_ops,
800 .id = VIVID_CID_XFER_FUNC,
801 .name = "Transfer Function",
802 .type = V4L2_CTRL_TYPE_MENU,
803 .max = ARRAY_SIZE(vivid_ctrl_xfer_func_strings) - 2,
804 .qmenu = vivid_ctrl_xfer_func_strings,
807 static const char * const vivid_ctrl_ycbcr_enc_strings[] = {
815 "BT.2020 Constant Luminance",
820 static const struct v4l2_ctrl_config vivid_ctrl_ycbcr_enc = {
821 .ops = &vivid_vid_cap_ctrl_ops,
822 .id = VIVID_CID_YCBCR_ENC,
823 .name = "Y'CbCr Encoding",
824 .type = V4L2_CTRL_TYPE_MENU,
825 .menu_skip_mask = 1 << 5,
826 .max = ARRAY_SIZE(vivid_ctrl_ycbcr_enc_strings) - 2,
827 .qmenu = vivid_ctrl_ycbcr_enc_strings,
830 static const char * const vivid_ctrl_hsv_enc_strings[] = {
836 static const struct v4l2_ctrl_config vivid_ctrl_hsv_enc = {
837 .ops = &vivid_vid_cap_ctrl_ops,
838 .id = VIVID_CID_HSV_ENC,
839 .name = "HSV Encoding",
840 .type = V4L2_CTRL_TYPE_MENU,
841 .max = ARRAY_SIZE(vivid_ctrl_hsv_enc_strings) - 2,
842 .qmenu = vivid_ctrl_hsv_enc_strings,
845 static const char * const vivid_ctrl_quantization_strings[] = {
852 static const struct v4l2_ctrl_config vivid_ctrl_quantization = {
853 .ops = &vivid_vid_cap_ctrl_ops,
854 .id = VIVID_CID_QUANTIZATION,
855 .name = "Quantization",
856 .type = V4L2_CTRL_TYPE_MENU,
857 .max = ARRAY_SIZE(vivid_ctrl_quantization_strings) - 2,
858 .qmenu = vivid_ctrl_quantization_strings,
861 static const struct v4l2_ctrl_config vivid_ctrl_alpha_mode = {
862 .ops = &vivid_vid_cap_ctrl_ops,
863 .id = VIVID_CID_ALPHA_MODE,
864 .name = "Apply Alpha To Red Only",
865 .type = V4L2_CTRL_TYPE_BOOLEAN,
870 static const struct v4l2_ctrl_config vivid_ctrl_limited_rgb_range = {
871 .ops = &vivid_vid_cap_ctrl_ops,
872 .id = VIVID_CID_LIMITED_RGB_RANGE,
873 .name = "Limited RGB Range (16-235)",
874 .type = V4L2_CTRL_TYPE_BOOLEAN,
880 /* Video Loop Control */
882 static int vivid_loop_cap_s_ctrl(struct v4l2_ctrl *ctrl)
884 struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_loop_cap);
887 case VIVID_CID_LOOP_VIDEO:
888 dev->loop_video = ctrl->val;
889 vivid_update_quality(dev);
890 vivid_send_source_change(dev, SVID);
891 vivid_send_source_change(dev, HDMI);
897 static const struct v4l2_ctrl_ops vivid_loop_cap_ctrl_ops = {
898 .s_ctrl = vivid_loop_cap_s_ctrl,
901 static const struct v4l2_ctrl_config vivid_ctrl_loop_video = {
902 .ops = &vivid_loop_cap_ctrl_ops,
903 .id = VIVID_CID_LOOP_VIDEO,
904 .name = "Loop Video",
905 .type = V4L2_CTRL_TYPE_BOOLEAN,
911 /* VBI Capture Control */
913 static int vivid_vbi_cap_s_ctrl(struct v4l2_ctrl *ctrl)
915 struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_vbi_cap);
918 case VIVID_CID_VBI_CAP_INTERLACED:
919 dev->vbi_cap_interlaced = ctrl->val;
925 static const struct v4l2_ctrl_ops vivid_vbi_cap_ctrl_ops = {
926 .s_ctrl = vivid_vbi_cap_s_ctrl,
929 static const struct v4l2_ctrl_config vivid_ctrl_vbi_cap_interlaced = {
930 .ops = &vivid_vbi_cap_ctrl_ops,
931 .id = VIVID_CID_VBI_CAP_INTERLACED,
932 .name = "Interlaced VBI Format",
933 .type = V4L2_CTRL_TYPE_BOOLEAN,
939 /* Video Output Controls */
941 static int vivid_vid_out_s_ctrl(struct v4l2_ctrl *ctrl)
943 struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_vid_out);
944 struct v4l2_bt_timings *bt = &dev->dv_timings_out.bt;
945 u32 display_present = 0;
946 unsigned int i, j, bus_idx;
949 case VIVID_CID_HAS_CROP_OUT:
950 dev->has_crop_out = ctrl->val;
951 vivid_update_format_out(dev);
953 case VIVID_CID_HAS_COMPOSE_OUT:
954 dev->has_compose_out = ctrl->val;
955 vivid_update_format_out(dev);
957 case VIVID_CID_HAS_SCALER_OUT:
958 dev->has_scaler_out = ctrl->val;
959 vivid_update_format_out(dev);
961 case V4L2_CID_DV_TX_MODE:
962 dev->dvi_d_out = ctrl->val == V4L2_DV_TX_MODE_DVI_D;
963 if (!vivid_is_hdmi_out(dev))
965 if (!dev->dvi_d_out && (bt->flags & V4L2_DV_FL_IS_CE_VIDEO)) {
966 if (bt->width == 720 && bt->height <= 576)
967 dev->colorspace_out = V4L2_COLORSPACE_SMPTE170M;
969 dev->colorspace_out = V4L2_COLORSPACE_REC709;
970 dev->quantization_out = V4L2_QUANTIZATION_DEFAULT;
972 dev->colorspace_out = V4L2_COLORSPACE_SRGB;
973 dev->quantization_out = dev->dvi_d_out ?
974 V4L2_QUANTIZATION_LIM_RANGE :
975 V4L2_QUANTIZATION_DEFAULT;
978 vivid_send_source_change(dev, HDMI);
980 case VIVID_CID_DISPLAY_PRESENT:
981 if (dev->output_type[dev->output] != HDMI)
984 dev->display_present[dev->output] = ctrl->val;
985 for (i = 0, j = 0; i < dev->num_outputs; i++)
986 if (dev->output_type[i] == HDMI)
988 dev->display_present[i] << j++;
990 __v4l2_ctrl_s_ctrl(dev->ctrl_tx_rxsense, display_present);
992 if (dev->edid_blocks) {
993 __v4l2_ctrl_s_ctrl(dev->ctrl_tx_edid_present,
995 __v4l2_ctrl_s_ctrl(dev->ctrl_tx_hotplug,
999 bus_idx = dev->cec_output2bus_map[dev->output];
1000 if (!dev->cec_tx_adap[bus_idx])
1003 if (ctrl->val && dev->edid_blocks)
1004 cec_s_phys_addr(dev->cec_tx_adap[bus_idx],
1005 dev->cec_tx_adap[bus_idx]->phys_addr,
1008 cec_phys_addr_invalidate(dev->cec_tx_adap[bus_idx]);
1015 static const struct v4l2_ctrl_ops vivid_vid_out_ctrl_ops = {
1016 .s_ctrl = vivid_vid_out_s_ctrl,
1019 static const struct v4l2_ctrl_config vivid_ctrl_has_crop_out = {
1020 .ops = &vivid_vid_out_ctrl_ops,
1021 .id = VIVID_CID_HAS_CROP_OUT,
1022 .name = "Enable Output Cropping",
1023 .type = V4L2_CTRL_TYPE_BOOLEAN,
1029 static const struct v4l2_ctrl_config vivid_ctrl_has_compose_out = {
1030 .ops = &vivid_vid_out_ctrl_ops,
1031 .id = VIVID_CID_HAS_COMPOSE_OUT,
1032 .name = "Enable Output Composing",
1033 .type = V4L2_CTRL_TYPE_BOOLEAN,
1039 static const struct v4l2_ctrl_config vivid_ctrl_has_scaler_out = {
1040 .ops = &vivid_vid_out_ctrl_ops,
1041 .id = VIVID_CID_HAS_SCALER_OUT,
1042 .name = "Enable Output Scaler",
1043 .type = V4L2_CTRL_TYPE_BOOLEAN,
1049 static const struct v4l2_ctrl_config vivid_ctrl_display_present = {
1050 .ops = &vivid_vid_out_ctrl_ops,
1051 .id = VIVID_CID_DISPLAY_PRESENT,
1052 .name = "Display Present",
1053 .type = V4L2_CTRL_TYPE_BOOLEAN,
1059 /* Streaming Controls */
1061 static int vivid_streaming_s_ctrl(struct v4l2_ctrl *ctrl)
1063 struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_streaming);
1067 case VIVID_CID_DQBUF_ERROR:
1068 dev->dqbuf_error = true;
1070 case VIVID_CID_PERC_DROPPED:
1071 dev->perc_dropped_buffers = ctrl->val;
1073 case VIVID_CID_QUEUE_SETUP_ERROR:
1074 dev->queue_setup_error = true;
1076 case VIVID_CID_BUF_PREPARE_ERROR:
1077 dev->buf_prepare_error = true;
1079 case VIVID_CID_START_STR_ERROR:
1080 dev->start_streaming_error = true;
1082 case VIVID_CID_REQ_VALIDATE_ERROR:
1083 dev->req_validate_error = true;
1085 case VIVID_CID_QUEUE_ERROR:
1086 if (vb2_start_streaming_called(&dev->vb_vid_cap_q))
1087 vb2_queue_error(&dev->vb_vid_cap_q);
1088 if (vb2_start_streaming_called(&dev->vb_vbi_cap_q))
1089 vb2_queue_error(&dev->vb_vbi_cap_q);
1090 if (vb2_start_streaming_called(&dev->vb_vid_out_q))
1091 vb2_queue_error(&dev->vb_vid_out_q);
1092 if (vb2_start_streaming_called(&dev->vb_vbi_out_q))
1093 vb2_queue_error(&dev->vb_vbi_out_q);
1094 if (vb2_start_streaming_called(&dev->vb_sdr_cap_q))
1095 vb2_queue_error(&dev->vb_sdr_cap_q);
1097 case VIVID_CID_SEQ_WRAP:
1098 dev->seq_wrap = ctrl->val;
1100 case VIVID_CID_TIME_WRAP:
1101 dev->time_wrap = ctrl->val;
1102 if (ctrl->val == 0) {
1103 dev->time_wrap_offset = 0;
1107 * We want to set the time 16 seconds before the 32 bit tv_sec
1108 * value of struct timeval would wrap around. So first we
1109 * calculate ktime_get_ns() % ((1 << 32) * NSEC_PER_SEC), and
1110 * then we set the offset to ((1 << 32) - 16) * NSEC_PER_SEC).
1112 div64_u64_rem(ktime_get_ns(),
1113 0x100000000ULL * NSEC_PER_SEC, &rem);
1114 dev->time_wrap_offset =
1115 (0x100000000ULL - 16) * NSEC_PER_SEC - rem;
1121 static const struct v4l2_ctrl_ops vivid_streaming_ctrl_ops = {
1122 .s_ctrl = vivid_streaming_s_ctrl,
1125 static const struct v4l2_ctrl_config vivid_ctrl_dqbuf_error = {
1126 .ops = &vivid_streaming_ctrl_ops,
1127 .id = VIVID_CID_DQBUF_ERROR,
1128 .name = "Inject V4L2_BUF_FLAG_ERROR",
1129 .type = V4L2_CTRL_TYPE_BUTTON,
1132 static const struct v4l2_ctrl_config vivid_ctrl_perc_dropped = {
1133 .ops = &vivid_streaming_ctrl_ops,
1134 .id = VIVID_CID_PERC_DROPPED,
1135 .name = "Percentage of Dropped Buffers",
1136 .type = V4L2_CTRL_TYPE_INTEGER,
1142 static const struct v4l2_ctrl_config vivid_ctrl_queue_setup_error = {
1143 .ops = &vivid_streaming_ctrl_ops,
1144 .id = VIVID_CID_QUEUE_SETUP_ERROR,
1145 .name = "Inject VIDIOC_REQBUFS Error",
1146 .type = V4L2_CTRL_TYPE_BUTTON,
1149 static const struct v4l2_ctrl_config vivid_ctrl_buf_prepare_error = {
1150 .ops = &vivid_streaming_ctrl_ops,
1151 .id = VIVID_CID_BUF_PREPARE_ERROR,
1152 .name = "Inject VIDIOC_QBUF Error",
1153 .type = V4L2_CTRL_TYPE_BUTTON,
1156 static const struct v4l2_ctrl_config vivid_ctrl_start_streaming_error = {
1157 .ops = &vivid_streaming_ctrl_ops,
1158 .id = VIVID_CID_START_STR_ERROR,
1159 .name = "Inject VIDIOC_STREAMON Error",
1160 .type = V4L2_CTRL_TYPE_BUTTON,
1163 static const struct v4l2_ctrl_config vivid_ctrl_queue_error = {
1164 .ops = &vivid_streaming_ctrl_ops,
1165 .id = VIVID_CID_QUEUE_ERROR,
1166 .name = "Inject Fatal Streaming Error",
1167 .type = V4L2_CTRL_TYPE_BUTTON,
1170 #ifdef CONFIG_MEDIA_CONTROLLER
1171 static const struct v4l2_ctrl_config vivid_ctrl_req_validate_error = {
1172 .ops = &vivid_streaming_ctrl_ops,
1173 .id = VIVID_CID_REQ_VALIDATE_ERROR,
1174 .name = "Inject req_validate() Error",
1175 .type = V4L2_CTRL_TYPE_BUTTON,
1179 static const struct v4l2_ctrl_config vivid_ctrl_seq_wrap = {
1180 .ops = &vivid_streaming_ctrl_ops,
1181 .id = VIVID_CID_SEQ_WRAP,
1182 .name = "Wrap Sequence Number",
1183 .type = V4L2_CTRL_TYPE_BOOLEAN,
1188 static const struct v4l2_ctrl_config vivid_ctrl_time_wrap = {
1189 .ops = &vivid_streaming_ctrl_ops,
1190 .id = VIVID_CID_TIME_WRAP,
1191 .name = "Wrap Timestamp",
1192 .type = V4L2_CTRL_TYPE_BOOLEAN,
1198 /* SDTV Capture Controls */
1200 static int vivid_sdtv_cap_s_ctrl(struct v4l2_ctrl *ctrl)
1202 struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_sdtv_cap);
1205 case VIVID_CID_STD_SIGNAL_MODE:
1206 dev->std_signal_mode[dev->input] =
1207 dev->ctrl_std_signal_mode->val;
1208 if (dev->std_signal_mode[dev->input] == SELECTED_STD)
1209 dev->query_std[dev->input] =
1210 vivid_standard[dev->ctrl_standard->val];
1211 v4l2_ctrl_activate(dev->ctrl_standard,
1212 dev->std_signal_mode[dev->input] ==
1214 vivid_update_quality(dev);
1215 vivid_send_source_change(dev, TV);
1216 vivid_send_source_change(dev, SVID);
1222 static const struct v4l2_ctrl_ops vivid_sdtv_cap_ctrl_ops = {
1223 .s_ctrl = vivid_sdtv_cap_s_ctrl,
1226 static const char * const vivid_ctrl_std_signal_mode_strings[] = {
1231 "Selected Standard",
1232 "Cycle Through All Standards",
1236 static const struct v4l2_ctrl_config vivid_ctrl_std_signal_mode = {
1237 .ops = &vivid_sdtv_cap_ctrl_ops,
1238 .id = VIVID_CID_STD_SIGNAL_MODE,
1239 .name = "Standard Signal Mode",
1240 .type = V4L2_CTRL_TYPE_MENU,
1241 .max = ARRAY_SIZE(vivid_ctrl_std_signal_mode_strings) - 2,
1242 .menu_skip_mask = 1 << 3,
1243 .qmenu = vivid_ctrl_std_signal_mode_strings,
1246 static const struct v4l2_ctrl_config vivid_ctrl_standard = {
1247 .ops = &vivid_sdtv_cap_ctrl_ops,
1248 .id = VIVID_CID_STANDARD,
1250 .type = V4L2_CTRL_TYPE_MENU,
1252 .qmenu = vivid_ctrl_standard_strings,
1257 /* Radio Receiver Controls */
1259 static int vivid_radio_rx_s_ctrl(struct v4l2_ctrl *ctrl)
1261 struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_radio_rx);
1264 case VIVID_CID_RADIO_SEEK_MODE:
1265 dev->radio_rx_hw_seek_mode = ctrl->val;
1267 case VIVID_CID_RADIO_SEEK_PROG_LIM:
1268 dev->radio_rx_hw_seek_prog_lim = ctrl->val;
1270 case VIVID_CID_RADIO_RX_RDS_RBDS:
1271 dev->rds_gen.use_rbds = ctrl->val;
1273 case VIVID_CID_RADIO_RX_RDS_BLOCKIO:
1274 dev->radio_rx_rds_controls = ctrl->val;
1275 dev->radio_rx_caps &= ~V4L2_CAP_READWRITE;
1276 dev->radio_rx_rds_use_alternates = false;
1277 if (!dev->radio_rx_rds_controls) {
1278 dev->radio_rx_caps |= V4L2_CAP_READWRITE;
1279 __v4l2_ctrl_s_ctrl(dev->radio_rx_rds_pty, 0);
1280 __v4l2_ctrl_s_ctrl(dev->radio_rx_rds_ta, 0);
1281 __v4l2_ctrl_s_ctrl(dev->radio_rx_rds_tp, 0);
1282 __v4l2_ctrl_s_ctrl(dev->radio_rx_rds_ms, 0);
1283 __v4l2_ctrl_s_ctrl_string(dev->radio_rx_rds_psname, "");
1284 __v4l2_ctrl_s_ctrl_string(dev->radio_rx_rds_radiotext, "");
1286 v4l2_ctrl_activate(dev->radio_rx_rds_pty, dev->radio_rx_rds_controls);
1287 v4l2_ctrl_activate(dev->radio_rx_rds_psname, dev->radio_rx_rds_controls);
1288 v4l2_ctrl_activate(dev->radio_rx_rds_radiotext, dev->radio_rx_rds_controls);
1289 v4l2_ctrl_activate(dev->radio_rx_rds_ta, dev->radio_rx_rds_controls);
1290 v4l2_ctrl_activate(dev->radio_rx_rds_tp, dev->radio_rx_rds_controls);
1291 v4l2_ctrl_activate(dev->radio_rx_rds_ms, dev->radio_rx_rds_controls);
1292 dev->radio_rx_dev.device_caps = dev->radio_rx_caps;
1294 case V4L2_CID_RDS_RECEPTION:
1295 dev->radio_rx_rds_enabled = ctrl->val;
1301 static const struct v4l2_ctrl_ops vivid_radio_rx_ctrl_ops = {
1302 .s_ctrl = vivid_radio_rx_s_ctrl,
1305 static const char * const vivid_ctrl_radio_rds_mode_strings[] = {
1311 static const struct v4l2_ctrl_config vivid_ctrl_radio_rx_rds_blockio = {
1312 .ops = &vivid_radio_rx_ctrl_ops,
1313 .id = VIVID_CID_RADIO_RX_RDS_BLOCKIO,
1314 .name = "RDS Rx I/O Mode",
1315 .type = V4L2_CTRL_TYPE_MENU,
1316 .qmenu = vivid_ctrl_radio_rds_mode_strings,
1320 static const struct v4l2_ctrl_config vivid_ctrl_radio_rx_rds_rbds = {
1321 .ops = &vivid_radio_rx_ctrl_ops,
1322 .id = VIVID_CID_RADIO_RX_RDS_RBDS,
1323 .name = "Generate RBDS Instead of RDS",
1324 .type = V4L2_CTRL_TYPE_BOOLEAN,
1329 static const char * const vivid_ctrl_radio_hw_seek_mode_strings[] = {
1336 static const struct v4l2_ctrl_config vivid_ctrl_radio_hw_seek_mode = {
1337 .ops = &vivid_radio_rx_ctrl_ops,
1338 .id = VIVID_CID_RADIO_SEEK_MODE,
1339 .name = "Radio HW Seek Mode",
1340 .type = V4L2_CTRL_TYPE_MENU,
1342 .qmenu = vivid_ctrl_radio_hw_seek_mode_strings,
1345 static const struct v4l2_ctrl_config vivid_ctrl_radio_hw_seek_prog_lim = {
1346 .ops = &vivid_radio_rx_ctrl_ops,
1347 .id = VIVID_CID_RADIO_SEEK_PROG_LIM,
1348 .name = "Radio Programmable HW Seek",
1349 .type = V4L2_CTRL_TYPE_BOOLEAN,
1355 /* Radio Transmitter Controls */
1357 static int vivid_radio_tx_s_ctrl(struct v4l2_ctrl *ctrl)
1359 struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_radio_tx);
1362 case VIVID_CID_RADIO_TX_RDS_BLOCKIO:
1363 dev->radio_tx_rds_controls = ctrl->val;
1364 dev->radio_tx_caps &= ~V4L2_CAP_READWRITE;
1365 if (!dev->radio_tx_rds_controls)
1366 dev->radio_tx_caps |= V4L2_CAP_READWRITE;
1367 dev->radio_tx_dev.device_caps = dev->radio_tx_caps;
1369 case V4L2_CID_RDS_TX_PTY:
1370 if (dev->radio_rx_rds_controls)
1371 v4l2_ctrl_s_ctrl(dev->radio_rx_rds_pty, ctrl->val);
1373 case V4L2_CID_RDS_TX_PS_NAME:
1374 if (dev->radio_rx_rds_controls)
1375 v4l2_ctrl_s_ctrl_string(dev->radio_rx_rds_psname, ctrl->p_new.p_char);
1377 case V4L2_CID_RDS_TX_RADIO_TEXT:
1378 if (dev->radio_rx_rds_controls)
1379 v4l2_ctrl_s_ctrl_string(dev->radio_rx_rds_radiotext, ctrl->p_new.p_char);
1381 case V4L2_CID_RDS_TX_TRAFFIC_ANNOUNCEMENT:
1382 if (dev->radio_rx_rds_controls)
1383 v4l2_ctrl_s_ctrl(dev->radio_rx_rds_ta, ctrl->val);
1385 case V4L2_CID_RDS_TX_TRAFFIC_PROGRAM:
1386 if (dev->radio_rx_rds_controls)
1387 v4l2_ctrl_s_ctrl(dev->radio_rx_rds_tp, ctrl->val);
1389 case V4L2_CID_RDS_TX_MUSIC_SPEECH:
1390 if (dev->radio_rx_rds_controls)
1391 v4l2_ctrl_s_ctrl(dev->radio_rx_rds_ms, ctrl->val);
1397 static const struct v4l2_ctrl_ops vivid_radio_tx_ctrl_ops = {
1398 .s_ctrl = vivid_radio_tx_s_ctrl,
1401 static const struct v4l2_ctrl_config vivid_ctrl_radio_tx_rds_blockio = {
1402 .ops = &vivid_radio_tx_ctrl_ops,
1403 .id = VIVID_CID_RADIO_TX_RDS_BLOCKIO,
1404 .name = "RDS Tx I/O Mode",
1405 .type = V4L2_CTRL_TYPE_MENU,
1406 .qmenu = vivid_ctrl_radio_rds_mode_strings,
1412 /* SDR Capture Controls */
1414 static int vivid_sdr_cap_s_ctrl(struct v4l2_ctrl *ctrl)
1416 struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_sdr_cap);
1419 case VIVID_CID_SDR_CAP_FM_DEVIATION:
1420 dev->sdr_fm_deviation = ctrl->val;
1426 static const struct v4l2_ctrl_ops vivid_sdr_cap_ctrl_ops = {
1427 .s_ctrl = vivid_sdr_cap_s_ctrl,
1430 static const struct v4l2_ctrl_config vivid_ctrl_sdr_cap_fm_deviation = {
1431 .ops = &vivid_sdr_cap_ctrl_ops,
1432 .id = VIVID_CID_SDR_CAP_FM_DEVIATION,
1433 .name = "FM Deviation",
1434 .type = V4L2_CTRL_TYPE_INTEGER,
1441 /* Metadata Capture Control */
1443 static int vivid_meta_cap_s_ctrl(struct v4l2_ctrl *ctrl)
1445 struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev,
1449 case VIVID_CID_META_CAP_GENERATE_PTS:
1450 dev->meta_pts = ctrl->val;
1452 case VIVID_CID_META_CAP_GENERATE_SCR:
1453 dev->meta_scr = ctrl->val;
1459 static const struct v4l2_ctrl_ops vivid_meta_cap_ctrl_ops = {
1460 .s_ctrl = vivid_meta_cap_s_ctrl,
1463 static const struct v4l2_ctrl_config vivid_ctrl_meta_has_pts = {
1464 .ops = &vivid_meta_cap_ctrl_ops,
1465 .id = VIVID_CID_META_CAP_GENERATE_PTS,
1466 .name = "Generate PTS",
1467 .type = V4L2_CTRL_TYPE_BOOLEAN,
1473 static const struct v4l2_ctrl_config vivid_ctrl_meta_has_src_clk = {
1474 .ops = &vivid_meta_cap_ctrl_ops,
1475 .id = VIVID_CID_META_CAP_GENERATE_SCR,
1476 .name = "Generate SCR",
1477 .type = V4L2_CTRL_TYPE_BOOLEAN,
1483 static const struct v4l2_ctrl_config vivid_ctrl_class = {
1484 .ops = &vivid_user_gen_ctrl_ops,
1485 .flags = V4L2_CTRL_FLAG_READ_ONLY | V4L2_CTRL_FLAG_WRITE_ONLY,
1486 .id = VIVID_CID_VIVID_CLASS,
1487 .name = "Vivid Controls",
1488 .type = V4L2_CTRL_TYPE_CTRL_CLASS,
1491 int vivid_create_controls(struct vivid_dev *dev, bool show_ccs_cap,
1492 bool show_ccs_out, bool no_error_inj,
1493 bool has_sdtv, bool has_hdmi)
1495 struct v4l2_ctrl_handler *hdl_user_gen = &dev->ctrl_hdl_user_gen;
1496 struct v4l2_ctrl_handler *hdl_user_vid = &dev->ctrl_hdl_user_vid;
1497 struct v4l2_ctrl_handler *hdl_user_aud = &dev->ctrl_hdl_user_aud;
1498 struct v4l2_ctrl_handler *hdl_streaming = &dev->ctrl_hdl_streaming;
1499 struct v4l2_ctrl_handler *hdl_sdtv_cap = &dev->ctrl_hdl_sdtv_cap;
1500 struct v4l2_ctrl_handler *hdl_loop_cap = &dev->ctrl_hdl_loop_cap;
1501 struct v4l2_ctrl_handler *hdl_fb = &dev->ctrl_hdl_fb;
1502 struct v4l2_ctrl_handler *hdl_vid_cap = &dev->ctrl_hdl_vid_cap;
1503 struct v4l2_ctrl_handler *hdl_vid_out = &dev->ctrl_hdl_vid_out;
1504 struct v4l2_ctrl_handler *hdl_vbi_cap = &dev->ctrl_hdl_vbi_cap;
1505 struct v4l2_ctrl_handler *hdl_vbi_out = &dev->ctrl_hdl_vbi_out;
1506 struct v4l2_ctrl_handler *hdl_radio_rx = &dev->ctrl_hdl_radio_rx;
1507 struct v4l2_ctrl_handler *hdl_radio_tx = &dev->ctrl_hdl_radio_tx;
1508 struct v4l2_ctrl_handler *hdl_sdr_cap = &dev->ctrl_hdl_sdr_cap;
1509 struct v4l2_ctrl_handler *hdl_meta_cap = &dev->ctrl_hdl_meta_cap;
1510 struct v4l2_ctrl_handler *hdl_meta_out = &dev->ctrl_hdl_meta_out;
1511 struct v4l2_ctrl_handler *hdl_tch_cap = &dev->ctrl_hdl_touch_cap;
1513 struct v4l2_ctrl_config vivid_ctrl_dv_timings = {
1514 .ops = &vivid_vid_cap_ctrl_ops,
1515 .id = VIVID_CID_DV_TIMINGS,
1516 .name = "DV Timings",
1517 .type = V4L2_CTRL_TYPE_MENU,
1521 v4l2_ctrl_handler_init(hdl_user_gen, 10);
1522 v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_class, NULL);
1523 v4l2_ctrl_handler_init(hdl_user_vid, 9);
1524 v4l2_ctrl_new_custom(hdl_user_vid, &vivid_ctrl_class, NULL);
1525 v4l2_ctrl_handler_init(hdl_user_aud, 2);
1526 v4l2_ctrl_new_custom(hdl_user_aud, &vivid_ctrl_class, NULL);
1527 v4l2_ctrl_handler_init(hdl_streaming, 8);
1528 v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_class, NULL);
1529 v4l2_ctrl_handler_init(hdl_sdtv_cap, 2);
1530 v4l2_ctrl_new_custom(hdl_sdtv_cap, &vivid_ctrl_class, NULL);
1531 v4l2_ctrl_handler_init(hdl_loop_cap, 1);
1532 v4l2_ctrl_new_custom(hdl_loop_cap, &vivid_ctrl_class, NULL);
1533 v4l2_ctrl_handler_init(hdl_fb, 1);
1534 v4l2_ctrl_new_custom(hdl_fb, &vivid_ctrl_class, NULL);
1535 v4l2_ctrl_handler_init(hdl_vid_cap, 55);
1536 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_class, NULL);
1537 v4l2_ctrl_handler_init(hdl_vid_out, 26);
1538 if (!no_error_inj || dev->has_fb || dev->num_hdmi_outputs)
1539 v4l2_ctrl_new_custom(hdl_vid_out, &vivid_ctrl_class, NULL);
1540 v4l2_ctrl_handler_init(hdl_vbi_cap, 21);
1541 v4l2_ctrl_new_custom(hdl_vbi_cap, &vivid_ctrl_class, NULL);
1542 v4l2_ctrl_handler_init(hdl_vbi_out, 19);
1544 v4l2_ctrl_new_custom(hdl_vbi_out, &vivid_ctrl_class, NULL);
1545 v4l2_ctrl_handler_init(hdl_radio_rx, 17);
1546 v4l2_ctrl_new_custom(hdl_radio_rx, &vivid_ctrl_class, NULL);
1547 v4l2_ctrl_handler_init(hdl_radio_tx, 17);
1548 v4l2_ctrl_new_custom(hdl_radio_tx, &vivid_ctrl_class, NULL);
1549 v4l2_ctrl_handler_init(hdl_sdr_cap, 19);
1550 v4l2_ctrl_new_custom(hdl_sdr_cap, &vivid_ctrl_class, NULL);
1551 v4l2_ctrl_handler_init(hdl_meta_cap, 2);
1552 v4l2_ctrl_new_custom(hdl_meta_cap, &vivid_ctrl_class, NULL);
1553 v4l2_ctrl_handler_init(hdl_meta_out, 2);
1554 v4l2_ctrl_new_custom(hdl_meta_out, &vivid_ctrl_class, NULL);
1555 v4l2_ctrl_handler_init(hdl_tch_cap, 2);
1556 v4l2_ctrl_new_custom(hdl_tch_cap, &vivid_ctrl_class, NULL);
1559 dev->volume = v4l2_ctrl_new_std(hdl_user_aud, NULL,
1560 V4L2_CID_AUDIO_VOLUME, 0, 255, 1, 200);
1561 dev->mute = v4l2_ctrl_new_std(hdl_user_aud, NULL,
1562 V4L2_CID_AUDIO_MUTE, 0, 1, 1, 0);
1563 if (dev->has_vid_cap) {
1564 dev->brightness = v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops,
1565 V4L2_CID_BRIGHTNESS, 0, 255, 1, 128);
1566 for (i = 0; i < MAX_INPUTS; i++)
1567 dev->input_brightness[i] = 128;
1568 dev->contrast = v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops,
1569 V4L2_CID_CONTRAST, 0, 255, 1, 128);
1570 dev->saturation = v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops,
1571 V4L2_CID_SATURATION, 0, 255, 1, 128);
1572 dev->hue = v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops,
1573 V4L2_CID_HUE, -128, 128, 1, 0);
1574 v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops,
1575 V4L2_CID_HFLIP, 0, 1, 1, 0);
1576 v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops,
1577 V4L2_CID_VFLIP, 0, 1, 1, 0);
1578 dev->autogain = v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops,
1579 V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
1580 dev->gain = v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops,
1581 V4L2_CID_GAIN, 0, 255, 1, 100);
1582 dev->alpha = v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops,
1583 V4L2_CID_ALPHA_COMPONENT, 0, 255, 1, 0);
1585 dev->button = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_button, NULL);
1586 dev->int32 = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_int32, NULL);
1587 dev->int64 = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_int64, NULL);
1588 dev->boolean = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_boolean, NULL);
1589 dev->menu = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_menu, NULL);
1590 dev->string = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_string, NULL);
1591 dev->bitmask = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_bitmask, NULL);
1592 dev->int_menu = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_int_menu, NULL);
1593 v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_area, NULL);
1594 v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_u32_array, NULL);
1595 v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_u16_matrix, NULL);
1596 v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_u8_4d_array, NULL);
1598 if (dev->has_vid_cap) {
1599 /* Image Processing Controls */
1600 struct v4l2_ctrl_config vivid_ctrl_test_pattern = {
1601 .ops = &vivid_vid_cap_ctrl_ops,
1602 .id = VIVID_CID_TEST_PATTERN,
1603 .name = "Test Pattern",
1604 .type = V4L2_CTRL_TYPE_MENU,
1605 .max = TPG_PAT_NOISE,
1606 .qmenu = tpg_pattern_strings,
1609 dev->test_pattern = v4l2_ctrl_new_custom(hdl_vid_cap,
1610 &vivid_ctrl_test_pattern, NULL);
1611 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_perc_fill, NULL);
1612 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_hor_movement, NULL);
1613 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_vert_movement, NULL);
1614 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_osd_mode, NULL);
1615 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_show_border, NULL);
1616 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_show_square, NULL);
1617 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_hflip, NULL);
1618 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_vflip, NULL);
1619 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_insert_sav, NULL);
1620 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_insert_eav, NULL);
1621 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_reduced_fps, NULL);
1623 dev->ctrl_has_crop_cap = v4l2_ctrl_new_custom(hdl_vid_cap,
1624 &vivid_ctrl_has_crop_cap, NULL);
1625 dev->ctrl_has_compose_cap = v4l2_ctrl_new_custom(hdl_vid_cap,
1626 &vivid_ctrl_has_compose_cap, NULL);
1627 dev->ctrl_has_scaler_cap = v4l2_ctrl_new_custom(hdl_vid_cap,
1628 &vivid_ctrl_has_scaler_cap, NULL);
1631 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_tstamp_src, NULL);
1632 dev->colorspace = v4l2_ctrl_new_custom(hdl_vid_cap,
1633 &vivid_ctrl_colorspace, NULL);
1634 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_xfer_func, NULL);
1635 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_ycbcr_enc, NULL);
1636 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_hsv_enc, NULL);
1637 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_quantization, NULL);
1638 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_alpha_mode, NULL);
1641 if (dev->has_vid_out && show_ccs_out) {
1642 dev->ctrl_has_crop_out = v4l2_ctrl_new_custom(hdl_vid_out,
1643 &vivid_ctrl_has_crop_out, NULL);
1644 dev->ctrl_has_compose_out = v4l2_ctrl_new_custom(hdl_vid_out,
1645 &vivid_ctrl_has_compose_out, NULL);
1646 dev->ctrl_has_scaler_out = v4l2_ctrl_new_custom(hdl_vid_out,
1647 &vivid_ctrl_has_scaler_out, NULL);
1651 * Testing this driver with v4l2-compliance will trigger the error
1652 * injection controls, and after that nothing will work as expected.
1653 * So we have a module option to drop these error injecting controls
1654 * allowing us to run v4l2_compliance again.
1656 if (!no_error_inj) {
1657 v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_disconnect, NULL);
1658 v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_dqbuf_error, NULL);
1659 v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_perc_dropped, NULL);
1660 v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_queue_setup_error, NULL);
1661 v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_buf_prepare_error, NULL);
1662 v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_start_streaming_error, NULL);
1663 v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_queue_error, NULL);
1664 #ifdef CONFIG_MEDIA_CONTROLLER
1665 v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_req_validate_error, NULL);
1667 v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_seq_wrap, NULL);
1668 v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_time_wrap, NULL);
1671 if (has_sdtv && (dev->has_vid_cap || dev->has_vbi_cap)) {
1672 if (dev->has_vid_cap)
1673 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_std_aspect_ratio, NULL);
1674 dev->ctrl_std_signal_mode = v4l2_ctrl_new_custom(hdl_sdtv_cap,
1675 &vivid_ctrl_std_signal_mode, NULL);
1676 dev->ctrl_standard = v4l2_ctrl_new_custom(hdl_sdtv_cap,
1677 &vivid_ctrl_standard, NULL);
1678 if (dev->ctrl_std_signal_mode)
1679 v4l2_ctrl_cluster(2, &dev->ctrl_std_signal_mode);
1680 if (dev->has_raw_vbi_cap)
1681 v4l2_ctrl_new_custom(hdl_vbi_cap, &vivid_ctrl_vbi_cap_interlaced, NULL);
1684 if (dev->num_hdmi_inputs) {
1685 s64 hdmi_input_mask = GENMASK(dev->num_hdmi_inputs - 1, 0);
1687 dev->ctrl_dv_timings_signal_mode = v4l2_ctrl_new_custom(hdl_vid_cap,
1688 &vivid_ctrl_dv_timings_signal_mode, NULL);
1690 vivid_ctrl_dv_timings.max = dev->query_dv_timings_size - 1;
1691 vivid_ctrl_dv_timings.qmenu =
1692 (const char * const *)dev->query_dv_timings_qmenu;
1693 dev->ctrl_dv_timings = v4l2_ctrl_new_custom(hdl_vid_cap,
1694 &vivid_ctrl_dv_timings, NULL);
1695 if (dev->ctrl_dv_timings_signal_mode)
1696 v4l2_ctrl_cluster(2, &dev->ctrl_dv_timings_signal_mode);
1698 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_dv_timings_aspect_ratio, NULL);
1699 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_max_edid_blocks, NULL);
1700 dev->real_rgb_range_cap = v4l2_ctrl_new_custom(hdl_vid_cap,
1701 &vivid_ctrl_limited_rgb_range, NULL);
1702 dev->rgb_range_cap = v4l2_ctrl_new_std_menu(hdl_vid_cap,
1703 &vivid_vid_cap_ctrl_ops,
1704 V4L2_CID_DV_RX_RGB_RANGE, V4L2_DV_RGB_RANGE_FULL,
1705 0, V4L2_DV_RGB_RANGE_AUTO);
1706 dev->ctrl_rx_power_present = v4l2_ctrl_new_std(hdl_vid_cap,
1707 NULL, V4L2_CID_DV_RX_POWER_PRESENT, 0, hdmi_input_mask,
1708 0, hdmi_input_mask);
1711 if (dev->num_hdmi_outputs) {
1712 s64 hdmi_output_mask = GENMASK(dev->num_hdmi_outputs - 1, 0);
1715 * We aren't doing anything with this at the moment, but
1716 * HDMI outputs typically have this controls.
1718 dev->ctrl_tx_rgb_range = v4l2_ctrl_new_std_menu(hdl_vid_out, NULL,
1719 V4L2_CID_DV_TX_RGB_RANGE, V4L2_DV_RGB_RANGE_FULL,
1720 0, V4L2_DV_RGB_RANGE_AUTO);
1721 dev->ctrl_tx_mode = v4l2_ctrl_new_std_menu(hdl_vid_out, NULL,
1722 V4L2_CID_DV_TX_MODE, V4L2_DV_TX_MODE_HDMI,
1723 0, V4L2_DV_TX_MODE_HDMI);
1724 dev->ctrl_display_present = v4l2_ctrl_new_custom(hdl_vid_out,
1725 &vivid_ctrl_display_present, NULL);
1726 dev->ctrl_tx_hotplug = v4l2_ctrl_new_std(hdl_vid_out,
1727 NULL, V4L2_CID_DV_TX_HOTPLUG, 0, hdmi_output_mask,
1728 0, hdmi_output_mask);
1729 dev->ctrl_tx_rxsense = v4l2_ctrl_new_std(hdl_vid_out,
1730 NULL, V4L2_CID_DV_TX_RXSENSE, 0, hdmi_output_mask,
1731 0, hdmi_output_mask);
1732 dev->ctrl_tx_edid_present = v4l2_ctrl_new_std(hdl_vid_out,
1733 NULL, V4L2_CID_DV_TX_EDID_PRESENT, 0, hdmi_output_mask,
1734 0, hdmi_output_mask);
1736 if ((dev->has_vid_cap && dev->has_vid_out) ||
1737 (dev->has_vbi_cap && dev->has_vbi_out))
1738 v4l2_ctrl_new_custom(hdl_loop_cap, &vivid_ctrl_loop_video, NULL);
1741 v4l2_ctrl_new_custom(hdl_fb, &vivid_ctrl_clear_fb, NULL);
1743 if (dev->has_radio_rx) {
1744 v4l2_ctrl_new_custom(hdl_radio_rx, &vivid_ctrl_radio_hw_seek_mode, NULL);
1745 v4l2_ctrl_new_custom(hdl_radio_rx, &vivid_ctrl_radio_hw_seek_prog_lim, NULL);
1746 v4l2_ctrl_new_custom(hdl_radio_rx, &vivid_ctrl_radio_rx_rds_blockio, NULL);
1747 v4l2_ctrl_new_custom(hdl_radio_rx, &vivid_ctrl_radio_rx_rds_rbds, NULL);
1748 v4l2_ctrl_new_std(hdl_radio_rx, &vivid_radio_rx_ctrl_ops,
1749 V4L2_CID_RDS_RECEPTION, 0, 1, 1, 1);
1750 dev->radio_rx_rds_pty = v4l2_ctrl_new_std(hdl_radio_rx,
1751 &vivid_radio_rx_ctrl_ops,
1752 V4L2_CID_RDS_RX_PTY, 0, 31, 1, 0);
1753 dev->radio_rx_rds_psname = v4l2_ctrl_new_std(hdl_radio_rx,
1754 &vivid_radio_rx_ctrl_ops,
1755 V4L2_CID_RDS_RX_PS_NAME, 0, 8, 8, 0);
1756 dev->radio_rx_rds_radiotext = v4l2_ctrl_new_std(hdl_radio_rx,
1757 &vivid_radio_rx_ctrl_ops,
1758 V4L2_CID_RDS_RX_RADIO_TEXT, 0, 64, 64, 0);
1759 dev->radio_rx_rds_ta = v4l2_ctrl_new_std(hdl_radio_rx,
1760 &vivid_radio_rx_ctrl_ops,
1761 V4L2_CID_RDS_RX_TRAFFIC_ANNOUNCEMENT, 0, 1, 1, 0);
1762 dev->radio_rx_rds_tp = v4l2_ctrl_new_std(hdl_radio_rx,
1763 &vivid_radio_rx_ctrl_ops,
1764 V4L2_CID_RDS_RX_TRAFFIC_PROGRAM, 0, 1, 1, 0);
1765 dev->radio_rx_rds_ms = v4l2_ctrl_new_std(hdl_radio_rx,
1766 &vivid_radio_rx_ctrl_ops,
1767 V4L2_CID_RDS_RX_MUSIC_SPEECH, 0, 1, 1, 1);
1769 if (dev->has_radio_tx) {
1770 v4l2_ctrl_new_custom(hdl_radio_tx,
1771 &vivid_ctrl_radio_tx_rds_blockio, NULL);
1772 dev->radio_tx_rds_pi = v4l2_ctrl_new_std(hdl_radio_tx,
1773 &vivid_radio_tx_ctrl_ops,
1774 V4L2_CID_RDS_TX_PI, 0, 0xffff, 1, 0x8088);
1775 dev->radio_tx_rds_pty = v4l2_ctrl_new_std(hdl_radio_tx,
1776 &vivid_radio_tx_ctrl_ops,
1777 V4L2_CID_RDS_TX_PTY, 0, 31, 1, 3);
1778 dev->radio_tx_rds_psname = v4l2_ctrl_new_std(hdl_radio_tx,
1779 &vivid_radio_tx_ctrl_ops,
1780 V4L2_CID_RDS_TX_PS_NAME, 0, 8, 8, 0);
1781 if (dev->radio_tx_rds_psname)
1782 v4l2_ctrl_s_ctrl_string(dev->radio_tx_rds_psname, "VIVID-TX");
1783 dev->radio_tx_rds_radiotext = v4l2_ctrl_new_std(hdl_radio_tx,
1784 &vivid_radio_tx_ctrl_ops,
1785 V4L2_CID_RDS_TX_RADIO_TEXT, 0, 64 * 2, 64, 0);
1786 if (dev->radio_tx_rds_radiotext)
1787 v4l2_ctrl_s_ctrl_string(dev->radio_tx_rds_radiotext,
1788 "This is a VIVID default Radio Text template text, change at will");
1789 dev->radio_tx_rds_mono_stereo = v4l2_ctrl_new_std(hdl_radio_tx,
1790 &vivid_radio_tx_ctrl_ops,
1791 V4L2_CID_RDS_TX_MONO_STEREO, 0, 1, 1, 1);
1792 dev->radio_tx_rds_art_head = v4l2_ctrl_new_std(hdl_radio_tx,
1793 &vivid_radio_tx_ctrl_ops,
1794 V4L2_CID_RDS_TX_ARTIFICIAL_HEAD, 0, 1, 1, 0);
1795 dev->radio_tx_rds_compressed = v4l2_ctrl_new_std(hdl_radio_tx,
1796 &vivid_radio_tx_ctrl_ops,
1797 V4L2_CID_RDS_TX_COMPRESSED, 0, 1, 1, 0);
1798 dev->radio_tx_rds_dyn_pty = v4l2_ctrl_new_std(hdl_radio_tx,
1799 &vivid_radio_tx_ctrl_ops,
1800 V4L2_CID_RDS_TX_DYNAMIC_PTY, 0, 1, 1, 0);
1801 dev->radio_tx_rds_ta = v4l2_ctrl_new_std(hdl_radio_tx,
1802 &vivid_radio_tx_ctrl_ops,
1803 V4L2_CID_RDS_TX_TRAFFIC_ANNOUNCEMENT, 0, 1, 1, 0);
1804 dev->radio_tx_rds_tp = v4l2_ctrl_new_std(hdl_radio_tx,
1805 &vivid_radio_tx_ctrl_ops,
1806 V4L2_CID_RDS_TX_TRAFFIC_PROGRAM, 0, 1, 1, 1);
1807 dev->radio_tx_rds_ms = v4l2_ctrl_new_std(hdl_radio_tx,
1808 &vivid_radio_tx_ctrl_ops,
1809 V4L2_CID_RDS_TX_MUSIC_SPEECH, 0, 1, 1, 1);
1811 if (dev->has_sdr_cap) {
1812 v4l2_ctrl_new_custom(hdl_sdr_cap,
1813 &vivid_ctrl_sdr_cap_fm_deviation, NULL);
1815 if (dev->has_meta_cap) {
1816 v4l2_ctrl_new_custom(hdl_meta_cap,
1817 &vivid_ctrl_meta_has_pts, NULL);
1818 v4l2_ctrl_new_custom(hdl_meta_cap,
1819 &vivid_ctrl_meta_has_src_clk, NULL);
1822 if (hdl_user_gen->error)
1823 return hdl_user_gen->error;
1824 if (hdl_user_vid->error)
1825 return hdl_user_vid->error;
1826 if (hdl_user_aud->error)
1827 return hdl_user_aud->error;
1828 if (hdl_streaming->error)
1829 return hdl_streaming->error;
1830 if (hdl_sdr_cap->error)
1831 return hdl_sdr_cap->error;
1832 if (hdl_loop_cap->error)
1833 return hdl_loop_cap->error;
1836 v4l2_ctrl_auto_cluster(2, &dev->autogain, 0, true);
1838 if (dev->has_vid_cap) {
1839 v4l2_ctrl_add_handler(hdl_vid_cap, hdl_user_gen, NULL, false);
1840 v4l2_ctrl_add_handler(hdl_vid_cap, hdl_user_vid, NULL, false);
1841 v4l2_ctrl_add_handler(hdl_vid_cap, hdl_user_aud, NULL, false);
1842 v4l2_ctrl_add_handler(hdl_vid_cap, hdl_streaming, NULL, false);
1843 v4l2_ctrl_add_handler(hdl_vid_cap, hdl_sdtv_cap, NULL, false);
1844 v4l2_ctrl_add_handler(hdl_vid_cap, hdl_loop_cap, NULL, false);
1845 v4l2_ctrl_add_handler(hdl_vid_cap, hdl_fb, NULL, false);
1846 if (hdl_vid_cap->error)
1847 return hdl_vid_cap->error;
1848 dev->vid_cap_dev.ctrl_handler = hdl_vid_cap;
1850 if (dev->has_vid_out) {
1851 v4l2_ctrl_add_handler(hdl_vid_out, hdl_user_gen, NULL, false);
1852 v4l2_ctrl_add_handler(hdl_vid_out, hdl_user_aud, NULL, false);
1853 v4l2_ctrl_add_handler(hdl_vid_out, hdl_streaming, NULL, false);
1854 v4l2_ctrl_add_handler(hdl_vid_out, hdl_fb, NULL, false);
1855 if (hdl_vid_out->error)
1856 return hdl_vid_out->error;
1857 dev->vid_out_dev.ctrl_handler = hdl_vid_out;
1859 if (dev->has_vbi_cap) {
1860 v4l2_ctrl_add_handler(hdl_vbi_cap, hdl_user_gen, NULL, false);
1861 v4l2_ctrl_add_handler(hdl_vbi_cap, hdl_streaming, NULL, false);
1862 v4l2_ctrl_add_handler(hdl_vbi_cap, hdl_sdtv_cap, NULL, false);
1863 v4l2_ctrl_add_handler(hdl_vbi_cap, hdl_loop_cap, NULL, false);
1864 if (hdl_vbi_cap->error)
1865 return hdl_vbi_cap->error;
1866 dev->vbi_cap_dev.ctrl_handler = hdl_vbi_cap;
1868 if (dev->has_vbi_out) {
1869 v4l2_ctrl_add_handler(hdl_vbi_out, hdl_user_gen, NULL, false);
1870 v4l2_ctrl_add_handler(hdl_vbi_out, hdl_streaming, NULL, false);
1871 if (hdl_vbi_out->error)
1872 return hdl_vbi_out->error;
1873 dev->vbi_out_dev.ctrl_handler = hdl_vbi_out;
1875 if (dev->has_radio_rx) {
1876 v4l2_ctrl_add_handler(hdl_radio_rx, hdl_user_gen, NULL, false);
1877 v4l2_ctrl_add_handler(hdl_radio_rx, hdl_user_aud, NULL, false);
1878 if (hdl_radio_rx->error)
1879 return hdl_radio_rx->error;
1880 dev->radio_rx_dev.ctrl_handler = hdl_radio_rx;
1882 if (dev->has_radio_tx) {
1883 v4l2_ctrl_add_handler(hdl_radio_tx, hdl_user_gen, NULL, false);
1884 v4l2_ctrl_add_handler(hdl_radio_tx, hdl_user_aud, NULL, false);
1885 if (hdl_radio_tx->error)
1886 return hdl_radio_tx->error;
1887 dev->radio_tx_dev.ctrl_handler = hdl_radio_tx;
1889 if (dev->has_sdr_cap) {
1890 v4l2_ctrl_add_handler(hdl_sdr_cap, hdl_user_gen, NULL, false);
1891 v4l2_ctrl_add_handler(hdl_sdr_cap, hdl_streaming, NULL, false);
1892 if (hdl_sdr_cap->error)
1893 return hdl_sdr_cap->error;
1894 dev->sdr_cap_dev.ctrl_handler = hdl_sdr_cap;
1896 if (dev->has_meta_cap) {
1897 v4l2_ctrl_add_handler(hdl_meta_cap, hdl_user_gen, NULL, false);
1898 v4l2_ctrl_add_handler(hdl_meta_cap, hdl_streaming, NULL, false);
1899 if (hdl_meta_cap->error)
1900 return hdl_meta_cap->error;
1901 dev->meta_cap_dev.ctrl_handler = hdl_meta_cap;
1903 if (dev->has_meta_out) {
1904 v4l2_ctrl_add_handler(hdl_meta_out, hdl_user_gen, NULL, false);
1905 v4l2_ctrl_add_handler(hdl_meta_out, hdl_streaming, NULL, false);
1906 if (hdl_meta_out->error)
1907 return hdl_meta_out->error;
1908 dev->meta_out_dev.ctrl_handler = hdl_meta_out;
1910 if (dev->has_touch_cap) {
1911 v4l2_ctrl_add_handler(hdl_tch_cap, hdl_user_gen, NULL, false);
1912 v4l2_ctrl_add_handler(hdl_tch_cap, hdl_streaming, NULL, false);
1913 if (hdl_tch_cap->error)
1914 return hdl_tch_cap->error;
1915 dev->touch_cap_dev.ctrl_handler = hdl_tch_cap;
1920 void vivid_free_controls(struct vivid_dev *dev)
1922 v4l2_ctrl_handler_free(&dev->ctrl_hdl_vid_cap);
1923 v4l2_ctrl_handler_free(&dev->ctrl_hdl_vid_out);
1924 v4l2_ctrl_handler_free(&dev->ctrl_hdl_vbi_cap);
1925 v4l2_ctrl_handler_free(&dev->ctrl_hdl_vbi_out);
1926 v4l2_ctrl_handler_free(&dev->ctrl_hdl_radio_rx);
1927 v4l2_ctrl_handler_free(&dev->ctrl_hdl_radio_tx);
1928 v4l2_ctrl_handler_free(&dev->ctrl_hdl_sdr_cap);
1929 v4l2_ctrl_handler_free(&dev->ctrl_hdl_user_gen);
1930 v4l2_ctrl_handler_free(&dev->ctrl_hdl_user_vid);
1931 v4l2_ctrl_handler_free(&dev->ctrl_hdl_user_aud);
1932 v4l2_ctrl_handler_free(&dev->ctrl_hdl_streaming);
1933 v4l2_ctrl_handler_free(&dev->ctrl_hdl_sdtv_cap);
1934 v4l2_ctrl_handler_free(&dev->ctrl_hdl_loop_cap);
1935 v4l2_ctrl_handler_free(&dev->ctrl_hdl_fb);
1936 v4l2_ctrl_handler_free(&dev->ctrl_hdl_meta_cap);
1937 v4l2_ctrl_handler_free(&dev->ctrl_hdl_meta_out);
1938 v4l2_ctrl_handler_free(&dev->ctrl_hdl_touch_cap);