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)
83 #define VIVID_CID_STD_SIGNAL_MODE (VIVID_CID_VIVID_BASE + 60)
84 #define VIVID_CID_STANDARD (VIVID_CID_VIVID_BASE + 61)
85 #define VIVID_CID_DV_TIMINGS_SIGNAL_MODE (VIVID_CID_VIVID_BASE + 62)
86 #define VIVID_CID_DV_TIMINGS (VIVID_CID_VIVID_BASE + 63)
87 #define VIVID_CID_PERC_DROPPED (VIVID_CID_VIVID_BASE + 64)
88 #define VIVID_CID_DISCONNECT (VIVID_CID_VIVID_BASE + 65)
89 #define VIVID_CID_DQBUF_ERROR (VIVID_CID_VIVID_BASE + 66)
90 #define VIVID_CID_QUEUE_SETUP_ERROR (VIVID_CID_VIVID_BASE + 67)
91 #define VIVID_CID_BUF_PREPARE_ERROR (VIVID_CID_VIVID_BASE + 68)
92 #define VIVID_CID_START_STR_ERROR (VIVID_CID_VIVID_BASE + 69)
93 #define VIVID_CID_QUEUE_ERROR (VIVID_CID_VIVID_BASE + 70)
94 #define VIVID_CID_CLEAR_FB (VIVID_CID_VIVID_BASE + 71)
96 #define VIVID_CID_RADIO_SEEK_MODE (VIVID_CID_VIVID_BASE + 90)
97 #define VIVID_CID_RADIO_SEEK_PROG_LIM (VIVID_CID_VIVID_BASE + 91)
98 #define VIVID_CID_RADIO_RX_RDS_RBDS (VIVID_CID_VIVID_BASE + 92)
99 #define VIVID_CID_RADIO_RX_RDS_BLOCKIO (VIVID_CID_VIVID_BASE + 93)
101 #define VIVID_CID_RADIO_TX_RDS_BLOCKIO (VIVID_CID_VIVID_BASE + 94)
103 #define VIVID_CID_SDR_CAP_FM_DEVIATION (VIVID_CID_VIVID_BASE + 110)
105 /* General User Controls */
107 static int vivid_user_gen_s_ctrl(struct v4l2_ctrl
*ctrl
)
109 struct vivid_dev
*dev
= container_of(ctrl
->handler
, struct vivid_dev
, ctrl_hdl_user_gen
);
112 case VIVID_CID_DISCONNECT
:
113 v4l2_info(&dev
->v4l2_dev
, "disconnect\n");
114 clear_bit(V4L2_FL_REGISTERED
, &dev
->vid_cap_dev
.flags
);
115 clear_bit(V4L2_FL_REGISTERED
, &dev
->vid_out_dev
.flags
);
116 clear_bit(V4L2_FL_REGISTERED
, &dev
->vbi_cap_dev
.flags
);
117 clear_bit(V4L2_FL_REGISTERED
, &dev
->vbi_out_dev
.flags
);
118 clear_bit(V4L2_FL_REGISTERED
, &dev
->sdr_cap_dev
.flags
);
119 clear_bit(V4L2_FL_REGISTERED
, &dev
->radio_rx_dev
.flags
);
120 clear_bit(V4L2_FL_REGISTERED
, &dev
->radio_tx_dev
.flags
);
122 case VIVID_CID_CLEAR_FB
:
125 case VIVID_CID_BUTTON
:
126 dev
->button_pressed
= 30;
132 static const struct v4l2_ctrl_ops vivid_user_gen_ctrl_ops
= {
133 .s_ctrl
= vivid_user_gen_s_ctrl
,
136 static const struct v4l2_ctrl_config vivid_ctrl_button
= {
137 .ops
= &vivid_user_gen_ctrl_ops
,
138 .id
= VIVID_CID_BUTTON
,
140 .type
= V4L2_CTRL_TYPE_BUTTON
,
143 static const struct v4l2_ctrl_config vivid_ctrl_boolean
= {
144 .ops
= &vivid_user_gen_ctrl_ops
,
145 .id
= VIVID_CID_BOOLEAN
,
147 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
154 static const struct v4l2_ctrl_config vivid_ctrl_int32
= {
155 .ops
= &vivid_user_gen_ctrl_ops
,
156 .id
= VIVID_CID_INTEGER
,
157 .name
= "Integer 32 Bits",
158 .type
= V4L2_CTRL_TYPE_INTEGER
,
159 .min
= 0xffffffff80000000ULL
,
164 static const struct v4l2_ctrl_config vivid_ctrl_int64
= {
165 .ops
= &vivid_user_gen_ctrl_ops
,
166 .id
= VIVID_CID_INTEGER64
,
167 .name
= "Integer 64 Bits",
168 .type
= V4L2_CTRL_TYPE_INTEGER64
,
169 .min
= 0x8000000000000000ULL
,
170 .max
= 0x7fffffffffffffffLL
,
174 static const struct v4l2_ctrl_config vivid_ctrl_u32_array
= {
175 .ops
= &vivid_user_gen_ctrl_ops
,
176 .id
= VIVID_CID_U32_ARRAY
,
177 .name
= "U32 1 Element Array",
178 .type
= V4L2_CTRL_TYPE_U32
,
186 static const struct v4l2_ctrl_config vivid_ctrl_u16_matrix
= {
187 .ops
= &vivid_user_gen_ctrl_ops
,
188 .id
= VIVID_CID_U16_MATRIX
,
189 .name
= "U16 8x16 Matrix",
190 .type
= V4L2_CTRL_TYPE_U16
,
198 static const struct v4l2_ctrl_config vivid_ctrl_u8_4d_array
= {
199 .ops
= &vivid_user_gen_ctrl_ops
,
200 .id
= VIVID_CID_U8_4D_ARRAY
,
201 .name
= "U8 2x3x4x5 Array",
202 .type
= V4L2_CTRL_TYPE_U8
,
207 .dims
= { 2, 3, 4, 5 },
210 static const char * const vivid_ctrl_menu_strings
[] = {
211 "Menu Item 0 (Skipped)",
213 "Menu Item 2 (Skipped)",
216 "Menu Item 5 (Skipped)",
220 static const struct v4l2_ctrl_config vivid_ctrl_menu
= {
221 .ops
= &vivid_user_gen_ctrl_ops
,
222 .id
= VIVID_CID_MENU
,
224 .type
= V4L2_CTRL_TYPE_MENU
,
228 .menu_skip_mask
= 0x04,
229 .qmenu
= vivid_ctrl_menu_strings
,
232 static const struct v4l2_ctrl_config vivid_ctrl_string
= {
233 .ops
= &vivid_user_gen_ctrl_ops
,
234 .id
= VIVID_CID_STRING
,
236 .type
= V4L2_CTRL_TYPE_STRING
,
242 static const struct v4l2_ctrl_config vivid_ctrl_bitmask
= {
243 .ops
= &vivid_user_gen_ctrl_ops
,
244 .id
= VIVID_CID_BITMASK
,
246 .type
= V4L2_CTRL_TYPE_BITMASK
,
253 static const s64 vivid_ctrl_int_menu_values
[] = {
254 1, 1, 2, 3, 5, 8, 13, 21, 42,
257 static const struct v4l2_ctrl_config vivid_ctrl_int_menu
= {
258 .ops
= &vivid_user_gen_ctrl_ops
,
259 .id
= VIVID_CID_INTMENU
,
260 .name
= "Integer Menu",
261 .type
= V4L2_CTRL_TYPE_INTEGER_MENU
,
265 .menu_skip_mask
= 0x02,
266 .qmenu_int
= vivid_ctrl_int_menu_values
,
269 static const struct v4l2_ctrl_config vivid_ctrl_disconnect
= {
270 .ops
= &vivid_user_gen_ctrl_ops
,
271 .id
= VIVID_CID_DISCONNECT
,
272 .name
= "Disconnect",
273 .type
= V4L2_CTRL_TYPE_BUTTON
,
276 static const struct v4l2_ctrl_config vivid_ctrl_clear_fb
= {
277 .ops
= &vivid_user_gen_ctrl_ops
,
278 .id
= VIVID_CID_CLEAR_FB
,
279 .name
= "Clear Framebuffer",
280 .type
= V4L2_CTRL_TYPE_BUTTON
,
284 /* Video User Controls */
286 static int vivid_user_vid_g_volatile_ctrl(struct v4l2_ctrl
*ctrl
)
288 struct vivid_dev
*dev
= container_of(ctrl
->handler
, struct vivid_dev
, ctrl_hdl_user_vid
);
291 case V4L2_CID_AUTOGAIN
:
292 dev
->gain
->val
= dev
->jiffies_vid_cap
& 0xff;
298 static int vivid_user_vid_s_ctrl(struct v4l2_ctrl
*ctrl
)
300 struct vivid_dev
*dev
= container_of(ctrl
->handler
, struct vivid_dev
, ctrl_hdl_user_vid
);
303 case V4L2_CID_BRIGHTNESS
:
304 dev
->input_brightness
[dev
->input
] = ctrl
->val
- dev
->input
* 128;
305 tpg_s_brightness(&dev
->tpg
, dev
->input_brightness
[dev
->input
]);
307 case V4L2_CID_CONTRAST
:
308 tpg_s_contrast(&dev
->tpg
, ctrl
->val
);
310 case V4L2_CID_SATURATION
:
311 tpg_s_saturation(&dev
->tpg
, ctrl
->val
);
314 tpg_s_hue(&dev
->tpg
, ctrl
->val
);
317 dev
->hflip
= ctrl
->val
;
318 tpg_s_hflip(&dev
->tpg
, dev
->sensor_hflip
^ dev
->hflip
);
321 dev
->vflip
= ctrl
->val
;
322 tpg_s_vflip(&dev
->tpg
, dev
->sensor_vflip
^ dev
->vflip
);
324 case V4L2_CID_ALPHA_COMPONENT
:
325 tpg_s_alpha_component(&dev
->tpg
, ctrl
->val
);
331 static const struct v4l2_ctrl_ops vivid_user_vid_ctrl_ops
= {
332 .g_volatile_ctrl
= vivid_user_vid_g_volatile_ctrl
,
333 .s_ctrl
= vivid_user_vid_s_ctrl
,
337 /* Video Capture Controls */
339 static int vivid_vid_cap_s_ctrl(struct v4l2_ctrl
*ctrl
)
341 static const u32 colorspaces
[] = {
342 V4L2_COLORSPACE_SMPTE170M
,
343 V4L2_COLORSPACE_REC709
,
344 V4L2_COLORSPACE_SRGB
,
345 V4L2_COLORSPACE_ADOBERGB
,
346 V4L2_COLORSPACE_BT2020
,
347 V4L2_COLORSPACE_DCI_P3
,
348 V4L2_COLORSPACE_SMPTE240M
,
349 V4L2_COLORSPACE_470_SYSTEM_M
,
350 V4L2_COLORSPACE_470_SYSTEM_BG
,
352 struct vivid_dev
*dev
= container_of(ctrl
->handler
, struct vivid_dev
, ctrl_hdl_vid_cap
);
356 case VIVID_CID_TEST_PATTERN
:
357 vivid_update_quality(dev
);
358 tpg_s_pattern(&dev
->tpg
, ctrl
->val
);
360 case VIVID_CID_COLORSPACE
:
361 tpg_s_colorspace(&dev
->tpg
, colorspaces
[ctrl
->val
]);
362 vivid_send_source_change(dev
, TV
);
363 vivid_send_source_change(dev
, SVID
);
364 vivid_send_source_change(dev
, HDMI
);
365 vivid_send_source_change(dev
, WEBCAM
);
367 case VIVID_CID_XFER_FUNC
:
368 tpg_s_xfer_func(&dev
->tpg
, ctrl
->val
);
369 vivid_send_source_change(dev
, TV
);
370 vivid_send_source_change(dev
, SVID
);
371 vivid_send_source_change(dev
, HDMI
);
372 vivid_send_source_change(dev
, WEBCAM
);
374 case VIVID_CID_YCBCR_ENC
:
375 tpg_s_ycbcr_enc(&dev
->tpg
, ctrl
->val
);
376 vivid_send_source_change(dev
, TV
);
377 vivid_send_source_change(dev
, SVID
);
378 vivid_send_source_change(dev
, HDMI
);
379 vivid_send_source_change(dev
, WEBCAM
);
381 case VIVID_CID_QUANTIZATION
:
382 tpg_s_quantization(&dev
->tpg
, ctrl
->val
);
383 vivid_send_source_change(dev
, TV
);
384 vivid_send_source_change(dev
, SVID
);
385 vivid_send_source_change(dev
, HDMI
);
386 vivid_send_source_change(dev
, WEBCAM
);
388 case V4L2_CID_DV_RX_RGB_RANGE
:
389 if (!vivid_is_hdmi_cap(dev
))
391 tpg_s_rgb_range(&dev
->tpg
, ctrl
->val
);
393 case VIVID_CID_LIMITED_RGB_RANGE
:
394 tpg_s_real_rgb_range(&dev
->tpg
, ctrl
->val
?
395 V4L2_DV_RGB_RANGE_LIMITED
: V4L2_DV_RGB_RANGE_FULL
);
397 case VIVID_CID_ALPHA_MODE
:
398 tpg_s_alpha_mode(&dev
->tpg
, ctrl
->val
);
400 case VIVID_CID_HOR_MOVEMENT
:
401 tpg_s_mv_hor_mode(&dev
->tpg
, ctrl
->val
);
403 case VIVID_CID_VERT_MOVEMENT
:
404 tpg_s_mv_vert_mode(&dev
->tpg
, ctrl
->val
);
406 case VIVID_CID_OSD_TEXT_MODE
:
407 dev
->osd_mode
= ctrl
->val
;
409 case VIVID_CID_PERCENTAGE_FILL
:
410 tpg_s_perc_fill(&dev
->tpg
, ctrl
->val
);
411 for (i
= 0; i
< VIDEO_MAX_FRAME
; i
++)
412 dev
->must_blank
[i
] = ctrl
->val
< 100;
414 case VIVID_CID_INSERT_SAV
:
415 tpg_s_insert_sav(&dev
->tpg
, ctrl
->val
);
417 case VIVID_CID_INSERT_EAV
:
418 tpg_s_insert_eav(&dev
->tpg
, ctrl
->val
);
420 case VIVID_CID_HFLIP
:
421 dev
->sensor_hflip
= ctrl
->val
;
422 tpg_s_hflip(&dev
->tpg
, dev
->sensor_hflip
^ dev
->hflip
);
424 case VIVID_CID_VFLIP
:
425 dev
->sensor_vflip
= ctrl
->val
;
426 tpg_s_vflip(&dev
->tpg
, dev
->sensor_vflip
^ dev
->vflip
);
428 case VIVID_CID_REDUCED_FPS
:
429 dev
->reduced_fps
= ctrl
->val
;
430 vivid_update_format_cap(dev
, true);
432 case VIVID_CID_HAS_CROP_CAP
:
433 dev
->has_crop_cap
= ctrl
->val
;
434 vivid_update_format_cap(dev
, true);
436 case VIVID_CID_HAS_COMPOSE_CAP
:
437 dev
->has_compose_cap
= ctrl
->val
;
438 vivid_update_format_cap(dev
, true);
440 case VIVID_CID_HAS_SCALER_CAP
:
441 dev
->has_scaler_cap
= ctrl
->val
;
442 vivid_update_format_cap(dev
, true);
444 case VIVID_CID_SHOW_BORDER
:
445 tpg_s_show_border(&dev
->tpg
, ctrl
->val
);
447 case VIVID_CID_SHOW_SQUARE
:
448 tpg_s_show_square(&dev
->tpg
, ctrl
->val
);
450 case VIVID_CID_STD_ASPECT_RATIO
:
451 dev
->std_aspect_ratio
= ctrl
->val
;
452 tpg_s_video_aspect(&dev
->tpg
, vivid_get_video_aspect(dev
));
454 case VIVID_CID_DV_TIMINGS_SIGNAL_MODE
:
455 dev
->dv_timings_signal_mode
= dev
->ctrl_dv_timings_signal_mode
->val
;
456 if (dev
->dv_timings_signal_mode
== SELECTED_DV_TIMINGS
)
457 dev
->query_dv_timings
= dev
->ctrl_dv_timings
->val
;
458 v4l2_ctrl_activate(dev
->ctrl_dv_timings
,
459 dev
->dv_timings_signal_mode
== SELECTED_DV_TIMINGS
);
460 vivid_update_quality(dev
);
461 vivid_send_source_change(dev
, HDMI
);
463 case VIVID_CID_DV_TIMINGS_ASPECT_RATIO
:
464 dev
->dv_timings_aspect_ratio
= ctrl
->val
;
465 tpg_s_video_aspect(&dev
->tpg
, vivid_get_video_aspect(dev
));
467 case VIVID_CID_TSTAMP_SRC
:
468 dev
->tstamp_src_is_soe
= ctrl
->val
;
469 dev
->vb_vid_cap_q
.timestamp_flags
&= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK
;
470 if (dev
->tstamp_src_is_soe
)
471 dev
->vb_vid_cap_q
.timestamp_flags
|= V4L2_BUF_FLAG_TSTAMP_SRC_SOE
;
473 case VIVID_CID_MAX_EDID_BLOCKS
:
474 dev
->edid_max_blocks
= ctrl
->val
;
475 if (dev
->edid_blocks
> dev
->edid_max_blocks
)
476 dev
->edid_blocks
= dev
->edid_max_blocks
;
482 static const struct v4l2_ctrl_ops vivid_vid_cap_ctrl_ops
= {
483 .s_ctrl
= vivid_vid_cap_s_ctrl
,
486 static const char * const vivid_ctrl_hor_movement_strings
[] = {
497 static const struct v4l2_ctrl_config vivid_ctrl_hor_movement
= {
498 .ops
= &vivid_vid_cap_ctrl_ops
,
499 .id
= VIVID_CID_HOR_MOVEMENT
,
500 .name
= "Horizontal Movement",
501 .type
= V4L2_CTRL_TYPE_MENU
,
502 .max
= TPG_MOVE_POS_FAST
,
503 .def
= TPG_MOVE_NONE
,
504 .qmenu
= vivid_ctrl_hor_movement_strings
,
507 static const char * const vivid_ctrl_vert_movement_strings
[] = {
518 static const struct v4l2_ctrl_config vivid_ctrl_vert_movement
= {
519 .ops
= &vivid_vid_cap_ctrl_ops
,
520 .id
= VIVID_CID_VERT_MOVEMENT
,
521 .name
= "Vertical Movement",
522 .type
= V4L2_CTRL_TYPE_MENU
,
523 .max
= TPG_MOVE_POS_FAST
,
524 .def
= TPG_MOVE_NONE
,
525 .qmenu
= vivid_ctrl_vert_movement_strings
,
528 static const struct v4l2_ctrl_config vivid_ctrl_show_border
= {
529 .ops
= &vivid_vid_cap_ctrl_ops
,
530 .id
= VIVID_CID_SHOW_BORDER
,
531 .name
= "Show Border",
532 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
537 static const struct v4l2_ctrl_config vivid_ctrl_show_square
= {
538 .ops
= &vivid_vid_cap_ctrl_ops
,
539 .id
= VIVID_CID_SHOW_SQUARE
,
540 .name
= "Show Square",
541 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
546 static const char * const vivid_ctrl_osd_mode_strings
[] = {
553 static const struct v4l2_ctrl_config vivid_ctrl_osd_mode
= {
554 .ops
= &vivid_vid_cap_ctrl_ops
,
555 .id
= VIVID_CID_OSD_TEXT_MODE
,
556 .name
= "OSD Text Mode",
557 .type
= V4L2_CTRL_TYPE_MENU
,
558 .max
= ARRAY_SIZE(vivid_ctrl_osd_mode_strings
) - 2,
559 .qmenu
= vivid_ctrl_osd_mode_strings
,
562 static const struct v4l2_ctrl_config vivid_ctrl_perc_fill
= {
563 .ops
= &vivid_vid_cap_ctrl_ops
,
564 .id
= VIVID_CID_PERCENTAGE_FILL
,
565 .name
= "Fill Percentage of Frame",
566 .type
= V4L2_CTRL_TYPE_INTEGER
,
573 static const struct v4l2_ctrl_config vivid_ctrl_insert_sav
= {
574 .ops
= &vivid_vid_cap_ctrl_ops
,
575 .id
= VIVID_CID_INSERT_SAV
,
576 .name
= "Insert SAV Code in Image",
577 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
582 static const struct v4l2_ctrl_config vivid_ctrl_insert_eav
= {
583 .ops
= &vivid_vid_cap_ctrl_ops
,
584 .id
= VIVID_CID_INSERT_EAV
,
585 .name
= "Insert EAV Code in Image",
586 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
591 static const struct v4l2_ctrl_config vivid_ctrl_hflip
= {
592 .ops
= &vivid_vid_cap_ctrl_ops
,
593 .id
= VIVID_CID_HFLIP
,
594 .name
= "Sensor Flipped Horizontally",
595 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
600 static const struct v4l2_ctrl_config vivid_ctrl_vflip
= {
601 .ops
= &vivid_vid_cap_ctrl_ops
,
602 .id
= VIVID_CID_VFLIP
,
603 .name
= "Sensor Flipped Vertically",
604 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
609 static const struct v4l2_ctrl_config vivid_ctrl_reduced_fps
= {
610 .ops
= &vivid_vid_cap_ctrl_ops
,
611 .id
= VIVID_CID_REDUCED_FPS
,
612 .name
= "Reduced Framerate",
613 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
618 static const struct v4l2_ctrl_config vivid_ctrl_has_crop_cap
= {
619 .ops
= &vivid_vid_cap_ctrl_ops
,
620 .id
= VIVID_CID_HAS_CROP_CAP
,
621 .name
= "Enable Capture Cropping",
622 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
628 static const struct v4l2_ctrl_config vivid_ctrl_has_compose_cap
= {
629 .ops
= &vivid_vid_cap_ctrl_ops
,
630 .id
= VIVID_CID_HAS_COMPOSE_CAP
,
631 .name
= "Enable Capture Composing",
632 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
638 static const struct v4l2_ctrl_config vivid_ctrl_has_scaler_cap
= {
639 .ops
= &vivid_vid_cap_ctrl_ops
,
640 .id
= VIVID_CID_HAS_SCALER_CAP
,
641 .name
= "Enable Capture Scaler",
642 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
648 static const char * const vivid_ctrl_tstamp_src_strings
[] = {
654 static const struct v4l2_ctrl_config vivid_ctrl_tstamp_src
= {
655 .ops
= &vivid_vid_cap_ctrl_ops
,
656 .id
= VIVID_CID_TSTAMP_SRC
,
657 .name
= "Timestamp Source",
658 .type
= V4L2_CTRL_TYPE_MENU
,
659 .max
= ARRAY_SIZE(vivid_ctrl_tstamp_src_strings
) - 2,
660 .qmenu
= vivid_ctrl_tstamp_src_strings
,
663 static const struct v4l2_ctrl_config vivid_ctrl_std_aspect_ratio
= {
664 .ops
= &vivid_vid_cap_ctrl_ops
,
665 .id
= VIVID_CID_STD_ASPECT_RATIO
,
666 .name
= "Standard Aspect Ratio",
667 .type
= V4L2_CTRL_TYPE_MENU
,
671 .qmenu
= tpg_aspect_strings
,
674 static const char * const vivid_ctrl_dv_timings_signal_mode_strings
[] = {
675 "Current DV Timings",
679 "Selected DV Timings",
680 "Cycle Through All DV Timings",
685 static const struct v4l2_ctrl_config vivid_ctrl_dv_timings_signal_mode
= {
686 .ops
= &vivid_vid_cap_ctrl_ops
,
687 .id
= VIVID_CID_DV_TIMINGS_SIGNAL_MODE
,
688 .name
= "DV Timings Signal Mode",
689 .type
= V4L2_CTRL_TYPE_MENU
,
691 .qmenu
= vivid_ctrl_dv_timings_signal_mode_strings
,
694 static const struct v4l2_ctrl_config vivid_ctrl_dv_timings_aspect_ratio
= {
695 .ops
= &vivid_vid_cap_ctrl_ops
,
696 .id
= VIVID_CID_DV_TIMINGS_ASPECT_RATIO
,
697 .name
= "DV Timings Aspect Ratio",
698 .type
= V4L2_CTRL_TYPE_MENU
,
700 .qmenu
= tpg_aspect_strings
,
703 static const struct v4l2_ctrl_config vivid_ctrl_max_edid_blocks
= {
704 .ops
= &vivid_vid_cap_ctrl_ops
,
705 .id
= VIVID_CID_MAX_EDID_BLOCKS
,
706 .name
= "Maximum EDID Blocks",
707 .type
= V4L2_CTRL_TYPE_INTEGER
,
714 static const char * const vivid_ctrl_colorspace_strings
[] = {
727 static const struct v4l2_ctrl_config vivid_ctrl_colorspace
= {
728 .ops
= &vivid_vid_cap_ctrl_ops
,
729 .id
= VIVID_CID_COLORSPACE
,
730 .name
= "Colorspace",
731 .type
= V4L2_CTRL_TYPE_MENU
,
732 .max
= ARRAY_SIZE(vivid_ctrl_colorspace_strings
) - 2,
734 .qmenu
= vivid_ctrl_colorspace_strings
,
737 static const char * const vivid_ctrl_xfer_func_strings
[] = {
749 static const struct v4l2_ctrl_config vivid_ctrl_xfer_func
= {
750 .ops
= &vivid_vid_cap_ctrl_ops
,
751 .id
= VIVID_CID_XFER_FUNC
,
752 .name
= "Transfer Function",
753 .type
= V4L2_CTRL_TYPE_MENU
,
754 .max
= ARRAY_SIZE(vivid_ctrl_xfer_func_strings
) - 2,
755 .qmenu
= vivid_ctrl_xfer_func_strings
,
758 static const char * const vivid_ctrl_ycbcr_enc_strings
[] = {
766 "BT.2020 Constant Luminance",
771 static const struct v4l2_ctrl_config vivid_ctrl_ycbcr_enc
= {
772 .ops
= &vivid_vid_cap_ctrl_ops
,
773 .id
= VIVID_CID_YCBCR_ENC
,
774 .name
= "Y'CbCr Encoding",
775 .type
= V4L2_CTRL_TYPE_MENU
,
776 .menu_skip_mask
= 1 << 5,
777 .max
= ARRAY_SIZE(vivid_ctrl_ycbcr_enc_strings
) - 2,
778 .qmenu
= vivid_ctrl_ycbcr_enc_strings
,
781 static const char * const vivid_ctrl_quantization_strings
[] = {
788 static const struct v4l2_ctrl_config vivid_ctrl_quantization
= {
789 .ops
= &vivid_vid_cap_ctrl_ops
,
790 .id
= VIVID_CID_QUANTIZATION
,
791 .name
= "Quantization",
792 .type
= V4L2_CTRL_TYPE_MENU
,
793 .max
= ARRAY_SIZE(vivid_ctrl_quantization_strings
) - 2,
794 .qmenu
= vivid_ctrl_quantization_strings
,
797 static const struct v4l2_ctrl_config vivid_ctrl_alpha_mode
= {
798 .ops
= &vivid_vid_cap_ctrl_ops
,
799 .id
= VIVID_CID_ALPHA_MODE
,
800 .name
= "Apply Alpha To Red Only",
801 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
806 static const struct v4l2_ctrl_config vivid_ctrl_limited_rgb_range
= {
807 .ops
= &vivid_vid_cap_ctrl_ops
,
808 .id
= VIVID_CID_LIMITED_RGB_RANGE
,
809 .name
= "Limited RGB Range (16-235)",
810 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
816 /* Video Loop Control */
818 static int vivid_loop_cap_s_ctrl(struct v4l2_ctrl
*ctrl
)
820 struct vivid_dev
*dev
= container_of(ctrl
->handler
, struct vivid_dev
, ctrl_hdl_loop_cap
);
823 case VIVID_CID_LOOP_VIDEO
:
824 dev
->loop_video
= ctrl
->val
;
825 vivid_update_quality(dev
);
826 vivid_send_source_change(dev
, SVID
);
827 vivid_send_source_change(dev
, HDMI
);
833 static const struct v4l2_ctrl_ops vivid_loop_cap_ctrl_ops
= {
834 .s_ctrl
= vivid_loop_cap_s_ctrl
,
837 static const struct v4l2_ctrl_config vivid_ctrl_loop_video
= {
838 .ops
= &vivid_loop_cap_ctrl_ops
,
839 .id
= VIVID_CID_LOOP_VIDEO
,
840 .name
= "Loop Video",
841 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
847 /* VBI Capture Control */
849 static int vivid_vbi_cap_s_ctrl(struct v4l2_ctrl
*ctrl
)
851 struct vivid_dev
*dev
= container_of(ctrl
->handler
, struct vivid_dev
, ctrl_hdl_vbi_cap
);
854 case VIVID_CID_VBI_CAP_INTERLACED
:
855 dev
->vbi_cap_interlaced
= ctrl
->val
;
861 static const struct v4l2_ctrl_ops vivid_vbi_cap_ctrl_ops
= {
862 .s_ctrl
= vivid_vbi_cap_s_ctrl
,
865 static const struct v4l2_ctrl_config vivid_ctrl_vbi_cap_interlaced
= {
866 .ops
= &vivid_vbi_cap_ctrl_ops
,
867 .id
= VIVID_CID_VBI_CAP_INTERLACED
,
868 .name
= "Interlaced VBI Format",
869 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
875 /* Video Output Controls */
877 static int vivid_vid_out_s_ctrl(struct v4l2_ctrl
*ctrl
)
879 struct vivid_dev
*dev
= container_of(ctrl
->handler
, struct vivid_dev
, ctrl_hdl_vid_out
);
880 struct v4l2_bt_timings
*bt
= &dev
->dv_timings_out
.bt
;
883 case VIVID_CID_HAS_CROP_OUT
:
884 dev
->has_crop_out
= ctrl
->val
;
885 vivid_update_format_out(dev
);
887 case VIVID_CID_HAS_COMPOSE_OUT
:
888 dev
->has_compose_out
= ctrl
->val
;
889 vivid_update_format_out(dev
);
891 case VIVID_CID_HAS_SCALER_OUT
:
892 dev
->has_scaler_out
= ctrl
->val
;
893 vivid_update_format_out(dev
);
895 case V4L2_CID_DV_TX_MODE
:
896 dev
->dvi_d_out
= ctrl
->val
== V4L2_DV_TX_MODE_DVI_D
;
897 if (!vivid_is_hdmi_out(dev
))
899 if (!dev
->dvi_d_out
&& (bt
->flags
& V4L2_DV_FL_IS_CE_VIDEO
)) {
900 if (bt
->width
== 720 && bt
->height
<= 576)
901 dev
->colorspace_out
= V4L2_COLORSPACE_SMPTE170M
;
903 dev
->colorspace_out
= V4L2_COLORSPACE_REC709
;
904 dev
->quantization_out
= V4L2_QUANTIZATION_DEFAULT
;
906 dev
->colorspace_out
= V4L2_COLORSPACE_SRGB
;
907 dev
->quantization_out
= dev
->dvi_d_out
?
908 V4L2_QUANTIZATION_LIM_RANGE
:
909 V4L2_QUANTIZATION_DEFAULT
;
912 vivid_send_source_change(dev
, HDMI
);
918 static const struct v4l2_ctrl_ops vivid_vid_out_ctrl_ops
= {
919 .s_ctrl
= vivid_vid_out_s_ctrl
,
922 static const struct v4l2_ctrl_config vivid_ctrl_has_crop_out
= {
923 .ops
= &vivid_vid_out_ctrl_ops
,
924 .id
= VIVID_CID_HAS_CROP_OUT
,
925 .name
= "Enable Output Cropping",
926 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
932 static const struct v4l2_ctrl_config vivid_ctrl_has_compose_out
= {
933 .ops
= &vivid_vid_out_ctrl_ops
,
934 .id
= VIVID_CID_HAS_COMPOSE_OUT
,
935 .name
= "Enable Output Composing",
936 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
942 static const struct v4l2_ctrl_config vivid_ctrl_has_scaler_out
= {
943 .ops
= &vivid_vid_out_ctrl_ops
,
944 .id
= VIVID_CID_HAS_SCALER_OUT
,
945 .name
= "Enable Output Scaler",
946 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
953 /* Streaming Controls */
955 static int vivid_streaming_s_ctrl(struct v4l2_ctrl
*ctrl
)
957 struct vivid_dev
*dev
= container_of(ctrl
->handler
, struct vivid_dev
, ctrl_hdl_streaming
);
961 case VIVID_CID_DQBUF_ERROR
:
962 dev
->dqbuf_error
= true;
964 case VIVID_CID_PERC_DROPPED
:
965 dev
->perc_dropped_buffers
= ctrl
->val
;
967 case VIVID_CID_QUEUE_SETUP_ERROR
:
968 dev
->queue_setup_error
= true;
970 case VIVID_CID_BUF_PREPARE_ERROR
:
971 dev
->buf_prepare_error
= true;
973 case VIVID_CID_START_STR_ERROR
:
974 dev
->start_streaming_error
= true;
976 case VIVID_CID_QUEUE_ERROR
:
977 if (vb2_start_streaming_called(&dev
->vb_vid_cap_q
))
978 vb2_queue_error(&dev
->vb_vid_cap_q
);
979 if (vb2_start_streaming_called(&dev
->vb_vbi_cap_q
))
980 vb2_queue_error(&dev
->vb_vbi_cap_q
);
981 if (vb2_start_streaming_called(&dev
->vb_vid_out_q
))
982 vb2_queue_error(&dev
->vb_vid_out_q
);
983 if (vb2_start_streaming_called(&dev
->vb_vbi_out_q
))
984 vb2_queue_error(&dev
->vb_vbi_out_q
);
985 if (vb2_start_streaming_called(&dev
->vb_sdr_cap_q
))
986 vb2_queue_error(&dev
->vb_sdr_cap_q
);
988 case VIVID_CID_SEQ_WRAP
:
989 dev
->seq_wrap
= ctrl
->val
;
991 case VIVID_CID_TIME_WRAP
:
992 dev
->time_wrap
= ctrl
->val
;
993 if (ctrl
->val
== 0) {
994 dev
->time_wrap_offset
= 0;
998 * We want to set the time 16 seconds before the 32 bit tv_sec
999 * value of struct timeval would wrap around. So first we
1000 * calculate ktime_get_ns() % ((1 << 32) * NSEC_PER_SEC), and
1001 * then we set the offset to ((1 << 32) - 16) * NSEC_PER_SEC).
1003 div64_u64_rem(ktime_get_ns(),
1004 0x100000000ULL
* NSEC_PER_SEC
, &rem
);
1005 dev
->time_wrap_offset
=
1006 (0x100000000ULL
- 16) * NSEC_PER_SEC
- rem
;
1012 static const struct v4l2_ctrl_ops vivid_streaming_ctrl_ops
= {
1013 .s_ctrl
= vivid_streaming_s_ctrl
,
1016 static const struct v4l2_ctrl_config vivid_ctrl_dqbuf_error
= {
1017 .ops
= &vivid_streaming_ctrl_ops
,
1018 .id
= VIVID_CID_DQBUF_ERROR
,
1019 .name
= "Inject V4L2_BUF_FLAG_ERROR",
1020 .type
= V4L2_CTRL_TYPE_BUTTON
,
1023 static const struct v4l2_ctrl_config vivid_ctrl_perc_dropped
= {
1024 .ops
= &vivid_streaming_ctrl_ops
,
1025 .id
= VIVID_CID_PERC_DROPPED
,
1026 .name
= "Percentage of Dropped Buffers",
1027 .type
= V4L2_CTRL_TYPE_INTEGER
,
1033 static const struct v4l2_ctrl_config vivid_ctrl_queue_setup_error
= {
1034 .ops
= &vivid_streaming_ctrl_ops
,
1035 .id
= VIVID_CID_QUEUE_SETUP_ERROR
,
1036 .name
= "Inject VIDIOC_REQBUFS Error",
1037 .type
= V4L2_CTRL_TYPE_BUTTON
,
1040 static const struct v4l2_ctrl_config vivid_ctrl_buf_prepare_error
= {
1041 .ops
= &vivid_streaming_ctrl_ops
,
1042 .id
= VIVID_CID_BUF_PREPARE_ERROR
,
1043 .name
= "Inject VIDIOC_QBUF Error",
1044 .type
= V4L2_CTRL_TYPE_BUTTON
,
1047 static const struct v4l2_ctrl_config vivid_ctrl_start_streaming_error
= {
1048 .ops
= &vivid_streaming_ctrl_ops
,
1049 .id
= VIVID_CID_START_STR_ERROR
,
1050 .name
= "Inject VIDIOC_STREAMON Error",
1051 .type
= V4L2_CTRL_TYPE_BUTTON
,
1054 static const struct v4l2_ctrl_config vivid_ctrl_queue_error
= {
1055 .ops
= &vivid_streaming_ctrl_ops
,
1056 .id
= VIVID_CID_QUEUE_ERROR
,
1057 .name
= "Inject Fatal Streaming Error",
1058 .type
= V4L2_CTRL_TYPE_BUTTON
,
1061 static const struct v4l2_ctrl_config vivid_ctrl_seq_wrap
= {
1062 .ops
= &vivid_streaming_ctrl_ops
,
1063 .id
= VIVID_CID_SEQ_WRAP
,
1064 .name
= "Wrap Sequence Number",
1065 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
1070 static const struct v4l2_ctrl_config vivid_ctrl_time_wrap
= {
1071 .ops
= &vivid_streaming_ctrl_ops
,
1072 .id
= VIVID_CID_TIME_WRAP
,
1073 .name
= "Wrap Timestamp",
1074 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
1080 /* SDTV Capture Controls */
1082 static int vivid_sdtv_cap_s_ctrl(struct v4l2_ctrl
*ctrl
)
1084 struct vivid_dev
*dev
= container_of(ctrl
->handler
, struct vivid_dev
, ctrl_hdl_sdtv_cap
);
1087 case VIVID_CID_STD_SIGNAL_MODE
:
1088 dev
->std_signal_mode
= dev
->ctrl_std_signal_mode
->val
;
1089 if (dev
->std_signal_mode
== SELECTED_STD
)
1090 dev
->query_std
= vivid_standard
[dev
->ctrl_standard
->val
];
1091 v4l2_ctrl_activate(dev
->ctrl_standard
, dev
->std_signal_mode
== SELECTED_STD
);
1092 vivid_update_quality(dev
);
1093 vivid_send_source_change(dev
, TV
);
1094 vivid_send_source_change(dev
, SVID
);
1100 static const struct v4l2_ctrl_ops vivid_sdtv_cap_ctrl_ops
= {
1101 .s_ctrl
= vivid_sdtv_cap_s_ctrl
,
1104 static const char * const vivid_ctrl_std_signal_mode_strings
[] = {
1109 "Selected Standard",
1110 "Cycle Through All Standards",
1114 static const struct v4l2_ctrl_config vivid_ctrl_std_signal_mode
= {
1115 .ops
= &vivid_sdtv_cap_ctrl_ops
,
1116 .id
= VIVID_CID_STD_SIGNAL_MODE
,
1117 .name
= "Standard Signal Mode",
1118 .type
= V4L2_CTRL_TYPE_MENU
,
1119 .max
= ARRAY_SIZE(vivid_ctrl_std_signal_mode_strings
) - 2,
1120 .menu_skip_mask
= 1 << 3,
1121 .qmenu
= vivid_ctrl_std_signal_mode_strings
,
1124 static const struct v4l2_ctrl_config vivid_ctrl_standard
= {
1125 .ops
= &vivid_sdtv_cap_ctrl_ops
,
1126 .id
= VIVID_CID_STANDARD
,
1128 .type
= V4L2_CTRL_TYPE_MENU
,
1130 .qmenu
= vivid_ctrl_standard_strings
,
1135 /* Radio Receiver Controls */
1137 static int vivid_radio_rx_s_ctrl(struct v4l2_ctrl
*ctrl
)
1139 struct vivid_dev
*dev
= container_of(ctrl
->handler
, struct vivid_dev
, ctrl_hdl_radio_rx
);
1142 case VIVID_CID_RADIO_SEEK_MODE
:
1143 dev
->radio_rx_hw_seek_mode
= ctrl
->val
;
1145 case VIVID_CID_RADIO_SEEK_PROG_LIM
:
1146 dev
->radio_rx_hw_seek_prog_lim
= ctrl
->val
;
1148 case VIVID_CID_RADIO_RX_RDS_RBDS
:
1149 dev
->rds_gen
.use_rbds
= ctrl
->val
;
1151 case VIVID_CID_RADIO_RX_RDS_BLOCKIO
:
1152 dev
->radio_rx_rds_controls
= ctrl
->val
;
1153 dev
->radio_rx_caps
&= ~V4L2_CAP_READWRITE
;
1154 dev
->radio_rx_rds_use_alternates
= false;
1155 if (!dev
->radio_rx_rds_controls
) {
1156 dev
->radio_rx_caps
|= V4L2_CAP_READWRITE
;
1157 __v4l2_ctrl_s_ctrl(dev
->radio_rx_rds_pty
, 0);
1158 __v4l2_ctrl_s_ctrl(dev
->radio_rx_rds_ta
, 0);
1159 __v4l2_ctrl_s_ctrl(dev
->radio_rx_rds_tp
, 0);
1160 __v4l2_ctrl_s_ctrl(dev
->radio_rx_rds_ms
, 0);
1161 __v4l2_ctrl_s_ctrl_string(dev
->radio_rx_rds_psname
, "");
1162 __v4l2_ctrl_s_ctrl_string(dev
->radio_rx_rds_radiotext
, "");
1164 v4l2_ctrl_activate(dev
->radio_rx_rds_pty
, dev
->radio_rx_rds_controls
);
1165 v4l2_ctrl_activate(dev
->radio_rx_rds_psname
, dev
->radio_rx_rds_controls
);
1166 v4l2_ctrl_activate(dev
->radio_rx_rds_radiotext
, dev
->radio_rx_rds_controls
);
1167 v4l2_ctrl_activate(dev
->radio_rx_rds_ta
, dev
->radio_rx_rds_controls
);
1168 v4l2_ctrl_activate(dev
->radio_rx_rds_tp
, dev
->radio_rx_rds_controls
);
1169 v4l2_ctrl_activate(dev
->radio_rx_rds_ms
, dev
->radio_rx_rds_controls
);
1170 dev
->radio_rx_dev
.device_caps
= dev
->radio_rx_caps
;
1172 case V4L2_CID_RDS_RECEPTION
:
1173 dev
->radio_rx_rds_enabled
= ctrl
->val
;
1179 static const struct v4l2_ctrl_ops vivid_radio_rx_ctrl_ops
= {
1180 .s_ctrl
= vivid_radio_rx_s_ctrl
,
1183 static const char * const vivid_ctrl_radio_rds_mode_strings
[] = {
1189 static const struct v4l2_ctrl_config vivid_ctrl_radio_rx_rds_blockio
= {
1190 .ops
= &vivid_radio_rx_ctrl_ops
,
1191 .id
= VIVID_CID_RADIO_RX_RDS_BLOCKIO
,
1192 .name
= "RDS Rx I/O Mode",
1193 .type
= V4L2_CTRL_TYPE_MENU
,
1194 .qmenu
= vivid_ctrl_radio_rds_mode_strings
,
1198 static const struct v4l2_ctrl_config vivid_ctrl_radio_rx_rds_rbds
= {
1199 .ops
= &vivid_radio_rx_ctrl_ops
,
1200 .id
= VIVID_CID_RADIO_RX_RDS_RBDS
,
1201 .name
= "Generate RBDS Instead of RDS",
1202 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
1207 static const char * const vivid_ctrl_radio_hw_seek_mode_strings
[] = {
1214 static const struct v4l2_ctrl_config vivid_ctrl_radio_hw_seek_mode
= {
1215 .ops
= &vivid_radio_rx_ctrl_ops
,
1216 .id
= VIVID_CID_RADIO_SEEK_MODE
,
1217 .name
= "Radio HW Seek Mode",
1218 .type
= V4L2_CTRL_TYPE_MENU
,
1220 .qmenu
= vivid_ctrl_radio_hw_seek_mode_strings
,
1223 static const struct v4l2_ctrl_config vivid_ctrl_radio_hw_seek_prog_lim
= {
1224 .ops
= &vivid_radio_rx_ctrl_ops
,
1225 .id
= VIVID_CID_RADIO_SEEK_PROG_LIM
,
1226 .name
= "Radio Programmable HW Seek",
1227 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
1233 /* Radio Transmitter Controls */
1235 static int vivid_radio_tx_s_ctrl(struct v4l2_ctrl
*ctrl
)
1237 struct vivid_dev
*dev
= container_of(ctrl
->handler
, struct vivid_dev
, ctrl_hdl_radio_tx
);
1240 case VIVID_CID_RADIO_TX_RDS_BLOCKIO
:
1241 dev
->radio_tx_rds_controls
= ctrl
->val
;
1242 dev
->radio_tx_caps
&= ~V4L2_CAP_READWRITE
;
1243 if (!dev
->radio_tx_rds_controls
)
1244 dev
->radio_tx_caps
|= V4L2_CAP_READWRITE
;
1245 dev
->radio_tx_dev
.device_caps
= dev
->radio_tx_caps
;
1247 case V4L2_CID_RDS_TX_PTY
:
1248 if (dev
->radio_rx_rds_controls
)
1249 v4l2_ctrl_s_ctrl(dev
->radio_rx_rds_pty
, ctrl
->val
);
1251 case V4L2_CID_RDS_TX_PS_NAME
:
1252 if (dev
->radio_rx_rds_controls
)
1253 v4l2_ctrl_s_ctrl_string(dev
->radio_rx_rds_psname
, ctrl
->p_new
.p_char
);
1255 case V4L2_CID_RDS_TX_RADIO_TEXT
:
1256 if (dev
->radio_rx_rds_controls
)
1257 v4l2_ctrl_s_ctrl_string(dev
->radio_rx_rds_radiotext
, ctrl
->p_new
.p_char
);
1259 case V4L2_CID_RDS_TX_TRAFFIC_ANNOUNCEMENT
:
1260 if (dev
->radio_rx_rds_controls
)
1261 v4l2_ctrl_s_ctrl(dev
->radio_rx_rds_ta
, ctrl
->val
);
1263 case V4L2_CID_RDS_TX_TRAFFIC_PROGRAM
:
1264 if (dev
->radio_rx_rds_controls
)
1265 v4l2_ctrl_s_ctrl(dev
->radio_rx_rds_tp
, ctrl
->val
);
1267 case V4L2_CID_RDS_TX_MUSIC_SPEECH
:
1268 if (dev
->radio_rx_rds_controls
)
1269 v4l2_ctrl_s_ctrl(dev
->radio_rx_rds_ms
, ctrl
->val
);
1275 static const struct v4l2_ctrl_ops vivid_radio_tx_ctrl_ops
= {
1276 .s_ctrl
= vivid_radio_tx_s_ctrl
,
1279 static const struct v4l2_ctrl_config vivid_ctrl_radio_tx_rds_blockio
= {
1280 .ops
= &vivid_radio_tx_ctrl_ops
,
1281 .id
= VIVID_CID_RADIO_TX_RDS_BLOCKIO
,
1282 .name
= "RDS Tx I/O Mode",
1283 .type
= V4L2_CTRL_TYPE_MENU
,
1284 .qmenu
= vivid_ctrl_radio_rds_mode_strings
,
1290 /* SDR Capture Controls */
1292 static int vivid_sdr_cap_s_ctrl(struct v4l2_ctrl
*ctrl
)
1294 struct vivid_dev
*dev
= container_of(ctrl
->handler
, struct vivid_dev
, ctrl_hdl_sdr_cap
);
1297 case VIVID_CID_SDR_CAP_FM_DEVIATION
:
1298 dev
->sdr_fm_deviation
= ctrl
->val
;
1304 static const struct v4l2_ctrl_ops vivid_sdr_cap_ctrl_ops
= {
1305 .s_ctrl
= vivid_sdr_cap_s_ctrl
,
1308 static const struct v4l2_ctrl_config vivid_ctrl_sdr_cap_fm_deviation
= {
1309 .ops
= &vivid_sdr_cap_ctrl_ops
,
1310 .id
= VIVID_CID_SDR_CAP_FM_DEVIATION
,
1311 .name
= "FM Deviation",
1312 .type
= V4L2_CTRL_TYPE_INTEGER
,
1320 static const struct v4l2_ctrl_config vivid_ctrl_class
= {
1321 .ops
= &vivid_user_gen_ctrl_ops
,
1322 .flags
= V4L2_CTRL_FLAG_READ_ONLY
| V4L2_CTRL_FLAG_WRITE_ONLY
,
1323 .id
= VIVID_CID_VIVID_CLASS
,
1324 .name
= "Vivid Controls",
1325 .type
= V4L2_CTRL_TYPE_CTRL_CLASS
,
1328 int vivid_create_controls(struct vivid_dev
*dev
, bool show_ccs_cap
,
1329 bool show_ccs_out
, bool no_error_inj
,
1330 bool has_sdtv
, bool has_hdmi
)
1332 struct v4l2_ctrl_handler
*hdl_user_gen
= &dev
->ctrl_hdl_user_gen
;
1333 struct v4l2_ctrl_handler
*hdl_user_vid
= &dev
->ctrl_hdl_user_vid
;
1334 struct v4l2_ctrl_handler
*hdl_user_aud
= &dev
->ctrl_hdl_user_aud
;
1335 struct v4l2_ctrl_handler
*hdl_streaming
= &dev
->ctrl_hdl_streaming
;
1336 struct v4l2_ctrl_handler
*hdl_sdtv_cap
= &dev
->ctrl_hdl_sdtv_cap
;
1337 struct v4l2_ctrl_handler
*hdl_loop_cap
= &dev
->ctrl_hdl_loop_cap
;
1338 struct v4l2_ctrl_handler
*hdl_vid_cap
= &dev
->ctrl_hdl_vid_cap
;
1339 struct v4l2_ctrl_handler
*hdl_vid_out
= &dev
->ctrl_hdl_vid_out
;
1340 struct v4l2_ctrl_handler
*hdl_vbi_cap
= &dev
->ctrl_hdl_vbi_cap
;
1341 struct v4l2_ctrl_handler
*hdl_vbi_out
= &dev
->ctrl_hdl_vbi_out
;
1342 struct v4l2_ctrl_handler
*hdl_radio_rx
= &dev
->ctrl_hdl_radio_rx
;
1343 struct v4l2_ctrl_handler
*hdl_radio_tx
= &dev
->ctrl_hdl_radio_tx
;
1344 struct v4l2_ctrl_handler
*hdl_sdr_cap
= &dev
->ctrl_hdl_sdr_cap
;
1345 struct v4l2_ctrl_config vivid_ctrl_dv_timings
= {
1346 .ops
= &vivid_vid_cap_ctrl_ops
,
1347 .id
= VIVID_CID_DV_TIMINGS
,
1348 .name
= "DV Timings",
1349 .type
= V4L2_CTRL_TYPE_MENU
,
1353 v4l2_ctrl_handler_init(hdl_user_gen
, 10);
1354 v4l2_ctrl_new_custom(hdl_user_gen
, &vivid_ctrl_class
, NULL
);
1355 v4l2_ctrl_handler_init(hdl_user_vid
, 9);
1356 v4l2_ctrl_new_custom(hdl_user_vid
, &vivid_ctrl_class
, NULL
);
1357 v4l2_ctrl_handler_init(hdl_user_aud
, 2);
1358 v4l2_ctrl_new_custom(hdl_user_aud
, &vivid_ctrl_class
, NULL
);
1359 v4l2_ctrl_handler_init(hdl_streaming
, 8);
1360 v4l2_ctrl_new_custom(hdl_streaming
, &vivid_ctrl_class
, NULL
);
1361 v4l2_ctrl_handler_init(hdl_sdtv_cap
, 2);
1362 v4l2_ctrl_new_custom(hdl_sdtv_cap
, &vivid_ctrl_class
, NULL
);
1363 v4l2_ctrl_handler_init(hdl_loop_cap
, 1);
1364 v4l2_ctrl_new_custom(hdl_loop_cap
, &vivid_ctrl_class
, NULL
);
1365 v4l2_ctrl_handler_init(hdl_vid_cap
, 55);
1366 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_class
, NULL
);
1367 v4l2_ctrl_handler_init(hdl_vid_out
, 26);
1369 v4l2_ctrl_new_custom(hdl_vid_out
, &vivid_ctrl_class
, NULL
);
1370 v4l2_ctrl_handler_init(hdl_vbi_cap
, 21);
1371 v4l2_ctrl_new_custom(hdl_vbi_cap
, &vivid_ctrl_class
, NULL
);
1372 v4l2_ctrl_handler_init(hdl_vbi_out
, 19);
1374 v4l2_ctrl_new_custom(hdl_vbi_out
, &vivid_ctrl_class
, NULL
);
1375 v4l2_ctrl_handler_init(hdl_radio_rx
, 17);
1376 v4l2_ctrl_new_custom(hdl_radio_rx
, &vivid_ctrl_class
, NULL
);
1377 v4l2_ctrl_handler_init(hdl_radio_tx
, 17);
1378 v4l2_ctrl_new_custom(hdl_radio_tx
, &vivid_ctrl_class
, NULL
);
1379 v4l2_ctrl_handler_init(hdl_sdr_cap
, 19);
1380 v4l2_ctrl_new_custom(hdl_sdr_cap
, &vivid_ctrl_class
, NULL
);
1383 dev
->volume
= v4l2_ctrl_new_std(hdl_user_aud
, NULL
,
1384 V4L2_CID_AUDIO_VOLUME
, 0, 255, 1, 200);
1385 dev
->mute
= v4l2_ctrl_new_std(hdl_user_aud
, NULL
,
1386 V4L2_CID_AUDIO_MUTE
, 0, 1, 1, 0);
1387 if (dev
->has_vid_cap
) {
1388 dev
->brightness
= v4l2_ctrl_new_std(hdl_user_vid
, &vivid_user_vid_ctrl_ops
,
1389 V4L2_CID_BRIGHTNESS
, 0, 255, 1, 128);
1390 for (i
= 0; i
< MAX_INPUTS
; i
++)
1391 dev
->input_brightness
[i
] = 128;
1392 dev
->contrast
= v4l2_ctrl_new_std(hdl_user_vid
, &vivid_user_vid_ctrl_ops
,
1393 V4L2_CID_CONTRAST
, 0, 255, 1, 128);
1394 dev
->saturation
= v4l2_ctrl_new_std(hdl_user_vid
, &vivid_user_vid_ctrl_ops
,
1395 V4L2_CID_SATURATION
, 0, 255, 1, 128);
1396 dev
->hue
= v4l2_ctrl_new_std(hdl_user_vid
, &vivid_user_vid_ctrl_ops
,
1397 V4L2_CID_HUE
, -128, 128, 1, 0);
1398 v4l2_ctrl_new_std(hdl_user_vid
, &vivid_user_vid_ctrl_ops
,
1399 V4L2_CID_HFLIP
, 0, 1, 1, 0);
1400 v4l2_ctrl_new_std(hdl_user_vid
, &vivid_user_vid_ctrl_ops
,
1401 V4L2_CID_VFLIP
, 0, 1, 1, 0);
1402 dev
->autogain
= v4l2_ctrl_new_std(hdl_user_vid
, &vivid_user_vid_ctrl_ops
,
1403 V4L2_CID_AUTOGAIN
, 0, 1, 1, 1);
1404 dev
->gain
= v4l2_ctrl_new_std(hdl_user_vid
, &vivid_user_vid_ctrl_ops
,
1405 V4L2_CID_GAIN
, 0, 255, 1, 100);
1406 dev
->alpha
= v4l2_ctrl_new_std(hdl_user_vid
, &vivid_user_vid_ctrl_ops
,
1407 V4L2_CID_ALPHA_COMPONENT
, 0, 255, 1, 0);
1409 dev
->button
= v4l2_ctrl_new_custom(hdl_user_gen
, &vivid_ctrl_button
, NULL
);
1410 dev
->int32
= v4l2_ctrl_new_custom(hdl_user_gen
, &vivid_ctrl_int32
, NULL
);
1411 dev
->int64
= v4l2_ctrl_new_custom(hdl_user_gen
, &vivid_ctrl_int64
, NULL
);
1412 dev
->boolean
= v4l2_ctrl_new_custom(hdl_user_gen
, &vivid_ctrl_boolean
, NULL
);
1413 dev
->menu
= v4l2_ctrl_new_custom(hdl_user_gen
, &vivid_ctrl_menu
, NULL
);
1414 dev
->string
= v4l2_ctrl_new_custom(hdl_user_gen
, &vivid_ctrl_string
, NULL
);
1415 dev
->bitmask
= v4l2_ctrl_new_custom(hdl_user_gen
, &vivid_ctrl_bitmask
, NULL
);
1416 dev
->int_menu
= v4l2_ctrl_new_custom(hdl_user_gen
, &vivid_ctrl_int_menu
, NULL
);
1417 v4l2_ctrl_new_custom(hdl_user_gen
, &vivid_ctrl_u32_array
, NULL
);
1418 v4l2_ctrl_new_custom(hdl_user_gen
, &vivid_ctrl_u16_matrix
, NULL
);
1419 v4l2_ctrl_new_custom(hdl_user_gen
, &vivid_ctrl_u8_4d_array
, NULL
);
1421 if (dev
->has_vid_cap
) {
1422 /* Image Processing Controls */
1423 struct v4l2_ctrl_config vivid_ctrl_test_pattern
= {
1424 .ops
= &vivid_vid_cap_ctrl_ops
,
1425 .id
= VIVID_CID_TEST_PATTERN
,
1426 .name
= "Test Pattern",
1427 .type
= V4L2_CTRL_TYPE_MENU
,
1428 .max
= TPG_PAT_NOISE
,
1429 .qmenu
= tpg_pattern_strings
,
1432 dev
->test_pattern
= v4l2_ctrl_new_custom(hdl_vid_cap
,
1433 &vivid_ctrl_test_pattern
, NULL
);
1434 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_perc_fill
, NULL
);
1435 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_hor_movement
, NULL
);
1436 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_vert_movement
, NULL
);
1437 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_osd_mode
, NULL
);
1438 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_show_border
, NULL
);
1439 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_show_square
, NULL
);
1440 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_hflip
, NULL
);
1441 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_vflip
, NULL
);
1442 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_insert_sav
, NULL
);
1443 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_insert_eav
, NULL
);
1444 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_reduced_fps
, NULL
);
1446 dev
->ctrl_has_crop_cap
= v4l2_ctrl_new_custom(hdl_vid_cap
,
1447 &vivid_ctrl_has_crop_cap
, NULL
);
1448 dev
->ctrl_has_compose_cap
= v4l2_ctrl_new_custom(hdl_vid_cap
,
1449 &vivid_ctrl_has_compose_cap
, NULL
);
1450 dev
->ctrl_has_scaler_cap
= v4l2_ctrl_new_custom(hdl_vid_cap
,
1451 &vivid_ctrl_has_scaler_cap
, NULL
);
1454 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_tstamp_src
, NULL
);
1455 dev
->colorspace
= v4l2_ctrl_new_custom(hdl_vid_cap
,
1456 &vivid_ctrl_colorspace
, NULL
);
1457 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_xfer_func
, NULL
);
1458 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_ycbcr_enc
, NULL
);
1459 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_quantization
, NULL
);
1460 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_alpha_mode
, NULL
);
1463 if (dev
->has_vid_out
&& show_ccs_out
) {
1464 dev
->ctrl_has_crop_out
= v4l2_ctrl_new_custom(hdl_vid_out
,
1465 &vivid_ctrl_has_crop_out
, NULL
);
1466 dev
->ctrl_has_compose_out
= v4l2_ctrl_new_custom(hdl_vid_out
,
1467 &vivid_ctrl_has_compose_out
, NULL
);
1468 dev
->ctrl_has_scaler_out
= v4l2_ctrl_new_custom(hdl_vid_out
,
1469 &vivid_ctrl_has_scaler_out
, NULL
);
1473 * Testing this driver with v4l2-compliance will trigger the error
1474 * injection controls, and after that nothing will work as expected.
1475 * So we have a module option to drop these error injecting controls
1476 * allowing us to run v4l2_compliance again.
1478 if (!no_error_inj
) {
1479 v4l2_ctrl_new_custom(hdl_user_gen
, &vivid_ctrl_disconnect
, NULL
);
1480 v4l2_ctrl_new_custom(hdl_streaming
, &vivid_ctrl_dqbuf_error
, NULL
);
1481 v4l2_ctrl_new_custom(hdl_streaming
, &vivid_ctrl_perc_dropped
, NULL
);
1482 v4l2_ctrl_new_custom(hdl_streaming
, &vivid_ctrl_queue_setup_error
, NULL
);
1483 v4l2_ctrl_new_custom(hdl_streaming
, &vivid_ctrl_buf_prepare_error
, NULL
);
1484 v4l2_ctrl_new_custom(hdl_streaming
, &vivid_ctrl_start_streaming_error
, NULL
);
1485 v4l2_ctrl_new_custom(hdl_streaming
, &vivid_ctrl_queue_error
, NULL
);
1486 v4l2_ctrl_new_custom(hdl_streaming
, &vivid_ctrl_seq_wrap
, NULL
);
1487 v4l2_ctrl_new_custom(hdl_streaming
, &vivid_ctrl_time_wrap
, NULL
);
1490 if (has_sdtv
&& (dev
->has_vid_cap
|| dev
->has_vbi_cap
)) {
1491 if (dev
->has_vid_cap
)
1492 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_std_aspect_ratio
, NULL
);
1493 dev
->ctrl_std_signal_mode
= v4l2_ctrl_new_custom(hdl_sdtv_cap
,
1494 &vivid_ctrl_std_signal_mode
, NULL
);
1495 dev
->ctrl_standard
= v4l2_ctrl_new_custom(hdl_sdtv_cap
,
1496 &vivid_ctrl_standard
, NULL
);
1497 if (dev
->ctrl_std_signal_mode
)
1498 v4l2_ctrl_cluster(2, &dev
->ctrl_std_signal_mode
);
1499 if (dev
->has_raw_vbi_cap
)
1500 v4l2_ctrl_new_custom(hdl_vbi_cap
, &vivid_ctrl_vbi_cap_interlaced
, NULL
);
1503 if (has_hdmi
&& dev
->has_vid_cap
) {
1504 dev
->ctrl_dv_timings_signal_mode
= v4l2_ctrl_new_custom(hdl_vid_cap
,
1505 &vivid_ctrl_dv_timings_signal_mode
, NULL
);
1507 vivid_ctrl_dv_timings
.max
= dev
->query_dv_timings_size
- 1;
1508 vivid_ctrl_dv_timings
.qmenu
=
1509 (const char * const *)dev
->query_dv_timings_qmenu
;
1510 dev
->ctrl_dv_timings
= v4l2_ctrl_new_custom(hdl_vid_cap
,
1511 &vivid_ctrl_dv_timings
, NULL
);
1512 if (dev
->ctrl_dv_timings_signal_mode
)
1513 v4l2_ctrl_cluster(2, &dev
->ctrl_dv_timings_signal_mode
);
1515 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_dv_timings_aspect_ratio
, NULL
);
1516 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_max_edid_blocks
, NULL
);
1517 dev
->real_rgb_range_cap
= v4l2_ctrl_new_custom(hdl_vid_cap
,
1518 &vivid_ctrl_limited_rgb_range
, NULL
);
1519 dev
->rgb_range_cap
= v4l2_ctrl_new_std_menu(hdl_vid_cap
,
1520 &vivid_vid_cap_ctrl_ops
,
1521 V4L2_CID_DV_RX_RGB_RANGE
, V4L2_DV_RGB_RANGE_FULL
,
1522 0, V4L2_DV_RGB_RANGE_AUTO
);
1524 if (has_hdmi
&& dev
->has_vid_out
) {
1526 * We aren't doing anything with this at the moment, but
1527 * HDMI outputs typically have this controls.
1529 dev
->ctrl_tx_rgb_range
= v4l2_ctrl_new_std_menu(hdl_vid_out
, NULL
,
1530 V4L2_CID_DV_TX_RGB_RANGE
, V4L2_DV_RGB_RANGE_FULL
,
1531 0, V4L2_DV_RGB_RANGE_AUTO
);
1532 dev
->ctrl_tx_mode
= v4l2_ctrl_new_std_menu(hdl_vid_out
, NULL
,
1533 V4L2_CID_DV_TX_MODE
, V4L2_DV_TX_MODE_HDMI
,
1534 0, V4L2_DV_TX_MODE_HDMI
);
1536 if ((dev
->has_vid_cap
&& dev
->has_vid_out
) ||
1537 (dev
->has_vbi_cap
&& dev
->has_vbi_out
))
1538 v4l2_ctrl_new_custom(hdl_loop_cap
, &vivid_ctrl_loop_video
, NULL
);
1541 v4l2_ctrl_new_custom(hdl_user_gen
, &vivid_ctrl_clear_fb
, NULL
);
1543 if (dev
->has_radio_rx
) {
1544 v4l2_ctrl_new_custom(hdl_radio_rx
, &vivid_ctrl_radio_hw_seek_mode
, NULL
);
1545 v4l2_ctrl_new_custom(hdl_radio_rx
, &vivid_ctrl_radio_hw_seek_prog_lim
, NULL
);
1546 v4l2_ctrl_new_custom(hdl_radio_rx
, &vivid_ctrl_radio_rx_rds_blockio
, NULL
);
1547 v4l2_ctrl_new_custom(hdl_radio_rx
, &vivid_ctrl_radio_rx_rds_rbds
, NULL
);
1548 v4l2_ctrl_new_std(hdl_radio_rx
, &vivid_radio_rx_ctrl_ops
,
1549 V4L2_CID_RDS_RECEPTION
, 0, 1, 1, 1);
1550 dev
->radio_rx_rds_pty
= v4l2_ctrl_new_std(hdl_radio_rx
,
1551 &vivid_radio_rx_ctrl_ops
,
1552 V4L2_CID_RDS_RX_PTY
, 0, 31, 1, 0);
1553 dev
->radio_rx_rds_psname
= v4l2_ctrl_new_std(hdl_radio_rx
,
1554 &vivid_radio_rx_ctrl_ops
,
1555 V4L2_CID_RDS_RX_PS_NAME
, 0, 8, 8, 0);
1556 dev
->radio_rx_rds_radiotext
= v4l2_ctrl_new_std(hdl_radio_rx
,
1557 &vivid_radio_rx_ctrl_ops
,
1558 V4L2_CID_RDS_RX_RADIO_TEXT
, 0, 64, 64, 0);
1559 dev
->radio_rx_rds_ta
= v4l2_ctrl_new_std(hdl_radio_rx
,
1560 &vivid_radio_rx_ctrl_ops
,
1561 V4L2_CID_RDS_RX_TRAFFIC_ANNOUNCEMENT
, 0, 1, 1, 0);
1562 dev
->radio_rx_rds_tp
= v4l2_ctrl_new_std(hdl_radio_rx
,
1563 &vivid_radio_rx_ctrl_ops
,
1564 V4L2_CID_RDS_RX_TRAFFIC_PROGRAM
, 0, 1, 1, 0);
1565 dev
->radio_rx_rds_ms
= v4l2_ctrl_new_std(hdl_radio_rx
,
1566 &vivid_radio_rx_ctrl_ops
,
1567 V4L2_CID_RDS_RX_MUSIC_SPEECH
, 0, 1, 1, 1);
1569 if (dev
->has_radio_tx
) {
1570 v4l2_ctrl_new_custom(hdl_radio_tx
,
1571 &vivid_ctrl_radio_tx_rds_blockio
, NULL
);
1572 dev
->radio_tx_rds_pi
= v4l2_ctrl_new_std(hdl_radio_tx
,
1573 &vivid_radio_tx_ctrl_ops
,
1574 V4L2_CID_RDS_TX_PI
, 0, 0xffff, 1, 0x8088);
1575 dev
->radio_tx_rds_pty
= v4l2_ctrl_new_std(hdl_radio_tx
,
1576 &vivid_radio_tx_ctrl_ops
,
1577 V4L2_CID_RDS_TX_PTY
, 0, 31, 1, 3);
1578 dev
->radio_tx_rds_psname
= v4l2_ctrl_new_std(hdl_radio_tx
,
1579 &vivid_radio_tx_ctrl_ops
,
1580 V4L2_CID_RDS_TX_PS_NAME
, 0, 8, 8, 0);
1581 if (dev
->radio_tx_rds_psname
)
1582 v4l2_ctrl_s_ctrl_string(dev
->radio_tx_rds_psname
, "VIVID-TX");
1583 dev
->radio_tx_rds_radiotext
= v4l2_ctrl_new_std(hdl_radio_tx
,
1584 &vivid_radio_tx_ctrl_ops
,
1585 V4L2_CID_RDS_TX_RADIO_TEXT
, 0, 64 * 2, 64, 0);
1586 if (dev
->radio_tx_rds_radiotext
)
1587 v4l2_ctrl_s_ctrl_string(dev
->radio_tx_rds_radiotext
,
1588 "This is a VIVID default Radio Text template text, change at will");
1589 dev
->radio_tx_rds_mono_stereo
= v4l2_ctrl_new_std(hdl_radio_tx
,
1590 &vivid_radio_tx_ctrl_ops
,
1591 V4L2_CID_RDS_TX_MONO_STEREO
, 0, 1, 1, 1);
1592 dev
->radio_tx_rds_art_head
= v4l2_ctrl_new_std(hdl_radio_tx
,
1593 &vivid_radio_tx_ctrl_ops
,
1594 V4L2_CID_RDS_TX_ARTIFICIAL_HEAD
, 0, 1, 1, 0);
1595 dev
->radio_tx_rds_compressed
= v4l2_ctrl_new_std(hdl_radio_tx
,
1596 &vivid_radio_tx_ctrl_ops
,
1597 V4L2_CID_RDS_TX_COMPRESSED
, 0, 1, 1, 0);
1598 dev
->radio_tx_rds_dyn_pty
= v4l2_ctrl_new_std(hdl_radio_tx
,
1599 &vivid_radio_tx_ctrl_ops
,
1600 V4L2_CID_RDS_TX_DYNAMIC_PTY
, 0, 1, 1, 0);
1601 dev
->radio_tx_rds_ta
= v4l2_ctrl_new_std(hdl_radio_tx
,
1602 &vivid_radio_tx_ctrl_ops
,
1603 V4L2_CID_RDS_TX_TRAFFIC_ANNOUNCEMENT
, 0, 1, 1, 0);
1604 dev
->radio_tx_rds_tp
= v4l2_ctrl_new_std(hdl_radio_tx
,
1605 &vivid_radio_tx_ctrl_ops
,
1606 V4L2_CID_RDS_TX_TRAFFIC_PROGRAM
, 0, 1, 1, 1);
1607 dev
->radio_tx_rds_ms
= v4l2_ctrl_new_std(hdl_radio_tx
,
1608 &vivid_radio_tx_ctrl_ops
,
1609 V4L2_CID_RDS_TX_MUSIC_SPEECH
, 0, 1, 1, 1);
1611 if (dev
->has_sdr_cap
) {
1612 v4l2_ctrl_new_custom(hdl_sdr_cap
,
1613 &vivid_ctrl_sdr_cap_fm_deviation
, NULL
);
1615 if (hdl_user_gen
->error
)
1616 return hdl_user_gen
->error
;
1617 if (hdl_user_vid
->error
)
1618 return hdl_user_vid
->error
;
1619 if (hdl_user_aud
->error
)
1620 return hdl_user_aud
->error
;
1621 if (hdl_streaming
->error
)
1622 return hdl_streaming
->error
;
1623 if (hdl_sdr_cap
->error
)
1624 return hdl_sdr_cap
->error
;
1625 if (hdl_loop_cap
->error
)
1626 return hdl_loop_cap
->error
;
1629 v4l2_ctrl_auto_cluster(2, &dev
->autogain
, 0, true);
1631 if (dev
->has_vid_cap
) {
1632 v4l2_ctrl_add_handler(hdl_vid_cap
, hdl_user_gen
, NULL
);
1633 v4l2_ctrl_add_handler(hdl_vid_cap
, hdl_user_vid
, NULL
);
1634 v4l2_ctrl_add_handler(hdl_vid_cap
, hdl_user_aud
, NULL
);
1635 v4l2_ctrl_add_handler(hdl_vid_cap
, hdl_streaming
, NULL
);
1636 v4l2_ctrl_add_handler(hdl_vid_cap
, hdl_sdtv_cap
, NULL
);
1637 v4l2_ctrl_add_handler(hdl_vid_cap
, hdl_loop_cap
, NULL
);
1638 if (hdl_vid_cap
->error
)
1639 return hdl_vid_cap
->error
;
1640 dev
->vid_cap_dev
.ctrl_handler
= hdl_vid_cap
;
1642 if (dev
->has_vid_out
) {
1643 v4l2_ctrl_add_handler(hdl_vid_out
, hdl_user_gen
, NULL
);
1644 v4l2_ctrl_add_handler(hdl_vid_out
, hdl_user_aud
, NULL
);
1645 v4l2_ctrl_add_handler(hdl_vid_out
, hdl_streaming
, NULL
);
1646 if (hdl_vid_out
->error
)
1647 return hdl_vid_out
->error
;
1648 dev
->vid_out_dev
.ctrl_handler
= hdl_vid_out
;
1650 if (dev
->has_vbi_cap
) {
1651 v4l2_ctrl_add_handler(hdl_vbi_cap
, hdl_user_gen
, NULL
);
1652 v4l2_ctrl_add_handler(hdl_vbi_cap
, hdl_streaming
, NULL
);
1653 v4l2_ctrl_add_handler(hdl_vbi_cap
, hdl_sdtv_cap
, NULL
);
1654 v4l2_ctrl_add_handler(hdl_vbi_cap
, hdl_loop_cap
, NULL
);
1655 if (hdl_vbi_cap
->error
)
1656 return hdl_vbi_cap
->error
;
1657 dev
->vbi_cap_dev
.ctrl_handler
= hdl_vbi_cap
;
1659 if (dev
->has_vbi_out
) {
1660 v4l2_ctrl_add_handler(hdl_vbi_out
, hdl_user_gen
, NULL
);
1661 v4l2_ctrl_add_handler(hdl_vbi_out
, hdl_streaming
, NULL
);
1662 if (hdl_vbi_out
->error
)
1663 return hdl_vbi_out
->error
;
1664 dev
->vbi_out_dev
.ctrl_handler
= hdl_vbi_out
;
1666 if (dev
->has_radio_rx
) {
1667 v4l2_ctrl_add_handler(hdl_radio_rx
, hdl_user_gen
, NULL
);
1668 v4l2_ctrl_add_handler(hdl_radio_rx
, hdl_user_aud
, NULL
);
1669 if (hdl_radio_rx
->error
)
1670 return hdl_radio_rx
->error
;
1671 dev
->radio_rx_dev
.ctrl_handler
= hdl_radio_rx
;
1673 if (dev
->has_radio_tx
) {
1674 v4l2_ctrl_add_handler(hdl_radio_tx
, hdl_user_gen
, NULL
);
1675 v4l2_ctrl_add_handler(hdl_radio_tx
, hdl_user_aud
, NULL
);
1676 if (hdl_radio_tx
->error
)
1677 return hdl_radio_tx
->error
;
1678 dev
->radio_tx_dev
.ctrl_handler
= hdl_radio_tx
;
1680 if (dev
->has_sdr_cap
) {
1681 v4l2_ctrl_add_handler(hdl_sdr_cap
, hdl_user_gen
, NULL
);
1682 v4l2_ctrl_add_handler(hdl_sdr_cap
, hdl_streaming
, NULL
);
1683 if (hdl_sdr_cap
->error
)
1684 return hdl_sdr_cap
->error
;
1685 dev
->sdr_cap_dev
.ctrl_handler
= hdl_sdr_cap
;
1690 void vivid_free_controls(struct vivid_dev
*dev
)
1692 v4l2_ctrl_handler_free(&dev
->ctrl_hdl_vid_cap
);
1693 v4l2_ctrl_handler_free(&dev
->ctrl_hdl_vid_out
);
1694 v4l2_ctrl_handler_free(&dev
->ctrl_hdl_vbi_cap
);
1695 v4l2_ctrl_handler_free(&dev
->ctrl_hdl_vbi_out
);
1696 v4l2_ctrl_handler_free(&dev
->ctrl_hdl_radio_rx
);
1697 v4l2_ctrl_handler_free(&dev
->ctrl_hdl_radio_tx
);
1698 v4l2_ctrl_handler_free(&dev
->ctrl_hdl_sdr_cap
);
1699 v4l2_ctrl_handler_free(&dev
->ctrl_hdl_user_gen
);
1700 v4l2_ctrl_handler_free(&dev
->ctrl_hdl_user_vid
);
1701 v4l2_ctrl_handler_free(&dev
->ctrl_hdl_user_aud
);
1702 v4l2_ctrl_handler_free(&dev
->ctrl_hdl_streaming
);
1703 v4l2_ctrl_handler_free(&dev
->ctrl_hdl_sdtv_cap
);
1704 v4l2_ctrl_handler_free(&dev
->ctrl_hdl_loop_cap
);