直接从代码进行分析:
#define START_REG_ARRAY \
{ \
{0xfe, 0x00, 0x00}, \
}
#define STOP_REG_ARRAY \
{ \
{0xfe, 0x00, 0x00}, \
}
#define GROUPON_REG_ARRAY \
{ \
{0xfe, 0x00, 0x00}, \
}
#define GROUPOFF_REG_ARRAY \
{ \
{0xfe, 0x00, 0x00}, \
}
#define INIT0_REG_ARRAY \
{ \
{0xfe,0x00,0x00}, \
}
#define RES0_REG_ARRAY \
{ \
{0xfe,0x00, 0x00}, \
} //以上是分别对应不同sensor对应不同工作模式时的寄存器设置,该数据有供应商提供
static sensor_lib_t sensor_lib_ptr =
{
.sensor_slave_info = //sensor_slave_info配置sensor的基础信息,name, addr,ID,power up/down
{
.sensor_name = SENSOR_MODEL,
.slave_addr = 0x6e,
.i2c_freq_mode = SENSOR_I2C_MODE_FAST, /* 400K */ //I2C传输速率
.addr_type = CAMERA_I2C_BYTE_ADDR,
.sensor_id_info =
{
.sensor_id_reg_addr = 0xf0,
.sensor_id = 0x5025,
},
.power_setting_array = //这里配置时序,power up/down,具体时序配置需要参考供应商提供的camera spac文件
{
.power_setting_a =
{
{
.seq_type = CAMERA_POW_SEQ_GPIO,
.seq_val = CAMERA_GPIO_RESET,
.config_val = GPIO_OUT_LOW,
.delay = 5,
},
{
.seq_type = CAMERA_POW_SEQ_VREG,
.seq_val = CAMERA_VDIG,
.config_val = 0,
.delay = 5,
},
{
.seq_type = CAMERA_POW_SEQ_VREG,
.seq_val = CAMERA_VANA,
.config_val = 0,
.delay = 1,
},
},
.size = 3,
.power_down_setting_a =
{
{
.seq_type = CAMERA_POW_SEQ_CLK,
.seq_val = CAMERA_MCLK,
.config_val = 0,
.delay = 1,
},
{
.seq_type = CAMERA_POW_SEQ_GPIO,
.seq_val = CAMERA_GPIO_RESET,
.config_val = GPIO_OUT_LOW,
.delay = 1,
},
{
.seq_type = CAMERA_POW_SEQ_GPIO,
.seq_val = CAMERA_GPIO_STANDBY,
.config_val = GPIO_OUT_LOW,
.delay = 1,
},
},
.size_down = 3,
},
},
.sensor_output = //配置sensor的输出模式(MIPI),以及输出数据格式
{
.output_format = SENSOR_BAYER,
.connection_mode = SENSOR_MIPI_CSI,
.raw_output = SENSOR_10_BIT_DIRECT,
#if defined(GC5025A_NORMAL_MIRROR)
.filter_arrangement = SENSOR_RGGB, //正常模式
#elif defined(GC5025A_H_MIRROR)
.filter_arrangement = SENSOR_GRBG, //竖直镜像模式
#elif defined(GC5025A_V_MIRROR)
.filter_arrangement = SENSOR_GBRG, //水平镜像模式
#elif defined(GC5025A_HV_MIRROR)
.filter_arrangement = SENSOR_BGGR,
#else
.filter_arrangement = SENSOR_RGGB,
#endif
},
.output_reg_addr =
{
.x_output = 0xff, //寄存器X_OUT 地址
.y_output = 0xff, //寄存器Y_OUT 地址
.line_length_pclk = 0xff,
.frame_length_lines = 0xff,
},
.exp_gain_info = //曝光相关寄存器地址
{
.coarse_int_time_addr = 0x03, //曝光时间寄存器地址
.global_gain_addr = 0xb2,
.vert_offset = 2,
},
.aec_info =
{
.max_gain = 16.0,
.max_linecount = 5000,
},
.sensor_num_frame_skip = 2,
.sensor_num_HDR_frame_skip = 2,
.sensor_max_pipeline_frame_delay = 2,
.sensor_property =
{
.pix_size = 1.12,
.sensing_method = SENSOR_SMETHOD_ONE_CHIP_COLOR_AREA_SENSOR,
.crop_factor = 1.0,
},
.pixel_array_size_info =
{
.active_array_size =
{
.width = 2592,
.height = 1944,
},
.left_dummy = 0,
.right_dummy = 0,
.top_dummy = 0,
.bottom_dummy = 0,
},
.color_level_info =
{
.white_level = 1023,
.r_pedestal = 64,
.gr_pedestal = 64,
.gb_pedestal = 64,
.b_pedestal = 64,
},
.sensor_stream_info_array =
{
.sensor_stream_info =
{
{
.vc_cfg_size = 1,
.vc_cfg =
{
{
.cid = 0,
.dt = CSI_RAW10,
.decode_format = CSI_DECODE_10BIT,
},
},
.pix_data_fmt =
{
SENSOR_BAYER,
},
},
},
.size = 1,
},
.start_settings = //不同模式的对应设置 start
{
.reg_setting_a = START_REG_ARRAY,
.addr_type = CAMERA_I2C_BYTE_ADDR,
.data_type = CAMERA_I2C_BYTE_DATA,
.delay = 0,
},
.stop_settings = //stop模式设置
{
.reg_setting_a = STOP_REG_ARRAY,
.addr_type = CAMERA_I2C_BYTE_ADDR,
.data_type = CAMERA_I2C_BYTE_DATA,
.delay = 0,
},
.groupon_settings =
{
.reg_setting_a = GROUPON_REG_ARRAY,
.addr_type = CAMERA_I2C_BYTE_ADDR,
.data_type = CAMERA_I2C_BYTE_DATA,
.delay = 0,
},
.groupoff_settings =
{
.reg_setting_a = GROUPOFF_REG_ARRAY,
.addr_type = CAMERA_I2C_BYTE_ADDR,
.data_type = CAMERA_I2C_BYTE_DATA,
.delay = 0,
},
.embedded_data_enable_settings =
{
.reg_setting_a = {},
.addr_type = 0,
.data_type = 0,
.delay = 0,
},
.embedded_data_disable_settings =
{
.reg_setting_a = {},
.addr_type = 0,
.data_type = 0,
.delay = 0,
},
.init_settings_array = //初始化设置
{
.reg_settings =
{
{
.reg_setting_a = INIT0_REG_ARRAY,
.addr_type = CAMERA_I2C_BYTE_ADDR,
.data_type = CAMERA_I2C_BYTE_DATA,
.delay = 60,
},
},
.size = 1,
},
.res_settings_array = //resolution设置
{
.reg_settings = //根据不同resolution输出来设置不同寄存器
{
/* Res 0 */
{
.reg_setting_a = RES0_REG_ARRAY,
.addr_type = CAMERA_I2C_BYTE_ADDR,
.data_type = CAMERA_I2C_BYTE_DATA,
.delay = 0,
},
},
.size = 1,
},
.out_info_array = //输出信息设置,与上面reg_settings设置相对应
{
.out_info =
{
{
.x_output = 2592, //输出有效宽度
.y_output = 1944, //输出有效高度
.line_length_pclk = 4800, //含有blanking的宽度值
.frame_length_lines = 2000, //含有blanking的高度值
.vt_pixel_clk = 288000000, //虚拟时钟,用于曝光时间计算
.op_pixel_clk = 216000000, //VFE的处理数据速率
.binning_factor = 1,
.min_fps = 7.5, //最小帧率
.max_fps = 30.0, //最大帧率
.mode = SENSOR_DEFAULT_MODE, //sensor工作模式
.offset_x = 0,
.offset_y = 0,
.scale_factor = 0,
},
},
.size = 1,
},
.csi_params =
{
.lane_cnt = 2,
.settle_cnt = 0x14,
.is_csi_3phase = 0,
},
.csid_lut_params_array =
{
.lut_params =
{
/* Res 0 */
{
.num_cid = 1,
.vc_cfg_a =
{
{
.cid = 0,
.dt = CSI_RAW10,
.decode_format = CSI_DECODE_10BIT
},
},
},
},
.size = 2,
},
.crop_params_array =
{
.crop_params =
{
/* Res 0 */
{
.top_crop = 0,
.bottom_crop = 0,
.left_crop = 0,
.right_crop = 0,
},
},
.size = 1,
},
.exposure_func_table = //曝光计算函数调用
{
.sensor_calculate_exposure = sensor_calculate_exposure,
.sensor_fill_exposure_array = sensor_fill_exposure_array,
},
.meta_data_out_info_array =
{
.meta_data_out_info =
{
{
.width = 0,
.height = 0,
.stats_type = 0,
},
},
.size = 0,
},
.rolloff_config =
{
.enable = FALSE,
.full_size_info =
{
.full_size_width = 0,
.full_size_height = 0,
.full_size_left_crop = 0,
.full_size_top_crop = 0,
},
},
.adc_readout_time = 0,
.app_delay = {
[SENSOR_DELAY_EXPOSURE] = 0,
[SENSOR_DELAY_ANALOG_SENSOR_GAIN] = 0,
[SENSOR_DELAY_DIGITAL_SENSOR_GAIN] = 0,
},
.noise_coeff = {
.gradient_S = 3.738032e-06,
.offset_S = 3.651935e-04,
.gradient_O = 4.499952e-07,
.offset_O = -2.968624e-04,
},
};
#endif
驱动中的大多数数据都是需要供应商提供参考的,需要注意的是sensor的不同输出模式对应不同的寄存器设置,根据这个会有RES0_REG_ARRAY,RES1_REG_ARRAY等,一般对应不同的分辨率输出,对应的需要在res_settings_array,out_info_array等中添加多个res与之对应,另外需要注意的是:这里不同的res输出需要对应tunning的分别调试,所以在vendor/qcom/propriety/mm-camera/mm-camera2/media-controll/module/sensor/config/XXXX_chromatix.xml中添加对应模式(这里对应对tunning参数的调用)。