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
);