diff options
author | Alexandre Courbot <acourbot@nvidia.com> | 2016-06-23 03:39:44 -0400 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2016-06-23 06:34:35 -0400 |
commit | 27bfa8893b15a3fa22a593c90a48c8bcb1f9c75b (patch) | |
tree | 1b309e0c66596fcc8c7c9163cc41cb51a47c1664 | |
parent | 830583004e615a4637eacc77866b84908414d7a0 (diff) |
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>
-rw-r--r-- | Documentation/devicetree/bindings/regulator/pwm-regulator.txt | 7 | ||||
-rw-r--r-- | drivers/regulator/pwm-regulator.c | 26 |
2 files changed, 32 insertions, 1 deletions
diff --git a/Documentation/devicetree/bindings/regulator/pwm-regulator.txt b/Documentation/devicetree/bindings/regulator/pwm-regulator.txt index ed936f0f34f2..dd6f59cf1455 100644 --- a/Documentation/devicetree/bindings/regulator/pwm-regulator.txt +++ b/Documentation/devicetree/bindings/regulator/pwm-regulator.txt | |||
@@ -38,13 +38,18 @@ NB: To be clear, if voltage-table is provided, then the device will be used | |||
38 | in Voltage Table Mode. If no voltage-table is provided, then the device will | 38 | in Voltage Table Mode. If no voltage-table is provided, then the device will |
39 | be used in Continuous Voltage Mode. | 39 | be used in Continuous Voltage Mode. |
40 | 40 | ||
41 | Optional properties: | ||
42 | -------------------- | ||
43 | - enable-gpios: GPIO to use to enable/disable the regulator | ||
44 | |||
41 | Any property defined as part of the core regulator binding can also be used. | 45 | Any property defined as part of the core regulator binding can also be used. |
42 | (See: ../regulator/regulator.txt) | 46 | (See: ../regulator/regulator.txt) |
43 | 47 | ||
44 | Continuous Voltage Example: | 48 | Continuous Voltage With Enable GPIO Example: |
45 | pwm_regulator { | 49 | pwm_regulator { |
46 | compatible = "pwm-regulator; | 50 | compatible = "pwm-regulator; |
47 | pwms = <&pwm1 0 8448 0>; | 51 | pwms = <&pwm1 0 8448 0>; |
52 | enable-gpios = <&gpio0 23 GPIO_ACTIVE_HIGH>; | ||
48 | regulator-min-microvolt = <1016000>; | 53 | regulator-min-microvolt = <1016000>; |
49 | regulator-max-microvolt = <1114000>; | 54 | regulator-max-microvolt = <1114000>; |
50 | regulator-name = "vdd_logic"; | 55 | regulator-name = "vdd_logic"; |
diff --git a/drivers/regulator/pwm-regulator.c b/drivers/regulator/pwm-regulator.c index ab3cc0235843..90f8b7fd0437 100644 --- a/drivers/regulator/pwm-regulator.c +++ b/drivers/regulator/pwm-regulator.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/of.h> | 20 | #include <linux/of.h> |
21 | #include <linux/of_device.h> | 21 | #include <linux/of_device.h> |
22 | #include <linux/pwm.h> | 22 | #include <linux/pwm.h> |
23 | #include <linux/gpio/consumer.h> | ||
23 | 24 | ||
24 | struct pwm_regulator_data { | 25 | struct pwm_regulator_data { |
25 | /* Shared */ | 26 | /* Shared */ |
@@ -38,6 +39,9 @@ struct pwm_regulator_data { | |||
38 | 39 | ||
39 | /* Continuous voltage */ | 40 | /* Continuous voltage */ |
40 | int volt_uV; | 41 | int volt_uV; |
42 | |||
43 | /* Enable GPIO */ | ||
44 | struct gpio_desc *enb_gpio; | ||
41 | }; | 45 | }; |
42 | 46 | ||
43 | struct pwm_voltages { | 47 | struct pwm_voltages { |
@@ -94,6 +98,9 @@ static int pwm_regulator_enable(struct regulator_dev *dev) | |||
94 | { | 98 | { |
95 | struct pwm_regulator_data *drvdata = rdev_get_drvdata(dev); | 99 | struct pwm_regulator_data *drvdata = rdev_get_drvdata(dev); |
96 | 100 | ||
101 | if (drvdata->enb_gpio) | ||
102 | gpiod_set_value_cansleep(drvdata->enb_gpio, 1); | ||
103 | |||
97 | return pwm_enable(drvdata->pwm); | 104 | return pwm_enable(drvdata->pwm); |
98 | } | 105 | } |
99 | 106 | ||
@@ -103,6 +110,9 @@ static int pwm_regulator_disable(struct regulator_dev *dev) | |||
103 | 110 | ||
104 | pwm_disable(drvdata->pwm); | 111 | pwm_disable(drvdata->pwm); |
105 | 112 | ||
113 | if (drvdata->enb_gpio) | ||
114 | gpiod_set_value_cansleep(drvdata->enb_gpio, 0); | ||
115 | |||
106 | return 0; | 116 | return 0; |
107 | } | 117 | } |
108 | 118 | ||
@@ -110,6 +120,9 @@ static int pwm_regulator_is_enabled(struct regulator_dev *dev) | |||
110 | { | 120 | { |
111 | struct pwm_regulator_data *drvdata = rdev_get_drvdata(dev); | 121 | struct pwm_regulator_data *drvdata = rdev_get_drvdata(dev); |
112 | 122 | ||
123 | if (drvdata->enb_gpio && !gpiod_get_value_cansleep(drvdata->enb_gpio)) | ||
124 | return false; | ||
125 | |||
113 | return pwm_is_enabled(drvdata->pwm); | 126 | return pwm_is_enabled(drvdata->pwm); |
114 | } | 127 | } |
115 | 128 | ||
@@ -248,6 +261,7 @@ static int pwm_regulator_probe(struct platform_device *pdev) | |||
248 | struct regulator_dev *regulator; | 261 | struct regulator_dev *regulator; |
249 | struct regulator_config config = { }; | 262 | struct regulator_config config = { }; |
250 | struct device_node *np = pdev->dev.of_node; | 263 | struct device_node *np = pdev->dev.of_node; |
264 | enum gpiod_flags gpio_flags; | ||
251 | int ret; | 265 | int ret; |
252 | 266 | ||
253 | if (!np) { | 267 | if (!np) { |
@@ -285,6 +299,18 @@ static int pwm_regulator_probe(struct platform_device *pdev) | |||
285 | return ret; | 299 | return ret; |
286 | } | 300 | } |
287 | 301 | ||
302 | if (init_data->constraints.boot_on || init_data->constraints.always_on) | ||
303 | gpio_flags = GPIOD_OUT_HIGH; | ||
304 | else | ||
305 | gpio_flags = GPIOD_OUT_LOW; | ||
306 | drvdata->enb_gpio = devm_gpiod_get_optional(&pdev->dev, "enable", | ||
307 | gpio_flags); | ||
308 | if (IS_ERR(drvdata->enb_gpio)) { | ||
309 | ret = PTR_ERR(drvdata->enb_gpio); | ||
310 | dev_err(&pdev->dev, "Failed to get enable GPIO: %d\n", ret); | ||
311 | return ret; | ||
312 | } | ||
313 | |||
288 | /* | 314 | /* |
289 | * FIXME: pwm_apply_args() should be removed when switching to the | 315 | * FIXME: pwm_apply_args() should be removed when switching to the |
290 | * atomic PWM API. | 316 | * atomic PWM API. |