All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/9] wm5110 Boot Fixups
@ 2015-04-08 15:56 Charles Keepax
  2015-04-08 15:56 ` [PATCH 1/9] mfd: arizona: Use devres to manage reset GPIO Charles Keepax
                   ` (8 more replies)
  0 siblings, 9 replies; 11+ messages in thread
From: Charles Keepax @ 2015-04-08 15:56 UTC (permalink / raw)
  To: lee.jones; +Cc: sameo, broonie, lgirdwood, patches, linux-kernel

Ok so I have completed the rework to the second of the two patch
chains on this and pulled them back together into one series.

Note the main difference is I have pulled a couple patches from
the second series to the start of the chain. This is because of
patch 3 which is a bug fix for 5102 I have discovered whilst
working through this better system suspend support stuff.

Thanks,
Charles


Charles Keepax (9):
  mfd: arizona: Use devres to manage reset GPIO
  mfd: arizona: Factor out hard reset into helper functions
  mfd: wm5102: Ensure we always boot the device fully
  mfd: arizona: Factor out SYSCLK enable from wm5102 hardware patch
  mfd: wm5110: Add register patch required for low power sleep
  regulator: arizona-ldo1: Add additional supported voltage
  mfd: wm5110: Set DCVDD voltage to 1.175V before entering sleep mode
  mfd: arizona: Add better support for system suspend
  mfd: wm5110: Add delay before releasing reset line

 drivers/mfd/arizona-core.c       |  338 ++++++++++++++++++++++++++++++++------
 drivers/regulator/arizona-ldo1.c |   15 ++
 include/linux/mfd/arizona/core.h |    1 +
 3 files changed, 302 insertions(+), 52 deletions(-)

-- 
1.7.2.5


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

* [PATCH 1/9] mfd: arizona: Use devres to manage reset GPIO
  2015-04-08 15:56 [PATCH 0/9] wm5110 Boot Fixups Charles Keepax
@ 2015-04-08 15:56 ` Charles Keepax
  2015-04-08 15:56 ` [PATCH 2/9] mfd: arizona: Factor out hard reset into helper functions Charles Keepax
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 11+ messages in thread
From: Charles Keepax @ 2015-04-08 15:56 UTC (permalink / raw)
  To: lee.jones; +Cc: sameo, broonie, lgirdwood, patches, linux-kernel

This also handily fixes a leak of the GPIO in arizona_dev_exit.

Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
---
 drivers/mfd/arizona-core.c |   10 ++++------
 1 files changed, 4 insertions(+), 6 deletions(-)

