Skip to contentSkip to conversation

regulator: Add GPIO enable control to fixed voltage regulator driver

PATCH Superseded Roger Quadros 5 participants 9 messages Jul 31, 2009 – Aug 1, 2009 Voltage and current regulator framework

v2 of 5 Superseded Latest is v5 →

lore
Share & tools
lore
#0 lore raw

PATCH v2 1/1 regulator: Add GPIO enable control to fixed voltage regulator driver

From: Roger Quadros <[email protected]>

Now fixed regulators that have their enable pin connected to a GPIO line can use the fixed regulator driver. The GPIO number and polarity information is passed through platform data. GPIO enable control is acheived using gpiolib.

---
 drivers/regulator/fixed.c       |   66 +++++++++++++++++++++++++++++++++++++-
 include/linux/regulator/fixed.h |   17 ++++++++++
 2 files changed, 81 insertions(+), 2 deletions(-)
drivers/regulator/fixed.c +64 -2
index cdc674f..bcebb0c 100644
@@ -20,20 +20,50 @@
 #include <linux/platform_device.h>
 #include <linux/regulator/driver.h>
 #include <linux/regulator/fixed.h>
+#include <linux/gpio.h>
 
 struct fixed_voltage_data {
 	struct regulator_desc desc;
 	struct regulator_dev *dev;
 	int microvolts;
+	int gpio;
+	int enable_high;
+	int is_enabled;
 };
 
 static int fixed_voltage_is_enabled(struct regulator_dev *dev)
 {
-	return 1;
+	struct fixed_voltage_data *data = rdev_get_drvdata(dev);
+
+	if (data->gpio)
+		return data->is_enabled;
+	else
+		return 1;
 }
 
 static int fixed_voltage_enable(struct regulator_dev *dev)
 {
+	struct fixed_voltage_data *data = rdev_get_drvdata(dev);
+
+	if (data->gpio) {
+		gpio_set_value(data->gpio,
+				data->enable_high ? 1 : 0);
+		data->is_enabled = 1;
+	}
+
+	return 0;
+}
+
+static int fixed_voltage_disable(struct regulator_dev *dev)
+{
+	struct fixed_voltage_data *data = rdev_get_drvdata(dev);
+
+	if (data->gpio) {
+		gpio_set_value(data->gpio,
+				data->enable_high ? 0 : 1);
+		data->is_enabled = 0;
+	}
+
 	return 0;
 }
 
@@ -58,6 +88,7 @@ static int fixed_voltage_list_voltage(struct regulator_dev *dev,
 static struct regulator_ops fixed_voltage_ops = {
 	.is_enabled = fixed_voltage_is_enabled,
 	.enable = fixed_voltage_enable,
+	.disable = fixed_voltage_disable,
 	.get_voltage = fixed_voltage_get_voltage,
 	.list_voltage = fixed_voltage_list_voltage,
 };
@@ -85,12 +116,37 @@ static int regulator_fixed_voltage_probe(struct platform_device *pdev)
 	drvdata->desc.n_voltages = 1;
 
 	drvdata->microvolts = config->microvolts;
+	if (config->gpio) {
+		drvdata->gpio = config->gpio;
+		drvdata->enable_high = config->enable_high;
+
+		ret = gpio_request(config->gpio,
+					config->supply_name);
+		if (ret) {
+			dev_err(&pdev->dev, "Could not obtain regulator"
+				"enable GPIO %d: %d\n", config->gpio, ret);
+			goto err_name;
+		}
+
+		/* set output direction without changing state
+		 * to prevent glitch
+		 */
+		ret = gpio_get_value(config->gpio);
+		ret = gpio_direction_output(config->gpio, ret);
+		if (ret) {
+			dev_err(&pdev->dev, "Could not configure "
+				"enable GPIO %d direction: %d\n",
+						config->gpio, ret);
+			goto err_gpio;
+		}
+	} else
+		dev_warn(&pdev->dev, "Not using GPIO 0 for enable control\n");
 
 	drvdata->dev = regulator_register(&drvdata->desc, &pdev->dev,
 					  config->init_data, drvdata);
 	if (IS_ERR(drvdata->dev)) {
 		ret = PTR_ERR(drvdata->dev);
-		goto err_name;
+		goto err_gpio;
 	}
 
 	platform_set_drvdata(pdev, drvdata);
@@ -100,6 +156,9 @@ static int regulator_fixed_voltage_probe(struct platform_device *pdev)
 
 	return 0;
 
+err_gpio:
+	if (config->gpio)
+		gpio_free(config->gpio);
 err_name:
 	kfree(drvdata->desc.name);
 err:
@@ -115,6 +174,9 @@ static int regulator_fixed_voltage_remove(struct platform_device *pdev)
 	kfree(drvdata->desc.name);
 	kfree(drvdata);
 
+	if (drvdata->gpio)
+		gpio_free(drvdata->gpio);
+
 	return 0;
 }
 
