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);
1171 case V4L2_CID_RDS_RECEPTION:
1172 dev->radio_rx_rds_enabled = ctrl->val;
1178 static const struct v4l2_ctrl_ops vivid_radio_rx_ctrl_ops = {
1179 .s_ctrl = vivid_radio_rx_s_ctrl,
1182 static const char * const vivid_ctrl_radio_rds_mode_strings[] = {
1188 static const struct v4l2_ctrl_config vivid_ctrl_radio_rx_rds_blockio = {
1189 .ops = &vivid_radio_rx_ctrl_ops,
1190 .id = VIVID_CID_RADIO_RX_RDS_BLOCKIO,
1191 .name = "RDS Rx I/O Mode",
1192 .type = V4L2_CTRL_TYPE_MENU,
1193 .qmenu = vivid_ctrl_radio_rds_mode_strings,
1197 static const struct v4l2_ctrl_config vivid_ctrl_radio_rx_rds_rbds = {
1198 .ops = &vivid_radio_rx_ctrl_ops,
1199 .id = VIVID_CID_RADIO_RX_RDS_RBDS,
1200 .name = "Generate RBDS Instead of RDS",
1201 .type = V4L2_CTRL_TYPE_BOOLEAN,
1206 static const char * const vivid_ctrl_radio_hw_seek_mode_strings[] = {
1213 static const struct v4l2_ctrl_config vivid_ctrl_radio_hw_seek_mode = {
1214 .ops = &vivid_radio_rx_ctrl_ops,
1215 .id = VIVID_CID_RADIO_SEEK_MODE,
1216 .name = "Radio HW Seek Mode",
1217 .type = V4L2_CTRL_TYPE_MENU,
1219 .qmenu = vivid_ctrl_radio_hw_seek_mode_strings,
1222 static const struct v4l2_ctrl_config vivid_ctrl_radio_hw_seek_prog_lim = {
1223 .ops = &vivid_radio_rx_ctrl_ops,
1224 .id = VIVID_CID_RADIO_SEEK_PROG_LIM,
1225 .name = "Radio Programmable HW Seek",
1226 .type = V4L2_CTRL_TYPE_BOOLEAN,
1232 /* Radio Transmitter Controls */
1234 static int vivid_radio_tx_s_ctrl(struct v4l2_ctrl *ctrl)
1236 struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_radio_tx);
1239 case VIVID_CID_RADIO_TX_RDS_BLOCKIO:
1240 dev->radio_tx_rds_controls = ctrl->val;
1241 dev->radio_tx_caps &= ~V4L2_CAP_READWRITE;
1242 if (!dev->radio_tx_rds_controls)
1243 dev->radio_tx_caps |= V4L2_CAP_READWRITE;
1245 case V4L2_CID_RDS_TX_PTY:
1246 if (dev->radio_rx_rds_controls)
1247 v4l2_ctrl_s_ctrl(dev->radio_rx_rds_pty, ctrl->val);
1249 case V4L2_CID_RDS_TX_PS_NAME:
1250 if (dev->radio_rx_rds_controls)
1251 v4l2_ctrl_s_ctrl_string(dev->radio_rx_rds_psname, ctrl->p_new.p_char);
1253 case V4L2_CID_RDS_TX_RADIO_TEXT:
1254 if (dev->radio_rx_rds_controls)
1255 v4l2_ctrl_s_ctrl_string(dev->radio_rx_rds_radiotext, ctrl->p_new.p_char);
1257 case V4L2_CID_RDS_TX_TRAFFIC_ANNOUNCEMENT:
1258 if (dev->radio_rx_rds_controls)
1259 v4l2_ctrl_s_ctrl(dev->radio_rx_rds_ta, ctrl->val);
1261 case V4L2_CID_RDS_TX_TRAFFIC_PROGRAM:
1262 if (dev->radio_rx_rds_controls)
1263 v4l2_ctrl_s_ctrl(dev->radio_rx_rds_tp, ctrl->val);
1265 case V4L2_CID_RDS_TX_MUSIC_SPEECH:
1266 if (dev->radio_rx_rds_controls)
1267 v4l2_ctrl_s_ctrl(dev->radio_rx_rds_ms, ctrl->val);
1273 static const struct v4l2_ctrl_ops vivid_radio_tx_ctrl_ops = {
1274 .s_ctrl = vivid_radio_tx_s_ctrl,
1277 static const struct v4l2_ctrl_config vivid_ctrl_radio_tx_rds_blockio = {
1278 .ops = &vivid_radio_tx_ctrl_ops,
1279 .id = VIVID_CID_RADIO_TX_RDS_BLOCKIO,
1280 .name = "RDS Tx I/O Mode",
1281 .type = V4L2_CTRL_TYPE_MENU,
1282 .qmenu = vivid_ctrl_radio_rds_mode_strings,
1288 /* SDR Capture Controls */
1290 static int vivid_sdr_cap_s_ctrl(struct v4l2_ctrl *ctrl)
1292 struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_sdr_cap);
1295 case VIVID_CID_SDR_CAP_FM_DEVIATION:
1296 dev->sdr_fm_deviation = ctrl->val;
1302 static const struct v4l2_ctrl_ops vivid_sdr_cap_ctrl_ops = {
1303 .s_ctrl = vivid_sdr_cap_s_ctrl,
1306 static const struct v4l2_ctrl_config vivid_ctrl_sdr_cap_fm_deviation = {
1307 .ops = &vivid_sdr_cap_ctrl_ops,
1308 .id = VIVID_CID_SDR_CAP_FM_DEVIATION,
1309 .name = "FM Deviation",
1310 .type = V4L2_CTRL_TYPE_INTEGER,
1318 static const struct v4l2_ctrl_config vivid_ctrl_class = {
1319 .ops = &vivid_user_gen_ctrl_ops,
1320 .flags = V4L2_CTRL_FLAG_READ_ONLY | V4L2_CTRL_FLAG_WRITE_ONLY,
1321 .id = VIVID_CID_VIVID_CLASS,
1322 .name = "Vivid Controls",
1323 .type = V4L2_CTRL_TYPE_CTRL_CLASS,
1326 int vivid_create_controls(struct vivid_dev *dev, bool show_ccs_cap,
1327 bool show_ccs_out, bool no_error_inj,
1328 bool has_sdtv, bool has_hdmi)
1330 struct v4l2_ctrl_handler *hdl_user_gen = &dev->ctrl_hdl_user_gen;
1331 struct v4l2_ctrl_handler *hdl_user_vid = &dev->ctrl_hdl_user_vid;
1332 struct v4l2_ctrl_handler *hdl_user_aud = &dev->ctrl_hdl_user_aud;
1333 struct v4l2_ctrl_handler *hdl_streaming = &dev->ctrl_hdl_streaming;
1334 struct v4l2_ctrl_handler *hdl_sdtv_cap = &dev->ctrl_hdl_sdtv_cap;
1335 struct v4l2_ctrl_handler *hdl_loop_cap = &dev->ctrl_hdl_loop_cap;
1336 struct v4l2_ctrl_handler *hdl_vid_cap = &dev->ctrl_hdl_vid_cap;
1337 struct v4l2_ctrl_handler *hdl_vid_out = &dev->ctrl_hdl_vid_out;
1338 struct v4l2_ctrl_handler *hdl_vbi_cap = &dev->ctrl_hdl_vbi_cap;
1339 struct v4l2_ctrl_handler *hdl_vbi_out = &dev->ctrl_hdl_vbi_out;
1340 struct v4l2_ctrl_handler *hdl_radio_rx = &dev->ctrl_hdl_radio_rx;
1341 struct v4l2_ctrl_handler *hdl_radio_tx = &dev->ctrl_hdl_radio_tx;
1342 struct v4l2_ctrl_handler *hdl_sdr_cap = &dev->ctrl_hdl_sdr_cap;
1343 struct v4l2_ctrl_config vivid_ctrl_dv_timings = {
1344 .ops = &vivid_vid_cap_ctrl_ops,
1345 .id = VIVID_CID_DV_TIMINGS,
1346 .name = "DV Timings",
1347 .type = V4L2_CTRL_TYPE_MENU,
1351 v4l2_ctrl_handler_init(hdl_user_gen, 10);
1352 v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_class, NULL);
1353 v4l2_ctrl_handler_init(hdl_user_vid, 9);
1354 v4l2_ctrl_new_custom(hdl_user_vid, &vivid_ctrl_class, NULL);
1355 v4l2_ctrl_handler_init(hdl_user_aud, 2);
1356 v4l2_ctrl_new_custom(hdl_user_aud, &vivid_ctrl_class, NULL);
1357 v4l2_ctrl_handler_init(hdl_streaming, 8);
1358 v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_class, NULL);
1359 v4l2_ctrl_handler_init(hdl_sdtv_cap, 2);
1360 v4l2_ctrl_new_custom(hdl_sdtv_cap, &vivid_ctrl_class, NULL);
1361 v4l2_ctrl_handler_init(hdl_loop_cap, 1);
1362 v4l2_ctrl_new_custom(hdl_loop_cap, &vivid_ctrl_class, NULL);
1363 v4l2_ctrl_handler_init(hdl_vid_cap, 55);
1364 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_class, NULL);
1365 v4l2_ctrl_handler_init(hdl_vid_out, 26);
1367 v4l2_ctrl_new_custom(hdl_vid_out, &vivid_ctrl_class, NULL);
1368 v4l2_ctrl_handler_init(hdl_vbi_cap, 21);
1369 v4l2_ctrl_new_custom(hdl_vbi_cap, &vivid_ctrl_class, NULL);
1370 v4l2_ctrl_handler_init(hdl_vbi_out, 19);
1372 v4l2_ctrl_new_custom(hdl_vbi_out, &vivid_ctrl_class, NULL);
1373 v4l2_ctrl_handler_init(hdl_radio_rx, 17);
1374 v4l2_ctrl_new_custom(hdl_radio_rx, &vivid_ctrl_class, NULL);
1375 v4l2_ctrl_handler_init(hdl_radio_tx, 17);
1376 v4l2_ctrl_new_custom(hdl_radio_tx, &vivid_ctrl_class, NULL);
1377 v4l2_ctrl_handler_init(hdl_sdr_cap, 19);
1378 v4l2_ctrl_new_custom(hdl_sdr_cap, &vivid_ctrl_class, NULL);
1381 dev->volume = v4l2_ctrl_new_std(hdl_user_aud, NULL,
1382 V4L2_CID_AUDIO_VOLUME, 0, 255, 1, 200);
1383 dev->mute = v4l2_ctrl_new_std(hdl_user_aud, NULL,
1384 V4L2_CID_AUDIO_MUTE, 0, 1, 1, 0);
1385 if (dev->has_vid_cap) {
1386 dev->brightness = v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops,
1387 V4L2_CID_BRIGHTNESS, 0, 255, 1, 128);
1388 for (i = 0; i < MAX_INPUTS; i++)
1389 dev->input_brightness[i] = 128;
1390 dev->contrast = v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops,
1391 V4L2_CID_CONTRAST, 0, 255, 1, 128);
1392 dev->saturation = v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops,
1393 V4L2_CID_SATURATION, 0, 255, 1, 128);
1394 dev->hue = v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops,
1395 V4L2_CID_HUE, -128, 128, 1, 0);
1396 v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops,
1397 V4L2_CID_HFLIP, 0, 1, 1, 0);
1398 v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops,
1399 V4L2_CID_VFLIP, 0, 1, 1, 0);
1400 dev->autogain = v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops,
1401 V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
1402 dev->gain = v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops,
1403 V4L2_CID_GAIN, 0, 255, 1, 100);
1404 dev->alpha = v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops,
1405 V4L2_CID_ALPHA_COMPONENT, 0, 255, 1, 0);
1407 dev->button = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_button, NULL);
1408 dev->int32 = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_int32, NULL);
1409 dev->int64 = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_int64, NULL);
1410 dev->boolean = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_boolean, NULL);
1411 dev->menu = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_menu, NULL);
1412 dev->string = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_string, NULL);
1413 dev->bitmask = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_bitmask, NULL);
1414 dev->int_menu = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_int_menu, NULL);
1415 v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_u32_array, NULL);
1416 v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_u16_matrix, NULL);
1417 v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_u8_4d_array, NULL);
1419 if (dev->has_vid_cap) {
1420 /* Image Processing Controls */
1421 struct v4l2_ctrl_config vivid_ctrl_test_pattern = {
1422 .ops = &vivid_vid_cap_ctrl_ops,
1423 .id = VIVID_CID_TEST_PATTERN,
1424 .name = "Test Pattern",
1425 .type = V4L2_CTRL_TYPE_MENU,
1426 .max = TPG_PAT_NOISE,
1427 .qmenu = tpg_pattern_strings,
1430 dev->test_pattern = v4l2_ctrl_new_custom(hdl_vid_cap,
1431 &vivid_ctrl_test_pattern, NULL);
1432 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_perc_fill, NULL);
1433 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_hor_movement, NULL);
1434 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_vert_movement, NULL);
1435 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_osd_mode, NULL);
1436 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_show_border, NULL);
1437 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_show_square, NULL);
1438 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_hflip, NULL);
1439 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_vflip, NULL);
1440 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_insert_sav, NULL);
1441 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_insert_eav, NULL);
1442 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_reduced_fps, NULL);
1444 dev->ctrl_has_crop_cap = v4l2_ctrl_new_custom(hdl_vid_cap,
1445 &vivid_ctrl_has_crop_cap, NULL);
1446 dev->ctrl_has_compose_cap = v4l2_ctrl_new_custom(hdl_vid_cap,
1447 &vivid_ctrl_has_compose_cap, NULL);
1448 dev->ctrl_has_scaler_cap = v4l2_ctrl_new_custom(hdl_vid_cap,
1449 &vivid_ctrl_has_scaler_cap, NULL);
1452 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_tstamp_src, NULL);
1453 dev->colorspace = v4l2_ctrl_new_custom(hdl_vid_cap,
1454 &vivid_ctrl_colorspace, NULL);
1455 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_xfer_func, NULL);
1456 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_ycbcr_enc, NULL);
1457 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_quantization, NULL);
1458 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_alpha_mode, NULL);
1461 if (dev->has_vid_out && show_ccs_out) {
1462 dev->ctrl_has_crop_out = v4l2_ctrl_new_custom(hdl_vid_out,
1463 &vivid_ctrl_has_crop_out, NULL);
1464 dev->ctrl_has_compose_out = v4l2_ctrl_new_custom(hdl_vid_out,
1465 &vivid_ctrl_has_compose_out, NULL);
1466 dev->ctrl_has_scaler_out = v4l2_ctrl_new_custom(hdl_vid_out,
1467 &vivid_ctrl_has_scaler_out, NULL);
1471 * Testing this driver with v4l2-compliance will trigger the error
1472 * injection controls, and after that nothing will work as expected.
1473 * So we have a module option to drop these error injecting controls
1474 * allowing us to run v4l2_compliance again.
1476 if (!no_error_inj) {
1477 v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_disconnect, NULL);
1478 v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_dqbuf_error, NULL);
1479 v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_perc_dropped, NULL);
1480 v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_queue_setup_error, NULL);
1481 v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_buf_prepare_error, NULL);
1482 v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_start_streaming_error, NULL);
1483 v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_queue_error, NULL);
1484 v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_seq_wrap, NULL);
1485 v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_time_wrap, NULL);
1488 if (has_sdtv && (dev->has_vid_cap || dev->has_vbi_cap)) {
1489 if (dev->has_vid_cap)
1490 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_std_aspect_ratio, NULL);
1491 dev->ctrl_std_signal_mode = v4l2_ctrl_new_custom(hdl_sdtv_cap,
1492 &vivid_ctrl_std_signal_mode, NULL);
1493 dev->ctrl_standard = v4l2_ctrl_new_custom(hdl_sdtv_cap,
1494 &vivid_ctrl_standard, NULL);
1495 if (dev->ctrl_std_signal_mode)
1496 v4l2_ctrl_cluster(2, &dev->ctrl_std_signal_mode);
1497 if (dev->has_raw_vbi_cap)
1498 v4l2_ctrl_new_custom(hdl_vbi_cap, &vivid_ctrl_vbi_cap_interlaced, NULL);
1501 if (has_hdmi && dev->has_vid_cap) {
1502 dev->ctrl_dv_timings_signal_mode = v4l2_ctrl_new_custom(hdl_vid_cap,
1503 &vivid_ctrl_dv_timings_signal_mode, NULL);
1505 vivid_ctrl_dv_timings.max = dev->query_dv_timings_size - 1;
1506 vivid_ctrl_dv_timings.qmenu =
1507 (const char * const *)dev->query_dv_timings_qmenu;
1508 dev->ctrl_dv_timings = v4l2_ctrl_new_custom(hdl_vid_cap,
1509 &vivid_ctrl_dv_timings, NULL);
1510 if (dev->ctrl_dv_timings_signal_mode)
1511 v4l2_ctrl_cluster(2, &dev->ctrl_dv_timings_signal_mode);
1513 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_dv_timings_aspect_ratio, NULL);
1514 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_max_edid_blocks, NULL);
1515 dev->real_rgb_range_cap = v4l2_ctrl_new_custom(hdl_vid_cap,
1516 &vivid_ctrl_limited_rgb_range, NULL);
1517 dev->rgb_range_cap = v4l2_ctrl_new_std_menu(hdl_vid_cap,
1518 &vivid_vid_cap_ctrl_ops,
1519 V4L2_CID_DV_RX_RGB_RANGE, V4L2_DV_RGB_RANGE_FULL,
1520 0, V4L2_DV_RGB_RANGE_AUTO);
1522 if (has_hdmi && dev->has_vid_out) {
1524 * We aren't doing anything with this at the moment, but
1525 * HDMI outputs typically have this controls.
1527 dev->ctrl_tx_rgb_range = v4l2_ctrl_new_std_menu(hdl_vid_out, NULL,
1528 V4L2_CID_DV_TX_RGB_RANGE, V4L2_DV_RGB_RANGE_FULL,
1529 0, V4L2_DV_RGB_RANGE_AUTO);
1530 dev->ctrl_tx_mode = v4l2_ctrl_new_std_menu(hdl_vid_out, NULL,
1531 V4L2_CID_DV_TX_MODE, V4L2_DV_TX_MODE_HDMI,
1532 0, V4L2_DV_TX_MODE_HDMI);
1534 if ((dev->has_vid_cap && dev->has_vid_out) ||
1535 (dev->has_vbi_cap && dev->has_vbi_out))
1536 v4l2_ctrl_new_custom(hdl_loop_cap, &vivid_ctrl_loop_video, NULL);
1539 v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_clear_fb, NULL);
1541 if (dev->has_radio_rx) {
1542 v4l2_ctrl_new_custom(hdl_radio_rx, &vivid_ctrl_radio_hw_seek_mode, NULL);
1543 v4l2_ctrl_new_custom(hdl_radio_rx, &vivid_ctrl_radio_hw_seek_prog_lim, NULL);
1544 v4l2_ctrl_new_custom(hdl_radio_rx, &vivid_ctrl_radio_rx_rds_blockio, NULL);
1545 v4l2_ctrl_new_custom(hdl_radio_rx, &vivid_ctrl_radio_rx_rds_rbds, NULL);
1546 v4l2_ctrl_new_std(hdl_radio_rx, &vivid_radio_rx_ctrl_ops,
1547 V4L2_CID_RDS_RECEPTION, 0, 1, 1, 1);
1548 dev->radio_rx_rds_pty = v4l2_ctrl_new_std(hdl_radio_rx,
1549 &vivid_radio_rx_ctrl_ops,
1550 V4L2_CID_RDS_RX_PTY, 0, 31, 1, 0);
1551 dev->radio_rx_rds_psname = v4l2_ctrl_new_std(hdl_radio_rx,
1552 &vivid_radio_rx_ctrl_ops,
1553 V4L2_CID_RDS_RX_PS_NAME, 0, 8, 8, 0);
1554 dev->radio_rx_rds_radiotext = v4l2_ctrl_new_std(hdl_radio_rx,
1555 &vivid_radio_rx_ctrl_ops,
1556 V4L2_CID_RDS_RX_RADIO_TEXT, 0, 64, 64, 0);
1557 dev->radio_rx_rds_ta = v4l2_ctrl_new_std(hdl_radio_rx,
1558 &vivid_radio_rx_ctrl_ops,
1559 V4L2_CID_RDS_RX_TRAFFIC_ANNOUNCEMENT, 0, 1, 1, 0);
1560 dev->radio_rx_rds_tp = v4l2_ctrl_new_std(hdl_radio_rx,
1561 &vivid_radio_rx_ctrl_ops,
1562 V4L2_CID_RDS_RX_TRAFFIC_PROGRAM, 0, 1, 1, 0);
1563 dev->radio_rx_rds_ms = v4l2_ctrl_new_std(hdl_radio_rx,
1564 &vivid_radio_rx_ctrl_ops,
1565 V4L2_CID_RDS_RX_MUSIC_SPEECH, 0, 1, 1, 1);
1567 if (dev->has_radio_tx) {
1568 v4l2_ctrl_new_custom(hdl_radio_tx,
1569 &vivid_ctrl_radio_tx_rds_blockio, NULL);
1570 dev->radio_tx_rds_pi = v4l2_ctrl_new_std(hdl_radio_tx,
1571 &vivid_radio_tx_ctrl_ops,
1572 V4L2_CID_RDS_TX_PI, 0, 0xffff, 1, 0x8088);
1573 dev->radio_tx_rds_pty = v4l2_ctrl_new_std(hdl_radio_tx,
1574 &vivid_radio_tx_ctrl_ops,
1575 V4L2_CID_RDS_TX_PTY, 0, 31, 1, 3);
1576 dev->radio_tx_rds_psname = v4l2_ctrl_new_std(hdl_radio_tx,
1577 &vivid_radio_tx_ctrl_ops,
1578 V4L2_CID_RDS_TX_PS_NAME, 0, 8, 8, 0);
1579 if (dev->radio_tx_rds_psname)
1580 v4l2_ctrl_s_ctrl_string(dev->radio_tx_rds_psname, "VIVID-TX");
1581 dev->radio_tx_rds_radiotext = v4l2_ctrl_new_std(hdl_radio_tx,
1582 &vivid_radio_tx_ctrl_ops,
1583 V4L2_CID_RDS_TX_RADIO_TEXT, 0, 64 * 2, 64, 0);
1584 if (dev->radio_tx_rds_radiotext)
1585 v4l2_ctrl_s_ctrl_string(dev->radio_tx_rds_radiotext,
1586 "This is a VIVID default Radio Text template text, change at will");
1587 dev->radio_tx_rds_mono_stereo = v4l2_ctrl_new_std(hdl_radio_tx,
1588 &vivid_radio_tx_ctrl_ops,
1589 V4L2_CID_RDS_TX_MONO_STEREO, 0, 1, 1, 1);
1590 dev->radio_tx_rds_art_head = v4l2_ctrl_new_std(hdl_radio_tx,
1591 &vivid_radio_tx_ctrl_ops,
1592 V4L2_CID_RDS_TX_ARTIFICIAL_HEAD, 0, 1, 1, 0);
1593 dev->radio_tx_rds_compressed = v4l2_ctrl_new_std(hdl_radio_tx,
1594 &vivid_radio_tx_ctrl_ops,
1595 V4L2_CID_RDS_TX_COMPRESSED, 0, 1, 1, 0);
1596 dev->radio_tx_rds_dyn_pty = v4l2_ctrl_new_std(hdl_radio_tx,
1597 &vivid_radio_tx_ctrl_ops,
1598 V4L2_CID_RDS_TX_DYNAMIC_PTY, 0, 1, 1, 0);
1599 dev->radio_tx_rds_ta = v4l2_ctrl_new_std(hdl_radio_tx,
1600 &vivid_radio_tx_ctrl_ops,
1601 V4L2_CID_RDS_TX_TRAFFIC_ANNOUNCEMENT, 0, 1, 1, 0);
1602 dev->radio_tx_rds_tp = v4l2_ctrl_new_std(hdl_radio_tx,
1603 &vivid_radio_tx_ctrl_ops,
1604 V4L2_CID_RDS_TX_TRAFFIC_PROGRAM, 0, 1, 1, 1);
1605 dev->radio_tx_rds_ms = v4l2_ctrl_new_std(hdl_radio_tx,
1606 &vivid_radio_tx_ctrl_ops,
1607 V4L2_CID_RDS_TX_MUSIC_SPEECH, 0, 1, 1, 1);
1609 if (dev->has_sdr_cap) {
1610 v4l2_ctrl_new_custom(hdl_sdr_cap,
1611 &vivid_ctrl_sdr_cap_fm_deviation, NULL);
1613 if (hdl_user_gen->error)
1614 return hdl_user_gen->error;
1615 if (hdl_user_vid->error)
1616 return hdl_user_vid->error;
1617 if (hdl_user_aud->error)
1618 return hdl_user_aud->error;
1619 if (hdl_streaming->error)
1620 return hdl_streaming->error;
1621 if (hdl_sdr_cap->error)
1622 return hdl_sdr_cap->error;
1623 if (hdl_loop_cap->error)
1624 return hdl_loop_cap->error;
1627 v4l2_ctrl_auto_cluster(2, &dev->autogain, 0, true);
1629 if (dev->has_vid_cap) {
1630 v4l2_ctrl_add_handler(hdl_vid_cap, hdl_user_gen, NULL);
1631 v4l2_ctrl_add_handler(hdl_vid_cap, hdl_user_vid, NULL);
1632 v4l2_ctrl_add_handler(hdl_vid_cap, hdl_user_aud, NULL);
1633 v4l2_ctrl_add_handler(hdl_vid_cap, hdl_streaming, NULL);
1634 v4l2_ctrl_add_handler(hdl_vid_cap, hdl_sdtv_cap, NULL);
1635 v4l2_ctrl_add_handler(hdl_vid_cap, hdl_loop_cap, NULL);
1636 if (hdl_vid_cap->error)
1637 return hdl_vid_cap->error;
1638 dev->vid_cap_dev.ctrl_handler = hdl_vid_cap;
1640 if (dev->has_vid_out) {
1641 v4l2_ctrl_add_handler(hdl_vid_out, hdl_user_gen, NULL);
1642 v4l2_ctrl_add_handler(hdl_vid_out, hdl_user_aud, NULL);
1643 v4l2_ctrl_add_handler(hdl_vid_out, hdl_streaming, NULL);
1644 if (hdl_vid_out->error)
1645 return hdl_vid_out->error;
1646 dev->vid_out_dev.ctrl_handler = hdl_vid_out;
1648 if (dev->has_vbi_cap) {
1649 v4l2_ctrl_add_handler(hdl_vbi_cap, hdl_user_gen, NULL);
1650 v4l2_ctrl_add_handler(hdl_vbi_cap, hdl_streaming, NULL);
1651 v4l2_ctrl_add_handler(hdl_vbi_cap, hdl_sdtv_cap, NULL);
1652 v4l2_ctrl_add_handler(hdl_vbi_cap, hdl_loop_cap, NULL);
1653 if (hdl_vbi_cap->error)
1654 return hdl_vbi_cap->error;
1655 dev->vbi_cap_dev.ctrl_handler = hdl_vbi_cap;
1657 if (dev->has_vbi_out) {
1658 v4l2_ctrl_add_handler(hdl_vbi_out, hdl_user_gen, NULL);
1659 v4l2_ctrl_add_handler(hdl_vbi_out, hdl_streaming, NULL);
1660 if (hdl_vbi_out->error)
1661 return hdl_vbi_out->error;
1662 dev->vbi_out_dev.ctrl_handler = hdl_vbi_out;
1664 if (dev->has_radio_rx) {
1665 v4l2_ctrl_add_handler(hdl_radio_rx, hdl_user_gen, NULL);
1666 v4l2_ctrl_add_handler(hdl_radio_rx, hdl_user_aud, NULL);
1667 if (hdl_radio_rx->error)
1668 return hdl_radio_rx->error;
1669 dev->radio_rx_dev.ctrl_handler = hdl_radio_rx;
1671 if (dev->has_radio_tx) {
1672 v4l2_ctrl_add_handler(hdl_radio_tx, hdl_user_gen, NULL);
1673 v4l2_ctrl_add_handler(hdl_radio_tx, hdl_user_aud, NULL);
1674 if (hdl_radio_tx->error)
1675 return hdl_radio_tx->error;
1676 dev->radio_tx_dev.ctrl_handler = hdl_radio_tx;
1678 if (dev->has_sdr_cap) {
1679 v4l2_ctrl_add_handler(hdl_sdr_cap, hdl_user_gen, NULL);
1680 v4l2_ctrl_add_handler(hdl_sdr_cap, hdl_streaming, NULL);
1681 if (hdl_sdr_cap->error)
1682 return hdl_sdr_cap->error;
1683 dev->sdr_cap_dev.ctrl_handler = hdl_sdr_cap;
1688 void vivid_free_controls(struct vivid_dev *dev)
1690 v4l2_ctrl_handler_free(&dev->ctrl_hdl_vid_cap);
1691 v4l2_ctrl_handler_free(&dev->ctrl_hdl_vid_out);
1692 v4l2_ctrl_handler_free(&dev->ctrl_hdl_vbi_cap);
1693 v4l2_ctrl_handler_free(&dev->ctrl_hdl_vbi_out);
1694 v4l2_ctrl_handler_free(&dev->ctrl_hdl_radio_rx);
1695 v4l2_ctrl_handler_free(&dev->ctrl_hdl_radio_tx);
1696 v4l2_ctrl_handler_free(&dev->ctrl_hdl_sdr_cap);
1697 v4l2_ctrl_handler_free(&dev->ctrl_hdl_user_gen);
1698 v4l2_ctrl_handler_free(&dev->ctrl_hdl_user_vid);
1699 v4l2_ctrl_handler_free(&dev->ctrl_hdl_user_aud);
1700 v4l2_ctrl_handler_free(&dev->ctrl_hdl_streaming);
1701 v4l2_ctrl_handler_free(&dev->ctrl_hdl_sdtv_cap);
1702 v4l2_ctrl_handler_free(&dev->ctrl_hdl_loop_cap);