diff --git a/drivers/mfd/arizona-core.c b/drivers/mfd/arizona-core.c
index 6ca6dfa..be8b1a4 100644
--- a/drivers/mfd/arizona-core.c
+++ b/drivers/mfd/arizona-core.c
@@ -728,9 +728,9 @@ int arizona_dev_init(struct arizona *arizona)
 
 	if (arizona->pdata.reset) {
 		/* Start out with /RESET low to put the chip into reset */
-		ret = gpio_request_one(arizona->pdata.reset,
-				       GPIOF_DIR_OUT | GPIOF_INIT_LOW,
-				       "arizona /RESET");
+		ret = devm_gpio_request_one(arizona->dev, arizona->pdata.reset,
+					    GPIOF_DIR_OUT | GPIOF_INIT_LOW,
+					    "arizona /RESET");
 		if (ret != 0) {
 			dev_err(dev, "Failed to request /RESET: %d\n", ret);
 			goto err_dcvdd;
@@ -1054,10 +1054,8 @@ int arizona_dev_init(struct arizona *arizona)
 err_irq:
 	arizona_irq_exit(arizona);
 err_reset:
-	if (arizona->pdata.reset) {
+	if (arizona->pdata.reset)
 		gpio_set_value_cansleep(arizona->pdata.reset, 0);
-		gpio_free(arizona->pdata.reset);
-	}
 	regulator_disable(arizona->dcvdd);
 err_enable:
 	regulator_bulk_disable(arizona->num_core_supplies,
-- 
1.7.2.5


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

* [PATCH 2/9] mfd: arizona: Factor out hard reset into helper functions
  2015-04-08 15:56 [PATCH 0/9] wm5110 Boot Fixups Charles Keepax
  2015-04-08 15:56 ` [PATCH 1/9] mfd: arizona: Use devres to manage reset GPIO Charles Keepax
@ 2015-04-08 15:56 ` Charles Keepax
  2015-04-08 15:56 ` [PATCH 3/9] mfd: wm5102: Ensure we always boot the device fully Charles Keepax
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 11+ messages in thread
From: Charles Keepax @ 2015-04-08 15:56 UTC (permalink / raw)
  To: lee.jones; +Cc: sameo, broonie, lgirdwood, patches, linux-kernel

This patch adds functions for enabling and disabling the physical reset
line. This will be helpful in future refactoring.

Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
---
 drivers/mfd/arizona-core.c |   25 +++++++++++++++++--------
 1 files changed, 17 insertions(+), 8 deletions(-)

diff --git a/drivers/mfd/arizona-core.c b/drivers/mfd/arizona-core.c
index be8b1a4..c0e8a96 100644
--- a/drivers/mfd/arizona-core.c
+++ b/drivers/mfd/arizona-core.c
@@ -250,6 +250,20 @@ static int arizona_wait_for_boot(struct arizona *arizona)
 	return ret;
 }
 
+static inline void arizona_enable_reset(struct arizona *arizona)
+{
+	if (arizona->pdata.reset)
+		gpio_set_value_cansleep(arizona->pdata.reset, 0);
+}
+
+static void arizona_disable_reset(struct arizona *arizona)
+{
+	if (arizona->pdata.reset) {
+		gpio_set_value_cansleep(arizona->pdata.reset, 1);
+		msleep(1);
+	}
+}
+
 static int arizona_apply_hardware_patch(struct arizona* arizona)
 {
 	unsigned int fll, sysclk;
@@ -751,10 +765,7 @@ int arizona_dev_init(struct arizona *arizona)
 		goto err_enable;
 	}
 
-	if (arizona->pdata.reset) {
-		gpio_set_value_cansleep(arizona->pdata.reset, 1);
-		msleep(1);
-	}
+	arizona_disable_reset(arizona);
 
 	regcache_cache_only(arizona->regmap, false);
 
@@ -1054,8 +1065,7 @@ int arizona_dev_init(struct arizona *arizona)
 err_irq:
 	arizona_irq_exit(arizona);
 err_reset:
-	if (arizona->pdata.reset)
-		gpio_set_value_cansleep(arizona->pdata.reset, 0);
+	arizona_enable_reset(arizona);
 	regulator_disable(arizona->dcvdd);
 err_enable:
 	regulator_bulk_disable(arizona->num_core_supplies,
@@ -1080,8 +1090,7 @@ int arizona_dev_exit(struct arizona *arizona)
 	arizona_free_irq(arizona, ARIZONA_IRQ_OVERCLOCKED, arizona);
 	arizona_free_irq(arizona, ARIZONA_IRQ_CLKGEN_ERR, arizona);
 	arizona_irq_exit(arizona);
-	if (arizona->pdata.reset)
-		gpio_set_value_cansleep(arizona->pdata.reset, 0);
+	arizona_enable_reset(arizona);
 
 	regulator_bulk_disable(arizona->num_core_supplies,
 			       arizona->core_supplies);
-- 
1.7.2.5


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

* [PATCH 3/9] mfd: wm5102: Ensure we always boot the device fully
  2015-04-08 15:56 [PATCH 0/9] wm5110 Boot Fixups Charles Keepax
  2015-04-08 15:56 ` [PATCH 1/9] mfd: arizona: Use devres to manage reset GPIO Charles Keepax
  2015-04-08 15:56 ` [PATCH 2/9] mfd: arizona: Factor out hard reset into helper functions Charles Keepax
@ 2015-04-08 15:56 ` Charles Keepax
  2015-04-08 15:56 ` [PATCH 4/9] mfd: arizona: Factor out SYSCLK enable from wm5102 hardware patch Charles Keepax
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 11+ messages in thread
From: Charles Keepax @ 2015-04-08 15:56 UTC (permalink / raw)
  To: lee.jones; +Cc: sameo, broonie, lgirdwood, patches, linux-kernel

The wm5102 uses a custom boot sequence and the standard boot sequence is
disabled. However, the standard boot sequence must be run at least once
after a cold boot (caused by either a hard reset or removal of AVDD).
Unfortunately the register WRITE_SEQUENCER_CTRL_3 is not affected by the
hardware reset. This means if the device has been previously booted but
the AVDD supply has never been removed, arizona_dev_init will reset the
chip but the boot sequence will not run, which can cause numerous
problems. The solution is to manually clear this register and then boot
the chip again, which is what this patch does.

Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
---
 drivers/mfd/arizona-core.c |   50 +++++++++++++++++++++++++++++++++++--------
 1 files changed, 40 insertions(+), 10 deletions(-)

diff --git a/drivers/mfd/arizona-core.c b/drivers/mfd/arizona-core.c
index c0e8a96..73418bd 100644
--- a/drivers/mfd/arizona-core.c
+++ b/drivers/mfd/arizona-core.c
@@ -344,6 +344,33 @@ err_fll:
 		return err;
 }
 
+static int wm5102_clear_write_sequencer(struct arizona *arizona)
+{
+	int ret;
+
+	ret = regmap_write(arizona->regmap, ARIZONA_WRITE_SEQUENCER_CTRL_3,
+			   0x0);
+	if (ret) {
+		dev_err(arizona->dev,
+			"Failed to clear write sequencer state: %d\n", ret);
+		return ret;
+	}
+
+	arizona_enable_reset(arizona);
+	regulator_disable(arizona->dcvdd);
+
+	msleep(20);
+
+	ret = regulator_enable(arizona->dcvdd);
+	if (ret) {
+		dev_err(arizona->dev, "Failed to re-enable DCVDD: %d\n", ret);
+		return ret;
+	}
+	arizona_disable_reset(arizona);
+
+	return 0;
+}
+
 #ifdef CONFIG_PM
 static int arizona_runtime_resume(struct device *dev)
 {
@@ -810,21 +837,24 @@ int arizona_dev_init(struct arizona *arizona)
 	case WM5102:
 		ret = regmap_read(arizona->regmap,
 				  ARIZONA_WRITE_SEQUENCER_CTRL_3, &val);
-		if (ret != 0)
+		if (ret) {
 			dev_err(dev,
 				"Failed to check write sequencer state: %d\n",
 				ret);
-		else if (val & 0x01)
-			break;
-		/* Fall through */
-	default:
-		ret = arizona_wait_for_boot(arizona);
-		if (ret != 0) {
-			dev_err(arizona->dev,
-				"Device failed initial boot: %d\n", ret);
-			goto err_reset;
+		} else if (val & 0x01) {
+			ret = wm5102_clear_write_sequencer(arizona);
+			if (ret)
+				return ret;
 		}
 		break;
+	default:
+		break;
+	}
+
+	ret = arizona_wait_for_boot(arizona);
+	if (ret) {
+		dev_err(arizona->dev, "Device failed initial boot: %d\n", ret);
+		goto err_reset;
 	}
 
 	/* Read the device ID information & do device specific stuff */
-- 
1.7.2.5


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

* [PATCH 4/9] mfd: arizona: Factor out SYSCLK enable from wm5102 hardware patch
  2015-04-08 15:56 [PATCH 0/9] wm5110 Boot Fixups Charles Keepax
                   ` (2 preceding siblings ...)
  2015-04-08 15:56 ` [PATCH 3/9] mfd: wm5102: Ensure we always boot the device fully Charles Keepax
@ 2015-04-08 15:56 ` Charles Keepax
  2015-04-08 15:56 ` [PATCH 5/9] mfd: wm5110: Add register patch required for low power sleep Charles Keepax
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 11+ messages in thread
From: Charles Keepax @ 2015-04-08 15:56 UTC (permalink / raw)
  To: lee.jones; +Cc: sameo, broonie, lgirdwood, patches, linux-kernel

wm5102 applies a custom hardware boot sequence, for this the SYSCLK
needs to be enabled. This patch factors out the code that enables
SYSCLK for this sequence such that it can be used for other boot time
operations that require SYSCLK.

Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
---
 drivers/mfd/arizona-core.c |  106 +++++++++++++++++++++++++++++---------------
 1 files changed, 70 insertions(+), 36 deletions(-)

diff --git a/drivers/mfd/arizona-core.c b/drivers/mfd/arizona-core.c
index 73418bd..f1d9ef0 100644
--- a/drivers/mfd/arizona-core.c
+++ b/drivers/mfd/arizona-core.c
@@ -264,20 +264,26 @@ static void arizona_disable_reset(struct arizona *arizona)
 	}
 }
 
-static int arizona_apply_hardware_patch(struct arizona* arizona)
+struct arizona_sysclk_state {
+	unsigned int fll;
+	unsigned int sysclk;
+};
+
+static int arizona_enable_freerun_sysclk(struct arizona *arizona,
+					 struct arizona_sysclk_state *state)
 {
-	unsigned int fll, sysclk;
 	int ret, err;
 
 	/* Cache existing FLL and SYSCLK settings */
-	ret = regmap_read(arizona->regmap, ARIZONA_FLL1_CONTROL_1, &fll);
-	if (ret != 0) {
+	ret = regmap_read(arizona->regmap, ARIZONA_FLL1_CONTROL_1, &state->fll);
+	if (ret) {
 		dev_err(arizona->dev, "Failed to cache FLL settings: %d\n",
 			ret);
 		return ret;
 	}
-	ret = regmap_read(arizona->regmap, ARIZONA_SYSTEM_CLOCK_1, &sysclk);
-	if (ret != 0) {
+	ret = regmap_read(arizona->regmap, ARIZONA_SYSTEM_CLOCK_1,
+			  &state->sysclk);
+	if (ret) {
 		dev_err(arizona->dev, "Failed to cache SYSCLK settings: %d\n",
 			ret);
 		return ret;
@@ -286,7 +292,7 @@ static int arizona_apply_hardware_patch(struct arizona* arizona)
 	/* Start up SYSCLK using the FLL in free running mode */
 	ret = regmap_write(arizona->regmap, ARIZONA_FLL1_CONTROL_1,
 			ARIZONA_FLL1_ENA | ARIZONA_FLL1_FREERUN);
-	if (ret != 0) {
+	if (ret) {
 		dev_err(arizona->dev,
 			"Failed to start FLL in freerunning mode: %d\n",
 			ret);
@@ -295,53 +301,81 @@ static int arizona_apply_hardware_patch(struct arizona* arizona)
 	ret = arizona_poll_reg(arizona, 25, ARIZONA_INTERRUPT_RAW_STATUS_5,
 			       ARIZONA_FLL1_CLOCK_OK_STS,
 			       ARIZONA_FLL1_CLOCK_OK_STS);
-	if (ret != 0) {
+	if (ret) {
 		ret = -ETIMEDOUT;
 		goto err_fll;
 	}
 
 	ret = regmap_write(arizona->regmap, ARIZONA_SYSTEM_CLOCK_1, 0x0144);
-	if (ret != 0) {
+	if (ret) {
 		dev_err(arizona->dev, "Failed to start SYSCLK: %d\n", ret);
 		goto err_fll;
 	}
 
+	return 0;
+
+err_fll:
+	err = regmap_write(arizona->regmap, ARIZONA_FLL1_CONTROL_1, state->fll);
+	if (err)
+		dev_err(arizona->dev,
+			"Failed to re-apply old FLL settings: %d\n", err);
+
+	return ret;
+}
+
+static int arizona_disable_freerun_sysclk(struct arizona *arizona,
+					  struct arizona_sysclk_state *state)
+{
+	int ret;
+
+	ret = regmap_write(arizona->regmap, ARIZONA_SYSTEM_CLOCK_1,
+			   state->sysclk);
+	if (ret) {
+		dev_err(arizona->dev,
+			"Failed to re-apply old SYSCLK settings: %d\n", ret);
+		return ret;
+	}
+
+	ret = regmap_write(arizona->regmap, ARIZONA_FLL1_CONTROL_1, state->fll);
+	if (ret) {
+		dev_err(arizona->dev,
+			"Failed to re-apply old FLL settings: %d\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int wm5102_apply_hardware_patch(struct arizona *arizona)
+{
+	struct arizona_sysclk_state state;
+	int err, ret;
+
+	ret = arizona_enable_freerun_sysclk(arizona, &state);
+	if (ret)
+		return ret;
+
 	/* Start the write sequencer and wait for it to finish */
 	ret = regmap_write(arizona->regmap, ARIZONA_WRITE_SEQUENCER_CTRL_0,
 			ARIZONA_WSEQ_ENA | ARIZONA_WSEQ_START | 160);
-	if (ret != 0) {
+	if (ret) {
 		dev_err(arizona->dev, "Failed to start write sequencer: %d\n",
 			ret);
-		goto err_sysclk;
+		goto err;
 	}
+
 	ret = arizona_poll_reg(arizona, 5, ARIZONA_WRITE_SEQUENCER_CTRL_1,
 			       ARIZONA_WSEQ_BUSY, 0);
-	if (ret != 0) {
+	if (ret) {
 		regmap_write(arizona->regmap, ARIZONA_WRITE_SEQUENCER_CTRL_0,
-				ARIZONA_WSEQ_ABORT);
+			     ARIZONA_WSEQ_ABORT);
 		ret = -ETIMEDOUT;
 	}
 
-err_sysclk:
-	err = regmap_write(arizona->regmap, ARIZONA_SYSTEM_CLOCK_1, sysclk);
-	if (err != 0) {
-		dev_err(arizona->dev,
-			"Failed to re-apply old SYSCLK settings: %d\n",
-			err);
-	}
-
-err_fll:
-	err = regmap_write(arizona->regmap, ARIZONA_FLL1_CONTROL_1, fll);
-	if (err != 0) {
-		dev_err(arizona->dev,
-			"Failed to re-apply old FLL settings: %d\n",
-			err);
-	}
+err:
+	err = arizona_disable_freerun_sysclk(arizona, &state);
 
-	if (ret != 0)
-		return ret;
-	else
-		return err;
+	return ret ?: err;
 }
 
 static int wm5102_clear_write_sequencer(struct arizona *arizona)
@@ -407,8 +441,8 @@ static int arizona_runtime_resume(struct device *dev)
 			goto err;
 		}
 
-		ret = arizona_apply_hardware_patch(arizona);
-		if (ret != 0) {
+		ret = wm5102_apply_hardware_patch(arizona);
+		if (ret) {
 			dev_err(arizona->dev,
 				"Failed to apply hardware patch: %d\n",
 				ret);
@@ -932,8 +966,8 @@ int arizona_dev_init(struct arizona *arizona)
 
 		switch (arizona->type) {
 		case WM5102:
-			ret = arizona_apply_hardware_patch(arizona);
-			if (ret != 0) {
+			ret = wm5102_apply_hardware_patch(arizona);
+			if (ret) {
 				dev_err(arizona->dev,
 					"Failed to apply hardware patch: %d\n",
 					ret);
-- 
1.7.2.5


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

* [PATCH 5/9] mfd: wm5110: Add register patch required for low power sleep
  2015-04-08 15:56 [PATCH 0/9] wm5110 Boot Fixups Charles Keepax
                   ` (3 preceding siblings ...)
  2015-04-08 15:56 ` [PATCH 4/9] mfd: arizona: Factor out SYSCLK enable from wm5102 hardware patch Charles Keepax
@ 2015-04-08 15:56 ` Charles Keepax
  2015-04-17  8:09   ` Charles Keepax
  2015-04-08 15:56 ` [PATCH 6/9] regulator: arizona-ldo1: Add additional supported voltage Charles Keepax
                   ` (3 subsequent siblings)
  8 siblings, 1 reply; 11+ messages in thread
From: Charles Keepax @ 2015-04-08 15:56 UTC (permalink / raw)
  To: lee.jones; +Cc: sameo, broonie, lgirdwood, patches, linux-kernel

Some register settings must be applied before the first time low power
sleep mode is entered on the wm5110 to ensure optimium performance.
These settings require SYSCLK to be enabled whilst they are being
applied. This patch applies the settings using the recently factored out
boot time SYSCLK functionality.

Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
Acked-by: Lee Jones <lee.jones@linaro.org>
---
 drivers/mfd/arizona-core.c |   42 ++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 42 insertions(+), 0 deletions(-)

diff --git a/drivers/mfd/arizona-core.c b/drivers/mfd/arizona-core.c
index f1d9ef0..745ee6c 100644
--- a/drivers/mfd/arizona-core.c
+++ b/drivers/mfd/arizona-core.c
@@ -405,6 +405,38 @@ static int wm5102_clear_write_sequencer(struct arizona *arizona)
 	return 0;
 }
 
+/*
+ * Register patch to some of the CODECs internal write sequences
+ * to ensure a clean exit from the low power sleep state.
+ */
+static const struct reg_default wm5110_sleep_patch[] = {
+	{ 0x337A, 0xC100 },
+	{ 0x337B, 0x0041 },
+	{ 0x3300, 0xA210 },
+	{ 0x3301, 0x050C },
+};
+
+static int wm5110_apply_sleep_patch(struct arizona *arizona)
+{
+	struct arizona_sysclk_state state;
+	int err, ret;
+
+	ret = arizona_enable_freerun_sysclk(arizona, &state);
+	if (ret)
+		return ret;
+
+	ret = regmap_multi_reg_write_bypassed(arizona->regmap,
+					      wm5110_sleep_patch,
+					      ARRAY_SIZE(wm5110_sleep_patch));
+
+	err = arizona_disable_freerun_sysclk(arizona, &state);
+
+	if (ret)
+		return ret;
+	else
+		return err;
+}
+
 #ifdef CONFIG_PM
 static int arizona_runtime_resume(struct device *dev)
 {
@@ -974,6 +1006,16 @@ int arizona_dev_init(struct arizona *arizona)
 				goto err_reset;
 			}
 			break;
+		case WM5110:
+		case WM8280:
+			ret = wm5110_apply_sleep_patch(arizona);
+			if (ret) {
+				dev_err(arizona->dev,
+					"Failed to apply sleep patch: %d\n",
+					ret);
+				goto err_reset;
+			}
+			break;
 		default:
 			break;
 		}
-- 
1.7.2.5


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

* [PATCH 6/9] regulator: arizona-ldo1: Add additional supported voltage
  2015-04-08 15:56 [PATCH 0/9] wm5110 Boot Fixups Charles Keepax
                   ` (4 preceding siblings ...)
  2015-04-08 15:56 ` [PATCH 5/9] mfd: wm5110: Add register patch required for low power sleep Charles Keepax
@ 2015-04-08 15:56 ` Charles Keepax
  2015-04-08 15:56 ` [PATCH 7/9] mfd: wm5110: Set DCVDD voltage to 1.175V before entering sleep mode Charles Keepax
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 11+ messages in thread
From: Charles Keepax @ 2015-04-08 15:56 UTC (permalink / raw)
  To: lee.jones; +Cc: sameo, broonie, lgirdwood, patches, linux-kernel

This patch adds support for the 1.175V mode on the LDO1 regulator on the
wm5110. This is need as part of the low power sleep mode operation.

Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
Acked-by: Mark Brown <broonie@kernel.org>
---
 drivers/regulator/arizona-ldo1.c |   15 +++++++++++++++
 1 files changed, 15 insertions(+), 0 deletions(-)

diff --git a/drivers/regulator/arizona-ldo1.c b/drivers/regulator/arizona-ldo1.c
index 8169165..c9f6302 100644
--- a/drivers/regulator/arizona-ldo1.c
+++ b/drivers/regulator/arizona-ldo1.c
@@ -178,6 +178,16 @@ static const struct regulator_init_data arizona_ldo1_default = {
 	.num_consumer_supplies = 1,
 };
 
+static const struct regulator_init_data arizona_ldo1_wm5110 = {
+	.constraints = {
+		.min_uV = 1175000,
+		.max_uV = 1200000,
+		.valid_ops_mask = REGULATOR_CHANGE_STATUS |
+				  REGULATOR_CHANGE_VOLTAGE,
+	},
+	.num_consumer_supplies = 1,
+};
+
 static int arizona_ldo1_of_get_pdata(struct arizona *arizona,
 				     struct regulator_config *config,
 				     const struct regulator_desc *desc)
@@ -243,6 +253,11 @@ static int arizona_ldo1_probe(struct platform_device *pdev)
 		desc = &arizona_ldo1_hc;
 		ldo1->init_data = arizona_ldo1_dvfs;
 		break;
+	case WM5110:
+	case WM8280:
+		desc = &arizona_ldo1;
+		ldo1->init_data = arizona_ldo1_wm5110;
+		break;
 	default:
 		desc = &arizona_ldo1;
 		ldo1->init_data = arizona_ldo1_default;
-- 
1.7.2.5


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

* [PATCH 7/9] mfd: wm5110: Set DCVDD voltage to 1.175V before entering sleep mode
  2015-04-08 15:56 [PATCH 0/9] wm5110 Boot Fixups Charles Keepax
                   ` (5 preceding siblings ...)
  2015-04-08 15:56 ` [PATCH 6/9] regulator: arizona-ldo1: Add additional supported voltage Charles Keepax
@ 2015-04-08 15:56 ` Charles Keepax
  2015-04-08 15:56 ` [PATCH 8/9] mfd: arizona: Add better support for system suspend Charles Keepax
  2015-04-08 15:56 ` [PATCH 9/9] mfd: wm5110: Add delay before releasing reset line Charles Keepax
  8 siblings, 0 replies; 11+ messages in thread
From: Charles Keepax @ 2015-04-08 15:56 UTC (permalink / raw)
  To: lee.jones; +Cc: sameo, broonie, lgirdwood, patches, linux-kernel

The low power sleep mode on wm5110 requires that the LDO1 regulator be
set to 1.175V prior to entering sleep, then returned to 1.2V after
exiting sleep mode. This patch apply these regulator settings.

Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
Acked-by: Mark Brown <broonie@kernel.org>
Acked-by: Lee Jones <lee.jones@linaro.org>
---
 drivers/mfd/arizona-core.c |   52 ++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 52 insertions(+), 0 deletions(-)

diff --git a/drivers/mfd/arizona-core.c b/drivers/mfd/arizona-core.c
index 745ee6c..1c1f5d0 100644
--- a/drivers/mfd/arizona-core.c
+++ b/drivers/mfd/arizona-core.c
@@ -481,6 +481,37 @@ static int arizona_runtime_resume(struct device *dev)
 			goto err;
 		}
 		break;
+	case WM5110:
+	case WM8280:
+		ret = arizona_wait_for_boot(arizona);
+		if (ret)
+			goto err;
+
+		if (arizona->external_dcvdd) {
+			ret = regmap_update_bits(arizona->regmap,
+						 ARIZONA_ISOLATION_CONTROL,
+						 ARIZONA_ISOLATE_DCVDD1, 0);
+			if (ret) {
+				dev_err(arizona->dev,
+					"Failed to connect DCVDD: %d\n", ret);
+				goto err;
+			}
+		} else {
+			/*
+			 * As this is only called for the internal regulator
+			 * (where we know voltage ranges available) it is ok
+			 * to request an exact range.
+			 */
+			ret = regulator_set_voltage(arizona->dcvdd,
+						    1200000, 1200000);
+			if (ret < 0) {
+				dev_err(arizona->dev,
+					"Failed to set resume voltage: %d\n",
+					ret);
+				goto err;
+			}
+		}
+		break;
 	default:
 		ret = arizona_wait_for_boot(arizona);
 		if (ret != 0) {
@@ -531,6 +562,27 @@ static int arizona_runtime_suspend(struct device *dev)
 				ret);
 			return ret;
 		}
+	} else {
+		switch (arizona->type) {
+		case WM5110:
+		case WM8280:
+			/*
+			 * As this is only called for the internal regulator
+			 * (where we know voltage ranges available) it is ok
+			 * to request an exact range.
+			 */
+			ret = regulator_set_voltage(arizona->dcvdd,
+						    1175000, 1175000);
+			if (ret < 0) {
+				dev_err(arizona->dev,
+					"Failed to set suspend voltage: %d\n",
+					ret);
+				return ret;
+			}
+			break;
+		default:
+			break;
+		}
 	}
 
 	regcache_cache_only(arizona->regmap, true);
