]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/blob - drivers/media/platform/vivid/vivid-ctrls.c
[media] vivid: add the Test Pattern Generator
[mirror_ubuntu-hirsute-kernel.git] / drivers / media / platform / vivid / vivid-ctrls.c
1 /*
2 * vivid-ctrls.c - control support functions.
3 *
4 * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
5 *
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.
9 *
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.
18 */
19
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>
25
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"
33
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
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)
55
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)
75
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)
88
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)
93
94 #define VIVID_CID_RADIO_TX_RDS_BLOCKIO (VIVID_CID_VIVID_BASE + 94)
95
96
97 /* General User Controls */
98
99 static int vivid_user_gen_s_ctrl(struct v4l2_ctrl *ctrl)
100 {
101 struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_user_gen);
102
103 switch (ctrl->id) {
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);
113 break;
114 case VIVID_CID_CLEAR_FB:
115 vivid_clear_fb(dev);
116 break;
117 case VIVID_CID_BUTTON:
118 dev->button_pressed = 30;
119 break;
120 }
121 return 0;
122 }
123
124 static const struct v4l2_ctrl_ops vivid_user_gen_ctrl_ops = {
125 .s_ctrl = vivid_user_gen_s_ctrl,
126 };
127
128 static const struct v4l2_ctrl_config vivid_ctrl_button = {
129 .ops = &vivid_user_gen_ctrl_ops,
130 .id = VIVID_CID_BUTTON,
131 .name = "Button",
132 .type = V4L2_CTRL_TYPE_BUTTON,
133 };
134
135 static const struct v4l2_ctrl_config vivid_ctrl_boolean = {
136 .ops = &vivid_user_gen_ctrl_ops,
137 .id = VIVID_CID_BOOLEAN,
138 .name = "Boolean",
139 .type = V4L2_CTRL_TYPE_BOOLEAN,
140 .min = 0,
141 .max = 1,
142 .step = 1,
143 .def = 1,
144 };
145
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,
152 .max = 0x7fffffff,
153 .step = 1,
154 };
155
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,
163 .step = 1,
164 };
165
166 static const char * const vivid_ctrl_menu_strings[] = {
167 "Menu Item 0 (Skipped)",
168 "Menu Item 1",
169 "Menu Item 2 (Skipped)",
170 "Menu Item 3",
171 "Menu Item 4",
172 "Menu Item 5 (Skipped)",
173 NULL,
174 };
175
176 static const struct v4l2_ctrl_config vivid_ctrl_menu = {
177 .ops = &vivid_user_gen_ctrl_ops,
178 .id = VIVID_CID_MENU,
179 .name = "Menu",
180 .type = V4L2_CTRL_TYPE_MENU,
181 .min = 1,
182 .max = 4,
183 .def = 3,
184 .menu_skip_mask = 0x04,
185 .qmenu = vivid_ctrl_menu_strings,
186 };
187
188 static const struct v4l2_ctrl_config vivid_ctrl_string = {
189 .ops = &vivid_user_gen_ctrl_ops,
190 .id = VIVID_CID_STRING,
191 .name = "String",
192 .type = V4L2_CTRL_TYPE_STRING,
193 .min = 2,
194 .max = 4,
195 .step = 1,
196 };
197
198 static const struct v4l2_ctrl_config vivid_ctrl_bitmask = {
199 .ops = &vivid_user_gen_ctrl_ops,
200 .id = VIVID_CID_BITMASK,
201 .name = "Bitmask",
202 .type = V4L2_CTRL_TYPE_BITMASK,
203 .def = 0x80002000,
204 .min = 0,
205 .max = 0x80402010,
206 .step = 0,
207 };
208
209 static const s64 vivid_ctrl_int_menu_values[] = {
210 1, 1, 2, 3, 5, 8, 13, 21, 42,
211 };
212
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,
218 .min = 1,
219 .max = 8,
220 .def = 4,
221 .menu_skip_mask = 0x02,
222 .qmenu_int = vivid_ctrl_int_menu_values,
223 };
224
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,
230 };
231
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,
237 };
238
239
240 /* Video User Controls */
241
242 static int vivid_user_vid_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
243 {
244 struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_user_vid);
245
246 switch (ctrl->id) {
247 case V4L2_CID_AUTOGAIN:
248 dev->gain->val = dev->jiffies_vid_cap & 0xff;
249 break;
250 }
251 return 0;
252 }
253
254 static int vivid_user_vid_s_ctrl(struct v4l2_ctrl *ctrl)
255 {
256 struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_user_vid);
257
258 switch (ctrl->id) {
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]);
262 break;
263 case V4L2_CID_CONTRAST:
264 tpg_s_contrast(&dev->tpg, ctrl->val);
265 break;
266 case V4L2_CID_SATURATION:
267 tpg_s_saturation(&dev->tpg, ctrl->val);
268 break;
269 case V4L2_CID_HUE:
270 tpg_s_hue(&dev->tpg, ctrl->val);
271 break;
272 case V4L2_CID_HFLIP:
273 dev->hflip = ctrl->val;
274 tpg_s_hflip(&dev->tpg, dev->sensor_hflip ^ dev->hflip);
275 break;
276 case V4L2_CID_VFLIP:
277 dev->vflip = ctrl->val;
278 tpg_s_vflip(&dev->tpg, dev->sensor_vflip ^ dev->vflip);
279 break;
280 case V4L2_CID_ALPHA_COMPONENT:
281 tpg_s_alpha_component(&dev->tpg, ctrl->val);
282 break;
283 }
284 return 0;
285 }
286
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,
290 };
291
292
293 /* Video Capture Controls */
294
295 static int vivid_vid_cap_s_ctrl(struct v4l2_ctrl *ctrl)
296 {
297 struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_vid_cap);
298 unsigned i;
299
300 switch (ctrl->id) {
301 case VIVID_CID_TEST_PATTERN:
302 vivid_update_quality(dev);
303 tpg_s_pattern(&dev->tpg, ctrl->val);
304 break;
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);
311 break;
312 case V4L2_CID_DV_RX_RGB_RANGE:
313 if (!vivid_is_hdmi_cap(dev))
314 break;
315 tpg_s_rgb_range(&dev->tpg, ctrl->val);
316 break;
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);
320 break;
321 case VIVID_CID_ALPHA_MODE:
322 tpg_s_alpha_mode(&dev->tpg, ctrl->val);
323 break;
324 case VIVID_CID_HOR_MOVEMENT:
325 tpg_s_mv_hor_mode(&dev->tpg, ctrl->val);
326 break;
327 case VIVID_CID_VERT_MOVEMENT:
328 tpg_s_mv_vert_mode(&dev->tpg, ctrl->val);
329 break;
330 case VIVID_CID_OSD_TEXT_MODE:
331 dev->osd_mode = ctrl->val;
332 break;
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;
337 break;
338 case VIVID_CID_INSERT_SAV:
339 tpg_s_insert_sav(&dev->tpg, ctrl->val);
340 break;
341 case VIVID_CID_INSERT_EAV:
342 tpg_s_insert_eav(&dev->tpg, ctrl->val);
343 break;
344 case VIVID_CID_HFLIP:
345 dev->sensor_hflip = ctrl->val;
346 tpg_s_hflip(&dev->tpg, dev->sensor_hflip ^ dev->hflip);
347 break;
348 case VIVID_CID_VFLIP:
349 dev->sensor_vflip = ctrl->val;
350 tpg_s_vflip(&dev->tpg, dev->sensor_vflip ^ dev->vflip);
351 break;
352 case VIVID_CID_HAS_CROP_CAP:
353 dev->has_crop_cap = ctrl->val;
354 vivid_update_format_cap(dev, true);
355 break;
356 case VIVID_CID_HAS_COMPOSE_CAP:
357 dev->has_compose_cap = ctrl->val;
358 vivid_update_format_cap(dev, true);
359 break;
360 case VIVID_CID_HAS_SCALER_CAP:
361 dev->has_scaler_cap = ctrl->val;
362 vivid_update_format_cap(dev, true);
363 break;
364 case VIVID_CID_SHOW_BORDER:
365 tpg_s_show_border(&dev->tpg, ctrl->val);
366 break;
367 case VIVID_CID_SHOW_SQUARE:
368 tpg_s_show_square(&dev->tpg, ctrl->val);
369 break;
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));
373 break;
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);
382 break;
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));
386 break;
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;
392 break;
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;
397 break;
398 }
399 return 0;
400 }
401
402 static const struct v4l2_ctrl_ops vivid_vid_cap_ctrl_ops = {
403 .s_ctrl = vivid_vid_cap_s_ctrl,
404 };
405
406 static const char * const vivid_ctrl_hor_movement_strings[] = {
407 "Move Left Fast",
408 "Move Left",
409 "Move Left Slow",
410 "No Movement",
411 "Move Right Slow",
412 "Move Right",
413 "Move Right Fast",
414 NULL,
415 };
416
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,
425 };
426
427 static const char * const vivid_ctrl_vert_movement_strings[] = {
428 "Move Up Fast",
429 "Move Up",
430 "Move Up Slow",
431 "No Movement",
432 "Move Down Slow",
433 "Move Down",
434 "Move Down Fast",
435 NULL,
436 };
437
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,
446 };
447
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,
453 .max = 1,
454 .step = 1,
455 };
456
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,
462 .max = 1,
463 .step = 1,
464 };
465
466 static const char * const vivid_ctrl_osd_mode_strings[] = {
467 "All",
468 "Counters Only",
469 "None",
470 NULL,
471 };
472
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,
478 .max = 2,
479 .qmenu = vivid_ctrl_osd_mode_strings,
480 };
481
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,
487 .min = 0,
488 .max = 100,
489 .def = 100,
490 .step = 1,
491 };
492
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,
498 .max = 1,
499 .step = 1,
500 };
501
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,
507 .max = 1,
508 .step = 1,
509 };
510
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,
516 .max = 1,
517 .step = 1,
518 };
519
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,
525 .max = 1,
526 .step = 1,
527 };
528
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,
534 .max = 1,
535 .def = 1,
536 .step = 1,
537 };
538
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,
544 .max = 1,
545 .def = 1,
546 .step = 1,
547 };
548
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,
554 .max = 1,
555 .def = 1,
556 .step = 1,
557 };
558
559 static const char * const vivid_ctrl_tstamp_src_strings[] = {
560 "End of Frame",
561 "Start of Exposure",
562 NULL,
563 };
564
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,
570 .max = 1,
571 .qmenu = vivid_ctrl_tstamp_src_strings,
572 };
573
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,
579 .min = 1,
580 .max = 4,
581 .def = 1,
582 .qmenu = tpg_aspect_strings,
583 };
584
585 static const char * const vivid_ctrl_dv_timings_signal_mode_strings[] = {
586 "Current DV Timings",
587 "No Signal",
588 "No Lock",
589 "Out of Range",
590 "Selected DV Timings",
591 "Cycle Through All DV Timings",
592 "Custom DV Timings",
593 NULL,
594 };
595
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,
601 .max = 5,
602 .qmenu = vivid_ctrl_dv_timings_signal_mode_strings,
603 };
604
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,
610 .max = 3,
611 .qmenu = tpg_aspect_strings,
612 };
613
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,
619 .min = 1,
620 .max = 256,
621 .def = 2,
622 .step = 1,
623 };
624
625 static const char * const vivid_ctrl_colorspace_strings[] = {
626 "",
627 "SMPTE 170M",
628 "SMPTE 240M",
629 "REC 709",
630 "", /* Skip Bt878 entry */
631 "470 System M",
632 "470 System BG",
633 "", /* Skip JPEG entry */
634 "sRGB",
635 NULL,
636 };
637
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,
643 .min = 1,
644 .max = 8,
645 .menu_skip_mask = (1 << 4) | (1 << 7),
646 .def = 8,
647 .qmenu = vivid_ctrl_colorspace_strings,
648 };
649
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,
655 .max = 1,
656 .step = 1,
657 };
658
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,
664 .max = 1,
665 .step = 1,
666 };
667
668
669 /* VBI Capture Control */
670
671 static int vivid_vbi_cap_s_ctrl(struct v4l2_ctrl *ctrl)
672 {
673 struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_vbi_cap);
674
675 switch (ctrl->id) {
676 case VIVID_CID_VBI_CAP_INTERLACED:
677 dev->vbi_cap_interlaced = ctrl->val;
678 break;
679 }
680 return 0;
681 }
682
683 static const struct v4l2_ctrl_ops vivid_vbi_cap_ctrl_ops = {
684 .s_ctrl = vivid_vbi_cap_s_ctrl,
685 };
686
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,
692 .max = 1,
693 .step = 1,
694 };
695
696
697 /* Video Output Controls */
698
699 static int vivid_vid_out_s_ctrl(struct v4l2_ctrl *ctrl)
700 {
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;
703
704 switch (ctrl->id) {
705 case VIVID_CID_HAS_CROP_OUT:
706 dev->has_crop_out = ctrl->val;
707 vivid_update_format_out(dev);
708 break;
709 case VIVID_CID_HAS_COMPOSE_OUT:
710 dev->has_compose_out = ctrl->val;
711 vivid_update_format_out(dev);
712 break;
713 case VIVID_CID_HAS_SCALER_OUT:
714 dev->has_scaler_out = ctrl->val;
715 vivid_update_format_out(dev);
716 break;
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))
720 break;
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;
724 else
725 dev->colorspace_out = V4L2_COLORSPACE_REC709;
726 } else {
727 dev->colorspace_out = V4L2_COLORSPACE_SRGB;
728 }
729 if (dev->loop_video)
730 vivid_send_source_change(dev, HDMI);
731 break;
732 }
733 return 0;
734 }
735
736 static const struct v4l2_ctrl_ops vivid_vid_out_ctrl_ops = {
737 .s_ctrl = vivid_vid_out_s_ctrl,
738 };
739
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,
745 .max = 1,
746 .def = 1,
747 .step = 1,
748 };
749
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,
755 .max = 1,
756 .def = 1,
757 .step = 1,
758 };
759
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,
765 .max = 1,
766 .def = 1,
767 .step = 1,
768 };
769
770
771 /* Streaming Controls */
772
773 static int vivid_streaming_s_ctrl(struct v4l2_ctrl *ctrl)
774 {
775 struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_streaming);
776 struct timeval tv;
777
778 switch (ctrl->id) {
779 case VIVID_CID_DQBUF_ERROR:
780 dev->dqbuf_error = true;
781 break;
782 case VIVID_CID_PERC_DROPPED:
783 dev->perc_dropped_buffers = ctrl->val;
784 break;
785 case VIVID_CID_QUEUE_SETUP_ERROR:
786 dev->queue_setup_error = true;
787 break;
788 case VIVID_CID_BUF_PREPARE_ERROR:
789 dev->buf_prepare_error = true;
790 break;
791 case VIVID_CID_START_STR_ERROR:
792 dev->start_streaming_error = true;
793 break;
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);
805 break;
806 case VIVID_CID_SEQ_WRAP:
807 dev->seq_wrap = ctrl->val;
808 break;
809 case VIVID_CID_TIME_WRAP:
810 dev->time_wrap = ctrl->val;
811 if (ctrl->val == 0) {
812 dev->time_wrap_offset = 0;
813 break;
814 }
815 v4l2_get_timestamp(&tv);
816 dev->time_wrap_offset = -tv.tv_sec - 16;
817 break;
818 }
819 return 0;
820 }
821
822 static const struct v4l2_ctrl_ops vivid_streaming_ctrl_ops = {
823 .s_ctrl = vivid_streaming_s_ctrl,
824 };
825
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,
831 };
832
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,
838 .min = 0,
839 .max = 100,
840 .step = 1,
841 };
842
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,
848 };
849
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,
855 };
856
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,
862 };
863
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,
869 };
870
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,
876 .max = 1,
877 .step = 1,
878 };
879
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,
885 .max = 1,
886 .step = 1,
887 };
888
889
890 /* SDTV Capture Controls */
891
892 static int vivid_sdtv_cap_s_ctrl(struct v4l2_ctrl *ctrl)
893 {
894 struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_sdtv_cap);
895
896 switch (ctrl->id) {
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);
905 break;
906 }
907 return 0;
908 }
909
910 static const struct v4l2_ctrl_ops vivid_sdtv_cap_ctrl_ops = {
911 .s_ctrl = vivid_sdtv_cap_s_ctrl,
912 };
913
914 static const char * const vivid_ctrl_std_signal_mode_strings[] = {
915 "Current Standard",
916 "No Signal",
917 "No Lock",
918 "",
919 "Selected Standard",
920 "Cycle Through All Standards",
921 NULL,
922 };
923
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,
929 .max = 5,
930 .menu_skip_mask = 1 << 3,
931 .qmenu = vivid_ctrl_std_signal_mode_strings,
932 };
933
934 static const struct v4l2_ctrl_config vivid_ctrl_standard = {
935 .ops = &vivid_sdtv_cap_ctrl_ops,
936 .id = VIVID_CID_STANDARD,
937 .name = "Standard",
938 .type = V4L2_CTRL_TYPE_MENU,
939 .max = 14,
940 .qmenu = vivid_ctrl_standard_strings,
941 };
942
943
944
945 /* Radio Receiver Controls */
946
947 static int vivid_radio_rx_s_ctrl(struct v4l2_ctrl *ctrl)
948 {
949 struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_radio_rx);
950
951 switch (ctrl->id) {
952 case VIVID_CID_RADIO_SEEK_MODE:
953 dev->radio_rx_hw_seek_mode = ctrl->val;
954 break;
955 case VIVID_CID_RADIO_SEEK_PROG_LIM:
956 dev->radio_rx_hw_seek_prog_lim = ctrl->val;
957 break;
958 case VIVID_CID_RADIO_RX_RDS_RBDS:
959 dev->rds_gen.use_rbds = ctrl->val;
960 break;
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, "");
973 }
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);
980 break;
981 case V4L2_CID_RDS_RECEPTION:
982 dev->radio_rx_rds_enabled = ctrl->val;
983 break;
984 }
985 return 0;
986 }
987
988 static const struct v4l2_ctrl_ops vivid_radio_rx_ctrl_ops = {
989 .s_ctrl = vivid_radio_rx_s_ctrl,
990 };
991
992 static const char * const vivid_ctrl_radio_rds_mode_strings[] = {
993 "Block I/O",
994 "Controls",
995 NULL,
996 };
997
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,
1004 .max = 1,
1005 };
1006
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,
1012 .max = 1,
1013 .step = 1,
1014 };
1015
1016 static const char * const vivid_ctrl_radio_hw_seek_mode_strings[] = {
1017 "Bounded",
1018 "Wrap Around",
1019 "Both",
1020 NULL,
1021 };
1022
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,
1028 .max = 2,
1029 .qmenu = vivid_ctrl_radio_hw_seek_mode_strings,
1030 };
1031
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,
1037 .max = 1,
1038 .step = 1,
1039 };
1040
1041
1042 /* Radio Transmitter Controls */
1043
1044 static int vivid_radio_tx_s_ctrl(struct v4l2_ctrl *ctrl)
1045 {
1046 struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_radio_tx);
1047
1048 switch (ctrl->id) {
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;
1054 break;
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);
1058 break;
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);
1062 break;
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);
1066 break;
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);
1070 break;
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);
1074 break;
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);
1078 break;
1079 }
1080 return 0;
1081 }
1082
1083 static const struct v4l2_ctrl_ops vivid_radio_tx_ctrl_ops = {
1084 .s_ctrl = vivid_radio_tx_s_ctrl,
1085 };
1086
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,
1093 .max = 1,
1094 .def = 1,
1095 };
1096
1097
1098
1099 /* Video Loop Control */
1100
1101 static int vivid_loop_out_s_ctrl(struct v4l2_ctrl *ctrl)
1102 {
1103 struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_loop_out);
1104
1105 switch (ctrl->id) {
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);
1111 break;
1112 }
1113 return 0;
1114 }
1115
1116 static const struct v4l2_ctrl_ops vivid_loop_out_ctrl_ops = {
1117 .s_ctrl = vivid_loop_out_s_ctrl,
1118 };
1119
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,
1125 .max = 1,
1126 .step = 1,
1127 };
1128
1129
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,
1136 };
1137
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)
1141 {
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,
1160 };
1161 int i;
1162
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);
1189
1190 /* User Controls */
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);
1216 }
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);
1225
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,
1235 };
1236
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);
1249 if (show_ccs_cap) {
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);
1256 }
1257
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);
1262 }
1263
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);
1271 }
1272
1273 /*
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.
1278 */
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);
1289 }
1290
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);
1302 }
1303
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);
1307
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);
1315
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);
1324 }
1325 if (has_hdmi && dev->has_vid_out) {
1326 /*
1327 * We aren't doing anything with this at the moment, but
1328 * HDMI outputs typically have this controls.
1329 */
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);
1336 }
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);
1340
1341 if (dev->has_fb)
1342 v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_clear_fb, NULL);
1343
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);
1369 }
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);
1411 }
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;
1424
1425 if (dev->autogain)
1426 v4l2_ctrl_auto_cluster(2, &dev->autogain, 0, true);
1427
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;
1437 }
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;
1446 }
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;
1454 }
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;
1462 }
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;
1469 }
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;
1476 }
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;
1483 }
1484 return 0;
1485 }
1486
1487 void vivid_free_controls(struct vivid_dev *dev)
1488 {
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);
1502 }