SENSOR 使用参考¶
REVISION HISTORY¶
| Revision No. | Description |
Date |
|---|---|---|
| 1.0 | 11/19/2025 |
1. 概述¶
本文以 IFORD 系列芯片的 Comake_Pi_D2 开发板为例,为图像传感器(sensor)的使用提供参考。使用时需了解一些基础技术知识,包括 MIPI 协议里的 CSI 接口、CCI 接口,以及sensor的规格等。
为确保图像sensor正常输出图像,请按以下步骤操作:
- 确认sensor与 SOC 芯片的硬件连接是否正确;
- 明确 SOC 芯片上哪些引脚可用于sensor的 MIPI 接口;
- 在设备树(dts)中正确配置 CSI 和 sensor_if 接口参数;
- 确认需要加载的模块 ko 文件;
- 确认需要加载的sensor驱动 ko 文件;
- 正确使用 MI 模块的 API 接口。
2. 关键字说明¶
-
sensor : 即传感器。在嵌入式音视频开发中,单独提及 “sensor” 时,特指 CMOS 图像传感器,其功能为采集图像数据。
-
sensor pad : 指sensor硬件对应的 SoC 芯片引脚。
-
mipi : 即 MIPI 协议簇,涵盖触摸、图像采集、图像显示等协议。在传感器使用场景中,“mipi” 特指 CSI-2 协议 / 接口(一种图像采集协议);在面板(panel)或显示(disp)场景中,“mipi” 特指 DSI 协议 / 接口(一种图像显示协议)。
-
lane : 对实际物理接线的抽象概念,称为 “通道”,例如时钟通道(时钟 lane)、数据通道(数据 lane)。一个 lane 对应的物理接线可为 1 根或多根,以 MIPI 协议簇中 CSI-2 协议的物理层 D-PHY 为例,其单个数据 lane 包含 “data-” 和 “data+” 两根物理线。部分传感器支持多数据 lane,如 GC2053 传感器配备 2 个数据 lane(基于 D-PHY),对应 4 根物理数据线。默认情况下,单独提及 “lane” 时,均指 “数据通道”。
3. 功能描述¶
sensor padmux设置可以为sensor 上下电提供需要的reset 和power down引脚电压,并按照sensor需要的上下电时序进行变化。同时也提供了主从设备之间i2c引脚的配置,用于读写sensor端的寄存器。sensor padmux 提供了多组mipi mode 设定,通过修改使用的mode可以使用对应引脚将数据传到IC内部。
-
不同chip支持的mclk频率存在差异,iford 支持的mclk如下

mclk支持配置时钟类型
4. 硬件连接介绍¶
4.1. 硬件接口确认¶
注意:
iford 最高规格支持MIPI0(4lane)。MIPI0 可以拆分为MIPI00和MIPI01 --snr00和snr01
Iford系列mipi 4lane支持接入4lane sensor,也兼容2lane的sensor。mipi 2lane支持接入2lane sensor,也兼容 1lane sensor。Comake_Pi_D2的配套sensor IMX681是一个2lane sensor,下面以Comake_Pi_D2与 IMX681 sensor 为例,进行介绍。
确认soc芯片哪些引脚和sensor连接
4lane mipi mode:
如下所示为Comake_Pi_D2的snr0 4lane的原理图,4lane兼容2lane。如下图所示,snr0连接到SJ6接线座上
"681_D0P/N"、"MIPI_D0P/N"和"PAD_OUTP/N_RX0_CH[1]"是连接的
"681_D1P/N"、"MIPI_D1P/N"和"PAD_OUTP/N_RX0_CH[0]"是连接的
"681_CKP/N"、"MIPI_CKP/N"和"PAD_OUTP/N_RX0_CH[2]"是连接的
"471_D2N/P"、"MIPI_D2P/N"和"PAD_OUTP/N_RX0_CH[3]"是连接的。
"471_D3N/P"、"MIPI_D3P/N"和"PAD_OUTP/N_RX0_CH[4]"是连接的。

