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