linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/4] Add pca9450 driver
@ 2020-07-03 16:19 Robin Gong
  2020-07-03 16:19 ` [PATCH v2 1/4] regulator: pca9450: add pca9450 pmic driver Robin Gong
                   ` (4 more replies)
  0 siblings, 5 replies; 9+ messages in thread
From: Robin Gong @ 2020-07-03 16:19 UTC (permalink / raw)
  To: lgirdwood, broonie, robh+dt, frieder.schrempf, catalin.marinas,
	will, shawnguo, anson.huang, festevam, s.hauer, john.lee
  Cc: kernel, devicetree, linux-kernel, linux-arm-kernel, linux-imx

Add pca9450 driver for i.mx8mn-evk board. PCA9450A/B/C supported now.
Please refer to below link for PCA9450 datasheet:
https://www.nxp.com/docs/en/data-sheet/PCA9450DS.pdf

v2:
  1. rebase with the latest code to use linear_ranges helper instead.
  2. address Frieder's comments, such as dulipcated buck4 description,
     debug info added etc.

Robin Gong (4):
  regulator: pca9450: add pca9450 pmic driver
  dt-bindings: regulator: add pca9450 regulator yaml
  arm64: dts: imx8mn-evk: add pca9450 for i.mx8mn-evk board
  arm64: configs: add pca9450 pmic driver

 .../bindings/regulator/nxp,pca9450-regulator.yaml  | 190 +++++
 arch/arm64/boot/dts/freescale/imx8mn-evk.dts       |  96 +++
 arch/arm64/boot/dts/freescale/imx8mn-evk.dtsi      |   6 +
 arch/arm64/configs/defconfig                       |   1 +
 drivers/regulator/Kconfig                          |   8 +
 drivers/regulator/Makefile                         |   1 +
 drivers/regulator/pca9450-regulator.c              | 859 +++++++++++++++++++++
 include/linux/regulator/pca9450.h                  | 219 ++++++
 8 files changed, 1380 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/regulator/nxp,pca9450-regulator.yaml
 create mode 100644 drivers/regulator/pca9450-regulator.c
 create mode 100644 include/linux/regulator/pca9450.h

-- 
2.7.4


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

* [PATCH v2 1/4] regulator: pca9450: add pca9450 pmic driver
  2020-07-03 16:19 [PATCH v2 0/4] Add pca9450 driver Robin Gong
