为R329添加i2c设备
添加设备树
设备树在/linux/arch/arm64/boot/dts/allwinner/
路径下,和r329相关的设备树有
sun50i-r329-maix-iia.dtsi
sun50i-r329-maixsense.dts
sun50i-r329.dtsi
三个,其中没有i2c的定义。
参考下隔壁H6的设备树:
引脚定义:
i2c0_pins: i2c0-pins {
pins = "PD25", "PD26";
function = "i2c0";
};
I2C描述:
i2c0: i2c@5002000 {
compatible = "allwinner,sun50i-h6-i2c",
"allwinner,sun6i-a31-i2c";
reg = <0x05002000 0x400>;
interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&ccu CLK_BUS_I2C0>;
resets = <&ccu RST_BUS_I2C0>;
pinctrl-names = "default";
pinctrl-0 = <&i2c0_pins>;
status = "disabled";
#address-cells = <1>;
#size-cells = <0>;
};
注册引脚
原理图如下:
在pinctrl中,可以看到PH8 PH9是i2c1:
SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 8),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "i2c1"), /* SDA */
SUNXI_FUNCTION(0x3, "spi1"), /* WP/DBI-TE */
SUNXI_FUNCTION(0x4, "ledc"), /* DO */
SUNXI_FUNCTION(0x5, "ir"), /* TX */
SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 8)), /* PH_EINT8 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 9),
SUNXI_FUNCTION(0x0, "gpio_in"),
SUNXI_FUNCTION(0x1, "gpio_out"),
SUNXI_FUNCTION(0x2, "i2c1"), /* SCK */
SUNXI_FUNCTION(0x3, "spi1"), /* HOLD/DBI-DCX/DBI-WRX */
SUNXI_FUNCTION(0x4, "spdif"), /* IN */
SUNXI_FUNCTION(0x5, "ir"), /* RX */
SUNXI_FUNCTION_IRQ_BANK(0x6, 3, 9)), /* PH_EINT9 */
在pio: pinctrl@2000400添加引脚定义:
i2c1_ph_pins: i2c1-ph-pins {
pins = "PH8", "PH9";
function = "i2c1";
};
添加i2c描述
查找i2c寄存器地址
在USER manual中
7.1.5 Register List
Module Name | BaseAddress |
---|---|
TWI0 | 0x02502000 |
TWI1 | 0x02502400 |
R_TWI0 | 0x07081400 |
这里使用的是TWI1,因此地址是0x02502400,地址范围0x400;
查找compatible
在 linux/drivers/i2c/busses/
没有相关描述,抄一个隔壁的
查找中断号
Interrupt Number | Interrupt Source |
---|---|
41 | TWI0 |
42 | TWI1 |
参考标准串口使用的GIC_SPI
(SPI:shared processor interrupts 中断号 32 ~32+224),
得到r_uart的中断号42-32=10
查找时钟及复位号
在#include <dt-bindings/clock/sun50i-r329-ccu.h>
和#include <dt-bindings/reset/sun50i-r329-ccu.h>
中
#define RST_BUS_I2C1 18
#define CLK_BUS_I2C1 37
整体描述如下:
i2c1: i2c@2502400{
compatible = "allwinner,sun6i-a31-i2c";
reg = <0x02502400 0x400>;
interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&ccu CLK_BUS_I2C1>;
resets = <&ccu RST_BUS_I2C1>;
pinctrl-names = "default";
pinctrl-0 = <&i2c1_ph_pins>;
status = "disabled";
};
添加到dtbs文件中。
启用I2C设备
在sun50i-r329-maixsense.dts中开启i2c1
&i2c1{
status = "okay";
};
声明i2c1设备名
aliases {
serial0 = &uart0;
serial1 = &r_uart;
mmc0 = &mmc0;
i2c1 = &i2c1;
};
编译,然后将设备树文件放入maixsense中。
测试
启动后,可以列出i2c设备:
maixsense:~:# ls /sys/bus/i2c/devices
i2c-1
maixsense:~:# ls /dev/i2c*
/dev/i2c-1
完整设备树文件见linux/arch/arm64/boot/dts/allwinner at r329-wip · USTHzhanglu/linux (github.com)