diff mbox

[1/2] regulator: gpio-regulator: Allow use of GPIO controlled regulators though DT

Message ID 1350307020-5910-1-git-send-email-lee.jones@linaro.org (mailing list archive)
State New, archived
Headers show

Commit Message

Lee Jones Oct. 15, 2012, 1:16 p.m. UTC
Here we provide the GPIO Regulator driver with Device Tree capability, so
that when a platform is booting with DT instead of platform data we can
still make full use of it.

Cc: Mark Brown <broonie@opensource.wolfsonmicro.com>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
---
 drivers/regulator/gpio-regulator.c |   94 ++++++++++++++++++++++++++++++++++++
 1 file changed, 94 insertions(+)

Comments

Mark Brown Oct. 16, 2012, 5:14 a.m. UTC | #1
On Mon, Oct 15, 2012 at 02:16:59PM +0100, Lee Jones wrote:
> Here we provide the GPIO Regulator driver with Device Tree capability, so
> that when a platform is booting with DT instead of platform data we can
> still make full use of it.

Not looked at the patch yet but patch 2 doesn't seem to have appeared?
Lee Jones Oct. 16, 2012, 7:29 a.m. UTC | #2
On Tue, 16 Oct 2012, Mark Brown wrote:

> On Mon, Oct 15, 2012 at 02:16:59PM +0100, Lee Jones wrote:
> > Here we provide the GPIO Regulator driver with Device Tree capability, so
> > that when a platform is booting with DT instead of platform data we can
> > still make full use of it.
> 
> Not looked at the patch yet but patch 2 doesn't seem to have appeared?

Has it arrived yet?

Arnd responded to it, so it hit the list.

Since Arnd's comments I've also fired v2 up - do you see it/them?
Mark Brown Oct. 16, 2012, 7:46 a.m. UTC | #3
On Tue, Oct 16, 2012 at 08:29:56AM +0100, Lee Jones wrote:
> On Tue, 16 Oct 2012, Mark Brown wrote:

> > Not looked at the patch yet but patch 2 doesn't seem to have appeared?

> Has it arrived yet?

> Arnd responded to it, so it hit the list.

> Since Arnd's comments I've also fired v2 up - do you see it/them?

Not in my inbox, I'm not looking at the list right now.
Lee Jones Oct. 16, 2012, 8:01 a.m. UTC | #4
On Tue, 16 Oct 2012, Mark Brown wrote:

> On Tue, Oct 16, 2012 at 08:29:56AM +0100, Lee Jones wrote:
> > On Tue, 16 Oct 2012, Mark Brown wrote:
> 
> > > Not looked at the patch yet but patch 2 doesn't seem to have appeared?
> 
> > Has it arrived yet?
> 
> > Arnd responded to it, so it hit the list.
> 
> > Since Arnd's comments I've also fired v2 up - do you see it/them?
> 
> Not in my inbox, I'm not looking at the list right now.

Strange, both emails had you in CC.

I'm assuming it's just the documentation patch you're missing.

Let me resend it as a single patch.
Mark Brown Oct. 17, 2012, 7:41 a.m. UTC | #5
On Tue, Oct 16, 2012 at 09:01:09AM +0100, Lee Jones wrote:

> I'm assuming it's just the documentation patch you're missing.

> Let me resend it as a single patch.

This should really be part of the patch adding the bindings...
Lee Jones Oct. 22, 2012, 9:13 a.m. UTC | #6
On Wed, 17 Oct 2012, Mark Brown wrote:

> On Tue, Oct 16, 2012 at 09:01:09AM +0100, Lee Jones wrote:
> 
> > I'm assuming it's just the documentation patch you're missing.
> 
> > Let me resend it as a single patch.
> 
> This should really be part of the patch adding the bindings...

Would you like me to send the patch-set again?
Mark Brown Oct. 22, 2012, 9:44 a.m. UTC | #7
On Mon, Oct 22, 2012 at 10:13:55AM +0100, Lee Jones wrote:
> On Wed, 17 Oct 2012, Mark Brown wrote:

> > This should really be part of the patch adding the bindings...

> Would you like me to send the patch-set again?

When I said I'd applied the patch that was what I meant.
diff mbox

Patch

diff --git a/drivers/regulator/gpio-regulator.c b/drivers/regulator/gpio-regulator.c
index 8b5944f..e467d0a 100644
--- a/drivers/regulator/gpio-regulator.c
+++ b/drivers/regulator/gpio-regulator.c
@@ -28,9 +28,12 @@ 
 #include <linux/platform_device.h>
 #include <linux/regulator/driver.h>
 #include <linux/regulator/machine.h>
