Skip to content

移植-外设接口

本文档介绍 I2C / SPI 外设接口的适配方法,包括节点查看、硬件信息与设备树修改示例。

I2C

在 Rhino Pi A1R 的板子上,有四组 I2C 在使用,通过以下命令可以查看这些 I2C 所对应的节点:

bash
ls -l /sys/bus/i2c/devices/i2c*

命令输出示例:

text
lrwxrwxrwx 1 root root 0 Jan  1  1970 /sys/bus/i2c/devices/i2c-0 -> ../../../devices/platform/soc@0/9c0000.geniqup/980000.i2c/i2c-0
lrwxrwxrwx 1 root root 0 Jan  1  1970 /sys/bus/i2c/devices/i2c-13 -> ../../../devices/platform/soc@0/ac0000.geniqup/a94000.i2c/i2c-13

对应的硬件信息如下:

I2C 节点基地址GPIO 引脚硬件节点
i2c-09880000/1qupv3_id_0-i2c0
i2c-13a9400052/53qupv3_id_1-i2c13

修改示例:RTC 芯片 INS5830B

RTC 芯片 INS5830B 使用的 I2C 引脚是 GPIO0 和 GPIO1。

sc7280.dtsi 中配置了这两个引脚的 I2C 复用:

text
layers/meta-qcom-hwe/recipes-kernel/linux/linux-qcom-custom/kernel-source/arch/arm64/boot/dts/qcom/sc7280.dtsi
dts
i2c0: i2c@980000 {
    compatible = "qcom,geni-i2c";
    reg = <0 0x00980000 0 0x4000>;
    clocks = <&gcc GCC_QUPV3_WRAP0_S0_CLK>;
    clock-names = "se";
    pinctrl-names = "default";
    pinctrl-0 = <&qup_i2c0_data_clk>;
    interrupts = <GIC_SPI 601 IRQ_TYPE_LEVEL_HIGH>;
    #address-cells = <1>;
    #size-cells = <0>;
    interconnects = <&clk_virt MASTER_QUP_CORE_0 0 &clk_virt SLAVE_QUP_CORE_0 0>,
                    <&gem_noc MASTER_APPSS_PROC 0 &cnoc2 SLAVE_QUP_0 0>,
                    <&aggre1_noc MASTER_QUP_0 0 &mc_virt SLAVE_EBI1 0>;
    interconnect-names = "qup-core", "qup-config", "qup-memory";
    power-domains = <&rpmhpd SC7280_CX>;
    required-opps = <&rpmhpd_opp_low_svs>;
    dmas = <&gpi_dma0 0 0 QCOM_GPI_I2C>,
           <&gpi_dma0 1 0 QCOM_GPI_I2C>;
    dma-names = "tx", "rx";
    status = "disabled";
};

qup_i2c0_data_clk: qup-i2c0-data-clk-state {
    pins = "gpio0", "gpio1";
    function = "qup00";
};

qcm6490-addons-idp.dts 中,于 qupv3_hub_i2c2 下配置了 RTC 的设备树节点:

text
layers/meta-qcom-hwe/recipes-kernel/linux/linux-qcom-custom/kernel-source/arch/arm64/boot/dts/qcom/qcm6490-addons-idp.dts
dts
&i2c0 {
    clock-frequency = <100000>;
    status = "okay";

    qps615_switch: pcie-switch@77 {
        compatible = "qcom,switch-i2c";
        reg = <0x77>;
        vdda-supply = <&qps615_rsex_vreg>;
        status = "okay";
    };

    ins5830b: ins5830b@32 {
        compatible = "dptel,rtc-ins5830b";
        reg = <0x32>;
        pinctrl-names = "default";
        pinctrl-0 = <&ins5830b_int_default>;
        interrupt-parent = <&tlmm>;
        interrupts = <104 IRQ_TYPE_EDGE_FALLING>;
        status = "okay";
    };
};

SPI

在 Rhino Pi A1R 的板子上,有四组 SPI 在使用,通过以下命令可以查看这些 SPI 所对应的节点:

