设备树配置
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;
}