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)
44 #define VIVID_CID_VIVID_BASE (0x00f00000 | 0xf000)
45 #define VIVID_CID_VIVID_CLASS (0x00f00000 | 1)
46 #define VIVID_CID_TEST_PATTERN (VIVID_CID_VIVID_BASE + 0)
47 #define VIVID_CID_OSD_TEXT_MODE (VIVID_CID_VIVID_BASE + 1)
48 #define VIVID_CID_HOR_MOVEMENT (VIVID_CID_VIVID_BASE + 2)
49 #define VIVID_CID_VERT_MOVEMENT (VIVID_CID_VIVID_BASE + 3)
50 #define VIVID_CID_SHOW_BORDER (VIVID_CID_VIVID_BASE + 4)
51 #define VIVID_CID_SHOW_SQUARE (VIVID_CID_VIVID_BASE + 5)
52 #define VIVID_CID_INSERT_SAV (VIVID_CID_VIVID_BASE + 6)
53 #define VIVID_CID_INSERT_EAV (VIVID_CID_VIVID_BASE + 7)
54 #define VIVID_CID_VBI_CAP_INTERLACED (VIVID_CID_VIVID_BASE + 8)
56 #define VIVID_CID_HFLIP (VIVID_CID_VIVID_BASE + 20)
57 #define VIVID_CID_VFLIP (VIVID_CID_VIVID_BASE + 21)
58 #define VIVID_CID_STD_ASPECT_RATIO (VIVID_CID_VIVID_BASE + 22)
59 #define VIVID_CID_DV_TIMINGS_ASPECT_RATIO (VIVID_CID_VIVID_BASE + 23)
60 #define VIVID_CID_TSTAMP_SRC (VIVID_CID_VIVID_BASE + 24)
61 #define VIVID_CID_COLORSPACE (VIVID_CID_VIVID_BASE + 25)
62 #define VIVID_CID_LIMITED_RGB_RANGE (VIVID_CID_VIVID_BASE + 26)
63 #define VIVID_CID_ALPHA_MODE (VIVID_CID_VIVID_BASE + 27)
64 #define VIVID_CID_HAS_CROP_CAP (VIVID_CID_VIVID_BASE + 28)
65 #define VIVID_CID_HAS_COMPOSE_CAP (VIVID_CID_VIVID_BASE + 29)
66 #define VIVID_CID_HAS_SCALER_CAP (VIVID_CID_VIVID_BASE + 30)
67 #define VIVID_CID_HAS_CROP_OUT (VIVID_CID_VIVID_BASE + 31)
68 #define VIVID_CID_HAS_COMPOSE_OUT (VIVID_CID_VIVID_BASE + 32)
69 #define VIVID_CID_HAS_SCALER_OUT (VIVID_CID_VIVID_BASE + 33)
70 #define VIVID_CID_LOOP_VIDEO (VIVID_CID_VIVID_BASE + 34)
71 #define VIVID_CID_SEQ_WRAP (VIVID_CID_VIVID_BASE + 35)
72 #define VIVID_CID_TIME_WRAP (VIVID_CID_VIVID_BASE + 36)
73 #define VIVID_CID_MAX_EDID_BLOCKS (VIVID_CID_VIVID_BASE + 37)
74 #define VIVID_CID_PERCENTAGE_FILL (VIVID_CID_VIVID_BASE + 38)
76 #define VIVID_CID_STD_SIGNAL_MODE (VIVID_CID_VIVID_BASE + 60)
77 #define VIVID_CID_STANDARD (VIVID_CID_VIVID_BASE + 61)
78 #define VIVID_CID_DV_TIMINGS_SIGNAL_MODE (VIVID_CID_VIVID_BASE + 62)
79 #define VIVID_CID_DV_TIMINGS (VIVID_CID_VIVID_BASE + 63)
80 #define VIVID_CID_PERC_DROPPED (VIVID_CID_VIVID_BASE + 64)
81 #define VIVID_CID_DISCONNECT (VIVID_CID_VIVID_BASE + 65)
82 #define VIVID_CID_DQBUF_ERROR (VIVID_CID_VIVID_BASE + 66)
83 #define VIVID_CID_QUEUE_SETUP_ERROR (VIVID_CID_VIVID_BASE + 67)
84 #define VIVID_CID_BUF_PREPARE_ERROR (VIVID_CID_VIVID_BASE + 68)
85 #define VIVID_CID_START_STR_ERROR (VIVID_CID_VIVID_BASE + 69)
86 #define VIVID_CID_QUEUE_ERROR (VIVID_CID_VIVID_BASE + 70)
87 #define VIVID_CID_CLEAR_FB (VIVID_CID_VIVID_BASE + 71)
89 #define VIVID_CID_RADIO_SEEK_MODE (VIVID_CID_VIVID_BASE + 90)
90 #define VIVID_CID_RADIO_SEEK_PROG_LIM (VIVID_CID_VIVID_BASE + 91)
91 #define VIVID_CID_RADIO_RX_RDS_RBDS (VIVID_CID_VIVID_BASE + 92)
92 #define VIVID_CID_RADIO_RX_RDS_BLOCKIO (VIVID_CID_VIVID_BASE + 93)
94 #define VIVID_CID_RADIO_TX_RDS_BLOCKIO (VIVID_CID_VIVID_BASE + 94)
97 /* General User Controls */
99 static int vivid_user_gen_s_ctrl(struct v4l2_ctrl
*ctrl
)
101 struct vivid_dev
*dev
= container_of(ctrl
->handler
, struct vivid_dev
, ctrl_hdl_user_gen
);
104 case VIVID_CID_DISCONNECT
:
105 v4l2_info(&dev
->v4l2_dev
, "disconnect\n");
106 clear_bit(V4L2_FL_REGISTERED
, &dev
->vid_cap_dev
.flags
);
107 clear_bit(V4L2_FL_REGISTERED
, &dev
->vid_out_dev
.flags
);
108 clear_bit(V4L2_FL_REGISTERED
, &dev
->vbi_cap_dev
.flags
);
109 clear_bit(V4L2_FL_REGISTERED
, &dev
->vbi_out_dev
.flags
);
110 clear_bit(V4L2_FL_REGISTERED
, &dev
->sdr_cap_dev
.flags
);
111 clear_bit(V4L2_FL_REGISTERED
, &dev
->radio_rx_dev
.flags
);
112 clear_bit(V4L2_FL_REGISTERED
, &dev
->radio_tx_dev
.flags
);
114 case VIVID_CID_CLEAR_FB
:
117 case VIVID_CID_BUTTON
:
118 dev
->button_pressed
= 30;
124 static const struct v4l2_ctrl_ops vivid_user_gen_ctrl_ops
= {
125 .s_ctrl
= vivid_user_gen_s_ctrl
,
128 static const struct v4l2_ctrl_config vivid_ctrl_button
= {
129 .ops
= &vivid_user_gen_ctrl_ops
,
130 .id
= VIVID_CID_BUTTON
,
132 .type
= V4L2_CTRL_TYPE_BUTTON
,
135 static const struct v4l2_ctrl_config vivid_ctrl_boolean
= {
136 .ops
= &vivid_user_gen_ctrl_ops
,
137 .id
= VIVID_CID_BOOLEAN
,
139 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
146 static const struct v4l2_ctrl_config vivid_ctrl_int32
= {
147 .ops
= &vivid_user_gen_ctrl_ops
,
148 .id
= VIVID_CID_INTEGER
,
149 .name
= "Integer 32 Bits",
150 .type
= V4L2_CTRL_TYPE_INTEGER
,
151 .min
= 0xffffffff80000000ULL
,
156 static const struct v4l2_ctrl_config vivid_ctrl_int64
= {
157 .ops
= &vivid_user_gen_ctrl_ops
,
158 .id
= VIVID_CID_INTEGER64
,
159 .name
= "Integer 64 Bits",
160 .type
= V4L2_CTRL_TYPE_INTEGER64
,
161 .min
= 0x8000000000000000ULL
,
162 .max
= 0x7fffffffffffffffLL
,
166 static const char * const vivid_ctrl_menu_strings
[] = {
167 "Menu Item 0 (Skipped)",
169 "Menu Item 2 (Skipped)",
172 "Menu Item 5 (Skipped)",
176 static const struct v4l2_ctrl_config vivid_ctrl_menu
= {
177 .ops
= &vivid_user_gen_ctrl_ops
,
178 .id
= VIVID_CID_MENU
,
180 .type
= V4L2_CTRL_TYPE_MENU
,
184 .menu_skip_mask
= 0x04,
185 .qmenu
= vivid_ctrl_menu_strings
,
188 static const struct v4l2_ctrl_config vivid_ctrl_string
= {
189 .ops
= &vivid_user_gen_ctrl_ops
,
190 .id
= VIVID_CID_STRING
,
192 .type
= V4L2_CTRL_TYPE_STRING
,
198 static const struct v4l2_ctrl_config vivid_ctrl_bitmask
= {
199 .ops
= &vivid_user_gen_ctrl_ops
,
200 .id
= VIVID_CID_BITMASK
,
202 .type
= V4L2_CTRL_TYPE_BITMASK
,
209 static const s64 vivid_ctrl_int_menu_values
[] = {
210 1, 1, 2, 3, 5, 8, 13, 21, 42,
213 static const struct v4l2_ctrl_config vivid_ctrl_int_menu
= {
214 .ops
= &vivid_user_gen_ctrl_ops
,
215 .id
= VIVID_CID_INTMENU
,
216 .name
= "Integer Menu",
217 .type
= V4L2_CTRL_TYPE_INTEGER_MENU
,
221 .menu_skip_mask
= 0x02,
222 .qmenu_int
= vivid_ctrl_int_menu_values
,
225 static const struct v4l2_ctrl_config vivid_ctrl_disconnect
= {
226 .ops
= &vivid_user_gen_ctrl_ops
,
227 .id
= VIVID_CID_DISCONNECT
,
228 .name
= "Disconnect",
229 .type
= V4L2_CTRL_TYPE_BUTTON
,
232 static const struct v4l2_ctrl_config vivid_ctrl_clear_fb
= {
233 .ops
= &vivid_user_gen_ctrl_ops
,
234 .id
= VIVID_CID_CLEAR_FB
,
235 .name
= "Clear Framebuffer",
236 .type
= V4L2_CTRL_TYPE_BUTTON
,
240 /* Video User Controls */
242 static int vivid_user_vid_g_volatile_ctrl(struct v4l2_ctrl
*ctrl
)
244 struct vivid_dev
*dev
= container_of(ctrl
->handler
, struct vivid_dev
, ctrl_hdl_user_vid
);
247 case V4L2_CID_AUTOGAIN
:
248 dev
->gain
->val
= dev
->jiffies_vid_cap
& 0xff;
254 static int vivid_user_vid_s_ctrl(struct v4l2_ctrl
*ctrl
)
256 struct vivid_dev
*dev
= container_of(ctrl
->handler
, struct vivid_dev
, ctrl_hdl_user_vid
);
259 case V4L2_CID_BRIGHTNESS
:
260 dev
->input_brightness
[dev
->input
] = ctrl
->val
- dev
->input
* 128;
261 tpg_s_brightness(&dev
->tpg
, dev
->input_brightness
[dev
->input
]);
263 case V4L2_CID_CONTRAST
:
264 tpg_s_contrast(&dev
->tpg
, ctrl
->val
);
266 case V4L2_CID_SATURATION
:
267 tpg_s_saturation(&dev
->tpg
, ctrl
->val
);
270 tpg_s_hue(&dev
->tpg
, ctrl
->val
);
273 dev
->hflip
= ctrl
->val
;
274 tpg_s_hflip(&dev
->tpg
, dev
->sensor_hflip
^ dev
->hflip
);
277 dev
->vflip
= ctrl
->val
;
278 tpg_s_vflip(&dev
->tpg
, dev
->sensor_vflip
^ dev
->vflip
);
280 case V4L2_CID_ALPHA_COMPONENT
:
281 tpg_s_alpha_component(&dev
->tpg
, ctrl
->val
);
287 static const struct v4l2_ctrl_ops vivid_user_vid_ctrl_ops
= {
288 .g_volatile_ctrl
= vivid_user_vid_g_volatile_ctrl
,
289 .s_ctrl
= vivid_user_vid_s_ctrl
,
293 /* Video Capture Controls */
295 static int vivid_vid_cap_s_ctrl(struct v4l2_ctrl
*ctrl
)
297 struct vivid_dev
*dev
= container_of(ctrl
->handler
, struct vivid_dev
, ctrl_hdl_vid_cap
);
301 case VIVID_CID_TEST_PATTERN
:
302 vivid_update_quality(dev
);
303 tpg_s_pattern(&dev
->tpg
, ctrl
->val
);
305 case VIVID_CID_COLORSPACE
:
306 tpg_s_colorspace(&dev
->tpg
, ctrl
->val
);
307 vivid_send_source_change(dev
, TV
);
308 vivid_send_source_change(dev
, SVID
);
309 vivid_send_source_change(dev
, HDMI
);
310 vivid_send_source_change(dev
, WEBCAM
);
312 case V4L2_CID_DV_RX_RGB_RANGE
:
313 if (!vivid_is_hdmi_cap(dev
))
315 tpg_s_rgb_range(&dev
->tpg
, ctrl
->val
);
317 case VIVID_CID_LIMITED_RGB_RANGE
:
318 tpg_s_real_rgb_range(&dev
->tpg
, ctrl
->val
?
319 V4L2_DV_RGB_RANGE_LIMITED
: V4L2_DV_RGB_RANGE_FULL
);
321 case VIVID_CID_ALPHA_MODE
:
322 tpg_s_alpha_mode(&dev
->tpg
, ctrl
->val
);
324 case VIVID_CID_HOR_MOVEMENT
:
325 tpg_s_mv_hor_mode(&dev
->tpg
, ctrl
->val
);
327 case VIVID_CID_VERT_MOVEMENT
:
328 tpg_s_mv_vert_mode(&dev
->tpg
, ctrl
->val
);
330 case VIVID_CID_OSD_TEXT_MODE
:
331 dev
->osd_mode
= ctrl
->val
;
333 case VIVID_CID_PERCENTAGE_FILL
:
334 tpg_s_perc_fill(&dev
->tpg
, ctrl
->val
);
335 for (i
= 0; i
< VIDEO_MAX_FRAME
; i
++)
336 dev
->must_blank
[i
] = ctrl
->val
< 100;
338 case VIVID_CID_INSERT_SAV
:
339 tpg_s_insert_sav(&dev
->tpg
, ctrl
->val
);
341 case VIVID_CID_INSERT_EAV
:
342 tpg_s_insert_eav(&dev
->tpg
, ctrl
->val
);
344 case VIVID_CID_HFLIP
:
345 dev
->sensor_hflip
= ctrl
->val
;
346 tpg_s_hflip(&dev
->tpg
, dev
->sensor_hflip
^ dev
->hflip
);
348 case VIVID_CID_VFLIP
:
349 dev
->sensor_vflip
= ctrl
->val
;
350 tpg_s_vflip(&dev
->tpg
, dev
->sensor_vflip
^ dev
->vflip
);
352 case VIVID_CID_HAS_CROP_CAP
:
353 dev
->has_crop_cap
= ctrl
->val
;
354 vivid_update_format_cap(dev
, true);
356 case VIVID_CID_HAS_COMPOSE_CAP
:
357 dev
->has_compose_cap
= ctrl
->val
;
358 vivid_update_format_cap(dev
, true);
360 case VIVID_CID_HAS_SCALER_CAP
:
361 dev
->has_scaler_cap
= ctrl
->val
;
362 vivid_update_format_cap(dev
, true);
364 case VIVID_CID_SHOW_BORDER
:
365 tpg_s_show_border(&dev
->tpg
, ctrl
->val
);
367 case VIVID_CID_SHOW_SQUARE
:
368 tpg_s_show_square(&dev
->tpg
, ctrl
->val
);
370 case VIVID_CID_STD_ASPECT_RATIO
:
371 dev
->std_aspect_ratio
= ctrl
->val
;
372 tpg_s_video_aspect(&dev
->tpg
, vivid_get_video_aspect(dev
));
374 case VIVID_CID_DV_TIMINGS_SIGNAL_MODE
:
375 dev
->dv_timings_signal_mode
= dev
->ctrl_dv_timings_signal_mode
->val
;
376 if (dev
->dv_timings_signal_mode
== SELECTED_DV_TIMINGS
)
377 dev
->query_dv_timings
= dev
->ctrl_dv_timings
->val
;
378 v4l2_ctrl_activate(dev
->ctrl_dv_timings
,
379 dev
->dv_timings_signal_mode
== SELECTED_DV_TIMINGS
);
380 vivid_update_quality(dev
);
381 vivid_send_source_change(dev
, HDMI
);
383 case VIVID_CID_DV_TIMINGS_ASPECT_RATIO
:
384 dev
->dv_timings_aspect_ratio
= ctrl
->val
;
385 tpg_s_video_aspect(&dev
->tpg
, vivid_get_video_aspect(dev
));
387 case VIVID_CID_TSTAMP_SRC
:
388 dev
->tstamp_src_is_soe
= ctrl
->val
;
389 dev
->vb_vid_cap_q
.timestamp_flags
&= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK
;
390 if (dev
->tstamp_src_is_soe
)
391 dev
->vb_vid_cap_q
.timestamp_flags
|= V4L2_BUF_FLAG_TSTAMP_SRC_SOE
;
393 case VIVID_CID_MAX_EDID_BLOCKS
:
394 dev
->edid_max_blocks
= ctrl
->val
;
395 if (dev
->edid_blocks
> dev
->edid_max_blocks
)
396 dev
->edid_blocks
= dev
->edid_max_blocks
;
402 static const struct v4l2_ctrl_ops vivid_vid_cap_ctrl_ops
= {
403 .s_ctrl
= vivid_vid_cap_s_ctrl
,
406 static const char * const vivid_ctrl_hor_movement_strings
[] = {
417 static const struct v4l2_ctrl_config vivid_ctrl_hor_movement
= {
418 .ops
= &vivid_vid_cap_ctrl_ops
,
419 .id
= VIVID_CID_HOR_MOVEMENT
,
420 .name
= "Horizontal Movement",
421 .type
= V4L2_CTRL_TYPE_MENU
,
422 .max
= TPG_MOVE_POS_FAST
,
423 .def
= TPG_MOVE_NONE
,
424 .qmenu
= vivid_ctrl_hor_movement_strings
,
427 static const char * const vivid_ctrl_vert_movement_strings
[] = {
438 static const struct v4l2_ctrl_config vivid_ctrl_vert_movement
= {
439 .ops
= &vivid_vid_cap_ctrl_ops
,
440 .id
= VIVID_CID_VERT_MOVEMENT
,
441 .name
= "Vertical Movement",
442 .type
= V4L2_CTRL_TYPE_MENU
,
443 .max
= TPG_MOVE_POS_FAST
,
444 .def
= TPG_MOVE_NONE
,
445 .qmenu
= vivid_ctrl_vert_movement_strings
,
448 static const struct v4l2_ctrl_config vivid_ctrl_show_border
= {
449 .ops
= &vivid_vid_cap_ctrl_ops
,
450 .id
= VIVID_CID_SHOW_BORDER
,
451 .name
= "Show Border",
452 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
457 static const struct v4l2_ctrl_config vivid_ctrl_show_square
= {
458 .ops
= &vivid_vid_cap_ctrl_ops
,
459 .id
= VIVID_CID_SHOW_SQUARE
,
460 .name
= "Show Square",
461 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
466 static const char * const vivid_ctrl_osd_mode_strings
[] = {
473 static const struct v4l2_ctrl_config vivid_ctrl_osd_mode
= {
474 .ops
= &vivid_vid_cap_ctrl_ops
,
475 .id
= VIVID_CID_OSD_TEXT_MODE
,
476 .name
= "OSD Text Mode",
477 .type
= V4L2_CTRL_TYPE_MENU
,
479 .qmenu
= vivid_ctrl_osd_mode_strings
,
482 static const struct v4l2_ctrl_config vivid_ctrl_perc_fill
= {
483 .ops
= &vivid_vid_cap_ctrl_ops
,
484 .id
= VIVID_CID_PERCENTAGE_FILL
,
485 .name
= "Fill Percentage of Frame",
486 .type
= V4L2_CTRL_TYPE_INTEGER
,
493 static const struct v4l2_ctrl_config vivid_ctrl_insert_sav
= {
494 .ops
= &vivid_vid_cap_ctrl_ops
,
495 .id
= VIVID_CID_INSERT_SAV
,
496 .name
= "Insert SAV Code in Image",
497 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
502 static const struct v4l2_ctrl_config vivid_ctrl_insert_eav
= {
503 .ops
= &vivid_vid_cap_ctrl_ops
,
504 .id
= VIVID_CID_INSERT_EAV
,
505 .name
= "Insert EAV Code in Image",
506 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
511 static const struct v4l2_ctrl_config vivid_ctrl_hflip
= {
512 .ops
= &vivid_vid_cap_ctrl_ops
,
513 .id
= VIVID_CID_HFLIP
,
514 .name
= "Sensor Flipped Horizontally",
515 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
520 static const struct v4l2_ctrl_config vivid_ctrl_vflip
= {
521 .ops
= &vivid_vid_cap_ctrl_ops
,
522 .id
= VIVID_CID_VFLIP
,
523 .name
= "Sensor Flipped Vertically",
524 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
529 static const struct v4l2_ctrl_config vivid_ctrl_has_crop_cap
= {
530 .ops
= &vivid_vid_cap_ctrl_ops
,
531 .id
= VIVID_CID_HAS_CROP_CAP
,
532 .name
= "Enable Capture Cropping",
533 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
539 static const struct v4l2_ctrl_config vivid_ctrl_has_compose_cap
= {
540 .ops
= &vivid_vid_cap_ctrl_ops
,
541 .id
= VIVID_CID_HAS_COMPOSE_CAP
,
542 .name
= "Enable Capture Composing",
543 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
549 static const struct v4l2_ctrl_config vivid_ctrl_has_scaler_cap
= {
550 .ops
= &vivid_vid_cap_ctrl_ops
,
551 .id
= VIVID_CID_HAS_SCALER_CAP
,
552 .name
= "Enable Capture Scaler",
553 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
559 static const char * const vivid_ctrl_tstamp_src_strings
[] = {
565 static const struct v4l2_ctrl_config vivid_ctrl_tstamp_src
= {
566 .ops
= &vivid_vid_cap_ctrl_ops
,
567 .id
= VIVID_CID_TSTAMP_SRC
,
568 .name
= "Timestamp Source",
569 .type
= V4L2_CTRL_TYPE_MENU
,
571 .qmenu
= vivid_ctrl_tstamp_src_strings
,
574 static const struct v4l2_ctrl_config vivid_ctrl_std_aspect_ratio
= {
575 .ops
= &vivid_vid_cap_ctrl_ops
,
576 .id
= VIVID_CID_STD_ASPECT_RATIO
,
577 .name
= "Standard Aspect Ratio",
578 .type
= V4L2_CTRL_TYPE_MENU
,
582 .qmenu
= tpg_aspect_strings
,
585 static const char * const vivid_ctrl_dv_timings_signal_mode_strings
[] = {
586 "Current DV Timings",
590 "Selected DV Timings",
591 "Cycle Through All DV Timings",
596 static const struct v4l2_ctrl_config vivid_ctrl_dv_timings_signal_mode
= {
597 .ops
= &vivid_vid_cap_ctrl_ops
,
598 .id
= VIVID_CID_DV_TIMINGS_SIGNAL_MODE
,
599 .name
= "DV Timings Signal Mode",
600 .type
= V4L2_CTRL_TYPE_MENU
,
602 .qmenu
= vivid_ctrl_dv_timings_signal_mode_strings
,
605 static const struct v4l2_ctrl_config vivid_ctrl_dv_timings_aspect_ratio
= {
606 .ops
= &vivid_vid_cap_ctrl_ops
,
607 .id
= VIVID_CID_DV_TIMINGS_ASPECT_RATIO
,
608 .name
= "DV Timings Aspect Ratio",
609 .type
= V4L2_CTRL_TYPE_MENU
,
611 .qmenu
= tpg_aspect_strings
,
614 static const struct v4l2_ctrl_config vivid_ctrl_max_edid_blocks
= {
615 .ops
= &vivid_vid_cap_ctrl_ops
,
616 .id
= VIVID_CID_MAX_EDID_BLOCKS
,
617 .name
= "Maximum EDID Blocks",
618 .type
= V4L2_CTRL_TYPE_INTEGER
,
625 static const char * const vivid_ctrl_colorspace_strings
[] = {
630 "", /* Skip Bt878 entry */
633 "", /* Skip JPEG entry */
638 static const struct v4l2_ctrl_config vivid_ctrl_colorspace
= {
639 .ops
= &vivid_vid_cap_ctrl_ops
,
640 .id
= VIVID_CID_COLORSPACE
,
641 .name
= "Colorspace",
642 .type
= V4L2_CTRL_TYPE_MENU
,
645 .menu_skip_mask
= (1 << 4) | (1 << 7),
647 .qmenu
= vivid_ctrl_colorspace_strings
,
650 static const struct v4l2_ctrl_config vivid_ctrl_alpha_mode
= {
651 .ops
= &vivid_vid_cap_ctrl_ops
,
652 .id
= VIVID_CID_ALPHA_MODE
,
653 .name
= "Apply Alpha To Red Only",
654 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
659 static const struct v4l2_ctrl_config vivid_ctrl_limited_rgb_range
= {
660 .ops
= &vivid_vid_cap_ctrl_ops
,
661 .id
= VIVID_CID_LIMITED_RGB_RANGE
,
662 .name
= "Limited RGB Range (16-235)",
663 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
669 /* VBI Capture Control */
671 static int vivid_vbi_cap_s_ctrl(struct v4l2_ctrl
*ctrl
)
673 struct vivid_dev
*dev
= container_of(ctrl
->handler
, struct vivid_dev
, ctrl_hdl_vbi_cap
);
676 case VIVID_CID_VBI_CAP_INTERLACED
:
677 dev
->vbi_cap_interlaced
= ctrl
->val
;
683 static const struct v4l2_ctrl_ops vivid_vbi_cap_ctrl_ops
= {
684 .s_ctrl
= vivid_vbi_cap_s_ctrl
,
687 static const struct v4l2_ctrl_config vivid_ctrl_vbi_cap_interlaced
= {
688 .ops
= &vivid_vbi_cap_ctrl_ops
,
689 .id
= VIVID_CID_VBI_CAP_INTERLACED
,
690 .name
= "Interlaced VBI Format",
691 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
697 /* Video Output Controls */
699 static int vivid_vid_out_s_ctrl(struct v4l2_ctrl
*ctrl
)
701 struct vivid_dev
*dev
= container_of(ctrl
->handler
, struct vivid_dev
, ctrl_hdl_vid_out
);
702 struct v4l2_bt_timings
*bt
= &dev
->dv_timings_out
.bt
;
705 case VIVID_CID_HAS_CROP_OUT
:
706 dev
->has_crop_out
= ctrl
->val
;
707 vivid_update_format_out(dev
);
709 case VIVID_CID_HAS_COMPOSE_OUT
:
710 dev
->has_compose_out
= ctrl
->val
;
711 vivid_update_format_out(dev
);
713 case VIVID_CID_HAS_SCALER_OUT
:
714 dev
->has_scaler_out
= ctrl
->val
;
715 vivid_update_format_out(dev
);
717 case V4L2_CID_DV_TX_MODE
:
718 dev
->dvi_d_out
= ctrl
->val
== V4L2_DV_TX_MODE_DVI_D
;
719 if (!vivid_is_hdmi_out(dev
))
721 if (!dev
->dvi_d_out
&& (bt
->standards
& V4L2_DV_BT_STD_CEA861
)) {
722 if (bt
->width
== 720 && bt
->height
<= 576)
723 dev
->colorspace_out
= V4L2_COLORSPACE_SMPTE170M
;
725 dev
->colorspace_out
= V4L2_COLORSPACE_REC709
;
727 dev
->colorspace_out
= V4L2_COLORSPACE_SRGB
;
730 vivid_send_source_change(dev
, HDMI
);
736 static const struct v4l2_ctrl_ops vivid_vid_out_ctrl_ops
= {
737 .s_ctrl
= vivid_vid_out_s_ctrl
,
740 static const struct v4l2_ctrl_config vivid_ctrl_has_crop_out
= {
741 .ops
= &vivid_vid_out_ctrl_ops
,
742 .id
= VIVID_CID_HAS_CROP_OUT
,
743 .name
= "Enable Output Cropping",
744 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
750 static const struct v4l2_ctrl_config vivid_ctrl_has_compose_out
= {
751 .ops
= &vivid_vid_out_ctrl_ops
,
752 .id
= VIVID_CID_HAS_COMPOSE_OUT
,
753 .name
= "Enable Output Composing",
754 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
760 static const struct v4l2_ctrl_config vivid_ctrl_has_scaler_out
= {
761 .ops
= &vivid_vid_out_ctrl_ops
,
762 .id
= VIVID_CID_HAS_SCALER_OUT
,
763 .name
= "Enable Output Scaler",
764 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
771 /* Streaming Controls */
773 static int vivid_streaming_s_ctrl(struct v4l2_ctrl
*ctrl
)
775 struct vivid_dev
*dev
= container_of(ctrl
->handler
, struct vivid_dev
, ctrl_hdl_streaming
);
779 case VIVID_CID_DQBUF_ERROR
:
780 dev
->dqbuf_error
= true;
782 case VIVID_CID_PERC_DROPPED
:
783 dev
->perc_dropped_buffers
= ctrl
->val
;
785 case VIVID_CID_QUEUE_SETUP_ERROR
:
786 dev
->queue_setup_error
= true;
788 case VIVID_CID_BUF_PREPARE_ERROR
:
789 dev
->buf_prepare_error
= true;
791 case VIVID_CID_START_STR_ERROR
:
792 dev
->start_streaming_error
= true;
794 case VIVID_CID_QUEUE_ERROR
:
795 if (dev
->vb_vid_cap_q
.start_streaming_called
)
796 vb2_queue_error(&dev
->vb_vid_cap_q
);
797 if (dev
->vb_vbi_cap_q
.start_streaming_called
)
798 vb2_queue_error(&dev
->vb_vbi_cap_q
);
799 if (dev
->vb_vid_out_q
.start_streaming_called
)
800 vb2_queue_error(&dev
->vb_vid_out_q
);
801 if (dev
->vb_vbi_out_q
.start_streaming_called
)
802 vb2_queue_error(&dev
->vb_vbi_out_q
);
803 if (dev
->vb_sdr_cap_q
.start_streaming_called
)
804 vb2_queue_error(&dev
->vb_sdr_cap_q
);
806 case VIVID_CID_SEQ_WRAP
:
807 dev
->seq_wrap
= ctrl
->val
;
809 case VIVID_CID_TIME_WRAP
:
810 dev
->time_wrap
= ctrl
->val
;
811 if (ctrl
->val
== 0) {
812 dev
->time_wrap_offset
= 0;
815 v4l2_get_timestamp(&tv
);
816 dev
->time_wrap_offset
= -tv
.tv_sec
- 16;
822 static const struct v4l2_ctrl_ops vivid_streaming_ctrl_ops
= {
823 .s_ctrl
= vivid_streaming_s_ctrl
,
826 static const struct v4l2_ctrl_config vivid_ctrl_dqbuf_error
= {
827 .ops
= &vivid_streaming_ctrl_ops
,
828 .id
= VIVID_CID_DQBUF_ERROR
,
829 .name
= "Inject V4L2_BUF_FLAG_ERROR",
830 .type
= V4L2_CTRL_TYPE_BUTTON
,
833 static const struct v4l2_ctrl_config vivid_ctrl_perc_dropped
= {
834 .ops
= &vivid_streaming_ctrl_ops
,
835 .id
= VIVID_CID_PERC_DROPPED
,
836 .name
= "Percentage of Dropped Buffers",
837 .type
= V4L2_CTRL_TYPE_INTEGER
,
843 static const struct v4l2_ctrl_config vivid_ctrl_queue_setup_error
= {
844 .ops
= &vivid_streaming_ctrl_ops
,
845 .id
= VIVID_CID_QUEUE_SETUP_ERROR
,
846 .name
= "Inject VIDIOC_REQBUFS Error",
847 .type
= V4L2_CTRL_TYPE_BUTTON
,
850 static const struct v4l2_ctrl_config vivid_ctrl_buf_prepare_error
= {
851 .ops
= &vivid_streaming_ctrl_ops
,
852 .id
= VIVID_CID_BUF_PREPARE_ERROR
,
853 .name
= "Inject VIDIOC_QBUF Error",
854 .type
= V4L2_CTRL_TYPE_BUTTON
,
857 static const struct v4l2_ctrl_config vivid_ctrl_start_streaming_error
= {
858 .ops
= &vivid_streaming_ctrl_ops
,
859 .id
= VIVID_CID_START_STR_ERROR
,
860 .name
= "Inject VIDIOC_STREAMON Error",
861 .type
= V4L2_CTRL_TYPE_BUTTON
,
864 static const struct v4l2_ctrl_config vivid_ctrl_queue_error
= {
865 .ops
= &vivid_streaming_ctrl_ops
,
866 .id
= VIVID_CID_QUEUE_ERROR
,
867 .name
= "Inject Fatal Streaming Error",
868 .type
= V4L2_CTRL_TYPE_BUTTON
,
871 static const struct v4l2_ctrl_config vivid_ctrl_seq_wrap
= {
872 .ops
= &vivid_streaming_ctrl_ops
,
873 .id
= VIVID_CID_SEQ_WRAP
,
874 .name
= "Wrap Sequence Number",
875 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
880 static const struct v4l2_ctrl_config vivid_ctrl_time_wrap
= {
881 .ops
= &vivid_streaming_ctrl_ops
,
882 .id
= VIVID_CID_TIME_WRAP
,
883 .name
= "Wrap Timestamp",
884 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
890 /* SDTV Capture Controls */
892 static int vivid_sdtv_cap_s_ctrl(struct v4l2_ctrl
*ctrl
)
894 struct vivid_dev
*dev
= container_of(ctrl
->handler
, struct vivid_dev
, ctrl_hdl_sdtv_cap
);
897 case VIVID_CID_STD_SIGNAL_MODE
:
898 dev
->std_signal_mode
= dev
->ctrl_std_signal_mode
->val
;
899 if (dev
->std_signal_mode
== SELECTED_STD
)
900 dev
->query_std
= vivid_standard
[dev
->ctrl_standard
->val
];
901 v4l2_ctrl_activate(dev
->ctrl_standard
, dev
->std_signal_mode
== SELECTED_STD
);
902 vivid_update_quality(dev
);
903 vivid_send_source_change(dev
, TV
);
904 vivid_send_source_change(dev
, SVID
);
910 static const struct v4l2_ctrl_ops vivid_sdtv_cap_ctrl_ops
= {
911 .s_ctrl
= vivid_sdtv_cap_s_ctrl
,
914 static const char * const vivid_ctrl_std_signal_mode_strings
[] = {
920 "Cycle Through All Standards",
924 static const struct v4l2_ctrl_config vivid_ctrl_std_signal_mode
= {
925 .ops
= &vivid_sdtv_cap_ctrl_ops
,
926 .id
= VIVID_CID_STD_SIGNAL_MODE
,
927 .name
= "Standard Signal Mode",
928 .type
= V4L2_CTRL_TYPE_MENU
,
930 .menu_skip_mask
= 1 << 3,
931 .qmenu
= vivid_ctrl_std_signal_mode_strings
,
934 static const struct v4l2_ctrl_config vivid_ctrl_standard
= {
935 .ops
= &vivid_sdtv_cap_ctrl_ops
,
936 .id
= VIVID_CID_STANDARD
,
938 .type
= V4L2_CTRL_TYPE_MENU
,
940 .qmenu
= vivid_ctrl_standard_strings
,
945 /* Radio Receiver Controls */
947 static int vivid_radio_rx_s_ctrl(struct v4l2_ctrl
*ctrl
)
949 struct vivid_dev
*dev
= container_of(ctrl
->handler
, struct vivid_dev
, ctrl_hdl_radio_rx
);
952 case VIVID_CID_RADIO_SEEK_MODE
:
953 dev
->radio_rx_hw_seek_mode
= ctrl
->val
;
955 case VIVID_CID_RADIO_SEEK_PROG_LIM
:
956 dev
->radio_rx_hw_seek_prog_lim
= ctrl
->val
;
958 case VIVID_CID_RADIO_RX_RDS_RBDS
:
959 dev
->rds_gen
.use_rbds
= ctrl
->val
;
961 case VIVID_CID_RADIO_RX_RDS_BLOCKIO
:
962 dev
->radio_rx_rds_controls
= ctrl
->val
;
963 dev
->radio_rx_caps
&= ~V4L2_CAP_READWRITE
;
964 dev
->radio_rx_rds_use_alternates
= false;
965 if (!dev
->radio_rx_rds_controls
) {
966 dev
->radio_rx_caps
|= V4L2_CAP_READWRITE
;
967 __v4l2_ctrl_s_ctrl(dev
->radio_rx_rds_pty
, 0);
968 __v4l2_ctrl_s_ctrl(dev
->radio_rx_rds_ta
, 0);
969 __v4l2_ctrl_s_ctrl(dev
->radio_rx_rds_tp
, 0);
970 __v4l2_ctrl_s_ctrl(dev
->radio_rx_rds_ms
, 0);
971 __v4l2_ctrl_s_ctrl_string(dev
->radio_rx_rds_psname
, "");
972 __v4l2_ctrl_s_ctrl_string(dev
->radio_rx_rds_radiotext
, "");
974 v4l2_ctrl_activate(dev
->radio_rx_rds_pty
, dev
->radio_rx_rds_controls
);
975 v4l2_ctrl_activate(dev
->radio_rx_rds_psname
, dev
->radio_rx_rds_controls
);
976 v4l2_ctrl_activate(dev
->radio_rx_rds_radiotext
, dev
->radio_rx_rds_controls
);
977 v4l2_ctrl_activate(dev
->radio_rx_rds_ta
, dev
->radio_rx_rds_controls
);
978 v4l2_ctrl_activate(dev
->radio_rx_rds_tp
, dev
->radio_rx_rds_controls
);
979 v4l2_ctrl_activate(dev
->radio_rx_rds_ms
, dev
->radio_rx_rds_controls
);
981 case V4L2_CID_RDS_RECEPTION
:
982 dev
->radio_rx_rds_enabled
= ctrl
->val
;
988 static const struct v4l2_ctrl_ops vivid_radio_rx_ctrl_ops
= {
989 .s_ctrl
= vivid_radio_rx_s_ctrl
,
992 static const char * const vivid_ctrl_radio_rds_mode_strings
[] = {
998 static const struct v4l2_ctrl_config vivid_ctrl_radio_rx_rds_blockio
= {
999 .ops
= &vivid_radio_rx_ctrl_ops
,
1000 .id
= VIVID_CID_RADIO_RX_RDS_BLOCKIO
,
1001 .name
= "RDS Rx I/O Mode",
1002 .type
= V4L2_CTRL_TYPE_MENU
,
1003 .qmenu
= vivid_ctrl_radio_rds_mode_strings
,
1007 static const struct v4l2_ctrl_config vivid_ctrl_radio_rx_rds_rbds
= {
1008 .ops
= &vivid_radio_rx_ctrl_ops
,
1009 .id
= VIVID_CID_RADIO_RX_RDS_RBDS
,
1010 .name
= "Generate RBDS Instead of RDS",
1011 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
1016 static const char * const vivid_ctrl_radio_hw_seek_mode_strings
[] = {
1023 static const struct v4l2_ctrl_config vivid_ctrl_radio_hw_seek_mode
= {
1024 .ops
= &vivid_radio_rx_ctrl_ops
,
1025 .id
= VIVID_CID_RADIO_SEEK_MODE
,
1026 .name
= "Radio HW Seek Mode",
1027 .type
= V4L2_CTRL_TYPE_MENU
,
1029 .qmenu
= vivid_ctrl_radio_hw_seek_mode_strings
,
1032 static const struct v4l2_ctrl_config vivid_ctrl_radio_hw_seek_prog_lim
= {
1033 .ops
= &vivid_radio_rx_ctrl_ops
,
1034 .id
= VIVID_CID_RADIO_SEEK_PROG_LIM
,
1035 .name
= "Radio Programmable HW Seek",
1036 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
1042 /* Radio Transmitter Controls */
1044 static int vivid_radio_tx_s_ctrl(struct v4l2_ctrl
*ctrl
)
1046 struct vivid_dev
*dev
= container_of(ctrl
->handler
, struct vivid_dev
, ctrl_hdl_radio_tx
);
1049 case VIVID_CID_RADIO_TX_RDS_BLOCKIO
:
1050 dev
->radio_tx_rds_controls
= ctrl
->val
;
1051 dev
->radio_tx_caps
&= ~V4L2_CAP_READWRITE
;
1052 if (!dev
->radio_tx_rds_controls
)
1053 dev
->radio_tx_caps
|= V4L2_CAP_READWRITE
;
1055 case V4L2_CID_RDS_TX_PTY
:
1056 if (dev
->radio_rx_rds_controls
)
1057 v4l2_ctrl_s_ctrl(dev
->radio_rx_rds_pty
, ctrl
->val
);
1059 case V4L2_CID_RDS_TX_PS_NAME
:
1060 if (dev
->radio_rx_rds_controls
)
1061 v4l2_ctrl_s_ctrl_string(dev
->radio_rx_rds_psname
, ctrl
->p_new
.p_char
);
1063 case V4L2_CID_RDS_TX_RADIO_TEXT
:
1064 if (dev
->radio_rx_rds_controls
)
1065 v4l2_ctrl_s_ctrl_string(dev
->radio_rx_rds_radiotext
, ctrl
->p_new
.p_char
);
1067 case V4L2_CID_RDS_TX_TRAFFIC_ANNOUNCEMENT
:
1068 if (dev
->radio_rx_rds_controls
)
1069 v4l2_ctrl_s_ctrl(dev
->radio_rx_rds_ta
, ctrl
->val
);
1071 case V4L2_CID_RDS_TX_TRAFFIC_PROGRAM
:
1072 if (dev
->radio_rx_rds_controls
)
1073 v4l2_ctrl_s_ctrl(dev
->radio_rx_rds_tp
, ctrl
->val
);
1075 case V4L2_CID_RDS_TX_MUSIC_SPEECH
:
1076 if (dev
->radio_rx_rds_controls
)
1077 v4l2_ctrl_s_ctrl(dev
->radio_rx_rds_ms
, ctrl
->val
);
1083 static const struct v4l2_ctrl_ops vivid_radio_tx_ctrl_ops
= {
1084 .s_ctrl
= vivid_radio_tx_s_ctrl
,
1087 static const struct v4l2_ctrl_config vivid_ctrl_radio_tx_rds_blockio
= {
1088 .ops
= &vivid_radio_tx_ctrl_ops
,
1089 .id
= VIVID_CID_RADIO_TX_RDS_BLOCKIO
,
1090 .name
= "RDS Tx I/O Mode",
1091 .type
= V4L2_CTRL_TYPE_MENU
,
1092 .qmenu
= vivid_ctrl_radio_rds_mode_strings
,
1099 /* Video Loop Control */
1101 static int vivid_loop_out_s_ctrl(struct v4l2_ctrl
*ctrl
)
1103 struct vivid_dev
*dev
= container_of(ctrl
->handler
, struct vivid_dev
, ctrl_hdl_loop_out
);
1106 case VIVID_CID_LOOP_VIDEO
:
1107 dev
->loop_video
= ctrl
->val
;
1108 vivid_update_quality(dev
);
1109 vivid_send_source_change(dev
, SVID
);
1110 vivid_send_source_change(dev
, HDMI
);
1116 static const struct v4l2_ctrl_ops vivid_loop_out_ctrl_ops
= {
1117 .s_ctrl
= vivid_loop_out_s_ctrl
,
1120 static const struct v4l2_ctrl_config vivid_ctrl_loop_video
= {
1121 .ops
= &vivid_loop_out_ctrl_ops
,
1122 .id
= VIVID_CID_LOOP_VIDEO
,
1123 .name
= "Loop Video",
1124 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
1130 static const struct v4l2_ctrl_config vivid_ctrl_class
= {
1131 .ops
= &vivid_user_gen_ctrl_ops
,
1132 .flags
= V4L2_CTRL_FLAG_READ_ONLY
| V4L2_CTRL_FLAG_WRITE_ONLY
,
1133 .id
= VIVID_CID_VIVID_CLASS
,
1134 .name
= "Vivid Controls",
1135 .type
= V4L2_CTRL_TYPE_CTRL_CLASS
,
1138 int vivid_create_controls(struct vivid_dev
*dev
, bool show_ccs_cap
,
1139 bool show_ccs_out
, bool no_error_inj
,
1140 bool has_sdtv
, bool has_hdmi
)
1142 struct v4l2_ctrl_handler
*hdl_user_gen
= &dev
->ctrl_hdl_user_gen
;
1143 struct v4l2_ctrl_handler
*hdl_user_vid
= &dev
->ctrl_hdl_user_vid
;
1144 struct v4l2_ctrl_handler
*hdl_user_aud
= &dev
->ctrl_hdl_user_aud
;
1145 struct v4l2_ctrl_handler
*hdl_streaming
= &dev
->ctrl_hdl_streaming
;
1146 struct v4l2_ctrl_handler
*hdl_sdtv_cap
= &dev
->ctrl_hdl_sdtv_cap
;
1147 struct v4l2_ctrl_handler
*hdl_loop_out
= &dev
->ctrl_hdl_loop_out
;
1148 struct v4l2_ctrl_handler
*hdl_vid_cap
= &dev
->ctrl_hdl_vid_cap
;
1149 struct v4l2_ctrl_handler
*hdl_vid_out
= &dev
->ctrl_hdl_vid_out
;
1150 struct v4l2_ctrl_handler
*hdl_vbi_cap
= &dev
->ctrl_hdl_vbi_cap
;
1151 struct v4l2_ctrl_handler
*hdl_vbi_out
= &dev
->ctrl_hdl_vbi_out
;
1152 struct v4l2_ctrl_handler
*hdl_radio_rx
= &dev
->ctrl_hdl_radio_rx
;
1153 struct v4l2_ctrl_handler
*hdl_radio_tx
= &dev
->ctrl_hdl_radio_tx
;
1154 struct v4l2_ctrl_handler
*hdl_sdr_cap
= &dev
->ctrl_hdl_sdr_cap
;
1155 struct v4l2_ctrl_config vivid_ctrl_dv_timings
= {
1156 .ops
= &vivid_vid_cap_ctrl_ops
,
1157 .id
= VIVID_CID_DV_TIMINGS
,
1158 .name
= "DV Timings",
1159 .type
= V4L2_CTRL_TYPE_MENU
,
1163 v4l2_ctrl_handler_init(hdl_user_gen
, 10);
1164 v4l2_ctrl_new_custom(hdl_user_gen
, &vivid_ctrl_class
, NULL
);
1165 v4l2_ctrl_handler_init(hdl_user_vid
, 9);
1166 v4l2_ctrl_new_custom(hdl_user_vid
, &vivid_ctrl_class
, NULL
);
1167 v4l2_ctrl_handler_init(hdl_user_aud
, 2);
1168 v4l2_ctrl_new_custom(hdl_user_aud
, &vivid_ctrl_class
, NULL
);
1169 v4l2_ctrl_handler_init(hdl_streaming
, 8);
1170 v4l2_ctrl_new_custom(hdl_streaming
, &vivid_ctrl_class
, NULL
);
1171 v4l2_ctrl_handler_init(hdl_sdtv_cap
, 2);
1172 v4l2_ctrl_new_custom(hdl_sdtv_cap
, &vivid_ctrl_class
, NULL
);
1173 v4l2_ctrl_handler_init(hdl_loop_out
, 1);
1174 v4l2_ctrl_new_custom(hdl_loop_out
, &vivid_ctrl_class
, NULL
);
1175 v4l2_ctrl_handler_init(hdl_vid_cap
, 55);
1176 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_class
, NULL
);
1177 v4l2_ctrl_handler_init(hdl_vid_out
, 26);
1178 v4l2_ctrl_new_custom(hdl_vid_out
, &vivid_ctrl_class
, NULL
);
1179 v4l2_ctrl_handler_init(hdl_vbi_cap
, 21);
1180 v4l2_ctrl_new_custom(hdl_vbi_cap
, &vivid_ctrl_class
, NULL
);
1181 v4l2_ctrl_handler_init(hdl_vbi_out
, 19);
1182 v4l2_ctrl_new_custom(hdl_vbi_out
, &vivid_ctrl_class
, NULL
);
1183 v4l2_ctrl_handler_init(hdl_radio_rx
, 17);
1184 v4l2_ctrl_new_custom(hdl_radio_rx
, &vivid_ctrl_class
, NULL
);
1185 v4l2_ctrl_handler_init(hdl_radio_tx
, 17);
1186 v4l2_ctrl_new_custom(hdl_radio_tx
, &vivid_ctrl_class
, NULL
);
1187 v4l2_ctrl_handler_init(hdl_sdr_cap
, 18);
1188 v4l2_ctrl_new_custom(hdl_sdr_cap
, &vivid_ctrl_class
, NULL
);
1191 dev
->volume
= v4l2_ctrl_new_std(hdl_user_aud
, NULL
,
1192 V4L2_CID_AUDIO_VOLUME
, 0, 255, 1, 200);
1193 dev
->mute
= v4l2_ctrl_new_std(hdl_user_aud
, NULL
,
1194 V4L2_CID_AUDIO_MUTE
, 0, 1, 1, 0);
1195 if (dev
->has_vid_cap
) {
1196 dev
->brightness
= v4l2_ctrl_new_std(hdl_user_vid
, &vivid_user_vid_ctrl_ops
,
1197 V4L2_CID_BRIGHTNESS
, 0, 255, 1, 128);
1198 for (i
= 0; i
< MAX_INPUTS
; i
++)
1199 dev
->input_brightness
[i
] = 128;
1200 dev
->contrast
= v4l2_ctrl_new_std(hdl_user_vid
, &vivid_user_vid_ctrl_ops
,
1201 V4L2_CID_CONTRAST
, 0, 255, 1, 128);
1202 dev
->saturation
= v4l2_ctrl_new_std(hdl_user_vid
, &vivid_user_vid_ctrl_ops
,
1203 V4L2_CID_SATURATION
, 0, 255, 1, 128);
1204 dev
->hue
= v4l2_ctrl_new_std(hdl_user_vid
, &vivid_user_vid_ctrl_ops
,
1205 V4L2_CID_HUE
, -128, 128, 1, 0);
1206 v4l2_ctrl_new_std(hdl_user_vid
, &vivid_user_vid_ctrl_ops
,
1207 V4L2_CID_HFLIP
, 0, 1, 1, 0);
1208 v4l2_ctrl_new_std(hdl_user_vid
, &vivid_user_vid_ctrl_ops
,
1209 V4L2_CID_VFLIP
, 0, 1, 1, 0);
1210 dev
->autogain
= v4l2_ctrl_new_std(hdl_user_vid
, &vivid_user_vid_ctrl_ops
,
1211 V4L2_CID_AUTOGAIN
, 0, 1, 1, 1);
1212 dev
->gain
= v4l2_ctrl_new_std(hdl_user_vid
, &vivid_user_vid_ctrl_ops
,
1213 V4L2_CID_GAIN
, 0, 255, 1, 100);
1214 dev
->alpha
= v4l2_ctrl_new_std(hdl_user_vid
, &vivid_user_vid_ctrl_ops
,
1215 V4L2_CID_ALPHA_COMPONENT
, 0, 255, 1, 0);
1217 dev
->button
= v4l2_ctrl_new_custom(hdl_user_gen
, &vivid_ctrl_button
, NULL
);
1218 dev
->int32
= v4l2_ctrl_new_custom(hdl_user_gen
, &vivid_ctrl_int32
, NULL
);
1219 dev
->int64
= v4l2_ctrl_new_custom(hdl_user_gen
, &vivid_ctrl_int64
, NULL
);
1220 dev
->boolean
= v4l2_ctrl_new_custom(hdl_user_gen
, &vivid_ctrl_boolean
, NULL
);
1221 dev
->menu
= v4l2_ctrl_new_custom(hdl_user_gen
, &vivid_ctrl_menu
, NULL
);
1222 dev
->string
= v4l2_ctrl_new_custom(hdl_user_gen
, &vivid_ctrl_string
, NULL
);
1223 dev
->bitmask
= v4l2_ctrl_new_custom(hdl_user_gen
, &vivid_ctrl_bitmask
, NULL
);
1224 dev
->int_menu
= v4l2_ctrl_new_custom(hdl_user_gen
, &vivid_ctrl_int_menu
, NULL
);
1226 if (dev
->has_vid_cap
) {
1227 /* Image Processing Controls */
1228 struct v4l2_ctrl_config vivid_ctrl_test_pattern
= {
1229 .ops
= &vivid_vid_cap_ctrl_ops
,
1230 .id
= VIVID_CID_TEST_PATTERN
,
1231 .name
= "Test Pattern",
1232 .type
= V4L2_CTRL_TYPE_MENU
,
1233 .max
= TPG_PAT_NOISE
,
1234 .qmenu
= tpg_pattern_strings
,
1237 dev
->test_pattern
= v4l2_ctrl_new_custom(hdl_vid_cap
,
1238 &vivid_ctrl_test_pattern
, NULL
);
1239 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_perc_fill
, NULL
);
1240 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_hor_movement
, NULL
);
1241 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_vert_movement
, NULL
);
1242 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_osd_mode
, NULL
);
1243 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_show_border
, NULL
);
1244 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_show_square
, NULL
);
1245 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_hflip
, NULL
);
1246 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_vflip
, NULL
);
1247 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_insert_sav
, NULL
);
1248 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_insert_eav
, NULL
);
1250 dev
->ctrl_has_crop_cap
= v4l2_ctrl_new_custom(hdl_vid_cap
,
1251 &vivid_ctrl_has_crop_cap
, NULL
);
1252 dev
->ctrl_has_compose_cap
= v4l2_ctrl_new_custom(hdl_vid_cap
,
1253 &vivid_ctrl_has_compose_cap
, NULL
);
1254 dev
->ctrl_has_scaler_cap
= v4l2_ctrl_new_custom(hdl_vid_cap
,
1255 &vivid_ctrl_has_scaler_cap
, NULL
);
1258 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_tstamp_src
, NULL
);
1259 dev
->colorspace
= v4l2_ctrl_new_custom(hdl_vid_cap
,
1260 &vivid_ctrl_colorspace
, NULL
);
1261 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_alpha_mode
, NULL
);
1264 if (dev
->has_vid_out
&& show_ccs_out
) {
1265 dev
->ctrl_has_crop_out
= v4l2_ctrl_new_custom(hdl_vid_out
,
1266 &vivid_ctrl_has_crop_out
, NULL
);
1267 dev
->ctrl_has_compose_out
= v4l2_ctrl_new_custom(hdl_vid_out
,
1268 &vivid_ctrl_has_compose_out
, NULL
);
1269 dev
->ctrl_has_scaler_out
= v4l2_ctrl_new_custom(hdl_vid_out
,
1270 &vivid_ctrl_has_scaler_out
, NULL
);
1274 * Testing this driver with v4l2-compliance will trigger the error
1275 * injection controls, and after that nothing will work as expected.
1276 * So we have a module option to drop these error injecting controls
1277 * allowing us to run v4l2_compliance again.
1279 if (!no_error_inj
) {
1280 v4l2_ctrl_new_custom(hdl_user_gen
, &vivid_ctrl_disconnect
, NULL
);
1281 v4l2_ctrl_new_custom(hdl_streaming
, &vivid_ctrl_dqbuf_error
, NULL
);
1282 v4l2_ctrl_new_custom(hdl_streaming
, &vivid_ctrl_perc_dropped
, NULL
);
1283 v4l2_ctrl_new_custom(hdl_streaming
, &vivid_ctrl_queue_setup_error
, NULL
);
1284 v4l2_ctrl_new_custom(hdl_streaming
, &vivid_ctrl_buf_prepare_error
, NULL
);
1285 v4l2_ctrl_new_custom(hdl_streaming
, &vivid_ctrl_start_streaming_error
, NULL
);
1286 v4l2_ctrl_new_custom(hdl_streaming
, &vivid_ctrl_queue_error
, NULL
);
1287 v4l2_ctrl_new_custom(hdl_streaming
, &vivid_ctrl_seq_wrap
, NULL
);
1288 v4l2_ctrl_new_custom(hdl_streaming
, &vivid_ctrl_time_wrap
, NULL
);
1291 if (has_sdtv
&& (dev
->has_vid_cap
|| dev
->has_vbi_cap
)) {
1292 if (dev
->has_vid_cap
)
1293 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_std_aspect_ratio
, NULL
);
1294 dev
->ctrl_std_signal_mode
= v4l2_ctrl_new_custom(hdl_sdtv_cap
,
1295 &vivid_ctrl_std_signal_mode
, NULL
);
1296 dev
->ctrl_standard
= v4l2_ctrl_new_custom(hdl_sdtv_cap
,
1297 &vivid_ctrl_standard
, NULL
);
1298 if (dev
->ctrl_std_signal_mode
)
1299 v4l2_ctrl_cluster(2, &dev
->ctrl_std_signal_mode
);
1300 if (dev
->has_raw_vbi_cap
)
1301 v4l2_ctrl_new_custom(hdl_vbi_cap
, &vivid_ctrl_vbi_cap_interlaced
, NULL
);
1304 if (has_hdmi
&& dev
->has_vid_cap
) {
1305 dev
->ctrl_dv_timings_signal_mode
= v4l2_ctrl_new_custom(hdl_vid_cap
,
1306 &vivid_ctrl_dv_timings_signal_mode
, NULL
);
1308 vivid_ctrl_dv_timings
.max
= dev
->query_dv_timings_size
- 1;
1309 vivid_ctrl_dv_timings
.qmenu
=
1310 (const char * const *)dev
->query_dv_timings_qmenu
;
1311 dev
->ctrl_dv_timings
= v4l2_ctrl_new_custom(hdl_vid_cap
,
1312 &vivid_ctrl_dv_timings
, NULL
);
1313 if (dev
->ctrl_dv_timings_signal_mode
)
1314 v4l2_ctrl_cluster(2, &dev
->ctrl_dv_timings_signal_mode
);
1316 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_dv_timings_aspect_ratio
, NULL
);
1317 v4l2_ctrl_new_custom(hdl_vid_cap
, &vivid_ctrl_max_edid_blocks
, NULL
);
1318 dev
->real_rgb_range_cap
= v4l2_ctrl_new_custom(hdl_vid_cap
,
1319 &vivid_ctrl_limited_rgb_range
, NULL
);
1320 dev
->rgb_range_cap
= v4l2_ctrl_new_std_menu(hdl_vid_cap
,
1321 &vivid_vid_cap_ctrl_ops
,
1322 V4L2_CID_DV_RX_RGB_RANGE
, V4L2_DV_RGB_RANGE_FULL
,
1323 0, V4L2_DV_RGB_RANGE_AUTO
);
1325 if (has_hdmi
&& dev
->has_vid_out
) {
1327 * We aren't doing anything with this at the moment, but
1328 * HDMI outputs typically have this controls.
1330 dev
->ctrl_tx_rgb_range
= v4l2_ctrl_new_std_menu(hdl_vid_out
, NULL
,
1331 V4L2_CID_DV_TX_RGB_RANGE
, V4L2_DV_RGB_RANGE_FULL
,
1332 0, V4L2_DV_RGB_RANGE_AUTO
);
1333 dev
->ctrl_tx_mode
= v4l2_ctrl_new_std_menu(hdl_vid_out
, NULL
,
1334 V4L2_CID_DV_TX_MODE
, V4L2_DV_TX_MODE_HDMI
,
1335 0, V4L2_DV_TX_MODE_HDMI
);
1337 if ((dev
->has_vid_cap
&& dev
->has_vid_out
) ||
1338 (dev
->has_vbi_cap
&& dev
->has_vbi_out
))
1339 v4l2_ctrl_new_custom(hdl_loop_out
, &vivid_ctrl_loop_video
, NULL
);
1342 v4l2_ctrl_new_custom(hdl_user_gen
, &vivid_ctrl_clear_fb
, NULL
);
1344 if (dev
->has_radio_rx
) {
1345 v4l2_ctrl_new_custom(hdl_radio_rx
, &vivid_ctrl_radio_hw_seek_mode
, NULL
);
1346 v4l2_ctrl_new_custom(hdl_radio_rx
, &vivid_ctrl_radio_hw_seek_prog_lim
, NULL
);
1347 v4l2_ctrl_new_custom(hdl_radio_rx
, &vivid_ctrl_radio_rx_rds_blockio
, NULL
);
1348 v4l2_ctrl_new_custom(hdl_radio_rx
, &vivid_ctrl_radio_rx_rds_rbds
, NULL
);
1349 v4l2_ctrl_new_std(hdl_radio_rx
, &vivid_radio_rx_ctrl_ops
,
1350 V4L2_CID_RDS_RECEPTION
, 0, 1, 1, 1);
1351 dev
->radio_rx_rds_pty
= v4l2_ctrl_new_std(hdl_radio_rx
,
1352 &vivid_radio_rx_ctrl_ops
,
1353 V4L2_CID_RDS_RX_PTY
, 0, 31, 1, 0);
1354 dev
->radio_rx_rds_psname
= v4l2_ctrl_new_std(hdl_radio_rx
,
1355 &vivid_radio_rx_ctrl_ops
,
1356 V4L2_CID_RDS_RX_PS_NAME
, 0, 8, 8, 0);
1357 dev
->radio_rx_rds_radiotext
= v4l2_ctrl_new_std(hdl_radio_rx
,
1358 &vivid_radio_rx_ctrl_ops
,
1359 V4L2_CID_RDS_RX_RADIO_TEXT
, 0, 64, 64, 0);
1360 dev
->radio_rx_rds_ta
= v4l2_ctrl_new_std(hdl_radio_rx
,
1361 &vivid_radio_rx_ctrl_ops
,
1362 V4L2_CID_RDS_RX_TRAFFIC_ANNOUNCEMENT
, 0, 1, 1, 0);
1363 dev
->radio_rx_rds_tp
= v4l2_ctrl_new_std(hdl_radio_rx
,
1364 &vivid_radio_rx_ctrl_ops
,
1365 V4L2_CID_RDS_RX_TRAFFIC_PROGRAM
, 0, 1, 1, 0);
1366 dev
->radio_rx_rds_ms
= v4l2_ctrl_new_std(hdl_radio_rx
,
1367 &vivid_radio_rx_ctrl_ops
,
1368 V4L2_CID_RDS_RX_MUSIC_SPEECH
, 0, 1, 1, 1);
1370 if (dev
->has_radio_tx
) {
1371 v4l2_ctrl_new_custom(hdl_radio_tx
,
1372 &vivid_ctrl_radio_tx_rds_blockio
, NULL
);
1373 dev
->radio_tx_rds_pi
= v4l2_ctrl_new_std(hdl_radio_tx
,
1374 &vivid_radio_tx_ctrl_ops
,
1375 V4L2_CID_RDS_TX_PI
, 0, 0xffff, 1, 0x8088);
1376 dev
->radio_tx_rds_pty
= v4l2_ctrl_new_std(hdl_radio_tx
,
1377 &vivid_radio_tx_ctrl_ops
,
1378 V4L2_CID_RDS_TX_PTY
, 0, 31, 1, 3);
1379 dev
->radio_tx_rds_psname
= v4l2_ctrl_new_std(hdl_radio_tx
,
1380 &vivid_radio_tx_ctrl_ops
,
1381 V4L2_CID_RDS_TX_PS_NAME
, 0, 8, 8, 0);
1382 if (dev
->radio_tx_rds_psname
)
1383 v4l2_ctrl_s_ctrl_string(dev
->radio_tx_rds_psname
, "VIVID-TX");
1384 dev
->radio_tx_rds_radiotext
= v4l2_ctrl_new_std(hdl_radio_tx
,
1385 &vivid_radio_tx_ctrl_ops
,
1386 V4L2_CID_RDS_TX_RADIO_TEXT
, 0, 64 * 2, 64, 0);
1387 if (dev
->radio_tx_rds_radiotext
)
1388 v4l2_ctrl_s_ctrl_string(dev
->radio_tx_rds_radiotext
,
1389 "This is a VIVID default Radio Text template text, change at will");
1390 dev
->radio_tx_rds_mono_stereo
= v4l2_ctrl_new_std(hdl_radio_tx
,
1391 &vivid_radio_tx_ctrl_ops
,
1392 V4L2_CID_RDS_TX_MONO_STEREO
, 0, 1, 1, 1);
1393 dev
->radio_tx_rds_art_head
= v4l2_ctrl_new_std(hdl_radio_tx
,
1394 &vivid_radio_tx_ctrl_ops
,
1395 V4L2_CID_RDS_TX_ARTIFICIAL_HEAD
, 0, 1, 1, 0);
1396 dev
->radio_tx_rds_compressed
= v4l2_ctrl_new_std(hdl_radio_tx
,
1397 &vivid_radio_tx_ctrl_ops
,
1398 V4L2_CID_RDS_TX_COMPRESSED
, 0, 1, 1, 0);
1399 dev
->radio_tx_rds_dyn_pty
= v4l2_ctrl_new_std(hdl_radio_tx
,
1400 &vivid_radio_tx_ctrl_ops
,
1401 V4L2_CID_RDS_TX_DYNAMIC_PTY
, 0, 1, 1, 0);
1402 dev
->radio_tx_rds_ta
= v4l2_ctrl_new_std(hdl_radio_tx
,
1403 &vivid_radio_tx_ctrl_ops
,
1404 V4L2_CID_RDS_TX_TRAFFIC_ANNOUNCEMENT
, 0, 1, 1, 0);
1405 dev
->radio_tx_rds_tp
= v4l2_ctrl_new_std(hdl_radio_tx
,
1406 &vivid_radio_tx_ctrl_ops
,
1407 V4L2_CID_RDS_TX_TRAFFIC_PROGRAM
, 0, 1, 1, 1);
1408 dev
->radio_tx_rds_ms
= v4l2_ctrl_new_std(hdl_radio_tx
,
1409 &vivid_radio_tx_ctrl_ops
,
1410 V4L2_CID_RDS_TX_MUSIC_SPEECH
, 0, 1, 1, 1);
1412 if (hdl_user_gen
->error
)
1413 return hdl_user_gen
->error
;
1414 if (hdl_user_vid
->error
)
1415 return hdl_user_vid
->error
;
1416 if (hdl_user_aud
->error
)
1417 return hdl_user_aud
->error
;
1418 if (hdl_streaming
->error
)
1419 return hdl_streaming
->error
;
1420 if (hdl_sdr_cap
->error
)
1421 return hdl_sdr_cap
->error
;
1422 if (hdl_loop_out
->error
)
1423 return hdl_loop_out
->error
;
1426 v4l2_ctrl_auto_cluster(2, &dev
->autogain
, 0, true);
1428 if (dev
->has_vid_cap
) {
1429 v4l2_ctrl_add_handler(hdl_vid_cap
, hdl_user_gen
, NULL
);
1430 v4l2_ctrl_add_handler(hdl_vid_cap
, hdl_user_vid
, NULL
);
1431 v4l2_ctrl_add_handler(hdl_vid_cap
, hdl_user_aud
, NULL
);
1432 v4l2_ctrl_add_handler(hdl_vid_cap
, hdl_streaming
, NULL
);
1433 v4l2_ctrl_add_handler(hdl_vid_cap
, hdl_sdtv_cap
, NULL
);
1434 if (hdl_vid_cap
->error
)
1435 return hdl_vid_cap
->error
;
1436 dev
->vid_cap_dev
.ctrl_handler
= hdl_vid_cap
;
1438 if (dev
->has_vid_out
) {
1439 v4l2_ctrl_add_handler(hdl_vid_out
, hdl_user_gen
, NULL
);
1440 v4l2_ctrl_add_handler(hdl_vid_out
, hdl_user_aud
, NULL
);
1441 v4l2_ctrl_add_handler(hdl_vid_out
, hdl_streaming
, NULL
);
1442 v4l2_ctrl_add_handler(hdl_vid_out
, hdl_loop_out
, NULL
);
1443 if (hdl_vid_out
->error
)
1444 return hdl_vid_out
->error
;
1445 dev
->vid_out_dev
.ctrl_handler
= hdl_vid_out
;
1447 if (dev
->has_vbi_cap
) {
1448 v4l2_ctrl_add_handler(hdl_vbi_cap
, hdl_user_gen
, NULL
);
1449 v4l2_ctrl_add_handler(hdl_vbi_cap
, hdl_streaming
, NULL
);
1450 v4l2_ctrl_add_handler(hdl_vbi_cap
, hdl_sdtv_cap
, NULL
);
1451 if (hdl_vbi_cap
->error
)
1452 return hdl_vbi_cap
->error
;
1453 dev
->vbi_cap_dev
.ctrl_handler
= hdl_vbi_cap
;
1455 if (dev
->has_vbi_out
) {
1456 v4l2_ctrl_add_handler(hdl_vbi_out
, hdl_user_gen
, NULL
);
1457 v4l2_ctrl_add_handler(hdl_vbi_out
, hdl_streaming
, NULL
);
1458 v4l2_ctrl_add_handler(hdl_vbi_out
, hdl_loop_out
, NULL
);
1459 if (hdl_vbi_out
->error
)
1460 return hdl_vbi_out
->error
;
1461 dev
->vbi_out_dev
.ctrl_handler
= hdl_vbi_out
;
1463 if (dev
->has_radio_rx
) {
1464 v4l2_ctrl_add_handler(hdl_radio_rx
, hdl_user_gen
, NULL
);
1465 v4l2_ctrl_add_handler(hdl_radio_rx
, hdl_user_aud
, NULL
);
1466 if (hdl_radio_rx
->error
)
1467 return hdl_radio_rx
->error
;
1468 dev
->radio_rx_dev
.ctrl_handler
= hdl_radio_rx
;
1470 if (dev
->has_radio_tx
) {
1471 v4l2_ctrl_add_handler(hdl_radio_tx
, hdl_user_gen
, NULL
);
1472 v4l2_ctrl_add_handler(hdl_radio_tx
, hdl_user_aud
, NULL
);
1473 if (hdl_radio_tx
->error
)
1474 return hdl_radio_tx
->error
;
1475 dev
->radio_tx_dev
.ctrl_handler
= hdl_radio_tx
;
1477 if (dev
->has_sdr_cap
) {
1478 v4l2_ctrl_add_handler(hdl_sdr_cap
, hdl_user_gen
, NULL
);
1479 v4l2_ctrl_add_handler(hdl_sdr_cap
, hdl_streaming
, NULL
);
1480 if (hdl_sdr_cap
->error
)
1481 return hdl_sdr_cap
->error
;
1482 dev
->sdr_cap_dev
.ctrl_handler
= hdl_sdr_cap
;
1487 void vivid_free_controls(struct vivid_dev
*dev
)
1489 v4l2_ctrl_handler_free(&dev
->ctrl_hdl_vid_cap
);
1490 v4l2_ctrl_handler_free(&dev
->ctrl_hdl_vid_out
);
1491 v4l2_ctrl_handler_free(&dev
->ctrl_hdl_vbi_cap
);
1492 v4l2_ctrl_handler_free(&dev
->ctrl_hdl_vbi_out
);
1493 v4l2_ctrl_handler_free(&dev
->ctrl_hdl_radio_rx
);
1494 v4l2_ctrl_handler_free(&dev
->ctrl_hdl_radio_tx
);
1495 v4l2_ctrl_handler_free(&dev
->ctrl_hdl_sdr_cap
);
1496 v4l2_ctrl_handler_free(&dev
->ctrl_hdl_user_gen
);
1497 v4l2_ctrl_handler_free(&dev
->ctrl_hdl_user_vid
);
1498 v4l2_ctrl_handler_free(&dev
->ctrl_hdl_user_aud
);
1499 v4l2_ctrl_handler_free(&dev
->ctrl_hdl_streaming
);
1500 v4l2_ctrl_handler_free(&dev
->ctrl_hdl_sdtv_cap
);
1501 v4l2_ctrl_handler_free(&dev
->ctrl_hdl_loop_out
);