由上述可知,可以总结对应如下的表格
| MIPI | PAD |
|---|---|
| MIPI_D0N/P(data0 lane) | PAD_OUTN/P_RX0_CH[1] |
| MIPI_D1N/P(data1 lane) | PAD_OUTN/P_RX0_CH[0] |
| clock lane(MIPI_CKP) | PAD_OUTN/P_RX0_CH[2] |
| MIPI_D2N/P(data2 lane) | PAD_OUTN/P_RX0_CH[3] |
| MIPI_D3N/P(data3 lane) | PAD_OUTN/P_RX0_CH[4] |
综合硬件原理图,通过查阅 HW Checklist ,如下表可知,目前snr0 mipi_mode选择mode 5

如果接入的sensor为4lane的,可以参考 mipi pimux 表,将实际的mipi正确接入RX_CH,根据后文的mipi线序描述,配置正确的线序即可。
2+2lane mipi mode
如下所示为Comake_Pi_D2的snr01 2lane的原理图,2lane 线序兼容 4lane,snr00 2lane的原理图可参考上文中的 4lane原理图。snr00的接入方式可参考 4lane 的接入描述,snr01 2lane的接入方式如下

snr01连接到SJ1接线座上
"MIPI01_D0P/N"和"PAD_OUTP/N_RX0_CH[4]"是连接的
"MIPI01_D1P/N"和"PAD_OUTP/N_RX0_CH[3]"是连接的
"MIPI01_CKP/N"和"PAD_OUTP/N_RX0_CH[5]"是连接的。
由上述可知,可以总结对应如下的表格
| MIPI | PAD |
|---|---|
| MIPI_D0N/P(data0 lane) | PAD_OUTN/P_RX0_CH[1] |
| MIPI_D1N/P(data1 lane) | PAD_OUTN/P_RX0_CH[0] |
| clock lane(MIPI_CKP) | PAD_OUTN/P_RX0_CH[2] |
| MIPI01_D0N/P(data0 lane) | PAD_OUTN/P_RX0_CH[4] |
| MIPI01_D1N/P(data1 lane) | PAD_OUTN/P_RX0_CH[3] |
| clock lane(MIPI01_CKP/N) | PAD_OUTN/P_RX0_CH[5] |
综合硬件原理图,通过查阅 HW Checklist ,如上表 mipi pinmux,可知,目前mipi_mode选择 mode 5
mclk_mode 与 rst_mode
通过查阅 HW Checklist 表中的 mipi pinmux 与 PAD_list 表,如上 图4-2 mipi pinmux 与下图可知
mclk_mode
4lane的情况下,mipi_mode = 1,2+2lane的情况下,snr00 mipi_mode = 1,snr01 mipi_mode = 1
rst_mode
4lane的情况下,rst_mode = 1,2+2lane的情况下,snr00 rst_mode = 1,snr01 rst_mode = 1

