sh_eth: fix EESIPR values for SH77{34|63}
[linux/fpc-iii.git] / drivers / media / platform / vivid / vivid-ctrls.c
blob34731f71cc0077f4e66bb344c2e6737833e8b44e
1 /*
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
17 * SOFTWARE.
20 #include <linux/errno.h>
21 #include <linux/kernel.h>
22 #include <linux/videodev2.h>
23 #include <media/v4l2-event.h>
24 #include <media/v4l2-common.h>
26 #include "vivid-core.h"
27 #include "vivid-vid-cap.h"
28 #include "vivid-vid-out.h"
29 #include "vivid-vid-common.h"
30 #include "vivid-radio-common.h"
31 #include "vivid-osd.h"
32 #include "vivid-ctrls.h"
34 #define VIVID_CID_CUSTOM_BASE (V4L2_CID_USER_BASE | 0xf000)
35 #define VIVID_CID_BUTTON (VIVID_CID_CUSTOM_BASE + 0)
36 #define VIVID_CID_BOOLEAN (VIVID_CID_CUSTOM_BASE + 1)
37 #define VIVID_CID_INTEGER (VIVID_CID_CUSTOM_BASE + 2)
38 #define VIVID_CID_INTEGER64 (VIVID_CID_CUSTOM_BASE + 3)
39 #define VIVID_CID_MENU (VIVID_CID_CUSTOM_BASE + 4)
40 #define VIVID_CID_STRING (VIVID_CID_CUSTOM_BASE + 5)
41 #define VIVID_CID_BITMASK (VIVID_CID_CUSTOM_BASE + 6)
42 #define VIVID_CID_INTMENU (VIVID_CID_CUSTOM_BASE + 7)
43 #define VIVID_CID_U32_ARRAY (VIVID_CID_CUSTOM_BASE + 8)
44 #define VIVID_CID_U16_MATRIX (VIVID_CID_CUSTOM_BASE + 9)
45 #define VIVID_CID_U8_4D_ARRAY (VIVID_CID_CUSTOM_BASE + 10)
47 #define VIVID_CID_VIVID_BASE (0x00f00000 | 0xf000)
48 #define VIVID_CID_VIVID_CLASS (0x00f00000 | 1)
49 #define VIVID_CID_TEST_PATTERN (VIVID_CID_VIVID_BASE + 0)
50 #define VIVID_CID_OSD_TEXT_MODE (VIVID_CID_VIVID_BASE + 1)
51 #define VIVID_CID_HOR_MOVEMENT (VIVID_CID_VIVID_BASE + 2)
52 #define VIVID_CID_VERT_MOVEMENT (VIVID_CID_VIVID_BASE + 3)
53 #define VIVID_CID_SHOW_BORDER (VIVID_CID_VIVID_BASE + 4)
54 #define VIVID_CID_SHOW_SQUARE (VIVID_CID_VIVID_BASE + 5)
55 #define VIVID_CID_INSERT_SAV (VIVID_CID_VIVID_BASE + 6)
56 #define VIVID_CID_INSERT_EAV (VIVID_CID_VIVID_BASE + 7)
57 #define VIVID_CID_VBI_CAP_INTERLACED (VIVID_CID_VIVID_BASE + 8)
59 #define VIVID_CID_HFLIP (VIVID_CID_VIVID_BASE + 20)
60 #define VIVID_CID_VFLIP (VIVID_CID_VIVID_BASE + 21)
61 #define VIVID_CID_STD_ASPECT_RATIO (VIVID_CID_VIVID_BASE + 22)
62 #define VIVID_CID_DV_TIMINGS_ASPECT_RATIO (VIVID_CID_VIVID_BASE + 23)
63 #define VIVID_CID_TSTAMP_SRC (VIVID_CID_VIVID_BASE + 24)
64 #define VIVID_CID_COLORSPACE (VIVID_CID_VIVID_BASE + 25)
65 #define VIVID_CID_XFER_FUNC (VIVID_CID_VIVID_BASE + 26)
66 #define VIVID_CID_YCBCR_ENC (VIVID_CID_VIVID_BASE + 27)
67 #define VIVID_CID_QUANTIZATION (VIVID_CID_VIVID_BASE + 28)
68 #define VIVID_CID_LIMITED_RGB_RANGE (VIVID_CID_VIVID_BASE + 29)
69 #define VIVID_CID_ALPHA_MODE (VIVID_CID_VIVID_BASE + 30)
70 #define VIVID_CID_HAS_CROP_CAP (VIVID_CID_VIVID_BASE + 31)
71 #define VIVID_CID_HAS_COMPOSE_CAP (VIVID_CID_VIVID_BASE + 32)
72 #define VIVID_CID_HAS_SCALER_CAP (VIVID_CID_VIVID_BASE + 33)
73 #define VIVID_CID_HAS_CROP_OUT (VIVID_CID_VIVID_BASE + 34)
74 #define VIVID_CID_HAS_COMPOSE_OUT (VIVID_CID_VIVID_BASE + 35)
75 #define VIVID_CID_HAS_SCALER_OUT (VIVID_CID_VIVID_BASE + 36)
76 #define VIVID_CID_LOOP_VIDEO (VIVID_CID_VIVID_BASE + 37)
77 #define VIVID_CID_SEQ_WRAP (VIVID_CID_VIVID_BASE + 38)
78 #define VIVID_CID_TIME_WRAP (VIVID_CID_VIVID_BASE + 39)
79 #define VIVID_CID_MAX_EDID_BLOCKS (VIVID_CID_VIVID_BASE + 40)
80 #define VIVID_CID_PERCENTAGE_FILL (VIVID_CID_VIVID_BASE + 41)
81 #define VIVID_CID_REDUCED_FPS (VIVID_CID_VIVID_BASE + 42)
82 #define VIVID_CID_HSV_ENC (VIVID_CID_VIVID_BASE + 43)
84 #define VIVID_CID_STD_SIGNAL_MODE (VIVID_CID_VIVID_BASE + 60)
85 #define VIVID_CID_STANDARD (VIVID_CID_VIVID_BASE + 61)
86 #define VIVID_CID_DV_TIMINGS_SIGNAL_MODE (VIVID_CID_VIVID_BASE + 62)
87 #define VIVID_CID_DV_TIMINGS (VIVID_CID_VIVID_BASE + 63)
88 #define VIVID_CID_PERC_DROPPED (VIVID_CID_VIVID_BASE + 64)
89 #define VIVID_CID_DISCONNECT (VIVID_CID_VIVID_BASE + 65)
90 #define VIVID_CID_DQBUF_ERROR (VIVID_CID_VIVID_BASE + 66)
91 #define VIVID_CID_QUEUE_SETUP_ERROR (VIVID_CID_VIVID_BASE + 67)
92 #define VIVID_CID_BUF_PREPARE_ERROR (VIVID_CID_VIVID_BASE + 68)
93 #define VIVID_CID_START_STR_ERROR (VIVID_CID_VIVID_BASE + 69)
94 #define VIVID_CID_QUEUE_ERROR (VIVID_CID_VIVID_BASE + 70)
95 #define VIVID_CID_CLEAR_FB (VIVID_CID_VIVID_BASE + 71)
97 #define VIVID_CID_RADIO_SEEK_MODE (VIVID_CID_VIVID_BASE + 90)
98 #define VIVID_CID_RADIO_SEEK_PROG_LIM (VIVID_CID_VIVID_BASE + 91)
99 #define VIVID_CID_RADIO_RX_RDS_RBDS (VIVID_CID_VIVID_BASE + 92)
100 #define VIVID_CID_RADIO_RX_RDS_BLOCKIO (VIVID_CID_VIVID_BASE + 93)
102 #define VIVID_CID_RADIO_TX_RDS_BLOCKIO (VIVID_CID_VIVID_BASE + 94)
104 #define VIVID_CID_SDR_CAP_FM_DEVIATION (VIVID_CID_VIVID_BASE + 110)
106 /* General User Controls */
108 static int vivid_user_gen_s_ctrl(struct v4l2_ctrl *ctrl)
110 struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_user_gen);
112 switch (ctrl->id) {
113 case VIVID_CID_DISCONNECT:
114 v4l2_info(&dev->v4l2_dev, "disconnect\n");
115 clear_bit(V4L2_FL_REGISTERED, &dev->vid_cap_dev.flags);
116 clear_bit(V4L2_FL_REGISTERED, &dev->vid_out_dev.flags);
117 clear_bit(V4L2_FL_REGISTERED, &dev->vbi_cap_dev.flags);
118 clear_bit(V4L2_FL_REGISTERED, &dev->vbi_out_dev.flags);
119 clear_bit(V4L2_FL_REGISTERED, &dev->sdr_cap_dev.flags);
120 clear_bit(V4L2_FL_REGISTERED, &dev->radio_rx_dev.flags);
121 clear_bit(V4L2_FL_REGISTERED, &dev->radio_tx_dev.flags);
122 break;
123 case VIVID_CID_CLEAR_FB:
124 vivid_clear_fb(dev);
125 break;
126 case VIVID_CID_BUTTON:
127 dev->button_pressed = 30;
128 break;
130 return 0;
133 static const struct v4l2_ctrl_ops vivid_user_gen_ctrl_ops = {
134 .s_ctrl = vivid_user_gen_s_ctrl,
137 static const struct v4l2_ctrl_config vivid_ctrl_button = {
138 .ops = &vivid_user_gen_ctrl_ops,
139 .id = VIVID_CID_BUTTON,
140 .name = "Button",
141 .type = V4L2_CTRL_TYPE_BUTTON,
144 static const struct v4l2_ctrl_config vivid_ctrl_boolean = {
145 .ops = &vivid_user_gen_ctrl_ops,
146 .id = VIVID_CID_BOOLEAN,
147 .name = "Boolean",
148 .type = V4L2_CTRL_TYPE_BOOLEAN,
149 .min = 0,
150 .max = 1,
151 .step = 1,
152 .def = 1,
155 static const struct v4l2_ctrl_config vivid_ctrl_int32 = {
156 .ops = &vivid_user_gen_ctrl_ops,
157 .id = VIVID_CID_INTEGER,
158 .name = "Integer 32 Bits",
159 .type = V4L2_CTRL_TYPE_INTEGER,
160 .min = 0xffffffff80000000ULL,
161 .max = 0x7fffffff,
162 .step = 1,
165 static const struct v4l2_ctrl_config vivid_ctrl_int64 = {
166 .ops = &vivid_user_gen_ctrl_ops,
167 .id = VIVID_CID_INTEGER64,
168 .name = "Integer 64 Bits",
169 .type = V4L2_CTRL_TYPE_INTEGER64,
170 .min = 0x8000000000000000ULL,
171 .max = 0x7fffffffffffffffLL,
172 .step = 1,
175 static const struct v4l2_ctrl_config vivid_ctrl_u32_array = {
176 .ops = &vivid_user_gen_ctrl_ops,
177 .id = VIVID_CID_U32_ARRAY,
178 .name = "U32 1 Element Array",
179 .type = V4L2_CTRL_TYPE_U32,
180 .def = 0x18,
181 .min = 0x10,
182 .max = 0x20000,
183 .step = 1,
184 .dims = { 1 },
187 static const struct v4l2_ctrl_config vivid_ctrl_u16_matrix = {
188 .ops = &vivid_user_gen_ctrl_ops,
189 .id = VIVID_CID_U16_MATRIX,
190 .name = "U16 8x16 Matrix",
191 .type = V4L2_CTRL_TYPE_U16,
192 .def = 0x18,
193 .min = 0x10,
194 .max = 0x2000,
195 .step = 1,
196 .dims = { 8, 16 },
199 static const struct v4l2_ctrl_config vivid_ctrl_u8_4d_array = {
200 .ops = &vivid_user_gen_ctrl_ops,
201 .id = VIVID_CID_U8_4D_ARRAY,
202 .name = "U8 2x3x4x5 Array",
203 .type = V4L2_CTRL_TYPE_U8,
204 .def = 0x18,
205 .min = 0x10,
206 .max = 0x20,
207 .step = 1,
208 .dims = { 2, 3, 4, 5 },
211 static const char * const vivid_ctrl_menu_strings[] = {
212 "Menu Item 0 (Skipped)",
213 "Menu Item 1",
214 "Menu Item 2 (Skipped)",
215 "Menu Item 3",
216 "Menu Item 4",
217 "Menu Item 5 (Skipped)",
218 NULL,
221 static const struct v4l2_ctrl_config vivid_ctrl_menu = {
222 .ops = &vivid_user_gen_ctrl_ops,
223 .id = VIVID_CID_MENU,
224 .name = "Menu",
225 .type = V4L2_CTRL_TYPE_MENU,
226 .min = 1,
227 .max = 4,
228 .def = 3,
229 .menu_skip_mask = 0x04,
230 .qmenu = vivid_ctrl_menu_strings,
233 static const struct v4l2_ctrl_config vivid_ctrl_string = {
234 .ops = &vivid_user_gen_ctrl_ops,
235 .id = VIVID_CID_STRING,
236 .name = "String",
237 .type = V4L2_CTRL_TYPE_STRING,
238 .min = 2,
239 .max = 4,
240 .step = 1,
243 static const struct v4l2_ctrl_config vivid_ctrl_bitmask = {
244 .ops = &vivid_user_gen_ctrl_ops,
245 .id = VIVID_CID_BITMASK,
246 .name = "Bitmask",
247 .type = V4L2_CTRL_TYPE_BITMASK,
248 .def = 0x80002000,
249 .min = 0,
250 .max = 0x80402010,
251 .step = 0,
254 static const s64 vivid_ctrl_int_menu_values[] = {
255 1, 1, 2, 3, 5, 8, 13, 21, 42,
258 static const struct v4l2_ctrl_config vivid_ctrl_int_menu = {
259 .ops = &vivid_user_gen_ctrl_ops,
260 .id = VIVID_CID_INTMENU,
261 .name = "Integer Menu",
262 .type = V4L2_CTRL_TYPE_INTEGER_MENU,
263 .min = 1,
264 .max = 8,
265 .def = 4,
266 .menu_skip_mask = 0x02,
267 .qmenu_int = vivid_ctrl_int_menu_values,
270 static const struct v4l2_ctrl_config vivid_ctrl_disconnect = {
271 .ops = &vivid_user_gen_ctrl_ops,
272 .id = VIVID_CID_DISCONNECT,
273 .name = "Disconnect",
274 .type = V4L2_CTRL_TYPE_BUTTON,
277 static const struct v4l2_ctrl_config vivid_ctrl_clear_fb = {
278 .ops = &vivid_user_gen_ctrl_ops,
279 .id = VIVID_CID_CLEAR_FB,
280 .name = "Clear Framebuffer",
281 .type = V4L2_CTRL_TYPE_BUTTON,
285 /* Video User Controls */
287 static int vivid_user_vid_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
289 struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_user_vid);
291 switch (ctrl->id) {
292 case V4L2_CID_AUTOGAIN:
293 dev->gain->val = dev->jiffies_vid_cap & 0xff;
294 break;
296 return 0;
299 static int vivid_user_vid_s_ctrl(struct v4l2_ctrl *ctrl)
301 struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_user_vid);
303 switch (ctrl->id) {
304 case V4L2_CID_BRIGHTNESS:
305 dev->input_brightness[dev->input] = ctrl->val - dev->input * 128;
306 tpg_s_brightness(&dev->tpg, dev->input_brightness[dev->input]);
307 break;
308 case V4L2_CID_CONTRAST:
309 tpg_s_contrast(&dev->tpg, ctrl->val);
310 break;
311 case V4L2_CID_SATURATION:
312 tpg_s_saturation(&dev->tpg, ctrl->val);
313 break;
314 case V4L2_CID_HUE:
315 tpg_s_hue(&dev->tpg, ctrl->val);
316 break;
317 case V4L2_CID_HFLIP:
318 dev->hflip = ctrl->val;
319 tpg_s_hflip(&dev->tpg, dev->sensor_hflip ^ dev->hflip);
320 break;
321 case V4L2_CID_VFLIP:
322 dev->vflip = ctrl->val;
323 tpg_s_vflip(&dev->tpg, dev->sensor_vflip ^ dev->vflip);
324 break;
325 case V4L2_CID_ALPHA_COMPONENT:
326 tpg_s_alpha_component(&dev->tpg, ctrl->val);
327 break;
329 return 0;
332 static const struct v4l2_ctrl_ops vivid_user_vid_ctrl_ops = {
333 .g_volatile_ctrl = vivid_user_vid_g_volatile_ctrl,
334 .s_ctrl = vivid_user_vid_s_ctrl,
338 /* Video Capture Controls */
340 static int vivid_vid_cap_s_ctrl(struct v4l2_ctrl *ctrl)
342 static const u32 colorspaces[] = {
343 V4L2_COLORSPACE_SMPTE170M,
344 V4L2_COLORSPACE_REC709,
345 V4L2_COLORSPACE_SRGB,
346 V4L2_COLORSPACE_ADOBERGB,
347 V4L2_COLORSPACE_BT2020,
348 V4L2_COLORSPACE_DCI_P3,
349 V4L2_COLORSPACE_SMPTE240M,
350 V4L2_COLORSPACE_470_SYSTEM_M,
351 V4L2_COLORSPACE_470_SYSTEM_BG,
353 struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_vid_cap);
354 unsigned i;
356 switch (ctrl->id) {
357 case VIVID_CID_TEST_PATTERN:
358 vivid_update_quality(dev);
359 tpg_s_pattern(&dev->tpg, ctrl->val);
360 break;
361 case VIVID_CID_COLORSPACE:
362 tpg_s_colorspace(&dev->tpg, colorspaces[ctrl->val]);
363 vivid_send_source_change(dev, TV);
364 vivid_send_source_change(dev, SVID);
365 vivid_send_source_change(dev, HDMI);
366 vivid_send_source_change(dev, WEBCAM);
367 break;
368 case VIVID_CID_XFER_FUNC:
369 tpg_s_xfer_func(&dev->tpg, ctrl->val);
370 vivid_send_source_change(dev, TV);
371 vivid_send_source_change(dev, SVID);
372 vivid_send_source_change(dev, HDMI);
373 vivid_send_source_change(dev, WEBCAM);
374 break;
375 case VIVID_CID_YCBCR_ENC:
376 tpg_s_ycbcr_enc(&dev->tpg, ctrl->val);
377 vivid_send_source_change(dev, TV);
378 vivid_send_source_change(dev, SVID);
379 vivid_send_source_change(dev, HDMI);
380 vivid_send_source_change(dev, WEBCAM);
381 break;
382 case VIVID_CID_HSV_ENC:
383 tpg_s_hsv_enc(&dev->tpg, ctrl->val ? V4L2_HSV_ENC_256 :
384 V4L2_HSV_ENC_180);
385 vivid_send_source_change(dev, TV);
386 vivid_send_source_change(dev, SVID);
387 vivid_send_source_change(dev, HDMI);
388 vivid_send_source_change(dev, WEBCAM);
389 break;
390 case VIVID_CID_QUANTIZATION:
391 tpg_s_quantization(&dev->tpg, ctrl->val);
392 vivid_send_source_change(dev, TV);
393 vivid_send_source_change(dev, SVID);
394 vivid_send_source_change(dev, HDMI);
395 vivid_send_source_change(dev, WEBCAM);
396 break;
397 case V4L2_CID_DV_RX_RGB_RANGE:
398 if (!vivid_is_hdmi_cap(dev))
399 break;
400 tpg_s_rgb_range(&dev->tpg, ctrl->val);
401 break;
402 case VIVID_CID_LIMITED_RGB_RANGE:
403 tpg_s_real_rgb_range(&dev->tpg, ctrl->val ?
404 V4L2_DV_RGB_RANGE_LIMITED : V4L2_DV_RGB_RANGE_FULL);
405 break;
406 case VIVID_CID_ALPHA_MODE:
407 tpg_s_alpha_mode(&dev->tpg, ctrl->val);
408 break;
409 case VIVID_CID_HOR_MOVEMENT:
410 tpg_s_mv_hor_mode(&dev->tpg, ctrl->val);
411 break;
412 case VIVID_CID_VERT_MOVEMENT:
413 tpg_s_mv_vert_mode(&dev->tpg, ctrl->val);
414 break;
415 case VIVID_CID_OSD_TEXT_MODE:
416 dev->osd_mode = ctrl->val;
417 break;
418 case VIVID_CID_PERCENTAGE_FILL:
419 tpg_s_perc_fill(&dev->tpg, ctrl->val);
420 for (i = 0; i < VIDEO_MAX_FRAME; i++)
421 dev->must_blank[i] = ctrl->val < 100;
422 break;
423 case VIVID_CID_INSERT_SAV:
424 tpg_s_insert_sav(&dev->tpg, ctrl->val);
425 break;
426 case VIVID_CID_INSERT_EAV:
427 tpg_s_insert_eav(&dev->tpg, ctrl->val);
428 break;
429 case VIVID_CID_HFLIP:
430 dev->sensor_hflip = ctrl->val;
431 tpg_s_hflip(&dev->tpg, dev->sensor_hflip ^ dev->hflip);
432 break;
433 case VIVID_CID_VFLIP:
434 dev->sensor_vflip = ctrl->val;
435 tpg_s_vflip(&dev->tpg, dev->sensor_vflip ^ dev->vflip);
436 break;
437 case VIVID_CID_REDUCED_FPS:
438 dev->reduced_fps = ctrl->val;
439 vivid_update_format_cap(dev, true);
440 break;
441 case VIVID_CID_HAS_CROP_CAP:
442 dev->has_crop_cap = ctrl->val;
443 vivid_update_format_cap(dev, true);
444 break;
445 case VIVID_CID_HAS_COMPOSE_CAP:
446 dev->has_compose_cap = ctrl->val;
447 vivid_update_format_cap(dev, true);
448 break;
449 case VIVID_CID_HAS_SCALER_CAP:
450 dev->has_scaler_cap = ctrl->val;
451 vivid_update_format_cap(dev, true);
452 break;
453 case VIVID_CID_SHOW_BORDER:
454 tpg_s_show_border(&dev->tpg, ctrl->val);
455 break;
456 case VIVID_CID_SHOW_SQUARE:
457 tpg_s_show_square(&dev->tpg, ctrl->val);
458 break;
459 case VIVID_CID_STD_ASPECT_RATIO:
460 dev->std_aspect_ratio = ctrl->val;
461 tpg_s_video_aspect(&dev->tpg, vivid_get_video_aspect(dev));
462 break;
463 case VIVID_CID_DV_TIMINGS_SIGNAL_MODE:
464 dev->dv_timings_signal_mode = dev->ctrl_dv_timings_signal_mode->val;
465 if (dev->dv_timings_signal_mode == SELECTED_DV_TIMINGS)
466 dev->query_dv_timings = dev->ctrl_dv_timings->val;
467 v4l2_ctrl_activate(dev->ctrl_dv_timings,
468 dev->dv_timings_signal_mode == SELECTED_DV_TIMINGS);
469 vivid_update_quality(dev);
470 vivid_send_source_change(dev, HDMI);
471 break;
472 case VIVID_CID_DV_TIMINGS_ASPECT_RATIO:
473 dev->dv_timings_aspect_ratio = ctrl->val;
474 tpg_s_video_aspect(&dev->tpg, vivid_get_video_aspect(dev));
475 break;
476 case VIVID_CID_TSTAMP_SRC:
477 dev->tstamp_src_is_soe = ctrl->val;
478 dev->vb_vid_cap_q.timestamp_flags &= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
479 if (dev->tstamp_src_is_soe)
480 dev->vb_vid_cap_q.timestamp_flags |= V4L2_BUF_FLAG_TSTAMP_SRC_SOE;
481 break;
482 case VIVID_CID_MAX_EDID_BLOCKS:
483 dev->edid_max_blocks = ctrl->val;
484 if (dev->edid_blocks > dev->edid_max_blocks)
485 dev->edid_blocks = dev->edid_max_blocks;
486 break;
488 return 0;
491 static const struct v4l2_ctrl_ops vivid_vid_cap_ctrl_ops = {
492 .s_ctrl = vivid_vid_cap_s_ctrl,
495 static const char * const vivid_ctrl_hor_movement_strings[] = {
496 "Move Left Fast",
497 "Move Left",
498 "Move Left Slow",
499 "No Movement",
500 "Move Right Slow",
501 "Move Right",
502 "Move Right Fast",
503 NULL,
506 static const struct v4l2_ctrl_config vivid_ctrl_hor_movement = {
507 .ops = &vivid_vid_cap_ctrl_ops,
508 .id = VIVID_CID_HOR_MOVEMENT,
509 .name = "Horizontal Movement",
510 .type = V4L2_CTRL_TYPE_MENU,
511 .max = TPG_MOVE_POS_FAST,
512 .def = TPG_MOVE_NONE,
513 .qmenu = vivid_ctrl_hor_movement_strings,
516 static const char * const vivid_ctrl_vert_movement_strings[] = {
517 "Move Up Fast",
518 "Move Up",
519 "Move Up Slow",
520 "No Movement",
521 "Move Down Slow",
522 "Move Down",
523 "Move Down Fast",
524 NULL,
527 static const struct v4l2_ctrl_config vivid_ctrl_vert_movement = {
528 .ops = &vivid_vid_cap_ctrl_ops,
529 .id = VIVID_CID_VERT_MOVEMENT,
530 .name = "Vertical Movement",
531 .type = V4L2_CTRL_TYPE_MENU,
532 .max = TPG_MOVE_POS_FAST,
533 .def = TPG_MOVE_NONE,
534 .qmenu = vivid_ctrl_vert_movement_strings,
537 static const struct v4l2_ctrl_config vivid_ctrl_show_border = {
538 .ops = &vivid_vid_cap_ctrl_ops,
539 .id = VIVID_CID_SHOW_BORDER,
540 .name = "Show Border",
541 .type = V4L2_CTRL_TYPE_BOOLEAN,
542 .max = 1,
543 .step = 1,
546 static const struct v4l2_ctrl_config vivid_ctrl_show_square = {
547 .ops = &vivid_vid_cap_ctrl_ops,
548 .id = VIVID_CID_SHOW_SQUARE,
549 .name = "Show Square",
550 .type = V4L2_CTRL_TYPE_BOOLEAN,
551 .max = 1,
552 .step = 1,
555 static const char * const vivid_ctrl_osd_mode_strings[] = {
556 "All",
557 "Counters Only",
558 "None",
559 NULL,
562 static const struct v4l2_ctrl_config vivid_ctrl_osd_mode = {
563 .ops = &vivid_vid_cap_ctrl_ops,
564 .id = VIVID_CID_OSD_TEXT_MODE,
565 .name = "OSD Text Mode",
566 .type = V4L2_CTRL_TYPE_MENU,
567 .max = ARRAY_SIZE(vivid_ctrl_osd_mode_strings) - 2,
568 .qmenu = vivid_ctrl_osd_mode_strings,
571 static const struct v4l2_ctrl_config vivid_ctrl_perc_fill = {
572 .ops = &vivid_vid_cap_ctrl_ops,
573 .id = VIVID_CID_PERCENTAGE_FILL,
574 .name = "Fill Percentage of Frame",
575 .type = V4L2_CTRL_TYPE_INTEGER,
576 .min = 0,
577 .max = 100,
578 .def = 100,
579 .step = 1,
582 static const struct v4l2_ctrl_config vivid_ctrl_insert_sav = {
583 .ops = &vivid_vid_cap_ctrl_ops,
584 .id = VIVID_CID_INSERT_SAV,
585 .name = "Insert SAV Code in Image",
586 .type = V4L2_CTRL_TYPE_BOOLEAN,
587 .max = 1,
588 .step = 1,
591 static const struct v4l2_ctrl_config vivid_ctrl_insert_eav = {
592 .ops = &vivid_vid_cap_ctrl_ops,
593 .id = VIVID_CID_INSERT_EAV,
594 .name = "Insert EAV Code in Image",
595 .type = V4L2_CTRL_TYPE_BOOLEAN,
596 .max = 1,
597 .step = 1,
600 static const struct v4l2_ctrl_config vivid_ctrl_hflip = {
601 .ops = &vivid_vid_cap_ctrl_ops,
602 .id = VIVID_CID_HFLIP,
603 .name = "Sensor Flipped Horizontally",
604 .type = V4L2_CTRL_TYPE_BOOLEAN,
605 .max = 1,
606 .step = 1,
609 static const struct v4l2_ctrl_config vivid_ctrl_vflip = {
610 .ops = &vivid_vid_cap_ctrl_ops,
611 .id = VIVID_CID_VFLIP,
612 .name = "Sensor Flipped Vertically",
613 .type = V4L2_CTRL_TYPE_BOOLEAN,
614 .max = 1,
615 .step = 1,
618 static const struct v4l2_ctrl_config vivid_ctrl_reduced_fps = {
619 .ops = &vivid_vid_cap_ctrl_ops,
620 .id = VIVID_CID_REDUCED_FPS,
621 .name = "Reduced Framerate",
622 .type = V4L2_CTRL_TYPE_BOOLEAN,
623 .max = 1,
624 .step = 1,
627 static const struct v4l2_ctrl_config vivid_ctrl_has_crop_cap = {
628 .ops = &vivid_vid_cap_ctrl_ops,
629 .id = VIVID_CID_HAS_CROP_CAP,
630 .name = "Enable Capture Cropping",
631 .type = V4L2_CTRL_TYPE_BOOLEAN,
632 .max = 1,
633 .def = 1,
634 .step = 1,
637 static const struct v4l2_ctrl_config vivid_ctrl_has_compose_cap = {
638 .ops = &vivid_vid_cap_ctrl_ops,
639 .id = VIVID_CID_HAS_COMPOSE_CAP,
640 .name = "Enable Capture Composing",
641 .type = V4L2_CTRL_TYPE_BOOLEAN,
642 .max = 1,
643 .def = 1,
644 .step = 1,
647 static const struct v4l2_ctrl_config vivid_ctrl_has_scaler_cap = {
648 .ops = &vivid_vid_cap_ctrl_ops,
649 .id = VIVID_CID_HAS_SCALER_CAP,
650 .name = "Enable Capture Scaler",
651 .type = V4L2_CTRL_TYPE_BOOLEAN,
652 .max = 1,
653 .def = 1,
654 .step = 1,
657 static const char * const vivid_ctrl_tstamp_src_strings[] = {
658 "End of Frame",
659 "Start of Exposure",
660 NULL,
663 static const struct v4l2_ctrl_config vivid_ctrl_tstamp_src = {
664 .ops = &vivid_vid_cap_ctrl_ops,
665 .id = VIVID_CID_TSTAMP_SRC,
666 .name = "Timestamp Source",
667 .type = V4L2_CTRL_TYPE_MENU,
668 .max = ARRAY_SIZE(vivid_ctrl_tstamp_src_strings) - 2,
669 .qmenu = vivid_ctrl_tstamp_src_strings,
672 static const struct v4l2_ctrl_config vivid_ctrl_std_aspect_ratio = {
673 .ops = &vivid_vid_cap_ctrl_ops,
674 .id = VIVID_CID_STD_ASPECT_RATIO,
675 .name = "Standard Aspect Ratio",
676 .type = V4L2_CTRL_TYPE_MENU,
677 .min = 1,
678 .max = 4,
679 .def = 1,
680 .qmenu = tpg_aspect_strings,
683 static const char * const vivid_ctrl_dv_timings_signal_mode_strings[] = {
684 "Current DV Timings",
685 "No Signal",
686 "No Lock",
687 "Out of Range",
688 "Selected DV Timings",
689 "Cycle Through All DV Timings",
690 "Custom DV Timings",
691 NULL,
694 static const struct v4l2_ctrl_config vivid_ctrl_dv_timings_signal_mode = {
695 .ops = &vivid_vid_cap_ctrl_ops,
696 .id = VIVID_CID_DV_TIMINGS_SIGNAL_MODE,
697 .name = "DV Timings Signal Mode",
698 .type = V4L2_CTRL_TYPE_MENU,
699 .max = 5,
700 .qmenu = vivid_ctrl_dv_timings_signal_mode_strings,
703 static const struct v4l2_ctrl_config vivid_ctrl_dv_timings_aspect_ratio = {
704 .ops = &vivid_vid_cap_ctrl_ops,
705 .id = VIVID_CID_DV_TIMINGS_ASPECT_RATIO,
706 .name = "DV Timings Aspect Ratio",
707 .type = V4L2_CTRL_TYPE_MENU,
708 .max = 3,
709 .qmenu = tpg_aspect_strings,
712 static const struct v4l2_ctrl_config vivid_ctrl_max_edid_blocks = {
713 .ops = &vivid_vid_cap_ctrl_ops,
714 .id = VIVID_CID_MAX_EDID_BLOCKS,
715 .name = "Maximum EDID Blocks",
716 .type = V4L2_CTRL_TYPE_INTEGER,
717 .min = 1,
718 .max = 256,
719 .def = 2,
720 .step = 1,
723 static const char * const vivid_ctrl_colorspace_strings[] = {
724 "SMPTE 170M",
725 "Rec. 709",
726 "sRGB",
727 "AdobeRGB",
728 "BT.2020",
729 "DCI-P3",
730 "SMPTE 240M",
731 "470 System M",
732 "470 System BG",
733 NULL,
736 static const struct v4l2_ctrl_config vivid_ctrl_colorspace = {
737 .ops = &vivid_vid_cap_ctrl_ops,
738 .id = VIVID_CID_COLORSPACE,
739 .name = "Colorspace",
740 .type = V4L2_CTRL_TYPE_MENU,
741 .max = ARRAY_SIZE(vivid_ctrl_colorspace_strings) - 2,
742 .def = 2,
743 .qmenu = vivid_ctrl_colorspace_strings,
746 static const char * const vivid_ctrl_xfer_func_strings[] = {
747 "Default",
748 "Rec. 709",
749 "sRGB",
750 "AdobeRGB",
751 "SMPTE 240M",
752 "None",
753 "DCI-P3",
754 "SMPTE 2084",
755 NULL,
758 static const struct v4l2_ctrl_config vivid_ctrl_xfer_func = {
759 .ops = &vivid_vid_cap_ctrl_ops,
760 .id = VIVID_CID_XFER_FUNC,
761 .name = "Transfer Function",
762 .type = V4L2_CTRL_TYPE_MENU,
763 .max = ARRAY_SIZE(vivid_ctrl_xfer_func_strings) - 2,
764 .qmenu = vivid_ctrl_xfer_func_strings,
767 static const char * const vivid_ctrl_ycbcr_enc_strings[] = {
768 "Default",
769 "ITU-R 601",
770 "Rec. 709",
771 "xvYCC 601",
772 "xvYCC 709",
774 "BT.2020",
775 "BT.2020 Constant Luminance",
776 "SMPTE 240M",
777 NULL,
780 static const struct v4l2_ctrl_config vivid_ctrl_ycbcr_enc = {
781 .ops = &vivid_vid_cap_ctrl_ops,
782 .id = VIVID_CID_YCBCR_ENC,
783 .name = "Y'CbCr Encoding",
784 .type = V4L2_CTRL_TYPE_MENU,
785 .menu_skip_mask = 1 << 5,
786 .max = ARRAY_SIZE(vivid_ctrl_ycbcr_enc_strings) - 2,
787 .qmenu = vivid_ctrl_ycbcr_enc_strings,
790 static const char * const vivid_ctrl_hsv_enc_strings[] = {
791 "Hue 0-179",
792 "Hue 0-256",
793 NULL,
796 static const struct v4l2_ctrl_config vivid_ctrl_hsv_enc = {
797 .ops = &vivid_vid_cap_ctrl_ops,
798 .id = VIVID_CID_HSV_ENC,
799 .name = "HSV Encoding",
800 .type = V4L2_CTRL_TYPE_MENU,
801 .max = ARRAY_SIZE(vivid_ctrl_hsv_enc_strings) - 2,
802 .qmenu = vivid_ctrl_hsv_enc_strings,
805 static const char * const vivid_ctrl_quantization_strings[] = {
806 "Default",
807 "Full Range",
808 "Limited Range",
809 NULL,
812 static const struct v4l2_ctrl_config vivid_ctrl_quantization = {
813 .ops = &vivid_vid_cap_ctrl_ops,
814 .id = VIVID_CID_QUANTIZATION,
815 .name = "Quantization",
816 .type = V4L2_CTRL_TYPE_MENU,
817 .max = ARRAY_SIZE(vivid_ctrl_quantization_strings) - 2,
818 .qmenu = vivid_ctrl_quantization_strings,
821 static const struct v4l2_ctrl_config vivid_ctrl_alpha_mode = {
822 .ops = &vivid_vid_cap_ctrl_ops,
823 .id = VIVID_CID_ALPHA_MODE,
824 .name = "Apply Alpha To Red Only",
825 .type = V4L2_CTRL_TYPE_BOOLEAN,
826 .max = 1,
827 .step = 1,
830 static const struct v4l2_ctrl_config vivid_ctrl_limited_rgb_range = {
831 .ops = &vivid_vid_cap_ctrl_ops,
832 .id = VIVID_CID_LIMITED_RGB_RANGE,
833 .name = "Limited RGB Range (16-235)",
834 .type = V4L2_CTRL_TYPE_BOOLEAN,
835 .max = 1,
836 .step = 1,
840 /* Video Loop Control */
842 static int vivid_loop_cap_s_ctrl(struct v4l2_ctrl *ctrl)
844 struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_loop_cap);
846 switch (ctrl->id) {
847 case VIVID_CID_LOOP_VIDEO:
848 dev->loop_video = ctrl->val;
849 vivid_update_quality(dev);
850 vivid_send_source_change(dev, SVID);
851 vivid_send_source_change(dev, HDMI);
852 break;
854 return 0;
857 static const struct v4l2_ctrl_ops vivid_loop_cap_ctrl_ops = {
858 .s_ctrl = vivid_loop_cap_s_ctrl,
861 static const struct v4l2_ctrl_config vivid_ctrl_loop_video = {
862 .ops = &vivid_loop_cap_ctrl_ops,
863 .id = VIVID_CID_LOOP_VIDEO,
864 .name = "Loop Video",
865 .type = V4L2_CTRL_TYPE_BOOLEAN,
866 .max = 1,
867 .step = 1,
871 /* VBI Capture Control */
873 static int vivid_vbi_cap_s_ctrl(struct v4l2_ctrl *ctrl)
875 struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_vbi_cap);
877 switch (ctrl->id) {
878 case VIVID_CID_VBI_CAP_INTERLACED:
879 dev->vbi_cap_interlaced = ctrl->val;
880 break;
882 return 0;
885 static const struct v4l2_ctrl_ops vivid_vbi_cap_ctrl_ops = {
886 .s_ctrl = vivid_vbi_cap_s_ctrl,
889 static const struct v4l2_ctrl_config vivid_ctrl_vbi_cap_interlaced = {
890 .ops = &vivid_vbi_cap_ctrl_ops,
891 .id = VIVID_CID_VBI_CAP_INTERLACED,
892 .name = "Interlaced VBI Format",
893 .type = V4L2_CTRL_TYPE_BOOLEAN,
894 .max = 1,
895 .step = 1,
899 /* Video Output Controls */
901 static int vivid_vid_out_s_ctrl(struct v4l2_ctrl *ctrl)
903 struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_vid_out);
904 struct v4l2_bt_timings *bt = &dev->dv_timings_out.bt;
906 switch (ctrl->id) {
907 case VIVID_CID_HAS_CROP_OUT:
908 dev->has_crop_out = ctrl->val;
909 vivid_update_format_out(dev);
910 break;
911 case VIVID_CID_HAS_COMPOSE_OUT:
912 dev->has_compose_out = ctrl->val;
913 vivid_update_format_out(dev);
914 break;
915 case VIVID_CID_HAS_SCALER_OUT:
916 dev->has_scaler_out = ctrl->val;
917 vivid_update_format_out(dev);
918 break;
919 case V4L2_CID_DV_TX_MODE:
920 dev->dvi_d_out = ctrl->val == V4L2_DV_TX_MODE_DVI_D;
921 if (!vivid_is_hdmi_out(dev))
922 break;
923 if (!dev->dvi_d_out && (bt->flags & V4L2_DV_FL_IS_CE_VIDEO)) {
924 if (bt->width == 720 && bt->height <= 576)
925 dev->colorspace_out = V4L2_COLORSPACE_SMPTE170M;
926 else
927 dev->colorspace_out = V4L2_COLORSPACE_REC709;
928 dev->quantization_out = V4L2_QUANTIZATION_DEFAULT;
929 } else {
930 dev->colorspace_out = V4L2_COLORSPACE_SRGB;
931 dev->quantization_out = dev->dvi_d_out ?
932 V4L2_QUANTIZATION_LIM_RANGE :
933 V4L2_QUANTIZATION_DEFAULT;
935 if (dev->loop_video)
936 vivid_send_source_change(dev, HDMI);
937 break;
939 return 0;
942 static const struct v4l2_ctrl_ops vivid_vid_out_ctrl_ops = {
943 .s_ctrl = vivid_vid_out_s_ctrl,
946 static const struct v4l2_ctrl_config vivid_ctrl_has_crop_out = {
947 .ops = &vivid_vid_out_ctrl_ops,
948 .id = VIVID_CID_HAS_CROP_OUT,
949 .name = "Enable Output Cropping",
950 .type = V4L2_CTRL_TYPE_BOOLEAN,
951 .max = 1,
952 .def = 1,
953 .step = 1,
956 static const struct v4l2_ctrl_config vivid_ctrl_has_compose_out = {
957 .ops = &vivid_vid_out_ctrl_ops,
958 .id = VIVID_CID_HAS_COMPOSE_OUT,
959 .name = "Enable Output Composing",
960 .type = V4L2_CTRL_TYPE_BOOLEAN,
961 .max = 1,
962 .def = 1,
963 .step = 1,
966 static const struct v4l2_ctrl_config vivid_ctrl_has_scaler_out = {
967 .ops = &vivid_vid_out_ctrl_ops,
968 .id = VIVID_CID_HAS_SCALER_OUT,
969 .name = "Enable Output Scaler",
970 .type = V4L2_CTRL_TYPE_BOOLEAN,
971 .max = 1,
972 .def = 1,
973 .step = 1,
977 /* Streaming Controls */
979 static int vivid_streaming_s_ctrl(struct v4l2_ctrl *ctrl)
981 struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_streaming);
982 u64 rem;
984 switch (ctrl->id) {
985 case VIVID_CID_DQBUF_ERROR:
986 dev->dqbuf_error = true;
987 break;
988 case VIVID_CID_PERC_DROPPED:
989 dev->perc_dropped_buffers = ctrl->val;
990 break;
991 case VIVID_CID_QUEUE_SETUP_ERROR:
992 dev->queue_setup_error = true;
993 break;
994 case VIVID_CID_BUF_PREPARE_ERROR:
995 dev->buf_prepare_error = true;
996 break;
997 case VIVID_CID_START_STR_ERROR:
998 dev->start_streaming_error = true;
999 break;
1000 case VIVID_CID_QUEUE_ERROR:
1001 if (vb2_start_streaming_called(&dev->vb_vid_cap_q))
1002 vb2_queue_error(&dev->vb_vid_cap_q);
1003 if (vb2_start_streaming_called(&dev->vb_vbi_cap_q))
1004 vb2_queue_error(&dev->vb_vbi_cap_q);
1005 if (vb2_start_streaming_called(&dev->vb_vid_out_q))
1006 vb2_queue_error(&dev->vb_vid_out_q);
1007 if (vb2_start_streaming_called(&dev->vb_vbi_out_q))
1008 vb2_queue_error(&dev->vb_vbi_out_q);
1009 if (vb2_start_streaming_called(&dev->vb_sdr_cap_q))
1010 vb2_queue_error(&dev->vb_sdr_cap_q);
1011 break;
1012 case VIVID_CID_SEQ_WRAP:
1013 dev->seq_wrap = ctrl->val;
1014 break;
1015 case VIVID_CID_TIME_WRAP:
1016 dev->time_wrap = ctrl->val;
1017 if (ctrl->val == 0) {
1018 dev->time_wrap_offset = 0;
1019 break;
1022 * We want to set the time 16 seconds before the 32 bit tv_sec
1023 * value of struct timeval would wrap around. So first we
1024 * calculate ktime_get_ns() % ((1 << 32) * NSEC_PER_SEC), and
1025 * then we set the offset to ((1 << 32) - 16) * NSEC_PER_SEC).
1027 div64_u64_rem(ktime_get_ns(),
1028 0x100000000ULL * NSEC_PER_SEC, &rem);
1029 dev->time_wrap_offset =
1030 (0x100000000ULL - 16) * NSEC_PER_SEC - rem;
1031 break;
1033 return 0;
1036 static const struct v4l2_ctrl_ops vivid_streaming_ctrl_ops = {
1037 .s_ctrl = vivid_streaming_s_ctrl,
1040 static const struct v4l2_ctrl_config vivid_ctrl_dqbuf_error = {
1041 .ops = &vivid_streaming_ctrl_ops,
1042 .id = VIVID_CID_DQBUF_ERROR,
1043 .name = "Inject V4L2_BUF_FLAG_ERROR",
1044 .type = V4L2_CTRL_TYPE_BUTTON,
1047 static const struct v4l2_ctrl_config vivid_ctrl_perc_dropped = {
1048 .ops = &vivid_streaming_ctrl_ops,
1049 .id = VIVID_CID_PERC_DROPPED,
1050 .name = "Percentage of Dropped Buffers",
1051 .type = V4L2_CTRL_TYPE_INTEGER,
1052 .min = 0,
1053 .max = 100,
1054 .step = 1,
1057 static const struct v4l2_ctrl_config vivid_ctrl_queue_setup_error = {
1058 .ops = &vivid_streaming_ctrl_ops,
1059 .id = VIVID_CID_QUEUE_SETUP_ERROR,
1060 .name = "Inject VIDIOC_REQBUFS Error",
1061 .type = V4L2_CTRL_TYPE_BUTTON,
1064 static const struct v4l2_ctrl_config vivid_ctrl_buf_prepare_error = {
1065 .ops = &vivid_streaming_ctrl_ops,
1066 .id = VIVID_CID_BUF_PREPARE_ERROR,
1067 .name = "Inject VIDIOC_QBUF Error",
1068 .type = V4L2_CTRL_TYPE_BUTTON,
1071 static const struct v4l2_ctrl_config vivid_ctrl_start_streaming_error = {
1072 .ops = &vivid_streaming_ctrl_ops,
1073 .id = VIVID_CID_START_STR_ERROR,
1074 .name = "Inject VIDIOC_STREAMON Error",
1075 .type = V4L2_CTRL_TYPE_BUTTON,
1078 static const struct v4l2_ctrl_config vivid_ctrl_queue_error = {
1079 .ops = &vivid_streaming_ctrl_ops,
1080 .id = VIVID_CID_QUEUE_ERROR,
1081 .name = "Inject Fatal Streaming Error",
1082 .type = V4L2_CTRL_TYPE_BUTTON,
1085 static const struct v4l2_ctrl_config vivid_ctrl_seq_wrap = {
1086 .ops = &vivid_streaming_ctrl_ops,
1087 .id = VIVID_CID_SEQ_WRAP,
1088 .name = "Wrap Sequence Number",
1089 .type = V4L2_CTRL_TYPE_BOOLEAN,
1090 .max = 1,
1091 .step = 1,
1094 static const struct v4l2_ctrl_config vivid_ctrl_time_wrap = {
1095 .ops = &vivid_streaming_ctrl_ops,
1096 .id = VIVID_CID_TIME_WRAP,
1097 .name = "Wrap Timestamp",
1098 .type = V4L2_CTRL_TYPE_BOOLEAN,
1099 .max = 1,
1100 .step = 1,
1104 /* SDTV Capture Controls */
1106 static int vivid_sdtv_cap_s_ctrl(struct v4l2_ctrl *ctrl)
1108 struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_sdtv_cap);
1110 switch (ctrl->id) {
1111 case VIVID_CID_STD_SIGNAL_MODE:
1112 dev->std_signal_mode = dev->ctrl_std_signal_mode->val;
1113 if (dev->std_signal_mode == SELECTED_STD)
1114 dev->query_std = vivid_standard[dev->ctrl_standard->val];
1115 v4l2_ctrl_activate(dev->ctrl_standard, dev->std_signal_mode == SELECTED_STD);
1116 vivid_update_quality(dev);
1117 vivid_send_source_change(dev, TV);
1118 vivid_send_source_change(dev, SVID);
1119 break;
1121 return 0;
1124 static const struct v4l2_ctrl_ops vivid_sdtv_cap_ctrl_ops = {
1125 .s_ctrl = vivid_sdtv_cap_s_ctrl,
1128 static const char * const vivid_ctrl_std_signal_mode_strings[] = {
1129 "Current Standard",
1130 "No Signal",
1131 "No Lock",
1133 "Selected Standard",
1134 "Cycle Through All Standards",
1135 NULL,
1138 static const struct v4l2_ctrl_config vivid_ctrl_std_signal_mode = {
1139 .ops = &vivid_sdtv_cap_ctrl_ops,
1140 .id = VIVID_CID_STD_SIGNAL_MODE,
1141 .name = "Standard Signal Mode",
1142 .type = V4L2_CTRL_TYPE_MENU,
1143 .max = ARRAY_SIZE(vivid_ctrl_std_signal_mode_strings) - 2,
1144 .menu_skip_mask = 1 << 3,
1145 .qmenu = vivid_ctrl_std_signal_mode_strings,
1148 static const struct v4l2_ctrl_config vivid_ctrl_standard = {
1149 .ops = &vivid_sdtv_cap_ctrl_ops,
1150 .id = VIVID_CID_STANDARD,
1151 .name = "Standard",
1152 .type = V4L2_CTRL_TYPE_MENU,
1153 .max = 14,
1154 .qmenu = vivid_ctrl_standard_strings,
1159 /* Radio Receiver Controls */
1161 static int vivid_radio_rx_s_ctrl(struct v4l2_ctrl *ctrl)
1163 struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_radio_rx);
1165 switch (ctrl->id) {
1166 case VIVID_CID_RADIO_SEEK_MODE:
1167 dev->radio_rx_hw_seek_mode = ctrl->val;
1168 break;
1169 case VIVID_CID_RADIO_SEEK_PROG_LIM:
1170 dev->radio_rx_hw_seek_prog_lim = ctrl->val;
1171 break;
1172 case VIVID_CID_RADIO_RX_RDS_RBDS:
1173 dev->rds_gen.use_rbds = ctrl->val;
1174 break;
1175 case VIVID_CID_RADIO_RX_RDS_BLOCKIO:
1176 dev->radio_rx_rds_controls = ctrl->val;
1177 dev->radio_rx_caps &= ~V4L2_CAP_READWRITE;
1178 dev->radio_rx_rds_use_alternates = false;
1179 if (!dev->radio_rx_rds_controls) {
1180 dev->radio_rx_caps |= V4L2_CAP_READWRITE;
1181 __v4l2_ctrl_s_ctrl(dev->radio_rx_rds_pty, 0);
1182 __v4l2_ctrl_s_ctrl(dev->radio_rx_rds_ta, 0);
1183 __v4l2_ctrl_s_ctrl(dev->radio_rx_rds_tp, 0);
1184 __v4l2_ctrl_s_ctrl(dev->radio_rx_rds_ms, 0);
1185 __v4l2_ctrl_s_ctrl_string(dev->radio_rx_rds_psname, "");
1186 __v4l2_ctrl_s_ctrl_string(dev->radio_rx_rds_radiotext, "");
1188 v4l2_ctrl_activate(dev->radio_rx_rds_pty, dev->radio_rx_rds_controls);
1189 v4l2_ctrl_activate(dev->radio_rx_rds_psname, dev->radio_rx_rds_controls);
1190 v4l2_ctrl_activate(dev->radio_rx_rds_radiotext, dev->radio_rx_rds_controls);
1191 v4l2_ctrl_activate(dev->radio_rx_rds_ta, dev->radio_rx_rds_controls);
1192 v4l2_ctrl_activate(dev->radio_rx_rds_tp, dev->radio_rx_rds_controls);
1193 v4l2_ctrl_activate(dev->radio_rx_rds_ms, dev->radio_rx_rds_controls);
1194 break;
1195 case V4L2_CID_RDS_RECEPTION:
1196 dev->radio_rx_rds_enabled = ctrl->val;
1197 break;
1199 return 0;
1202 static const struct v4l2_ctrl_ops vivid_radio_rx_ctrl_ops = {
1203 .s_ctrl = vivid_radio_rx_s_ctrl,
1206 static const char * const vivid_ctrl_radio_rds_mode_strings[] = {
1207 "Block I/O",
1208 "Controls",
1209 NULL,
1212 static const struct v4l2_ctrl_config vivid_ctrl_radio_rx_rds_blockio = {
1213 .ops = &vivid_radio_rx_ctrl_ops,
1214 .id = VIVID_CID_RADIO_RX_RDS_BLOCKIO,
1215 .name = "RDS Rx I/O Mode",
1216 .type = V4L2_CTRL_TYPE_MENU,
1217 .qmenu = vivid_ctrl_radio_rds_mode_strings,
1218 .max = 1,
1221 static const struct v4l2_ctrl_config vivid_ctrl_radio_rx_rds_rbds = {
1222 .ops = &vivid_radio_rx_ctrl_ops,
1223 .id = VIVID_CID_RADIO_RX_RDS_RBDS,
1224 .name = "Generate RBDS Instead of RDS",
1225 .type = V4L2_CTRL_TYPE_BOOLEAN,
1226 .max = 1,
1227 .step = 1,
1230 static const char * const vivid_ctrl_radio_hw_seek_mode_strings[] = {
1231 "Bounded",
1232 "Wrap Around",
1233 "Both",
1234 NULL,
1237 static const struct v4l2_ctrl_config vivid_ctrl_radio_hw_seek_mode = {
1238 .ops = &vivid_radio_rx_ctrl_ops,
1239 .id = VIVID_CID_RADIO_SEEK_MODE,
1240 .name = "Radio HW Seek Mode",
1241 .type = V4L2_CTRL_TYPE_MENU,
1242 .max = 2,
1243 .qmenu = vivid_ctrl_radio_hw_seek_mode_strings,
1246 static const struct v4l2_ctrl_config vivid_ctrl_radio_hw_seek_prog_lim = {
1247 .ops = &vivid_radio_rx_ctrl_ops,
1248 .id = VIVID_CID_RADIO_SEEK_PROG_LIM,
1249 .name = "Radio Programmable HW Seek",
1250 .type = V4L2_CTRL_TYPE_BOOLEAN,
1251 .max = 1,
1252 .step = 1,
1256 /* Radio Transmitter Controls */
1258 static int vivid_radio_tx_s_ctrl(struct v4l2_ctrl *ctrl)
1260 struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_radio_tx);
1262 switch (ctrl->id) {
1263 case VIVID_CID_RADIO_TX_RDS_BLOCKIO:
1264 dev->radio_tx_rds_controls = ctrl->val;
1265 dev->radio_tx_caps &= ~V4L2_CAP_READWRITE;
1266 if (!dev->radio_tx_rds_controls)
1267 dev->radio_tx_caps |= V4L2_CAP_READWRITE;
1268 break;
1269 case V4L2_CID_RDS_TX_PTY:
1270 if (dev->radio_rx_rds_controls)
1271 v4l2_ctrl_s_ctrl(dev->radio_rx_rds_pty, ctrl->val);
1272 break;
1273 case V4L2_CID_RDS_TX_PS_NAME:
1274 if (dev->radio_rx_rds_controls)
1275 v4l2_ctrl_s_ctrl_string(dev->radio_rx_rds_psname, ctrl->p_new.p_char);
1276 break;
1277 case V4L2_CID_RDS_TX_RADIO_TEXT:
1278 if (dev->radio_rx_rds_controls)
1279 v4l2_ctrl_s_ctrl_string(dev->radio_rx_rds_radiotext, ctrl->p_new.p_char);
1280 break;
1281 case V4L2_CID_RDS_TX_TRAFFIC_ANNOUNCEMENT:
1282 if (dev->radio_rx_rds_controls)
1283 v4l2_ctrl_s_ctrl(dev->radio_rx_rds_ta, ctrl->val);
1284 break;
1285 case V4L2_CID_RDS_TX_TRAFFIC_PROGRAM:
1286 if (dev->radio_rx_rds_controls)
1287 v4l2_ctrl_s_ctrl(dev->radio_rx_rds_tp, ctrl->val);
1288 break;
1289 case V4L2_CID_RDS_TX_MUSIC_SPEECH:
1290 if (dev->radio_rx_rds_controls)
1291 v4l2_ctrl_s_ctrl(dev->radio_rx_rds_ms, ctrl->val);
1292 break;
1294 return 0;
1297 static const struct v4l2_ctrl_ops vivid_radio_tx_ctrl_ops = {
1298 .s_ctrl = vivid_radio_tx_s_ctrl,
1301 static const struct v4l2_ctrl_config vivid_ctrl_radio_tx_rds_blockio = {
1302 .ops = &vivid_radio_tx_ctrl_ops,
1303 .id = VIVID_CID_RADIO_TX_RDS_BLOCKIO,
1304 .name = "RDS Tx I/O Mode",
1305 .type = V4L2_CTRL_TYPE_MENU,
1306 .qmenu = vivid_ctrl_radio_rds_mode_strings,
1307 .max = 1,
1308 .def = 1,
1312 /* SDR Capture Controls */
1314 static int vivid_sdr_cap_s_ctrl(struct v4l2_ctrl *ctrl)
1316 struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_sdr_cap);
1318 switch (ctrl->id) {
1319 case VIVID_CID_SDR_CAP_FM_DEVIATION:
1320 dev->sdr_fm_deviation = ctrl->val;
1321 break;
1323 return 0;
1326 static const struct v4l2_ctrl_ops vivid_sdr_cap_ctrl_ops = {
1327 .s_ctrl = vivid_sdr_cap_s_ctrl,
1330 static const struct v4l2_ctrl_config vivid_ctrl_sdr_cap_fm_deviation = {
1331 .ops = &vivid_sdr_cap_ctrl_ops,
1332 .id = VIVID_CID_SDR_CAP_FM_DEVIATION,
1333 .name = "FM Deviation",
1334 .type = V4L2_CTRL_TYPE_INTEGER,
1335 .min = 100,
1336 .max = 200000,
1337 .def = 75000,
1338 .step = 1,
1342 static const struct v4l2_ctrl_config vivid_ctrl_class = {
1343 .ops = &vivid_user_gen_ctrl_ops,
1344 .flags = V4L2_CTRL_FLAG_READ_ONLY | V4L2_CTRL_FLAG_WRITE_ONLY,
1345 .id = VIVID_CID_VIVID_CLASS,
1346 .name = "Vivid Controls",
1347 .type = V4L2_CTRL_TYPE_CTRL_CLASS,
1350 int vivid_create_controls(struct vivid_dev *dev, bool show_ccs_cap,
1351 bool show_ccs_out, bool no_error_inj,
1352 bool has_sdtv, bool has_hdmi)
1354 struct v4l2_ctrl_handler *hdl_user_gen = &dev->ctrl_hdl_user_gen;
1355 struct v4l2_ctrl_handler *hdl_user_vid = &dev->ctrl_hdl_user_vid;
1356 struct v4l2_ctrl_handler *hdl_user_aud = &dev->ctrl_hdl_user_aud;
1357 struct v4l2_ctrl_handler *hdl_streaming = &dev->ctrl_hdl_streaming;
1358 struct v4l2_ctrl_handler *hdl_sdtv_cap = &dev->ctrl_hdl_sdtv_cap;
1359 struct v4l2_ctrl_handler *hdl_loop_cap = &dev->ctrl_hdl_loop_cap;
1360 struct v4l2_ctrl_handler *hdl_vid_cap = &dev->ctrl_hdl_vid_cap;
1361 struct v4l2_ctrl_handler *hdl_vid_out = &dev->ctrl_hdl_vid_out;
1362 struct v4l2_ctrl_handler *hdl_vbi_cap = &dev->ctrl_hdl_vbi_cap;
1363 struct v4l2_ctrl_handler *hdl_vbi_out = &dev->ctrl_hdl_vbi_out;
1364 struct v4l2_ctrl_handler *hdl_radio_rx = &dev->ctrl_hdl_radio_rx;
1365 struct v4l2_ctrl_handler *hdl_radio_tx = &dev->ctrl_hdl_radio_tx;
1366 struct v4l2_ctrl_handler *hdl_sdr_cap = &dev->ctrl_hdl_sdr_cap;
1367 struct v4l2_ctrl_config vivid_ctrl_dv_timings = {
1368 .ops = &vivid_vid_cap_ctrl_ops,
1369 .id = VIVID_CID_DV_TIMINGS,
1370 .name = "DV Timings",
1371 .type = V4L2_CTRL_TYPE_MENU,
1373 int i;
1375 v4l2_ctrl_handler_init(hdl_user_gen, 10);
1376 v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_class, NULL);
1377 v4l2_ctrl_handler_init(hdl_user_vid, 9);
1378 v4l2_ctrl_new_custom(hdl_user_vid, &vivid_ctrl_class, NULL);
1379 v4l2_ctrl_handler_init(hdl_user_aud, 2);
1380 v4l2_ctrl_new_custom(hdl_user_aud, &vivid_ctrl_class, NULL);
1381 v4l2_ctrl_handler_init(hdl_streaming, 8);
1382 v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_class, NULL);
1383 v4l2_ctrl_handler_init(hdl_sdtv_cap, 2);
1384 v4l2_ctrl_new_custom(hdl_sdtv_cap, &vivid_ctrl_class, NULL);
1385 v4l2_ctrl_handler_init(hdl_loop_cap, 1);
1386 v4l2_ctrl_new_custom(hdl_loop_cap, &vivid_ctrl_class, NULL);
1387 v4l2_ctrl_handler_init(hdl_vid_cap, 55);
1388 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_class, NULL);
1389 v4l2_ctrl_handler_init(hdl_vid_out, 26);
1390 if (!no_error_inj)
1391 v4l2_ctrl_new_custom(hdl_vid_out, &vivid_ctrl_class, NULL);
1392 v4l2_ctrl_handler_init(hdl_vbi_cap, 21);
1393 v4l2_ctrl_new_custom(hdl_vbi_cap, &vivid_ctrl_class, NULL);
1394 v4l2_ctrl_handler_init(hdl_vbi_out, 19);
1395 if (!no_error_inj)
1396 v4l2_ctrl_new_custom(hdl_vbi_out, &vivid_ctrl_class, NULL);
1397 v4l2_ctrl_handler_init(hdl_radio_rx, 17);
1398 v4l2_ctrl_new_custom(hdl_radio_rx, &vivid_ctrl_class, NULL);
1399 v4l2_ctrl_handler_init(hdl_radio_tx, 17);
1400 v4l2_ctrl_new_custom(hdl_radio_tx, &vivid_ctrl_class, NULL);
1401 v4l2_ctrl_handler_init(hdl_sdr_cap, 19);
1402 v4l2_ctrl_new_custom(hdl_sdr_cap, &vivid_ctrl_class, NULL);
1404 /* User Controls */
1405 dev->volume = v4l2_ctrl_new_std(hdl_user_aud, NULL,
1406 V4L2_CID_AUDIO_VOLUME, 0, 255, 1, 200);
1407 dev->mute = v4l2_ctrl_new_std(hdl_user_aud, NULL,
1408 V4L2_CID_AUDIO_MUTE, 0, 1, 1, 0);
1409 if (dev->has_vid_cap) {
1410 dev->brightness = v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops,
1411 V4L2_CID_BRIGHTNESS, 0, 255, 1, 128);
1412 for (i = 0; i < MAX_INPUTS; i++)
1413 dev->input_brightness[i] = 128;
1414 dev->contrast = v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops,
1415 V4L2_CID_CONTRAST, 0, 255, 1, 128);
1416 dev->saturation = v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops,
1417 V4L2_CID_SATURATION, 0, 255, 1, 128);
1418 dev->hue = v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops,
1419 V4L2_CID_HUE, -128, 128, 1, 0);
1420 v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops,
1421 V4L2_CID_HFLIP, 0, 1, 1, 0);
1422 v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops,
1423 V4L2_CID_VFLIP, 0, 1, 1, 0);
1424 dev->autogain = v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops,
1425 V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
1426 dev->gain = v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops,
1427 V4L2_CID_GAIN, 0, 255, 1, 100);
1428 dev->alpha = v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops,
1429 V4L2_CID_ALPHA_COMPONENT, 0, 255, 1, 0);
1431 dev->button = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_button, NULL);
1432 dev->int32 = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_int32, NULL);
1433 dev->int64 = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_int64, NULL);
1434 dev->boolean = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_boolean, NULL);
1435 dev->menu = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_menu, NULL);
1436 dev->string = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_string, NULL);
1437 dev->bitmask = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_bitmask, NULL);
1438 dev->int_menu = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_int_menu, NULL);
1439 v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_u32_array, NULL);
1440 v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_u16_matrix, NULL);
1441 v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_u8_4d_array, NULL);
1443 if (dev->has_vid_cap) {
1444 /* Image Processing Controls */
1445 struct v4l2_ctrl_config vivid_ctrl_test_pattern = {
1446 .ops = &vivid_vid_cap_ctrl_ops,
1447 .id = VIVID_CID_TEST_PATTERN,
1448 .name = "Test Pattern",
1449 .type = V4L2_CTRL_TYPE_MENU,
1450 .max = TPG_PAT_NOISE,
1451 .qmenu = tpg_pattern_strings,
1454 dev->test_pattern = v4l2_ctrl_new_custom(hdl_vid_cap,
1455 &vivid_ctrl_test_pattern, NULL);
1456 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_perc_fill, NULL);
1457 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_hor_movement, NULL);
1458 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_vert_movement, NULL);
1459 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_osd_mode, NULL);
1460 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_show_border, NULL);
1461 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_show_square, NULL);
1462 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_hflip, NULL);
1463 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_vflip, NULL);
1464 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_insert_sav, NULL);
1465 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_insert_eav, NULL);
1466 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_reduced_fps, NULL);
1467 if (show_ccs_cap) {
1468 dev->ctrl_has_crop_cap = v4l2_ctrl_new_custom(hdl_vid_cap,
1469 &vivid_ctrl_has_crop_cap, NULL);
1470 dev->ctrl_has_compose_cap = v4l2_ctrl_new_custom(hdl_vid_cap,
1471 &vivid_ctrl_has_compose_cap, NULL);
1472 dev->ctrl_has_scaler_cap = v4l2_ctrl_new_custom(hdl_vid_cap,
1473 &vivid_ctrl_has_scaler_cap, NULL);
1476 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_tstamp_src, NULL);
1477 dev->colorspace = v4l2_ctrl_new_custom(hdl_vid_cap,
1478 &vivid_ctrl_colorspace, NULL);
1479 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_xfer_func, NULL);
1480 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_ycbcr_enc, NULL);
1481 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_hsv_enc, NULL);
1482 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_quantization, NULL);
1483 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_alpha_mode, NULL);
1486 if (dev->has_vid_out && show_ccs_out) {
1487 dev->ctrl_has_crop_out = v4l2_ctrl_new_custom(hdl_vid_out,
1488 &vivid_ctrl_has_crop_out, NULL);
1489 dev->ctrl_has_compose_out = v4l2_ctrl_new_custom(hdl_vid_out,
1490 &vivid_ctrl_has_compose_out, NULL);
1491 dev->ctrl_has_scaler_out = v4l2_ctrl_new_custom(hdl_vid_out,
1492 &vivid_ctrl_has_scaler_out, NULL);
1496 * Testing this driver with v4l2-compliance will trigger the error
1497 * injection controls, and after that nothing will work as expected.
1498 * So we have a module option to drop these error injecting controls
1499 * allowing us to run v4l2_compliance again.
1501 if (!no_error_inj) {
1502 v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_disconnect, NULL);
1503 v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_dqbuf_error, NULL);
1504 v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_perc_dropped, NULL);
1505 v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_queue_setup_error, NULL);
1506 v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_buf_prepare_error, NULL);
1507 v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_start_streaming_error, NULL);
1508 v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_queue_error, NULL);
1509 v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_seq_wrap, NULL);
1510 v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_time_wrap, NULL);
1513 if (has_sdtv && (dev->has_vid_cap || dev->has_vbi_cap)) {
1514 if (dev->has_vid_cap)
1515 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_std_aspect_ratio, NULL);
1516 dev->ctrl_std_signal_mode = v4l2_ctrl_new_custom(hdl_sdtv_cap,
1517 &vivid_ctrl_std_signal_mode, NULL);
1518 dev->ctrl_standard = v4l2_ctrl_new_custom(hdl_sdtv_cap,
1519 &vivid_ctrl_standard, NULL);
1520 if (dev->ctrl_std_signal_mode)
1521 v4l2_ctrl_cluster(2, &dev->ctrl_std_signal_mode);
1522 if (dev->has_raw_vbi_cap)
1523 v4l2_ctrl_new_custom(hdl_vbi_cap, &vivid_ctrl_vbi_cap_interlaced, NULL);
1526 if (has_hdmi && dev->has_vid_cap) {
1527 dev->ctrl_dv_timings_signal_mode = v4l2_ctrl_new_custom(hdl_vid_cap,
1528 &vivid_ctrl_dv_timings_signal_mode, NULL);
1530 vivid_ctrl_dv_timings.max = dev->query_dv_timings_size - 1;
1531 vivid_ctrl_dv_timings.qmenu =
1532 (const char * const *)dev->query_dv_timings_qmenu;
1533 dev->ctrl_dv_timings = v4l2_ctrl_new_custom(hdl_vid_cap,
1534 &vivid_ctrl_dv_timings, NULL);
1535 if (dev->ctrl_dv_timings_signal_mode)
1536 v4l2_ctrl_cluster(2, &dev->ctrl_dv_timings_signal_mode);
1538 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_dv_timings_aspect_ratio, NULL);
1539 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_max_edid_blocks, NULL);
1540 dev->real_rgb_range_cap = v4l2_ctrl_new_custom(hdl_vid_cap,
1541 &vivid_ctrl_limited_rgb_range, NULL);
1542 dev->rgb_range_cap = v4l2_ctrl_new_std_menu(hdl_vid_cap,
1543 &vivid_vid_cap_ctrl_ops,
1544 V4L2_CID_DV_RX_RGB_RANGE, V4L2_DV_RGB_RANGE_FULL,
1545 0, V4L2_DV_RGB_RANGE_AUTO);
1547 if (has_hdmi && dev->has_vid_out) {
1549 * We aren't doing anything with this at the moment, but
1550 * HDMI outputs typically have this controls.
1552 dev->ctrl_tx_rgb_range = v4l2_ctrl_new_std_menu(hdl_vid_out, NULL,
1553 V4L2_CID_DV_TX_RGB_RANGE, V4L2_DV_RGB_RANGE_FULL,
1554 0, V4L2_DV_RGB_RANGE_AUTO);
1555 dev->ctrl_tx_mode = v4l2_ctrl_new_std_menu(hdl_vid_out, NULL,
1556 V4L2_CID_DV_TX_MODE, V4L2_DV_TX_MODE_HDMI,
1557 0, V4L2_DV_TX_MODE_HDMI);
1559 if ((dev->has_vid_cap && dev->has_vid_out) ||
1560 (dev->has_vbi_cap && dev->has_vbi_out))
1561 v4l2_ctrl_new_custom(hdl_loop_cap, &vivid_ctrl_loop_video, NULL);
1563 if (dev->has_fb)
1564 v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_clear_fb, NULL);
1566 if (dev->has_radio_rx) {
1567 v4l2_ctrl_new_custom(hdl_radio_rx, &vivid_ctrl_radio_hw_seek_mode, NULL);
1568 v4l2_ctrl_new_custom(hdl_radio_rx, &vivid_ctrl_radio_hw_seek_prog_lim, NULL);
1569 v4l2_ctrl_new_custom(hdl_radio_rx, &vivid_ctrl_radio_rx_rds_blockio, NULL);
1570 v4l2_ctrl_new_custom(hdl_radio_rx, &vivid_ctrl_radio_rx_rds_rbds, NULL);
1571 v4l2_ctrl_new_std(hdl_radio_rx, &vivid_radio_rx_ctrl_ops,
1572 V4L2_CID_RDS_RECEPTION, 0, 1, 1, 1);
1573 dev->radio_rx_rds_pty = v4l2_ctrl_new_std(hdl_radio_rx,
1574 &vivid_radio_rx_ctrl_ops,
1575 V4L2_CID_RDS_RX_PTY, 0, 31, 1, 0);
1576 dev->radio_rx_rds_psname = v4l2_ctrl_new_std(hdl_radio_rx,
1577 &vivid_radio_rx_ctrl_ops,
1578 V4L2_CID_RDS_RX_PS_NAME, 0, 8, 8, 0);
1579 dev->radio_rx_rds_radiotext = v4l2_ctrl_new_std(hdl_radio_rx,
1580 &vivid_radio_rx_ctrl_ops,
1581 V4L2_CID_RDS_RX_RADIO_TEXT, 0, 64, 64, 0);
1582 dev->radio_rx_rds_ta = v4l2_ctrl_new_std(hdl_radio_rx,
1583 &vivid_radio_rx_ctrl_ops,
1584 V4L2_CID_RDS_RX_TRAFFIC_ANNOUNCEMENT, 0, 1, 1, 0);
1585 dev->radio_rx_rds_tp = v4l2_ctrl_new_std(hdl_radio_rx,
1586 &vivid_radio_rx_ctrl_ops,
1587 V4L2_CID_RDS_RX_TRAFFIC_PROGRAM, 0, 1, 1, 0);
1588 dev->radio_rx_rds_ms = v4l2_ctrl_new_std(hdl_radio_rx,
1589 &vivid_radio_rx_ctrl_ops,
1590 V4L2_CID_RDS_RX_MUSIC_SPEECH, 0, 1, 1, 1);
1592 if (dev->has_radio_tx) {
1593 v4l2_ctrl_new_custom(hdl_radio_tx,
1594 &vivid_ctrl_radio_tx_rds_blockio, NULL);
1595 dev->radio_tx_rds_pi = v4l2_ctrl_new_std(hdl_radio_tx,
1596 &vivid_radio_tx_ctrl_ops,
1597 V4L2_CID_RDS_TX_PI, 0, 0xffff, 1, 0x8088);
1598 dev->radio_tx_rds_pty = v4l2_ctrl_new_std(hdl_radio_tx,
1599 &vivid_radio_tx_ctrl_ops,
1600 V4L2_CID_RDS_TX_PTY, 0, 31, 1, 3);
1601 dev->radio_tx_rds_psname = v4l2_ctrl_new_std(hdl_radio_tx,
1602 &vivid_radio_tx_ctrl_ops,
1603 V4L2_CID_RDS_TX_PS_NAME, 0, 8, 8, 0);
1604 if (dev->radio_tx_rds_psname)
1605 v4l2_ctrl_s_ctrl_string(dev->radio_tx_rds_psname, "VIVID-TX");
1606 dev->radio_tx_rds_radiotext = v4l2_ctrl_new_std(hdl_radio_tx,
1607 &vivid_radio_tx_ctrl_ops,
1608 V4L2_CID_RDS_TX_RADIO_TEXT, 0, 64 * 2, 64, 0);
1609 if (dev->radio_tx_rds_radiotext)
1610 v4l2_ctrl_s_ctrl_string(dev->radio_tx_rds_radiotext,
1611 "This is a VIVID default Radio Text template text, change at will");
1612 dev->radio_tx_rds_mono_stereo = v4l2_ctrl_new_std(hdl_radio_tx,
1613 &vivid_radio_tx_ctrl_ops,
1614 V4L2_CID_RDS_TX_MONO_STEREO, 0, 1, 1, 1);
1615 dev->radio_tx_rds_art_head = v4l2_ctrl_new_std(hdl_radio_tx,
1616 &vivid_radio_tx_ctrl_ops,
1617 V4L2_CID_RDS_TX_ARTIFICIAL_HEAD, 0, 1, 1, 0);
1618 dev->radio_tx_rds_compressed = v4l2_ctrl_new_std(hdl_radio_tx,
1619 &vivid_radio_tx_ctrl_ops,
1620 V4L2_CID_RDS_TX_COMPRESSED, 0, 1, 1, 0);
1621 dev->radio_tx_rds_dyn_pty = v4l2_ctrl_new_std(hdl_radio_tx,
1622 &vivid_radio_tx_ctrl_ops,
1623 V4L2_CID_RDS_TX_DYNAMIC_PTY, 0, 1, 1, 0);
1624 dev->radio_tx_rds_ta = v4l2_ctrl_new_std(hdl_radio_tx,
1625 &vivid_radio_tx_ctrl_ops,
1626 V4L2_CID_RDS_TX_TRAFFIC_ANNOUNCEMENT, 0, 1, 1, 0);
1627 dev->radio_tx_rds_tp = v4l2_ctrl_new_std(hdl_radio_tx,
1628 &vivid_radio_tx_ctrl_ops,
1629 V4L2_CID_RDS_TX_TRAFFIC_PROGRAM, 0, 1, 1, 1);
1630 dev->radio_tx_rds_ms = v4l2_ctrl_new_std(hdl_radio_tx,
1631 &vivid_radio_tx_ctrl_ops,
1632 V4L2_CID_RDS_TX_MUSIC_SPEECH, 0, 1, 1, 1);
1634 if (dev->has_sdr_cap) {
1635 v4l2_ctrl_new_custom(hdl_sdr_cap,
1636 &vivid_ctrl_sdr_cap_fm_deviation, NULL);
1638 if (hdl_user_gen->error)
1639 return hdl_user_gen->error;
1640 if (hdl_user_vid->error)
1641 return hdl_user_vid->error;
1642 if (hdl_user_aud->error)
1643 return hdl_user_aud->error;
1644 if (hdl_streaming->error)
1645 return hdl_streaming->error;
1646 if (hdl_sdr_cap->error)
1647 return hdl_sdr_cap->error;
1648 if (hdl_loop_cap->error)
1649 return hdl_loop_cap->error;
1651 if (dev->autogain)
1652 v4l2_ctrl_auto_cluster(2, &dev->autogain, 0, true);
1654 if (dev->has_vid_cap) {
1655 v4l2_ctrl_add_handler(hdl_vid_cap, hdl_user_gen, NULL);
1656 v4l2_ctrl_add_handler(hdl_vid_cap, hdl_user_vid, NULL);
1657 v4l2_ctrl_add_handler(hdl_vid_cap, hdl_user_aud, NULL);
1658 v4l2_ctrl_add_handler(hdl_vid_cap, hdl_streaming, NULL);
1659 v4l2_ctrl_add_handler(hdl_vid_cap, hdl_sdtv_cap, NULL);
1660 v4l2_ctrl_add_handler(hdl_vid_cap, hdl_loop_cap, NULL);
1661 if (hdl_vid_cap->error)
1662 return hdl_vid_cap->error;
1663 dev->vid_cap_dev.ctrl_handler = hdl_vid_cap;
1665 if (dev->has_vid_out) {
1666 v4l2_ctrl_add_handler(hdl_vid_out, hdl_user_gen, NULL);
1667 v4l2_ctrl_add_handler(hdl_vid_out, hdl_user_aud, NULL);
1668 v4l2_ctrl_add_handler(hdl_vid_out, hdl_streaming, NULL);
1669 if (hdl_vid_out->error)
1670 return hdl_vid_out->error;
1671 dev->vid_out_dev.ctrl_handler = hdl_vid_out;
1673 if (dev->has_vbi_cap) {
1674 v4l2_ctrl_add_handler(hdl_vbi_cap, hdl_user_gen, NULL);
1675 v4l2_ctrl_add_handler(hdl_vbi_cap, hdl_streaming, NULL);
1676 v4l2_ctrl_add_handler(hdl_vbi_cap, hdl_sdtv_cap, NULL);
1677 v4l2_ctrl_add_handler(hdl_vbi_cap, hdl_loop_cap, NULL);
1678 if (hdl_vbi_cap->error)
1679 return hdl_vbi_cap->error;
1680 dev->vbi_cap_dev.ctrl_handler = hdl_vbi_cap;
1682 if (dev->has_vbi_out) {
1683 v4l2_ctrl_add_handler(hdl_vbi_out, hdl_user_gen, NULL);
1684 v4l2_ctrl_add_handler(hdl_vbi_out, hdl_streaming, NULL);
1685 if (hdl_vbi_out->error)
1686 return hdl_vbi_out->error;
1687 dev->vbi_out_dev.ctrl_handler = hdl_vbi_out;
1689 if (dev->has_radio_rx) {
1690 v4l2_ctrl_add_handler(hdl_radio_rx, hdl_user_gen, NULL);
1691 v4l2_ctrl_add_handler(hdl_radio_rx, hdl_user_aud, NULL);
1692 if (hdl_radio_rx->error)
1693 return hdl_radio_rx->error;
1694 dev->radio_rx_dev.ctrl_handler = hdl_radio_rx;
1696 if (dev->has_radio_tx) {
1697 v4l2_ctrl_add_handler(hdl_radio_tx, hdl_user_gen, NULL);
1698 v4l2_ctrl_add_handler(hdl_radio_tx, hdl_user_aud, NULL);
1699 if (hdl_radio_tx->error)
1700 return hdl_radio_tx->error;
1701 dev->radio_tx_dev.ctrl_handler = hdl_radio_tx;
1703 if (dev->has_sdr_cap) {
1704 v4l2_ctrl_add_handler(hdl_sdr_cap, hdl_user_gen, NULL);
1705 v4l2_ctrl_add_handler(hdl_sdr_cap, hdl_streaming, NULL);
1706 if (hdl_sdr_cap->error)
1707 return hdl_sdr_cap->error;
1708 dev->sdr_cap_dev.ctrl_handler = hdl_sdr_cap;
1710 return 0;
1713 void vivid_free_controls(struct vivid_dev *dev)
1715 v4l2_ctrl_handler_free(&dev->ctrl_hdl_vid_cap);
1716 v4l2_ctrl_handler_free(&dev->ctrl_hdl_vid_out);
1717 v4l2_ctrl_handler_free(&dev->ctrl_hdl_vbi_cap);
1718 v4l2_ctrl_handler_free(&dev->ctrl_hdl_vbi_out);
1719 v4l2_ctrl_handler_free(&dev->ctrl_hdl_radio_rx);
1720 v4l2_ctrl_handler_free(&dev->ctrl_hdl_radio_tx);
1721 v4l2_ctrl_handler_free(&dev->ctrl_hdl_sdr_cap);
1722 v4l2_ctrl_handler_free(&dev->ctrl_hdl_user_gen);
1723 v4l2_ctrl_handler_free(&dev->ctrl_hdl_user_vid);
1724 v4l2_ctrl_handler_free(&dev->ctrl_hdl_user_aud);
1725 v4l2_ctrl_handler_free(&dev->ctrl_hdl_streaming);
1726 v4l2_ctrl_handler_free(&dev->ctrl_hdl_sdtv_cap);
1727 v4l2_ctrl_handler_free(&dev->ctrl_hdl_loop_cap);