移植-外设接口
本文档介绍 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-0 | 988000 | 0/1 | qupv3_id_0-i2c0 |
i2c-13 | a94000 | 52/53 | qupv3_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.dtsidts
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.dtsdts
&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.0 | 98c000 | 12/13/14/15 | qupv3_id_0-spi3 |
spi6.0 | 998000 | 24/25/26/27 | qupv3_id_0-spi6 |
spi12.0 | a90000 | 48/49/50/51 | qupv3_id_1-spi12 |
spi14.0 | a98000 | 56/57/58/59 | qupv3_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.dtsidts
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.dtsdts
&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";
};
};