pdn_mode
pdn实际为控制sensor power down的,对reg_sr00_pdn_mode,reg_sr01_pdn_mode寄存器写不同的值,soc对外的sensor pdn引脚也会不同。dts里用snr_sr0_mipi_pdn_mode配置项对reg_sr00_pdn_mode寄存器传值。需要注意的是,有的sensor pdn引脚可以悬空不接,不需要控制。Comake_Pi_D2板子pdn已接入soc,但默认不使用,具体接入情况可查阅硬件原理图。
配置snr0,snr2各自的reg_mipi_rx_mode,reg_mclk_mode,reg_rst_mode,reg_i2c_mode寄存器为不同值时,有不同的用法,reg_i2c_mode可参考本文的**5.2IIC配置**,下面给出推荐性的使用组合。
| Panmux mode type | 4Lane | 2+2Lane |
|---|---|---|
| Pad num | snr0 | snr0 & snr2 |
| mipi_rx_mode | mode5 | mode5 & mode5 |
| mclk_mode | mode1 | mode1 & mode1 |
| rst_mode | mode1 | mode1 & mode1 |
| I2C_BUS | I2C1 | I2C1 & I2C2 |
4.2. MIPI 接口线序匹配¶
在dts里可以通过csi_sr0_lane_select配置MIPI线序,通过csi_sr0_lane_pn_swap配置mipi线序 P/N 的交换
csi_sr0_lane_select与csi_sr0_lane_pn_swap的配置方法如下所示,请根据实际的硬件连接配置正确的mipi线序
csi_sr0_lane_select = < CLK, DataLane0, DataLane1, DataLane2, DataLane3>
csi_sr0_lane_pn_swap = < CLK, DataLane0, DataLane1, DataLane2, DataLane3>
#其中 CLK,DataLane0,DataLane1等都是相对位置
接下来我们分别以 4lane 和 2+2 lane 为例,详细介绍csi_sr0_lane_select与csi_sr0_lane_pn_swap的用法
4lane :
从**4.1硬件连接介绍**章节的**4lane**介绍中可以得到**如下表**所示*sensor pad匹配关系
| MIPI | PAD |
|---|---|
| MIPI_D0N/P(data0 lane) | PAD_OUTN/P_RX0_CH[1] |
| MIPI_D1N/P(data1 lane) | PAD_OUTN/P_RX0_CH[0] |
| clock lane(MIPI_CKP) | PAD_OUTN/P_RX0_CH[2] |
| MIPI_D2N/P(data2 lane) | PAD_OUTN/P_RX0_CH[3] |
| MIPI_D3N/P(data3 lane) | PAD_OUTN/P_RX0_CH[4] |
综上,所以csi_sr0_lane_select = <2 1 0 3 4>
如果mipi data lane pn 接反,上表中的Polarity接反,则需要设置, csi_sr0_lane_pn_swap = <1 1 1 1 1>;
2+2lane :
从**4.1硬件连接介绍**章节的**2+2lane**介绍中可以得到**如下表**所示*sensor pad匹配关系
| sensor | MIPI | PAD |
|---|---|---|
| snr00 | MIPI_D0N/P(data0 lane) | PAD_OUTN/P_RX0_CH[1] |
| snr00 | MIPI_D1N/P(data1 lane) | PAD_OUTN/P_RX0_CH[0] |
| snr00 | clock lane(MIPI_CKP) | PAD_OUTN/P_RX0_CH[2] |
| snr01 | MIPI01_D0N/P(data0 lane) | PAD_OUTN/P_RX0_CH[3] |
| snr01 | MIPI01_D1N/P(data1 lane) | PAD_OUTN/P_RX0_CH[4] |
| snr01 | clock lane(MIPI01_CKP/N) | PAD_OUTN/P_RX0_CH[5] |
MIPI00 2lane(snr00):
csi_sr0_lane_select = <2 1 0>
如果mipi data lane pn 接反, 则需要设置, csi_sr0_lane_pn_swap = <1 1 1>
MIPI01 2lane(snr01):
注意:csi_sr0_lane_select 的CLK,DataLane0,DataLane1等都是相对位置,所以csi_sr2_lane_select = <2 1 0>
如果mipi data lane pn 接反, 则需要设置, csi_sr2_lane_pn_swap = <1 1 1>
快速确认 lane线序修改方法:
#通过读取寄存器确认 lane 顺序修改 生效
/customer/riu_r 0x1538 # 读取 0x6 0xA 0xE 0x22 0x25 来看顺序是否有生效
#0x1538 为sensor0
#0x153c 为sensor2
快速修改 lane线序方法:
由于修改sensor 线序需要替换kernel,较为麻烦, 可以先用以下方式快速修改线序
通过加载 insmod /config/modules/5.10/mi_sensor.ko gp_sntExternalConfig=/customer/sensorpad0_2lane.json 加载json来配置
例如:
imx681 2lane线序 2 1 0:
{
"SensorIF": [
{
"sensorPad": 0,
"hwClass": "mipi",
"content": {
"lane_number": 2,
"hdr_lane_number": 2,
"lane_select": "2,1,0",
"lane_swap": "0,0,0"
}
}
]
}
5. kernel用法介绍¶
5.1. dts 配置¶
4lane:
csi: csi {
compatible = "sgs,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 = <4>;
/* Config lane selection */
csi_sr0_lane_select = <2 1 3 0 4>;
/* Config lane P/N swap */
csi_sr0_lane_pn_swap = <0 0 0 0 0>;
};
sensorif: sensorif {
compatible = "sgs,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 = <1>;
snr_sr0_mipi_pdn_mode = <0>;
snr_sr0_mipi_mclk_mode = <1>;
snr_sr0_rst_gpio = <-1>;
snr_sr0_pdn_gpio = <-1>;
/* Config mclk 37.125MHz supported */
snr_sr0_mclk_37p125 = <1>;
/* Config i2c for sensor pad */
snr0_mipi_i2c = <1>;
};
2+2lane:
csi: csi {
compatible = "sgs,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 = <2>;
/* Config lane selection */
csi_sr0_lane_select = <2 1 0 3 4>;
csi_sr2_lane_select = <2 1 0>;
/* Config lane P/N swap */
csi_sr0_lane_pn_swap = <0 0 0 0 0>;
csi_sr2_lane_pn_swap = <0 0 0>;
};
sensorif: sensorif {
compatible = "sgs,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 = <1>;
snr_sr0_mipi_pdn_mode = <0>;
snr_sr0_mipi_mclk_mode = <1>;
snr_sr0_rst_gpio = <-1>;
snr_sr0_pdn_gpio = <-1>;
/* Config sensor 2 pad mux */
snr_sr2_mipi_mode = <1>;
snr_sr2_mipi_rst_mode = <1>;
snr_sr2_mipi_pdn_mode = <0>;
snr_sr2_mipi_mclk_mode = <1>;
snr_sr2_rst_gpio = <-1>;
snr_sr2_pdn_gpio = <-1>;
/* Config mclk 37.125MHz supported */
snr_sr0_mclk_37p125 = <1>;
snr_sr2_mclk_37p125 = <1>;
/* Config i2c for sensor pad */
snr0_mipi_i2c = <1>;
snr2_mipi_i2c = <2>;
};
csi部分释义如下:
| 参数 | 释义 | 备注 |
|---|---|---|
| interrupts | mipi rx csi中断 | 不需要修改 |
| clocks | mipi rx csi时钟源 | 不需要修改 |
| csi_sr0_lane_num | 配置snr0 data lane的初始化数量 | 根据需要初始化,snr0最大有四个data lane,可选值0,1,2,3,4,注意:这里lane_num需要小于等于reg_mipi_mode寄存器指定的lane数量。如果初始化snr0为4lane,实际使用时,也可以只使4lane |
| csi_sr0_lane_select | 配置csi接口snr0 lane的相对线序 | <clk_lane的相对序号 data0_lane的相对序号 data1_lane的相对序号>,相对序号是指clk_lane,data0_lane,data1_lane三者比较各自CH值的大小顺序,CH值最小的相对序号是0,中间的是1,最大的是2。例如当csi_sr0_lane_num=2,结合前面提到的SJ6-snr0线序表,clk_lane接的是CH2,data0_lane接的是CH1,data1_lane接的是CH0,那么 csi_sr0_lane_select=<2 1 0 > |
| csi_sr0_lane_pn_swap | 配置snr0的lane极性是否反转 | <clk_lane的极性反转标志 data0_lane的极性反转标志 data1_lane的极性反转标志> 反转标志值只有两个,0和1。0表示lane的极性没有反转,N线接N线,P线接P线。1表示lane的极性出现反转,N线接了P线,P线接了N线。这是芯片兼容性设计,防止外部电路设计出错改版,只要改这里的配置就行了。Comake_Pi_D2板子snr0的所有lane和snr2的所有lane极性都没有反转。例如 csi_sr0_lane_pn_swap=<0 0 0> |
| csi_sr2_lane_num | 配置snr2 data lane的初始化数量 | 根据需要初始化,snr2最大有2个data lane,可选值0,1 ,2 |
| csi_sr2_lane_select | 配置csi接口snr2 lane的相对线序 | 同上分析 |
| csi_sr2_lane_pn_swap | 配置snr2的lane极性是否反转 | 同上分析,极性没有反转,例如 csi_sr2_lane_pn_swap=<0 0 0> |
sensorif部分释义如下:
| 参数 | 释义 | 备注 |
|---|---|---|
| clocks | sensor mclk时钟源 | 需要按照snr0 snr2的顺序配置 |
| snr_sr0_mipi_mode | snr0 mipi的mode,不同mode主要是csi接口pad(引脚)不同 | 参考hw_checklist的ARMTmux子表 |
| snr_sr0_mipi_rst_mode | snr0用mipi接口时reset引脚的mode,不同mode主要是pad(引脚)差异 | 参考hw_checklist的ARMTmux子表 |
| snr_sr0_mipi_pdn_mode | snr0用mipi接口时pdn引脚的mode,不同mode主要是pad(引脚)差异 | 参考hw_checklist的ARMTmux子表 |
| snr_sr0_mipi_mclk_mode | snr0用mipi接口时mclk引脚的mode,不同mode主要是pad(引脚)差异 | 参考hw_checklist的ARMTmux子表 |
| snr_sr0_rst_gpio | snr0 的reset gpio 引脚index | 同时配置rst mode和rst gpio的话优先使用gpio的设定 |
| snr_sr0_pdn_gpio | snr0 的pdn gpio 引脚设置 | 同时配置pdn mode和pdn gpio的话优先使用gpio的设定 |
| snr_sr0_mclk_37p125 | 配置snr0 支持37.125MHz | 1-支持37.125MHz |
| snr0_mipi_i2c | 配置snr0 使用的i2c bus id | 需要根据实际使用的i2c bus进行配置 |
5.2. IIC 配置¶
如上节所示: 4lane 情况下snr0 绑定 i2c1 mode1, 2+2情况下snr00 和 snr01 绑定i2c1 mode1 和 i2c2 mode1
snr0_mipi_i2c = <1>;
snr2_mipi_i2c = <2>;
snr0 代表MIPI sensor 0
<1> 代表使用I2C bus 1
I2C padmux 在对应kernel\arch\arm64\boot\dts\sgs下面对应padmux的dtsi中配置:
//I2C1 Mode1,sensorif_mipi_grp1_i2c
<PAD_GPIOB_00 PINMUX_FOR_I2C0_MODE_1 MDRV_PUSE_I2C1_SCL>,
<PAD_GPIOB_01 PINMUX_FOR_I2C0_MODE_1 MDRV_PUSE_I2C1_SDA>,
//I2C2 Mode1,sensorif_mipi_grp0_i2c
<PAD_GPIOB_04 PINMUX_FOR_I2C1_MODE_1 MDRV_PUSE_I2C2_SCL>,
<PAD_GPIOB_05 PINMUX_FOR_I2C1_MODE_1 MDRV_PUSE_I2C2_SDA>,
I2c1: /customer/riu_r 0x103c 53 //bit[0:1]是否为对应mode的值
I2c2: trust zone 設置
5.3. 默认sensor驱动加载¶
5.3.1. sensor driver配置¶
insmod /config/modules/5.10/imx307_MIPI.ko chmap=1
chmap 代表用 bit map 的形式配置
sensor 0 bit[0]----> chmap=1
sensor 2 bit[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 部分函数介绍¶
mipi Sensor接口注册列表的handle
| 参数 | 释义 | 备注 |
|---|---|---|
| handle->interface_attr.attr_mipi.mipi_lane_num | 注册设置 MIPI 通道数 | 默认值:4 |
| handle->interface_attr.attr_mipi.mipi_data_format | 注册设置MIPI数据格式 | CUS_SEN_INPUT_FORMAT_YUV422, CUS_SEN_INPUT_FORMAT_RGB, |
| handle->interface_attr.attr_mipi.mipi_yuv_order | 注册设置MIPI yuv 顺序 | 仅适用于 yuv Sensor |
| handle->interface_attr.attr_mipi.mipi_hdr_mode | 注册设置MIPI HDR 模式 | CUS_HDR_MODE_NONE /无 HDR/ CUS_HDR_MODE_SONY_DOL /索尼标准线信息输出/ CUS_HDR_MODE_DCG /双增益 HDR/ CUS_HDR_MODE_EMBEEDED_RAW8 /嵌入式 8bit HDR/ CUS_HDR_MODE_EMBEEDED_RAW10 /嵌入式 10bit HDR/ CUS_HDR_MODE_EMBEEDED_RAW12 /嵌入式 12bit HDR/ CUS_HDR_MODE_EMBEEDED_RAW14 /嵌入式 14bit HDR/ CUS_HDR_MODE_EMBEEDED_RAW16 /嵌入式 16bit HDR/ CUS_HDR_MODE_COMP /压缩 HDR/ CUS_HDR_MODE_LI /行交错 HDR/ CUS_HDR_MODE_COMP_VS /压缩 HDR + very short/ CUS_HDR_MODE_VC /虚拟通道模式/ CUS_HDR_MODE_MAX 注意: 在旧版的CUS_HDR_MODE_DCG 代表通过虚拟通道传输的HDR,在新版的架构下更名为CUS_HDR_MODE_VC。 |
| handle->interface_attr.attr_mipi.mipi_hdr_virtual_channel_num | 注册设置HDR虚拟通道数根据各个sensor VC模式头文件定义 | 例如imx415: 长曝光帧数: 0 短曝光帧数: 1 |
| handle->interface_attr.attr_mipi.mipi_hdr_fusion_type | 注册设置 HDR 融合类型 | CUS_HDR_FUSION_TYPE_NONE,(默认) CUS_HDR_FUSION_TYPE_2T1, CUS_HDR_FUSION_TYPE_3T1, |
mipi csi回调函数列表
| 参数 | 释义 | 备注 |
|---|---|---|
| sensor_if->SetCSI_Clk (u32 idx, CUS_CSI_CLK clk) | 参数: idx:Sensor Pad CUS_CSI_CLK:Mipi clk 设置 MIPI 接口 MAC CLK |
回调至 CSI 驱动程序 |
| sensor_if->SetCSI_Lane(u32 idx, u16 num_lane, u8 bon_off) | 参数: idx:Sensor Pad num_lane:Mipi 通道号 bon_off:启用或禁用 设置 MIPI 接口数据通道 |
回调至 CSI 驱动程序 |
| sensor_if->SetCSI_hdr_mode(idx, CUS_HDR_MODE hdr_mode, u8 bon_off) | 参数: idx:Sensor Pad hdr_mode: bon_off:启用或禁用 设置 HDR 数据格式 |
回调到 CSI 驱动程序 CUS_HDR_MODE_NONE /无 HDR/ CUS_HDR_MODE_SONY_DOL /Sony 标准线信息输出/ CUS_HDR_MODE_DCG /双增益 HDR/ /嵌入式 16 位 HDR/ CUS_HDR_MODE_COMP /压缩 HDR/ CUS_HDR_MODE_LI /线交错 HDR/ CUS_HDR_MODE_COMP_VS /压缩 HDR + very short/ CUS_HDR_MODE_VC /虚拟通道模式/ CUS_HDR_MODE_MAX |
| sensor_if->SetCSI_LongPacketType(u32 idx, u16 dt0_15, u16 dt16_31, u16 u32_47) | 参数: idx:Sensor Pad 类型[15:0],[31:16],[47:32] 设置 MIPI 长数据包类型启用 |
回调至 CSI 驱动程序长数据包类型启用 [0]: Null [1]: blinking [2]: embedded [14]: YUV422_8B [26]: RAW8 [27]: RAW10 [28]: RAW12 [29]: RAW14 [30]: RAW16 [32]: UD1 [33]: UD2 [34]: UD3 [35]: UD4 [36]: UD5 [37]: UD6 [38]: UD7 [39]: UD8 |
| Sensor_if->SetCSI_yuv_order_swap(u32 idx, u8 swap) | 参数: idx:Sensor Pad swap:启用或禁用 设置 MIPI 输入 YUV422 数据顺序交换 |
回调至 CSI 驱动程序 |
sensorif回调函数列表的handle
| 参数 | 释义 | 备注 |
|---|---|---|
| sensor_if->PowerOff(u32 idx, CUS_CLK_POL pol); | 参数: idx:Sensor Pad CUS_CLK_POL:拉高或拉低 设置 Sensor-IF PowerDown 是否拉高。 |
回调至 VIF司机 |
| sensor_if->Reset(u32 idx, CUS_CLK_POL pol); | 参数: idx:Sensor Pad CUS_CLK_POL:拉高或拉低 设置 Sensor-IF SW RESET 是否拉高。 |
回调至VIF 驱动程序 |
| sensor_if->MCLK(u32 idx , u8 bon_off, CUS_MCLK_FREQ mclk); | 参数: idx:Sensor Pad bon_off:启用或禁用 CUS_MCLK_FREQ:Sensor clk 注册设置 VIF 模块输出 MCLK 到Sensor用于 MI 查询!! |
主芯片支持 MCLK 列表为: CUS_CMU_CLK_27MHZ, CUS_CMU_CLK_21P6MHZ, CUS_CMU_CLK_12MHZ, CUS_CMU_CLK_5P4MHZ, CUS_CMU_CLK_36MHZ, CUS_CMU_CLK_54MHZ, CUS_CMU_CLK_43P2MHZ, CUS_CMU_CLK_61P7MHZ, CU S_CMU_CLK_72MHZ, CUS_CMU_CLK_48MHZ, CUS_CMU_CLK_24MHZ, CUS_CMU_CLK_37P125MHZ, CUS_CMU_CLK_LPLL_DIV1, CUS_CMU_CLK_LPLL_DIV2, CUS_CMU_CLK_LPLL_DIV4, CUS_CMU_CLK_LPLL_DIV8, |
| sensor_if->SetIOPad (u32 idx, CUS_SENIF_BUS ulSnrType, NULL) | 参数: idx:Sensor Pad CUS_SENIF_BUS:Sensor接口 用于 SENSOR-IF I/O 总线模式 |
回调至 VIF 驱动程序 |
| sensor_if->SetSkipFrame(u32 idx, u16 skip_num, u8 bon_off) | 参数: idx:Sensor Pad skip_num:跳过帧cnt bon_off:启用或禁用 跳过vif输出帧 |
回调至VIF驱动程序 |
更多请参考Sensor_Porting_Guide
5.5. sensor驱动开发¶
不同接口类型的sensor 驱动实现基本一样,具体请参考Sensor_Guide
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 数 | 种类 | 关键指标 | 数据格式 | Souffle | Iford |
|---|---|---|---|---|---|---|
| MIPI | 4Lane | IMX415 | 3840x2160@30FPS, 3F HDR, 4lane | Bayer | Pass | Pass |
| SC450AI | 2688x1520@60FPS, 4lane | Bayer | Pass | Pass | ||
| SC830AI | 3840x2160@30FPS, 4lane | Bayer | Pass | None | ||
| OS08A10 | 3840x2160@60FPS, 4lane | Bayer | Pass | None | ||
| OS12D40 | 4512x2512@30fps, 4lane | Bayer | Pass | None | ||
| OS04C10 | 2560x1440@30fps, 4lane | Bayer | Pass | None | ||
| IMX675 | 2592x1944@30fps, HDR, 4lane | Bayer | Pass | None | ||
| IMX485 | 3840x2160@30FPSs, HDR, 4lane | Bayer | Pass | None | ||
| AR0830 | 3848x2168@30FPSs, HDR, 4lane | Bayer | Pass | None | ||
| OS05A10 | 2592x1944@30FPSs, 4lane | Bayer | Pass | None | ||
| 2lane/4lane | IMX307 | 1920x1080@30FPS, 2F HDR, 2/4lane | Bayer | Pass | Pass | |
| OS04A10 | 2688x1520@30FPS, 2lane/4lane | Bayer | Pass | None | ||
| 1 lane | OG0VA1B | 1920x1080@30FPS, 1lane | Bayer | Pass | None |
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 中断信息