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 dev
->disconnect_error
= true;
111 if (dev
->has_vid_cap
)
112 clear_bit(V4L2_FL_REGISTERED
, &dev
->vid_cap_dev
.flags
);
113 if (dev
->has_vid_out
)
114 clear_bit(V4L2_FL_REGISTERED
, &dev
->vid_out_dev
.flags
);
115 if (dev
->has_vbi_cap
)
116 clear_bit(V4L2_FL_REGISTERED
, &dev
->vbi_cap_dev
.flags
);
117 if (dev
->has_vbi_out
)
118 clear_bit(V4L2_FL_REGISTERED
, &dev
->vbi_out_dev
.flags
);
119 if (dev
->has_radio_rx
)
120 clear_bit(V4L2_FL_REGISTERED
, &dev
->radio_rx_dev
.flags
);
121 if (dev
->has_radio_tx
)
122 clear_bit(V4L2_FL_REGISTERED
, &dev
->radio_tx_dev
.flags
);
123 if (dev
->has_sdr_cap
)
124 clear_bit(V4L2_FL_REGISTERED
, &dev
->sdr_cap_dev
.flags
);
125 if (dev
->has_meta_cap
)
126 clear_bit(V4L2_FL_REGISTERED
, &dev
->meta_cap_dev
.flags
);
127 if (dev
->has_meta_out
)
128 clear_bit(V4L2_FL_REGISTERED
, &dev
->meta_out_dev
.flags
);
129 if (dev
->has_touch_cap
)
130 clear_bit(V4L2_FL_REGISTERED
, &dev
->touch_cap_dev
.flags
);
132 case VIVID_CID_BUTTON
:
133 dev
->button_pressed
= 30;
139 static const struct v4l2_ctrl_ops vivid_user_gen_ctrl_ops
= {
140 .s_ctrl
= vivid_user_gen_s_ctrl
,
143 static const struct v4l2_ctrl_config vivid_ctrl_button
= {
144 .ops
= &vivid_user_gen_ctrl_ops
,
145 .id
= VIVID_CID_BUTTON
,
147 .type
= V4L2_CTRL_TYPE_BUTTON
,
150 static const struct v4l2_ctrl_config vivid_ctrl_boolean
= {
151 .ops
= &vivid_user_gen_ctrl_ops
,
152 .id
= VIVID_CID_BOOLEAN
,
154 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
161 static const struct v4l2_ctrl_config vivid_ctrl_int32
= {
162 .ops
= &vivid_user_gen_ctrl_ops
,
163 .id
= VIVID_CID_INTEGER
,
164 .name
= "Integer 32 Bits",
165 .type
= V4L2_CTRL_TYPE_INTEGER
,
166 .min
= 0xffffffff80000000ULL
,
171 static const struct v4l2_ctrl_config vivid_ctrl_int64
= {
172 .ops
= &vivid_user_gen_ctrl_ops
,
173 .id
= VIVID_CID_INTEGER64
,
174 .name
= "Integer 64 Bits",
175 .type
= V4L2_CTRL_TYPE_INTEGER64
,
176 .min
= 0x8000000000000000ULL
,
177 .max
= 0x7fffffffffffffffLL
,
181 static const struct v4l2_ctrl_config vivid_ctrl_u32_array
= {
182 .ops
= &vivid_user_gen_ctrl_ops
,
183 .id
= VIVID_CID_U32_ARRAY
,
184 .name
= "U32 1 Element Array",
185 .type
= V4L2_CTRL_TYPE_U32
,
193 static const struct v4l2_ctrl_config vivid_ctrl_u16_matrix
= {
194 .ops
= &vivid_user_gen_ctrl_ops
,
195 .id
= VIVID_CID_U16_MATRIX
,
196 .name
= "U16 8x16 Matrix",
197 .type
= V4L2_CTRL_TYPE_U16
,
205 static const struct v4l2_ctrl_config vivid_ctrl_u8_4d_array
= {
206 .ops
= &vivid_user_gen_ctrl_ops
,
207 .id
= VIVID_CID_U8_4D_ARRAY
,
208 .name
= "U8 2x3x4x5 Array",
209 .type
= V4L2_CTRL_TYPE_U8
,
214 .dims
= { 2, 3, 4, 5 },
217 static const char * const vivid_ctrl_menu_strings
[] = {
218 "Menu Item 0 (Skipped)",
220 "Menu Item 2 (Skipped)",
223 "Menu Item 5 (Skipped)",
227 static const struct v4l2_ctrl_config vivid_ctrl_menu
= {
228 .ops
= &vivid_user_gen_ctrl_ops
,
229 .id
= VIVID_CID_MENU
,
231 .type
= V4L2_CTRL_TYPE_MENU
,
235 .menu_skip_mask
= 0x04,
236 .qmenu
= vivid_ctrl_menu_strings
,
239 static const struct v4l2_ctrl_config vivid_ctrl_string
= {
240 .ops
= &vivid_user_gen_ctrl_ops
,
241 .id
= VIVID_CID_STRING
,
243 .type
= V4L2_CTRL_TYPE_STRING
,
249 static const struct v4l2_ctrl_config vivid_ctrl_bitmask
= {
250 .ops
= &vivid_user_gen_ctrl_ops
,
251 .id
= VIVID_CID_BITMASK
,
253 .type
= V4L2_CTRL_TYPE_BITMASK
,
260 static const s64 vivid_ctrl_int_menu_values
[] = {
261 1, 1, 2, 3, 5, 8, 13, 21, 42,
264 static const struct v4l2_ctrl_config vivid_ctrl_int_menu
= {
265 .ops
= &vivid_user_gen_ctrl_ops
,
266 .id
= VIVID_CID_INTMENU
,
267 .name
= "Integer Menu",
268 .type
= V4L2_CTRL_TYPE_INTEGER_MENU
,
272 .menu_skip_mask
= 0x02,
273 .qmenu_int
= vivid_ctrl_int_menu_values
,
276 static const struct v4l2_ctrl_config vivid_ctrl_disconnect
= {
277 .ops
= &vivid_user_gen_ctrl_ops
,
278 .id
= VIVID_CID_DISCONNECT
,
279 .name
= "Disconnect",
280 .type
= V4L2_CTRL_TYPE_BUTTON
,
283 static const struct v4l2_area area
= {
288 static const struct v4l2_ctrl_config vivid_ctrl_area
= {
289 .ops
= &vivid_user_gen_ctrl_ops
,
290 .id
= VIVID_CID_AREA
,
292 .type
= V4L2_CTRL_TYPE_AREA
,
293 .p_def
.p_const
= &area
,
296 /* Framebuffer Controls */
298 static int vivid_fb_s_ctrl(struct v4l2_ctrl
*ctrl
)
300 struct vivid_dev
*dev
= container_of(ctrl
->handler
,
301 struct vivid_dev
, ctrl_hdl_fb
);
304 case VIVID_CID_CLEAR_FB
:
311 static const struct v4l2_ctrl_ops vivid_fb_ctrl_ops
= {
312 .s_ctrl
= vivid_fb_s_ctrl
,
315 static const struct v4l2_ctrl_config vivid_ctrl_clear_fb
= {
316 .ops
= &vivid_fb_ctrl_ops
,
317 .id
= VIVID_CID_CLEAR_FB
,
318 .name
= "Clear Framebuffer",
319 .type
= V4L2_CTRL_TYPE_BUTTON
,
323 /* Video User Controls */
325 static int vivid_user_vid_g_volatile_ctrl(struct v4l2_ctrl
*ctrl
)
327 struct vivid_dev
*dev
= container_of(ctrl
->handler
, struct vivid_dev
, ctrl_hdl_user_vid
);
330 case V4L2_CID_AUTOGAIN
:
331 dev
->gain
->val
= (jiffies_to_msecs(jiffies
) / 1000) & 0xff;
337 static int vivid_user_vid_s_ctrl(struct v4l2_ctrl
*ctrl
)
339 struct vivid_dev
*dev
= container_of(ctrl
->handler
, struct vivid_dev
, ctrl_hdl_user_vid
);
342 case V4L2_CID_BRIGHTNESS
:
343 dev
->input_brightness
[dev
->input
] = ctrl
->val
- dev
->input
* 128;
344 tpg_s_brightness(&dev
->tpg
, dev
->input_brightness
[dev
->input
]);
346 case V4L2_CID_CONTRAST
:
347 tpg_s_contrast(&dev
->tpg
, ctrl
->val
);
349 case V4L2_CID_SATURATION
:
350 tpg_s_saturation(&dev
->tpg
, ctrl
->val
);
353 tpg_s_hue(&dev
->tpg
, ctrl
->val
);
356 dev
->hflip
= ctrl
->val
;
357 tpg_s_hflip(&dev
->tpg
, dev
->sensor_hflip
^ dev
->hflip
);
360 dev
->vflip
= ctrl
->val
;
361 tpg_s_vflip(&dev
->tpg
, dev
->sensor_vflip
^ dev
->vflip
);
363 case V4L2_CID_ALPHA_COMPONENT
:
364 tpg_s_alpha_component(&dev
->tpg
, ctrl
->val
);
370 static const struct v4l2_ctrl_ops vivid_user_vid_ctrl_ops
= {
371 .g_volatile_ctrl
= vivid_user_vid_g_volatile_ctrl
,
372 .s_ctrl
= vivid_user_vid_s_ctrl
,
376 /* Video Capture Controls */
378 static int vivid_vid_cap_s_ctrl(struct v4l2_ctrl
*ctrl
)
380 static const u32 colorspaces
[] = {
381 V4L2_COLORSPACE_SMPTE170M
,
382 V4L2_COLORSPACE_REC709
,
383 V4L2_COLORSPACE_SRGB
,
384 V4L2_COLORSPACE_OPRGB
,
385 V4L2_COLORSPACE_BT2020
,
386 V4L2_COLORSPACE_DCI_P3
,
387 V4L2_COLORSPACE_SMPTE240M
,
388 V4L2_COLORSPACE_470_SYSTEM_M
,
389 V4L2_COLORSPACE_470_SYSTEM_BG
,
391 struct vivid_dev
*dev
= container_of(ctrl
->handler
, struct vivid_dev
, ctrl_hdl_vid_cap
);
395 case VIVID_CID_TEST_PATTERN
:
396 vivid_update_quality(dev
);
397 tpg_s_pattern(&dev
->tpg
, ctrl
->val
);
399 case VIVID_CID_COLORSPACE
:
400 tpg_s_colorspace(&dev
->tpg
, colorspaces
[ctrl
->val
]);
401 vivid_send_source_change(dev
, TV
);
402 vivid_send_source_change(dev
, SVID
);
403 vivid_send_source_change(dev
, HDMI
);
404 vivid_send_source_change(dev
, WEBCAM
);
406 case VIVID_CID_XFER_FUNC
:
407 tpg_s_xfer_func(&dev
->tpg
, ctrl
->val
);
408 vivid_send_source_change(dev
, TV
);
409 vivid_send_source_change(dev
, SVID
);
410 vivid_send_source_change(dev
, HDMI
);
411 vivid_send_source_change(dev
, WEBCAM
);
413 case VIVID_CID_YCBCR_ENC
:
414 tpg_s_ycbcr_enc(&dev
->tpg
, ctrl
->val
);
415 vivid_send_source_change(dev
, TV
);
416 vivid_send_source_change(dev
, SVID
);
417 vivid_send_source_change(dev
, HDMI
);
418 vivid_send_source_change(dev
, WEBCAM
);
420 case VIVID_CID_HSV_ENC
:
421 tpg_s_hsv_enc(&dev
->tpg
, ctrl
->val
? V4L2_HSV_ENC_256
:
423 vivid_send_source_change(dev
, TV
);
424 vivid_send_source_change(dev
, SVID
);
425 vivid_send_source_change(dev
, HDMI
);
426 vivid_send_source_change(dev
, WEBCAM
);
428 case VIVID_CID_QUANTIZATION
:
429 tpg_s_quantization(&dev
->tpg
, ctrl
->val
);
430 vivid_send_source_change(dev
, TV
);
431 vivid_send_source_change(dev
, SVID
);
432 vivid_send_source_change(dev
, HDMI
);
433 vivid_send_source_change(dev
, WEBCAM
);
435 case V4L2_CID_DV_RX_RGB_RANGE
:
436 if (!vivid_is_hdmi_cap(dev
))
438 tpg_s_rgb_range(&dev
->tpg
, ctrl
->val
);
440 case VIVID_CID_LIMITED_RGB_RANGE
:
441 tpg_s_real_rgb_range(&dev
->tpg
, ctrl
->val
?
442 V4L2_DV_RGB_RANGE_LIMITED
: V4L2_DV_RGB_RANGE_FULL
);
444 case VIVID_CID_ALPHA_MODE
:
445 tpg_s_alpha_mode(&dev
->tpg
, ctrl
->val
);
447 case VIVID_CID_HOR_MOVEMENT
:
448 tpg_s_mv_hor_mode(&dev
->tpg
, ctrl
->val
);
450 case VIVID_CID_VERT_MOVEMENT
:
451 tpg_s_mv_vert_mode(&dev
->tpg
, ctrl
->val
);
453 case VIVID_CID_OSD_TEXT_MODE
:
454 dev
->osd_mode
= ctrl
->val
;
456 case VIVID_CID_PERCENTAGE_FILL
:
457 tpg_s_perc_fill(&dev
->tpg
, ctrl
->val
);
458 for (i
= 0; i
< VIDEO_MAX_FRAME
; i
++)
459 dev
->must_blank
[i
] = ctrl
->val
< 100;
461 case VIVID_CID_INSERT_SAV
:
462 tpg_s_insert_sav(&dev
->tpg
, ctrl
->val
);
464 case VIVID_CID_INSERT_EAV
:
465 tpg_s_insert_eav(&dev
->tpg
, ctrl
->val
);
467 case VIVID_CID_HFLIP
:
468 dev
->sensor_hflip
= ctrl
->val
;
469 tpg_s_hflip(&dev
->tpg
, dev
->sensor_hflip
^ dev
->hflip
);
471 case VIVID_CID_VFLIP
:
472 dev
->sensor_vflip
= ctrl
->val
;
473 tpg_s_vflip(&dev
->tpg
, dev
->sensor_vflip
^ dev
->vflip
);
475 case VIVID_CID_REDUCED_FPS
:
476 dev
->reduced_fps
= ctrl
->val
;
477 vivid_update_format_cap(dev
, true);
479 case VIVID_CID_HAS_CROP_CAP
:
480 dev
->has_crop_cap
= ctrl
->val
;
481 vivid_update_format_cap(dev
, true);
483 case VIVID_CID_HAS_COMPOSE_CAP
:
484 dev
->has_compose_cap
= ctrl
->val
;
485 vivid_update_format_cap(dev
, true);
487 case VIVID_CID_HAS_SCALER_CAP
:
488 dev
->has_scaler_cap
= ctrl
->val
;
489 vivid_update_format_cap(dev
, true);
491 case VIVID_CID_SHOW_BORDER
:
492 tpg_s_show_border(&dev
->tpg
, ctrl
->val
);
494 case VIVID_CID_SHOW_SQUARE
:
495 tpg_s_show_square(&dev
->tpg
, ctrl
->val
);
497 case VIVID_CID_STD_ASPECT_RATIO
:
498 dev
->std_aspect_ratio
[dev
->input
] = ctrl
->val
;
499 tpg_s_video_aspect(&dev
->tpg
, vivid_get_video_aspect(dev
));
501 case VIVID_CID_DV_TIMINGS_SIGNAL_MODE
:
502 dev
->dv_timings_signal_mode
[dev
->input
] =
503 dev
->ctrl_dv_timings_signal_mode
->val
;
504 dev
->query_dv_timings
[dev
->input
] = dev
->ctrl_dv_timings
->val
;
506 dev
->power_present
= 0;
508 i
< ARRAY_SIZE(dev
->dv_timings_signal_mode
);
510 if (dev
->input_type
[i
] == HDMI
) {
511 if (dev
->dv_timings_signal_mode
[i
] != NO_SIGNAL
)
512 dev
->power_present
|= (1 << j
);
515 __v4l2_ctrl_s_ctrl(dev
->ctrl_rx_power_present
,
518 v4l2_ctrl_activate(dev
->ctrl_dv_timings
,
519 dev
->dv_timings_signal_mode
[dev
->input
] ==
520 SELECTED_DV_TIMINGS
);
522 vivid_update_quality(dev
);
523 vivid_send_source_change(dev
, HDMI
);
525 case VIVID_CID_DV_TIMINGS_ASPECT_RATIO
:
526 dev
->dv_timings_aspect_ratio
[dev
->input
] = ctrl
->val
;
527 tpg_s_video_aspect(&dev
->tpg
, vivid_get_video_aspect(dev
));
529 case VIVID_CID_TSTAMP_SRC
:
530 dev
->tstamp_src_is_soe
= ctrl
->val
;
531 dev
->vb_vid_cap_q
.timestamp_flags
&= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK
;
532 if (dev
->tstamp_src_is_soe
)
533 dev
->vb_vid_cap_q
.timestamp_flags
|= V4L2_BUF_FLAG_TSTAMP_SRC_SOE
;
535 case VIVID_CID_MAX_EDID_BLOCKS
:
536 dev
->edid_max_blocks
= ctrl
->val
;
537 if (dev
->edid_blocks
> dev
->edid_max_blocks
)
538 dev
->edid_blocks
= dev
->edid_max_blocks
;
544 static const struct v4l2_ctrl_ops vivid_vid_cap_ctrl_ops
= {
545 .s_ctrl
= vivid_vid_cap_s_ctrl
,
548 static const char * const vivid_ctrl_hor_movement_strings
[] = {
559 static const struct v4l2_ctrl_config vivid_ctrl_hor_movement
= {
560 .ops
= &vivid_vid_cap_ctrl_ops
,
561 .id
= VIVID_CID_HOR_MOVEMENT
,
562 .name
= "Horizontal Movement",
563 .type
= V4L2_CTRL_TYPE_MENU
,
564 .max
= TPG_MOVE_POS_FAST
,
565 .def
= TPG_MOVE_NONE
,
566 .qmenu
= vivid_ctrl_hor_movement_strings
,
569 static const char * const vivid_ctrl_vert_movement_strings
[] = {
580 static const struct v4l2_ctrl_config vivid_ctrl_vert_movement
= {
581 .ops
= &vivid_vid_cap_ctrl_ops
,
582 .id
= VIVID_CID_VERT_MOVEMENT
,
583 .name
= "Vertical Movement",
584 .type
= V4L2_CTRL_TYPE_MENU
,
585 .max
= TPG_MOVE_POS_FAST
,
586 .def
= TPG_MOVE_NONE
,
587 .qmenu
= vivid_ctrl_vert_movement_strings
,
590 static const struct v4l2_ctrl_config vivid_ctrl_show_border
= {
591 .ops
= &vivid_vid_cap_ctrl_ops
,
592 .id
= VIVID_CID_SHOW_BORDER
,
593 .name
= "Show Border",
594 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
599 static const struct v4l2_ctrl_config vivid_ctrl_show_square
= {
600 .ops
= &vivid_vid_cap_ctrl_ops
,
601 .id
= VIVID_CID_SHOW_SQUARE
,
602 .name
= "Show Square",
603 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
608 static const char * const vivid_ctrl_osd_mode_strings
[] = {
615 static const struct v4l2_ctrl_config vivid_ctrl_osd_mode
= {
616 .ops
= &vivid_vid_cap_ctrl_ops
,
617 .id
= VIVID_CID_OSD_TEXT_MODE
,
618 .name
= "OSD Text Mode",
619 .type
= V4L2_CTRL_TYPE_MENU
,
620 .max
= ARRAY_SIZE(vivid_ctrl_osd_mode_strings
) - 2,
621 .qmenu
= vivid_ctrl_osd_mode_strings
,
624 static const struct v4l2_ctrl_config vivid_ctrl_perc_fill
= {
625 .ops
= &vivid_vid_cap_ctrl_ops
,
626 .id
= VIVID_CID_PERCENTAGE_FILL
,
627 .name
= "Fill Percentage of Frame",
628 .type
= V4L2_CTRL_TYPE_INTEGER
,
635 static const struct v4l2_ctrl_config vivid_ctrl_insert_sav
= {
636 .ops
= &vivid_vid_cap_ctrl_ops
,
637 .id
= VIVID_CID_INSERT_SAV
,
638 .name
= "Insert SAV Code in Image",
639 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
644 static const struct v4l2_ctrl_config vivid_ctrl_insert_eav
= {
645 .ops
= &vivid_vid_cap_ctrl_ops
,
646 .id
= VIVID_CID_INSERT_EAV
,
647 .name
= "Insert EAV Code in Image",
648 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
653 static const struct v4l2_ctrl_config vivid_ctrl_hflip
= {
654 .ops
= &vivid_vid_cap_ctrl_ops
,
655 .id
= VIVID_CID_HFLIP
,
656 .name
= "Sensor Flipped Horizontally",
657 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
662 static const struct v4l2_ctrl_config vivid_ctrl_vflip
= {
663 .ops
= &vivid_vid_cap_ctrl_ops
,
664 .id
= VIVID_CID_VFLIP
,
665 .name
= "Sensor Flipped Vertically",
666 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
671 static const struct v4l2_ctrl_config vivid_ctrl_reduced_fps
= {
672 .ops
= &vivid_vid_cap_ctrl_ops
,
673 .id
= VIVID_CID_REDUCED_FPS
,
674 .name
= "Reduced Framerate",
675 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
680 static const struct v4l2_ctrl_config vivid_ctrl_has_crop_cap
= {
681 .ops
= &vivid_vid_cap_ctrl_ops
,
682 .id
= VIVID_CID_HAS_CROP_CAP
,
683 .name
= "Enable Capture Cropping",
684 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
690 static const struct v4l2_ctrl_config vivid_ctrl_has_compose_cap
= {
691 .ops
= &vivid_vid_cap_ctrl_ops
,
692 .id
= VIVID_CID_HAS_COMPOSE_CAP
,
693 .name
= "Enable Capture Composing",
694 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
700 static const struct v4l2_ctrl_config vivid_ctrl_has_scaler_cap
= {
701 .ops
= &vivid_vid_cap_ctrl_ops
,
702 .id
= VIVID_CID_HAS_SCALER_CAP
,
703 .name
= "Enable Capture Scaler",
704 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
710 static const char * const vivid_ctrl_tstamp_src_strings
[] = {
716 static const struct v4l2_ctrl_config vivid_ctrl_tstamp_src
= {
717 .ops
= &vivid_vid_cap_ctrl_ops
,
718 .id
= VIVID_CID_TSTAMP_SRC
,
719 .name
= "Timestamp Source",
720 .type
= V4L2_CTRL_TYPE_MENU
,
721 .max
= ARRAY_SIZE(vivid_ctrl_tstamp_src_strings
) - 2,
722 .qmenu
= vivid_ctrl_tstamp_src_strings
,
725 static const struct v4l2_ctrl_config vivid_ctrl_std_aspect_ratio
= {
726 .ops
= &vivid_vid_cap_ctrl_ops
,
727 .id
= VIVID_CID_STD_ASPECT_RATIO
,
728 .name
= "Standard Aspect Ratio",
729 .type
= V4L2_CTRL_TYPE_MENU
,
733 .qmenu
= tpg_aspect_strings
,
736 static const char * const vivid_ctrl_dv_timings_signal_mode_strings
[] = {
737 "Current DV Timings",
741 "Selected DV Timings",
742 "Cycle Through All DV Timings",
747 static const struct v4l2_ctrl_config vivid_ctrl_dv_timings_signal_mode
= {
748 .ops
= &vivid_vid_cap_ctrl_ops
,
749 .id
= VIVID_CID_DV_TIMINGS_SIGNAL_MODE
,
750 .name
= "DV Timings Signal Mode",
751 .type
= V4L2_CTRL_TYPE_MENU
,
753 .qmenu
= vivid_ctrl_dv_timings_signal_mode_strings
,
756 static const struct v4l2_ctrl_config vivid_ctrl_dv_timings_aspect_ratio
= {
757 .ops
= &vivid_vid_cap_ctrl_ops
,
758 .id
= VIVID_CID_DV_TIMINGS_ASPECT_RATIO
,
759 .name
= "DV Timings Aspect Ratio",
760 .type
= V4L2_CTRL_TYPE_MENU
,
762 .qmenu
= tpg_aspect_strings
,
765 static const struct v4l2_ctrl_config vivid_ctrl_max_edid_blocks
= {
766 .ops
= &vivid_vid_cap_ctrl_ops
,
767 .id
= VIVID_CID_MAX_EDID_BLOCKS
,
768 .name
= "Maximum EDID Blocks",
769 .type
= V4L2_CTRL_TYPE_INTEGER
,
776 static const char * const vivid_ctrl_colorspace_strings
[] = {
789 static const struct v4l2_ctrl_config vivid_ctrl_colorspace
= {
790 .ops
= &vivid_vid_cap_ctrl_ops
,
791 .id
= VIVID_CID_COLORSPACE
,
792 .name
= "Colorspace",
793 .type
= V4L2_CTRL_TYPE_MENU
,
794 .max
= ARRAY_SIZE(vivid_ctrl_colorspace_strings
) - 2,
796 .qmenu
= vivid_ctrl_colorspace_strings
,
799 static const char * const vivid_ctrl_xfer_func_strings
[] = {
811 static const struct v4l2_ctrl_config vivid_ctrl_xfer_func
= {
812 .ops
= &vivid_vid_cap_ctrl_ops
,
813 .id
= VIVID_CID_XFER_FUNC
,
814 .name
= "Transfer Function",
815 .type
= V4L2_CTRL_TYPE_MENU
,
816 .max
= ARRAY_SIZE(vivid_ctrl_xfer_func_strings
) - 2,
817 .qmenu
= vivid_ctrl_xfer_func_strings
,
820 static const char * const vivid_ctrl_ycbcr_enc_strings
[] = {
828 "BT.2020 Constant Luminance",
833 static const struct v4l2_ctrl_config vivid_ctrl_ycbcr_enc
= {
834 .ops
= &vivid_vid_cap_ctrl_ops
,
835 .id
= VIVID_CID_YCBCR_ENC
,
836 .name
= "Y'CbCr Encoding",
837 .type
= V4L2_CTRL_TYPE_MENU
,
838 .menu_skip_mask
= 1 << 5,
839 .max
= ARRAY_SIZE(vivid_ctrl_ycbcr_enc_strings
) - 2,
840 .qmenu
= vivid_ctrl_ycbcr_enc_strings
,
843 static const char * const vivid_ctrl_hsv_enc_strings
[] = {
849 static const struct v4l2_ctrl_config vivid_ctrl_hsv_enc
= {
850 .ops
= &vivid_vid_cap_ctrl_ops
,
851 .id
= VIVID_CID_HSV_ENC
,
852 .name
= "HSV Encoding",
853 .type
= V4L2_CTRL_TYPE_MENU
,
854 .max
= ARRAY_SIZE(vivid_ctrl_hsv_enc_strings
) - 2,
855 .qmenu
= vivid_ctrl_hsv_enc_strings
,
858 static const char * const vivid_ctrl_quantization_strings
[] = {
865 static const struct v4l2_ctrl_config vivid_ctrl_quantization
= {
866 .ops
= &vivid_vid_cap_ctrl_ops
,
867 .id
= VIVID_CID_QUANTIZATION
,
868 .name
= "Quantization",
869 .type
= V4L2_CTRL_TYPE_MENU
,
870 .max
= ARRAY_SIZE(vivid_ctrl_quantization_strings
) - 2,
871 .qmenu
= vivid_ctrl_quantization_strings
,
874 static const struct v4l2_ctrl_config vivid_ctrl_alpha_mode
= {
875 .ops
= &vivid_vid_cap_ctrl_ops
,
876 .id
= VIVID_CID_ALPHA_MODE
,
877 .name
= "Apply Alpha To Red Only",
878 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
883 static const struct v4l2_ctrl_config vivid_ctrl_limited_rgb_range
= {
884 .ops
= &vivid_vid_cap_ctrl_ops
,
885 .id
= VIVID_CID_LIMITED_RGB_RANGE
,
886 .name
= "Limited RGB Range (16-235)",
887 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
893 /* Video Loop Control */
895 static int vivid_loop_cap_s_ctrl(struct v4l2_ctrl
*ctrl
)
897 struct vivid_dev
*dev
= container_of(ctrl
->handler
, struct vivid_dev
, ctrl_hdl_loop_cap
);
900 case VIVID_CID_LOOP_VIDEO
:
901 dev
->loop_video
= ctrl
->val
;
902 vivid_update_quality(dev
);
903 vivid_send_source_change(dev
, SVID
);
904 vivid_send_source_change(dev
, HDMI
);
910 static const struct v4l2_ctrl_ops vivid_loop_cap_ctrl_ops
= {
911 .s_ctrl
= vivid_loop_cap_s_ctrl
,
914 static const struct v4l2_ctrl_config vivid_ctrl_loop_video
= {
915 .ops
= &vivid_loop_cap_ctrl_ops
,
916 .id
= VIVID_CID_LOOP_VIDEO
,
917 .name
= "Loop Video",
918 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
924 /* VBI Capture Control */
926 static int vivid_vbi_cap_s_ctrl(struct v4l2_ctrl
*ctrl
)
928 struct vivid_dev
*dev
= container_of(ctrl
->handler
, struct vivid_dev
, ctrl_hdl_vbi_cap
);
931 case VIVID_CID_VBI_CAP_INTERLACED
:
932 dev
->vbi_cap_interlaced
= ctrl
->val
;
938 static const struct v4l2_ctrl_ops vivid_vbi_cap_ctrl_ops
= {
939 .s_ctrl
= vivid_vbi_cap_s_ctrl
,
942 static const struct v4l2_ctrl_config vivid_ctrl_vbi_cap_interlaced
= {
943 .ops
= &vivid_vbi_cap_ctrl_ops
,
944 .id
= VIVID_CID_VBI_CAP_INTERLACED
,
945 .name
= "Interlaced VBI Format",
946 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
952 /* Video Output Controls */
954 static int vivid_vid_out_s_ctrl(struct v4l2_ctrl
*ctrl
)
956 struct vivid_dev
*dev
= container_of(ctrl
->handler
, struct vivid_dev
, ctrl_hdl_vid_out
);
957 struct v4l2_bt_timings
*bt
= &dev
->dv_timings_out
.bt
;
958 u32 display_present
= 0;
959 unsigned int i
, j
, bus_idx
;
962 case VIVID_CID_HAS_CROP_OUT
:
963 dev
->has_crop_out
= ctrl
->val
;
964 vivid_update_format_out(dev
);
966 case VIVID_CID_HAS_COMPOSE_OUT
:
967 dev
->has_compose_out
= ctrl
->val
;
968 vivid_update_format_out(dev
);
970 case VIVID_CID_HAS_SCALER_OUT
:
971 dev
->has_scaler_out
= ctrl
->val
;
972 vivid_update_format_out(dev
);
974 case V4L2_CID_DV_TX_MODE
:
975 dev
->dvi_d_out
= ctrl
->val
== V4L2_DV_TX_MODE_DVI_D
;
976 if (!vivid_is_hdmi_out(dev
))
978 if (!dev
->dvi_d_out
&& (bt
->flags
& V4L2_DV_FL_IS_CE_VIDEO
)) {
979 if (bt
->width
== 720 && bt
->height
<= 576)
980 dev
->colorspace_out
= V4L2_COLORSPACE_SMPTE170M
;
982 dev
->colorspace_out
= V4L2_COLORSPACE_REC709
;
983 dev
->quantization_out
= V4L2_QUANTIZATION_DEFAULT
;
985 dev
->colorspace_out
= V4L2_COLORSPACE_SRGB
;
986 dev
->quantization_out
= dev
->dvi_d_out
?
987 V4L2_QUANTIZATION_LIM_RANGE
:
988 V4L2_QUANTIZATION_DEFAULT
;
991 vivid_send_source_change(dev
, HDMI
);
993 case VIVID_CID_DISPLAY_PRESENT
:
994 if (dev
->output_type
[dev
->output
] != HDMI
)
997 dev
->display_present
[dev
->output
] = ctrl
->val
;
998 for (i
= 0, j
= 0; i
< dev
->num_outputs
; i
++)
999 if (dev
->output_type
[i
] == HDMI
)
1001 dev
->display_present
[i
] << j
++;
1003 __v4l2_ctrl_s_ctrl(dev
->ctrl_tx_rxsense
, display_present
);
1005 if (dev
->edid_blocks
) {
1006 __v4l2_ctrl_s_ctrl(dev
->ctrl_tx_edid_present
,
1008 __v4l2_ctrl_s_ctrl(dev
->ctrl_tx_hotplug
,
1012 bus_idx
= dev
->cec_output2bus_map
[dev
->output
];
1013 if (!dev
->cec_tx_adap
[bus_idx
])
1016 if (ctrl
->val
&& dev
->edid_blocks
)
1017 cec_s_phys_addr(dev
->cec_tx_adap
[bus_idx
],
1018 dev
->cec_tx_adap
[bus_idx
]->phys_addr
,
1021 cec_phys_addr_invalidate(dev
->cec_tx_adap
[bus_idx
]);
1028 static const struct v4l2_ctrl_ops vivid_vid_out_ctrl_ops
= {
1029 .s_ctrl
= vivid_vid_out_s_ctrl
,
1032 static const struct v4l2_ctrl_config vivid_ctrl_has_crop_out
= {
1033 .ops
= &vivid_vid_out_ctrl_ops
,
1034 .id
= VIVID_CID_HAS_CROP_OUT
,
1035 .name
= "Enable Output Cropping",
1036 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
1042 static const struct v4l2_ctrl_config vivid_ctrl_has_compose_out
= {
1043 .ops
= &vivid_vid_out_ctrl_ops
,
1044 .id
= VIVID_CID_HAS_COMPOSE_OUT
,
1045 .name
= "Enable Output Composing",
1046 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
1052 static const struct v4l2_ctrl_config vivid_ctrl_has_scaler_out
= {
1053 .ops
= &vivid_vid_out_ctrl_ops
,
1054 .id
= VIVID_CID_HAS_SCALER_OUT
,
1055 .name
= "Enable Output Scaler",
1056 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
1062 static const struct v4l2_ctrl_config vivid_ctrl_display_present
= {
1063 .ops
= &vivid_vid_out_ctrl_ops
,
1064 .id
= VIVID_CID_DISPLAY_PRESENT
,
1065 .name
= "Display Present",
1066 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
1072 /* Streaming Controls */
1074 static int vivid_streaming_s_ctrl(struct v4l2_ctrl
*ctrl
)
1076 struct vivid_dev
*dev
= container_of(ctrl
->handler
, struct vivid_dev
, ctrl_hdl_streaming
);
1080 case VIVID_CID_DQBUF_ERROR
:
1081 dev
->dqbuf_error
= true;
1083 case VIVID_CID_PERC_DROPPED
:
1084 dev
->perc_dropped_buffers
= ctrl
->val
;
1086 case VIVID_CID_QUEUE_SETUP_ERROR
:
1087 dev
->queue_setup_error
= true;
1089 case VIVID_CID_BUF_PREPARE_ERROR
:
1090 dev
->buf_prepare_error
= true;
1092 case VIVID_CID_START_STR_ERROR
:
1093 dev
->start_streaming_error
= true;
1095 case VIVID_CID_REQ_VALIDATE_ERROR
:
1096 dev
->req_validate_error
= true;
1098 case VIVID_CID_QUEUE_ERROR
:
1099 if (vb2_start_streaming_called(&dev
->vb_vid_cap_q
))
1100 vb2_queue_error(&dev
->vb_vid_cap_q
);
1101 if (vb2_start_streaming_called(&dev
->vb_vbi_cap_q
))
1102 vb2_queue_error(&dev
->vb_vbi_cap_q
);
1103 if (vb2_start_streaming_called(&dev
->vb_vid_out_q
))
1104 vb2_queue_error(&dev
->vb_vid_out_q
);
1105 if (vb2_start_streaming_called(&dev
->vb_vbi_out_q
))
1106 vb2_queue_error(&dev
->vb_vbi_out_q
);
1107 if (vb2_start_streaming_called(&dev
->vb_sdr_cap_q
))
1108 vb2_queue_error(&dev
->vb_sdr_cap_q
);
1110 case VIVID_CID_SEQ_WRAP
:
1111 dev
->seq_wrap
= ctrl
->val
;
1113 case VIVID_CID_TIME_WRAP
:
1114 dev
->time_wrap
= ctrl
->val
;
1115 if (ctrl
->val
== 0) {
1116 dev
->time_wrap_offset
= 0;
1120 * We want to set the time 16 seconds before the 32 bit tv_sec
1121 * value of struct timeval would wrap around. So first we
1122 * calculate ktime_get_ns() % ((1 << 32) * NSEC_PER_SEC), and
1123 * then we set the offset to ((1 << 32) - 16) * NSEC_PER_SEC).
1125 div64_u64_rem(ktime_get_ns(),
1126 0x100000000ULL
* NSEC_PER_SEC
, &rem
);
1127 dev
->time_wrap_offset
=
1128 (0x100000000ULL
- 16) * NSEC_PER_SEC
- rem
;
1134 static const struct v4l2_ctrl_ops vivid_streaming_ctrl_ops
= {
1135 .s_ctrl
= vivid_streaming_s_ctrl
,
1138 static const struct v4l2_ctrl_config vivid_ctrl_dqbuf_error
= {
1139 .ops
= &vivid_streaming_ctrl_ops
,
1140 .id
= VIVID_CID_DQBUF_ERROR
,
1141 .name
= "Inject V4L2_BUF_FLAG_ERROR",
1142 .type
= V4L2_CTRL_TYPE_BUTTON
,
1145 static const struct v4l2_ctrl_config vivid_ctrl_perc_dropped
= {
1146 .ops
= &vivid_streaming_ctrl_ops
,
1147 .id
= VIVID_CID_PERC_DROPPED
,
1148 .name
= "Percentage of Dropped Buffers",
1149 .type
= V4L2_CTRL_TYPE_INTEGER
,
1155 static const struct v4l2_ctrl_config vivid_ctrl_queue_setup_error
= {
1156 .ops
= &vivid_streaming_ctrl_ops
,
1157 .id
= VIVID_CID_QUEUE_SETUP_ERROR
,
1158 .name
= "Inject VIDIOC_REQBUFS Error",
1159 .type
= V4L2_CTRL_TYPE_BUTTON
,
1162 static const struct v4l2_ctrl_config vivid_ctrl_buf_prepare_error
= {
1163 .ops
= &vivid_streaming_ctrl_ops
,
1164 .id
= VIVID_CID_BUF_PREPARE_ERROR
,
1165 .name
= "Inject VIDIOC_QBUF Error",
1166 .type
= V4L2_CTRL_TYPE_BUTTON
,
1169 static const struct v4l2_ctrl_config vivid_ctrl_start_streaming_error
= {
1170 .ops
= &vivid_streaming_ctrl_ops
,
1171 .id
= VIVID_CID_START_STR_ERROR
,
1172 .name
= "Inject VIDIOC_STREAMON Error",
1173 .type
= V4L2_CTRL_TYPE_BUTTON
,
1176 static const struct v4l2_ctrl_config vivid_ctrl_queue_error
= {
1177 .ops
= &vivid_streaming_ctrl_ops
,
1178 .id
= VIVID_CID_QUEUE_ERROR
,
1179 .name
= "Inject Fatal Streaming Error",
1180 .type
= V4L2_CTRL_TYPE_BUTTON
,
1183 #ifdef CONFIG_MEDIA_CONTROLLER
1184 static const struct v4l2_ctrl_config vivid_ctrl_req_validate_error
= {
1185 .ops
= &vivid_streaming_ctrl_ops
,
1186 .id
= VIVID_CID_REQ_VALIDATE_ERROR
,
1187 .name
= "Inject req_validate() Error",
1188 .type
= V4L2_CTRL_TYPE_BUTTON
,
1192 static const struct v4l2_ctrl_config vivid_ctrl_seq_wrap
= {
1193 .ops
= &vivid_streaming_ctrl_ops
,
1194 .id
= VIVID_CID_SEQ_WRAP
,
1195 .name
= "Wrap Sequence Number",
1196 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
1201 static const struct v4l2_ctrl_config vivid_ctrl_time_wrap
= {
1202 .ops
= &vivid_streaming_ctrl_ops
,
1203 .id
= VIVID_CID_TIME_WRAP
,
1204 .name
= "Wrap Timestamp",
1205 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
1211 /* SDTV Capture Controls */
1213 static int vivid_sdtv_cap_s_ctrl(struct v4l2_ctrl
*ctrl
)
1215 struct vivid_dev
*dev
= container_of(ctrl
->handler
, struct vivid_dev
, ctrl_hdl_sdtv_cap
);
1218 case VIVID_CID_STD_SIGNAL_MODE
:
1219 dev
->std_signal_mode
[dev
->input
] =
1220 dev
->ctrl_std_signal_mode
->val
;
1221 if (dev
->std_signal_mode
[dev
->input
] == SELECTED_STD
)
1222 dev
->query_std
[dev
->input
] =
1223 vivid_standard
[dev
->ctrl_standard
->val
];
1224 v4l2_ctrl_activate(dev
->ctrl_standard
,
1225 dev
->std_signal_mode
[dev
->input
] ==
1227 vivid_update_quality(dev
);
1228 vivid_send_source_change(dev
, TV
);
1229 vivid_send_source_change(dev
, SVID
);
1235 static const struct v4l2_ctrl_ops vivid_sdtv_cap_ctrl_ops
= {
1236 .s_ctrl
= vivid_sdtv_cap_s_ctrl
,
1239 static const char * const vivid_ctrl_std_signal_mode_strings
[] = {
1244 "Selected Standard",
1245 "Cycle Through All Standards",
1249 static const struct v4l2_ctrl_config vivid_ctrl_std_signal_mode
= {
1250 .ops
= &vivid_sdtv_cap_ctrl_ops
,
1251 .id
= VIVID_CID_STD_SIGNAL_MODE
,
1252 .name
= "Standard Signal Mode",
1253 .type
= V4L2_CTRL_TYPE_MENU
,
1254 .max
= ARRAY_SIZE(vivid_ctrl_std_signal_mode_strings
) - 2,
1255 .menu_skip_mask
= 1 << 3,
1256 .qmenu
= vivid_ctrl_std_signal_mode_strings
,
1259 static const struct v4l2_ctrl_config vivid_ctrl_standard
= {
1260 .ops
= &vivid_sdtv_cap_ctrl_ops
,
1261 .id
= VIVID_CID_STANDARD
,
1263 .type
= V4L2_CTRL_TYPE_MENU
,
1265 .qmenu
= vivid_ctrl_standard_strings
,
1270 /* Radio Receiver Controls */
1272 static int vivid_radio_rx_s_ctrl(struct v4l2_ctrl
*ctrl
)
1274 struct vivid_dev
*dev
= container_of(ctrl
->handler
, struct vivid_dev
, ctrl_hdl_radio_rx
);
1277 case VIVID_CID_RADIO_SEEK_MODE
:
1278 dev
->radio_rx_hw_seek_mode
= ctrl
->val
;
1280 case VIVID_CID_RADIO_SEEK_PROG_LIM
:
1281 dev
->radio_rx_hw_seek_prog_lim
= ctrl
->val
;
1283 case VIVID_CID_RADIO_RX_RDS_RBDS
:
1284 dev
->rds_gen
.use_rbds
= ctrl
->val
;
1286 case VIVID_CID_RADIO_RX_RDS_BLOCKIO
:
1287 dev
->radio_rx_rds_controls
= ctrl
->val
;
1288 dev
->radio_rx_caps
&= ~V4L2_CAP_READWRITE
;
1289 dev
->radio_rx_rds_use_alternates
= false;
1290 if (!dev
->radio_rx_rds_controls
) {
1291 dev
->radio_rx_caps
|= V4L2_CAP_READWRITE
;
1292 __v4l2_ctrl_s_ctrl(dev
->radio_rx_rds_pty
, 0);
1293 __v4l2_ctrl_s_ctrl(dev
->radio_rx_rds_ta
, 0);
1294 __v4l2_ctrl_s_ctrl(dev
->radio_rx_rds_tp
, 0);
1295 __v4l2_ctrl_s_ctrl(dev
->radio_rx_rds_ms
, 0);
1296 __v4l2_ctrl_s_ctrl_string(dev
->radio_rx_rds_psname
, "");
1297 __v4l2_ctrl_s_ctrl_string(dev
->radio_rx_rds_radiotext
, "");
1299 v4l2_ctrl_activate(dev
->radio_rx_rds_pty
, dev
->radio_rx_rds_controls
);
1300 v4l2_ctrl_activate(dev
->radio_rx_rds_psname
, dev
->radio_rx_rds_controls
);
1301 v4l2_ctrl_activate(dev
->radio_rx_rds_radiotext
, dev
->radio_rx_rds_controls
);
1302 v4l2_ctrl_activate(dev
->radio_rx_rds_ta
, dev
->radio_rx_rds_controls
);
1303 v4l2_ctrl_activate(dev
->radio_rx_rds_tp
, dev
->radio_rx_rds_controls
);
1304 v4l2_ctrl_activate(dev
->radio_rx_rds_ms
, dev
->radio_rx_rds_controls
);
1305 dev
->radio_rx_dev
.device_caps
= dev
->radio_rx_caps
;
1307 case V4L2_CID_RDS_RECEPTION
:
1308 dev
->radio_rx_rds_enabled
= ctrl
->val
;
1314 static const struct v4l2_ctrl_ops vivid_radio_rx_ctrl_ops
= {
1315 .s_ctrl
= vivid_radio_rx_s_ctrl
,
1318 static const char * const vivid_ctrl_radio_rds_mode_strings
[] = {
1324 static const struct v4l2_ctrl_config vivid_ctrl_radio_rx_rds_blockio
= {
1325 .ops
= &vivid_radio_rx_ctrl_ops
,
1326 .id
= VIVID_CID_RADIO_RX_RDS_BLOCKIO
,
1327 .name
= "RDS Rx I/O Mode",
1328 .type
= V4L2_CTRL_TYPE_MENU
,
1329 .qmenu
= vivid_ctrl_radio_rds_mode_strings
,
1333 static const struct v4l2_ctrl_config vivid_ctrl_radio_rx_rds_rbds
= {
1334 .ops
= &vivid_radio_rx_ctrl_ops
,
1335 .id
= VIVID_CID_RADIO_RX_RDS_RBDS
,
1336 .name
= "Generate RBDS Instead of RDS",
1337 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
1342 static const char * const vivid_ctrl_radio_hw_seek_mode_strings
[] = {
1349 static const struct v4l2_ctrl_config vivid_ctrl_radio_hw_seek_mode
= {
1350 .ops
= &vivid_radio_rx_ctrl_ops
,
1351 .id
= VIVID_CID_RADIO_SEEK_MODE
,
1352 .name
= "Radio HW Seek Mode",
1353 .type
= V4L2_CTRL_TYPE_MENU
,
1355 .qmenu
= vivid_ctrl_radio_hw_seek_mode_strings
,
1358 static const struct v4l2_ctrl_config vivid_ctrl_radio_hw_seek_prog_lim
= {
1359 .ops
= &vivid_radio_rx_ctrl_ops
,
1360 .id
= VIVID_CID_RADIO_SEEK_PROG_LIM
,
1361 .name
= "Radio Programmable HW Seek",
1362 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
1368 /* Radio Transmitter Controls */
1370 static int vivid_radio_tx_s_ctrl(struct v4l2_ctrl
*ctrl
)
1372 struct vivid_dev
*dev
= container_of(ctrl
->handler
, struct vivid_dev
, ctrl_hdl_radio_tx
);
1375 case VIVID_CID_RADIO_TX_RDS_BLOCKIO
:
1376 dev
->radio_tx_rds_controls
= ctrl
->val
;
1377 dev
->radio_tx_caps
&= ~V4L2_CAP_READWRITE
;
1378 if (!dev
->radio_tx_rds_controls
)
1379 dev
->radio_tx_caps
|= V4L2_CAP_READWRITE
;
1380 dev
->radio_tx_dev
.device_caps
= dev
->radio_tx_caps
;
1382 case V4L2_CID_RDS_TX_PTY
:
1383 if (dev
->radio_rx_rds_controls
)
1384 v4l2_ctrl_s_ctrl(dev
->radio_rx_rds_pty
, ctrl
->val
);
1386 case V4L2_CID_RDS_TX_PS_NAME
:
1387 if (dev
->radio_rx_rds_controls
)
1388 v4l2_ctrl_s_ctrl_string(dev
->radio_rx_rds_psname
, ctrl
->p_new
.p_char
);
1390 case V4L2_CID_RDS_TX_RADIO_TEXT
:
1391 if (dev
->radio_rx_rds_controls
)
1392 v4l2_ctrl_s_ctrl_string(dev
->radio_rx_rds_radiotext
, ctrl
->p_new
.p_char
);
1394 case V4L2_CID_RDS_TX_TRAFFIC_ANNOUNCEMENT
:
1395 if (dev
->radio_rx_rds_controls
)
1396 v4l2_ctrl_s_ctrl(dev
->radio_rx_rds_ta
, ctrl
->val
);
1398 case V4L2_CID_RDS_TX_TRAFFIC_PROGRAM
:
1399 if (dev
->radio_rx_rds_controls
)
1400 v4l2_ctrl_s_ctrl(dev
->radio_rx_rds_tp
, ctrl
->val
);
1402 case V4L2_CID_RDS_TX_MUSIC_SPEECH
:
1403 if (dev
->radio_rx_rds_controls
)
1404 v4l2_ctrl_s_ctrl(dev
->radio_rx_rds_ms
, ctrl
->val
);
1410 static const struct v4l2_ctrl_ops vivid_radio_tx_ctrl_ops
= {
1411 .s_ctrl
= vivid_radio_tx_s_ctrl
,
1414 static const struct v4l2_ctrl_config vivid_ctrl_radio_tx_rds_blockio
= {
1415 .ops
= &vivid_radio_tx_ctrl_ops
,
1416 .id
= VIVID_CID_RADIO_TX_RDS_BLOCKIO
,
1417 .name
= "RDS Tx I/O Mode",
1418 .type
= V4L2_CTRL_TYPE_MENU
,
1419 .qmenu
= vivid_ctrl_radio_rds_mode_strings
,
1425 /* SDR Capture Controls */
1427 static int vivid_sdr_cap_s_ctrl(struct v4l2_ctrl
*ctrl
)
1429 struct vivid_dev
*dev
= container_of(ctrl
->handler
, struct vivid_dev
, ctrl_hdl_sdr_cap
);
1432 case VIVID_CID_SDR_CAP_FM_DEVIATION
:
1433 dev
->sdr_fm_deviation
= ctrl
->val
;
1439 static const struct v4l2_ctrl_ops vivid_sdr_cap_ctrl_ops
= {
1440 .s_ctrl
= vivid_sdr_cap_s_ctrl
,
1443 static const struct v4l2_ctrl_config vivid_ctrl_sdr_cap_fm_deviation
= {
1444 .ops
= &vivid_sdr_cap_ctrl_ops
,
1445 .id
= VIVID_CID_SDR_CAP_FM_DEVIATION
,
1446 .name
= "FM Deviation",
1447 .type
= V4L2_CTRL_TYPE_INTEGER
,
1454 /* Metadata Capture Control */
1456 static int vivid_meta_cap_s_ctrl(struct v4l2_ctrl
*ctrl
)
1458 struct vivid_dev
*dev
= container_of(ctrl
->handler
, struct vivid_dev
,
1462 case VIVID_CID_META_CAP_GENERATE_PTS
:
1463 dev
->meta_pts
= ctrl
->val
;
1465 case VIVID_CID_META_CAP_GENERATE_SCR
:
1466 dev
->meta_scr
= ctrl
->val
;
1472 static const struct v4l2_ctrl_ops vivid_meta_cap_ctrl_ops
= {
1473 .s_ctrl
= vivid_meta_cap_s_ctrl
,
1476 static const struct v4l2_ctrl_config vivid_ctrl_meta_has_pts
= {
1477 .ops
= &vivid_meta_cap_ctrl_ops
,
1478 .id
= VIVID_CID_META_CAP_GENERATE_PTS
,
1479 .name
= "Generate PTS",
1480 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
1486 static const struct v4l2_ctrl_config vivid_ctrl_meta_has_src_clk
= {
1487 .ops
= &vivid_meta_cap_ctrl_ops
,
1488 .id
= VIVID_CID_META_CAP_GENERATE_SCR
,
1489 .name
= "Generate SCR",
1490 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
1496 static const struct v4l2_ctrl_config vivid_ctrl_class
= {
1497 .ops
= &vivid_user_gen_ctrl_ops
,
1498 .flags
= V4L2_CTRL_FLAG_READ_ONLY
| V4L2_CTRL_FLAG_WRITE_ONLY
,
1499 .id
= VIVID_CID_VIVID_CLASS
,
1500 .name
= "Vivid Controls",
1501 .type
= V4L2_CTRL_TYPE_CTRL_CLASS
,
1504 int vivid_create_controls(struct vivid_dev
*dev
, bool show_ccs_cap
,
1505 bool show_ccs_out
, bool no_error_inj
,
1506 bool has_sdtv
, bool has_hdmi
)
1508 struct v4l2_ctrl_handler
*hdl_user_gen
= &dev
->ctrl_hdl_user_gen
;
1509 struct v4l2_ctrl_handler
*hdl_user_vid
= &dev
->ctrl_hdl_user_vid
;
1510 struct v4l2_ctrl_handler
*hdl_user_aud
= &dev
->ctrl_hdl_user_aud
;
1511 struct v4l2_ctrl_handler
*hdl_streaming
= &dev
->ctrl_hdl_streaming
;
1512 struct v4l2_ctrl_handler
*hdl_sdtv_cap
= &dev
->ctrl_hdl_sdtv_cap
;
1513 struct v4l2_ctrl_handler
*hdl_loop_cap
= &dev
->ctrl_hdl_loop_cap
;
1514 struct v4l2_ctrl_handler
*hdl_fb
= &dev
->ctrl_hdl_fb
;
1515 struct v4l2_ctrl_handler
*hdl_vid_cap
= &dev
->ctrl_hdl_vid_cap
;
1516 struct v4l2_ctrl_handler
*hdl_vid_out
= &dev
->ctrl_hdl_vid_out
;
1517 struct v4l2_ctrl_handler
*hdl_vbi_cap
= &dev
->ctrl_hdl_vbi_cap
;
1518 struct v4l2_ctrl_handler
*hdl_vbi_out
= &dev
->ctrl_hdl_vbi_out
;
1519 struct v4l2_ctrl_handler
*hdl_radio_rx
= &dev
->ctrl_hdl_radio_rx
;
1520 struct v4l2_ctrl_handler
*hdl_radio_tx
= &dev
->ctrl_hdl_radio_tx
;
1521 struct v4l2_ctrl_handler
*hdl_sdr_cap
= &dev
->ctrl_hdl_sdr_cap
;
1522 struct v4l2_ctrl_handler
*hdl_meta_cap
= &dev
->ctrl_hdl_meta_cap
;
1523 struct v4l2_ctrl_handler
*hdl_meta_out
= &dev
->ctrl_hdl_meta_out
;
1524 struct v4l2_ctrl_handler
*hdl_tch_cap
= &dev
->ctrl_hdl_touch_cap
;
1526 struct v4l2_ctrl_config vivid_ctrl_dv_timings
= {
1527 .ops
= &vivid_vid_cap_ctrl_ops
,
1528 .id
= VIVID_CID_DV_TIMINGS
,
1529 .name
= "DV Timings",
1530 .type
= V4L2_CTRL_TYPE_MENU
,
1534 v4l2_ctrl_handler_init(hdl_user_gen
, 10);
1535 v4l2_ctrl_new_custom(hdl_user_gen
, &vivid_ctrl_class
, NULL
);
1536 v4l2_ctrl_handler_init(hdl_user_vid
, 9);
1537 v4l2_ctrl_new_custom(hdl_user_vid
, &vivid_ctrl_class
, NULL
);
1538 v4l2_ctrl_handler_init(hdl_user_aud
, 2);
1539 v4l2_ctrl_new_custom(hdl_user_aud
, &vivid_ctrl_class
, NULL
);
1540 v4l2_ctrl_handler_init(hdl_streaming
, 8);
1541 v4l2_ctrl_new_custom(hdl_streaming
, &vivid_ctrl_class
, NULL
);
1542 v4l2_ctrl_handler_init(hdl_sdtv_cap
, 2);
1543 v4l2_ctrl_new_custom(hdl_sdtv_cap
, &vivid_ctrl_class
, NULL
);
1544 v4l2_ctrl_handler_init(hdl_loop_cap
, 1);
1545 v4l2_ctrl_new_custom(hdl_loop_cap
, &vivid_ctrl_class
, NULL
);
1546 v4l2_ctrl_handler_init(hdl_fb
, 1);
1547 v4l2_ctrl_new_custom(hdl_fb
, &vivid_ctrl_class
, NULL
);
1548 v4l2_ctrl_handler_init(hdl_vid_cap
, 55);
1549 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_class
, NULL
);
1550 v4l2_ctrl_handler_init(hdl_vid_out
, 26);
1551 if (!no_error_inj
|| dev
->has_fb
|| dev
->num_hdmi_outputs
)
1552 v4l2_ctrl_new_custom(hdl_vid_out
, &vivid_ctrl_class
, NULL
);
1553 v4l2_ctrl_handler_init(hdl_vbi_cap
, 21);
1554 v4l2_ctrl_new_custom(hdl_vbi_cap
, &vivid_ctrl_class
, NULL
);
1555 v4l2_ctrl_handler_init(hdl_vbi_out
, 19);
1557 v4l2_ctrl_new_custom(hdl_vbi_out
, &vivid_ctrl_class
, NULL
);
1558 v4l2_ctrl_handler_init(hdl_radio_rx
, 17);
1559 v4l2_ctrl_new_custom(hdl_radio_rx
, &vivid_ctrl_class
, NULL
);
1560 v4l2_ctrl_handler_init(hdl_radio_tx
, 17);
1561 v4l2_ctrl_new_custom(hdl_radio_tx
, &vivid_ctrl_class
, NULL
);
1562 v4l2_ctrl_handler_init(hdl_sdr_cap
, 19);
1563 v4l2_ctrl_new_custom(hdl_sdr_cap
, &vivid_ctrl_class
, NULL
);
1564 v4l2_ctrl_handler_init(hdl_meta_cap
, 2);
1565 v4l2_ctrl_new_custom(hdl_meta_cap
, &vivid_ctrl_class
, NULL
);
1566 v4l2_ctrl_handler_init(hdl_meta_out
, 2);
1567 v4l2_ctrl_new_custom(hdl_meta_out
, &vivid_ctrl_class
, NULL
);
1568 v4l2_ctrl_handler_init(hdl_tch_cap
, 2);
1569 v4l2_ctrl_new_custom(hdl_tch_cap
, &vivid_ctrl_class
, NULL
);
1572 dev
->volume
= v4l2_ctrl_new_std(hdl_user_aud
, NULL
,
1573 V4L2_CID_AUDIO_VOLUME
, 0, 255, 1, 200);
1574 dev
->mute
= v4l2_ctrl_new_std(hdl_user_aud
, NULL
,
1575 V4L2_CID_AUDIO_MUTE
, 0, 1, 1, 0);
1576 if (dev
->has_vid_cap
) {
1577 dev
->brightness
= v4l2_ctrl_new_std(hdl_user_vid
, &vivid_user_vid_ctrl_ops
,
1578 V4L2_CID_BRIGHTNESS
, 0, 255, 1, 128);
1579 for (i
= 0; i
< MAX_INPUTS
; i
++)
1580 dev
->input_brightness
[i
] = 128;
1581 dev
->contrast
= v4l2_ctrl_new_std(hdl_user_vid
, &vivid_user_vid_ctrl_ops
,
1582 V4L2_CID_CONTRAST
, 0, 255, 1, 128);
1583 dev
->saturation
= v4l2_ctrl_new_std(hdl_user_vid
, &vivid_user_vid_ctrl_ops
,
1584 V4L2_CID_SATURATION
, 0, 255, 1, 128);
1585 dev
->hue
= v4l2_ctrl_new_std(hdl_user_vid
, &vivid_user_vid_ctrl_ops
,
1586 V4L2_CID_HUE
, -128, 128, 1, 0);
1587 v4l2_ctrl_new_std(hdl_user_vid
, &vivid_user_vid_ctrl_ops
,
1588 V4L2_CID_HFLIP
, 0, 1, 1, 0);
1589 v4l2_ctrl_new_std(hdl_user_vid
, &vivid_user_vid_ctrl_ops
,
1590 V4L2_CID_VFLIP
, 0, 1, 1, 0);
1591 dev
->autogain
= v4l2_ctrl_new_std(hdl_user_vid
, &vivid_user_vid_ctrl_ops
,
1592 V4L2_CID_AUTOGAIN
, 0, 1, 1, 1);
1593 dev
->gain
= v4l2_ctrl_new_std(hdl_user_vid
, &vivid_user_vid_ctrl_ops
,
1594 V4L2_CID_GAIN
, 0, 255, 1, 100);
1595 dev
->alpha
= v4l2_ctrl_new_std(hdl_user_vid
, &vivid_user_vid_ctrl_ops
,
1596 V4L2_CID_ALPHA_COMPONENT
, 0, 255, 1, 0);
1598 dev
->button
= v4l2_ctrl_new_custom(hdl_user_gen
, &vivid_ctrl_button
, NULL
);
1599 dev
->int32
= v4l2_ctrl_new_custom(hdl_user_gen
, &vivid_ctrl_int32
, NULL
);
1600 dev
->int64
= v4l2_ctrl_new_custom(hdl_user_gen
, &vivid_ctrl_int64
, NULL
);
1601 dev
->boolean
= v4l2_ctrl_new_custom(hdl_user_gen
, &vivid_ctrl_boolean
, NULL
);
1602 dev
->menu
= v4l2_ctrl_new_custom(hdl_user_gen
, &vivid_ctrl_menu
, NULL
);
1603 dev
->string
= v4l2_ctrl_new_custom(hdl_user_gen
, &vivid_ctrl_string
, NULL
);
1604 dev
->bitmask
= v4l2_ctrl_new_custom(hdl_user_gen
, &vivid_ctrl_bitmask
, NULL
);
1605 dev
->int_menu
= v4l2_ctrl_new_custom(hdl_user_gen
, &vivid_ctrl_int_menu
, NULL
);
1606 v4l2_ctrl_new_custom(hdl_user_gen
, &vivid_ctrl_area
, NULL
);
1607 v4l2_ctrl_new_custom(hdl_user_gen
, &vivid_ctrl_u32_array
, NULL
);
1608 v4l2_ctrl_new_custom(hdl_user_gen
, &vivid_ctrl_u16_matrix
, NULL
);
1609 v4l2_ctrl_new_custom(hdl_user_gen
, &vivid_ctrl_u8_4d_array
, NULL
);
1611 if (dev
->has_vid_cap
) {
1612 /* Image Processing Controls */
1613 struct v4l2_ctrl_config vivid_ctrl_test_pattern
= {
1614 .ops
= &vivid_vid_cap_ctrl_ops
,
1615 .id
= VIVID_CID_TEST_PATTERN
,
1616 .name
= "Test Pattern",
1617 .type
= V4L2_CTRL_TYPE_MENU
,
1618 .max
= TPG_PAT_NOISE
,
1619 .qmenu
= tpg_pattern_strings
,
1622 dev
->test_pattern
= v4l2_ctrl_new_custom(hdl_vid_cap
,
1623 &vivid_ctrl_test_pattern
, NULL
);
1624 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_perc_fill
, NULL
);
1625 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_hor_movement
, NULL
);
1626 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_vert_movement
, NULL
);
1627 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_osd_mode
, NULL
);
1628 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_show_border
, NULL
);
1629 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_show_square
, NULL
);
1630 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_hflip
, NULL
);
1631 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_vflip
, NULL
);
1632 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_insert_sav
, NULL
);
1633 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_insert_eav
, NULL
);
1634 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_reduced_fps
, NULL
);
1636 dev
->ctrl_has_crop_cap
= v4l2_ctrl_new_custom(hdl_vid_cap
,
1637 &vivid_ctrl_has_crop_cap
, NULL
);
1638 dev
->ctrl_has_compose_cap
= v4l2_ctrl_new_custom(hdl_vid_cap
,
1639 &vivid_ctrl_has_compose_cap
, NULL
);
1640 dev
->ctrl_has_scaler_cap
= v4l2_ctrl_new_custom(hdl_vid_cap
,
1641 &vivid_ctrl_has_scaler_cap
, NULL
);
1644 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_tstamp_src
, NULL
);
1645 dev
->colorspace
= v4l2_ctrl_new_custom(hdl_vid_cap
,
1646 &vivid_ctrl_colorspace
, NULL
);
1647 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_xfer_func
, NULL
);
1648 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_ycbcr_enc
, NULL
);
1649 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_hsv_enc
, NULL
);
1650 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_quantization
, NULL
);
1651 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_alpha_mode
, NULL
);
1654 if (dev
->has_vid_out
&& show_ccs_out
) {
1655 dev
->ctrl_has_crop_out
= v4l2_ctrl_new_custom(hdl_vid_out
,
1656 &vivid_ctrl_has_crop_out
, NULL
);
1657 dev
->ctrl_has_compose_out
= v4l2_ctrl_new_custom(hdl_vid_out
,
1658 &vivid_ctrl_has_compose_out
, NULL
);
1659 dev
->ctrl_has_scaler_out
= v4l2_ctrl_new_custom(hdl_vid_out
,
1660 &vivid_ctrl_has_scaler_out
, NULL
);
1664 * Testing this driver with v4l2-compliance will trigger the error
1665 * injection controls, and after that nothing will work as expected.
1666 * So we have a module option to drop these error injecting controls
1667 * allowing us to run v4l2_compliance again.
1669 if (!no_error_inj
) {
1670 v4l2_ctrl_new_custom(hdl_user_gen
, &vivid_ctrl_disconnect
, NULL
);
1671 v4l2_ctrl_new_custom(hdl_streaming
, &vivid_ctrl_dqbuf_error
, NULL
);
1672 v4l2_ctrl_new_custom(hdl_streaming
, &vivid_ctrl_perc_dropped
, NULL
);
1673 v4l2_ctrl_new_custom(hdl_streaming
, &vivid_ctrl_queue_setup_error
, NULL
);
1674 v4l2_ctrl_new_custom(hdl_streaming
, &vivid_ctrl_buf_prepare_error
, NULL
);
1675 v4l2_ctrl_new_custom(hdl_streaming
, &vivid_ctrl_start_streaming_error
, NULL
);
1676 v4l2_ctrl_new_custom(hdl_streaming
, &vivid_ctrl_queue_error
, NULL
);
1677 #ifdef CONFIG_MEDIA_CONTROLLER
1678 v4l2_ctrl_new_custom(hdl_streaming
, &vivid_ctrl_req_validate_error
, NULL
);
1680 v4l2_ctrl_new_custom(hdl_streaming
, &vivid_ctrl_seq_wrap
, NULL
);
1681 v4l2_ctrl_new_custom(hdl_streaming
, &vivid_ctrl_time_wrap
, NULL
);
1684 if (has_sdtv
&& (dev
->has_vid_cap
|| dev
->has_vbi_cap
)) {
1685 if (dev
->has_vid_cap
)
1686 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_std_aspect_ratio
, NULL
);
1687 dev
->ctrl_std_signal_mode
= v4l2_ctrl_new_custom(hdl_sdtv_cap
,
1688 &vivid_ctrl_std_signal_mode
, NULL
);
1689 dev
->ctrl_standard
= v4l2_ctrl_new_custom(hdl_sdtv_cap
,
1690 &vivid_ctrl_standard
, NULL
);
1691 if (dev
->ctrl_std_signal_mode
)
1692 v4l2_ctrl_cluster(2, &dev
->ctrl_std_signal_mode
);
1693 if (dev
->has_raw_vbi_cap
)
1694 v4l2_ctrl_new_custom(hdl_vbi_cap
, &vivid_ctrl_vbi_cap_interlaced
, NULL
);
1697 if (dev
->num_hdmi_inputs
) {
1698 s64 hdmi_input_mask
= GENMASK(dev
->num_hdmi_inputs
- 1, 0);
1700 dev
->ctrl_dv_timings_signal_mode
= v4l2_ctrl_new_custom(hdl_vid_cap
,
1701 &vivid_ctrl_dv_timings_signal_mode
, NULL
);
1703 vivid_ctrl_dv_timings
.max
= dev
->query_dv_timings_size
- 1;
1704 vivid_ctrl_dv_timings
.qmenu
=
1705 (const char * const *)dev
->query_dv_timings_qmenu
;
1706 dev
->ctrl_dv_timings
= v4l2_ctrl_new_custom(hdl_vid_cap
,
1707 &vivid_ctrl_dv_timings
, NULL
);
1708 if (dev
->ctrl_dv_timings_signal_mode
)
1709 v4l2_ctrl_cluster(2, &dev
->ctrl_dv_timings_signal_mode
);
1711 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_dv_timings_aspect_ratio
, NULL
);
1712 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_max_edid_blocks
, NULL
);
1713 dev
->real_rgb_range_cap
= v4l2_ctrl_new_custom(hdl_vid_cap
,
1714 &vivid_ctrl_limited_rgb_range
, NULL
);
1715 dev
->rgb_range_cap
= v4l2_ctrl_new_std_menu(hdl_vid_cap
,
1716 &vivid_vid_cap_ctrl_ops
,
1717 V4L2_CID_DV_RX_RGB_RANGE
, V4L2_DV_RGB_RANGE_FULL
,
1718 0, V4L2_DV_RGB_RANGE_AUTO
);
1719 dev
->ctrl_rx_power_present
= v4l2_ctrl_new_std(hdl_vid_cap
,
1720 NULL
, V4L2_CID_DV_RX_POWER_PRESENT
, 0, hdmi_input_mask
,
1721 0, hdmi_input_mask
);
1724 if (dev
->num_hdmi_outputs
) {
1725 s64 hdmi_output_mask
= GENMASK(dev
->num_hdmi_outputs
- 1, 0);
1728 * We aren't doing anything with this at the moment, but
1729 * HDMI outputs typically have this controls.
1731 dev
->ctrl_tx_rgb_range
= v4l2_ctrl_new_std_menu(hdl_vid_out
, NULL
,
1732 V4L2_CID_DV_TX_RGB_RANGE
, V4L2_DV_RGB_RANGE_FULL
,
1733 0, V4L2_DV_RGB_RANGE_AUTO
);
1734 dev
->ctrl_tx_mode
= v4l2_ctrl_new_std_menu(hdl_vid_out
, NULL
,
1735 V4L2_CID_DV_TX_MODE
, V4L2_DV_TX_MODE_HDMI
,
1736 0, V4L2_DV_TX_MODE_HDMI
);
1737 dev
->ctrl_display_present
= v4l2_ctrl_new_custom(hdl_vid_out
,
1738 &vivid_ctrl_display_present
, NULL
);
1739 dev
->ctrl_tx_hotplug
= v4l2_ctrl_new_std(hdl_vid_out
,
1740 NULL
, V4L2_CID_DV_TX_HOTPLUG
, 0, hdmi_output_mask
,
1741 0, hdmi_output_mask
);
1742 dev
->ctrl_tx_rxsense
= v4l2_ctrl_new_std(hdl_vid_out
,
1743 NULL
, V4L2_CID_DV_TX_RXSENSE
, 0, hdmi_output_mask
,
1744 0, hdmi_output_mask
);
1745 dev
->ctrl_tx_edid_present
= v4l2_ctrl_new_std(hdl_vid_out
,
1746 NULL
, V4L2_CID_DV_TX_EDID_PRESENT
, 0, hdmi_output_mask
,
1747 0, hdmi_output_mask
);
1749 if ((dev
->has_vid_cap
&& dev
->has_vid_out
) ||
1750 (dev
->has_vbi_cap
&& dev
->has_vbi_out
))
1751 v4l2_ctrl_new_custom(hdl_loop_cap
, &vivid_ctrl_loop_video
, NULL
);
1754 v4l2_ctrl_new_custom(hdl_fb
, &vivid_ctrl_clear_fb
, NULL
);
1756 if (dev
->has_radio_rx
) {
1757 v4l2_ctrl_new_custom(hdl_radio_rx
, &vivid_ctrl_radio_hw_seek_mode
, NULL
);
1758 v4l2_ctrl_new_custom(hdl_radio_rx
, &vivid_ctrl_radio_hw_seek_prog_lim
, NULL
);
1759 v4l2_ctrl_new_custom(hdl_radio_rx
, &vivid_ctrl_radio_rx_rds_blockio
, NULL
);
1760 v4l2_ctrl_new_custom(hdl_radio_rx
, &vivid_ctrl_radio_rx_rds_rbds
, NULL
);
1761 v4l2_ctrl_new_std(hdl_radio_rx
, &vivid_radio_rx_ctrl_ops
,
1762 V4L2_CID_RDS_RECEPTION
, 0, 1, 1, 1);
1763 dev
->radio_rx_rds_pty
= v4l2_ctrl_new_std(hdl_radio_rx
,
1764 &vivid_radio_rx_ctrl_ops
,
1765 V4L2_CID_RDS_RX_PTY
, 0, 31, 1, 0);
1766 dev
->radio_rx_rds_psname
= v4l2_ctrl_new_std(hdl_radio_rx
,
1767 &vivid_radio_rx_ctrl_ops
,
1768 V4L2_CID_RDS_RX_PS_NAME
, 0, 8, 8, 0);
1769 dev
->radio_rx_rds_radiotext
= v4l2_ctrl_new_std(hdl_radio_rx
,
1770 &vivid_radio_rx_ctrl_ops
,
1771 V4L2_CID_RDS_RX_RADIO_TEXT
, 0, 64, 64, 0);
1772 dev
->radio_rx_rds_ta
= v4l2_ctrl_new_std(hdl_radio_rx
,
1773 &vivid_radio_rx_ctrl_ops
,
1774 V4L2_CID_RDS_RX_TRAFFIC_ANNOUNCEMENT
, 0, 1, 1, 0);
1775 dev
->radio_rx_rds_tp
= v4l2_ctrl_new_std(hdl_radio_rx
,
1776 &vivid_radio_rx_ctrl_ops
,
1777 V4L2_CID_RDS_RX_TRAFFIC_PROGRAM
, 0, 1, 1, 0);
1778 dev
->radio_rx_rds_ms
= v4l2_ctrl_new_std(hdl_radio_rx
,
1779 &vivid_radio_rx_ctrl_ops
,
1780 V4L2_CID_RDS_RX_MUSIC_SPEECH
, 0, 1, 1, 1);
1782 if (dev
->has_radio_tx
) {
1783 v4l2_ctrl_new_custom(hdl_radio_tx
,
1784 &vivid_ctrl_radio_tx_rds_blockio
, NULL
);
1785 dev
->radio_tx_rds_pi
= v4l2_ctrl_new_std(hdl_radio_tx
,
1786 &vivid_radio_tx_ctrl_ops
,
1787 V4L2_CID_RDS_TX_PI
, 0, 0xffff, 1, 0x8088);
1788 dev
->radio_tx_rds_pty
= v4l2_ctrl_new_std(hdl_radio_tx
,
1789 &vivid_radio_tx_ctrl_ops
,
1790 V4L2_CID_RDS_TX_PTY
, 0, 31, 1, 3);
1791 dev
->radio_tx_rds_psname
= v4l2_ctrl_new_std(hdl_radio_tx
,
1792 &vivid_radio_tx_ctrl_ops
,
1793 V4L2_CID_RDS_TX_PS_NAME
, 0, 8, 8, 0);
1794 if (dev
->radio_tx_rds_psname
)
1795 v4l2_ctrl_s_ctrl_string(dev
->radio_tx_rds_psname
, "VIVID-TX");
1796 dev
->radio_tx_rds_radiotext
= v4l2_ctrl_new_std(hdl_radio_tx
,
1797 &vivid_radio_tx_ctrl_ops
,
1798 V4L2_CID_RDS_TX_RADIO_TEXT
, 0, 64 * 2, 64, 0);
1799 if (dev
->radio_tx_rds_radiotext
)
1800 v4l2_ctrl_s_ctrl_string(dev
->radio_tx_rds_radiotext
,
1801 "This is a VIVID default Radio Text template text, change at will");
1802 dev
->radio_tx_rds_mono_stereo
= v4l2_ctrl_new_std(hdl_radio_tx
,
1803 &vivid_radio_tx_ctrl_ops
,
1804 V4L2_CID_RDS_TX_MONO_STEREO
, 0, 1, 1, 1);
1805 dev
->radio_tx_rds_art_head
= v4l2_ctrl_new_std(hdl_radio_tx
,
1806 &vivid_radio_tx_ctrl_ops
,
1807 V4L2_CID_RDS_TX_ARTIFICIAL_HEAD
, 0, 1, 1, 0);
1808 dev
->radio_tx_rds_compressed
= v4l2_ctrl_new_std(hdl_radio_tx
,
1809 &vivid_radio_tx_ctrl_ops
,
1810 V4L2_CID_RDS_TX_COMPRESSED
, 0, 1, 1, 0);
1811 dev
->radio_tx_rds_dyn_pty
= v4l2_ctrl_new_std(hdl_radio_tx
,
1812 &vivid_radio_tx_ctrl_ops
,
1813 V4L2_CID_RDS_TX_DYNAMIC_PTY
, 0, 1, 1, 0);
1814 dev
->radio_tx_rds_ta
= v4l2_ctrl_new_std(hdl_radio_tx
,
1815 &vivid_radio_tx_ctrl_ops
,
1816 V4L2_CID_RDS_TX_TRAFFIC_ANNOUNCEMENT
, 0, 1, 1, 0);
1817 dev
->radio_tx_rds_tp
= v4l2_ctrl_new_std(hdl_radio_tx
,
1818 &vivid_radio_tx_ctrl_ops
,
1819 V4L2_CID_RDS_TX_TRAFFIC_PROGRAM
, 0, 1, 1, 1);
1820 dev
->radio_tx_rds_ms
= v4l2_ctrl_new_std(hdl_radio_tx
,
1821 &vivid_radio_tx_ctrl_ops
,
1822 V4L2_CID_RDS_TX_MUSIC_SPEECH
, 0, 1, 1, 1);
1824 if (dev
->has_sdr_cap
) {
1825 v4l2_ctrl_new_custom(hdl_sdr_cap
,
1826 &vivid_ctrl_sdr_cap_fm_deviation
, NULL
);
1828 if (dev
->has_meta_cap
) {
1829 v4l2_ctrl_new_custom(hdl_meta_cap
,
1830 &vivid_ctrl_meta_has_pts
, NULL
);
1831 v4l2_ctrl_new_custom(hdl_meta_cap
,
1832 &vivid_ctrl_meta_has_src_clk
, NULL
);
1835 if (hdl_user_gen
->error
)
1836 return hdl_user_gen
->error
;
1837 if (hdl_user_vid
->error
)
1838 return hdl_user_vid
->error
;
1839 if (hdl_user_aud
->error
)
1840 return hdl_user_aud
->error
;
1841 if (hdl_streaming
->error
)
1842 return hdl_streaming
->error
;
1843 if (hdl_sdr_cap
->error
)
1844 return hdl_sdr_cap
->error
;
1845 if (hdl_loop_cap
->error
)
1846 return hdl_loop_cap
->error
;
1849 v4l2_ctrl_auto_cluster(2, &dev
->autogain
, 0, true);
1851 if (dev
->has_vid_cap
) {
1852 v4l2_ctrl_add_handler(hdl_vid_cap
, hdl_user_gen
, NULL
, false);
1853 v4l2_ctrl_add_handler(hdl_vid_cap
, hdl_user_vid
, NULL
, false);
1854 v4l2_ctrl_add_handler(hdl_vid_cap
, hdl_user_aud
, NULL
, false);
1855 v4l2_ctrl_add_handler(hdl_vid_cap
, hdl_streaming
, NULL
, false);
1856 v4l2_ctrl_add_handler(hdl_vid_cap
, hdl_sdtv_cap
, NULL
, false);
1857 v4l2_ctrl_add_handler(hdl_vid_cap
, hdl_loop_cap
, NULL
, false);
1858 v4l2_ctrl_add_handler(hdl_vid_cap
, hdl_fb
, NULL
, false);
1859 if (hdl_vid_cap
->error
)
1860 return hdl_vid_cap
->error
;
1861 dev
->vid_cap_dev
.ctrl_handler
= hdl_vid_cap
;
1863 if (dev
->has_vid_out
) {
1864 v4l2_ctrl_add_handler(hdl_vid_out
, hdl_user_gen
, NULL
, false);
1865 v4l2_ctrl_add_handler(hdl_vid_out
, hdl_user_aud
, NULL
, false);
1866 v4l2_ctrl_add_handler(hdl_vid_out
, hdl_streaming
, NULL
, false);
1867 v4l2_ctrl_add_handler(hdl_vid_out
, hdl_fb
, NULL
, false);
1868 if (hdl_vid_out
->error
)
1869 return hdl_vid_out
->error
;
1870 dev
->vid_out_dev
.ctrl_handler
= hdl_vid_out
;
1872 if (dev
->has_vbi_cap
) {
1873 v4l2_ctrl_add_handler(hdl_vbi_cap
, hdl_user_gen
, NULL
, false);
1874 v4l2_ctrl_add_handler(hdl_vbi_cap
, hdl_streaming
, NULL
, false);
1875 v4l2_ctrl_add_handler(hdl_vbi_cap
, hdl_sdtv_cap
, NULL
, false);
1876 v4l2_ctrl_add_handler(hdl_vbi_cap
, hdl_loop_cap
, NULL
, false);
1877 if (hdl_vbi_cap
->error
)
1878 return hdl_vbi_cap
->error
;
1879 dev
->vbi_cap_dev
.ctrl_handler
= hdl_vbi_cap
;
1881 if (dev
->has_vbi_out
) {
1882 v4l2_ctrl_add_handler(hdl_vbi_out
, hdl_user_gen
, NULL
, false);
1883 v4l2_ctrl_add_handler(hdl_vbi_out
, hdl_streaming
, NULL
, false);
1884 if (hdl_vbi_out
->error
)
1885 return hdl_vbi_out
->error
;
1886 dev
->vbi_out_dev
.ctrl_handler
= hdl_vbi_out
;
1888 if (dev
->has_radio_rx
) {
1889 v4l2_ctrl_add_handler(hdl_radio_rx
, hdl_user_gen
, NULL
, false);
1890 v4l2_ctrl_add_handler(hdl_radio_rx
, hdl_user_aud
, NULL
, false);
1891 if (hdl_radio_rx
->error
)
1892 return hdl_radio_rx
->error
;
1893 dev
->radio_rx_dev
.ctrl_handler
= hdl_radio_rx
;
1895 if (dev
->has_radio_tx
) {
1896 v4l2_ctrl_add_handler(hdl_radio_tx
, hdl_user_gen
, NULL
, false);
1897 v4l2_ctrl_add_handler(hdl_radio_tx
, hdl_user_aud
, NULL
, false);
1898 if (hdl_radio_tx
->error
)
1899 return hdl_radio_tx
->error
;
1900 dev
->radio_tx_dev
.ctrl_handler
= hdl_radio_tx
;
1902 if (dev
->has_sdr_cap
) {
1903 v4l2_ctrl_add_handler(hdl_sdr_cap
, hdl_user_gen
, NULL
, false);
1904 v4l2_ctrl_add_handler(hdl_sdr_cap
, hdl_streaming
, NULL
, false);
1905 if (hdl_sdr_cap
->error
)
1906 return hdl_sdr_cap
->error
;
1907 dev
->sdr_cap_dev
.ctrl_handler
= hdl_sdr_cap
;
1909 if (dev
->has_meta_cap
) {
1910 v4l2_ctrl_add_handler(hdl_meta_cap
, hdl_user_gen
, NULL
, false);
1911 v4l2_ctrl_add_handler(hdl_meta_cap
, hdl_streaming
, NULL
, false);
1912 if (hdl_meta_cap
->error
)
1913 return hdl_meta_cap
->error
;
1914 dev
->meta_cap_dev
.ctrl_handler
= hdl_meta_cap
;
1916 if (dev
->has_meta_out
) {
1917 v4l2_ctrl_add_handler(hdl_meta_out
, hdl_user_gen
, NULL
, false);
1918 v4l2_ctrl_add_handler(hdl_meta_out
, hdl_streaming
, NULL
, false);
1919 if (hdl_meta_out
->error
)
1920 return hdl_meta_out
->error
;
1921 dev
->meta_out_dev
.ctrl_handler
= hdl_meta_out
;
1923 if (dev
->has_touch_cap
) {
1924 v4l2_ctrl_add_handler(hdl_tch_cap
, hdl_user_gen
, NULL
, false);
1925 v4l2_ctrl_add_handler(hdl_tch_cap
, hdl_streaming
, NULL
, false);
1926 if (hdl_tch_cap
->error
)
1927 return hdl_tch_cap
->error
;
1928 dev
->touch_cap_dev
.ctrl_handler
= hdl_tch_cap
;
1933 void vivid_free_controls(struct vivid_dev
*dev
)
1935 v4l2_ctrl_handler_free(&dev
->ctrl_hdl_vid_cap
);
1936 v4l2_ctrl_handler_free(&dev
->ctrl_hdl_vid_out
);
1937 v4l2_ctrl_handler_free(&dev
->ctrl_hdl_vbi_cap
);
1938 v4l2_ctrl_handler_free(&dev
->ctrl_hdl_vbi_out
);
1939 v4l2_ctrl_handler_free(&dev
->ctrl_hdl_radio_rx
);
1940 v4l2_ctrl_handler_free(&dev
->ctrl_hdl_radio_tx
);
1941 v4l2_ctrl_handler_free(&dev
->ctrl_hdl_sdr_cap
);
1942 v4l2_ctrl_handler_free(&dev
->ctrl_hdl_user_gen
);
1943 v4l2_ctrl_handler_free(&dev
->ctrl_hdl_user_vid
);
1944 v4l2_ctrl_handler_free(&dev
->ctrl_hdl_user_aud
);
1945 v4l2_ctrl_handler_free(&dev
->ctrl_hdl_streaming
);
1946 v4l2_ctrl_handler_free(&dev
->ctrl_hdl_sdtv_cap
);
1947 v4l2_ctrl_handler_free(&dev
->ctrl_hdl_loop_cap
);
1948 v4l2_ctrl_handler_free(&dev
->ctrl_hdl_fb
);
1949 v4l2_ctrl_handler_free(&dev
->ctrl_hdl_meta_cap
);
1950 v4l2_ctrl_handler_free(&dev
->ctrl_hdl_meta_out
);
1951 v4l2_ctrl_handler_free(&dev
->ctrl_hdl_touch_cap
);