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