|
15 | 15 | #include <linux/mfd/tps65086.h>
|
16 | 16 |
|
17 | 17 | enum tps65086_regulators { BUCK1, BUCK2, BUCK3, BUCK4, BUCK5, BUCK6, LDOA1,
|
18 |
| - LDOA2, LDOA3, SWA1, SWB1, SWB2, VTT }; |
| 18 | + LDOA2, LDOA3, VTT, SWA1, SWB1, SWB2 }; |
| 19 | + |
| 20 | +/* Selector for regulator configuration regarding PMIC chip ID. */ |
| 21 | +enum tps65086_ids { |
| 22 | + TPS6508640 = 0, |
| 23 | + TPS65086401, |
| 24 | + TPS6508641, |
| 25 | + TPS65086470, |
| 26 | +}; |
19 | 27 |
|
20 | 28 | #define TPS65086_REGULATOR(_name, _of, _id, _nv, _vr, _vm, _er, _em, _lr, _dr, _dm) \
|
21 | 29 | [_id] = { \
|
@@ -57,12 +65,24 @@ enum tps65086_regulators { BUCK1, BUCK2, BUCK3, BUCK4, BUCK5, BUCK6, LDOA1,
|
57 | 65 | }, \
|
58 | 66 | }
|
59 | 67 |
|
| 68 | + |
| 69 | +#define TPS65086_REGULATOR_CONFIG(_chip_id, _config) \ |
| 70 | + [_chip_id] = { \ |
| 71 | + .config = _config, \ |
| 72 | + .num_elems = ARRAY_SIZE(_config), \ |
| 73 | + } |
| 74 | + |
60 | 75 | struct tps65086_regulator {
|
61 | 76 | struct regulator_desc desc;
|
62 | 77 | unsigned int decay_reg;
|
63 | 78 | unsigned int decay_mask;
|
64 | 79 | };
|
65 | 80 |
|
| 81 | +struct tps65086_regulator_config { |
| 82 | + struct tps65086_regulator * const config; |
| 83 | + const unsigned int num_elems; |
| 84 | +}; |
| 85 | + |
66 | 86 | static const struct linear_range tps65086_10mv_ranges[] = {
|
67 | 87 | REGULATOR_LINEAR_RANGE(0, 0x0, 0x0, 0),
|
68 | 88 | REGULATOR_LINEAR_RANGE(410000, 0x1, 0x7F, 10000),
|
@@ -114,7 +134,125 @@ static int tps65086_of_parse_cb(struct device_node *dev,
|
114 | 134 | const struct regulator_desc *desc,
|
115 | 135 | struct regulator_config *config);
|
116 | 136 |
|
117 |
| -static struct tps65086_regulator regulators[] = { |
| 137 | +static struct tps65086_regulator tps6508640_regulator_config[] = { |
| 138 | + TPS65086_REGULATOR("BUCK1", "buck1", BUCK1, 0x80, TPS65086_BUCK1CTRL, |
| 139 | + BUCK_VID_MASK, TPS65086_BUCK123CTRL, BIT(0), |
| 140 | + tps65086_10mv_ranges, TPS65086_BUCK1CTRL, |
| 141 | + BIT(0)), |
| 142 | + TPS65086_REGULATOR("BUCK2", "buck2", BUCK2, 0x80, TPS65086_BUCK2CTRL, |
| 143 | + BUCK_VID_MASK, TPS65086_BUCK123CTRL, BIT(1), |
| 144 | + tps65086_10mv_ranges, TPS65086_BUCK2CTRL, |
| 145 | + BIT(0)), |
| 146 | + TPS65086_REGULATOR("BUCK3", "buck3", BUCK3, 0x80, TPS65086_BUCK3VID, |
| 147 | + BUCK_VID_MASK, TPS65086_BUCK123CTRL, BIT(2), |
| 148 | + tps65086_10mv_ranges, TPS65086_BUCK3DECAY, |
| 149 | + BIT(0)), |
| 150 | + TPS65086_REGULATOR("BUCK4", "buck4", BUCK4, 0x80, TPS65086_BUCK4VID, |
| 151 | + BUCK_VID_MASK, TPS65086_BUCK4CTRL, BIT(0), |
| 152 | + tps65086_10mv_ranges, TPS65086_BUCK4VID, |
| 153 | + BIT(0)), |
| 154 | + TPS65086_REGULATOR("BUCK5", "buck5", BUCK5, 0x80, TPS65086_BUCK5VID, |
| 155 | + BUCK_VID_MASK, TPS65086_BUCK5CTRL, BIT(0), |
| 156 | + tps65086_10mv_ranges, TPS65086_BUCK5CTRL, |
| 157 | + BIT(0)), |
| 158 | + TPS65086_REGULATOR("BUCK6", "buck6", BUCK6, 0x80, TPS65086_BUCK6VID, |
| 159 | + BUCK_VID_MASK, TPS65086_BUCK6CTRL, BIT(0), |
| 160 | + tps65086_10mv_ranges, TPS65086_BUCK6CTRL, |
| 161 | + BIT(0)), |
| 162 | + TPS65086_REGULATOR("LDOA1", "ldoa1", LDOA1, 0xF, TPS65086_LDOA1CTRL, |
| 163 | + VDOA1_VID_MASK, TPS65086_SWVTT_EN, BIT(7), |
| 164 | + tps65086_ldoa1_ranges, 0, 0), |
| 165 | + TPS65086_REGULATOR("LDOA2", "ldoa2", LDOA2, 0x10, TPS65086_LDOA2VID, |
| 166 | + VDOA23_VID_MASK, TPS65086_LDOA2CTRL, BIT(0), |
| 167 | + tps65086_ldoa23_ranges, 0, 0), |
| 168 | + TPS65086_REGULATOR("LDOA3", "ldoa3", LDOA3, 0x10, TPS65086_LDOA3VID, |
| 169 | + VDOA23_VID_MASK, TPS65086_LDOA3CTRL, BIT(0), |
| 170 | + tps65086_ldoa23_ranges, 0, 0), |
| 171 | + TPS65086_SWITCH("VTT", "vtt", VTT, TPS65086_SWVTT_EN, BIT(4)), |
| 172 | + TPS65086_SWITCH("SWA1", "swa1", SWA1, TPS65086_SWVTT_EN, BIT(5)), |
| 173 | + TPS65086_SWITCH("SWB1", "swb1", SWB1, TPS65086_SWVTT_EN, BIT(6)), |
| 174 | + TPS65086_SWITCH("SWB2", "swb2", SWB2, TPS65086_LDOA1CTRL, BIT(0)), |
| 175 | +}; |
| 176 | + |
| 177 | +static struct tps65086_regulator tps65086401_regulator_config[] = { |
| 178 | + TPS65086_REGULATOR("BUCK1", "buck1", BUCK1, 0x80, TPS65086_BUCK1CTRL, |
| 179 | + BUCK_VID_MASK, TPS65086_BUCK123CTRL, BIT(0), |
| 180 | + tps65086_10mv_ranges, TPS65086_BUCK1CTRL, |
| 181 | + BIT(0)), |
| 182 | + TPS65086_REGULATOR("BUCK2", "buck2", BUCK2, 0x80, TPS65086_BUCK2CTRL, |
| 183 | + BUCK_VID_MASK, TPS65086_BUCK123CTRL, BIT(1), |
| 184 | + tps65086_10mv_ranges, TPS65086_BUCK2CTRL, |
| 185 | + BIT(0)), |
| 186 | + TPS65086_REGULATOR("BUCK3", "buck3", BUCK3, 0x80, TPS65086_BUCK3VID, |
| 187 | + BUCK_VID_MASK, TPS65086_BUCK123CTRL, BIT(2), |
| 188 | + tps65086_10mv_ranges, TPS65086_BUCK3DECAY, |
| 189 | + BIT(0)), |
| 190 | + TPS65086_REGULATOR("BUCK4", "buck4", BUCK4, 0x80, TPS65086_BUCK4VID, |
| 191 | + BUCK_VID_MASK, TPS65086_BUCK4CTRL, BIT(0), |
| 192 | + tps65086_10mv_ranges, TPS65086_BUCK4VID, |
| 193 | + BIT(0)), |
| 194 | + TPS65086_REGULATOR("BUCK5", "buck5", BUCK5, 0x80, TPS65086_BUCK5VID, |
| 195 | + BUCK_VID_MASK, TPS65086_BUCK5CTRL, BIT(0), |
| 196 | + tps65086_10mv_ranges, TPS65086_BUCK5CTRL, |
| 197 | + BIT(0)), |
| 198 | + TPS65086_REGULATOR("BUCK6", "buck6", BUCK6, 0x80, TPS65086_BUCK6VID, |
| 199 | + BUCK_VID_MASK, TPS65086_BUCK6CTRL, BIT(0), |
| 200 | + tps65086_10mv_ranges, TPS65086_BUCK6CTRL, |
| 201 | + BIT(0)), |
| 202 | + TPS65086_REGULATOR("LDOA1", "ldoa1", LDOA1, 0xF, TPS65086_LDOA1CTRL, |
| 203 | + VDOA1_VID_MASK, TPS65086_SWVTT_EN, BIT(7), |
| 204 | + tps65086_ldoa1_ranges, 0, 0), |
| 205 | + TPS65086_REGULATOR("LDOA2", "ldoa2", LDOA2, 0x10, TPS65086_LDOA2VID, |
| 206 | + VDOA23_VID_MASK, TPS65086_LDOA2CTRL, BIT(0), |
| 207 | + tps65086_ldoa23_ranges, 0, 0), |
| 208 | + TPS65086_REGULATOR("LDOA3", "ldoa3", LDOA3, 0x10, TPS65086_LDOA3VID, |
| 209 | + VDOA23_VID_MASK, TPS65086_LDOA3CTRL, BIT(0), |
| 210 | + tps65086_ldoa23_ranges, 0, 0), |
| 211 | + TPS65086_SWITCH("VTT", "vtt", VTT, TPS65086_SWVTT_EN, BIT(4)), |
| 212 | + TPS65086_SWITCH("SWA1", "swa1", SWA1, TPS65086_SWVTT_EN, BIT(5)), |
| 213 | + TPS65086_SWITCH("SWB1", "swb1", SWB1, TPS65086_SWVTT_EN, BIT(6)), |
| 214 | +}; |
| 215 | + |
| 216 | +static struct tps65086_regulator tps6508641_regulator_config[] = { |
| 217 | + TPS65086_REGULATOR("BUCK1", "buck1", BUCK1, 0x80, TPS65086_BUCK1CTRL, |
| 218 | + BUCK_VID_MASK, TPS65086_BUCK123CTRL, BIT(0), |
| 219 | + tps65086_10mv_ranges, TPS65086_BUCK1CTRL, |
| 220 | + BIT(0)), |
| 221 | + TPS65086_REGULATOR("BUCK2", "buck2", BUCK2, 0x80, TPS65086_BUCK2CTRL, |
| 222 | + BUCK_VID_MASK, TPS65086_BUCK123CTRL, BIT(1), |
| 223 | + tps65086_10mv_ranges, TPS65086_BUCK2CTRL, |
| 224 | + BIT(0)), |
| 225 | + TPS65086_REGULATOR("BUCK3", "buck3", BUCK3, 0x80, TPS65086_BUCK3VID, |
| 226 | + BUCK_VID_MASK, TPS65086_BUCK123CTRL, BIT(2), |
| 227 | + tps65086_10mv_ranges, TPS65086_BUCK3DECAY, |
| 228 | + BIT(0)), |
| 229 | + TPS65086_REGULATOR("BUCK4", "buck4", BUCK4, 0x80, TPS65086_BUCK4VID, |
| 230 | + BUCK_VID_MASK, TPS65086_BUCK4CTRL, BIT(0), |
| 231 | + tps65086_10mv_ranges, TPS65086_BUCK4VID, |
| 232 | + BIT(0)), |
| 233 | + TPS65086_REGULATOR("BUCK5", "buck5", BUCK5, 0x80, TPS65086_BUCK5VID, |
| 234 | + BUCK_VID_MASK, TPS65086_BUCK5CTRL, BIT(0), |
| 235 | + tps65086_10mv_ranges, TPS65086_BUCK5CTRL, |
| 236 | + BIT(0)), |
| 237 | + TPS65086_REGULATOR("BUCK6", "buck6", BUCK6, 0x80, TPS65086_BUCK6VID, |
| 238 | + BUCK_VID_MASK, TPS65086_BUCK6CTRL, BIT(0), |
| 239 | + tps65086_10mv_ranges, TPS65086_BUCK6CTRL, |
| 240 | + BIT(0)), |
| 241 | + TPS65086_REGULATOR("LDOA1", "ldoa1", LDOA1, 0xF, TPS65086_LDOA1CTRL, |
| 242 | + VDOA1_VID_MASK, TPS65086_SWVTT_EN, BIT(7), |
| 243 | + tps65086_ldoa1_ranges, 0, 0), |
| 244 | + TPS65086_REGULATOR("LDOA2", "ldoa2", LDOA2, 0x10, TPS65086_LDOA2VID, |
| 245 | + VDOA23_VID_MASK, TPS65086_LDOA2CTRL, BIT(0), |
| 246 | + tps65086_ldoa23_ranges, 0, 0), |
| 247 | + TPS65086_REGULATOR("LDOA3", "ldoa3", LDOA3, 0x10, TPS65086_LDOA3VID, |
| 248 | + VDOA23_VID_MASK, TPS65086_LDOA3CTRL, BIT(0), |
| 249 | + tps65086_ldoa23_ranges, 0, 0), |
| 250 | + TPS65086_SWITCH("VTT", "vtt", VTT, TPS65086_SWVTT_EN, BIT(4)), |
| 251 | + TPS65086_SWITCH("SWA1", "swa1", SWA1, TPS65086_SWVTT_EN, BIT(5)), |
| 252 | + TPS65086_SWITCH("SWB1", "swb1", SWB1, TPS65086_SWVTT_EN, BIT(6)), |
| 253 | +}; |
| 254 | + |
| 255 | +static struct tps65086_regulator tps65086470_regulator_config[] = { |
118 | 256 | TPS65086_REGULATOR("BUCK1", "buck1", BUCK1, 0x80, TPS65086_BUCK1CTRL,
|
119 | 257 | BUCK_VID_MASK, TPS65086_BUCK123CTRL, BIT(0),
|
120 | 258 | tps65086_10mv_ranges, TPS65086_BUCK1CTRL,
|
@@ -148,16 +286,25 @@ static struct tps65086_regulator regulators[] = {
|
148 | 286 | TPS65086_REGULATOR("LDOA3", "ldoa3", LDOA3, 0x10, TPS65086_LDOA3VID,
|
149 | 287 | VDOA23_VID_MASK, TPS65086_LDOA3CTRL, BIT(0),
|
150 | 288 | tps65086_ldoa23_ranges, 0, 0),
|
| 289 | + TPS65086_SWITCH("VTT", "vtt", VTT, TPS65086_SWVTT_EN, BIT(4)), |
151 | 290 | TPS65086_SWITCH("SWA1", "swa1", SWA1, TPS65086_SWVTT_EN, BIT(5)),
|
152 | 291 | TPS65086_SWITCH("SWB1", "swb1", SWB1, TPS65086_SWVTT_EN, BIT(6)),
|
153 | 292 | TPS65086_SWITCH("SWB2", "swb2", SWB2, TPS65086_SWVTT_EN, BIT(7)),
|
154 |
| - TPS65086_SWITCH("VTT", "vtt", VTT, TPS65086_SWVTT_EN, BIT(4)), |
| 293 | +}; |
| 294 | + |
| 295 | +static const struct tps65086_regulator_config regulator_configs[] = { |
| 296 | + TPS65086_REGULATOR_CONFIG(TPS6508640, tps6508640_regulator_config), |
| 297 | + TPS65086_REGULATOR_CONFIG(TPS65086401, tps65086401_regulator_config), |
| 298 | + TPS65086_REGULATOR_CONFIG(TPS6508641, tps6508641_regulator_config), |
| 299 | + TPS65086_REGULATOR_CONFIG(TPS65086470, tps65086470_regulator_config) |
155 | 300 | };
|
156 | 301 |
|
157 | 302 | static int tps65086_of_parse_cb(struct device_node *node,
|
158 | 303 | const struct regulator_desc *desc,
|
159 | 304 | struct regulator_config *config)
|
160 | 305 | {
|
| 306 | + struct tps65086 * const tps = dev_get_drvdata(config->dev); |
| 307 | + struct tps65086_regulator *regulators = tps->reg_config->config; |
161 | 308 | int ret;
|
162 | 309 |
|
163 | 310 | /* Check for 25mV step mode */
|
@@ -203,22 +350,47 @@ static int tps65086_regulator_probe(struct platform_device *pdev)
|
203 | 350 | {
|
204 | 351 | struct tps65086 *tps = dev_get_drvdata(pdev->dev.parent);
|
205 | 352 | struct regulator_config config = { };
|
| 353 | + unsigned int selector_reg_config; |
206 | 354 | struct regulator_dev *rdev;
|
207 | 355 | int i;
|
208 | 356 |
|
| 357 | + /* Select regulator configuration for used PMIC device */ |
| 358 | + switch (tps->chip_id) { |
| 359 | + case TPS6508640_ID: |
| 360 | + selector_reg_config = TPS6508640; |
| 361 | + break; |
| 362 | + case TPS65086401_ID: |
| 363 | + selector_reg_config = TPS65086401; |
| 364 | + break; |
| 365 | + case TPS6508641_ID: |
| 366 | + selector_reg_config = TPS6508641; |
| 367 | + break; |
| 368 | + case TPS65086470_ID: |
| 369 | + selector_reg_config = TPS65086470; |
| 370 | + break; |
| 371 | + default: |
| 372 | + dev_err(tps->dev, "Unknown device ID. Cannot determine regulator config.\n"); |
| 373 | + return -ENODEV; |
| 374 | + } |
| 375 | + tps->reg_config = ®ulator_configs[selector_reg_config]; |
| 376 | + |
209 | 377 | platform_set_drvdata(pdev, tps);
|
210 | 378 |
|
211 | 379 | config.dev = &pdev->dev;
|
212 | 380 | config.dev->of_node = tps->dev->of_node;
|
213 | 381 | config.driver_data = tps;
|
214 | 382 | config.regmap = tps->regmap;
|
215 | 383 |
|
216 |
| - for (i = 0; i < ARRAY_SIZE(regulators); i++) { |
217 |
| - rdev = devm_regulator_register(&pdev->dev, ®ulators[i].desc, |
218 |
| - &config); |
| 384 | + for (i = 0; i < tps->reg_config->num_elems; ++i) { |
| 385 | + struct regulator_desc * const desc_ptr = &tps->reg_config->config[i].desc; |
| 386 | + |
| 387 | + dev_dbg(tps->dev, "Index: %u; Regulator name: \"%s\"; Regulator ID: %d\n", |
| 388 | + i, desc_ptr->name, desc_ptr->id); |
| 389 | + |
| 390 | + rdev = devm_regulator_register(&pdev->dev, desc_ptr, &config); |
219 | 391 | if (IS_ERR(rdev)) {
|
220 |
| - dev_err(tps->dev, "failed to register %s regulator\n", |
221 |
| - pdev->name); |
| 392 | + dev_err(tps->dev, "failed to register %d \"%s\" regulator\n", |
| 393 | + i, desc_ptr->name); |
222 | 394 | return PTR_ERR(rdev);
|
223 | 395 | }
|
224 | 396 | }
|
|
0 commit comments