-- 
1.7.2.5


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

* [PATCH 8/9] mfd: arizona: Add better support for system suspend
  2015-04-08 15:56 [PATCH 0/9] wm5110 Boot Fixups Charles Keepax
                   ` (6 preceding siblings ...)
  2015-04-08 15:56 ` [PATCH 7/9] mfd: wm5110: Set DCVDD voltage to 1.175V before entering sleep mode Charles Keepax
@ 2015-04-08 15:56 ` Charles Keepax
  2015-04-08 15:56 ` [PATCH 9/9] mfd: wm5110: Add delay before releasing reset line Charles Keepax
  8 siblings, 0 replies; 11+ messages in thread
From: Charles Keepax @ 2015-04-08 15:56 UTC (permalink / raw)
  To: lee.jones; +Cc: sameo, broonie, lgirdwood, patches, linux-kernel

Allow the chip to completely power off if we enter runtime suspend and
there is no jack detection active. This is helpful for systems where
system suspend might remove the supplies to the CODEC, without informing
us. Note the powering off is done in runtime suspend rather than system
suspend, because we need to hold reset until the first time DCVDD is
powered anyway (which would be in runtime resume), and we might as well
save the extra power.

Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
---
 drivers/mfd/arizona-core.c       |   94 +++++++++++++++++++++++++++++++-------
 include/linux/mfd/arizona/core.h |    1 +
 2 files changed, 78 insertions(+), 17 deletions(-)