@ 2020-07-03 16:19 ` Robin Gong
  2020-07-06  8:02   ` Frieder Schrempf
  2020-07-03 16:19 ` [PATCH v2 2/4] dt-bindings: regulator: add pca9450 regulator yaml Robin Gong
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 9+ messages in thread
From: Robin Gong @ 2020-07-03 16:19 UTC (permalink / raw)
  To: lgirdwood, broonie, robh+dt, frieder.schrempf, catalin.marinas,
	will, shawnguo, anson.huang, festevam, s.hauer, john.lee
  Cc: kernel, devicetree, linux-kernel, linux-arm-kernel, linux-imx

Add NXP pca9450 pmic driver.

Signed-off-by: Robin Gong <yibin.gong@nxp.com>
---
 drivers/regulator/Kconfig             |   8 +
 drivers/regulator/Makefile            |   1 +
 drivers/regulator/pca9450-regulator.c | 843 ++++++++++++++++++++++++++++++++++
 include/linux/regulator/pca9450.h     | 219 +++++++++
 4 files changed, 1071 insertions(+)
 create mode 100644 drivers/regulator/pca9450-regulator.c
 create mode 100644 include/linux/regulator/pca9450.h

diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index f60eeaa..f992a17 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -740,6 +740,14 @@ config REGULATOR_PBIAS
 	 This driver provides support for OMAP pbias modelled
 	 regulators.
 
+config REGULATOR_PCA9450
+	tristate "NXP PCA9450A/PCA9450B/PCA9450C regulator driver"
+	depends on I2C
+	select REGMAP_I2C
+	help
+	  Say y here to support the NXP PCA9450A/PCA9450B/PCA9450C PMIC
+	  regulator driver.
+
 config REGULATOR_PCAP
 	tristate "Motorola PCAP2 regulator driver"
 	depends on EZX_PCAP
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 5ce7350..ff524922 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -94,6 +94,7 @@ obj-$(CONFIG_REGULATOR_QCOM_RPMH) += qcom-rpmh-regulator.o
 obj-$(CONFIG_REGULATOR_QCOM_SMD_RPM) += qcom_smd-regulator.o
 obj-$(CONFIG_REGULATOR_QCOM_SPMI) += qcom_spmi-regulator.o
 obj-$(CONFIG_REGULATOR_PALMAS) += palmas-regulator.o
+obj-$(CONFIG_REGULATOR_PCA9450) += pca9450-regulator.o
 obj-$(CONFIG_REGULATOR_PFUZE100) += pfuze100-regulator.o
 obj-$(CONFIG_REGULATOR_PV88060) += pv88060-regulator.o
 obj-$(CONFIG_REGULATOR_PV88080) += pv88080-regulator.o
diff --git a/drivers/regulator/pca9450-regulator.c b/drivers/regulator/pca9450-regulator.c
new file mode 100644
index 00000000..0225045
--- /dev/null
+++ b/drivers/regulator/pca9450-regulator.c
@@ -0,0 +1,843 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2020 NXP.
+ * NXP PCA9450 pmic driver
+ */
+
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/of_regulator.h>
+#include <linux/regulator/pca9450.h>
+
+struct pc9450_dvs_config {
+	unsigned int run_reg; /* dvs0 */
+	unsigned int run_mask;
+	unsigned int standby_reg; /* dvs1 */
+	unsigned int standby_mask;
+};
+
+struct pca9450_regulator_desc {
+	struct regulator_desc desc;
+	const struct pc9450_dvs_config dvs;
+};
+
+struct pca9450 {
+	struct device *dev;
+	struct regmap *regmap;
+	enum pca9450_chip_type type;
+	unsigned int rcnt;
+	int irq;
+};
+
+static const struct regmap_range pca9450_status_range = {
+	.range_min = PCA9450_REG_INT1,
+	.range_max = PCA9450_REG_PWRON_STAT,
+};
+
+static const struct regmap_access_table pca9450_volatile_regs = {
+	.yes_ranges = &pca9450_status_range,
+	.n_yes_ranges = 1,
+};
+
+static const struct regmap_config pca9450_regmap_config = {
+	.reg_bits = 8,
+	.val_bits = 8,
+	.volatile_table = &pca9450_volatile_regs,
+	.max_register = PCA9450_MAX_REGISTER - 1,
+	.cache_type = REGCACHE_RBTREE,
+};
+
+/*
+ * BUCK1/2/3
+ * BUCK1RAM[1:0] BUCK1 DVS ramp rate setting
+ * 00: 25mV/1usec
+ * 01: 25mV/2usec
+ * 10: 25mV/4usec
+ * 11: 25mV/8usec
+ */
+static int pca9450_dvs_set_ramp_delay(struct regulator_dev *rdev,
+				      int ramp_delay)
+{
+	int id = rdev_get_id(rdev);
+	unsigned int ramp_value;
+
+	switch (ramp_delay) {
+	case 1 ... 3125:
+		ramp_value = BUCK1_RAMP_3P125MV;
+		break;
+	case 3126 ... 6250:
+		ramp_value = BUCK1_RAMP_6P25MV;
+		break;
+	case 6251 ... 12500:
+		ramp_value = BUCK1_RAMP_12P5MV;
+		break;
+	case 12501 ... 25000:
+		ramp_value = BUCK1_RAMP_25MV;
+		break;
+	default:
+		ramp_value = BUCK1_RAMP_25MV;
+	}
+
+	return regmap_update_bits(rdev->regmap, PCA9450_REG_BUCK1CTRL + id * 3,
+				  BUCK1_RAMP_MASK, ramp_value << 6);
+}
+
+static struct regulator_ops pca9450_dvs_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 = 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 = pca9450_dvs_set_ramp_delay,
+};
+
+static struct regulator_ops pca9450_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 = regulator_set_voltage_sel_regmap,
+	.get_voltage_sel = regulator_get_voltage_sel_regmap,
+	.set_voltage_time_sel = regulator_set_voltage_time_sel,
+};
+
+static struct regulator_ops pca9450_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 = regulator_set_voltage_sel_regmap,
+	.get_voltage_sel = regulator_get_voltage_sel_regmap,
+};
+
+/*
+ * BUCK1/2/3
+ * 0.60 to 2.1875V (12.5mV step)
+ */
+static const struct linear_range pca9450_dvs_buck_volts[] = {
+	REGULATOR_LINEAR_RANGE(600000,  0x00, 0x7F, 12500),
+};
+
+/*
+ * BUCK4/5/6
+ * 0.6V to 3.4V (25mV step)
+ */
+static const struct linear_range pca9450_buck_volts[] = {
+	REGULATOR_LINEAR_RANGE(600000, 0x00, 0x70, 25000),
+	REGULATOR_LINEAR_RANGE(3400000, 0x71, 0x7F, 0),
+};
+
+/*
+ * LDO1
+ * 1.6 to 3.3V ()
+ */
+static const struct linear_range pca9450_ldo1_volts[] = {
+	REGULATOR_LINEAR_RANGE(1600000, 0x00, 0x03, 100000),
+	REGULATOR_LINEAR_RANGE(3000000, 0x04, 0x07, 100000),
+};
+
+/*
+ * LDO2
+ * 0.8 to 1.15V (50mV step)
+ */
+static const struct linear_range pca9450_ldo2_volts[] = {
+	REGULATOR_LINEAR_RANGE(800000, 0x00, 0x07, 50000),
+};
+
+/*
+ * LDO3/4
+ * 0.8 to 3.3V (100mV step)
+ */
+static const struct linear_range pca9450_ldo34_volts[] = {
+	REGULATOR_LINEAR_RANGE(800000, 0x00, 0x19, 100000),
+	REGULATOR_LINEAR_RANGE(3300000, 0x1A, 0x1F, 0),
+};
+
+/*
+ * LDO5
+ * 1.8 to 3.3V (100mV step)
+ */
+static const struct linear_range pca9450_ldo5_volts[] = {
+	REGULATOR_LINEAR_RANGE(1800000,  0x00, 0x0F, 100000),
+};
+
+static int buck_set_dvs(const struct regulator_desc *desc,
+			struct device_node *np, struct regmap *regmap,
+			char *prop, unsigned int reg, unsigned int mask)
+{
+	int ret, i;
+	uint32_t uv;
+
+	ret = of_property_read_u32(np, prop, &uv);
+	if (ret == -EINVAL)
+		return 0;
+	else if (ret)
+		return ret;
+
+	for (i = 0; i < desc->n_voltages; i++) {
+		ret = regulator_desc_list_voltage_linear_range(desc, i);
+		if (ret < 0)
+			continue;
+		if (ret == uv) {
+			i <<= ffs(desc->vsel_mask) - 1;
+			ret = regmap_update_bits(regmap, reg, mask, i);
+			break;
+		}
+	}
+
+	return ret;
+}
+
+static int pca9450_set_dvs_levels(struct device_node *np,
+			    const struct regulator_desc *desc,
+			    struct regulator_config *cfg)
+{
+	struct pca9450_regulator_desc *data = container_of(desc,
+					struct pca9450_regulator_desc, desc);
+	const struct pc9450_dvs_config *dvs = &data->dvs;
+	unsigned int reg, mask;
+	char *prop;
+	int i, ret = 0;
+
+	for (i = 0; i < PCA9450_DVS_LEVEL_MAX; i++) {
+		switch (i) {
+		case PCA9450_DVS_LEVEL_RUN:
+			prop = "nxp,dvs-run-voltage";
+			reg = dvs->run_reg;
+			mask = dvs->run_mask;
+			break;
+		case PCA9450_DVS_LEVEL_STANDBY:
+			prop = "nxp,dvs-standby-voltage";
+			reg = dvs->standby_reg;
+			mask = dvs->standby_mask;
+			break;
+		default:
+			return -EINVAL;
+		}
+
+		ret = buck_set_dvs(desc, np, cfg->regmap, prop, reg, mask);
+		if (ret)
+			break;
+	}
+
+	return ret;
+}
+
+static const struct pca9450_regulator_desc pca9450a_regulators[] = {
+	{
+		.desc = {
+			.name = "buck1",
+			.of_match = of_match_ptr("BUCK1"),
+			.regulators_node = of_match_ptr("regulators"),
+			.id = PCA9450_BUCK1,
+			.ops = &pca9450_dvs_buck_regulator_ops,
+			.type = REGULATOR_VOLTAGE,
+			.n_voltages = PCA9450_BUCK1_VOLTAGE_NUM,
+			.linear_ranges = pca9450_dvs_buck_volts,
+			.n_linear_ranges = ARRAY_SIZE(pca9450_dvs_buck_volts),
+			.vsel_reg = PCA9450_REG_BUCK1OUT_DVS0,
+			.vsel_mask = BUCK1OUT_DVS0_MASK,
+			.enable_reg = PCA9450_REG_BUCK1CTRL,
+			.enable_mask = BUCK1_ENMODE_MASK,
+			.owner = THIS_MODULE,
+			.of_parse_cb = pca9450_set_dvs_levels,
+		},
+		.dvs = {
+			.run_reg = PCA9450_REG_BUCK1OUT_DVS0,
+			.run_mask = BUCK1OUT_DVS0_MASK,
+			.standby_reg = PCA9450_REG_BUCK1OUT_DVS1,
+			.standby_mask = BUCK1OUT_DVS1_MASK,
+		},
+	},
+	{
+		.desc = {
+			.name = "buck2",
+			.of_match = of_match_ptr("BUCK2"),
+			.regulators_node = of_match_ptr("regulators"),
+			.id = PCA9450_BUCK2,
+			.ops = &pca9450_dvs_buck_regulator_ops,
+			.type = REGULATOR_VOLTAGE,
+			.n_voltages = PCA9450_BUCK2_VOLTAGE_NUM,
+			.linear_ranges = pca9450_dvs_buck_volts,
+			.n_linear_ranges = ARRAY_SIZE(pca9450_dvs_buck_volts),
+			.vsel_reg = PCA9450_REG_BUCK2OUT_DVS0,
+			.vsel_mask = BUCK2OUT_DVS0_MASK,
+			.enable_reg = PCA9450_REG_BUCK2CTRL,
+			.enable_mask = BUCK1_ENMODE_MASK,
+			.owner = THIS_MODULE,
+			.of_parse_cb = pca9450_set_dvs_levels,
+		},
+		.dvs = {
+			.run_reg = PCA9450_REG_BUCK2OUT_DVS0,
+			.run_mask = BUCK2OUT_DVS0_MASK,
+			.standby_reg = PCA9450_REG_BUCK2OUT_DVS1,
+			.standby_mask = BUCK2OUT_DVS1_MASK,
+		},
+	},
+	{
+		.desc = {
+			.name = "buck3",
+			.of_match = of_match_ptr("BUCK3"),
+			.regulators_node = of_match_ptr("regulators"),
+			.id = PCA9450_BUCK3,
+			.ops = &pca9450_dvs_buck_regulator_ops,
+			.type = REGULATOR_VOLTAGE,
+			.n_voltages = PCA9450_BUCK3_VOLTAGE_NUM,
+			.linear_ranges = pca9450_dvs_buck_volts,
+			.n_linear_ranges = ARRAY_SIZE(pca9450_dvs_buck_volts),
+			.vsel_reg = PCA9450_REG_BUCK3OUT_DVS0,
+			.vsel_mask = BUCK3OUT_DVS0_MASK,
+			.enable_reg = PCA9450_REG_BUCK3CTRL,
+			.enable_mask = BUCK3_ENMODE_MASK,
+			.owner = THIS_MODULE,
+			.of_parse_cb = pca9450_set_dvs_levels,
+		},
+		.dvs = {
+			.run_reg = PCA9450_REG_BUCK3OUT_DVS0,
+			.run_mask = BUCK3OUT_DVS0_MASK,
+			.standby_reg = PCA9450_REG_BUCK3OUT_DVS1,
+			.standby_mask = BUCK3OUT_DVS1_MASK,
+		},
+	},
+	{
+		.desc = {
+			.name = "buck4",
+			.of_match = of_match_ptr("BUCK4"),
+			.regulators_node = of_match_ptr("regulators"),
+			.id = PCA9450_BUCK4,
+			.ops = &pca9450_buck_regulator_ops,
+			.type = REGULATOR_VOLTAGE,
+			.n_voltages = PCA9450_BUCK4_VOLTAGE_NUM,
+			.linear_ranges = pca9450_buck_volts,
+			.n_linear_ranges = ARRAY_SIZE(pca9450_buck_volts),
+			.vsel_reg = PCA9450_REG_BUCK4OUT,
+			.vsel_mask = BUCK4OUT_MASK,
+			.enable_reg = PCA9450_REG_BUCK4CTRL,
+			.enable_mask = BUCK4_ENMODE_MASK,
+			.owner = THIS_MODULE,
+		},
+	},
+	{
+		.desc = {
+			.name = "buck5",
+			.of_match = of_match_ptr("BUCK5"),
+			.regulators_node = of_match_ptr("regulators"),
+			.id = PCA9450_BUCK5,
+			.ops = &pca9450_buck_regulator_ops,
+			.type = REGULATOR_VOLTAGE,
+			.n_voltages = PCA9450_BUCK5_VOLTAGE_NUM,
+			.linear_ranges = pca9450_buck_volts,
+			.n_linear_ranges = ARRAY_SIZE(pca9450_buck_volts),
+			.vsel_reg = PCA9450_REG_BUCK5OUT,
+			.vsel_mask = BUCK5OUT_MASK,
+			.enable_reg = PCA9450_REG_BUCK5CTRL,
+			.enable_mask = BUCK5_ENMODE_MASK,
+			.owner = THIS_MODULE,
+		},
+	},
+	{
+		.desc = {
+			.name = "buck6",
+			.of_match = of_match_ptr("BUCK6"),
+			.regulators_node = of_match_ptr("regulators"),
+			.id = PCA9450_BUCK6,
+			.ops = &pca9450_buck_regulator_ops,
+			.type = REGULATOR_VOLTAGE,
+			.n_voltages = PCA9450_BUCK6_VOLTAGE_NUM,
+			.linear_ranges = pca9450_buck_volts,
+			.n_linear_ranges = ARRAY_SIZE(pca9450_buck_volts),
+			.vsel_reg = PCA9450_REG_BUCK6OUT,
+			.vsel_mask = BUCK6OUT_MASK,
+			.enable_reg = PCA9450_REG_BUCK6CTRL,
+			.enable_mask = BUCK6_ENMODE_MASK,
+			.owner = THIS_MODULE,
+		},
+	},
+	{
+		.desc = {
+			.name = "ldo1",
+			.of_match = of_match_ptr("LDO1"),
+			.regulators_node = of_match_ptr("regulators"),
+			.id = PCA9450_LDO1,
+			.ops = &pca9450_ldo_regulator_ops,
+			.type = REGULATOR_VOLTAGE,
+			.n_voltages = PCA9450_LDO1_VOLTAGE_NUM,
+			.linear_ranges = pca9450_ldo1_volts,
+			.n_linear_ranges = ARRAY_SIZE(pca9450_ldo1_volts),
+			.vsel_reg = PCA9450_REG_LDO1CTRL,
+			.vsel_mask = LDO1OUT_MASK,
+			.enable_reg = PCA9450_REG_LDO1CTRL,
+			.enable_mask = LDO1_EN_MASK,
+			.owner = THIS_MODULE,
+		},
+	},
+	{
+		.desc = {
+			.name = "ldo2",
+			.of_match = of_match_ptr("LDO2"),
+			.regulators_node = of_match_ptr("regulators"),
+			.id = PCA9450_LDO2,
+			.ops = &pca9450_ldo_regulator_ops,
+			.type = REGULATOR_VOLTAGE,
+			.n_voltages = PCA9450_LDO2_VOLTAGE_NUM,
+			.linear_ranges = pca9450_ldo2_volts,
+			.n_linear_ranges = ARRAY_SIZE(pca9450_ldo2_volts),
+			.vsel_reg = PCA9450_REG_LDO2CTRL,
+			.vsel_mask = LDO2OUT_MASK,
+			.enable_reg = PCA9450_REG_LDO2CTRL,
+			.enable_mask = LDO2_EN_MASK,
+			.owner = THIS_MODULE,
+		},
+	},
+	{
+		.desc = {
+			.name = "ldo3",
+			.of_match = of_match_ptr("LDO3"),
+			.regulators_node = of_match_ptr("regulators"),
+			.id = PCA9450_LDO3,
+			.ops = &pca9450_ldo_regulator_ops,
+			.type = REGULATOR_VOLTAGE,
+			.n_voltages = PCA9450_LDO3_VOLTAGE_NUM,
+			.linear_ranges = pca9450_ldo34_volts,
+			.n_linear_ranges = ARRAY_SIZE(pca9450_ldo34_volts),
+			.vsel_reg = PCA9450_REG_LDO3CTRL,
+			.vsel_mask = LDO3OUT_MASK,
+			.enable_reg = PCA9450_REG_LDO3CTRL,
+			.enable_mask = LDO3_EN_MASK,
+			.owner = THIS_MODULE,
+		},
+	},
+	{
+		.desc = {
+			.name = "ldo4",
+			.of_match = of_match_ptr("LDO4"),
+			.regulators_node = of_match_ptr("regulators"),
+			.id = PCA9450_LDO4,
+			.ops = &pca9450_ldo_regulator_ops,
+			.type = REGULATOR_VOLTAGE,
+			.n_voltages = PCA9450_LDO4_VOLTAGE_NUM,
+			.linear_ranges = pca9450_ldo34_volts,
+			.n_linear_ranges = ARRAY_SIZE(pca9450_ldo34_volts),
+			.vsel_reg = PCA9450_REG_LDO4CTRL,
+			.vsel_mask = LDO4OUT_MASK,
+			.enable_reg = PCA9450_REG_LDO4CTRL,
+			.enable_mask = LDO4_EN_MASK,
+			.owner = THIS_MODULE,
+		},
+	},
+	{
+		.desc = {
+			.name = "ldo5",
+			.of_match = of_match_ptr("LDO5"),
+			.regulators_node = of_match_ptr("regulators"),
+			.id = PCA9450_LDO5,
+			.ops = &pca9450_ldo_regulator_ops,
+			.type = REGULATOR_VOLTAGE,
+			.n_voltages = PCA9450_LDO5_VOLTAGE_NUM,
+			.linear_ranges = pca9450_ldo5_volts,
+			.n_linear_ranges = ARRAY_SIZE(pca9450_ldo5_volts),
+			.vsel_reg = PCA9450_REG_LDO5CTRL_H,
+			.vsel_mask = LDO5HOUT_MASK,
+			.enable_reg = PCA9450_REG_LDO5CTRL_H,
+			.enable_mask = LDO5H_EN_MASK,
+			.owner = THIS_MODULE,
+		},
+	},
+};
+
+/*
+ * Buck3 removed on PCA9450B and connected with Buck1 internal for dual phase
+ * on PCA9450C as no Buck3.
+ */
+static const struct pca9450_regulator_desc pca9450bc_regulators[] = {
+	{
+		.desc = {
+			.name = "buck1",
+			.of_match = of_match_ptr("BUCK1"),
+			.regulators_node = of_match_ptr("regulators"),
+			.id = PCA9450_BUCK1,
+			.ops = &pca9450_dvs_buck_regulator_ops,
+			.type = REGULATOR_VOLTAGE,
+			.n_voltages = PCA9450_BUCK1_VOLTAGE_NUM,
+			.linear_ranges = pca9450_dvs_buck_volts,
+			.n_linear_ranges = ARRAY_SIZE(pca9450_dvs_buck_volts),
+			.vsel_reg = PCA9450_REG_BUCK1OUT_DVS0,
+			.vsel_mask = BUCK1OUT_DVS0_MASK,
+			.enable_reg = PCA9450_REG_BUCK1CTRL,
+			.enable_mask = BUCK1_ENMODE_MASK,
+			.owner = THIS_MODULE,
+			.of_parse_cb = pca9450_set_dvs_levels,
+		},
+		.dvs = {
+			.run_reg = PCA9450_REG_BUCK1OUT_DVS0,
+			.run_mask = BUCK1OUT_DVS0_MASK,
+			.standby_reg = PCA9450_REG_BUCK1OUT_DVS1,
+			.standby_mask = BUCK1OUT_DVS1_MASK,
+		},
+	},
+	{
+		.desc = {
+			.name = "buck2",
+			.of_match = of_match_ptr("BUCK2"),
+			.regulators_node = of_match_ptr("regulators"),
+			.id = PCA9450_BUCK2,
+			.ops = &pca9450_dvs_buck_regulator_ops,
+			.type = REGULATOR_VOLTAGE,
+			.n_voltages = PCA9450_BUCK2_VOLTAGE_NUM,
+			.linear_ranges = pca9450_dvs_buck_volts,
+			.n_linear_ranges = ARRAY_SIZE(pca9450_dvs_buck_volts),
+			.vsel_reg = PCA9450_REG_BUCK2OUT_DVS0,
+			.vsel_mask = BUCK2OUT_DVS0_MASK,
+			.enable_reg = PCA9450_REG_BUCK2CTRL,
+			.enable_mask = BUCK1_ENMODE_MASK,
+			.owner = THIS_MODULE,
+			.of_parse_cb = pca9450_set_dvs_levels,
+		},
+		.dvs = {
+			.run_reg = PCA9450_REG_BUCK2OUT_DVS0,
+			.run_mask = BUCK2OUT_DVS0_MASK,
+			.standby_reg = PCA9450_REG_BUCK2OUT_DVS1,
+			.standby_mask = BUCK2OUT_DVS1_MASK,
+		},
+	},
+	{
+		.desc = {
+			.name = "buck4",
+			.of_match = of_match_ptr("BUCK4"),
+			.regulators_node = of_match_ptr("regulators"),
+			.id = PCA9450_BUCK4,
+			.ops = &pca9450_buck_regulator_ops,
+			.type = REGULATOR_VOLTAGE,
+			.n_voltages = PCA9450_BUCK4_VOLTAGE_NUM,
+			.linear_ranges = pca9450_buck_volts,
+			.n_linear_ranges = ARRAY_SIZE(pca9450_buck_volts),
+			.vsel_reg = PCA9450_REG_BUCK4OUT,
+			.vsel_mask = BUCK4OUT_MASK,
+			.enable_reg = PCA9450_REG_BUCK4CTRL,
+			.enable_mask = BUCK4_ENMODE_MASK,
+			.owner = THIS_MODULE,
+		},
+	},
+	{
+		.desc = {
+			.name = "buck5",
+			.of_match = of_match_ptr("BUCK5"),
+			.regulators_node = of_match_ptr("regulators"),
+			.id = PCA9450_BUCK5,
+			.ops = &pca9450_buck_regulator_ops,
+			.type = REGULATOR_VOLTAGE,
+			.n_voltages = PCA9450_BUCK5_VOLTAGE_NUM,
+			.linear_ranges = pca9450_buck_volts,
+			.n_linear_ranges = ARRAY_SIZE(pca9450_buck_volts),
+			.vsel_reg = PCA9450_REG_BUCK5OUT,
+			.vsel_mask = BUCK5OUT_MASK,
+			.enable_reg = PCA9450_REG_BUCK5CTRL,
+			.enable_mask = BUCK5_ENMODE_MASK,
+			.owner = THIS_MODULE,
+		},
+	},
+	{
+		.desc = {
+			.name = "buck6",
+			.of_match = of_match_ptr("BUCK6"),
+			.regulators_node = of_match_ptr("regulators"),
+			.id = PCA9450_BUCK6,
+			.ops = &pca9450_buck_regulator_ops,
+			.type = REGULATOR_VOLTAGE,
+			.n_voltages = PCA9450_BUCK6_VOLTAGE_NUM,
+			.linear_ranges = pca9450_buck_volts,
+			.n_linear_ranges = ARRAY_SIZE(pca9450_buck_volts),
+			.vsel_reg = PCA9450_REG_BUCK6OUT,
+			.vsel_mask = BUCK6OUT_MASK,
+			.enable_reg = PCA9450_REG_BUCK6CTRL,
+			.enable_mask = BUCK6_ENMODE_MASK,
+			.owner = THIS_MODULE,
+		},
+	},
+	{
+		.desc = {
+			.name = "ldo1",
+			.of_match = of_match_ptr("LDO1"),
+			.regulators_node = of_match_ptr("regulators"),
+			.id = PCA9450_LDO1,
+			.ops = &pca9450_ldo_regulator_ops,
+			.type = REGULATOR_VOLTAGE,
+			.n_voltages = PCA9450_LDO1_VOLTAGE_NUM,
+			.linear_ranges = pca9450_ldo1_volts,
+			.n_linear_ranges = ARRAY_SIZE(pca9450_ldo1_volts),
+			.vsel_reg = PCA9450_REG_LDO1CTRL,
+			.vsel_mask = LDO1OUT_MASK,
+			.enable_reg = PCA9450_REG_LDO1CTRL,
+			.enable_mask = LDO1_EN_MASK,
+			.owner = THIS_MODULE,
+		},
+	},
+	{
+		.desc = {
+			.name = "ldo2",
+			.of_match = of_match_ptr("LDO2"),
+			.regulators_node = of_match_ptr("regulators"),
+			.id = PCA9450_LDO2,
+			.ops = &pca9450_ldo_regulator_ops,
+			.type = REGULATOR_VOLTAGE,
+			.n_voltages = PCA9450_LDO2_VOLTAGE_NUM,
+			.linear_ranges = pca9450_ldo2_volts,
+			.n_linear_ranges = ARRAY_SIZE(pca9450_ldo2_volts),
+			.vsel_reg = PCA9450_REG_LDO2CTRL,
+			.vsel_mask = LDO2OUT_MASK,
+			.enable_reg = PCA9450_REG_LDO2CTRL,
+			.enable_mask = LDO2_EN_MASK,
+			.owner = THIS_MODULE,
+		},
+	},
+	{
+		.desc = {
+			.name = "ldo3",
+			.of_match = of_match_ptr("LDO3"),
+			.regulators_node = of_match_ptr("regulators"),
+			.id = PCA9450_LDO3,
+			.ops = &pca9450_ldo_regulator_ops,
+			.type = REGULATOR_VOLTAGE,
+			.n_voltages = PCA9450_LDO3_VOLTAGE_NUM,
+			.linear_ranges = pca9450_ldo34_volts,
+			.n_linear_ranges = ARRAY_SIZE(pca9450_ldo34_volts),
+			.vsel_reg = PCA9450_REG_LDO3CTRL,
+			.vsel_mask = LDO3OUT_MASK,
+			.enable_reg = PCA9450_REG_LDO3CTRL,
+			.enable_mask = LDO3_EN_MASK,
+			.owner = THIS_MODULE,
+		},
+	},
+	{
+		.desc = {
+			.name = "ldo4",
+			.of_match = of_match_ptr("LDO4"),
+			.regulators_node = of_match_ptr("regulators"),
+			.id = PCA9450_LDO4,
+			.ops = &pca9450_ldo_regulator_ops,
+			.type = REGULATOR_VOLTAGE,
+			.n_voltages = PCA9450_LDO4_VOLTAGE_NUM,
+			.linear_ranges = pca9450_ldo34_volts,
+			.n_linear_ranges = ARRAY_SIZE(pca9450_ldo34_volts),
+			.vsel_reg = PCA9450_REG_LDO4CTRL,
+			.vsel_mask = LDO4OUT_MASK,
+			.enable_reg = PCA9450_REG_LDO4CTRL,
+			.enable_mask = LDO4_EN_MASK,
+			.owner = THIS_MODULE,
+		},
+	},
+	{
+		.desc = {
+			.name = "ldo5",
+			.of_match = of_match_ptr("LDO5"),
+			.regulators_node = of_match_ptr("regulators"),
+			.id = PCA9450_LDO5,
+			.ops = &pca9450_ldo_regulator_ops,
+			.type = REGULATOR_VOLTAGE,
+			.n_voltages = PCA9450_LDO5_VOLTAGE_NUM,
+			.linear_ranges = pca9450_ldo5_volts,
+			.n_linear_ranges = ARRAY_SIZE(pca9450_ldo5_volts),
+			.vsel_reg = PCA9450_REG_LDO5CTRL_H,
+			.vsel_mask = LDO5HOUT_MASK,
+			.enable_reg = PCA9450_REG_LDO5CTRL_H,
+			.enable_mask = LDO5H_EN_MASK,
+			.owner = THIS_MODULE,
+		},
+	},
+};
+
+static irqreturn_t pca9450_irq_handler(int irq, void *data)
+{
+	struct pca9450 *pca9450 = data;
+	struct regmap *regmap = pca9450->regmap;
+	unsigned int status;
+	int ret;
+
+	ret = regmap_read(regmap, PCA9450_REG_INT1, &status);
+	if (ret < 0) {
+		dev_err(pca9450->dev,
+			"Failed to read INT1(%d)\n", ret);
+		return IRQ_NONE;
+	}
+
+	if (status & IRQ_PWRON)
+		dev_warn(pca9450->dev, "PWRON interrupt.\n");
+
+	if (status & IRQ_WDOGB)
+		dev_warn(pca9450->dev, "WDOGB interrupt.\n");
+
+	if (status & IRQ_VR_FLT1)
+		dev_warn(pca9450->dev, "VRFLT1 interrupt.\n");
+
+	if (status & IRQ_VR_FLT2)
+		dev_warn(pca9450->dev, "VRFLT2 interrupt.\n");
+
+	if (status & IRQ_LOWVSYS)
+		dev_warn(pca9450->dev, "LOWVSYS interrupt.\n");
+
+	if (status & IRQ_THERM_105)
+		dev_warn(pca9450->dev, "IRQ_THERM_105 interrupt.\n");
+
+	if (status & IRQ_THERM_125)
+		dev_warn(pca9450->dev, "IRQ_THERM_125 interrupt.\n");
+
+	return IRQ_HANDLED;
+}
+
+static int pca9450_i2c_probe(struct i2c_client *i2c,
+			     const struct i2c_device_id *id)
+{
+	enum pca9450_chip_type type = (unsigned int)(uintptr_t)
+				      of_device_get_match_data(&i2c->dev);
+	const struct pca9450_regulator_desc	*regulator_desc;
+	struct regulator_config config = { };
+	struct pca9450 *pca9450;
+	unsigned int device_id, i;
+	int ret;
+
+	if (!i2c->irq) {
+		dev_err(&i2c->dev, "No IRQ configured?\n");
+		return -EINVAL;
+	}
+
+	pca9450 = devm_kzalloc(&i2c->dev, sizeof(struct pca9450), GFP_KERNEL);
+	if (!pca9450)
+		return -ENOMEM;
+
+	switch (type) {
+	case PCA9450_TYPE_PCA9450A:
+		regulator_desc = pca9450a_regulators;
+		pca9450->rcnt = ARRAY_SIZE(pca9450a_regulators);
+		break;
+	case PCA9450_TYPE_PCA9450BC:
+		regulator_desc = pca9450bc_regulators;
+		pca9450->rcnt = ARRAY_SIZE(pca9450bc_regulators);
+		break;
+	default:
+		dev_err(&i2c->dev, "Unknown device type");
+		return -EINVAL;
+	}
+
+	pca9450->irq = i2c->irq;
+	pca9450->type = type;
+	pca9450->dev = &i2c->dev;
+
+	dev_set_drvdata(&i2c->dev, pca9450);
+
+	pca9450->regmap = devm_regmap_init_i2c(i2c,
+					       &pca9450_regmap_config);
+	if (IS_ERR(pca9450->regmap)) {
+		dev_err(&i2c->dev, "regmap initialization failed\n");
+		return PTR_ERR(pca9450->regmap);
+	}
+
+	ret = regmap_read(pca9450->regmap, PCA9450_REG_DEV_ID, &device_id);
+	if (ret) {
+		dev_err(&i2c->dev, "Read device id error\n");
+		return ret;
+	}
+
+	/* Check your board and dts for match the right pmic */
+	if (((device_id >> 4) != 0x1 && type == PCA9450_TYPE_PCA9450A) ||
+	    ((device_id >> 4) != 0x3 && type == PCA9450_TYPE_PCA9450BC)) {
+		dev_err(&i2c->dev, "Device id(%x) mismatched\n",
+			device_id >> 4);
+		return -EINVAL;
+	}
+
+	for (i = 0; i < pca9450->rcnt; i++) {
+		const struct regulator_desc *desc;
+		struct regulator_dev *rdev;
+		const struct pca9450_regulator_desc *r;
+
+		r = &regulator_desc[i];
+		desc = &r->desc;
+
+		config.regmap = pca9450->regmap;
+		config.dev = pca9450->dev;
+
+		rdev = devm_regulator_register(pca9450->dev, desc, &config);
+		if (IS_ERR(rdev)) {
+			ret = PTR_ERR(rdev);
+			dev_err(pca9450->dev,
+				"Failed to register regulator(%s): %d\n",
+				desc->name, ret);
+			return ret;
+		}
+	}
+
+	ret = devm_request_threaded_irq(pca9450->dev, pca9450->irq, NULL,
+					pca9450_irq_handler,
+					(IRQF_TRIGGER_FALLING | IRQF_ONESHOT),
+					"pca9450-irq", pca9450);
+	if (ret != 0) {
+		dev_err(pca9450->dev, "Failed to request IRQ: %d\n",
+			pca9450->irq);
+		return ret;
+	}
+	/* Unmask all interrupt except PWRON/WDOG/RSVD */
+	ret = regmap_update_bits(pca9450->regmap, PCA9450_REG_INT1_MSK,
+				IRQ_VR_FLT1 | IRQ_VR_FLT2 | IRQ_LOWVSYS |
+				IRQ_THERM_105 | IRQ_THERM_125,
+				IRQ_PWRON | IRQ_WDOGB | IRQ_RSVD);
+	if (ret) {
+		dev_err(&i2c->dev, "Unmask irq error\n");
+		return ret;
+	}
+
+	dev_info(&i2c->dev, "%s probed.\n",
+		type == PCA9450_TYPE_PCA9450A ? "pca9450a" : "pca9450bc");
+
+	return 0;
+}
+
+static const struct of_device_id pca9450_of_match[] = {
+	{
+		.compatible = "nxp,pca9450a",
+		.data = (void *)PCA9450_TYPE_PCA9450A,
+	},
+	{
+		.compatible = "nxp,pca9450b",
+		.data = (void *)PCA9450_TYPE_PCA9450BC,
+	},
+	{
+		.compatible = "nxp,pca9450c",
+		.data = (void *)PCA9450_TYPE_PCA9450BC,
+	},
+	{ }
+};
+MODULE_DEVICE_TABLE(of, pca9450_of_match);
+
+static struct i2c_driver pca9450_i2c_driver = {
+	.driver = {
+		.name = "nxp-pca9450",
+		.of_match_table = pca9450_of_match,
+	},
+	.probe = pca9450_i2c_probe,
+};
+
+static int __init pca9450_i2c_init(void)
+{
+	return i2c_add_driver(&pca9450_i2c_driver);
+}
+module_init(pca9450_i2c_init);
+
+static void __exit pca9450_i2c_exit(void)
+{
+	i2c_del_driver(&pca9450_i2c_driver);
+}
+module_exit(pca9450_i2c_exit);
+
+MODULE_AUTHOR("Robin Gong <yibin.gong@nxp.com>");
+MODULE_DESCRIPTION("NXP PCA9450 Power Management IC driver");
+MODULE_LICENSE("GPL");
diff --git a/include/linux/regulator/pca9450.h b/include/linux/regulator/pca9450.h
new file mode 100644
index 00000000..1bbd301
--- /dev/null
+++ b/include/linux/regulator/pca9450.h
@@ -0,0 +1,219 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/* Copyright 2020 NXP. */
+
+#ifndef __LINUX_REG_PCA9450_H__
+#define __LINUX_REG_PCA9450_H__
+
+#include <linux/regmap.h>
+
+enum pca9450_chip_type {
+	PCA9450_TYPE_PCA9450A = 0,
+	PCA9450_TYPE_PCA9450BC,
+	PCA9450_TYPE_AMOUNT,
+};
+
+enum {
+	PCA9450_BUCK1 = 0,
+	PCA9450_BUCK2,
+	PCA9450_BUCK3,
+	PCA9450_BUCK4,
+	PCA9450_BUCK5,
+	PCA9450_BUCK6,
+	PCA9450_LDO1,
+	PCA9450_LDO2,
+	PCA9450_LDO3,
+	PCA9450_LDO4,
+	PCA9450_LDO5,
+	PCA9450_REGULATOR_CNT,
+};
+
+enum {
+	PCA9450_DVS_LEVEL_RUN = 0,
+	PCA9450_DVS_LEVEL_STANDBY,
+	PCA9450_DVS_LEVEL_MAX,
+};
+
+#define PCA9450_BUCK1_VOLTAGE_NUM	0x80
+#define PCA9450_BUCK2_VOLTAGE_NUM	0x80
+#define PCA9450_BUCK3_VOLTAGE_NUM	0x80
+#define PCA9450_BUCK4_VOLTAGE_NUM	0x80
+
+#define PCA9450_BUCK5_VOLTAGE_NUM	0x80
+#define PCA9450_BUCK6_VOLTAGE_NUM	0x80
+
+#define PCA9450_LDO1_VOLTAGE_NUM	0x08
+#define PCA9450_LDO2_VOLTAGE_NUM	0x08
+#define PCA9450_LDO3_VOLTAGE_NUM	0x20
+#define PCA9450_LDO4_VOLTAGE_NUM	0x20
+#define PCA9450_LDO5_VOLTAGE_NUM	0x10
+
+enum {
+	PCA9450_REG_DEV_ID	    = 0x00,
+	PCA9450_REG_INT1	    = 0x01,
+	PCA9450_REG_INT1_MSK	    = 0x02,
+	PCA9450_REG_STATUS1	    = 0x03,
+	PCA9450_REG_STATUS2	    = 0x04,
+	PCA9450_REG_PWRON_STAT	    = 0x05,
+	PCA9450_REG_SWRST	    = 0x06,
+	PCA9450_REG_PWRCTRL         = 0x07,
+	PCA9450_REG_RESET_CTRL      = 0x08,
+	PCA9450_REG_CONFIG1         = 0x09,
+	PCA9450_REG_CONFIG2         = 0x0A,
+	PCA9450_REG_BUCK123_DVS     = 0x0C,
+	PCA9450_REG_BUCK1OUT_LIMIT  = 0x0D,
+	PCA9450_REG_BUCK2OUT_LIMIT  = 0x0E,
+	PCA9450_REG_BUCK3OUT_LIMIT  = 0x0F,
+	PCA9450_REG_BUCK1CTRL       = 0x10,
+	PCA9450_REG_BUCK1OUT_DVS0   = 0x11,
+	PCA9450_REG_BUCK1OUT_DVS1   = 0x12,
+	PCA9450_REG_BUCK2CTRL       = 0x13,
+	PCA9450_REG_BUCK2OUT_DVS0   = 0x14,
+	PCA9450_REG_BUCK2OUT_DVS1   = 0x15,
+	PCA9450_REG_BUCK3CTRL       = 0x16,
+	PCA9450_REG_BUCK3OUT_DVS0   = 0x17,
+	PCA9450_REG_BUCK3OUT_DVS1   = 0x18,
+	PCA9450_REG_BUCK4CTRL       = 0x19,
+	PCA9450_REG_BUCK4OUT        = 0x1A,
+	PCA9450_REG_BUCK5CTRL       = 0x1B,
+	PCA9450_REG_BUCK5OUT        = 0x1C,
+	PCA9450_REG_BUCK6CTRL       = 0x1D,
+	PCA9450_REG_BUCK6OUT        = 0x1E,
+	PCA9450_REG_LDO_AD_CTRL     = 0x20,
+	PCA9450_REG_LDO1CTRL        = 0x21,
+	PCA9450_REG_LDO2CTRL        = 0x22,
+	PCA9450_REG_LDO3CTRL        = 0x23,
+	PCA9450_REG_LDO4CTRL        = 0x24,
+	PCA9450_REG_LDO5CTRL_L      = 0x25,
+	PCA9450_REG_LDO5CTRL_H      = 0x26,
+	PCA9450_REG_LOADSW_CTRL     = 0x2A,
+	PCA9450_REG_VRFLT1_STS      = 0x2B,
+	PCA9450_REG_VRFLT2_STS      = 0x2C,
+	PCA9450_REG_VRFLT1_MASK     = 0x2D,
+	PCA9450_REG_VRFLT2_MASK     = 0x2E,
+	PCA9450_MAX_REGISTER	    = 0x2F,
+};
+
+/* PCA9450 BUCK ENMODE bits */
+#define BUCK_ENMODE_OFF			0x00
+#define BUCK_ENMODE_ONREQ		0x01
+#define BUCK_ENMODE_ONREQ_STBYREQ	0x02
+#define BUCK_ENMODE_ON			0x03
+
+/* PCA9450_REG_BUCK1_CTRL bits */
+#define BUCK1_RAMP_MASK			0xC0
+#define BUCK1_RAMP_25MV			0x0
+#define BUCK1_RAMP_12P5MV		0x1
+#define BUCK1_RAMP_6P25MV		0x2
+#define BUCK1_RAMP_3P125MV		0x3
+#define BUCK1_DVS_CTRL			0x10
+#define BUCK1_AD			0x08
+#define BUCK1_FPWM			0x04
+#define BUCK1_ENMODE_MASK		0x03
+
+/* PCA9450_REG_BUCK2_CTRL bits */
+#define BUCK2_RAMP_MASK			0xC0
+#define BUCK2_RAMP_25MV			0x0
+#define BUCK2_RAMP_12P5MV		0x1
+#define BUCK2_RAMP_6P25MV		0x2
+#define BUCK2_RAMP_3P125MV		0x3
+#define BUCK2_DVS_CTRL			0x10
+#define BUCK2_AD			0x08
+#define BUCK2_FPWM			0x04
+#define BUCK2_ENMODE_MASK		0x03
+
+/* PCA9450_REG_BUCK3_CTRL bits */
+#define BUCK3_RAMP_MASK			0xC0
+#define BUCK3_RAMP_25MV			0x0
+#define BUCK3_RAMP_12P5MV		0x1
+#define BUCK3_RAMP_6P25MV		0x2
+#define BUCK3_RAMP_3P125MV		0x3
+#define BUCK3_DVS_CTRL			0x10
+#define BUCK3_AD			0x08
+#define BUCK3_FPWM			0x04
+#define BUCK3_ENMODE_MASK		0x03
+
+/* PCA9450_REG_BUCK4_CTRL bits */
+#define BUCK4_AD			0x08
+#define BUCK4_FPWM			0x04
+#define BUCK4_ENMODE_MASK		0x03
+
+/* PCA9450_REG_BUCK5_CTRL bits */
+#define BUCK5_AD			0x08
+#define BUCK5_FPWM			0x04
+#define BUCK5_ENMODE_MASK		0x03
+
+/* PCA9450_REG_BUCK6_CTRL bits */
+#define BUCK6_AD			0x08
+#define BUCK6_FPWM			0x04
+#define BUCK6_ENMODE_MASK		0x03
+
+/* PCA9450_BUCK1OUT_DVS0 bits */
+#define BUCK1OUT_DVS0_MASK		0x7F
+#define BUCK1OUT_DVS0_DEFAULT		0x14
+
+/* PCA9450_BUCK1OUT_DVS1 bits */
+#define BUCK1OUT_DVS1_MASK		0x7F
+#define BUCK1OUT_DVS1_DEFAULT		0x14
+
+/* PCA9450_BUCK2OUT_DVS0 bits */
+#define BUCK2OUT_DVS0_MASK		0x7F
+#define BUCK2OUT_DVS0_DEFAULT		0x14
+
+/* PCA9450_BUCK2OUT_DVS1 bits */
+#define BUCK2OUT_DVS1_MASK		0x7F
+#define BUCK2OUT_DVS1_DEFAULT		0x14
+
+/* PCA9450_BUCK3OUT_DVS0 bits */
+#define BUCK3OUT_DVS0_MASK		0x7F
+#define BUCK3OUT_DVS0_DEFAULT		0x14
+
+/* PCA9450_BUCK3OUT_DVS1 bits */
+#define BUCK3OUT_DVS1_MASK		0x7F
+#define BUCK3OUT_DVS1_DEFAULT		0x14
+
+/* PCA9450_REG_BUCK4OUT bits */
+#define BUCK4OUT_MASK			0x7F
+#define BUCK4OUT_DEFAULT		0x6C
+
+/* PCA9450_REG_BUCK5OUT bits */
+#define BUCK5OUT_MASK			0x7F
+#define BUCK5OUT_DEFAULT		0x30
+
+/* PCA9450_REG_BUCK6OUT bits */
+#define BUCK6OUT_MASK			0x7F
+#define BUCK6OUT_DEFAULT		0x14
+
+/* PCA9450_REG_LDO1_VOLT bits */
+#define LDO1_EN_MASK			0xC0
+#define LDO1OUT_MASK			0x07
+
+/* PCA9450_REG_LDO2_VOLT bits */
+#define LDO2_EN_MASK			0xC0
+#define LDO2OUT_MASK			0x07
+
+/* PCA9450_REG_LDO3_VOLT bits */
+#define LDO3_EN_MASK			0xC0
+#define LDO3OUT_MASK			0x0F
+
+/* PCA9450_REG_LDO4_VOLT bits */
+#define LDO4_EN_MASK			0xC0
+#define LDO4OUT_MASK			0x0F
+
+/* PCA9450_REG_LDO5_VOLT bits */
+#define LDO5L_EN_MASK			0xC0
+#define LDO5LOUT_MASK			0x0F
+
+#define LDO5H_EN_MASK			0xC0
+#define LDO5HOUT_MASK			0x0F
+
+/* PCA9450_REG_IRQ bits */
+#define IRQ_PWRON			0x80
+#define IRQ_WDOGB			0x40
+#define IRQ_RSVD			0x20
+#define IRQ_VR_FLT1			0x10
+#define IRQ_VR_FLT2			0x08
+#define IRQ_LOWVSYS			0x04
+#define IRQ_THERM_105			0x02
+#define IRQ_THERM_125			0x01
+
+#endif /* __LINUX_REG_PCA9450_H__ */
-- 
2.7.4


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

* [PATCH v2 2/4] dt-bindings: regulator: add pca9450 regulator yaml
  2020-07-03 16:19 [PATCH v2 0/4] Add pca9450 driver Robin Gong
  2020-07-03 16:19 ` [PATCH v2 1/4] regulator: pca9450: add pca9450 pmic driver Robin Gong
