当前位置: 首页 > news >正文

Day 8(下篇):总线驱动模型实战全解析 —— 以 PCA9450 PMIC 为例

✅ Day 8(下篇):总线驱动模型实战全解析 —— 以 PCA9450 PMIC 为例

在上一篇博文中,我们深入梳理了 Linux 驱动框架中两大核心模型 —— 平台驱动模型与总线驱动模型 —— 的结构差异与匹配逻辑。在本篇下篇中,我们将从一个完整的 I2C 总线驱动模型实战出发,以 NXP i.MX8M Plus EVK 板载的 PCA9450 PMIC 电源芯片为例,详细讲解设备树设计、驱动匹配过程、驱动模型与资源获取机制,帮助你真正掌握“总线驱动模型”的应用与核心技术点。


🔁 一、上篇回顾:平台 vs 总线驱动模型

在上篇中,我们明确区分了两个核心驱动模型:

分类模型名称典型接口设备绑定方式匹配依据
平台驱动模型platform_driver + platform_deviceplatform_get_resource()设备树 + platform_bus.compatible + platform_match
总线驱动模型i2c_driverspi_driverpci_driveri2c_add_driver()i2c_probe()总线设备自动挂载总线类型 + .id_table or .of_match_table

它们都属于统一的 Linux 设备模型体系,但在驱动注册、设备创建、资源获取方式等方面有着本质差异。

在这篇文章中,我们将把理论落地,从实际硬件和驱动代码出发,对总线驱动模型做一次全面的实战讲解。


🧩 二、硬件结构解析:PCA9450 在 i.MX8MP 上的供电角色

✅ 2.1 电源架构图理解

我们首先看下官方 EVK 的 PWR TREE 图:

这张图显示了 PCA9450 PMIC 所控制的多个电压通道(BUCKx、LDOx),它们为 i.MX8MP 的核心电源、IO 电源、LPDDR4 等子系统提供稳压输出。

从图中可见:

  • PCA9450 是通过 I2C 接口与 SoC 相连。
  • PMIC 的多个输出通道,如 BUCK1/2/4/5/6LDO1/2/3/4/5,分别负责供电给 CPU、LPDDR4、eMMC、USB、WiFi 等模块。
  • VDD_ARMVDD_DRAMNVCC_DRAM 等电源信号直接由 PCA9450 管脚控制。

📁 三、设备树结构讲解(以 i2c1@30a20000 节点为起点)

我们先来看设备树中关于 I2C1 控制器与 PCA9450 的定义:

&i2c1 {
    clock-frequency = <400000>;
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_i2c1>;
    status = "okay";

    pmic@25 {
        compatible = "nxp,pca9450c";
        reg = <0x25>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_pmic>;
        interrupt-parent = <&gpio1>;
        interrupts = <3 IRQ_TYPE_LEVEL_LOW>;

        regulators {
            buck1: BUCK1 {
                regulator-name = "BUCK1";
                regulator-min-microvolt = <600000>;
                regulator-max-microvolt = <2187500>;
                regulator-boot-on;
                regulator-always-on;
            };
            ...
        };
    };
};

✅ 核心字段解释:

字段含义
&i2c1表示引用 i2c1 控制器
pmic@25PMIC 芯片的 I2C 地址为 0x25
compatible匹配驱动的关键字段,驱动需声明支持 "nxp,pca9450c"
regulators子节点,定义具体电源通道的电压配置和属性

设备树中通过 .compatible + reg 进行 设备绑定,再通过 regulators 子节点完成电源控制逻辑的描述。


🧩 四、驱动注册与匹配分析

在 PCA9450 的驱动源码中,我们可以看到典型的 I2C 总线驱动写法:

static const struct of_device_id pca9450_of_match[] = {
    { .compatible = "nxp,pca9450c", .data = (void *)PCA9450_TYPE_PCA9450C },
    ...
};
MODULE_DEVICE_TABLE(of, pca9450_of_match);

static struct i2c_driver pca9450_i2c_driver = {
    .driver = {
        .name = "nxp-pca9450",
        .of_match_table = pca9450_of_match,
    },
    .probe = pca9450_i2c_probe,
};
module_i2c_driver(pca9450_i2c_driver);

✅ 匹配流程详解:

  1. i2c 总线子系统扫描设备树,识别挂载在 i2c1 控制器下的从设备节点。
  2. 找到 compatible = "nxp,pca9450c"
  3. 内核会遍历 i2c_driver 中的 .of_match_table,发现匹配项,调用 .probe()

此过程无需手动注册 platform_device,而是 通过 i2c 子系统自动完成,这就是总线驱动模型的优势:结构清晰,自动匹配


