spi 结构体清单


0 总线私有资源
struct subsys_private {
struct kset subsys;
struct kset *devices_kset;
struct list_head interfaces;
struct mutex mutex;


struct kset *drivers_kset;
struct klist klist_devices;
struct klist klist_drivers;
struct blocking_notifier_head bus_notifier;
unsigned int drivers_autoprobe:1;
struct bus_type *bus;


struct kset glue_dirs;
struct class *class;
};


1 SPI的主机和从机通信接口,也就是SPI总线
struct bus_type {  
       const char              *name;     //总线的名字  
       struct bus_attribute *bus_attrs;  
       struct device_attribute    *dev_attrs;  
       struct driver_attribute    *drv_attrs;   
  
//总线上的device和driver的匹配,匹配成功返回非0值  
       int (*match)(struct device *dev, struct device_driver *drv);  
       int (*uevent)(struct device *dev, struct kobj_uevent_env *env);  
       //当新的device或driver加到总线上的时候,调用driver中的probe函数经行匹配  
       int (*probe)(struct device *dev);  
       int (*remove)(struct device *dev);  
       void (*shutdown)(struct device *dev);  
       int (*suspend)(struct device *dev, pm_message_t state);  
       int (*resume)(struct device *dev);  
       const struct dev_pm_ops *pm;  
       struct subsys_private *p;  
};  


2 SPI设备
struct spi_device {  
      struct device          dev;  
      struct spi_master    *master;    //SPI控制器  
       u32                max_speed_hz;  //最大时钟频率  
       u8                  chip_select;     //片选  
       u8                  mode;          //SPI模式  
#define    SPI_CPHA     0x01                     /* clock phase */  
#define    SPI_CPOL     0x02                     /* clock polarity */  
#define    SPI_MODE_0       (0|0)                     /* (original MicroWire) */  
#define    SPI_MODE_1       (0|SPI_CPHA)  
#define    SPI_MODE_2       (SPI_CPOL|0)  
#define    SPI_MODE_3       (SPI_CPOL|SPI_CPHA)  
#define    SPI_CS_HIGH      0x04                     /* chipselect active high? */  
#define    SPI_LSB_FIRST    0x08                     /* per-word bits-on-wire */  
#define    SPI_3WIRE   0x10                     /* SI/SO signals shared */  
#define    SPI_LOOP     0x20                     /* loopback mode */  
#define    SPI_NO_CS   0x40                     /* 1 dev/bus, no chipselect */  
#define    SPI_READY  0x80                     /* slave pulls low to pause */  
       u8                  bits_per_word;              //一次传输的bits,可以是8、16、32,默认是8  
       int                 irq;                   
       void               *controller_state;  
       void               *controller_data;          
       char               modalias[SPI_NAME_SIZE];  //别名,用于device和driver的匹配  
};  



3 SPI驱动
struct spi_driver {  
       const struct spi_device_id *id_table;  
       int                 (*probe)(struct spi_device *spi);  //绑定驱动和SPI设备  
         int                 (*remove)(struct spi_device *spi);  
       void               (*shutdown)(struct spi_device *spi);  
       int                 (*suspend)(struct spi_device *spi, pm_message_t mesg);  
       int                 (*resume)(struct spi_device *spi);  
  
       struct device_driver         driver;  
};  


  
4  SPI主控制器  :
struct spi_master {  
       struct device   dev;   //驱动的设备接口  
       struct list_head list;        //SPI控制器的链表头  
       s16                bus_num;    //总线号  
       u16                num_chipselect;    //SPI设备的片选号  
         u16                dma_alignment;     //dma模式    
       u16                mode_bits;           
       u16                flags;  
#define SPI_MASTER_HALF_DUPLEX    BIT(0)           /* can't do full duplex */  
#define SPI_MASTER_NO_RX   BIT(1)           /* can't do buffer read */  
#define SPI_MASTER_NO_TX    BIT(2)           /* can't do buffer write */  
      spinlock_t              bus_lock_spinlock;  
       struct mutex           bus_lock_mutex;  
  
