linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/8] regulator/mfd/dt_bindings: bd718x7: Support ROHM bd71847
@ 2018-08-29 12:35 Matti Vaittinen
  2018-08-29 12:36 ` [PATCH 1/8] regulator: bd71837: Disable voltage monitoring for LDO3/4 Matti Vaittinen
                   ` (7 more replies)
  0 siblings, 8 replies; 22+ messages in thread
From: Matti Vaittinen @ 2018-08-29 12:35 UTC (permalink / raw)
  To: lee.jones, robh+dt, mark.rutland, lgirdwood, broonie,
	mazziesaccount, matti.vaittinen, devicetree, linux-kernel,
	heikki.haikola, mikko.mutanen

Patch series adding support for ROHM BD71847 PMIC.

ROHM BD71847 is modified version of ROHM BD71837 Power Management IC.
BD71847 integrates 6 buck regulators and 6  LDO’s.

The patch series adds support for BD71847 in BD71837 driver. It also
extends BD71837 to support all BUCK/LDO output voltages.

Support for "pickable voltage ranges" is introduced in order to fully
support BD71837/BD71847 voltage selection registers. Some of the voltage
regulators provide different multiple voltage ranges and output voltage
is determined by range selection bit(s) and voltage selection bits
instead of plain voltage selection bits.

Patch 1:
	BD71837/BD71847 voltage monitoring fix.
Patch 2:
	limited BD71847 support (without range selection)
Patch 3:
	BD71847 device-tree bindings for regulators
Patch 4:
	BD71847 device-tree bindings for mfd
Patch 5:
	Voltage range selection support to regulator helpers
Patch 6:
	Simple renaming plenty of BD71837 occurrences to BD718XX
Patch 7:
	BD71837/BD71847 Full voltage range support using helpers from
	patch 5
Patch 8:
	Renaming bd71837 regulator driver to bd718x7

this patch series is based on linux-next tag next-20180823.

Matti Vaittinen (8):
  regulator: bd71837: Disable voltage monitoring for LDO3/4
  regulator: Support ROHM BD71847 power management IC
  regulator: dt bindings: add BD71847 device-tree binding documentation
  mfd: dt bindings: add BD71847 device-tree binding documentation
  regulator: Support regulators where voltage ranges are selectable
  regulator/mfd: bd718xx: rename bd71837/bd71847 common instances
  regulator: bd718XX use pickable ranges
  regulator: bd718xx: renme bd71837 to 718xx

 .../devicetree/bindings/mfd/rohm,bd71837-pmic.txt  |   17 +-
 .../bindings/regulator/rohm,bd71837-regulator.txt  |   12 +-
 drivers/mfd/rohm-bd718x7.c                         |  182 ++--
 drivers/regulator/Kconfig                          |    2 +-
 drivers/regulator/Makefile                         |    2 +-
 drivers/regulator/bd71837-regulator.c              |  626 -----------
 drivers/regulator/bd718x7-regulator.c              | 1138 ++++++++++++++++++++
 drivers/regulator/core.c                           |    5 +
 drivers/regulator/helpers.c                        |  232 ++++
 include/linux/mfd/rohm-bd718x7.h                   |  375 +++----
 include/linux/regulator/driver.h                   |   20 +-
 11 files changed, 1714 insertions(+), 897 deletions(-)
 delete mode 100644 drivers/regulator/bd71837-regulator.c
 create mode 100644 drivers/regulator/bd718x7-regulator.c

-- 
2.14.3


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

* [PATCH 1/8] regulator: bd71837: Disable voltage monitoring for LDO3/4
  2018-08-29 12:35 [PATCH 0/8] regulator/mfd/dt_bindings: bd718x7: Support ROHM bd71847 Matti Vaittinen
@ 2018-08-29 12:36 ` Matti Vaittinen
  2018-09-11 12:40   ` Lee Jones
  2018-08-29 12:36 ` [PATCH 2/8] regulator: Support ROHM BD71847 power management IC Matti Vaittinen
                   ` (6 subsequent siblings)
  7 siblings, 1 reply; 22+ messages in thread
From: Matti Vaittinen @ 2018-08-29 12:36 UTC (permalink / raw)
  To: lee.jones, robh+dt, mark.rutland, lgirdwood, broonie,
	mazziesaccount, matti.vaittinen, devicetree, linux-kernel,
	heikki.haikola, mikko.mutanen

There is a HW quirk in BD71837. The shutdown sequence timings for
bucks/LDOs which are enabled via register interface are changed.
At PMIC poweroff the voltage for BUCK6/7 is cut immediately at the
beginning of shut-down sequence. This causes LDO5/6 voltage
monitoring to detect under voltage and force PMIC to emergency
state instead of poweroff. Disable voltage monitoring for LDO5 and
LDO6 at probe to avoid this.

Signed-off-by: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
---
 drivers/regulator/bd71837-regulator.c | 19 +++++++++++++++++++
 include/linux/mfd/rohm-bd718x7.h      | 33 ++++++++++++++++++++++++++++++---
 2 files changed, 49 insertions(+), 3 deletions(-)

diff --git a/drivers/regulator/bd71837-regulator.c b/drivers/regulator/bd71837-regulator.c
index 0f8ac8dec3e1..a1bd8aaf4d98 100644
--- a/drivers/regulator/bd71837-regulator.c
+++ b/drivers/regulator/bd71837-regulator.c
@@ -569,6 +569,25 @@ static int bd71837_probe(struct platform_device *pdev)
 			BD71837_REG_REGLOCK);
 	}
 
