^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) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * imx415 driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2020 Rockchip Electronics Co., Ltd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * V0.0X01.0X00 first version.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * V0.0X01.0X01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * 1. fix hdr ae ratio error,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * 0x3260 should be set 0x01 in normal mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * should be 0x00 in hdr mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * 2. rhs1 should be 4n+1 when set hdr ae.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * V0.0X01.0X02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * 1. shr0 should be greater than (rsh1 + 9).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * 2. rhs1 should be ceil to 4n + 1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * V0.0X01.0X03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * 1. support 12bit HDR DOL3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * 2. support HDR/Linear quick switch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * V0.0X01.0X04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * 1. support enum format info by aiq
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * V0.0X01.0X05
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * 1. fixed 10bit hdr2/hdr3 frame rate issue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * V0.0X01.0X06
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * 1. support DOL3 10bit 20fps 1485Mbps
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * 2. fixed linkfreq error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * V0.0X01.0X07
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * 1. fix set_fmt & ioctl get mode unmatched issue.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * 2. need to set default vblank when change format.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * 3. enum all supported mode mbus_code, not just cur_mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * V0.0X01.0X08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * 1. add dcphy param for hdrx2 mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include <linux/gpio/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #include <linux/pm_runtime.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #include <linux/regulator/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #include <linux/sysfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #include <linux/version.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #include <linux/rk-camera-module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #include <media/media-entity.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #include <media/v4l2-async.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #include <media/v4l2-ctrls.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #include <media/v4l2-subdev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #include <linux/pinctrl/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #include <linux/rk-preisp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #include "../platform/rockchip/isp/rkisp_tb_helper.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x08)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #ifndef V4L2_CID_DIGITAL_GAIN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define V4L2_CID_DIGITAL_GAIN V4L2_CID_GAIN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define MIPI_FREQ_891M 891000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define MIPI_FREQ_446M 446000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define MIPI_FREQ_743M 743000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define MIPI_FREQ_297M 297000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define IMX415_4LANES 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define IMX415_MAX_PIXEL_RATE (MIPI_FREQ_891M / 10 * 2 * IMX415_4LANES)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define OF_CAMERA_HDR_MODE "rockchip,camera-hdr-mode"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define IMX415_XVCLK_FREQ_37M 37125000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) /* TODO: Get the real chip id from reg */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #define CHIP_ID 0xE0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #define IMX415_REG_CHIP_ID 0x311A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define IMX415_REG_CTRL_MODE 0x3000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #define IMX415_MODE_SW_STANDBY BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #define IMX415_MODE_STREAMING 0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #define IMX415_LF_GAIN_REG_H 0x3091
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define IMX415_LF_GAIN_REG_L 0x3090
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #define IMX415_SF1_GAIN_REG_H 0x3093
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #define IMX415_SF1_GAIN_REG_L 0x3092
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #define IMX415_SF2_GAIN_REG_H 0x3095
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #define IMX415_SF2_GAIN_REG_L 0x3094
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) #define IMX415_LF_EXPO_REG_H 0x3052
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) #define IMX415_LF_EXPO_REG_M 0x3051
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) #define IMX415_LF_EXPO_REG_L 0x3050
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) #define IMX415_SF1_EXPO_REG_H 0x3056
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) #define IMX415_SF1_EXPO_REG_M 0x3055
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) #define IMX415_SF1_EXPO_REG_L 0x3054
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) #define IMX415_SF2_EXPO_REG_H 0x305A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) #define IMX415_SF2_EXPO_REG_M 0x3059
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) #define IMX415_SF2_EXPO_REG_L 0x3058
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) #define IMX415_RHS1_REG_H 0x3062
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) #define IMX415_RHS1_REG_M 0x3061
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) #define IMX415_RHS1_REG_L 0x3060
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) #define IMX415_RHS1_DEFAULT 0x004D
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) #define IMX415_RHS2_REG_H 0x3066
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) #define IMX415_RHS2_REG_M 0x3065
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) #define IMX415_RHS2_REG_L 0x3064
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) #define IMX415_RHS2_DEFAULT 0x004D
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) #define IMX415_EXPOSURE_MIN 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) #define IMX415_EXPOSURE_STEP 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) #define IMX415_VTS_MAX 0x7fff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) #define IMX415_GAIN_MIN 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) #define IMX415_GAIN_MAX 0xf0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) #define IMX415_GAIN_STEP 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) #define IMX415_GAIN_DEFAULT 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) #define IMX415_FETCH_GAIN_H(VAL) (((VAL) >> 8) & 0x07)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) #define IMX415_FETCH_GAIN_L(VAL) ((VAL) & 0xFF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) #define IMX415_FETCH_EXP_H(VAL) (((VAL) >> 16) & 0x0F)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) #define IMX415_FETCH_EXP_M(VAL) (((VAL) >> 8) & 0xFF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) #define IMX415_FETCH_EXP_L(VAL) ((VAL) & 0xFF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) #define IMX415_FETCH_RHS1_H(VAL) (((VAL) >> 16) & 0x0F)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) #define IMX415_FETCH_RHS1_M(VAL) (((VAL) >> 8) & 0xFF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) #define IMX415_FETCH_RHS1_L(VAL) ((VAL) & 0xFF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) #define IMX415_FETCH_VTS_H(VAL) (((VAL) >> 16) & 0x0F)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) #define IMX415_FETCH_VTS_M(VAL) (((VAL) >> 8) & 0xFF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) #define IMX415_FETCH_VTS_L(VAL) ((VAL) & 0xFF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) #define IMX415_VTS_REG_L 0x3024
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) #define IMX415_VTS_REG_M 0x3025
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) #define IMX415_VTS_REG_H 0x3026
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) #define IMX415_MIRROR_BIT_MASK BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) #define IMX415_FLIP_BIT_MASK BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) #define IMX415_FLIP_REG 0x3030
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) #define REG_NULL 0xFFFF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) #define IMX415_REG_VALUE_08BIT 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) #define IMX415_REG_VALUE_16BIT 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) #define IMX415_REG_VALUE_24BIT 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) #define IMX415_GROUP_HOLD_REG 0x3001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) #define IMX415_GROUP_HOLD_START 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) #define IMX415_GROUP_HOLD_END 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) /* Basic Readout Lines. Number of necessary readout lines in sensor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) #define BRL_ALL 2228u
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) #define BRL_BINNING 1115u
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) /* Readout timing setting of SEF1(DOL2): RHS1 < 2 * BRL and should be 4n + 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) #define RHS1_MAX_X2(VAL) (((VAL) * 2 - 1) / 4 * 4 + 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) #define SHR1_MIN_X2 9u
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) /* Readout timing setting of SEF1(DOL3): RHS1 < 3 * BRL and should be 6n + 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) #define RHS1_MAX_X3(VAL) (((VAL) * 3 - 1) / 6 * 6 + 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) #define SHR1_MIN_X3 13u
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) #define OF_CAMERA_PINCTRL_STATE_DEFAULT "rockchip,camera_default"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) #define OF_CAMERA_PINCTRL_STATE_SLEEP "rockchip,camera_sleep"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) #define IMX415_NAME "imx415"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) static const char * const imx415_supply_names[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) "dvdd", /* Digital core power */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) "dovdd", /* Digital I/O power */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) "avdd", /* Analog power */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) #define IMX415_NUM_SUPPLIES ARRAY_SIZE(imx415_supply_names)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) struct regval {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) u16 addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) u8 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) struct imx415_mode {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) u32 bus_fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) u32 width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) u32 height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) struct v4l2_fract max_fps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) u32 hts_def;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) u32 vts_def;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) u32 exp_def;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) u32 mipi_freq_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) u32 bpp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) const struct regval *global_reg_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) const struct regval *reg_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) u32 hdr_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) u32 vc[PAD_MAX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) struct imx415 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) struct i2c_client *client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) struct clk *xvclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) struct gpio_desc *reset_gpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) struct gpio_desc *power_gpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) struct regulator_bulk_data supplies[IMX415_NUM_SUPPLIES];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) struct pinctrl *pinctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) struct pinctrl_state *pins_default;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) struct pinctrl_state *pins_sleep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) struct v4l2_subdev subdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) struct media_pad pad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) struct v4l2_ctrl_handler ctrl_handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) struct v4l2_ctrl *exposure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) struct v4l2_ctrl *anal_a_gain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) struct v4l2_ctrl *digi_gain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) struct v4l2_ctrl *hblank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) struct v4l2_ctrl *vblank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) struct v4l2_ctrl *pixel_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) struct v4l2_ctrl *link_freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) struct mutex mutex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) bool streaming;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) bool power_on;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) bool is_thunderboot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) bool is_thunderboot_ng;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) bool is_first_streamoff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) const struct imx415_mode *cur_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) u32 module_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) u32 cfg_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) const char *module_facing;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) const char *module_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) const char *len_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) u32 cur_vts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) bool has_init_exp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) struct preisp_hdrae_exp_s init_hdrae_exp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) static struct rkmodule_csi_dphy_param dcphy_param = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) .vendor = PHY_VENDOR_SAMSUNG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) .lp_vol_ref = 6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) .lp_hys_sw = {3, 0, 0, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) .lp_escclk_pol_sel = {1, 1, 1, 1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) .skew_data_cal_clk = {0, 3, 3, 3},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) .clk_hs_term_sel = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) .data_hs_term_sel = {2, 2, 2, 2},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) .reserved = {0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) #define to_imx415(sd) container_of(sd, struct imx415, subdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) * Xclk 37.125Mhz
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) static __maybe_unused const struct regval imx415_global_12bit_3864x2192_regs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) {0x3002, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) {0x3008, 0x7F},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) {0x300A, 0x5B},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) {0x30C1, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) {0x3031, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) {0x3032, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) {0x30D9, 0x06},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) {0x3116, 0x24},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) {0x3118, 0xC0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) {0x311E, 0x24},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) {0x32D4, 0x21},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) {0x32EC, 0xA1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) {0x3452, 0x7F},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) {0x3453, 0x03},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) {0x358A, 0x04},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) {0x35A1, 0x02},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) {0x36BC, 0x0C},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) {0x36CC, 0x53},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) {0x36CD, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) {0x36CE, 0x3C},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) {0x36D0, 0x8C},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) {0x36D1, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) {0x36D2, 0x71},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) {0x36D4, 0x3C},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) {0x36D6, 0x53},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) {0x36D7, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) {0x36D8, 0x71},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) {0x36DA, 0x8C},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) {0x36DB, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) {0x3701, 0x03},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) {0x3724, 0x02},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) {0x3726, 0x02},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) {0x3732, 0x02},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) {0x3734, 0x03},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) {0x3736, 0x03},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) {0x3742, 0x03},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) {0x3862, 0xE0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) {0x38CC, 0x30},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) {0x38CD, 0x2F},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) {0x395C, 0x0C},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) {0x3A42, 0xD1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) {0x3A4C, 0x77},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) {0x3AE0, 0x02},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) {0x3AEC, 0x0C},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) {0x3B00, 0x2E},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) {0x3B06, 0x29},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) {0x3B98, 0x25},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) {0x3B99, 0x21},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) {0x3B9B, 0x13},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) {0x3B9C, 0x13},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) {0x3B9D, 0x13},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) {0x3B9E, 0x13},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) {0x3BA1, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) {0x3BA2, 0x06},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) {0x3BA3, 0x0B},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) {0x3BA4, 0x10},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) {0x3BA5, 0x14},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) {0x3BA6, 0x18},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) {0x3BA7, 0x1A},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) {0x3BA8, 0x1A},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) {0x3BA9, 0x1A},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) {0x3BAC, 0xED},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) {0x3BAD, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) {0x3BAE, 0xF6},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) {0x3BAF, 0x02},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) {0x3BB0, 0xA2},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) {0x3BB1, 0x03},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) {0x3BB2, 0xE0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) {0x3BB3, 0x03},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) {0x3BB4, 0xE0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) {0x3BB5, 0x03},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) {0x3BB6, 0xE0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) {0x3BB7, 0x03},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) {0x3BB8, 0xE0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) {0x3BBA, 0xE0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) {0x3BBC, 0xDA},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) {0x3BBE, 0x88},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) {0x3BC0, 0x44},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) {0x3BC2, 0x7B},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) {0x3BC4, 0xA2},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) {0x3BC8, 0xBD},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) {0x3BCA, 0xBD},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) {0x4004, 0x48},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) {0x4005, 0x09},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) {REG_NULL, 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 __maybe_unused const struct regval imx415_linear_12bit_3864x2192_891M_regs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) {0x3020, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) {0x3021, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) {0x3022, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) {0x3024, 0xCA},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) {0x3025, 0x08},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) {0x3028, 0x4C},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) {0x3029, 0x04},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) {0x302C, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) {0x302D, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) {0x3033, 0x05},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) {0x3050, 0x08},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) {0x3051, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) {0x3054, 0x19},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) {0x3058, 0x3E},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) {0x3060, 0x25},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) {0x3064, 0x4A},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) {0x30CF, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) {0x3260, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) {0x400C, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) {0x4018, 0x7F},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) {0x401A, 0x37},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) {0x401C, 0x37},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) {0x401E, 0xF7},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) {0x401F, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) {0x4020, 0x3F},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) {0x4022, 0x6F},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) {0x4024, 0x3F},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) {0x4026, 0x5F},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) {0x4028, 0x2F},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) {0x4074, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) {REG_NULL, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) static __maybe_unused const struct regval imx415_hdr2_12bit_3864x2192_1782M_regs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) {0x3020, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) {0x3021, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) {0x3022, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) {0x3024, 0xCA},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) {0x3025, 0x08},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) {0x3028, 0x26},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) {0x3029, 0x02},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) {0x302C, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) {0x302D, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) {0x3033, 0x04},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) {0x3050, 0x90},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) {0x3051, 0x0D},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) {0x3054, 0x09},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) {0x3058, 0x3E},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) {0x3060, 0x4D},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) {0x3064, 0x4A},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) {0x30CF, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) {0x3260, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) {0x400C, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) {0x4018, 0xB7},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) {0x401A, 0x67},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) {0x401C, 0x6F},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) {0x401E, 0xDF},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) {0x401F, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) {0x4020, 0x6F},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) {0x4022, 0xCF},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) {0x4024, 0x6F},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) {0x4026, 0xB7},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) {0x4028, 0x5F},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) {0x4074, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) {REG_NULL, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) static __maybe_unused const struct regval imx415_hdr3_12bit_3864x2192_1782M_regs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) {0x3020, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) {0x3021, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) {0x3022, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) {0x3024, 0x96},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) {0x3025, 0x06},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) {0x3028, 0x26},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) {0x3029, 0x02},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) {0x302C, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) {0x302D, 0x02},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) {0x3033, 0x04},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) {0x3050, 0x14},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) {0x3051, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) {0x3054, 0x0D},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) {0x3058, 0x26},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) {0x3060, 0x19},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) {0x3064, 0x32},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) {0x30CF, 0x03},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) {0x3260, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) {0x400C, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) {0x4018, 0xB7},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) {0x401A, 0x67},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) {0x401C, 0x6F},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) {0x401E, 0xDF},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) {0x401F, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) {0x4020, 0x6F},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) {0x4022, 0xCF},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) {0x4024, 0x6F},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) {0x4026, 0xB7},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) {0x4028, 0x5F},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) {0x4074, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) {REG_NULL, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) static __maybe_unused const struct regval imx415_global_10bit_3864x2192_regs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) {0x3002, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) {0x3008, 0x7F},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) {0x300A, 0x5B},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) {0x3031, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) {0x3032, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) {0x30C1, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) {0x30D9, 0x06},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) {0x3116, 0x24},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) {0x311E, 0x24},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) {0x32D4, 0x21},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) {0x32EC, 0xA1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) {0x3452, 0x7F},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) {0x3453, 0x03},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) {0x358A, 0x04},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) {0x35A1, 0x02},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) {0x36BC, 0x0C},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) {0x36CC, 0x53},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) {0x36CD, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) {0x36CE, 0x3C},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) {0x36D0, 0x8C},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) {0x36D1, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) {0x36D2, 0x71},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) {0x36D4, 0x3C},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) {0x36D6, 0x53},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) {0x36D7, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) {0x36D8, 0x71},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) {0x36DA, 0x8C},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) {0x36DB, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) {0x3701, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) {0x3724, 0x02},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) {0x3726, 0x02},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) {0x3732, 0x02},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) {0x3734, 0x03},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) {0x3736, 0x03},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) {0x3742, 0x03},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) {0x3862, 0xE0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) {0x38CC, 0x30},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) {0x38CD, 0x2F},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) {0x395C, 0x0C},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) {0x3A42, 0xD1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) {0x3A4C, 0x77},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) {0x3AE0, 0x02},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) {0x3AEC, 0x0C},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) {0x3B00, 0x2E},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) {0x3B06, 0x29},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) {0x3B98, 0x25},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) {0x3B99, 0x21},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) {0x3B9B, 0x13},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) {0x3B9C, 0x13},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) {0x3B9D, 0x13},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) {0x3B9E, 0x13},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) {0x3BA1, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) {0x3BA2, 0x06},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) {0x3BA3, 0x0B},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) {0x3BA4, 0x10},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) {0x3BA5, 0x14},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) {0x3BA6, 0x18},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) {0x3BA7, 0x1A},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) {0x3BA8, 0x1A},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) {0x3BA9, 0x1A},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) {0x3BAC, 0xED},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) {0x3BAD, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) {0x3BAE, 0xF6},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) {0x3BAF, 0x02},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) {0x3BB0, 0xA2},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) {0x3BB1, 0x03},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) {0x3BB2, 0xE0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) {0x3BB3, 0x03},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) {0x3BB4, 0xE0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) {0x3BB5, 0x03},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) {0x3BB6, 0xE0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) {0x3BB7, 0x03},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) {0x3BB8, 0xE0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) {0x3BBA, 0xE0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) {0x3BBC, 0xDA},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) {0x3BBE, 0x88},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) {0x3BC0, 0x44},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) {0x3BC2, 0x7B},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) {0x3BC4, 0xA2},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) {0x3BC8, 0xBD},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) {0x3BCA, 0xBD},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) {0x4004, 0x48},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) {0x4005, 0x09},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) {REG_NULL, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) static __maybe_unused const struct regval imx415_hdr3_10bit_3864x2192_1485M_regs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) {0x3020, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) {0x3021, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) {0x3022, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) {0x3024, 0xBD},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) {0x3025, 0x06},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) {0x3028, 0x1A},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) {0x3029, 0x02},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) {0x302C, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) {0x302D, 0x02},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) {0x3033, 0x08},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) {0x3050, 0x90},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) {0x3051, 0x15},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) {0x3054, 0x0D},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) {0x3058, 0xA4},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) {0x3060, 0x97},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) {0x3064, 0xB6},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) {0x30CF, 0x03},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) {0x3118, 0xA0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) {0x3260, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) {0x400C, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) {0x4018, 0xA7},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) {0x401A, 0x57},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) {0x401C, 0x5F},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) {0x401E, 0x97},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) {0x401F, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) {0x4020, 0x5F},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) {0x4022, 0xAF},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) {0x4024, 0x5F},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) {0x4026, 0x9F},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) {0x4028, 0x4F},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) {0x4074, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) {REG_NULL, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) static __maybe_unused const struct regval imx415_hdr3_10bit_3864x2192_1782M_regs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) {0x3020, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) {0x3021, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) {0x3022, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) {0x3024, 0xEA},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) {0x3025, 0x07},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) {0x3028, 0xCA},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) {0x3029, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) {0x302C, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) {0x302D, 0x02},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) {0x3033, 0x04},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) {0x3050, 0x3E},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) {0x3051, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) {0x3054, 0x0D},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) {0x3058, 0x9E},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) {0x3060, 0x91},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) {0x3064, 0xC2},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) {0x30CF, 0x03},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) {0x3118, 0xC0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) {0x3260, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) {0x400C, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) {0x4018, 0xB7},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) {0x401A, 0x67},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) {0x401C, 0x6F},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) {0x401E, 0xDF},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) {0x401F, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) {0x4020, 0x6F},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) {0x4022, 0xCF},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) {0x4024, 0x6F},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) {0x4026, 0xB7},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) {0x4028, 0x5F},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) {0x4074, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) {REG_NULL, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) static __maybe_unused const struct regval imx415_hdr2_10bit_3864x2192_1485M_regs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) {0x3020, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) {0x3021, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) {0x3022, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) {0x3024, 0xFC},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) {0x3025, 0x08},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) {0x3028, 0x1A},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) {0x3029, 0x02},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) {0x302C, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) {0x302D, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) {0x3033, 0x08},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) {0x3050, 0xA8},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) {0x3051, 0x0D},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) {0x3054, 0x09},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) {0x3058, 0x3E},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) {0x3060, 0x4D},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) {0x3064, 0x4a},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) {0x30CF, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) {0x3118, 0xA0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) {0x3260, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) {0x400C, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) {0x4018, 0xA7},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) {0x401A, 0x57},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) {0x401C, 0x5F},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) {0x401E, 0x97},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) {0x401F, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) {0x4020, 0x5F},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) {0x4022, 0xAF},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) {0x4024, 0x5F},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) {0x4026, 0x9F},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) {0x4028, 0x4F},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) {0x4074, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) {REG_NULL, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) static __maybe_unused const struct regval imx415_linear_10bit_3864x2192_891M_regs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) {0x3020, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) {0x3021, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) {0x3022, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) {0x3024, 0xCA},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) {0x3025, 0x08},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) {0x3028, 0x4C},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) {0x3029, 0x04},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) {0x302C, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) {0x302D, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) {0x3033, 0x05},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) {0x3050, 0x08},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) {0x3051, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) {0x3054, 0x19},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) {0x3058, 0x3E},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) {0x3060, 0x25},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) {0x3064, 0x4a},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) {0x30CF, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) {0x3118, 0xC0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) {0x3260, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) {0x400C, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) {0x4018, 0x7F},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) {0x401A, 0x37},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) {0x401C, 0x37},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) {0x401E, 0xF7},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) {0x401F, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) {0x4020, 0x3F},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) {0x4022, 0x6F},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) {0x4024, 0x3F},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) {0x4026, 0x5F},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) {0x4028, 0x2F},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) {0x4074, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) {REG_NULL, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) static __maybe_unused const struct regval imx415_linear_12bit_1932x1096_594M_regs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) {0x3020, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) {0x3021, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) {0x3022, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) {0x3024, 0x5D},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) {0x3025, 0x0C},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) {0x3028, 0x0E},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) {0x3029, 0x03},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) {0x302C, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) {0x302D, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) {0x3031, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) {0x3033, 0x07},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) {0x3050, 0x08},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) {0x3051, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) {0x3054, 0x19},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) {0x3058, 0x3E},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) {0x3060, 0x25},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) {0x3064, 0x4A},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) {0x30CF, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) {0x30D9, 0x02},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) {0x30DA, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) {0x3118, 0x80},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) {0x3260, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) {0x3701, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) {0x400C, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) {0x4018, 0x67},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) {0x401A, 0x27},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) {0x401C, 0x27},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) {0x401E, 0xB7},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) {0x401F, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) {0x4020, 0x2F},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) {0x4022, 0x4F},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) {0x4024, 0x2F},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) {0x4026, 0x47},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) {0x4028, 0x27},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) {0x4074, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) {REG_NULL, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) static __maybe_unused const struct regval imx415_hdr2_12bit_1932x1096_891M_regs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) {0x3020, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) {0x3021, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) {0x3022, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) {0x3024, 0xFC},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) {0x3025, 0x08},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) {0x3028, 0x1A},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) {0x3029, 0x02},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) {0x302C, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) {0x302D, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) {0x3031, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) {0x3033, 0x05},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) {0x3050, 0xB8},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) {0x3051, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) {0x3054, 0x09},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) {0x3058, 0x3E},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) {0x3060, 0x25},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) {0x3064, 0x4A},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) {0x30CF, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) {0x30D9, 0x02},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) {0x30DA, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) {0x3118, 0xC0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) {0x3260, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) {0x3701, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) {0x400C, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) {0x4018, 0xA7},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) {0x401A, 0x57},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) {0x401C, 0x5F},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) {0x401E, 0x97},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) {0x401F, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) {0x4020, 0x5F},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) {0x4022, 0xAF},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) {0x4024, 0x5F},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) {0x4026, 0x9F},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) {0x4028, 0x4F},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) {0x4074, 0x01},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) {REG_NULL, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) * The width and height must be configured to be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) * the same as the current output resolution of the sensor.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) * The input width of the isp needs to be 16 aligned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) * The input height of the isp needs to be 8 aligned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) * If the width or height does not meet the alignment rules,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) * you can configure the cropping parameters with the following function to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) * crop out the appropriate resolution.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) * struct v4l2_subdev_pad_ops {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) * .get_selection
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) * }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) static const struct imx415_mode supported_modes[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) * frame rate = 1 / (Vtt * 1H) = 1 / (VMAX * 1H)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) * VMAX >= (PIX_VWIDTH / 2) + 46 = height + 46
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) .bus_fmt = MEDIA_BUS_FMT_SGBRG10_1X10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) .width = 3864,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) .height = 2192,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) .max_fps = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) .numerator = 10000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) .denominator = 300000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) .exp_def = 0x08ca - 0x08,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) .hts_def = 0x044c * IMX415_4LANES * 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) .vts_def = 0x08ca,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) .global_reg_list = imx415_global_10bit_3864x2192_regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) .reg_list = imx415_linear_10bit_3864x2192_891M_regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) .hdr_mode = NO_HDR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) .mipi_freq_idx = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) .bpp = 10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) .vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) .bus_fmt = MEDIA_BUS_FMT_SGBRG10_1X10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) .width = 3864,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) .height = 2192,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) .max_fps = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) .numerator = 10000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) .denominator = 300000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) .exp_def = 0x08fc * 2 - 0x0da8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) .hts_def = 0x0226 * IMX415_4LANES * 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) * IMX415 HDR mode T-line is half of Linear mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) * make vts double to workaround.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) .vts_def = 0x08fc * 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) .global_reg_list = imx415_global_10bit_3864x2192_regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) .reg_list = imx415_hdr2_10bit_3864x2192_1485M_regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) .hdr_mode = HDR_X2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) .mipi_freq_idx = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) .bpp = 10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) .vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) .vc[PAD1] = V4L2_MBUS_CSI2_CHANNEL_0,//L->csi wr0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) .vc[PAD2] = V4L2_MBUS_CSI2_CHANNEL_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) .vc[PAD3] = V4L2_MBUS_CSI2_CHANNEL_1,//M->csi wr2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) .bus_fmt = MEDIA_BUS_FMT_SGBRG10_1X10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) .width = 3864,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) .height = 2192,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) .max_fps = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) .numerator = 10000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) .denominator = 200000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) .exp_def = 0x13e,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) .hts_def = 0x021A * IMX415_4LANES * 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) * IMX415 HDR mode T-line is half of Linear mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) * make vts double to workaround.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) .vts_def = 0x06BD * 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) .global_reg_list = imx415_global_10bit_3864x2192_regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) .reg_list = imx415_hdr3_10bit_3864x2192_1485M_regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) .hdr_mode = HDR_X3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) .mipi_freq_idx = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) .bpp = 10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) .vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) .vc[PAD1] = V4L2_MBUS_CSI2_CHANNEL_1,//M->csi wr0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) .vc[PAD2] = V4L2_MBUS_CSI2_CHANNEL_0,//L->csi wr0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) .vc[PAD3] = V4L2_MBUS_CSI2_CHANNEL_2,//S->csi wr2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) .bus_fmt = MEDIA_BUS_FMT_SGBRG10_1X10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) .width = 3864,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) .height = 2192,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) .max_fps = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) .numerator = 10000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) .denominator = 200000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) .exp_def = 0x13e,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) .hts_def = 0x01ca * IMX415_4LANES * 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) * IMX415 HDR mode T-line is half of Linear mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) * make vts double to workaround.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) .vts_def = 0x07ea * 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) .global_reg_list = imx415_global_10bit_3864x2192_regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) .reg_list = imx415_hdr3_10bit_3864x2192_1782M_regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) .hdr_mode = HDR_X3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) .mipi_freq_idx = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) .bpp = 10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) .vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) .vc[PAD1] = V4L2_MBUS_CSI2_CHANNEL_1,//M->csi wr0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) .vc[PAD2] = V4L2_MBUS_CSI2_CHANNEL_0,//L->csi wr0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) .vc[PAD3] = V4L2_MBUS_CSI2_CHANNEL_2,//S->csi wr2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) /* 1H period = (1100 clock) = (1100 * 1 / 74.25MHz) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) .bus_fmt = MEDIA_BUS_FMT_SGBRG12_1X12,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) .width = 3864,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) .height = 2192,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) .max_fps = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) .numerator = 10000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) .denominator = 300000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) .exp_def = 0x08ca - 0x08,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) .hts_def = 0x044c * IMX415_4LANES * 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) .vts_def = 0x08ca,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) .global_reg_list = imx415_global_12bit_3864x2192_regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) .reg_list = imx415_linear_12bit_3864x2192_891M_regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) .hdr_mode = NO_HDR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) .mipi_freq_idx = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) .bpp = 12,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) .vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0,
^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) .bus_fmt = MEDIA_BUS_FMT_SGBRG12_1X12,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) .width = 3864,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) .height = 2192,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) .max_fps = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) .numerator = 10000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) .denominator = 300000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) .exp_def = 0x08CA * 2 - 0x0d90,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) .hts_def = 0x0226 * IMX415_4LANES * 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) * IMX415 HDR mode T-line is half of Linear mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) * make vts double(that is FSC) to workaround.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) .vts_def = 0x08CA * 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) .global_reg_list = imx415_global_12bit_3864x2192_regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) .reg_list = imx415_hdr2_12bit_3864x2192_1782M_regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) .hdr_mode = HDR_X2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) .mipi_freq_idx = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) .bpp = 12,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) .vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) .vc[PAD1] = V4L2_MBUS_CSI2_CHANNEL_0,//L->csi wr0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) .vc[PAD2] = V4L2_MBUS_CSI2_CHANNEL_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) .vc[PAD3] = V4L2_MBUS_CSI2_CHANNEL_1,//M->csi wr2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) .bus_fmt = MEDIA_BUS_FMT_SGBRG12_1X12,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) .width = 3864,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) .height = 2192,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) .max_fps = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) .numerator = 10000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) .denominator = 200000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) .exp_def = 0x114,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) .hts_def = 0x0226 * IMX415_4LANES * 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) * IMX415 HDR mode T-line is half of Linear mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) * make vts double(that is FSC) to workaround.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) .vts_def = 0x0696 * 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) .global_reg_list = imx415_global_12bit_3864x2192_regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) .reg_list = imx415_hdr3_12bit_3864x2192_1782M_regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) .hdr_mode = HDR_X3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) .mipi_freq_idx = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) .bpp = 12,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) .vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) .vc[PAD1] = V4L2_MBUS_CSI2_CHANNEL_1,//M->csi wr0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) .vc[PAD2] = V4L2_MBUS_CSI2_CHANNEL_0,//L->csi wr0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) .vc[PAD3] = V4L2_MBUS_CSI2_CHANNEL_2,//S->csi wr2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) .bus_fmt = MEDIA_BUS_FMT_SGBRG12_1X12,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) .width = 1944,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) .height = 1097,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) .max_fps = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) .numerator = 10000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) .denominator = 300000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) .exp_def = 0x05dc - 0x08,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) .hts_def = 0x030e * 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) .vts_def = 0x0c5d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) .global_reg_list = imx415_global_12bit_3864x2192_regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) .reg_list = imx415_linear_12bit_1932x1096_594M_regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) .hdr_mode = NO_HDR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) .mipi_freq_idx = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) .bpp = 12,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) .vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) .bus_fmt = MEDIA_BUS_FMT_SGBRG12_1X12,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) .width = 1944,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) .height = 1097,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) .max_fps = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) .numerator = 10000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) .denominator = 300000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) .exp_def = 0x08FC / 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) .hts_def = 0x021A * 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) * IMX415 HDR mode T-line is half of Linear mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) * make vts double(that is FSC) to workaround.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) .vts_def = 0x08FC * 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) .global_reg_list = imx415_global_12bit_3864x2192_regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) .reg_list = imx415_hdr2_12bit_1932x1096_891M_regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) .hdr_mode = HDR_X2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) .mipi_freq_idx = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) .bpp = 12,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) .vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) .vc[PAD1] = V4L2_MBUS_CSI2_CHANNEL_0,//L->csi wr0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) .vc[PAD2] = V4L2_MBUS_CSI2_CHANNEL_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) .vc[PAD3] = V4L2_MBUS_CSI2_CHANNEL_1,//M->csi wr2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) static const s64 link_freq_items[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) MIPI_FREQ_297M,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) MIPI_FREQ_446M,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) MIPI_FREQ_743M,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) MIPI_FREQ_891M,
^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) /* Write registers up to 4 at a time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) static int imx415_write_reg(struct i2c_client *client, u16 reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) u32 len, u32 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) u32 buf_i, val_i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) u8 buf[6];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) u8 *val_p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) __be32 val_be;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) if (len > 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) buf[0] = reg >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) buf[1] = reg & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) val_be = cpu_to_be32(val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) val_p = (u8 *)&val_be;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) buf_i = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) val_i = 4 - len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) while (val_i < 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) buf[buf_i++] = val_p[val_i++];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) if (i2c_master_send(client, buf, len + 2) != len + 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) return -EIO;
^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 imx415_write_array(struct i2c_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) const struct regval *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) u32 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) for (i = 0; ret == 0 && regs[i].addr != REG_NULL; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) ret = imx415_write_reg(client, regs[i].addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) IMX415_REG_VALUE_08BIT, regs[i].val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) /* Read registers up to 4 at a time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) static int imx415_read_reg(struct i2c_client *client, u16 reg, unsigned int len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) u32 *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) struct i2c_msg msgs[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) u8 *data_be_p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) __be32 data_be = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) __be16 reg_addr_be = cpu_to_be16(reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) if (len > 4 || !len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) data_be_p = (u8 *)&data_be;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) /* Write register address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) msgs[0].addr = client->addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) msgs[0].flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) msgs[0].len = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) msgs[0].buf = (u8 *)®_addr_be;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) /* Read data from register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) msgs[1].addr = client->addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) msgs[1].flags = I2C_M_RD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) msgs[1].len = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) msgs[1].buf = &data_be_p[4 - len];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) if (ret != ARRAY_SIZE(msgs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) *val = be32_to_cpu(data_be);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) static int imx415_get_reso_dist(const struct imx415_mode *mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) struct v4l2_mbus_framefmt *framefmt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) return abs(mode->width - framefmt->width) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) abs(mode->height - framefmt->height);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) static const struct imx415_mode *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) imx415_find_best_fit(struct imx415 *imx415, struct v4l2_subdev_format *fmt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) struct v4l2_mbus_framefmt *framefmt = &fmt->format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) int dist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) int cur_best_fit = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) int cur_best_fit_dist = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) for (i = 0; i < imx415->cfg_num; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) dist = imx415_get_reso_dist(&supported_modes[i], framefmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) if ((cur_best_fit_dist == -1 || dist < cur_best_fit_dist) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) supported_modes[i].bus_fmt == framefmt->code) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) cur_best_fit_dist = dist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) cur_best_fit = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) dev_info(&imx415->client->dev, "%s: cur_best_fit(%d)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) __func__, cur_best_fit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) return &supported_modes[cur_best_fit];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) static int __imx415_power_on(struct imx415 *imx415);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) static void imx415_change_mode(struct imx415 *imx415, const struct imx415_mode *mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) if (imx415->is_thunderboot && rkisp_tb_get_state() == RKISP_TB_NG) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) imx415->is_thunderboot = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) imx415->is_thunderboot_ng = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) __imx415_power_on(imx415);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) imx415->cur_mode = mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) imx415->cur_vts = imx415->cur_mode->vts_def;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) dev_dbg(&imx415->client->dev, "set fmt: cur_mode: %dx%d, hdr: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) mode->width, mode->height, mode->hdr_mode);
^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) static int imx415_set_fmt(struct v4l2_subdev *sd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) struct v4l2_subdev_pad_config *cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) struct v4l2_subdev_format *fmt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) struct imx415 *imx415 = to_imx415(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) const struct imx415_mode *mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) s64 h_blank, vblank_def, vblank_min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) u64 pixel_rate = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) mutex_lock(&imx415->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) mode = imx415_find_best_fit(imx415, fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) fmt->format.code = mode->bus_fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) fmt->format.width = mode->width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) fmt->format.height = mode->height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) fmt->format.field = V4L2_FIELD_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) *v4l2_subdev_get_try_format(sd, cfg, fmt->pad) = fmt->format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) mutex_unlock(&imx415->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) return -ENOTTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) imx415_change_mode(imx415, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) h_blank = mode->hts_def - mode->width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) __v4l2_ctrl_modify_range(imx415->hblank, h_blank,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) h_blank, 1, h_blank);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) vblank_def = mode->vts_def - mode->height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) /* VMAX >= (PIX_VWIDTH / 2) + 46 = height + 46 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) vblank_min = (mode->height + 46) - mode->height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) __v4l2_ctrl_modify_range(imx415->vblank, vblank_min,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) IMX415_VTS_MAX - mode->height,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) 1, vblank_def);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) __v4l2_ctrl_s_ctrl(imx415->vblank, vblank_def);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) __v4l2_ctrl_s_ctrl(imx415->link_freq, mode->mipi_freq_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) pixel_rate = (u32)link_freq_items[mode->mipi_freq_idx] / mode->bpp * 2 * IMX415_4LANES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) __v4l2_ctrl_s_ctrl_int64(imx415->pixel_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) pixel_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) dev_info(&imx415->client->dev, "%s: mode->mipi_freq_idx(%d)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) __func__, mode->mipi_freq_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) mutex_unlock(&imx415->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) static int imx415_get_fmt(struct v4l2_subdev *sd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) struct v4l2_subdev_pad_config *cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) struct v4l2_subdev_format *fmt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) struct imx415 *imx415 = to_imx415(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) const struct imx415_mode *mode = imx415->cur_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) mutex_lock(&imx415->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) fmt->format = *v4l2_subdev_get_try_format(sd, cfg, fmt->pad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) mutex_unlock(&imx415->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) return -ENOTTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) fmt->format.width = mode->width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) fmt->format.height = mode->height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) fmt->format.code = mode->bus_fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) fmt->format.field = V4L2_FIELD_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) if (fmt->pad < PAD_MAX && mode->hdr_mode != NO_HDR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) fmt->reserved[0] = mode->vc[fmt->pad];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) fmt->reserved[0] = mode->vc[PAD0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) mutex_unlock(&imx415->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175)
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) static int imx415_enum_mbus_code(struct v4l2_subdev *sd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) struct v4l2_subdev_pad_config *cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) struct v4l2_subdev_mbus_code_enum *code)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) struct imx415 *imx415 = to_imx415(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) if (code->index >= imx415->cfg_num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) code->code = supported_modes[code->index].bus_fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) static int imx415_enum_frame_sizes(struct v4l2_subdev *sd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) struct v4l2_subdev_pad_config *cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) struct v4l2_subdev_frame_size_enum *fse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) struct imx415 *imx415 = to_imx415(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) if (fse->index >= imx415->cfg_num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) if (fse->code != supported_modes[fse->index].bus_fmt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) fse->min_width = supported_modes[fse->index].width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) fse->max_width = supported_modes[fse->index].width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) fse->max_height = supported_modes[fse->index].height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) fse->min_height = supported_modes[fse->index].height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) static int imx415_g_frame_interval(struct v4l2_subdev *sd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) struct v4l2_subdev_frame_interval *fi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) struct imx415 *imx415 = to_imx415(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) const struct imx415_mode *mode = imx415->cur_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) mutex_lock(&imx415->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) fi->interval = mode->max_fps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) mutex_unlock(&imx415->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) static int imx415_g_mbus_config(struct v4l2_subdev *sd, unsigned int pad_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) struct v4l2_mbus_config *config)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) struct imx415 *imx415 = to_imx415(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) const struct imx415_mode *mode = imx415->cur_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) u32 val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) val = 1 << (IMX415_4LANES - 1) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) V4L2_MBUS_CSI2_CHANNEL_0 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) if (mode->hdr_mode != NO_HDR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) val |= V4L2_MBUS_CSI2_CHANNEL_1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) if (mode->hdr_mode == HDR_X3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) val |= V4L2_MBUS_CSI2_CHANNEL_2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) config->type = V4L2_MBUS_CSI2_DPHY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) config->flags = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) static void imx415_get_module_inf(struct imx415 *imx415,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) struct rkmodule_inf *inf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) memset(inf, 0, sizeof(*inf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) strlcpy(inf->base.sensor, IMX415_NAME, sizeof(inf->base.sensor));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) strlcpy(inf->base.module, imx415->module_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) sizeof(inf->base.module));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) strlcpy(inf->base.lens, imx415->len_name, sizeof(inf->base.lens));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) static int imx415_set_hdrae_3frame(struct imx415 *imx415,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) struct preisp_hdrae_exp_s *ae)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) struct i2c_client *client = imx415->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) u32 l_exp_time, m_exp_time, s_exp_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) u32 l_a_gain, m_a_gain, s_a_gain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) int shr2, shr1, shr0, rhs2, rhs1 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) int rhs1_change_limit, rhs2_change_limit = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) static int rhs1_old = IMX415_RHS1_DEFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) static int rhs2_old = IMX415_RHS2_DEFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) u32 fsc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) int rhs1_max = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) int shr2_min = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) if (!imx415->has_init_exp && !imx415->streaming) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) imx415->init_hdrae_exp = *ae;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) imx415->has_init_exp = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) dev_dbg(&imx415->client->dev, "imx415 is not streaming, save hdr ae!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) l_exp_time = ae->long_exp_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) m_exp_time = ae->middle_exp_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) s_exp_time = ae->short_exp_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) l_a_gain = ae->long_gain_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) m_a_gain = ae->middle_gain_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) s_a_gain = ae->short_gain_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) dev_dbg(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) "rev exp req: L_exp: 0x%x, 0x%x, M_exp: 0x%x, 0x%x S_exp: 0x%x, 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) l_exp_time, m_exp_time, s_exp_time,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) l_a_gain, m_a_gain, s_a_gain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) ret = imx415_write_reg(client, IMX415_GROUP_HOLD_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) IMX415_REG_VALUE_08BIT, IMX415_GROUP_HOLD_START);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) /* gain effect n+1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) ret |= imx415_write_reg(client, IMX415_LF_GAIN_REG_H,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) IMX415_REG_VALUE_08BIT, IMX415_FETCH_GAIN_H(l_a_gain));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) ret |= imx415_write_reg(client, IMX415_LF_GAIN_REG_L,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) IMX415_REG_VALUE_08BIT, IMX415_FETCH_GAIN_L(l_a_gain));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) ret |= imx415_write_reg(client, IMX415_SF1_GAIN_REG_H,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) IMX415_REG_VALUE_08BIT, IMX415_FETCH_GAIN_H(m_a_gain));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) ret |= imx415_write_reg(client, IMX415_SF1_GAIN_REG_L,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) IMX415_REG_VALUE_08BIT, IMX415_FETCH_GAIN_L(m_a_gain));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) ret |= imx415_write_reg(client, IMX415_SF2_GAIN_REG_H,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) IMX415_REG_VALUE_08BIT, IMX415_FETCH_GAIN_H(s_a_gain));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) ret |= imx415_write_reg(client, IMX415_SF2_GAIN_REG_L,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) IMX415_REG_VALUE_08BIT, IMX415_FETCH_GAIN_L(s_a_gain));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) /* Restrictions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) * FSC = 4 * VMAX and FSC should be 6n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) * exp_l = FSC - SHR0 + Toffset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) * SHR0 = FSC - exp_l + Toffset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) * SHR0 <= (FSC -12);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) * SHR0 >= RHS2 + 13;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) * SHR0 should be 3n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) * exp_m = RHS1 - SHR1 + Toffset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) * RHS1 < BRL * 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) * RHS1 <= SHR2 - 13;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) * RHS1 >= SHR1 + 12;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) * SHR1 >= 13;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) * SHR1 <= RHS1 - 12;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) * RHS1(n+1) >= RHS1(n) + BRL * 3 -FSC + 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) * SHR1 should be 3n+1 and RHS1 should be 6n+1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) * exp_s = RHS2 - SHR2 + Toffset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) * RHS2 < BRL * 3 + RHS1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) * RHS2 <= SHR0 - 13;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) * RHS2 >= SHR2 + 12;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) * SHR2 >= RHS1 + 13;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) * SHR2 <= RHS2 - 12;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) * RHS1(n+1) >= RHS1(n) + BRL * 3 -FSC + 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) * SHR2 should be 3n+2 and RHS2 should be 6n+2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) /* The HDR mode vts is double by default to workaround T-line */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) fsc = imx415->cur_vts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) fsc = fsc / 6 * 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) shr0 = fsc - l_exp_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) dev_dbg(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) "line(%d) shr0 %d, l_exp_time %d, fsc %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) __LINE__, shr0, l_exp_time, fsc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) rhs1 = (SHR1_MIN_X3 + m_exp_time + 5) / 6 * 6 + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) if (imx415->cur_mode->height == 2192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) rhs1_max = RHS1_MAX_X3(BRL_ALL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) rhs1_max = RHS1_MAX_X3(BRL_BINNING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) if (rhs1 < 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) rhs1 = 25;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) else if (rhs1 > rhs1_max)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) rhs1 = rhs1_max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) dev_dbg(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) "line(%d) rhs1 %d, m_exp_time %d rhs1_old %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) __LINE__, rhs1, m_exp_time, rhs1_old);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) //Dynamic adjustment rhs2 must meet the following conditions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) if (imx415->cur_mode->height == 2192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) rhs1_change_limit = rhs1_old + 3 * BRL_ALL - fsc + 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) rhs1_change_limit = rhs1_old + 3 * BRL_BINNING - fsc + 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) rhs1_change_limit = (rhs1_change_limit < 25) ? 25 : rhs1_change_limit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) rhs1_change_limit = (rhs1_change_limit + 5) / 6 * 6 + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) if (rhs1_max < rhs1_change_limit) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) dev_err(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) "The total exposure limit makes rhs1 max is %d,but old rhs1 limit makes rhs1 min is %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) rhs1_max, rhs1_change_limit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) if (rhs1 < rhs1_change_limit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) rhs1 = rhs1_change_limit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) dev_dbg(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) "line(%d) m_exp_time %d rhs1_old %d, rhs1_new %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) __LINE__, m_exp_time, rhs1_old, rhs1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) rhs1_old = rhs1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) /* shr1 = rhs1 - s_exp_time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) if (rhs1 - m_exp_time <= SHR1_MIN_X3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) shr1 = SHR1_MIN_X3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) m_exp_time = rhs1 - shr1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) shr1 = rhs1 - m_exp_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) shr2_min = rhs1 + 13;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) rhs2 = (shr2_min + s_exp_time + 5) / 6 * 6 + 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) if (rhs2 > (shr0 - 13))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) rhs2 = shr0 - 13;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) else if (rhs2 < 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) rhs2 = 50;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) dev_dbg(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) "line(%d) rhs2 %d, s_exp_time %d, rhs2_old %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) __LINE__, rhs2, s_exp_time, rhs2_old);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) //Dynamic adjustment rhs2 must meet the following conditions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) if (imx415->cur_mode->height == 2192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) rhs2_change_limit = rhs2_old + 3 * BRL_ALL - fsc + 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) rhs2_change_limit = rhs2_old + 3 * BRL_BINNING - fsc + 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) rhs2_change_limit = (rhs2_change_limit < 50) ? 50 : rhs2_change_limit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) rhs2_change_limit = (rhs2_change_limit + 5) / 6 * 6 + 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) if ((shr0 - 13) < rhs2_change_limit) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) dev_err(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) "The total exposure limit makes rhs2 max is %d,but old rhs1 limit makes rhs2 min is %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) shr0 - 13, rhs2_change_limit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) if (rhs2 < rhs2_change_limit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) rhs2 = rhs2_change_limit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) rhs2_old = rhs2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) /* shr2 = rhs2 - s_exp_time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) if (rhs2 - s_exp_time <= shr2_min) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) shr2 = shr2_min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) s_exp_time = rhs2 - shr2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) shr2 = rhs2 - s_exp_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) dev_dbg(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) "line(%d) rhs2_new %d, s_exp_time %d shr2 %d, rhs2_change_limit %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) __LINE__, rhs2, s_exp_time, shr2, rhs2_change_limit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) if (shr0 < rhs2 + 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) shr0 = rhs2 + 13;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) else if (shr0 > fsc - 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) shr0 = fsc - 12;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) dev_dbg(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) "long exposure: l_exp_time=%d, fsc=%d, shr0=%d, l_a_gain=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) l_exp_time, fsc, shr0, l_a_gain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) dev_dbg(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) "middle exposure(SEF1): m_exp_time=%d, rhs1=%d, shr1=%d, m_a_gain=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) m_exp_time, rhs1, shr1, m_a_gain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) dev_dbg(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) "short exposure(SEF2): s_exp_time=%d, rhs2=%d, shr2=%d, s_a_gain=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) s_exp_time, rhs2, shr2, s_a_gain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) /* time effect n+1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) /* write SEF2 exposure RHS2 regs*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) ret |= imx415_write_reg(client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) IMX415_RHS2_REG_L,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) IMX415_REG_VALUE_08BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) IMX415_FETCH_RHS1_L(rhs2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) ret |= imx415_write_reg(client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) IMX415_RHS2_REG_M,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) IMX415_REG_VALUE_08BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) IMX415_FETCH_RHS1_M(rhs2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) ret |= imx415_write_reg(client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) IMX415_RHS2_REG_H,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) IMX415_REG_VALUE_08BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) IMX415_FETCH_RHS1_H(rhs2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) /* write SEF2 exposure SHR2 regs*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) ret |= imx415_write_reg(client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) IMX415_SF2_EXPO_REG_L,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) IMX415_REG_VALUE_08BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) IMX415_FETCH_EXP_L(shr2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) ret |= imx415_write_reg(client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) IMX415_SF2_EXPO_REG_M,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) IMX415_REG_VALUE_08BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) IMX415_FETCH_EXP_M(shr2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) ret |= imx415_write_reg(client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) IMX415_SF2_EXPO_REG_H,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) IMX415_REG_VALUE_08BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) IMX415_FETCH_EXP_H(shr2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) /* write SEF1 exposure RHS1 regs*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) ret |= imx415_write_reg(client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) IMX415_RHS1_REG_L,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) IMX415_REG_VALUE_08BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) IMX415_FETCH_RHS1_L(rhs1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) ret |= imx415_write_reg(client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) IMX415_RHS1_REG_M,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) IMX415_REG_VALUE_08BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) IMX415_FETCH_RHS1_M(rhs1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) ret |= imx415_write_reg(client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) IMX415_RHS1_REG_H,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) IMX415_REG_VALUE_08BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) IMX415_FETCH_RHS1_H(rhs1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) /* write SEF1 exposure SHR1 regs*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) ret |= imx415_write_reg(client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) IMX415_SF1_EXPO_REG_L,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) IMX415_REG_VALUE_08BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) IMX415_FETCH_EXP_L(shr1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) ret |= imx415_write_reg(client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) IMX415_SF1_EXPO_REG_M,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) IMX415_REG_VALUE_08BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) IMX415_FETCH_EXP_M(shr1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) ret |= imx415_write_reg(client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) IMX415_SF1_EXPO_REG_H,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) IMX415_REG_VALUE_08BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) IMX415_FETCH_EXP_H(shr1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) /* write LF exposure SHR0 regs*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) ret |= imx415_write_reg(client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) IMX415_LF_EXPO_REG_L,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) IMX415_REG_VALUE_08BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) IMX415_FETCH_EXP_L(shr0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) ret |= imx415_write_reg(client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) IMX415_LF_EXPO_REG_M,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) IMX415_REG_VALUE_08BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) IMX415_FETCH_EXP_M(shr0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) ret |= imx415_write_reg(client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) IMX415_LF_EXPO_REG_H,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) IMX415_REG_VALUE_08BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) IMX415_FETCH_EXP_H(shr0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) ret |= imx415_write_reg(client, IMX415_GROUP_HOLD_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) IMX415_REG_VALUE_08BIT, IMX415_GROUP_HOLD_END);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) static int imx415_set_hdrae(struct imx415 *imx415,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) struct preisp_hdrae_exp_s *ae)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) struct i2c_client *client = imx415->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) u32 l_exp_time, m_exp_time, s_exp_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) u32 l_a_gain, m_a_gain, s_a_gain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) int shr1, shr0, rhs1, rhs1_max, rhs1_min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) static int rhs1_old = IMX415_RHS1_DEFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) u32 fsc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) if (!imx415->has_init_exp && !imx415->streaming) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) imx415->init_hdrae_exp = *ae;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) imx415->has_init_exp = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) dev_dbg(&imx415->client->dev, "imx415 is not streaming, save hdr ae!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) l_exp_time = ae->long_exp_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) m_exp_time = ae->middle_exp_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) s_exp_time = ae->short_exp_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) l_a_gain = ae->long_gain_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) m_a_gain = ae->middle_gain_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) s_a_gain = ae->short_gain_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) dev_dbg(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) "rev exp req: L_exp: 0x%x, 0x%x, M_exp: 0x%x, 0x%x S_exp: 0x%x, 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) l_exp_time, m_exp_time, s_exp_time,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) l_a_gain, m_a_gain, s_a_gain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) if (imx415->cur_mode->hdr_mode == HDR_X2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) l_a_gain = m_a_gain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) l_exp_time = m_exp_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) ret = imx415_write_reg(client, IMX415_GROUP_HOLD_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) IMX415_REG_VALUE_08BIT, IMX415_GROUP_HOLD_START);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) /* gain effect n+1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) ret |= imx415_write_reg(client, IMX415_LF_GAIN_REG_H,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) IMX415_REG_VALUE_08BIT, IMX415_FETCH_GAIN_H(l_a_gain));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) ret |= imx415_write_reg(client, IMX415_LF_GAIN_REG_L,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) IMX415_REG_VALUE_08BIT, IMX415_FETCH_GAIN_L(l_a_gain));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) ret |= imx415_write_reg(client, IMX415_SF1_GAIN_REG_H,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) IMX415_REG_VALUE_08BIT, IMX415_FETCH_GAIN_H(s_a_gain));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) ret |= imx415_write_reg(client, IMX415_SF1_GAIN_REG_L,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) IMX415_REG_VALUE_08BIT, IMX415_FETCH_GAIN_L(s_a_gain));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) /* Restrictions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) * FSC = 2 * VMAX and FSC should be 4n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) * exp_l = FSC - SHR0 + Toffset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) * exp_l should be even value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) * SHR0 = FSC - exp_l + Toffset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) * SHR0 <= (FSC -8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) * SHR0 >= RHS1 + 9;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) * SHR0 should be 2n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) * exp_s = RHS1 - SHR1 + Toffset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) * exp_s should be even value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) * RHS1 < BRL * 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) * RHS1 <= SHR0 - 9;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) * RHS1 >= SHR1 + 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) * SHR1 >= 9;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) * RHS1(n+1) >= RHS1(n) + BRL * 2 -FSC + 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) * SHR1 should be 2n+1 and RHS1 should be 4n+1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) /* The HDR mode vts is double by default to workaround T-line */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) fsc = imx415->cur_vts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) shr0 = fsc - l_exp_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) if (imx415->cur_mode->height == 2192) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) rhs1_max = min(RHS1_MAX_X2(BRL_ALL), ((shr0 - 9u) / 4 * 4 + 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) rhs1_min = max(SHR1_MIN_X2 + 8u, rhs1_old + 2 * BRL_ALL - fsc + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) rhs1_max = min(RHS1_MAX_X2(BRL_BINNING), ((shr0 - 9u) / 4 * 4 + 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) rhs1_min = max(SHR1_MIN_X2 + 8u, rhs1_old + 2 * BRL_BINNING - fsc + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) rhs1_min = (rhs1_min + 3) / 4 * 4 + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) rhs1 = (SHR1_MIN_X2 + s_exp_time + 3) / 4 * 4 + 1;/* shall be 4n + 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) dev_dbg(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) "line(%d) rhs1 %d, rhs1 min %d rhs1 max %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) __LINE__, rhs1, rhs1_min, rhs1_max);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) if (rhs1_max < rhs1_min) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) dev_err(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) "The total exposure limit makes rhs1 max is %d,but old rhs1 limit makes rhs1 min is %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) rhs1_max, rhs1_min);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) rhs1 = clamp(rhs1, rhs1_min, rhs1_max);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) dev_dbg(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) "line(%d) rhs1 %d, short time %d rhs1_old %d, rhs1_new %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) __LINE__, rhs1, s_exp_time, rhs1_old, rhs1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) rhs1_old = rhs1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) /* shr1 = rhs1 - s_exp_time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) if (rhs1 - s_exp_time <= SHR1_MIN_X2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) shr1 = SHR1_MIN_X2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) s_exp_time = rhs1 - shr1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) shr1 = rhs1 - s_exp_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) if (shr0 < rhs1 + 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) shr0 = rhs1 + 9;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) else if (shr0 > fsc - 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) shr0 = fsc - 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) dev_dbg(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) "fsc=%d,RHS1_MAX=%d,SHR1_MIN=%d,rhs1_max=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) fsc, RHS1_MAX_X2(BRL_ALL), SHR1_MIN_X2, rhs1_max);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) dev_dbg(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) "l_exp_time=%d,s_exp_time=%d,shr0=%d,shr1=%d,rhs1=%d,l_a_gain=%d,s_a_gain=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) l_exp_time, s_exp_time, shr0, shr1, rhs1, l_a_gain, s_a_gain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) /* time effect n+2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) ret |= imx415_write_reg(client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) IMX415_RHS1_REG_L,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) IMX415_REG_VALUE_08BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) IMX415_FETCH_RHS1_L(rhs1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) ret |= imx415_write_reg(client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) IMX415_RHS1_REG_M,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) IMX415_REG_VALUE_08BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) IMX415_FETCH_RHS1_M(rhs1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) ret |= imx415_write_reg(client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) IMX415_RHS1_REG_H,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) IMX415_REG_VALUE_08BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) IMX415_FETCH_RHS1_H(rhs1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) ret |= imx415_write_reg(client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) IMX415_SF1_EXPO_REG_L,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) IMX415_REG_VALUE_08BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) IMX415_FETCH_EXP_L(shr1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) ret |= imx415_write_reg(client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) IMX415_SF1_EXPO_REG_M,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) IMX415_REG_VALUE_08BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) IMX415_FETCH_EXP_M(shr1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) ret |= imx415_write_reg(client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) IMX415_SF1_EXPO_REG_H,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) IMX415_REG_VALUE_08BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) IMX415_FETCH_EXP_H(shr1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) ret |= imx415_write_reg(client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) IMX415_LF_EXPO_REG_L,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) IMX415_REG_VALUE_08BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) IMX415_FETCH_EXP_L(shr0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) ret |= imx415_write_reg(client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) IMX415_LF_EXPO_REG_M,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) IMX415_REG_VALUE_08BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) IMX415_FETCH_EXP_M(shr0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) ret |= imx415_write_reg(client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) IMX415_LF_EXPO_REG_H,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) IMX415_REG_VALUE_08BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) IMX415_FETCH_EXP_H(shr0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) ret |= imx415_write_reg(client, IMX415_GROUP_HOLD_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) IMX415_REG_VALUE_08BIT, IMX415_GROUP_HOLD_END);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) return ret;
^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) static int imx415_get_channel_info(struct imx415 *imx415, struct rkmodule_channel_info *ch_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) if (ch_info->index < PAD0 || ch_info->index >= PAD_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) ch_info->vc = imx415->cur_mode->vc[ch_info->index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) ch_info->width = imx415->cur_mode->width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) ch_info->height = imx415->cur_mode->height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) ch_info->bus_fmt = imx415->cur_mode->bus_fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) static long imx415_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) struct imx415 *imx415 = to_imx415(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) struct rkmodule_hdr_cfg *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) struct rkmodule_channel_info *ch_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) u32 i, h, w, stream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) long ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) const struct imx415_mode *mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) u64 pixel_rate = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) struct rkmodule_csi_dphy_param *dphy_param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) case PREISP_CMD_SET_HDRAE_EXP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) if (imx415->cur_mode->hdr_mode == HDR_X2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) ret = imx415_set_hdrae(imx415, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) else if (imx415->cur_mode->hdr_mode == HDR_X3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) ret = imx415_set_hdrae_3frame(imx415, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) case RKMODULE_GET_MODULE_INFO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) imx415_get_module_inf(imx415, (struct rkmodule_inf *)arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) case RKMODULE_GET_HDR_CFG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) hdr = (struct rkmodule_hdr_cfg *)arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) hdr->esp.mode = HDR_NORMAL_VC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) hdr->hdr_mode = imx415->cur_mode->hdr_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) case RKMODULE_SET_HDR_CFG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) hdr = (struct rkmodule_hdr_cfg *)arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) w = imx415->cur_mode->width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) h = imx415->cur_mode->height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) for (i = 0; i < imx415->cfg_num; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) if (w == supported_modes[i].width &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) h == supported_modes[i].height &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) supported_modes[i].hdr_mode == hdr->hdr_mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) imx415_change_mode(imx415, &supported_modes[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) if (i == imx415->cfg_num) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) dev_err(&imx415->client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) "not find hdr mode:%d %dx%d config\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) hdr->hdr_mode, w, h);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) mode = imx415->cur_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) if (imx415->streaming) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) ret = imx415_write_reg(imx415->client, IMX415_GROUP_HOLD_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) IMX415_REG_VALUE_08BIT, IMX415_GROUP_HOLD_START);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) ret |= imx415_write_array(imx415->client, imx415->cur_mode->reg_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) ret |= imx415_write_reg(imx415->client, IMX415_GROUP_HOLD_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) IMX415_REG_VALUE_08BIT, IMX415_GROUP_HOLD_END);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) w = mode->hts_def - imx415->cur_mode->width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) h = mode->vts_def - mode->height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) mutex_lock(&imx415->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) __v4l2_ctrl_modify_range(imx415->hblank, w, w, 1, w);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) __v4l2_ctrl_modify_range(imx415->vblank, h,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) IMX415_VTS_MAX - mode->height,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) 1, h);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) __v4l2_ctrl_s_ctrl(imx415->link_freq, mode->mipi_freq_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) pixel_rate = (u32)link_freq_items[mode->mipi_freq_idx] / mode->bpp * 2 * IMX415_4LANES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) __v4l2_ctrl_s_ctrl_int64(imx415->pixel_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) pixel_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) mutex_unlock(&imx415->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) case RKMODULE_SET_QUICK_STREAM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) stream = *((u32 *)arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) if (stream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) ret = imx415_write_reg(imx415->client, IMX415_REG_CTRL_MODE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) IMX415_REG_VALUE_08BIT, IMX415_MODE_STREAMING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) ret = imx415_write_reg(imx415->client, IMX415_REG_CTRL_MODE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) IMX415_REG_VALUE_08BIT, IMX415_MODE_SW_STANDBY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) case RKMODULE_GET_SONY_BRL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) if (imx415->cur_mode->width == 3864 && imx415->cur_mode->height == 2192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) *((u32 *)arg) = BRL_ALL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) *((u32 *)arg) = BRL_BINNING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) case RKMODULE_GET_CHANNEL_INFO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) ch_info = (struct rkmodule_channel_info *)arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) ret = imx415_get_channel_info(imx415, ch_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) case RKMODULE_GET_CSI_DPHY_PARAM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) if (imx415->cur_mode->hdr_mode == HDR_X2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) dphy_param = (struct rkmodule_csi_dphy_param *)arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) if (dphy_param->vendor == dcphy_param.vendor)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) *dphy_param = dcphy_param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) dev_info(&imx415->client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) "get sensor dphy param\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) ret = -ENOIOCTLCMD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) #ifdef CONFIG_COMPAT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) static long imx415_compat_ioctl32(struct v4l2_subdev *sd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) unsigned int cmd, unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) void __user *up = compat_ptr(arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) struct rkmodule_inf *inf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) struct rkmodule_awb_cfg *cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) struct rkmodule_hdr_cfg *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) struct preisp_hdrae_exp_s *hdrae;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) struct rkmodule_channel_info *ch_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) long ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) u32 stream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) u32 brl = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) struct rkmodule_csi_dphy_param *dphy_param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) case RKMODULE_GET_MODULE_INFO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) inf = kzalloc(sizeof(*inf), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) if (!inf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) ret = imx415_ioctl(sd, cmd, inf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) if (!ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) if (copy_to_user(up, inf, sizeof(*inf))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) kfree(inf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) kfree(inf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) case RKMODULE_AWB_CFG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) cfg = kzalloc(sizeof(*cfg), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) if (!cfg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) ret = -ENOMEM;
^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) if (copy_from_user(cfg, up, sizeof(*cfg))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) kfree(cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) ret = imx415_ioctl(sd, cmd, cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) kfree(cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) case RKMODULE_GET_HDR_CFG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) hdr = kzalloc(sizeof(*hdr), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) if (!hdr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) ret = imx415_ioctl(sd, cmd, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) if (!ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) if (copy_to_user(up, hdr, sizeof(*hdr))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) kfree(hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) kfree(hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) case RKMODULE_SET_HDR_CFG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) hdr = kzalloc(sizeof(*hdr), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) if (!hdr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) return ret;
^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) if (copy_from_user(hdr, up, sizeof(*hdr))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) kfree(hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) ret = imx415_ioctl(sd, cmd, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) kfree(hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) case PREISP_CMD_SET_HDRAE_EXP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) hdrae = kzalloc(sizeof(*hdrae), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) if (!hdrae) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) if (copy_from_user(hdrae, up, sizeof(*hdrae))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) kfree(hdrae);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) ret = imx415_ioctl(sd, cmd, hdrae);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) kfree(hdrae);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) case RKMODULE_SET_QUICK_STREAM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) if (copy_from_user(&stream, up, sizeof(u32)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) ret = imx415_ioctl(sd, cmd, &stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) case RKMODULE_GET_SONY_BRL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) ret = imx415_ioctl(sd, cmd, &brl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) if (!ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) if (copy_to_user(up, &brl, sizeof(u32)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) case RKMODULE_GET_CHANNEL_INFO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) ch_info = kzalloc(sizeof(*ch_info), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) if (!ch_info) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) ret = imx415_ioctl(sd, cmd, ch_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) if (!ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) ret = copy_to_user(up, ch_info, sizeof(*ch_info));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) ret = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) kfree(ch_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) case RKMODULE_GET_CSI_DPHY_PARAM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) dphy_param = kzalloc(sizeof(*dphy_param), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) if (!dphy_param) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) ret = imx415_ioctl(sd, cmd, dphy_param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) if (!ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) ret = copy_to_user(up, dphy_param, sizeof(*dphy_param));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) ret = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) kfree(dphy_param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) ret = -ENOIOCTLCMD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) static int __imx415_start_stream(struct imx415 *imx415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) if (!imx415->is_thunderboot) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) ret = imx415_write_array(imx415->client, imx415->cur_mode->global_reg_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) ret = imx415_write_array(imx415->client, imx415->cur_mode->reg_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) /* In case these controls are set before streaming */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) ret = __v4l2_ctrl_handler_setup(&imx415->ctrl_handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) if (imx415->has_init_exp && imx415->cur_mode->hdr_mode != NO_HDR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) ret = imx415_ioctl(&imx415->subdev, PREISP_CMD_SET_HDRAE_EXP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) &imx415->init_hdrae_exp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) dev_err(&imx415->client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) "init exp fail in hdr mode\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) return imx415_write_reg(imx415->client, IMX415_REG_CTRL_MODE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) IMX415_REG_VALUE_08BIT, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) static int __imx415_stop_stream(struct imx415 *imx415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) imx415->has_init_exp = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) if (imx415->is_thunderboot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) imx415->is_first_streamoff = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) return imx415_write_reg(imx415->client, IMX415_REG_CTRL_MODE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) IMX415_REG_VALUE_08BIT, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) static int imx415_s_stream(struct v4l2_subdev *sd, int on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) struct imx415 *imx415 = to_imx415(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) struct i2c_client *client = imx415->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) dev_info(&imx415->client->dev, "s_stream: %d. %dx%d, hdr: %d, bpp: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) on, imx415->cur_mode->width, imx415->cur_mode->height,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) imx415->cur_mode->hdr_mode, imx415->cur_mode->bpp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) mutex_lock(&imx415->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) on = !!on;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) if (on == imx415->streaming)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) goto unlock_and_return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) if (on) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) if (imx415->is_thunderboot && rkisp_tb_get_state() == RKISP_TB_NG) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) imx415->is_thunderboot = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) __imx415_power_on(imx415);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) ret = pm_runtime_get_sync(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) pm_runtime_put_noidle(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) goto unlock_and_return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) ret = __imx415_start_stream(imx415);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) v4l2_err(sd, "start stream failed while write regs\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) pm_runtime_put(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) goto unlock_and_return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) __imx415_stop_stream(imx415);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) pm_runtime_put(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) imx415->streaming = on;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) unlock_and_return:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) mutex_unlock(&imx415->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) static int imx415_s_power(struct v4l2_subdev *sd, int on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) struct imx415 *imx415 = to_imx415(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) struct i2c_client *client = imx415->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) mutex_lock(&imx415->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) if (imx415->power_on == !!on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) goto unlock_and_return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) if (on) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) ret = pm_runtime_get_sync(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) pm_runtime_put_noidle(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) goto unlock_and_return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) imx415->power_on = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) pm_runtime_put(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) imx415->power_on = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) unlock_and_return:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) mutex_unlock(&imx415->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) int __imx415_power_on(struct imx415 *imx415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) struct device *dev = &imx415->client->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) if (imx415->is_thunderboot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) if (!IS_ERR_OR_NULL(imx415->pins_default)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) ret = pinctrl_select_state(imx415->pinctrl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) imx415->pins_default);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) dev_err(dev, "could not set pins\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) ret = regulator_bulk_enable(IMX415_NUM_SUPPLIES, imx415->supplies);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) dev_err(dev, "Failed to enable regulators\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) goto err_pinctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) if (!IS_ERR(imx415->power_gpio))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) gpiod_direction_output(imx415->power_gpio, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) /* At least 500ns between power raising and XCLR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) /* fix power on timing if insmod this ko */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) usleep_range(10 * 1000, 20 * 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) if (!IS_ERR(imx415->reset_gpio))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) gpiod_direction_output(imx415->reset_gpio, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) /* At least 1us between XCLR and clk */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) /* fix power on timing if insmod this ko */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) usleep_range(10 * 1000, 20 * 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) ret = clk_set_rate(imx415->xvclk, IMX415_XVCLK_FREQ_37M);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) dev_warn(dev, "Failed to set xvclk rate\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) if (clk_get_rate(imx415->xvclk) != IMX415_XVCLK_FREQ_37M)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) dev_warn(dev, "xvclk mismatched\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) ret = clk_prepare_enable(imx415->xvclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) dev_err(dev, "Failed to enable xvclk\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) goto err_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) /* At least 20us between XCLR and I2C communication */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) usleep_range(20*1000, 30*1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) err_clk:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) if (!IS_ERR(imx415->reset_gpio))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) gpiod_direction_output(imx415->reset_gpio, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) regulator_bulk_disable(IMX415_NUM_SUPPLIES, imx415->supplies);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) err_pinctrl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) if (!IS_ERR_OR_NULL(imx415->pins_sleep))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) pinctrl_select_state(imx415->pinctrl, imx415->pins_sleep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) static void __imx415_power_off(struct imx415 *imx415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) struct device *dev = &imx415->client->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) if (imx415->is_thunderboot) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) if (imx415->is_first_streamoff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) imx415->is_thunderboot = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) imx415->is_first_streamoff = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) if (!IS_ERR(imx415->reset_gpio))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) gpiod_direction_output(imx415->reset_gpio, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) clk_disable_unprepare(imx415->xvclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) if (!IS_ERR_OR_NULL(imx415->pins_sleep)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) ret = pinctrl_select_state(imx415->pinctrl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) imx415->pins_sleep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) dev_dbg(dev, "could not set pins\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) if (!IS_ERR(imx415->power_gpio))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) gpiod_direction_output(imx415->power_gpio, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) regulator_bulk_disable(IMX415_NUM_SUPPLIES, imx415->supplies);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) static int imx415_runtime_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) struct i2c_client *client = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) struct v4l2_subdev *sd = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) struct imx415 *imx415 = to_imx415(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) return __imx415_power_on(imx415);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) static int imx415_runtime_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) struct i2c_client *client = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) struct v4l2_subdev *sd = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) struct imx415 *imx415 = to_imx415(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) __imx415_power_off(imx415);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) static int imx415_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) struct imx415 *imx415 = to_imx415(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) struct v4l2_mbus_framefmt *try_fmt =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) v4l2_subdev_get_try_format(sd, fh->pad, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) const struct imx415_mode *def_mode = &supported_modes[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) mutex_lock(&imx415->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) /* Initialize try_fmt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) try_fmt->width = def_mode->width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) try_fmt->height = def_mode->height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) try_fmt->code = def_mode->bus_fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) try_fmt->field = V4L2_FIELD_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) mutex_unlock(&imx415->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) /* No crop or compose */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) static int imx415_enum_frame_interval(struct v4l2_subdev *sd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) struct v4l2_subdev_pad_config *cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) struct v4l2_subdev_frame_interval_enum *fie)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) struct imx415 *imx415 = to_imx415(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) if (fie->index >= imx415->cfg_num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) fie->code = supported_modes[fie->index].bus_fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) fie->width = supported_modes[fie->index].width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) fie->height = supported_modes[fie->index].height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) fie->interval = supported_modes[fie->index].max_fps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) fie->reserved[0] = supported_modes[fie->index].hdr_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) #define CROP_START(SRC, DST) (((SRC) - (DST)) / 2 / 4 * 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) #define DST_WIDTH_3840 3840
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195) #define DST_HEIGHT_2160 2160
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) #define DST_WIDTH_1920 1920
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) #define DST_HEIGHT_1080 1080
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) * The resolution of the driver configuration needs to be exactly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) * the same as the current output resolution of the sensor,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) * the input width of the isp needs to be 16 aligned,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) * the input height of the isp needs to be 8 aligned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) * Can be cropped to standard resolution by this function,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) * otherwise it will crop out strange resolution according
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) * to the alignment rules.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) static int imx415_get_selection(struct v4l2_subdev *sd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) struct v4l2_subdev_pad_config *cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) struct v4l2_subdev_selection *sel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) struct imx415 *imx415 = to_imx415(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) if (sel->target == V4L2_SEL_TGT_CROP_BOUNDS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) if (imx415->cur_mode->width == 3864) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) sel->r.left = CROP_START(imx415->cur_mode->width, DST_WIDTH_3840);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) sel->r.width = DST_WIDTH_3840;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) sel->r.top = CROP_START(imx415->cur_mode->height, DST_HEIGHT_2160);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) sel->r.height = DST_HEIGHT_2160;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) } else if (imx415->cur_mode->width == 1944) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221) sel->r.left = CROP_START(imx415->cur_mode->width, DST_WIDTH_1920);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) sel->r.width = DST_WIDTH_1920;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) sel->r.top = CROP_START(imx415->cur_mode->height, DST_HEIGHT_1080);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) sel->r.height = DST_HEIGHT_1080;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226) sel->r.left = CROP_START(imx415->cur_mode->width, imx415->cur_mode->width);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) sel->r.width = imx415->cur_mode->width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) sel->r.top = CROP_START(imx415->cur_mode->height, imx415->cur_mode->height);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) sel->r.height = imx415->cur_mode->height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) static const struct dev_pm_ops imx415_pm_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) SET_RUNTIME_PM_OPS(imx415_runtime_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) imx415_runtime_resume, NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) static const struct v4l2_subdev_internal_ops imx415_internal_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) .open = imx415_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) static const struct v4l2_subdev_core_ops imx415_core_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) .s_power = imx415_s_power,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) .ioctl = imx415_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) #ifdef CONFIG_COMPAT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) .compat_ioctl32 = imx415_compat_ioctl32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) static const struct v4l2_subdev_video_ops imx415_video_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) .s_stream = imx415_s_stream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) .g_frame_interval = imx415_g_frame_interval,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) static const struct v4l2_subdev_pad_ops imx415_pad_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) .enum_mbus_code = imx415_enum_mbus_code,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) .enum_frame_size = imx415_enum_frame_sizes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) .enum_frame_interval = imx415_enum_frame_interval,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) .get_fmt = imx415_get_fmt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) .set_fmt = imx415_set_fmt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) .get_selection = imx415_get_selection,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) .get_mbus_config = imx415_g_mbus_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) static const struct v4l2_subdev_ops imx415_subdev_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271) .core = &imx415_core_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272) .video = &imx415_video_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273) .pad = &imx415_pad_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) static int imx415_set_ctrl(struct v4l2_ctrl *ctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278) struct imx415 *imx415 = container_of(ctrl->handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279) struct imx415, ctrl_handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) struct i2c_client *client = imx415->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) s64 max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) u32 vts = 0, val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) u32 shr0 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) /* Propagate change of current control to all related controls */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) switch (ctrl->id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) case V4L2_CID_VBLANK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) if (imx415->cur_mode->hdr_mode == NO_HDR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) /* Update max exposure while meeting expected vblanking */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) max = imx415->cur_mode->height + ctrl->val - 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) __v4l2_ctrl_modify_range(imx415->exposure,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) imx415->exposure->minimum, max,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) imx415->exposure->step,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) imx415->exposure->default_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) if (!pm_runtime_get_if_in_use(&client->dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) switch (ctrl->id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) case V4L2_CID_EXPOSURE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305) if (imx415->cur_mode->hdr_mode != NO_HDR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) shr0 = imx415->cur_vts - ctrl->val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308) ret = imx415_write_reg(imx415->client, IMX415_LF_EXPO_REG_L,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) IMX415_REG_VALUE_08BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) IMX415_FETCH_EXP_L(shr0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) ret |= imx415_write_reg(imx415->client, IMX415_LF_EXPO_REG_M,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) IMX415_REG_VALUE_08BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) IMX415_FETCH_EXP_M(shr0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) ret |= imx415_write_reg(imx415->client, IMX415_LF_EXPO_REG_H,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) IMX415_REG_VALUE_08BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) IMX415_FETCH_EXP_H(shr0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) dev_dbg(&client->dev, "set exposure(shr0) %d = cur_vts(%d) - val(%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) shr0, imx415->cur_vts, ctrl->val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) case V4L2_CID_ANALOGUE_GAIN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) if (imx415->cur_mode->hdr_mode != NO_HDR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) ret = imx415_write_reg(imx415->client, IMX415_LF_GAIN_REG_H,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) IMX415_REG_VALUE_08BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325) IMX415_FETCH_GAIN_H(ctrl->val));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) ret |= imx415_write_reg(imx415->client, IMX415_LF_GAIN_REG_L,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) IMX415_REG_VALUE_08BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) IMX415_FETCH_GAIN_L(ctrl->val));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) dev_dbg(&client->dev, "set analog gain 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) ctrl->val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) case V4L2_CID_VBLANK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333) vts = ctrl->val + imx415->cur_mode->height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) * vts of hdr mode is double to correct T-line calculation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) * Restore before write to reg.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) if (imx415->cur_mode->hdr_mode == HDR_X2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) vts = (vts + 3) / 4 * 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340) imx415->cur_vts = vts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341) vts /= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) } else if (imx415->cur_mode->hdr_mode == HDR_X3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) vts = (vts + 11) / 12 * 12;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344) imx415->cur_vts = vts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) vts /= 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) imx415->cur_vts = vts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349) ret = imx415_write_reg(imx415->client, IMX415_VTS_REG_L,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350) IMX415_REG_VALUE_08BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) IMX415_FETCH_VTS_L(vts));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352) ret |= imx415_write_reg(imx415->client, IMX415_VTS_REG_M,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) IMX415_REG_VALUE_08BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) IMX415_FETCH_VTS_M(vts));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355) ret |= imx415_write_reg(imx415->client, IMX415_VTS_REG_H,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) IMX415_REG_VALUE_08BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357) IMX415_FETCH_VTS_H(vts));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) dev_dbg(&client->dev, "set vblank 0x%x vts %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) ctrl->val, vts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361) case V4L2_CID_HFLIP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) ret = imx415_read_reg(imx415->client, IMX415_FLIP_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) IMX415_REG_VALUE_08BIT, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) if (ctrl->val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367) val |= IMX415_MIRROR_BIT_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) val &= ~IMX415_MIRROR_BIT_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) ret = imx415_write_reg(imx415->client, IMX415_FLIP_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) IMX415_REG_VALUE_08BIT, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) case V4L2_CID_VFLIP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374) ret = imx415_read_reg(imx415->client, IMX415_FLIP_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375) IMX415_REG_VALUE_08BIT, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378) if (ctrl->val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379) val |= IMX415_FLIP_BIT_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381) val &= ~IMX415_FLIP_BIT_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) ret = imx415_write_reg(imx415->client, IMX415_FLIP_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383) IMX415_REG_VALUE_08BIT, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386) dev_warn(&client->dev, "%s Unhandled id:0x%x, val:0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387) __func__, ctrl->id, ctrl->val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) pm_runtime_put(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396) static const struct v4l2_ctrl_ops imx415_ctrl_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397) .s_ctrl = imx415_set_ctrl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400) static int imx415_initialize_controls(struct imx415 *imx415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402) const struct imx415_mode *mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403) struct v4l2_ctrl_handler *handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404) s64 exposure_max, vblank_def;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405) u64 pixel_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) u32 h_blank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409) handler = &imx415->ctrl_handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) mode = imx415->cur_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411) ret = v4l2_ctrl_handler_init(handler, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414) handler->lock = &imx415->mutex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416) imx415->link_freq = v4l2_ctrl_new_int_menu(handler, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) V4L2_CID_LINK_FREQ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418) ARRAY_SIZE(link_freq_items) - 1, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419) link_freq_items);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) v4l2_ctrl_s_ctrl(imx415->link_freq, mode->mipi_freq_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422) /* pixel rate = link frequency * 2 * lanes / BITS_PER_SAMPLE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423) pixel_rate = (u32)link_freq_items[mode->mipi_freq_idx] / mode->bpp * 2 * IMX415_4LANES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424) imx415->pixel_rate = v4l2_ctrl_new_std(handler, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425) V4L2_CID_PIXEL_RATE, 0, IMX415_MAX_PIXEL_RATE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426) 1, pixel_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428) h_blank = mode->hts_def - mode->width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429) imx415->hblank = v4l2_ctrl_new_std(handler, NULL, V4L2_CID_HBLANK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430) h_blank, h_blank, 1, h_blank);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431) if (imx415->hblank)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432) imx415->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434) vblank_def = mode->vts_def - mode->height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435) imx415->vblank = v4l2_ctrl_new_std(handler, &imx415_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436) V4L2_CID_VBLANK, vblank_def,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437) IMX415_VTS_MAX - mode->height,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438) 1, vblank_def);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439) imx415->cur_vts = mode->vts_def;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441) exposure_max = mode->vts_def - 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442) imx415->exposure = v4l2_ctrl_new_std(handler, &imx415_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443) V4L2_CID_EXPOSURE, IMX415_EXPOSURE_MIN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444) exposure_max, IMX415_EXPOSURE_STEP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445) mode->exp_def);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447) imx415->anal_a_gain = v4l2_ctrl_new_std(handler, &imx415_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448) V4L2_CID_ANALOGUE_GAIN, IMX415_GAIN_MIN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449) IMX415_GAIN_MAX, IMX415_GAIN_STEP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450) IMX415_GAIN_DEFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452) v4l2_ctrl_new_std(handler, &imx415_ctrl_ops, V4L2_CID_HFLIP, 0, 1, 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453) v4l2_ctrl_new_std(handler, &imx415_ctrl_ops, V4L2_CID_VFLIP, 0, 1, 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455) if (handler->error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456) ret = handler->error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457) dev_err(&imx415->client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458) "Failed to init controls(%d)\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459) goto err_free_handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462) imx415->subdev.ctrl_handler = handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463) imx415->has_init_exp = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467) err_free_handler:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468) v4l2_ctrl_handler_free(handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473) static int imx415_check_sensor_id(struct imx415 *imx415,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474) struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476) struct device *dev = &imx415->client->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477) u32 id = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480) if (imx415->is_thunderboot) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481) dev_info(dev, "Enable thunderboot mode, skip sensor id check\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485) ret = imx415_read_reg(client, IMX415_REG_CHIP_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486) IMX415_REG_VALUE_08BIT, &id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487) if (id != CHIP_ID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488) dev_err(dev, "Unexpected sensor id(%06x), ret(%d)\n", id, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492) dev_info(dev, "Detected imx415 id %06x\n", CHIP_ID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497) static int imx415_configure_regulators(struct imx415 *imx415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501) for (i = 0; i < IMX415_NUM_SUPPLIES; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502) imx415->supplies[i].supply = imx415_supply_names[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504) return devm_regulator_bulk_get(&imx415->client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505) IMX415_NUM_SUPPLIES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506) imx415->supplies);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509) static int imx415_probe(struct i2c_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510) const struct i2c_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512) struct device *dev = &client->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513) struct device_node *node = dev->of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514) struct imx415 *imx415;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515) struct v4l2_subdev *sd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516) char facing[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518) u32 i, hdr_mode = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520) dev_info(dev, "driver version: %02x.%02x.%02x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521) DRIVER_VERSION >> 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522) (DRIVER_VERSION & 0xff00) >> 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523) DRIVER_VERSION & 0x00ff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525) imx415 = devm_kzalloc(dev, sizeof(*imx415), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526) if (!imx415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529) ret = of_property_read_u32(node, RKMODULE_CAMERA_MODULE_INDEX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530) &imx415->module_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531) ret |= of_property_read_string(node, RKMODULE_CAMERA_MODULE_FACING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532) &imx415->module_facing);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533) ret |= of_property_read_string(node, RKMODULE_CAMERA_MODULE_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534) &imx415->module_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535) ret |= of_property_read_string(node, RKMODULE_CAMERA_LENS_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536) &imx415->len_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538) dev_err(dev, "could not get module information!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542) ret = of_property_read_u32(node, OF_CAMERA_HDR_MODE, &hdr_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544) hdr_mode = NO_HDR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545) dev_warn(dev, " Get hdr mode failed! no hdr default\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547) imx415->client = client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548) imx415->cfg_num = ARRAY_SIZE(supported_modes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549) for (i = 0; i < imx415->cfg_num; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550) if (hdr_mode == supported_modes[i].hdr_mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551) imx415->cur_mode = &supported_modes[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556) imx415->is_thunderboot = IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558) imx415->xvclk = devm_clk_get(dev, "xvclk");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559) if (IS_ERR(imx415->xvclk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560) dev_err(dev, "Failed to get xvclk\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564) imx415->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_ASIS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565) if (IS_ERR(imx415->reset_gpio))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566) dev_warn(dev, "Failed to get reset-gpios\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2567) imx415->power_gpio = devm_gpiod_get(dev, "power", GPIOD_ASIS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2568) if (IS_ERR(imx415->power_gpio))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2569) dev_warn(dev, "Failed to get power-gpios\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2570) imx415->pinctrl = devm_pinctrl_get(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2571) if (!IS_ERR(imx415->pinctrl)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2572) imx415->pins_default =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2573) pinctrl_lookup_state(imx415->pinctrl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2574) OF_CAMERA_PINCTRL_STATE_DEFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2575) if (IS_ERR(imx415->pins_default))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2576) dev_info(dev, "could not get default pinstate\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2578) imx415->pins_sleep =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2579) pinctrl_lookup_state(imx415->pinctrl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2580) OF_CAMERA_PINCTRL_STATE_SLEEP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2581) if (IS_ERR(imx415->pins_sleep))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2582) dev_info(dev, "could not get sleep pinstate\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2583) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2584) dev_info(dev, "no pinctrl\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2585) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2587) ret = imx415_configure_regulators(imx415);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2588) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2589) dev_err(dev, "Failed to get power regulators\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2590) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2591) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2593) mutex_init(&imx415->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2595) sd = &imx415->subdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2596) v4l2_i2c_subdev_init(sd, client, &imx415_subdev_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2597) ret = imx415_initialize_controls(imx415);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2598) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2599) goto err_destroy_mutex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2601) ret = __imx415_power_on(imx415);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2602) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2603) goto err_free_handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2605) ret = imx415_check_sensor_id(imx415, client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2606) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2607) goto err_power_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2609) #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2610) sd->internal_ops = &imx415_internal_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2611) sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2612) V4L2_SUBDEV_FL_HAS_EVENTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2613) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2614) #if defined(CONFIG_MEDIA_CONTROLLER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2615) imx415->pad.flags = MEDIA_PAD_FL_SOURCE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2616) sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2617) ret = media_entity_pads_init(&sd->entity, 1, &imx415->pad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2618) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2619) goto err_power_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2620) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2622) memset(facing, 0, sizeof(facing));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2623) if (strcmp(imx415->module_facing, "back") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2624) facing[0] = 'b';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2625) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2626) facing[0] = 'f';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2628) snprintf(sd->name, sizeof(sd->name), "m%02d_%s_%s %s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2629) imx415->module_index, facing,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2630) IMX415_NAME, dev_name(sd->dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2631) ret = v4l2_async_register_subdev_sensor_common(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2632) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2633) dev_err(dev, "v4l2 async register subdev failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2634) goto err_clean_entity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2635) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2637) pm_runtime_set_active(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2638) pm_runtime_enable(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2639) pm_runtime_idle(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2641) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2643) err_clean_entity:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2644) #if defined(CONFIG_MEDIA_CONTROLLER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2645) media_entity_cleanup(&sd->entity);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2646) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2647) err_power_off:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2648) __imx415_power_off(imx415);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2649) err_free_handler:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2650) v4l2_ctrl_handler_free(&imx415->ctrl_handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2651) err_destroy_mutex:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2652) mutex_destroy(&imx415->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2654) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2655) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2657) static int imx415_remove(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2658) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2659) struct v4l2_subdev *sd = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2660) struct imx415 *imx415 = to_imx415(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2662) v4l2_async_unregister_subdev(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2663) #if defined(CONFIG_MEDIA_CONTROLLER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2664) media_entity_cleanup(&sd->entity);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2665) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2666) v4l2_ctrl_handler_free(&imx415->ctrl_handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2667) mutex_destroy(&imx415->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2669) pm_runtime_disable(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2670) if (!pm_runtime_status_suspended(&client->dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2671) __imx415_power_off(imx415);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2672) pm_runtime_set_suspended(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2674) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2675) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2677) #if IS_ENABLED(CONFIG_OF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2678) static const struct of_device_id imx415_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2679) { .compatible = "sony,imx415" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2680) {},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2681) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2682) MODULE_DEVICE_TABLE(of, imx415_of_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2683) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2685) static const struct i2c_device_id imx415_match_id[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2686) { "sony,imx415", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2687) { },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2688) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2690) static struct i2c_driver imx415_i2c_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2691) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2692) .name = IMX415_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2693) .pm = &imx415_pm_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2694) .of_match_table = of_match_ptr(imx415_of_match),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2695) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2696) .probe = &imx415_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2697) .remove = &imx415_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2698) .id_table = imx415_match_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2699) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2701) static int __init sensor_mod_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2702) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2703) return i2c_add_driver(&imx415_i2c_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2704) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2706) static void __exit sensor_mod_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2707) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2708) i2c_del_driver(&imx415_i2c_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2709) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2711) device_initcall_sync(sensor_mod_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2712) module_exit(sensor_mod_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2714) MODULE_DESCRIPTION("Sony imx415 sensor driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2715) MODULE_LICENSE("GPL v2");