regulator: bd718x7: support ROHM BD71837 and BD71847 PMICs

BD71837 and BD71847 is PMIC intended for powering single-core,
dual-core, and quad-core SoC’s such as NXP-i.MX 8M. BD71847
is used for example on NXP imx8mm EVK.

Add regulator driver for ROHM BD71837 and BD71847 PMICs.
BD71837 contains 8 bucks and 7 LDOS. BD71847 is reduced
version containing 6 bucks and 6 LDOs. Voltages for DVS
bucks (1-4 on BD71837, 1 and 2 on BD71847) can be adjusted
when regulators are enabled. For other bucks and LDOs we may
have over- or undershooting if voltage is adjusted when
regulator is enabled. Thus this is prevented by default.

BD718x7 has a quirk which may leave power output disabled
after reset if enable/disable state was controlled by SW.
Thus the SW control is only allowed for BD71837  bucks
3 and 4 by default. The impact of this limitation must be
evaluated board-by board and restrictions may need to be
modified. (Linux driver get's these limitations from DT and we
may want to implement same on u-Boot driver).

Signed-off-by: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
diff --git a/drivers/power/pmic/bd71837.c b/drivers/power/pmic/bd71837.c
index 24d9f7f..e292d42 100644
--- a/drivers/power/pmic/bd71837.c
+++ b/drivers/power/pmic/bd71837.c
@@ -3,6 +3,8 @@
  * Copyright 2018 NXP
  */
 
+#define DEBUG
+
 #include <common.h>
 #include <errno.h>
 #include <dm.h>
@@ -15,15 +17,15 @@
 
 static const struct pmic_child_info pmic_children_info[] = {
 	/* buck */
-	{ .prefix = "b", .driver = BD71837_REGULATOR_DRIVER},
+	{ .prefix = "b", .driver = BD718XX_REGULATOR_DRIVER},
 	/* ldo */
-	{ .prefix = "l", .driver = BD71837_REGULATOR_DRIVER},
+	{ .prefix = "l", .driver = BD718XX_REGULATOR_DRIVER},
 	{ },
 };
 
 static int bd71837_reg_count(struct udevice *dev)
 {
-	return BD71837_REG_NUM;
+	return BD718XX_MAX_REGISTER - 1;
 }
 
 static int bd71837_write(struct udevice *dev, uint reg, const uint8_t *buff,
@@ -54,7 +56,7 @@
 
 	regulators_node = dev_read_subnode(dev, "regulators");
 	if (!ofnode_valid(regulators_node)) {
-		debug("%s: %s regulators subnode not found!", __func__,
+		debug("%s: %s regulators subnode not found!\n", __func__,
 		      dev->name);
 		return -ENXIO;
 	}
@@ -69,6 +71,24 @@
 	return 0;
 }
 
+static int bd718x7_probe(struct udevice *dev)
+{
+	int ret;
+	uint8_t mask = BD718XX_REGLOCK_PWRSEQ | BD718XX_REGLOCK_VREG;
+
+	/* Unlock the PMIC regulator control before probing the children */
+	ret = pmic_clrsetbits(dev, BD718XX_REGLOCK, mask, 0);
+	if (ret) {
+		debug("%s: %s Failed to unlock regulator control\n", __func__,
+		      dev->name);
+		return ret;
+	}
+	debug("%s: '%s' - BD718x7 PMIC registers unlocked\n", __func__,
+	      dev->name);
+
+	return 0;
+}
+
 static struct dm_pmic_ops bd71837_ops = {
 	.reg_count = bd71837_reg_count,
 	.read = bd71837_read,
@@ -76,7 +96,8 @@
 };
 
 static const struct udevice_id bd71837_ids[] = {
-	{ .compatible = "rohm,bd71837", .data = 0x4b, },
+	{ .compatible = "rohm,bd71837", .data = ROHM_CHIP_TYPE_BD71837, },
+	{ .compatible = "rohm,bd71847", .data = ROHM_CHIP_TYPE_BD71847, },
 	{ }
 };
 
@@ -85,5 +106,6 @@
 	.id = UCLASS_PMIC,
 	.of_match = bd71837_ids,
 	.bind = bd71837_bind,
+	.probe = bd718x7_probe,
 	.ops = &bd71837_ops,
 };