linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2] regulator: gpio-regulator: add DT bindings
@ 2012-09-10 15:03 Daniel Mack
  2012-09-10 19:40 ` Stephen Warren
  0 siblings, 1 reply; 5+ messages in thread
From: Daniel Mack @ 2012-09-10 15:03 UTC (permalink / raw)
  To: devicetree-discuss; +Cc: lrg, broonie, linux-kernel, Daniel Mack

Add DT bindings for the gpio-regulator driver and some documentation on
how to use it.

Signed-off-by: Daniel Mack <zonque@gmail.com>
---
v1 -> v2
  Fixed wrong kzalloc() size.

 .../bindings/regulator/gpio-regulator.txt          |  58 ++++++++++
 drivers/regulator/gpio-regulator.c                 | 118 ++++++++++++++++++++-
 2 files changed, 175 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/regulator/gpio-regulator.txt

diff --git a/Documentation/devicetree/bindings/regulator/gpio-regulator.txt b/Documentation/devicetree/bindings/regulator/gpio-regulator.txt
new file mode 100644
index 0000000..ea3eb09
--- /dev/null
+++ b/Documentation/devicetree/bindings/regulator/gpio-regulator.txt
@@ -0,0 +1,58 @@
+Device tree bindings for GPIO controlled voltages
+
+Voltage or current regulators on boards that are controlled by GPIOs can
+be used by the gpio-regulator driver.
+
+Required properties:
+
+ - "compatible":	must be set to "gpio-regulator"
+ - "regulator-name": 	must be set to a string describing the name of this
+			regulator.
+
+Optional properties:
+
+ - "startup-delay":		Start-up time in microseconds
+ - "enable-high":		Polarity of enable GPIO. Active high if
+				defined, otherwise active low
+ - "enabled-at-boot":		If set, the regulator has been enabled at boot
+				time
+ - "regulator-type-voltage":	The regulator controls a voltage
+ - "regulator-type-current":	The regulator controls a current
+ - "states":			An array of possible states, describing the
+				GPIO states to reach a given value
+	- "value":		The value of the state, in microvolts or
+				microamperes
+	- "gpios":		bitfield of gpio target-states for the value
+				The n-th bit in the bitfield describes the
+				state of the n-th GPIO from the gpios-array
+
+Also, all properties described in
+Documentation/devicetree/bindings/regulator/regulator.txt are supported as
+well.
+
+Example:
+
+	reg_gpio {
+		compatible = "gpio-regulator";
+		regulator-name = "voltage";
+		regulator-enable-high;
+		regulator-type-voltage;
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-always-on;
+
+		gpios = <&gpio 23 0>;
+
+		states {
+			state-on {
+				value = <3300000>;
+				gpios = <0x1>;
+			};
+
+			state-off {
+				value = <0>;
+				gpios = <0x0>;
+			};
+		};
+	};
+
diff --git a/drivers/regulator/gpio-regulator.c b/drivers/regulator/gpio-regulator.c
index 8b5944f..d34ec68 100644
--- a/drivers/regulator/gpio-regulator.c
+++ b/drivers/regulator/gpio-regulator.c
@@ -25,10 +25,14 @@
 #include <linux/err.h>
 #include <linux/mutex.h>
 #include <linux/module.h>
+#include <linux/string.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
 #include <linux/platform_device.h>
 #include <linux/regulator/driver.h>
 #include <linux/regulator/machine.h>
 #include <linux/regulator/gpio-regulator.h>
+#include <linux/regulator/of_regulator.h>
 #include <linux/gpio.h>
 #include <linux/slab.h>
 
@@ -134,13 +138,124 @@ static struct regulator_ops gpio_regulator_current_ops = {
 	.set_current_limit = gpio_regulator_set_current_limit,
 };
 
+#ifdef CONFIG_OF
+static const struct of_device_id gpio_regulator_dt_ids[] = {
+	{ .compatible = "gpio-regulator", },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, gpio_regulator_dt_ids);
+
+static int gpio_regulator_probe_dt(struct platform_device *pdev)
+{
+	struct device_node *states, *np = pdev->dev.of_node;
+	struct gpio_regulator_config *config;
+	int ret, i;
+
+	if (!np)
+		return 0;
+
+	config = kzalloc(sizeof(*config), GFP_KERNEL);
+	if (!config) {
+		ret = -ENOMEM;
+		goto exit;
+	}
+
+	config->nr_gpios = of_gpio_named_count(np, "gpios");
+	config->gpios = kcalloc(config->nr_gpios, sizeof(struct gpio),
+				GFP_KERNEL);
+	if (!config->gpios) {
+		ret = -ENOMEM;
+		goto exit_free_config;
+	}
+
+	for (i = 0; i < config->nr_gpios; i++) {
+		int gpio = of_get_named_gpio(np, "gpios", i);
+
+		config->gpios[i].gpio = gpio;
+		config->gpios[i].flags = GPIOF_DIR_OUT;
+	}
+
+	config->supply_name =
+		kstrdup(of_get_property(np, "regulator-name", NULL),
+			GFP_KERNEL);
+	of_property_read_u32(np, "startup-delay", &config->startup_delay);
+
+	if (of_get_property(np, "enable-high", NULL))
+		config->enable_high = 1;
+	if (of_get_property(np, "enabled-at-boot", NULL))
+		config->enabled_at_boot = 1;
+	if (of_get_property(np, "regulator-type-current", NULL))
+		config->type = REGULATOR_CURRENT;
+	if (of_get_property(np, "regulator-type-voltage", NULL))
+		config->type = REGULATOR_VOLTAGE;
+
+	states = of_find_node_by_name(np, "states");
+
+	if (states) {
+		struct device_node *child = NULL;
+		while ((child = of_get_next_child(states, child)))
+			config->nr_states++;
+
+		config->states = kcalloc(config->nr_states,
+					 sizeof(struct regulator_state),
+					 GFP_KERNEL);
+		if (!config->states) {
+			ret = -ENOMEM;
+			goto exit_free_gpios;
+		}
+
+		i = 0;
+		child = NULL;
+		while ((child = of_get_next_child(states, child))) {
+			u32 value, gpios;
+
+			of_property_read_u32(child, "value", &value);
+			of_property_read_u32(child, "gpios", &gpios);
+
+			config->states[i].value = value;
+			config->states[i].gpios = gpios;
+
+			i++;
+		}
+	}
+
+	config->init_data = of_get_regulator_init_data(&pdev->dev, np);
+
+	pdev->dev.platform_data = config;
+
+	return 0;
+
+exit_free_gpios:
+	kfree(config->gpios);
+exit_free_config:
+	kfree(config);
+exit:
+	return ret;
+}
+#else
+static int gpio_regulator_probe_dt(struct platform_device *dev)
+{
+	return 0;
+}
+#endif
+
 static int __devinit gpio_regulator_probe(struct platform_device *pdev)
 {
-	struct gpio_regulator_config *config = pdev->dev.platform_data;
+	struct gpio_regulator_config *config;
 	struct gpio_regulator_data *drvdata;
 	struct regulator_config cfg = { };
 	int ptr, ret, state;
 
+	ret = gpio_regulator_probe_dt(pdev);
+	if (ret < 0)
+		return ret;
+
+	config = pdev->dev.platform_data;
+	if (!config) {
+		dev_err(&pdev->dev, "Platform data missing\n");
+		return -EINVAL;
+	}
+
 	drvdata = devm_kzalloc(&pdev->dev, sizeof(struct gpio_regulator_data),
 			       GFP_KERNEL);
 	if (drvdata == NULL) {
@@ -276,6 +391,7 @@ static struct platform_driver gpio_regulator_driver = {
 	.driver		= {
 		.name		= "gpio-regulator",
 		.owner		= THIS_MODULE,
+		.of_match_table	= of_match_ptr(gpio_regulator_dt_ids),
 	},
 };
 
-- 
1.7.11.4


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH v2] regulator: gpio-regulator: add DT bindings
  2012-09-10 15:03 [PATCH v2] regulator: gpio-regulator: add DT bindings Daniel Mack
@ 2012-09-10 19:40 ` Stephen Warren
  2012-09-10 23:41   ` Mark Brown
  2012-09-12  8:57   ` Daniel Mack
  0 siblings, 2 replies; 5+ messages in thread
