参考资料
https://www.cnblogs.com/aaronLinux/p/6219146.html
1.SPI
2.SPI传输
2.1传输示例
首先,CS0拉低选中的SPI Flash ,
然后在每个时钟周期,
DO输出对应的电平。
SPI FLASH会在每个时钟的上升沿读取D0的电平。
2.2SPI模式
根据SCK的电平以及数据在第一个跳变沿还是第二个跳变沿传输,SPI传输总共有四种模式。
3.SPI总线设备驱动模型
SPI系统中设涉及两类硬件:
SPI控制器
SPI设备
spi控制器有驱动程序,提供spi的传输能力。
spi设备也有自己的驱动程序,提供spi设备的访问能力。
4.spi设备驱动框架图
SPI驱动程序由spi_master及spi_device组成
spi_master是在设备树中定义的spi master及master
下边的device信息;当左边drive中的of_device_id和设备树中的compatible参数匹配的时候,会调用driver中的prboe函数,probe函数会生成master,还会生成spi_device。
spi设备左边包括一个spi驱动,当其中的of_device_id和spi_device匹配时,会调用左边driver中的probe函数。
4.1SPI控制器驱动程序
基于平台总线设备驱动模型实现。在probe函数中除了生成spi_master,还会创建spi_device结构体。
4.2SPI设备驱动程序
左边是spi_drive,里边有id_table表示能支持哪些SPI设备,有probe函数。
右边是spi_device,用来描述spi设备,可以来自设备树或者c文件
5.spi设备树处理过程
5.1spi_device
/*** struct spi_device - Master side proxy for an SPI slave device* @dev: Driver model representation of the device.* @master: SPI controller used with the device.* @max_speed_hz: Maximum clock rate to be used with this chip* (on this board); may be changed by the device's driver.* The spi_transfer.speed_hz can override this for each transfer.* @chip_select: Chipselect, distinguishing chips handled by @master.* @mode: The spi mode defines how data is clocked out and in.* This may be changed by the device's driver.* The "active low" default for chipselect mode can be overridden* (by specifying SPI_CS_HIGH) as can the "MSB first" default for* each word in a transfer (by specifying SPI_LSB_FIRST).* @bits_per_word: Data transfers involve one or more words; word sizes* like eight or 12 bits are common. In-memory wordsizes are* powers of two bytes (e.g. 20 bit samples use 32 bits).* This may be changed by the device's driver, or left at the* default (0) indicating protocol words are eight bit bytes.* The spi_transfer.bits_per_word can override this for each transfer.* @irq: Negative, or the number passed to request_irq() to receive* interrupts from this device.* @controller_state: Controller's runtime state* @controller_data: Board-specific definitions for controller, such as* FIFO initialization parameters; from board_info.controller_data* @modalias: Name of the driver to use with this device, or an alias* for that name. This appears in the sysfs "modalias" attribute* for driver coldplugging, and in uevents used for hotplugging* @cs_gpio: gpio number of the chipselect line (optional, -ENOENT when* when not using a GPIO line)** @statistics: statistics for the spi_device** A @spi_device is used to interchange data between an SPI slave* (usually a discrete chip) and CPU memory.** In @dev, the platform_data is used to hold information about this* device that's meaningful to the device's protocol driver, but not* to its controller. One example might be an identifier for a chip* variant with slightly different functionality; another might be* information about how this particular board wires the chip's pins.*/
struct spi_device {struct device dev;struct spi_master *master;u32 max_speed_hz;/* 该设备能支持的spi时钟最大值 */u8 chip_select;/* 是对应的spi_master下边的第几个设备 */u8 bits_per_word;/* 每个基本的spi传输涉及多少位 */u16 mode; /*spi_chpa spi_cpol组合起来得到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 */
#define SPI_TX_DUAL 0x100 /* transmit with 2 wires */
#define SPI_TX_QUAD 0x200 /* transmit with 4 wires */
#define SPI_RX_DUAL 0x400 /* receive with 2 wires */
#define SPI_RX_QUAD 0x800 /* receive with 4 wires */int irq;void *controller_state;void *controller_data;char modalias[SPI_NAME_SIZE];int cs_gpio; /* chip select gpio *//* the statistics */struct spi_statistics statistics;/** likely need more hooks for more protocol options affecting how* the controller talks to each chip, like:* - memory packing (12 bit samples into low bits, others zeroed)* - priority* - drop chipselect after each word* - chipselect delays* - ...*/
};
5.2设备树中的spi节点
spi4 {compatible = "spi-gpio";/* 这个属性很关键,因为根据这个属性找到spi_master */pinctrl-names = "default";pinctrl-0 = <&pinctrl_spi4>;pinctrl-assert-gpios = <&gpio5 8 GPIO_ACTIVE_LOW>;status = "okay";gpio-sck = <&gpio5 11 0>;gpio-mosi = <&gpio5 10 0>;cs-gpios = <&gpio5 7 0>;num-chipselects = <1>;#address-cells = <1>;/* 这个SPI Master下的SPI设备,需要多少个cell来表述它的片选引脚 */#size-cells = <0>; /* 这个必须设置为0 *//* gpio_spi是spi_master 下边的device节点 */gpio_spi: gpio_spi@0 {compatible = "fairchild,74hc595";/* 根据它找到spi device驱动 */gpio-controller;#gpio-cells = <2>;reg = <0>;/* 使用哪个片选引脚 */registers-number = <1>;registers-default = /bits/ 8 <0x57>;spi-max-frequency = <10000>;/* 该设备支持的最大spi时钟 */};};