add_tca9555_driver - TreeNewbeer/Coonix GitHub Wiki

向内核中添加TCA9555芯片驱动支持

TCA9555是一个I2C接口的16路IO扩展芯片。查阅 dirver/gpio 中的代码发现内核在 gpio-pca953x.c 文件中提供了pca9555的驱动,而没有tca9555的驱动。 经过对比pca9555和tca9555的数据手册发现寄存器定义完全一直。可能是ti出品的就叫tca9555,nxp出品的就叫pca9555吧。

开启内核I2C与GPIO驱动支持

开启内核I2C驱动支持

首先进入linux-menuconfig,找到

  • Device Drivers → (*)I2C support
  • Device Drivers → I2C support → I2C Hardware Bus support → <*> NUC980 I2C Driver for Port 0

开启I2C支持,然后由于与TCA9555相连的是I2C0,所以也要开启NUC980的I2C0支持 至于 NUC980 I2C0 pin selection 这一部分可以不用管,引脚可以在设备树中设置。

开启内核GPIO驱动支持

首先进入linux-menuconfig,找到

  • Device Drivers → GPIO Support
  • Device Drivers → GPIO Support → [*]/sys/class/gpio/... (sysfs interface)
  • Device Drivers → GPIO Support → I2C GPIO expanders → <*> PCA95[357]x, PCA9698, TCA64xx, and MAX7310 I/O ports

这个 /sys/class/gpio 是应用程序操作 GPIO的基础。

修改设备树添加tca9555设备

在设备树中只需要在 i2c0 这个节点下添加一个子节点就好了,就像这样

        i2c0: i2c0@b0080000 {
            status = "okay";
            pinctrl-0 = <&pinctrl_i2c0_PA>;

            tca9555: tca9555@20 {
                compatible = "nxp,pca9555";
                reg = <0x20>;
            };
        };

  • 设置i2c0节点的 status = "okay" 启用 i2c0 节点。
  • 设置pinctrl-0 = <&pinctrl_i2c0_PA> 设置 i2c0 的引脚为PA0, PA1。
  • tca9555: tca9555@20 这一部分是 label: name@<address> 的结构。label和name都可以自己定义,address是指的总线地址。在这里 tca9555 挂在 i2c0 总线下,tca9555 的 i2c 设备地址为 0x20,所以这里的 address 是 20。
  • compatible = "nxp,pca9555"说明这个节点的类型。在加载驱动的时候会自动根据 "nxp,pca9555" 这个字符串找到对应的驱动。
  • reg = <0x20> 设置 tca9555 的 i2c 设备地址为0x20。

做完上述修改就可以编译内核然后烧写了。

用shell操作gpio

首先进入 /sys/class/gpio 目录。输入 ls 命令后显示如下

export       gpiochip0    gpiochip496  unexport

gpiochip0是nuc980自带的gpio,而gpiochip496则是tca9555扩展出来的gpio。可以进入gpiochip496这个文件夹中,发现这个文件夹中有

base       device     label      ngpio      subsystem  uevent 

这么几个文件。用cat可以查看这些文件的内容。

# cat label                                                                     
pca9555                                                                         
# cat base                                                                      
496                                                                             
# cat ngpio                                                                     
16 

所以在 label 文件内容是gpio芯片驱动的名称,base文件中放的是gpio的起始编号,ngpio文件中放的是gpio的数量。

# cat device/of_node/compatible
nxp,pca9555                                                
# cat device/of_node/name                                                       
tca9555

这两个文件中的内容是设备树中该节点的 compatible 字段和节点的名称。

在操作gpio之前首先要导出 gpio ,导出gpio的方法是向 /sys/class/gpio/export 文件中写入 gpio 的编号。在上面通过base文件可以知道tca9555芯片的io-0的编号是496, io-1的编号是497.... 如果需要导出io-0,则需输入

echo 496 > /sys/class/gpio/export

然后会发现 /sys/class/gpio 目录下多了一个 gpio496 文件夹。然后通过向该文件夹中 direction 文件写入 in 或者 out 来控制gpio的方向,比如设置gpio的方向为输出:

echo out > gpio496/direction

通过向 value 文件中写入0或者1来控制io输出电平,也可以读取这个文件来获得io状态。

# echo 1 > gpio496/value                                                        
# cat gpio496/value                                                             
1 

最后,如果gpio使用完毕可以向 /sys/class/gpio/unexport 文件中写入gpio编号取消导出对应的gpio。

# echo 496 > /sys/class/gpio/unexport

执行这条命令之后 gpio496 这个文件夹就消失了。

⚠️ **GitHub.com Fallback** ⚠️