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"
22 #define VIVID_CID_CUSTOM_BASE (V4L2_CID_USER_BASE | 0xf000)
23 #define VIVID_CID_BUTTON (VIVID_CID_CUSTOM_BASE + 0)
24 #define VIVID_CID_BOOLEAN (VIVID_CID_CUSTOM_BASE + 1)
25 #define VIVID_CID_INTEGER (VIVID_CID_CUSTOM_BASE + 2)
26 #define VIVID_CID_INTEGER64 (VIVID_CID_CUSTOM_BASE + 3)
27 #define VIVID_CID_MENU (VIVID_CID_CUSTOM_BASE + 4)
28 #define VIVID_CID_STRING (VIVID_CID_CUSTOM_BASE + 5)
29 #define VIVID_CID_BITMASK (VIVID_CID_CUSTOM_BASE + 6)
30 #define VIVID_CID_INTMENU (VIVID_CID_CUSTOM_BASE + 7)
31 #define VIVID_CID_U32_ARRAY (VIVID_CID_CUSTOM_BASE + 8)
32 #define VIVID_CID_U16_MATRIX (VIVID_CID_CUSTOM_BASE + 9)
33 #define VIVID_CID_U8_4D_ARRAY (VIVID_CID_CUSTOM_BASE + 10)
35 #define VIVID_CID_VIVID_BASE (0x00f00000 | 0xf000)
36 #define VIVID_CID_VIVID_CLASS (0x00f00000 | 1)
37 #define VIVID_CID_TEST_PATTERN (VIVID_CID_VIVID_BASE + 0)
38 #define VIVID_CID_OSD_TEXT_MODE (VIVID_CID_VIVID_BASE + 1)
39 #define VIVID_CID_HOR_MOVEMENT (VIVID_CID_VIVID_BASE + 2)
40 #define VIVID_CID_VERT_MOVEMENT (VIVID_CID_VIVID_BASE + 3)
41 #define VIVID_CID_SHOW_BORDER (VIVID_CID_VIVID_BASE + 4)
42 #define VIVID_CID_SHOW_SQUARE (VIVID_CID_VIVID_BASE + 5)
43 #define VIVID_CID_INSERT_SAV (VIVID_CID_VIVID_BASE + 6)
44 #define VIVID_CID_INSERT_EAV (VIVID_CID_VIVID_BASE + 7)
45 #define VIVID_CID_VBI_CAP_INTERLACED (VIVID_CID_VIVID_BASE + 8)
47 #define VIVID_CID_HFLIP (VIVID_CID_VIVID_BASE + 20)
48 #define VIVID_CID_VFLIP (VIVID_CID_VIVID_BASE + 21)
49 #define VIVID_CID_STD_ASPECT_RATIO (VIVID_CID_VIVID_BASE + 22)
50 #define VIVID_CID_DV_TIMINGS_ASPECT_RATIO (VIVID_CID_VIVID_BASE + 23)
51 #define VIVID_CID_TSTAMP_SRC (VIVID_CID_VIVID_BASE + 24)
52 #define VIVID_CID_COLORSPACE (VIVID_CID_VIVID_BASE + 25)
53 #define VIVID_CID_XFER_FUNC (VIVID_CID_VIVID_BASE + 26)
54 #define VIVID_CID_YCBCR_ENC (VIVID_CID_VIVID_BASE + 27)
55 #define VIVID_CID_QUANTIZATION (VIVID_CID_VIVID_BASE + 28)
56 #define VIVID_CID_LIMITED_RGB_RANGE (VIVID_CID_VIVID_BASE + 29)
57 #define VIVID_CID_ALPHA_MODE (VIVID_CID_VIVID_BASE + 30)
58 #define VIVID_CID_HAS_CROP_CAP (VIVID_CID_VIVID_BASE + 31)
59 #define VIVID_CID_HAS_COMPOSE_CAP (VIVID_CID_VIVID_BASE + 32)
60 #define VIVID_CID_HAS_SCALER_CAP (VIVID_CID_VIVID_BASE + 33)
61 #define VIVID_CID_HAS_CROP_OUT (VIVID_CID_VIVID_BASE + 34)
62 #define VIVID_CID_HAS_COMPOSE_OUT (VIVID_CID_VIVID_BASE + 35)
63 #define VIVID_CID_HAS_SCALER_OUT (VIVID_CID_VIVID_BASE + 36)
64 #define VIVID_CID_LOOP_VIDEO (VIVID_CID_VIVID_BASE + 37)
65 #define VIVID_CID_SEQ_WRAP (VIVID_CID_VIVID_BASE + 38)
66 #define VIVID_CID_TIME_WRAP (VIVID_CID_VIVID_BASE + 39)
67 #define VIVID_CID_MAX_EDID_BLOCKS (VIVID_CID_VIVID_BASE + 40)
68 #define VIVID_CID_PERCENTAGE_FILL (VIVID_CID_VIVID_BASE + 41)
69 #define VIVID_CID_REDUCED_FPS (VIVID_CID_VIVID_BASE + 42)
70 #define VIVID_CID_HSV_ENC (VIVID_CID_VIVID_BASE + 43)
72 #define VIVID_CID_STD_SIGNAL_MODE (VIVID_CID_VIVID_BASE + 60)
73 #define VIVID_CID_STANDARD (VIVID_CID_VIVID_BASE + 61)
74 #define VIVID_CID_DV_TIMINGS_SIGNAL_MODE (VIVID_CID_VIVID_BASE + 62)
75 #define VIVID_CID_DV_TIMINGS (VIVID_CID_VIVID_BASE + 63)
76 #define VIVID_CID_PERC_DROPPED (VIVID_CID_VIVID_BASE + 64)
77 #define VIVID_CID_DISCONNECT (VIVID_CID_VIVID_BASE + 65)
78 #define VIVID_CID_DQBUF_ERROR (VIVID_CID_VIVID_BASE + 66)
79 #define VIVID_CID_QUEUE_SETUP_ERROR (VIVID_CID_VIVID_BASE + 67)
80 #define VIVID_CID_BUF_PREPARE_ERROR (VIVID_CID_VIVID_BASE + 68)
81 #define VIVID_CID_START_STR_ERROR (VIVID_CID_VIVID_BASE + 69)
82 #define VIVID_CID_QUEUE_ERROR (VIVID_CID_VIVID_BASE + 70)
83 #define VIVID_CID_CLEAR_FB (VIVID_CID_VIVID_BASE + 71)
85 #define VIVID_CID_RADIO_SEEK_MODE (VIVID_CID_VIVID_BASE + 90)
86 #define VIVID_CID_RADIO_SEEK_PROG_LIM (VIVID_CID_VIVID_BASE + 91)
87 #define VIVID_CID_RADIO_RX_RDS_RBDS (VIVID_CID_VIVID_BASE + 92)
88 #define VIVID_CID_RADIO_RX_RDS_BLOCKIO (VIVID_CID_VIVID_BASE + 93)
90 #define VIVID_CID_RADIO_TX_RDS_BLOCKIO (VIVID_CID_VIVID_BASE + 94)
92 #define VIVID_CID_SDR_CAP_FM_DEVIATION (VIVID_CID_VIVID_BASE + 110)
94 /* General User Controls */
96 static int vivid_user_gen_s_ctrl(struct v4l2_ctrl
*ctrl
)
98 struct vivid_dev
*dev
= container_of(ctrl
->handler
, struct vivid_dev
, ctrl_hdl_user_gen
);
101 case VIVID_CID_DISCONNECT
:
102 v4l2_info(&dev
->v4l2_dev
, "disconnect\n");
103 clear_bit(V4L2_FL_REGISTERED
, &dev
->vid_cap_dev
.flags
);
104 clear_bit(V4L2_FL_REGISTERED
, &dev
->vid_out_dev
.flags
);
105 clear_bit(V4L2_FL_REGISTERED
, &dev
->vbi_cap_dev
.flags
);
106 clear_bit(V4L2_FL_REGISTERED
, &dev
->vbi_out_dev
.flags
);
107 clear_bit(V4L2_FL_REGISTERED
, &dev
->sdr_cap_dev
.flags
);
108 clear_bit(V4L2_FL_REGISTERED
, &dev
->radio_rx_dev
.flags
);
109 clear_bit(V4L2_FL_REGISTERED
, &dev
->radio_tx_dev
.flags
);
111 case VIVID_CID_BUTTON
:
112 dev
->button_pressed
= 30;
118 static const struct v4l2_ctrl_ops vivid_user_gen_ctrl_ops
= {
119 .s_ctrl
= vivid_user_gen_s_ctrl
,
122 static const struct v4l2_ctrl_config vivid_ctrl_button
= {
123 .ops
= &vivid_user_gen_ctrl_ops
,
124 .id
= VIVID_CID_BUTTON
,
126 .type
= V4L2_CTRL_TYPE_BUTTON
,
129 static const struct v4l2_ctrl_config vivid_ctrl_boolean
= {
130 .ops
= &vivid_user_gen_ctrl_ops
,
131 .id
= VIVID_CID_BOOLEAN
,
133 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
140 static const struct v4l2_ctrl_config vivid_ctrl_int32
= {
141 .ops
= &vivid_user_gen_ctrl_ops
,
142 .id
= VIVID_CID_INTEGER
,
143 .name
= "Integer 32 Bits",
144 .type
= V4L2_CTRL_TYPE_INTEGER
,
145 .min
= 0xffffffff80000000ULL
,
150 static const struct v4l2_ctrl_config vivid_ctrl_int64
= {
151 .ops
= &vivid_user_gen_ctrl_ops
,
152 .id
= VIVID_CID_INTEGER64
,
153 .name
= "Integer 64 Bits",
154 .type
= V4L2_CTRL_TYPE_INTEGER64
,
155 .min
= 0x8000000000000000ULL
,
156 .max
= 0x7fffffffffffffffLL
,
160 static const struct v4l2_ctrl_config vivid_ctrl_u32_array
= {
161 .ops
= &vivid_user_gen_ctrl_ops
,
162 .id
= VIVID_CID_U32_ARRAY
,
163 .name
= "U32 1 Element Array",
164 .type
= V4L2_CTRL_TYPE_U32
,
172 static const struct v4l2_ctrl_config vivid_ctrl_u16_matrix
= {
173 .ops
= &vivid_user_gen_ctrl_ops
,
174 .id
= VIVID_CID_U16_MATRIX
,
175 .name
= "U16 8x16 Matrix",
176 .type
= V4L2_CTRL_TYPE_U16
,
184 static const struct v4l2_ctrl_config vivid_ctrl_u8_4d_array
= {
185 .ops
= &vivid_user_gen_ctrl_ops
,
186 .id
= VIVID_CID_U8_4D_ARRAY
,
187 .name
= "U8 2x3x4x5 Array",
188 .type
= V4L2_CTRL_TYPE_U8
,
193 .dims
= { 2, 3, 4, 5 },
196 static const char * const vivid_ctrl_menu_strings
[] = {
197 "Menu Item 0 (Skipped)",
199 "Menu Item 2 (Skipped)",
202 "Menu Item 5 (Skipped)",
206 static const struct v4l2_ctrl_config vivid_ctrl_menu
= {
207 .ops
= &vivid_user_gen_ctrl_ops
,
208 .id
= VIVID_CID_MENU
,
210 .type
= V4L2_CTRL_TYPE_MENU
,
214 .menu_skip_mask
= 0x04,
215 .qmenu
= vivid_ctrl_menu_strings
,
218 static const struct v4l2_ctrl_config vivid_ctrl_string
= {
219 .ops
= &vivid_user_gen_ctrl_ops
,
220 .id
= VIVID_CID_STRING
,
222 .type
= V4L2_CTRL_TYPE_STRING
,
228 static const struct v4l2_ctrl_config vivid_ctrl_bitmask
= {
229 .ops
= &vivid_user_gen_ctrl_ops
,
230 .id
= VIVID_CID_BITMASK
,
232 .type
= V4L2_CTRL_TYPE_BITMASK
,
239 static const s64 vivid_ctrl_int_menu_values
[] = {
240 1, 1, 2, 3, 5, 8, 13, 21, 42,
243 static const struct v4l2_ctrl_config vivid_ctrl_int_menu
= {
244 .ops
= &vivid_user_gen_ctrl_ops
,
245 .id
= VIVID_CID_INTMENU
,
246 .name
= "Integer Menu",
247 .type
= V4L2_CTRL_TYPE_INTEGER_MENU
,
251 .menu_skip_mask
= 0x02,
252 .qmenu_int
= vivid_ctrl_int_menu_values
,
255 static const struct v4l2_ctrl_config vivid_ctrl_disconnect
= {
256 .ops
= &vivid_user_gen_ctrl_ops
,
257 .id
= VIVID_CID_DISCONNECT
,
258 .name
= "Disconnect",
259 .type
= V4L2_CTRL_TYPE_BUTTON
,
263 /* Framebuffer Controls */
265 static int vivid_fb_s_ctrl(struct v4l2_ctrl
*ctrl
)
267 struct vivid_dev
*dev
= container_of(ctrl
->handler
,
268 struct vivid_dev
, ctrl_hdl_fb
);
271 case VIVID_CID_CLEAR_FB
:
278 static const struct v4l2_ctrl_ops vivid_fb_ctrl_ops
= {
279 .s_ctrl
= vivid_fb_s_ctrl
,
282 static const struct v4l2_ctrl_config vivid_ctrl_clear_fb
= {
283 .ops
= &vivid_fb_ctrl_ops
,
284 .id
= VIVID_CID_CLEAR_FB
,
285 .name
= "Clear Framebuffer",
286 .type
= V4L2_CTRL_TYPE_BUTTON
,
290 /* Video User Controls */
292 static int vivid_user_vid_g_volatile_ctrl(struct v4l2_ctrl
*ctrl
)
294 struct vivid_dev
*dev
= container_of(ctrl
->handler
, struct vivid_dev
, ctrl_hdl_user_vid
);
297 case V4L2_CID_AUTOGAIN
:
298 dev
->gain
->val
= (jiffies_to_msecs(jiffies
) / 1000) & 0xff;
304 static int vivid_user_vid_s_ctrl(struct v4l2_ctrl
*ctrl
)
306 struct vivid_dev
*dev
= container_of(ctrl
->handler
, struct vivid_dev
, ctrl_hdl_user_vid
);
309 case V4L2_CID_BRIGHTNESS
:
310 dev
->input_brightness
[dev
->input
] = ctrl
->val
- dev
->input
* 128;
311 tpg_s_brightness(&dev
->tpg
, dev
->input_brightness
[dev
->input
]);
313 case V4L2_CID_CONTRAST
:
314 tpg_s_contrast(&dev
->tpg
, ctrl
->val
);
316 case V4L2_CID_SATURATION
:
317 tpg_s_saturation(&dev
->tpg
, ctrl
->val
);
320 tpg_s_hue(&dev
->tpg
, ctrl
->val
);
323 dev
->hflip
= ctrl
->val
;
324 tpg_s_hflip(&dev
->tpg
, dev
->sensor_hflip
^ dev
->hflip
);
327 dev
->vflip
= ctrl
->val
;
328 tpg_s_vflip(&dev
->tpg
, dev
->sensor_vflip
^ dev
->vflip
);
330 case V4L2_CID_ALPHA_COMPONENT
:
331 tpg_s_alpha_component(&dev
->tpg
, ctrl
->val
);
337 static const struct v4l2_ctrl_ops vivid_user_vid_ctrl_ops
= {
338 .g_volatile_ctrl
= vivid_user_vid_g_volatile_ctrl
,
339 .s_ctrl
= vivid_user_vid_s_ctrl
,
343 /* Video Capture Controls */
345 static int vivid_vid_cap_s_ctrl(struct v4l2_ctrl
*ctrl
)
347 static const u32 colorspaces
[] = {
348 V4L2_COLORSPACE_SMPTE170M
,
349 V4L2_COLORSPACE_REC709
,
350 V4L2_COLORSPACE_SRGB
,
351 V4L2_COLORSPACE_ADOBERGB
,
352 V4L2_COLORSPACE_BT2020
,
353 V4L2_COLORSPACE_DCI_P3
,
354 V4L2_COLORSPACE_SMPTE240M
,
355 V4L2_COLORSPACE_470_SYSTEM_M
,
356 V4L2_COLORSPACE_470_SYSTEM_BG
,
358 struct vivid_dev
*dev
= container_of(ctrl
->handler
, struct vivid_dev
, ctrl_hdl_vid_cap
);
362 case VIVID_CID_TEST_PATTERN
:
363 vivid_update_quality(dev
);
364 tpg_s_pattern(&dev
->tpg
, ctrl
->val
);
366 case VIVID_CID_COLORSPACE
:
367 tpg_s_colorspace(&dev
->tpg
, colorspaces
[ctrl
->val
]);
368 vivid_send_source_change(dev
, TV
);
369 vivid_send_source_change(dev
, SVID
);
370 vivid_send_source_change(dev
, HDMI
);
371 vivid_send_source_change(dev
, WEBCAM
);
373 case VIVID_CID_XFER_FUNC
:
374 tpg_s_xfer_func(&dev
->tpg
, ctrl
->val
);
375 vivid_send_source_change(dev
, TV
);
376 vivid_send_source_change(dev
, SVID
);
377 vivid_send_source_change(dev
, HDMI
);
378 vivid_send_source_change(dev
, WEBCAM
);
380 case VIVID_CID_YCBCR_ENC
:
381 tpg_s_ycbcr_enc(&dev
->tpg
, ctrl
->val
);
382 vivid_send_source_change(dev
, TV
);
383 vivid_send_source_change(dev
, SVID
);
384 vivid_send_source_change(dev
, HDMI
);
385 vivid_send_source_change(dev
, WEBCAM
);
387 case VIVID_CID_HSV_ENC
:
388 tpg_s_hsv_enc(&dev
->tpg
, ctrl
->val
? V4L2_HSV_ENC_256
:
390 vivid_send_source_change(dev
, TV
);
391 vivid_send_source_change(dev
, SVID
);
392 vivid_send_source_change(dev
, HDMI
);
393 vivid_send_source_change(dev
, WEBCAM
);
395 case VIVID_CID_QUANTIZATION
:
396 tpg_s_quantization(&dev
->tpg
, ctrl
->val
);
397 vivid_send_source_change(dev
, TV
);
398 vivid_send_source_change(dev
, SVID
);
399 vivid_send_source_change(dev
, HDMI
);
400 vivid_send_source_change(dev
, WEBCAM
);
402 case V4L2_CID_DV_RX_RGB_RANGE
:
403 if (!vivid_is_hdmi_cap(dev
))
405 tpg_s_rgb_range(&dev
->tpg
, ctrl
->val
);
407 case VIVID_CID_LIMITED_RGB_RANGE
:
408 tpg_s_real_rgb_range(&dev
->tpg
, ctrl
->val
?
409 V4L2_DV_RGB_RANGE_LIMITED
: V4L2_DV_RGB_RANGE_FULL
);
411 case VIVID_CID_ALPHA_MODE
:
412 tpg_s_alpha_mode(&dev
->tpg
, ctrl
->val
);
414 case VIVID_CID_HOR_MOVEMENT
:
415 tpg_s_mv_hor_mode(&dev
->tpg
, ctrl
->val
);
417 case VIVID_CID_VERT_MOVEMENT
:
418 tpg_s_mv_vert_mode(&dev
->tpg
, ctrl
->val
);
420 case VIVID_CID_OSD_TEXT_MODE
:
421 dev
->osd_mode
= ctrl
->val
;
423 case VIVID_CID_PERCENTAGE_FILL
:
424 tpg_s_perc_fill(&dev
->tpg
, ctrl
->val
);
425 for (i
= 0; i
< VIDEO_MAX_FRAME
; i
++)
426 dev
->must_blank
[i
] = ctrl
->val
< 100;
428 case VIVID_CID_INSERT_SAV
:
429 tpg_s_insert_sav(&dev
->tpg
, ctrl
->val
);
431 case VIVID_CID_INSERT_EAV
:
432 tpg_s_insert_eav(&dev
->tpg
, ctrl
->val
);
434 case VIVID_CID_HFLIP
:
435 dev
->sensor_hflip
= ctrl
->val
;
436 tpg_s_hflip(&dev
->tpg
, dev
->sensor_hflip
^ dev
->hflip
);
438 case VIVID_CID_VFLIP
:
439 dev
->sensor_vflip
= ctrl
->val
;
440 tpg_s_vflip(&dev
->tpg
, dev
->sensor_vflip
^ dev
->vflip
);
442 case VIVID_CID_REDUCED_FPS
:
443 dev
->reduced_fps
= ctrl
->val
;
444 vivid_update_format_cap(dev
, true);
446 case VIVID_CID_HAS_CROP_CAP
:
447 dev
->has_crop_cap
= ctrl
->val
;
448 vivid_update_format_cap(dev
, true);
450 case VIVID_CID_HAS_COMPOSE_CAP
:
451 dev
->has_compose_cap
= ctrl
->val
;
452 vivid_update_format_cap(dev
, true);
454 case VIVID_CID_HAS_SCALER_CAP
:
455 dev
->has_scaler_cap
= ctrl
->val
;
456 vivid_update_format_cap(dev
, true);
458 case VIVID_CID_SHOW_BORDER
:
459 tpg_s_show_border(&dev
->tpg
, ctrl
->val
);
461 case VIVID_CID_SHOW_SQUARE
:
462 tpg_s_show_square(&dev
->tpg
, ctrl
->val
);
464 case VIVID_CID_STD_ASPECT_RATIO
:
465 dev
->std_aspect_ratio
= ctrl
->val
;
466 tpg_s_video_aspect(&dev
->tpg
, vivid_get_video_aspect(dev
));
468 case VIVID_CID_DV_TIMINGS_SIGNAL_MODE
:
469 dev
->dv_timings_signal_mode
= dev
->ctrl_dv_timings_signal_mode
->val
;
470 if (dev
->dv_timings_signal_mode
== SELECTED_DV_TIMINGS
)
471 dev
->query_dv_timings
= dev
->ctrl_dv_timings
->val
;
472 v4l2_ctrl_activate(dev
->ctrl_dv_timings
,
473 dev
->dv_timings_signal_mode
== SELECTED_DV_TIMINGS
);
474 vivid_update_quality(dev
);
475 vivid_send_source_change(dev
, HDMI
);
477 case VIVID_CID_DV_TIMINGS_ASPECT_RATIO
:
478 dev
->dv_timings_aspect_ratio
= ctrl
->val
;
479 tpg_s_video_aspect(&dev
->tpg
, vivid_get_video_aspect(dev
));
481 case VIVID_CID_TSTAMP_SRC
:
482 dev
->tstamp_src_is_soe
= ctrl
->val
;
483 dev
->vb_vid_cap_q
.timestamp_flags
&= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK
;
484 if (dev
->tstamp_src_is_soe
)
485 dev
->vb_vid_cap_q
.timestamp_flags
|= V4L2_BUF_FLAG_TSTAMP_SRC_SOE
;
487 case VIVID_CID_MAX_EDID_BLOCKS
:
488 dev
->edid_max_blocks
= ctrl
->val
;
489 if (dev
->edid_blocks
> dev
->edid_max_blocks
)
490 dev
->edid_blocks
= dev
->edid_max_blocks
;
496 static const struct v4l2_ctrl_ops vivid_vid_cap_ctrl_ops
= {
497 .s_ctrl
= vivid_vid_cap_s_ctrl
,
500 static const char * const vivid_ctrl_hor_movement_strings
[] = {
511 static const struct v4l2_ctrl_config vivid_ctrl_hor_movement
= {
512 .ops
= &vivid_vid_cap_ctrl_ops
,
513 .id
= VIVID_CID_HOR_MOVEMENT
,
514 .name
= "Horizontal Movement",
515 .type
= V4L2_CTRL_TYPE_MENU
,
516 .max
= TPG_MOVE_POS_FAST
,
517 .def
= TPG_MOVE_NONE
,
518 .qmenu
= vivid_ctrl_hor_movement_strings
,
521 static const char * const vivid_ctrl_vert_movement_strings
[] = {
532 static const struct v4l2_ctrl_config vivid_ctrl_vert_movement
= {
533 .ops
= &vivid_vid_cap_ctrl_ops
,
534 .id
= VIVID_CID_VERT_MOVEMENT
,
535 .name
= "Vertical Movement",
536 .type
= V4L2_CTRL_TYPE_MENU
,
537 .max
= TPG_MOVE_POS_FAST
,
538 .def
= TPG_MOVE_NONE
,
539 .qmenu
= vivid_ctrl_vert_movement_strings
,
542 static const struct v4l2_ctrl_config vivid_ctrl_show_border
= {
543 .ops
= &vivid_vid_cap_ctrl_ops
,
544 .id
= VIVID_CID_SHOW_BORDER
,
545 .name
= "Show Border",
546 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
551 static const struct v4l2_ctrl_config vivid_ctrl_show_square
= {
552 .ops
= &vivid_vid_cap_ctrl_ops
,
553 .id
= VIVID_CID_SHOW_SQUARE
,
554 .name
= "Show Square",
555 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
560 static const char * const vivid_ctrl_osd_mode_strings
[] = {
567 static const struct v4l2_ctrl_config vivid_ctrl_osd_mode
= {
568 .ops
= &vivid_vid_cap_ctrl_ops
,
569 .id
= VIVID_CID_OSD_TEXT_MODE
,
570 .name
= "OSD Text Mode",
571 .type
= V4L2_CTRL_TYPE_MENU
,
572 .max
= ARRAY_SIZE(vivid_ctrl_osd_mode_strings
) - 2,
573 .qmenu
= vivid_ctrl_osd_mode_strings
,
576 static const struct v4l2_ctrl_config vivid_ctrl_perc_fill
= {
577 .ops
= &vivid_vid_cap_ctrl_ops
,
578 .id
= VIVID_CID_PERCENTAGE_FILL
,
579 .name
= "Fill Percentage of Frame",
580 .type
= V4L2_CTRL_TYPE_INTEGER
,
587 static const struct v4l2_ctrl_config vivid_ctrl_insert_sav
= {
588 .ops
= &vivid_vid_cap_ctrl_ops
,
589 .id
= VIVID_CID_INSERT_SAV
,
590 .name
= "Insert SAV Code in Image",
591 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
596 static const struct v4l2_ctrl_config vivid_ctrl_insert_eav
= {
597 .ops
= &vivid_vid_cap_ctrl_ops
,
598 .id
= VIVID_CID_INSERT_EAV
,
599 .name
= "Insert EAV Code in Image",
600 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
605 static const struct v4l2_ctrl_config vivid_ctrl_hflip
= {
606 .ops
= &vivid_vid_cap_ctrl_ops
,
607 .id
= VIVID_CID_HFLIP
,
608 .name
= "Sensor Flipped Horizontally",
609 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
614 static const struct v4l2_ctrl_config vivid_ctrl_vflip
= {
615 .ops
= &vivid_vid_cap_ctrl_ops
,
616 .id
= VIVID_CID_VFLIP
,
617 .name
= "Sensor Flipped Vertically",
618 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
623 static const struct v4l2_ctrl_config vivid_ctrl_reduced_fps
= {
624 .ops
= &vivid_vid_cap_ctrl_ops
,
625 .id
= VIVID_CID_REDUCED_FPS
,
626 .name
= "Reduced Framerate",
627 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
632 static const struct v4l2_ctrl_config vivid_ctrl_has_crop_cap
= {
633 .ops
= &vivid_vid_cap_ctrl_ops
,
634 .id
= VIVID_CID_HAS_CROP_CAP
,
635 .name
= "Enable Capture Cropping",
636 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
642 static const struct v4l2_ctrl_config vivid_ctrl_has_compose_cap
= {
643 .ops
= &vivid_vid_cap_ctrl_ops
,
644 .id
= VIVID_CID_HAS_COMPOSE_CAP
,
645 .name
= "Enable Capture Composing",
646 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
652 static const struct v4l2_ctrl_config vivid_ctrl_has_scaler_cap
= {
653 .ops
= &vivid_vid_cap_ctrl_ops
,
654 .id
= VIVID_CID_HAS_SCALER_CAP
,
655 .name
= "Enable Capture Scaler",
656 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
662 static const char * const vivid_ctrl_tstamp_src_strings
[] = {
668 static const struct v4l2_ctrl_config vivid_ctrl_tstamp_src
= {
669 .ops
= &vivid_vid_cap_ctrl_ops
,
670 .id
= VIVID_CID_TSTAMP_SRC
,
671 .name
= "Timestamp Source",
672 .type
= V4L2_CTRL_TYPE_MENU
,
673 .max
= ARRAY_SIZE(vivid_ctrl_tstamp_src_strings
) - 2,
674 .qmenu
= vivid_ctrl_tstamp_src_strings
,
677 static const struct v4l2_ctrl_config vivid_ctrl_std_aspect_ratio
= {
678 .ops
= &vivid_vid_cap_ctrl_ops
,
679 .id
= VIVID_CID_STD_ASPECT_RATIO
,
680 .name
= "Standard Aspect Ratio",
681 .type
= V4L2_CTRL_TYPE_MENU
,
685 .qmenu
= tpg_aspect_strings
,
688 static const char * const vivid_ctrl_dv_timings_signal_mode_strings
[] = {
689 "Current DV Timings",
693 "Selected DV Timings",
694 "Cycle Through All DV Timings",
699 static const struct v4l2_ctrl_config vivid_ctrl_dv_timings_signal_mode
= {
700 .ops
= &vivid_vid_cap_ctrl_ops
,
701 .id
= VIVID_CID_DV_TIMINGS_SIGNAL_MODE
,
702 .name
= "DV Timings Signal Mode",
703 .type
= V4L2_CTRL_TYPE_MENU
,
705 .qmenu
= vivid_ctrl_dv_timings_signal_mode_strings
,
708 static const struct v4l2_ctrl_config vivid_ctrl_dv_timings_aspect_ratio
= {
709 .ops
= &vivid_vid_cap_ctrl_ops
,
710 .id
= VIVID_CID_DV_TIMINGS_ASPECT_RATIO
,
711 .name
= "DV Timings Aspect Ratio",
712 .type
= V4L2_CTRL_TYPE_MENU
,
714 .qmenu
= tpg_aspect_strings
,
717 static const struct v4l2_ctrl_config vivid_ctrl_max_edid_blocks
= {
718 .ops
= &vivid_vid_cap_ctrl_ops
,
719 .id
= VIVID_CID_MAX_EDID_BLOCKS
,
720 .name
= "Maximum EDID Blocks",
721 .type
= V4L2_CTRL_TYPE_INTEGER
,
728 static const char * const vivid_ctrl_colorspace_strings
[] = {
741 static const struct v4l2_ctrl_config vivid_ctrl_colorspace
= {
742 .ops
= &vivid_vid_cap_ctrl_ops
,
743 .id
= VIVID_CID_COLORSPACE
,
744 .name
= "Colorspace",
745 .type
= V4L2_CTRL_TYPE_MENU
,
746 .max
= ARRAY_SIZE(vivid_ctrl_colorspace_strings
) - 2,
748 .qmenu
= vivid_ctrl_colorspace_strings
,
751 static const char * const vivid_ctrl_xfer_func_strings
[] = {
763 static const struct v4l2_ctrl_config vivid_ctrl_xfer_func
= {
764 .ops
= &vivid_vid_cap_ctrl_ops
,
765 .id
= VIVID_CID_XFER_FUNC
,
766 .name
= "Transfer Function",
767 .type
= V4L2_CTRL_TYPE_MENU
,
768 .max
= ARRAY_SIZE(vivid_ctrl_xfer_func_strings
) - 2,
769 .qmenu
= vivid_ctrl_xfer_func_strings
,
772 static const char * const vivid_ctrl_ycbcr_enc_strings
[] = {
780 "BT.2020 Constant Luminance",
785 static const struct v4l2_ctrl_config vivid_ctrl_ycbcr_enc
= {
786 .ops
= &vivid_vid_cap_ctrl_ops
,
787 .id
= VIVID_CID_YCBCR_ENC
,
788 .name
= "Y'CbCr Encoding",
789 .type
= V4L2_CTRL_TYPE_MENU
,
790 .menu_skip_mask
= 1 << 5,
791 .max
= ARRAY_SIZE(vivid_ctrl_ycbcr_enc_strings
) - 2,
792 .qmenu
= vivid_ctrl_ycbcr_enc_strings
,
795 static const char * const vivid_ctrl_hsv_enc_strings
[] = {
801 static const struct v4l2_ctrl_config vivid_ctrl_hsv_enc
= {
802 .ops
= &vivid_vid_cap_ctrl_ops
,
803 .id
= VIVID_CID_HSV_ENC
,
804 .name
= "HSV Encoding",
805 .type
= V4L2_CTRL_TYPE_MENU
,
806 .max
= ARRAY_SIZE(vivid_ctrl_hsv_enc_strings
) - 2,
807 .qmenu
= vivid_ctrl_hsv_enc_strings
,
810 static const char * const vivid_ctrl_quantization_strings
[] = {
817 static const struct v4l2_ctrl_config vivid_ctrl_quantization
= {
818 .ops
= &vivid_vid_cap_ctrl_ops
,
819 .id
= VIVID_CID_QUANTIZATION
,
820 .name
= "Quantization",
821 .type
= V4L2_CTRL_TYPE_MENU
,
822 .max
= ARRAY_SIZE(vivid_ctrl_quantization_strings
) - 2,
823 .qmenu
= vivid_ctrl_quantization_strings
,
826 static const struct v4l2_ctrl_config vivid_ctrl_alpha_mode
= {
827 .ops
= &vivid_vid_cap_ctrl_ops
,
828 .id
= VIVID_CID_ALPHA_MODE
,
829 .name
= "Apply Alpha To Red Only",
830 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
835 static const struct v4l2_ctrl_config vivid_ctrl_limited_rgb_range
= {
836 .ops
= &vivid_vid_cap_ctrl_ops
,
837 .id
= VIVID_CID_LIMITED_RGB_RANGE
,
838 .name
= "Limited RGB Range (16-235)",
839 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
845 /* Video Loop Control */
847 static int vivid_loop_cap_s_ctrl(struct v4l2_ctrl
*ctrl
)
849 struct vivid_dev
*dev
= container_of(ctrl
->handler
, struct vivid_dev
, ctrl_hdl_loop_cap
);
852 case VIVID_CID_LOOP_VIDEO
:
853 dev
->loop_video
= ctrl
->val
;
854 vivid_update_quality(dev
);
855 vivid_send_source_change(dev
, SVID
);
856 vivid_send_source_change(dev
, HDMI
);
862 static const struct v4l2_ctrl_ops vivid_loop_cap_ctrl_ops
= {
863 .s_ctrl
= vivid_loop_cap_s_ctrl
,
866 static const struct v4l2_ctrl_config vivid_ctrl_loop_video
= {
867 .ops
= &vivid_loop_cap_ctrl_ops
,
868 .id
= VIVID_CID_LOOP_VIDEO
,
869 .name
= "Loop Video",
870 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
876 /* VBI Capture Control */
878 static int vivid_vbi_cap_s_ctrl(struct v4l2_ctrl
*ctrl
)
880 struct vivid_dev
*dev
= container_of(ctrl
->handler
, struct vivid_dev
, ctrl_hdl_vbi_cap
);
883 case VIVID_CID_VBI_CAP_INTERLACED
:
884 dev
->vbi_cap_interlaced
= ctrl
->val
;
890 static const struct v4l2_ctrl_ops vivid_vbi_cap_ctrl_ops
= {
891 .s_ctrl
= vivid_vbi_cap_s_ctrl
,
894 static const struct v4l2_ctrl_config vivid_ctrl_vbi_cap_interlaced
= {
895 .ops
= &vivid_vbi_cap_ctrl_ops
,
896 .id
= VIVID_CID_VBI_CAP_INTERLACED
,
897 .name
= "Interlaced VBI Format",
898 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
904 /* Video Output Controls */
906 static int vivid_vid_out_s_ctrl(struct v4l2_ctrl
*ctrl
)
908 struct vivid_dev
*dev
= container_of(ctrl
->handler
, struct vivid_dev
, ctrl_hdl_vid_out
);
909 struct v4l2_bt_timings
*bt
= &dev
->dv_timings_out
.bt
;
912 case VIVID_CID_HAS_CROP_OUT
:
913 dev
->has_crop_out
= ctrl
->val
;
914 vivid_update_format_out(dev
);
916 case VIVID_CID_HAS_COMPOSE_OUT
:
917 dev
->has_compose_out
= ctrl
->val
;
918 vivid_update_format_out(dev
);
920 case VIVID_CID_HAS_SCALER_OUT
:
921 dev
->has_scaler_out
= ctrl
->val
;
922 vivid_update_format_out(dev
);
924 case V4L2_CID_DV_TX_MODE
:
925 dev
->dvi_d_out
= ctrl
->val
== V4L2_DV_TX_MODE_DVI_D
;
926 if (!vivid_is_hdmi_out(dev
))
928 if (!dev
->dvi_d_out
&& (bt
->flags
& V4L2_DV_FL_IS_CE_VIDEO
)) {
929 if (bt
->width
== 720 && bt
->height
<= 576)
930 dev
->colorspace_out
= V4L2_COLORSPACE_SMPTE170M
;
932 dev
->colorspace_out
= V4L2_COLORSPACE_REC709
;
933 dev
->quantization_out
= V4L2_QUANTIZATION_DEFAULT
;
935 dev
->colorspace_out
= V4L2_COLORSPACE_SRGB
;
936 dev
->quantization_out
= dev
->dvi_d_out
?
937 V4L2_QUANTIZATION_LIM_RANGE
:
938 V4L2_QUANTIZATION_DEFAULT
;
941 vivid_send_source_change(dev
, HDMI
);
947 static const struct v4l2_ctrl_ops vivid_vid_out_ctrl_ops
= {
948 .s_ctrl
= vivid_vid_out_s_ctrl
,
951 static const struct v4l2_ctrl_config vivid_ctrl_has_crop_out
= {
952 .ops
= &vivid_vid_out_ctrl_ops
,
953 .id
= VIVID_CID_HAS_CROP_OUT
,
954 .name
= "Enable Output Cropping",
955 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
961 static const struct v4l2_ctrl_config vivid_ctrl_has_compose_out
= {
962 .ops
= &vivid_vid_out_ctrl_ops
,
963 .id
= VIVID_CID_HAS_COMPOSE_OUT
,
964 .name
= "Enable Output Composing",
965 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
971 static const struct v4l2_ctrl_config vivid_ctrl_has_scaler_out
= {
972 .ops
= &vivid_vid_out_ctrl_ops
,
973 .id
= VIVID_CID_HAS_SCALER_OUT
,
974 .name
= "Enable Output Scaler",
975 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
982 /* Streaming Controls */
984 static int vivid_streaming_s_ctrl(struct v4l2_ctrl
*ctrl
)
986 struct vivid_dev
*dev
= container_of(ctrl
->handler
, struct vivid_dev
, ctrl_hdl_streaming
);
990 case VIVID_CID_DQBUF_ERROR
:
991 dev
->dqbuf_error
= true;
993 case VIVID_CID_PERC_DROPPED
:
994 dev
->perc_dropped_buffers
= ctrl
->val
;
996 case VIVID_CID_QUEUE_SETUP_ERROR
:
997 dev
->queue_setup_error
= true;
999 case VIVID_CID_BUF_PREPARE_ERROR
:
1000 dev
->buf_prepare_error
= true;
1002 case VIVID_CID_START_STR_ERROR
:
1003 dev
->start_streaming_error
= true;
1005 case VIVID_CID_QUEUE_ERROR
:
1006 if (vb2_start_streaming_called(&dev
->vb_vid_cap_q
))
1007 vb2_queue_error(&dev
->vb_vid_cap_q
);
1008 if (vb2_start_streaming_called(&dev
->vb_vbi_cap_q
))
1009 vb2_queue_error(&dev
->vb_vbi_cap_q
);
1010 if (vb2_start_streaming_called(&dev
->vb_vid_out_q
))
1011 vb2_queue_error(&dev
->vb_vid_out_q
);
1012 if (vb2_start_streaming_called(&dev
->vb_vbi_out_q
))
1013 vb2_queue_error(&dev
->vb_vbi_out_q
);
1014 if (vb2_start_streaming_called(&dev
->vb_sdr_cap_q
))
1015 vb2_queue_error(&dev
->vb_sdr_cap_q
);
1017 case VIVID_CID_SEQ_WRAP
:
1018 dev
->seq_wrap
= ctrl
->val
;
1020 case VIVID_CID_TIME_WRAP
:
1021 dev
->time_wrap
= ctrl
->val
;
1022 if (ctrl
->val
== 0) {
1023 dev
->time_wrap_offset
= 0;
1027 * We want to set the time 16 seconds before the 32 bit tv_sec
1028 * value of struct timeval would wrap around. So first we
1029 * calculate ktime_get_ns() % ((1 << 32) * NSEC_PER_SEC), and
1030 * then we set the offset to ((1 << 32) - 16) * NSEC_PER_SEC).
1032 div64_u64_rem(ktime_get_ns(),
1033 0x100000000ULL
* NSEC_PER_SEC
, &rem
);
1034 dev
->time_wrap_offset
=
1035 (0x100000000ULL
- 16) * NSEC_PER_SEC
- rem
;
1041 static const struct v4l2_ctrl_ops vivid_streaming_ctrl_ops
= {
1042 .s_ctrl
= vivid_streaming_s_ctrl
,
1045 static const struct v4l2_ctrl_config vivid_ctrl_dqbuf_error
= {
1046 .ops
= &vivid_streaming_ctrl_ops
,
1047 .id
= VIVID_CID_DQBUF_ERROR
,
1048 .name
= "Inject V4L2_BUF_FLAG_ERROR",
1049 .type
= V4L2_CTRL_TYPE_BUTTON
,
1052 static const struct v4l2_ctrl_config vivid_ctrl_perc_dropped
= {
1053 .ops
= &vivid_streaming_ctrl_ops
,
1054 .id
= VIVID_CID_PERC_DROPPED
,
1055 .name
= "Percentage of Dropped Buffers",
1056 .type
= V4L2_CTRL_TYPE_INTEGER
,
1062 static const struct v4l2_ctrl_config vivid_ctrl_queue_setup_error
= {
1063 .ops
= &vivid_streaming_ctrl_ops
,
1064 .id
= VIVID_CID_QUEUE_SETUP_ERROR
,
1065 .name
= "Inject VIDIOC_REQBUFS Error",
1066 .type
= V4L2_CTRL_TYPE_BUTTON
,
1069 static const struct v4l2_ctrl_config vivid_ctrl_buf_prepare_error
= {
1070 .ops
= &vivid_streaming_ctrl_ops
,
1071 .id
= VIVID_CID_BUF_PREPARE_ERROR
,
1072 .name
= "Inject VIDIOC_QBUF Error",
1073 .type
= V4L2_CTRL_TYPE_BUTTON
,
1076 static const struct v4l2_ctrl_config vivid_ctrl_start_streaming_error
= {
1077 .ops
= &vivid_streaming_ctrl_ops
,
1078 .id
= VIVID_CID_START_STR_ERROR
,
1079 .name
= "Inject VIDIOC_STREAMON Error",
1080 .type
= V4L2_CTRL_TYPE_BUTTON
,
1083 static const struct v4l2_ctrl_config vivid_ctrl_queue_error
= {
1084 .ops
= &vivid_streaming_ctrl_ops
,
1085 .id
= VIVID_CID_QUEUE_ERROR
,
1086 .name
= "Inject Fatal Streaming Error",
1087 .type
= V4L2_CTRL_TYPE_BUTTON
,
1090 static const struct v4l2_ctrl_config vivid_ctrl_seq_wrap
= {
1091 .ops
= &vivid_streaming_ctrl_ops
,
1092 .id
= VIVID_CID_SEQ_WRAP
,
1093 .name
= "Wrap Sequence Number",
1094 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
1099 static const struct v4l2_ctrl_config vivid_ctrl_time_wrap
= {
1100 .ops
= &vivid_streaming_ctrl_ops
,
1101 .id
= VIVID_CID_TIME_WRAP
,
1102 .name
= "Wrap Timestamp",
1103 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
1109 /* SDTV Capture Controls */
1111 static int vivid_sdtv_cap_s_ctrl(struct v4l2_ctrl
*ctrl
)
1113 struct vivid_dev
*dev
= container_of(ctrl
->handler
, struct vivid_dev
, ctrl_hdl_sdtv_cap
);
1116 case VIVID_CID_STD_SIGNAL_MODE
:
1117 dev
->std_signal_mode
= dev
->ctrl_std_signal_mode
->val
;
1118 if (dev
->std_signal_mode
== SELECTED_STD
)
1119 dev
->query_std
= vivid_standard
[dev
->ctrl_standard
->val
];
1120 v4l2_ctrl_activate(dev
->ctrl_standard
, dev
->std_signal_mode
== SELECTED_STD
);
1121 vivid_update_quality(dev
);
1122 vivid_send_source_change(dev
, TV
);
1123 vivid_send_source_change(dev
, SVID
);
1129 static const struct v4l2_ctrl_ops vivid_sdtv_cap_ctrl_ops
= {
1130 .s_ctrl
= vivid_sdtv_cap_s_ctrl
,
1133 static const char * const vivid_ctrl_std_signal_mode_strings
[] = {
1138 "Selected Standard",
1139 "Cycle Through All Standards",
1143 static const struct v4l2_ctrl_config vivid_ctrl_std_signal_mode
= {
1144 .ops
= &vivid_sdtv_cap_ctrl_ops
,
1145 .id
= VIVID_CID_STD_SIGNAL_MODE
,
1146 .name
= "Standard Signal Mode",
1147 .type
= V4L2_CTRL_TYPE_MENU
,
1148 .max
= ARRAY_SIZE(vivid_ctrl_std_signal_mode_strings
) - 2,
1149 .menu_skip_mask
= 1 << 3,
1150 .qmenu
= vivid_ctrl_std_signal_mode_strings
,
1153 static const struct v4l2_ctrl_config vivid_ctrl_standard
= {
1154 .ops
= &vivid_sdtv_cap_ctrl_ops
,
1155 .id
= VIVID_CID_STANDARD
,
1157 .type
= V4L2_CTRL_TYPE_MENU
,
1159 .qmenu
= vivid_ctrl_standard_strings
,
1164 /* Radio Receiver Controls */
1166 static int vivid_radio_rx_s_ctrl(struct v4l2_ctrl
*ctrl
)
1168 struct vivid_dev
*dev
= container_of(ctrl
->handler
, struct vivid_dev
, ctrl_hdl_radio_rx
);
1171 case VIVID_CID_RADIO_SEEK_MODE
:
1172 dev
->radio_rx_hw_seek_mode
= ctrl
->val
;
1174 case VIVID_CID_RADIO_SEEK_PROG_LIM
:
1175 dev
->radio_rx_hw_seek_prog_lim
= ctrl
->val
;
1177 case VIVID_CID_RADIO_RX_RDS_RBDS
:
1178 dev
->rds_gen
.use_rbds
= ctrl
->val
;
1180 case VIVID_CID_RADIO_RX_RDS_BLOCKIO
:
1181 dev
->radio_rx_rds_controls
= ctrl
->val
;
1182 dev
->radio_rx_caps
&= ~V4L2_CAP_READWRITE
;
1183 dev
->radio_rx_rds_use_alternates
= false;
1184 if (!dev
->radio_rx_rds_controls
) {
1185 dev
->radio_rx_caps
|= V4L2_CAP_READWRITE
;
1186 __v4l2_ctrl_s_ctrl(dev
->radio_rx_rds_pty
, 0);
1187 __v4l2_ctrl_s_ctrl(dev
->radio_rx_rds_ta
, 0);
1188 __v4l2_ctrl_s_ctrl(dev
->radio_rx_rds_tp
, 0);
1189 __v4l2_ctrl_s_ctrl(dev
->radio_rx_rds_ms
, 0);
1190 __v4l2_ctrl_s_ctrl_string(dev
->radio_rx_rds_psname
, "");
1191 __v4l2_ctrl_s_ctrl_string(dev
->radio_rx_rds_radiotext
, "");
1193 v4l2_ctrl_activate(dev
->radio_rx_rds_pty
, dev
->radio_rx_rds_controls
);
1194 v4l2_ctrl_activate(dev
->radio_rx_rds_psname
, dev
->radio_rx_rds_controls
);
1195 v4l2_ctrl_activate(dev
->radio_rx_rds_radiotext
, dev
->radio_rx_rds_controls
);
1196 v4l2_ctrl_activate(dev
->radio_rx_rds_ta
, dev
->radio_rx_rds_controls
);
1197 v4l2_ctrl_activate(dev
->radio_rx_rds_tp
, dev
->radio_rx_rds_controls
);
1198 v4l2_ctrl_activate(dev
->radio_rx_rds_ms
, dev
->radio_rx_rds_controls
);
1199 dev
->radio_rx_dev
.device_caps
= dev
->radio_rx_caps
;
1201 case V4L2_CID_RDS_RECEPTION
:
1202 dev
->radio_rx_rds_enabled
= ctrl
->val
;
1208 static const struct v4l2_ctrl_ops vivid_radio_rx_ctrl_ops
= {
1209 .s_ctrl
= vivid_radio_rx_s_ctrl
,
1212 static const char * const vivid_ctrl_radio_rds_mode_strings
[] = {
1218 static const struct v4l2_ctrl_config vivid_ctrl_radio_rx_rds_blockio
= {
1219 .ops
= &vivid_radio_rx_ctrl_ops
,
1220 .id
= VIVID_CID_RADIO_RX_RDS_BLOCKIO
,
1221 .name
= "RDS Rx I/O Mode",
1222 .type
= V4L2_CTRL_TYPE_MENU
,
1223 .qmenu
= vivid_ctrl_radio_rds_mode_strings
,
1227 static const struct v4l2_ctrl_config vivid_ctrl_radio_rx_rds_rbds
= {
1228 .ops
= &vivid_radio_rx_ctrl_ops
,
1229 .id
= VIVID_CID_RADIO_RX_RDS_RBDS
,
1230 .name
= "Generate RBDS Instead of RDS",
1231 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
1236 static const char * const vivid_ctrl_radio_hw_seek_mode_strings
[] = {
1243 static const struct v4l2_ctrl_config vivid_ctrl_radio_hw_seek_mode
= {
1244 .ops
= &vivid_radio_rx_ctrl_ops
,
1245 .id
= VIVID_CID_RADIO_SEEK_MODE
,
1246 .name
= "Radio HW Seek Mode",
1247 .type
= V4L2_CTRL_TYPE_MENU
,
1249 .qmenu
= vivid_ctrl_radio_hw_seek_mode_strings
,
1252 static const struct v4l2_ctrl_config vivid_ctrl_radio_hw_seek_prog_lim
= {
1253 .ops
= &vivid_radio_rx_ctrl_ops
,
1254 .id
= VIVID_CID_RADIO_SEEK_PROG_LIM
,
1255 .name
= "Radio Programmable HW Seek",
1256 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
1262 /* Radio Transmitter Controls */
1264 static int vivid_radio_tx_s_ctrl(struct v4l2_ctrl
*ctrl
)
1266 struct vivid_dev
*dev
= container_of(ctrl
->handler
, struct vivid_dev
, ctrl_hdl_radio_tx
);
1269 case VIVID_CID_RADIO_TX_RDS_BLOCKIO
:
1270 dev
->radio_tx_rds_controls
= ctrl
->val
;
1271 dev
->radio_tx_caps
&= ~V4L2_CAP_READWRITE
;
1272 if (!dev
->radio_tx_rds_controls
)
1273 dev
->radio_tx_caps
|= V4L2_CAP_READWRITE
;
1274 dev
->radio_tx_dev
.device_caps
= dev
->radio_tx_caps
;
1276 case V4L2_CID_RDS_TX_PTY
:
1277 if (dev
->radio_rx_rds_controls
)
1278 v4l2_ctrl_s_ctrl(dev
->radio_rx_rds_pty
, ctrl
->val
);
1280 case V4L2_CID_RDS_TX_PS_NAME
:
1281 if (dev
->radio_rx_rds_controls
)
1282 v4l2_ctrl_s_ctrl_string(dev
->radio_rx_rds_psname
, ctrl
->p_new
.p_char
);
1284 case V4L2_CID_RDS_TX_RADIO_TEXT
:
1285 if (dev
->radio_rx_rds_controls
)
1286 v4l2_ctrl_s_ctrl_string(dev
->radio_rx_rds_radiotext
, ctrl
->p_new
.p_char
);
1288 case V4L2_CID_RDS_TX_TRAFFIC_ANNOUNCEMENT
:
1289 if (dev
->radio_rx_rds_controls
)
1290 v4l2_ctrl_s_ctrl(dev
->radio_rx_rds_ta
, ctrl
->val
);
1292 case V4L2_CID_RDS_TX_TRAFFIC_PROGRAM
:
1293 if (dev
->radio_rx_rds_controls
)
1294 v4l2_ctrl_s_ctrl(dev
->radio_rx_rds_tp
, ctrl
->val
);
1296 case V4L2_CID_RDS_TX_MUSIC_SPEECH
:
1297 if (dev
->radio_rx_rds_controls
)
1298 v4l2_ctrl_s_ctrl(dev
->radio_rx_rds_ms
, ctrl
->val
);
1304 static const struct v4l2_ctrl_ops vivid_radio_tx_ctrl_ops
= {
1305 .s_ctrl
= vivid_radio_tx_s_ctrl
,
1308 static const struct v4l2_ctrl_config vivid_ctrl_radio_tx_rds_blockio
= {
1309 .ops
= &vivid_radio_tx_ctrl_ops
,
1310 .id
= VIVID_CID_RADIO_TX_RDS_BLOCKIO
,
1311 .name
= "RDS Tx I/O Mode",
1312 .type
= V4L2_CTRL_TYPE_MENU
,
1313 .qmenu
= vivid_ctrl_radio_rds_mode_strings
,
1319 /* SDR Capture Controls */
1321 static int vivid_sdr_cap_s_ctrl(struct v4l2_ctrl
*ctrl
)
1323 struct vivid_dev
*dev
= container_of(ctrl
->handler
, struct vivid_dev
, ctrl_hdl_sdr_cap
);
1326 case VIVID_CID_SDR_CAP_FM_DEVIATION
:
1327 dev
->sdr_fm_deviation
= ctrl
->val
;
1333 static const struct v4l2_ctrl_ops vivid_sdr_cap_ctrl_ops
= {
1334 .s_ctrl
= vivid_sdr_cap_s_ctrl
,
1337 static const struct v4l2_ctrl_config vivid_ctrl_sdr_cap_fm_deviation
= {
1338 .ops
= &vivid_sdr_cap_ctrl_ops
,
1339 .id
= VIVID_CID_SDR_CAP_FM_DEVIATION
,
1340 .name
= "FM Deviation",
1341 .type
= V4L2_CTRL_TYPE_INTEGER
,
1349 static const struct v4l2_ctrl_config vivid_ctrl_class
= {
1350 .ops
= &vivid_user_gen_ctrl_ops
,
1351 .flags
= V4L2_CTRL_FLAG_READ_ONLY
| V4L2_CTRL_FLAG_WRITE_ONLY
,
1352 .id
= VIVID_CID_VIVID_CLASS
,
1353 .name
= "Vivid Controls",
1354 .type
= V4L2_CTRL_TYPE_CTRL_CLASS
,
1357 int vivid_create_controls(struct vivid_dev
*dev
, bool show_ccs_cap
,
1358 bool show_ccs_out
, bool no_error_inj
,
1359 bool has_sdtv
, bool has_hdmi
)
1361 struct v4l2_ctrl_handler
*hdl_user_gen
= &dev
->ctrl_hdl_user_gen
;
1362 struct v4l2_ctrl_handler
*hdl_user_vid
= &dev
->ctrl_hdl_user_vid
;
1363 struct v4l2_ctrl_handler
*hdl_user_aud
= &dev
->ctrl_hdl_user_aud
;
1364 struct v4l2_ctrl_handler
*hdl_streaming
= &dev
->ctrl_hdl_streaming
;
1365 struct v4l2_ctrl_handler
*hdl_sdtv_cap
= &dev
->ctrl_hdl_sdtv_cap
;
1366 struct v4l2_ctrl_handler
*hdl_loop_cap
= &dev
->ctrl_hdl_loop_cap
;
1367 struct v4l2_ctrl_handler
*hdl_fb
= &dev
->ctrl_hdl_fb
;
1368 struct v4l2_ctrl_handler
*hdl_vid_cap
= &dev
->ctrl_hdl_vid_cap
;
1369 struct v4l2_ctrl_handler
*hdl_vid_out
= &dev
->ctrl_hdl_vid_out
;
1370 struct v4l2_ctrl_handler
*hdl_vbi_cap
= &dev
->ctrl_hdl_vbi_cap
;
1371 struct v4l2_ctrl_handler
*hdl_vbi_out
= &dev
->ctrl_hdl_vbi_out
;
1372 struct v4l2_ctrl_handler
*hdl_radio_rx
= &dev
->ctrl_hdl_radio_rx
;
1373 struct v4l2_ctrl_handler
*hdl_radio_tx
= &dev
->ctrl_hdl_radio_tx
;
1374 struct v4l2_ctrl_handler
*hdl_sdr_cap
= &dev
->ctrl_hdl_sdr_cap
;
1375 struct v4l2_ctrl_config vivid_ctrl_dv_timings
= {
1376 .ops
= &vivid_vid_cap_ctrl_ops
,
1377 .id
= VIVID_CID_DV_TIMINGS
,
1378 .name
= "DV Timings",
1379 .type
= V4L2_CTRL_TYPE_MENU
,
1383 v4l2_ctrl_handler_init(hdl_user_gen
, 10);
1384 v4l2_ctrl_new_custom(hdl_user_gen
, &vivid_ctrl_class
, NULL
);
1385 v4l2_ctrl_handler_init(hdl_user_vid
, 9);
1386 v4l2_ctrl_new_custom(hdl_user_vid
, &vivid_ctrl_class
, NULL
);
1387 v4l2_ctrl_handler_init(hdl_user_aud
, 2);
1388 v4l2_ctrl_new_custom(hdl_user_aud
, &vivid_ctrl_class
, NULL
);
1389 v4l2_ctrl_handler_init(hdl_streaming
, 8);
1390 v4l2_ctrl_new_custom(hdl_streaming
, &vivid_ctrl_class
, NULL
);
1391 v4l2_ctrl_handler_init(hdl_sdtv_cap
, 2);
1392 v4l2_ctrl_new_custom(hdl_sdtv_cap
, &vivid_ctrl_class
, NULL
);
1393 v4l2_ctrl_handler_init(hdl_loop_cap
, 1);
1394 v4l2_ctrl_new_custom(hdl_loop_cap
, &vivid_ctrl_class
, NULL
);
1395 v4l2_ctrl_handler_init(hdl_fb
, 1);
1396 v4l2_ctrl_new_custom(hdl_fb
, &vivid_ctrl_class
, NULL
);
1397 v4l2_ctrl_handler_init(hdl_vid_cap
, 55);
1398 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_class
, NULL
);
1399 v4l2_ctrl_handler_init(hdl_vid_out
, 26);
1400 if (!no_error_inj
|| dev
->has_fb
)
1401 v4l2_ctrl_new_custom(hdl_vid_out
, &vivid_ctrl_class
, NULL
);
1402 v4l2_ctrl_handler_init(hdl_vbi_cap
, 21);
1403 v4l2_ctrl_new_custom(hdl_vbi_cap
, &vivid_ctrl_class
, NULL
);
1404 v4l2_ctrl_handler_init(hdl_vbi_out
, 19);
1406 v4l2_ctrl_new_custom(hdl_vbi_out
, &vivid_ctrl_class
, NULL
);
1407 v4l2_ctrl_handler_init(hdl_radio_rx
, 17);
1408 v4l2_ctrl_new_custom(hdl_radio_rx
, &vivid_ctrl_class
, NULL
);
1409 v4l2_ctrl_handler_init(hdl_radio_tx
, 17);
1410 v4l2_ctrl_new_custom(hdl_radio_tx
, &vivid_ctrl_class
, NULL
);
1411 v4l2_ctrl_handler_init(hdl_sdr_cap
, 19);
1412 v4l2_ctrl_new_custom(hdl_sdr_cap
, &vivid_ctrl_class
, NULL
);
1415 dev
->volume
= v4l2_ctrl_new_std(hdl_user_aud
, NULL
,
1416 V4L2_CID_AUDIO_VOLUME
, 0, 255, 1, 200);
1417 dev
->mute
= v4l2_ctrl_new_std(hdl_user_aud
, NULL
,
1418 V4L2_CID_AUDIO_MUTE
, 0, 1, 1, 0);
1419 if (dev
->has_vid_cap
) {
1420 dev
->brightness
= v4l2_ctrl_new_std(hdl_user_vid
, &vivid_user_vid_ctrl_ops
,
1421 V4L2_CID_BRIGHTNESS
, 0, 255, 1, 128);
1422 for (i
= 0; i
< MAX_INPUTS
; i
++)
1423 dev
->input_brightness
[i
] = 128;
1424 dev
->contrast
= v4l2_ctrl_new_std(hdl_user_vid
, &vivid_user_vid_ctrl_ops
,
1425 V4L2_CID_CONTRAST
, 0, 255, 1, 128);
1426 dev
->saturation
= v4l2_ctrl_new_std(hdl_user_vid
, &vivid_user_vid_ctrl_ops
,
1427 V4L2_CID_SATURATION
, 0, 255, 1, 128);
1428 dev
->hue
= v4l2_ctrl_new_std(hdl_user_vid
, &vivid_user_vid_ctrl_ops
,
1429 V4L2_CID_HUE
, -128, 128, 1, 0);
1430 v4l2_ctrl_new_std(hdl_user_vid
, &vivid_user_vid_ctrl_ops
,
1431 V4L2_CID_HFLIP
, 0, 1, 1, 0);
1432 v4l2_ctrl_new_std(hdl_user_vid
, &vivid_user_vid_ctrl_ops
,
1433 V4L2_CID_VFLIP
, 0, 1, 1, 0);
1434 dev
->autogain
= v4l2_ctrl_new_std(hdl_user_vid
, &vivid_user_vid_ctrl_ops
,
1435 V4L2_CID_AUTOGAIN
, 0, 1, 1, 1);
1436 dev
->gain
= v4l2_ctrl_new_std(hdl_user_vid
, &vivid_user_vid_ctrl_ops
,
1437 V4L2_CID_GAIN
, 0, 255, 1, 100);
1438 dev
->alpha
= v4l2_ctrl_new_std(hdl_user_vid
, &vivid_user_vid_ctrl_ops
,
1439 V4L2_CID_ALPHA_COMPONENT
, 0, 255, 1, 0);
1441 dev
->button
= v4l2_ctrl_new_custom(hdl_user_gen
, &vivid_ctrl_button
, NULL
);
1442 dev
->int32
= v4l2_ctrl_new_custom(hdl_user_gen
, &vivid_ctrl_int32
, NULL
);
1443 dev
->int64
= v4l2_ctrl_new_custom(hdl_user_gen
, &vivid_ctrl_int64
, NULL
);
1444 dev
->boolean
= v4l2_ctrl_new_custom(hdl_user_gen
, &vivid_ctrl_boolean
, NULL
);
1445 dev
->menu
= v4l2_ctrl_new_custom(hdl_user_gen
, &vivid_ctrl_menu
, NULL
);
1446 dev
->string
= v4l2_ctrl_new_custom(hdl_user_gen
, &vivid_ctrl_string
, NULL
);
1447 dev
->bitmask
= v4l2_ctrl_new_custom(hdl_user_gen
, &vivid_ctrl_bitmask
, NULL
);
1448 dev
->int_menu
= v4l2_ctrl_new_custom(hdl_user_gen
, &vivid_ctrl_int_menu
, NULL
);
1449 v4l2_ctrl_new_custom(hdl_user_gen
, &vivid_ctrl_u32_array
, NULL
);
1450 v4l2_ctrl_new_custom(hdl_user_gen
, &vivid_ctrl_u16_matrix
, NULL
);
1451 v4l2_ctrl_new_custom(hdl_user_gen
, &vivid_ctrl_u8_4d_array
, NULL
);
1453 if (dev
->has_vid_cap
) {
1454 /* Image Processing Controls */
1455 struct v4l2_ctrl_config vivid_ctrl_test_pattern
= {
1456 .ops
= &vivid_vid_cap_ctrl_ops
,
1457 .id
= VIVID_CID_TEST_PATTERN
,
1458 .name
= "Test Pattern",
1459 .type
= V4L2_CTRL_TYPE_MENU
,
1460 .max
= TPG_PAT_NOISE
,
1461 .qmenu
= tpg_pattern_strings
,
1464 dev
->test_pattern
= v4l2_ctrl_new_custom(hdl_vid_cap
,
1465 &vivid_ctrl_test_pattern
, NULL
);
1466 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_perc_fill
, NULL
);
1467 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_hor_movement
, NULL
);
1468 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_vert_movement
, NULL
);
1469 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_osd_mode
, NULL
);
1470 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_show_border
, NULL
);
1471 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_show_square
, NULL
);
1472 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_hflip
, NULL
);
1473 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_vflip
, NULL
);
1474 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_insert_sav
, NULL
);
1475 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_insert_eav
, NULL
);
1476 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_reduced_fps
, NULL
);
1478 dev
->ctrl_has_crop_cap
= v4l2_ctrl_new_custom(hdl_vid_cap
,
1479 &vivid_ctrl_has_crop_cap
, NULL
);
1480 dev
->ctrl_has_compose_cap
= v4l2_ctrl_new_custom(hdl_vid_cap
,
1481 &vivid_ctrl_has_compose_cap
, NULL
);
1482 dev
->ctrl_has_scaler_cap
= v4l2_ctrl_new_custom(hdl_vid_cap
,
1483 &vivid_ctrl_has_scaler_cap
, NULL
);
1486 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_tstamp_src
, NULL
);
1487 dev
->colorspace
= v4l2_ctrl_new_custom(hdl_vid_cap
,
1488 &vivid_ctrl_colorspace
, NULL
);
1489 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_xfer_func
, NULL
);
1490 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_ycbcr_enc
, NULL
);
1491 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_hsv_enc
, NULL
);
1492 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_quantization
, NULL
);
1493 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_alpha_mode
, NULL
);
1496 if (dev
->has_vid_out
&& show_ccs_out
) {
1497 dev
->ctrl_has_crop_out
= v4l2_ctrl_new_custom(hdl_vid_out
,
1498 &vivid_ctrl_has_crop_out
, NULL
);
1499 dev
->ctrl_has_compose_out
= v4l2_ctrl_new_custom(hdl_vid_out
,
1500 &vivid_ctrl_has_compose_out
, NULL
);
1501 dev
->ctrl_has_scaler_out
= v4l2_ctrl_new_custom(hdl_vid_out
,
1502 &vivid_ctrl_has_scaler_out
, NULL
);
1506 * Testing this driver with v4l2-compliance will trigger the error
1507 * injection controls, and after that nothing will work as expected.
1508 * So we have a module option to drop these error injecting controls
1509 * allowing us to run v4l2_compliance again.
1511 if (!no_error_inj
) {
1512 v4l2_ctrl_new_custom(hdl_user_gen
, &vivid_ctrl_disconnect
, NULL
);
1513 v4l2_ctrl_new_custom(hdl_streaming
, &vivid_ctrl_dqbuf_error
, NULL
);
1514 v4l2_ctrl_new_custom(hdl_streaming
, &vivid_ctrl_perc_dropped
, NULL
);
1515 v4l2_ctrl_new_custom(hdl_streaming
, &vivid_ctrl_queue_setup_error
, NULL
);
1516 v4l2_ctrl_new_custom(hdl_streaming
, &vivid_ctrl_buf_prepare_error
, NULL
);
1517 v4l2_ctrl_new_custom(hdl_streaming
, &vivid_ctrl_start_streaming_error
, NULL
);
1518 v4l2_ctrl_new_custom(hdl_streaming
, &vivid_ctrl_queue_error
, NULL
);
1519 v4l2_ctrl_new_custom(hdl_streaming
, &vivid_ctrl_seq_wrap
, NULL
);
1520 v4l2_ctrl_new_custom(hdl_streaming
, &vivid_ctrl_time_wrap
, NULL
);
1523 if (has_sdtv
&& (dev
->has_vid_cap
|| dev
->has_vbi_cap
)) {
1524 if (dev
->has_vid_cap
)
1525 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_std_aspect_ratio
, NULL
);
1526 dev
->ctrl_std_signal_mode
= v4l2_ctrl_new_custom(hdl_sdtv_cap
,
1527 &vivid_ctrl_std_signal_mode
, NULL
);
1528 dev
->ctrl_standard
= v4l2_ctrl_new_custom(hdl_sdtv_cap
,
1529 &vivid_ctrl_standard
, NULL
);
1530 if (dev
->ctrl_std_signal_mode
)
1531 v4l2_ctrl_cluster(2, &dev
->ctrl_std_signal_mode
);
1532 if (dev
->has_raw_vbi_cap
)
1533 v4l2_ctrl_new_custom(hdl_vbi_cap
, &vivid_ctrl_vbi_cap_interlaced
, NULL
);
1536 if (has_hdmi
&& dev
->has_vid_cap
) {
1537 dev
->ctrl_dv_timings_signal_mode
= v4l2_ctrl_new_custom(hdl_vid_cap
,
1538 &vivid_ctrl_dv_timings_signal_mode
, NULL
);
1540 vivid_ctrl_dv_timings
.max
= dev
->query_dv_timings_size
- 1;
1541 vivid_ctrl_dv_timings
.qmenu
=
1542 (const char * const *)dev
->query_dv_timings_qmenu
;
1543 dev
->ctrl_dv_timings
= v4l2_ctrl_new_custom(hdl_vid_cap
,
1544 &vivid_ctrl_dv_timings
, NULL
);
1545 if (dev
->ctrl_dv_timings_signal_mode
)
1546 v4l2_ctrl_cluster(2, &dev
->ctrl_dv_timings_signal_mode
);
1548 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_dv_timings_aspect_ratio
, NULL
);
1549 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_max_edid_blocks
, NULL
);
1550 dev
->real_rgb_range_cap
= v4l2_ctrl_new_custom(hdl_vid_cap
,
1551 &vivid_ctrl_limited_rgb_range
, NULL
);
1552 dev
->rgb_range_cap
= v4l2_ctrl_new_std_menu(hdl_vid_cap
,
1553 &vivid_vid_cap_ctrl_ops
,
1554 V4L2_CID_DV_RX_RGB_RANGE
, V4L2_DV_RGB_RANGE_FULL
,
1555 0, V4L2_DV_RGB_RANGE_AUTO
);
1557 if (has_hdmi
&& dev
->has_vid_out
) {
1559 * We aren't doing anything with this at the moment, but
1560 * HDMI outputs typically have this controls.
1562 dev
->ctrl_tx_rgb_range
= v4l2_ctrl_new_std_menu(hdl_vid_out
, NULL
,
1563 V4L2_CID_DV_TX_RGB_RANGE
, V4L2_DV_RGB_RANGE_FULL
,
1564 0, V4L2_DV_RGB_RANGE_AUTO
);
1565 dev
->ctrl_tx_mode
= v4l2_ctrl_new_std_menu(hdl_vid_out
, NULL
,
1566 V4L2_CID_DV_TX_MODE
, V4L2_DV_TX_MODE_HDMI
,
1567 0, V4L2_DV_TX_MODE_HDMI
);
1569 if ((dev
->has_vid_cap
&& dev
->has_vid_out
) ||
1570 (dev
->has_vbi_cap
&& dev
->has_vbi_out
))
1571 v4l2_ctrl_new_custom(hdl_loop_cap
, &vivid_ctrl_loop_video
, NULL
);
1574 v4l2_ctrl_new_custom(hdl_fb
, &vivid_ctrl_clear_fb
, NULL
);
1576 if (dev
->has_radio_rx
) {
1577 v4l2_ctrl_new_custom(hdl_radio_rx
, &vivid_ctrl_radio_hw_seek_mode
, NULL
);
1578 v4l2_ctrl_new_custom(hdl_radio_rx
, &vivid_ctrl_radio_hw_seek_prog_lim
, NULL
);
1579 v4l2_ctrl_new_custom(hdl_radio_rx
, &vivid_ctrl_radio_rx_rds_blockio
, NULL
);
1580 v4l2_ctrl_new_custom(hdl_radio_rx
, &vivid_ctrl_radio_rx_rds_rbds
, NULL
);
1581 v4l2_ctrl_new_std(hdl_radio_rx
, &vivid_radio_rx_ctrl_ops
,
1582 V4L2_CID_RDS_RECEPTION
, 0, 1, 1, 1);
1583 dev
->radio_rx_rds_pty
= v4l2_ctrl_new_std(hdl_radio_rx
,
1584 &vivid_radio_rx_ctrl_ops
,
1585 V4L2_CID_RDS_RX_PTY
, 0, 31, 1, 0);
1586 dev
->radio_rx_rds_psname
= v4l2_ctrl_new_std(hdl_radio_rx
,
1587 &vivid_radio_rx_ctrl_ops
,
1588 V4L2_CID_RDS_RX_PS_NAME
, 0, 8, 8, 0);
1589 dev
->radio_rx_rds_radiotext
= v4l2_ctrl_new_std(hdl_radio_rx
,
1590 &vivid_radio_rx_ctrl_ops
,
1591 V4L2_CID_RDS_RX_RADIO_TEXT
, 0, 64, 64, 0);
1592 dev
->radio_rx_rds_ta
= v4l2_ctrl_new_std(hdl_radio_rx
,
1593 &vivid_radio_rx_ctrl_ops
,
1594 V4L2_CID_RDS_RX_TRAFFIC_ANNOUNCEMENT
, 0, 1, 1, 0);
1595 dev
->radio_rx_rds_tp
= v4l2_ctrl_new_std(hdl_radio_rx
,
1596 &vivid_radio_rx_ctrl_ops
,
1597 V4L2_CID_RDS_RX_TRAFFIC_PROGRAM
, 0, 1, 1, 0);
1598 dev
->radio_rx_rds_ms
= v4l2_ctrl_new_std(hdl_radio_rx
,
1599 &vivid_radio_rx_ctrl_ops
,
1600 V4L2_CID_RDS_RX_MUSIC_SPEECH
, 0, 1, 1, 1);
1602 if (dev
->has_radio_tx
) {
1603 v4l2_ctrl_new_custom(hdl_radio_tx
,
1604 &vivid_ctrl_radio_tx_rds_blockio
, NULL
);
1605 dev
->radio_tx_rds_pi
= v4l2_ctrl_new_std(hdl_radio_tx
,
1606 &vivid_radio_tx_ctrl_ops
,
1607 V4L2_CID_RDS_TX_PI
, 0, 0xffff, 1, 0x8088);
1608 dev
->radio_tx_rds_pty
= v4l2_ctrl_new_std(hdl_radio_tx
,
1609 &vivid_radio_tx_ctrl_ops
,
1610 V4L2_CID_RDS_TX_PTY
, 0, 31, 1, 3);
1611 dev
->radio_tx_rds_psname
= v4l2_ctrl_new_std(hdl_radio_tx
,
1612 &vivid_radio_tx_ctrl_ops
,
1613 V4L2_CID_RDS_TX_PS_NAME
, 0, 8, 8, 0);
1614 if (dev
->radio_tx_rds_psname
)
1615 v4l2_ctrl_s_ctrl_string(dev
->radio_tx_rds_psname
, "VIVID-TX");
1616 dev
->radio_tx_rds_radiotext
= v4l2_ctrl_new_std(hdl_radio_tx
,
1617 &vivid_radio_tx_ctrl_ops
,
1618 V4L2_CID_RDS_TX_RADIO_TEXT
, 0, 64 * 2, 64, 0);
1619 if (dev
->radio_tx_rds_radiotext
)
1620 v4l2_ctrl_s_ctrl_string(dev
->radio_tx_rds_radiotext
,
1621 "This is a VIVID default Radio Text template text, change at will");
1622 dev
->radio_tx_rds_mono_stereo
= v4l2_ctrl_new_std(hdl_radio_tx
,
1623 &vivid_radio_tx_ctrl_ops
,
1624 V4L2_CID_RDS_TX_MONO_STEREO
, 0, 1, 1, 1);
1625 dev
->radio_tx_rds_art_head
= v4l2_ctrl_new_std(hdl_radio_tx
,
1626 &vivid_radio_tx_ctrl_ops
,
1627 V4L2_CID_RDS_TX_ARTIFICIAL_HEAD
, 0, 1, 1, 0);
1628 dev
->radio_tx_rds_compressed
= v4l2_ctrl_new_std(hdl_radio_tx
,
1629 &vivid_radio_tx_ctrl_ops
,
1630 V4L2_CID_RDS_TX_COMPRESSED
, 0, 1, 1, 0);
1631 dev
->radio_tx_rds_dyn_pty
= v4l2_ctrl_new_std(hdl_radio_tx
,
1632 &vivid_radio_tx_ctrl_ops
,
1633 V4L2_CID_RDS_TX_DYNAMIC_PTY
, 0, 1, 1, 0);
1634 dev
->radio_tx_rds_ta
= v4l2_ctrl_new_std(hdl_radio_tx
,
1635 &vivid_radio_tx_ctrl_ops
,
1636 V4L2_CID_RDS_TX_TRAFFIC_ANNOUNCEMENT
, 0, 1, 1, 0);
1637 dev
->radio_tx_rds_tp
= v4l2_ctrl_new_std(hdl_radio_tx
,
1638 &vivid_radio_tx_ctrl_ops
,
1639 V4L2_CID_RDS_TX_TRAFFIC_PROGRAM
, 0, 1, 1, 1);
1640 dev
->radio_tx_rds_ms
= v4l2_ctrl_new_std(hdl_radio_tx
,
1641 &vivid_radio_tx_ctrl_ops
,
1642 V4L2_CID_RDS_TX_MUSIC_SPEECH
, 0, 1, 1, 1);
1644 if (dev
->has_sdr_cap
) {
1645 v4l2_ctrl_new_custom(hdl_sdr_cap
,
1646 &vivid_ctrl_sdr_cap_fm_deviation
, NULL
);
1648 if (hdl_user_gen
->error
)
1649 return hdl_user_gen
->error
;
1650 if (hdl_user_vid
->error
)
1651 return hdl_user_vid
->error
;
1652 if (hdl_user_aud
->error
)
1653 return hdl_user_aud
->error
;
1654 if (hdl_streaming
->error
)
1655 return hdl_streaming
->error
;
1656 if (hdl_sdr_cap
->error
)
1657 return hdl_sdr_cap
->error
;
1658 if (hdl_loop_cap
->error
)
1659 return hdl_loop_cap
->error
;
1662 v4l2_ctrl_auto_cluster(2, &dev
->autogain
, 0, true);
1664 if (dev
->has_vid_cap
) {
1665 v4l2_ctrl_add_handler(hdl_vid_cap
, hdl_user_gen
, NULL
);
1666 v4l2_ctrl_add_handler(hdl_vid_cap
, hdl_user_vid
, NULL
);
1667 v4l2_ctrl_add_handler(hdl_vid_cap
, hdl_user_aud
, NULL
);
1668 v4l2_ctrl_add_handler(hdl_vid_cap
, hdl_streaming
, NULL
);
1669 v4l2_ctrl_add_handler(hdl_vid_cap
, hdl_sdtv_cap
, NULL
);
1670 v4l2_ctrl_add_handler(hdl_vid_cap
, hdl_loop_cap
, NULL
);
1671 v4l2_ctrl_add_handler(hdl_vid_cap
, hdl_fb
, NULL
);
1672 if (hdl_vid_cap
->error
)
1673 return hdl_vid_cap
->error
;
1674 dev
->vid_cap_dev
.ctrl_handler
= hdl_vid_cap
;
1676 if (dev
->has_vid_out
) {
1677 v4l2_ctrl_add_handler(hdl_vid_out
, hdl_user_gen
, NULL
);
1678 v4l2_ctrl_add_handler(hdl_vid_out
, hdl_user_aud
, NULL
);
1679 v4l2_ctrl_add_handler(hdl_vid_out
, hdl_streaming
, NULL
);
1680 v4l2_ctrl_add_handler(hdl_vid_out
, hdl_fb
, NULL
);
1681 if (hdl_vid_out
->error
)
1682 return hdl_vid_out
->error
;
1683 dev
->vid_out_dev
.ctrl_handler
= hdl_vid_out
;
1685 if (dev
->has_vbi_cap
) {
1686 v4l2_ctrl_add_handler(hdl_vbi_cap
, hdl_user_gen
, NULL
);
1687 v4l2_ctrl_add_handler(hdl_vbi_cap
, hdl_streaming
, NULL
);
1688 v4l2_ctrl_add_handler(hdl_vbi_cap
, hdl_sdtv_cap
, NULL
);
1689 v4l2_ctrl_add_handler(hdl_vbi_cap
, hdl_loop_cap
, NULL
);
1690 if (hdl_vbi_cap
->error
)
1691 return hdl_vbi_cap
->error
;
1692 dev
->vbi_cap_dev
.ctrl_handler
= hdl_vbi_cap
;
1694 if (dev
->has_vbi_out
) {
1695 v4l2_ctrl_add_handler(hdl_vbi_out
, hdl_user_gen
, NULL
);
1696 v4l2_ctrl_add_handler(hdl_vbi_out
, hdl_streaming
, NULL
);
1697 if (hdl_vbi_out
->error
)
1698 return hdl_vbi_out
->error
;
1699 dev
->vbi_out_dev
.ctrl_handler
= hdl_vbi_out
;
1701 if (dev
->has_radio_rx
) {
1702 v4l2_ctrl_add_handler(hdl_radio_rx
, hdl_user_gen
, NULL
);
1703 v4l2_ctrl_add_handler(hdl_radio_rx
, hdl_user_aud
, NULL
);
1704 if (hdl_radio_rx
->error
)
1705 return hdl_radio_rx
->error
;
1706 dev
->radio_rx_dev
.ctrl_handler
= hdl_radio_rx
;
1708 if (dev
->has_radio_tx
) {
1709 v4l2_ctrl_add_handler(hdl_radio_tx
, hdl_user_gen
, NULL
);
1710 v4l2_ctrl_add_handler(hdl_radio_tx
, hdl_user_aud
, NULL
);
1711 if (hdl_radio_tx
->error
)
1712 return hdl_radio_tx
->error
;
1713 dev
->radio_tx_dev
.ctrl_handler
= hdl_radio_tx
;
1715 if (dev
->has_sdr_cap
) {
1716 v4l2_ctrl_add_handler(hdl_sdr_cap
, hdl_user_gen
, NULL
);
1717 v4l2_ctrl_add_handler(hdl_sdr_cap
, hdl_streaming
, NULL
);
1718 if (hdl_sdr_cap
->error
)
1719 return hdl_sdr_cap
->error
;
1720 dev
->sdr_cap_dev
.ctrl_handler
= hdl_sdr_cap
;
1725 void vivid_free_controls(struct vivid_dev
*dev
)
1727 v4l2_ctrl_handler_free(&dev
->ctrl_hdl_vid_cap
);
1728 v4l2_ctrl_handler_free(&dev
->ctrl_hdl_vid_out
);
1729 v4l2_ctrl_handler_free(&dev
->ctrl_hdl_vbi_cap
);
1730 v4l2_ctrl_handler_free(&dev
->ctrl_hdl_vbi_out
);
1731 v4l2_ctrl_handler_free(&dev
->ctrl_hdl_radio_rx
);
1732 v4l2_ctrl_handler_free(&dev
->ctrl_hdl_radio_tx
);
1733 v4l2_ctrl_handler_free(&dev
->ctrl_hdl_sdr_cap
);
1734 v4l2_ctrl_handler_free(&dev
->ctrl_hdl_user_gen
);
1735 v4l2_ctrl_handler_free(&dev
->ctrl_hdl_user_vid
);
1736 v4l2_ctrl_handler_free(&dev
->ctrl_hdl_user_aud
);
1737 v4l2_ctrl_handler_free(&dev
->ctrl_hdl_streaming
);
1738 v4l2_ctrl_handler_free(&dev
->ctrl_hdl_sdtv_cap
);
1739 v4l2_ctrl_handler_free(&dev
->ctrl_hdl_loop_cap
);
1740 v4l2_ctrl_handler_free(&dev
->ctrl_hdl_fb
);