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 {       struct list_head    list;              //用于挂接到链表头board_list上                 
  2.     unsigned        n_board_info;      //设备信息号,spi_board_info成员的编号        struct spi_board_info   board_info[0];     //内嵌的spi_board_info结构   
  3. };   //其中内嵌的描述spi设备的具体信息的结构struct spi_board_info为:   
  4. struct spi_board_info {       /* the device name and module name are coupled, like platform_bus; 
  5.      * "modalias" is normally the driver name.       * 
  6.      * platform_data goes to spi_device.dev.platform_data,       * controller_data goes to spi_device.controller_data, 
  7.      * irq is copied too       */  
  8.     char        modalias[SPI_NAME_SIZE];     //名字        const void  *platform_data;              //如同注释写的指向spi_device.dev.platform_data   
  9.     void        *controller_data;            //指向spi_device.controller_data        int     irq;                         //中断号   
  10.     /* slower signaling on noisy or low voltage boards */       u32     max_speed_hz;                //时钟速率   
  11.     /* bus_num is board specific and matches the bus_num of some       * spi_master that will probably be registered later. 
  12.      *       * chip_select reflects how this chip is wired to that master; 
  13.      * it's less than num_chipselect.       */  
  14.     u16     bus_num;                     //所在的spi总线编号        u16     chip_select;                     
  15.     /* mode becomes spi_device.mode, and is essential for chips       * where the default of SPI_CS_HIGH = 0 is wrong. 
  16.      */       u8      mode;                        //模式   
  17.     /* ... may need additional spi_device chip config data here.       * avoid stuff protocol drivers can set; but include stuff 
  18.      * needed to behave without being bound to a driver:       *  - quirks like clock rate mattering when not selected 
  19.      */   };   

     利用boardinfo->list成员会将自身挂接到全局的board_list链表上。

     再来看一下spi控制器的表述结构:

  [cpp]

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

   而对于要操控的spi总线上的设备,其表述结构为:

[cpp]

  1. struct spi_device {       struct device       dev;               //内嵌标准device结构体   
  2.     struct spi_master   *master;         //spi主控制器        u32         max_speed_hz;              //时钟速率   
  3.     u8          chip_select;               //设备编号        u8          mode;                      //模式   
  4. #define SPI_CPHA    0x01            /* clock phase */    #define SPI_CPOL    0x02            /* clock polarity */   
  5. #define SPI_MODE_0  (0|0)           /* (original MicroWire) */    #define SPI_MODE_1  (0|SPI_CPHA)   
  6. #define SPI_MODE_2  (SPI_CPOL|0)    #define SPI_MODE_3  (SPI_CPOL|SPI_CPHA)   
  7. #define SPI_CS_HIGH 0x04            /* chipselect active high? */    #define SPI_LSB_FIRST   0x08            /* per-word bits-on-wire */   
  8. #define SPI_3WIRE   0x10            /* SI/SO signals shared */    #define SPI_LOOP    0x20            /* loopback mode */   
  9. #define SPI_NO_CS   0x40            /* 1 dev/bus, no chipselect */    #define SPI_READY   0x80            /* slave pulls low to pause */   
  10.     u8          bits_per_word;       int         irq;                        //中断号   
  11.     void            *controller_state;        //控制状态        void            *controller_data;         //私有数据   
  12.     char            modalias[SPI_NAME_SIZE];  //名字        /* 
  13.      * likely need more hooks for more protocol options affecting how       * the controller talks to each chip, like: 
  14.      *  - memory packing (12 bit samples into low bits, others zeroed)       *  - priority 
  15.      *  - drop chipselect after each word       *  - chipselect delays 
  16.      *  - ...       */  
  17. };  

此文章由 http://www.ositren.com 收集整理 ,地址为: http://www.ositren.com/htmls/58029.html