iJoe's Blog
Published on

linux驱动学习-设备树05-Regulator

Authors

Regulator 作用与供电关系

Regulator 的电源分配实际上在物理层就已经分配好了,比如:输入源5v -> PMIC/LDO/Buck等硬件 -> 3.3v -> 具体某个硬件

而linux要做的实际就只是一个选择哪条用多少v的电压,或者选择使能,所以从设备树开始,就主要包含了引用关系,同时有些 regulator 内部的对应关系不是通过 phandle 显式写出来,而是 binding/driver 固定规定的,例如 pldo-reg5 → vcc12-supply。比如下面dts例子:

/*
 * 上游系统电源
 */
vcc5v0_sys_s5: regulator-vcc5v0-sys {
    compatible = "regulator-fixed";

    regulator-name = "vcc5v0_sys_s5";
    regulator-min-microvolt = <5000000>;
    regulator-max-microvolt = <5000000>;
    regulator-always-on;
};


/*
 * 一个固定 3.3V regulator
 *
 * 输入来自 vcc_3v3_s0,
 * 输出固定 3.3V,
 * 最终给 SD 卡的 VMMC 使用。
 */
vcc3v3_sd: regulator-vcc3v3-sd {
    compatible = "regulator-fixed";

    regulator-name = "vcc3v3_sd";
    regulator-min-microvolt = <3300000>;
    regulator-max-microvolt = <3300000>;

    vin-supply = <&vcc_3v3_s0>;

    enable-active-high;
    gpios = <&gpio0 RK_PB6 GPIO_ACTIVE_HIGH>;
};


/*
 * RK806 PMIC
 */
rk806: pmic@0 {
    compatible = "rockchip,rk806";

    /*
     * PMIC 内部不同 regulator 的输入电源。
     *
     * dcdc-reg4 对应 vcc4-supply;
     * pldo-reg5 对应 vcc12-supply。
     *
     * 这个对应关系不是从 DTS 子节点名字自动推出来的,
     * 而是 RK806 regulator driver 里规定的。
     */
    vcc4-supply = <&vcc5v0_sys_s5>;
    vcc12-supply = <&vcc5v0_sys_s5>;

    regulators {
        /*
         * PMIC 内部 PLDO5
         *
         * 允许 Linux 在 1.8V ~ 3.3V 范围内使用。
         * 后面作为 SDMMC 的 VQMMC。
         */
        vccio_sd_s0: pldo-reg5 {
            regulator-name = "vccio_sd_s0";

            regulator-min-microvolt = <1800000>;
            regulator-max-microvolt = <3300000>;
        };
    };
};


/*
 * SD/MMC controller
 */
&sdmmc {
    /*
     * SD 卡本体主供电。
     * 使用固定 3.3V 的 vcc3v3_sd。
     */
    vmmc-supply = <&vcc3v3_sd>;

    /*
     * SD/MMC 接口 IO 电平供电。
     * 使用可调的 vccio_sd_s0:
     *
     * 普通模式可以是 3.3V,
     * 某些高速模式可以切换到 1.8V。
     */
    vqmmc-supply = <&vccio_sd_s0>;

    status = "okay";
};

从上面来看,sd的主供电和数据io电压,都来自不同供电支路,分别承担主供电和 IO 电平供电,像主电源是恒定的,而io电压是可变的,所以就由两套来管理。

实际上,从最初始供电源到vcc5v0_sys_s5也经过了多个regulator。

Regulator 的注册、查找与使用

Regulator涉及到的注册,查找,使用很散乱,下面以sd为例。

因为 vmmc/vqmmc 是板上 SDMMC controller/card slot 这一侧的固定硬件资源,所以它们挂在 &sdmmc 节点,并由 MMC host/core 路径获取和管理。如上dts,就是将sd的供电由mmc管理。

注册与查找

compatible 匹配
→ provider driver 被 probe

provider driver
→ devm_regulator_register()
→ 真正注册 regulator

SDMMC controller driver probe
→ 创建 mmc_host
→ mmc_regulator_get_supply()
→ 获取 vmmc/vqmmc

如上dts,regulator将对应的regulator-fixed的driver进行匹配并注册。而mmc则与对应的controller做匹配(细节暂不关注),并获取到对应的电压handle。

使用

使用也很简单,查找阶段只是获取并保存对应的 regulator handle,真正需要供电时才调用 Regulator API 设置电压或使能。

参考文档

torvalds/linux