歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux基礎 >> Linux教程

Linux設備模型之spi子系統

相比於前面介紹的i2c子系統(見 http://www.linuxidc.com/Linux/2012-01/52782.htm ),spi子系統相對簡單,和i2c的結構也很相似,這裡主要介紹一下平台無關部分的代碼。先概括的說一下,spi總線或者說是spi控制器用結構體struct spi_master來表述,而一般不會明顯的主動實現這個結構而是借助板級的一些信息結構,利用spi的模型填充,存在板級信息的一條鏈表board_list,上面掛接著板級spi設備的描述信息,其掛接的結構是struct boardinfo,這個結構內部嵌入了具體的板級spi設備所需信息結構struct spi_board_info,對於要操控的spi設備,用struct spidev_data來描述,內嵌了具體設備信息結構struct spi_device,並通過struct spi_device->device_entry成員掛接到全局spi設備鏈表device_list,結構struct spi_device就是根據前面board_list上所掛的信息填充的,而driver端比較簡單,用struct spi_driver來描述,一會兒會看到該結構和標准的platform非常相似,總括的說下一般編寫流程:對於soc,spi控制器一般注冊成platform,當driver匹配後,會根據platform_device等信息構造出spi_master,一般發生在driver的probe函數,並且注冊該master,在master的注冊過程中會去遍歷board_list找到bus號相同的spi設備信息,並實例化它,好了先就說這麼多,下面先看一下具體的數據結構。

一、spi相關的數據結構

      先看一下spi設備的板級信息填充的結構:

      [cpp]

  1. struct boardinfo {  
  2.     struct list_head    list;              //用於掛接到鏈表頭board_list上                 
  3.     unsigned        n_board_info;      //設備信息號,spi_board_info成員的編號   
  4.     struct spi_board_info   board_info[0];     //內嵌的spi_board_info結構   
  5. };  
  6. //其中內嵌的描述spi設備的具體信息的結構struct spi_board_info為:   
  7. struct spi_board_info {  
  8.     /* the device name and module name are coupled, like platform_bus; 
  9.      * "modalias" is normally the driver name. 
  10.      * 
  11.      * platform_data goes to spi_device.dev.platform_data, 
  12.      * controller_data goes to spi_device.controller_data, 
  13.      * irq is copied too 
  14.      */  
  15.     char        modalias[SPI_NAME_SIZE];     //名字   
  16.     const void  *platform_data;              //如同注釋寫的指向spi_device.dev.platform_data   
  17.     void        *controller_data;            //指向spi_device.controller_data   
  18.     int     irq;                         //中斷號   
  19.     /* slower signaling on noisy or low voltage boards */  
  20.     u32     max_speed_hz;                //時鐘速率   
  21.     /* bus_num is board specific and matches the bus_num of some 
  22.      * spi_master that will probably be registered later. 
  23.      * 
  24.      * chip_select reflects how this chip is wired to that master; 
  25.      * it's less than num_chipselect. 
  26.      */  
  27.     u16     bus_num;                     //所在的spi總線編號   
  28.     u16     chip_select;                     
  29.     /* mode becomes spi_device.mode, and is essential for chips 
  30.      * where the default of SPI_CS_HIGH = 0 is wrong. 
  31.      */  
  32.     u8      mode;                        //模式   
  33.     /* ... may need additional spi_device chip config data here. 
  34.      * avoid stuff protocol drivers can set; but include stuff 
  35.      * needed to behave without being bound to a driver: 
  36.      *  - quirks like clock rate mattering when not selected 
  37.      */  
  38. };   

     利用boardinfo->list成員會將自身掛接到全局的board_list鏈表上。

     再來看一下spi控制器的表述結構:

  [cpp]

  1. struct spi_master {  
  2.     struct device   dev;                //內嵌的標准dev結構   
  3.     /* other than negative (== assign one dynamically), bus_num is fully 
  4.      * board-specific.  usually that simplifies to being SOC-specific. 
  5.      * example:  one SOC has three SPI controllers, numbered 0..2, 
  6.      * and one board's schematics might show it using SPI-2.  software 
  7.      * would normally use bus_num=2 for that controller. 
  8.      */  
  9.     s16         bus_num;                  //標識的總線號   
  10.     /* chipselects will be integral to many controllers; some others 
  11.      * might use board-specific GPIOs. 
  12.      */  
  13.     u16         num_chipselect;  
  14.     /* some SPI controllers pose alignment requirements on DMAable 
  15.      * buffers; let protocol drivers know about these requirements. 
  16.      */  
  17.     u16         dma_alignment;           //dma對其要求   
  18.     /* spi_device.mode flags understood by this controller driver */  
  19.     u16         mode_bits;               //代表操作的spi_device.mode   
  20.     /* other constraints relevant to this driver */  
  21.     u16         flags;                   //另外的一些標志   
  22. #define SPI_MASTER_HALF_DUPLEX  BIT(0)      /* can't do full duplex */   
  23. #define SPI_MASTER_NO_RX    BIT(1)      /* can't do buffer read */   
  24. #define SPI_MASTER_NO_TX    BIT(2)      /* can't do buffer write */   
  25.     /* lock and mutex for SPI bus locking */  
  26.     spinlock_t      bus_lock_spinlock;  
  27.     struct mutex        bus_lock_mutex;  
  28.     /* flag indicating that the SPI bus is locked for exclusive use */  
  29.     bool            bus_lock_flag;  
  30.     /* Setup mode and clock, etc (spi driver may call many times). 
  31.      * 
  32.      * IMPORTANT:  this may be called when transfers to another 
  33.      * device are active.  DO NOT UPDATE SHARED REGISTERS in ways 
  34.      * which could break those transfers. 
  35.      */  
  36.     int         (*setup)(struct spi_device *spi);   //設置模式   
  37.     /* bidirectional bulk transfers 
  38.      * 
  39.      * + The transfer() method may not sleep; its main role is 
  40.      *   just to add the message to the queue. 
  41.      * + For now there's no remove-from-queue operation, or 
  42.      *   any other request management 
  43.      * + To a given spi_device, message queueing is pure fifo 
  44.      * 
  45.      * + The master's main job is to process its message queue, 
  46.      *   selecting a chip then transferring data 
  47.      * + If there are multiple spi_device children, the i/o queue 
  48.      *   arbitration algorithm is unspecified (round robin, fifo, 
  49.      *   priority, reservations, preemption, etc) 
  50.      * 
  51.      * + Chipselect stays active during the entire message 
  52.      *   (unless modified by spi_transfer.cs_change != 0). 
  53.      * + The message transfers use clock and SPI mode parameters 
  54.      *   previously established by setup() for this device 
  55.      */  
  56.     int         (*transfer)(struct spi_device *spi,    //傳輸函數   
  57.                         struct spi_message *mesg);  
  58.     /* called on release() to free memory provided by spi_master */  
  59.     void            (*cleanup)(struct spi_device *spi);  
  60. };  

   而對於要操控的spi總線上的設備,其表述結構為:

[cpp]

  1. struct spi_device {  
  2.     struct device       dev;               //內嵌標准device結構體   
  3.     struct spi_master   *master;         //spi主控制器   
  4.     u32         max_speed_hz;              //時鐘速率   
  5.     u8          chip_select;               //設備編號   
  6.     u8          mode;                      //模式   
  7. #define SPI_CPHA    0x01            /* clock phase */   
  8. #define SPI_CPOL    0x02            /* clock polarity */   
  9. #define SPI_MODE_0  (0|0)           /* (original MicroWire) */   
  10. #define SPI_MODE_1  (0|SPI_CPHA)   
  11. #define SPI_MODE_2  (SPI_CPOL|0)   
  12. #define SPI_MODE_3  (SPI_CPOL|SPI_CPHA)   
  13. #define SPI_CS_HIGH 0x04            /* chipselect active high? */   
  14. #define SPI_LSB_FIRST   0x08            /* per-word bits-on-wire */   
  15. #define SPI_3WIRE   0x10            /* SI/SO signals shared */   
  16. #define SPI_LOOP    0x20            /* loopback mode */   
  17. #define SPI_NO_CS   0x40            /* 1 dev/bus, no chipselect */   
  18. #define SPI_READY   0x80            /* slave pulls low to pause */   
  19.     u8          bits_per_word;  
  20.     int         irq;                        //中斷號   
  21.     void            *controller_state;        //控制狀態   
  22.     void            *controller_data;         //私有數據   
  23.     char            modalias[SPI_NAME_SIZE];  //名字   
  24.     /* 
  25.      * likely need more hooks for more protocol options affecting how 
  26.      * the controller talks to each chip, like: 
  27.      *  - memory packing (12 bit samples into low bits, others zeroed) 
  28.      *  - priority 
  29.      *  - drop chipselect after each word 
  30.      *  - chipselect delays 
  31.      *  - ... 
  32.      */  
  33. };  
Copyright © Linux教程網 All Rights Reserved