1
2
3
4
5
6
7
8#include <linux/errno.h>
9#include <linux/kernel.h>
10#include <linux/videodev2.h>
11#include <media/v4l2-event.h>
12#include <media/v4l2-common.h>
13
14#include "vivid-core.h"
15#include "vivid-vid-cap.h"
16#include "vivid-vid-out.h"
17#include "vivid-vid-common.h"
18#include "vivid-radio-common.h"
19#include "vivid-osd.h"
20#include "vivid-ctrls.h"
21#include "vivid-cec.h"
22
23#define VIVID_CID_CUSTOM_BASE (V4L2_CID_USER_BASE | 0xf000)
24#define VIVID_CID_BUTTON (VIVID_CID_CUSTOM_BASE + 0)
25#define VIVID_CID_BOOLEAN (VIVID_CID_CUSTOM_BASE + 1)
26#define VIVID_CID_INTEGER (VIVID_CID_CUSTOM_BASE + 2)
27#define VIVID_CID_INTEGER64 (VIVID_CID_CUSTOM_BASE + 3)
28#define VIVID_CID_MENU (VIVID_CID_CUSTOM_BASE + 4)
29#define VIVID_CID_STRING (VIVID_CID_CUSTOM_BASE + 5)
30#define VIVID_CID_BITMASK (VIVID_CID_CUSTOM_BASE + 6)
31#define VIVID_CID_INTMENU (VIVID_CID_CUSTOM_BASE + 7)
32#define VIVID_CID_U32_ARRAY (VIVID_CID_CUSTOM_BASE + 8)
33#define VIVID_CID_U16_MATRIX (VIVID_CID_CUSTOM_BASE + 9)
34#define VIVID_CID_U8_4D_ARRAY (VIVID_CID_CUSTOM_BASE + 10)
35#define VIVID_CID_AREA (VIVID_CID_CUSTOM_BASE + 11)
36
37#define VIVID_CID_VIVID_BASE (0x00f00000 | 0xf000)
38#define VIVID_CID_VIVID_CLASS (0x00f00000 | 1)
39#define VIVID_CID_TEST_PATTERN (VIVID_CID_VIVID_BASE + 0)
40#define VIVID_CID_OSD_TEXT_MODE (VIVID_CID_VIVID_BASE + 1)
41#define VIVID_CID_HOR_MOVEMENT (VIVID_CID_VIVID_BASE + 2)
42#define VIVID_CID_VERT_MOVEMENT (VIVID_CID_VIVID_BASE + 3)
43#define VIVID_CID_SHOW_BORDER (VIVID_CID_VIVID_BASE + 4)
44#define VIVID_CID_SHOW_SQUARE (VIVID_CID_VIVID_BASE + 5)
45#define VIVID_CID_INSERT_SAV (VIVID_CID_VIVID_BASE + 6)
46#define VIVID_CID_INSERT_EAV (VIVID_CID_VIVID_BASE + 7)
47#define VIVID_CID_VBI_CAP_INTERLACED (VIVID_CID_VIVID_BASE + 8)
48
49#define VIVID_CID_HFLIP (VIVID_CID_VIVID_BASE + 20)
50#define VIVID_CID_VFLIP (VIVID_CID_VIVID_BASE + 21)
51#define VIVID_CID_STD_ASPECT_RATIO (VIVID_CID_VIVID_BASE + 22)
52#define VIVID_CID_DV_TIMINGS_ASPECT_RATIO (VIVID_CID_VIVID_BASE + 23)
53#define VIVID_CID_TSTAMP_SRC (VIVID_CID_VIVID_BASE + 24)
54#define VIVID_CID_COLORSPACE (VIVID_CID_VIVID_BASE + 25)
55#define VIVID_CID_XFER_FUNC (VIVID_CID_VIVID_BASE + 26)
56#define VIVID_CID_YCBCR_ENC (VIVID_CID_VIVID_BASE + 27)
57#define VIVID_CID_QUANTIZATION (VIVID_CID_VIVID_BASE + 28)
58#define VIVID_CID_LIMITED_RGB_RANGE (VIVID_CID_VIVID_BASE + 29)
59#define VIVID_CID_ALPHA_MODE (VIVID_CID_VIVID_BASE + 30)
60#define VIVID_CID_HAS_CROP_CAP (VIVID_CID_VIVID_BASE + 31)
61#define VIVID_CID_HAS_COMPOSE_CAP (VIVID_CID_VIVID_BASE + 32)
62#define VIVID_CID_HAS_SCALER_CAP (VIVID_CID_VIVID_BASE + 33)
63#define VIVID_CID_HAS_CROP_OUT (VIVID_CID_VIVID_BASE + 34)
64#define VIVID_CID_HAS_COMPOSE_OUT (VIVID_CID_VIVID_BASE + 35)
65#define VIVID_CID_HAS_SCALER_OUT (VIVID_CID_VIVID_BASE + 36)
66#define VIVID_CID_LOOP_VIDEO (VIVID_CID_VIVID_BASE + 37)
67#define VIVID_CID_SEQ_WRAP (VIVID_CID_VIVID_BASE + 38)
68#define VIVID_CID_TIME_WRAP (VIVID_CID_VIVID_BASE + 39)
69#define VIVID_CID_MAX_EDID_BLOCKS (VIVID_CID_VIVID_BASE + 40)
70#define VIVID_CID_PERCENTAGE_FILL (VIVID_CID_VIVID_BASE + 41)
71#define VIVID_CID_REDUCED_FPS (VIVID_CID_VIVID_BASE + 42)
72#define VIVID_CID_HSV_ENC (VIVID_CID_VIVID_BASE + 43)
73#define VIVID_CID_DISPLAY_PRESENT (VIVID_CID_VIVID_BASE + 44)
74
75#define VIVID_CID_STD_SIGNAL_MODE (VIVID_CID_VIVID_BASE + 60)
76#define VIVID_CID_STANDARD (VIVID_CID_VIVID_BASE + 61)
77#define VIVID_CID_DV_TIMINGS_SIGNAL_MODE (VIVID_CID_VIVID_BASE + 62)
78#define VIVID_CID_DV_TIMINGS (VIVID_CID_VIVID_BASE + 63)
79#define VIVID_CID_PERC_DROPPED (VIVID_CID_VIVID_BASE + 64)
80#define VIVID_CID_DISCONNECT (VIVID_CID_VIVID_BASE + 65)
81#define VIVID_CID_DQBUF_ERROR (VIVID_CID_VIVID_BASE + 66)
82#define VIVID_CID_QUEUE_SETUP_ERROR (VIVID_CID_VIVID_BASE + 67)
83#define VIVID_CID_BUF_PREPARE_ERROR (VIVID_CID_VIVID_BASE + 68)
84#define VIVID_CID_START_STR_ERROR (VIVID_CID_VIVID_BASE + 69)
85#define VIVID_CID_QUEUE_ERROR (VIVID_CID_VIVID_BASE + 70)
86#define VIVID_CID_CLEAR_FB (VIVID_CID_VIVID_BASE + 71)
87#define VIVID_CID_REQ_VALIDATE_ERROR (VIVID_CID_VIVID_BASE + 72)
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#define VIVID_CID_SDR_CAP_FM_DEVIATION (VIVID_CID_VIVID_BASE + 110)
97
98#define VIVID_CID_META_CAP_GENERATE_PTS (VIVID_CID_VIVID_BASE + 111)
99#define VIVID_CID_META_CAP_GENERATE_SCR (VIVID_CID_VIVID_BASE + 112)
100
101
102
103static void vivid_unregister_dev(bool valid, struct video_device *vdev)
104{
105 if (!valid)
106 return;
107 clear_bit(V4L2_FL_REGISTERED, &vdev->flags);
108 v4l2_event_wake_all(vdev);
109}
110
111static int vivid_user_gen_s_ctrl(struct v4l2_ctrl *ctrl)
112{
113 struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_user_gen);
114
115 switch (ctrl->id) {
116 case VIVID_CID_DISCONNECT:
117 v4l2_info(&dev->v4l2_dev, "disconnect\n");
118 dev->disconnect_error = true;
119 vivid_unregister_dev(dev->has_vid_cap, &dev->vid_cap_dev);
120 vivid_unregister_dev(dev->has_vid_out, &dev->vid_out_dev);
121 vivid_unregister_dev(dev->has_vbi_cap, &dev->vbi_cap_dev);
122 vivid_unregister_dev(dev->has_vbi_out, &dev->vbi_out_dev);
123 vivid_unregister_dev(dev->has_radio_rx, &dev->radio_rx_dev);
124 vivid_unregister_dev(dev->has_radio_tx, &dev->radio_tx_dev);
125 vivid_unregister_dev(dev->has_sdr_cap, &dev->sdr_cap_dev);
126 vivid_unregister_dev(dev->has_meta_cap, &dev->meta_cap_dev);
127 vivid_unregister_dev(dev->has_meta_out, &dev->meta_out_dev);
128 vivid_unregister_dev(dev->has_touch_cap, &dev->touch_cap_dev);
129 break;
130 case VIVID_CID_BUTTON:
131 dev->button_pressed = 30;
132 break;
133 }
134 return 0;
135}
136
137static const struct v4l2_ctrl_ops vivid_user_gen_ctrl_ops = {
138 .s_ctrl = vivid_user_gen_s_ctrl,
139};
140
141static const struct v4l2_ctrl_config vivid_ctrl_button = {
142 .ops = &vivid_user_gen_ctrl_ops,
143 .id = VIVID_CID_BUTTON,
144 .name = "Button",
145 .type = V4L2_CTRL_TYPE_BUTTON,
146};
147
148static const struct v4l2_ctrl_config vivid_ctrl_boolean = {
149 .ops = &vivid_user_gen_ctrl_ops,
150 .id = VIVID_CID_BOOLEAN,
151 .name = "Boolean",
152 .type = V4L2_CTRL_TYPE_BOOLEAN,
153 .min = 0,
154 .max = 1,
155 .step = 1,
156 .def = 1,
157};
158
159static const struct v4l2_ctrl_config vivid_ctrl_int32 = {
160 .ops = &vivid_user_gen_ctrl_ops,
161 .id = VIVID_CID_INTEGER,
162 .name = "Integer 32 Bits",
163 .type = V4L2_CTRL_TYPE_INTEGER,
164 .min = 0xffffffff80000000ULL,
165 .max = 0x7fffffff,
166 .step = 1,
167};
168
169static const struct v4l2_ctrl_config vivid_ctrl_int64 = {
170 .ops = &vivid_user_gen_ctrl_ops,
171 .id = VIVID_CID_INTEGER64,
172 .name = "Integer 64 Bits",
173 .type = V4L2_CTRL_TYPE_INTEGER64,
174 .min = 0x8000000000000000ULL,
175 .max = 0x7fffffffffffffffLL,
176 .step = 1,
177};
178
179static const struct v4l2_ctrl_config vivid_ctrl_u32_array = {
180 .ops = &vivid_user_gen_ctrl_ops,
181 .id = VIVID_CID_U32_ARRAY,
182 .name = "U32 1 Element Array",
183 .type = V4L2_CTRL_TYPE_U32,
184 .def = 0x18,
185 .min = 0x10,
186 .max = 0x20000,
187 .step = 1,
188 .dims = { 1 },
189};
190
191static const struct v4l2_ctrl_config vivid_ctrl_u16_matrix = {
192 .ops = &vivid_user_gen_ctrl_ops,
193 .id = VIVID_CID_U16_MATRIX,
194 .name = "U16 8x16 Matrix",
195 .type = V4L2_CTRL_TYPE_U16,
196 .def = 0x18,
197 .min = 0x10,
198 .max = 0x2000,
199 .step = 1,
200 .dims = { 8, 16 },
201};
202
203static const struct v4l2_ctrl_config vivid_ctrl_u8_4d_array = {
204 .ops = &vivid_user_gen_ctrl_ops,
205 .id = VIVID_CID_U8_4D_ARRAY,
206 .name = "U8 2x3x4x5 Array",
207 .type = V4L2_CTRL_TYPE_U8,
208 .def = 0x18,
209 .min = 0x10,
210 .max = 0x20,
211 .step = 1,
212 .dims = { 2, 3, 4, 5 },
213};
214
215static const char * const vivid_ctrl_menu_strings[] = {
216 "Menu Item 0 (Skipped)",
217 "Menu Item 1",
218 "Menu Item 2 (Skipped)",
219 "Menu Item 3",
220 "Menu Item 4",
221 "Menu Item 5 (Skipped)",
222 NULL,
223};
224
225static const struct v4l2_ctrl_config vivid_ctrl_menu = {
226 .ops = &vivid_user_gen_ctrl_ops,
227 .id = VIVID_CID_MENU,
228 .name = "Menu",
229 .type = V4L2_CTRL_TYPE_MENU,
230 .min = 1,
231 .max = 4,
232 .def = 3,
233 .menu_skip_mask = 0x04,
234 .qmenu = vivid_ctrl_menu_strings,
235};
236
237static const struct v4l2_ctrl_config vivid_ctrl_string = {
238 .ops = &vivid_user_gen_ctrl_ops,
239 .id = VIVID_CID_STRING,
240 .name = "String",
241 .type = V4L2_CTRL_TYPE_STRING,
242 .min = 2,
243 .max = 4,
244 .step = 1,
245};
246
247static const struct v4l2_ctrl_config vivid_ctrl_bitmask = {
248 .ops = &vivid_user_gen_ctrl_ops,
249 .id = VIVID_CID_BITMASK,
250 .name = "Bitmask",
251 .type = V4L2_CTRL_TYPE_BITMASK,
252 .def = 0x80002000,
253 .min = 0,
254 .max = 0x80402010,
255 .step = 0,
256};
257
258static const s64 vivid_ctrl_int_menu_values[] = {
259 1, 1, 2, 3, 5, 8, 13, 21, 42,
260};
261
262static const struct v4l2_ctrl_config vivid_ctrl_int_menu = {
263 .ops = &vivid_user_gen_ctrl_ops,
264 .id = VIVID_CID_INTMENU,
265 .name = "Integer Menu",
266 .type = V4L2_CTRL_TYPE_INTEGER_MENU,
267 .min = 1,
268 .max = 8,
269 .def = 4,
270 .menu_skip_mask = 0x02,
271 .qmenu_int = vivid_ctrl_int_menu_values,
272};
273
274static const struct v4l2_ctrl_config vivid_ctrl_disconnect = {
275 .ops = &vivid_user_gen_ctrl_ops,
276 .id = VIVID_CID_DISCONNECT,
277 .name = "Disconnect",
278 .type = V4L2_CTRL_TYPE_BUTTON,
279};
280
281static const struct v4l2_area area = {
282 .width = 1000,
283 .height = 2000,
284};
285
286static const struct v4l2_ctrl_config vivid_ctrl_area = {
287 .ops = &vivid_user_gen_ctrl_ops,
288 .id = VIVID_CID_AREA,
289 .name = "Area",
290 .type = V4L2_CTRL_TYPE_AREA,
291 .p_def.p_const = &area,
292};
293
294
295
296static int vivid_fb_s_ctrl(struct v4l2_ctrl *ctrl)
297{
298 struct vivid_dev *dev = container_of(ctrl->handler,
299 struct vivid_dev, ctrl_hdl_fb);
300
301 switch (ctrl->id) {
302 case VIVID_CID_CLEAR_FB:
303 vivid_clear_fb(dev);
304 break;
305 }
306 return 0;
307}
308
309static const struct v4l2_ctrl_ops vivid_fb_ctrl_ops = {
310 .s_ctrl = vivid_fb_s_ctrl,
311};
312
313static const struct v4l2_ctrl_config vivid_ctrl_clear_fb = {
314 .ops = &vivid_fb_ctrl_ops,
315 .id = VIVID_CID_CLEAR_FB,
316 .name = "Clear Framebuffer",
317 .type = V4L2_CTRL_TYPE_BUTTON,
318};
319
320
321
322
323static int vivid_user_vid_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
324{
325 struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_user_vid);
326
327 switch (ctrl->id) {
328 case V4L2_CID_AUTOGAIN:
329 dev->gain->val = (jiffies_to_msecs(jiffies) / 1000) & 0xff;
330 break;
331 }
332 return 0;
333}
334
335static int vivid_user_vid_s_ctrl(struct v4l2_ctrl *ctrl)
336{
337 struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_user_vid);
338
339 switch (ctrl->id) {
340 case V4L2_CID_BRIGHTNESS:
341 dev->input_brightness[dev->input] = ctrl->val - dev->input * 128;
342 tpg_s_brightness(&dev->tpg, dev->input_brightness[dev->input]);
343 break;
344 case V4L2_CID_CONTRAST:
345 tpg_s_contrast(&dev->tpg, ctrl->val);
346 break;
347 case V4L2_CID_SATURATION:
348 tpg_s_saturation(&dev->tpg, ctrl->val);
349 break;
350 case V4L2_CID_HUE:
351 tpg_s_hue(&dev->tpg, ctrl->val);
352 break;
353 case V4L2_CID_HFLIP:
354 dev->hflip = ctrl->val;
355 tpg_s_hflip(&dev->tpg, dev->sensor_hflip ^ dev->hflip);
356 break;
357 case V4L2_CID_VFLIP:
358 dev->vflip = ctrl->val;
359 tpg_s_vflip(&dev->tpg, dev->sensor_vflip ^ dev->vflip);
360 break;
361 case V4L2_CID_ALPHA_COMPONENT:
362 tpg_s_alpha_component(&dev->tpg, ctrl->val);
363 break;
364 }
365 return 0;
366}
367
368static const struct v4l2_ctrl_ops vivid_user_vid_ctrl_ops = {
369 .g_volatile_ctrl = vivid_user_vid_g_volatile_ctrl,
370 .s_ctrl = vivid_user_vid_s_ctrl,
371};
372
373
374
375
376static int vivid_vid_cap_s_ctrl(struct v4l2_ctrl *ctrl)
377{
378 static const u32 colorspaces[] = {
379 V4L2_COLORSPACE_SMPTE170M,
380 V4L2_COLORSPACE_REC709,
381 V4L2_COLORSPACE_SRGB,
382 V4L2_COLORSPACE_OPRGB,
383 V4L2_COLORSPACE_BT2020,
384 V4L2_COLORSPACE_DCI_P3,
385 V4L2_COLORSPACE_SMPTE240M,
386 V4L2_COLORSPACE_470_SYSTEM_M,
387 V4L2_COLORSPACE_470_SYSTEM_BG,
388 };
389 struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_vid_cap);
390 unsigned int i, j;
391
392 switch (ctrl->id) {
393 case VIVID_CID_TEST_PATTERN:
394 vivid_update_quality(dev);
395 tpg_s_pattern(&dev->tpg, ctrl->val);
396 break;
397 case VIVID_CID_COLORSPACE:
398 tpg_s_colorspace(&dev->tpg, colorspaces[ctrl->val]);
399 vivid_send_source_change(dev, TV);
400 vivid_send_source_change(dev, SVID);
401 vivid_send_source_change(dev, HDMI);
402 vivid_send_source_change(dev, WEBCAM);
403 break;
404 case VIVID_CID_XFER_FUNC:
405 tpg_s_xfer_func(&dev->tpg, ctrl->val);
406 vivid_send_source_change(dev, TV);
407 vivid_send_source_change(dev, SVID);
408 vivid_send_source_change(dev, HDMI);
409 vivid_send_source_change(dev, WEBCAM);
410 break;
411 case VIVID_CID_YCBCR_ENC:
412 tpg_s_ycbcr_enc(&dev->tpg, ctrl->val);
413 vivid_send_source_change(dev, TV);
414 vivid_send_source_change(dev, SVID);
415 vivid_send_source_change(dev, HDMI);
416 vivid_send_source_change(dev, WEBCAM);
417 break;
418 case VIVID_CID_HSV_ENC:
419 tpg_s_hsv_enc(&dev->tpg, ctrl->val ? V4L2_HSV_ENC_256 :
420 V4L2_HSV_ENC_180);
421 vivid_send_source_change(dev, TV);
422 vivid_send_source_change(dev, SVID);
423 vivid_send_source_change(dev, HDMI);
424 vivid_send_source_change(dev, WEBCAM);
425 break;
426 case VIVID_CID_QUANTIZATION:
427 tpg_s_quantization(&dev->tpg, ctrl->val);
428 vivid_send_source_change(dev, TV);
429 vivid_send_source_change(dev, SVID);
430 vivid_send_source_change(dev, HDMI);
431 vivid_send_source_change(dev, WEBCAM);
432 break;
433 case V4L2_CID_DV_RX_RGB_RANGE:
434 if (!vivid_is_hdmi_cap(dev))
435 break;
436 tpg_s_rgb_range(&dev->tpg, ctrl->val);
437 break;
438 case VIVID_CID_LIMITED_RGB_RANGE:
439 tpg_s_real_rgb_range(&dev->tpg, ctrl->val ?
440 V4L2_DV_RGB_RANGE_LIMITED : V4L2_DV_RGB_RANGE_FULL);
441 break;
442 case VIVID_CID_ALPHA_MODE:
443 tpg_s_alpha_mode(&dev->tpg, ctrl->val);
444 break;
445 case VIVID_CID_HOR_MOVEMENT:
446 tpg_s_mv_hor_mode(&dev->tpg, ctrl->val);
447 break;
448 case VIVID_CID_VERT_MOVEMENT:
449 tpg_s_mv_vert_mode(&dev->tpg, ctrl->val);
450 break;
451 case VIVID_CID_OSD_TEXT_MODE:
452 dev->osd_mode = ctrl->val;
453 break;
454 case VIVID_CID_PERCENTAGE_FILL:
455 tpg_s_perc_fill(&dev->tpg, ctrl->val);
456 for (i = 0; i < VIDEO_MAX_FRAME; i++)
457 dev->must_blank[i] = ctrl->val < 100;
458 break;
459 case VIVID_CID_INSERT_SAV:
460 tpg_s_insert_sav(&dev->tpg, ctrl->val);
461 break;
462 case VIVID_CID_INSERT_EAV:
463 tpg_s_insert_eav(&dev->tpg, ctrl->val);
464 break;
465 case VIVID_CID_HFLIP:
466 dev->sensor_hflip = ctrl->val;
467 tpg_s_hflip(&dev->tpg, dev->sensor_hflip ^ dev->hflip);
468 break;
469 case VIVID_CID_VFLIP:
470 dev->sensor_vflip = ctrl->val;
471 tpg_s_vflip(&dev->tpg, dev->sensor_vflip ^ dev->vflip);
472 break;
473 case VIVID_CID_REDUCED_FPS:
474 dev->reduced_fps = ctrl->val;
475 vivid_update_format_cap(dev, true);
476 break;
477 case VIVID_CID_HAS_CROP_CAP:
478 dev->has_crop_cap = ctrl->val;
479 vivid_update_format_cap(dev, true);
480 break;
481 case VIVID_CID_HAS_COMPOSE_CAP:
482 dev->has_compose_cap = ctrl->val;
483 vivid_update_format_cap(dev, true);
484 break;
485 case VIVID_CID_HAS_SCALER_CAP:
486 dev->has_scaler_cap = ctrl->val;
487 vivid_update_format_cap(dev, true);
488 break;
489 case VIVID_CID_SHOW_BORDER:
490 tpg_s_show_border(&dev->tpg, ctrl->val);
491 break;
492 case VIVID_CID_SHOW_SQUARE:
493 tpg_s_show_square(&dev->tpg, ctrl->val);
494 break;
495 case VIVID_CID_STD_ASPECT_RATIO:
496 dev->std_aspect_ratio[dev->input] = ctrl->val;
497 tpg_s_video_aspect(&dev->tpg, vivid_get_video_aspect(dev));
498 break;
499 case VIVID_CID_DV_TIMINGS_SIGNAL_MODE:
500 dev->dv_timings_signal_mode[dev->input] =
501 dev->ctrl_dv_timings_signal_mode->val;
502 dev->query_dv_timings[dev->input] = dev->ctrl_dv_timings->val;
503
504 dev->power_present = 0;
505 for (i = 0, j = 0;
506 i < ARRAY_SIZE(dev->dv_timings_signal_mode);
507 i++)
508 if (dev->input_type[i] == HDMI) {
509 if (dev->dv_timings_signal_mode[i] != NO_SIGNAL)
510 dev->power_present |= (1 << j);
511 j++;
512 }
513 __v4l2_ctrl_s_ctrl(dev->ctrl_rx_power_present,
514 dev->power_present);
515
516 v4l2_ctrl_activate(dev->ctrl_dv_timings,
517 dev->dv_timings_signal_mode[dev->input] ==
518 SELECTED_DV_TIMINGS);
519
520 vivid_update_quality(dev);
521 vivid_send_source_change(dev, HDMI);
522 break;
523 case VIVID_CID_DV_TIMINGS_ASPECT_RATIO:
524 dev->dv_timings_aspect_ratio[dev->input] = ctrl->val;
525 tpg_s_video_aspect(&dev->tpg, vivid_get_video_aspect(dev));
526 break;
527 case VIVID_CID_TSTAMP_SRC:
528 dev->tstamp_src_is_soe = ctrl->val;
529 dev->vb_vid_cap_q.timestamp_flags &= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
530 if (dev->tstamp_src_is_soe)
531 dev->vb_vid_cap_q.timestamp_flags |= V4L2_BUF_FLAG_TSTAMP_SRC_SOE;
532 break;
533 case VIVID_CID_MAX_EDID_BLOCKS:
534 dev->edid_max_blocks = ctrl->val;
535 if (dev->edid_blocks > dev->edid_max_blocks)
536 dev->edid_blocks = dev->edid_max_blocks;
537 break;
538 }
539 return 0;
540}
541
542static const struct v4l2_ctrl_ops vivid_vid_cap_ctrl_ops = {
543 .s_ctrl = vivid_vid_cap_s_ctrl,
544};
545
546static const char * const vivid_ctrl_hor_movement_strings[] = {
547 "Move Left Fast",
548 "Move Left",
549 "Move Left Slow",
550 "No Movement",
551 "Move Right Slow",
552 "Move Right",
553 "Move Right Fast",
554 NULL,
555};
556
557static const struct v4l2_ctrl_config vivid_ctrl_hor_movement = {
558 .ops = &vivid_vid_cap_ctrl_ops,
559 .id = VIVID_CID_HOR_MOVEMENT,
560 .name = "Horizontal Movement",
561 .type = V4L2_CTRL_TYPE_MENU,
562 .max = TPG_MOVE_POS_FAST,
563 .def = TPG_MOVE_NONE,
564 .qmenu = vivid_ctrl_hor_movement_strings,
565};
566
567static const char * const vivid_ctrl_vert_movement_strings[] = {
568 "Move Up Fast",
569 "Move Up",
570 "Move Up Slow",
571 "No Movement",
572 "Move Down Slow",
573 "Move Down",
574 "Move Down Fast",
575 NULL,
576};
577
578static const struct v4l2_ctrl_config vivid_ctrl_vert_movement = {
579 .ops = &vivid_vid_cap_ctrl_ops,
580 .id = VIVID_CID_VERT_MOVEMENT,
581 .name = "Vertical Movement",
582 .type = V4L2_CTRL_TYPE_MENU,
583 .max = TPG_MOVE_POS_FAST,
584 .def = TPG_MOVE_NONE,
585 .qmenu = vivid_ctrl_vert_movement_strings,
586};
587
588static const struct v4l2_ctrl_config vivid_ctrl_show_border = {
589 .ops = &vivid_vid_cap_ctrl_ops,
590 .id = VIVID_CID_SHOW_BORDER,
591 .name = "Show Border",
592 .type = V4L2_CTRL_TYPE_BOOLEAN,
593 .max = 1,
594 .step = 1,
595};
596
597static const struct v4l2_ctrl_config vivid_ctrl_show_square = {
598 .ops = &vivid_vid_cap_ctrl_ops,
599 .id = VIVID_CID_SHOW_SQUARE,
600 .name = "Show Square",
601 .type = V4L2_CTRL_TYPE_BOOLEAN,
602 .max = 1,
603 .step = 1,
604};
605
606static const char * const vivid_ctrl_osd_mode_strings[] = {
607 "All",
608 "Counters Only",
609 "None",
610 NULL,
611};
612
613static const struct v4l2_ctrl_config vivid_ctrl_osd_mode = {
614 .ops = &vivid_vid_cap_ctrl_ops,
615 .id = VIVID_CID_OSD_TEXT_MODE,
616 .name = "OSD Text Mode",
617 .type = V4L2_CTRL_TYPE_MENU,
618 .max = ARRAY_SIZE(vivid_ctrl_osd_mode_strings) - 2,
619 .qmenu = vivid_ctrl_osd_mode_strings,
620};
621
622static const struct v4l2_ctrl_config vivid_ctrl_perc_fill = {
623 .ops = &vivid_vid_cap_ctrl_ops,
624 .id = VIVID_CID_PERCENTAGE_FILL,
625 .name = "Fill Percentage of Frame",
626 .type = V4L2_CTRL_TYPE_INTEGER,
627 .min = 0,
628 .max = 100,
629 .def = 100,
630 .step = 1,
631};
632
633static const struct v4l2_ctrl_config vivid_ctrl_insert_sav = {
634 .ops = &vivid_vid_cap_ctrl_ops,
635 .id = VIVID_CID_INSERT_SAV,
636 .name = "Insert SAV Code in Image",
637 .type = V4L2_CTRL_TYPE_BOOLEAN,
638 .max = 1,
639 .step = 1,
640};
641
642static const struct v4l2_ctrl_config vivid_ctrl_insert_eav = {
643 .ops = &vivid_vid_cap_ctrl_ops,
644 .id = VIVID_CID_INSERT_EAV,
645 .name = "Insert EAV Code in Image",
646 .type = V4L2_CTRL_TYPE_BOOLEAN,
647 .max = 1,
648 .step = 1,
649};
650
651static const struct v4l2_ctrl_config vivid_ctrl_hflip = {
652 .ops = &vivid_vid_cap_ctrl_ops,
653 .id = VIVID_CID_HFLIP,
654 .name = "Sensor Flipped Horizontally",
655 .type = V4L2_CTRL_TYPE_BOOLEAN,
656 .max = 1,
657 .step = 1,
658};
659
660static const struct v4l2_ctrl_config vivid_ctrl_vflip = {
661 .ops = &vivid_vid_cap_ctrl_ops,
662 .id = VIVID_CID_VFLIP,
663 .name = "Sensor Flipped Vertically",
664 .type = V4L2_CTRL_TYPE_BOOLEAN,
665 .max = 1,
666 .step = 1,
667};
668
669static const struct v4l2_ctrl_config vivid_ctrl_reduced_fps = {
670 .ops = &vivid_vid_cap_ctrl_ops,
671 .id = VIVID_CID_REDUCED_FPS,
672 .name = "Reduced Framerate",
673 .type = V4L2_CTRL_TYPE_BOOLEAN,
674 .max = 1,
675 .step = 1,
676};
677
678static const struct v4l2_ctrl_config vivid_ctrl_has_crop_cap = {
679 .ops = &vivid_vid_cap_ctrl_ops,
680 .id = VIVID_CID_HAS_CROP_CAP,
681 .name = "Enable Capture Cropping",
682 .type = V4L2_CTRL_TYPE_BOOLEAN,
683 .max = 1,
684 .def = 1,
685 .step = 1,
686};
687
688static const struct v4l2_ctrl_config vivid_ctrl_has_compose_cap = {
689 .ops = &vivid_vid_cap_ctrl_ops,
690 .id = VIVID_CID_HAS_COMPOSE_CAP,
691 .name = "Enable Capture Composing",
692 .type = V4L2_CTRL_TYPE_BOOLEAN,
693 .max = 1,
694 .def = 1,
695 .step = 1,
696};
697
698static const struct v4l2_ctrl_config vivid_ctrl_has_scaler_cap = {
699 .ops = &vivid_vid_cap_ctrl_ops,
700 .id = VIVID_CID_HAS_SCALER_CAP,
701 .name = "Enable Capture Scaler",
702 .type = V4L2_CTRL_TYPE_BOOLEAN,
703 .max = 1,
704 .def = 1,
705 .step = 1,
706};
707
708static const char * const vivid_ctrl_tstamp_src_strings[] = {
709 "End of Frame",
710 "Start of Exposure",
711 NULL,
712};
713
714static const struct v4l2_ctrl_config vivid_ctrl_tstamp_src = {
715 .ops = &vivid_vid_cap_ctrl_ops,
716 .id = VIVID_CID_TSTAMP_SRC,
717 .name = "Timestamp Source",
718 .type = V4L2_CTRL_TYPE_MENU,
719 .max = ARRAY_SIZE(vivid_ctrl_tstamp_src_strings) - 2,
720 .qmenu = vivid_ctrl_tstamp_src_strings,
721};
722
723static const struct v4l2_ctrl_config vivid_ctrl_std_aspect_ratio = {
724 .ops = &vivid_vid_cap_ctrl_ops,
725 .id = VIVID_CID_STD_ASPECT_RATIO,
726 .name = "Standard Aspect Ratio",
727 .type = V4L2_CTRL_TYPE_MENU,
728 .min = 1,
729 .max = 4,
730 .def = 1,
731 .qmenu = tpg_aspect_strings,
732};
733
734static const char * const vivid_ctrl_dv_timings_signal_mode_strings[] = {
735 "Current DV Timings",
736 "No Signal",
737 "No Lock",
738 "Out of Range",
739 "Selected DV Timings",
740 "Cycle Through All DV Timings",
741 "Custom DV Timings",
742 NULL,
743};
744
745static const struct v4l2_ctrl_config vivid_ctrl_dv_timings_signal_mode = {
746 .ops = &vivid_vid_cap_ctrl_ops,
747 .id = VIVID_CID_DV_TIMINGS_SIGNAL_MODE,
748 .name = "DV Timings Signal Mode",
749 .type = V4L2_CTRL_TYPE_MENU,
750 .max = 5,
751 .qmenu = vivid_ctrl_dv_timings_signal_mode_strings,
752};
753
754static const struct v4l2_ctrl_config vivid_ctrl_dv_timings_aspect_ratio = {
755 .ops = &vivid_vid_cap_ctrl_ops,
756 .id = VIVID_CID_DV_TIMINGS_ASPECT_RATIO,
757 .name = "DV Timings Aspect Ratio",
758 .type = V4L2_CTRL_TYPE_MENU,
759 .max = 3,
760 .qmenu = tpg_aspect_strings,
761};
762
763static const struct v4l2_ctrl_config vivid_ctrl_max_edid_blocks = {
764 .ops = &vivid_vid_cap_ctrl_ops,
765 .id = VIVID_CID_MAX_EDID_BLOCKS,
766 .name = "Maximum EDID Blocks",
767 .type = V4L2_CTRL_TYPE_INTEGER,
768 .min = 1,
769 .max = 256,
770 .def = 2,
771 .step = 1,
772};
773
774static const char * const vivid_ctrl_colorspace_strings[] = {
775 "SMPTE 170M",
776 "Rec. 709",
777 "sRGB",
778 "opRGB",
779 "BT.2020",
780 "DCI-P3",
781 "SMPTE 240M",
782 "470 System M",
783 "470 System BG",
784 NULL,
785};
786
787static const struct v4l2_ctrl_config vivid_ctrl_colorspace = {
788 .ops = &vivid_vid_cap_ctrl_ops,
789 .id = VIVID_CID_COLORSPACE,
790 .name = "Colorspace",
791 .type = V4L2_CTRL_TYPE_MENU,
792 .max = ARRAY_SIZE(vivid_ctrl_colorspace_strings) - 2,
793 .def = 2,
794 .qmenu = vivid_ctrl_colorspace_strings,
795};
796
797static const char * const vivid_ctrl_xfer_func_strings[] = {
798 "Default",
799 "Rec. 709",
800 "sRGB",
801 "opRGB",
802 "SMPTE 240M",
803 "None",
804 "DCI-P3",
805 "SMPTE 2084",
806 NULL,
807};
808
809static const struct v4l2_ctrl_config vivid_ctrl_xfer_func = {
810 .ops = &vivid_vid_cap_ctrl_ops,
811 .id = VIVID_CID_XFER_FUNC,
812 .name = "Transfer Function",
813 .type = V4L2_CTRL_TYPE_MENU,
814 .max = ARRAY_SIZE(vivid_ctrl_xfer_func_strings) - 2,
815 .qmenu = vivid_ctrl_xfer_func_strings,
816};
817
818static const char * const vivid_ctrl_ycbcr_enc_strings[] = {
819 "Default",
820 "ITU-R 601",
821 "Rec. 709",
822 "xvYCC 601",
823 "xvYCC 709",
824 "",
825 "BT.2020",
826 "BT.2020 Constant Luminance",
827 "SMPTE 240M",
828 NULL,
829};
830
831static const struct v4l2_ctrl_config vivid_ctrl_ycbcr_enc = {
832 .ops = &vivid_vid_cap_ctrl_ops,
833 .id = VIVID_CID_YCBCR_ENC,
834 .name = "Y'CbCr Encoding",
835 .type = V4L2_CTRL_TYPE_MENU,
836 .menu_skip_mask = 1 << 5,
837 .max = ARRAY_SIZE(vivid_ctrl_ycbcr_enc_strings) - 2,
838 .qmenu = vivid_ctrl_ycbcr_enc_strings,
839};
840
841static const char * const vivid_ctrl_hsv_enc_strings[] = {
842 "Hue 0-179",
843 "Hue 0-256",
844 NULL,
845};
846
847static const struct v4l2_ctrl_config vivid_ctrl_hsv_enc = {
848 .ops = &vivid_vid_cap_ctrl_ops,
849 .id = VIVID_CID_HSV_ENC,
850 .name = "HSV Encoding",
851 .type = V4L2_CTRL_TYPE_MENU,
852 .max = ARRAY_SIZE(vivid_ctrl_hsv_enc_strings) - 2,
853 .qmenu = vivid_ctrl_hsv_enc_strings,
854};
855
856static const char * const vivid_ctrl_quantization_strings[] = {
857 "Default",
858 "Full Range",
859 "Limited Range",
860 NULL,
861};
862
863static const struct v4l2_ctrl_config vivid_ctrl_quantization = {
864 .ops = &vivid_vid_cap_ctrl_ops,
865 .id = VIVID_CID_QUANTIZATION,
866 .name = "Quantization",
867 .type = V4L2_CTRL_TYPE_MENU,
868 .max = ARRAY_SIZE(vivid_ctrl_quantization_strings) - 2,
869 .qmenu = vivid_ctrl_quantization_strings,
870};
871
872static const struct v4l2_ctrl_config vivid_ctrl_alpha_mode = {
873 .ops = &vivid_vid_cap_ctrl_ops,
874 .id = VIVID_CID_ALPHA_MODE,
875 .name = "Apply Alpha To Red Only",
876 .type = V4L2_CTRL_TYPE_BOOLEAN,
877 .max = 1,
878 .step = 1,
879};
880
881static const struct v4l2_ctrl_config vivid_ctrl_limited_rgb_range = {
882 .ops = &vivid_vid_cap_ctrl_ops,
883 .id = VIVID_CID_LIMITED_RGB_RANGE,
884 .name = "Limited RGB Range (16-235)",
885 .type = V4L2_CTRL_TYPE_BOOLEAN,
886 .max = 1,
887 .step = 1,
888};
889
890
891
892
893static int vivid_loop_cap_s_ctrl(struct v4l2_ctrl *ctrl)
894{
895 struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_loop_cap);
896
897 switch (ctrl->id) {
898 case VIVID_CID_LOOP_VIDEO:
899 dev->loop_video = ctrl->val;
900 vivid_update_quality(dev);
901 vivid_send_source_change(dev, SVID);
902 vivid_send_source_change(dev, HDMI);
903 break;
904 }
905 return 0;
906}
907
908static const struct v4l2_ctrl_ops vivid_loop_cap_ctrl_ops = {
909 .s_ctrl = vivid_loop_cap_s_ctrl,
910};
911
912static const struct v4l2_ctrl_config vivid_ctrl_loop_video = {
913 .ops = &vivid_loop_cap_ctrl_ops,
914 .id = VIVID_CID_LOOP_VIDEO,
915 .name = "Loop Video",
916 .type = V4L2_CTRL_TYPE_BOOLEAN,
917 .max = 1,
918 .step = 1,
919};
920
921
922
923
924static int vivid_vbi_cap_s_ctrl(struct v4l2_ctrl *ctrl)
925{
926 struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_vbi_cap);
927
928 switch (ctrl->id) {
929 case VIVID_CID_VBI_CAP_INTERLACED:
930 dev->vbi_cap_interlaced = ctrl->val;
931 break;
932 }
933 return 0;
934}
935
936static const struct v4l2_ctrl_ops vivid_vbi_cap_ctrl_ops = {
937 .s_ctrl = vivid_vbi_cap_s_ctrl,
938};
939
940static const struct v4l2_ctrl_config vivid_ctrl_vbi_cap_interlaced = {
941 .ops = &vivid_vbi_cap_ctrl_ops,
942 .id = VIVID_CID_VBI_CAP_INTERLACED,
943 .name = "Interlaced VBI Format",
944 .type = V4L2_CTRL_TYPE_BOOLEAN,
945 .max = 1,
946 .step = 1,
947};
948
949
950
951
952static int vivid_vid_out_s_ctrl(struct v4l2_ctrl *ctrl)
953{
954 struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_vid_out);
955 struct v4l2_bt_timings *bt = &dev->dv_timings_out.bt;
956 u32 display_present = 0;
957 unsigned int i, j, bus_idx;
958
959 switch (ctrl->id) {
960 case VIVID_CID_HAS_CROP_OUT:
961 dev->has_crop_out = ctrl->val;
962 vivid_update_format_out(dev);
963 break;
964 case VIVID_CID_HAS_COMPOSE_OUT:
965 dev->has_compose_out = ctrl->val;
966 vivid_update_format_out(dev);
967 break;
968 case VIVID_CID_HAS_SCALER_OUT:
969 dev->has_scaler_out = ctrl->val;
970 vivid_update_format_out(dev);
971 break;
972 case V4L2_CID_DV_TX_MODE:
973 dev->dvi_d_out = ctrl->val == V4L2_DV_TX_MODE_DVI_D;
974 if (!vivid_is_hdmi_out(dev))
975 break;
976 if (!dev->dvi_d_out && (bt->flags & V4L2_DV_FL_IS_CE_VIDEO)) {
977 if (bt->width == 720 && bt->height <= 576)
978 dev->colorspace_out = V4L2_COLORSPACE_SMPTE170M;
979 else
980 dev->colorspace_out = V4L2_COLORSPACE_REC709;
981 dev->quantization_out = V4L2_QUANTIZATION_DEFAULT;
982 } else {
983 dev->colorspace_out = V4L2_COLORSPACE_SRGB;
984 dev->quantization_out = dev->dvi_d_out ?
985 V4L2_QUANTIZATION_LIM_RANGE :
986 V4L2_QUANTIZATION_DEFAULT;
987 }
988 if (dev->loop_video)
989 vivid_send_source_change(dev, HDMI);
990 break;
991 case VIVID_CID_DISPLAY_PRESENT:
992 if (dev->output_type[dev->output] != HDMI)
993 break;
994
995 dev->display_present[dev->output] = ctrl->val;
996 for (i = 0, j = 0; i < dev->num_outputs; i++)
997 if (dev->output_type[i] == HDMI)
998 display_present |=
999 dev->display_present[i] << j++;
1000
1001 __v4l2_ctrl_s_ctrl(dev->ctrl_tx_rxsense, display_present);
1002
1003 if (dev->edid_blocks) {
1004 __v4l2_ctrl_s_ctrl(dev->ctrl_tx_edid_present,
1005 display_present);
1006 __v4l2_ctrl_s_ctrl(dev->ctrl_tx_hotplug,
1007 display_present);
1008 }
1009
1010 bus_idx = dev->cec_output2bus_map[dev->output];
1011 if (!dev->cec_tx_adap[bus_idx])
1012 break;
1013
1014 if (ctrl->val && dev->edid_blocks)
1015 cec_s_phys_addr(dev->cec_tx_adap[bus_idx],
1016 dev->cec_tx_adap[bus_idx]->phys_addr,
1017 false);
1018 else
1019 cec_phys_addr_invalidate(dev->cec_tx_adap[bus_idx]);
1020
1021 break;
1022 }
1023 return 0;
1024}
1025
1026static const struct v4l2_ctrl_ops vivid_vid_out_ctrl_ops = {
1027 .s_ctrl = vivid_vid_out_s_ctrl,
1028};
1029
1030static const struct v4l2_ctrl_config vivid_ctrl_has_crop_out = {
1031 .ops = &vivid_vid_out_ctrl_ops,
1032 .id = VIVID_CID_HAS_CROP_OUT,
1033 .name = "Enable Output Cropping",
1034 .type = V4L2_CTRL_TYPE_BOOLEAN,
1035 .max = 1,
1036 .def = 1,
1037 .step = 1,
1038};
1039
1040static const struct v4l2_ctrl_config vivid_ctrl_has_compose_out = {
1041 .ops = &vivid_vid_out_ctrl_ops,
1042 .id = VIVID_CID_HAS_COMPOSE_OUT,
1043 .name = "Enable Output Composing",
1044 .type = V4L2_CTRL_TYPE_BOOLEAN,
1045 .max = 1,
1046 .def = 1,
1047 .step = 1,
1048};
1049
1050static const struct v4l2_ctrl_config vivid_ctrl_has_scaler_out = {
1051 .ops = &vivid_vid_out_ctrl_ops,
1052 .id = VIVID_CID_HAS_SCALER_OUT,
1053 .name = "Enable Output Scaler",
1054 .type = V4L2_CTRL_TYPE_BOOLEAN,
1055 .max = 1,
1056 .def = 1,
1057 .step = 1,
1058};
1059
1060static const struct v4l2_ctrl_config vivid_ctrl_display_present = {
1061 .ops = &vivid_vid_out_ctrl_ops,
1062 .id = VIVID_CID_DISPLAY_PRESENT,
1063 .name = "Display Present",
1064 .type = V4L2_CTRL_TYPE_BOOLEAN,
1065 .max = 1,
1066 .def = 1,
1067 .step = 1,
1068};
1069
1070
1071
1072static int vivid_streaming_s_ctrl(struct v4l2_ctrl *ctrl)
1073{
1074 struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_streaming);
1075 u64 rem;
1076
1077 switch (ctrl->id) {
1078 case VIVID_CID_DQBUF_ERROR:
1079 dev->dqbuf_error = true;
1080 break;
1081 case VIVID_CID_PERC_DROPPED:
1082 dev->perc_dropped_buffers = ctrl->val;
1083 break;
1084 case VIVID_CID_QUEUE_SETUP_ERROR:
1085 dev->queue_setup_error = true;
1086 break;
1087 case VIVID_CID_BUF_PREPARE_ERROR:
1088 dev->buf_prepare_error = true;
1089 break;
1090 case VIVID_CID_START_STR_ERROR:
1091 dev->start_streaming_error = true;
1092 break;
1093 case VIVID_CID_REQ_VALIDATE_ERROR:
1094 dev->req_validate_error = true;
1095 break;
1096 case VIVID_CID_QUEUE_ERROR:
1097 if (vb2_start_streaming_called(&dev->vb_vid_cap_q))
1098 vb2_queue_error(&dev->vb_vid_cap_q);
1099 if (vb2_start_streaming_called(&dev->vb_vbi_cap_q))
1100 vb2_queue_error(&dev->vb_vbi_cap_q);
1101 if (vb2_start_streaming_called(&dev->vb_vid_out_q))
1102 vb2_queue_error(&dev->vb_vid_out_q);
1103 if (vb2_start_streaming_called(&dev->vb_vbi_out_q))
1104 vb2_queue_error(&dev->vb_vbi_out_q);
1105 if (vb2_start_streaming_called(&dev->vb_sdr_cap_q))
1106 vb2_queue_error(&dev->vb_sdr_cap_q);
1107 break;
1108 case VIVID_CID_SEQ_WRAP:
1109 dev->seq_wrap = ctrl->val;
1110 break;
1111 case VIVID_CID_TIME_WRAP:
1112 dev->time_wrap = ctrl->val;
1113 if (ctrl->val == 0) {
1114 dev->time_wrap_offset = 0;
1115 break;
1116 }
1117
1118
1119
1120
1121
1122
1123 div64_u64_rem(ktime_get_ns(),
1124 0x100000000ULL * NSEC_PER_SEC, &rem);
1125 dev->time_wrap_offset =
1126 (0x100000000ULL - 16) * NSEC_PER_SEC - rem;
1127 break;
1128 }
1129 return 0;
1130}
1131
1132static const struct v4l2_ctrl_ops vivid_streaming_ctrl_ops = {
1133 .s_ctrl = vivid_streaming_s_ctrl,
1134};
1135
1136static const struct v4l2_ctrl_config vivid_ctrl_dqbuf_error = {
1137 .ops = &vivid_streaming_ctrl_ops,
1138 .id = VIVID_CID_DQBUF_ERROR,
1139 .name = "Inject V4L2_BUF_FLAG_ERROR",
1140 .type = V4L2_CTRL_TYPE_BUTTON,
1141};
1142
1143static const struct v4l2_ctrl_config vivid_ctrl_perc_dropped = {
1144 .ops = &vivid_streaming_ctrl_ops,
1145 .id = VIVID_CID_PERC_DROPPED,
1146 .name = "Percentage of Dropped Buffers",
1147 .type = V4L2_CTRL_TYPE_INTEGER,
1148 .min = 0,
1149 .max = 100,
1150 .step = 1,
1151};
1152
1153static const struct v4l2_ctrl_config vivid_ctrl_queue_setup_error = {
1154 .ops = &vivid_streaming_ctrl_ops,
1155 .id = VIVID_CID_QUEUE_SETUP_ERROR,
1156 .name = "Inject VIDIOC_REQBUFS Error",
1157 .type = V4L2_CTRL_TYPE_BUTTON,
1158};
1159
1160static const struct v4l2_ctrl_config vivid_ctrl_buf_prepare_error = {
1161 .ops = &vivid_streaming_ctrl_ops,
1162 .id = VIVID_CID_BUF_PREPARE_ERROR,
1163 .name = "Inject VIDIOC_QBUF Error",
1164 .type = V4L2_CTRL_TYPE_BUTTON,
1165};
1166
1167static const struct v4l2_ctrl_config vivid_ctrl_start_streaming_error = {
1168 .ops = &vivid_streaming_ctrl_ops,
1169 .id = VIVID_CID_START_STR_ERROR,
1170 .name = "Inject VIDIOC_STREAMON Error",
1171 .type = V4L2_CTRL_TYPE_BUTTON,
1172};
1173
1174static const struct v4l2_ctrl_config vivid_ctrl_queue_error = {
1175 .ops = &vivid_streaming_ctrl_ops,
1176 .id = VIVID_CID_QUEUE_ERROR,
1177 .name = "Inject Fatal Streaming Error",
1178 .type = V4L2_CTRL_TYPE_BUTTON,
1179};
1180
1181#ifdef CONFIG_MEDIA_CONTROLLER
1182static const struct v4l2_ctrl_config vivid_ctrl_req_validate_error = {
1183 .ops = &vivid_streaming_ctrl_ops,
1184 .id = VIVID_CID_REQ_VALIDATE_ERROR,
1185 .name = "Inject req_validate() Error",
1186 .type = V4L2_CTRL_TYPE_BUTTON,
1187};
1188#endif
1189
1190static const struct v4l2_ctrl_config vivid_ctrl_seq_wrap = {
1191 .ops = &vivid_streaming_ctrl_ops,
1192 .id = VIVID_CID_SEQ_WRAP,
1193 .name = "Wrap Sequence Number",
1194 .type = V4L2_CTRL_TYPE_BOOLEAN,
1195 .max = 1,
1196 .step = 1,
1197};
1198
1199static const struct v4l2_ctrl_config vivid_ctrl_time_wrap = {
1200 .ops = &vivid_streaming_ctrl_ops,
1201 .id = VIVID_CID_TIME_WRAP,
1202 .name = "Wrap Timestamp",
1203 .type = V4L2_CTRL_TYPE_BOOLEAN,
1204 .max = 1,
1205 .step = 1,
1206};
1207
1208
1209
1210
1211static int vivid_sdtv_cap_s_ctrl(struct v4l2_ctrl *ctrl)
1212{
1213 struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_sdtv_cap);
1214
1215 switch (ctrl->id) {
1216 case VIVID_CID_STD_SIGNAL_MODE:
1217 dev->std_signal_mode[dev->input] =
1218 dev->ctrl_std_signal_mode->val;
1219 if (dev->std_signal_mode[dev->input] == SELECTED_STD)
1220 dev->query_std[dev->input] =
1221 vivid_standard[dev->ctrl_standard->val];
1222 v4l2_ctrl_activate(dev->ctrl_standard,
1223 dev->std_signal_mode[dev->input] ==
1224 SELECTED_STD);
1225 vivid_update_quality(dev);
1226 vivid_send_source_change(dev, TV);
1227 vivid_send_source_change(dev, SVID);
1228 break;
1229 }
1230 return 0;
1231}
1232
1233static const struct v4l2_ctrl_ops vivid_sdtv_cap_ctrl_ops = {
1234 .s_ctrl = vivid_sdtv_cap_s_ctrl,
1235};
1236
1237static const char * const vivid_ctrl_std_signal_mode_strings[] = {
1238 "Current Standard",
1239 "No Signal",
1240 "No Lock",
1241 "",
1242 "Selected Standard",
1243 "Cycle Through All Standards",
1244 NULL,
1245};
1246
1247static const struct v4l2_ctrl_config vivid_ctrl_std_signal_mode = {
1248 .ops = &vivid_sdtv_cap_ctrl_ops,
1249 .id = VIVID_CID_STD_SIGNAL_MODE,
1250 .name = "Standard Signal Mode",
1251 .type = V4L2_CTRL_TYPE_MENU,
1252 .max = ARRAY_SIZE(vivid_ctrl_std_signal_mode_strings) - 2,
1253 .menu_skip_mask = 1 << 3,
1254 .qmenu = vivid_ctrl_std_signal_mode_strings,
1255};
1256
1257static const struct v4l2_ctrl_config vivid_ctrl_standard = {
1258 .ops = &vivid_sdtv_cap_ctrl_ops,
1259 .id = VIVID_CID_STANDARD,
1260 .name = "Standard",
1261 .type = V4L2_CTRL_TYPE_MENU,
1262 .max = 14,
1263 .qmenu = vivid_ctrl_standard_strings,
1264};
1265
1266
1267
1268
1269
1270static int vivid_radio_rx_s_ctrl(struct v4l2_ctrl *ctrl)
1271{
1272 struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_radio_rx);
1273
1274 switch (ctrl->id) {
1275 case VIVID_CID_RADIO_SEEK_MODE:
1276 dev->radio_rx_hw_seek_mode = ctrl->val;
1277 break;
1278 case VIVID_CID_RADIO_SEEK_PROG_LIM:
1279 dev->radio_rx_hw_seek_prog_lim = ctrl->val;
1280 break;
1281 case VIVID_CID_RADIO_RX_RDS_RBDS:
1282 dev->rds_gen.use_rbds = ctrl->val;
1283 break;
1284 case VIVID_CID_RADIO_RX_RDS_BLOCKIO:
1285 dev->radio_rx_rds_controls = ctrl->val;
1286 dev->radio_rx_caps &= ~V4L2_CAP_READWRITE;
1287 dev->radio_rx_rds_use_alternates = false;
1288 if (!dev->radio_rx_rds_controls) {
1289 dev->radio_rx_caps |= V4L2_CAP_READWRITE;
1290 __v4l2_ctrl_s_ctrl(dev->radio_rx_rds_pty, 0);
1291 __v4l2_ctrl_s_ctrl(dev->radio_rx_rds_ta, 0);
1292 __v4l2_ctrl_s_ctrl(dev->radio_rx_rds_tp, 0);
1293 __v4l2_ctrl_s_ctrl(dev->radio_rx_rds_ms, 0);
1294 __v4l2_ctrl_s_ctrl_string(dev->radio_rx_rds_psname, "");
1295 __v4l2_ctrl_s_ctrl_string(dev->radio_rx_rds_radiotext, "");
1296 }
1297 v4l2_ctrl_activate(dev->radio_rx_rds_pty, dev->radio_rx_rds_controls);
1298 v4l2_ctrl_activate(dev->radio_rx_rds_psname, dev->radio_rx_rds_controls);
1299 v4l2_ctrl_activate(dev->radio_rx_rds_radiotext, dev->radio_rx_rds_controls);
1300 v4l2_ctrl_activate(dev->radio_rx_rds_ta, dev->radio_rx_rds_controls);
1301 v4l2_ctrl_activate(dev->radio_rx_rds_tp, dev->radio_rx_rds_controls);
1302 v4l2_ctrl_activate(dev->radio_rx_rds_ms, dev->radio_rx_rds_controls);
1303 dev->radio_rx_dev.device_caps = dev->radio_rx_caps;
1304 break;
1305 case V4L2_CID_RDS_RECEPTION:
1306 dev->radio_rx_rds_enabled = ctrl->val;
1307 break;
1308 }
1309 return 0;
1310}
1311
1312static const struct v4l2_ctrl_ops vivid_radio_rx_ctrl_ops = {
1313 .s_ctrl = vivid_radio_rx_s_ctrl,
1314};
1315
1316static const char * const vivid_ctrl_radio_rds_mode_strings[] = {
1317 "Block I/O",
1318 "Controls",
1319 NULL,
1320};
1321
1322static const struct v4l2_ctrl_config vivid_ctrl_radio_rx_rds_blockio = {
1323 .ops = &vivid_radio_rx_ctrl_ops,
1324 .id = VIVID_CID_RADIO_RX_RDS_BLOCKIO,
1325 .name = "RDS Rx I/O Mode",
1326 .type = V4L2_CTRL_TYPE_MENU,
1327 .qmenu = vivid_ctrl_radio_rds_mode_strings,
1328 .max = 1,
1329};
1330
1331static const struct v4l2_ctrl_config vivid_ctrl_radio_rx_rds_rbds = {
1332 .ops = &vivid_radio_rx_ctrl_ops,
1333 .id = VIVID_CID_RADIO_RX_RDS_RBDS,
1334 .name = "Generate RBDS Instead of RDS",
1335 .type = V4L2_CTRL_TYPE_BOOLEAN,
1336 .max = 1,
1337 .step = 1,
1338};
1339
1340static const char * const vivid_ctrl_radio_hw_seek_mode_strings[] = {
1341 "Bounded",
1342 "Wrap Around",
1343 "Both",
1344 NULL,
1345};
1346
1347static const struct v4l2_ctrl_config vivid_ctrl_radio_hw_seek_mode = {
1348 .ops = &vivid_radio_rx_ctrl_ops,
1349 .id = VIVID_CID_RADIO_SEEK_MODE,
1350 .name = "Radio HW Seek Mode",
1351 .type = V4L2_CTRL_TYPE_MENU,
1352 .max = 2,
1353 .qmenu = vivid_ctrl_radio_hw_seek_mode_strings,
1354};
1355
1356static const struct v4l2_ctrl_config vivid_ctrl_radio_hw_seek_prog_lim = {
1357 .ops = &vivid_radio_rx_ctrl_ops,
1358 .id = VIVID_CID_RADIO_SEEK_PROG_LIM,
1359 .name = "Radio Programmable HW Seek",
1360 .type = V4L2_CTRL_TYPE_BOOLEAN,
1361 .max = 1,
1362 .step = 1,
1363};
1364
1365
1366
1367
1368static int vivid_radio_tx_s_ctrl(struct v4l2_ctrl *ctrl)
1369{
1370 struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_radio_tx);
1371
1372 switch (ctrl->id) {
1373 case VIVID_CID_RADIO_TX_RDS_BLOCKIO:
1374 dev->radio_tx_rds_controls = ctrl->val;
1375 dev->radio_tx_caps &= ~V4L2_CAP_READWRITE;
1376 if (!dev->radio_tx_rds_controls)
1377 dev->radio_tx_caps |= V4L2_CAP_READWRITE;
1378 dev->radio_tx_dev.device_caps = dev->radio_tx_caps;
1379 break;
1380 case V4L2_CID_RDS_TX_PTY:
1381 if (dev->radio_rx_rds_controls)
1382 v4l2_ctrl_s_ctrl(dev->radio_rx_rds_pty, ctrl->val);
1383 break;
1384 case V4L2_CID_RDS_TX_PS_NAME:
1385 if (dev->radio_rx_rds_controls)
1386 v4l2_ctrl_s_ctrl_string(dev->radio_rx_rds_psname, ctrl->p_new.p_char);
1387 break;
1388 case V4L2_CID_RDS_TX_RADIO_TEXT:
1389 if (dev->radio_rx_rds_controls)
1390 v4l2_ctrl_s_ctrl_string(dev->radio_rx_rds_radiotext, ctrl->p_new.p_char);
1391 break;
1392 case V4L2_CID_RDS_TX_TRAFFIC_ANNOUNCEMENT:
1393 if (dev->radio_rx_rds_controls)
1394 v4l2_ctrl_s_ctrl(dev->radio_rx_rds_ta, ctrl->val);
1395 break;
1396 case V4L2_CID_RDS_TX_TRAFFIC_PROGRAM:
1397 if (dev->radio_rx_rds_controls)
1398 v4l2_ctrl_s_ctrl(dev->radio_rx_rds_tp, ctrl->val);
1399 break;
1400 case V4L2_CID_RDS_TX_MUSIC_SPEECH:
1401 if (dev->radio_rx_rds_controls)
1402 v4l2_ctrl_s_ctrl(dev->radio_rx_rds_ms, ctrl->val);
1403 break;
1404 }
1405 return 0;
1406}
1407
1408static const struct v4l2_ctrl_ops vivid_radio_tx_ctrl_ops = {
1409 .s_ctrl = vivid_radio_tx_s_ctrl,
1410};
1411
1412static const struct v4l2_ctrl_config vivid_ctrl_radio_tx_rds_blockio = {
1413 .ops = &vivid_radio_tx_ctrl_ops,
1414 .id = VIVID_CID_RADIO_TX_RDS_BLOCKIO,
1415 .name = "RDS Tx I/O Mode",
1416 .type = V4L2_CTRL_TYPE_MENU,
1417 .qmenu = vivid_ctrl_radio_rds_mode_strings,
1418 .max = 1,
1419 .def = 1,
1420};
1421
1422
1423
1424
1425static int vivid_sdr_cap_s_ctrl(struct v4l2_ctrl *ctrl)
1426{
1427 struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_sdr_cap);
1428
1429 switch (ctrl->id) {
1430 case VIVID_CID_SDR_CAP_FM_DEVIATION:
1431 dev->sdr_fm_deviation = ctrl->val;
1432 break;
1433 }
1434 return 0;
1435}
1436
1437static const struct v4l2_ctrl_ops vivid_sdr_cap_ctrl_ops = {
1438 .s_ctrl = vivid_sdr_cap_s_ctrl,
1439};
1440
1441static const struct v4l2_ctrl_config vivid_ctrl_sdr_cap_fm_deviation = {
1442 .ops = &vivid_sdr_cap_ctrl_ops,
1443 .id = VIVID_CID_SDR_CAP_FM_DEVIATION,
1444 .name = "FM Deviation",
1445 .type = V4L2_CTRL_TYPE_INTEGER,
1446 .min = 100,
1447 .max = 200000,
1448 .def = 75000,
1449 .step = 1,
1450};
1451
1452
1453
1454static int vivid_meta_cap_s_ctrl(struct v4l2_ctrl *ctrl)
1455{
1456 struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev,
1457 ctrl_hdl_meta_cap);
1458
1459 switch (ctrl->id) {
1460 case VIVID_CID_META_CAP_GENERATE_PTS:
1461 dev->meta_pts = ctrl->val;
1462 break;
1463 case VIVID_CID_META_CAP_GENERATE_SCR:
1464 dev->meta_scr = ctrl->val;
1465 break;
1466 }
1467 return 0;
1468}
1469
1470static const struct v4l2_ctrl_ops vivid_meta_cap_ctrl_ops = {
1471 .s_ctrl = vivid_meta_cap_s_ctrl,
1472};
1473
1474static const struct v4l2_ctrl_config vivid_ctrl_meta_has_pts = {
1475 .ops = &vivid_meta_cap_ctrl_ops,
1476 .id = VIVID_CID_META_CAP_GENERATE_PTS,
1477 .name = "Generate PTS",
1478 .type = V4L2_CTRL_TYPE_BOOLEAN,
1479 .max = 1,
1480 .def = 1,
1481 .step = 1,
1482};
1483
1484static const struct v4l2_ctrl_config vivid_ctrl_meta_has_src_clk = {
1485 .ops = &vivid_meta_cap_ctrl_ops,
1486 .id = VIVID_CID_META_CAP_GENERATE_SCR,
1487 .name = "Generate SCR",
1488 .type = V4L2_CTRL_TYPE_BOOLEAN,
1489 .max = 1,
1490 .def = 1,
1491 .step = 1,
1492};
1493
1494static const struct v4l2_ctrl_config vivid_ctrl_class = {
1495 .ops = &vivid_user_gen_ctrl_ops,
1496 .flags = V4L2_CTRL_FLAG_READ_ONLY | V4L2_CTRL_FLAG_WRITE_ONLY,
1497 .id = VIVID_CID_VIVID_CLASS,
1498 .name = "Vivid Controls",
1499 .type = V4L2_CTRL_TYPE_CTRL_CLASS,
1500};
1501
1502int vivid_create_controls(struct vivid_dev *dev, bool show_ccs_cap,
1503 bool show_ccs_out, bool no_error_inj,
1504 bool has_sdtv, bool has_hdmi)
1505{
1506 struct v4l2_ctrl_handler *hdl_user_gen = &dev->ctrl_hdl_user_gen;
1507 struct v4l2_ctrl_handler *hdl_user_vid = &dev->ctrl_hdl_user_vid;
1508 struct v4l2_ctrl_handler *hdl_user_aud = &dev->ctrl_hdl_user_aud;
1509 struct v4l2_ctrl_handler *hdl_streaming = &dev->ctrl_hdl_streaming;
1510 struct v4l2_ctrl_handler *hdl_sdtv_cap = &dev->ctrl_hdl_sdtv_cap;
1511 struct v4l2_ctrl_handler *hdl_loop_cap = &dev->ctrl_hdl_loop_cap;
1512 struct v4l2_ctrl_handler *hdl_fb = &dev->ctrl_hdl_fb;
1513 struct v4l2_ctrl_handler *hdl_vid_cap = &dev->ctrl_hdl_vid_cap;
1514 struct v4l2_ctrl_handler *hdl_vid_out = &dev->ctrl_hdl_vid_out;
1515 struct v4l2_ctrl_handler *hdl_vbi_cap = &dev->ctrl_hdl_vbi_cap;
1516 struct v4l2_ctrl_handler *hdl_vbi_out = &dev->ctrl_hdl_vbi_out;
1517 struct v4l2_ctrl_handler *hdl_radio_rx = &dev->ctrl_hdl_radio_rx;
1518 struct v4l2_ctrl_handler *hdl_radio_tx = &dev->ctrl_hdl_radio_tx;
1519 struct v4l2_ctrl_handler *hdl_sdr_cap = &dev->ctrl_hdl_sdr_cap;
1520 struct v4l2_ctrl_handler *hdl_meta_cap = &dev->ctrl_hdl_meta_cap;
1521 struct v4l2_ctrl_handler *hdl_meta_out = &dev->ctrl_hdl_meta_out;
1522 struct v4l2_ctrl_handler *hdl_tch_cap = &dev->ctrl_hdl_touch_cap;
1523
1524 struct v4l2_ctrl_config vivid_ctrl_dv_timings = {
1525 .ops = &vivid_vid_cap_ctrl_ops,
1526 .id = VIVID_CID_DV_TIMINGS,
1527 .name = "DV Timings",
1528 .type = V4L2_CTRL_TYPE_MENU,
1529 };
1530 int i;
1531
1532 v4l2_ctrl_handler_init(hdl_user_gen, 10);
1533 v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_class, NULL);
1534 v4l2_ctrl_handler_init(hdl_user_vid, 9);
1535 v4l2_ctrl_new_custom(hdl_user_vid, &vivid_ctrl_class, NULL);
1536 v4l2_ctrl_handler_init(hdl_user_aud, 2);
1537 v4l2_ctrl_new_custom(hdl_user_aud, &vivid_ctrl_class, NULL);
1538 v4l2_ctrl_handler_init(hdl_streaming, 8);
1539 v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_class, NULL);
1540 v4l2_ctrl_handler_init(hdl_sdtv_cap, 2);
1541 v4l2_ctrl_new_custom(hdl_sdtv_cap, &vivid_ctrl_class, NULL);
1542 v4l2_ctrl_handler_init(hdl_loop_cap, 1);
1543 v4l2_ctrl_new_custom(hdl_loop_cap, &vivid_ctrl_class, NULL);
1544 v4l2_ctrl_handler_init(hdl_fb, 1);
1545 v4l2_ctrl_new_custom(hdl_fb, &vivid_ctrl_class, NULL);
1546 v4l2_ctrl_handler_init(hdl_vid_cap, 55);
1547 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_class, NULL);
1548 v4l2_ctrl_handler_init(hdl_vid_out, 26);
1549 if (!no_error_inj || dev->has_fb || dev->num_hdmi_outputs)
1550 v4l2_ctrl_new_custom(hdl_vid_out, &vivid_ctrl_class, NULL);
1551 v4l2_ctrl_handler_init(hdl_vbi_cap, 21);
1552 v4l2_ctrl_new_custom(hdl_vbi_cap, &vivid_ctrl_class, NULL);
1553 v4l2_ctrl_handler_init(hdl_vbi_out, 19);
1554 if (!no_error_inj)
1555 v4l2_ctrl_new_custom(hdl_vbi_out, &vivid_ctrl_class, NULL);
1556 v4l2_ctrl_handler_init(hdl_radio_rx, 17);
1557 v4l2_ctrl_new_custom(hdl_radio_rx, &vivid_ctrl_class, NULL);
1558 v4l2_ctrl_handler_init(hdl_radio_tx, 17);
1559 v4l2_ctrl_new_custom(hdl_radio_tx, &vivid_ctrl_class, NULL);
1560 v4l2_ctrl_handler_init(hdl_sdr_cap, 19);
1561 v4l2_ctrl_new_custom(hdl_sdr_cap, &vivid_ctrl_class, NULL);
1562 v4l2_ctrl_handler_init(hdl_meta_cap, 2);
1563 v4l2_ctrl_new_custom(hdl_meta_cap, &vivid_ctrl_class, NULL);
1564 v4l2_ctrl_handler_init(hdl_meta_out, 2);
1565 v4l2_ctrl_new_custom(hdl_meta_out, &vivid_ctrl_class, NULL);
1566 v4l2_ctrl_handler_init(hdl_tch_cap, 2);
1567 v4l2_ctrl_new_custom(hdl_tch_cap, &vivid_ctrl_class, NULL);
1568
1569
1570 dev->volume = v4l2_ctrl_new_std(hdl_user_aud, NULL,
1571 V4L2_CID_AUDIO_VOLUME, 0, 255, 1, 200);
1572 dev->mute = v4l2_ctrl_new_std(hdl_user_aud, NULL,
1573 V4L2_CID_AUDIO_MUTE, 0, 1, 1, 0);
1574 if (dev->has_vid_cap) {
1575 dev->brightness = v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops,
1576 V4L2_CID_BRIGHTNESS, 0, 255, 1, 128);
1577 for (i = 0; i < MAX_INPUTS; i++)
1578 dev->input_brightness[i] = 128;
1579 dev->contrast = v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops,
1580 V4L2_CID_CONTRAST, 0, 255, 1, 128);
1581 dev->saturation = v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops,
1582 V4L2_CID_SATURATION, 0, 255, 1, 128);
1583 dev->hue = v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops,
1584 V4L2_CID_HUE, -128, 128, 1, 0);
1585 v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops,
1586 V4L2_CID_HFLIP, 0, 1, 1, 0);
1587 v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops,
1588 V4L2_CID_VFLIP, 0, 1, 1, 0);
1589 dev->autogain = v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops,
1590 V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
1591 dev->gain = v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops,
1592 V4L2_CID_GAIN, 0, 255, 1, 100);
1593 dev->alpha = v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops,
1594 V4L2_CID_ALPHA_COMPONENT, 0, 255, 1, 0);
1595 }
1596 dev->button = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_button, NULL);
1597 dev->int32 = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_int32, NULL);
1598 dev->int64 = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_int64, NULL);
1599 dev->boolean = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_boolean, NULL);
1600 dev->menu = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_menu, NULL);
1601 dev->string = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_string, NULL);
1602 dev->bitmask = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_bitmask, NULL);
1603 dev->int_menu = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_int_menu, NULL);
1604 v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_area, NULL);
1605 v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_u32_array, NULL);
1606 v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_u16_matrix, NULL);
1607 v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_u8_4d_array, NULL);
1608
1609 if (dev->has_vid_cap) {
1610
1611 struct v4l2_ctrl_config vivid_ctrl_test_pattern = {
1612 .ops = &vivid_vid_cap_ctrl_ops,
1613 .id = VIVID_CID_TEST_PATTERN,
1614 .name = "Test Pattern",
1615 .type = V4L2_CTRL_TYPE_MENU,
1616 .max = TPG_PAT_NOISE,
1617 .qmenu = tpg_pattern_strings,
1618 };
1619
1620 dev->test_pattern = v4l2_ctrl_new_custom(hdl_vid_cap,
1621 &vivid_ctrl_test_pattern, NULL);
1622 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_perc_fill, NULL);
1623 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_hor_movement, NULL);
1624 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_vert_movement, NULL);
1625 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_osd_mode, NULL);
1626 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_show_border, NULL);
1627 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_show_square, NULL);
1628 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_hflip, NULL);
1629 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_vflip, NULL);
1630 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_insert_sav, NULL);
1631 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_insert_eav, NULL);
1632 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_reduced_fps, NULL);
1633 if (show_ccs_cap) {
1634 dev->ctrl_has_crop_cap = v4l2_ctrl_new_custom(hdl_vid_cap,
1635 &vivid_ctrl_has_crop_cap, NULL);
1636 dev->ctrl_has_compose_cap = v4l2_ctrl_new_custom(hdl_vid_cap,
1637 &vivid_ctrl_has_compose_cap, NULL);
1638 dev->ctrl_has_scaler_cap = v4l2_ctrl_new_custom(hdl_vid_cap,
1639 &vivid_ctrl_has_scaler_cap, NULL);
1640 }
1641
1642 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_tstamp_src, NULL);
1643 dev->colorspace = v4l2_ctrl_new_custom(hdl_vid_cap,
1644 &vivid_ctrl_colorspace, NULL);
1645 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_xfer_func, NULL);
1646 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_ycbcr_enc, NULL);
1647 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_hsv_enc, NULL);
1648 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_quantization, NULL);
1649 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_alpha_mode, NULL);
1650 }
1651
1652 if (dev->has_vid_out && show_ccs_out) {
1653 dev->ctrl_has_crop_out = v4l2_ctrl_new_custom(hdl_vid_out,
1654 &vivid_ctrl_has_crop_out, NULL);
1655 dev->ctrl_has_compose_out = v4l2_ctrl_new_custom(hdl_vid_out,
1656 &vivid_ctrl_has_compose_out, NULL);
1657 dev->ctrl_has_scaler_out = v4l2_ctrl_new_custom(hdl_vid_out,
1658 &vivid_ctrl_has_scaler_out, NULL);
1659 }
1660
1661
1662
1663
1664
1665
1666
1667 if (!no_error_inj) {
1668 v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_disconnect, NULL);
1669 v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_dqbuf_error, NULL);
1670 v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_perc_dropped, NULL);
1671 v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_queue_setup_error, NULL);
1672 v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_buf_prepare_error, NULL);
1673 v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_start_streaming_error, NULL);
1674 v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_queue_error, NULL);
1675#ifdef CONFIG_MEDIA_CONTROLLER
1676 v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_req_validate_error, NULL);
1677#endif
1678 v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_seq_wrap, NULL);
1679 v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_time_wrap, NULL);
1680 }
1681
1682 if (has_sdtv && (dev->has_vid_cap || dev->has_vbi_cap)) {
1683 if (dev->has_vid_cap)
1684 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_std_aspect_ratio, NULL);
1685 dev->ctrl_std_signal_mode = v4l2_ctrl_new_custom(hdl_sdtv_cap,
1686 &vivid_ctrl_std_signal_mode, NULL);
1687 dev->ctrl_standard = v4l2_ctrl_new_custom(hdl_sdtv_cap,
1688 &vivid_ctrl_standard, NULL);
1689 if (dev->ctrl_std_signal_mode)
1690 v4l2_ctrl_cluster(2, &dev->ctrl_std_signal_mode);
1691 if (dev->has_raw_vbi_cap)
1692 v4l2_ctrl_new_custom(hdl_vbi_cap, &vivid_ctrl_vbi_cap_interlaced, NULL);
1693 }
1694
1695 if (dev->num_hdmi_inputs) {
1696 s64 hdmi_input_mask = GENMASK(dev->num_hdmi_inputs - 1, 0);
1697
1698 dev->ctrl_dv_timings_signal_mode = v4l2_ctrl_new_custom(hdl_vid_cap,
1699 &vivid_ctrl_dv_timings_signal_mode, NULL);
1700
1701 vivid_ctrl_dv_timings.max = dev->query_dv_timings_size - 1;
1702 vivid_ctrl_dv_timings.qmenu =
1703 (const char * const *)dev->query_dv_timings_qmenu;
1704 dev->ctrl_dv_timings = v4l2_ctrl_new_custom(hdl_vid_cap,
1705 &vivid_ctrl_dv_timings, NULL);
1706 if (dev->ctrl_dv_timings_signal_mode)
1707 v4l2_ctrl_cluster(2, &dev->ctrl_dv_timings_signal_mode);
1708
1709 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_dv_timings_aspect_ratio, NULL);
1710 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_max_edid_blocks, NULL);
1711 dev->real_rgb_range_cap = v4l2_ctrl_new_custom(hdl_vid_cap,
1712 &vivid_ctrl_limited_rgb_range, NULL);
1713 dev->rgb_range_cap = v4l2_ctrl_new_std_menu(hdl_vid_cap,
1714 &vivid_vid_cap_ctrl_ops,
1715 V4L2_CID_DV_RX_RGB_RANGE, V4L2_DV_RGB_RANGE_FULL,
1716 0, V4L2_DV_RGB_RANGE_AUTO);
1717 dev->ctrl_rx_power_present = v4l2_ctrl_new_std(hdl_vid_cap,
1718 NULL, V4L2_CID_DV_RX_POWER_PRESENT, 0, hdmi_input_mask,
1719 0, hdmi_input_mask);
1720
1721 }
1722 if (dev->num_hdmi_outputs) {
1723 s64 hdmi_output_mask = GENMASK(dev->num_hdmi_outputs - 1, 0);
1724
1725
1726
1727
1728
1729 dev->ctrl_tx_rgb_range = v4l2_ctrl_new_std_menu(hdl_vid_out, NULL,
1730 V4L2_CID_DV_TX_RGB_RANGE, V4L2_DV_RGB_RANGE_FULL,
1731 0, V4L2_DV_RGB_RANGE_AUTO);
1732 dev->ctrl_tx_mode = v4l2_ctrl_new_std_menu(hdl_vid_out, NULL,
1733 V4L2_CID_DV_TX_MODE, V4L2_DV_TX_MODE_HDMI,
1734 0, V4L2_DV_TX_MODE_HDMI);
1735 dev->ctrl_display_present = v4l2_ctrl_new_custom(hdl_vid_out,
1736 &vivid_ctrl_display_present, NULL);
1737 dev->ctrl_tx_hotplug = v4l2_ctrl_new_std(hdl_vid_out,
1738 NULL, V4L2_CID_DV_TX_HOTPLUG, 0, hdmi_output_mask,
1739 0, hdmi_output_mask);
1740 dev->ctrl_tx_rxsense = v4l2_ctrl_new_std(hdl_vid_out,
1741 NULL, V4L2_CID_DV_TX_RXSENSE, 0, hdmi_output_mask,
1742 0, hdmi_output_mask);
1743 dev->ctrl_tx_edid_present = v4l2_ctrl_new_std(hdl_vid_out,
1744 NULL, V4L2_CID_DV_TX_EDID_PRESENT, 0, hdmi_output_mask,
1745 0, hdmi_output_mask);
1746 }
1747 if ((dev->has_vid_cap && dev->has_vid_out) ||
1748 (dev->has_vbi_cap && dev->has_vbi_out))
1749 v4l2_ctrl_new_custom(hdl_loop_cap, &vivid_ctrl_loop_video, NULL);
1750
1751 if (dev->has_fb)
1752 v4l2_ctrl_new_custom(hdl_fb, &vivid_ctrl_clear_fb, NULL);
1753
1754 if (dev->has_radio_rx) {
1755 v4l2_ctrl_new_custom(hdl_radio_rx, &vivid_ctrl_radio_hw_seek_mode, NULL);
1756 v4l2_ctrl_new_custom(hdl_radio_rx, &vivid_ctrl_radio_hw_seek_prog_lim, NULL);
1757 v4l2_ctrl_new_custom(hdl_radio_rx, &vivid_ctrl_radio_rx_rds_blockio, NULL);
1758 v4l2_ctrl_new_custom(hdl_radio_rx, &vivid_ctrl_radio_rx_rds_rbds, NULL);
1759 v4l2_ctrl_new_std(hdl_radio_rx, &vivid_radio_rx_ctrl_ops,
1760 V4L2_CID_RDS_RECEPTION, 0, 1, 1, 1);
1761 dev->radio_rx_rds_pty = v4l2_ctrl_new_std(hdl_radio_rx,
1762 &vivid_radio_rx_ctrl_ops,
1763 V4L2_CID_RDS_RX_PTY, 0, 31, 1, 0);
1764 dev->radio_rx_rds_psname = v4l2_ctrl_new_std(hdl_radio_rx,
1765 &vivid_radio_rx_ctrl_ops,
1766 V4L2_CID_RDS_RX_PS_NAME, 0, 8, 8, 0);
1767 dev->radio_rx_rds_radiotext = v4l2_ctrl_new_std(hdl_radio_rx,
1768 &vivid_radio_rx_ctrl_ops,
1769 V4L2_CID_RDS_RX_RADIO_TEXT, 0, 64, 64, 0);
1770 dev->radio_rx_rds_ta = v4l2_ctrl_new_std(hdl_radio_rx,
1771 &vivid_radio_rx_ctrl_ops,
1772 V4L2_CID_RDS_RX_TRAFFIC_ANNOUNCEMENT, 0, 1, 1, 0);
1773 dev->radio_rx_rds_tp = v4l2_ctrl_new_std(hdl_radio_rx,
1774 &vivid_radio_rx_ctrl_ops,
1775 V4L2_CID_RDS_RX_TRAFFIC_PROGRAM, 0, 1, 1, 0);
1776 dev->radio_rx_rds_ms = v4l2_ctrl_new_std(hdl_radio_rx,
1777 &vivid_radio_rx_ctrl_ops,
1778 V4L2_CID_RDS_RX_MUSIC_SPEECH, 0, 1, 1, 1);
1779 }
1780 if (dev->has_radio_tx) {
1781 v4l2_ctrl_new_custom(hdl_radio_tx,
1782 &vivid_ctrl_radio_tx_rds_blockio, NULL);
1783 dev->radio_tx_rds_pi = v4l2_ctrl_new_std(hdl_radio_tx,
1784 &vivid_radio_tx_ctrl_ops,
1785 V4L2_CID_RDS_TX_PI, 0, 0xffff, 1, 0x8088);
1786 dev->radio_tx_rds_pty = v4l2_ctrl_new_std(hdl_radio_tx,
1787 &vivid_radio_tx_ctrl_ops,
1788 V4L2_CID_RDS_TX_PTY, 0, 31, 1, 3);
1789 dev->radio_tx_rds_psname = v4l2_ctrl_new_std(hdl_radio_tx,
1790 &vivid_radio_tx_ctrl_ops,
1791 V4L2_CID_RDS_TX_PS_NAME, 0, 8, 8, 0);
1792 if (dev->radio_tx_rds_psname)
1793 v4l2_ctrl_s_ctrl_string(dev->radio_tx_rds_psname, "VIVID-TX");
1794 dev->radio_tx_rds_radiotext = v4l2_ctrl_new_std(hdl_radio_tx,
1795 &vivid_radio_tx_ctrl_ops,
1796 V4L2_CID_RDS_TX_RADIO_TEXT, 0, 64 * 2, 64, 0);
1797 if (dev->radio_tx_rds_radiotext)
1798 v4l2_ctrl_s_ctrl_string(dev->radio_tx_rds_radiotext,
1799 "This is a VIVID default Radio Text template text, change at will");
1800 dev->radio_tx_rds_mono_stereo = v4l2_ctrl_new_std(hdl_radio_tx,
1801 &vivid_radio_tx_ctrl_ops,
1802 V4L2_CID_RDS_TX_MONO_STEREO, 0, 1, 1, 1);
1803 dev->radio_tx_rds_art_head = v4l2_ctrl_new_std(hdl_radio_tx,
1804 &vivid_radio_tx_ctrl_ops,
1805 V4L2_CID_RDS_TX_ARTIFICIAL_HEAD, 0, 1, 1, 0);
1806 dev->radio_tx_rds_compressed = v4l2_ctrl_new_std(hdl_radio_tx,
1807 &vivid_radio_tx_ctrl_ops,
1808 V4L2_CID_RDS_TX_COMPRESSED, 0, 1, 1, 0);
1809 dev->radio_tx_rds_dyn_pty = v4l2_ctrl_new_std(hdl_radio_tx,
1810 &vivid_radio_tx_ctrl_ops,
1811 V4L2_CID_RDS_TX_DYNAMIC_PTY, 0, 1, 1, 0);
1812 dev->radio_tx_rds_ta = v4l2_ctrl_new_std(hdl_radio_tx,
1813 &vivid_radio_tx_ctrl_ops,
1814 V4L2_CID_RDS_TX_TRAFFIC_ANNOUNCEMENT, 0, 1, 1, 0);
1815 dev->radio_tx_rds_tp = v4l2_ctrl_new_std(hdl_radio_tx,
1816 &vivid_radio_tx_ctrl_ops,
1817 V4L2_CID_RDS_TX_TRAFFIC_PROGRAM, 0, 1, 1, 1);
1818 dev->radio_tx_rds_ms = v4l2_ctrl_new_std(hdl_radio_tx,
1819 &vivid_radio_tx_ctrl_ops,
1820 V4L2_CID_RDS_TX_MUSIC_SPEECH, 0, 1, 1, 1);
1821 }
1822 if (dev->has_sdr_cap) {
1823 v4l2_ctrl_new_custom(hdl_sdr_cap,
1824 &vivid_ctrl_sdr_cap_fm_deviation, NULL);
1825 }
1826 if (dev->has_meta_cap) {
1827 v4l2_ctrl_new_custom(hdl_meta_cap,
1828 &vivid_ctrl_meta_has_pts, NULL);
1829 v4l2_ctrl_new_custom(hdl_meta_cap,
1830 &vivid_ctrl_meta_has_src_clk, NULL);
1831 }
1832
1833 if (hdl_user_gen->error)
1834 return hdl_user_gen->error;
1835 if (hdl_user_vid->error)
1836 return hdl_user_vid->error;
1837 if (hdl_user_aud->error)
1838 return hdl_user_aud->error;
1839 if (hdl_streaming->error)
1840 return hdl_streaming->error;
1841 if (hdl_sdr_cap->error)
1842 return hdl_sdr_cap->error;
1843 if (hdl_loop_cap->error)
1844 return hdl_loop_cap->error;
1845
1846 if (dev->autogain)
1847 v4l2_ctrl_auto_cluster(2, &dev->autogain, 0, true);
1848
1849 if (dev->has_vid_cap) {
1850 v4l2_ctrl_add_handler(hdl_vid_cap, hdl_user_gen, NULL, false);
1851 v4l2_ctrl_add_handler(hdl_vid_cap, hdl_user_vid, NULL, false);
1852 v4l2_ctrl_add_handler(hdl_vid_cap, hdl_user_aud, NULL, false);
1853 v4l2_ctrl_add_handler(hdl_vid_cap, hdl_streaming, NULL, false);
1854 v4l2_ctrl_add_handler(hdl_vid_cap, hdl_sdtv_cap, NULL, false);
1855 v4l2_ctrl_add_handler(hdl_vid_cap, hdl_loop_cap, NULL, false);
1856 v4l2_ctrl_add_handler(hdl_vid_cap, hdl_fb, NULL, false);
1857 if (hdl_vid_cap->error)
1858 return hdl_vid_cap->error;
1859 dev->vid_cap_dev.ctrl_handler = hdl_vid_cap;
1860 }
1861 if (dev->has_vid_out) {
1862 v4l2_ctrl_add_handler(hdl_vid_out, hdl_user_gen, NULL, false);
1863 v4l2_ctrl_add_handler(hdl_vid_out, hdl_user_aud, NULL, false);
1864 v4l2_ctrl_add_handler(hdl_vid_out, hdl_streaming, NULL, false);
1865 v4l2_ctrl_add_handler(hdl_vid_out, hdl_fb, NULL, false);
1866 if (hdl_vid_out->error)
1867 return hdl_vid_out->error;
1868 dev->vid_out_dev.ctrl_handler = hdl_vid_out;
1869 }
1870 if (dev->has_vbi_cap) {
1871 v4l2_ctrl_add_handler(hdl_vbi_cap, hdl_user_gen, NULL, false);
1872 v4l2_ctrl_add_handler(hdl_vbi_cap, hdl_streaming, NULL, false);
1873 v4l2_ctrl_add_handler(hdl_vbi_cap, hdl_sdtv_cap, NULL, false);
1874 v4l2_ctrl_add_handler(hdl_vbi_cap, hdl_loop_cap, NULL, false);
1875 if (hdl_vbi_cap->error)
1876 return hdl_vbi_cap->error;
1877 dev->vbi_cap_dev.ctrl_handler = hdl_vbi_cap;
1878 }
1879 if (dev->has_vbi_out) {
1880 v4l2_ctrl_add_handler(hdl_vbi_out, hdl_user_gen, NULL, false);
1881 v4l2_ctrl_add_handler(hdl_vbi_out, hdl_streaming, NULL, false);
1882 if (hdl_vbi_out->error)
1883 return hdl_vbi_out->error;
1884 dev->vbi_out_dev.ctrl_handler = hdl_vbi_out;
1885 }
1886 if (dev->has_radio_rx) {
1887 v4l2_ctrl_add_handler(hdl_radio_rx, hdl_user_gen, NULL, false);
1888 v4l2_ctrl_add_handler(hdl_radio_rx, hdl_user_aud, NULL, false);
1889 if (hdl_radio_rx->error)
1890 return hdl_radio_rx->error;
1891 dev->radio_rx_dev.ctrl_handler = hdl_radio_rx;
1892 }
1893 if (dev->has_radio_tx) {
1894 v4l2_ctrl_add_handler(hdl_radio_tx, hdl_user_gen, NULL, false);
1895 v4l2_ctrl_add_handler(hdl_radio_tx, hdl_user_aud, NULL, false);
1896 if (hdl_radio_tx->error)
1897 return hdl_radio_tx->error;
1898 dev->radio_tx_dev.ctrl_handler = hdl_radio_tx;
1899 }
1900 if (dev->has_sdr_cap) {
1901 v4l2_ctrl_add_handler(hdl_sdr_cap, hdl_user_gen, NULL, false);
1902 v4l2_ctrl_add_handler(hdl_sdr_cap, hdl_streaming, NULL, false);
1903 if (hdl_sdr_cap->error)
1904 return hdl_sdr_cap->error;
1905 dev->sdr_cap_dev.ctrl_handler = hdl_sdr_cap;
1906 }
1907 if (dev->has_meta_cap) {
1908 v4l2_ctrl_add_handler(hdl_meta_cap, hdl_user_gen, NULL, false);
1909 v4l2_ctrl_add_handler(hdl_meta_cap, hdl_streaming, NULL, false);
1910 if (hdl_meta_cap->error)
1911 return hdl_meta_cap->error;
1912 dev->meta_cap_dev.ctrl_handler = hdl_meta_cap;
1913 }
1914 if (dev->has_meta_out) {
1915 v4l2_ctrl_add_handler(hdl_meta_out, hdl_user_gen, NULL, false);
1916 v4l2_ctrl_add_handler(hdl_meta_out, hdl_streaming, NULL, false);
1917 if (hdl_meta_out->error)
1918 return hdl_meta_out->error;
1919 dev->meta_out_dev.ctrl_handler = hdl_meta_out;
1920 }
1921 if (dev->has_touch_cap) {
1922 v4l2_ctrl_add_handler(hdl_tch_cap, hdl_user_gen, NULL, false);
1923 v4l2_ctrl_add_handler(hdl_tch_cap, hdl_streaming, NULL, false);
1924 if (hdl_tch_cap->error)
1925 return hdl_tch_cap->error;
1926 dev->touch_cap_dev.ctrl_handler = hdl_tch_cap;
1927 }
1928 return 0;
1929}
1930
1931void vivid_free_controls(struct vivid_dev *dev)
1932{
1933 v4l2_ctrl_handler_free(&dev->ctrl_hdl_vid_cap);
1934 v4l2_ctrl_handler_free(&dev->ctrl_hdl_vid_out);
1935 v4l2_ctrl_handler_free(&dev->ctrl_hdl_vbi_cap);
1936 v4l2_ctrl_handler_free(&dev->ctrl_hdl_vbi_out);
1937 v4l2_ctrl_handler_free(&dev->ctrl_hdl_radio_rx);
1938 v4l2_ctrl_handler_free(&dev->ctrl_hdl_radio_tx);
1939 v4l2_ctrl_handler_free(&dev->ctrl_hdl_sdr_cap);
1940 v4l2_ctrl_handler_free(&dev->ctrl_hdl_user_gen);
1941 v4l2_ctrl_handler_free(&dev->ctrl_hdl_user_vid);
1942 v4l2_ctrl_handler_free(&dev->ctrl_hdl_user_aud);
1943 v4l2_ctrl_handler_free(&dev->ctrl_hdl_streaming);
1944 v4l2_ctrl_handler_free(&dev->ctrl_hdl_sdtv_cap);
1945 v4l2_ctrl_handler_free(&dev->ctrl_hdl_loop_cap);
1946 v4l2_ctrl_handler_free(&dev->ctrl_hdl_fb);
1947 v4l2_ctrl_handler_free(&dev->ctrl_hdl_meta_cap);
1948 v4l2_ctrl_handler_free(&dev->ctrl_hdl_meta_out);
1949 v4l2_ctrl_handler_free(&dev->ctrl_hdl_touch_cap);
1950}
1951