Skip to content

Commit b8717a8

Browse files
babnskidatabroonie
authored andcommitted
regulator: da9063: implement setter for voltage monitoring
Allow to en- and disable voltage monitoring from the device tree. Consider that the da9063 only monitors under- *and* over-voltage together, so both must be set to the same severity and value. Reviewed-by: Adam Ward <[email protected]> Signed-off-by: Benjamin Bara <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Mark Brown <[email protected]>
1 parent 13186da commit b8717a8

File tree

1 file changed

+90
-28
lines changed

1 file changed

+90
-28
lines changed

drivers/regulator/da9063-regulator.c

Lines changed: 90 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,24 @@ static const unsigned int da9063_bmem_bio_merged_limits[] = {
207207
4600000, 4800000, 5000000, 5200000, 5400000, 5600000, 5800000, 6000000
208208
};
209209

210+
static int da9063_set_xvp(struct regulator_dev *rdev, int lim_uV, int severity, bool enable)
211+
{
212+
struct da9063_regulator *regl = rdev_get_drvdata(rdev);
213+
struct device *dev = regl->hw->dev;
214+
215+
dev_dbg(dev, "%s: lim: %d, sev: %d, en: %d\n", regl->desc.name, lim_uV, severity, enable);
216+
217+
/*
218+
* only support enable and disable.
219+
* the da9063 offers a GPIO (GP_FB2) which is unasserted if an XV happens.
220+
* therefore ignore severity here, as there might be handlers in hardware.
221+
*/
222+
if (lim_uV)
223+
return -EINVAL;
224+
225+
return regmap_field_write(regl->vmon, enable ? 1 : 0);
226+
}
227+
210228
static int da9063_buck_set_mode(struct regulator_dev *rdev, unsigned int mode)
211229
{
212230
struct da9063_regulator *regl = rdev_get_drvdata(rdev);
@@ -545,37 +563,41 @@ static int da9063_buck_get_current_limit(struct regulator_dev *rdev)
545563
}
546564

547565
static const struct regulator_ops da9063_buck_ops = {
548-
.enable = regulator_enable_regmap,
549-
.disable = regulator_disable_regmap,
550-
.is_enabled = regulator_is_enabled_regmap,
551-
.get_voltage_sel = regulator_get_voltage_sel_regmap,
552-
.set_voltage_sel = regulator_set_voltage_sel_regmap,
553-
.list_voltage = regulator_list_voltage_linear,
554-
.set_current_limit = da9063_buck_set_current_limit,
555-
.get_current_limit = da9063_buck_get_current_limit,
556-
.set_mode = da9063_buck_set_mode,
557-
.get_mode = da9063_buck_get_mode,
558-
.get_status = da9063_buck_get_status,
559-
.set_suspend_voltage = da9063_set_suspend_voltage,
560-
.set_suspend_enable = da9063_suspend_enable,
561-
.set_suspend_disable = da9063_suspend_disable,
562-
.set_suspend_mode = da9063_buck_set_suspend_mode,
566+
.enable = regulator_enable_regmap,
567+
.disable = regulator_disable_regmap,
568+
.is_enabled = regulator_is_enabled_regmap,
569+
.get_voltage_sel = regulator_get_voltage_sel_regmap,
570+
.set_voltage_sel = regulator_set_voltage_sel_regmap,
571+
.list_voltage = regulator_list_voltage_linear,
572+
.set_current_limit = da9063_buck_set_current_limit,
573+
.get_current_limit = da9063_buck_get_current_limit,
574+
.set_mode = da9063_buck_set_mode,
575+
.get_mode = da9063_buck_get_mode,
576+
.get_status = da9063_buck_get_status,
577+
.set_suspend_voltage = da9063_set_suspend_voltage,
578+
.set_suspend_enable = da9063_suspend_enable,
579+
.set_suspend_disable = da9063_suspend_disable,
580+
.set_suspend_mode = da9063_buck_set_suspend_mode,
581+
.set_over_voltage_protection = da9063_set_xvp,
582+
.set_under_voltage_protection = da9063_set_xvp,
563583
};
564584

