SENSOR 使用参考
REVISION HISTORY¶
Revision No. | Description |
Date |
---|---|---|
1.0 | 04/17/2025 | |
1. 概述¶
sensor padmux 用于配置sensor相关引脚的复用模式以支持不同硬件电路和mipi lane 数量。根据硬件原理图和引脚复用表选取和配置正确的sensor引脚复用模式是能够正常点亮sensor的第一步也是至关重要的一步。
2. 关键字说明¶
- sensor pad : Sensor 硬件插口位置。
3. 功能描述¶
sensor padmux设置可以为sensor 上下电提供需要的reset 和power down引脚电压,并按照sensor需要的上下电时序进行变化。同时也提供了主从设备之间i2c引脚的配置,用于读写sensor端的寄存器。sensor padmux 提供了多组mipi mode、bt656 mode等设定,通过修改使用的mode可以使用对应引脚将数据传到IC内部。
-
不同chip支持的mclk频率存在差异,pcupid支持的mclk如下
mclk支持配置时钟类型
4. 硬件连接介绍¶
4.1. 硬件接口确认¶
如下图 BGA14 demo 板上支持MIPI0 (2lane) 或者 MIPI00 + MIPI01 (1+1 lane)




通过上面的硬件原理图和引脚复用表可以确认BGA14 demo板的两种sensor padmux配置如下
pinmux mode type | FPC(2lane) | FPC(1+1) |
---|---|---|
mipi_rx_mode | snr0 mode1 | snr0 & snr2 mode5 |
mclk_mode | snr0 mode2 | snr0 & snr2 mode2 |
rst_mode | snr0 mode2 | snr0 & snr2 mode2 |
I2C_mode | I2C0 mode4 | I2C0 & I2C1 mode4 |
PS: 1.BGA14 只有MIPI0 2lane snr0或者 拆成 MIPI00 1lane + MIPI01 1lane snr0 + snr2, 所以目前设置 1+1 驱动上要注意 配置是snr0 和snr2
snr0 对应 snr00、srn2对应snr01。 pcupid 最高规格支持MIPI0(2lane)。MIPI0 可以拆分为MIPI00和MIPI01 --snr00和snr01。
4.2. MIPI 接口线序匹配¶
csi_sr0_lane_select里面3个位置分别对应MIPI CSI的\< CLK Lane0 Lane1>
如下图imx307_2lane,j1为sensor端线序,CON1为mipi_to_36pin转板线序和BGA14板端CON24一一对应。clk 在CH1位置, D0 在CH0位置, D1 在CH2,所以csi_sr0_lane_select = <1 0 2>

如下图gc2053_2lane,j8为sensor端线序,CON1为mipi_to_36pin转板线序和BGA14板端CON24一一对应。:clk 在CH1位置, D0 在CH2位置, D1 在CH0 所以csi_sr0_lane_select = <1 2 0>

如下图gc2053_1lane,j1为sensor端线序,CON2为mipi_rx_1+1lane转板线序和BGA14板端CON24一一对应。clk 在CH1位置, D0 在CH0位置, 所以csi_sr0_lane_select = <1 0>

如下图sc035hgs_1lane,j1为sensor端线序,CON2为mipi_rx_1+1lane转板线序和BGA14板端CON24一一对应。clk 在CH1位置, D0 在CH0位置,所以csi_sr0_lane_select = <1 0>

