內核版本:3.9.5
spi_master
struct spi_master用來描述一個SPI主控制器,我們一般不需要自己編寫spi控制器驅動.
1 /*結構體master代表一個SPI接口,或者叫一個SPI主機控制器,一個接口對應一條SPI總線,master->bus_num則記錄了這個總線號*/ 2 struct spi_master { 3 struct device dev; 4 5 struct list_head list; 6 7 /* other than negative (== assign one dynamically), bus_num is fully 8 * board-specific. usually that simplifies to being SOC-specific. 9 * example: one SOC has three SPI controllers, numbered 0..2, 10 * and one board's schematics might show it using SPI-2. software 11 * would normally use bus_num=2 for that controller. 12 */ 13 s16 bus_num;/*總線編號,從零開始.系統會用這個值去和系統中board_list鏈表中加入的每一個boardinfo結構 14 (每個boardinfo結構都是一個spi_board_info的集合,每一個spi_board_info都是對應一個SPI(從)設備的描述)中的每一個 15 spi_board_info中的bus_num進行匹配,如果匹配上就說明這個spi_board_info描述的SPI(從)設備是鏈接在此總線上的,因 16 此就會調用spi_new_device去創建一個spi_device*/ 17 18 /* chipselects will be integral to many controllers; some others 19 * might use board-specific GPIOs. 20 */ 21 u16 num_chipselect;//支持的片選的數量.從設備的片選號不能大於這個數.該值當然不能為0,否則會注冊失敗 22 23 /* some SPI controllers pose alignment requirements on DMAable 24 * buffers; let protocol drivers know about these requirements. 25 */ 26 u16 dma_alignment; 27 28 /* spi_device.mode flags understood by this controller driver */ 29 u16 mode_bits; 30 31 /* other constraints relevant to this driver */ 32 u16 flags; 33 #define SPI_MASTER_HALF_DUPLEX BIT(0) /* can't do full duplex */ 34 #define SPI_MASTER_NO_RX BIT(1) /* can't do buffer read */ 35 #define SPI_MASTER_NO_TX BIT(2) /* can't do buffer write */ 36 37 /* lock and mutex for SPI bus locking */ 38 spinlock_t bus_lock_spinlock; 39 struct mutex bus_lock_mutex; 40 41 /* flag indicating that the SPI bus is locked for exclusive use */ 42 bool bus_lock_flag; 43 44 /* Setup mode and clock, etc (spi driver may call many times). 45 * 46 * IMPORTANT: this may be called when transfers to another 47 * device are active. DO NOT UPDATE SHARED REGISTERS in ways 48 * which could break those transfers. 49 */ 50 int (*setup)(struct spi_device *spi);//根據spi設備更新硬件配置 51 52 /* bidirectional bulk transfers 53 * 54 * + The transfer() method may not sleep; its main role is 55 * just to add the message to the queue. 56 * + For now there's no remove-from-queue operation, or 57 * any other request management 58 * + To a given spi_device, message queueing is pure fifo 59 * 60 * + The master's main job is to process its message queue, 61 * selecting a chip then transferring data 62 * + If there are multiple spi_device children, the i/o queue 63 * arbitration algorithm is unspecified (round robin, fifo, 64 * priority, reservations, preemption, etc) 65 * 66 * + Chipselect stays active during the entire message 67 * (unless modified by spi_transfer.cs_change != 0). 68 * + The message transfers use clock and SPI mode parameters 69 * previously established by setup() for this device 70 */ 71 int (*transfer)(struct spi_device *spi, 72 struct spi_message *mesg);/*添加消息到隊列的方法.此函數不可睡眠,其作用只是安排需要的傳送,並且在適當的時候(傳\ 73 送完成或者失敗)調用spi_message中的complete方法,來將結果報告給用戶*/ 74 75 /* called on release() to free memory provided by spi_master */ 76 void (*cleanup)(struct spi_device *spi);/*cleanup函數會在spidev_release函數中被調用,spidev_release被登記為spi dev的release 77 函數*/ 78 79 /* 80 * These hooks are for drivers that want to use the generic 81 * master transfer queueing mechanism. If these are used, the 82 * transfer() function above must NOT be specified by the driver. 83 * Over time we expect SPI drivers to be phased over to this API. 84 */ 85 bool queued; 86 struct kthread_worker kworker; 87 struct task_struct *kworker_task; 88 struct kthread_work pump_messages; 89 spinlock_t queue_lock; 90 struct list_head queue; 91 struct spi_message *cur_msg; 92 bool busy; 93 bool running; 94 bool rt; 95 96 int (*prepare_transfer_hardware)(struct spi_master *master); 97 int (*transfer_one_message)(struct spi_master *master, 98 struct spi_message *mesg); 99 int (*unprepare_transfer_hardware)(struct spi_master *master); 100 /* gpio chip select */ 101 int *cs_gpios; 102 };
spi控制器的驅動一般在arch/.../mach-*/board-*.c聲明,注冊一個平台設備,然后在driver/spi下面建立一個平台驅動.spi_master注冊過程中會掃描arch/.../mach-*/board-*.c 中調用spi_register_board_info注冊的信息,為每一個與本總線編號相同的信息建立一個spi_device.根據Linux內核的驅動模型,注冊在同一總線下的驅動和設備會進行匹配.spi_bus_type總線匹配的依據是名字.這樣當自己編寫的spi_driver和spi_device同名的時候,spi_driver的probe方法就會被調用.spi_driver就能看到與自己匹配的spi_device了.
spi_device
struct spi_device用來描述一個SPI從設備.
1 /*該結構用於描述SPI設備,也就是從設備的相關信息. 2 NOTE:SPI子系統只支持主模式,也就是說SOC上的SPI只能工作在master模式,外圍設備只能為slave模式*/ 3 struct spi_device { 4 struct device dev; 5 struct spi_master *master;//對應的控制器指針 6 u32 max_speed_hz;//spi傳輸時鍾 7 u8 chip_select;//片選號,用來區分同一主控制器上的設備 8 u8 mode;//各bit的定義如下,主要是傳輸模式/片選極性 9 #define SPI_CPHA 0x01 /* clock phase */ 10 #define SPI_CPOL 0x02 /* clock polarity */ 11 #define SPI_MODE_0 (0|0) /* (original MicroWire) */ 12 #define SPI_MODE_1 (0|SPI_CPHA) 13 #define SPI_MODE_2 (SPI_CPOL|0) 14 #define SPI_MODE_3 (SPI_CPOL|SPI_CPHA) 15 #define SPI_CS_HIGH 0x04 /* chipselect active high? *//*片選電位為高*/ 16 #define SPI_LSB_FIRST 0x08 /* per-word bits-on-wire *//*先輸出低比特*/ 17 #define SPI_3WIRE 0x10 /* SI/SO signals shared *//*輸入輸出共享接口,此時只能做半雙工*/ 18 #define SPI_LOOP 0x20 /* loopback mode *//*回寫/回顯模式*/ 19 #define SPI_NO_CS 0x40 /* 1 dev/bus, no chipselect */ 20 #define SPI_READY 0x80 /* slave pulls low to pause */ 21 u8 bits_per_word;/*每個字長的比特數*/ 22 int irq;/*使用到的中斷號*/ 23 void *controller_state; 24 void *controller_data; 25 char modalias[SPI_NAME_SIZE];/*spi設備的名字*/ 26 int cs_gpio; /* chip select gpio */ 27 28 /* 29 * likely need more hooks for more protocol options affecting how 30 * the controller talks to each chip, like: 31 * - memory packing (12 bit samples into low bits, others zeroed) 32 * - priority 33 * - drop chipselect after each word 34 * - chipselect delays 35 * - ... 36 */ 37 };
spi_driver
struct spi_driver用於描述SPI(從)設備驅動.驅動核心將根據driver.name和spi_board_info的modalias進行匹配,如過modalia和name相等,則綁定驅動程序和arch/.../mach-xxx/board-xxx.c中調用spi_register_board_info注冊的信息對應的spi_device設備.它的形式和struct platform_driver是一致的.
1 struct spi_driver { 2 const struct spi_device_id *id_table; 3 int (*probe)(struct spi_device *spi);/*和spi_device匹配成功之后會調用這個方法.因此這個方法需要對設備和私有數據進行初始化*/ 4 int (*remove)(struct spi_device *spi);/*解除spi_device和spi_driver的綁定,釋放probe申請的資源*/ 5 void (*shutdown)(struct spi_device *spi);/*一般牽扯到電源管理會用到,關閉*/ 6 int (*suspend)(struct spi_device *spi, pm_message_t mesg);/*一般牽扯到電源管理會用到,掛起*/ 7 int (*resume)(struct spi_device *spi);/*一般牽扯到電源管理會用到,恢復*/ 8 struct device_driver driver; 9 };
spi_board_info
struct spi_board_info是板級信息,是在移植時就寫好的,並且要將其注冊.
1 /*該結構也是對SPI(從)設備(spi_device)的描述,只不過它是板級信息,最終該結構的所有字段都將用於初始化SPI設備結構體spi_device*/ 2 struct spi_board_info { 3 /* the device name and module name are coupled, like platform_bus; 4 * "modalias" is normally the driver name. 5 * 6 * platform_data goes to spi_device.dev.platform_data, 7 * controller_data goes to spi_device.controller_data, 8 * irq is copied too 9 */ 10 char modalias[SPI_NAME_SIZE];/*spi設備名,會拷貝到spi_device的相應字段中.這是設備spi_device在SPI總線spi_bus_type上匹配驅動的唯一標識*/ 11 const void *platform_data;/*平台數據*/ 12 void *controller_data; 13 int irq;/*中斷號*/ 14 15 /* slower signaling on noisy or low voltage boards */ 16 u32 max_speed_hz;/*SPI設備工作時的波特率*/ 17 18 19 /* bus_num is board specific and matches the bus_num of some 20 * spi_master that will probably be registered later. 21 * 22 * chip_select reflects how this chip is wired to that master; 23 * it's less than num_chipselect. 24 */ 25 u16 bus_num;/*該SPI(從)設備所在總線的總線號,就記錄了所屬的spi_master之中的bus_num編號.一個spi_master就對應一條總線*/ 26 u16 chip_select;/*片選號.該SPI(從)設備在該條SPI總線上的設備號的唯一標識*/ 27 28 /* mode becomes spi_device.mode, and is essential for chips 29 * where the default of SPI_CS_HIGH = 0 is wrong. 30 */ 31 u8 mode;/*參考spi_device中的成員*/ 32 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 };
spi_transfer
struct spi_transfer是對一次完整的數據傳輸的描述.每個spi_transfer總是讀取和寫入同樣長度的比特數,但是可以很容易的使用空指針舍棄讀或寫.為spi_transfer和spi_message分配的內存應該在消息處理期間保證是完整的.
1 struct spi_transfer { 2 /* it's ok if tx_buf == rx_buf (right?) 3 * for MicroWire, one buffer must be null 4 * buffers must work with dma_*map_single() calls, unless 5 * spi_message.is_dma_mapped reports a pre-existing mapping 6 */ 7 const void *tx_buf;/*發送緩沖區地址,這里存放要寫入設備的數據(必須是dma_safe),或者為NULL*/ 8 void *rx_buf;/*接收緩沖區地址,從設備中讀取的數據(必須是dma_safe)就放在這里,或者為NULL*/ 9 unsigned len;/*傳輸數據的長度.記錄了tx和rx的大小(字節數),這里不是指它的和,而是各自的長度,他們總是相等的*/ 10 11 dma_addr_t tx_dma;/*如果spi_message.is_dma_mapped是真,這個是tx的dma地址*/ 12 dma_addr_t rx_dma;/*如果spi_message.is_dma_mapped是真,這個是rx的dma地址*/ 13 14 unsigned cs_change:1;/*影響此次傳輸之后的片選.指示本次transfer結束之后是否要重新片選並調用setup改變設置.若為1則表示當該transfer 15 傳輸完后,改變片選信號.這個標志可以減少系統開銷*/ 16 u8 bits_per_word;/*每個字長的比特數.如果是0,使用默認值*/ 17 u16 delay_usecs;/*此次傳輸結束和片選改變之間的延時,之后就會啟動另一個傳輸或者結束整個消息*/ 18 u32 speed_hz;/*通信時鍾.如果是0,使用默認值*/ 19 20 struct list_head transfer_list;/*用來連接的雙向鏈表節點,用於將該transfer鏈入message*/ 21 };
再說一下:cs_change影響此transfer完成后是否禁用片選線並調用setup改變配置.(這個標志量就是chip select change片選改變的意思).沒有特殊情況,一個spi_message因該只在最后一個transfer置位該標志量.
spi_message
struct spi_message就是對多個spi_transfer的封裝.spi_message用來原子的執行spi_transfer表示的一串數組傳輸請求.這個傳輸隊列是原子的,這意味着在這個消息完成之前不會有其它消息占用總線.消息的執行總是按照FIFO的順序.向底層提交spi_message的代碼要負責管理它的內存空間.未顯示初始化的內存需要使用0來初始化.為spi_transfer和spi_message分配的內存應該在消息處理期間保證是完整的.
1 struct spi_message { 2 struct list_head transfers;/*此次消息的傳輸段(spi_transfer)隊列,一個消息可以包含多個傳輸段(spi_transfer)*/ 3 4 struct spi_device *spi;/*傳輸的目的設備,無論如何這里都是spi從設備,至於數據流向(是從主機到從設備還是從從設備到主機)這是由write/read 5 每個傳輸段(spi_transfer)內部的tx_buf或者是rx_buf決定的*/ 6 7 unsigned is_dma_mapped:1;/*如果為真,此次調用提供dma和cpu虛擬地址.spi主機提供了dma緩存池.如果此消息確定要使用dma(那當然更好 8 了).則從那個緩存池中申請高速緩存.替代傳輸段(spi_transfer)中的tx_buf/rx_buf*/ 9 10 /* REVISIT: we might want a flag affecting the behavior of the 11 * last transfer ... allowing things like "read 16 bit length L" 12 * immediately followed by "read L bytes". Basically imposing 13 * a specific message scheduling algorithm. 14 * 15 * Some controller drivers (message-at-a-time queue processing) 16 * could provide that as their default scheduling algorithm. But 17 * others (with multi-message pipelines) could need a flag to 18 * tell them about such special cases. 19 */ 20 21 /* completion is reported through a callback */ 22 void (*complete)(void *context);/*用於異步傳輸完成時調用的回調函數*/ 23 void *context;/*回調函數的參數*/ 24 unsigned actual_length;/*此次傳輸的實際長度,這個長度包括了此消息spi_message中所有傳輸段spi_transfer傳輸的長度之和(不管每個傳 25 輸段spi_transfer到底是輸入還是輸出,因為本來具體的傳輸就是針對每一個傳輸段spi_transfer來進行的)*/ 26 int status;/*執行的結果.成功被置0,否則是一個負的錯誤碼*/ 27 28 /* for optional use by whatever driver currently owns the 29 * spi_message ... between calls to spi_async and then later 30 * complete(), that's the spi_master controller driver. 31 */ 32 /*下面兩個成員是給擁有本消息的驅動選用的.spi_master會使用它們.自己最好不要使用*/ 33 struct list_head queue;/*用於將該message鏈入bitbang等待隊列*/ 34 void *state; 35 };
spi_bitbang
struct spi_bitbang結構用於控制實際的數據傳輸.
1 struct spi_bitbang { 2 struct workqueue_struct *workqueue;/*工作隊列*/ 3 struct work_struct work; 4 5 spinlock_t lock; 6 struct list_head queue; 7 u8 busy; 8 u8 use_dma; 9 u8 flags; /* extra spi->mode support */ 10 11 struct spi_master *master;/*bitbang所屬的master*/ 12 13 /* setup_transfer() changes clock and/or wordsize to match settings 14 * for this transfer; zeroes restore defaults from spi_device. 15 */ 16 int (*setup_transfer)(struct spi_device *spi, 17 struct spi_transfer *t);/*用於設置設備傳輸時的時鍾,字長等*/ 18 19 void (*chipselect)(struct spi_device *spi, int is_on); 20 #define BITBANG_CS_ACTIVE 1 /* normally nCS, active low */ 21 #define BITBANG_CS_INACTIVE 0 22 23 /* txrx_bufs() may handle dma mapping for transfers that don't 24 * already have one (transfer.{tx,rx}_dma is zero), or use PIO 25 */ 26 int (*txrx_bufs)(struct spi_device *spi, struct spi_transfer *t); 27 28 /* txrx_word[SPI_MODE_*]() just looks like a shift register */ 29 u32 (*txrx_word[4])(struct spi_device *spi, 30 unsigned nsecs, 31 u32 word, u8 bits); 32 };
本文引用:http://blog.csdn.net/yuanlulu/article/details/6318165