🔧 五、资源获取方式差异说明

功能平台驱动模型总线驱动模型
获取资源(reg)platform_get_resource()regmap_init_i2c()i2c_smbus_read_*()
时钟devm_clk_get()通常不涉及
中断platform_get_irq()通过 client->irq 获得
设备数据platform_get_drvdata()i2c_set_clientdata()

以 PCA9450 为例,驱动通过 regmap_init_i2c() 来访问内部寄存器:

pca9450->regmap = devm_regmap_init_i2c(i2c, &pca9450_regmap_config);

这本质上就是用 i2c_transfersmbus API,完成对 PMIC 内部寄存器的读写操作。


🧩 六、regulator 框架接入流程

PCA9450 的每一个电源输出(BUCK/LDO)都以子设备形式注册为一个 regulator 控制器,整个驱动通过如下步骤完成电源输出控制的注册:

  1. 解析设备树 regulators 节点;
  2. 注册每个 regulator 设备;
  3. 提供 regulator_ops 函数集支持 enable/disable、set_voltage 等操作;
  4. 提供 ramp_delay、电压范围等配置。

示例代码:

rdev = devm_regulator_register(pca9450->dev, desc, &config);

注册成功后,其他子系统(如 CPU 调频、系统电源管理等)就可以调用 regulator API 控制该 PMIC 电压。


📌 七、I2C 总线驱动模型核心总结

核心要素总结说明
驱动结构i2c_driver 注册、.probe() 初始化、.remove() 清理
匹配机制依赖 i2c-core 扫描设备树并调用 .of_match_table
资源访问通过 regmap_init_i2c() 映射寄存器,使用 i2c_transfer 进行访问
驱动模型本质上是总线驱动模型的一种典型实现,属于设备模型框架下的子类
与平台模型区别不需创建 platform_device,资源访问机制不同,结构更自动

✅ 结语:理解“设备模型”的统一性

总线驱动模型和平台驱动模型虽然接口风格不同,但都基于 Linux 内核统一的 设备模型(device model) 框架:

  • 驱动与设备通过 bus_type 关联;
  • 匹配靠 of_match_tableid_table
  • 所有子系统设备(如 i2c_clientspi_deviceplatform_device)都挂接到统一的 /sys/bus/ 下。

通过本篇内容,我们以 PCA9450 的完整结构为例,深刻理解了 “从设备树 → 总线匹配 → 驱动注册 → 子设备资源注册” 的全过程。


📚 推荐阅读

  • Documentation/devicetree/bindings/regulator/
  • drivers/regulator/core.c
  • drivers/i2c/i2c-core-base.c
  • NXP i.MX Linux BSP 源码中的 drivers/regulator/pca9450.c

如果你已经理解本篇内容,那么恭喜你已真正掌握 Linux 总线驱动模型的底层结构和实战应用。下一篇,我们将深入 Linux 电源管理机制中的 suspend/resume 实现逻辑,进一步探讨 regulator 与 runtime PM 的协同作用。

相关文章:

  • 【机器学习】每日一讲-朴素贝叶斯公式
  • 超强大小白工具,应用广泛,PDF 删除,无需下载,在线使用,操作超简单,超实用
  • WMware虚拟机Ubuntu磁盘扩容
  • 突破性能瓶颈:Java微服务多任务管理的架构设计与实践
  • 可编辑33页PPT | 经营管理数字化转型平台解决方案
  • MySQL 优化方案大全
  • Acrel-1000DP分布式光伏监控系统在嘉兴亨泰新能源有限公司2996.37KWP分布式光伏项目中的应用
  • STL-函数对象
  • 程序员技能跃迁:职坐标精准赋能
  • 2.2goweb解析http请求信息
  • Colmap的安装和使用
  • Dockerfile部署springboot 项目或者springcloud项目
  • AcWing 6100. 奶牛选美
  • (十三)人工智能应用--深度学习原理与实战--理解卷积神经网络的原理及优势
  • Linux-----驱动
  • 视频活体检测:为您的身份信息安全保驾护航
  • Mysql--基础知识点--85.1--Innodb自适应哈希索引
  • 慢查询解决思路
  • 【Unity3D中UI与物体可见性的判断方法】
  • CSS基础知识学习指南
  • 有做外国人的零售网站吗/淘宝新店怎么快速做起来
  • 附近做网站的公司电话/seo手机关键词排行推广
  • 跨境电商公司/惠州短视频seo
  • 无锡网站优化推广/seo搜索引擎优化是什么
  • 做网站推广电话/谷歌推广效果怎么样
  • 内部网站开发/推广神器