summaryrefslogtreecommitdiffstats
path: root/drivers/regulator
diff options
context:
space:
mode:
authorIcenowy Zheng <icenowy@aosc.io>2017-05-18 03:16:49 -0400
committerMark Brown <broonie@kernel.org>2017-05-19 12:57:59 -0400
commit1dbe0ccb0631c4ed399261934fe16f07407b078d (patch)
tree3b0709acd9a113dcedacc4209475fc2991301625 /drivers/regulator
parent2ea659a9ef488125eb46da6eb571de5eae5c43f6 (diff)
regulator: axp20x-regulator: add support for AXP803
AXP803 PMIC also have a series of regulators (DCDCs and LDOs) controllable via I2C/RSB bus. Add support for them. Signed-off-by: Icenowy Zheng <icenowy@aosc.io> Acked-by: Chen-Yu Tsai <wens@csie.org> Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'drivers/regulator')
-rw-r--r--drivers/regulator/axp20x-regulator.c153
1 files changed, 131 insertions, 22 deletions
diff --git a/drivers/regulator/axp20x-regulator.c b/drivers/regulator/axp20x-regulator.c
index 0b9d4e3e52c7..e2608fe770b9 100644
--- a/drivers/regulator/axp20x-regulator.c
+++ b/drivers/regulator/axp20x-regulator.c
@@ -244,6 +244,82 @@ static const struct regulator_desc axp22x_drivevbus_regulator = {
244 .ops = &axp20x_ops_sw, 244 .ops = &axp20x_ops_sw,
245}; 245};
246 246
247static const struct regulator_linear_range axp803_dcdc234_ranges[] = {
248 REGULATOR_LINEAR_RANGE(500000, 0x0, 0x46, 10000),
249 REGULATOR_LINEAR_RANGE(1220000, 0x47, 0x4b, 20000),
250};
251
252static const struct regulator_linear_range axp803_dcdc5_ranges[] = {
253 REGULATOR_LINEAR_RANGE(800000, 0x0, 0x20, 10000),
254 REGULATOR_LINEAR_RANGE(1140000, 0x21, 0x44, 20000),
255};
256
257static const struct regulator_linear_range axp803_dcdc6_ranges[] = {
258 REGULATOR_LINEAR_RANGE(600000, 0x0, 0x32, 10000),
259 REGULATOR_LINEAR_RANGE(1120000, 0x33, 0x47, 20000),
260};
261
262/* AXP806's CLDO2 and AXP809's DLDO1 shares the same range */
263static const struct regulator_linear_range axp803_dldo2_ranges[] = {
264 REGULATOR_LINEAR_RANGE(700000, 0x0, 0x1a, 100000),
265 REGULATOR_LINEAR_RANGE(3400000, 0x1b, 0x1f, 200000),
266};
267
268static const struct regulator_desc axp803_regulators[] = {
269 AXP_DESC(AXP803, DCDC1, "dcdc1", "vin1", 1600, 3400, 100,
270 AXP803_DCDC1_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL1, BIT(0)),
271 AXP_DESC_RANGES(AXP803, DCDC2, "dcdc2", "vin2", axp803_dcdc234_ranges,
272 76, AXP803_DCDC2_V_OUT, 0x7f, AXP22X_PWR_OUT_CTRL1,
273 BIT(1)),
274 AXP_DESC_RANGES(AXP803, DCDC3, "dcdc3", "vin3", axp803_dcdc234_ranges,
275 76, AXP803_DCDC3_V_OUT, 0x7f, AXP22X_PWR_OUT_CTRL1,
276 BIT(2)),
277 AXP_DESC_RANGES(AXP803, DCDC4, "dcdc4", "vin4", axp803_dcdc234_ranges,
278 76, AXP803_DCDC4_V_OUT, 0x7f, AXP22X_PWR_OUT_CTRL1,
279 BIT(3)),
280 AXP_DESC_RANGES(AXP803, DCDC5, "dcdc5", "vin5", axp803_dcdc5_ranges,
281 68, AXP803_DCDC5_V_OUT, 0x7f, AXP22X_PWR_OUT_CTRL1,
282 BIT(4)),
283 AXP_DESC_RANGES(AXP803, DCDC6, "dcdc6", "vin6", axp803_dcdc6_ranges,
284 72, AXP803_DCDC6_V_OUT, 0x7f, AXP22X_PWR_OUT_CTRL1,
285 BIT(5)),
286 /* secondary switchable output of DCDC1 */
287 AXP_DESC_SW(AXP803, DC1SW, "dc1sw", NULL, AXP22X_PWR_OUT_CTRL2,
288 BIT(7)),
289 AXP_DESC(AXP803, ALDO1, "aldo1", "aldoin", 700, 3300, 100,
290 AXP22X_ALDO1_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL3, BIT(5)),
291 AXP_DESC(AXP803, ALDO2, "aldo2", "aldoin", 700, 3300, 100,
292 AXP22X_ALDO2_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL3, BIT(6)),
293 AXP_DESC(AXP803, ALDO3, "aldo3", "aldoin", 700, 3300, 100,
294 AXP22X_ALDO3_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL3, BIT(7)),
295 AXP_DESC(AXP803, DLDO1, "dldo1", "dldoin", 700, 3300, 100,
296 AXP22X_DLDO1_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL2, BIT(3)),
297 AXP_DESC_RANGES(AXP803, DLDO2, "dldo2", "dldoin", axp803_dldo2_ranges,
298 32, AXP22X_DLDO2_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL2,
299 BIT(4)),
300 AXP_DESC(AXP803, DLDO3, "dldo3", "dldoin", 700, 3300, 100,
301 AXP22X_DLDO3_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL2, BIT(5)),
302 AXP_DESC(AXP803, DLDO4, "dldo4", "dldoin", 700, 3300, 100,
303 AXP22X_DLDO4_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL2, BIT(6)),
304 AXP_DESC(AXP803, ELDO1, "eldo1", "eldoin", 700, 1900, 50,
305 AXP22X_ELDO1_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL2, BIT(0)),
306 AXP_DESC(AXP803, ELDO2, "eldo2", "eldoin", 700, 1900, 50,
307 AXP22X_ELDO2_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL2, BIT(1)),
308 AXP_DESC(AXP803, ELDO3, "eldo3", "eldoin", 700, 1900, 50,
309 AXP22X_ELDO3_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL2, BIT(2)),
310 AXP_DESC(AXP803, FLDO1, "fldo1", "fldoin", 700, 1450, 50,
311 AXP803_FLDO1_V_OUT, 0x0f, AXP22X_PWR_OUT_CTRL3, BIT(2)),
312 AXP_DESC(AXP803, FLDO2, "fldo2", "fldoin", 700, 1450, 50,
313 AXP803_FLDO2_V_OUT, 0x0f, AXP22X_PWR_OUT_CTRL3, BIT(3)),
314 AXP_DESC_IO(AXP803, LDO_IO0, "ldo-io0", "ips", 700, 3300, 100,
315 AXP22X_LDO_IO0_V_OUT, 0x1f, AXP20X_GPIO0_CTRL, 0x07,
316 AXP22X_IO_ENABLED, AXP22X_IO_DISABLED),
317 AXP_DESC_IO(AXP803, LDO_IO1, "ldo-io1", "ips", 700, 3300, 100,
318 AXP22X_LDO_IO1_V_OUT, 0x1f, AXP20X_GPIO1_CTRL, 0x07,
319 AXP22X_IO_ENABLED, AXP22X_IO_DISABLED),
320 AXP_DESC_FIXED(AXP803, RTC_LDO, "rtc-ldo", "ips", 3000),
321};
322
247static const struct regulator_linear_range axp806_dcdca_ranges[] = { 323static const struct regulator_linear_range axp806_dcdca_ranges[] = {
248 REGULATOR_LINEAR_RANGE(600000, 0x0, 0x32, 10000), 324 REGULATOR_LINEAR_RANGE(600000, 0x0, 0x32, 10000),
249 REGULATOR_LINEAR_RANGE(1120000, 0x33, 0x47, 20000), 325 REGULATOR_LINEAR_RANGE(1120000, 0x33, 0x47, 20000),
@@ -254,11 +330,6 @@ static const struct regulator_linear_range axp806_dcdcd_ranges[] = {
254 REGULATOR_LINEAR_RANGE(1600000, 0x2e, 0x3f, 100000), 330 REGULATOR_LINEAR_RANGE(1600000, 0x2e, 0x3f, 100000),
255}; 331};
256 332
257static const struct regulator_linear_range axp806_cldo2_ranges[] = {
258 REGULATOR_LINEAR_RANGE(700000, 0x0, 0x1a, 100000),
259 REGULATOR_LINEAR_RANGE(3400000, 0x1b, 0x1f, 200000),
260};
261
262static const struct regulator_desc axp806_regulators[] = { 333static const struct regulator_desc axp806_regulators[] = {
263 AXP_DESC_RANGES(AXP806, DCDCA, "dcdca", "vina", axp806_dcdca_ranges, 334 AXP_DESC_RANGES(AXP806, DCDCA, "dcdca", "vina", axp806_dcdca_ranges,
264 72, AXP806_DCDCA_V_CTRL, 0x7f, AXP806_PWR_OUT_CTRL1, 335 72, AXP806_DCDCA_V_CTRL, 0x7f, AXP806_PWR_OUT_CTRL1,
@@ -289,7 +360,7 @@ static const struct regulator_desc axp806_regulators[] = {
289 AXP806_BLDO4_V_CTRL, 0x0f, AXP806_PWR_OUT_CTRL2, BIT(3)), 360 AXP806_BLDO4_V_CTRL, 0x0f, AXP806_PWR_OUT_CTRL2, BIT(3)),
290 AXP_DESC(AXP806, CLDO1, "cldo1", "cldoin", 700, 3300, 100, 361 AXP_DESC(AXP806, CLDO1, "cldo1", "cldoin", 700, 3300, 100,
291 AXP806_CLDO1_V_CTRL, 0x1f, AXP806_PWR_OUT_CTRL2, BIT(4)), 362 AXP806_CLDO1_V_CTRL, 0x1f, AXP806_PWR_OUT_CTRL2, BIT(4)),
292 AXP_DESC_RANGES(AXP806, CLDO2, "cldo2", "cldoin", axp806_cldo2_ranges, 363 AXP_DESC_RANGES(AXP806, CLDO2, "cldo2", "cldoin", axp803_dldo2_ranges,
293 32, AXP806_CLDO2_V_CTRL, 0x1f, AXP806_PWR_OUT_CTRL2, 364 32, AXP806_CLDO2_V_CTRL, 0x1f, AXP806_PWR_OUT_CTRL2,
294 BIT(5)), 365 BIT(5)),
295 AXP_DESC(AXP806, CLDO3, "cldo3", "cldoin", 700, 3300, 100, 366 AXP_DESC(AXP806, CLDO3, "cldo3", "cldoin", 700, 3300, 100,
@@ -326,7 +397,7 @@ static const struct regulator_desc axp809_regulators[] = {
326 AXP22X_ALDO2_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL1, BIT(7)), 397 AXP22X_ALDO2_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL1, BIT(7)),
327 AXP_DESC(AXP809, ALDO3, "aldo3", "aldoin", 700, 3300, 100, 398 AXP_DESC(AXP809, ALDO3, "aldo3", "aldoin", 700, 3300, 100,
328 AXP22X_ALDO3_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL2, BIT(5)), 399 AXP22X_ALDO3_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL2, BIT(5)),
329 AXP_DESC_RANGES(AXP809, DLDO1, "dldo1", "dldoin", axp806_cldo2_ranges, 400 AXP_DESC_RANGES(AXP809, DLDO1, "dldo1", "dldoin", axp803_dldo2_ranges,
330 32, AXP22X_DLDO1_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL2, 401 32, AXP22X_DLDO1_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL2,
331 BIT(3)), 402 BIT(3)),
332 AXP_DESC(AXP809, DLDO2, "dldo2", "dldoin", 700, 3300, 100, 403 AXP_DESC(AXP809, DLDO2, "dldo2", "dldoin", 700, 3300, 100,
@@ -369,14 +440,21 @@ static int axp20x_set_dcdc_freq(struct platform_device *pdev, u32 dcdcfreq)
369 def = 1500; 440 def = 1500;
370 step = 75; 441 step = 75;
371 break; 442 break;
372 case AXP806_ID: 443 case AXP803_ID:
373 /* 444 /*
374 * AXP806 DCDC work frequency setting has the same range and 445 * AXP803 DCDC work frequency setting has the same range and
375 * step as AXP22X, but at a different register. 446 * step as AXP22X, but at a different register.
376 * Fall through to the check below. 447 * Fall through to the check below.
377 * (See include/linux/mfd/axp20x.h) 448 * (See include/linux/mfd/axp20x.h)
378 */ 449 */
379 reg = AXP806_DCDC_FREQ_CTRL; 450 reg = AXP803_DCDC_FREQ_CTRL;
451 case AXP806_ID:
452 /*
453 * AXP806 also have DCDC work frequency setting register at a
454 * different position.
455 */
456 if (axp20x->variant == AXP806_ID)
457 reg = AXP806_DCDC_FREQ_CTRL;
380 case AXP221_ID: 458 case AXP221_ID:
381 case AXP223_ID: 459 case AXP223_ID:
382 case AXP809_ID: 460 case AXP809_ID:
@@ -475,6 +553,14 @@ static int axp20x_set_dcdc_workmode(struct regulator_dev *rdev, int id, u32 work
475 workmode <<= id - AXP22X_DCDC1; 553 workmode <<= id - AXP22X_DCDC1;
476 break; 554 break;
477 555
556 case AXP803_ID:
557 if (id < AXP803_DCDC1 || id > AXP803_DCDC6)
558 return -EINVAL;
559
560 mask = AXP22X_WORKMODE_DCDCX_MASK(id - AXP803_DCDC1);
561 workmode <<= id - AXP803_DCDC1;
562 break;
563
478 default: 564 default:
479 /* should not happen */ 565 /* should not happen */
480 WARN_ON(1); 566 WARN_ON(1);
@@ -492,20 +578,38 @@ static bool axp20x_is_polyphase_slave(struct axp20x_dev *axp20x, int id)
492{ 578{
493 u32 reg = 0; 579 u32 reg = 0;
494 580
495 /* Only AXP806 has poly-phase outputs */ 581 /*
496 if (axp20x->variant != AXP806_ID) 582 * Currently in our supported AXP variants, only AXP803 and AXP806
497 return false; 583 * have polyphase regulators.
584 */
585 switch (axp20x->variant) {
586 case AXP803_ID:
587 regmap_read(axp20x->regmap, AXP803_POLYPHASE_CTRL, &reg);
588
589 switch (id) {
590 case AXP803_DCDC3:
591 return !!(reg & BIT(6));
592 case AXP803_DCDC6:
593 return !!(reg & BIT(7));
594 }
595 break;
498 596
499 regmap_read(axp20x->regmap, AXP806_DCDC_MODE_CTRL2, &reg); 597 case AXP806_ID:
598 regmap_read(axp20x->regmap, AXP806_DCDC_MODE_CTRL2, &reg);
599
600 switch (id) {
601 case AXP806_DCDCB:
602 return (((reg & GENMASK(7, 6)) == BIT(6)) ||
603 ((reg & GENMASK(7, 6)) == BIT(7)));
604 case AXP806_DCDCC:
605 return ((reg & GENMASK(7, 6)) == BIT(7));
606 case AXP806_DCDCE:
607 return !!(reg & BIT(5));
608 }
609 break;
500 610
501 switch (id) { 611 default:
502 case AXP806_DCDCB: 612 return false;
503 return (((reg & GENMASK(7, 6)) == BIT(6)) ||
504 ((reg & GENMASK(7, 6)) == BIT(7)));
505 case AXP806_DCDCC:
506 return ((reg & GENMASK(7, 6)) == BIT(7));
507 case AXP806_DCDCE:
508 return !!(reg & BIT(5));
509 } 613 }
510 614
511 return false; 615 return false;
@@ -540,6 +644,10 @@ static int axp20x_regulator_probe(struct platform_device *pdev)
540 drivevbus = of_property_read_bool(pdev->dev.parent->of_node, 644 drivevbus = of_property_read_bool(pdev->dev.parent->of_node,
541 "x-powers,drive-vbus-en"); 645 "x-powers,drive-vbus-en");
542 break; 646 break;
647 case AXP803_ID:
648 regulators = axp803_regulators;
649 nregulators = AXP803_REG_ID_MAX;
650 break;
543 case AXP806_ID: 651 case AXP806_ID:
544 regulators = axp806_regulators; 652 regulators = axp806_regulators;
545 nregulators = AXP806_REG_ID_MAX; 653 nregulators = AXP806_REG_ID_MAX;
@@ -579,6 +687,7 @@ static int axp20x_regulator_probe(struct platform_device *pdev)
579 * name. 687 * name.
580 */ 688 */
581 if ((regulators == axp22x_regulators && i == AXP22X_DC1SW) || 689 if ((regulators == axp22x_regulators && i == AXP22X_DC1SW) ||
690 (regulators == axp803_regulators && i == AXP803_DC1SW) ||
582 (regulators == axp809_regulators && i == AXP809_DC1SW)) { 691 (regulators == axp809_regulators && i == AXP809_DC1SW)) {
583 new_desc = devm_kzalloc(&pdev->dev, sizeof(*desc), 692 new_desc = devm_kzalloc(&pdev->dev, sizeof(*desc),
584 GFP_KERNEL); 693 GFP_KERNEL);