1. 程式人生 > >高通CAMERA 除錯

高通CAMERA 除錯

Camera sensor bring up

2016年08月12日 13:14:19 tamell5555 閱讀數:4083 標籤: android

眾所周知,camera在我們生活中應用十分廣泛,在未來智慧硬體社會,camera就是裝置的眼睛,它的機器視覺也將扮演非常重要的角色。在我們移動裝置終端中,我們知道camera模組是由鏡頭(lens)、感測器(sensor)、軟板(FPC)、影象處理晶片(DSP)等4部分組成。決定一個攝像頭好壞的重要部件是:鏡頭(lens)、影象處理晶片 (DSP)、感測器(sensor)。而今天我們主要偏向於軟體側,來介紹下Dragonboard410C Camera sensor bring up的一個配置。

 

本文主要分為兩部分來介紹要注意的配置
第一部分、 Kernel 及  vendor porting( Sensor dtsi 及上下電時序)

第二部分 vendor層引數(其中包括  csiphy 、csid和其他引數)
(針對的是 msm8916,也相容msm8926平臺)

 

一、 Kernel及Vendor porting:


1、新 Porting 一顆 sensor kernel 需要新增和配置的

@arch/arm/configs/msm8226_defconfig
+ CONFIG_IMX135=y
@arch/arm/mach-msm/clock-8226.c
+ CLK_LOOKUP("cam_src_clk", mclk0_clk_src.c, "20.qcom,camera"),
+ CLK_LOOKUP("cam_clk", camss_mclk0_clk.c, "20.qcom,camera"),
+ CLK_LOOKUP("cam_src_clk", mclk0_clk_src.c, "20.qcom,eeprom"),
+ CLK_LOOKUP("cam_clk", camss_mclk0_clk.c, "20.qcom,eeprom"),
@arch/arm/boot/dts/msm8226-camera-sensor-qrd.dtsi
+ "qcom,imx135"
……
@ drivers/media/platform/msm/camera_v2/Kconfig
+ config IMX135
@drivers/media/platform/msm/camera_v2/sensor/Makefile
+ obj-$(CONFIG_IMX135) += imx135.o
@drivers/media/platform/msm/camera_v2/sensor/imx135.c

2、新 Porting 一顆 sensor User 需要新增和配置的

@vendor/qcom/proprietary/common/config/device-vendor.mk
+ MM_CAMERA += libchromatix_imx135_common
+ MM_CAMERA += libchromatix_imx135_default_video
+ MM_CAMERA += libchromatix_imx135_hfr_60
+ MM_CAMERA += libchromatix_imx135_hfr_90
+ MM_CAMERA += libchromatix_imx135_hfr_120
+ MM_CAMERA += libchromatix_imx135_liveshot
+ MM_CAMERA += libchromatix_imx135_preview
+ MM_CAMERA += libchromatix_imx135_snapshot
+ MM_CAMERA += libchromatix_imx135_video_hd
+ MM_CAMERA += libchromatix_imx135_zsl
+ MM_CAMERA += libmmcamera_imx135
@vendor/qcom/proprietary/mm-camera/mm-camera2/media-controller/modules/sensors/sens
or_libs/imx135
Add imx135 folder
Android.mk/imx135_lib.c imx135_lib.h
Note: build 出來的庫放在 system/vendor/lib/下面
@vendor/qcom/proprietary/mm-camera/mm-camera2/media-controller/modules/sensors/chro
matix/0301/libchromatix/
Add chromatix_imx135 folder
Note: build 出來的庫放在 system/vendor/lib/下面

3、 kernel 中需要客製化的地方

