Linux 的 I2C、SPI、Regmap 子系统
2026/7/11 1:52:32 网站建设 项目流程

I2C 子系统

断言

1. I2C 需要 “平台总线” 作为"引子"是因为它没有硬件枚举能力,必须通过静态配置知道总线上有什么设备。USB/PCI 有硬件枚举,所以不需要这个中间层(除了控制器本身)。

整个链路的枚举和诞生过程是这样的:

Step 1: 平台总线阶段(Platform Bus)

SoC 芯片上的 I2C 控制器 IP(比如 Rockchip 的 I2C 模块),其寄存器地址、中断号等信息写在设备树(DTS)中。

  1. 内核启动时,解析 DTS,将其转换成一个platform_device

  2. 芯片厂商编写的控制芯片驱动是一个platform_driver

  3. 两者在Platform Bus上匹配成功,触发probe()函数。

Step 2: I2C 总线阶段(I2C Bus)

platform_driverprobe()函数内部:

  1. 驱动分配并初始化了一个struct i2c_adapter

  2. 驱动调用i2c_add_adapter()

  3. 关键点来了:I2C Core 在注册这个 adapter 时,会将adapter->dev.bus挂载到内核自带的i2c_bus_type(I2C 总线)上,而不是平台总线上。

总结:

  • platform_device守护的是控制器的内存映射寄存器和中断等硬件资源

  • i2c_adapter是在这个基础设施上抽象出来的、向外提供 I2C 传输能力的软件实体

  • 它本身不通过平台总线枚举,它是平台总线驱动probe成功后的产物,随后被注册到 I2C 核心层中。

💡 终极看清关系

如果你去翻看内核源码或/sys/devices/目录,你会发现它们呈现出完美的父子层级关系:

/sys/devices/platform/fe5a0000.i2c/ <-- 这是一个 platform_device (来自设备树) └── i2c-0/ <-- 这就是被注册的 i2c_adapter (它的 parent 是上面的 platform_device) ├── i2c-dev/i2c-0/ <-- 暴露给用户空间的 /dev/i2c-0 节点 └── 0-0050/ <-- 挂载在这个 I2C 总线上、地址为 0x50 的 i2c_client (外设,如 EEPROM)
  • platform_device是老子(负责提供物理温床、寄存器和电源)。

  • i2c_adapter是儿子(承上启下,拿着老子给的资源,开辟了一条 I2C 通道)。

  • i2c_client是孙子(挂在儿子开辟的通道上的具体外设芯片)。

SPI 子系统

[todo]

Regmap 子系统

[todo]

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询