@ 2020-07-03 16:19 ` Robin Gong
  2020-07-03 16:19 ` [PATCH v2 3/4] arm64: dts: imx8mn-evk: add pca9450 for i.mx8mn-evk board Robin Gong
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 9+ messages in thread
From: Robin Gong @ 2020-07-03 16:19 UTC (permalink / raw)
  To: lgirdwood, broonie, robh+dt, frieder.schrempf, catalin.marinas,
	will, shawnguo, anson.huang, festevam, s.hauer, john.lee
  Cc: kernel, devicetree, linux-kernel, linux-arm-kernel, linux-imx

Add device binding doc for pca9450 pmic driver.

Signed-off-by: Robin Gong <yibin.gong@nxp.com>
Reviewed-by: Rob Herring <robh@kernel.org>
---
 .../bindings/regulator/nxp,pca9450-regulator.yaml  | 190 +++++++++++++++++++++
 1 file changed, 190 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/regulator/nxp,pca9450-regulator.yaml

diff --git a/Documentation/devicetree/bindings/regulator/nxp,pca9450-regulator.yaml b/Documentation/devicetree/bindings/regulator/nxp,pca9450-regulator.yaml
new file mode 100644
index 00000000..c2b0a8b
--- /dev/null
+++ b/Documentation/devicetree/bindings/regulator/nxp,pca9450-regulator.yaml
@@ -0,0 +1,190 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/regulator/nxp,pca9450-regulator.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NXP PCA9450A/B/C Power Management Integrated Circuit regulators
+
+maintainers:
+  - Robin Gong <yibin.gong@nxp.com>
+
+description: |
+  Regulator nodes should be named to BUCK_<number> and LDO_<number>. The
+  definition for each of these nodes is defined using the standard
+  binding for regulators at
+  Documentation/devicetree/bindings/regulator/regulator.txt.
+  Datasheet is available at
+  https://www.nxp.com/docs/en/data-sheet/PCA9450DS.pdf
+
+#The valid names for PCA9450 regulator nodes are:
+#BUCK1, BUCK2, BUCK3, BUCK4, BUCK5, BUCK6,
+#LDO1, LDO2, LDO3, LDO4, LDO5
+#Note: Buck3 removed on PCA9450B and connect with Buck1 on PCA9450C.
+
+properties:
+  compatible:
+    enum:
+      - nxp,pca9450a
+      - nxp,pca9450b
+      - nxp,pca9450c
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  regulators:
+    type: object
+    description: |
+      list of regulators provided by this controller
+
+    patternProperties:
+      "^LDO[1-5]$":
+        type: object
+        $ref: regulator.yaml#
+        description:
+          Properties for single LDO regulator.
+
+        properties:
+          regulator-name:
+            pattern: "^LDO[1-5]$"
+            description:
+              should be "LDO1", ..., "LDO5"
+
+        unevaluatedProperties: false
+
+      "^BUCK[1-6]$":
+        type: object
+        $ref: regulator.yaml#
+        description:
+          Properties for single BUCK regulator.
+
+        properties:
+          regulator-name:
+            pattern: "^BUCK[1-6]$"
+            description:
+              should be "BUCK1", ..., "BUCK6"
+
+          nxp,dvs-run-voltage:
+            $ref: "/schemas/types.yaml#/definitions/uint32"
+            minimum: 600000
+            maximum: 2187500
+            description:
+              PMIC default "RUN" state voltage in uV. Only Buck1~3 have such
+              dvs(dynamic voltage scaling) property.
+
+          nxp,dvs-standby-voltage:
+            $ref: "/schemas/types.yaml#/definitions/uint32"
+            minimum: 600000
+            maximum: 2187500
+            description:
+              PMIC default "STANDBY" state voltage in uV. Only Buck1~3 have such
+              dvs(dynamic voltage scaling) property.
+
+        unevaluatedProperties: false
+
+    additionalProperties: false
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - regulators
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    i2c {
+        #address-cells = <1>;
+        #size-cells = <0>;
+        pmic: pmic@25 {
+            compatible = "nxp,pca9450b";
+            reg = <0x25>;
+            pinctrl-0 = <&pinctrl_pmic>;
+            interrupt-parent = <&gpio1>;
+            interrupts = <3 IRQ_TYPE_LEVEL_LOW>;
+
+            regulators {
+                buck1: BUCK1 {
+                    regulator-name = "BUCK1";
+                    regulator-min-microvolt = <600000>;
+                    regulator-max-microvolt = <2187500>;
+                    regulator-boot-on;
+                    regulator-always-on;
+                    regulator-ramp-delay = <3125>;
+                };
+                buck2: BUCK2 {
+                    regulator-name = "BUCK2";
+                    regulator-min-microvolt = <600000>;
+                    regulator-max-microvolt = <2187500>;
+                    regulator-boot-on;
+                    regulator-always-on;
+                    regulator-ramp-delay = <3125>;
+                    nxp,dvs-run-voltage = <950000>;
+                    nxp,dvs-standby-voltage = <850000>;
+                };
+                buck4: BUCK4 {
+                    regulator-name = "BUCK4";
+                    regulator-min-microvolt = <600000>;
+                    regulator-max-microvolt = <3400000>;
+                    regulator-boot-on;
+                    regulator-always-on;
+                };
+                buck5: BUCK5 {
+                    regulator-name = "BUCK5";
+                    regulator-min-microvolt = <600000>;
+                    regulator-max-microvolt = <3400000>;
+                    regulator-boot-on;
+                    regulator-always-on;
+                };
+                buck6: BUCK6 {
+                    regulator-name = "BUCK6";
+                    regulator-min-microvolt = <600000>;
+                    regulator-max-microvolt = <3400000>;
+                    regulator-boot-on;
+                    regulator-always-on;
+                };
+
+                ldo1: LDO1 {
+                    regulator-name = "LDO1";
+                    regulator-min-microvolt = <1600000>;
+                    regulator-max-microvolt = <3300000>;
+                    regulator-boot-on;
+                    regulator-always-on;
+                };
+                ldo2: LDO2 {
+                    regulator-name = "LDO2";
+                    regulator-min-microvolt = <800000>;
+                    regulator-max-microvolt = <1150000>;
+                    regulator-boot-on;
+                    regulator-always-on;
+                };
+                ldo3: LDO3 {
+                    regulator-name = "LDO3";
+                    regulator-min-microvolt = <800000>;
+                    regulator-max-microvolt = <3300000>;
+                    regulator-boot-on;
+                    regulator-always-on;
+                };
+                ldo4: LDO4 {
+                    regulator-name = "LDO4";
+                    regulator-min-microvolt = <800000>;
+                    regulator-max-microvolt = <3300000>;
+                    regulator-boot-on;
+                    regulator-always-on;
+                };
+                ldo5: LDO5 {
+                    regulator-name = "LDO5";
+                    regulator-min-microvolt = <1800000>;
+                    regulator-max-microvolt = <3300000>;
+                    regulator-boot-on;
+                    regulator-always-on;
+                };
+            };
+        };
+    };
-- 
2.7.4


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