From: Stephen Warren @ 2012-09-10 19:40 UTC (permalink / raw)
  To: Daniel Mack; +Cc: devicetree-discuss, lrg, broonie, linux-kernel

On 09/10/2012 09:03 AM, Daniel Mack wrote:
> Add DT bindings for the gpio-regulator driver and some documentation on
> how to use it.

> +++ b/Documentation/devicetree/bindings/regulator/gpio-regulator.txt
> @@ -0,0 +1,58 @@
> +Device tree bindings for GPIO controlled voltages
> +
> +Voltage or current regulators on boards that are controlled by GPIOs can
> +be used by the gpio-regulator driver.
> +
> +Required properties:
> +
> + - "compatible":	must be set to "gpio-regulator"
> + - "regulator-name": 	must be set to a string describing the name of this
> +			regulator.

I'd expect the "gpios" property to be listed here.

> +Optional properties:
> +
> + - "startup-delay":		Start-up time in microseconds
> + - "enable-high":		Polarity of enable GPIO. Active high if
> +				defined, otherwise active low

fixed-regulator.txt already has an "enable-active-high" property; it'd
be nice to be consistent.

> + - "enabled-at-boot":		If set, the regulator has been enabled at boot
> +				time

Isn't that regulator-boot-on, as defined in regulator.txt that you
mentioned?