        bool               bus_lock_flag;  
       int                 (*setup)(struct spi_device *spi);   //更新SPI设备的模式和SPI设备的采样时钟  
       int                 (*transfer)(struct spi_device *spi,    //添加一个消息到控制器的传输队列  
                                          struct spi_message *mesg);  
       void               (*cleanup)(struct spi_device *spi);  
  int (*transfer)(struct spi_device *spi,
struct spi_message *mesg);
  
};  



5  SPI传输  
struct spi_transfer {  
     const void       *tx_buf;    //发送缓冲区  
       void        *rx_buf;                //接收缓冲区
       unsigned  len;                       //数据长度  
       dma_addr_t    tx_dma;       //tx_buf的DMA地址  
       dma_addr_t    rx_dma;         //rx_buf的DMA地址  
      unsigned  cs_change:1;     //片选位
      u8           bits_per_word;       //传输的bytes数,不选就用默认的  
       u16         delay_usecs;                  //微秒延时,用以传输数据后,改变片选信号前  
       u32         speed_hz;            //传输速率,不选就用默认的  
      struct list_head transfer_list;     //传输链表,用以传输spi_message  
}; 


6  spi 对SPI控制器的抽象,SPI控制器接口
struct spi_message {  
       struct list_head       transfers;   //挂接在本 message下的transfers链表头
       struct spi_device     *spi;      //加到传输队列中的spi设备  
        unsigned         is_dma_mapped:1;   //DMA传输控制位  
       void               (*complete)(void *context);      //传输完成 回调函数  
       void               *context;        //complete函数的参数                  
       unsigned         actual_length;    //所有成功传输字段的总长度  
       int                 status;       //传输成功返回0,否则返回错误  
       struct list_head  queue; //链表字段queue用于把该挂在代表控制器的spi_message的queue字段上,   
       void        *state;  
};  
void spi_message_init(structspi_message *m);   初始化
spi_message_add_tail()                         向 spi_message 添加 spi_transfers
spi_async() 准备好了spi_message,就可以使用spi_async来向SPI系统提交了
            异步通信,提交之后马上返回,使用spi_async 需要注意的是:
在complete()没有返回之前不要轻易访问你提交的 spi_transfer 中的buffer。
也不要释放SPI系统正在使用的buffer,一谈你的complete返回了,这些buffe就又
不是你的了
使用完成回调机制有些复杂,可以使用SPI系统提供的另一种同步版本
; spi_sync

int spi_sync(struct spi_device *spi,struct spi_message *message);
因为是同步的,spi_sync 提交完 spi_message 后不会立即返回,会一直等待被处理,
一旦返回就可以重新使用buffer了,




在SPI控制器里面最常用的用来处理传输的结构体spi_bitbang了
struct spi_bitbang {  
       struct workqueue_struct *workqueue;  
       struct work_struct   work;  
  
       spinlock_t              lock;  
       struct list_head       queue;  
  
       u8                  busy;  
       u8                  use_dma;  
       u8                  flags;             /* extra spi->mode support */  
  
       struct spi_master    *master;  
  
       /* setup_transfer() changes clock and/or wordsize to match settings  
      * for this transfer; zeroes restore defaults from spi_device.  
        */  
       int   (*setup_transfer)(struct spi_device *spi,  
                     struct spi_transfer *t);  
  
        void (*chipselect)(struct spi_device *spi, int is_on);  
#define    BITBANG_CS_ACTIVE      1     /* normally nCS, active low */  
#define    BITBANG_CS_INACTIVE   0  
  
   
  
       /* txrx_bufs() may handle dma mapping for transfers that don't  
        * already have one (transfer.{tx,rx}_dma is zero), or use PIO  
        */  
       int   (*txrx_bufs)(struct spi_device *spi, struct spi_transfer *t);  
  
       /* txrx_word[SPI_MODE_*]() just looks like a shift register */  
       u32  (*txrx_word[4])(struct spi_device *spi,  
                     unsigned nsecs,  
                     u32 word, u8 bits);  
  
};  





































评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Linux老A

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值