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