linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/5] DA9062 PMIC fixes and features
@ 2019-09-17 12:42 Marco Felsch
  2019-09-17 12:42 ` [PATCH 1/5] regulator: da9062: fix suspend_enable/disable preparation Marco Felsch
                   ` (4 more replies)
  0 siblings, 5 replies; 29+ messages in thread
From: Marco Felsch @ 2019-09-17 12:42 UTC (permalink / raw)
  To: support.opensource, lee.jones, robh+dt, lgirdwood, broonie,
	stwiss.opensource
  Cc: kernel, devicetree, linux-kernel

Hi,

the main purpose of this serie is to add the voltage selection support
upon a given gpio input signal and to dis-/enable a regulator upon a
gpio input signal.

This series depends on [1].

[1] https://patchwork.ozlabs.org/project/linux-gpio/list/?series=131029

Regards,
  Marco

Marco Felsch (5):
  regulator: da9062: fix suspend_enable/disable preparation
  dt-bindings: mfd: da9062: add regulator voltage selection
    documentation
  regulator: da9062: add voltage selection gpio support
  dt-bindings: mfd: da9062: add regulator gpio enable/disable
    documentation
  regulator: da9062: add gpio based regulator dis-/enable support

 .../devicetree/bindings/mfd/da9062.txt        |  16 +
 drivers/regulator/da9062-regulator.c          | 347 ++++++++++++++----
 2 files changed, 292 insertions(+), 71 deletions(-)

-- 
2.20.1


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

* [PATCH 1/5] regulator: da9062: fix suspend_enable/disable preparation
  2019-09-17 12:42 [PATCH 0/5] DA9062 PMIC fixes and features Marco Felsch
@ 2019-09-17 12:42 ` Marco Felsch
  2019-09-18 12:41   ` Adam Thomson
                     ` (2 more replies)
  2019-09-17 12:42 ` [PATCH 2/5] dt-bindings: mfd: da9062: add regulator voltage selection documentation Marco Felsch
                   ` (3 subsequent siblings)
  4 siblings, 3 replies; 29+ messages in thread
From: Marco Felsch @ 2019-09-17 12:42 UTC (permalink / raw)
  To: support.opensource, lee.jones, robh+dt, lgirdwood, broonie,
	stwiss.opensource
  Cc: kernel, devicetree, linux-kernel

Currently the suspend reg_field maps to the pmic voltage selection bits
and is used during suspend_enabe/disable() and during get_mode(). This
seems to be wrong for both use cases.

Use case one (suspend_enabe/disable):
Those callbacks are used to mark a regulator device as enabled/disabled
during suspend. Marking the regulator enabled during suspend is done by
the LDOx_CONF/BUCKx_CONF bit within the LDOx_CONT/BUCKx_CONT registers.
Setting this bit tells the DA9062 PMIC state machine to keep the
regulator on in POWERDOWN mode and switch to suspend voltage.

Use case two (get_mode):
The get_mode callback is used to retrieve the active mode state. Since
the regulator-setting-A is used for the active state and
regulator-setting-B for the suspend state there is no need to check
which regulator setting is active.

Fixes: 4068e5182ada ("regulator: da9062: DA9062 regulator driver")
Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
---
 drivers/regulator/da9062-regulator.c | 118 +++++++++++----------------
 1 file changed, 47 insertions(+), 71 deletions(-)

diff --git a/drivers/regulator/da9062-regulator.c b/drivers/regulator/da9062-regulator.c
index 2ffc64622451..9b2ca472f70c 100644
--- a/drivers/regulator/da9062-regulator.c
+++ b/drivers/regulator/da9062-regulator.c
@@ -136,7 +136,6 @@ static int da9062_buck_set_mode(struct regulator_dev *rdev, unsigned mode)
 static unsigned da9062_buck_get_mode(struct regulator_dev *rdev)
 {
 	struct da9062_regulator *regl = rdev_get_drvdata(rdev);
-	struct regmap_field *field;
 	unsigned int val, mode = 0;
 	int ret;
 
@@ -158,18 +157,7 @@ static unsigned da9062_buck_get_mode(struct regulator_dev *rdev)
 		return REGULATOR_MODE_NORMAL;
 	}
 
-	/* Detect current regulator state */
-	ret = regmap_field_read(regl->suspend, &val);
-	if (ret < 0)
-		return 0;
-
-	/* Read regulator mode from proper register, depending on state */
-	if (val)
-		field = regl->suspend_sleep;
-	else
-		field = regl->sleep;
-
-	ret = regmap_field_read(field, &val);
+	ret = regmap_field_read(regl->sleep, &val);
 	if (ret < 0)
 		return 0;
 
@@ -208,21 +196,9 @@ static int da9062_ldo_set_mode(struct regulator_dev *rdev, unsigned mode)
 static unsigned da9062_ldo_get_mode(struct regulator_dev *rdev)
 {
 	struct da9062_regulator *regl = rdev_get_drvdata(rdev);
-	struct regmap_field *field;
 	int ret, val;
 
-	/* Detect current regulator state */
-	ret = regmap_field_read(regl->suspend, &val);
-	if (ret < 0)
-		return 0;
-
-	/* Read regulator mode from proper register, depending on state */
-	if (val)
-		field = regl->suspend_sleep;
-	else
-		field = regl->sleep;
-
-	ret = regmap_field_read(field, &val);
+	ret = regmap_field_read(regl->sleep, &val);
 	if (ret < 0)
 		return 0;
 
@@ -408,10 +384,10 @@ static const struct da9062_regulator_info local_da9061_regulator_info[] = {
 			__builtin_ffs((int)DA9062AA_BUCK1_MODE_MASK) - 1,
 			sizeof(unsigned int) * 8 -
 			__builtin_clz((DA9062AA_BUCK1_MODE_MASK)) - 1),
-		.suspend = REG_FIELD(DA9062AA_DVC_1,
-			__builtin_ffs((int)DA9062AA_VBUCK1_SEL_MASK) - 1,
+		.suspend = REG_FIELD(DA9062AA_BUCK1_CONT,
+			__builtin_ffs((int)DA9062AA_BUCK1_CONF_MASK) - 1,
 			sizeof(unsigned int) * 8 -
-			__builtin_clz((DA9062AA_VBUCK1_SEL_MASK)) - 1),
+			__builtin_clz(DA9062AA_BUCK1_CONF_MASK) - 1),
 	},
 	{
 		.desc.id = DA9061_ID_BUCK2,
@@ -444,10 +420,10 @@ static const struct da9062_regulator_info local_da9061_regulator_info[] = {
 			__builtin_ffs((int)DA9062AA_BUCK3_MODE_MASK) - 1,
 			sizeof(unsigned int) * 8 -
 			__builtin_clz((DA9062AA_BUCK3_MODE_MASK)) - 1),
-		.suspend = REG_FIELD(DA9062AA_DVC_1,
-			__builtin_ffs((int)DA9062AA_VBUCK3_SEL_MASK) - 1,
+		.suspend = REG_FIELD(DA9062AA_BUCK3_CONT,
+			__builtin_ffs((int)DA9062AA_BUCK3_CONF_MASK) - 1,
 			sizeof(unsigned int) * 8 -
-			__builtin_clz((DA9062AA_VBUCK3_SEL_MASK)) - 1),
+			__builtin_clz(DA9062AA_BUCK3_CONF_MASK) - 1),
 	},
 	{
 		.desc.id = DA9061_ID_BUCK3,
@@ -480,10 +456,10 @@ static const struct da9062_regulator_info local_da9061_regulator_info[] = {
 			__builtin_ffs((int)DA9062AA_BUCK4_MODE_MASK) - 1,
 			sizeof(unsigned int) * 8 -
 			__builtin_clz((DA9062AA_BUCK4_MODE_MASK)) - 1),
-		.suspend = REG_FIELD(DA9062AA_DVC_1,
-			__builtin_ffs((int)DA9062AA_VBUCK4_SEL_MASK) - 1,
+		.suspend = REG_FIELD(DA9062AA_BUCK4_CONT,
+			__builtin_ffs((int)DA9062AA_BUCK4_CONF_MASK) - 1,
 			sizeof(unsigned int) * 8 -
-			__builtin_clz((DA9062AA_VBUCK4_SEL_MASK)) - 1),
+			__builtin_clz(DA9062AA_BUCK4_CONF_MASK) - 1),
 	},
 	{
 		.desc.id = DA9061_ID_LDO1,
@@ -509,10 +485,10 @@ static const struct da9062_regulator_info local_da9061_regulator_info[] = {
 			sizeof(unsigned int) * 8 -
 			__builtin_clz((DA9062AA_LDO1_SL_B_MASK)) - 1),
 		.suspend_vsel_reg = DA9062AA_VLDO1_B,
-		.suspend = REG_FIELD(DA9062AA_DVC_1,
-			__builtin_ffs((int)DA9062AA_VLDO1_SEL_MASK) - 1,
+		.suspend = REG_FIELD(DA9062AA_LDO1_CONT,
+			__builtin_ffs((int)DA9062AA_LDO1_CONF_MASK) - 1,
 			sizeof(unsigned int) * 8 -
-			__builtin_clz((DA9062AA_VLDO1_SEL_MASK)) - 1),
+			__builtin_clz(DA9062AA_LDO1_CONF_MASK) - 1),
 		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
 			__builtin_ffs((int)DA9062AA_LDO1_ILIM_MASK) - 1,
 			sizeof(unsigned int) * 8 -
@@ -542,10 +518,10 @@ static const struct da9062_regulator_info local_da9061_regulator_info[] = {
 			sizeof(unsigned int) * 8 -
 			__builtin_clz((DA9062AA_LDO2_SL_B_MASK)) - 1),
 		.suspend_vsel_reg = DA9062AA_VLDO2_B,
-		.suspend = REG_FIELD(DA9062AA_DVC_1,
-			__builtin_ffs((int)DA9062AA_VLDO2_SEL_MASK) - 1,
+		.suspend = REG_FIELD(DA9062AA_LDO2_CONT,
+			__builtin_ffs((int)DA9062AA_LDO2_CONF_MASK) - 1,
 			sizeof(unsigned int) * 8 -
-			__builtin_clz((DA9062AA_VLDO2_SEL_MASK)) - 1),
+			__builtin_clz(DA9062AA_LDO2_CONF_MASK) - 1),
 		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
 			__builtin_ffs((int)DA9062AA_LDO2_ILIM_MASK) - 1,
 			sizeof(unsigned int) * 8 -
@@ -575,10 +551,10 @@ static const struct da9062_regulator_info local_da9061_regulator_info[] = {
 			sizeof(unsigned int) * 8 -
 			__builtin_clz((DA9062AA_LDO3_SL_B_MASK)) - 1),
 		.suspend_vsel_reg = DA9062AA_VLDO3_B,
-		.suspend = REG_FIELD(DA9062AA_DVC_1,
-			__builtin_ffs((int)DA9062AA_VLDO3_SEL_MASK) - 1,
+		.suspend = REG_FIELD(DA9062AA_LDO3_CONT,
+			__builtin_ffs((int)DA9062AA_LDO3_CONF_MASK) - 1,
 			sizeof(unsigned int) * 8 -
-			__builtin_clz((DA9062AA_VLDO3_SEL_MASK)) - 1),
+			__builtin_clz(DA9062AA_LDO3_CONF_MASK) - 1),
 		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
 			__builtin_ffs((int)DA9062AA_LDO3_ILIM_MASK) - 1,
 			sizeof(unsigned int) * 8 -
@@ -608,10 +584,10 @@ static const struct da9062_regulator_info local_da9061_regulator_info[] = {
 			sizeof(unsigned int) * 8 -
 			__builtin_clz((DA9062AA_LDO4_SL_B_MASK)) - 1),
 		.suspend_vsel_reg = DA9062AA_VLDO4_B,
-		.suspend = REG_FIELD(DA9062AA_DVC_1,
-			__builtin_ffs((int)DA9062AA_VLDO4_SEL_MASK) - 1,
+		.suspend = REG_FIELD(DA9062AA_LDO4_CONT,
+			__builtin_ffs((int)DA9062AA_LDO4_CONF_MASK) - 1,
 			sizeof(unsigned int) * 8 -
-			__builtin_clz((DA9062AA_VLDO4_SEL_MASK)) - 1),
+			__builtin_clz(DA9062AA_LDO4_CONF_MASK) - 1),
 		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
 			__builtin_ffs((int)DA9062AA_LDO4_ILIM_MASK) - 1,
 			sizeof(unsigned int) * 8 -
@@ -652,10 +628,10 @@ static const struct da9062_regulator_info local_da9062_regulator_info[] = {
 			__builtin_ffs((int)DA9062AA_BUCK1_MODE_MASK) - 1,
 			sizeof(unsigned int) * 8 -
 			__builtin_clz((DA9062AA_BUCK1_MODE_MASK)) - 1),
-		.suspend = REG_FIELD(DA9062AA_DVC_1,
-			__builtin_ffs((int)DA9062AA_VBUCK1_SEL_MASK) - 1,
+		.suspend = REG_FIELD(DA9062AA_BUCK1_CONT,
+			__builtin_ffs((int)DA9062AA_BUCK1_CONF_MASK) - 1,
 			sizeof(unsigned int) * 8 -
-			__builtin_clz((DA9062AA_VBUCK1_SEL_MASK)) - 1),
+			__builtin_clz(DA9062AA_BUCK1_CONF_MASK) - 1),
 	},
 	{
 		.desc.id = DA9062_ID_BUCK2,
@@ -688,10 +664,10 @@ static const struct da9062_regulator_info local_da9062_regulator_info[] = {
 			__builtin_ffs((int)DA9062AA_BUCK2_MODE_MASK) - 1,
 			sizeof(unsigned int) * 8 -
 			__builtin_clz((DA9062AA_BUCK2_MODE_MASK)) - 1),
-		.suspend = REG_FIELD(DA9062AA_DVC_1,
-			__builtin_ffs((int)DA9062AA_VBUCK2_SEL_MASK) - 1,
+		.suspend = REG_FIELD(DA9062AA_BUCK2_CONT,
+			__builtin_ffs((int)DA9062AA_BUCK2_CONF_MASK) - 1,
 			sizeof(unsigned int) * 8 -
-			__builtin_clz((DA9062AA_VBUCK2_SEL_MASK)) - 1),
+			__builtin_clz(DA9062AA_BUCK2_CONF_MASK) - 1),
 	},
 	{
 		.desc.id = DA9062_ID_BUCK3,
@@ -724,10 +700,10 @@ static const struct da9062_regulator_info local_da9062_regulator_info[] = {
 			__builtin_ffs((int)DA9062AA_BUCK3_MODE_MASK) - 1,
 			sizeof(unsigned int) * 8 -
 			__builtin_clz((DA9062AA_BUCK3_MODE_MASK)) - 1),
-		.suspend = REG_FIELD(DA9062AA_DVC_1,
-			__builtin_ffs((int)DA9062AA_VBUCK3_SEL_MASK) - 1,
+		.suspend = REG_FIELD(DA9062AA_BUCK3_CONT,
+			__builtin_ffs((int)DA9062AA_BUCK3_CONF_MASK) - 1,
 			sizeof(unsigned int) * 8 -
-			__builtin_clz((DA9062AA_VBUCK3_SEL_MASK)) - 1),
+			__builtin_clz(DA9062AA_BUCK3_CONF_MASK) - 1),
 	},
 	{
 		.desc.id = DA9062_ID_BUCK4,
@@ -760,10 +736,10 @@ static const struct da9062_regulator_info local_da9062_regulator_info[] = {
 			__builtin_ffs((int)DA9062AA_BUCK4_MODE_MASK) - 1,
 			sizeof(unsigned int) * 8 -
 			__builtin_clz((DA9062AA_BUCK4_MODE_MASK)) - 1),
-		.suspend = REG_FIELD(DA9062AA_DVC_1,
-			__builtin_ffs((int)DA9062AA_VBUCK4_SEL_MASK) - 1,
+		.suspend = REG_FIELD(DA9062AA_BUCK4_CONT,
+			__builtin_ffs((int)DA9062AA_BUCK4_CONF_MASK) - 1,
 			sizeof(unsigned int) * 8 -
-			__builtin_clz((DA9062AA_VBUCK4_SEL_MASK)) - 1),
+			__builtin_clz(DA9062AA_BUCK4_CONF_MASK) - 1),
 	},
 	{
 		.desc.id = DA9062_ID_LDO1,
@@ -789,10 +765,10 @@ static const struct da9062_regulator_info local_da9062_regulator_info[] = {
 			sizeof(unsigned int) * 8 -
 			__builtin_clz((DA9062AA_LDO1_SL_B_MASK)) - 1),
 		.suspend_vsel_reg = DA9062AA_VLDO1_B,
-		.suspend = REG_FIELD(DA9062AA_DVC_1,
-			__builtin_ffs((int)DA9062AA_VLDO1_SEL_MASK) - 1,
+		.suspend = REG_FIELD(DA9062AA_LDO1_CONT,
+			__builtin_ffs((int)DA9062AA_LDO1_CONF_MASK) - 1,
 			sizeof(unsigned int) * 8 -
-			__builtin_clz((DA9062AA_VLDO1_SEL_MASK)) - 1),
+			__builtin_clz(DA9062AA_LDO1_CONF_MASK) - 1),
 		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
 			__builtin_ffs((int)DA9062AA_LDO1_ILIM_MASK) - 1,
 			sizeof(unsigned int) * 8 -
@@ -822,10 +798,10 @@ static const struct da9062_regulator_info local_da9062_regulator_info[] = {
 			sizeof(unsigned int) * 8 -
 			__builtin_clz((DA9062AA_LDO2_SL_B_MASK)) - 1),
 		.suspend_vsel_reg = DA9062AA_VLDO2_B,
-		.suspend = REG_FIELD(DA9062AA_DVC_1,
-			__builtin_ffs((int)DA9062AA_VLDO2_SEL_MASK) - 1,
+		.suspend = REG_FIELD(DA9062AA_LDO2_CONT,
+			__builtin_ffs((int)DA9062AA_LDO2_CONF_MASK) - 1,
 			sizeof(unsigned int) * 8 -
-			__builtin_clz((DA9062AA_VLDO2_SEL_MASK)) - 1),
+			__builtin_clz(DA9062AA_LDO2_CONF_MASK) - 1),
 		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
 			__builtin_ffs((int)DA9062AA_LDO2_ILIM_MASK) - 1,
 			sizeof(unsigned int) * 8 -
@@ -855,10 +831,10 @@ static const struct da9062_regulator_info local_da9062_regulator_info[] = {
 			sizeof(unsigned int) * 8 -
 			__builtin_clz((DA9062AA_LDO3_SL_B_MASK)) - 1),
 		.suspend_vsel_reg = DA9062AA_VLDO3_B,
-		.suspend = REG_FIELD(DA9062AA_DVC_1,
-			__builtin_ffs((int)DA9062AA_VLDO3_SEL_MASK) - 1,
+		.suspend = REG_FIELD(DA9062AA_LDO3_CONT,
+			__builtin_ffs((int)DA9062AA_LDO3_CONF_MASK) - 1,
 			sizeof(unsigned int) * 8 -
-			__builtin_clz((DA9062AA_VLDO3_SEL_MASK)) - 1),
+			__builtin_clz(DA9062AA_LDO3_CONF_MASK) - 1),
 		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
 			__builtin_ffs((int)DA9062AA_LDO3_ILIM_MASK) - 1,
 			sizeof(unsigned int) * 8 -
@@ -888,10 +864,10 @@ static const struct da9062_regulator_info local_da9062_regulator_info[] = {
 			sizeof(unsigned int) * 8 -
 			__builtin_clz((DA9062AA_LDO4_SL_B_MASK)) - 1),
 		.suspend_vsel_reg = DA9062AA_VLDO4_B,
-		.suspend = REG_FIELD(DA9062AA_DVC_1,
-			__builtin_ffs((int)DA9062AA_VLDO4_SEL_MASK) - 1,
+		.suspend = REG_FIELD(DA9062AA_LDO4_CONT,
+			__builtin_ffs((int)DA9062AA_LDO4_CONF_MASK) - 1,
 			sizeof(unsigned int) * 8 -
-			__builtin_clz((DA9062AA_VLDO4_SEL_MASK)) - 1),
+			__builtin_clz(DA9062AA_LDO4_CONF_MASK) - 1),
 		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
 			__builtin_ffs((int)DA9062AA_LDO4_ILIM_MASK) - 1,
 			sizeof(unsigned int) * 8 -
-- 
2.20.1


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

* [PATCH 2/5] dt-bindings: mfd: da9062: add regulator voltage selection documentation
  2019-09-17 12:42 [PATCH 0/5] DA9062 PMIC fixes and features Marco Felsch
  2019-09-17 12:42 ` [PATCH 1/5] regulator: da9062: fix suspend_enable/disable preparation Marco Felsch
@ 2019-09-17 12:42 ` Marco Felsch
  2019-09-24  9:23   ` Adam Thomson
  2019-09-17 12:42 ` [PATCH 3/5] regulator: da9062: add voltage selection gpio support Marco Felsch
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 29+ messages in thread
From: Marco Felsch @ 2019-09-17 12:42 UTC (permalink / raw)
  To: support.opensource, lee.jones, robh+dt, lgirdwood, broonie,
	stwiss.opensource
  Cc: kernel, devicetree, linux-kernel

Add the documentation which describe the voltage selection gpio support.
This property can be applied to each subnode within the 'regulators'
node so each regulator can be configured differently.

Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
---
 Documentation/devicetree/bindings/mfd/da9062.txt | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/Documentation/devicetree/bindings/mfd/da9062.txt b/Documentation/devicetree/bindings/mfd/da9062.txt
index edca653a5777..9d9820d8177d 100644
--- a/Documentation/devicetree/bindings/mfd/da9062.txt
+++ b/Documentation/devicetree/bindings/mfd/da9062.txt
@@ -66,6 +66,15 @@ Sub-nodes:
   details of individual regulator device can be found in:
   Documentation/devicetree/bindings/regulator/regulator.txt
 
+  Optional regulator device-specific properties:
+  - dlg,vsel-sense-gpios : The GPIO reference which should be used by the
+    regulator to switch the voltage between active/suspend voltage settings. If
+    the signal is active the active-settings are applied else the suspend
+    settings are applied. Attention: Sharing the same gpio for other purposes
+    or across multiple regulators is possible but the gpio settings must be the
+    same. Also the gpio phandle must refer to to the dlg,da9062-gpio device
+    other gpios are not allowed and make no sense.
+
 - rtc : This node defines settings required for the Real-Time Clock associated
   with the DA9062. There are currently no entries in this binding, however
   compatible = "dlg,da9062-rtc" should be added if a node is created.
-- 
2.20.1


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

* [PATCH 3/5] regulator: da9062: add voltage selection gpio support
  2019-09-17 12:42 [PATCH 0/5] DA9062 PMIC fixes and features Marco Felsch
  2019-09-17 12:42 ` [PATCH 1/5] regulator: da9062: fix suspend_enable/disable preparation Marco Felsch
  2019-09-17 12:42 ` [PATCH 2/5] dt-bindings: mfd: da9062: add regulator voltage selection documentation Marco Felsch
@ 2019-09-17 12:42 ` Marco Felsch
  2019-09-17 14:22   ` kbuild test robot
                     ` (2 more replies)
  2019-09-17 12:42 ` [PATCH 4/5] dt-bindings: mfd: da9062: add regulator gpio enable/disable documentation Marco Felsch
  2019-09-17 12:42 ` [PATCH 5/5] regulator: da9062: add gpio based regulator dis-/enable support Marco Felsch
  4 siblings, 3 replies; 29+ messages in thread
From: Marco Felsch @ 2019-09-17 12:42 UTC (permalink / raw)
  To: support.opensource, lee.jones, robh+dt, lgirdwood, broonie,
	stwiss.opensource
  Cc: kernel, devicetree, linux-kernel

The DA9062/1 devices can switch their regulator voltages between
voltage-A (active) and voltage-B (suspend) settings. Switching the
voltages can be controlled by ther internal state-machine or by a gpio
input signal and can be configured for each individual regulator. This
commit adds the gpio-based voltage switching support.

Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
---
 drivers/regulator/da9062-regulator.c | 149 +++++++++++++++++++++++++++
 1 file changed, 149 insertions(+)

diff --git a/drivers/regulator/da9062-regulator.c b/drivers/regulator/da9062-regulator.c
index 9b2ca472f70c..9d6eb7625948 100644
--- a/drivers/regulator/da9062-regulator.c
+++ b/drivers/regulator/da9062-regulator.c
@@ -7,6 +7,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/err.h>
+#include <linux/gpio/consumer.h>
 #include <linux/slab.h>
 #include <linux/of.h>
 #include <linux/platform_device.h>
@@ -15,6 +16,7 @@
 #include <linux/regulator/machine.h>
 #include <linux/regulator/of_regulator.h>
 #include <linux/mfd/da9062/core.h>
+#include <linux/mfd/da9062/gpio.h>
 #include <linux/mfd/da9062/registers.h>
 
 /* Regulator IDs */
@@ -50,6 +52,7 @@ struct da9062_regulator_info {
 	struct reg_field sleep;
 	struct reg_field suspend_sleep;
 	unsigned int suspend_vsel_reg;
+	struct reg_field vsel_gpi;
 	/* Event detection bit */
 	struct reg_field oc_event;
 };
@@ -65,6 +68,7 @@ struct da9062_regulator {
 	struct regmap_field			*suspend;
 	struct regmap_field			*sleep;
 	struct regmap_field			*suspend_sleep;
+	struct regmap_field			*vsel_gpi;
 };
 
 /* Encapsulates all information for the regulators driver */
@@ -351,6 +355,65 @@ static const struct regulator_ops da9062_ldo_ops = {
 	.set_suspend_mode	= da9062_ldo_set_suspend_mode,
 };
 
+static int da9062_config_gpi(struct device_node *np,
+			     const struct regulator_desc *desc,
+			     struct regulator_config *cfg, const char *gpi_id)
+{
+	struct da9062_regulator *regl = cfg->driver_data;
+	struct gpio_desc *gpi;
+	unsigned int nr;
+	int ret;
+	char *prop, *label;
+
+	prop = kasprintf(GFP_KERNEL, "dlg,%s-sense-gpios", gpi_id);
+	if (!prop)
+		return -ENOMEM;
+	label = kasprintf(GFP_KERNEL, "%s-%s-gpi", desc->name, gpi_id);
+	if (!label) {
+		ret = -ENOMEM;
+		goto free;
+	}
+
+	/*
+	 * We only must ensure that the gpio device is probed before the
+	 * regulator driver so no need to store the reference global. Luckily
+	 * devm_* releases the gpio upon a unbound action.
+	 */
+	gpi = devm_gpiod_get_from_of_node(cfg->dev, np, prop, 0, GPIOD_IN |
+					  GPIOD_FLAGS_BIT_NONEXCLUSIVE, label);
+	if (IS_ERR(gpi)) {
+		ret = PTR_ERR(gpi);
+		goto free;
+	}
+
+	if (!gpi) {
+		ret = 0;
+		goto free;
+	}
+
+	/* We need the local number */
+	nr = da9062_gpio_get_hwgpio(gpi);
+	if (nr < 1 || nr > 3) {
+		ret = -EINVAL;
+		goto free;
+	}
+
+	ret = regmap_field_write(regl->vsel_gpi, nr);
+
+free:
+	kfree(prop);
+	kfree(label);
+
+	return ret;
+}
+
+static int da9062_parse_dt(struct device_node *np,
+			   const struct regulator_desc *desc,
+			   struct regulator_config *cfg)
+{
+	return da9062_config_gpi(np, desc, cfg, "vsel");
+}
+
 /* DA9061 Regulator information */
 static const struct da9062_regulator_info local_da9061_regulator_info[] = {
 	{
@@ -358,6 +421,7 @@ static const struct da9062_regulator_info local_da9061_regulator_info[] = {
 		.desc.name = "DA9061 BUCK1",
 		.desc.of_match = of_match_ptr("buck1"),
 		.desc.regulators_node = of_match_ptr("regulators"),
+		.desc.of_parse_cb = da9062_parse_dt,
 		.desc.ops = &da9062_buck_ops,
 		.desc.min_uV = (300) * 1000,
 		.desc.uV_step = (10) * 1000,
@@ -388,12 +452,17 @@ static const struct da9062_regulator_info local_da9061_regulator_info[] = {
 			__builtin_ffs((int)DA9062AA_BUCK1_CONF_MASK) - 1,
 			sizeof(unsigned int) * 8 -
 			__builtin_clz(DA9062AA_BUCK1_CONF_MASK) - 1),
+		.vsel_gpi = REG_FIELD(DA9062AA_BUCK1_CONT,
+			__builtin_ffs((int)DA9062AA_VBUCK1_GPI_MASK) - 1,
+			sizeof(unsigned int) * 8 -
+			__builtin_clz(DA9062AA_VBUCK1_GPI_MASK) - 1),
 	},
 	{
 		.desc.id = DA9061_ID_BUCK2,
 		.desc.name = "DA9061 BUCK2",
 		.desc.of_match = of_match_ptr("buck2"),
 		.desc.regulators_node = of_match_ptr("regulators"),
+		.desc.of_parse_cb = da9062_parse_dt,
 		.desc.ops = &da9062_buck_ops,
 		.desc.min_uV = (800) * 1000,
 		.desc.uV_step = (20) * 1000,
@@ -424,12 +493,17 @@ static const struct da9062_regulator_info local_da9061_regulator_info[] = {
 			__builtin_ffs((int)DA9062AA_BUCK3_CONF_MASK) - 1,
 			sizeof(unsigned int) * 8 -
 			__builtin_clz(DA9062AA_BUCK3_CONF_MASK) - 1),
+		.vsel_gpi = REG_FIELD(DA9062AA_BUCK3_CONT,
+			__builtin_ffs((int)DA9062AA_VBUCK3_GPI_MASK) - 1,
+			sizeof(unsigned int) * 8 -
+			__builtin_clz(DA9062AA_VBUCK3_GPI_MASK) - 1),
 	},
 	{
 		.desc.id = DA9061_ID_BUCK3,
 		.desc.name = "DA9061 BUCK3",
 		.desc.of_match = of_match_ptr("buck3"),
 		.desc.regulators_node = of_match_ptr("regulators"),
+		.desc.of_parse_cb = da9062_parse_dt,
 		.desc.ops = &da9062_buck_ops,
 		.desc.min_uV = (530) * 1000,
 		.desc.uV_step = (10) * 1000,
@@ -460,12 +534,17 @@ static const struct da9062_regulator_info local_da9061_regulator_info[] = {
 			__builtin_ffs((int)DA9062AA_BUCK4_CONF_MASK) - 1,
 			sizeof(unsigned int) * 8 -
 			__builtin_clz(DA9062AA_BUCK4_CONF_MASK) - 1),
+		.vsel_gpi = REG_FIELD(DA9062AA_BUCK4_CONT,
+			__builtin_ffs((int)DA9062AA_VBUCK4_GPI_MASK) - 1,
+			sizeof(unsigned int) * 8 -
+			__builtin_clz(DA9062AA_VBUCK4_GPI_MASK) - 1),
 	},
 	{
 		.desc.id = DA9061_ID_LDO1,
 		.desc.name = "DA9061 LDO1",
 		.desc.of_match = of_match_ptr("ldo1"),
 		.desc.regulators_node = of_match_ptr("regulators"),
+		.desc.of_parse_cb = da9062_parse_dt,
 		.desc.ops = &da9062_ldo_ops,
 		.desc.min_uV = (900) * 1000,
 		.desc.uV_step = (50) * 1000,
@@ -489,6 +568,10 @@ static const struct da9062_regulator_info local_da9061_regulator_info[] = {
 			__builtin_ffs((int)DA9062AA_LDO1_CONF_MASK) - 1,
 			sizeof(unsigned int) * 8 -
 			__builtin_clz(DA9062AA_LDO1_CONF_MASK) - 1),
+		.vsel_gpi = REG_FIELD(DA9062AA_LDO1_CONT,
+			__builtin_ffs((int)DA9062AA_VLDO1_GPI_MASK) - 1,
+			sizeof(unsigned int) * 8 -
+			__builtin_clz(DA9062AA_VLDO1_GPI_MASK) - 1),
 		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
 			__builtin_ffs((int)DA9062AA_LDO1_ILIM_MASK) - 1,
 			sizeof(unsigned int) * 8 -
@@ -499,6 +582,7 @@ static const struct da9062_regulator_info local_da9061_regulator_info[] = {
 		.desc.name = "DA9061 LDO2",
 		.desc.of_match = of_match_ptr("ldo2"),
 		.desc.regulators_node = of_match_ptr("regulators"),
+		.desc.of_parse_cb = da9062_parse_dt,
 		.desc.ops = &da9062_ldo_ops,
 		.desc.min_uV = (900) * 1000,
 		.desc.uV_step = (50) * 1000,
@@ -522,6 +606,10 @@ static const struct da9062_regulator_info local_da9061_regulator_info[] = {
 			__builtin_ffs((int)DA9062AA_LDO2_CONF_MASK) - 1,
 			sizeof(unsigned int) * 8 -
 			__builtin_clz(DA9062AA_LDO2_CONF_MASK) - 1),
+		.vsel_gpi = REG_FIELD(DA9062AA_LDO2_CONT,
+			__builtin_ffs((int)DA9062AA_VLDO2_GPI_MASK) - 1,
+			sizeof(unsigned int) * 8 -
+			__builtin_clz(DA9062AA_VLDO2_GPI_MASK) - 1),
 		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
 			__builtin_ffs((int)DA9062AA_LDO2_ILIM_MASK) - 1,
 			sizeof(unsigned int) * 8 -
@@ -532,6 +620,7 @@ static const struct da9062_regulator_info local_da9061_regulator_info[] = {
 		.desc.name = "DA9061 LDO3",
 		.desc.of_match = of_match_ptr("ldo3"),
 		.desc.regulators_node = of_match_ptr("regulators"),
+		.desc.of_parse_cb = da9062_parse_dt,
 		.desc.ops = &da9062_ldo_ops,
 		.desc.min_uV = (900) * 1000,
 		.desc.uV_step = (50) * 1000,
@@ -555,6 +644,10 @@ static const struct da9062_regulator_info local_da9061_regulator_info[] = {
 			__builtin_ffs((int)DA9062AA_LDO3_CONF_MASK) - 1,
 			sizeof(unsigned int) * 8 -
 			__builtin_clz(DA9062AA_LDO3_CONF_MASK) - 1),
+		.vsel_gpi = REG_FIELD(DA9062AA_LDO3_CONT,
+			__builtin_ffs((int)DA9062AA_VLDO3_GPI_MASK) - 1,
+			sizeof(unsigned int) * 8 -
+			__builtin_clz(DA9062AA_VLDO3_GPI_MASK) - 1),
 		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
 			__builtin_ffs((int)DA9062AA_LDO3_ILIM_MASK) - 1,
 			sizeof(unsigned int) * 8 -
@@ -565,6 +658,7 @@ static const struct da9062_regulator_info local_da9061_regulator_info[] = {
 		.desc.name = "DA9061 LDO4",
 		.desc.of_match = of_match_ptr("ldo4"),
 		.desc.regulators_node = of_match_ptr("regulators"),
+		.desc.of_parse_cb = da9062_parse_dt,
 		.desc.ops = &da9062_ldo_ops,
 		.desc.min_uV = (900) * 1000,
 		.desc.uV_step = (50) * 1000,
@@ -588,6 +682,10 @@ static const struct da9062_regulator_info local_da9061_regulator_info[] = {
 			__builtin_ffs((int)DA9062AA_LDO4_CONF_MASK) - 1,
 			sizeof(unsigned int) * 8 -
 			__builtin_clz(DA9062AA_LDO4_CONF_MASK) - 1),
+		.vsel_gpi = REG_FIELD(DA9062AA_LDO4_CONT,
+			__builtin_ffs((int)DA9062AA_VLDO4_GPI_MASK) - 1,
+			sizeof(unsigned int) * 8 -
+			__builtin_clz(DA9062AA_VLDO4_GPI_MASK) - 1),
 		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
 			__builtin_ffs((int)DA9062AA_LDO4_ILIM_MASK) - 1,
 			sizeof(unsigned int) * 8 -
@@ -602,6 +700,7 @@ static const struct da9062_regulator_info local_da9062_regulator_info[] = {
 		.desc.name = "DA9062 BUCK1",
 		.desc.of_match = of_match_ptr("buck1"),
 		.desc.regulators_node = of_match_ptr("regulators"),
+		.desc.of_parse_cb = da9062_parse_dt,
 		.desc.ops = &da9062_buck_ops,
 		.desc.min_uV = (300) * 1000,
 		.desc.uV_step = (10) * 1000,
@@ -632,12 +731,17 @@ static const struct da9062_regulator_info local_da9062_regulator_info[] = {
 			__builtin_ffs((int)DA9062AA_BUCK1_CONF_MASK) - 1,
 			sizeof(unsigned int) * 8 -
 			__builtin_clz(DA9062AA_BUCK1_CONF_MASK) - 1),
+		.vsel_gpi = REG_FIELD(DA9062AA_BUCK1_CONT,
+			__builtin_ffs((int)DA9062AA_VBUCK1_GPI_MASK) - 1,
+			sizeof(unsigned int) * 8 -
+			__builtin_clz(DA9062AA_VBUCK1_GPI_MASK) - 1),
 	},
 	{
 		.desc.id = DA9062_ID_BUCK2,
 		.desc.name = "DA9062 BUCK2",
 		.desc.of_match = of_match_ptr("buck2"),
 		.desc.regulators_node = of_match_ptr("regulators"),
+		.desc.of_parse_cb = da9062_parse_dt,
 		.desc.ops = &da9062_buck_ops,
 		.desc.min_uV = (300) * 1000,
 		.desc.uV_step = (10) * 1000,
@@ -668,12 +772,17 @@ static const struct da9062_regulator_info local_da9062_regulator_info[] = {
 			__builtin_ffs((int)DA9062AA_BUCK2_CONF_MASK) - 1,
 			sizeof(unsigned int) * 8 -
 			__builtin_clz(DA9062AA_BUCK2_CONF_MASK) - 1),
+		.vsel_gpi = REG_FIELD(DA9062AA_BUCK2_CONT,
+			__builtin_ffs((int)DA9062AA_VBUCK2_GPI_MASK) - 1,
+			sizeof(unsigned int) * 8 -
+			__builtin_clz(DA9062AA_VBUCK2_GPI_MASK) - 1),
 	},
 	{
 		.desc.id = DA9062_ID_BUCK3,
 		.desc.name = "DA9062 BUCK3",
 		.desc.of_match = of_match_ptr("buck3"),
 		.desc.regulators_node = of_match_ptr("regulators"),
+		.desc.of_parse_cb = da9062_parse_dt,
 		.desc.ops = &da9062_buck_ops,
 		.desc.min_uV = (800) * 1000,
 		.desc.uV_step = (20) * 1000,
@@ -704,12 +813,17 @@ static const struct da9062_regulator_info local_da9062_regulator_info[] = {
 			__builtin_ffs((int)DA9062AA_BUCK3_CONF_MASK) - 1,
 			sizeof(unsigned int) * 8 -
 			__builtin_clz(DA9062AA_BUCK3_CONF_MASK) - 1),
+		.vsel_gpi = REG_FIELD(DA9062AA_BUCK3_CONT,
+			__builtin_ffs((int)DA9062AA_VBUCK3_GPI_MASK) - 1,
+			sizeof(unsigned int) * 8 -
+			__builtin_clz(DA9062AA_VBUCK3_GPI_MASK) - 1),
 	},
 	{
 		.desc.id = DA9062_ID_BUCK4,
 		.desc.name = "DA9062 BUCK4",
 		.desc.of_match = of_match_ptr("buck4"),
 		.desc.regulators_node = of_match_ptr("regulators"),
+		.desc.of_parse_cb = da9062_parse_dt,
 		.desc.ops = &da9062_buck_ops,
 		.desc.min_uV = (530) * 1000,
 		.desc.uV_step = (10) * 1000,
@@ -740,12 +854,17 @@ static const struct da9062_regulator_info local_da9062_regulator_info[] = {
 			__builtin_ffs((int)DA9062AA_BUCK4_CONF_MASK) - 1,
 			sizeof(unsigned int) * 8 -
 			__builtin_clz(DA9062AA_BUCK4_CONF_MASK) - 1),
+		.vsel_gpi = REG_FIELD(DA9062AA_BUCK4_CONT,
+			__builtin_ffs((int)DA9062AA_VBUCK4_GPI_MASK) - 1,
+			sizeof(unsigned int) * 8 -
+			__builtin_clz(DA9062AA_VBUCK4_GPI_MASK) - 1),
 	},
 	{
 		.desc.id = DA9062_ID_LDO1,
 		.desc.name = "DA9062 LDO1",
 		.desc.of_match = of_match_ptr("ldo1"),
 		.desc.regulators_node = of_match_ptr("regulators"),
+		.desc.of_parse_cb = da9062_parse_dt,
 		.desc.ops = &da9062_ldo_ops,
 		.desc.min_uV = (900) * 1000,
 		.desc.uV_step = (50) * 1000,
@@ -769,6 +888,10 @@ static const struct da9062_regulator_info local_da9062_regulator_info[] = {
 			__builtin_ffs((int)DA9062AA_LDO1_CONF_MASK) - 1,
 			sizeof(unsigned int) * 8 -
 			__builtin_clz(DA9062AA_LDO1_CONF_MASK) - 1),
+		.vsel_gpi = REG_FIELD(DA9062AA_LDO1_CONT,
+			__builtin_ffs((int)DA9062AA_VLDO1_GPI_MASK) - 1,
+			sizeof(unsigned int) * 8 -
+			__builtin_clz(DA9062AA_VLDO1_GPI_MASK) - 1),
 		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
 			__builtin_ffs((int)DA9062AA_LDO1_ILIM_MASK) - 1,
 			sizeof(unsigned int) * 8 -
@@ -779,6 +902,7 @@ static const struct da9062_regulator_info local_da9062_regulator_info[] = {
 		.desc.name = "DA9062 LDO2",
 		.desc.of_match = of_match_ptr("ldo2"),
 		.desc.regulators_node = of_match_ptr("regulators"),
+		.desc.of_parse_cb = da9062_parse_dt,
 		.desc.ops = &da9062_ldo_ops,
 		.desc.min_uV = (900) * 1000,
 		.desc.uV_step = (50) * 1000,
@@ -802,6 +926,10 @@ static const struct da9062_regulator_info local_da9062_regulator_info[] = {
 			__builtin_ffs((int)DA9062AA_LDO2_CONF_MASK) - 1,
 			sizeof(unsigned int) * 8 -
 			__builtin_clz(DA9062AA_LDO2_CONF_MASK) - 1),
+		.vsel_gpi = REG_FIELD(DA9062AA_LDO2_CONT,
+			__builtin_ffs((int)DA9062AA_VLDO2_GPI_MASK) - 1,
+			sizeof(unsigned int) * 8 -
+			__builtin_clz(DA9062AA_VLDO2_GPI_MASK) - 1),
 		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
 			__builtin_ffs((int)DA9062AA_LDO2_ILIM_MASK) - 1,
 			sizeof(unsigned int) * 8 -
@@ -812,6 +940,7 @@ static const struct da9062_regulator_info local_da9062_regulator_info[] = {
 		.desc.name = "DA9062 LDO3",
 		.desc.of_match = of_match_ptr("ldo3"),
 		.desc.regulators_node = of_match_ptr("regulators"),
+		.desc.of_parse_cb = da9062_parse_dt,
 		.desc.ops = &da9062_ldo_ops,
 		.desc.min_uV = (900) * 1000,
 		.desc.uV_step = (50) * 1000,
@@ -835,6 +964,10 @@ static const struct da9062_regulator_info local_da9062_regulator_info[] = {
 			__builtin_ffs((int)DA9062AA_LDO3_CONF_MASK) - 1,
 			sizeof(unsigned int) * 8 -
 			__builtin_clz(DA9062AA_LDO3_CONF_MASK) - 1),
+		.vsel_gpi = REG_FIELD(DA9062AA_LDO3_CONT,
+			__builtin_ffs((int)DA9062AA_VLDO3_GPI_MASK) - 1,
+			sizeof(unsigned int) * 8 -
+			__builtin_clz(DA9062AA_VLDO3_GPI_MASK) - 1),
 		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
 			__builtin_ffs((int)DA9062AA_LDO3_ILIM_MASK) - 1,
 			sizeof(unsigned int) * 8 -
@@ -845,6 +978,7 @@ static const struct da9062_regulator_info local_da9062_regulator_info[] = {
 		.desc.name = "DA9062 LDO4",
 		.desc.of_match = of_match_ptr("ldo4"),
 		.desc.regulators_node = of_match_ptr("regulators"),
+		.desc.of_parse_cb = da9062_parse_dt,
 		.desc.ops = &da9062_ldo_ops,
 		.desc.min_uV = (900) * 1000,
 		.desc.uV_step = (50) * 1000,
@@ -868,6 +1002,10 @@ static const struct da9062_regulator_info local_da9062_regulator_info[] = {
 			__builtin_ffs((int)DA9062AA_LDO4_CONF_MASK) - 1,
 			sizeof(unsigned int) * 8 -
 			__builtin_clz(DA9062AA_LDO4_CONF_MASK) - 1),
+		.vsel_gpi = REG_FIELD(DA9062AA_LDO4_CONT,
+			__builtin_ffs((int)DA9062AA_VLDO4_GPI_MASK) - 1,
+			sizeof(unsigned int) * 8 -
+			__builtin_clz(DA9062AA_VLDO4_GPI_MASK) - 1),
 		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
 			__builtin_ffs((int)DA9062AA_LDO4_ILIM_MASK) - 1,
 			sizeof(unsigned int) * 8 -
@@ -988,6 +1126,15 @@ static int da9062_regulator_probe(struct platform_device *pdev)
 				return PTR_ERR(regl->suspend_sleep);
 		}
 
+		if (regl->info->vsel_gpi.reg) {
+			regl->vsel_gpi = devm_regmap_field_alloc(
+					&pdev->dev,
+					chip->regmap,
+					regl->info->vsel_gpi);
+			if (IS_ERR(regl->vsel_gpi))
+				return PTR_ERR(regl->vsel_gpi);
+		}
+
 		/* Register regulator */
 		memset(&config, 0, sizeof(config));
 		config.dev = chip->dev;
@@ -997,6 +1144,8 @@ static int da9062_regulator_probe(struct platform_device *pdev)
 		regl->rdev = devm_regulator_register(&pdev->dev, &regl->desc,
 						     &config);
 		if (IS_ERR(regl->rdev)) {
+			if (PTR_ERR(regl->rdev) == -EPROBE_DEFER)
+				return -EPROBE_DEFER;
 			dev_err(&pdev->dev,
 				"Failed to register %s regulator\n",
 				regl->desc.name);
-- 
2.20.1


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

* [PATCH 4/5] dt-bindings: mfd: da9062: add regulator gpio enable/disable documentation
  2019-09-17 12:42 [PATCH 0/5] DA9062 PMIC fixes and features Marco Felsch
                   ` (2 preceding siblings ...)
  2019-09-17 12:42 ` [PATCH 3/5] regulator: da9062: add voltage selection gpio support Marco Felsch
@ 2019-09-17 12:42 ` Marco Felsch
  2019-09-17 12:42 ` [PATCH 5/5] regulator: da9062: add gpio based regulator dis-/enable support Marco Felsch
  4 siblings, 0 replies; 29+ messages in thread
From: Marco Felsch @ 2019-09-17 12:42 UTC (permalink / raw)
  To: support.opensource, lee.jones, robh+dt, lgirdwood, broonie,
	stwiss.opensource
  Cc: kernel, devicetree, linux-kernel

At the gpio-based regulator enable/disable documentation. This property
can be applied to each subnode within the 'regulators' node so each
regulator can be configured differently.

Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
---
 Documentation/devicetree/bindings/mfd/da9062.txt | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/Documentation/devicetree/bindings/mfd/da9062.txt b/Documentation/devicetree/bindings/mfd/da9062.txt
index 9d9820d8177d..3d4b90bf8ea6 100644
--- a/Documentation/devicetree/bindings/mfd/da9062.txt
+++ b/Documentation/devicetree/bindings/mfd/da9062.txt
@@ -75,6 +75,13 @@ Sub-nodes:
     same. Also the gpio phandle must refer to to the dlg,da9062-gpio device
     other gpios are not allowed and make no sense.
 
+  - dlg,ena-sense-gpios : The GPIO reference which should be used by the
+    regulator to enable/disable the output. If the signal is active the
+    regulator is on else it is off. Attention: Sharing the same gpio for other
+    purposes or across multiple regulators is possible but the gpio settings
+    must be the same. Also the gpio phandle must refer to to the
+    dlg,da9062-gpio device other gpios are not allowed and make no sense.
+
 - rtc : This node defines settings required for the Real-Time Clock associated
   with the DA9062. There are currently no entries in this binding, however
   compatible = "dlg,da9062-rtc" should be added if a node is created.
-- 
2.20.1


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

* [PATCH 5/5] regulator: da9062: add gpio based regulator dis-/enable support
  2019-09-17 12:42 [PATCH 0/5] DA9062 PMIC fixes and features Marco Felsch
                   ` (3 preceding siblings ...)
  2019-09-17 12:42 ` [PATCH 4/5] dt-bindings: mfd: da9062: add regulator gpio enable/disable documentation Marco Felsch
@ 2019-09-17 12:42 ` Marco Felsch
  4 siblings, 0 replies; 29+ messages in thread
From: Marco Felsch @ 2019-09-17 12:42 UTC (permalink / raw)
  To: support.opensource, lee.jones, robh+dt, lgirdwood, broonie,
	stwiss.opensource
  Cc: kernel, devicetree, linux-kernel

Each regulator can be enabeld/disabled by the internal pmic state
machine or by a gpio input signal. Typically the OTP configures the
regulators to be enabled/disabled on a specific sequence number which is
most the time fine. Sometimes we need to reconfigure that due to a PCB
bug. This patch adds the support to disable/enable the regulator based
on a gpio input signal.

Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
---
 drivers/regulator/da9062-regulator.c | 84 +++++++++++++++++++++++++++-
 1 file changed, 82 insertions(+), 2 deletions(-)

diff --git a/drivers/regulator/da9062-regulator.c b/drivers/regulator/da9062-regulator.c
index 9d6eb7625948..1fd15c6c654f 100644
--- a/drivers/regulator/da9062-regulator.c
+++ b/drivers/regulator/da9062-regulator.c
@@ -53,6 +53,7 @@ struct da9062_regulator_info {
 	struct reg_field suspend_sleep;
 	unsigned int suspend_vsel_reg;
 	struct reg_field vsel_gpi;
+	struct reg_field ena_gpi;
 	/* Event detection bit */
 	struct reg_field oc_event;
 };
@@ -69,6 +70,7 @@ struct da9062_regulator {
 	struct regmap_field			*sleep;
 	struct regmap_field			*suspend_sleep;
 	struct regmap_field			*vsel_gpi;
+	struct regmap_field			*ena_gpi;
 };
 
 /* Encapsulates all information for the regulators driver */
@@ -398,7 +400,10 @@ static int da9062_config_gpi(struct device_node *np,
 		goto free;
 	}
 
-	ret = regmap_field_write(regl->vsel_gpi, nr);
+	if (!strncmp(gpi_id, "ena", 3))
+		ret = regmap_field_write(regl->ena_gpi, nr);
+	else
+		ret = regmap_field_write(regl->vsel_gpi, nr);
 
 free:
 	kfree(prop);
@@ -411,7 +416,13 @@ static int da9062_parse_dt(struct device_node *np,
 			   const struct regulator_desc *desc,
 			   struct regulator_config *cfg)
 {
-	return da9062_config_gpi(np, desc, cfg, "vsel");
+	int error;
+
+	error = da9062_config_gpi(np, desc, cfg, "vsel");
+	if (error)
+		return error;
+
+	return da9062_config_gpi(np, desc, cfg, "ena");
 }
 
 /* DA9061 Regulator information */
@@ -456,6 +467,10 @@ static const struct da9062_regulator_info local_da9061_regulator_info[] = {
 			__builtin_ffs((int)DA9062AA_VBUCK1_GPI_MASK) - 1,
 			sizeof(unsigned int) * 8 -
 			__builtin_clz(DA9062AA_VBUCK1_GPI_MASK) - 1),
+		.ena_gpi = REG_FIELD(DA9062AA_BUCK1_CONT,
+			__builtin_ffs((int)DA9062AA_BUCK1_GPI_MASK) - 1,
+			sizeof(unsigned int) * 8 -
+			__builtin_clz(DA9062AA_BUCK1_GPI_MASK) - 1),
 	},
 	{
 		.desc.id = DA9061_ID_BUCK2,
@@ -497,6 +512,10 @@ static const struct da9062_regulator_info local_da9061_regulator_info[] = {
 			__builtin_ffs((int)DA9062AA_VBUCK3_GPI_MASK) - 1,
 			sizeof(unsigned int) * 8 -
 			__builtin_clz(DA9062AA_VBUCK3_GPI_MASK) - 1),
+		.ena_gpi = REG_FIELD(DA9062AA_BUCK3_CONT,
+			__builtin_ffs((int)DA9062AA_BUCK3_GPI_MASK) - 1,
+			sizeof(unsigned int) * 8 -
+			__builtin_clz(DA9062AA_BUCK3_GPI_MASK) - 1),
 	},
 	{
 		.desc.id = DA9061_ID_BUCK3,
@@ -538,6 +557,10 @@ static const struct da9062_regulator_info local_da9061_regulator_info[] = {
 			__builtin_ffs((int)DA9062AA_VBUCK4_GPI_MASK) - 1,
 			sizeof(unsigned int) * 8 -
 			__builtin_clz(DA9062AA_VBUCK4_GPI_MASK) - 1),
+		.ena_gpi = REG_FIELD(DA9062AA_BUCK4_CONT,
+			__builtin_ffs((int)DA9062AA_BUCK4_GPI_MASK) - 1,
+			sizeof(unsigned int) * 8 -
+			__builtin_clz(DA9062AA_BUCK4_GPI_MASK) - 1),
 	},
 	{
 		.desc.id = DA9061_ID_LDO1,
@@ -572,6 +595,10 @@ static const struct da9062_regulator_info local_da9061_regulator_info[] = {
 			__builtin_ffs((int)DA9062AA_VLDO1_GPI_MASK) - 1,
 			sizeof(unsigned int) * 8 -
 			__builtin_clz(DA9062AA_VLDO1_GPI_MASK) - 1),
+		.ena_gpi = REG_FIELD(DA9062AA_LDO1_CONT,
+			__builtin_ffs((int)DA9062AA_LDO1_GPI_MASK) - 1,
+			sizeof(unsigned int) * 8 -
+			__builtin_clz(DA9062AA_LDO1_GPI_MASK) - 1),
 		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
 			__builtin_ffs((int)DA9062AA_LDO1_ILIM_MASK) - 1,
 			sizeof(unsigned int) * 8 -
@@ -610,6 +637,10 @@ static const struct da9062_regulator_info local_da9061_regulator_info[] = {
 			__builtin_ffs((int)DA9062AA_VLDO2_GPI_MASK) - 1,
 			sizeof(unsigned int) * 8 -
 			__builtin_clz(DA9062AA_VLDO2_GPI_MASK) - 1),
+		.ena_gpi = REG_FIELD(DA9062AA_LDO2_CONT,
+			__builtin_ffs((int)DA9062AA_LDO2_GPI_MASK) - 1,
+			sizeof(unsigned int) * 8 -
+			__builtin_clz(DA9062AA_LDO2_GPI_MASK) - 1),
 		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
 			__builtin_ffs((int)DA9062AA_LDO2_ILIM_MASK) - 1,
 			sizeof(unsigned int) * 8 -
@@ -648,6 +679,10 @@ static const struct da9062_regulator_info local_da9061_regulator_info[] = {
 			__builtin_ffs((int)DA9062AA_VLDO3_GPI_MASK) - 1,
 			sizeof(unsigned int) * 8 -
 			__builtin_clz(DA9062AA_VLDO3_GPI_MASK) - 1),
+		.ena_gpi = REG_FIELD(DA9062AA_LDO3_CONT,
+			__builtin_ffs((int)DA9062AA_LDO3_GPI_MASK) - 1,
+			sizeof(unsigned int) * 8 -
+			__builtin_clz(DA9062AA_LDO3_GPI_MASK) - 1),
 		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
 			__builtin_ffs((int)DA9062AA_LDO3_ILIM_MASK) - 1,
 			sizeof(unsigned int) * 8 -
@@ -686,6 +721,10 @@ static const struct da9062_regulator_info local_da9061_regulator_info[] = {
 			__builtin_ffs((int)DA9062AA_VLDO4_GPI_MASK) - 1,
 			sizeof(unsigned int) * 8 -
 			__builtin_clz(DA9062AA_VLDO4_GPI_MASK) - 1),
+		.ena_gpi = REG_FIELD(DA9062AA_LDO4_CONT,
+			__builtin_ffs((int)DA9062AA_LDO4_GPI_MASK) - 1,
+			sizeof(unsigned int) * 8 -
+			__builtin_clz(DA9062AA_LDO4_GPI_MASK) - 1),
 		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
 			__builtin_ffs((int)DA9062AA_LDO4_ILIM_MASK) - 1,
 			sizeof(unsigned int) * 8 -
@@ -735,6 +774,10 @@ static const struct da9062_regulator_info local_da9062_regulator_info[] = {
 			__builtin_ffs((int)DA9062AA_VBUCK1_GPI_MASK) - 1,
 			sizeof(unsigned int) * 8 -
 			__builtin_clz(DA9062AA_VBUCK1_GPI_MASK) - 1),
+		.ena_gpi = REG_FIELD(DA9062AA_BUCK1_CONT,
+			__builtin_ffs((int)DA9062AA_BUCK1_GPI_MASK) - 1,
+			sizeof(unsigned int) * 8 -
+			__builtin_clz(DA9062AA_BUCK1_GPI_MASK) - 1),
 	},
 	{
 		.desc.id = DA9062_ID_BUCK2,
@@ -776,6 +819,10 @@ static const struct da9062_regulator_info local_da9062_regulator_info[] = {
 			__builtin_ffs((int)DA9062AA_VBUCK2_GPI_MASK) - 1,
 			sizeof(unsigned int) * 8 -
 			__builtin_clz(DA9062AA_VBUCK2_GPI_MASK) - 1),
+		.ena_gpi = REG_FIELD(DA9062AA_BUCK2_CONT,
+			__builtin_ffs((int)DA9062AA_BUCK2_GPI_MASK) - 1,
+			sizeof(unsigned int) * 8 -
+			__builtin_clz(DA9062AA_BUCK2_GPI_MASK) - 1),
 	},
 	{
 		.desc.id = DA9062_ID_BUCK3,
@@ -817,6 +864,10 @@ static const struct da9062_regulator_info local_da9062_regulator_info[] = {
 			__builtin_ffs((int)DA9062AA_VBUCK3_GPI_MASK) - 1,
 			sizeof(unsigned int) * 8 -
 			__builtin_clz(DA9062AA_VBUCK3_GPI_MASK) - 1),
+		.ena_gpi = REG_FIELD(DA9062AA_BUCK3_CONT,
+			__builtin_ffs((int)DA9062AA_BUCK3_GPI_MASK) - 1,
+			sizeof(unsigned int) * 8 -
+			__builtin_clz(DA9062AA_BUCK3_GPI_MASK) - 1),
 	},
 	{
 		.desc.id = DA9062_ID_BUCK4,
@@ -858,6 +909,10 @@ static const struct da9062_regulator_info local_da9062_regulator_info[] = {
 			__builtin_ffs((int)DA9062AA_VBUCK4_GPI_MASK) - 1,
 			sizeof(unsigned int) * 8 -
 			__builtin_clz(DA9062AA_VBUCK4_GPI_MASK) - 1),
+		.ena_gpi = REG_FIELD(DA9062AA_BUCK4_CONT,
+			__builtin_ffs((int)DA9062AA_BUCK4_GPI_MASK) - 1,
+			sizeof(unsigned int) * 8 -
+			__builtin_clz(DA9062AA_BUCK4_GPI_MASK) - 1),
 	},
 	{
 		.desc.id = DA9062_ID_LDO1,
@@ -892,6 +947,10 @@ static const struct da9062_regulator_info local_da9062_regulator_info[] = {
 			__builtin_ffs((int)DA9062AA_VLDO1_GPI_MASK) - 1,
 			sizeof(unsigned int) * 8 -
 			__builtin_clz(DA9062AA_VLDO1_GPI_MASK) - 1),
+		.ena_gpi = REG_FIELD(DA9062AA_LDO1_CONT,
+			__builtin_ffs((int)DA9062AA_LDO1_GPI_MASK) - 1,
+			sizeof(unsigned int) * 8 -
+			__builtin_clz(DA9062AA_LDO1_GPI_MASK) - 1),
 		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
 			__builtin_ffs((int)DA9062AA_LDO1_ILIM_MASK) - 1,
 			sizeof(unsigned int) * 8 -
@@ -930,6 +989,10 @@ static const struct da9062_regulator_info local_da9062_regulator_info[] = {
 			__builtin_ffs((int)DA9062AA_VLDO2_GPI_MASK) - 1,
 			sizeof(unsigned int) * 8 -
 			__builtin_clz(DA9062AA_VLDO2_GPI_MASK) - 1),
+		.ena_gpi = REG_FIELD(DA9062AA_LDO2_CONT,
+			__builtin_ffs((int)DA9062AA_LDO2_GPI_MASK) - 1,
+			sizeof(unsigned int) * 8 -
+			__builtin_clz(DA9062AA_LDO2_GPI_MASK) - 1),
 		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
 			__builtin_ffs((int)DA9062AA_LDO2_ILIM_MASK) - 1,
 			sizeof(unsigned int) * 8 -
@@ -968,6 +1031,10 @@ static const struct da9062_regulator_info local_da9062_regulator_info[] = {
 			__builtin_ffs((int)DA9062AA_VLDO3_GPI_MASK) - 1,
 			sizeof(unsigned int) * 8 -
 			__builtin_clz(DA9062AA_VLDO3_GPI_MASK) - 1),
+		.ena_gpi = REG_FIELD(DA9062AA_LDO3_CONT,
+			__builtin_ffs((int)DA9062AA_LDO3_GPI_MASK) - 1,
+			sizeof(unsigned int) * 8 -
+			__builtin_clz(DA9062AA_LDO3_GPI_MASK) - 1),
 		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
 			__builtin_ffs((int)DA9062AA_LDO3_ILIM_MASK) - 1,
 			sizeof(unsigned int) * 8 -
@@ -1006,6 +1073,10 @@ static const struct da9062_regulator_info local_da9062_regulator_info[] = {
 			__builtin_ffs((int)DA9062AA_VLDO4_GPI_MASK) - 1,
 			sizeof(unsigned int) * 8 -
 			__builtin_clz(DA9062AA_VLDO4_GPI_MASK) - 1),
+		.ena_gpi = REG_FIELD(DA9062AA_LDO4_CONT,
+			__builtin_ffs((int)DA9062AA_LDO4_GPI_MASK) - 1,
+			sizeof(unsigned int) * 8 -
+			__builtin_clz(DA9062AA_LDO4_GPI_MASK) - 1),
 		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
 			__builtin_ffs((int)DA9062AA_LDO4_ILIM_MASK) - 1,
 			sizeof(unsigned int) * 8 -
@@ -1135,6 +1206,15 @@ static int da9062_regulator_probe(struct platform_device *pdev)
 				return PTR_ERR(regl->vsel_gpi);
 		}
 
+		if (regl->info->ena_gpi.reg) {
+			regl->ena_gpi = devm_regmap_field_alloc(
+					&pdev->dev,
+					chip->regmap,
+					regl->info->ena_gpi);
+			if (IS_ERR(regl->ena_gpi))
+				return PTR_ERR(regl->ena_gpi);
+		}
+
 		/* Register regulator */
 		memset(&config, 0, sizeof(config));
 		config.dev = chip->dev;
-- 
2.20.1


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

* Re: [PATCH 3/5] regulator: da9062: add voltage selection gpio support
  2019-09-17 12:42 ` [PATCH 3/5] regulator: da9062: add voltage selection gpio support Marco Felsch
@ 2019-09-17 14:22   ` kbuild test robot
  2019-09-17 14:34     ` Marco Felsch
  2019-09-24  9:48   ` Adam Thomson
  2019-10-04 19:41   ` Linus Walleij
  2 siblings, 1 reply; 29+ messages in thread
From: kbuild test robot @ 2019-09-17 14:22 UTC (permalink / raw)
  To: Marco Felsch
  Cc: kbuild-all, support.opensource, lee.jones, robh+dt, lgirdwood,
	broonie, stwiss.opensource, kernel, devicetree, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 1686 bytes --]

Hi Marco,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on linus/master]
[cannot apply to v5.3 next-20190916]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Marco-Felsch/DA9062-PMIC-fixes-and-features/20190917-205911
config: x86_64-randconfig-e004-201937 (attached as .config)
compiler: gcc-7 (Debian 7.4.0-11) 7.4.0
reproduce:
        # save the attached .config to linux build tree
        make ARCH=x86_64 

If you fix the issue, kindly add following tag
Reported-by: kbuild test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

>> drivers/regulator/da9062-regulator.c:19:10: fatal error: linux/mfd/da9062/gpio.h: No such file or directory
    #include <linux/mfd/da9062/gpio.h>
             ^~~~~~~~~~~~~~~~~~~~~~~~~
   compilation terminated.

vim +19 drivers/regulator/da9062-regulator.c

     5	
     6	#include <linux/kernel.h>
     7	#include <linux/module.h>
     8	#include <linux/init.h>
     9	#include <linux/err.h>
    10	#include <linux/gpio/consumer.h>
    11	#include <linux/slab.h>
    12	#include <linux/of.h>
    13	#include <linux/platform_device.h>
    14	#include <linux/regmap.h>
    15	#include <linux/regulator/driver.h>
    16	#include <linux/regulator/machine.h>
    17	#include <linux/regulator/of_regulator.h>
    18	#include <linux/mfd/da9062/core.h>
  > 19	#include <linux/mfd/da9062/gpio.h>
    20	#include <linux/mfd/da9062/registers.h>
    21	

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 35179 bytes --]

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

* Re: [PATCH 3/5] regulator: da9062: add voltage selection gpio support
  2019-09-17 14:22   ` kbuild test robot
@ 2019-09-17 14:34     ` Marco Felsch
  0 siblings, 0 replies; 29+ messages in thread
From: Marco Felsch @ 2019-09-17 14:34 UTC (permalink / raw)
  To: support.opensource
  Cc: support.opensource, lee.jones, robh+dt, lgirdwood, broonie,
	stwiss.opensource, kernel, devicetree, linux-kernel

Hi,

please ignore this error because the kbuild don't apply the dependency I
noted in the cover-letter.

Regards,
  Marco

On 19-09-17 22:22, kbuild test robot wrote:
> Hi Marco,
> 
> Thank you for the patch! Yet something to improve:
> 
> [auto build test ERROR on linus/master]
> [cannot apply to v5.3 next-20190916]
> [if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
> 
> url:    https://github.com/0day-ci/linux/commits/Marco-Felsch/DA9062-PMIC-fixes-and-features/20190917-205911
> config: x86_64-randconfig-e004-201937 (attached as .config)
> compiler: gcc-7 (Debian 7.4.0-11) 7.4.0
> reproduce:
>         # save the attached .config to linux build tree
>         make ARCH=x86_64 
> 
> If you fix the issue, kindly add following tag
> Reported-by: kbuild test robot <lkp@intel.com>
> 
> All errors (new ones prefixed by >>):
> 
> >> drivers/regulator/da9062-regulator.c:19:10: fatal error: linux/mfd/da9062/gpio.h: No such file or directory
>     #include <linux/mfd/da9062/gpio.h>
>              ^~~~~~~~~~~~~~~~~~~~~~~~~
>    compilation terminated.
> 
> vim +19 drivers/regulator/da9062-regulator.c
> 
>      5	
>      6	#include <linux/kernel.h>
>      7	#include <linux/module.h>
>      8	#include <linux/init.h>
>      9	#include <linux/err.h>
>     10	#include <linux/gpio/consumer.h>
>     11	#include <linux/slab.h>
>     12	#include <linux/of.h>
>     13	#include <linux/platform_device.h>
>     14	#include <linux/regmap.h>
>     15	#include <linux/regulator/driver.h>
>     16	#include <linux/regulator/machine.h>
>     17	#include <linux/regulator/of_regulator.h>
>     18	#include <linux/mfd/da9062/core.h>
>   > 19	#include <linux/mfd/da9062/gpio.h>
>     20	#include <linux/mfd/da9062/registers.h>
>     21	
> 
> ---
> 0-DAY kernel test infrastructure                Open Source Technology Center
> https://lists.01.org/pipermail/kbuild-all                   Intel Corporation



-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

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

* RE: [PATCH 1/5] regulator: da9062: fix suspend_enable/disable preparation
  2019-09-17 12:42 ` [PATCH 1/5] regulator: da9062: fix suspend_enable/disable preparation Marco Felsch
@ 2019-09-18 12:41   ` Adam Thomson
  2019-09-18 15:05     ` Marco Felsch
  2019-09-23 16:03   ` Adam Thomson
  2019-09-23 21:23   ` Applied "regulator: da9062: fix suspend_enable/disable preparation" to the regulator tree Mark Brown
  2 siblings, 1 reply; 29+ messages in thread
From: Adam Thomson @ 2019-09-18 12:41 UTC (permalink / raw)
  To: Marco Felsch, Support Opensource, lee.jones, robh+dt, lgirdwood, broonie
  Cc: kernel, devicetree, linux-kernel

On 17 September 2019 13:43, Marco Felsch wrote:

> Currently the suspend reg_field maps to the pmic voltage selection bits
> and is used during suspend_enabe/disable() and during get_mode(). This
> seems to be wrong for both use cases.

Hi Marco,

I'd be very surprised if what was in place was wrong as I know Stephen tested
this driver thoroughly over its lifetime. Regardless, I'll need some time to review
your proposed updates to make sure this aligns with our expectation of operation.

> 
> Use case one (suspend_enabe/disable):
> Those callbacks are used to mark a regulator device as enabled/disabled
> during suspend. Marking the regulator enabled during suspend is done by
> the LDOx_CONF/BUCKx_CONF bit within the LDOx_CONT/BUCKx_CONT
> registers.
> Setting this bit tells the DA9062 PMIC state machine to keep the
> regulator on in POWERDOWN mode and switch to suspend voltage.
> 
> Use case two (get_mode):
> The get_mode callback is used to retrieve the active mode state. Since
> the regulator-setting-A is used for the active state and
> regulator-setting-B for the suspend state there is no need to check
> which regulator setting is active.
> 
> Fixes: 4068e5182ada ("regulator: da9062: DA9062 regulator driver")
> Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
> ---
>  drivers/regulator/da9062-regulator.c | 118 +++++++++++----------------
>  1 file changed, 47 insertions(+), 71 deletions(-)
> 
> diff --git a/drivers/regulator/da9062-regulator.c b/drivers/regulator/da9062-
> regulator.c
> index 2ffc64622451..9b2ca472f70c 100644
> --- a/drivers/regulator/da9062-regulator.c
> +++ b/drivers/regulator/da9062-regulator.c
> @@ -136,7 +136,6 @@ static int da9062_buck_set_mode(struct regulator_dev
> *rdev, unsigned mode)
>  static unsigned da9062_buck_get_mode(struct regulator_dev *rdev)
>  {
>  	struct da9062_regulator *regl = rdev_get_drvdata(rdev);
> -	struct regmap_field *field;
>  	unsigned int val, mode = 0;
>  	int ret;
> 
> @@ -158,18 +157,7 @@ static unsigned da9062_buck_get_mode(struct
> regulator_dev *rdev)
>  		return REGULATOR_MODE_NORMAL;
>  	}
> 
> -	/* Detect current regulator state */
> -	ret = regmap_field_read(regl->suspend, &val);
> -	if (ret < 0)
> -		return 0;
> -
> -	/* Read regulator mode from proper register, depending on state */
> -	if (val)
> -		field = regl->suspend_sleep;
> -	else
> -		field = regl->sleep;
> -
> -	ret = regmap_field_read(field, &val);
> +	ret = regmap_field_read(regl->sleep, &val);
>  	if (ret < 0)
>  		return 0;
> 
> @@ -208,21 +196,9 @@ static int da9062_ldo_set_mode(struct regulator_dev
> *rdev, unsigned mode)
>  static unsigned da9062_ldo_get_mode(struct regulator_dev *rdev)
>  {
>  	struct da9062_regulator *regl = rdev_get_drvdata(rdev);
> -	struct regmap_field *field;
>  	int ret, val;
> 
> -	/* Detect current regulator state */
> -	ret = regmap_field_read(regl->suspend, &val);
> -	if (ret < 0)
> -		return 0;
> -
> -	/* Read regulator mode from proper register, depending on state */
> -	if (val)
> -		field = regl->suspend_sleep;
> -	else
> -		field = regl->sleep;
> -
> -	ret = regmap_field_read(field, &val);
> +	ret = regmap_field_read(regl->sleep, &val);
>  	if (ret < 0)
>  		return 0;
> 
> @@ -408,10 +384,10 @@ static const struct da9062_regulator_info
> local_da9061_regulator_info[] = {
>  			__builtin_ffs((int)DA9062AA_BUCK1_MODE_MASK) - 1,
>  			sizeof(unsigned int) * 8 -
>  			__builtin_clz((DA9062AA_BUCK1_MODE_MASK)) - 1),
> -		.suspend = REG_FIELD(DA9062AA_DVC_1,
> -			__builtin_ffs((int)DA9062AA_VBUCK1_SEL_MASK) - 1,
> +		.suspend = REG_FIELD(DA9062AA_BUCK1_CONT,
> +			__builtin_ffs((int)DA9062AA_BUCK1_CONF_MASK) - 1,
>  			sizeof(unsigned int) * 8 -
> -			__builtin_clz((DA9062AA_VBUCK1_SEL_MASK)) - 1),
> +			__builtin_clz(DA9062AA_BUCK1_CONF_MASK) - 1),
>  	},
>  	{
>  		.desc.id = DA9061_ID_BUCK2,
> @@ -444,10 +420,10 @@ static const struct da9062_regulator_info
> local_da9061_regulator_info[] = {
>  			__builtin_ffs((int)DA9062AA_BUCK3_MODE_MASK) - 1,
>  			sizeof(unsigned int) * 8 -
>  			__builtin_clz((DA9062AA_BUCK3_MODE_MASK)) - 1),
> -		.suspend = REG_FIELD(DA9062AA_DVC_1,
> -			__builtin_ffs((int)DA9062AA_VBUCK3_SEL_MASK) - 1,
> +		.suspend = REG_FIELD(DA9062AA_BUCK3_CONT,
> +			__builtin_ffs((int)DA9062AA_BUCK3_CONF_MASK) - 1,
>  			sizeof(unsigned int) * 8 -
> -			__builtin_clz((DA9062AA_VBUCK3_SEL_MASK)) - 1),
> +			__builtin_clz(DA9062AA_BUCK3_CONF_MASK) - 1),
>  	},
>  	{
>  		.desc.id = DA9061_ID_BUCK3,
> @@ -480,10 +456,10 @@ static const struct da9062_regulator_info
> local_da9061_regulator_info[] = {
>  			__builtin_ffs((int)DA9062AA_BUCK4_MODE_MASK) - 1,
>  			sizeof(unsigned int) * 8 -
>  			__builtin_clz((DA9062AA_BUCK4_MODE_MASK)) - 1),
> -		.suspend = REG_FIELD(DA9062AA_DVC_1,
> -			__builtin_ffs((int)DA9062AA_VBUCK4_SEL_MASK) - 1,
> +		.suspend = REG_FIELD(DA9062AA_BUCK4_CONT,
> +			__builtin_ffs((int)DA9062AA_BUCK4_CONF_MASK) - 1,
>  			sizeof(unsigned int) * 8 -
> -			__builtin_clz((DA9062AA_VBUCK4_SEL_MASK)) - 1),
> +			__builtin_clz(DA9062AA_BUCK4_CONF_MASK) - 1),
>  	},
>  	{
>  		.desc.id = DA9061_ID_LDO1,
> @@ -509,10 +485,10 @@ static const struct da9062_regulator_info
> local_da9061_regulator_info[] = {
>  			sizeof(unsigned int) * 8 -
>  			__builtin_clz((DA9062AA_LDO1_SL_B_MASK)) - 1),
>  		.suspend_vsel_reg = DA9062AA_VLDO1_B,
> -		.suspend = REG_FIELD(DA9062AA_DVC_1,
> -			__builtin_ffs((int)DA9062AA_VLDO1_SEL_MASK) - 1,
> +		.suspend = REG_FIELD(DA9062AA_LDO1_CONT,
> +			__builtin_ffs((int)DA9062AA_LDO1_CONF_MASK) - 1,
>  			sizeof(unsigned int) * 8 -
> -			__builtin_clz((DA9062AA_VLDO1_SEL_MASK)) - 1),
> +			__builtin_clz(DA9062AA_LDO1_CONF_MASK) - 1),
>  		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
>  			__builtin_ffs((int)DA9062AA_LDO1_ILIM_MASK) - 1,
>  			sizeof(unsigned int) * 8 -
> @@ -542,10 +518,10 @@ static const struct da9062_regulator_info
> local_da9061_regulator_info[] = {
>  			sizeof(unsigned int) * 8 -
>  			__builtin_clz((DA9062AA_LDO2_SL_B_MASK)) - 1),
>  		.suspend_vsel_reg = DA9062AA_VLDO2_B,
> -		.suspend = REG_FIELD(DA9062AA_DVC_1,
> -			__builtin_ffs((int)DA9062AA_VLDO2_SEL_MASK) - 1,
> +		.suspend = REG_FIELD(DA9062AA_LDO2_CONT,
> +			__builtin_ffs((int)DA9062AA_LDO2_CONF_MASK) - 1,
>  			sizeof(unsigned int) * 8 -
> -			__builtin_clz((DA9062AA_VLDO2_SEL_MASK)) - 1),
> +			__builtin_clz(DA9062AA_LDO2_CONF_MASK) - 1),
>  		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
>  			__builtin_ffs((int)DA9062AA_LDO2_ILIM_MASK) - 1,
>  			sizeof(unsigned int) * 8 -
> @@ -575,10 +551,10 @@ static const struct da9062_regulator_info
> local_da9061_regulator_info[] = {
>  			sizeof(unsigned int) * 8 -
>  			__builtin_clz((DA9062AA_LDO3_SL_B_MASK)) - 1),
>  		.suspend_vsel_reg = DA9062AA_VLDO3_B,
> -		.suspend = REG_FIELD(DA9062AA_DVC_1,
> -			__builtin_ffs((int)DA9062AA_VLDO3_SEL_MASK) - 1,
> +		.suspend = REG_FIELD(DA9062AA_LDO3_CONT,
> +			__builtin_ffs((int)DA9062AA_LDO3_CONF_MASK) - 1,
>  			sizeof(unsigned int) * 8 -
> -			__builtin_clz((DA9062AA_VLDO3_SEL_MASK)) - 1),
> +			__builtin_clz(DA9062AA_LDO3_CONF_MASK) - 1),
>  		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
>  			__builtin_ffs((int)DA9062AA_LDO3_ILIM_MASK) - 1,
>  			sizeof(unsigned int) * 8 -
> @@ -608,10 +584,10 @@ static const struct da9062_regulator_info
> local_da9061_regulator_info[] = {
>  			sizeof(unsigned int) * 8 -
>  			__builtin_clz((DA9062AA_LDO4_SL_B_MASK)) - 1),
>  		.suspend_vsel_reg = DA9062AA_VLDO4_B,
> -		.suspend = REG_FIELD(DA9062AA_DVC_1,
> -			__builtin_ffs((int)DA9062AA_VLDO4_SEL_MASK) - 1,
> +		.suspend = REG_FIELD(DA9062AA_LDO4_CONT,
> +			__builtin_ffs((int)DA9062AA_LDO4_CONF_MASK) - 1,
>  			sizeof(unsigned int) * 8 -
> -			__builtin_clz((DA9062AA_VLDO4_SEL_MASK)) - 1),
> +			__builtin_clz(DA9062AA_LDO4_CONF_MASK) - 1),
>  		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
>  			__builtin_ffs((int)DA9062AA_LDO4_ILIM_MASK) - 1,
>  			sizeof(unsigned int) * 8 -
> @@ -652,10 +628,10 @@ static const struct da9062_regulator_info
> local_da9062_regulator_info[] = {
>  			__builtin_ffs((int)DA9062AA_BUCK1_MODE_MASK) - 1,
>  			sizeof(unsigned int) * 8 -
>  			__builtin_clz((DA9062AA_BUCK1_MODE_MASK)) - 1),
> -		.suspend = REG_FIELD(DA9062AA_DVC_1,
> -			__builtin_ffs((int)DA9062AA_VBUCK1_SEL_MASK) - 1,
> +		.suspend = REG_FIELD(DA9062AA_BUCK1_CONT,
> +			__builtin_ffs((int)DA9062AA_BUCK1_CONF_MASK) - 1,
>  			sizeof(unsigned int) * 8 -
> -			__builtin_clz((DA9062AA_VBUCK1_SEL_MASK)) - 1),
> +			__builtin_clz(DA9062AA_BUCK1_CONF_MASK) - 1),
>  	},
>  	{
>  		.desc.id = DA9062_ID_BUCK2,
> @@ -688,10 +664,10 @@ static const struct da9062_regulator_info
> local_da9062_regulator_info[] = {
>  			__builtin_ffs((int)DA9062AA_BUCK2_MODE_MASK) - 1,
>  			sizeof(unsigned int) * 8 -
>  			__builtin_clz((DA9062AA_BUCK2_MODE_MASK)) - 1),
> -		.suspend = REG_FIELD(DA9062AA_DVC_1,
> -			__builtin_ffs((int)DA9062AA_VBUCK2_SEL_MASK) - 1,
> +		.suspend = REG_FIELD(DA9062AA_BUCK2_CONT,
> +			__builtin_ffs((int)DA9062AA_BUCK2_CONF_MASK) - 1,
>  			sizeof(unsigned int) * 8 -
> -			__builtin_clz((DA9062AA_VBUCK2_SEL_MASK)) - 1),
> +			__builtin_clz(DA9062AA_BUCK2_CONF_MASK) - 1),
>  	},
>  	{
>  		.desc.id = DA9062_ID_BUCK3,
> @@ -724,10 +700,10 @@ static const struct da9062_regulator_info
> local_da9062_regulator_info[] = {
>  			__builtin_ffs((int)DA9062AA_BUCK3_MODE_MASK) - 1,
>  			sizeof(unsigned int) * 8 -
>  			__builtin_clz((DA9062AA_BUCK3_MODE_MASK)) - 1),
> -		.suspend = REG_FIELD(DA9062AA_DVC_1,
> -			__builtin_ffs((int)DA9062AA_VBUCK3_SEL_MASK) - 1,
> +		.suspend = REG_FIELD(DA9062AA_BUCK3_CONT,
> +			__builtin_ffs((int)DA9062AA_BUCK3_CONF_MASK) - 1,
>  			sizeof(unsigned int) * 8 -
> -			__builtin_clz((DA9062AA_VBUCK3_SEL_MASK)) - 1),
> +			__builtin_clz(DA9062AA_BUCK3_CONF_MASK) - 1),
>  	},
>  	{
>  		.desc.id = DA9062_ID_BUCK4,
> @@ -760,10 +736,10 @@ static const struct da9062_regulator_info
> local_da9062_regulator_info[] = {
>  			__builtin_ffs((int)DA9062AA_BUCK4_MODE_MASK) - 1,
>  			sizeof(unsigned int) * 8 -
>  			__builtin_clz((DA9062AA_BUCK4_MODE_MASK)) - 1),
> -		.suspend = REG_FIELD(DA9062AA_DVC_1,
> -			__builtin_ffs((int)DA9062AA_VBUCK4_SEL_MASK) - 1,
> +		.suspend = REG_FIELD(DA9062AA_BUCK4_CONT,
> +			__builtin_ffs((int)DA9062AA_BUCK4_CONF_MASK) - 1,
>  			sizeof(unsigned int) * 8 -
> -			__builtin_clz((DA9062AA_VBUCK4_SEL_MASK)) - 1),
> +			__builtin_clz(DA9062AA_BUCK4_CONF_MASK) - 1),
>  	},
>  	{
>  		.desc.id = DA9062_ID_LDO1,
> @@ -789,10 +765,10 @@ static const struct da9062_regulator_info
> local_da9062_regulator_info[] = {
>  			sizeof(unsigned int) * 8 -
>  			__builtin_clz((DA9062AA_LDO1_SL_B_MASK)) - 1),
>  		.suspend_vsel_reg = DA9062AA_VLDO1_B,
> -		.suspend = REG_FIELD(DA9062AA_DVC_1,
> -			__builtin_ffs((int)DA9062AA_VLDO1_SEL_MASK) - 1,
> +		.suspend = REG_FIELD(DA9062AA_LDO1_CONT,
> +			__builtin_ffs((int)DA9062AA_LDO1_CONF_MASK) - 1,
>  			sizeof(unsigned int) * 8 -
> -			__builtin_clz((DA9062AA_VLDO1_SEL_MASK)) - 1),
> +			__builtin_clz(DA9062AA_LDO1_CONF_MASK) - 1),
>  		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
>  			__builtin_ffs((int)DA9062AA_LDO1_ILIM_MASK) - 1,
>  			sizeof(unsigned int) * 8 -
> @@ -822,10 +798,10 @@ static const struct da9062_regulator_info
> local_da9062_regulator_info[] = {
>  			sizeof(unsigned int) * 8 -
>  			__builtin_clz((DA9062AA_LDO2_SL_B_MASK)) - 1),
>  		.suspend_vsel_reg = DA9062AA_VLDO2_B,
> -		.suspend = REG_FIELD(DA9062AA_DVC_1,
> -			__builtin_ffs((int)DA9062AA_VLDO2_SEL_MASK) - 1,
> +		.suspend = REG_FIELD(DA9062AA_LDO2_CONT,
> +			__builtin_ffs((int)DA9062AA_LDO2_CONF_MASK) - 1,
>  			sizeof(unsigned int) * 8 -
> -			__builtin_clz((DA9062AA_VLDO2_SEL_MASK)) - 1),
> +			__builtin_clz(DA9062AA_LDO2_CONF_MASK) - 1),
>  		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
>  			__builtin_ffs((int)DA9062AA_LDO2_ILIM_MASK) - 1,
>  			sizeof(unsigned int) * 8 -
> @@ -855,10 +831,10 @@ static const struct da9062_regulator_info
> local_da9062_regulator_info[] = {
>  			sizeof(unsigned int) * 8 -
>  			__builtin_clz((DA9062AA_LDO3_SL_B_MASK)) - 1),
>  		.suspend_vsel_reg = DA9062AA_VLDO3_B,
> -		.suspend = REG_FIELD(DA9062AA_DVC_1,
> -			__builtin_ffs((int)DA9062AA_VLDO3_SEL_MASK) - 1,
> +		.suspend = REG_FIELD(DA9062AA_LDO3_CONT,
> +			__builtin_ffs((int)DA9062AA_LDO3_CONF_MASK) - 1,
>  			sizeof(unsigned int) * 8 -
> -			__builtin_clz((DA9062AA_VLDO3_SEL_MASK)) - 1),
> +			__builtin_clz(DA9062AA_LDO3_CONF_MASK) - 1),
>  		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
>  			__builtin_ffs((int)DA9062AA_LDO3_ILIM_MASK) - 1,
>  			sizeof(unsigned int) * 8 -
> @@ -888,10 +864,10 @@ static const struct da9062_regulator_info
> local_da9062_regulator_info[] = {
>  			sizeof(unsigned int) * 8 -
>  			__builtin_clz((DA9062AA_LDO4_SL_B_MASK)) - 1),
>  		.suspend_vsel_reg = DA9062AA_VLDO4_B,
> -		.suspend = REG_FIELD(DA9062AA_DVC_1,
> -			__builtin_ffs((int)DA9062AA_VLDO4_SEL_MASK) - 1,
> +		.suspend = REG_FIELD(DA9062AA_LDO4_CONT,
> +			__builtin_ffs((int)DA9062AA_LDO4_CONF_MASK) - 1,
>  			sizeof(unsigned int) * 8 -
> -			__builtin_clz((DA9062AA_VLDO4_SEL_MASK)) - 1),
> +			__builtin_clz(DA9062AA_LDO4_CONF_MASK) - 1),
>  		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
>  			__builtin_ffs((int)DA9062AA_LDO4_ILIM_MASK) - 1,
>  			sizeof(unsigned int) * 8 -
> --
> 2.20.1


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

* Re: [PATCH 1/5] regulator: da9062: fix suspend_enable/disable preparation
  2019-09-18 12:41   ` Adam Thomson
@ 2019-09-18 15:05     ` Marco Felsch
  0 siblings, 0 replies; 29+ messages in thread
From: Marco Felsch @ 2019-09-18 15:05 UTC (permalink / raw)
  To: Adam Thomson
  Cc: Support Opensource, lee.jones, robh+dt, lgirdwood, broonie,
	kernel, devicetree, linux-kernel

Hi Adam,

On 19-09-18 12:41, Adam Thomson wrote:
> On 17 September 2019 13:43, Marco Felsch wrote:
> 
> > Currently the suspend reg_field maps to the pmic voltage selection bits
> > and is used during suspend_enabe/disable() and during get_mode(). This
> > seems to be wrong for both use cases.
> 
> Hi Marco,
> 
> I'd be very surprised if what was in place was wrong as I know Stephen tested
> this driver thoroughly over its lifetime. Regardless, I'll need some time to review
> your proposed updates to make sure this aligns with our expectation of operation.

Thanks for the upcoming review.

Regards,
  Marco


> > 
> > Use case one (suspend_enabe/disable):
> > Those callbacks are used to mark a regulator device as enabled/disabled
> > during suspend. Marking the regulator enabled during suspend is done by
> > the LDOx_CONF/BUCKx_CONF bit within the LDOx_CONT/BUCKx_CONT
> > registers.
> > Setting this bit tells the DA9062 PMIC state machine to keep the
> > regulator on in POWERDOWN mode and switch to suspend voltage.
> > 
> > Use case two (get_mode):
> > The get_mode callback is used to retrieve the active mode state. Since
> > the regulator-setting-A is used for the active state and
> > regulator-setting-B for the suspend state there is no need to check
> > which regulator setting is active.
> > 
> > Fixes: 4068e5182ada ("regulator: da9062: DA9062 regulator driver")
> > Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
> > ---
> >  drivers/regulator/da9062-regulator.c | 118 +++++++++++----------------
> >  1 file changed, 47 insertions(+), 71 deletions(-)
> > 
> > diff --git a/drivers/regulator/da9062-regulator.c b/drivers/regulator/da9062-
> > regulator.c
> > index 2ffc64622451..9b2ca472f70c 100644
> > --- a/drivers/regulator/da9062-regulator.c
> > +++ b/drivers/regulator/da9062-regulator.c
> > @@ -136,7 +136,6 @@ static int da9062_buck_set_mode(struct regulator_dev
> > *rdev, unsigned mode)
> >  static unsigned da9062_buck_get_mode(struct regulator_dev *rdev)
> >  {
> >  	struct da9062_regulator *regl = rdev_get_drvdata(rdev);
> > -	struct regmap_field *field;
> >  	unsigned int val, mode = 0;
> >  	int ret;
> > 
> > @@ -158,18 +157,7 @@ static unsigned da9062_buck_get_mode(struct
> > regulator_dev *rdev)
> >  		return REGULATOR_MODE_NORMAL;
> >  	}
> > 
> > -	/* Detect current regulator state */
> > -	ret = regmap_field_read(regl->suspend, &val);
> > -	if (ret < 0)
> > -		return 0;
> > -
> > -	/* Read regulator mode from proper register, depending on state */
> > -	if (val)
> > -		field = regl->suspend_sleep;
> > -	else
> > -		field = regl->sleep;
> > -
> > -	ret = regmap_field_read(field, &val);
> > +	ret = regmap_field_read(regl->sleep, &val);
> >  	if (ret < 0)
> >  		return 0;
> > 
> > @@ -208,21 +196,9 @@ static int da9062_ldo_set_mode(struct regulator_dev
> > *rdev, unsigned mode)
> >  static unsigned da9062_ldo_get_mode(struct regulator_dev *rdev)
> >  {
> >  	struct da9062_regulator *regl = rdev_get_drvdata(rdev);
> > -	struct regmap_field *field;
> >  	int ret, val;
> > 
> > -	/* Detect current regulator state */
> > -	ret = regmap_field_read(regl->suspend, &val);
> > -	if (ret < 0)
> > -		return 0;
> > -
> > -	/* Read regulator mode from proper register, depending on state */
> > -	if (val)
> > -		field = regl->suspend_sleep;
> > -	else
> > -		field = regl->sleep;
> > -
> > -	ret = regmap_field_read(field, &val);
> > +	ret = regmap_field_read(regl->sleep, &val);
> >  	if (ret < 0)
> >  		return 0;
> > 
> > @@ -408,10 +384,10 @@ static const struct da9062_regulator_info
> > local_da9061_regulator_info[] = {
> >  			__builtin_ffs((int)DA9062AA_BUCK1_MODE_MASK) - 1,
> >  			sizeof(unsigned int) * 8 -
> >  			__builtin_clz((DA9062AA_BUCK1_MODE_MASK)) - 1),
> > -		.suspend = REG_FIELD(DA9062AA_DVC_1,
> > -			__builtin_ffs((int)DA9062AA_VBUCK1_SEL_MASK) - 1,
> > +		.suspend = REG_FIELD(DA9062AA_BUCK1_CONT,
> > +			__builtin_ffs((int)DA9062AA_BUCK1_CONF_MASK) - 1,
> >  			sizeof(unsigned int) * 8 -
> > -			__builtin_clz((DA9062AA_VBUCK1_SEL_MASK)) - 1),
> > +			__builtin_clz(DA9062AA_BUCK1_CONF_MASK) - 1),
> >  	},
> >  	{
> >  		.desc.id = DA9061_ID_BUCK2,
> > @@ -444,10 +420,10 @@ static const struct da9062_regulator_info
> > local_da9061_regulator_info[] = {
> >  			__builtin_ffs((int)DA9062AA_BUCK3_MODE_MASK) - 1,
> >  			sizeof(unsigned int) * 8 -
> >  			__builtin_clz((DA9062AA_BUCK3_MODE_MASK)) - 1),
> > -		.suspend = REG_FIELD(DA9062AA_DVC_1,
> > -			__builtin_ffs((int)DA9062AA_VBUCK3_SEL_MASK) - 1,
> > +		.suspend = REG_FIELD(DA9062AA_BUCK3_CONT,
> > +			__builtin_ffs((int)DA9062AA_BUCK3_CONF_MASK) - 1,
> >  			sizeof(unsigned int) * 8 -
> > -			__builtin_clz((DA9062AA_VBUCK3_SEL_MASK)) - 1),
> > +			__builtin_clz(DA9062AA_BUCK3_CONF_MASK) - 1),
> >  	},
> >  	{
> >  		.desc.id = DA9061_ID_BUCK3,
> > @@ -480,10 +456,10 @@ static const struct da9062_regulator_info
> > local_da9061_regulator_info[] = {
> >  			__builtin_ffs((int)DA9062AA_BUCK4_MODE_MASK) - 1,
> >  			sizeof(unsigned int) * 8 -
> >  			__builtin_clz((DA9062AA_BUCK4_MODE_MASK)) - 1),
> > -		.suspend = REG_FIELD(DA9062AA_DVC_1,
> > -			__builtin_ffs((int)DA9062AA_VBUCK4_SEL_MASK) - 1,
> > +		.suspend = REG_FIELD(DA9062AA_BUCK4_CONT,
> > +			__builtin_ffs((int)DA9062AA_BUCK4_CONF_MASK) - 1,
> >  			sizeof(unsigned int) * 8 -
> > -			__builtin_clz((DA9062AA_VBUCK4_SEL_MASK)) - 1),
> > +			__builtin_clz(DA9062AA_BUCK4_CONF_MASK) - 1),
> >  	},
> >  	{
> >  		.desc.id = DA9061_ID_LDO1,
> > @@ -509,10 +485,10 @@ static const struct da9062_regulator_info
> > local_da9061_regulator_info[] = {
> >  			sizeof(unsigned int) * 8 -
> >  			__builtin_clz((DA9062AA_LDO1_SL_B_MASK)) - 1),
> >  		.suspend_vsel_reg = DA9062AA_VLDO1_B,
> > -		.suspend = REG_FIELD(DA9062AA_DVC_1,
> > -			__builtin_ffs((int)DA9062AA_VLDO1_SEL_MASK) - 1,
> > +		.suspend = REG_FIELD(DA9062AA_LDO1_CONT,
> > +			__builtin_ffs((int)DA9062AA_LDO1_CONF_MASK) - 1,
> >  			sizeof(unsigned int) * 8 -
> > -			__builtin_clz((DA9062AA_VLDO1_SEL_MASK)) - 1),
> > +			__builtin_clz(DA9062AA_LDO1_CONF_MASK) - 1),
> >  		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
> >  			__builtin_ffs((int)DA9062AA_LDO1_ILIM_MASK) - 1,
> >  			sizeof(unsigned int) * 8 -
> > @@ -542,10 +518,10 @@ static const struct da9062_regulator_info
> > local_da9061_regulator_info[] = {
> >  			sizeof(unsigned int) * 8 -
> >  			__builtin_clz((DA9062AA_LDO2_SL_B_MASK)) - 1),
> >  		.suspend_vsel_reg = DA9062AA_VLDO2_B,
> > -		.suspend = REG_FIELD(DA9062AA_DVC_1,
> > -			__builtin_ffs((int)DA9062AA_VLDO2_SEL_MASK) - 1,
> > +		.suspend = REG_FIELD(DA9062AA_LDO2_CONT,
> > +			__builtin_ffs((int)DA9062AA_LDO2_CONF_MASK) - 1,
> >  			sizeof(unsigned int) * 8 -
> > -			__builtin_clz((DA9062AA_VLDO2_SEL_MASK)) - 1),
> > +			__builtin_clz(DA9062AA_LDO2_CONF_MASK) - 1),
> >  		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
> >  			__builtin_ffs((int)DA9062AA_LDO2_ILIM_MASK) - 1,
> >  			sizeof(unsigned int) * 8 -
> > @@ -575,10 +551,10 @@ static const struct da9062_regulator_info
> > local_da9061_regulator_info[] = {
> >  			sizeof(unsigned int) * 8 -
> >  			__builtin_clz((DA9062AA_LDO3_SL_B_MASK)) - 1),
> >  		.suspend_vsel_reg = DA9062AA_VLDO3_B,
> > -		.suspend = REG_FIELD(DA9062AA_DVC_1,
> > -			__builtin_ffs((int)DA9062AA_VLDO3_SEL_MASK) - 1,
> > +		.suspend = REG_FIELD(DA9062AA_LDO3_CONT,
> > +			__builtin_ffs((int)DA9062AA_LDO3_CONF_MASK) - 1,
> >  			sizeof(unsigned int) * 8 -
> > -			__builtin_clz((DA9062AA_VLDO3_SEL_MASK)) - 1),
> > +			__builtin_clz(DA9062AA_LDO3_CONF_MASK) - 1),
> >  		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
> >  			__builtin_ffs((int)DA9062AA_LDO3_ILIM_MASK) - 1,
> >  			sizeof(unsigned int) * 8 -
> > @@ -608,10 +584,10 @@ static const struct da9062_regulator_info
> > local_da9061_regulator_info[] = {
> >  			sizeof(unsigned int) * 8 -
> >  			__builtin_clz((DA9062AA_LDO4_SL_B_MASK)) - 1),
> >  		.suspend_vsel_reg = DA9062AA_VLDO4_B,
> > -		.suspend = REG_FIELD(DA9062AA_DVC_1,
> > -			__builtin_ffs((int)DA9062AA_VLDO4_SEL_MASK) - 1,
> > +		.suspend = REG_FIELD(DA9062AA_LDO4_CONT,
> > +			__builtin_ffs((int)DA9062AA_LDO4_CONF_MASK) - 1,
> >  			sizeof(unsigned int) * 8 -
> > -			__builtin_clz((DA9062AA_VLDO4_SEL_MASK)) - 1),
> > +			__builtin_clz(DA9062AA_LDO4_CONF_MASK) - 1),
> >  		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
> >  			__builtin_ffs((int)DA9062AA_LDO4_ILIM_MASK) - 1,
> >  			sizeof(unsigned int) * 8 -
> > @@ -652,10 +628,10 @@ static const struct da9062_regulator_info
> > local_da9062_regulator_info[] = {
> >  			__builtin_ffs((int)DA9062AA_BUCK1_MODE_MASK) - 1,
> >  			sizeof(unsigned int) * 8 -
> >  			__builtin_clz((DA9062AA_BUCK1_MODE_MASK)) - 1),
> > -		.suspend = REG_FIELD(DA9062AA_DVC_1,
> > -			__builtin_ffs((int)DA9062AA_VBUCK1_SEL_MASK) - 1,
> > +		.suspend = REG_FIELD(DA9062AA_BUCK1_CONT,
> > +			__builtin_ffs((int)DA9062AA_BUCK1_CONF_MASK) - 1,
> >  			sizeof(unsigned int) * 8 -
> > -			__builtin_clz((DA9062AA_VBUCK1_SEL_MASK)) - 1),
> > +			__builtin_clz(DA9062AA_BUCK1_CONF_MASK) - 1),
> >  	},
> >  	{
> >  		.desc.id = DA9062_ID_BUCK2,
> > @@ -688,10 +664,10 @@ static const struct da9062_regulator_info
> > local_da9062_regulator_info[] = {
> >  			__builtin_ffs((int)DA9062AA_BUCK2_MODE_MASK) - 1,
> >  			sizeof(unsigned int) * 8 -
> >  			__builtin_clz((DA9062AA_BUCK2_MODE_MASK)) - 1),
> > -		.suspend = REG_FIELD(DA9062AA_DVC_1,
> > -			__builtin_ffs((int)DA9062AA_VBUCK2_SEL_MASK) - 1,
> > +		.suspend = REG_FIELD(DA9062AA_BUCK2_CONT,
> > +			__builtin_ffs((int)DA9062AA_BUCK2_CONF_MASK) - 1,
> >  			sizeof(unsigned int) * 8 -
> > -			__builtin_clz((DA9062AA_VBUCK2_SEL_MASK)) - 1),
> > +			__builtin_clz(DA9062AA_BUCK2_CONF_MASK) - 1),
> >  	},
> >  	{
> >  		.desc.id = DA9062_ID_BUCK3,
> > @@ -724,10 +700,10 @@ static const struct da9062_regulator_info
> > local_da9062_regulator_info[] = {
> >  			__builtin_ffs((int)DA9062AA_BUCK3_MODE_MASK) - 1,
> >  			sizeof(unsigned int) * 8 -
> >  			__builtin_clz((DA9062AA_BUCK3_MODE_MASK)) - 1),
> > -		.suspend = REG_FIELD(DA9062AA_DVC_1,
> > -			__builtin_ffs((int)DA9062AA_VBUCK3_SEL_MASK) - 1,
> > +		.suspend = REG_FIELD(DA9062AA_BUCK3_CONT,
> > +			__builtin_ffs((int)DA9062AA_BUCK3_CONF_MASK) - 1,
> >  			sizeof(unsigned int) * 8 -
> > -			__builtin_clz((DA9062AA_VBUCK3_SEL_MASK)) - 1),
> > +			__builtin_clz(DA9062AA_BUCK3_CONF_MASK) - 1),
> >  	},
> >  	{
> >  		.desc.id = DA9062_ID_BUCK4,
> > @@ -760,10 +736,10 @@ static const struct da9062_regulator_info
> > local_da9062_regulator_info[] = {
> >  			__builtin_ffs((int)DA9062AA_BUCK4_MODE_MASK) - 1,
> >  			sizeof(unsigned int) * 8 -
> >  			__builtin_clz((DA9062AA_BUCK4_MODE_MASK)) - 1),
> > -		.suspend = REG_FIELD(DA9062AA_DVC_1,
> > -			__builtin_ffs((int)DA9062AA_VBUCK4_SEL_MASK) - 1,
> > +		.suspend = REG_FIELD(DA9062AA_BUCK4_CONT,
> > +			__builtin_ffs((int)DA9062AA_BUCK4_CONF_MASK) - 1,
> >  			sizeof(unsigned int) * 8 -
> > -			__builtin_clz((DA9062AA_VBUCK4_SEL_MASK)) - 1),
> > +			__builtin_clz(DA9062AA_BUCK4_CONF_MASK) - 1),
> >  	},
> >  	{
> >  		.desc.id = DA9062_ID_LDO1,
> > @@ -789,10 +765,10 @@ static const struct da9062_regulator_info
> > local_da9062_regulator_info[] = {
> >  			sizeof(unsigned int) * 8 -
> >  			__builtin_clz((DA9062AA_LDO1_SL_B_MASK)) - 1),
> >  		.suspend_vsel_reg = DA9062AA_VLDO1_B,
> > -		.suspend = REG_FIELD(DA9062AA_DVC_1,
> > -			__builtin_ffs((int)DA9062AA_VLDO1_SEL_MASK) - 1,
> > +		.suspend = REG_FIELD(DA9062AA_LDO1_CONT,
> > +			__builtin_ffs((int)DA9062AA_LDO1_CONF_MASK) - 1,
> >  			sizeof(unsigned int) * 8 -
> > -			__builtin_clz((DA9062AA_VLDO1_SEL_MASK)) - 1),
> > +			__builtin_clz(DA9062AA_LDO1_CONF_MASK) - 1),
> >  		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
> >  			__builtin_ffs((int)DA9062AA_LDO1_ILIM_MASK) - 1,
> >  			sizeof(unsigned int) * 8 -
> > @@ -822,10 +798,10 @@ static const struct da9062_regulator_info
> > local_da9062_regulator_info[] = {
> >  			sizeof(unsigned int) * 8 -
> >  			__builtin_clz((DA9062AA_LDO2_SL_B_MASK)) - 1),
> >  		.suspend_vsel_reg = DA9062AA_VLDO2_B,
> > -		.suspend = REG_FIELD(DA9062AA_DVC_1,
> > -			__builtin_ffs((int)DA9062AA_VLDO2_SEL_MASK) - 1,
> > +		.suspend = REG_FIELD(DA9062AA_LDO2_CONT,
> > +			__builtin_ffs((int)DA9062AA_LDO2_CONF_MASK) - 1,
> >  			sizeof(unsigned int) * 8 -
> > -			__builtin_clz((DA9062AA_VLDO2_SEL_MASK)) - 1),
> > +			__builtin_clz(DA9062AA_LDO2_CONF_MASK) - 1),
> >  		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
> >  			__builtin_ffs((int)DA9062AA_LDO2_ILIM_MASK) - 1,
> >  			sizeof(unsigned int) * 8 -
> > @@ -855,10 +831,10 @@ static const struct da9062_regulator_info
> > local_da9062_regulator_info[] = {
> >  			sizeof(unsigned int) * 8 -
> >  			__builtin_clz((DA9062AA_LDO3_SL_B_MASK)) - 1),
> >  		.suspend_vsel_reg = DA9062AA_VLDO3_B,
> > -		.suspend = REG_FIELD(DA9062AA_DVC_1,
> > -			__builtin_ffs((int)DA9062AA_VLDO3_SEL_MASK) - 1,
> > +		.suspend = REG_FIELD(DA9062AA_LDO3_CONT,
> > +			__builtin_ffs((int)DA9062AA_LDO3_CONF_MASK) - 1,
> >  			sizeof(unsigned int) * 8 -
> > -			__builtin_clz((DA9062AA_VLDO3_SEL_MASK)) - 1),
> > +			__builtin_clz(DA9062AA_LDO3_CONF_MASK) - 1),
> >  		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
> >  			__builtin_ffs((int)DA9062AA_LDO3_ILIM_MASK) - 1,
> >  			sizeof(unsigned int) * 8 -
> > @@ -888,10 +864,10 @@ static const struct da9062_regulator_info
> > local_da9062_regulator_info[] = {
> >  			sizeof(unsigned int) * 8 -
> >  			__builtin_clz((DA9062AA_LDO4_SL_B_MASK)) - 1),
> >  		.suspend_vsel_reg = DA9062AA_VLDO4_B,
> > -		.suspend = REG_FIELD(DA9062AA_DVC_1,
> > -			__builtin_ffs((int)DA9062AA_VLDO4_SEL_MASK) - 1,
> > +		.suspend = REG_FIELD(DA9062AA_LDO4_CONT,
> > +			__builtin_ffs((int)DA9062AA_LDO4_CONF_MASK) - 1,
> >  			sizeof(unsigned int) * 8 -
> > -			__builtin_clz((DA9062AA_VLDO4_SEL_MASK)) - 1),
> > +			__builtin_clz(DA9062AA_LDO4_CONF_MASK) - 1),
> >  		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
> >  			__builtin_ffs((int)DA9062AA_LDO4_ILIM_MASK) - 1,
> >  			sizeof(unsigned int) * 8 -
> > --
> > 2.20.1
> 
> 

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

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

* RE: [PATCH 1/5] regulator: da9062: fix suspend_enable/disable preparation
  2019-09-17 12:42 ` [PATCH 1/5] regulator: da9062: fix suspend_enable/disable preparation Marco Felsch
  2019-09-18 12:41   ` Adam Thomson
@ 2019-09-23 16:03   ` Adam Thomson
  2019-09-23 22:02     ` Marco Felsch
  2019-09-23 21:23   ` Applied "regulator: da9062: fix suspend_enable/disable preparation" to the regulator tree Mark Brown
  2 siblings, 1 reply; 29+ messages in thread
From: Adam Thomson @ 2019-09-23 16:03 UTC (permalink / raw)
  To: Marco Felsch, Support Opensource, lee.jones, robh+dt, lgirdwood,
	broonie, Steve Twiss
  Cc: kernel, devicetree, linux-kernel

On 17 September 2019 13:43, Marco Felsch wrote:

> Currently the suspend reg_field maps to the pmic voltage selection bits
> and is used during suspend_enabe/disable() and during get_mode(). This
> seems to be wrong for both use cases.
>
> Use case one (suspend_enabe/disable):
> Those callbacks are used to mark a regulator device as enabled/disabled
> during suspend. Marking the regulator enabled during suspend is done by
> the LDOx_CONF/BUCKx_CONF bit within the LDOx_CONT/BUCKx_CONT
> registers.
> Setting this bit tells the DA9062 PMIC state machine to keep the
> regulator on in POWERDOWN mode and switch to suspend voltage.
>
> Use case two (get_mode):
> The get_mode callback is used to retrieve the active mode state. Since
> the regulator-setting-A is used for the active state and
> regulator-setting-B for the suspend state there is no need to check
> which regulator setting is active.
>

So I believe you're correct with the above statements. The driver, rather than
enabling/disabling a regulator in system suspend, will instead put the regulator
to a low power state, which is definitely not the desired outcome. Thanks for
rectifying this.

Reviewed-by: Adam Thomson <Adam.Thomson.Opensource@diasemi.com>

> Fixes: 4068e5182ada ("regulator: da9062: DA9062 regulator driver")
> Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
> ---
>  drivers/regulator/da9062-regulator.c | 118 +++++++++++----------------
>  1 file changed, 47 insertions(+), 71 deletions(-)
>
> diff --git a/drivers/regulator/da9062-regulator.c b/drivers/regulator/da9062-
> regulator.c
> index 2ffc64622451..9b2ca472f70c 100644
> --- a/drivers/regulator/da9062-regulator.c
> +++ b/drivers/regulator/da9062-regulator.c
> @@ -136,7 +136,6 @@ static int da9062_buck_set_mode(struct regulator_dev
> *rdev, unsigned mode)
>  static unsigned da9062_buck_get_mode(struct regulator_dev *rdev)
>  {
>  	struct da9062_regulator *regl = rdev_get_drvdata(rdev);
> -	struct regmap_field *field;
>  	unsigned int val, mode = 0;
>  	int ret;
>
> @@ -158,18 +157,7 @@ static unsigned da9062_buck_get_mode(struct
> regulator_dev *rdev)
>  		return REGULATOR_MODE_NORMAL;
>  	}
>
> -	/* Detect current regulator state */
> -	ret = regmap_field_read(regl->suspend, &val);
> -	if (ret < 0)
> -		return 0;
> -
> -	/* Read regulator mode from proper register, depending on state */
> -	if (val)
> -		field = regl->suspend_sleep;
> -	else
> -		field = regl->sleep;
> -
> -	ret = regmap_field_read(field, &val);
> +	ret = regmap_field_read(regl->sleep, &val);
>  	if (ret < 0)
>  		return 0;
>
> @@ -208,21 +196,9 @@ static int da9062_ldo_set_mode(struct regulator_dev
> *rdev, unsigned mode)
>  static unsigned da9062_ldo_get_mode(struct regulator_dev *rdev)
>  {
>  	struct da9062_regulator *regl = rdev_get_drvdata(rdev);
> -	struct regmap_field *field;
>  	int ret, val;
>
> -	/* Detect current regulator state */
> -	ret = regmap_field_read(regl->suspend, &val);
> -	if (ret < 0)
> -		return 0;
> -
> -	/* Read regulator mode from proper register, depending on state */
> -	if (val)
> -		field = regl->suspend_sleep;
> -	else
> -		field = regl->sleep;
> -
> -	ret = regmap_field_read(field, &val);
> +	ret = regmap_field_read(regl->sleep, &val);
>  	if (ret < 0)
>  		return 0;
>
> @@ -408,10 +384,10 @@ static const struct da9062_regulator_info
> local_da9061_regulator_info[] = {
>  			__builtin_ffs((int)DA9062AA_BUCK1_MODE_MASK) - 1,
>  			sizeof(unsigned int) * 8 -
>  			__builtin_clz((DA9062AA_BUCK1_MODE_MASK)) - 1),
> -		.suspend = REG_FIELD(DA9062AA_DVC_1,
> -			__builtin_ffs((int)DA9062AA_VBUCK1_SEL_MASK) - 1,
> +		.suspend = REG_FIELD(DA9062AA_BUCK1_CONT,
> +			__builtin_ffs((int)DA9062AA_BUCK1_CONF_MASK) - 1,
>  			sizeof(unsigned int) * 8 -
> -			__builtin_clz((DA9062AA_VBUCK1_SEL_MASK)) - 1),
> +			__builtin_clz(DA9062AA_BUCK1_CONF_MASK) - 1),
>  	},
>  	{
>  		.desc.id = DA9061_ID_BUCK2,
> @@ -444,10 +420,10 @@ static const struct da9062_regulator_info
> local_da9061_regulator_info[] = {
>  			__builtin_ffs((int)DA9062AA_BUCK3_MODE_MASK) - 1,
>  			sizeof(unsigned int) * 8 -
>  			__builtin_clz((DA9062AA_BUCK3_MODE_MASK)) - 1),
> -		.suspend = REG_FIELD(DA9062AA_DVC_1,
> -			__builtin_ffs((int)DA9062AA_VBUCK3_SEL_MASK) - 1,
> +		.suspend = REG_FIELD(DA9062AA_BUCK3_CONT,
> +			__builtin_ffs((int)DA9062AA_BUCK3_CONF_MASK) - 1,
>  			sizeof(unsigned int) * 8 -
> -			__builtin_clz((DA9062AA_VBUCK3_SEL_MASK)) - 1),
> +			__builtin_clz(DA9062AA_BUCK3_CONF_MASK) - 1),
>  	},
>  	{
>  		.desc.id = DA9061_ID_BUCK3,
> @@ -480,10 +456,10 @@ static const struct da9062_regulator_info
> local_da9061_regulator_info[] = {
>  			__builtin_ffs((int)DA9062AA_BUCK4_MODE_MASK) - 1,
>  			sizeof(unsigned int) * 8 -
>  			__builtin_clz((DA9062AA_BUCK4_MODE_MASK)) - 1),
> -		.suspend = REG_FIELD(DA9062AA_DVC_1,
> -			__builtin_ffs((int)DA9062AA_VBUCK4_SEL_MASK) - 1,
> +		.suspend = REG_FIELD(DA9062AA_BUCK4_CONT,
> +			__builtin_ffs((int)DA9062AA_BUCK4_CONF_MASK) - 1,
>  			sizeof(unsigned int) * 8 -
> -			__builtin_clz((DA9062AA_VBUCK4_SEL_MASK)) - 1),
> +			__builtin_clz(DA9062AA_BUCK4_CONF_MASK) - 1),
>  	},
>  	{
>  		.desc.id = DA9061_ID_LDO1,
> @@ -509,10 +485,10 @@ static const struct da9062_regulator_info
> local_da9061_regulator_info[] = {
>  			sizeof(unsigned int) * 8 -
>  			__builtin_clz((DA9062AA_LDO1_SL_B_MASK)) - 1),
>  		.suspend_vsel_reg = DA9062AA_VLDO1_B,
> -		.suspend = REG_FIELD(DA9062AA_DVC_1,
> -			__builtin_ffs((int)DA9062AA_VLDO1_SEL_MASK) - 1,
> +		.suspend = REG_FIELD(DA9062AA_LDO1_CONT,
> +			__builtin_ffs((int)DA9062AA_LDO1_CONF_MASK) - 1,
>  			sizeof(unsigned int) * 8 -
> -			__builtin_clz((DA9062AA_VLDO1_SEL_MASK)) - 1),
> +			__builtin_clz(DA9062AA_LDO1_CONF_MASK) - 1),
>  		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
>  			__builtin_ffs((int)DA9062AA_LDO1_ILIM_MASK) - 1,
>  			sizeof(unsigned int) * 8 -
> @@ -542,10 +518,10 @@ static const struct da9062_regulator_info
> local_da9061_regulator_info[] = {
>  			sizeof(unsigned int) * 8 -
>  			__builtin_clz((DA9062AA_LDO2_SL_B_MASK)) - 1),
>  		.suspend_vsel_reg = DA9062AA_VLDO2_B,
> -		.suspend = REG_FIELD(DA9062AA_DVC_1,
> -			__builtin_ffs((int)DA9062AA_VLDO2_SEL_MASK) - 1,
> +		.suspend = REG_FIELD(DA9062AA_LDO2_CONT,
> +			__builtin_ffs((int)DA9062AA_LDO2_CONF_MASK) - 1,
>  			sizeof(unsigned int) * 8 -
> -			__builtin_clz((DA9062AA_VLDO2_SEL_MASK)) - 1),
> +			__builtin_clz(DA9062AA_LDO2_CONF_MASK) - 1),
>  		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
>  			__builtin_ffs((int)DA9062AA_LDO2_ILIM_MASK) - 1,
>  			sizeof(unsigned int) * 8 -
> @@ -575,10 +551,10 @@ static const struct da9062_regulator_info
> local_da9061_regulator_info[] = {
>  			sizeof(unsigned int) * 8 -
>  			__builtin_clz((DA9062AA_LDO3_SL_B_MASK)) - 1),
>  		.suspend_vsel_reg = DA9062AA_VLDO3_B,
> -		.suspend = REG_FIELD(DA9062AA_DVC_1,
> -			__builtin_ffs((int)DA9062AA_VLDO3_SEL_MASK) - 1,
> +		.suspend = REG_FIELD(DA9062AA_LDO3_CONT,
> +			__builtin_ffs((int)DA9062AA_LDO3_CONF_MASK) - 1,
>  			sizeof(unsigned int) * 8 -
> -			__builtin_clz((DA9062AA_VLDO3_SEL_MASK)) - 1),
> +			__builtin_clz(DA9062AA_LDO3_CONF_MASK) - 1),
>  		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
>  			__builtin_ffs((int)DA9062AA_LDO3_ILIM_MASK) - 1,
>  			sizeof(unsigned int) * 8 -
> @@ -608,10 +584,10 @@ static const struct da9062_regulator_info
> local_da9061_regulator_info[] = {
>  			sizeof(unsigned int) * 8 -
>  			__builtin_clz((DA9062AA_LDO4_SL_B_MASK)) - 1),
>  		.suspend_vsel_reg = DA9062AA_VLDO4_B,
> -		.suspend = REG_FIELD(DA9062AA_DVC_1,
> -			__builtin_ffs((int)DA9062AA_VLDO4_SEL_MASK) - 1,
> +		.suspend = REG_FIELD(DA9062AA_LDO4_CONT,
> +			__builtin_ffs((int)DA9062AA_LDO4_CONF_MASK) - 1,
>  			sizeof(unsigned int) * 8 -
> -			__builtin_clz((DA9062AA_VLDO4_SEL_MASK)) - 1),
> +			__builtin_clz(DA9062AA_LDO4_CONF_MASK) - 1),
>  		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
>  			__builtin_ffs((int)DA9062AA_LDO4_ILIM_MASK) - 1,
>  			sizeof(unsigned int) * 8 -
> @@ -652,10 +628,10 @@ static const struct da9062_regulator_info
> local_da9062_regulator_info[] = {
>  			__builtin_ffs((int)DA9062AA_BUCK1_MODE_MASK) - 1,
>  			sizeof(unsigned int) * 8 -
>  			__builtin_clz((DA9062AA_BUCK1_MODE_MASK)) - 1),
> -		.suspend = REG_FIELD(DA9062AA_DVC_1,
> -			__builtin_ffs((int)DA9062AA_VBUCK1_SEL_MASK) - 1,
> +		.suspend = REG_FIELD(DA9062AA_BUCK1_CONT,
> +			__builtin_ffs((int)DA9062AA_BUCK1_CONF_MASK) - 1,
>  			sizeof(unsigned int) * 8 -
> -			__builtin_clz((DA9062AA_VBUCK1_SEL_MASK)) - 1),
> +			__builtin_clz(DA9062AA_BUCK1_CONF_MASK) - 1),
>  	},
>  	{
>  		.desc.id = DA9062_ID_BUCK2,
> @@ -688,10 +664,10 @@ static const struct da9062_regulator_info
> local_da9062_regulator_info[] = {
>  			__builtin_ffs((int)DA9062AA_BUCK2_MODE_MASK) - 1,
>  			sizeof(unsigned int) * 8 -
>  			__builtin_clz((DA9062AA_BUCK2_MODE_MASK)) - 1),
> -		.suspend = REG_FIELD(DA9062AA_DVC_1,
> -			__builtin_ffs((int)DA9062AA_VBUCK2_SEL_MASK) - 1,
> +		.suspend = REG_FIELD(DA9062AA_BUCK2_CONT,
> +			__builtin_ffs((int)DA9062AA_BUCK2_CONF_MASK) - 1,
>  			sizeof(unsigned int) * 8 -
> -			__builtin_clz((DA9062AA_VBUCK2_SEL_MASK)) - 1),
> +			__builtin_clz(DA9062AA_BUCK2_CONF_MASK) - 1),
>  	},
>  	{
>  		.desc.id = DA9062_ID_BUCK3,
> @@ -724,10 +700,10 @@ static const struct da9062_regulator_info
> local_da9062_regulator_info[] = {
>  			__builtin_ffs((int)DA9062AA_BUCK3_MODE_MASK) - 1,
>  			sizeof(unsigned int) * 8 -
>  			__builtin_clz((DA9062AA_BUCK3_MODE_MASK)) - 1),
> -		.suspend = REG_FIELD(DA9062AA_DVC_1,
> -			__builtin_ffs((int)DA9062AA_VBUCK3_SEL_MASK) - 1,
> +		.suspend = REG_FIELD(DA9062AA_BUCK3_CONT,
> +			__builtin_ffs((int)DA9062AA_BUCK3_CONF_MASK) - 1,
>  			sizeof(unsigned int) * 8 -
> -			__builtin_clz((DA9062AA_VBUCK3_SEL_MASK)) - 1),
> +			__builtin_clz(DA9062AA_BUCK3_CONF_MASK) - 1),
>  	},
>  	{
>  		.desc.id = DA9062_ID_BUCK4,
> @@ -760,10 +736,10 @@ static const struct da9062_regulator_info
> local_da9062_regulator_info[] = {
>  			__builtin_ffs((int)DA9062AA_BUCK4_MODE_MASK) - 1,
>  			sizeof(unsigned int) * 8 -
>  			__builtin_clz((DA9062AA_BUCK4_MODE_MASK)) - 1),
> -		.suspend = REG_FIELD(DA9062AA_DVC_1,
> -			__builtin_ffs((int)DA9062AA_VBUCK4_SEL_MASK) - 1,
> +		.suspend = REG_FIELD(DA9062AA_BUCK4_CONT,
> +			__builtin_ffs((int)DA9062AA_BUCK4_CONF_MASK) - 1,
>  			sizeof(unsigned int) * 8 -
> -			__builtin_clz((DA9062AA_VBUCK4_SEL_MASK)) - 1),
> +			__builtin_clz(DA9062AA_BUCK4_CONF_MASK) - 1),
>  	},
>  	{
>  		.desc.id = DA9062_ID_LDO1,
> @@ -789,10 +765,10 @@ static const struct da9062_regulator_info
> local_da9062_regulator_info[] = {
>  			sizeof(unsigned int) * 8 -
>  			__builtin_clz((DA9062AA_LDO1_SL_B_MASK)) - 1),
>  		.suspend_vsel_reg = DA9062AA_VLDO1_B,
> -		.suspend = REG_FIELD(DA9062AA_DVC_1,
> -			__builtin_ffs((int)DA9062AA_VLDO1_SEL_MASK) - 1,
> +		.suspend = REG_FIELD(DA9062AA_LDO1_CONT,
> +			__builtin_ffs((int)DA9062AA_LDO1_CONF_MASK) - 1,
>  			sizeof(unsigned int) * 8 -
> -			__builtin_clz((DA9062AA_VLDO1_SEL_MASK)) - 1),
> +			__builtin_clz(DA9062AA_LDO1_CONF_MASK) - 1),
>  		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
>  			__builtin_ffs((int)DA9062AA_LDO1_ILIM_MASK) - 1,
>  			sizeof(unsigned int) * 8 -
> @@ -822,10 +798,10 @@ static const struct da9062_regulator_info
> local_da9062_regulator_info[] = {
>  			sizeof(unsigned int) * 8 -
>  			__builtin_clz((DA9062AA_LDO2_SL_B_MASK)) - 1),
>  		.suspend_vsel_reg = DA9062AA_VLDO2_B,
> -		.suspend = REG_FIELD(DA9062AA_DVC_1,
> -			__builtin_ffs((int)DA9062AA_VLDO2_SEL_MASK) - 1,
> +		.suspend = REG_FIELD(DA9062AA_LDO2_CONT,
> +			__builtin_ffs((int)DA9062AA_LDO2_CONF_MASK) - 1,
>  			sizeof(unsigned int) * 8 -
> -			__builtin_clz((DA9062AA_VLDO2_SEL_MASK)) - 1),
> +			__builtin_clz(DA9062AA_LDO2_CONF_MASK) - 1),
>  		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
>  			__builtin_ffs((int)DA9062AA_LDO2_ILIM_MASK) - 1,
>  			sizeof(unsigned int) * 8 -
> @@ -855,10 +831,10 @@ static const struct da9062_regulator_info
> local_da9062_regulator_info[] = {
>  			sizeof(unsigned int) * 8 -
>  			__builtin_clz((DA9062AA_LDO3_SL_B_MASK)) - 1),
>  		.suspend_vsel_reg = DA9062AA_VLDO3_B,
> -		.suspend = REG_FIELD(DA9062AA_DVC_1,
> -			__builtin_ffs((int)DA9062AA_VLDO3_SEL_MASK) - 1,
> +		.suspend = REG_FIELD(DA9062AA_LDO3_CONT,
> +			__builtin_ffs((int)DA9062AA_LDO3_CONF_MASK) - 1,
>  			sizeof(unsigned int) * 8 -
> -			__builtin_clz((DA9062AA_VLDO3_SEL_MASK)) - 1),
> +			__builtin_clz(DA9062AA_LDO3_CONF_MASK) - 1),
>  		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
>  			__builtin_ffs((int)DA9062AA_LDO3_ILIM_MASK) - 1,
>  			sizeof(unsigned int) * 8 -
> @@ -888,10 +864,10 @@ static const struct da9062_regulator_info
> local_da9062_regulator_info[] = {
>  			sizeof(unsigned int) * 8 -
>  			__builtin_clz((DA9062AA_LDO4_SL_B_MASK)) - 1),
>  		.suspend_vsel_reg = DA9062AA_VLDO4_B,
> -		.suspend = REG_FIELD(DA9062AA_DVC_1,
> -			__builtin_ffs((int)DA9062AA_VLDO4_SEL_MASK) - 1,
> +		.suspend = REG_FIELD(DA9062AA_LDO4_CONT,
> +			__builtin_ffs((int)DA9062AA_LDO4_CONF_MASK) - 1,
>  			sizeof(unsigned int) * 8 -
> -			__builtin_clz((DA9062AA_VLDO4_SEL_MASK)) - 1),
> +			__builtin_clz(DA9062AA_LDO4_CONF_MASK) - 1),
>  		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
>  			__builtin_ffs((int)DA9062AA_LDO4_ILIM_MASK) - 1,
>  			sizeof(unsigned int) * 8 -
> --
> 2.20.1


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

* Applied "regulator: da9062: fix suspend_enable/disable preparation" to the regulator tree
  2019-09-17 12:42 ` [PATCH 1/5] regulator: da9062: fix suspend_enable/disable preparation Marco Felsch
  2019-09-18 12:41   ` Adam Thomson
  2019-09-23 16:03   ` Adam Thomson
@ 2019-09-23 21:23   ` Mark Brown
  2 siblings, 0 replies; 29+ messages in thread
From: Mark Brown @ 2019-09-23 21:23 UTC (permalink / raw)
  To: Marco Felsch
  Cc: broonie, devicetree, kernel, lee.jones, lgirdwood, linux-kernel,
	Mark Brown, robh+dt, stwiss.opensource, support.opensource

The patch

   regulator: da9062: fix suspend_enable/disable preparation

has been applied to the regulator tree at

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator.git for-5.4

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.  

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark

From a72865f057820ea9f57597915da4b651d65eb92f Mon Sep 17 00:00:00 2001
From: Marco Felsch <m.felsch@pengutronix.de>
Date: Tue, 17 Sep 2019 14:42:42 +0200
Subject: [PATCH] regulator: da9062: fix suspend_enable/disable preparation

Currently the suspend reg_field maps to the pmic voltage selection bits
and is used during suspend_enabe/disable() and during get_mode(). This
seems to be wrong for both use cases.

Use case one (suspend_enabe/disable):
Those callbacks are used to mark a regulator device as enabled/disabled
during suspend. Marking the regulator enabled during suspend is done by
the LDOx_CONF/BUCKx_CONF bit within the LDOx_CONT/BUCKx_CONT registers.
Setting this bit tells the DA9062 PMIC state machine to keep the
regulator on in POWERDOWN mode and switch to suspend voltage.

Use case two (get_mode):
The get_mode callback is used to retrieve the active mode state. Since
the regulator-setting-A is used for the active state and
regulator-setting-B for the suspend state there is no need to check
which regulator setting is active.

Fixes: 4068e5182ada ("regulator: da9062: DA9062 regulator driver")
Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
Reviewed-by: Adam Thomson <Adam.Thomson.Opensource@diasemi.com>
Link: https://lore.kernel.org/r/20190917124246.11732-2-m.felsch@pengutronix.de
Signed-off-by: Mark Brown <broonie@kernel.org>
---
 drivers/regulator/da9062-regulator.c | 118 +++++++++++----------------
 1 file changed, 47 insertions(+), 71 deletions(-)

diff --git a/drivers/regulator/da9062-regulator.c b/drivers/regulator/da9062-regulator.c
index 56f3f72d7707..710e67081d53 100644
--- a/drivers/regulator/da9062-regulator.c
+++ b/drivers/regulator/da9062-regulator.c
@@ -136,7 +136,6 @@ static int da9062_buck_set_mode(struct regulator_dev *rdev, unsigned mode)
 static unsigned da9062_buck_get_mode(struct regulator_dev *rdev)
 {
 	struct da9062_regulator *regl = rdev_get_drvdata(rdev);
-	struct regmap_field *field;
 	unsigned int val, mode = 0;
 	int ret;
 
@@ -158,18 +157,7 @@ static unsigned da9062_buck_get_mode(struct regulator_dev *rdev)
 		return REGULATOR_MODE_NORMAL;
 	}
 
-	/* Detect current regulator state */
-	ret = regmap_field_read(regl->suspend, &val);
-	if (ret < 0)
-		return 0;
-
-	/* Read regulator mode from proper register, depending on state */
-	if (val)
-		field = regl->suspend_sleep;
-	else
-		field = regl->sleep;
-
-	ret = regmap_field_read(field, &val);
+	ret = regmap_field_read(regl->sleep, &val);
 	if (ret < 0)
 		return 0;
 
@@ -208,21 +196,9 @@ static int da9062_ldo_set_mode(struct regulator_dev *rdev, unsigned mode)
 static unsigned da9062_ldo_get_mode(struct regulator_dev *rdev)
 {
 	struct da9062_regulator *regl = rdev_get_drvdata(rdev);
-	struct regmap_field *field;
 	int ret, val;
 
-	/* Detect current regulator state */
-	ret = regmap_field_read(regl->suspend, &val);
-	if (ret < 0)
-		return 0;
-
-	/* Read regulator mode from proper register, depending on state */
-	if (val)
-		field = regl->suspend_sleep;
-	else
-		field = regl->sleep;
-
-	ret = regmap_field_read(field, &val);
+	ret = regmap_field_read(regl->sleep, &val);
 	if (ret < 0)
 		return 0;
 
@@ -408,10 +384,10 @@ static const struct da9062_regulator_info local_da9061_regulator_info[] = {
 			__builtin_ffs((int)DA9062AA_BUCK1_MODE_MASK) - 1,
 			sizeof(unsigned int) * 8 -
 			__builtin_clz((DA9062AA_BUCK1_MODE_MASK)) - 1),
-		.suspend = REG_FIELD(DA9062AA_DVC_1,
-			__builtin_ffs((int)DA9062AA_VBUCK1_SEL_MASK) - 1,
+		.suspend = REG_FIELD(DA9062AA_BUCK1_CONT,
+			__builtin_ffs((int)DA9062AA_BUCK1_CONF_MASK) - 1,
 			sizeof(unsigned int) * 8 -
-			__builtin_clz((DA9062AA_VBUCK1_SEL_MASK)) - 1),
+			__builtin_clz(DA9062AA_BUCK1_CONF_MASK) - 1),
 	},
 	{
 		.desc.id = DA9061_ID_BUCK2,
@@ -444,10 +420,10 @@ static const struct da9062_regulator_info local_da9061_regulator_info[] = {
 			__builtin_ffs((int)DA9062AA_BUCK3_MODE_MASK) - 1,
 			sizeof(unsigned int) * 8 -
 			__builtin_clz((DA9062AA_BUCK3_MODE_MASK)) - 1),
-		.suspend = REG_FIELD(DA9062AA_DVC_1,
-			__builtin_ffs((int)DA9062AA_VBUCK3_SEL_MASK) - 1,
+		.suspend = REG_FIELD(DA9062AA_BUCK3_CONT,
+			__builtin_ffs((int)DA9062AA_BUCK3_CONF_MASK) - 1,
 			sizeof(unsigned int) * 8 -
-			__builtin_clz((DA9062AA_VBUCK3_SEL_MASK)) - 1),
+			__builtin_clz(DA9062AA_BUCK3_CONF_MASK) - 1),
 	},
 	{
 		.desc.id = DA9061_ID_BUCK3,
@@ -480,10 +456,10 @@ static const struct da9062_regulator_info local_da9061_regulator_info[] = {
 			__builtin_ffs((int)DA9062AA_BUCK4_MODE_MASK) - 1,
 			sizeof(unsigned int) * 8 -
 			__builtin_clz((DA9062AA_BUCK4_MODE_MASK)) - 1),
-		.suspend = REG_FIELD(DA9062AA_DVC_1,
-			__builtin_ffs((int)DA9062AA_VBUCK4_SEL_MASK) - 1,
+		.suspend = REG_FIELD(DA9062AA_BUCK4_CONT,
+			__builtin_ffs((int)DA9062AA_BUCK4_CONF_MASK) - 1,
 			sizeof(unsigned int) * 8 -
-			__builtin_clz((DA9062AA_VBUCK4_SEL_MASK)) - 1),
+			__builtin_clz(DA9062AA_BUCK4_CONF_MASK) - 1),
 	},
 	{
 		.desc.id = DA9061_ID_LDO1,
@@ -509,10 +485,10 @@ static const struct da9062_regulator_info local_da9061_regulator_info[] = {
 			sizeof(unsigned int) * 8 -
 			__builtin_clz((DA9062AA_LDO1_SL_B_MASK)) - 1),
 		.suspend_vsel_reg = DA9062AA_VLDO1_B,
-		.suspend = REG_FIELD(DA9062AA_DVC_1,
-			__builtin_ffs((int)DA9062AA_VLDO1_SEL_MASK) - 1,
+		.suspend = REG_FIELD(DA9062AA_LDO1_CONT,
+			__builtin_ffs((int)DA9062AA_LDO1_CONF_MASK) - 1,
 			sizeof(unsigned int) * 8 -
-			__builtin_clz((DA9062AA_VLDO1_SEL_MASK)) - 1),
+			__builtin_clz(DA9062AA_LDO1_CONF_MASK) - 1),
 		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
 			__builtin_ffs((int)DA9062AA_LDO1_ILIM_MASK) - 1,
 			sizeof(unsigned int) * 8 -
@@ -542,10 +518,10 @@ static const struct da9062_regulator_info local_da9061_regulator_info[] = {
 			sizeof(unsigned int) * 8 -
 			__builtin_clz((DA9062AA_LDO2_SL_B_MASK)) - 1),
 		.suspend_vsel_reg = DA9062AA_VLDO2_B,
-		.suspend = REG_FIELD(DA9062AA_DVC_1,
-			__builtin_ffs((int)DA9062AA_VLDO2_SEL_MASK) - 1,
+		.suspend = REG_FIELD(DA9062AA_LDO2_CONT,
+			__builtin_ffs((int)DA9062AA_LDO2_CONF_MASK) - 1,
 			sizeof(unsigned int) * 8 -
-			__builtin_clz((DA9062AA_VLDO2_SEL_MASK)) - 1),
+			__builtin_clz(DA9062AA_LDO2_CONF_MASK) - 1),
 		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
 			__builtin_ffs((int)DA9062AA_LDO2_ILIM_MASK) - 1,
 			sizeof(unsigned int) * 8 -
@@ -575,10 +551,10 @@ static const struct da9062_regulator_info local_da9061_regulator_info[] = {
 			sizeof(unsigned int) * 8 -
 			__builtin_clz((DA9062AA_LDO3_SL_B_MASK)) - 1),
 		.suspend_vsel_reg = DA9062AA_VLDO3_B,
-		.suspend = REG_FIELD(DA9062AA_DVC_1,
-			__builtin_ffs((int)DA9062AA_VLDO3_SEL_MASK) - 1,
+		.suspend = REG_FIELD(DA9062AA_LDO3_CONT,
+			__builtin_ffs((int)DA9062AA_LDO3_CONF_MASK) - 1,
 			sizeof(unsigned int) * 8 -
-			__builtin_clz((DA9062AA_VLDO3_SEL_MASK)) - 1),
+			__builtin_clz(DA9062AA_LDO3_CONF_MASK) - 1),
 		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
 			__builtin_ffs((int)DA9062AA_LDO3_ILIM_MASK) - 1,
 			sizeof(unsigned int) * 8 -
@@ -608,10 +584,10 @@ static const struct da9062_regulator_info local_da9061_regulator_info[] = {
 			sizeof(unsigned int) * 8 -
 			__builtin_clz((DA9062AA_LDO4_SL_B_MASK)) - 1),
 		.suspend_vsel_reg = DA9062AA_VLDO4_B,
-		.suspend = REG_FIELD(DA9062AA_DVC_1,
-			__builtin_ffs((int)DA9062AA_VLDO4_SEL_MASK) - 1,
+		.suspend = REG_FIELD(DA9062AA_LDO4_CONT,
+			__builtin_ffs((int)DA9062AA_LDO4_CONF_MASK) - 1,
 			sizeof(unsigned int) * 8 -
-			__builtin_clz((DA9062AA_VLDO4_SEL_MASK)) - 1),
+			__builtin_clz(DA9062AA_LDO4_CONF_MASK) - 1),
 		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
 			__builtin_ffs((int)DA9062AA_LDO4_ILIM_MASK) - 1,
 			sizeof(unsigned int) * 8 -
@@ -652,10 +628,10 @@ static const struct da9062_regulator_info local_da9062_regulator_info[] = {
 			__builtin_ffs((int)DA9062AA_BUCK1_MODE_MASK) - 1,
 			sizeof(unsigned int) * 8 -
 			__builtin_clz((DA9062AA_BUCK1_MODE_MASK)) - 1),
-		.suspend = REG_FIELD(DA9062AA_DVC_1,
-			__builtin_ffs((int)DA9062AA_VBUCK1_SEL_MASK) - 1,
+		.suspend = REG_FIELD(DA9062AA_BUCK1_CONT,
+			__builtin_ffs((int)DA9062AA_BUCK1_CONF_MASK) - 1,
 			sizeof(unsigned int) * 8 -
-			__builtin_clz((DA9062AA_VBUCK1_SEL_MASK)) - 1),
+			__builtin_clz(DA9062AA_BUCK1_CONF_MASK) - 1),
 	},
 	{
 		.desc.id = DA9062_ID_BUCK2,
@@ -688,10 +664,10 @@ static const struct da9062_regulator_info local_da9062_regulator_info[] = {
 			__builtin_ffs((int)DA9062AA_BUCK2_MODE_MASK) - 1,
 			sizeof(unsigned int) * 8 -
 			__builtin_clz((DA9062AA_BUCK2_MODE_MASK)) - 1),
-		.suspend = REG_FIELD(DA9062AA_DVC_1,
-			__builtin_ffs((int)DA9062AA_VBUCK2_SEL_MASK) - 1,
+		.suspend = REG_FIELD(DA9062AA_BUCK2_CONT,
+			__builtin_ffs((int)DA9062AA_BUCK2_CONF_MASK) - 1,
 			sizeof(unsigned int) * 8 -
-			__builtin_clz((DA9062AA_VBUCK2_SEL_MASK)) - 1),
+			__builtin_clz(DA9062AA_BUCK2_CONF_MASK) - 1),
 	},
 	{
 		.desc.id = DA9062_ID_BUCK3,
@@ -724,10 +700,10 @@ static const struct da9062_regulator_info local_da9062_regulator_info[] = {
 			__builtin_ffs((int)DA9062AA_BUCK3_MODE_MASK) - 1,
 			sizeof(unsigned int) * 8 -
 			__builtin_clz((DA9062AA_BUCK3_MODE_MASK)) - 1),
-		.suspend = REG_FIELD(DA9062AA_DVC_1,
-			__builtin_ffs((int)DA9062AA_VBUCK3_SEL_MASK) - 1,
+		.suspend = REG_FIELD(DA9062AA_BUCK3_CONT,
+			__builtin_ffs((int)DA9062AA_BUCK3_CONF_MASK) - 1,
 			sizeof(unsigned int) * 8 -
-			__builtin_clz((DA9062AA_VBUCK3_SEL_MASK)) - 1),
+			__builtin_clz(DA9062AA_BUCK3_CONF_MASK) - 1),
 	},
 	{
 		.desc.id = DA9062_ID_BUCK4,
@@ -760,10 +736,10 @@ static const struct da9062_regulator_info local_da9062_regulator_info[] = {
 			__builtin_ffs((int)DA9062AA_BUCK4_MODE_MASK) - 1,
 			sizeof(unsigned int) * 8 -
 			__builtin_clz((DA9062AA_BUCK4_MODE_MASK)) - 1),
-		.suspend = REG_FIELD(DA9062AA_DVC_1,
-			__builtin_ffs((int)DA9062AA_VBUCK4_SEL_MASK) - 1,
+		.suspend = REG_FIELD(DA9062AA_BUCK4_CONT,
+			__builtin_ffs((int)DA9062AA_BUCK4_CONF_MASK) - 1,
 			sizeof(unsigned int) * 8 -
-			__builtin_clz((DA9062AA_VBUCK4_SEL_MASK)) - 1),
+			__builtin_clz(DA9062AA_BUCK4_CONF_MASK) - 1),
 	},
 	{
 		.desc.id = DA9062_ID_LDO1,
@@ -789,10 +765,10 @@ static const struct da9062_regulator_info local_da9062_regulator_info[] = {
 			sizeof(unsigned int) * 8 -
 			__builtin_clz((DA9062AA_LDO1_SL_B_MASK)) - 1),
 		.suspend_vsel_reg = DA9062AA_VLDO1_B,
-		.suspend = REG_FIELD(DA9062AA_DVC_1,
-			__builtin_ffs((int)DA9062AA_VLDO1_SEL_MASK) - 1,
+		.suspend = REG_FIELD(DA9062AA_LDO1_CONT,
+			__builtin_ffs((int)DA9062AA_LDO1_CONF_MASK) - 1,
 			sizeof(unsigned int) * 8 -
-			__builtin_clz((DA9062AA_VLDO1_SEL_MASK)) - 1),
+			__builtin_clz(DA9062AA_LDO1_CONF_MASK) - 1),
 		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
 			__builtin_ffs((int)DA9062AA_LDO1_ILIM_MASK) - 1,
 			sizeof(unsigned int) * 8 -
@@ -822,10 +798,10 @@ static const struct da9062_regulator_info local_da9062_regulator_info[] = {
 			sizeof(unsigned int) * 8 -
 			__builtin_clz((DA9062AA_LDO2_SL_B_MASK)) - 1),
 		.suspend_vsel_reg = DA9062AA_VLDO2_B,
-		.suspend = REG_FIELD(DA9062AA_DVC_1,
-			__builtin_ffs((int)DA9062AA_VLDO2_SEL_MASK) - 1,
+		.suspend = REG_FIELD(DA9062AA_LDO2_CONT,
+			__builtin_ffs((int)DA9062AA_LDO2_CONF_MASK) - 1,
 			sizeof(unsigned int) * 8 -
-			__builtin_clz((DA9062AA_VLDO2_SEL_MASK)) - 1),
+			__builtin_clz(DA9062AA_LDO2_CONF_MASK) - 1),
 		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
 			__builtin_ffs((int)DA9062AA_LDO2_ILIM_MASK) - 1,
 			sizeof(unsigned int) * 8 -
@@ -855,10 +831,10 @@ static const struct da9062_regulator_info local_da9062_regulator_info[] = {
 			sizeof(unsigned int) * 8 -
 			__builtin_clz((DA9062AA_LDO3_SL_B_MASK)) - 1),
 		.suspend_vsel_reg = DA9062AA_VLDO3_B,
-		.suspend = REG_FIELD(DA9062AA_DVC_1,
-			__builtin_ffs((int)DA9062AA_VLDO3_SEL_MASK) - 1,
+		.suspend = REG_FIELD(DA9062AA_LDO3_CONT,
+			__builtin_ffs((int)DA9062AA_LDO3_CONF_MASK) - 1,
 			sizeof(unsigned int) * 8 -
-			__builtin_clz((DA9062AA_VLDO3_SEL_MASK)) - 1),
+			__builtin_clz(DA9062AA_LDO3_CONF_MASK) - 1),
 		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
 			__builtin_ffs((int)DA9062AA_LDO3_ILIM_MASK) - 1,
 			sizeof(unsigned int) * 8 -
@@ -888,10 +864,10 @@ static const struct da9062_regulator_info local_da9062_regulator_info[] = {
 			sizeof(unsigned int) * 8 -
 			__builtin_clz((DA9062AA_LDO4_SL_B_MASK)) - 1),
 		.suspend_vsel_reg = DA9062AA_VLDO4_B,
-		.suspend = REG_FIELD(DA9062AA_DVC_1,
-			__builtin_ffs((int)DA9062AA_VLDO4_SEL_MASK) - 1,
+		.suspend = REG_FIELD(DA9062AA_LDO4_CONT,
+			__builtin_ffs((int)DA9062AA_LDO4_CONF_MASK) - 1,
 			sizeof(unsigned int) * 8 -
-			__builtin_clz((DA9062AA_VLDO4_SEL_MASK)) - 1),
+			__builtin_clz(DA9062AA_LDO4_CONF_MASK) - 1),
 		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
 			__builtin_ffs((int)DA9062AA_LDO4_ILIM_MASK) - 1,
 			sizeof(unsigned int) * 8 -
-- 
2.20.1


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

* Re: [PATCH 1/5] regulator: da9062: fix suspend_enable/disable preparation
  2019-09-23 16:03   ` Adam Thomson
@ 2019-09-23 22:02     ` Marco Felsch
  2019-09-24  8:58       ` Adam Thomson
  0 siblings, 1 reply; 29+ messages in thread
From: Marco Felsch @ 2019-09-23 22:02 UTC (permalink / raw)
  To: Adam Thomson
  Cc: Support Opensource, lee.jones, robh+dt, lgirdwood, broonie,
	Steve Twiss, kernel, devicetree, linux-kernel

Hi Adam,

On 19-09-23 16:03, Adam Thomson wrote:
> On 17 September 2019 13:43, Marco Felsch wrote:
> 
> > Currently the suspend reg_field maps to the pmic voltage selection bits
> > and is used during suspend_enabe/disable() and during get_mode(). This
> > seems to be wrong for both use cases.
> >
> > Use case one (suspend_enabe/disable):
> > Those callbacks are used to mark a regulator device as enabled/disabled
> > during suspend. Marking the regulator enabled during suspend is done by
> > the LDOx_CONF/BUCKx_CONF bit within the LDOx_CONT/BUCKx_CONT
> > registers.
> > Setting this bit tells the DA9062 PMIC state machine to keep the
> > regulator on in POWERDOWN mode and switch to suspend voltage.
> >
> > Use case two (get_mode):
> > The get_mode callback is used to retrieve the active mode state. Since
> > the regulator-setting-A is used for the active state and
> > regulator-setting-B for the suspend state there is no need to check
> > which regulator setting is active.
> >
> 
> So I believe you're correct with the above statements. The driver, rather than
> enabling/disabling a regulator in system suspend, will instead put the regulator
> to a low power state, which is definitely not the desired outcome. Thanks for
> rectifying this.
> 
> Reviewed-by: Adam Thomson <Adam.Thomson.Opensource@diasemi.com>

Thanks a lot for reviewing the patch :) Can you also have a look on the
other patches within this series?

Regards,
  Marco

> > Fixes: 4068e5182ada ("regulator: da9062: DA9062 regulator driver")
> > Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
> > ---
> >  drivers/regulator/da9062-regulator.c | 118 +++++++++++----------------
> >  1 file changed, 47 insertions(+), 71 deletions(-)
> >
> > diff --git a/drivers/regulator/da9062-regulator.c b/drivers/regulator/da9062-
> > regulator.c
> > index 2ffc64622451..9b2ca472f70c 100644
> > --- a/drivers/regulator/da9062-regulator.c
> > +++ b/drivers/regulator/da9062-regulator.c
> > @@ -136,7 +136,6 @@ static int da9062_buck_set_mode(struct regulator_dev
> > *rdev, unsigned mode)
> >  static unsigned da9062_buck_get_mode(struct regulator_dev *rdev)
> >  {
> >  	struct da9062_regulator *regl = rdev_get_drvdata(rdev);
> > -	struct regmap_field *field;
> >  	unsigned int val, mode = 0;
> >  	int ret;
> >
> > @@ -158,18 +157,7 @@ static unsigned da9062_buck_get_mode(struct
> > regulator_dev *rdev)
> >  		return REGULATOR_MODE_NORMAL;
> >  	}
> >
> > -	/* Detect current regulator state */
> > -	ret = regmap_field_read(regl->suspend, &val);
> > -	if (ret < 0)
> > -		return 0;
> > -
> > -	/* Read regulator mode from proper register, depending on state */
> > -	if (val)
> > -		field = regl->suspend_sleep;
> > -	else
> > -		field = regl->sleep;
> > -
> > -	ret = regmap_field_read(field, &val);
> > +	ret = regmap_field_read(regl->sleep, &val);
> >  	if (ret < 0)
> >  		return 0;
> >
> > @@ -208,21 +196,9 @@ static int da9062_ldo_set_mode(struct regulator_dev
> > *rdev, unsigned mode)
> >  static unsigned da9062_ldo_get_mode(struct regulator_dev *rdev)
> >  {
> >  	struct da9062_regulator *regl = rdev_get_drvdata(rdev);
> > -	struct regmap_field *field;
> >  	int ret, val;
> >
> > -	/* Detect current regulator state */
> > -	ret = regmap_field_read(regl->suspend, &val);
> > -	if (ret < 0)
> > -		return 0;
> > -
> > -	/* Read regulator mode from proper register, depending on state */
> > -	if (val)
> > -		field = regl->suspend_sleep;
> > -	else
> > -		field = regl->sleep;
> > -
> > -	ret = regmap_field_read(field, &val);
> > +	ret = regmap_field_read(regl->sleep, &val);
> >  	if (ret < 0)
> >  		return 0;
> >
> > @@ -408,10 +384,10 @@ static const struct da9062_regulator_info
> > local_da9061_regulator_info[] = {
> >  			__builtin_ffs((int)DA9062AA_BUCK1_MODE_MASK) - 1,
> >  			sizeof(unsigned int) * 8 -
> >  			__builtin_clz((DA9062AA_BUCK1_MODE_MASK)) - 1),
> > -		.suspend = REG_FIELD(DA9062AA_DVC_1,
> > -			__builtin_ffs((int)DA9062AA_VBUCK1_SEL_MASK) - 1,
> > +		.suspend = REG_FIELD(DA9062AA_BUCK1_CONT,
> > +			__builtin_ffs((int)DA9062AA_BUCK1_CONF_MASK) - 1,
> >  			sizeof(unsigned int) * 8 -
> > -			__builtin_clz((DA9062AA_VBUCK1_SEL_MASK)) - 1),
> > +			__builtin_clz(DA9062AA_BUCK1_CONF_MASK) - 1),
> >  	},
> >  	{
> >  		.desc.id = DA9061_ID_BUCK2,
> > @@ -444,10 +420,10 @@ static const struct da9062_regulator_info
> > local_da9061_regulator_info[] = {
> >  			__builtin_ffs((int)DA9062AA_BUCK3_MODE_MASK) - 1,
> >  			sizeof(unsigned int) * 8 -
> >  			__builtin_clz((DA9062AA_BUCK3_MODE_MASK)) - 1),
> > -		.suspend = REG_FIELD(DA9062AA_DVC_1,
> > -			__builtin_ffs((int)DA9062AA_VBUCK3_SEL_MASK) - 1,
> > +		.suspend = REG_FIELD(DA9062AA_BUCK3_CONT,
> > +			__builtin_ffs((int)DA9062AA_BUCK3_CONF_MASK) - 1,
> >  			sizeof(unsigned int) * 8 -
> > -			__builtin_clz((DA9062AA_VBUCK3_SEL_MASK)) - 1),
> > +			__builtin_clz(DA9062AA_BUCK3_CONF_MASK) - 1),
> >  	},
> >  	{
> >  		.desc.id = DA9061_ID_BUCK3,
> > @@ -480,10 +456,10 @@ static const struct da9062_regulator_info
> > local_da9061_regulator_info[] = {
> >  			__builtin_ffs((int)DA9062AA_BUCK4_MODE_MASK) - 1,
> >  			sizeof(unsigned int) * 8 -
> >  			__builtin_clz((DA9062AA_BUCK4_MODE_MASK)) - 1),
> > -		.suspend = REG_FIELD(DA9062AA_DVC_1,
> > -			__builtin_ffs((int)DA9062AA_VBUCK4_SEL_MASK) - 1,
> > +		.suspend = REG_FIELD(DA9062AA_BUCK4_CONT,
> > +			__builtin_ffs((int)DA9062AA_BUCK4_CONF_MASK) - 1,
> >  			sizeof(unsigned int) * 8 -
> > -			__builtin_clz((DA9062AA_VBUCK4_SEL_MASK)) - 1),
> > +			__builtin_clz(DA9062AA_BUCK4_CONF_MASK) - 1),
> >  	},
> >  	{
> >  		.desc.id = DA9061_ID_LDO1,
> > @@ -509,10 +485,10 @@ static const struct da9062_regulator_info
> > local_da9061_regulator_info[] = {
> >  			sizeof(unsigned int) * 8 -
> >  			__builtin_clz((DA9062AA_LDO1_SL_B_MASK)) - 1),
> >  		.suspend_vsel_reg = DA9062AA_VLDO1_B,
> > -		.suspend = REG_FIELD(DA9062AA_DVC_1,
> > -			__builtin_ffs((int)DA9062AA_VLDO1_SEL_MASK) - 1,
> > +		.suspend = REG_FIELD(DA9062AA_LDO1_CONT,
> > +			__builtin_ffs((int)DA9062AA_LDO1_CONF_MASK) - 1,
> >  			sizeof(unsigned int) * 8 -
> > -			__builtin_clz((DA9062AA_VLDO1_SEL_MASK)) - 1),
> > +			__builtin_clz(DA9062AA_LDO1_CONF_MASK) - 1),
> >  		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
> >  			__builtin_ffs((int)DA9062AA_LDO1_ILIM_MASK) - 1,
> >  			sizeof(unsigned int) * 8 -
> > @@ -542,10 +518,10 @@ static const struct da9062_regulator_info
> > local_da9061_regulator_info[] = {
> >  			sizeof(unsigned int) * 8 -
> >  			__builtin_clz((DA9062AA_LDO2_SL_B_MASK)) - 1),
> >  		.suspend_vsel_reg = DA9062AA_VLDO2_B,
> > -		.suspend = REG_FIELD(DA9062AA_DVC_1,
> > -			__builtin_ffs((int)DA9062AA_VLDO2_SEL_MASK) - 1,
> > +		.suspend = REG_FIELD(DA9062AA_LDO2_CONT,
> > +			__builtin_ffs((int)DA9062AA_LDO2_CONF_MASK) - 1,
> >  			sizeof(unsigned int) * 8 -
> > -			__builtin_clz((DA9062AA_VLDO2_SEL_MASK)) - 1),
> > +			__builtin_clz(DA9062AA_LDO2_CONF_MASK) - 1),
> >  		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
> >  			__builtin_ffs((int)DA9062AA_LDO2_ILIM_MASK) - 1,
> >  			sizeof(unsigned int) * 8 -
> > @@ -575,10 +551,10 @@ static const struct da9062_regulator_info
> > local_da9061_regulator_info[] = {
> >  			sizeof(unsigned int) * 8 -
> >  			__builtin_clz((DA9062AA_LDO3_SL_B_MASK)) - 1),
> >  		.suspend_vsel_reg = DA9062AA_VLDO3_B,
> > -		.suspend = REG_FIELD(DA9062AA_DVC_1,
> > -			__builtin_ffs((int)DA9062AA_VLDO3_SEL_MASK) - 1,
> > +		.suspend = REG_FIELD(DA9062AA_LDO3_CONT,
> > +			__builtin_ffs((int)DA9062AA_LDO3_CONF_MASK) - 1,
> >  			sizeof(unsigned int) * 8 -
> > -			__builtin_clz((DA9062AA_VLDO3_SEL_MASK)) - 1),
> > +			__builtin_clz(DA9062AA_LDO3_CONF_MASK) - 1),
> >  		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
> >  			__builtin_ffs((int)DA9062AA_LDO3_ILIM_MASK) - 1,
> >  			sizeof(unsigned int) * 8 -
> > @@ -608,10 +584,10 @@ static const struct da9062_regulator_info
> > local_da9061_regulator_info[] = {
> >  			sizeof(unsigned int) * 8 -
> >  			__builtin_clz((DA9062AA_LDO4_SL_B_MASK)) - 1),
> >  		.suspend_vsel_reg = DA9062AA_VLDO4_B,
> > -		.suspend = REG_FIELD(DA9062AA_DVC_1,
> > -			__builtin_ffs((int)DA9062AA_VLDO4_SEL_MASK) - 1,
> > +		.suspend = REG_FIELD(DA9062AA_LDO4_CONT,
> > +			__builtin_ffs((int)DA9062AA_LDO4_CONF_MASK) - 1,
> >  			sizeof(unsigned int) * 8 -
> > -			__builtin_clz((DA9062AA_VLDO4_SEL_MASK)) - 1),
> > +			__builtin_clz(DA9062AA_LDO4_CONF_MASK) - 1),
> >  		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
> >  			__builtin_ffs((int)DA9062AA_LDO4_ILIM_MASK) - 1,
> >  			sizeof(unsigned int) * 8 -
> > @@ -652,10 +628,10 @@ static const struct da9062_regulator_info
> > local_da9062_regulator_info[] = {
> >  			__builtin_ffs((int)DA9062AA_BUCK1_MODE_MASK) - 1,
> >  			sizeof(unsigned int) * 8 -
> >  			__builtin_clz((DA9062AA_BUCK1_MODE_MASK)) - 1),
> > -		.suspend = REG_FIELD(DA9062AA_DVC_1,
> > -			__builtin_ffs((int)DA9062AA_VBUCK1_SEL_MASK) - 1,
> > +		.suspend = REG_FIELD(DA9062AA_BUCK1_CONT,
> > +			__builtin_ffs((int)DA9062AA_BUCK1_CONF_MASK) - 1,
> >  			sizeof(unsigned int) * 8 -
> > -			__builtin_clz((DA9062AA_VBUCK1_SEL_MASK)) - 1),
> > +			__builtin_clz(DA9062AA_BUCK1_CONF_MASK) - 1),
> >  	},
> >  	{
> >  		.desc.id = DA9062_ID_BUCK2,
> > @@ -688,10 +664,10 @@ static const struct da9062_regulator_info
> > local_da9062_regulator_info[] = {
> >  			__builtin_ffs((int)DA9062AA_BUCK2_MODE_MASK) - 1,
> >  			sizeof(unsigned int) * 8 -
> >  			__builtin_clz((DA9062AA_BUCK2_MODE_MASK)) - 1),
> > -		.suspend = REG_FIELD(DA9062AA_DVC_1,
> > -			__builtin_ffs((int)DA9062AA_VBUCK2_SEL_MASK) - 1,
> > +		.suspend = REG_FIELD(DA9062AA_BUCK2_CONT,
> > +			__builtin_ffs((int)DA9062AA_BUCK2_CONF_MASK) - 1,
> >  			sizeof(unsigned int) * 8 -
> > -			__builtin_clz((DA9062AA_VBUCK2_SEL_MASK)) - 1),
> > +			__builtin_clz(DA9062AA_BUCK2_CONF_MASK) - 1),
> >  	},
> >  	{
> >  		.desc.id = DA9062_ID_BUCK3,
> > @@ -724,10 +700,10 @@ static const struct da9062_regulator_info
> > local_da9062_regulator_info[] = {
> >  			__builtin_ffs((int)DA9062AA_BUCK3_MODE_MASK) - 1,
> >  			sizeof(unsigned int) * 8 -
> >  			__builtin_clz((DA9062AA_BUCK3_MODE_MASK)) - 1),
> > -		.suspend = REG_FIELD(DA9062AA_DVC_1,
> > -			__builtin_ffs((int)DA9062AA_VBUCK3_SEL_MASK) - 1,
> > +		.suspend = REG_FIELD(DA9062AA_BUCK3_CONT,
> > +			__builtin_ffs((int)DA9062AA_BUCK3_CONF_MASK) - 1,
> >  			sizeof(unsigned int) * 8 -
> > -			__builtin_clz((DA9062AA_VBUCK3_SEL_MASK)) - 1),
> > +			__builtin_clz(DA9062AA_BUCK3_CONF_MASK) - 1),
> >  	},
> >  	{
> >  		.desc.id = DA9062_ID_BUCK4,
> > @@ -760,10 +736,10 @@ static const struct da9062_regulator_info
> > local_da9062_regulator_info[] = {
> >  			__builtin_ffs((int)DA9062AA_BUCK4_MODE_MASK) - 1,
> >  			sizeof(unsigned int) * 8 -
> >  			__builtin_clz((DA9062AA_BUCK4_MODE_MASK)) - 1),
> > -		.suspend = REG_FIELD(DA9062AA_DVC_1,
> > -			__builtin_ffs((int)DA9062AA_VBUCK4_SEL_MASK) - 1,
> > +		.suspend = REG_FIELD(DA9062AA_BUCK4_CONT,
> > +			__builtin_ffs((int)DA9062AA_BUCK4_CONF_MASK) - 1,
> >  			sizeof(unsigned int) * 8 -
> > -			__builtin_clz((DA9062AA_VBUCK4_SEL_MASK)) - 1),
> > +			__builtin_clz(DA9062AA_BUCK4_CONF_MASK) - 1),
> >  	},
> >  	{
> >  		.desc.id = DA9062_ID_LDO1,
> > @@ -789,10 +765,10 @@ static const struct da9062_regulator_info
> > local_da9062_regulator_info[] = {
> >  			sizeof(unsigned int) * 8 -
> >  			__builtin_clz((DA9062AA_LDO1_SL_B_MASK)) - 1),
> >  		.suspend_vsel_reg = DA9062AA_VLDO1_B,
> > -		.suspend = REG_FIELD(DA9062AA_DVC_1,
> > -			__builtin_ffs((int)DA9062AA_VLDO1_SEL_MASK) - 1,
> > +		.suspend = REG_FIELD(DA9062AA_LDO1_CONT,
> > +			__builtin_ffs((int)DA9062AA_LDO1_CONF_MASK) - 1,
> >  			sizeof(unsigned int) * 8 -
> > -			__builtin_clz((DA9062AA_VLDO1_SEL_MASK)) - 1),
> > +			__builtin_clz(DA9062AA_LDO1_CONF_MASK) - 1),
> >  		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
> >  			__builtin_ffs((int)DA9062AA_LDO1_ILIM_MASK) - 1,
> >  			sizeof(unsigned int) * 8 -
> > @@ -822,10 +798,10 @@ static const struct da9062_regulator_info
> > local_da9062_regulator_info[] = {
> >  			sizeof(unsigned int) * 8 -
> >  			__builtin_clz((DA9062AA_LDO2_SL_B_MASK)) - 1),
> >  		.suspend_vsel_reg = DA9062AA_VLDO2_B,
> > -		.suspend = REG_FIELD(DA9062AA_DVC_1,
> > -			__builtin_ffs((int)DA9062AA_VLDO2_SEL_MASK) - 1,
> > +		.suspend = REG_FIELD(DA9062AA_LDO2_CONT,
> > +			__builtin_ffs((int)DA9062AA_LDO2_CONF_MASK) - 1,
> >  			sizeof(unsigned int) * 8 -
> > -			__builtin_clz((DA9062AA_VLDO2_SEL_MASK)) - 1),
> > +			__builtin_clz(DA9062AA_LDO2_CONF_MASK) - 1),
> >  		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
> >  			__builtin_ffs((int)DA9062AA_LDO2_ILIM_MASK) - 1,
> >  			sizeof(unsigned int) * 8 -
> > @@ -855,10 +831,10 @@ static const struct da9062_regulator_info
> > local_da9062_regulator_info[] = {
> >  			sizeof(unsigned int) * 8 -
> >  			__builtin_clz((DA9062AA_LDO3_SL_B_MASK)) - 1),
> >  		.suspend_vsel_reg = DA9062AA_VLDO3_B,
> > -		.suspend = REG_FIELD(DA9062AA_DVC_1,
> > -			__builtin_ffs((int)DA9062AA_VLDO3_SEL_MASK) - 1,
> > +		.suspend = REG_FIELD(DA9062AA_LDO3_CONT,
> > +			__builtin_ffs((int)DA9062AA_LDO3_CONF_MASK) - 1,
> >  			sizeof(unsigned int) * 8 -
> > -			__builtin_clz((DA9062AA_VLDO3_SEL_MASK)) - 1),
> > +			__builtin_clz(DA9062AA_LDO3_CONF_MASK) - 1),
> >  		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
> >  			__builtin_ffs((int)DA9062AA_LDO3_ILIM_MASK) - 1,
> >  			sizeof(unsigned int) * 8 -
> > @@ -888,10 +864,10 @@ static const struct da9062_regulator_info
> > local_da9062_regulator_info[] = {
> >  			sizeof(unsigned int) * 8 -
> >  			__builtin_clz((DA9062AA_LDO4_SL_B_MASK)) - 1),
> >  		.suspend_vsel_reg = DA9062AA_VLDO4_B,
> > -		.suspend = REG_FIELD(DA9062AA_DVC_1,
> > -			__builtin_ffs((int)DA9062AA_VLDO4_SEL_MASK) - 1,
> > +		.suspend = REG_FIELD(DA9062AA_LDO4_CONT,
> > +			__builtin_ffs((int)DA9062AA_LDO4_CONF_MASK) - 1,
> >  			sizeof(unsigned int) * 8 -
> > -			__builtin_clz((DA9062AA_VLDO4_SEL_MASK)) - 1),
> > +			__builtin_clz(DA9062AA_LDO4_CONF_MASK) - 1),
> >  		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
> >  			__builtin_ffs((int)DA9062AA_LDO4_ILIM_MASK) - 1,
> >  			sizeof(unsigned int) * 8 -
> > --
> > 2.20.1
> 
> 

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

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

* RE: [PATCH 1/5] regulator: da9062: fix suspend_enable/disable preparation
  2019-09-23 22:02     ` Marco Felsch
@ 2019-09-24  8:58       ` Adam Thomson
  0 siblings, 0 replies; 29+ messages in thread
From: Adam Thomson @ 2019-09-24  8:58 UTC (permalink / raw)
  To: Marco Felsch, Adam Thomson
  Cc: Support Opensource, lee.jones, robh+dt, lgirdwood, broonie,
	Steve Twiss, kernel, devicetree, linux-kernel

On 23 September 2019 23:03, Marco Felsch wrote:

> Hi Adam,
> 
> On 19-09-23 16:03, Adam Thomson wrote:
> > On 17 September 2019 13:43, Marco Felsch wrote:
> >
> > > Currently the suspend reg_field maps to the pmic voltage selection bits
> > > and is used during suspend_enabe/disable() and during get_mode(). This
> > > seems to be wrong for both use cases.
> > >
> > > Use case one (suspend_enabe/disable):
> > > Those callbacks are used to mark a regulator device as enabled/disabled
> > > during suspend. Marking the regulator enabled during suspend is done by
> > > the LDOx_CONF/BUCKx_CONF bit within the LDOx_CONT/BUCKx_CONT
> > > registers.
> > > Setting this bit tells the DA9062 PMIC state machine to keep the
> > > regulator on in POWERDOWN mode and switch to suspend voltage.
> > >
> > > Use case two (get_mode):
> > > The get_mode callback is used to retrieve the active mode state. Since
> > > the regulator-setting-A is used for the active state and
> > > regulator-setting-B for the suspend state there is no need to check
> > > which regulator setting is active.
> > >
> >
> > So I believe you're correct with the above statements. The driver, rather than
> > enabling/disabling a regulator in system suspend, will instead put the regulator
> > to a low power state, which is definitely not the desired outcome. Thanks for
> > rectifying this.
> >
> > Reviewed-by: Adam Thomson <Adam.Thomson.Opensource@diasemi.com>
> 
> Thanks a lot for reviewing the patch :) Can you also have a look on the
> other patches within this series?

Yes, I will take a look at those next. :)

> 
> Regards,
>   Marco
> 
> > > Fixes: 4068e5182ada ("regulator: da9062: DA9062 regulator driver")
> > > Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
> > > ---
> > >  drivers/regulator/da9062-regulator.c | 118 +++++++++++----------------
> > >  1 file changed, 47 insertions(+), 71 deletions(-)
> > >
> > > diff --git a/drivers/regulator/da9062-regulator.c b/drivers/regulator/da9062-
> > > regulator.c
> > > index 2ffc64622451..9b2ca472f70c 100644
> > > --- a/drivers/regulator/da9062-regulator.c
> > > +++ b/drivers/regulator/da9062-regulator.c
> > > @@ -136,7 +136,6 @@ static int da9062_buck_set_mode(struct
> regulator_dev
> > > *rdev, unsigned mode)
> > >  static unsigned da9062_buck_get_mode(struct regulator_dev *rdev)
> > >  {
> > >  	struct da9062_regulator *regl = rdev_get_drvdata(rdev);
> > > -	struct regmap_field *field;
> > >  	unsigned int val, mode = 0;
> > >  	int ret;
> > >
> > > @@ -158,18 +157,7 @@ static unsigned da9062_buck_get_mode(struct
> > > regulator_dev *rdev)
> > >  		return REGULATOR_MODE_NORMAL;
> > >  	}
> > >
> > > -	/* Detect current regulator state */
> > > -	ret = regmap_field_read(regl->suspend, &val);
> > > -	if (ret < 0)
> > > -		return 0;
> > > -
> > > -	/* Read regulator mode from proper register, depending on state */
> > > -	if (val)
> > > -		field = regl->suspend_sleep;
> > > -	else
> > > -		field = regl->sleep;
> > > -
> > > -	ret = regmap_field_read(field, &val);
> > > +	ret = regmap_field_read(regl->sleep, &val);
> > >  	if (ret < 0)
> > >  		return 0;
> > >
> > > @@ -208,21 +196,9 @@ static int da9062_ldo_set_mode(struct regulator_dev
> > > *rdev, unsigned mode)
> > >  static unsigned da9062_ldo_get_mode(struct regulator_dev *rdev)
> > >  {
> > >  	struct da9062_regulator *regl = rdev_get_drvdata(rdev);
> > > -	struct regmap_field *field;
> > >  	int ret, val;
> > >
> > > -	/* Detect current regulator state */
> > > -	ret = regmap_field_read(regl->suspend, &val);
> > > -	if (ret < 0)
> > > -		return 0;
> > > -
> > > -	/* Read regulator mode from proper register, depending on state */
> > > -	if (val)
> > > -		field = regl->suspend_sleep;
> > > -	else
> > > -		field = regl->sleep;
> > > -
> > > -	ret = regmap_field_read(field, &val);
> > > +	ret = regmap_field_read(regl->sleep, &val);
> > >  	if (ret < 0)
> > >  		return 0;
> > >
> > > @@ -408,10 +384,10 @@ static const struct da9062_regulator_info
> > > local_da9061_regulator_info[] = {
> > >  			__builtin_ffs((int)DA9062AA_BUCK1_MODE_MASK) - 1,
> > >  			sizeof(unsigned int) * 8 -
> > >  			__builtin_clz((DA9062AA_BUCK1_MODE_MASK)) - 1),
> > > -		.suspend = REG_FIELD(DA9062AA_DVC_1,
> > > -			__builtin_ffs((int)DA9062AA_VBUCK1_SEL_MASK) - 1,
> > > +		.suspend = REG_FIELD(DA9062AA_BUCK1_CONT,
> > > +			__builtin_ffs((int)DA9062AA_BUCK1_CONF_MASK) - 1,
> > >  			sizeof(unsigned int) * 8 -
> > > -			__builtin_clz((DA9062AA_VBUCK1_SEL_MASK)) - 1),
> > > +			__builtin_clz(DA9062AA_BUCK1_CONF_MASK) - 1),
> > >  	},
> > >  	{
> > >  		.desc.id = DA9061_ID_BUCK2,
> > > @@ -444,10 +420,10 @@ static const struct da9062_regulator_info
> > > local_da9061_regulator_info[] = {
> > >  			__builtin_ffs((int)DA9062AA_BUCK3_MODE_MASK) - 1,
> > >  			sizeof(unsigned int) * 8 -
> > >  			__builtin_clz((DA9062AA_BUCK3_MODE_MASK)) - 1),
> > > -		.suspend = REG_FIELD(DA9062AA_DVC_1,
> > > -			__builtin_ffs((int)DA9062AA_VBUCK3_SEL_MASK) - 1,
> > > +		.suspend = REG_FIELD(DA9062AA_BUCK3_CONT,
> > > +			__builtin_ffs((int)DA9062AA_BUCK3_CONF_MASK) - 1,
> > >  			sizeof(unsigned int) * 8 -
> > > -			__builtin_clz((DA9062AA_VBUCK3_SEL_MASK)) - 1),
> > > +			__builtin_clz(DA9062AA_BUCK3_CONF_MASK) - 1),
> > >  	},
> > >  	{
> > >  		.desc.id = DA9061_ID_BUCK3,
> > > @@ -480,10 +456,10 @@ static const struct da9062_regulator_info
> > > local_da9061_regulator_info[] = {
> > >  			__builtin_ffs((int)DA9062AA_BUCK4_MODE_MASK) - 1,
> > >  			sizeof(unsigned int) * 8 -
> > >  			__builtin_clz((DA9062AA_BUCK4_MODE_MASK)) - 1),
> > > -		.suspend = REG_FIELD(DA9062AA_DVC_1,
> > > -			__builtin_ffs((int)DA9062AA_VBUCK4_SEL_MASK) - 1,
> > > +		.suspend = REG_FIELD(DA9062AA_BUCK4_CONT,
> > > +			__builtin_ffs((int)DA9062AA_BUCK4_CONF_MASK) - 1,
> > >  			sizeof(unsigned int) * 8 -
> > > -			__builtin_clz((DA9062AA_VBUCK4_SEL_MASK)) - 1),
> > > +			__builtin_clz(DA9062AA_BUCK4_CONF_MASK) - 1),
> > >  	},
> > >  	{
> > >  		.desc.id = DA9061_ID_LDO1,
> > > @@ -509,10 +485,10 @@ static const struct da9062_regulator_info
> > > local_da9061_regulator_info[] = {
> > >  			sizeof(unsigned int) * 8 -
> > >  			__builtin_clz((DA9062AA_LDO1_SL_B_MASK)) - 1),
> > >  		.suspend_vsel_reg = DA9062AA_VLDO1_B,
> > > -		.suspend = REG_FIELD(DA9062AA_DVC_1,
> > > -			__builtin_ffs((int)DA9062AA_VLDO1_SEL_MASK) - 1,
> > > +		.suspend = REG_FIELD(DA9062AA_LDO1_CONT,
> > > +			__builtin_ffs((int)DA9062AA_LDO1_CONF_MASK) - 1,
> > >  			sizeof(unsigned int) * 8 -
> > > -			__builtin_clz((DA9062AA_VLDO1_SEL_MASK)) - 1),
> > > +			__builtin_clz(DA9062AA_LDO1_CONF_MASK) - 1),
> > >  		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
> > >  			__builtin_ffs((int)DA9062AA_LDO1_ILIM_MASK) - 1,
> > >  			sizeof(unsigned int) * 8 -
> > > @@ -542,10 +518,10 @@ static const struct da9062_regulator_info
> > > local_da9061_regulator_info[] = {
> > >  			sizeof(unsigned int) * 8 -
> > >  			__builtin_clz((DA9062AA_LDO2_SL_B_MASK)) - 1),
> > >  		.suspend_vsel_reg = DA9062AA_VLDO2_B,
> > > -		.suspend = REG_FIELD(DA9062AA_DVC_1,
> > > -			__builtin_ffs((int)DA9062AA_VLDO2_SEL_MASK) - 1,
> > > +		.suspend = REG_FIELD(DA9062AA_LDO2_CONT,
> > > +			__builtin_ffs((int)DA9062AA_LDO2_CONF_MASK) - 1,
> > >  			sizeof(unsigned int) * 8 -
> > > -			__builtin_clz((DA9062AA_VLDO2_SEL_MASK)) - 1),
> > > +			__builtin_clz(DA9062AA_LDO2_CONF_MASK) - 1),
> > >  		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
> > >  			__builtin_ffs((int)DA9062AA_LDO2_ILIM_MASK) - 1,
> > >  			sizeof(unsigned int) * 8 -
> > > @@ -575,10 +551,10 @@ static const struct da9062_regulator_info
> > > local_da9061_regulator_info[] = {
> > >  			sizeof(unsigned int) * 8 -
> > >  			__builtin_clz((DA9062AA_LDO3_SL_B_MASK)) - 1),
> > >  		.suspend_vsel_reg = DA9062AA_VLDO3_B,
> > > -		.suspend = REG_FIELD(DA9062AA_DVC_1,
> > > -			__builtin_ffs((int)DA9062AA_VLDO3_SEL_MASK) - 1,
> > > +		.suspend = REG_FIELD(DA9062AA_LDO3_CONT,
> > > +			__builtin_ffs((int)DA9062AA_LDO3_CONF_MASK) - 1,
> > >  			sizeof(unsigned int) * 8 -
> > > -			__builtin_clz((DA9062AA_VLDO3_SEL_MASK)) - 1),
> > > +			__builtin_clz(DA9062AA_LDO3_CONF_MASK) - 1),
> > >  		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
> > >  			__builtin_ffs((int)DA9062AA_LDO3_ILIM_MASK) - 1,
> > >  			sizeof(unsigned int) * 8 -
> > > @@ -608,10 +584,10 @@ static const struct da9062_regulator_info
> > > local_da9061_regulator_info[] = {
> > >  			sizeof(unsigned int) * 8 -
> > >  			__builtin_clz((DA9062AA_LDO4_SL_B_MASK)) - 1),
> > >  		.suspend_vsel_reg = DA9062AA_VLDO4_B,
> > > -		.suspend = REG_FIELD(DA9062AA_DVC_1,
> > > -			__builtin_ffs((int)DA9062AA_VLDO4_SEL_MASK) - 1,
> > > +		.suspend = REG_FIELD(DA9062AA_LDO4_CONT,
> > > +			__builtin_ffs((int)DA9062AA_LDO4_CONF_MASK) - 1,
> > >  			sizeof(unsigned int) * 8 -
> > > -			__builtin_clz((DA9062AA_VLDO4_SEL_MASK)) - 1),
> > > +			__builtin_clz(DA9062AA_LDO4_CONF_MASK) - 1),
> > >  		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
> > >  			__builtin_ffs((int)DA9062AA_LDO4_ILIM_MASK) - 1,
> > >  			sizeof(unsigned int) * 8 -
> > > @@ -652,10 +628,10 @@ static const struct da9062_regulator_info
> > > local_da9062_regulator_info[] = {
> > >  			__builtin_ffs((int)DA9062AA_BUCK1_MODE_MASK) - 1,
> > >  			sizeof(unsigned int) * 8 -
> > >  			__builtin_clz((DA9062AA_BUCK1_MODE_MASK)) - 1),
> > > -		.suspend = REG_FIELD(DA9062AA_DVC_1,
> > > -			__builtin_ffs((int)DA9062AA_VBUCK1_SEL_MASK) - 1,
> > > +		.suspend = REG_FIELD(DA9062AA_BUCK1_CONT,
> > > +			__builtin_ffs((int)DA9062AA_BUCK1_CONF_MASK) - 1,
> > >  			sizeof(unsigned int) * 8 -
> > > -			__builtin_clz((DA9062AA_VBUCK1_SEL_MASK)) - 1),
> > > +			__builtin_clz(DA9062AA_BUCK1_CONF_MASK) - 1),
> > >  	},
> > >  	{
> > >  		.desc.id = DA9062_ID_BUCK2,
> > > @@ -688,10 +664,10 @@ static const struct da9062_regulator_info
> > > local_da9062_regulator_info[] = {
> > >  			__builtin_ffs((int)DA9062AA_BUCK2_MODE_MASK) - 1,
> > >  			sizeof(unsigned int) * 8 -
> > >  			__builtin_clz((DA9062AA_BUCK2_MODE_MASK)) - 1),
> > > -		.suspend = REG_FIELD(DA9062AA_DVC_1,
> > > -			__builtin_ffs((int)DA9062AA_VBUCK2_SEL_MASK) - 1,
> > > +		.suspend = REG_FIELD(DA9062AA_BUCK2_CONT,
> > > +			__builtin_ffs((int)DA9062AA_BUCK2_CONF_MASK) - 1,
> > >  			sizeof(unsigned int) * 8 -
> > > -			__builtin_clz((DA9062AA_VBUCK2_SEL_MASK)) - 1),
> > > +			__builtin_clz(DA9062AA_BUCK2_CONF_MASK) - 1),
> > >  	},
> > >  	{
> > >  		.desc.id = DA9062_ID_BUCK3,
> > > @@ -724,10 +700,10 @@ static const struct da9062_regulator_info
> > > local_da9062_regulator_info[] = {
> > >  			__builtin_ffs((int)DA9062AA_BUCK3_MODE_MASK) - 1,
> > >  			sizeof(unsigned int) * 8 -
> > >  			__builtin_clz((DA9062AA_BUCK3_MODE_MASK)) - 1),
> > > -		.suspend = REG_FIELD(DA9062AA_DVC_1,
> > > -			__builtin_ffs((int)DA9062AA_VBUCK3_SEL_MASK) - 1,
> > > +		.suspend = REG_FIELD(DA9062AA_BUCK3_CONT,
> > > +			__builtin_ffs((int)DA9062AA_BUCK3_CONF_MASK) - 1,
> > >  			sizeof(unsigned int) * 8 -
> > > -			__builtin_clz((DA9062AA_VBUCK3_SEL_MASK)) - 1),
> > > +			__builtin_clz(DA9062AA_BUCK3_CONF_MASK) - 1),
> > >  	},
> > >  	{
> > >  		.desc.id = DA9062_ID_BUCK4,
> > > @@ -760,10 +736,10 @@ static const struct da9062_regulator_info
> > > local_da9062_regulator_info[] = {
> > >  			__builtin_ffs((int)DA9062AA_BUCK4_MODE_MASK) - 1,
> > >  			sizeof(unsigned int) * 8 -
> > >  			__builtin_clz((DA9062AA_BUCK4_MODE_MASK)) - 1),
> > > -		.suspend = REG_FIELD(DA9062AA_DVC_1,
> > > -			__builtin_ffs((int)DA9062AA_VBUCK4_SEL_MASK) - 1,
> > > +		.suspend = REG_FIELD(DA9062AA_BUCK4_CONT,
> > > +			__builtin_ffs((int)DA9062AA_BUCK4_CONF_MASK) - 1,
> > >  			sizeof(unsigned int) * 8 -
> > > -			__builtin_clz((DA9062AA_VBUCK4_SEL_MASK)) - 1),
> > > +			__builtin_clz(DA9062AA_BUCK4_CONF_MASK) - 1),
> > >  	},
> > >  	{
> > >  		.desc.id = DA9062_ID_LDO1,
> > > @@ -789,10 +765,10 @@ static const struct da9062_regulator_info
> > > local_da9062_regulator_info[] = {
> > >  			sizeof(unsigned int) * 8 -
> > >  			__builtin_clz((DA9062AA_LDO1_SL_B_MASK)) - 1),
> > >  		.suspend_vsel_reg = DA9062AA_VLDO1_B,
> > > -		.suspend = REG_FIELD(DA9062AA_DVC_1,
> > > -			__builtin_ffs((int)DA9062AA_VLDO1_SEL_MASK) - 1,
> > > +		.suspend = REG_FIELD(DA9062AA_LDO1_CONT,
> > > +			__builtin_ffs((int)DA9062AA_LDO1_CONF_MASK) - 1,
> > >  			sizeof(unsigned int) * 8 -
> > > -			__builtin_clz((DA9062AA_VLDO1_SEL_MASK)) - 1),
> > > +			__builtin_clz(DA9062AA_LDO1_CONF_MASK) - 1),
> > >  		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
> > >  			__builtin_ffs((int)DA9062AA_LDO1_ILIM_MASK) - 1,
> > >  			sizeof(unsigned int) * 8 -
> > > @@ -822,10 +798,10 @@ static const struct da9062_regulator_info
> > > local_da9062_regulator_info[] = {
> > >  			sizeof(unsigned int) * 8 -
> > >  			__builtin_clz((DA9062AA_LDO2_SL_B_MASK)) - 1),
> > >  		.suspend_vsel_reg = DA9062AA_VLDO2_B,
> > > -		.suspend = REG_FIELD(DA9062AA_DVC_1,
> > > -			__builtin_ffs((int)DA9062AA_VLDO2_SEL_MASK) - 1,
> > > +		.suspend = REG_FIELD(DA9062AA_LDO2_CONT,
> > > +			__builtin_ffs((int)DA9062AA_LDO2_CONF_MASK) - 1,
> > >  			sizeof(unsigned int) * 8 -
> > > -			__builtin_clz((DA9062AA_VLDO2_SEL_MASK)) - 1),
> > > +			__builtin_clz(DA9062AA_LDO2_CONF_MASK) - 1),
> > >  		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
> > >  			__builtin_ffs((int)DA9062AA_LDO2_ILIM_MASK) - 1,
> > >  			sizeof(unsigned int) * 8 -
> > > @@ -855,10 +831,10 @@ static const struct da9062_regulator_info
> > > local_da9062_regulator_info[] = {
> > >  			sizeof(unsigned int) * 8 -
> > >  			__builtin_clz((DA9062AA_LDO3_SL_B_MASK)) - 1),
> > >  		.suspend_vsel_reg = DA9062AA_VLDO3_B,
> > > -		.suspend = REG_FIELD(DA9062AA_DVC_1,
> > > -			__builtin_ffs((int)DA9062AA_VLDO3_SEL_MASK) - 1,
> > > +		.suspend = REG_FIELD(DA9062AA_LDO3_CONT,
> > > +			__builtin_ffs((int)DA9062AA_LDO3_CONF_MASK) - 1,
> > >  			sizeof(unsigned int) * 8 -
> > > -			__builtin_clz((DA9062AA_VLDO3_SEL_MASK)) - 1),
> > > +			__builtin_clz(DA9062AA_LDO3_CONF_MASK) - 1),
> > >  		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
> > >  			__builtin_ffs((int)DA9062AA_LDO3_ILIM_MASK) - 1,
> > >  			sizeof(unsigned int) * 8 -
> > > @@ -888,10 +864,10 @@ static const struct da9062_regulator_info
> > > local_da9062_regulator_info[] = {
> > >  			sizeof(unsigned int) * 8 -
> > >  			__builtin_clz((DA9062AA_LDO4_SL_B_MASK)) - 1),
> > >  		.suspend_vsel_reg = DA9062AA_VLDO4_B,
> > > -		.suspend = REG_FIELD(DA9062AA_DVC_1,
> > > -			__builtin_ffs((int)DA9062AA_VLDO4_SEL_MASK) - 1,
> > > +		.suspend = REG_FIELD(DA9062AA_LDO4_CONT,
> > > +			__builtin_ffs((int)DA9062AA_LDO4_CONF_MASK) - 1,
> > >  			sizeof(unsigned int) * 8 -
> > > -			__builtin_clz((DA9062AA_VLDO4_SEL_MASK)) - 1),
> > > +			__builtin_clz(DA9062AA_LDO4_CONF_MASK) - 1),
> > >  		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
> > >  			__builtin_ffs((int)DA9062AA_LDO4_ILIM_MASK) - 1,
> > >  			sizeof(unsigned int) * 8 -
> > > --
> > > 2.20.1
> >
> >
> 
> --
> Pengutronix e.K.                           |                             |
> Industrial Linux Solutions                 | http://www.pengutronix.de/  |
> Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
> Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

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

* RE: [PATCH 2/5] dt-bindings: mfd: da9062: add regulator voltage selection documentation
  2019-09-17 12:42 ` [PATCH 2/5] dt-bindings: mfd: da9062: add regulator voltage selection documentation Marco Felsch
@ 2019-09-24  9:23   ` Adam Thomson
  2019-09-25 15:51     ` Marco Felsch
  0 siblings, 1 reply; 29+ messages in thread
From: Adam Thomson @ 2019-09-24  9:23 UTC (permalink / raw)
  To: Marco Felsch, Support Opensource, lee.jones, robh+dt, lgirdwood,
	broonie, Steve Twiss
  Cc: kernel, devicetree, linux-kernel

On 17 September 2019 13:43, Marco Felsch wrote:

> Add the documentation which describe the voltage selection gpio support.
> This property can be applied to each subnode within the 'regulators'
> node so each regulator can be configured differently.
> 
> Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
> ---
>  Documentation/devicetree/bindings/mfd/da9062.txt | 9 +++++++++
>  1 file changed, 9 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/mfd/da9062.txt
> b/Documentation/devicetree/bindings/mfd/da9062.txt
> index edca653a5777..9d9820d8177d 100644
> --- a/Documentation/devicetree/bindings/mfd/da9062.txt
> +++ b/Documentation/devicetree/bindings/mfd/da9062.txt
> @@ -66,6 +66,15 @@ Sub-nodes:
>    details of individual regulator device can be found in:
>    Documentation/devicetree/bindings/regulator/regulator.txt
> 
> +  Optional regulator device-specific properties:
> +  - dlg,vsel-sense-gpios : The GPIO reference which should be used by the
> +    regulator to switch the voltage between active/suspend voltage settings. If
> +    the signal is active the active-settings are applied else the suspend
> +    settings are applied. Attention: Sharing the same gpio for other purposes
> +    or across multiple regulators is possible but the gpio settings must be the
> +    same. Also the gpio phandle must refer to to the dlg,da9062-gpio device
> +    other gpios are not allowed and make no sense.
> +

Should we not use the binding names that are defined in 'gpio-regulator.yaml' as
these seem to be generic and would probably serve the purpose here?

>  - rtc : This node defines settings required for the Real-Time Clock associated
>    with the DA9062. There are currently no entries in this binding, however
>    compatible = "dlg,da9062-rtc" should be added if a node is created.
> --
> 2.20.1


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

* RE: [PATCH 3/5] regulator: da9062: add voltage selection gpio support
  2019-09-17 12:42 ` [PATCH 3/5] regulator: da9062: add voltage selection gpio support Marco Felsch
  2019-09-17 14:22   ` kbuild test robot
@ 2019-09-24  9:48   ` Adam Thomson
  2019-09-25 15:59     ` Marco Felsch
  2019-10-04 19:41   ` Linus Walleij
  2 siblings, 1 reply; 29+ messages in thread
From: Adam Thomson @ 2019-09-24  9:48 UTC (permalink / raw)
  To: Marco Felsch, Support Opensource, lee.jones, robh+dt, lgirdwood,
	broonie, Steve Twiss
  Cc: kernel, devicetree, linux-kernel

On 17 September 2019 13:43, Marco Felsch wrote:

> The DA9062/1 devices can switch their regulator voltages between
> voltage-A (active) and voltage-B (suspend) settings. Switching the
> voltages can be controlled by ther internal state-machine or by a gpio
> input signal and can be configured for each individual regulator. This
> commit adds the gpio-based voltage switching support.
> 
> Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
> ---
>  drivers/regulator/da9062-regulator.c | 149 +++++++++++++++++++++++++++
>  1 file changed, 149 insertions(+)
> 
> diff --git a/drivers/regulator/da9062-regulator.c b/drivers/regulator/da9062-
> regulator.c
> index 9b2ca472f70c..9d6eb7625948 100644
> --- a/drivers/regulator/da9062-regulator.c
> +++ b/drivers/regulator/da9062-regulator.c
> @@ -7,6 +7,7 @@
>  #include <linux/module.h>
>  #include <linux/init.h>
>  #include <linux/err.h>
> +#include <linux/gpio/consumer.h>
>  #include <linux/slab.h>
>  #include <linux/of.h>
>  #include <linux/platform_device.h>
> @@ -15,6 +16,7 @@
>  #include <linux/regulator/machine.h>
>  #include <linux/regulator/of_regulator.h>
>  #include <linux/mfd/da9062/core.h>
> +#include <linux/mfd/da9062/gpio.h>
>  #include <linux/mfd/da9062/registers.h>
> 
>  /* Regulator IDs */
> @@ -50,6 +52,7 @@ struct da9062_regulator_info {
>  	struct reg_field sleep;
>  	struct reg_field suspend_sleep;
>  	unsigned int suspend_vsel_reg;
> +	struct reg_field vsel_gpi;
>  	/* Event detection bit */
>  	struct reg_field oc_event;
>  };
> @@ -65,6 +68,7 @@ struct da9062_regulator {
>  	struct regmap_field			*suspend;
>  	struct regmap_field			*sleep;
>  	struct regmap_field			*suspend_sleep;
> +	struct regmap_field			*vsel_gpi;
>  };
> 
>  /* Encapsulates all information for the regulators driver */
> @@ -351,6 +355,65 @@ static const struct regulator_ops da9062_ldo_ops = {
>  	.set_suspend_mode	= da9062_ldo_set_suspend_mode,
>  };
> 
> +static int da9062_config_gpi(struct device_node *np,
> +			     const struct regulator_desc *desc,
> +			     struct regulator_config *cfg, const char *gpi_id)
> +{
> +	struct da9062_regulator *regl = cfg->driver_data;
> +	struct gpio_desc *gpi;
> +	unsigned int nr;
> +	int ret;
> +	char *prop, *label;
> +
> +	prop = kasprintf(GFP_KERNEL, "dlg,%s-sense-gpios", gpi_id);
> +	if (!prop)
> +		return -ENOMEM;
> +	label = kasprintf(GFP_KERNEL, "%s-%s-gpi", desc->name, gpi_id);
> +	if (!label) {
> +		ret = -ENOMEM;
> +		goto free;

If we use the generic bindings names then the above will change I guess.

> +	}
> +
> +	/*
> +	 * We only must ensure that the gpio device is probed before the
> +	 * regulator driver so no need to store the reference global. Luckily
> +	 * devm_* releases the gpio upon a unbound action.
> +	 */
> +	gpi = devm_gpiod_get_from_of_node(cfg->dev, np, prop, 0, GPIOD_IN |
> +					  GPIOD_FLAGS_BIT_NONEXCLUSIVE,
> label);
> +	if (IS_ERR(gpi)) {
> +		ret = PTR_ERR(gpi);
> +		goto free;
> +	}
> +
> +	if (!gpi) {
> +		ret = 0;
> +		goto free;
> +	}
> +
> +	/* We need the local number */
> +	nr = da9062_gpio_get_hwgpio(gpi);
> +	if (nr < 1 || nr > 3) {
> +		ret = -EINVAL;
> +		goto free;
> +	}
> +
> +	ret = regmap_field_write(regl->vsel_gpi, nr);

Actually thinking about this some more, should we really be setting alternate
functions of the GPIO here? Would this not be done through GPIO/Pinmux
frameworks? That way the GPIO would be blocked off from other's requesting it.
This seems a little unsafe, unless I'm mistaken.

> +
> +free:
> +	kfree(prop);
> +	kfree(label);
> +
> +	return ret;
> +}
> +
> +static int da9062_parse_dt(struct device_node *np,
> +			   const struct regulator_desc *desc,
> +			   struct regulator_config *cfg)
> +{
> +	return da9062_config_gpi(np, desc, cfg, "vsel");
> +}
> +
>  /* DA9061 Regulator information */
>  static const struct da9062_regulator_info local_da9061_regulator_info[] = {
>  	{
> @@ -358,6 +421,7 @@ static const struct da9062_regulator_info
> local_da9061_regulator_info[] = {
>  		.desc.name = "DA9061 BUCK1",
>  		.desc.of_match = of_match_ptr("buck1"),
>  		.desc.regulators_node = of_match_ptr("regulators"),
> +		.desc.of_parse_cb = da9062_parse_dt,
>  		.desc.ops = &da9062_buck_ops,
>  		.desc.min_uV = (300) * 1000,
>  		.desc.uV_step = (10) * 1000,
> @@ -388,12 +452,17 @@ static const struct da9062_regulator_info
> local_da9061_regulator_info[] = {
>  			__builtin_ffs((int)DA9062AA_BUCK1_CONF_MASK) - 1,
>  			sizeof(unsigned int) * 8 -
>  			__builtin_clz(DA9062AA_BUCK1_CONF_MASK) - 1),
> +		.vsel_gpi = REG_FIELD(DA9062AA_BUCK1_CONT,
> +			__builtin_ffs((int)DA9062AA_VBUCK1_GPI_MASK) - 1,
> +			sizeof(unsigned int) * 8 -
> +			__builtin_clz(DA9062AA_VBUCK1_GPI_MASK) - 1),
>  	},
>  	{
>  		.desc.id = DA9061_ID_BUCK2,
>  		.desc.name = "DA9061 BUCK2",
>  		.desc.of_match = of_match_ptr("buck2"),
>  		.desc.regulators_node = of_match_ptr("regulators"),
> +		.desc.of_parse_cb = da9062_parse_dt,
>  		.desc.ops = &da9062_buck_ops,
>  		.desc.min_uV = (800) * 1000,
>  		.desc.uV_step = (20) * 1000,
> @@ -424,12 +493,17 @@ static const struct da9062_regulator_info
> local_da9061_regulator_info[] = {
>  			__builtin_ffs((int)DA9062AA_BUCK3_CONF_MASK) - 1,
>  			sizeof(unsigned int) * 8 -
>  			__builtin_clz(DA9062AA_BUCK3_CONF_MASK) - 1),
> +		.vsel_gpi = REG_FIELD(DA9062AA_BUCK3_CONT,
> +			__builtin_ffs((int)DA9062AA_VBUCK3_GPI_MASK) - 1,
> +			sizeof(unsigned int) * 8 -
> +			__builtin_clz(DA9062AA_VBUCK3_GPI_MASK) - 1),
>  	},
>  	{
>  		.desc.id = DA9061_ID_BUCK3,
>  		.desc.name = "DA9061 BUCK3",
>  		.desc.of_match = of_match_ptr("buck3"),
>  		.desc.regulators_node = of_match_ptr("regulators"),
> +		.desc.of_parse_cb = da9062_parse_dt,
>  		.desc.ops = &da9062_buck_ops,
>  		.desc.min_uV = (530) * 1000,
>  		.desc.uV_step = (10) * 1000,
> @@ -460,12 +534,17 @@ static const struct da9062_regulator_info
> local_da9061_regulator_info[] = {
>  			__builtin_ffs((int)DA9062AA_BUCK4_CONF_MASK) - 1,
>  			sizeof(unsigned int) * 8 -
>  			__builtin_clz(DA9062AA_BUCK4_CONF_MASK) - 1),
> +		.vsel_gpi = REG_FIELD(DA9062AA_BUCK4_CONT,
> +			__builtin_ffs((int)DA9062AA_VBUCK4_GPI_MASK) - 1,
> +			sizeof(unsigned int) * 8 -
> +			__builtin_clz(DA9062AA_VBUCK4_GPI_MASK) - 1),
>  	},
>  	{
>  		.desc.id = DA9061_ID_LDO1,
>  		.desc.name = "DA9061 LDO1",
>  		.desc.of_match = of_match_ptr("ldo1"),
>  		.desc.regulators_node = of_match_ptr("regulators"),
> +		.desc.of_parse_cb = da9062_parse_dt,
>  		.desc.ops = &da9062_ldo_ops,
>  		.desc.min_uV = (900) * 1000,
>  		.desc.uV_step = (50) * 1000,
> @@ -489,6 +568,10 @@ static const struct da9062_regulator_info
> local_da9061_regulator_info[] = {
>  			__builtin_ffs((int)DA9062AA_LDO1_CONF_MASK) - 1,
>  			sizeof(unsigned int) * 8 -
>  			__builtin_clz(DA9062AA_LDO1_CONF_MASK) - 1),
> +		.vsel_gpi = REG_FIELD(DA9062AA_LDO1_CONT,
> +			__builtin_ffs((int)DA9062AA_VLDO1_GPI_MASK) - 1,
> +			sizeof(unsigned int) * 8 -
> +			__builtin_clz(DA9062AA_VLDO1_GPI_MASK) - 1),
>  		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
>  			__builtin_ffs((int)DA9062AA_LDO1_ILIM_MASK) - 1,
>  			sizeof(unsigned int) * 8 -
> @@ -499,6 +582,7 @@ static const struct da9062_regulator_info
> local_da9061_regulator_info[] = {
>  		.desc.name = "DA9061 LDO2",
>  		.desc.of_match = of_match_ptr("ldo2"),
>  		.desc.regulators_node = of_match_ptr("regulators"),
> +		.desc.of_parse_cb = da9062_parse_dt,
>  		.desc.ops = &da9062_ldo_ops,
>  		.desc.min_uV = (900) * 1000,
>  		.desc.uV_step = (50) * 1000,
> @@ -522,6 +606,10 @@ static const struct da9062_regulator_info
> local_da9061_regulator_info[] = {
>  			__builtin_ffs((int)DA9062AA_LDO2_CONF_MASK) - 1,
>  			sizeof(unsigned int) * 8 -
>  			__builtin_clz(DA9062AA_LDO2_CONF_MASK) - 1),
> +		.vsel_gpi = REG_FIELD(DA9062AA_LDO2_CONT,
> +			__builtin_ffs((int)DA9062AA_VLDO2_GPI_MASK) - 1,
> +			sizeof(unsigned int) * 8 -
> +			__builtin_clz(DA9062AA_VLDO2_GPI_MASK) - 1),
>  		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
>  			__builtin_ffs((int)DA9062AA_LDO2_ILIM_MASK) - 1,
>  			sizeof(unsigned int) * 8 -
> @@ -532,6 +620,7 @@ static const struct da9062_regulator_info
> local_da9061_regulator_info[] = {
>  		.desc.name = "DA9061 LDO3",
>  		.desc.of_match = of_match_ptr("ldo3"),
>  		.desc.regulators_node = of_match_ptr("regulators"),
> +		.desc.of_parse_cb = da9062_parse_dt,
>  		.desc.ops = &da9062_ldo_ops,
>  		.desc.min_uV = (900) * 1000,
>  		.desc.uV_step = (50) * 1000,
> @@ -555,6 +644,10 @@ static const struct da9062_regulator_info
> local_da9061_regulator_info[] = {
>  			__builtin_ffs((int)DA9062AA_LDO3_CONF_MASK) - 1,
>  			sizeof(unsigned int) * 8 -
>  			__builtin_clz(DA9062AA_LDO3_CONF_MASK) - 1),
> +		.vsel_gpi = REG_FIELD(DA9062AA_LDO3_CONT,
> +			__builtin_ffs((int)DA9062AA_VLDO3_GPI_MASK) - 1,
> +			sizeof(unsigned int) * 8 -
> +			__builtin_clz(DA9062AA_VLDO3_GPI_MASK) - 1),
>  		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
>  			__builtin_ffs((int)DA9062AA_LDO3_ILIM_MASK) - 1,
>  			sizeof(unsigned int) * 8 -
> @@ -565,6 +658,7 @@ static const struct da9062_regulator_info
> local_da9061_regulator_info[] = {
>  		.desc.name = "DA9061 LDO4",
>  		.desc.of_match = of_match_ptr("ldo4"),
>  		.desc.regulators_node = of_match_ptr("regulators"),
> +		.desc.of_parse_cb = da9062_parse_dt,
>  		.desc.ops = &da9062_ldo_ops,
>  		.desc.min_uV = (900) * 1000,
>  		.desc.uV_step = (50) * 1000,
> @@ -588,6 +682,10 @@ static const struct da9062_regulator_info
> local_da9061_regulator_info[] = {
>  			__builtin_ffs((int)DA9062AA_LDO4_CONF_MASK) - 1,
>  			sizeof(unsigned int) * 8 -
>  			__builtin_clz(DA9062AA_LDO4_CONF_MASK) - 1),
> +		.vsel_gpi = REG_FIELD(DA9062AA_LDO4_CONT,
> +			__builtin_ffs((int)DA9062AA_VLDO4_GPI_MASK) - 1,
> +			sizeof(unsigned int) * 8 -
> +			__builtin_clz(DA9062AA_VLDO4_GPI_MASK) - 1),
>  		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
>  			__builtin_ffs((int)DA9062AA_LDO4_ILIM_MASK) - 1,
>  			sizeof(unsigned int) * 8 -
> @@ -602,6 +700,7 @@ static const struct da9062_regulator_info
> local_da9062_regulator_info[] = {
>  		.desc.name = "DA9062 BUCK1",
>  		.desc.of_match = of_match_ptr("buck1"),
>  		.desc.regulators_node = of_match_ptr("regulators"),
> +		.desc.of_parse_cb = da9062_parse_dt,
>  		.desc.ops = &da9062_buck_ops,
>  		.desc.min_uV = (300) * 1000,
>  		.desc.uV_step = (10) * 1000,
> @@ -632,12 +731,17 @@ static const struct da9062_regulator_info
> local_da9062_regulator_info[] = {
>  			__builtin_ffs((int)DA9062AA_BUCK1_CONF_MASK) - 1,
>  			sizeof(unsigned int) * 8 -
>  			__builtin_clz(DA9062AA_BUCK1_CONF_MASK) - 1),
> +		.vsel_gpi = REG_FIELD(DA9062AA_BUCK1_CONT,
> +			__builtin_ffs((int)DA9062AA_VBUCK1_GPI_MASK) - 1,
> +			sizeof(unsigned int) * 8 -
> +			__builtin_clz(DA9062AA_VBUCK1_GPI_MASK) - 1),
>  	},
>  	{
>  		.desc.id = DA9062_ID_BUCK2,
>  		.desc.name = "DA9062 BUCK2",
>  		.desc.of_match = of_match_ptr("buck2"),
>  		.desc.regulators_node = of_match_ptr("regulators"),
> +		.desc.of_parse_cb = da9062_parse_dt,
>  		.desc.ops = &da9062_buck_ops,
>  		.desc.min_uV = (300) * 1000,
>  		.desc.uV_step = (10) * 1000,
> @@ -668,12 +772,17 @@ static const struct da9062_regulator_info
> local_da9062_regulator_info[] = {
>  			__builtin_ffs((int)DA9062AA_BUCK2_CONF_MASK) - 1,
>  			sizeof(unsigned int) * 8 -
>  			__builtin_clz(DA9062AA_BUCK2_CONF_MASK) - 1),
> +		.vsel_gpi = REG_FIELD(DA9062AA_BUCK2_CONT,
> +			__builtin_ffs((int)DA9062AA_VBUCK2_GPI_MASK) - 1,
> +			sizeof(unsigned int) * 8 -
> +			__builtin_clz(DA9062AA_VBUCK2_GPI_MASK) - 1),
>  	},
>  	{
>  		.desc.id = DA9062_ID_BUCK3,
>  		.desc.name = "DA9062 BUCK3",
>  		.desc.of_match = of_match_ptr("buck3"),
>  		.desc.regulators_node = of_match_ptr("regulators"),
> +		.desc.of_parse_cb = da9062_parse_dt,
>  		.desc.ops = &da9062_buck_ops,
>  		.desc.min_uV = (800) * 1000,
>  		.desc.uV_step = (20) * 1000,
> @@ -704,12 +813,17 @@ static const struct da9062_regulator_info
> local_da9062_regulator_info[] = {
>  			__builtin_ffs((int)DA9062AA_BUCK3_CONF_MASK) - 1,
>  			sizeof(unsigned int) * 8 -
>  			__builtin_clz(DA9062AA_BUCK3_CONF_MASK) - 1),
> +		.vsel_gpi = REG_FIELD(DA9062AA_BUCK3_CONT,
> +			__builtin_ffs((int)DA9062AA_VBUCK3_GPI_MASK) - 1,
> +			sizeof(unsigned int) * 8 -
> +			__builtin_clz(DA9062AA_VBUCK3_GPI_MASK) - 1),
>  	},
>  	{
>  		.desc.id = DA9062_ID_BUCK4,
>  		.desc.name = "DA9062 BUCK4",
>  		.desc.of_match = of_match_ptr("buck4"),
>  		.desc.regulators_node = of_match_ptr("regulators"),
> +		.desc.of_parse_cb = da9062_parse_dt,
>  		.desc.ops = &da9062_buck_ops,
>  		.desc.min_uV = (530) * 1000,
>  		.desc.uV_step = (10) * 1000,
> @@ -740,12 +854,17 @@ static const struct da9062_regulator_info
> local_da9062_regulator_info[] = {
>  			__builtin_ffs((int)DA9062AA_BUCK4_CONF_MASK) - 1,
>  			sizeof(unsigned int) * 8 -
>  			__builtin_clz(DA9062AA_BUCK4_CONF_MASK) - 1),
> +		.vsel_gpi = REG_FIELD(DA9062AA_BUCK4_CONT,
> +			__builtin_ffs((int)DA9062AA_VBUCK4_GPI_MASK) - 1,
> +			sizeof(unsigned int) * 8 -
> +			__builtin_clz(DA9062AA_VBUCK4_GPI_MASK) - 1),
>  	},
>  	{
>  		.desc.id = DA9062_ID_LDO1,
>  		.desc.name = "DA9062 LDO1",
>  		.desc.of_match = of_match_ptr("ldo1"),
>  		.desc.regulators_node = of_match_ptr("regulators"),
> +		.desc.of_parse_cb = da9062_parse_dt,
>  		.desc.ops = &da9062_ldo_ops,
>  		.desc.min_uV = (900) * 1000,
>  		.desc.uV_step = (50) * 1000,
> @@ -769,6 +888,10 @@ static const struct da9062_regulator_info
> local_da9062_regulator_info[] = {
>  			__builtin_ffs((int)DA9062AA_LDO1_CONF_MASK) - 1,
>  			sizeof(unsigned int) * 8 -
>  			__builtin_clz(DA9062AA_LDO1_CONF_MASK) - 1),
> +		.vsel_gpi = REG_FIELD(DA9062AA_LDO1_CONT,
> +			__builtin_ffs((int)DA9062AA_VLDO1_GPI_MASK) - 1,
> +			sizeof(unsigned int) * 8 -
> +			__builtin_clz(DA9062AA_VLDO1_GPI_MASK) - 1),
>  		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
>  			__builtin_ffs((int)DA9062AA_LDO1_ILIM_MASK) - 1,
>  			sizeof(unsigned int) * 8 -
> @@ -779,6 +902,7 @@ static const struct da9062_regulator_info
> local_da9062_regulator_info[] = {
>  		.desc.name = "DA9062 LDO2",
>  		.desc.of_match = of_match_ptr("ldo2"),
>  		.desc.regulators_node = of_match_ptr("regulators"),
> +		.desc.of_parse_cb = da9062_parse_dt,
>  		.desc.ops = &da9062_ldo_ops,
>  		.desc.min_uV = (900) * 1000,
>  		.desc.uV_step = (50) * 1000,
> @@ -802,6 +926,10 @@ static const struct da9062_regulator_info
> local_da9062_regulator_info[] = {
>  			__builtin_ffs((int)DA9062AA_LDO2_CONF_MASK) - 1,
>  			sizeof(unsigned int) * 8 -
>  			__builtin_clz(DA9062AA_LDO2_CONF_MASK) - 1),
> +		.vsel_gpi = REG_FIELD(DA9062AA_LDO2_CONT,
> +			__builtin_ffs((int)DA9062AA_VLDO2_GPI_MASK) - 1,
> +			sizeof(unsigned int) * 8 -
> +			__builtin_clz(DA9062AA_VLDO2_GPI_MASK) - 1),
>  		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
>  			__builtin_ffs((int)DA9062AA_LDO2_ILIM_MASK) - 1,
>  			sizeof(unsigned int) * 8 -
> @@ -812,6 +940,7 @@ static const struct da9062_regulator_info
> local_da9062_regulator_info[] = {
>  		.desc.name = "DA9062 LDO3",
>  		.desc.of_match = of_match_ptr("ldo3"),
>  		.desc.regulators_node = of_match_ptr("regulators"),
> +		.desc.of_parse_cb = da9062_parse_dt,
>  		.desc.ops = &da9062_ldo_ops,
>  		.desc.min_uV = (900) * 1000,
>  		.desc.uV_step = (50) * 1000,
> @@ -835,6 +964,10 @@ static const struct da9062_regulator_info
> local_da9062_regulator_info[] = {
>  			__builtin_ffs((int)DA9062AA_LDO3_CONF_MASK) - 1,
>  			sizeof(unsigned int) * 8 -
>  			__builtin_clz(DA9062AA_LDO3_CONF_MASK) - 1),
> +		.vsel_gpi = REG_FIELD(DA9062AA_LDO3_CONT,
> +			__builtin_ffs((int)DA9062AA_VLDO3_GPI_MASK) - 1,
> +			sizeof(unsigned int) * 8 -
> +			__builtin_clz(DA9062AA_VLDO3_GPI_MASK) - 1),
>  		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
>  			__builtin_ffs((int)DA9062AA_LDO3_ILIM_MASK) - 1,
>  			sizeof(unsigned int) * 8 -
> @@ -845,6 +978,7 @@ static const struct da9062_regulator_info
> local_da9062_regulator_info[] = {
>  		.desc.name = "DA9062 LDO4",
>  		.desc.of_match = of_match_ptr("ldo4"),
>  		.desc.regulators_node = of_match_ptr("regulators"),
> +		.desc.of_parse_cb = da9062_parse_dt,
>  		.desc.ops = &da9062_ldo_ops,
>  		.desc.min_uV = (900) * 1000,
>  		.desc.uV_step = (50) * 1000,
> @@ -868,6 +1002,10 @@ static const struct da9062_regulator_info
> local_da9062_regulator_info[] = {
>  			__builtin_ffs((int)DA9062AA_LDO4_CONF_MASK) - 1,
>  			sizeof(unsigned int) * 8 -
>  			__builtin_clz(DA9062AA_LDO4_CONF_MASK) - 1),
> +		.vsel_gpi = REG_FIELD(DA9062AA_LDO4_CONT,
> +			__builtin_ffs((int)DA9062AA_VLDO4_GPI_MASK) - 1,
> +			sizeof(unsigned int) * 8 -
> +			__builtin_clz(DA9062AA_VLDO4_GPI_MASK) - 1),
>  		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
>  			__builtin_ffs((int)DA9062AA_LDO4_ILIM_MASK) - 1,
>  			sizeof(unsigned int) * 8 -
> @@ -988,6 +1126,15 @@ static int da9062_regulator_probe(struct
> platform_device *pdev)
>  				return PTR_ERR(regl->suspend_sleep);
>  		}
> 
> +		if (regl->info->vsel_gpi.reg) {
> +			regl->vsel_gpi = devm_regmap_field_alloc(
> +					&pdev->dev,
> +					chip->regmap,
> +					regl->info->vsel_gpi);
> +			if (IS_ERR(regl->vsel_gpi))
> +				return PTR_ERR(regl->vsel_gpi);
> +		}
> +
>  		/* Register regulator */
>  		memset(&config, 0, sizeof(config));
>  		config.dev = chip->dev;
> @@ -997,6 +1144,8 @@ static int da9062_regulator_probe(struct
> platform_device *pdev)
>  		regl->rdev = devm_regulator_register(&pdev->dev, &regl->desc,
>  						     &config);
>  		if (IS_ERR(regl->rdev)) {
> +			if (PTR_ERR(regl->rdev) == -EPROBE_DEFER)
> +				return -EPROBE_DEFER;
>  			dev_err(&pdev->dev,
>  				"Failed to register %s regulator\n",
>  				regl->desc.name);
> --
> 2.20.1


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

* Re: [PATCH 2/5] dt-bindings: mfd: da9062: add regulator voltage selection documentation
  2019-09-24  9:23   ` Adam Thomson
@ 2019-09-25 15:51     ` Marco Felsch
  2019-09-25 16:18       ` Adam Thomson
  0 siblings, 1 reply; 29+ messages in thread
From: Marco Felsch @ 2019-09-25 15:51 UTC (permalink / raw)
  To: Adam Thomson
  Cc: Support Opensource, lee.jones, robh+dt, lgirdwood, broonie,
	Steve Twiss, kernel, devicetree, linux-kernel

Hi Adam,

On 19-09-24 09:23, Adam Thomson wrote:
> On 17 September 2019 13:43, Marco Felsch wrote:
> 
> > Add the documentation which describe the voltage selection gpio support.
> > This property can be applied to each subnode within the 'regulators'
> > node so each regulator can be configured differently.
> > 
> > Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
> > ---
> >  Documentation/devicetree/bindings/mfd/da9062.txt | 9 +++++++++
> >  1 file changed, 9 insertions(+)
> > 
> > diff --git a/Documentation/devicetree/bindings/mfd/da9062.txt
> > b/Documentation/devicetree/bindings/mfd/da9062.txt
> > index edca653a5777..9d9820d8177d 100644
> > --- a/Documentation/devicetree/bindings/mfd/da9062.txt
> > +++ b/Documentation/devicetree/bindings/mfd/da9062.txt
> > @@ -66,6 +66,15 @@ Sub-nodes:
> >    details of individual regulator device can be found in:
> >    Documentation/devicetree/bindings/regulator/regulator.txt
> > 
> > +  Optional regulator device-specific properties:
> > +  - dlg,vsel-sense-gpios : The GPIO reference which should be used by the
> > +    regulator to switch the voltage between active/suspend voltage settings. If
> > +    the signal is active the active-settings are applied else the suspend
> > +    settings are applied. Attention: Sharing the same gpio for other purposes
> > +    or across multiple regulators is possible but the gpio settings must be the
> > +    same. Also the gpio phandle must refer to to the dlg,da9062-gpio device
> > +    other gpios are not allowed and make no sense.
> > +
> 
> Should we not use the binding names that are defined in 'gpio-regulator.yaml' as
> these seem to be generic and would probably serve the purpose here?

Hm.. as the description says:

8<--------------------------------------------------
gpios:
   description: Array of one or more GPIO pins used to select the
   regulator voltage/current listed in "states".
8<--------------------------------------------------

But we don't have a "states" property and we can't select between
voltage or current.

Regards,
  Marco

> >  - rtc : This node defines settings required for the Real-Time Clock associated
> >    with the DA9062. There are currently no entries in this binding, however
> >    compatible = "dlg,da9062-rtc" should be added if a node is created.
> > --
> > 2.20.1
> 
> 

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

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

* Re: [PATCH 3/5] regulator: da9062: add voltage selection gpio support
  2019-09-24  9:48   ` Adam Thomson
@ 2019-09-25 15:59     ` Marco Felsch
  0 siblings, 0 replies; 29+ messages in thread
From: Marco Felsch @ 2019-09-25 15:59 UTC (permalink / raw)
  To: Adam Thomson
  Cc: Support Opensource, lee.jones, robh+dt, lgirdwood, broonie,
	Steve Twiss, kernel, devicetree, linux-kernel

Hi Adam,

On 19-09-24 09:48, Adam Thomson wrote:
> On 17 September 2019 13:43, Marco Felsch wrote:
> 
> > The DA9062/1 devices can switch their regulator voltages between
> > voltage-A (active) and voltage-B (suspend) settings. Switching the
> > voltages can be controlled by ther internal state-machine or by a gpio
> > input signal and can be configured for each individual regulator. This
> > commit adds the gpio-based voltage switching support.
> > 
> > Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
> > ---
> >  drivers/regulator/da9062-regulator.c | 149 +++++++++++++++++++++++++++
> >  1 file changed, 149 insertions(+)
> > 
> > diff --git a/drivers/regulator/da9062-regulator.c b/drivers/regulator/da9062-
> > regulator.c
> > index 9b2ca472f70c..9d6eb7625948 100644
> > --- a/drivers/regulator/da9062-regulator.c
> > +++ b/drivers/regulator/da9062-regulator.c
> > @@ -7,6 +7,7 @@
> >  #include <linux/module.h>
> >  #include <linux/init.h>
> >  #include <linux/err.h>
> > +#include <linux/gpio/consumer.h>
> >  #include <linux/slab.h>
> >  #include <linux/of.h>
> >  #include <linux/platform_device.h>
> > @@ -15,6 +16,7 @@
> >  #include <linux/regulator/machine.h>
> >  #include <linux/regulator/of_regulator.h>
> >  #include <linux/mfd/da9062/core.h>
> > +#include <linux/mfd/da9062/gpio.h>
> >  #include <linux/mfd/da9062/registers.h>
> > 
> >  /* Regulator IDs */
> > @@ -50,6 +52,7 @@ struct da9062_regulator_info {
> >  	struct reg_field sleep;
> >  	struct reg_field suspend_sleep;
> >  	unsigned int suspend_vsel_reg;
> > +	struct reg_field vsel_gpi;
> >  	/* Event detection bit */
> >  	struct reg_field oc_event;
> >  };
> > @@ -65,6 +68,7 @@ struct da9062_regulator {
> >  	struct regmap_field			*suspend;
> >  	struct regmap_field			*sleep;
> >  	struct regmap_field			*suspend_sleep;
> > +	struct regmap_field			*vsel_gpi;
> >  };
> > 
> >  /* Encapsulates all information for the regulators driver */
> > @@ -351,6 +355,65 @@ static const struct regulator_ops da9062_ldo_ops = {
> >  	.set_suspend_mode	= da9062_ldo_set_suspend_mode,
> >  };
> > 
> > +static int da9062_config_gpi(struct device_node *np,
> > +			     const struct regulator_desc *desc,
> > +			     struct regulator_config *cfg, const char *gpi_id)
> > +{
> > +	struct da9062_regulator *regl = cfg->driver_data;
> > +	struct gpio_desc *gpi;
> > +	unsigned int nr;
> > +	int ret;
> > +	char *prop, *label;
> > +
> > +	prop = kasprintf(GFP_KERNEL, "dlg,%s-sense-gpios", gpi_id);
> > +	if (!prop)
> > +		return -ENOMEM;
> > +	label = kasprintf(GFP_KERNEL, "%s-%s-gpi", desc->name, gpi_id);
> > +	if (!label) {
> > +		ret = -ENOMEM;
> > +		goto free;
> 
> If we use the generic bindings names then the above will change I guess.

Yes.

> > +	}
> > +
> > +	/*
> > +	 * We only must ensure that the gpio device is probed before the
> > +	 * regulator driver so no need to store the reference global. Luckily
> > +	 * devm_* releases the gpio upon a unbound action.
> > +	 */
> > +	gpi = devm_gpiod_get_from_of_node(cfg->dev, np, prop, 0, GPIOD_IN |
> > +					  GPIOD_FLAGS_BIT_NONEXCLUSIVE,
> > label);
> > +	if (IS_ERR(gpi)) {
> > +		ret = PTR_ERR(gpi);
> > +		goto free;
> > +	}
> > +
> > +	if (!gpi) {
> > +		ret = 0;
> > +		goto free;
> > +	}
> > +
> > +	/* We need the local number */
> > +	nr = da9062_gpio_get_hwgpio(gpi);
> > +	if (nr < 1 || nr > 3) {
> > +		ret = -EINVAL;
> > +		goto free;
> > +	}
> > +
> > +	ret = regmap_field_write(regl->vsel_gpi, nr);
> 
> Actually thinking about this some more, should we really be setting alternate
> functions of the GPIO here? Would this not be done through GPIO/Pinmux
> frameworks? That way the GPIO would be blocked off from other's requesting it.
> This seems a little unsafe, unless I'm mistaken.

The GPIO is used as input, see the flags I passed to
devm_gpiod_get_from_of_node(). What I did here is to tell the regulator
to listen to the gpio input instead of the sequencer. But as I said the
gpio is still configured as input which is absolutly correct. Please
check [1] chapter 7.7.1

[1] https://www.dialog-semiconductor.com/sites/default/files/da9062-a_datasheet_2v3.pdf

Regards,
  Marco

> > +
> > +free:
> > +	kfree(prop);
> > +	kfree(label);
> > +
> > +	return ret;
> > +}
> > +
> > +static int da9062_parse_dt(struct device_node *np,
> > +			   const struct regulator_desc *desc,
> > +			   struct regulator_config *cfg)
> > +{
> > +	return da9062_config_gpi(np, desc, cfg, "vsel");
> > +}
> > +
> >  /* DA9061 Regulator information */
> >  static const struct da9062_regulator_info local_da9061_regulator_info[] = {
> >  	{
> > @@ -358,6 +421,7 @@ static const struct da9062_regulator_info
> > local_da9061_regulator_info[] = {
> >  		.desc.name = "DA9061 BUCK1",
> >  		.desc.of_match = of_match_ptr("buck1"),
> >  		.desc.regulators_node = of_match_ptr("regulators"),
> > +		.desc.of_parse_cb = da9062_parse_dt,
> >  		.desc.ops = &da9062_buck_ops,
> >  		.desc.min_uV = (300) * 1000,
> >  		.desc.uV_step = (10) * 1000,
> > @@ -388,12 +452,17 @@ static const struct da9062_regulator_info
> > local_da9061_regulator_info[] = {
> >  			__builtin_ffs((int)DA9062AA_BUCK1_CONF_MASK) - 1,
> >  			sizeof(unsigned int) * 8 -
> >  			__builtin_clz(DA9062AA_BUCK1_CONF_MASK) - 1),
> > +		.vsel_gpi = REG_FIELD(DA9062AA_BUCK1_CONT,
> > +			__builtin_ffs((int)DA9062AA_VBUCK1_GPI_MASK) - 1,
> > +			sizeof(unsigned int) * 8 -
> > +			__builtin_clz(DA9062AA_VBUCK1_GPI_MASK) - 1),
> >  	},
> >  	{
> >  		.desc.id = DA9061_ID_BUCK2,
> >  		.desc.name = "DA9061 BUCK2",
> >  		.desc.of_match = of_match_ptr("buck2"),
> >  		.desc.regulators_node = of_match_ptr("regulators"),
> > +		.desc.of_parse_cb = da9062_parse_dt,
> >  		.desc.ops = &da9062_buck_ops,
> >  		.desc.min_uV = (800) * 1000,
> >  		.desc.uV_step = (20) * 1000,
> > @@ -424,12 +493,17 @@ static const struct da9062_regulator_info
> > local_da9061_regulator_info[] = {
> >  			__builtin_ffs((int)DA9062AA_BUCK3_CONF_MASK) - 1,
> >  			sizeof(unsigned int) * 8 -
> >  			__builtin_clz(DA9062AA_BUCK3_CONF_MASK) - 1),
> > +		.vsel_gpi = REG_FIELD(DA9062AA_BUCK3_CONT,
> > +			__builtin_ffs((int)DA9062AA_VBUCK3_GPI_MASK) - 1,
> > +			sizeof(unsigned int) * 8 -
> > +			__builtin_clz(DA9062AA_VBUCK3_GPI_MASK) - 1),
> >  	},
> >  	{
> >  		.desc.id = DA9061_ID_BUCK3,
> >  		.desc.name = "DA9061 BUCK3",
> >  		.desc.of_match = of_match_ptr("buck3"),
> >  		.desc.regulators_node = of_match_ptr("regulators"),
> > +		.desc.of_parse_cb = da9062_parse_dt,
> >  		.desc.ops = &da9062_buck_ops,
> >  		.desc.min_uV = (530) * 1000,
> >  		.desc.uV_step = (10) * 1000,
> > @@ -460,12 +534,17 @@ static const struct da9062_regulator_info
> > local_da9061_regulator_info[] = {
> >  			__builtin_ffs((int)DA9062AA_BUCK4_CONF_MASK) - 1,
> >  			sizeof(unsigned int) * 8 -
> >  			__builtin_clz(DA9062AA_BUCK4_CONF_MASK) - 1),
> > +		.vsel_gpi = REG_FIELD(DA9062AA_BUCK4_CONT,
> > +			__builtin_ffs((int)DA9062AA_VBUCK4_GPI_MASK) - 1,
> > +			sizeof(unsigned int) * 8 -
> > +			__builtin_clz(DA9062AA_VBUCK4_GPI_MASK) - 1),
> >  	},
> >  	{
> >  		.desc.id = DA9061_ID_LDO1,
> >  		.desc.name = "DA9061 LDO1",
> >  		.desc.of_match = of_match_ptr("ldo1"),
> >  		.desc.regulators_node = of_match_ptr("regulators"),
> > +		.desc.of_parse_cb = da9062_parse_dt,
> >  		.desc.ops = &da9062_ldo_ops,
> >  		.desc.min_uV = (900) * 1000,
> >  		.desc.uV_step = (50) * 1000,
> > @@ -489,6 +568,10 @@ static const struct da9062_regulator_info
> > local_da9061_regulator_info[] = {
> >  			__builtin_ffs((int)DA9062AA_LDO1_CONF_MASK) - 1,
> >  			sizeof(unsigned int) * 8 -
> >  			__builtin_clz(DA9062AA_LDO1_CONF_MASK) - 1),
> > +		.vsel_gpi = REG_FIELD(DA9062AA_LDO1_CONT,
> > +			__builtin_ffs((int)DA9062AA_VLDO1_GPI_MASK) - 1,
> > +			sizeof(unsigned int) * 8 -
> > +			__builtin_clz(DA9062AA_VLDO1_GPI_MASK) - 1),
> >  		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
> >  			__builtin_ffs((int)DA9062AA_LDO1_ILIM_MASK) - 1,
> >  			sizeof(unsigned int) * 8 -
> > @@ -499,6 +582,7 @@ static const struct da9062_regulator_info
> > local_da9061_regulator_info[] = {
> >  		.desc.name = "DA9061 LDO2",
> >  		.desc.of_match = of_match_ptr("ldo2"),
> >  		.desc.regulators_node = of_match_ptr("regulators"),
> > +		.desc.of_parse_cb = da9062_parse_dt,
> >  		.desc.ops = &da9062_ldo_ops,
> >  		.desc.min_uV = (900) * 1000,
> >  		.desc.uV_step = (50) * 1000,
> > @@ -522,6 +606,10 @@ static const struct da9062_regulator_info
> > local_da9061_regulator_info[] = {
> >  			__builtin_ffs((int)DA9062AA_LDO2_CONF_MASK) - 1,
> >  			sizeof(unsigned int) * 8 -
> >  			__builtin_clz(DA9062AA_LDO2_CONF_MASK) - 1),
> > +		.vsel_gpi = REG_FIELD(DA9062AA_LDO2_CONT,
> > +			__builtin_ffs((int)DA9062AA_VLDO2_GPI_MASK) - 1,
> > +			sizeof(unsigned int) * 8 -
> > +			__builtin_clz(DA9062AA_VLDO2_GPI_MASK) - 1),
> >  		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
> >  			__builtin_ffs((int)DA9062AA_LDO2_ILIM_MASK) - 1,
> >  			sizeof(unsigned int) * 8 -
> > @@ -532,6 +620,7 @@ static const struct da9062_regulator_info
> > local_da9061_regulator_info[] = {
> >  		.desc.name = "DA9061 LDO3",
> >  		.desc.of_match = of_match_ptr("ldo3"),
> >  		.desc.regulators_node = of_match_ptr("regulators"),
> > +		.desc.of_parse_cb = da9062_parse_dt,
> >  		.desc.ops = &da9062_ldo_ops,
> >  		.desc.min_uV = (900) * 1000,
> >  		.desc.uV_step = (50) * 1000,
> > @@ -555,6 +644,10 @@ static const struct da9062_regulator_info
> > local_da9061_regulator_info[] = {
> >  			__builtin_ffs((int)DA9062AA_LDO3_CONF_MASK) - 1,
> >  			sizeof(unsigned int) * 8 -
> >  			__builtin_clz(DA9062AA_LDO3_CONF_MASK) - 1),
> > +		.vsel_gpi = REG_FIELD(DA9062AA_LDO3_CONT,
> > +			__builtin_ffs((int)DA9062AA_VLDO3_GPI_MASK) - 1,
> > +			sizeof(unsigned int) * 8 -
> > +			__builtin_clz(DA9062AA_VLDO3_GPI_MASK) - 1),
> >  		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
> >  			__builtin_ffs((int)DA9062AA_LDO3_ILIM_MASK) - 1,
> >  			sizeof(unsigned int) * 8 -
> > @@ -565,6 +658,7 @@ static const struct da9062_regulator_info
> > local_da9061_regulator_info[] = {
> >  		.desc.name = "DA9061 LDO4",
> >  		.desc.of_match = of_match_ptr("ldo4"),
> >  		.desc.regulators_node = of_match_ptr("regulators"),
> > +		.desc.of_parse_cb = da9062_parse_dt,
> >  		.desc.ops = &da9062_ldo_ops,
> >  		.desc.min_uV = (900) * 1000,
> >  		.desc.uV_step = (50) * 1000,
> > @@ -588,6 +682,10 @@ static const struct da9062_regulator_info
> > local_da9061_regulator_info[] = {
> >  			__builtin_ffs((int)DA9062AA_LDO4_CONF_MASK) - 1,
> >  			sizeof(unsigned int) * 8 -
> >  			__builtin_clz(DA9062AA_LDO4_CONF_MASK) - 1),
> > +		.vsel_gpi = REG_FIELD(DA9062AA_LDO4_CONT,
> > +			__builtin_ffs((int)DA9062AA_VLDO4_GPI_MASK) - 1,
> > +			sizeof(unsigned int) * 8 -
> > +			__builtin_clz(DA9062AA_VLDO4_GPI_MASK) - 1),
> >  		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
> >  			__builtin_ffs((int)DA9062AA_LDO4_ILIM_MASK) - 1,
> >  			sizeof(unsigned int) * 8 -
> > @@ -602,6 +700,7 @@ static const struct da9062_regulator_info
> > local_da9062_regulator_info[] = {
> >  		.desc.name = "DA9062 BUCK1",
> >  		.desc.of_match = of_match_ptr("buck1"),
> >  		.desc.regulators_node = of_match_ptr("regulators"),
> > +		.desc.of_parse_cb = da9062_parse_dt,
> >  		.desc.ops = &da9062_buck_ops,
> >  		.desc.min_uV = (300) * 1000,
> >  		.desc.uV_step = (10) * 1000,
> > @@ -632,12 +731,17 @@ static const struct da9062_regulator_info
> > local_da9062_regulator_info[] = {
> >  			__builtin_ffs((int)DA9062AA_BUCK1_CONF_MASK) - 1,
> >  			sizeof(unsigned int) * 8 -
> >  			__builtin_clz(DA9062AA_BUCK1_CONF_MASK) - 1),
> > +		.vsel_gpi = REG_FIELD(DA9062AA_BUCK1_CONT,
> > +			__builtin_ffs((int)DA9062AA_VBUCK1_GPI_MASK) - 1,
> > +			sizeof(unsigned int) * 8 -
> > +			__builtin_clz(DA9062AA_VBUCK1_GPI_MASK) - 1),
> >  	},
> >  	{
> >  		.desc.id = DA9062_ID_BUCK2,
> >  		.desc.name = "DA9062 BUCK2",
> >  		.desc.of_match = of_match_ptr("buck2"),
> >  		.desc.regulators_node = of_match_ptr("regulators"),
> > +		.desc.of_parse_cb = da9062_parse_dt,
> >  		.desc.ops = &da9062_buck_ops,
> >  		.desc.min_uV = (300) * 1000,
> >  		.desc.uV_step = (10) * 1000,
> > @@ -668,12 +772,17 @@ static const struct da9062_regulator_info
> > local_da9062_regulator_info[] = {
> >  			__builtin_ffs((int)DA9062AA_BUCK2_CONF_MASK) - 1,
> >  			sizeof(unsigned int) * 8 -
> >  			__builtin_clz(DA9062AA_BUCK2_CONF_MASK) - 1),
> > +		.vsel_gpi = REG_FIELD(DA9062AA_BUCK2_CONT,
> > +			__builtin_ffs((int)DA9062AA_VBUCK2_GPI_MASK) - 1,
> > +			sizeof(unsigned int) * 8 -
> > +			__builtin_clz(DA9062AA_VBUCK2_GPI_MASK) - 1),
> >  	},
> >  	{
> >  		.desc.id = DA9062_ID_BUCK3,
> >  		.desc.name = "DA9062 BUCK3",
> >  		.desc.of_match = of_match_ptr("buck3"),
> >  		.desc.regulators_node = of_match_ptr("regulators"),
> > +		.desc.of_parse_cb = da9062_parse_dt,
> >  		.desc.ops = &da9062_buck_ops,
> >  		.desc.min_uV = (800) * 1000,
> >  		.desc.uV_step = (20) * 1000,
> > @@ -704,12 +813,17 @@ static const struct da9062_regulator_info
> > local_da9062_regulator_info[] = {
> >  			__builtin_ffs((int)DA9062AA_BUCK3_CONF_MASK) - 1,
> >  			sizeof(unsigned int) * 8 -
> >  			__builtin_clz(DA9062AA_BUCK3_CONF_MASK) - 1),
> > +		.vsel_gpi = REG_FIELD(DA9062AA_BUCK3_CONT,
> > +			__builtin_ffs((int)DA9062AA_VBUCK3_GPI_MASK) - 1,
> > +			sizeof(unsigned int) * 8 -
> > +			__builtin_clz(DA9062AA_VBUCK3_GPI_MASK) - 1),
> >  	},
> >  	{
> >  		.desc.id = DA9062_ID_BUCK4,
> >  		.desc.name = "DA9062 BUCK4",
> >  		.desc.of_match = of_match_ptr("buck4"),
> >  		.desc.regulators_node = of_match_ptr("regulators"),
> > +		.desc.of_parse_cb = da9062_parse_dt,
> >  		.desc.ops = &da9062_buck_ops,
> >  		.desc.min_uV = (530) * 1000,
> >  		.desc.uV_step = (10) * 1000,
> > @@ -740,12 +854,17 @@ static const struct da9062_regulator_info
> > local_da9062_regulator_info[] = {
> >  			__builtin_ffs((int)DA9062AA_BUCK4_CONF_MASK) - 1,
> >  			sizeof(unsigned int) * 8 -
> >  			__builtin_clz(DA9062AA_BUCK4_CONF_MASK) - 1),
> > +		.vsel_gpi = REG_FIELD(DA9062AA_BUCK4_CONT,
> > +			__builtin_ffs((int)DA9062AA_VBUCK4_GPI_MASK) - 1,
> > +			sizeof(unsigned int) * 8 -
> > +			__builtin_clz(DA9062AA_VBUCK4_GPI_MASK) - 1),
> >  	},
> >  	{
> >  		.desc.id = DA9062_ID_LDO1,
> >  		.desc.name = "DA9062 LDO1",
> >  		.desc.of_match = of_match_ptr("ldo1"),
> >  		.desc.regulators_node = of_match_ptr("regulators"),
> > +		.desc.of_parse_cb = da9062_parse_dt,
> >  		.desc.ops = &da9062_ldo_ops,
> >  		.desc.min_uV = (900) * 1000,
> >  		.desc.uV_step = (50) * 1000,
> > @@ -769,6 +888,10 @@ static const struct da9062_regulator_info
> > local_da9062_regulator_info[] = {
> >  			__builtin_ffs((int)DA9062AA_LDO1_CONF_MASK) - 1,
> >  			sizeof(unsigned int) * 8 -
> >  			__builtin_clz(DA9062AA_LDO1_CONF_MASK) - 1),
> > +		.vsel_gpi = REG_FIELD(DA9062AA_LDO1_CONT,
> > +			__builtin_ffs((int)DA9062AA_VLDO1_GPI_MASK) - 1,
> > +			sizeof(unsigned int) * 8 -
> > +			__builtin_clz(DA9062AA_VLDO1_GPI_MASK) - 1),
> >  		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
> >  			__builtin_ffs((int)DA9062AA_LDO1_ILIM_MASK) - 1,
> >  			sizeof(unsigned int) * 8 -
> > @@ -779,6 +902,7 @@ static const struct da9062_regulator_info
> > local_da9062_regulator_info[] = {
> >  		.desc.name = "DA9062 LDO2",
> >  		.desc.of_match = of_match_ptr("ldo2"),
> >  		.desc.regulators_node = of_match_ptr("regulators"),
> > +		.desc.of_parse_cb = da9062_parse_dt,
> >  		.desc.ops = &da9062_ldo_ops,
> >  		.desc.min_uV = (900) * 1000,
> >  		.desc.uV_step = (50) * 1000,
> > @@ -802,6 +926,10 @@ static const struct da9062_regulator_info
> > local_da9062_regulator_info[] = {
> >  			__builtin_ffs((int)DA9062AA_LDO2_CONF_MASK) - 1,
> >  			sizeof(unsigned int) * 8 -
> >  			__builtin_clz(DA9062AA_LDO2_CONF_MASK) - 1),
> > +		.vsel_gpi = REG_FIELD(DA9062AA_LDO2_CONT,
> > +			__builtin_ffs((int)DA9062AA_VLDO2_GPI_MASK) - 1,
> > +			sizeof(unsigned int) * 8 -
> > +			__builtin_clz(DA9062AA_VLDO2_GPI_MASK) - 1),
> >  		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
> >  			__builtin_ffs((int)DA9062AA_LDO2_ILIM_MASK) - 1,
> >  			sizeof(unsigned int) * 8 -
> > @@ -812,6 +940,7 @@ static const struct da9062_regulator_info
> > local_da9062_regulator_info[] = {
> >  		.desc.name = "DA9062 LDO3",
> >  		.desc.of_match = of_match_ptr("ldo3"),
> >  		.desc.regulators_node = of_match_ptr("regulators"),
> > +		.desc.of_parse_cb = da9062_parse_dt,
> >  		.desc.ops = &da9062_ldo_ops,
> >  		.desc.min_uV = (900) * 1000,
> >  		.desc.uV_step = (50) * 1000,
> > @@ -835,6 +964,10 @@ static const struct da9062_regulator_info
> > local_da9062_regulator_info[] = {
> >  			__builtin_ffs((int)DA9062AA_LDO3_CONF_MASK) - 1,
> >  			sizeof(unsigned int) * 8 -
> >  			__builtin_clz(DA9062AA_LDO3_CONF_MASK) - 1),
> > +		.vsel_gpi = REG_FIELD(DA9062AA_LDO3_CONT,
> > +			__builtin_ffs((int)DA9062AA_VLDO3_GPI_MASK) - 1,
> > +			sizeof(unsigned int) * 8 -
> > +			__builtin_clz(DA9062AA_VLDO3_GPI_MASK) - 1),
> >  		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
> >  			__builtin_ffs((int)DA9062AA_LDO3_ILIM_MASK) - 1,
> >  			sizeof(unsigned int) * 8 -
> > @@ -845,6 +978,7 @@ static const struct da9062_regulator_info
> > local_da9062_regulator_info[] = {
> >  		.desc.name = "DA9062 LDO4",
> >  		.desc.of_match = of_match_ptr("ldo4"),
> >  		.desc.regulators_node = of_match_ptr("regulators"),
> > +		.desc.of_parse_cb = da9062_parse_dt,
> >  		.desc.ops = &da9062_ldo_ops,
> >  		.desc.min_uV = (900) * 1000,
> >  		.desc.uV_step = (50) * 1000,
> > @@ -868,6 +1002,10 @@ static const struct da9062_regulator_info
> > local_da9062_regulator_info[] = {
> >  			__builtin_ffs((int)DA9062AA_LDO4_CONF_MASK) - 1,
> >  			sizeof(unsigned int) * 8 -
> >  			__builtin_clz(DA9062AA_LDO4_CONF_MASK) - 1),
> > +		.vsel_gpi = REG_FIELD(DA9062AA_LDO4_CONT,
> > +			__builtin_ffs((int)DA9062AA_VLDO4_GPI_MASK) - 1,
> > +			sizeof(unsigned int) * 8 -
> > +			__builtin_clz(DA9062AA_VLDO4_GPI_MASK) - 1),
> >  		.oc_event = REG_FIELD(DA9062AA_STATUS_D,
> >  			__builtin_ffs((int)DA9062AA_LDO4_ILIM_MASK) - 1,
> >  			sizeof(unsigned int) * 8 -
> > @@ -988,6 +1126,15 @@ static int da9062_regulator_probe(struct
> > platform_device *pdev)
> >  				return PTR_ERR(regl->suspend_sleep);
> >  		}
> > 
> > +		if (regl->info->vsel_gpi.reg) {
> > +			regl->vsel_gpi = devm_regmap_field_alloc(
> > +					&pdev->dev,
> > +					chip->regmap,
> > +					regl->info->vsel_gpi);
> > +			if (IS_ERR(regl->vsel_gpi))
> > +				return PTR_ERR(regl->vsel_gpi);
> > +		}
> > +
> >  		/* Register regulator */
> >  		memset(&config, 0, sizeof(config));
> >  		config.dev = chip->dev;
> > @@ -997,6 +1144,8 @@ static int da9062_regulator_probe(struct
> > platform_device *pdev)
> >  		regl->rdev = devm_regulator_register(&pdev->dev, &regl->desc,
> >  						     &config);
> >  		if (IS_ERR(regl->rdev)) {
> > +			if (PTR_ERR(regl->rdev) == -EPROBE_DEFER)
> > +				return -EPROBE_DEFER;
> >  			dev_err(&pdev->dev,
> >  				"Failed to register %s regulator\n",
> >  				regl->desc.name);
> > --
> > 2.20.1
> 
> 

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

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

* RE: [PATCH 2/5] dt-bindings: mfd: da9062: add regulator voltage selection documentation
  2019-09-25 15:51     ` Marco Felsch
@ 2019-09-25 16:18       ` Adam Thomson
  2019-09-26  8:09         ` Marco Felsch
  0 siblings, 1 reply; 29+ messages in thread
From: Adam Thomson @ 2019-09-25 16:18 UTC (permalink / raw)
  To: Marco Felsch, Adam Thomson
  Cc: Support Opensource, lee.jones, robh+dt, lgirdwood, broonie,
	Steve Twiss, kernel, devicetree, linux-kernel

On 25 September 2019 16:52, Marco Felsch wrote:

> Hi Adam,
> 
> On 19-09-24 09:23, Adam Thomson wrote:
> > On 17 September 2019 13:43, Marco Felsch wrote:
> >
> > > Add the documentation which describe the voltage selection gpio support.
> > > This property can be applied to each subnode within the 'regulators'
> > > node so each regulator can be configured differently.
> > >
> > > Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
> > > ---
> > >  Documentation/devicetree/bindings/mfd/da9062.txt | 9 +++++++++
> > >  1 file changed, 9 insertions(+)
> > >
> > > diff --git a/Documentation/devicetree/bindings/mfd/da9062.txt
> > > b/Documentation/devicetree/bindings/mfd/da9062.txt
> > > index edca653a5777..9d9820d8177d 100644
> > > --- a/Documentation/devicetree/bindings/mfd/da9062.txt
> > > +++ b/Documentation/devicetree/bindings/mfd/da9062.txt
> > > @@ -66,6 +66,15 @@ Sub-nodes:
> > >    details of individual regulator device can be found in:
> > >    Documentation/devicetree/bindings/regulator/regulator.txt
> > >
> > > +  Optional regulator device-specific properties:
> > > +  - dlg,vsel-sense-gpios : The GPIO reference which should be used by the
> > > +    regulator to switch the voltage between active/suspend voltage settings.
> If
> > > +    the signal is active the active-settings are applied else the suspend
> > > +    settings are applied. Attention: Sharing the same gpio for other purposes
> > > +    or across multiple regulators is possible but the gpio settings must be the
> > > +    same. Also the gpio phandle must refer to to the dlg,da9062-gpio device
> > > +    other gpios are not allowed and make no sense.
> > > +
> >
> > Should we not use the binding names that are defined in 'gpio-regulator.yaml'
> as
> > these seem to be generic and would probably serve the purpose here?
> 
> Hm.. as the description says:
> 
> 8<--------------------------------------------------
> gpios:
>    description: Array of one or more GPIO pins used to select the
>    regulator voltage/current listed in "states".
> 8<--------------------------------------------------
> 
> But we don't have a "states" property and we can't select between
> voltage or current.

Yes I think I was at cross purposes when I made this remark. The bindings there
describe the GPOs that are used to enable/disable and set voltage/current for
regulators and the supported voltage/current levels that can be configured in
this manner. What you're describing is the GPI for DA9061/2. If you look at
GPIO handling in existing regulator drivers I believe they all deal with external
GPOs that are configured to enable/disable and set voltage/current limits rather
than the GPI on the PMIC itself. That's why I'm thinking that the configurations
you're doing here should actually be in a pinctrl or GPIO driver.

I'd be interested in hearing Mark's view on this though as he has far more
experience in this area than I do.

> 
> Regards,
>   Marco
> 
> > >  - rtc : This node defines settings required for the Real-Time Clock associated
> > >    with the DA9062. There are currently no entries in this binding, however
> > >    compatible = "dlg,da9062-rtc" should be added if a node is created.
> > > --
> > > 2.20.1
> >
> >
> 
> --
> Pengutronix e.K.                           |                             |
> Industrial Linux Solutions                 | http://www.pengutronix.de/  |
> Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
> Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

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

* Re: [PATCH 2/5] dt-bindings: mfd: da9062: add regulator voltage selection documentation
  2019-09-25 16:18       ` Adam Thomson
@ 2019-09-26  8:09         ` Marco Felsch
  2019-09-26 10:17           ` Adam Thomson
  0 siblings, 1 reply; 29+ messages in thread
From: Marco Felsch @ 2019-09-26  8:09 UTC (permalink / raw)
  To: Adam Thomson
  Cc: Support Opensource, lee.jones, robh+dt, lgirdwood, broonie,
	Steve Twiss, kernel, devicetree, linux-kernel

On 19-09-25 16:18, Adam Thomson wrote:
> On 25 September 2019 16:52, Marco Felsch wrote:
> 
> > Hi Adam,
> > 
> > On 19-09-24 09:23, Adam Thomson wrote:
> > > On 17 September 2019 13:43, Marco Felsch wrote:
> > >
> > > > Add the documentation which describe the voltage selection gpio support.
> > > > This property can be applied to each subnode within the 'regulators'
> > > > node so each regulator can be configured differently.
> > > >
> > > > Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
> > > > ---
> > > >  Documentation/devicetree/bindings/mfd/da9062.txt | 9 +++++++++
> > > >  1 file changed, 9 insertions(+)
> > > >
> > > > diff --git a/Documentation/devicetree/bindings/mfd/da9062.txt
> > > > b/Documentation/devicetree/bindings/mfd/da9062.txt
> > > > index edca653a5777..9d9820d8177d 100644
> > > > --- a/Documentation/devicetree/bindings/mfd/da9062.txt
> > > > +++ b/Documentation/devicetree/bindings/mfd/da9062.txt
> > > > @@ -66,6 +66,15 @@ Sub-nodes:
> > > >    details of individual regulator device can be found in:
> > > >    Documentation/devicetree/bindings/regulator/regulator.txt
> > > >
> > > > +  Optional regulator device-specific properties:
> > > > +  - dlg,vsel-sense-gpios : The GPIO reference which should be used by the
> > > > +    regulator to switch the voltage between active/suspend voltage settings.
> > If
> > > > +    the signal is active the active-settings are applied else the suspend
> > > > +    settings are applied. Attention: Sharing the same gpio for other purposes
> > > > +    or across multiple regulators is possible but the gpio settings must be the
> > > > +    same. Also the gpio phandle must refer to to the dlg,da9062-gpio device
> > > > +    other gpios are not allowed and make no sense.
> > > > +
> > >
> > > Should we not use the binding names that are defined in 'gpio-regulator.yaml'
> > as
> > > these seem to be generic and would probably serve the purpose here?
> > 
> > Hm.. as the description says:
> > 
> > 8<--------------------------------------------------
> > gpios:
> >    description: Array of one or more GPIO pins used to select the
> >    regulator voltage/current listed in "states".
> > 8<--------------------------------------------------
> > 
> > But we don't have a "states" property and we can't select between
> > voltage or current.
> 
> Yes I think I was at cross purposes when I made this remark. The bindings there
> describe the GPOs that are used to enable/disable and set voltage/current for
> regulators and the supported voltage/current levels that can be configured in
> this manner. What you're describing is the GPI for DA9061/2. If you look at
> GPIO handling in existing regulator drivers I believe they all deal with external
> GPOs that are configured to enable/disable and set voltage/current limits rather
> than the GPI on the PMIC itself. That's why I'm thinking that the configurations
> you're doing here should actually be in a pinctrl or GPIO driver.

That's true, the common gpio bindings are from the view of the
processor, e.g. which gpio must the processor drive to enable/switch the
regualtor. So one reasone more to use a non-common binding.

Please take a look on my other comment I made :) I don't use the
gpio-alternative function. I use it as an input.

Regards,
  Marco


> I'd be interested in hearing Mark's view on this though as he has far more
> experience in this area than I do.
> 
> > 
> > Regards,
> >   Marco
> > 
> > > >  - rtc : This node defines settings required for the Real-Time Clock associated
> > > >    with the DA9062. There are currently no entries in this binding, however
> > > >    compatible = "dlg,da9062-rtc" should be added if a node is created.
> > > > --
> > > > 2.20.1
> > >
> > >
> > 
> > --
> > Pengutronix e.K.                           |                             |
> > Industrial Linux Solutions                 | http://www.pengutronix.de/  |
> > Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
> > Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
> 

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

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

* RE: [PATCH 2/5] dt-bindings: mfd: da9062: add regulator voltage selection documentation
  2019-09-26  8:09         ` Marco Felsch
@ 2019-09-26 10:17           ` Adam Thomson
  2019-09-26 11:43             ` Marco Felsch
  0 siblings, 1 reply; 29+ messages in thread
From: Adam Thomson @ 2019-09-26 10:17 UTC (permalink / raw)
  To: Marco Felsch, Adam Thomson
  Cc: Support Opensource, lee.jones, robh+dt, lgirdwood, broonie,
	Steve Twiss, kernel, devicetree, linux-kernel

On 26 September 2019 09:10, Marco Felsch wrote:

> On 19-09-25 16:18, Adam Thomson wrote:
> > On 25 September 2019 16:52, Marco Felsch wrote:
> >
> > > Hi Adam,
> > >
> > > On 19-09-24 09:23, Adam Thomson wrote:
> > > > On 17 September 2019 13:43, Marco Felsch wrote:
> > > >
> > > > > Add the documentation which describe the voltage selection gpio
> support.
> > > > > This property can be applied to each subnode within the 'regulators'
> > > > > node so each regulator can be configured differently.
> > > > >
> > > > > Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
> > > > > ---
> > > > >  Documentation/devicetree/bindings/mfd/da9062.txt | 9 +++++++++
> > > > >  1 file changed, 9 insertions(+)
> > > > >
> > > > > diff --git a/Documentation/devicetree/bindings/mfd/da9062.txt
> > > > > b/Documentation/devicetree/bindings/mfd/da9062.txt
> > > > > index edca653a5777..9d9820d8177d 100644
> > > > > --- a/Documentation/devicetree/bindings/mfd/da9062.txt
> > > > > +++ b/Documentation/devicetree/bindings/mfd/da9062.txt
> > > > > @@ -66,6 +66,15 @@ Sub-nodes:
> > > > >    details of individual regulator device can be found in:
> > > > >    Documentation/devicetree/bindings/regulator/regulator.txt
> > > > >
> > > > > +  Optional regulator device-specific properties:
> > > > > +  - dlg,vsel-sense-gpios : The GPIO reference which should be used by
> the
> > > > > +    regulator to switch the voltage between active/suspend voltage
> settings.
> > > If
> > > > > +    the signal is active the active-settings are applied else the suspend
> > > > > +    settings are applied. Attention: Sharing the same gpio for other
> purposes
> > > > > +    or across multiple regulators is possible but the gpio settings must be
> the
> > > > > +    same. Also the gpio phandle must refer to to the dlg,da9062-gpio
> device
> > > > > +    other gpios are not allowed and make no sense.
> > > > > +
> > > >
> > > > Should we not use the binding names that are defined in 'gpio-
> regulator.yaml'
> > > as
> > > > these seem to be generic and would probably serve the purpose here?
> > >
> > > Hm.. as the description says:
> > >
> > > 8<--------------------------------------------------
> > > gpios:
> > >    description: Array of one or more GPIO pins used to select the
> > >    regulator voltage/current listed in "states".
> > > 8<--------------------------------------------------
> > >
> > > But we don't have a "states" property and we can't select between
> > > voltage or current.
> >
> > Yes I think I was at cross purposes when I made this remark. The bindings there
> > describe the GPOs that are used to enable/disable and set voltage/current for
> > regulators and the supported voltage/current levels that can be configured in
> > this manner. What you're describing is the GPI for DA9061/2. If you look at
> > GPIO handling in existing regulator drivers I believe they all deal with external
> > GPOs that are configured to enable/disable and set voltage/current limits
> rather
> > than the GPI on the PMIC itself. That's why I'm thinking that the configurations
> > you're doing here should actually be in a pinctrl or GPIO driver.
> 
> That's true, the common gpio bindings are from the view of the
> processor, e.g. which gpio must the processor drive to enable/switch the
> regualtor. So one reasone more to use a non-common binding.
> 
> Please take a look on my other comment I made :) I don't use the
> gpio-alternative function. I use it as an input.

I know in the datasheet this isn't marked as an alternate function specifically
but to me having regulator control by the chip's own GPI is an alternative
function for that GPIO pin, in the same way a specific pin can be used for
SYS_EN or Watchdog control. It's a dedicated purpose rather than being a normal
GPI.

See the following as an example of what I'm suggesting:

https://elixir.bootlin.com/linux/latest/source/Documentation/devicetree/bindings/pinctrl/pinctrl-palmas.txt

You could then pass the pinctrl information to the regulator driver and use
that rather than having device specific bindings for this. That's at least my
current interpretation of this anyway.

> 
> Regards,
>   Marco
> 
> 
> > I'd be interested in hearing Mark's view on this though as he has far more
> > experience in this area than I do.
> >
> > >
> > > Regards,
> > >   Marco
> > >
> > > > >  - rtc : This node defines settings required for the Real-Time Clock
> associated
> > > > >    with the DA9062. There are currently no entries in this binding, however
> > > > >    compatible = "dlg,da9062-rtc" should be added if a node is created.
> > > > > --
> > > > > 2.20.1
> > > >
> > > >
> > >
> > > --
> > > Pengutronix e.K.                           |                             |
> > > Industrial Linux Solutions                 | http://www.pengutronix.de/  |
> > > Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
> > > Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
> >
> 
> --
> Pengutronix e.K.                           |                             |
> Industrial Linux Solutions                 | http://www.pengutronix.de/  |
> Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
> Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

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

* Re: [PATCH 2/5] dt-bindings: mfd: da9062: add regulator voltage selection documentation
  2019-09-26 10:17           ` Adam Thomson
@ 2019-09-26 11:43             ` Marco Felsch
  2019-09-26 14:04               ` Adam Thomson
  0 siblings, 1 reply; 29+ messages in thread
From: Marco Felsch @ 2019-09-26 11:43 UTC (permalink / raw)
  To: Adam Thomson
  Cc: Support Opensource, lee.jones, robh+dt, lgirdwood, broonie,
	Steve Twiss, kernel, devicetree, linux-kernel

On 19-09-26 10:17, Adam Thomson wrote:
> On 26 September 2019 09:10, Marco Felsch wrote:
> 
> > On 19-09-25 16:18, Adam Thomson wrote:
> > > On 25 September 2019 16:52, Marco Felsch wrote:
> > >
> > > > Hi Adam,
> > > >
> > > > On 19-09-24 09:23, Adam Thomson wrote:
> > > > > On 17 September 2019 13:43, Marco Felsch wrote:
> > > > >
> > > > > > Add the documentation which describe the voltage selection gpio
> > support.
> > > > > > This property can be applied to each subnode within the 'regulators'
> > > > > > node so each regulator can be configured differently.
> > > > > >
> > > > > > Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
> > > > > > ---
> > > > > >  Documentation/devicetree/bindings/mfd/da9062.txt | 9 +++++++++
> > > > > >  1 file changed, 9 insertions(+)
> > > > > >
> > > > > > diff --git a/Documentation/devicetree/bindings/mfd/da9062.txt
> > > > > > b/Documentation/devicetree/bindings/mfd/da9062.txt
> > > > > > index edca653a5777..9d9820d8177d 100644
> > > > > > --- a/Documentation/devicetree/bindings/mfd/da9062.txt
> > > > > > +++ b/Documentation/devicetree/bindings/mfd/da9062.txt
> > > > > > @@ -66,6 +66,15 @@ Sub-nodes:
> > > > > >    details of individual regulator device can be found in:
> > > > > >    Documentation/devicetree/bindings/regulator/regulator.txt
> > > > > >
> > > > > > +  Optional regulator device-specific properties:
> > > > > > +  - dlg,vsel-sense-gpios : The GPIO reference which should be used by
> > the
> > > > > > +    regulator to switch the voltage between active/suspend voltage
> > settings.
> > > > If
> > > > > > +    the signal is active the active-settings are applied else the suspend
> > > > > > +    settings are applied. Attention: Sharing the same gpio for other
> > purposes
> > > > > > +    or across multiple regulators is possible but the gpio settings must be
> > the
> > > > > > +    same. Also the gpio phandle must refer to to the dlg,da9062-gpio
> > device
> > > > > > +    other gpios are not allowed and make no sense.
> > > > > > +
> > > > >
> > > > > Should we not use the binding names that are defined in 'gpio-
> > regulator.yaml'
> > > > as
> > > > > these seem to be generic and would probably serve the purpose here?
> > > >
> > > > Hm.. as the description says:
> > > >
> > > > 8<--------------------------------------------------
> > > > gpios:
> > > >    description: Array of one or more GPIO pins used to select the
> > > >    regulator voltage/current listed in "states".
> > > > 8<--------------------------------------------------
> > > >
> > > > But we don't have a "states" property and we can't select between
> > > > voltage or current.
> > >
> > > Yes I think I was at cross purposes when I made this remark. The bindings there
> > > describe the GPOs that are used to enable/disable and set voltage/current for
> > > regulators and the supported voltage/current levels that can be configured in
> > > this manner. What you're describing is the GPI for DA9061/2. If you look at
> > > GPIO handling in existing regulator drivers I believe they all deal with external
> > > GPOs that are configured to enable/disable and set voltage/current limits
> > rather
> > > than the GPI on the PMIC itself. That's why I'm thinking that the configurations
> > > you're doing here should actually be in a pinctrl or GPIO driver.
> > 
> > That's true, the common gpio bindings are from the view of the
> > processor, e.g. which gpio must the processor drive to enable/switch the
> > regualtor. So one reasone more to use a non-common binding.
> > 
> > Please take a look on my other comment I made :) I don't use the
> > gpio-alternative function. I use it as an input.
> 
> I know in the datasheet this isn't marked as an alternate function specifically
> but to me having regulator control by the chip's own GPI is an alternative
> function for that GPIO pin, in the same way a specific pin can be used for
> SYS_EN or Watchdog control. It's a dedicated purpose rather than being a normal
> GPI.

Nope, SYS_EN or Watchdog is a special/alternate function and not a
normal input.

> See the following as an example of what I'm suggesting:
> 
> https://elixir.bootlin.com/linux/latest/source/Documentation/devicetree/bindings/pinctrl/pinctrl-palmas.txt
> 
> You could then pass the pinctrl information to the regulator driver and use
> that rather than having device specific bindings for this. That's at least my
> current interpretation of this anyway.

For me pinctrl decides which function should be assigned to a pin. So in
our case this would be:
  - alternate
  - gpo
  - gpi

In our use-case it is a gpi..

An other reason why pinctrl seems not be the right solution is that the
regulator must be configured to use this gpi. This decision can't be
made globally because each regulator can be configured differently.. For
me its just a local gpio.

Regards,
  Marco

> > 
> > Regards,
> >   Marco
> > 
> > 
> > > I'd be interested in hearing Mark's view on this though as he has far more
> > > experience in this area than I do.
> > >
> > > >
> > > > Regards,
> > > >   Marco
> > > >
> > > > > >  - rtc : This node defines settings required for the Real-Time Clock
> > associated
> > > > > >    with the DA9062. There are currently no entries in this binding, however
> > > > > >    compatible = "dlg,da9062-rtc" should be added if a node is created.
> > > > > > --
> > > > > > 2.20.1
> > > > >
> > > > >
> > > >
> > > > --
> > > > Pengutronix e.K.                           |                             |
> > > > Industrial Linux Solutions                 | http://www.pengutronix.de/  |
> > > > Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
> > > > Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
> > >
> > 
> > --
> > Pengutronix e.K.                           |                             |
> > Industrial Linux Solutions                 | http://www.pengutronix.de/  |
> > Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
> > Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
> 

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

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

* RE: [PATCH 2/5] dt-bindings: mfd: da9062: add regulator voltage selection documentation
  2019-09-26 11:43             ` Marco Felsch
@ 2019-09-26 14:04               ` Adam Thomson
  2019-09-26 14:38                 ` Marco Felsch
  0 siblings, 1 reply; 29+ messages in thread
From: Adam Thomson @ 2019-09-26 14:04 UTC (permalink / raw)
  To: Marco Felsch, broonie, Adam Thomson
  Cc: Support Opensource, lee.jones, robh+dt, lgirdwood, Steve Twiss,
	kernel, devicetree, linux-kernel

On 26 September 2019 12:44, Marco Felsch wrote:

> On 19-09-26 10:17, Adam Thomson wrote:
> > On 26 September 2019 09:10, Marco Felsch wrote:
> >
> > > On 19-09-25 16:18, Adam Thomson wrote:
> > > > On 25 September 2019 16:52, Marco Felsch wrote:
> > > >
> > > > > Hi Adam,
> > > > >
> > > > > On 19-09-24 09:23, Adam Thomson wrote:
> > > > > > On 17 September 2019 13:43, Marco Felsch wrote:
> > > > > >
> > > > > > > Add the documentation which describe the voltage selection gpio
> > > support.
> > > > > > > This property can be applied to each subnode within the 'regulators'
> > > > > > > node so each regulator can be configured differently.
> > > > > > >
> > > > > > > Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
> > > > > > > ---
> > > > > > >  Documentation/devicetree/bindings/mfd/da9062.txt | 9 +++++++++
> > > > > > >  1 file changed, 9 insertions(+)
> > > > > > >
> > > > > > > diff --git a/Documentation/devicetree/bindings/mfd/da9062.txt
> > > > > > > b/Documentation/devicetree/bindings/mfd/da9062.txt
> > > > > > > index edca653a5777..9d9820d8177d 100644
> > > > > > > --- a/Documentation/devicetree/bindings/mfd/da9062.txt
> > > > > > > +++ b/Documentation/devicetree/bindings/mfd/da9062.txt
> > > > > > > @@ -66,6 +66,15 @@ Sub-nodes:
> > > > > > >    details of individual regulator device can be found in:
> > > > > > >    Documentation/devicetree/bindings/regulator/regulator.txt
> > > > > > >
> > > > > > > +  Optional regulator device-specific properties:
> > > > > > > +  - dlg,vsel-sense-gpios : The GPIO reference which should be used
> by
> > > the
> > > > > > > +    regulator to switch the voltage between active/suspend voltage
> > > settings.
> > > > > If
> > > > > > > +    the signal is active the active-settings are applied else the suspend
> > > > > > > +    settings are applied. Attention: Sharing the same gpio for other
> > > purposes
> > > > > > > +    or across multiple regulators is possible but the gpio settings must
> be
> > > the
> > > > > > > +    same. Also the gpio phandle must refer to to the dlg,da9062-gpio
> > > device
> > > > > > > +    other gpios are not allowed and make no sense.
> > > > > > > +
> > > > > >
> > > > > > Should we not use the binding names that are defined in 'gpio-
> > > regulator.yaml'
> > > > > as
> > > > > > these seem to be generic and would probably serve the purpose here?
> > > > >
> > > > > Hm.. as the description says:
> > > > >
> > > > > 8<--------------------------------------------------
> > > > > gpios:
> > > > >    description: Array of one or more GPIO pins used to select the
> > > > >    regulator voltage/current listed in "states".
> > > > > 8<--------------------------------------------------
> > > > >
> > > > > But we don't have a "states" property and we can't select between
> > > > > voltage or current.
> > > >
> > > > Yes I think I was at cross purposes when I made this remark. The bindings
> there
> > > > describe the GPOs that are used to enable/disable and set voltage/current
> for
> > > > regulators and the supported voltage/current levels that can be configured
> in
> > > > this manner. What you're describing is the GPI for DA9061/2. If you look at
> > > > GPIO handling in existing regulator drivers I believe they all deal with
> external
> > > > GPOs that are configured to enable/disable and set voltage/current limits
> > > rather
> > > > than the GPI on the PMIC itself. That's why I'm thinking that the
> configurations
> > > > you're doing here should actually be in a pinctrl or GPIO driver.
> > >
> > > That's true, the common gpio bindings are from the view of the
> > > processor, e.g. which gpio must the processor drive to enable/switch the
> > > regualtor. So one reasone more to use a non-common binding.
> > >
> > > Please take a look on my other comment I made :) I don't use the
> > > gpio-alternative function. I use it as an input.
> >
> > I know in the datasheet this isn't marked as an alternate function specifically
> > but to me having regulator control by the chip's own GPI is an alternative
> > function for that GPIO pin, in the same way a specific pin can be used for
> > SYS_EN or Watchdog control. It's a dedicated purpose rather than being a
> normal
> > GPI.
> 
> Nope, SYS_EN or Watchdog is a special/alternate function and not a
> normal input.

Having spoken with our HW team there's essentially no real difference.

> 
> > See the following as an example of what I'm suggesting:
> >
> >
> https://elixir.bootlin.com/linux/latest/source/Documentation/devicetree/bindin
> gs/pinctrl/pinctrl-palmas.txt
> >
> > You could then pass the pinctrl information to the regulator driver and use
> > that rather than having device specific bindings for this. That's at least my
> > current interpretation of this anyway.
> 
> For me pinctrl decides which function should be assigned to a pin. So in
> our case this would be:
>   - alternate
>   - gpo
>   - gpi
> 
> In our use-case it is a gpi..

It's not being used as a normal GPI as such. It's being used to enable/disable
the regulator so I disagree.

> 
> An other reason why pinctrl seems not be the right solution is that the
> regulator must be configured to use this gpi. This decision can't be
> made globally because each regulator can be configured differently.. For
> me its just a local gpio.

You'd pass pinctrl information, via DT, to the regulator driver so it can set
accordingly. At least that's my take here, unless I'm missing something. The
regulator driver would be the consumer and could set the regulator control
accordingly.

At the end of the day I'm not the gatekeeper here so I think Mark's input is
necessary as he will likely have a view on how this should be done. I appreciate
the work you've done here but I want to be sure we have a generic solution
as this would also apply to DA9063 and possibly other devices too.

Have added Mark to the 'To' in this e-mail thread so he might see it.
> 
> Regards,
>   Marco
> 
> > >
> > > Regards,
> > >   Marco
> > >
> > >
> > > > I'd be interested in hearing Mark's view on this though as he has far more
> > > > experience in this area than I do.
> > > >
> > > > >
> > > > > Regards,
> > > > >   Marco
> > > > >
> > > > > > >  - rtc : This node defines settings required for the Real-Time Clock
> > > associated
> > > > > > >    with the DA9062. There are currently no entries in this binding,
> however
> > > > > > >    compatible = "dlg,da9062-rtc" should be added if a node is created.
> > > > > > > --
> > > > > > > 2.20.1
> > > > > >
> > > > > >
> > > > >
> > > > > --
> > > > > Pengutronix e.K.                           |                             |
> > > > > Industrial Linux Solutions                 | http://www.pengutronix.de/  |
> > > > > Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0
> |
> > > > > Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
> > > >
> > >
> > > --
> > > Pengutronix e.K.                           |                             |
> > > Industrial Linux Solutions                 | http://www.pengutronix.de/  |
> > > Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
> > > Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
> >
> 
> --
> Pengutronix e.K.                           |                             |
> Industrial Linux Solutions                 | http://www.pengutronix.de/  |
> Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
> Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

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

* Re: [PATCH 2/5] dt-bindings: mfd: da9062: add regulator voltage selection documentation
  2019-09-26 14:04               ` Adam Thomson
@ 2019-09-26 14:38                 ` Marco Felsch
  2019-09-30  9:53                   ` Adam Thomson
  0 siblings, 1 reply; 29+ messages in thread
From: Marco Felsch @ 2019-09-26 14:38 UTC (permalink / raw)
  To: Adam Thomson
  Cc: broonie, Support Opensource, lee.jones, robh+dt, lgirdwood,
	Steve Twiss, kernel, devicetree, linux-kernel

On 19-09-26 14:04, Adam Thomson wrote:
> On 26 September 2019 12:44, Marco Felsch wrote:
> 
> > On 19-09-26 10:17, Adam Thomson wrote:
> > > On 26 September 2019 09:10, Marco Felsch wrote:
> > >
> > > > On 19-09-25 16:18, Adam Thomson wrote:
> > > > > On 25 September 2019 16:52, Marco Felsch wrote:
> > > > >
> > > > > > Hi Adam,
> > > > > >
> > > > > > On 19-09-24 09:23, Adam Thomson wrote:
> > > > > > > On 17 September 2019 13:43, Marco Felsch wrote:
> > > > > > >
> > > > > > > > Add the documentation which describe the voltage selection gpio
> > > > support.
> > > > > > > > This property can be applied to each subnode within the 'regulators'
> > > > > > > > node so each regulator can be configured differently.
> > > > > > > >
> > > > > > > > Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
> > > > > > > > ---
> > > > > > > >  Documentation/devicetree/bindings/mfd/da9062.txt | 9 +++++++++
> > > > > > > >  1 file changed, 9 insertions(+)
> > > > > > > >
> > > > > > > > diff --git a/Documentation/devicetree/bindings/mfd/da9062.txt
> > > > > > > > b/Documentation/devicetree/bindings/mfd/da9062.txt
> > > > > > > > index edca653a5777..9d9820d8177d 100644
> > > > > > > > --- a/Documentation/devicetree/bindings/mfd/da9062.txt
> > > > > > > > +++ b/Documentation/devicetree/bindings/mfd/da9062.txt
> > > > > > > > @@ -66,6 +66,15 @@ Sub-nodes:
> > > > > > > >    details of individual regulator device can be found in:
> > > > > > > >    Documentation/devicetree/bindings/regulator/regulator.txt
> > > > > > > >
> > > > > > > > +  Optional regulator device-specific properties:
> > > > > > > > +  - dlg,vsel-sense-gpios : The GPIO reference which should be used
> > by
> > > > the
> > > > > > > > +    regulator to switch the voltage between active/suspend voltage
> > > > settings.
> > > > > > If
> > > > > > > > +    the signal is active the active-settings are applied else the suspend
> > > > > > > > +    settings are applied. Attention: Sharing the same gpio for other
> > > > purposes
> > > > > > > > +    or across multiple regulators is possible but the gpio settings must
> > be
> > > > the
> > > > > > > > +    same. Also the gpio phandle must refer to to the dlg,da9062-gpio
> > > > device
> > > > > > > > +    other gpios are not allowed and make no sense.
> > > > > > > > +
> > > > > > >
> > > > > > > Should we not use the binding names that are defined in 'gpio-
> > > > regulator.yaml'
> > > > > > as
> > > > > > > these seem to be generic and would probably serve the purpose here?
> > > > > >
> > > > > > Hm.. as the description says:
> > > > > >
> > > > > > 8<--------------------------------------------------
> > > > > > gpios:
> > > > > >    description: Array of one or more GPIO pins used to select the
> > > > > >    regulator voltage/current listed in "states".
> > > > > > 8<--------------------------------------------------
> > > > > >
> > > > > > But we don't have a "states" property and we can't select between
> > > > > > voltage or current.
> > > > >
> > > > > Yes I think I was at cross purposes when I made this remark. The bindings
> > there
> > > > > describe the GPOs that are used to enable/disable and set voltage/current
> > for
> > > > > regulators and the supported voltage/current levels that can be configured
> > in
> > > > > this manner. What you're describing is the GPI for DA9061/2. If you look at
> > > > > GPIO handling in existing regulator drivers I believe they all deal with
> > external
> > > > > GPOs that are configured to enable/disable and set voltage/current limits
> > > > rather
> > > > > than the GPI on the PMIC itself. That's why I'm thinking that the
> > configurations
> > > > > you're doing here should actually be in a pinctrl or GPIO driver.
> > > >
> > > > That's true, the common gpio bindings are from the view of the
> > > > processor, e.g. which gpio must the processor drive to enable/switch the
> > > > regualtor. So one reasone more to use a non-common binding.
> > > >
> > > > Please take a look on my other comment I made :) I don't use the
> > > > gpio-alternative function. I use it as an input.
> > >
> > > I know in the datasheet this isn't marked as an alternate function specifically
> > > but to me having regulator control by the chip's own GPI is an alternative
> > > function for that GPIO pin, in the same way a specific pin can be used for
> > > SYS_EN or Watchdog control. It's a dedicated purpose rather than being a
> > normal
> > > GPI.
> > 
> > Nope, SYS_EN or Watchdog is a special/alternate function and not a
> > normal input.
> 
> Having spoken with our HW team there's essentially no real difference.

So I don't have to configure the gpio to alternate to use it as SYS_EN?

> > 
> > > See the following as an example of what I'm suggesting:
> > >
> > >
> > https://elixir.bootlin.com/linux/latest/source/Documentation/devicetree/bindin
> > gs/pinctrl/pinctrl-palmas.txt
> > >
> > > You could then pass the pinctrl information to the regulator driver and use
> > > that rather than having device specific bindings for this. That's at least my
> > > current interpretation of this anyway.
> > 
> > For me pinctrl decides which function should be assigned to a pin. So in
> > our case this would be:
> >   - alternate
> >   - gpo
> >   - gpi
> > 
> > In our use-case it is a gpi..
> 
> It's not being used as a normal GPI as such. It's being used to enable/disable
> the regulator so I disagree.

This one is used as voltage-selection. What is a "normal" GPI in your
point of view?

> > 
> > An other reason why pinctrl seems not be the right solution is that the
> > regulator must be configured to use this gpi. This decision can't be
> > made globally because each regulator can be configured differently.. For
> > me its just a local gpio.
> 
> You'd pass pinctrl information, via DT, to the regulator driver so it can set
> accordingly. At least that's my take here, unless I'm missing something. The
> regulator driver would be the consumer and could set the regulator control
> accordingly.

IMHO this is what I have done. I use the gpi so the regulator is the
consumer. Since the gpi can be used by several regulators for voltage
selection or enable/disable action this gpi is marked as shared. If I
got you right than you would do something like for regulatorX.

  pinctrl-node {

  	gpio2 {
		func = "vsel";
	}
  }

But the gpi(o)2 can also be used to enable/disable a regulatorY if I
understood the datasheet correctly. I other words:



         +--> Alternate function
      /
  ---+   +--> GPI ----> Edge detection ---> more processing
   |       |                |
   |       |                +-----> Regulator control
   |       |                          |
   \__  __/ \__________  _______
      \/               \/
   pinctrl            gpio

This is how I understood the pinctrl use-case. I configure the pin as
gpio and then the regulator driver consume a gpio.

> At the end of the day I'm not the gatekeeper here so I think Mark's input is
> necessary as he will likely have a view on how this should be done. I appreciate
> the work you've done here but I want to be sure we have a generic solution
> as this would also apply to DA9063 and possibly other devices too.

Why should this only apply to da9062 devices? IMHO this property can be
used by any other dlg pmic as well if it is supported. Comments and suggestions
are welcome so no worries ;)

Regards,
  Marco

> Have added Mark to the 'To' in this e-mail thread so he might see it.
> > 
> > Regards,
> >   Marco
> > 
> > > >
> > > > Regards,
> > > >   Marco
> > > >
> > > >
> > > > > I'd be interested in hearing Mark's view on this though as he has far more
> > > > > experience in this area than I do.
> > > > >
> > > > > >
> > > > > > Regards,
> > > > > >   Marco
> > > > > >
> > > > > > > >  - rtc : This node defines settings required for the Real-Time Clock
> > > > associated
> > > > > > > >    with the DA9062. There are currently no entries in this binding,
> > however
> > > > > > > >    compatible = "dlg,da9062-rtc" should be added if a node is created.
> > > > > > > > --
> > > > > > > > 2.20.1
> > > > > > >
> > > > > > >
> > > > > >
> > > > > > --
> > > > > > Pengutronix e.K.                           |                             |
> > > > > > Industrial Linux Solutions                 | http://www.pengutronix.de/  |
> > > > > > Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0
> > |
> > > > > > Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
> > > > >
> > > >
> > > > --
> > > > Pengutronix e.K.                           |                             |
> > > > Industrial Linux Solutions                 | http://www.pengutronix.de/  |
> > > > Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
> > > > Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
> > >
> > 
> > --
> > Pengutronix e.K.                           |                             |
> > Industrial Linux Solutions                 | http://www.pengutronix.de/  |
> > Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
> > Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
> 

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

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

* RE: [PATCH 2/5] dt-bindings: mfd: da9062: add regulator voltage selection documentation
  2019-09-26 14:38                 ` Marco Felsch
@ 2019-09-30  9:53                   ` Adam Thomson
  2019-10-02 13:45                     ` Marco Felsch
  0 siblings, 1 reply; 29+ messages in thread
From: Adam Thomson @ 2019-09-30  9:53 UTC (permalink / raw)
  To: Marco Felsch, Adam Thomson
  Cc: broonie, Support Opensource, lee.jones, robh+dt, lgirdwood,
	Steve Twiss, kernel, devicetree, linux-kernel

On 26 September 2019 15:39, Marco Felsch wrote:

> On 19-09-26 14:04, Adam Thomson wrote:
> > On 26 September 2019 12:44, Marco Felsch wrote:
> >
> > > On 19-09-26 10:17, Adam Thomson wrote:
> > > > On 26 September 2019 09:10, Marco Felsch wrote:
> > > >
> > > > > On 19-09-25 16:18, Adam Thomson wrote:
> > > > > > On 25 September 2019 16:52, Marco Felsch wrote:
> > > > > >
> > > > > > > Hi Adam,
> > > > > > >
> > > > > > > On 19-09-24 09:23, Adam Thomson wrote:
> > > > > > > > On 17 September 2019 13:43, Marco Felsch wrote:
> > > > > > > >
> > > > > > > > > Add the documentation which describe the voltage selection gpio
> > > > > support.
> > > > > > > > > This property can be applied to each subnode within the
> 'regulators'
> > > > > > > > > node so each regulator can be configured differently.
> > > > > > > > >
> > > > > > > > > Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
> > > > > > > > > ---
> > > > > > > > >  Documentation/devicetree/bindings/mfd/da9062.txt | 9
> +++++++++
> > > > > > > > >  1 file changed, 9 insertions(+)
> > > > > > > > >
> > > > > > > > > diff --git a/Documentation/devicetree/bindings/mfd/da9062.txt
> > > > > > > > > b/Documentation/devicetree/bindings/mfd/da9062.txt
> > > > > > > > > index edca653a5777..9d9820d8177d 100644
> > > > > > > > > --- a/Documentation/devicetree/bindings/mfd/da9062.txt
> > > > > > > > > +++ b/Documentation/devicetree/bindings/mfd/da9062.txt
> > > > > > > > > @@ -66,6 +66,15 @@ Sub-nodes:
> > > > > > > > >    details of individual regulator device can be found in:
> > > > > > > > >    Documentation/devicetree/bindings/regulator/regulator.txt
> > > > > > > > >
> > > > > > > > > +  Optional regulator device-specific properties:
> > > > > > > > > +  - dlg,vsel-sense-gpios : The GPIO reference which should be
> used
> > > by
> > > > > the
> > > > > > > > > +    regulator to switch the voltage between active/suspend
> voltage
> > > > > settings.
> > > > > > > If
> > > > > > > > > +    the signal is active the active-settings are applied else the
> suspend
> > > > > > > > > +    settings are applied. Attention: Sharing the same gpio for other
> > > > > purposes
> > > > > > > > > +    or across multiple regulators is possible but the gpio settings
> must
> > > be
> > > > > the
> > > > > > > > > +    same. Also the gpio phandle must refer to to the dlg,da9062-
> gpio
> > > > > device
> > > > > > > > > +    other gpios are not allowed and make no sense.
> > > > > > > > > +
> > > > > > > >
> > > > > > > > Should we not use the binding names that are defined in 'gpio-
> > > > > regulator.yaml'
> > > > > > > as
> > > > > > > > these seem to be generic and would probably serve the purpose
> here?
> > > > > > >
> > > > > > > Hm.. as the description says:
> > > > > > >
> > > > > > > 8<--------------------------------------------------
> > > > > > > gpios:
> > > > > > >    description: Array of one or more GPIO pins used to select the
> > > > > > >    regulator voltage/current listed in "states".
> > > > > > > 8<--------------------------------------------------
> > > > > > >
> > > > > > > But we don't have a "states" property and we can't select between
> > > > > > > voltage or current.
> > > > > >
> > > > > > Yes I think I was at cross purposes when I made this remark. The
> bindings
> > > there
> > > > > > describe the GPOs that are used to enable/disable and set
> voltage/current
> > > for
> > > > > > regulators and the supported voltage/current levels that can be
> configured
> > > in
> > > > > > this manner. What you're describing is the GPI for DA9061/2. If you look
> at
> > > > > > GPIO handling in existing regulator drivers I believe they all deal with
> > > external
> > > > > > GPOs that are configured to enable/disable and set voltage/current
> limits
> > > > > rather
> > > > > > than the GPI on the PMIC itself. That's why I'm thinking that the
> > > configurations
> > > > > > you're doing here should actually be in a pinctrl or GPIO driver.
> > > > >
> > > > > That's true, the common gpio bindings are from the view of the
> > > > > processor, e.g. which gpio must the processor drive to enable/switch the
> > > > > regualtor. So one reasone more to use a non-common binding.
> > > > >
> > > > > Please take a look on my other comment I made :) I don't use the
> > > > > gpio-alternative function. I use it as an input.
> > > >
> > > > I know in the datasheet this isn't marked as an alternate function specifically
> > > > but to me having regulator control by the chip's own GPI is an alternative
> > > > function for that GPIO pin, in the same way a specific pin can be used for
> > > > SYS_EN or Watchdog control. It's a dedicated purpose rather than being a
> > > normal
> > > > GPI.
> > >
> > > Nope, SYS_EN or Watchdog is a special/alternate function and not a
> > > normal input.
> >
> > Having spoken with our HW team there's essentially no real difference.
>
> So I don't have to configure the gpio to alternate to use it as SYS_EN?

Yes you do, but the effect is much the same as manually configuring the GPIO as
input, just that the IC does it for you. The regulator control features could
well have been done in a similar manner. Guess that was a design choice.

>
> > >
> > > > See the following as an example of what I'm suggesting:
> > > >
> > > >
> > >
> https://elixir.bootlin.com/linux/latest/source/Documentation/devicetree/bindin
> > > gs/pinctrl/pinctrl-palmas.txt
> > > >
> > > > You could then pass the pinctrl information to the regulator driver and use
> > > > that rather than having device specific bindings for this. That's at least my
> > > > current interpretation of this anyway.
> > >
> > > For me pinctrl decides which function should be assigned to a pin. So in
> > > our case this would be:
> > >   - alternate
> > >   - gpo
> > >   - gpi
> > >
> > > In our use-case it is a gpi..
> >
> > It's not being used as a normal GPI as such. It's being used to enable/disable
> > the regulator so I disagree.
>
> This one is used as voltage-selection. What is a "normal" GPI in your
> point of view?

With the voltage selection and enable/disable control the actual work of
handling the GPI state is all done internally in the IC. There is no control
required from SW other than setting of initial direction. For a normal GPI
I would expect SW to be involved in the handling of that GPI state, for example
as part of a bit banging interface.

>
> > >
> > > An other reason why pinctrl seems not be the right solution is that the
> > > regulator must be configured to use this gpi. This decision can't be
> > > made globally because each regulator can be configured differently.. For
> > > me its just a local gpio.
> >
> > You'd pass pinctrl information, via DT, to the regulator driver so it can set
> > accordingly. At least that's my take here, unless I'm missing something. The
> > regulator driver would be the consumer and could set the regulator control
> > accordingly.
>
> IMHO this is what I have done. I use the gpi so the regulator is the
> consumer. Since the gpi can be used by several regulators for voltage
> selection or enable/disable action this gpi is marked as shared. If I
> got you right than you would do something like for regulatorX.
>
>   pinctrl-node {
>
>   	gpio2 {
> 		func = "vsel";
> 	}
>   }
>
> But the gpi(o)2 can also be used to enable/disable a regulatorY if I
> understood the datasheet correctly. I other words:
>
>
>
>          +--> Alternate function
>       /
>   ---+   +--> GPI ----> Edge detection ---> more processing
>    |       |                |
>    |       |                +-----> Regulator control
>    |       |                          |
>    \__  __/ \__________  _______
>       \/               \/
>    pinctrl            gpio
>
> This is how I understood the pinctrl use-case. I configure the pin as
> gpio and then the regulator driver consume a gpio.

How I see it is that you configure the function through pinctrl as
'regulator_switch' or 'regulator_vsel' (or whatever name is deemed sensible to
cover the two types of functionality) and then the pinctrl driver code would do
the work of requesting and configuring the relevant GPIO as input so it's no
longer available for use as something else (basically what you do in the
regulator driver right now).

I believe you can have more than one consumer of a pinctrl pin so it could be
provided to both regulator X and Y to indicate that this is the chosen
functionality of that pin and so the regulator can then be marked as being
controlled by that pin. Using pinctrl also would mean you're using standard
bindings as well rather than something which is device specific.

>
> > At the end of the day I'm not the gatekeeper here so I think Mark's input is
> > necessary as he will likely have a view on how this should be done. I appreciate
> > the work you've done here but I want to be sure we have a generic solution
> > as this would also apply to DA9063 and possibly other devices too.
>
> Why should this only apply to da9062 devices? IMHO this property can be
> used by any other dlg pmic as well if it is supported. Comments and suggestions
> are welcome so no worries ;)

You're right. You can do the same for DA9063 and other devices potentially. I
would just like to make sure we take the right/agreed approach. Potentially
this could be used in non-Dialog products as well which have similar
functionality.

As I say, Mark is really the gatekeeper so his input is also key in this.

>
> Regards,
>   Marco
>
> > Have added Mark to the 'To' in this e-mail thread so he might see it.
> > >
> > > Regards,
> > >   Marco
> > >
> > > > >
> > > > > Regards,
> > > > >   Marco
> > > > >
> > > > >
> > > > > > I'd be interested in hearing Mark's view on this though as he has far
> more
> > > > > > experience in this area than I do.
> > > > > >
> > > > > > >
> > > > > > > Regards,
> > > > > > >   Marco
> > > > > > >
> > > > > > > > >  - rtc : This node defines settings required for the Real-Time Clock
> > > > > associated
> > > > > > > > >    with the DA9062. There are currently no entries in this binding,
> > > however
> > > > > > > > >    compatible = "dlg,da9062-rtc" should be added if a node is
> created.
> > > > > > > > > --
> > > > > > > > > 2.20.1
> > > > > > > >
> > > > > > > >
> > > > > > >
> > > > > > > --
> > > > > > > Pengutronix e.K.                           |                             |
> > > > > > > Industrial Linux Solutions                 | http://www.pengutronix.de/  |
> > > > > > > Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-
> 0
> > > |
> > > > > > > Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555
> |
> > > > > >
> > > > >
> > > > > --
> > > > > Pengutronix e.K.                           |                             |
> > > > > Industrial Linux Solutions                 | http://www.pengutronix.de/  |
> > > > > Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0
> |
> > > > > Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
> > > >
> > >
> > > --
> > > Pengutronix e.K.                           |                             |
> > > Industrial Linux Solutions                 | http://www.pengutronix.de/  |
> > > Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
> > > Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
> >
>
> --
> Pengutronix e.K.                           |                             |
> Industrial Linux Solutions                 | http://www.pengutronix.de/  |
> Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
> Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

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

* Re: [PATCH 2/5] dt-bindings: mfd: da9062: add regulator voltage selection documentation
  2019-09-30  9:53                   ` Adam Thomson
@ 2019-10-02 13:45                     ` Marco Felsch
  2019-10-22 10:22                       ` Marco Felsch
  0 siblings, 1 reply; 29+ messages in thread
From: Marco Felsch @ 2019-10-02 13:45 UTC (permalink / raw)
  To: Adam Thomson, broonie
  Cc: broonie, Support Opensource, lee.jones, robh+dt, lgirdwood,
	Steve Twiss, kernel, devicetree, linux-kernel

On 19-09-30 09:53, Adam Thomson wrote:
> On 26 September 2019 15:39, Marco Felsch wrote:
> 
> > On 19-09-26 14:04, Adam Thomson wrote:
> > > On 26 September 2019 12:44, Marco Felsch wrote:
> > >
> > > > On 19-09-26 10:17, Adam Thomson wrote:
> > > > > On 26 September 2019 09:10, Marco Felsch wrote:
> > > > >
> > > > > > On 19-09-25 16:18, Adam Thomson wrote:
> > > > > > > On 25 September 2019 16:52, Marco Felsch wrote:
> > > > > > >
> > > > > > > > Hi Adam,
> > > > > > > >
> > > > > > > > On 19-09-24 09:23, Adam Thomson wrote:
> > > > > > > > > On 17 September 2019 13:43, Marco Felsch wrote:
> > > > > > > > >
> > > > > > > > > > Add the documentation which describe the voltage selection gpio
> > > > > > support.
> > > > > > > > > > This property can be applied to each subnode within the
> > 'regulators'
> > > > > > > > > > node so each regulator can be configured differently.
> > > > > > > > > >
> > > > > > > > > > Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
> > > > > > > > > > ---
> > > > > > > > > >  Documentation/devicetree/bindings/mfd/da9062.txt | 9
> > +++++++++
> > > > > > > > > >  1 file changed, 9 insertions(+)
> > > > > > > > > >
> > > > > > > > > > diff --git a/Documentation/devicetree/bindings/mfd/da9062.txt
> > > > > > > > > > b/Documentation/devicetree/bindings/mfd/da9062.txt
> > > > > > > > > > index edca653a5777..9d9820d8177d 100644
> > > > > > > > > > --- a/Documentation/devicetree/bindings/mfd/da9062.txt
> > > > > > > > > > +++ b/Documentation/devicetree/bindings/mfd/da9062.txt
> > > > > > > > > > @@ -66,6 +66,15 @@ Sub-nodes:
> > > > > > > > > >    details of individual regulator device can be found in:
> > > > > > > > > >    Documentation/devicetree/bindings/regulator/regulator.txt
> > > > > > > > > >
> > > > > > > > > > +  Optional regulator device-specific properties:
> > > > > > > > > > +  - dlg,vsel-sense-gpios : The GPIO reference which should be
> > used
> > > > by
> > > > > > the
> > > > > > > > > > +    regulator to switch the voltage between active/suspend
> > voltage
> > > > > > settings.
> > > > > > > > If
> > > > > > > > > > +    the signal is active the active-settings are applied else the
> > suspend
> > > > > > > > > > +    settings are applied. Attention: Sharing the same gpio for other
> > > > > > purposes
> > > > > > > > > > +    or across multiple regulators is possible but the gpio settings
> > must
> > > > be
> > > > > > the
> > > > > > > > > > +    same. Also the gpio phandle must refer to to the dlg,da9062-
> > gpio
> > > > > > device
> > > > > > > > > > +    other gpios are not allowed and make no sense.
> > > > > > > > > > +
> > > > > > > > >
> > > > > > > > > Should we not use the binding names that are defined in 'gpio-
> > > > > > regulator.yaml'
> > > > > > > > as
> > > > > > > > > these seem to be generic and would probably serve the purpose
> > here?
> > > > > > > >
> > > > > > > > Hm.. as the description says:
> > > > > > > >
> > > > > > > > 8<--------------------------------------------------
> > > > > > > > gpios:
> > > > > > > >    description: Array of one or more GPIO pins used to select the
> > > > > > > >    regulator voltage/current listed in "states".
> > > > > > > > 8<--------------------------------------------------
> > > > > > > >
> > > > > > > > But we don't have a "states" property and we can't select between
> > > > > > > > voltage or current.
> > > > > > >
> > > > > > > Yes I think I was at cross purposes when I made this remark. The
> > bindings
> > > > there
> > > > > > > describe the GPOs that are used to enable/disable and set
> > voltage/current
> > > > for
> > > > > > > regulators and the supported voltage/current levels that can be
> > configured
> > > > in
> > > > > > > this manner. What you're describing is the GPI for DA9061/2. If you look
> > at
> > > > > > > GPIO handling in existing regulator drivers I believe they all deal with
> > > > external
> > > > > > > GPOs that are configured to enable/disable and set voltage/current
> > limits
> > > > > > rather
> > > > > > > than the GPI on the PMIC itself. That's why I'm thinking that the
> > > > configurations
> > > > > > > you're doing here should actually be in a pinctrl or GPIO driver.
> > > > > >
> > > > > > That's true, the common gpio bindings are from the view of the
> > > > > > processor, e.g. which gpio must the processor drive to enable/switch the
> > > > > > regualtor. So one reasone more to use a non-common binding.
> > > > > >
> > > > > > Please take a look on my other comment I made :) I don't use the
> > > > > > gpio-alternative function. I use it as an input.
> > > > >
> > > > > I know in the datasheet this isn't marked as an alternate function specifically
> > > > > but to me having regulator control by the chip's own GPI is an alternative
> > > > > function for that GPIO pin, in the same way a specific pin can be used for
> > > > > SYS_EN or Watchdog control. It's a dedicated purpose rather than being a
> > > > normal
> > > > > GPI.
> > > >
> > > > Nope, SYS_EN or Watchdog is a special/alternate function and not a
> > > > normal input.
> > >
> > > Having spoken with our HW team there's essentially no real difference.
> >
> > So I don't have to configure the gpio to alternate to use it as SYS_EN?
> 
> Yes you do, but the effect is much the same as manually configuring the GPIO as
> input, just that the IC does it for you. The regulator control features could
> well have been done in a similar manner. Guess that was a design choice.
> 
> >
> > > >
> > > > > See the following as an example of what I'm suggesting:
> > > > >
> > > > >
> > > >
> > https://elixir.bootlin.com/linux/latest/source/Documentation/devicetree/bindin
> > > > gs/pinctrl/pinctrl-palmas.txt
> > > > >
> > > > > You could then pass the pinctrl information to the regulator driver and use
> > > > > that rather than having device specific bindings for this. That's at least my
> > > > > current interpretation of this anyway.
> > > >
> > > > For me pinctrl decides which function should be assigned to a pin. So in
> > > > our case this would be:
> > > >   - alternate
> > > >   - gpo
> > > >   - gpi
> > > >
> > > > In our use-case it is a gpi..
> > >
> > > It's not being used as a normal GPI as such. It's being used to enable/disable
> > > the regulator so I disagree.
> >
> > This one is used as voltage-selection. What is a "normal" GPI in your
> > point of view?
> 
> With the voltage selection and enable/disable control the actual work of
> handling the GPI state is all done internally in the IC. There is no control
> required from SW other than setting of initial direction. For a normal GPI

Thats correct and setting the direction and active levels can be done
perfectly by the gpio-interface.

> I would expect SW to be involved in the handling of that GPI state, for example
> as part of a bit banging interface.
> 
> >
> > > >
> > > > An other reason why pinctrl seems not be the right solution is that the
> > > > regulator must be configured to use this gpi. This decision can't be
> > > > made globally because each regulator can be configured differently.. For
> > > > me its just a local gpio.
> > >
> > > You'd pass pinctrl information, via DT, to the regulator driver so it can set
> > > accordingly. At least that's my take here, unless I'm missing something. The
> > > regulator driver would be the consumer and could set the regulator control
> > > accordingly.
> >
> > IMHO this is what I have done. I use the gpi so the regulator is the
> > consumer. Since the gpi can be used by several regulators for voltage
> > selection or enable/disable action this gpi is marked as shared. If I
> > got you right than you would do something like for regulatorX.
> >
> >   pinctrl-node {
> >
> >   	gpio2 {
> > 		func = "vsel";
> > 	}
> >   }
> >
> > But the gpi(o)2 can also be used to enable/disable a regulatorY if I
> > understood the datasheet correctly. I other words:
> >
> >
> >
> >          +--> Alternate function
> >       /
> >   ---+   +--> GPI ----> Edge detection ---> more processing
> >    |       |                |
> >    |       |                +-----> Regulator control
> >    |       |                          |
> >    \__  __/ \__________  _______
> >       \/               \/
> >    pinctrl            gpio
> >
> > This is how I understood the pinctrl use-case. I configure the pin as
> > gpio and then the regulator driver consume a gpio.
> 
> How I see it is that you configure the function through pinctrl as
> 'regulator_switch' or 'regulator_vsel' (or whatever name is deemed sensible to

The case is that it can be "muxed" for both at same time so there is no
or instead it is a or/and. Depending on the design some regulators can
be turned off and some should be switched upon that signal.

> cover the two types of functionality) and then the pinctrl driver code would do
> the work of requesting and configuring the relevant GPIO as input so it's no
> longer available for use as something else (basically what you do in the
> regulator driver right now).

So by this I avoided the user-space to get this gpio and this seems fine
to me. What a driver does with a gpio is up to the driver but the gpio
shouldn't be reachable from the user-space.

> I believe you can have more than one consumer of a pinctrl pin so it could be
> provided to both regulator X and Y to indicate that this is the chosen
> functionality of that pin and so the regulator can then be marked as being
> controlled by that pin. Using pinctrl also would mean you're using standard
> bindings as well rather than something which is device specific.

That seems wrong to me because pinctrl should assign a dedicated function
to that pin e.g. regulator_switch or regulator_vsel. But thats wrong as
I pointed out above. On the other hand the gpio as the name says is
general purpose and each regulator gives the meaning to it.

> > > At the end of the day I'm not the gatekeeper here so I think Mark's input is
> > > necessary as he will likely have a view on how this should be done. I appreciate
> > > the work you've done here but I want to be sure we have a generic solution
> > > as this would also apply to DA9063 and possibly other devices too.
> >
> > Why should this only apply to da9062 devices? IMHO this property can be
> > used by any other dlg pmic as well if it is supported. Comments and suggestions
> > are welcome so no worries ;)
> 
> You're right. You can do the same for DA9063 and other devices potentially. I
> would just like to make sure we take the right/agreed approach. Potentially
> this could be used in non-Dialog products as well which have similar
> functionality.

Yeah, but I think we should consider about that after an other device
appears with that funcitonality.

> As I say, Mark is really the gatekeeper so his input is also key in this.

That's right, I added Mark to To.

Regards,
  Marco

> 
> >
> > Regards,
> >   Marco
> >
> > > Have added Mark to the 'To' in this e-mail thread so he might see it.
> > > >
> > > > Regards,
> > > >   Marco
> > > >
> > > > > >
> > > > > > Regards,
> > > > > >   Marco
> > > > > >
> > > > > >
> > > > > > > I'd be interested in hearing Mark's view on this though as he has far
> > more
> > > > > > > experience in this area than I do.
> > > > > > >
> > > > > > > >
> > > > > > > > Regards,
> > > > > > > >   Marco
> > > > > > > >
> > > > > > > > > >  - rtc : This node defines settings required for the Real-Time Clock
> > > > > > associated
> > > > > > > > > >    with the DA9062. There are currently no entries in this binding,
> > > > however
> > > > > > > > > >    compatible = "dlg,da9062-rtc" should be added if a node is
> > created.
> > > > > > > > > > --
> > > > > > > > > > 2.20.1
> > > > > > > > >
> > > > > > > > >
> > > > > > > >
> > > > > > > > --
> > > > > > > > Pengutronix e.K.                           |                             |
> > > > > > > > Industrial Linux Solutions                 | http://www.pengutronix.de/  |
> > > > > > > > Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-
> > 0
> > > > |
> > > > > > > > Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555
> > |
> > > > > > >
> > > > > >
> > > > > > --
> > > > > > Pengutronix e.K.                           |                             |
> > > > > > Industrial Linux Solutions                 | http://www.pengutronix.de/  |
> > > > > > Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0
> > |
> > > > > > Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
> > > > >
> > > >
> > > > --
> > > > Pengutronix e.K.                           |                             |
> > > > Industrial Linux Solutions                 | http://www.pengutronix.de/  |
> > > > Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
> > > > Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
> > >
> >
> > --
> > Pengutronix e.K.                           |                             |
> > Industrial Linux Solutions                 | http://www.pengutronix.de/  |
> > Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
> > Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
> 

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

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

* Re: [PATCH 3/5] regulator: da9062: add voltage selection gpio support
  2019-09-17 12:42 ` [PATCH 3/5] regulator: da9062: add voltage selection gpio support Marco Felsch
  2019-09-17 14:22   ` kbuild test robot
  2019-09-24  9:48   ` Adam Thomson
@ 2019-10-04 19:41   ` Linus Walleij
  2019-10-07  8:59     ` Marco Felsch
  2 siblings, 1 reply; 29+ messages in thread
From: Linus Walleij @ 2019-10-04 19:41 UTC (permalink / raw)
  To: Marco Felsch
  Cc: Support Opensource, Lee Jones, Rob Herring, Liam Girdwood,
	Mark Brown, stwiss.opensource, Sascha Hauer,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	linux-kernel

On Tue, Sep 17, 2019 at 2:43 PM Marco Felsch <m.felsch@pengutronix.de> wrote:

> +       /*
> +        * We only must ensure that the gpio device is probed before the
> +        * regulator driver so no need to store the reference global. Luckily
> +        * devm_* releases the gpio upon a unbound action.
> +        */
> +       gpi = devm_gpiod_get_from_of_node(cfg->dev, np, prop, 0, GPIOD_IN |
> +                                         GPIOD_FLAGS_BIT_NONEXCLUSIVE, label);

Do you really need the GPIOD_FLAGS_BIT_NONEXCLUSIVE flag here?
I don't think so, but describe what usecase you have that warrants this
being claimed twice. Normally that is just needed when you let the
regulator core handle enablement of a regulator over GPIO, i.e.
ena_gpiod in struct regulator_config.

> +       /* We need the local number */
> +       nr = da9062_gpio_get_hwgpio(gpi);

If you really need this we should add a public API to gpiolib and not
create custom APIs.

Just make a patch adding

int gpiod_to_offset(struct gpio_desc *d);

to the public gpiolib API in include/linux/gpio/consumer.h

and add the code in gpiolib.c to do this trick.

Yours,
Linus Walleij

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

* Re: [PATCH 3/5] regulator: da9062: add voltage selection gpio support
  2019-10-04 19:41   ` Linus Walleij
@ 2019-10-07  8:59     ` Marco Felsch
  0 siblings, 0 replies; 29+ messages in thread
From: Marco Felsch @ 2019-10-07  8:59 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Support Opensource, Lee Jones, Rob Herring, Liam Girdwood,
	Mark Brown, stwiss.opensource, Sascha Hauer,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	linux-kernel

On 19-10-04 21:41, Linus Walleij wrote:
> On Tue, Sep 17, 2019 at 2:43 PM Marco Felsch <m.felsch@pengutronix.de> wrote:
> 
> > +       /*
> > +        * We only must ensure that the gpio device is probed before the
> > +        * regulator driver so no need to store the reference global. Luckily
> > +        * devm_* releases the gpio upon a unbound action.
> > +        */
> > +       gpi = devm_gpiod_get_from_of_node(cfg->dev, np, prop, 0, GPIOD_IN |
> > +                                         GPIOD_FLAGS_BIT_NONEXCLUSIVE, label);
> 
> Do you really need the GPIOD_FLAGS_BIT_NONEXCLUSIVE flag here?
> I don't think so, but describe what usecase you have that warrants this
> being claimed twice. Normally that is just needed when you let the
> regulator core handle enablement of a regulator over GPIO, i.e.
> ena_gpiod in struct regulator_config.

This pin can be assigned to all regulators so it is shared across them
also it can be used as voltage-selection gpio by regulator and as
enable signal by an other regulator. I mentioned that within the
dt-bindings and also mentioned that the config has to be the same.

> > +       /* We need the local number */
> > +       nr = da9062_gpio_get_hwgpio(gpi);
> 
> If you really need this we should add a public API to gpiolib and not
> create custom APIs.
> 
> Just make a patch adding
> 
> int gpiod_to_offset(struct gpio_desc *d);
> 
> to the public gpiolib API in include/linux/gpio/consumer.h
> 
> and add the code in gpiolib.c to do this trick.

Okay, I will add it.

Thanks for the review.

Regards,
  Marco

> Yours,
> Linus Walleij
> 

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

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

* Re: [PATCH 2/5] dt-bindings: mfd: da9062: add regulator voltage selection documentation
  2019-10-02 13:45                     ` Marco Felsch
@ 2019-10-22 10:22                       ` Marco Felsch
  0 siblings, 0 replies; 29+ messages in thread
From: Marco Felsch @ 2019-10-22 10:22 UTC (permalink / raw)
  To: Adam Thomson, broonie, linus.walleij, bgolaszewski
  Cc: devicetree, Support Opensource, lgirdwood, robh+dt, linux-kernel,
	Steve Twiss, kernel, lee.jones

Hi Linus, Bartosz,

can you have a look on this discussion? I wanna prepare a new version
and this is still open.

Regards,
  Marco

On 19-10-02 15:45, Marco Felsch wrote:
> On 19-09-30 09:53, Adam Thomson wrote:
> > On 26 September 2019 15:39, Marco Felsch wrote:
> > 
> > > On 19-09-26 14:04, Adam Thomson wrote:
> > > > On 26 September 2019 12:44, Marco Felsch wrote:
> > > >
> > > > > On 19-09-26 10:17, Adam Thomson wrote:
> > > > > > On 26 September 2019 09:10, Marco Felsch wrote:
> > > > > >
> > > > > > > On 19-09-25 16:18, Adam Thomson wrote:
> > > > > > > > On 25 September 2019 16:52, Marco Felsch wrote:
> > > > > > > >
> > > > > > > > > Hi Adam,
> > > > > > > > >
> > > > > > > > > On 19-09-24 09:23, Adam Thomson wrote:
> > > > > > > > > > On 17 September 2019 13:43, Marco Felsch wrote:
> > > > > > > > > >
> > > > > > > > > > > Add the documentation which describe the voltage selection gpio
> > > > > > > support.
> > > > > > > > > > > This property can be applied to each subnode within the
> > > 'regulators'
> > > > > > > > > > > node so each regulator can be configured differently.
> > > > > > > > > > >
> > > > > > > > > > > Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
> > > > > > > > > > > ---
> > > > > > > > > > >  Documentation/devicetree/bindings/mfd/da9062.txt | 9
> > > +++++++++
> > > > > > > > > > >  1 file changed, 9 insertions(+)
> > > > > > > > > > >
> > > > > > > > > > > diff --git a/Documentation/devicetree/bindings/mfd/da9062.txt
> > > > > > > > > > > b/Documentation/devicetree/bindings/mfd/da9062.txt
> > > > > > > > > > > index edca653a5777..9d9820d8177d 100644
> > > > > > > > > > > --- a/Documentation/devicetree/bindings/mfd/da9062.txt
> > > > > > > > > > > +++ b/Documentation/devicetree/bindings/mfd/da9062.txt
> > > > > > > > > > > @@ -66,6 +66,15 @@ Sub-nodes:
> > > > > > > > > > >    details of individual regulator device can be found in:
> > > > > > > > > > >    Documentation/devicetree/bindings/regulator/regulator.txt
> > > > > > > > > > >
> > > > > > > > > > > +  Optional regulator device-specific properties:
> > > > > > > > > > > +  - dlg,vsel-sense-gpios : The GPIO reference which should be
> > > used
> > > > > by
> > > > > > > the
> > > > > > > > > > > +    regulator to switch the voltage between active/suspend
> > > voltage
> > > > > > > settings.
> > > > > > > > > If
> > > > > > > > > > > +    the signal is active the active-settings are applied else the
> > > suspend
> > > > > > > > > > > +    settings are applied. Attention: Sharing the same gpio for other
> > > > > > > purposes
> > > > > > > > > > > +    or across multiple regulators is possible but the gpio settings
> > > must
> > > > > be
> > > > > > > the
> > > > > > > > > > > +    same. Also the gpio phandle must refer to to the dlg,da9062-
> > > gpio
> > > > > > > device
> > > > > > > > > > > +    other gpios are not allowed and make no sense.
> > > > > > > > > > > +
> > > > > > > > > >
> > > > > > > > > > Should we not use the binding names that are defined in 'gpio-
> > > > > > > regulator.yaml'
> > > > > > > > > as
> > > > > > > > > > these seem to be generic and would probably serve the purpose
> > > here?
> > > > > > > > >
> > > > > > > > > Hm.. as the description says:
> > > > > > > > >
> > > > > > > > > 8<--------------------------------------------------
> > > > > > > > > gpios:
> > > > > > > > >    description: Array of one or more GPIO pins used to select the
> > > > > > > > >    regulator voltage/current listed in "states".
> > > > > > > > > 8<--------------------------------------------------
> > > > > > > > >
> > > > > > > > > But we don't have a "states" property and we can't select between
> > > > > > > > > voltage or current.
> > > > > > > >
> > > > > > > > Yes I think I was at cross purposes when I made this remark. The
> > > bindings
> > > > > there
> > > > > > > > describe the GPOs that are used to enable/disable and set
> > > voltage/current
> > > > > for
> > > > > > > > regulators and the supported voltage/current levels that can be
> > > configured
> > > > > in
> > > > > > > > this manner. What you're describing is the GPI for DA9061/2. If you look
> > > at
> > > > > > > > GPIO handling in existing regulator drivers I believe they all deal with
> > > > > external
> > > > > > > > GPOs that are configured to enable/disable and set voltage/current
> > > limits
> > > > > > > rather
> > > > > > > > than the GPI on the PMIC itself. That's why I'm thinking that the
> > > > > configurations
> > > > > > > > you're doing here should actually be in a pinctrl or GPIO driver.
> > > > > > >
> > > > > > > That's true, the common gpio bindings are from the view of the
> > > > > > > processor, e.g. which gpio must the processor drive to enable/switch the
> > > > > > > regualtor. So one reasone more to use a non-common binding.
> > > > > > >
> > > > > > > Please take a look on my other comment I made :) I don't use the
> > > > > > > gpio-alternative function. I use it as an input.
> > > > > >
> > > > > > I know in the datasheet this isn't marked as an alternate function specifically
> > > > > > but to me having regulator control by the chip's own GPI is an alternative
> > > > > > function for that GPIO pin, in the same way a specific pin can be used for
> > > > > > SYS_EN or Watchdog control. It's a dedicated purpose rather than being a
> > > > > normal
> > > > > > GPI.
> > > > >
> > > > > Nope, SYS_EN or Watchdog is a special/alternate function and not a
> > > > > normal input.
> > > >
> > > > Having spoken with our HW team there's essentially no real difference.
> > >
> > > So I don't have to configure the gpio to alternate to use it as SYS_EN?
> > 
> > Yes you do, but the effect is much the same as manually configuring the GPIO as
> > input, just that the IC does it for you. The regulator control features could
> > well have been done in a similar manner. Guess that was a design choice.
> > 
> > >
> > > > >
> > > > > > See the following as an example of what I'm suggesting:
> > > > > >
> > > > > >
> > > > >
> > > https://elixir.bootlin.com/linux/latest/source/Documentation/devicetree/bindin
> > > > > gs/pinctrl/pinctrl-palmas.txt
> > > > > >
> > > > > > You could then pass the pinctrl information to the regulator driver and use
> > > > > > that rather than having device specific bindings for this. That's at least my
> > > > > > current interpretation of this anyway.
> > > > >
> > > > > For me pinctrl decides which function should be assigned to a pin. So in
> > > > > our case this would be:
> > > > >   - alternate
> > > > >   - gpo
> > > > >   - gpi
> > > > >
> > > > > In our use-case it is a gpi..
> > > >
> > > > It's not being used as a normal GPI as such. It's being used to enable/disable
> > > > the regulator so I disagree.
> > >
> > > This one is used as voltage-selection. What is a "normal" GPI in your
> > > point of view?
> > 
> > With the voltage selection and enable/disable control the actual work of
> > handling the GPI state is all done internally in the IC. There is no control
> > required from SW other than setting of initial direction. For a normal GPI
> 
> Thats correct and setting the direction and active levels can be done
> perfectly by the gpio-interface.
> 
> > I would expect SW to be involved in the handling of that GPI state, for example
> > as part of a bit banging interface.
> > 
> > >
> > > > >
> > > > > An other reason why pinctrl seems not be the right solution is that the
> > > > > regulator must be configured to use this gpi. This decision can't be
> > > > > made globally because each regulator can be configured differently.. For
> > > > > me its just a local gpio.
> > > >
> > > > You'd pass pinctrl information, via DT, to the regulator driver so it can set
> > > > accordingly. At least that's my take here, unless I'm missing something. The
> > > > regulator driver would be the consumer and could set the regulator control
> > > > accordingly.
> > >
> > > IMHO this is what I have done. I use the gpi so the regulator is the
> > > consumer. Since the gpi can be used by several regulators for voltage
> > > selection or enable/disable action this gpi is marked as shared. If I
> > > got you right than you would do something like for regulatorX.
> > >
> > >   pinctrl-node {
> > >
> > >   	gpio2 {
> > > 		func = "vsel";
> > > 	}
> > >   }
> > >
> > > But the gpi(o)2 can also be used to enable/disable a regulatorY if I
> > > understood the datasheet correctly. I other words:
> > >
> > >
> > >
> > >          +--> Alternate function
> > >       /
> > >   ---+   +--> GPI ----> Edge detection ---> more processing
> > >    |       |                |
> > >    |       |                +-----> Regulator control
> > >    |       |                          |
> > >    \__  __/ \__________  _______
> > >       \/               \/
> > >    pinctrl            gpio
> > >
> > > This is how I understood the pinctrl use-case. I configure the pin as
> > > gpio and then the regulator driver consume a gpio.
> > 
> > How I see it is that you configure the function through pinctrl as
> > 'regulator_switch' or 'regulator_vsel' (or whatever name is deemed sensible to
> 
> The case is that it can be "muxed" for both at same time so there is no
> or instead it is a or/and. Depending on the design some regulators can
> be turned off and some should be switched upon that signal.
> 
> > cover the two types of functionality) and then the pinctrl driver code would do
> > the work of requesting and configuring the relevant GPIO as input so it's no
> > longer available for use as something else (basically what you do in the
> > regulator driver right now).
> 
> So by this I avoided the user-space to get this gpio and this seems fine
> to me. What a driver does with a gpio is up to the driver but the gpio
> shouldn't be reachable from the user-space.
> 
> > I believe you can have more than one consumer of a pinctrl pin so it could be
> > provided to both regulator X and Y to indicate that this is the chosen
> > functionality of that pin and so the regulator can then be marked as being
> > controlled by that pin. Using pinctrl also would mean you're using standard
> > bindings as well rather than something which is device specific.
> 
> That seems wrong to me because pinctrl should assign a dedicated function
> to that pin e.g. regulator_switch or regulator_vsel. But thats wrong as
> I pointed out above. On the other hand the gpio as the name says is
> general purpose and each regulator gives the meaning to it.
> 
> > > > At the end of the day I'm not the gatekeeper here so I think Mark's input is
> > > > necessary as he will likely have a view on how this should be done. I appreciate
> > > > the work you've done here but I want to be sure we have a generic solution
> > > > as this would also apply to DA9063 and possibly other devices too.
> > >
> > > Why should this only apply to da9062 devices? IMHO this property can be
> > > used by any other dlg pmic as well if it is supported. Comments and suggestions
> > > are welcome so no worries ;)
> > 
> > You're right. You can do the same for DA9063 and other devices potentially. I
> > would just like to make sure we take the right/agreed approach. Potentially
> > this could be used in non-Dialog products as well which have similar
> > functionality.
> 
> Yeah, but I think we should consider about that after an other device
> appears with that funcitonality.
> 
> > As I say, Mark is really the gatekeeper so his input is also key in this.
> 
> That's right, I added Mark to To.
> 
> Regards,
>   Marco
> 
> > 
> > >
> > > Regards,
> > >   Marco
> > >
> > > > Have added Mark to the 'To' in this e-mail thread so he might see it.
> > > > >
> > > > > Regards,
> > > > >   Marco
> > > > >
> > > > > > >
> > > > > > > Regards,
> > > > > > >   Marco
> > > > > > >
> > > > > > >
> > > > > > > > I'd be interested in hearing Mark's view on this though as he has far
> > > more
> > > > > > > > experience in this area than I do.
> > > > > > > >
> > > > > > > > >
> > > > > > > > > Regards,
> > > > > > > > >   Marco
> > > > > > > > >
> > > > > > > > > > >  - rtc : This node defines settings required for the Real-Time Clock
> > > > > > > associated
> > > > > > > > > > >    with the DA9062. There are currently no entries in this binding,
> > > > > however
> > > > > > > > > > >    compatible = "dlg,da9062-rtc" should be added if a node is
> > > created.
> > > > > > > > > > > --
> > > > > > > > > > > 2.20.1
> > > > > > > > > >
> > > > > > > > > >
> > > > > > > > >
> > > > > > > > > --
> > > > > > > > > Pengutronix e.K.                           |                             |
> > > > > > > > > Industrial Linux Solutions                 | http://www.pengutronix.de/  |
> > > > > > > > > Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-
> > > 0
> > > > > |
> > > > > > > > > Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555
> > > |
> > > > > > > >
> > > > > > >
> > > > > > > --
> > > > > > > Pengutronix e.K.                           |                             |
> > > > > > > Industrial Linux Solutions                 | http://www.pengutronix.de/  |
> > > > > > > Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0
> > > |
> > > > > > > Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
> > > > > >
> > > > >
> > > > > --
> > > > > Pengutronix e.K.                           |                             |
> > > > > Industrial Linux Solutions                 | http://www.pengutronix.de/  |
> > > > > Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
> > > > > Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
> > > >
> > >
> > > --
> > > Pengutronix e.K.                           |                             |
> > > Industrial Linux Solutions                 | http://www.pengutronix.de/  |
> > > Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
> > > Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
> > 
> 
> -- 
> Pengutronix e.K.                           |                             |
> Industrial Linux Solutions                 | http://www.pengutronix.de/  |
> Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
> Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
> 
> 

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

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

end of thread, other threads:[~2019-10-22 10:22 UTC | newest]

Thread overview: 29+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-09-17 12:42 [PATCH 0/5] DA9062 PMIC fixes and features Marco Felsch
2019-09-17 12:42 ` [PATCH 1/5] regulator: da9062: fix suspend_enable/disable preparation Marco Felsch
2019-09-18 12:41   ` Adam Thomson
2019-09-18 15:05     ` Marco Felsch
2019-09-23 16:03   ` Adam Thomson
2019-09-23 22:02     ` Marco Felsch
2019-09-24  8:58       ` Adam Thomson
2019-09-23 21:23   ` Applied "regulator: da9062: fix suspend_enable/disable preparation" to the regulator tree Mark Brown
2019-09-17 12:42 ` [PATCH 2/5] dt-bindings: mfd: da9062: add regulator voltage selection documentation Marco Felsch
2019-09-24  9:23   ` Adam Thomson
2019-09-25 15:51     ` Marco Felsch
2019-09-25 16:18       ` Adam Thomson
2019-09-26  8:09         ` Marco Felsch
2019-09-26 10:17           ` Adam Thomson
2019-09-26 11:43             ` Marco Felsch
2019-09-26 14:04               ` Adam Thomson
2019-09-26 14:38                 ` Marco Felsch
2019-09-30  9:53                   ` Adam Thomson
2019-10-02 13:45                     ` Marco Felsch
2019-10-22 10:22                       ` Marco Felsch
2019-09-17 12:42 ` [PATCH 3/5] regulator: da9062: add voltage selection gpio support Marco Felsch
2019-09-17 14:22   ` kbuild test robot
2019-09-17 14:34     ` Marco Felsch
2019-09-24  9:48   ` Adam Thomson
2019-09-25 15:59     ` Marco Felsch
2019-10-04 19:41   ` Linus Walleij
2019-10-07  8:59     ` Marco Felsch
2019-09-17 12:42 ` [PATCH 4/5] dt-bindings: mfd: da9062: add regulator gpio enable/disable documentation Marco Felsch
2019-09-17 12:42 ` [PATCH 5/5] regulator: da9062: add gpio based regulator dis-/enable support Marco Felsch

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).