lkml.org 
[lkml]   [2019]   [Sep]   [3]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 1/3] regulator: fixed: add possibility to enable by clock
    Date
    This commit adds the possibility to choose the compatible
    "regulator-fixed-clock" in devicetree.

    This is a special regulator-fixed that has to have a clock, from which
    the regulator gets switched on and off.

    Signed-off-by: Philippe Schenker <philippe.schenker@toradex.com>
    ---

    drivers/regulator/fixed.c | 86 +++++++++++++++++++++++++++++++++++++--
    1 file changed, 83 insertions(+), 3 deletions(-)

    diff --git a/drivers/regulator/fixed.c b/drivers/regulator/fixed.c
    index 999547dde99d..eadeca9a1a6c 100644
    --- a/drivers/regulator/fixed.c
    +++ b/drivers/regulator/fixed.c
    @@ -23,14 +23,66 @@
    #include <linux/gpio/consumer.h>
    #include <linux/slab.h>
    #include <linux/of.h>
    +#include <linux/of_device.h>
    #include <linux/regulator/of_regulator.h>
    #include <linux/regulator/machine.h>
    +#include <linux/clk.h>
    +

    struct fixed_voltage_data {
    struct regulator_desc desc;
    struct regulator_dev *dev;
    +
    + struct clk *enable_clock;
    + unsigned int clk_enable_counter;
    +};
    +
    +struct fixed_dev_type {
    + bool has_enable_clock;
    +};
    +
    +static const struct fixed_dev_type fixed_voltage_data = {
    + .has_enable_clock = false,
    };

    +static const struct fixed_dev_type fixed_clkenable_data = {
    + .has_enable_clock = true,
    +};
    +
    +static int reg_clock_enable(struct regulator_dev *rdev)
    +{
    + struct fixed_voltage_data *priv = rdev_get_drvdata(rdev);
    + int ret = 0;
    +
    + ret = clk_prepare_enable(priv->enable_clock);
    + if (ret)
    + return ret;
    +
    + priv->clk_enable_counter++;
    +
    + return ret;
    +}
    +
    +static int reg_clock_disable(struct regulator_dev *rdev)
    +{
    + struct fixed_voltage_data *priv = rdev_get_drvdata(rdev);
    +
    + clk_disable_unprepare(priv->enable_clock);
    + priv->clk_enable_counter--;
    +
    + return 0;
    +}
    +
    +static int reg_clock_is_enabled(struct regulator_dev *rdev)
    +{
    + struct fixed_voltage_data *priv = rdev_get_drvdata(rdev);
    +
    + if (priv->clk_enable_counter > 0)
    + return 1;
    +
    + return 0;
    +}
    +

    /**
    * of_get_fixed_voltage_config - extract fixed_voltage_config structure info
    @@ -84,10 +136,19 @@ of_get_fixed_voltage_config(struct device *dev,
    static struct regulator_ops fixed_voltage_ops = {
    };

    +static struct regulator_ops fixed_voltage_clkenabled_ops = {
    + .enable = reg_clock_enable,
    + .disable = reg_clock_disable,
    + .is_enabled = reg_clock_is_enabled,
    +};
    +
    static int reg_fixed_voltage_probe(struct platform_device *pdev)
    {
    + struct device *dev = &pdev->dev;
    struct fixed_voltage_config *config;
    struct fixed_voltage_data *drvdata;
    + const struct fixed_dev_type *drvtype =
    + of_match_device(dev->driver->of_match_table, dev)->data;
    struct regulator_config cfg = { };
    enum gpiod_flags gflags;
    int ret;
    @@ -118,7 +179,18 @@ static int reg_fixed_voltage_probe(struct platform_device *pdev)
    }
    drvdata->desc.type = REGULATOR_VOLTAGE;
    drvdata->desc.owner = THIS_MODULE;
    - drvdata->desc.ops = &fixed_voltage_ops;
    +
    + if (drvtype->has_enable_clock) {
    + drvdata->desc.ops = &fixed_voltage_clkenabled_ops;
    +
    + drvdata->enable_clock = devm_clk_get(dev, NULL);
    + if (IS_ERR(drvdata->enable_clock)) {
    + dev_err(dev, "Cant get enable-clock from devicetree\n");
    + return -ENOENT;
    + }
    + } else {
    + drvdata->desc.ops = &fixed_voltage_ops;
    + }

    drvdata->desc.enable_time = config->startup_delay;

    @@ -191,8 +263,16 @@ static int reg_fixed_voltage_probe(struct platform_device *pdev)

    #if defined(CONFIG_OF)
    static const struct of_device_id fixed_of_match[] = {
    - { .compatible = "regulator-fixed", },
    - {},
    + {
    + .compatible = "regulator-fixed",
    + .data = &fixed_voltage_data,
    + },
    + {
    + .compatible = "regulator-fixed-clock",
    + .data = &fixed_clkenable_data,
    + },
    + {
    + },
    };
    MODULE_DEVICE_TABLE(of, fixed_of_match);
    #endif
    --
    2.23.0
    \
     
     \ /
      Last update: 2019-09-03 10:04    [W:2.552 / U:0.692 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site