^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) 2020 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/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/pm_runtime.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/nvmem-provider.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/regmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <media/v4l2-ctrls.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <media/v4l2-device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <media/v4l2-fwnode.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #define OV2740_LINK_FREQ_360MHZ 360000000ULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #define OV2740_SCLK 72000000LL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #define OV2740_MCLK 19200000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #define OV2740_DATA_LANES 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #define OV2740_RGB_DEPTH 10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define OV2740_REG_CHIP_ID 0x300a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #define OV2740_CHIP_ID 0x2740
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define OV2740_REG_MODE_SELECT 0x0100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define OV2740_MODE_STANDBY 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define OV2740_MODE_STREAMING 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) /* vertical-timings from sensor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define OV2740_REG_VTS 0x380e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define OV2740_VTS_DEF 0x088a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define OV2740_VTS_MIN 0x0460
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define OV2740_VTS_MAX 0x7fff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) /* horizontal-timings from sensor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define OV2740_REG_HTS 0x380c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) /* Exposure controls from sensor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define OV2740_REG_EXPOSURE 0x3500
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define OV2740_EXPOSURE_MIN 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define OV2740_EXPOSURE_MAX_MARGIN 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define OV2740_EXPOSURE_STEP 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) /* Analog gain controls from sensor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define OV2740_REG_ANALOG_GAIN 0x3508
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define OV2740_ANAL_GAIN_MIN 128
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define OV2740_ANAL_GAIN_MAX 1983
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define OV2740_ANAL_GAIN_STEP 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) /* Digital gain controls from sensor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define OV2740_REG_MWB_R_GAIN 0x500a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define OV2740_REG_MWB_G_GAIN 0x500c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define OV2740_REG_MWB_B_GAIN 0x500e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define OV2740_DGTL_GAIN_MIN 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define OV2740_DGTL_GAIN_MAX 4095
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define OV2740_DGTL_GAIN_STEP 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define OV2740_DGTL_GAIN_DEFAULT 1024
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) /* Test Pattern Control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define OV2740_REG_TEST_PATTERN 0x5040
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define OV2740_TEST_PATTERN_ENABLE BIT(7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define OV2740_TEST_PATTERN_BAR_SHIFT 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) /* ISP CTRL00 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define OV2740_REG_ISP_CTRL00 0x5000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) /* ISP CTRL01 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define OV2740_REG_ISP_CTRL01 0x5001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) /* Customer Addresses: 0x7010 - 0x710F */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define CUSTOMER_USE_OTP_SIZE 0x100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) /* OTP registers from sensor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define OV2740_REG_OTP_CUSTOMER 0x7010
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) struct nvm_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) char *nvm_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) struct nvmem_device *nvmem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) struct regmap *regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) OV2740_LINK_FREQ_360MHZ_INDEX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) struct ov2740_reg {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) u16 address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) u8 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) struct ov2740_reg_list {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) u32 num_of_regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) const struct ov2740_reg *regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) struct ov2740_link_freq_config {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) const struct ov2740_reg_list reg_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) struct ov2740_mode {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) /* Frame width in pixels */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) u32 width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) /* Frame height in pixels */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) u32 height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) /* Horizontal timining size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) u32 hts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) /* Default vertical timining size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) u32 vts_def;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) /* Min vertical timining size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) u32 vts_min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) /* Link frequency needed for this resolution */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) u32 link_freq_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) /* Sensor register settings for this resolution */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) const struct ov2740_reg_list reg_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) static const struct ov2740_reg mipi_data_rate_720mbps[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) {0x0103, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) {0x0302, 0x4b},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) {0x030d, 0x4b},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) {0x030e, 0x02},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) {0x030a, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) {0x0312, 0x11},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) static const struct ov2740_reg mode_1932x1092_regs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) {0x3000, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) {0x3018, 0x32},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) {0x3031, 0x0a},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) {0x3080, 0x08},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) {0x3083, 0xB4},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) {0x3103, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) {0x3104, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) {0x3106, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) {0x3500, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) {0x3501, 0x44},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) {0x3502, 0x40},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) {0x3503, 0x88},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) {0x3507, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) {0x3508, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) {0x3509, 0x80},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) {0x350c, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) {0x350d, 0x80},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) {0x3510, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) {0x3511, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) {0x3512, 0x20},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) {0x3632, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) {0x3633, 0x10},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) {0x3634, 0x10},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) {0x3635, 0x10},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) {0x3645, 0x13},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) {0x3646, 0x81},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) {0x3636, 0x10},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) {0x3651, 0x0a},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) {0x3656, 0x02},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) {0x3659, 0x04},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) {0x365a, 0xda},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) {0x365b, 0xa2},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) {0x365c, 0x04},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) {0x365d, 0x1d},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) {0x365e, 0x1a},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) {0x3662, 0xd7},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) {0x3667, 0x78},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) {0x3669, 0x0a},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) {0x366a, 0x92},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) {0x3700, 0x54},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) {0x3702, 0x10},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) {0x3706, 0x42},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) {0x3709, 0x30},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) {0x370b, 0xc2},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) {0x3714, 0x63},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) {0x3715, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) {0x3716, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) {0x371a, 0x3e},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) {0x3732, 0x0e},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) {0x3733, 0x10},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) {0x375f, 0x0e},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) {0x3768, 0x30},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) {0x3769, 0x44},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) {0x376a, 0x22},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) {0x377b, 0x20},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) {0x377c, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) {0x377d, 0x0c},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) {0x3798, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) {0x37a1, 0x55},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) {0x37a8, 0x6d},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) {0x37c2, 0x04},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) {0x37c5, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) {0x37c8, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) {0x3800, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) {0x3801, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) {0x3802, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) {0x3803, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) {0x3804, 0x07},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) {0x3805, 0x8f},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) {0x3806, 0x04},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) {0x3807, 0x47},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) {0x3808, 0x07},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) {0x3809, 0x88},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) {0x380a, 0x04},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) {0x380b, 0x40},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) {0x380c, 0x04},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) {0x380d, 0x38},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) {0x380e, 0x04},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) {0x380f, 0x60},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) {0x3810, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) {0x3811, 0x04},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) {0x3812, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) {0x3813, 0x04},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) {0x3814, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) {0x3815, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) {0x3820, 0x80},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) {0x3821, 0x46},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) {0x3822, 0x84},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) {0x3829, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) {0x382a, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) {0x382b, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) {0x3830, 0x04},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) {0x3836, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) {0x3837, 0x08},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) {0x3839, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) {0x383a, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) {0x383b, 0x08},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) {0x383c, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) {0x3f0b, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) {0x4001, 0x20},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) {0x4009, 0x07},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) {0x4003, 0x10},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) {0x4010, 0xe0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) {0x4016, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) {0x4017, 0x10},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) {0x4044, 0x02},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) {0x4304, 0x08},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) {0x4307, 0x30},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) {0x4320, 0x80},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) {0x4322, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) {0x4323, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) {0x4324, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) {0x4325, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) {0x4326, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) {0x4327, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) {0x4328, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) {0x4329, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) {0x432c, 0x03},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) {0x432d, 0x81},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) {0x4501, 0x84},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) {0x4502, 0x40},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) {0x4503, 0x18},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) {0x4504, 0x04},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) {0x4508, 0x02},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) {0x4601, 0x10},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) {0x4800, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) {0x4816, 0x52},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) {0x4837, 0x16},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) {0x5000, 0x7f},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) {0x5001, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) {0x5005, 0x38},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) {0x501e, 0x0d},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) {0x5040, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) {0x5901, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) {0x3800, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) {0x3801, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) {0x3802, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) {0x3803, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) {0x3804, 0x07},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) {0x3805, 0x8f},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) {0x3806, 0x04},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) {0x3807, 0x47},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) {0x3808, 0x07},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) {0x3809, 0x8c},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) {0x380a, 0x04},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) {0x380b, 0x44},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) {0x3810, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) {0x3811, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) {0x3812, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) {0x3813, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) static const char * const ov2740_test_pattern_menu[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) "Disabled",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) "Color Bar",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) "Top-Bottom Darker Color Bar",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) "Right-Left Darker Color Bar",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) "Bottom-Top Darker Color Bar",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) static const s64 link_freq_menu_items[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) OV2740_LINK_FREQ_360MHZ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) static const struct ov2740_link_freq_config link_freq_configs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) [OV2740_LINK_FREQ_360MHZ_INDEX] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) .reg_list = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) .num_of_regs = ARRAY_SIZE(mipi_data_rate_720mbps),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) .regs = mipi_data_rate_720mbps,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) static const struct ov2740_mode supported_modes[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) .width = 1932,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) .height = 1092,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) .hts = 1080,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) .vts_def = OV2740_VTS_DEF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) .vts_min = OV2740_VTS_MIN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) .reg_list = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) .num_of_regs = ARRAY_SIZE(mode_1932x1092_regs),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) .regs = mode_1932x1092_regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) .link_freq_index = OV2740_LINK_FREQ_360MHZ_INDEX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) struct ov2740 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) struct v4l2_subdev sd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) struct media_pad pad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) struct v4l2_ctrl_handler ctrl_handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) /* V4L2 Controls */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) struct v4l2_ctrl *link_freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) struct v4l2_ctrl *pixel_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) struct v4l2_ctrl *vblank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) struct v4l2_ctrl *hblank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) struct v4l2_ctrl *exposure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) /* Current mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) const struct ov2740_mode *cur_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) /* To serialize asynchronus callbacks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) struct mutex mutex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) /* Streaming on/off */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) bool streaming;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) static inline struct ov2740 *to_ov2740(struct v4l2_subdev *subdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) return container_of(subdev, struct ov2740, sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) static u64 to_pixel_rate(u32 f_index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) u64 pixel_rate = link_freq_menu_items[f_index] * 2 * OV2740_DATA_LANES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) do_div(pixel_rate, OV2740_RGB_DEPTH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) return pixel_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) static u64 to_pixels_per_line(u32 hts, u32 f_index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) u64 ppl = hts * to_pixel_rate(f_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) do_div(ppl, OV2740_SCLK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) return ppl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) static int ov2740_read_reg(struct ov2740 *ov2740, u16 reg, u16 len, u32 *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) struct i2c_client *client = v4l2_get_subdevdata(&ov2740->sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) struct i2c_msg msgs[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) u8 addr_buf[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) u8 data_buf[4] = {0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) if (len > sizeof(data_buf))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) put_unaligned_be16(reg, addr_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) msgs[0].addr = client->addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) msgs[0].flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) msgs[0].len = sizeof(addr_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) msgs[0].buf = addr_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) msgs[1].addr = client->addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) msgs[1].flags = I2C_M_RD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) msgs[1].len = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) msgs[1].buf = &data_buf[sizeof(data_buf) - len];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) if (ret != ARRAY_SIZE(msgs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) return ret < 0 ? ret : -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) *val = get_unaligned_be32(data_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) static int ov2740_write_reg(struct ov2740 *ov2740, u16 reg, u16 len, u32 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) struct i2c_client *client = v4l2_get_subdevdata(&ov2740->sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) u8 buf[6];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) if (len > 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) put_unaligned_be16(reg, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) put_unaligned_be32(val << 8 * (4 - len), buf + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) ret = i2c_master_send(client, buf, len + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) if (ret != len + 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) return ret < 0 ? ret : -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) static int ov2740_write_reg_list(struct ov2740 *ov2740,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) const struct ov2740_reg_list *r_list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) struct i2c_client *client = v4l2_get_subdevdata(&ov2740->sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) for (i = 0; i < r_list->num_of_regs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) ret = ov2740_write_reg(ov2740, r_list->regs[i].address, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) r_list->regs[i].val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) dev_err_ratelimited(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) "write reg 0x%4.4x return err = %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) r_list->regs[i].address, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) static int ov2740_update_digital_gain(struct ov2740 *ov2740, u32 d_gain)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) ret = ov2740_write_reg(ov2740, OV2740_REG_MWB_R_GAIN, 2, d_gain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) ret = ov2740_write_reg(ov2740, OV2740_REG_MWB_G_GAIN, 2, d_gain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) return ov2740_write_reg(ov2740, OV2740_REG_MWB_B_GAIN, 2, d_gain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) static int ov2740_test_pattern(struct ov2740 *ov2740, u32 pattern)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) if (pattern)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) pattern = (pattern - 1) << OV2740_TEST_PATTERN_BAR_SHIFT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) OV2740_TEST_PATTERN_ENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) return ov2740_write_reg(ov2740, OV2740_REG_TEST_PATTERN, 1, pattern);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) static int ov2740_set_ctrl(struct v4l2_ctrl *ctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) struct ov2740 *ov2740 = container_of(ctrl->handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) struct ov2740, ctrl_handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) struct i2c_client *client = v4l2_get_subdevdata(&ov2740->sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) s64 exposure_max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) /* Propagate change of current control to all related controls */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) if (ctrl->id == V4L2_CID_VBLANK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) /* Update max exposure while meeting expected vblanking */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) exposure_max = ov2740->cur_mode->height + ctrl->val -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) OV2740_EXPOSURE_MAX_MARGIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) __v4l2_ctrl_modify_range(ov2740->exposure,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) ov2740->exposure->minimum,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) exposure_max, ov2740->exposure->step,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) exposure_max);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) /* V4L2 controls values will be applied only when power is already up */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) if (!pm_runtime_get_if_in_use(&client->dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) switch (ctrl->id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) case V4L2_CID_ANALOGUE_GAIN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) ret = ov2740_write_reg(ov2740, OV2740_REG_ANALOG_GAIN, 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) ctrl->val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) case V4L2_CID_DIGITAL_GAIN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) ret = ov2740_update_digital_gain(ov2740, ctrl->val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) case V4L2_CID_EXPOSURE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) /* 4 least significant bits of expsoure are fractional part */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) ret = ov2740_write_reg(ov2740, OV2740_REG_EXPOSURE, 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) ctrl->val << 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) case V4L2_CID_VBLANK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) ret = ov2740_write_reg(ov2740, OV2740_REG_VTS, 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) ov2740->cur_mode->height + ctrl->val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) case V4L2_CID_TEST_PATTERN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) ret = ov2740_test_pattern(ov2740, ctrl->val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) pm_runtime_put(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) static const struct v4l2_ctrl_ops ov2740_ctrl_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) .s_ctrl = ov2740_set_ctrl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) static int ov2740_init_controls(struct ov2740 *ov2740)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) struct v4l2_ctrl_handler *ctrl_hdlr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) const struct ov2740_mode *cur_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) s64 exposure_max, h_blank, pixel_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) u32 vblank_min, vblank_max, vblank_default;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) int size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) ctrl_hdlr = &ov2740->ctrl_handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) ret = v4l2_ctrl_handler_init(ctrl_hdlr, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) ctrl_hdlr->lock = &ov2740->mutex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) cur_mode = ov2740->cur_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) size = ARRAY_SIZE(link_freq_menu_items);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) ov2740->link_freq = v4l2_ctrl_new_int_menu(ctrl_hdlr, &ov2740_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) V4L2_CID_LINK_FREQ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) size - 1, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) link_freq_menu_items);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) if (ov2740->link_freq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) ov2740->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) pixel_rate = to_pixel_rate(OV2740_LINK_FREQ_360MHZ_INDEX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) ov2740->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &ov2740_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) V4L2_CID_PIXEL_RATE, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) pixel_rate, 1, pixel_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) vblank_min = cur_mode->vts_min - cur_mode->height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) vblank_max = OV2740_VTS_MAX - cur_mode->height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) vblank_default = cur_mode->vts_def - cur_mode->height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) ov2740->vblank = v4l2_ctrl_new_std(ctrl_hdlr, &ov2740_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) V4L2_CID_VBLANK, vblank_min,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) vblank_max, 1, vblank_default);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) h_blank = to_pixels_per_line(cur_mode->hts, cur_mode->link_freq_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) h_blank -= cur_mode->width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) ov2740->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &ov2740_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) V4L2_CID_HBLANK, h_blank, h_blank, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) h_blank);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) if (ov2740->hblank)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) ov2740->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) v4l2_ctrl_new_std(ctrl_hdlr, &ov2740_ctrl_ops, V4L2_CID_ANALOGUE_GAIN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) OV2740_ANAL_GAIN_MIN, OV2740_ANAL_GAIN_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) OV2740_ANAL_GAIN_STEP, OV2740_ANAL_GAIN_MIN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) v4l2_ctrl_new_std(ctrl_hdlr, &ov2740_ctrl_ops, V4L2_CID_DIGITAL_GAIN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) OV2740_DGTL_GAIN_MIN, OV2740_DGTL_GAIN_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) OV2740_DGTL_GAIN_STEP, OV2740_DGTL_GAIN_DEFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) exposure_max = cur_mode->vts_def - OV2740_EXPOSURE_MAX_MARGIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) ov2740->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &ov2740_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) V4L2_CID_EXPOSURE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) OV2740_EXPOSURE_MIN, exposure_max,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) OV2740_EXPOSURE_STEP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) exposure_max);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) v4l2_ctrl_new_std_menu_items(ctrl_hdlr, &ov2740_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) V4L2_CID_TEST_PATTERN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) ARRAY_SIZE(ov2740_test_pattern_menu) - 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) 0, 0, ov2740_test_pattern_menu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) if (ctrl_hdlr->error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) return ctrl_hdlr->error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) ov2740->sd.ctrl_handler = ctrl_hdlr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) static void ov2740_update_pad_format(const struct ov2740_mode *mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) struct v4l2_mbus_framefmt *fmt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) fmt->width = mode->width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) fmt->height = mode->height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) fmt->code = MEDIA_BUS_FMT_SGRBG10_1X10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) fmt->field = V4L2_FIELD_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) static int ov2740_start_streaming(struct ov2740 *ov2740)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) struct i2c_client *client = v4l2_get_subdevdata(&ov2740->sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) const struct ov2740_reg_list *reg_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) int link_freq_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) link_freq_index = ov2740->cur_mode->link_freq_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) reg_list = &link_freq_configs[link_freq_index].reg_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) ret = ov2740_write_reg_list(ov2740, reg_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) dev_err(&client->dev, "failed to set plls");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) reg_list = &ov2740->cur_mode->reg_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) ret = ov2740_write_reg_list(ov2740, reg_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) dev_err(&client->dev, "failed to set mode");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) ret = __v4l2_ctrl_handler_setup(ov2740->sd.ctrl_handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) ret = ov2740_write_reg(ov2740, OV2740_REG_MODE_SELECT, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) OV2740_MODE_STREAMING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) dev_err(&client->dev, "failed to start streaming");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) static void ov2740_stop_streaming(struct ov2740 *ov2740)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) struct i2c_client *client = v4l2_get_subdevdata(&ov2740->sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) if (ov2740_write_reg(ov2740, OV2740_REG_MODE_SELECT, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) OV2740_MODE_STANDBY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) dev_err(&client->dev, "failed to stop streaming");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) static int ov2740_set_stream(struct v4l2_subdev *sd, int enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) struct ov2740 *ov2740 = to_ov2740(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) struct i2c_client *client = v4l2_get_subdevdata(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) if (ov2740->streaming == enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) mutex_lock(&ov2740->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) if (enable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) ret = pm_runtime_get_sync(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) pm_runtime_put_noidle(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) mutex_unlock(&ov2740->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) ret = ov2740_start_streaming(ov2740);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) enable = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) ov2740_stop_streaming(ov2740);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) pm_runtime_put(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) ov2740_stop_streaming(ov2740);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) pm_runtime_put(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) ov2740->streaming = enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) mutex_unlock(&ov2740->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) static int __maybe_unused ov2740_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) struct i2c_client *client = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) struct v4l2_subdev *sd = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) struct ov2740 *ov2740 = to_ov2740(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) mutex_lock(&ov2740->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) if (ov2740->streaming)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) ov2740_stop_streaming(ov2740);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) mutex_unlock(&ov2740->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) static int __maybe_unused ov2740_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) struct i2c_client *client = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) struct v4l2_subdev *sd = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) struct ov2740 *ov2740 = to_ov2740(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) mutex_lock(&ov2740->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) if (!ov2740->streaming)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) ret = ov2740_start_streaming(ov2740);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) ov2740->streaming = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) ov2740_stop_streaming(ov2740);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) mutex_unlock(&ov2740->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) static int ov2740_set_format(struct v4l2_subdev *sd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) struct v4l2_subdev_pad_config *cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) struct v4l2_subdev_format *fmt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) struct ov2740 *ov2740 = to_ov2740(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) const struct ov2740_mode *mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) s32 vblank_def, h_blank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) mode = v4l2_find_nearest_size(supported_modes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) ARRAY_SIZE(supported_modes), width,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) height, fmt->format.width,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) fmt->format.height);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) mutex_lock(&ov2740->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) ov2740_update_pad_format(mode, &fmt->format);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) *v4l2_subdev_get_try_format(sd, cfg, fmt->pad) = fmt->format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) ov2740->cur_mode = mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) __v4l2_ctrl_s_ctrl(ov2740->link_freq, mode->link_freq_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) __v4l2_ctrl_s_ctrl_int64(ov2740->pixel_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) to_pixel_rate(mode->link_freq_index));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) /* Update limits and set FPS to default */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) vblank_def = mode->vts_def - mode->height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) __v4l2_ctrl_modify_range(ov2740->vblank,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) mode->vts_min - mode->height,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) OV2740_VTS_MAX - mode->height, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) vblank_def);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) __v4l2_ctrl_s_ctrl(ov2740->vblank, vblank_def);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) h_blank = to_pixels_per_line(mode->hts, mode->link_freq_index) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) mode->width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) __v4l2_ctrl_modify_range(ov2740->hblank, h_blank, h_blank, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) h_blank);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) mutex_unlock(&ov2740->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) static int ov2740_get_format(struct v4l2_subdev *sd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) struct v4l2_subdev_pad_config *cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) struct v4l2_subdev_format *fmt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) struct ov2740 *ov2740 = to_ov2740(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) mutex_lock(&ov2740->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) if (fmt->which == V4L2_SUBDEV_FORMAT_TRY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) fmt->format = *v4l2_subdev_get_try_format(&ov2740->sd, cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) fmt->pad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) ov2740_update_pad_format(ov2740->cur_mode, &fmt->format);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) mutex_unlock(&ov2740->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) static int ov2740_enum_mbus_code(struct v4l2_subdev *sd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) struct v4l2_subdev_pad_config *cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) struct v4l2_subdev_mbus_code_enum *code)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) if (code->index > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) code->code = MEDIA_BUS_FMT_SGRBG10_1X10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) static int ov2740_enum_frame_size(struct v4l2_subdev *sd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) struct v4l2_subdev_pad_config *cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) struct v4l2_subdev_frame_size_enum *fse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) if (fse->index >= ARRAY_SIZE(supported_modes))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) if (fse->code != MEDIA_BUS_FMT_SGRBG10_1X10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) fse->min_width = supported_modes[fse->index].width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) fse->max_width = fse->min_width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) fse->min_height = supported_modes[fse->index].height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) fse->max_height = fse->min_height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) static int ov2740_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) struct ov2740 *ov2740 = to_ov2740(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) mutex_lock(&ov2740->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) ov2740_update_pad_format(&supported_modes[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) v4l2_subdev_get_try_format(sd, fh->pad, 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) mutex_unlock(&ov2740->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) static const struct v4l2_subdev_video_ops ov2740_video_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) .s_stream = ov2740_set_stream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) static const struct v4l2_subdev_pad_ops ov2740_pad_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) .set_fmt = ov2740_set_format,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) .get_fmt = ov2740_get_format,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) .enum_mbus_code = ov2740_enum_mbus_code,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) .enum_frame_size = ov2740_enum_frame_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) static const struct v4l2_subdev_ops ov2740_subdev_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) .video = &ov2740_video_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) .pad = &ov2740_pad_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) static const struct media_entity_operations ov2740_subdev_entity_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) .link_validate = v4l2_subdev_link_validate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) static const struct v4l2_subdev_internal_ops ov2740_internal_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) .open = ov2740_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) static int ov2740_identify_module(struct ov2740 *ov2740)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) struct i2c_client *client = v4l2_get_subdevdata(&ov2740->sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) ret = ov2740_read_reg(ov2740, OV2740_REG_CHIP_ID, 3, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) if (val != OV2740_CHIP_ID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) dev_err(&client->dev, "chip id mismatch: %x!=%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) OV2740_CHIP_ID, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) static int ov2740_check_hwcfg(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) struct fwnode_handle *ep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) struct fwnode_handle *fwnode = dev_fwnode(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) struct v4l2_fwnode_endpoint bus_cfg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) .bus_type = V4L2_MBUS_CSI2_DPHY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) u32 mclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) unsigned int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) if (!fwnode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) ret = fwnode_property_read_u32(fwnode, "clock-frequency", &mclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) if (mclk != OV2740_MCLK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) dev_err(dev, "external clock %d is not supported", mclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) ep = fwnode_graph_get_next_endpoint(fwnode, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) if (!ep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) ret = v4l2_fwnode_endpoint_alloc_parse(ep, &bus_cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) fwnode_handle_put(ep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) if (bus_cfg.bus.mipi_csi2.num_data_lanes != OV2740_DATA_LANES) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) dev_err(dev, "number of CSI2 data lanes %d is not supported",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) bus_cfg.bus.mipi_csi2.num_data_lanes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) goto check_hwcfg_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) if (!bus_cfg.nr_of_link_frequencies) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) dev_err(dev, "no link frequencies defined");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) goto check_hwcfg_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) for (i = 0; i < ARRAY_SIZE(link_freq_menu_items); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) for (j = 0; j < bus_cfg.nr_of_link_frequencies; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) if (link_freq_menu_items[i] ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) bus_cfg.link_frequencies[j])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) if (j == bus_cfg.nr_of_link_frequencies) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) dev_err(dev, "no link frequency %lld supported",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) link_freq_menu_items[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) goto check_hwcfg_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) check_hwcfg_error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) v4l2_fwnode_endpoint_free(&bus_cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) static int ov2740_remove(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) struct v4l2_subdev *sd = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) struct ov2740 *ov2740 = to_ov2740(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) v4l2_async_unregister_subdev(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) media_entity_cleanup(&sd->entity);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) v4l2_ctrl_handler_free(sd->ctrl_handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) pm_runtime_disable(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) mutex_destroy(&ov2740->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) static int ov2740_load_otp_data(struct i2c_client *client, struct nvm_data *nvm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) struct ov2740 *ov2740 = to_ov2740(i2c_get_clientdata(client));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) u32 isp_ctrl00 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) u32 isp_ctrl01 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) ret = ov2740_read_reg(ov2740, OV2740_REG_ISP_CTRL00, 1, &isp_ctrl00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) dev_err(&client->dev, "failed to read ISP CTRL00\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) ret = ov2740_read_reg(ov2740, OV2740_REG_ISP_CTRL01, 1, &isp_ctrl01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) dev_err(&client->dev, "failed to read ISP CTRL01\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) /* Clear bit 5 of ISP CTRL00 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) ret = ov2740_write_reg(ov2740, OV2740_REG_ISP_CTRL00, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) isp_ctrl00 & ~BIT(5));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) dev_err(&client->dev, "failed to write ISP CTRL00\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) /* Clear bit 7 of ISP CTRL01 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) ret = ov2740_write_reg(ov2740, OV2740_REG_ISP_CTRL01, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) isp_ctrl01 & ~BIT(7));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) dev_err(&client->dev, "failed to write ISP CTRL01\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) ret = ov2740_write_reg(ov2740, OV2740_REG_MODE_SELECT, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) OV2740_MODE_STREAMING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) dev_err(&client->dev, "failed to start streaming\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) * Users are not allowed to access OTP-related registers and memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) * during the 20 ms period after streaming starts (0x100 = 0x01).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) msleep(20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) ret = regmap_bulk_read(nvm->regmap, OV2740_REG_OTP_CUSTOMER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) nvm->nvm_buffer, CUSTOMER_USE_OTP_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) dev_err(&client->dev, "failed to read OTP data, ret %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) ov2740_write_reg(ov2740, OV2740_REG_MODE_SELECT, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) OV2740_MODE_STANDBY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) ov2740_write_reg(ov2740, OV2740_REG_ISP_CTRL01, 1, isp_ctrl01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) ov2740_write_reg(ov2740, OV2740_REG_ISP_CTRL00, 1, isp_ctrl00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) static int ov2740_nvmem_read(void *priv, unsigned int off, void *val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) struct nvm_data *nvm = priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) memcpy(val, nvm->nvm_buffer + off, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) static int ov2740_register_nvmem(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) struct nvm_data *nvm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) struct regmap_config regmap_config = { };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) struct nvmem_config nvmem_config = { };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) struct regmap *regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) struct device *dev = &client->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) nvm = devm_kzalloc(dev, sizeof(*nvm), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) if (!nvm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) nvm->nvm_buffer = devm_kzalloc(dev, CUSTOMER_USE_OTP_SIZE, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) if (!nvm->nvm_buffer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) regmap_config.val_bits = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) regmap_config.reg_bits = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) regmap_config.disable_locking = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) regmap = devm_regmap_init_i2c(client, ®map_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) if (IS_ERR(regmap))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) return PTR_ERR(regmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) nvm->regmap = regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) ret = ov2740_load_otp_data(client, nvm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) dev_err(dev, "failed to load OTP data, ret %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) nvmem_config.name = dev_name(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) nvmem_config.dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) nvmem_config.read_only = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) nvmem_config.root_only = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) nvmem_config.owner = THIS_MODULE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) nvmem_config.compat = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) nvmem_config.base_dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) nvmem_config.reg_read = ov2740_nvmem_read;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) nvmem_config.reg_write = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) nvmem_config.priv = nvm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) nvmem_config.stride = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) nvmem_config.word_size = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) nvmem_config.size = CUSTOMER_USE_OTP_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) nvm->nvmem = devm_nvmem_register(dev, &nvmem_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) return PTR_ERR_OR_ZERO(nvm->nvmem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) static int ov2740_probe(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) struct ov2740 *ov2740;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) ret = ov2740_check_hwcfg(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) dev_err(&client->dev, "failed to check HW configuration: %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) ov2740 = devm_kzalloc(&client->dev, sizeof(*ov2740), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) if (!ov2740)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) v4l2_i2c_subdev_init(&ov2740->sd, client, &ov2740_subdev_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) ret = ov2740_identify_module(ov2740);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) dev_err(&client->dev, "failed to find sensor: %d", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) mutex_init(&ov2740->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) ov2740->cur_mode = &supported_modes[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) ret = ov2740_init_controls(ov2740);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) dev_err(&client->dev, "failed to init controls: %d", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) goto probe_error_v4l2_ctrl_handler_free;
^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) ov2740->sd.internal_ops = &ov2740_internal_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) ov2740->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) ov2740->sd.entity.ops = &ov2740_subdev_entity_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) ov2740->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) ov2740->pad.flags = MEDIA_PAD_FL_SOURCE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) ret = media_entity_pads_init(&ov2740->sd.entity, 1, &ov2740->pad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) dev_err(&client->dev, "failed to init entity pads: %d", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) goto probe_error_v4l2_ctrl_handler_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) ret = v4l2_async_register_subdev_sensor_common(&ov2740->sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) dev_err(&client->dev, "failed to register V4L2 subdev: %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) goto probe_error_media_entity_cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) ret = ov2740_register_nvmem(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) dev_warn(&client->dev, "register nvmem failed, ret %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) * Device is already turned on by i2c-core with ACPI domain PM.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) * Enable runtime PM and turn off the device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) pm_runtime_set_active(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) pm_runtime_enable(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) pm_runtime_idle(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) probe_error_media_entity_cleanup:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) media_entity_cleanup(&ov2740->sd.entity);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) probe_error_v4l2_ctrl_handler_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) v4l2_ctrl_handler_free(ov2740->sd.ctrl_handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) mutex_destroy(&ov2740->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) static const struct dev_pm_ops ov2740_pm_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) SET_SYSTEM_SLEEP_PM_OPS(ov2740_suspend, ov2740_resume)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) static const struct acpi_device_id ov2740_acpi_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) {"INT3474"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) MODULE_DEVICE_TABLE(acpi, ov2740_acpi_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) static struct i2c_driver ov2740_i2c_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) .name = "ov2740",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) .pm = &ov2740_pm_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) .acpi_match_table = ov2740_acpi_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) .probe_new = ov2740_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) .remove = ov2740_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) module_i2c_driver(ov2740_i2c_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) MODULE_AUTHOR("Qiu, Tianshu <tian.shu.qiu@intel.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) MODULE_AUTHOR("Shawn Tu <shawnx.tu@intel.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) MODULE_AUTHOR("Bingbu Cao <bingbu.cao@intel.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) MODULE_DESCRIPTION("OmniVision OV2740 sensor driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) MODULE_LICENSE("GPL v2");