1) kernel 中 dtsi 詳解
&cci { ……
qcom,[email protected] {
compatible = "qcom,imx135";
reg = <0x20>;
qcom,slave-id = <0x20 0x0016 0x0135>;
//0x20 是 sensor I2C 地址,高 7bit 是 I2C slave 地址,最低位是寫標記 0
//0x16 sensor ID 高位地址 0x17 ID 低位地址
//msm_sensor.c 中讀取 id 的時候設定為雙位元組讀取,所以這裡設定高位地址即可
qcom,csiphy-sd-index = <0>; // 1:前置 mipi 0:後者 mipi 根據硬體連線決定 cs0、 cs1.
qcom,csid-sd-index = <0>; // CSID 的連線,選哪個
qcom,actuator-src = <&actuator1>;
qcom,led-flash-src = <&led_flash1>;
//qcom,eeprom-src = <&eeprom1>; add by chenqiang for CR01296254 20140618
qcom,mount-angle = <90>;//sensor 成像方向與手機主機板的角度
qcom,sensor-name = "imx135";
//sensor 的名字,這個名字影響到載入 lib.so 庫,在 kernel 層解析完會傳到 vendor 層的
//sensor.c 中,在這個函式中會去獲取到這個名字,這個名字必須和 lib 庫的名字一樣,否則
//無法解析出 lib 庫,即無法獲取到 lib 庫中的函式
cam_vdig-supply = <&pm8226_l5>;//L5 的意思是電源型別是 LDO 輸出
cam_vana-supply = <&pm8226_l19>;
cam_vio-supply = <&pm8226_lvs1>;//LVS 輸出
cam_vaf-supply = <&pm8226_l15>;
qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana",
"cam_vaf";
qcom,cam-vreg-type = <0 1 0 0>; //0 : LDO 1:LVS
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>; //電流值
qcom,gpio-no-mux = <0>; // 1、表示 gpio mux 不可用 0、表示可用
gpios = <&msmgpio 26 0>,
<&msmgpio 37 0>,
<&msmgpio 36 0>,
<&msmgpio 38 0>,//avdd
<&msmgpio 22 0>,//dvdd
<&msmgpio 34 0>;//AF
qcom,gpio-reset = <1>;
qcom,gpio-standby = <2>;
qcom,gpio-vana = <3>;
qcom,gpio-vdig = <4>;
qcom,gpio-af-pwdm = <5>;
qcom,gpio-req-tbl-num = <0 1 2 3 4 5>;
qcom,gpio-req-tbl-flags = <1 0 0 0 0 0>;
//gpio 的輸入輸出設定,第一位是 MCLK,不屬於 gpio,所以這裡設定為 1
qcom,gpio-req-tbl-label = "CAMIF_MCLK",
"CAM_RESET",
"CAM_STANDBY",
"CAM_VANA",
"CAM_VDIG",
"CAM_AF_PWDM";
qcom,gpio-set-tbl-num = <1 1>;
qcom,gpio-set-tbl-flags = <0 2>;
qcom,gpio-set-tbl-delay = <1000 30000>;
qcom,csi-lane-assign = <0x4320>;
//這個和硬體原理圖對應,表示 4 3 2 0 這幾條線作為 mipi 資料線, 1 作為時鐘線
qcom,csi-lane-mask = <0x1F>; // 使用幾條 lan 這裡是使用 4 條 0x1f = 00o1 1111
qcom,sensor-position = <0>; // 1:前置 0:後置
qcom,sensor-mode = <0>; // 感測器的資料格式 1:yuv 格式 0:bayer 格式
qcom,sensor-type = <0>;
qcom,cci-master = <0>;
status = "ok";
};
……
}

2) kernel 中上電時序, Power setting 需要根據 datasheet 的上電時序來寫

Sensor 的上下電時序以陣列的格式寫於驅動的 msm_sensor_power_setting 資料結
構中,
static struct msm_sensor_power_setting imx135_power_setting[] = {

{
.seq_type = SENSOR_GPIO,
.seq_val = SENSOR_GPIO_VDIG,
.config_val = GPIO_OUT_LOW,
.delay = 0,
},
… }
DateSheet 中對電壓和時序的說明:

msm8226-camera-sensor-qrd.dtsi
cam_vdig-supply = <&pm8226_l5>;
cam_vana-supply = <&pm8226_l19>;
cam_vio-supply = <&pm8226_lvs1>;
cam_vaf-supply = <&pm8226_l15>;
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>;
msm8226-regulator.dtsi
rpm-regulator-ldoa5 {
status = "okay";
pm8226_l5: regulator-l5 {
regulator-name = "8226_l5";
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <1200000>;
qcom,init-voltage = <1200000>;
status = "okay";
};
};


上電時序和下電時序都可以分別加在 msm_sensor_power_setting_array 陣列中. 如果
power_down_setting/size_down 資料成員沒有新增,下電時序會使用上電時序的反時序.

 

二、 Vendor 層引數

 

1、 CSIPHY、 CSID

