SPI驱动模型框架及spidev.c分析---学习记录
SPI设备如何使用
一般我们使用spi设备驱动是类似文件操作,使用open/read/write/ioctl这些去控制/dev/spix.x,而/dev/spix.x是spi设备驱动实现的。而spi 控制器驱动实现的则是从设备树解析出spi 控制器与设备端的映射关系,并且实现传输接口。
SPI驱动模型框架
SPI驱动分成两部分:SPI控制器或者叫SPI Master,SPI 设备端或者SPI Slave。
先看设备树节点:
&ecspi3 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_ecspi3>;
cs-gpios = <&gpio1 20 GPIO_ACTIVE_LOW>;
status = "okay";
spidev: icm20608@0{
compatible = "invensense,icm20608";
interrupt-parent = <&gpio1>;
interrupts = <1 1>;
spi-max-frequency = <8000000>;
reg = <0>;
};
};
ecspi3是控制器节点,在这之下有一个spi设备节点(spidev: icm20608@0)。
那么我们要写驱动应该怎么写呢?猜想应该是要分别实现SPI 控制器以及SPI 设备端。
SPI 控制器/SPI Master分析
如上设备树节点,在设备树的结构里spi控制器为大节点,然后在其内部创建spi设备节点,如下图设备树节点事例。
使用platform总线驱动用来与设备树中的SPI 控制器节点进行匹配,在下图中platform device自然是从设备树中获取,platform driver我们用module_platform_driver或者platform_driver_register来注册。并通过设备树中的compatible属性匹配。最后进入到probe函数中做下一步处理(如下图中的spi_gpio_probe)
这里以spi-imx.c(实现的是SPI 控制器的驱动代码)代码分析:
用一句话概括就是做了三件事:
1.创建spi_master,这个结构体里包含有传输数据的实现。
2.解析出SPI 控制器节点下的所有设备节点,创建spi_device与每一个设备节点对应.
3.映射spi_master与spi_device关系,并初始化硬件信息,实现传输数据。
具体如下:
在spi_imx_probe函数中用spi_alloc_master创建一个spi_master结构体,然后spi_bitbang_start-->spi_register_master---->of_register_spi_devices函数中把设备树中的每一个spi控制器节点下的设备节点(如上图gpio_spi)创建spi_device结构体,这样spi_device与spi_master(如上图的spi3)就有了映射关系,以后操作设备节点的时候,就可以通过spi_device设备节点找到与之对应的spi_master,然后调用spi_master里的传输接口来传输数据。具体传输数据是如何实现的可以在spi-imx.c查看下面设置的3个接口实现
1.spi_imx_probe-->(spi_imx->bitbang.txrx_bufs = spi_imx_transfer;)
2.spi_imx_probe-->spi_bitbang_start-->(master->transfer_one = spi_bitbang_transfer_one;)
3.spi_imx_probe-->spi_bitbang_start-->spi_register_master--> spi_master_initialize_queue-->(master->transfer_one_message = spi_transfer_one_message;)
SPI 设备端/SPI Slave分析
设备端这块就相对简单,因为在SPI 控制器的驱动里已经实现了获取设备端的节点,也就是实现了下图中spi总线下的spi_device,所以我们使用spi_register_driver注册spi_driver结构体,然后实现file_operations结构体的open/read/write/ioctl,这块linux自带的spidev.c已经实现了。
SPI 控制器/SPI Master与SPI 设备端/SPI Slave驱动模型
如下图,类似在SPI 控制器驱动代码下的probe分枝下挂载SPI 设备端驱动代码
Linux内核自带的SPI 设备端/SPI Slave代码spidev.c
spidev.c实现的就是常规的字符设备驱动,调用spi_register_driver注册spi_driver结构体。
只要你在设备树文件里SPI控制器节点下的设备节点里的compatible = "rohm,dh2228fv";如下图
那么就能与SPI 控制器驱动代码里spi_device匹配到,这样就会进入spidev_probe里创建/dev/spix.x。以后当你open的时候,就会获取到SPI 控制器驱动代码里的spi_device,然后用spi_master进行数据传输。
小结
可以看出spidev.c的作用相当于创建一个字符设备然后与设备树里SPI控制器下的设备节点匹配。
这块之所以能够与任何SPI设备通用,就是因为分离出了SPI 控制器的驱动,我们只需要实现SPI 控制器需要做的事情就好。
原文地址:https://blog.csdn.net/weixin_42717961/article/details/144309185
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!