diff --git a/drivers/mfd/arizona-core.c b/drivers/mfd/arizona-core.c
index 1c1f5d0..8ac8f9d 100644
--- a/drivers/mfd/arizona-core.c
+++ b/drivers/mfd/arizona-core.c
@@ -445,12 +445,33 @@ static int arizona_runtime_resume(struct device *dev)
 
 	dev_dbg(arizona->dev, "Leaving AoD mode\n");
 
+	if (arizona->has_fully_powered_off) {
+		dev_dbg(arizona->dev, "Re-enabling core supplies\n");
+
+		ret = regulator_bulk_enable(arizona->num_core_supplies,
+					    arizona->core_supplies);
+		if (ret) {
+			dev_err(dev, "Failed to enable core supplies: %d\n",
+				ret);
+			return ret;
+		}
+	}
+
 	ret = regulator_enable(arizona->dcvdd);
 	if (ret != 0) {
 		dev_err(arizona->dev, "Failed to enable DCVDD: %d\n", ret);
+		if (arizona->has_fully_powered_off)
+			regulator_bulk_disable(arizona->num_core_supplies,
+					       arizona->core_supplies);
 		return ret;
 	}
 
+	if (arizona->has_fully_powered_off) {
+		arizona_disable_reset(arizona);
+		enable_irq(arizona->irq);
+		arizona->has_fully_powered_off = false;
+	}
+
 	regcache_cache_only(arizona->regmap, false);
 
 	switch (arizona->type) {
@@ -511,6 +532,14 @@ static int arizona_runtime_resume(struct device *dev)
 				goto err;
 			}
 		}
