brintos

brintos / linux-shallow public Read only

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