+	/*
+	 * There is a HW quirk in BD71837. The shutdown sequence timings for
+	 * bucks/LDOs which are controlled via register interface are changed.
+	 * At PMIC poweroff the voltage for BUCK6/7 is cut immediately at the
+	 * beginning of shut-down sequence. As bucks 6 and 7 are parent
+	 * supplies for LDO5 and LDO6 - this causes LDO5/6 voltage
+	 * monitoring to errorneously detect under voltage and force PMIC to
+	 * emergency state instead of poweroff. In order to avoid this we
+	 * disable voltage monitoring for LDO5 and LDO6
+	 */
+	err = regmap_update_bits(pmic->mfd->regmap, BD718XX_REG_MVRFLTMASK2,
+				 BD718XX_LDO5_VRMON80 | BD718XX_LDO6_VRMON80,
+				 BD718XX_LDO5_VRMON80 | BD718XX_LDO6_VRMON80);
+	if (err) {
+		dev_err(&pmic->pdev->dev,
+			"Failed to disable voltage monitoring\n");
+		goto err;
+	}
+
 	for (i = 0; i < ARRAY_SIZE(pmic_regulator_inits); i++) {
 
 		struct regulator_desc *desc;
diff --git a/include/linux/mfd/rohm-bd718x7.h b/include/linux/mfd/rohm-bd718x7.h
index a528747f8aed..e8338e5dc10b 100644
--- a/include/linux/mfd/rohm-bd718x7.h
+++ b/include/linux/mfd/rohm-bd718x7.h
@@ -78,9 +78,9 @@ enum {
 	BD71837_REG_TRANS_COND0        = 0x1F,
 	BD71837_REG_TRANS_COND1        = 0x20,
 	BD71837_REG_VRFAULTEN          = 0x21,
-	BD71837_REG_MVRFLTMASK0        = 0x22,
-	BD71837_REG_MVRFLTMASK1        = 0x23,
-	BD71837_REG_MVRFLTMASK2        = 0x24,
+	BD718XX_REG_MVRFLTMASK0        = 0x22,
+	BD718XX_REG_MVRFLTMASK1        = 0x23,
+	BD718XX_REG_MVRFLTMASK2        = 0x24,
 	BD71837_REG_RCVCFG             = 0x25,
 	BD71837_REG_RCVNUM             = 0x26,
 	BD71837_REG_PWRONCONFIG0       = 0x27,
@@ -159,6 +159,33 @@ enum {
 #define BUCK8_MASK		0x3F
 #define BUCK8_DEFAULT		0x1E
 
+/* BD718XX Voltage monitoring masks */
+#define BD718XX_BUCK1_VRMON80           0x1
+#define BD718XX_BUCK1_VRMON130          0x2
+#define BD718XX_BUCK2_VRMON80           0x4
+#define BD718XX_BUCK2_VRMON130          0x8
+#define BD718XX_1ST_NODVS_BUCK_VRMON80  0x1
+#define BD718XX_1ST_NODVS_BUCK_VRMON130 0x2
+#define BD718XX_2ND_NODVS_BUCK_VRMON80  0x4
+#define BD718XX_2ND_NODVS_BUCK_VRMON130 0x8
+#define BD718XX_3RD_NODVS_BUCK_VRMON80  0x10
+#define BD718XX_3RD_NODVS_BUCK_VRMON130 0x20
+#define BD718XX_4TH_NODVS_BUCK_VRMON80  0x40
+#define BD718XX_4TH_NODVS_BUCK_VRMON130 0x80
+#define BD718XX_LDO1_VRMON80            0x1
+#define BD718XX_LDO2_VRMON80            0x2
+#define BD718XX_LDO3_VRMON80            0x4
+#define BD718XX_LDO4_VRMON80            0x8
+#define BD718XX_LDO5_VRMON80            0x10
+#define BD718XX_LDO6_VRMON80            0x20
+
+/* BD71837 specific voltage monitoring masks */
+#define BD71837_BUCK3_VRMON80           0x10
+#define BD71837_BUCK3_VRMON130          0x20
+#define BD71837_BUCK4_VRMON80           0x40
+#define BD71837_BUCK4_VRMON130          0x80
+#define BD71837_LDO7_VRMON80            0x40
+
 /* BD71837_REG_IRQ bits */
 #define IRQ_SWRST		0x40
 #define IRQ_PWRON_S		0x20
-- 
2.14.3


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

* [PATCH 2/8] regulator: Support ROHM BD71847 power management IC
  2018-08-29 12:35 [PATCH 0/8] regulator/mfd/dt_bindings: bd718x7: Support ROHM bd71847 Matti Vaittinen
  2018-08-29 12:36 ` [PATCH 1/8] regulator: bd71837: Disable voltage monitoring for LDO3/4 Matti Vaittinen
@ 2018-08-29 12:36 ` Matti Vaittinen
  2018-09-11 13:48   ` Lee Jones
  2018-08-29 12:37 ` [PATCH 3/8] regulator: dt bindings: add BD71847 device-tree binding documentation Matti Vaittinen
                   ` (5 subsequent siblings)
  7 siblings, 1 reply; 22+ messages in thread
From: Matti Vaittinen @ 2018-08-29 12:36 UTC (permalink / raw)
  To: lee.jones, robh+dt, mark.rutland, lgirdwood, broonie,
	mazziesaccount, matti.vaittinen, devicetree, linux-kernel,
	heikki.haikola, mikko.mutanen

BD71847 is reduced version of BD71837. DVS bucks 3 and 4 are
removed as is LDO7. Voltage ranges of some regulators are
expanded.

Add initial support for BD71847 with BD71847 driver.

Signed-off-by: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
---
 drivers/mfd/rohm-bd718x7.c            |   84 ++-
 drivers/regulator/bd71837-regulator.c | 1056 ++++++++++++++++++++++-----------
 include/linux/mfd/rohm-bd718x7.h      |  272 ++++-----
 3 files changed, 910 insertions(+), 502 deletions(-)

diff --git a/drivers/mfd/rohm-bd718x7.c b/drivers/mfd/rohm-bd718x7.c
index 75c8ec659547..c95f34269bb6 100644
--- a/drivers/mfd/rohm-bd718x7.c
+++ b/drivers/mfd/rohm-bd718x7.c
@@ -7,21 +7,34 @@
 // Datasheet available from
 // https://www.rohm.com/datasheet/BD71837MWV/bd71837mwv-e
 
+#include <linux/gpio_keys.h>
 #include <linux/i2c.h>
 #include <linux/input.h>
 #include <linux/interrupt.h>
 #include <linux/mfd/rohm-bd718x7.h>
 #include <linux/mfd/core.h>
 #include <linux/module.h>
+#include <linux/of_device.h>
 #include <linux/regmap.h>
 
-/*
- * gpio_keys.h requires definiton of bool. It is brought in
- * by above includes. Keep this as last until gpio_keys.h gets fixed.
- */
-#include <linux/gpio_keys.h>
+static const u8 bd71837_supported_revisions[] = { 0xA2 };
+static const u8 bd71847_supported_revisions[] = { 0xA0 };
 
-static const u8 supported_revisions[] = { 0xA2 /* BD71837 */ };
+struct known_revisions {
+	const u8 (*revisions)[];
+	unsigned int known_revisions;
+};
+
+static const struct known_revisions supported_revisions[BD718XX_TYPE_AMNT] = {
+	[BD718XX_TYPE_BD71837] = {
+		.revisions = &bd71837_supported_revisions,
+		.known_revisions = ARRAY_SIZE(bd71837_supported_revisions),
+	},
+	[BD718XX_TYPE_BD71847] = {
+		.revisions = &bd71847_supported_revisions,
+		.known_revisions = ARRAY_SIZE(bd71847_supported_revisions),
+	},
+};
 
 static struct gpio_keys_button button = {
 	.code = KEY_POWER,
@@ -41,8 +54,8 @@ static struct mfd_cell bd71837_mfd_cells[] = {
 		.platform_data = &bd718xx_powerkey_data,
 		.pdata_size = sizeof(bd718xx_powerkey_data),
 	},
-	{ .name = "bd71837-clk", },
-	{ .name = "bd71837-pmic", },
+	{ .name = "bd718xx-clk", },
+	{ .name = "bd718xx-pmic", },
 };
 
 static const struct regmap_irq bd71837_irqs[] = {
@@ -61,16 +74,16 @@ static struct regmap_irq_chip bd71837_irq_chip = {
 	.num_irqs = ARRAY_SIZE(bd71837_irqs),
 	.num_regs = 1,
 	.irq_reg_stride = 1,
-	.status_base = BD71837_REG_IRQ,
-	.mask_base = BD71837_REG_MIRQ,
-	.ack_base = BD71837_REG_IRQ,
+	.status_base = BD718XX_REG_IRQ,
+	.mask_base = BD718XX_REG_MIRQ,
+	.ack_base = BD718XX_REG_IRQ,
 	.init_ack_masked = true,
 	.mask_invert = false,
 };
 
 static const struct regmap_range pmic_status_range = {
-	.range_min = BD71837_REG_IRQ,
-	.range_max = BD71837_REG_POW_STATE,
+	.range_min = BD718XX_REG_IRQ,
+	.range_max = BD718XX_REG_POW_STATE,
 };
 
 static const struct regmap_access_table volatile_regs = {
@@ -82,7 +95,7 @@ static const struct regmap_config bd71837_regmap_config = {
 	.reg_bits = 8,
 	.val_bits = 8,
 	.volatile_table = &volatile_regs,
-	.max_register = BD71837_MAX_REGISTER - 1,
+	.max_register = BD718XX_MAX_REGISTER - 1,
 	.cache_type = REGCACHE_RBTREE,
 };
 
@@ -91,13 +104,19 @@ static int bd71837_i2c_probe(struct i2c_client *i2c,
 {
 	struct bd71837 *bd71837;
 	int ret, i;
-	unsigned int val;
+	const unsigned int *type;
 
 	bd71837 = devm_kzalloc(&i2c->dev, sizeof(struct bd71837), GFP_KERNEL);
 
 	if (!bd71837)
 		return -ENOMEM;
 
+	type = of_device_get_match_data(&i2c->dev);
+	if (!type || *type >= BD718XX_TYPE_AMNT) {
+		dev_err(&i2c->dev, "Bad chip type\n");
+		return -ENODEV;
+	}
+
 	bd71837->chip_irq = i2c->irq;
 
 	if (!bd71837->chip_irq) {
@@ -105,6 +124,7 @@ static int bd71837_i2c_probe(struct i2c_client *i2c,
 		return -EINVAL;
 	}
 
+	bd71837->chip_type = *type;
 	bd71837->dev = &i2c->dev;
 	dev_set_drvdata(&i2c->dev, bd71837);
 
@@ -114,18 +134,21 @@ static int bd71837_i2c_probe(struct i2c_client *i2c,
 		return PTR_ERR(bd71837->regmap);
 	}
 
-	ret = regmap_read(bd71837->regmap, BD71837_REG_REV, &val);
+	ret = regmap_read(bd71837->regmap, BD718XX_REG_REV, &bd71837->chip_rev);
 	if (ret) {
-		dev_err(&i2c->dev, "Read BD71837_REG_DEVICE failed\n");
+		dev_err(&i2c->dev, "Failed to read revision register\n");
 		return ret;
 	}
-	for (i = 0; i < ARRAY_SIZE(supported_revisions); i++)
-		if (supported_revisions[i] == val)
+	for (i = 0;
+	     i < supported_revisions[bd71837->chip_type].known_revisions; i++)
+		if ((*supported_revisions[bd71837->chip_type].revisions)[i] ==
+		    bd71837->chip_rev)
 			break;
 
-	if (i == ARRAY_SIZE(supported_revisions)) {
-		dev_err(&i2c->dev, "Unsupported chip revision\n");
-		return -ENODEV;
+	if (i == supported_revisions[bd71837->chip_type].known_revisions) {
+		dev_err(&i2c->dev, "Unrecognized revision 0x%02x\n",
+			bd71837->chip_rev);
+		return -EINVAL;
 	}
 
 	ret = devm_regmap_add_irq_chip(&i2c->dev, bd71837->regmap,
@@ -138,7 +161,7 @@ static int bd71837_i2c_probe(struct i2c_client *i2c,
 
 	/* Configure short press to 10 milliseconds */
 	ret = regmap_update_bits(bd71837->regmap,
-				 BD71837_REG_PWRONCONFIG0,
+				 BD718XX_REG_PWRONCONFIG0,
 				 BD718XX_PWRBTN_PRESS_DURATION_MASK,
 				 BD718XX_PWRBTN_SHORT_PRESS_10MS);
 	if (ret) {
@@ -149,7 +172,7 @@ static int bd71837_i2c_probe(struct i2c_client *i2c,
 
 	/* Configure long press to 10 seconds */
 	ret = regmap_update_bits(bd71837->regmap,
-				 BD71837_REG_PWRONCONFIG1,
+				 BD718XX_REG_PWRONCONFIG1,
 				 BD718XX_PWRBTN_PRESS_DURATION_MASK,
 				 BD718XX_PWRBTN_LONG_PRESS_10S);
 
@@ -177,9 +200,20 @@ static int bd71837_i2c_probe(struct i2c_client *i2c,
 
 	return ret;
 }
+static const unsigned int chip_types[] = {
+	[BD718XX_TYPE_BD71837] = BD718XX_TYPE_BD71837,
+	[BD718XX_TYPE_BD71847] = BD718XX_TYPE_BD71847,
+};
 
 static const struct of_device_id bd71837_of_match[] = {
-	{ .compatible = "rohm,bd71837", },
+	{
+		.compatible = "rohm,bd71837",
+		.data = &chip_types[BD718XX_TYPE_BD71837]
+	},
+	{
+		.compatible = "rohm,bd71847",
+		.data = &chip_types[BD718XX_TYPE_BD71847]
+	},
 	{ }
 };
 MODULE_DEVICE_TABLE(of, bd71837_of_match);
diff --git a/drivers/regulator/bd71837-regulator.c b/drivers/regulator/bd71837-regulator.c
index a1bd8aaf4d98..49f75258aa20 100644
--- a/drivers/regulator/bd71837-regulator.c
+++ b/drivers/regulator/bd71837-regulator.c
@@ -15,11 +15,11 @@
 #include <linux/regulator/of_regulator.h>
 #include <linux/slab.h>
 
-struct bd71837_pmic {
-	struct regulator_desc descs[BD71837_REGULATOR_CNT];
+struct bd718xx_pmic {
+	struct bd718xx_regulator_data *rdata;
 	struct bd71837 *mfd;
 	struct platform_device *pdev;
-	struct regulator_dev *rdev[BD71837_REGULATOR_CNT];
+	struct regulator_dev *rdev[BD718XX_REGULATOR_MAX];
 };
 
 /*
@@ -33,7 +33,7 @@ struct bd71837_pmic {
 static int bd71837_buck1234_set_ramp_delay(struct regulator_dev *rdev,
 					   int ramp_delay)
 {
-	struct bd71837_pmic *pmic = rdev_get_drvdata(rdev);
+	struct bd718xx_pmic *pmic = rdev_get_drvdata(rdev);
 	struct bd71837 *mfd = pmic->mfd;
 	int id = rdev->desc->id;
 	unsigned int ramp_value = BUCK_RAMPRATE_10P00MV;
@@ -60,7 +60,7 @@ static int bd71837_buck1234_set_ramp_delay(struct regulator_dev *rdev,
 			rdev->desc->name, ramp_delay);
 	}
 
-	return regmap_update_bits(mfd->regmap, BD71837_REG_BUCK1_CTRL + id,
+	return regmap_update_bits(mfd->regmap, BD718XX_REG_BUCK1_CTRL + id,
 				  BUCK_RAMPRATE_MASK, ramp_value << 6);
 }
 
@@ -69,7 +69,7 @@ static int bd71837_buck1234_set_ramp_delay(struct regulator_dev *rdev,
  * is changed. Hence we return -EBUSY for these if voltage is changed
  * when BUCK/LDO is enabled.
  */
-static int bd71837_set_voltage_sel_restricted(struct regulator_dev *rdev,
+static int bd718xx_set_voltage_sel_restricted(struct regulator_dev *rdev,
 						    unsigned int sel)
 {
 	if (regulator_is_enabled_regmap(rdev))
@@ -78,45 +78,45 @@ static int bd71837_set_voltage_sel_restricted(struct regulator_dev *rdev,
 	return regulator_set_voltage_sel_regmap(rdev, sel);
 }
 
-static struct regulator_ops bd71837_ldo_regulator_ops = {
+static struct regulator_ops bd718xx_ldo_regulator_ops = {
 	.enable = regulator_enable_regmap,
 	.disable = regulator_disable_regmap,
 	.is_enabled = regulator_is_enabled_regmap,
 	.list_voltage = regulator_list_voltage_linear_range,
-	.set_voltage_sel = bd71837_set_voltage_sel_restricted,
+	.set_voltage_sel = bd718xx_set_voltage_sel_restricted,
 	.get_voltage_sel = regulator_get_voltage_sel_regmap,
 };
 
-static struct regulator_ops bd71837_ldo_regulator_nolinear_ops = {
+static struct regulator_ops bd718xx_ldo_regulator_nolinear_ops = {
 	.enable = regulator_enable_regmap,
 	.disable = regulator_disable_regmap,
 	.is_enabled = regulator_is_enabled_regmap,
 	.list_voltage = regulator_list_voltage_table,
-	.set_voltage_sel = bd71837_set_voltage_sel_restricted,
+	.set_voltage_sel = bd718xx_set_voltage_sel_restricted,
 	.get_voltage_sel = regulator_get_voltage_sel_regmap,
 };
 
-static struct regulator_ops bd71837_buck_regulator_ops = {
+static struct regulator_ops bd718xx_buck_regulator_ops = {
 	.enable = regulator_enable_regmap,
 	.disable = regulator_disable_regmap,
 	.is_enabled = regulator_is_enabled_regmap,
 	.list_voltage = regulator_list_voltage_linear_range,
-	.set_voltage_sel = bd71837_set_voltage_sel_restricted,
+	.set_voltage_sel = bd718xx_set_voltage_sel_restricted,
 	.get_voltage_sel = regulator_get_voltage_sel_regmap,
 	.set_voltage_time_sel = regulator_set_voltage_time_sel,
 };
 
-static struct regulator_ops bd71837_buck_regulator_nolinear_ops = {
+static struct regulator_ops bd718xx_buck_regulator_nolinear_ops = {
 	.enable = regulator_enable_regmap,
 	.disable = regulator_disable_regmap,
 	.is_enabled = regulator_is_enabled_regmap,
 	.list_voltage = regulator_list_voltage_table,
-	.set_voltage_sel = bd71837_set_voltage_sel_restricted,
+	.set_voltage_sel = bd718xx_set_voltage_sel_restricted,
 	.get_voltage_sel = regulator_get_voltage_sel_regmap,
 	.set_voltage_time_sel = regulator_set_voltage_time_sel,
 };
 
-static struct regulator_ops bd71837_buck1234_regulator_ops = {
+static struct regulator_ops bd718xx_dvs_buck_regulator_ops = {
 	.enable = regulator_enable_regmap,
 	.disable = regulator_disable_regmap,
 	.is_enabled = regulator_is_enabled_regmap,
@@ -128,24 +128,30 @@ static struct regulator_ops bd71837_buck1234_regulator_ops = {
 };
 
 /*
- * BUCK1/2/3/4
+ * BD71837 BUCK1/2/3/4
+ * BD71847 BUCK1/2
  * 0.70 to 1.30V (10mV step)
  */
-static const struct regulator_linear_range bd71837_buck1234_voltage_ranges[] = {
+static const struct regulator_linear_range bd718xx_dvs_buck_volts[] = {
 	REGULATOR_LINEAR_RANGE(700000, 0x00, 0x3C, 10000),
 	REGULATOR_LINEAR_RANGE(1300000, 0x3D, 0x3F, 0),
 };
 
 /*
- * BUCK5
- * 0.9V to 1.35V ()
+ * BD71837 BUCK5
+ * BD71847 BUCK3
+ * 0.7V to 1.35V ()
  */
-static const struct regulator_linear_range bd71837_buck5_voltage_ranges[] = {
+static const struct regulator_linear_range bd718xx_1st_nodvs_buck_volts[] = {
 	REGULATOR_LINEAR_RANGE(700000, 0x00, 0x03, 100000),
 	REGULATOR_LINEAR_RANGE(1050000, 0x04, 0x05, 50000),
 	REGULATOR_LINEAR_RANGE(1200000, 0x06, 0x07, 150000),
 };
 
+static const struct regulator_linear_range bd71847_buck4_voltage_ranges[] = {
+	REGULATOR_LINEAR_RANGE(3000000, 0x00, 0x03, 100000),
+};
+
 /*
  * BUCK6
  * 3.0V to 3.3V (step 100mV)
@@ -155,7 +161,8 @@ static const struct regulator_linear_range bd71837_buck6_voltage_ranges[] = {
 };
 
 /*
- * BUCK7
+ * BD71837 BUCK7
+ * BD71847 BUCK5
  * 000 = 1.605V
  * 001 = 1.695V
  * 010 = 1.755V
@@ -165,7 +172,7 @@ static const struct regulator_linear_range bd71837_buck6_voltage_ranges[] = {
  * 110 = 1.95V
  * 111 = 1.995V
  */
-static const unsigned int buck_7_volts[] = {
+static const unsigned int bd718xx_3rd_nodvs_buck_volts[] = {
 	1605000, 1695000, 1755000, 1800000, 1845000, 1905000, 1950000, 1995000
 };
 
@@ -173,16 +180,15 @@ static const unsigned int buck_7_volts[] = {
  * BUCK8
  * 0.8V to 1.40V (step 10mV)
  */
-static const struct regulator_linear_range bd71837_buck8_voltage_ranges[] = {
+static const struct regulator_linear_range bd718xx_4th_nodvs_buck_volts[] = {
 	REGULATOR_LINEAR_RANGE(800000, 0x00, 0x3C, 10000),
-	REGULATOR_LINEAR_RANGE(1400000, 0x3D, 0x3F, 0),
 };
 
 /*
  * LDO1
  * 3.0 to 3.3V (100mV step)
  */
-static const struct regulator_linear_range bd71837_ldo1_voltage_ranges[] = {
+static const struct regulator_linear_range bd718xx_ldo1_volts[] = {
 	REGULATOR_LINEAR_RANGE(3000000, 0x00, 0x03, 100000),
 };
 
@@ -198,7 +204,7 @@ static const unsigned int ldo_2_volts[] = {
  * LDO3
  * 1.8 to 3.3V (100mV step)
  */
-static const struct regulator_linear_range bd71837_ldo3_voltage_ranges[] = {
+static const struct regulator_linear_range bd718xx_ldo3_volts[] = {
 	REGULATOR_LINEAR_RANGE(1800000, 0x00, 0x0F, 100000),
 };
 
@@ -206,16 +212,15 @@ static const struct regulator_linear_range bd71837_ldo3_voltage_ranges[] = {
  * LDO4
  * 0.9 to 1.8V (100mV step)
  */
-static const struct regulator_linear_range bd71837_ldo4_voltage_ranges[] = {
+static const struct regulator_linear_range bd718xx_ldo4_volts[] = {
 	REGULATOR_LINEAR_RANGE(900000, 0x00, 0x09, 100000),
-	REGULATOR_LINEAR_RANGE(1800000, 0x0A, 0x0F, 0),
 };
 
 /*
- * LDO5
+ * LDO5 for BD71837
  * 1.8 to 3.3V (100mV step)
  */
-static const struct regulator_linear_range bd71837_ldo5_voltage_ranges[] = {
+static const struct regulator_linear_range bd718xx_ldo5_volts[] = {
 	REGULATOR_LINEAR_RANGE(1800000, 0x00, 0x0F, 100000),
 };
 
@@ -223,331 +228,722 @@ static const struct regulator_linear_range bd71837_ldo5_voltage_ranges[] = {
  * LDO6
  * 0.9 to 1.8V (100mV step)
  */
-static const struct regulator_linear_range bd71837_ldo6_voltage_ranges[] = {
+static const struct regulator_linear_range bd718xx_ldo6_volts[] = {
 	REGULATOR_LINEAR_RANGE(900000, 0x00, 0x09, 100000),
-	REGULATOR_LINEAR_RANGE(1800000, 0x0A, 0x0F, 0),
 };
 
 /*
  * LDO7
  * 1.8 to 3.3V (100mV step)
  */
-static const struct regulator_linear_range bd71837_ldo7_voltage_ranges[] = {
+static const struct regulator_linear_range bd71837_ldo7_volts[] = {
 	REGULATOR_LINEAR_RANGE(1800000, 0x00, 0x0F, 100000),
 };
 
-static const struct regulator_desc bd71837_regulators[] = {
+struct reg_init {
+	unsigned int reg;
+	unsigned int mask;
+	unsigned int val;
+};
+struct bd718xx_regulator_data {
+	struct regulator_desc desc;
+	const struct reg_init init;
+	const struct reg_init *additional_inits;
+	int additional_init_amnt;
+};
+
+/*
+ * There is a HW quirk in BD71837. The shutdown sequence timings for
+ * bucks/LDOs which are controlled via register interface are changed.
+ * At PMIC poweroff the voltage for BUCK6/7 is cut immediately at the
+ * beginning of shut-down sequence. As bucks 6 and 7 are parent
+ * supplies for LDO5 and LDO6 - this causes LDO5/6 voltage
+ * monitoring to errorneously detect under voltage and force PMIC to
+ * emergency state instead of poweroff. In order to avoid this we
+ * disable voltage monitoring for LDO5 and LDO6
+ */
+static const struct reg_init bd71837_ldo5_inits[] = {
+	{
+		.reg = BD718XX_REG_MVRFLTMASK2,
+		.mask = BD718XX_LDO5_VRMON80,
+		.val = BD718XX_LDO5_VRMON80,
+	},
+};
+
+static const struct reg_init bd71837_ldo6_inits[] = {
+	{
+		.reg = BD718XX_REG_MVRFLTMASK2,
+		.mask = BD718XX_LDO6_VRMON80,
+		.val = BD718XX_LDO6_VRMON80,
+	},
+};
+
+static const struct bd718xx_regulator_data bd71847_regulators[] = {
+	{
+		.desc = {
+			.name = "buck1",
+			.of_match = of_match_ptr("BUCK1"),
+			.regulators_node = of_match_ptr("regulators"),
+			.id = BD718XX_BUCK1,
+			.ops = &bd718xx_dvs_buck_regulator_ops,
+			.type = REGULATOR_VOLTAGE,
+			.n_voltages = BD718XX_DVS_BUCK_VOLTAGE_NUM,
+			.linear_ranges = bd718xx_dvs_buck_volts,
+			.n_linear_ranges =
+				ARRAY_SIZE(bd718xx_dvs_buck_volts),
+			.vsel_reg = BD718XX_REG_BUCK1_VOLT_RUN,
+			.vsel_mask = DVS_BUCK_RUN_MASK,
+			.enable_reg = BD718XX_REG_BUCK1_CTRL,
+			.enable_mask = BD718XX_BUCK_EN,
+			.owner = THIS_MODULE,
+		},
+		.init = {
+			.reg = BD718XX_REG_BUCK1_CTRL,
+			.mask = BD718XX_BUCK_SEL,
+			.val = BD718XX_BUCK_SEL,
+		},
+	},
 	{
-		.name = "buck1",
-		.of_match = of_match_ptr("BUCK1"),
-		.regulators_node = of_match_ptr("regulators"),
-		.id = BD71837_BUCK1,
-		.ops = &bd71837_buck1234_regulator_ops,
-		.type = REGULATOR_VOLTAGE,
-		.n_voltages = BD71837_BUCK1_VOLTAGE_NUM,
-		.linear_ranges = bd71837_buck1234_voltage_ranges,
-		.n_linear_ranges = ARRAY_SIZE(bd71837_buck1234_voltage_ranges),
-		.vsel_reg = BD71837_REG_BUCK1_VOLT_RUN,
-		.vsel_mask = BUCK1_RUN_MASK,
-		.enable_reg = BD71837_REG_BUCK1_CTRL,
-		.enable_mask = BD71837_BUCK_EN,
-		.owner = THIS_MODULE,
+		.desc = {
+			.name = "buck2",
+			.of_match = of_match_ptr("BUCK2"),
+			.regulators_node = of_match_ptr("regulators"),
+			.id = BD718XX_BUCK2,
+			.ops = &bd718xx_dvs_buck_regulator_ops,
+			.type = REGULATOR_VOLTAGE,
+			.n_voltages = BD718XX_DVS_BUCK_VOLTAGE_NUM,
+			.linear_ranges = bd718xx_dvs_buck_volts,
+			.n_linear_ranges = ARRAY_SIZE(bd718xx_dvs_buck_volts),
+			.vsel_reg = BD718XX_REG_BUCK2_VOLT_RUN,
+			.vsel_mask = DVS_BUCK_RUN_MASK,
+			.enable_reg = BD718XX_REG_BUCK2_CTRL,
+			.enable_mask = BD718XX_BUCK_EN,
+			.owner = THIS_MODULE,
+		},
+		.init = {
+			.reg = BD718XX_REG_BUCK2_CTRL,
+			.mask = BD718XX_BUCK_SEL,
+			.val = BD718XX_BUCK_SEL,
+		},
 	},
 	{
-		.name = "buck2",
-		.of_match = of_match_ptr("BUCK2"),
-		.regulators_node = of_match_ptr("regulators"),
-		.id = BD71837_BUCK2,
-		.ops = &bd71837_buck1234_regulator_ops,
-		.type = REGULATOR_VOLTAGE,
-		.n_voltages = BD71837_BUCK2_VOLTAGE_NUM,
-		.linear_ranges = bd71837_buck1234_voltage_ranges,
-		.n_linear_ranges = ARRAY_SIZE(bd71837_buck1234_voltage_ranges),
-		.vsel_reg = BD71837_REG_BUCK2_VOLT_RUN,
-		.vsel_mask = BUCK2_RUN_MASK,
-		.enable_reg = BD71837_REG_BUCK2_CTRL,
-		.enable_mask = BD71837_BUCK_EN,
-		.owner = THIS_MODULE,
+		.desc = {
+			.name = "buck3",
+			.of_match = of_match_ptr("BUCK3"),
+			.regulators_node = of_match_ptr("regulators"),
+			.id = BD718XX_BUCK3,
+			.ops = &bd718xx_buck_regulator_ops,
+			.type = REGULATOR_VOLTAGE,
+			.n_voltages = BD718XX_1ST_NODVS_BUCK_VOLTAGE_NUM,
+			.linear_ranges = bd718xx_1st_nodvs_buck_volts,
+			.n_linear_ranges =
+				ARRAY_SIZE(bd718xx_1st_nodvs_buck_volts),
+			.vsel_reg = BD718XX_REG_1ST_NODVS_BUCK_VOLT,
+			.vsel_mask = BD718XX_1ST_NODVS_BUCK_MASK,
+			.enable_reg = BD718XX_REG_1ST_NODVS_BUCK_CTRL,
+			.enable_mask = BD718XX_BUCK_EN,
+			.owner = THIS_MODULE,
+		},
+		.init = {
+			.reg = BD718XX_REG_1ST_NODVS_BUCK_CTRL,
+			.mask = BD718XX_BUCK_SEL,
+			.val = BD718XX_BUCK_SEL,
+		},
 	},
 	{
-		.name = "buck3",
-		.of_match = of_match_ptr("BUCK3"),
-		.regulators_node = of_match_ptr("regulators"),
-		.id = BD71837_BUCK3,
-		.ops = &bd71837_buck1234_regulator_ops,
-		.type = REGULATOR_VOLTAGE,
-		.n_voltages = BD71837_BUCK3_VOLTAGE_NUM,
-		.linear_ranges = bd71837_buck1234_voltage_ranges,
-		.n_linear_ranges = ARRAY_SIZE(bd71837_buck1234_voltage_ranges),
-		.vsel_reg = BD71837_REG_BUCK3_VOLT_RUN,
-		.vsel_mask = BUCK3_RUN_MASK,
-		.enable_reg = BD71837_REG_BUCK3_CTRL,
-		.enable_mask = BD71837_BUCK_EN,
-		.owner = THIS_MODULE,
+		.desc = {
+			.name = "buck4",
+			.of_match = of_match_ptr("BUCK4"),
+			.regulators_node = of_match_ptr("regulators"),
+			.id = BD718XX_BUCK4,
+			.ops = &bd718xx_buck_regulator_ops,
+			.type = REGULATOR_VOLTAGE,
+			.n_voltages = BD71847_BUCK4_VOLTAGE_NUM,
+			.linear_ranges = bd71847_buck4_voltage_ranges,
+			.n_linear_ranges =
+				ARRAY_SIZE(bd71847_buck4_voltage_ranges),
+			.enable_reg = BD718XX_REG_2ND_NODVS_BUCK_CTRL,
+			.vsel_reg = BD718XX_REG_2ND_NODVS_BUCK_VOLT,
+			.vsel_mask = BD71847_BUCK4_MASK,
+			.enable_mask = BD718XX_BUCK_EN,
+			.owner = THIS_MODULE,
+		},
+		.init = {
+			.reg = BD718XX_REG_2ND_NODVS_BUCK_CTRL,
+			.mask = BD718XX_BUCK_SEL,
+			.val = BD718XX_BUCK_SEL,
+		},
 	},
 	{
-		.name = "buck4",
-		.of_match = of_match_ptr("BUCK4"),
-		.regulators_node = of_match_ptr("regulators"),
-			.id = BD71837_BUCK4,
-		.ops = &bd71837_buck1234_regulator_ops,
-		.type = REGULATOR_VOLTAGE,
-		.n_voltages = BD71837_BUCK4_VOLTAGE_NUM,
-		.linear_ranges = bd71837_buck1234_voltage_ranges,
-		.n_linear_ranges = ARRAY_SIZE(bd71837_buck1234_voltage_ranges),
-		.vsel_reg = BD71837_REG_BUCK4_VOLT_RUN,
-		.vsel_mask = BUCK4_RUN_MASK,
-		.enable_reg = BD71837_REG_BUCK4_CTRL,
-		.enable_mask = BD71837_BUCK_EN,
-		.owner = THIS_MODULE,
+		.desc = {
+			.name = "buck5",
+			.of_match = of_match_ptr("BUCK5"),
+				.regulators_node = of_match_ptr("regulators"),
+			.id = BD718XX_BUCK5,
+			.ops = &bd718xx_buck_regulator_nolinear_ops,
+			.type = REGULATOR_VOLTAGE,
+			.volt_table = &bd718xx_3rd_nodvs_buck_volts[0],
+			.n_voltages = ARRAY_SIZE(bd718xx_3rd_nodvs_buck_volts),
+			.vsel_reg = BD718XX_REG_3RD_NODVS_BUCK_VOLT,
+			.vsel_mask = BD718XX_3RD_NODVS_BUCK_MASK,
+			.enable_reg = BD718XX_REG_3RD_NODVS_BUCK_CTRL,
+			.enable_mask = BD718XX_BUCK_EN,
+			.owner = THIS_MODULE,
+		},
+		.init = {
+			.reg = BD718XX_REG_3RD_NODVS_BUCK_CTRL,
+			.mask = BD718XX_BUCK_SEL,
+			.val = BD718XX_BUCK_SEL,
+		},
 	},
 	{
-		.name = "buck5",
-		.of_match = of_match_ptr("BUCK5"),
-		.regulators_node = of_match_ptr("regulators"),
-		.id = BD71837_BUCK5,
-		.ops = &bd71837_buck_regulator_ops,
-		.type = REGULATOR_VOLTAGE,
-		.n_voltages = BD71837_BUCK5_VOLTAGE_NUM,
-		.linear_ranges = bd71837_buck5_voltage_ranges,
-		.n_linear_ranges = ARRAY_SIZE(bd71837_buck5_voltage_ranges),
-		.vsel_reg = BD71837_REG_BUCK5_VOLT,
-		.vsel_mask = BUCK5_MASK,
-		.enable_reg = BD71837_REG_BUCK5_CTRL,
-		.enable_mask = BD71837_BUCK_EN,
-		.owner = THIS_MODULE,
+		.desc = {
+			.name = "buck6",
+			.of_match = of_match_ptr("BUCK6"),
+			.regulators_node = of_match_ptr("regulators"),
+			.id = BD718XX_BUCK6,
+			.ops = &bd718xx_buck_regulator_ops,
+			.type = REGULATOR_VOLTAGE,
+			.n_voltages = BD71837_4TH_NODVS_BUCK_VOLTAGE_NUM,
+			.linear_ranges = bd718xx_4th_nodvs_buck_volts,
+			.n_linear_ranges =
+				ARRAY_SIZE(bd718xx_4th_nodvs_buck_volts),
+			.vsel_reg = BD718XX_REG_4TH_NODVS_BUCK_VOLT,
+			.vsel_mask = BD718XX_4TH_NODVS_BUCK_MASK,
+			.enable_reg = BD718XX_REG_4TH_NODVS_BUCK_CTRL,
+			.enable_mask = BD718XX_BUCK_EN,
+			.owner = THIS_MODULE,
+		},
+		.init = {
+			.reg = BD718XX_REG_4TH_NODVS_BUCK_CTRL,
+			.mask = BD718XX_BUCK_SEL,
+			.val = BD718XX_BUCK_SEL,
+		},
 	},
 	{
-		.name = "buck6",
-		.of_match = of_match_ptr("BUCK6"),
-		.regulators_node = of_match_ptr("regulators"),
-		.id = BD71837_BUCK6,
-		.ops = &bd71837_buck_regulator_ops,
-		.type = REGULATOR_VOLTAGE,
-		.n_voltages = BD71837_BUCK6_VOLTAGE_NUM,
-		.linear_ranges = bd71837_buck6_voltage_ranges,
-		.n_linear_ranges = ARRAY_SIZE(bd71837_buck6_voltage_ranges),
-		.vsel_reg = BD71837_REG_BUCK6_VOLT,
-		.vsel_mask = BUCK6_MASK,
-		.enable_reg = BD71837_REG_BUCK6_CTRL,
-		.enable_mask = BD71837_BUCK_EN,
-		.owner = THIS_MODULE,
+		.desc = {
+			.name = "ldo1",
+			.of_match = of_match_ptr("LDO1"),
+			.regulators_node = of_match_ptr("regulators"),
+			.id = BD718XX_LDO1,
+			.ops = &bd718xx_ldo_regulator_ops,
+			.type = REGULATOR_VOLTAGE,
+			.n_voltages = BD718XX_LDO1_VOLTAGE_NUM,
+			.linear_ranges = bd718xx_ldo1_volts,
+			.n_linear_ranges = ARRAY_SIZE(bd718xx_ldo1_volts),
+			.vsel_reg = BD718XX_REG_LDO1_VOLT,
+			.vsel_mask = BD718XX_LDO1_MASK,
+			.enable_reg = BD718XX_REG_LDO1_VOLT,
+			.enable_mask = BD718XX_LDO_EN,
+			.owner = THIS_MODULE,
+		},
+		.init = {
+			.reg = BD718XX_REG_LDO1_VOLT,
+			.mask = BD718XX_LDO_SEL,
+			.val = BD718XX_LDO_SEL,
+		},
 	},
 	{
-		.name = "buck7",
-		.of_match = of_match_ptr("BUCK7"),
-		.regulators_node = of_match_ptr("regulators"),
-		.id = BD71837_BUCK7,
-		.ops = &bd71837_buck_regulator_nolinear_ops,
-		.type = REGULATOR_VOLTAGE,
-		.volt_table = &buck_7_volts[0],
-		.n_voltages = ARRAY_SIZE(buck_7_volts),
-		.vsel_reg = BD71837_REG_BUCK7_VOLT,
-		.vsel_mask = BUCK7_MASK,
-		.enable_reg = BD71837_REG_BUCK7_CTRL,
-		.enable_mask = BD71837_BUCK_EN,
-		.owner = THIS_MODULE,
+		.desc = {
+			.name = "ldo2",
+			.of_match = of_match_ptr("LDO2"),
+			.regulators_node = of_match_ptr("regulators"),
+			.id = BD718XX_LDO2,
+			.ops = &bd718xx_ldo_regulator_nolinear_ops,
+			.type = REGULATOR_VOLTAGE,
+			.volt_table = &ldo_2_volts[0],
+			.vsel_reg = BD718XX_REG_LDO2_VOLT,
+			.vsel_mask = BD718XX_LDO2_MASK,
+			.n_voltages = ARRAY_SIZE(ldo_2_volts),
+			.enable_reg = BD718XX_REG_LDO2_VOLT,
+			.enable_mask = BD718XX_LDO_EN,
+			.owner = THIS_MODULE,
+		},
+		.init = {
+			.reg = BD718XX_REG_LDO2_VOLT,
+			.mask = BD718XX_LDO_SEL,
+			.val = BD718XX_LDO_SEL,
+		},
 	},
 	{
-		.name = "buck8",
-		.of_match = of_match_ptr("BUCK8"),
-		.regulators_node = of_match_ptr("regulators"),
-		.id = BD71837_BUCK8,
-		.ops = &bd71837_buck_regulator_ops,
-		.type = REGULATOR_VOLTAGE,
-		.n_voltages = BD71837_BUCK8_VOLTAGE_NUM,
-		.linear_ranges = bd71837_buck8_voltage_ranges,
-		.n_linear_ranges = ARRAY_SIZE(bd71837_buck8_voltage_ranges),
-		.vsel_reg = BD71837_REG_BUCK8_VOLT,
-		.vsel_mask = BUCK8_MASK,
-		.enable_reg = BD71837_REG_BUCK8_CTRL,
-		.enable_mask = BD71837_BUCK_EN,
-		.owner = THIS_MODULE,
+		.desc = {
+			.name = "ldo3",
+			.of_match = of_match_ptr("LDO3"),
+			.regulators_node = of_match_ptr("regulators"),
+			.id = BD718XX_LDO3,
+			.ops = &bd718xx_ldo_regulator_ops,
+			.type = REGULATOR_VOLTAGE,
+			.n_voltages = BD718XX_LDO3_VOLTAGE_NUM,
+			.linear_ranges = bd718xx_ldo3_volts,
+			.n_linear_ranges = ARRAY_SIZE(bd718xx_ldo3_volts),
+			.vsel_reg = BD718XX_REG_LDO3_VOLT,
+			.vsel_mask = BD718XX_LDO3_MASK,
+			.enable_reg = BD718XX_REG_LDO3_VOLT,
+			.enable_mask = BD718XX_LDO_EN,
+			.owner = THIS_MODULE,
+		},
+		.init = {
+			.reg = BD718XX_REG_LDO3_VOLT,
+			.mask = BD718XX_LDO_SEL,
+			.val = BD718XX_LDO_SEL,
+		},
 	},
 	{
-		.name = "ldo1",
-		.of_match = of_match_ptr("LDO1"),
-		.regulators_node = of_match_ptr("regulators"),
-		.id = BD71837_LDO1,
-		.ops = &bd71837_ldo_regulator_ops,
-		.type = REGULATOR_VOLTAGE,
-		.n_voltages = BD71837_LDO1_VOLTAGE_NUM,
-		.linear_ranges = bd71837_ldo1_voltage_ranges,
-		.n_linear_ranges = ARRAY_SIZE(bd71837_ldo1_voltage_ranges),
-		.vsel_reg = BD71837_REG_LDO1_VOLT,
-		.vsel_mask = LDO1_MASK,
-		.enable_reg = BD71837_REG_LDO1_VOLT,
-		.enable_mask = BD71837_LDO_EN,
-		.owner = THIS_MODULE,
+		.desc = {
+			.name = "ldo4",
+			.of_match = of_match_ptr("LDO4"),
+			.regulators_node = of_match_ptr("regulators"),
+			.id = BD718XX_LDO4,
+			.ops = &bd718xx_ldo_regulator_ops,
+			.type = REGULATOR_VOLTAGE,
+			.n_voltages = BD718XX_LDO4_VOLTAGE_NUM,
+			.linear_ranges = bd718xx_ldo4_volts,
+			.n_linear_ranges = ARRAY_SIZE(bd718xx_ldo4_volts),
+			.vsel_reg = BD718XX_REG_LDO4_VOLT,
+			.vsel_mask = BD718XX_LDO4_MASK,
+			.enable_reg = BD718XX_REG_LDO4_VOLT,
+			.enable_mask = BD718XX_LDO_EN,
+			.owner = THIS_MODULE,
+		},
+		.init = {
+			.reg = BD718XX_REG_LDO4_VOLT,
+			.mask = BD718XX_LDO_SEL,
+			.val = BD718XX_LDO_SEL,
+		},
 	},
 	{
-		.name = "ldo2",
-		.of_match = of_match_ptr("LDO2"),
-		.regulators_node = of_match_ptr("regulators"),
-		.id = BD71837_LDO2,
-		.ops = &bd71837_ldo_regulator_nolinear_ops,
-		.type = REGULATOR_VOLTAGE,
-		.volt_table = &ldo_2_volts[0],
-		.vsel_reg = BD71837_REG_LDO2_VOLT,
-		.vsel_mask = LDO2_MASK,
-		.n_voltages = ARRAY_SIZE(ldo_2_volts),
-		.n_voltages = BD71837_LDO2_VOLTAGE_NUM,
-		.enable_reg = BD71837_REG_LDO2_VOLT,
-		.enable_mask = BD71837_LDO_EN,
-		.owner = THIS_MODULE,
+		.desc = {
+			.name = "ldo5",
+			.of_match = of_match_ptr("LDO5"),
+			.regulators_node = of_match_ptr("regulators"),
+			.id = BD718XX_LDO5,
+			.ops = &bd718xx_ldo_regulator_ops,
+			.type = REGULATOR_VOLTAGE,
+			.n_voltages = BD718XX_LDO5_VOLTAGE_NUM,
+			.linear_ranges = bd718xx_ldo5_volts,
+			.n_linear_ranges = ARRAY_SIZE(bd718xx_ldo5_volts),
+			.vsel_reg = BD718XX_REG_LDO5_VOLT,
+			.vsel_mask = BD71847_LDO5_MASK,
+			.enable_reg = BD718XX_REG_LDO5_VOLT,
+			.enable_mask = BD718XX_LDO_EN,
+			.owner = THIS_MODULE,
+		},
+		.init = {
+			.reg = BD718XX_REG_LDO5_VOLT,
+			.mask = BD718XX_LDO_SEL,
+			.val = BD718XX_LDO_SEL,
+		},
 	},
 	{
-		.name = "ldo3",
-		.of_match = of_match_ptr("LDO3"),
-		.regulators_node = of_match_ptr("regulators"),
-		.id = BD71837_LDO3,
-		.ops = &bd71837_ldo_regulator_ops,
-		.type = REGULATOR_VOLTAGE,
-		.n_voltages = BD71837_LDO3_VOLTAGE_NUM,
-		.linear_ranges = bd71837_ldo3_voltage_ranges,
-		.n_linear_ranges = ARRAY_SIZE(bd71837_ldo3_voltage_ranges),
-		.vsel_reg = BD71837_REG_LDO3_VOLT,
-		.vsel_mask = LDO3_MASK,
-		.enable_reg = BD71837_REG_LDO3_VOLT,
-		.enable_mask = BD71837_LDO_EN,
-		.owner = THIS_MODULE,
+		.desc = {
+			.name = "ldo6",
+			.of_match = of_match_ptr("LDO6"),
+			.regulators_node = of_match_ptr("regulators"),
+			.id = BD718XX_LDO6,
+			.ops = &bd718xx_ldo_regulator_ops,
+			.type = REGULATOR_VOLTAGE,
+			.n_voltages = BD718XX_LDO6_VOLTAGE_NUM,
+			.linear_ranges = bd718xx_ldo6_volts,
+			.n_linear_ranges = ARRAY_SIZE(bd718xx_ldo6_volts),
+			/* LDO6 is supplied by buck5 */
+			.supply_name = "buck5",
+			.vsel_reg = BD718XX_REG_LDO6_VOLT,
+			.vsel_mask = BD718XX_LDO6_MASK,
+			.enable_reg = BD718XX_REG_LDO6_VOLT,
+			.enable_mask = BD718XX_LDO_EN,
+			.owner = THIS_MODULE,
+		},
+		.init = {
+			.reg = BD718XX_REG_LDO6_VOLT,
+			.mask = BD718XX_LDO_SEL,
+			.val = BD718XX_LDO_SEL,
+		},
+	},
+};
+
+static const struct bd718xx_regulator_data bd71837_regulators[] = {
+	{
+		.desc = {
+			.name = "buck1",
+			.of_match = of_match_ptr("BUCK1"),
+			.regulators_node = of_match_ptr("regulators"),
+			.id = BD718XX_BUCK1,
+			.ops = &bd718xx_dvs_buck_regulator_ops,
+			.type = REGULATOR_VOLTAGE,
+			.n_voltages = BD718XX_DVS_BUCK_VOLTAGE_NUM,
+			.linear_ranges = bd718xx_dvs_buck_volts,
+			.n_linear_ranges = ARRAY_SIZE(bd718xx_dvs_buck_volts),
+			.vsel_reg = BD718XX_REG_BUCK1_VOLT_RUN,
+			.vsel_mask = DVS_BUCK_RUN_MASK,
+			.enable_reg = BD718XX_REG_BUCK1_CTRL,
+			.enable_mask = BD718XX_BUCK_EN,
+			.owner = THIS_MODULE,
+		},
+		.init = {
+			.reg = BD718XX_REG_BUCK1_CTRL,
+			.mask = BD718XX_BUCK_SEL,
+			.val = BD718XX_BUCK_SEL,
+		},
+	},
+	{
+		.desc = {
+			.name = "buck2",
+			.of_match = of_match_ptr("BUCK2"),
+			.regulators_node = of_match_ptr("regulators"),
+			.id = BD718XX_BUCK2,
+			.ops = &bd718xx_dvs_buck_regulator_ops,
+			.type = REGULATOR_VOLTAGE,
+			.n_voltages = BD718XX_DVS_BUCK_VOLTAGE_NUM,
+			.linear_ranges = bd718xx_dvs_buck_volts,
+			.n_linear_ranges = ARRAY_SIZE(bd718xx_dvs_buck_volts),
+			.vsel_reg = BD718XX_REG_BUCK2_VOLT_RUN,
+			.vsel_mask = DVS_BUCK_RUN_MASK,
+			.enable_reg = BD718XX_REG_BUCK2_CTRL,
+			.enable_mask = BD718XX_BUCK_EN,
+			.owner = THIS_MODULE,
+		},
+		.init = {
+			.reg = BD718XX_REG_BUCK2_CTRL,
+			.mask = BD718XX_BUCK_SEL,
+			.val = BD718XX_BUCK_SEL,
+		},
+	},
+	{
+		.desc = {
+			.name = "buck3",
+			.of_match = of_match_ptr("BUCK3"),
+			.regulators_node = of_match_ptr("regulators"),
+			.id = BD718XX_BUCK3,
+			.ops = &bd718xx_dvs_buck_regulator_ops,
+			.type = REGULATOR_VOLTAGE,
+			.n_voltages = BD718XX_DVS_BUCK_VOLTAGE_NUM,
+			.linear_ranges = bd718xx_dvs_buck_volts,
+			.n_linear_ranges = ARRAY_SIZE(bd718xx_dvs_buck_volts),
+			.vsel_reg = BD71837_REG_BUCK3_VOLT_RUN,
+			.vsel_mask = DVS_BUCK_RUN_MASK,
+			.enable_reg = BD71837_REG_BUCK3_CTRL,
+			.enable_mask = BD718XX_BUCK_EN,
+			.owner = THIS_MODULE,
+		},
+		.init = {
+			.reg = BD71837_REG_BUCK3_CTRL,
+			.mask = BD718XX_BUCK_SEL,
+			.val = BD718XX_BUCK_SEL,
+		},
+	},
+	{
+		.desc = {
+			.name = "buck4",
+			.of_match = of_match_ptr("BUCK4"),
+			.regulators_node = of_match_ptr("regulators"),
+			.id = BD718XX_BUCK4,
+			.ops = &bd718xx_dvs_buck_regulator_ops,
+			.type = REGULATOR_VOLTAGE,
+			.n_voltages = BD718XX_DVS_BUCK_VOLTAGE_NUM,
+			.linear_ranges = bd718xx_dvs_buck_volts,
+			.n_linear_ranges = ARRAY_SIZE(bd718xx_dvs_buck_volts),
+			.vsel_reg = BD71837_REG_BUCK4_VOLT_RUN,
+			.vsel_mask = DVS_BUCK_RUN_MASK,
+			.enable_reg = BD71837_REG_BUCK4_CTRL,
+			.enable_mask = BD718XX_BUCK_EN,
+			.owner = THIS_MODULE,
+		},
+		.init = {
+			.reg = BD71837_REG_BUCK4_CTRL,
+			.mask = BD718XX_BUCK_SEL,
+			.val = BD718XX_BUCK_SEL,
+		},
 	},
 	{
-		.name = "ldo4",
-		.of_match = of_match_ptr("LDO4"),
-		.regulators_node = of_match_ptr("regulators"),
-		.id = BD71837_LDO4,
-		.ops = &bd71837_ldo_regulator_ops,
-		.type = REGULATOR_VOLTAGE,
-		.n_voltages = BD71837_LDO4_VOLTAGE_NUM,
-		.linear_ranges = bd71837_ldo4_voltage_ranges,
-		.n_linear_ranges = ARRAY_SIZE(bd71837_ldo4_voltage_ranges),
-		.vsel_reg = BD71837_REG_LDO4_VOLT,
-		.vsel_mask = LDO4_MASK,
-		.enable_reg = BD71837_REG_LDO4_VOLT,
-		.enable_mask = BD71837_LDO_EN,
-		.owner = THIS_MODULE,
+		.desc = {
+			.name = "buck5",
+			.of_match = of_match_ptr("BUCK5"),
+			.regulators_node = of_match_ptr("regulators"),
+			.id = BD718XX_BUCK5,
+			.ops = &bd718xx_buck_regulator_ops,
+			.type = REGULATOR_VOLTAGE,
+			.n_voltages = BD718XX_1ST_NODVS_BUCK_VOLTAGE_NUM,
+			.linear_ranges = bd718xx_1st_nodvs_buck_volts,
+			.n_linear_ranges =
+				ARRAY_SIZE(bd718xx_1st_nodvs_buck_volts),
+			.vsel_reg = BD718XX_REG_1ST_NODVS_BUCK_VOLT,
+			.vsel_mask = BD718XX_1ST_NODVS_BUCK_MASK,
+			.enable_reg = BD718XX_REG_1ST_NODVS_BUCK_CTRL,
+			.enable_mask = BD718XX_BUCK_EN,
+			.owner = THIS_MODULE,
+		},
+		.init = {
+			.reg = BD718XX_REG_1ST_NODVS_BUCK_CTRL,
+			.mask = BD718XX_BUCK_SEL,
+			.val = BD718XX_BUCK_SEL,
+		},
 	},
 	{
-		.name = "ldo5",
-		.of_match = of_match_ptr("LDO5"),
-		.regulators_node = of_match_ptr("regulators"),
-		.id = BD71837_LDO5,
-		.ops = &bd71837_ldo_regulator_ops,
-		.type = REGULATOR_VOLTAGE,
-		.n_voltages = BD71837_LDO5_VOLTAGE_NUM,
-		.linear_ranges = bd71837_ldo5_voltage_ranges,
-		.n_linear_ranges = ARRAY_SIZE(bd71837_ldo5_voltage_ranges),
-		/* LDO5 is supplied by buck6 */
-		.supply_name = "buck6",
-		.vsel_reg = BD71837_REG_LDO5_VOLT,
-		.vsel_mask = LDO5_MASK,
-		.enable_reg = BD71837_REG_LDO5_VOLT,
-		.enable_mask = BD71837_LDO_EN,
-		.owner = THIS_MODULE,
+		.desc = {
+			.name = "buck6",
+			.of_match = of_match_ptr("BUCK6"),
+			.regulators_node = of_match_ptr("regulators"),
+			.id = BD718XX_BUCK6,
+			.ops = &bd718xx_buck_regulator_ops,
+			.type = REGULATOR_VOLTAGE,
+			.n_voltages = BD71837_BUCK6_VOLTAGE_NUM,
+			.linear_ranges = bd71837_buck6_voltage_ranges,
+			.n_linear_ranges =
+				ARRAY_SIZE(bd71837_buck6_voltage_ranges),
+			.vsel_reg = BD718XX_REG_2ND_NODVS_BUCK_VOLT,
+			.vsel_mask = BD71837_BUCK6_MASK,
+			.enable_reg = BD718XX_REG_2ND_NODVS_BUCK_CTRL,
+			.enable_mask = BD718XX_BUCK_EN,
+			.owner = THIS_MODULE,
+		},
+		.init = {
+			.reg = BD718XX_REG_2ND_NODVS_BUCK_CTRL,
+			.mask = BD718XX_BUCK_SEL,
+			.val = BD718XX_BUCK_SEL,
+		},
 	},
 	{
-		.name = "ldo6",
-		.of_match = of_match_ptr("LDO6"),
-		.regulators_node = of_match_ptr("regulators"),
-		.id = BD71837_LDO6,
-		.ops = &bd71837_ldo_regulator_ops,
-		.type = REGULATOR_VOLTAGE,
-		.n_voltages = BD71837_LDO6_VOLTAGE_NUM,
-		.linear_ranges = bd71837_ldo6_voltage_ranges,
-		.n_linear_ranges = ARRAY_SIZE(bd71837_ldo6_voltage_ranges),
-		/* LDO6 is supplied by buck7 */
-		.supply_name = "buck7",
-		.vsel_reg = BD71837_REG_LDO6_VOLT,
-		.vsel_mask = LDO6_MASK,
-		.enable_reg = BD71837_REG_LDO6_VOLT,
-		.enable_mask = BD71837_LDO_EN,
-		.owner = THIS_MODULE,
+		.desc = {
+			.name = "buck7",
+			.of_match = of_match_ptr("BUCK7"),
+			.regulators_node = of_match_ptr("regulators"),
+			.id = BD718XX_BUCK7,
+			.ops = &bd718xx_buck_regulator_nolinear_ops,
+			.type = REGULATOR_VOLTAGE,
+			.volt_table = &bd718xx_3rd_nodvs_buck_volts[0],
+			.n_voltages = ARRAY_SIZE(bd718xx_3rd_nodvs_buck_volts),
+			.vsel_reg = BD718XX_REG_3RD_NODVS_BUCK_VOLT,
+			.vsel_mask = BD718XX_3RD_NODVS_BUCK_MASK,
+			.enable_reg = BD718XX_REG_3RD_NODVS_BUCK_CTRL,
+			.enable_mask = BD718XX_BUCK_EN,
+			.owner = THIS_MODULE,
+		},
+		.init = {
+			.reg = BD718XX_REG_3RD_NODVS_BUCK_CTRL,
+			.mask = BD718XX_BUCK_SEL,
+			.val = BD718XX_BUCK_SEL,
+		},
 	},
 	{
-		.name = "ldo7",
-		.of_match = of_match_ptr("LDO7"),
-		.regulators_node = of_match_ptr("regulators"),
-		.id = BD71837_LDO7,
-		.ops = &bd71837_ldo_regulator_ops,
-		.type = REGULATOR_VOLTAGE,
-		.n_voltages = BD71837_LDO7_VOLTAGE_NUM,
-		.linear_ranges = bd71837_ldo7_voltage_ranges,
-		.n_linear_ranges = ARRAY_SIZE(bd71837_ldo7_voltage_ranges),
-		.vsel_reg = BD71837_REG_LDO7_VOLT,
-		.vsel_mask = LDO7_MASK,
-		.enable_reg = BD71837_REG_LDO7_VOLT,
-		.enable_mask = BD71837_LDO_EN,
-		.owner = THIS_MODULE,
+		.desc = {
+			.name = "buck8",
+			.of_match = of_match_ptr("BUCK8"),
+			.regulators_node = of_match_ptr("regulators"),
+			.id = BD718XX_BUCK8,
+			.ops = &bd718xx_buck_regulator_ops,
+			.type = REGULATOR_VOLTAGE,
+			.n_voltages = BD71837_4TH_NODVS_BUCK_VOLTAGE_NUM,
+			.linear_ranges = bd718xx_4th_nodvs_buck_volts,
+			.n_linear_ranges =
+				ARRAY_SIZE(bd718xx_4th_nodvs_buck_volts),
+			.vsel_reg = BD718XX_REG_4TH_NODVS_BUCK_VOLT,
+			.vsel_mask = BD718XX_4TH_NODVS_BUCK_MASK,
+			.enable_reg = BD718XX_REG_4TH_NODVS_BUCK_CTRL,
+			.enable_mask = BD718XX_BUCK_EN,
+			.owner = THIS_MODULE,
+		},
+		.init = {
+			.reg = BD718XX_REG_4TH_NODVS_BUCK_CTRL,
+			.mask = BD718XX_BUCK_SEL,
+			.val = BD718XX_BUCK_SEL,
+		},
+	},
+	{
+		.desc = {
+			.name = "ldo1",
+			.of_match = of_match_ptr("LDO1"),
+			.regulators_node = of_match_ptr("regulators"),
+			.id = BD718XX_LDO1,
+			.ops = &bd718xx_ldo_regulator_ops,
+			.type = REGULATOR_VOLTAGE,
+			.n_voltages = BD718XX_LDO1_VOLTAGE_NUM,
+			.linear_ranges = bd718xx_ldo1_volts,
+			.n_linear_ranges = ARRAY_SIZE(bd718xx_ldo1_volts),
+			.vsel_reg = BD718XX_REG_LDO1_VOLT,
+			.vsel_mask = BD718XX_LDO1_MASK,
+			.enable_reg = BD718XX_REG_LDO1_VOLT,
+			.enable_mask = BD718XX_LDO_EN,
+			.owner = THIS_MODULE,
+		},
+		.init = {
+			.reg = BD718XX_REG_LDO1_VOLT,
+			.mask = BD718XX_LDO_SEL,
+			.val = BD718XX_LDO_SEL,
+		},
+	},
+	{
+		.desc = {
+			.name = "ldo2",
+			.of_match = of_match_ptr("LDO2"),
+			.regulators_node = of_match_ptr("regulators"),
+			.id = BD718XX_LDO2,
+			.ops = &bd718xx_ldo_regulator_nolinear_ops,
+			.type = REGULATOR_VOLTAGE,
+			.volt_table = &ldo_2_volts[0],
+			.vsel_reg = BD718XX_REG_LDO2_VOLT,
+			.vsel_mask = BD718XX_LDO2_MASK,
+			.n_voltages = ARRAY_SIZE(ldo_2_volts),
+			.enable_reg = BD718XX_REG_LDO2_VOLT,
+			.enable_mask = BD718XX_LDO_EN,
+			.owner = THIS_MODULE,
+		},
+		.init = {
+			.reg = BD718XX_REG_LDO2_VOLT,
+			.mask = BD718XX_LDO_SEL,
+			.val = BD718XX_LDO_SEL,
+		},
+	},
+	{
+		.desc = {
+			.name = "ldo3",
+			.of_match = of_match_ptr("LDO3"),
+			.regulators_node = of_match_ptr("regulators"),
+			.id = BD718XX_LDO3,
+			.ops = &bd718xx_ldo_regulator_ops,
+			.type = REGULATOR_VOLTAGE,
+			.n_voltages = BD718XX_LDO3_VOLTAGE_NUM,
+			.linear_ranges = bd718xx_ldo3_volts,
+			.n_linear_ranges = ARRAY_SIZE(bd718xx_ldo3_volts),
+			.vsel_reg = BD718XX_REG_LDO3_VOLT,
+			.vsel_mask = BD718XX_LDO3_MASK,
+			.enable_reg = BD718XX_REG_LDO3_VOLT,
+			.enable_mask = BD718XX_LDO_EN,
+			.owner = THIS_MODULE,
+		},
+		.init = {
+			.reg = BD718XX_REG_LDO3_VOLT,
+			.mask = BD718XX_LDO_SEL,
+			.val = BD718XX_LDO_SEL,
+		},
+	},
+	{
+		.desc = {
+			.name = "ldo4",
+			.of_match = of_match_ptr("LDO4"),
+			.regulators_node = of_match_ptr("regulators"),
+			.id = BD718XX_LDO4,
+			.ops = &bd718xx_ldo_regulator_ops,
+			.type = REGULATOR_VOLTAGE,
+			.n_voltages = BD718XX_LDO4_VOLTAGE_NUM,
+			.linear_ranges = bd718xx_ldo4_volts,
+			.n_linear_ranges = ARRAY_SIZE(bd718xx_ldo4_volts),
+			.vsel_reg = BD718XX_REG_LDO4_VOLT,
+			.vsel_mask = BD718XX_LDO4_MASK,
+			.enable_reg = BD718XX_REG_LDO4_VOLT,
+			.enable_mask = BD718XX_LDO_EN,
+			.owner = THIS_MODULE,
+		},
+		.init = {
+			.reg = BD718XX_REG_LDO4_VOLT,
+			.mask = BD718XX_LDO_SEL,
+			.val = BD718XX_LDO_SEL,
+		},
+	},
+	{
+		.desc = {
+			.name = "ldo5",
+			.of_match = of_match_ptr("LDO5"),
+			.regulators_node = of_match_ptr("regulators"),
+			.id = BD718XX_LDO5,
+			.ops = &bd718xx_ldo_regulator_ops,
+			.type = REGULATOR_VOLTAGE,
+			.n_voltages = BD718XX_LDO5_VOLTAGE_NUM,
+			.linear_ranges = bd718xx_ldo5_volts,
+			.n_linear_ranges = ARRAY_SIZE(bd718xx_ldo5_volts),
+			/* LDO5 is supplied by buck6 */
+			.supply_name = "buck6",
+			.vsel_reg = BD718XX_REG_LDO5_VOLT,
+			.vsel_mask = BD71837_LDO5_MASK,
+			.enable_reg = BD718XX_REG_LDO5_VOLT,
+			.enable_mask = BD718XX_LDO_EN,
+			.owner = THIS_MODULE,
+		},
+		.init = {
+			.reg = BD718XX_REG_LDO5_VOLT,
+			.mask = BD718XX_LDO_SEL,
+			.val = BD718XX_LDO_SEL,
+		},
+		.additional_inits = bd71837_ldo5_inits,
+		.additional_init_amnt = ARRAY_SIZE(bd71837_ldo5_inits),
+	},
+	{
+		.desc = {
+			.name = "ldo6",
+			.of_match = of_match_ptr("LDO6"),
+			.regulators_node = of_match_ptr("regulators"),
+			.id = BD718XX_LDO6,
+			.ops = &bd718xx_ldo_regulator_ops,
+			.type = REGULATOR_VOLTAGE,
+			.n_voltages = BD718XX_LDO6_VOLTAGE_NUM,
+			.linear_ranges = bd718xx_ldo6_volts,
+			.n_linear_ranges = ARRAY_SIZE(bd718xx_ldo6_volts),
+			/* LDO6 is supplied by buck7 */
+			.supply_name = "buck7",
+			.vsel_reg = BD718XX_REG_LDO6_VOLT,
+			.vsel_mask = BD718XX_LDO6_MASK,
+			.enable_reg = BD718XX_REG_LDO6_VOLT,
+			.enable_mask = BD718XX_LDO_EN,
+			.owner = THIS_MODULE,
+		},
+		.init = {
+			.reg = BD718XX_REG_LDO6_VOLT,
+			.mask = BD718XX_LDO_SEL,
+			.val = BD718XX_LDO_SEL,
+		},
+		.additional_inits = bd71837_ldo6_inits,
+		.additional_init_amnt = ARRAY_SIZE(bd71837_ldo6_inits),
+	},
+	{
+		.desc = {
+			.name = "ldo7",
+			.of_match = of_match_ptr("LDO7"),
+			.regulators_node = of_match_ptr("regulators"),
+			.id = BD718XX_LDO7,
+			.ops = &bd718xx_ldo_regulator_ops,
+			.type = REGULATOR_VOLTAGE,
+			.n_voltages = BD71837_LDO7_VOLTAGE_NUM,
+			.linear_ranges = bd71837_ldo7_volts,
+			.n_linear_ranges = ARRAY_SIZE(bd71837_ldo7_volts),
+			.vsel_reg = BD71837_REG_LDO7_VOLT,
+			.vsel_mask = BD71837_LDO7_MASK,
+			.enable_reg = BD71837_REG_LDO7_VOLT,
+			.enable_mask = BD718XX_LDO_EN,
+			.owner = THIS_MODULE,
+		},
+		.init = {
+			.reg = BD71837_REG_LDO7_VOLT,
+			.mask = BD718XX_LDO_SEL,
+			.val = BD718XX_LDO_SEL,
+		},
 	},
 };
 
-struct reg_init {
-	unsigned int reg;
-	unsigned int mask;
+struct bd718xx_pmic_inits {
+	const struct bd718xx_regulator_data (*r_datas)[];
+	unsigned int r_amount;
 };
 
 static int bd71837_probe(struct platform_device *pdev)
 {
-	struct bd71837_pmic *pmic;
+	struct bd718xx_pmic *pmic;
 	struct regulator_config config = { 0 };
-	struct reg_init pmic_regulator_inits[] = {
-		{
-			.reg = BD71837_REG_BUCK1_CTRL,
-			.mask = BD71837_BUCK_SEL,
-		}, {
-			.reg = BD71837_REG_BUCK2_CTRL,
-			.mask = BD71837_BUCK_SEL,
-		}, {
-			.reg = BD71837_REG_BUCK3_CTRL,
-			.mask = BD71837_BUCK_SEL,
-		}, {
-			.reg = BD71837_REG_BUCK4_CTRL,
-			.mask = BD71837_BUCK_SEL,
-		}, {
-			.reg = BD71837_REG_BUCK5_CTRL,
-			.mask = BD71837_BUCK_SEL,
-		}, {
-			.reg = BD71837_REG_BUCK6_CTRL,
-			.mask = BD71837_BUCK_SEL,
-		}, {
-			.reg = BD71837_REG_BUCK7_CTRL,
-			.mask = BD71837_BUCK_SEL,
-		}, {
-			.reg = BD71837_REG_BUCK8_CTRL,
-			.mask = BD71837_BUCK_SEL,
-		}, {
-			.reg = BD71837_REG_LDO1_VOLT,
-			.mask = BD71837_LDO_SEL,
-		}, {
-			.reg = BD71837_REG_LDO2_VOLT,
-			.mask = BD71837_LDO_SEL,
-		}, {
-			.reg = BD71837_REG_LDO3_VOLT,
-			.mask = BD71837_LDO_SEL,
-		}, {
-			.reg = BD71837_REG_LDO4_VOLT,
-			.mask = BD71837_LDO_SEL,
-		}, {
-			.reg = BD71837_REG_LDO5_VOLT,
-			.mask = BD71837_LDO_SEL,
-		}, {
-			.reg = BD71837_REG_LDO6_VOLT,
-			.mask = BD71837_LDO_SEL,
-		}, {
-			.reg = BD71837_REG_LDO7_VOLT,
-			.mask = BD71837_LDO_SEL,
-		}
+	struct bd718xx_pmic_inits pmic_regulators[] = {
+		[BD718XX_TYPE_BD71837] = {
+			.r_datas = &bd71837_regulators,
+			.r_amount = ARRAY_SIZE(bd71837_regulators),
+		},
+		[BD718XX_TYPE_BD71847] = {
+			.r_datas = &bd71847_regulators,
+			.r_amount = ARRAY_SIZE(bd71847_regulators),
+		},
 	};
 
-	int i, err;
+	int i, j, err;
 
 	pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL);
 	if (!pmic)
 		return -ENOMEM;
 
-	memcpy(pmic->descs, bd71837_regulators, sizeof(pmic->descs));
-
 	pmic->pdev = pdev;
 	pmic->mfd = dev_get_drvdata(pdev->dev.parent);
 
@@ -556,44 +952,34 @@ static int bd71837_probe(struct platform_device *pdev)
 		err = -EINVAL;
 		goto err;
 	}
+	if (pmic->mfd->chip_type >= BD718XX_TYPE_AMNT ||
+	    !pmic_regulators[pmic->mfd->chip_type].r_datas) {
+		dev_err(&pdev->dev, "Unsupported chip type\n");
+		err = -EINVAL;
+		goto err;
+	}
+
 	platform_set_drvdata(pdev, pmic);
 
 	/* Register LOCK release */
-	err = regmap_update_bits(pmic->mfd->regmap, BD71837_REG_REGLOCK,
+	err = regmap_update_bits(pmic->mfd->regmap, BD718XX_REG_REGLOCK,
 				 (REGLOCK_PWRSEQ | REGLOCK_VREG), 0);
 	if (err) {
 		dev_err(&pmic->pdev->dev, "Failed to unlock PMIC (%d)\n", err);
 		goto err;
 	} else {
 		dev_dbg(&pmic->pdev->dev, "Unlocked lock register 0x%x\n",
-			BD71837_REG_REGLOCK);
-	}
-
-	/*
-	 * There is a HW quirk in BD71837. The shutdown sequence timings for
-	 * bucks/LDOs which are controlled via register interface are changed.
-	 * At PMIC poweroff the voltage for BUCK6/7 is cut immediately at the
-	 * beginning of shut-down sequence. As bucks 6 and 7 are parent
-	 * supplies for LDO5 and LDO6 - this causes LDO5/6 voltage
-	 * monitoring to errorneously detect under voltage and force PMIC to
-	 * emergency state instead of poweroff. In order to avoid this we
-	 * disable voltage monitoring for LDO5 and LDO6
-	 */
-	err = regmap_update_bits(pmic->mfd->regmap, BD718XX_REG_MVRFLTMASK2,
-				 BD718XX_LDO5_VRMON80 | BD718XX_LDO6_VRMON80,
-				 BD718XX_LDO5_VRMON80 | BD718XX_LDO6_VRMON80);
-	if (err) {
-		dev_err(&pmic->pdev->dev,
-			"Failed to disable voltage monitoring\n");
-		goto err;
+			BD718XX_REG_REGLOCK);
 	}
 
-	for (i = 0; i < ARRAY_SIZE(pmic_regulator_inits); i++) {
+	for (i = 0; i < pmic_regulators[pmic->mfd->chip_type].r_amount; i++) {
 
-		struct regulator_desc *desc;
+		const struct regulator_desc *desc;
 		struct regulator_dev *rdev;
+		const struct bd718xx_regulator_data *r;
 
-		desc = &pmic->descs[i];
+		r = &(*pmic_regulators[pmic->mfd->chip_type].r_datas)[i];
+		desc = &r->desc;
 
 		config.dev = pdev->dev.parent;
 		config.driver_data = pmic;
@@ -613,16 +999,26 @@ static int bd71837_probe(struct platform_device *pdev)
 		 * can now switch the control from PMIC state machine to the
 		 * register interface
 		 */
-		err = regmap_update_bits(pmic->mfd->regmap,
-					 pmic_regulator_inits[i].reg,
-					 pmic_regulator_inits[i].mask,
-					 0xFFFFFFFF);
+		err = regmap_update_bits(pmic->mfd->regmap, r->init.reg,
+					 r->init.mask, r->init.val);
 		if (err) {
 			dev_err(&pmic->pdev->dev,
 				"Failed to write BUCK/LDO SEL bit for (%s)\n",
 				desc->name);
 			goto err;
 		}
+		for (j = 0; j < r->additional_init_amnt; j++) {
+			err = regmap_update_bits(pmic->mfd->regmap,
+						 r->additional_inits[j].reg,
+						 r->additional_inits[j].mask,
+						 r->additional_inits[j].val);
+			if (err) {
+				dev_err(&pmic->pdev->dev,
+					"Buck (%s) initialization failed\n",
+					desc->name);
+				goto err;
+			}
+		}
 
 		pmic->rdev[i] = rdev;
 	}
@@ -633,7 +1029,7 @@ static int bd71837_probe(struct platform_device *pdev)
 
 static struct platform_driver bd71837_regulator = {
 	.driver = {
-		.name = "bd71837-pmic",
+		.name = "bd718xx-pmic",
 	},
 	.probe = bd71837_probe,
 };
diff --git a/include/linux/mfd/rohm-bd718x7.h b/include/linux/mfd/rohm-bd718x7.h
index e8338e5dc10b..d1ed232e669e 100644
--- a/include/linux/mfd/rohm-bd718x7.h
+++ b/include/linux/mfd/rohm-bd718x7.h
@@ -7,106 +7,125 @@
 #include <linux/regmap.h>
 
 enum {
-	BD71837_BUCK1	=	0,
-	BD71837_BUCK2,
-	BD71837_BUCK3,
-	BD71837_BUCK4,
-	BD71837_BUCK5,
-	BD71837_BUCK6,
-	BD71837_BUCK7,
-	BD71837_BUCK8,
-	BD71837_LDO1,
-	BD71837_LDO2,
-	BD71837_LDO3,
-	BD71837_LDO4,
-	BD71837_LDO5,
-	BD71837_LDO6,
-	BD71837_LDO7,
-	BD71837_REGULATOR_CNT,
+	BD718XX_TYPE_BD71837,
+	BD718XX_TYPE_BD71847,
+	BD718XX_TYPE_AMNT // Keep this as last item
 };
 
-#define BD71837_BUCK1_VOLTAGE_NUM	0x40
-#define BD71837_BUCK2_VOLTAGE_NUM	0x40
-#define BD71837_BUCK3_VOLTAGE_NUM	0x40
-#define BD71837_BUCK4_VOLTAGE_NUM	0x40
+enum {
+	BD718XX_BUCK1	=	0,
+	BD718XX_BUCK2,
+	BD718XX_BUCK3,
+	BD718XX_BUCK4,
+	BD718XX_BUCK5,
+	BD718XX_BUCK6,
+	BD718XX_BUCK7,
+	BD718XX_BUCK8,
+	BD718XX_LDO1,
+	BD718XX_LDO2,
+	BD718XX_LDO3,
+	BD718XX_LDO4,
+	BD718XX_LDO5,
+	BD718XX_LDO6,
+	BD718XX_LDO7,
+	BD718XX_REGULATOR_MAX,
+};
+
+/* Common voltage configurations
+ *
+ * Note, we support only one range of voltages for each buck/LDO until we
+ * get pickable ranges support. (See range selection bits for BUCK5 and
+ * LDO1. On BD71847 also the second no DVS buck and LDO5)
+ */
+
+#define BD718XX_DVS_BUCK_VOLTAGE_NUM		0x3D
+#define BD718XX_1ST_NODVS_BUCK_VOLTAGE_NUM	0x08
+#define BD71837_4TH_NODVS_BUCK_VOLTAGE_NUM	0x3D
+
+#define BD718XX_LDO1_VOLTAGE_NUM	0x04
+#define BD718XX_LDO2_VOLTAGE_NUM	0x02
+#define BD718XX_LDO3_VOLTAGE_NUM	0x10
+#define BD718XX_LDO4_VOLTAGE_NUM	0x0A
+#define BD718XX_LDO5_VOLTAGE_NUM	0x10
+#define BD718XX_LDO6_VOLTAGE_NUM	0x0A
 
-#define BD71837_BUCK5_VOLTAGE_NUM	0x08
+/* BD71837 specific voltage configurations */
 #define BD71837_BUCK6_VOLTAGE_NUM	0x04
 #define BD71837_BUCK7_VOLTAGE_NUM	0x08
-#define BD71837_BUCK8_VOLTAGE_NUM	0x40
-
-#define BD71837_LDO1_VOLTAGE_NUM	0x04
-#define BD71837_LDO2_VOLTAGE_NUM	0x02
-#define BD71837_LDO3_VOLTAGE_NUM	0x10
-#define BD71837_LDO4_VOLTAGE_NUM	0x10
-#define BD71837_LDO5_VOLTAGE_NUM	0x10
-#define BD71837_LDO6_VOLTAGE_NUM	0x10
 #define BD71837_LDO7_VOLTAGE_NUM	0x10
 
+/* BD71847 specific voltage configurations */
+#define BD71847_BUCK4_VOLTAGE_NUM	0x04
+
+/* Registers specific to BD71837 */
 enum {
-	BD71837_REG_REV                = 0x00,
-	BD71837_REG_SWRESET            = 0x01,
-	BD71837_REG_I2C_DEV            = 0x02,
-	BD71837_REG_PWRCTRL0           = 0x03,
-	BD71837_REG_PWRCTRL1           = 0x04,
-	BD71837_REG_BUCK1_CTRL         = 0x05,
-	BD71837_REG_BUCK2_CTRL         = 0x06,
-	BD71837_REG_BUCK3_CTRL         = 0x07,
-	BD71837_REG_BUCK4_CTRL         = 0x08,
-	BD71837_REG_BUCK5_CTRL         = 0x09,
-	BD71837_REG_BUCK6_CTRL         = 0x0A,
-	BD71837_REG_BUCK7_CTRL         = 0x0B,
-	BD71837_REG_BUCK8_CTRL         = 0x0C,
-	BD71837_REG_BUCK1_VOLT_RUN     = 0x0D,
-	BD71837_REG_BUCK1_VOLT_IDLE    = 0x0E,
-	BD71837_REG_BUCK1_VOLT_SUSP    = 0x0F,
-	BD71837_REG_BUCK2_VOLT_RUN     = 0x10,
-	BD71837_REG_BUCK2_VOLT_IDLE    = 0x11,
-	BD71837_REG_BUCK3_VOLT_RUN     = 0x12,
-	BD71837_REG_BUCK4_VOLT_RUN     = 0x13,
-	BD71837_REG_BUCK5_VOLT         = 0x14,
-	BD71837_REG_BUCK6_VOLT         = 0x15,
-	BD71837_REG_BUCK7_VOLT         = 0x16,
-	BD71837_REG_BUCK8_VOLT         = 0x17,
-	BD71837_REG_LDO1_VOLT          = 0x18,
-	BD71837_REG_LDO2_VOLT          = 0x19,
-	BD71837_REG_LDO3_VOLT          = 0x1A,
-	BD71837_REG_LDO4_VOLT          = 0x1B,
-	BD71837_REG_LDO5_VOLT          = 0x1C,
-	BD71837_REG_LDO6_VOLT          = 0x1D,
-	BD71837_REG_LDO7_VOLT          = 0x1E,
-	BD71837_REG_TRANS_COND0        = 0x1F,
-	BD71837_REG_TRANS_COND1        = 0x20,
-	BD71837_REG_VRFAULTEN          = 0x21,
-	BD718XX_REG_MVRFLTMASK0        = 0x22,
-	BD718XX_REG_MVRFLTMASK1        = 0x23,
-	BD718XX_REG_MVRFLTMASK2        = 0x24,
-	BD71837_REG_RCVCFG             = 0x25,
-	BD71837_REG_RCVNUM             = 0x26,
-	BD71837_REG_PWRONCONFIG0       = 0x27,
-	BD71837_REG_PWRONCONFIG1       = 0x28,
-	BD71837_REG_RESETSRC           = 0x29,
-	BD71837_REG_MIRQ               = 0x2A,
-	BD71837_REG_IRQ                = 0x2B,
-	BD71837_REG_IN_MON             = 0x2C,
-	BD71837_REG_POW_STATE          = 0x2D,
-	BD71837_REG_OUT32K             = 0x2E,
-	BD71837_REG_REGLOCK            = 0x2F,
-	BD71837_REG_OTPVER             = 0xFF,
-	BD71837_MAX_REGISTER           = 0x100,
+	BD71837_REG_BUCK3_CTRL =	0x07,
+	BD71837_REG_BUCK4_CTRL =	0x08,
+	BD71837_REG_BUCK3_VOLT_RUN =	0x12,
+	BD71837_REG_BUCK4_VOLT_RUN =	0x13,
+	BD71837_REG_LDO7_VOLT =		0x1E,
+};
+
+/* Registers common for BD71837 and BD71847 */
+enum {
+	BD718XX_REG_REV =			0x00,
+	BD718XX_REG_SWRESET =			0x01,
+	BD718XX_REG_I2C_DEV =			0x02,
+	BD718XX_REG_PWRCTRL0 =			0x03,
+	BD718XX_REG_PWRCTRL1 =			0x04,
+	BD718XX_REG_BUCK1_CTRL =		0x05,
+	BD718XX_REG_BUCK2_CTRL =		0x06,
+	BD718XX_REG_1ST_NODVS_BUCK_CTRL =	0x09,
+	BD718XX_REG_2ND_NODVS_BUCK_CTRL =	0x0A,
+	BD718XX_REG_3RD_NODVS_BUCK_CTRL =	0x0B,
+	BD718XX_REG_4TH_NODVS_BUCK_CTRL =	0x0C,
+	BD718XX_REG_BUCK1_VOLT_RUN =		0x0D,
+	BD718XX_REG_BUCK1_VOLT_IDLE =		0x0E,
+	BD718XX_REG_BUCK1_VOLT_SUSP =		0x0F,
+	BD718XX_REG_BUCK2_VOLT_RUN =		0x10,
+	BD718XX_REG_BUCK2_VOLT_IDLE =		0x11,
+	BD718XX_REG_1ST_NODVS_BUCK_VOLT =	0x14,
+	BD718XX_REG_2ND_NODVS_BUCK_VOLT =	0x15,
+	BD718XX_REG_3RD_NODVS_BUCK_VOLT =	0x16,
+	BD718XX_REG_4TH_NODVS_BUCK_VOLT =	0x17,
+	BD718XX_REG_LDO1_VOLT =			0x18,
+	BD718XX_REG_LDO2_VOLT =			0x19,
+	BD718XX_REG_LDO3_VOLT =			0x1A,
+	BD718XX_REG_LDO4_VOLT =			0x1B,
+	BD718XX_REG_LDO5_VOLT =			0x1C,
+	BD718XX_REG_LDO6_VOLT =			0x1D,
+	BD718XX_REG_TRANS_COND0 =		0x1F,
+	BD718XX_REG_TRANS_COND1 =		0x20,
+	BD718XX_REG_VRFAULTEN =			0x21,
+	BD718XX_REG_MVRFLTMASK0 =		0x22,
+	BD718XX_REG_MVRFLTMASK1 =		0x23,
+	BD718XX_REG_MVRFLTMASK2 =		0x24,
+	BD718XX_REG_RCVCFG =			0x25,
+	BD718XX_REG_RCVNUM =			0x26,
+	BD718XX_REG_PWRONCONFIG0 =		0x27,
+	BD718XX_REG_PWRONCONFIG1 =		0x28,
+	BD718XX_REG_RESETSRC =			0x29,
+	BD718XX_REG_MIRQ =			0x2A,
+	BD718XX_REG_IRQ =			0x2B,
+	BD718XX_REG_IN_MON =			0x2C,
+	BD718XX_REG_POW_STATE =			0x2D,
+	BD718XX_REG_OUT32K =			0x2E,
+	BD718XX_REG_REGLOCK =			0x2F,
+	BD718XX_REG_OTPVER =			0xFF,
+	BD718XX_MAX_REGISTER =			0x100,
 };
 
 #define REGLOCK_PWRSEQ	0x1
 #define REGLOCK_VREG	0x10
 
 /* Generic BUCK control masks */
-#define BD71837_BUCK_SEL	0x02
-#define BD71837_BUCK_EN		0x01
-#define BD71837_BUCK_RUN_ON	0x04
+#define BD718XX_BUCK_SEL	0x02
+#define BD718XX_BUCK_EN		0x01
+#define BD718XX_BUCK_RUN_ON	0x04
 
 /* Generic LDO masks */
-#define BD71837_LDO_SEL		0x80
-#define BD71837_LDO_EN		0x40
+#define BD718XX_LDO_SEL		0x80
+#define BD718XX_LDO_EN		0x40
 
 /* BD71837 BUCK ramp rate CTRL reg bits */
 #define BUCK_RAMPRATE_MASK	0xC0
@@ -115,49 +134,27 @@ enum {
 #define BUCK_RAMPRATE_2P50MV	0x2
 #define BUCK_RAMPRATE_1P25MV	0x3
 
-/* BD71837_REG_BUCK1_VOLT_RUN bits */
-#define BUCK1_RUN_MASK		0x3F
-#define BUCK1_RUN_DEFAULT	0x14
-
-/* BD71837_REG_BUCK1_VOLT_SUSP bits */
-#define BUCK1_SUSP_MASK		0x3F
-#define BUCK1_SUSP_DEFAULT	0x14
+#define DVS_BUCK_RUN_MASK	0x3F
+#define DVS_BUCK_SUSP_MASK	0x3F
+#define DVS_BUCK_IDLE_MASK	0x3F
 
-/* BD71837_REG_BUCK1_VOLT_IDLE bits */
-#define BUCK1_IDLE_MASK		0x3F
-#define BUCK1_IDLE_DEFAULT	0x14
+#define BD718XX_1ST_NODVS_BUCK_MASK	0x07
+#define BD71847_BUCK4_MASK		0x03
+#define BD71837_BUCK6_MASK		0x03
+#define BD718XX_3RD_NODVS_BUCK_MASK	0x07
+#define BD718XX_4TH_NODVS_BUCK_MASK	0x3F
 
-/* BD71837_REG_BUCK2_VOLT_RUN bits */
-#define BUCK2_RUN_MASK		0x3F
-#define BUCK2_RUN_DEFAULT	0x1E
+#define BD718XX_LDO1_MASK		0x03
+#define BD718XX_LDO2_MASK		0x20
+#define BD718XX_LDO3_MASK		0x0F
+#define BD718XX_LDO4_MASK		0x0F
+#define BD718XX_LDO6_MASK		0x0F
 
-/* BD71837_REG_BUCK2_VOLT_IDLE bits */
-#define BUCK2_IDLE_MASK		0x3F
-#define BUCK2_IDLE_DEFAULT	0x14
+#define BD71837_LDO5_MASK		0x0F
+#define BD71847_LDO5_MASK		0x0F
 
-/* BD71837_REG_BUCK3_VOLT_RUN bits */
-#define BUCK3_RUN_MASK		0x3F
-#define BUCK3_RUN_DEFAULT	0x1E
+#define BD71837_LDO7_MASK		0x0F
 
-/* BD71837_REG_BUCK4_VOLT_RUN bits */
-#define BUCK4_RUN_MASK		0x3F
-#define BUCK4_RUN_DEFAULT	0x1E
-
-/* BD71837_REG_BUCK5_VOLT bits */
-#define BUCK5_MASK		0x07
-#define BUCK5_DEFAULT		0x02
-
-/* BD71837_REG_BUCK6_VOLT bits */
-#define BUCK6_MASK		0x03
-#define BUCK6_DEFAULT		0x03
-
-/* BD71837_REG_BUCK7_VOLT bits */
-#define BUCK7_MASK		0x07
-#define BUCK7_DEFAULT		0x03
-
-/* BD71837_REG_BUCK8_VOLT bits */
-#define BUCK8_MASK		0x3F
-#define BUCK8_DEFAULT		0x1E
 
 /* BD718XX Voltage monitoring masks */
 #define BD718XX_BUCK1_VRMON80           0x1
@@ -221,27 +218,6 @@ enum {
 #define BD71837_INT_ON_REQ_MASK		0x2
 #define BD71837_INT_STBY_REQ_MASK	0x1
 
-/* BD71837_REG_LDO1_VOLT bits */
-#define LDO1_MASK		0x03
-
-/* BD71837_REG_LDO1_VOLT bits */
-#define LDO2_MASK		0x20
-
-/* BD71837_REG_LDO3_VOLT bits */
-#define LDO3_MASK		0x0F
-
-/* BD71837_REG_LDO4_VOLT bits */
-#define LDO4_MASK		0x0F
-
-/* BD71837_REG_LDO5_VOLT bits */
-#define LDO5_MASK		0x0F
-
-/* BD71837_REG_LDO6_VOLT bits */
-#define LDO6_MASK		0x0F
-
-/* BD71837_REG_LDO7_VOLT bits */
-#define LDO7_MASK		0x0F
-
 /* Register write induced reset settings */
 
 /*
@@ -341,10 +317,12 @@ enum {
 	BD718XX_PWRBTN_LONG_PRESS_15S
 };
 
-struct bd71837_pmic;
-struct bd71837_clk;
+struct bd718xx_pmic;
+struct bd718xx_clk;
 
 struct bd71837 {
+	unsigned int chip_type;
+	unsigned int chip_rev;
 	struct device *dev;
 	struct regmap *regmap;
 	unsigned long int id;
@@ -352,8 +330,8 @@ struct bd71837 {
 	int chip_irq;
 	struct regmap_irq_chip_data *irq_data;
 
-	struct bd71837_pmic *pmic;
-	struct bd71837_clk *clk;
+	struct bd718xx_pmic *pmic;
+	struct bd718xx_clk *clk;
 };
 
 #endif /* __LINUX_MFD_BD71837_H__ */
-- 
2.14.3


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

* [PATCH 3/8] regulator: dt bindings: add BD71847 device-tree binding documentation
  2018-08-29 12:35 [PATCH 0/8] regulator/mfd/dt_bindings: bd718x7: Support ROHM bd71847 Matti Vaittinen
  2018-08-29 12:36 ` [PATCH 1/8] regulator: bd71837: Disable voltage monitoring for LDO3/4 Matti Vaittinen
  2018-08-29 12:36 ` [PATCH 2/8] regulator: Support ROHM BD71847 power management IC Matti Vaittinen
@ 2018-08-29 12:37 ` Matti Vaittinen
  2018-08-29 12:37 ` [PATCH 4/8] mfd: " Matti Vaittinen
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 22+ messages in thread
From: Matti Vaittinen @ 2018-08-29 12:37 UTC (permalink / raw)
  To: lee.jones, robh+dt, mark.rutland, lgirdwood, broonie,
	mazziesaccount, matti.vaittinen, devicetree, linux-kernel
  Cc: heikki.haikola, mikko.mutanen

Add ROHM BD71847 Power Management IC regulator binding information to
device-tree binding documents.

Signed-off-by: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
---
 .../devicetree/bindings/regulator/rohm,bd71837-regulator.txt | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/regulator/rohm,bd71837-regulator.txt b/Documentation/devicetree/bindings/regulator/rohm,bd71837-regulator.txt
index 76ead07072b1..4b98ca26e61a 100644
--- a/Documentation/devicetree/bindings/regulator/rohm,bd71837-regulator.txt
+++ b/Documentation/devicetree/bindings/regulator/rohm,bd71837-regulator.txt
@@ -1,7 +1,9 @@
-ROHM BD71837 Power Management Integrated Circuit (PMIC) regulator bindings
+ROHM BD71837 and BD71847 Power Management Integrated Circuit regulator bindings
 
 Required properties:
- - regulator-name: should be "buck1", ..., "buck8" and "ldo1", ..., "ldo7"
+ - regulator-name: should be "buck1", ..., "buck8" and "ldo1", ..., "ldo7" for
+                   BD71837. For BD71847 names should be "buck1", ..., "buck6"
+		   and "ldo1", ..., "ldo6"
 
 List of regulators provided by this controller. BD71837 regulators node
 should be sub node of the BD71837 MFD node. See BD71837 MFD bindings at
@@ -16,10 +18,14 @@ disabled by driver at startup. LDO5 and LDO6 are supplied by those and
 if they are disabled at startup the voltage monitoring for LDO5/LDO6 will
 cause PMIC to reset.
 
-The valid names for regulator nodes are:
+The valid names for BD71837 regulator nodes are:
 BUCK1, BUCK2, BUCK3, BUCK4, BUCK5, BUCK6, BUCK7, BUCK8
 LDO1, LDO2, LDO3, LDO4, LDO5, LDO6, LDO7
 
+The valid names for BD71847 regulator nodes are:
+BUCK1, BUCK2, BUCK3, BUCK4, BUCK5, BUCK6
+LDO1, LDO2, LDO3, LDO4, LDO5, LDO6
+
 Optional properties:
 - Any optional property defined in bindings/regulator/regulator.txt
 
-- 
2.14.3


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

* [PATCH 4/8] mfd: dt bindings: add BD71847 device-tree binding documentation
  2018-08-29 12:35 [PATCH 0/8] regulator/mfd/dt_bindings: bd718x7: Support ROHM bd71847 Matti Vaittinen
                   ` (2 preceding siblings ...)
  2018-08-29 12:37 ` [PATCH 3/8] regulator: dt bindings: add BD71847 device-tree binding documentation Matti Vaittinen
@ 2018-08-29 12:37 ` Matti Vaittinen
  2018-09-11 13:49   ` Lee Jones
  2018-08-29 12:38 ` [PATCH 5/8] regulator: Support regulators where voltage ranges are selectable Matti Vaittinen
                   ` (3 subsequent siblings)
  7 siblings, 1 reply; 22+ messages in thread
From: Matti Vaittinen @ 2018-08-29 12:37 UTC (permalink / raw)
  To: lee.jones, robh+dt, mark.rutland, lgirdwood, broonie,
	mazziesaccount, matti.vaittinen, devicetree, linux-kernel,
	heikki.haikola, mikko.mutanen

Add ROHM BD71847 Power Management IC MFD binding information to
device-tree binding documents.

Signed-off-by: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
---
 .../devicetree/bindings/mfd/rohm,bd71837-pmic.txt       | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/Documentation/devicetree/bindings/mfd/rohm,bd71837-pmic.txt b/Documentation/devicetree/bindings/mfd/rohm,bd71837-pmic.txt
index 3ca56fdb5ffe..d78172878faa 100644
--- a/Documentation/devicetree/bindings/mfd/rohm,bd71837-pmic.txt
+++ b/Documentation/devicetree/bindings/mfd/rohm,bd71837-pmic.txt
@@ -1,16 +1,17 @@
-* ROHM BD71837 Power Management Integrated Circuit bindings
+* ROHM BD71837 and BD71847 Power Management Integrated Circuit bindings
 
-BD71837MWV is a programmable Power Management IC for powering single-core,
-dual-core, and quad-core SoCs such as NXP-i.MX 8M. It is optimized for
-low BOM cost and compact solution footprint. It integrates 8 Buck
-egulators and 7 LDOs to provide all the power rails required by the SoC and
-the commonly used peripherals.
+BD71837MWV and BD71847MWV are programmable Power Management ICs for powering
+single-core, dual-core, and quad-core SoCs such as NXP-i.MX 8M. They are
+optimized for low BOM cost and compact solution footprint. BD71837MWV
+integrates 8 Buck regulators and 7 LDOs. BD71847MWV contains 6 Buck regulators
+and 6 LDOs.
 
-Datasheet for PMIC is available at:
+Datasheet for BD71837 is available at:
 https://www.rohm.com/datasheet/BD71837MWV/bd71837mwv-e
 
 Required properties:
- - compatible		: Should be "rohm,bd71837".
+ - compatible		: Should be "rohm,bd71837" for bd71837 and
+			  "rohm,bd71847" for bd71847.
  - reg			: I2C slave address.
  - interrupt-parent	: Phandle to the parent interrupt controller.
  - interrupts		: The interrupt line the device is connected to.
-- 
2.14.3


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

* [PATCH 5/8] regulator: Support regulators where voltage ranges are selectable
  2018-08-29 12:35 [PATCH 0/8] regulator/mfd/dt_bindings: bd718x7: Support ROHM bd71847 Matti Vaittinen
                   ` (3 preceding siblings ...)
  2018-08-29 12:37 ` [PATCH 4/8] mfd: " Matti Vaittinen
@ 2018-08-29 12:38 ` Matti Vaittinen
  2018-08-29 12:38 ` [PATCH 6/8] regulator/mfd: bd718xx: rename bd71837/bd71847 common instances Matti Vaittinen
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 22+ messages in thread
From: Matti Vaittinen @ 2018-08-29 12:38 UTC (permalink / raw)
  To: lee.jones, robh+dt, mark.rutland, lgirdwood, broonie,
	mazziesaccount, matti.vaittinen, devicetree, linux-kernel,
	heikki.haikola, mikko.mutanen

For example ROHM BD71837 and ROHM BD71847 Power management ICs have
regulators which provide multiple linear ranges. Ranges can be
selected by individual non contagious bit in vsel register. Add
regmap helper functions for selecting ranges.

Signed-off-by: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
---
 drivers/regulator/core.c         |   5 +
 drivers/regulator/helpers.c      | 232 +++++++++++++++++++++++++++++++++++++++
 include/linux/regulator/driver.h |  20 +++-
 3 files changed, 256 insertions(+), 1 deletion(-)

diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index bb1324f93143..be19163048f4 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -2783,6 +2783,11 @@ static int regulator_map_voltage(struct regulator_dev *rdev, int min_uV,
 	if (desc->ops->list_voltage == regulator_list_voltage_linear_range)
 		return regulator_map_voltage_linear_range(rdev, min_uV, max_uV);
 
+	if (desc->ops->list_voltage ==
+		regulator_list_voltage_pickable_linear_range)
+		return regulator_map_voltage_pickable_linear_range(rdev,
+							min_uV, max_uV);
+
 	return regulator_map_voltage_iterate(rdev, min_uV, max_uV);
 }
 
diff --git a/drivers/regulator/helpers.c b/drivers/regulator/helpers.c
index 2ae7c3ac5940..d2b9fc359318 100644
--- a/drivers/regulator/helpers.c
+++ b/drivers/regulator/helpers.c
@@ -103,6 +103,128 @@ int regulator_disable_regmap(struct regulator_dev *rdev)
 }
 EXPORT_SYMBOL_GPL(regulator_disable_regmap);
 
+static int regulator_range_selector_to_index(struct regulator_dev *rdev,
+					     unsigned int rval)
+{
+	int i;
+
+	if (!rdev->desc->linear_range_selectors)
+		return -EINVAL;
+
+	rval &= rdev->desc->vsel_range_mask;
+
+	for (i = 0; i < rdev->desc->n_linear_ranges; i++) {
+		if (rdev->desc->linear_range_selectors[i] == rval)
+			return i;
+	}
+	return -EINVAL;
+}
+
+/**
+ * regulator_get_voltage_sel_pickable_regmap - pickable range get_voltage_sel
+ *
+ * @rdev: regulator to operate on
+ *
+ * Regulators that use regmap for their register I/O and use pickable
+ * ranges can set the vsel_reg, vsel_mask, vsel_range_reg and vsel_range_mask
+ * fields in their descriptor and then use this as their get_voltage_vsel
+ * operation, saving some code.
+ */
+int regulator_get_voltage_sel_pickable_regmap(struct regulator_dev *rdev)
+{
+	unsigned int r_val;
+	int range;
+	unsigned int val;
+	int ret, i;
+	unsigned int voltages_in_range = 0;
+
+	if (!rdev->desc->linear_ranges)
+		return -EINVAL;
+
+	ret = regmap_read(rdev->regmap, rdev->desc->vsel_reg, &val);
+	if (ret != 0)
+		return ret;
+
+	ret = regmap_read(rdev->regmap, rdev->desc->vsel_range_reg, &r_val);
+	if (ret != 0)
+		return ret;
+
+	val &= rdev->desc->vsel_mask;
+	val >>= ffs(rdev->desc->vsel_mask) - 1;
+
+	range = regulator_range_selector_to_index(rdev, r_val);
+	if (range < 0)
+		return -EINVAL;
+
+	for (i = 0; i < range; i++)
+		voltages_in_range += (rdev->desc->linear_ranges[i].max_sel -
+				     rdev->desc->linear_ranges[i].min_sel) + 1;
+
+	return val + voltages_in_range;
+}
+EXPORT_SYMBOL_GPL(regulator_get_voltage_sel_pickable_regmap);
+
+/**
+ * regulator_set_voltage_sel_pickable_regmap - pickable range set_voltage_sel
+ *
+ * @rdev: regulator to operate on
+ * @sel: Selector to set
+ *
+ * Regulators that use regmap for their register I/O and use pickable
+ * ranges can set the vsel_reg, vsel_mask, vsel_range_reg and vsel_range_mask
+ * fields in their descriptor and then use this as their set_voltage_vsel
+ * operation, saving some code.
+ */
+int regulator_set_voltage_sel_pickable_regmap(struct regulator_dev *rdev,
+					      unsigned int sel)
+{
+	unsigned int range;
+	int ret, i;
+	unsigned int voltages_in_range = 0;
+
+	for (i = 0; i < rdev->desc->n_linear_ranges; i++) {
+		voltages_in_range = (rdev->desc->linear_ranges[i].max_sel -
+				     rdev->desc->linear_ranges[i].min_sel) + 1;
+		if (sel < voltages_in_range)
+			break;
+		sel -= voltages_in_range;
+	}
+
+	if (i == rdev->desc->n_linear_ranges)
+		return -EINVAL;
+
+	sel <<= ffs(rdev->desc->vsel_mask) - 1;
+	sel += rdev->desc->linear_ranges[i].min_sel;
+
+	range = rdev->desc->linear_range_selectors[i];
+
+	if (rdev->desc->vsel_reg == rdev->desc->vsel_range_reg) {
+		ret = regmap_update_bits(rdev->regmap,
+					 rdev->desc->vsel_reg,
+					 rdev->desc->vsel_range_mask |
+					 rdev->desc->vsel_mask, sel | range);
+	} else {
+		ret = regmap_update_bits(rdev->regmap,
+					 rdev->desc->vsel_range_reg,
+					 rdev->desc->vsel_range_mask, range);
+		if (ret)
+			return ret;
+
+		ret = regmap_update_bits(rdev->regmap, rdev->desc->vsel_reg,
+				  rdev->desc->vsel_mask, sel);
+	}
+
+	if (ret)
+		return ret;
+
+	if (rdev->desc->apply_bit)
+		ret = regmap_update_bits(rdev->regmap, rdev->desc->apply_reg,
+					 rdev->desc->apply_bit,
+					 rdev->desc->apply_bit);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(regulator_set_voltage_sel_pickable_regmap);
+
 /**
  * regulator_get_voltage_sel_regmap - standard get_voltage_sel for regmap users
  *
@@ -336,6 +458,76 @@ int regulator_map_voltage_linear_range(struct regulator_dev *rdev,
 }
 EXPORT_SYMBOL_GPL(regulator_map_voltage_linear_range);
 
+/**
+ * regulator_map_voltage_pickable_linear_range - map_voltage, pickable ranges
+ *
+ * @rdev: Regulator to operate on
+ * @min_uV: Lower bound for voltage
+ * @max_uV: Upper bound for voltage
+ *
+ * Drivers providing pickable linear_ranges in their descriptor can use
+ * this as their map_voltage() callback.
+ */
+int regulator_map_voltage_pickable_linear_range(struct regulator_dev *rdev,
+						int min_uV, int max_uV)
+{
+	const struct regulator_linear_range *range;
+	int ret = -EINVAL;
+	int voltage, i;
+	unsigned int selector = 0;
+
+	if (!rdev->desc->n_linear_ranges) {
+		BUG_ON(!rdev->desc->n_linear_ranges);
+		return -EINVAL;
+	}
+
+	for (i = 0; i < rdev->desc->n_linear_ranges; i++) {
+		int linear_max_uV;
+
+		range = &rdev->desc->linear_ranges[i];
+		linear_max_uV = range->min_uV +
+			(range->max_sel - range->min_sel) * range->uV_step;
+
+		if (!(min_uV <= linear_max_uV && max_uV >= range->min_uV)) {
+			selector += (range->max_sel - range->min_sel + 1);
+			continue;
+		}
+
+		if (min_uV <= range->min_uV)
+			min_uV = range->min_uV;
+
+		/* range->uV_step == 0 means fixed voltage range */
+		if (range->uV_step == 0) {
+			ret = 0;
+		} else {
+			ret = DIV_ROUND_UP(min_uV - range->min_uV,
+					   range->uV_step);
+			if (ret < 0)
+				return ret;
+		}
+
+		ret += selector;
+
+		voltage = rdev->desc->ops->list_voltage(rdev, ret);
+
+		/*
+		 * Map back into a voltage to verify we're still in bounds.
+		 * We may have overlapping voltage ranges. Hence we don't
+		 * exit but retry until we have checked all ranges.
+		 */
+		if (voltage < min_uV || voltage > max_uV)
+			selector += (range->max_sel - range->min_sel + 1);
+		else
+			break;
+	}
+
+	if (i == rdev->desc->n_linear_ranges)
+		return -EINVAL;
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(regulator_map_voltage_pickable_linear_range);
+
 /**
  * regulator_list_voltage_linear - List voltages with simple calculation
  *
@@ -360,6 +552,46 @@ int regulator_list_voltage_linear(struct regulator_dev *rdev,
 }
 EXPORT_SYMBOL_GPL(regulator_list_voltage_linear);
 
+/**
+ * regulator_list_voltage_pickable_linear_range - pickable range list voltages
+ *
+ * @rdev: Regulator device
+ * @selector: Selector to convert into a voltage
+ *
+ * list_voltage() operation, intended to be used by drivers utilizing pickable
+ * ranges helpers.
+ */
+int regulator_list_voltage_pickable_linear_range(struct regulator_dev *rdev,
+						 unsigned int selector)
+{
+	const struct regulator_linear_range *range;
+	int i;
+	unsigned int all_sels = 0;
+
+	if (!rdev->desc->n_linear_ranges) {
+		BUG_ON(!rdev->desc->n_linear_ranges);
+		return -EINVAL;
+	}
+
+	for (i = 0; i < rdev->desc->n_linear_ranges; i++) {
+		unsigned int sels_in_range;
+
+		range = &rdev->desc->linear_ranges[i];
+
+		sels_in_range = range->max_sel - range->min_sel;
+
+		if (all_sels + sels_in_range >= selector) {
+			selector -= all_sels;
+			return range->min_uV + (range->uV_step * selector);
+		}
+
+		all_sels += (sels_in_range + 1);
+	}
+
+	return -EINVAL;
+}
+EXPORT_SYMBOL_GPL(regulator_list_voltage_pickable_linear_range);
+
 /**
  * regulator_list_voltage_linear_range - List voltages for linear ranges
  *
diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h
index 0fd8fbb74763..a9c030192147 100644
--- a/include/linux/regulator/driver.h
+++ b/include/linux/regulator/driver.h
@@ -271,9 +271,16 @@ enum regulator_type {
  * @ramp_delay: Time to settle down after voltage change (unit: uV/us)
  * @min_dropout_uV: The minimum dropout voltage this regulator can handle
  * @linear_ranges: A constant table of possible voltage ranges.
- * @n_linear_ranges: Number of entries in the @linear_ranges table.
+ * @linear_range_selectors: A constant table of voltage range selectors.
+ *			    If pickable ranges are used each range must
+ *			    have corresponding selector here.
+ * @n_linear_ranges: Number of entries in the @linear_ranges (and in
+ *		     linear_range_selectors if used) table(s).
  * @volt_table: Voltage mapping table (if table based mapping)
  *
+ * @vsel_range_reg: Register for range selector when using pickable ranges
+ *		    and regulator_regmap_X_voltage_X_pickable functions.
+ * @vsel_range_mask: Mask for register bitfield used for range selector
  * @vsel_reg: Register for selector when using regulator_regmap_X_voltage_
  * @vsel_mask: Mask for register bitfield used for selector
  * @csel_reg: Register for TPS65218 LS3 current regulator
@@ -338,10 +345,14 @@ struct regulator_desc {
 	int min_dropout_uV;
 
 	const struct regulator_linear_range *linear_ranges;
+	const unsigned int *linear_range_selectors;
+
 	int n_linear_ranges;
 
 	const unsigned int *volt_table;
 
+	unsigned int vsel_range_reg;
+	unsigned int vsel_range_mask;
 	unsigned int vsel_reg;
 	unsigned int vsel_mask;
 	unsigned int csel_reg;
@@ -498,18 +509,25 @@ int regulator_mode_to_status(unsigned int);
 
 int regulator_list_voltage_linear(struct regulator_dev *rdev,
 				  unsigned int selector);
+int regulator_list_voltage_pickable_linear_range(struct regulator_dev *rdev,
+						   unsigned int selector);
 int regulator_list_voltage_linear_range(struct regulator_dev *rdev,
 					unsigned int selector);
 int regulator_list_voltage_table(struct regulator_dev *rdev,
 				  unsigned int selector);
 int regulator_map_voltage_linear(struct regulator_dev *rdev,
 				  int min_uV, int max_uV);
+int regulator_map_voltage_pickable_linear_range(struct regulator_dev *rdev,
+						  int min_uV, int max_uV);
 int regulator_map_voltage_linear_range(struct regulator_dev *rdev,
 				       int min_uV, int max_uV);
 int regulator_map_voltage_iterate(struct regulator_dev *rdev,
 				  int min_uV, int max_uV);
 int regulator_map_voltage_ascend(struct regulator_dev *rdev,
 				  int min_uV, int max_uV);
+int regulator_get_voltage_sel_pickable_regmap(struct regulator_dev *rdev);
+int regulator_set_voltage_sel_pickable_regmap(struct regulator_dev *rdev,
+						unsigned int sel);
 int regulator_get_voltage_sel_regmap(struct regulator_dev *rdev);
 int regulator_set_voltage_sel_regmap(struct regulator_dev *rdev, unsigned sel);
 int regulator_is_enabled_regmap(struct regulator_dev *rdev);
-- 
2.14.3


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

* [PATCH 6/8] regulator/mfd: bd718xx: rename bd71837/bd71847 common instances
  2018-08-29 12:35 [PATCH 0/8] regulator/mfd/dt_bindings: bd718x7: Support ROHM bd71847 Matti Vaittinen
                   ` (4 preceding siblings ...)
  2018-08-29 12:38 ` [PATCH 5/8] regulator: Support regulators where voltage ranges are selectable Matti Vaittinen
@ 2018-08-29 12:38 ` Matti Vaittinen
  2018-09-11 13:51   ` Lee Jones
  2018-08-29 12:39 ` [PATCH 7/8] regulator: bd718XX use pickable ranges Matti Vaittinen
  2018-08-29 12:39 ` [PATCH 8/8] regulator: bd718xx: renme bd71837 to 718xx Matti Vaittinen
  7 siblings, 1 reply; 22+ messages in thread
From: Matti Vaittinen @ 2018-08-29 12:38 UTC (permalink / raw)
  To: lee.jones, robh+dt, mark.rutland, lgirdwood, broonie,
	mazziesaccount, matti.vaittinen, devicetree, linux-kernel,
	heikki.haikola, mikko.mutanen

Rename parts of code that support both BD71837 and BD71847 to BD718XX.

Signed-off-by: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
---
 drivers/mfd/rohm-bd718x7.c            | 112 +++++++++++++++++-----------------
 drivers/regulator/bd71837-regulator.c |  24 ++++----
 include/linux/mfd/rohm-bd718x7.h      |  62 +++++++++----------
 3 files changed, 99 insertions(+), 99 deletions(-)

diff --git a/drivers/mfd/rohm-bd718x7.c b/drivers/mfd/rohm-bd718x7.c
index c95f34269bb6..1d0ba2309f57 100644
--- a/drivers/mfd/rohm-bd718x7.c
+++ b/drivers/mfd/rohm-bd718x7.c
@@ -2,9 +2,9 @@
 //
 // Copyright (C) 2018 ROHM Semiconductors
 //
-// ROHM BD71837MWV PMIC driver
+// ROHM BD71837MWV and BD71847MWV PMIC driver
 //
-// Datasheet available from
+// Datasheet for BD71837MWV available from
 // https://www.rohm.com/datasheet/BD71837MWV/bd71837mwv-e
 
 #include <linux/gpio_keys.h>
@@ -48,7 +48,7 @@ static struct gpio_keys_platform_data bd718xx_powerkey_data = {
 	.name = "bd718xx-pwrkey",
 };
 
-static struct mfd_cell bd71837_mfd_cells[] = {
+static struct mfd_cell bd718xx_mfd_cells[] = {
 	{
 		.name = "gpio-keys",
 		.platform_data = &bd718xx_powerkey_data,
@@ -58,20 +58,20 @@ static struct mfd_cell bd71837_mfd_cells[] = {
 	{ .name = "bd718xx-pmic", },
 };
 
-static const struct regmap_irq bd71837_irqs[] = {
-	REGMAP_IRQ_REG(BD71837_INT_SWRST, 0, BD71837_INT_SWRST_MASK),
-	REGMAP_IRQ_REG(BD71837_INT_PWRBTN_S, 0, BD71837_INT_PWRBTN_S_MASK),
-	REGMAP_IRQ_REG(BD71837_INT_PWRBTN_L, 0, BD71837_INT_PWRBTN_L_MASK),
-	REGMAP_IRQ_REG(BD71837_INT_PWRBTN, 0, BD71837_INT_PWRBTN_MASK),
-	REGMAP_IRQ_REG(BD71837_INT_WDOG, 0, BD71837_INT_WDOG_MASK),
-	REGMAP_IRQ_REG(BD71837_INT_ON_REQ, 0, BD71837_INT_ON_REQ_MASK),
-	REGMAP_IRQ_REG(BD71837_INT_STBY_REQ, 0, BD71837_INT_STBY_REQ_MASK),
+static const struct regmap_irq bd718xx_irqs[] = {
+	REGMAP_IRQ_REG(BD718XX_INT_SWRST, 0, BD718XX_INT_SWRST_MASK),
+	REGMAP_IRQ_REG(BD718XX_INT_PWRBTN_S, 0, BD718XX_INT_PWRBTN_S_MASK),
+	REGMAP_IRQ_REG(BD718XX_INT_PWRBTN_L, 0, BD718XX_INT_PWRBTN_L_MASK),
+	REGMAP_IRQ_REG(BD718XX_INT_PWRBTN, 0, BD718XX_INT_PWRBTN_MASK),
+	REGMAP_IRQ_REG(BD718XX_INT_WDOG, 0, BD718XX_INT_WDOG_MASK),
+	REGMAP_IRQ_REG(BD718XX_INT_ON_REQ, 0, BD718XX_INT_ON_REQ_MASK),
+	REGMAP_IRQ_REG(BD718XX_INT_STBY_REQ, 0, BD718XX_INT_STBY_REQ_MASK),
 };
 
-static struct regmap_irq_chip bd71837_irq_chip = {
-	.name = "bd71837-irq",
-	.irqs = bd71837_irqs,
-	.num_irqs = ARRAY_SIZE(bd71837_irqs),
+static struct regmap_irq_chip bd718xx_irq_chip = {
+	.name = "bd718xx-irq",
+	.irqs = bd718xx_irqs,
+	.num_irqs = ARRAY_SIZE(bd718xx_irqs),
 	.num_regs = 1,
 	.irq_reg_stride = 1,
 	.status_base = BD718XX_REG_IRQ,
@@ -91,7 +91,7 @@ static const struct regmap_access_table volatile_regs = {
 	.n_yes_ranges = 1,
 };
 
-static const struct regmap_config bd71837_regmap_config = {
+static const struct regmap_config bd718xx_regmap_config = {
 	.reg_bits = 8,
 	.val_bits = 8,
 	.volatile_table = &volatile_regs,
@@ -99,16 +99,16 @@ static const struct regmap_config bd71837_regmap_config = {
 	.cache_type = REGCACHE_RBTREE,
 };
 
-static int bd71837_i2c_probe(struct i2c_client *i2c,
+static int bd718xx_i2c_probe(struct i2c_client *i2c,
 			    const struct i2c_device_id *id)
 {
-	struct bd71837 *bd71837;
+	struct bd718xx *bd718xx;
 	int ret, i;
 	const unsigned int *type;
 
-	bd71837 = devm_kzalloc(&i2c->dev, sizeof(struct bd71837), GFP_KERNEL);
+	bd718xx = devm_kzalloc(&i2c->dev, sizeof(struct bd718xx), GFP_KERNEL);
 
-	if (!bd71837)
+	if (!bd718xx)
 		return -ENOMEM;
 
 	type = of_device_get_match_data(&i2c->dev);
@@ -117,50 +117,50 @@ static int bd71837_i2c_probe(struct i2c_client *i2c,
 		return -ENODEV;
 	}
 
-	bd71837->chip_irq = i2c->irq;
+	bd718xx->chip_irq = i2c->irq;
 
-	if (!bd71837->chip_irq) {
+	if (!bd718xx->chip_irq) {
 		dev_err(&i2c->dev, "No IRQ configured\n");
 		return -EINVAL;
 	}
 
-	bd71837->chip_type = *type;
-	bd71837->dev = &i2c->dev;
-	dev_set_drvdata(&i2c->dev, bd71837);
+	bd718xx->chip_type = *type;
+	bd718xx->dev = &i2c->dev;
+	dev_set_drvdata(&i2c->dev, bd718xx);
 
-	bd71837->regmap = devm_regmap_init_i2c(i2c, &bd71837_regmap_config);
-	if (IS_ERR(bd71837->regmap)) {
+	bd718xx->regmap = devm_regmap_init_i2c(i2c, &bd718xx_regmap_config);
+	if (IS_ERR(bd718xx->regmap)) {
 		dev_err(&i2c->dev, "regmap initialization failed\n");
-		return PTR_ERR(bd71837->regmap);
+		return PTR_ERR(bd718xx->regmap);
 	}
 
-	ret = regmap_read(bd71837->regmap, BD718XX_REG_REV, &bd71837->chip_rev);
+	ret = regmap_read(bd718xx->regmap, BD718XX_REG_REV, &bd718xx->chip_rev);
 	if (ret) {
 		dev_err(&i2c->dev, "Failed to read revision register\n");
 		return ret;
 	}
 	for (i = 0;
-	     i < supported_revisions[bd71837->chip_type].known_revisions; i++)
-		if ((*supported_revisions[bd71837->chip_type].revisions)[i] ==
-		    bd71837->chip_rev)
+	     i < supported_revisions[bd718xx->chip_type].known_revisions; i++)
+		if ((*supported_revisions[bd718xx->chip_type].revisions)[i] ==
+		    bd718xx->chip_rev)
 			break;
 
-	if (i == supported_revisions[bd71837->chip_type].known_revisions) {
+	if (i == supported_revisions[bd718xx->chip_type].known_revisions) {
 		dev_err(&i2c->dev, "Unrecognized revision 0x%02x\n",
-			bd71837->chip_rev);
+			bd718xx->chip_rev);
 		return -EINVAL;
 	}
 
-	ret = devm_regmap_add_irq_chip(&i2c->dev, bd71837->regmap,
-				       bd71837->chip_irq, IRQF_ONESHOT, 0,
-				       &bd71837_irq_chip, &bd71837->irq_data);
+	ret = devm_regmap_add_irq_chip(&i2c->dev, bd718xx->regmap,
+				       bd718xx->chip_irq, IRQF_ONESHOT, 0,
+				       &bd718xx_irq_chip, &bd718xx->irq_data);
 	if (ret) {
 		dev_err(&i2c->dev, "Failed to add irq_chip\n");
 		return ret;
 	}
 
 	/* Configure short press to 10 milliseconds */
-	ret = regmap_update_bits(bd71837->regmap,
+	ret = regmap_update_bits(bd718xx->regmap,
 				 BD718XX_REG_PWRONCONFIG0,
 				 BD718XX_PWRBTN_PRESS_DURATION_MASK,
 				 BD718XX_PWRBTN_SHORT_PRESS_10MS);
@@ -171,7 +171,7 @@ static int bd71837_i2c_probe(struct i2c_client *i2c,
 	}
 
 	/* Configure long press to 10 seconds */
-	ret = regmap_update_bits(bd71837->regmap,
+	ret = regmap_update_bits(bd718xx->regmap,
 				 BD718XX_REG_PWRONCONFIG1,
 				 BD718XX_PWRBTN_PRESS_DURATION_MASK,
 				 BD718XX_PWRBTN_LONG_PRESS_10S);
@@ -182,7 +182,7 @@ static int bd71837_i2c_probe(struct i2c_client *i2c,
 		return ret;
 	}
 
-	ret = regmap_irq_get_virq(bd71837->irq_data, BD71837_INT_PWRBTN_S);
+	ret = regmap_irq_get_virq(bd718xx->irq_data, BD718XX_INT_PWRBTN_S);
 
 	if (ret < 0) {
 		dev_err(&i2c->dev, "Failed to get the IRQ\n");
@@ -191,10 +191,10 @@ static int bd71837_i2c_probe(struct i2c_client *i2c,
 
 	button.irq = ret;
 
-	ret = devm_mfd_add_devices(bd71837->dev, PLATFORM_DEVID_AUTO,
-				   bd71837_mfd_cells,
-				   ARRAY_SIZE(bd71837_mfd_cells), NULL, 0,
-				   regmap_irq_get_domain(bd71837->irq_data));
+	ret = devm_mfd_add_devices(bd718xx->dev, PLATFORM_DEVID_AUTO,
+				   bd718xx_mfd_cells,
+				   ARRAY_SIZE(bd718xx_mfd_cells), NULL, 0,
+				   regmap_irq_get_domain(bd718xx->irq_data));
 	if (ret)
 		dev_err(&i2c->dev, "Failed to create subdevices\n");
 
@@ -205,7 +205,7 @@ static const unsigned int chip_types[] = {
 	[BD718XX_TYPE_BD71847] = BD718XX_TYPE_BD71847,
 };
 
-static const struct of_device_id bd71837_of_match[] = {
+static const struct of_device_id bd718xx_of_match[] = {
 	{
 		.compatible = "rohm,bd71837",
 		.data = &chip_types[BD718XX_TYPE_BD71837]
@@ -216,30 +216,30 @@ static const struct of_device_id bd71837_of_match[] = {
 	},
 	{ }
 };
-MODULE_DEVICE_TABLE(of, bd71837_of_match);
+MODULE_DEVICE_TABLE(of, bd718xx_of_match);
 
-static struct i2c_driver bd71837_i2c_driver = {
+static struct i2c_driver bd718xx_i2c_driver = {
 	.driver = {
 		.name = "rohm-bd718x7",
-		.of_match_table = bd71837_of_match,
+		.of_match_table = bd718xx_of_match,
 	},
-	.probe = bd71837_i2c_probe,
+	.probe = bd718xx_i2c_probe,
 };
 
-static int __init bd71837_i2c_init(void)
+static int __init bd718xx_i2c_init(void)
 {
-	return i2c_add_driver(&bd71837_i2c_driver);
+	return i2c_add_driver(&bd718xx_i2c_driver);
 }
 
 /* Initialise early so consumer devices can complete system boot */
-subsys_initcall(bd71837_i2c_init);
+subsys_initcall(bd718xx_i2c_init);
 
-static void __exit bd71837_i2c_exit(void)
+static void __exit bd718xx_i2c_exit(void)
 {
-	i2c_del_driver(&bd71837_i2c_driver);
+	i2c_del_driver(&bd718xx_i2c_driver);
 }
-module_exit(bd71837_i2c_exit);
+module_exit(bd718xx_i2c_exit);
 
 MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>");
-MODULE_DESCRIPTION("ROHM BD71837 Power Management IC driver");
+MODULE_DESCRIPTION("ROHM BD71837/BD71847 Power Management IC driver");
 MODULE_LICENSE("GPL");
diff --git a/drivers/regulator/bd71837-regulator.c b/drivers/regulator/bd71837-regulator.c
index 49f75258aa20..4780c92db49a 100644
--- a/drivers/regulator/bd71837-regulator.c
+++ b/drivers/regulator/bd71837-regulator.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 // Copyright (C) 2018 ROHM Semiconductors
-// bd71837-regulator.c ROHM BD71837MWV regulator driver
+// bd71837-regulator.c ROHM BD71837MWV/BD71847MWV regulator driver
 
 #include <linux/delay.h>
 #include <linux/err.h>
@@ -17,7 +17,7 @@
 
 struct bd718xx_pmic {
 	struct bd718xx_regulator_data *rdata;
-	struct bd71837 *mfd;
+	struct bd718xx *mfd;
 	struct platform_device *pdev;
 	struct regulator_dev *rdev[BD718XX_REGULATOR_MAX];
 };
@@ -30,11 +30,11 @@ struct bd718xx_pmic {
  * 10: 2.50mV/usec	10mV 4uS
  * 11: 1.25mV/usec	10mV 8uS
  */
-static int bd71837_buck1234_set_ramp_delay(struct regulator_dev *rdev,
+static int bd718xx_buck1234_set_ramp_delay(struct regulator_dev *rdev,
 					   int ramp_delay)
 {
 	struct bd718xx_pmic *pmic = rdev_get_drvdata(rdev);
-	struct bd71837 *mfd = pmic->mfd;
+	struct bd718xx *mfd = pmic->mfd;
 	int id = rdev->desc->id;
 	unsigned int ramp_value = BUCK_RAMPRATE_10P00MV;
 
@@ -124,7 +124,7 @@ static struct regulator_ops bd718xx_dvs_buck_regulator_ops = {
 	.set_voltage_sel = regulator_set_voltage_sel_regmap,
 	.get_voltage_sel = regulator_get_voltage_sel_regmap,
 	.set_voltage_time_sel = regulator_set_voltage_time_sel,
-	.set_ramp_delay = bd71837_buck1234_set_ramp_delay,
+	.set_ramp_delay = bd718xx_buck1234_set_ramp_delay,
 };
 
 /*
@@ -404,7 +404,7 @@ static const struct bd718xx_regulator_data bd71847_regulators[] = {
 			.id = BD718XX_BUCK6,
 			.ops = &bd718xx_buck_regulator_ops,
 			.type = REGULATOR_VOLTAGE,
-			.n_voltages = BD71837_4TH_NODVS_BUCK_VOLTAGE_NUM,
+			.n_voltages = BD718XX_4TH_NODVS_BUCK_VOLTAGE_NUM,
 			.linear_ranges = bd718xx_4th_nodvs_buck_volts,
 			.n_linear_ranges =
 				ARRAY_SIZE(bd718xx_4th_nodvs_buck_volts),
@@ -732,7 +732,7 @@ static const struct bd718xx_regulator_data bd71837_regulators[] = {
 			.id = BD718XX_BUCK8,
 			.ops = &bd718xx_buck_regulator_ops,
 			.type = REGULATOR_VOLTAGE,
-			.n_voltages = BD71837_4TH_NODVS_BUCK_VOLTAGE_NUM,
+			.n_voltages = BD718XX_4TH_NODVS_BUCK_VOLTAGE_NUM,
 			.linear_ranges = bd718xx_4th_nodvs_buck_volts,
 			.n_linear_ranges =
 				ARRAY_SIZE(bd718xx_4th_nodvs_buck_volts),
@@ -923,7 +923,7 @@ struct bd718xx_pmic_inits {
 	unsigned int r_amount;
 };
 
-static int bd71837_probe(struct platform_device *pdev)
+static int bd718xx_probe(struct platform_device *pdev)
 {
 	struct bd718xx_pmic *pmic;
 	struct regulator_config config = { 0 };
@@ -1027,15 +1027,15 @@ static int bd71837_probe(struct platform_device *pdev)
 	return err;
 }
 
-static struct platform_driver bd71837_regulator = {
+static struct platform_driver bd718xx_regulator = {
 	.driver = {
 		.name = "bd718xx-pmic",
 	},
-	.probe = bd71837_probe,
+	.probe = bd718xx_probe,
 };
 
-module_platform_driver(bd71837_regulator);
+module_platform_driver(bd718xx_regulator);
 
 MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>");
-MODULE_DESCRIPTION("BD71837 voltage regulator driver");
+MODULE_DESCRIPTION("BD71837/BD71847 voltage regulator driver");
 MODULE_LICENSE("GPL");
diff --git a/include/linux/mfd/rohm-bd718x7.h b/include/linux/mfd/rohm-bd718x7.h
index d1ed232e669e..d1730b97ba52 100644
--- a/include/linux/mfd/rohm-bd718x7.h
+++ b/include/linux/mfd/rohm-bd718x7.h
@@ -1,8 +1,8 @@
 /* SPDX-License-Identifier: GPL-2.0-or-later */
 /* Copyright (C) 2018 ROHM Semiconductors */
 
-#ifndef __LINUX_MFD_BD71837_H__
-#define __LINUX_MFD_BD71837_H__
+#ifndef __LINUX_MFD_BD718XX_H__
+#define __LINUX_MFD_BD718XX_H__
 
 #include <linux/regmap.h>
 
@@ -183,7 +183,7 @@ enum {
 #define BD71837_BUCK4_VRMON130          0x80
 #define BD71837_LDO7_VRMON80            0x40
 
-/* BD71837_REG_IRQ bits */
+/* BD718XX_REG_IRQ bits */
 #define IRQ_SWRST		0x40
 #define IRQ_PWRON_S		0x20
 #define IRQ_PWRON_L		0x10
@@ -192,31 +192,31 @@ enum {
 #define IRQ_ON_REQ		0x02
 #define IRQ_STBY_REQ		0x01
 
-/* BD71837_REG_OUT32K bits */
-#define BD71837_OUT32K_EN	0x01
+/* BD718XX_REG_OUT32K bits */
+#define BD718XX_OUT32K_EN	0x01
 
-/* BD71837 gated clock rate */
-#define BD71837_CLK_RATE 32768
+/* BD7183XX gated clock rate */
+#define BD718XX_CLK_RATE 32768
 
-/* ROHM BD71837 irqs */
+/* ROHM BD718XX irqs */
 enum {
-	BD71837_INT_STBY_REQ,
-	BD71837_INT_ON_REQ,
-	BD71837_INT_WDOG,
-	BD71837_INT_PWRBTN,
-	BD71837_INT_PWRBTN_L,
-	BD71837_INT_PWRBTN_S,
-	BD71837_INT_SWRST
+	BD718XX_INT_STBY_REQ,
+	BD718XX_INT_ON_REQ,
+	BD718XX_INT_WDOG,
+	BD718XX_INT_PWRBTN,
+	BD718XX_INT_PWRBTN_L,
+	BD718XX_INT_PWRBTN_S,
+	BD718XX_INT_SWRST
 };
 
-/* ROHM BD71837 interrupt masks */
-#define BD71837_INT_SWRST_MASK		0x40
-#define BD71837_INT_PWRBTN_S_MASK	0x20
-#define BD71837_INT_PWRBTN_L_MASK	0x10
-#define BD71837_INT_PWRBTN_MASK		0x8
-#define BD71837_INT_WDOG_MASK		0x4
-#define BD71837_INT_ON_REQ_MASK		0x2
-#define BD71837_INT_STBY_REQ_MASK	0x1
+/* ROHM BD718XX interrupt masks */
+#define BD718XX_INT_SWRST_MASK		0x40
+#define BD718XX_INT_PWRBTN_S_MASK	0x20
+#define BD718XX_INT_PWRBTN_L_MASK	0x10
+#define BD718XX_INT_PWRBTN_MASK		0x8
+#define BD718XX_INT_WDOG_MASK		0x4
+#define BD718XX_INT_ON_REQ_MASK		0x2
+#define BD718XX_INT_STBY_REQ_MASK	0x1
 
 /* Register write induced reset settings */
 
@@ -226,13 +226,13 @@ enum {
  * write 1 to it we will trigger the action. So always write 0 to it when
  * changning SWRESET action - no matter what we read from it.
  */
-#define BD71837_SWRESET_TYPE_MASK	7
-#define BD71837_SWRESET_TYPE_DISABLED	0
-#define BD71837_SWRESET_TYPE_COLD	4
-#define BD71837_SWRESET_TYPE_WARM	6
+#define BD718XX_SWRESET_TYPE_MASK	7
+#define BD718XX_SWRESET_TYPE_DISABLED	0
+#define BD718XX_SWRESET_TYPE_COLD	4
+#define BD718XX_SWRESET_TYPE_WARM	6
 
-#define BD71837_SWRESET_RESET_MASK	1
-#define BD71837_SWRESET_RESET		1
+#define BD718XX_SWRESET_RESET_MASK	1
+#define BD718XX_SWRESET_RESET		1
 
 /* Poweroff state transition conditions */
 
@@ -320,7 +320,7 @@ enum {
 struct bd718xx_pmic;
 struct bd718xx_clk;
 
-struct bd71837 {
+struct bd718xx {
 	unsigned int chip_type;
 	unsigned int chip_rev;
 	struct device *dev;
@@ -334,4 +334,4 @@ struct bd71837 {
 	struct bd718xx_clk *clk;
 };
 
-#endif /* __LINUX_MFD_BD71837_H__ */
+#endif /* __LINUX_MFD_BD718XX_H__ */
-- 
2.14.3


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

* [PATCH 7/8] regulator: bd718XX use pickable ranges
  2018-08-29 12:35 [PATCH 0/8] regulator/mfd/dt_bindings: bd718x7: Support ROHM bd71847 Matti Vaittinen
                   ` (5 preceding siblings ...)
  2018-08-29 12:38 ` [PATCH 6/8] regulator/mfd: bd718xx: rename bd71837/bd71847 common instances Matti Vaittinen
@ 2018-08-29 12:39 ` Matti Vaittinen
  2018-09-11 13:55   ` Lee Jones
  2018-08-29 12:39 ` [PATCH 8/8] regulator: bd718xx: renme bd71837 to 718xx Matti Vaittinen
  7 siblings, 1 reply; 22+ messages in thread
From: Matti Vaittinen @ 2018-08-29 12:39 UTC (permalink / raw)
  To: lee.jones, robh+dt, mark.rutland, lgirdwood, broonie,
	mazziesaccount, matti.vaittinen, devicetree, linux-kernel,
	heikki.haikola, mikko.mutanen

Few regulators in BD71837 and BD71847 can output voltages from
different voltage ranges. Register interface is arranged so that
used range is selected by toggling bits which are not next to actual
voltage selection bits. Then the voltage inside selected range is
determined by voltage selection bits (as usual). Support BD71837
and BD71847 selectible range voltages using new pickable ranges
helpers.

Signed-off-by: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
---
 drivers/regulator/bd71837-regulator.c | 155 +++++++++++++++++++++++++++-------
 include/linux/mfd/rohm-bd718x7.h      |  38 +++++----
 2 files changed, 147 insertions(+), 46 deletions(-)

diff --git a/drivers/regulator/bd71837-regulator.c b/drivers/regulator/bd71837-regulator.c
index 4780c92db49a..04bcbd636c2f 100644
--- a/drivers/regulator/bd71837-regulator.c
+++ b/drivers/regulator/bd71837-regulator.c
@@ -78,6 +78,34 @@ static int bd718xx_set_voltage_sel_restricted(struct regulator_dev *rdev,
 	return regulator_set_voltage_sel_regmap(rdev, sel);
 }
 
+static int bd718xx_set_voltage_sel_pickable_restricted(
+		struct regulator_dev *rdev, unsigned int sel)
+{
+	if (regulator_is_enabled_regmap(rdev))
+		return -EBUSY;
+
+	return regulator_set_voltage_sel_pickable_regmap(rdev, sel);
+}
+
+static struct regulator_ops bd718xx_pickable_range_ldo_ops = {
+	.enable = regulator_enable_regmap,
+	.disable = regulator_disable_regmap,
+	.is_enabled = regulator_is_enabled_regmap,
+	.list_voltage = regulator_list_voltage_pickable_linear_range,
+	.set_voltage_sel = bd718xx_set_voltage_sel_pickable_restricted,
+	.get_voltage_sel = regulator_get_voltage_sel_pickable_regmap,
+};
+
+static struct regulator_ops bd718xx_pickable_range_buck_ops = {
+	.enable = regulator_enable_regmap,
+	.disable = regulator_disable_regmap,
+	.is_enabled = regulator_is_enabled_regmap,
+	.list_voltage = regulator_list_voltage_pickable_linear_range,
+	.set_voltage_sel = bd718xx_set_voltage_sel_pickable_restricted,
+	.get_voltage_sel = regulator_get_voltage_sel_pickable_regmap,
+	.set_voltage_time_sel = regulator_set_voltage_time_sel,
+};
+
 static struct regulator_ops bd718xx_ldo_regulator_ops = {
 	.enable = regulator_enable_regmap,
 	.disable = regulator_disable_regmap,
@@ -139,24 +167,61 @@ static const struct regulator_linear_range bd718xx_dvs_buck_volts[] = {
 
 /*
  * BD71837 BUCK5
+ * 0.7V to 1.35V  (range 0)
+ * and
+ * 0.675 to 1.325 (range 1)
+ */
+static const struct regulator_linear_range bd71837_buck5_volts[] = {
+	/* Ranges when VOLT_SEL bit is 0 */
+	REGULATOR_LINEAR_RANGE(700000, 0x00, 0x03, 100000),
+	REGULATOR_LINEAR_RANGE(1050000, 0x04, 0x05, 50000),
+	REGULATOR_LINEAR_RANGE(1200000, 0x06, 0x07, 150000),
+	/* Ranges when VOLT_SEL bit is 1  */
+	REGULATOR_LINEAR_RANGE(675000, 0x0, 0x3, 100000),
+	REGULATOR_LINEAR_RANGE(1025000, 0x4, 0x5, 50000),
+	REGULATOR_LINEAR_RANGE(1175000, 0x6, 0x7, 150000),
+};
+
+/*
+ * Range selector for first 3 linear ranges is 0x0
+ * and 0x1 for last 3 ranges.
+ */
+static const unsigned int bd71837_buck5_volt_range_sel[] = {
+	0x0, 0x0, 0x0, 0x80, 0x80, 0x80
+};
+
+/*
  * BD71847 BUCK3
- * 0.7V to 1.35V ()
  */
-static const struct regulator_linear_range bd718xx_1st_nodvs_buck_volts[] = {
+static const struct regulator_linear_range bd71847_buck3_volts[] = {
+	/* Ranges when VOLT_SEL bits are 00 */
 	REGULATOR_LINEAR_RANGE(700000, 0x00, 0x03, 100000),
 	REGULATOR_LINEAR_RANGE(1050000, 0x04, 0x05, 50000),
 	REGULATOR_LINEAR_RANGE(1200000, 0x06, 0x07, 150000),
+	/* Ranges when VOLT_SEL bits are 01 */
+	REGULATOR_LINEAR_RANGE(550000, 0x0, 0x7, 50000),
+	/* Ranges when VOLT_SEL bits are 11 */
+	REGULATOR_LINEAR_RANGE(675000, 0x0, 0x3, 100000),
+	REGULATOR_LINEAR_RANGE(1025000, 0x4, 0x5, 50000),
+	REGULATOR_LINEAR_RANGE(1175000, 0x6, 0x7, 150000),
+};
+
+static const unsigned int bd71847_buck3_volt_range_sel[] = {
+	0x0, 0x0, 0x0, 0x40, 0x80, 0x80, 0x80
 };
 
-static const struct regulator_linear_range bd71847_buck4_voltage_ranges[] = {
+static const struct regulator_linear_range bd71847_buck4_volts[] = {
 	REGULATOR_LINEAR_RANGE(3000000, 0x00, 0x03, 100000),
+	REGULATOR_LINEAR_RANGE(2600000, 0x00, 0x03, 100000),
 };
 
+static const unsigned int bd71847_buck4_volt_range_sel[] = { 0x0, 0x40 };
+
 /*
  * BUCK6
  * 3.0V to 3.3V (step 100mV)
  */
-static const struct regulator_linear_range bd71837_buck6_voltage_ranges[] = {
+static const struct regulator_linear_range bd71837_buck6_volts[] = {
 	REGULATOR_LINEAR_RANGE(3000000, 0x00, 0x03, 100000),
 };
 
@@ -190,8 +255,11 @@ static const struct regulator_linear_range bd718xx_4th_nodvs_buck_volts[] = {
  */
 static const struct regulator_linear_range bd718xx_ldo1_volts[] = {
 	REGULATOR_LINEAR_RANGE(3000000, 0x00, 0x03, 100000),
+	REGULATOR_LINEAR_RANGE(1600000, 0x00, 0x03, 100000),
 };
 
+static const unsigned int bd718xx_ldo1_volt_range_sel[] = { 0x0, 0x20 };
+
 /*
  * LDO2
  * 0.8 or 0.9V
@@ -220,10 +288,21 @@ static const struct regulator_linear_range bd718xx_ldo4_volts[] = {
  * LDO5 for BD71837
  * 1.8 to 3.3V (100mV step)
  */
-static const struct regulator_linear_range bd718xx_ldo5_volts[] = {
+static const struct regulator_linear_range bd71837_ldo5_volts[] = {
+	REGULATOR_LINEAR_RANGE(1800000, 0x00, 0x0F, 100000),
+};
+
+/*
+ * LDO5 for BD71837
+ * 1.8 to 3.3V (100mV step)
+ */
+static const struct regulator_linear_range bd71847_ldo5_volts[] = {
 	REGULATOR_LINEAR_RANGE(1800000, 0x00, 0x0F, 100000),
+	REGULATOR_LINEAR_RANGE(800000, 0x00, 0x0F, 100000),
 };
 
+static const unsigned int bd71847_ldo5_volt_range_sel[] = { 0x0, 0x20 };
+
 /*
  * LDO6
  * 0.9 to 1.8V (100mV step)
@@ -332,14 +411,17 @@ static const struct bd718xx_regulator_data bd71847_regulators[] = {
 			.of_match = of_match_ptr("BUCK3"),
 			.regulators_node = of_match_ptr("regulators"),
 			.id = BD718XX_BUCK3,
-			.ops = &bd718xx_buck_regulator_ops,
+			.ops = &bd718xx_pickable_range_buck_ops,
 			.type = REGULATOR_VOLTAGE,
-			.n_voltages = BD718XX_1ST_NODVS_BUCK_VOLTAGE_NUM,
-			.linear_ranges = bd718xx_1st_nodvs_buck_volts,
+			.n_voltages = BD71847_BUCK3_VOLTAGE_NUM,
+			.linear_ranges = bd71847_buck3_volts,
 			.n_linear_ranges =
-				ARRAY_SIZE(bd718xx_1st_nodvs_buck_volts),
+				ARRAY_SIZE(bd71847_buck3_volts),
 			.vsel_reg = BD718XX_REG_1ST_NODVS_BUCK_VOLT,
 			.vsel_mask = BD718XX_1ST_NODVS_BUCK_MASK,
+			.vsel_range_reg = BD718XX_REG_1ST_NODVS_BUCK_VOLT,
+			.vsel_range_mask = BD71847_BUCK3_RANGE_MASK,
+			.linear_range_selectors = bd71847_buck3_volt_range_sel,
 			.enable_reg = BD718XX_REG_1ST_NODVS_BUCK_CTRL,
 			.enable_mask = BD718XX_BUCK_EN,
 			.owner = THIS_MODULE,
@@ -356,15 +438,18 @@ static const struct bd718xx_regulator_data bd71847_regulators[] = {
 			.of_match = of_match_ptr("BUCK4"),
 			.regulators_node = of_match_ptr("regulators"),
 			.id = BD718XX_BUCK4,
-			.ops = &bd718xx_buck_regulator_ops,
+			.ops = &bd718xx_pickable_range_buck_ops,
 			.type = REGULATOR_VOLTAGE,
 			.n_voltages = BD71847_BUCK4_VOLTAGE_NUM,
-			.linear_ranges = bd71847_buck4_voltage_ranges,
+			.linear_ranges = bd71847_buck4_volts,
 			.n_linear_ranges =
-				ARRAY_SIZE(bd71847_buck4_voltage_ranges),
+				ARRAY_SIZE(bd71847_buck4_volts),
 			.enable_reg = BD718XX_REG_2ND_NODVS_BUCK_CTRL,
 			.vsel_reg = BD718XX_REG_2ND_NODVS_BUCK_VOLT,
 			.vsel_mask = BD71847_BUCK4_MASK,
+			.vsel_range_reg = BD718XX_REG_2ND_NODVS_BUCK_VOLT,
+			.vsel_range_mask = BD71847_BUCK4_RANGE_MASK,
+			.linear_range_selectors = bd71847_buck4_volt_range_sel,
 			.enable_mask = BD718XX_BUCK_EN,
 			.owner = THIS_MODULE,
 		},
@@ -378,7 +463,7 @@ static const struct bd718xx_regulator_data bd71847_regulators[] = {
 		.desc = {
 			.name = "buck5",
 			.of_match = of_match_ptr("BUCK5"),
-				.regulators_node = of_match_ptr("regulators"),
+			.regulators_node = of_match_ptr("regulators"),
 			.id = BD718XX_BUCK5,
 			.ops = &bd718xx_buck_regulator_nolinear_ops,
 			.type = REGULATOR_VOLTAGE,
@@ -426,13 +511,16 @@ static const struct bd718xx_regulator_data bd71847_regulators[] = {
 			.of_match = of_match_ptr("LDO1"),
 			.regulators_node = of_match_ptr("regulators"),
 			.id = BD718XX_LDO1,
-			.ops = &bd718xx_ldo_regulator_ops,
+			.ops = &bd718xx_pickable_range_ldo_ops,
 			.type = REGULATOR_VOLTAGE,
 			.n_voltages = BD718XX_LDO1_VOLTAGE_NUM,
 			.linear_ranges = bd718xx_ldo1_volts,
 			.n_linear_ranges = ARRAY_SIZE(bd718xx_ldo1_volts),
 			.vsel_reg = BD718XX_REG_LDO1_VOLT,
 			.vsel_mask = BD718XX_LDO1_MASK,
+			.vsel_range_reg = BD718XX_REG_LDO1_VOLT,
+			.vsel_range_mask = BD718XX_LDO1_RANGE_MASK,
+			.linear_range_selectors = bd718xx_ldo1_volt_range_sel,
 			.enable_reg = BD718XX_REG_LDO1_VOLT,
 			.enable_mask = BD718XX_LDO_EN,
 			.owner = THIS_MODULE,
@@ -517,13 +605,16 @@ static const struct bd718xx_regulator_data bd71847_regulators[] = {
 			.of_match = of_match_ptr("LDO5"),
 			.regulators_node = of_match_ptr("regulators"),
 			.id = BD718XX_LDO5,
-			.ops = &bd718xx_ldo_regulator_ops,
+			.ops = &bd718xx_pickable_range_ldo_ops,
 			.type = REGULATOR_VOLTAGE,
-			.n_voltages = BD718XX_LDO5_VOLTAGE_NUM,
-			.linear_ranges = bd718xx_ldo5_volts,
-			.n_linear_ranges = ARRAY_SIZE(bd718xx_ldo5_volts),
+			.n_voltages = BD71847_LDO5_VOLTAGE_NUM,
+			.linear_ranges = bd71847_ldo5_volts,
+			.n_linear_ranges = ARRAY_SIZE(bd71847_ldo5_volts),
 			.vsel_reg = BD718XX_REG_LDO5_VOLT,
 			.vsel_mask = BD71847_LDO5_MASK,
+			.vsel_range_reg = BD718XX_REG_LDO5_VOLT,
+			.vsel_range_mask = BD71847_LDO5_RANGE_MASK,
+			.linear_range_selectors = bd71847_ldo5_volt_range_sel,
 			.enable_reg = BD718XX_REG_LDO5_VOLT,
 			.enable_mask = BD718XX_LDO_EN,
 			.owner = THIS_MODULE,
@@ -660,14 +751,17 @@ static const struct bd718xx_regulator_data bd71837_regulators[] = {
 			.of_match = of_match_ptr("BUCK5"),
 			.regulators_node = of_match_ptr("regulators"),
 			.id = BD718XX_BUCK5,
-			.ops = &bd718xx_buck_regulator_ops,
+			.ops = &bd718xx_pickable_range_buck_ops,
 			.type = REGULATOR_VOLTAGE,
-			.n_voltages = BD718XX_1ST_NODVS_BUCK_VOLTAGE_NUM,
-			.linear_ranges = bd718xx_1st_nodvs_buck_volts,
+			.n_voltages = BD71837_BUCK5_VOLTAGE_NUM,
+			.linear_ranges = bd71837_buck5_volts,
 			.n_linear_ranges =
-				ARRAY_SIZE(bd718xx_1st_nodvs_buck_volts),
+				ARRAY_SIZE(bd71837_buck5_volts),
 			.vsel_reg = BD718XX_REG_1ST_NODVS_BUCK_VOLT,
-			.vsel_mask = BD718XX_1ST_NODVS_BUCK_MASK,
+			.vsel_mask = BD71837_BUCK5_MASK,
+			.vsel_range_reg = BD718XX_REG_1ST_NODVS_BUCK_VOLT,
+			.vsel_range_mask = BD71837_BUCK5_RANGE_MASK,
+			.linear_range_selectors = bd71837_buck5_volt_range_sel,
 			.enable_reg = BD718XX_REG_1ST_NODVS_BUCK_CTRL,
 			.enable_mask = BD718XX_BUCK_EN,
 			.owner = THIS_MODULE,
@@ -687,9 +781,9 @@ static const struct bd718xx_regulator_data bd71837_regulators[] = {
 			.ops = &bd718xx_buck_regulator_ops,
 			.type = REGULATOR_VOLTAGE,
 			.n_voltages = BD71837_BUCK6_VOLTAGE_NUM,
-			.linear_ranges = bd71837_buck6_voltage_ranges,
+			.linear_ranges = bd71837_buck6_volts,
 			.n_linear_ranges =
-				ARRAY_SIZE(bd71837_buck6_voltage_ranges),
+				ARRAY_SIZE(bd71837_buck6_volts),
 			.vsel_reg = BD718XX_REG_2ND_NODVS_BUCK_VOLT,
 			.vsel_mask = BD71837_BUCK6_MASK,
 			.enable_reg = BD718XX_REG_2ND_NODVS_BUCK_CTRL,
@@ -754,13 +848,16 @@ static const struct bd718xx_regulator_data bd71837_regulators[] = {
 			.of_match = of_match_ptr("LDO1"),
 			.regulators_node = of_match_ptr("regulators"),
 			.id = BD718XX_LDO1,
-			.ops = &bd718xx_ldo_regulator_ops,
+			.ops = &bd718xx_pickable_range_ldo_ops,
 			.type = REGULATOR_VOLTAGE,
 			.n_voltages = BD718XX_LDO1_VOLTAGE_NUM,
 			.linear_ranges = bd718xx_ldo1_volts,
 			.n_linear_ranges = ARRAY_SIZE(bd718xx_ldo1_volts),
 			.vsel_reg = BD718XX_REG_LDO1_VOLT,
 			.vsel_mask = BD718XX_LDO1_MASK,
+			.vsel_range_reg = BD718XX_REG_LDO1_VOLT,
+			.vsel_range_mask = BD718XX_LDO1_RANGE_MASK,
+			.linear_range_selectors = bd718xx_ldo1_volt_range_sel,
 			.enable_reg = BD718XX_REG_LDO1_VOLT,
 			.enable_mask = BD718XX_LDO_EN,
 			.owner = THIS_MODULE,
@@ -847,9 +944,9 @@ static const struct bd718xx_regulator_data bd71837_regulators[] = {
 			.id = BD718XX_LDO5,
 			.ops = &bd718xx_ldo_regulator_ops,
 			.type = REGULATOR_VOLTAGE,
-			.n_voltages = BD718XX_LDO5_VOLTAGE_NUM,
-			.linear_ranges = bd718xx_ldo5_volts,
-			.n_linear_ranges = ARRAY_SIZE(bd718xx_ldo5_volts),
+			.n_voltages = BD71837_LDO5_VOLTAGE_NUM,
+			.linear_ranges = bd71837_ldo5_volts,
+			.n_linear_ranges = ARRAY_SIZE(bd71837_ldo5_volts),
 			/* LDO5 is supplied by buck6 */
 			.supply_name = "buck6",
 			.vsel_reg = BD718XX_REG_LDO5_VOLT,
diff --git a/include/linux/mfd/rohm-bd718x7.h b/include/linux/mfd/rohm-bd718x7.h
index d1730b97ba52..4cc617047d5f 100644
--- a/include/linux/mfd/rohm-bd718x7.h
+++ b/include/linux/mfd/rohm-bd718x7.h
@@ -7,13 +7,13 @@
 #include <linux/regmap.h>
 
 enum {
-	BD718XX_TYPE_BD71837,
+	BD718XX_TYPE_BD71837 = 0,
 	BD718XX_TYPE_BD71847,
 	BD718XX_TYPE_AMNT // Keep this as last item
 };
 
 enum {
-	BD718XX_BUCK1	=	0,
+	BD718XX_BUCK1 = 0,
 	BD718XX_BUCK2,
 	BD718XX_BUCK3,
 	BD718XX_BUCK4,
@@ -31,31 +31,27 @@ enum {
 	BD718XX_REGULATOR_MAX,
 };
 
-/* Common voltage configurations
- *
- * Note, we support only one range of voltages for each buck/LDO until we
- * get pickable ranges support. (See range selection bits for BUCK5 and
- * LDO1. On BD71847 also the second no DVS buck and LDO5)
- */
-
+/* Common voltage configurations */
 #define BD718XX_DVS_BUCK_VOLTAGE_NUM		0x3D
-#define BD718XX_1ST_NODVS_BUCK_VOLTAGE_NUM	0x08
-#define BD71837_4TH_NODVS_BUCK_VOLTAGE_NUM	0x3D
+#define BD718XX_4TH_NODVS_BUCK_VOLTAGE_NUM	0x3D
 
-#define BD718XX_LDO1_VOLTAGE_NUM	0x04
+#define BD718XX_LDO1_VOLTAGE_NUM	0x08
 #define BD718XX_LDO2_VOLTAGE_NUM	0x02
 #define BD718XX_LDO3_VOLTAGE_NUM	0x10
 #define BD718XX_LDO4_VOLTAGE_NUM	0x0A
-#define BD718XX_LDO5_VOLTAGE_NUM	0x10
 #define BD718XX_LDO6_VOLTAGE_NUM	0x0A
 
 /* BD71837 specific voltage configurations */
+#define BD71837_BUCK5_VOLTAGE_NUM	0x10
 #define BD71837_BUCK6_VOLTAGE_NUM	0x04
 #define BD71837_BUCK7_VOLTAGE_NUM	0x08
+#define BD71837_LDO5_VOLTAGE_NUM	0x10
 #define BD71837_LDO7_VOLTAGE_NUM	0x10
 
 /* BD71847 specific voltage configurations */
-#define BD71847_BUCK4_VOLTAGE_NUM	0x04
+#define BD71847_BUCK3_VOLTAGE_NUM	0x18
+#define BD71847_BUCK4_VOLTAGE_NUM	0x08
+#define BD71847_LDO5_VOLTAGE_NUM	0x20
 
 /* Registers specific to BD71837 */
 enum {
@@ -139,12 +135,20 @@ enum {
 #define DVS_BUCK_IDLE_MASK	0x3F
 
 #define BD718XX_1ST_NODVS_BUCK_MASK	0x07
-#define BD71847_BUCK4_MASK		0x03
-#define BD71837_BUCK6_MASK		0x03
 #define BD718XX_3RD_NODVS_BUCK_MASK	0x07
 #define BD718XX_4TH_NODVS_BUCK_MASK	0x3F
 
+#define BD71847_BUCK3_MASK		0x07
+#define BD71847_BUCK3_RANGE_MASK	0xC0
+#define BD71847_BUCK4_MASK		0x03
+#define BD71847_BUCK4_RANGE_MASK	0x40
+
+#define BD71837_BUCK5_MASK		0x07
+#define BD71837_BUCK5_RANGE_MASK	0x80
+#define BD71837_BUCK6_MASK		0x03
+
 #define BD718XX_LDO1_MASK		0x03
+#define BD718XX_LDO1_RANGE_MASK		0x20
 #define BD718XX_LDO2_MASK		0x20
 #define BD718XX_LDO3_MASK		0x0F
 #define BD718XX_LDO4_MASK		0x0F
@@ -152,10 +156,10 @@ enum {
 
 #define BD71837_LDO5_MASK		0x0F
 #define BD71847_LDO5_MASK		0x0F
+#define BD71847_LDO5_RANGE_MASK		0x20
 
 #define BD71837_LDO7_MASK		0x0F
 
-
 /* BD718XX Voltage monitoring masks */
 #define BD718XX_BUCK1_VRMON80           0x1
 #define BD718XX_BUCK1_VRMON130          0x2
-- 
2.14.3


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

* [PATCH 8/8] regulator: bd718xx: renme bd71837 to 718xx
  2018-08-29 12:35 [PATCH 0/8] regulator/mfd/dt_bindings: bd718x7: Support ROHM bd71847 Matti Vaittinen
                   ` (6 preceding siblings ...)
  2018-08-29 12:39 ` [PATCH 7/8] regulator: bd718XX use pickable ranges Matti Vaittinen
@ 2018-08-29 12:39 ` Matti Vaittinen
  7 siblings, 0 replies; 22+ messages in thread
From: Matti Vaittinen @ 2018-08-29 12:39 UTC (permalink / raw)
  To: lee.jones, robh+dt, mark.rutland, lgirdwood, broonie,
	mazziesaccount, matti.vaittinen, devicetree, linux-kernel,
	heikki.haikola, mikko.mutanen

rename bd71837-regulator.c to bd718x7-regulator.c to reflect the
fact that also BD71847 is now supported by the driver.

Signed-off-by: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
---
 drivers/regulator/Kconfig                                      | 2 +-
 drivers/regulator/Makefile                                     | 2 +-
 drivers/regulator/{bd71837-regulator.c => bd718x7-regulator.c} | 0
 3 files changed, 2 insertions(+), 2 deletions(-)
 rename drivers/regulator/{bd71837-regulator.c => bd718x7-regulator.c} (100%)

diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 329cdd33ed62..6e96ef1bd74a 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -189,7 +189,7 @@ config REGULATOR_BD718XX
 	  and LDO regulators.
 
 	  This driver can also be built as a module. If so, the module
-	  will be called bd71837-regulator.
+	  will be called bd718x7-regulator.
 
 config REGULATOR_BD9571MWV
 	tristate "ROHM BD9571MWV Regulators"
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 801d9a34a203..eac4d794f3b8 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -27,7 +27,7 @@ obj-$(CONFIG_REGULATOR_AS3711) += as3711-regulator.o
 obj-$(CONFIG_REGULATOR_AS3722) += as3722-regulator.o
 obj-$(CONFIG_REGULATOR_AXP20X) += axp20x-regulator.o
 obj-$(CONFIG_REGULATOR_BCM590XX) += bcm590xx-regulator.o
-obj-$(CONFIG_REGULATOR_BD718XX) += bd71837-regulator.o
+obj-$(CONFIG_REGULATOR_BD718XX) += bd718x7-regulator.o
 obj-$(CONFIG_REGULATOR_BD9571MWV) += bd9571mwv-regulator.o
 obj-$(CONFIG_REGULATOR_DA903X)	+= da903x.o
 obj-$(CONFIG_REGULATOR_DA9052)	+= da9052-regulator.o
diff --git a/drivers/regulator/bd71837-regulator.c b/drivers/regulator/bd718x7-regulator.c
similarity index 100%
rename from drivers/regulator/bd71837-regulator.c
rename to drivers/regulator/bd718x7-regulator.c
-- 
2.14.3


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

* Re: [PATCH 1/8] regulator: bd71837: Disable voltage monitoring for LDO3/4
  2018-08-29 12:36 ` [PATCH 1/8] regulator: bd71837: Disable voltage monitoring for LDO3/4 Matti Vaittinen
@ 2018-09-11 12:40   ` Lee Jones
  2018-09-12  7:47     ` Matti Vaittinen
  0 siblings, 1 reply; 22+ messages in thread
From: Lee Jones @ 2018-09-11 12:40 UTC (permalink / raw)
  To: Matti Vaittinen
  Cc: robh+dt, mark.rutland, lgirdwood, broonie, mazziesaccount,
	devicetree, linux-kernel, heikki.haikola, mikko.mutanen

On Wed, 29 Aug 2018, Matti Vaittinen wrote:

> There is a HW quirk in BD71837. The shutdown sequence timings for
> bucks/LDOs which are enabled via register interface are changed.
> At PMIC poweroff the voltage for BUCK6/7 is cut immediately at the
> beginning of shut-down sequence. This causes LDO5/6 voltage
> monitoring to detect under voltage and force PMIC to emergency
> state instead of poweroff. Disable voltage monitoring for LDO5 and
> LDO6 at probe to avoid this.
> 
> Signed-off-by: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
> ---
>  drivers/regulator/bd71837-regulator.c | 19 +++++++++++++++++++

>  include/linux/mfd/rohm-bd718x7.h      | 33 ++++++++++++++++++++++++++++++---

For my own reference:
  Acked-for-MFD-by: Lee Jones <lee.jones@linaro.org>

-- 
Lee Jones [李琼斯]
Linaro Services Technical Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

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

* Re: [PATCH 2/8] regulator: Support ROHM BD71847 power management IC
  2018-08-29 12:36 ` [PATCH 2/8] regulator: Support ROHM BD71847 power management IC Matti Vaittinen
@ 2018-09-11 13:48   ` Lee Jones
  2018-09-12  6:37     ` Matti Vaittinen
  0 siblings, 1 reply; 22+ messages in thread
From: Lee Jones @ 2018-09-11 13:48 UTC (permalink / raw)
  To: Matti Vaittinen
  Cc: robh+dt, mark.rutland, lgirdwood, broonie, mazziesaccount,
	devicetree, linux-kernel, heikki.haikola, mikko.mutanen

On Wed, 29 Aug 2018, Matti Vaittinen wrote:

> BD71847 is reduced version of BD71837. DVS bucks 3 and 4 are
> removed as is LDO7. Voltage ranges of some regulators are
> expanded.
> 
> Add initial support for BD71847 with BD71847 driver.
> 
> Signed-off-by: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
> ---
>  drivers/mfd/rohm-bd718x7.c            |   84 ++-
>  drivers/regulator/bd71837-regulator.c | 1056 ++++++++++++++++++++++-----------
>  include/linux/mfd/rohm-bd718x7.h      |  272 ++++-----
>  3 files changed, 910 insertions(+), 502 deletions(-)
> 
> diff --git a/drivers/mfd/rohm-bd718x7.c b/drivers/mfd/rohm-bd718x7.c
> index 75c8ec659547..c95f34269bb6 100644
> --- a/drivers/mfd/rohm-bd718x7.c
> +++ b/drivers/mfd/rohm-bd718x7.c
> @@ -7,21 +7,34 @@
>  // Datasheet available from
>  // https://www.rohm.com/datasheet/BD71837MWV/bd71837mwv-e
>  
> +#include <linux/gpio_keys.h>
>  #include <linux/i2c.h>
>  #include <linux/input.h>
>  #include <linux/interrupt.h>
>  #include <linux/mfd/rohm-bd718x7.h>
>  #include <linux/mfd/core.h>
>  #include <linux/module.h>
> +#include <linux/of_device.h>
>  #include <linux/regmap.h>
>  
> -/*
> - * gpio_keys.h requires definiton of bool. It is brought in
> - * by above includes. Keep this as last until gpio_keys.h gets fixed.
> - */
> -#include <linux/gpio_keys.h>
> +static const u8 bd71837_supported_revisions[] = { 0xA2 };
> +static const u8 bd71847_supported_revisions[] = { 0xA0 };

I haven't seen anything like this before.

Is this really required?

Especially since you only have 1 of each currently.

> -static const u8 supported_revisions[] = { 0xA2 /* BD71837 */ };
> +struct known_revisions {
> +	const u8 (*revisions)[];
> +	unsigned int known_revisions;

I didn't initially know what this was at first glance.

Please re-name it to show that it is the number of stored revisions.

> +};
> +
> +static const struct known_revisions supported_revisions[BD718XX_TYPE_AMNT] = {
> +	[BD718XX_TYPE_BD71837] = {
> +		.revisions = &bd71837_supported_revisions,
> +		.known_revisions = ARRAY_SIZE(bd71837_supported_revisions),
> +	},
> +	[BD718XX_TYPE_BD71847] = {
> +		.revisions = &bd71847_supported_revisions,
> +		.known_revisions = ARRAY_SIZE(bd71847_supported_revisions),
> +	},
> +};
>  
>  static struct gpio_keys_button button = {
>  	.code = KEY_POWER,
> @@ -41,8 +54,8 @@ static struct mfd_cell bd71837_mfd_cells[] = {
>  		.platform_data = &bd718xx_powerkey_data,
>  		.pdata_size = sizeof(bd718xx_powerkey_data),
>  	},
> -	{ .name = "bd71837-clk", },
> -	{ .name = "bd71837-pmic", },
> +	{ .name = "bd718xx-clk", },
> +	{ .name = "bd718xx-pmic", },
>  };
>  
>  static const struct regmap_irq bd71837_irqs[] = {
> @@ -61,16 +74,16 @@ static struct regmap_irq_chip bd71837_irq_chip = {
>  	.num_irqs = ARRAY_SIZE(bd71837_irqs),
>  	.num_regs = 1,
>  	.irq_reg_stride = 1,
> -	.status_base = BD71837_REG_IRQ,
> -	.mask_base = BD71837_REG_MIRQ,
> -	.ack_base = BD71837_REG_IRQ,
> +	.status_base = BD718XX_REG_IRQ,
> +	.mask_base = BD718XX_REG_MIRQ,
> +	.ack_base = BD718XX_REG_IRQ,
>  	.init_ack_masked = true,
>  	.mask_invert = false,
>  };
>  
>  static const struct regmap_range pmic_status_range = {
> -	.range_min = BD71837_REG_IRQ,
> -	.range_max = BD71837_REG_POW_STATE,
> +	.range_min = BD718XX_REG_IRQ,
> +	.range_max = BD718XX_REG_POW_STATE,
>  };
>  
>  static const struct regmap_access_table volatile_regs = {
> @@ -82,7 +95,7 @@ static const struct regmap_config bd71837_regmap_config = {
>  	.reg_bits = 8,
>  	.val_bits = 8,
>  	.volatile_table = &volatile_regs,
> -	.max_register = BD71837_MAX_REGISTER - 1,
> +	.max_register = BD718XX_MAX_REGISTER - 1,
>  	.cache_type = REGCACHE_RBTREE,
>  };
>  
> @@ -91,13 +104,19 @@ static int bd71837_i2c_probe(struct i2c_client *i2c,
>  {
>  	struct bd71837 *bd71837;
>  	int ret, i;
> -	unsigned int val;
> +	const unsigned int *type;
>  
>  	bd71837 = devm_kzalloc(&i2c->dev, sizeof(struct bd71837), GFP_KERNEL);
>  
>  	if (!bd71837)
>  		return -ENOMEM;
>  
> +	type = of_device_get_match_data(&i2c->dev);
> +	if (!type || *type >= BD718XX_TYPE_AMNT) {
> +		dev_err(&i2c->dev, "Bad chip type\n");
> +		return -ENODEV;
> +	}
> +
>  	bd71837->chip_irq = i2c->irq;
>  
>  	if (!bd71837->chip_irq) {
> @@ -105,6 +124,7 @@ static int bd71837_i2c_probe(struct i2c_client *i2c,
>  		return -EINVAL;
>  	}
>  
> +	bd71837->chip_type = *type;
>  	bd71837->dev = &i2c->dev;
>  	dev_set_drvdata(&i2c->dev, bd71837);
>  
> @@ -114,18 +134,21 @@ static int bd71837_i2c_probe(struct i2c_client *i2c,
>  		return PTR_ERR(bd71837->regmap);
>  	}
>  
> -	ret = regmap_read(bd71837->regmap, BD71837_REG_REV, &val);
> +	ret = regmap_read(bd71837->regmap, BD718XX_REG_REV, &bd71837->chip_rev);
>  	if (ret) {
> -		dev_err(&i2c->dev, "Read BD71837_REG_DEVICE failed\n");
> +		dev_err(&i2c->dev, "Failed to read revision register\n");
>  		return ret;
>  	}
> -	for (i = 0; i < ARRAY_SIZE(supported_revisions); i++)
> -		if (supported_revisions[i] == val)
> +	for (i = 0;
> +	     i < supported_revisions[bd71837->chip_type].known_revisions; i++)
> +		if ((*supported_revisions[bd71837->chip_type].revisions)[i] ==
> +		    bd71837->chip_rev)
>  			break;
>  
> -	if (i == ARRAY_SIZE(supported_revisions)) {
> -		dev_err(&i2c->dev, "Unsupported chip revision\n");
> -		return -ENODEV;
> +	if (i == supported_revisions[bd71837->chip_type].known_revisions) {
> +		dev_err(&i2c->dev, "Unrecognized revision 0x%02x\n",
> +			bd71837->chip_rev);
> +		return -EINVAL;
>  	}

This has become a very (too) elaborate way to see if the current
running version is supported.  Please find a way to solve this (much)
more succinctly.  There are lots of examples of this.

In fact, since you are using OF, it is not possible for this driver to
probe with an unsupported device.  You can remove the whole lot.

>  	ret = devm_regmap_add_irq_chip(&i2c->dev, bd71837->regmap,
> @@ -138,7 +161,7 @@ static int bd71837_i2c_probe(struct i2c_client *i2c,
>  
>  	/* Configure short press to 10 milliseconds */
>  	ret = regmap_update_bits(bd71837->regmap,
> -				 BD71837_REG_PWRONCONFIG0,
> +				 BD718XX_REG_PWRONCONFIG0,
>  				 BD718XX_PWRBTN_PRESS_DURATION_MASK,
>  				 BD718XX_PWRBTN_SHORT_PRESS_10MS);
>  	if (ret) {
> @@ -149,7 +172,7 @@ static int bd71837_i2c_probe(struct i2c_client *i2c,
>  
>  	/* Configure long press to 10 seconds */
>  	ret = regmap_update_bits(bd71837->regmap,
> -				 BD71837_REG_PWRONCONFIG1,
> +				 BD718XX_REG_PWRONCONFIG1,
>  				 BD718XX_PWRBTN_PRESS_DURATION_MASK,
>  				 BD718XX_PWRBTN_LONG_PRESS_10S);
>  
> @@ -177,9 +200,20 @@ static int bd71837_i2c_probe(struct i2c_client *i2c,
>  
>  	return ret;
>  }
> +static const unsigned int chip_types[] = {
> +	[BD718XX_TYPE_BD71837] = BD718XX_TYPE_BD71837,
> +	[BD718XX_TYPE_BD71847] = BD718XX_TYPE_BD71847,
> +};
>  
>  static const struct of_device_id bd71837_of_match[] = {
> -	{ .compatible = "rohm,bd71837", },
> +	{
> +		.compatible = "rohm,bd71837",
> +		.data = &chip_types[BD718XX_TYPE_BD71837]
> +	},
> +	{
> +		.compatible = "rohm,bd71847",
> +		.data = &chip_types[BD718XX_TYPE_BD71847]

Again, way too complex.  Why not simply:

       .data = (void *)BD718XX_TYPE_BD71847?

>  	{ }
>  };
>  MODULE_DEVICE_TABLE(of, bd71837_of_match);

[...]

> diff --git a/include/linux/mfd/rohm-bd718x7.h b/include/linux/mfd/rohm-bd718x7.h
> index e8338e5dc10b..d1ed232e669e 100644
> --- a/include/linux/mfd/rohm-bd718x7.h
> +++ b/include/linux/mfd/rohm-bd718x7.h
> @@ -7,106 +7,125 @@
>  #include <linux/regmap.h>
>  
>  enum {
> -	BD71837_BUCK1	=	0,
> -	BD71837_BUCK2,
> -	BD71837_BUCK3,
> -	BD71837_BUCK4,
> -	BD71837_BUCK5,
> -	BD71837_BUCK6,
> -	BD71837_BUCK7,
> -	BD71837_BUCK8,
> -	BD71837_LDO1,
> -	BD71837_LDO2,
> -	BD71837_LDO3,
> -	BD71837_LDO4,
> -	BD71837_LDO5,
> -	BD71837_LDO6,
> -	BD71837_LDO7,
> -	BD71837_REGULATOR_CNT,
> +	BD718XX_TYPE_BD71837,
> +	BD718XX_TYPE_BD71847,
> +	BD718XX_TYPE_AMNT // Keep this as last item

No C++ comments please.

What does AMNT mean?  I'm guessing it means amount, which isn't a
valid type. I suggest MAX_BOARD_TYPES or similar instead.

>  };
>  
> -#define BD71837_BUCK1_VOLTAGE_NUM	0x40
> -#define BD71837_BUCK2_VOLTAGE_NUM	0x40
> -#define BD71837_BUCK3_VOLTAGE_NUM	0x40
> -#define BD71837_BUCK4_VOLTAGE_NUM	0x40
> +enum {
> +	BD718XX_BUCK1	=	0,
> +	BD718XX_BUCK2,
> +	BD718XX_BUCK3,
> +	BD718XX_BUCK4,
> +	BD718XX_BUCK5,
> +	BD718XX_BUCK6,
> +	BD718XX_BUCK7,
> +	BD718XX_BUCK8,
> +	BD718XX_LDO1,
> +	BD718XX_LDO2,
> +	BD718XX_LDO3,
> +	BD718XX_LDO4,
> +	BD718XX_LDO5,
> +	BD718XX_LDO6,
> +	BD718XX_LDO7,
> +	BD718XX_REGULATOR_MAX,

Closer.

Whatever you choose to use, please ensure the last entries of the
enums use a similar format.

[...]

-- 
Lee Jones [李琼斯]
Linaro Services Technical Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

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

* Re: [PATCH 4/8] mfd: dt bindings: add BD71847 device-tree binding documentation
  2018-08-29 12:37 ` [PATCH 4/8] mfd: " Matti Vaittinen
@ 2018-09-11 13:49   ` Lee Jones
  2018-09-12  7:43     ` Matti Vaittinen
  0 siblings, 1 reply; 22+ messages in thread
From: Lee Jones @ 2018-09-11 13:49 UTC (permalink / raw)
  To: Matti Vaittinen
  Cc: robh+dt, mark.rutland, lgirdwood, broonie, mazziesaccount,
	devicetree, linux-kernel, heikki.haikola, mikko.mutanen

On Wed, 29 Aug 2018, Matti Vaittinen wrote:

> Add ROHM BD71847 Power Management IC MFD binding information to
> device-tree binding documents.
> 
> Signed-off-by: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
> ---
>  .../devicetree/bindings/mfd/rohm,bd71837-pmic.txt       | 17 +++++++++--------
>  1 file changed, 9 insertions(+), 8 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/mfd/rohm,bd71837-pmic.txt b/Documentation/devicetree/bindings/mfd/rohm,bd71837-pmic.txt
> index 3ca56fdb5ffe..d78172878faa 100644
> --- a/Documentation/devicetree/bindings/mfd/rohm,bd71837-pmic.txt
> +++ b/Documentation/devicetree/bindings/mfd/rohm,bd71837-pmic.txt
> @@ -1,16 +1,17 @@
> -* ROHM BD71837 Power Management Integrated Circuit bindings
> +* ROHM BD71837 and BD71847 Power Management Integrated Circuit bindings
>  
> -BD71837MWV is a programmable Power Management IC for powering single-core,
> -dual-core, and quad-core SoCs such as NXP-i.MX 8M. It is optimized for
> -low BOM cost and compact solution footprint. It integrates 8 Buck
> -egulators and 7 LDOs to provide all the power rails required by the SoC and
> -the commonly used peripherals.
> +BD71837MWV and BD71847MWV are programmable Power Management ICs for powering
> +single-core, dual-core, and quad-core SoCs such as NXP-i.MX 8M. They are
> +optimized for low BOM cost and compact solution footprint. BD71837MWV
> +integrates 8 Buck regulators and 7 LDOs. BD71847MWV contains 6 Buck regulators
> +and 6 LDOs.
>  
> -Datasheet for PMIC is available at:
> +Datasheet for BD71837 is available at:
>  https://www.rohm.com/datasheet/BD71837MWV/bd71837mwv-e
>  
>  Required properties:
> - - compatible		: Should be "rohm,bd71837".
> + - compatible		: Should be "rohm,bd71837" for bd71837 and
> +			  "rohm,bd71847" for bd71847.

Nit: Probably sightly clearer as:

> + - compatible		: Should be "rohm,bd71837" for bd71837
> +			                    "rohm,bd71847" for bd71847.

Apart from that:

For my own reference:
  Acked-for-MFD-by: Lee Jones <lee.jones@linaro.org>

-- 
Lee Jones [李琼斯]
Linaro Services Technical Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

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

* Re: [PATCH 6/8] regulator/mfd: bd718xx: rename bd71837/bd71847 common instances
  2018-08-29 12:38 ` [PATCH 6/8] regulator/mfd: bd718xx: rename bd71837/bd71847 common instances Matti Vaittinen
@ 2018-09-11 13:51   ` Lee Jones
  0 siblings, 0 replies; 22+ messages in thread
From: Lee Jones @ 2018-09-11 13:51 UTC (permalink / raw)
  To: Matti Vaittinen
  Cc: robh+dt, mark.rutland, lgirdwood, broonie, mazziesaccount,
	devicetree, linux-kernel, heikki.haikola, mikko.mutanen

On Wed, 29 Aug 2018, Matti Vaittinen wrote:

> Rename parts of code that support both BD71837 and BD71847 to BD718XX.
> 
> Signed-off-by: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
> ---
>  drivers/mfd/rohm-bd718x7.c            | 112 +++++++++++++++++-----------------
>  drivers/regulator/bd71837-regulator.c |  24 ++++----
>  include/linux/mfd/rohm-bd718x7.h      |  62 +++++++++----------
>  3 files changed, 99 insertions(+), 99 deletions(-)

The premise of XXing things out seems fine.

For my own reference:
  Acked-for-MFD-by: Lee Jones <lee.jones@linaro.org>

-- 
Lee Jones [李琼斯]
Linaro Services Technical Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

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

* Re: [PATCH 7/8] regulator: bd718XX use pickable ranges
  2018-08-29 12:39 ` [PATCH 7/8] regulator: bd718XX use pickable ranges Matti Vaittinen
@ 2018-09-11 13:55   ` Lee Jones
  2018-09-12  7:41     ` Matti Vaittinen
  0 siblings, 1 reply; 22+ messages in thread
From: Lee Jones @ 2018-09-11 13:55 UTC (permalink / raw)
  To: Matti Vaittinen
  Cc: robh+dt, mark.rutland, lgirdwood, broonie, mazziesaccount,
	devicetree, linux-kernel, heikki.haikola, mikko.mutanen

On Wed, 29 Aug 2018, Matti Vaittinen wrote:

> Few regulators in BD71837 and BD71847 can output voltages from
> different voltage ranges. Register interface is arranged so that
> used range is selected by toggling bits which are not next to actual
> voltage selection bits. Then the voltage inside selected range is
> determined by voltage selection bits (as usual). Support BD71837
> and BD71847 selectible range voltages using new pickable ranges
> helpers.
> 
> Signed-off-by: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
> ---
>  drivers/regulator/bd71837-regulator.c | 155 +++++++++++++++++++++++++++-------
>  include/linux/mfd/rohm-bd718x7.h      |  38 +++++----
>  2 files changed, 147 insertions(+), 46 deletions(-)

[...]

> diff --git a/include/linux/mfd/rohm-bd718x7.h b/include/linux/mfd/rohm-bd718x7.h
> index d1730b97ba52..4cc617047d5f 100644
> --- a/include/linux/mfd/rohm-bd718x7.h
> +++ b/include/linux/mfd/rohm-bd718x7.h
> @@ -7,13 +7,13 @@
>  #include <linux/regmap.h>
>  
>  enum {
> -	BD718XX_TYPE_BD71837,
> +	BD718XX_TYPE_BD71837 = 0,
>  	BD718XX_TYPE_BD71847,
>  	BD718XX_TYPE_AMNT // Keep this as last item
>  };
>  
>  enum {
> -	BD718XX_BUCK1	=	0,
> +	BD718XX_BUCK1 = 0,
>  	BD718XX_BUCK2,
>  	BD718XX_BUCK3,
>  	BD718XX_BUCK4,
> @@ -31,31 +31,27 @@ enum {
>  	BD718XX_REGULATOR_MAX,
>  };

Even though I don't care enough to NACK the patch, the above are
unrelated changes and should normally be contained in a separate
patch.

For my own reference:
  Acked-for-MFD-by: Lee Jones <lee.jones@linaro.org>

-- 
Lee Jones [李琼斯]
Linaro Services Technical Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

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

* Re: [PATCH 2/8] regulator: Support ROHM BD71847 power management IC
  2018-09-11 13:48   ` Lee Jones
@ 2018-09-12  6:37     ` Matti Vaittinen
  0 siblings, 0 replies; 22+ messages in thread
From: Matti Vaittinen @ 2018-09-12  6:37 UTC (permalink / raw)
  To: Lee Jones
  Cc: robh+dt, mark.rutland, lgirdwood, broonie, mazziesaccount,
	devicetree, linux-kernel, heikki.haikola, mikko.mutanen

Hello Lee,

Thanks again for the review! I see you did bunch of them... I really
admire your devotion. For me reviewing is hard work. I do appreciate
it. So nice to see you're back in the business =)

On Tue, Sep 11, 2018 at 02:48:08PM +0100, Lee Jones wrote:
> On Wed, 29 Aug 2018, Matti Vaittinen wrote:
> 
> > +static const u8 bd71837_supported_revisions[] = { 0xA2 };
> > +static const u8 bd71847_supported_revisions[] = { 0xA0 };
> 
> I haven't seen anything like this before.
> 
> Is this really required?
> 
> Especially since you only have 1 of each currently.

Valid question. I did ask the same thing myself. Reason why I ended up
doing this is simple though. I have no idea what may change if "chip
revision" is changed. I only know that I have chip(s) with these
revisions on my table - and I have a data sheet which mentions these
revisions. So I can only test that driver works with these revisions. I
however assume there will be new revisions and I thought that with this
approach marking them as supported will only require adding the revisio
to these arrays.

But as you have said - this makes code slightly more complex - even if I
disagree with you regarding how complex is too complex =) The use case
and intention of tables is quite obvious, right? That makes following
the loops in probe pretty easy after all...

But I won't start arguing with you - let's assume the register interface
won't get changed - and if it does, well, let's handle that then. So
I'll drop whole revision check.

> 
> > -static const u8 supported_revisions[] = { 0xA2 /* BD71837 */ };
> > +struct known_revisions {
> > +	const u8 (*revisions)[];
> > +	unsigned int known_revisions;
> 
> I didn't initially know what this was at first glance.
> 
> Please re-name it to show that it is the number of stored revisions.

This will be fixed as I'll drop the revision check

> > +static const struct known_revisions supported_revisions[BD718XX_TYPE_AMNT] = {
> > +	[BD718XX_TYPE_BD71837] = {
> > +		.revisions = &bd71837_supported_revisions,
> > +		.known_revisions = ARRAY_SIZE(bd71837_supported_revisions),
> > +	},
> > +	[BD718XX_TYPE_BD71847] = {
> > +		.revisions = &bd71847_supported_revisions,
> > +		.known_revisions = ARRAY_SIZE(bd71847_supported_revisions),
> > +	},
> > +};
> >  
> > @@ -91,13 +104,19 @@ static int bd71837_i2c_probe(struct i2c_client *i2c,
> >  {
> >  	struct bd71837 *bd71837;
> >  	int ret, i;
> > +	const unsigned int *type;
> >  
> > +	type = of_device_get_match_data(&i2c->dev);
> > +	if (!type || *type >= BD718XX_TYPE_AMNT) {
> > +		dev_err(&i2c->dev, "Bad chip type\n");
> > +		return -ENODEV;
> > +	}
> > +
> > +	bd71837->chip_type = *type;

> > +	ret = regmap_read(bd71837->regmap, BD718XX_REG_REV, &bd71837->chip_rev);

> > +	for (i = 0;
> > +	     i < supported_revisions[bd71837->chip_type].known_revisions; i++)
> > +		if ((*supported_revisions[bd71837->chip_type].revisions)[i] ==
> > +		    bd71837->chip_rev)
> >  			break;
> >  
> > +	if (i == supported_revisions[bd71837->chip_type].known_revisions) {
> > +		dev_err(&i2c->dev, "Unrecognized revision 0x%02x\n",
> > +			bd71837->chip_rev);
> > +		return -EINVAL;
> >  	}
> 
> This has become a very (too) elaborate way to see if the current
> running version is supported.  Please find a way to solve this (much)
> more succinctly.  There are lots of examples of this.

I cut out pieces of quoted patch to shorten it to relevant bits.

As I said above - I think this is not as bad as you say - it is quite
obvious what it does after all. And adding new revision would be just
adding new entry to the revision array. But yes, I am not sure if this
is needed so I'll drop this. Let's work the compatibility issues between
revisions only if such ever emerge =)
> 
> In fact, since you are using OF, it is not possible for this driver to
> probe with an unsupported device.  You can remove the whole lot.
> 
I don't really see how the OF helps me with revisions - as chip revision
is not presented in DT. The type of chip of course is. So you're right.
Check for invalid chip_type can be dropped.

> > +static const unsigned int chip_types[] = {
> > +	[BD718XX_TYPE_BD71837] = BD718XX_TYPE_BD71837,
> > +	[BD718XX_TYPE_BD71847] = BD718XX_TYPE_BD71847,
> > +};
> >  
> >  static const struct of_device_id bd71837_of_match[] = {
> > -	{ .compatible = "rohm,bd71837", },
> > +	{
> > +		.compatible = "rohm,bd71837",
> > +		.data = &chip_types[BD718XX_TYPE_BD71837]
> > +	},
> > +	{
> > +		.compatible = "rohm,bd71847",
> > +		.data = &chip_types[BD718XX_TYPE_BD71847]
> 
> Again, way too complex.  Why not simply:
> 
>        .data = (void *)BD718XX_TYPE_BD71847?
> 

Ugh. That's horrible on my eyes. I dislike delivering data in addresses.
That's why I rather did array with IDs and used pointer to array member
here. But this is again not the battle I must win - so I'll do as you
suggested even if it looks ugly to me. I think we alreadt  had discussion
about vomitting on keyboard last summer - so let's not go back to that
now. ;)

> [...]
> 
> > -	BD71837_REGULATOR_CNT,
> > +	BD718XX_TYPE_BD71837,
> > +	BD718XX_TYPE_BD71847,
> > +	BD718XX_TYPE_AMNT // Keep this as last item
> 
> No C++ comments please.
> 
> What does AMNT mean?  I'm guessing it means amount, which isn't a
> valid type. I suggest MAX_BOARD_TYPES or similar instead.

You're not bad at guessing! =)

Well, what I like here is keeping the beginning of enum member the same.
When you see BD718XX_TYPE_AMNT used in driver you know that the enum value
belongs to this enum defining all BD718XX_TYPEs. And I like the amount
rather than MAX because MAX suggests that the value is last valid value.
Which is not the case here. And as the numbering begins from zero, this
enum really is amount of valid types. Thus I like the amount. Do you
think BD718XX_TYPE_AMOUNT would do? I know it is a bit Yodaish language
but it still should be clear enough and it would maintain the same enum
name prefix as other members in this enum.

> > +	BD718XX_LDO7,
> > +	BD718XX_REGULATOR_MAX,
> 
> Closer.
> 
> Whatever you choose to use, please ensure the last entries of the
> enums use a similar format.

Fair point. I'll cook new patch which fixes the define naming (just please
give me your opinion on using "BD718XX_TYPE_AMOUNT") and drops the
revision check from probe. Oh, and uses the .data pointer to contain the
chip type and not location where chip type is stored (even if my heart
burns, eyes bleed and <invent more things here by yourself>) ;)

Br,
	Matti Vaittinen

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

* Re: [PATCH 7/8] regulator: bd718XX use pickable ranges
  2018-09-11 13:55   ` Lee Jones
@ 2018-09-12  7:41     ` Matti Vaittinen
  0 siblings, 0 replies; 22+ messages in thread
From: Matti Vaittinen @ 2018-09-12  7:41 UTC (permalink / raw)
  To: Lee Jones
  Cc: robh+dt, mark.rutland, lgirdwood, broonie, mazziesaccount,
	devicetree, linux-kernel, heikki.haikola, mikko.mutanen

Hello,

On Tue, Sep 11, 2018 at 02:55:49PM +0100, Lee Jones wrote:
> On Wed, 29 Aug 2018, Matti Vaittinen wrote:
> 
> > Few regulators in BD71837 and BD71847 can output voltages from
> > different voltage ranges. Register interface is arranged so that
> > used range is selected by toggling bits which are not next to actual
> > voltage selection bits. Then the voltage inside selected range is
> > determined by voltage selection bits (as usual). Support BD71837
> > and BD71847 selectible range voltages using new pickable ranges
> > helpers.
> 
> [...]
> 
> > diff --git a/include/linux/mfd/rohm-bd718x7.h b/include/linux/mfd/rohm-bd718x7.h
> > index d1730b97ba52..4cc617047d5f 100644
> > --- a/include/linux/mfd/rohm-bd718x7.h
> > +++ b/include/linux/mfd/rohm-bd718x7.h
> > @@ -7,13 +7,13 @@
> >  #include <linux/regmap.h>
> >  
> >  enum {
> > -	BD718XX_TYPE_BD71837,
> > +	BD718XX_TYPE_BD71837 = 0,
> >  	BD718XX_TYPE_BD71847,
> >  	BD718XX_TYPE_AMNT // Keep this as last item
> >  };
> >  
> >  enum {
> > -	BD718XX_BUCK1	=	0,
> > +	BD718XX_BUCK1 = 0,
> >  	BD718XX_BUCK2,
> >  	BD718XX_BUCK3,
> >  	BD718XX_BUCK4,
> > @@ -31,31 +31,27 @@ enum {
> >  	BD718XX_REGULATOR_MAX,
> >  };
> 
> Even though I don't care enough to NACK the patch, the above are
> unrelated changes and should normally be contained in a separate
> patch.

Thanks. But as I am going to modify the patch set anyways I can do this
change in first patch for the series. You're right that it is more
appropriate place for this change.

> 
> For my own reference:
>   Acked-for-MFD-by: Lee Jones <lee.jones@linaro.org>
> 
> -- 
> Lee Jones [李琼斯]
> Linaro Services Technical Lead
> Linaro.org │ Open source software for ARM SoCs
> Follow Linaro: Facebook | Twitter | Blog

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

* Re: [PATCH 4/8] mfd: dt bindings: add BD71847 device-tree binding documentation
  2018-09-11 13:49   ` Lee Jones
@ 2018-09-12  7:43     ` Matti Vaittinen
  0 siblings, 0 replies; 22+ messages in thread
From: Matti Vaittinen @ 2018-09-12  7:43 UTC (permalink / raw)
  To: Lee Jones
  Cc: robh+dt, mark.rutland, lgirdwood, broonie, mazziesaccount,
	devicetree, linux-kernel, heikki.haikola, mikko.mutanen

On Tue, Sep 11, 2018 at 02:49:47PM +0100, Lee Jones wrote:
> On Wed, 29 Aug 2018, Matti Vaittinen wrote:
> 
> > Add ROHM BD71847 Power Management IC MFD binding information to
> > device-tree binding documents.
> > 
> > Signed-off-by: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
> > ---
> >  .../devicetree/bindings/mfd/rohm,bd71837-pmic.txt       | 17 +++++++++--------
> >  1 file changed, 9 insertions(+), 8 deletions(-)
> > 
> > diff --git a/Documentation/devicetree/bindings/mfd/rohm,bd71837-pmic.txt b/Documentation/devicetree/bindings/mfd/rohm,bd71837-pmic.txt
> > index 3ca56fdb5ffe..d78172878faa 100644
> > --- a/Documentation/devicetree/bindings/mfd/rohm,bd71837-pmic.txt
> > +++ b/Documentation/devicetree/bindings/mfd/rohm,bd71837-pmic.txt
> > @@ -1,16 +1,17 @@
> > -* ROHM BD71837 Power Management Integrated Circuit bindings
> > +* ROHM BD71837 and BD71847 Power Management Integrated Circuit bindings
> >  
> > -BD71837MWV is a programmable Power Management IC for powering single-core,
> > -dual-core, and quad-core SoCs such as NXP-i.MX 8M. It is optimized for
> > -low BOM cost and compact solution footprint. It integrates 8 Buck
> > -egulators and 7 LDOs to provide all the power rails required by the SoC and
> > -the commonly used peripherals.
> > +BD71837MWV and BD71847MWV are programmable Power Management ICs for powering
> > +single-core, dual-core, and quad-core SoCs such as NXP-i.MX 8M. They are
> > +optimized for low BOM cost and compact solution footprint. BD71837MWV
> > +integrates 8 Buck regulators and 7 LDOs. BD71847MWV contains 6 Buck regulators
> > +and 6 LDOs.
> >  
> > -Datasheet for PMIC is available at:
> > +Datasheet for BD71837 is available at:
> >  https://www.rohm.com/datasheet/BD71837MWV/bd71837mwv-e
> >  
> >  Required properties:
> > - - compatible		: Should be "rohm,bd71837".
> > + - compatible		: Should be "rohm,bd71837" for bd71837 and
> > +			  "rohm,bd71847" for bd71847.
> 
> Nit: Probably sightly clearer as:
> 
> > + - compatible		: Should be "rohm,bd71837" for bd71837
> > +			                    "rohm,bd71847" for bd71847.

I think you're correct. I can change this while resending the series
anyways.

> 
> Apart from that:
> 
> For my own reference:
>   Acked-for-MFD-by: Lee Jones <lee.jones@linaro.org>
> 
> -- 
> Lee Jones [李琼斯]
> Linaro Services Technical Lead
> Linaro.org │ Open source software for ARM SoCs
> Follow Linaro: Facebook | Twitter | Blog

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

* Re: [PATCH 1/8] regulator: bd71837: Disable voltage monitoring for LDO3/4
  2018-09-11 12:40   ` Lee Jones
@ 2018-09-12  7:47     ` Matti Vaittinen
  2018-09-12  8:42       ` Lee Jones
  0 siblings, 1 reply; 22+ messages in thread
From: Matti Vaittinen @ 2018-09-12  7:47 UTC (permalink / raw)
  To: Lee Jones
  Cc: robh+dt, mark.rutland, lgirdwood, broonie, mazziesaccount,
	devicetree, linux-kernel, heikki.haikola, mikko.mutanen

On Tue, Sep 11, 2018 at 01:40:29PM +0100, Lee Jones wrote:
> On Wed, 29 Aug 2018, Matti Vaittinen wrote:
> 
> > There is a HW quirk in BD71837. The shutdown sequence timings for
> > bucks/LDOs which are enabled via register interface are changed.
> > At PMIC poweroff the voltage for BUCK6/7 is cut immediately at the
> > beginning of shut-down sequence. This causes LDO5/6 voltage
> > monitoring to detect under voltage and force PMIC to emergency
> > state instead of poweroff. Disable voltage monitoring for LDO5 and
> > LDO6 at probe to avoid this.
> > 
> > Signed-off-by: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
> > ---
> >  drivers/regulator/bd71837-regulator.c | 19 +++++++++++++++++++
> 
> >  include/linux/mfd/rohm-bd718x7.h      | 33 ++++++++++++++++++++++++++++++---
> 
> For my own reference:
>   Acked-for-MFD-by: Lee Jones <lee.jones@linaro.org>

I m not sure if it is relevant but I think this was already applied to
Mark's regulator tree.

Br,
	Matti Vaittinen

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

* Re: [PATCH 1/8] regulator: bd71837: Disable voltage monitoring for LDO3/4
  2018-09-12  7:47     ` Matti Vaittinen
@ 2018-09-12  8:42       ` Lee Jones
  2018-09-12  8:53         ` Matti Vaittinen
  0 siblings, 1 reply; 22+ messages in thread
From: Lee Jones @ 2018-09-12  8:42 UTC (permalink / raw)
  To: Matti Vaittinen
  Cc: robh+dt, mark.rutland, lgirdwood, broonie, mazziesaccount,
	devicetree, linux-kernel, heikki.haikola, mikko.mutanen

On Wed, 12 Sep 2018, Matti Vaittinen wrote:

> On Tue, Sep 11, 2018 at 01:40:29PM +0100, Lee Jones wrote:
> > On Wed, 29 Aug 2018, Matti Vaittinen wrote:
> > 
> > > There is a HW quirk in BD71837. The shutdown sequence timings for
> > > bucks/LDOs which are enabled via register interface are changed.
> > > At PMIC poweroff the voltage for BUCK6/7 is cut immediately at the
> > > beginning of shut-down sequence. This causes LDO5/6 voltage
> > > monitoring to detect under voltage and force PMIC to emergency
> > > state instead of poweroff. Disable voltage monitoring for LDO5 and
> > > LDO6 at probe to avoid this.
> > > 
> > > Signed-off-by: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
> > > ---
> > >  drivers/regulator/bd71837-regulator.c | 19 +++++++++++++++++++
> > 
> > >  include/linux/mfd/rohm-bd718x7.h      | 33 ++++++++++++++++++++++++++++++---
> > 
> > For my own reference:
> >   Acked-for-MFD-by: Lee Jones <lee.jones@linaro.org>
> 
> I m not sure if it is relevant but I think this was already applied to
> Mark's regulator tree.

Where is Mark's acceptance email?

-- 
Lee Jones [李琼斯]
Linaro Services Technical Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

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

* Re: [PATCH 1/8] regulator: bd71837: Disable voltage monitoring for LDO3/4
  2018-09-12  8:42       ` Lee Jones
@ 2018-09-12  8:53         ` Matti Vaittinen
  2018-09-12 10:23           ` Mark Brown
  0 siblings, 1 reply; 22+ messages in thread
From: Matti Vaittinen @ 2018-09-12  8:53 UTC (permalink / raw)
  To: Lee Jones
  Cc: robh+dt, mark.rutland, lgirdwood, broonie, mazziesaccount,
	devicetree, linux-kernel, heikki.haikola, mikko.mutanen

On Wed, Sep 12, 2018 at 09:42:51AM +0100, Lee Jones wrote:
> On Wed, 12 Sep 2018, Matti Vaittinen wrote:
> 
> > On Tue, Sep 11, 2018 at 01:40:29PM +0100, Lee Jones wrote:
> > > On Wed, 29 Aug 2018, Matti Vaittinen wrote:
> > > 
> > > > There is a HW quirk in BD71837. The shutdown sequence timings for
> > > > bucks/LDOs which are enabled via register interface are changed.
> > > > At PMIC poweroff the voltage for BUCK6/7 is cut immediately at the
> > > > beginning of shut-down sequence. This causes LDO5/6 voltage
> > > > monitoring to detect under voltage and force PMIC to emergency
> > > > state instead of poweroff. Disable voltage monitoring for LDO5 and
> > > > LDO6 at probe to avoid this.
> > > > 
> > > > Signed-off-by: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
> > > > ---
> > > >  drivers/regulator/bd71837-regulator.c | 19 +++++++++++++++++++
> > > 
> > > >  include/linux/mfd/rohm-bd718x7.h      | 33 ++++++++++++++++++++++++++++++---
> > > 
> > > For my own reference:
> > >   Acked-for-MFD-by: Lee Jones <lee.jones@linaro.org>
> > 
> > I m not sure if it is relevant but I think this was already applied to
> > Mark's regulator tree.
> 
> Where is Mark's acceptance email?

https://lkml.org/lkml/2018/8/29/644


> 
> -- 
> Lee Jones [李琼斯]
> Linaro Services Technical Lead
> Linaro.org │ Open source software for ARM SoCs
> Follow Linaro: Facebook | Twitter | Blog

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

* Re: [PATCH 1/8] regulator: bd71837: Disable voltage monitoring for LDO3/4
  2018-09-12  8:53         ` Matti Vaittinen
@ 2018-09-12 10:23           ` Mark Brown
  2018-09-12 10:44             ` Lee Jones
  0 siblings, 1 reply; 22+ messages in thread
From: Mark Brown @ 2018-09-12 10:23 UTC (permalink / raw)
  To: Matti Vaittinen
  Cc: Lee Jones, robh+dt, mark.rutland, lgirdwood, mazziesaccount,
	devicetree, linux-kernel, heikki.haikola, mikko.mutanen

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

On Wed, Sep 12, 2018 at 11:53:15AM +0300, Matti Vaittinen wrote:
> On Wed, Sep 12, 2018 at 09:42:51AM +0100, Lee Jones wrote:
> > On Wed, 12 Sep 2018, Matti Vaittinen wrote:

> > > I m not sure if it is relevant but I think this was already applied to
> > > Mark's regulator tree.

> > Where is Mark's acceptance email?

> https://lkml.org/lkml/2018/8/29/644

Yeah, sorry about not saying something explict there - IIRC when I
applied it I knew you were on vacation and it's a stable fix.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

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

* Re: [PATCH 1/8] regulator: bd71837: Disable voltage monitoring for LDO3/4
  2018-09-12 10:23           ` Mark Brown
@ 2018-09-12 10:44             ` Lee Jones
  0 siblings, 0 replies; 22+ messages in thread
From: Lee Jones @ 2018-09-12 10:44 UTC (permalink / raw)
  To: Mark Brown
  Cc: Matti Vaittinen, robh+dt, mark.rutland, lgirdwood,
	mazziesaccount, devicetree, linux-kernel, heikki.haikola,
	mikko.mutanen

On Wed, 12 Sep 2018, Mark Brown wrote:

> On Wed, Sep 12, 2018 at 11:53:15AM +0300, Matti Vaittinen wrote:
> > On Wed, Sep 12, 2018 at 09:42:51AM +0100, Lee Jones wrote:
> > > On Wed, 12 Sep 2018, Matti Vaittinen wrote:
> 
> > > > I m not sure if it is relevant but I think this was already applied to
> > > > Mark's regulator tree.
> 
> > > Where is Mark's acceptance email?
> 
> > https://lkml.org/lkml/2018/8/29/644
> 
> Yeah, sorry about not saying something explict there - IIRC when I
> applied it I knew you were on vacation and it's a stable fix.

No worries.  I know now.

-- 
Lee Jones [李琼斯]
Linaro Services Technical Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

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

end of thread, other threads:[~2018-09-12 10:44 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-08-29 12:35 [PATCH 0/8] regulator/mfd/dt_bindings: bd718x7: Support ROHM bd71847 Matti Vaittinen
2018-08-29 12:36 ` [PATCH 1/8] regulator: bd71837: Disable voltage monitoring for LDO3/4 Matti Vaittinen
2018-09-11 12:40   ` Lee Jones
2018-09-12  7:47     ` Matti Vaittinen
2018-09-12  8:42       ` Lee Jones
2018-09-12  8:53         ` Matti Vaittinen
2018-09-12 10:23           ` Mark Brown
2018-09-12 10:44             ` Lee Jones
2018-08-29 12:36 ` [PATCH 2/8] regulator: Support ROHM BD71847 power management IC Matti Vaittinen
2018-09-11 13:48   ` Lee Jones
2018-09-12  6:37     ` Matti Vaittinen
2018-08-29 12:37 ` [PATCH 3/8] regulator: dt bindings: add BD71847 device-tree binding documentation Matti Vaittinen
2018-08-29 12:37 ` [PATCH 4/8] mfd: " Matti Vaittinen
2018-09-11 13:49   ` Lee Jones
2018-09-12  7:43     ` Matti Vaittinen
2018-08-29 12:38 ` [PATCH 5/8] regulator: Support regulators where voltage ranges are selectable Matti Vaittinen
2018-08-29 12:38 ` [PATCH 6/8] regulator/mfd: bd718xx: rename bd71837/bd71847 common instances Matti Vaittinen
2018-09-11 13:51   ` Lee Jones
2018-08-29 12:39 ` [PATCH 7/8] regulator: bd718XX use pickable ranges Matti Vaittinen
2018-09-11 13:55   ` Lee Jones
2018-09-12  7:41     ` Matti Vaittinen
2018-08-29 12:39 ` [PATCH 8/8] regulator: bd718xx: renme bd71837 to 718xx Matti Vaittinen

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