7.10.6.2. 如何添加新的 SPI NOR 设备
7.10.6.2.1. 驱动层次关系
SPI NOR 属于 SPI 的从设备,在内核中相关驱动通过 SPI MEM
对接到 SPI
子系统,如 图 7.50 所示。
在 SPI 控制器初始化时,SPI 驱动会检查该控制器下是否有挂载的 SPI NOR,有则添加到 SPI BUS 中。
aic_spi_probe(dev);
|-> spi_register_controller(ctlr);/spi_register_master(ctlr);
| // spi_register_master 是一个宏
|
|-> of_register_spi_devices(ctlr);
|-> spi = of_register_spi_device(ctlr, nc);
|-> spi = spi_alloc_device(ctlr);
|-> of_spi_parse_dt(ctlr, spi, nc);
|-> rc = spi_add_device(spi);
// 将 SPI device 添加到 SPI 总线 spi_bus_type 中
在调用 spi_add_device
的过程中,会查找和匹配对应设备的驱动程序(如果这时候对
应的驱动程序还没有被添加到系统中,则在这里先将设备添加到 Bus,等到对应驱动程序
被添加进来时,再进行匹配。)
模块 |
驱动源码路径 |
---|---|
SPI NOR |
linux-5.10/drivers/mtd/spi-nor/ |
7.10.6.2.2. 检查和添加新设备
内核中所支持的 SPI NOR 设备通过两级列表进行设置。
首先检查 linux-5.10/drivers/mtd/spi-nor/core.c
中的 manufacturers
,
查看新设备的厂商是否在列表之中:
static const struct spi_nor_manufacturer *manufacturers[] = {
&spi_nor_atmel,
&spi_nor_catalyst,
&spi_nor_eon,
&spi_nor_esmt,
&spi_nor_everspin,
&spi_nor_fujitsu,
&spi_nor_gigadevice,
&spi_nor_intel,
&spi_nor_issi,
&spi_nor_macronix,
&spi_nor_micron,
&spi_nor_st,
&spi_nor_spansion,
&spi_nor_sst,
&spi_nor_winbond,
&spi_nor_xilinx,
&spi_nor_xmc,
&spi_nor_boya,
};
再检查具体的设备厂商文件,具体的型号是否在列表之中( 以gigadevice 为例):
static const struct flash_info gigadevice_parts[] = {
......
{ "gd25q256", INFO(0xc84019, 0, 64 * 1024, 512,
SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
SPI_NOR_4B_OPCODES | SPI_NOR_HAS_LOCK |
SPI_NOR_HAS_TB | SPI_NOR_TB_SR_BIT6)
.fixups = &gd25q256_fixups },
......
};
此处检查,需要查找新设备的 Datasheet,找到该设备的 Manufacture 和 Device ID,并查看该 ID 是否出现在列表中。
例如此处为 0xc84019
,其中 Manufacture ID = 0xc8
, Device ID ID[15~8] = 0x40
, ID[7~0] = 0x19
。
如果不存在,则参考上述例子,添加一个新的设备记录。
7.10.6.2.3. 修改 DTS
要在实际项目中使用 SPI NOR 设备,还需要修改 DTS 配置。
xxx-board.dts
应在具体的 SPI 控制器下添加 jedec,spi-nor
设备。
&spi0 {
pinctrl-names = "default";
pinctrl-0 = <&spi0_pins_a>;
status = "okay";
spi-max-frequency = <100000000>;
spi-flash@0 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "jedec,spi-nor";
spi-max-frequency = <100000000>;
spi-tx-bus-width = <4>;
spi-rx-bus-width = <4>;
reg = <0>;
status = "okay";
};
};
同时还需在 board-u-boot.dtsi
文件中,将该设备标记为 u-boot,dm-pre-reloc
,不然 SPL 无法识别和使用。
&spi0 {
u-boot,dm-pre-reloc;
spi-flash@0 {
u-boot,dm-pre-reloc;
};
};