|
@@ -20,6 +20,7 @@
|
|
|
#include <linux/of.h>
|
|
|
#include <linux/of_device.h>
|
|
|
#include <linux/pwm.h>
|
|
|
+#include <linux/gpio/consumer.h>
|
|
|
|
|
|
struct pwm_regulator_data {
|
|
|
/* Shared */
|
|
@@ -38,6 +39,9 @@ struct pwm_regulator_data {
|
|
|
|
|
|
/* Continuous voltage */
|
|
|
int volt_uV;
|
|
|
+
|
|
|
+ /* Enable GPIO */
|
|
|
+ struct gpio_desc *enb_gpio;
|
|
|
};
|
|
|
|
|
|
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);
|
|
|
|
|
|
+ if (drvdata->enb_gpio)
|
|
|
+ gpiod_set_value_cansleep(drvdata->enb_gpio, 1);
|
|
|
+
|
|
|
return pwm_enable(drvdata->pwm);
|
|
|
}
|
|
|
|
|
@@ -103,6 +110,9 @@ static int pwm_regulator_disable(struct regulator_dev *dev)
|
|
|
|
|
|
pwm_disable(drvdata->pwm);
|
|
|
|
|
|
+ if (drvdata->enb_gpio)
|
|
|
+ gpiod_set_value_cansleep(drvdata->enb_gpio, 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);
|
|
|
|
|
|
+ if (drvdata->enb_gpio && !gpiod_get_value_cansleep(drvdata->enb_gpio))
|
|
|
+ return false;
|
|
|
+
|
|
|
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_config config = { };
|
|
|
struct device_node *np = pdev->dev.of_node;
|
|
|
+ enum gpiod_flags gpio_flags;
|
|
|
int ret;
|
|
|
|
|
|
if (!np) {
|
|
@@ -285,6 +299,18 @@ static int pwm_regulator_probe(struct platform_device *pdev)
|
|
|
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
|
|
|
* atomic PWM API.
|