162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * vivid-ctrls.c - control support functions. 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved. 662306a36Sopenharmony_ci */ 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#include <linux/errno.h> 962306a36Sopenharmony_ci#include <linux/kernel.h> 1062306a36Sopenharmony_ci#include <linux/videodev2.h> 1162306a36Sopenharmony_ci#include <media/v4l2-event.h> 1262306a36Sopenharmony_ci#include <media/v4l2-common.h> 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_ci#include "vivid-core.h" 1562306a36Sopenharmony_ci#include "vivid-vid-cap.h" 1662306a36Sopenharmony_ci#include "vivid-vid-out.h" 1762306a36Sopenharmony_ci#include "vivid-vid-common.h" 1862306a36Sopenharmony_ci#include "vivid-radio-common.h" 1962306a36Sopenharmony_ci#include "vivid-osd.h" 2062306a36Sopenharmony_ci#include "vivid-ctrls.h" 2162306a36Sopenharmony_ci#include "vivid-cec.h" 2262306a36Sopenharmony_ci 2362306a36Sopenharmony_ci#define VIVID_CID_CUSTOM_BASE (V4L2_CID_USER_BASE | 0xf000) 2462306a36Sopenharmony_ci#define VIVID_CID_BUTTON (VIVID_CID_CUSTOM_BASE + 0) 2562306a36Sopenharmony_ci#define VIVID_CID_BOOLEAN (VIVID_CID_CUSTOM_BASE + 1) 2662306a36Sopenharmony_ci#define VIVID_CID_INTEGER (VIVID_CID_CUSTOM_BASE + 2) 2762306a36Sopenharmony_ci#define VIVID_CID_INTEGER64 (VIVID_CID_CUSTOM_BASE + 3) 2862306a36Sopenharmony_ci#define VIVID_CID_MENU (VIVID_CID_CUSTOM_BASE + 4) 2962306a36Sopenharmony_ci#define VIVID_CID_STRING (VIVID_CID_CUSTOM_BASE + 5) 3062306a36Sopenharmony_ci#define VIVID_CID_BITMASK (VIVID_CID_CUSTOM_BASE + 6) 3162306a36Sopenharmony_ci#define VIVID_CID_INTMENU (VIVID_CID_CUSTOM_BASE + 7) 3262306a36Sopenharmony_ci#define VIVID_CID_U32_ARRAY (VIVID_CID_CUSTOM_BASE + 8) 3362306a36Sopenharmony_ci#define VIVID_CID_U16_MATRIX (VIVID_CID_CUSTOM_BASE + 9) 3462306a36Sopenharmony_ci#define VIVID_CID_U8_4D_ARRAY (VIVID_CID_CUSTOM_BASE + 10) 3562306a36Sopenharmony_ci#define VIVID_CID_AREA (VIVID_CID_CUSTOM_BASE + 11) 3662306a36Sopenharmony_ci#define VIVID_CID_RO_INTEGER (VIVID_CID_CUSTOM_BASE + 12) 3762306a36Sopenharmony_ci#define VIVID_CID_U32_DYN_ARRAY (VIVID_CID_CUSTOM_BASE + 13) 3862306a36Sopenharmony_ci#define VIVID_CID_U8_PIXEL_ARRAY (VIVID_CID_CUSTOM_BASE + 14) 3962306a36Sopenharmony_ci#define VIVID_CID_S32_ARRAY (VIVID_CID_CUSTOM_BASE + 15) 4062306a36Sopenharmony_ci#define VIVID_CID_S64_ARRAY (VIVID_CID_CUSTOM_BASE + 16) 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_ci#define VIVID_CID_VIVID_BASE (0x00f00000 | 0xf000) 4362306a36Sopenharmony_ci#define VIVID_CID_VIVID_CLASS (0x00f00000 | 1) 4462306a36Sopenharmony_ci#define VIVID_CID_TEST_PATTERN (VIVID_CID_VIVID_BASE + 0) 4562306a36Sopenharmony_ci#define VIVID_CID_OSD_TEXT_MODE (VIVID_CID_VIVID_BASE + 1) 4662306a36Sopenharmony_ci#define VIVID_CID_HOR_MOVEMENT (VIVID_CID_VIVID_BASE + 2) 4762306a36Sopenharmony_ci#define VIVID_CID_VERT_MOVEMENT (VIVID_CID_VIVID_BASE + 3) 4862306a36Sopenharmony_ci#define VIVID_CID_SHOW_BORDER (VIVID_CID_VIVID_BASE + 4) 4962306a36Sopenharmony_ci#define VIVID_CID_SHOW_SQUARE (VIVID_CID_VIVID_BASE + 5) 5062306a36Sopenharmony_ci#define VIVID_CID_INSERT_SAV (VIVID_CID_VIVID_BASE + 6) 5162306a36Sopenharmony_ci#define VIVID_CID_INSERT_EAV (VIVID_CID_VIVID_BASE + 7) 5262306a36Sopenharmony_ci#define VIVID_CID_VBI_CAP_INTERLACED (VIVID_CID_VIVID_BASE + 8) 5362306a36Sopenharmony_ci#define VIVID_CID_INSERT_HDMI_VIDEO_GUARD_BAND (VIVID_CID_VIVID_BASE + 9) 5462306a36Sopenharmony_ci 5562306a36Sopenharmony_ci#define VIVID_CID_HFLIP (VIVID_CID_VIVID_BASE + 20) 5662306a36Sopenharmony_ci#define VIVID_CID_VFLIP (VIVID_CID_VIVID_BASE + 21) 5762306a36Sopenharmony_ci#define VIVID_CID_STD_ASPECT_RATIO (VIVID_CID_VIVID_BASE + 22) 5862306a36Sopenharmony_ci#define VIVID_CID_DV_TIMINGS_ASPECT_RATIO (VIVID_CID_VIVID_BASE + 23) 5962306a36Sopenharmony_ci#define VIVID_CID_TSTAMP_SRC (VIVID_CID_VIVID_BASE + 24) 6062306a36Sopenharmony_ci#define VIVID_CID_COLORSPACE (VIVID_CID_VIVID_BASE + 25) 6162306a36Sopenharmony_ci#define VIVID_CID_XFER_FUNC (VIVID_CID_VIVID_BASE + 26) 6262306a36Sopenharmony_ci#define VIVID_CID_YCBCR_ENC (VIVID_CID_VIVID_BASE + 27) 6362306a36Sopenharmony_ci#define VIVID_CID_QUANTIZATION (VIVID_CID_VIVID_BASE + 28) 6462306a36Sopenharmony_ci#define VIVID_CID_LIMITED_RGB_RANGE (VIVID_CID_VIVID_BASE + 29) 6562306a36Sopenharmony_ci#define VIVID_CID_ALPHA_MODE (VIVID_CID_VIVID_BASE + 30) 6662306a36Sopenharmony_ci#define VIVID_CID_HAS_CROP_CAP (VIVID_CID_VIVID_BASE + 31) 6762306a36Sopenharmony_ci#define VIVID_CID_HAS_COMPOSE_CAP (VIVID_CID_VIVID_BASE + 32) 6862306a36Sopenharmony_ci#define VIVID_CID_HAS_SCALER_CAP (VIVID_CID_VIVID_BASE + 33) 6962306a36Sopenharmony_ci#define VIVID_CID_HAS_CROP_OUT (VIVID_CID_VIVID_BASE + 34) 7062306a36Sopenharmony_ci#define VIVID_CID_HAS_COMPOSE_OUT (VIVID_CID_VIVID_BASE + 35) 7162306a36Sopenharmony_ci#define VIVID_CID_HAS_SCALER_OUT (VIVID_CID_VIVID_BASE + 36) 7262306a36Sopenharmony_ci#define VIVID_CID_LOOP_VIDEO (VIVID_CID_VIVID_BASE + 37) 7362306a36Sopenharmony_ci#define VIVID_CID_SEQ_WRAP (VIVID_CID_VIVID_BASE + 38) 7462306a36Sopenharmony_ci#define VIVID_CID_TIME_WRAP (VIVID_CID_VIVID_BASE + 39) 7562306a36Sopenharmony_ci#define VIVID_CID_MAX_EDID_BLOCKS (VIVID_CID_VIVID_BASE + 40) 7662306a36Sopenharmony_ci#define VIVID_CID_PERCENTAGE_FILL (VIVID_CID_VIVID_BASE + 41) 7762306a36Sopenharmony_ci#define VIVID_CID_REDUCED_FPS (VIVID_CID_VIVID_BASE + 42) 7862306a36Sopenharmony_ci#define VIVID_CID_HSV_ENC (VIVID_CID_VIVID_BASE + 43) 7962306a36Sopenharmony_ci#define VIVID_CID_DISPLAY_PRESENT (VIVID_CID_VIVID_BASE + 44) 8062306a36Sopenharmony_ci 8162306a36Sopenharmony_ci#define VIVID_CID_STD_SIGNAL_MODE (VIVID_CID_VIVID_BASE + 60) 8262306a36Sopenharmony_ci#define VIVID_CID_STANDARD (VIVID_CID_VIVID_BASE + 61) 8362306a36Sopenharmony_ci#define VIVID_CID_DV_TIMINGS_SIGNAL_MODE (VIVID_CID_VIVID_BASE + 62) 8462306a36Sopenharmony_ci#define VIVID_CID_DV_TIMINGS (VIVID_CID_VIVID_BASE + 63) 8562306a36Sopenharmony_ci#define VIVID_CID_PERC_DROPPED (VIVID_CID_VIVID_BASE + 64) 8662306a36Sopenharmony_ci#define VIVID_CID_DISCONNECT (VIVID_CID_VIVID_BASE + 65) 8762306a36Sopenharmony_ci#define VIVID_CID_DQBUF_ERROR (VIVID_CID_VIVID_BASE + 66) 8862306a36Sopenharmony_ci#define VIVID_CID_QUEUE_SETUP_ERROR (VIVID_CID_VIVID_BASE + 67) 8962306a36Sopenharmony_ci#define VIVID_CID_BUF_PREPARE_ERROR (VIVID_CID_VIVID_BASE + 68) 9062306a36Sopenharmony_ci#define VIVID_CID_START_STR_ERROR (VIVID_CID_VIVID_BASE + 69) 9162306a36Sopenharmony_ci#define VIVID_CID_QUEUE_ERROR (VIVID_CID_VIVID_BASE + 70) 9262306a36Sopenharmony_ci#define VIVID_CID_CLEAR_FB (VIVID_CID_VIVID_BASE + 71) 9362306a36Sopenharmony_ci#define VIVID_CID_REQ_VALIDATE_ERROR (VIVID_CID_VIVID_BASE + 72) 9462306a36Sopenharmony_ci 9562306a36Sopenharmony_ci#define VIVID_CID_RADIO_SEEK_MODE (VIVID_CID_VIVID_BASE + 90) 9662306a36Sopenharmony_ci#define VIVID_CID_RADIO_SEEK_PROG_LIM (VIVID_CID_VIVID_BASE + 91) 9762306a36Sopenharmony_ci#define VIVID_CID_RADIO_RX_RDS_RBDS (VIVID_CID_VIVID_BASE + 92) 9862306a36Sopenharmony_ci#define VIVID_CID_RADIO_RX_RDS_BLOCKIO (VIVID_CID_VIVID_BASE + 93) 9962306a36Sopenharmony_ci 10062306a36Sopenharmony_ci#define VIVID_CID_RADIO_TX_RDS_BLOCKIO (VIVID_CID_VIVID_BASE + 94) 10162306a36Sopenharmony_ci 10262306a36Sopenharmony_ci#define VIVID_CID_SDR_CAP_FM_DEVIATION (VIVID_CID_VIVID_BASE + 110) 10362306a36Sopenharmony_ci 10462306a36Sopenharmony_ci#define VIVID_CID_META_CAP_GENERATE_PTS (VIVID_CID_VIVID_BASE + 111) 10562306a36Sopenharmony_ci#define VIVID_CID_META_CAP_GENERATE_SCR (VIVID_CID_VIVID_BASE + 112) 10662306a36Sopenharmony_ci 10762306a36Sopenharmony_ci/* General User Controls */ 10862306a36Sopenharmony_ci 10962306a36Sopenharmony_cistatic void vivid_unregister_dev(bool valid, struct video_device *vdev) 11062306a36Sopenharmony_ci{ 11162306a36Sopenharmony_ci if (!valid) 11262306a36Sopenharmony_ci return; 11362306a36Sopenharmony_ci clear_bit(V4L2_FL_REGISTERED, &vdev->flags); 11462306a36Sopenharmony_ci v4l2_event_wake_all(vdev); 11562306a36Sopenharmony_ci} 11662306a36Sopenharmony_ci 11762306a36Sopenharmony_cistatic int vivid_user_gen_s_ctrl(struct v4l2_ctrl *ctrl) 11862306a36Sopenharmony_ci{ 11962306a36Sopenharmony_ci struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_user_gen); 12062306a36Sopenharmony_ci 12162306a36Sopenharmony_ci switch (ctrl->id) { 12262306a36Sopenharmony_ci case VIVID_CID_DISCONNECT: 12362306a36Sopenharmony_ci v4l2_info(&dev->v4l2_dev, "disconnect\n"); 12462306a36Sopenharmony_ci dev->disconnect_error = true; 12562306a36Sopenharmony_ci vivid_unregister_dev(dev->has_vid_cap, &dev->vid_cap_dev); 12662306a36Sopenharmony_ci vivid_unregister_dev(dev->has_vid_out, &dev->vid_out_dev); 12762306a36Sopenharmony_ci vivid_unregister_dev(dev->has_vbi_cap, &dev->vbi_cap_dev); 12862306a36Sopenharmony_ci vivid_unregister_dev(dev->has_vbi_out, &dev->vbi_out_dev); 12962306a36Sopenharmony_ci vivid_unregister_dev(dev->has_radio_rx, &dev->radio_rx_dev); 13062306a36Sopenharmony_ci vivid_unregister_dev(dev->has_radio_tx, &dev->radio_tx_dev); 13162306a36Sopenharmony_ci vivid_unregister_dev(dev->has_sdr_cap, &dev->sdr_cap_dev); 13262306a36Sopenharmony_ci vivid_unregister_dev(dev->has_meta_cap, &dev->meta_cap_dev); 13362306a36Sopenharmony_ci vivid_unregister_dev(dev->has_meta_out, &dev->meta_out_dev); 13462306a36Sopenharmony_ci vivid_unregister_dev(dev->has_touch_cap, &dev->touch_cap_dev); 13562306a36Sopenharmony_ci break; 13662306a36Sopenharmony_ci case VIVID_CID_BUTTON: 13762306a36Sopenharmony_ci dev->button_pressed = 30; 13862306a36Sopenharmony_ci break; 13962306a36Sopenharmony_ci } 14062306a36Sopenharmony_ci return 0; 14162306a36Sopenharmony_ci} 14262306a36Sopenharmony_ci 14362306a36Sopenharmony_cistatic const struct v4l2_ctrl_ops vivid_user_gen_ctrl_ops = { 14462306a36Sopenharmony_ci .s_ctrl = vivid_user_gen_s_ctrl, 14562306a36Sopenharmony_ci}; 14662306a36Sopenharmony_ci 14762306a36Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_button = { 14862306a36Sopenharmony_ci .ops = &vivid_user_gen_ctrl_ops, 14962306a36Sopenharmony_ci .id = VIVID_CID_BUTTON, 15062306a36Sopenharmony_ci .name = "Button", 15162306a36Sopenharmony_ci .type = V4L2_CTRL_TYPE_BUTTON, 15262306a36Sopenharmony_ci}; 15362306a36Sopenharmony_ci 15462306a36Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_boolean = { 15562306a36Sopenharmony_ci .ops = &vivid_user_gen_ctrl_ops, 15662306a36Sopenharmony_ci .id = VIVID_CID_BOOLEAN, 15762306a36Sopenharmony_ci .name = "Boolean", 15862306a36Sopenharmony_ci .type = V4L2_CTRL_TYPE_BOOLEAN, 15962306a36Sopenharmony_ci .min = 0, 16062306a36Sopenharmony_ci .max = 1, 16162306a36Sopenharmony_ci .step = 1, 16262306a36Sopenharmony_ci .def = 1, 16362306a36Sopenharmony_ci}; 16462306a36Sopenharmony_ci 16562306a36Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_int32 = { 16662306a36Sopenharmony_ci .ops = &vivid_user_gen_ctrl_ops, 16762306a36Sopenharmony_ci .id = VIVID_CID_INTEGER, 16862306a36Sopenharmony_ci .name = "Integer 32 Bits", 16962306a36Sopenharmony_ci .type = V4L2_CTRL_TYPE_INTEGER, 17062306a36Sopenharmony_ci .min = 0xffffffff80000000ULL, 17162306a36Sopenharmony_ci .max = 0x7fffffff, 17262306a36Sopenharmony_ci .step = 1, 17362306a36Sopenharmony_ci}; 17462306a36Sopenharmony_ci 17562306a36Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_int64 = { 17662306a36Sopenharmony_ci .ops = &vivid_user_gen_ctrl_ops, 17762306a36Sopenharmony_ci .id = VIVID_CID_INTEGER64, 17862306a36Sopenharmony_ci .name = "Integer 64 Bits", 17962306a36Sopenharmony_ci .type = V4L2_CTRL_TYPE_INTEGER64, 18062306a36Sopenharmony_ci .min = 0x8000000000000000ULL, 18162306a36Sopenharmony_ci .max = 0x7fffffffffffffffLL, 18262306a36Sopenharmony_ci .step = 1, 18362306a36Sopenharmony_ci}; 18462306a36Sopenharmony_ci 18562306a36Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_u32_array = { 18662306a36Sopenharmony_ci .ops = &vivid_user_gen_ctrl_ops, 18762306a36Sopenharmony_ci .id = VIVID_CID_U32_ARRAY, 18862306a36Sopenharmony_ci .name = "U32 1 Element Array", 18962306a36Sopenharmony_ci .type = V4L2_CTRL_TYPE_U32, 19062306a36Sopenharmony_ci .def = 0x18, 19162306a36Sopenharmony_ci .min = 0x10, 19262306a36Sopenharmony_ci .max = 0x20000, 19362306a36Sopenharmony_ci .step = 1, 19462306a36Sopenharmony_ci .dims = { 1 }, 19562306a36Sopenharmony_ci}; 19662306a36Sopenharmony_ci 19762306a36Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_u32_dyn_array = { 19862306a36Sopenharmony_ci .ops = &vivid_user_gen_ctrl_ops, 19962306a36Sopenharmony_ci .id = VIVID_CID_U32_DYN_ARRAY, 20062306a36Sopenharmony_ci .name = "U32 Dynamic Array", 20162306a36Sopenharmony_ci .type = V4L2_CTRL_TYPE_U32, 20262306a36Sopenharmony_ci .flags = V4L2_CTRL_FLAG_DYNAMIC_ARRAY, 20362306a36Sopenharmony_ci .def = 50, 20462306a36Sopenharmony_ci .min = 10, 20562306a36Sopenharmony_ci .max = 90, 20662306a36Sopenharmony_ci .step = 1, 20762306a36Sopenharmony_ci .dims = { 100 }, 20862306a36Sopenharmony_ci}; 20962306a36Sopenharmony_ci 21062306a36Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_u16_matrix = { 21162306a36Sopenharmony_ci .ops = &vivid_user_gen_ctrl_ops, 21262306a36Sopenharmony_ci .id = VIVID_CID_U16_MATRIX, 21362306a36Sopenharmony_ci .name = "U16 8x16 Matrix", 21462306a36Sopenharmony_ci .type = V4L2_CTRL_TYPE_U16, 21562306a36Sopenharmony_ci .def = 0x18, 21662306a36Sopenharmony_ci .min = 0x10, 21762306a36Sopenharmony_ci .max = 0x2000, 21862306a36Sopenharmony_ci .step = 1, 21962306a36Sopenharmony_ci .dims = { 8, 16 }, 22062306a36Sopenharmony_ci}; 22162306a36Sopenharmony_ci 22262306a36Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_u8_4d_array = { 22362306a36Sopenharmony_ci .ops = &vivid_user_gen_ctrl_ops, 22462306a36Sopenharmony_ci .id = VIVID_CID_U8_4D_ARRAY, 22562306a36Sopenharmony_ci .name = "U8 2x3x4x5 Array", 22662306a36Sopenharmony_ci .type = V4L2_CTRL_TYPE_U8, 22762306a36Sopenharmony_ci .def = 0x18, 22862306a36Sopenharmony_ci .min = 0x10, 22962306a36Sopenharmony_ci .max = 0x20, 23062306a36Sopenharmony_ci .step = 1, 23162306a36Sopenharmony_ci .dims = { 2, 3, 4, 5 }, 23262306a36Sopenharmony_ci}; 23362306a36Sopenharmony_ci 23462306a36Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_u8_pixel_array = { 23562306a36Sopenharmony_ci .ops = &vivid_user_gen_ctrl_ops, 23662306a36Sopenharmony_ci .id = VIVID_CID_U8_PIXEL_ARRAY, 23762306a36Sopenharmony_ci .name = "U8 Pixel Array", 23862306a36Sopenharmony_ci .type = V4L2_CTRL_TYPE_U8, 23962306a36Sopenharmony_ci .def = 0x80, 24062306a36Sopenharmony_ci .min = 0x00, 24162306a36Sopenharmony_ci .max = 0xff, 24262306a36Sopenharmony_ci .step = 1, 24362306a36Sopenharmony_ci .dims = { 640 / PIXEL_ARRAY_DIV, 360 / PIXEL_ARRAY_DIV }, 24462306a36Sopenharmony_ci}; 24562306a36Sopenharmony_ci 24662306a36Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_s32_array = { 24762306a36Sopenharmony_ci .ops = &vivid_user_gen_ctrl_ops, 24862306a36Sopenharmony_ci .id = VIVID_CID_S32_ARRAY, 24962306a36Sopenharmony_ci .name = "S32 2 Element Array", 25062306a36Sopenharmony_ci .type = V4L2_CTRL_TYPE_INTEGER, 25162306a36Sopenharmony_ci .def = 2, 25262306a36Sopenharmony_ci .min = -10, 25362306a36Sopenharmony_ci .max = 10, 25462306a36Sopenharmony_ci .step = 1, 25562306a36Sopenharmony_ci .dims = { 2 }, 25662306a36Sopenharmony_ci}; 25762306a36Sopenharmony_ci 25862306a36Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_s64_array = { 25962306a36Sopenharmony_ci .ops = &vivid_user_gen_ctrl_ops, 26062306a36Sopenharmony_ci .id = VIVID_CID_S64_ARRAY, 26162306a36Sopenharmony_ci .name = "S64 5 Element Array", 26262306a36Sopenharmony_ci .type = V4L2_CTRL_TYPE_INTEGER64, 26362306a36Sopenharmony_ci .def = 4, 26462306a36Sopenharmony_ci .min = -10, 26562306a36Sopenharmony_ci .max = 10, 26662306a36Sopenharmony_ci .step = 1, 26762306a36Sopenharmony_ci .dims = { 5 }, 26862306a36Sopenharmony_ci}; 26962306a36Sopenharmony_ci 27062306a36Sopenharmony_cistatic const char * const vivid_ctrl_menu_strings[] = { 27162306a36Sopenharmony_ci "Menu Item 0 (Skipped)", 27262306a36Sopenharmony_ci "Menu Item 1", 27362306a36Sopenharmony_ci "Menu Item 2 (Skipped)", 27462306a36Sopenharmony_ci "Menu Item 3", 27562306a36Sopenharmony_ci "Menu Item 4", 27662306a36Sopenharmony_ci "Menu Item 5 (Skipped)", 27762306a36Sopenharmony_ci NULL, 27862306a36Sopenharmony_ci}; 27962306a36Sopenharmony_ci 28062306a36Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_menu = { 28162306a36Sopenharmony_ci .ops = &vivid_user_gen_ctrl_ops, 28262306a36Sopenharmony_ci .id = VIVID_CID_MENU, 28362306a36Sopenharmony_ci .name = "Menu", 28462306a36Sopenharmony_ci .type = V4L2_CTRL_TYPE_MENU, 28562306a36Sopenharmony_ci .min = 1, 28662306a36Sopenharmony_ci .max = 4, 28762306a36Sopenharmony_ci .def = 3, 28862306a36Sopenharmony_ci .menu_skip_mask = 0x04, 28962306a36Sopenharmony_ci .qmenu = vivid_ctrl_menu_strings, 29062306a36Sopenharmony_ci}; 29162306a36Sopenharmony_ci 29262306a36Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_string = { 29362306a36Sopenharmony_ci .ops = &vivid_user_gen_ctrl_ops, 29462306a36Sopenharmony_ci .id = VIVID_CID_STRING, 29562306a36Sopenharmony_ci .name = "String", 29662306a36Sopenharmony_ci .type = V4L2_CTRL_TYPE_STRING, 29762306a36Sopenharmony_ci .min = 2, 29862306a36Sopenharmony_ci .max = 4, 29962306a36Sopenharmony_ci .step = 1, 30062306a36Sopenharmony_ci}; 30162306a36Sopenharmony_ci 30262306a36Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_bitmask = { 30362306a36Sopenharmony_ci .ops = &vivid_user_gen_ctrl_ops, 30462306a36Sopenharmony_ci .id = VIVID_CID_BITMASK, 30562306a36Sopenharmony_ci .name = "Bitmask", 30662306a36Sopenharmony_ci .type = V4L2_CTRL_TYPE_BITMASK, 30762306a36Sopenharmony_ci .def = 0x80002000, 30862306a36Sopenharmony_ci .min = 0, 30962306a36Sopenharmony_ci .max = 0x80402010, 31062306a36Sopenharmony_ci .step = 0, 31162306a36Sopenharmony_ci}; 31262306a36Sopenharmony_ci 31362306a36Sopenharmony_cistatic const s64 vivid_ctrl_int_menu_values[] = { 31462306a36Sopenharmony_ci 1, 1, 2, 3, 5, 8, 13, 21, 42, 31562306a36Sopenharmony_ci}; 31662306a36Sopenharmony_ci 31762306a36Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_int_menu = { 31862306a36Sopenharmony_ci .ops = &vivid_user_gen_ctrl_ops, 31962306a36Sopenharmony_ci .id = VIVID_CID_INTMENU, 32062306a36Sopenharmony_ci .name = "Integer Menu", 32162306a36Sopenharmony_ci .type = V4L2_CTRL_TYPE_INTEGER_MENU, 32262306a36Sopenharmony_ci .min = 1, 32362306a36Sopenharmony_ci .max = 8, 32462306a36Sopenharmony_ci .def = 4, 32562306a36Sopenharmony_ci .menu_skip_mask = 0x02, 32662306a36Sopenharmony_ci .qmenu_int = vivid_ctrl_int_menu_values, 32762306a36Sopenharmony_ci}; 32862306a36Sopenharmony_ci 32962306a36Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_disconnect = { 33062306a36Sopenharmony_ci .ops = &vivid_user_gen_ctrl_ops, 33162306a36Sopenharmony_ci .id = VIVID_CID_DISCONNECT, 33262306a36Sopenharmony_ci .name = "Disconnect", 33362306a36Sopenharmony_ci .type = V4L2_CTRL_TYPE_BUTTON, 33462306a36Sopenharmony_ci}; 33562306a36Sopenharmony_ci 33662306a36Sopenharmony_cistatic const struct v4l2_area area = { 33762306a36Sopenharmony_ci .width = 1000, 33862306a36Sopenharmony_ci .height = 2000, 33962306a36Sopenharmony_ci}; 34062306a36Sopenharmony_ci 34162306a36Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_area = { 34262306a36Sopenharmony_ci .ops = &vivid_user_gen_ctrl_ops, 34362306a36Sopenharmony_ci .id = VIVID_CID_AREA, 34462306a36Sopenharmony_ci .name = "Area", 34562306a36Sopenharmony_ci .type = V4L2_CTRL_TYPE_AREA, 34662306a36Sopenharmony_ci .p_def.p_const = &area, 34762306a36Sopenharmony_ci}; 34862306a36Sopenharmony_ci 34962306a36Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_ro_int32 = { 35062306a36Sopenharmony_ci .ops = &vivid_user_gen_ctrl_ops, 35162306a36Sopenharmony_ci .id = VIVID_CID_RO_INTEGER, 35262306a36Sopenharmony_ci .name = "Read-Only Integer 32 Bits", 35362306a36Sopenharmony_ci .type = V4L2_CTRL_TYPE_INTEGER, 35462306a36Sopenharmony_ci .flags = V4L2_CTRL_FLAG_READ_ONLY, 35562306a36Sopenharmony_ci .min = 0, 35662306a36Sopenharmony_ci .max = 255, 35762306a36Sopenharmony_ci .step = 1, 35862306a36Sopenharmony_ci}; 35962306a36Sopenharmony_ci 36062306a36Sopenharmony_ci/* Framebuffer Controls */ 36162306a36Sopenharmony_ci 36262306a36Sopenharmony_cistatic int vivid_fb_s_ctrl(struct v4l2_ctrl *ctrl) 36362306a36Sopenharmony_ci{ 36462306a36Sopenharmony_ci struct vivid_dev *dev = container_of(ctrl->handler, 36562306a36Sopenharmony_ci struct vivid_dev, ctrl_hdl_fb); 36662306a36Sopenharmony_ci 36762306a36Sopenharmony_ci switch (ctrl->id) { 36862306a36Sopenharmony_ci case VIVID_CID_CLEAR_FB: 36962306a36Sopenharmony_ci vivid_clear_fb(dev); 37062306a36Sopenharmony_ci break; 37162306a36Sopenharmony_ci } 37262306a36Sopenharmony_ci return 0; 37362306a36Sopenharmony_ci} 37462306a36Sopenharmony_ci 37562306a36Sopenharmony_cistatic const struct v4l2_ctrl_ops vivid_fb_ctrl_ops = { 37662306a36Sopenharmony_ci .s_ctrl = vivid_fb_s_ctrl, 37762306a36Sopenharmony_ci}; 37862306a36Sopenharmony_ci 37962306a36Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_clear_fb = { 38062306a36Sopenharmony_ci .ops = &vivid_fb_ctrl_ops, 38162306a36Sopenharmony_ci .id = VIVID_CID_CLEAR_FB, 38262306a36Sopenharmony_ci .name = "Clear Framebuffer", 38362306a36Sopenharmony_ci .type = V4L2_CTRL_TYPE_BUTTON, 38462306a36Sopenharmony_ci}; 38562306a36Sopenharmony_ci 38662306a36Sopenharmony_ci 38762306a36Sopenharmony_ci/* Video User Controls */ 38862306a36Sopenharmony_ci 38962306a36Sopenharmony_cistatic int vivid_user_vid_g_volatile_ctrl(struct v4l2_ctrl *ctrl) 39062306a36Sopenharmony_ci{ 39162306a36Sopenharmony_ci struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_user_vid); 39262306a36Sopenharmony_ci 39362306a36Sopenharmony_ci switch (ctrl->id) { 39462306a36Sopenharmony_ci case V4L2_CID_AUTOGAIN: 39562306a36Sopenharmony_ci dev->gain->val = (jiffies_to_msecs(jiffies) / 1000) & 0xff; 39662306a36Sopenharmony_ci break; 39762306a36Sopenharmony_ci } 39862306a36Sopenharmony_ci return 0; 39962306a36Sopenharmony_ci} 40062306a36Sopenharmony_ci 40162306a36Sopenharmony_cistatic int vivid_user_vid_s_ctrl(struct v4l2_ctrl *ctrl) 40262306a36Sopenharmony_ci{ 40362306a36Sopenharmony_ci struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_user_vid); 40462306a36Sopenharmony_ci 40562306a36Sopenharmony_ci switch (ctrl->id) { 40662306a36Sopenharmony_ci case V4L2_CID_BRIGHTNESS: 40762306a36Sopenharmony_ci dev->input_brightness[dev->input] = ctrl->val - dev->input * 128; 40862306a36Sopenharmony_ci tpg_s_brightness(&dev->tpg, dev->input_brightness[dev->input]); 40962306a36Sopenharmony_ci break; 41062306a36Sopenharmony_ci case V4L2_CID_CONTRAST: 41162306a36Sopenharmony_ci tpg_s_contrast(&dev->tpg, ctrl->val); 41262306a36Sopenharmony_ci break; 41362306a36Sopenharmony_ci case V4L2_CID_SATURATION: 41462306a36Sopenharmony_ci tpg_s_saturation(&dev->tpg, ctrl->val); 41562306a36Sopenharmony_ci break; 41662306a36Sopenharmony_ci case V4L2_CID_HUE: 41762306a36Sopenharmony_ci tpg_s_hue(&dev->tpg, ctrl->val); 41862306a36Sopenharmony_ci break; 41962306a36Sopenharmony_ci case V4L2_CID_HFLIP: 42062306a36Sopenharmony_ci dev->hflip = ctrl->val; 42162306a36Sopenharmony_ci tpg_s_hflip(&dev->tpg, dev->sensor_hflip ^ dev->hflip); 42262306a36Sopenharmony_ci break; 42362306a36Sopenharmony_ci case V4L2_CID_VFLIP: 42462306a36Sopenharmony_ci dev->vflip = ctrl->val; 42562306a36Sopenharmony_ci tpg_s_vflip(&dev->tpg, dev->sensor_vflip ^ dev->vflip); 42662306a36Sopenharmony_ci break; 42762306a36Sopenharmony_ci case V4L2_CID_ALPHA_COMPONENT: 42862306a36Sopenharmony_ci tpg_s_alpha_component(&dev->tpg, ctrl->val); 42962306a36Sopenharmony_ci break; 43062306a36Sopenharmony_ci } 43162306a36Sopenharmony_ci return 0; 43262306a36Sopenharmony_ci} 43362306a36Sopenharmony_ci 43462306a36Sopenharmony_cistatic const struct v4l2_ctrl_ops vivid_user_vid_ctrl_ops = { 43562306a36Sopenharmony_ci .g_volatile_ctrl = vivid_user_vid_g_volatile_ctrl, 43662306a36Sopenharmony_ci .s_ctrl = vivid_user_vid_s_ctrl, 43762306a36Sopenharmony_ci}; 43862306a36Sopenharmony_ci 43962306a36Sopenharmony_ci 44062306a36Sopenharmony_ci/* Video Capture Controls */ 44162306a36Sopenharmony_ci 44262306a36Sopenharmony_cistatic int vivid_vid_cap_s_ctrl(struct v4l2_ctrl *ctrl) 44362306a36Sopenharmony_ci{ 44462306a36Sopenharmony_ci static const u32 colorspaces[] = { 44562306a36Sopenharmony_ci V4L2_COLORSPACE_SMPTE170M, 44662306a36Sopenharmony_ci V4L2_COLORSPACE_REC709, 44762306a36Sopenharmony_ci V4L2_COLORSPACE_SRGB, 44862306a36Sopenharmony_ci V4L2_COLORSPACE_OPRGB, 44962306a36Sopenharmony_ci V4L2_COLORSPACE_BT2020, 45062306a36Sopenharmony_ci V4L2_COLORSPACE_DCI_P3, 45162306a36Sopenharmony_ci V4L2_COLORSPACE_SMPTE240M, 45262306a36Sopenharmony_ci V4L2_COLORSPACE_470_SYSTEM_M, 45362306a36Sopenharmony_ci V4L2_COLORSPACE_470_SYSTEM_BG, 45462306a36Sopenharmony_ci }; 45562306a36Sopenharmony_ci struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_vid_cap); 45662306a36Sopenharmony_ci unsigned int i, j; 45762306a36Sopenharmony_ci 45862306a36Sopenharmony_ci switch (ctrl->id) { 45962306a36Sopenharmony_ci case VIVID_CID_TEST_PATTERN: 46062306a36Sopenharmony_ci vivid_update_quality(dev); 46162306a36Sopenharmony_ci tpg_s_pattern(&dev->tpg, ctrl->val); 46262306a36Sopenharmony_ci break; 46362306a36Sopenharmony_ci case VIVID_CID_COLORSPACE: 46462306a36Sopenharmony_ci tpg_s_colorspace(&dev->tpg, colorspaces[ctrl->val]); 46562306a36Sopenharmony_ci vivid_send_source_change(dev, TV); 46662306a36Sopenharmony_ci vivid_send_source_change(dev, SVID); 46762306a36Sopenharmony_ci vivid_send_source_change(dev, HDMI); 46862306a36Sopenharmony_ci vivid_send_source_change(dev, WEBCAM); 46962306a36Sopenharmony_ci break; 47062306a36Sopenharmony_ci case VIVID_CID_XFER_FUNC: 47162306a36Sopenharmony_ci tpg_s_xfer_func(&dev->tpg, ctrl->val); 47262306a36Sopenharmony_ci vivid_send_source_change(dev, TV); 47362306a36Sopenharmony_ci vivid_send_source_change(dev, SVID); 47462306a36Sopenharmony_ci vivid_send_source_change(dev, HDMI); 47562306a36Sopenharmony_ci vivid_send_source_change(dev, WEBCAM); 47662306a36Sopenharmony_ci break; 47762306a36Sopenharmony_ci case VIVID_CID_YCBCR_ENC: 47862306a36Sopenharmony_ci tpg_s_ycbcr_enc(&dev->tpg, ctrl->val); 47962306a36Sopenharmony_ci vivid_send_source_change(dev, TV); 48062306a36Sopenharmony_ci vivid_send_source_change(dev, SVID); 48162306a36Sopenharmony_ci vivid_send_source_change(dev, HDMI); 48262306a36Sopenharmony_ci vivid_send_source_change(dev, WEBCAM); 48362306a36Sopenharmony_ci break; 48462306a36Sopenharmony_ci case VIVID_CID_HSV_ENC: 48562306a36Sopenharmony_ci tpg_s_hsv_enc(&dev->tpg, ctrl->val ? V4L2_HSV_ENC_256 : 48662306a36Sopenharmony_ci V4L2_HSV_ENC_180); 48762306a36Sopenharmony_ci vivid_send_source_change(dev, TV); 48862306a36Sopenharmony_ci vivid_send_source_change(dev, SVID); 48962306a36Sopenharmony_ci vivid_send_source_change(dev, HDMI); 49062306a36Sopenharmony_ci vivid_send_source_change(dev, WEBCAM); 49162306a36Sopenharmony_ci break; 49262306a36Sopenharmony_ci case VIVID_CID_QUANTIZATION: 49362306a36Sopenharmony_ci tpg_s_quantization(&dev->tpg, ctrl->val); 49462306a36Sopenharmony_ci vivid_send_source_change(dev, TV); 49562306a36Sopenharmony_ci vivid_send_source_change(dev, SVID); 49662306a36Sopenharmony_ci vivid_send_source_change(dev, HDMI); 49762306a36Sopenharmony_ci vivid_send_source_change(dev, WEBCAM); 49862306a36Sopenharmony_ci break; 49962306a36Sopenharmony_ci case V4L2_CID_DV_RX_RGB_RANGE: 50062306a36Sopenharmony_ci if (!vivid_is_hdmi_cap(dev)) 50162306a36Sopenharmony_ci break; 50262306a36Sopenharmony_ci tpg_s_rgb_range(&dev->tpg, ctrl->val); 50362306a36Sopenharmony_ci break; 50462306a36Sopenharmony_ci case VIVID_CID_LIMITED_RGB_RANGE: 50562306a36Sopenharmony_ci tpg_s_real_rgb_range(&dev->tpg, ctrl->val ? 50662306a36Sopenharmony_ci V4L2_DV_RGB_RANGE_LIMITED : V4L2_DV_RGB_RANGE_FULL); 50762306a36Sopenharmony_ci break; 50862306a36Sopenharmony_ci case VIVID_CID_ALPHA_MODE: 50962306a36Sopenharmony_ci tpg_s_alpha_mode(&dev->tpg, ctrl->val); 51062306a36Sopenharmony_ci break; 51162306a36Sopenharmony_ci case VIVID_CID_HOR_MOVEMENT: 51262306a36Sopenharmony_ci tpg_s_mv_hor_mode(&dev->tpg, ctrl->val); 51362306a36Sopenharmony_ci break; 51462306a36Sopenharmony_ci case VIVID_CID_VERT_MOVEMENT: 51562306a36Sopenharmony_ci tpg_s_mv_vert_mode(&dev->tpg, ctrl->val); 51662306a36Sopenharmony_ci break; 51762306a36Sopenharmony_ci case VIVID_CID_OSD_TEXT_MODE: 51862306a36Sopenharmony_ci dev->osd_mode = ctrl->val; 51962306a36Sopenharmony_ci break; 52062306a36Sopenharmony_ci case VIVID_CID_PERCENTAGE_FILL: 52162306a36Sopenharmony_ci tpg_s_perc_fill(&dev->tpg, ctrl->val); 52262306a36Sopenharmony_ci for (i = 0; i < VIDEO_MAX_FRAME; i++) 52362306a36Sopenharmony_ci dev->must_blank[i] = ctrl->val < 100; 52462306a36Sopenharmony_ci break; 52562306a36Sopenharmony_ci case VIVID_CID_INSERT_SAV: 52662306a36Sopenharmony_ci tpg_s_insert_sav(&dev->tpg, ctrl->val); 52762306a36Sopenharmony_ci break; 52862306a36Sopenharmony_ci case VIVID_CID_INSERT_EAV: 52962306a36Sopenharmony_ci tpg_s_insert_eav(&dev->tpg, ctrl->val); 53062306a36Sopenharmony_ci break; 53162306a36Sopenharmony_ci case VIVID_CID_INSERT_HDMI_VIDEO_GUARD_BAND: 53262306a36Sopenharmony_ci tpg_s_insert_hdmi_video_guard_band(&dev->tpg, ctrl->val); 53362306a36Sopenharmony_ci break; 53462306a36Sopenharmony_ci case VIVID_CID_HFLIP: 53562306a36Sopenharmony_ci dev->sensor_hflip = ctrl->val; 53662306a36Sopenharmony_ci tpg_s_hflip(&dev->tpg, dev->sensor_hflip ^ dev->hflip); 53762306a36Sopenharmony_ci break; 53862306a36Sopenharmony_ci case VIVID_CID_VFLIP: 53962306a36Sopenharmony_ci dev->sensor_vflip = ctrl->val; 54062306a36Sopenharmony_ci tpg_s_vflip(&dev->tpg, dev->sensor_vflip ^ dev->vflip); 54162306a36Sopenharmony_ci break; 54262306a36Sopenharmony_ci case VIVID_CID_REDUCED_FPS: 54362306a36Sopenharmony_ci dev->reduced_fps = ctrl->val; 54462306a36Sopenharmony_ci vivid_update_format_cap(dev, true); 54562306a36Sopenharmony_ci break; 54662306a36Sopenharmony_ci case VIVID_CID_HAS_CROP_CAP: 54762306a36Sopenharmony_ci dev->has_crop_cap = ctrl->val; 54862306a36Sopenharmony_ci vivid_update_format_cap(dev, true); 54962306a36Sopenharmony_ci break; 55062306a36Sopenharmony_ci case VIVID_CID_HAS_COMPOSE_CAP: 55162306a36Sopenharmony_ci dev->has_compose_cap = ctrl->val; 55262306a36Sopenharmony_ci vivid_update_format_cap(dev, true); 55362306a36Sopenharmony_ci break; 55462306a36Sopenharmony_ci case VIVID_CID_HAS_SCALER_CAP: 55562306a36Sopenharmony_ci dev->has_scaler_cap = ctrl->val; 55662306a36Sopenharmony_ci vivid_update_format_cap(dev, true); 55762306a36Sopenharmony_ci break; 55862306a36Sopenharmony_ci case VIVID_CID_SHOW_BORDER: 55962306a36Sopenharmony_ci tpg_s_show_border(&dev->tpg, ctrl->val); 56062306a36Sopenharmony_ci break; 56162306a36Sopenharmony_ci case VIVID_CID_SHOW_SQUARE: 56262306a36Sopenharmony_ci tpg_s_show_square(&dev->tpg, ctrl->val); 56362306a36Sopenharmony_ci break; 56462306a36Sopenharmony_ci case VIVID_CID_STD_ASPECT_RATIO: 56562306a36Sopenharmony_ci dev->std_aspect_ratio[dev->input] = ctrl->val; 56662306a36Sopenharmony_ci tpg_s_video_aspect(&dev->tpg, vivid_get_video_aspect(dev)); 56762306a36Sopenharmony_ci break; 56862306a36Sopenharmony_ci case VIVID_CID_DV_TIMINGS_SIGNAL_MODE: 56962306a36Sopenharmony_ci dev->dv_timings_signal_mode[dev->input] = 57062306a36Sopenharmony_ci dev->ctrl_dv_timings_signal_mode->val; 57162306a36Sopenharmony_ci dev->query_dv_timings[dev->input] = dev->ctrl_dv_timings->val; 57262306a36Sopenharmony_ci 57362306a36Sopenharmony_ci dev->power_present = 0; 57462306a36Sopenharmony_ci for (i = 0, j = 0; 57562306a36Sopenharmony_ci i < ARRAY_SIZE(dev->dv_timings_signal_mode); 57662306a36Sopenharmony_ci i++) 57762306a36Sopenharmony_ci if (dev->input_type[i] == HDMI) { 57862306a36Sopenharmony_ci if (dev->dv_timings_signal_mode[i] != NO_SIGNAL) 57962306a36Sopenharmony_ci dev->power_present |= (1 << j); 58062306a36Sopenharmony_ci j++; 58162306a36Sopenharmony_ci } 58262306a36Sopenharmony_ci __v4l2_ctrl_s_ctrl(dev->ctrl_rx_power_present, 58362306a36Sopenharmony_ci dev->power_present); 58462306a36Sopenharmony_ci 58562306a36Sopenharmony_ci v4l2_ctrl_activate(dev->ctrl_dv_timings, 58662306a36Sopenharmony_ci dev->dv_timings_signal_mode[dev->input] == 58762306a36Sopenharmony_ci SELECTED_DV_TIMINGS); 58862306a36Sopenharmony_ci 58962306a36Sopenharmony_ci vivid_update_quality(dev); 59062306a36Sopenharmony_ci vivid_send_source_change(dev, HDMI); 59162306a36Sopenharmony_ci break; 59262306a36Sopenharmony_ci case VIVID_CID_DV_TIMINGS_ASPECT_RATIO: 59362306a36Sopenharmony_ci dev->dv_timings_aspect_ratio[dev->input] = ctrl->val; 59462306a36Sopenharmony_ci tpg_s_video_aspect(&dev->tpg, vivid_get_video_aspect(dev)); 59562306a36Sopenharmony_ci break; 59662306a36Sopenharmony_ci case VIVID_CID_TSTAMP_SRC: 59762306a36Sopenharmony_ci dev->tstamp_src_is_soe = ctrl->val; 59862306a36Sopenharmony_ci dev->vb_vid_cap_q.timestamp_flags &= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK; 59962306a36Sopenharmony_ci if (dev->tstamp_src_is_soe) 60062306a36Sopenharmony_ci dev->vb_vid_cap_q.timestamp_flags |= V4L2_BUF_FLAG_TSTAMP_SRC_SOE; 60162306a36Sopenharmony_ci break; 60262306a36Sopenharmony_ci case VIVID_CID_MAX_EDID_BLOCKS: 60362306a36Sopenharmony_ci dev->edid_max_blocks = ctrl->val; 60462306a36Sopenharmony_ci if (dev->edid_blocks > dev->edid_max_blocks) 60562306a36Sopenharmony_ci dev->edid_blocks = dev->edid_max_blocks; 60662306a36Sopenharmony_ci break; 60762306a36Sopenharmony_ci } 60862306a36Sopenharmony_ci return 0; 60962306a36Sopenharmony_ci} 61062306a36Sopenharmony_ci 61162306a36Sopenharmony_cistatic const struct v4l2_ctrl_ops vivid_vid_cap_ctrl_ops = { 61262306a36Sopenharmony_ci .s_ctrl = vivid_vid_cap_s_ctrl, 61362306a36Sopenharmony_ci}; 61462306a36Sopenharmony_ci 61562306a36Sopenharmony_cistatic const char * const vivid_ctrl_hor_movement_strings[] = { 61662306a36Sopenharmony_ci "Move Left Fast", 61762306a36Sopenharmony_ci "Move Left", 61862306a36Sopenharmony_ci "Move Left Slow", 61962306a36Sopenharmony_ci "No Movement", 62062306a36Sopenharmony_ci "Move Right Slow", 62162306a36Sopenharmony_ci "Move Right", 62262306a36Sopenharmony_ci "Move Right Fast", 62362306a36Sopenharmony_ci NULL, 62462306a36Sopenharmony_ci}; 62562306a36Sopenharmony_ci 62662306a36Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_hor_movement = { 62762306a36Sopenharmony_ci .ops = &vivid_vid_cap_ctrl_ops, 62862306a36Sopenharmony_ci .id = VIVID_CID_HOR_MOVEMENT, 62962306a36Sopenharmony_ci .name = "Horizontal Movement", 63062306a36Sopenharmony_ci .type = V4L2_CTRL_TYPE_MENU, 63162306a36Sopenharmony_ci .max = TPG_MOVE_POS_FAST, 63262306a36Sopenharmony_ci .def = TPG_MOVE_NONE, 63362306a36Sopenharmony_ci .qmenu = vivid_ctrl_hor_movement_strings, 63462306a36Sopenharmony_ci}; 63562306a36Sopenharmony_ci 63662306a36Sopenharmony_cistatic const char * const vivid_ctrl_vert_movement_strings[] = { 63762306a36Sopenharmony_ci "Move Up Fast", 63862306a36Sopenharmony_ci "Move Up", 63962306a36Sopenharmony_ci "Move Up Slow", 64062306a36Sopenharmony_ci "No Movement", 64162306a36Sopenharmony_ci "Move Down Slow", 64262306a36Sopenharmony_ci "Move Down", 64362306a36Sopenharmony_ci "Move Down Fast", 64462306a36Sopenharmony_ci NULL, 64562306a36Sopenharmony_ci}; 64662306a36Sopenharmony_ci 64762306a36Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_vert_movement = { 64862306a36Sopenharmony_ci .ops = &vivid_vid_cap_ctrl_ops, 64962306a36Sopenharmony_ci .id = VIVID_CID_VERT_MOVEMENT, 65062306a36Sopenharmony_ci .name = "Vertical Movement", 65162306a36Sopenharmony_ci .type = V4L2_CTRL_TYPE_MENU, 65262306a36Sopenharmony_ci .max = TPG_MOVE_POS_FAST, 65362306a36Sopenharmony_ci .def = TPG_MOVE_NONE, 65462306a36Sopenharmony_ci .qmenu = vivid_ctrl_vert_movement_strings, 65562306a36Sopenharmony_ci}; 65662306a36Sopenharmony_ci 65762306a36Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_show_border = { 65862306a36Sopenharmony_ci .ops = &vivid_vid_cap_ctrl_ops, 65962306a36Sopenharmony_ci .id = VIVID_CID_SHOW_BORDER, 66062306a36Sopenharmony_ci .name = "Show Border", 66162306a36Sopenharmony_ci .type = V4L2_CTRL_TYPE_BOOLEAN, 66262306a36Sopenharmony_ci .max = 1, 66362306a36Sopenharmony_ci .step = 1, 66462306a36Sopenharmony_ci}; 66562306a36Sopenharmony_ci 66662306a36Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_show_square = { 66762306a36Sopenharmony_ci .ops = &vivid_vid_cap_ctrl_ops, 66862306a36Sopenharmony_ci .id = VIVID_CID_SHOW_SQUARE, 66962306a36Sopenharmony_ci .name = "Show Square", 67062306a36Sopenharmony_ci .type = V4L2_CTRL_TYPE_BOOLEAN, 67162306a36Sopenharmony_ci .max = 1, 67262306a36Sopenharmony_ci .step = 1, 67362306a36Sopenharmony_ci}; 67462306a36Sopenharmony_ci 67562306a36Sopenharmony_cistatic const char * const vivid_ctrl_osd_mode_strings[] = { 67662306a36Sopenharmony_ci "All", 67762306a36Sopenharmony_ci "Counters Only", 67862306a36Sopenharmony_ci "None", 67962306a36Sopenharmony_ci NULL, 68062306a36Sopenharmony_ci}; 68162306a36Sopenharmony_ci 68262306a36Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_osd_mode = { 68362306a36Sopenharmony_ci .ops = &vivid_vid_cap_ctrl_ops, 68462306a36Sopenharmony_ci .id = VIVID_CID_OSD_TEXT_MODE, 68562306a36Sopenharmony_ci .name = "OSD Text Mode", 68662306a36Sopenharmony_ci .type = V4L2_CTRL_TYPE_MENU, 68762306a36Sopenharmony_ci .max = ARRAY_SIZE(vivid_ctrl_osd_mode_strings) - 2, 68862306a36Sopenharmony_ci .qmenu = vivid_ctrl_osd_mode_strings, 68962306a36Sopenharmony_ci}; 69062306a36Sopenharmony_ci 69162306a36Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_perc_fill = { 69262306a36Sopenharmony_ci .ops = &vivid_vid_cap_ctrl_ops, 69362306a36Sopenharmony_ci .id = VIVID_CID_PERCENTAGE_FILL, 69462306a36Sopenharmony_ci .name = "Fill Percentage of Frame", 69562306a36Sopenharmony_ci .type = V4L2_CTRL_TYPE_INTEGER, 69662306a36Sopenharmony_ci .min = 0, 69762306a36Sopenharmony_ci .max = 100, 69862306a36Sopenharmony_ci .def = 100, 69962306a36Sopenharmony_ci .step = 1, 70062306a36Sopenharmony_ci}; 70162306a36Sopenharmony_ci 70262306a36Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_insert_sav = { 70362306a36Sopenharmony_ci .ops = &vivid_vid_cap_ctrl_ops, 70462306a36Sopenharmony_ci .id = VIVID_CID_INSERT_SAV, 70562306a36Sopenharmony_ci .name = "Insert SAV Code in Image", 70662306a36Sopenharmony_ci .type = V4L2_CTRL_TYPE_BOOLEAN, 70762306a36Sopenharmony_ci .max = 1, 70862306a36Sopenharmony_ci .step = 1, 70962306a36Sopenharmony_ci}; 71062306a36Sopenharmony_ci 71162306a36Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_insert_eav = { 71262306a36Sopenharmony_ci .ops = &vivid_vid_cap_ctrl_ops, 71362306a36Sopenharmony_ci .id = VIVID_CID_INSERT_EAV, 71462306a36Sopenharmony_ci .name = "Insert EAV Code in Image", 71562306a36Sopenharmony_ci .type = V4L2_CTRL_TYPE_BOOLEAN, 71662306a36Sopenharmony_ci .max = 1, 71762306a36Sopenharmony_ci .step = 1, 71862306a36Sopenharmony_ci}; 71962306a36Sopenharmony_ci 72062306a36Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_insert_hdmi_video_guard_band = { 72162306a36Sopenharmony_ci .ops = &vivid_vid_cap_ctrl_ops, 72262306a36Sopenharmony_ci .id = VIVID_CID_INSERT_HDMI_VIDEO_GUARD_BAND, 72362306a36Sopenharmony_ci .name = "Insert Video Guard Band", 72462306a36Sopenharmony_ci .type = V4L2_CTRL_TYPE_BOOLEAN, 72562306a36Sopenharmony_ci .max = 1, 72662306a36Sopenharmony_ci .step = 1, 72762306a36Sopenharmony_ci}; 72862306a36Sopenharmony_ci 72962306a36Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_hflip = { 73062306a36Sopenharmony_ci .ops = &vivid_vid_cap_ctrl_ops, 73162306a36Sopenharmony_ci .id = VIVID_CID_HFLIP, 73262306a36Sopenharmony_ci .name = "Sensor Flipped Horizontally", 73362306a36Sopenharmony_ci .type = V4L2_CTRL_TYPE_BOOLEAN, 73462306a36Sopenharmony_ci .max = 1, 73562306a36Sopenharmony_ci .step = 1, 73662306a36Sopenharmony_ci}; 73762306a36Sopenharmony_ci 73862306a36Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_vflip = { 73962306a36Sopenharmony_ci .ops = &vivid_vid_cap_ctrl_ops, 74062306a36Sopenharmony_ci .id = VIVID_CID_VFLIP, 74162306a36Sopenharmony_ci .name = "Sensor Flipped Vertically", 74262306a36Sopenharmony_ci .type = V4L2_CTRL_TYPE_BOOLEAN, 74362306a36Sopenharmony_ci .max = 1, 74462306a36Sopenharmony_ci .step = 1, 74562306a36Sopenharmony_ci}; 74662306a36Sopenharmony_ci 74762306a36Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_reduced_fps = { 74862306a36Sopenharmony_ci .ops = &vivid_vid_cap_ctrl_ops, 74962306a36Sopenharmony_ci .id = VIVID_CID_REDUCED_FPS, 75062306a36Sopenharmony_ci .name = "Reduced Framerate", 75162306a36Sopenharmony_ci .type = V4L2_CTRL_TYPE_BOOLEAN, 75262306a36Sopenharmony_ci .max = 1, 75362306a36Sopenharmony_ci .step = 1, 75462306a36Sopenharmony_ci}; 75562306a36Sopenharmony_ci 75662306a36Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_has_crop_cap = { 75762306a36Sopenharmony_ci .ops = &vivid_vid_cap_ctrl_ops, 75862306a36Sopenharmony_ci .id = VIVID_CID_HAS_CROP_CAP, 75962306a36Sopenharmony_ci .name = "Enable Capture Cropping", 76062306a36Sopenharmony_ci .type = V4L2_CTRL_TYPE_BOOLEAN, 76162306a36Sopenharmony_ci .max = 1, 76262306a36Sopenharmony_ci .def = 1, 76362306a36Sopenharmony_ci .step = 1, 76462306a36Sopenharmony_ci}; 76562306a36Sopenharmony_ci 76662306a36Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_has_compose_cap = { 76762306a36Sopenharmony_ci .ops = &vivid_vid_cap_ctrl_ops, 76862306a36Sopenharmony_ci .id = VIVID_CID_HAS_COMPOSE_CAP, 76962306a36Sopenharmony_ci .name = "Enable Capture Composing", 77062306a36Sopenharmony_ci .type = V4L2_CTRL_TYPE_BOOLEAN, 77162306a36Sopenharmony_ci .max = 1, 77262306a36Sopenharmony_ci .def = 1, 77362306a36Sopenharmony_ci .step = 1, 77462306a36Sopenharmony_ci}; 77562306a36Sopenharmony_ci 77662306a36Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_has_scaler_cap = { 77762306a36Sopenharmony_ci .ops = &vivid_vid_cap_ctrl_ops, 77862306a36Sopenharmony_ci .id = VIVID_CID_HAS_SCALER_CAP, 77962306a36Sopenharmony_ci .name = "Enable Capture Scaler", 78062306a36Sopenharmony_ci .type = V4L2_CTRL_TYPE_BOOLEAN, 78162306a36Sopenharmony_ci .max = 1, 78262306a36Sopenharmony_ci .def = 1, 78362306a36Sopenharmony_ci .step = 1, 78462306a36Sopenharmony_ci}; 78562306a36Sopenharmony_ci 78662306a36Sopenharmony_cistatic const char * const vivid_ctrl_tstamp_src_strings[] = { 78762306a36Sopenharmony_ci "End of Frame", 78862306a36Sopenharmony_ci "Start of Exposure", 78962306a36Sopenharmony_ci NULL, 79062306a36Sopenharmony_ci}; 79162306a36Sopenharmony_ci 79262306a36Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_tstamp_src = { 79362306a36Sopenharmony_ci .ops = &vivid_vid_cap_ctrl_ops, 79462306a36Sopenharmony_ci .id = VIVID_CID_TSTAMP_SRC, 79562306a36Sopenharmony_ci .name = "Timestamp Source", 79662306a36Sopenharmony_ci .type = V4L2_CTRL_TYPE_MENU, 79762306a36Sopenharmony_ci .max = ARRAY_SIZE(vivid_ctrl_tstamp_src_strings) - 2, 79862306a36Sopenharmony_ci .qmenu = vivid_ctrl_tstamp_src_strings, 79962306a36Sopenharmony_ci}; 80062306a36Sopenharmony_ci 80162306a36Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_std_aspect_ratio = { 80262306a36Sopenharmony_ci .ops = &vivid_vid_cap_ctrl_ops, 80362306a36Sopenharmony_ci .id = VIVID_CID_STD_ASPECT_RATIO, 80462306a36Sopenharmony_ci .name = "Standard Aspect Ratio", 80562306a36Sopenharmony_ci .type = V4L2_CTRL_TYPE_MENU, 80662306a36Sopenharmony_ci .min = 1, 80762306a36Sopenharmony_ci .max = 4, 80862306a36Sopenharmony_ci .def = 1, 80962306a36Sopenharmony_ci .qmenu = tpg_aspect_strings, 81062306a36Sopenharmony_ci}; 81162306a36Sopenharmony_ci 81262306a36Sopenharmony_cistatic const char * const vivid_ctrl_dv_timings_signal_mode_strings[] = { 81362306a36Sopenharmony_ci "Current DV Timings", 81462306a36Sopenharmony_ci "No Signal", 81562306a36Sopenharmony_ci "No Lock", 81662306a36Sopenharmony_ci "Out of Range", 81762306a36Sopenharmony_ci "Selected DV Timings", 81862306a36Sopenharmony_ci "Cycle Through All DV Timings", 81962306a36Sopenharmony_ci "Custom DV Timings", 82062306a36Sopenharmony_ci NULL, 82162306a36Sopenharmony_ci}; 82262306a36Sopenharmony_ci 82362306a36Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_dv_timings_signal_mode = { 82462306a36Sopenharmony_ci .ops = &vivid_vid_cap_ctrl_ops, 82562306a36Sopenharmony_ci .id = VIVID_CID_DV_TIMINGS_SIGNAL_MODE, 82662306a36Sopenharmony_ci .name = "DV Timings Signal Mode", 82762306a36Sopenharmony_ci .type = V4L2_CTRL_TYPE_MENU, 82862306a36Sopenharmony_ci .max = 5, 82962306a36Sopenharmony_ci .qmenu = vivid_ctrl_dv_timings_signal_mode_strings, 83062306a36Sopenharmony_ci}; 83162306a36Sopenharmony_ci 83262306a36Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_dv_timings_aspect_ratio = { 83362306a36Sopenharmony_ci .ops = &vivid_vid_cap_ctrl_ops, 83462306a36Sopenharmony_ci .id = VIVID_CID_DV_TIMINGS_ASPECT_RATIO, 83562306a36Sopenharmony_ci .name = "DV Timings Aspect Ratio", 83662306a36Sopenharmony_ci .type = V4L2_CTRL_TYPE_MENU, 83762306a36Sopenharmony_ci .max = 3, 83862306a36Sopenharmony_ci .qmenu = tpg_aspect_strings, 83962306a36Sopenharmony_ci}; 84062306a36Sopenharmony_ci 84162306a36Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_max_edid_blocks = { 84262306a36Sopenharmony_ci .ops = &vivid_vid_cap_ctrl_ops, 84362306a36Sopenharmony_ci .id = VIVID_CID_MAX_EDID_BLOCKS, 84462306a36Sopenharmony_ci .name = "Maximum EDID Blocks", 84562306a36Sopenharmony_ci .type = V4L2_CTRL_TYPE_INTEGER, 84662306a36Sopenharmony_ci .min = 1, 84762306a36Sopenharmony_ci .max = 256, 84862306a36Sopenharmony_ci .def = 2, 84962306a36Sopenharmony_ci .step = 1, 85062306a36Sopenharmony_ci}; 85162306a36Sopenharmony_ci 85262306a36Sopenharmony_cistatic const char * const vivid_ctrl_colorspace_strings[] = { 85362306a36Sopenharmony_ci "SMPTE 170M", 85462306a36Sopenharmony_ci "Rec. 709", 85562306a36Sopenharmony_ci "sRGB", 85662306a36Sopenharmony_ci "opRGB", 85762306a36Sopenharmony_ci "BT.2020", 85862306a36Sopenharmony_ci "DCI-P3", 85962306a36Sopenharmony_ci "SMPTE 240M", 86062306a36Sopenharmony_ci "470 System M", 86162306a36Sopenharmony_ci "470 System BG", 86262306a36Sopenharmony_ci NULL, 86362306a36Sopenharmony_ci}; 86462306a36Sopenharmony_ci 86562306a36Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_colorspace = { 86662306a36Sopenharmony_ci .ops = &vivid_vid_cap_ctrl_ops, 86762306a36Sopenharmony_ci .id = VIVID_CID_COLORSPACE, 86862306a36Sopenharmony_ci .name = "Colorspace", 86962306a36Sopenharmony_ci .type = V4L2_CTRL_TYPE_MENU, 87062306a36Sopenharmony_ci .max = ARRAY_SIZE(vivid_ctrl_colorspace_strings) - 2, 87162306a36Sopenharmony_ci .def = 2, 87262306a36Sopenharmony_ci .qmenu = vivid_ctrl_colorspace_strings, 87362306a36Sopenharmony_ci}; 87462306a36Sopenharmony_ci 87562306a36Sopenharmony_cistatic const char * const vivid_ctrl_xfer_func_strings[] = { 87662306a36Sopenharmony_ci "Default", 87762306a36Sopenharmony_ci "Rec. 709", 87862306a36Sopenharmony_ci "sRGB", 87962306a36Sopenharmony_ci "opRGB", 88062306a36Sopenharmony_ci "SMPTE 240M", 88162306a36Sopenharmony_ci "None", 88262306a36Sopenharmony_ci "DCI-P3", 88362306a36Sopenharmony_ci "SMPTE 2084", 88462306a36Sopenharmony_ci NULL, 88562306a36Sopenharmony_ci}; 88662306a36Sopenharmony_ci 88762306a36Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_xfer_func = { 88862306a36Sopenharmony_ci .ops = &vivid_vid_cap_ctrl_ops, 88962306a36Sopenharmony_ci .id = VIVID_CID_XFER_FUNC, 89062306a36Sopenharmony_ci .name = "Transfer Function", 89162306a36Sopenharmony_ci .type = V4L2_CTRL_TYPE_MENU, 89262306a36Sopenharmony_ci .max = ARRAY_SIZE(vivid_ctrl_xfer_func_strings) - 2, 89362306a36Sopenharmony_ci .qmenu = vivid_ctrl_xfer_func_strings, 89462306a36Sopenharmony_ci}; 89562306a36Sopenharmony_ci 89662306a36Sopenharmony_cistatic const char * const vivid_ctrl_ycbcr_enc_strings[] = { 89762306a36Sopenharmony_ci "Default", 89862306a36Sopenharmony_ci "ITU-R 601", 89962306a36Sopenharmony_ci "Rec. 709", 90062306a36Sopenharmony_ci "xvYCC 601", 90162306a36Sopenharmony_ci "xvYCC 709", 90262306a36Sopenharmony_ci "", 90362306a36Sopenharmony_ci "BT.2020", 90462306a36Sopenharmony_ci "BT.2020 Constant Luminance", 90562306a36Sopenharmony_ci "SMPTE 240M", 90662306a36Sopenharmony_ci NULL, 90762306a36Sopenharmony_ci}; 90862306a36Sopenharmony_ci 90962306a36Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_ycbcr_enc = { 91062306a36Sopenharmony_ci .ops = &vivid_vid_cap_ctrl_ops, 91162306a36Sopenharmony_ci .id = VIVID_CID_YCBCR_ENC, 91262306a36Sopenharmony_ci .name = "Y'CbCr Encoding", 91362306a36Sopenharmony_ci .type = V4L2_CTRL_TYPE_MENU, 91462306a36Sopenharmony_ci .menu_skip_mask = 1 << 5, 91562306a36Sopenharmony_ci .max = ARRAY_SIZE(vivid_ctrl_ycbcr_enc_strings) - 2, 91662306a36Sopenharmony_ci .qmenu = vivid_ctrl_ycbcr_enc_strings, 91762306a36Sopenharmony_ci}; 91862306a36Sopenharmony_ci 91962306a36Sopenharmony_cistatic const char * const vivid_ctrl_hsv_enc_strings[] = { 92062306a36Sopenharmony_ci "Hue 0-179", 92162306a36Sopenharmony_ci "Hue 0-256", 92262306a36Sopenharmony_ci NULL, 92362306a36Sopenharmony_ci}; 92462306a36Sopenharmony_ci 92562306a36Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_hsv_enc = { 92662306a36Sopenharmony_ci .ops = &vivid_vid_cap_ctrl_ops, 92762306a36Sopenharmony_ci .id = VIVID_CID_HSV_ENC, 92862306a36Sopenharmony_ci .name = "HSV Encoding", 92962306a36Sopenharmony_ci .type = V4L2_CTRL_TYPE_MENU, 93062306a36Sopenharmony_ci .max = ARRAY_SIZE(vivid_ctrl_hsv_enc_strings) - 2, 93162306a36Sopenharmony_ci .qmenu = vivid_ctrl_hsv_enc_strings, 93262306a36Sopenharmony_ci}; 93362306a36Sopenharmony_ci 93462306a36Sopenharmony_cistatic const char * const vivid_ctrl_quantization_strings[] = { 93562306a36Sopenharmony_ci "Default", 93662306a36Sopenharmony_ci "Full Range", 93762306a36Sopenharmony_ci "Limited Range", 93862306a36Sopenharmony_ci NULL, 93962306a36Sopenharmony_ci}; 94062306a36Sopenharmony_ci 94162306a36Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_quantization = { 94262306a36Sopenharmony_ci .ops = &vivid_vid_cap_ctrl_ops, 94362306a36Sopenharmony_ci .id = VIVID_CID_QUANTIZATION, 94462306a36Sopenharmony_ci .name = "Quantization", 94562306a36Sopenharmony_ci .type = V4L2_CTRL_TYPE_MENU, 94662306a36Sopenharmony_ci .max = ARRAY_SIZE(vivid_ctrl_quantization_strings) - 2, 94762306a36Sopenharmony_ci .qmenu = vivid_ctrl_quantization_strings, 94862306a36Sopenharmony_ci}; 94962306a36Sopenharmony_ci 95062306a36Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_alpha_mode = { 95162306a36Sopenharmony_ci .ops = &vivid_vid_cap_ctrl_ops, 95262306a36Sopenharmony_ci .id = VIVID_CID_ALPHA_MODE, 95362306a36Sopenharmony_ci .name = "Apply Alpha To Red Only", 95462306a36Sopenharmony_ci .type = V4L2_CTRL_TYPE_BOOLEAN, 95562306a36Sopenharmony_ci .max = 1, 95662306a36Sopenharmony_ci .step = 1, 95762306a36Sopenharmony_ci}; 95862306a36Sopenharmony_ci 95962306a36Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_limited_rgb_range = { 96062306a36Sopenharmony_ci .ops = &vivid_vid_cap_ctrl_ops, 96162306a36Sopenharmony_ci .id = VIVID_CID_LIMITED_RGB_RANGE, 96262306a36Sopenharmony_ci .name = "Limited RGB Range (16-235)", 96362306a36Sopenharmony_ci .type = V4L2_CTRL_TYPE_BOOLEAN, 96462306a36Sopenharmony_ci .max = 1, 96562306a36Sopenharmony_ci .step = 1, 96662306a36Sopenharmony_ci}; 96762306a36Sopenharmony_ci 96862306a36Sopenharmony_ci 96962306a36Sopenharmony_ci/* Video Loop Control */ 97062306a36Sopenharmony_ci 97162306a36Sopenharmony_cistatic int vivid_loop_cap_s_ctrl(struct v4l2_ctrl *ctrl) 97262306a36Sopenharmony_ci{ 97362306a36Sopenharmony_ci struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_loop_cap); 97462306a36Sopenharmony_ci 97562306a36Sopenharmony_ci switch (ctrl->id) { 97662306a36Sopenharmony_ci case VIVID_CID_LOOP_VIDEO: 97762306a36Sopenharmony_ci dev->loop_video = ctrl->val; 97862306a36Sopenharmony_ci vivid_update_quality(dev); 97962306a36Sopenharmony_ci vivid_send_source_change(dev, SVID); 98062306a36Sopenharmony_ci vivid_send_source_change(dev, HDMI); 98162306a36Sopenharmony_ci break; 98262306a36Sopenharmony_ci } 98362306a36Sopenharmony_ci return 0; 98462306a36Sopenharmony_ci} 98562306a36Sopenharmony_ci 98662306a36Sopenharmony_cistatic const struct v4l2_ctrl_ops vivid_loop_cap_ctrl_ops = { 98762306a36Sopenharmony_ci .s_ctrl = vivid_loop_cap_s_ctrl, 98862306a36Sopenharmony_ci}; 98962306a36Sopenharmony_ci 99062306a36Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_loop_video = { 99162306a36Sopenharmony_ci .ops = &vivid_loop_cap_ctrl_ops, 99262306a36Sopenharmony_ci .id = VIVID_CID_LOOP_VIDEO, 99362306a36Sopenharmony_ci .name = "Loop Video", 99462306a36Sopenharmony_ci .type = V4L2_CTRL_TYPE_BOOLEAN, 99562306a36Sopenharmony_ci .max = 1, 99662306a36Sopenharmony_ci .step = 1, 99762306a36Sopenharmony_ci}; 99862306a36Sopenharmony_ci 99962306a36Sopenharmony_ci 100062306a36Sopenharmony_ci/* VBI Capture Control */ 100162306a36Sopenharmony_ci 100262306a36Sopenharmony_cistatic int vivid_vbi_cap_s_ctrl(struct v4l2_ctrl *ctrl) 100362306a36Sopenharmony_ci{ 100462306a36Sopenharmony_ci struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_vbi_cap); 100562306a36Sopenharmony_ci 100662306a36Sopenharmony_ci switch (ctrl->id) { 100762306a36Sopenharmony_ci case VIVID_CID_VBI_CAP_INTERLACED: 100862306a36Sopenharmony_ci dev->vbi_cap_interlaced = ctrl->val; 100962306a36Sopenharmony_ci break; 101062306a36Sopenharmony_ci } 101162306a36Sopenharmony_ci return 0; 101262306a36Sopenharmony_ci} 101362306a36Sopenharmony_ci 101462306a36Sopenharmony_cistatic const struct v4l2_ctrl_ops vivid_vbi_cap_ctrl_ops = { 101562306a36Sopenharmony_ci .s_ctrl = vivid_vbi_cap_s_ctrl, 101662306a36Sopenharmony_ci}; 101762306a36Sopenharmony_ci 101862306a36Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_vbi_cap_interlaced = { 101962306a36Sopenharmony_ci .ops = &vivid_vbi_cap_ctrl_ops, 102062306a36Sopenharmony_ci .id = VIVID_CID_VBI_CAP_INTERLACED, 102162306a36Sopenharmony_ci .name = "Interlaced VBI Format", 102262306a36Sopenharmony_ci .type = V4L2_CTRL_TYPE_BOOLEAN, 102362306a36Sopenharmony_ci .max = 1, 102462306a36Sopenharmony_ci .step = 1, 102562306a36Sopenharmony_ci}; 102662306a36Sopenharmony_ci 102762306a36Sopenharmony_ci 102862306a36Sopenharmony_ci/* Video Output Controls */ 102962306a36Sopenharmony_ci 103062306a36Sopenharmony_cistatic int vivid_vid_out_s_ctrl(struct v4l2_ctrl *ctrl) 103162306a36Sopenharmony_ci{ 103262306a36Sopenharmony_ci struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_vid_out); 103362306a36Sopenharmony_ci struct v4l2_bt_timings *bt = &dev->dv_timings_out.bt; 103462306a36Sopenharmony_ci u32 display_present = 0; 103562306a36Sopenharmony_ci unsigned int i, j, bus_idx; 103662306a36Sopenharmony_ci 103762306a36Sopenharmony_ci switch (ctrl->id) { 103862306a36Sopenharmony_ci case VIVID_CID_HAS_CROP_OUT: 103962306a36Sopenharmony_ci dev->has_crop_out = ctrl->val; 104062306a36Sopenharmony_ci vivid_update_format_out(dev); 104162306a36Sopenharmony_ci break; 104262306a36Sopenharmony_ci case VIVID_CID_HAS_COMPOSE_OUT: 104362306a36Sopenharmony_ci dev->has_compose_out = ctrl->val; 104462306a36Sopenharmony_ci vivid_update_format_out(dev); 104562306a36Sopenharmony_ci break; 104662306a36Sopenharmony_ci case VIVID_CID_HAS_SCALER_OUT: 104762306a36Sopenharmony_ci dev->has_scaler_out = ctrl->val; 104862306a36Sopenharmony_ci vivid_update_format_out(dev); 104962306a36Sopenharmony_ci break; 105062306a36Sopenharmony_ci case V4L2_CID_DV_TX_MODE: 105162306a36Sopenharmony_ci dev->dvi_d_out = ctrl->val == V4L2_DV_TX_MODE_DVI_D; 105262306a36Sopenharmony_ci if (!vivid_is_hdmi_out(dev)) 105362306a36Sopenharmony_ci break; 105462306a36Sopenharmony_ci if (!dev->dvi_d_out && (bt->flags & V4L2_DV_FL_IS_CE_VIDEO)) { 105562306a36Sopenharmony_ci if (bt->width == 720 && bt->height <= 576) 105662306a36Sopenharmony_ci dev->colorspace_out = V4L2_COLORSPACE_SMPTE170M; 105762306a36Sopenharmony_ci else 105862306a36Sopenharmony_ci dev->colorspace_out = V4L2_COLORSPACE_REC709; 105962306a36Sopenharmony_ci dev->quantization_out = V4L2_QUANTIZATION_DEFAULT; 106062306a36Sopenharmony_ci } else { 106162306a36Sopenharmony_ci dev->colorspace_out = V4L2_COLORSPACE_SRGB; 106262306a36Sopenharmony_ci dev->quantization_out = dev->dvi_d_out ? 106362306a36Sopenharmony_ci V4L2_QUANTIZATION_LIM_RANGE : 106462306a36Sopenharmony_ci V4L2_QUANTIZATION_DEFAULT; 106562306a36Sopenharmony_ci } 106662306a36Sopenharmony_ci if (dev->loop_video) 106762306a36Sopenharmony_ci vivid_send_source_change(dev, HDMI); 106862306a36Sopenharmony_ci break; 106962306a36Sopenharmony_ci case VIVID_CID_DISPLAY_PRESENT: 107062306a36Sopenharmony_ci if (dev->output_type[dev->output] != HDMI) 107162306a36Sopenharmony_ci break; 107262306a36Sopenharmony_ci 107362306a36Sopenharmony_ci dev->display_present[dev->output] = ctrl->val; 107462306a36Sopenharmony_ci for (i = 0, j = 0; i < dev->num_outputs; i++) 107562306a36Sopenharmony_ci if (dev->output_type[i] == HDMI) 107662306a36Sopenharmony_ci display_present |= 107762306a36Sopenharmony_ci dev->display_present[i] << j++; 107862306a36Sopenharmony_ci 107962306a36Sopenharmony_ci __v4l2_ctrl_s_ctrl(dev->ctrl_tx_rxsense, display_present); 108062306a36Sopenharmony_ci 108162306a36Sopenharmony_ci if (dev->edid_blocks) { 108262306a36Sopenharmony_ci __v4l2_ctrl_s_ctrl(dev->ctrl_tx_edid_present, 108362306a36Sopenharmony_ci display_present); 108462306a36Sopenharmony_ci __v4l2_ctrl_s_ctrl(dev->ctrl_tx_hotplug, 108562306a36Sopenharmony_ci display_present); 108662306a36Sopenharmony_ci } 108762306a36Sopenharmony_ci 108862306a36Sopenharmony_ci bus_idx = dev->cec_output2bus_map[dev->output]; 108962306a36Sopenharmony_ci if (!dev->cec_tx_adap[bus_idx]) 109062306a36Sopenharmony_ci break; 109162306a36Sopenharmony_ci 109262306a36Sopenharmony_ci if (ctrl->val && dev->edid_blocks) 109362306a36Sopenharmony_ci cec_s_phys_addr(dev->cec_tx_adap[bus_idx], 109462306a36Sopenharmony_ci dev->cec_tx_adap[bus_idx]->phys_addr, 109562306a36Sopenharmony_ci false); 109662306a36Sopenharmony_ci else 109762306a36Sopenharmony_ci cec_phys_addr_invalidate(dev->cec_tx_adap[bus_idx]); 109862306a36Sopenharmony_ci 109962306a36Sopenharmony_ci break; 110062306a36Sopenharmony_ci } 110162306a36Sopenharmony_ci return 0; 110262306a36Sopenharmony_ci} 110362306a36Sopenharmony_ci 110462306a36Sopenharmony_cistatic const struct v4l2_ctrl_ops vivid_vid_out_ctrl_ops = { 110562306a36Sopenharmony_ci .s_ctrl = vivid_vid_out_s_ctrl, 110662306a36Sopenharmony_ci}; 110762306a36Sopenharmony_ci 110862306a36Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_has_crop_out = { 110962306a36Sopenharmony_ci .ops = &vivid_vid_out_ctrl_ops, 111062306a36Sopenharmony_ci .id = VIVID_CID_HAS_CROP_OUT, 111162306a36Sopenharmony_ci .name = "Enable Output Cropping", 111262306a36Sopenharmony_ci .type = V4L2_CTRL_TYPE_BOOLEAN, 111362306a36Sopenharmony_ci .max = 1, 111462306a36Sopenharmony_ci .def = 1, 111562306a36Sopenharmony_ci .step = 1, 111662306a36Sopenharmony_ci}; 111762306a36Sopenharmony_ci 111862306a36Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_has_compose_out = { 111962306a36Sopenharmony_ci .ops = &vivid_vid_out_ctrl_ops, 112062306a36Sopenharmony_ci .id = VIVID_CID_HAS_COMPOSE_OUT, 112162306a36Sopenharmony_ci .name = "Enable Output Composing", 112262306a36Sopenharmony_ci .type = V4L2_CTRL_TYPE_BOOLEAN, 112362306a36Sopenharmony_ci .max = 1, 112462306a36Sopenharmony_ci .def = 1, 112562306a36Sopenharmony_ci .step = 1, 112662306a36Sopenharmony_ci}; 112762306a36Sopenharmony_ci 112862306a36Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_has_scaler_out = { 112962306a36Sopenharmony_ci .ops = &vivid_vid_out_ctrl_ops, 113062306a36Sopenharmony_ci .id = VIVID_CID_HAS_SCALER_OUT, 113162306a36Sopenharmony_ci .name = "Enable Output Scaler", 113262306a36Sopenharmony_ci .type = V4L2_CTRL_TYPE_BOOLEAN, 113362306a36Sopenharmony_ci .max = 1, 113462306a36Sopenharmony_ci .def = 1, 113562306a36Sopenharmony_ci .step = 1, 113662306a36Sopenharmony_ci}; 113762306a36Sopenharmony_ci 113862306a36Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_display_present = { 113962306a36Sopenharmony_ci .ops = &vivid_vid_out_ctrl_ops, 114062306a36Sopenharmony_ci .id = VIVID_CID_DISPLAY_PRESENT, 114162306a36Sopenharmony_ci .name = "Display Present", 114262306a36Sopenharmony_ci .type = V4L2_CTRL_TYPE_BOOLEAN, 114362306a36Sopenharmony_ci .max = 1, 114462306a36Sopenharmony_ci .def = 1, 114562306a36Sopenharmony_ci .step = 1, 114662306a36Sopenharmony_ci}; 114762306a36Sopenharmony_ci 114862306a36Sopenharmony_ci/* Streaming Controls */ 114962306a36Sopenharmony_ci 115062306a36Sopenharmony_cistatic int vivid_streaming_s_ctrl(struct v4l2_ctrl *ctrl) 115162306a36Sopenharmony_ci{ 115262306a36Sopenharmony_ci struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_streaming); 115362306a36Sopenharmony_ci 115462306a36Sopenharmony_ci switch (ctrl->id) { 115562306a36Sopenharmony_ci case VIVID_CID_DQBUF_ERROR: 115662306a36Sopenharmony_ci dev->dqbuf_error = true; 115762306a36Sopenharmony_ci break; 115862306a36Sopenharmony_ci case VIVID_CID_PERC_DROPPED: 115962306a36Sopenharmony_ci dev->perc_dropped_buffers = ctrl->val; 116062306a36Sopenharmony_ci break; 116162306a36Sopenharmony_ci case VIVID_CID_QUEUE_SETUP_ERROR: 116262306a36Sopenharmony_ci dev->queue_setup_error = true; 116362306a36Sopenharmony_ci break; 116462306a36Sopenharmony_ci case VIVID_CID_BUF_PREPARE_ERROR: 116562306a36Sopenharmony_ci dev->buf_prepare_error = true; 116662306a36Sopenharmony_ci break; 116762306a36Sopenharmony_ci case VIVID_CID_START_STR_ERROR: 116862306a36Sopenharmony_ci dev->start_streaming_error = true; 116962306a36Sopenharmony_ci break; 117062306a36Sopenharmony_ci case VIVID_CID_REQ_VALIDATE_ERROR: 117162306a36Sopenharmony_ci dev->req_validate_error = true; 117262306a36Sopenharmony_ci break; 117362306a36Sopenharmony_ci case VIVID_CID_QUEUE_ERROR: 117462306a36Sopenharmony_ci if (vb2_start_streaming_called(&dev->vb_vid_cap_q)) 117562306a36Sopenharmony_ci vb2_queue_error(&dev->vb_vid_cap_q); 117662306a36Sopenharmony_ci if (vb2_start_streaming_called(&dev->vb_vbi_cap_q)) 117762306a36Sopenharmony_ci vb2_queue_error(&dev->vb_vbi_cap_q); 117862306a36Sopenharmony_ci if (vb2_start_streaming_called(&dev->vb_vid_out_q)) 117962306a36Sopenharmony_ci vb2_queue_error(&dev->vb_vid_out_q); 118062306a36Sopenharmony_ci if (vb2_start_streaming_called(&dev->vb_vbi_out_q)) 118162306a36Sopenharmony_ci vb2_queue_error(&dev->vb_vbi_out_q); 118262306a36Sopenharmony_ci if (vb2_start_streaming_called(&dev->vb_sdr_cap_q)) 118362306a36Sopenharmony_ci vb2_queue_error(&dev->vb_sdr_cap_q); 118462306a36Sopenharmony_ci break; 118562306a36Sopenharmony_ci case VIVID_CID_SEQ_WRAP: 118662306a36Sopenharmony_ci dev->seq_wrap = ctrl->val; 118762306a36Sopenharmony_ci break; 118862306a36Sopenharmony_ci case VIVID_CID_TIME_WRAP: 118962306a36Sopenharmony_ci dev->time_wrap = ctrl->val; 119062306a36Sopenharmony_ci if (dev->time_wrap == 1) 119162306a36Sopenharmony_ci dev->time_wrap = (1ULL << 63) - NSEC_PER_SEC * 16ULL; 119262306a36Sopenharmony_ci else if (dev->time_wrap == 2) 119362306a36Sopenharmony_ci dev->time_wrap = ((1ULL << 31) - 16) * NSEC_PER_SEC; 119462306a36Sopenharmony_ci break; 119562306a36Sopenharmony_ci } 119662306a36Sopenharmony_ci return 0; 119762306a36Sopenharmony_ci} 119862306a36Sopenharmony_ci 119962306a36Sopenharmony_cistatic const struct v4l2_ctrl_ops vivid_streaming_ctrl_ops = { 120062306a36Sopenharmony_ci .s_ctrl = vivid_streaming_s_ctrl, 120162306a36Sopenharmony_ci}; 120262306a36Sopenharmony_ci 120362306a36Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_dqbuf_error = { 120462306a36Sopenharmony_ci .ops = &vivid_streaming_ctrl_ops, 120562306a36Sopenharmony_ci .id = VIVID_CID_DQBUF_ERROR, 120662306a36Sopenharmony_ci .name = "Inject V4L2_BUF_FLAG_ERROR", 120762306a36Sopenharmony_ci .type = V4L2_CTRL_TYPE_BUTTON, 120862306a36Sopenharmony_ci}; 120962306a36Sopenharmony_ci 121062306a36Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_perc_dropped = { 121162306a36Sopenharmony_ci .ops = &vivid_streaming_ctrl_ops, 121262306a36Sopenharmony_ci .id = VIVID_CID_PERC_DROPPED, 121362306a36Sopenharmony_ci .name = "Percentage of Dropped Buffers", 121462306a36Sopenharmony_ci .type = V4L2_CTRL_TYPE_INTEGER, 121562306a36Sopenharmony_ci .min = 0, 121662306a36Sopenharmony_ci .max = 100, 121762306a36Sopenharmony_ci .step = 1, 121862306a36Sopenharmony_ci}; 121962306a36Sopenharmony_ci 122062306a36Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_queue_setup_error = { 122162306a36Sopenharmony_ci .ops = &vivid_streaming_ctrl_ops, 122262306a36Sopenharmony_ci .id = VIVID_CID_QUEUE_SETUP_ERROR, 122362306a36Sopenharmony_ci .name = "Inject VIDIOC_REQBUFS Error", 122462306a36Sopenharmony_ci .type = V4L2_CTRL_TYPE_BUTTON, 122562306a36Sopenharmony_ci}; 122662306a36Sopenharmony_ci 122762306a36Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_buf_prepare_error = { 122862306a36Sopenharmony_ci .ops = &vivid_streaming_ctrl_ops, 122962306a36Sopenharmony_ci .id = VIVID_CID_BUF_PREPARE_ERROR, 123062306a36Sopenharmony_ci .name = "Inject VIDIOC_QBUF Error", 123162306a36Sopenharmony_ci .type = V4L2_CTRL_TYPE_BUTTON, 123262306a36Sopenharmony_ci}; 123362306a36Sopenharmony_ci 123462306a36Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_start_streaming_error = { 123562306a36Sopenharmony_ci .ops = &vivid_streaming_ctrl_ops, 123662306a36Sopenharmony_ci .id = VIVID_CID_START_STR_ERROR, 123762306a36Sopenharmony_ci .name = "Inject VIDIOC_STREAMON Error", 123862306a36Sopenharmony_ci .type = V4L2_CTRL_TYPE_BUTTON, 123962306a36Sopenharmony_ci}; 124062306a36Sopenharmony_ci 124162306a36Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_queue_error = { 124262306a36Sopenharmony_ci .ops = &vivid_streaming_ctrl_ops, 124362306a36Sopenharmony_ci .id = VIVID_CID_QUEUE_ERROR, 124462306a36Sopenharmony_ci .name = "Inject Fatal Streaming Error", 124562306a36Sopenharmony_ci .type = V4L2_CTRL_TYPE_BUTTON, 124662306a36Sopenharmony_ci}; 124762306a36Sopenharmony_ci 124862306a36Sopenharmony_ci#ifdef CONFIG_MEDIA_CONTROLLER 124962306a36Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_req_validate_error = { 125062306a36Sopenharmony_ci .ops = &vivid_streaming_ctrl_ops, 125162306a36Sopenharmony_ci .id = VIVID_CID_REQ_VALIDATE_ERROR, 125262306a36Sopenharmony_ci .name = "Inject req_validate() Error", 125362306a36Sopenharmony_ci .type = V4L2_CTRL_TYPE_BUTTON, 125462306a36Sopenharmony_ci}; 125562306a36Sopenharmony_ci#endif 125662306a36Sopenharmony_ci 125762306a36Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_seq_wrap = { 125862306a36Sopenharmony_ci .ops = &vivid_streaming_ctrl_ops, 125962306a36Sopenharmony_ci .id = VIVID_CID_SEQ_WRAP, 126062306a36Sopenharmony_ci .name = "Wrap Sequence Number", 126162306a36Sopenharmony_ci .type = V4L2_CTRL_TYPE_BOOLEAN, 126262306a36Sopenharmony_ci .max = 1, 126362306a36Sopenharmony_ci .step = 1, 126462306a36Sopenharmony_ci}; 126562306a36Sopenharmony_ci 126662306a36Sopenharmony_cistatic const char * const vivid_ctrl_time_wrap_strings[] = { 126762306a36Sopenharmony_ci "None", 126862306a36Sopenharmony_ci "64 Bit", 126962306a36Sopenharmony_ci "32 Bit", 127062306a36Sopenharmony_ci NULL, 127162306a36Sopenharmony_ci}; 127262306a36Sopenharmony_ci 127362306a36Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_time_wrap = { 127462306a36Sopenharmony_ci .ops = &vivid_streaming_ctrl_ops, 127562306a36Sopenharmony_ci .id = VIVID_CID_TIME_WRAP, 127662306a36Sopenharmony_ci .name = "Wrap Timestamp", 127762306a36Sopenharmony_ci .type = V4L2_CTRL_TYPE_MENU, 127862306a36Sopenharmony_ci .max = ARRAY_SIZE(vivid_ctrl_time_wrap_strings) - 2, 127962306a36Sopenharmony_ci .qmenu = vivid_ctrl_time_wrap_strings, 128062306a36Sopenharmony_ci}; 128162306a36Sopenharmony_ci 128262306a36Sopenharmony_ci 128362306a36Sopenharmony_ci/* SDTV Capture Controls */ 128462306a36Sopenharmony_ci 128562306a36Sopenharmony_cistatic int vivid_sdtv_cap_s_ctrl(struct v4l2_ctrl *ctrl) 128662306a36Sopenharmony_ci{ 128762306a36Sopenharmony_ci struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_sdtv_cap); 128862306a36Sopenharmony_ci 128962306a36Sopenharmony_ci switch (ctrl->id) { 129062306a36Sopenharmony_ci case VIVID_CID_STD_SIGNAL_MODE: 129162306a36Sopenharmony_ci dev->std_signal_mode[dev->input] = 129262306a36Sopenharmony_ci dev->ctrl_std_signal_mode->val; 129362306a36Sopenharmony_ci if (dev->std_signal_mode[dev->input] == SELECTED_STD) 129462306a36Sopenharmony_ci dev->query_std[dev->input] = 129562306a36Sopenharmony_ci vivid_standard[dev->ctrl_standard->val]; 129662306a36Sopenharmony_ci v4l2_ctrl_activate(dev->ctrl_standard, 129762306a36Sopenharmony_ci dev->std_signal_mode[dev->input] == 129862306a36Sopenharmony_ci SELECTED_STD); 129962306a36Sopenharmony_ci vivid_update_quality(dev); 130062306a36Sopenharmony_ci vivid_send_source_change(dev, TV); 130162306a36Sopenharmony_ci vivid_send_source_change(dev, SVID); 130262306a36Sopenharmony_ci break; 130362306a36Sopenharmony_ci } 130462306a36Sopenharmony_ci return 0; 130562306a36Sopenharmony_ci} 130662306a36Sopenharmony_ci 130762306a36Sopenharmony_cistatic const struct v4l2_ctrl_ops vivid_sdtv_cap_ctrl_ops = { 130862306a36Sopenharmony_ci .s_ctrl = vivid_sdtv_cap_s_ctrl, 130962306a36Sopenharmony_ci}; 131062306a36Sopenharmony_ci 131162306a36Sopenharmony_cistatic const char * const vivid_ctrl_std_signal_mode_strings[] = { 131262306a36Sopenharmony_ci "Current Standard", 131362306a36Sopenharmony_ci "No Signal", 131462306a36Sopenharmony_ci "No Lock", 131562306a36Sopenharmony_ci "", 131662306a36Sopenharmony_ci "Selected Standard", 131762306a36Sopenharmony_ci "Cycle Through All Standards", 131862306a36Sopenharmony_ci NULL, 131962306a36Sopenharmony_ci}; 132062306a36Sopenharmony_ci 132162306a36Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_std_signal_mode = { 132262306a36Sopenharmony_ci .ops = &vivid_sdtv_cap_ctrl_ops, 132362306a36Sopenharmony_ci .id = VIVID_CID_STD_SIGNAL_MODE, 132462306a36Sopenharmony_ci .name = "Standard Signal Mode", 132562306a36Sopenharmony_ci .type = V4L2_CTRL_TYPE_MENU, 132662306a36Sopenharmony_ci .max = ARRAY_SIZE(vivid_ctrl_std_signal_mode_strings) - 2, 132762306a36Sopenharmony_ci .menu_skip_mask = 1 << 3, 132862306a36Sopenharmony_ci .qmenu = vivid_ctrl_std_signal_mode_strings, 132962306a36Sopenharmony_ci}; 133062306a36Sopenharmony_ci 133162306a36Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_standard = { 133262306a36Sopenharmony_ci .ops = &vivid_sdtv_cap_ctrl_ops, 133362306a36Sopenharmony_ci .id = VIVID_CID_STANDARD, 133462306a36Sopenharmony_ci .name = "Standard", 133562306a36Sopenharmony_ci .type = V4L2_CTRL_TYPE_MENU, 133662306a36Sopenharmony_ci .max = 14, 133762306a36Sopenharmony_ci .qmenu = vivid_ctrl_standard_strings, 133862306a36Sopenharmony_ci}; 133962306a36Sopenharmony_ci 134062306a36Sopenharmony_ci 134162306a36Sopenharmony_ci 134262306a36Sopenharmony_ci/* Radio Receiver Controls */ 134362306a36Sopenharmony_ci 134462306a36Sopenharmony_cistatic int vivid_radio_rx_s_ctrl(struct v4l2_ctrl *ctrl) 134562306a36Sopenharmony_ci{ 134662306a36Sopenharmony_ci struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_radio_rx); 134762306a36Sopenharmony_ci 134862306a36Sopenharmony_ci switch (ctrl->id) { 134962306a36Sopenharmony_ci case VIVID_CID_RADIO_SEEK_MODE: 135062306a36Sopenharmony_ci dev->radio_rx_hw_seek_mode = ctrl->val; 135162306a36Sopenharmony_ci break; 135262306a36Sopenharmony_ci case VIVID_CID_RADIO_SEEK_PROG_LIM: 135362306a36Sopenharmony_ci dev->radio_rx_hw_seek_prog_lim = ctrl->val; 135462306a36Sopenharmony_ci break; 135562306a36Sopenharmony_ci case VIVID_CID_RADIO_RX_RDS_RBDS: 135662306a36Sopenharmony_ci dev->rds_gen.use_rbds = ctrl->val; 135762306a36Sopenharmony_ci break; 135862306a36Sopenharmony_ci case VIVID_CID_RADIO_RX_RDS_BLOCKIO: 135962306a36Sopenharmony_ci dev->radio_rx_rds_controls = ctrl->val; 136062306a36Sopenharmony_ci dev->radio_rx_caps &= ~V4L2_CAP_READWRITE; 136162306a36Sopenharmony_ci dev->radio_rx_rds_use_alternates = false; 136262306a36Sopenharmony_ci if (!dev->radio_rx_rds_controls) { 136362306a36Sopenharmony_ci dev->radio_rx_caps |= V4L2_CAP_READWRITE; 136462306a36Sopenharmony_ci __v4l2_ctrl_s_ctrl(dev->radio_rx_rds_pty, 0); 136562306a36Sopenharmony_ci __v4l2_ctrl_s_ctrl(dev->radio_rx_rds_ta, 0); 136662306a36Sopenharmony_ci __v4l2_ctrl_s_ctrl(dev->radio_rx_rds_tp, 0); 136762306a36Sopenharmony_ci __v4l2_ctrl_s_ctrl(dev->radio_rx_rds_ms, 0); 136862306a36Sopenharmony_ci __v4l2_ctrl_s_ctrl_string(dev->radio_rx_rds_psname, ""); 136962306a36Sopenharmony_ci __v4l2_ctrl_s_ctrl_string(dev->radio_rx_rds_radiotext, ""); 137062306a36Sopenharmony_ci } 137162306a36Sopenharmony_ci v4l2_ctrl_activate(dev->radio_rx_rds_pty, dev->radio_rx_rds_controls); 137262306a36Sopenharmony_ci v4l2_ctrl_activate(dev->radio_rx_rds_psname, dev->radio_rx_rds_controls); 137362306a36Sopenharmony_ci v4l2_ctrl_activate(dev->radio_rx_rds_radiotext, dev->radio_rx_rds_controls); 137462306a36Sopenharmony_ci v4l2_ctrl_activate(dev->radio_rx_rds_ta, dev->radio_rx_rds_controls); 137562306a36Sopenharmony_ci v4l2_ctrl_activate(dev->radio_rx_rds_tp, dev->radio_rx_rds_controls); 137662306a36Sopenharmony_ci v4l2_ctrl_activate(dev->radio_rx_rds_ms, dev->radio_rx_rds_controls); 137762306a36Sopenharmony_ci dev->radio_rx_dev.device_caps = dev->radio_rx_caps; 137862306a36Sopenharmony_ci break; 137962306a36Sopenharmony_ci case V4L2_CID_RDS_RECEPTION: 138062306a36Sopenharmony_ci dev->radio_rx_rds_enabled = ctrl->val; 138162306a36Sopenharmony_ci break; 138262306a36Sopenharmony_ci } 138362306a36Sopenharmony_ci return 0; 138462306a36Sopenharmony_ci} 138562306a36Sopenharmony_ci 138662306a36Sopenharmony_cistatic const struct v4l2_ctrl_ops vivid_radio_rx_ctrl_ops = { 138762306a36Sopenharmony_ci .s_ctrl = vivid_radio_rx_s_ctrl, 138862306a36Sopenharmony_ci}; 138962306a36Sopenharmony_ci 139062306a36Sopenharmony_cistatic const char * const vivid_ctrl_radio_rds_mode_strings[] = { 139162306a36Sopenharmony_ci "Block I/O", 139262306a36Sopenharmony_ci "Controls", 139362306a36Sopenharmony_ci NULL, 139462306a36Sopenharmony_ci}; 139562306a36Sopenharmony_ci 139662306a36Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_radio_rx_rds_blockio = { 139762306a36Sopenharmony_ci .ops = &vivid_radio_rx_ctrl_ops, 139862306a36Sopenharmony_ci .id = VIVID_CID_RADIO_RX_RDS_BLOCKIO, 139962306a36Sopenharmony_ci .name = "RDS Rx I/O Mode", 140062306a36Sopenharmony_ci .type = V4L2_CTRL_TYPE_MENU, 140162306a36Sopenharmony_ci .qmenu = vivid_ctrl_radio_rds_mode_strings, 140262306a36Sopenharmony_ci .max = 1, 140362306a36Sopenharmony_ci}; 140462306a36Sopenharmony_ci 140562306a36Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_radio_rx_rds_rbds = { 140662306a36Sopenharmony_ci .ops = &vivid_radio_rx_ctrl_ops, 140762306a36Sopenharmony_ci .id = VIVID_CID_RADIO_RX_RDS_RBDS, 140862306a36Sopenharmony_ci .name = "Generate RBDS Instead of RDS", 140962306a36Sopenharmony_ci .type = V4L2_CTRL_TYPE_BOOLEAN, 141062306a36Sopenharmony_ci .max = 1, 141162306a36Sopenharmony_ci .step = 1, 141262306a36Sopenharmony_ci}; 141362306a36Sopenharmony_ci 141462306a36Sopenharmony_cistatic const char * const vivid_ctrl_radio_hw_seek_mode_strings[] = { 141562306a36Sopenharmony_ci "Bounded", 141662306a36Sopenharmony_ci "Wrap Around", 141762306a36Sopenharmony_ci "Both", 141862306a36Sopenharmony_ci NULL, 141962306a36Sopenharmony_ci}; 142062306a36Sopenharmony_ci 142162306a36Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_radio_hw_seek_mode = { 142262306a36Sopenharmony_ci .ops = &vivid_radio_rx_ctrl_ops, 142362306a36Sopenharmony_ci .id = VIVID_CID_RADIO_SEEK_MODE, 142462306a36Sopenharmony_ci .name = "Radio HW Seek Mode", 142562306a36Sopenharmony_ci .type = V4L2_CTRL_TYPE_MENU, 142662306a36Sopenharmony_ci .max = 2, 142762306a36Sopenharmony_ci .qmenu = vivid_ctrl_radio_hw_seek_mode_strings, 142862306a36Sopenharmony_ci}; 142962306a36Sopenharmony_ci 143062306a36Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_radio_hw_seek_prog_lim = { 143162306a36Sopenharmony_ci .ops = &vivid_radio_rx_ctrl_ops, 143262306a36Sopenharmony_ci .id = VIVID_CID_RADIO_SEEK_PROG_LIM, 143362306a36Sopenharmony_ci .name = "Radio Programmable HW Seek", 143462306a36Sopenharmony_ci .type = V4L2_CTRL_TYPE_BOOLEAN, 143562306a36Sopenharmony_ci .max = 1, 143662306a36Sopenharmony_ci .step = 1, 143762306a36Sopenharmony_ci}; 143862306a36Sopenharmony_ci 143962306a36Sopenharmony_ci 144062306a36Sopenharmony_ci/* Radio Transmitter Controls */ 144162306a36Sopenharmony_ci 144262306a36Sopenharmony_cistatic int vivid_radio_tx_s_ctrl(struct v4l2_ctrl *ctrl) 144362306a36Sopenharmony_ci{ 144462306a36Sopenharmony_ci struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_radio_tx); 144562306a36Sopenharmony_ci 144662306a36Sopenharmony_ci switch (ctrl->id) { 144762306a36Sopenharmony_ci case VIVID_CID_RADIO_TX_RDS_BLOCKIO: 144862306a36Sopenharmony_ci dev->radio_tx_rds_controls = ctrl->val; 144962306a36Sopenharmony_ci dev->radio_tx_caps &= ~V4L2_CAP_READWRITE; 145062306a36Sopenharmony_ci if (!dev->radio_tx_rds_controls) 145162306a36Sopenharmony_ci dev->radio_tx_caps |= V4L2_CAP_READWRITE; 145262306a36Sopenharmony_ci dev->radio_tx_dev.device_caps = dev->radio_tx_caps; 145362306a36Sopenharmony_ci break; 145462306a36Sopenharmony_ci case V4L2_CID_RDS_TX_PTY: 145562306a36Sopenharmony_ci if (dev->radio_rx_rds_controls) 145662306a36Sopenharmony_ci v4l2_ctrl_s_ctrl(dev->radio_rx_rds_pty, ctrl->val); 145762306a36Sopenharmony_ci break; 145862306a36Sopenharmony_ci case V4L2_CID_RDS_TX_PS_NAME: 145962306a36Sopenharmony_ci if (dev->radio_rx_rds_controls) 146062306a36Sopenharmony_ci v4l2_ctrl_s_ctrl_string(dev->radio_rx_rds_psname, ctrl->p_new.p_char); 146162306a36Sopenharmony_ci break; 146262306a36Sopenharmony_ci case V4L2_CID_RDS_TX_RADIO_TEXT: 146362306a36Sopenharmony_ci if (dev->radio_rx_rds_controls) 146462306a36Sopenharmony_ci v4l2_ctrl_s_ctrl_string(dev->radio_rx_rds_radiotext, ctrl->p_new.p_char); 146562306a36Sopenharmony_ci break; 146662306a36Sopenharmony_ci case V4L2_CID_RDS_TX_TRAFFIC_ANNOUNCEMENT: 146762306a36Sopenharmony_ci if (dev->radio_rx_rds_controls) 146862306a36Sopenharmony_ci v4l2_ctrl_s_ctrl(dev->radio_rx_rds_ta, ctrl->val); 146962306a36Sopenharmony_ci break; 147062306a36Sopenharmony_ci case V4L2_CID_RDS_TX_TRAFFIC_PROGRAM: 147162306a36Sopenharmony_ci if (dev->radio_rx_rds_controls) 147262306a36Sopenharmony_ci v4l2_ctrl_s_ctrl(dev->radio_rx_rds_tp, ctrl->val); 147362306a36Sopenharmony_ci break; 147462306a36Sopenharmony_ci case V4L2_CID_RDS_TX_MUSIC_SPEECH: 147562306a36Sopenharmony_ci if (dev->radio_rx_rds_controls) 147662306a36Sopenharmony_ci v4l2_ctrl_s_ctrl(dev->radio_rx_rds_ms, ctrl->val); 147762306a36Sopenharmony_ci break; 147862306a36Sopenharmony_ci } 147962306a36Sopenharmony_ci return 0; 148062306a36Sopenharmony_ci} 148162306a36Sopenharmony_ci 148262306a36Sopenharmony_cistatic const struct v4l2_ctrl_ops vivid_radio_tx_ctrl_ops = { 148362306a36Sopenharmony_ci .s_ctrl = vivid_radio_tx_s_ctrl, 148462306a36Sopenharmony_ci}; 148562306a36Sopenharmony_ci 148662306a36Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_radio_tx_rds_blockio = { 148762306a36Sopenharmony_ci .ops = &vivid_radio_tx_ctrl_ops, 148862306a36Sopenharmony_ci .id = VIVID_CID_RADIO_TX_RDS_BLOCKIO, 148962306a36Sopenharmony_ci .name = "RDS Tx I/O Mode", 149062306a36Sopenharmony_ci .type = V4L2_CTRL_TYPE_MENU, 149162306a36Sopenharmony_ci .qmenu = vivid_ctrl_radio_rds_mode_strings, 149262306a36Sopenharmony_ci .max = 1, 149362306a36Sopenharmony_ci .def = 1, 149462306a36Sopenharmony_ci}; 149562306a36Sopenharmony_ci 149662306a36Sopenharmony_ci 149762306a36Sopenharmony_ci/* SDR Capture Controls */ 149862306a36Sopenharmony_ci 149962306a36Sopenharmony_cistatic int vivid_sdr_cap_s_ctrl(struct v4l2_ctrl *ctrl) 150062306a36Sopenharmony_ci{ 150162306a36Sopenharmony_ci struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_sdr_cap); 150262306a36Sopenharmony_ci 150362306a36Sopenharmony_ci switch (ctrl->id) { 150462306a36Sopenharmony_ci case VIVID_CID_SDR_CAP_FM_DEVIATION: 150562306a36Sopenharmony_ci dev->sdr_fm_deviation = ctrl->val; 150662306a36Sopenharmony_ci break; 150762306a36Sopenharmony_ci } 150862306a36Sopenharmony_ci return 0; 150962306a36Sopenharmony_ci} 151062306a36Sopenharmony_ci 151162306a36Sopenharmony_cistatic const struct v4l2_ctrl_ops vivid_sdr_cap_ctrl_ops = { 151262306a36Sopenharmony_ci .s_ctrl = vivid_sdr_cap_s_ctrl, 151362306a36Sopenharmony_ci}; 151462306a36Sopenharmony_ci 151562306a36Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_sdr_cap_fm_deviation = { 151662306a36Sopenharmony_ci .ops = &vivid_sdr_cap_ctrl_ops, 151762306a36Sopenharmony_ci .id = VIVID_CID_SDR_CAP_FM_DEVIATION, 151862306a36Sopenharmony_ci .name = "FM Deviation", 151962306a36Sopenharmony_ci .type = V4L2_CTRL_TYPE_INTEGER, 152062306a36Sopenharmony_ci .min = 100, 152162306a36Sopenharmony_ci .max = 200000, 152262306a36Sopenharmony_ci .def = 75000, 152362306a36Sopenharmony_ci .step = 1, 152462306a36Sopenharmony_ci}; 152562306a36Sopenharmony_ci 152662306a36Sopenharmony_ci/* Metadata Capture Control */ 152762306a36Sopenharmony_ci 152862306a36Sopenharmony_cistatic int vivid_meta_cap_s_ctrl(struct v4l2_ctrl *ctrl) 152962306a36Sopenharmony_ci{ 153062306a36Sopenharmony_ci struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, 153162306a36Sopenharmony_ci ctrl_hdl_meta_cap); 153262306a36Sopenharmony_ci 153362306a36Sopenharmony_ci switch (ctrl->id) { 153462306a36Sopenharmony_ci case VIVID_CID_META_CAP_GENERATE_PTS: 153562306a36Sopenharmony_ci dev->meta_pts = ctrl->val; 153662306a36Sopenharmony_ci break; 153762306a36Sopenharmony_ci case VIVID_CID_META_CAP_GENERATE_SCR: 153862306a36Sopenharmony_ci dev->meta_scr = ctrl->val; 153962306a36Sopenharmony_ci break; 154062306a36Sopenharmony_ci } 154162306a36Sopenharmony_ci return 0; 154262306a36Sopenharmony_ci} 154362306a36Sopenharmony_ci 154462306a36Sopenharmony_cistatic const struct v4l2_ctrl_ops vivid_meta_cap_ctrl_ops = { 154562306a36Sopenharmony_ci .s_ctrl = vivid_meta_cap_s_ctrl, 154662306a36Sopenharmony_ci}; 154762306a36Sopenharmony_ci 154862306a36Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_meta_has_pts = { 154962306a36Sopenharmony_ci .ops = &vivid_meta_cap_ctrl_ops, 155062306a36Sopenharmony_ci .id = VIVID_CID_META_CAP_GENERATE_PTS, 155162306a36Sopenharmony_ci .name = "Generate PTS", 155262306a36Sopenharmony_ci .type = V4L2_CTRL_TYPE_BOOLEAN, 155362306a36Sopenharmony_ci .max = 1, 155462306a36Sopenharmony_ci .def = 1, 155562306a36Sopenharmony_ci .step = 1, 155662306a36Sopenharmony_ci}; 155762306a36Sopenharmony_ci 155862306a36Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_meta_has_src_clk = { 155962306a36Sopenharmony_ci .ops = &vivid_meta_cap_ctrl_ops, 156062306a36Sopenharmony_ci .id = VIVID_CID_META_CAP_GENERATE_SCR, 156162306a36Sopenharmony_ci .name = "Generate SCR", 156262306a36Sopenharmony_ci .type = V4L2_CTRL_TYPE_BOOLEAN, 156362306a36Sopenharmony_ci .max = 1, 156462306a36Sopenharmony_ci .def = 1, 156562306a36Sopenharmony_ci .step = 1, 156662306a36Sopenharmony_ci}; 156762306a36Sopenharmony_ci 156862306a36Sopenharmony_cistatic const struct v4l2_ctrl_config vivid_ctrl_class = { 156962306a36Sopenharmony_ci .ops = &vivid_user_gen_ctrl_ops, 157062306a36Sopenharmony_ci .flags = V4L2_CTRL_FLAG_READ_ONLY | V4L2_CTRL_FLAG_WRITE_ONLY, 157162306a36Sopenharmony_ci .id = VIVID_CID_VIVID_CLASS, 157262306a36Sopenharmony_ci .name = "Vivid Controls", 157362306a36Sopenharmony_ci .type = V4L2_CTRL_TYPE_CTRL_CLASS, 157462306a36Sopenharmony_ci}; 157562306a36Sopenharmony_ci 157662306a36Sopenharmony_ciint vivid_create_controls(struct vivid_dev *dev, bool show_ccs_cap, 157762306a36Sopenharmony_ci bool show_ccs_out, bool no_error_inj, 157862306a36Sopenharmony_ci bool has_sdtv, bool has_hdmi) 157962306a36Sopenharmony_ci{ 158062306a36Sopenharmony_ci struct v4l2_ctrl_handler *hdl_user_gen = &dev->ctrl_hdl_user_gen; 158162306a36Sopenharmony_ci struct v4l2_ctrl_handler *hdl_user_vid = &dev->ctrl_hdl_user_vid; 158262306a36Sopenharmony_ci struct v4l2_ctrl_handler *hdl_user_aud = &dev->ctrl_hdl_user_aud; 158362306a36Sopenharmony_ci struct v4l2_ctrl_handler *hdl_streaming = &dev->ctrl_hdl_streaming; 158462306a36Sopenharmony_ci struct v4l2_ctrl_handler *hdl_sdtv_cap = &dev->ctrl_hdl_sdtv_cap; 158562306a36Sopenharmony_ci struct v4l2_ctrl_handler *hdl_loop_cap = &dev->ctrl_hdl_loop_cap; 158662306a36Sopenharmony_ci struct v4l2_ctrl_handler *hdl_fb = &dev->ctrl_hdl_fb; 158762306a36Sopenharmony_ci struct v4l2_ctrl_handler *hdl_vid_cap = &dev->ctrl_hdl_vid_cap; 158862306a36Sopenharmony_ci struct v4l2_ctrl_handler *hdl_vid_out = &dev->ctrl_hdl_vid_out; 158962306a36Sopenharmony_ci struct v4l2_ctrl_handler *hdl_vbi_cap = &dev->ctrl_hdl_vbi_cap; 159062306a36Sopenharmony_ci struct v4l2_ctrl_handler *hdl_vbi_out = &dev->ctrl_hdl_vbi_out; 159162306a36Sopenharmony_ci struct v4l2_ctrl_handler *hdl_radio_rx = &dev->ctrl_hdl_radio_rx; 159262306a36Sopenharmony_ci struct v4l2_ctrl_handler *hdl_radio_tx = &dev->ctrl_hdl_radio_tx; 159362306a36Sopenharmony_ci struct v4l2_ctrl_handler *hdl_sdr_cap = &dev->ctrl_hdl_sdr_cap; 159462306a36Sopenharmony_ci struct v4l2_ctrl_handler *hdl_meta_cap = &dev->ctrl_hdl_meta_cap; 159562306a36Sopenharmony_ci struct v4l2_ctrl_handler *hdl_meta_out = &dev->ctrl_hdl_meta_out; 159662306a36Sopenharmony_ci struct v4l2_ctrl_handler *hdl_tch_cap = &dev->ctrl_hdl_touch_cap; 159762306a36Sopenharmony_ci 159862306a36Sopenharmony_ci struct v4l2_ctrl_config vivid_ctrl_dv_timings = { 159962306a36Sopenharmony_ci .ops = &vivid_vid_cap_ctrl_ops, 160062306a36Sopenharmony_ci .id = VIVID_CID_DV_TIMINGS, 160162306a36Sopenharmony_ci .name = "DV Timings", 160262306a36Sopenharmony_ci .type = V4L2_CTRL_TYPE_MENU, 160362306a36Sopenharmony_ci }; 160462306a36Sopenharmony_ci int i; 160562306a36Sopenharmony_ci 160662306a36Sopenharmony_ci v4l2_ctrl_handler_init(hdl_user_gen, 10); 160762306a36Sopenharmony_ci v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_class, NULL); 160862306a36Sopenharmony_ci v4l2_ctrl_handler_init(hdl_user_vid, 9); 160962306a36Sopenharmony_ci v4l2_ctrl_new_custom(hdl_user_vid, &vivid_ctrl_class, NULL); 161062306a36Sopenharmony_ci v4l2_ctrl_handler_init(hdl_user_aud, 2); 161162306a36Sopenharmony_ci v4l2_ctrl_new_custom(hdl_user_aud, &vivid_ctrl_class, NULL); 161262306a36Sopenharmony_ci v4l2_ctrl_handler_init(hdl_streaming, 8); 161362306a36Sopenharmony_ci v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_class, NULL); 161462306a36Sopenharmony_ci v4l2_ctrl_handler_init(hdl_sdtv_cap, 2); 161562306a36Sopenharmony_ci v4l2_ctrl_new_custom(hdl_sdtv_cap, &vivid_ctrl_class, NULL); 161662306a36Sopenharmony_ci v4l2_ctrl_handler_init(hdl_loop_cap, 1); 161762306a36Sopenharmony_ci v4l2_ctrl_new_custom(hdl_loop_cap, &vivid_ctrl_class, NULL); 161862306a36Sopenharmony_ci v4l2_ctrl_handler_init(hdl_fb, 1); 161962306a36Sopenharmony_ci v4l2_ctrl_new_custom(hdl_fb, &vivid_ctrl_class, NULL); 162062306a36Sopenharmony_ci v4l2_ctrl_handler_init(hdl_vid_cap, 55); 162162306a36Sopenharmony_ci v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_class, NULL); 162262306a36Sopenharmony_ci v4l2_ctrl_handler_init(hdl_vid_out, 26); 162362306a36Sopenharmony_ci if (!no_error_inj || dev->has_fb || dev->num_hdmi_outputs) 162462306a36Sopenharmony_ci v4l2_ctrl_new_custom(hdl_vid_out, &vivid_ctrl_class, NULL); 162562306a36Sopenharmony_ci v4l2_ctrl_handler_init(hdl_vbi_cap, 21); 162662306a36Sopenharmony_ci v4l2_ctrl_new_custom(hdl_vbi_cap, &vivid_ctrl_class, NULL); 162762306a36Sopenharmony_ci v4l2_ctrl_handler_init(hdl_vbi_out, 19); 162862306a36Sopenharmony_ci if (!no_error_inj) 162962306a36Sopenharmony_ci v4l2_ctrl_new_custom(hdl_vbi_out, &vivid_ctrl_class, NULL); 163062306a36Sopenharmony_ci v4l2_ctrl_handler_init(hdl_radio_rx, 17); 163162306a36Sopenharmony_ci v4l2_ctrl_new_custom(hdl_radio_rx, &vivid_ctrl_class, NULL); 163262306a36Sopenharmony_ci v4l2_ctrl_handler_init(hdl_radio_tx, 17); 163362306a36Sopenharmony_ci v4l2_ctrl_new_custom(hdl_radio_tx, &vivid_ctrl_class, NULL); 163462306a36Sopenharmony_ci v4l2_ctrl_handler_init(hdl_sdr_cap, 19); 163562306a36Sopenharmony_ci v4l2_ctrl_new_custom(hdl_sdr_cap, &vivid_ctrl_class, NULL); 163662306a36Sopenharmony_ci v4l2_ctrl_handler_init(hdl_meta_cap, 2); 163762306a36Sopenharmony_ci v4l2_ctrl_new_custom(hdl_meta_cap, &vivid_ctrl_class, NULL); 163862306a36Sopenharmony_ci v4l2_ctrl_handler_init(hdl_meta_out, 2); 163962306a36Sopenharmony_ci v4l2_ctrl_new_custom(hdl_meta_out, &vivid_ctrl_class, NULL); 164062306a36Sopenharmony_ci v4l2_ctrl_handler_init(hdl_tch_cap, 2); 164162306a36Sopenharmony_ci v4l2_ctrl_new_custom(hdl_tch_cap, &vivid_ctrl_class, NULL); 164262306a36Sopenharmony_ci 164362306a36Sopenharmony_ci /* User Controls */ 164462306a36Sopenharmony_ci dev->volume = v4l2_ctrl_new_std(hdl_user_aud, NULL, 164562306a36Sopenharmony_ci V4L2_CID_AUDIO_VOLUME, 0, 255, 1, 200); 164662306a36Sopenharmony_ci dev->mute = v4l2_ctrl_new_std(hdl_user_aud, NULL, 164762306a36Sopenharmony_ci V4L2_CID_AUDIO_MUTE, 0, 1, 1, 0); 164862306a36Sopenharmony_ci if (dev->has_vid_cap) { 164962306a36Sopenharmony_ci dev->brightness = v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops, 165062306a36Sopenharmony_ci V4L2_CID_BRIGHTNESS, 0, 255, 1, 128); 165162306a36Sopenharmony_ci for (i = 0; i < MAX_INPUTS; i++) 165262306a36Sopenharmony_ci dev->input_brightness[i] = 128; 165362306a36Sopenharmony_ci dev->contrast = v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops, 165462306a36Sopenharmony_ci V4L2_CID_CONTRAST, 0, 255, 1, 128); 165562306a36Sopenharmony_ci dev->saturation = v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops, 165662306a36Sopenharmony_ci V4L2_CID_SATURATION, 0, 255, 1, 128); 165762306a36Sopenharmony_ci dev->hue = v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops, 165862306a36Sopenharmony_ci V4L2_CID_HUE, -128, 128, 1, 0); 165962306a36Sopenharmony_ci v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops, 166062306a36Sopenharmony_ci V4L2_CID_HFLIP, 0, 1, 1, 0); 166162306a36Sopenharmony_ci v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops, 166262306a36Sopenharmony_ci V4L2_CID_VFLIP, 0, 1, 1, 0); 166362306a36Sopenharmony_ci dev->autogain = v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops, 166462306a36Sopenharmony_ci V4L2_CID_AUTOGAIN, 0, 1, 1, 1); 166562306a36Sopenharmony_ci dev->gain = v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops, 166662306a36Sopenharmony_ci V4L2_CID_GAIN, 0, 255, 1, 100); 166762306a36Sopenharmony_ci dev->alpha = v4l2_ctrl_new_std(hdl_user_vid, &vivid_user_vid_ctrl_ops, 166862306a36Sopenharmony_ci V4L2_CID_ALPHA_COMPONENT, 0, 255, 1, 0); 166962306a36Sopenharmony_ci } 167062306a36Sopenharmony_ci dev->button = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_button, NULL); 167162306a36Sopenharmony_ci dev->int32 = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_int32, NULL); 167262306a36Sopenharmony_ci dev->int64 = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_int64, NULL); 167362306a36Sopenharmony_ci dev->boolean = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_boolean, NULL); 167462306a36Sopenharmony_ci dev->menu = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_menu, NULL); 167562306a36Sopenharmony_ci dev->string = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_string, NULL); 167662306a36Sopenharmony_ci dev->bitmask = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_bitmask, NULL); 167762306a36Sopenharmony_ci dev->int_menu = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_int_menu, NULL); 167862306a36Sopenharmony_ci dev->ro_int32 = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_ro_int32, NULL); 167962306a36Sopenharmony_ci v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_area, NULL); 168062306a36Sopenharmony_ci v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_u32_array, NULL); 168162306a36Sopenharmony_ci v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_u32_dyn_array, NULL); 168262306a36Sopenharmony_ci v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_u16_matrix, NULL); 168362306a36Sopenharmony_ci v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_u8_4d_array, NULL); 168462306a36Sopenharmony_ci dev->pixel_array = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_u8_pixel_array, NULL); 168562306a36Sopenharmony_ci v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_s32_array, NULL); 168662306a36Sopenharmony_ci v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_s64_array, NULL); 168762306a36Sopenharmony_ci 168862306a36Sopenharmony_ci if (dev->has_vid_cap) { 168962306a36Sopenharmony_ci /* Image Processing Controls */ 169062306a36Sopenharmony_ci struct v4l2_ctrl_config vivid_ctrl_test_pattern = { 169162306a36Sopenharmony_ci .ops = &vivid_vid_cap_ctrl_ops, 169262306a36Sopenharmony_ci .id = VIVID_CID_TEST_PATTERN, 169362306a36Sopenharmony_ci .name = "Test Pattern", 169462306a36Sopenharmony_ci .type = V4L2_CTRL_TYPE_MENU, 169562306a36Sopenharmony_ci .max = TPG_PAT_NOISE, 169662306a36Sopenharmony_ci .qmenu = tpg_pattern_strings, 169762306a36Sopenharmony_ci }; 169862306a36Sopenharmony_ci 169962306a36Sopenharmony_ci dev->test_pattern = v4l2_ctrl_new_custom(hdl_vid_cap, 170062306a36Sopenharmony_ci &vivid_ctrl_test_pattern, NULL); 170162306a36Sopenharmony_ci v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_perc_fill, NULL); 170262306a36Sopenharmony_ci v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_hor_movement, NULL); 170362306a36Sopenharmony_ci v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_vert_movement, NULL); 170462306a36Sopenharmony_ci v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_osd_mode, NULL); 170562306a36Sopenharmony_ci v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_show_border, NULL); 170662306a36Sopenharmony_ci v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_show_square, NULL); 170762306a36Sopenharmony_ci v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_hflip, NULL); 170862306a36Sopenharmony_ci v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_vflip, NULL); 170962306a36Sopenharmony_ci v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_insert_sav, NULL); 171062306a36Sopenharmony_ci v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_insert_eav, NULL); 171162306a36Sopenharmony_ci v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_insert_hdmi_video_guard_band, NULL); 171262306a36Sopenharmony_ci v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_reduced_fps, NULL); 171362306a36Sopenharmony_ci if (show_ccs_cap) { 171462306a36Sopenharmony_ci dev->ctrl_has_crop_cap = v4l2_ctrl_new_custom(hdl_vid_cap, 171562306a36Sopenharmony_ci &vivid_ctrl_has_crop_cap, NULL); 171662306a36Sopenharmony_ci dev->ctrl_has_compose_cap = v4l2_ctrl_new_custom(hdl_vid_cap, 171762306a36Sopenharmony_ci &vivid_ctrl_has_compose_cap, NULL); 171862306a36Sopenharmony_ci dev->ctrl_has_scaler_cap = v4l2_ctrl_new_custom(hdl_vid_cap, 171962306a36Sopenharmony_ci &vivid_ctrl_has_scaler_cap, NULL); 172062306a36Sopenharmony_ci } 172162306a36Sopenharmony_ci 172262306a36Sopenharmony_ci v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_tstamp_src, NULL); 172362306a36Sopenharmony_ci dev->colorspace = v4l2_ctrl_new_custom(hdl_vid_cap, 172462306a36Sopenharmony_ci &vivid_ctrl_colorspace, NULL); 172562306a36Sopenharmony_ci v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_xfer_func, NULL); 172662306a36Sopenharmony_ci v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_ycbcr_enc, NULL); 172762306a36Sopenharmony_ci v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_hsv_enc, NULL); 172862306a36Sopenharmony_ci v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_quantization, NULL); 172962306a36Sopenharmony_ci v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_alpha_mode, NULL); 173062306a36Sopenharmony_ci } 173162306a36Sopenharmony_ci 173262306a36Sopenharmony_ci if (dev->has_vid_out && show_ccs_out) { 173362306a36Sopenharmony_ci dev->ctrl_has_crop_out = v4l2_ctrl_new_custom(hdl_vid_out, 173462306a36Sopenharmony_ci &vivid_ctrl_has_crop_out, NULL); 173562306a36Sopenharmony_ci dev->ctrl_has_compose_out = v4l2_ctrl_new_custom(hdl_vid_out, 173662306a36Sopenharmony_ci &vivid_ctrl_has_compose_out, NULL); 173762306a36Sopenharmony_ci dev->ctrl_has_scaler_out = v4l2_ctrl_new_custom(hdl_vid_out, 173862306a36Sopenharmony_ci &vivid_ctrl_has_scaler_out, NULL); 173962306a36Sopenharmony_ci } 174062306a36Sopenharmony_ci 174162306a36Sopenharmony_ci /* 174262306a36Sopenharmony_ci * Testing this driver with v4l2-compliance will trigger the error 174362306a36Sopenharmony_ci * injection controls, and after that nothing will work as expected. 174462306a36Sopenharmony_ci * So we have a module option to drop these error injecting controls 174562306a36Sopenharmony_ci * allowing us to run v4l2_compliance again. 174662306a36Sopenharmony_ci */ 174762306a36Sopenharmony_ci if (!no_error_inj) { 174862306a36Sopenharmony_ci v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_disconnect, NULL); 174962306a36Sopenharmony_ci v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_dqbuf_error, NULL); 175062306a36Sopenharmony_ci v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_perc_dropped, NULL); 175162306a36Sopenharmony_ci v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_queue_setup_error, NULL); 175262306a36Sopenharmony_ci v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_buf_prepare_error, NULL); 175362306a36Sopenharmony_ci v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_start_streaming_error, NULL); 175462306a36Sopenharmony_ci v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_queue_error, NULL); 175562306a36Sopenharmony_ci#ifdef CONFIG_MEDIA_CONTROLLER 175662306a36Sopenharmony_ci v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_req_validate_error, NULL); 175762306a36Sopenharmony_ci#endif 175862306a36Sopenharmony_ci v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_seq_wrap, NULL); 175962306a36Sopenharmony_ci v4l2_ctrl_new_custom(hdl_streaming, &vivid_ctrl_time_wrap, NULL); 176062306a36Sopenharmony_ci } 176162306a36Sopenharmony_ci 176262306a36Sopenharmony_ci if (has_sdtv && (dev->has_vid_cap || dev->has_vbi_cap)) { 176362306a36Sopenharmony_ci if (dev->has_vid_cap) 176462306a36Sopenharmony_ci v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_std_aspect_ratio, NULL); 176562306a36Sopenharmony_ci dev->ctrl_std_signal_mode = v4l2_ctrl_new_custom(hdl_sdtv_cap, 176662306a36Sopenharmony_ci &vivid_ctrl_std_signal_mode, NULL); 176762306a36Sopenharmony_ci dev->ctrl_standard = v4l2_ctrl_new_custom(hdl_sdtv_cap, 176862306a36Sopenharmony_ci &vivid_ctrl_standard, NULL); 176962306a36Sopenharmony_ci if (dev->ctrl_std_signal_mode) 177062306a36Sopenharmony_ci v4l2_ctrl_cluster(2, &dev->ctrl_std_signal_mode); 177162306a36Sopenharmony_ci if (dev->has_raw_vbi_cap) 177262306a36Sopenharmony_ci v4l2_ctrl_new_custom(hdl_vbi_cap, &vivid_ctrl_vbi_cap_interlaced, NULL); 177362306a36Sopenharmony_ci } 177462306a36Sopenharmony_ci 177562306a36Sopenharmony_ci if (dev->num_hdmi_inputs) { 177662306a36Sopenharmony_ci s64 hdmi_input_mask = GENMASK(dev->num_hdmi_inputs - 1, 0); 177762306a36Sopenharmony_ci 177862306a36Sopenharmony_ci dev->ctrl_dv_timings_signal_mode = v4l2_ctrl_new_custom(hdl_vid_cap, 177962306a36Sopenharmony_ci &vivid_ctrl_dv_timings_signal_mode, NULL); 178062306a36Sopenharmony_ci 178162306a36Sopenharmony_ci vivid_ctrl_dv_timings.max = dev->query_dv_timings_size - 1; 178262306a36Sopenharmony_ci vivid_ctrl_dv_timings.qmenu = 178362306a36Sopenharmony_ci (const char * const *)dev->query_dv_timings_qmenu; 178462306a36Sopenharmony_ci dev->ctrl_dv_timings = v4l2_ctrl_new_custom(hdl_vid_cap, 178562306a36Sopenharmony_ci &vivid_ctrl_dv_timings, NULL); 178662306a36Sopenharmony_ci if (dev->ctrl_dv_timings_signal_mode) 178762306a36Sopenharmony_ci v4l2_ctrl_cluster(2, &dev->ctrl_dv_timings_signal_mode); 178862306a36Sopenharmony_ci 178962306a36Sopenharmony_ci v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_dv_timings_aspect_ratio, NULL); 179062306a36Sopenharmony_ci v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_max_edid_blocks, NULL); 179162306a36Sopenharmony_ci dev->real_rgb_range_cap = v4l2_ctrl_new_custom(hdl_vid_cap, 179262306a36Sopenharmony_ci &vivid_ctrl_limited_rgb_range, NULL); 179362306a36Sopenharmony_ci dev->rgb_range_cap = v4l2_ctrl_new_std_menu(hdl_vid_cap, 179462306a36Sopenharmony_ci &vivid_vid_cap_ctrl_ops, 179562306a36Sopenharmony_ci V4L2_CID_DV_RX_RGB_RANGE, V4L2_DV_RGB_RANGE_FULL, 179662306a36Sopenharmony_ci 0, V4L2_DV_RGB_RANGE_AUTO); 179762306a36Sopenharmony_ci dev->ctrl_rx_power_present = v4l2_ctrl_new_std(hdl_vid_cap, 179862306a36Sopenharmony_ci NULL, V4L2_CID_DV_RX_POWER_PRESENT, 0, hdmi_input_mask, 179962306a36Sopenharmony_ci 0, hdmi_input_mask); 180062306a36Sopenharmony_ci 180162306a36Sopenharmony_ci } 180262306a36Sopenharmony_ci if (dev->num_hdmi_outputs) { 180362306a36Sopenharmony_ci s64 hdmi_output_mask = GENMASK(dev->num_hdmi_outputs - 1, 0); 180462306a36Sopenharmony_ci 180562306a36Sopenharmony_ci /* 180662306a36Sopenharmony_ci * We aren't doing anything with this at the moment, but 180762306a36Sopenharmony_ci * HDMI outputs typically have this controls. 180862306a36Sopenharmony_ci */ 180962306a36Sopenharmony_ci dev->ctrl_tx_rgb_range = v4l2_ctrl_new_std_menu(hdl_vid_out, NULL, 181062306a36Sopenharmony_ci V4L2_CID_DV_TX_RGB_RANGE, V4L2_DV_RGB_RANGE_FULL, 181162306a36Sopenharmony_ci 0, V4L2_DV_RGB_RANGE_AUTO); 181262306a36Sopenharmony_ci dev->ctrl_tx_mode = v4l2_ctrl_new_std_menu(hdl_vid_out, NULL, 181362306a36Sopenharmony_ci V4L2_CID_DV_TX_MODE, V4L2_DV_TX_MODE_HDMI, 181462306a36Sopenharmony_ci 0, V4L2_DV_TX_MODE_HDMI); 181562306a36Sopenharmony_ci dev->ctrl_display_present = v4l2_ctrl_new_custom(hdl_vid_out, 181662306a36Sopenharmony_ci &vivid_ctrl_display_present, NULL); 181762306a36Sopenharmony_ci dev->ctrl_tx_hotplug = v4l2_ctrl_new_std(hdl_vid_out, 181862306a36Sopenharmony_ci NULL, V4L2_CID_DV_TX_HOTPLUG, 0, hdmi_output_mask, 181962306a36Sopenharmony_ci 0, hdmi_output_mask); 182062306a36Sopenharmony_ci dev->ctrl_tx_rxsense = v4l2_ctrl_new_std(hdl_vid_out, 182162306a36Sopenharmony_ci NULL, V4L2_CID_DV_TX_RXSENSE, 0, hdmi_output_mask, 182262306a36Sopenharmony_ci 0, hdmi_output_mask); 182362306a36Sopenharmony_ci dev->ctrl_tx_edid_present = v4l2_ctrl_new_std(hdl_vid_out, 182462306a36Sopenharmony_ci NULL, V4L2_CID_DV_TX_EDID_PRESENT, 0, hdmi_output_mask, 182562306a36Sopenharmony_ci 0, hdmi_output_mask); 182662306a36Sopenharmony_ci } 182762306a36Sopenharmony_ci if ((dev->has_vid_cap && dev->has_vid_out) || 182862306a36Sopenharmony_ci (dev->has_vbi_cap && dev->has_vbi_out)) 182962306a36Sopenharmony_ci v4l2_ctrl_new_custom(hdl_loop_cap, &vivid_ctrl_loop_video, NULL); 183062306a36Sopenharmony_ci 183162306a36Sopenharmony_ci if (dev->has_fb) 183262306a36Sopenharmony_ci v4l2_ctrl_new_custom(hdl_fb, &vivid_ctrl_clear_fb, NULL); 183362306a36Sopenharmony_ci 183462306a36Sopenharmony_ci if (dev->has_radio_rx) { 183562306a36Sopenharmony_ci v4l2_ctrl_new_custom(hdl_radio_rx, &vivid_ctrl_radio_hw_seek_mode, NULL); 183662306a36Sopenharmony_ci v4l2_ctrl_new_custom(hdl_radio_rx, &vivid_ctrl_radio_hw_seek_prog_lim, NULL); 183762306a36Sopenharmony_ci v4l2_ctrl_new_custom(hdl_radio_rx, &vivid_ctrl_radio_rx_rds_blockio, NULL); 183862306a36Sopenharmony_ci v4l2_ctrl_new_custom(hdl_radio_rx, &vivid_ctrl_radio_rx_rds_rbds, NULL); 183962306a36Sopenharmony_ci v4l2_ctrl_new_std(hdl_radio_rx, &vivid_radio_rx_ctrl_ops, 184062306a36Sopenharmony_ci V4L2_CID_RDS_RECEPTION, 0, 1, 1, 1); 184162306a36Sopenharmony_ci dev->radio_rx_rds_pty = v4l2_ctrl_new_std(hdl_radio_rx, 184262306a36Sopenharmony_ci &vivid_radio_rx_ctrl_ops, 184362306a36Sopenharmony_ci V4L2_CID_RDS_RX_PTY, 0, 31, 1, 0); 184462306a36Sopenharmony_ci dev->radio_rx_rds_psname = v4l2_ctrl_new_std(hdl_radio_rx, 184562306a36Sopenharmony_ci &vivid_radio_rx_ctrl_ops, 184662306a36Sopenharmony_ci V4L2_CID_RDS_RX_PS_NAME, 0, 8, 8, 0); 184762306a36Sopenharmony_ci dev->radio_rx_rds_radiotext = v4l2_ctrl_new_std(hdl_radio_rx, 184862306a36Sopenharmony_ci &vivid_radio_rx_ctrl_ops, 184962306a36Sopenharmony_ci V4L2_CID_RDS_RX_RADIO_TEXT, 0, 64, 64, 0); 185062306a36Sopenharmony_ci dev->radio_rx_rds_ta = v4l2_ctrl_new_std(hdl_radio_rx, 185162306a36Sopenharmony_ci &vivid_radio_rx_ctrl_ops, 185262306a36Sopenharmony_ci V4L2_CID_RDS_RX_TRAFFIC_ANNOUNCEMENT, 0, 1, 1, 0); 185362306a36Sopenharmony_ci dev->radio_rx_rds_tp = v4l2_ctrl_new_std(hdl_radio_rx, 185462306a36Sopenharmony_ci &vivid_radio_rx_ctrl_ops, 185562306a36Sopenharmony_ci V4L2_CID_RDS_RX_TRAFFIC_PROGRAM, 0, 1, 1, 0); 185662306a36Sopenharmony_ci dev->radio_rx_rds_ms = v4l2_ctrl_new_std(hdl_radio_rx, 185762306a36Sopenharmony_ci &vivid_radio_rx_ctrl_ops, 185862306a36Sopenharmony_ci V4L2_CID_RDS_RX_MUSIC_SPEECH, 0, 1, 1, 1); 185962306a36Sopenharmony_ci } 186062306a36Sopenharmony_ci if (dev->has_radio_tx) { 186162306a36Sopenharmony_ci v4l2_ctrl_new_custom(hdl_radio_tx, 186262306a36Sopenharmony_ci &vivid_ctrl_radio_tx_rds_blockio, NULL); 186362306a36Sopenharmony_ci dev->radio_tx_rds_pi = v4l2_ctrl_new_std(hdl_radio_tx, 186462306a36Sopenharmony_ci &vivid_radio_tx_ctrl_ops, 186562306a36Sopenharmony_ci V4L2_CID_RDS_TX_PI, 0, 0xffff, 1, 0x8088); 186662306a36Sopenharmony_ci dev->radio_tx_rds_pty = v4l2_ctrl_new_std(hdl_radio_tx, 186762306a36Sopenharmony_ci &vivid_radio_tx_ctrl_ops, 186862306a36Sopenharmony_ci V4L2_CID_RDS_TX_PTY, 0, 31, 1, 3); 186962306a36Sopenharmony_ci dev->radio_tx_rds_psname = v4l2_ctrl_new_std(hdl_radio_tx, 187062306a36Sopenharmony_ci &vivid_radio_tx_ctrl_ops, 187162306a36Sopenharmony_ci V4L2_CID_RDS_TX_PS_NAME, 0, 8, 8, 0); 187262306a36Sopenharmony_ci if (dev->radio_tx_rds_psname) 187362306a36Sopenharmony_ci v4l2_ctrl_s_ctrl_string(dev->radio_tx_rds_psname, "VIVID-TX"); 187462306a36Sopenharmony_ci dev->radio_tx_rds_radiotext = v4l2_ctrl_new_std(hdl_radio_tx, 187562306a36Sopenharmony_ci &vivid_radio_tx_ctrl_ops, 187662306a36Sopenharmony_ci V4L2_CID_RDS_TX_RADIO_TEXT, 0, 64 * 2, 64, 0); 187762306a36Sopenharmony_ci if (dev->radio_tx_rds_radiotext) 187862306a36Sopenharmony_ci v4l2_ctrl_s_ctrl_string(dev->radio_tx_rds_radiotext, 187962306a36Sopenharmony_ci "This is a VIVID default Radio Text template text, change at will"); 188062306a36Sopenharmony_ci dev->radio_tx_rds_mono_stereo = v4l2_ctrl_new_std(hdl_radio_tx, 188162306a36Sopenharmony_ci &vivid_radio_tx_ctrl_ops, 188262306a36Sopenharmony_ci V4L2_CID_RDS_TX_MONO_STEREO, 0, 1, 1, 1); 188362306a36Sopenharmony_ci dev->radio_tx_rds_art_head = v4l2_ctrl_new_std(hdl_radio_tx, 188462306a36Sopenharmony_ci &vivid_radio_tx_ctrl_ops, 188562306a36Sopenharmony_ci V4L2_CID_RDS_TX_ARTIFICIAL_HEAD, 0, 1, 1, 0); 188662306a36Sopenharmony_ci dev->radio_tx_rds_compressed = v4l2_ctrl_new_std(hdl_radio_tx, 188762306a36Sopenharmony_ci &vivid_radio_tx_ctrl_ops, 188862306a36Sopenharmony_ci V4L2_CID_RDS_TX_COMPRESSED, 0, 1, 1, 0); 188962306a36Sopenharmony_ci dev->radio_tx_rds_dyn_pty = v4l2_ctrl_new_std(hdl_radio_tx, 189062306a36Sopenharmony_ci &vivid_radio_tx_ctrl_ops, 189162306a36Sopenharmony_ci V4L2_CID_RDS_TX_DYNAMIC_PTY, 0, 1, 1, 0); 189262306a36Sopenharmony_ci dev->radio_tx_rds_ta = v4l2_ctrl_new_std(hdl_radio_tx, 189362306a36Sopenharmony_ci &vivid_radio_tx_ctrl_ops, 189462306a36Sopenharmony_ci V4L2_CID_RDS_TX_TRAFFIC_ANNOUNCEMENT, 0, 1, 1, 0); 189562306a36Sopenharmony_ci dev->radio_tx_rds_tp = v4l2_ctrl_new_std(hdl_radio_tx, 189662306a36Sopenharmony_ci &vivid_radio_tx_ctrl_ops, 189762306a36Sopenharmony_ci V4L2_CID_RDS_TX_TRAFFIC_PROGRAM, 0, 1, 1, 1); 189862306a36Sopenharmony_ci dev->radio_tx_rds_ms = v4l2_ctrl_new_std(hdl_radio_tx, 189962306a36Sopenharmony_ci &vivid_radio_tx_ctrl_ops, 190062306a36Sopenharmony_ci V4L2_CID_RDS_TX_MUSIC_SPEECH, 0, 1, 1, 1); 190162306a36Sopenharmony_ci } 190262306a36Sopenharmony_ci if (dev->has_sdr_cap) { 190362306a36Sopenharmony_ci v4l2_ctrl_new_custom(hdl_sdr_cap, 190462306a36Sopenharmony_ci &vivid_ctrl_sdr_cap_fm_deviation, NULL); 190562306a36Sopenharmony_ci } 190662306a36Sopenharmony_ci if (dev->has_meta_cap) { 190762306a36Sopenharmony_ci v4l2_ctrl_new_custom(hdl_meta_cap, 190862306a36Sopenharmony_ci &vivid_ctrl_meta_has_pts, NULL); 190962306a36Sopenharmony_ci v4l2_ctrl_new_custom(hdl_meta_cap, 191062306a36Sopenharmony_ci &vivid_ctrl_meta_has_src_clk, NULL); 191162306a36Sopenharmony_ci } 191262306a36Sopenharmony_ci 191362306a36Sopenharmony_ci if (hdl_user_gen->error) 191462306a36Sopenharmony_ci return hdl_user_gen->error; 191562306a36Sopenharmony_ci if (hdl_user_vid->error) 191662306a36Sopenharmony_ci return hdl_user_vid->error; 191762306a36Sopenharmony_ci if (hdl_user_aud->error) 191862306a36Sopenharmony_ci return hdl_user_aud->error; 191962306a36Sopenharmony_ci if (hdl_streaming->error) 192062306a36Sopenharmony_ci return hdl_streaming->error; 192162306a36Sopenharmony_ci if (hdl_sdr_cap->error) 192262306a36Sopenharmony_ci return hdl_sdr_cap->error; 192362306a36Sopenharmony_ci if (hdl_loop_cap->error) 192462306a36Sopenharmony_ci return hdl_loop_cap->error; 192562306a36Sopenharmony_ci 192662306a36Sopenharmony_ci if (dev->autogain) 192762306a36Sopenharmony_ci v4l2_ctrl_auto_cluster(2, &dev->autogain, 0, true); 192862306a36Sopenharmony_ci 192962306a36Sopenharmony_ci if (dev->has_vid_cap) { 193062306a36Sopenharmony_ci v4l2_ctrl_add_handler(hdl_vid_cap, hdl_user_gen, NULL, false); 193162306a36Sopenharmony_ci v4l2_ctrl_add_handler(hdl_vid_cap, hdl_user_vid, NULL, false); 193262306a36Sopenharmony_ci v4l2_ctrl_add_handler(hdl_vid_cap, hdl_user_aud, NULL, false); 193362306a36Sopenharmony_ci v4l2_ctrl_add_handler(hdl_vid_cap, hdl_streaming, NULL, false); 193462306a36Sopenharmony_ci v4l2_ctrl_add_handler(hdl_vid_cap, hdl_sdtv_cap, NULL, false); 193562306a36Sopenharmony_ci v4l2_ctrl_add_handler(hdl_vid_cap, hdl_loop_cap, NULL, false); 193662306a36Sopenharmony_ci v4l2_ctrl_add_handler(hdl_vid_cap, hdl_fb, NULL, false); 193762306a36Sopenharmony_ci if (hdl_vid_cap->error) 193862306a36Sopenharmony_ci return hdl_vid_cap->error; 193962306a36Sopenharmony_ci dev->vid_cap_dev.ctrl_handler = hdl_vid_cap; 194062306a36Sopenharmony_ci } 194162306a36Sopenharmony_ci if (dev->has_vid_out) { 194262306a36Sopenharmony_ci v4l2_ctrl_add_handler(hdl_vid_out, hdl_user_gen, NULL, false); 194362306a36Sopenharmony_ci v4l2_ctrl_add_handler(hdl_vid_out, hdl_user_aud, NULL, false); 194462306a36Sopenharmony_ci v4l2_ctrl_add_handler(hdl_vid_out, hdl_streaming, NULL, false); 194562306a36Sopenharmony_ci v4l2_ctrl_add_handler(hdl_vid_out, hdl_fb, NULL, false); 194662306a36Sopenharmony_ci if (hdl_vid_out->error) 194762306a36Sopenharmony_ci return hdl_vid_out->error; 194862306a36Sopenharmony_ci dev->vid_out_dev.ctrl_handler = hdl_vid_out; 194962306a36Sopenharmony_ci } 195062306a36Sopenharmony_ci if (dev->has_vbi_cap) { 195162306a36Sopenharmony_ci v4l2_ctrl_add_handler(hdl_vbi_cap, hdl_user_gen, NULL, false); 195262306a36Sopenharmony_ci v4l2_ctrl_add_handler(hdl_vbi_cap, hdl_streaming, NULL, false); 195362306a36Sopenharmony_ci v4l2_ctrl_add_handler(hdl_vbi_cap, hdl_sdtv_cap, NULL, false); 195462306a36Sopenharmony_ci v4l2_ctrl_add_handler(hdl_vbi_cap, hdl_loop_cap, NULL, false); 195562306a36Sopenharmony_ci if (hdl_vbi_cap->error) 195662306a36Sopenharmony_ci return hdl_vbi_cap->error; 195762306a36Sopenharmony_ci dev->vbi_cap_dev.ctrl_handler = hdl_vbi_cap; 195862306a36Sopenharmony_ci } 195962306a36Sopenharmony_ci if (dev->has_vbi_out) { 196062306a36Sopenharmony_ci v4l2_ctrl_add_handler(hdl_vbi_out, hdl_user_gen, NULL, false); 196162306a36Sopenharmony_ci v4l2_ctrl_add_handler(hdl_vbi_out, hdl_streaming, NULL, false); 196262306a36Sopenharmony_ci if (hdl_vbi_out->error) 196362306a36Sopenharmony_ci return hdl_vbi_out->error; 196462306a36Sopenharmony_ci dev->vbi_out_dev.ctrl_handler = hdl_vbi_out; 196562306a36Sopenharmony_ci } 196662306a36Sopenharmony_ci if (dev->has_radio_rx) { 196762306a36Sopenharmony_ci v4l2_ctrl_add_handler(hdl_radio_rx, hdl_user_gen, NULL, false); 196862306a36Sopenharmony_ci v4l2_ctrl_add_handler(hdl_radio_rx, hdl_user_aud, NULL, false); 196962306a36Sopenharmony_ci if (hdl_radio_rx->error) 197062306a36Sopenharmony_ci return hdl_radio_rx->error; 197162306a36Sopenharmony_ci dev->radio_rx_dev.ctrl_handler = hdl_radio_rx; 197262306a36Sopenharmony_ci } 197362306a36Sopenharmony_ci if (dev->has_radio_tx) { 197462306a36Sopenharmony_ci v4l2_ctrl_add_handler(hdl_radio_tx, hdl_user_gen, NULL, false); 197562306a36Sopenharmony_ci v4l2_ctrl_add_handler(hdl_radio_tx, hdl_user_aud, NULL, false); 197662306a36Sopenharmony_ci if (hdl_radio_tx->error) 197762306a36Sopenharmony_ci return hdl_radio_tx->error; 197862306a36Sopenharmony_ci dev->radio_tx_dev.ctrl_handler = hdl_radio_tx; 197962306a36Sopenharmony_ci } 198062306a36Sopenharmony_ci if (dev->has_sdr_cap) { 198162306a36Sopenharmony_ci v4l2_ctrl_add_handler(hdl_sdr_cap, hdl_user_gen, NULL, false); 198262306a36Sopenharmony_ci v4l2_ctrl_add_handler(hdl_sdr_cap, hdl_streaming, NULL, false); 198362306a36Sopenharmony_ci if (hdl_sdr_cap->error) 198462306a36Sopenharmony_ci return hdl_sdr_cap->error; 198562306a36Sopenharmony_ci dev->sdr_cap_dev.ctrl_handler = hdl_sdr_cap; 198662306a36Sopenharmony_ci } 198762306a36Sopenharmony_ci if (dev->has_meta_cap) { 198862306a36Sopenharmony_ci v4l2_ctrl_add_handler(hdl_meta_cap, hdl_user_gen, NULL, false); 198962306a36Sopenharmony_ci v4l2_ctrl_add_handler(hdl_meta_cap, hdl_streaming, NULL, false); 199062306a36Sopenharmony_ci if (hdl_meta_cap->error) 199162306a36Sopenharmony_ci return hdl_meta_cap->error; 199262306a36Sopenharmony_ci dev->meta_cap_dev.ctrl_handler = hdl_meta_cap; 199362306a36Sopenharmony_ci } 199462306a36Sopenharmony_ci if (dev->has_meta_out) { 199562306a36Sopenharmony_ci v4l2_ctrl_add_handler(hdl_meta_out, hdl_user_gen, NULL, false); 199662306a36Sopenharmony_ci v4l2_ctrl_add_handler(hdl_meta_out, hdl_streaming, NULL, false); 199762306a36Sopenharmony_ci if (hdl_meta_out->error) 199862306a36Sopenharmony_ci return hdl_meta_out->error; 199962306a36Sopenharmony_ci dev->meta_out_dev.ctrl_handler = hdl_meta_out; 200062306a36Sopenharmony_ci } 200162306a36Sopenharmony_ci if (dev->has_touch_cap) { 200262306a36Sopenharmony_ci v4l2_ctrl_add_handler(hdl_tch_cap, hdl_user_gen, NULL, false); 200362306a36Sopenharmony_ci v4l2_ctrl_add_handler(hdl_tch_cap, hdl_streaming, NULL, false); 200462306a36Sopenharmony_ci if (hdl_tch_cap->error) 200562306a36Sopenharmony_ci return hdl_tch_cap->error; 200662306a36Sopenharmony_ci dev->touch_cap_dev.ctrl_handler = hdl_tch_cap; 200762306a36Sopenharmony_ci } 200862306a36Sopenharmony_ci return 0; 200962306a36Sopenharmony_ci} 201062306a36Sopenharmony_ci 201162306a36Sopenharmony_civoid vivid_free_controls(struct vivid_dev *dev) 201262306a36Sopenharmony_ci{ 201362306a36Sopenharmony_ci v4l2_ctrl_handler_free(&dev->ctrl_hdl_vid_cap); 201462306a36Sopenharmony_ci v4l2_ctrl_handler_free(&dev->ctrl_hdl_vid_out); 201562306a36Sopenharmony_ci v4l2_ctrl_handler_free(&dev->ctrl_hdl_vbi_cap); 201662306a36Sopenharmony_ci v4l2_ctrl_handler_free(&dev->ctrl_hdl_vbi_out); 201762306a36Sopenharmony_ci v4l2_ctrl_handler_free(&dev->ctrl_hdl_radio_rx); 201862306a36Sopenharmony_ci v4l2_ctrl_handler_free(&dev->ctrl_hdl_radio_tx); 201962306a36Sopenharmony_ci v4l2_ctrl_handler_free(&dev->ctrl_hdl_sdr_cap); 202062306a36Sopenharmony_ci v4l2_ctrl_handler_free(&dev->ctrl_hdl_user_gen); 202162306a36Sopenharmony_ci v4l2_ctrl_handler_free(&dev->ctrl_hdl_user_vid); 202262306a36Sopenharmony_ci v4l2_ctrl_handler_free(&dev->ctrl_hdl_user_aud); 202362306a36Sopenharmony_ci v4l2_ctrl_handler_free(&dev->ctrl_hdl_streaming); 202462306a36Sopenharmony_ci v4l2_ctrl_handler_free(&dev->ctrl_hdl_sdtv_cap); 202562306a36Sopenharmony_ci v4l2_ctrl_handler_free(&dev->ctrl_hdl_loop_cap); 202662306a36Sopenharmony_ci v4l2_ctrl_handler_free(&dev->ctrl_hdl_fb); 202762306a36Sopenharmony_ci v4l2_ctrl_handler_free(&dev->ctrl_hdl_meta_cap); 202862306a36Sopenharmony_ci v4l2_ctrl_handler_free(&dev->ctrl_hdl_meta_out); 202962306a36Sopenharmony_ci v4l2_ctrl_handler_free(&dev->ctrl_hdl_touch_cap); 203062306a36Sopenharmony_ci} 2031