drivers: regulator: pca9420: refactor mode handling

- Similar to what was done for other parts of the driver, remove any
  register specification from Devicetree (modesel-reg/mask)
- Keep all the information in the driver, and define modes as "numbers",
  e.g. PCA9420_MODE0: 0, PCA9420_MODE1: 1, etc.
- Bindings provide IC defaults now (all modes allowed 0/1/2/3 and
  initial mode set to 0).
- When mode is controlled via the MODESEL0/1 pins (ie directly by an iMX
  MCU using the dedicated PMIC_MODE0/1 pins), the driver will not allow
  to select a mode (it is not possible). This mode is now enabled by
  setting `nxp,enable-modesel-pins` in Devicetree. When enabled, all the
  allowed modes are configured to be selectable via pins. When disabled,
  mode can be set via I2C (using TOP_CNTL3 MODE0/1_I2C fields)

Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
diff --git a/boards/arm/mimxrt595_evk/mimxrt595_evk_cm33.dts b/boards/arm/mimxrt595_evk/mimxrt595_evk_cm33.dts
index 58c96d3..cbed467 100644
--- a/boards/arm/mimxrt595_evk/mimxrt595_evk_cm33.dts
+++ b/boards/arm/mimxrt595_evk/mimxrt595_evk_cm33.dts
@@ -159,28 +159,10 @@
 	pinctrl-names = "default";
 
 	pca9420: pca9420@61 {
-		reg = <0x61>;
 		compatible = "nxp,pca9420";
-		/*
-		 * This mode-reg setting will permit mode control by
-		 * pins, a feature of the PCA9240. If mode control via
-		 * I2C is desired, the following settings
-		 * should be used:
-		 * regulator-initial-mode = <PCA9420_MODECFG0_I2C>;
-		 * regulator-allowed-modes = <PCA9420_MODECFG0_I2C>,
-		 *			<PCA9420_MODECFG1_I2C>,
-		 *			<PCA9420_MODECFG2_I2C>,
-		 *			<PCA9420_MODECFG3_I2C>;
-		 * modesel-reg = <PCA9420_TOP_CNTL3>;
-		 * modesel-mask = <PCA9420_TOP_CNTL3_MODE_I2C_MASK>;
-		 */
-		regulator-allowed-modes = <PCA9420_MODECFG0_PIN>,
-					<PCA9420_MODECFG1_PIN>,
-					<PCA9420_MODECFG2_PIN>,
-					<PCA9420_MODECFG3_PIN>;
-		regulator-initial-mode = <PCA9420_MODECFG0_PIN>;
-		modesel-reg = <PCA9420_MODECFG_0_0>;
-		modesel-mask = <PCA9420_MODECFG_0_MODE_CTRL_SEL_MASK>;
+		reg = <0x61>;
+		nxp,enable-modesel-pins;
+
 		pca9420_sw1: BUCK1 {
 			regulator-min-microvolt = <500000>;
 			regulator-max-microvolt = <1800000>;
diff --git a/boards/arm/mimxrt685_evk/mimxrt685_evk_cm33.dts b/boards/arm/mimxrt685_evk/mimxrt685_evk_cm33.dts
index 17127e0..e198c9f 100644
--- a/boards/arm/mimxrt685_evk/mimxrt685_evk_cm33.dts
+++ b/boards/arm/mimxrt685_evk/mimxrt685_evk_cm33.dts
@@ -229,28 +229,10 @@
 	pinctrl-names = "default";
 
 	pca9420: pca9420@61 {
-		reg = <0x61>;
 		compatible = "nxp,pca9420";
-		/*
-		 * This mode-reg setting will permit mode control by
-		 * pins, a feature of the PCA9240. If mode control via
-		 * I2C is desired, the following settings
-		 * should be used:
-		 * regulator-initial-mode = <PCA9420_MODECFG0_I2C>;
-		 * regulator-allowed-modes = <PCA9420_MODECFG0_I2C>,
-		 *			<PCA9420_MODECFG1_I2C>,
-		 *			<PCA9420_MODECFG2_I2C>,
-		 *			<PCA9420_MODECFG3_I2C>;
-		 * modesel-reg = <PCA9420_TOP_CNTL3>;
-		 * modesel-mask = <PCA9420_TOP_CNTL3_MODE_I2C_MASK>;
-		 */
-		regulator-allowed-modes = <PCA9420_MODECFG0_PIN>,
-					<PCA9420_MODECFG1_PIN>,
-					<PCA9420_MODECFG2_PIN>,
-					<PCA9420_MODECFG3_PIN>;
-		regulator-initial-mode = <PCA9420_MODECFG0_PIN>;
-		modesel-reg = <PCA9420_MODECFG_0_0>;
-		modesel-mask = <PCA9420_MODECFG_0_MODE_CTRL_SEL_MASK>;
+		reg = <0x61>;
+		nxp,enable-modesel-pins;
+
 		BUCK1 {
 			regulator-min-microvolt = <500000>;
 			regulator-max-microvolt = <1800000>;
diff --git a/drivers/regulator/regulator_pca9420.c b/drivers/regulator/regulator_pca9420.c
index 5604dc2..e97e009 100644
--- a/drivers/regulator/regulator_pca9420.c
+++ b/drivers/regulator/regulator_pca9420.c
@@ -18,6 +18,8 @@
 /** General purpose registers */
 /** @brief Top level system ctrl 0 */
 #define PCA9420_TOP_CNTL0     0x09U
+/** @brief Top level system ctrl 3 */
+#define PCA9420_TOP_CNTL3     0x0CU
 
 /** Regulator status indication registers */
 /** @brief Mode configuration for mode 0_0 */
@@ -34,11 +36,15 @@
 #define PCA9420_TOP_CNTL0_VIN_ILIM_SEL_MASK 0xE0U
 #define PCA9420_TOP_CNTL0_VIN_ILIM_SEL_DISABLED 0x7U
 
+/** @brief I2C Mode control mask */
+#define PCA9420_TOP_CNTL3_MODE_I2C_POS 3U
+#define PCA9420_TOP_CNTL3_MODE_I2C_MASK 0x18U
+
 /*
  * @brief Mode control selection mask. When this bit is set, the external
  * PMIC pins MODESEL0 and MODESEL1 can be used to select the active mode
  */
-#define PCA9420_MODECFG_0_MODE_CTRL_SEL_MASK 0x40U
+#define PCA9420_MODECFG_0_X_EN_MODE_SEL_BY_PIN 0x40U
 
 /*
  * @brief Mode configuration upon falling edge applied to ON pin. If set,
@@ -75,6 +81,9 @@
 /** VIN ILIM minimum value, uA */
 #define PCA9420_VIN_ILIM_MIN_UA 85000
 
+/** Offset applied to MODECFG* registers for a given mode */
+#define PCA9420_MODECFG_OFFSET(mode) ((mode) * 4U)
+
 struct regulator_pca9420_desc {
 	uint8_t enable_reg;
 	uint8_t enable_mask;
@@ -89,11 +98,13 @@
 struct regulator_pca9420_common_config {
 	struct i2c_dt_spec i2c;
 	int32_t vin_ilim_ua;
-	uint8_t modesel_reg;
-	uint8_t modesel_mask;
-	const uint16_t *allowed_modes;
-	int num_modes;
-	uint16_t initial_mode;
+	const uint8_t *allowed_modes;
+	uint8_t allowed_modes_cnt;
+	bool enable_modesel_pins;
+};
+
+struct regulator_pca9420_common_data {
+	uint8_t mode;
 };
 
 struct regulator_pca9420_config {
@@ -181,13 +192,23 @@
 						  int32_t min_uv,
 						  int32_t max_uv);
 
-/*
- * Internal helper function- gets the voltage from a regulator, with an
- * offset applied to the vsel_reg. Useful to support reading voltages
- * in another target mode
- */
-static int regulator_pca9420_get_voltage_offset(const struct device *dev,
-						uint32_t off, int32_t *voltage)
+static bool regulator_pca9420_is_mode_allowed(const struct device *dev,
+					      uint8_t mode)
+{
+	const struct regulator_pca9420_config *config = dev->config;
+	const struct regulator_pca9420_common_config *cconfig = config->parent->config;
+
+	for (uint8_t i = 0U; i < cconfig->allowed_modes_cnt; i++) {
+		if (mode == cconfig->allowed_modes[i]) {
+			return true;
+		}
+	}
+
+	return false;
+}
+
+static int regulator_pca9420_get_voltage_mode(const struct device *dev,
+					      uint8_t mode, int32_t *voltage)
 {
 	const struct regulator_pca9420_config *config = dev->config;
 	const struct regulator_pca9420_common_config *cconfig = config->parent->config;
@@ -195,8 +216,14 @@
 	int ret;
 	uint8_t raw_reg;
 
-	ret = i2c_reg_read_byte_dt(&cconfig->i2c, config->desc->vsel_reg + off,
-				   &raw_reg);
+	if (!regulator_pca9420_is_mode_allowed(dev, mode)) {
+		return -ENOTSUP;
+	}
+
+	ret = i2c_reg_read_byte_dt(
+		&cconfig->i2c,
+		config->desc->vsel_reg + PCA9420_MODECFG_OFFSET(mode),
+		&raw_reg);
 	if (ret < 0) {
 		return ret;
 	}
@@ -208,20 +235,19 @@
 					    voltage);
 }
 
-/**
- * Internal helper function- sets the voltage for a regulator, with an
- * offset applied to the vsel_reg. Useful to support setting voltages in
- * another target mode.
- */
-static int regulator_set_voltage_offset(const struct device *dev,
-					int32_t min_uv, int32_t max_uv,
-					uint32_t off)
+static int regulator_set_voltage_mode(const struct device *dev,
+				      int32_t min_uv, int32_t max_uv,
+				      uint8_t mode)
 {
 	const struct regulator_pca9420_config *config = dev->config;
 	const struct regulator_pca9420_common_config *cconfig = config->parent->config;
 	uint16_t idx;
 	int ret;
 
+	if (!regulator_pca9420_is_mode_allowed(dev, mode)) {
+		return -ENOTSUP;
+	}
+
 	ret = linear_range_group_get_win_index(config->desc->ranges,
 					       config->desc->num_ranges, min_uv,
 					       max_uv, &idx);
@@ -231,9 +257,10 @@
 
 	idx <<= config->desc->vsel_pos;
 
-	return i2c_reg_update_byte_dt(&cconfig->i2c,
-				      config->desc->vsel_reg + off,
-				      config->desc->vsel_mask, (uint8_t)idx);
+	return i2c_reg_update_byte_dt(
+		&cconfig->i2c,
+		config->desc->vsel_reg + PCA9420_MODECFG_OFFSET(mode),
+		config->desc->vsel_mask, (uint8_t)idx);
 }
 
 
@@ -258,7 +285,7 @@
 	const struct regulator_pca9420_config *config = dev->config;
 	const struct regulator_pca9420_common_config *cconfig = config->parent->config;
 
-	return cconfig->num_modes;
+	return cconfig->allowed_modes_cnt;
 }
 
 /**
@@ -303,7 +330,10 @@
 static int regulator_pca9420_set_voltage(const struct device *dev,
 					 int32_t min_uv, int32_t max_uv)
 {
-	return regulator_set_voltage_offset(dev, min_uv, max_uv, 0);
+	const struct regulator_pca9420_config *config = dev->config;
+	struct regulator_pca9420_common_data *cdata = config->parent->data;
+
+	return regulator_set_voltage_mode(dev, min_uv, max_uv, cdata->mode);
 }
 
 
@@ -313,9 +343,11 @@
  */
 static int32_t regulator_pca9420_get_voltage(const struct device *dev)
 {
+	const struct regulator_pca9420_config *config = dev->config;
+	struct regulator_pca9420_common_data *cdata = config->parent->data;
 	int32_t voltage = 0;
 
-	(void)regulator_pca9420_get_voltage_offset(dev, 0, &voltage);
+	(void)regulator_pca9420_get_voltage_mode(dev, cdata->mode, &voltage);
 
 	return voltage;
 }
@@ -347,26 +379,7 @@
 					      uint32_t mode, int32_t min_uv,
 					      int32_t max_uv)
 {
-	const struct regulator_pca9420_config *config = dev->config;
-	const struct regulator_pca9420_common_config *cconfig = config->parent->config;
-	uint8_t i, sel_off;
-
-	if (cconfig->num_modes == 0) {
-		return -ENOTSUP;
-	}
-
-	/* Search for mode ID in allowed modes. */
-	for (i = 0 ; i < cconfig->num_modes; i++) {
-		if (cconfig->allowed_modes[i] == mode) {
-			break;
-		}
-	}
-	if (i == cconfig->num_modes) {
-		/* Mode was not found */
-		return -EINVAL;
-	}
-	sel_off = ((mode & PCA9420_MODE_OFFSET_MASK) >> PCA9420_MODE_OFFSET_SHIFT);
-	return regulator_set_voltage_offset(dev, min_uv, max_uv, sel_off);
+	return regulator_set_voltage_mode(dev, min_uv, max_uv, mode);
 }
 
 /*
@@ -379,27 +392,13 @@
 {
 	const struct regulator_pca9420_config *config = dev->config;
 	const struct regulator_pca9420_common_config *cconfig = config->parent->config;
-	uint8_t i, sel_off, dis_val;
+	uint8_t dis_val;
 
-	if (cconfig->num_modes == 0) {
-		return -ENOTSUP;
-	}
-
-	/* Search for mode ID in allowed modes. */
-	for (i = 0 ; i < cconfig->num_modes; i++) {
-		if (cconfig->allowed_modes[i] == mode) {
-			break;
-		}
-	}
-	if (i == cconfig->num_modes) {
-		/* Mode was not found */
-		return -EINVAL;
-	}
-	sel_off = ((mode & PCA9420_MODE_OFFSET_MASK) >> PCA9420_MODE_OFFSET_SHIFT);
 	dis_val = config->enable_inverted ? config->desc->enable_val : 0;
-	return i2c_reg_update_byte_dt(&cconfig->i2c,
-				      config->desc->enable_reg + sel_off,
-				      config->desc->enable_mask, dis_val);
+	return i2c_reg_update_byte_dt(
+		&cconfig->i2c,
+		config->desc->enable_reg + PCA9420_MODECFG_OFFSET(mode),
+		config->desc->enable_mask, dis_val);
 }
 
 /*
@@ -412,27 +411,13 @@
 {
 	const struct regulator_pca9420_config *config = dev->config;
 	const struct regulator_pca9420_common_config *cconfig = config->parent->config;
-	uint8_t i, sel_off, en_val;
+	uint8_t en_val;
 
-	if (cconfig->num_modes == 0) {
-		return -ENOTSUP;
-	}
-
-	/* Search for mode ID in allowed modes. */
-	for (i = 0 ; i < cconfig->num_modes; i++) {
-		if (cconfig->allowed_modes[i] == mode) {
-			break;
-		}
-	}
-	if (i == cconfig->num_modes) {
-		/* Mode was not found */
-		return -EINVAL;
-	}
-	sel_off = ((mode & PCA9420_MODE_OFFSET_MASK) >> PCA9420_MODE_OFFSET_SHIFT);
 	en_val = config->enable_inverted ? 0 : config->desc->enable_val;
-	return i2c_reg_update_byte_dt(&cconfig->i2c,
-				      config->desc->enable_reg + sel_off,
-				      config->desc->enable_mask, en_val);
+	return i2c_reg_update_byte_dt(
+		&cconfig->i2c,
+		config->desc->enable_reg + PCA9420_MODECFG_OFFSET(mode),
+		config->desc->enable_mask, en_val);
 }
 
 /*
@@ -444,74 +429,37 @@
 static int32_t regulator_pca9420_get_mode_voltage(const struct device *dev,
 						  uint32_t mode)
 {
-	const struct regulator_pca9420_config *config = dev->config;
-	const struct regulator_pca9420_common_config *cconfig = config->parent->config;
-	uint8_t i, sel_off;
 	int32_t voltage;
 
-	if (cconfig->num_modes == 0) {
-		return -ENOTSUP;
+	if (regulator_pca9420_get_voltage_mode(dev, mode, &voltage) < 0) {
+		return 0;
 	}
 
-	/* Search for mode ID in allowed modes. */
-	for (i = 0 ; i < cconfig->num_modes; i++) {
-		if (cconfig->allowed_modes[i] == mode) {
-			break;
-		}
-	}
-	if (i == cconfig->num_modes) {
-		/* Mode was not found */
-		return -EINVAL;
-	}
-
-	sel_off = ((mode & PCA9420_MODE_OFFSET_MASK) >> PCA9420_MODE_OFFSET_SHIFT);
-
-	(void)regulator_pca9420_get_voltage_offset(dev, sel_off, &voltage);
-
 	return voltage;
 }
 
