Linux中SPI子系统图解和mini2440下的SPI驱动移植

转自:https://blog.csdn.net/viewsky11/article/details/11877619

1.SPI子系统框图详解

SPI总线上有两类设备:

一类是主控端,通常作为SOC系统的一个子模块出现,比如很多嵌入式MPU中都常常包含SPI模块。

一类是受控端,例如一些SPI接口的Flash、传感器等等。主控端是SPI总线的控制者,通过使用SPI协议主动发起SPI总线上的会话。而受控端则被动接受SPI主控端的指令,并作出响应的响应。

图1 SPI子系统框图

如图1所示,linux下的spi子系统主要涉及3个部分:

spi核心、spiprotocol驱动和spi主控制器驱动。

如图1.1,spi核心负责抽象出所有控制器都具备的功能代码,同时向上为spiprotocol驱动提供接口比如spi_message、spi_transfer,spi_async等,具体可参见linux/spi/spi.h文件,需要自己写客户驱动的可以详细了解一下spi.h文件。

图 1.1 SPI协议驱动、SPI CORE、SPI MASTER驱动

spi控制器驱动负责与具体的控制器硬件沟通,进行bit级的数据传输。

spi客户驱动,即protocol驱动负责从控制器端接收数据,然后按照“protocol”将其解释为有意义的数据格式。

图2 SPI子系统总线及设备、驱动注册

图2则显示了Linux下SPI子系统所涉及的大部分结构和函数调用,其中一些细节可以在这里找到你想要得。

1. spi master设备对应的platform_device向platform bus注册

主要通过platform.c或者dts文件解析为SPI master创建platform device 并挂接到platform bus上;

2. spi master驱动对应的platfrom_driver向platform bus注册

主要通过spi master驱动中的platform_driver_register将spi master代表的platform driver挂接到platform bus上;

3.通过spi core的spi_init执行spi_bus注册及spi class注册

4.spi master向spi bus注册

主要通过spi_master的probe函数中spi_bitbang_start完成spi_register_master

5.spi slave device向spi bus注册

spi_register_master执行过程中,会扫描board info, board info记录了spi slave device的信息,

如果发现board info中spi device的master号与自己相同则会调用spi_add_device将spi_device注册到spi bus上

6. spi slave driver向spi bus注册

通过spi slave driver的probe中调用spi_register_driver完成spi slave driver项spi bus的注册

2. SPI 驱动移植

平台:mini2440

kernel:linux-2.6.32.2

Master:SPI0

Slave:of

从图2中我们看出,要进行驱动移植,大致要做的就是完成上面的6个主要结构的注册,使系统能够识别他们。

首先:在LinuxSource Code中修改arch/arm/mach-s3c2440/mach-mini2440.c文件,加入头文件:

  1. #include<linux/spi/spi.h>   
  2. #include<../mach-s3c2410/include/mach/spi.h>  

接着是各个结构的注册:

s3c_device_spi0:在devs.c中定义,需要在板级文件mach-mini2440.c中mini2440_devices[]平台数组中添加如下代码:

&s3c_device_spi0,  

s3c2410_spi_info:就是s3c_device_spi0的platform_data,用来初始化master,给出了总线有几条,和其相连的slave数量,设置片选的函数...也需要在mach-mini2440.c中加入:

  1. static structs3c2410_spi_info s3c2410_spi0_platdata = {  
  2.     .pin_cs= S3C2410_GPG(2),//这个得看你的板子具体情形了   
  3.     .num_cs= 1, //有一个slave   
  4.     .bus_num= 0, //只有一条SPI总线   
  5.     .gpio_setup =s3c24xx_spi_gpiocfg_bus0_gpe11_12_13,  
  6. };  

接着在mini2440_machine_init中加入:

  1. s3c_device_spi0.dev.platform_data=&s3c2410_spi0_platdata;  

controller的平台驱动:s3c24xx_spi_driver,在makemenuconfig时打开便好;

总线spi_bus_type:spi核心,在makemenuconfig时打开便好;

controller驱动:也不需要动;

板级设备信息,即你的slave和总线的连接:

  1. spi_board_info:在mach-mini2440.c中加入s3c2410_spi0_board,如下  
  2. static structspi_board_info s3c2410_spi0_board[] = {  
  3.     [0] = {  
  4.         .modalias= "adns3080", //需要和你的驱动一致   
  5.         .bus_num= 0,  
  6.         .platform_data =&adns3080_data,  
  7.         .chip_select= 0,  
  8.         .irq =IRQ_EINT9,  
  9.         .max_speed_hz= 500 * 1000,  
  10.     }  
  11. };  

外加头文件(有必要的话):adns3080.h

  1. #ifndef __SPI_PLATFORM_ADNS3080_H__   
  2. #define __SPI_PLATFORM_ADNS3080_H__   
  3. struct adns3080_platform_data{  
  4.     your_data_0;  
  5. };  
  6. #endif   
  7. static structadns3080_platform_data adns3080_data = {  
  8.     .your_data_0 =your_data,  
  9. };  

接着在mini2440_machine_init中加入:

spi_register_board_info(s3c2410_spi0_board,ARRAY_SIZE(s3c2410_spi0_board));  

6. my_driver:其实可以没有my_driver这一步,这需要你自己写的,在module_init中会注册的...也可以使用kernel自带的spidev.c驱动,这就需要打开SPIDEV的支持:

在makemenuconfig时:

Device Drivers

SPI support

User mode SPIdevicedriver support //打开这一项

然后是板级信息:

7.接着就不是结构注册,上面如果是板级,下面就得是芯片级了。配置文件的改动:

需要修改arch/arm/plat-s3c24xx/KConfig文件

 

找到如下代码段:

  1. configS3C24XX_SPI_BUS0_GPE11_GPE12_GPE13  
  2.     bool  
  3.     help  
  4.     SPI GPIOconfiguration code for BUS0 when connected to GPE11, GPE12 andGPE13.  
  1. configS3C24XX_SPI_BUS1_GPG5_GPG6_GPG7  
  2.     bool  
  3.     help  
  4.     SPI GPIOconfiguration code for BUS 1 when connected to GPG5, GPG6 andGPG7.  
 
  1. configS3C24XX_SPI_BUS0_GPE11_GPE12_GPE13  
  2.     bool"S3C24XX_SPI_BUS0_GPE11_GPE12_GPE13" // 管脚可以看芯片手册   
  3.     help  
  4.     SPI GPIOconfiguration code for BUS0 when connected to GPE11, GPE12 andGPE13.  //spi_bus0   
  5.   
  6. configS3C24XX_SPI_BUS1_GPG5_GPG6_GPG7  
  7.     bool"S3C24XX_SPI_BUS1_GPG5_GPG6_GPG7"  
  8.     help  
  9.     SPI GPIOconfiguration code for BUS 1 when connected to GPG5,GPG6 and GPG7. //spi_bus1  

最后的make menuconfig了.

 

posted @ 2018-03-29 15:42  jasonactions  阅读(430)  评论(0)    收藏  举报