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