All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/6] regulator: Fix WM831x regulator ID lookups for multiple WM831xs
@ 2011-07-25 21:20 Mark Brown
  2011-07-25 21:20 ` [PATCH 2/6] regulator: Fix WM831x DCDC DVS VSEL bootstrapping Mark Brown
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: Mark Brown @ 2011-07-25 21:20 UTC (permalink / raw)
  To: Liam Girdwood; +Cc: linux-kernel, patches, Mark Brown

With multiple wm831x devices the device IDs used for the regulators will
not always be contiguous so simply taking the modulus is not sufficient
to look up the ID, we need to reverse the way the ID is generated.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
---
 drivers/regulator/wm831x-dcdc.c |   16 ++++++++++++++--
 drivers/regulator/wm831x-ldo.c  |   25 ++++++++++++++++++++++---
 2 files changed, 36 insertions(+), 5 deletions(-)

diff --git a/drivers/regulator/wm831x-dcdc.c b/drivers/regulator/wm831x-dcdc.c
index a0982e8..0c7a9d5 100644
--- a/drivers/regulator/wm831x-dcdc.c
+++ b/drivers/regulator/wm831x-dcdc.c
@@ -504,11 +504,17 @@ static __devinit int wm831x_buckv_probe(struct platform_device *pdev)
 {
 	struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
 	struct wm831x_pdata *pdata = wm831x->dev->platform_data;
-	int id = pdev->id % ARRAY_SIZE(pdata->dcdc);
+	int id;
 	struct wm831x_dcdc *dcdc;
 	struct resource *res;
 	int ret, irq;
 
+	if (pdata && pdata->wm831x_num)
+		id = (pdata->wm831x_num * 10) + 1;
+	else
+		id = 0;
+	id = pdev->id - id;
+
 	dev_dbg(&pdev->dev, "Probing DCDC%d\n", id + 1);
 
 	if (pdata == NULL || pdata->dcdc[id] == NULL)
@@ -709,11 +715,17 @@ static __devinit int wm831x_buckp_probe(struct platform_device *pdev)
 {
 	struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
 	struct wm831x_pdata *pdata = wm831x->dev->platform_data;
-	int id = pdev->id % ARRAY_SIZE(pdata->dcdc);
+	int id;
 	struct wm831x_dcdc *dcdc;
 	struct resource *res;
 	int ret, irq;
 
+	if (pdata && pdata->wm831x_num)
+		id = (pdata->wm831x_num * 10) + 1;
+	else
+		id = 0;
+	id = pdev->id - id;
+
 	dev_dbg(&pdev->dev, "Probing DCDC%d\n", id + 1);
 
 	if (pdata == NULL || pdata->dcdc[id] == NULL)
diff --git a/drivers/regulator/wm831x-ldo.c b/drivers/regulator/wm831x-ldo.c
index 2220cf8..6709710 100644
--- a/drivers/regulator/wm831x-ldo.c
+++ b/drivers/regulator/wm831x-ldo.c
@@ -310,11 +310,17 @@ static __devinit int wm831x_gp_ldo_probe(struct platform_device *pdev)
 {
 	struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
 	struct wm831x_pdata *pdata = wm831x->dev->platform_data;
-	int id = pdev->id % ARRAY_SIZE(pdata->ldo);
+	int id;
 	struct wm831x_ldo *ldo;
 	struct resource *res;
 	int ret, irq;
 
+	if (pdata && pdata->wm831x_num)
+		id = (pdata->wm831x_num * 10) + 1;
+	else
+		id = 0;
+	id = pdev->id - id;
+
 	dev_dbg(&pdev->dev, "Probing LDO%d\n", id + 1);
 
 	if (pdata == NULL || pdata->ldo[id] == NULL)
@@ -574,11 +580,17 @@ static __devinit int wm831x_aldo_probe(struct platform_device *pdev)
 {
 	struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
 	struct wm831x_pdata *pdata = wm831x->dev->platform_data;
-	int id = pdev->id % ARRAY_SIZE(pdata->ldo);
+	int id;
 	struct wm831x_ldo *ldo;
 	struct resource *res;
 	int ret, irq;
 
+	if (pdata && pdata->wm831x_num)
+		id = (pdata->wm831x_num * 10) + 1;
+	else
+		id = 0;
+	id = pdev->id - id;
+
 	dev_dbg(&pdev->dev, "Probing LDO%d\n", id + 1);
 
 	if (pdata == NULL || pdata->ldo[id] == NULL)
@@ -764,11 +776,18 @@ static __devinit int wm831x_alive_ldo_probe(struct platform_device *pdev)
 {
 	struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
 	struct wm831x_pdata *pdata = wm831x->dev->platform_data;
-	int id = pdev->id % ARRAY_SIZE(pdata->ldo);
+	int id;
 	struct wm831x_ldo *ldo;
 	struct resource *res;
 	int ret;
 
+	if (pdata && pdata->wm831x_num)
+		id = (pdata->wm831x_num * 10) + 1;
+	else
+		id = 0;
+	id = pdev->id - id;
+
+
 	dev_dbg(&pdev->dev, "Probing LDO%d\n", id + 1);
 
 	if (pdata == NULL || pdata->ldo[id] == NULL)
-- 
1.7.5.4


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

* [PATCH 2/6] regulator: Fix WM831x DCDC DVS VSEL bootstrapping
  2011-07-25 21:20 [PATCH 1/6] regulator: Fix WM831x regulator ID lookups for multiple WM831xs Mark Brown
@ 2011-07-25 21:20 ` Mark Brown
  2011-07-25 21:20 ` [PATCH 3/6] regulator: Add EPEs to the MODULE_ALIAS() for wm831x-dcdc Mark Brown
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Mark Brown @ 2011-07-25 21:20 UTC (permalink / raw)
  To: Liam Girdwood; +Cc: linux-kernel, patches, Mark Brown

Read our initial VSEL from the correct register.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
---
 drivers/regulator/wm831x-dcdc.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/regulator/wm831x-dcdc.c b/drivers/regulator/wm831x-dcdc.c
index 0c7a9d5..8a4fdc3 100644
--- a/drivers/regulator/wm831x-dcdc.c
+++ b/drivers/regulator/wm831x-dcdc.c
@@ -551,7 +551,7 @@ static __devinit int wm831x_buckv_probe(struct platform_device *pdev)
 	}
 	dcdc->on_vsel = ret & WM831X_DC1_ON_VSEL_MASK;
 
-	ret = wm831x_reg_read(wm831x, dcdc->base + WM831X_DCDC_ON_CONFIG);
+	ret = wm831x_reg_read(wm831x, dcdc->base + WM831X_DCDC_DVS_CONTROL);
 	if (ret < 0) {
 		dev_err(wm831x->dev, "Failed to read DVS VSEL: %d\n", ret);
 		goto err;
-- 
1.7.5.4


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

* [PATCH 3/6] regulator: Add EPEs to the MODULE_ALIAS() for wm831x-dcdc
  2011-07-25 21:20 [PATCH 1/6] regulator: Fix WM831x regulator ID lookups for multiple WM831xs Mark Brown
  2011-07-25 21:20 ` [PATCH 2/6] regulator: Fix WM831x DCDC DVS VSEL bootstrapping Mark Brown