如上圖所示, CSID 是一個數據流控制器
像 8939 上有 3 個 D-PHY 對應有四個 csid,前兩個 csid 分別控制前兩個 D-PHY
後兩個 csid 各有分工,因為 8939 支援第三路 D-PHY 可以用作 4lane 的 camera
也可以用作 1lane 的兩個 camera 如果是後一種情況的話,就需要兩個 csid 來分別走資料流。
1>、 MIPI 接收器配置 (CSIPHY CSID)
Sensor 通過 MIPI CSI2 傳輸影象,高通接收器通過 MIPI CSI PHY 和 CSID 接收相應資料。
CSI-PHY、 and CSID config (code 中的具體設定參考有道筆記)
在 vendor 層中有 csi 的配置,具體配置結構體如下:
static struct csi_lane_params_t csi_lane_params = {
.csi_lane_assign = 0x4320,
.csi_lane_mask = 0x1F,//0001 1111
.csi_if = 1,
.csid_core = { 0 },
.csi_phy_sel = 0,
};
static struct msm_camera_csid_vc_cfg imx135_cid_cfg[] = {
{ 0, CSI_RAW10, CSI_DECODE_10BIT },
{ 1, 0x35, CSI_DECODE_8BIT },
{ 2, CSI_EMBED_DATA, CSI_DECODE_8BIT}
};
static struct msm_camera_csi2_params imx135_csi_params = {
.csid_params = {
.lane_cnt = 4,
.lut_params = {
.num_cid = ARRAY_SIZE(imx135_cid_cfg),
.vc_cfg = {
&imx135_cid_cfg[0],
&imx135_cid_cfg[1],
&imx135_cid_cfg[2],
},
},
},
.csiphy_params = {
.lane_cnt = 4,
.settle_cnt = 0x1B, //mipi 從低速到高速的一個緩衝時間
},
};

 

CSI-D 配置:


2、 Vendor 層其他引數

1)輸出尺寸表 out_info
{
/* full size @ 22.27 fps*/
.x_output = 4208,
.y_output = 3120,
.line_length_pclk = 4572,
.frame_length_lines = 3142,
.vt_pixel_clk = 360000000, //PCLK 時鐘,資料同步時鐘,
.op_pixel_clk = 360000000,
.binning_factor = 1, //當這個為 0 和 1 的時候沒有影響,當為 2 的時候會影響到 line_count
的大小
.max_fps = 24.01, //VFE 的時鐘,
.min_fps = 7.5,
.mode = SENSOR_DEFAULT_MODE,
},



2)曝光設定暫存器地址

static struct msm_sensor_exp_gain_info_t exp_gain_info = {
.coarse_int_time_addr = 0x0202,
.global_gain_addr = 0x0205,
.vert_offset = 4,
};

vert_offset – 曝光行數上限的邊界值,曝光行數任何情況下都應該小於
frame_length_lines 減去 vert_offset.

3)輸出控制暫存器地址

static struct msm_sensor_output_reg_addr_t output_reg_addr = {
.x_output = 0x034C,
.y_output = 0x034E,
.line_length_pclk = 0x0342,
.frame_length_lines = 0x0340,
};

4)sensor_stream_info_t

static struct sensor_pix_fmt_info_t imx135_pix_fmt0_fourcc[] = {
{ V4L2_PIX_FMT_SRGGB10 },
{ MSM_V4L2_PIX_FMT_META },
};
static struct sensor_pix_fmt_info_t imx135_pix_fmt1_fourcc[] = {
{ MSM_V4L2_PIX_FMT_META },
};
static sensor_stream_info_t imx135_stream_info[] = {
{ 2, &imx135_cid_cfg[0], imx135_pix_fmt0_fourcc },
{ 1, &imx135_cid_cfg[1], imx135_pix_fmt1_fourcc },
};
這個和 kernel 中的 v4l2_subdev_info.Code 對應
5) Gain 轉換函式
real gain 換算成暫存器 gain(寫到暫存器裡的那個值)
static uint16_t imx135_real_to_register_gain(float gain) {
uint16_t reg_gain;
if (gain < 1.0)
gain = 1.0;
if (gain > 8.0)
gain = 8.0;
reg_gain = (uint16_t)(256.0 - 256.0 / gain);
return reg_gain;
}
sensor gain 換算成 real gain
float imx135_register_to_real_gain(uint16_t reg_gain) {
float gain;
if (reg_gain > 224)
reg_gain = 224;
gain = 256.0 / (256.0 - reg_gain);
return gain;
}
Datasheet 中有 gain 的轉換


6)
static int32_t imx135_calculate_exposure
exp_info->reg_gain = imx135_real_to_register_gain(real_gain);( real gain 換算從 sensor register gain)
exp_info->digital_gain = real_gain / sensor_real_gain;(用 ISP gain 補上 real gain 到 sensor gain 換算中帶來的損失)
exp_info->line_count = line_count;(曝光時間)

7) imx135_fill_exposure_array
執行 AEC 的結果,寫曝光時間和 gain(需要保證 frame_length_lines 至少要比coarse_int_time 長vert_offset)
這個要根據 sensor 的曝光時間和 gain 的寫法更改