?????? 既然知道了協議了,那么就可以開始去瞧瞧linux kenerl中的spi的驅動代碼了,代碼中有很多的結構體,還是對主要的結構體先做個了解吧,那樣才可以很好的理解驅動。主要是include/linux/spi.h
?
首先是SPI的主機和從機通信接口,也就是SPI總線,
extern struct bus_type spi_bus_type;
bus_type定義在linux/device.h中
?
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;
};
?
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,默認是8int irq; void *controller_state;void *controller_data; char modalias[SPI_NAME_SIZE]; //別名,用于device和driver的匹配
};
?
?
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;
};
?
SPI主控制器
?
struct spi_master {struct device dev; //驅動的設備接口struct list_head list; //SPI控制器的鏈表頭s16 bus_num; //總線號/* chipselects will be integral to many controllers; some others* might use board-specific GPIOs.*/u16 num_chipselect; //SPI設備的片選號u16 dma_alignment; //dma模式 /* spi_device.mode flags understood by this controller driver */u16 mode_bits; /* other constraints relevant to this driver */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 *//* lock and mutex for SPI bus locking */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);};
?
SPI傳輸
?
struct spi_transfer {/* it's ok if tx_buf == rx_buf (right?)* for MicroWire, one buffer must be null* buffers must work with dma_*map_single() calls, unless* spi_message.is_dma_mapped reports a pre-existing mapping*/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};
?
SPI消息
?
struct spi_message {struct list_head transfers; // struct spi_device *spi; //加到傳輸隊列中的spi設備unsigned is_dma_mapped:1; //DMA傳輸控制位/* completion is reported through a callback */void (*complete)(void *context); //傳輸完成void *context; //complete函數的參數 unsigned actual_length; //所有成功傳輸字段的總長度int status; //傳輸成功返回0,否則返回錯誤/* for optional use by whatever driver currently owns the* spi_message ... between calls to spi_async and then later* complete(), that's the spi_master controller driver.*/struct list_head queue;void *state;};
?
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);};
??????? 在SPI控制器里面最常用的用來處理傳輸的結構體spi_bitbang了。
?
SPI borad info
struct spi_board_info {/* the device name and module name are coupled, like platform_bus;* "modalias" is normally the driver name.** platform_data goes to spi_device.dev.platform_data,* controller_data goes to spi_device.controller_data,* irq is copied too*/char modalias[SPI_NAME_SIZE];const void *platform_data;void *controller_data;int irq;/* slower signaling on noisy or low voltage boards */u32 max_speed_hz;/* bus_num is board specific and matches the bus_num of some* spi_master that will probably be registered later.** chip_select reflects how this chip is wired to that master;* it's less than num_chipselect.*/u16 bus_num;u16 chip_select;/* mode becomes spi_device.mode, and is essential for chips* where the default of SPI_CS_HIGH = 0 is wrong.*/u8 mode;/* ... may need additional spi_device chip config data here.* avoid stuff protocol drivers can set; but include stuff* needed to behave without being bound to a driver:* - quirks like clock rate mattering when not selected*/
};
?????? 控制器里會讀取borad info里的參數
?
SPI gpio_platform_data
?
struct spi_gpio_platform_data {unsigned sck;unsigned mosi;unsigned miso;u16 num_chipselect;};
??????? 因為我用的比較多的是GPIO模擬的,所以還是記錄下這個從platform傳進來的管腳號。
?
?????? OK,對于SPI用到的結構體基本上已經介紹完了,那么接下來就介紹其主要函數了。
?