From 6782b3fb80ee2842247f2a616fffad9ef791ae23 Mon Sep 17 00:00:00 2001 From: "rick.chan" Date: Wed, 19 Aug 2020 17:03:22 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=20Linux=20Spidev=20=E4=B8=8E?= =?UTF-8?q?=20DeviceTree.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: rick.chan --- .../Modules/SPI/Linux_Spidev_与_DeviceTree.md | 105 ++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 Software/Development/OperatingSystem/Linux/Kernel/Modules/SPI/Linux_Spidev_与_DeviceTree.md diff --git a/Software/Development/OperatingSystem/Linux/Kernel/Modules/SPI/Linux_Spidev_与_DeviceTree.md b/Software/Development/OperatingSystem/Linux/Kernel/Modules/SPI/Linux_Spidev_与_DeviceTree.md new file mode 100644 index 0000000..65f0831 --- /dev/null +++ b/Software/Development/OperatingSystem/Linux/Kernel/Modules/SPI/Linux_Spidev_与_DeviceTree.md @@ -0,0 +1,105 @@ +# Linux Spidev 与 DeviceTree + +在 Linux SPI 子系统——x86 平台中介绍了 x86 平台上 SPI 子系统的概况。其原理也适用于 ARM 平台,只不过在 ARM 平台上,需要编写 DeviceTree 以替代 platform device 或 ACPI。 + +最常见也最普通的 SPI 设备就是 spidev,这是 Linux 允许用户态操作 spi 的接口,其导出的接口以 spidev<总线号>.<子设备号/片选序号> 的文件形式出现在 /dev 系统目录下。 + +以下以 spidev 为例,说明其 DeviceTree 的写法,以及其与驱动和用户态节点的关系。 + +## 1.DeviceTree + +一般 SOC 下都会包含 SPI 控制器的信息: + +```dts +soc: soc { + ... + spi0: spi@e6e90000 { + compatible = "xxx-compatible"; + status = "disabled"; + ... + }; + ... +} +``` + +在板级 DTS 文件中需要对 pin control 和 spi 部分进行改写和扩充: + +```dts +&pin-controller { + ... + spi0_pins: spi0 { + // 这里是 SPI 要用到的 Pin + groups = "spi0_clk","spi0_ss1","spi0_txd","spi0_rxd"; + function = "spi0"; + } + ... +} + +&spi0 { + pinctrl-0 = <&spi0_pins>; + pinctrl-names = "default"; + status = "okay"; + + // 下面包含两个 spidev + spirpc@0 { + compatible = "my_spi_device_0"; + reg = <0>; + spi-max-frequency = <1000000>; + }; + + spirpc@1 { + compatible = "my_spi_device_1"; + reg = <1>; + spi-max-frequency = <1000000>; + }; +}; +``` + +## 2.spidev_dt_ids + +然后修改 spidev.c 中的 spidev_dt_ids[] 数组,增加以下内容: + +```cpp +/** + * @file /drivers/spi/spidev.c + */ +static const struct of_device_id spidev_dt_ids[] = { + ... + { .compatible = "my_spi_device_0" }, + { .compatible = "my_spi_device_1" }, + ... + } +``` + +最后在 Kernel 中设置 CONFIG_SPI=y,CONFIG_SPI_SPIDEV=y。这样就可以使用 spidev 了,上面相当于 spi0 下声明了两个设备:spidev0.0 和 spidev0.1。 + +## 3.特殊说明 + +### 3.1.关于 compatible + +在一些例子中,spidev 直接出现在 compatible 字段,这是一种错误的写法,有可能在编译中出现错误或警告: + +```dts +spirpc@0 { + compatible = "spidev"; + reg = <0>; + spi-max-frequency = <1000000>; +}; +``` + +为什么 spidev 不能直接出现在 DeviceTree 的 compatible 字段里,而是需要自定义一个 compatible,并且修改 spidev_dt_ids 呢?这是因为 DeviceTree 应当用于描述硬件信息,而 spidev 并没有描述任何硬件信息。 + +Mark Brown wrote: + +```blk +Since spidev is a detail of how Linux controls a device rather than a description of the hardware in the system we should never have a node described as "spidev" in DT, any SPI device could be a spidev so this is just not a useful description. +``` + +### 3.2.spi gpio + +spidev 除了出现在 spi 节点下意外,还有可能出现在 spi gpio 节点下,spi gpio 是 Linux 下使用 gpio 模拟 spi 控制器的一种方法。若想使用 spi gpio,需要设置 CONFIG_SPI_GPIO=y。 + +## 4.内部参考关键字 + +* SPI +* x86