* [PATCH v2 3/4] arm64: dts: imx8mn-evk: add pca9450 for i.mx8mn-evk board
  2020-07-03 16:19 [PATCH v2 0/4] Add pca9450 driver Robin Gong
  2020-07-03 16:19 ` [PATCH v2 1/4] regulator: pca9450: add pca9450 pmic driver Robin Gong
  2020-07-03 16:19 ` [PATCH v2 2/4] dt-bindings: regulator: add pca9450 regulator yaml Robin Gong
@ 2020-07-03 16:19 ` Robin Gong
  2020-07-13  4:09   ` Shawn Guo
  2020-07-03 16:19 ` [PATCH v2 4/4] arm64: configs: add pca9450 pmic driver Robin Gong
  2020-07-06 14:43 ` [PATCH v2 0/4] Add pca9450 driver Mark Brown
  4 siblings, 1 reply; 9+ messages in thread
From: Robin Gong @ 2020-07-03 16:19 UTC (permalink / raw)
  To: lgirdwood, broonie, robh+dt, frieder.schrempf, catalin.marinas,
	will, shawnguo, anson.huang, festevam, s.hauer, john.lee
  Cc: kernel, devicetree, linux-kernel, linux-arm-kernel, linux-imx

Add pca9450 pmic driver for i.mx8mn-evk board.

Signed-off-by: Robin Gong <yibin.gong@nxp.com>
---
 arch/arm64/boot/dts/freescale/imx8mn-evk.dts  | 96 +++++++++++++++++++++++++++
 arch/arm64/boot/dts/freescale/imx8mn-evk.dtsi |  6 ++
 2 files changed, 102 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8mn-evk.dts b/arch/arm64/boot/dts/freescale/imx8mn-evk.dts
index 61f3519..b846526 100644
--- a/arch/arm64/boot/dts/freescale/imx8mn-evk.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mn-evk.dts
@@ -13,6 +13,102 @@
 	compatible = "fsl,imx8mn-evk", "fsl,imx8mn";
 };
 
