1000字范文,内容丰富有趣,学习的好帮手!
1000字范文 > android_驱动_qcom_【高通SDM660平台 Android 10.0】(10) --- Camera Sensor lib 与 Kernel Camera Probe 代码分析

android_驱动_qcom_【高通SDM660平台 Android 10.0】(10) --- Camera Sensor lib 与 Kernel Camera Probe 代码分析

时间:2023-07-25 20:45:22

相关推荐

android_驱动_qcom_【高通SDM660平台 Android 10.0】(10) --- Camera Sensor lib 与 Kernel Camera Probe 代码分析

【高通SDM660平台 Android 10.0】Camera Sensor lib 与 Kernel Camera Probe 代码分析

一、libmmcamera_imx258.so 代码分析1.1 struct sensor_lib_t 结构体1.2 imx258_lib.h 头文件分析二、 Kernel Camera Probe 代码分析2.1 msm_sensor_driver_probe() 代码分析2.1.1 创建 /dev/videoX、 /dev/v4l-subdevX 节点

《【高通SDM660平台】(1) — Camera 驱动 Bringup Guide》

《【高通SDM660平台】(2) — Camera Kernel 驱动层代码逻辑分析》

《【高通SDM660平台】(3) — Camera V4L2 驱动层分析 》

《【高通SDM660平台】(4) — Camera Init 初始化流程 》

《【高通SDM660平台】(5) — Camera Open 流程》

《【高通SDM660平台】(6) — Camera getParameters 及 setParameters 流程》

《【高通SDM660平台】(7) — Camera onPreview 代码流程》

《【高通SDM660平台】(8) — Camera MetaData介绍》

《【高通SDM660平台 Android 10.0】(9) — Qcom Camera Daemon 代码分析》

《【高通SDM660平台 Android 10.0】(10) — Camera Sensor lib 与 Kernel Camera Probe 代码分析》

《【高通SDM660平台】Camera Capture 流程》

《【高通SDM660平台】Camera mm-qcamera-app 代码分析》

在前面《【高通SDM660平台 Android 10.0】Qcom Camera Daemon 代码分析》 中,

我们分析了 Camera module_sensor_init() 的整个过程,考虑到篇幅的问题,本文是接module_sensor_init() 继续分析的。

主题如下:

分析 Camera lib 库的代码vendor 下发 CFG_SINIT_PROBE 后,Kernel 中 Camera Probe的流程

好, 开始吧!

一、libmmcamera_imx258.so 代码分析

Sensor LIB 库代码位于/vendor/qcom/proprietary/mm-camera/mm-camera2/media-controller/modules/sensors/sensor/libs

本文以 imx258 为例。

先来看下imx258_lib.c,其最核心的函数就是sensor_open_lib

返回sensor_lib_ptr结构体,所有的 Camera 信息,都保存在该结构体中。

@ /vendor/qcom/proprietary/mm-camera/mm-camera2/media-controller/modules/sensors/sensor/libs/imx258/imx258_lib.c

/**

FUNCTION: sensor_open_libDESCRIPTION: Open sensor library and returns data pointer

**/

void *sensor_open_lib(void)

{

return &sensor_lib_ptr;

} 12345678910

我们来看下sensor_lib_ptr结构体的定义

1.1 struct sensor_lib_t 结构体

@ /vendor/qcom/proprietary/mm-camerasdk/sensor/includes/sensor_lib.htypedef struct {/* sensor slave info */ // 从设备包括,I2C地址、I2C速率、Sensor_id 寄存器地址及Sensor_id 值、上下电的时序及电压值struct camera_sensor_slave_info sensor_slave_info;

/* sensor output settings */

// 包括 出图的格式(BAYER / YCbCr), 连接类型为 MIPI CSI

sensor_output_t sensor_output;

/* sensor output register address */

// 输出寄存器的地址,pclk,及line length pclk 、 frame length lines

struct 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 前丢弃过的 帧数

unsigned short sensor_num_frame_skip;

/* number of frames to skip after start HDR stream info */

// HDR 丢弃的帧数

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;

// 关闭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,数据传输速率

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;

<span class="token comment">/* sensor_awb_table_t */</span>

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 calculation

Tuning 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;

1234567891011121314151617181922232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811911122123124125126127128129

1.2 imx258_lib.h 头文件分析

@ /vendor/qcom/proprietary/mm-camera/mm-camera2/media-controller/modules/sensors/sensor/libs/imx258/imx258_lib.h

/* imx258_lib.h

*

Copyright © - Qualcomm Technologies, Inc.All Rights Reserved.Confidential and Proprietary - Qualcomm Technologies, Inc.

*/

#ifndefIMX258_LIB_H

#defineIMX258_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 to

enable flip and mirror in sensor readout

change bayer pattern

load 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, 对应的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 = 1296000000ULL4

},

