regulator: pwm: Support for enable GPIO

Add an optional enable GPIO to the pwm-regulator driver.

Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
Alexandre Courbot 2016-06-23 16:39:44 +09:00 committed by Mark Brown
parent 830583004e
commit 27bfa8893b
2 changed files with 32 additions and 1 deletions

View File

@ -38,13 +38,18 @@ NB: To be clear, if voltage-table is provided, then the device will be used
in Voltage Table Mode. If no voltage-table is provided, then the device will in Voltage Table Mode. If no voltage-table is provided, then the device will
be used in Continuous Voltage Mode. be used in Continuous Voltage Mode.
Optional properties:
--------------------
- enable-gpios: GPIO to use to enable/disable the regulator
Any property defined as part of the core regulator binding can also be used. Any property defined as part of the core regulator binding can also be used.
(See: ../regulator/regulator.txt) (See: ../regulator/regulator.txt)
Continuous Voltage Example: Continuous Voltage With Enable GPIO Example:
pwm_regulator { pwm_regulator {
compatible = "pwm-regulator; compatible = "pwm-regulator;
pwms = <&pwm1 0 8448 0>; pwms = <&pwm1 0 8448 0>;
enable-gpios = <&gpio0 23 GPIO_ACTIVE_HIGH>;
regulator-min-microvolt = <1016000>; regulator-min-microvolt = <1016000>;
regulator-max-microvolt = <1114000>; regulator-max-microvolt = <1114000>;
regulator-name = "vdd_logic"; regulator-name = "vdd_logic";

View File

@ -20,6 +20,7 @@
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_device.h> #include <linux/of_device.h>
#include <linux/pwm.h> #include <linux/pwm.h>
#include <linux/gpio/consumer.h>
struct pwm_regulator_data { struct pwm_regulator_data {
/* Shared */ /* Shared */
@ -38,6 +39,9 @@ struct pwm_regulator_data {
/* Continuous voltage */ /* Continuous voltage */
int volt_uV; int volt_uV;
/* Enable GPIO */
struct gpio_desc *enb_gpio;
}; };
struct pwm_voltages { struct pwm_voltages {
@ -94,6 +98,9 @@ static int pwm_regulator_enable(struct regulator_dev *dev)
{ {
struct pwm_regulator_data *drvdata = rdev_get_drvdata(dev); struct pwm_regulator_data *drvdata = rdev_get_drvdata(dev);
if (drvdata->enb_gpio)
gpiod_set_value_cansleep(drvdata->enb_gpio, 1);
return pwm_enable(drvdata->pwm); return pwm_enable(drvdata->pwm);
} }
@ -103,6 +110,9 @@ static int pwm_regulator_disable(struct regulator_dev *dev)
pwm_disable(drvdata->pwm); pwm_disable(drvdata->pwm);
if (drvdata->enb_gpio)
gpiod_set_value_cansleep(drvdata->enb_gpio, 0);
return 0; return 0;
} }
@ -110,6 +120,9 @@ static int pwm_regulator_is_enabled(struct regulator_dev *dev)
{ {
struct pwm_regulator_data *drvdata = rdev_get_drvdata(dev); struct pwm_regulator_data *drvdata = rdev_get_drvdata(dev);
if (drvdata->enb_gpio && !gpiod_get_value_cansleep(drvdata->enb_gpio))
return false;
return pwm_is_enabled(drvdata->pwm); return pwm_is_enabled(drvdata->pwm);
} }
@ -248,6 +261,7 @@ static int pwm_regulator_probe(struct platform_device *pdev)
struct regulator_dev *regulator; struct regulator_dev *regulator;
struct regulator_config config = { }; struct regulator_config config = { };
struct device_node *np = pdev->dev.of_node; struct device_node *np = pdev->dev.of_node;
enum gpiod_flags gpio_flags;
int ret; int ret;
if (!np) { if (!np) {
@ -285,6 +299,18 @@ static int pwm_regulator_probe(struct platform_device *pdev)
return ret; return ret;
} }
if (init_data->constraints.boot_on || init_data->constraints.always_on)
gpio_flags = GPIOD_OUT_HIGH;
else
gpio_flags = GPIOD_OUT_LOW;
drvdata->enb_gpio = devm_gpiod_get_optional(&pdev->dev, "enable",
gpio_flags);
if (IS_ERR(drvdata->enb_gpio)) {
ret = PTR_ERR(drvdata->enb_gpio);
dev_err(&pdev->dev, "Failed to get enable GPIO: %d\n", ret);
return ret;
}
/* /*
* FIXME: pwm_apply_args() should be removed when switching to the * FIXME: pwm_apply_args() should be removed when switching to the
* atomic PWM API. * atomic PWM API.