> + - "regulator-type-voltage":	The regulator controls a voltage
> + - "regulator-type-current":	The regulator controls a current

I wonder if it'd be better to differentiate this using different
compatible values instead?

> + - "states":			An array of possible states, describing the
> +				GPIO states to reach a given value
> +	- "value":		The value of the state, in microvolts or
> +				microamperes

A name like "microvolts", "voltage", "microamps", or "current" might be
more descriptive here.

> +	- "gpios":		bitfield of gpio target-states for the value
> +				The n-th bit in the bitfield describes the
> +				state of the n-th GPIO from the gpios-array

"gpios" sounds like the name of a property that defines which GPIOs are
used, rather than the value of those GPIOs. Perhaps "gpio-values" instead?

Actually, I wonder if we really even need to represent that values
explicitly; rather than have a big set of nodes, perhaps you can instead
have a single property that lists the voltage (or current) that each
combination of GPIO values gives; something like:

reg_gpio {
    ...
    gpios = <&ggpio 23 0 &gpio 24 0>;
    voltages = <0 1000000 2000000 3000000>;
};

(As inspiration for that, I looked at
Documentation/devicetree/bindings/net/mdio-mux-gpio.txt which doesn't
have a property defining the value of the GPIOs for each combination,
but rather a node per valid combination).

Perhaps represent and invalid GPIO combination with 0xffffffff?

> +Also, all properties described in
> +Documentation/devicetree/bindings/regulator/regulator.txt are supported as
> +well.
> +
> +Example:
> +
> +	reg_gpio {
> +		compatible = "gpio-regulator";
> +		regulator-name = "voltage";
> +		regulator-enable-high;
> +		regulator-type-voltage;
> +		regulator-min-microvolt = <3300000>;
> +		regulator-max-microvolt = <3300000>;
> +		regulator-always-on;
> +
> +		gpios = <&gpio 23 0>;
> +
> +		states {
> +			state-on {
> +				value = <3300000>;
> +				gpios = <0x1>;
> +			};
> +
> +			state-off {
> +				value = <0>;
> +				gpios = <0x0>;
> +			};
> +		};
> +	};

