status = spi_register_driver(&spidev_spi_driver);
在
static int __init spidev_init(void)
功能。
再说一次,我还不太确定自己在写什么,我来这里寻求指导。
首先,您可能需要阅读 Linux 设备驱动程序 - 第 14 章。
一般来说,在 Linux 内核中,
devices
和 drivers
位于 bus
(subsystem
) 上。您必须使用函数 register_device()
和 register_driver()
来注册它们(确切的名称取决于子系统)。当设备或驱动程序注册时,subsystem
将尝试将 devices
与 drivers
匹配。如果它们匹配,则 subsystem
调用驱动程序的函数 probe()
。因此,probe()
函数的执行可以由驱动程序注册或设备注册触发。这也意味着该设备在执行probe()
之前就存在
回到您的具体案例:SPI。要注册设备实例,您需要使用spi_alloc_device和spi_add_device或spi_new_device。这段代码该放在哪里?这取决于您的需要。通常,SPI 设备在某些架构文件或设备树描述中声明。也许你也可以在模块中完成它(不确定)。
spidev
是一个Linux设备驱动程序,它将SPI原始接口导出到用户空间。这意味着一旦您注册了 SPI 设备实例,驱动程序 spidev
就会控制它。实际上,spidev
什么也不做:它等待用户空间程序在 SPI 总线上读/写数据。因此,您最终将在用户空间中为您的设备编写驱动程序。
首先我们讨论的是SPI控制器驱动程序还是SPI设备驱动程序? 我认为是后者。
简而言之,
spidev
只是一个用户空间接口,一个不知道任何底层协议的字符设备驱动程序。
spidev
不能也无法识别正在与之通信的设备,它不知道它是FLASH、CODEC、EEPROM,并且不了解协议,它不了解它处理的数据部分是地址、操作码还是数据。
您需要针对特定 SPI 设备的特定内核驱动程序。
内核将尝试通过设备树 SPI 节点的设备树兼容属性将您的驱动程序与设备进行匹配:
.compatible = "tcg,tpm_tis-spi"n
如果匹配,它将调用驱动程序内的
probe()
函数,该函数
将使用设备树 SPI 节点中提供的数据初始化驱动程序和设备。
并尝试与设备本身进行通信,读取ID寄存器以进一步识别设备,因为该驱动程序知道该设备使用的协议。