diff mbox series

[6/9] regulator: da9121: Update registration to support multiple buck variants

Message ID a2b4186b47e4786bd856ec11d2353b7183c22af2.1605868780.git.Adam.Ward.opensource@diasemi.com
State New
Headers show
Series regulator: da9121: extend support to variants, add features | expand

Commit Message

Adam Ward Nov. 20, 2020, 12:14 p.m. UTC
Checks DT matches tally with variant maximum and register accordingly.

Signed-off-by: Adam Ward <Adam.Ward.opensource@diasemi.com>
---
 drivers/regulator/da9121-regulator.c | 81 +++++++++++++++++++++++++++++++-----
 1 file changed, 70 insertions(+), 11 deletions(-)

Comments

Mark Brown Nov. 20, 2020, 1:06 p.m. UTC | #1
On Fri, Nov 20, 2020 at 12:14:56PM +0000, Adam Ward wrote:

> Checks DT matches tally with variant maximum and register accordingly.

This changelog doesn't really explain what the change is supposed to
be doing or why which makes it very hard to review, and the code is far
from obvious.  I can't really tie much of the change to the words here.

> +	if (max_matches > variant_parameters[chip->variant_id].num_bucks) {
> +		dev_err(chip->dev, "Too many regulators in the DT\n");
> +		ret = -EINVAL;
> +		goto error;
> +	}

If this validation is needed it should be in the regulator core.

> +	for (i = 0; i < max_matches; i++) {
> +		const struct regulator_desc *regl_desc =
> +			local_da9121_regulators[chip->variant_id][i];
> +		int id = regl_desc->id;
> +		struct gpio_desc *gpio_ren;
> +
> +		if (chip->pdata->gpiod_ren[i])
> +			gpio_ren = chip->pdata->gpiod_ren[i];
> +		else
> +			gpio_ren = NULL;
> +
> +		config.init_data = chip->pdata->init_data[i];
> +		config.dev = chip->dev;
> +		config.driver_data = chip;
> +		config.regmap = chip->regmap;
> +		config.of_node = chip->pdata->reg_node[i];

I *think* this is all open coding the core's DT parsing support.
diff mbox series

Patch

diff --git a/drivers/regulator/da9121-regulator.c b/drivers/regulator/da9121-regulator.c
index 5020774..13b0aad 100644
--- a/drivers/regulator/da9121-regulator.c
+++ b/drivers/regulator/da9121-regulator.c
@@ -314,6 +314,69 @@  static struct da9121_pdata *da9121_parse_regulators_dt(struct da9121 *chip)
 }
 #endif
 
+static int da9121_set_regulator_config(struct da9121 *chip)
+{
+	struct regulator_config config = { };
+	unsigned int max_matches = chip->pdata->num_buck;
+	int ret = 0;
+	int i;
+
+	if (max_matches > variant_parameters[chip->variant_id].num_bucks) {
+		dev_err(chip->dev, "Too many regulators in the DT\n");
+		ret = -EINVAL;
+		goto error;
+	}
+
+	for (i = 0; i < max_matches; i++) {
+		const struct regulator_desc *regl_desc =
+			local_da9121_regulators[chip->variant_id][i];
+		int id = regl_desc->id;
+		struct gpio_desc *gpio_ren;
+
+		if (chip->pdata->gpiod_ren[i])
+			gpio_ren = chip->pdata->gpiod_ren[i];
+		else
+			gpio_ren = NULL;
+
+		config.init_data = chip->pdata->init_data[i];
+		config.dev = chip->dev;
+		config.driver_data = chip;
+		config.regmap = chip->regmap;
+		config.of_node = chip->pdata->reg_node[i];
+
+		switch (id) {
+		case DA9121_IDX_BUCK1:
+		case DA9121_IDX_BUCK2:
+			config.ena_gpiod = gpio_ren;
+			break;
+		default:
+			dev_err(chip->dev, "Invalid regulator ID\n");
+			ret = -EINVAL;
+			goto error;
+		}
+
+		/*
+		 * Hand the GPIO descriptor management over to the regulator
+		 * core, remove it from GPIO devres management.
+		 */
+		if (config.ena_gpiod)
+			devm_gpiod_unhinge(chip->dev, config.ena_gpiod);
+
+		chip->rdev[i] = devm_regulator_register(chip->dev,
+					regl_desc,
+					&config);
+		if (IS_ERR(chip->rdev[i])) {
+			dev_err(chip->dev, "Failed to register regulator %s, %d/%d of_map_mode:%p\n",
+				regl_desc->name, (i+1), max_matches, regl_desc->of_map_mode);
+			ret = PTR_ERR(chip->rdev[i]);
+			goto error;
+		}
+	}
+
+error:
+	return ret;
+}
+
 /* DA9121 chip register model */
 static const struct regmap_range da9121_1ch_readable_ranges[] = {
 	regmap_reg_range(DA9121_REG_SYS_STATUS_0, DA9121_REG_SYS_MASK_3),
@@ -586,9 +649,6 @@  static int da9121_i2c_probe(struct i2c_client *i2c,
 {
 	struct da9121 *chip;
 	int ret = 0;
-	struct device *dev = &i2c->dev;
-	struct regulator_config config = {};
-	struct regulator_dev *rdev;
 
 	chip = devm_kzalloc(&i2c->dev, sizeof(struct da9121), GFP_KERNEL);
 	if (!chip) {
@@ -606,16 +666,15 @@  static int da9121_i2c_probe(struct i2c_client *i2c,
 	if (!chip->pdata)
 		chip->pdata = da9121_parse_regulators_dt(chip);
 
-	config.dev = &i2c->dev;
-	config.of_node = dev->of_node;
-	config.regmap = chip->regmap;
-
-	rdev = devm_regulator_register(&i2c->dev, &da9121_reg, &config);
-	if (IS_ERR(rdev)) {
-		dev_err(&i2c->dev, "Failed to register da9121 regulator\n");
-		return PTR_ERR(rdev);
+	if (IS_ERR(chip->pdata)) {
+		dev_err(chip->dev, "No regulators defined for the platform\n");
+		return PTR_ERR(chip->pdata);
 	}
 
+	ret = da9121_set_regulator_config(chip);
+	if (ret < 0)
+		goto error;
+
 error:
 	return ret;
 }