2 * vivid-ctrls.c - control support functions.
4 * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
6 * This program is free software; you may redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
10 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
11 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
12 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
13 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
14 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
15 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
16 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 #include <linux/errno.h>
21 #include <linux/kernel.h>
22 #include <linux/videodev2.h>
23 #include <media/v4l2-event.h>
24 #include <media/v4l2-common.h>
26 #include "vivid-core.h"
27 #include "vivid-vid-cap.h"
28 #include "vivid-vid-out.h"
29 #include "vivid-vid-common.h"
30 #include "vivid-radio-common.h"
31 #include "vivid-osd.h"
32 #include "vivid-ctrls.h"
34 #define VIVID_CID_CUSTOM_BASE (V4L2_CID_USER_BASE | 0xf000)
35 #define VIVID_CID_BUTTON (VIVID_CID_CUSTOM_BASE + 0)
36 #define VIVID_CID_BOOLEAN (VIVID_CID_CUSTOM_BASE + 1)
37 #define VIVID_CID_INTEGER (VIVID_CID_CUSTOM_BASE + 2)
38 #define VIVID_CID_INTEGER64 (VIVID_CID_CUSTOM_BASE + 3)
39 #define VIVID_CID_MENU (VIVID_CID_CUSTOM_BASE + 4)
40 #define VIVID_CID_STRING (VIVID_CID_CUSTOM_BASE + 5)
41 #define VIVID_CID_BITMASK (VIVID_CID_CUSTOM_BASE + 6)
42 #define VIVID_CID_INTMENU (VIVID_CID_CUSTOM_BASE + 7)
43 #define VIVID_CID_U32_ARRAY (VIVID_CID_CUSTOM_BASE + 8)
44 #define VIVID_CID_U16_MATRIX (VIVID_CID_CUSTOM_BASE + 9)
45 #define VIVID_CID_U8_4D_ARRAY (VIVID_CID_CUSTOM_BASE + 10)
47 #define VIVID_CID_VIVID_BASE (0x00f00000 | 0xf000)
48 #define VIVID_CID_VIVID_CLASS (0x00f00000 | 1)
49 #define VIVID_CID_TEST_PATTERN (VIVID_CID_VIVID_BASE + 0)
50 #define VIVID_CID_OSD_TEXT_MODE (VIVID_CID_VIVID_BASE + 1)
51 #define VIVID_CID_HOR_MOVEMENT (VIVID_CID_VIVID_BASE + 2)
52 #define VIVID_CID_VERT_MOVEMENT (VIVID_CID_VIVID_BASE + 3)
53 #define VIVID_CID_SHOW_BORDER (VIVID_CID_VIVID_BASE + 4)
54 #define VIVID_CID_SHOW_SQUARE (VIVID_CID_VIVID_BASE + 5)
55 #define VIVID_CID_INSERT_SAV (VIVID_CID_VIVID_BASE + 6)
56 #define VIVID_CID_INSERT_EAV (VIVID_CID_VIVID_BASE + 7)
57 #define VIVID_CID_VBI_CAP_INTERLACED (VIVID_CID_VIVID_BASE + 8)
59 #define VIVID_CID_HFLIP (VIVID_CID_VIVID_BASE + 20)
60 #define VIVID_CID_VFLIP (VIVID_CID_VIVID_BASE + 21)
61 #define VIVID_CID_STD_ASPECT_RATIO (VIVID_CID_VIVID_BASE + 22)
62 #define VIVID_CID_DV_TIMINGS_ASPECT_RATIO (VIVID_CID_VIVID_BASE + 23)
63 #define VIVID_CID_TSTAMP_SRC (VIVID_CID_VIVID_BASE + 24)
64 #define VIVID_CID_COLORSPACE (VIVID_CID_VIVID_BASE + 25)
65 #define VIVID_CID_XFER_FUNC (VIVID_CID_VIVID_BASE + 26)
66 #define VIVID_CID_YCBCR_ENC (VIVID_CID_VIVID_BASE + 27)
67 #define VIVID_CID_QUANTIZATION (VIVID_CID_VIVID_BASE + 28)
68 #define VIVID_CID_LIMITED_RGB_RANGE (VIVID_CID_VIVID_BASE + 29)
69 #define VIVID_CID_ALPHA_MODE (VIVID_CID_VIVID_BASE + 30)
70 #define VIVID_CID_HAS_CROP_CAP (VIVID_CID_VIVID_BASE + 31)
71 #define VIVID_CID_HAS_COMPOSE_CAP (VIVID_CID_VIVID_BASE + 32)
72 #define VIVID_CID_HAS_SCALER_CAP (VIVID_CID_VIVID_BASE + 33)
73 #define VIVID_CID_HAS_CROP_OUT (VIVID_CID_VIVID_BASE + 34)
74 #define VIVID_CID_HAS_COMPOSE_OUT (VIVID_CID_VIVID_BASE + 35)
75 #define VIVID_CID_HAS_SCALER_OUT (VIVID_CID_VIVID_BASE + 36)
76 #define VIVID_CID_LOOP_VIDEO (VIVID_CID_VIVID_BASE + 37)
77 #define VIVID_CID_SEQ_WRAP (VIVID_CID_VIVID_BASE + 38)
78 #define VIVID_CID_TIME_WRAP (VIVID_CID_VIVID_BASE + 39)
79 #define VIVID_CID_MAX_EDID_BLOCKS (VIVID_CID_VIVID_BASE + 40)
80 #define VIVID_CID_PERCENTAGE_FILL (VIVID_CID_VIVID_BASE + 41)
81 #define VIVID_CID_REDUCED_FPS (VIVID_CID_VIVID_BASE + 42)
82 #define VIVID_CID_HSV_ENC (VIVID_CID_VIVID_BASE + 43)
84 #define VIVID_CID_STD_SIGNAL_MODE (VIVID_CID_VIVID_BASE + 60)
85 #define VIVID_CID_STANDARD (VIVID_CID_VIVID_BASE + 61)
86 #define VIVID_CID_DV_TIMINGS_SIGNAL_MODE (VIVID_CID_VIVID_BASE + 62)
87 #define VIVID_CID_DV_TIMINGS (VIVID_CID_VIVID_BASE + 63)
88 #define VIVID_CID_PERC_DROPPED (VIVID_CID_VIVID_BASE + 64)
89 #define VIVID_CID_DISCONNECT (VIVID_CID_VIVID_BASE + 65)
90 #define VIVID_CID_DQBUF_ERROR (VIVID_CID_VIVID_BASE + 66)
91 #define VIVID_CID_QUEUE_SETUP_ERROR (VIVID_CID_VIVID_BASE + 67)
92 #define VIVID_CID_BUF_PREPARE_ERROR (VIVID_CID_VIVID_BASE + 68)
93 #define VIVID_CID_START_STR_ERROR (VIVID_CID_VIVID_BASE + 69)
94 #define VIVID_CID_QUEUE_ERROR (VIVID_CID_VIVID_BASE + 70)
95 #define VIVID_CID_CLEAR_FB (VIVID_CID_VIVID_BASE + 71)
97 #define VIVID_CID_RADIO_SEEK_MODE (VIVID_CID_VIVID_BASE + 90)
98 #define VIVID_CID_RADIO_SEEK_PROG_LIM (VIVID_CID_VIVID_BASE + 91)
99 #define VIVID_CID_RADIO_RX_RDS_RBDS (VIVID_CID_VIVID_BASE + 92)
100 #define VIVID_CID_RADIO_RX_RDS_BLOCKIO (VIVID_CID_VIVID_BASE + 93)
102 #define VIVID_CID_RADIO_TX_RDS_BLOCKIO (VIVID_CID_VIVID_BASE + 94)
104 #define VIVID_CID_SDR_CAP_FM_DEVIATION (VIVID_CID_VIVID_BASE + 110)
106 /* General User Controls */
108 static int vivid_user_gen_s_ctrl(struct v4l2_ctrl
*ctrl
)
110 struct vivid_dev
*dev
= container_of(ctrl
->handler
, struct vivid_dev
, ctrl_hdl_user_gen
);
113 case VIVID_CID_DISCONNECT
:
114 v4l2_info(&dev
->v4l2_dev
, "disconnect\n");
115 clear_bit(V4L2_FL_REGISTERED
, &dev
->vid_cap_dev
.flags
);
116 clear_bit(V4L2_FL_REGISTERED
, &dev
->vid_out_dev
.flags
);
117 clear_bit(V4L2_FL_REGISTERED
, &dev
->vbi_cap_dev
.flags
);
118 clear_bit(V4L2_FL_REGISTERED
, &dev
->vbi_out_dev
.flags
);
119 clear_bit(V4L2_FL_REGISTERED
, &dev
->sdr_cap_dev
.flags
);
120 clear_bit(V4L2_FL_REGISTERED
, &dev
->radio_rx_dev
.flags
);
121 clear_bit(V4L2_FL_REGISTERED
, &dev
->radio_tx_dev
.flags
);
123 case VIVID_CID_BUTTON
:
124 dev
->button_pressed
= 30;
130 static const struct v4l2_ctrl_ops vivid_user_gen_ctrl_ops
= {
131 .s_ctrl
= vivid_user_gen_s_ctrl
,
134 static const struct v4l2_ctrl_config vivid_ctrl_button
= {
135 .ops
= &vivid_user_gen_ctrl_ops
,
136 .id
= VIVID_CID_BUTTON
,
138 .type
= V4L2_CTRL_TYPE_BUTTON
,
141 static const struct v4l2_ctrl_config vivid_ctrl_boolean
= {
142 .ops
= &vivid_user_gen_ctrl_ops
,
143 .id
= VIVID_CID_BOOLEAN
,
145 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
152 static const struct v4l2_ctrl_config vivid_ctrl_int32
= {
153 .ops
= &vivid_user_gen_ctrl_ops
,
154 .id
= VIVID_CID_INTEGER
,
155 .name
= "Integer 32 Bits",
156 .type
= V4L2_CTRL_TYPE_INTEGER
,
157 .min
= 0xffffffff80000000ULL
,
162 static const struct v4l2_ctrl_config vivid_ctrl_int64
= {
163 .ops
= &vivid_user_gen_ctrl_ops
,
164 .id
= VIVID_CID_INTEGER64
,
165 .name
= "Integer 64 Bits",
166 .type
= V4L2_CTRL_TYPE_INTEGER64
,
167 .min
= 0x8000000000000000ULL
,
168 .max
= 0x7fffffffffffffffLL
,
172 static const struct v4l2_ctrl_config vivid_ctrl_u32_array
= {
173 .ops
= &vivid_user_gen_ctrl_ops
,
174 .id
= VIVID_CID_U32_ARRAY
,
175 .name
= "U32 1 Element Array",
176 .type
= V4L2_CTRL_TYPE_U32
,
184 static const struct v4l2_ctrl_config vivid_ctrl_u16_matrix
= {
185 .ops
= &vivid_user_gen_ctrl_ops
,
186 .id
= VIVID_CID_U16_MATRIX
,
187 .name
= "U16 8x16 Matrix",
188 .type
= V4L2_CTRL_TYPE_U16
,
196 static const struct v4l2_ctrl_config vivid_ctrl_u8_4d_array
= {
197 .ops
= &vivid_user_gen_ctrl_ops
,
198 .id
= VIVID_CID_U8_4D_ARRAY
,
199 .name
= "U8 2x3x4x5 Array",
200 .type
= V4L2_CTRL_TYPE_U8
,
205 .dims
= { 2, 3, 4, 5 },
208 static const char * const vivid_ctrl_menu_strings
[] = {
209 "Menu Item 0 (Skipped)",
211 "Menu Item 2 (Skipped)",
214 "Menu Item 5 (Skipped)",
218 static const struct v4l2_ctrl_config vivid_ctrl_menu
= {
219 .ops
= &vivid_user_gen_ctrl_ops
,
220 .id
= VIVID_CID_MENU
,
222 .type
= V4L2_CTRL_TYPE_MENU
,
226 .menu_skip_mask
= 0x04,
227 .qmenu
= vivid_ctrl_menu_strings
,
230 static const struct v4l2_ctrl_config vivid_ctrl_string
= {
231 .ops
= &vivid_user_gen_ctrl_ops
,
232 .id
= VIVID_CID_STRING
,
234 .type
= V4L2_CTRL_TYPE_STRING
,
240 static const struct v4l2_ctrl_config vivid_ctrl_bitmask
= {
241 .ops
= &vivid_user_gen_ctrl_ops
,
242 .id
= VIVID_CID_BITMASK
,
244 .type
= V4L2_CTRL_TYPE_BITMASK
,
251 static const s64 vivid_ctrl_int_menu_values
[] = {
252 1, 1, 2, 3, 5, 8, 13, 21, 42,
255 static const struct v4l2_ctrl_config vivid_ctrl_int_menu
= {
256 .ops
= &vivid_user_gen_ctrl_ops
,
257 .id
= VIVID_CID_INTMENU
,
258 .name
= "Integer Menu",
259 .type
= V4L2_CTRL_TYPE_INTEGER_MENU
,
263 .menu_skip_mask
= 0x02,
264 .qmenu_int
= vivid_ctrl_int_menu_values
,
267 static const struct v4l2_ctrl_config vivid_ctrl_disconnect
= {
268 .ops
= &vivid_user_gen_ctrl_ops
,
269 .id
= VIVID_CID_DISCONNECT
,
270 .name
= "Disconnect",
271 .type
= V4L2_CTRL_TYPE_BUTTON
,
275 /* Framebuffer Controls */
277 static int vivid_fb_s_ctrl(struct v4l2_ctrl
*ctrl
)
279 struct vivid_dev
*dev
= container_of(ctrl
->handler
,
280 struct vivid_dev
, ctrl_hdl_fb
);
283 case VIVID_CID_CLEAR_FB
:
290 static const struct v4l2_ctrl_ops vivid_fb_ctrl_ops
= {
291 .s_ctrl
= vivid_fb_s_ctrl
,
294 static const struct v4l2_ctrl_config vivid_ctrl_clear_fb
= {
295 .ops
= &vivid_fb_ctrl_ops
,
296 .id
= VIVID_CID_CLEAR_FB
,
297 .name
= "Clear Framebuffer",
298 .type
= V4L2_CTRL_TYPE_BUTTON
,
302 /* Video User Controls */
304 static int vivid_user_vid_g_volatile_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_AUTOGAIN
:
310 dev
->gain
->val
= dev
->jiffies_vid_cap
& 0xff;
316 static int vivid_user_vid_s_ctrl(struct v4l2_ctrl
*ctrl
)
318 struct vivid_dev
*dev
= container_of(ctrl
->handler
, struct vivid_dev
, ctrl_hdl_user_vid
);
321 case V4L2_CID_BRIGHTNESS
:
322 dev
->input_brightness
[dev
->input
] = ctrl
->val
- dev
->input
* 128;
323 tpg_s_brightness(&dev
->tpg
, dev
->input_brightness
[dev
->input
]);
325 case V4L2_CID_CONTRAST
:
326 tpg_s_contrast(&dev
->tpg
, ctrl
->val
);
328 case V4L2_CID_SATURATION
:
329 tpg_s_saturation(&dev
->tpg
, ctrl
->val
);
332 tpg_s_hue(&dev
->tpg
, ctrl
->val
);
335 dev
->hflip
= ctrl
->val
;
336 tpg_s_hflip(&dev
->tpg
, dev
->sensor_hflip
^ dev
->hflip
);
339 dev
->vflip
= ctrl
->val
;
340 tpg_s_vflip(&dev
->tpg
, dev
->sensor_vflip
^ dev
->vflip
);
342 case V4L2_CID_ALPHA_COMPONENT
:
343 tpg_s_alpha_component(&dev
->tpg
, ctrl
->val
);
349 static const struct v4l2_ctrl_ops vivid_user_vid_ctrl_ops
= {
350 .g_volatile_ctrl
= vivid_user_vid_g_volatile_ctrl
,
351 .s_ctrl
= vivid_user_vid_s_ctrl
,
355 /* Video Capture Controls */
357 static int vivid_vid_cap_s_ctrl(struct v4l2_ctrl
*ctrl
)
359 static const u32 colorspaces
[] = {
360 V4L2_COLORSPACE_SMPTE170M
,
361 V4L2_COLORSPACE_REC709
,
362 V4L2_COLORSPACE_SRGB
,
363 V4L2_COLORSPACE_ADOBERGB
,
364 V4L2_COLORSPACE_BT2020
,
365 V4L2_COLORSPACE_DCI_P3
,
366 V4L2_COLORSPACE_SMPTE240M
,
367 V4L2_COLORSPACE_470_SYSTEM_M
,
368 V4L2_COLORSPACE_470_SYSTEM_BG
,
370 struct vivid_dev
*dev
= container_of(ctrl
->handler
, struct vivid_dev
, ctrl_hdl_vid_cap
);
374 case VIVID_CID_TEST_PATTERN
:
375 vivid_update_quality(dev
);
376 tpg_s_pattern(&dev
->tpg
, ctrl
->val
);
378 case VIVID_CID_COLORSPACE
:
379 tpg_s_colorspace(&dev
->tpg
, colorspaces
[ctrl
->val
]);
380 vivid_send_source_change(dev
, TV
);
381 vivid_send_source_change(dev
, SVID
);
382 vivid_send_source_change(dev
, HDMI
);
383 vivid_send_source_change(dev
, WEBCAM
);
385 case VIVID_CID_XFER_FUNC
:
386 tpg_s_xfer_func(&dev
->tpg
, ctrl
->val
);
387 vivid_send_source_change(dev
, TV
);
388 vivid_send_source_change(dev
, SVID
);
389 vivid_send_source_change(dev
, HDMI
);
390 vivid_send_source_change(dev
, WEBCAM
);
392 case VIVID_CID_YCBCR_ENC
:
393 tpg_s_ycbcr_enc(&dev
->tpg
, ctrl
->val
);
394 vivid_send_source_change(dev
, TV
);
395 vivid_send_source_change(dev
, SVID
);
396 vivid_send_source_change(dev
, HDMI
);
397 vivid_send_source_change(dev
, WEBCAM
);
399 case VIVID_CID_HSV_ENC
:
400 tpg_s_hsv_enc(&dev
->tpg
, ctrl
->val
? V4L2_HSV_ENC_256
:
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_QUANTIZATION
:
408 tpg_s_quantization(&dev
->tpg
, ctrl
->val
);
409 vivid_send_source_change(dev
, TV
);
410 vivid_send_source_change(dev
, SVID
);
411 vivid_send_source_change(dev
, HDMI
);
412 vivid_send_source_change(dev
, WEBCAM
);
414 case V4L2_CID_DV_RX_RGB_RANGE
:
415 if (!vivid_is_hdmi_cap(dev
))
417 tpg_s_rgb_range(&dev
->tpg
, ctrl
->val
);
419 case VIVID_CID_LIMITED_RGB_RANGE
:
420 tpg_s_real_rgb_range(&dev
->tpg
, ctrl
->val
?
421 V4L2_DV_RGB_RANGE_LIMITED
: V4L2_DV_RGB_RANGE_FULL
);
423 case VIVID_CID_ALPHA_MODE
:
424 tpg_s_alpha_mode(&dev
->tpg
, ctrl
->val
);
426 case VIVID_CID_HOR_MOVEMENT
:
427 tpg_s_mv_hor_mode(&dev
->tpg
, ctrl
->val
);
429 case VIVID_CID_VERT_MOVEMENT
:
430 tpg_s_mv_vert_mode(&dev
->tpg
, ctrl
->val
);
432 case VIVID_CID_OSD_TEXT_MODE
:
433 dev
->osd_mode
= ctrl
->val
;
435 case VIVID_CID_PERCENTAGE_FILL
:
436 tpg_s_perc_fill(&dev
->tpg
, ctrl
->val
);
437 for (i
= 0; i
< VIDEO_MAX_FRAME
; i
++)
438 dev
->must_blank
[i
] = ctrl
->val
< 100;
440 case VIVID_CID_INSERT_SAV
:
441 tpg_s_insert_sav(&dev
->tpg
, ctrl
->val
);
443 case VIVID_CID_INSERT_EAV
:
444 tpg_s_insert_eav(&dev
->tpg
, ctrl
->val
);
446 case VIVID_CID_HFLIP
:
447 dev
->sensor_hflip
= ctrl
->val
;
448 tpg_s_hflip(&dev
->tpg
, dev
->sensor_hflip
^ dev
->hflip
);
450 case VIVID_CID_VFLIP
:
451 dev
->sensor_vflip
= ctrl
->val
;
452 tpg_s_vflip(&dev
->tpg
, dev
->sensor_vflip
^ dev
->vflip
);
454 case VIVID_CID_REDUCED_FPS
:
455 dev
->reduced_fps
= ctrl
->val
;
456 vivid_update_format_cap(dev
, true);
458 case VIVID_CID_HAS_CROP_CAP
:
459 dev
->has_crop_cap
= ctrl
->val
;
460 vivid_update_format_cap(dev
, true);
462 case VIVID_CID_HAS_COMPOSE_CAP
:
463 dev
->has_compose_cap
= ctrl
->val
;
464 vivid_update_format_cap(dev
, true);
466 case VIVID_CID_HAS_SCALER_CAP
:
467 dev
->has_scaler_cap
= ctrl
->val
;
468 vivid_update_format_cap(dev
, true);
470 case VIVID_CID_SHOW_BORDER
:
471 tpg_s_show_border(&dev
->tpg
, ctrl
->val
);
473 case VIVID_CID_SHOW_SQUARE
:
474 tpg_s_show_square(&dev
->tpg
, ctrl
->val
);
476 case VIVID_CID_STD_ASPECT_RATIO
:
477 dev
->std_aspect_ratio
= ctrl
->val
;
478 tpg_s_video_aspect(&dev
->tpg
, vivid_get_video_aspect(dev
));
480 case VIVID_CID_DV_TIMINGS_SIGNAL_MODE
:
481 dev
->dv_timings_signal_mode
= dev
->ctrl_dv_timings_signal_mode
->val
;
482 if (dev
->dv_timings_signal_mode
== SELECTED_DV_TIMINGS
)
483 dev
->query_dv_timings
= dev
->ctrl_dv_timings
->val
;
484 v4l2_ctrl_activate(dev
->ctrl_dv_timings
,
485 dev
->dv_timings_signal_mode
== SELECTED_DV_TIMINGS
);
486 vivid_update_quality(dev
);
487 vivid_send_source_change(dev
, HDMI
);
489 case VIVID_CID_DV_TIMINGS_ASPECT_RATIO
:
490 dev
->dv_timings_aspect_ratio
= ctrl
->val
;
491 tpg_s_video_aspect(&dev
->tpg
, vivid_get_video_aspect(dev
));
493 case VIVID_CID_TSTAMP_SRC
:
494 dev
->tstamp_src_is_soe
= ctrl
->val
;
495 dev
->vb_vid_cap_q
.timestamp_flags
&= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK
;
496 if (dev
->tstamp_src_is_soe
)
497 dev
->vb_vid_cap_q
.timestamp_flags
|= V4L2_BUF_FLAG_TSTAMP_SRC_SOE
;
499 case VIVID_CID_MAX_EDID_BLOCKS
:
500 dev
->edid_max_blocks
= ctrl
->val
;
501 if (dev
->edid_blocks
> dev
->edid_max_blocks
)
502 dev
->edid_blocks
= dev
->edid_max_blocks
;
508 static const struct v4l2_ctrl_ops vivid_vid_cap_ctrl_ops
= {
509 .s_ctrl
= vivid_vid_cap_s_ctrl
,
512 static const char * const vivid_ctrl_hor_movement_strings
[] = {
523 static const struct v4l2_ctrl_config vivid_ctrl_hor_movement
= {
524 .ops
= &vivid_vid_cap_ctrl_ops
,
525 .id
= VIVID_CID_HOR_MOVEMENT
,
526 .name
= "Horizontal Movement",
527 .type
= V4L2_CTRL_TYPE_MENU
,
528 .max
= TPG_MOVE_POS_FAST
,
529 .def
= TPG_MOVE_NONE
,
530 .qmenu
= vivid_ctrl_hor_movement_strings
,
533 static const char * const vivid_ctrl_vert_movement_strings
[] = {
544 static const struct v4l2_ctrl_config vivid_ctrl_vert_movement
= {
545 .ops
= &vivid_vid_cap_ctrl_ops
,
546 .id
= VIVID_CID_VERT_MOVEMENT
,
547 .name
= "Vertical Movement",
548 .type
= V4L2_CTRL_TYPE_MENU
,
549 .max
= TPG_MOVE_POS_FAST
,
550 .def
= TPG_MOVE_NONE
,
551 .qmenu
= vivid_ctrl_vert_movement_strings
,
554 static const struct v4l2_ctrl_config vivid_ctrl_show_border
= {
555 .ops
= &vivid_vid_cap_ctrl_ops
,
556 .id
= VIVID_CID_SHOW_BORDER
,
557 .name
= "Show Border",
558 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
563 static const struct v4l2_ctrl_config vivid_ctrl_show_square
= {
564 .ops
= &vivid_vid_cap_ctrl_ops
,
565 .id
= VIVID_CID_SHOW_SQUARE
,
566 .name
= "Show Square",
567 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
572 static const char * const vivid_ctrl_osd_mode_strings
[] = {
579 static const struct v4l2_ctrl_config vivid_ctrl_osd_mode
= {
580 .ops
= &vivid_vid_cap_ctrl_ops
,
581 .id
= VIVID_CID_OSD_TEXT_MODE
,
582 .name
= "OSD Text Mode",
583 .type
= V4L2_CTRL_TYPE_MENU
,
584 .max
= ARRAY_SIZE(vivid_ctrl_osd_mode_strings
) - 2,
585 .qmenu
= vivid_ctrl_osd_mode_strings
,
588 static const struct v4l2_ctrl_config vivid_ctrl_perc_fill
= {
589 .ops
= &vivid_vid_cap_ctrl_ops
,
590 .id
= VIVID_CID_PERCENTAGE_FILL
,
591 .name
= "Fill Percentage of Frame",
592 .type
= V4L2_CTRL_TYPE_INTEGER
,
599 static const struct v4l2_ctrl_config vivid_ctrl_insert_sav
= {
600 .ops
= &vivid_vid_cap_ctrl_ops
,
601 .id
= VIVID_CID_INSERT_SAV
,
602 .name
= "Insert SAV Code in Image",
603 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
608 static const struct v4l2_ctrl_config vivid_ctrl_insert_eav
= {
609 .ops
= &vivid_vid_cap_ctrl_ops
,
610 .id
= VIVID_CID_INSERT_EAV
,
611 .name
= "Insert EAV Code in Image",
612 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
617 static const struct v4l2_ctrl_config vivid_ctrl_hflip
= {
618 .ops
= &vivid_vid_cap_ctrl_ops
,
619 .id
= VIVID_CID_HFLIP
,
620 .name
= "Sensor Flipped Horizontally",
621 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
626 static const struct v4l2_ctrl_config vivid_ctrl_vflip
= {
627 .ops
= &vivid_vid_cap_ctrl_ops
,
628 .id
= VIVID_CID_VFLIP
,
629 .name
= "Sensor Flipped Vertically",
630 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
635 static const struct v4l2_ctrl_config vivid_ctrl_reduced_fps
= {
636 .ops
= &vivid_vid_cap_ctrl_ops
,
637 .id
= VIVID_CID_REDUCED_FPS
,
638 .name
= "Reduced Framerate",
639 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
644 static const struct v4l2_ctrl_config vivid_ctrl_has_crop_cap
= {
645 .ops
= &vivid_vid_cap_ctrl_ops
,
646 .id
= VIVID_CID_HAS_CROP_CAP
,
647 .name
= "Enable Capture Cropping",
648 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
654 static const struct v4l2_ctrl_config vivid_ctrl_has_compose_cap
= {
655 .ops
= &vivid_vid_cap_ctrl_ops
,
656 .id
= VIVID_CID_HAS_COMPOSE_CAP
,
657 .name
= "Enable Capture Composing",
658 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
664 static const struct v4l2_ctrl_config vivid_ctrl_has_scaler_cap
= {
665 .ops
= &vivid_vid_cap_ctrl_ops
,
666 .id
= VIVID_CID_HAS_SCALER_CAP
,
667 .name
= "Enable Capture Scaler",
668 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
674 static const char * const vivid_ctrl_tstamp_src_strings
[] = {
680 static const struct v4l2_ctrl_config vivid_ctrl_tstamp_src
= {
681 .ops
= &vivid_vid_cap_ctrl_ops
,
682 .id
= VIVID_CID_TSTAMP_SRC
,
683 .name
= "Timestamp Source",
684 .type
= V4L2_CTRL_TYPE_MENU
,
685 .max
= ARRAY_SIZE(vivid_ctrl_tstamp_src_strings
) - 2,
686 .qmenu
= vivid_ctrl_tstamp_src_strings
,
689 static const struct v4l2_ctrl_config vivid_ctrl_std_aspect_ratio
= {
690 .ops
= &vivid_vid_cap_ctrl_ops
,
691 .id
= VIVID_CID_STD_ASPECT_RATIO
,
692 .name
= "Standard Aspect Ratio",
693 .type
= V4L2_CTRL_TYPE_MENU
,
697 .qmenu
= tpg_aspect_strings
,
700 static const char * const vivid_ctrl_dv_timings_signal_mode_strings
[] = {
701 "Current DV Timings",
705 "Selected DV Timings",
706 "Cycle Through All DV Timings",
711 static const struct v4l2_ctrl_config vivid_ctrl_dv_timings_signal_mode
= {
712 .ops
= &vivid_vid_cap_ctrl_ops
,
713 .id
= VIVID_CID_DV_TIMINGS_SIGNAL_MODE
,
714 .name
= "DV Timings Signal Mode",
715 .type
= V4L2_CTRL_TYPE_MENU
,
717 .qmenu
= vivid_ctrl_dv_timings_signal_mode_strings
,
720 static const struct v4l2_ctrl_config vivid_ctrl_dv_timings_aspect_ratio
= {
721 .ops
= &vivid_vid_cap_ctrl_ops
,
722 .id
= VIVID_CID_DV_TIMINGS_ASPECT_RATIO
,
723 .name
= "DV Timings Aspect Ratio",
724 .type
= V4L2_CTRL_TYPE_MENU
,
726 .qmenu
= tpg_aspect_strings
,
729 static const struct v4l2_ctrl_config vivid_ctrl_max_edid_blocks
= {
730 .ops
= &vivid_vid_cap_ctrl_ops
,
731 .id
= VIVID_CID_MAX_EDID_BLOCKS
,
732 .name
= "Maximum EDID Blocks",
733 .type
= V4L2_CTRL_TYPE_INTEGER
,
740 static const char * const vivid_ctrl_colorspace_strings
[] = {
753 static const struct v4l2_ctrl_config vivid_ctrl_colorspace
= {
754 .ops
= &vivid_vid_cap_ctrl_ops
,
755 .id
= VIVID_CID_COLORSPACE
,
756 .name
= "Colorspace",
757 .type
= V4L2_CTRL_TYPE_MENU
,
758 .max
= ARRAY_SIZE(vivid_ctrl_colorspace_strings
) - 2,
760 .qmenu
= vivid_ctrl_colorspace_strings
,
763 static const char * const vivid_ctrl_xfer_func_strings
[] = {
775 static const struct v4l2_ctrl_config vivid_ctrl_xfer_func
= {
776 .ops
= &vivid_vid_cap_ctrl_ops
,
777 .id
= VIVID_CID_XFER_FUNC
,
778 .name
= "Transfer Function",
779 .type
= V4L2_CTRL_TYPE_MENU
,
780 .max
= ARRAY_SIZE(vivid_ctrl_xfer_func_strings
) - 2,
781 .qmenu
= vivid_ctrl_xfer_func_strings
,
784 static const char * const vivid_ctrl_ycbcr_enc_strings
[] = {
792 "BT.2020 Constant Luminance",
797 static const struct v4l2_ctrl_config vivid_ctrl_ycbcr_enc
= {
798 .ops
= &vivid_vid_cap_ctrl_ops
,
799 .id
= VIVID_CID_YCBCR_ENC
,
800 .name
= "Y'CbCr Encoding",
801 .type
= V4L2_CTRL_TYPE_MENU
,
802 .menu_skip_mask
= 1 << 5,
803 .max
= ARRAY_SIZE(vivid_ctrl_ycbcr_enc_strings
) - 2,
804 .qmenu
= vivid_ctrl_ycbcr_enc_strings
,
807 static const char * const vivid_ctrl_hsv_enc_strings
[] = {
813 static const struct v4l2_ctrl_config vivid_ctrl_hsv_enc
= {
814 .ops
= &vivid_vid_cap_ctrl_ops
,
815 .id
= VIVID_CID_HSV_ENC
,
816 .name
= "HSV Encoding",
817 .type
= V4L2_CTRL_TYPE_MENU
,
818 .max
= ARRAY_SIZE(vivid_ctrl_hsv_enc_strings
) - 2,
819 .qmenu
= vivid_ctrl_hsv_enc_strings
,
822 static const char * const vivid_ctrl_quantization_strings
[] = {
829 static const struct v4l2_ctrl_config vivid_ctrl_quantization
= {
830 .ops
= &vivid_vid_cap_ctrl_ops
,
831 .id
= VIVID_CID_QUANTIZATION
,
832 .name
= "Quantization",
833 .type
= V4L2_CTRL_TYPE_MENU
,
834 .max
= ARRAY_SIZE(vivid_ctrl_quantization_strings
) - 2,
835 .qmenu
= vivid_ctrl_quantization_strings
,
838 static const struct v4l2_ctrl_config vivid_ctrl_alpha_mode
= {
839 .ops
= &vivid_vid_cap_ctrl_ops
,
840 .id
= VIVID_CID_ALPHA_MODE
,
841 .name
= "Apply Alpha To Red Only",
842 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
847 static const struct v4l2_ctrl_config vivid_ctrl_limited_rgb_range
= {
848 .ops
= &vivid_vid_cap_ctrl_ops
,
849 .id
= VIVID_CID_LIMITED_RGB_RANGE
,
850 .name
= "Limited RGB Range (16-235)",
851 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
857 /* Video Loop Control */
859 static int vivid_loop_cap_s_ctrl(struct v4l2_ctrl
*ctrl
)
861 struct vivid_dev
*dev
= container_of(ctrl
->handler
, struct vivid_dev
, ctrl_hdl_loop_cap
);
864 case VIVID_CID_LOOP_VIDEO
:
865 dev
->loop_video
= ctrl
->val
;
866 vivid_update_quality(dev
);
867 vivid_send_source_change(dev
, SVID
);
868 vivid_send_source_change(dev
, HDMI
);
874 static const struct v4l2_ctrl_ops vivid_loop_cap_ctrl_ops
= {
875 .s_ctrl
= vivid_loop_cap_s_ctrl
,
878 static const struct v4l2_ctrl_config vivid_ctrl_loop_video
= {
879 .ops
= &vivid_loop_cap_ctrl_ops
,
880 .id
= VIVID_CID_LOOP_VIDEO
,
881 .name
= "Loop Video",
882 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
888 /* VBI Capture Control */
890 static int vivid_vbi_cap_s_ctrl(struct v4l2_ctrl
*ctrl
)
892 struct vivid_dev
*dev
= container_of(ctrl
->handler
, struct vivid_dev
, ctrl_hdl_vbi_cap
);
895 case VIVID_CID_VBI_CAP_INTERLACED
:
896 dev
->vbi_cap_interlaced
= ctrl
->val
;
902 static const struct v4l2_ctrl_ops vivid_vbi_cap_ctrl_ops
= {
903 .s_ctrl
= vivid_vbi_cap_s_ctrl
,
906 static const struct v4l2_ctrl_config vivid_ctrl_vbi_cap_interlaced
= {
907 .ops
= &vivid_vbi_cap_ctrl_ops
,
908 .id
= VIVID_CID_VBI_CAP_INTERLACED
,
909 .name
= "Interlaced VBI Format",
910 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
916 /* Video Output Controls */
918 static int vivid_vid_out_s_ctrl(struct v4l2_ctrl
*ctrl
)
920 struct vivid_dev
*dev
= container_of(ctrl
->handler
, struct vivid_dev
, ctrl_hdl_vid_out
);
921 struct v4l2_bt_timings
*bt
= &dev
->dv_timings_out
.bt
;
924 case VIVID_CID_HAS_CROP_OUT
:
925 dev
->has_crop_out
= ctrl
->val
;
926 vivid_update_format_out(dev
);
928 case VIVID_CID_HAS_COMPOSE_OUT
:
929 dev
->has_compose_out
= ctrl
->val
;
930 vivid_update_format_out(dev
);
932 case VIVID_CID_HAS_SCALER_OUT
:
933 dev
->has_scaler_out
= ctrl
->val
;
934 vivid_update_format_out(dev
);
936 case V4L2_CID_DV_TX_MODE
:
937 dev
->dvi_d_out
= ctrl
->val
== V4L2_DV_TX_MODE_DVI_D
;
938 if (!vivid_is_hdmi_out(dev
))
940 if (!dev
->dvi_d_out
&& (bt
->flags
& V4L2_DV_FL_IS_CE_VIDEO
)) {
941 if (bt
->width
== 720 && bt
->height
<= 576)
942 dev
->colorspace_out
= V4L2_COLORSPACE_SMPTE170M
;
944 dev
->colorspace_out
= V4L2_COLORSPACE_REC709
;
945 dev
->quantization_out
= V4L2_QUANTIZATION_DEFAULT
;
947 dev
->colorspace_out
= V4L2_COLORSPACE_SRGB
;
948 dev
->quantization_out
= dev
->dvi_d_out
?
949 V4L2_QUANTIZATION_LIM_RANGE
:
950 V4L2_QUANTIZATION_DEFAULT
;
953 vivid_send_source_change(dev
, HDMI
);
959 static const struct v4l2_ctrl_ops vivid_vid_out_ctrl_ops
= {
960 .s_ctrl
= vivid_vid_out_s_ctrl
,
963 static const struct v4l2_ctrl_config vivid_ctrl_has_crop_out
= {
964 .ops
= &vivid_vid_out_ctrl_ops
,
965 .id
= VIVID_CID_HAS_CROP_OUT
,
966 .name
= "Enable Output Cropping",
967 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
973 static const struct v4l2_ctrl_config vivid_ctrl_has_compose_out
= {
974 .ops
= &vivid_vid_out_ctrl_ops
,
975 .id
= VIVID_CID_HAS_COMPOSE_OUT
,
976 .name
= "Enable Output Composing",
977 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
983 static const struct v4l2_ctrl_config vivid_ctrl_has_scaler_out
= {
984 .ops
= &vivid_vid_out_ctrl_ops
,
985 .id
= VIVID_CID_HAS_SCALER_OUT
,
986 .name
= "Enable Output Scaler",
987 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
994 /* Streaming Controls */
996 static int vivid_streaming_s_ctrl(struct v4l2_ctrl
*ctrl
)
998 struct vivid_dev
*dev
= container_of(ctrl
->handler
, struct vivid_dev
, ctrl_hdl_streaming
);
1002 case VIVID_CID_DQBUF_ERROR
:
1003 dev
->dqbuf_error
= true;
1005 case VIVID_CID_PERC_DROPPED
:
1006 dev
->perc_dropped_buffers
= ctrl
->val
;
1008 case VIVID_CID_QUEUE_SETUP_ERROR
:
1009 dev
->queue_setup_error
= true;
1011 case VIVID_CID_BUF_PREPARE_ERROR
:
1012 dev
->buf_prepare_error
= true;
1014 case VIVID_CID_START_STR_ERROR
:
1015 dev
->start_streaming_error
= true;
1017 case VIVID_CID_QUEUE_ERROR
:
1018 if (vb2_start_streaming_called(&dev
->vb_vid_cap_q
))
1019 vb2_queue_error(&dev
->vb_vid_cap_q
);
1020 if (vb2_start_streaming_called(&dev
->vb_vbi_cap_q
))
1021 vb2_queue_error(&dev
->vb_vbi_cap_q
);
1022 if (vb2_start_streaming_called(&dev
->vb_vid_out_q
))
1023 vb2_queue_error(&dev
->vb_vid_out_q
);
1024 if (vb2_start_streaming_called(&dev
->vb_vbi_out_q
))
1025 vb2_queue_error(&dev
->vb_vbi_out_q
);
1026 if (vb2_start_streaming_called(&dev
->vb_sdr_cap_q
))
1027 vb2_queue_error(&dev
->vb_sdr_cap_q
);
1029 case VIVID_CID_SEQ_WRAP
:
1030 dev
->seq_wrap
= ctrl
->val
;
1032 case VIVID_CID_TIME_WRAP
:
1033 dev
->time_wrap
= ctrl
->val
;
1034 if (ctrl
->val
== 0) {
1035 dev
->time_wrap_offset
= 0;
1039 * We want to set the time 16 seconds before the 32 bit tv_sec
1040 * value of struct timeval would wrap around. So first we
1041 * calculate ktime_get_ns() % ((1 << 32) * NSEC_PER_SEC), and
1042 * then we set the offset to ((1 << 32) - 16) * NSEC_PER_SEC).
1044 div64_u64_rem(ktime_get_ns(),
1045 0x100000000ULL
* NSEC_PER_SEC
, &rem
);
1046 dev
->time_wrap_offset
=
1047 (0x100000000ULL
- 16) * NSEC_PER_SEC
- rem
;
1053 static const struct v4l2_ctrl_ops vivid_streaming_ctrl_ops
= {
1054 .s_ctrl
= vivid_streaming_s_ctrl
,
1057 static const struct v4l2_ctrl_config vivid_ctrl_dqbuf_error
= {
1058 .ops
= &vivid_streaming_ctrl_ops
,
1059 .id
= VIVID_CID_DQBUF_ERROR
,
1060 .name
= "Inject V4L2_BUF_FLAG_ERROR",
1061 .type
= V4L2_CTRL_TYPE_BUTTON
,
1064 static const struct v4l2_ctrl_config vivid_ctrl_perc_dropped
= {
1065 .ops
= &vivid_streaming_ctrl_ops
,
1066 .id
= VIVID_CID_PERC_DROPPED
,
1067 .name
= "Percentage of Dropped Buffers",
1068 .type
= V4L2_CTRL_TYPE_INTEGER
,
1074 static const struct v4l2_ctrl_config vivid_ctrl_queue_setup_error
= {
1075 .ops
= &vivid_streaming_ctrl_ops
,
1076 .id
= VIVID_CID_QUEUE_SETUP_ERROR
,
1077 .name
= "Inject VIDIOC_REQBUFS Error",
1078 .type
= V4L2_CTRL_TYPE_BUTTON
,
1081 static const struct v4l2_ctrl_config vivid_ctrl_buf_prepare_error
= {
1082 .ops
= &vivid_streaming_ctrl_ops
,
1083 .id
= VIVID_CID_BUF_PREPARE_ERROR
,
1084 .name
= "Inject VIDIOC_QBUF Error",
1085 .type
= V4L2_CTRL_TYPE_BUTTON
,
1088 static const struct v4l2_ctrl_config vivid_ctrl_start_streaming_error
= {
1089 .ops
= &vivid_streaming_ctrl_ops
,
1090 .id
= VIVID_CID_START_STR_ERROR
,
1091 .name
= "Inject VIDIOC_STREAMON Error",
1092 .type
= V4L2_CTRL_TYPE_BUTTON
,
1095 static const struct v4l2_ctrl_config vivid_ctrl_queue_error
= {
1096 .ops
= &vivid_streaming_ctrl_ops
,
1097 .id
= VIVID_CID_QUEUE_ERROR
,
1098 .name
= "Inject Fatal Streaming Error",
1099 .type
= V4L2_CTRL_TYPE_BUTTON
,
1102 static const struct v4l2_ctrl_config vivid_ctrl_seq_wrap
= {
1103 .ops
= &vivid_streaming_ctrl_ops
,
1104 .id
= VIVID_CID_SEQ_WRAP
,
1105 .name
= "Wrap Sequence Number",
1106 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
1111 static const struct v4l2_ctrl_config vivid_ctrl_time_wrap
= {
1112 .ops
= &vivid_streaming_ctrl_ops
,
1113 .id
= VIVID_CID_TIME_WRAP
,
1114 .name
= "Wrap Timestamp",
1115 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
1121 /* SDTV Capture Controls */
1123 static int vivid_sdtv_cap_s_ctrl(struct v4l2_ctrl
*ctrl
)
1125 struct vivid_dev
*dev
= container_of(ctrl
->handler
, struct vivid_dev
, ctrl_hdl_sdtv_cap
);
1128 case VIVID_CID_STD_SIGNAL_MODE
:
1129 dev
->std_signal_mode
= dev
->ctrl_std_signal_mode
->val
;
1130 if (dev
->std_signal_mode
== SELECTED_STD
)
1131 dev
->query_std
= vivid_standard
[dev
->ctrl_standard
->val
];
1132 v4l2_ctrl_activate(dev
->ctrl_standard
, dev
->std_signal_mode
== SELECTED_STD
);
1133 vivid_update_quality(dev
);
1134 vivid_send_source_change(dev
, TV
);
1135 vivid_send_source_change(dev
, SVID
);
1141 static const struct v4l2_ctrl_ops vivid_sdtv_cap_ctrl_ops
= {
1142 .s_ctrl
= vivid_sdtv_cap_s_ctrl
,
1145 static const char * const vivid_ctrl_std_signal_mode_strings
[] = {
1150 "Selected Standard",
1151 "Cycle Through All Standards",
1155 static const struct v4l2_ctrl_config vivid_ctrl_std_signal_mode
= {
1156 .ops
= &vivid_sdtv_cap_ctrl_ops
,
1157 .id
= VIVID_CID_STD_SIGNAL_MODE
,
1158 .name
= "Standard Signal Mode",
1159 .type
= V4L2_CTRL_TYPE_MENU
,
1160 .max
= ARRAY_SIZE(vivid_ctrl_std_signal_mode_strings
) - 2,
1161 .menu_skip_mask
= 1 << 3,
1162 .qmenu
= vivid_ctrl_std_signal_mode_strings
,
1165 static const struct v4l2_ctrl_config vivid_ctrl_standard
= {
1166 .ops
= &vivid_sdtv_cap_ctrl_ops
,
1167 .id
= VIVID_CID_STANDARD
,
1169 .type
= V4L2_CTRL_TYPE_MENU
,
1171 .qmenu
= vivid_ctrl_standard_strings
,
1176 /* Radio Receiver Controls */
1178 static int vivid_radio_rx_s_ctrl(struct v4l2_ctrl
*ctrl
)
1180 struct vivid_dev
*dev
= container_of(ctrl
->handler
, struct vivid_dev
, ctrl_hdl_radio_rx
);
1183 case VIVID_CID_RADIO_SEEK_MODE
:
1184 dev
->radio_rx_hw_seek_mode
= ctrl
->val
;
1186 case VIVID_CID_RADIO_SEEK_PROG_LIM
:
1187 dev
->radio_rx_hw_seek_prog_lim
= ctrl
->val
;
1189 case VIVID_CID_RADIO_RX_RDS_RBDS
:
1190 dev
->rds_gen
.use_rbds
= ctrl
->val
;
1192 case VIVID_CID_RADIO_RX_RDS_BLOCKIO
:
1193 dev
->radio_rx_rds_controls
= ctrl
->val
;
1194 dev
->radio_rx_caps
&= ~V4L2_CAP_READWRITE
;
1195 dev
->radio_rx_rds_use_alternates
= false;
1196 if (!dev
->radio_rx_rds_controls
) {
1197 dev
->radio_rx_caps
|= V4L2_CAP_READWRITE
;
1198 __v4l2_ctrl_s_ctrl(dev
->radio_rx_rds_pty
, 0);
1199 __v4l2_ctrl_s_ctrl(dev
->radio_rx_rds_ta
, 0);
1200 __v4l2_ctrl_s_ctrl(dev
->radio_rx_rds_tp
, 0);
1201 __v4l2_ctrl_s_ctrl(dev
->radio_rx_rds_ms
, 0);
1202 __v4l2_ctrl_s_ctrl_string(dev
->radio_rx_rds_psname
, "");
1203 __v4l2_ctrl_s_ctrl_string(dev
->radio_rx_rds_radiotext
, "");
1205 v4l2_ctrl_activate(dev
->radio_rx_rds_pty
, dev
->radio_rx_rds_controls
);
1206 v4l2_ctrl_activate(dev
->radio_rx_rds_psname
, dev
->radio_rx_rds_controls
);
1207 v4l2_ctrl_activate(dev
->radio_rx_rds_radiotext
, dev
->radio_rx_rds_controls
);
1208 v4l2_ctrl_activate(dev
->radio_rx_rds_ta
, dev
->radio_rx_rds_controls
);
1209 v4l2_ctrl_activate(dev
->radio_rx_rds_tp
, dev
->radio_rx_rds_controls
);
1210 v4l2_ctrl_activate(dev
->radio_rx_rds_ms
, dev
->radio_rx_rds_controls
);
1212 case V4L2_CID_RDS_RECEPTION
:
1213 dev
->radio_rx_rds_enabled
= ctrl
->val
;
1219 static const struct v4l2_ctrl_ops vivid_radio_rx_ctrl_ops
= {
1220 .s_ctrl
= vivid_radio_rx_s_ctrl
,
1223 static const char * const vivid_ctrl_radio_rds_mode_strings
[] = {
1229 static const struct v4l2_ctrl_config vivid_ctrl_radio_rx_rds_blockio
= {
1230 .ops
= &vivid_radio_rx_ctrl_ops
,
1231 .id
= VIVID_CID_RADIO_RX_RDS_BLOCKIO
,
1232 .name
= "RDS Rx I/O Mode",
1233 .type
= V4L2_CTRL_TYPE_MENU
,
1234 .qmenu
= vivid_ctrl_radio_rds_mode_strings
,
1238 static const struct v4l2_ctrl_config vivid_ctrl_radio_rx_rds_rbds
= {
1239 .ops
= &vivid_radio_rx_ctrl_ops
,
1240 .id
= VIVID_CID_RADIO_RX_RDS_RBDS
,
1241 .name
= "Generate RBDS Instead of RDS",
1242 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
1247 static const char * const vivid_ctrl_radio_hw_seek_mode_strings
[] = {
1254 static const struct v4l2_ctrl_config vivid_ctrl_radio_hw_seek_mode
= {
1255 .ops
= &vivid_radio_rx_ctrl_ops
,
1256 .id
= VIVID_CID_RADIO_SEEK_MODE
,
1257 .name
= "Radio HW Seek Mode",
1258 .type
= V4L2_CTRL_TYPE_MENU
,
1260 .qmenu
= vivid_ctrl_radio_hw_seek_mode_strings
,
1263 static const struct v4l2_ctrl_config vivid_ctrl_radio_hw_seek_prog_lim
= {
1264 .ops
= &vivid_radio_rx_ctrl_ops
,
1265 .id
= VIVID_CID_RADIO_SEEK_PROG_LIM
,
1266 .name
= "Radio Programmable HW Seek",
1267 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
1273 /* Radio Transmitter Controls */
1275 static int vivid_radio_tx_s_ctrl(struct v4l2_ctrl
*ctrl
)
1277 struct vivid_dev
*dev
= container_of(ctrl
->handler
, struct vivid_dev
, ctrl_hdl_radio_tx
);
1280 case VIVID_CID_RADIO_TX_RDS_BLOCKIO
:
1281 dev
->radio_tx_rds_controls
= ctrl
->val
;
1282 dev
->radio_tx_caps
&= ~V4L2_CAP_READWRITE
;
1283 if (!dev
->radio_tx_rds_controls
)
1284 dev
->radio_tx_caps
|= V4L2_CAP_READWRITE
;
1286 case V4L2_CID_RDS_TX_PTY
:
1287 if (dev
->radio_rx_rds_controls
)
1288 v4l2_ctrl_s_ctrl(dev
->radio_rx_rds_pty
, ctrl
->val
);
1290 case V4L2_CID_RDS_TX_PS_NAME
:
1291 if (dev
->radio_rx_rds_controls
)
1292 v4l2_ctrl_s_ctrl_string(dev
->radio_rx_rds_psname
, ctrl
->p_new
.p_char
);
1294 case V4L2_CID_RDS_TX_RADIO_TEXT
:
1295 if (dev
->radio_rx_rds_controls
)
1296 v4l2_ctrl_s_ctrl_string(dev
->radio_rx_rds_radiotext
, ctrl
->p_new
.p_char
);
1298 case V4L2_CID_RDS_TX_TRAFFIC_ANNOUNCEMENT
:
1299 if (dev
->radio_rx_rds_controls
)
1300 v4l2_ctrl_s_ctrl(dev
->radio_rx_rds_ta
, ctrl
->val
);
1302 case V4L2_CID_RDS_TX_TRAFFIC_PROGRAM
:
1303 if (dev
->radio_rx_rds_controls
)
1304 v4l2_ctrl_s_ctrl(dev
->radio_rx_rds_tp
, ctrl
->val
);
1306 case V4L2_CID_RDS_TX_MUSIC_SPEECH
:
1307 if (dev
->radio_rx_rds_controls
)
1308 v4l2_ctrl_s_ctrl(dev
->radio_rx_rds_ms
, ctrl
->val
);
1314 static const struct v4l2_ctrl_ops vivid_radio_tx_ctrl_ops
= {
1315 .s_ctrl
= vivid_radio_tx_s_ctrl
,
1318 static const struct v4l2_ctrl_config vivid_ctrl_radio_tx_rds_blockio
= {
1319 .ops
= &vivid_radio_tx_ctrl_ops
,
1320 .id
= VIVID_CID_RADIO_TX_RDS_BLOCKIO
,
1321 .name
= "RDS Tx I/O Mode",
1322 .type
= V4L2_CTRL_TYPE_MENU
,
1323 .qmenu
= vivid_ctrl_radio_rds_mode_strings
,
1329 /* SDR Capture Controls */
1331 static int vivid_sdr_cap_s_ctrl(struct v4l2_ctrl
*ctrl
)
1333 struct vivid_dev
*dev
= container_of(ctrl
->handler
, struct vivid_dev
, ctrl_hdl_sdr_cap
);
1336 case VIVID_CID_SDR_CAP_FM_DEVIATION
:
1337 dev
->sdr_fm_deviation
= ctrl
->val
;
1343 static const struct v4l2_ctrl_ops vivid_sdr_cap_ctrl_ops
= {
1344 .s_ctrl
= vivid_sdr_cap_s_ctrl
,
1347 static const struct v4l2_ctrl_config vivid_ctrl_sdr_cap_fm_deviation
= {
1348 .ops
= &vivid_sdr_cap_ctrl_ops
,
1349 .id
= VIVID_CID_SDR_CAP_FM_DEVIATION
,
1350 .name
= "FM Deviation",
1351 .type
= V4L2_CTRL_TYPE_INTEGER
,
1359 static const struct v4l2_ctrl_config vivid_ctrl_class
= {
1360 .ops
= &vivid_user_gen_ctrl_ops
,
1361 .flags
= V4L2_CTRL_FLAG_READ_ONLY
| V4L2_CTRL_FLAG_WRITE_ONLY
,
1362 .id
= VIVID_CID_VIVID_CLASS
,
1363 .name
= "Vivid Controls",
1364 .type
= V4L2_CTRL_TYPE_CTRL_CLASS
,
1367 int vivid_create_controls(struct vivid_dev
*dev
, bool show_ccs_cap
,
1368 bool show_ccs_out
, bool no_error_inj
,
1369 bool has_sdtv
, bool has_hdmi
)
1371 struct v4l2_ctrl_handler
*hdl_user_gen
= &dev
->ctrl_hdl_user_gen
;
1372 struct v4l2_ctrl_handler
*hdl_user_vid
= &dev
->ctrl_hdl_user_vid
;
1373 struct v4l2_ctrl_handler
*hdl_user_aud
= &dev
->ctrl_hdl_user_aud
;
1374 struct v4l2_ctrl_handler
*hdl_streaming
= &dev
->ctrl_hdl_streaming
;
1375 struct v4l2_ctrl_handler
*hdl_sdtv_cap
= &dev
->ctrl_hdl_sdtv_cap
;
1376 struct v4l2_ctrl_handler
*hdl_loop_cap
= &dev
->ctrl_hdl_loop_cap
;
1377 struct v4l2_ctrl_handler
*hdl_fb
= &dev
->ctrl_hdl_fb
;
1378 struct v4l2_ctrl_handler
*hdl_vid_cap
= &dev
->ctrl_hdl_vid_cap
;
1379 struct v4l2_ctrl_handler
*hdl_vid_out
= &dev
->ctrl_hdl_vid_out
;
1380 struct v4l2_ctrl_handler
*hdl_vbi_cap
= &dev
->ctrl_hdl_vbi_cap
;
1381 struct v4l2_ctrl_handler
*hdl_vbi_out
= &dev
->ctrl_hdl_vbi_out
;
1382 struct v4l2_ctrl_handler
*hdl_radio_rx
= &dev
->ctrl_hdl_radio_rx
;
1383 struct v4l2_ctrl_handler
*hdl_radio_tx
= &dev
->ctrl_hdl_radio_tx
;
1384 struct v4l2_ctrl_handler
*hdl_sdr_cap
= &dev
->ctrl_hdl_sdr_cap
;
1385 struct v4l2_ctrl_config vivid_ctrl_dv_timings
= {
1386 .ops
= &vivid_vid_cap_ctrl_ops
,
1387 .id
= VIVID_CID_DV_TIMINGS
,
1388 .name
= "DV Timings",
1389 .type
= V4L2_CTRL_TYPE_MENU
,
1393 v4l2_ctrl_handler_init(hdl_user_gen
, 10);
1394 v4l2_ctrl_new_custom(hdl_user_gen
, &vivid_ctrl_class
, NULL
);
1395 v4l2_ctrl_handler_init(hdl_user_vid
, 9);
1396 v4l2_ctrl_new_custom(hdl_user_vid
, &vivid_ctrl_class
, NULL
);
1397 v4l2_ctrl_handler_init(hdl_user_aud
, 2);
1398 v4l2_ctrl_new_custom(hdl_user_aud
, &vivid_ctrl_class
, NULL
);
1399 v4l2_ctrl_handler_init(hdl_streaming
, 8);
1400 v4l2_ctrl_new_custom(hdl_streaming
, &vivid_ctrl_class
, NULL
);
1401 v4l2_ctrl_handler_init(hdl_sdtv_cap
, 2);
1402 v4l2_ctrl_new_custom(hdl_sdtv_cap
, &vivid_ctrl_class
, NULL
);
1403 v4l2_ctrl_handler_init(hdl_loop_cap
, 1);
1404 v4l2_ctrl_new_custom(hdl_loop_cap
, &vivid_ctrl_class
, NULL
);
1405 v4l2_ctrl_handler_init(hdl_fb
, 1);
1406 v4l2_ctrl_new_custom(hdl_fb
, &vivid_ctrl_class
, NULL
);
1407 v4l2_ctrl_handler_init(hdl_vid_cap
, 55);
1408 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_class
, NULL
);
1409 v4l2_ctrl_handler_init(hdl_vid_out
, 26);
1410 if (!no_error_inj
|| dev
->has_fb
)
1411 v4l2_ctrl_new_custom(hdl_vid_out
, &vivid_ctrl_class
, NULL
);
1412 v4l2_ctrl_handler_init(hdl_vbi_cap
, 21);
1413 v4l2_ctrl_new_custom(hdl_vbi_cap
, &vivid_ctrl_class
, NULL
);
1414 v4l2_ctrl_handler_init(hdl_vbi_out
, 19);
1416 v4l2_ctrl_new_custom(hdl_vbi_out
, &vivid_ctrl_class
, NULL
);
1417 v4l2_ctrl_handler_init(hdl_radio_rx
, 17);
1418 v4l2_ctrl_new_custom(hdl_radio_rx
, &vivid_ctrl_class
, NULL
);
1419 v4l2_ctrl_handler_init(hdl_radio_tx
, 17);
1420 v4l2_ctrl_new_custom(hdl_radio_tx
, &vivid_ctrl_class
, NULL
);
1421 v4l2_ctrl_handler_init(hdl_sdr_cap
, 19);
1422 v4l2_ctrl_new_custom(hdl_sdr_cap
, &vivid_ctrl_class
, NULL
);
1425 dev
->volume
= v4l2_ctrl_new_std(hdl_user_aud
, NULL
,
1426 V4L2_CID_AUDIO_VOLUME
, 0, 255, 1, 200);
1427 dev
->mute
= v4l2_ctrl_new_std(hdl_user_aud
, NULL
,
1428 V4L2_CID_AUDIO_MUTE
, 0, 1, 1, 0);
1429 if (dev
->has_vid_cap
) {
1430 dev
->brightness
= v4l2_ctrl_new_std(hdl_user_vid
, &vivid_user_vid_ctrl_ops
,
1431 V4L2_CID_BRIGHTNESS
, 0, 255, 1, 128);
1432 for (i
= 0; i
< MAX_INPUTS
; i
++)
1433 dev
->input_brightness
[i
] = 128;
1434 dev
->contrast
= v4l2_ctrl_new_std(hdl_user_vid
, &vivid_user_vid_ctrl_ops
,
1435 V4L2_CID_CONTRAST
, 0, 255, 1, 128);
1436 dev
->saturation
= v4l2_ctrl_new_std(hdl_user_vid
, &vivid_user_vid_ctrl_ops
,
1437 V4L2_CID_SATURATION
, 0, 255, 1, 128);
1438 dev
->hue
= v4l2_ctrl_new_std(hdl_user_vid
, &vivid_user_vid_ctrl_ops
,
1439 V4L2_CID_HUE
, -128, 128, 1, 0);
1440 v4l2_ctrl_new_std(hdl_user_vid
, &vivid_user_vid_ctrl_ops
,
1441 V4L2_CID_HFLIP
, 0, 1, 1, 0);
1442 v4l2_ctrl_new_std(hdl_user_vid
, &vivid_user_vid_ctrl_ops
,
1443 V4L2_CID_VFLIP
, 0, 1, 1, 0);
1444 dev
->autogain
= v4l2_ctrl_new_std(hdl_user_vid
, &vivid_user_vid_ctrl_ops
,
1445 V4L2_CID_AUTOGAIN
, 0, 1, 1, 1);
1446 dev
->gain
= v4l2_ctrl_new_std(hdl_user_vid
, &vivid_user_vid_ctrl_ops
,
1447 V4L2_CID_GAIN
, 0, 255, 1, 100);
1448 dev
->alpha
= v4l2_ctrl_new_std(hdl_user_vid
, &vivid_user_vid_ctrl_ops
,
1449 V4L2_CID_ALPHA_COMPONENT
, 0, 255, 1, 0);
1451 dev
->button
= v4l2_ctrl_new_custom(hdl_user_gen
, &vivid_ctrl_button
, NULL
);
1452 dev
->int32
= v4l2_ctrl_new_custom(hdl_user_gen
, &vivid_ctrl_int32
, NULL
);
1453 dev
->int64
= v4l2_ctrl_new_custom(hdl_user_gen
, &vivid_ctrl_int64
, NULL
);
1454 dev
->boolean
= v4l2_ctrl_new_custom(hdl_user_gen
, &vivid_ctrl_boolean
, NULL
);
1455 dev
->menu
= v4l2_ctrl_new_custom(hdl_user_gen
, &vivid_ctrl_menu
, NULL
);
1456 dev
->string
= v4l2_ctrl_new_custom(hdl_user_gen
, &vivid_ctrl_string
, NULL
);
1457 dev
->bitmask
= v4l2_ctrl_new_custom(hdl_user_gen
, &vivid_ctrl_bitmask
, NULL
);
1458 dev
->int_menu
= v4l2_ctrl_new_custom(hdl_user_gen
, &vivid_ctrl_int_menu
, NULL
);
1459 v4l2_ctrl_new_custom(hdl_user_gen
, &vivid_ctrl_u32_array
, NULL
);
1460 v4l2_ctrl_new_custom(hdl_user_gen
, &vivid_ctrl_u16_matrix
, NULL
);
1461 v4l2_ctrl_new_custom(hdl_user_gen
, &vivid_ctrl_u8_4d_array
, NULL
);
1463 if (dev
->has_vid_cap
) {
1464 /* Image Processing Controls */
1465 struct v4l2_ctrl_config vivid_ctrl_test_pattern
= {
1466 .ops
= &vivid_vid_cap_ctrl_ops
,
1467 .id
= VIVID_CID_TEST_PATTERN
,
1468 .name
= "Test Pattern",
1469 .type
= V4L2_CTRL_TYPE_MENU
,
1470 .max
= TPG_PAT_NOISE
,
1471 .qmenu
= tpg_pattern_strings
,
1474 dev
->test_pattern
= v4l2_ctrl_new_custom(hdl_vid_cap
,
1475 &vivid_ctrl_test_pattern
, NULL
);
1476 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_perc_fill
, NULL
);
1477 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_hor_movement
, NULL
);
1478 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_vert_movement
, NULL
);
1479 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_osd_mode
, NULL
);
1480 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_show_border
, NULL
);
1481 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_show_square
, NULL
);
1482 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_hflip
, NULL
);
1483 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_vflip
, NULL
);
1484 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_insert_sav
, NULL
);
1485 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_insert_eav
, NULL
);
1486 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_reduced_fps
, NULL
);
1488 dev
->ctrl_has_crop_cap
= v4l2_ctrl_new_custom(hdl_vid_cap
,
1489 &vivid_ctrl_has_crop_cap
, NULL
);
1490 dev
->ctrl_has_compose_cap
= v4l2_ctrl_new_custom(hdl_vid_cap
,
1491 &vivid_ctrl_has_compose_cap
, NULL
);
1492 dev
->ctrl_has_scaler_cap
= v4l2_ctrl_new_custom(hdl_vid_cap
,
1493 &vivid_ctrl_has_scaler_cap
, NULL
);
1496 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_tstamp_src
, NULL
);
1497 dev
->colorspace
= v4l2_ctrl_new_custom(hdl_vid_cap
,
1498 &vivid_ctrl_colorspace
, NULL
);
1499 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_xfer_func
, NULL
);
1500 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_ycbcr_enc
, NULL
);
1501 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_hsv_enc
, NULL
);
1502 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_quantization
, NULL
);
1503 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_alpha_mode
, NULL
);
1506 if (dev
->has_vid_out
&& show_ccs_out
) {
1507 dev
->ctrl_has_crop_out
= v4l2_ctrl_new_custom(hdl_vid_out
,
1508 &vivid_ctrl_has_crop_out
, NULL
);
1509 dev
->ctrl_has_compose_out
= v4l2_ctrl_new_custom(hdl_vid_out
,
1510 &vivid_ctrl_has_compose_out
, NULL
);
1511 dev
->ctrl_has_scaler_out
= v4l2_ctrl_new_custom(hdl_vid_out
,
1512 &vivid_ctrl_has_scaler_out
, NULL
);
1516 * Testing this driver with v4l2-compliance will trigger the error
1517 * injection controls, and after that nothing will work as expected.
1518 * So we have a module option to drop these error injecting controls
1519 * allowing us to run v4l2_compliance again.
1521 if (!no_error_inj
) {
1522 v4l2_ctrl_new_custom(hdl_user_gen
, &vivid_ctrl_disconnect
, NULL
);
1523 v4l2_ctrl_new_custom(hdl_streaming
, &vivid_ctrl_dqbuf_error
, NULL
);
1524 v4l2_ctrl_new_custom(hdl_streaming
, &vivid_ctrl_perc_dropped
, NULL
);
1525 v4l2_ctrl_new_custom(hdl_streaming
, &vivid_ctrl_queue_setup_error
, NULL
);
1526 v4l2_ctrl_new_custom(hdl_streaming
, &vivid_ctrl_buf_prepare_error
, NULL
);
1527 v4l2_ctrl_new_custom(hdl_streaming
, &vivid_ctrl_start_streaming_error
, NULL
);
1528 v4l2_ctrl_new_custom(hdl_streaming
, &vivid_ctrl_queue_error
, NULL
);
1529 v4l2_ctrl_new_custom(hdl_streaming
, &vivid_ctrl_seq_wrap
, NULL
);
1530 v4l2_ctrl_new_custom(hdl_streaming
, &vivid_ctrl_time_wrap
, NULL
);
1533 if (has_sdtv
&& (dev
->has_vid_cap
|| dev
->has_vbi_cap
)) {
1534 if (dev
->has_vid_cap
)
1535 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_std_aspect_ratio
, NULL
);
1536 dev
->ctrl_std_signal_mode
= v4l2_ctrl_new_custom(hdl_sdtv_cap
,
1537 &vivid_ctrl_std_signal_mode
, NULL
);
1538 dev
->ctrl_standard
= v4l2_ctrl_new_custom(hdl_sdtv_cap
,
1539 &vivid_ctrl_standard
, NULL
);
1540 if (dev
->ctrl_std_signal_mode
)
1541 v4l2_ctrl_cluster(2, &dev
->ctrl_std_signal_mode
);
1542 if (dev
->has_raw_vbi_cap
)
1543 v4l2_ctrl_new_custom(hdl_vbi_cap
, &vivid_ctrl_vbi_cap_interlaced
, NULL
);
1546 if (has_hdmi
&& dev
->has_vid_cap
) {
1547 dev
->ctrl_dv_timings_signal_mode
= v4l2_ctrl_new_custom(hdl_vid_cap
,
1548 &vivid_ctrl_dv_timings_signal_mode
, NULL
);
1550 vivid_ctrl_dv_timings
.max
= dev
->query_dv_timings_size
- 1;
1551 vivid_ctrl_dv_timings
.qmenu
=
1552 (const char * const *)dev
->query_dv_timings_qmenu
;
1553 dev
->ctrl_dv_timings
= v4l2_ctrl_new_custom(hdl_vid_cap
,
1554 &vivid_ctrl_dv_timings
, NULL
);
1555 if (dev
->ctrl_dv_timings_signal_mode
)
1556 v4l2_ctrl_cluster(2, &dev
->ctrl_dv_timings_signal_mode
);
1558 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_dv_timings_aspect_ratio
, NULL
);
1559 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_max_edid_blocks
, NULL
);
1560 dev
->real_rgb_range_cap
= v4l2_ctrl_new_custom(hdl_vid_cap
,
1561 &vivid_ctrl_limited_rgb_range
, NULL
);
1562 dev
->rgb_range_cap
= v4l2_ctrl_new_std_menu(hdl_vid_cap
,
1563 &vivid_vid_cap_ctrl_ops
,
1564 V4L2_CID_DV_RX_RGB_RANGE
, V4L2_DV_RGB_RANGE_FULL
,
1565 0, V4L2_DV_RGB_RANGE_AUTO
);
1567 if (has_hdmi
&& dev
->has_vid_out
) {
1569 * We aren't doing anything with this at the moment, but
1570 * HDMI outputs typically have this controls.
1572 dev
->ctrl_tx_rgb_range
= v4l2_ctrl_new_std_menu(hdl_vid_out
, NULL
,
1573 V4L2_CID_DV_TX_RGB_RANGE
, V4L2_DV_RGB_RANGE_FULL
,
1574 0, V4L2_DV_RGB_RANGE_AUTO
);
1575 dev
->ctrl_tx_mode
= v4l2_ctrl_new_std_menu(hdl_vid_out
, NULL
,
1576 V4L2_CID_DV_TX_MODE
, V4L2_DV_TX_MODE_HDMI
,
1577 0, V4L2_DV_TX_MODE_HDMI
);
1579 if ((dev
->has_vid_cap
&& dev
->has_vid_out
) ||
1580 (dev
->has_vbi_cap
&& dev
->has_vbi_out
))
1581 v4l2_ctrl_new_custom(hdl_loop_cap
, &vivid_ctrl_loop_video
, NULL
);
1584 v4l2_ctrl_new_custom(hdl_fb
, &vivid_ctrl_clear_fb
, NULL
);
1586 if (dev
->has_radio_rx
) {
1587 v4l2_ctrl_new_custom(hdl_radio_rx
, &vivid_ctrl_radio_hw_seek_mode
, NULL
);
1588 v4l2_ctrl_new_custom(hdl_radio_rx
, &vivid_ctrl_radio_hw_seek_prog_lim
, NULL
);
1589 v4l2_ctrl_new_custom(hdl_radio_rx
, &vivid_ctrl_radio_rx_rds_blockio
, NULL
);
1590 v4l2_ctrl_new_custom(hdl_radio_rx
, &vivid_ctrl_radio_rx_rds_rbds
, NULL
);
1591 v4l2_ctrl_new_std(hdl_radio_rx
, &vivid_radio_rx_ctrl_ops
,
1592 V4L2_CID_RDS_RECEPTION
, 0, 1, 1, 1);
1593 dev
->radio_rx_rds_pty
= v4l2_ctrl_new_std(hdl_radio_rx
,
1594 &vivid_radio_rx_ctrl_ops
,
1595 V4L2_CID_RDS_RX_PTY
, 0, 31, 1, 0);
1596 dev
->radio_rx_rds_psname
= v4l2_ctrl_new_std(hdl_radio_rx
,
1597 &vivid_radio_rx_ctrl_ops
,
1598 V4L2_CID_RDS_RX_PS_NAME
, 0, 8, 8, 0);
1599 dev
->radio_rx_rds_radiotext
= v4l2_ctrl_new_std(hdl_radio_rx
,
1600 &vivid_radio_rx_ctrl_ops
,
1601 V4L2_CID_RDS_RX_RADIO_TEXT
, 0, 64, 64, 0);
1602 dev
->radio_rx_rds_ta
= v4l2_ctrl_new_std(hdl_radio_rx
,
1603 &vivid_radio_rx_ctrl_ops
,
1604 V4L2_CID_RDS_RX_TRAFFIC_ANNOUNCEMENT
, 0, 1, 1, 0);
1605 dev
->radio_rx_rds_tp
= v4l2_ctrl_new_std(hdl_radio_rx
,
1606 &vivid_radio_rx_ctrl_ops
,
1607 V4L2_CID_RDS_RX_TRAFFIC_PROGRAM
, 0, 1, 1, 0);
1608 dev
->radio_rx_rds_ms
= v4l2_ctrl_new_std(hdl_radio_rx
,
1609 &vivid_radio_rx_ctrl_ops
,
1610 V4L2_CID_RDS_RX_MUSIC_SPEECH
, 0, 1, 1, 1);
1612 if (dev
->has_radio_tx
) {
1613 v4l2_ctrl_new_custom(hdl_radio_tx
,
1614 &vivid_ctrl_radio_tx_rds_blockio
, NULL
);
1615 dev
->radio_tx_rds_pi
= v4l2_ctrl_new_std(hdl_radio_tx
,
1616 &vivid_radio_tx_ctrl_ops
,
1617 V4L2_CID_RDS_TX_PI
, 0, 0xffff, 1, 0x8088);
1618 dev
->radio_tx_rds_pty
= v4l2_ctrl_new_std(hdl_radio_tx
,
1619 &vivid_radio_tx_ctrl_ops
,
1620 V4L2_CID_RDS_TX_PTY
, 0, 31, 1, 3);
1621 dev
->radio_tx_rds_psname
= v4l2_ctrl_new_std(hdl_radio_tx
,
1622 &vivid_radio_tx_ctrl_ops
,
1623 V4L2_CID_RDS_TX_PS_NAME
, 0, 8, 8, 0);
1624 if (dev
->radio_tx_rds_psname
)
1625 v4l2_ctrl_s_ctrl_string(dev
->radio_tx_rds_psname
, "VIVID-TX");
1626 dev
->radio_tx_rds_radiotext
= v4l2_ctrl_new_std(hdl_radio_tx
,
1627 &vivid_radio_tx_ctrl_ops
,
1628 V4L2_CID_RDS_TX_RADIO_TEXT
, 0, 64 * 2, 64, 0);
1629 if (dev
->radio_tx_rds_radiotext
)
1630 v4l2_ctrl_s_ctrl_string(dev
->radio_tx_rds_radiotext
,
1631 "This is a VIVID default Radio Text template text, change at will");
1632 dev
->radio_tx_rds_mono_stereo
= v4l2_ctrl_new_std(hdl_radio_tx
,
1633 &vivid_radio_tx_ctrl_ops
,
1634 V4L2_CID_RDS_TX_MONO_STEREO
, 0, 1, 1, 1);
1635 dev
->radio_tx_rds_art_head
= v4l2_ctrl_new_std(hdl_radio_tx
,
1636 &vivid_radio_tx_ctrl_ops
,
1637 V4L2_CID_RDS_TX_ARTIFICIAL_HEAD
, 0, 1, 1, 0);
1638 dev
->radio_tx_rds_compressed
= v4l2_ctrl_new_std(hdl_radio_tx
,
1639 &vivid_radio_tx_ctrl_ops
,
1640 V4L2_CID_RDS_TX_COMPRESSED
, 0, 1, 1, 0);
1641 dev
->radio_tx_rds_dyn_pty
= v4l2_ctrl_new_std(hdl_radio_tx
,
1642 &vivid_radio_tx_ctrl_ops
,
1643 V4L2_CID_RDS_TX_DYNAMIC_PTY
, 0, 1, 1, 0);
1644 dev
->radio_tx_rds_ta
= v4l2_ctrl_new_std(hdl_radio_tx
,
1645 &vivid_radio_tx_ctrl_ops
,
1646 V4L2_CID_RDS_TX_TRAFFIC_ANNOUNCEMENT
, 0, 1, 1, 0);
1647 dev
->radio_tx_rds_tp
= v4l2_ctrl_new_std(hdl_radio_tx
,
1648 &vivid_radio_tx_ctrl_ops
,
1649 V4L2_CID_RDS_TX_TRAFFIC_PROGRAM
, 0, 1, 1, 1);
1650 dev
->radio_tx_rds_ms
= v4l2_ctrl_new_std(hdl_radio_tx
,
1651 &vivid_radio_tx_ctrl_ops
,
1652 V4L2_CID_RDS_TX_MUSIC_SPEECH
, 0, 1, 1, 1);
1654 if (dev
->has_sdr_cap
) {
1655 v4l2_ctrl_new_custom(hdl_sdr_cap
,
1656 &vivid_ctrl_sdr_cap_fm_deviation
, NULL
);
1658 if (hdl_user_gen
->error
)
1659 return hdl_user_gen
->error
;
1660 if (hdl_user_vid
->error
)
1661 return hdl_user_vid
->error
;
1662 if (hdl_user_aud
->error
)
1663 return hdl_user_aud
->error
;
1664 if (hdl_streaming
->error
)
1665 return hdl_streaming
->error
;
1666 if (hdl_sdr_cap
->error
)
1667 return hdl_sdr_cap
->error
;
1668 if (hdl_loop_cap
->error
)
1669 return hdl_loop_cap
->error
;
1672 v4l2_ctrl_auto_cluster(2, &dev
->autogain
, 0, true);
1674 if (dev
->has_vid_cap
) {
1675 v4l2_ctrl_add_handler(hdl_vid_cap
, hdl_user_gen
, NULL
);
1676 v4l2_ctrl_add_handler(hdl_vid_cap
, hdl_user_vid
, NULL
);
1677 v4l2_ctrl_add_handler(hdl_vid_cap
, hdl_user_aud
, NULL
);
1678 v4l2_ctrl_add_handler(hdl_vid_cap
, hdl_streaming
, NULL
);
1679 v4l2_ctrl_add_handler(hdl_vid_cap
, hdl_sdtv_cap
, NULL
);
1680 v4l2_ctrl_add_handler(hdl_vid_cap
, hdl_loop_cap
, NULL
);
1681 v4l2_ctrl_add_handler(hdl_vid_cap
, hdl_fb
, NULL
);
1682 if (hdl_vid_cap
->error
)
1683 return hdl_vid_cap
->error
;
1684 dev
->vid_cap_dev
.ctrl_handler
= hdl_vid_cap
;
1686 if (dev
->has_vid_out
) {
1687 v4l2_ctrl_add_handler(hdl_vid_out
, hdl_user_gen
, NULL
);
1688 v4l2_ctrl_add_handler(hdl_vid_out
, hdl_user_aud
, NULL
);
1689 v4l2_ctrl_add_handler(hdl_vid_out
, hdl_streaming
, NULL
);
1690 v4l2_ctrl_add_handler(hdl_vid_out
, hdl_fb
, NULL
);
1691 if (hdl_vid_out
->error
)
1692 return hdl_vid_out
->error
;
1693 dev
->vid_out_dev
.ctrl_handler
= hdl_vid_out
;
1695 if (dev
->has_vbi_cap
) {
1696 v4l2_ctrl_add_handler(hdl_vbi_cap
, hdl_user_gen
, NULL
);
1697 v4l2_ctrl_add_handler(hdl_vbi_cap
, hdl_streaming
, NULL
);
1698 v4l2_ctrl_add_handler(hdl_vbi_cap
, hdl_sdtv_cap
, NULL
);
1699 v4l2_ctrl_add_handler(hdl_vbi_cap
, hdl_loop_cap
, NULL
);
1700 if (hdl_vbi_cap
->error
)
1701 return hdl_vbi_cap
->error
;
1702 dev
->vbi_cap_dev
.ctrl_handler
= hdl_vbi_cap
;
1704 if (dev
->has_vbi_out
) {
1705 v4l2_ctrl_add_handler(hdl_vbi_out
, hdl_user_gen
, NULL
);
1706 v4l2_ctrl_add_handler(hdl_vbi_out
, hdl_streaming
, NULL
);
1707 if (hdl_vbi_out
->error
)
1708 return hdl_vbi_out
->error
;
1709 dev
->vbi_out_dev
.ctrl_handler
= hdl_vbi_out
;
1711 if (dev
->has_radio_rx
) {
1712 v4l2_ctrl_add_handler(hdl_radio_rx
, hdl_user_gen
, NULL
);
1713 v4l2_ctrl_add_handler(hdl_radio_rx
, hdl_user_aud
, NULL
);
1714 if (hdl_radio_rx
->error
)
1715 return hdl_radio_rx
->error
;
1716 dev
->radio_rx_dev
.ctrl_handler
= hdl_radio_rx
;
1718 if (dev
->has_radio_tx
) {
1719 v4l2_ctrl_add_handler(hdl_radio_tx
, hdl_user_gen
, NULL
);
1720 v4l2_ctrl_add_handler(hdl_radio_tx
, hdl_user_aud
, NULL
);
1721 if (hdl_radio_tx
->error
)
1722 return hdl_radio_tx
->error
;
1723 dev
->radio_tx_dev
.ctrl_handler
= hdl_radio_tx
;
1725 if (dev
->has_sdr_cap
) {
1726 v4l2_ctrl_add_handler(hdl_sdr_cap
, hdl_user_gen
, NULL
);
1727 v4l2_ctrl_add_handler(hdl_sdr_cap
, hdl_streaming
, NULL
);
1728 if (hdl_sdr_cap
->error
)
1729 return hdl_sdr_cap
->error
;
1730 dev
->sdr_cap_dev
.ctrl_handler
= hdl_sdr_cap
;
1735 void vivid_free_controls(struct vivid_dev
*dev
)
1737 v4l2_ctrl_handler_free(&dev
->ctrl_hdl_vid_cap
);
1738 v4l2_ctrl_handler_free(&dev
->ctrl_hdl_vid_out
);
1739 v4l2_ctrl_handler_free(&dev
->ctrl_hdl_vbi_cap
);
1740 v4l2_ctrl_handler_free(&dev
->ctrl_hdl_vbi_out
);
1741 v4l2_ctrl_handler_free(&dev
->ctrl_hdl_radio_rx
);
1742 v4l2_ctrl_handler_free(&dev
->ctrl_hdl_radio_tx
);
1743 v4l2_ctrl_handler_free(&dev
->ctrl_hdl_sdr_cap
);
1744 v4l2_ctrl_handler_free(&dev
->ctrl_hdl_user_gen
);
1745 v4l2_ctrl_handler_free(&dev
->ctrl_hdl_user_vid
);
1746 v4l2_ctrl_handler_free(&dev
->ctrl_hdl_user_aud
);
1747 v4l2_ctrl_handler_free(&dev
->ctrl_hdl_streaming
);
1748 v4l2_ctrl_handler_free(&dev
->ctrl_hdl_sdtv_cap
);
1749 v4l2_ctrl_handler_free(&dev
->ctrl_hdl_loop_cap
);
1750 v4l2_ctrl_handler_free(&dev
->ctrl_hdl_fb
);