【电源管理】Linux电源管理之Regular系统

前言

本文简单介绍了Linux电源管理中较为简单的Regular子系统,regular系统使用简单广泛,在各种外设中只要需要电源都可以使用,以减少产品功耗。

一、概念

Regulator指的是稳定器,有电压稳定器及电流稳定器两种,能够自动维持恒定电流或者电压。其中,电压稳定器voltage regulator在电路中比较常见。从设备驱动的角度来看,regulator的控制比较简单,主要有enable/disable/输出电压或电流大小的控制。Linux利用regulator framework对regulator进行管理和控制。

Regulator : 电源芯片, 比如电压转换芯片
Consumer : 消费者,使用电源的部件, Regulator是给Consumer供电的
machine : 单板,上面焊接有Regulator和Consumer
Constraints : 约束, 比如某个电源管理芯片输出的电压范围
Supply : 提供电源的部件, Regulator就是一个Supply; Regulator A可以给Regulator B供电, 那么Regulator B的Supply就是A

二、框架

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jUONADWf-1680666769924)(image/Linux之电源管理/v2-de25e80eac1533cd78bd78caa55ef286_r.jpg)]

1、machine

machin使用struct regulator_init_data,静态的描述regulator在板级的硬件连接情况,这些限制通过驱动或dts配置,涉及到系统供电安全,因此必须小心,这些配置主要包括:

1)用于描述regulator在板级的级联关系:前级regulator(即该regulator的输出是另一个regulator的输入,简称supply regulator)和后级regulator(即该regulator的输入是其它regulator的输出,简称consumer regulator)。

2)利用struct regulation_constraints 描述regulator的物理限制,比如:

  • 输出电压的最大值和最小值(voltage regulator);
  • 输出电流的最大值和最小值(current regulator);
  • 允许的操作(修改电压值、修改电流限制、enable、disable等);
  • 输入电压是多少(当输入是另一个regulator时);
  • 是否不允许关闭(always_on);
  • 是否启动时就要打开(always_on);

2、regulator driver

regulator driver指的是regulator设备的驱动,主要包含如下结构:

1)使用struct regulator_desc,描述regulator的静态信息,包括:名字、supply regulator的名字、中断号、操作函数集(struct regulator_ops)、使用regmap时相应的寄存器即bitmap等。

2)使用struct regulator_config,描述regulator的动态信息(所谓的动态信息,体现在struct regulator_config变量都是局部变量,因此不会永久保存),包括struct regulator_init_data指针、设备指针、enable gpio等。

3)提供regulator的注册接口(regulator_register/devm_regulator_register),该接口接受描述该regulator的两个变量的指针:struct regulator_desc和struct regulator_config,并分配一个新的数据结构(struct regulator_dev,从设备的角度描述regulator),并把静态指针(struct regulator_desc)和动态指针(struct regulator_config)提供的信息保存在其中。

4)regulator driver以struct regulator_dev(代表设备)指针为对象,对regulator进行后续的操作。

2、regulator consumer

regulator consumer抽象出regulator设备(struct regulator),并提供regulator操作相关的接口。包括:regulator_get/regulator_put/regulator_enable/regulator_disable/ regulator_set_voltage/regulator_get_voltage等。

2、regulator core

regulator core负责上述regulator driver/consumer/machine逻辑的具体实现,对底层的硬件进行封装,并提供接口给内核中其他的consumer(使用当前regulator设备的驱动)提供操作接口,并以sysfs的形式,向用户空间提供接口。

三、驱动程序编写思路

  1. regulator:
    注册一个platform_driver: 在它的probe函数里分配、设置、注册一个regulator
    "设置"里要做的事情: 实现regulator的操作, 比如enable, disable, set_voltage
  2. machine:
    注册一个platform_device: 在它的私有数据里指定regulator和consume的对应关系(这个电源芯片给哪一个部件供电)
    指定约束条件(比如电压范围)
  3. consumer: 使用即可: regulator_get, regulator_enable, regulator_disable, regulator_set_voltage…

四、设备树regular节点

  • regular主节点(/Linux-5.4/arch/arm/boot/dts/stm32mp15xx-edx.dtsi +163)