565585
static const struct regulator_ops da9063_ldo_ops = {
566-
.enable = regulator_enable_regmap,
567-
.disable = regulator_disable_regmap,
568-
.is_enabled = regulator_is_enabled_regmap,
569-
.get_voltage_sel = regulator_get_voltage_sel_regmap,
570-
.set_voltage_sel = regulator_set_voltage_sel_regmap,
571-
.list_voltage = regulator_list_voltage_linear,
572-
.set_mode = da9063_ldo_set_mode,
573-
.get_mode = da9063_ldo_get_mode,
574-
.get_status = da9063_ldo_get_status,
575-
.set_suspend_voltage = da9063_set_suspend_voltage,
576-
.set_suspend_enable = da9063_suspend_enable,
577-
.set_suspend_disable = da9063_suspend_disable,
578-
.set_suspend_mode = da9063_ldo_set_suspend_mode,
586+
.enable = regulator_enable_regmap,
587+
.disable = regulator_disable_regmap,
588+
.is_enabled = regulator_is_enabled_regmap,
589+
.get_voltage_sel = regulator_get_voltage_sel_regmap,
590+
.set_voltage_sel = regulator_set_voltage_sel_regmap,
591+
.list_voltage = regulator_list_voltage_linear,
592+
.set_mode = da9063_ldo_set_mode,
593+
.get_mode = da9063_ldo_get_mode,
594+
.get_status = da9063_ldo_get_status,
595+
.set_suspend_voltage = da9063_set_suspend_voltage,
596+
.set_suspend_enable = da9063_suspend_enable,
597+
.set_suspend_disable = da9063_suspend_disable,
598+
.set_suspend_mode = da9063_ldo_set_suspend_mode,
599+
.set_over_voltage_protection = da9063_set_xvp,
600+
.set_under_voltage_protection = da9063_set_xvp,
579601
};
580602

581603
/* Info of regulators for DA9063 */
@@ -749,6 +771,41 @@ static const struct regulator_init_data *da9063_get_regulator_initdata(
749771
return NULL;
750772
}
751773

774+
static int da9063_check_xvp_constraints(struct regulator_config *config)
775+
{
776+
struct da9063_regulator *regl = config->driver_data;
777+
const struct regulation_constraints *constr = &config->init_data->constraints;
778+
const struct notification_limit *uv_l = &constr->under_voltage_limits;
779+
const struct notification_limit *ov_l = &constr->over_voltage_limits;
780+
781+
/* make sure that only one severity is used to clarify if unchanged, enabled or disabled */
782+
if ((!!uv_l->prot + !!uv_l->err + !!uv_l->warn) > 1) {
783+
dev_err(config->dev, "%s: at most one voltage monitoring severity allowed!\n",
784+
regl->desc.name);
785+
return -EINVAL;
786+
}
787+
788+
/* make sure that UV and OV monitoring is set to the same severity and value */
789+
if (uv_l->prot != ov_l->prot) {
790+
dev_err(config->dev,
791+
"%s: protection-microvolt: value must be equal for uv and ov!\n",
792+
regl->desc.name);
793+
return -EINVAL;
794+
}
795+
if (uv_l->err != ov_l->err) {
796+
dev_err(config->dev, "%s: error-microvolt: value must be equal for uv and ov!\n",
797+
regl->desc.name);
798+
return -EINVAL;
799+
}
800+
if (uv_l->warn != ov_l->warn) {
801+
dev_err(config->dev, "%s: warn-microvolt: value must be equal for uv and ov!\n",
802+
regl->desc.name);
803+
return -EINVAL;
804+
}
805+
806+
return 0;
807+
}
808+
752809
static struct of_regulator_match da9063_matches[] = {
753810
[DA9063_ID_BCORE1] = { .name = "bcore1" },
754811
[DA9063_ID_BCORE2] = { .name = "bcore2" },
@@ -970,6 +1027,11 @@ static int da9063_regulator_probe(struct platform_device *pdev)
9701027
if (da9063_reg_matches)
9711028
config.of_node = da9063_reg_matches[id].of_node;
9721029
config.regmap = da9063->regmap;
1030+
1031+
ret = da9063_check_xvp_constraints(&config);
1032+
if (ret)
1033+
return ret;
1034+
9731035
regl->rdev = devm_regulator_register(&pdev->dev, &regl->desc,
9741036
&config);
9751037
if (IS_ERR(regl->rdev)) {

0 commit comments

Comments
 (0)