@ 2011-07-25 21:20 ` Mark Brown
  2011-07-25 21:20 ` [PATCH 4/6] regulator: Set up GPIO for WM831x VSEL before enabling VSEL mode Mark Brown
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Mark Brown @ 2011-07-25 21:20 UTC (permalink / raw)
  To: Liam Girdwood; +Cc: linux-kernel, patches, Mark Brown

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
---
 drivers/regulator/wm831x-dcdc.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/drivers/regulator/wm831x-dcdc.c b/drivers/regulator/wm831x-dcdc.c
index 8a4fdc3..2ee4823 100644
--- a/drivers/regulator/wm831x-dcdc.c
+++ b/drivers/regulator/wm831x-dcdc.c
@@ -1058,3 +1058,4 @@ MODULE_DESCRIPTION("WM831x DC-DC convertor driver");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("platform:wm831x-buckv");
 MODULE_ALIAS("platform:wm831x-buckp");
+MODULE_ALIAS("platform:wm831x-epe");
-- 
1.7.5.4


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

* [PATCH 4/6] regulator: Set up GPIO for WM831x VSEL before enabling VSEL mode
  2011-07-25 21:20 [PATCH 1/6] regulator: Fix WM831x regulator ID lookups for multiple WM831xs Mark Brown
  2011-07-25 21:20 ` [PATCH 2/6] regulator: Fix WM831x DCDC DVS VSEL bootstrapping Mark Brown
  2011-07-25 21:20 ` [PATCH 3/6] regulator: Add EPEs to the MODULE_ALIAS() for wm831x-dcdc Mark Brown
