summaryrefslogtreecommitdiff
path: root/drivers/regulator
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/regulator')
-rw-r--r--drivers/regulator/Kconfig12
-rw-r--r--drivers/regulator/Makefile1
-rw-r--r--drivers/regulator/axp20x-regulator.c94
-rw-r--r--drivers/regulator/bd71828-regulator.c58
-rw-r--r--drivers/regulator/core.c31
-rw-r--r--drivers/regulator/da9121-regulator.c4
-rw-r--r--drivers/regulator/da9211-regulator.c2
-rw-r--r--drivers/regulator/devres.c59
-rw-r--r--drivers/regulator/helpers.c43
-rw-r--r--drivers/regulator/irq_helpers.c3
-rw-r--r--drivers/regulator/isl9305.c2
-rw-r--r--drivers/regulator/max8973-regulator.c2
-rw-r--r--drivers/regulator/mt6311-regulator.c2
-rw-r--r--drivers/regulator/mt6360-regulator.c32
-rw-r--r--drivers/regulator/pca9450-regulator.c196
-rw-r--r--drivers/regulator/pf8x00-regulator.c2
-rw-r--r--drivers/regulator/pfuze100-regulator.c2
-rw-r--r--drivers/regulator/qcom-refgen-regulator.c1
-rw-r--r--drivers/regulator/rk808-regulator.c218
-rw-r--r--drivers/regulator/rohm-regulator.c4
-rw-r--r--drivers/regulator/rpi-panel-attiny-regulator.c2
-rw-r--r--drivers/regulator/rtmv20-regulator.c2
-rw-r--r--drivers/regulator/rtq2208-regulator.c129
-rw-r--r--drivers/regulator/rtq6752-regulator.c2
-rw-r--r--drivers/regulator/sun20i-regulator.c157
-rw-r--r--drivers/regulator/tps51632-regulator.c2
-rw-r--r--drivers/regulator/tps62360-regulator.c2
-rw-r--r--drivers/regulator/tps6287x-regulator.c1
-rw-r--r--drivers/regulator/tps65132-regulator.c7
-rw-r--r--drivers/regulator/tps6594-regulator.c350
-rw-r--r--drivers/regulator/vqmmc-ipq4019-regulator.c1
31 files changed, 1173 insertions, 250 deletions
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 7db0a29b5b8d..d333be2bea3b 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -1415,6 +1415,14 @@ config REGULATOR_STW481X_VMMC
This driver supports the internal VMMC regulator in the STw481x
PMIC chips.
+config REGULATOR_SUN20I
+ tristate "Allwinner D1 internal LDOs"
+ depends on ARCH_SUNXI || COMPILE_TEST
+ select MFD_SYSCON
+ default ARCH_SUNXI
+ help
+ This driver supports the internal LDOs in the Allwinner D1 SoC.
+
config REGULATOR_SY7636A
tristate "Silergy SY7636A voltage regulator"
depends on MFD_SY7636A
@@ -1563,13 +1571,15 @@ config REGULATOR_TPS6594
depends on MFD_TPS6594 && OF
default MFD_TPS6594
help
- This driver supports TPS6594 voltage regulator chips.
+ This driver supports TPS6594 series and TPS65224 voltage regulator chips.
TPS6594 series of PMICs have 5 BUCKs and 4 LDOs
voltage regulators.
BUCKs 1,2,3,4 can be used in single phase or multiphase mode.
Part number defines which single or multiphase mode is i used.
It supports software based voltage control
for different voltage domains.
+ TPS65224 PMIC has 4 BUCKs and 3 LDOs. BUCK12 can be used in dual phase.
+ All BUCKs and LDOs volatge can be controlled through software.
config REGULATOR_TPS6524X
tristate "TI TPS6524X Power regulators"
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 46fb569e6be8..ba15fa5f30ad 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -163,6 +163,7 @@ obj-$(CONFIG_REGULATOR_STM32_VREFBUF) += stm32-vrefbuf.o
obj-$(CONFIG_REGULATOR_STM32_PWR) += stm32-pwr.o
obj-$(CONFIG_REGULATOR_STPMIC1) += stpmic1_regulator.o
obj-$(CONFIG_REGULATOR_STW481X_VMMC) += stw481x-vmmc.o
+obj-$(CONFIG_REGULATOR_SUN20I) += sun20i-regulator.o
obj-$(CONFIG_REGULATOR_SY7636A) += sy7636a-regulator.o
obj-$(CONFIG_REGULATOR_SY8106A) += sy8106a-regulator.o
obj-$(CONFIG_REGULATOR_SY8824X) += sy8824x.o
diff --git a/drivers/regulator/axp20x-regulator.c b/drivers/regulator/axp20x-regulator.c
index c657820b0bbb..34fcdd82b2ea 100644
--- a/drivers/regulator/axp20x-regulator.c
+++ b/drivers/regulator/axp20x-regulator.c
@@ -138,6 +138,12 @@
#define AXP313A_DCDC_V_OUT_MASK GENMASK(6, 0)
#define AXP313A_LDO_V_OUT_MASK GENMASK(4, 0)
+#define AXP717_DCDC1_NUM_VOLTAGES 88
+#define AXP717_DCDC2_NUM_VOLTAGES 107
+#define AXP717_DCDC3_NUM_VOLTAGES 104
+#define AXP717_DCDC_V_OUT_MASK GENMASK(6, 0)
+#define AXP717_LDO_V_OUT_MASK GENMASK(4, 0)
+
#define AXP803_PWR_OUT_DCDC1_MASK BIT_MASK(0)
#define AXP803_PWR_OUT_DCDC2_MASK BIT_MASK(1)
#define AXP803_PWR_OUT_DCDC3_MASK BIT_MASK(2)
@@ -733,25 +739,98 @@ static const struct linear_range axp313a_dcdc3_ranges[] = {
static const struct regulator_desc axp313a_regulators[] = {
AXP_DESC_RANGES(AXP313A, DCDC1, "dcdc1", "vin1",
axp313a_dcdc1_ranges, AXP313A_DCDC1_NUM_VOLTAGES,
- AXP313A_DCDC1_CONRTOL, AXP313A_DCDC_V_OUT_MASK,
+ AXP313A_DCDC1_CONTROL, AXP313A_DCDC_V_OUT_MASK,
AXP313A_OUTPUT_CONTROL, BIT(0)),
AXP_DESC_RANGES(AXP313A, DCDC2, "dcdc2", "vin2",
axp313a_dcdc2_ranges, AXP313A_DCDC23_NUM_VOLTAGES,
- AXP313A_DCDC2_CONRTOL, AXP313A_DCDC_V_OUT_MASK,
+ AXP313A_DCDC2_CONTROL, AXP313A_DCDC_V_OUT_MASK,
AXP313A_OUTPUT_CONTROL, BIT(1)),
AXP_DESC_RANGES(AXP313A, DCDC3, "dcdc3", "vin3",
axp313a_dcdc3_ranges, AXP313A_DCDC23_NUM_VOLTAGES,
- AXP313A_DCDC3_CONRTOL, AXP313A_DCDC_V_OUT_MASK,
+ AXP313A_DCDC3_CONTROL, AXP313A_DCDC_V_OUT_MASK,
AXP313A_OUTPUT_CONTROL, BIT(2)),
AXP_DESC(AXP313A, ALDO1, "aldo1", "vin1", 500, 3500, 100,
- AXP313A_ALDO1_CONRTOL, AXP313A_LDO_V_OUT_MASK,
+ AXP313A_ALDO1_CONTROL, AXP313A_LDO_V_OUT_MASK,
AXP313A_OUTPUT_CONTROL, BIT(3)),
AXP_DESC(AXP313A, DLDO1, "dldo1", "vin1", 500, 3500, 100,
- AXP313A_DLDO1_CONRTOL, AXP313A_LDO_V_OUT_MASK,
+ AXP313A_DLDO1_CONTROL, AXP313A_LDO_V_OUT_MASK,
AXP313A_OUTPUT_CONTROL, BIT(4)),
AXP_DESC_FIXED(AXP313A, RTC_LDO, "rtc-ldo", "vin1", 1800),
};
+static const struct linear_range axp717_dcdc1_ranges[] = {
+ REGULATOR_LINEAR_RANGE(500000, 0, 70, 10000),
+ REGULATOR_LINEAR_RANGE(1220000, 71, 87, 20000),
+};
+
+static const struct linear_range axp717_dcdc2_ranges[] = {
+ REGULATOR_LINEAR_RANGE(500000, 0, 70, 10000),
+ REGULATOR_LINEAR_RANGE(1220000, 71, 87, 20000),
+ REGULATOR_LINEAR_RANGE(1600000, 88, 107, 100000),
+};
+
+static const struct linear_range axp717_dcdc3_ranges[] = {
+ REGULATOR_LINEAR_RANGE(500000, 0, 70, 10000),
+ REGULATOR_LINEAR_RANGE(1220000, 71, 102, 20000),
+};
+
+static const struct regulator_desc axp717_regulators[] = {
+ AXP_DESC_RANGES(AXP717, DCDC1, "dcdc1", "vin1",
+ axp717_dcdc1_ranges, AXP717_DCDC1_NUM_VOLTAGES,
+ AXP717_DCDC1_CONTROL, AXP717_DCDC_V_OUT_MASK,
+ AXP717_DCDC_OUTPUT_CONTROL, BIT(0)),
+ AXP_DESC_RANGES(AXP717, DCDC2, "dcdc2", "vin2",
+ axp717_dcdc2_ranges, AXP717_DCDC2_NUM_VOLTAGES,
+ AXP717_DCDC2_CONTROL, AXP717_DCDC_V_OUT_MASK,
+ AXP717_DCDC_OUTPUT_CONTROL, BIT(1)),
+ AXP_DESC_RANGES(AXP717, DCDC3, "dcdc3", "vin3",
+ axp717_dcdc3_ranges, AXP717_DCDC3_NUM_VOLTAGES,
+ AXP717_DCDC3_CONTROL, AXP717_DCDC_V_OUT_MASK,
+ AXP717_DCDC_OUTPUT_CONTROL, BIT(2)),
+ AXP_DESC(AXP717, DCDC4, "dcdc4", "vin4", 1000, 3700, 100,
+ AXP717_DCDC4_CONTROL, AXP717_DCDC_V_OUT_MASK,
+ AXP717_DCDC_OUTPUT_CONTROL, BIT(3)),
+ AXP_DESC(AXP717, ALDO1, "aldo1", "vin1", 500, 3500, 100,
+ AXP717_ALDO1_CONTROL, AXP717_LDO_V_OUT_MASK,
+ AXP717_LDO0_OUTPUT_CONTROL, BIT(0)),
+ AXP_DESC(AXP717, ALDO2, "aldo2", "vin1", 500, 3500, 100,
+ AXP717_ALDO2_CONTROL, AXP717_LDO_V_OUT_MASK,
+ AXP717_LDO0_OUTPUT_CONTROL, BIT(1)),
+ AXP_DESC(AXP717, ALDO3, "aldo3", "vin1", 500, 3500, 100,
+ AXP717_ALDO3_CONTROL, AXP717_LDO_V_OUT_MASK,
+ AXP717_LDO0_OUTPUT_CONTROL, BIT(2)),
+ AXP_DESC(AXP717, ALDO4, "aldo4", "vin1", 500, 3500, 100,
+ AXP717_ALDO4_CONTROL, AXP717_LDO_V_OUT_MASK,
+ AXP717_LDO0_OUTPUT_CONTROL, BIT(3)),
+ AXP_DESC(AXP717, BLDO1, "bldo1", "vin1", 500, 3500, 100,
+ AXP717_BLDO1_CONTROL, AXP717_LDO_V_OUT_MASK,
+ AXP717_LDO0_OUTPUT_CONTROL, BIT(4)),
+ AXP_DESC(AXP717, BLDO2, "bldo2", "vin1", 500, 3500, 100,
+ AXP717_BLDO2_CONTROL, AXP717_LDO_V_OUT_MASK,
+ AXP717_LDO0_OUTPUT_CONTROL, BIT(5)),
+ AXP_DESC(AXP717, BLDO3, "bldo3", "vin1", 500, 3500, 100,
+ AXP717_BLDO3_CONTROL, AXP717_LDO_V_OUT_MASK,
+ AXP717_LDO0_OUTPUT_CONTROL, BIT(6)),
+ AXP_DESC(AXP717, BLDO4, "bldo4", "vin1", 500, 3500, 100,
+ AXP717_BLDO4_CONTROL, AXP717_LDO_V_OUT_MASK,
+ AXP717_LDO0_OUTPUT_CONTROL, BIT(7)),
+ AXP_DESC(AXP717, CLDO1, "cldo1", "vin1", 500, 3500, 100,
+ AXP717_CLDO1_CONTROL, AXP717_LDO_V_OUT_MASK,
+ AXP717_LDO1_OUTPUT_CONTROL, BIT(0)),
+ AXP_DESC(AXP717, CLDO2, "cldo2", "vin1", 500, 3500, 100,
+ AXP717_CLDO2_CONTROL, AXP717_LDO_V_OUT_MASK,
+ AXP717_LDO1_OUTPUT_CONTROL, BIT(1)),
+ AXP_DESC(AXP717, CLDO3, "cldo3", "vin1", 500, 3500, 100,
+ AXP717_CLDO3_CONTROL, AXP717_LDO_V_OUT_MASK,
+ AXP717_LDO1_OUTPUT_CONTROL, BIT(2)),
+ AXP_DESC(AXP717, CLDO4, "cldo4", "vin1", 500, 3500, 100,
+ AXP717_CLDO4_CONTROL, AXP717_LDO_V_OUT_MASK,
+ AXP717_LDO1_OUTPUT_CONTROL, BIT(3)),
+ AXP_DESC(AXP717, CPUSLDO, "cpusldo", "vin1", 500, 1400, 50,
+ AXP717_CPUSLDO_CONTROL, AXP717_LDO_V_OUT_MASK,
+ AXP717_LDO1_OUTPUT_CONTROL, BIT(4)),
+};
+
/* DCDC ranges shared with AXP813 */
static const struct linear_range axp803_dcdc234_ranges[] = {
REGULATOR_LINEAR_RANGE(500000,
@@ -1253,6 +1332,7 @@ static int axp20x_set_dcdc_freq(struct platform_device *pdev, u32 dcdcfreq)
step = 150;
break;
case AXP313A_ID:
+ case AXP717_ID:
case AXP15060_ID:
/* The DCDC PWM frequency seems to be fixed to 3 MHz. */
if (dcdcfreq != 0) {
@@ -1479,6 +1559,10 @@ static int axp20x_regulator_probe(struct platform_device *pdev)
regulators = axp313a_regulators;
nregulators = AXP313A_REG_ID_MAX;
break;
+ case AXP717_ID:
+ regulators = axp717_regulators;
+ nregulators = AXP717_REG_ID_MAX;
+ break;
case AXP803_ID:
regulators = axp803_regulators;
nregulators = AXP803_REG_ID_MAX;
diff --git a/drivers/regulator/bd71828-regulator.c b/drivers/regulator/bd71828-regulator.c
index 08d4ee369287..dd871ffe979c 100644
--- a/drivers/regulator/bd71828-regulator.c
+++ b/drivers/regulator/bd71828-regulator.c
@@ -206,14 +206,11 @@ static const struct bd71828_regulator_data bd71828_rdata[] = {
.suspend_reg = BD71828_REG_BUCK1_SUSP_VOLT,
.suspend_mask = BD71828_MASK_BUCK1267_VOLT,
.suspend_on_mask = BD71828_MASK_SUSP_EN,
- .lpsr_on_mask = BD71828_MASK_LPSR_EN,
/*
* LPSR voltage is same as SUSPEND voltage. Allow
- * setting it so that regulator can be set enabled at
- * LPSR state
+ * only enabling/disabling regulator for LPSR state
*/
- .lpsr_reg = BD71828_REG_BUCK1_SUSP_VOLT,
- .lpsr_mask = BD71828_MASK_BUCK1267_VOLT,
+ .lpsr_on_mask = BD71828_MASK_LPSR_EN,
},
.reg_inits = buck1_inits,
.reg_init_amnt = ARRAY_SIZE(buck1_inits),
@@ -288,13 +285,7 @@ static const struct bd71828_regulator_data bd71828_rdata[] = {
ROHM_DVS_LEVEL_SUSPEND |
ROHM_DVS_LEVEL_LPSR,
.run_reg = BD71828_REG_BUCK3_VOLT,
- .idle_reg = BD71828_REG_BUCK3_VOLT,
- .suspend_reg = BD71828_REG_BUCK3_VOLT,
- .lpsr_reg = BD71828_REG_BUCK3_VOLT,
.run_mask = BD71828_MASK_BUCK3_VOLT,
- .idle_mask = BD71828_MASK_BUCK3_VOLT,
- .suspend_mask = BD71828_MASK_BUCK3_VOLT,
- .lpsr_mask = BD71828_MASK_BUCK3_VOLT,
.idle_on_mask = BD71828_MASK_IDLE_EN,
.suspend_on_mask = BD71828_MASK_SUSP_EN,
.lpsr_on_mask = BD71828_MASK_LPSR_EN,
@@ -329,13 +320,7 @@ static const struct bd71828_regulator_data bd71828_rdata[] = {
ROHM_DVS_LEVEL_SUSPEND |
ROHM_DVS_LEVEL_LPSR,
.run_reg = BD71828_REG_BUCK4_VOLT,
- .idle_reg = BD71828_REG_BUCK4_VOLT,
- .suspend_reg = BD71828_REG_BUCK4_VOLT,
- .lpsr_reg = BD71828_REG_BUCK4_VOLT,
.run_mask = BD71828_MASK_BUCK4_VOLT,
- .idle_mask = BD71828_MASK_BUCK4_VOLT,
- .suspend_mask = BD71828_MASK_BUCK4_VOLT,
- .lpsr_mask = BD71828_MASK_BUCK4_VOLT,
.idle_on_mask = BD71828_MASK_IDLE_EN,
.suspend_on_mask = BD71828_MASK_SUSP_EN,
.lpsr_on_mask = BD71828_MASK_LPSR_EN,
@@ -370,13 +355,7 @@ static const struct bd71828_regulator_data bd71828_rdata[] = {
ROHM_DVS_LEVEL_SUSPEND |
ROHM_DVS_LEVEL_LPSR,
.run_reg = BD71828_REG_BUCK5_VOLT,
- .idle_reg = BD71828_REG_BUCK5_VOLT,
- .suspend_reg = BD71828_REG_BUCK5_VOLT,
- .lpsr_reg = BD71828_REG_BUCK5_VOLT,
.run_mask = BD71828_MASK_BUCK5_VOLT,
- .idle_mask = BD71828_MASK_BUCK5_VOLT,
- .suspend_mask = BD71828_MASK_BUCK5_VOLT,
- .lpsr_mask = BD71828_MASK_BUCK5_VOLT,
.idle_on_mask = BD71828_MASK_IDLE_EN,
.suspend_on_mask = BD71828_MASK_SUSP_EN,
.lpsr_on_mask = BD71828_MASK_LPSR_EN,
@@ -493,13 +472,7 @@ static const struct bd71828_regulator_data bd71828_rdata[] = {
ROHM_DVS_LEVEL_SUSPEND |
ROHM_DVS_LEVEL_LPSR,
.run_reg = BD71828_REG_LDO1_VOLT,
- .idle_reg = BD71828_REG_LDO1_VOLT,
- .suspend_reg = BD71828_REG_LDO1_VOLT,
- .lpsr_reg = BD71828_REG_LDO1_VOLT,
.run_mask = BD71828_MASK_LDO_VOLT,
- .idle_mask = BD71828_MASK_LDO_VOLT,
- .suspend_mask = BD71828_MASK_LDO_VOLT,
- .lpsr_mask = BD71828_MASK_LDO_VOLT,
.idle_on_mask = BD71828_MASK_IDLE_EN,
.suspend_on_mask = BD71828_MASK_SUSP_EN,
.lpsr_on_mask = BD71828_MASK_LPSR_EN,
@@ -533,13 +506,7 @@ static const struct bd71828_regulator_data bd71828_rdata[] = {
ROHM_DVS_LEVEL_SUSPEND |
ROHM_DVS_LEVEL_LPSR,
.run_reg = BD71828_REG_LDO2_VOLT,
- .idle_reg = BD71828_REG_LDO2_VOLT,
- .suspend_reg = BD71828_REG_LDO2_VOLT,
- .lpsr_reg = BD71828_REG_LDO2_VOLT,
.run_mask = BD71828_MASK_LDO_VOLT,
- .idle_mask = BD71828_MASK_LDO_VOLT,
- .suspend_mask = BD71828_MASK_LDO_VOLT,
- .lpsr_mask = BD71828_MASK_LDO_VOLT,
.idle_on_mask = BD71828_MASK_IDLE_EN,
.suspend_on_mask = BD71828_MASK_SUSP_EN,
.lpsr_on_mask = BD71828_MASK_LPSR_EN,
@@ -573,13 +540,7 @@ static const struct bd71828_regulator_data bd71828_rdata[] = {
ROHM_DVS_LEVEL_SUSPEND |
ROHM_DVS_LEVEL_LPSR,
.run_reg = BD71828_REG_LDO3_VOLT,
- .idle_reg = BD71828_REG_LDO3_VOLT,
- .suspend_reg = BD71828_REG_LDO3_VOLT,
- .lpsr_reg = BD71828_REG_LDO3_VOLT,
.run_mask = BD71828_MASK_LDO_VOLT,
- .idle_mask = BD71828_MASK_LDO_VOLT,
- .suspend_mask = BD71828_MASK_LDO_VOLT,
- .lpsr_mask = BD71828_MASK_LDO_VOLT,
.idle_on_mask = BD71828_MASK_IDLE_EN,
.suspend_on_mask = BD71828_MASK_SUSP_EN,
.lpsr_on_mask = BD71828_MASK_LPSR_EN,
@@ -614,13 +575,7 @@ static const struct bd71828_regulator_data bd71828_rdata[] = {
ROHM_DVS_LEVEL_SUSPEND |
ROHM_DVS_LEVEL_LPSR,
.run_reg = BD71828_REG_LDO4_VOLT,
- .idle_reg = BD71828_REG_LDO4_VOLT,
- .suspend_reg = BD71828_REG_LDO4_VOLT,
- .lpsr_reg = BD71828_REG_LDO4_VOLT,
.run_mask = BD71828_MASK_LDO_VOLT,
- .idle_mask = BD71828_MASK_LDO_VOLT,
- .suspend_mask = BD71828_MASK_LDO_VOLT,
- .lpsr_mask = BD71828_MASK_LDO_VOLT,
.idle_on_mask = BD71828_MASK_IDLE_EN,
.suspend_on_mask = BD71828_MASK_SUSP_EN,
.lpsr_on_mask = BD71828_MASK_LPSR_EN,
@@ -655,13 +610,7 @@ static const struct bd71828_regulator_data bd71828_rdata[] = {
ROHM_DVS_LEVEL_SUSPEND |
ROHM_DVS_LEVEL_LPSR,
.run_reg = BD71828_REG_LDO5_VOLT,
- .idle_reg = BD71828_REG_LDO5_VOLT,
- .suspend_reg = BD71828_REG_LDO5_VOLT,
- .lpsr_reg = BD71828_REG_LDO5_VOLT,
.run_mask = BD71828_MASK_LDO_VOLT,
- .idle_mask = BD71828_MASK_LDO_VOLT,
- .suspend_mask = BD71828_MASK_LDO_VOLT,
- .lpsr_mask = BD71828_MASK_LDO_VOLT,
.idle_on_mask = BD71828_MASK_IDLE_EN,
.suspend_on_mask = BD71828_MASK_SUSP_EN,
.lpsr_on_mask = BD71828_MASK_LPSR_EN,
@@ -720,9 +669,6 @@ static const struct bd71828_regulator_data bd71828_rdata[] = {
.suspend_reg = BD71828_REG_LDO7_VOLT,
.lpsr_reg = BD71828_REG_LDO7_VOLT,
.run_mask = BD71828_MASK_LDO_VOLT,
- .idle_mask = BD71828_MASK_LDO_VOLT,
- .suspend_mask = BD71828_MASK_LDO_VOLT,
- .lpsr_mask = BD71828_MASK_LDO_VOLT,
.idle_on_mask = BD71828_MASK_IDLE_EN,
.suspend_on_mask = BD71828_MASK_SUSP_EN,
.lpsr_on_mask = BD71828_MASK_LPSR_EN,
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index dabac9772741..5794f4e9dd52 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -1911,19 +1911,24 @@ static struct regulator *create_regulator(struct regulator_dev *rdev,
}
}
- if (err != -EEXIST)
+ if (err != -EEXIST) {
regulator->debugfs = debugfs_create_dir(supply_name, rdev->debugfs);
- if (IS_ERR(regulator->debugfs))
- rdev_dbg(rdev, "Failed to create debugfs directory\n");
+ if (IS_ERR(regulator->debugfs)) {
+ rdev_dbg(rdev, "Failed to create debugfs directory\n");
+ regulator->debugfs = NULL;
+ }
+ }
- debugfs_create_u32("uA_load", 0444, regulator->debugfs,
- &regulator->uA_load);
- debugfs_create_u32("min_uV", 0444, regulator->debugfs,
- &regulator->voltage[PM_SUSPEND_ON].min_uV);
- debugfs_create_u32("max_uV", 0444, regulator->debugfs,
- &regulator->voltage[PM_SUSPEND_ON].max_uV);
- debugfs_create_file("constraint_flags", 0444, regulator->debugfs,
- regulator, &constraint_flags_fops);
+ if (regulator->debugfs) {
+ debugfs_create_u32("uA_load", 0444, regulator->debugfs,
+ &regulator->uA_load);
+ debugfs_create_u32("min_uV", 0444, regulator->debugfs,
+ &regulator->voltage[PM_SUSPEND_ON].min_uV);
+ debugfs_create_u32("max_uV", 0444, regulator->debugfs,
+ &regulator->voltage[PM_SUSPEND_ON].max_uV);
+ debugfs_create_file("constraint_flags", 0444, regulator->debugfs,
+ regulator, &constraint_flags_fops);
+ }
/*
* Check now if the regulator is an always on regulator - if
@@ -2195,7 +2200,7 @@ struct regulator *_regulator_get(struct device *dev, const char *id,
if (!have_full_constraints()) {
dev_warn(dev,
- "incomplete constraints, dummy supplies not allowed\n");
+ "incomplete constraints, dummy supplies not allowed (id=%s)\n", id);
return ERR_PTR(-ENODEV);
}
@@ -2213,7 +2218,7 @@ struct regulator *_regulator_get(struct device *dev, const char *id,
case EXCLUSIVE_GET:
dev_warn(dev,
- "dummy supplies not allowed for exclusive requests\n");
+ "dummy supplies not allowed for exclusive requests (id=%s)\n", id);
fallthrough;
default:
diff --git a/drivers/regulator/da9121-regulator.c b/drivers/regulator/da9121-regulator.c
index 5ee76b533576..96257551bb12 100644
--- a/drivers/regulator/da9121-regulator.c
+++ b/drivers/regulator/da9121-regulator.c
@@ -872,7 +872,7 @@ static struct regmap_config da9121_1ch_regmap_config = {
.rd_table = &da9121_1ch_readable_table,
.wr_table = &da9121_1ch_writeable_table,
.volatile_table = &da9121_volatile_table,
- .cache_type = REGCACHE_RBTREE,
+ .cache_type = REGCACHE_MAPLE,
};
/* DA9121 regmap config for 2 channel variants */
@@ -883,7 +883,7 @@ static struct regmap_config da9121_2ch_regmap_config = {
.rd_table = &da9121_2ch_readable_table,
.wr_table = &da9121_2ch_writeable_table,
.volatile_table = &da9121_volatile_table,
- .cache_type = REGCACHE_RBTREE,
+ .cache_type = REGCACHE_MAPLE,
};
static int da9121_check_device_type(struct i2c_client *i2c, struct da9121 *chip)
diff --git a/drivers/regulator/da9211-regulator.c b/drivers/regulator/da9211-regulator.c
index af383ff0fe57..d8b39ea3de0e 100644
--- a/drivers/regulator/da9211-regulator.c
+++ b/drivers/regulator/da9211-regulator.c
@@ -68,7 +68,7 @@ static const struct regmap_config da9211_regmap_config = {
.val_bits = 8,
.max_register = 5 * 128,
.volatile_reg = da9211_volatile_reg,
- .cache_type = REGCACHE_RBTREE,
+ .cache_type = REGCACHE_MAPLE,
.ranges = da9211_regmap_range,
.num_ranges = ARRAY_SIZE(da9211_regmap_range),
};
diff --git a/drivers/regulator/devres.c b/drivers/regulator/devres.c
index 90bb0d178885..7111c46e9de1 100644
--- a/drivers/regulator/devres.c
+++ b/drivers/regulator/devres.c
@@ -145,6 +145,65 @@ struct regulator *devm_regulator_get_optional(struct device *dev,
}
EXPORT_SYMBOL_GPL(devm_regulator_get_optional);
+/**
+ * devm_regulator_get_enable_read_voltage - Resource managed regulator get and
+ * enable that returns the voltage
+ * @dev: device to supply
+ * @id: supply name or regulator ID.
+ *
+ * Get and enable regulator for duration of the device life-time.
+ * regulator_disable() and regulator_put() are automatically called on driver
+ * detach. See regulator_get_optional(), regulator_enable(), and
+ * regulator_get_voltage() for more information.
+ *
+ * This is a convenience function for supplies that provide a reference voltage
+ * where the consumer driver just needs to know the voltage and keep the
+ * regulator enabled.
+ *
+ * In cases where the supply is not strictly required, callers can check for
+ * -ENODEV error and handle it accordingly.
+ *
+ * Returns: voltage in microvolts on success, or an error code on failure.
+ */
+int devm_regulator_get_enable_read_voltage(struct device *dev, const char *id)
+{
+ struct regulator *r;
+ int ret;
+
+ /*
+ * Since we need a real voltage, we use devm_regulator_get_optional()
+ * rather than getting a dummy regulator with devm_regulator_get() and
+ * then letting regulator_get_voltage() fail with -EINVAL. This way, the
+ * caller can handle the -ENODEV error code if needed instead of the
+ * ambiguous -EINVAL.
+ */
+ r = devm_regulator_get_optional(dev, id);
+ if (IS_ERR(r))
+ return PTR_ERR(r);
+
+ ret = regulator_enable(r);
+ if (ret)
+ goto err_regulator_put;
+
+ ret = devm_add_action_or_reset(dev, regulator_action_disable, r);
+ if (ret)
+ goto err_regulator_put;
+
+ ret = regulator_get_voltage(r);
+ if (ret < 0)
+ goto err_release_action;
+
+ return ret;
+
+err_release_action:
+ devm_release_action(dev, regulator_action_disable, r);
+err_regulator_put:
+ devm_regulator_put(r);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(devm_regulator_get_enable_read_voltage);
+
static int devm_regulator_match(struct device *dev, void *res, void *data)
{
struct regulator **r = res;
diff --git a/drivers/regulator/helpers.c b/drivers/regulator/helpers.c
index d49268336553..6e1ace660b8c 100644
--- a/drivers/regulator/helpers.c
+++ b/drivers/regulator/helpers.c
@@ -161,6 +161,32 @@ int regulator_get_voltage_sel_pickable_regmap(struct regulator_dev *rdev)
}
EXPORT_SYMBOL_GPL(regulator_get_voltage_sel_pickable_regmap);
+static int write_separate_vsel_and_range(struct regulator_dev *rdev,
+ unsigned int sel, unsigned int range)
+{
+ bool range_updated;
+ int ret;
+
+ ret = regmap_update_bits_base(rdev->regmap, rdev->desc->vsel_range_reg,
+ rdev->desc->vsel_range_mask,
+ range, &range_updated, false, false);
+ if (ret)
+ return ret;
+
+ /*
+ * Some PMICs treat the vsel_reg same as apply-bit. Force it to be
+ * written if the range changed, even if the old selector was same as
+ * the new one
+ */
+ if (rdev->desc->range_applied_by_vsel && range_updated)
+ return regmap_write_bits(rdev->regmap,
+ rdev->desc->vsel_reg,
+ rdev->desc->vsel_mask, sel);
+
+ return regmap_update_bits(rdev->regmap, rdev->desc->vsel_reg,
+ rdev->desc->vsel_mask, sel);
+}
+
/**
* regulator_set_voltage_sel_pickable_regmap - pickable range set_voltage_sel
*
@@ -199,21 +225,12 @@ int regulator_set_voltage_sel_pickable_regmap(struct regulator_dev *rdev,
range = rdev->desc->linear_range_selectors_bitfield[i];
range <<= ffs(rdev->desc->vsel_range_mask) - 1;
- if (rdev->desc->vsel_reg == rdev->desc->vsel_range_reg) {
- ret = regmap_update_bits(rdev->regmap,
- rdev->desc->vsel_reg,
+ if (rdev->desc->vsel_reg == rdev->desc->vsel_range_reg)
+ ret = regmap_update_bits(rdev->regmap, rdev->desc->vsel_reg,
rdev->desc->vsel_range_mask |
rdev->desc->vsel_mask, sel | range);
- } else {
- ret = regmap_update_bits(rdev->regmap,
- rdev->desc->vsel_range_reg,
- rdev->desc->vsel_range_mask, range);
- if (ret)
- return ret;
-
- ret = regmap_update_bits(rdev->regmap, rdev->desc->vsel_reg,
- rdev->desc->vsel_mask, sel);
- }
+ else
+ ret = write_separate_vsel_and_range(rdev, sel, range);
if (ret)
return ret;
diff --git a/drivers/regulator/irq_helpers.c b/drivers/regulator/irq_helpers.c
index fe7ae0f3f46a..5ab1a0befe12 100644
--- a/drivers/regulator/irq_helpers.c
+++ b/drivers/regulator/irq_helpers.c
@@ -352,6 +352,9 @@ void *regulator_irq_helper(struct device *dev,
h->irq = irq;
h->desc = *d;
+ h->desc.name = devm_kstrdup(dev, d->name, GFP_KERNEL);
+ if (!h->desc.name)
+ return ERR_PTR(-ENOMEM);
ret = init_rdev_state(dev, h, rdev, common_errs, per_rdev_errs,
rdev_amount);
diff --git a/drivers/regulator/isl9305.c b/drivers/regulator/isl9305.c
index 0f7560093091..5a234f25e6bb 100644
--- a/drivers/regulator/isl9305.c
+++ b/drivers/regulator/isl9305.c
@@ -134,7 +134,7 @@ static const struct regmap_config isl9305_regmap = {
.val_bits = 8,
.max_register = ISL9305_MAX_REG,
- .cache_type = REGCACHE_RBTREE,
+ .cache_type = REGCACHE_MAPLE,
};
static int isl9305_i2c_probe(struct i2c_client *i2c)
diff --git a/drivers/regulator/max8973-regulator.c b/drivers/regulator/max8973-regulator.c
index f8bb6828feef..96ca146281d6 100644
--- a/drivers/regulator/max8973-regulator.c
+++ b/drivers/regulator/max8973-regulator.c
@@ -510,7 +510,7 @@ static const struct regmap_config max8973_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
.max_register = MAX8973_CHIPID2,
- .cache_type = REGCACHE_RBTREE,
+ .cache_type = REGCACHE_MAPLE,
};
static struct max8973_regulator_platform_data *max8973_parse_dt(
diff --git a/drivers/regulator/mt6311-regulator.c b/drivers/regulator/mt6311-regulator.c
index 63a51485f2cc..c00638cd2d1e 100644
--- a/drivers/regulator/mt6311-regulator.c
+++ b/drivers/regulator/mt6311-regulator.c
@@ -20,7 +20,7 @@ static const struct regmap_config mt6311_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
.max_register = MT6311_FQMTR_CON4,
- .cache_type = REGCACHE_RBTREE,
+ .cache_type = REGCACHE_MAPLE,
};
/* Default limits measured in millivolts and milliamps */
diff --git a/drivers/regulator/mt6360-regulator.c b/drivers/regulator/mt6360-regulator.c
index ad6587a378d0..24cc9fc94e90 100644
--- a/drivers/regulator/mt6360-regulator.c
+++ b/drivers/regulator/mt6360-regulator.c
@@ -319,15 +319,15 @@ static unsigned int mt6360_regulator_of_map_mode(unsigned int hw_mode)
}
}
-#define MT6360_REGULATOR_DESC(_name, _sname, ereg, emask, vreg, vmask, \
- mreg, mmask, streg, stmask, vranges, \
- vcnts, offon_delay, irq_tbls) \
+#define MT6360_REGULATOR_DESC(match, _name, _sname, ereg, emask, vreg, \
+ vmask, mreg, mmask, streg, stmask, \
+ vranges, vcnts, offon_delay, irq_tbls) \
{ \
.desc = { \
.name = #_name, \
.supply_name = #_sname, \
.id = MT6360_REGULATOR_##_name, \
- .of_match = of_match_ptr(#_name), \
+ .of_match = of_match_ptr(match), \
.regulators_node = of_match_ptr("regulator"), \
.of_map_mode = mt6360_regulator_of_map_mode, \
.owner = THIS_MODULE, \
@@ -351,21 +351,29 @@ static unsigned int mt6360_regulator_of_map_mode(unsigned int hw_mode)
}
static const struct mt6360_regulator_desc mt6360_regulator_descs[] = {
- MT6360_REGULATOR_DESC(BUCK1, BUCK1_VIN, 0x117, 0x40, 0x110, 0xff, 0x117, 0x30, 0x117, 0x04,
+ MT6360_REGULATOR_DESC("buck1", BUCK1, BUCK1_VIN,
+ 0x117, 0x40, 0x110, 0xff, 0x117, 0x30, 0x117, 0x04,
buck_vout_ranges, 256, 0, buck1_irq_tbls),
- MT6360_REGULATOR_DESC(BUCK2, BUCK2_VIN, 0x127, 0x40, 0x120, 0xff, 0x127, 0x30, 0x127, 0x04,
+ MT6360_REGULATOR_DESC("buck2", BUCK2, BUCK2_VIN,
+ 0x127, 0x40, 0x120, 0xff, 0x127, 0x30, 0x127, 0x04,
buck_vout_ranges, 256, 0, buck2_irq_tbls),
- MT6360_REGULATOR_DESC(LDO6, LDO_VIN3, 0x137, 0x40, 0x13B, 0xff, 0x137, 0x30, 0x137, 0x04,
+ MT6360_REGULATOR_DESC("ldo6", LDO6, LDO_VIN3,
+ 0x137, 0x40, 0x13B, 0xff, 0x137, 0x30, 0x137, 0x04,
ldo_vout_ranges1, 256, 0, ldo6_irq_tbls),
- MT6360_REGULATOR_DESC(LDO7, LDO_VIN3, 0x131, 0x40, 0x135, 0xff, 0x131, 0x30, 0x131, 0x04,
+ MT6360_REGULATOR_DESC("ldo7", LDO7, LDO_VIN3,
+ 0x131, 0x40, 0x135, 0xff, 0x131, 0x30, 0x131, 0x04,
ldo_vout_ranges1, 256, 0, ldo7_irq_tbls),
- MT6360_REGULATOR_DESC(LDO1, LDO_VIN1, 0x217, 0x40, 0x21B, 0xff, 0x217, 0x30, 0x217, 0x04,
+ MT6360_REGULATOR_DESC("ldo1", LDO1, LDO_VIN1,
+ 0x217, 0x40, 0x21B, 0xff, 0x217, 0x30, 0x217, 0x04,
ldo_vout_ranges2, 256, 0, ldo1_irq_tbls),
- MT6360_REGULATOR_DESC(LDO2, LDO_VIN1, 0x211, 0x40, 0x215, 0xff, 0x211, 0x30, 0x211, 0x04,
+ MT6360_REGULATOR_DESC("ldo2", LDO2, LDO_VIN1,
+ 0x211, 0x40, 0x215, 0xff, 0x211, 0x30, 0x211, 0x04,
ldo_vout_ranges2, 256, 0, ldo2_irq_tbls),
- MT6360_REGULATOR_DESC(LDO3, LDO_VIN1, 0x205, 0x40, 0x209, 0xff, 0x205, 0x30, 0x205, 0x04,
+ MT6360_REGULATOR_DESC("ldo3", LDO3, LDO_VIN1,
+ 0x205, 0x40, 0x209, 0xff, 0x205, 0x30, 0x205, 0x04,
ldo_vout_ranges2, 256, 100, ldo3_irq_tbls),
- MT6360_REGULATOR_DESC(LDO5, LDO_VIN2, 0x20B, 0x40, 0x20F, 0x7f, 0x20B, 0x30, 0x20B, 0x04,
+ MT6360_REGULATOR_DESC("ldo5", LDO5, LDO_VIN2,
+ 0x20B, 0x40, 0x20F, 0x7f, 0x20B, 0x30, 0x20B, 0x04,
ldo_vout_ranges3, 128, 100, ldo5_irq_tbls),
};
diff --git a/drivers/regulator/pca9450-regulator.c b/drivers/regulator/pca9450-regulator.c
index 2ab365d2749f..be488c5dff14 100644
--- a/drivers/regulator/pca9450-regulator.c
+++ b/drivers/regulator/pca9450-regulator.c
@@ -53,7 +53,7 @@ static const struct regmap_config pca9450_regmap_config = {
.val_bits = 8,
.volatile_table = &pca9450_volatile_regs,
.max_register = PCA9450_MAX_REGISTER - 1,
- .cache_type = REGCACHE_RBTREE,
+ .cache_type = REGCACHE_MAPLE,
};
/*
@@ -107,6 +107,14 @@ static const struct linear_range pca9450_dvs_buck_volts[] = {
};
/*
+ * BUCK1/3
+ * 0.65 to 2.2375V (12.5mV step)
+ */
+static const struct linear_range pca9451a_dvs_buck_volts[] = {
+ REGULATOR_LINEAR_RANGE(650000, 0x00, 0x7F, 12500),
+};
+
+/*
* BUCK4/5/6
* 0.6V to 3.4V (25mV step)
*/
@@ -662,6 +670,178 @@ static const struct pca9450_regulator_desc pca9450bc_regulators[] = {
},
};
+static const struct pca9450_regulator_desc pca9451a_regulators[] = {
+ {
+ .desc = {
+ .name = "buck1",
+ .of_match = of_match_ptr("BUCK1"),
+ .regulators_node = of_match_ptr("regulators"),
+ .id = PCA9450_BUCK1,
+ .ops = &pca9450_dvs_buck_regulator_ops,
+ .type = REGULATOR_VOLTAGE,
+ .n_voltages = PCA9450_BUCK1_VOLTAGE_NUM,
+ .linear_ranges = pca9451a_dvs_buck_volts,
+ .n_linear_ranges = ARRAY_SIZE(pca9451a_dvs_buck_volts),
+ .vsel_reg = PCA9450_REG_BUCK1OUT_DVS0,
+ .vsel_mask = BUCK1OUT_DVS0_MASK,
+ .enable_reg = PCA9450_REG_BUCK1CTRL,
+ .enable_mask = BUCK1_ENMODE_MASK,
+ .enable_val = BUCK_ENMODE_ONREQ,
+ .ramp_mask = BUCK1_RAMP_MASK,
+ .ramp_delay_table = pca9450_dvs_buck_ramp_table,
+ .n_ramp_values = ARRAY_SIZE(pca9450_dvs_buck_ramp_table),
+ .owner = THIS_MODULE,
+ .of_parse_cb = pca9450_set_dvs_levels,
+ },
+ .dvs = {
+ .run_reg = PCA9450_REG_BUCK1OUT_DVS0,
+ .run_mask = BUCK1OUT_DVS0_MASK,
+ .standby_reg = PCA9450_REG_BUCK1OUT_DVS1,
+ .standby_mask = BUCK1OUT_DVS1_MASK,
+ },
+ },
+ {
+ .desc = {
+ .name = "buck2",
+ .of_match = of_match_ptr("BUCK2"),
+ .regulators_node = of_match_ptr("regulators"),
+ .id = PCA9450_BUCK2,
+ .ops = &pca9450_dvs_buck_regulator_ops,
+ .type = REGULATOR_VOLTAGE,
+ .n_voltages = PCA9450_BUCK2_VOLTAGE_NUM,
+ .linear_ranges = pca9450_dvs_buck_volts,
+ .n_linear_ranges = ARRAY_SIZE(pca9450_dvs_buck_volts),
+ .vsel_reg = PCA9450_REG_BUCK2OUT_DVS0,
+ .vsel_mask = BUCK2OUT_DVS0_MASK,
+ .enable_reg = PCA9450_REG_BUCK2CTRL,
+ .enable_mask = BUCK2_ENMODE_MASK,
+ .enable_val = BUCK_ENMODE_ONREQ_STBYREQ,
+ .ramp_mask = BUCK2_RAMP_MASK,
+ .ramp_delay_table = pca9450_dvs_buck_ramp_table,
+ .n_ramp_values = ARRAY_SIZE(pca9450_dvs_buck_ramp_table),
+ .owner = THIS_MODULE,
+ .of_parse_cb = pca9450_set_dvs_levels,
+ },
+ .dvs = {
+ .run_reg = PCA9450_REG_BUCK2OUT_DVS0,
+ .run_mask = BUCK2OUT_DVS0_MASK,
+ .standby_reg = PCA9450_REG_BUCK2OUT_DVS1,
+ .standby_mask = BUCK2OUT_DVS1_MASK,
+ },
+ },
+ {
+ .desc = {
+ .name = "buck4",
+ .of_match = of_match_ptr("BUCK4"),
+ .regulators_node = of_match_ptr("regulators"),
+ .id = PCA9450_BUCK4,
+ .ops = &pca9450_buck_regulator_ops,
+ .type = REGULATOR_VOLTAGE,
+ .n_voltages = PCA9450_BUCK4_VOLTAGE_NUM,
+ .linear_ranges = pca9450_buck_volts,
+ .n_linear_ranges = ARRAY_SIZE(pca9450_buck_volts),
+ .vsel_reg = PCA9450_REG_BUCK4OUT,
+ .vsel_mask = BUCK4OUT_MASK,
+ .enable_reg = PCA9450_REG_BUCK4CTRL,
+ .enable_mask = BUCK4_ENMODE_MASK,
+ .enable_val = BUCK_ENMODE_ONREQ,
+ .owner = THIS_MODULE,
+ },
+ },
+ {
+ .desc = {
+ .name = "buck5",
+ .of_match = of_match_ptr("BUCK5"),
+ .regulators_node = of_match_ptr("regulators"),
+ .id = PCA9450_BUCK5,
+ .ops = &pca9450_buck_regulator_ops,
+ .type = REGULATOR_VOLTAGE,
+ .n_voltages = PCA9450_BUCK5_VOLTAGE_NUM,
+ .linear_ranges = pca9450_buck_volts,
+ .n_linear_ranges = ARRAY_SIZE(pca9450_buck_volts),
+ .vsel_reg = PCA9450_REG_BUCK5OUT,
+ .vsel_mask = BUCK5OUT_MASK,
+ .enable_reg = PCA9450_REG_BUCK5CTRL,
+ .enable_mask = BUCK5_ENMODE_MASK,
+ .enable_val = BUCK_ENMODE_ONREQ,
+ .owner = THIS_MODULE,
+ },
+ },
+ {
+ .desc = {
+ .name = "buck6",
+ .of_match = of_match_ptr("BUCK6"),
+ .regulators_node = of_match_ptr("regulators"),
+ .id = PCA9450_BUCK6,
+ .ops = &pca9450_buck_regulator_ops,
+ .type = REGULATOR_VOLTAGE,
+ .n_voltages = PCA9450_BUCK6_VOLTAGE_NUM,
+ .linear_ranges = pca9450_buck_volts,
+ .n_linear_ranges = ARRAY_SIZE(pca9450_buck_volts),
+ .vsel_reg = PCA9450_REG_BUCK6OUT,
+ .vsel_mask = BUCK6OUT_MASK,
+ .enable_reg = PCA9450_REG_BUCK6CTRL,
+ .enable_mask = BUCK6_ENMODE_MASK,
+ .enable_val = BUCK_ENMODE_ONREQ,
+ .owner = THIS_MODULE,
+ },
+ },
+ {
+ .desc = {
+ .name = "ldo1",
+ .of_match = of_match_ptr("LDO1"),
+ .regulators_node = of_match_ptr("regulators"),
+ .id = PCA9450_LDO1,
+ .ops = &pca9450_ldo_regulator_ops,
+ .type = REGULATOR_VOLTAGE,
+ .n_voltages = PCA9450_LDO1_VOLTAGE_NUM,
+ .linear_ranges = pca9450_ldo1_volts,
+ .n_linear_ranges = ARRAY_SIZE(pca9450_ldo1_volts),
+ .vsel_reg = PCA9450_REG_LDO1CTRL,
+ .vsel_mask = LDO1OUT_MASK,
+ .enable_reg = PCA9450_REG_LDO1CTRL,
+ .enable_mask = LDO1_EN_MASK,
+ .owner = THIS_MODULE,
+ },
+ },
+ {
+ .desc = {
+ .name = "ldo4",
+ .of_match = of_match_ptr("LDO4"),
+ .regulators_node = of_match_ptr("regulators"),
+ .id = PCA9450_LDO4,
+ .ops = &pca9450_ldo_regulator_ops,
+ .type = REGULATOR_VOLTAGE,
+ .n_voltages = PCA9450_LDO4_VOLTAGE_NUM,
+ .linear_ranges = pca9450_ldo34_volts,
+ .n_linear_ranges = ARRAY_SIZE(pca9450_ldo34_volts),
+ .vsel_reg = PCA9450_REG_LDO4CTRL,
+ .vsel_mask = LDO4OUT_MASK,
+ .enable_reg = PCA9450_REG_LDO4CTRL,
+ .enable_mask = LDO4_EN_MASK,
+ .owner = THIS_MODULE,
+ },
+ },
+ {
+ .desc = {
+ .name = "ldo5",
+ .of_match = of_match_ptr("LDO5"),
+ .regulators_node = of_match_ptr("regulators"),
+ .id = PCA9450_LDO5,
+ .ops = &pca9450_ldo_regulator_ops,
+ .type = REGULATOR_VOLTAGE,
+ .n_voltages = PCA9450_LDO5_VOLTAGE_NUM,
+ .linear_ranges = pca9450_ldo5_volts,
+ .n_linear_ranges = ARRAY_SIZE(pca9450_ldo5_volts),
+ .vsel_reg = PCA9450_REG_LDO5CTRL_H,
+ .vsel_mask = LDO5HOUT_MASK,
+ .enable_reg = PCA9450_REG_LDO5CTRL_H,
+ .enable_mask = LDO5H_EN_MASK,
+ .owner = THIS_MODULE,
+ },
+ },
+};
+
static irqreturn_t pca9450_irq_handler(int irq, void *data)
{
struct pca9450 *pca9450 = data;
@@ -729,6 +909,10 @@ static int pca9450_i2c_probe(struct i2c_client *i2c)
regulator_desc = pca9450bc_regulators;
pca9450->rcnt = ARRAY_SIZE(pca9450bc_regulators);
break;
+ case PCA9450_TYPE_PCA9451A:
+ regulator_desc = pca9451a_regulators;
+ pca9450->rcnt = ARRAY_SIZE(pca9451a_regulators);
+ break;
default:
dev_err(&i2c->dev, "Unknown device type");
return -EINVAL;
@@ -755,7 +939,8 @@ static int pca9450_i2c_probe(struct i2c_client *i2c)
/* Check your board and dts for match the right pmic */
if (((device_id >> 4) != 0x1 && type == PCA9450_TYPE_PCA9450A) ||
- ((device_id >> 4) != 0x3 && type == PCA9450_TYPE_PCA9450BC)) {
+ ((device_id >> 4) != 0x3 && type == PCA9450_TYPE_PCA9450BC) ||
+ ((device_id >> 4) != 0x9 && type == PCA9450_TYPE_PCA9451A)) {
dev_err(&i2c->dev, "Device id(%x) mismatched\n",
device_id >> 4);
return -EINVAL;
@@ -846,7 +1031,8 @@ static int pca9450_i2c_probe(struct i2c_client *i2c)
}
dev_info(&i2c->dev, "%s probed.\n",
- type == PCA9450_TYPE_PCA9450A ? "pca9450a" : "pca9450bc");
+ type == PCA9450_TYPE_PCA9450A ? "pca9450a" :
+ (type == PCA9450_TYPE_PCA9451A ? "pca9451a" : "pca9450bc"));
return 0;
}
@@ -864,6 +1050,10 @@ static const struct of_device_id pca9450_of_match[] = {
.compatible = "nxp,pca9450c",
.data = (void *)PCA9450_TYPE_PCA9450BC,
},
+ {
+ .compatible = "nxp,pca9451a",
+ .data = (void *)PCA9450_TYPE_PCA9451A,
+ },
{ }
};
MODULE_DEVICE_TABLE(of, pca9450_of_match);
diff --git a/drivers/regulator/pf8x00-regulator.c b/drivers/regulator/pf8x00-regulator.c
index b0781d9a1058..9fd8e0949b32 100644
--- a/drivers/regulator/pf8x00-regulator.c
+++ b/drivers/regulator/pf8x00-regulator.c
@@ -142,7 +142,7 @@ static const struct regmap_config pf8x00_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
.max_register = PF8X00_PAGE_SELECT,
- .cache_type = REGCACHE_RBTREE,
+ .cache_type = REGCACHE_MAPLE,
};
/* VLDOx output: 1.5V to 5.0V */
diff --git a/drivers/regulator/pfuze100-regulator.c b/drivers/regulator/pfuze100-regulator.c
index 46854602b3ea..7c04870442d3 100644
--- a/drivers/regulator/pfuze100-regulator.c
+++ b/drivers/regulator/pfuze100-regulator.c
@@ -680,7 +680,7 @@ static const struct regmap_config pfuze_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
.max_register = PFUZE_NUMREGS - 1,
- .cache_type = REGCACHE_RBTREE,
+ .cache_type = REGCACHE_MAPLE,
};
static int pfuze100_regulator_probe(struct i2c_client *client)
diff --git a/drivers/regulator/qcom-refgen-regulator.c b/drivers/regulator/qcom-refgen-regulator.c
index 656fe330d38f..063e12c08e75 100644
--- a/drivers/regulator/qcom-refgen-regulator.c
+++ b/drivers/regulator/qcom-refgen-regulator.c
@@ -140,6 +140,7 @@ static const struct of_device_id qcom_refgen_match_table[] = {
{ .compatible = "qcom,sm8250-refgen-regulator", .data = &sm8250_refgen_desc },
{ }
};
+MODULE_DEVICE_TABLE(of, qcom_refgen_match_table);
static struct platform_driver qcom_refgen_driver = {
.probe = qcom_refgen_probe,
diff --git a/drivers/regulator/rk808-regulator.c b/drivers/regulator/rk808-regulator.c
index d89ae7f16d7a..14b60abd6afc 100644
--- a/drivers/regulator/rk808-regulator.c
+++ b/drivers/regulator/rk808-regulator.c
@@ -158,6 +158,11 @@
RK8XX_DESC_COM(_id, _match, _supply, _min, _max, _step, _vreg, \
_vmask, _ereg, _emask, 0, 0, _etime, &rk808_reg_ops)
+#define RK816_DESC(_id, _match, _supply, _min, _max, _step, _vreg, \
+ _vmask, _ereg, _emask, _disval, _etime) \
+ RK8XX_DESC_COM(_id, _match, _supply, _min, _max, _step, _vreg, \
+ _vmask, _ereg, _emask, _emask, _disval, _etime, &rk816_reg_ops)
+
#define RK817_DESC(_id, _match, _supply, _min, _max, _step, _vreg, \
_vmask, _ereg, _emask, _disval, _etime) \
RK8XX_DESC_COM(_id, _match, _supply, _min, _max, _step, _vreg, \
@@ -258,7 +263,7 @@ static const unsigned int rk808_buck1_2_ramp_table[] = {
2000, 4000, 6000, 10000
};
-/* RK817 RK809 */
+/* RK817/RK809/RK816 (buck 1/2 only) */
static const unsigned int rk817_buck1_4_ramp_table[] = {
3000, 6300, 12500, 25000
};
@@ -534,15 +539,25 @@ static int rk808_set_suspend_voltage_range(struct regulator_dev *rdev, int uv)
{
unsigned int reg;
int sel = regulator_map_voltage_linear_range(rdev, uv, uv);
+ int ret;
if (sel < 0)
return -EINVAL;
reg = rdev->desc->vsel_reg + RK808_SLP_REG_OFFSET;
- return regmap_update_bits(rdev->regmap, reg,
- rdev->desc->vsel_mask,
- sel);
+ ret = regmap_update_bits(rdev->regmap, reg,
+ rdev->desc->vsel_mask,
+ sel);
+ if (ret)
+ return ret;
+
+ if (rdev->desc->apply_bit)
+ ret = regmap_update_bits(rdev->regmap, rdev->desc->apply_reg,
+ rdev->desc->apply_bit,
+ rdev->desc->apply_bit);
+
+ return ret;
}
static int rk805_set_suspend_enable(struct regulator_dev *rdev)
@@ -630,6 +645,38 @@ static int rk808_set_suspend_disable(struct regulator_dev *rdev)
rdev->desc->enable_mask);
}
+static const struct rk8xx_register_bit rk816_suspend_bits[] = {
+ RK8XX_REG_BIT(RK818_SLEEP_SET_OFF_REG1, 0),
+ RK8XX_REG_BIT(RK818_SLEEP_SET_OFF_REG1, 1),
+ RK8XX_REG_BIT(RK818_SLEEP_SET_OFF_REG1, 2),
+ RK8XX_REG_BIT(RK818_SLEEP_SET_OFF_REG1, 3),
+ RK8XX_REG_BIT(RK818_SLEEP_SET_OFF_REG2, 0),
+ RK8XX_REG_BIT(RK818_SLEEP_SET_OFF_REG2, 1),
+ RK8XX_REG_BIT(RK818_SLEEP_SET_OFF_REG2, 2),
+ RK8XX_REG_BIT(RK818_SLEEP_SET_OFF_REG2, 3),
+ RK8XX_REG_BIT(RK818_SLEEP_SET_OFF_REG2, 4),
+ RK8XX_REG_BIT(RK818_SLEEP_SET_OFF_REG2, 5),
+ RK8XX_REG_BIT(RK818_SLEEP_SET_OFF_REG1, 5),
+ RK8XX_REG_BIT(RK818_SLEEP_SET_OFF_REG1, 6),
+};
+
+static int rk816_set_suspend_enable(struct regulator_dev *rdev)
+{
+ int rid = rdev_get_id(rdev);
+
+ return regmap_update_bits(rdev->regmap, rk816_suspend_bits[rid].reg,
+ rk816_suspend_bits[rid].bit,
+ rk816_suspend_bits[rid].bit);
+}
+
+static int rk816_set_suspend_disable(struct regulator_dev *rdev)
+{
+ int rid = rdev_get_id(rdev);
+
+ return regmap_update_bits(rdev->regmap, rk816_suspend_bits[rid].reg,
+ rk816_suspend_bits[rid].bit, 0);
+}
+
static int rk817_set_suspend_enable_ctrl(struct regulator_dev *rdev,
unsigned int en)
{
@@ -903,6 +950,54 @@ static const struct regulator_ops rk809_buck5_ops_range = {
.set_suspend_disable = rk817_set_suspend_disable,
};
+static const struct regulator_ops rk816_buck1_2_ops_ranges = {
+ .list_voltage = regulator_list_voltage_linear_range,
+ .map_voltage = regulator_map_voltage_linear_range,
+ .get_voltage_sel = regulator_get_voltage_sel_regmap,
+ .set_voltage_sel = regulator_set_voltage_sel_regmap,
+ .set_voltage_time_sel = regulator_set_voltage_time_sel,
+ .enable = regulator_enable_regmap,
+ .disable = regulator_disable_regmap,
+ .is_enabled = regulator_is_enabled_regmap,
+ .set_mode = rk8xx_set_mode,
+ .get_mode = rk8xx_get_mode,
+ .set_suspend_mode = rk8xx_set_suspend_mode,
+ .set_ramp_delay = regulator_set_ramp_delay_regmap,
+ .set_suspend_voltage = rk808_set_suspend_voltage_range,
+ .set_suspend_enable = rk816_set_suspend_enable,
+ .set_suspend_disable = rk816_set_suspend_disable,
+};
+
+static const struct regulator_ops rk816_buck4_ops_ranges = {
+ .list_voltage = regulator_list_voltage_linear_range,
+ .map_voltage = regulator_map_voltage_linear_range,
+ .get_voltage_sel = regulator_get_voltage_sel_regmap,
+ .set_voltage_sel = regulator_set_voltage_sel_regmap,
+ .set_voltage_time_sel = regulator_set_voltage_time_sel,
+ .enable = regulator_enable_regmap,
+ .disable = regulator_disable_regmap,
+ .is_enabled = regulator_is_enabled_regmap,
+ .set_mode = rk8xx_set_mode,
+ .get_mode = rk8xx_get_mode,
+ .set_suspend_mode = rk8xx_set_suspend_mode,
+ .set_suspend_voltage = rk808_set_suspend_voltage_range,
+ .set_suspend_enable = rk816_set_suspend_enable,
+ .set_suspend_disable = rk816_set_suspend_disable,
+};
+
+static const struct regulator_ops rk816_reg_ops = {
+ .list_voltage = regulator_list_voltage_linear,
+ .map_voltage = regulator_map_voltage_linear,
+ .get_voltage_sel = regulator_get_voltage_sel_regmap,
+ .set_voltage_sel = regulator_set_voltage_sel_regmap,
+ .enable = regulator_enable_regmap,
+ .disable = regulator_disable_regmap,
+ .is_enabled = rk8xx_is_enabled_wmsk_regmap,
+ .set_suspend_voltage = rk808_set_suspend_voltage,
+ .set_suspend_enable = rk816_set_suspend_enable,
+ .set_suspend_disable = rk816_set_suspend_disable,
+};
+
static const struct regulator_ops rk817_reg_ops = {
.list_voltage = regulator_list_voltage_linear,
.map_voltage = regulator_map_voltage_linear,
@@ -1382,6 +1477,117 @@ static const struct regulator_desc rk809_reg[] = {
DISABLE_VAL(3)),
};
+static const struct linear_range rk816_buck_4_voltage_ranges[] = {
+ REGULATOR_LINEAR_RANGE(800000, 0, 26, 100000),
+ REGULATOR_LINEAR_RANGE(3500000, 27, 31, 0),
+};
+
+static const struct regulator_desc rk816_reg[] = {
+ {
+ .name = "dcdc1",
+ .supply_name = "vcc1",
+ .of_match = of_match_ptr("dcdc1"),
+ .regulators_node = of_match_ptr("regulators"),
+ .id = RK816_ID_DCDC1,
+ .ops = &rk816_buck1_2_ops_ranges,
+ .type = REGULATOR_VOLTAGE,
+ .n_voltages = 64,
+ .linear_ranges = rk805_buck_1_2_voltage_ranges,
+ .n_linear_ranges = ARRAY_SIZE(rk805_buck_1_2_voltage_ranges),
+ .vsel_reg = RK818_BUCK1_ON_VSEL_REG,
+ .vsel_mask = RK818_BUCK_VSEL_MASK,
+ .apply_reg = RK816_DCDC_EN_REG2,
+ .apply_bit = RK816_BUCK_DVS_CONFIRM,
+ .enable_reg = RK816_DCDC_EN_REG1,
+ .enable_mask = BIT(4) | BIT(0),
+ .enable_val = BIT(4) | BIT(0),
+ .disable_val = BIT(4),
+ .ramp_reg = RK818_BUCK1_CONFIG_REG,
+ .ramp_mask = RK808_RAMP_RATE_MASK,
+ .ramp_delay_table = rk817_buck1_4_ramp_table,
+ .n_ramp_values = ARRAY_SIZE(rk817_buck1_4_ramp_table),
+ .of_map_mode = rk8xx_regulator_of_map_mode,
+ .owner = THIS_MODULE,
+ }, {
+ .name = "dcdc2",
+ .supply_name = "vcc2",
+ .of_match = of_match_ptr("dcdc2"),
+ .regulators_node = of_match_ptr("regulators"),
+ .id = RK816_ID_DCDC2,
+ .ops = &rk816_buck1_2_ops_ranges,
+ .type = REGULATOR_VOLTAGE,
+ .n_voltages = 64,
+ .linear_ranges = rk805_buck_1_2_voltage_ranges,
+ .n_linear_ranges = ARRAY_SIZE(rk805_buck_1_2_voltage_ranges),
+ .vsel_reg = RK818_BUCK2_ON_VSEL_REG,
+ .vsel_mask = RK818_BUCK_VSEL_MASK,
+ .apply_reg = RK816_DCDC_EN_REG2,
+ .apply_bit = RK816_BUCK_DVS_CONFIRM,
+ .enable_reg = RK816_DCDC_EN_REG1,
+ .enable_mask = BIT(5) | BIT(1),
+ .enable_val = BIT(5) | BIT(1),
+ .disable_val = BIT(5),
+ .ramp_reg = RK818_BUCK2_CONFIG_REG,
+ .ramp_mask = RK808_RAMP_RATE_MASK,
+ .ramp_delay_table = rk817_buck1_4_ramp_table,
+ .n_ramp_values = ARRAY_SIZE(rk817_buck1_4_ramp_table),
+ .of_map_mode = rk8xx_regulator_of_map_mode,
+ .owner = THIS_MODULE,
+ }, {
+ .name = "dcdc3",
+ .supply_name = "vcc3",
+ .of_match = of_match_ptr("dcdc3"),
+ .regulators_node = of_match_ptr("regulators"),
+ .id = RK816_ID_DCDC3,
+ .ops = &rk808_switch_ops,
+ .type = REGULATOR_VOLTAGE,
+ .n_voltages = 1,
+ .enable_reg = RK816_DCDC_EN_REG1,
+ .enable_mask = BIT(6) | BIT(2),
+ .enable_val = BIT(6) | BIT(2),
+ .disable_val = BIT(6),
+ .of_map_mode = rk8xx_regulator_of_map_mode,
+ .owner = THIS_MODULE,
+ }, {
+ .name = "dcdc4",
+ .supply_name = "vcc4",
+ .of_match = of_match_ptr("dcdc4"),
+ .regulators_node = of_match_ptr("regulators"),
+ .id = RK816_ID_DCDC4,
+ .ops = &rk816_buck4_ops_ranges,
+ .type = REGULATOR_VOLTAGE,
+ .n_voltages = 32,
+ .linear_ranges = rk816_buck_4_voltage_ranges,
+ .n_linear_ranges = ARRAY_SIZE(rk816_buck_4_voltage_ranges),
+ .vsel_reg = RK818_BUCK4_ON_VSEL_REG,
+ .vsel_mask = RK818_BUCK4_VSEL_MASK,
+ .enable_reg = RK816_DCDC_EN_REG1,
+ .enable_mask = BIT(7) | BIT(3),
+ .enable_val = BIT(7) | BIT(3),
+ .disable_val = BIT(7),
+ .of_map_mode = rk8xx_regulator_of_map_mode,
+ .owner = THIS_MODULE,
+ },
+ RK816_DESC(RK816_ID_LDO1, "ldo1", "vcc5", 800, 3400, 100,
+ RK818_LDO1_ON_VSEL_REG, RK818_LDO_VSEL_MASK,
+ RK816_LDO_EN_REG1, ENABLE_MASK(0), DISABLE_VAL(0), 400),
+ RK816_DESC(RK816_ID_LDO2, "ldo2", "vcc5", 800, 3400, 100,
+ RK818_LDO2_ON_VSEL_REG, RK818_LDO_VSEL_MASK,
+ RK816_LDO_EN_REG1, ENABLE_MASK(1), DISABLE_VAL(1), 400),
+ RK816_DESC(RK816_ID_LDO3, "ldo3", "vcc5", 800, 3400, 100,
+ RK818_LDO3_ON_VSEL_REG, RK818_LDO_VSEL_MASK,
+ RK816_LDO_EN_REG1, ENABLE_MASK(2), DISABLE_VAL(2), 400),
+ RK816_DESC(RK816_ID_LDO4, "ldo4", "vcc6", 800, 3400, 100,
+ RK818_LDO4_ON_VSEL_REG, RK818_LDO_VSEL_MASK,
+ RK816_LDO_EN_REG1, ENABLE_MASK(3), DISABLE_VAL(3), 400),
+ RK816_DESC(RK816_ID_LDO5, "ldo5", "vcc6", 800, 3400, 100,
+ RK818_LDO5_ON_VSEL_REG, RK818_LDO_VSEL_MASK,
+ RK816_LDO_EN_REG2, ENABLE_MASK(0), DISABLE_VAL(0), 400),
+ RK816_DESC(RK816_ID_LDO6, "ldo6", "vcc6", 800, 3400, 100,
+ RK818_LDO6_ON_VSEL_REG, RK818_LDO_VSEL_MASK,
+ RK816_LDO_EN_REG2, ENABLE_MASK(1), DISABLE_VAL(1), 400),
+};
+
static const struct regulator_desc rk817_reg[] = {
{
.name = "DCDC_REG1",
@@ -1704,6 +1910,10 @@ static int rk808_regulator_probe(struct platform_device *pdev)
regulators = rk809_reg;
nregulators = RK809_NUM_REGULATORS;
break;
+ case RK816_ID:
+ regulators = rk816_reg;
+ nregulators = ARRAY_SIZE(rk816_reg);
+ break;
case RK817_ID:
regulators = rk817_reg;
nregulators = RK817_NUM_REGULATORS;
diff --git a/drivers/regulator/rohm-regulator.c b/drivers/regulator/rohm-regulator.c
index 0e2418ed957c..4b95ca01959c 100644
--- a/drivers/regulator/rohm-regulator.c
+++ b/drivers/regulator/rohm-regulator.c
@@ -46,6 +46,7 @@ static int set_dvs_level(const struct regulator_desc *desc,
continue;
if (ret == uv) {
i <<= ffs(desc->vsel_mask) - 1;
+
ret = regmap_update_bits(regmap, reg, mask, i);
if (omask && !ret)
ret = regmap_update_bits(regmap, oreg, omask,
@@ -53,6 +54,9 @@ static int set_dvs_level(const struct regulator_desc *desc,
break;
}
}
+ if (i == desc->n_voltages)
+ pr_warn("Unsupported %s voltage %u\n", prop, uv);
+
return ret;
}
diff --git a/drivers/regulator/rpi-panel-attiny-regulator.c b/drivers/regulator/rpi-panel-attiny-regulator.c
index f52c3d47ecea..6c3b6bfac961 100644
--- a/drivers/regulator/rpi-panel-attiny-regulator.c
+++ b/drivers/regulator/rpi-panel-attiny-regulator.c
@@ -75,7 +75,7 @@ static const struct regmap_config attiny_regmap_config = {
.val_bits = 8,
.disable_locking = 1,
.max_register = REG_WRITE_DATA_L,
- .cache_type = REGCACHE_RBTREE,
+ .cache_type = REGCACHE_MAPLE,
};
static int attiny_set_port_state(struct attiny_lcd *state, int reg, u8 val)
diff --git a/drivers/regulator/rtmv20-regulator.c b/drivers/regulator/rtmv20-regulator.c
index dfd1522637e4..3d8d29f87b58 100644
--- a/drivers/regulator/rtmv20-regulator.c
+++ b/drivers/regulator/rtmv20-regulator.c
@@ -312,7 +312,7 @@ static bool rtmv20_is_volatile_reg(struct device *dev, unsigned int reg)
static const struct regmap_config rtmv20_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
- .cache_type = REGCACHE_RBTREE,
+ .cache_type = REGCACHE_MAPLE,
.max_register = RTMV20_REG_LDMASK,
.num_reg_defaults_raw = RTMV20_MAX_REGS,
diff --git a/drivers/regulator/rtq2208-regulator.c b/drivers/regulator/rtq2208-regulator.c
index 2d54844c4226..c31b6dc3229c 100644
--- a/drivers/regulator/rtq2208-regulator.c
+++ b/drivers/regulator/rtq2208-regulator.c
@@ -26,6 +26,7 @@
#define RTQ2208_REG_BUCK_H_CFG0 0xA2
#define RTQ2208_REG_LDO1_CFG 0xB1
#define RTQ2208_REG_LDO2_CFG 0xC1
+#define RTQ2208_REG_LDO_DVS_CTRL 0xD0
/* Mask */
#define RTQ2208_BUCK_NR_MTP_SEL_MASK GENMASK(7, 0)
@@ -40,6 +41,10 @@
#define RTQ2208_EN_DIS_MASK BIT(0)
#define RTQ2208_BUCK_RAMP_SEL_MASK GENMASK(2, 0)
#define RTQ2208_HD_INT_MASK BIT(0)
+#define RTQ2208_LDO1_DISCHG_EN_MASK BIT(4)
+#define RTQ2208_LDO1_VOSEL_SD_MASK BIT(5)
+#define RTQ2208_LDO2_DISCHG_EN_MASK BIT(6)
+#define RTQ2208_LDO2_VOSEL_SD_MASK BIT(7)
/* Size */
#define RTQ2208_VOUT_MAXNUM 256
@@ -48,7 +53,7 @@
/* Value */
#define RTQ2208_RAMP_VALUE_MIN_uV 500
-#define RTQ2208_RAMP_VALUE_MAX_uV 64000
+#define RTQ2208_RAMP_VALUE_MAX_uV 16000
#define RTQ2208_BUCK_MASK(uv_irq, ov_irq) (1 << ((uv_irq) % 8) | 1 << ((ov_irq) % 8))
@@ -142,12 +147,11 @@ static int rtq2208_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay)
* Because the relation of seleltion and value is like that
*
* seletion: value
- * 000: 64mv
- * 001: 32mv
+ * 010: 16mv
* ...
* 111: 0.5mv
*
- * For example, if I would like to select 64mv, the fls(ramp_delay) - 1 will be 0b111,
+ * For example, if I would like to select 16mv, the fls(ramp_delay) - 1 will be 0b010,
* and I need to use 0b111 - sel to do the shifting
*/
@@ -224,6 +228,11 @@ static const struct regulator_ops rtq2208_regulator_ldo_ops = {
.set_suspend_disable = rtq2208_set_suspend_disable,
};
+static struct of_regulator_match rtq2208_ldo_match[] = {
+ {.name = "ldo2", },
+ {.name = "ldo1", },
+};
+
static unsigned int rtq2208_of_map_mode(unsigned int mode)
{
switch (mode) {
@@ -318,25 +327,7 @@ static irqreturn_t rtq2208_irq_handler(int irqno, void *devid)
return IRQ_HANDLED;
}
-#define RTQ2208_REGULATOR_INFO(_name, _base) \
-{ \
- .name = #_name, \
- .base = _base, \
-}
-#define BUCK_RG_BASE(_id) RTQ2208_REG_BUCK_##_id##_CFG0
-#define BUCK_RG_SHIFT(_base, _shift) (_base + _shift)
-#define LDO_RG_BASE(_id) RTQ2208_REG_LDO##_id##_CFG
-#define LDO_RG_SHIFT(_base, _shift) (_base + _shift)
-#define VSEL_SHIFT(_sel) (_sel ? 3 : 1)
-#define MTP_SEL_MASK(_sel) RTQ2208_BUCK_EN_NR_MTP_SEL##_sel##_MASK
-
-static const struct linear_range rtq2208_vout_range[] = {
- REGULATOR_LINEAR_RANGE(400000, 0, 180, 5000),
- REGULATOR_LINEAR_RANGE(1310000, 181, 255, 10000),
-};
-
-static int rtq2208_of_get_fixed_voltage(struct device *dev,
- struct of_regulator_match *rtq2208_ldo_match, int n_fixed)
+static int rtq2208_of_get_ldo_dvs_ability(struct device *dev)
{
struct device_node *np;
struct of_regulator_match *match;
@@ -351,14 +342,14 @@ static int rtq2208_of_get_fixed_voltage(struct device *dev,
if (!np)
np = dev->of_node;
- ret = of_regulator_match(dev, np, rtq2208_ldo_match, n_fixed);
+ ret = of_regulator_match(dev, np, rtq2208_ldo_match, ARRAY_SIZE(rtq2208_ldo_match));
of_node_put(np);
if (ret < 0)
return ret;
- for (i = 0; i < n_fixed; i++) {
+ for (i = 0; i < ARRAY_SIZE(rtq2208_ldo_match); i++) {
match = rtq2208_ldo_match + i;
init_data = match->init_data;
rdesc = (struct rtq2208_regulator_desc *)match->driver_data;
@@ -373,24 +364,56 @@ static int rtq2208_of_get_fixed_voltage(struct device *dev,
return 0;
}
-static void rtq2208_init_regulator_desc(struct rtq2208_regulator_desc *rdesc, int mtp_sel,
- int idx, struct of_regulator_match *rtq2208_ldo_match, int *ldo_idx)
+
+#define BUCK_INFO(_name, _id) \
+{ \
+ .name = _name, \
+ .base = RTQ2208_REG_BUCK_##_id##_CFG0, \
+ .enable_reg = BUCK_RG_SHIFT(RTQ2208_REG_BUCK_##_id##_CFG0, 2), \
+ .dis_reg = RTQ2208_REG_BUCK_##_id##_CFG0, \
+}
+
+#define LDO_INFO(_name, _id) \
+{ \
+ .name = _name, \
+ .base = RTQ2208_REG_LDO##_id##_CFG, \
+ .enable_reg = RTQ2208_REG_LDO##_id##_CFG, \
+ .dis_mask = RTQ2208_LDO##_id##_DISCHG_EN_MASK, \
+ .dis_on = RTQ2208_LDO##_id##_DISCHG_EN_MASK, \
+ .vsel_mask = RTQ2208_LDO##_id##_VOSEL_SD_MASK, \
+}
+
+#define BUCK_RG_SHIFT(_base, _shift) (_base + _shift)
+#define VSEL_SHIFT(_sel) (_sel ? 3 : 1)
+#define MTP_SEL_MASK(_sel) RTQ2208_BUCK_EN_NR_MTP_SEL##_sel##_MASK
+
+static const struct linear_range rtq2208_vout_range[] = {
+ REGULATOR_LINEAR_RANGE(400000, 0, 180, 5000),
+ REGULATOR_LINEAR_RANGE(1310000, 181, 255, 10000),
+};
+
+static void rtq2208_init_regulator_desc(struct rtq2208_regulator_desc *rdesc, int mtp_sel, int idx)
{
struct regulator_desc *desc;
static const struct {
char *name;
int base;
+ int enable_reg;
+ int dis_reg;
+ int dis_mask;
+ int dis_on;
+ int vsel_mask;
} regulator_info[] = {
- RTQ2208_REGULATOR_INFO(buck-b, BUCK_RG_BASE(B)),
- RTQ2208_REGULATOR_INFO(buck-c, BUCK_RG_BASE(C)),
- RTQ2208_REGULATOR_INFO(buck-d, BUCK_RG_BASE(D)),
- RTQ2208_REGULATOR_INFO(buck-a, BUCK_RG_BASE(A)),
- RTQ2208_REGULATOR_INFO(buck-f, BUCK_RG_BASE(F)),
- RTQ2208_REGULATOR_INFO(buck-g, BUCK_RG_BASE(G)),
- RTQ2208_REGULATOR_INFO(buck-h, BUCK_RG_BASE(H)),
- RTQ2208_REGULATOR_INFO(buck-e, BUCK_RG_BASE(E)),
- RTQ2208_REGULATOR_INFO(ldo2, LDO_RG_BASE(2)),
- RTQ2208_REGULATOR_INFO(ldo1, LDO_RG_BASE(1)),
+ BUCK_INFO("buck-b", B),
+ BUCK_INFO("buck-c", C),
+ BUCK_INFO("buck-d", D),
+ BUCK_INFO("buck-a", A),
+ BUCK_INFO("buck-f", F),
+ BUCK_INFO("buck-g", G),
+ BUCK_INFO("buck-h", H),
+ BUCK_INFO("buck-e", E),
+ LDO_INFO("ldo2", 2),
+ LDO_INFO("ldo1", 1),
}, *curr_info;
curr_info = regulator_info + idx;
@@ -402,15 +425,13 @@ static void rtq2208_init_regulator_desc(struct rtq2208_regulator_desc *rdesc, in
desc->owner = THIS_MODULE;
desc->type = REGULATOR_VOLTAGE;
desc->enable_mask = mtp_sel ? MTP_SEL_MASK(1) : MTP_SEL_MASK(0);
- desc->active_discharge_on = RTQ2208_EN_DIS_MASK;
+ desc->enable_reg = curr_info->enable_reg;
desc->active_discharge_off = 0;
- desc->active_discharge_mask = RTQ2208_EN_DIS_MASK;
rdesc->mode_mask = RTQ2208_BUCK_NRMODE_MASK;
if (idx >= RTQ2208_BUCK_B && idx <= RTQ2208_BUCK_E) {
/* init buck desc */
- desc->enable_reg = BUCK_RG_SHIFT(curr_info->base, 2);
desc->ops = &rtq2208_regulator_buck_ops;
desc->vsel_reg = curr_info->base + VSEL_SHIFT(mtp_sel);
desc->vsel_mask = RTQ2208_BUCK_NR_MTP_SEL_MASK;
@@ -418,8 +439,10 @@ static void rtq2208_init_regulator_desc(struct rtq2208_regulator_desc *rdesc, in
desc->linear_ranges = rtq2208_vout_range;
desc->n_linear_ranges = ARRAY_SIZE(rtq2208_vout_range);
desc->ramp_reg = BUCK_RG_SHIFT(curr_info->base, 5);
- desc->active_discharge_reg = curr_info->base;
desc->of_map_mode = rtq2208_of_map_mode;
+ desc->active_discharge_reg = curr_info->dis_reg;
+ desc->active_discharge_on = RTQ2208_EN_DIS_MASK;
+ desc->active_discharge_mask = RTQ2208_EN_DIS_MASK;
rdesc->mode_reg = BUCK_RG_SHIFT(curr_info->base, 2);
rdesc->suspend_config_reg = BUCK_RG_SHIFT(curr_info->base, 4);
@@ -427,14 +450,11 @@ static void rtq2208_init_regulator_desc(struct rtq2208_regulator_desc *rdesc, in
rdesc->suspend_mode_mask = RTQ2208_BUCK_STRMODE_MASK;
} else {
/* init ldo desc */
- desc->enable_reg = curr_info->base;
- desc->ops = &rtq2208_regulator_ldo_ops;
- desc->n_voltages = 1;
- desc->active_discharge_reg = LDO_RG_SHIFT(curr_info->base, 2);
-
- rtq2208_ldo_match[*ldo_idx].name = desc->name;
- rtq2208_ldo_match[*ldo_idx].driver_data = rdesc;
- rtq2208_ldo_match[(*ldo_idx)++].desc = desc;
+ desc->active_discharge_reg = RTQ2208_REG_LDO_DVS_CTRL;
+ desc->active_discharge_on = curr_info->dis_on;
+ desc->active_discharge_mask = curr_info->dis_mask;
+ desc->vsel_reg = RTQ2208_REG_LDO_DVS_CTRL;
+ desc->vsel_mask = curr_info->vsel_mask;
rdesc->suspend_config_reg = curr_info->base;
rdesc->suspend_enable_mask = RTQ2208_LDO_EN_STR_MASK;
@@ -444,8 +464,7 @@ static void rtq2208_init_regulator_desc(struct rtq2208_regulator_desc *rdesc, in
static int rtq2208_parse_regulator_dt_data(int n_regulator, const unsigned int *regulator_idx_table,
struct rtq2208_regulator_desc *rdesc[RTQ2208_LDO_MAX], struct device *dev)
{
- struct of_regulator_match rtq2208_ldo_match[2];
- int mtp_sel, ret, i, idx, ldo_idx = 0;
+ int mtp_sel, i, idx, ret;
/* get mtp_sel0 or mtp_sel1 */
mtp_sel = device_property_read_bool(dev, "richtek,mtp-sel-high");
@@ -457,11 +476,15 @@ static int rtq2208_parse_regulator_dt_data(int n_regulator, const unsigned int *
if (!rdesc[i])
return -ENOMEM;
- rtq2208_init_regulator_desc(rdesc[i], mtp_sel, idx, rtq2208_ldo_match, &ldo_idx);
+ rtq2208_init_regulator_desc(rdesc[i], mtp_sel, idx);
+
+ /* init ldo dvs ability */
+ if (idx >= RTQ2208_LDO2)
+ rtq2208_ldo_match[idx - RTQ2208_LDO2].desc = &rdesc[i]->desc;
}
/* init ldo fixed_uV */
- ret = rtq2208_of_get_fixed_voltage(dev, rtq2208_ldo_match, ldo_idx);
+ ret = rtq2208_of_get_ldo_dvs_ability(dev);
if (ret)
return dev_err_probe(dev, ret, "Failed to get ldo fixed_uV\n");
diff --git a/drivers/regulator/rtq6752-regulator.c b/drivers/regulator/rtq6752-regulator.c
index 8176e5ab0683..d35d844eff3b 100644
--- a/drivers/regulator/rtq6752-regulator.c
+++ b/drivers/regulator/rtq6752-regulator.c
@@ -209,7 +209,7 @@ static const struct reg_default rtq6752_reg_defaults[] = {
static const struct regmap_config rtq6752_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
- .cache_type = REGCACHE_RBTREE,
+ .cache_type = REGCACHE_MAPLE,
.max_register = RTQ6752_REG_FAULT,
.reg_defaults = rtq6752_reg_defaults,
.num_reg_defaults = ARRAY_SIZE(rtq6752_reg_defaults),
diff --git a/drivers/regulator/sun20i-regulator.c b/drivers/regulator/sun20i-regulator.c
new file mode 100644
index 000000000000..e09be44859e7
--- /dev/null
+++ b/drivers/regulator/sun20i-regulator.c
@@ -0,0 +1,157 @@
+// SPDX-License-Identifier: GPL-2.0-only
+//
+// Copyright (c) 2021-2022 Samuel Holland <samuel@sholland.org>
+//
+
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/regulator/driver.h>
+
+#define SUN20I_SYS_LDO_CTRL_REG 0x150
+
+struct sun20i_regulator_data {
+ const struct regulator_desc *descs;
+ unsigned int ndescs;
+};
+
+/* regulator_list_voltage_linear() modified for the non-integral uV_step. */
+static int sun20i_d1_system_ldo_list_voltage(struct regulator_dev *rdev,
+ unsigned int selector)
+{
+ const struct regulator_desc *desc = rdev->desc;
+ unsigned int fraction, uV;
+
+ if (selector >= desc->n_voltages)
+ return -EINVAL;
+
+ uV = desc->min_uV + (desc->uV_step * selector);
+ fraction = selector + (desc->min_uV % 4);
+
+ if (uV > 1606667)
+ uV += 6667;
+ else
+ fraction++;
+
+ /* Produce correctly-rounded absolute voltages. */
+ return uV + (fraction / 3);
+}
+
+static const struct regulator_ops sun20i_d1_system_ldo_ops = {
+ .list_voltage = sun20i_d1_system_ldo_list_voltage,
+ .map_voltage = regulator_map_voltage_ascend,
+ .set_voltage_sel = regulator_set_voltage_sel_regmap,
+ .get_voltage_sel = regulator_get_voltage_sel_regmap,
+};
+
+static const struct regulator_desc sun20i_d1_system_ldo_descs[] = {
+ {
+ .name = "ldoa",
+ .supply_name = "ldo-in",
+ .of_match = "ldoa",
+ .ops = &sun20i_d1_system_ldo_ops,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE,
+ .n_voltages = 32,
+ .min_uV = 1593333,
+ .uV_step = 13333, /* repeating */
+ .vsel_reg = SUN20I_SYS_LDO_CTRL_REG,
+ .vsel_mask = GENMASK(7, 0),
+ },
+ {
+ .name = "ldob",
+ .supply_name = "ldo-in",
+ .of_match = "ldob",
+ .ops = &sun20i_d1_system_ldo_ops,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE,
+ .n_voltages = 64,
+ .min_uV = 1166666,
+ .uV_step = 13333, /* repeating */
+ .vsel_reg = SUN20I_SYS_LDO_CTRL_REG,
+ .vsel_mask = GENMASK(15, 8),
+ },
+};
+
+static const struct sun20i_regulator_data sun20i_d1_system_ldos = {
+ .descs = sun20i_d1_system_ldo_descs,
+ .ndescs = ARRAY_SIZE(sun20i_d1_system_ldo_descs),
+};
+
+static struct regmap *sun20i_regulator_get_regmap(struct device *dev)
+{
+ struct regmap *regmap;
+
+ /*
+ * First try the syscon interface. The system control device is not
+ * compatible with "syscon", so fall back to getting the regmap from
+ * its platform device. This is ugly, but required for devicetree
+ * backward compatibility.
+ */
+ regmap = syscon_node_to_regmap(dev->parent->of_node);
+ if (!IS_ERR(regmap))
+ return regmap;
+
+ regmap = dev_get_regmap(dev->parent, NULL);
+ if (regmap)
+ return regmap;
+
+ return ERR_PTR(-EPROBE_DEFER);
+}
+
+static int sun20i_regulator_probe(struct platform_device *pdev)
+{
+ const struct sun20i_regulator_data *data;
+ struct device *dev = &pdev->dev;
+ struct regulator_config config;
+ struct regmap *regmap;
+
+ data = of_device_get_match_data(dev);
+ if (!data)
+ return -EINVAL;
+
+ regmap = sun20i_regulator_get_regmap(dev);
+ if (IS_ERR(regmap))
+ return dev_err_probe(dev, PTR_ERR(regmap), "Failed to get regmap\n");
+
+ config = (struct regulator_config) {
+ .dev = dev,
+ .regmap = regmap,
+ };
+
+ for (unsigned int i = 0; i < data->ndescs; ++i) {
+ const struct regulator_desc *desc = &data->descs[i];
+ struct regulator_dev *rdev;
+
+ rdev = devm_regulator_register(dev, desc, &config);
+ if (IS_ERR(rdev))
+ return PTR_ERR(rdev);
+ }
+
+ return 0;
+}
+
+static const struct of_device_id sun20i_regulator_of_match[] = {
+ {
+ .compatible = "allwinner,sun20i-d1-system-ldos",
+ .data = &sun20i_d1_system_ldos,
+ },
+ { },
+};
+MODULE_DEVICE_TABLE(of, sun20i_regulator_of_match);
+
+static struct platform_driver sun20i_regulator_driver = {
+ .probe = sun20i_regulator_probe,
+ .driver = {
+ .name = "sun20i-regulator",
+ .of_match_table = sun20i_regulator_of_match,
+ },
+};
+module_platform_driver(sun20i_regulator_driver);
+
+MODULE_AUTHOR("Samuel Holland <samuel@sholland.org>");
+MODULE_DESCRIPTION("Allwinner D1 internal LDO driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/regulator/tps51632-regulator.c b/drivers/regulator/tps51632-regulator.c
index 5199e0437388..3a384bf9d2c5 100644
--- a/drivers/regulator/tps51632-regulator.c
+++ b/drivers/regulator/tps51632-regulator.c
@@ -199,7 +199,7 @@ static const struct regmap_config tps51632_regmap_config = {
.readable_reg = is_read_reg,
.volatile_reg = is_volatile_reg,
.max_register = TPS51632_MAX_REG - 1,
- .cache_type = REGCACHE_RBTREE,
+ .cache_type = REGCACHE_MAPLE,
};
#if defined(CONFIG_OF)
diff --git a/drivers/regulator/tps62360-regulator.c b/drivers/regulator/tps62360-regulator.c
index 32e1a05a57fd..be6a6702cbfa 100644
--- a/drivers/regulator/tps62360-regulator.c
+++ b/drivers/regulator/tps62360-regulator.c
@@ -275,7 +275,7 @@ static const struct regmap_config tps62360_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
.max_register = REG_CHIPID,
- .cache_type = REGCACHE_RBTREE,
+ .cache_type = REGCACHE_MAPLE,
};
static struct tps62360_regulator_platform_data *
diff --git a/drivers/regulator/tps6287x-regulator.c b/drivers/regulator/tps6287x-regulator.c
index 9b7c3d77789e..3c9d79e003e4 100644
--- a/drivers/regulator/tps6287x-regulator.c
+++ b/drivers/regulator/tps6287x-regulator.c
@@ -115,6 +115,7 @@ static struct regulator_desc tps6287x_reg = {
.vsel_mask = 0xFF,
.vsel_range_reg = TPS6287X_CTRL2,
.vsel_range_mask = TPS6287X_CTRL2_VRANGE,
+ .range_applied_by_vsel = true,
.ramp_reg = TPS6287X_CTRL1,
.ramp_mask = TPS6287X_CTRL1_VRAMP,
.ramp_delay_table = tps6287x_ramp_table,
diff --git a/drivers/regulator/tps65132-regulator.c b/drivers/regulator/tps65132-regulator.c
index a06f5f2d7932..9c2f0dd42613 100644
--- a/drivers/regulator/tps65132-regulator.c
+++ b/drivers/regulator/tps65132-regulator.c
@@ -267,10 +267,17 @@ static const struct i2c_device_id tps65132_id[] = {
};
MODULE_DEVICE_TABLE(i2c, tps65132_id);
+static const struct of_device_id __maybe_unused tps65132_of_match[] = {
+ { .compatible = "ti,tps65132" },
+ {},
+};
+MODULE_DEVICE_TABLE(of, tps65132_of_match);
+
static struct i2c_driver tps65132_i2c_driver = {
.driver = {
.name = "tps65132",
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
+ .of_match_table = of_match_ptr(tps65132_of_match),
},
.probe = tps65132_probe,
.id_table = tps65132_id,
diff --git a/drivers/regulator/tps6594-regulator.c b/drivers/regulator/tps6594-regulator.c
index b7f0c8779757..4a859f4c0f83 100644
--- a/drivers/regulator/tps6594-regulator.c
+++ b/drivers/regulator/tps6594-regulator.c
@@ -18,10 +18,13 @@
#include <linux/mfd/tps6594.h>
-#define BUCK_NB 5
-#define LDO_NB 4
-#define MULTI_PHASE_NB 4
-#define REGS_INT_NB 4
+#define BUCK_NB 5
+#define LDO_NB 4
+#define MULTI_PHASE_NB 4
+/* TPS6593 and LP8764 supports OV, UV, SC, ILIM */
+#define REGS_INT_NB 4
+/* TPS65224 supports OV or UV */
+#define TPS65224_REGS_INT_NB 1
enum tps6594_regulator_id {
/* DCDC's */
@@ -66,6 +69,15 @@ static struct tps6594_regulator_irq_type tps6594_ext_regulator_irq_types[] = {
REGULATOR_EVENT_OVER_VOLTAGE_WARN },
};
+static struct tps6594_regulator_irq_type tps65224_ext_regulator_irq_types[] = {
+ { TPS65224_IRQ_NAME_VCCA_UVOV, "VCCA", "voltage out of range",
+ REGULATOR_EVENT_REGULATION_OUT },
+ { TPS65224_IRQ_NAME_VMON1_UVOV, "VMON1", "voltage out of range",
+ REGULATOR_EVENT_REGULATION_OUT },
+ { TPS65224_IRQ_NAME_VMON2_UVOV, "VMON2", "voltage out of range",
+ REGULATOR_EVENT_REGULATION_OUT },
+};
+
struct tps6594_regulator_irq_data {
struct device *dev;
struct tps6594_regulator_irq_type *type;
@@ -122,6 +134,27 @@ static const struct linear_range ldos_4_ranges[] = {
REGULATOR_LINEAR_RANGE(1200000, 0x20, 0x74, 25000),
};
+/* Voltage range for TPS65224 Bucks and LDOs */
+static const struct linear_range tps65224_bucks_1_ranges[] = {
+ REGULATOR_LINEAR_RANGE(500000, 0x0a, 0x0e, 20000),
+ REGULATOR_LINEAR_RANGE(600000, 0x0f, 0x72, 5000),
+ REGULATOR_LINEAR_RANGE(1100000, 0x73, 0xaa, 10000),
+ REGULATOR_LINEAR_RANGE(1660000, 0xab, 0xfd, 20000),
+};
+
+static const struct linear_range tps65224_bucks_2_3_4_ranges[] = {
+ REGULATOR_LINEAR_RANGE(500000, 0x0, 0x1a, 25000),
+ REGULATOR_LINEAR_RANGE(1200000, 0x1b, 0x45, 50000),
+};
+
+static const struct linear_range tps65224_ldos_1_ranges[] = {
+ REGULATOR_LINEAR_RANGE(1200000, 0xC, 0x36, 50000),
+};
+
+static const struct linear_range tps65224_ldos_2_3_ranges[] = {
+ REGULATOR_LINEAR_RANGE(600000, 0x0, 0x38, 50000),
+};
+
/* Operations permitted on BUCK1/2/3/4/5 */
static const struct regulator_ops tps6594_bucks_ops = {
.is_enabled = regulator_is_enabled_regmap,
@@ -197,6 +230,38 @@ static const struct regulator_desc buck_regs[] = {
4, 0, 0, NULL, 0, 0),
};
+/* Buck configuration for TPS65224 */
+static const struct regulator_desc tps65224_buck_regs[] = {
+ TPS6594_REGULATOR("BUCK1", "buck1", TPS6594_BUCK_1,
+ REGULATOR_VOLTAGE, tps6594_bucks_ops, TPS65224_MASK_BUCK1_VSET,
+ TPS6594_REG_BUCKX_VOUT_1(0),
+ TPS65224_MASK_BUCK1_VSET,
+ TPS6594_REG_BUCKX_CTRL(0),
+ TPS6594_BIT_BUCK_EN, 0, 0, tps65224_bucks_1_ranges,
+ 4, 0, 0, NULL, 0, 0),
+ TPS6594_REGULATOR("BUCK2", "buck2", TPS6594_BUCK_2,
+ REGULATOR_VOLTAGE, tps6594_bucks_ops, TPS65224_MASK_BUCKS_VSET,
+ TPS6594_REG_BUCKX_VOUT_1(1),
+ TPS65224_MASK_BUCKS_VSET,
+ TPS6594_REG_BUCKX_CTRL(1),
+ TPS6594_BIT_BUCK_EN, 0, 0, tps65224_bucks_2_3_4_ranges,
+ 4, 0, 0, NULL, 0, 0),
+ TPS6594_REGULATOR("BUCK3", "buck3", TPS6594_BUCK_3,
+ REGULATOR_VOLTAGE, tps6594_bucks_ops, TPS65224_MASK_BUCKS_VSET,
+ TPS6594_REG_BUCKX_VOUT_1(2),
+ TPS65224_MASK_BUCKS_VSET,
+ TPS6594_REG_BUCKX_CTRL(2),
+ TPS6594_BIT_BUCK_EN, 0, 0, tps65224_bucks_2_3_4_ranges,
+ 4, 0, 0, NULL, 0, 0),
+ TPS6594_REGULATOR("BUCK4", "buck4", TPS6594_BUCK_4,
+ REGULATOR_VOLTAGE, tps6594_bucks_ops, TPS65224_MASK_BUCKS_VSET,
+ TPS6594_REG_BUCKX_VOUT_1(3),
+ TPS65224_MASK_BUCKS_VSET,
+ TPS6594_REG_BUCKX_CTRL(3),
+ TPS6594_BIT_BUCK_EN, 0, 0, tps65224_bucks_2_3_4_ranges,
+ 4, 0, 0, NULL, 0, 0),
+};
+
static struct tps6594_regulator_irq_type tps6594_buck1_irq_types[] = {
{ TPS6594_IRQ_NAME_BUCK1_OV, "BUCK1", "overvoltage", REGULATOR_EVENT_OVER_VOLTAGE_WARN },
{ TPS6594_IRQ_NAME_BUCK1_UV, "BUCK1", "undervoltage", REGULATOR_EVENT_UNDER_VOLTAGE },
@@ -269,6 +334,41 @@ static struct tps6594_regulator_irq_type tps6594_ldo4_irq_types[] = {
REGULATOR_EVENT_OVER_CURRENT },
};
+static struct tps6594_regulator_irq_type tps65224_buck1_irq_types[] = {
+ { TPS65224_IRQ_NAME_BUCK1_UVOV, "BUCK1", "voltage out of range",
+ REGULATOR_EVENT_REGULATION_OUT },
+};
+
+static struct tps6594_regulator_irq_type tps65224_buck2_irq_types[] = {
+ { TPS65224_IRQ_NAME_BUCK2_UVOV, "BUCK2", "voltage out of range",
+ REGULATOR_EVENT_REGULATION_OUT },
+};
+
+static struct tps6594_regulator_irq_type tps65224_buck3_irq_types[] = {
+ { TPS65224_IRQ_NAME_BUCK3_UVOV, "BUCK3", "voltage out of range",
+ REGULATOR_EVENT_REGULATION_OUT },
+};
+
+static struct tps6594_regulator_irq_type tps65224_buck4_irq_types[] = {
+ { TPS65224_IRQ_NAME_BUCK4_UVOV, "BUCK4", "voltage out of range",
+ REGULATOR_EVENT_REGULATION_OUT },
+};
+
+static struct tps6594_regulator_irq_type tps65224_ldo1_irq_types[] = {
+ { TPS65224_IRQ_NAME_LDO1_UVOV, "LDO1", "voltage out of range",
+ REGULATOR_EVENT_REGULATION_OUT },
+};
+
+static struct tps6594_regulator_irq_type tps65224_ldo2_irq_types[] = {
+ { TPS65224_IRQ_NAME_LDO2_UVOV, "LDO2", "voltage out of range",
+ REGULATOR_EVENT_REGULATION_OUT },
+};
+
+static struct tps6594_regulator_irq_type tps65224_ldo3_irq_types[] = {
+ { TPS65224_IRQ_NAME_LDO3_UVOV, "LDO3", "voltage out of range",
+ REGULATOR_EVENT_REGULATION_OUT },
+};
+
static struct tps6594_regulator_irq_type *tps6594_bucks_irq_types[] = {
tps6594_buck1_irq_types,
tps6594_buck2_irq_types,
@@ -284,38 +384,61 @@ static struct tps6594_regulator_irq_type *tps6594_ldos_irq_types[] = {
tps6594_ldo4_irq_types,
};
-static const struct regulator_desc multi_regs[] = {
+static struct tps6594_regulator_irq_type *tps65224_bucks_irq_types[] = {
+ tps65224_buck1_irq_types,
+ tps65224_buck2_irq_types,
+ tps65224_buck3_irq_types,
+ tps65224_buck4_irq_types,
+};
+
+static struct tps6594_regulator_irq_type *tps65224_ldos_irq_types[] = {
+ tps65224_ldo1_irq_types,
+ tps65224_ldo2_irq_types,
+ tps65224_ldo3_irq_types,
+};
+
+static const struct regulator_desc tps6594_multi_regs[] = {
TPS6594_REGULATOR("BUCK12", "buck12", TPS6594_BUCK_1,
REGULATOR_VOLTAGE, tps6594_bucks_ops, TPS6594_MASK_BUCKS_VSET,
- TPS6594_REG_BUCKX_VOUT_1(1),
+ TPS6594_REG_BUCKX_VOUT_1(0),
TPS6594_MASK_BUCKS_VSET,
- TPS6594_REG_BUCKX_CTRL(1),
+ TPS6594_REG_BUCKX_CTRL(0),
TPS6594_BIT_BUCK_EN, 0, 0, bucks_ranges,
4, 4000, 0, NULL, 0, 0),
TPS6594_REGULATOR("BUCK34", "buck34", TPS6594_BUCK_3,
REGULATOR_VOLTAGE, tps6594_bucks_ops, TPS6594_MASK_BUCKS_VSET,
- TPS6594_REG_BUCKX_VOUT_1(3),
+ TPS6594_REG_BUCKX_VOUT_1(2),
TPS6594_MASK_BUCKS_VSET,
- TPS6594_REG_BUCKX_CTRL(3),
+ TPS6594_REG_BUCKX_CTRL(2),
TPS6594_BIT_BUCK_EN, 0, 0, bucks_ranges,
4, 0, 0, NULL, 0, 0),
TPS6594_REGULATOR("BUCK123", "buck123", TPS6594_BUCK_1,
REGULATOR_VOLTAGE, tps6594_bucks_ops, TPS6594_MASK_BUCKS_VSET,
- TPS6594_REG_BUCKX_VOUT_1(1),
+ TPS6594_REG_BUCKX_VOUT_1(0),
TPS6594_MASK_BUCKS_VSET,
- TPS6594_REG_BUCKX_CTRL(1),
+ TPS6594_REG_BUCKX_CTRL(0),
TPS6594_BIT_BUCK_EN, 0, 0, bucks_ranges,
4, 4000, 0, NULL, 0, 0),
TPS6594_REGULATOR("BUCK1234", "buck1234", TPS6594_BUCK_1,
REGULATOR_VOLTAGE, tps6594_bucks_ops, TPS6594_MASK_BUCKS_VSET,
- TPS6594_REG_BUCKX_VOUT_1(1),
+ TPS6594_REG_BUCKX_VOUT_1(0),
TPS6594_MASK_BUCKS_VSET,
- TPS6594_REG_BUCKX_CTRL(1),
+ TPS6594_REG_BUCKX_CTRL(0),
TPS6594_BIT_BUCK_EN, 0, 0, bucks_ranges,
4, 4000, 0, NULL, 0, 0),
};
-static const struct regulator_desc ldo_regs[] = {
+static const struct regulator_desc tps65224_multi_regs[] = {
+ TPS6594_REGULATOR("BUCK12", "buck12", TPS6594_BUCK_1,
+ REGULATOR_VOLTAGE, tps6594_bucks_ops, TPS65224_MASK_BUCK1_VSET,
+ TPS6594_REG_BUCKX_VOUT_1(0),
+ TPS65224_MASK_BUCK1_VSET,
+ TPS6594_REG_BUCKX_CTRL(0),
+ TPS6594_BIT_BUCK_EN, 0, 0, tps65224_bucks_1_ranges,
+ 4, 4000, 0, NULL, 0, 0),
+};
+
+static const struct regulator_desc tps6594_ldo_regs[] = {
TPS6594_REGULATOR("LDO1", "ldo1", TPS6594_LDO_1,
REGULATOR_VOLTAGE, tps6594_ldos_1_2_3_ops, TPS6594_MASK_LDO123_VSET,
TPS6594_REG_LDOX_VOUT(0),
@@ -346,6 +469,30 @@ static const struct regulator_desc ldo_regs[] = {
1, 0, 0, NULL, 0, 0),
};
+static const struct regulator_desc tps65224_ldo_regs[] = {
+ TPS6594_REGULATOR("LDO1", "ldo1", TPS6594_LDO_1,
+ REGULATOR_VOLTAGE, tps6594_ldos_1_2_3_ops, TPS6594_MASK_LDO123_VSET,
+ TPS6594_REG_LDOX_VOUT(0),
+ TPS6594_MASK_LDO123_VSET,
+ TPS6594_REG_LDOX_CTRL(0),
+ TPS6594_BIT_LDO_EN, 0, 0, tps65224_ldos_1_ranges,
+ 1, 0, 0, NULL, 0, TPS6594_BIT_LDO_BYPASS),
+ TPS6594_REGULATOR("LDO2", "ldo2", TPS6594_LDO_2,
+ REGULATOR_VOLTAGE, tps6594_ldos_1_2_3_ops, TPS6594_MASK_LDO123_VSET,
+ TPS6594_REG_LDOX_VOUT(1),
+ TPS6594_MASK_LDO123_VSET,
+ TPS6594_REG_LDOX_CTRL(1),
+ TPS6594_BIT_LDO_EN, 0, 0, tps65224_ldos_2_3_ranges,
+ 1, 0, 0, NULL, 0, TPS6594_BIT_LDO_BYPASS),
+ TPS6594_REGULATOR("LDO3", "ldo3", TPS6594_LDO_3,
+ REGULATOR_VOLTAGE, tps6594_ldos_1_2_3_ops, TPS6594_MASK_LDO123_VSET,
+ TPS6594_REG_LDOX_VOUT(2),
+ TPS6594_MASK_LDO123_VSET,
+ TPS6594_REG_LDOX_CTRL(2),
+ TPS6594_BIT_LDO_EN, 0, 0, tps65224_ldos_2_3_ranges,
+ 1, 0, 0, NULL, 0, TPS6594_BIT_LDO_BYPASS),
+};
+
static irqreturn_t tps6594_regulator_irq_handler(int irq, void *data)
{
struct tps6594_regulator_irq_data *irq_data = data;
@@ -369,17 +516,18 @@ static irqreturn_t tps6594_regulator_irq_handler(int irq, void *data)
static int tps6594_request_reg_irqs(struct platform_device *pdev,
struct regulator_dev *rdev,
struct tps6594_regulator_irq_data *irq_data,
- struct tps6594_regulator_irq_type *tps6594_regs_irq_types,
+ struct tps6594_regulator_irq_type *regs_irq_types,
+ size_t interrupt_cnt,
int *irq_idx)
{
struct tps6594_regulator_irq_type *irq_type;
struct tps6594 *tps = dev_get_drvdata(pdev->dev.parent);
- int j;
+ size_t j;
int irq;
int error;
- for (j = 0; j < REGS_INT_NB; j++) {
- irq_type = &tps6594_regs_irq_types[j];
+ for (j = 0; j < interrupt_cnt; j++) {
+ irq_type = &regs_irq_types[j];
irq = platform_get_irq_byname(pdev, irq_type->irq_name);
if (irq < 0)
return -EINVAL;
@@ -411,23 +559,47 @@ static int tps6594_regulator_probe(struct platform_device *pdev)
struct tps6594_regulator_irq_data *irq_data;
struct tps6594_ext_regulator_irq_data *irq_ext_reg_data;
struct tps6594_regulator_irq_type *irq_type;
- u8 buck_configured[BUCK_NB] = { 0 };
- u8 buck_multi[MULTI_PHASE_NB] = { 0 };
- static const char * const multiphases[] = {"buck12", "buck123", "buck1234", "buck34"};
+ struct tps6594_regulator_irq_type *irq_types;
+ bool buck_configured[BUCK_NB] = { false };
+ bool buck_multi[MULTI_PHASE_NB] = { false };
+
static const char *npname;
- int error, i, irq, multi, delta;
+ int error, i, irq, multi;
int irq_idx = 0;
int buck_idx = 0;
- size_t ext_reg_irq_nb = 2;
+ int nr_ldo;
+ int nr_buck;
+ int nr_types;
+ unsigned int irq_count;
+ unsigned int multi_phase_cnt;
size_t reg_irq_nb;
+ struct tps6594_regulator_irq_type **bucks_irq_types;
+ const struct regulator_desc *multi_regs;
+ struct tps6594_regulator_irq_type **ldos_irq_types;
+ const struct regulator_desc *ldo_regs;
+ size_t interrupt_count;
+
+ if (tps->chip_id == TPS65224) {
+ bucks_irq_types = tps65224_bucks_irq_types;
+ interrupt_count = ARRAY_SIZE(tps65224_buck1_irq_types);
+ multi_regs = tps65224_multi_regs;
+ ldos_irq_types = tps65224_ldos_irq_types;
+ ldo_regs = tps65224_ldo_regs;
+ multi_phase_cnt = ARRAY_SIZE(tps65224_multi_regs);
+ } else {
+ bucks_irq_types = tps6594_bucks_irq_types;
+ interrupt_count = ARRAY_SIZE(tps6594_buck1_irq_types);
+ multi_regs = tps6594_multi_regs;
+ ldos_irq_types = tps6594_ldos_irq_types;
+ ldo_regs = tps6594_ldo_regs;
+ multi_phase_cnt = ARRAY_SIZE(tps6594_multi_regs);
+ }
+
enum {
MULTI_BUCK12,
+ MULTI_BUCK12_34,
MULTI_BUCK123,
MULTI_BUCK1234,
- MULTI_BUCK12_34,
- MULTI_FIRST = MULTI_BUCK12,
- MULTI_LAST = MULTI_BUCK12_34,
- MULTI_NUM = MULTI_LAST - MULTI_FIRST + 1
};
config.dev = tps->dev;
@@ -442,61 +614,68 @@ static int tps6594_regulator_probe(struct platform_device *pdev)
* In case of Multiphase configuration, value should be defined for
* buck_configured to avoid creating bucks for every buck in multiphase
*/
- for (multi = MULTI_FIRST; multi < MULTI_NUM; multi++) {
- np = of_find_node_by_name(tps->dev->of_node, multiphases[multi]);
+ for (multi = 0; multi < multi_phase_cnt; multi++) {
+ np = of_find_node_by_name(tps->dev->of_node, multi_regs[multi].supply_name);
npname = of_node_full_name(np);
np_pmic_parent = of_get_parent(of_get_parent(np));
if (of_node_cmp(of_node_full_name(np_pmic_parent), tps->dev->of_node->full_name))
continue;
- delta = strcmp(npname, multiphases[multi]);
- if (!delta) {
+ if (strcmp(npname, multi_regs[multi].supply_name) == 0) {
switch (multi) {
case MULTI_BUCK12:
- buck_multi[0] = 1;
- buck_configured[0] = 1;
- buck_configured[1] = 1;
+ buck_multi[0] = true;
+ buck_configured[0] = true;
+ buck_configured[1] = true;
break;
/* multiphase buck34 is supported only with buck12 */
case MULTI_BUCK12_34:
- buck_multi[0] = 1;
- buck_multi[1] = 1;
- buck_configured[0] = 1;
- buck_configured[1] = 1;
- buck_configured[2] = 1;
- buck_configured[3] = 1;
+ buck_multi[0] = true;
+ buck_multi[1] = true;
+ buck_configured[0] = true;
+ buck_configured[1] = true;
+ buck_configured[2] = true;
+ buck_configured[3] = true;
break;
case MULTI_BUCK123:
- buck_multi[2] = 1;
- buck_configured[0] = 1;
- buck_configured[1] = 1;
- buck_configured[2] = 1;
+ buck_multi[2] = true;
+ buck_configured[0] = true;
+ buck_configured[1] = true;
+ buck_configured[2] = true;
break;
case MULTI_BUCK1234:
- buck_multi[3] = 1;
- buck_configured[0] = 1;
- buck_configured[1] = 1;
- buck_configured[2] = 1;
- buck_configured[3] = 1;
+ buck_multi[3] = true;
+ buck_configured[0] = true;
+ buck_configured[1] = true;
+ buck_configured[2] = true;
+ buck_configured[3] = true;
break;
}
}
}
if (tps->chip_id == LP8764) {
- /* There is only 4 buck on LP8764 */
- buck_configured[4] = 1;
- reg_irq_nb = size_mul(REGS_INT_NB, (BUCK_NB - 1));
+ nr_buck = ARRAY_SIZE(buck_regs);
+ nr_ldo = 0;
+ nr_types = REGS_INT_NB;
+ } else if (tps->chip_id == TPS65224) {
+ nr_buck = ARRAY_SIZE(tps65224_buck_regs);
+ nr_ldo = ARRAY_SIZE(tps65224_ldo_regs);
+ nr_types = REGS_INT_NB;
} else {
- reg_irq_nb = size_mul(REGS_INT_NB, (size_add(BUCK_NB, LDO_NB)));
+ nr_buck = ARRAY_SIZE(buck_regs);
+ nr_ldo = ARRAY_SIZE(tps6594_ldo_regs);
+ nr_types = TPS65224_REGS_INT_NB;
}
+ reg_irq_nb = nr_types * (nr_buck + nr_ldo);
+
irq_data = devm_kmalloc_array(tps->dev, reg_irq_nb,
sizeof(struct tps6594_regulator_irq_data), GFP_KERNEL);
if (!irq_data)
return -ENOMEM;
- for (i = 0; i < MULTI_PHASE_NB; i++) {
- if (buck_multi[i] == 0)
+ for (i = 0; i < multi_phase_cnt; i++) {
+ if (!buck_multi[i])
continue;
rdev = devm_regulator_register(&pdev->dev, &multi_regs[i], &config);
@@ -506,52 +685,60 @@ static int tps6594_regulator_probe(struct platform_device *pdev)
pdev->name);
/* config multiphase buck12+buck34 */
- if (i == 1)
+ if (i == MULTI_BUCK12_34)
buck_idx = 2;
+
error = tps6594_request_reg_irqs(pdev, rdev, irq_data,
- tps6594_bucks_irq_types[buck_idx], &irq_idx);
+ bucks_irq_types[buck_idx],
+ interrupt_count, &irq_idx);
if (error)
return error;
+
error = tps6594_request_reg_irqs(pdev, rdev, irq_data,
- tps6594_bucks_irq_types[buck_idx + 1], &irq_idx);
+ bucks_irq_types[buck_idx + 1],
+ interrupt_count, &irq_idx);
if (error)
return error;
- if (i == 2 || i == 3) {
+ if (i == MULTI_BUCK123 || i == MULTI_BUCK1234) {
error = tps6594_request_reg_irqs(pdev, rdev, irq_data,
tps6594_bucks_irq_types[buck_idx + 2],
+ interrupt_count,
&irq_idx);
if (error)
return error;
}
- if (i == 3) {
+ if (i == MULTI_BUCK1234) {
error = tps6594_request_reg_irqs(pdev, rdev, irq_data,
tps6594_bucks_irq_types[buck_idx + 3],
+ interrupt_count,
&irq_idx);
if (error)
return error;
}
}
- for (i = 0; i < BUCK_NB; i++) {
- if (buck_configured[i] == 1)
+ for (i = 0; i < nr_buck; i++) {
+ if (buck_configured[i])
continue;
- rdev = devm_regulator_register(&pdev->dev, &buck_regs[i], &config);
+ const struct regulator_desc *buck_cfg = (tps->chip_id == TPS65224) ?
+ tps65224_buck_regs : buck_regs;
+
+ rdev = devm_regulator_register(&pdev->dev, &buck_cfg[i], &config);
if (IS_ERR(rdev))
return dev_err_probe(tps->dev, PTR_ERR(rdev),
- "failed to register %s regulator\n",
- pdev->name);
+ "failed to register %s regulator\n", pdev->name);
error = tps6594_request_reg_irqs(pdev, rdev, irq_data,
- tps6594_bucks_irq_types[i], &irq_idx);
+ bucks_irq_types[i], interrupt_count, &irq_idx);
if (error)
return error;
}
- /* LP8764 dosen't have LDO */
+ /* LP8764 doesn't have LDO */
if (tps->chip_id != LP8764) {
- for (i = 0; i < ARRAY_SIZE(ldo_regs); i++) {
+ for (i = 0; i < nr_ldo; i++) {
rdev = devm_regulator_register(&pdev->dev, &ldo_regs[i], &config);
if (IS_ERR(rdev))
return dev_err_probe(tps->dev, PTR_ERR(rdev),
@@ -559,26 +746,34 @@ static int tps6594_regulator_probe(struct platform_device *pdev)
pdev->name);
error = tps6594_request_reg_irqs(pdev, rdev, irq_data,
- tps6594_ldos_irq_types[i],
+ ldos_irq_types[i], interrupt_count,
&irq_idx);
if (error)
return error;
}
}
- if (tps->chip_id == LP8764)
- ext_reg_irq_nb = ARRAY_SIZE(tps6594_ext_regulator_irq_types);
+ if (tps->chip_id == TPS65224) {
+ irq_types = tps65224_ext_regulator_irq_types;
+ irq_count = ARRAY_SIZE(tps65224_ext_regulator_irq_types);
+ } else {
+ irq_types = tps6594_ext_regulator_irq_types;
+ if (tps->chip_id == LP8764)
+ irq_count = ARRAY_SIZE(tps6594_ext_regulator_irq_types);
+ else
+ /* TPS6593 supports only VCCA OV and UV */
+ irq_count = 2;
+ }
irq_ext_reg_data = devm_kmalloc_array(tps->dev,
- ext_reg_irq_nb,
- sizeof(struct tps6594_ext_regulator_irq_data),
- GFP_KERNEL);
+ irq_count,
+ sizeof(struct tps6594_ext_regulator_irq_data),
+ GFP_KERNEL);
if (!irq_ext_reg_data)
return -ENOMEM;
- for (i = 0; i < ext_reg_irq_nb; ++i) {
- irq_type = &tps6594_ext_regulator_irq_types[i];
-
+ for (i = 0; i < irq_count; ++i) {
+ irq_type = &irq_types[i];
irq = platform_get_irq_byname(pdev, irq_type->irq_name);
if (irq < 0)
return -EINVAL;
@@ -610,5 +805,6 @@ module_platform_driver(tps6594_regulator_driver);
MODULE_ALIAS("platform:tps6594-regulator");
MODULE_AUTHOR("Jerome Neanne <jneanne@baylibre.com>");
+MODULE_AUTHOR("Nirmala Devi Mal Nadar <m.nirmaladevi@ltts.com>");
MODULE_DESCRIPTION("TPS6594 voltage regulator driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/regulator/vqmmc-ipq4019-regulator.c b/drivers/regulator/vqmmc-ipq4019-regulator.c
index 086da36abc0b..4955616517ce 100644
--- a/drivers/regulator/vqmmc-ipq4019-regulator.c
+++ b/drivers/regulator/vqmmc-ipq4019-regulator.c
@@ -84,6 +84,7 @@ static const struct of_device_id regulator_ipq4019_of_match[] = {
{ .compatible = "qcom,vqmmc-ipq4019-regulator", },
{},
};
+MODULE_DEVICE_TABLE(of, regulator_ipq4019_of_match);
static struct platform_driver ipq4019_regulator_driver = {
.probe = ipq4019_regulator_probe,