^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) // Copyright (c) 2019 Intel Corporation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) #include <asm/unaligned.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) #include <linux/acpi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/gpio/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/pm_runtime.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/regulator/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <media/v4l2-ctrls.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <media/v4l2-device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <media/v4l2-fwnode.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #define OV8856_REG_VALUE_08BIT 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #define OV8856_REG_VALUE_16BIT 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #define OV8856_REG_VALUE_24BIT 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #define OV8856_LINK_FREQ_360MHZ 360000000ULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define OV8856_LINK_FREQ_180MHZ 180000000ULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #define OV8856_SCLK 144000000ULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define OV8856_XVCLK_19_2 19200000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define OV8856_DATA_LANES 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define OV8856_RGB_DEPTH 10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define OV8856_REG_CHIP_ID 0x300a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define OV8856_CHIP_ID 0x00885a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define OV8856_REG_MODE_SELECT 0x0100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define OV8856_MODE_STANDBY 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define OV8856_MODE_STREAMING 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) /* module revisions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define OV8856_2A_MODULE 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define OV8856_1B_MODULE 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) /* the OTP read-out buffer is at 0x7000 and 0xf is the offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) * of the byte in the OTP that means the module revision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define OV8856_MODULE_REVISION 0x700f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define OV8856_OTP_MODE_CTRL 0x3d84
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define OV8856_OTP_LOAD_CTRL 0x3d81
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define OV8856_OTP_MODE_AUTO 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define OV8856_OTP_LOAD_CTRL_ENABLE BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) /* vertical-timings from sensor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define OV8856_REG_VTS 0x380e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define OV8856_VTS_MAX 0x7fff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) /* horizontal-timings from sensor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define OV8856_REG_HTS 0x380c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) /* Exposure controls from sensor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define OV8856_REG_EXPOSURE 0x3500
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define OV8856_EXPOSURE_MIN 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define OV8856_EXPOSURE_MAX_MARGIN 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define OV8856_EXPOSURE_STEP 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) /* Analog gain controls from sensor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define OV8856_REG_ANALOG_GAIN 0x3508
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define OV8856_ANAL_GAIN_MIN 128
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define OV8856_ANAL_GAIN_MAX 2047
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define OV8856_ANAL_GAIN_STEP 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) /* Digital gain controls from sensor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define OV8856_REG_MWB_R_GAIN 0x5019
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define OV8856_REG_MWB_G_GAIN 0x501b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define OV8856_REG_MWB_B_GAIN 0x501d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define OV8856_DGTL_GAIN_MIN 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define OV8856_DGTL_GAIN_MAX 4095
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define OV8856_DGTL_GAIN_STEP 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #define OV8856_DGTL_GAIN_DEFAULT 1024
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) /* Test Pattern Control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define OV8856_REG_TEST_PATTERN 0x5e00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #define OV8856_TEST_PATTERN_ENABLE BIT(7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #define OV8856_TEST_PATTERN_BAR_SHIFT 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #define to_ov8856(_sd) container_of(_sd, struct ov8856, sd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) static const char * const ov8856_supply_names[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) "dovdd", /* Digital I/O power */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) "avdd", /* Analog power */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) "dvdd", /* Digital core power */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) OV8856_LINK_FREQ_720MBPS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) OV8856_LINK_FREQ_360MBPS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) struct ov8856_reg {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) u16 address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) u8 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) struct ov8856_reg_list {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) u32 num_of_regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) const struct ov8856_reg *regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) struct ov8856_link_freq_config {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) const struct ov8856_reg_list reg_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) struct ov8856_mode {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) /* Frame width in pixels */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) u32 width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) /* Frame height in pixels */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) u32 height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) /* Horizontal timining size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) u32 hts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) /* Default vertical timining size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) u32 vts_def;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) /* Min vertical timining size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) u32 vts_min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) /* Link frequency needed for this resolution */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) u32 link_freq_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) /* Sensor register settings for this resolution */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) const struct ov8856_reg_list reg_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) static const struct ov8856_reg mipi_data_rate_720mbps[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) {0x0103, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) {0x0100, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) {0x0302, 0x4b},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) {0x0303, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) {0x030b, 0x02},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) {0x030d, 0x4b},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) {0x031e, 0x0c},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) static const struct ov8856_reg mipi_data_rate_360mbps[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) {0x0103, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) {0x0100, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) {0x0302, 0x4b},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) {0x0303, 0x03},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) {0x030b, 0x02},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) {0x030d, 0x4b},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) {0x031e, 0x0c},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) static const struct ov8856_reg mode_3280x2464_regs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) {0x3000, 0x20},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) {0x3003, 0x08},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) {0x300e, 0x20},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) {0x3010, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) {0x3015, 0x84},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) {0x3018, 0x72},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) {0x3021, 0x23},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) {0x3033, 0x24},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) {0x3500, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) {0x3501, 0x9a},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) {0x3502, 0x20},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) {0x3503, 0x08},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) {0x3505, 0x83},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) {0x3508, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) {0x3509, 0x80},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) {0x350c, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) {0x350d, 0x80},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) {0x350e, 0x04},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) {0x350f, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) {0x3510, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) {0x3511, 0x02},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) {0x3512, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) {0x3600, 0x72},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) {0x3601, 0x40},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) {0x3602, 0x30},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) {0x3610, 0xc5},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) {0x3611, 0x58},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) {0x3612, 0x5c},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) {0x3613, 0xca},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) {0x3614, 0x20},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) {0x3628, 0xff},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) {0x3629, 0xff},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) {0x362a, 0xff},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) {0x3633, 0x10},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) {0x3634, 0x10},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) {0x3635, 0x10},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) {0x3636, 0x10},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) {0x3663, 0x08},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) {0x3669, 0x34},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) {0x366e, 0x10},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) {0x3706, 0x86},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) {0x370b, 0x7e},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) {0x3714, 0x23},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) {0x3730, 0x12},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) {0x3733, 0x10},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) {0x3764, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) {0x3765, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) {0x3769, 0x62},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) {0x376a, 0x2a},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) {0x376b, 0x30},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) {0x3780, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) {0x3781, 0x24},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) {0x3782, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) {0x3783, 0x23},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) {0x3798, 0x2f},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) {0x37a1, 0x60},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) {0x37a8, 0x6a},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) {0x37ab, 0x3f},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) {0x37c2, 0x04},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) {0x37c3, 0xf1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) {0x37c9, 0x80},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) {0x37cb, 0x16},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) {0x37cc, 0x16},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) {0x37cd, 0x16},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) {0x37ce, 0x16},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) {0x3800, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) {0x3801, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) {0x3802, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) {0x3803, 0x06},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) {0x3804, 0x0c},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) {0x3805, 0xdf},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) {0x3806, 0x09},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) {0x3807, 0xa7},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) {0x3808, 0x0c},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) {0x3809, 0xd0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) {0x380a, 0x09},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) {0x380b, 0xa0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) {0x380c, 0x07},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) {0x380d, 0x88},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) {0x380e, 0x09},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) {0x380f, 0xb8},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) {0x3810, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) {0x3811, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) {0x3812, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) {0x3813, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) {0x3814, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) {0x3815, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) {0x3816, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) {0x3817, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) {0x3818, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) {0x3819, 0x10},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) {0x3820, 0x80},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) {0x3821, 0x46},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) {0x382a, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) {0x382b, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) {0x3830, 0x06},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) {0x3836, 0x02},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) {0x3862, 0x04},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) {0x3863, 0x08},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) {0x3cc0, 0x33},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) {0x3d85, 0x17},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) {0x3d8c, 0x73},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) {0x3d8d, 0xde},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) {0x4001, 0xe0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) {0x4003, 0x40},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) {0x4008, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) {0x4009, 0x0b},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) {0x400a, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) {0x400b, 0x84},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) {0x400f, 0x80},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) {0x4010, 0xf0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) {0x4011, 0xff},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) {0x4012, 0x02},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) {0x4013, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) {0x4014, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) {0x4015, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) {0x4042, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) {0x4043, 0x80},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) {0x4044, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) {0x4045, 0x80},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) {0x4046, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) {0x4047, 0x80},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) {0x4048, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) {0x4049, 0x80},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) {0x4041, 0x03},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) {0x404c, 0x20},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) {0x404d, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) {0x404e, 0x20},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) {0x4203, 0x80},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) {0x4307, 0x30},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) {0x4317, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) {0x4503, 0x08},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) {0x4601, 0x80},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) {0x4800, 0x44},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) {0x4816, 0x53},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) {0x481b, 0x58},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) {0x481f, 0x27},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) {0x4837, 0x16},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) {0x483c, 0x0f},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) {0x484b, 0x05},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) {0x5000, 0x57},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) {0x5001, 0x0a},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) {0x5004, 0x04},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) {0x502e, 0x03},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) {0x5030, 0x41},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) {0x5780, 0x14},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) {0x5781, 0x0f},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) {0x5782, 0x44},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) {0x5783, 0x02},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) {0x5784, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) {0x5785, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) {0x5786, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) {0x5787, 0x04},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) {0x5788, 0x02},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) {0x5789, 0x0f},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) {0x578a, 0xfd},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) {0x578b, 0xf5},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) {0x578c, 0xf5},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) {0x578d, 0x03},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) {0x578e, 0x08},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) {0x578f, 0x0c},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) {0x5790, 0x08},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) {0x5791, 0x04},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) {0x5792, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) {0x5793, 0x52},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) {0x5794, 0xa3},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) {0x5795, 0x02},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) {0x5796, 0x20},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) {0x5797, 0x20},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) {0x5798, 0xd5},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) {0x5799, 0xd5},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) {0x579a, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) {0x579b, 0x50},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) {0x579c, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) {0x579d, 0x2c},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) {0x579e, 0x0c},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) {0x579f, 0x40},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) {0x57a0, 0x09},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) {0x57a1, 0x40},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) {0x59f8, 0x3d},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) {0x5a08, 0x02},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) {0x5b00, 0x02},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) {0x5b01, 0x10},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) {0x5b02, 0x03},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) {0x5b03, 0xcf},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) {0x5b05, 0x6c},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) {0x5e00, 0x00}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) static const struct ov8856_reg mode_3264x2448_regs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) {0x0103, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) {0x0302, 0x3c},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) {0x0303, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) {0x031e, 0x0c},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) {0x3000, 0x20},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) {0x3003, 0x08},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) {0x300e, 0x20},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) {0x3010, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) {0x3015, 0x84},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) {0x3018, 0x72},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) {0x3021, 0x23},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) {0x3033, 0x24},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) {0x3500, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) {0x3501, 0x9a},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) {0x3502, 0x20},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) {0x3503, 0x08},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) {0x3505, 0x83},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) {0x3508, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) {0x3509, 0x80},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) {0x350c, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) {0x350d, 0x80},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) {0x350e, 0x04},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) {0x350f, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) {0x3510, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) {0x3511, 0x02},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) {0x3512, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) {0x3600, 0x72},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) {0x3601, 0x40},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) {0x3602, 0x30},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) {0x3610, 0xc5},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) {0x3611, 0x58},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) {0x3612, 0x5c},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) {0x3613, 0xca},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) {0x3614, 0x60},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) {0x3628, 0xff},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) {0x3629, 0xff},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) {0x362a, 0xff},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) {0x3633, 0x10},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) {0x3634, 0x10},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) {0x3635, 0x10},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) {0x3636, 0x10},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) {0x3663, 0x08},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) {0x3669, 0x34},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) {0x366d, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) {0x366e, 0x10},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) {0x3706, 0x86},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) {0x370b, 0x7e},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) {0x3714, 0x23},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) {0x3730, 0x12},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) {0x3733, 0x10},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) {0x3764, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) {0x3765, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) {0x3769, 0x62},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) {0x376a, 0x2a},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) {0x376b, 0x30},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) {0x3780, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) {0x3781, 0x24},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) {0x3782, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) {0x3783, 0x23},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) {0x3798, 0x2f},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) {0x37a1, 0x60},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) {0x37a8, 0x6a},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) {0x37ab, 0x3f},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) {0x37c2, 0x04},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) {0x37c3, 0xf1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) {0x37c9, 0x80},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) {0x37cb, 0x16},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) {0x37cc, 0x16},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) {0x37cd, 0x16},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) {0x37ce, 0x16},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) {0x3800, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) {0x3801, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) {0x3802, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) {0x3803, 0x0c},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) {0x3804, 0x0c},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) {0x3805, 0xdf},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) {0x3806, 0x09},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) {0x3807, 0xa3},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) {0x3808, 0x0c},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) {0x3809, 0xc0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) {0x380a, 0x09},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) {0x380b, 0x90},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) {0x380c, 0x07},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) {0x380d, 0x8c},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) {0x380e, 0x09},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) {0x380f, 0xb2},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) {0x3810, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) {0x3811, 0x04},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) {0x3812, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) {0x3813, 0x02},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) {0x3814, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) {0x3815, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) {0x3816, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) {0x3817, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) {0x3818, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) {0x3819, 0x10},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) {0x3820, 0x80},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) {0x3821, 0x46},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) {0x382a, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) {0x382b, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) {0x3830, 0x06},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) {0x3836, 0x02},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) {0x3862, 0x04},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) {0x3863, 0x08},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) {0x3cc0, 0x33},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) {0x3d85, 0x17},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) {0x3d8c, 0x73},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) {0x3d8d, 0xde},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) {0x4001, 0xe0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) {0x4003, 0x40},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) {0x4008, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) {0x4009, 0x0b},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) {0x400a, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) {0x400b, 0x84},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) {0x400f, 0x80},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) {0x4010, 0xf0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) {0x4011, 0xff},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) {0x4012, 0x02},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) {0x4013, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) {0x4014, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) {0x4015, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) {0x4042, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) {0x4043, 0x80},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) {0x4044, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) {0x4045, 0x80},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) {0x4046, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) {0x4047, 0x80},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) {0x4048, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) {0x4049, 0x80},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) {0x4041, 0x03},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) {0x404c, 0x20},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) {0x404d, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) {0x404e, 0x20},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) {0x4203, 0x80},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) {0x4307, 0x30},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) {0x4317, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) {0x4502, 0x50},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) {0x4503, 0x08},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) {0x4601, 0x80},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) {0x4800, 0x44},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) {0x4816, 0x53},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) {0x481b, 0x50},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) {0x481f, 0x27},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) {0x4823, 0x3c},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) {0x482b, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) {0x4831, 0x66},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) {0x4837, 0x16},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) {0x483c, 0x0f},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) {0x484b, 0x05},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) {0x5000, 0x77},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) {0x5001, 0x0a},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) {0x5003, 0xc8},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) {0x5004, 0x04},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) {0x5006, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) {0x5007, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) {0x502e, 0x03},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) {0x5030, 0x41},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) {0x5780, 0x14},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) {0x5781, 0x0f},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) {0x5782, 0x44},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) {0x5783, 0x02},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) {0x5784, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) {0x5785, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) {0x5786, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) {0x5787, 0x04},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) {0x5788, 0x02},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) {0x5789, 0x0f},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) {0x578a, 0xfd},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) {0x578b, 0xf5},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) {0x578c, 0xf5},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) {0x578d, 0x03},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) {0x578e, 0x08},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) {0x578f, 0x0c},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) {0x5790, 0x08},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) {0x5791, 0x04},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) {0x5792, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) {0x5793, 0x52},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) {0x5794, 0xa3},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) {0x5795, 0x02},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) {0x5796, 0x20},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) {0x5797, 0x20},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) {0x5798, 0xd5},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) {0x5799, 0xd5},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) {0x579a, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) {0x579b, 0x50},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) {0x579c, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) {0x579d, 0x2c},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) {0x579e, 0x0c},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) {0x579f, 0x40},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) {0x57a0, 0x09},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) {0x57a1, 0x40},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) {0x59f8, 0x3d},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) {0x5a08, 0x02},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) {0x5b00, 0x02},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) {0x5b01, 0x10},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) {0x5b02, 0x03},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) {0x5b03, 0xcf},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) {0x5b05, 0x6c},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) {0x5e00, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) {0x5e10, 0xfc}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) static const struct ov8856_reg mode_1640x1232_regs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) {0x3000, 0x20},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) {0x3003, 0x08},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) {0x300e, 0x20},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) {0x3010, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) {0x3015, 0x84},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) {0x3018, 0x72},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) {0x3021, 0x23},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) {0x3033, 0x24},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) {0x3500, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) {0x3501, 0x4c},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) {0x3502, 0xe0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) {0x3503, 0x08},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) {0x3505, 0x83},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) {0x3508, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) {0x3509, 0x80},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) {0x350c, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) {0x350d, 0x80},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) {0x350e, 0x04},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) {0x350f, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) {0x3510, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) {0x3511, 0x02},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) {0x3512, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) {0x3600, 0x72},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) {0x3601, 0x40},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) {0x3602, 0x30},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) {0x3610, 0xc5},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) {0x3611, 0x58},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) {0x3612, 0x5c},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) {0x3613, 0xca},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) {0x3614, 0x20},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) {0x3628, 0xff},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) {0x3629, 0xff},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) {0x362a, 0xff},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) {0x3633, 0x10},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) {0x3634, 0x10},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) {0x3635, 0x10},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) {0x3636, 0x10},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) {0x3663, 0x08},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) {0x3669, 0x34},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) {0x366e, 0x08},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) {0x3706, 0x86},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) {0x370b, 0x7e},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) {0x3714, 0x27},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) {0x3730, 0x12},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) {0x3733, 0x10},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) {0x3764, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) {0x3765, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) {0x3769, 0x62},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) {0x376a, 0x2a},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) {0x376b, 0x30},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) {0x3780, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) {0x3781, 0x24},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) {0x3782, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) {0x3783, 0x23},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) {0x3798, 0x2f},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) {0x37a1, 0x60},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) {0x37a8, 0x6a},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) {0x37ab, 0x3f},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) {0x37c2, 0x14},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) {0x37c3, 0xf1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) {0x37c9, 0x80},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) {0x37cb, 0x16},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) {0x37cc, 0x16},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) {0x37cd, 0x16},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) {0x37ce, 0x16},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) {0x3800, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) {0x3801, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) {0x3802, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) {0x3803, 0x06},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) {0x3804, 0x0c},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) {0x3805, 0xdf},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) {0x3806, 0x09},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) {0x3807, 0xa7},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) {0x3808, 0x06},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) {0x3809, 0x68},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) {0x380a, 0x04},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) {0x380b, 0xd0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) {0x380c, 0x0e},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) {0x380d, 0xec},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) {0x380e, 0x04},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) {0x380f, 0xe8},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) {0x3810, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) {0x3811, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) {0x3812, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) {0x3813, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) {0x3814, 0x03},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) {0x3815, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) {0x3816, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) {0x3817, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) {0x3818, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) {0x3819, 0x10},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) {0x3820, 0x90},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) {0x3821, 0x67},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) {0x382a, 0x03},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) {0x382b, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) {0x3830, 0x06},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) {0x3836, 0x02},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) {0x3862, 0x04},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) {0x3863, 0x08},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) {0x3cc0, 0x33},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) {0x3d85, 0x17},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) {0x3d8c, 0x73},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) {0x3d8d, 0xde},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) {0x4001, 0xe0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) {0x4003, 0x40},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) {0x4008, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) {0x4009, 0x05},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) {0x400a, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) {0x400b, 0x84},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) {0x400f, 0x80},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) {0x4010, 0xf0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) {0x4011, 0xff},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) {0x4012, 0x02},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) {0x4013, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) {0x4014, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) {0x4015, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) {0x4042, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) {0x4043, 0x80},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) {0x4044, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) {0x4045, 0x80},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) {0x4046, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) {0x4047, 0x80},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) {0x4048, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) {0x4049, 0x80},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) {0x4041, 0x03},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) {0x404c, 0x20},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) {0x404d, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) {0x404e, 0x20},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) {0x4203, 0x80},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) {0x4307, 0x30},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) {0x4317, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) {0x4503, 0x08},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) {0x4601, 0x80},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) {0x4800, 0x44},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) {0x4816, 0x53},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) {0x481b, 0x58},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) {0x481f, 0x27},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) {0x4837, 0x16},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) {0x483c, 0x0f},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) {0x484b, 0x05},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) {0x5000, 0x57},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) {0x5001, 0x0a},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) {0x5004, 0x04},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) {0x502e, 0x03},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) {0x5030, 0x41},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) {0x5780, 0x14},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) {0x5781, 0x0f},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) {0x5782, 0x44},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) {0x5783, 0x02},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) {0x5784, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) {0x5785, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) {0x5786, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) {0x5787, 0x04},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) {0x5788, 0x02},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) {0x5789, 0x0f},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) {0x578a, 0xfd},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) {0x578b, 0xf5},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) {0x578c, 0xf5},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) {0x578d, 0x03},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) {0x578e, 0x08},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) {0x578f, 0x0c},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) {0x5790, 0x08},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) {0x5791, 0x04},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) {0x5792, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) {0x5793, 0x52},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) {0x5794, 0xa3},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) {0x5795, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) {0x5796, 0x10},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) {0x5797, 0x10},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) {0x5798, 0x73},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) {0x5799, 0x73},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) {0x579a, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) {0x579b, 0x28},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) {0x579c, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) {0x579d, 0x16},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) {0x579e, 0x06},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) {0x579f, 0x20},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) {0x57a0, 0x04},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) {0x57a1, 0xa0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) {0x59f8, 0x3d},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) {0x5a08, 0x02},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) {0x5b00, 0x02},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) {0x5b01, 0x10},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) {0x5b02, 0x03},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) {0x5b03, 0xcf},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) {0x5b05, 0x6c},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) {0x5e00, 0x00}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) static const struct ov8856_reg mode_1632x1224_regs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) {0x0103, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) {0x0302, 0x3c},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) {0x0303, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) {0x031e, 0x0c},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) {0x3000, 0x20},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) {0x3003, 0x08},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) {0x300e, 0x20},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) {0x3010, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) {0x3015, 0x84},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) {0x3018, 0x72},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) {0x3021, 0x23},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) {0x3033, 0x24},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) {0x3500, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) {0x3501, 0x4c},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) {0x3502, 0xe0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) {0x3503, 0x08},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) {0x3505, 0x83},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) {0x3508, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) {0x3509, 0x80},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) {0x350c, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) {0x350d, 0x80},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) {0x350e, 0x04},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) {0x350f, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) {0x3510, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) {0x3511, 0x02},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) {0x3512, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) {0x3600, 0x72},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) {0x3601, 0x40},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) {0x3602, 0x30},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) {0x3610, 0xc5},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) {0x3611, 0x58},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) {0x3612, 0x5c},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) {0x3613, 0xca},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) {0x3614, 0x60},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) {0x3628, 0xff},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) {0x3629, 0xff},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) {0x362a, 0xff},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) {0x3633, 0x10},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) {0x3634, 0x10},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) {0x3635, 0x10},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) {0x3636, 0x10},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) {0x3663, 0x08},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) {0x3669, 0x34},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) {0x366d, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) {0x366e, 0x08},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) {0x3706, 0x86},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) {0x370b, 0x7e},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) {0x3714, 0x27},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) {0x3730, 0x12},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) {0x3733, 0x10},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) {0x3764, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) {0x3765, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) {0x3769, 0x62},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) {0x376a, 0x2a},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) {0x376b, 0x30},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) {0x3780, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) {0x3781, 0x24},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) {0x3782, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) {0x3783, 0x23},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) {0x3798, 0x2f},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) {0x37a1, 0x60},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) {0x37a8, 0x6a},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) {0x37ab, 0x3f},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) {0x37c2, 0x14},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) {0x37c3, 0xf1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) {0x37c9, 0x80},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) {0x37cb, 0x16},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) {0x37cc, 0x16},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) {0x37cd, 0x16},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) {0x37ce, 0x16},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) {0x3800, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) {0x3801, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) {0x3802, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) {0x3803, 0x0c},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) {0x3804, 0x0c},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) {0x3805, 0xdf},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) {0x3806, 0x09},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) {0x3807, 0xa3},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) {0x3808, 0x06},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) {0x3809, 0x60},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) {0x380a, 0x04},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) {0x380b, 0xc8},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) {0x380c, 0x07},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) {0x380d, 0x8c},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) {0x380e, 0x09},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) {0x380f, 0xb2},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) {0x3810, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) {0x3811, 0x02},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) {0x3812, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) {0x3813, 0x02},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) {0x3814, 0x03},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) {0x3815, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) {0x3816, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) {0x3817, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) {0x3818, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) {0x3819, 0x10},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) {0x3820, 0x80},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) {0x3821, 0x47},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) {0x382a, 0x03},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) {0x382b, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) {0x3830, 0x06},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) {0x3836, 0x02},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) {0x3862, 0x04},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) {0x3863, 0x08},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) {0x3cc0, 0x33},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) {0x3d85, 0x17},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) {0x3d8c, 0x73},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) {0x3d8d, 0xde},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) {0x4001, 0xe0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) {0x4003, 0x40},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) {0x4008, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) {0x4009, 0x05},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) {0x400a, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) {0x400b, 0x84},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) {0x400f, 0x80},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) {0x4010, 0xf0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) {0x4011, 0xff},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) {0x4012, 0x02},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) {0x4013, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) {0x4014, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) {0x4015, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) {0x4042, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) {0x4043, 0x80},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) {0x4044, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) {0x4045, 0x80},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) {0x4046, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) {0x4047, 0x80},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) {0x4048, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) {0x4049, 0x80},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) {0x4041, 0x03},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) {0x404c, 0x20},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) {0x404d, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) {0x404e, 0x20},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) {0x4203, 0x80},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) {0x4307, 0x30},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) {0x4317, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) {0x4502, 0x50},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) {0x4503, 0x08},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) {0x4601, 0x80},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) {0x4800, 0x44},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) {0x4816, 0x53},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) {0x481b, 0x50},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) {0x481f, 0x27},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) {0x4823, 0x3c},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) {0x482b, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) {0x4831, 0x66},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) {0x4837, 0x16},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) {0x483c, 0x0f},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) {0x484b, 0x05},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) {0x5000, 0x77},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) {0x5001, 0x0a},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) {0x5003, 0xc8},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) {0x5004, 0x04},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) {0x5006, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) {0x5007, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) {0x502e, 0x03},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) {0x5030, 0x41},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) {0x5795, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) {0x5796, 0x10},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) {0x5797, 0x10},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) {0x5798, 0x73},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) {0x5799, 0x73},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) {0x579a, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) {0x579b, 0x28},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) {0x579c, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) {0x579d, 0x16},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) {0x579e, 0x06},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) {0x579f, 0x20},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) {0x57a0, 0x04},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) {0x57a1, 0xa0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) {0x5780, 0x14},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) {0x5781, 0x0f},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) {0x5782, 0x44},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) {0x5783, 0x02},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) {0x5784, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) {0x5785, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) {0x5786, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) {0x5787, 0x04},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) {0x5788, 0x02},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) {0x5789, 0x0f},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) {0x578a, 0xfd},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) {0x578b, 0xf5},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) {0x578c, 0xf5},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) {0x578d, 0x03},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) {0x578e, 0x08},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) {0x578f, 0x0c},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) {0x5790, 0x08},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) {0x5791, 0x04},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) {0x5792, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) {0x5793, 0x52},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) {0x5794, 0xa3},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) {0x59f8, 0x3d},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) {0x5a08, 0x02},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) {0x5b00, 0x02},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) {0x5b01, 0x10},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) {0x5b02, 0x03},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) {0x5b03, 0xcf},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) {0x5b05, 0x6c},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) {0x5e00, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) {0x5e10, 0xfc}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) static const char * const ov8856_test_pattern_menu[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) "Disabled",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) "Standard Color Bar",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) "Top-Bottom Darker Color Bar",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) "Right-Left Darker Color Bar",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) "Bottom-Top Darker Color Bar"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) static const s64 link_freq_menu_items[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) OV8856_LINK_FREQ_360MHZ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) OV8856_LINK_FREQ_180MHZ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) static const struct ov8856_link_freq_config link_freq_configs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) [OV8856_LINK_FREQ_720MBPS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) .reg_list = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) .num_of_regs = ARRAY_SIZE(mipi_data_rate_720mbps),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) .regs = mipi_data_rate_720mbps,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) [OV8856_LINK_FREQ_360MBPS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) .reg_list = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) .num_of_regs = ARRAY_SIZE(mipi_data_rate_360mbps),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) .regs = mipi_data_rate_360mbps,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) static const struct ov8856_mode supported_modes[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) .width = 3280,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) .height = 2464,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) .hts = 1928,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) .vts_def = 2488,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) .vts_min = 2488,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) .reg_list = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) .num_of_regs = ARRAY_SIZE(mode_3280x2464_regs),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) .regs = mode_3280x2464_regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) .link_freq_index = OV8856_LINK_FREQ_720MBPS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) .width = 3264,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) .height = 2448,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) .hts = 1932,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) .vts_def = 2482,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) .vts_min = 2482,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) .reg_list = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) .num_of_regs = ARRAY_SIZE(mode_3264x2448_regs),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) .regs = mode_3264x2448_regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) .link_freq_index = OV8856_LINK_FREQ_720MBPS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) .width = 1640,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) .height = 1232,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) .hts = 3820,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) .vts_def = 1256,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) .vts_min = 1256,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) .reg_list = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) .num_of_regs = ARRAY_SIZE(mode_1640x1232_regs),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) .regs = mode_1640x1232_regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) .link_freq_index = OV8856_LINK_FREQ_360MBPS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) .width = 1632,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) .height = 1224,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) .hts = 1932,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) .vts_def = 2482,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) .vts_min = 2482,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) .reg_list = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) .num_of_regs = ARRAY_SIZE(mode_1632x1224_regs),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) .regs = mode_1632x1224_regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) .link_freq_index = OV8856_LINK_FREQ_360MBPS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) struct ov8856 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) struct v4l2_subdev sd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) struct media_pad pad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) struct v4l2_ctrl_handler ctrl_handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) struct clk *xvclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) struct gpio_desc *reset_gpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) struct regulator_bulk_data supplies[ARRAY_SIZE(ov8856_supply_names)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) /* V4L2 Controls */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) struct v4l2_ctrl *link_freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) struct v4l2_ctrl *pixel_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) struct v4l2_ctrl *vblank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) struct v4l2_ctrl *hblank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) struct v4l2_ctrl *exposure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) /* Current mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) const struct ov8856_mode *cur_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) /* To serialize asynchronus callbacks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) struct mutex mutex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) /* Streaming on/off */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) bool streaming;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) static u64 to_pixel_rate(u32 f_index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) u64 pixel_rate = link_freq_menu_items[f_index] * 2 * OV8856_DATA_LANES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) do_div(pixel_rate, OV8856_RGB_DEPTH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) return pixel_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) static u64 to_pixels_per_line(u32 hts, u32 f_index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) u64 ppl = hts * to_pixel_rate(f_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) do_div(ppl, OV8856_SCLK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) return ppl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) static int ov8856_read_reg(struct ov8856 *ov8856, u16 reg, u16 len, u32 *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) struct i2c_client *client = v4l2_get_subdevdata(&ov8856->sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) struct i2c_msg msgs[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) u8 addr_buf[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) u8 data_buf[4] = {0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) if (len > 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) put_unaligned_be16(reg, addr_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) msgs[0].addr = client->addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) msgs[0].flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) msgs[0].len = sizeof(addr_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) msgs[0].buf = addr_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) msgs[1].addr = client->addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) msgs[1].flags = I2C_M_RD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) msgs[1].len = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) msgs[1].buf = &data_buf[4 - len];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) if (ret != ARRAY_SIZE(msgs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) *val = get_unaligned_be32(data_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) static int ov8856_write_reg(struct ov8856 *ov8856, u16 reg, u16 len, u32 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) struct i2c_client *client = v4l2_get_subdevdata(&ov8856->sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) u8 buf[6];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) if (len > 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) put_unaligned_be16(reg, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) put_unaligned_be32(val << 8 * (4 - len), buf + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) if (i2c_master_send(client, buf, len + 2) != len + 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) static int ov8856_write_reg_list(struct ov8856 *ov8856,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) const struct ov8856_reg_list *r_list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) struct i2c_client *client = v4l2_get_subdevdata(&ov8856->sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) for (i = 0; i < r_list->num_of_regs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) ret = ov8856_write_reg(ov8856, r_list->regs[i].address, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) r_list->regs[i].val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) dev_err_ratelimited(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) "failed to write reg 0x%4.4x. error = %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) r_list->regs[i].address, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) static int ov8856_update_digital_gain(struct ov8856 *ov8856, u32 d_gain)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) ret = ov8856_write_reg(ov8856, OV8856_REG_MWB_R_GAIN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) OV8856_REG_VALUE_16BIT, d_gain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) ret = ov8856_write_reg(ov8856, OV8856_REG_MWB_G_GAIN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) OV8856_REG_VALUE_16BIT, d_gain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) return ov8856_write_reg(ov8856, OV8856_REG_MWB_B_GAIN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) OV8856_REG_VALUE_16BIT, d_gain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) static int ov8856_test_pattern(struct ov8856 *ov8856, u32 pattern)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) if (pattern)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) pattern = (pattern - 1) << OV8856_TEST_PATTERN_BAR_SHIFT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) OV8856_TEST_PATTERN_ENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) return ov8856_write_reg(ov8856, OV8856_REG_TEST_PATTERN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) OV8856_REG_VALUE_08BIT, pattern);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) static int ov8856_set_ctrl(struct v4l2_ctrl *ctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) struct ov8856 *ov8856 = container_of(ctrl->handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) struct ov8856, ctrl_handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) struct i2c_client *client = v4l2_get_subdevdata(&ov8856->sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) s64 exposure_max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) /* Propagate change of current control to all related controls */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) if (ctrl->id == V4L2_CID_VBLANK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) /* Update max exposure while meeting expected vblanking */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) exposure_max = ov8856->cur_mode->height + ctrl->val -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) OV8856_EXPOSURE_MAX_MARGIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) __v4l2_ctrl_modify_range(ov8856->exposure,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) ov8856->exposure->minimum,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) exposure_max, ov8856->exposure->step,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) exposure_max);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) /* V4L2 controls values will be applied only when power is already up */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) if (!pm_runtime_get_if_in_use(&client->dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) switch (ctrl->id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) case V4L2_CID_ANALOGUE_GAIN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) ret = ov8856_write_reg(ov8856, OV8856_REG_ANALOG_GAIN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) OV8856_REG_VALUE_16BIT, ctrl->val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) case V4L2_CID_DIGITAL_GAIN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) ret = ov8856_update_digital_gain(ov8856, ctrl->val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) case V4L2_CID_EXPOSURE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) /* 4 least significant bits of expsoure are fractional part */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) ret = ov8856_write_reg(ov8856, OV8856_REG_EXPOSURE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) OV8856_REG_VALUE_24BIT, ctrl->val << 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) case V4L2_CID_VBLANK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) ret = ov8856_write_reg(ov8856, OV8856_REG_VTS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) OV8856_REG_VALUE_16BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) ov8856->cur_mode->height + ctrl->val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) case V4L2_CID_TEST_PATTERN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) ret = ov8856_test_pattern(ov8856, ctrl->val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) pm_runtime_put(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) static const struct v4l2_ctrl_ops ov8856_ctrl_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) .s_ctrl = ov8856_set_ctrl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) static int ov8856_init_controls(struct ov8856 *ov8856)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) struct v4l2_ctrl_handler *ctrl_hdlr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) s64 exposure_max, h_blank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) ctrl_hdlr = &ov8856->ctrl_handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) ret = v4l2_ctrl_handler_init(ctrl_hdlr, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) ctrl_hdlr->lock = &ov8856->mutex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) ov8856->link_freq = v4l2_ctrl_new_int_menu(ctrl_hdlr, &ov8856_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) V4L2_CID_LINK_FREQ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) ARRAY_SIZE(link_freq_menu_items) - 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) 0, link_freq_menu_items);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) if (ov8856->link_freq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) ov8856->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) ov8856->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &ov8856_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) V4L2_CID_PIXEL_RATE, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) to_pixel_rate(OV8856_LINK_FREQ_720MBPS),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) to_pixel_rate(OV8856_LINK_FREQ_720MBPS));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) ov8856->vblank = v4l2_ctrl_new_std(ctrl_hdlr, &ov8856_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) V4L2_CID_VBLANK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) ov8856->cur_mode->vts_min - ov8856->cur_mode->height,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) OV8856_VTS_MAX - ov8856->cur_mode->height, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) ov8856->cur_mode->vts_def - ov8856->cur_mode->height);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) h_blank = to_pixels_per_line(ov8856->cur_mode->hts,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) ov8856->cur_mode->link_freq_index) - ov8856->cur_mode->width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) ov8856->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &ov8856_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) V4L2_CID_HBLANK, h_blank, h_blank, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) h_blank);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) if (ov8856->hblank)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) ov8856->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) v4l2_ctrl_new_std(ctrl_hdlr, &ov8856_ctrl_ops, V4L2_CID_ANALOGUE_GAIN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) OV8856_ANAL_GAIN_MIN, OV8856_ANAL_GAIN_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) OV8856_ANAL_GAIN_STEP, OV8856_ANAL_GAIN_MIN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) v4l2_ctrl_new_std(ctrl_hdlr, &ov8856_ctrl_ops, V4L2_CID_DIGITAL_GAIN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) OV8856_DGTL_GAIN_MIN, OV8856_DGTL_GAIN_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) OV8856_DGTL_GAIN_STEP, OV8856_DGTL_GAIN_DEFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) exposure_max = ov8856->cur_mode->vts_def - OV8856_EXPOSURE_MAX_MARGIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) ov8856->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &ov8856_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) V4L2_CID_EXPOSURE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) OV8856_EXPOSURE_MIN, exposure_max,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) OV8856_EXPOSURE_STEP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) exposure_max);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) v4l2_ctrl_new_std_menu_items(ctrl_hdlr, &ov8856_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) V4L2_CID_TEST_PATTERN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) ARRAY_SIZE(ov8856_test_pattern_menu) - 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) 0, 0, ov8856_test_pattern_menu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) if (ctrl_hdlr->error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) return ctrl_hdlr->error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) ov8856->sd.ctrl_handler = ctrl_hdlr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) static void ov8856_update_pad_format(const struct ov8856_mode *mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) struct v4l2_mbus_framefmt *fmt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) fmt->width = mode->width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) fmt->height = mode->height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) fmt->code = MEDIA_BUS_FMT_SGRBG10_1X10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) fmt->field = V4L2_FIELD_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) static int ov8856_start_streaming(struct ov8856 *ov8856)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) struct i2c_client *client = v4l2_get_subdevdata(&ov8856->sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) const struct ov8856_reg_list *reg_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) int link_freq_index, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) link_freq_index = ov8856->cur_mode->link_freq_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) reg_list = &link_freq_configs[link_freq_index].reg_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) ret = ov8856_write_reg_list(ov8856, reg_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) dev_err(&client->dev, "failed to set plls");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) reg_list = &ov8856->cur_mode->reg_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) ret = ov8856_write_reg_list(ov8856, reg_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) dev_err(&client->dev, "failed to set mode");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) ret = __v4l2_ctrl_handler_setup(ov8856->sd.ctrl_handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) ret = ov8856_write_reg(ov8856, OV8856_REG_MODE_SELECT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) OV8856_REG_VALUE_08BIT, OV8856_MODE_STREAMING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) dev_err(&client->dev, "failed to set stream");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) static void ov8856_stop_streaming(struct ov8856 *ov8856)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) struct i2c_client *client = v4l2_get_subdevdata(&ov8856->sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) if (ov8856_write_reg(ov8856, OV8856_REG_MODE_SELECT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) OV8856_REG_VALUE_08BIT, OV8856_MODE_STANDBY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) dev_err(&client->dev, "failed to set stream");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) static int ov8856_set_stream(struct v4l2_subdev *sd, int enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) struct ov8856 *ov8856 = to_ov8856(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) struct i2c_client *client = v4l2_get_subdevdata(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) if (ov8856->streaming == enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) mutex_lock(&ov8856->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) if (enable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) ret = pm_runtime_get_sync(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) pm_runtime_put_noidle(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) mutex_unlock(&ov8856->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) ret = ov8856_start_streaming(ov8856);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) enable = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) ov8856_stop_streaming(ov8856);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) pm_runtime_put(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) ov8856_stop_streaming(ov8856);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) pm_runtime_put(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) ov8856->streaming = enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) mutex_unlock(&ov8856->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) static int __ov8856_power_on(struct ov8856 *ov8856)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) struct i2c_client *client = v4l2_get_subdevdata(&ov8856->sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) if (is_acpi_node(dev_fwnode(&client->dev)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) ret = clk_prepare_enable(ov8856->xvclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) dev_err(&client->dev, "failed to enable xvclk\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) if (ov8856->reset_gpio) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) gpiod_set_value_cansleep(ov8856->reset_gpio, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) usleep_range(1000, 2000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) ret = regulator_bulk_enable(ARRAY_SIZE(ov8856_supply_names),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) ov8856->supplies);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) dev_err(&client->dev, "failed to enable regulators\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) goto disable_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) gpiod_set_value_cansleep(ov8856->reset_gpio, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) usleep_range(1500, 1800);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) disable_clk:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) gpiod_set_value_cansleep(ov8856->reset_gpio, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) clk_disable_unprepare(ov8856->xvclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) static void __ov8856_power_off(struct ov8856 *ov8856)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) struct i2c_client *client = v4l2_get_subdevdata(&ov8856->sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) if (is_acpi_node(dev_fwnode(&client->dev)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) gpiod_set_value_cansleep(ov8856->reset_gpio, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) regulator_bulk_disable(ARRAY_SIZE(ov8856_supply_names),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) ov8856->supplies);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) clk_disable_unprepare(ov8856->xvclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) static int __maybe_unused ov8856_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) struct i2c_client *client = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) struct v4l2_subdev *sd = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) struct ov8856 *ov8856 = to_ov8856(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) mutex_lock(&ov8856->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) if (ov8856->streaming)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) ov8856_stop_streaming(ov8856);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) __ov8856_power_off(ov8856);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) mutex_unlock(&ov8856->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) static int __maybe_unused ov8856_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) struct i2c_client *client = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) struct v4l2_subdev *sd = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) struct ov8856 *ov8856 = to_ov8856(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) mutex_lock(&ov8856->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) __ov8856_power_on(ov8856);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) if (ov8856->streaming) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) ret = ov8856_start_streaming(ov8856);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) ov8856->streaming = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) ov8856_stop_streaming(ov8856);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) mutex_unlock(&ov8856->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) mutex_unlock(&ov8856->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) static int ov8856_set_format(struct v4l2_subdev *sd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) struct v4l2_subdev_pad_config *cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) struct v4l2_subdev_format *fmt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) struct ov8856 *ov8856 = to_ov8856(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) const struct ov8856_mode *mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) s32 vblank_def, h_blank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) mode = v4l2_find_nearest_size(supported_modes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) ARRAY_SIZE(supported_modes), width,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) height, fmt->format.width,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) fmt->format.height);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) mutex_lock(&ov8856->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) ov8856_update_pad_format(mode, &fmt->format);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) *v4l2_subdev_get_try_format(sd, cfg, fmt->pad) = fmt->format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) ov8856->cur_mode = mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) __v4l2_ctrl_s_ctrl(ov8856->link_freq, mode->link_freq_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) __v4l2_ctrl_s_ctrl_int64(ov8856->pixel_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) to_pixel_rate(mode->link_freq_index));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) /* Update limits and set FPS to default */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) vblank_def = mode->vts_def - mode->height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) __v4l2_ctrl_modify_range(ov8856->vblank,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) mode->vts_min - mode->height,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) OV8856_VTS_MAX - mode->height, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) vblank_def);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) __v4l2_ctrl_s_ctrl(ov8856->vblank, vblank_def);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) h_blank = to_pixels_per_line(mode->hts, mode->link_freq_index) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) mode->width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) __v4l2_ctrl_modify_range(ov8856->hblank, h_blank, h_blank, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) h_blank);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) mutex_unlock(&ov8856->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) static int ov8856_get_format(struct v4l2_subdev *sd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) struct v4l2_subdev_pad_config *cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) struct v4l2_subdev_format *fmt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) struct ov8856 *ov8856 = to_ov8856(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) mutex_lock(&ov8856->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) if (fmt->which == V4L2_SUBDEV_FORMAT_TRY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) fmt->format = *v4l2_subdev_get_try_format(&ov8856->sd, cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) fmt->pad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) ov8856_update_pad_format(ov8856->cur_mode, &fmt->format);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) mutex_unlock(&ov8856->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) static int ov8856_enum_mbus_code(struct v4l2_subdev *sd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) struct v4l2_subdev_pad_config *cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) struct v4l2_subdev_mbus_code_enum *code)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) /* Only one bayer order GRBG is supported */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) if (code->index > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) code->code = MEDIA_BUS_FMT_SGRBG10_1X10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) static int ov8856_enum_frame_size(struct v4l2_subdev *sd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) struct v4l2_subdev_pad_config *cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) struct v4l2_subdev_frame_size_enum *fse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) if (fse->index >= ARRAY_SIZE(supported_modes))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) if (fse->code != MEDIA_BUS_FMT_SGRBG10_1X10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) fse->min_width = supported_modes[fse->index].width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) fse->max_width = fse->min_width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) fse->min_height = supported_modes[fse->index].height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) fse->max_height = fse->min_height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) static int ov8856_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) struct ov8856 *ov8856 = to_ov8856(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) mutex_lock(&ov8856->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) ov8856_update_pad_format(&supported_modes[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) v4l2_subdev_get_try_format(sd, fh->pad, 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) mutex_unlock(&ov8856->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) static const struct v4l2_subdev_video_ops ov8856_video_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) .s_stream = ov8856_set_stream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) static const struct v4l2_subdev_pad_ops ov8856_pad_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) .set_fmt = ov8856_set_format,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) .get_fmt = ov8856_get_format,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) .enum_mbus_code = ov8856_enum_mbus_code,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) .enum_frame_size = ov8856_enum_frame_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) static const struct v4l2_subdev_ops ov8856_subdev_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) .video = &ov8856_video_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) .pad = &ov8856_pad_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) static const struct media_entity_operations ov8856_subdev_entity_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) .link_validate = v4l2_subdev_link_validate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) static const struct v4l2_subdev_internal_ops ov8856_internal_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) .open = ov8856_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) static int ov8856_identify_module(struct ov8856 *ov8856)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) struct i2c_client *client = v4l2_get_subdevdata(&ov8856->sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) ret = ov8856_read_reg(ov8856, OV8856_REG_CHIP_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) OV8856_REG_VALUE_24BIT, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) if (val != OV8856_CHIP_ID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) dev_err(&client->dev, "chip id mismatch: %x!=%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) OV8856_CHIP_ID, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) ret = ov8856_write_reg(ov8856, OV8856_REG_MODE_SELECT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) OV8856_REG_VALUE_08BIT, OV8856_MODE_STREAMING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) ret = ov8856_write_reg(ov8856, OV8856_OTP_MODE_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) OV8856_REG_VALUE_08BIT, OV8856_OTP_MODE_AUTO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) dev_err(&client->dev, "failed to set otp mode");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) ret = ov8856_write_reg(ov8856, OV8856_OTP_LOAD_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) OV8856_REG_VALUE_08BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) OV8856_OTP_LOAD_CTRL_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) dev_err(&client->dev, "failed to enable load control");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) ret = ov8856_read_reg(ov8856, OV8856_MODULE_REVISION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) OV8856_REG_VALUE_08BIT, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) dev_err(&client->dev, "failed to read module revision");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) dev_info(&client->dev, "OV8856 revision %x (%s) at address 0x%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) val == OV8856_2A_MODULE ? "2A" :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) val == OV8856_1B_MODULE ? "1B" : "unknown revision",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) client->addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) ret = ov8856_write_reg(ov8856, OV8856_REG_MODE_SELECT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) OV8856_REG_VALUE_08BIT, OV8856_MODE_STANDBY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) dev_err(&client->dev, "failed to exit streaming mode");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) static int ov8856_get_hwcfg(struct ov8856 *ov8856, struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) struct fwnode_handle *ep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) struct fwnode_handle *fwnode = dev_fwnode(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) struct v4l2_fwnode_endpoint bus_cfg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) .bus_type = V4L2_MBUS_CSI2_DPHY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) u32 xvclk_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) unsigned int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) if (!fwnode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) ret = fwnode_property_read_u32(fwnode, "clock-frequency", &xvclk_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) if (!is_acpi_node(fwnode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) ov8856->xvclk = devm_clk_get(dev, "xvclk");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) if (IS_ERR(ov8856->xvclk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) dev_err(dev, "could not get xvclk clock (%pe)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) ov8856->xvclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) return PTR_ERR(ov8856->xvclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) clk_set_rate(ov8856->xvclk, xvclk_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) xvclk_rate = clk_get_rate(ov8856->xvclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) if (xvclk_rate != OV8856_XVCLK_19_2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) dev_warn(dev, "external clock rate %u is unsupported",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) xvclk_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) ov8856->reset_gpio = devm_gpiod_get_optional(dev, "reset",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) GPIOD_OUT_LOW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) if (IS_ERR(ov8856->reset_gpio))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) return PTR_ERR(ov8856->reset_gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) for (i = 0; i < ARRAY_SIZE(ov8856_supply_names); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) ov8856->supplies[i].supply = ov8856_supply_names[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(ov8856_supply_names),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) ov8856->supplies);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) ep = fwnode_graph_get_next_endpoint(fwnode, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) if (!ep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) ret = v4l2_fwnode_endpoint_alloc_parse(ep, &bus_cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) fwnode_handle_put(ep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) if (bus_cfg.bus.mipi_csi2.num_data_lanes != OV8856_DATA_LANES) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) dev_err(dev, "number of CSI2 data lanes %d is not supported",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) bus_cfg.bus.mipi_csi2.num_data_lanes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) goto check_hwcfg_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) if (!bus_cfg.nr_of_link_frequencies) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) dev_err(dev, "no link frequencies defined");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) goto check_hwcfg_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) for (i = 0; i < ARRAY_SIZE(link_freq_menu_items); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) for (j = 0; j < bus_cfg.nr_of_link_frequencies; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) if (link_freq_menu_items[i] ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) bus_cfg.link_frequencies[j])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) if (j == bus_cfg.nr_of_link_frequencies) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) dev_err(dev, "no link frequency %lld supported",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) link_freq_menu_items[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) goto check_hwcfg_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) check_hwcfg_error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) v4l2_fwnode_endpoint_free(&bus_cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) static int ov8856_remove(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) struct v4l2_subdev *sd = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) struct ov8856 *ov8856 = to_ov8856(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) v4l2_async_unregister_subdev(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) media_entity_cleanup(&sd->entity);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) v4l2_ctrl_handler_free(sd->ctrl_handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) pm_runtime_disable(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) mutex_destroy(&ov8856->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) __ov8856_power_off(ov8856);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) static int ov8856_probe(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) struct ov8856 *ov8856;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) ov8856 = devm_kzalloc(&client->dev, sizeof(*ov8856), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) if (!ov8856)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) ret = ov8856_get_hwcfg(ov8856, &client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) dev_err(&client->dev, "failed to get HW configuration: %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) v4l2_i2c_subdev_init(&ov8856->sd, client, &ov8856_subdev_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) ret = __ov8856_power_on(ov8856);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) dev_err(&client->dev, "failed to power on\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) ret = ov8856_identify_module(ov8856);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) dev_err(&client->dev, "failed to find sensor: %d", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) goto probe_power_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) mutex_init(&ov8856->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) ov8856->cur_mode = &supported_modes[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) ret = ov8856_init_controls(ov8856);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) dev_err(&client->dev, "failed to init controls: %d", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) goto probe_error_v4l2_ctrl_handler_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) ov8856->sd.internal_ops = &ov8856_internal_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) ov8856->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) ov8856->sd.entity.ops = &ov8856_subdev_entity_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) ov8856->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) ov8856->pad.flags = MEDIA_PAD_FL_SOURCE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) ret = media_entity_pads_init(&ov8856->sd.entity, 1, &ov8856->pad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) dev_err(&client->dev, "failed to init entity pads: %d", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) goto probe_error_v4l2_ctrl_handler_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) ret = v4l2_async_register_subdev_sensor_common(&ov8856->sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) dev_err(&client->dev, "failed to register V4L2 subdev: %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) goto probe_error_media_entity_cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) * Device is already turned on by i2c-core with ACPI domain PM.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) * Enable runtime PM and turn off the device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) pm_runtime_set_active(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) pm_runtime_enable(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) pm_runtime_idle(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) probe_error_media_entity_cleanup:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) media_entity_cleanup(&ov8856->sd.entity);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) probe_error_v4l2_ctrl_handler_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) v4l2_ctrl_handler_free(ov8856->sd.ctrl_handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) mutex_destroy(&ov8856->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) probe_power_off:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) __ov8856_power_off(ov8856);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) static const struct dev_pm_ops ov8856_pm_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) SET_SYSTEM_SLEEP_PM_OPS(ov8856_suspend, ov8856_resume)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) #ifdef CONFIG_ACPI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) static const struct acpi_device_id ov8856_acpi_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) {"OVTI8856"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) MODULE_DEVICE_TABLE(acpi, ov8856_acpi_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) static const struct of_device_id ov8856_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) { .compatible = "ovti,ov8856" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) { /* sentinel */ }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) MODULE_DEVICE_TABLE(of, ov8856_of_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) static struct i2c_driver ov8856_i2c_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) .name = "ov8856",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) .pm = &ov8856_pm_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) .acpi_match_table = ACPI_PTR(ov8856_acpi_ids),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) .of_match_table = ov8856_of_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) .probe_new = ov8856_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) .remove = ov8856_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) module_i2c_driver(ov8856_i2c_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) MODULE_AUTHOR("Ben Kao <ben.kao@intel.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) MODULE_DESCRIPTION("OmniVision OV8856 sensor driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) MODULE_LICENSE("GPL v2");