@ 2011-07-25 21:20 ` Mark Brown
  2011-07-25 21:20 ` [PATCH 5/6] regulator: Bootstrap wm831x DVS VSEL value from ON VSEL if not already set Mark Brown
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Mark Brown @ 2011-07-25 21:20 UTC (permalink / raw)
  To: Liam Girdwood; +Cc: linux-kernel, patches, Mark Brown

If the VSEL is not in use prior to us starting up then we need to make
sure we initialise the GPIO before we push the DVS control to being done
by the GPIO.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
---
 drivers/regulator/wm831x-dcdc.c |   41 +++++++++++++++++++--------------------
 1 files changed, 20 insertions(+), 21 deletions(-)

diff --git a/drivers/regulator/wm831x-dcdc.c b/drivers/regulator/wm831x-dcdc.c
index 2ee4823..95249f7 100644
--- a/drivers/regulator/wm831x-dcdc.c
+++ b/drivers/regulator/wm831x-dcdc.c
@@ -456,27 +456,6 @@ static __devinit void wm831x_buckv_dvs_init(struct wm831x_dcdc *dcdc,
 	if (!pdata || !pdata->dvs_gpio)
 		return;
 
-	switch (pdata->dvs_control_src) {
-	case 1:
-		ctrl = 2 << WM831X_DC1_DVS_SRC_SHIFT;
-		break;
-	case 2:
-		ctrl = 3 << WM831X_DC1_DVS_SRC_SHIFT;
-		break;
-	default:
-		dev_err(wm831x->dev, "Invalid DVS control source %d for %s\n",
-			pdata->dvs_control_src, dcdc->name);
-		return;
-	}
-
-	ret = wm831x_set_bits(wm831x, dcdc->base + WM831X_DCDC_DVS_CONTROL,
-			      WM831X_DC1_DVS_SRC_MASK, ctrl);
-	if (ret < 0) {
-		dev_err(wm831x->dev, "Failed to set %s DVS source: %d\n",
-			dcdc->name, ret);
-		return;
-	}
-
 	ret = gpio_request(pdata->dvs_gpio, "DCDC DVS");
 	if (ret < 0) {
 		dev_err(wm831x->dev, "Failed to get %s DVS GPIO: %d\n",
@@ -498,6 +477,26 @@ static __devinit void wm831x_buckv_dvs_init(struct wm831x_dcdc *dcdc,
 	}
 
 	dcdc->dvs_gpio = pdata->dvs_gpio;
+
+	switch (pdata->dvs_control_src) {
+	case 1:
+		ctrl = 2 << WM831X_DC1_DVS_SRC_SHIFT;
+		break;
+	case 2:
+		ctrl = 3 << WM831X_DC1_DVS_SRC_SHIFT;
+		break;
+	default:
+		dev_err(wm831x->dev, "Invalid DVS control source %d for %s\n",
+			pdata->dvs_control_src, dcdc->name);
+		return;
+	}
+
+	ret = wm831x_set_bits(wm831x, dcdc->base + WM831X_DCDC_DVS_CONTROL,
+			      WM831X_DC1_DVS_SRC_MASK, ctrl);
+	if (ret < 0) {
+		dev_err(wm831x->dev, "Failed to set %s DVS source: %d\n",
+			dcdc->name, ret);
+	}
 }
 
 static __devinit int wm831x_buckv_probe(struct platform_device *pdev)
-- 
1.7.5.4


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

* [PATCH 5/6] regulator: Bootstrap wm831x DVS VSEL value from ON VSEL if not already set
  2011-07-25 21:20 [PATCH 1/6] regulator: Fix WM831x regulator ID lookups for multiple WM831xs Mark Brown
                   ` (2 preceding siblings ...)
  2011-07-25 21:20 ` [PATCH 4/6] regulator: Set up GPIO for WM831x VSEL before enabling VSEL mode Mark Brown
@ 2011-07-25 21:20 ` Mark Brown
  2011-07-25 21:20 ` [PATCH 6/6] regulator: Improve WM831x DVS VSEL selection algorithm Mark Brown
  2011-07-28  9:30 ` [PATCH 1/6] regulator: Fix WM831x regulator ID lookups for multiple WM831xs Liam Girdwood
  5 siblings, 0 replies; 7+ messages in thread
From: Mark Brown @ 2011-07-25 21:20 UTC (permalink / raw)
  To: Liam Girdwood; +Cc: linux-kernel, patches, Mark Brown

If we don't have a DVS VSEL value already set when we start up then start
it off with the value currently being used for ON.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
---
 drivers/regulator/wm831x-dcdc.c |   14 ++++++++++++++
 1 files changed, 14 insertions(+), 0 deletions(-)

diff --git a/drivers/regulator/wm831x-dcdc.c b/drivers/regulator/wm831x-dcdc.c
index 95249f7..2c5d54b 100644
--- a/drivers/regulator/wm831x-dcdc.c
+++ b/drivers/regulator/wm831x-dcdc.c
@@ -491,6 +491,20 @@ static __devinit void wm831x_buckv_dvs_init(struct wm831x_dcdc *dcdc,
 		return;
 	}
 
+	/* If DVS_VSEL is set to the minimum value then raise it to ON_VSEL
+	 * to make bootstrapping a bit smoother.
+	 */
+	if (!dcdc->dvs_vsel) {
+		ret = wm831x_set_bits(wm831x,
+				      dcdc->base + WM831X_DCDC_DVS_CONTROL,
+				      WM831X_DC1_DVS_VSEL_MASK, dcdc->on_vsel);
+		if (ret == 0)
+			dcdc->dvs_vsel = dcdc->on_vsel;
+		else
+			dev_warn(wm831x->dev, "Failed to set DVS_VSEL: %d\n",
+				 ret);
+	}
+
 	ret = wm831x_set_bits(wm831x, dcdc->base + WM831X_DCDC_DVS_CONTROL,
 			      WM831X_DC1_DVS_SRC_MASK, ctrl);
 	if (ret < 0) {
-- 
1.7.5.4


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

* [PATCH 6/6] regulator: Improve WM831x DVS VSEL selection algorithm
  2011-07-25 21:20 [PATCH 1/6] regulator: Fix WM831x regulator ID lookups for multiple WM831xs Mark Brown
                   ` (3 preceding siblings ...)
  2011-07-25 21:20 ` [PATCH 5/6] regulator: Bootstrap wm831x DVS VSEL value from ON VSEL if not already set Mark Brown
@ 2011-07-25 21:20 ` Mark Brown
  2011-07-28  9:30 ` [PATCH 1/6] regulator: Fix WM831x regulator ID lookups for multiple WM831xs Liam Girdwood
  5 siblings, 0 replies; 7+ messages in thread
From: Mark Brown @ 2011-07-25 21:20 UTC (permalink / raw)
  To: Liam Girdwood; +Cc: linux-kernel, patches, Mark Brown

Rather than using the maximum voltage we get passed to select the DVS
voltage to use remember the highest voltage we've ever seen. This improves
how the driver works when the consumer permits higher voltages than it
will ever selects in order to support the widest possible voltage range.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
---
 drivers/regulator/wm831x-dcdc.c |   52 +++++++++++---------------------------
 1 files changed, 15 insertions(+), 37 deletions(-)

diff --git a/drivers/regulator/wm831x-dcdc.c b/drivers/regulator/wm831x-dcdc.c
index 2c5d54b..bd3531d 100644
--- a/drivers/regulator/wm831x-dcdc.c
+++ b/drivers/regulator/wm831x-dcdc.c
@@ -267,23 +267,6 @@ static int wm831x_buckv_select_min_voltage(struct regulator_dev *rdev,
 	return vsel;
 }
 
-static int wm831x_buckv_select_max_voltage(struct regulator_dev *rdev,
-					   int min_uV, int max_uV)
-{
-	u16 vsel;
-
-	if (max_uV < 600000 || max_uV > 1800000)
-		return -EINVAL;
-
-	vsel = ((max_uV - 600000) / 12500) + 8;
-
-	if (wm831x_buckv_list_voltage(rdev, vsel) < min_uV ||
-	    wm831x_buckv_list_voltage(rdev, vsel) < max_uV)
-		return -EINVAL;
-
-	return vsel;
-}
-
 static int wm831x_buckv_set_dvs(struct regulator_dev *rdev, int state)
 {
 	struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
@@ -338,28 +321,23 @@ static int wm831x_buckv_set_voltage(struct regulator_dev *rdev,
 	if (ret < 0)
 		return ret;
 
-	/* Set the high voltage as the DVS voltage.  This is optimised
-	 * for CPUfreq usage, most processors will keep the maximum
-	 * voltage constant and lower the minimum with the frequency. */
-	vsel = wm831x_buckv_select_max_voltage(rdev, min_uV, max_uV);
-	if (vsel < 0) {
-		/* This should never happen - at worst the same vsel
-		 * should be chosen */
-		WARN_ON(vsel < 0);
-		return 0;
+	/*
+	 * If this VSEL is higher than the last one we've seen then
+	 * remember it as the DVS VSEL.  This is optimised for CPUfreq
+	 * usage where we want to get to the highest voltage very
+	 * quickly.
+	 */
+	if (vsel > dcdc->dvs_vsel) {
+		ret = wm831x_set_bits(wm831x, dvs_reg,
+				      WM831X_DC1_DVS_VSEL_MASK,
+				      dcdc->dvs_vsel);
+		if (ret == 0)
+			dcdc->dvs_vsel = vsel;
+		else
+			dev_warn(wm831x->dev,
+				 "Failed to set DCDC DVS VSEL: %d\n", ret);
 	}
 
-	/* Don't bother if it's the same VSEL we're already using */
-	if (vsel == dcdc->on_vsel)
-		return 0;
-
-	ret = wm831x_set_bits(wm831x, dvs_reg, WM831X_DC1_DVS_VSEL_MASK, vsel);
-	if (ret == 0)
-		dcdc->dvs_vsel = vsel;
-	else
-		dev_warn(wm831x->dev, "Failed to set DCDC DVS VSEL: %d\n",
-			 ret);
-
 	return 0;
 }
 
-- 
1.7.5.4


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

* Re: [PATCH 1/6] regulator: Fix WM831x regulator ID lookups for multiple WM831xs
  2011-07-25 21:20 [PATCH 1/6] regulator: Fix WM831x regulator ID lookups for multiple WM831xs Mark Brown
                   ` (4 preceding siblings ...)
  2011-07-25 21:20 ` [PATCH 6/6] regulator: Improve WM831x DVS VSEL selection algorithm Mark Brown
@ 2011-07-28  9:30 ` Liam Girdwood
  5 siblings, 0 replies; 7+ messages in thread
From: Liam Girdwood @ 2011-07-28  9:30 UTC (permalink / raw)
  To: Mark Brown; +Cc: Liam Girdwood, linux-kernel, patches

On Mon, 2011-07-25 at 22:20 +0100, Mark Brown wrote:
> With multiple wm831x devices the device IDs used for the regulators will
> not always be contiguous so simply taking the modulus is not sufficient
> to look up the ID, we need to reverse the way the ID is generated.
> 
> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
> ---
>  drivers/regulator/wm831x-dcdc.c |   16 ++++++++++++++--
>  drivers/regulator/wm831x-ldo.c  |   25 ++++++++++++++++++++++---
>  2 files changed, 36 insertions(+), 5 deletions(-)
> 

All Applied

Thanks

Liam


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

end of thread, other threads:[~2011-07-28  9:30 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-07-25 21:20 [PATCH 1/6] regulator: Fix WM831x regulator ID lookups for multiple WM831xs Mark Brown
2011-07-25 21:20 ` [PATCH 2/6] regulator: Fix WM831x DCDC DVS VSEL bootstrapping Mark Brown
2011-07-25 21:20 ` [PATCH 3/6] regulator: Add EPEs to the MODULE_ALIAS() for wm831x-dcdc Mark Brown
2011-07-25 21:20 ` [PATCH 4/6] regulator: Set up GPIO for WM831x VSEL before enabling VSEL mode Mark Brown
2011-07-25 21:20 ` [PATCH 5/6] regulator: Bootstrap wm831x DVS VSEL value from ON VSEL if not already set Mark Brown
2011-07-25 21:20 ` [PATCH 6/6] regulator: Improve WM831x DVS VSEL selection algorithm Mark Brown
2011-07-28  9:30 ` [PATCH 1/6] regulator: Fix WM831x regulator ID lookups for multiple WM831xs Liam Girdwood

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.