1. 程式人生 > >深入淺出spi驅動之資料結構(一)

深入淺出spi驅動之資料結構(一)

Allein.Cao原創作品,轉載請註明出處:

核心版本:2.6.32.2

硬體:S3C2440 

SPI匯流排是一種比較通用的資料傳輸匯流排,遵從主從模式,由主裝置發起通訊請求,通常工作於全雙工模式,由4條資料時鐘線組成,下面這段話摘自s3c2440資料手冊:

There are 4 I/O pin signals associated with SPItransfers: SCK (SPICLK0,1), MISO (SPIMISO0,1) data line, MOSI (SPIMOSI0,1) dataline and active low /SS (nSS0,1) pin (input).

  • 確定驅動檔案

 SPI作為Linux裡面比較小的一個子系統,其驅動程式位於/drivers/spi/*目錄,首先,我們可以通過Makefile及Kconfig來確定我們需要看的原始檔:

Makefile:

  1. <prename="code"class="csharp">#  
  2. # Makefile for kernel SPI drivers.  
  3. #  
  4. ……………………………………………….  
  5. # small core, mostly translating board-specific  
  6. # config declarations into driver model code  
  7. obj-$(CONFIG_SPI_MASTER)        += spi.o              
  8. # SPI master controller drivers (bus)  
  9. …………………………………………………  
  10. obj-$(CONFIG_SPI_BITBANG)       += spi_bitbang.o  
  11. …………………………………………………  
  12. obj-$(CONFIG_SPI_S3C24XX_GPIO)      += spi_s3c24xx_gpio.o  
  13. obj-$(CONFIG_SPI_S3C24XX)       += spi_s3c24xx.o  
  14. …………………………………………………  
  15. #   ... add above this line ...  
  16. # SPI protocol drivers (device/link on bus)  
  17. obj-$(CONFIG_SPI_SPIDEV)    += spidev.o  
  18. …………………………………………………  
  19. #   ... add above this line ...</pre>
  20. <pre></pre>
  21. <p></p>
  22. <p>通過以上分析我們知道,spi驅動由三部分組成,分別是core(spi.c),master controller driver (spi_s3c24xx.c or spi_s3c24xx_gpio.)以及SPIprotocol drivers (spidev.c),這裡spi_s3c24xx_gpio.c檔案是用普通的io口來模擬spi時序,具體見Kconfig描述:</p>
  23. <prename="code"class="csharp">config SPI_S3C24XX_GPIO  
  24.     tristate "Samsung S3C24XX series SPI by GPIO"  
  25.     depends on ARCH_S3C2410 && EXPERIMENTAL  
  26.     select SPI_BITBANG  
  27.     help  
  28.       SPI driver for Samsung S3C24XX series ARM SoCs using  
  29.       GPIO lines to provide the SPI bus. This can be used where  
  30.       the inbuilt hardware cannot provide the transfer mode, or  
  31.       where the board is using non hardware connected pins.  
  32. </pre>
  33. <p>在此,我們以spi控制器方式進行分析。</p>
  34. <p></p>
  35. <ul>
  36. <li>資料結構</li></ul>
  37. <p></p>
  38. <p>Spi驅動涉及的<ahref="http://lib.csdn.net/base/datastructure"class="replace_word"title="演算法與資料結構知識庫"target="_blank"style="color:#df3434; font-weight:bold;">資料結構</a>主要位於/include/<ahref="http://lib.csdn.net/base/linux"class="replace_word"title="Linux知識庫"target="_blank"style="color:#df3434; font-weight:bold;">linux</a>/spi.h,對各個結構有比較詳細的解釋,限於篇幅,簡單介紹如下:</p>
  39. <p>1、Spi_device代表一個外圍spi裝置,由master controller driver註冊完成後掃描BSP中註冊裝置產生的裝置連結串列並向spi_bus註冊產生。</p>
  40. <p></p>
  41. <prename="code"class="csharp">struct spi_device {  
  42.     struct device       dev;            //裝置模型使用  
  43.     struct spi_master   *master;        //裝置使用的master結構  
  44.     u32         max_speed_hz;   //通訊時鐘  
  45.     u8          chip_select;        //片選號,每個master支援多個spi_device  
  46.     u8          mode;           //裝置支援的模式,如片選是高or低?  
  47. #define SPI_CPHA    0x01            /* clock phase */  
  48. #define SPI_CPOL    0x02            /* clock polarity */  
  49. #define SPI_MODE_0  (0|0)           /* (original MicroWire) */  
  50. #define SPI_MODE_1  (0|SPI_CPHA)  
  51. #define SPI_MODE_2  (SPI_CPOL|0)  
  52. #define SPI_MODE_3  (SPI_CPOL|SPI_CPHA)  
  53. #define SPI_CS_HIGH 0x04            /* chipselect active high? */  
  54. #define SPI_LSB_FIRST   0x08            /* per-word bits-on-wire */  
  55. #define SPI_3WIRE   0x10            /* SI/SO signals shared */  
  56. #define SPI_LOOP    0x20            /* loopback mode */  
  57. #define SPI_NO_CS   0x40            /* 1 dev/bus, no chipselect */  
  58. #define SPI_READY   0x80            /* slave pulls low to pause */  
  59.     u8          bits_per_word;  //每個字長的位元數  
  60.     int         irq;                //中斷號  
  61.     void            *controller_state;  //控制器暫存器狀態  
  62.     void            *controller_data;  
  63.     char            modalias[SPI_NAME_SIZE];    //裝置名稱  
  64. };  
  65. </pre>
  66. <p>2、  spi_driver代表一個SPI protocol drivers,即外設驅動。</p>
  67. <p></p>
  68. <prename="code"class="csharp">struct spi_driver {  
  69.     const struct spi_device_id *id_table;       //支援的spi_device裝置表  
  70.     int         (*probe)(struct spi_device *spi);   //probe函式  
  71.     int         (*remove)(struct spi_device *spi);  
  72.     void            (*shutdown)(struct spi_device *spi);  
  73.     int         (*suspend)(struct spi_device *spi, pm_message_t mesg);  
  74.     int         (*resume)(struct spi_device *spi);  
  75.     struct device_driver    driver;     //裝置模型使用  
  76. };  
  77. </pre>
  78. <p>3、spi_master代表一個主機控制器,此處即S3C2440中的SPI控制器</p>
  79. <p></p>
  80. <prename="code"class="csharp">struct spi_master {  
  81.     struct device   dev;            //裝置模型使用  
  82.     s16         bus_num;    //master編號,s3c2440有2個spi控制器,編號為0 1  
  83.     u16         num_chipselect;     //支援的片選的數量,從裝置的片選