Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
[deliverable/linux.git] / drivers / media / platform / vivid / vivid-ctrls.c
CommitLineData
73c3f482
HV
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)
24c4942d
HV
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)
73c3f482
HV
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)
ca5316db
HV
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)
c79aa6ae 81#define VIVID_CID_REDUCED_FPS (VIVID_CID_VIVID_BASE + 42)
73c3f482
HV
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
f335c3f2 103#define VIVID_CID_SDR_CAP_FM_DEVIATION (VIVID_CID_VIVID_BASE + 110)
73c3f482
HV
104
105/* General User Controls */
106
107static 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
132static const struct v4l2_ctrl_ops vivid_user_gen_ctrl_ops = {
133 .s_ctrl = vivid_user_gen_s_ctrl,
134};
135
136static 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
143static 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
154static 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
164static 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
24c4942d
HV
174static 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
186static 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
198static 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
73c3f482
HV
210static 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
220static 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
232static 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
242static 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
253static const s64 vivid_ctrl_int_menu_values[] = {
254 1, 1, 2, 3, 5, 8, 13, 21, 42,
255};
256
257static 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
269static 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
276static 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
286static 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
298static 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
331static 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
339static int vivid_vid_cap_s_ctrl(struct v4l2_ctrl *ctrl)
340{
cd8adbe7
HV
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,
1d780535 347 V4L2_COLORSPACE_DCI_P3,
cd8adbe7
HV
348 V4L2_COLORSPACE_SMPTE240M,
349 V4L2_COLORSPACE_470_SYSTEM_M,
350 V4L2_COLORSPACE_470_SYSTEM_BG,
351 };
73c3f482
HV
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:
cd8adbe7 361 tpg_s_colorspace(&dev->tpg, colorspaces[ctrl->val]);
73c3f482
HV
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;
ca5316db
HV
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;
3e8a78d1
HV
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;
73c3f482
HV
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;
c79aa6ae
PL
428 case VIVID_CID_REDUCED_FPS:
429 dev->reduced_fps = ctrl->val;
430 vivid_update_format_cap(dev, true);
431 break;
73c3f482
HV
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
482static const struct v4l2_ctrl_ops vivid_vid_cap_ctrl_ops = {
483 .s_ctrl = vivid_vid_cap_s_ctrl,
484};
485
486static 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
497static 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
507static 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
518static 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
528static 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
537static 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
546static const char * const vivid_ctrl_osd_mode_strings[] = {
547 "All",
548 "Counters Only",
549 "None",
550 NULL,
551};
552
553static 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,
ff144726 558 .max = ARRAY_SIZE(vivid_ctrl_osd_mode_strings) - 2,
73c3f482
HV
559 .qmenu = vivid_ctrl_osd_mode_strings,
560};
561
562static 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
573static 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
582static 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
591static 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
600static 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
c79aa6ae
PL
609static 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
73c3f482
HV
618static 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
628static 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
638static 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
648static const char * const vivid_ctrl_tstamp_src_strings[] = {
649 "End of Frame",
650 "Start of Exposure",
651 NULL,
652};
653
654static 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,
ff144726 659 .max = ARRAY_SIZE(vivid_ctrl_tstamp_src_strings) - 2,
73c3f482
HV
660 .qmenu = vivid_ctrl_tstamp_src_strings,
661};
662
663static 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
674static 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
685static 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
694static 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
703static 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
714static const char * const vivid_ctrl_colorspace_strings[] = {
73c3f482 715 "SMPTE 170M",
eb79dbf6 716 "Rec. 709",
cd8adbe7
HV
717 "sRGB",
718 "AdobeRGB",
719 "BT.2020",
1d780535 720 "DCI-P3",
cd8adbe7 721 "SMPTE 240M",
73c3f482
HV
722 "470 System M",
723 "470 System BG",
73c3f482
HV
724 NULL,
725};
726
727static 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,
ff144726 732 .max = ARRAY_SIZE(vivid_ctrl_colorspace_strings) - 2,
cd8adbe7 733 .def = 2,
73c3f482
HV
734 .qmenu = vivid_ctrl_colorspace_strings,
735};
736
ca5316db
HV
737static const char * const vivid_ctrl_xfer_func_strings[] = {
738 "Default",
739 "Rec. 709",
740 "sRGB",
741 "AdobeRGB",
742 "SMPTE 240M",
743 "None",
1d780535 744 "DCI-P3",
c732e647 745 "SMPTE 2084",
ca5316db
HV
746 NULL,
747};
748
749static 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,
ff144726 754 .max = ARRAY_SIZE(vivid_ctrl_xfer_func_strings) - 2,
ca5316db
HV
755 .qmenu = vivid_ctrl_xfer_func_strings,
756};
757
3e8a78d1
HV
758static const char * const vivid_ctrl_ycbcr_enc_strings[] = {
759 "Default",
760 "ITU-R 601",
761 "Rec. 709",
762 "xvYCC 601",
763 "xvYCC 709",
764 "sYCC",
eb79dbf6 765 "BT.2020",
3e8a78d1
HV
766 "BT.2020 Constant Luminance",
767 "SMPTE 240M",
768 NULL,
769};
770
771static 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,
ff144726 776 .max = ARRAY_SIZE(vivid_ctrl_ycbcr_enc_strings) - 2,
3e8a78d1
HV
777 .qmenu = vivid_ctrl_ycbcr_enc_strings,
778};
779
780static const char * const vivid_ctrl_quantization_strings[] = {
781 "Default",
782 "Full Range",
783 "Limited Range",
784 NULL,
785};
786
787static const struct v4l2_ctrl_config vivid_ctrl_quantization = {
788 .ops = &vivid_vid_cap_ctrl_ops,
789 .id = VIVID_CID_QUANTIZATION,
790 .name = "Quantization",
791 .type = V4L2_CTRL_TYPE_MENU,
ff144726 792 .max = ARRAY_SIZE(vivid_ctrl_quantization_strings) - 2,
3e8a78d1
HV
793 .qmenu = vivid_ctrl_quantization_strings,
794};
795
73c3f482
HV
796static const struct v4l2_ctrl_config vivid_ctrl_alpha_mode = {
797 .ops = &vivid_vid_cap_ctrl_ops,
798 .id = VIVID_CID_ALPHA_MODE,
799 .name = "Apply Alpha To Red Only",
800 .type = V4L2_CTRL_TYPE_BOOLEAN,
801 .max = 1,
802 .step = 1,
803};
804
805static const struct v4l2_ctrl_config vivid_ctrl_limited_rgb_range = {
806 .ops = &vivid_vid_cap_ctrl_ops,
807 .id = VIVID_CID_LIMITED_RGB_RANGE,
808 .name = "Limited RGB Range (16-235)",
809 .type = V4L2_CTRL_TYPE_BOOLEAN,
810 .max = 1,
811 .step = 1,
812};
813
814
63344b65
HV
815/* Video Loop Control */
816
817static int vivid_loop_cap_s_ctrl(struct v4l2_ctrl *ctrl)
818{
819 struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_loop_cap);
820
821 switch (ctrl->id) {
822 case VIVID_CID_LOOP_VIDEO:
823 dev->loop_video = ctrl->val;
824 vivid_update_quality(dev);
825 vivid_send_source_change(dev, SVID);
826 vivid_send_source_change(dev, HDMI);
827 break;
828 }
829 return 0;
830}
831
832static const struct v4l2_ctrl_ops vivid_loop_cap_ctrl_ops = {
833 .s_ctrl = vivid_loop_cap_s_ctrl,
834};
835
836static const struct v4l2_ctrl_config vivid_ctrl_loop_video = {
837 .ops = &vivid_loop_cap_ctrl_ops,
838 .id = VIVID_CID_LOOP_VIDEO,
839 .name = "Loop Video",
840 .type = V4L2_CTRL_TYPE_BOOLEAN,
841 .max = 1,
842 .step = 1,
843};
844
845
73c3f482
HV
846/* VBI Capture Control */
847
848static int vivid_vbi_cap_s_ctrl(struct v4l2_ctrl *ctrl)
849{
850 struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_vbi_cap);
851
852 switch (ctrl->id) {
853 case VIVID_CID_VBI_CAP_INTERLACED:
854 dev->vbi_cap_interlaced = ctrl->val;
855 break;
856 }
857 return 0;
858}
859
860static const struct v4l2_ctrl_ops vivid_vbi_cap_ctrl_ops = {
861 .s_ctrl = vivid_vbi_cap_s_ctrl,
862};
863
864static const struct v4l2_ctrl_config vivid_ctrl_vbi_cap_interlaced = {
865 .ops = &vivid_vbi_cap_ctrl_ops,
866 .id = VIVID_CID_VBI_CAP_INTERLACED,
867 .name = "Interlaced VBI Format",
868 .type = V4L2_CTRL_TYPE_BOOLEAN,
869 .max = 1,
870 .step = 1,
871};
872
873
874/* Video Output Controls */
875
876static int vivid_vid_out_s_ctrl(struct v4l2_ctrl *ctrl)
877{
878 struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_vid_out);
879 struct v4l2_bt_timings *bt = &dev->dv_timings_out.bt;
880
881 switch (ctrl->id) {
882 case VIVID_CID_HAS_CROP_OUT:
883 dev->has_crop_out = ctrl->val;
884 vivid_update_format_out(dev);
885 break;
886 case VIVID_CID_HAS_COMPOSE_OUT:
887 dev->has_compose_out = ctrl->val;
888 vivid_update_format_out(dev);
889 break;
890 case VIVID_CID_HAS_SCALER_OUT:
891 dev->has_scaler_out = ctrl->val;
892 vivid_update_format_out(dev);
893 break;
894 case V4L2_CID_DV_TX_MODE:
895 dev->dvi_d_out = ctrl->val == V4L2_DV_TX_MODE_DVI_D;
896 if (!vivid_is_hdmi_out(dev))
897 break;
4a203349 898 if (!dev->dvi_d_out && (bt->flags & V4L2_DV_FL_IS_CE_VIDEO)) {
73c3f482
HV
899 if (bt->width == 720 && bt->height <= 576)
900 dev->colorspace_out = V4L2_COLORSPACE_SMPTE170M;
901 else
902 dev->colorspace_out = V4L2_COLORSPACE_REC709;
3e8a78d1 903 dev->quantization_out = V4L2_QUANTIZATION_DEFAULT;
73c3f482
HV
904 } else {
905 dev->colorspace_out = V4L2_COLORSPACE_SRGB;
3e8a78d1
HV
906 dev->quantization_out = dev->dvi_d_out ?
907 V4L2_QUANTIZATION_LIM_RANGE :
908 V4L2_QUANTIZATION_DEFAULT;
73c3f482
HV
909 }
910 if (dev->loop_video)
911 vivid_send_source_change(dev, HDMI);
912 break;
913 }
914 return 0;
915}
916
917static const struct v4l2_ctrl_ops vivid_vid_out_ctrl_ops = {
918 .s_ctrl = vivid_vid_out_s_ctrl,
919};
920
921static const struct v4l2_ctrl_config vivid_ctrl_has_crop_out = {
922 .ops = &vivid_vid_out_ctrl_ops,
923 .id = VIVID_CID_HAS_CROP_OUT,
924 .name = "Enable Output Cropping",
925 .type = V4L2_CTRL_TYPE_BOOLEAN,
926 .max = 1,
927 .def = 1,
928 .step = 1,
929};
930
931static const struct v4l2_ctrl_config vivid_ctrl_has_compose_out = {
932 .ops = &vivid_vid_out_ctrl_ops,
933 .id = VIVID_CID_HAS_COMPOSE_OUT,
934 .name = "Enable Output Composing",
935 .type = V4L2_CTRL_TYPE_BOOLEAN,
936 .max = 1,
937 .def = 1,
938 .step = 1,
939};
940
941static const struct v4l2_ctrl_config vivid_ctrl_has_scaler_out = {
942 .ops = &vivid_vid_out_ctrl_ops,
943 .id = VIVID_CID_HAS_SCALER_OUT,
944 .name = "Enable Output Scaler",
945 .type = V4L2_CTRL_TYPE_BOOLEAN,
946 .max = 1,
947 .def = 1,
948 .step = 1,
949};
950
951
952/* Streaming Controls */
953
954static int vivid_streaming_s_ctrl(struct v4l2_ctrl *ctrl)
955{
956 struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_streaming);
d6dd645e 957 u64 rem;
73c3f482
HV
958
959 switch (ctrl->id) {
960 case VIVID_CID_DQBUF_ERROR:
961 dev->dqbuf_error = true;
962 break;
963 case VIVID_CID_PERC_DROPPED:
964 dev->perc_dropped_buffers = ctrl->val;
965 break;
966 case VIVID_CID_QUEUE_SETUP_ERROR:
967 dev->queue_setup_error = true;
968 break;
969 case VIVID_CID_BUF_PREPARE_ERROR:
970 dev->buf_prepare_error = true;
971 break;
972 case VIVID_CID_START_STR_ERROR:
973 dev->start_streaming_error = true;
974 break;
975 case VIVID_CID_QUEUE_ERROR:
eab34eab 976 if (vb2_start_streaming_called(&dev->vb_vid_cap_q))
73c3f482 977 vb2_queue_error(&dev->vb_vid_cap_q);
eab34eab 978 if (vb2_start_streaming_called(&dev->vb_vbi_cap_q))
73c3f482 979 vb2_queue_error(&dev->vb_vbi_cap_q);
eab34eab 980 if (vb2_start_streaming_called(&dev->vb_vid_out_q))
73c3f482 981 vb2_queue_error(&dev->vb_vid_out_q);
eab34eab 982 if (vb2_start_streaming_called(&dev->vb_vbi_out_q))
73c3f482 983 vb2_queue_error(&dev->vb_vbi_out_q);
eab34eab 984 if (vb2_start_streaming_called(&dev->vb_sdr_cap_q))
73c3f482
HV
985 vb2_queue_error(&dev->vb_sdr_cap_q);
986 break;
987 case VIVID_CID_SEQ_WRAP:
988 dev->seq_wrap = ctrl->val;
989 break;
990 case VIVID_CID_TIME_WRAP:
991 dev->time_wrap = ctrl->val;
992 if (ctrl->val == 0) {
993 dev->time_wrap_offset = 0;
994 break;
995 }
d6dd645e
JS
996 /*
997 * We want to set the time 16 seconds before the 32 bit tv_sec
998 * value of struct timeval would wrap around. So first we
999 * calculate ktime_get_ns() % ((1 << 32) * NSEC_PER_SEC), and
1000 * then we set the offset to ((1 << 32) - 16) * NSEC_PER_SEC).
1001 */
1002 div64_u64_rem(ktime_get_ns(),
1003 0x100000000ULL * NSEC_PER_SEC, &rem);
1004 dev->time_wrap_offset =
1005 (0x100000000ULL - 16) * NSEC_PER_SEC - rem;
73c3f482
HV
1006 break;
1007 }
1008 return 0;
1009}
1010
1011static const struct v4l2_ctrl_ops vivid_streaming_ctrl_ops = {
1012 .s_ctrl = vivid_streaming_s_ctrl,
1013};
1014
1015static const struct v4l2_ctrl_config vivid_ctrl_dqbuf_error = {
1016 .ops = &vivid_streaming_ctrl_ops,
1017 .id = VIVID_CID_DQBUF_ERROR,
1018 .name = "Inject V4L2_BUF_FLAG_ERROR",
1019 .type = V4L2_CTRL_TYPE_BUTTON,
1020};
1021
1022static const struct v4l2_ctrl_config vivid_ctrl_perc_dropped = {
1023 .ops = &vivid_streaming_ctrl_ops,
1024 .id = VIVID_CID_PERC_DROPPED,
1025 .name = "Percentage of Dropped Buffers",
1026 .type = V4L2_CTRL_TYPE_INTEGER,
1027 .min = 0,
1028 .max = 100,
1029 .step = 1,
1030};
1031
1032static const struct v4l2_ctrl_config vivid_ctrl_queue_setup_error = {
1033 .ops = &vivid_streaming_ctrl_ops,
1034 .id = VIVID_CID_QUEUE_SETUP_ERROR,
1035 .name = "Inject VIDIOC_REQBUFS Error",
1036 .type = V4L2_CTRL_TYPE_BUTTON,
1037};
1038
1039static const struct v4l2_ctrl_config vivid_ctrl_buf_prepare_error = {
1040 .ops = &vivid_streaming_ctrl_ops,
1041 .id = VIVID_CID_BUF_PREPARE_ERROR,
1042 .name = "Inject VIDIOC_QBUF Error",
1043 .type = V4L2_CTRL_TYPE_BUTTON,
1044};
1045
1046static const struct v4l2_ctrl_config vivid_ctrl_start_streaming_error = {
1047 .ops = &vivid_streaming_ctrl_ops,
1048 .id = VIVID_CID_START_STR_ERROR,
1049 .name = "Inject VIDIOC_STREAMON Error",
1050 .type = V4L2_CTRL_TYPE_BUTTON,
1051};
1052
1053static const struct v4l2_ctrl_config vivid_ctrl_queue_error = {
1054 .ops = &vivid_streaming_ctrl_ops,
1055 .id = VIVID_CID_QUEUE_ERROR,
1056 .name = "Inject Fatal Streaming Error",
1057 .type = V4L2_CTRL_TYPE_BUTTON,
1058};
1059
1060static const struct v4l2_ctrl_config vivid_ctrl_seq_wrap = {
1061 .ops = &vivid_streaming_ctrl_ops,
1062 .id = VIVID_CID_SEQ_WRAP,
1063 .name = "Wrap Sequence Number",
1064 .type = V4L2_CTRL_TYPE_BOOLEAN,
1065 .max = 1,
1066 .step = 1,
1067};
1068
1069static const struct v4l2_ctrl_config vivid_ctrl_time_wrap = {
1070 .ops = &vivid_streaming_ctrl_ops,
1071 .id = VIVID_CID_TIME_WRAP,
1072 .name = "Wrap Timestamp",
1073 .type = V4L2_CTRL_TYPE_BOOLEAN,
1074 .max = 1,
1075 .step = 1,
1076};
1077
1078
1079/* SDTV Capture Controls */
1080
1081static int vivid_sdtv_cap_s_ctrl(struct v4l2_ctrl *ctrl)
1082{
1083 struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_sdtv_cap);
1084
1085 switch (ctrl->id) {
1086 case VIVID_CID_STD_SIGNAL_MODE:
1087 dev->std_signal_mode = dev->ctrl_std_signal_mode->val;
1088 if (dev->std_signal_mode == SELECTED_STD)
1089 dev->query_std = vivid_standard[dev->ctrl_standard->val];
1090 v4l2_ctrl_activate(dev->ctrl_standard, dev->std_signal_mode == SELECTED_STD);
1091 vivid_update_quality(dev);
1092 vivid_send_source_change(dev, TV);
1093 vivid_send_source_change(dev, SVID);
1094 break;
1095 }
1096 return 0;
1097}
1098
1099static const struct v4l2_ctrl_ops vivid_sdtv_cap_ctrl_ops = {
1100 .s_ctrl = vivid_sdtv_cap_s_ctrl,
1101};
1102
1103static const char * const vivid_ctrl_std_signal_mode_strings[] = {
1104 "Current Standard",
1105 "No Signal",
1106 "No Lock",
1107 "",
1108 "Selected Standard",
1109 "Cycle Through All Standards",
1110 NULL,
1111};
1112
1113static const struct v4l2_ctrl_config vivid_ctrl_std_signal_mode = {
1114 .ops = &vivid_sdtv_cap_ctrl_ops,
1115 .id = VIVID_CID_STD_SIGNAL_MODE,
1116 .name = "Standard Signal Mode",
1117 .type = V4L2_CTRL_TYPE_MENU,
ff144726 1118 .max = ARRAY_SIZE(vivid_ctrl_std_signal_mode_strings) - 2,
73c3f482
HV
1119 .menu_skip_mask = 1 << 3,
1120 .qmenu = vivid_ctrl_std_signal_mode_strings,
1121};
1122
1123static const struct v4l2_ctrl_config vivid_ctrl_standard = {
1124 .ops = &vivid_sdtv_cap_ctrl_ops,
1125 .id = VIVID_CID_STANDARD,
1126 .name = "Standard",
1127 .type = V4L2_CTRL_TYPE_MENU,
1128 .max = 14,
1129 .qmenu = vivid_ctrl_standard_strings,
1130};
1131
1132
1133
1134/* Radio Receiver Controls */
1135
1136static int vivid_radio_rx_s_ctrl(struct v4l2_ctrl *ctrl)
1137{
1138 struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_radio_rx);
1139
1140 switch (ctrl->id) {
1141 case VIVID_CID_RADIO_SEEK_MODE:
1142 dev->radio_rx_hw_seek_mode = ctrl->val;
1143 break;
1144 case VIVID_CID_RADIO_SEEK_PROG_LIM:
1145 dev->radio_rx_hw_seek_prog_lim = ctrl->val;
1146 break;
1147 case VIVID_CID_RADIO_RX_RDS_RBDS:
1148 dev->rds_gen.use_rbds = ctrl->val;
1149 break;
1150 case VIVID_CID_RADIO_RX_RDS_BLOCKIO:
1151 dev->radio_rx_rds_controls = ctrl->val;
1152 dev->radio_rx_caps &= ~V4L2_CAP_READWRITE;
1153 dev->radio_rx_rds_use_alternates = false;
1154 if (!dev->radio_rx_rds_controls) {
1155 dev->radio_rx_caps |= V4L2_CAP_READWRITE;
1156 __v4l2_ctrl_s_ctrl(dev->radio_rx_rds_pty, 0);
1157 __v4l2_ctrl_s_ctrl(dev->radio_rx_rds_ta, 0);
1158 __v4l2_ctrl_s_ctrl(dev->radio_rx_rds_tp, 0);
1159 __v4l2_ctrl_s_ctrl(dev->radio_rx_rds_ms, 0);
1160 __v4l2_ctrl_s_ctrl_string(dev->radio_rx_rds_psname, "");
1161 __v4l2_ctrl_s_ctrl_string(dev->radio_rx_rds_radiotext, "");
1162 }
1163 v4l2_ctrl_activate(dev->radio_rx_rds_pty, dev->radio_rx_rds_controls);
1164 v4l2_ctrl_activate(dev->radio_rx_rds_psname, dev->radio_rx_rds_controls);
1165 v4l2_ctrl_activate(dev->radio_rx_rds_radiotext, dev->radio_rx_rds_controls);
1166 v4l2_ctrl_activate(dev->radio_rx_rds_ta, dev->radio_rx_rds_controls);
1167 v4l2_ctrl_activate(dev->radio_rx_rds_tp, dev->radio_rx_rds_controls);
1168 v4l2_ctrl_activate(dev->radio_rx_rds_ms, dev->radio_rx_rds_controls);
1169 break;
1170 case V4L2_CID_RDS_RECEPTION:
1171 dev->radio_rx_rds_enabled = ctrl->val;
1172 break;
1173 }
1174 return 0;
1175}
1176
1177static const struct v4l2_ctrl_ops vivid_radio_rx_ctrl_ops = {
1178 .s_ctrl = vivid_radio_rx_s_ctrl,
1179};
1180
1181static const char * const vivid_ctrl_radio_rds_mode_strings[] = {
1182 "Block I/O",
1183 "Controls",
1184 NULL,
1185};
1186
1187static const struct v4l2_ctrl_config vivid_ctrl_radio_rx_rds_blockio = {
1188 .ops = &vivid_radio_rx_ctrl_ops,
1189 .id = VIVID_CID_RADIO_RX_RDS_BLOCKIO,
1190 .name = "RDS Rx I/O Mode",
1191 .type = V4L2_CTRL_TYPE_MENU,
1192 .qmenu = vivid_ctrl_radio_rds_mode_strings,
1193 .max = 1,
1194};
1195
1196static const struct v4l2_ctrl_config vivid_ctrl_radio_rx_rds_rbds = {
1197 .ops = &vivid_radio_rx_ctrl_ops,
1198 .id = VIVID_CID_RADIO_RX_RDS_RBDS,
1199 .name = "Generate RBDS Instead of RDS",
1200 .type = V4L2_CTRL_TYPE_BOOLEAN,
1201 .max = 1,
1202 .step = 1,
1203};
1204
1205static const char * const vivid_ctrl_radio_hw_seek_mode_strings[] = {
1206 "Bounded",
1207 "Wrap Around",
1208 "Both",
1209 NULL,
1210};
1211
1212static const struct v4l2_ctrl_config vivid_ctrl_radio_hw_seek_mode = {
1213 .ops = &vivid_radio_rx_ctrl_ops,
1214 .id = VIVID_CID_RADIO_SEEK_MODE,
1215 .name = "Radio HW Seek Mode",
1216 .type = V4L2_CTRL_TYPE_MENU,
1217 .max = 2,
1218 .qmenu = vivid_ctrl_radio_hw_seek_mode_strings,
1219};
1220
1221static const struct v4l2_ctrl_config vivid_ctrl_radio_hw_seek_prog_lim = {
1222 .ops = &vivid_radio_rx_ctrl_ops,
1223 .id = VIVID_CID_RADIO_SEEK_PROG_LIM,
1224 .name = "Radio Programmable HW Seek",
1225 .type = V4L2_CTRL_TYPE_BOOLEAN,
1226 .max = 1,
1227 .step = 1,
1228};
1229
1230
1231/* Radio Transmitter Controls */
1232
1233static int vivid_radio_tx_s_ctrl(struct v4l2_ctrl *ctrl)
1234{
1235 struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_radio_tx);
1236
1237 switch (ctrl->id) {
1238 case VIVID_CID_RADIO_TX_RDS_BLOCKIO:
1239 dev->radio_tx_rds_controls = ctrl->val;
1240 dev->radio_tx_caps &= ~V4L2_CAP_READWRITE;
1241 if (!dev->radio_tx_rds_controls)
1242 dev->radio_tx_caps |= V4L2_CAP_READWRITE;
1243 break;
1244 case V4L2_CID_RDS_TX_PTY:
1245 if (dev->radio_rx_rds_controls)
1246 v4l2_ctrl_s_ctrl(dev->radio_rx_rds_pty, ctrl->val);
1247 break;
1248 case V4L2_CID_RDS_TX_PS_NAME:
1249 if (dev->radio_rx_rds_controls)
1250 v4l2_ctrl_s_ctrl_string(dev->radio_rx_rds_psname, ctrl->p_new.p_char);
1251 break;
1252 case V4L2_CID_RDS_TX_RADIO_TEXT:
1253 if (dev->radio_rx_rds_controls)
1254 v4l2_ctrl_s_ctrl_string(dev->radio_rx_rds_radiotext, ctrl->p_new.p_char);
1255 break;
1256 case V4L2_CID_RDS_TX_TRAFFIC_ANNOUNCEMENT:
1257 if (dev->radio_rx_rds_controls)
1258 v4l2_ctrl_s_ctrl(dev->radio_rx_rds_ta, ctrl->val);
1259 break;
1260 case V4L2_CID_RDS_TX_TRAFFIC_PROGRAM:
1261 if (dev->radio_rx_rds_controls)
1262 v4l2_ctrl_s_ctrl(dev->radio_rx_rds_tp, ctrl->val);
1263 break;
1264 case V4L2_CID_RDS_TX_MUSIC_SPEECH:
1265 if (dev->radio_rx_rds_controls)
1266 v4l2_ctrl_s_ctrl(dev->radio_rx_rds_ms, ctrl->val);
1267 break;
1268 }
1269 return 0;
1270}
1271
1272static const struct v4l2_ctrl_ops vivid_radio_tx_ctrl_ops = {
1273 .s_ctrl = vivid_radio_tx_s_ctrl,
1274};
1275
1276static const struct v4l2_ctrl_config vivid_ctrl_radio_tx_rds_blockio = {
1277 .ops = &vivid_radio_tx_ctrl_ops,
1278 .id = VIVID_CID_RADIO_TX_RDS_BLOCKIO,
1279 .name = "RDS Tx I/O Mode",
1280 .type = V4L2_CTRL_TYPE_MENU,
1281 .qmenu = vivid_ctrl_radio_rds_mode_strings,
1282 .max = 1,
1283 .def = 1,
1284};
1285
1286
f335c3f2
AP
1287/* SDR Capture Controls */
1288
1289static int vivid_sdr_cap_s_ctrl(struct v4l2_ctrl *ctrl)
1290{
1291 struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_sdr_cap);
1292
1293 switch (ctrl->id) {
1294 case VIVID_CID_SDR_CAP_FM_DEVIATION:
1295 dev->sdr_fm_deviation = ctrl->val;
1296 break;
1297 }
1298 return 0;
1299}
1300
1301static const struct v4l2_ctrl_ops vivid_sdr_cap_ctrl_ops = {
1302 .s_ctrl = vivid_sdr_cap_s_ctrl,
1303};
1304
1305static const struct v4l2_ctrl_config vivid_ctrl_sdr_cap_fm_deviation = {
1306 .ops = &vivid_sdr_cap_ctrl_ops,
1307 .id = VIVID_CID_SDR_CAP_FM_DEVIATION,
1308 .name = "FM Deviation",
1309 .type = V4L2_CTRL_TYPE_INTEGER,
1310 .min = 100,
1311 .max = 200000,
1312 .def = 75000,
1313 .step = 1,
1314};
1315
1316
73c3f482
HV
1317static const struct v4l2_ctrl_config vivid_ctrl_class = {
1318 .ops = &vivid_user_gen_ctrl_ops,
1319 .flags = V4L2_CTRL_FLAG_READ_ONLY | V4L2_CTRL_FLAG_WRITE_ONLY,
1320 .id = VIVID_CID_VIVID_CLASS,
1321 .name = "Vivid Controls",
1322 .type = V4L2_CTRL_TYPE_CTRL_CLASS,
1323};
1324
1325int vivid_create_controls(struct vivid_dev *dev, bool show_ccs_cap,
1326 bool show_ccs_out, bool no_error_inj,
1327 bool has_sdtv, bool has_hdmi)
1328{
1329 struct v4l2_ctrl_handler *hdl_user_gen = &dev->ctrl_hdl_user_gen;
1330 struct v4l2_ctrl_handler *hdl_user_vid = &dev->ctrl_hdl_user_vid;
1331 struct v4l2_ctrl_handler *hdl_user_aud = &dev->ctrl_hdl_user_aud;
1332 struct v4l2_ctrl_handler *hdl_streaming = &dev->ctrl_hdl_streaming;
1333 struct v4l2_ctrl_handler *hdl_sdtv_cap = &dev->ctrl_hdl_sdtv_cap;
63344b65 1334 struct v4l2_ctrl_handler *hdl_loop_cap = &dev->ctrl_hdl_loop_cap;
73c3f482
HV
1335 struct v4l2_ctrl_handler *hdl_vid_cap = &dev->ctrl_hdl_vid_cap;
1336 struct v4l2_ctrl_handler *hdl_vid_out = &dev->ctrl_hdl_vid_out;
1337 struct v4l2_ctrl_handler *hdl_vbi_cap = &dev->ctrl_hdl_vbi_cap;
1338 struct v4l2_ctrl_handler *hdl_vbi_out = &dev->ctrl_hdl_vbi_out;
1339 struct v4l2_ctrl_handler *hdl_radio_rx = &dev->ctrl_hdl_radio_rx;
1340 struct v4l2_ctrl_handler *hdl_radio_tx = &dev->ctrl_hdl_radio_tx;
1341 struct v4l2_ctrl_handler *hdl_sdr_cap = &dev->ctrl_hdl_sdr_cap;
1342 struct v4l2_ctrl_config vivid_ctrl_dv_timings = {
1343 .ops = &vivid_vid_cap_ctrl_ops,
1344 .id = VIVID_CID_DV_TIMINGS,
1345 .name = "DV Timings",
1346 .type = V4L2_CTRL_TYPE_MENU,
1347 };
1348 int i;
1349
1350 v4l2_ctrl_handler_init(hdl_user_gen, 10);
1351 v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_class, NULL);
1352 v4l2_ctrl_handler_init(hdl_user_vid, 9);
1353 v4l2_ctrl_new_custom(hdl_user_vid, &vivid_ctrl_class, NULL);
1354 v4l2_ctrl_handler_init(hdl_user_aud, 2);
1355 v4l2_ctrl_new_custom(hdl_user_aud, &vivid_ctrl_class, NULL);
1356 v4l2_ctrl_handler_init(hdl_streaming, 8);
1357 v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_class, NULL);
1358 v4l2_ctrl_handler_init(hdl_sdtv_cap, 2);
1359 v4l2_ctrl_new_custom(hdl_sdtv_cap, &vivid_ctrl_class, NULL);
63344b65
HV
1360 v4l2_ctrl_handler_init(hdl_loop_cap, 1);
1361 v4l2_ctrl_new_custom(hdl_loop_cap, &vivid_ctrl_class, NULL);
73c3f482
HV
1362 v4l2_ctrl_handler_init(hdl_vid_cap, 55);
1363 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_class, NULL);
1364 v4l2_ctrl_handler_init(hdl_vid_out, 26);
f6de9f60
HV
1365 if (!no_error_inj)
1366 v4l2_ctrl_new_custom(hdl_vid_out, &vivid_ctrl_class, NULL);
73c3f482
HV
1367 v4l2_ctrl_handler_init(hdl_vbi_cap, 21);
1368 v4l2_ctrl_new_custom(hdl_vbi_cap, &vivid_ctrl_class, NULL);
1369 v4l2_ctrl_handler_init(hdl_vbi_out, 19);
f6de9f60
HV
1370 if (!no_error_inj)
1371 v4l2_ctrl_new_custom(hdl_vbi_out, &vivid_ctrl_class, NULL);
73c3f482
HV
1372 v4l2_ctrl_handler_init(hdl_radio_rx, 17);
1373 v4l2_ctrl_new_custom(hdl_radio_rx, &vivid_ctrl_class, NULL);
1374 v4l2_ctrl_handler_init(hdl_radio_tx, 17);
1375 v4l2_ctrl_new_custom(hdl_radio_tx, &vivid_ctrl_class, NULL);
f335c3f2 1376 v4l2_ctrl_handler_init(hdl_sdr_cap, 19);
73c3f482
HV
1377 v4l2_ctrl_new_custom(hdl_sdr_cap, &vivid_ctrl_class, NULL);
1378
1379 /* User Controls */
1380 dev->volume = v4l2_ctrl_new_std(hdl_user_aud, NULL,
1381 V4L2_CID_AUDIO_VOLUME, 0, 255, 1, 200);
1382 dev->mute = v4l2_ctrl_new_std(hdl_user_aud, NULL,
1383 V4L2_CID_AUDIO_MUTE, 0, 1, 1, 0);
1384 if (dev->has_vid_cap) {
1385 dev->brightness = v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops,
1386 V4L2_CID_BRIGHTNESS, 0, 255, 1, 128);
1387 for (i = 0; i < MAX_INPUTS; i++)
1388 dev->input_brightness[i] = 128;
1389 dev->contrast = v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops,
1390 V4L2_CID_CONTRAST, 0, 255, 1, 128);
1391 dev->saturation = v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops,
1392 V4L2_CID_SATURATION, 0, 255, 1, 128);
1393 dev->hue = v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops,
1394 V4L2_CID_HUE, -128, 128, 1, 0);
1395 v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops,
1396 V4L2_CID_HFLIP, 0, 1, 1, 0);
1397 v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops,
1398 V4L2_CID_VFLIP, 0, 1, 1, 0);
1399 dev->autogain = v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops,
1400 V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
1401 dev->gain = v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops,
1402 V4L2_CID_GAIN, 0, 255, 1, 100);
1403 dev->alpha = v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops,
1404 V4L2_CID_ALPHA_COMPONENT, 0, 255, 1, 0);
1405 }
1406 dev->button = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_button, NULL);
1407 dev->int32 = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_int32, NULL);
1408 dev->int64 = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_int64, NULL);
1409 dev->boolean = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_boolean, NULL);
1410 dev->menu = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_menu, NULL);
1411 dev->string = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_string, NULL);
1412 dev->bitmask = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_bitmask, NULL);
1413 dev->int_menu = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_int_menu, NULL);
24c4942d
HV
1414 v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_u32_array, NULL);
1415 v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_u16_matrix, NULL);
1416 v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_u8_4d_array, NULL);
73c3f482
HV
1417
1418 if (dev->has_vid_cap) {
1419 /* Image Processing Controls */
1420 struct v4l2_ctrl_config vivid_ctrl_test_pattern = {
1421 .ops = &vivid_vid_cap_ctrl_ops,
1422 .id = VIVID_CID_TEST_PATTERN,
1423 .name = "Test Pattern",
1424 .type = V4L2_CTRL_TYPE_MENU,
1425 .max = TPG_PAT_NOISE,
1426 .qmenu = tpg_pattern_strings,
1427 };
1428
1429 dev->test_pattern = v4l2_ctrl_new_custom(hdl_vid_cap,
1430 &vivid_ctrl_test_pattern, NULL);
1431 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_perc_fill, NULL);
1432 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_hor_movement, NULL);
1433 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_vert_movement, NULL);
1434 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_osd_mode, NULL);
1435 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_show_border, NULL);
1436 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_show_square, NULL);
1437 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_hflip, NULL);
1438 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_vflip, NULL);
1439 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_insert_sav, NULL);
1440 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_insert_eav, NULL);
c79aa6ae 1441 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_reduced_fps, NULL);
73c3f482
HV
1442 if (show_ccs_cap) {
1443 dev->ctrl_has_crop_cap = v4l2_ctrl_new_custom(hdl_vid_cap,
1444 &vivid_ctrl_has_crop_cap, NULL);
1445 dev->ctrl_has_compose_cap = v4l2_ctrl_new_custom(hdl_vid_cap,
1446 &vivid_ctrl_has_compose_cap, NULL);
1447 dev->ctrl_has_scaler_cap = v4l2_ctrl_new_custom(hdl_vid_cap,
1448 &vivid_ctrl_has_scaler_cap, NULL);
1449 }
1450
1451 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_tstamp_src, NULL);
1452 dev->colorspace = v4l2_ctrl_new_custom(hdl_vid_cap,
1453 &vivid_ctrl_colorspace, NULL);
ca5316db 1454 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_xfer_func, NULL);
3e8a78d1
HV
1455 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_ycbcr_enc, NULL);
1456 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_quantization, NULL);
73c3f482
HV
1457 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_alpha_mode, NULL);
1458 }
1459
1460 if (dev->has_vid_out && show_ccs_out) {
1461 dev->ctrl_has_crop_out = v4l2_ctrl_new_custom(hdl_vid_out,
1462 &vivid_ctrl_has_crop_out, NULL);
1463 dev->ctrl_has_compose_out = v4l2_ctrl_new_custom(hdl_vid_out,
1464 &vivid_ctrl_has_compose_out, NULL);
1465 dev->ctrl_has_scaler_out = v4l2_ctrl_new_custom(hdl_vid_out,
1466 &vivid_ctrl_has_scaler_out, NULL);
1467 }
1468
1469 /*
1470 * Testing this driver with v4l2-compliance will trigger the error
1471 * injection controls, and after that nothing will work as expected.
1472 * So we have a module option to drop these error injecting controls
1473 * allowing us to run v4l2_compliance again.
1474 */
1475 if (!no_error_inj) {
1476 v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_disconnect, NULL);
1477 v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_dqbuf_error, NULL);
1478 v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_perc_dropped, NULL);
1479 v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_queue_setup_error, NULL);
1480 v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_buf_prepare_error, NULL);
1481 v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_start_streaming_error, NULL);
1482 v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_queue_error, NULL);
1483 v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_seq_wrap, NULL);
1484 v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_time_wrap, NULL);
1485 }
1486
1487 if (has_sdtv && (dev->has_vid_cap || dev->has_vbi_cap)) {
1488 if (dev->has_vid_cap)
1489 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_std_aspect_ratio, NULL);
1490 dev->ctrl_std_signal_mode = v4l2_ctrl_new_custom(hdl_sdtv_cap,
1491 &vivid_ctrl_std_signal_mode, NULL);
1492 dev->ctrl_standard = v4l2_ctrl_new_custom(hdl_sdtv_cap,
1493 &vivid_ctrl_standard, NULL);
1494 if (dev->ctrl_std_signal_mode)
1495 v4l2_ctrl_cluster(2, &dev->ctrl_std_signal_mode);
1496 if (dev->has_raw_vbi_cap)
1497 v4l2_ctrl_new_custom(hdl_vbi_cap, &vivid_ctrl_vbi_cap_interlaced, NULL);
1498 }
1499
1500 if (has_hdmi && dev->has_vid_cap) {
1501 dev->ctrl_dv_timings_signal_mode = v4l2_ctrl_new_custom(hdl_vid_cap,
1502 &vivid_ctrl_dv_timings_signal_mode, NULL);
1503
1504 vivid_ctrl_dv_timings.max = dev->query_dv_timings_size - 1;
1505 vivid_ctrl_dv_timings.qmenu =
1506 (const char * const *)dev->query_dv_timings_qmenu;
1507 dev->ctrl_dv_timings = v4l2_ctrl_new_custom(hdl_vid_cap,
1508 &vivid_ctrl_dv_timings, NULL);
1509 if (dev->ctrl_dv_timings_signal_mode)
1510 v4l2_ctrl_cluster(2, &dev->ctrl_dv_timings_signal_mode);
1511
1512 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_dv_timings_aspect_ratio, NULL);
1513 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_max_edid_blocks, NULL);
1514 dev->real_rgb_range_cap = v4l2_ctrl_new_custom(hdl_vid_cap,
1515 &vivid_ctrl_limited_rgb_range, NULL);
1516 dev->rgb_range_cap = v4l2_ctrl_new_std_menu(hdl_vid_cap,
1517 &vivid_vid_cap_ctrl_ops,
1518 V4L2_CID_DV_RX_RGB_RANGE, V4L2_DV_RGB_RANGE_FULL,
1519 0, V4L2_DV_RGB_RANGE_AUTO);
1520 }
1521 if (has_hdmi && dev->has_vid_out) {
1522 /*
1523 * We aren't doing anything with this at the moment, but
1524 * HDMI outputs typically have this controls.
1525 */
1526 dev->ctrl_tx_rgb_range = v4l2_ctrl_new_std_menu(hdl_vid_out, NULL,
1527 V4L2_CID_DV_TX_RGB_RANGE, V4L2_DV_RGB_RANGE_FULL,
1528 0, V4L2_DV_RGB_RANGE_AUTO);
1529 dev->ctrl_tx_mode = v4l2_ctrl_new_std_menu(hdl_vid_out, NULL,
1530 V4L2_CID_DV_TX_MODE, V4L2_DV_TX_MODE_HDMI,
1531 0, V4L2_DV_TX_MODE_HDMI);
1532 }
1533 if ((dev->has_vid_cap && dev->has_vid_out) ||
1534 (dev->has_vbi_cap && dev->has_vbi_out))
63344b65 1535 v4l2_ctrl_new_custom(hdl_loop_cap, &vivid_ctrl_loop_video, NULL);
73c3f482
HV
1536
1537 if (dev->has_fb)
1538 v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_clear_fb, NULL);
1539
1540 if (dev->has_radio_rx) {
1541 v4l2_ctrl_new_custom(hdl_radio_rx, &vivid_ctrl_radio_hw_seek_mode, NULL);
1542 v4l2_ctrl_new_custom(hdl_radio_rx, &vivid_ctrl_radio_hw_seek_prog_lim, NULL);
1543 v4l2_ctrl_new_custom(hdl_radio_rx, &vivid_ctrl_radio_rx_rds_blockio, NULL);
1544 v4l2_ctrl_new_custom(hdl_radio_rx, &vivid_ctrl_radio_rx_rds_rbds, NULL);
1545 v4l2_ctrl_new_std(hdl_radio_rx, &vivid_radio_rx_ctrl_ops,
1546 V4L2_CID_RDS_RECEPTION, 0, 1, 1, 1);
1547 dev->radio_rx_rds_pty = v4l2_ctrl_new_std(hdl_radio_rx,
1548 &vivid_radio_rx_ctrl_ops,
1549 V4L2_CID_RDS_RX_PTY, 0, 31, 1, 0);
1550 dev->radio_rx_rds_psname = v4l2_ctrl_new_std(hdl_radio_rx,
1551 &vivid_radio_rx_ctrl_ops,
1552 V4L2_CID_RDS_RX_PS_NAME, 0, 8, 8, 0);
1553 dev->radio_rx_rds_radiotext = v4l2_ctrl_new_std(hdl_radio_rx,
1554 &vivid_radio_rx_ctrl_ops,
1555 V4L2_CID_RDS_RX_RADIO_TEXT, 0, 64, 64, 0);
1556 dev->radio_rx_rds_ta = v4l2_ctrl_new_std(hdl_radio_rx,
1557 &vivid_radio_rx_ctrl_ops,
1558 V4L2_CID_RDS_RX_TRAFFIC_ANNOUNCEMENT, 0, 1, 1, 0);
1559 dev->radio_rx_rds_tp = v4l2_ctrl_new_std(hdl_radio_rx,
1560 &vivid_radio_rx_ctrl_ops,
1561 V4L2_CID_RDS_RX_TRAFFIC_PROGRAM, 0, 1, 1, 0);
1562 dev->radio_rx_rds_ms = v4l2_ctrl_new_std(hdl_radio_rx,
1563 &vivid_radio_rx_ctrl_ops,
1564 V4L2_CID_RDS_RX_MUSIC_SPEECH, 0, 1, 1, 1);
1565 }
1566 if (dev->has_radio_tx) {
1567 v4l2_ctrl_new_custom(hdl_radio_tx,
1568 &vivid_ctrl_radio_tx_rds_blockio, NULL);
1569 dev->radio_tx_rds_pi = v4l2_ctrl_new_std(hdl_radio_tx,
1570 &vivid_radio_tx_ctrl_ops,
1571 V4L2_CID_RDS_TX_PI, 0, 0xffff, 1, 0x8088);
1572 dev->radio_tx_rds_pty = v4l2_ctrl_new_std(hdl_radio_tx,
1573 &vivid_radio_tx_ctrl_ops,
1574 V4L2_CID_RDS_TX_PTY, 0, 31, 1, 3);
1575 dev->radio_tx_rds_psname = v4l2_ctrl_new_std(hdl_radio_tx,
1576 &vivid_radio_tx_ctrl_ops,
1577 V4L2_CID_RDS_TX_PS_NAME, 0, 8, 8, 0);
1578 if (dev->radio_tx_rds_psname)
1579 v4l2_ctrl_s_ctrl_string(dev->radio_tx_rds_psname, "VIVID-TX");
1580 dev->radio_tx_rds_radiotext = v4l2_ctrl_new_std(hdl_radio_tx,
1581 &vivid_radio_tx_ctrl_ops,
1582 V4L2_CID_RDS_TX_RADIO_TEXT, 0, 64 * 2, 64, 0);
1583 if (dev->radio_tx_rds_radiotext)
1584 v4l2_ctrl_s_ctrl_string(dev->radio_tx_rds_radiotext,
1585 "This is a VIVID default Radio Text template text, change at will");
1586 dev->radio_tx_rds_mono_stereo = v4l2_ctrl_new_std(hdl_radio_tx,
1587 &vivid_radio_tx_ctrl_ops,
1588 V4L2_CID_RDS_TX_MONO_STEREO, 0, 1, 1, 1);
1589 dev->radio_tx_rds_art_head = v4l2_ctrl_new_std(hdl_radio_tx,
1590 &vivid_radio_tx_ctrl_ops,
1591 V4L2_CID_RDS_TX_ARTIFICIAL_HEAD, 0, 1, 1, 0);
1592 dev->radio_tx_rds_compressed = v4l2_ctrl_new_std(hdl_radio_tx,
1593 &vivid_radio_tx_ctrl_ops,
1594 V4L2_CID_RDS_TX_COMPRESSED, 0, 1, 1, 0);
1595 dev->radio_tx_rds_dyn_pty = v4l2_ctrl_new_std(hdl_radio_tx,
1596 &vivid_radio_tx_ctrl_ops,
1597 V4L2_CID_RDS_TX_DYNAMIC_PTY, 0, 1, 1, 0);
1598 dev->radio_tx_rds_ta = v4l2_ctrl_new_std(hdl_radio_tx,
1599 &vivid_radio_tx_ctrl_ops,
1600 V4L2_CID_RDS_TX_TRAFFIC_ANNOUNCEMENT, 0, 1, 1, 0);
1601 dev->radio_tx_rds_tp = v4l2_ctrl_new_std(hdl_radio_tx,
1602 &vivid_radio_tx_ctrl_ops,
1603 V4L2_CID_RDS_TX_TRAFFIC_PROGRAM, 0, 1, 1, 1);
1604 dev->radio_tx_rds_ms = v4l2_ctrl_new_std(hdl_radio_tx,
1605 &vivid_radio_tx_ctrl_ops,
1606 V4L2_CID_RDS_TX_MUSIC_SPEECH, 0, 1, 1, 1);
1607 }
f335c3f2
AP
1608 if (dev->has_sdr_cap) {
1609 v4l2_ctrl_new_custom(hdl_sdr_cap,
1610 &vivid_ctrl_sdr_cap_fm_deviation, NULL);
1611 }
73c3f482
HV
1612 if (hdl_user_gen->error)
1613 return hdl_user_gen->error;
1614 if (hdl_user_vid->error)
1615 return hdl_user_vid->error;
1616 if (hdl_user_aud->error)
1617 return hdl_user_aud->error;
1618 if (hdl_streaming->error)
1619 return hdl_streaming->error;
1620 if (hdl_sdr_cap->error)
1621 return hdl_sdr_cap->error;
63344b65
HV
1622 if (hdl_loop_cap->error)
1623 return hdl_loop_cap->error;
73c3f482
HV
1624
1625 if (dev->autogain)
1626 v4l2_ctrl_auto_cluster(2, &dev->autogain, 0, true);
1627
1628 if (dev->has_vid_cap) {
1629 v4l2_ctrl_add_handler(hdl_vid_cap, hdl_user_gen, NULL);
1630 v4l2_ctrl_add_handler(hdl_vid_cap, hdl_user_vid, NULL);
1631 v4l2_ctrl_add_handler(hdl_vid_cap, hdl_user_aud, NULL);
1632 v4l2_ctrl_add_handler(hdl_vid_cap, hdl_streaming, NULL);
1633 v4l2_ctrl_add_handler(hdl_vid_cap, hdl_sdtv_cap, NULL);
63344b65 1634 v4l2_ctrl_add_handler(hdl_vid_cap, hdl_loop_cap, NULL);
73c3f482
HV
1635 if (hdl_vid_cap->error)
1636 return hdl_vid_cap->error;
1637 dev->vid_cap_dev.ctrl_handler = hdl_vid_cap;
1638 }
1639 if (dev->has_vid_out) {
1640 v4l2_ctrl_add_handler(hdl_vid_out, hdl_user_gen, NULL);
1641 v4l2_ctrl_add_handler(hdl_vid_out, hdl_user_aud, NULL);
1642 v4l2_ctrl_add_handler(hdl_vid_out, hdl_streaming, NULL);
73c3f482
HV
1643 if (hdl_vid_out->error)
1644 return hdl_vid_out->error;
1645 dev->vid_out_dev.ctrl_handler = hdl_vid_out;
1646 }
1647 if (dev->has_vbi_cap) {
1648 v4l2_ctrl_add_handler(hdl_vbi_cap, hdl_user_gen, NULL);
1649 v4l2_ctrl_add_handler(hdl_vbi_cap, hdl_streaming, NULL);
1650 v4l2_ctrl_add_handler(hdl_vbi_cap, hdl_sdtv_cap, NULL);
63344b65 1651 v4l2_ctrl_add_handler(hdl_vbi_cap, hdl_loop_cap, NULL);
73c3f482
HV
1652 if (hdl_vbi_cap->error)
1653 return hdl_vbi_cap->error;
1654 dev->vbi_cap_dev.ctrl_handler = hdl_vbi_cap;
1655 }
1656 if (dev->has_vbi_out) {
1657 v4l2_ctrl_add_handler(hdl_vbi_out, hdl_user_gen, NULL);
1658 v4l2_ctrl_add_handler(hdl_vbi_out, hdl_streaming, NULL);
73c3f482
HV
1659 if (hdl_vbi_out->error)
1660 return hdl_vbi_out->error;
1661 dev->vbi_out_dev.ctrl_handler = hdl_vbi_out;
1662 }
1663 if (dev->has_radio_rx) {
1664 v4l2_ctrl_add_handler(hdl_radio_rx, hdl_user_gen, NULL);
1665 v4l2_ctrl_add_handler(hdl_radio_rx, hdl_user_aud, NULL);
1666 if (hdl_radio_rx->error)
1667 return hdl_radio_rx->error;
1668 dev->radio_rx_dev.ctrl_handler = hdl_radio_rx;
1669 }
1670 if (dev->has_radio_tx) {
1671 v4l2_ctrl_add_handler(hdl_radio_tx, hdl_user_gen, NULL);
1672 v4l2_ctrl_add_handler(hdl_radio_tx, hdl_user_aud, NULL);
1673 if (hdl_radio_tx->error)
1674 return hdl_radio_tx->error;
1675 dev->radio_tx_dev.ctrl_handler = hdl_radio_tx;
1676 }
1677 if (dev->has_sdr_cap) {
1678 v4l2_ctrl_add_handler(hdl_sdr_cap, hdl_user_gen, NULL);
1679 v4l2_ctrl_add_handler(hdl_sdr_cap, hdl_streaming, NULL);
1680 if (hdl_sdr_cap->error)
1681 return hdl_sdr_cap->error;
1682 dev->sdr_cap_dev.ctrl_handler = hdl_sdr_cap;
1683 }
1684 return 0;
1685}
1686
1687void vivid_free_controls(struct vivid_dev *dev)
1688{
1689 v4l2_ctrl_handler_free(&dev->ctrl_hdl_vid_cap);
1690 v4l2_ctrl_handler_free(&dev->ctrl_hdl_vid_out);
1691 v4l2_ctrl_handler_free(&dev->ctrl_hdl_vbi_cap);
1692 v4l2_ctrl_handler_free(&dev->ctrl_hdl_vbi_out);
1693 v4l2_ctrl_handler_free(&dev->ctrl_hdl_radio_rx);
1694 v4l2_ctrl_handler_free(&dev->ctrl_hdl_radio_tx);
1695 v4l2_ctrl_handler_free(&dev->ctrl_hdl_sdr_cap);
1696 v4l2_ctrl_handler_free(&dev->ctrl_hdl_user_gen);
1697 v4l2_ctrl_handler_free(&dev->ctrl_hdl_user_vid);
1698 v4l2_ctrl_handler_free(&dev->ctrl_hdl_user_aud);
1699 v4l2_ctrl_handler_free(&dev->ctrl_hdl_streaming);
1700 v4l2_ctrl_handler_free(&dev->ctrl_hdl_sdtv_cap);
63344b65 1701 v4l2_ctrl_handler_free(&dev->ctrl_hdl_loop_cap);
73c3f482 1702}
This page took 0.163081 seconds and 5 git commands to generate.