-/*
- * Part of the extended regulator consumer API
- * switches the regulator to a given mode. This API will apply a mode for
- * the regulator.
- */
 static int regulator_pca9420_set_mode(const struct device *dev, uint32_t mode)
 {
 	const struct regulator_pca9420_config *config = dev->config;
 	const struct regulator_pca9420_common_config *cconfig = config->parent->config;
-	int rc;
-	uint8_t i, sel_off;
+	struct regulator_pca9420_common_data *cdata = config->parent->data;
+	int ret;
 
-	if (cconfig->num_modes == 0) {
+	if (cconfig->enable_modesel_pins ||
+	    !regulator_pca9420_is_mode_allowed(dev, mode)) {
 		return -ENOTSUP;
 	}
 
-	/* Search for mode ID in allowed modes. */
-	for (i = 0 ; i < cconfig->num_modes; i++) {
-		if (cconfig->allowed_modes[i] == mode) {
-			break;
-		}
+	ret = i2c_reg_update_byte_dt(&cconfig->i2c, PCA9420_TOP_CNTL3,
+				     mode << PCA9420_TOP_CNTL3_MODE_I2C_POS,
+				     PCA9420_TOP_CNTL3_MODE_I2C_MASK);
+	if (ret < 0) {
+		return ret;
 	}
-	if (i == cconfig->num_modes) {
-		/* Mode was not found */
-		return -EINVAL;
-	}
-	sel_off = ((mode & PCA9420_MODE_OFFSET_MASK) >> PCA9420_MODE_OFFSET_SHIFT);
-	/* Configure mode */
-	if (mode & PCA9420_MODE_FLAG_MODESEL_MULTI_REG) {
-		/* Select mode with offset calculation */
-		rc = i2c_reg_update_byte_dt(&cconfig->i2c,
-					    cconfig->modesel_reg + sel_off,
-					    mode & PCA9420_MODE_SELECTOR_MASK,
-					    cconfig->modesel_mask);
-	} else {
-		/* Select mode without offset to modesel_reg */
-		rc = i2c_reg_update_byte_dt(&cconfig->i2c, cconfig->modesel_reg,
-					    mode & PCA9420_MODE_SELECTOR_MASK,
-					    cconfig->modesel_mask);
-	}
-	return rc;
+
+	cdata->mode = mode;
+
+	return 0;
 }
 
 static int regulator_pca9420_enable(const struct device *dev)
@@ -539,7 +487,6 @@
 static int regulator_pca9420_init(const struct device *dev)
 {
 	const struct regulator_pca9420_config *config = dev->config;
-	const struct regulator_pca9420_common_config *cconfig = config->parent->config;
 	int rc  = 0;
 
 	regulator_common_data_init(dev);
@@ -551,21 +498,44 @@
 	if (config->boot_on) {
 		rc = regulator_pca9420_enable(dev);
 	}
-	if (cconfig->initial_mode) {
-		rc = regulator_pca9420_set_mode(dev, cconfig->initial_mode);
-	}
+
 	return rc;
 }
 
 static int regulator_pca9420_common_init(const struct device *dev)
 {
 	const struct regulator_pca9420_common_config *config = dev->config;
+	const struct regulator_pca9420_common_data *data = dev->data;
 	uint8_t reg_val = PCA9420_TOP_CNTL0_VIN_ILIM_SEL_DISABLED;
+	int ret;
 
 	if (!device_is_ready(config->i2c.bus)) {
 		return -ENODEV;
 	}
 
+	if (config->enable_modesel_pins) {
+		/* enable MODESEL0/1 pins for each allowed mode */
+		for (uint8_t i = 0U; i < config->allowed_modes_cnt; i++) {
+			ret = i2c_reg_update_byte_dt(
+				&config->i2c,
+				PCA9420_MODECFG_0_0 +
+				PCA9420_MODECFG_OFFSET(config->allowed_modes[i]),
+				PCA9420_MODECFG_0_X_EN_MODE_SEL_BY_PIN,
+				PCA9420_MODECFG_0_X_EN_MODE_SEL_BY_PIN);
+			if (ret < 0) {
+				return ret;
+			}
+		}
+	} else {
+		ret = i2c_reg_update_byte_dt(
+			&config->i2c, PCA9420_TOP_CNTL3,
+			data->mode << PCA9420_TOP_CNTL3_MODE_I2C_POS,
+			PCA9420_TOP_CNTL3_MODE_I2C_MASK);
+		if (ret < 0) {
+			return ret;
+		}
+	}
+
 	/* configure VIN current limit */
 	if (config->vin_ilim_ua != 0U) {
 		reg_val = (config->vin_ilim_ua - PCA9420_VIN_ILIM_MIN_UA) /
@@ -618,22 +588,24 @@
 		    ())
 
 #define REGULATOR_PCA9420_DEFINE_ALL(inst)                                     \
-	static const uint16_t allowed_modes_##inst[] =                         \
-		DT_INST_PROP_OR(inst, regulator_allowed_modes, {});            \
+	static const uint8_t allowed_modes_##inst[] =                          \
+		DT_INST_PROP(inst, regulator_allowed_modes);                   \
+                                                                               \
+	static struct regulator_pca9420_common_data data_##inst = {            \
+		.mode = DT_INST_PROP(inst, regulator_initial_mode)             \
+	};                                                                     \
                                                                                \
 	static const struct regulator_pca9420_common_config config_##inst = {  \
 		.i2c = I2C_DT_SPEC_INST_GET(inst),                             \
 		.vin_ilim_ua = DT_INST_PROP(inst, nxp_vin_ilim_microamp),      \
 		.allowed_modes = allowed_modes_##inst,                         \
-		.num_modes = ARRAY_SIZE(allowed_modes_##inst),                 \
-		.initial_mode =                                                \
-			DT_INST_PROP_OR(inst, regulator_initial_mode, 0),      \
-		.modesel_reg = DT_INST_PROP_OR(inst, modesel_reg, 0),          \
-		.modesel_mask = DT_INST_PROP_OR(inst, modesel_mask, 0),        \
+		.allowed_modes_cnt = ARRAY_SIZE(allowed_modes_##inst),         \
+		.enable_modesel_pins =                                         \
+			DT_INST_PROP(inst, nxp_enable_modesel_pins),           \
 	};                                                                     \
                                                                                \
-	DEVICE_DT_INST_DEFINE(inst, regulator_pca9420_common_init, NULL, NULL, \
-			      &config_##inst, POST_KERNEL,                     \
+	DEVICE_DT_INST_DEFINE(inst, regulator_pca9420_common_init, NULL,       \
+			      &data_##inst, &config_##inst, POST_KERNEL,       \
 			      CONFIG_REGULATOR_PCA9420_COMMON_INIT_PRIORITY,   \
 			      NULL);                                           \
                                                                                \
diff --git a/dts/bindings/regulator/nxp,pca9420.yaml b/dts/bindings/regulator/nxp,pca9420.yaml
index d913c58..2327d53 100644
--- a/dts/bindings/regulator/nxp,pca9420.yaml
+++ b/dts/bindings/regulator/nxp,pca9420.yaml
@@ -36,6 +36,18 @@
       - regulator-initial-mode
 
 properties:
+  regulator-allowed-modes:
+    default: [0, 1, 2, 3]
+
+  regulator-initial-mode:
+    default: 0
+
+  nxp,enable-modesel-pins:
+    type: boolean
+    description:
+      When enabled, the PMIC will be configured to allow mode selection using
+      the MODESEL0/1 inputs.
+
   nxp,vin-ilim-microamp:
     type: int
     default: 425000
@@ -62,18 +74,6 @@
       To disable current limit, set property to zero. Defaults to 425mA, the IC
       default value.
 
-  modesel-reg:
-    type: int
-    description: |
-      Mode selection register. This register is used by the regulator driver
-      to select the target mode of the regulator
-
-  modesel-mask:
-    type: int
-    description: |
-      Mode selection mask. Applied to a mode selection when it is written
-      to the modesel-reg.
-
 child-binding:
   include:
     - name: regulator.yaml
diff --git a/include/zephyr/dt-bindings/regulator/pca9420.h b/include/zephyr/dt-bindings/regulator/pca9420.h
index 1db2cb6..ed9de39 100644
--- a/include/zephyr/dt-bindings/regulator/pca9420.h
+++ b/include/zephyr/dt-bindings/regulator/pca9420.h
@@ -4,110 +4,25 @@
  * SPDX-License-Identifier: Apache-2.0
  */
 
-#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_REGULATOR_PCA9420_I2C_H_
-#define ZEPHYR_INCLUDE_DT_BINDINGS_REGULATOR_PCA9420_I2C_H_
+#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_REGULATOR_PCA9420_H_
+#define ZEPHYR_INCLUDE_DT_BINDINGS_REGULATOR_PCA9420_H_
 
-#define PCA9420_MODE_OFFSET_MASK 0x1E00
-#define PCA9420_MODE_OFFSET_SHIFT 0x9
-
-/*
- * PMIC mode offset macro. This macro will encode a PMIC mode offset into
- * a given PMIC mode. When selecting a mode for the regulator, all registers
- * will have an offset applied (vsel, ilim, enable), so that the new mode
- * can be configured. This macro encodes that offset for a given mode.
- * @param off: Offset to apply to PMIC config regs when selecting mode
- */
-#define PCA9420_MODE_OFFSET(off) \
-	((off << PCA9420_MODE_OFFSET_SHIFT) & PCA9420_MODE_OFFSET_MASK)
-
-
-/*
- * PMIC mode selection multi-register flag. This flag indicates that the
- * mode selection register for this mode requires an offset applied to it.
- * When this flag is set for a given mode, the value passed as the PMIC
- * mode selector will be written into the register:
- * <modesel-reg> + <pmic mode offset value>. If the flag is not passed,
- * the value of the PMIC mode selector will be written directly to
- * <modesel-reg> with no offset applied.
- */
-#define PCA9420_MODE_FLAG_MODESEL_MULTI_REG 0x100
-
-/*
- * PMIC flags mask. These bits are used to indicate features or requirements
- * of PMIC modes.
- */
-#define PCA9420_MODE_FLAGS_MASK 0xF00
-
-#define PCA9420_MODE_SELECTOR_MASK 0xFF
-
-/*
- * PMIC mode selector macro. This macro should be passed a value to be written
- * to the PMIC modesel-reg, in order to select a given mode. When the regulator
- * driver mode is switched, this value will be written to <modesel-reg>, or
- * <modesel-reg> + <pmic mode offset value> if MODESEL_MULTI_REG flag is set.
- * this will switch the PMIC to the new mode, which can then be configured with
- * the voltage and current limit setting APIs.
- * @param mode: mode selection value, to be written to modesel-reg
- */
-#define PCA9420_MODE_SELECTOR(mode) (mode & PCA9420_MODE_SELECTOR_MASK)
-
-
-/*
- * PMIC mode macro. This macro should be used to create a PMIC mode definition
- * for each PMIC mode. Each mode encodes the offset that must be applied to
- * the regulator's configuration registers to manage the specific mode, as well
- * as the value to write to the regulators' <modesel-reg>. Finally, the flags
- * field controls specific behaviors of the PMIC mode, which are defined
- * with the pattern PCA9420_MODE_FLAG_xxx.
- *
- * @param offset: offset to apply to regulator configuration registers to
- *	configure the target PMIC mode's voltage and current
- * @param flags: pmic mode flags, used to indicate specific behaviors of
- *	a given mode.
- * @param selection_val: selection value, this is the actual value to be
- *	written to the pmic's <modesel-reg> to select the given mode.
+/**
+ * @defgroup regulator_pca9420 PCA9420 Devicetree helpers.
+ * @ingroup regulator_interface
+ * @{
  */
 
-#define PCA9420_MODE(offset, flags, selection_val) \
-	PCA9420_MODE_OFFSET(offset) | \
-	(flags & PCA9420_MODE_FLAGS_MASK) | \
-	PCA9420_MODE_SELECTOR(selection_val)
-
-#define PCA9420_MODECFG0 \
-	(PCA9420_MODE(0x0, 0x0, 0x0)) /* ModeCfg 0, selected via I2C */
-#define PCA9420_MODECFG1 \
-	(PCA9420_MODE(0x4, 0x0, 0x8)) /* ModeCfg 1, selected via I2C */
-#define PCA9420_MODECFG2 \
-	(PCA9420_MODE(0x8, 0x0, 0x10)) /* ModeCfg 2, selected via I2C */
-#define PCA9420_MODECFG3 \
-	(PCA9420_MODE(0xC, 0x0, 0x18)) /* ModeCfg 3, selected via I2C */
-
-/* ModeCfg 0, selected via PIN */
-#define PCA9420_MODECFG0_PIN \
-	(PCA9420_MODE(0x0, PCA9420_MODE_FLAG_MODESEL_MULTI_REG, 0x40))
-/* ModeCfg 1, selected via PIN */
-#define PCA9420_MODECFG1_PIN \
-	(PCA9420_MODE(0x4, PCA9420_MODE_FLAG_MODESEL_MULTI_REG, 0x40))
-/* ModeCfg 2, selected via PIN */
-#define PCA9420_MODECFG2_PIN \
-	(PCA9420_MODE(0x8, PCA9420_MODE_FLAG_MODESEL_MULTI_REG, 0x40))
-/* ModeCfg 3, selected via PIN */
-#define PCA9420_MODECFG3_PIN \
-	(PCA9420_MODE(0xC, PCA9420_MODE_FLAG_MODESEL_MULTI_REG, 0x40))
-
-/** @brief Top level system ctrl 3 */
-#define PCA9420_TOP_CNTL3     0x0CU
-
-/** @brief Mode configuration for mode 0_0 */
-#define PCA9420_MODECFG_0_0          0x22U
-
-/** @brief I2C Mode control mask */
-#define PCA9420_TOP_CNTL3_MODE_I2C_MASK 0x18U
-
-/*
- * @brief Mode control selection mask. When this bit is set, the external
- * PMIC pins MODESEL0 and MODESEL1 can be used to select the active mode
+/**
+ * @name PCA9420 Regulator modes
+ * @{
  */
-#define PCA9420_MODECFG_0_MODE_CTRL_SEL_MASK 0x40U
+#define PCA9420_MODE0 0
+#define PCA9420_MODE1 1
+#define PCA9420_MODE2 2
+#define PCA9420_MODE3 3
+/** @} */
 
-#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_REGULATOR_PCA9420_I2C_H_*/
+/** @} */
+
+#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_REGULATOR_PCA9420_H_*/