+
+		ret = wm5110_apply_sleep_patch(arizona);
+		if (ret) {
+			dev_err(arizona->dev,
+				"Failed to re-apply sleep patch: %d\n",
+				ret);
+			goto err;
+		}
 		break;
 	default:
 		ret = arizona_wait_for_boot(arizona);
@@ -548,10 +577,17 @@ err:
 static int arizona_runtime_suspend(struct device *dev)
 {
 	struct arizona *arizona = dev_get_drvdata(dev);
+	unsigned int val;
 	int ret;
 
 	dev_dbg(arizona->dev, "Entering AoD mode\n");
 
+	ret = regmap_read(arizona->regmap, ARIZONA_JACK_DETECT_ANALOGUE, &val);
+	if (ret) {
+		dev_err(dev, "Failed to check jack det status: %d\n", ret);
+		return ret;
+	}
+
 	if (arizona->external_dcvdd) {
 		ret = regmap_update_bits(arizona->regmap,
 					 ARIZONA_ISOLATION_CONTROL,
@@ -562,33 +598,57 @@ static int arizona_runtime_suspend(struct device *dev)
 				ret);
 			return ret;
 		}
-	} else {
-		switch (arizona->type) {
-		case WM5110:
-		case WM8280:
-			/*
-			 * As this is only called for the internal regulator
-			 * (where we know voltage ranges available) it is ok
-			 * to request an exact range.
-			 */
-			ret = regulator_set_voltage(arizona->dcvdd,
-						    1175000, 1175000);
-			if (ret < 0) {
+	}
+
+	switch (arizona->type) {
+	case WM5110:
+	case WM8280:
+		if (arizona->external_dcvdd)
+			break;
+
+		/*
+		 * As this is only called for the internal regulator
+		 * (where we know voltage ranges available) it is ok
+		 * to request an exact range.
+		 */
+		ret = regulator_set_voltage(arizona->dcvdd, 1175000, 1175000);
+		if (ret < 0) {
+			dev_err(arizona->dev,
+				"Failed to set suspend voltage: %d\n", ret);
+			return ret;
+		}
+		break;
+	case WM5102:
+		if (!(val & ARIZONA_JD1_ENA))
+			ret = regmap_write(arizona->regmap,
+					   ARIZONA_WRITE_SEQUENCER_CTRL_3, 0x0);
+			if (ret) {
 				dev_err(arizona->dev,
-					"Failed to set suspend voltage: %d\n",
+					"Failed to clear write sequencer: %d\n",
 					ret);
 				return ret;
 			}
-			break;
-		default:
-			break;
-		}
+		break;
+	default:
+		break;
 	}
 
 	regcache_cache_only(arizona->regmap, true);
 	regcache_mark_dirty(arizona->regmap);
 	regulator_disable(arizona->dcvdd);
 
+	/* Allow us to completely power down if no jack detection */
+	if (!(val & ARIZONA_JD1_ENA)) {
+		dev_dbg(arizona->dev, "Fully powering off\n");
+
+		arizona->has_fully_powered_off = true;
+
+		disable_irq(arizona->irq);
+		arizona_enable_reset(arizona);
+		regulator_bulk_disable(arizona->num_core_supplies,
+				       arizona->core_supplies);
+	}
+
 	return 0;
 }
 #endif
