驱动开发硬核特训 │ Regulator 子系统全解

[复制链接]
发表于 2025-4-29 22:01:48 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
一、Regulator子系统概述

在 Linux 内核中,Regulator 子系统是专门用于管理电源开关、电压调整、电流控制的一套完整框架。
它重要办理以下问题:


  • 设备需要的电压通常不一样,怎样动态调整?
  • 有些设备休眠时需要关闭供电,怎样优雅关闭?
  • 开机、关机过程中怎样同一管理电源状态?
以是:
   Regulator 子系统就是在操作系统级别,同一管理设备电源的控制系统。
  
二、架构总览

Regulator 子系统可以划分为三层:
层次功能阐明用户接口层提供 API 给驱动利用regulator_get,regulator_enable 等Core 管理层通用管理逻辑电压、电流调整,状态记载硬件驱动层具体硬件操作PMIC、LDO、BUCK 等硬件控制
三、根本概念

什么是 LDO?



  • 全称:Low Dropout Regulator(低压差线性稳压器)
  • 特点:输入电压与输出电压很接近,服从中等。
  • 应用:为噪声敏感器件供电,比如模拟电路、音频设备。
什么是 BUCK?



  • 全称:Buck Converter(降压开关稳压器)
  • 特点:输入电压高,输出电压低;服从高(通常 > 90%)。
  • 应用:为CPU、GPU、大电流设备供电。
总结:
类型特点应用场景LDO简单、低噪声、低压差模拟电路、摄像头BUCK高服从、大电流CPU、GPU、DDR
四、设备树中怎样描述 Regulator


设备树根本结构示例

  1. reg_pcie0: regulator-pcie {
  2.     compatible = "regulator-fixed";
  3.     regulator-name = "MPCIE_3V3";
  4.     regulator-min-microvolt = <3300000>;
  5.     regulator-max-microvolt = <3300000>;
  6.     gpio = <&gpio2 6 GPIO_ACTIVE_HIGH>;
  7.     enable-active-high;
  8.     regulator-always-on;
  9. };
复制代码
字段阐明:
属性寄义compatible类型(如固定电压 regulator)regulator-name名称regulator-min-microvolt / max-microvolt输出电压范围gpio控制供电开关的 GPIOenable-active-high高电平有效regulator-always-on系统上电后始终开启
五、设备怎样利用 Regulator

以 PCIe 控制器为例:
  1. &pcie {
  2.     vpcie-supply = <&reg_pcie0>;
  3.     status = "okay";
  4. };
复制代码


  • vpcie-supply 指向一个 Regulator 节点
  • 驱动中调用 regulator_get() 自动获得供电控制
  • 调用 regulator_enable() 实际使能电源

六、Regulator 焦点 API 讲解

函数作用regulator_get(dev, id)获取 regulator 句柄regulator_enable(regulator)使能供电regulator_disable(regulator)禁用供电regulator_set_voltage(regulator, min_uV, max_uV)设置电压regulator_put(regulator)释放 regulator 示例代码:

  1. struct regulator *vpcie;
  2. vpcie = regulator_get(dev, "vpcie");
  3. if (IS_ERR(vpcie))
  4.     return PTR_ERR(vpcie);
  5. regulator_enable(vpcie);
  6. /* 使用完毕后关闭 */
  7. regulator_disable(vpcie);
  8. regulator_put(vpcie);
复制代码

七、焦点结构体分析

struct regulator_desc

描述一个 regulator:
  1. struct regulator_desc {
  2.     const char *name;
  3.     const char *supply_name;
  4.     int id;
  5.     struct regulator_ops *ops;
  6.     const struct regulator_init_data *init_data;
  7. };
复制代码
阐明:


  • name:名字
  • supply_name:上游供电来源(可选)
  • ops:具体实现函数,比如 enable,disable
  • init_data:初始化时的默认配置

八、pca9450 PMIC中的 Regulator 实际例子

  1. static const struct regulator_desc pca9450_descs[] = {
  2.     {
  3.         .name = "pca9450-buck1",
  4.         .id = PCA9450_BUCK1,
  5.         .of_match = of_match_ptr("buck1"),
  6.         .regulators_node = of_match_ptr("regulators"),
  7.         ...
  8.     },
  9.     ...
  10. };
复制代码
设备树描述:
  1. pmic@25 {
  2.     regulators {
  3.         buck1: BUCK1 {
  4.             regulator-name = "BUCK1";
  5.             regulator-min-microvolt = <600000>;
  6.             regulator-max-microvolt = <2187500>;
  7.         };
  8.     };
  9. };
复制代码
对应关系:


  • pca9450-buck1 → BUCK1
  • Linux自动绑定,根据 of_match_ptr 来识别。

九、LDO 和 BUCK 在驱动中的差别

特性LDOBUCK工作原理线性压降开关电源降压服从中等高效(>90%)噪声低相对高电流能力小大控制接口通过简单寄存器开关更复杂,需要设置模式 通常:


  • 音频、传感器利用 LDO
  • CPU、GPU 利用 BUCK

十、在实际驱动 probe 中应用

例如 PCIe 控制器 probe:
  1. static int pcie_probe(struct platform_device *pdev)
  2. {
  3.     struct regulator *vpcie;
  4.     vpcie = devm_regulator_get(&pdev->dev, "vpcie");
  5.     if (IS_ERR(vpcie))
  6.         return PTR_ERR(vpcie);
  7.     regulator_enable(vpcie);
  8.     /* 继续初始化其他部分 */
  9.     return 0;
  10. }
复制代码
特点:


  • devm_regulator_get:自动跟随设备生命周期,无需手动释放
  • regulator_enable:启用电源

十一、总结:Regulator 子系统的重要性

层次作用硬件提供真实电源(LDO/BUCK/PMIC)Regulator 驱动层将硬件能力抽象成标准接口Regulator Core通用电源管理,提供同等性设备驱动简单调用,无需关心细节 正因为有了 Regulator 框架,Linux 设备驱动可以做到:


  • 开机动态供电
  • 按需调整电压
  • 休眠省电自动关电
  • 简化代码,提高移植性

十二、常见问题答疑

1. Regulator 和 Power Domain 是什么关系?


  • Power Domain:逻辑域,策略控制(比如整个 GPU 电源域)
  • Regulator:物理供电开关(实际高低电压操作)
两者配合利用:


  • power-domain 负责组织谁需要上电;
  • regulator 负责真正把电压拉起来。

十三、附:Regulator 调试技巧


  • 内核启动打印 regulator 状态:
  1. dmesg | grep regulator
复制代码

  • 动态调节某个 regulator 电压(需要接口支持):
  1. regulator_set_voltage(vreg, 1800000, 1800000);
复制代码

  • 查看设备树中 regulator 节点是否精确绑定。

回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表