+#include <linux/regulator/of_regulator.h>
 #include <linux/regulator/gpio-regulator.h>
 #include <linux/gpio.h>
 #include <linux/slab.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
 
 struct gpio_regulator_data {
 	struct regulator_desc desc;
@@ -129,6 +132,84 @@  static struct regulator_ops gpio_regulator_voltage_ops = {
 	.list_voltage = gpio_regulator_list_voltage,
 };
 
+struct gpio_regulator_config *
+of_get_gpio_regulator_config(struct device *dev, struct device_node *np)
+{
+	struct gpio_regulator_config *config;
+	struct property *prop;
+	const char *regtype;
+	int proplen, gpio, i;
+
+	config = devm_kzalloc(dev,
+			sizeof(struct gpio_regulator_config),
+			GFP_KERNEL);
+	if (!config)
+		return ERR_PTR(-ENOMEM);
+
+	config->init_data = of_get_regulator_init_data(dev, np);
+	if (!config->init_data)
+		return ERR_PTR(-EINVAL);
+
+	config->supply_name = config->init_data->constraints.name;
+
+	if (of_property_read_bool(np, "enable-active-high"))
+		config->enable_high = true;
+
+	if (of_property_read_bool(np, "enable-at-boot"))
+		config->enabled_at_boot = true;
+
+	of_property_read_u32(np, "startup-delay-us", &config->startup_delay);
+
+	config->enable_gpio = of_get_named_gpio(np, "enable-gpio", 0);
+
+	/* Fetch GPIOs. */
+	for (i = 0; ; i++)
+		if (of_get_named_gpio(np, "gpios", i) < 0)
+			break;
+	config->nr_gpios = i;
+
+	config->gpios = devm_kzalloc(dev,
+				sizeof(struct gpio) * config->nr_gpios,
+				GFP_KERNEL);
+	if (!config->gpios)
+		return ERR_PTR(-ENOMEM);
+
+	for (i = 0; config->nr_gpios; i++) {
+		gpio = of_get_named_gpio(np, "gpios", i);
+		if (gpio < 0)
+			break;
+		config->gpios[i].gpio = gpio;
+	}
+
+	/* Fetch states. */
+	prop = of_find_property(np, "states", NULL);
+	proplen = prop->length / sizeof(int);
+
+	config->states = devm_kzalloc(dev,
+				sizeof(struct gpio_regulator_state)
+				* (proplen / 2),
+				GFP_KERNEL);
+	if (!config->states)
+		return ERR_PTR(-ENOMEM);
+
+	for (i = 0; i < proplen / 2; i++) {
+		config->states[i].value =
+			be32_to_cpup((int *)prop->value + (i * 2));
+		config->states[i].gpios =
+			be32_to_cpup((int *)prop->value + (i * 2 + 1));
+	}
+	config->nr_states = i;
+
+	of_property_read_string(np, "regulator-type", &regtype);
+
+	if (!strncmp("voltage", regtype, 7))
+		config->type = REGULATOR_VOLTAGE;
+	else if (!strncmp("current", regtype, 7))
+		config->type = REGULATOR_CURRENT;
+
+	return config;
+}
+
 static struct regulator_ops gpio_regulator_current_ops = {
 	.get_current_limit = gpio_regulator_get_value,
 	.set_current_limit = gpio_regulator_set_current_limit,
@@ -137,10 +218,17 @@  static struct regulator_ops gpio_regulator_current_ops = {
 static int __devinit gpio_regulator_probe(struct platform_device *pdev)
 {
 	struct gpio_regulator_config *config = pdev->dev.platform_data;
+	struct device_node *np = pdev->dev.of_node;
 	struct gpio_regulator_data *drvdata;
 	struct regulator_config cfg = { };
 	int ptr, ret, state;
 
+	if (np) {
+		config = of_get_gpio_regulator_config(&pdev->dev, np);
+		if (IS_ERR(config))
+			return PTR_ERR(config);
+	}
+
 	drvdata = devm_kzalloc(&pdev->dev, sizeof(struct gpio_regulator_data),
 			       GFP_KERNEL);
 	if (drvdata == NULL) {
@@ -270,12 +358,18 @@  static int __devexit gpio_regulator_remove(struct platform_device *pdev)
 	return 0;
 }
 
+static const struct of_device_id regulator_gpio_of_match[] __devinitconst = {
+	{ .compatible = "regulator-gpio", },
+	{},
+};
+
 static struct platform_driver gpio_regulator_driver = {
 	.probe		= gpio_regulator_probe,
 	.remove		= __devexit_p(gpio_regulator_remove),
 	.driver		= {
 		.name		= "gpio-regulator",
 		.owner		= THIS_MODULE,
+		.of_match_table = regulator_gpio_of_match,
 	},
 };