include/linux/regulator/fixed.h +17 -0
index 91b4da3..b40e06b 100644
@@ -16,9 +16,26 @@
 
 struct regulator_init_data;
 
+/**
+ * struct fixed_voltage_config - fixed_voltage_config structure
+ * @supply_name:	Name of the regulator supply
+ * @microvolts:		Output voltage of regulator
+ * @use_gpio_control:	Use GPIO enable control
+ * @gpio:		GPIO to use for enable control
+ * @enable_high:	Polarity of enable GPIO
+ *			1 = Active high, 0 = Active low
+ * @init_data:		regulator_init_data
+ *
+ * This structure contains fixed voltage regulator configuration
+ * information that must be passed by platform code to the fixed
+ * voltage regulator driver.
+ */
 struct fixed_voltage_config {
 	const char *supply_name;
 	int microvolts;
+	int use_gpio_control;
+	int gpio;
+	int enable_high;
 	struct regulator_init_data *init_data;
 };
 
Signature · 1 line
1.6.0.4
#1 lore raw
Quoted 6 lines · ext Roger Quadros

From: Roger Quadros <[email protected]>

Now fixed regulators that have their enable pin connected to a GPIO line can use the fixed regulator driver. The GPIO number and polarity information is passed through platform data. GPIO enable control is acheived using gpiolib.

little typo here.

Quoted 16 lines
---
 drivers/regulator/fixed.c       |   66 +++++++++++++++++++++++++++++++++++++-
 include/linux/regulator/fixed.h |   17 ++++++++++
 2 files changed, 81 insertions(+), 2 deletions(-)
drivers/regulator/fixed.c +0 -0
index cdc674f..bcebb0c 100644
@@ -20,20 +20,50 @@
 #include <linux/platform_device.h>
 #include <linux/regulator/driver.h>

drivers/regulator/fixed.c line 31

Quoted 10 lines
drivers/regulator/fixed.c +4 -0
 #include <linux/regulator/fixed.h>
