驱动里面如何操作regulator

设备树配置

        qca,bt-vdd-rfa1-supply = <&pm8150_s5>;
        qca,bt-vdd-rfa2-supply = <&pm8150a_s8>;
        qca,bt-vdd-asd-supply = <&pm8150_l16>;

        qca,bt-vdd-aon-voltage-level = <950000 950000>;
        qca,bt-vdd-dig-voltage-level = <950000 952000>;
        qca,bt-vdd-rfa1-voltage-level = <1900000 1900000>;
        qca,bt-vdd-rfa2-voltage-level = <1350000 1350000>;
        qca,bt-vdd-asd-voltage-level = <3024000 3304000>;

内核自带的bt驱动电源部分如下

static int bt_dt_parse_vreg_info(struct device *dev,
        struct bt_power_vreg_data **vreg_data, const char *vreg_name)
{
    int len, ret = 0;
    const __be32 *prop;
    char prop_name[MAX_PROP_SIZE];
    struct bt_power_vreg_data *vreg;
    struct device_node *np = dev->of_node;

    BT_PWR_DBG("vreg dev tree parse for %s", vreg_name);

    *vreg_data = NULL;
    snprintf(prop_name, MAX_PROP_SIZE, "%s-supply", vreg_name);
    if (of_parse_phandle(np, prop_name, 0)) {
        vreg = devm_kzalloc(dev, sizeof(*vreg), GFP_KERNEL);
        if (!vreg) {
            BT_PWR_ERR("No memory for vreg: %s", vreg_name);
            ret = -ENOMEM;
            goto err;
        }

        vreg->name = vreg_name;

        /* Parse voltage-level from each node */
        snprintf(prop_name, MAX_PROP_SIZE,
                "%s-voltage-level", vreg_name);
        prop = of_get_property(np, prop_name, &len);
        if (!prop || (len != (2 * sizeof(__be32)))) {
            dev_warn(dev, "%s %s property\n",
                prop ? "invalid format" : "no", prop_name);
        } else {
            vreg->low_vol_level = be32_to_cpup(&prop[0]);
            vreg->high_vol_level = be32_to_cpup(&prop[1]);
        }

        /* Parse current-level from each node */
        snprintf(prop_name, MAX_PROP_SIZE,
                "%s-current-level", vreg_name);
        ret = of_property_read_u32(np, prop_name, &vreg->load_uA);
        if (ret < 0) {
            BT_PWR_DBG("%s property is not valid\n", prop_name);
            vreg->load_uA = -1;
            ret = 0;
        }

        *vreg_data = vreg;
        BT_PWR_DBG("%s: vol=[%d %d]uV, current=[%d]uA\n",
            vreg->name, vreg->low_vol_level,
            vreg->high_vol_level,
            vreg->load_uA);
    } else
	BT_PWR_INFO("%s: is not provided in device tree", vreg_name);

err:
    return ret;
}

static int bt_vreg_init(struct bt_power_vreg_data *vreg)
{
    int rc = 0;
    struct device *dev = &btpdev->dev;

    BT_PWR_DBG("vreg_get for : %s", vreg->name);

    /* Get the regulator handle */
    vreg->reg = regulator_get(dev, vreg->name);
    if (IS_ERR(vreg->reg)) {
        rc = PTR_ERR(vreg->reg);
        vreg->reg = NULL;
        pr_err("%s: regulator_get(%s) failed. rc=%d\n",
            __func__, vreg->name, rc);
        goto out;
    }

    if ((regulator_count_voltages(vreg->reg) > 0)
            && (vreg->low_vol_level) && (vreg->high_vol_level))
        vreg->set_voltage_sup = 1;

out:
    return rc;
}

static int bt_vreg_enable(struct bt_power_vreg_data *vreg)
{
    int rc = 0;

    if (!vreg->is_enabled) {
        if (vreg->set_voltage_sup) {
            rc = regulator_set_voltage(vreg->reg,
                        vreg->low_vol_level,
                        vreg->high_vol_level);
            if (rc < 0) {
                BT_PWR_ERR("vreg_set_vol(%s) failed rc=%d\n",
                        vreg->name, rc);
                goto out;
            }
        }

        if (vreg->load_uA >= 0) {
            rc = regulator_set_load(vreg->reg,
                    vreg->load_uA);
            if (rc < 0) {
                BT_PWR_ERR("vreg_set_mode(%s) failed rc=%d\n",
                        vreg->name, rc);
                goto out;
            }
        }

        rc = regulator_enable(vreg->reg);
        if (rc < 0) {
            BT_PWR_ERR("regulator_enable(%s) failed. rc=%d\n",
                    vreg->name, rc);
            goto out;
        }
        vreg->is_enabled = true;
    }

    BT_PWR_ERR("vreg_en successful for : %s", vreg->name);
out:
    return rc;
}

static int bt_vreg_disable(struct bt_power_vreg_data *vreg)
{
    int rc = 0;

    if (!vreg)
        return rc;

    if (vreg->is_enabled) {
        rc = regulator_disable(vreg->reg);
        if (rc < 0) {
            BT_PWR_ERR("regulator_disable(%s) failed. rc=%d\n",
                    vreg->name, rc);
            goto out;
        }
        vreg->is_enabled = false;

        if (vreg->set_voltage_sup) {
            /* Set the min voltage to 0 */
            rc = regulator_set_voltage(vreg->reg, 0,
                    vreg->high_vol_level);
            if (rc < 0) {
                BT_PWR_ERR("vreg_set_vol(%s) failed rc=%d\n",
                        vreg->name, rc);
                goto out;
            }
        }
        if (vreg->load_uA >= 0) {
            rc = regulator_set_load(vreg->reg, 0);
            if (rc < 0) {
                BT_PWR_ERR("vreg_set_mode(%s) failed rc=%d\n",
                        vreg->name, rc);
                goto out;
            }
        }
    }

    BT_PWR_ERR("vreg_disable successful for : %s", vreg->name);
out:
    return rc;
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值