Camera Probe 代码分析
1.libmmcamera_imx258.so 代碼分析
?
Sensor LIB 庫代碼位于 /vendor/qcom/proprietary/mm-camera/mm-camera2/media-controller/modules/sensors/sensor/libs
本文以 imx258 為例。
先來看下imx258_lib.c,其最核心的函數(shù)就是 sensor_open_lib,
返回 sensor_lib_ptr 結(jié)構(gòu)體,所有的 Camera 信息,都保存在該結(jié)構(gòu)體中。
我們來看下?sensor_lib_ptr?結(jié)構(gòu)體的定義。
@ /vendor/qcom/proprietary/mm-camerasdk/sensor/includes/sensor_lib.h typedef struct {/* sensor slave info */ // 從設(shè)備包括,I2C地址、I2C速率、Sensor_id 寄存器地址及Sensor_id 值、上下電的時序及電壓值struct camera_sensor_slave_info sensor_slave_info;/* sensor output settings */// 包括 出圖的格式(BAYER / YCbCr), 連接類型為 MIPI CSIsensor_output_t sensor_output;/* sensor output register address */// 輸出寄存器的地址,pclk,及l(fā)ine length pclk 、 frame length linesstruct sensor_output_reg_addr_t output_reg_addr;/* sensor exposure gain register address */// 曝光增益struct sensor_exp_gain_info_t exp_gain_info;/* sensor aec info */sensor_aec_data_t aec_info;/* number of frames to skip after start stream info */// preview 前丟棄過的 幀數(shù)unsigned short sensor_num_frame_skip;/* number of frames to skip after start HDR stream info */// HDR 丟棄的幀數(shù)unsigned short sensor_num_HDR_frame_skip;/* sensor pipeline delay */// pipeline 幀延時unsigned int sensor_max_pipeline_frame_delay;/* sensor lens info */// sensor line info 信息sensor_property_t sensor_property;/* imaging pixel array size info */// 像素點大小,寬高sensor_imaging_pixel_array_size pixel_array_size_info;/* Sensor color level information */// 顏色等級sensor_color_level_info color_level_info;/* sensor port info that consists of cid mask and fourcc mapaping */sensor_stream_info_array_t sensor_stream_info_array;/* Sensor Settings */// 初始化Camera 寄存器配置struct camera_i2c_reg_setting_array start_settings;// 關(guān)閉Camera 時的寄存器配置struct camera_i2c_reg_setting_array stop_settings;struct camera_i2c_reg_setting_array groupon_settings;struct camera_i2c_reg_setting_array groupoff_settings;struct camera_i2c_reg_setting_array embedded_data_enable_settings;struct camera_i2c_reg_setting_array embedded_data_disable_settings;struct camera_i2c_reg_setting_array aec_enable_settings;struct camera_i2c_reg_setting_array aec_disable_settings;struct camera_i2c_reg_setting_array dualcam_master_settings;struct camera_i2c_reg_setting_array dualcam_slave_settings;/* sensor test pattern info */// 測試圖信息sensor_test_info test_pattern_info;/* sensor effects info */struct sensor_effect_info effect_info;/* Sensor Settings Array *///初始化 Camera 寄存器配置struct sensor_lib_reg_settings_array init_settings_array;struct sensor_lib_reg_settings_array res_settings_array;// 不同辨率的輸出信息,xy像素大小,pclk,fps,數(shù)據(jù)傳輸速率struct sensor_lib_out_info_array out_info_array;// MIPI CSI 信息struct sensor_csi_params csi_params;struct sensor_csid_lut_params_array csid_lut_params_array;struct sensor_lib_crop_params_array crop_params_array;/* Exposure Info */sensor_exposure_table_t exposure_func_table;/* video_hdr mode info*/struct sensor_lib_meta_data_info_array meta_data_out_info_array;/* sensor optical black regions */sensor_optical_black_region_t optical_black_region_info;/* sensor_capability */sensor_capability_t sensor_capability;/* sensor_awb_table_t */sensor_awb_table_t awb_func_table;/* sensor_awb_table_t */sensor_fps_table_t fps_func_table;/* Parse RDI stats callback function */sensor_RDI_parser_stats_t parse_RDI_stats;/* full size info */sensor_rolloff_config rolloff_config;/* analog-digital conversion time */long long adc_readout_time;/* number of frames to skip for fast AEC use case */unsigned short sensor_num_fast_aec_frame_skip;/* add soft delay for sensor settings like exposure, gain ...*/unsigned char app_delay[SENSOR_DELAY_MAX];/* for noise profile calculationTuning team must update with proper values. */struct sensor_noise_coefficient_t noise_coeff;/* Flag to be set if any external library are to be loaded */unsigned char external_library;sensorlib_pdaf_apis_t sensorlib_pdaf_api;// PDAF 配軒pdaf_lib_t pdaf_config;/* sensor orientation flag */sensor_orientation_type_t sensor_orientation;} sensor_lib_t;imx258_lib.h?頭文件分析
@ /vendor/qcom/proprietary/mm-camera/mm-camera2/media-controller/modules/sensors/sensor/libs/imx258/imx258_lib.h/* imx258_lib.h** Copyright (c) 2015-2018 Qualcomm Technologies, Inc.* All Rights Reserved.* Confidential and Proprietary - Qualcomm Technologies, Inc.*/#ifndef __IMX258_LIB_H__ #define __IMX258_LIB_H__#include "sensor_lib.h" #include "eeprom_lib.h" #include "pdaf_api.h" #include "pdaf_camif_api.h" #define SENSOR_MODEL "imx258"/* IMX258 Regs */ #define IMX258_DIG_GAIN_GR_ADDR 0x020E #define IMX258_DIG_GAIN_R_ADDR 0x0210 #define IMX258_DIG_GAIN_B_ADDR 0x0212 #define IMX258_DIG_GAIN_GB_ADDR 0x0214 #define IMX258_EXP_RATIO_ADDR 0x0222 #define IMX258_ABS_GAIN_R_WORD_ADDR 0x0B90 #define IMX258_ABS_GAIN_B_WORD_ADDR 0x0B92/* IMX258 CONSTANTS */ #define IMX258_MAX_INTEGRATION_MARGIN 20/* STATS DATA TYPE */ #define IMX258_CSI_PD_ISTATS 0x2F#define IMX258_DATA_PEDESTAL 0x40 /* 10bit value */#define IMX258_MIN_AGAIN_REG_VAL 0 /* 1.0x */ #define IMX258_MAX_AGAIN_REG_VAL 480 /* 16.0x */#define IMX258_MIN_DGAIN_REG_VAL 256 /* 1.0x */ #define IMX258_MAX_DGAIN_REG_VAL 256 /* 1.0x */#define IMX258_MAX_DGAIN_DECIMATOR 256/* IMX258 FORMULAS */ #define IMX258_MIN_AGAIN (512 / (512 - IMX258_MIN_AGAIN_REG_VAL)) #define IMX258_MAX_AGAIN (512 / (512 - IMX258_MAX_AGAIN_REG_VAL))#define IMX258_MIN_DGAIN (IMX258_MIN_DGAIN_REG_VAL / 256) #define IMX258_MAX_DGAIN (IMX258_MAX_DGAIN_REG_VAL / 256)#define IMX258_MIN_GAIN IMX258_MIN_AGAIN * IMX258_MIN_DGAIN #define IMX258_MAX_GAIN IMX258_MAX_AGAIN * IMX258_MAX_DGAIN/* uncomment FLIP_MIRROR macro toenable flip and mirror in sensor readoutchange bayer patternload pdaf flip and mirror header */ //#define FLIP_MIRROR #define START_REG_ARRAY \ { \{0x0100, 0x01, 0x00}, \ }#define STOP_REG_ARRAY \ { \{0x0100, 0x00, 0x00}, \ }#define GROUPON_REG_ARRAY \ { \{0x0104, 0x01, 0x00}, \ }#define GROUPOFF_REG_ARRAY \ { \{0x0104, 0x00, 0x00}, \ }// 初始化 寄存器配置 #define INIT0_REG_ARRAY \ { \/* External Clock Settings */ \{0x0136, 0x18, 0x00}, \{0x0137, 0x00, 0x00}, \/* Global Settings */ \{0x3051, 0x00, 0x00}, \...... //配置一系烈的寄存器{0x3006, 0x00, 0x00}, \{0x3007, 0x00, 0x00}, \ }#ifndef FLIP_MIRROR#define FLIP_MIRROR_SETTING {{0x0101, 0x00, 0x00}} #else#define FLIP_MIRROR_SETTING {{0x0101, 0x03, 0x00}} #endif // 分辨率0 寄存器配置 #define RES0_REG_ARRAY \ { \/* Mode A1: 4208x3120 Full 30fps */ \/* Output Format Settings */ \{0x0112, 0x0A, 0x00}, \{0x0113, 0x0A, 0x00}, \...... //配置一系烈的寄存器{0x0818, 0x00, 0x00}, \{0x0819, 0x47, 0x00}, \ } // 分辨率1 寄存器配置 #define RES1_REG_ARRAY \ {\/* (Reg-10)Mode: Full 16:9 30 fps */ \/* Output Format Settings */ \{0x0112, 0x0A, 0x00}, \{0x0113, 0x0A, 0x00}, \/* Clock Settings */ \{0x0301, 0x05, 0x00}, \{0x0303, 0x02, 0x00}, \...... //配置一系烈的寄存器{0x0818, 0x00, 0x00}, \{0x0819, 0x47, 0x00}, \ } // 分辨率2 寄存器配置 #define RES2_REG_ARRAY \ { \/* Mode: 2100x1560 2x2 binning 30 fps */ \/* Output Format Settings */ \{0x0112, 0x0A, 0x00}, \{0x0113, 0x0A, 0x00}, \...... //配置一系烈的寄存器{0x0819, 0x47, 0x00}, \{0x3031, 0x00, 0x00}, \ } // 分辨率3 寄存器配置 #define RES3_REG_ARRAY \ { \/* Mode: 2100x1176 60 fps */ \/* Output Format Settings */ \{0x0112, 0x0A, 0x00}, \{0x0113, 0x0A, 0x00}, \...... //配置一系列的寄存器{0x0819, 0x47, 0x00}, \{0x3031, 0x00, 0x00}, \ } // 分辨率4 寄存器配置 #define RES4_REG_ARRAY \ { \/* Mode: 1400x784 90 fps*/ \/* Output Format Settings */ \{0x0112, 0x0A, 0x00}, \{0x0113, 0x0A, 0x00}, \...... //配置一系列的寄存器{0x0819, 0x47, 0x00}, \{0x3031, 0x00, 0x00}, \ } // 分辨率5 寄存器配置 #define RES5_REG_ARRAY \ { \/* Mode: 1400x760 120 fps*/ \/* Output Format Settings */ \{0x0112, 0x0A, 0x00}, \{0x0113, 0x0A, 0x00}, \...... //配置一系列的寄存器{0x0819, 0x47, 0x00}, \{0x3031, 0x00, 0x00}, \ }/* Sensor Handler */ static sensor_lib_t sensor_lib_ptr = {.sensor_slave_info ={.sensor_name = SENSOR_MODEL, // "imx258".slave_addr = 0x20, // 7位地址0x20, 010 0000, 對應(yīng)的8位地址為0100 0000, 0x40.i2c_freq_mode = SENSOR_I2C_MODE_FAST,.addr_type = CAMERA_I2C_WORD_ADDR,.sensor_id_info ={.sensor_id_reg_addr = 0x0016,.sensor_id = 0x0258,},.power_setting_array ={.power_setting_a ={{.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_VANA,.config_val = GPIO_OUT_HIGH,.delay = 1,},{.seq_type = CAMERA_POW_SEQ_VREG,.seq_val = CAMERA_VANA,.config_val = 0,.delay = 0,},{.seq_type = CAMERA_POW_SEQ_GPIO,.seq_val = CAMERA_GPIO_VDIG,.config_val = GPIO_OUT_HIGH,.delay = 1,},{.seq_type = CAMERA_POW_SEQ_VREG,.seq_val = CAMERA_VDIG,.config_val = 0,.delay = 0,},{.seq_type = CAMERA_POW_SEQ_VREG,.seq_val = CAMERA_VIO,.config_val = 0,.delay = 0,},{.seq_type = CAMERA_POW_SEQ_GPIO,.seq_val = CAMERA_GPIO_VAF,.config_val = GPIO_OUT_HIGH,.delay = 1,},{.seq_type = CAMERA_POW_SEQ_CLK,.seq_val = CAMERA_MCLK,.config_val = 24000000,.delay = 1,},{.seq_type = CAMERA_POW_SEQ_GPIO,.seq_val = CAMERA_GPIO_RESET,.config_val = GPIO_OUT_HIGH,.delay = 12,},},.size = 9,.power_down_setting_a ={{.seq_type = CAMERA_POW_SEQ_GPIO,.seq_val = CAMERA_GPIO_RESET,.config_val = GPIO_OUT_LOW,.delay = 1,},{.seq_type = CAMERA_POW_SEQ_CLK,.seq_val = CAMERA_MCLK,.config_val = 0,.delay = 1,},{.seq_type = CAMERA_POW_SEQ_VREG,.seq_val = CAMERA_VIO,.config_val = 0,.delay = 0,},{.seq_type = CAMERA_POW_SEQ_VREG,.seq_val = CAMERA_VDIG,.config_val = 0,.delay = 0,},{.seq_type = CAMERA_POW_SEQ_GPIO,.seq_val = CAMERA_GPIO_VDIG,.config_val = GPIO_OUT_LOW,.delay = 1,},{.seq_type = CAMERA_POW_SEQ_VREG,.seq_val = CAMERA_VANA,.config_val = 0,.delay = 0,},{.seq_type = CAMERA_POW_SEQ_GPIO,.seq_val = CAMERA_GPIO_VANA,.config_val = GPIO_OUT_LOW,.delay = 1,},{.seq_type = CAMERA_POW_SEQ_GPIO,.seq_val = CAMERA_GPIO_VAF,.config_val = GPIO_OUT_LOW,.delay = 1,},},.size_down = 8,},},.sensor_output ={.output_format = SENSOR_BAYER,.connection_mode = SENSOR_MIPI_CSI,.raw_output = SENSOR_10_BIT_DIRECT, #ifndef FLIP_MIRROR.filter_arrangement = SENSOR_RGGB, #else.filter_arrangement = SENSOR_BGGR, #endif},.output_reg_addr ={.x_output = 0x034C,.y_output = 0x034E,.line_length_pclk = 0x0342,.frame_length_lines = 0x0340,},.exp_gain_info ={.coarse_int_time_addr = 0x0202,.global_gain_addr = 0x0204,.vert_offset = IMX258_MAX_INTEGRATION_MARGIN,},.aec_info ={.min_gain = IMX258_MIN_GAIN,.max_gain = IMX258_MAX_GAIN,.max_analog_gain = IMX258_MAX_AGAIN,.max_linecount = 65525 - IMX258_MAX_INTEGRATION_MARGIN,},.sensor_num_frame_skip = 2,.sensor_num_HDR_frame_skip = 2,.sensor_max_pipeline_frame_delay = 2,.sensor_property ={.pix_size = 1.12, /* um */.sensing_method = SENSOR_SMETHOD_ONE_CHIP_COLOR_AREA_SENSOR,.crop_factor = 5.78,},.pixel_array_size_info ={.active_array_size ={.width = 4208,.height = 3120,},.left_dummy = 8,.right_dummy = 8,.top_dummy = 8,.bottom_dummy = 8,},.color_level_info ={.white_level = 1023,.r_pedestal = IMX258_DATA_PEDESTAL,.gr_pedestal = IMX258_DATA_PEDESTAL,.gb_pedestal = IMX258_DATA_PEDESTAL,.b_pedestal = IMX258_DATA_PEDESTAL,},.start_settings ={.reg_setting_a = START_REG_ARRAY,.addr_type = CAMERA_I2C_WORD_ADDR,.data_type = CAMERA_I2C_BYTE_DATA,.delay = 0,},.stop_settings ={.reg_setting_a = STOP_REG_ARRAY,.addr_type = CAMERA_I2C_WORD_ADDR,.data_type = CAMERA_I2C_BYTE_DATA,.delay = 0,},.groupon_settings ={.reg_setting_a = GROUPON_REG_ARRAY,.addr_type = CAMERA_I2C_WORD_ADDR,.data_type = CAMERA_I2C_BYTE_DATA,.delay = 0,},.groupoff_settings ={.reg_setting_a = GROUPOFF_REG_ARRAY,.addr_type = CAMERA_I2C_WORD_ADDR,.data_type = CAMERA_I2C_BYTE_DATA,.delay = 0,},.dualcam_master_settings ={.reg_setting_a = DUALCAM_MASTER_REG_ARRAY,.addr_type = CAMERA_I2C_WORD_ADDR,.data_type = CAMERA_I2C_BYTE_DATA,.delay = 0,.size = 8,},.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,},.test_pattern_info ={.test_pattern_settings ={{.mode = SENSOR_TEST_PATTERN_OFF,.settings ={.reg_setting_a ={{0x0600, 0x0000, 0x00},},.addr_type = CAMERA_I2C_WORD_ADDR,.data_type = CAMERA_I2C_WORD_DATA,.delay = 0,}},{.mode = SENSOR_TEST_PATTERN_SOLID_COLOR,.settings ={.reg_setting_a ={{0x0600, 0x0001, 0x00},},.addr_type = CAMERA_I2C_WORD_ADDR,.data_type = CAMERA_I2C_WORD_DATA,.delay = 0,},},{.mode = SENSOR_TEST_PATTERN_COLOR_BARS,.settings ={.reg_setting_a ={{0x0600, 0x0002, 0x00},},.addr_type = CAMERA_I2C_WORD_ADDR,.data_type = CAMERA_I2C_WORD_DATA,.delay = 0,},},{.mode = SENSOR_TEST_PATTERN_COLOR_BARS_FADE_TO_GRAY,.settings ={.reg_setting_a ={{0x0600, 0x0003, 0x00},},.addr_type = CAMERA_I2C_WORD_ADDR,.data_type = CAMERA_I2C_WORD_DATA,.delay = 0,},},{.mode = SENSOR_TEST_PATTERN_PN9,.settings ={.reg_setting_a ={{0x0600, 0x0004, 0x00},},.addr_type = CAMERA_I2C_WORD_ADDR,.data_type = CAMERA_I2C_WORD_DATA,.delay = 0,},},},.size = 5,.solid_mode_addr ={.r_addr = 0x0602,.gr_addr = 0x0604,.gb_addr = 0x0608,.b_addr = 0x0606,},},.init_settings_array ={.reg_settings ={{.reg_setting_a = INIT0_REG_ARRAY,.addr_type = CAMERA_I2C_WORD_ADDR,.data_type = CAMERA_I2C_BYTE_DATA,.delay = 0,},{.reg_setting_a = FLIP_MIRROR_SETTING,.addr_type = CAMERA_I2C_WORD_ADDR,.data_type = CAMERA_I2C_BYTE_DATA,.delay = 0,},},.size = 2,},.res_settings_array ={.reg_settings ={/* Res 0 */{.reg_setting_a = RES0_REG_ARRAY,.addr_type = CAMERA_I2C_WORD_ADDR,.data_type = CAMERA_I2C_BYTE_DATA,.delay = 0,},/* Res 1 */{.reg_setting_a = RES1_REG_ARRAY,.addr_type = CAMERA_I2C_WORD_ADDR,.data_type = CAMERA_I2C_BYTE_DATA,.delay = 0,},/* Res 2 */{.reg_setting_a = RES2_REG_ARRAY,.addr_type = CAMERA_I2C_WORD_ADDR,.data_type = CAMERA_I2C_BYTE_DATA,.delay = 0,},/* Res 3 */{.reg_setting_a = RES3_REG_ARRAY,.addr_type = CAMERA_I2C_WORD_ADDR,.data_type = CAMERA_I2C_BYTE_DATA,.delay = 0,},/* Res 4 */{.reg_setting_a = RES4_REG_ARRAY,.addr_type = CAMERA_I2C_WORD_ADDR,.data_type = CAMERA_I2C_BYTE_DATA,.delay = 0,},/* Res 5 */{.reg_setting_a = RES5_REG_ARRAY,.addr_type = CAMERA_I2C_WORD_ADDR,.data_type = CAMERA_I2C_BYTE_DATA,.delay = 0,},},.size = 6,},.out_info_array ={.out_info ={ /* Res 0 */{.x_output = 4208,.y_output = 3120,.line_length_pclk = 5352,.frame_length_lines = 3224,.op_pixel_clk = 480000000,.binning_factor = 1,.min_fps = 7.500,.max_fps = 30.04,.mode = SENSOR_DEFAULT_MODE,.offset_x = 0,.offset_y = 0,.scale_factor = 1.000,.is_pdaf_supported = 1,.data_rate = 1296000000ULL * 4},/* Res 1 */{.x_output = 4208,.y_output = 2352,.line_length_pclk = 5352,.frame_length_lines = 2852,.op_pixel_clk = 458400000,.binning_factor = 1,.min_fps = 7.500,.max_fps = 30.03,.mode = SENSOR_DEFAULT_MODE,.offset_x = 0,.offset_y = 384,.scale_factor = 1.000,.is_pdaf_supported = 1,.data_rate = 1296000000ULL * 4},/* Res 2 */{.x_output = 2100,.y_output = 1560,.line_length_pclk = 5352,.frame_length_lines = 2851,.op_pixel_clk = 458400000,.binning_factor = 2,.min_fps = 7.500,.max_fps = 30.04,.mode = SENSOR_DEFAULT_MODE,.offset_x = 0,.offset_y = 0,.scale_factor = 1.000,.is_pdaf_supported = 0,.data_rate = 1296000000ULL * 4},/* Res 3*/{.x_output = 2100,.y_output = 1176,.line_length_pclk = 5352,.frame_length_lines = 1424,.op_pixel_clk = 458400000,.binning_factor = 2,.min_fps = 7.500,.max_fps = 60.14,.mode = SENSOR_HFR_MODE | SENSOR_DEFAULT_MODE,.offset_x = 0,.offset_y = 384,.scale_factor = 1.000,.is_pdaf_supported = 0,.data_rate = 1296000000ULL * 4},/* Res 4 */{.x_output = 1400,.y_output = 784,.line_length_pclk = 5352,.frame_length_lines = 948,.op_pixel_clk = 458400000,.binning_factor = 2,.min_fps = 7.500,.max_fps = 90.18,.mode = SENSOR_HFR_MODE,.offset_x = 0,.offset_y = 384,.scale_factor = 1.000,.is_pdaf_supported = 0,.data_rate = 1296000000ULL * 4},/* Res 5 */{.x_output = 1400,.y_output = 760,.line_length_pclk = 5352,.frame_length_lines = 828,.op_pixel_clk = 480000000,.binning_factor = 2,.min_fps = 7.500,.max_fps = 120.47,.mode = SENSOR_HFR_MODE,.offset_x = 0,.offset_y = 384,.scale_factor = 1.000,.is_pdaf_supported = 0,.data_rate = 1296000000ULL * 4},},.size = 6,},.csi_params ={.lane_cnt = 4,.settle_cnt = 0xB,.is_csi_3phase = 0,},.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 ={{/* set the meta half size which it should be to overcome the isp bug */.width = 80,.height = 1920,.stats_type = PD_STATS,.dt = IMX258_CSI_PD_ISTATS,},},.size = 1,},.sensor_capability = 0,.awb_func_table ={.sensor_fill_awb_array = 0,.awb_table_size = 0,},.parse_RDI_stats ={.parse_VHDR_stats = NULL,},.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,.sensor_num_fast_aec_frame_skip = 0,.noise_coeff = {.gradient_S = 3.738032e-06,.offset_S = 3.651935e-04,.gradient_O = 6.396835e-11,.offset_O = -2.968624e-04,},.pdaf_config = { #ifndef FLIP_MIRROR#include "imx258_pdaf.h" #else#include "imx258_pdaf_flip_mirror.h" #endif}, };#endif /* __IMX258_LIB_H__ */2.probe流程
hal層函數(shù) module_sensor_init()
hal層代碼位于?\vendor\qcom\proprietary\mm-camera\mm-camera2\media-controller\modules\sensors\module\module_sensor.c
//@\vendor\qcom\proprietary\mm-camera\mm-camera2\media-controller\modules\sensors\module\module_sensor.c mct_module_t *module_sensor_init(const char *name) {....../* module_sensor_probe_sensors */ret = sensor_init_probe(module_ctrl);/* find all the actuator, etc with sensor */ret = module_sensor_find_other_subdev(module_ctrl);/* Init sensor modules */ret = mct_list_traverse(module_ctrl->sensor_bundle, module_sensors_subinit,NULL);/* intiialize the eeprom */ret = mct_list_traverse(module_ctrl->sensor_bundle, module_sensor_init_eeprom,module_ctrl->eebin_hdl);/* Create chromatix manager */ret = mct_list_traverse(module_ctrl->sensor_bundle, module_sensor_init_chromatix, module_ctrl->eebin_hdl);/* Initialize dual cam stream mutex */pthread_mutex_init(&module_ctrl->dual_cam_mutex, NULL);}hal層函數(shù) sensor_init_probe()
在?sensor_init_eebin_probe()中,我們可以看出,知道camera 數(shù)量后,在for循環(huán)中,依次調(diào)用?sensor_probe()函數(shù)初始化每個camera,我們當(dāng)前代碼中有三個camera,這面就會調(diào)用三次sensor_probe()。
/** sensor_init_probe: probe available sensors** @module_ctrl: sensor ctrl pointer** Return: 0 for success and negative error on failure** 1) Find sensor_init subdev and it* 2) Open EEPROM subdev and check whether any sensor library* is present in EEPROM* 3) Open sensor libraries present in dumped firware location* 4) Check library version of EEPROM and dumped firmware* 5) Load latest of both* 6) Pass slave information, power up and probe sensors* 7) If probe succeeds, create video node and sensor subdev* 8) Repeat step 2-8 for all sensor libraries present in* EEPROM* 9) Repeat step 6-8 for all sensor libraries present in* absolute path**/boolean sensor_init_probe(module_sensor_ctrl_t *module_ctrl) {......ret = sensor_init_eebin_probe(module_ctrl, sd_fd);......RETURN_ON_FALSE(sensor_init_xml_probe(module_ctrl, sd_fd)); }static boolean sensor_init_eebin_probe(module_sensor_ctrl_t *module_ctrl,int32_t sd_fd) {SLOW("Enter");bin_ctl.cmd = EEPROM_BIN_GET_NUM_DEV;bin_ctl.ctl.q_num.type = EEPROM_BIN_LIB_SENSOR;bin_ctl.ctl.q_num.num_devs = 0;eebin_interface_control(module_ctrl->eebin_hdl, &bin_ctl);num_devs = bin_ctl.ctl.q_num.num_devs;SLOW("num_devs:%d", num_devs);for (i = 0; i < num_devs; i++ ) {bin_ctl.cmd = EEPROM_BIN_GET_DEV_DATA;bin_ctl.ctl.dev_data.type = EEPROM_BIN_LIB_SENSOR;bin_ctl.ctl.dev_data.num = i;rc = eebin_interface_control(module_ctrl->eebin_hdl, &bin_ctl);if (rc < 0)continue;ret = sensor_probe(module_ctrl,sd_fd,bin_ctl.ctl.dev_data.name,bin_ctl.ctl.dev_data.path,NULL,FALSE,FALSE);if (ret == FALSE) {SINFO("failed: to load %s", bin_ctl.ctl.dev_data.name);}}SLOW("Exit");return TRUE; }雖然前面也有 sensor_probe ,但正常流程中,我們走的不是eebin ,
而是通過 sensor_init_xml_probe(module_ctrl, sd_fd) 來解析
vendor/qcom/proprietary/mm-camera/mm-camera2/media-controller/modules/sensors/configs/sdm660_camera.xml 文件,
通過 xml 中 配置的sensor name 和 subdev name,來下發(fā)參數(shù)。
詳細如下:
->首先拼湊 sdm660_camera.xml 的字符串路徑
->odm 公司如果要自已定制路徑的話,也可以通過 屬性 persist.vendor.camera.customer.config 來配置。
->開始解析 sdm660_camera.xml文件中的 CameraConfigurationRoot 節(jié)點。
->通過 CameraModuleConfig 的數(shù)量可以知道 ,當(dāng)前支持多少個camera。
->解析每個camera 的信息,并且在 sensor_probe[]數(shù)組中檢查當(dāng)前sensor 是否已經(jīng)probe 過了。
->根據(jù)xml 中解析的結(jié)果,調(diào)用 sensor_probe 開始正式probe。
->當(dāng)所有xml 中的項都遍歷完成后,關(guān)閉xml。
hal層函數(shù) sensor_probe() 下發(fā) CFG_SINIT_PROBE
進入?sensor_probe()函數(shù):
在函數(shù)中可以看出,首先會調(diào)用?sensor_load_library()加載vendor 中camera sensor 的庫文件。
接著通過 IOCTRL 向通過下發(fā)?CFG_SINIT_PROBE消息,通知驅(qū)動層作probe 初始化。
Kernel Ioctl 函數(shù) msm_sensor_init_subdev_ioctl()
上層IOCTRL 命令下發(fā)到kernerl 中,進入msm_sensor_init_subdev_ioctl()中,接著轉(zhuǎn)發(fā)到msm_sensor_driver_cmd()中,調(diào)用?msm_sensor_driver_probe()函數(shù)..
// @\kernel\msm-4.4\drivers\media\platform\msm\camera_v2\sensor\msm_sensor_init.c static long msm_sensor_init_subdev_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) {switch (cmd) {case VIDIOC_MSM_SENSOR_INIT_CFG:rc = msm_sensor_driver_cmd(s_init, arg);break;} }/* Static function definition */ static int32_t msm_sensor_driver_cmd(struct msm_sensor_init_t *s_init, void *arg) {switch (cfg->cfgtype) {case CFG_SINIT_PROBE:mutex_lock(&s_init->imutex);s_init->module_init_status = 0;rc = msm_sensor_driver_probe(cfg->cfg.setting,&cfg->probed_info,cfg->entity_name);mutex_unlock(&s_init->imutex);if (rc < 0)pr_err("%s failed (non-fatal) rc %d", __func__, rc);break;case CFG_SINIT_PROBE_DONE:s_init->module_init_status = 1;wake_up(&s_init->state_wait);break;case CFG_SINIT_PROBE_WAIT_DONE:msm_sensor_wait_for_probe_done(s_init);break;return rc; }probe函數(shù) msm_sensor_driver_probe()
從上層開始下發(fā)probe 命令,至此正式開始probe 初始化 camera,代碼如下:
->初始化并分配 slave_info 內(nèi)存
->將上層下發(fā)的 slave_info保存在 slave_info32 中
->將 slave_info32 中的信息保存到 slave_info中。
->打印 slave info 信息
->通過camera id 獲取到對應(yīng)的 camera sensor ctrol 信息,也就是對應(yīng)的camera 的dts 信息。
->檢測sensor 是否已經(jīng)probe 過了,如果不是,直接跳過if 進行probe
->獲取camera的power settting
->初始化 msm_camera_slave_info 結(jié)構(gòu)體變量 camera_info ,用于保存 camera 的信息
->配置camera i2c 相關(guān)信息
->往s_ctrl 中填充 上下電相關(guān)信息
->解析該camera 中所有外設(shè) dts 節(jié)點信息 "qcom,eeprom-src"、"qcom,actuator-src"、"qcom,led-? ? ?flash-src"
->調(diào)用 sensor_power_up()給sensor 上電,開始probe sensor ,上電時調(diào)用 ->msm_sensor_check_id(),然后調(diào)用msm_sensor_match_id()檢測 sensor id 是否區(qū)配。
->創(chuàng)建對應(yīng)的 /dev/videox 節(jié)點 及 /dev/mediax 的節(jié)點
->probe 成功后下電
->更新s_ctrl 結(jié)構(gòu)體信息
?
3.camx-chi框架probe 流程?
Camx 剛接觸的時候?qū)τ谶@個xml 一臉懵逼,實際上和mm-camera差不多就是以xml node節(jié)點的方式標(biāo)準(zhǔn)化了driver相關(guān)的code,exposure 和 gain的邏輯實現(xiàn)還是在同級目錄的cpp中,并且將 xml 的解析工作放在了 out/target/<product>/gen/STATIC_LIBERARIES/libcamxgenerated_intermediates/generated/ 中主要是包含了:
g_chromatix : tuning 相關(guān)xml的解析code
g_facedetection :人臉檢測相關(guān)xml的解析code
g_parser :主要的解析manager 流程圖中的 imageSensorModuleDataManager 的 初始化調(diào)到了,此目錄下的paramtersetmanager.cpp 的 LoadBinaryParameters() 再根據(jù)type不同進行各個sub module xml 的讀取。
g_sensor:camera sensor xml 解析code,包括:actuator, eeprom, flash, moduleconfig, ois ,sensor, sensormodule, eebin主要看此目錄下的 camxsenordriver.cpp ,主要功能把 sensor driver xml 的各個節(jié)點內(nèi)容全都 load 一遍。看懂了這里剩下的就是 xml 的填空工作啦。
詳細的加載過程流程圖:
camx 的sensor probe 主要流程:
camera 的 probe success 主要需要 xml 中 salveAddress 、sensorIdRegAddr 、sensorID 和 powerUpSequence 這個4個參數(shù)(當(dāng)然還有一個前提是你的 kenrel 的i2c clock power gpio等配置的沒有問題),這時候還用不到 initsetting 等等其他參數(shù),畢竟你sensor 還沒有讀到正確寄存器值,詳細過程見流程圖。
參考鏈接:
?【高通SDM660平臺】(2) --- Camera Kernel 驅(qū)動層代碼邏輯分析_CielleeX的博客-CSDN博客
??????【高通SDM660平臺 Android 10.0】(10) --- Camera Sensor lib 與 Kernel Camera Probe 代碼分析_CielleeX的博客-CSDN博客
高通camera驅(qū)動 camx read xml 和 probe 流程 和 sensor I2C讀寫的波形圖 (三)_shangbolei的博客-CSDN博客_camera probe流程
?
總結(jié)
以上是生活随笔為你收集整理的Camera Probe 代码分析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: hdu 2188悼念512汶川大地震遇难
- 下一篇: Mantis-如何自定义流程状态