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

一、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

设备树基本结构示例

dts 复制代码
reg_pcie0: regulator-pcie {
    compatible = "regulator-fixed";
    regulator-name = "MPCIE_3V3";
    regulator-min-microvolt = <3300000>;
    regulator-max-microvolt = <3300000>;
    gpio = <&gpio2 6 GPIO_ACTIVE_HIGH>;
    enable-active-high;
    regulator-always-on;
};

字段说明

属性 含义
compatible 类型(如固定电压 regulator)
regulator-name 名称
regulator-min-microvolt / max-microvolt 输出电压范围
gpio 控制供电开关的 GPIO
enable-active-high 高电平有效
regulator-always-on 系统上电后始终开启

五、设备如何使用 Regulator

以 PCIe 控制器为例:

dts 复制代码
&pcie {
    vpcie-supply = <&reg_pcie0>;
    status = "okay";
};
  • 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

示例代码:

c 复制代码
struct regulator *vpcie;

vpcie = regulator_get(dev, "vpcie");
if (IS_ERR(vpcie))
    return PTR_ERR(vpcie);

regulator_enable(vpcie);

/* 使用完毕后关闭 */
regulator_disable(vpcie);
regulator_put(vpcie);

七、核心结构体分析

struct regulator_desc

描述一个 regulator:

c 复制代码
struct regulator_desc {
    const char *name;
    const char *supply_name;
    int id;
    struct regulator_ops *ops;
    const struct regulator_init_data *init_data;
};

说明

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

八、pca9450 PMIC中的 Regulator 实际例子

c 复制代码
static const struct regulator_desc pca9450_descs[] = {
    {
        .name = "pca9450-buck1",
        .id = PCA9450_BUCK1,
        .of_match = of_match_ptr("buck1"),
        .regulators_node = of_match_ptr("regulators"),
        ...
    },
    ...
};

设备树描述:

dts 复制代码
pmic@25 {
    regulators {
        buck1: BUCK1 {
            regulator-name = "BUCK1";
            regulator-min-microvolt = <600000>;
            regulator-max-microvolt = <2187500>;
        };
    };
};

对应关系:

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

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

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

通常:

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

十、在实际驱动 probe 中应用

例如 PCIe 控制器 probe:

c 复制代码
static int pcie_probe(struct platform_device *pdev)
{
    struct regulator *vpcie;

    vpcie = devm_regulator_get(&pdev->dev, "vpcie");
    if (IS_ERR(vpcie))
        return PTR_ERR(vpcie);

    regulator_enable(vpcie);

    /* 继续初始化其他部分 */

    return 0;
}

特点:

  • 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 调试技巧

  1. 内核启动打印 regulator 状态:
bash 复制代码
dmesg | grep regulator
  1. 动态调节某个 regulator 电压(需要接口支持):
c 复制代码
regulator_set_voltage(vreg, 1800000, 1800000);
  1. 查看设备树中 regulator 节点是否正确绑定。

📌 结语

理解 Regulator 子系统是迈向电源管理高手的第一步。掌握好它,未来在调试 PMIC、电源设计、功耗优化时,都能得心应手。

相关推荐
Once_day16 分钟前
Linux之netlink(2)libnl使用介绍(1)
linux·netlink·libnl3
Hfc.36 分钟前
rabbitmq-集群部署
linux·运维·服务器
追月亮的少年1 小时前
STM32F103C8T6信息
stm32·单片机·嵌入式硬件
lishaoan771 小时前
快速安装Arduino IED的STM32 MCU开发包
stm32·单片机·嵌入式硬件·arduino·arduino ide·stm32 arduino
Python少年班2 小时前
vim粘贴代码格式错乱 排版错乱 缩进错乱 解决方案
linux·编辑器·vim·排版错乱·缩进错乱·格式错乱·换行错乱
一眼青苔2 小时前
如何知道Ubuntu的端口是否被占用,被那个进程占用?如何终止进程
linux·运维·ubuntu
编程绿豆侠3 小时前
Win11安装Ubuntu20.04简记
linux
程序员JerrySUN4 小时前
驱动开发硬核特训 · Day 25 (附加篇):从设备树到驱动——深入理解Linux时钟子系统的实战链路
linux·运维·驱动开发
程序员JerrySUN4 小时前
驱动开发硬核特训 · Day 24(上篇):走进Linux内核时钟子系统 —— 硬件基础全解析
linux·驱动开发·单片机