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