kernel-brax3-ubuntu-touch/drivers/misc/mediatek/imgsensor/src-v4l2/adaptor-subdrv.h
erascape f319b992b1 kernel-5.15: Initial import brax3 UT kernel
* halium configs enabled

Signed-off-by: erascape <erascape@proton.me>
2025-09-23 15:17:10 +00:00

504 lines
12 KiB
C

/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright (c) 2020 MediaTek Inc. */
#ifndef __ADAPTOR_SUBDRV_H__
#define __ADAPTOR_SUBDRV_H__
#include <media/v4l2-subdev.h>
//#include "kd_imgsensor_define_v4l2.h"
#include "imgsensor-user.h"
#include "adaptor-def.h"
#define DEBUG_LOG(ctx, ...) do { \
if (ctx->i2c_client) \
imgsensor_info.sd = i2c_get_clientdata(ctx->i2c_client); \
if (imgsensor_info.sd) \
imgsensor_info.adaptor_ctx_ = to_ctx(imgsensor_info.sd); \
if ((imgsensor_info.adaptor_ctx_) \
&& unlikely(*((imgsensor_info.adaptor_ctx_)->sensor_debug_flag))) { \
LOG_INF(__VA_ARGS__); \
} \
} while (0)
/* def V4L2_MBUS_CSI2_IS_USER_DEFINED_DATA */
#define IMGSENSOR_VC_ROUTING
#define PARAM_DEFAULT 0
#define PARAM_UNDEFINED 0
enum {
I2C_DT_ADDR_16_DATA_8 = 0,
I2C_DT_ADDR_16_DATA_16,
I2C_DT_MAXCNT,
};
enum {
HW_ID_AVDD = 0,
HW_ID_DVDD,
HW_ID_DOVDD,
HW_ID_AFVDD,
HW_ID_AFVDD1,
HW_ID_AVDD1,
HW_ID_AVDD2,
HW_ID_PDN,
HW_ID_RST,
HW_ID_MCLK,
HW_ID_MCLK_DRIVING_CURRENT,
HW_ID_MIPI_SWITCH,
HW_ID_DVDD1,
HW_ID_RST1,
HW_ID_MCLK1,
HW_ID_MCLK1_DRIVING_CURRENT,
HW_ID_PONV,
HW_ID_SCL,
HW_ID_SDA,
HW_ID_EINT,
HW_ID_MAXCNT,
};
#define HW_ID_NAMES \
"HW_ID_AVDD", \
"HW_ID_DVDD", \
"HW_ID_DOVDD", \
"HW_ID_AFVDD", \
"HW_ID_AFVDD1", \
"HW_ID_AVDD1", \
"HW_ID_AVDD2", \
"HW_ID_PDN", \
"HW_ID_RST", \
"HW_ID_MCLK", \
"HW_ID_MCLK_DRIVING_CURRENT", \
"HW_ID_MIPI_SWITCH", \
"HW_ID_DVDD1", \
"HW_ID_RST1", \
"HW_ID_MCLK1", \
"HW_ID_MCLK1_DRIVING_CURRENT", \
"HW_ID_PONV", \
"HW_ID_SCL", \
"HW_ID_SDA", \
"HW_ID_EINT", \
enum AOV_MODE_CTRL_OPS {
AOV_MODE_CTRL_OPS_SENSING_CTRL = 0,
AOV_MODE_CTRL_OPS_MONTION_DETECTION_CTRL,
AOV_MODE_CTRL_OPS_SENSING_UT_ON_SCP,
AOV_MODE_CTRL_OPS_SENSING_UT_ON_APMCU,
AOV_MODE_CTRL_OPS_DPHY_GLOBAL_TIMING_CONTINUOUS_CLK,
AOV_MODE_CTRL_OPS_DPHY_GLOBAL_TIMING_NON_CONTINUOUS_CLK,
AOV_MODE_CTRL_OPS_MAX_NUM,
};
struct subdrv_pw_seq_entry {
int id;
int val;
int delay;
};
struct eeprom_info_struct {
u32 header_id;
u32 addr_header_id;
u8 i2c_write_id;
u8 qsc_support;
u16 qsc_size;
u16 addr_qsc;
u16 sensor_reg_addr_qsc;
u8 *qsc_table;
u8 pdc_support;
u16 pdc_size;
u16 addr_pdc;
u16 sensor_reg_addr_pdc;
u8 *pdc_table;
u8 lrc_support;
u16 lrc_size;
u16 addr_lrc;
u16 sensor_reg_addr_lrc;
u8 *lrc_table;
u8 xtalk_support; /* [1]sw-remo; [0]hw-remo; 0, not support */
u16 xtalk_size;
u16 addr_xtalk;
u16 sensor_reg_addr_xtalk;
u8 *xtalk_table;
/* preloaded data */
u8 *preload_qsc_table;
u8 *preload_pdc_table;
u8 *preload_lrc_table;
u8 *preload_xtalk_table;
};
struct subdrv_mode_struct {
u16 *mode_setting_table;
u32 mode_setting_len;
u32 seamless_switch_group;
u16 *seamless_switch_mode_setting_table;
u32 seamless_switch_mode_setting_len;
u32 hdr_group;
enum IMGSENSOR_HDR_MODE_ENUM hdr_mode;
u32 pclk;
u32 linelength;
u32 framelength;
u16 max_framerate;
u32 mipi_pixel_rate;
u32 readout_length;
u8 read_margin;
u32 framelength_step;
u32 coarse_integ_step;
u32 min_exposure_line;
struct SENSOR_WINSIZE_INFO_STRUCT imgsensor_winsize_info;
enum IMGSENSOR_RGBW_OUTPUT_MODE rgbw_output_mode;
u8 aov_mode;
u8 pdaf_cap;
struct SET_PD_BLOCK_INFO_T *imgsensor_pd_info;
u32 ae_binning_ratio;
u32 fine_integ_line;
u8 delay_frame;
struct mtk_csi_param csi_param;
struct mtk_mbus_frame_desc_entry *frame_desc;
u32 num_entries;
/* assign value only if fixed value by mode */
u8 sensor_output_dataformat;
u32 ana_gain_min;
u32 ana_gain_max;
u32 dig_gain_min;
u32 dig_gain_max;
u32 dig_gain_step;
};
#define REG_ADDR_MAXCNT 3
struct reg_ {
u16 addr[REG_ADDR_MAXCNT];
};
struct subdrv_static_ctx {
u32 sensor_id;
struct reg_ reg_addr_sensor_id;
u8 i2c_addr_table[5]; /* must end with 0xFF */
u32 i2c_burst_write_support;
u32 i2c_transfer_data_type;
struct eeprom_info_struct *eeprom_info;
u32 eeprom_num;
u16 resolution[2];
u8 mirror;
u8 mclk; /* mclk freqency, suggest 24 or 26 for 24Mhz or 26Mhz */
u8 isp_driving_current; /* mclk driving current */
u8 sensor_interface_type;
u8 mipi_sensor_type; /* 0,MIPI_OPHY_NCSI2; 1,MIPI_OPHY_CSI2, default is NCSI2 */
u8 mipi_lane_num;
u32 ob_pedestal;
u8 sensor_output_dataformat;
u32 ana_gain_def; /* ana_gain = 4x, ISO400 = 0dB */
u32 ana_gain_min;
u32 ana_gain_max;
u32 ana_gain_type;
u32 ana_gain_step;
u32 *ana_gain_table;
u32 ana_gain_table_size;
u32 min_gain_iso; /* ana_gain = 1x, support min ISO100 */
u32 exposure_def;
u32 exposure_min;
u32 exposure_max;
u32 exposure_step;
u8 exposure_margin;
u32 dig_gain_min;
u32 dig_gain_max;
u32 dig_gain_step;
u32 frame_length_max;
u8 ae_effective_frame;
u8 frame_time_delay_frame; /* EX: sony => 3 ; non-sony => 2 */
u32 start_exposure_offset;
enum IMGSENSOR_PDAF_SUPPORT_TYPE_ENUM pdaf_type;
enum IMGSENSOR_HDR_SUPPORT_TYPE_ENUM hdr_type;
enum IMGSENSOR_RGBW_SUPPORT_TYPE_ENUM rgbw_support;
u8 seamless_switch_support;
u8 temperature_support;
int (*g_temp)(void *arg);
u16 (*g_gain2reg)(u32 arg);
void (*g_cali)(void *arg);
void (*s_gph)(void *arg, u8 en);
void (*s_cali)(void *arg);
u16 reg_addr_stream;
u16 reg_addr_mirror_flip;
struct reg_ reg_addr_exposure[IMGSENSOR_STAGGER_EXPOSURE_CNT];
u16 long_exposure_support;
u16 reg_addr_exposure_lshift;
struct reg_ reg_addr_ana_gain[IMGSENSOR_STAGGER_EXPOSURE_CNT];
struct reg_ reg_addr_dig_gain[IMGSENSOR_STAGGER_EXPOSURE_CNT];
struct reg_ reg_addr_frame_length;
u16 reg_addr_temp_en;
u16 reg_addr_temp_read;
u16 reg_addr_auto_extend;
u16 reg_addr_frame_count;
u16 reg_addr_fast_mode;
u16 *init_setting_table;
u32 init_setting_len;
struct subdrv_mode_struct *mode;
u32 sensor_mode_num;
struct subdrv_feature_control *list;
u32 list_len;
u8 chk_s_off_sta;
u8 chk_s_off_end;
u32 checksum_value;
};
#define HDR_CAP_IHDR 0x1
#define HDR_CAP_MVHDR 0x2
#define HDR_CAP_ZHDR 0x4
#define HDR_CAP_3HDR 0x8
#define HDR_CAP_ATR 0x10
#define PDAF_CAP_PIXEL_DATA_IN_RAW 0x1
#define PDAF_CAP_PIXEL_DATA_IN_VC 0x2
#define PDAF_CAP_DIFF_DATA_IN_VC 0x4
#define PDAF_CAP_PDFOCUS_AREA 0x10
#define SUBDRV_I2C_BUF_SIZE 256
struct subdrv_ctx {
struct i2c_client *i2c_client;
u8 i2c_write_id;
u16 _i2c_data[SUBDRV_I2C_BUF_SIZE];
u16 _size_to_write;
u32 eeprom_index;
u8 eeprom_i2c_write_id;
u32 is_hflip:1;
u32 is_vflip:1;
u32 hdr_cap;
u32 pdaf_cap;
int max_frame_length;
int ana_gain_min;
int ana_gain_max;
int ana_gain_step;
int ana_gain_def;
int exposure_min;
int exposure_max;
int exposure_step;
int exposure_def;
int le_shutter_def;
int me_shutter_def;
int se_shutter_def;
int le_gain_def;
int me_gain_def;
int se_gain_def;
enum SENSOR_SCENARIO_ID_ENUM current_scenario_id;
bool is_streaming;
u32 sof_cnt;
u32 ref_sof_cnt;
u8 mirror; /* mirrorflip information */
u8 sensor_mode; /* record IMGSENSOR_MODE enum value */
u32 exposure[IMGSENSOR_STAGGER_EXPOSURE_CNT]; /* current exposure */
u32 ana_gain[IMGSENSOR_STAGGER_EXPOSURE_CNT]; /* current ana_gain */
u32 dig_gain[IMGSENSOR_STAGGER_EXPOSURE_CNT]; /* current dig_gain */
u32 shutter; /* current shutter */
u32 gain; /* current gain */
u32 pclk; /* current pclk */
u32 frame_length; /* current framelength */
u32 line_length; /* current linelength */
u32 min_frame_length; /* current framelength limitation */
u8 margin; /* current (mode's) exp margin */
u8 frame_time_delay_frame; /* EX: sony => 3 ; non-sony => 2 */
u16 dummy_pixel; /* current dummypixel */
u16 dummy_line; /* current dummline */
u16 current_fps; /* current max fps */
u32 readout_length; /* current readoutlength */
u8 read_margin; /* current read margin */
bool autoflicker_en; /* record autoflicker enable or disable */
u8 test_pattern; /* record test pattern mode or not */
u8 ihdr_mode; /* ihdr enable or disable */
u8 pdaf_mode; /* pdaf enable or disable */
u8 hdr_mode; /* HDR mode : 0: disable HDR, 1:IHDR, 2:HDR, 9:ZHDR */
struct IMGSENSOR_AE_FRM_MODE ae_frm_mode;
u8 current_ae_effective_frame;
bool extend_frame_length_en;
bool is_seamless;
bool fast_mode_on;
bool ae_ctrl_gph_en;
u32 is_read_preload_eeprom;
u32 is_read_four_cell;
struct pinctrl *pinctrl;
struct pinctrl_state *state[STATE_MAXCNT];
struct regulator *regulator[REGULATOR_MAXCNT];
struct clk *clk[CLK_MAXCNT];
struct subdrv_static_ctx s_ctx;
u32 aov_csi_clk; /* aov switch csi clk param */
unsigned int sensor_mode_ops;
bool sensor_debug_sensing_ut_on_scp;
bool sensor_debug_dphy_global_timing_continuous_clk;
};
struct subdrv_feature_control {
MSDK_SENSOR_FEATURE_ENUM feature_id;
void (*func)(struct subdrv_ctx *ctx, u8 *para, u32 *len);
};
struct subdrv_ops {
int (*get_id)(struct subdrv_ctx *ctx, u32 *id);
int (*init_ctx)(struct subdrv_ctx *ctx,
struct i2c_client *i2c_client, u8 i2c_write_id);
int (*open)(struct subdrv_ctx *ctx);
int (*get_info)(struct subdrv_ctx *ctx,
enum MSDK_SCENARIO_ID_ENUM scenario_id,
MSDK_SENSOR_INFO_STRUCT *pSensorInfo,
MSDK_SENSOR_CONFIG_STRUCT *pSensorConfigData);
int (*get_resolution)(struct subdrv_ctx *ctx,
MSDK_SENSOR_RESOLUTION_INFO_STRUCT *pSensorResolution);
int (*feature_control)(struct subdrv_ctx *ctx,
MSDK_SENSOR_FEATURE_ENUM FeatureId,
u8 *pFeaturePara,
u32 *pFeatureParaLen);
int (*control)(struct subdrv_ctx *ctx,
enum MSDK_SCENARIO_ID_ENUM ScenarioId,
MSDK_SENSOR_EXPOSURE_WINDOW_STRUCT *pImageWindow,
MSDK_SENSOR_CONFIG_STRUCT *pSensorConfigData);
int (*close)(struct subdrv_ctx *ctx);
int (*get_frame_desc)(struct subdrv_ctx *ctx,
int scenario_id,
struct mtk_mbus_frame_desc *fd);
int (*get_temp)(struct subdrv_ctx *ctx, int *temp);
int (*vsync_notify)(struct subdrv_ctx *ctx, unsigned int sof_cnt);
int (*update_sof_cnt)(struct subdrv_ctx *ctx, unsigned int sof_cnt);
int (*get_csi_param)(struct subdrv_ctx *ctx,
enum SENSOR_SCENARIO_ID_ENUM scenario_id,
struct mtk_csi_param *csi_param);
int (*power_on)(struct subdrv_ctx *ctx, void *data);
int (*power_off)(struct subdrv_ctx *ctx, void *data);
};
struct subdrv_entry {
const char *name;
unsigned int id;
const struct subdrv_pw_seq_entry *pw_seq;
const struct subdrv_ops *ops;
int pw_seq_cnt;
};
#define subdrv_call(ctx, o, args...) \
({ \
struct adaptor_ctx *__ctx = (ctx); \
int __ret; \
if (!__ctx || !__ctx->subdrv || !__ctx->subdrv->ops) \
__ret = -ENODEV; \
else if (!__ctx->subdrv->ops->o) \
__ret = -ENOIOCTLCMD; \
else \
__ret = __ctx->subdrv->ops->o(&ctx->subctx, ##args); \
__ret; \
})
#define subdrv_i2c_rd_u8(subctx, reg) \
({ \
u8 __val = 0xff; \
adaptor_i2c_rd_u8(subctx->i2c_client, \
subctx->i2c_write_id >> 1, reg, &__val); \
__val; \
})
#define subdrv_i2c_rd_u16(subctx, reg) \
({ \
u16 __val = 0xffff; \
adaptor_i2c_rd_u16(subctx->i2c_client, \
subctx->i2c_write_id >> 1, reg, &__val); \
__val; \
})
#define subdrv_i2c_wr_u8(subctx, reg, val) \
adaptor_i2c_wr_u8(subctx->i2c_client, \
subctx->i2c_write_id >> 1, reg, val)
#define subdrv_i2c_wr_u16(subctx, reg, val) \
adaptor_i2c_wr_u16(subctx->i2c_client, \
subctx->i2c_write_id >> 1, reg, val)
#define subdrv_i2c_wr_p8(subctx, reg, p_vals, n_vals) \
adaptor_i2c_wr_p8(subctx->i2c_client, \
subctx->i2c_write_id >> 1, reg, p_vals, n_vals)
#define subdrv_i2c_wr_p16(subctx, reg, p_vals, n_vals) \
adaptor_i2c_wr_p16(subctx->i2c_client, \
subctx->i2c_write_id >> 1, reg, p_vals, n_vals)
#define subdrv_i2c_wr_seq_p8(subctx, reg, p_vals, n_vals) \
adaptor_i2c_wr_seq_p8(subctx->i2c_client, \
subctx->i2c_write_id >> 1, reg, p_vals, n_vals)
#define subdrv_i2c_wr_regs_u8(subctx, list, len) \
adaptor_i2c_wr_regs_u8(subctx->i2c_client, \
subctx->i2c_write_id >> 1, list, len)
#define subdrv_i2c_wr_regs_u16(subctx, list, len) \
adaptor_i2c_wr_regs_u16(subctx->i2c_client, \
subctx->i2c_write_id >> 1, list, len)
#define FINE_INTEG_CONVERT(_shutter, _fine_integ) \
( \
((_fine_integ) <= 0) ? \
(_shutter) : \
(((_shutter) > (_fine_integ)) ? (((_shutter) - (_fine_integ)) / 1000) : 0) \
)
#define CALC_LINE_TIME_IN_NS(pclk, linelength) \
({ \
unsigned int val = 0; \
do { \
if (((pclk) / 1000) == 0) { \
val = 0; \
break; \
} \
val = \
((unsigned long long)(linelength)*1000000+(((pclk)/1000)-1)) \
/((pclk)/1000); \
} while (0); \
val; \
})
#define CONVERT_2_TOTAL_TIME(lineTimeInNs, lc) \
({ \
unsigned int val = 0; \
do { \
if ((lineTimeInNs) == 0) { \
val = 0; \
break; \
} \
val = \
(unsigned int)((unsigned long long)(lc)*(lineTimeInNs)/1000); \
} while (0); \
val; \
})
#define CONVERT_2_TOTAL_TIME_V2(pclk, linelength, lc) \
({ \
unsigned int val = 0; \
unsigned int lineTimeInNs = 0; \
lineTimeInNs = CALC_LINE_TIME_IN_NS((pclk), (linelength)); \
do { \
if ((lineTimeInNs) == 0) { \
val = 0; \
break; \
} \
val = \
(unsigned int)((unsigned long long)(lc)*(lineTimeInNs)/1000); \
} while (0); \
val; \
})
#endif