lane 顺序修改 ./riu_r 0x1538 0x6 0xA 0xE 0x22 0x25 的bit[12:15] 来看顺序是否有生效 0x1538 为sensor0 0x153c 为sensor2 mipi_rx_mode Sensor0&Sensor2: /customer/riu_r 0x103c 0x69 //查看bit[0:2]对应的值是否为snr_sr0_mipi_mode/snr_sr2_mipi_mode配置的值 /customer/riu_r 0x103c 0x6a //查看bit[0]对应的值是否为snr_sr0_mipi_mclk_mode的值 /customer/riu_r 0x103c 0x54 //查看bit[0]对应的值是否为snr_sr0_mipi_rst_mode的值
以上所述csi N\P 和 sensor 板的MIPI 接口 N\P 一致, 则配置csi_sr0_lane_pn_swap = <0 0 0>, 如果N 和 P 相接即配置csi_sr0_lane_pn_swap = <1 1 1>
PS:由于修改sensor 线序需要替换kernel,较为麻烦, 可以先用以下方式快速确认线序
通过加载 insmod /config/modules/5.10/mi_sensor.ko gp_sntExternalConfig=/customer/sensorpad0_2lane.json
加载json来配置
例如:
imx307 2lane线序 1 0 2:
{ "SensorIF": [ { "sensorPad": 0, "hwClass": "mipi", "content": { "lane_number": 2, "hdr_lane_number": 2, "lane_select": "1,0,2", "lane_swap": "0,0,0" } } ] }
gc2053 2lane线序1 2 0:
{ "SensorIF": [ { "sensorPad": 0, "hwClass": "mipi", "content": { "lane_number": 2, "hdr_lane_number": 2, "lane_select": "1,2,0", "lane_swap": "0,0,0" } } ] }
5. kernel用法介绍¶
5.1. dts 配置¶
2lane:
csi: csi { compatible = "sstar,csi"; io_phy_addr = <0x1f000000>; banks = <0x153C>,<0x153D>,<0x153E>,<0x1538>,<0x153A>,<0x153B>; atop_banks = <0x153F>; clkgen_banks = <0x1038>; interrupts= <GIC_SPI INT_IRQ_MIPI_CSI2 IRQ_TYPE_LEVEL_HIGH>; clocks = <&CLK_csi0_mac_lptx_top_i>,<&CLK_csi0_mac_top_i>,<&CLK_csi0_ns_top_i>,<&CLK_csi1_mac_lptx_top_i>,<&CLK_csi1_mac_top_i>,<&CLK_csi1_ns_top_i>; status = "ok"; /* Config max lane number */ csi_sr0_lane_num = <2>; csi_sr2_lane_num = <1>; /* Config lane selection */ csi_sr0_lane_select = <1 0 2>; csi_sr2_lane_select = <1 0>; /* Config lane P/N swap */ csi_sr0_lane_pn_swap = <0 0>; csi_sr2_lane_pn_swap = <0 0>; }; sensorif: sensorif { compatible = "sstar,sensorif"; status = "ok"; clocks = <&CLK_sr00_mclk>, <&CLK_sr01_mclk>; /* Config sensor 0 pad mux */ snr_sr0_mipi_mode = <1>; snr_sr0_mipi_rst_mode = <2>; snr_sr0_mipi_pdn_mode = <0>; snr_sr0_mipi_mclk_mode = <2>; snr_sr0_rst_gpio = <73>; snr_sr0_pdn_gpio = <77>; snr_sr0_par_mode = <2>; snr_sr0_par_rst_mode = <2>; snr_sr0_par_pdn_mode = <1>; snr_sr0_par_mclk_mode = <2>; snr_sr0_bt656_mode = <1>; snr_sr0_bt656_rst_mode = <2>; snr_sr0_bt656_pdn_mode = <1>; snr_sr0_bt656_mclk_mode = <2>; /* Config sensor 2 pad mux */ snr_sr2_mipi_mode = <5>; snr_sr2_mipi_rst_mode = <2>; snr_sr2_mipi_pdn_mode = <0>; snr_sr2_mipi_mclk_mode = <2>; /* Config mclk 37.125MHz supported */ snr_sr0_mclk_37p125 = <1>; snr_sr1_mclk_37p125 = <1>; snr_sr2_mclk_37p125 = <1>; snr0_mipi_i2c = <0>; snr0_paral_i2c = <0>; snr2_mipi_i2c = <1>; };
1+1lane:
csi: csi { compatible = "sstar,csi"; io_phy_addr = <0x1f000000>; banks = <0x153C>,<0x153D>,<0x153E>,<0x1538>,<0x153A>,<0x153B>; atop_banks = <0x153F>; clkgen_banks = <0x1038>; interrupts= <GIC_SPI INT_IRQ_MIPI_CSI2 IRQ_TYPE_LEVEL_HIGH>; clocks = <&CLK_csi0_mac_lptx_top_i>,<&CLK_csi0_mac_top_i>,<&CLK_csi0_ns_top_i>,<&CLK_csi1_mac_lptx_top_i>,<&CLK_csi1_mac_top_i>,<&CLK_csi1_ns_top_i>; status = "ok"; /* Config max lane number */ csi_sr0_lane_num = <1>; csi_sr2_lane_num = <1>; /* Config lane selection */ csi_sr0_lane_select = <1 0>; csi_sr2_lane_select = <1 0>; /* Config lane P/N swap */ csi_sr0_lane_pn_swap = <0 0>; csi_sr2_lane_pn_swap = <0 0>; }; sensorif: sensorif { compatible = "sstar,sensorif"; status = "ok"; clocks = <&CLK_sr00_mclk>, <&CLK_sr01_mclk>; /* Config sensor 0 pad mux */ snr_sr0_mipi_mode = <5>; snr_sr0_mipi_rst_mode = <2>; snr_sr0_mipi_pdn_mode = <0>; snr_sr0_mipi_mclk_mode = <2>; snr_sr0_rst_gpio = <73>; snr_sr0_pdn_gpio = <77>; snr_sr0_par_mode = <2>; snr_sr0_par_rst_mode = <2>; snr_sr0_par_pdn_mode = <1>; snr_sr0_par_mclk_mode = <2>; snr_sr0_bt656_mode = <1>; snr_sr0_bt656_rst_mode = <2>; snr_sr0_bt656_pdn_mode = <1>; snr_sr0_bt656_mclk_mode = <2>; /* Config sensor 2 pad mux */ snr_sr2_mipi_mode = <5>; snr_sr2_mipi_rst_mode = <2>; snr_sr2_mipi_pdn_mode = <0>; snr_sr2_mipi_mclk_mode = <2>; /* Config mclk 37.125MHz supported */ snr_sr0_mclk_37p125 = <1>; snr_sr1_mclk_37p125 = <1>; snr_sr2_mclk_37p125 = <1>; snr0_mipi_i2c = <0>; snr0_paral_i2c = <0>; snr2_mipi_i2c = <1>; };
csi部分释义如下:
参数 | 释义 | 备注 |
---|---|---|
interrupts | mipi rx csi中断 | 不需要修改 |
clocks | mipi rx csi时钟源 | 不需要修改 |
csi_sr0_lane_num | sensor pad0 的mipi信号线数量 | 需要根据实际使用的mipi sensor 信号线数量进行配置,参考2.3 |
csi_sr0_lane_select | 配置sensor pad0的mipi信号线线序 | 需要根据板端和sensor模组实际的mipi信号线线序进行修改参考2.3 |
csi_sr0_lane_pn_swap | 配置sensor pad0的mipi信号线电源极性 | 配置为1时代表一组mipi信号的电源极性做互换参考2.3 |
csi_sr2_lane_select | 配置sensor pad2的mipi信号线线序 | 需要根据板端和sensor模组实际的mipi信号线线序进行修改参考2.3 |
csi_sr2_lane_num | sensor pad2 的mipi信号线数量 | 需要根据实际使用的mipi sensor 信号线数量进行配置参考2.3 |
csi_sr2_lane_pn_swap | 配置sensor pad2的mipi信号线电源极性 | 配置为1时代表一组mipi信号的电源极性做互换参考2.3 |
sensorif部分释义如下:
参数 | 释义 | 备注 |
---|---|---|
clocks | sensor mclk时钟源 | 需要按照pad0 pad2的顺序配置 |
snr_sr0_mipi_mode | mipi sensor pad0 的mipi mode | 参考第1节 |
snr_sr0_mipi_rst_mode | mipi sensor pad0 的reset mode | 参考第1节 |
snr_sr0_mipi_pdn_mode | mipi sensor pad0 的pdn mode | 参考第1节 |
snr_sr0_mipi_mclk_mode | mipi sensor pad0 的mclk mode | 参考第1节 |
snr_sr0_rst_gpio | mipi sensor pad0 的reset gpio 引脚设置 | 同时配置rst mode和rst gpio的话优先使用gpio的设定 |
snr_sr0_pdn_gpio | mipi sensor pad0 的pdn gpio 引脚设置 | 同时配置pdn mode和pdn gpio的话优先使用gpio的设定 |
snr_sr0_bt656_mode | bt656 sensor pad0 的mipi mode | 参考第1节 |
snr_sr0_bt656_rst_mode | bt656 sensor pad0 的reset mode | 参考第1节 |
snr_sr0_bt656_pdn_mode | bt656 sensor pad0 的pdn mode | 参考第1节 |
snr_sr0_bt656_mclk_mode | bt656 sensor pad0 的mclk mode | 参考第1节 |
snr_sr0_mclk_37p125 | 配置sensor pad0 支持37.125MHz mclk | |
snr0_mipi_i2c | 配置mipi sensor pad0 使用的i2c bus id | 需要根据实际使用的i2c bus进行配置 |
snr0_paral_i2c | 配置parallel sensor pad0 使用的i2c bus id | 需要根据实际使用的i2c bus进行配置 |
5.2. IIC 配置¶
如上节所示: 2lane 情况下snr0 绑定 i2c0 mode4 1+1情况下snr00 和 snr01 绑定i2c0 mode4 和 i2c1 mode4
snr0_mipi_i2c = <0>; snr0_paral_i2c = <0>; snr2_mipi_i2c = <1>;
snr0
代表MIPI sensor 0
<0>
代表使用I2C bus 0
I2C padmux 在对应kernel\arch\arm64\boot\dts\sstar下面对应padmux的dtsi中配置:
//I2C1 Mode1,sensorif_mipi_grp1_i2c <PAD_GPIOB_00 PINMUX_FOR_I2C0_MODE_4 MDRV_PUSE_I2C0_SCL>, <PAD_GPIOB_01 PINMUX_FOR_I2C0_MODE_4 MDRV_PUSE_I2C0_SDA>, //I2C0 Mode1,sensorif_mipi_grp0_i2c <PAD_GPIOB_04 PINMUX_FOR_I2C1_MODE_4 MDRV_PUSE_I2C1_SCL>, <PAD_GPIOB_05 PINMUX_FOR_I2C1_MODE_4 MDRV_PUSE_I2C1_SDA>,
I2c0: /customer/riu_r 0x103c 6f //bit[0:2]是否为对应mode的值
I2c1: /customer/riu_r 0x103c 53 //bit[0:2]是否为对应mode的值
5.3. 默认sensor驱动加载¶
5.3.1. sensor driver配置¶
insmod /config/modules/5.10/imx307_MIPI.ko chmap=1 sensor 0 ----> chmap=1 sensor 2 ----> chmap=4
可以通过menuconfig修改image默认支持的sensor drvier和预安装的sensor driver
-
进入alkaid project根目录,make menuconfig
-
回车键进入Sensor子选项
-
回车键进入Sensor List子选项,写上需要的sensor driver名称
-
编辑完成后退出,再回车键进入Sensor0子选项,写上需要预insmod的sensor driver名称
-
编辑完成后退出,再回车键进入Sensor0 Opt子选项,写上需要预insmod sensor0后面需要配置的参数。
编译完成将在/config/modules/5.10 下生成Sensor List中选择的sensor driver,同时在/customer/demo.sh中会看到预先insmod sensor0的命令。
5.3.2. sensor IQ文件配置¶
可以通过menuconfig修改image默认支持的sensor IQ文件
-
进入alkaid project根目录,make menuconfig
-
回车键进入Sensor子选项
-
回车键进入IQ0子选项,写上需要使用的iq file名称。IQ后的序号对应不同sensor pad,例如IQ0对应sensor0。
编译完成将在/config/modules/iqfile 下生成IQ0中选择的iq file。
5.4. sensor driver 部分函数介绍¶
函数名 | 功能 |
---|---|
cus_camsensor_init_handle | 设置sensor基础参数、注册功能回调 |
handle->pCus_sensor_init\handle->pCus_sensor_release | 初始化sensor(通过iic配置参数) |
handle->pCus_sensor_poweron/handle->pCus_sensor_poweroff | 上电\掉电函数(poweron会在sensor_init之前调用) |
handle->sif_bus | 接口类型(MIPI、DVP等) |
handle->data_prec | 数据类型(raw8\10\12 YUV等) |
handle->bayer_id\handle->RGBIR_id | BAYE或者RGB排列顺序 |
handle->interface_attr.attr_mipi | MIPI 配置 |
handle->video_res_supported | 支持多少种配置 |
handle->i2c_cfg | iic配置 |
handle->pwdn_POLARITY\handle->reset_POLARITY\handle->VSYNC_POLARITY\handle->HSYNC_POLARITY\handle->PCLK_POLARITY | 控制引脚的极性配置 |
handle->mclk | MCLK clk |
sensor_if->SetCSI_Clk\sensor_if->SetCSI_Lane\sensor_if->SetCSI_LongPacketType | CSI 配置(clk、 lane 数、支持收包类型(1c代表支持收Raw8、10、12)) |
Preview_line_period | 行长(包含h blank) |
params->expo.vts | 帧长(包含V blank& h blank) |
PS: Preview_line_period = 1*10^9/(fps*(data_h+v_blank))

