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);