+#include <linux/gpio.h>
 
 struct fixed_voltage_data {
 	struct regulator_desc desc;
 	struct regulator_dev *dev;
 	int microvolts;
+	int gpio;
+	int enable_high;
+	int is_enabled;

how about making these two:

unsigned enable_high:1;
unsigned is_enabled:1;

Quoted 10 lines
drivers/regulator/fixed.c +5 -1
 };
 
 static int fixed_voltage_is_enabled(struct regulator_dev *dev)
 {
-	return 1;
+	struct fixed_voltage_data *data = rdev_get_drvdata(dev);
+
+	if (data->gpio)
+		return data->is_enabled;
+	else

drivers/regulator/fixed.c line 50

Quoted 10 lines
drivers/regulator/fixed.c +6 -0
+		return 1;
 }
 
 static int fixed_voltage_enable(struct regulator_dev *dev)
 {
+	struct fixed_voltage_data *data = rdev_get_drvdata(dev);
+
+	if (data->gpio) {
+		gpio_set_value(data->gpio,
+				data->enable_high ? 1 : 0);

gpio_set_value(data->gpio, data->enable_high);
should be enough, no ?

drivers/regulator/fixed.c line 63

Quoted 13 lines
drivers/regulator/fixed.c +13 -0
+		data->is_enabled = 1;
+	}
+
+	return 0;
+}
+
+static int fixed_voltage_disable(struct regulator_dev *dev)
+{
+	struct fixed_voltage_data *data = rdev_get_drvdata(dev);
+
+	if (data->gpio) {
+		gpio_set_value(data->gpio,
+				data->enable_high ? 0 : 1);

gpio_set_value(data->gpio, !data->enable_high); ??

drivers/regulator/fixed.c static int regulator_fixed_voltage_probe(struct platform_device *pdev) · line 119

Quoted 5 lines
drivers/regulator/fixed.c +1 -0
@@ -85,12 +116,37 @@ static int regulator_fixed_voltage_probe(struct platform_device *pdev)
 	drvdata->desc.n_voltages = 1;
 
 	drvdata->microvolts = config->microvolts;
+	if (config->gpio) {

gpio_is_valid() since 0 is a valid gpio number.

Quoted 5 lines
drivers/regulator/fixed.c +5 -0
+		drvdata->gpio = config->gpio;
+		drvdata->enable_high = config->enable_high;
+
+		ret = gpio_request(config->gpio,
+					config->supply_name);

drivers/regulator/fixed.c static int regulator_fixed_voltage_probe(struct platform_device *pdev) · line 134

Quoted 10 lines
drivers/regulator/fixed.c +10 -0
+		if (ret) {
+			dev_err(&pdev->dev, "Could not obtain regulator"
+				"enable GPIO %d: %d\n", config->gpio, ret);
+			goto err_name;
+		}
+
+		/* set output direction without changing state
+		 * to prevent glitch
+		 */
+		ret = gpio_get_value(config->gpio);

and if this fails ??

drivers/regulator/fixed.c static int regulator_fixed_voltage_probe(struct platform_device *pdev) · line 135

Quoted 1 line
drivers/regulator/fixed.c +1 -0
+		ret = gpio_direction_output(config->gpio, ret);

you continue anyways...

drivers/regulator/fixed.c static int regulator_fixed_voltage_probe(struct platform_device *pdev) · line 142

Quoted 7 lines
drivers/regulator/fixed.c +7 -0
+		if (ret) {
+			dev_err(&pdev->dev, "Could not configure "
+				"enable GPIO %d direction: %d\n",
+						config->gpio, ret);
+			goto err_gpio;
+		}
+	} else

this should have brackets.

Quoted 12 lines
drivers/regulator/fixed.c +2 -1
+		dev_warn(&pdev->dev, "Not using GPIO 0 for enable control\n");
 
 	drvdata->dev = regulator_register(&drvdata->desc, &pdev->dev,
 					  config->init_data, drvdata);
 	if (IS_ERR(drvdata->dev)) {
 		ret = PTR_ERR(drvdata->dev);
-		goto err_name;
+		goto err_gpio;
 	}
 
 	platform_set_drvdata(pdev, drvdata);

drivers/regulator/fixed.c static int regulator_fixed_voltage_probe(struct platform_device *pdev) · line 160

Quoted 5 lines
drivers/regulator/fixed.c +2 -0
@@ -100,6 +156,9 @@ static int regulator_fixed_voltage_probe(struct platform_device *pdev)
 
 	return 0;
 
+err_gpio:
+	if (config->gpio)

0 is a valid gpio number, you should initialize everyone using this to -EINVAL, for example, and use gpio_is_valid()

drivers/regulator/fixed.c static int regulator_fixed_voltage_remove(struct platform_device *pdev) · line 177

Quoted 9 lines
drivers/regulator/fixed.c +2 -0
+		gpio_free(config->gpio);
 err_name:
 	kfree(drvdata->desc.name);
 err:
@@ -115,6 +174,9 @@ static int regulator_fixed_voltage_remove(struct platform_device *pdev)
 	kfree(drvdata->desc.name);
 	kfree(drvdata);
 
+	if (drvdata->gpio)

likewise, use gpio_is_valid()

Quoted 22 lines
drivers/regulator/fixed.c +2 -0
+		gpio_free(drvdata->gpio);
+
 	return 0;
 }
 
include/linux/regulator/fixed.h +9 -0
index 91b4da3..b40e06b 100644
@@ -16,9 +16,26 @@
 
 struct regulator_init_data;
 
+/**
+ * struct fixed_voltage_config - fixed_voltage_config structure
+ * @supply_name:	Name of the regulator supply
+ * @microvolts:		Output voltage of regulator
+ * @use_gpio_control:	Use GPIO enable control
+ * @gpio:		GPIO to use for enable control
+ * @enable_high:	Polarity of enable GPIO
+ *			1 = Active high, 0 = Active low
+ * @init_data:		regulator_init_data

include/linux/regulator/fixed.h line 37

Quoted 10 lines
include/linux/regulator/fixed.h +7 -0
+ *
+ * This structure contains fixed voltage regulator configuration
+ * information that must be passed by platform code to the fixed
+ * voltage regulator driver.
+ */
 struct fixed_voltage_config {
 	const char *supply_name;
 	int microvolts;
+	int use_gpio_control;
+	int gpio;

put a comment for this field asking people to intialized to -EINVAL if they're not gonna use it.

include/linux/regulator/fixed.h line 38

Quoted 1 line
include/linux/regulator/fixed.h +1 -0
+	int enable_high;

unsigned enable_high:1;

Signature · 1 line
balbi
#2 lore raw
In reply to Roger Quadros
Quoted 31 lines · Roger Quadros

From: Roger Quadros <[email protected]>

Now fixed regulators that have their enable pin connected to a GPIO line can use the fixed regulator driver. The GPIO number and polarity information is passed through platform data. GPIO enable control is acheived using gpiolib.

---
 drivers/regulator/fixed.c       |   66 +++++++++++++++++++++++++++++++++++++- include/linux/regulator/fixed.h |   17 ++++++++++

 2 files changed, 81 insertions(+), 2 deletions(-)
drivers/regulator/fixed.c +2 -0
index cdc674f..bcebb0c 100644
@@ -20,20 +20,50 @@
  #include <linux/platform_device.h>
  #include <linux/regulator/driver.h>
  #include <linux/regulator/fixed.h>
+#include <linux/gpio.h>
 
  struct fixed_voltage_data {
        struct regulator_desc desc;
        struct regulator_dev *dev;
        int microvolts;
+       int gpio;

drivers/regulator/fixed.c line 38

Quoted 10 lines
drivers/regulator/fixed.c +5 -1
+       int enable_high;
+       int is_enabled;
  };
 
  static int fixed_voltage_is_enabled(struct regulator_dev *dev)
  {
-       return 1;
+       struct fixed_voltage_data *data = rdev_get_drvdata(dev);
+
+       if (data->gpio)

if (gpio_is_valid(data->gpio))

drivers/regulator/fixed.c line 42

Quoted 4 lines
drivers/regulator/fixed.c +3 -0
+               return data->is_enabled;
+       else
+               return 1;
  }

Or this function could just unconditionally return data->is_enabled if you set it to 1 in _probe for gpio-less regulators.

drivers/regulator/fixed.c line 48

Quoted 6 lines
drivers/regulator/fixed.c +3 -0
  static int fixed_voltage_enable(struct regulator_dev *dev)
  {
+       struct fixed_voltage_data *data = rdev_get_drvdata(dev);
+
+       if (data->gpio) {

if (gpio_is_valid(data->gpio)) {

Quoted 30 lines
drivers/regulator/fixed.c +19 -0
+               gpio_set_value(data->gpio,
+                               data->enable_high ? 1 : 0);
+               data->is_enabled = 1;
+       }
+
+       return 0;
+}
+
+static int fixed_voltage_disable(struct regulator_dev *dev)
+{
+       struct fixed_voltage_data *data = rdev_get_drvdata(dev);
+
+       if (data->gpio) {
+               gpio_set_value(data->gpio,
+                               data->enable_high ? 0 : 1);
+               data->is_enabled = 0;
+       }
+
        return 0;
  }
 
@@ -58,6 +88,7 @@ static int fixed_voltage_list_voltage(struct regulator_dev *dev,
  static struct regulator_ops fixed_voltage_ops = {
        .is_enabled = fixed_voltage_is_enabled,
        .enable = fixed_voltage_enable,
+       .disable = fixed_voltage_disable,
        .get_voltage = fixed_voltage_get_voltage,
        .list_voltage = fixed_voltage_list_voltage,
  };

drivers/regulator/fixed.c static int regulator_fixed_voltage_probe(struct platform_device *pdev) · line 119

Quoted 4 lines
drivers/regulator/fixed.c +1 -0
@@ -85,12 +116,37 @@ static int regulator_fixed_voltage_probe(struct platform_device *pdev)
        drvdata->desc.n_voltages = 1;
 
        drvdata->microvolts = config->microvolts;
+       if (config->gpio) {

That should be more like

    if (gpio_is_valid(config->gpio) && config->gpio) {

People are going to set config->gpio to negative values to disable the gpio. (And I think eventually GPIO0 should be allowed here.)

Quoted 35 lines
drivers/regulator/fixed.c +25 -1
+               drvdata->gpio = config->gpio;
+               drvdata->enable_high = config->enable_high;
+
+               ret = gpio_request(config->gpio,
+                                       config->supply_name);
+               if (ret) {
+                       dev_err(&pdev->dev, "Could not obtain regulator"
+                               "enable GPIO %d: %d\n", config->gpio, ret);
+                       goto err_name;
+               }
+
+               /* set output direction without changing state
+                * to prevent glitch
+                */
+               ret = gpio_get_value(config->gpio);
+               ret = gpio_direction_output(config->gpio, ret);
+               if (ret) {
+                       dev_err(&pdev->dev, "Could not configure "
+                               "enable GPIO %d direction: %d\n",
+                                               config->gpio, ret);
+                       goto err_gpio;
+               }
+       } else
+               dev_warn(&pdev->dev, "Not using GPIO 0 for enable control\n");
 
        drvdata->dev = regulator_register(&drvdata->desc, &pdev->dev,
                                          config->init_data, drvdata);
        if (IS_ERR(drvdata->dev)) {
                ret = PTR_ERR(drvdata->dev);
-               goto err_name;
+               goto err_gpio;
        }
 
        platform_set_drvdata(pdev, drvdata);

drivers/regulator/fixed.c static int regulator_fixed_voltage_probe(struct platform_device *pdev) · line 161

Quoted 6 lines
drivers/regulator/fixed.c +3 -0
@@ -100,6 +156,9 @@ static int regulator_fixed_voltage_probe(struct platform_device *pdev)
 
        return 0;
 
+err_gpio:
+       if (config->gpio)
+               gpio_free(config->gpio);

gpio_is_valid(config->gpio)

drivers/regulator/fixed.c static int regulator_fixed_voltage_remove(struct platform_device *pdev) · line 179

Quoted 10 lines

 err_name:
       kfree(drvdata->desc.name);
 err:

drivers/regulator/fixed.c +3 -0
@@ -115,6 +174,9 @@ static int regulator_fixed_voltage_remove(struct platform_device *pdev)
        kfree(drvdata->desc.name);
        kfree(drvdata);
 
+       if (drvdata->gpio)
+               gpio_free(drvdata->gpio);
+

dito

Quoted 19 lines
drivers/regulator/fixed.c +0 -0
        return 0;
  }
 
include/linux/regulator/fixed.h +8 -0
index 91b4da3..b40e06b 100644
@@ -16,9 +16,26 @@
 
  struct regulator_init_data;
 
+/**
+ * struct fixed_voltage_config - fixed_voltage_config structure
+ * @supply_name:       Name of the regulator supply
+ * @microvolts:                Output voltage of regulator
+ * @use_gpio_control:  Use GPIO enable control
+ * @gpio:              GPIO to use for enable control
+ * @enable_high:       Polarity of enable GPIO
+ *                     1 = Active high, 0 = Active low

include/linux/regulator/fixed.h line 36

Quoted 10 lines
include/linux/regulator/fixed.h +7 -0
+ * @init_data:         regulator_init_data
+ *
+ * This structure contains fixed voltage regulator configuration
+ * information that must be passed by platform code to the fixed
+ * voltage regulator driver.
+ */
  struct fixed_voltage_config {
        const char *supply_name;
        int microvolts;
+       int use_gpio_control;

You wanted to drop that, it's not used anymore.

Quoted 9 lines
include/linux/regulator/fixed.h +2 -1
+       int gpio;
+       int enable_high;
        struct regulator_init_data *init_data;
  };
 
--

1.6.0.4

regards
Philipp

#3 lore raw
In reply to Roger Quadros
Quoted 2 lines · Roger Quadros

Err... no, it isn't. I reviewed a previous version of the patch but there were some issues that needed fixing. I've not reviewed this version.

drivers/regulator/fixed.c line 39

Quoted 7 lines

static int fixed_voltage_is_enabled(struct regulator_dev *dev) {

drivers/regulator/fixed.c +4 -1
-	return 1;
+	struct fixed_voltage_data *data = rdev_get_drvdata(dev);
+
+	if (data->gpio)
+		return data->is_enabled;

Please use gpio_is_valid() as Phillip previously suggested. For this particular use you could simplify the code marginally by just setting is_enabled at probe() time if there's no GPIO, not that it really matters.

drivers/regulator/fixed.c line 50

Quoted 3 lines
drivers/regulator/fixed.c +3 -0
+       if (data->gpio) {
+               gpio_set_value(data->gpio,
+                               data->enable_high ? 1 : 0);

_cansleep(), please, as previously requested.

drivers/regulator/fixed.c static int regulator_fixed_voltage_probe(struct platform_device *pdev) · line 134

Quoted 1 line
drivers/regulator/fixed.c +1 -0
+		ret = gpio_get_value(config->gpio);

Can this fail? It returns an int...

drivers/regulator/fixed.c static int regulator_fixed_voltage_probe(struct platform_device *pdev) · line 140

Quoted 6 lines
drivers/regulator/fixed.c +6 -0
+		ret = gpio_direction_output(config->gpio, ret);
+		if (ret) {
+			dev_err(&pdev->dev, "Could not configure "
+				"enable GPIO %d direction: %d\n",
+						config->gpio, ret);
+			goto err_gpio;

As previously requested please don't split for log messages text over lines unless you have to. It makes it easier to find the message from a kernel log - grep for 'configure enable GPIO' won't match this source file the way you've written it above.

drivers/regulator/fixed.c static int regulator_fixed_voltage_probe(struct platform_device *pdev) · line 143

Quoted 3 lines
drivers/regulator/fixed.c +3 -0
+		}
+	} else
+		dev_warn(&pdev->dev, "Not using GPIO 0 for enable control\n");

Probably better to soldier on and use the GPIO here but either way is fine; the warning is for the benefit of existing out of tree users to help them transition gracefully.

#4 lore raw
Quoted 26 lines · Mark Brown
Quoted 2 lines · Roger Quadros

Err...  no, it isn't.  I reviewed a previous version of the patch but there were some issues that needed fixing.  I've not reviewed this version.

Quoted 7 lines

 static int fixed_voltage_is_enabled(struct regulator_dev *dev) {
-     return 1;
+     struct fixed_voltage_data *data = rdev_get_drvdata(dev); +
+     if (data->gpio)
+             return data->is_enabled;

Please use gpio_is_valid() as Phillip previously suggested.  For this particular use you could simplify the code marginally by just setting is_enabled at probe() time if there's no GPIO, not that it really matters.

Quoted 3 lines

+       if (data->gpio) {
+               gpio_set_value(data->gpio,
+                               data->enable_high ? 1 : 0);

Quoted 5 lines

_cansleep(), please, as previously requested.

Quoted 1 line

+             ret = gpio_get_value(config->gpio);

Can this fail?  It returns an int...

No, gpio_get_value(_cansleep) return either zero or non-zero. I think some I2C gpio chips just return zero when the read fails. Also that's the return value if a gpiochip doesn't define the .get method.

Only problem: drivers/gpio/gpiolib.c contains this piece of wisdom:

/* Drivers MUST set GPIO direction before making get/set calls. In
* some cases this is done in early boot, before IRQs are enabled. [...]
*/

Quoted 12 lines
Quoted 6 lines

+             ret = gpio_direction_output(config->gpio, ret);
+             if (ret) {
+                     dev_err(&pdev->dev, "Could not configure "
+                             "enable GPIO %d direction: %d\n",
+                                             config->gpio, ret);
+                     goto err_gpio;

As previously requested please don't split for log messages text over lines unless you have to.  It makes it easier to find the message from a kernel log - grep for 'configure enable GPIO' won't match this source file the way you've written it above.

Quoted 8 lines
Quoted 3 lines

+             }
+     } else
+             dev_warn(&pdev->dev, "Not using GPIO 0 for enable control\n");

Probably better to soldier on and use the GPIO here but either way is fine; the warning is for the benefit of existing out of tree users to help them transition gracefully.

regards
Philipp

#5 lore raw
Quoted 13 lines · pHilipp Zabel
Quoted 6 lines · Mark Brown
Quoted 1 line · Roger Quadros

+             ret = gpio_get_value(config->gpio);

Can this fail?  It returns an int...

No, gpio_get_value(_cansleep) return either zero or non-zero. I think some I2C gpio chips just return zero when the read fails. Also that's the return value if a gpiochip doesn't define the .get method.

Quoted 7 lines

Only problem: drivers/gpio/gpiolib.c contains this piece of wisdom:

/* Drivers MUST set GPIO direction before making get/set calls.  In
 * some cases this is done in early boot, before IRQs are enabled. [...]
 */

Not having gpio_get_direction() in gpiolib is a limitation I think. Can we just do the following for now ? (i.e. disable regulator by default) Will there be any glitch? If yes, then how?

                ret = gpio_request(config->gpio, config->supply_name);
                ...
-               ret = gpio_get_value(config->gpio);
-               ret = gpio_direction_output(config->gpio, ret);
+               ret = gpio_direction_output(config->gpio, !config->enable_high);
                if (ret) {
                        dev_err(&pdev->dev, "Could not configure
enable GPIO %d direction: %d\n",
                                                        config->gpio, ret);
                        goto err_gpio;
                }
#6 lore raw
Quoted 3 lines · Roger Quadros

Not having gpio_get_direction() in gpiolib is a limitation I think. Can we just do the following for now ? (i.e. disable regulator by default) Will there be any glitch? If yes, then how?

If you're going to do this then like I say you should make the default state controllable by platform data. If we unconditionally disable the regulator then if, for example, the regulator is controlling the display backlight and it's on when Linux get controls then the user will see the backlight blink off then on during startup.

#7 lore raw
Quoted 6 lines · Mark Brown
Quoted 3 lines · Roger Quadros

Not having gpio_get_direction() in gpiolib is a limitation I think. Can we just do the following for now ? (i.e. disable regulator by default) Will there be any glitch? If yes, then how?

Quoted 6 lines

If you're going to do this then like I say you should make the default state controllable by platform data.  If we unconditionally disable the regulator then if, for example, the regulator is controlling the display backlight and it's on when Linux get controls then the user will see the backlight blink off then on during startup.

OK I will add another bit for this in fixed_voltage_config.

Do we need to check whether CONFIG_GPIOLIB is available? or do we need to explicitly
select it in Kconfig?

#8 lore raw
Quoted 3 lines · Roger Quadros

Do we need to check whether CONFIG_GPIOLIB is available? or do we need to explicitly
select it in Kconfig?

Check but I think that all the APIs you are using are stubbed out if gpiolib is not available so you can just ignore it. If not then ifdefs around the code are the way forward.