Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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 <DLG-Adam.Ward.opensource@dm.renesas.com>
Signed-off-by: Benjamin Bara <benjamin.bara@skidata.com>
Link: https://lore.kernel.org/r/20230403-da9063-disable-unused-v3-2-cc4dc698864c@skidata.com
Signed-off-by: Mark Brown <broonie@kernel.org>

authored by

Benjamin Bara and committed by
Mark Brown
b8717a80 13186dae

+90 -28
+90 -28
drivers/regulator/da9063-regulator.c
··· 207 207 4600000, 4800000, 5000000, 5200000, 5400000, 5600000, 5800000, 6000000 208 208 }; 209 209 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 + 210 228 static int da9063_buck_set_mode(struct regulator_dev *rdev, unsigned int mode) 211 229 { 212 230 struct da9063_regulator *regl = rdev_get_drvdata(rdev); ··· 563 545 } 564 546 565 547 static const struct regulator_ops da9063_buck_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_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, 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, 563 + .set_over_voltage_protection = da9063_set_xvp, 564 + .set_under_voltage_protection = da9063_set_xvp, 581 565 }; 582 566 583 567 static const struct regulator_ops da9063_ldo_ops = { 584 - .enable = regulator_enable_regmap, 585 - .disable = regulator_disable_regmap, 586 - .is_enabled = regulator_is_enabled_regmap, 587 - .get_voltage_sel = regulator_get_voltage_sel_regmap, 588 - .set_voltage_sel = regulator_set_voltage_sel_regmap, 589 - .list_voltage = regulator_list_voltage_linear, 590 - .set_mode = da9063_ldo_set_mode, 591 - .get_mode = da9063_ldo_get_mode, 592 - .get_status = da9063_ldo_get_status, 593 - .set_suspend_voltage = da9063_set_suspend_voltage, 594 - .set_suspend_enable = da9063_suspend_enable, 595 - .set_suspend_disable = da9063_suspend_disable, 596 - .set_suspend_mode = da9063_ldo_set_suspend_mode, 568 + .enable = regulator_enable_regmap, 569 + .disable = regulator_disable_regmap, 570 + .is_enabled = regulator_is_enabled_regmap, 571 + .get_voltage_sel = regulator_get_voltage_sel_regmap, 572 + .set_voltage_sel = regulator_set_voltage_sel_regmap, 573 + .list_voltage = regulator_list_voltage_linear, 574 + .set_mode = da9063_ldo_set_mode, 575 + .get_mode = da9063_ldo_get_mode, 576 + .get_status = da9063_ldo_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_ldo_set_suspend_mode, 581 + .set_over_voltage_protection = da9063_set_xvp, 582 + .set_under_voltage_protection = da9063_set_xvp, 597 583 }; 598 584 599 585 /* Info of regulators for DA9063 */ ··· 769 747 } 770 748 771 749 return NULL; 750 + } 751 + 752 + static int da9063_check_xvp_constraints(struct regulator_config *config) 753 + { 754 + struct da9063_regulator *regl = config->driver_data; 755 + const struct regulation_constraints *constr = &config->init_data->constraints; 756 + const struct notification_limit *uv_l = &constr->under_voltage_limits; 757 + const struct notification_limit *ov_l = &constr->over_voltage_limits; 758 + 759 + /* make sure that only one severity is used to clarify if unchanged, enabled or disabled */ 760 + if ((!!uv_l->prot + !!uv_l->err + !!uv_l->warn) > 1) { 761 + dev_err(config->dev, "%s: at most one voltage monitoring severity allowed!\n", 762 + regl->desc.name); 763 + return -EINVAL; 764 + } 765 + 766 + /* make sure that UV and OV monitoring is set to the same severity and value */ 767 + if (uv_l->prot != ov_l->prot) { 768 + dev_err(config->dev, 769 + "%s: protection-microvolt: value must be equal for uv and ov!\n", 770 + regl->desc.name); 771 + return -EINVAL; 772 + } 773 + if (uv_l->err != ov_l->err) { 774 + dev_err(config->dev, "%s: error-microvolt: value must be equal for uv and ov!\n", 775 + regl->desc.name); 776 + return -EINVAL; 777 + } 778 + if (uv_l->warn != ov_l->warn) { 779 + dev_err(config->dev, "%s: warn-microvolt: value must be equal for uv and ov!\n", 780 + regl->desc.name); 781 + return -EINVAL; 782 + } 783 + 784 + return 0; 772 785 } 773 786 774 787 static struct of_regulator_match da9063_matches[] = { ··· 1027 970 if (da9063_reg_matches) 1028 971 config.of_node = da9063_reg_matches[id].of_node; 1029 972 config.regmap = da9063->regmap; 973 + 974 + ret = da9063_check_xvp_constraints(&config); 975 + if (ret) 976 + return ret; 977 + 1030 978 regl->rdev = devm_regulator_register(&pdev->dev, &regl->desc, 1031 979 &config); 1032 980 if (IS_ERR(regl->rdev)) {