That particular example only has on/off states, and so might be better
covered using the existing fixed-regulator, with optional GPIO control.
Perhaps an example using 2 GPIOs for 4 voltage states would be more useful?

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH v2] regulator: gpio-regulator: add DT bindings
  2012-09-10 19:40 ` Stephen Warren
@ 2012-09-10 23:41   ` Mark Brown
  2012-09-12  8:57   ` Daniel Mack
  1 sibling, 0 replies; 5+ messages in thread
From: Mark Brown @ 2012-09-10 23:41 UTC (permalink / raw)
  To: Stephen Warren; +Cc: Daniel Mack, devicetree-discuss, lrg, linux-kernel

On Mon, Sep 10, 2012 at 01:40:36PM -0600, Stephen Warren wrote:
> On 09/10/2012 09:03 AM, Daniel Mack wrote:

> > + - "enabled-at-boot":		If set, the regulator has been enabled at boot
> > +				time

> Isn't that regulator-boot-on, as defined in regulator.txt that you
> mentioned?

It's slightly different due to our unfortunate inability to support
GPIO readback for output GPIOs - this means the regualtor is enabled at
boot and the driver should use that to bootstrap state, the core one
means the regulator should be turned on at boot.  The latter would force
the regulator to be be enabled during boot.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH v2] regulator: gpio-regulator: add DT bindings
  2012-09-10 19:40 ` Stephen Warren
  2012-09-10 23:41   ` Mark Brown
@ 2012-09-12  8:57   ` Daniel Mack
  2012-09-12 18:47     ` Stephen Warren
  1 sibling, 1 reply; 5+ messages in thread
From: Daniel Mack @ 2012-09-12  8:57 UTC (permalink / raw)
  To: Stephen Warren; +Cc: devicetree-discuss, lrg, broonie, linux-kernel

Hi Stephen,

On 10.09.2012 21:40, Stephen Warren wrote:
> On 09/10/2012 09:03 AM, Daniel Mack wrote:
>> Add DT bindings for the gpio-regulator driver and some documentation on
>> how to use it.
> 
>> +++ b/Documentation/devicetree/bindings/regulator/gpio-regulator.txt
>> @@ -0,0 +1,58 @@
>> +Device tree bindings for GPIO controlled voltages
>> +
>> +Voltage or current regulators on boards that are controlled by GPIOs can
>> +be used by the gpio-regulator driver.
>> +
>> +Required properties:
>> +
>> + - "compatible":	must be set to "gpio-regulator"
>> + - "regulator-name": 	must be set to a string describing the name of this
>> +			regulator.
> 
> I'd expect the "gpios" property to be listed here.

Yes, I'll add that.

> 
>> +Optional properties:
>> +
>> + - "startup-delay":		Start-up time in microseconds
>> + - "enable-high":		Polarity of enable GPIO. Active high if
>> +				defined, otherwise active low
> 
> fixed-regulator.txt already has an "enable-active-high" property; it'd
> be nice to be consistent.

Ok.

>> + - "enabled-at-boot":		If set, the regulator has been enabled at boot
>> +				time
> 
> Isn't that regulator-boot-on, as defined in regulator.txt that you
> mentioned?
> 
>> + - "regulator-type-voltage":	The regulator controls a voltage
>> + - "regulator-type-current":	The regulator controls a current
> 
> I wonder if it'd be better to differentiate this using different
> compatible values instead?

I like this idea. Will make that "gpio-voltage-regulator" and
"gpio-current-regulator".

> 
>> + - "states":			An array of possible states, describing the
>> +				GPIO states to reach a given value
>> +	- "value":		The value of the state, in microvolts or
>> +				microamperes
> 
> A name like "microvolts", "voltage", "microamps", or "current" might be
> more descriptive here.

I'm for "microvolts" and "microamperes". Will change. I just thought it
might be good to keep as close to the struct member names for making it
easiest for users to convert over to DT, but you're right, a more
descriptive property name is certainly better.

>> +	- "gpios":		bitfield of gpio target-states for the value
>> +				The n-th bit in the bitfield describes the
>> +				state of the n-th GPIO from the gpios-array
> 
> "gpios" sounds like the name of a property that defines which GPIOs are
> used, rather than the value of those GPIOs. Perhaps "gpio-values" instead?
> 
> Actually, I wonder if we really even need to represent that values
> explicitly; rather than have a big set of nodes, perhaps you can instead
> have a single property that lists the voltage (or current) that each
> combination of GPIO values gives; something like:
> 
> reg_gpio {
>     ...
>     gpios = <&ggpio 23 0 &gpio 24 0>;
>     voltages = <0 1000000 2000000 3000000>;
> };
> 
> (As inspiration for that, I looked at
> Documentation/devicetree/bindings/net/mdio-mux-gpio.txt which doesn't
> have a property defining the value of the GPIOs for each combination,
> but rather a node per valid combination).
> 
> Perhaps represent and invalid GPIO combination with 0xffffffff?

Sorry, I don't follow you on this one. How would you specify the
voltages that way? And The driver allows for arbitrary GPIO patterns to
be set on the GPIOs in order to reach a specific voltage. Could you give
me another example how that would look like in your approach?

Once that topic is agreed on, I'll send out a new version.

>> +Also, all properties described in
>> +Documentation/devicetree/bindings/regulator/regulator.txt are supported as
>> +well.
>> +
>> +Example:
>> +
>> +	reg_gpio {
>> +		compatible = "gpio-regulator";
>> +		regulator-name = "voltage";
>> +		regulator-enable-high;
>> +		regulator-type-voltage;
>> +		regulator-min-microvolt = <3300000>;
>> +		regulator-max-microvolt = <3300000>;
>> +		regulator-always-on;
>> +
>> +		gpios = <&gpio 23 0>;
>> +
>> +		states {
>> +			state-on {
>> +				value = <3300000>;
>> +				gpios = <0x1>;
>> +			};
>> +
>> +			state-off {
>> +				value = <0>;
>> +				gpios = <0x0>;
>> +			};
>> +		};
>> +	};
> 
> That particular example only has on/off states, and so might be better
> covered using the existing fixed-regulator, with optional GPIO control.
> Perhaps an example using 2 GPIOs for 4 voltage states would be more useful?

Yes, that's true. Funny thing is - I forgot about the fixed-regulator's
feature to control GPIOs and use the driver as in the example that I
provided :) Anyway, I'll finish the conversion of this one now, as I'm
on it.


Many thanks for your review,

Daniel




^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH v2] regulator: gpio-regulator: add DT bindings
  2012-09-12  8:57   ` Daniel Mack
