Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

regulator: da9121: Add support for device variants via devicetree

Add devicetree configuration and device variant parameters. Use the latter
to enable the check and use of parameters specific to dual buck variants.

Signed-off-by: Adam Ward <Adam.Ward.opensource@diasemi.com>
Link: https://lore.kernel.org/r/5849ce60595aef1018bdde7dcfb54a7397597545.1606755367.git.Adam.Ward.opensource@diasemi.com
Signed-off-by: Mark Brown <broonie@kernel.org>

authored by

Adam Ward and committed by
Mark Brown
46c413d5 91863239

+130
+119
drivers/regulator/da9121-regulator.c
··· 14 14 // Copyright (C) 2020 Dialog Semiconductor 15 15 16 16 #include <linux/of_device.h> 17 + #include <linux/of_gpio.h> 17 18 #include <linux/regulator/of_regulator.h> 18 19 #include <linux/regulator/machine.h> 19 20 #include <linux/regulator/driver.h> ··· 29 28 /* Chip data */ 30 29 struct da9121 { 31 30 struct device *dev; 31 + struct da9121_pdata *pdata; 32 32 struct regmap *regmap; 33 33 int variant_id; 34 + }; 35 + 36 + /* Define ranges for different variants, enabling translation to/from 37 + * registers. Maximums give scope to allow for transients. 38 + */ 39 + struct da9121_range { 40 + int val_min; 41 + int val_max; 42 + int val_stp; 43 + int reg_min; 44 + int reg_max; 45 + }; 46 + 47 + struct da9121_range da9121_10A_2phase_current = { 48 + .val_min = 7000000, 49 + .val_max = 20000000, 50 + .val_stp = 1000000, 51 + .reg_min = 1, 52 + .reg_max = 14, 53 + }; 54 + 55 + struct da9121_range da9121_6A_2phase_current = { 56 + .val_min = 7000000, 57 + .val_max = 12000000, 58 + .val_stp = 1000000, 59 + .reg_min = 1, 60 + .reg_max = 6, 61 + }; 62 + 63 + struct da9121_range da9121_5A_1phase_current = { 64 + .val_min = 3500000, 65 + .val_max = 10000000, 66 + .val_stp = 500000, 67 + .reg_min = 1, 68 + .reg_max = 14, 69 + }; 70 + 71 + struct da9121_range da9121_3A_1phase_current = { 72 + .val_min = 3500000, 73 + .val_max = 6000000, 74 + .val_stp = 500000, 75 + .reg_min = 1, 76 + .reg_max = 6, 77 + }; 78 + 79 + struct da9121_variant_info { 80 + int num_bucks; 81 + int num_phases; 82 + struct da9121_range *current_range; 83 + }; 84 + 85 + static const struct da9121_variant_info variant_parameters[] = { 86 + { 1, 2, &da9121_10A_2phase_current }, //DA9121_TYPE_DA9121_DA9130 87 + { 2, 1, &da9121_3A_1phase_current }, //DA9121_TYPE_DA9220_DA9132 88 + { 2, 1, &da9121_5A_1phase_current }, //DA9121_TYPE_DA9122_DA9131 89 + { 1, 2, &da9121_6A_2phase_current }, //DA9121_TYPE_DA9217 34 90 }; 35 91 36 92 static const struct regulator_ops da9121_buck_ops = { ··· 104 46 [DA9121_IDX_BUCK2] = { .name = "buck2" }, 105 47 }; 106 48 49 + static int da9121_of_parse_cb(struct device_node *np, 50 + const struct regulator_desc *desc, 51 + struct regulator_config *config) 52 + { 53 + struct da9121 *chip = config->driver_data; 54 + struct da9121_pdata *pdata; 55 + struct gpio_desc *ena_gpiod; 56 + 57 + if (chip->pdata == NULL) { 58 + pdata = devm_kzalloc(chip->dev, sizeof(*pdata), GFP_KERNEL); 59 + if (!pdata) 60 + return -ENOMEM; 61 + } else { 62 + pdata = chip->pdata; 63 + } 64 + 65 + pdata->num_buck++; 66 + 67 + if (pdata->num_buck > variant_parameters[chip->variant_id].num_bucks) { 68 + dev_err(chip->dev, "Error: excessive regulators for device\n"); 69 + return -ENODEV; 70 + } 71 + 72 + ena_gpiod = fwnode_gpiod_get_index(of_fwnode_handle(np), "enable", 0, 73 + GPIOD_OUT_HIGH | 74 + GPIOD_FLAGS_BIT_NONEXCLUSIVE, 75 + "da9121-enable"); 76 + if (!IS_ERR(ena_gpiod)) 77 + config->ena_gpiod = ena_gpiod; 78 + 79 + if (variant_parameters[chip->variant_id].num_bucks == 2) { 80 + uint32_t ripple_cancel; 81 + uint32_t ripple_reg; 82 + int ret; 83 + 84 + if (of_property_read_u32(da9121_matches[pdata->num_buck].of_node, 85 + "dlg,ripple-cancel", &ripple_cancel)) { 86 + if (pdata->num_buck > 1) 87 + ripple_reg = DA9xxx_REG_BUCK_BUCK2_7; 88 + else 89 + ripple_reg = DA9121_REG_BUCK_BUCK1_7; 90 + 91 + ret = regmap_update_bits(chip->regmap, ripple_reg, 92 + DA9xxx_MASK_BUCK_BUCKx_7_CHx_RIPPLE_CANCEL, 93 + ripple_cancel); 94 + if (ret < 0) 95 + dev_err(chip->dev, "Cannot set ripple mode, err: %d\n", ret); 96 + } 97 + } 98 + 99 + return 0; 100 + } 101 + 107 102 #define DA9121_MIN_MV 300 108 103 #define DA9121_MAX_MV 1900 109 104 #define DA9121_STEP_MV 10 ··· 168 57 .id = DA9121_IDX_BUCK1, 169 58 .name = "da9121", 170 59 .of_match = "buck1", 60 + .of_parse_cb = da9121_of_parse_cb, 171 61 .owner = THIS_MODULE, 172 62 .regulators_node = of_match_ptr("regulators"), 173 63 .ops = &da9121_buck_ops, ··· 192 80 .id = DA9121_IDX_BUCK1, 193 81 .name = "DA9220/DA9132 BUCK1", 194 82 .of_match = "buck1", 83 + .of_parse_cb = da9121_of_parse_cb, 195 84 .owner = THIS_MODULE, 196 85 .regulators_node = of_match_ptr("regulators"), 197 86 .ops = &da9121_buck_ops, ··· 210 97 .id = DA9121_IDX_BUCK2, 211 98 .name = "DA9220/DA9132 BUCK2", 212 99 .of_match = "buck2", 100 + .of_parse_cb = da9121_of_parse_cb, 213 101 .owner = THIS_MODULE, 214 102 .regulators_node = of_match_ptr("regulators"), 215 103 .ops = &da9121_buck_ops, ··· 231 117 .id = DA9121_IDX_BUCK1, 232 118 .name = "DA9122/DA9131 BUCK1", 233 119 .of_match = "buck1", 120 + .of_parse_cb = da9121_of_parse_cb, 234 121 .owner = THIS_MODULE, 235 122 .regulators_node = of_match_ptr("regulators"), 236 123 .ops = &da9121_buck_ops, ··· 249 134 .id = DA9121_IDX_BUCK2, 250 135 .name = "DA9122/DA9131 BUCK2", 251 136 .of_match = "buck2", 137 + .of_parse_cb = da9121_of_parse_cb, 252 138 .owner = THIS_MODULE, 253 139 .regulators_node = of_match_ptr("regulators"), 254 140 .ops = &da9121_buck_ops, ··· 269 153 .id = DA9121_IDX_BUCK1, 270 154 .name = "DA9217 BUCK1", 271 155 .of_match = "buck1", 156 + .of_parse_cb = da9121_of_parse_cb, 272 157 .owner = THIS_MODULE, 273 158 .regulators_node = of_match_ptr("regulators"), 274 159 .ops = &da9121_buck_ops, ··· 532 415 goto error; 533 416 } 534 417 418 + chip->pdata = i2c->dev.platform_data; 535 419 chip->variant_id = da9121_of_get_id(&i2c->dev); 536 420 537 421 ret = da9121_assign_chip_model(i2c, chip); ··· 540 422 goto error; 541 423 542 424 config.dev = &i2c->dev; 425 + config.driver_data = chip; 543 426 config.of_node = dev->of_node; 544 427 config.regmap = chip->regmap; 545 428
+11
include/linux/regulator/da9121.h
··· 16 16 #ifndef __LINUX_REGULATOR_DA9121_H 17 17 #define __LINUX_REGULATOR_DA9121_H 18 18 19 + #include <linux/regulator/machine.h> 20 + 21 + struct gpio_desc; 22 + 19 23 enum { 20 24 DA9121_IDX_BUCK1, 21 25 DA9121_IDX_BUCK2, 22 26 DA9121_IDX_MAX 27 + }; 28 + 29 + struct da9121_pdata { 30 + int num_buck; 31 + struct gpio_desc *gpiod_ren[DA9121_IDX_MAX]; 32 + struct device_node *reg_node[DA9121_IDX_MAX]; 33 + struct regulator_init_data *init_data[DA9121_IDX_MAX]; 23 34 }; 24 35 25 36 #endif