自学内容网 自学内容网

SPI驱动模型框架及spidev.c分析---学习记录

目录

SPI设备如何使用

SPI驱动模型框架

SPI 控制器/SPI Master分析

SPI 设备端/SPI Slave分析

SPI 控制器/SPI Master与SPI 设备端/SPI Slave驱动模型

Linux内核自带的SPI 设备端/SPI Slave代码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)!