@ 2012-09-12 18:47     ` Stephen Warren
  0 siblings, 0 replies; 5+ messages in thread
From: Stephen Warren @ 2012-09-12 18:47 UTC (permalink / raw)
  To: Daniel Mack; +Cc: devicetree-discuss, lrg, broonie, linux-kernel

On 09/12/2012 02:57 AM, Daniel Mack wrote:
> On 10.09.2012 21:40, Stephen Warren wrote:
>> On 09/10/2012 09:03 AM, Daniel Mack wrote:
>>> Add DT bindings for the gpio-regulator driver and some documentation on
>>> how to use it.
...
>>> +++ b/Documentation/devicetree/bindings/regulator/gpio-regulator.txt
...
>>> +	- "gpios":		bitfield of gpio target-states for the value
>>> +				The n-th bit in the bitfield describes the
>>> +				state of the n-th GPIO from the gpios-array
>>
>> "gpios" sounds like the name of a property that defines which GPIOs are
>> used, rather than the value of those GPIOs. Perhaps "gpio-values" instead?
>>
>> Actually, I wonder if we really even need to represent that values
>> explicitly; rather than have a big set of nodes, perhaps you can instead
>> have a single property that lists the voltage (or current) that each
>> combination of GPIO values gives; something like:
>>
>> reg_gpio {
>>     ...
>>     gpios = <&ggpio 23 0 &gpio 24 0>;
>>     voltages = <0 1000000 2000000 3000000>;
>> };
>>
>> (As inspiration for that, I looked at
>> Documentation/devicetree/bindings/net/mdio-mux-gpio.txt which doesn't
>> have a property defining the value of the GPIOs for each combination,
>> but rather a node per valid combination).
>>
>> Perhaps represent and invalid GPIO combination with 0xffffffff?
> 
> Sorry, I don't follow you on this one. How would you specify the
> voltages that way? And The driver allows for arbitrary GPIO patterns to
> be set on the GPIOs in order to reach a specific voltage. Could you give
> me another example how that would look like in your approach?
> 
> Once that topic is agreed on, I'll send out a new version.

The idea is that you treat the GPIOs as an array of bits. so, two
entries in the gpios property and you've got two bits in your values.
Use that value as the index into the "voltages" property. For each
combination of GPIO values, you have an entry in "voltages" that
indicates what voltage will be produced. This is much more compact than
having a node per setting, but perhaps is more wordy if the subset of
legal GPIO value is much more sparse than all possible 2^n GPIO values.

Put another way,

GPIO0=0, GPIO1=0 -> index 0 -> voltage 0 in the example above
GPIO0=0, GPIO1=1 -> index 1 -> voltage 1000000 in the example above
GPIO0=1, GPIO1=0 -> index 2 -> voltage 2000000 in the example above
GPIO0=1, GPIO1=1 -> index 3 -> voltage 3000000 in the example above

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2012-09-12 18:47 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-09-10 15:03 [PATCH v2] regulator: gpio-regulator: add DT bindings Daniel Mack
2012-09-10 19:40 ` Stephen Warren
2012-09-10 23:41   ` Mark Brown
2012-09-12  8:57   ` Daniel Mack
2012-09-12 18:47     ` Stephen Warren

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).