一. 简介
SPI 驱动框架和 I2C 很类似,都分为主机控制器驱动和设备驱动。
SPI主机控制器的驱动一般是芯片半导体厂商写好了,我们要编写的是SPI设备驱动代码。
本文开始来学习SPI设备驱动的编写流程(前提是支持设备树的情况)。
二. SPI 设备驱动编写流程:创建SPI节点以及SPI设备节点(在设备树文件中)
SPI 设备信息描述,针对支持设备树的情况下,就是在设备树文件中创建SPI节点以及SPI设备节点。分为两个部分:
1. 创建IO的 pinctrl节点
2. 创建SPI节点以及SPI设备子节点、
下面分别举例说明,如何创建IO的pinctrl节点,SPI节点以及SPI设备子节点。
1. 创建IO的 pinctrl节点
首先肯定是根据所使用的 IO 来创建或修改 pinctrl 子节点。
注意:唯独要注意的就是检查相应的 IO 有没有被其他的设备所使用,如果有的话需要将其删除掉!
例如,ALPHA开发板上的ICM20608设备是SPI设备,硬件原理图如下:
根据硬件原理图可知,ICM20608设备的SPI使用的是(IMX6ULL的)SPI3接口,的四个IO对应如下:
SPI3_CS -> UART2_TXD
SPI3_SCLK -> UART2_RXD
SPI3_MISO -> UART2_RTS
SPI3_MOSI -> UART2_CTS
所以,在设备树文件中,创建SPI的四个IO的 pinctrl节点为:
pinctrl_ecspi3: icm20608 {fsl,pins = <MX6UL_PAD_UART2_TX_DATA__GPIO1_IO20 0x10b0 /* CS */MX6UL_PAD_UART2_RX_DATA__ECSPI3_SCLK 0x10b1 /* SCLK */MX6UL_PAD_UART2_RTS_B__ECSPI3_MISO 0x10b1 /* MISO */ MX6UL_PAD_UART2_CTS_B__ECSPI3_MOSI 0x10b1 /* MOSI */ >;};
2. 创建SPI节点以及SPI设备子节点
采用设备树的情况下, SPI 设备信息描述就通过创建相应的设备子节点来完成,我们可以 打开 imx6qdl-sabresd.dtsi 这个设备树头文件,在此文件里面找到如下所示内容:
&ecspi1 {fsl,spi-num-chipselects = <1>;cs-gpios = <&gpio4 9 0>;pinctrl-names = "default";pinctrl-0 = <&pinctrl_ecspi1>;status = "okay";flash: m25p80@0 {#address-cells = <1>;#size-cells = <1>;compatible = "st,m25p32";spi-max-frequency = <20000000>;reg = <0>;};
};
示例代码 是 I.MX6Q 的一款板子上的一个 SPI 设备节点,在这个板子的 ECSPI 上接了一个 m25p80 ,这是一个 SPI 接口的设备。
第 2 行,设置 “ fsl,spi-num-chipselects ” 属性为 1 ,表示只有一个设备。
第 3 行,设置“ cs-gpios ”属性,也就是片选信号为 GPIO4_IO09 。
第 4 行,设置“ pinctrl-names ”属性,也就是 SPI 设备所使用的 IO 名字。
第 5 行,设置“ pinctrl-0 ” 属性,也就是所使用的 IO 对应的 pinctrl 节点。
第 6 行,将 ecspi1 节点的“ status ”属性改为“ okay ”。
第 8~14 行, ecspi1 下的 m25p80 设备信息,每一个 SPI 设备都采用一个子节点来描述 其设备信息。
第 8 行的“ m25p80@0 ”后面的“ 0 ”表示 m25p80 的接到了 ECSPI 的通道 0 上。这个要根据自己的具体硬件来设置。
第 11 行, SPI 设备的 compatible 属性值,用于匹配设备驱动。
第 12 行,“ spi-max-frequency ”属性设置 SPI 控制器的最高频率,这个要根据所使用的 SPI 设备(SPI从机设备)来设置。 比如,在这里将 SPI 控制器最高频率设置为 20MHz 。
第 13 行, reg 属性设置 m25p80 这个设备所使用的 ECSPI 通道,和“ m25p80@0 ”后面的 “ 0 ”一样。
后面我们在实现ALPHA开发板上的ICM20608 的设备树节点信息的时候,就可以参考以上SPI节点及SPI设备子节点的编写内容。
也可以查看SPI节点的绑定文档,在Linux内核源码目录下,具体查看绑定文档 fsl-imx-spi.txt,该文档说明了SPI节点如何创建,包括SPI节点必须写的属性或可选的属性。