[Mod] 更新文档
This commit is contained in:
141
spi/ReadMe.md
141
spi/ReadMe.md
@ -2,6 +2,7 @@
|
||||
|
||||
|
||||
## 参考
|
||||
|
||||
- linux_5.10/Documentation/spi/spi-summary.rst
|
||||
|
||||
|
||||
@ -15,10 +16,12 @@
|
||||
### 两种SPI驱动
|
||||
|
||||
#### Controller drivers ...
|
||||
|
||||
此类驱动的对象为SOC片上的SPI控制器,这些控制器通常支持“Master”与“Slave”角色切换。
|
||||
此类驱动常直接访问硬件寄存器并使用DMA来提高数据传递效率,或许也可以通过CPU控制数据的每一位来控制可编程GPIO管脚。
|
||||
|
||||
#### Protocol drivers ...
|
||||
|
||||
此类驱动的对象为SOC片外接的SPI设备,这些设备以“Master”或“Slave”角色接入SPI控制器,进而完成数据的传输。
|
||||
在SPI驱动之上,可能被具象化为MTD、Audio等设备接入更上一级的子系统。
|
||||
|
||||
@ -56,13 +59,16 @@ SPI设备必须管理以下两种类型内存:
|
||||
|
||||
## 示例
|
||||
|
||||
### 静态定义
|
||||
### 设备
|
||||
|
||||
#### 板级设备
|
||||
#### 板级静态定义
|
||||
|
||||
##### Master
|
||||
"struct platform_device"
|
||||
|
||||
- `struct platform_device`, 基于平台设备开发;
|
||||
|
||||
路径:`arch/.../mach-*/board-*.c`:
|
||||
|
||||
```c
|
||||
#include <mach/spi.h> /* for mysoc_spi_data */
|
||||
|
||||
@ -105,8 +111,11 @@ SPI设备必须管理以下两种类型内存:
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
##### Slave
|
||||
|
||||
文件:`arch/.../mach-*/board-*.c`:
|
||||
|
||||
```c
|
||||
static struct ads7846_platform_data ads_info = {
|
||||
.vref_delay_usecs = 100,
|
||||
@ -131,13 +140,121 @@ SPI设备必须管理以下两种类型内存:
|
||||
spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
|
||||
```
|
||||
|
||||
### 非静态定义
|
||||
#### DTS动态定义
|
||||
|
||||
使用`spi_busnum_to_master()`查找目标SPI控制器;
|
||||
使用`spi_new_device()`创建;
|
||||
使用`spi_unregister_device()`销毁;
|
||||
##### Master
|
||||
|
||||
### 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
|
||||
struct spi_master *master;
|
||||
@ -152,14 +269,14 @@ SPI设备必须管理以下两种类型内存:
|
||||
|
||||
- `spi_[un]register_master()`注册至系统;
|
||||
|
||||
#### 接口
|
||||
master操作集
|
||||
|
||||
- `master->setup(struct spi_device *spi)`, clock rate, SPI mode, and word sizes.
|
||||
- `master->cleanup(struct spi_device *spi)`, 清除之前由`spi_device.controller_state`锁定的状态;
|
||||
...
|
||||
...
|
||||
- `master->transfer_one_message(struct spi_master *master, struct spi_message *mesg)`, 发送一个mesg;
|
||||
|
||||
### SPI Protocol Driver
|
||||
#### SPI Protocol Driver
|
||||
|
||||
```c
|
||||
static int CHIP_probe(struct spi_device *spi)
|
||||
@ -193,7 +310,9 @@ SPI设备必须管理以下两种类型内存:
|
||||
.remove = CHIP_remove,
|
||||
};
|
||||
```
|
||||
|
||||
spi_setup(),
|
||||
|
||||
## 属性
|
||||
|
||||
- `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
|
||||
|
||||
static struct spi_driver CHIP_driver = {
|
||||
|
||||
Reference in New Issue
Block a user