bash
ls -l /sys/bus/spi/devices/

命令输出示例:

text
total 0
lrwxrwxrwx 1 root root 0 Aug 18 09:24 spi12.0 -> ../../../devices/platform/soc@0/ac0000.geniqup/a90000.spi/spi_master/spi12/spi12.0
lrwxrwxrwx 1 root root 0 Aug 18 09:24 spi14.0 -> ../../../devices/platform/soc@0/ac0000.geniqup/a98000.spi/spi_master/spi14/spi14.0
lrwxrwxrwx 1 root root 0 Aug 18 09:24 spi3.0 -> ../../../devices/platform/soc@0/9c0000.geniqup/98c000.spi/spi_master/spi3/spi3.0
lrwxrwxrwx 1 root root 0 Aug 18 09:24 spi6.0 -> ../../../devices/platform/soc@0/9c0000.geniqup/998000.spi/spi_master/spi6/spi6.0

对应的硬件信息如下:

SPI 节点基地址GPIO 引脚硬件节点
spi3.098c00012/13/14/15qupv3_id_0-spi3
spi6.099800024/25/26/27qupv3_id_0-spi6
spi12.0a9000048/49/50/51qupv3_id_1-spi12
spi14.0a9800056/57/58/59qupv3_id_1-spi14

修改示例:CAN 芯片 MCP2518

CAN 芯片 MCP2518 使用的 SPI 引脚是 GPIO48 到 GPIO51。

sc7280.dtsi 中配置了这几个引脚的 QUP 复用(TZ 中配置了 SE1 的 QUP 类型为 SPI):

text
layers/meta-qcom-hwe/recipes-kernel/linux/linux-qcom-custom/kernel-source/arch/arm64/boot/dts/qcom/sc7280.dtsi
dts
spi12: spi@a90000 {
    compatible = "qcom,geni-spi";
    reg = <0 0x00a90000 0 0x4000>;
    clocks = <&gcc GCC_QUPV3_WRAP1_S4_CLK>;
    clock-names = "se";
    pinctrl-names = "default";
    pinctrl-0 = <&qup_spi12_data_clk>, <&qup_spi12_cs>;
    interrupts = <GIC_SPI 357 IRQ_TYPE_LEVEL_HIGH>;
    #address-cells = <1>;
    #size-cells = <0>;
    power-domains = <&rpmhpd SC7280_CX>;
    operating-points-v2 = <&qup_opp_table>;
    interconnects = <&clk_virt MASTER_QUP_CORE_1 0 &clk_virt SLAVE_QUP_CORE_1 0>,
                    <&gem_noc MASTER_APPSS_PROC 0 &cnoc2 SLAVE_QUP_1 0>;
    interconnect-names = "qup-core", "qup-config";
    dmas = <&gpi_dma1 0 4 QCOM_GPI_SPI>,
           <&gpi_dma1 1 4 QCOM_GPI_SPI>;
    dma-names = "tx", "rx";
    status = "disabled";
};

qup_spi12_data_clk: qup-spi12-data-clk-state {
    pins = "gpio48", "gpio49", "gpio50";
    function = "qup14";
};

qup_spi12_cs: qup-spi12-cs-state {
    pins = "gpio51";
    function = "qup14";
};

qcm6490-addons-idp.dts 中配置了 spi12 的设备树节点,使用了上面的 pinctrl:

text
layers/meta-qcom-hwe/recipes-kernel/linux/linux-qcom-custom/kernel-source/arch/arm64/boot/dts/qcom/qcm6490-addons-idp.dts
dts
&spi12 {
    status = "okay";
    can@0 {
        compatible = "microchip,mcp2518fd";
        reg = <0>;
        clock-frequency = <40000000>;
        interrupt-parent = <&tlmm>;
        interrupts = <41 0>;
        interrupt-names = "can_irq";
        spi-max-frequency = <10000000>;
        gpio-controller;
        pinctrl-names = "default";
        pinctrl-0 = <&can0_int>;
        status = "ok";
    };
};