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