aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/regulator/Kconfig2
-rw-r--r--drivers/regulator/axp20x-regulator.c92
-rw-r--r--drivers/regulator/da9211-regulator.c14
-rw-r--r--drivers/regulator/da9211-regulator.h2
-rw-r--r--drivers/regulator/qcom_spmi-regulator.c48
-rw-r--r--drivers/regulator/tps65218-regulator.c2
6 files changed, 143 insertions, 17 deletions
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 0fd6195601ba..96cd55f9e3c5 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -244,7 +244,7 @@ config REGULATOR_DA9210
244 interface. 244 interface.
245 245
246config REGULATOR_DA9211 246config REGULATOR_DA9211
247 tristate "Dialog Semiconductor DA9211/DA9212/DA9213/DA9214/DA9215 regulator" 247 tristate "Dialog Semiconductor DA9211/DA9212/DA9213/DA9223/DA9214/DA9224/DA9215/DA9225 regulator"
248 depends on I2C 248 depends on I2C
249 select REGMAP_I2C 249 select REGMAP_I2C
250 help 250 help
diff --git a/drivers/regulator/axp20x-regulator.c b/drivers/regulator/axp20x-regulator.c
index 376a99b7cf5d..181622b2813d 100644
--- a/drivers/regulator/axp20x-regulator.c
+++ b/drivers/regulator/axp20x-regulator.c
@@ -244,6 +244,7 @@ static const struct regulator_desc axp22x_drivevbus_regulator = {
244 .ops = &axp20x_ops_sw, 244 .ops = &axp20x_ops_sw,
245}; 245};
246 246
247/* DCDC ranges shared with AXP813 */
247static const struct regulator_linear_range axp803_dcdc234_ranges[] = { 248static const struct regulator_linear_range axp803_dcdc234_ranges[] = {
248 REGULATOR_LINEAR_RANGE(500000, 0x0, 0x46, 10000), 249 REGULATOR_LINEAR_RANGE(500000, 0x0, 0x46, 10000),
249 REGULATOR_LINEAR_RANGE(1220000, 0x47, 0x4b, 20000), 250 REGULATOR_LINEAR_RANGE(1220000, 0x47, 0x4b, 20000),
@@ -426,6 +427,69 @@ static const struct regulator_desc axp809_regulators[] = {
426 AXP_DESC_SW(AXP809, SW, "sw", "swin", AXP22X_PWR_OUT_CTRL2, BIT(6)), 427 AXP_DESC_SW(AXP809, SW, "sw", "swin", AXP22X_PWR_OUT_CTRL2, BIT(6)),
427}; 428};
428 429
430static const struct regulator_desc axp813_regulators[] = {
431 AXP_DESC(AXP813, DCDC1, "dcdc1", "vin1", 1600, 3400, 100,
432 AXP803_DCDC1_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL1, BIT(0)),
433 AXP_DESC_RANGES(AXP813, DCDC2, "dcdc2", "vin2", axp803_dcdc234_ranges,
434 76, AXP803_DCDC2_V_OUT, 0x7f, AXP22X_PWR_OUT_CTRL1,
435 BIT(1)),
436 AXP_DESC_RANGES(AXP813, DCDC3, "dcdc3", "vin3", axp803_dcdc234_ranges,
437 76, AXP803_DCDC3_V_OUT, 0x7f, AXP22X_PWR_OUT_CTRL1,
438 BIT(2)),
439 AXP_DESC_RANGES(AXP813, DCDC4, "dcdc4", "vin4", axp803_dcdc234_ranges,
440 76, AXP803_DCDC4_V_OUT, 0x7f, AXP22X_PWR_OUT_CTRL1,
441 BIT(3)),
442 AXP_DESC_RANGES(AXP813, DCDC5, "dcdc5", "vin5", axp803_dcdc5_ranges,
443 68, AXP803_DCDC5_V_OUT, 0x7f, AXP22X_PWR_OUT_CTRL1,
444 BIT(4)),
445 AXP_DESC_RANGES(AXP813, DCDC6, "dcdc6", "vin6", axp803_dcdc6_ranges,
446 72, AXP803_DCDC6_V_OUT, 0x7f, AXP22X_PWR_OUT_CTRL1,
447 BIT(5)),
448 AXP_DESC_RANGES(AXP813, DCDC7, "dcdc7", "vin7", axp803_dcdc6_ranges,
449 72, AXP813_DCDC7_V_OUT, 0x7f, AXP22X_PWR_OUT_CTRL1,
450 BIT(6)),
451 AXP_DESC(AXP813, ALDO1, "aldo1", "aldoin", 700, 3300, 100,
452 AXP22X_ALDO1_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL3, BIT(5)),
453 AXP_DESC(AXP813, ALDO2, "aldo2", "aldoin", 700, 3300, 100,
454 AXP22X_ALDO2_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL3, BIT(6)),
455 AXP_DESC(AXP813, ALDO3, "aldo3", "aldoin", 700, 3300, 100,
456 AXP22X_ALDO3_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL3, BIT(7)),
457 AXP_DESC(AXP813, DLDO1, "dldo1", "dldoin", 700, 3300, 100,
458 AXP22X_DLDO1_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL2, BIT(3)),
459 AXP_DESC_RANGES(AXP813, DLDO2, "dldo2", "dldoin", axp803_dldo2_ranges,
460 32, AXP22X_DLDO2_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL2,
461 BIT(4)),
462 AXP_DESC(AXP813, DLDO3, "dldo3", "dldoin", 700, 3300, 100,
463 AXP22X_DLDO3_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL2, BIT(5)),
464 AXP_DESC(AXP813, DLDO4, "dldo4", "dldoin", 700, 3300, 100,
465 AXP22X_DLDO4_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL2, BIT(6)),
466 AXP_DESC(AXP813, ELDO1, "eldo1", "eldoin", 700, 1900, 50,
467 AXP22X_ELDO1_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL2, BIT(0)),
468 AXP_DESC(AXP813, ELDO2, "eldo2", "eldoin", 700, 1900, 50,
469 AXP22X_ELDO2_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL2, BIT(1)),
470 AXP_DESC(AXP813, ELDO3, "eldo3", "eldoin", 700, 1900, 50,
471 AXP22X_ELDO3_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL2, BIT(2)),
472 /* to do / check ... */
473 AXP_DESC(AXP813, FLDO1, "fldo1", "fldoin", 700, 1450, 50,
474 AXP803_FLDO1_V_OUT, 0x0f, AXP22X_PWR_OUT_CTRL3, BIT(2)),
475 AXP_DESC(AXP813, FLDO2, "fldo2", "fldoin", 700, 1450, 50,
476 AXP803_FLDO2_V_OUT, 0x0f, AXP22X_PWR_OUT_CTRL3, BIT(3)),
477 /*
478 * TODO: FLDO3 = {DCDC5, FLDOIN} / 2
479 *
480 * This means FLDO3 effectively switches supplies at runtime,
481 * something the regulator subsystem does not support.
482 */
483 AXP_DESC_FIXED(AXP813, RTC_LDO, "rtc-ldo", "ips", 1800),
484 AXP_DESC_IO(AXP813, LDO_IO0, "ldo-io0", "ips", 700, 3300, 100,
485 AXP22X_LDO_IO0_V_OUT, 0x1f, AXP20X_GPIO0_CTRL, 0x07,
486 AXP22X_IO_ENABLED, AXP22X_IO_DISABLED),
487 AXP_DESC_IO(AXP813, LDO_IO1, "ldo-io1", "ips", 700, 3300, 100,
488 AXP22X_LDO_IO1_V_OUT, 0x1f, AXP20X_GPIO1_CTRL, 0x07,
489 AXP22X_IO_ENABLED, AXP22X_IO_DISABLED),
490 AXP_DESC_SW(AXP813, SW, "sw", "swin", AXP22X_PWR_OUT_CTRL2, BIT(7)),
491};
492
429static int axp20x_set_dcdc_freq(struct platform_device *pdev, u32 dcdcfreq) 493static int axp20x_set_dcdc_freq(struct platform_device *pdev, u32 dcdcfreq)
430{ 494{
431 struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent); 495 struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent);
@@ -441,9 +505,10 @@ static int axp20x_set_dcdc_freq(struct platform_device *pdev, u32 dcdcfreq)
441 step = 75; 505 step = 75;
442 break; 506 break;
443 case AXP803_ID: 507 case AXP803_ID:
508 case AXP813_ID:
444 /* 509 /*
445 * AXP803 DCDC work frequency setting has the same range and 510 * AXP803/AXP813 DCDC work frequency setting has the same
446 * step as AXP22X, but at a different register. 511 * range and step as AXP22X, but at a different register.
447 * Fall through to the check below. 512 * Fall through to the check below.
448 * (See include/linux/mfd/axp20x.h) 513 * (See include/linux/mfd/axp20x.h)
449 */ 514 */
@@ -561,6 +626,14 @@ static int axp20x_set_dcdc_workmode(struct regulator_dev *rdev, int id, u32 work
561 workmode <<= id - AXP803_DCDC1; 626 workmode <<= id - AXP803_DCDC1;
562 break; 627 break;
563 628
629 case AXP813_ID:
630 if (id < AXP813_DCDC1 || id > AXP813_DCDC7)
631 return -EINVAL;
632
633 mask = AXP22X_WORKMODE_DCDCX_MASK(id - AXP813_DCDC1);
634 workmode <<= id - AXP813_DCDC1;
635 break;
636
564 default: 637 default:
565 /* should not happen */ 638 /* should not happen */
566 WARN_ON(1); 639 WARN_ON(1);
@@ -579,11 +652,12 @@ static bool axp20x_is_polyphase_slave(struct axp20x_dev *axp20x, int id)
579 u32 reg = 0; 652 u32 reg = 0;
580 653
581 /* 654 /*
582 * Currently in our supported AXP variants, only AXP803 and AXP806 655 * Currently in our supported AXP variants, only AXP803, AXP806,
583 * have polyphase regulators. 656 * and AXP813 have polyphase regulators.
584 */ 657 */
585 switch (axp20x->variant) { 658 switch (axp20x->variant) {
586 case AXP803_ID: 659 case AXP803_ID:
660 case AXP813_ID:
587 regmap_read(axp20x->regmap, AXP803_POLYPHASE_CTRL, &reg); 661 regmap_read(axp20x->regmap, AXP803_POLYPHASE_CTRL, &reg);
588 662
589 switch (id) { 663 switch (id) {
@@ -656,6 +730,12 @@ static int axp20x_regulator_probe(struct platform_device *pdev)
656 regulators = axp809_regulators; 730 regulators = axp809_regulators;
657 nregulators = AXP809_REG_ID_MAX; 731 nregulators = AXP809_REG_ID_MAX;
658 break; 732 break;
733 case AXP813_ID:
734 regulators = axp813_regulators;
735 nregulators = AXP813_REG_ID_MAX;
736 drivevbus = of_property_read_bool(pdev->dev.parent->of_node,
737 "x-powers,drive-vbus-en");
738 break;
659 default: 739 default:
660 dev_err(&pdev->dev, "Unsupported AXP variant: %ld\n", 740 dev_err(&pdev->dev, "Unsupported AXP variant: %ld\n",
661 axp20x->variant); 741 axp20x->variant);
@@ -677,6 +757,10 @@ static int axp20x_regulator_probe(struct platform_device *pdev)
677 if (axp20x_is_polyphase_slave(axp20x, i)) 757 if (axp20x_is_polyphase_slave(axp20x, i))
678 continue; 758 continue;
679 759
760 /* Support for AXP813's FLDO3 is not implemented */
761 if (axp20x->variant == AXP813_ID && i == AXP813_FLDO3)
762 continue;
763
680 /* 764 /*
681 * Regulators DC1SW and DC5LDO are connected internally, 765 * Regulators DC1SW and DC5LDO are connected internally,
682 * so we have to handle their supply names separately. 766 * so we have to handle their supply names separately.
diff --git a/drivers/regulator/da9211-regulator.c b/drivers/regulator/da9211-regulator.c
index aa47280efd32..9b8f47617724 100644
--- a/drivers/regulator/da9211-regulator.c
+++ b/drivers/regulator/da9211-regulator.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * da9211-regulator.c - Regulator device driver for DA9211/DA9212 2 * da9211-regulator.c - Regulator device driver for DA9211/DA9212
3 * /DA9213/DA9214/DA9215 3 * /DA9213/DA9223/DA9214/DA9224/DA9215/DA9225
4 * Copyright (C) 2015 Dialog Semiconductor Ltd. 4 * Copyright (C) 2015 Dialog Semiconductor Ltd.
5 * 5 *
6 * This library is free software; you can redistribute it and/or 6 * This library is free software; you can redistribute it and/or
@@ -496,8 +496,11 @@ static const struct i2c_device_id da9211_i2c_id[] = {
496 {"da9211", DA9211}, 496 {"da9211", DA9211},
497 {"da9212", DA9212}, 497 {"da9212", DA9212},
498 {"da9213", DA9213}, 498 {"da9213", DA9213},
499 {"da9223", DA9223},
499 {"da9214", DA9214}, 500 {"da9214", DA9214},
501 {"da9224", DA9224},
500 {"da9215", DA9215}, 502 {"da9215", DA9215},
503 {"da9225", DA9225},
501 {}, 504 {},
502}; 505};
503MODULE_DEVICE_TABLE(i2c, da9211_i2c_id); 506MODULE_DEVICE_TABLE(i2c, da9211_i2c_id);
@@ -507,8 +510,11 @@ static const struct of_device_id da9211_dt_ids[] = {
507 { .compatible = "dlg,da9211", .data = &da9211_i2c_id[0] }, 510 { .compatible = "dlg,da9211", .data = &da9211_i2c_id[0] },
508 { .compatible = "dlg,da9212", .data = &da9211_i2c_id[1] }, 511 { .compatible = "dlg,da9212", .data = &da9211_i2c_id[1] },
509 { .compatible = "dlg,da9213", .data = &da9211_i2c_id[2] }, 512 { .compatible = "dlg,da9213", .data = &da9211_i2c_id[2] },
510 { .compatible = "dlg,da9214", .data = &da9211_i2c_id[3] }, 513 { .compatible = "dlg,da9223", .data = &da9211_i2c_id[3] },
511 { .compatible = "dlg,da9215", .data = &da9211_i2c_id[4] }, 514 { .compatible = "dlg,da9214", .data = &da9211_i2c_id[4] },
515 { .compatible = "dlg,da9224", .data = &da9211_i2c_id[5] },
516 { .compatible = "dlg,da9215", .data = &da9211_i2c_id[6] },
517 { .compatible = "dlg,da9225", .data = &da9211_i2c_id[7] },
512 {}, 518 {},
513}; 519};
514MODULE_DEVICE_TABLE(of, da9211_dt_ids); 520MODULE_DEVICE_TABLE(of, da9211_dt_ids);
@@ -526,5 +532,5 @@ static struct i2c_driver da9211_regulator_driver = {
526module_i2c_driver(da9211_regulator_driver); 532module_i2c_driver(da9211_regulator_driver);
527 533
528MODULE_AUTHOR("James Ban <James.Ban.opensource@diasemi.com>"); 534MODULE_AUTHOR("James Ban <James.Ban.opensource@diasemi.com>");
529MODULE_DESCRIPTION("DA9211/DA9212/DA9213/DA9214/DA9215 regulator driver"); 535MODULE_DESCRIPTION("DA9211/DA9212/DA9213/DA9223/DA9214/DA9224/DA9215/DA9225 regulator driver");
530MODULE_LICENSE("GPL"); 536MODULE_LICENSE("GPL");
diff --git a/drivers/regulator/da9211-regulator.h b/drivers/regulator/da9211-regulator.h
index b841bbf330cc..2cb32aab4f82 100644
--- a/drivers/regulator/da9211-regulator.h
+++ b/drivers/regulator/da9211-regulator.h
@@ -1,6 +1,6 @@
1/* 1/*
2 * da9211-regulator.h - Regulator definitions for DA9211/DA9212 2 * da9211-regulator.h - Regulator definitions for DA9211/DA9212
3 * /DA9213/DA9214/DA9215 3 * /DA9213/DA9223/DA9214/DA9224/DA9215/DA9225
4 * Copyright (C) 2015 Dialog Semiconductor Ltd. 4 * Copyright (C) 2015 Dialog Semiconductor Ltd.
5 * 5 *
6 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
diff --git a/drivers/regulator/qcom_spmi-regulator.c b/drivers/regulator/qcom_spmi-regulator.c
index 16c5f84e06a7..0241ada47d04 100644
--- a/drivers/regulator/qcom_spmi-regulator.c
+++ b/drivers/regulator/qcom_spmi-regulator.c
@@ -593,13 +593,20 @@ static int spmi_sw_selector_to_hw(struct spmi_regulator *vreg,
593 u8 *voltage_sel) 593 u8 *voltage_sel)
594{ 594{
595 const struct spmi_voltage_range *range, *end; 595 const struct spmi_voltage_range *range, *end;
596 unsigned offset;
596 597
597 range = vreg->set_points->range; 598 range = vreg->set_points->range;
598 end = range + vreg->set_points->count; 599 end = range + vreg->set_points->count;
599 600
600 for (; range < end; range++) { 601 for (; range < end; range++) {
601 if (selector < range->n_voltages) { 602 if (selector < range->n_voltages) {
602 *voltage_sel = selector; 603 /*
604 * hardware selectors between set point min and real
605 * min are invalid so we ignore them
606 */
607 offset = range->set_point_min_uV - range->min_uV;
608 offset /= range->step_uV;
609 *voltage_sel = selector + offset;
603 *range_sel = range->range_sel; 610 *range_sel = range->range_sel;
604 return 0; 611 return 0;
605 } 612 }
@@ -613,15 +620,35 @@ static int spmi_sw_selector_to_hw(struct spmi_regulator *vreg,
613static int spmi_hw_selector_to_sw(struct spmi_regulator *vreg, u8 hw_sel, 620static int spmi_hw_selector_to_sw(struct spmi_regulator *vreg, u8 hw_sel,
614 const struct spmi_voltage_range *range) 621 const struct spmi_voltage_range *range)
615{ 622{
616 int sw_sel = hw_sel; 623 unsigned sw_sel = 0;
624 unsigned offset, max_hw_sel;
617 const struct spmi_voltage_range *r = vreg->set_points->range; 625 const struct spmi_voltage_range *r = vreg->set_points->range;
618 626 const struct spmi_voltage_range *end = r + vreg->set_points->count;
619 while (r != range) { 627
628 for (; r < end; r++) {
629 if (r == range && range->n_voltages) {
630 /*
631 * hardware selectors between set point min and real
632 * min and between set point max and real max are
633 * invalid so we return an error if they're
634 * programmed into the hardware
635 */
636 offset = range->set_point_min_uV - range->min_uV;
637 offset /= range->step_uV;
638 if (hw_sel < offset)
639 return -EINVAL;
640
641 max_hw_sel = range->set_point_max_uV - range->min_uV;
642 max_hw_sel /= range->step_uV;
643 if (hw_sel > max_hw_sel)
644 return -EINVAL;
645
646 return sw_sel + hw_sel - offset;
647 }
620 sw_sel += r->n_voltages; 648 sw_sel += r->n_voltages;
621 r++;
622 } 649 }
623 650
624 return sw_sel; 651 return -EINVAL;
625} 652}
626 653
627static const struct spmi_voltage_range * 654static const struct spmi_voltage_range *
@@ -1619,11 +1646,20 @@ static const struct spmi_regulator_data pm8994_regulators[] = {
1619 { } 1646 { }
1620}; 1647};
1621 1648
1649static const struct spmi_regulator_data pmi8994_regulators[] = {
1650 { "s1", 0x1400, "vdd_s1", },
1651 { "s2", 0x1700, "vdd_s2", },
1652 { "s3", 0x1a00, "vdd_s3", },
1653 { "l1", 0x4000, "vdd_l1", },
1654 { }
1655};
1656
1622static const struct of_device_id qcom_spmi_regulator_match[] = { 1657static const struct of_device_id qcom_spmi_regulator_match[] = {
1623 { .compatible = "qcom,pm8841-regulators", .data = &pm8841_regulators }, 1658 { .compatible = "qcom,pm8841-regulators", .data = &pm8841_regulators },
1624 { .compatible = "qcom,pm8916-regulators", .data = &pm8916_regulators }, 1659 { .compatible = "qcom,pm8916-regulators", .data = &pm8916_regulators },
1625 { .compatible = "qcom,pm8941-regulators", .data = &pm8941_regulators }, 1660 { .compatible = "qcom,pm8941-regulators", .data = &pm8941_regulators },
1626 { .compatible = "qcom,pm8994-regulators", .data = &pm8994_regulators }, 1661 { .compatible = "qcom,pm8994-regulators", .data = &pm8994_regulators },
1662 { .compatible = "qcom,pmi8994-regulators", .data = &pmi8994_regulators },
1627 { } 1663 { }
1628}; 1664};
1629MODULE_DEVICE_TABLE(of, qcom_spmi_regulator_match); 1665MODULE_DEVICE_TABLE(of, qcom_spmi_regulator_match);
diff --git a/drivers/regulator/tps65218-regulator.c b/drivers/regulator/tps65218-regulator.c
index 9aafbb03482d..bc489958fed7 100644
--- a/drivers/regulator/tps65218-regulator.c
+++ b/drivers/regulator/tps65218-regulator.c
@@ -154,7 +154,7 @@ static int tps65218_pmic_set_suspend_disable(struct regulator_dev *dev)
154 154
155 if (!tps->strobes[rid]) { 155 if (!tps->strobes[rid]) {
156 if (rid == TPS65218_DCDC_3) 156 if (rid == TPS65218_DCDC_3)
157 tps->info[rid]->strobe = 3; 157 tps->strobes[rid] = 3;
158 else 158 else
159 return -EINVAL; 159 return -EINVAL;
160 } 160 }