regulators {
164             compatible = "st,stpmic1-regulators";
165             buck1-supply = <&vin>;
166             buck2-supply = <&vin>;
167             buck3-supply = <&vin>;
168             buck4-supply = <&vin>;
169             ldo1-supply = <&v3v3>;
170             ldo2-supply = <&v3v3>;
171             ldo3-supply = <&vdd_ddr>;
172             ldo4-supply = <&vin>;
173             ldo5-supply = <&v3v3>;
174             ldo6-supply = <&v3v3>;
175             vref_ddr-supply = <&vin>;
176             boost-supply = <&vin>;
177             pwr_sw1-supply = <&bst_out>;
178             pwr_sw2-supply = <&bst_out>;
179
180             vddcore: buck1 {
181                 regulator-name = "vddcore";
182                 regulator-min-microvolt = <1200000>;
183                 regulator-max-microvolt = <1350000>;
184                 regulator-always-on;
185                 regulator-initial-mode = <0>;
186                 regulator-over-current-protection;
187             };
188
189             vdd_ddr: buck2 {
190                 regulator-name = "vdd_ddr";
191                 regulator-min-microvolt = <1350000>;
192                 regulator-max-microvolt = <1350000>;
193                 regulator-always-on;
194                 regulator-initial-mode = <0>;
195                 regulator-over-current-protection;
196             };
197
198             vdd: buck3 {
199                 regulator-name = "vdd";
200                 regulator-min-microvolt = <3300000>;
201                 regulator-max-microvolt = <3300000>;
202                 regulator-always-on;
203                 st,mask-reset;
204                 regulator-initial-mode = <0>;
205                 regulator-over-current-protection;
206             };
207
208             v3v3: buck4 {
209                 regulator-name = "v3v3";
210                 regulator-min-microvolt = <3300000>;
211                 regulator-max-microvolt = <3300000>;
212                 regulator-always-on;
213                 regulator-over-current-protection;
214                 regulator-initial-mode = <0>;
215             };
216
217             vdda: ldo1 {
218                 regulator-name = "vdda";
219                 regulator-min-microvolt = <2900000>;
220                 regulator-max-microvolt = <2900000>;
221                 interrupts = <IT_CURLIM_LDO1 0>;
222             };
223
224             v2v8: ldo2 {
225                 regulator-name = "v2v8";
225                 regulator-name = "v2v8";
226                 regulator-min-microvolt = <2800000>;
227                 regulator-max-microvolt = <2800000>;
228                 interrupts = <IT_CURLIM_LDO2 0>;
229             };
230
231             vtt_ddr: ldo3 {
232                 regulator-name = "vtt_ddr";
233                 regulator-min-microvolt = <500000>;
234                 regulator-max-microvolt = <750000>;
235                 regulator-always-on;
236                 regulator-over-current-protection;
237             };
238
239             vdd_usb: ldo4 {
240                 regulator-name = "vdd_usb";
241                 regulator-min-microvolt = <3300000>;
242                 regulator-max-microvolt = <3300000>;
243                 interrupts = <IT_CURLIM_LDO4 0>;
244                 regulator-always-on;
245             };
246
247             vdd_sd: ldo5 {
248                 regulator-name = "vdd_sd";
249                 regulator-min-microvolt = <2900000>;
250                 regulator-max-microvolt = <2900000>;
251                 interrupts = <IT_CURLIM_LDO5 0>;
252                 regulator-boot-on;
253             };
254
255             v1v8: ldo6 {
256                 regulator-name = "v1v8";
257                 regulator-min-microvolt = <1800000>;
258                 regulator-max-microvolt = <1800000>;
259                 interrupts = <IT_CURLIM_LDO6 0>;
260             };
261
262             vref_ddr: vref_ddr {
263                 regulator-name = "vref_ddr";
264                 regulator-always-on;
265                 regulator-over-current-protection;
266             };
267
68             bst_out: boost {
269                 regulator-name = "bst_out";
270                 interrupts = <IT_OCP_BOOST 0>;
271             };
272
273             vbus_otg: pwr_sw1 {
274                 regulator-name = "vbus_otg";
275                 interrupts = <IT_OCP_OTG 0>;
276              };
277
278              vbus_sw: pwr_sw2 {
279                 regulator-name = "vbus_sw";
280                 interrupts = <IT_OCP_SWOUT 0>;
281                 regulator-active-discharge = <1>;
282              };
283         };
284
  • sd卡开关电源管理节点(/Linux-5.4/arch/arm/boot/dts/stm32mp15xx-edx.dtsi 67)
 68     sd_switch: regulator-sd_switch {
 69         compatible = "regulator-gpio";
 70         regulator-name = "sd_switch";
 71         regulator-min-microvolt = <1800000>;
 72         regulator-max-microvolt = <2900000>;
 73         regulator-type = "voltage";
 74         regulator-always-on;
 75
 76         gpios = <&gpiof 14 GPIO_ACTIVE_HIGH>;
 77         gpios-states = <0>;
 78         states = <1800000 0x1 2900000 0x0>;
 79     };

  • 输入电源节点
81     vin: vin {
 82         compatible = "regulator-fixed";
 83         regulator-name = "vin";
 84         regulator-min-microvolt = <5000000>;
 85         regulator-max-microvolt = <5000000>;
 86         regulator-always-on;
 87     };

参考资料

一文搞懂linux regulator子系统 - 知乎 (zhihu.com)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ssq不是上上签

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值