跳转至

SENSOR 使用参考


REVISION HISTORY

Revision No.
Description
Date
1.0
  • Initial release
  • 11/19/2025

    1. 概述

    本文以 IFORD 系列芯片的 Comake_Pi_D2 开发板为例,为图像传感器(sensor)的使用提供参考。使用时需了解一些基础技术知识,包括 MIPI 协议里的 CSI 接口、CCI 接口,以及sensor的规格等。

    为确保图像sensor正常输出图像,请按以下步骤操作:

    1. 确认sensor与 SOC 芯片的硬件连接是否正确;
    2. 明确 SOC 芯片上哪些引脚可用于sensor的 MIPI 接口;
    3. 在设备树(dts)中正确配置 CSI 和 sensor_if 接口参数;
    4. 确认需要加载的模块 ko 文件;
    5. 确认需要加载的sensor驱动 ko 文件;
    6. 正确使用 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]"是连接的。

    图4-1 4lane原理图

    由上述可知,可以总结对应如下的表格

    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

    图4-2 mipi pinmux

    如果接入的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的接入方式如下

    图4-3 snr01 原理图

    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

    图4-3 PAD_List

    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_selectcsi_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_selectcsi_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

    1. 进入alkaid project根目录,make menuconfig

    2. 回车键进入Sensor子选项

    3. 回车键进入Sensor List子选项,写上需要的sensor driver名称

    4. 编辑完成后退出,再回车键进入Sensor0子选项,写上需要预insmod的sensor driver名称

    5. 编辑完成后退出,再回车键进入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文件

    1. 进入alkaid project根目录,make menuconfig

    2. 回车键进入Sensor子选项

    3. 回车键进入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 中断信息

    请参考MI VIF API 章节5.PROCFS介绍