/* * Bucks 1 and 2 have two voltage selection registers where selected * voltage can be set. Which of the registers is used can be either controlled * by a control bit in register - or by HW state. If HW state specific voltages * are given - then we assume HW state based control should be used. * * If volatge value is updated to currently selected register - then output * voltage is immediately changed no matter what is set as ramp rate. Thus we * default changing voltage by writing new value to inactive register and * then updating the 'register selection' bit. This naturally only works when * HW state machine is not used to select the voltage.
*/ staticint buck12_set_hw_dvs_levels(struct device_node *np, conststruct regulator_desc *desc, struct regulator_config *cfg)
{ struct bd71815_regulator *data; int ret = 0, val;
data = container_of(desc, struct bd71815_regulator, desc);
if (of_property_present(np, "rohm,dvs-run-voltage") ||
of_property_present(np, "rohm,dvs-suspend-voltage") ||
of_property_present(np, "rohm,dvs-lpsr-voltage") ||
of_property_present(np, "rohm,dvs-snvs-voltage")) {
ret = regmap_read(cfg->regmap, desc->vsel_reg, &val); if (ret) return ret;
if (!(BD71815_BUCK_STBY_DVS & val) &&
!(BD71815_BUCK_DVSSEL & val)) { int val2;
/* * We are currently using voltage from _L. * We'd better copy it to _H and switch to it to * avoid shutting us down if LPSR or SUSPEND is set to * disabled. _L value is at reg _H + 1
*/
ret = regmap_read(cfg->regmap, desc->vsel_reg + 1,
&val2); if (ret) return ret;
ret = regmap_update_bits(cfg->regmap, desc->vsel_reg,
BD71815_VOLT_MASK |
BD71815_BUCK_DVSSEL,
val2 | BD71815_BUCK_DVSSEL); if (ret) return ret;
}
ret = rohm_regulator_set_dvs_levels(data->dvs, np, desc,
cfg->regmap); if (ret) return ret; /* * DVS levels were given => use HW-state machine for voltage * controls. NOTE: AFAIK, This means that if voltage is changed * by SW the ramp-rate is not respected. Should we disable * SW voltage control when the HW state machine is used?
*/
ret = regmap_update_bits(cfg->regmap, desc->vsel_reg,
BD71815_BUCK_STBY_DVS,
BD71815_BUCK_STBY_DVS);
}
staticint bd7181x_led_set_current_limit(struct regulator_dev *rdev, int min_uA, int max_uA)
{ int ret; int onstatus;
onstatus = regulator_is_enabled_regmap(rdev);
ret = regulator_set_current_limit_regmap(rdev, min_uA, max_uA); if (!ret) { int newstatus;
newstatus = regulator_is_enabled_regmap(rdev); if (onstatus != newstatus) { /* * HW FIX: spurious led status change detected. Toggle * state as a workaround
*/ if (onstatus)
ret = regulator_enable_regmap(rdev); else
ret = regulator_disable_regmap(rdev);
if (ret)
dev_err(rdev_get_dev(rdev), "failed to revert the LED state (%d)\n",
ret);
}
}
return ret;
}
staticint bd7181x_buck12_get_voltage_sel(struct regulator_dev *rdev)
{ int rid = rdev_get_id(rdev); int ret, regh, regl, val;
ret = regmap_read(rdev->regmap, regh, &val); if (ret) return ret;
/* * If we use HW state machine based voltage reg selection - then we * return BD71815_REG_BUCK1_VOLT_H which is used at RUN. * Else we do return the BD71815_REG_BUCK1_VOLT_H or * BD71815_REG_BUCK1_VOLT_L depending on which is selected to be used * by BD71815_BUCK_DVSSEL bit
*/ if ((!(val & BD71815_BUCK_STBY_DVS)) && (!(val & BD71815_BUCK_DVSSEL)))
ret = regmap_read(rdev->regmap, regl, &val);
if (ret) return ret;
return val & BD71815_VOLT_MASK;
}
/* * For Buck 1/2.
*/ staticint bd7181x_buck12_set_voltage_sel(struct regulator_dev *rdev, unsignedint sel)
{ int rid = rdev_get_id(rdev); int ret, val, reg, regh, regl;
ret = regmap_read(rdev->regmap, regh, &val); if (ret) return ret;
/* * If bucks 1 & 2 are controlled by state machine - then the RUN state * voltage is set to BD71815_REG_BUCK1_VOLT_H. Changing SUSPEND/LPSR * voltages at runtime is not supported by this driver.
*/ if (((val & BD71815_BUCK_STBY_DVS))) { return regmap_update_bits(rdev->regmap, regh, BD71815_VOLT_MASK,
sel);
} /* Update new voltage to the register which is not selected now */ if (val & BD71815_BUCK_DVSSEL)
reg = regl; else
reg = regh;
ret = regmap_update_bits(rdev->regmap, reg, BD71815_VOLT_MASK, sel); if (ret) return ret;
/* Select the other DVS register to be used */ return regmap_update_bits(rdev->regmap, regh, BD71815_BUCK_DVSSEL,
~val);
}
MODULE_AUTHOR("Tony Luo <luofc@embedinfo.com>");
MODULE_DESCRIPTION("BD71815 voltage regulator driver");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:bd7181x-pmic");
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.13 Sekunden
(vorverarbeitet am 2026-04-28)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.