18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * vivid-ctrls.c - control support functions. 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved. 68c2ecf20Sopenharmony_ci */ 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_ci#include <linux/errno.h> 98c2ecf20Sopenharmony_ci#include <linux/kernel.h> 108c2ecf20Sopenharmony_ci#include <linux/videodev2.h> 118c2ecf20Sopenharmony_ci#include <media/v4l2-event.h> 128c2ecf20Sopenharmony_ci#include <media/v4l2-common.h> 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_ci#include "vivid-core.h" 158c2ecf20Sopenharmony_ci#include "vivid-vid-cap.h" 168c2ecf20Sopenharmony_ci#include "vivid-vid-out.h" 178c2ecf20Sopenharmony_ci#include "vivid-vid-common.h" 188c2ecf20Sopenharmony_ci#include "vivid-radio-common.h" 198c2ecf20Sopenharmony_ci#include "vivid-osd.h" 208c2ecf20Sopenharmony_ci#include "vivid-ctrls.h" 218c2ecf20Sopenharmony_ci#include "vivid-cec.h" 228c2ecf20Sopenharmony_ci 238c2ecf20Sopenharmony_ci#define VIVID_CID_CUSTOM_BASE (V4L2_CID_USER_BASE | 0xf000) 248c2ecf20Sopenharmony_ci#define VIVID_CID_BUTTON (VIVID_CID_CUSTOM_BASE + 0) 258c2ecf20Sopenharmony_ci#define VIVID_CID_BOOLEAN (VIVID_CID_CUSTOM_BASE + 1) 268c2ecf20Sopenharmony_ci#define VIVID_CID_INTEGER (VIVID_CID_CUSTOM_BASE + 2) 278c2ecf20Sopenharmony_ci#define VIVID_CID_INTEGER64 (VIVID_CID_CUSTOM_BASE + 3) 288c2ecf20Sopenharmony_ci#define VIVID_CID_MENU (VIVID_CID_CUSTOM_BASE + 4) 298c2ecf20Sopenharmony_ci#define VIVID_CID_STRING (VIVID_CID_CUSTOM_BASE + 5) 308c2ecf20Sopenharmony_ci#define VIVID_CID_BITMASK (VIVID_CID_CUSTOM_BASE + 6) 318c2ecf20Sopenharmony_ci#define VIVID_CID_INTMENU (VIVID_CID_CUSTOM_BASE + 7) 328c2ecf20Sopenharmony_ci#define VIVID_CID_U32_ARRAY (VIVID_CID_CUSTOM_BASE + 8) 338c2ecf20Sopenharmony_ci#define VIVID_CID_U16_MATRIX (VIVID_CID_CUSTOM_BASE + 9) 348c2ecf20Sopenharmony_ci#define VIVID_CID_U8_4D_ARRAY (VIVID_CID_CUSTOM_BASE + 10) 358c2ecf20Sopenharmony_ci#define VIVID_CID_AREA (VIVID_CID_CUSTOM_BASE + 11) 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_ci#define VIVID_CID_VIVID_BASE (0x00f00000 | 0xf000) 388c2ecf20Sopenharmony_ci#define VIVID_CID_VIVID_CLASS (0x00f00000 | 1) 398c2ecf20Sopenharmony_ci#define VIVID_CID_TEST_PATTERN (VIVID_CID_VIVID_BASE + 0) 408c2ecf20Sopenharmony_ci#define VIVID_CID_OSD_TEXT_MODE (VIVID_CID_VIVID_BASE + 1) 418c2ecf20Sopenharmony_ci#define VIVID_CID_HOR_MOVEMENT (VIVID_CID_VIVID_BASE + 2) 428c2ecf20Sopenharmony_ci#define VIVID_CID_VERT_MOVEMENT (VIVID_CID_VIVID_BASE + 3) 438c2ecf20Sopenharmony_ci#define VIVID_CID_SHOW_BORDER (VIVID_CID_VIVID_BASE + 4) 448c2ecf20Sopenharmony_ci#define VIVID_CID_SHOW_SQUARE (VIVID_CID_VIVID_BASE + 5) 458c2ecf20Sopenharmony_ci#define VIVID_CID_INSERT_SAV (VIVID_CID_VIVID_BASE + 6) 468c2ecf20Sopenharmony_ci#define VIVID_CID_INSERT_EAV (VIVID_CID_VIVID_BASE + 7) 478c2ecf20Sopenharmony_ci#define VIVID_CID_VBI_CAP_INTERLACED (VIVID_CID_VIVID_BASE + 8) 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_ci#define VIVID_CID_HFLIP (VIVID_CID_VIVID_BASE + 20) 508c2ecf20Sopenharmony_ci#define VIVID_CID_VFLIP (VIVID_CID_VIVID_BASE + 21) 518c2ecf20Sopenharmony_ci#define VIVID_CID_STD_ASPECT_RATIO (VIVID_CID_VIVID_BASE + 22) 528c2ecf20Sopenharmony_ci#define VIVID_CID_DV_TIMINGS_ASPECT_RATIO (VIVID_CID_VIVID_BASE + 23) 538c2ecf20Sopenharmony_ci#define VIVID_CID_TSTAMP_SRC (VIVID_CID_VIVID_BASE + 24) 548c2ecf20Sopenharmony_ci#define VIVID_CID_COLORSPACE (VIVID_CID_VIVID_BASE + 25) 558c2ecf20Sopenharmony_ci#define VIVID_CID_XFER_FUNC (VIVID_CID_VIVID_BASE + 26) 568c2ecf20Sopenharmony_ci#define VIVID_CID_YCBCR_ENC (VIVID_CID_VIVID_BASE + 27) 578c2ecf20Sopenharmony_ci#define VIVID_CID_QUANTIZATION (VIVID_CID_VIVID_BASE + 28) 588c2ecf20Sopenharmony_ci#define VIVID_CID_LIMITED_RGB_RANGE (VIVID_CID_VIVID_BASE + 29) 598c2ecf20Sopenharmony_ci#define VIVID_CID_ALPHA_MODE (VIVID_CID_VIVID_BASE + 30) 608c2ecf20Sopenharmony_ci#define VIVID_CID_HAS_CROP_CAP (VIVID_CID_VIVID_BASE + 31) 618c2ecf20Sopenharmony_ci#define VIVID_CID_HAS_COMPOSE_CAP (VIVID_CID_VIVID_BASE + 32) 628c2ecf20Sopenharmony_ci#define VIVID_CID_HAS_SCALER_CAP (VIVID_CID_VIVID_BASE + 33) 638c2ecf20Sopenharmony_ci#define VIVID_CID_HAS_CROP_OUT (VIVID_CID_VIVID_BASE + 34) 648c2ecf20Sopenharmony_ci#define VIVID_CID_HAS_COMPOSE_OUT (VIVID_CID_VIVID_BASE + 35) 658c2ecf20Sopenharmony_ci#define VIVID_CID_HAS_SCALER_OUT (VIVID_CID_VIVID_BASE + 36) 668c2ecf20Sopenharmony_ci#define VIVID_CID_LOOP_VIDEO (VIVID_CID_VIVID_BASE + 37) 678c2ecf20Sopenharmony_ci#define VIVID_CID_SEQ_WRAP (VIVID_CID_VIVID_BASE + 38) 688c2ecf20Sopenharmony_ci#define VIVID_CID_TIME_WRAP (VIVID_CID_VIVID_BASE + 39) 698c2ecf20Sopenharmony_ci#define VIVID_CID_MAX_EDID_BLOCKS (VIVID_CID_VIVID_BASE + 40) 708c2ecf20Sopenharmony_ci#define VIVID_CID_PERCENTAGE_FILL (VIVID_CID_VIVID_BASE + 41) 718c2ecf20Sopenharmony_ci#define VIVID_CID_REDUCED_FPS (VIVID_CID_VIVID_BASE + 42) 728c2ecf20Sopenharmony_ci#define VIVID_CID_HSV_ENC (VIVID_CID_VIVID_BASE + 43) 738c2ecf20Sopenharmony_ci#define VIVID_CID_DISPLAY_PRESENT (VIVID_CID_VIVID_BASE + 44) 748c2ecf20Sopenharmony_ci 758c2ecf20Sopenharmony_ci#define VIVID_CID_STD_SIGNAL_MODE (VIVID_CID_VIVID_BASE + 60) 768c2ecf20Sopenharmony_ci#define VIVID_CID_STANDARD (VIVID_CID_VIVID_BASE + 61) 778c2ecf20Sopenharmony_ci#define VIVID_CID_DV_TIMINGS_SIGNAL_MODE (VIVID_CID_VIVID_BASE + 62) 788c2ecf20Sopenharmony_ci#define VIVID_CID_DV_TIMINGS (VIVID_CID_VIVID_BASE + 63) 798c2ecf20Sopenharmony_ci#define VIVID_CID_PERC_DROPPED (VIVID_CID_VIVID_BASE + 64) 808c2ecf20Sopenharmony_ci#define VIVID_CID_DISCONNECT (VIVID_CID_VIVID_BASE + 65) 818c2ecf20Sopenharmony_ci#define VIVID_CID_DQBUF_ERROR (VIVID_CID_VIVID_BASE + 66) 828c2ecf20Sopenharmony_ci#define VIVID_CID_QUEUE_SETUP_ERROR (VIVID_CID_VIVID_BASE + 67) 838c2ecf20Sopenharmony_ci#define VIVID_CID_BUF_PREPARE_ERROR (VIVID_CID_VIVID_BASE + 68) 848c2ecf20Sopenharmony_ci#define VIVID_CID_START_STR_ERROR (VIVID_CID_VIVID_BASE + 69) 858c2ecf20Sopenharmony_ci#define VIVID_CID_QUEUE_ERROR (VIVID_CID_VIVID_BASE + 70) 868c2ecf20Sopenharmony_ci#define VIVID_CID_CLEAR_FB (VIVID_CID_VIVID_BASE + 71) 878c2ecf20Sopenharmony_ci#define VIVID_CID_REQ_VALIDATE_ERROR (VIVID_CID_VIVID_BASE + 72) 888c2ecf20Sopenharmony_ci 898c2ecf20Sopenharmony_ci#define VIVID_CID_RADIO_SEEK_MODE (VIVID_CID_VIVID_BASE + 90) 908c2ecf20Sopenharmony_ci#define VIVID_CID_RADIO_SEEK_PROG_LIM (VIVID_CID_VIVID_BASE + 91) 918c2ecf20Sopenharmony_ci#define VIVID_CID_RADIO_RX_RDS_RBDS (VIVID_CID_VIVID_BASE + 92) 928c2ecf20Sopenharmony_ci#define VIVID_CID_RADIO_RX_RDS_BLOCKIO (VIVID_CID_VIVID_BASE + 93) 938c2ecf20Sopenharmony_ci 948c2ecf20Sopenharmony_ci#define VIVID_CID_RADIO_TX_RDS_BLOCKIO (VIVID_CID_VIVID_BASE + 94) 958c2ecf20Sopenharmony_ci 968c2ecf20Sopenharmony_ci#define VIVID_CID_SDR_CAP_FM_DEVIATION (VIVID_CID_VIVID_BASE + 110) 978c2ecf20Sopenharmony_ci 988c2ecf20Sopenharmony_ci#define VIVID_CID_META_CAP_GENERATE_PTS (VIVID_CID_VIVID_BASE + 111) 998c2ecf20Sopenharmony_ci#define VIVID_CID_META_CAP_GENERATE_SCR (VIVID_CID_VIVID_BASE + 112) 1008c2ecf20Sopenharmony_ci 1018c2ecf20Sopenharmony_ci/* General User Controls */ 1028c2ecf20Sopenharmony_ci 1038c2ecf20Sopenharmony_cistatic int vivid_user_gen_s_ctrl(struct v4l2_ctrl *ctrl) 1048c2ecf20Sopenharmony_ci{ 1058c2ecf20Sopenharmony_ci struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_user_gen); 1068c2ecf20Sopenharmony_ci 1078c2ecf20Sopenharmony_ci switch (ctrl->id) { 1088c2ecf20Sopenharmony_ci case VIVID_CID_DISCONNECT: 1098c2ecf20Sopenharmony_ci v4l2_info(&dev->v4l2_dev, "disconnect\n"); 1108c2ecf20Sopenharmony_ci clear_bit(V4L2_FL_REGISTERED, &dev->vid_cap_dev.flags); 1118c2ecf20Sopenharmony_ci clear_bit(V4L2_FL_REGISTERED, &dev->vid_out_dev.flags); 1128c2ecf20Sopenharmony_ci clear_bit(V4L2_FL_REGISTERED, &dev->vbi_cap_dev.flags); 1138c2ecf20Sopenharmony_ci clear_bit(V4L2_FL_REGISTERED, &dev->vbi_out_dev.flags); 1148c2ecf20Sopenharmony_ci clear_bit(V4L2_FL_REGISTERED, &dev->sdr_cap_dev.flags); 1158c2ecf20Sopenharmony_ci clear_bit(V4L2_FL_REGISTERED, &dev->radio_rx_dev.flags); 1168c2ecf20Sopenharmony_ci clear_bit(V4L2_FL_REGISTERED, &dev->radio_tx_dev.flags); 1178c2ecf20Sopenharmony_ci clear_bit(V4L2_FL_REGISTERED, &dev->meta_cap_dev.flags); 1188c2ecf20Sopenharmony_ci break; 1198c2ecf20Sopenharmony_ci case VIVID_CID_BUTTON: 1208c2ecf20Sopenharmony_ci dev->button_pressed = 30; 1218c2ecf20Sopenharmony_ci break; 1228c2ecf20Sopenharmony_ci } 1238c2ecf20Sopenharmony_ci return 0; 1248c2ecf20Sopenharmony_ci} 1258c2ecf20Sopenharmony_ci 1268c2ecf20Sopenharmony_cistatic const struct v4l2_ctrl_ops vivid_user_gen_ctrl_ops = { 1278c2ecf20Sopenharmony_ci .s_ctrl = vivid_user_gen_s_ctrl, 1288c2ecf20Sopenharmony_ci}; 1298c2ecf20Sopenharmony_ci 1308c2ecf20Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_button = { 1318c2ecf20Sopenharmony_ci .ops = &vivid_user_gen_ctrl_ops, 1328c2ecf20Sopenharmony_ci .id = VIVID_CID_BUTTON, 1338c2ecf20Sopenharmony_ci .name = "Button", 1348c2ecf20Sopenharmony_ci .type = V4L2_CTRL_TYPE_BUTTON, 1358c2ecf20Sopenharmony_ci}; 1368c2ecf20Sopenharmony_ci 1378c2ecf20Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_boolean = { 1388c2ecf20Sopenharmony_ci .ops = &vivid_user_gen_ctrl_ops, 1398c2ecf20Sopenharmony_ci .id = VIVID_CID_BOOLEAN, 1408c2ecf20Sopenharmony_ci .name = "Boolean", 1418c2ecf20Sopenharmony_ci .type = V4L2_CTRL_TYPE_BOOLEAN, 1428c2ecf20Sopenharmony_ci .min = 0, 1438c2ecf20Sopenharmony_ci .max = 1, 1448c2ecf20Sopenharmony_ci .step = 1, 1458c2ecf20Sopenharmony_ci .def = 1, 1468c2ecf20Sopenharmony_ci}; 1478c2ecf20Sopenharmony_ci 1488c2ecf20Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_int32 = { 1498c2ecf20Sopenharmony_ci .ops = &vivid_user_gen_ctrl_ops, 1508c2ecf20Sopenharmony_ci .id = VIVID_CID_INTEGER, 1518c2ecf20Sopenharmony_ci .name = "Integer 32 Bits", 1528c2ecf20Sopenharmony_ci .type = V4L2_CTRL_TYPE_INTEGER, 1538c2ecf20Sopenharmony_ci .min = 0xffffffff80000000ULL, 1548c2ecf20Sopenharmony_ci .max = 0x7fffffff, 1558c2ecf20Sopenharmony_ci .step = 1, 1568c2ecf20Sopenharmony_ci}; 1578c2ecf20Sopenharmony_ci 1588c2ecf20Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_int64 = { 1598c2ecf20Sopenharmony_ci .ops = &vivid_user_gen_ctrl_ops, 1608c2ecf20Sopenharmony_ci .id = VIVID_CID_INTEGER64, 1618c2ecf20Sopenharmony_ci .name = "Integer 64 Bits", 1628c2ecf20Sopenharmony_ci .type = V4L2_CTRL_TYPE_INTEGER64, 1638c2ecf20Sopenharmony_ci .min = 0x8000000000000000ULL, 1648c2ecf20Sopenharmony_ci .max = 0x7fffffffffffffffLL, 1658c2ecf20Sopenharmony_ci .step = 1, 1668c2ecf20Sopenharmony_ci}; 1678c2ecf20Sopenharmony_ci 1688c2ecf20Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_u32_array = { 1698c2ecf20Sopenharmony_ci .ops = &vivid_user_gen_ctrl_ops, 1708c2ecf20Sopenharmony_ci .id = VIVID_CID_U32_ARRAY, 1718c2ecf20Sopenharmony_ci .name = "U32 1 Element Array", 1728c2ecf20Sopenharmony_ci .type = V4L2_CTRL_TYPE_U32, 1738c2ecf20Sopenharmony_ci .def = 0x18, 1748c2ecf20Sopenharmony_ci .min = 0x10, 1758c2ecf20Sopenharmony_ci .max = 0x20000, 1768c2ecf20Sopenharmony_ci .step = 1, 1778c2ecf20Sopenharmony_ci .dims = { 1 }, 1788c2ecf20Sopenharmony_ci}; 1798c2ecf20Sopenharmony_ci 1808c2ecf20Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_u16_matrix = { 1818c2ecf20Sopenharmony_ci .ops = &vivid_user_gen_ctrl_ops, 1828c2ecf20Sopenharmony_ci .id = VIVID_CID_U16_MATRIX, 1838c2ecf20Sopenharmony_ci .name = "U16 8x16 Matrix", 1848c2ecf20Sopenharmony_ci .type = V4L2_CTRL_TYPE_U16, 1858c2ecf20Sopenharmony_ci .def = 0x18, 1868c2ecf20Sopenharmony_ci .min = 0x10, 1878c2ecf20Sopenharmony_ci .max = 0x2000, 1888c2ecf20Sopenharmony_ci .step = 1, 1898c2ecf20Sopenharmony_ci .dims = { 8, 16 }, 1908c2ecf20Sopenharmony_ci}; 1918c2ecf20Sopenharmony_ci 1928c2ecf20Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_u8_4d_array = { 1938c2ecf20Sopenharmony_ci .ops = &vivid_user_gen_ctrl_ops, 1948c2ecf20Sopenharmony_ci .id = VIVID_CID_U8_4D_ARRAY, 1958c2ecf20Sopenharmony_ci .name = "U8 2x3x4x5 Array", 1968c2ecf20Sopenharmony_ci .type = V4L2_CTRL_TYPE_U8, 1978c2ecf20Sopenharmony_ci .def = 0x18, 1988c2ecf20Sopenharmony_ci .min = 0x10, 1998c2ecf20Sopenharmony_ci .max = 0x20, 2008c2ecf20Sopenharmony_ci .step = 1, 2018c2ecf20Sopenharmony_ci .dims = { 2, 3, 4, 5 }, 2028c2ecf20Sopenharmony_ci}; 2038c2ecf20Sopenharmony_ci 2048c2ecf20Sopenharmony_cistatic const char * const vivid_ctrl_menu_strings[] = { 2058c2ecf20Sopenharmony_ci "Menu Item 0 (Skipped)", 2068c2ecf20Sopenharmony_ci "Menu Item 1", 2078c2ecf20Sopenharmony_ci "Menu Item 2 (Skipped)", 2088c2ecf20Sopenharmony_ci "Menu Item 3", 2098c2ecf20Sopenharmony_ci "Menu Item 4", 2108c2ecf20Sopenharmony_ci "Menu Item 5 (Skipped)", 2118c2ecf20Sopenharmony_ci NULL, 2128c2ecf20Sopenharmony_ci}; 2138c2ecf20Sopenharmony_ci 2148c2ecf20Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_menu = { 2158c2ecf20Sopenharmony_ci .ops = &vivid_user_gen_ctrl_ops, 2168c2ecf20Sopenharmony_ci .id = VIVID_CID_MENU, 2178c2ecf20Sopenharmony_ci .name = "Menu", 2188c2ecf20Sopenharmony_ci .type = V4L2_CTRL_TYPE_MENU, 2198c2ecf20Sopenharmony_ci .min = 1, 2208c2ecf20Sopenharmony_ci .max = 4, 2218c2ecf20Sopenharmony_ci .def = 3, 2228c2ecf20Sopenharmony_ci .menu_skip_mask = 0x04, 2238c2ecf20Sopenharmony_ci .qmenu = vivid_ctrl_menu_strings, 2248c2ecf20Sopenharmony_ci}; 2258c2ecf20Sopenharmony_ci 2268c2ecf20Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_string = { 2278c2ecf20Sopenharmony_ci .ops = &vivid_user_gen_ctrl_ops, 2288c2ecf20Sopenharmony_ci .id = VIVID_CID_STRING, 2298c2ecf20Sopenharmony_ci .name = "String", 2308c2ecf20Sopenharmony_ci .type = V4L2_CTRL_TYPE_STRING, 2318c2ecf20Sopenharmony_ci .min = 2, 2328c2ecf20Sopenharmony_ci .max = 4, 2338c2ecf20Sopenharmony_ci .step = 1, 2348c2ecf20Sopenharmony_ci}; 2358c2ecf20Sopenharmony_ci 2368c2ecf20Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_bitmask = { 2378c2ecf20Sopenharmony_ci .ops = &vivid_user_gen_ctrl_ops, 2388c2ecf20Sopenharmony_ci .id = VIVID_CID_BITMASK, 2398c2ecf20Sopenharmony_ci .name = "Bitmask", 2408c2ecf20Sopenharmony_ci .type = V4L2_CTRL_TYPE_BITMASK, 2418c2ecf20Sopenharmony_ci .def = 0x80002000, 2428c2ecf20Sopenharmony_ci .min = 0, 2438c2ecf20Sopenharmony_ci .max = 0x80402010, 2448c2ecf20Sopenharmony_ci .step = 0, 2458c2ecf20Sopenharmony_ci}; 2468c2ecf20Sopenharmony_ci 2478c2ecf20Sopenharmony_cistatic const s64 vivid_ctrl_int_menu_values[] = { 2488c2ecf20Sopenharmony_ci 1, 1, 2, 3, 5, 8, 13, 21, 42, 2498c2ecf20Sopenharmony_ci}; 2508c2ecf20Sopenharmony_ci 2518c2ecf20Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_int_menu = { 2528c2ecf20Sopenharmony_ci .ops = &vivid_user_gen_ctrl_ops, 2538c2ecf20Sopenharmony_ci .id = VIVID_CID_INTMENU, 2548c2ecf20Sopenharmony_ci .name = "Integer Menu", 2558c2ecf20Sopenharmony_ci .type = V4L2_CTRL_TYPE_INTEGER_MENU, 2568c2ecf20Sopenharmony_ci .min = 1, 2578c2ecf20Sopenharmony_ci .max = 8, 2588c2ecf20Sopenharmony_ci .def = 4, 2598c2ecf20Sopenharmony_ci .menu_skip_mask = 0x02, 2608c2ecf20Sopenharmony_ci .qmenu_int = vivid_ctrl_int_menu_values, 2618c2ecf20Sopenharmony_ci}; 2628c2ecf20Sopenharmony_ci 2638c2ecf20Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_disconnect = { 2648c2ecf20Sopenharmony_ci .ops = &vivid_user_gen_ctrl_ops, 2658c2ecf20Sopenharmony_ci .id = VIVID_CID_DISCONNECT, 2668c2ecf20Sopenharmony_ci .name = "Disconnect", 2678c2ecf20Sopenharmony_ci .type = V4L2_CTRL_TYPE_BUTTON, 2688c2ecf20Sopenharmony_ci}; 2698c2ecf20Sopenharmony_ci 2708c2ecf20Sopenharmony_cistatic const struct v4l2_area area = { 2718c2ecf20Sopenharmony_ci .width = 1000, 2728c2ecf20Sopenharmony_ci .height = 2000, 2738c2ecf20Sopenharmony_ci}; 2748c2ecf20Sopenharmony_ci 2758c2ecf20Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_area = { 2768c2ecf20Sopenharmony_ci .ops = &vivid_user_gen_ctrl_ops, 2778c2ecf20Sopenharmony_ci .id = VIVID_CID_AREA, 2788c2ecf20Sopenharmony_ci .name = "Area", 2798c2ecf20Sopenharmony_ci .type = V4L2_CTRL_TYPE_AREA, 2808c2ecf20Sopenharmony_ci .p_def.p_const = &area, 2818c2ecf20Sopenharmony_ci}; 2828c2ecf20Sopenharmony_ci 2838c2ecf20Sopenharmony_ci/* Framebuffer Controls */ 2848c2ecf20Sopenharmony_ci 2858c2ecf20Sopenharmony_cistatic int vivid_fb_s_ctrl(struct v4l2_ctrl *ctrl) 2868c2ecf20Sopenharmony_ci{ 2878c2ecf20Sopenharmony_ci struct vivid_dev *dev = container_of(ctrl->handler, 2888c2ecf20Sopenharmony_ci struct vivid_dev, ctrl_hdl_fb); 2898c2ecf20Sopenharmony_ci 2908c2ecf20Sopenharmony_ci switch (ctrl->id) { 2918c2ecf20Sopenharmony_ci case VIVID_CID_CLEAR_FB: 2928c2ecf20Sopenharmony_ci vivid_clear_fb(dev); 2938c2ecf20Sopenharmony_ci break; 2948c2ecf20Sopenharmony_ci } 2958c2ecf20Sopenharmony_ci return 0; 2968c2ecf20Sopenharmony_ci} 2978c2ecf20Sopenharmony_ci 2988c2ecf20Sopenharmony_cistatic const struct v4l2_ctrl_ops vivid_fb_ctrl_ops = { 2998c2ecf20Sopenharmony_ci .s_ctrl = vivid_fb_s_ctrl, 3008c2ecf20Sopenharmony_ci}; 3018c2ecf20Sopenharmony_ci 3028c2ecf20Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_clear_fb = { 3038c2ecf20Sopenharmony_ci .ops = &vivid_fb_ctrl_ops, 3048c2ecf20Sopenharmony_ci .id = VIVID_CID_CLEAR_FB, 3058c2ecf20Sopenharmony_ci .name = "Clear Framebuffer", 3068c2ecf20Sopenharmony_ci .type = V4L2_CTRL_TYPE_BUTTON, 3078c2ecf20Sopenharmony_ci}; 3088c2ecf20Sopenharmony_ci 3098c2ecf20Sopenharmony_ci 3108c2ecf20Sopenharmony_ci/* Video User Controls */ 3118c2ecf20Sopenharmony_ci 3128c2ecf20Sopenharmony_cistatic int vivid_user_vid_g_volatile_ctrl(struct v4l2_ctrl *ctrl) 3138c2ecf20Sopenharmony_ci{ 3148c2ecf20Sopenharmony_ci struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_user_vid); 3158c2ecf20Sopenharmony_ci 3168c2ecf20Sopenharmony_ci switch (ctrl->id) { 3178c2ecf20Sopenharmony_ci case V4L2_CID_AUTOGAIN: 3188c2ecf20Sopenharmony_ci dev->gain->val = (jiffies_to_msecs(jiffies) / 1000) & 0xff; 3198c2ecf20Sopenharmony_ci break; 3208c2ecf20Sopenharmony_ci } 3218c2ecf20Sopenharmony_ci return 0; 3228c2ecf20Sopenharmony_ci} 3238c2ecf20Sopenharmony_ci 3248c2ecf20Sopenharmony_cistatic int vivid_user_vid_s_ctrl(struct v4l2_ctrl *ctrl) 3258c2ecf20Sopenharmony_ci{ 3268c2ecf20Sopenharmony_ci struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_user_vid); 3278c2ecf20Sopenharmony_ci 3288c2ecf20Sopenharmony_ci switch (ctrl->id) { 3298c2ecf20Sopenharmony_ci case V4L2_CID_BRIGHTNESS: 3308c2ecf20Sopenharmony_ci dev->input_brightness[dev->input] = ctrl->val - dev->input * 128; 3318c2ecf20Sopenharmony_ci tpg_s_brightness(&dev->tpg, dev->input_brightness[dev->input]); 3328c2ecf20Sopenharmony_ci break; 3338c2ecf20Sopenharmony_ci case V4L2_CID_CONTRAST: 3348c2ecf20Sopenharmony_ci tpg_s_contrast(&dev->tpg, ctrl->val); 3358c2ecf20Sopenharmony_ci break; 3368c2ecf20Sopenharmony_ci case V4L2_CID_SATURATION: 3378c2ecf20Sopenharmony_ci tpg_s_saturation(&dev->tpg, ctrl->val); 3388c2ecf20Sopenharmony_ci break; 3398c2ecf20Sopenharmony_ci case V4L2_CID_HUE: 3408c2ecf20Sopenharmony_ci tpg_s_hue(&dev->tpg, ctrl->val); 3418c2ecf20Sopenharmony_ci break; 3428c2ecf20Sopenharmony_ci case V4L2_CID_HFLIP: 3438c2ecf20Sopenharmony_ci dev->hflip = ctrl->val; 3448c2ecf20Sopenharmony_ci tpg_s_hflip(&dev->tpg, dev->sensor_hflip ^ dev->hflip); 3458c2ecf20Sopenharmony_ci break; 3468c2ecf20Sopenharmony_ci case V4L2_CID_VFLIP: 3478c2ecf20Sopenharmony_ci dev->vflip = ctrl->val; 3488c2ecf20Sopenharmony_ci tpg_s_vflip(&dev->tpg, dev->sensor_vflip ^ dev->vflip); 3498c2ecf20Sopenharmony_ci break; 3508c2ecf20Sopenharmony_ci case V4L2_CID_ALPHA_COMPONENT: 3518c2ecf20Sopenharmony_ci tpg_s_alpha_component(&dev->tpg, ctrl->val); 3528c2ecf20Sopenharmony_ci break; 3538c2ecf20Sopenharmony_ci } 3548c2ecf20Sopenharmony_ci return 0; 3558c2ecf20Sopenharmony_ci} 3568c2ecf20Sopenharmony_ci 3578c2ecf20Sopenharmony_cistatic const struct v4l2_ctrl_ops vivid_user_vid_ctrl_ops = { 3588c2ecf20Sopenharmony_ci .g_volatile_ctrl = vivid_user_vid_g_volatile_ctrl, 3598c2ecf20Sopenharmony_ci .s_ctrl = vivid_user_vid_s_ctrl, 3608c2ecf20Sopenharmony_ci}; 3618c2ecf20Sopenharmony_ci 3628c2ecf20Sopenharmony_ci 3638c2ecf20Sopenharmony_ci/* Video Capture Controls */ 3648c2ecf20Sopenharmony_ci 3658c2ecf20Sopenharmony_cistatic int vivid_vid_cap_s_ctrl(struct v4l2_ctrl *ctrl) 3668c2ecf20Sopenharmony_ci{ 3678c2ecf20Sopenharmony_ci static const u32 colorspaces[] = { 3688c2ecf20Sopenharmony_ci V4L2_COLORSPACE_SMPTE170M, 3698c2ecf20Sopenharmony_ci V4L2_COLORSPACE_REC709, 3708c2ecf20Sopenharmony_ci V4L2_COLORSPACE_SRGB, 3718c2ecf20Sopenharmony_ci V4L2_COLORSPACE_OPRGB, 3728c2ecf20Sopenharmony_ci V4L2_COLORSPACE_BT2020, 3738c2ecf20Sopenharmony_ci V4L2_COLORSPACE_DCI_P3, 3748c2ecf20Sopenharmony_ci V4L2_COLORSPACE_SMPTE240M, 3758c2ecf20Sopenharmony_ci V4L2_COLORSPACE_470_SYSTEM_M, 3768c2ecf20Sopenharmony_ci V4L2_COLORSPACE_470_SYSTEM_BG, 3778c2ecf20Sopenharmony_ci }; 3788c2ecf20Sopenharmony_ci struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_vid_cap); 3798c2ecf20Sopenharmony_ci unsigned int i, j; 3808c2ecf20Sopenharmony_ci 3818c2ecf20Sopenharmony_ci switch (ctrl->id) { 3828c2ecf20Sopenharmony_ci case VIVID_CID_TEST_PATTERN: 3838c2ecf20Sopenharmony_ci vivid_update_quality(dev); 3848c2ecf20Sopenharmony_ci tpg_s_pattern(&dev->tpg, ctrl->val); 3858c2ecf20Sopenharmony_ci break; 3868c2ecf20Sopenharmony_ci case VIVID_CID_COLORSPACE: 3878c2ecf20Sopenharmony_ci tpg_s_colorspace(&dev->tpg, colorspaces[ctrl->val]); 3888c2ecf20Sopenharmony_ci vivid_send_source_change(dev, TV); 3898c2ecf20Sopenharmony_ci vivid_send_source_change(dev, SVID); 3908c2ecf20Sopenharmony_ci vivid_send_source_change(dev, HDMI); 3918c2ecf20Sopenharmony_ci vivid_send_source_change(dev, WEBCAM); 3928c2ecf20Sopenharmony_ci break; 3938c2ecf20Sopenharmony_ci case VIVID_CID_XFER_FUNC: 3948c2ecf20Sopenharmony_ci tpg_s_xfer_func(&dev->tpg, ctrl->val); 3958c2ecf20Sopenharmony_ci vivid_send_source_change(dev, TV); 3968c2ecf20Sopenharmony_ci vivid_send_source_change(dev, SVID); 3978c2ecf20Sopenharmony_ci vivid_send_source_change(dev, HDMI); 3988c2ecf20Sopenharmony_ci vivid_send_source_change(dev, WEBCAM); 3998c2ecf20Sopenharmony_ci break; 4008c2ecf20Sopenharmony_ci case VIVID_CID_YCBCR_ENC: 4018c2ecf20Sopenharmony_ci tpg_s_ycbcr_enc(&dev->tpg, ctrl->val); 4028c2ecf20Sopenharmony_ci vivid_send_source_change(dev, TV); 4038c2ecf20Sopenharmony_ci vivid_send_source_change(dev, SVID); 4048c2ecf20Sopenharmony_ci vivid_send_source_change(dev, HDMI); 4058c2ecf20Sopenharmony_ci vivid_send_source_change(dev, WEBCAM); 4068c2ecf20Sopenharmony_ci break; 4078c2ecf20Sopenharmony_ci case VIVID_CID_HSV_ENC: 4088c2ecf20Sopenharmony_ci tpg_s_hsv_enc(&dev->tpg, ctrl->val ? V4L2_HSV_ENC_256 : 4098c2ecf20Sopenharmony_ci V4L2_HSV_ENC_180); 4108c2ecf20Sopenharmony_ci vivid_send_source_change(dev, TV); 4118c2ecf20Sopenharmony_ci vivid_send_source_change(dev, SVID); 4128c2ecf20Sopenharmony_ci vivid_send_source_change(dev, HDMI); 4138c2ecf20Sopenharmony_ci vivid_send_source_change(dev, WEBCAM); 4148c2ecf20Sopenharmony_ci break; 4158c2ecf20Sopenharmony_ci case VIVID_CID_QUANTIZATION: 4168c2ecf20Sopenharmony_ci tpg_s_quantization(&dev->tpg, ctrl->val); 4178c2ecf20Sopenharmony_ci vivid_send_source_change(dev, TV); 4188c2ecf20Sopenharmony_ci vivid_send_source_change(dev, SVID); 4198c2ecf20Sopenharmony_ci vivid_send_source_change(dev, HDMI); 4208c2ecf20Sopenharmony_ci vivid_send_source_change(dev, WEBCAM); 4218c2ecf20Sopenharmony_ci break; 4228c2ecf20Sopenharmony_ci case V4L2_CID_DV_RX_RGB_RANGE: 4238c2ecf20Sopenharmony_ci if (!vivid_is_hdmi_cap(dev)) 4248c2ecf20Sopenharmony_ci break; 4258c2ecf20Sopenharmony_ci tpg_s_rgb_range(&dev->tpg, ctrl->val); 4268c2ecf20Sopenharmony_ci break; 4278c2ecf20Sopenharmony_ci case VIVID_CID_LIMITED_RGB_RANGE: 4288c2ecf20Sopenharmony_ci tpg_s_real_rgb_range(&dev->tpg, ctrl->val ? 4298c2ecf20Sopenharmony_ci V4L2_DV_RGB_RANGE_LIMITED : V4L2_DV_RGB_RANGE_FULL); 4308c2ecf20Sopenharmony_ci break; 4318c2ecf20Sopenharmony_ci case VIVID_CID_ALPHA_MODE: 4328c2ecf20Sopenharmony_ci tpg_s_alpha_mode(&dev->tpg, ctrl->val); 4338c2ecf20Sopenharmony_ci break; 4348c2ecf20Sopenharmony_ci case VIVID_CID_HOR_MOVEMENT: 4358c2ecf20Sopenharmony_ci tpg_s_mv_hor_mode(&dev->tpg, ctrl->val); 4368c2ecf20Sopenharmony_ci break; 4378c2ecf20Sopenharmony_ci case VIVID_CID_VERT_MOVEMENT: 4388c2ecf20Sopenharmony_ci tpg_s_mv_vert_mode(&dev->tpg, ctrl->val); 4398c2ecf20Sopenharmony_ci break; 4408c2ecf20Sopenharmony_ci case VIVID_CID_OSD_TEXT_MODE: 4418c2ecf20Sopenharmony_ci dev->osd_mode = ctrl->val; 4428c2ecf20Sopenharmony_ci break; 4438c2ecf20Sopenharmony_ci case VIVID_CID_PERCENTAGE_FILL: 4448c2ecf20Sopenharmony_ci tpg_s_perc_fill(&dev->tpg, ctrl->val); 4458c2ecf20Sopenharmony_ci for (i = 0; i < VIDEO_MAX_FRAME; i++) 4468c2ecf20Sopenharmony_ci dev->must_blank[i] = ctrl->val < 100; 4478c2ecf20Sopenharmony_ci break; 4488c2ecf20Sopenharmony_ci case VIVID_CID_INSERT_SAV: 4498c2ecf20Sopenharmony_ci tpg_s_insert_sav(&dev->tpg, ctrl->val); 4508c2ecf20Sopenharmony_ci break; 4518c2ecf20Sopenharmony_ci case VIVID_CID_INSERT_EAV: 4528c2ecf20Sopenharmony_ci tpg_s_insert_eav(&dev->tpg, ctrl->val); 4538c2ecf20Sopenharmony_ci break; 4548c2ecf20Sopenharmony_ci case VIVID_CID_HFLIP: 4558c2ecf20Sopenharmony_ci dev->sensor_hflip = ctrl->val; 4568c2ecf20Sopenharmony_ci tpg_s_hflip(&dev->tpg, dev->sensor_hflip ^ dev->hflip); 4578c2ecf20Sopenharmony_ci break; 4588c2ecf20Sopenharmony_ci case VIVID_CID_VFLIP: 4598c2ecf20Sopenharmony_ci dev->sensor_vflip = ctrl->val; 4608c2ecf20Sopenharmony_ci tpg_s_vflip(&dev->tpg, dev->sensor_vflip ^ dev->vflip); 4618c2ecf20Sopenharmony_ci break; 4628c2ecf20Sopenharmony_ci case VIVID_CID_REDUCED_FPS: 4638c2ecf20Sopenharmony_ci dev->reduced_fps = ctrl->val; 4648c2ecf20Sopenharmony_ci vivid_update_format_cap(dev, true); 4658c2ecf20Sopenharmony_ci break; 4668c2ecf20Sopenharmony_ci case VIVID_CID_HAS_CROP_CAP: 4678c2ecf20Sopenharmony_ci dev->has_crop_cap = ctrl->val; 4688c2ecf20Sopenharmony_ci vivid_update_format_cap(dev, true); 4698c2ecf20Sopenharmony_ci break; 4708c2ecf20Sopenharmony_ci case VIVID_CID_HAS_COMPOSE_CAP: 4718c2ecf20Sopenharmony_ci dev->has_compose_cap = ctrl->val; 4728c2ecf20Sopenharmony_ci vivid_update_format_cap(dev, true); 4738c2ecf20Sopenharmony_ci break; 4748c2ecf20Sopenharmony_ci case VIVID_CID_HAS_SCALER_CAP: 4758c2ecf20Sopenharmony_ci dev->has_scaler_cap = ctrl->val; 4768c2ecf20Sopenharmony_ci vivid_update_format_cap(dev, true); 4778c2ecf20Sopenharmony_ci break; 4788c2ecf20Sopenharmony_ci case VIVID_CID_SHOW_BORDER: 4798c2ecf20Sopenharmony_ci tpg_s_show_border(&dev->tpg, ctrl->val); 4808c2ecf20Sopenharmony_ci break; 4818c2ecf20Sopenharmony_ci case VIVID_CID_SHOW_SQUARE: 4828c2ecf20Sopenharmony_ci tpg_s_show_square(&dev->tpg, ctrl->val); 4838c2ecf20Sopenharmony_ci break; 4848c2ecf20Sopenharmony_ci case VIVID_CID_STD_ASPECT_RATIO: 4858c2ecf20Sopenharmony_ci dev->std_aspect_ratio[dev->input] = ctrl->val; 4868c2ecf20Sopenharmony_ci tpg_s_video_aspect(&dev->tpg, vivid_get_video_aspect(dev)); 4878c2ecf20Sopenharmony_ci break; 4888c2ecf20Sopenharmony_ci case VIVID_CID_DV_TIMINGS_SIGNAL_MODE: 4898c2ecf20Sopenharmony_ci dev->dv_timings_signal_mode[dev->input] = 4908c2ecf20Sopenharmony_ci dev->ctrl_dv_timings_signal_mode->val; 4918c2ecf20Sopenharmony_ci dev->query_dv_timings[dev->input] = dev->ctrl_dv_timings->val; 4928c2ecf20Sopenharmony_ci 4938c2ecf20Sopenharmony_ci dev->power_present = 0; 4948c2ecf20Sopenharmony_ci for (i = 0, j = 0; 4958c2ecf20Sopenharmony_ci i < ARRAY_SIZE(dev->dv_timings_signal_mode); 4968c2ecf20Sopenharmony_ci i++) 4978c2ecf20Sopenharmony_ci if (dev->input_type[i] == HDMI) { 4988c2ecf20Sopenharmony_ci if (dev->dv_timings_signal_mode[i] != NO_SIGNAL) 4998c2ecf20Sopenharmony_ci dev->power_present |= (1 << j); 5008c2ecf20Sopenharmony_ci j++; 5018c2ecf20Sopenharmony_ci } 5028c2ecf20Sopenharmony_ci __v4l2_ctrl_s_ctrl(dev->ctrl_rx_power_present, 5038c2ecf20Sopenharmony_ci dev->power_present); 5048c2ecf20Sopenharmony_ci 5058c2ecf20Sopenharmony_ci v4l2_ctrl_activate(dev->ctrl_dv_timings, 5068c2ecf20Sopenharmony_ci dev->dv_timings_signal_mode[dev->input] == 5078c2ecf20Sopenharmony_ci SELECTED_DV_TIMINGS); 5088c2ecf20Sopenharmony_ci 5098c2ecf20Sopenharmony_ci vivid_update_quality(dev); 5108c2ecf20Sopenharmony_ci vivid_send_source_change(dev, HDMI); 5118c2ecf20Sopenharmony_ci break; 5128c2ecf20Sopenharmony_ci case VIVID_CID_DV_TIMINGS_ASPECT_RATIO: 5138c2ecf20Sopenharmony_ci dev->dv_timings_aspect_ratio[dev->input] = ctrl->val; 5148c2ecf20Sopenharmony_ci tpg_s_video_aspect(&dev->tpg, vivid_get_video_aspect(dev)); 5158c2ecf20Sopenharmony_ci break; 5168c2ecf20Sopenharmony_ci case VIVID_CID_TSTAMP_SRC: 5178c2ecf20Sopenharmony_ci dev->tstamp_src_is_soe = ctrl->val; 5188c2ecf20Sopenharmony_ci dev->vb_vid_cap_q.timestamp_flags &= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK; 5198c2ecf20Sopenharmony_ci if (dev->tstamp_src_is_soe) 5208c2ecf20Sopenharmony_ci dev->vb_vid_cap_q.timestamp_flags |= V4L2_BUF_FLAG_TSTAMP_SRC_SOE; 5218c2ecf20Sopenharmony_ci break; 5228c2ecf20Sopenharmony_ci case VIVID_CID_MAX_EDID_BLOCKS: 5238c2ecf20Sopenharmony_ci dev->edid_max_blocks = ctrl->val; 5248c2ecf20Sopenharmony_ci if (dev->edid_blocks > dev->edid_max_blocks) 5258c2ecf20Sopenharmony_ci dev->edid_blocks = dev->edid_max_blocks; 5268c2ecf20Sopenharmony_ci break; 5278c2ecf20Sopenharmony_ci } 5288c2ecf20Sopenharmony_ci return 0; 5298c2ecf20Sopenharmony_ci} 5308c2ecf20Sopenharmony_ci 5318c2ecf20Sopenharmony_cistatic const struct v4l2_ctrl_ops vivid_vid_cap_ctrl_ops = { 5328c2ecf20Sopenharmony_ci .s_ctrl = vivid_vid_cap_s_ctrl, 5338c2ecf20Sopenharmony_ci}; 5348c2ecf20Sopenharmony_ci 5358c2ecf20Sopenharmony_cistatic const char * const vivid_ctrl_hor_movement_strings[] = { 5368c2ecf20Sopenharmony_ci "Move Left Fast", 5378c2ecf20Sopenharmony_ci "Move Left", 5388c2ecf20Sopenharmony_ci "Move Left Slow", 5398c2ecf20Sopenharmony_ci "No Movement", 5408c2ecf20Sopenharmony_ci "Move Right Slow", 5418c2ecf20Sopenharmony_ci "Move Right", 5428c2ecf20Sopenharmony_ci "Move Right Fast", 5438c2ecf20Sopenharmony_ci NULL, 5448c2ecf20Sopenharmony_ci}; 5458c2ecf20Sopenharmony_ci 5468c2ecf20Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_hor_movement = { 5478c2ecf20Sopenharmony_ci .ops = &vivid_vid_cap_ctrl_ops, 5488c2ecf20Sopenharmony_ci .id = VIVID_CID_HOR_MOVEMENT, 5498c2ecf20Sopenharmony_ci .name = "Horizontal Movement", 5508c2ecf20Sopenharmony_ci .type = V4L2_CTRL_TYPE_MENU, 5518c2ecf20Sopenharmony_ci .max = TPG_MOVE_POS_FAST, 5528c2ecf20Sopenharmony_ci .def = TPG_MOVE_NONE, 5538c2ecf20Sopenharmony_ci .qmenu = vivid_ctrl_hor_movement_strings, 5548c2ecf20Sopenharmony_ci}; 5558c2ecf20Sopenharmony_ci 5568c2ecf20Sopenharmony_cistatic const char * const vivid_ctrl_vert_movement_strings[] = { 5578c2ecf20Sopenharmony_ci "Move Up Fast", 5588c2ecf20Sopenharmony_ci "Move Up", 5598c2ecf20Sopenharmony_ci "Move Up Slow", 5608c2ecf20Sopenharmony_ci "No Movement", 5618c2ecf20Sopenharmony_ci "Move Down Slow", 5628c2ecf20Sopenharmony_ci "Move Down", 5638c2ecf20Sopenharmony_ci "Move Down Fast", 5648c2ecf20Sopenharmony_ci NULL, 5658c2ecf20Sopenharmony_ci}; 5668c2ecf20Sopenharmony_ci 5678c2ecf20Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_vert_movement = { 5688c2ecf20Sopenharmony_ci .ops = &vivid_vid_cap_ctrl_ops, 5698c2ecf20Sopenharmony_ci .id = VIVID_CID_VERT_MOVEMENT, 5708c2ecf20Sopenharmony_ci .name = "Vertical Movement", 5718c2ecf20Sopenharmony_ci .type = V4L2_CTRL_TYPE_MENU, 5728c2ecf20Sopenharmony_ci .max = TPG_MOVE_POS_FAST, 5738c2ecf20Sopenharmony_ci .def = TPG_MOVE_NONE, 5748c2ecf20Sopenharmony_ci .qmenu = vivid_ctrl_vert_movement_strings, 5758c2ecf20Sopenharmony_ci}; 5768c2ecf20Sopenharmony_ci 5778c2ecf20Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_show_border = { 5788c2ecf20Sopenharmony_ci .ops = &vivid_vid_cap_ctrl_ops, 5798c2ecf20Sopenharmony_ci .id = VIVID_CID_SHOW_BORDER, 5808c2ecf20Sopenharmony_ci .name = "Show Border", 5818c2ecf20Sopenharmony_ci .type = V4L2_CTRL_TYPE_BOOLEAN, 5828c2ecf20Sopenharmony_ci .max = 1, 5838c2ecf20Sopenharmony_ci .step = 1, 5848c2ecf20Sopenharmony_ci}; 5858c2ecf20Sopenharmony_ci 5868c2ecf20Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_show_square = { 5878c2ecf20Sopenharmony_ci .ops = &vivid_vid_cap_ctrl_ops, 5888c2ecf20Sopenharmony_ci .id = VIVID_CID_SHOW_SQUARE, 5898c2ecf20Sopenharmony_ci .name = "Show Square", 5908c2ecf20Sopenharmony_ci .type = V4L2_CTRL_TYPE_BOOLEAN, 5918c2ecf20Sopenharmony_ci .max = 1, 5928c2ecf20Sopenharmony_ci .step = 1, 5938c2ecf20Sopenharmony_ci}; 5948c2ecf20Sopenharmony_ci 5958c2ecf20Sopenharmony_cistatic const char * const vivid_ctrl_osd_mode_strings[] = { 5968c2ecf20Sopenharmony_ci "All", 5978c2ecf20Sopenharmony_ci "Counters Only", 5988c2ecf20Sopenharmony_ci "None", 5998c2ecf20Sopenharmony_ci NULL, 6008c2ecf20Sopenharmony_ci}; 6018c2ecf20Sopenharmony_ci 6028c2ecf20Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_osd_mode = { 6038c2ecf20Sopenharmony_ci .ops = &vivid_vid_cap_ctrl_ops, 6048c2ecf20Sopenharmony_ci .id = VIVID_CID_OSD_TEXT_MODE, 6058c2ecf20Sopenharmony_ci .name = "OSD Text Mode", 6068c2ecf20Sopenharmony_ci .type = V4L2_CTRL_TYPE_MENU, 6078c2ecf20Sopenharmony_ci .max = ARRAY_SIZE(vivid_ctrl_osd_mode_strings) - 2, 6088c2ecf20Sopenharmony_ci .qmenu = vivid_ctrl_osd_mode_strings, 6098c2ecf20Sopenharmony_ci}; 6108c2ecf20Sopenharmony_ci 6118c2ecf20Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_perc_fill = { 6128c2ecf20Sopenharmony_ci .ops = &vivid_vid_cap_ctrl_ops, 6138c2ecf20Sopenharmony_ci .id = VIVID_CID_PERCENTAGE_FILL, 6148c2ecf20Sopenharmony_ci .name = "Fill Percentage of Frame", 6158c2ecf20Sopenharmony_ci .type = V4L2_CTRL_TYPE_INTEGER, 6168c2ecf20Sopenharmony_ci .min = 0, 6178c2ecf20Sopenharmony_ci .max = 100, 6188c2ecf20Sopenharmony_ci .def = 100, 6198c2ecf20Sopenharmony_ci .step = 1, 6208c2ecf20Sopenharmony_ci}; 6218c2ecf20Sopenharmony_ci 6228c2ecf20Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_insert_sav = { 6238c2ecf20Sopenharmony_ci .ops = &vivid_vid_cap_ctrl_ops, 6248c2ecf20Sopenharmony_ci .id = VIVID_CID_INSERT_SAV, 6258c2ecf20Sopenharmony_ci .name = "Insert SAV Code in Image", 6268c2ecf20Sopenharmony_ci .type = V4L2_CTRL_TYPE_BOOLEAN, 6278c2ecf20Sopenharmony_ci .max = 1, 6288c2ecf20Sopenharmony_ci .step = 1, 6298c2ecf20Sopenharmony_ci}; 6308c2ecf20Sopenharmony_ci 6318c2ecf20Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_insert_eav = { 6328c2ecf20Sopenharmony_ci .ops = &vivid_vid_cap_ctrl_ops, 6338c2ecf20Sopenharmony_ci .id = VIVID_CID_INSERT_EAV, 6348c2ecf20Sopenharmony_ci .name = "Insert EAV Code in Image", 6358c2ecf20Sopenharmony_ci .type = V4L2_CTRL_TYPE_BOOLEAN, 6368c2ecf20Sopenharmony_ci .max = 1, 6378c2ecf20Sopenharmony_ci .step = 1, 6388c2ecf20Sopenharmony_ci}; 6398c2ecf20Sopenharmony_ci 6408c2ecf20Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_hflip = { 6418c2ecf20Sopenharmony_ci .ops = &vivid_vid_cap_ctrl_ops, 6428c2ecf20Sopenharmony_ci .id = VIVID_CID_HFLIP, 6438c2ecf20Sopenharmony_ci .name = "Sensor Flipped Horizontally", 6448c2ecf20Sopenharmony_ci .type = V4L2_CTRL_TYPE_BOOLEAN, 6458c2ecf20Sopenharmony_ci .max = 1, 6468c2ecf20Sopenharmony_ci .step = 1, 6478c2ecf20Sopenharmony_ci}; 6488c2ecf20Sopenharmony_ci 6498c2ecf20Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_vflip = { 6508c2ecf20Sopenharmony_ci .ops = &vivid_vid_cap_ctrl_ops, 6518c2ecf20Sopenharmony_ci .id = VIVID_CID_VFLIP, 6528c2ecf20Sopenharmony_ci .name = "Sensor Flipped Vertically", 6538c2ecf20Sopenharmony_ci .type = V4L2_CTRL_TYPE_BOOLEAN, 6548c2ecf20Sopenharmony_ci .max = 1, 6558c2ecf20Sopenharmony_ci .step = 1, 6568c2ecf20Sopenharmony_ci}; 6578c2ecf20Sopenharmony_ci 6588c2ecf20Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_reduced_fps = { 6598c2ecf20Sopenharmony_ci .ops = &vivid_vid_cap_ctrl_ops, 6608c2ecf20Sopenharmony_ci .id = VIVID_CID_REDUCED_FPS, 6618c2ecf20Sopenharmony_ci .name = "Reduced Framerate", 6628c2ecf20Sopenharmony_ci .type = V4L2_CTRL_TYPE_BOOLEAN, 6638c2ecf20Sopenharmony_ci .max = 1, 6648c2ecf20Sopenharmony_ci .step = 1, 6658c2ecf20Sopenharmony_ci}; 6668c2ecf20Sopenharmony_ci 6678c2ecf20Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_has_crop_cap = { 6688c2ecf20Sopenharmony_ci .ops = &vivid_vid_cap_ctrl_ops, 6698c2ecf20Sopenharmony_ci .id = VIVID_CID_HAS_CROP_CAP, 6708c2ecf20Sopenharmony_ci .name = "Enable Capture Cropping", 6718c2ecf20Sopenharmony_ci .type = V4L2_CTRL_TYPE_BOOLEAN, 6728c2ecf20Sopenharmony_ci .max = 1, 6738c2ecf20Sopenharmony_ci .def = 1, 6748c2ecf20Sopenharmony_ci .step = 1, 6758c2ecf20Sopenharmony_ci}; 6768c2ecf20Sopenharmony_ci 6778c2ecf20Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_has_compose_cap = { 6788c2ecf20Sopenharmony_ci .ops = &vivid_vid_cap_ctrl_ops, 6798c2ecf20Sopenharmony_ci .id = VIVID_CID_HAS_COMPOSE_CAP, 6808c2ecf20Sopenharmony_ci .name = "Enable Capture Composing", 6818c2ecf20Sopenharmony_ci .type = V4L2_CTRL_TYPE_BOOLEAN, 6828c2ecf20Sopenharmony_ci .max = 1, 6838c2ecf20Sopenharmony_ci .def = 1, 6848c2ecf20Sopenharmony_ci .step = 1, 6858c2ecf20Sopenharmony_ci}; 6868c2ecf20Sopenharmony_ci 6878c2ecf20Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_has_scaler_cap = { 6888c2ecf20Sopenharmony_ci .ops = &vivid_vid_cap_ctrl_ops, 6898c2ecf20Sopenharmony_ci .id = VIVID_CID_HAS_SCALER_CAP, 6908c2ecf20Sopenharmony_ci .name = "Enable Capture Scaler", 6918c2ecf20Sopenharmony_ci .type = V4L2_CTRL_TYPE_BOOLEAN, 6928c2ecf20Sopenharmony_ci .max = 1, 6938c2ecf20Sopenharmony_ci .def = 1, 6948c2ecf20Sopenharmony_ci .step = 1, 6958c2ecf20Sopenharmony_ci}; 6968c2ecf20Sopenharmony_ci 6978c2ecf20Sopenharmony_cistatic const char * const vivid_ctrl_tstamp_src_strings[] = { 6988c2ecf20Sopenharmony_ci "End of Frame", 6998c2ecf20Sopenharmony_ci "Start of Exposure", 7008c2ecf20Sopenharmony_ci NULL, 7018c2ecf20Sopenharmony_ci}; 7028c2ecf20Sopenharmony_ci 7038c2ecf20Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_tstamp_src = { 7048c2ecf20Sopenharmony_ci .ops = &vivid_vid_cap_ctrl_ops, 7058c2ecf20Sopenharmony_ci .id = VIVID_CID_TSTAMP_SRC, 7068c2ecf20Sopenharmony_ci .name = "Timestamp Source", 7078c2ecf20Sopenharmony_ci .type = V4L2_CTRL_TYPE_MENU, 7088c2ecf20Sopenharmony_ci .max = ARRAY_SIZE(vivid_ctrl_tstamp_src_strings) - 2, 7098c2ecf20Sopenharmony_ci .qmenu = vivid_ctrl_tstamp_src_strings, 7108c2ecf20Sopenharmony_ci}; 7118c2ecf20Sopenharmony_ci 7128c2ecf20Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_std_aspect_ratio = { 7138c2ecf20Sopenharmony_ci .ops = &vivid_vid_cap_ctrl_ops, 7148c2ecf20Sopenharmony_ci .id = VIVID_CID_STD_ASPECT_RATIO, 7158c2ecf20Sopenharmony_ci .name = "Standard Aspect Ratio", 7168c2ecf20Sopenharmony_ci .type = V4L2_CTRL_TYPE_MENU, 7178c2ecf20Sopenharmony_ci .min = 1, 7188c2ecf20Sopenharmony_ci .max = 4, 7198c2ecf20Sopenharmony_ci .def = 1, 7208c2ecf20Sopenharmony_ci .qmenu = tpg_aspect_strings, 7218c2ecf20Sopenharmony_ci}; 7228c2ecf20Sopenharmony_ci 7238c2ecf20Sopenharmony_cistatic const char * const vivid_ctrl_dv_timings_signal_mode_strings[] = { 7248c2ecf20Sopenharmony_ci "Current DV Timings", 7258c2ecf20Sopenharmony_ci "No Signal", 7268c2ecf20Sopenharmony_ci "No Lock", 7278c2ecf20Sopenharmony_ci "Out of Range", 7288c2ecf20Sopenharmony_ci "Selected DV Timings", 7298c2ecf20Sopenharmony_ci "Cycle Through All DV Timings", 7308c2ecf20Sopenharmony_ci "Custom DV Timings", 7318c2ecf20Sopenharmony_ci NULL, 7328c2ecf20Sopenharmony_ci}; 7338c2ecf20Sopenharmony_ci 7348c2ecf20Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_dv_timings_signal_mode = { 7358c2ecf20Sopenharmony_ci .ops = &vivid_vid_cap_ctrl_ops, 7368c2ecf20Sopenharmony_ci .id = VIVID_CID_DV_TIMINGS_SIGNAL_MODE, 7378c2ecf20Sopenharmony_ci .name = "DV Timings Signal Mode", 7388c2ecf20Sopenharmony_ci .type = V4L2_CTRL_TYPE_MENU, 7398c2ecf20Sopenharmony_ci .max = 5, 7408c2ecf20Sopenharmony_ci .qmenu = vivid_ctrl_dv_timings_signal_mode_strings, 7418c2ecf20Sopenharmony_ci}; 7428c2ecf20Sopenharmony_ci 7438c2ecf20Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_dv_timings_aspect_ratio = { 7448c2ecf20Sopenharmony_ci .ops = &vivid_vid_cap_ctrl_ops, 7458c2ecf20Sopenharmony_ci .id = VIVID_CID_DV_TIMINGS_ASPECT_RATIO, 7468c2ecf20Sopenharmony_ci .name = "DV Timings Aspect Ratio", 7478c2ecf20Sopenharmony_ci .type = V4L2_CTRL_TYPE_MENU, 7488c2ecf20Sopenharmony_ci .max = 3, 7498c2ecf20Sopenharmony_ci .qmenu = tpg_aspect_strings, 7508c2ecf20Sopenharmony_ci}; 7518c2ecf20Sopenharmony_ci 7528c2ecf20Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_max_edid_blocks = { 7538c2ecf20Sopenharmony_ci .ops = &vivid_vid_cap_ctrl_ops, 7548c2ecf20Sopenharmony_ci .id = VIVID_CID_MAX_EDID_BLOCKS, 7558c2ecf20Sopenharmony_ci .name = "Maximum EDID Blocks", 7568c2ecf20Sopenharmony_ci .type = V4L2_CTRL_TYPE_INTEGER, 7578c2ecf20Sopenharmony_ci .min = 1, 7588c2ecf20Sopenharmony_ci .max = 256, 7598c2ecf20Sopenharmony_ci .def = 2, 7608c2ecf20Sopenharmony_ci .step = 1, 7618c2ecf20Sopenharmony_ci}; 7628c2ecf20Sopenharmony_ci 7638c2ecf20Sopenharmony_cistatic const char * const vivid_ctrl_colorspace_strings[] = { 7648c2ecf20Sopenharmony_ci "SMPTE 170M", 7658c2ecf20Sopenharmony_ci "Rec. 709", 7668c2ecf20Sopenharmony_ci "sRGB", 7678c2ecf20Sopenharmony_ci "opRGB", 7688c2ecf20Sopenharmony_ci "BT.2020", 7698c2ecf20Sopenharmony_ci "DCI-P3", 7708c2ecf20Sopenharmony_ci "SMPTE 240M", 7718c2ecf20Sopenharmony_ci "470 System M", 7728c2ecf20Sopenharmony_ci "470 System BG", 7738c2ecf20Sopenharmony_ci NULL, 7748c2ecf20Sopenharmony_ci}; 7758c2ecf20Sopenharmony_ci 7768c2ecf20Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_colorspace = { 7778c2ecf20Sopenharmony_ci .ops = &vivid_vid_cap_ctrl_ops, 7788c2ecf20Sopenharmony_ci .id = VIVID_CID_COLORSPACE, 7798c2ecf20Sopenharmony_ci .name = "Colorspace", 7808c2ecf20Sopenharmony_ci .type = V4L2_CTRL_TYPE_MENU, 7818c2ecf20Sopenharmony_ci .max = ARRAY_SIZE(vivid_ctrl_colorspace_strings) - 2, 7828c2ecf20Sopenharmony_ci .def = 2, 7838c2ecf20Sopenharmony_ci .qmenu = vivid_ctrl_colorspace_strings, 7848c2ecf20Sopenharmony_ci}; 7858c2ecf20Sopenharmony_ci 7868c2ecf20Sopenharmony_cistatic const char * const vivid_ctrl_xfer_func_strings[] = { 7878c2ecf20Sopenharmony_ci "Default", 7888c2ecf20Sopenharmony_ci "Rec. 709", 7898c2ecf20Sopenharmony_ci "sRGB", 7908c2ecf20Sopenharmony_ci "opRGB", 7918c2ecf20Sopenharmony_ci "SMPTE 240M", 7928c2ecf20Sopenharmony_ci "None", 7938c2ecf20Sopenharmony_ci "DCI-P3", 7948c2ecf20Sopenharmony_ci "SMPTE 2084", 7958c2ecf20Sopenharmony_ci NULL, 7968c2ecf20Sopenharmony_ci}; 7978c2ecf20Sopenharmony_ci 7988c2ecf20Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_xfer_func = { 7998c2ecf20Sopenharmony_ci .ops = &vivid_vid_cap_ctrl_ops, 8008c2ecf20Sopenharmony_ci .id = VIVID_CID_XFER_FUNC, 8018c2ecf20Sopenharmony_ci .name = "Transfer Function", 8028c2ecf20Sopenharmony_ci .type = V4L2_CTRL_TYPE_MENU, 8038c2ecf20Sopenharmony_ci .max = ARRAY_SIZE(vivid_ctrl_xfer_func_strings) - 2, 8048c2ecf20Sopenharmony_ci .qmenu = vivid_ctrl_xfer_func_strings, 8058c2ecf20Sopenharmony_ci}; 8068c2ecf20Sopenharmony_ci 8078c2ecf20Sopenharmony_cistatic const char * const vivid_ctrl_ycbcr_enc_strings[] = { 8088c2ecf20Sopenharmony_ci "Default", 8098c2ecf20Sopenharmony_ci "ITU-R 601", 8108c2ecf20Sopenharmony_ci "Rec. 709", 8118c2ecf20Sopenharmony_ci "xvYCC 601", 8128c2ecf20Sopenharmony_ci "xvYCC 709", 8138c2ecf20Sopenharmony_ci "", 8148c2ecf20Sopenharmony_ci "BT.2020", 8158c2ecf20Sopenharmony_ci "BT.2020 Constant Luminance", 8168c2ecf20Sopenharmony_ci "SMPTE 240M", 8178c2ecf20Sopenharmony_ci NULL, 8188c2ecf20Sopenharmony_ci}; 8198c2ecf20Sopenharmony_ci 8208c2ecf20Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_ycbcr_enc = { 8218c2ecf20Sopenharmony_ci .ops = &vivid_vid_cap_ctrl_ops, 8228c2ecf20Sopenharmony_ci .id = VIVID_CID_YCBCR_ENC, 8238c2ecf20Sopenharmony_ci .name = "Y'CbCr Encoding", 8248c2ecf20Sopenharmony_ci .type = V4L2_CTRL_TYPE_MENU, 8258c2ecf20Sopenharmony_ci .menu_skip_mask = 1 << 5, 8268c2ecf20Sopenharmony_ci .max = ARRAY_SIZE(vivid_ctrl_ycbcr_enc_strings) - 2, 8278c2ecf20Sopenharmony_ci .qmenu = vivid_ctrl_ycbcr_enc_strings, 8288c2ecf20Sopenharmony_ci}; 8298c2ecf20Sopenharmony_ci 8308c2ecf20Sopenharmony_cistatic const char * const vivid_ctrl_hsv_enc_strings[] = { 8318c2ecf20Sopenharmony_ci "Hue 0-179", 8328c2ecf20Sopenharmony_ci "Hue 0-256", 8338c2ecf20Sopenharmony_ci NULL, 8348c2ecf20Sopenharmony_ci}; 8358c2ecf20Sopenharmony_ci 8368c2ecf20Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_hsv_enc = { 8378c2ecf20Sopenharmony_ci .ops = &vivid_vid_cap_ctrl_ops, 8388c2ecf20Sopenharmony_ci .id = VIVID_CID_HSV_ENC, 8398c2ecf20Sopenharmony_ci .name = "HSV Encoding", 8408c2ecf20Sopenharmony_ci .type = V4L2_CTRL_TYPE_MENU, 8418c2ecf20Sopenharmony_ci .max = ARRAY_SIZE(vivid_ctrl_hsv_enc_strings) - 2, 8428c2ecf20Sopenharmony_ci .qmenu = vivid_ctrl_hsv_enc_strings, 8438c2ecf20Sopenharmony_ci}; 8448c2ecf20Sopenharmony_ci 8458c2ecf20Sopenharmony_cistatic const char * const vivid_ctrl_quantization_strings[] = { 8468c2ecf20Sopenharmony_ci "Default", 8478c2ecf20Sopenharmony_ci "Full Range", 8488c2ecf20Sopenharmony_ci "Limited Range", 8498c2ecf20Sopenharmony_ci NULL, 8508c2ecf20Sopenharmony_ci}; 8518c2ecf20Sopenharmony_ci 8528c2ecf20Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_quantization = { 8538c2ecf20Sopenharmony_ci .ops = &vivid_vid_cap_ctrl_ops, 8548c2ecf20Sopenharmony_ci .id = VIVID_CID_QUANTIZATION, 8558c2ecf20Sopenharmony_ci .name = "Quantization", 8568c2ecf20Sopenharmony_ci .type = V4L2_CTRL_TYPE_MENU, 8578c2ecf20Sopenharmony_ci .max = ARRAY_SIZE(vivid_ctrl_quantization_strings) - 2, 8588c2ecf20Sopenharmony_ci .qmenu = vivid_ctrl_quantization_strings, 8598c2ecf20Sopenharmony_ci}; 8608c2ecf20Sopenharmony_ci 8618c2ecf20Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_alpha_mode = { 8628c2ecf20Sopenharmony_ci .ops = &vivid_vid_cap_ctrl_ops, 8638c2ecf20Sopenharmony_ci .id = VIVID_CID_ALPHA_MODE, 8648c2ecf20Sopenharmony_ci .name = "Apply Alpha To Red Only", 8658c2ecf20Sopenharmony_ci .type = V4L2_CTRL_TYPE_BOOLEAN, 8668c2ecf20Sopenharmony_ci .max = 1, 8678c2ecf20Sopenharmony_ci .step = 1, 8688c2ecf20Sopenharmony_ci}; 8698c2ecf20Sopenharmony_ci 8708c2ecf20Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_limited_rgb_range = { 8718c2ecf20Sopenharmony_ci .ops = &vivid_vid_cap_ctrl_ops, 8728c2ecf20Sopenharmony_ci .id = VIVID_CID_LIMITED_RGB_RANGE, 8738c2ecf20Sopenharmony_ci .name = "Limited RGB Range (16-235)", 8748c2ecf20Sopenharmony_ci .type = V4L2_CTRL_TYPE_BOOLEAN, 8758c2ecf20Sopenharmony_ci .max = 1, 8768c2ecf20Sopenharmony_ci .step = 1, 8778c2ecf20Sopenharmony_ci}; 8788c2ecf20Sopenharmony_ci 8798c2ecf20Sopenharmony_ci 8808c2ecf20Sopenharmony_ci/* Video Loop Control */ 8818c2ecf20Sopenharmony_ci 8828c2ecf20Sopenharmony_cistatic int vivid_loop_cap_s_ctrl(struct v4l2_ctrl *ctrl) 8838c2ecf20Sopenharmony_ci{ 8848c2ecf20Sopenharmony_ci struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_loop_cap); 8858c2ecf20Sopenharmony_ci 8868c2ecf20Sopenharmony_ci switch (ctrl->id) { 8878c2ecf20Sopenharmony_ci case VIVID_CID_LOOP_VIDEO: 8888c2ecf20Sopenharmony_ci dev->loop_video = ctrl->val; 8898c2ecf20Sopenharmony_ci vivid_update_quality(dev); 8908c2ecf20Sopenharmony_ci vivid_send_source_change(dev, SVID); 8918c2ecf20Sopenharmony_ci vivid_send_source_change(dev, HDMI); 8928c2ecf20Sopenharmony_ci break; 8938c2ecf20Sopenharmony_ci } 8948c2ecf20Sopenharmony_ci return 0; 8958c2ecf20Sopenharmony_ci} 8968c2ecf20Sopenharmony_ci 8978c2ecf20Sopenharmony_cistatic const struct v4l2_ctrl_ops vivid_loop_cap_ctrl_ops = { 8988c2ecf20Sopenharmony_ci .s_ctrl = vivid_loop_cap_s_ctrl, 8998c2ecf20Sopenharmony_ci}; 9008c2ecf20Sopenharmony_ci 9018c2ecf20Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_loop_video = { 9028c2ecf20Sopenharmony_ci .ops = &vivid_loop_cap_ctrl_ops, 9038c2ecf20Sopenharmony_ci .id = VIVID_CID_LOOP_VIDEO, 9048c2ecf20Sopenharmony_ci .name = "Loop Video", 9058c2ecf20Sopenharmony_ci .type = V4L2_CTRL_TYPE_BOOLEAN, 9068c2ecf20Sopenharmony_ci .max = 1, 9078c2ecf20Sopenharmony_ci .step = 1, 9088c2ecf20Sopenharmony_ci}; 9098c2ecf20Sopenharmony_ci 9108c2ecf20Sopenharmony_ci 9118c2ecf20Sopenharmony_ci/* VBI Capture Control */ 9128c2ecf20Sopenharmony_ci 9138c2ecf20Sopenharmony_cistatic int vivid_vbi_cap_s_ctrl(struct v4l2_ctrl *ctrl) 9148c2ecf20Sopenharmony_ci{ 9158c2ecf20Sopenharmony_ci struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_vbi_cap); 9168c2ecf20Sopenharmony_ci 9178c2ecf20Sopenharmony_ci switch (ctrl->id) { 9188c2ecf20Sopenharmony_ci case VIVID_CID_VBI_CAP_INTERLACED: 9198c2ecf20Sopenharmony_ci dev->vbi_cap_interlaced = ctrl->val; 9208c2ecf20Sopenharmony_ci break; 9218c2ecf20Sopenharmony_ci } 9228c2ecf20Sopenharmony_ci return 0; 9238c2ecf20Sopenharmony_ci} 9248c2ecf20Sopenharmony_ci 9258c2ecf20Sopenharmony_cistatic const struct v4l2_ctrl_ops vivid_vbi_cap_ctrl_ops = { 9268c2ecf20Sopenharmony_ci .s_ctrl = vivid_vbi_cap_s_ctrl, 9278c2ecf20Sopenharmony_ci}; 9288c2ecf20Sopenharmony_ci 9298c2ecf20Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_vbi_cap_interlaced = { 9308c2ecf20Sopenharmony_ci .ops = &vivid_vbi_cap_ctrl_ops, 9318c2ecf20Sopenharmony_ci .id = VIVID_CID_VBI_CAP_INTERLACED, 9328c2ecf20Sopenharmony_ci .name = "Interlaced VBI Format", 9338c2ecf20Sopenharmony_ci .type = V4L2_CTRL_TYPE_BOOLEAN, 9348c2ecf20Sopenharmony_ci .max = 1, 9358c2ecf20Sopenharmony_ci .step = 1, 9368c2ecf20Sopenharmony_ci}; 9378c2ecf20Sopenharmony_ci 9388c2ecf20Sopenharmony_ci 9398c2ecf20Sopenharmony_ci/* Video Output Controls */ 9408c2ecf20Sopenharmony_ci 9418c2ecf20Sopenharmony_cistatic int vivid_vid_out_s_ctrl(struct v4l2_ctrl *ctrl) 9428c2ecf20Sopenharmony_ci{ 9438c2ecf20Sopenharmony_ci struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_vid_out); 9448c2ecf20Sopenharmony_ci struct v4l2_bt_timings *bt = &dev->dv_timings_out.bt; 9458c2ecf20Sopenharmony_ci u32 display_present = 0; 9468c2ecf20Sopenharmony_ci unsigned int i, j, bus_idx; 9478c2ecf20Sopenharmony_ci 9488c2ecf20Sopenharmony_ci switch (ctrl->id) { 9498c2ecf20Sopenharmony_ci case VIVID_CID_HAS_CROP_OUT: 9508c2ecf20Sopenharmony_ci dev->has_crop_out = ctrl->val; 9518c2ecf20Sopenharmony_ci vivid_update_format_out(dev); 9528c2ecf20Sopenharmony_ci break; 9538c2ecf20Sopenharmony_ci case VIVID_CID_HAS_COMPOSE_OUT: 9548c2ecf20Sopenharmony_ci dev->has_compose_out = ctrl->val; 9558c2ecf20Sopenharmony_ci vivid_update_format_out(dev); 9568c2ecf20Sopenharmony_ci break; 9578c2ecf20Sopenharmony_ci case VIVID_CID_HAS_SCALER_OUT: 9588c2ecf20Sopenharmony_ci dev->has_scaler_out = ctrl->val; 9598c2ecf20Sopenharmony_ci vivid_update_format_out(dev); 9608c2ecf20Sopenharmony_ci break; 9618c2ecf20Sopenharmony_ci case V4L2_CID_DV_TX_MODE: 9628c2ecf20Sopenharmony_ci dev->dvi_d_out = ctrl->val == V4L2_DV_TX_MODE_DVI_D; 9638c2ecf20Sopenharmony_ci if (!vivid_is_hdmi_out(dev)) 9648c2ecf20Sopenharmony_ci break; 9658c2ecf20Sopenharmony_ci if (!dev->dvi_d_out && (bt->flags & V4L2_DV_FL_IS_CE_VIDEO)) { 9668c2ecf20Sopenharmony_ci if (bt->width == 720 && bt->height <= 576) 9678c2ecf20Sopenharmony_ci dev->colorspace_out = V4L2_COLORSPACE_SMPTE170M; 9688c2ecf20Sopenharmony_ci else 9698c2ecf20Sopenharmony_ci dev->colorspace_out = V4L2_COLORSPACE_REC709; 9708c2ecf20Sopenharmony_ci dev->quantization_out = V4L2_QUANTIZATION_DEFAULT; 9718c2ecf20Sopenharmony_ci } else { 9728c2ecf20Sopenharmony_ci dev->colorspace_out = V4L2_COLORSPACE_SRGB; 9738c2ecf20Sopenharmony_ci dev->quantization_out = dev->dvi_d_out ? 9748c2ecf20Sopenharmony_ci V4L2_QUANTIZATION_LIM_RANGE : 9758c2ecf20Sopenharmony_ci V4L2_QUANTIZATION_DEFAULT; 9768c2ecf20Sopenharmony_ci } 9778c2ecf20Sopenharmony_ci if (dev->loop_video) 9788c2ecf20Sopenharmony_ci vivid_send_source_change(dev, HDMI); 9798c2ecf20Sopenharmony_ci break; 9808c2ecf20Sopenharmony_ci case VIVID_CID_DISPLAY_PRESENT: 9818c2ecf20Sopenharmony_ci if (dev->output_type[dev->output] != HDMI) 9828c2ecf20Sopenharmony_ci break; 9838c2ecf20Sopenharmony_ci 9848c2ecf20Sopenharmony_ci dev->display_present[dev->output] = ctrl->val; 9858c2ecf20Sopenharmony_ci for (i = 0, j = 0; i < dev->num_outputs; i++) 9868c2ecf20Sopenharmony_ci if (dev->output_type[i] == HDMI) 9878c2ecf20Sopenharmony_ci display_present |= 9888c2ecf20Sopenharmony_ci dev->display_present[i] << j++; 9898c2ecf20Sopenharmony_ci 9908c2ecf20Sopenharmony_ci __v4l2_ctrl_s_ctrl(dev->ctrl_tx_rxsense, display_present); 9918c2ecf20Sopenharmony_ci 9928c2ecf20Sopenharmony_ci if (dev->edid_blocks) { 9938c2ecf20Sopenharmony_ci __v4l2_ctrl_s_ctrl(dev->ctrl_tx_edid_present, 9948c2ecf20Sopenharmony_ci display_present); 9958c2ecf20Sopenharmony_ci __v4l2_ctrl_s_ctrl(dev->ctrl_tx_hotplug, 9968c2ecf20Sopenharmony_ci display_present); 9978c2ecf20Sopenharmony_ci } 9988c2ecf20Sopenharmony_ci 9998c2ecf20Sopenharmony_ci bus_idx = dev->cec_output2bus_map[dev->output]; 10008c2ecf20Sopenharmony_ci if (!dev->cec_tx_adap[bus_idx]) 10018c2ecf20Sopenharmony_ci break; 10028c2ecf20Sopenharmony_ci 10038c2ecf20Sopenharmony_ci if (ctrl->val && dev->edid_blocks) 10048c2ecf20Sopenharmony_ci cec_s_phys_addr(dev->cec_tx_adap[bus_idx], 10058c2ecf20Sopenharmony_ci dev->cec_tx_adap[bus_idx]->phys_addr, 10068c2ecf20Sopenharmony_ci false); 10078c2ecf20Sopenharmony_ci else 10088c2ecf20Sopenharmony_ci cec_phys_addr_invalidate(dev->cec_tx_adap[bus_idx]); 10098c2ecf20Sopenharmony_ci 10108c2ecf20Sopenharmony_ci break; 10118c2ecf20Sopenharmony_ci } 10128c2ecf20Sopenharmony_ci return 0; 10138c2ecf20Sopenharmony_ci} 10148c2ecf20Sopenharmony_ci 10158c2ecf20Sopenharmony_cistatic const struct v4l2_ctrl_ops vivid_vid_out_ctrl_ops = { 10168c2ecf20Sopenharmony_ci .s_ctrl = vivid_vid_out_s_ctrl, 10178c2ecf20Sopenharmony_ci}; 10188c2ecf20Sopenharmony_ci 10198c2ecf20Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_has_crop_out = { 10208c2ecf20Sopenharmony_ci .ops = &vivid_vid_out_ctrl_ops, 10218c2ecf20Sopenharmony_ci .id = VIVID_CID_HAS_CROP_OUT, 10228c2ecf20Sopenharmony_ci .name = "Enable Output Cropping", 10238c2ecf20Sopenharmony_ci .type = V4L2_CTRL_TYPE_BOOLEAN, 10248c2ecf20Sopenharmony_ci .max = 1, 10258c2ecf20Sopenharmony_ci .def = 1, 10268c2ecf20Sopenharmony_ci .step = 1, 10278c2ecf20Sopenharmony_ci}; 10288c2ecf20Sopenharmony_ci 10298c2ecf20Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_has_compose_out = { 10308c2ecf20Sopenharmony_ci .ops = &vivid_vid_out_ctrl_ops, 10318c2ecf20Sopenharmony_ci .id = VIVID_CID_HAS_COMPOSE_OUT, 10328c2ecf20Sopenharmony_ci .name = "Enable Output Composing", 10338c2ecf20Sopenharmony_ci .type = V4L2_CTRL_TYPE_BOOLEAN, 10348c2ecf20Sopenharmony_ci .max = 1, 10358c2ecf20Sopenharmony_ci .def = 1, 10368c2ecf20Sopenharmony_ci .step = 1, 10378c2ecf20Sopenharmony_ci}; 10388c2ecf20Sopenharmony_ci 10398c2ecf20Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_has_scaler_out = { 10408c2ecf20Sopenharmony_ci .ops = &vivid_vid_out_ctrl_ops, 10418c2ecf20Sopenharmony_ci .id = VIVID_CID_HAS_SCALER_OUT, 10428c2ecf20Sopenharmony_ci .name = "Enable Output Scaler", 10438c2ecf20Sopenharmony_ci .type = V4L2_CTRL_TYPE_BOOLEAN, 10448c2ecf20Sopenharmony_ci .max = 1, 10458c2ecf20Sopenharmony_ci .def = 1, 10468c2ecf20Sopenharmony_ci .step = 1, 10478c2ecf20Sopenharmony_ci}; 10488c2ecf20Sopenharmony_ci 10498c2ecf20Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_display_present = { 10508c2ecf20Sopenharmony_ci .ops = &vivid_vid_out_ctrl_ops, 10518c2ecf20Sopenharmony_ci .id = VIVID_CID_DISPLAY_PRESENT, 10528c2ecf20Sopenharmony_ci .name = "Display Present", 10538c2ecf20Sopenharmony_ci .type = V4L2_CTRL_TYPE_BOOLEAN, 10548c2ecf20Sopenharmony_ci .max = 1, 10558c2ecf20Sopenharmony_ci .def = 1, 10568c2ecf20Sopenharmony_ci .step = 1, 10578c2ecf20Sopenharmony_ci}; 10588c2ecf20Sopenharmony_ci 10598c2ecf20Sopenharmony_ci/* Streaming Controls */ 10608c2ecf20Sopenharmony_ci 10618c2ecf20Sopenharmony_cistatic int vivid_streaming_s_ctrl(struct v4l2_ctrl *ctrl) 10628c2ecf20Sopenharmony_ci{ 10638c2ecf20Sopenharmony_ci struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_streaming); 10648c2ecf20Sopenharmony_ci u64 rem; 10658c2ecf20Sopenharmony_ci 10668c2ecf20Sopenharmony_ci switch (ctrl->id) { 10678c2ecf20Sopenharmony_ci case VIVID_CID_DQBUF_ERROR: 10688c2ecf20Sopenharmony_ci dev->dqbuf_error = true; 10698c2ecf20Sopenharmony_ci break; 10708c2ecf20Sopenharmony_ci case VIVID_CID_PERC_DROPPED: 10718c2ecf20Sopenharmony_ci dev->perc_dropped_buffers = ctrl->val; 10728c2ecf20Sopenharmony_ci break; 10738c2ecf20Sopenharmony_ci case VIVID_CID_QUEUE_SETUP_ERROR: 10748c2ecf20Sopenharmony_ci dev->queue_setup_error = true; 10758c2ecf20Sopenharmony_ci break; 10768c2ecf20Sopenharmony_ci case VIVID_CID_BUF_PREPARE_ERROR: 10778c2ecf20Sopenharmony_ci dev->buf_prepare_error = true; 10788c2ecf20Sopenharmony_ci break; 10798c2ecf20Sopenharmony_ci case VIVID_CID_START_STR_ERROR: 10808c2ecf20Sopenharmony_ci dev->start_streaming_error = true; 10818c2ecf20Sopenharmony_ci break; 10828c2ecf20Sopenharmony_ci case VIVID_CID_REQ_VALIDATE_ERROR: 10838c2ecf20Sopenharmony_ci dev->req_validate_error = true; 10848c2ecf20Sopenharmony_ci break; 10858c2ecf20Sopenharmony_ci case VIVID_CID_QUEUE_ERROR: 10868c2ecf20Sopenharmony_ci if (vb2_start_streaming_called(&dev->vb_vid_cap_q)) 10878c2ecf20Sopenharmony_ci vb2_queue_error(&dev->vb_vid_cap_q); 10888c2ecf20Sopenharmony_ci if (vb2_start_streaming_called(&dev->vb_vbi_cap_q)) 10898c2ecf20Sopenharmony_ci vb2_queue_error(&dev->vb_vbi_cap_q); 10908c2ecf20Sopenharmony_ci if (vb2_start_streaming_called(&dev->vb_vid_out_q)) 10918c2ecf20Sopenharmony_ci vb2_queue_error(&dev->vb_vid_out_q); 10928c2ecf20Sopenharmony_ci if (vb2_start_streaming_called(&dev->vb_vbi_out_q)) 10938c2ecf20Sopenharmony_ci vb2_queue_error(&dev->vb_vbi_out_q); 10948c2ecf20Sopenharmony_ci if (vb2_start_streaming_called(&dev->vb_sdr_cap_q)) 10958c2ecf20Sopenharmony_ci vb2_queue_error(&dev->vb_sdr_cap_q); 10968c2ecf20Sopenharmony_ci break; 10978c2ecf20Sopenharmony_ci case VIVID_CID_SEQ_WRAP: 10988c2ecf20Sopenharmony_ci dev->seq_wrap = ctrl->val; 10998c2ecf20Sopenharmony_ci break; 11008c2ecf20Sopenharmony_ci case VIVID_CID_TIME_WRAP: 11018c2ecf20Sopenharmony_ci dev->time_wrap = ctrl->val; 11028c2ecf20Sopenharmony_ci if (ctrl->val == 0) { 11038c2ecf20Sopenharmony_ci dev->time_wrap_offset = 0; 11048c2ecf20Sopenharmony_ci break; 11058c2ecf20Sopenharmony_ci } 11068c2ecf20Sopenharmony_ci /* 11078c2ecf20Sopenharmony_ci * We want to set the time 16 seconds before the 32 bit tv_sec 11088c2ecf20Sopenharmony_ci * value of struct timeval would wrap around. So first we 11098c2ecf20Sopenharmony_ci * calculate ktime_get_ns() % ((1 << 32) * NSEC_PER_SEC), and 11108c2ecf20Sopenharmony_ci * then we set the offset to ((1 << 32) - 16) * NSEC_PER_SEC). 11118c2ecf20Sopenharmony_ci */ 11128c2ecf20Sopenharmony_ci div64_u64_rem(ktime_get_ns(), 11138c2ecf20Sopenharmony_ci 0x100000000ULL * NSEC_PER_SEC, &rem); 11148c2ecf20Sopenharmony_ci dev->time_wrap_offset = 11158c2ecf20Sopenharmony_ci (0x100000000ULL - 16) * NSEC_PER_SEC - rem; 11168c2ecf20Sopenharmony_ci break; 11178c2ecf20Sopenharmony_ci } 11188c2ecf20Sopenharmony_ci return 0; 11198c2ecf20Sopenharmony_ci} 11208c2ecf20Sopenharmony_ci 11218c2ecf20Sopenharmony_cistatic const struct v4l2_ctrl_ops vivid_streaming_ctrl_ops = { 11228c2ecf20Sopenharmony_ci .s_ctrl = vivid_streaming_s_ctrl, 11238c2ecf20Sopenharmony_ci}; 11248c2ecf20Sopenharmony_ci 11258c2ecf20Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_dqbuf_error = { 11268c2ecf20Sopenharmony_ci .ops = &vivid_streaming_ctrl_ops, 11278c2ecf20Sopenharmony_ci .id = VIVID_CID_DQBUF_ERROR, 11288c2ecf20Sopenharmony_ci .name = "Inject V4L2_BUF_FLAG_ERROR", 11298c2ecf20Sopenharmony_ci .type = V4L2_CTRL_TYPE_BUTTON, 11308c2ecf20Sopenharmony_ci}; 11318c2ecf20Sopenharmony_ci 11328c2ecf20Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_perc_dropped = { 11338c2ecf20Sopenharmony_ci .ops = &vivid_streaming_ctrl_ops, 11348c2ecf20Sopenharmony_ci .id = VIVID_CID_PERC_DROPPED, 11358c2ecf20Sopenharmony_ci .name = "Percentage of Dropped Buffers", 11368c2ecf20Sopenharmony_ci .type = V4L2_CTRL_TYPE_INTEGER, 11378c2ecf20Sopenharmony_ci .min = 0, 11388c2ecf20Sopenharmony_ci .max = 100, 11398c2ecf20Sopenharmony_ci .step = 1, 11408c2ecf20Sopenharmony_ci}; 11418c2ecf20Sopenharmony_ci 11428c2ecf20Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_queue_setup_error = { 11438c2ecf20Sopenharmony_ci .ops = &vivid_streaming_ctrl_ops, 11448c2ecf20Sopenharmony_ci .id = VIVID_CID_QUEUE_SETUP_ERROR, 11458c2ecf20Sopenharmony_ci .name = "Inject VIDIOC_REQBUFS Error", 11468c2ecf20Sopenharmony_ci .type = V4L2_CTRL_TYPE_BUTTON, 11478c2ecf20Sopenharmony_ci}; 11488c2ecf20Sopenharmony_ci 11498c2ecf20Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_buf_prepare_error = { 11508c2ecf20Sopenharmony_ci .ops = &vivid_streaming_ctrl_ops, 11518c2ecf20Sopenharmony_ci .id = VIVID_CID_BUF_PREPARE_ERROR, 11528c2ecf20Sopenharmony_ci .name = "Inject VIDIOC_QBUF Error", 11538c2ecf20Sopenharmony_ci .type = V4L2_CTRL_TYPE_BUTTON, 11548c2ecf20Sopenharmony_ci}; 11558c2ecf20Sopenharmony_ci 11568c2ecf20Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_start_streaming_error = { 11578c2ecf20Sopenharmony_ci .ops = &vivid_streaming_ctrl_ops, 11588c2ecf20Sopenharmony_ci .id = VIVID_CID_START_STR_ERROR, 11598c2ecf20Sopenharmony_ci .name = "Inject VIDIOC_STREAMON Error", 11608c2ecf20Sopenharmony_ci .type = V4L2_CTRL_TYPE_BUTTON, 11618c2ecf20Sopenharmony_ci}; 11628c2ecf20Sopenharmony_ci 11638c2ecf20Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_queue_error = { 11648c2ecf20Sopenharmony_ci .ops = &vivid_streaming_ctrl_ops, 11658c2ecf20Sopenharmony_ci .id = VIVID_CID_QUEUE_ERROR, 11668c2ecf20Sopenharmony_ci .name = "Inject Fatal Streaming Error", 11678c2ecf20Sopenharmony_ci .type = V4L2_CTRL_TYPE_BUTTON, 11688c2ecf20Sopenharmony_ci}; 11698c2ecf20Sopenharmony_ci 11708c2ecf20Sopenharmony_ci#ifdef CONFIG_MEDIA_CONTROLLER 11718c2ecf20Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_req_validate_error = { 11728c2ecf20Sopenharmony_ci .ops = &vivid_streaming_ctrl_ops, 11738c2ecf20Sopenharmony_ci .id = VIVID_CID_REQ_VALIDATE_ERROR, 11748c2ecf20Sopenharmony_ci .name = "Inject req_validate() Error", 11758c2ecf20Sopenharmony_ci .type = V4L2_CTRL_TYPE_BUTTON, 11768c2ecf20Sopenharmony_ci}; 11778c2ecf20Sopenharmony_ci#endif 11788c2ecf20Sopenharmony_ci 11798c2ecf20Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_seq_wrap = { 11808c2ecf20Sopenharmony_ci .ops = &vivid_streaming_ctrl_ops, 11818c2ecf20Sopenharmony_ci .id = VIVID_CID_SEQ_WRAP, 11828c2ecf20Sopenharmony_ci .name = "Wrap Sequence Number", 11838c2ecf20Sopenharmony_ci .type = V4L2_CTRL_TYPE_BOOLEAN, 11848c2ecf20Sopenharmony_ci .max = 1, 11858c2ecf20Sopenharmony_ci .step = 1, 11868c2ecf20Sopenharmony_ci}; 11878c2ecf20Sopenharmony_ci 11888c2ecf20Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_time_wrap = { 11898c2ecf20Sopenharmony_ci .ops = &vivid_streaming_ctrl_ops, 11908c2ecf20Sopenharmony_ci .id = VIVID_CID_TIME_WRAP, 11918c2ecf20Sopenharmony_ci .name = "Wrap Timestamp", 11928c2ecf20Sopenharmony_ci .type = V4L2_CTRL_TYPE_BOOLEAN, 11938c2ecf20Sopenharmony_ci .max = 1, 11948c2ecf20Sopenharmony_ci .step = 1, 11958c2ecf20Sopenharmony_ci}; 11968c2ecf20Sopenharmony_ci 11978c2ecf20Sopenharmony_ci 11988c2ecf20Sopenharmony_ci/* SDTV Capture Controls */ 11998c2ecf20Sopenharmony_ci 12008c2ecf20Sopenharmony_cistatic int vivid_sdtv_cap_s_ctrl(struct v4l2_ctrl *ctrl) 12018c2ecf20Sopenharmony_ci{ 12028c2ecf20Sopenharmony_ci struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_sdtv_cap); 12038c2ecf20Sopenharmony_ci 12048c2ecf20Sopenharmony_ci switch (ctrl->id) { 12058c2ecf20Sopenharmony_ci case VIVID_CID_STD_SIGNAL_MODE: 12068c2ecf20Sopenharmony_ci dev->std_signal_mode[dev->input] = 12078c2ecf20Sopenharmony_ci dev->ctrl_std_signal_mode->val; 12088c2ecf20Sopenharmony_ci if (dev->std_signal_mode[dev->input] == SELECTED_STD) 12098c2ecf20Sopenharmony_ci dev->query_std[dev->input] = 12108c2ecf20Sopenharmony_ci vivid_standard[dev->ctrl_standard->val]; 12118c2ecf20Sopenharmony_ci v4l2_ctrl_activate(dev->ctrl_standard, 12128c2ecf20Sopenharmony_ci dev->std_signal_mode[dev->input] == 12138c2ecf20Sopenharmony_ci SELECTED_STD); 12148c2ecf20Sopenharmony_ci vivid_update_quality(dev); 12158c2ecf20Sopenharmony_ci vivid_send_source_change(dev, TV); 12168c2ecf20Sopenharmony_ci vivid_send_source_change(dev, SVID); 12178c2ecf20Sopenharmony_ci break; 12188c2ecf20Sopenharmony_ci } 12198c2ecf20Sopenharmony_ci return 0; 12208c2ecf20Sopenharmony_ci} 12218c2ecf20Sopenharmony_ci 12228c2ecf20Sopenharmony_cistatic const struct v4l2_ctrl_ops vivid_sdtv_cap_ctrl_ops = { 12238c2ecf20Sopenharmony_ci .s_ctrl = vivid_sdtv_cap_s_ctrl, 12248c2ecf20Sopenharmony_ci}; 12258c2ecf20Sopenharmony_ci 12268c2ecf20Sopenharmony_cistatic const char * const vivid_ctrl_std_signal_mode_strings[] = { 12278c2ecf20Sopenharmony_ci "Current Standard", 12288c2ecf20Sopenharmony_ci "No Signal", 12298c2ecf20Sopenharmony_ci "No Lock", 12308c2ecf20Sopenharmony_ci "", 12318c2ecf20Sopenharmony_ci "Selected Standard", 12328c2ecf20Sopenharmony_ci "Cycle Through All Standards", 12338c2ecf20Sopenharmony_ci NULL, 12348c2ecf20Sopenharmony_ci}; 12358c2ecf20Sopenharmony_ci 12368c2ecf20Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_std_signal_mode = { 12378c2ecf20Sopenharmony_ci .ops = &vivid_sdtv_cap_ctrl_ops, 12388c2ecf20Sopenharmony_ci .id = VIVID_CID_STD_SIGNAL_MODE, 12398c2ecf20Sopenharmony_ci .name = "Standard Signal Mode", 12408c2ecf20Sopenharmony_ci .type = V4L2_CTRL_TYPE_MENU, 12418c2ecf20Sopenharmony_ci .max = ARRAY_SIZE(vivid_ctrl_std_signal_mode_strings) - 2, 12428c2ecf20Sopenharmony_ci .menu_skip_mask = 1 << 3, 12438c2ecf20Sopenharmony_ci .qmenu = vivid_ctrl_std_signal_mode_strings, 12448c2ecf20Sopenharmony_ci}; 12458c2ecf20Sopenharmony_ci 12468c2ecf20Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_standard = { 12478c2ecf20Sopenharmony_ci .ops = &vivid_sdtv_cap_ctrl_ops, 12488c2ecf20Sopenharmony_ci .id = VIVID_CID_STANDARD, 12498c2ecf20Sopenharmony_ci .name = "Standard", 12508c2ecf20Sopenharmony_ci .type = V4L2_CTRL_TYPE_MENU, 12518c2ecf20Sopenharmony_ci .max = 14, 12528c2ecf20Sopenharmony_ci .qmenu = vivid_ctrl_standard_strings, 12538c2ecf20Sopenharmony_ci}; 12548c2ecf20Sopenharmony_ci 12558c2ecf20Sopenharmony_ci 12568c2ecf20Sopenharmony_ci 12578c2ecf20Sopenharmony_ci/* Radio Receiver Controls */ 12588c2ecf20Sopenharmony_ci 12598c2ecf20Sopenharmony_cistatic int vivid_radio_rx_s_ctrl(struct v4l2_ctrl *ctrl) 12608c2ecf20Sopenharmony_ci{ 12618c2ecf20Sopenharmony_ci struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_radio_rx); 12628c2ecf20Sopenharmony_ci 12638c2ecf20Sopenharmony_ci switch (ctrl->id) { 12648c2ecf20Sopenharmony_ci case VIVID_CID_RADIO_SEEK_MODE: 12658c2ecf20Sopenharmony_ci dev->radio_rx_hw_seek_mode = ctrl->val; 12668c2ecf20Sopenharmony_ci break; 12678c2ecf20Sopenharmony_ci case VIVID_CID_RADIO_SEEK_PROG_LIM: 12688c2ecf20Sopenharmony_ci dev->radio_rx_hw_seek_prog_lim = ctrl->val; 12698c2ecf20Sopenharmony_ci break; 12708c2ecf20Sopenharmony_ci case VIVID_CID_RADIO_RX_RDS_RBDS: 12718c2ecf20Sopenharmony_ci dev->rds_gen.use_rbds = ctrl->val; 12728c2ecf20Sopenharmony_ci break; 12738c2ecf20Sopenharmony_ci case VIVID_CID_RADIO_RX_RDS_BLOCKIO: 12748c2ecf20Sopenharmony_ci dev->radio_rx_rds_controls = ctrl->val; 12758c2ecf20Sopenharmony_ci dev->radio_rx_caps &= ~V4L2_CAP_READWRITE; 12768c2ecf20Sopenharmony_ci dev->radio_rx_rds_use_alternates = false; 12778c2ecf20Sopenharmony_ci if (!dev->radio_rx_rds_controls) { 12788c2ecf20Sopenharmony_ci dev->radio_rx_caps |= V4L2_CAP_READWRITE; 12798c2ecf20Sopenharmony_ci __v4l2_ctrl_s_ctrl(dev->radio_rx_rds_pty, 0); 12808c2ecf20Sopenharmony_ci __v4l2_ctrl_s_ctrl(dev->radio_rx_rds_ta, 0); 12818c2ecf20Sopenharmony_ci __v4l2_ctrl_s_ctrl(dev->radio_rx_rds_tp, 0); 12828c2ecf20Sopenharmony_ci __v4l2_ctrl_s_ctrl(dev->radio_rx_rds_ms, 0); 12838c2ecf20Sopenharmony_ci __v4l2_ctrl_s_ctrl_string(dev->radio_rx_rds_psname, ""); 12848c2ecf20Sopenharmony_ci __v4l2_ctrl_s_ctrl_string(dev->radio_rx_rds_radiotext, ""); 12858c2ecf20Sopenharmony_ci } 12868c2ecf20Sopenharmony_ci v4l2_ctrl_activate(dev->radio_rx_rds_pty, dev->radio_rx_rds_controls); 12878c2ecf20Sopenharmony_ci v4l2_ctrl_activate(dev->radio_rx_rds_psname, dev->radio_rx_rds_controls); 12888c2ecf20Sopenharmony_ci v4l2_ctrl_activate(dev->radio_rx_rds_radiotext, dev->radio_rx_rds_controls); 12898c2ecf20Sopenharmony_ci v4l2_ctrl_activate(dev->radio_rx_rds_ta, dev->radio_rx_rds_controls); 12908c2ecf20Sopenharmony_ci v4l2_ctrl_activate(dev->radio_rx_rds_tp, dev->radio_rx_rds_controls); 12918c2ecf20Sopenharmony_ci v4l2_ctrl_activate(dev->radio_rx_rds_ms, dev->radio_rx_rds_controls); 12928c2ecf20Sopenharmony_ci dev->radio_rx_dev.device_caps = dev->radio_rx_caps; 12938c2ecf20Sopenharmony_ci break; 12948c2ecf20Sopenharmony_ci case V4L2_CID_RDS_RECEPTION: 12958c2ecf20Sopenharmony_ci dev->radio_rx_rds_enabled = ctrl->val; 12968c2ecf20Sopenharmony_ci break; 12978c2ecf20Sopenharmony_ci } 12988c2ecf20Sopenharmony_ci return 0; 12998c2ecf20Sopenharmony_ci} 13008c2ecf20Sopenharmony_ci 13018c2ecf20Sopenharmony_cistatic const struct v4l2_ctrl_ops vivid_radio_rx_ctrl_ops = { 13028c2ecf20Sopenharmony_ci .s_ctrl = vivid_radio_rx_s_ctrl, 13038c2ecf20Sopenharmony_ci}; 13048c2ecf20Sopenharmony_ci 13058c2ecf20Sopenharmony_cistatic const char * const vivid_ctrl_radio_rds_mode_strings[] = { 13068c2ecf20Sopenharmony_ci "Block I/O", 13078c2ecf20Sopenharmony_ci "Controls", 13088c2ecf20Sopenharmony_ci NULL, 13098c2ecf20Sopenharmony_ci}; 13108c2ecf20Sopenharmony_ci 13118c2ecf20Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_radio_rx_rds_blockio = { 13128c2ecf20Sopenharmony_ci .ops = &vivid_radio_rx_ctrl_ops, 13138c2ecf20Sopenharmony_ci .id = VIVID_CID_RADIO_RX_RDS_BLOCKIO, 13148c2ecf20Sopenharmony_ci .name = "RDS Rx I/O Mode", 13158c2ecf20Sopenharmony_ci .type = V4L2_CTRL_TYPE_MENU, 13168c2ecf20Sopenharmony_ci .qmenu = vivid_ctrl_radio_rds_mode_strings, 13178c2ecf20Sopenharmony_ci .max = 1, 13188c2ecf20Sopenharmony_ci}; 13198c2ecf20Sopenharmony_ci 13208c2ecf20Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_radio_rx_rds_rbds = { 13218c2ecf20Sopenharmony_ci .ops = &vivid_radio_rx_ctrl_ops, 13228c2ecf20Sopenharmony_ci .id = VIVID_CID_RADIO_RX_RDS_RBDS, 13238c2ecf20Sopenharmony_ci .name = "Generate RBDS Instead of RDS", 13248c2ecf20Sopenharmony_ci .type = V4L2_CTRL_TYPE_BOOLEAN, 13258c2ecf20Sopenharmony_ci .max = 1, 13268c2ecf20Sopenharmony_ci .step = 1, 13278c2ecf20Sopenharmony_ci}; 13288c2ecf20Sopenharmony_ci 13298c2ecf20Sopenharmony_cistatic const char * const vivid_ctrl_radio_hw_seek_mode_strings[] = { 13308c2ecf20Sopenharmony_ci "Bounded", 13318c2ecf20Sopenharmony_ci "Wrap Around", 13328c2ecf20Sopenharmony_ci "Both", 13338c2ecf20Sopenharmony_ci NULL, 13348c2ecf20Sopenharmony_ci}; 13358c2ecf20Sopenharmony_ci 13368c2ecf20Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_radio_hw_seek_mode = { 13378c2ecf20Sopenharmony_ci .ops = &vivid_radio_rx_ctrl_ops, 13388c2ecf20Sopenharmony_ci .id = VIVID_CID_RADIO_SEEK_MODE, 13398c2ecf20Sopenharmony_ci .name = "Radio HW Seek Mode", 13408c2ecf20Sopenharmony_ci .type = V4L2_CTRL_TYPE_MENU, 13418c2ecf20Sopenharmony_ci .max = 2, 13428c2ecf20Sopenharmony_ci .qmenu = vivid_ctrl_radio_hw_seek_mode_strings, 13438c2ecf20Sopenharmony_ci}; 13448c2ecf20Sopenharmony_ci 13458c2ecf20Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_radio_hw_seek_prog_lim = { 13468c2ecf20Sopenharmony_ci .ops = &vivid_radio_rx_ctrl_ops, 13478c2ecf20Sopenharmony_ci .id = VIVID_CID_RADIO_SEEK_PROG_LIM, 13488c2ecf20Sopenharmony_ci .name = "Radio Programmable HW Seek", 13498c2ecf20Sopenharmony_ci .type = V4L2_CTRL_TYPE_BOOLEAN, 13508c2ecf20Sopenharmony_ci .max = 1, 13518c2ecf20Sopenharmony_ci .step = 1, 13528c2ecf20Sopenharmony_ci}; 13538c2ecf20Sopenharmony_ci 13548c2ecf20Sopenharmony_ci 13558c2ecf20Sopenharmony_ci/* Radio Transmitter Controls */ 13568c2ecf20Sopenharmony_ci 13578c2ecf20Sopenharmony_cistatic int vivid_radio_tx_s_ctrl(struct v4l2_ctrl *ctrl) 13588c2ecf20Sopenharmony_ci{ 13598c2ecf20Sopenharmony_ci struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_radio_tx); 13608c2ecf20Sopenharmony_ci 13618c2ecf20Sopenharmony_ci switch (ctrl->id) { 13628c2ecf20Sopenharmony_ci case VIVID_CID_RADIO_TX_RDS_BLOCKIO: 13638c2ecf20Sopenharmony_ci dev->radio_tx_rds_controls = ctrl->val; 13648c2ecf20Sopenharmony_ci dev->radio_tx_caps &= ~V4L2_CAP_READWRITE; 13658c2ecf20Sopenharmony_ci if (!dev->radio_tx_rds_controls) 13668c2ecf20Sopenharmony_ci dev->radio_tx_caps |= V4L2_CAP_READWRITE; 13678c2ecf20Sopenharmony_ci dev->radio_tx_dev.device_caps = dev->radio_tx_caps; 13688c2ecf20Sopenharmony_ci break; 13698c2ecf20Sopenharmony_ci case V4L2_CID_RDS_TX_PTY: 13708c2ecf20Sopenharmony_ci if (dev->radio_rx_rds_controls) 13718c2ecf20Sopenharmony_ci v4l2_ctrl_s_ctrl(dev->radio_rx_rds_pty, ctrl->val); 13728c2ecf20Sopenharmony_ci break; 13738c2ecf20Sopenharmony_ci case V4L2_CID_RDS_TX_PS_NAME: 13748c2ecf20Sopenharmony_ci if (dev->radio_rx_rds_controls) 13758c2ecf20Sopenharmony_ci v4l2_ctrl_s_ctrl_string(dev->radio_rx_rds_psname, ctrl->p_new.p_char); 13768c2ecf20Sopenharmony_ci break; 13778c2ecf20Sopenharmony_ci case V4L2_CID_RDS_TX_RADIO_TEXT: 13788c2ecf20Sopenharmony_ci if (dev->radio_rx_rds_controls) 13798c2ecf20Sopenharmony_ci v4l2_ctrl_s_ctrl_string(dev->radio_rx_rds_radiotext, ctrl->p_new.p_char); 13808c2ecf20Sopenharmony_ci break; 13818c2ecf20Sopenharmony_ci case V4L2_CID_RDS_TX_TRAFFIC_ANNOUNCEMENT: 13828c2ecf20Sopenharmony_ci if (dev->radio_rx_rds_controls) 13838c2ecf20Sopenharmony_ci v4l2_ctrl_s_ctrl(dev->radio_rx_rds_ta, ctrl->val); 13848c2ecf20Sopenharmony_ci break; 13858c2ecf20Sopenharmony_ci case V4L2_CID_RDS_TX_TRAFFIC_PROGRAM: 13868c2ecf20Sopenharmony_ci if (dev->radio_rx_rds_controls) 13878c2ecf20Sopenharmony_ci v4l2_ctrl_s_ctrl(dev->radio_rx_rds_tp, ctrl->val); 13888c2ecf20Sopenharmony_ci break; 13898c2ecf20Sopenharmony_ci case V4L2_CID_RDS_TX_MUSIC_SPEECH: 13908c2ecf20Sopenharmony_ci if (dev->radio_rx_rds_controls) 13918c2ecf20Sopenharmony_ci v4l2_ctrl_s_ctrl(dev->radio_rx_rds_ms, ctrl->val); 13928c2ecf20Sopenharmony_ci break; 13938c2ecf20Sopenharmony_ci } 13948c2ecf20Sopenharmony_ci return 0; 13958c2ecf20Sopenharmony_ci} 13968c2ecf20Sopenharmony_ci 13978c2ecf20Sopenharmony_cistatic const struct v4l2_ctrl_ops vivid_radio_tx_ctrl_ops = { 13988c2ecf20Sopenharmony_ci .s_ctrl = vivid_radio_tx_s_ctrl, 13998c2ecf20Sopenharmony_ci}; 14008c2ecf20Sopenharmony_ci 14018c2ecf20Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_radio_tx_rds_blockio = { 14028c2ecf20Sopenharmony_ci .ops = &vivid_radio_tx_ctrl_ops, 14038c2ecf20Sopenharmony_ci .id = VIVID_CID_RADIO_TX_RDS_BLOCKIO, 14048c2ecf20Sopenharmony_ci .name = "RDS Tx I/O Mode", 14058c2ecf20Sopenharmony_ci .type = V4L2_CTRL_TYPE_MENU, 14068c2ecf20Sopenharmony_ci .qmenu = vivid_ctrl_radio_rds_mode_strings, 14078c2ecf20Sopenharmony_ci .max = 1, 14088c2ecf20Sopenharmony_ci .def = 1, 14098c2ecf20Sopenharmony_ci}; 14108c2ecf20Sopenharmony_ci 14118c2ecf20Sopenharmony_ci 14128c2ecf20Sopenharmony_ci/* SDR Capture Controls */ 14138c2ecf20Sopenharmony_ci 14148c2ecf20Sopenharmony_cistatic int vivid_sdr_cap_s_ctrl(struct v4l2_ctrl *ctrl) 14158c2ecf20Sopenharmony_ci{ 14168c2ecf20Sopenharmony_ci struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_sdr_cap); 14178c2ecf20Sopenharmony_ci 14188c2ecf20Sopenharmony_ci switch (ctrl->id) { 14198c2ecf20Sopenharmony_ci case VIVID_CID_SDR_CAP_FM_DEVIATION: 14208c2ecf20Sopenharmony_ci dev->sdr_fm_deviation = ctrl->val; 14218c2ecf20Sopenharmony_ci break; 14228c2ecf20Sopenharmony_ci } 14238c2ecf20Sopenharmony_ci return 0; 14248c2ecf20Sopenharmony_ci} 14258c2ecf20Sopenharmony_ci 14268c2ecf20Sopenharmony_cistatic const struct v4l2_ctrl_ops vivid_sdr_cap_ctrl_ops = { 14278c2ecf20Sopenharmony_ci .s_ctrl = vivid_sdr_cap_s_ctrl, 14288c2ecf20Sopenharmony_ci}; 14298c2ecf20Sopenharmony_ci 14308c2ecf20Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_sdr_cap_fm_deviation = { 14318c2ecf20Sopenharmony_ci .ops = &vivid_sdr_cap_ctrl_ops, 14328c2ecf20Sopenharmony_ci .id = VIVID_CID_SDR_CAP_FM_DEVIATION, 14338c2ecf20Sopenharmony_ci .name = "FM Deviation", 14348c2ecf20Sopenharmony_ci .type = V4L2_CTRL_TYPE_INTEGER, 14358c2ecf20Sopenharmony_ci .min = 100, 14368c2ecf20Sopenharmony_ci .max = 200000, 14378c2ecf20Sopenharmony_ci .def = 75000, 14388c2ecf20Sopenharmony_ci .step = 1, 14398c2ecf20Sopenharmony_ci}; 14408c2ecf20Sopenharmony_ci 14418c2ecf20Sopenharmony_ci/* Metadata Capture Control */ 14428c2ecf20Sopenharmony_ci 14438c2ecf20Sopenharmony_cistatic int vivid_meta_cap_s_ctrl(struct v4l2_ctrl *ctrl) 14448c2ecf20Sopenharmony_ci{ 14458c2ecf20Sopenharmony_ci struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, 14468c2ecf20Sopenharmony_ci ctrl_hdl_meta_cap); 14478c2ecf20Sopenharmony_ci 14488c2ecf20Sopenharmony_ci switch (ctrl->id) { 14498c2ecf20Sopenharmony_ci case VIVID_CID_META_CAP_GENERATE_PTS: 14508c2ecf20Sopenharmony_ci dev->meta_pts = ctrl->val; 14518c2ecf20Sopenharmony_ci break; 14528c2ecf20Sopenharmony_ci case VIVID_CID_META_CAP_GENERATE_SCR: 14538c2ecf20Sopenharmony_ci dev->meta_scr = ctrl->val; 14548c2ecf20Sopenharmony_ci break; 14558c2ecf20Sopenharmony_ci } 14568c2ecf20Sopenharmony_ci return 0; 14578c2ecf20Sopenharmony_ci} 14588c2ecf20Sopenharmony_ci 14598c2ecf20Sopenharmony_cistatic const struct v4l2_ctrl_ops vivid_meta_cap_ctrl_ops = { 14608c2ecf20Sopenharmony_ci .s_ctrl = vivid_meta_cap_s_ctrl, 14618c2ecf20Sopenharmony_ci}; 14628c2ecf20Sopenharmony_ci 14638c2ecf20Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_meta_has_pts = { 14648c2ecf20Sopenharmony_ci .ops = &vivid_meta_cap_ctrl_ops, 14658c2ecf20Sopenharmony_ci .id = VIVID_CID_META_CAP_GENERATE_PTS, 14668c2ecf20Sopenharmony_ci .name = "Generate PTS", 14678c2ecf20Sopenharmony_ci .type = V4L2_CTRL_TYPE_BOOLEAN, 14688c2ecf20Sopenharmony_ci .max = 1, 14698c2ecf20Sopenharmony_ci .def = 1, 14708c2ecf20Sopenharmony_ci .step = 1, 14718c2ecf20Sopenharmony_ci}; 14728c2ecf20Sopenharmony_ci 14738c2ecf20Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_meta_has_src_clk = { 14748c2ecf20Sopenharmony_ci .ops = &vivid_meta_cap_ctrl_ops, 14758c2ecf20Sopenharmony_ci .id = VIVID_CID_META_CAP_GENERATE_SCR, 14768c2ecf20Sopenharmony_ci .name = "Generate SCR", 14778c2ecf20Sopenharmony_ci .type = V4L2_CTRL_TYPE_BOOLEAN, 14788c2ecf20Sopenharmony_ci .max = 1, 14798c2ecf20Sopenharmony_ci .def = 1, 14808c2ecf20Sopenharmony_ci .step = 1, 14818c2ecf20Sopenharmony_ci}; 14828c2ecf20Sopenharmony_ci 14838c2ecf20Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_class = { 14848c2ecf20Sopenharmony_ci .ops = &vivid_user_gen_ctrl_ops, 14858c2ecf20Sopenharmony_ci .flags = V4L2_CTRL_FLAG_READ_ONLY | V4L2_CTRL_FLAG_WRITE_ONLY, 14868c2ecf20Sopenharmony_ci .id = VIVID_CID_VIVID_CLASS, 14878c2ecf20Sopenharmony_ci .name = "Vivid Controls", 14888c2ecf20Sopenharmony_ci .type = V4L2_CTRL_TYPE_CTRL_CLASS, 14898c2ecf20Sopenharmony_ci}; 14908c2ecf20Sopenharmony_ci 14918c2ecf20Sopenharmony_ciint vivid_create_controls(struct vivid_dev *dev, bool show_ccs_cap, 14928c2ecf20Sopenharmony_ci bool show_ccs_out, bool no_error_inj, 14938c2ecf20Sopenharmony_ci bool has_sdtv, bool has_hdmi) 14948c2ecf20Sopenharmony_ci{ 14958c2ecf20Sopenharmony_ci struct v4l2_ctrl_handler *hdl_user_gen = &dev->ctrl_hdl_user_gen; 14968c2ecf20Sopenharmony_ci struct v4l2_ctrl_handler *hdl_user_vid = &dev->ctrl_hdl_user_vid; 14978c2ecf20Sopenharmony_ci struct v4l2_ctrl_handler *hdl_user_aud = &dev->ctrl_hdl_user_aud; 14988c2ecf20Sopenharmony_ci struct v4l2_ctrl_handler *hdl_streaming = &dev->ctrl_hdl_streaming; 14998c2ecf20Sopenharmony_ci struct v4l2_ctrl_handler *hdl_sdtv_cap = &dev->ctrl_hdl_sdtv_cap; 15008c2ecf20Sopenharmony_ci struct v4l2_ctrl_handler *hdl_loop_cap = &dev->ctrl_hdl_loop_cap; 15018c2ecf20Sopenharmony_ci struct v4l2_ctrl_handler *hdl_fb = &dev->ctrl_hdl_fb; 15028c2ecf20Sopenharmony_ci struct v4l2_ctrl_handler *hdl_vid_cap = &dev->ctrl_hdl_vid_cap; 15038c2ecf20Sopenharmony_ci struct v4l2_ctrl_handler *hdl_vid_out = &dev->ctrl_hdl_vid_out; 15048c2ecf20Sopenharmony_ci struct v4l2_ctrl_handler *hdl_vbi_cap = &dev->ctrl_hdl_vbi_cap; 15058c2ecf20Sopenharmony_ci struct v4l2_ctrl_handler *hdl_vbi_out = &dev->ctrl_hdl_vbi_out; 15068c2ecf20Sopenharmony_ci struct v4l2_ctrl_handler *hdl_radio_rx = &dev->ctrl_hdl_radio_rx; 15078c2ecf20Sopenharmony_ci struct v4l2_ctrl_handler *hdl_radio_tx = &dev->ctrl_hdl_radio_tx; 15088c2ecf20Sopenharmony_ci struct v4l2_ctrl_handler *hdl_sdr_cap = &dev->ctrl_hdl_sdr_cap; 15098c2ecf20Sopenharmony_ci struct v4l2_ctrl_handler *hdl_meta_cap = &dev->ctrl_hdl_meta_cap; 15108c2ecf20Sopenharmony_ci struct v4l2_ctrl_handler *hdl_meta_out = &dev->ctrl_hdl_meta_out; 15118c2ecf20Sopenharmony_ci struct v4l2_ctrl_handler *hdl_tch_cap = &dev->ctrl_hdl_touch_cap; 15128c2ecf20Sopenharmony_ci 15138c2ecf20Sopenharmony_ci struct v4l2_ctrl_config vivid_ctrl_dv_timings = { 15148c2ecf20Sopenharmony_ci .ops = &vivid_vid_cap_ctrl_ops, 15158c2ecf20Sopenharmony_ci .id = VIVID_CID_DV_TIMINGS, 15168c2ecf20Sopenharmony_ci .name = "DV Timings", 15178c2ecf20Sopenharmony_ci .type = V4L2_CTRL_TYPE_MENU, 15188c2ecf20Sopenharmony_ci }; 15198c2ecf20Sopenharmony_ci int i; 15208c2ecf20Sopenharmony_ci 15218c2ecf20Sopenharmony_ci v4l2_ctrl_handler_init(hdl_user_gen, 10); 15228c2ecf20Sopenharmony_ci v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_class, NULL); 15238c2ecf20Sopenharmony_ci v4l2_ctrl_handler_init(hdl_user_vid, 9); 15248c2ecf20Sopenharmony_ci v4l2_ctrl_new_custom(hdl_user_vid, &vivid_ctrl_class, NULL); 15258c2ecf20Sopenharmony_ci v4l2_ctrl_handler_init(hdl_user_aud, 2); 15268c2ecf20Sopenharmony_ci v4l2_ctrl_new_custom(hdl_user_aud, &vivid_ctrl_class, NULL); 15278c2ecf20Sopenharmony_ci v4l2_ctrl_handler_init(hdl_streaming, 8); 15288c2ecf20Sopenharmony_ci v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_class, NULL); 15298c2ecf20Sopenharmony_ci v4l2_ctrl_handler_init(hdl_sdtv_cap, 2); 15308c2ecf20Sopenharmony_ci v4l2_ctrl_new_custom(hdl_sdtv_cap, &vivid_ctrl_class, NULL); 15318c2ecf20Sopenharmony_ci v4l2_ctrl_handler_init(hdl_loop_cap, 1); 15328c2ecf20Sopenharmony_ci v4l2_ctrl_new_custom(hdl_loop_cap, &vivid_ctrl_class, NULL); 15338c2ecf20Sopenharmony_ci v4l2_ctrl_handler_init(hdl_fb, 1); 15348c2ecf20Sopenharmony_ci v4l2_ctrl_new_custom(hdl_fb, &vivid_ctrl_class, NULL); 15358c2ecf20Sopenharmony_ci v4l2_ctrl_handler_init(hdl_vid_cap, 55); 15368c2ecf20Sopenharmony_ci v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_class, NULL); 15378c2ecf20Sopenharmony_ci v4l2_ctrl_handler_init(hdl_vid_out, 26); 15388c2ecf20Sopenharmony_ci if (!no_error_inj || dev->has_fb || dev->num_hdmi_outputs) 15398c2ecf20Sopenharmony_ci v4l2_ctrl_new_custom(hdl_vid_out, &vivid_ctrl_class, NULL); 15408c2ecf20Sopenharmony_ci v4l2_ctrl_handler_init(hdl_vbi_cap, 21); 15418c2ecf20Sopenharmony_ci v4l2_ctrl_new_custom(hdl_vbi_cap, &vivid_ctrl_class, NULL); 15428c2ecf20Sopenharmony_ci v4l2_ctrl_handler_init(hdl_vbi_out, 19); 15438c2ecf20Sopenharmony_ci if (!no_error_inj) 15448c2ecf20Sopenharmony_ci v4l2_ctrl_new_custom(hdl_vbi_out, &vivid_ctrl_class, NULL); 15458c2ecf20Sopenharmony_ci v4l2_ctrl_handler_init(hdl_radio_rx, 17); 15468c2ecf20Sopenharmony_ci v4l2_ctrl_new_custom(hdl_radio_rx, &vivid_ctrl_class, NULL); 15478c2ecf20Sopenharmony_ci v4l2_ctrl_handler_init(hdl_radio_tx, 17); 15488c2ecf20Sopenharmony_ci v4l2_ctrl_new_custom(hdl_radio_tx, &vivid_ctrl_class, NULL); 15498c2ecf20Sopenharmony_ci v4l2_ctrl_handler_init(hdl_sdr_cap, 19); 15508c2ecf20Sopenharmony_ci v4l2_ctrl_new_custom(hdl_sdr_cap, &vivid_ctrl_class, NULL); 15518c2ecf20Sopenharmony_ci v4l2_ctrl_handler_init(hdl_meta_cap, 2); 15528c2ecf20Sopenharmony_ci v4l2_ctrl_new_custom(hdl_meta_cap, &vivid_ctrl_class, NULL); 15538c2ecf20Sopenharmony_ci v4l2_ctrl_handler_init(hdl_meta_out, 2); 15548c2ecf20Sopenharmony_ci v4l2_ctrl_new_custom(hdl_meta_out, &vivid_ctrl_class, NULL); 15558c2ecf20Sopenharmony_ci v4l2_ctrl_handler_init(hdl_tch_cap, 2); 15568c2ecf20Sopenharmony_ci v4l2_ctrl_new_custom(hdl_tch_cap, &vivid_ctrl_class, NULL); 15578c2ecf20Sopenharmony_ci 15588c2ecf20Sopenharmony_ci /* User Controls */ 15598c2ecf20Sopenharmony_ci dev->volume = v4l2_ctrl_new_std(hdl_user_aud, NULL, 15608c2ecf20Sopenharmony_ci V4L2_CID_AUDIO_VOLUME, 0, 255, 1, 200); 15618c2ecf20Sopenharmony_ci dev->mute = v4l2_ctrl_new_std(hdl_user_aud, NULL, 15628c2ecf20Sopenharmony_ci V4L2_CID_AUDIO_MUTE, 0, 1, 1, 0); 15638c2ecf20Sopenharmony_ci if (dev->has_vid_cap) { 15648c2ecf20Sopenharmony_ci dev->brightness = v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops, 15658c2ecf20Sopenharmony_ci V4L2_CID_BRIGHTNESS, 0, 255, 1, 128); 15668c2ecf20Sopenharmony_ci for (i = 0; i < MAX_INPUTS; i++) 15678c2ecf20Sopenharmony_ci dev->input_brightness[i] = 128; 15688c2ecf20Sopenharmony_ci dev->contrast = v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops, 15698c2ecf20Sopenharmony_ci V4L2_CID_CONTRAST, 0, 255, 1, 128); 15708c2ecf20Sopenharmony_ci dev->saturation = v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops, 15718c2ecf20Sopenharmony_ci V4L2_CID_SATURATION, 0, 255, 1, 128); 15728c2ecf20Sopenharmony_ci dev->hue = v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops, 15738c2ecf20Sopenharmony_ci V4L2_CID_HUE, -128, 128, 1, 0); 15748c2ecf20Sopenharmony_ci v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops, 15758c2ecf20Sopenharmony_ci V4L2_CID_HFLIP, 0, 1, 1, 0); 15768c2ecf20Sopenharmony_ci v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops, 15778c2ecf20Sopenharmony_ci V4L2_CID_VFLIP, 0, 1, 1, 0); 15788c2ecf20Sopenharmony_ci dev->autogain = v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops, 15798c2ecf20Sopenharmony_ci V4L2_CID_AUTOGAIN, 0, 1, 1, 1); 15808c2ecf20Sopenharmony_ci dev->gain = v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops, 15818c2ecf20Sopenharmony_ci V4L2_CID_GAIN, 0, 255, 1, 100); 15828c2ecf20Sopenharmony_ci dev->alpha = v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops, 15838c2ecf20Sopenharmony_ci V4L2_CID_ALPHA_COMPONENT, 0, 255, 1, 0); 15848c2ecf20Sopenharmony_ci } 15858c2ecf20Sopenharmony_ci dev->button = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_button, NULL); 15868c2ecf20Sopenharmony_ci dev->int32 = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_int32, NULL); 15878c2ecf20Sopenharmony_ci dev->int64 = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_int64, NULL); 15888c2ecf20Sopenharmony_ci dev->boolean = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_boolean, NULL); 15898c2ecf20Sopenharmony_ci dev->menu = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_menu, NULL); 15908c2ecf20Sopenharmony_ci dev->string = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_string, NULL); 15918c2ecf20Sopenharmony_ci dev->bitmask = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_bitmask, NULL); 15928c2ecf20Sopenharmony_ci dev->int_menu = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_int_menu, NULL); 15938c2ecf20Sopenharmony_ci v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_area, NULL); 15948c2ecf20Sopenharmony_ci v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_u32_array, NULL); 15958c2ecf20Sopenharmony_ci v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_u16_matrix, NULL); 15968c2ecf20Sopenharmony_ci v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_u8_4d_array, NULL); 15978c2ecf20Sopenharmony_ci 15988c2ecf20Sopenharmony_ci if (dev->has_vid_cap) { 15998c2ecf20Sopenharmony_ci /* Image Processing Controls */ 16008c2ecf20Sopenharmony_ci struct v4l2_ctrl_config vivid_ctrl_test_pattern = { 16018c2ecf20Sopenharmony_ci .ops = &vivid_vid_cap_ctrl_ops, 16028c2ecf20Sopenharmony_ci .id = VIVID_CID_TEST_PATTERN, 16038c2ecf20Sopenharmony_ci .name = "Test Pattern", 16048c2ecf20Sopenharmony_ci .type = V4L2_CTRL_TYPE_MENU, 16058c2ecf20Sopenharmony_ci .max = TPG_PAT_NOISE, 16068c2ecf20Sopenharmony_ci .qmenu = tpg_pattern_strings, 16078c2ecf20Sopenharmony_ci }; 16088c2ecf20Sopenharmony_ci 16098c2ecf20Sopenharmony_ci dev->test_pattern = v4l2_ctrl_new_custom(hdl_vid_cap, 16108c2ecf20Sopenharmony_ci &vivid_ctrl_test_pattern, NULL); 16118c2ecf20Sopenharmony_ci v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_perc_fill, NULL); 16128c2ecf20Sopenharmony_ci v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_hor_movement, NULL); 16138c2ecf20Sopenharmony_ci v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_vert_movement, NULL); 16148c2ecf20Sopenharmony_ci v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_osd_mode, NULL); 16158c2ecf20Sopenharmony_ci v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_show_border, NULL); 16168c2ecf20Sopenharmony_ci v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_show_square, NULL); 16178c2ecf20Sopenharmony_ci v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_hflip, NULL); 16188c2ecf20Sopenharmony_ci v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_vflip, NULL); 16198c2ecf20Sopenharmony_ci v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_insert_sav, NULL); 16208c2ecf20Sopenharmony_ci v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_insert_eav, NULL); 16218c2ecf20Sopenharmony_ci v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_reduced_fps, NULL); 16228c2ecf20Sopenharmony_ci if (show_ccs_cap) { 16238c2ecf20Sopenharmony_ci dev->ctrl_has_crop_cap = v4l2_ctrl_new_custom(hdl_vid_cap, 16248c2ecf20Sopenharmony_ci &vivid_ctrl_has_crop_cap, NULL); 16258c2ecf20Sopenharmony_ci dev->ctrl_has_compose_cap = v4l2_ctrl_new_custom(hdl_vid_cap, 16268c2ecf20Sopenharmony_ci &vivid_ctrl_has_compose_cap, NULL); 16278c2ecf20Sopenharmony_ci dev->ctrl_has_scaler_cap = v4l2_ctrl_new_custom(hdl_vid_cap, 16288c2ecf20Sopenharmony_ci &vivid_ctrl_has_scaler_cap, NULL); 16298c2ecf20Sopenharmony_ci } 16308c2ecf20Sopenharmony_ci 16318c2ecf20Sopenharmony_ci v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_tstamp_src, NULL); 16328c2ecf20Sopenharmony_ci dev->colorspace = v4l2_ctrl_new_custom(hdl_vid_cap, 16338c2ecf20Sopenharmony_ci &vivid_ctrl_colorspace, NULL); 16348c2ecf20Sopenharmony_ci v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_xfer_func, NULL); 16358c2ecf20Sopenharmony_ci v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_ycbcr_enc, NULL); 16368c2ecf20Sopenharmony_ci v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_hsv_enc, NULL); 16378c2ecf20Sopenharmony_ci v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_quantization, NULL); 16388c2ecf20Sopenharmony_ci v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_alpha_mode, NULL); 16398c2ecf20Sopenharmony_ci } 16408c2ecf20Sopenharmony_ci 16418c2ecf20Sopenharmony_ci if (dev->has_vid_out && show_ccs_out) { 16428c2ecf20Sopenharmony_ci dev->ctrl_has_crop_out = v4l2_ctrl_new_custom(hdl_vid_out, 16438c2ecf20Sopenharmony_ci &vivid_ctrl_has_crop_out, NULL); 16448c2ecf20Sopenharmony_ci dev->ctrl_has_compose_out = v4l2_ctrl_new_custom(hdl_vid_out, 16458c2ecf20Sopenharmony_ci &vivid_ctrl_has_compose_out, NULL); 16468c2ecf20Sopenharmony_ci dev->ctrl_has_scaler_out = v4l2_ctrl_new_custom(hdl_vid_out, 16478c2ecf20Sopenharmony_ci &vivid_ctrl_has_scaler_out, NULL); 16488c2ecf20Sopenharmony_ci } 16498c2ecf20Sopenharmony_ci 16508c2ecf20Sopenharmony_ci /* 16518c2ecf20Sopenharmony_ci * Testing this driver with v4l2-compliance will trigger the error 16528c2ecf20Sopenharmony_ci * injection controls, and after that nothing will work as expected. 16538c2ecf20Sopenharmony_ci * So we have a module option to drop these error injecting controls 16548c2ecf20Sopenharmony_ci * allowing us to run v4l2_compliance again. 16558c2ecf20Sopenharmony_ci */ 16568c2ecf20Sopenharmony_ci if (!no_error_inj) { 16578c2ecf20Sopenharmony_ci v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_disconnect, NULL); 16588c2ecf20Sopenharmony_ci v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_dqbuf_error, NULL); 16598c2ecf20Sopenharmony_ci v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_perc_dropped, NULL); 16608c2ecf20Sopenharmony_ci v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_queue_setup_error, NULL); 16618c2ecf20Sopenharmony_ci v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_buf_prepare_error, NULL); 16628c2ecf20Sopenharmony_ci v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_start_streaming_error, NULL); 16638c2ecf20Sopenharmony_ci v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_queue_error, NULL); 16648c2ecf20Sopenharmony_ci#ifdef CONFIG_MEDIA_CONTROLLER 16658c2ecf20Sopenharmony_ci v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_req_validate_error, NULL); 16668c2ecf20Sopenharmony_ci#endif 16678c2ecf20Sopenharmony_ci v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_seq_wrap, NULL); 16688c2ecf20Sopenharmony_ci v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_time_wrap, NULL); 16698c2ecf20Sopenharmony_ci } 16708c2ecf20Sopenharmony_ci 16718c2ecf20Sopenharmony_ci if (has_sdtv && (dev->has_vid_cap || dev->has_vbi_cap)) { 16728c2ecf20Sopenharmony_ci if (dev->has_vid_cap) 16738c2ecf20Sopenharmony_ci v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_std_aspect_ratio, NULL); 16748c2ecf20Sopenharmony_ci dev->ctrl_std_signal_mode = v4l2_ctrl_new_custom(hdl_sdtv_cap, 16758c2ecf20Sopenharmony_ci &vivid_ctrl_std_signal_mode, NULL); 16768c2ecf20Sopenharmony_ci dev->ctrl_standard = v4l2_ctrl_new_custom(hdl_sdtv_cap, 16778c2ecf20Sopenharmony_ci &vivid_ctrl_standard, NULL); 16788c2ecf20Sopenharmony_ci if (dev->ctrl_std_signal_mode) 16798c2ecf20Sopenharmony_ci v4l2_ctrl_cluster(2, &dev->ctrl_std_signal_mode); 16808c2ecf20Sopenharmony_ci if (dev->has_raw_vbi_cap) 16818c2ecf20Sopenharmony_ci v4l2_ctrl_new_custom(hdl_vbi_cap, &vivid_ctrl_vbi_cap_interlaced, NULL); 16828c2ecf20Sopenharmony_ci } 16838c2ecf20Sopenharmony_ci 16848c2ecf20Sopenharmony_ci if (dev->num_hdmi_inputs) { 16858c2ecf20Sopenharmony_ci s64 hdmi_input_mask = GENMASK(dev->num_hdmi_inputs - 1, 0); 16868c2ecf20Sopenharmony_ci 16878c2ecf20Sopenharmony_ci dev->ctrl_dv_timings_signal_mode = v4l2_ctrl_new_custom(hdl_vid_cap, 16888c2ecf20Sopenharmony_ci &vivid_ctrl_dv_timings_signal_mode, NULL); 16898c2ecf20Sopenharmony_ci 16908c2ecf20Sopenharmony_ci vivid_ctrl_dv_timings.max = dev->query_dv_timings_size - 1; 16918c2ecf20Sopenharmony_ci vivid_ctrl_dv_timings.qmenu = 16928c2ecf20Sopenharmony_ci (const char * const *)dev->query_dv_timings_qmenu; 16938c2ecf20Sopenharmony_ci dev->ctrl_dv_timings = v4l2_ctrl_new_custom(hdl_vid_cap, 16948c2ecf20Sopenharmony_ci &vivid_ctrl_dv_timings, NULL); 16958c2ecf20Sopenharmony_ci if (dev->ctrl_dv_timings_signal_mode) 16968c2ecf20Sopenharmony_ci v4l2_ctrl_cluster(2, &dev->ctrl_dv_timings_signal_mode); 16978c2ecf20Sopenharmony_ci 16988c2ecf20Sopenharmony_ci v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_dv_timings_aspect_ratio, NULL); 16998c2ecf20Sopenharmony_ci v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_max_edid_blocks, NULL); 17008c2ecf20Sopenharmony_ci dev->real_rgb_range_cap = v4l2_ctrl_new_custom(hdl_vid_cap, 17018c2ecf20Sopenharmony_ci &vivid_ctrl_limited_rgb_range, NULL); 17028c2ecf20Sopenharmony_ci dev->rgb_range_cap = v4l2_ctrl_new_std_menu(hdl_vid_cap, 17038c2ecf20Sopenharmony_ci &vivid_vid_cap_ctrl_ops, 17048c2ecf20Sopenharmony_ci V4L2_CID_DV_RX_RGB_RANGE, V4L2_DV_RGB_RANGE_FULL, 17058c2ecf20Sopenharmony_ci 0, V4L2_DV_RGB_RANGE_AUTO); 17068c2ecf20Sopenharmony_ci dev->ctrl_rx_power_present = v4l2_ctrl_new_std(hdl_vid_cap, 17078c2ecf20Sopenharmony_ci NULL, V4L2_CID_DV_RX_POWER_PRESENT, 0, hdmi_input_mask, 17088c2ecf20Sopenharmony_ci 0, hdmi_input_mask); 17098c2ecf20Sopenharmony_ci 17108c2ecf20Sopenharmony_ci } 17118c2ecf20Sopenharmony_ci if (dev->num_hdmi_outputs) { 17128c2ecf20Sopenharmony_ci s64 hdmi_output_mask = GENMASK(dev->num_hdmi_outputs - 1, 0); 17138c2ecf20Sopenharmony_ci 17148c2ecf20Sopenharmony_ci /* 17158c2ecf20Sopenharmony_ci * We aren't doing anything with this at the moment, but 17168c2ecf20Sopenharmony_ci * HDMI outputs typically have this controls. 17178c2ecf20Sopenharmony_ci */ 17188c2ecf20Sopenharmony_ci dev->ctrl_tx_rgb_range = v4l2_ctrl_new_std_menu(hdl_vid_out, NULL, 17198c2ecf20Sopenharmony_ci V4L2_CID_DV_TX_RGB_RANGE, V4L2_DV_RGB_RANGE_FULL, 17208c2ecf20Sopenharmony_ci 0, V4L2_DV_RGB_RANGE_AUTO); 17218c2ecf20Sopenharmony_ci dev->ctrl_tx_mode = v4l2_ctrl_new_std_menu(hdl_vid_out, NULL, 17228c2ecf20Sopenharmony_ci V4L2_CID_DV_TX_MODE, V4L2_DV_TX_MODE_HDMI, 17238c2ecf20Sopenharmony_ci 0, V4L2_DV_TX_MODE_HDMI); 17248c2ecf20Sopenharmony_ci dev->ctrl_display_present = v4l2_ctrl_new_custom(hdl_vid_out, 17258c2ecf20Sopenharmony_ci &vivid_ctrl_display_present, NULL); 17268c2ecf20Sopenharmony_ci dev->ctrl_tx_hotplug = v4l2_ctrl_new_std(hdl_vid_out, 17278c2ecf20Sopenharmony_ci NULL, V4L2_CID_DV_TX_HOTPLUG, 0, hdmi_output_mask, 17288c2ecf20Sopenharmony_ci 0, hdmi_output_mask); 17298c2ecf20Sopenharmony_ci dev->ctrl_tx_rxsense = v4l2_ctrl_new_std(hdl_vid_out, 17308c2ecf20Sopenharmony_ci NULL, V4L2_CID_DV_TX_RXSENSE, 0, hdmi_output_mask, 17318c2ecf20Sopenharmony_ci 0, hdmi_output_mask); 17328c2ecf20Sopenharmony_ci dev->ctrl_tx_edid_present = v4l2_ctrl_new_std(hdl_vid_out, 17338c2ecf20Sopenharmony_ci NULL, V4L2_CID_DV_TX_EDID_PRESENT, 0, hdmi_output_mask, 17348c2ecf20Sopenharmony_ci 0, hdmi_output_mask); 17358c2ecf20Sopenharmony_ci } 17368c2ecf20Sopenharmony_ci if ((dev->has_vid_cap && dev->has_vid_out) || 17378c2ecf20Sopenharmony_ci (dev->has_vbi_cap && dev->has_vbi_out)) 17388c2ecf20Sopenharmony_ci v4l2_ctrl_new_custom(hdl_loop_cap, &vivid_ctrl_loop_video, NULL); 17398c2ecf20Sopenharmony_ci 17408c2ecf20Sopenharmony_ci if (dev->has_fb) 17418c2ecf20Sopenharmony_ci v4l2_ctrl_new_custom(hdl_fb, &vivid_ctrl_clear_fb, NULL); 17428c2ecf20Sopenharmony_ci 17438c2ecf20Sopenharmony_ci if (dev->has_radio_rx) { 17448c2ecf20Sopenharmony_ci v4l2_ctrl_new_custom(hdl_radio_rx, &vivid_ctrl_radio_hw_seek_mode, NULL); 17458c2ecf20Sopenharmony_ci v4l2_ctrl_new_custom(hdl_radio_rx, &vivid_ctrl_radio_hw_seek_prog_lim, NULL); 17468c2ecf20Sopenharmony_ci v4l2_ctrl_new_custom(hdl_radio_rx, &vivid_ctrl_radio_rx_rds_blockio, NULL); 17478c2ecf20Sopenharmony_ci v4l2_ctrl_new_custom(hdl_radio_rx, &vivid_ctrl_radio_rx_rds_rbds, NULL); 17488c2ecf20Sopenharmony_ci v4l2_ctrl_new_std(hdl_radio_rx, &vivid_radio_rx_ctrl_ops, 17498c2ecf20Sopenharmony_ci V4L2_CID_RDS_RECEPTION, 0, 1, 1, 1); 17508c2ecf20Sopenharmony_ci dev->radio_rx_rds_pty = v4l2_ctrl_new_std(hdl_radio_rx, 17518c2ecf20Sopenharmony_ci &vivid_radio_rx_ctrl_ops, 17528c2ecf20Sopenharmony_ci V4L2_CID_RDS_RX_PTY, 0, 31, 1, 0); 17538c2ecf20Sopenharmony_ci dev->radio_rx_rds_psname = v4l2_ctrl_new_std(hdl_radio_rx, 17548c2ecf20Sopenharmony_ci &vivid_radio_rx_ctrl_ops, 17558c2ecf20Sopenharmony_ci V4L2_CID_RDS_RX_PS_NAME, 0, 8, 8, 0); 17568c2ecf20Sopenharmony_ci dev->radio_rx_rds_radiotext = v4l2_ctrl_new_std(hdl_radio_rx, 17578c2ecf20Sopenharmony_ci &vivid_radio_rx_ctrl_ops, 17588c2ecf20Sopenharmony_ci V4L2_CID_RDS_RX_RADIO_TEXT, 0, 64, 64, 0); 17598c2ecf20Sopenharmony_ci dev->radio_rx_rds_ta = v4l2_ctrl_new_std(hdl_radio_rx, 17608c2ecf20Sopenharmony_ci &vivid_radio_rx_ctrl_ops, 17618c2ecf20Sopenharmony_ci V4L2_CID_RDS_RX_TRAFFIC_ANNOUNCEMENT, 0, 1, 1, 0); 17628c2ecf20Sopenharmony_ci dev->radio_rx_rds_tp = v4l2_ctrl_new_std(hdl_radio_rx, 17638c2ecf20Sopenharmony_ci &vivid_radio_rx_ctrl_ops, 17648c2ecf20Sopenharmony_ci V4L2_CID_RDS_RX_TRAFFIC_PROGRAM, 0, 1, 1, 0); 17658c2ecf20Sopenharmony_ci dev->radio_rx_rds_ms = v4l2_ctrl_new_std(hdl_radio_rx, 17668c2ecf20Sopenharmony_ci &vivid_radio_rx_ctrl_ops, 17678c2ecf20Sopenharmony_ci V4L2_CID_RDS_RX_MUSIC_SPEECH, 0, 1, 1, 1); 17688c2ecf20Sopenharmony_ci } 17698c2ecf20Sopenharmony_ci if (dev->has_radio_tx) { 17708c2ecf20Sopenharmony_ci v4l2_ctrl_new_custom(hdl_radio_tx, 17718c2ecf20Sopenharmony_ci &vivid_ctrl_radio_tx_rds_blockio, NULL); 17728c2ecf20Sopenharmony_ci dev->radio_tx_rds_pi = v4l2_ctrl_new_std(hdl_radio_tx, 17738c2ecf20Sopenharmony_ci &vivid_radio_tx_ctrl_ops, 17748c2ecf20Sopenharmony_ci V4L2_CID_RDS_TX_PI, 0, 0xffff, 1, 0x8088); 17758c2ecf20Sopenharmony_ci dev->radio_tx_rds_pty = v4l2_ctrl_new_std(hdl_radio_tx, 17768c2ecf20Sopenharmony_ci &vivid_radio_tx_ctrl_ops, 17778c2ecf20Sopenharmony_ci V4L2_CID_RDS_TX_PTY, 0, 31, 1, 3); 17788c2ecf20Sopenharmony_ci dev->radio_tx_rds_psname = v4l2_ctrl_new_std(hdl_radio_tx, 17798c2ecf20Sopenharmony_ci &vivid_radio_tx_ctrl_ops, 17808c2ecf20Sopenharmony_ci V4L2_CID_RDS_TX_PS_NAME, 0, 8, 8, 0); 17818c2ecf20Sopenharmony_ci if (dev->radio_tx_rds_psname) 17828c2ecf20Sopenharmony_ci v4l2_ctrl_s_ctrl_string(dev->radio_tx_rds_psname, "VIVID-TX"); 17838c2ecf20Sopenharmony_ci dev->radio_tx_rds_radiotext = v4l2_ctrl_new_std(hdl_radio_tx, 17848c2ecf20Sopenharmony_ci &vivid_radio_tx_ctrl_ops, 17858c2ecf20Sopenharmony_ci V4L2_CID_RDS_TX_RADIO_TEXT, 0, 64 * 2, 64, 0); 17868c2ecf20Sopenharmony_ci if (dev->radio_tx_rds_radiotext) 17878c2ecf20Sopenharmony_ci v4l2_ctrl_s_ctrl_string(dev->radio_tx_rds_radiotext, 17888c2ecf20Sopenharmony_ci "This is a VIVID default Radio Text template text, change at will"); 17898c2ecf20Sopenharmony_ci dev->radio_tx_rds_mono_stereo = v4l2_ctrl_new_std(hdl_radio_tx, 17908c2ecf20Sopenharmony_ci &vivid_radio_tx_ctrl_ops, 17918c2ecf20Sopenharmony_ci V4L2_CID_RDS_TX_MONO_STEREO, 0, 1, 1, 1); 17928c2ecf20Sopenharmony_ci dev->radio_tx_rds_art_head = v4l2_ctrl_new_std(hdl_radio_tx, 17938c2ecf20Sopenharmony_ci &vivid_radio_tx_ctrl_ops, 17948c2ecf20Sopenharmony_ci V4L2_CID_RDS_TX_ARTIFICIAL_HEAD, 0, 1, 1, 0); 17958c2ecf20Sopenharmony_ci dev->radio_tx_rds_compressed = v4l2_ctrl_new_std(hdl_radio_tx, 17968c2ecf20Sopenharmony_ci &vivid_radio_tx_ctrl_ops, 17978c2ecf20Sopenharmony_ci V4L2_CID_RDS_TX_COMPRESSED, 0, 1, 1, 0); 17988c2ecf20Sopenharmony_ci dev->radio_tx_rds_dyn_pty = v4l2_ctrl_new_std(hdl_radio_tx, 17998c2ecf20Sopenharmony_ci &vivid_radio_tx_ctrl_ops, 18008c2ecf20Sopenharmony_ci V4L2_CID_RDS_TX_DYNAMIC_PTY, 0, 1, 1, 0); 18018c2ecf20Sopenharmony_ci dev->radio_tx_rds_ta = v4l2_ctrl_new_std(hdl_radio_tx, 18028c2ecf20Sopenharmony_ci &vivid_radio_tx_ctrl_ops, 18038c2ecf20Sopenharmony_ci V4L2_CID_RDS_TX_TRAFFIC_ANNOUNCEMENT, 0, 1, 1, 0); 18048c2ecf20Sopenharmony_ci dev->radio_tx_rds_tp = v4l2_ctrl_new_std(hdl_radio_tx, 18058c2ecf20Sopenharmony_ci &vivid_radio_tx_ctrl_ops, 18068c2ecf20Sopenharmony_ci V4L2_CID_RDS_TX_TRAFFIC_PROGRAM, 0, 1, 1, 1); 18078c2ecf20Sopenharmony_ci dev->radio_tx_rds_ms = v4l2_ctrl_new_std(hdl_radio_tx, 18088c2ecf20Sopenharmony_ci &vivid_radio_tx_ctrl_ops, 18098c2ecf20Sopenharmony_ci V4L2_CID_RDS_TX_MUSIC_SPEECH, 0, 1, 1, 1); 18108c2ecf20Sopenharmony_ci } 18118c2ecf20Sopenharmony_ci if (dev->has_sdr_cap) { 18128c2ecf20Sopenharmony_ci v4l2_ctrl_new_custom(hdl_sdr_cap, 18138c2ecf20Sopenharmony_ci &vivid_ctrl_sdr_cap_fm_deviation, NULL); 18148c2ecf20Sopenharmony_ci } 18158c2ecf20Sopenharmony_ci if (dev->has_meta_cap) { 18168c2ecf20Sopenharmony_ci v4l2_ctrl_new_custom(hdl_meta_cap, 18178c2ecf20Sopenharmony_ci &vivid_ctrl_meta_has_pts, NULL); 18188c2ecf20Sopenharmony_ci v4l2_ctrl_new_custom(hdl_meta_cap, 18198c2ecf20Sopenharmony_ci &vivid_ctrl_meta_has_src_clk, NULL); 18208c2ecf20Sopenharmony_ci } 18218c2ecf20Sopenharmony_ci 18228c2ecf20Sopenharmony_ci if (hdl_user_gen->error) 18238c2ecf20Sopenharmony_ci return hdl_user_gen->error; 18248c2ecf20Sopenharmony_ci if (hdl_user_vid->error) 18258c2ecf20Sopenharmony_ci return hdl_user_vid->error; 18268c2ecf20Sopenharmony_ci if (hdl_user_aud->error) 18278c2ecf20Sopenharmony_ci return hdl_user_aud->error; 18288c2ecf20Sopenharmony_ci if (hdl_streaming->error) 18298c2ecf20Sopenharmony_ci return hdl_streaming->error; 18308c2ecf20Sopenharmony_ci if (hdl_sdr_cap->error) 18318c2ecf20Sopenharmony_ci return hdl_sdr_cap->error; 18328c2ecf20Sopenharmony_ci if (hdl_loop_cap->error) 18338c2ecf20Sopenharmony_ci return hdl_loop_cap->error; 18348c2ecf20Sopenharmony_ci 18358c2ecf20Sopenharmony_ci if (dev->autogain) 18368c2ecf20Sopenharmony_ci v4l2_ctrl_auto_cluster(2, &dev->autogain, 0, true); 18378c2ecf20Sopenharmony_ci 18388c2ecf20Sopenharmony_ci if (dev->has_vid_cap) { 18398c2ecf20Sopenharmony_ci v4l2_ctrl_add_handler(hdl_vid_cap, hdl_user_gen, NULL, false); 18408c2ecf20Sopenharmony_ci v4l2_ctrl_add_handler(hdl_vid_cap, hdl_user_vid, NULL, false); 18418c2ecf20Sopenharmony_ci v4l2_ctrl_add_handler(hdl_vid_cap, hdl_user_aud, NULL, false); 18428c2ecf20Sopenharmony_ci v4l2_ctrl_add_handler(hdl_vid_cap, hdl_streaming, NULL, false); 18438c2ecf20Sopenharmony_ci v4l2_ctrl_add_handler(hdl_vid_cap, hdl_sdtv_cap, NULL, false); 18448c2ecf20Sopenharmony_ci v4l2_ctrl_add_handler(hdl_vid_cap, hdl_loop_cap, NULL, false); 18458c2ecf20Sopenharmony_ci v4l2_ctrl_add_handler(hdl_vid_cap, hdl_fb, NULL, false); 18468c2ecf20Sopenharmony_ci if (hdl_vid_cap->error) 18478c2ecf20Sopenharmony_ci return hdl_vid_cap->error; 18488c2ecf20Sopenharmony_ci dev->vid_cap_dev.ctrl_handler = hdl_vid_cap; 18498c2ecf20Sopenharmony_ci } 18508c2ecf20Sopenharmony_ci if (dev->has_vid_out) { 18518c2ecf20Sopenharmony_ci v4l2_ctrl_add_handler(hdl_vid_out, hdl_user_gen, NULL, false); 18528c2ecf20Sopenharmony_ci v4l2_ctrl_add_handler(hdl_vid_out, hdl_user_aud, NULL, false); 18538c2ecf20Sopenharmony_ci v4l2_ctrl_add_handler(hdl_vid_out, hdl_streaming, NULL, false); 18548c2ecf20Sopenharmony_ci v4l2_ctrl_add_handler(hdl_vid_out, hdl_fb, NULL, false); 18558c2ecf20Sopenharmony_ci if (hdl_vid_out->error) 18568c2ecf20Sopenharmony_ci return hdl_vid_out->error; 18578c2ecf20Sopenharmony_ci dev->vid_out_dev.ctrl_handler = hdl_vid_out; 18588c2ecf20Sopenharmony_ci } 18598c2ecf20Sopenharmony_ci if (dev->has_vbi_cap) { 18608c2ecf20Sopenharmony_ci v4l2_ctrl_add_handler(hdl_vbi_cap, hdl_user_gen, NULL, false); 18618c2ecf20Sopenharmony_ci v4l2_ctrl_add_handler(hdl_vbi_cap, hdl_streaming, NULL, false); 18628c2ecf20Sopenharmony_ci v4l2_ctrl_add_handler(hdl_vbi_cap, hdl_sdtv_cap, NULL, false); 18638c2ecf20Sopenharmony_ci v4l2_ctrl_add_handler(hdl_vbi_cap, hdl_loop_cap, NULL, false); 18648c2ecf20Sopenharmony_ci if (hdl_vbi_cap->error) 18658c2ecf20Sopenharmony_ci return hdl_vbi_cap->error; 18668c2ecf20Sopenharmony_ci dev->vbi_cap_dev.ctrl_handler = hdl_vbi_cap; 18678c2ecf20Sopenharmony_ci } 18688c2ecf20Sopenharmony_ci if (dev->has_vbi_out) { 18698c2ecf20Sopenharmony_ci v4l2_ctrl_add_handler(hdl_vbi_out, hdl_user_gen, NULL, false); 18708c2ecf20Sopenharmony_ci v4l2_ctrl_add_handler(hdl_vbi_out, hdl_streaming, NULL, false); 18718c2ecf20Sopenharmony_ci if (hdl_vbi_out->error) 18728c2ecf20Sopenharmony_ci return hdl_vbi_out->error; 18738c2ecf20Sopenharmony_ci dev->vbi_out_dev.ctrl_handler = hdl_vbi_out; 18748c2ecf20Sopenharmony_ci } 18758c2ecf20Sopenharmony_ci if (dev->has_radio_rx) { 18768c2ecf20Sopenharmony_ci v4l2_ctrl_add_handler(hdl_radio_rx, hdl_user_gen, NULL, false); 18778c2ecf20Sopenharmony_ci v4l2_ctrl_add_handler(hdl_radio_rx, hdl_user_aud, NULL, false); 18788c2ecf20Sopenharmony_ci if (hdl_radio_rx->error) 18798c2ecf20Sopenharmony_ci return hdl_radio_rx->error; 18808c2ecf20Sopenharmony_ci dev->radio_rx_dev.ctrl_handler = hdl_radio_rx; 18818c2ecf20Sopenharmony_ci } 18828c2ecf20Sopenharmony_ci if (dev->has_radio_tx) { 18838c2ecf20Sopenharmony_ci v4l2_ctrl_add_handler(hdl_radio_tx, hdl_user_gen, NULL, false); 18848c2ecf20Sopenharmony_ci v4l2_ctrl_add_handler(hdl_radio_tx, hdl_user_aud, NULL, false); 18858c2ecf20Sopenharmony_ci if (hdl_radio_tx->error) 18868c2ecf20Sopenharmony_ci return hdl_radio_tx->error; 18878c2ecf20Sopenharmony_ci dev->radio_tx_dev.ctrl_handler = hdl_radio_tx; 18888c2ecf20Sopenharmony_ci } 18898c2ecf20Sopenharmony_ci if (dev->has_sdr_cap) { 18908c2ecf20Sopenharmony_ci v4l2_ctrl_add_handler(hdl_sdr_cap, hdl_user_gen, NULL, false); 18918c2ecf20Sopenharmony_ci v4l2_ctrl_add_handler(hdl_sdr_cap, hdl_streaming, NULL, false); 18928c2ecf20Sopenharmony_ci if (hdl_sdr_cap->error) 18938c2ecf20Sopenharmony_ci return hdl_sdr_cap->error; 18948c2ecf20Sopenharmony_ci dev->sdr_cap_dev.ctrl_handler = hdl_sdr_cap; 18958c2ecf20Sopenharmony_ci } 18968c2ecf20Sopenharmony_ci if (dev->has_meta_cap) { 18978c2ecf20Sopenharmony_ci v4l2_ctrl_add_handler(hdl_meta_cap, hdl_user_gen, NULL, false); 18988c2ecf20Sopenharmony_ci v4l2_ctrl_add_handler(hdl_meta_cap, hdl_streaming, NULL, false); 18998c2ecf20Sopenharmony_ci if (hdl_meta_cap->error) 19008c2ecf20Sopenharmony_ci return hdl_meta_cap->error; 19018c2ecf20Sopenharmony_ci dev->meta_cap_dev.ctrl_handler = hdl_meta_cap; 19028c2ecf20Sopenharmony_ci } 19038c2ecf20Sopenharmony_ci if (dev->has_meta_out) { 19048c2ecf20Sopenharmony_ci v4l2_ctrl_add_handler(hdl_meta_out, hdl_user_gen, NULL, false); 19058c2ecf20Sopenharmony_ci v4l2_ctrl_add_handler(hdl_meta_out, hdl_streaming, NULL, false); 19068c2ecf20Sopenharmony_ci if (hdl_meta_out->error) 19078c2ecf20Sopenharmony_ci return hdl_meta_out->error; 19088c2ecf20Sopenharmony_ci dev->meta_out_dev.ctrl_handler = hdl_meta_out; 19098c2ecf20Sopenharmony_ci } 19108c2ecf20Sopenharmony_ci if (dev->has_touch_cap) { 19118c2ecf20Sopenharmony_ci v4l2_ctrl_add_handler(hdl_tch_cap, hdl_user_gen, NULL, false); 19128c2ecf20Sopenharmony_ci v4l2_ctrl_add_handler(hdl_tch_cap, hdl_streaming, NULL, false); 19138c2ecf20Sopenharmony_ci if (hdl_tch_cap->error) 19148c2ecf20Sopenharmony_ci return hdl_tch_cap->error; 19158c2ecf20Sopenharmony_ci dev->touch_cap_dev.ctrl_handler = hdl_tch_cap; 19168c2ecf20Sopenharmony_ci } 19178c2ecf20Sopenharmony_ci return 0; 19188c2ecf20Sopenharmony_ci} 19198c2ecf20Sopenharmony_ci 19208c2ecf20Sopenharmony_civoid vivid_free_controls(struct vivid_dev *dev) 19218c2ecf20Sopenharmony_ci{ 19228c2ecf20Sopenharmony_ci v4l2_ctrl_handler_free(&dev->ctrl_hdl_vid_cap); 19238c2ecf20Sopenharmony_ci v4l2_ctrl_handler_free(&dev->ctrl_hdl_vid_out); 19248c2ecf20Sopenharmony_ci v4l2_ctrl_handler_free(&dev->ctrl_hdl_vbi_cap); 19258c2ecf20Sopenharmony_ci v4l2_ctrl_handler_free(&dev->ctrl_hdl_vbi_out); 19268c2ecf20Sopenharmony_ci v4l2_ctrl_handler_free(&dev->ctrl_hdl_radio_rx); 19278c2ecf20Sopenharmony_ci v4l2_ctrl_handler_free(&dev->ctrl_hdl_radio_tx); 19288c2ecf20Sopenharmony_ci v4l2_ctrl_handler_free(&dev->ctrl_hdl_sdr_cap); 19298c2ecf20Sopenharmony_ci v4l2_ctrl_handler_free(&dev->ctrl_hdl_user_gen); 19308c2ecf20Sopenharmony_ci v4l2_ctrl_handler_free(&dev->ctrl_hdl_user_vid); 19318c2ecf20Sopenharmony_ci v4l2_ctrl_handler_free(&dev->ctrl_hdl_user_aud); 19328c2ecf20Sopenharmony_ci v4l2_ctrl_handler_free(&dev->ctrl_hdl_streaming); 19338c2ecf20Sopenharmony_ci v4l2_ctrl_handler_free(&dev->ctrl_hdl_sdtv_cap); 19348c2ecf20Sopenharmony_ci v4l2_ctrl_handler_free(&dev->ctrl_hdl_loop_cap); 19358c2ecf20Sopenharmony_ci v4l2_ctrl_handler_free(&dev->ctrl_hdl_fb); 19368c2ecf20Sopenharmony_ci v4l2_ctrl_handler_free(&dev->ctrl_hdl_meta_cap); 19378c2ecf20Sopenharmony_ci v4l2_ctrl_handler_free(&dev->ctrl_hdl_meta_out); 19388c2ecf20Sopenharmony_ci v4l2_ctrl_handler_free(&dev->ctrl_hdl_touch_cap); 19398c2ecf20Sopenharmony_ci} 1940