From f3b5100aff3a7edd53fd5d15bd6db92d294865e2 Mon Sep 17 00:00:00 2001 From: Philippe Schenker Date: Fri, 8 Apr 2022 10:07:10 +0200 Subject: [PATCH] regulator: fixed: add possibility to enable by clock This commit adds the possibility to choose the compatible "regulator-fixed-clock" in devicetree. This is a special case of regulator-fixed where a clock has to be used to switch the regulator on and off. Signed-off-by: Philippe Schenker Signed-off-by: Marcel Ziswiler --- drivers/power/regulator/fixed.c | 60 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 59 insertions(+), 1 deletion(-) diff --git a/drivers/power/regulator/fixed.c b/drivers/power/regulator/fixed.c index d3e0fb6..90004d1 100644 --- a/drivers/power/regulator/fixed.c +++ b/drivers/power/regulator/fixed.c @@ -6,14 +6,21 @@ */ #include +#include #include #include +#include #include #include #include #include "regulator_common.h" +struct fixed_clock_regulator_plat { + struct clk *enable_clock; + unsigned int clk_enable_counter; +}; + static int fixed_regulator_of_to_plat(struct udevice *dev) { struct dm_regulator_uclass_plat *uc_pdata; @@ -71,6 +78,38 @@ static int fixed_regulator_set_enable(struct udevice *dev, bool enable) return regulator_common_set_enable(dev, dev_get_plat(dev), enable); } +static int fixed_clock_regulator_get_enable(struct udevice *dev) +{ + struct fixed_clock_regulator_plat *priv = dev_get_priv(dev); + + return priv->clk_enable_counter > 0; +} + +static int fixed_clock_regulator_set_enable(struct udevice *dev, bool enable) +{ + struct fixed_clock_regulator_plat *priv = dev_get_priv(dev); + struct regulator_common_plat *dev_pdata = dev_get_plat(dev); + int ret = 0; + + if (enable) { + ret = clk_enable(priv->enable_clock); + priv->clk_enable_counter++; + } else { + ret = clk_disable(priv->enable_clock); + priv->clk_enable_counter--; + } + if (ret) + return ret; + + if (enable && dev_pdata->startup_delay_us) + udelay(dev_pdata->startup_delay_us); + + if (!enable && dev_pdata->off_on_delay_us) + udelay(dev_pdata->off_on_delay_us); + + return ret; +} + static const struct dm_regulator_ops fixed_regulator_ops = { .get_value = fixed_regulator_get_value, .get_current = fixed_regulator_get_current, @@ -78,16 +117,35 @@ static const struct dm_regulator_ops fixed_regulator_ops = { .set_enable = fixed_regulator_set_enable, }; +static const struct dm_regulator_ops fixed_clock_regulator_ops = { + .get_enable = fixed_clock_regulator_get_enable, + .set_enable = fixed_clock_regulator_set_enable, +}; + static const struct udevice_id fixed_regulator_ids[] = { { .compatible = "regulator-fixed" }, { }, }; +static const struct udevice_id fixed_clock_regulator_ids[] = { + { .compatible = "regulator-fixed-clock" }, + { }, +}; + U_BOOT_DRIVER(regulator_fixed) = { .name = "regulator_fixed", .id = UCLASS_REGULATOR, .ops = &fixed_regulator_ops, .of_match = fixed_regulator_ids, .of_to_plat = fixed_regulator_of_to_plat, - .plat_auto = sizeof(struct regulator_common_plat), + .plat_auto = sizeof(struct regulator_common_plat), +}; + +U_BOOT_DRIVER(regulator_fixed_clock) = { + .name = "regulator_fixed_clk", + .id = UCLASS_REGULATOR, + .ops = &fixed_clock_regulator_ops, + .of_match = fixed_clock_regulator_ids, + .of_to_plat = fixed_regulator_of_to_plat, + .plat_auto = sizeof(struct fixed_clock_regulator_plat), }; -- 2.7.4