+&i2c1 {
+	pmic: pmic@25 {
+		compatible = "nxp,pca9450b";
+		reg = <0x25>;
+		pinctrl-0 = <&pinctrl_pmic>;
+		interrupt-parent = <&gpio1>;
+		interrupts = <3 GPIO_ACTIVE_LOW>;
+
+		regulators {
+			buck1: BUCK1{
+				regulator-name = "BUCK1";
+				regulator-min-microvolt = <600000>;
+				regulator-max-microvolt = <2187500>;
+				regulator-boot-on;
+				regulator-always-on;
+				regulator-ramp-delay = <3125>;
+			};
+
+			buck2: BUCK2 {
+				regulator-name = "BUCK2";
+				regulator-min-microvolt = <600000>;
+				regulator-max-microvolt = <2187500>;
+				regulator-boot-on;
+				regulator-always-on;
+				regulator-ramp-delay = <3125>;
+				nxp,dvs-run-voltage = <950000>;
+				nxp,dvs-standby-voltage = <850000>;
+			};
+
+			buck4: BUCK4{
+				regulator-name = "BUCK4";
+				regulator-min-microvolt = <600000>;
+				regulator-max-microvolt = <3400000>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			buck5: BUCK5{
+				regulator-name = "BUCK5";
+				regulator-min-microvolt = <600000>;
+				regulator-max-microvolt = <3400000>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			buck6: BUCK6 {
+				regulator-name = "BUCK6";
+				regulator-min-microvolt = <600000>;
+				regulator-max-microvolt = <3400000>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			ldo1: LDO1 {
+				regulator-name = "LDO1";
+				regulator-min-microvolt = <1600000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			ldo2: LDO2 {
+				regulator-name = "LDO2";
+				regulator-min-microvolt = <800000>;
+				regulator-max-microvolt = <1150000>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			ldo3: LDO3 {
+				regulator-name = "LDO3";
+				regulator-min-microvolt = <800000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			ldo4: LDO4 {
+				regulator-name = "LDO4";
+				regulator-min-microvolt = <800000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			ldo5: LDO5 {
+				regulator-name = "LDO5";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+		};
+	};
+};
+
 &A53_0 {
 	/delete-property/operating-points-v2;
 };
diff --git a/arch/arm64/boot/dts/freescale/imx8mn-evk.dtsi b/arch/arm64/boot/dts/freescale/imx8mn-evk.dtsi
index 85fc0aa..98f5324 100644
--- a/arch/arm64/boot/dts/freescale/imx8mn-evk.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mn-evk.dtsi
@@ -223,6 +223,12 @@
 		>;
 	};
 
+	pinctrl_pmic: pmicirq {
+		fsl,pins = <
+			MX8MN_IOMUXC_GPIO1_IO03_GPIO1_IO3	0x41
+		>;
+	};
+
 	pinctrl_reg_usdhc2_vmmc: regusdhc2vmmc {
 		fsl,pins = <
 			MX8MN_IOMUXC_SD2_RESET_B_GPIO2_IO19	0x41
-- 
2.7.4


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

* [PATCH v2 4/4] arm64: configs: add pca9450 pmic driver
  2020-07-03 16:19 [PATCH v2 0/4] Add pca9450 driver Robin Gong
                   ` (2 preceding siblings ...)
  2020-07-03 16:19 ` [PATCH v2 3/4] arm64: dts: imx8mn-evk: add pca9450 for i.mx8mn-evk board Robin Gong
@ 2020-07-03 16:19 ` Robin Gong
  2020-07-13  4:11   ` Shawn Guo
  2020-07-06 14:43 ` [PATCH v2 0/4] Add pca9450 driver Mark Brown
  4 siblings, 1 reply; 9+ messages in thread
From: Robin Gong @ 2020-07-03 16:19 UTC (permalink / raw)
  To: lgirdwood, broonie, robh+dt, frieder.schrempf, catalin.marinas,
	will, shawnguo, anson.huang, festevam, s.hauer, john.lee
  Cc: kernel, devicetree, linux-kernel, linux-arm-kernel, linux-imx

Add pca9450 pmic driver.

Signed-off-by: Robin Gong <yibin.gong@nxp.com>
---
 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index d786bd9..abd0438 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -557,6 +557,7 @@ CONFIG_REGULATOR_HI6421V530=y
 CONFIG_REGULATOR_HI655X=y
 CONFIG_REGULATOR_MAX77620=y
 CONFIG_REGULATOR_MAX8973=y
+CONFIG_REGULATOR_PCA9450=y
 CONFIG_REGULATOR_PFUZE100=y
 CONFIG_REGULATOR_PWM=y
 CONFIG_REGULATOR_QCOM_RPMH=y
-- 
2.7.4


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

* Re: [PATCH v2 1/4] regulator: pca9450: add pca9450 pmic driver
  2020-07-03 16:19 ` [PATCH v2 1/4] regulator: pca9450: add pca9450 pmic driver Robin Gong
@ 2020-07-06  8:02   ` Frieder Schrempf
  0 siblings, 0 replies; 9+ messages in thread
From: Frieder Schrempf @ 2020-07-06  8:02 UTC (permalink / raw)
  To: Robin Gong, lgirdwood, broonie, robh+dt, catalin.marinas, will,
	shawnguo, anson.huang, festevam, s.hauer, john.lee
  Cc: kernel, devicetree, linux-kernel, linux-arm-kernel, linux-imx

On 03.07.20 18:19, Robin Gong wrote:
> Add NXP pca9450 pmic driver.
> 
> Signed-off-by: Robin Gong <yibin.gong@nxp.com>

Reviewed-by: Frieder Schrempf <frieder.schrempf@kontron.de>

> ---
>   drivers/regulator/Kconfig             |   8 +
>   drivers/regulator/Makefile            |   1 +
>   drivers/regulator/pca9450-regulator.c | 843 ++++++++++++++++++++++++++++++++++
>   include/linux/regulator/pca9450.h     | 219 +++++++++
>   4 files changed, 1071 insertions(+)
>   create mode 100644 drivers/regulator/pca9450-regulator.c
>   create mode 100644 include/linux/regulator/pca9450.h
> 
> diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
> index f60eeaa..f992a17 100644
> --- a/drivers/regulator/Kconfig
> +++ b/drivers/regulator/Kconfig
> @@ -740,6 +740,14 @@ config REGULATOR_PBIAS
>   	 This driver provides support for OMAP pbias modelled
>   	 regulators.
>   
> +config REGULATOR_PCA9450
> +	tristate "NXP PCA9450A/PCA9450B/PCA9450C regulator driver"
> +	depends on I2C
> +	select REGMAP_I2C
> +	help
> +	  Say y here to support the NXP PCA9450A/PCA9450B/PCA9450C PMIC
> +	  regulator driver.
> +
>   config REGULATOR_PCAP
>   	tristate "Motorola PCAP2 regulator driver"
>   	depends on EZX_PCAP
> diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
> index 5ce7350..ff524922 100644
> --- a/drivers/regulator/Makefile
> +++ b/drivers/regulator/Makefile
> @@ -94,6 +94,7 @@ obj-$(CONFIG_REGULATOR_QCOM_RPMH) += qcom-rpmh-regulator.o
>   obj-$(CONFIG_REGULATOR_QCOM_SMD_RPM) += qcom_smd-regulator.o
>   obj-$(CONFIG_REGULATOR_QCOM_SPMI) += qcom_spmi-regulator.o
>   obj-$(CONFIG_REGULATOR_PALMAS) += palmas-regulator.o
> +obj-$(CONFIG_REGULATOR_PCA9450) += pca9450-regulator.o
>   obj-$(CONFIG_REGULATOR_PFUZE100) += pfuze100-regulator.o
>   obj-$(CONFIG_REGULATOR_PV88060) += pv88060-regulator.o
>   obj-$(CONFIG_REGULATOR_PV88080) += pv88080-regulator.o
> diff --git a/drivers/regulator/pca9450-regulator.c b/drivers/regulator/pca9450-regulator.c
> new file mode 100644
> index 00000000..0225045
> --- /dev/null
> +++ b/drivers/regulator/pca9450-regulator.c
> @@ -0,0 +1,843 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright 2020 NXP.
> + * NXP PCA9450 pmic driver
> + */
> +
> +#include <linux/err.h>
> +#include <linux/i2c.h>
> +#include <linux/interrupt.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/of_device.h>
> +#include <linux/platform_device.h>
> +#include <linux/regulator/driver.h>
> +#include <linux/regulator/machine.h>
> +#include <linux/regulator/of_regulator.h>
> +#include <linux/regulator/pca9450.h>
> +
> +struct pc9450_dvs_config {
> +	unsigned int run_reg; /* dvs0 */
> +	unsigned int run_mask;
> +	unsigned int standby_reg; /* dvs1 */
> +	unsigned int standby_mask;
> +};
> +
> +struct pca9450_regulator_desc {
> +	struct regulator_desc desc;
> +	const struct pc9450_dvs_config dvs;
> +};
> +
> +struct pca9450 {
> +	struct device *dev;
> +	struct regmap *regmap;
> +	enum pca9450_chip_type type;
> +	unsigned int rcnt;
> +	int irq;
> +};
> +
> +static const struct regmap_range pca9450_status_range = {
> +	.range_min = PCA9450_REG_INT1,
> +	.range_max = PCA9450_REG_PWRON_STAT,
> +};
> +
> +static const struct regmap_access_table pca9450_volatile_regs = {
> +	.yes_ranges = &pca9450_status_range,
> +	.n_yes_ranges = 1,
> +};
> +
> +static const struct regmap_config pca9450_regmap_config = {
> +	.reg_bits = 8,
> +	.val_bits = 8,
> +	.volatile_table = &pca9450_volatile_regs,
> +	.max_register = PCA9450_MAX_REGISTER - 1,
> +	.cache_type = REGCACHE_RBTREE,
> +};
> +
> +/*
> + * BUCK1/2/3
> + * BUCK1RAM[1:0] BUCK1 DVS ramp rate setting
> + * 00: 25mV/1usec
> + * 01: 25mV/2usec
> + * 10: 25mV/4usec
> + * 11: 25mV/8usec
> + */
> +static int pca9450_dvs_set_ramp_delay(struct regulator_dev *rdev,
> +				      int ramp_delay)
> +{
> +	int id = rdev_get_id(rdev);
> +	unsigned int ramp_value;
> +
> +	switch (ramp_delay) {
> +	case 1 ... 3125:
> +		ramp_value = BUCK1_RAMP_3P125MV;
> +		break;
> +	case 3126 ... 6250:
> +		ramp_value = BUCK1_RAMP_6P25MV;
> +		break;
> +	case 6251 ... 12500:
> +		ramp_value = BUCK1_RAMP_12P5MV;
> +		break;
> +	case 12501 ... 25000:
> +		ramp_value = BUCK1_RAMP_25MV;
> +		break;
> +	default:
> +		ramp_value = BUCK1_RAMP_25MV;
> +	}
> +
> +	return regmap_update_bits(rdev->regmap, PCA9450_REG_BUCK1CTRL + id * 3,
> +				  BUCK1_RAMP_MASK, ramp_value << 6);
> +}
> +
> +static struct regulator_ops pca9450_dvs_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 = 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 = pca9450_dvs_set_ramp_delay,
> +};
> +
> +static struct regulator_ops pca9450_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 = regulator_set_voltage_sel_regmap,
> +	.get_voltage_sel = regulator_get_voltage_sel_regmap,
> +	.set_voltage_time_sel = regulator_set_voltage_time_sel,
> +};
> +
> +static struct regulator_ops pca9450_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 = regulator_set_voltage_sel_regmap,
> +	.get_voltage_sel = regulator_get_voltage_sel_regmap,
> +};
> +
> +/*
> + * BUCK1/2/3
> + * 0.60 to 2.1875V (12.5mV step)
> + */
> +static const struct linear_range pca9450_dvs_buck_volts[] = {
> +	REGULATOR_LINEAR_RANGE(600000,  0x00, 0x7F, 12500),
> +};
> +
> +/*
> + * BUCK4/5/6
> + * 0.6V to 3.4V (25mV step)
> + */
> +static const struct linear_range pca9450_buck_volts[] = {
> +	REGULATOR_LINEAR_RANGE(600000, 0x00, 0x70, 25000),
> +	REGULATOR_LINEAR_RANGE(3400000, 0x71, 0x7F, 0),
> +};
> +
> +/*
> + * LDO1
> + * 1.6 to 3.3V ()
> + */
> +static const struct linear_range pca9450_ldo1_volts[] = {
> +	REGULATOR_LINEAR_RANGE(1600000, 0x00, 0x03, 100000),
> +	REGULATOR_LINEAR_RANGE(3000000, 0x04, 0x07, 100000),
> +};
> +
> +/*
> + * LDO2
> + * 0.8 to 1.15V (50mV step)
> + */
> +static const struct linear_range pca9450_ldo2_volts[] = {
> +	REGULATOR_LINEAR_RANGE(800000, 0x00, 0x07, 50000),
> +};
> +
> +/*
> + * LDO3/4
> + * 0.8 to 3.3V (100mV step)
> + */
> +static const struct linear_range pca9450_ldo34_volts[] = {
> +	REGULATOR_LINEAR_RANGE(800000, 0x00, 0x19, 100000),
> +	REGULATOR_LINEAR_RANGE(3300000, 0x1A, 0x1F, 0),
> +};
> +
> +/*
> + * LDO5
> + * 1.8 to 3.3V (100mV step)
> + */
> +static const struct linear_range pca9450_ldo5_volts[] = {
> +	REGULATOR_LINEAR_RANGE(1800000,  0x00, 0x0F, 100000),
> +};
> +
> +static int buck_set_dvs(const struct regulator_desc *desc,
> +			struct device_node *np, struct regmap *regmap,
> +			char *prop, unsigned int reg, unsigned int mask)
> +{
> +	int ret, i;
> +	uint32_t uv;
> +
> +	ret = of_property_read_u32(np, prop, &uv);
> +	if (ret == -EINVAL)
> +		return 0;
> +	else if (ret)
> +		return ret;
> +
> +	for (i = 0; i < desc->n_voltages; i++) {
> +		ret = regulator_desc_list_voltage_linear_range(desc, i);
> +		if (ret < 0)
> +			continue;
> +		if (ret == uv) {
> +			i <<= ffs(desc->vsel_mask) - 1;
> +			ret = regmap_update_bits(regmap, reg, mask, i);
> +			break;
> +		}
> +	}
> +
> +	return ret;
> +}
> +
> +static int pca9450_set_dvs_levels(struct device_node *np,
> +			    const struct regulator_desc *desc,
> +			    struct regulator_config *cfg)
> +{
> +	struct pca9450_regulator_desc *data = container_of(desc,
> +					struct pca9450_regulator_desc, desc);
> +	const struct pc9450_dvs_config *dvs = &data->dvs;
> +	unsigned int reg, mask;
> +	char *prop;
> +	int i, ret = 0;
> +
> +	for (i = 0; i < PCA9450_DVS_LEVEL_MAX; i++) {
> +		switch (i) {
> +		case PCA9450_DVS_LEVEL_RUN:
> +			prop = "nxp,dvs-run-voltage";
> +			reg = dvs->run_reg;
> +			mask = dvs->run_mask;
> +			break;
> +		case PCA9450_DVS_LEVEL_STANDBY:
> +			prop = "nxp,dvs-standby-voltage";
> +			reg = dvs->standby_reg;
> +			mask = dvs->standby_mask;
> +			break;
> +		default:
> +			return -EINVAL;
> +		}
> +
> +		ret = buck_set_dvs(desc, np, cfg->regmap, prop, reg, mask);
> +		if (ret)
> +			break;
> +	}
> +
> +	return ret;
> +}
> +
> +static const struct pca9450_regulator_desc pca9450a_regulators[] = {
> +	{
> +		.desc = {
> +			.name = "buck1",
> +			.of_match = of_match_ptr("BUCK1"),
> +			.regulators_node = of_match_ptr("regulators"),
> +			.id = PCA9450_BUCK1,
> +			.ops = &pca9450_dvs_buck_regulator_ops,
> +			.type = REGULATOR_VOLTAGE,
> +			.n_voltages = PCA9450_BUCK1_VOLTAGE_NUM,
> +			.linear_ranges = pca9450_dvs_buck_volts,
> +			.n_linear_ranges = ARRAY_SIZE(pca9450_dvs_buck_volts),
> +			.vsel_reg = PCA9450_REG_BUCK1OUT_DVS0,
> +			.vsel_mask = BUCK1OUT_DVS0_MASK,
> +			.enable_reg = PCA9450_REG_BUCK1CTRL,
> +			.enable_mask = BUCK1_ENMODE_MASK,
> +			.owner = THIS_MODULE,
> +			.of_parse_cb = pca9450_set_dvs_levels,
> +		},
> +		.dvs = {
> +			.run_reg = PCA9450_REG_BUCK1OUT_DVS0,
> +			.run_mask = BUCK1OUT_DVS0_MASK,
> +			.standby_reg = PCA9450_REG_BUCK1OUT_DVS1,
> +			.standby_mask = BUCK1OUT_DVS1_MASK,
> +		},
> +	},
> +	{
> +		.desc = {
> +			.name = "buck2",
> +			.of_match = of_match_ptr("BUCK2"),
> +			.regulators_node = of_match_ptr("regulators"),
> +			.id = PCA9450_BUCK2,
> +			.ops = &pca9450_dvs_buck_regulator_ops,
> +			.type = REGULATOR_VOLTAGE,
> +			.n_voltages = PCA9450_BUCK2_VOLTAGE_NUM,
> +			.linear_ranges = pca9450_dvs_buck_volts,
> +			.n_linear_ranges = ARRAY_SIZE(pca9450_dvs_buck_volts),
> +			.vsel_reg = PCA9450_REG_BUCK2OUT_DVS0,
> +			.vsel_mask = BUCK2OUT_DVS0_MASK,
> +			.enable_reg = PCA9450_REG_BUCK2CTRL,
> +			.enable_mask = BUCK1_ENMODE_MASK,
> +			.owner = THIS_MODULE,
> +			.of_parse_cb = pca9450_set_dvs_levels,
> +		},
> +		.dvs = {
> +			.run_reg = PCA9450_REG_BUCK2OUT_DVS0,
> +			.run_mask = BUCK2OUT_DVS0_MASK,
> +			.standby_reg = PCA9450_REG_BUCK2OUT_DVS1,
> +			.standby_mask = BUCK2OUT_DVS1_MASK,
> +		},
> +	},
> +	{
> +		.desc = {
> +			.name = "buck3",
> +			.of_match = of_match_ptr("BUCK3"),
> +			.regulators_node = of_match_ptr("regulators"),
> +			.id = PCA9450_BUCK3,
> +			.ops = &pca9450_dvs_buck_regulator_ops,
> +			.type = REGULATOR_VOLTAGE,
> +			.n_voltages = PCA9450_BUCK3_VOLTAGE_NUM,
> +			.linear_ranges = pca9450_dvs_buck_volts,
> +			.n_linear_ranges = ARRAY_SIZE(pca9450_dvs_buck_volts),
> +			.vsel_reg = PCA9450_REG_BUCK3OUT_DVS0,
> +			.vsel_mask = BUCK3OUT_DVS0_MASK,
> +			.enable_reg = PCA9450_REG_BUCK3CTRL,
> +			.enable_mask = BUCK3_ENMODE_MASK,
> +			.owner = THIS_MODULE,
> +			.of_parse_cb = pca9450_set_dvs_levels,
> +		},
> +		.dvs = {
> +			.run_reg = PCA9450_REG_BUCK3OUT_DVS0,
> +			.run_mask = BUCK3OUT_DVS0_MASK,
> +			.standby_reg = PCA9450_REG_BUCK3OUT_DVS1,
> +			.standby_mask = BUCK3OUT_DVS1_MASK,
> +		},
> +	},
> +	{
> +		.desc = {
> +			.name = "buck4",
> +			.of_match = of_match_ptr("BUCK4"),
> +			.regulators_node = of_match_ptr("regulators"),
> +			.id = PCA9450_BUCK4,
> +			.ops = &pca9450_buck_regulator_ops,
> +			.type = REGULATOR_VOLTAGE,
> +			.n_voltages = PCA9450_BUCK4_VOLTAGE_NUM,
> +			.linear_ranges = pca9450_buck_volts,
> +			.n_linear_ranges = ARRAY_SIZE(pca9450_buck_volts),
> +			.vsel_reg = PCA9450_REG_BUCK4OUT,
> +			.vsel_mask = BUCK4OUT_MASK,
> +			.enable_reg = PCA9450_REG_BUCK4CTRL,
> +			.enable_mask = BUCK4_ENMODE_MASK,
> +			.owner = THIS_MODULE,
> +		},
> +	},
> +	{
> +		.desc = {
> +			.name = "buck5",
> +			.of_match = of_match_ptr("BUCK5"),
> +			.regulators_node = of_match_ptr("regulators"),
> +			.id = PCA9450_BUCK5,
> +			.ops = &pca9450_buck_regulator_ops,
> +			.type = REGULATOR_VOLTAGE,
> +			.n_voltages = PCA9450_BUCK5_VOLTAGE_NUM,
> +			.linear_ranges = pca9450_buck_volts,
> +			.n_linear_ranges = ARRAY_SIZE(pca9450_buck_volts),
> +			.vsel_reg = PCA9450_REG_BUCK5OUT,
> +			.vsel_mask = BUCK5OUT_MASK,
> +			.enable_reg = PCA9450_REG_BUCK5CTRL,
> +			.enable_mask = BUCK5_ENMODE_MASK,
> +			.owner = THIS_MODULE,
> +		},
> +	},
> +	{
> +		.desc = {
> +			.name = "buck6",
> +			.of_match = of_match_ptr("BUCK6"),
> +			.regulators_node = of_match_ptr("regulators"),
> +			.id = PCA9450_BUCK6,
> +			.ops = &pca9450_buck_regulator_ops,
> +			.type = REGULATOR_VOLTAGE,
> +			.n_voltages = PCA9450_BUCK6_VOLTAGE_NUM,
> +			.linear_ranges = pca9450_buck_volts,
> +			.n_linear_ranges = ARRAY_SIZE(pca9450_buck_volts),
> +			.vsel_reg = PCA9450_REG_BUCK6OUT,
> +			.vsel_mask = BUCK6OUT_MASK,
> +			.enable_reg = PCA9450_REG_BUCK6CTRL,
> +			.enable_mask = BUCK6_ENMODE_MASK,
> +			.owner = THIS_MODULE,
> +		},
> +	},
> +	{
> +		.desc = {
> +			.name = "ldo1",
> +			.of_match = of_match_ptr("LDO1"),
> +			.regulators_node = of_match_ptr("regulators"),
> +			.id = PCA9450_LDO1,
> +			.ops = &pca9450_ldo_regulator_ops,
> +			.type = REGULATOR_VOLTAGE,
> +			.n_voltages = PCA9450_LDO1_VOLTAGE_NUM,
> +			.linear_ranges = pca9450_ldo1_volts,
> +			.n_linear_ranges = ARRAY_SIZE(pca9450_ldo1_volts),
> +			.vsel_reg = PCA9450_REG_LDO1CTRL,
> +			.vsel_mask = LDO1OUT_MASK,
> +			.enable_reg = PCA9450_REG_LDO1CTRL,
> +			.enable_mask = LDO1_EN_MASK,
> +			.owner = THIS_MODULE,
> +		},
> +	},
> +	{
> +		.desc = {
> +			.name = "ldo2",
> +			.of_match = of_match_ptr("LDO2"),
> +			.regulators_node = of_match_ptr("regulators"),
> +			.id = PCA9450_LDO2,
> +			.ops = &pca9450_ldo_regulator_ops,
> +			.type = REGULATOR_VOLTAGE,
> +			.n_voltages = PCA9450_LDO2_VOLTAGE_NUM,
> +			.linear_ranges = pca9450_ldo2_volts,
> +			.n_linear_ranges = ARRAY_SIZE(pca9450_ldo2_volts),
> +			.vsel_reg = PCA9450_REG_LDO2CTRL,
> +			.vsel_mask = LDO2OUT_MASK,
> +			.enable_reg = PCA9450_REG_LDO2CTRL,
> +			.enable_mask = LDO2_EN_MASK,
> +			.owner = THIS_MODULE,
> +		},
> +	},
> +	{
> +		.desc = {
> +			.name = "ldo3",
> +			.of_match = of_match_ptr("LDO3"),
> +			.regulators_node = of_match_ptr("regulators"),
> +			.id = PCA9450_LDO3,
> +			.ops = &pca9450_ldo_regulator_ops,
> +			.type = REGULATOR_VOLTAGE,
> +			.n_voltages = PCA9450_LDO3_VOLTAGE_NUM,
> +			.linear_ranges = pca9450_ldo34_volts,
> +			.n_linear_ranges = ARRAY_SIZE(pca9450_ldo34_volts),
> +			.vsel_reg = PCA9450_REG_LDO3CTRL,
> +			.vsel_mask = LDO3OUT_MASK,
> +			.enable_reg = PCA9450_REG_LDO3CTRL,
> +			.enable_mask = LDO3_EN_MASK,
> +			.owner = THIS_MODULE,
> +		},
> +	},
> +	{
> +		.desc = {
> +			.name = "ldo4",
> +			.of_match = of_match_ptr("LDO4"),
> +			.regulators_node = of_match_ptr("regulators"),
> +			.id = PCA9450_LDO4,
> +			.ops = &pca9450_ldo_regulator_ops,
> +			.type = REGULATOR_VOLTAGE,
> +			.n_voltages = PCA9450_LDO4_VOLTAGE_NUM,
> +			.linear_ranges = pca9450_ldo34_volts,
> +			.n_linear_ranges = ARRAY_SIZE(pca9450_ldo34_volts),
> +			.vsel_reg = PCA9450_REG_LDO4CTRL,
> +			.vsel_mask = LDO4OUT_MASK,
> +			.enable_reg = PCA9450_REG_LDO4CTRL,
> +			.enable_mask = LDO4_EN_MASK,
> +			.owner = THIS_MODULE,
> +		},
> +	},
> +	{
> +		.desc = {
> +			.name = "ldo5",
> +			.of_match = of_match_ptr("LDO5"),
> +			.regulators_node = of_match_ptr("regulators"),
> +			.id = PCA9450_LDO5,
> +			.ops = &pca9450_ldo_regulator_ops,
> +			.type = REGULATOR_VOLTAGE,
> +			.n_voltages = PCA9450_LDO5_VOLTAGE_NUM,
> +			.linear_ranges = pca9450_ldo5_volts,
> +			.n_linear_ranges = ARRAY_SIZE(pca9450_ldo5_volts),
> +			.vsel_reg = PCA9450_REG_LDO5CTRL_H,
> +			.vsel_mask = LDO5HOUT_MASK,
> +			.enable_reg = PCA9450_REG_LDO5CTRL_H,
> +			.enable_mask = LDO5H_EN_MASK,
> +			.owner = THIS_MODULE,
> +		},
> +	},
> +};
> +
> +/*
> + * Buck3 removed on PCA9450B and connected with Buck1 internal for dual phase
> + * on PCA9450C as no Buck3.
> + */
> +static const struct pca9450_regulator_desc pca9450bc_regulators[] = {
> +	{
> +		.desc = {
> +			.name = "buck1",
> +			.of_match = of_match_ptr("BUCK1"),
> +			.regulators_node = of_match_ptr("regulators"),
> +			.id = PCA9450_BUCK1,
> +			.ops = &pca9450_dvs_buck_regulator_ops,
> +			.type = REGULATOR_VOLTAGE,
> +			.n_voltages = PCA9450_BUCK1_VOLTAGE_NUM,
> +			.linear_ranges = pca9450_dvs_buck_volts,
> +			.n_linear_ranges = ARRAY_SIZE(pca9450_dvs_buck_volts),
> +			.vsel_reg = PCA9450_REG_BUCK1OUT_DVS0,
> +			.vsel_mask = BUCK1OUT_DVS0_MASK,
> +			.enable_reg = PCA9450_REG_BUCK1CTRL,
> +			.enable_mask = BUCK1_ENMODE_MASK,
> +			.owner = THIS_MODULE,
> +			.of_parse_cb = pca9450_set_dvs_levels,
> +		},
> +		.dvs = {
> +			.run_reg = PCA9450_REG_BUCK1OUT_DVS0,
> +			.run_mask = BUCK1OUT_DVS0_MASK,
> +			.standby_reg = PCA9450_REG_BUCK1OUT_DVS1,
> +			.standby_mask = BUCK1OUT_DVS1_MASK,
> +		},
> +	},
> +	{
> +		.desc = {
> +			.name = "buck2",
> +			.of_match = of_match_ptr("BUCK2"),
> +			.regulators_node = of_match_ptr("regulators"),
> +			.id = PCA9450_BUCK2,
> +			.ops = &pca9450_dvs_buck_regulator_ops,
> +			.type = REGULATOR_VOLTAGE,
> +			.n_voltages = PCA9450_BUCK2_VOLTAGE_NUM,
> +			.linear_ranges = pca9450_dvs_buck_volts,
> +			.n_linear_ranges = ARRAY_SIZE(pca9450_dvs_buck_volts),
> +			.vsel_reg = PCA9450_REG_BUCK2OUT_DVS0,
> +			.vsel_mask = BUCK2OUT_DVS0_MASK,
> +			.enable_reg = PCA9450_REG_BUCK2CTRL,
> +			.enable_mask = BUCK1_ENMODE_MASK,
> +			.owner = THIS_MODULE,
> +			.of_parse_cb = pca9450_set_dvs_levels,
> +		},
> +		.dvs = {
> +			.run_reg = PCA9450_REG_BUCK2OUT_DVS0,
> +			.run_mask = BUCK2OUT_DVS0_MASK,
> +			.standby_reg = PCA9450_REG_BUCK2OUT_DVS1,
> +			.standby_mask = BUCK2OUT_DVS1_MASK,
> +		},
> +	},
> +	{
> +		.desc = {
> +			.name = "buck4",
> +			.of_match = of_match_ptr("BUCK4"),
> +			.regulators_node = of_match_ptr("regulators"),
> +			.id = PCA9450_BUCK4,
> +			.ops = &pca9450_buck_regulator_ops,
> +			.type = REGULATOR_VOLTAGE,
> +			.n_voltages = PCA9450_BUCK4_VOLTAGE_NUM,
> +			.linear_ranges = pca9450_buck_volts,
> +			.n_linear_ranges = ARRAY_SIZE(pca9450_buck_volts),
> +			.vsel_reg = PCA9450_REG_BUCK4OUT,
> +			.vsel_mask = BUCK4OUT_MASK,
> +			.enable_reg = PCA9450_REG_BUCK4CTRL,
> +			.enable_mask = BUCK4_ENMODE_MASK,
> +			.owner = THIS_MODULE,
> +		},
> +	},
> +	{
> +		.desc = {
> +			.name = "buck5",
> +			.of_match = of_match_ptr("BUCK5"),
> +			.regulators_node = of_match_ptr("regulators"),
> +			.id = PCA9450_BUCK5,
> +			.ops = &pca9450_buck_regulator_ops,
> +			.type = REGULATOR_VOLTAGE,
> +			.n_voltages = PCA9450_BUCK5_VOLTAGE_NUM,
> +			.linear_ranges = pca9450_buck_volts,
> +			.n_linear_ranges = ARRAY_SIZE(pca9450_buck_volts),
> +			.vsel_reg = PCA9450_REG_BUCK5OUT,
> +			.vsel_mask = BUCK5OUT_MASK,
> +			.enable_reg = PCA9450_REG_BUCK5CTRL,
> +			.enable_mask = BUCK5_ENMODE_MASK,
> +			.owner = THIS_MODULE,
> +		},
> +	},
> +	{
> +		.desc = {
> +			.name = "buck6",
> +			.of_match = of_match_ptr("BUCK6"),
> +			.regulators_node = of_match_ptr("regulators"),
> +			.id = PCA9450_BUCK6,
> +			.ops = &pca9450_buck_regulator_ops,
> +			.type = REGULATOR_VOLTAGE,
> +			.n_voltages = PCA9450_BUCK6_VOLTAGE_NUM,
> +			.linear_ranges = pca9450_buck_volts,
> +			.n_linear_ranges = ARRAY_SIZE(pca9450_buck_volts),
> +			.vsel_reg = PCA9450_REG_BUCK6OUT,
> +			.vsel_mask = BUCK6OUT_MASK,
> +			.enable_reg = PCA9450_REG_BUCK6CTRL,
> +			.enable_mask = BUCK6_ENMODE_MASK,
> +			.owner = THIS_MODULE,
> +		},
> +	},
> +	{
> +		.desc = {
> +			.name = "ldo1",
> +			.of_match = of_match_ptr("LDO1"),
> +			.regulators_node = of_match_ptr("regulators"),
> +			.id = PCA9450_LDO1,
> +			.ops = &pca9450_ldo_regulator_ops,
> +			.type = REGULATOR_VOLTAGE,
> +			.n_voltages = PCA9450_LDO1_VOLTAGE_NUM,
> +			.linear_ranges = pca9450_ldo1_volts,
> +			.n_linear_ranges = ARRAY_SIZE(pca9450_ldo1_volts),
> +			.vsel_reg = PCA9450_REG_LDO1CTRL,
> +			.vsel_mask = LDO1OUT_MASK,
> +			.enable_reg = PCA9450_REG_LDO1CTRL,
> +			.enable_mask = LDO1_EN_MASK,
> +			.owner = THIS_MODULE,
> +		},
> +	},
> +	{
> +		.desc = {
> +			.name = "ldo2",
> +			.of_match = of_match_ptr("LDO2"),
> +			.regulators_node = of_match_ptr("regulators"),
> +			.id = PCA9450_LDO2,
> +			.ops = &pca9450_ldo_regulator_ops,
> +			.type = REGULATOR_VOLTAGE,
> +			.n_voltages = PCA9450_LDO2_VOLTAGE_NUM,
> +			.linear_ranges = pca9450_ldo2_volts,
> +			.n_linear_ranges = ARRAY_SIZE(pca9450_ldo2_volts),
> +			.vsel_reg = PCA9450_REG_LDO2CTRL,
> +			.vsel_mask = LDO2OUT_MASK,
> +			.enable_reg = PCA9450_REG_LDO2CTRL,
> +			.enable_mask = LDO2_EN_MASK,
> +			.owner = THIS_MODULE,
> +		},
> +	},
> +	{
> +		.desc = {
> +			.name = "ldo3",
> +			.of_match = of_match_ptr("LDO3"),
> +			.regulators_node = of_match_ptr("regulators"),
> +			.id = PCA9450_LDO3,
> +			.ops = &pca9450_ldo_regulator_ops,
> +			.type = REGULATOR_VOLTAGE,
> +			.n_voltages = PCA9450_LDO3_VOLTAGE_NUM,
> +			.linear_ranges = pca9450_ldo34_volts,
> +			.n_linear_ranges = ARRAY_SIZE(pca9450_ldo34_volts),
> +			.vsel_reg = PCA9450_REG_LDO3CTRL,
> +			.vsel_mask = LDO3OUT_MASK,
> +			.enable_reg = PCA9450_REG_LDO3CTRL,
> +			.enable_mask = LDO3_EN_MASK,
> +			.owner = THIS_MODULE,
> +		},
> +	},
> +	{
> +		.desc = {
> +			.name = "ldo4",
> +			.of_match = of_match_ptr("LDO4"),
> +			.regulators_node = of_match_ptr("regulators"),
> +			.id = PCA9450_LDO4,
> +			.ops = &pca9450_ldo_regulator_ops,
> +			.type = REGULATOR_VOLTAGE,
> +			.n_voltages = PCA9450_LDO4_VOLTAGE_NUM,
> +			.linear_ranges = pca9450_ldo34_volts,
> +			.n_linear_ranges = ARRAY_SIZE(pca9450_ldo34_volts),
> +			.vsel_reg = PCA9450_REG_LDO4CTRL,
> +			.vsel_mask = LDO4OUT_MASK,
> +			.enable_reg = PCA9450_REG_LDO4CTRL,
> +			.enable_mask = LDO4_EN_MASK,
> +			.owner = THIS_MODULE,
> +		},
> +	},
> +	{
> +		.desc = {
> +			.name = "ldo5",
> +			.of_match = of_match_ptr("LDO5"),
> +			.regulators_node = of_match_ptr("regulators"),
> +			.id = PCA9450_LDO5,
> +			.ops = &pca9450_ldo_regulator_ops,
> +			.type = REGULATOR_VOLTAGE,
> +			.n_voltages = PCA9450_LDO5_VOLTAGE_NUM,
> +			.linear_ranges = pca9450_ldo5_volts,
> +			.n_linear_ranges = ARRAY_SIZE(pca9450_ldo5_volts),
> +			.vsel_reg = PCA9450_REG_LDO5CTRL_H,
> +			.vsel_mask = LDO5HOUT_MASK,
> +			.enable_reg = PCA9450_REG_LDO5CTRL_H,
> +			.enable_mask = LDO5H_EN_MASK,
> +			.owner = THIS_MODULE,
> +		},
> +	},
> +};
> +
> +static irqreturn_t pca9450_irq_handler(int irq, void *data)
> +{
> +	struct pca9450 *pca9450 = data;
> +	struct regmap *regmap = pca9450->regmap;
> +	unsigned int status;
> +	int ret;
> +
> +	ret = regmap_read(regmap, PCA9450_REG_INT1, &status);
> +	if (ret < 0) {
> +		dev_err(pca9450->dev,
> +			"Failed to read INT1(%d)\n", ret);
> +		return IRQ_NONE;
> +	}
> +
> +	if (status & IRQ_PWRON)
> +		dev_warn(pca9450->dev, "PWRON interrupt.\n");
> +
> +	if (status & IRQ_WDOGB)
> +		dev_warn(pca9450->dev, "WDOGB interrupt.\n");
> +
> +	if (status & IRQ_VR_FLT1)
> +		dev_warn(pca9450->dev, "VRFLT1 interrupt.\n");
> +
> +	if (status & IRQ_VR_FLT2)
> +		dev_warn(pca9450->dev, "VRFLT2 interrupt.\n");
> +
> +	if (status & IRQ_LOWVSYS)
> +		dev_warn(pca9450->dev, "LOWVSYS interrupt.\n");
> +
> +	if (status & IRQ_THERM_105)
> +		dev_warn(pca9450->dev, "IRQ_THERM_105 interrupt.\n");
> +
> +	if (status & IRQ_THERM_125)
> +		dev_warn(pca9450->dev, "IRQ_THERM_125 interrupt.\n");
> +
> +	return IRQ_HANDLED;
> +}
> +
> +static int pca9450_i2c_probe(struct i2c_client *i2c,
> +			     const struct i2c_device_id *id)
> +{
> +	enum pca9450_chip_type type = (unsigned int)(uintptr_t)
> +				      of_device_get_match_data(&i2c->dev);
> +	const struct pca9450_regulator_desc	*regulator_desc;
> +	struct regulator_config config = { };
> +	struct pca9450 *pca9450;
> +	unsigned int device_id, i;
> +	int ret;
> +
> +	if (!i2c->irq) {
> +		dev_err(&i2c->dev, "No IRQ configured?\n");
> +		return -EINVAL;
> +	}
> +
> +	pca9450 = devm_kzalloc(&i2c->dev, sizeof(struct pca9450), GFP_KERNEL);
> +	if (!pca9450)
> +		return -ENOMEM;
> +
> +	switch (type) {
> +	case PCA9450_TYPE_PCA9450A:
> +		regulator_desc = pca9450a_regulators;
> +		pca9450->rcnt = ARRAY_SIZE(pca9450a_regulators);
> +		break;
> +	case PCA9450_TYPE_PCA9450BC:
> +		regulator_desc = pca9450bc_regulators;
> +		pca9450->rcnt = ARRAY_SIZE(pca9450bc_regulators);
> +		break;
> +	default:
> +		dev_err(&i2c->dev, "Unknown device type");
> +		return -EINVAL;
> +	}
> +
> +	pca9450->irq = i2c->irq;
> +	pca9450->type = type;
> +	pca9450->dev = &i2c->dev;
> +
> +	dev_set_drvdata(&i2c->dev, pca9450);
> +
> +	pca9450->regmap = devm_regmap_init_i2c(i2c,
> +					       &pca9450_regmap_config);
> +	if (IS_ERR(pca9450->regmap)) {
> +		dev_err(&i2c->dev, "regmap initialization failed\n");
> +		return PTR_ERR(pca9450->regmap);
> +	}
> +
> +	ret = regmap_read(pca9450->regmap, PCA9450_REG_DEV_ID, &device_id);
> +	if (ret) {
> +		dev_err(&i2c->dev, "Read device id error\n");
> +		return ret;
> +	}
> +
> +	/* Check your board and dts for match the right pmic */
> +	if (((device_id >> 4) != 0x1 && type == PCA9450_TYPE_PCA9450A) ||
> +	    ((device_id >> 4) != 0x3 && type == PCA9450_TYPE_PCA9450BC)) {
> +		dev_err(&i2c->dev, "Device id(%x) mismatched\n",
> +			device_id >> 4);
> +		return -EINVAL;
> +	}
> +
> +	for (i = 0; i < pca9450->rcnt; i++) {
> +		const struct regulator_desc *desc;
> +		struct regulator_dev *rdev;
> +		const struct pca9450_regulator_desc *r;
> +
> +		r = &regulator_desc[i];
> +		desc = &r->desc;
> +
> +		config.regmap = pca9450->regmap;
> +		config.dev = pca9450->dev;
> +
> +		rdev = devm_regulator_register(pca9450->dev, desc, &config);
> +		if (IS_ERR(rdev)) {
> +			ret = PTR_ERR(rdev);
> +			dev_err(pca9450->dev,
> +				"Failed to register regulator(%s): %d\n",
> +				desc->name, ret);
> +			return ret;
> +		}
> +	}
> +
> +	ret = devm_request_threaded_irq(pca9450->dev, pca9450->irq, NULL,
> +					pca9450_irq_handler,
> +					(IRQF_TRIGGER_FALLING | IRQF_ONESHOT),
> +					"pca9450-irq", pca9450);
> +	if (ret != 0) {
> +		dev_err(pca9450->dev, "Failed to request IRQ: %d\n",
> +			pca9450->irq);
> +		return ret;
> +	}
> +	/* Unmask all interrupt except PWRON/WDOG/RSVD */
> +	ret = regmap_update_bits(pca9450->regmap, PCA9450_REG_INT1_MSK,
> +				IRQ_VR_FLT1 | IRQ_VR_FLT2 | IRQ_LOWVSYS |
> +				IRQ_THERM_105 | IRQ_THERM_125,
> +				IRQ_PWRON | IRQ_WDOGB | IRQ_RSVD);
> +	if (ret) {
> +		dev_err(&i2c->dev, "Unmask irq error\n");
> +		return ret;
> +	}
> +
> +	dev_info(&i2c->dev, "%s probed.\n",
> +		type == PCA9450_TYPE_PCA9450A ? "pca9450a" : "pca9450bc");
> +
> +	return 0;
> +}
> +
> +static const struct of_device_id pca9450_of_match[] = {
> +	{
> +		.compatible = "nxp,pca9450a",
> +		.data = (void *)PCA9450_TYPE_PCA9450A,
> +	},
> +	{
> +		.compatible = "nxp,pca9450b",
> +		.data = (void *)PCA9450_TYPE_PCA9450BC,
> +	},
> +	{
> +		.compatible = "nxp,pca9450c",
> +		.data = (void *)PCA9450_TYPE_PCA9450BC,
> +	},
> +	{ }
> +};
> +MODULE_DEVICE_TABLE(of, pca9450_of_match);
> +
> +static struct i2c_driver pca9450_i2c_driver = {
> +	.driver = {
> +		.name = "nxp-pca9450",
> +		.of_match_table = pca9450_of_match,
> +	},
> +	.probe = pca9450_i2c_probe,
> +};
> +
> +static int __init pca9450_i2c_init(void)
> +{
> +	return i2c_add_driver(&pca9450_i2c_driver);
> +}
> +module_init(pca9450_i2c_init);
> +
> +static void __exit pca9450_i2c_exit(void)
> +{
> +	i2c_del_driver(&pca9450_i2c_driver);
> +}
> +module_exit(pca9450_i2c_exit);
> +
> +MODULE_AUTHOR("Robin Gong <yibin.gong@nxp.com>");
> +MODULE_DESCRIPTION("NXP PCA9450 Power Management IC driver");
> +MODULE_LICENSE("GPL");
> diff --git a/include/linux/regulator/pca9450.h b/include/linux/regulator/pca9450.h
> new file mode 100644
> index 00000000..1bbd301
> --- /dev/null
> +++ b/include/linux/regulator/pca9450.h
> @@ -0,0 +1,219 @@
> +/* SPDX-License-Identifier: GPL-2.0-or-later */
> +/* Copyright 2020 NXP. */
> +
> +#ifndef __LINUX_REG_PCA9450_H__
> +#define __LINUX_REG_PCA9450_H__
> +
> +#include <linux/regmap.h>
> +
> +enum pca9450_chip_type {
> +	PCA9450_TYPE_PCA9450A = 0,
> +	PCA9450_TYPE_PCA9450BC,
> +	PCA9450_TYPE_AMOUNT,
> +};
> +
> +enum {
> +	PCA9450_BUCK1 = 0,
> +	PCA9450_BUCK2,
> +	PCA9450_BUCK3,
> +	PCA9450_BUCK4,
> +	PCA9450_BUCK5,
> +	PCA9450_BUCK6,
> +	PCA9450_LDO1,
> +	PCA9450_LDO2,
> +	PCA9450_LDO3,
> +	PCA9450_LDO4,
> +	PCA9450_LDO5,
> +	PCA9450_REGULATOR_CNT,
> +};
> +
> +enum {
> +	PCA9450_DVS_LEVEL_RUN = 0,
> +	PCA9450_DVS_LEVEL_STANDBY,
> +	PCA9450_DVS_LEVEL_MAX,
> +};
> +
> +#define PCA9450_BUCK1_VOLTAGE_NUM	0x80
> +#define PCA9450_BUCK2_VOLTAGE_NUM	0x80
> +#define PCA9450_BUCK3_VOLTAGE_NUM	0x80
> +#define PCA9450_BUCK4_VOLTAGE_NUM	0x80
> +
> +#define PCA9450_BUCK5_VOLTAGE_NUM	0x80
> +#define PCA9450_BUCK6_VOLTAGE_NUM	0x80
> +
> +#define PCA9450_LDO1_VOLTAGE_NUM	0x08
> +#define PCA9450_LDO2_VOLTAGE_NUM	0x08
> +#define PCA9450_LDO3_VOLTAGE_NUM	0x20
> +#define PCA9450_LDO4_VOLTAGE_NUM	0x20
> +#define PCA9450_LDO5_VOLTAGE_NUM	0x10
> +
> +enum {
> +	PCA9450_REG_DEV_ID	    = 0x00,
> +	PCA9450_REG_INT1	    = 0x01,
> +	PCA9450_REG_INT1_MSK	    = 0x02,
> +	PCA9450_REG_STATUS1	    = 0x03,
> +	PCA9450_REG_STATUS2	    = 0x04,
> +	PCA9450_REG_PWRON_STAT	    = 0x05,
> +	PCA9450_REG_SWRST	    = 0x06,
> +	PCA9450_REG_PWRCTRL         = 0x07,
> +	PCA9450_REG_RESET_CTRL      = 0x08,
> +	PCA9450_REG_CONFIG1         = 0x09,
> +	PCA9450_REG_CONFIG2         = 0x0A,
> +	PCA9450_REG_BUCK123_DVS     = 0x0C,
> +	PCA9450_REG_BUCK1OUT_LIMIT  = 0x0D,
> +	PCA9450_REG_BUCK2OUT_LIMIT  = 0x0E,
> +	PCA9450_REG_BUCK3OUT_LIMIT  = 0x0F,
> +	PCA9450_REG_BUCK1CTRL       = 0x10,
> +	PCA9450_REG_BUCK1OUT_DVS0   = 0x11,
> +	PCA9450_REG_BUCK1OUT_DVS1   = 0x12,
> +	PCA9450_REG_BUCK2CTRL       = 0x13,
> +	PCA9450_REG_BUCK2OUT_DVS0   = 0x14,
> +	PCA9450_REG_BUCK2OUT_DVS1   = 0x15,
> +	PCA9450_REG_BUCK3CTRL       = 0x16,
> +	PCA9450_REG_BUCK3OUT_DVS0   = 0x17,
> +	PCA9450_REG_BUCK3OUT_DVS1   = 0x18,
> +	PCA9450_REG_BUCK4CTRL       = 0x19,
> +	PCA9450_REG_BUCK4OUT        = 0x1A,
> +	PCA9450_REG_BUCK5CTRL       = 0x1B,
> +	PCA9450_REG_BUCK5OUT        = 0x1C,
> +	PCA9450_REG_BUCK6CTRL       = 0x1D,
> +	PCA9450_REG_BUCK6OUT        = 0x1E,
> +	PCA9450_REG_LDO_AD_CTRL     = 0x20,
> +	PCA9450_REG_LDO1CTRL        = 0x21,
> +	PCA9450_REG_LDO2CTRL        = 0x22,
> +	PCA9450_REG_LDO3CTRL        = 0x23,
> +	PCA9450_REG_LDO4CTRL        = 0x24,
> +	PCA9450_REG_LDO5CTRL_L      = 0x25,
> +	PCA9450_REG_LDO5CTRL_H      = 0x26,
> +	PCA9450_REG_LOADSW_CTRL     = 0x2A,
> +	PCA9450_REG_VRFLT1_STS      = 0x2B,
> +	PCA9450_REG_VRFLT2_STS      = 0x2C,
> +	PCA9450_REG_VRFLT1_MASK     = 0x2D,
> +	PCA9450_REG_VRFLT2_MASK     = 0x2E,
> +	PCA9450_MAX_REGISTER	    = 0x2F,
> +};
> +
> +/* PCA9450 BUCK ENMODE bits */
> +#define BUCK_ENMODE_OFF			0x00
> +#define BUCK_ENMODE_ONREQ		0x01
> +#define BUCK_ENMODE_ONREQ_STBYREQ	0x02
> +#define BUCK_ENMODE_ON			0x03
> +
> +/* PCA9450_REG_BUCK1_CTRL bits */
> +#define BUCK1_RAMP_MASK			0xC0
> +#define BUCK1_RAMP_25MV			0x0
> +#define BUCK1_RAMP_12P5MV		0x1
> +#define BUCK1_RAMP_6P25MV		0x2
> +#define BUCK1_RAMP_3P125MV		0x3
> +#define BUCK1_DVS_CTRL			0x10
> +#define BUCK1_AD			0x08
> +#define BUCK1_FPWM			0x04
> +#define BUCK1_ENMODE_MASK		0x03
> +
> +/* PCA9450_REG_BUCK2_CTRL bits */
> +#define BUCK2_RAMP_MASK			0xC0
> +#define BUCK2_RAMP_25MV			0x0
> +#define BUCK2_RAMP_12P5MV		0x1
> +#define BUCK2_RAMP_6P25MV		0x2
> +#define BUCK2_RAMP_3P125MV		0x3
> +#define BUCK2_DVS_CTRL			0x10
> +#define BUCK2_AD			0x08
> +#define BUCK2_FPWM			0x04
> +#define BUCK2_ENMODE_MASK		0x03
> +
> +/* PCA9450_REG_BUCK3_CTRL bits */
> +#define BUCK3_RAMP_MASK			0xC0
> +#define BUCK3_RAMP_25MV			0x0
> +#define BUCK3_RAMP_12P5MV		0x1
> +#define BUCK3_RAMP_6P25MV		0x2
> +#define BUCK3_RAMP_3P125MV		0x3
> +#define BUCK3_DVS_CTRL			0x10
> +#define BUCK3_AD			0x08
> +#define BUCK3_FPWM			0x04
> +#define BUCK3_ENMODE_MASK		0x03
> +
> +/* PCA9450_REG_BUCK4_CTRL bits */
> +#define BUCK4_AD			0x08
> +#define BUCK4_FPWM			0x04
> +#define BUCK4_ENMODE_MASK		0x03
> +
> +/* PCA9450_REG_BUCK5_CTRL bits */
> +#define BUCK5_AD			0x08
> +#define BUCK5_FPWM			0x04
> +#define BUCK5_ENMODE_MASK		0x03
> +
> +/* PCA9450_REG_BUCK6_CTRL bits */
> +#define BUCK6_AD			0x08
> +#define BUCK6_FPWM			0x04
> +#define BUCK6_ENMODE_MASK		0x03
> +
> +/* PCA9450_BUCK1OUT_DVS0 bits */
> +#define BUCK1OUT_DVS0_MASK		0x7F
> +#define BUCK1OUT_DVS0_DEFAULT		0x14
> +
> +/* PCA9450_BUCK1OUT_DVS1 bits */
> +#define BUCK1OUT_DVS1_MASK		0x7F
> +#define BUCK1OUT_DVS1_DEFAULT		0x14
> +
> +/* PCA9450_BUCK2OUT_DVS0 bits */
> +#define BUCK2OUT_DVS0_MASK		0x7F
> +#define BUCK2OUT_DVS0_DEFAULT		0x14
> +
> +/* PCA9450_BUCK2OUT_DVS1 bits */
> +#define BUCK2OUT_DVS1_MASK		0x7F
> +#define BUCK2OUT_DVS1_DEFAULT		0x14
> +
> +/* PCA9450_BUCK3OUT_DVS0 bits */
> +#define BUCK3OUT_DVS0_MASK		0x7F
> +#define BUCK3OUT_DVS0_DEFAULT		0x14
> +
> +/* PCA9450_BUCK3OUT_DVS1 bits */
> +#define BUCK3OUT_DVS1_MASK		0x7F
> +#define BUCK3OUT_DVS1_DEFAULT		0x14
> +
> +/* PCA9450_REG_BUCK4OUT bits */
> +#define BUCK4OUT_MASK			0x7F
> +#define BUCK4OUT_DEFAULT		0x6C
> +
> +/* PCA9450_REG_BUCK5OUT bits */
> +#define BUCK5OUT_MASK			0x7F
> +#define BUCK5OUT_DEFAULT		0x30
> +
> +/* PCA9450_REG_BUCK6OUT bits */
> +#define BUCK6OUT_MASK			0x7F
> +#define BUCK6OUT_DEFAULT		0x14
> +
> +/* PCA9450_REG_LDO1_VOLT bits */
> +#define LDO1_EN_MASK			0xC0
> +#define LDO1OUT_MASK			0x07
> +
> +/* PCA9450_REG_LDO2_VOLT bits */
> +#define LDO2_EN_MASK			0xC0
> +#define LDO2OUT_MASK			0x07
> +
> +/* PCA9450_REG_LDO3_VOLT bits */
> +#define LDO3_EN_MASK			0xC0
> +#define LDO3OUT_MASK			0x0F
> +
> +/* PCA9450_REG_LDO4_VOLT bits */
> +#define LDO4_EN_MASK			0xC0
> +#define LDO4OUT_MASK			0x0F
> +
> +/* PCA9450_REG_LDO5_VOLT bits */
> +#define LDO5L_EN_MASK			0xC0
> +#define LDO5LOUT_MASK			0x0F
> +
> +#define LDO5H_EN_MASK			0xC0
> +#define LDO5HOUT_MASK			0x0F
> +
> +/* PCA9450_REG_IRQ bits */
> +#define IRQ_PWRON			0x80
> +#define IRQ_WDOGB			0x40
> +#define IRQ_RSVD			0x20
> +#define IRQ_VR_FLT1			0x10
> +#define IRQ_VR_FLT2			0x08
> +#define IRQ_LOWVSYS			0x04
> +#define IRQ_THERM_105			0x02
> +#define IRQ_THERM_125			0x01
> +
> +#endif /* __LINUX_REG_PCA9450_H__ */
> 

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

* Re: [PATCH v2 0/4] Add pca9450 driver
  2020-07-03 16:19 [PATCH v2 0/4] Add pca9450 driver Robin Gong
                   ` (3 preceding siblings ...)
  2020-07-03 16:19 ` [PATCH v2 4/4] arm64: configs: add pca9450 pmic driver Robin Gong
@ 2020-07-06 14:43 ` Mark Brown
  4 siblings, 0 replies; 9+ messages in thread
From: Mark Brown @ 2020-07-06 14:43 UTC (permalink / raw)
  To: catalin.marinas, s.hauer, shawnguo, Robin Gong, lgirdwood,
	john.lee, will, anson.huang, robh+dt, festevam, frieder.schrempf
  Cc: linux-imx, linux-arm-kernel, linux-kernel, devicetree, kernel

On Sat, 4 Jul 2020 00:19:34 +0800, Robin Gong wrote:
> Add pca9450 driver for i.mx8mn-evk board. PCA9450A/B/C supported now.
> Please refer to below link for PCA9450 datasheet:
> https://www.nxp.com/docs/en/data-sheet/PCA9450DS.pdf
> 
> v2:
>   1. rebase with the latest code to use linear_ranges helper instead.
>   2. address Frieder's comments, such as dulipcated buck4 description,
>      debug info added etc.
> 
> [...]

Applied to

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

Thanks!

[1/2] regulator: pca9450: add pca9450 pmic driver
      commit: 0935ff5f1f0a44f66a13e075ed49f97ad99d2fdc
[2/2] dt-bindings: regulator: add pca9450 regulator yaml
      commit: 7ae9e3a6bf3fb1b5a35a15d8a6e78fc42bed0867

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

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

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

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

Thanks,
Mark

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

* Re: [PATCH v2 3/4] arm64: dts: imx8mn-evk: add pca9450 for i.mx8mn-evk board
  2020-07-03 16:19 ` [PATCH v2 3/4] arm64: dts: imx8mn-evk: add pca9450 for i.mx8mn-evk board Robin Gong
@ 2020-07-13  4:09   ` Shawn Guo
  0 siblings, 0 replies; 9+ messages in thread
From: Shawn Guo @ 2020-07-13  4:09 UTC (permalink / raw)
  To: Robin Gong
  Cc: lgirdwood, broonie, robh+dt, frieder.schrempf, catalin.marinas,
	will, anson.huang, festevam, s.hauer, john.lee, kernel,
	devicetree, linux-kernel, linux-arm-kernel, linux-imx

On Sat, Jul 04, 2020 at 12:19:37AM +0800, Robin Gong wrote:
> Add pca9450 pmic driver for i.mx8mn-evk board.
> 
> Signed-off-by: Robin Gong <yibin.gong@nxp.com>

Applied, thanks.

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

* Re: [PATCH v2 4/4] arm64: configs: add pca9450 pmic driver
  2020-07-03 16:19 ` [PATCH v2 4/4] arm64: configs: add pca9450 pmic driver Robin Gong
@ 2020-07-13  4:11   ` Shawn Guo
  0 siblings, 0 replies; 9+ messages in thread
From: Shawn Guo @ 2020-07-13  4:11 UTC (permalink / raw)
  To: Robin Gong
  Cc: lgirdwood, broonie, robh+dt, frieder.schrempf, catalin.marinas,
	will, anson.huang, festevam, s.hauer, john.lee, kernel,
	devicetree, linux-kernel, linux-arm-kernel, linux-imx

On Sat, Jul 04, 2020 at 12:19:38AM +0800, Robin Gong wrote:
> Add pca9450 pmic driver.
> 
> Signed-off-by: Robin Gong <yibin.gong@nxp.com>

Updated subject prefix like 'arm64: defconfig: ...' and applied patch.

Shawn

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

end of thread, other threads:[~2020-07-13  4:12 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-07-03 16:19 [PATCH v2 0/4] Add pca9450 driver Robin Gong
2020-07-03 16:19 ` [PATCH v2 1/4] regulator: pca9450: add pca9450 pmic driver Robin Gong
2020-07-06  8:02   ` Frieder Schrempf
2020-07-03 16:19 ` [PATCH v2 2/4] dt-bindings: regulator: add pca9450 regulator yaml Robin Gong
2020-07-03 16:19 ` [PATCH v2 3/4] arm64: dts: imx8mn-evk: add pca9450 for i.mx8mn-evk board Robin Gong
2020-07-13  4:09   ` Shawn Guo
2020-07-03 16:19 ` [PATCH v2 4/4] arm64: configs: add pca9450 pmic driver Robin Gong
2020-07-13  4:11   ` Shawn Guo
2020-07-06 14:43 ` [PATCH v2 0/4] Add pca9450 driver Mark Brown

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