[Mod] 更新文档
This commit is contained in:
139
spi/ReadMe.md
139
spi/ReadMe.md
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
|
|
||||||
## 参考
|
## 参考
|
||||||
|
|
||||||
- linux_5.10/Documentation/spi/spi-summary.rst
|
- linux_5.10/Documentation/spi/spi-summary.rst
|
||||||
|
|
||||||
|
|
||||||
@ -15,10 +16,12 @@
|
|||||||
### 两种SPI驱动
|
### 两种SPI驱动
|
||||||
|
|
||||||
#### Controller drivers ...
|
#### Controller drivers ...
|
||||||
|
|
||||||
此类驱动的对象为SOC片上的SPI控制器,这些控制器通常支持“Master”与“Slave”角色切换。
|
此类驱动的对象为SOC片上的SPI控制器,这些控制器通常支持“Master”与“Slave”角色切换。
|
||||||
此类驱动常直接访问硬件寄存器并使用DMA来提高数据传递效率,或许也可以通过CPU控制数据的每一位来控制可编程GPIO管脚。
|
此类驱动常直接访问硬件寄存器并使用DMA来提高数据传递效率,或许也可以通过CPU控制数据的每一位来控制可编程GPIO管脚。
|
||||||
|
|
||||||
#### Protocol drivers ...
|
#### Protocol drivers ...
|
||||||
|
|
||||||
此类驱动的对象为SOC片外接的SPI设备,这些设备以“Master”或“Slave”角色接入SPI控制器,进而完成数据的传输。
|
此类驱动的对象为SOC片外接的SPI设备,这些设备以“Master”或“Slave”角色接入SPI控制器,进而完成数据的传输。
|
||||||
在SPI驱动之上,可能被具象化为MTD、Audio等设备接入更上一级的子系统。
|
在SPI驱动之上,可能被具象化为MTD、Audio等设备接入更上一级的子系统。
|
||||||
|
|
||||||
@ -56,13 +59,16 @@ SPI设备必须管理以下两种类型内存:
|
|||||||
|
|
||||||
## 示例
|
## 示例
|
||||||
|
|
||||||
### 静态定义
|
### 设备
|
||||||
|
|
||||||
#### 板级设备
|
#### 板级静态定义
|
||||||
|
|
||||||
##### Master
|
##### Master
|
||||||
"struct platform_device"
|
|
||||||
|
- `struct platform_device`, 基于平台设备开发;
|
||||||
|
|
||||||
路径:`arch/.../mach-*/board-*.c`:
|
路径:`arch/.../mach-*/board-*.c`:
|
||||||
|
|
||||||
```c
|
```c
|
||||||
#include <mach/spi.h> /* for mysoc_spi_data */
|
#include <mach/spi.h> /* for mysoc_spi_data */
|
||||||
|
|
||||||
@ -105,8 +111,11 @@ SPI设备必须管理以下两种类型内存:
|
|||||||
...
|
...
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
##### Slave
|
##### Slave
|
||||||
|
|
||||||
文件:`arch/.../mach-*/board-*.c`:
|
文件:`arch/.../mach-*/board-*.c`:
|
||||||
|
|
||||||
```c
|
```c
|
||||||
static struct ads7846_platform_data ads_info = {
|
static struct ads7846_platform_data ads_info = {
|
||||||
.vref_delay_usecs = 100,
|
.vref_delay_usecs = 100,
|
||||||
@ -131,13 +140,121 @@ SPI设备必须管理以下两种类型内存:
|
|||||||
spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
|
spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
|
||||||
```
|
```
|
||||||
|
|
||||||
### 非静态定义
|
#### DTS动态定义
|
||||||
|
|
||||||
使用`spi_busnum_to_master()`查找目标SPI控制器;
|
##### Master
|
||||||
使用`spi_new_device()`创建;
|
|
||||||
使用`spi_unregister_device()`销毁;
|
|
||||||
|
|
||||||
### SPI Controller Driver
|
```dts
|
||||||
|
#---- build/boards/default/dts/cv181x/cv181x_base.dtsi
|
||||||
|
/ {
|
||||||
|
spi3:spi3@041B0000 {
|
||||||
|
interrupts = <57 IRQ_TYPE_LEVEL_HIGH>;
|
||||||
|
interrupt-parent = <&plic0>;
|
||||||
|
};
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
##### Slave
|
||||||
|
|
||||||
|
- 独占总线
|
||||||
|
|
||||||
|
```dts
|
||||||
|
#---- build/boards/default/dts/cv181x/cv181x_asic_bga.dtsi
|
||||||
|
&spi3 {
|
||||||
|
status = "okay";
|
||||||
|
num-cs = <1>;
|
||||||
|
spidev@0 {
|
||||||
|
compatible = "rohm,dh2228fv";
|
||||||
|
spi-max-frequency = <1000000>;
|
||||||
|
reg = <0>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
#---- build/boards/cv181x/cv1813h_milkv_duos_sd/dts_riscv/cv1813h_milkv_duos_sd.dts
|
||||||
|
&spi3 {
|
||||||
|
status = "okay";
|
||||||
|
|
||||||
|
spidev@0 {
|
||||||
|
status = "okay";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
- 多设备
|
||||||
|
|
||||||
|
参考内核文档:
|
||||||
|
|
||||||
|
1. linux_5.10/Documentation/devicetree/bindings/spi/spi-bus.txt;
|
||||||
|
2. linux_5.10/arch/arm/boot/dts/imx6ul-imx6ull-opos6uldev.dtsi
|
||||||
|
|
||||||
|
```dts
|
||||||
|
#---- linux_5.10/arch/arm/boot/dts/imx6ull-opos6uldev.dts
|
||||||
|
/dts-v1/;
|
||||||
|
#include "imx6ull-opos6ul.dtsi" # 1
|
||||||
|
# include "imx6ul.dtsi" # 1.1
|
||||||
|
#include "imx6ul-imx6ull-opos6uldev.dtsi" # 2
|
||||||
|
|
||||||
|
/ {
|
||||||
|
model = "Armadeus Systems OPOS6UL SoM (i.MX6ULL) on OPOS6ULDev board";
|
||||||
|
compatible = "armadeus,imx6ull-opos6uldev", "armadeus,imx6ull-opos6ul", "fsl,imx6ull";
|
||||||
|
};
|
||||||
|
|
||||||
|
#1.1- linux_5.10/arch/arm/boot/dts/imx6ul.dtsi
|
||||||
|
/ {
|
||||||
|
...
|
||||||
|
soc {
|
||||||
|
...
|
||||||
|
aips1: bus@2000000 {
|
||||||
|
...
|
||||||
|
spba-bus@2000000 {
|
||||||
|
...
|
||||||
|
ecspi4: spi@2014000 {
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <0>;
|
||||||
|
compatible = "fsl,imx6ul-ecspi", "fsl,imx51-ecspi";
|
||||||
|
reg = <0x02014000 0x4000>;
|
||||||
|
interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
|
||||||
|
clocks = <&clks IMX6UL_CLK_ECSPI4>,
|
||||||
|
<&clks IMX6UL_CLK_ECSPI4>;
|
||||||
|
clock-names = "ipg", "per";
|
||||||
|
dmas = <&sdma 9 7 1>, <&sdma 10 7 2>;
|
||||||
|
dma-names = "rx", "tx";
|
||||||
|
status = "disabled";
|
||||||
|
};
|
||||||
|
|
||||||
|
#2--- linux_5.10/arch/arm/boot/dts/imx6ul-imx6ull-opos6uldev.dtsi
|
||||||
|
&ecspi4 {
|
||||||
|
pinctrl-names = "default";
|
||||||
|
pinctrl-0 = <&pinctrl_ecspi4>;
|
||||||
|
num-cs = 2;
|
||||||
|
cs-gpios = <&gpio4 9 GPIO_ACTIVE_LOW>, <&gpio4 3 GPIO_ACTIVE_LOW>;
|
||||||
|
status = "okay";
|
||||||
|
|
||||||
|
spidev0: spi@0 {
|
||||||
|
compatible = "spidev";
|
||||||
|
reg = <0>;
|
||||||
|
spi-max-frequency = <5000000>;
|
||||||
|
};
|
||||||
|
|
||||||
|
spidev1: spi@1 {
|
||||||
|
compatible = "spidev";
|
||||||
|
reg = <1>;
|
||||||
|
spi-max-frequency = <5000000>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 总结
|
||||||
|
|
||||||
|
1. `spi-max-frequency`,多通道时,需要定义设备允许的最大速率;---- 待确认;
|
||||||
|
|
||||||
|
### 驱动
|
||||||
|
|
||||||
|
- `spi_busnum_to_master()`, 查找目标SPI控制器;
|
||||||
|
- `spi_new_device()`, 创建;
|
||||||
|
- `spi_unregister_device()`销毁;
|
||||||
|
|
||||||
|
#### SPI Controller Driver
|
||||||
|
|
||||||
```c
|
```c
|
||||||
struct spi_master *master;
|
struct spi_master *master;
|
||||||
@ -152,14 +269,14 @@ SPI设备必须管理以下两种类型内存:
|
|||||||
|
|
||||||
- `spi_[un]register_master()`注册至系统;
|
- `spi_[un]register_master()`注册至系统;
|
||||||
|
|
||||||
#### 接口
|
master操作集
|
||||||
|
|
||||||
- `master->setup(struct spi_device *spi)`, clock rate, SPI mode, and word sizes.
|
- `master->setup(struct spi_device *spi)`, clock rate, SPI mode, and word sizes.
|
||||||
- `master->cleanup(struct spi_device *spi)`, 清除之前由`spi_device.controller_state`锁定的状态;
|
- `master->cleanup(struct spi_device *spi)`, 清除之前由`spi_device.controller_state`锁定的状态;
|
||||||
...
|
...
|
||||||
- `master->transfer_one_message(struct spi_master *master, struct spi_message *mesg)`, 发送一个mesg;
|
- `master->transfer_one_message(struct spi_master *master, struct spi_message *mesg)`, 发送一个mesg;
|
||||||
|
|
||||||
### SPI Protocol Driver
|
#### SPI Protocol Driver
|
||||||
|
|
||||||
```c
|
```c
|
||||||
static int CHIP_probe(struct spi_device *spi)
|
static int CHIP_probe(struct spi_device *spi)
|
||||||
@ -193,7 +310,9 @@ SPI设备必须管理以下两种类型内存:
|
|||||||
.remove = CHIP_remove,
|
.remove = CHIP_remove,
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
spi_setup(),
|
spi_setup(),
|
||||||
|
|
||||||
## 属性
|
## 属性
|
||||||
|
|
||||||
- `spi_message.is_dma_mapped`,
|
- `spi_message.is_dma_mapped`,
|
||||||
|
|||||||
@ -53,7 +53,7 @@ static const struct of_device_id CHIP_of_match[] = {
|
|||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
|
|
||||||
MODULE_DEVICE_TABLE(of, CHIP_of_match);
|
MODULE_DEVICE_TABLE(of, CHIP_of_match); // Used by file2alias, which indicated what devices are support with this drive.
|
||||||
#endif // CONFIG_OF
|
#endif // CONFIG_OF
|
||||||
|
|
||||||
static struct spi_driver CHIP_driver = {
|
static struct spi_driver CHIP_driver = {
|
||||||
|
|||||||
Reference in New Issue
Block a user