From 89401b459ee15ad5da75727be4c70222a834d578 Mon Sep 17 00:00:00 2001 From: Philippe Schenker Date: Mon, 27 Dec 2021 17:59:34 +0100 Subject: 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 --- drivers/power/regulator/fixed.c | 54 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/drivers/power/regulator/fixed.c b/drivers/power/regulator/fixed.c index f9f9659621..0e1167fb36 100644 --- a/drivers/power/regulator/fixed.c +++ b/drivers/power/regulator/fixed.c @@ -7,12 +7,19 @@ #include "regulator_common.h" #include +#include #include #include +#include #include #include #include +struct fixed_clock_regulator_info { + struct clk *enable_clock; + unsigned int clk_enable_counter; +}; + static int fixed_regulator_ofdata_to_platdata(struct udevice *dev) { struct dm_regulator_uclass_platdata *uc_pdata; @@ -70,6 +77,38 @@ static int fixed_regulator_set_enable(struct udevice *dev, bool enable) return regulator_common_set_enable(dev, dev_get_platdata(dev), enable); } +static int fixed_clock_regulator_get_enable(struct udevice *dev) +{ + struct fixed_clock_regulator_info *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_info *priv = dev_get_priv(dev); + struct regulator_common_platdata *dev_pdata = dev_get_platdata(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, @@ -77,8 +116,14 @@ 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" }, + { .compatible = "regulator-fixed-clock" }, { }, }; @@ -90,3 +135,12 @@ U_BOOT_DRIVER(fixed_regulator) = { .ofdata_to_platdata = fixed_regulator_ofdata_to_platdata, .platdata_auto_alloc_size = sizeof(struct regulator_common_platdata), }; + +U_BOOT_DRIVER(fixed_clock_regulator) = { + .name = "fixed clk regulator", + .id = UCLASS_REGULATOR, + .ops = &fixed_clock_regulator_ops, + .of_match = fixed_regulator_ids + 1, + .ofdata_to_platdata = fixed_regulator_ofdata_to_platdata, + .platdata_auto_alloc_size = sizeof(struct fixed_clock_regulator_info), +}; -- cgit v1.2.3