歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux教程 >> Linux設備模型之spi子系統

Linux設備模型之spi子系統

日期:2017/2/28 15:58:18   编辑:Linux教程
相比於前面介紹的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