5.5. sensor驱动开发¶
不同接口类型的sensor 驱动实现基本一样,具体请参考Sensor_Porting
5.6. SAMPLE CODE¶
snr vif 初始化函数
MI_S32 ST_VifInit(ST_Stream_Attr_T *pStreamAttr) { /************************************************ Step1: Init Sensor *************************************************/ MI_SNR_PADInfo_t stSnrPadInfo; MI_SNR_PlaneInfo_t stSnrPlaneInfo; MI_SNR_PADID snrPadId = pStreamAttr->u32SnrId; MI_U32 u32ResCount = 0; memset(&stSnrPadInfo, 0x0, sizeof(MI_SNR_PADInfo_t)); memset(&stSnrPlaneInfo, 0x0, sizeof(MI_SNR_PlaneInfo_t)); ExecFunc(MI_SNR_SetPlaneMode(snrPadId, FALSE), DRM_SUCCESS); ExecFunc(MI_SNR_QueryResCount(snrPadId, &u32ResCount), DRM_SUCCESS); if(pStreamAttr->u32SnrChoiceRes > u32ResCount-1){ printf("MI_SNR_QueryResCount :%d\n", u32ResCount); return -1; } ExecFunc(MI_SNR_SetRes(snrPadId, pStreamAttr->u32SnrChoiceRes), DRM_SUCCESS); ExecFunc(MI_SNR_Enable(snrPadId), DRM_SUCCESS); /************************************************ Step2: Init Vif *************************************************/ MI_VIF_GROUP VifGroupId = 0; MI_VIF_DEV VifDevId = 0; MI_VIF_DEV VifChnId = pStreamAttr->VifChnId; MI_VIF_PORT VifPortId = pStreamAttr->VifPortId; MI_VIF_GroupAttr_t stVifGroupAttr; MI_VIF_DevAttr_t stVifDevAttr; MI_VIF_OutputPortAttr_t stVifPortAttr; get_vif_from_snrpad(snrPadId, &VifGroupId, &VifDevId); memset(&stVifGroupAttr, 0x0, sizeof(MI_VIF_GroupAttr_t)); memset(&stVifDevAttr, 0x0, sizeof(MI_VIF_DevAttr_t)); memset(&stVifPortAttr, 0x0, sizeof(MI_VIF_OutputPortAttr_t)); ExecFunc(MI_SNR_GetPadInfo(snrPadId, &stSnrPadInfo), DRM_SUCCESS); ExecFunc(MI_SNR_GetPlaneInfo(snrPadId, 0, &stSnrPlaneInfo), DRM_SUCCESS); printf( "MI_SNR_GetPlaneInfo %d, outputsize(%d, %d, %d, %d)\n", snrPadId,stSnrPlaneInfo.stCapRect.u16X,stSnrPlaneInfo.stCapRect.u16Y, stSnrPlaneInfo.stCapRect.u16Width,stSnrPlaneInfo.stCapRect.u16Height); stVifGroupAttr.eIntfMode = E_MI_VIF_MODE_MIPI; stVifGroupAttr.eWorkMode = E_MI_VIF_WORK_MODE_1MULTIPLEX; stVifGroupAttr.eHDRType = E_MI_VIF_HDR_TYPE_OFF; if (stVifGroupAttr.eIntfMode == E_MI_VIF_MODE_BT656) { stVifGroupAttr.eClkEdge = (MI_VIF_ClkEdge_e)stSnrPadInfo.unIntfAttr.stBt656Attr.eClkEdge; } else { stVifGroupAttr.eClkEdge = E_MI_VIF_CLK_EDGE_DOUBLE; } ExecFunc(MI_VIF_CreateDevGroup(VifGroupId, &stVifGroupAttr), DRM_SUCCESS); stVifDevAttr.stInputRect.u16X = stSnrPlaneInfo.stCapRect.u16X; stVifDevAttr.stInputRect.u16Y = stSnrPlaneInfo.stCapRect.u16Y; stVifDevAttr.stInputRect.u16Width = stSnrPlaneInfo.stCapRect.u16Width; stVifDevAttr.stInputRect.u16Height = stSnrPlaneInfo.stCapRect.u16Height; if (stSnrPlaneInfo.eBayerId >= E_MI_SYS_PIXEL_BAYERID_MAX) { stVifDevAttr.eInputPixel = stSnrPlaneInfo.ePixel; } else { stVifDevAttr.eInputPixel = (MI_SYS_PixelFormat_e)RGB_BAYER_PIXEL( stSnrPlaneInfo.ePixPrecision, stSnrPlaneInfo.eBayerId); } ExecFunc(MI_VIF_SetDevAttr(VifDevId, &stVifDevAttr), DRM_SUCCESS); ExecFunc(MI_VIF_EnableDev(VifDevId), DRM_SUCCESS); stVifPortAttr.stCapRect.u16X = stSnrPlaneInfo.stCapRect.u16X; stVifPortAttr.stCapRect.u16Y = stSnrPlaneInfo.stCapRect.u16Y; stVifPortAttr.stCapRect.u16Width = stSnrPlaneInfo.stCapRect.u16Width; stVifPortAttr.stCapRect.u16Height = stSnrPlaneInfo.stCapRect.u16Height; stVifPortAttr.stDestSize.u16Width = stSnrPlaneInfo.stCapRect.u16Width; stVifPortAttr.stDestSize.u16Height = stSnrPlaneInfo.stCapRect.u16Height; stVifPortAttr.eFrameRate = E_MI_VIF_FRAMERATE_FULL; if (stSnrPlaneInfo.eBayerId >= E_MI_SYS_PIXEL_BAYERID_MAX) { stVifPortAttr.ePixFormat = stSnrPlaneInfo.ePixel; } else { stVifPortAttr.ePixFormat = (MI_SYS_PixelFormat_e)RGB_BAYER_PIXEL( stSnrPlaneInfo.ePixPrecision, stSnrPlaneInfo.eBayerId); } ExecFunc(MI_VIF_SetOutputPortAttr(VifDevId, VifPortId, &stVifPortAttr), DRM_SUCCESS); return 0; }
6. SENSOR SUPPORT LIST¶
6.1 MIPI Interface Camera Sensor Support list¶
在芯片验证阶段,验证的MIPI 接口的sensor 如下表所示:
接口类型 | Lane 数 | 种类 | 关键指标 | 数据格式 |
---|---|---|---|---|
MIPI | 2Lane | IMX307 | 1920x1080@30FPS,2lane | Bayer |
2/1Lane | gc2053 | 1920x1080@30FPS,2/1lane | Bayer | |
1Lane | sc035hgs | 640x480@30FPS,1lane | Bayer |
6.2 BT601(DVP) Interface Camera Sensor Support List¶
在芯片验证阶段,验证的BT601(DVP)接口的sensor 如下表所示:
接口类型 | data pin数 | 种类 | 关键指标 | 数据格式 | parallel | 10 pin | IMX323 | 1920x1080@30fps | Bayer |
---|
6.3 BT656 Interface Camera Sensor Support List¶
在芯片验证阶段,验证的BT656接口的sensor 如下表所示:
接口类型 | data pin数 | 种类 | 关键指标 | 数据格式 |
---|---|---|---|---|
BT656 | 8pin | NVP6158C | 1280x720@30fps | YUV |
7. FAQ¶
Q1:如何查看sensor出图
echo dumptaskfile 0 2 /mnt/pcm > /proc/mi_modules/mi_isp/mi_isp0 echo dumptaskfile 0 2 /mnt/pcm > /proc/mi_modules/mi_scl/mi_scl0
/mnt/pcm :存图路径 2:抓2张图 0: chnNum
Q2:如何进一步确认sensor 中断信息