/ 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*/

12345678910111213141516171819222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119111221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992000220320420520620720820921021121221321421521621721821921222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725

二、 Kernel Camera Probe 代码分析

前面我们mm-camera/mm-camera2/media-controller/modules/sensors/module/sensor_init.c中,会下发CFG_SINIT_PROBE给到kernel 中。

memset(&cfg, 0, sizeof(cfg));cfg.cfgtype = CFG_SINIT_PROBE;cfg.cfg.setting = slave_info;ioctl(fd, VIDIOC_MSM_SENSOR_INIT_CFG, &cfg);12345

Kernel 中处理的地方为:

@/kernel/msm-4.14/drivers/media/platform/msm/camera_v2/sensor/msm_sensor_init.c

/* Static function definition/

static int32_t msm_sensor_driver_cmd(struct msm_sensor_init_t s_init,voidarg)

{

struct sensor_init_cfg_data cfg = (struct sensor_init_cfg_data *)arg;

<span class="token keyword">switch</span> <span class="token punctuation">(</span>cfg<span class="token operator">-&gt;</span>cfgtype<span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token keyword">case</span> CFG_SINIT_PROBE<span class="token punctuation">:</span>s_init<span class="token operator">-&gt;</span>module_init_status <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>rc <span class="token operator">=</span> <span class="token function">msm_sensor_driver_probe</span><span class="token punctuation">(</span>cfg<span class="token operator">-&gt;</span>cfg<span class="token punctuation">.</span>setting<span class="token punctuation">,</span> <span class="token operator">&amp;</span>cfg<span class="token operator">-&gt;</span>probed_info<span class="token punctuation">,</span> cfg<span class="token operator">-&gt;</span>entity_name<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">break</span><span class="token punctuation">;</span>

}

12345678910111213

前面代码中,cfg.setting就是cfg.cfg.setting = slave_info;, 而最终probe的结果,保存在cfg->probed_info中。

2.1 msm_sensor_driver_probe() 代码分析

获取上层下发的slave_info 信息根据camera id 获取该camera 的控制函数如果已经probe 过了,则更新 probed_info 信息获取 power 上下电信息保存 Camera_info 结构体,包括 slave_addr,sensor id, setting填充上电信息填充下电信息更新外设设备信息解析eeprom、actuator、flash 等的dts 信息开始上电,上电后会进行check_id 操作,如果 sensor id 匹配成功,则返回成功将sensor 加加载到V4L2 subdev 中,创建 节点 /dev/videoX下电,保存 sensor_info 信息到 s_strl 中

@ /kernel/msm-4.14/drivers/media/platform/msm/camera_v2/sensor/msm_sensor_driver.c/* static function definition */int32_t msm_sensor_driver_probe(void *setting,struct msm_sensor_info_t *probed_info, char *entity_name){/* Allocate memory for slave info */slave_info = kzalloc(sizeof(*slave_info), GFP_KERNEL);{// 1. 获取上层下发的slave_info 信息。copy_from_user(slave_info, (void __user *)setting, sizeof(*slave_info));id_info = &(slave_info->sensor_id_info);reg_setting = kzalloc(id_info->setting.size * (sizeof(struct msm_camera_i2c_reg_array)), GFP_KERNEL);copy_from_user(reg_setting, (void __user *) slave_info->sensor_id_info.setting.reg_setting,slave_info->sensor_id_info.setting.size * sizeof(struct msm_camera_i2c_reg_array));slave_info->sensor_id_info.setting.reg_setting = reg_setting;}/* Print slave info */CDBG("camera id %d Slave addr 0x%X addr_type %d\n",slave_info->camera_id, slave_info->slave_addr,slave_info->addr_type);CDBG("sensor_id_reg_addr 0x%X sensor_id 0x%X sensor id mask %d",slave_info->sensor_id_info.sensor_id_reg_addr,slave_info->sensor_id_info.sensor_id,slave_info->sensor_id_info.sensor_id_mask);CDBG("power up size %d power down size %d\n",slave_info->power_setting_array.size,slave_info->power_setting_array.size_down);CDBG("position %d",slave_info->sensor_init_params.position);CDBG("mount %d",slave_info->sensor_init_params.sensor_mount_angle);CDBG("bypass video node creation %d",slave_info->bypass_video_node_creation);

<span class="token comment">// 2. 根据camera id 获取该camera 的控制函数</span><span class="token comment">/* Extract s_ctrl from camera id */</span>s_ctrl <span class="token operator">=</span> g_sctrl<span class="token punctuation">[</span>slave_info<span class="token operator">-&gt;</span>camera_id<span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token function">CDBG</span><span class="token punctuation">(</span><span class="token string">"s_ctrl[%d] %pK"</span><span class="token punctuation">,</span> slave_info<span class="token operator">-&gt;</span>camera_id<span class="token punctuation">,</span> s_ctrl<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">// 3. 如果已经probe 过了,则更新 probed_info 信息</span><span class="token keyword">if</span> <span class="token punctuation">(</span>s_ctrl<span class="token operator">-&gt;</span>is_probe_succeed <span class="token operator">==</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token comment">/* Different sensor on this camera slot has been connected* and probe already succeeded for that sensor. Ignore this probe */</span><span class="token keyword">if</span> <span class="token punctuation">(</span>slave_info<span class="token operator">-&gt;</span>sensor_id_info<span class="token punctuation">.</span>sensor_id <span class="token operator">==</span> s_ctrl<span class="token operator">-&gt;</span>sensordata<span class="token operator">-&gt;</span>cam_slave_info<span class="token operator">-&gt;</span>sensor_id_info<span class="token punctuation">.</span>sensor_id <span class="token operator">&amp;&amp;</span> <span class="token operator">!</span><span class="token punctuation">(</span><span class="token function">strcmp</span><span class="token punctuation">(</span>slave_info<span class="token operator">-&gt;</span>sensor_name<span class="token punctuation">,</span>s_ctrl<span class="token operator">-&gt;</span>sensordata<span class="token operator">-&gt;</span>cam_slave_info<span class="token operator">-&gt;</span>sensor_name<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token function">pr_err</span><span class="token punctuation">(</span><span class="token string">"slot%d: sensor name: %s sensor id%d already probed\n"</span><span class="token punctuation">,</span>slave_info<span class="token operator">-&gt;</span>camera_id<span class="token punctuation">,</span>slave_info<span class="token operator">-&gt;</span>sensor_name<span class="token punctuation">,</span>s_ctrl<span class="token operator">-&gt;</span>sensordata<span class="token operator">-&gt;</span>cam_slave_info<span class="token operator">-&gt;</span>sensor_id_info<span class="token punctuation">.</span>sensor_id<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">msm_sensor_fill_sensor_info</span><span class="token punctuation">(</span>s_ctrl<span class="token punctuation">,</span>probed_info<span class="token punctuation">,</span> entity_name<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span> rc <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span><span class="token keyword">goto</span> free_slave_info<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token comment">// 4.获取 power 上下电信息</span>rc <span class="token operator">=</span> <span class="token function">msm_sensor_get_power_settings</span><span class="token punctuation">(</span>setting<span class="token punctuation">,</span> slave_info<span class="token punctuation">,</span> <span class="token operator">&amp;</span>s_ctrl<span class="token operator">-&gt;</span>sensordata<span class="token operator">-&gt;</span>power_info<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">// 5. 保存 Camera_info 结构体,包括 slave_addr,sensor id, setting</span>camera_info <span class="token operator">=</span> <span class="token function">kzalloc</span><span class="token punctuation">(</span><span class="token keyword">sizeof</span><span class="token punctuation">(</span><span class="token keyword">struct</span> msm_camera_slave_info<span class="token punctuation">)</span><span class="token punctuation">,</span> GFP_KERNEL<span class="token punctuation">)</span><span class="token punctuation">;</span>s_ctrl<span class="token operator">-&gt;</span>sensordata<span class="token operator">-&gt;</span>slave_info <span class="token operator">=</span> camera_info<span class="token punctuation">;</span><span class="token comment">/* Fill sensor slave info */</span>camera_info<span class="token operator">-&gt;</span>sensor_slave_addr <span class="token operator">=</span> slave_info<span class="token operator">-&gt;</span>slave_addr<span class="token punctuation">;</span>camera_info<span class="token operator">-&gt;</span>sensor_id_reg_addr <span class="token operator">=</span> slave_info<span class="token operator">-&gt;</span>sensor_id_info<span class="token punctuation">.</span>sensor_id_reg_addr<span class="token punctuation">;</span>camera_info<span class="token operator">-&gt;</span>sensor_id <span class="token operator">=</span> slave_info<span class="token operator">-&gt;</span>sensor_id_info<span class="token punctuation">.</span>sensor_id<span class="token punctuation">;</span>camera_info<span class="token operator">-&gt;</span>sensor_id_mask <span class="token operator">=</span> slave_info<span class="token operator">-&gt;</span>sensor_id_info<span class="token punctuation">.</span>sensor_id_mask<span class="token punctuation">;</span>camera_info<span class="token operator">-&gt;</span>setting <span class="token operator">=</span> <span class="token operator">&amp;</span><span class="token punctuation">(</span>slave_info<span class="token operator">-&gt;</span>sensor_id_info<span class="token punctuation">.</span>setting<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">/* Fill sensor address type */</span>s_ctrl<span class="token operator">-&gt;</span>sensor_i2c_client<span class="token operator">-&gt;</span>addr_type <span class="token operator">=</span> slave_info<span class="token operator">-&gt;</span>addr_type<span class="token punctuation">;</span><span class="token keyword">if</span> <span class="token punctuation">(</span>s_ctrl<span class="token operator">-&gt;</span>sensor_i2c_client<span class="token operator">-&gt;</span>client<span class="token punctuation">)</span>s_ctrl<span class="token operator">-&gt;</span>sensor_i2c_client<span class="token operator">-&gt;</span>client<span class="token operator">-&gt;</span>addr <span class="token operator">=</span> camera_info<span class="token operator">-&gt;</span>sensor_slave_addr<span class="token punctuation">;</span>cci_client <span class="token operator">=</span> s_ctrl<span class="token operator">-&gt;</span>sensor_i2c_client<span class="token operator">-&gt;</span>cci_client<span class="token punctuation">;</span>cci_client<span class="token operator">-&gt;</span>cci_i2c_master <span class="token operator">=</span> s_ctrl<span class="token operator">-&gt;</span>cci_i2c_master<span class="token punctuation">;</span>cci_client<span class="token operator">-&gt;</span>sid <span class="token operator">=</span> slave_info<span class="token operator">-&gt;</span>slave_addr <span class="token operator">&gt;&gt;</span> <span class="token number">1</span><span class="token punctuation">;</span>cci_client<span class="token operator">-&gt;</span>retries <span class="token operator">=</span> <span class="token number">3</span><span class="token punctuation">;</span>cci_client<span class="token operator">-&gt;</span>id_map <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>cci_client<span class="token operator">-&gt;</span>i2c_freq_mode <span class="token operator">=</span> slave_info<span class="token operator">-&gt;</span>i2c_freq_mode<span class="token punctuation">;</span><span class="token comment">// 6. 填充上电信息</span><span class="token comment">/* Parse and fill vreg params for powerup settings */</span>rc <span class="token operator">=</span> <span class="token function">msm_camera_fill_vreg_params</span><span class="token punctuation">(</span>s_ctrl<span class="token operator">-&gt;</span>sensordata<span class="token operator">-&gt;</span>power_info<span class="token punctuation">.</span>cam_vreg<span class="token punctuation">,</span>s_ctrl<span class="token operator">-&gt;</span>sensordata<span class="token operator">-&gt;</span>power_info<span class="token punctuation">.</span>num_vreg<span class="token punctuation">,</span>s_ctrl<span class="token operator">-&gt;</span>sensordata<span class="token operator">-&gt;</span>power_info<span class="token punctuation">.</span>power_setting<span class="token punctuation">,</span>s_ctrl<span class="token operator">-&gt;</span>sensordata<span class="token operator">-&gt;</span>power_info<span class="token punctuation">.</span>power_setting_size<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">// 7. 填充下电信息</span><span class="token comment">/* Parse and fill vreg params for powerdown settings*/</span>rc <span class="token operator">=</span> <span class="token function">msm_camera_fill_vreg_params</span><span class="token punctuation">(</span>s_ctrl<span class="token operator">-&gt;</span>sensordata<span class="token operator">-&gt;</span>power_info<span class="token punctuation">.</span>cam_vreg<span class="token punctuation">,</span>s_ctrl<span class="token operator">-&gt;</span>sensordata<span class="token operator">-&gt;</span>power_info<span class="token punctuation">.</span>num_vreg<span class="token punctuation">,</span>s_ctrl<span class="token operator">-&gt;</span>sensordata<span class="token operator">-&gt;</span>power_info<span class="token punctuation">.</span>power_down_setting<span class="token punctuation">,</span>s_ctrl<span class="token operator">-&gt;</span>sensordata<span class="token operator">-&gt;</span>power_info<span class="token punctuation">.</span>power_down_setting_size<span class="token punctuation">)</span><span class="token punctuation">;</span>

CSID_TG:

/* Update sensor, actuator and eeprom name in

* sensor control structure

/

// 8. 更新外设设备信息

s_ctrl->sensordata->sensor_name = slave_info->sensor_name;

s_ctrl->sensordata->eeprom_name = slave_info->eeprom_name;

s_ctrl->sensordata->actuator_name = slave_info->actuator_name;

s_ctrl->sensordata->ois_name = slave_info->ois_name;

s_ctrl->sensordata->flash_name = slave_info->flash_name;

// 9. 解析eeprom、actuator、flash 等的dts 信息

/ Update eeporm subdevice Id by input eeprom name/

rc = msm_sensor_fill_eeprom_subdevid_by_name(s_ctrl);

/ Update actuator subdevice Id by input actuator name */

rc = msm_sensor_fill_actuator_subdevid_by_name(s_ctrl);

rc = msm_sensor_fill_laser_led_subdevid_by_name(s_ctrl);

rc = msm_sensor_fill_ois_subdevid_by_name(s_ctrl);

rc = msm_sensor_fill_flash_subdevid_by_name(s_ctrl);

<span class="token comment">// 10. 开始上电,上电后会进行check_id 操作,如果 sensor id 匹配成功,则返回成功,</span><span class="token comment">/* Power up and probe sensor */</span>rc <span class="token operator">=</span> s_ctrl<span class="token operator">-&gt;</span>func_tbl<span class="token operator">-&gt;</span><span class="token function">sensor_power_up</span><span class="token punctuation">(</span>s_ctrl<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">&gt;</span><span class="token operator">+</span>@ <span class="token operator">/</span>kernel<span class="token operator">/</span>msm<span class="token operator">-</span><span class="token number">4.14</span><span class="token operator">/</span>drivers<span class="token operator">/</span>media<span class="token operator">/</span>platform<span class="token operator">/</span>msm<span class="token operator">/</span>camera_v2<span class="token operator">/</span>sensor<span class="token operator">/</span>msm_sensor<span class="token punctuation">.</span>c<span class="token operator">+</span><span class="token keyword">static</span> <span class="token keyword">struct</span> msm_sensor_fn_t msm_sensor_func_tbl <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token operator">+</span><span class="token punctuation">.</span>sensor_config <span class="token operator">=</span> msm_sensor_config<span class="token punctuation">,</span><span class="token operator">+</span><span class="token punctuation">.</span>sensor_power_up <span class="token operator">=</span> msm_sensor_power_up<span class="token punctuation">,</span><span class="token operator">+</span><span class="token punctuation">.</span>sensor_power_down <span class="token operator">=</span> msm_sensor_power_down<span class="token punctuation">,</span><span class="token operator">+</span><span class="token punctuation">.</span>sensor_match_id <span class="token operator">=</span> msm_sensor_match_id<span class="token punctuation">,</span><span class="token operator">+</span><span class="token punctuation">}</span><span class="token punctuation">;</span><span class="token operator">+</span><span class="token operator">+</span>rc <span class="token operator">=</span> <span class="token function">msm_camera_power_up</span><span class="token punctuation">(</span>power_info<span class="token punctuation">,</span> s_ctrl<span class="token operator">-&gt;</span>sensor_device_type<span class="token punctuation">,</span> sensor_i2c_client<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token operator">+</span>rc <span class="token operator">=</span> <span class="token function">msm_sensor_check_id</span><span class="token punctuation">(</span>s_ctrl<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token operator">&lt;=</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">=</span><span class="token function">pr_err</span><span class="token punctuation">(</span><span class="token string">"%s probe succeeded"</span><span class="token punctuation">,</span> slave_info<span class="token operator">-&gt;</span>sensor_name<span class="token punctuation">)</span><span class="token punctuation">;</span>s_ctrl<span class="token operator">-&gt;</span>bypass_video_node_creation <span class="token operator">=</span> slave_info<span class="token operator">-&gt;</span>bypass_video_node_creation<span class="token punctuation">;</span><span class="token comment">/** Create /dev/videoX node, comment for now until dummy /dev/videoX* node is created and used by HAL*/</span><span class="token comment">// 11. 将sensor 加加载到V4L2 subdev 中,创建 节点 /dev/videoX</span><span class="token keyword">if</span> <span class="token punctuation">(</span>s_ctrl<span class="token operator">-&gt;</span>sensor_device_type <span class="token operator">==</span> MSM_CAMERA_PLATFORM_DEVICE<span class="token punctuation">)</span>rc <span class="token operator">=</span> <span class="token function">msm_sensor_driver_create_v4l_subdev</span><span class="token punctuation">(</span>s_ctrl<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">else</span>rc <span class="token operator">=</span> <span class="token function">msm_sensor_driver_create_i2c_v4l_subdev</span><span class="token punctuation">(</span>s_ctrl<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">// 12. 下电,保存 sensor_info 信息到 s_strl 中。</span><span class="token comment">/* Power down */</span>s_ctrl<span class="token operator">-&gt;</span>func_tbl<span class="token operator">-&gt;</span><span class="token function">sensor_power_down</span><span class="token punctuation">(</span>s_ctrl<span class="token punctuation">)</span><span class="token punctuation">;</span>rc <span class="token operator">=</span> <span class="token function">msm_sensor_fill_slave_info_init_params</span><span class="token punctuation">(</span>slave_info<span class="token punctuation">,</span> s_ctrl<span class="token operator">-&gt;</span>sensordata<span class="token operator">-&gt;</span>sensor_info<span class="token punctuation">)</span><span class="token punctuation">;</span>rc <span class="token operator">=</span> <span class="token function">msm_sensor_validate_slave_info</span><span class="token punctuation">(</span>s_ctrl<span class="token operator">-&gt;</span>sensordata<span class="token operator">-&gt;</span>sensor_info<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">/*Save sensor info*/</span>s_ctrl<span class="token operator">-&gt;</span>sensordata<span class="token operator">-&gt;</span>cam_slave_info <span class="token operator">=</span> slave_info<span class="token punctuation">;</span><span class="token function">msm_sensor_fill_sensor_info</span><span class="token punctuation">(</span>s_ctrl<span class="token punctuation">,</span> probed_info<span class="token punctuation">,</span> entity_name<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">/** Set probe succeeded flag to 1 so that no other camera shall* probed on this slot*/</span>s_ctrl<span class="token operator">-&gt;</span>is_probe_succeed <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span><span class="token keyword">return</span> rc<span class="token punctuation">;</span>

}

1234567891011121314151617181922232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811911122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162

2.1.1 创建 /dev/videoX、 /dev/v4l-subdevX 节点

创建 /dev/videoX 节点初始化 s_ctrl->msm_sd.sd 节构体信息,将ops 绑定到 sd 中更新 subdev 信息,并注册subdev将 subdev 添回到 subdev list 链表中创建 /dev/v4l-subdevX 节点

@ msm-4.14/drivers/media/platform/msm/camera_v2/sensor/msm_sensor_driver.cstatic int32_t msm_sensor_driver_create_v4l_subdev(struct msm_sensor_ctrl_t *s_ctrl){// 1. 创建 /dev/videoX 字付设备节点if (s_ctrl->bypass_video_node_creation == 0) {rc = camera_init_v4l2(&s_ctrl->pdev->dev, &session_id);=============>+@ msm-4.14/drivers/media/platform/msm/camera_v2/camera/camera.c+strlcpy(pvdev->vdev->name, "msm-sensor", sizeof(pvdev->vdev->name));+pvdev->vdev->fops= &camera_v4l2_fops;+pvdev->vdev->ioctl_ops = &camera_v4l2_ioctl_ops;+video_register_device(pvdev->vdev,VFL_TYPE_GRABBER, -1);+----------------->+@ msm-4.14/include/media/v4l2-dev.h+__video_register_device(vdev, type, nr, 1, vdev->fops->owner);+------------>+name_base = "video";+/* Pick a device node number */+minor_offset = 0;+minor_cnt = 64;+nr = devnode_find(vdev, 0, minor_cnt);+video_device[vdev->minor] = vdev;+/* Part 3: Initialize the character device */+vdev->cdev->ops = &v4l2_fops;+vdev->cdev->owner = owner;+ret = cdev_add(vdev->cdev, MKDEV(VIDEO_MAJOR, vdev->minor), 1);+/* Part 4: register the device with sysfs */+vdev->dev.class = &video_class;+vdev->dev.devt = MKDEV(VIDEO_MAJOR, vdev->minor);+vdev->dev.parent = vdev->dev_parent;+dev_set_name(&vdev->dev, "%s%d", name_base, vdev->num);+ret = device_register(&vdev->dev);+<------------+<-----------------<=============}

<span class="token function">CDBG</span><span class="token punctuation">(</span><span class="token string">"rc %d session_id %d"</span><span class="token punctuation">,</span> rc<span class="token punctuation">,</span> session_id<span class="token punctuation">)</span><span class="token punctuation">;</span>s_ctrl<span class="token operator">-&gt;</span>sensordata<span class="token operator">-&gt;</span>sensor_info<span class="token operator">-&gt;</span>session_id <span class="token operator">=</span> session_id<span class="token punctuation">;</span><span class="token comment">// 2. 初始化 s_ctrl-&gt;msm_sd.sd 节构体信息,将ops 绑定到 sd 中</span><span class="token comment">/* Create /dev/v4l-subdevX device */</span><span class="token function">v4l2_subdev_init</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>s_ctrl<span class="token operator">-&gt;</span>msm_sd<span class="token punctuation">.</span>sd<span class="token punctuation">,</span> s_ctrl<span class="token operator">-&gt;</span>sensor_v4l2_subdev_ops<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">// 3. 更新 subdev 信息,并注册</span><span class="token comment">// imx258</span><span class="token function">snprintf</span><span class="token punctuation">(</span>s_ctrl<span class="token operator">-&gt;</span>msm_sd<span class="token punctuation">.</span>sd<span class="token punctuation">.</span>name<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>s_ctrl<span class="token operator">-&gt;</span>msm_sd<span class="token punctuation">.</span>sd<span class="token punctuation">.</span>name<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string">"%s"</span><span class="token punctuation">,</span>s_ctrl<span class="token operator">-&gt;</span>sensordata<span class="token operator">-&gt;</span>sensor_name<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">v4l2_set_subdevdata</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>s_ctrl<span class="token operator">-&gt;</span>msm_sd<span class="token punctuation">.</span>sd<span class="token punctuation">,</span> s_ctrl<span class="token operator">-&gt;</span>pdev<span class="token punctuation">)</span><span class="token punctuation">;</span>s_ctrl<span class="token operator">-&gt;</span>msm_sd<span class="token punctuation">.</span>sd<span class="token punctuation">.</span>flags <span class="token operator">|</span><span class="token operator">=</span> V4L2_SUBDEV_FL_HAS_DEVNODE<span class="token punctuation">;</span><span class="token function">media_entity_pads_init</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>s_ctrl<span class="token operator">-&gt;</span>msm_sd<span class="token punctuation">.</span>sd<span class="token punctuation">.</span>entity<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token constant">NULL</span><span class="token punctuation">)</span><span class="token punctuation">;</span>s_ctrl<span class="token operator">-&gt;</span>msm_sd<span class="token punctuation">.</span>sd<span class="token punctuation">.</span>entity<span class="token punctuation">.</span>function <span class="token operator">=</span> MSM_CAMERA_SUBDEV_SENSOR<span class="token punctuation">;</span>s_ctrl<span class="token operator">-&gt;</span>msm_sd<span class="token punctuation">.</span>sd<span class="token punctuation">.</span>entity<span class="token punctuation">.</span>name <span class="token operator">=</span> s_ctrl<span class="token operator">-&gt;</span>msm_sd<span class="token punctuation">.</span>sd<span class="token punctuation">.</span>name<span class="token punctuation">;</span> <span class="token comment">// imx258</span>s_ctrl<span class="token operator">-&gt;</span>msm_sd<span class="token punctuation">.</span>close_seq <span class="token operator">=</span> MSM_SD_CLOSE_2ND_CATEGORY <span class="token operator">|</span> <span class="token number">0x3</span><span class="token punctuation">;</span>rc <span class="token operator">=</span> <span class="token function">msm_sd_register</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>s_ctrl<span class="token operator">-&gt;</span>msm_sd<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">=</span><span class="token operator">&gt;</span>@ msm<span class="token operator">-</span><span class="token number">4.14</span><span class="token operator">/</span>drivers<span class="token operator">/</span>media<span class="token operator">/</span>platform<span class="token operator">/</span>msm<span class="token operator">/</span>camera_v2<span class="token operator">/</span>msm<span class="token punctuation">.</span>c<span class="token function">__msm_sd_register_subdev</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>msm_subdev<span class="token operator">-&gt;</span>sd<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">-&gt;</span><span class="token comment">// 3.1 将 subdev 添回到 subdev list 链表中</span>rc <span class="token operator">=</span> <span class="token function">v4l2_device_register_subdev</span><span class="token punctuation">(</span>msm_v4l2_dev<span class="token punctuation">,</span> sd<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">-&gt;</span><span class="token function">list_add_tail</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>sd<span class="token operator">-&gt;</span>list<span class="token punctuation">,</span> <span class="token operator">&amp;</span>v4l2_dev<span class="token operator">-&gt;</span>subdevs<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token operator">&lt;</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">-</span><span class="token function">strlcpy</span><span class="token punctuation">(</span>vdev<span class="token operator">-&gt;</span>name<span class="token punctuation">,</span> sd<span class="token operator">-&gt;</span>name<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>vdev<span class="token operator">-&gt;</span>name<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">// imx258</span>vdev<span class="token operator">-&gt;</span>v4l2_dev <span class="token operator">=</span> msm_v4l2_dev<span class="token punctuation">;</span>vdev<span class="token operator">-&gt;</span>fops <span class="token operator">=</span> <span class="token function">msm_cam_get_v4l2_subdev_fops_ptr</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>vdev<span class="token operator">-&gt;</span>release <span class="token operator">=</span> msm_sd_unregister_subdev<span class="token punctuation">;</span><span class="token comment">// 3.2 创建 /dev/v4l-subdevX 节点</span>rc <span class="token operator">=</span> <span class="token function">__video_register_device</span><span class="token punctuation">(</span>vdev<span class="token punctuation">,</span> VFL_TYPE_SUBDEV<span class="token punctuation">,</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">,</span>sd<span class="token operator">-&gt;</span>owner<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">-&gt;</span>@ msm<span class="token operator">-</span><span class="token number">4.14</span><span class="token operator">/</span>drivers<span class="token operator">/</span>media<span class="token operator">/</span>v4l2<span class="token operator">-</span>core<span class="token operator">/</span>v4l2<span class="token operator">-</span>dev<span class="token punctuation">.</span>cname_base <span class="token operator">=</span> <span class="token string">"v4l-subdev"</span><span class="token punctuation">;</span>minor_offset <span class="token operator">=</span> <span class="token number">128</span><span class="token punctuation">;</span>minor_cnt <span class="token operator">=</span> <span class="token number">64</span><span class="token punctuation">;</span><span class="token comment">/* Pick a device node number */</span>nr <span class="token operator">=</span> <span class="token function">devnode_find</span><span class="token punctuation">(</span>vdev<span class="token punctuation">,</span> nr <span class="token operator">==</span> <span class="token operator">-</span><span class="token number">1</span> <span class="token operator">?</span> <span class="token number">0</span> <span class="token punctuation">:</span> nr<span class="token punctuation">,</span> minor_cnt<span class="token punctuation">)</span><span class="token punctuation">;</span>video_device<span class="token punctuation">[</span>vdev<span class="token operator">-&gt;</span>minor<span class="token punctuation">]</span> <span class="token operator">=</span> vdev<span class="token punctuation">;</span><span class="token comment">/* Part 3: Initialize the character device */</span>vdev<span class="token operator">-&gt;</span>cdev<span class="token operator">-&gt;</span>ops <span class="token operator">=</span> <span class="token operator">&amp;</span>v4l2_fops<span class="token punctuation">;</span>vdev<span class="token operator">-&gt;</span>cdev<span class="token operator">-&gt;</span>owner <span class="token operator">=</span> owner<span class="token punctuation">;</span>ret <span class="token operator">=</span> <span class="token function">cdev_add</span><span class="token punctuation">(</span>vdev<span class="token operator">-&gt;</span>cdev<span class="token punctuation">,</span> <span class="token function">MKDEV</span><span class="token punctuation">(</span>VIDEO_MAJOR<span class="token punctuation">,</span> vdev<span class="token operator">-&gt;</span>minor<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">/* Part 4: register the device with sysfs */</span>vdev<span class="token operator">-&gt;</span>dev<span class="token punctuation">.</span>class <span class="token operator">=</span> <span class="token operator">&amp;</span>video_class<span class="token punctuation">;</span>vdev<span class="token operator">-&gt;</span>dev<span class="token punctuation">.</span>devt <span class="token operator">=</span> <span class="token function">MKDEV</span><span class="token punctuation">(</span>VIDEO_MAJOR<span class="token punctuation">,</span> vdev<span class="token operator">-&gt;</span>minor<span class="token punctuation">)</span><span class="token punctuation">;</span>vdev<span class="token operator">-&gt;</span>dev<span class="token punctuation">.</span>parent <span class="token operator">=</span> vdev<span class="token operator">-&gt;</span>dev_parent<span class="token punctuation">;</span><span class="token function">dev_set_name</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>vdev<span class="token operator">-&gt;</span>dev<span class="token punctuation">,</span> <span class="token string">"%s%d"</span><span class="token punctuation">,</span> name_base<span class="token punctuation">,</span> vdev<span class="token operator">-&gt;</span>num<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// v4l-subdevX</span>ret <span class="token operator">=</span> <span class="token function">device_register</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>vdev<span class="token operator">-&gt;</span>dev<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token operator">&lt;</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">-</span><span class="token operator">&lt;</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">-</span><span class="token operator">&lt;=</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token function">msm_cam_copy_v4l2_subdev_fops</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>msm_sensor_v4l2_subdev_fops<span class="token punctuation">)</span><span class="token punctuation">;</span>

#ifdef CONFIG_COMPAT

pat_ioctl32 = msm_sensor_subdev_fops_ioctl;

#endif

s_ctrl->msm_sd.sd.devnode->fops = &msm_sensor_v4l2_subdev_fops;

<span class="token keyword">return</span> rc<span class="token punctuation">;</span>

}

12345678910111213141516171819222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899

至此,整个probe 过程就 完毕了。

</div><link href="/release/phoenix/mdeditor/markdown_views-60ecaf1f42.css" rel="stylesheet"></div>

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。