diff --git a/include/linux/mfd/arizona/core.h b/include/linux/mfd/arizona/core.h
index f970105..7c210af 100644
--- a/include/linux/mfd/arizona/core.h
+++ b/include/linux/mfd/arizona/core.h
@@ -117,6 +117,7 @@ struct arizona {
 	int num_core_supplies;
 	struct regulator_bulk_data core_supplies[ARIZONA_MAX_CORE_SUPPLIES];
 	struct regulator *dcvdd;
+	bool has_fully_powered_off;
 
 	struct arizona_pdata pdata;
 
-- 
1.7.2.5


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

* [PATCH 9/9] mfd: wm5110: Add delay before releasing reset line
  2015-04-08 15:56 [PATCH 0/9] wm5110 Boot Fixups Charles Keepax
                   ` (7 preceding siblings ...)
  2015-04-08 15:56 ` [PATCH 8/9] mfd: arizona: Add better support for system suspend Charles Keepax
@ 2015-04-08 15:56 ` Charles Keepax
  8 siblings, 0 replies; 11+ messages in thread
From: Charles Keepax @ 2015-04-08 15:56 UTC (permalink / raw)
  To: lee.jones; +Cc: sameo, broonie, lgirdwood, patches, linux-kernel

On the wm5110 it is important the reset line is held for slightly longer
to ensure the device starts up well. This patch adds a 5mS delay for
this.

Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
---
 drivers/mfd/arizona-core.c |    9 +++++++++
 1 files changed, 9 insertions(+), 0 deletions(-)

diff --git a/drivers/mfd/arizona-core.c b/drivers/mfd/arizona-core.c
index 8ac8f9d..0a563ccf 100644
--- a/drivers/mfd/arizona-core.c
+++ b/drivers/mfd/arizona-core.c
@@ -259,6 +259,15 @@ static inline void arizona_enable_reset(struct arizona *arizona)
 static void arizona_disable_reset(struct arizona *arizona)
 {
 	if (arizona->pdata.reset) {
+		switch (arizona->type) {
+		case WM5110:
+		case WM8280:
+			msleep(5);
+			break;
+		default:
+			break;
+		}
+
 		gpio_set_value_cansleep(arizona->pdata.reset, 1);
 		msleep(1);
 	}
-- 
1.7.2.5


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

* Re: [PATCH 5/9] mfd: wm5110: Add register patch required for low power sleep
  2015-04-08 15:56 ` [PATCH 5/9] mfd: wm5110: Add register patch required for low power sleep Charles Keepax
@ 2015-04-17  8:09   ` Charles Keepax
  0 siblings, 0 replies; 11+ messages in thread
From: Charles Keepax @ 2015-04-17  8:09 UTC (permalink / raw)
  To: lee.jones; +Cc: patches, broonie, sameo, linux-kernel, lgirdwood

On Wed, Apr 08, 2015 at 04:56:14PM +0100, Charles Keepax wrote:
> Some register settings must be applied before the first time low power
> sleep mode is entered on the wm5110 to ensure optimium performance.
> These settings require SYSCLK to be enabled whilst they are being
> applied. This patch applies the settings using the recently factored out
> boot time SYSCLK functionality.
> 
> Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
> Acked-by: Lee Jones <lee.jones@linaro.org>
> ---
>  drivers/mfd/arizona-core.c |   42 ++++++++++++++++++++++++++++++++++++++++++
>  1 files changed, 42 insertions(+), 0 deletions(-)
> 
> diff --git a/drivers/mfd/arizona-core.c b/drivers/mfd/arizona-core.c
> index f1d9ef0..745ee6c 100644
> --- a/drivers/mfd/arizona-core.c
> +++ b/drivers/mfd/arizona-core.c
> @@ -405,6 +405,38 @@ static int wm5102_clear_write_sequencer(struct arizona *arizona)
>  	return 0;
>  }
>  
> +/*
> + * Register patch to some of the CODECs internal write sequences
> + * to ensure a clean exit from the low power sleep state.
> + */
> +static const struct reg_default wm5110_sleep_patch[] = {
> +	{ 0x337A, 0xC100 },
> +	{ 0x337B, 0x0041 },
> +	{ 0x3300, 0xA210 },
> +	{ 0x3301, 0x050C },
> +};
> +
> +static int wm5110_apply_sleep_patch(struct arizona *arizona)
> +{
> +	struct arizona_sysclk_state state;
> +	int err, ret;
> +
> +	ret = arizona_enable_freerun_sysclk(arizona, &state);
> +	if (ret)
> +		return ret;
> +
> +	ret = regmap_multi_reg_write_bypassed(arizona->regmap,
> +					      wm5110_sleep_patch,
> +					      ARRAY_SIZE(wm5110_sleep_patch));
> +
> +	err = arizona_disable_freerun_sysclk(arizona, &state);
> +
> +	if (ret)
> +		return ret;
> +	else
> +		return err;

Sorry this should also be a ternary, will do a new spin.

Thanks,
Charles

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

end of thread, other threads:[~2015-04-17  8:09 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-04-08 15:56 [PATCH 0/9] wm5110 Boot Fixups Charles Keepax
2015-04-08 15:56 ` [PATCH 1/9] mfd: arizona: Use devres to manage reset GPIO Charles Keepax
2015-04-08 15:56 ` [PATCH 2/9] mfd: arizona: Factor out hard reset into helper functions Charles Keepax
2015-04-08 15:56 ` [PATCH 3/9] mfd: wm5102: Ensure we always boot the device fully Charles Keepax
2015-04-08 15:56 ` [PATCH 4/9] mfd: arizona: Factor out SYSCLK enable from wm5102 hardware patch Charles Keepax
2015-04-08 15:56 ` [PATCH 5/9] mfd: wm5110: Add register patch required for low power sleep Charles Keepax
2015-04-17  8:09   ` Charles Keepax
2015-04-08 15:56 ` [PATCH 6/9] regulator: arizona-ldo1: Add additional supported voltage Charles Keepax
2015-04-08 15:56 ` [PATCH 7/9] mfd: wm5110: Set DCVDD voltage to 1.175V before entering sleep mode Charles Keepax
2015-04-08 15:56 ` [PATCH 8/9] mfd: arizona: Add better support for system suspend Charles Keepax
2015-04-08 15:56 ` [PATCH 9/9] mfd: wm5110: Add delay before releasing reset line Charles Keepax

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.