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