高通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 = <0x6a 0x0>;  

——這需要與1.3節中添加的Clock地址向對應。

qcom,slave-id = <0x6c 0x300a 0x5648>;  

——0x6c爲攝像頭的I2C地址,0x300a爲攝像頭存放ID的寄存器地址,0x5648爲攝像頭的ID,這都需要查看datasheet或直接問模組廠。

qcom,csiphy-sd-index = <1>;

qcom,csid-sd-index = <1>;

——以上兩個設置需要查看主板原理圖,看主板上攝像頭是接在CSI0還是CSI1上的,一般後攝像頭都會接到CSI0上,前攝像頭會接在CSI1上。

qcom,mount-angle = <270>;

——該參數爲攝像頭預覽界面的方向,如果預覽方向有被旋轉,可以通過修改這個參數進行修正。

qcom,sensor-name = "ov5648_oty5f03";

——這個對應vendor中lib文件夾的文件名,具體可參看2.2節。

cam_vdig-supply = <&pm8916_l2>;

cam_vana-supply = <&pm8916_l17>;

cam_vio-supply = <&pm8916_l6>;

——以上三個參數分別對應DVDD(vdig)、AVDD(vana)、DOVDD(vio)三個電壓,具體所接的是哪路電壓,需要參看主板原理圖。

qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana";

qcom,cam-vreg-type = <0 1 0>;

qcom,cam-vreg-min-voltage = <1200000 0 2850000>;

qcom,cam-vreg-max-voltage = <1200000 0 2850000>;

qcom,cam-vreg-op-mode = <200000 0 80000>;

——這五個配置要分別與上面的三個電壓一一對應(按照從上到下的順序),如果有對焦馬達的還要在後面填一路AF的電壓,如下所示:

cam_vaf-supply = <&pm8916_l10>;

qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana",

 "cam_vaf";

qcom,cam-vreg-type = <0 1 0 0>;

qcom,cam-vreg-min-voltage = <1200000 0 2850000 2800000>;

qcom,cam-vreg-max-voltage = <1200000 0 2850000 2800000>;

qcom,cam-vreg-op-mode = <200000 0 80000 100000>;

 

pinctrl-names = "cam_default", "cam_suspend";

pinctrl-0 = <&cam_sensor_mclk1_default

&cam_sensor_front_default>;

pinctrl-1 = <&cam_sensor_mclk1_sleep &cam_sensor_front_sleep>;

——以上這兩個需要區分的就是前後攝像頭的配置不一樣,上面這種配置是前攝像頭的配置,後攝像頭的配置如下所示:

pinctrl-names = "cam_default", "cam_suspend";

pinctrl-0 = <&cam_sensor_mclk0_default

&cam_sensor_rear_default>;

pinctrl-1 = <&cam_sensor_mclk0_sleep &cam_sensor_rear_sleep>;

 

gpios = <&msm_gpio 27 0>,

<&msm_gpio 28 0>,

<&msm_gpio 33 0>,

<&msm_gpio 119 0>;               

qcom,gpio-reset = <1>;

qcom,gpio-standby = <2>;

qcom,gpio-vana = <3>;

qcom,gpio-req-tbl-num = <0 1 2 3>;

qcom,gpio-req-tbl-flags = <1 0 0 0>;

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 = <1 1>;

qcom,gpio-set-tbl-flags = <0 2>;

qcom,gpio-set-tbl-delay = <1000 4000>;

——這三個參數是前攝像頭的固定模式,後攝像頭不需要這個設置,在配置後攝像頭時直接去掉即可。

qcom,csi-lane-assign = <0x4320>;

——該參數爲主芯片mipi Lane個數配置寄存器。

qcom,csi-lane-mask = <0x3>;

——該參數爲配置mipi Lane個數,0x3爲1組數據線加1組時鐘線,0x07爲2組數據線加1組時鐘線,0x1f爲4組數據線加1主時鐘線。

qcom,sensor-position = <1>;

——該參數,如果添加的是前攝像頭需要配置成1,如果是後攝像頭需要配置成0

qcom,sensor-mode = <1>;

qcom,cci-master = <0>;

status = "ok";

clocks = <&clock_gcc clk_mclk1_clk_src>,

<&clock_gcc clk_gcc_camss_mclk1_clk>;

clock-names = "cam_src_clk", "cam_clk";

——上面兩個Clocks和Clock-names是前攝像頭的配置,後攝像頭的配置如下:

clocks = <&clock_gcc clk_mclk0_clk_src>,

<&clock_gcc clk_gcc_camss_mclk0_clk>;

clock-names = "cam_src_clk", "cam_clk";

};

另外如果有對焦馬達還需要修改對焦馬達的地址,如下所示:

actuator0: qcom,actuator@6e {

cell-index = <3>;

reg = <0x18>;

compatible = "qcom,actuator";

qcom,cci-master = <0>;

};

 

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廠索要該部分的文件。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章