高通Camera移植文档 | 您所在的位置:网站首页 › 摄像头驱动移植 › 高通Camera移植文档 |
高通Camera移植文档
此文档以在高通8916平台移植OV5648为例,蓝色字体为注释,红色字体为重要点。 一、Kernel 部分 1.1 添加Device Tree代码: 代码路径:srcLINUXandroidkernelarcharmbootdtsqcom 文件名:msm8916-camera-sensor-qrd-skui.dtsi 需添加的代码: qcom,camera@6a { ——这需要与1.3节中添加的Clock地址向对应。 compatible = "ovti,ov5648"; ——这要与1.5节中添加的驱动代码中的名字相对应,即:static const struct of_device_id ov5648_dt_match[] = { { .compatible = "ovti,ov5648", .data = &ov5648_s_ctrl }, reg = ; ——这需要与1.3节中添加的Clock地址向对应。 qcom,slave-id = ; ——0x6c为摄像头的I2C地址,0x300a为摄像头存放ID的寄存器地址,0x5648为摄像头的ID,这都需要查看datasheet或直接问模组厂。 qcom,csiphy-sd-index = ; qcom,csid-sd-index = ; ——以上两个设置需要查看主板原理图,看主板上摄像头是接在CSI0还是CSI1上的,一般后摄像头都会接到CSI0上,前摄像头会接在CSI1上。 qcom,mount-angle = ; ——该参数为摄像头预览界面的方向,如果预览方向有被旋转,可以通过修改这个参数进行修正。 qcom,sensor-name = "ov5648_oty5f03"; ——这个对应vendor中lib文件夹的文件名,具体可参看2.2节。 cam_vdig-supply = ; cam_vana-supply = ; cam_vio-supply = ; ——以上三个参数分别对应DVDD(vdig)、AVDD(vana)、DOVDD(vio)三个电压,具体所接的是哪路电压,需要参看主板原理图。 qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana"; qcom,cam-vreg-type = ; qcom,cam-vreg-min-voltage = ; qcom,cam-vreg-max-voltage = ; qcom,cam-vreg-op-mode = ; ——这五个配置要分别与上面的三个电压一一对应(按照从上到下的顺序),如果有对焦马达的还要在后面填一路AF的电压,如下所示: cam_vaf-supply = ; qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana", "cam_vaf"; qcom,cam-vreg-type = ; qcom,cam-vreg-min-voltage = ; qcom,cam-vreg-max-voltage = ; qcom,cam-vreg-op-mode = ;
pinctrl-names = "cam_default", "cam_suspend"; pinctrl-0 = ; pinctrl-1 = ; ——以上这两个需要区分的就是前后摄像头的配置不一样,上面这种配置是前摄像头的配置,后摄像头的配置如下所示: pinctrl-names = "cam_default", "cam_suspend"; pinctrl-0 = ; pinctrl-1 = ;
gpios = , , , ; qcom,gpio-reset = ; qcom,gpio-standby = ; qcom,gpio-vana = ; qcom,gpio-req-tbl-num = ; qcom,gpio-req-tbl-flags = ; qcom,gpio-req-tbl-label = "CAMIF_MCLK", "CAM_RESET", "CAM_STANDBY", "CAM_VANA"; ——上面这部分主要是配置GPIO口,这里需要注意的是gpios的数组要与gpio-req-tbl-label的名字一一对应,即gpio 27对应CAMIF_MCLK,而reset 、standby 、vana 分别对应gpios数组中的第1、2、3参数,gpio-req-tbl-num也对应于gpios中数组的标号。 qcom,gpio-set-tbl-num = ; qcom,gpio-set-tbl-flags = ; qcom,gpio-set-tbl-delay = ; ——这三个参数是前摄像头的固定模式,后摄像头不需要这个设置,在配置后摄像头时直接去掉即可。 qcom,csi-lane-assign = ; ——该参数为主芯片mipi Lane个数配置寄存器。 qcom,csi-lane-mask = ; ——该参数为配置mipi Lane个数,0x3为1组数据线加1组时钟线,0x07为2组数据线加1组时钟线,0x1f为4组数据线加1主时钟线。 qcom,sensor-position = ; ——该参数,如果添加的是前摄像头需要配置成1,如果是后摄像头需要配置成0 qcom,sensor-mode = ; qcom,cci-master = ; status = "ok"; clocks = , ; clock-names = "cam_src_clk", "cam_clk"; ——上面两个Clocks和Clock-names是前摄像头的配置,后摄像头的配置如下: clocks = , ; clock-names = "cam_src_clk", "cam_clk"; }; 另外如果有对焦马达还需要修改对焦马达的地址,如下所示: actuator0: qcom,actuator@6e { cell-index = ; reg = ; compatible = "qcom,actuator"; qcom,cci-master = ; }; 1.2 添加宏开关: 代码路径:srcLINUXandroidkernelarcharmconfigs 文件名:msm8916_defconfig 和msm8916-perf_defconfig 需添加的代码: CONFIG_OV5648=y 1.3 添加Clock: 代码路径:srcLINUXandroidkernelarcharmmach-msm 文件名:clock-8226.c 需添加的代码: /* MM sensor clocks */ CLK_LOOKUP("cam_src_clk", mclk0_clk_src.c, "6f.qcom,camera"), CLK_LOOKUP("cam_src_clk", mclk1_clk_src.c, "90.qcom,camera"), CLK_LOOKUP("cam_src_clk", mclk0_clk_src.c, "6d.qcom,camera"), CLK_LOOKUP("cam_src_clk", mclk0_clk_src.c, "6a.qcom,camera"), CLK_LOOKUP("cam_src_clk", mclk0_clk_src.c, "6c.qcom,camera"), CLK_LOOKUP("cam_src_clk", mclk0_clk_src.c, "20.qcom,camera"), CLK_LOOKUP("cam_src_clk", mclk0_clk_src.c, "78.qcom,camera"), CLK_LOOKUP("cam_clk", camss_mclk0_clk.c, "6f.qcom,camera"), CLK_LOOKUP("cam_clk", camss_mclk1_clk.c, "90.qcom,camera"), CLK_LOOKUP("cam_clk", camss_mclk0_clk.c, "6d.qcom,camera"), CLK_LOOKUP("cam_clk", camss_mclk0_clk.c, "6a.qcom,camera"), CLK_LOOKUP("cam_clk", camss_mclk0_clk.c, "6c.qcom,camera"), CLK_LOOKUP("cam_clk", camss_mclk0_clk.c, "78.qcom,camera"), CLK_LOOKUP("cam_clk", camss_mclk0_clk.c, "20.qcom,camera"), CLK_LOOKUP("cam_src_clk", mclk0_clk_src.c, "62.qcom,camera"), CLK_LOOKUP("cam_clk", camss_mclk0_clk.c, "62.qcom,camera"), CLK_LOOKUP("cam_src_clk", mclk0_clk_src.c, "0.qcom,camera"), CLK_LOOKUP("cam_src_clk", mclk0_clk_src.c, "1.qcom,camera"), CLK_LOOKUP("cam_clk", camss_mclk0_clk.c, "0.qcom,camera"), CLK_LOOKUP("cam_clk", camss_mclk0_clk.c, "1.qcom,camera"), 需要注意的是这里的标示(如:6a)不能重复,并且添加的时候需要同时添加一组代码,即上面红色标示的地方。 1.4 Kconfig和Makefile文件中添加对应IC代码:代码路径:srcLINUXandroidkerneldriversmediaplatformmsmcamera_v2(Kconfig路径),srcLINUXandroidkerneldriversmediaplatformmsmcamera_v2sensor(Makefile路径) 文件名:Kconfig和Makefile 需添加的代码: 添加Kconfig: config OV5648 bool "Sensor OV5648 (BAYER 5M)" depends on MSMB_CAMERA ---help--- OmniVision 5 MP Bayer Sensor, only use 1 mipi lane, preview set to 1296*972 at 30 fps, snapshot set to 2592*1944 at 12 fps, This sensor driver does not support auto focus. 添加Makefile: obj-$(CONFIG_OV5648) += ov5648.o 1.5 添加Camera驱动代码: 代码路径:srcLINUXandroidkerneldriversmediaplatformmsmcamera_v2sensor 文件名:ov5648.c 需添加的代码: 该部分主要要注意电源的设置,它包括传感器电源信息,IO控制和Mclk。通常情况下,无需修改该部分内容,因为大部分配置已在设备树文件中完成;但可以修改.delay = 0 字段来和时间匹配。 static struct msm_sensor_power_setting ov5648_power_setting[] = { { .seq_type = SENSOR_VREG, .seq_val = CAM_VIO, .config_val = 0, .delay = 0, }, { .seq_type = SENSOR_VREG, .seq_val = CAM_VAF, .config_val = 0, .delay = 5, }, { .seq_type = SENSOR_GPIO, .seq_val = SENSOR_GPIO_VDIG, .config_val = GPIO_OUT_LOW, .delay = 5, }, { .seq_type = SENSOR_GPIO, .seq_val = SENSOR_GPIO_VDIG, .config_val = GPIO_OUT_HIGH, .delay = 5, }, { .seq_type = SENSOR_GPIO, .seq_val = SENSOR_GPIO_VANA, .config_val = GPIO_OUT_HIGH, .delay = 5, }, { .seq_type = SENSOR_GPIO, .seq_val = SENSOR_GPIO_STANDBY, .config_val = GPIO_OUT_LOW, .delay = 5, }, { .seq_type = SENSOR_GPIO, .seq_val = SENSOR_GPIO_STANDBY, .config_val = GPIO_OUT_HIGH, .delay = 10, }, { .seq_type = SENSOR_GPIO, .seq_val = SENSOR_GPIO_RESET, .config_val = GPIO_OUT_LOW, .delay = 5, }, { .seq_type = SENSOR_GPIO, .seq_val = SENSOR_GPIO_RESET, .config_val = GPIO_OUT_HIGH, .delay = 10, }, { .seq_type = SENSOR_CLK, .seq_val = SENSOR_CAM_MCLK, .config_val = 23880000, .delay = 10, }, { .seq_type = SENSOR_I2C_MUX, .seq_val = 0, .config_val = 0, .delay = 0, }, };
static struct msm_sensor_power_setting ov5648_power_down_setting[] = { { .seq_type = SENSOR_VREG, .seq_val = CAM_VIO, .config_val = 0, .delay = 0, }, { .seq_type = SENSOR_VREG, .seq_val = CAM_VAF, .config_val = 0, .delay = 5, }, { .seq_type = SENSOR_GPIO, .seq_val = SENSOR_GPIO_VANA, .config_val = GPIO_OUT_LOW, .delay = 5, },
{ .seq_type = SENSOR_GPIO, .seq_val = SENSOR_GPIO_STANDBY, .config_val = GPIO_OUT_LOW, .delay = 5, }, { .seq_type = SENSOR_GPIO, .seq_val = SENSOR_GPIO_RESET, .config_val = GPIO_OUT_LOW, .delay = 10, }, { .seq_type = SENSOR_CLK, .seq_val = SENSOR_CAM_MCLK, .config_val = 23880000, .delay = 10, }, { .seq_type = SENSOR_I2C_MUX, .seq_val = 0, .config_val = 0, .delay = 0, }, }; 二、Vendor部分 2.1 在Makefile文件中添加IC代码: 代码路径:srcLINUXandroidvendorqcomproprietarycommonconfig 文件名:device-vendor.mk 需添加的代码: MM_CAMERA += libchromatix_ov5648_oty5f03_common MM_CAMERA += libchromatix_ov5648_oty5f03_default_video MM_CAMERA += libchromatix_ov5648_oty5f03_preview MM_CAMERA += libchromatix_ov5648_oty5f03_snapshot MM_CAMERA += libchromatix_ov5648_oty5f03_zsl
MM_CAMERA += libmmcamera_ov5648_oty5f03 注意:如果这里没有添加以上代码,在编译的时候就不会生成相应的so文件。这so文件可以在srcLINUXandroidouttargetproductmsm8916_32systemvendorlib目录下找到,如下所示: libchromatix_ov5648_oty5f03_common.so libchromatix_ov5648_oty5f03_default_video.so libchromatix_ov5648_oty5f03_preview.so libchromatix_ov5648_oty5f03_snapshot.so libchromatix_ov5648_oty5f03_zsl.so libmmcamera_ov5648_oty5f03.so 2.2 添加Lib驱动代码: 代码路径: srcLINUXandroidvendorqcomproprietarymm-cameramm-camera2media-controllermodulessensorssensor_libs 文件夹名:ov5648_oty5f03 需添加的代码: 2.2.1 移植相机接口配置 这部分内容定义了传感器接口配置,包括 I2C和 MIPI。请确认设置不会和 dtsi文件中的类似内容冲突。 static struct msm_camera_sensor_slave_info sensor_slave_info = { /* Camera slot where this camera is mounted */ .camera_id = CAMERA_0, /* sensor slave address */ .slave_addr = 0x6c, /* sensor address type */ .addr_type = MSM_CAMERA_I2C_WORD_ADDR, /* sensor id info*/ .sensor_id_info = { /* sensor id register address */ .sensor_id_reg_addr = 0x300a, /* sensor id */ .sensor_id = 0x5648, }, /* power up / down setting */ .power_setting_array = { .power_setting = ov5648_oty5f03_power_setting, .size = ARRAY_SIZE(ov5648_oty5f03_power_setting), .power_down_setting = ov5648_oty5f03_power_down_setting, .size_down = ARRAY_SIZE(ov5648_oty5f03_power_down_setting),
}, }; static sensor_output_t sensor_output = { .output_format = SENSOR_BAYER, .connection_mode = SENSOR_MIPI_CSI, .raw_output = SENSOR_10_BIT_DIRECT, }; #ifndef VFE_40 static struct csi_lane_params_t csi_lane_params = { .csi_lane_assign = 0xE4, .csi_lane_mask = 0x3, .csi_if = 1, .csid_core = {0}, .csi_phy_sel = 0, }; #else static struct csi_lane_params_t csi_lane_params = { .csi_lane_assign = 0x4320, .csi_lane_mask = 0x3, .csi_if = 1, .csid_core = {0}, .csi_phy_sel = 1, }; #endif 2.2.2 移植传感器输出配置 这部分内容介绍了传感器不同模式的配置和设置,包含各模式的 I2C 寄存器设备、CSI参数、crop参数、传感器输出信息和chormatix数组。这些配置的数组大小应和传感器支持的模式种类相同。 static struct msm_camera_i2c_reg_setting res_settings[] = { { .reg_setting = res0_reg_array, .size = ARRAY_SIZE(res0_reg_array), .addr_type = MSM_CAMERA_I2C_WORD_ADDR, .data_type = MSM_CAMERA_I2C_BYTE_DATA, .delay = 0, }, { .reg_setting = res1_reg_array, .size = ARRAY_SIZE(res1_reg_array), .addr_type = MSM_CAMERA_I2C_WORD_ADDR, .data_type = MSM_CAMERA_I2C_BYTE_DATA, .delay = 0, }, }; …… static struct msm_camera_csi2_params *csi_params[] = { &ov5648_oty5f03_csi_params, /* RES 0*/ &ov5648_oty5f03_csi_params, /* RES 1*/ }; …… static struct sensor_crop_parms_t crop_params[] = { {0, 0, 0, 0}, /* RES 0 */ {0, 0, 0, 0}, /* RES 1 */ }; …… static struct sensor_lib_out_info_t sensor_out_info[] = { { .x_output = 2592, .y_output = 1944, .line_length_pclk = 2816, .frame_length_lines = 2380, .vt_pixel_clk = 84000000, .op_pixel_clk = 84000000, .binning_factor = 1, .max_fps = 12.5, .min_fps = 7.5, .mode = SENSOR_DEFAULT_MODE, }, { .x_output = 1296, .y_output = 972, .line_length_pclk = 1408, .frame_length_lines = 992, .vt_pixel_clk = 42000000, .op_pixel_clk = 42000000, .binning_factor = 1, .max_fps = 30.0, .min_fps = 7.5, .mode = SENSOR_DEFAULT_MODE, }, }; …… static struct sensor_lib_chromatix_t ov5648_oty5f03_chromatix[] = { { .common_chromatix = OV5648_OTY5F03_LOAD_CHROMATIX(common), .camera_preview_chromatix = OV5648_OTY5F03_LOAD_CHROMATIX(snapshot), /* RES0 */ .camera_snapshot_chromatix = OV5648_OTY5F03_LOAD_CHROMATIX(snapshot), /* RES0 */ .camcorder_chromatix = OV5648_OTY5F03_LOAD_CHROMATIX(default_video), /* RES0 */ }, { .common_chromatix = OV5648_OTY5F03_LOAD_CHROMATIX(common), .camera_preview_chromatix = OV5648_OTY5F03_LOAD_CHROMATIX(preview), /* RES2 */ .camera_snapshot_chromatix = OV5648_OTY5F03_LOAD_CHROMATIX(preview), /* RES2 */ .camcorder_chromatix = OV5648_OTY5F03_LOAD_CHROMATIX(default_video), /* RES2 */ }, }; 2.2.3 镜头信息移植 相机处理流程(比如曝光计算)需要镜头信息。因此,以下结构需添加正确的镜头信息。 static sensor_lens_info_t default_lens_info = { .focal_length = 2.37, .pix_size = 1.4, .f_number = 2.4, .total_f_dist = 1.97, .hor_view_angle = 70.24, .ver_view_angle = 52.68, }; 2.2.4 曝光配置移植 通常情况下,不同传感器有不同的曝光控制方式。所以,当传感器打开后,需移植曝光配置以成功调试传感器的曝光控制。 包括以下函数: n ov5648_real_to_register_gain – 将实际逻辑增益转换为寄存器值。 n ov5648_register_to_real_gain – 将寄存器值转换成真实的逻辑增益。 n ov5648_calculate_exposure – 获取曝光时间和增益的另一个曝光配置. n ov5648_fill_exposure_array – 准备另一个曝光配置数组。 2.3 添加Chromatix文件: 代码路径: srcLINUXandroidvendorqcomproprietarymm-cameramm-camera2media-controllermodulessensorschromatix0301libchromatix 文件夹名:chromatix_ov5648_oty5f03 需添加的代码: 该部分主要是针对raw格式是摄像头,而yuv格式的摄像头不需要做该步骤,而这添加的内容主要是raw摄像头效果参数的.h文件,这需要向模组或IC厂索要该部分的文件。 |
CopyRight 2018-2019 实验室设备网 版权所有 |