summaryrefslogtreecommitdiff
path: root/drivers/regulator
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/regulator')
-rw-r--r--drivers/regulator/88pg86x.c4
-rw-r--r--drivers/regulator/Kconfig7
-rw-r--r--drivers/regulator/Makefile1
-rw-r--r--drivers/regulator/ab8500.c1
-rw-r--r--drivers/regulator/act8865-regulator.c2
-rw-r--r--drivers/regulator/ad5398.c4
-rw-r--r--drivers/regulator/adp5055-regulator.c6
-rw-r--r--drivers/regulator/as3722-regulator.c1
-rw-r--r--drivers/regulator/aw37503-regulator.c4
-rw-r--r--drivers/regulator/core.c6
-rw-r--r--drivers/regulator/da9121-regulator.c20
-rw-r--r--drivers/regulator/da9210-regulator.c4
-rw-r--r--drivers/regulator/da9211-regulator.c18
-rw-r--r--drivers/regulator/fan53555.c35
-rw-r--r--drivers/regulator/fan53880.c4
-rw-r--r--drivers/regulator/isl6271a-regulator.c2
-rw-r--r--drivers/regulator/isl9305.c4
-rw-r--r--drivers/regulator/lp3971.c2
-rw-r--r--drivers/regulator/lp3972.c2
-rw-r--r--drivers/regulator/lp872x.c4
-rw-r--r--drivers/regulator/lp8755.c4
-rw-r--r--drivers/regulator/ltc3589.c6
-rw-r--r--drivers/regulator/ltc3676.c2
-rw-r--r--drivers/regulator/max14577-regulator.c103
-rw-r--r--drivers/regulator/max1586.c2
-rw-r--r--drivers/regulator/max20086-regulator.c8
-rw-r--r--drivers/regulator/max20411-regulator.c2
-rw-r--r--drivers/regulator/max77503-regulator.c2
-rw-r--r--drivers/regulator/max77675-regulator.c2
-rw-r--r--drivers/regulator/max77826-regulator.c2
-rw-r--r--drivers/regulator/max77838-regulator.c2
-rw-r--r--drivers/regulator/max77857-regulator.c8
-rw-r--r--drivers/regulator/max8649.c2
-rw-r--r--drivers/regulator/max8893.c2
-rw-r--r--drivers/regulator/max8952.c2
-rw-r--r--drivers/regulator/max8973-regulator.c6
-rw-r--r--drivers/regulator/max8998.c1
-rw-r--r--drivers/regulator/mcp16502.c27
-rw-r--r--drivers/regulator/mp5416.c6
-rw-r--r--drivers/regulator/mp8859.c4
-rw-r--r--drivers/regulator/mp886x.c6
-rw-r--r--drivers/regulator/mpq7920.c4
-rw-r--r--drivers/regulator/mt6311-regulator.c4
-rw-r--r--drivers/regulator/pf530x-regulator.c8
-rw-r--r--drivers/regulator/pf8x00-regulator.c8
-rw-r--r--drivers/regulator/pfuze100-regulator.c20
-rw-r--r--drivers/regulator/pv88060-regulator.c4
-rw-r--r--drivers/regulator/pv88080-regulator.c8
-rw-r--r--drivers/regulator/pv88090-regulator.c4
-rw-r--r--drivers/regulator/qcom-refgen-regulator.c113
-rw-r--r--drivers/regulator/qcom-rpmh-regulator.c128
-rw-r--r--drivers/regulator/qcom_usb_vbus-regulator.c102
-rw-r--r--drivers/regulator/rt6245-regulator.c5
-rw-r--r--drivers/regulator/rtq2208-regulator.c7
-rw-r--r--drivers/regulator/sc2730-regulator.c375
-rw-r--r--drivers/regulator/sgm3804-regulator.c2
-rw-r--r--drivers/regulator/slg51000-regulator.c4
-rw-r--r--drivers/regulator/sy8106a-regulator.c2
-rw-r--r--drivers/regulator/sy8824x.c8
-rw-r--r--drivers/regulator/sy8827n.c4
-rw-r--r--drivers/regulator/tps51632-regulator.c4
-rw-r--r--drivers/regulator/tps62360-regulator.c10
-rw-r--r--drivers/regulator/tps6286x-regulator.c10
-rw-r--r--drivers/regulator/tps6287x-regulator.c10
-rw-r--r--drivers/regulator/tps65023-regulator.c6
-rw-r--r--drivers/regulator/tps65132-regulator.c4
-rw-r--r--drivers/regulator/tps65185.c5
-rw-r--r--drivers/regulator/tps6594-regulator.c19
-rw-r--r--drivers/regulator/wm831x-isink.c6
69 files changed, 1027 insertions, 187 deletions
diff --git a/drivers/regulator/88pg86x.c b/drivers/regulator/88pg86x.c
index e6598e74ec94..8c25a1db412f 100644
--- a/drivers/regulator/88pg86x.c
+++ b/drivers/regulator/88pg86x.c
@@ -92,8 +92,8 @@ static const struct of_device_id __maybe_unused pg86x_dt_ids[] = {
MODULE_DEVICE_TABLE(of, pg86x_dt_ids);
static const struct i2c_device_id pg86x_i2c_id[] = {
- { "88pg867", },
- { "88pg868", },
+ { .name = "88pg867" },
+ { .name = "88pg868" },
{ }
};
MODULE_DEVICE_TABLE(i2c, pg86x_i2c_id);
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index a54a549196fe..89789ac7a786 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -1477,6 +1477,13 @@ config REGULATOR_S5M8767
via I2C bus. S5M8767A have 9 Bucks and 28 LDOs output and
supports DVS mode with 8bits of output voltage control.
+config REGULATOR_SC2730
+ tristate "Spreadtrum SC2730 power regulator driver"
+ depends on MFD_SC27XX_PMIC || COMPILE_TEST
+ help
+ This driver provides support for the voltage regulators on the
+ SC2730 PMIC.
+
config REGULATOR_SC2731
tristate "Spreadtrum SC2731 power regulator driver"
depends on MFD_SC27XX_PMIC || COMPILE_TEST
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 134eee274dbf..5a764cec8df8 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -170,6 +170,7 @@ obj-$(CONFIG_REGULATOR_S2DOS05) += s2dos05-regulator.o
obj-$(CONFIG_REGULATOR_S2MPA01) += s2mpa01.o
obj-$(CONFIG_REGULATOR_S2MPS11) += s2mps11.o
obj-$(CONFIG_REGULATOR_S5M8767) += s5m8767.o
+obj-$(CONFIG_REGULATOR_SC2730) += sc2730-regulator.o
obj-$(CONFIG_REGULATOR_SC2731) += sc2731-regulator.o
obj-$(CONFIG_REGULATOR_SGM3804) += sgm3804-regulator.o
obj-$(CONFIG_REGULATOR_SKY81452) += sky81452-regulator.o
diff --git a/drivers/regulator/ab8500.c b/drivers/regulator/ab8500.c
index 6b4a3a3d8385..3705c98b0713 100644
--- a/drivers/regulator/ab8500.c
+++ b/drivers/regulator/ab8500.c
@@ -173,7 +173,6 @@ struct ab8500_shared_mode {
* @voltage_bank: bank to control regulator voltage
* @voltage_reg: register to control regulator voltage
* @voltage_mask: mask to control regulator voltage
- * @expand_register:
*/
struct ab8500_regulator_info {
struct device *dev;
diff --git a/drivers/regulator/act8865-regulator.c b/drivers/regulator/act8865-regulator.c
index b2a6ddc6f56d..882b6e58e911 100644
--- a/drivers/regulator/act8865-regulator.c
+++ b/drivers/regulator/act8865-regulator.c
@@ -780,7 +780,7 @@ static const struct i2c_device_id act8865_ids[] = {
{ .name = "act8600", .driver_data = ACT8600 },
{ .name = "act8846", .driver_data = ACT8846 },
{ .name = "act8865", .driver_data = ACT8865 },
- { },
+ { }
};
MODULE_DEVICE_TABLE(i2c, act8865_ids);
diff --git a/drivers/regulator/ad5398.c b/drivers/regulator/ad5398.c
index eb2a666a45cb..0123ca8157a8 100644
--- a/drivers/regulator/ad5398.c
+++ b/drivers/regulator/ad5398.c
@@ -207,8 +207,8 @@ struct ad5398_current_data_format {
static const struct ad5398_current_data_format df_10_4_120 = {10, 4, 0, 120000};
static const struct i2c_device_id ad5398_id[] = {
- { "ad5398", (kernel_ulong_t)&df_10_4_120 },
- { "ad5821", (kernel_ulong_t)&df_10_4_120 },
+ { .name = "ad5398", .driver_data = (kernel_ulong_t)&df_10_4_120 },
+ { .name = "ad5821", .driver_data = (kernel_ulong_t)&df_10_4_120 },
{ }
};
MODULE_DEVICE_TABLE(i2c, ad5398_id);
diff --git a/drivers/regulator/adp5055-regulator.c b/drivers/regulator/adp5055-regulator.c
index 9ebd52b39235..194dcfe4f527 100644
--- a/drivers/regulator/adp5055-regulator.c
+++ b/drivers/regulator/adp5055-regulator.c
@@ -224,7 +224,7 @@ static int adp5055_of_parse_cb(struct device_node *np,
adp5055->dvs_limit_upper[id] = pval;
if (adp5055->dvs_limit_upper[id] > 192000 || adp5055->dvs_limit_upper[id] < 12000)
- return dev_err_probe(config->dev, adp5055->dvs_limit_upper[id],
+ return dev_err_probe(config->dev, -EINVAL,
"Out of range - dvs-limit-upper-microvolt value.");
ret = of_property_read_u32(np, "adi,dvs-limit-lower-microvolt", &pval);
@@ -403,8 +403,8 @@ static const struct of_device_id adp5055_of_match[] = {
MODULE_DEVICE_TABLE(of, adp5055_of_match);
static const struct i2c_device_id adp5055_ids[] = {
- { .name = "adp5055"},
- { },
+ { .name = "adp5055" },
+ { }
};
MODULE_DEVICE_TABLE(i2c, adp5055_ids);
diff --git a/drivers/regulator/as3722-regulator.c b/drivers/regulator/as3722-regulator.c
index da378bfdba40..85e2aaa1a06b 100644
--- a/drivers/regulator/as3722-regulator.c
+++ b/drivers/regulator/as3722-regulator.c
@@ -600,7 +600,6 @@ static int as3722_get_regulator_dt_data(struct platform_device *pdev,
ret = of_regulator_match(&pdev->dev, np, as3722_regulator_matches,
ARRAY_SIZE(as3722_regulator_matches));
- of_node_put(np);
if (ret < 0) {
dev_err(&pdev->dev, "Parsing of regulator node failed: %d\n",
ret);
diff --git a/drivers/regulator/aw37503-regulator.c b/drivers/regulator/aw37503-regulator.c
index a5ff6dfd29b5..ca5f2a14c28c 100644
--- a/drivers/regulator/aw37503-regulator.c
+++ b/drivers/regulator/aw37503-regulator.c
@@ -212,8 +212,8 @@ static int aw37503_probe(struct i2c_client *client)
}
static const struct i2c_device_id aw37503_id[] = {
- {.name = "aw37503",},
- {},
+ { .name = "aw37503" },
+ { }
};
MODULE_DEVICE_TABLE(i2c, aw37503_id);
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 2e61606fc1d0..6a4008f387b5 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -27,6 +27,7 @@
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
#include <linux/module.h>
+#include <linux/workqueue.h>
#define CREATE_TRACE_POINTS
#include <trace/events/regulator.h>
@@ -6899,8 +6900,9 @@ static int __init regulator_init_complete(void)
* we'd only do this on systems that need it, and a kernel
* command line option might be useful.
*/
- schedule_delayed_work(&regulator_init_complete_work,
- msecs_to_jiffies(30000));
+ queue_delayed_work(system_freezable_wq,
+ &regulator_init_complete_work,
+ msecs_to_jiffies(30000));
return 0;
}
diff --git a/drivers/regulator/da9121-regulator.c b/drivers/regulator/da9121-regulator.c
index 36a52f707602..f501cf8152c2 100644
--- a/drivers/regulator/da9121-regulator.c
+++ b/drivers/regulator/da9121-regulator.c
@@ -1195,16 +1195,16 @@ static void da9121_i2c_remove(struct i2c_client *i2c)
}
static const struct i2c_device_id da9121_i2c_id[] = {
- {"da9121", DA9121_SUBTYPE_DA9121},
- {"da9130", DA9121_SUBTYPE_DA9130},
- {"da9217", DA9121_SUBTYPE_DA9217},
- {"da9122", DA9121_SUBTYPE_DA9122},
- {"da9131", DA9121_SUBTYPE_DA9131},
- {"da9220", DA9121_SUBTYPE_DA9220},
- {"da9132", DA9121_SUBTYPE_DA9132},
- {"da9141", DA9121_SUBTYPE_DA9141},
- {"da9142", DA9121_SUBTYPE_DA9142},
- {},
+ { .name = "da9121", .driver_data = DA9121_SUBTYPE_DA9121 },
+ { .name = "da9130", .driver_data = DA9121_SUBTYPE_DA9130 },
+ { .name = "da9217", .driver_data = DA9121_SUBTYPE_DA9217 },
+ { .name = "da9122", .driver_data = DA9121_SUBTYPE_DA9122 },
+ { .name = "da9131", .driver_data = DA9121_SUBTYPE_DA9131 },
+ { .name = "da9220", .driver_data = DA9121_SUBTYPE_DA9220 },
+ { .name = "da9132", .driver_data = DA9121_SUBTYPE_DA9132 },
+ { .name = "da9141", .driver_data = DA9121_SUBTYPE_DA9141 },
+ { .name = "da9142", .driver_data = DA9121_SUBTYPE_DA9142 },
+ { }
};
MODULE_DEVICE_TABLE(i2c, da9121_i2c_id);
diff --git a/drivers/regulator/da9210-regulator.c b/drivers/regulator/da9210-regulator.c
index 39ade0dba40f..9154e32bd745 100644
--- a/drivers/regulator/da9210-regulator.c
+++ b/drivers/regulator/da9210-regulator.c
@@ -202,8 +202,8 @@ static int da9210_i2c_probe(struct i2c_client *i2c)
}
static const struct i2c_device_id da9210_i2c_id[] = {
- { "da9210" },
- {}
+ { .name = "da9210" },
+ { }
};
MODULE_DEVICE_TABLE(i2c, da9210_i2c_id);
diff --git a/drivers/regulator/da9211-regulator.c b/drivers/regulator/da9211-regulator.c
index d4f14d7ea8cf..9cf713755636 100644
--- a/drivers/regulator/da9211-regulator.c
+++ b/drivers/regulator/da9211-regulator.c
@@ -522,15 +522,15 @@ static int da9211_i2c_probe(struct i2c_client *i2c)
}
static const struct i2c_device_id da9211_i2c_id[] = {
- {"da9211", DA9211},
- {"da9212", DA9212},
- {"da9213", DA9213},
- {"da9223", DA9223},
- {"da9214", DA9214},
- {"da9224", DA9224},
- {"da9215", DA9215},
- {"da9225", DA9225},
- {},
+ { .name = "da9211", .driver_data = DA9211 },
+ { .name = "da9212", .driver_data = DA9212 },
+ { .name = "da9213", .driver_data = DA9213 },
+ { .name = "da9223", .driver_data = DA9223 },
+ { .name = "da9214", .driver_data = DA9214 },
+ { .name = "da9224", .driver_data = DA9224 },
+ { .name = "da9215", .driver_data = DA9215 },
+ { .name = "da9225", .driver_data = DA9225 },
+ { }
};
MODULE_DEVICE_TABLE(i2c, da9211_i2c_id);
diff --git a/drivers/regulator/fan53555.c b/drivers/regulator/fan53555.c
index c282236959b1..6557d8cbe98d 100644
--- a/drivers/regulator/fan53555.c
+++ b/drivers/regulator/fan53555.c
@@ -21,6 +21,7 @@
#include <linux/regulator/machine.h>
#include <linux/regulator/of_regulator.h>
#include <linux/slab.h>
+#include <dt-bindings/regulator/fcs,fan53555-regulator.h>
/* Voltage setting */
#define FAN53555_VSEL0 0x00
@@ -113,6 +114,7 @@ enum {
enum {
FAN53555_CHIP_REV_00 = 0x3,
FAN53555_CHIP_REV_13 = 0xf,
+ FAN53555_CHIP_REV_23 = 0xc,
};
enum {
@@ -305,6 +307,11 @@ static int fan53555_voltages_setup_fairchild(struct fan53555_device_info *di)
di->vsel_step = 10000;
di->enable_time = 400;
break;
+ case FAN53555_CHIP_REV_23:
+ di->vsel_min = 600000;
+ di->vsel_step = 12500;
+ di->enable_time = 400;
+ break;
default:
dev_err(di->dev,
"Chip ID %d with rev %d not supported!\n",
@@ -389,6 +396,18 @@ static int rk8602_voltages_setup_rockchip(struct fan53555_device_info *di)
return 0;
}
+static inline unsigned int fan53555_map_mode(unsigned int mode)
+{
+ switch (mode) {
+ case FAN53555_REGULATOR_MODE_FORCE_PWM:
+ return REGULATOR_MODE_FAST;
+ case FAN53555_REGULATOR_MODE_AUTO:
+ return REGULATOR_MODE_NORMAL;
+ default:
+ return REGULATOR_MODE_INVALID;
+ }
+}
+
static int fan53555_voltages_setup_silergy(struct fan53555_device_info *di)
{
/* Init voltage range and step */
@@ -586,6 +605,17 @@ static int fan53555_device_setup(struct fan53555_device_info *di,
return ret;
}
+static void fan53555_device_mode_map_setup(struct fan53555_device_info *di)
+{
+ switch (di->vendor) {
+ case FAN53555_VENDOR_SILERGY:
+ di->desc.of_map_mode = fan53555_map_mode;
+ break;
+ default:
+ break;
+ }
+}
+
static int fan53555_regulator_register(struct fan53555_device_info *di,
struct regulator_config *config)
{
@@ -686,6 +716,10 @@ static int fan53555_regulator_probe(struct i2c_client *client)
if (!di)
return -ENOMEM;
+ di->vendor = (uintptr_t)i2c_get_match_data(client);
+
+ fan53555_device_mode_map_setup(di);
+
pdata = dev_get_platdata(&client->dev);
if (!pdata)
pdata = fan53555_parse_dt(&client->dev, np, &di->desc);
@@ -695,7 +729,6 @@ static int fan53555_regulator_probe(struct i2c_client *client)
"Platform data not found!\n");
di->regulator = pdata->regulator;
- di->vendor = (uintptr_t)i2c_get_match_data(client);
if (!dev_fwnode(&client->dev)) {
/* if no ramp constraint set, get the pdata ramp_delay */
if (!di->regulator->constraints.ramp_delay) {
diff --git a/drivers/regulator/fan53880.c b/drivers/regulator/fan53880.c
index 6cb5656845f9..79ba705ec324 100644
--- a/drivers/regulator/fan53880.c
+++ b/drivers/regulator/fan53880.c
@@ -164,8 +164,8 @@ static const struct of_device_id fan53880_dt_ids[] = {
MODULE_DEVICE_TABLE(of, fan53880_dt_ids);
static const struct i2c_device_id fan53880_i2c_id[] = {
- { "fan53880", },
- {}
+ { .name = "fan53880" },
+ { }
};
MODULE_DEVICE_TABLE(i2c, fan53880_i2c_id);
diff --git a/drivers/regulator/isl6271a-regulator.c b/drivers/regulator/isl6271a-regulator.c
index 7883cd160727..868f2b823a10 100644
--- a/drivers/regulator/isl6271a-regulator.c
+++ b/drivers/regulator/isl6271a-regulator.c
@@ -138,7 +138,7 @@ static int isl6271a_probe(struct i2c_client *i2c)
}
static const struct i2c_device_id isl6271a_id[] = {
- { .name = "isl6271a", },
+ { .name = "isl6271a" },
{ }
};
diff --git a/drivers/regulator/isl9305.c b/drivers/regulator/isl9305.c
index 5a234f25e6bb..ec6bd6bb9721 100644
--- a/drivers/regulator/isl9305.c
+++ b/drivers/regulator/isl9305.c
@@ -186,8 +186,8 @@ MODULE_DEVICE_TABLE(of, isl9305_dt_ids);
#endif
static const struct i2c_device_id isl9305_i2c_id[] = {
- { "isl9305", },
- { "isl9305h", },
+ { .name = "isl9305" },
+ { .name = "isl9305h" },
{ }
};
MODULE_DEVICE_TABLE(i2c, isl9305_i2c_id);
diff --git a/drivers/regulator/lp3971.c b/drivers/regulator/lp3971.c
index d4dab86fe385..6f830ae1bb61 100644
--- a/drivers/regulator/lp3971.c
+++ b/drivers/regulator/lp3971.c
@@ -439,7 +439,7 @@ static int lp3971_i2c_probe(struct i2c_client *i2c)
}
static const struct i2c_device_id lp3971_i2c_id[] = {
- { "lp3971" },
+ { .name = "lp3971" },
{ }
};
MODULE_DEVICE_TABLE(i2c, lp3971_i2c_id);
diff --git a/drivers/regulator/lp3972.c b/drivers/regulator/lp3972.c
index 1b918fb72134..235c640ba57f 100644
--- a/drivers/regulator/lp3972.c
+++ b/drivers/regulator/lp3972.c
@@ -537,7 +537,7 @@ static int lp3972_i2c_probe(struct i2c_client *i2c)
}
static const struct i2c_device_id lp3972_i2c_id[] = {
- { "lp3972" },
+ { .name = "lp3972" },
{ }
};
MODULE_DEVICE_TABLE(i2c, lp3972_i2c_id);
diff --git a/drivers/regulator/lp872x.c b/drivers/regulator/lp872x.c
index 942f37082cb1..5b2faddd8110 100644
--- a/drivers/regulator/lp872x.c
+++ b/drivers/regulator/lp872x.c
@@ -935,8 +935,8 @@ static const struct of_device_id lp872x_dt_ids[] __maybe_unused = {
MODULE_DEVICE_TABLE(of, lp872x_dt_ids);
static const struct i2c_device_id lp872x_ids[] = {
- {"lp8720", LP8720},
- {"lp8725", LP8725},
+ { .name = "lp8720", .driver_data = LP8720 },
+ { .name = "lp8725", .driver_data = LP8725 },
{ }
};
MODULE_DEVICE_TABLE(i2c, lp872x_ids);
diff --git a/drivers/regulator/lp8755.c b/drivers/regulator/lp8755.c
index 5509bee49bda..632320ba1800 100644
--- a/drivers/regulator/lp8755.c
+++ b/drivers/regulator/lp8755.c
@@ -430,8 +430,8 @@ static void lp8755_remove(struct i2c_client *client)
}
static const struct i2c_device_id lp8755_id[] = {
- { LP8755_NAME },
- {}
+ { .name = LP8755_NAME },
+ { }
};
MODULE_DEVICE_TABLE(i2c, lp8755_id);
diff --git a/drivers/regulator/ltc3589.c b/drivers/regulator/ltc3589.c
index 3f70c2225dba..8bae5d8aeaf4 100644
--- a/drivers/regulator/ltc3589.c
+++ b/drivers/regulator/ltc3589.c
@@ -445,9 +445,9 @@ static const struct ltc3589_info ltc3589_12_info = {
};
static const struct i2c_device_id ltc3589_i2c_id[] = {
- { "ltc3589", (kernel_ulong_t)&ltc3589_info },
- { "ltc3589-1", (kernel_ulong_t)&ltc3589_12_info },
- { "ltc3589-2", (kernel_ulong_t)&ltc3589_12_info },
+ { .name = "ltc3589", .driver_data = (kernel_ulong_t)&ltc3589_info },
+ { .name = "ltc3589-1", .driver_data = (kernel_ulong_t)&ltc3589_12_info },
+ { .name = "ltc3589-2", .driver_data = (kernel_ulong_t)&ltc3589_12_info },
{ }
};
MODULE_DEVICE_TABLE(i2c, ltc3589_i2c_id);
diff --git a/drivers/regulator/ltc3676.c b/drivers/regulator/ltc3676.c
index 768cdce0d4ec..307c6f7a155d 100644
--- a/drivers/regulator/ltc3676.c
+++ b/drivers/regulator/ltc3676.c
@@ -357,7 +357,7 @@ static int ltc3676_regulator_probe(struct i2c_client *client)
}
static const struct i2c_device_id ltc3676_i2c_id[] = {
- { "ltc3676" },
+ { .name = "ltc3676" },
{ }
};
MODULE_DEVICE_TABLE(i2c, ltc3676_i2c_id);
diff --git a/drivers/regulator/max14577-regulator.c b/drivers/regulator/max14577-regulator.c
index c9d8d5e31cbd..cd592c5de148 100644
--- a/drivers/regulator/max14577-regulator.c
+++ b/drivers/regulator/max14577-regulator.c
@@ -123,15 +123,88 @@ static const struct regulator_desc max14577_supported_regulators[] = {
[MAX14577_CHARGER] = MAX14577_CHARGER_REG,
};
+struct max77836_ldo {
+ struct max14577 *max14577;
+ unsigned int mode;
+};
+
+static int max77836_ldo_enable(struct regulator_dev *rdev)
+{
+ struct max77836_ldo *ldo = rdev_get_drvdata(rdev);
+
+ return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
+ MAX77836_CNFG1_LDO_PWRMD_MASK, ldo->mode);
+}
+
+static int max77836_ldo_disable(struct regulator_dev *rdev)
+{
+ return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
+ MAX77836_CNFG1_LDO_PWRMD_MASK,
+ MAX77836_CNFG1_LDO_PWRMD_OFF);
+}
+
+static unsigned int max77836_ldo_get_mode(struct regulator_dev *rdev)
+{
+ struct max77836_ldo *ldo = rdev_get_drvdata(rdev);
+
+ switch (ldo->mode) {
+ case MAX77836_CNFG1_LDO_PWRMD_LPM:
+ return REGULATOR_MODE_IDLE;
+ case MAX77836_CNFG1_LDO_PWRMD_NORMAL:
+ return REGULATOR_MODE_NORMAL;
+ default:
+ return REGULATOR_MODE_INVALID;
+ }
+}
+
+static int max77836_ldo_set_mode(struct regulator_dev *rdev,
+ unsigned int mode)
+{
+ struct max77836_ldo *ldo = rdev_get_drvdata(rdev);
+ unsigned int val;
+
+ switch (mode) {
+ case REGULATOR_MODE_NORMAL:
+ val = MAX77836_CNFG1_LDO_PWRMD_NORMAL;
+ break;
+ case REGULATOR_MODE_IDLE:
+ val = MAX77836_CNFG1_LDO_PWRMD_LPM;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ ldo->mode = val;
+
+ /* Only touch hardware if the regulator is already on */
+ if (regulator_is_enabled_regmap(rdev))
+ return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
+ MAX77836_CNFG1_LDO_PWRMD_MASK, val);
+
+ return 0;
+}
+
+static unsigned int max77836_ldo_of_map_mode(unsigned int mode)
+{
+ switch (mode) {
+ case REGULATOR_MODE_NORMAL:
+ case REGULATOR_MODE_IDLE:
+ return mode;
+ default:
+ return REGULATOR_MODE_INVALID;
+ }
+}
+
static const struct regulator_ops max77836_ldo_ops = {
.is_enabled = regulator_is_enabled_regmap,
- .enable = regulator_enable_regmap,
- .disable = regulator_disable_regmap,
+ .enable = max77836_ldo_enable,
+ .disable = max77836_ldo_disable,
.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,
- /* TODO: add .set_suspend_mode */
+ .get_mode = max77836_ldo_get_mode,
+ .set_mode = max77836_ldo_set_mode,
};
#define MAX77836_LDO_REG(num) { \
@@ -147,6 +220,7 @@ static const struct regulator_ops max77836_ldo_ops = {
.uV_step = MAX77836_REGULATOR_LDO_VOLTAGE_STEP, \
.enable_reg = MAX77836_LDO_REG_CNFG1_LDO ## num, \
.enable_mask = MAX77836_CNFG1_LDO_PWRMD_MASK, \
+ .of_map_mode = max77836_ldo_of_map_mode, \
.vsel_reg = MAX77836_LDO_REG_CNFG1_LDO ## num, \
.vsel_mask = MAX77836_CNFG1_LDO_TV_MASK, \
}
@@ -205,7 +279,6 @@ static int max14577_regulator_probe(struct platform_device *pdev)
}
config.dev = max14577->dev;
- config.driver_data = max14577;
for (i = 0; i < supported_regulators_size; i++) {
struct regulator_dev *regulator;
@@ -217,6 +290,28 @@ static int max14577_regulator_probe(struct platform_device *pdev)
config.init_data = pdata->regulators[i].initdata;
config.of_node = pdata->regulators[i].of_node;
}
+
+ /*
+ * LDOs need per-regulator driver data to store their mode.
+ * The charger and safeout share the core MFD struct.
+ */
+ if (dev_type == MAXIM_DEVICE_TYPE_MAX77836 &&
+ (supported_regulators[i].id == MAX77836_LDO1 ||
+ supported_regulators[i].id == MAX77836_LDO2)) {
+ struct max77836_ldo *ldo;
+
+ ldo = devm_kzalloc(&pdev->dev, sizeof(*ldo),
+ GFP_KERNEL);
+ if (!ldo)
+ return -ENOMEM;
+
+ ldo->max14577 = max14577;
+ ldo->mode = MAX77836_CNFG1_LDO_PWRMD_NORMAL;
+ config.driver_data = ldo;
+ } else {
+ config.driver_data = max14577;
+ }
+
config.regmap = max14577_get_regmap(max14577,
supported_regulators[i].id);
diff --git a/drivers/regulator/max1586.c b/drivers/regulator/max1586.c
index 4242fbb7b147..e5cbc09c2d39 100644
--- a/drivers/regulator/max1586.c
+++ b/drivers/regulator/max1586.c
@@ -276,7 +276,7 @@ static int max1586_pmic_probe(struct i2c_client *client)
}
static const struct i2c_device_id max1586_id[] = {
- { "max1586" },
+ { .name = "max1586" },
{ }
};
MODULE_DEVICE_TABLE(i2c, max1586_id);
diff --git a/drivers/regulator/max20086-regulator.c b/drivers/regulator/max20086-regulator.c
index fcdd2d0317a5..92594b2915f3 100644
--- a/drivers/regulator/max20086-regulator.c
+++ b/drivers/regulator/max20086-regulator.c
@@ -301,10 +301,10 @@ static const struct max20086_chip_info max20089_chip_info = {
};
static const struct i2c_device_id max20086_i2c_id[] = {
- { "max20086", (kernel_ulong_t)&max20086_chip_info },
- { "max20087", (kernel_ulong_t)&max20087_chip_info },
- { "max20088", (kernel_ulong_t)&max20088_chip_info },
- { "max20089", (kernel_ulong_t)&max20089_chip_info },
+ { .name = "max20086", .driver_data = (kernel_ulong_t)&max20086_chip_info },
+ { .name = "max20087", .driver_data = (kernel_ulong_t)&max20087_chip_info },
+ { .name = "max20088", .driver_data = (kernel_ulong_t)&max20088_chip_info },
+ { .name = "max20089", .driver_data = (kernel_ulong_t)&max20089_chip_info },
{ /* Sentinel */ }
};
MODULE_DEVICE_TABLE(i2c, max20086_i2c_id);
diff --git a/drivers/regulator/max20411-regulator.c b/drivers/regulator/max20411-regulator.c
index 6c0ebb970e90..ac7a9aa014aa 100644
--- a/drivers/regulator/max20411-regulator.c
+++ b/drivers/regulator/max20411-regulator.c
@@ -145,7 +145,7 @@ static const struct of_device_id of_max20411_match_tbl[] = {
MODULE_DEVICE_TABLE(of, of_max20411_match_tbl);
static const struct i2c_device_id max20411_id[] = {
- { "max20411" },
+ { .name = "max20411" },
{ }
};
MODULE_DEVICE_TABLE(i2c, max20411_id);
diff --git a/drivers/regulator/max77503-regulator.c b/drivers/regulator/max77503-regulator.c
index c7c94e868fc1..1cae846f96d0 100644
--- a/drivers/regulator/max77503-regulator.c
+++ b/drivers/regulator/max77503-regulator.c
@@ -107,7 +107,7 @@ static const struct of_device_id of_max77503_match_tbl[] = {
MODULE_DEVICE_TABLE(of, of_max77503_match_tbl);
static const struct i2c_device_id max77503_regulator_id[] = {
- {"max77503"},
+ { .name = "max77503" },
{ }
};
diff --git a/drivers/regulator/max77675-regulator.c b/drivers/regulator/max77675-regulator.c
index fad0844f364e..23b54b44f8b7 100644
--- a/drivers/regulator/max77675-regulator.c
+++ b/drivers/regulator/max77675-regulator.c
@@ -1028,7 +1028,7 @@ static int max77675_regulator_probe(struct i2c_client *client)
}
static const struct i2c_device_id max77675_i2c_id[] = {
- { "max77675", 0 },
+ { .name = "max77675" },
{ }
};
MODULE_DEVICE_TABLE(i2c, max77675_i2c_id);
diff --git a/drivers/regulator/max77826-regulator.c b/drivers/regulator/max77826-regulator.c
index 310bc8ee7af8..8b60a9fcab44 100644
--- a/drivers/regulator/max77826-regulator.c
+++ b/drivers/regulator/max77826-regulator.c
@@ -278,7 +278,7 @@ static const struct of_device_id __maybe_unused max77826_of_match[] = {
MODULE_DEVICE_TABLE(of, max77826_of_match);
static const struct i2c_device_id max77826_id[] = {
- { "max77826-regulator" },
+ { .name = "max77826-regulator" },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(i2c, max77826_id);
diff --git a/drivers/regulator/max77838-regulator.c b/drivers/regulator/max77838-regulator.c
index 9faddbfd25fd..765756fdcf6e 100644
--- a/drivers/regulator/max77838-regulator.c
+++ b/drivers/regulator/max77838-regulator.c
@@ -200,7 +200,7 @@ static const struct of_device_id __maybe_unused max77838_of_match[] = {
MODULE_DEVICE_TABLE(of, max77838_of_match);
static const struct i2c_device_id max77838_id[] = {
- { "max77838-regulator" },
+ { .name = "max77838-regulator" },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(i2c, max77838_id);
diff --git a/drivers/regulator/max77857-regulator.c b/drivers/regulator/max77857-regulator.c
index 1216cc3a6f72..f1410f845653 100644
--- a/drivers/regulator/max77857-regulator.c
+++ b/drivers/regulator/max77857-regulator.c
@@ -428,10 +428,10 @@ static int max77857_probe(struct i2c_client *client)
}
static const struct i2c_device_id max77857_id[] = {
- { "max77831", ID_MAX77831 },
- { "max77857", ID_MAX77857 },
- { "max77859", ID_MAX77859 },
- { "max77859a", ID_MAX77859A },
+ { .name = "max77831", .driver_data = ID_MAX77831 },
+ { .name = "max77857", .driver_data = ID_MAX77857 },
+ { .name = "max77859", .driver_data = ID_MAX77859 },
+ { .name = "max77859a", .driver_data = ID_MAX77859A },
{ }
};
MODULE_DEVICE_TABLE(i2c, max77857_id);
diff --git a/drivers/regulator/max8649.c b/drivers/regulator/max8649.c
index f57c588bcf28..2d17405242e7 100644
--- a/drivers/regulator/max8649.c
+++ b/drivers/regulator/max8649.c
@@ -240,7 +240,7 @@ static int max8649_regulator_probe(struct i2c_client *client)
}
static const struct i2c_device_id max8649_id[] = {
- { "max8649" },
+ { .name = "max8649" },
{ }
};
MODULE_DEVICE_TABLE(i2c, max8649_id);
diff --git a/drivers/regulator/max8893.c b/drivers/regulator/max8893.c
index 5a90633d8536..7a0e44a16d49 100644
--- a/drivers/regulator/max8893.c
+++ b/drivers/regulator/max8893.c
@@ -162,7 +162,7 @@ MODULE_DEVICE_TABLE(of, max8893_dt_match);
#endif
static const struct i2c_device_id max8893_ids[] = {
- { "max8893" },
+ { .name = "max8893" },
{ }
};
MODULE_DEVICE_TABLE(i2c, max8893_ids);
diff --git a/drivers/regulator/max8952.c b/drivers/regulator/max8952.c
index 1f94315bfb02..f8b91a5701f3 100644
--- a/drivers/regulator/max8952.c
+++ b/drivers/regulator/max8952.c
@@ -307,7 +307,7 @@ static int max8952_pmic_probe(struct i2c_client *client)
}
static const struct i2c_device_id max8952_ids[] = {
- { "max8952" },
+ { .name = "max8952" },
{ }
};
MODULE_DEVICE_TABLE(i2c, max8952_ids);
diff --git a/drivers/regulator/max8973-regulator.c b/drivers/regulator/max8973-regulator.c
index f68caa07f546..95062032dc7e 100644
--- a/drivers/regulator/max8973-regulator.c
+++ b/drivers/regulator/max8973-regulator.c
@@ -780,9 +780,9 @@ static int max8973_probe(struct i2c_client *client)
}
static const struct i2c_device_id max8973_id[] = {
- {.name = "max8973", .driver_data = MAX8973},
- {.name = "max77621", .driver_data = MAX77621},
- {},
+ { .name = "max8973", .driver_data = MAX8973 },
+ { .name = "max77621", .driver_data = MAX77621 },
+ { }
};
MODULE_DEVICE_TABLE(i2c, max8973_id);
diff --git a/drivers/regulator/max8998.c b/drivers/regulator/max8998.c
index cc85fbe8b77c..90651f4d1828 100644
--- a/drivers/regulator/max8998.c
+++ b/drivers/regulator/max8998.c
@@ -582,7 +582,6 @@ static int max8998_pmic_dt_parse_pdata(struct max8998_dev *iodev,
}
pdata->num_regulators = rdata - pdata->regulators;
- of_node_put(reg_np);
of_node_put(regulators_np);
pdata->buck_voltage_lock = of_property_read_bool(pmic_np, "max8998,pmic-buck-voltage-lock");
diff --git a/drivers/regulator/mcp16502.c b/drivers/regulator/mcp16502.c
index b34ae0bbba6f..07c67ad1ab7f 100644
--- a/drivers/regulator/mcp16502.c
+++ b/drivers/regulator/mcp16502.c
@@ -508,7 +508,7 @@ static int mcp16502_probe(struct i2c_client *client)
struct device *dev;
struct mcp16502 *mcp;
struct regmap *rmap;
- int i, ret;
+ int i;
dev = &client->dev;
config.dev = dev;
@@ -518,30 +518,23 @@ static int mcp16502_probe(struct i2c_client *client)
return -ENOMEM;
rmap = devm_regmap_init_i2c(client, &mcp16502_regmap_config);
- if (IS_ERR(rmap)) {
- ret = PTR_ERR(rmap);
- dev_err(dev, "regmap init failed: %d\n", ret);
- return ret;
- }
+ if (IS_ERR(rmap))
+ return dev_err_probe(dev, PTR_ERR(rmap), "regmap init failed\n");
i2c_set_clientdata(client, mcp);
config.regmap = rmap;
config.driver_data = mcp;
mcp->lpm = devm_gpiod_get_optional(dev, "lpm", GPIOD_OUT_LOW);
- if (IS_ERR(mcp->lpm)) {
- dev_err(dev, "failed to get lpm pin: %ld\n", PTR_ERR(mcp->lpm));
- return PTR_ERR(mcp->lpm);
- }
+ if (IS_ERR(mcp->lpm))
+ return dev_err_probe(dev, PTR_ERR(mcp->lpm), "failed to get lpm pin\n");
for (i = 0; i < NUM_REGULATORS; i++) {
rdev = devm_regulator_register(dev, &mcp16502_desc[i], &config);
- if (IS_ERR(rdev)) {
- dev_err(dev,
- "failed to register %s regulator %ld\n",
- mcp16502_desc[i].name, PTR_ERR(rdev));
- return PTR_ERR(rdev);
- }
+ if (IS_ERR(rdev))
+ return dev_err_probe(dev, PTR_ERR(rdev),
+ "failed to register %s regulator\n",
+ mcp16502_desc[i].name);
}
mcp16502_gpio_set_mode(mcp, MCP16502_OPMODE_ACTIVE);
@@ -578,7 +571,7 @@ static const struct dev_pm_ops mcp16502_pm_ops = {
};
#endif
static const struct i2c_device_id mcp16502_i2c_id[] = {
- { "mcp16502" },
+ { .name = "mcp16502" },
{ }
};
MODULE_DEVICE_TABLE(i2c, mcp16502_i2c_id);
diff --git a/drivers/regulator/mp5416.c b/drivers/regulator/mp5416.c
index e6794190cb68..2948635b1b9f 100644
--- a/drivers/regulator/mp5416.c
+++ b/drivers/regulator/mp5416.c
@@ -228,9 +228,9 @@ static const struct of_device_id mp5416_of_match[] = {
MODULE_DEVICE_TABLE(of, mp5416_of_match);
static const struct i2c_device_id mp5416_id[] = {
- { "mp5416", (kernel_ulong_t)&mp5416_regulators_desc },
- { "mp5496", (kernel_ulong_t)&mp5496_regulators_desc },
- {}
+ { .name = "mp5416", .driver_data = (kernel_ulong_t)&mp5416_regulators_desc },
+ { .name = "mp5496", .driver_data = (kernel_ulong_t)&mp5496_regulators_desc },
+ { }
};
MODULE_DEVICE_TABLE(i2c, mp5416_id);
diff --git a/drivers/regulator/mp8859.c b/drivers/regulator/mp8859.c
index ab105ffd6a2e..9a708e826d93 100644
--- a/drivers/regulator/mp8859.c
+++ b/drivers/regulator/mp8859.c
@@ -386,8 +386,8 @@ static const struct of_device_id mp8859_dt_id[] __maybe_unused = {
MODULE_DEVICE_TABLE(of, mp8859_dt_id);
static const struct i2c_device_id mp8859_i2c_id[] = {
- { "mp8859", },
- { },
+ { .name = "mp8859" },
+ { }
};
MODULE_DEVICE_TABLE(i2c, mp8859_i2c_id);
diff --git a/drivers/regulator/mp886x.c b/drivers/regulator/mp886x.c
index 9ad16b04c913..e0b62bc02a1e 100644
--- a/drivers/regulator/mp886x.c
+++ b/drivers/regulator/mp886x.c
@@ -348,9 +348,9 @@ static const struct of_device_id mp886x_dt_ids[] = {
MODULE_DEVICE_TABLE(of, mp886x_dt_ids);
static const struct i2c_device_id mp886x_id[] = {
- { "mp8867", (kernel_ulong_t)&mp8867_ci },
- { "mp8869", (kernel_ulong_t)&mp8869_ci },
- { },
+ { .name = "mp8867", .driver_data = (kernel_ulong_t)&mp8867_ci },
+ { .name = "mp8869", .driver_data = (kernel_ulong_t)&mp8869_ci },
+ { }
};
MODULE_DEVICE_TABLE(i2c, mp886x_id);
diff --git a/drivers/regulator/mpq7920.c b/drivers/regulator/mpq7920.c
index a670e09891e7..0cbc17deb1d1 100644
--- a/drivers/regulator/mpq7920.c
+++ b/drivers/regulator/mpq7920.c
@@ -309,8 +309,8 @@ static const struct of_device_id mpq7920_of_match[] = {
MODULE_DEVICE_TABLE(of, mpq7920_of_match);
static const struct i2c_device_id mpq7920_id[] = {
- { "mpq7920", },
- { },
+ { .name = "mpq7920" },
+ { }
};
MODULE_DEVICE_TABLE(i2c, mpq7920_id);
diff --git a/drivers/regulator/mt6311-regulator.c b/drivers/regulator/mt6311-regulator.c
index 2ebc1c0b5e6f..1d457d1fdf23 100644
--- a/drivers/regulator/mt6311-regulator.c
+++ b/drivers/regulator/mt6311-regulator.c
@@ -133,8 +133,8 @@ static int mt6311_i2c_probe(struct i2c_client *i2c)
}
static const struct i2c_device_id mt6311_i2c_id[] = {
- { "mt6311" },
- {}
+ { .name = "mt6311" },
+ { }
};
MODULE_DEVICE_TABLE(i2c, mt6311_i2c_id);
diff --git a/drivers/regulator/pf530x-regulator.c b/drivers/regulator/pf530x-regulator.c
index f789c4b6a499..8ad1cbbd7a8c 100644
--- a/drivers/regulator/pf530x-regulator.c
+++ b/drivers/regulator/pf530x-regulator.c
@@ -353,10 +353,10 @@ static const struct of_device_id pf530x_dt_ids[] = {
MODULE_DEVICE_TABLE(of, pf530x_dt_ids);
static const struct i2c_device_id pf530x_i2c_id[] = {
- { "pf5300", 0 },
- { "pf5301", 0 },
- { "pf5302", 0 },
- {},
+ { .name = "pf5300" },
+ { .name = "pf5301" },
+ { .name = "pf5302" },
+ { }
};
MODULE_DEVICE_TABLE(i2c, pf530x_i2c_id);
diff --git a/drivers/regulator/pf8x00-regulator.c b/drivers/regulator/pf8x00-regulator.c
index ea3611de42b4..c938b4632ef1 100644
--- a/drivers/regulator/pf8x00-regulator.c
+++ b/drivers/regulator/pf8x00-regulator.c
@@ -596,10 +596,10 @@ static const struct of_device_id pf8x00_dt_ids[] = {
MODULE_DEVICE_TABLE(of, pf8x00_dt_ids);
static const struct i2c_device_id pf8x00_i2c_id[] = {
- { "pf8100" },
- { "pf8121a" },
- { "pf8200" },
- {}
+ { .name = "pf8100" },
+ { .name = "pf8121a" },
+ { .name = "pf8200" },
+ { }
};
MODULE_DEVICE_TABLE(i2c, pf8x00_i2c_id);
diff --git a/drivers/regulator/pfuze100-regulator.c b/drivers/regulator/pfuze100-regulator.c
index 7d56c22b5e40..d3a0e2505524 100644
--- a/drivers/regulator/pfuze100-regulator.c
+++ b/drivers/regulator/pfuze100-regulator.c
@@ -158,6 +158,25 @@ static int pfuze100_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay)
return ret;
}
+static int pfuze100_ldo_set_suspend_disable(struct regulator_dev *rdev)
+{
+ struct pfuze_chip *pfuze100 = rdev_get_drvdata(rdev);
+ int id = rdev_get_id(rdev);
+ struct pfuze_regulator *desc = &pfuze100->regulator_descs[id];
+
+ /*
+ * Set the standby bit so the LDO output is turned off when the PMIC
+ * receives a STANDBY event, using the per-regulator stby_reg/stby_mask
+ * that describe the standby control for each LDO.
+ *
+ * The stby_mask only covers the VGENxSTBY bit. The VGENxLPWR stays at
+ * its reset value of 0, so the LDO is switched off rather than put
+ * into low-power mode.
+ */
+ return regmap_update_bits(pfuze100->regmap, desc->stby_reg,
+ desc->stby_mask, desc->stby_mask);
+}
+
static const struct regulator_ops pfuze100_ldo_regulator_ops = {
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
@@ -165,6 +184,7 @@ static const struct regulator_ops pfuze100_ldo_regulator_ops = {
.list_voltage = regulator_list_voltage_linear,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
+ .set_suspend_disable = pfuze100_ldo_set_suspend_disable,
};
static const struct regulator_ops pfuze100_fixed_regulator_ops = {
diff --git a/drivers/regulator/pv88060-regulator.c b/drivers/regulator/pv88060-regulator.c
index ae1c4b9daaa1..375d9e759c47 100644
--- a/drivers/regulator/pv88060-regulator.c
+++ b/drivers/regulator/pv88060-regulator.c
@@ -360,8 +360,8 @@ static int pv88060_i2c_probe(struct i2c_client *i2c)
}
static const struct i2c_device_id pv88060_i2c_id[] = {
- { "pv88060" },
- {}
+ { .name = "pv88060" },
+ { }
};
MODULE_DEVICE_TABLE(i2c, pv88060_i2c_id);
diff --git a/drivers/regulator/pv88080-regulator.c b/drivers/regulator/pv88080-regulator.c
index 112eb1c73647..b96afbf11ff3 100644
--- a/drivers/regulator/pv88080-regulator.c
+++ b/drivers/regulator/pv88080-regulator.c
@@ -522,10 +522,10 @@ static const struct of_device_id pv88080_dt_ids[] = {
MODULE_DEVICE_TABLE(of, pv88080_dt_ids);
static const struct i2c_device_id pv88080_i2c_id[] = {
- { "pv88080", (kernel_ulong_t)&pv88080_aa_regs },
- { "pv88080-aa", (kernel_ulong_t)&pv88080_aa_regs },
- { "pv88080-ba", (kernel_ulong_t)&pv88080_ba_regs },
- {}
+ { .name = "pv88080", .driver_data = (kernel_ulong_t)&pv88080_aa_regs },
+ { .name = "pv88080-aa", .driver_data = (kernel_ulong_t)&pv88080_aa_regs },
+ { .name = "pv88080-ba", .driver_data = (kernel_ulong_t)&pv88080_ba_regs },
+ { }
};
MODULE_DEVICE_TABLE(i2c, pv88080_i2c_id);
diff --git a/drivers/regulator/pv88090-regulator.c b/drivers/regulator/pv88090-regulator.c
index 3c48757bbbda..ca5eeb5dfe62 100644
--- a/drivers/regulator/pv88090-regulator.c
+++ b/drivers/regulator/pv88090-regulator.c
@@ -381,8 +381,8 @@ static int pv88090_i2c_probe(struct i2c_client *i2c)
}
static const struct i2c_device_id pv88090_i2c_id[] = {
- { "pv88090" },
- {}
+ { .name = "pv88090" },
+ { }
};
MODULE_DEVICE_TABLE(i2c, pv88090_i2c_id);
diff --git a/drivers/regulator/qcom-refgen-regulator.c b/drivers/regulator/qcom-refgen-regulator.c
index 299ac3c8c3bc..cc72e5a43ba6 100644
--- a/drivers/regulator/qcom-refgen-regulator.c
+++ b/drivers/regulator/qcom-refgen-regulator.c
@@ -3,6 +3,7 @@
// Copyright (c) 2023, Linaro Limited
#include <linux/bitfield.h>
+#include <linux/clk.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
@@ -16,6 +17,9 @@
#define REFGEN_BIAS_EN_ENABLE 0x7
#define REFGEN_BIAS_EN_DISABLE 0x6
+#define REFGEN_REG_REFGEN_STATUS 0xc
+#define REFGEN_STATUS_OUT_MASK BIT(3)
+
#define REFGEN_REG_BG_CTRL 0x14
#define REFGEN_BG_CTRL_MASK GENMASK(2, 1)
#define REFGEN_BG_CTRL_ENABLE 0x3
@@ -25,6 +29,17 @@
#define REFGEN_PWRDWN_CTRL5_MASK BIT(0)
#define REFGEN_PWRDWN_CTRL5_ENABLE 0x1
+struct qcom_refgen_regulator_data {
+ const struct regulator_desc *rdesc;
+ bool has_clocks;
+};
+
+struct qcom_refgen_drvdata {
+ struct clk_bulk_data *clks;
+ int num_clks;
+ bool is_enabled;
+};
+
static int qcom_sdm845_refgen_enable(struct regulator_dev *rdev)
{
regmap_update_bits(rdev->regmap, REFGEN_REG_BG_CTRL, REFGEN_BG_CTRL_MASK,
@@ -62,11 +77,67 @@ static int qcom_sdm845_refgen_is_enabled(struct regulator_dev *rdev)
return 1;
}
+static int qcom_ipq9650_refgen_enable(struct regulator_dev *rdev)
+{
+ struct qcom_refgen_drvdata *drvdata = rdev_get_drvdata(rdev);
+ int ret;
+
+ ret = clk_bulk_prepare_enable(drvdata->num_clks, drvdata->clks);
+ if (ret)
+ return ret;
+
+ drvdata->is_enabled = true;
+
+ return 0;
+}
+
+static int qcom_ipq9650_refgen_disable(struct regulator_dev *rdev)
+{
+ struct qcom_refgen_drvdata *drvdata = rdev_get_drvdata(rdev);
+
+ clk_bulk_disable_unprepare(drvdata->num_clks, drvdata->clks);
+
+ drvdata->is_enabled = false;
+
+ return 0;
+}
+
+static int qcom_ipq9650_refgen_is_enabled(struct regulator_dev *rdev)
+{
+ struct qcom_refgen_drvdata *drvdata = rdev_get_drvdata(rdev);
+
+ return drvdata->is_enabled;
+}
+
+static int qcom_ipq9650_refgen_get_status(struct regulator_dev *rdev)
+{
+ u32 val;
+
+ regmap_read(rdev->regmap, REFGEN_REG_REFGEN_STATUS, &val);
+ if (FIELD_GET(REFGEN_STATUS_OUT_MASK, val))
+ return REGULATOR_STATUS_ON;
+
+ return REGULATOR_STATUS_OFF;
+}
+
+static const struct regulator_desc ipq9650_refgen_desc = {
+ .enable_time = 5,
+ .name = "refgen",
+ .owner = THIS_MODULE,
+ .type = REGULATOR_CURRENT,
+ .ops = &(const struct regulator_ops) {
+ .enable = qcom_ipq9650_refgen_enable,
+ .disable = qcom_ipq9650_refgen_disable,
+ .is_enabled = qcom_ipq9650_refgen_is_enabled,
+ .get_status = qcom_ipq9650_refgen_get_status,
+ },
+};
+
static const struct regulator_desc sdm845_refgen_desc = {
.enable_time = 5,
.name = "refgen",
.owner = THIS_MODULE,
- .type = REGULATOR_VOLTAGE,
+ .type = REGULATOR_CURRENT,
.ops = &(const struct regulator_ops) {
.enable = qcom_sdm845_refgen_enable,
.disable = qcom_sdm845_refgen_disable,
@@ -82,7 +153,7 @@ static const struct regulator_desc sm8250_refgen_desc = {
.enable_time = 5,
.name = "refgen",
.owner = THIS_MODULE,
- .type = REGULATOR_VOLTAGE,
+ .type = REGULATOR_CURRENT,
.ops = &(const struct regulator_ops) {
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
@@ -90,6 +161,19 @@ static const struct regulator_desc sm8250_refgen_desc = {
},
};
+static const struct qcom_refgen_regulator_data ipq9650_data = {
+ .rdesc = &ipq9650_refgen_desc,
+ .has_clocks = true,
+};
+
+static const struct qcom_refgen_regulator_data sdm845_data = {
+ .rdesc = &sdm845_refgen_desc,
+};
+
+static const struct qcom_refgen_regulator_data sm8250_data = {
+ .rdesc = &sm8250_refgen_desc,
+};
+
static const struct regmap_config qcom_refgen_regmap_config = {
.reg_bits = 32,
.reg_stride = 4,
@@ -98,6 +182,8 @@ static const struct regmap_config qcom_refgen_regmap_config = {
static int qcom_refgen_probe(struct platform_device *pdev)
{
+ const struct qcom_refgen_regulator_data *data;
+ struct qcom_refgen_drvdata *drvdata = NULL;
struct regulator_init_data *init_data;
struct regulator_config config = {};
const struct regulator_desc *rdesc;
@@ -106,10 +192,23 @@ static int qcom_refgen_probe(struct platform_device *pdev)
struct regmap *regmap;
void __iomem *base;
- rdesc = of_device_get_match_data(dev);
- if (!rdesc)
+ data = of_device_get_match_data(dev);
+ if (!data)
return -ENODATA;
+ if (data->has_clocks) {
+ drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
+ if (!drvdata)
+ return -ENOMEM;
+
+ drvdata->num_clks = devm_clk_bulk_get_all(dev, &drvdata->clks);
+ if (drvdata->num_clks < 0)
+ return dev_err_probe(dev, drvdata->num_clks,
+ "failed to get clocks\n");
+ }
+
+ rdesc = data->rdesc;
+
base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(base))
return PTR_ERR(base);
@@ -126,6 +225,7 @@ static int qcom_refgen_probe(struct platform_device *pdev)
config.init_data = init_data;
config.of_node = dev->of_node;
config.regmap = regmap;
+ config.driver_data = drvdata;
rdev = devm_regulator_register(dev, rdesc, &config);
if (IS_ERR(rdev))
@@ -135,8 +235,9 @@ static int qcom_refgen_probe(struct platform_device *pdev)
}
static const struct of_device_id qcom_refgen_match_table[] = {
- { .compatible = "qcom,sdm845-refgen-regulator", .data = &sdm845_refgen_desc },
- { .compatible = "qcom,sm8250-refgen-regulator", .data = &sm8250_refgen_desc },
+ { .compatible = "qcom,ipq9650-refgen-regulator", .data = &ipq9650_data },
+ { .compatible = "qcom,sdm845-refgen-regulator", .data = &sdm845_data },
+ { .compatible = "qcom,sm8250-refgen-regulator", .data = &sm8250_data },
{ }
};
MODULE_DEVICE_TABLE(of, qcom_refgen_match_table);
diff --git a/drivers/regulator/qcom-rpmh-regulator.c b/drivers/regulator/qcom-rpmh-regulator.c
index 73856e3df337..25c14de3cd8b 100644
--- a/drivers/regulator/qcom-rpmh-regulator.c
+++ b/drivers/regulator/qcom-rpmh-regulator.c
@@ -4,6 +4,7 @@
#define pr_fmt(fmt) "%s: " fmt, __func__
+#include <linux/bits.h>
#include <linux/err.h>
#include <linux/kernel.h>
#include <linux/module.h>
@@ -61,8 +62,13 @@ static const struct resource_name_formats vreg_rsc_name_lookup[NUM_REGULATOR_TYP
};
#define RPMH_REGULATOR_REG_VRM_VOLTAGE 0x0
+#define RPMH_REGULATOR_VOLTAGE_MASK GENMASK(12, 0)
+
#define RPMH_REGULATOR_REG_ENABLE 0x4
+#define RPMH_REGULATOR_ENABLE_MASK BIT(0)
+
#define RPMH_REGULATOR_REG_VRM_MODE 0x8
+#define RPMH_REGULATOR_MODE_MASK GENMASK(2, 0)
#define PMIC4_LDO_MODE_RETENTION 4
#define PMIC4_LDO_MODE_LPM 5
@@ -104,13 +110,14 @@ static const struct resource_name_formats vreg_rsc_name_lookup[NUM_REGULATOR_TYP
* regulator
* @ops: Pointer to regulator ops callback structure
* @voltage_ranges: The possible ranges of voltages supported by this
- * PMIC regulator type
+ * PMIC regulator type
* @n_linear_ranges: Number of entries in voltage_ranges
* @n_voltages: The number of unique voltage set points defined
* by voltage_ranges
* @hpm_min_load_uA: Minimum load current in microamps that requires
* high power mode (HPM) operation. This is used
* for LDO hardware type regulators only.
+ * @pmic_bypass_mode: The PMIC bypass mode value.
* @pmic_mode_map: Array indexed by regulator framework mode
* containing PMIC hardware modes. Must be large
* enough to index all framework modes supported
@@ -125,6 +132,7 @@ struct rpmh_vreg_hw_data {
int n_linear_ranges;
int n_voltages;
int hpm_min_load_uA;
+ int pmic_bypass_mode;
const int *pmic_mode_map;
unsigned int (*of_map_mode)(unsigned int mode);
};
@@ -246,9 +254,34 @@ static int rpmh_regulator_vrm_set_voltage_sel(struct regulator_dev *rdev,
selector > vreg->voltage_selector);
}
+static int _rpmh_regulator_vrm_get_voltage(struct regulator_dev *rdev, int *uV)
+{
+ struct rpmh_vreg *vreg = rdev_get_drvdata(rdev);
+ struct tcs_cmd cmd = {
+ .addr = vreg->addr + RPMH_REGULATOR_REG_VRM_VOLTAGE,
+ };
+ int ret;
+
+ ret = rpmh_read(vreg->dev, &cmd);
+ if (!ret)
+ *uV = (cmd.data & RPMH_REGULATOR_VOLTAGE_MASK) * 1000;
+ else
+ dev_err(vreg->dev, "failed to read VOLTAGE ret = %d\n", ret);
+
+ return ret;
+}
+
static int rpmh_regulator_vrm_get_voltage_sel(struct regulator_dev *rdev)
{
struct rpmh_vreg *vreg = rdev_get_drvdata(rdev);
+ int ret, uV = 0;
+
+ if (vreg->voltage_selector < 0) {
+ ret = _rpmh_regulator_vrm_get_voltage(rdev, &uV);
+ if (!ret && uV != 0)
+ vreg->voltage_selector = regulator_map_voltage_linear_range(rdev,
+ uV, INT_MAX);
+ }
return vreg->voltage_selector;
}
@@ -311,7 +344,7 @@ static int rpmh_regulator_vrm_set_mode_bypass(struct rpmh_vreg *vreg,
return pmic_mode;
if (bypassed)
- cmd.data = PMIC4_BOB_MODE_PASS;
+ cmd.data = vreg->hw_data->pmic_bypass_mode;
else
cmd.data = pmic_mode;
@@ -334,6 +367,22 @@ static int rpmh_regulator_vrm_set_mode(struct regulator_dev *rdev,
return ret;
}
+static int rpmh_regulator_vrm_get_pmic_mode(struct rpmh_vreg *vreg, int *pmic_mode)
+{
+ struct tcs_cmd cmd = {
+ .addr = vreg->addr + RPMH_REGULATOR_REG_VRM_MODE,
+ };
+ int ret;
+
+ ret = rpmh_read(vreg->dev, &cmd);
+ if (!ret)
+ *pmic_mode = cmd.data & RPMH_REGULATOR_MODE_MASK;
+ else
+ return -EINVAL;
+
+ return 0;
+}
+
static unsigned int rpmh_regulator_vrm_get_mode(struct regulator_dev *rdev)
{
struct rpmh_vreg *vreg = rdev_get_drvdata(rdev);
@@ -538,6 +587,73 @@ static int rpmh_regulator_init_vreg(struct rpmh_vreg *vreg, struct device *dev,
return 0;
}
+static int rpmh_regulator_determine_initial_mode(struct rpmh_vreg *vreg)
+{
+ struct tcs_cmd cmd = {
+ .addr = vreg->addr + RPMH_REGULATOR_REG_ENABLE,
+ };
+ int ret, pmic_mode, mode;
+ int sts;
+
+ ret = rpmh_read(vreg->dev, &cmd);
+ if (ret) {
+ dev_err(vreg->dev, "failed to read ENABLE status ret = %d\n", ret);
+
+ return ret;
+ }
+
+ sts = cmd.data & RPMH_REGULATOR_ENABLE_MASK;
+ if (!sts)
+ return 0;
+
+ if (vreg->hw_data->regulator_type == XOB)
+ return 0;
+
+ ret = rpmh_regulator_vrm_get_pmic_mode(vreg, &pmic_mode);
+ if (ret < 0) {
+ vreg->mode = REGULATOR_MODE_INVALID;
+ dev_err(vreg->dev, "failed to read pmic_mode ret = %d\n", ret);
+
+ return ret;
+ }
+
+ /*
+ * NOTE: Since BOB4 BYPASS_MODE value = 0 we cannot confirm if that BOB
+ * regulator has been sent into bypass mode by bootloader or if bootloader
+ * just has not requested for any mode voting. Due this limitation, we
+ * must check if the read pmic_mode value is non-zero before comparing it
+ * to bypass mode value. This also is needed to avoid setting BYPASS status
+ * for LDOs which dont support bypass mode, and have the pmic_bypass_mode
+ * uninitialized value as zero in the vreg hw data. For such cases assume
+ * lowest mode, if pmic_mode is zero, to allow for mode voting.
+ */
+ if (!pmic_mode) {
+ for (mode = REGULATOR_MODE_STANDBY; mode > REGULATOR_MODE_INVALID; mode >>= 1) {
+ if (vreg->hw_data->pmic_mode_map[mode] >= 0) {
+ vreg->mode = mode;
+ break;
+ }
+ }
+
+ return 0;
+ }
+
+ if (vreg->hw_data->pmic_bypass_mode == pmic_mode) {
+ vreg->bypassed = true;
+
+ return 0;
+ }
+
+ for (mode = REGULATOR_MODE_STANDBY; mode > REGULATOR_MODE_INVALID; mode >>= 1) {
+ if (pmic_mode == vreg->hw_data->pmic_mode_map[mode]) {
+ vreg->mode = mode;
+ break;
+ }
+ }
+
+ return 0;
+}
+
static const int pmic_mode_map_pmic4_ldo[REGULATOR_MODE_STANDBY + 1] = {
[REGULATOR_MODE_INVALID] = -EINVAL,
[REGULATOR_MODE_STANDBY] = PMIC4_LDO_MODE_RETENTION,
@@ -767,6 +883,7 @@ static const struct rpmh_vreg_hw_data pmic4_bob = {
},
.n_linear_ranges = 1,
.n_voltages = 84,
+ .pmic_bypass_mode = PMIC4_BOB_MODE_PASS,
.pmic_mode_map = pmic_mode_map_pmic4_bob,
.of_map_mode = rpmh_regulator_pmic4_bob_of_map_mode,
};
@@ -975,6 +1092,7 @@ static const struct rpmh_vreg_hw_data pmic5_bob = {
},
.n_linear_ranges = 1,
.n_voltages = 32,
+ .pmic_bypass_mode = PMIC5_BOB_MODE_PASS,
.pmic_mode_map = pmic_mode_map_pmic5_bob,
.of_map_mode = rpmh_regulator_pmic4_bob_of_map_mode,
};
@@ -1839,6 +1957,12 @@ static int rpmh_regulator_probe(struct platform_device *pdev)
vreg_data);
if (ret < 0)
return ret;
+
+ ret = rpmh_regulator_determine_initial_mode(vreg);
+ if (ret < 0)
+ dev_err(dev, "failed to read initial mode for %s\n",
+ vreg->rdesc.name);
+
}
return 0;
diff --git a/drivers/regulator/qcom_usb_vbus-regulator.c b/drivers/regulator/qcom_usb_vbus-regulator.c
index cd94ed67621f..9aea68876284 100644
--- a/drivers/regulator/qcom_usb_vbus-regulator.c
+++ b/drivers/regulator/qcom_usb_vbus-regulator.c
@@ -20,10 +20,35 @@
#define OTG_CFG 0x53
#define OTG_EN_SRC_CFG BIT(1)
+#define PM4125_VBOOST_EN 0x50
+#define PM4125_VBOOST_SEL 0x52
+#define PM4125_VBOOST_CFG_MASK GENMASK(1, 0)
+#define PM4125_VBOOST_CFG 0x56
+#define PM4125_VBOOST_EN_SRC_CFG BIT(0)
+
+struct qcom_usb_vbus_reg_data {
+ u16 cmd_otg;
+ u16 otg_cfg;
+ u8 otg_en_src_cfg;
+ u16 csel_reg;
+ u8 csel_mask;
+ const unsigned int *curr_table;
+ unsigned int n_current_limits;
+ u16 vsel_reg;
+ u8 vsel_mask;
+ const unsigned int *volt_table;
+ unsigned int n_voltages;
+ const struct regulator_ops *ops;
+};
+
static const unsigned int curr_table[] = {
500000, 1000000, 1500000, 2000000, 2500000, 3000000,
};
+static const unsigned int pm4125_vboost_table[] = {
+ 4250000, 4500000, 4750000, 5000000,
+};
+
static const struct regulator_ops qcom_usb_vbus_reg_ops = {
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
@@ -32,19 +57,43 @@ static const struct regulator_ops qcom_usb_vbus_reg_ops = {
.set_current_limit = regulator_set_current_limit_regmap,
};
-static struct regulator_desc qcom_usb_vbus_rdesc = {
- .name = "usb_vbus",
- .ops = &qcom_usb_vbus_reg_ops,
- .owner = THIS_MODULE,
- .type = REGULATOR_VOLTAGE,
+static const struct qcom_usb_vbus_reg_data pm8150b_data = {
+ .cmd_otg = CMD_OTG,
+ .otg_cfg = OTG_CFG,
+ .otg_en_src_cfg = OTG_EN_SRC_CFG,
+ .csel_reg = OTG_CURRENT_LIMIT_CFG,
+ .csel_mask = OTG_CURRENT_LIMIT_MASK,
.curr_table = curr_table,
.n_current_limits = ARRAY_SIZE(curr_table),
+ .ops = &qcom_usb_vbus_reg_ops,
+};
+
+static const struct regulator_ops qcom_usb_vbus_pm4125_reg_ops = {
+ .enable = regulator_enable_regmap,
+ .disable = regulator_disable_regmap,
+ .is_enabled = regulator_is_enabled_regmap,
+ .get_voltage_sel = regulator_get_voltage_sel_regmap,
+ .set_voltage_sel = regulator_set_voltage_sel_regmap,
+ .list_voltage = regulator_list_voltage_table,
+};
+
+static const struct qcom_usb_vbus_reg_data pm4125_data = {
+ .cmd_otg = PM4125_VBOOST_EN,
+ .otg_cfg = PM4125_VBOOST_CFG,
+ .otg_en_src_cfg = PM4125_VBOOST_EN_SRC_CFG,
+ .vsel_reg = PM4125_VBOOST_SEL,
+ .vsel_mask = PM4125_VBOOST_CFG_MASK,
+ .volt_table = pm4125_vboost_table,
+ .n_voltages = ARRAY_SIZE(pm4125_vboost_table),
+ .ops = &qcom_usb_vbus_pm4125_reg_ops,
};
static int qcom_usb_vbus_regulator_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
+ const struct qcom_usb_vbus_reg_data *data;
struct regulator_dev *rdev;
+ struct regulator_desc *rdesc;
struct regmap *regmap;
struct regulator_config config = { };
struct regulator_init_data *init_data;
@@ -57,27 +106,51 @@ static int qcom_usb_vbus_regulator_probe(struct platform_device *pdev)
return ret;
}
+ data = of_device_get_match_data(dev);
+ if (!data)
+ return -EINVAL;
+
regmap = dev_get_regmap(dev->parent, NULL);
if (!regmap) {
dev_err(dev, "Failed to get regmap\n");
return -ENOENT;
}
- init_data = of_get_regulator_init_data(dev, dev->of_node,
- &qcom_usb_vbus_rdesc);
+ rdesc = devm_kzalloc(dev, sizeof(*rdesc), GFP_KERNEL);
+ if (!rdesc)
+ return -ENOMEM;
+
+ rdesc->name = "usb_vbus";
+ rdesc->ops = data->ops;
+ rdesc->owner = THIS_MODULE;
+ rdesc->type = REGULATOR_VOLTAGE;
+ rdesc->enable_reg = base + data->cmd_otg;
+ rdesc->enable_mask = OTG_EN;
+
+ if (data->curr_table) {
+ rdesc->curr_table = data->curr_table;
+ rdesc->n_current_limits = data->n_current_limits;
+ rdesc->csel_reg = base + data->csel_reg;
+ rdesc->csel_mask = data->csel_mask;
+ }
+
+ if (data->volt_table) {
+ rdesc->volt_table = data->volt_table;
+ rdesc->n_voltages = data->n_voltages;
+ rdesc->vsel_reg = base + data->vsel_reg;
+ rdesc->vsel_mask = data->vsel_mask;
+ }
+
+ init_data = of_get_regulator_init_data(dev, dev->of_node, rdesc);
if (!init_data)
return -ENOMEM;
- qcom_usb_vbus_rdesc.enable_reg = base + CMD_OTG;
- qcom_usb_vbus_rdesc.enable_mask = OTG_EN;
- qcom_usb_vbus_rdesc.csel_reg = base + OTG_CURRENT_LIMIT_CFG;
- qcom_usb_vbus_rdesc.csel_mask = OTG_CURRENT_LIMIT_MASK;
config.dev = dev;
config.init_data = init_data;
config.of_node = dev->of_node;
config.regmap = regmap;
- rdev = devm_regulator_register(dev, &qcom_usb_vbus_rdesc, &config);
+ rdev = devm_regulator_register(dev, rdesc, &config);
if (IS_ERR(rdev)) {
ret = PTR_ERR(rdev);
dev_err(dev, "not able to register vbus reg %d\n", ret);
@@ -85,13 +158,14 @@ static int qcom_usb_vbus_regulator_probe(struct platform_device *pdev)
}
/* Disable HW logic for VBUS enable */
- regmap_update_bits(regmap, base + OTG_CFG, OTG_EN_SRC_CFG, 0);
+ regmap_update_bits(regmap, base + data->otg_cfg, data->otg_en_src_cfg, 0);
return 0;
}
static const struct of_device_id qcom_usb_vbus_regulator_match[] = {
- { .compatible = "qcom,pm8150b-vbus-reg" },
+ { .compatible = "qcom,pm8150b-vbus-reg", .data = &pm8150b_data },
+ { .compatible = "qcom,pm4125-vbus-reg", .data = &pm4125_data },
{ }
};
MODULE_DEVICE_TABLE(of, qcom_usb_vbus_regulator_match);
diff --git a/drivers/regulator/rt6245-regulator.c b/drivers/regulator/rt6245-regulator.c
index 1843ecec1922..5c0ee04e97ac 100644
--- a/drivers/regulator/rt6245-regulator.c
+++ b/drivers/regulator/rt6245-regulator.c
@@ -49,8 +49,11 @@ static int rt6245_enable(struct regulator_dev *rdev)
regcache_cache_only(regmap, false);
ret = regcache_sync(regmap);
- if (ret)
+ if (ret) {
+ regcache_cache_only(regmap, true);
+ gpiod_direction_output(priv->enable_gpio, 0);
return ret;
+ }
priv->enable_state = true;
return 0;
diff --git a/drivers/regulator/rtq2208-regulator.c b/drivers/regulator/rtq2208-regulator.c
index 4fe111aa018f..b4eb5d3eb5bd 100644
--- a/drivers/regulator/rtq2208-regulator.c
+++ b/drivers/regulator/rtq2208-regulator.c
@@ -11,6 +11,7 @@
#include <linux/regulator/of_regulator.h>
/* Register */
+#define RTQ2208_REG_FSOUTB_CNTL 0x11
#define RTQ2208_REG_GLOBAL_INT1 0x12
#define RTQ2208_REG_FLT_RECORDBUCK_CB 0x18
#define RTQ2208_REG_GLOBAL_INT1_MASK 0x1D
@@ -33,6 +34,7 @@
#define RTQ2208_REG_HIDDEN1 0xFF
/* Mask */
+#define RTQ2208_MTP_SEL_RO_MASK BIT(7)
#define RTQ2208_BUCK_NR_MTP_SEL_MASK GENMASK(7, 0)
#define RTQ2208_BUCK_EN_NR_MTP_SEL0_MASK BIT(0)
#define RTQ2208_BUCK_EN_NR_MTP_SEL1_MASK BIT(1)
@@ -464,10 +466,13 @@ static int rtq2208_parse_regulator_dt_data(int n_regulator, const unsigned int *
struct rtq2208_regulator_desc *rdesc[RTQ2208_LDO_MAX], struct device *dev,
unsigned int ldo1_fixed, unsigned int ldo2_fixed)
{
+ struct regmap *regmap = dev_get_regmap(dev, NULL);
int mtp_sel, i, idx;
/* get mtp_sel0 or mtp_sel1 */
- mtp_sel = device_property_read_bool(dev, "richtek,mtp-sel-high");
+ mtp_sel = regmap_test_bits(regmap, RTQ2208_REG_FSOUTB_CNTL, RTQ2208_MTP_SEL_RO_MASK);
+ if (mtp_sel < 0)
+ return dev_err_probe(dev, mtp_sel, "Failed to init mtp_sel state\n");
for (i = 0; i < n_regulator; i++) {
idx = regulator_idx_table[i];
diff --git a/drivers/regulator/sc2730-regulator.c b/drivers/regulator/sc2730-regulator.c
new file mode 100644
index 000000000000..166b19ed539b
--- /dev/null
+++ b/drivers/regulator/sc2730-regulator.c
@@ -0,0 +1,375 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2018-2021 Unisoc Inc.
+ */
+
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/of_regulator.h>
+
+/*
+ * SC2730 regulator base address
+ */
+#define SC2730_REGULATOR_BASE 0x1800
+
+/*
+ * SC2730 regulator lock register
+ */
+#define SC2730_WR_UNLOCK_VALUE 0x6e7f
+#define SC2730_PWR_WR_PROT (SC2730_REGULATOR_BASE + 0x3d0)
+
+/*
+ * SC2730 enable register
+ */
+#define SC2730_POWER_PD_SW (SC2730_REGULATOR_BASE + 0x01c)
+#define SC2730_LDO_VDDRF18_PD (SC2730_REGULATOR_BASE + 0x10c)
+#define SC2730_LDO_VDDCAMIO_PD (SC2730_REGULATOR_BASE + 0x118)
+#define SC2730_LDO_VDDWCN_PD (SC2730_REGULATOR_BASE + 0x11c)
+#define SC2730_LDO_VDDCAMD1_PD (SC2730_REGULATOR_BASE + 0x128)
+#define SC2730_LDO_VDDCAMD0_PD (SC2730_REGULATOR_BASE + 0x134)
+#define SC2730_LDO_VDDRF1V25_PD (SC2730_REGULATOR_BASE + 0x140)
+#define SC2730_LDO_AVDD12_PD (SC2730_REGULATOR_BASE + 0x14c)
+#define SC2730_LDO_VDDCAMA0_PD (SC2730_REGULATOR_BASE + 0x158)
+#define SC2730_LDO_VDDCAMA1_PD (SC2730_REGULATOR_BASE + 0x164)
+#define SC2730_LDO_VDDCAMMOT_PD (SC2730_REGULATOR_BASE + 0x170)
+#define SC2730_LDO_VDDSIM2_PD (SC2730_REGULATOR_BASE + 0x194)
+#define SC2730_LDO_VDDEMMCCORE_PD (SC2730_REGULATOR_BASE + 0x1a0)
+#define SC2730_LDO_VDDSDCORE_PD (SC2730_REGULATOR_BASE + 0x1ac)
+#define SC2730_LDO_VDDSDIO_PD (SC2730_REGULATOR_BASE + 0x1b8)
+#define SC2730_LDO_VDDWIFIPA_PD (SC2730_REGULATOR_BASE + 0x1d0)
+#define SC2730_LDO_VDDUSB33_PD (SC2730_REGULATOR_BASE + 0x1e8)
+#define SC2730_LDO_VDDLDO0_PD (SC2730_REGULATOR_BASE + 0x1f4)
+#define SC2730_LDO_VDDLDO1_PD (SC2730_REGULATOR_BASE + 0x200)
+#define SC2730_LDO_VDDLDO2_PD (SC2730_REGULATOR_BASE + 0x20c)
+#define SC2730_LDO_VDDKPLED_PD (SC2730_REGULATOR_BASE + 0x38c)
+
+/*
+ * SC2730 enable mask
+ */
+#define SC2730_DCDC_CPU_PD_MASK BIT(4)
+#define SC2730_DCDC_GPU_PD_MASK BIT(3)
+#define SC2730_DCDC_CORE_PD_MASK BIT(5)
+#define SC2730_DCDC_MODEM_PD_MASK BIT(11)
+#define SC2730_DCDC_MEM_PD_MASK BIT(6)
+#define SC2730_DCDC_MEMQ_PD_MASK BIT(12)
+#define SC2730_DCDC_GEN0_PD_MASK BIT(8)
+#define SC2730_DCDC_GEN1_PD_MASK BIT(7)
+#define SC2730_DCDC_SRAM_PD_MASK BIT(13)
+#define SC2730_LDO_AVDD18_PD_MASK BIT(2)
+#define SC2730_LDO_VDDRF18_PD_MASK BIT(0)
+#define SC2730_LDO_VDDCAMIO_PD_MASK BIT(0)
+#define SC2730_LDO_VDDWCN_PD_MASK BIT(0)
+#define SC2730_LDO_VDDCAMD1_PD_MASK BIT(0)
+#define SC2730_LDO_VDDCAMD0_PD_MASK BIT(0)
+#define SC2730_LDO_VDDRF1V25_PD_MASK BIT(0)
+#define SC2730_LDO_AVDD12_PD_MASK BIT(0)
+#define SC2730_LDO_VDDCAMA0_PD_MASK BIT(0)
+#define SC2730_LDO_VDDCAMA1_PD_MASK BIT(0)
+#define SC2730_LDO_VDDCAMMOT_PD_MASK BIT(0)
+#define SC2730_LDO_VDDSIM2_PD_MASK BIT(0)
+#define SC2730_LDO_VDDEMMCCORE_PD_MASK BIT(0)
+#define SC2730_LDO_VDDSDCORE_PD_MASK BIT(0)
+#define SC2730_LDO_VDDSDIO_PD_MASK BIT(0)
+#define SC2730_LDO_VDD28_PD_MASK BIT(1)
+#define SC2730_LDO_VDDWIFIPA_PD_MASK BIT(0)
+#define SC2730_LDO_VDD18_DCXO_PD_MASK BIT(10)
+#define SC2730_LDO_VDDUSB33_PD_MASK BIT(0)
+#define SC2730_LDO_VDDLDO0_PD_MASK BIT(0)
+#define SC2730_LDO_VDDLDO1_PD_MASK BIT(0)
+#define SC2730_LDO_VDDLDO2_PD_MASK BIT(0)
+#define SC2730_LDO_VDDKPLED_PD_MASK BIT(15)
+
+/*
+ * SC2730 vsel register
+ */
+#define SC2730_DCDC_CPU_VOL (SC2730_REGULATOR_BASE + 0x44)
+#define SC2730_DCDC_GPU_VOL (SC2730_REGULATOR_BASE + 0x54)
+#define SC2730_DCDC_CORE_VOL (SC2730_REGULATOR_BASE + 0x64)
+#define SC2730_DCDC_MODEM_VOL (SC2730_REGULATOR_BASE + 0x74)
+#define SC2730_DCDC_MEM_VOL (SC2730_REGULATOR_BASE + 0x84)
+#define SC2730_DCDC_MEMQ_VOL (SC2730_REGULATOR_BASE + 0x94)
+#define SC2730_DCDC_GEN0_VOL (SC2730_REGULATOR_BASE + 0xa4)
+#define SC2730_DCDC_GEN1_VOL (SC2730_REGULATOR_BASE + 0xb4)
+#define SC2730_DCDC_SRAM_VOL (SC2730_REGULATOR_BASE + 0xdc)
+#define SC2730_LDO_AVDD18_VOL (SC2730_REGULATOR_BASE + 0x104)
+#define SC2730_LDO_VDDRF18_VOL (SC2730_REGULATOR_BASE + 0x110)
+#define SC2730_LDO_VDDCAMIO_VOL (SC2730_REGULATOR_BASE + 0x28)
+#define SC2730_LDO_VDDWCN_VOL (SC2730_REGULATOR_BASE + 0x120)
+#define SC2730_LDO_VDDCAMD1_VOL (SC2730_REGULATOR_BASE + 0x12c)
+#define SC2730_LDO_VDDCAMD0_VOL (SC2730_REGULATOR_BASE + 0x138)
+#define SC2730_LDO_VDDRF1V25_VOL (SC2730_REGULATOR_BASE + 0x144)
+#define SC2730_LDO_AVDD12_VOL (SC2730_REGULATOR_BASE + 0x150)
+#define SC2730_LDO_VDDCAMA0_VOL (SC2730_REGULATOR_BASE + 0x15c)
+#define SC2730_LDO_VDDCAMA1_VOL (SC2730_REGULATOR_BASE + 0x168)
+#define SC2730_LDO_VDDCAMMOT_VOL (SC2730_REGULATOR_BASE + 0x174)
+#define SC2730_LDO_VDDSIM2_VOL (SC2730_REGULATOR_BASE + 0x198)
+#define SC2730_LDO_VDDEMMCCORE_VOL (SC2730_REGULATOR_BASE + 0x1a4)
+#define SC2730_LDO_VDDSDCORE_VOL (SC2730_REGULATOR_BASE + 0x1b0)
+#define SC2730_LDO_VDDSDIO_VOL (SC2730_REGULATOR_BASE + 0x1bc)
+#define SC2730_LDO_VDD28_VOL (SC2730_REGULATOR_BASE + 0x1c8)
+#define SC2730_LDO_VDDWIFIPA_VOL (SC2730_REGULATOR_BASE + 0x1d4)
+#define SC2730_LDO_VDD18_DCXO_VOL (SC2730_REGULATOR_BASE + 0x1e0)
+#define SC2730_LDO_VDDUSB33_VOL (SC2730_REGULATOR_BASE + 0x1ec)
+#define SC2730_LDO_VDDLDO0_VOL (SC2730_REGULATOR_BASE + 0x1f8)
+#define SC2730_LDO_VDDLDO1_VOL (SC2730_REGULATOR_BASE + 0x204)
+#define SC2730_LDO_VDDLDO2_VOL (SC2730_REGULATOR_BASE + 0x210)
+#define SC2730_LDO_VDDKPLED_VOL (SC2730_REGULATOR_BASE + 0x38c)
+
+/*
+ * SC2730 vsel register mask
+ */
+#define SC2730_DCDC_CPU_VOL_MASK GENMASK(8, 0)
+#define SC2730_DCDC_GPU_VOL_MASK GENMASK(8, 0)
+#define SC2730_DCDC_CORE_VOL_MASK GENMASK(8, 0)
+#define SC2730_DCDC_MODEM_VOL_MASK GENMASK(8, 0)
+#define SC2730_DCDC_MEM_VOL_MASK GENMASK(7, 0)
+#define SC2730_DCDC_MEMQ_VOL_MASK GENMASK(8, 0)
+#define SC2730_DCDC_GEN0_VOL_MASK GENMASK(7, 0)
+#define SC2730_DCDC_GEN1_VOL_MASK GENMASK(7, 0)
+#define SC2730_DCDC_SRAM_VOL_MASK GENMASK(8, 0)
+#define SC2730_LDO_AVDD18_VOL_MASK GENMASK(5, 0)
+#define SC2730_LDO_VDDRF18_VOL_MASK GENMASK(5, 0)
+#define SC2730_LDO_VDDCAMIO_VOL_MASK GENMASK(5, 0)
+#define SC2730_LDO_VDDWCN_VOL_MASK GENMASK(5, 0)
+#define SC2730_LDO_VDDCAMD1_VOL_MASK GENMASK(4, 0)
+#define SC2730_LDO_VDDCAMD0_VOL_MASK GENMASK(4, 0)
+#define SC2730_LDO_VDDRF1V25_VOL_MASK GENMASK(4, 0)
+#define SC2730_LDO_AVDD12_VOL_MASK GENMASK(4, 0)
+#define SC2730_LDO_VDDCAMA0_VOL_MASK GENMASK(7, 0)
+#define SC2730_LDO_VDDCAMA1_VOL_MASK GENMASK(7, 0)
+#define SC2730_LDO_VDDCAMMOT_VOL_MASK GENMASK(7, 0)
+#define SC2730_LDO_VDDSIM2_VOL_MASK GENMASK(7, 0)
+#define SC2730_LDO_VDDEMMCCORE_VOL_MASK GENMASK(7, 0)
+#define SC2730_LDO_VDDSDCORE_VOL_MASK GENMASK(7, 0)
+#define SC2730_LDO_VDDSDIO_VOL_MASK GENMASK(7, 0)
+#define SC2730_LDO_VDD28_VOL_MASK GENMASK(7, 0)
+#define SC2730_LDO_VDDWIFIPA_VOL_MASK GENMASK(7, 0)
+#define SC2730_LDO_VDD18_DCXO_VOL_MASK GENMASK(7, 0)
+#define SC2730_LDO_VDDUSB33_VOL_MASK GENMASK(7, 0)
+#define SC2730_LDO_VDDLDO0_VOL_MASK GENMASK(7, 0)
+#define SC2730_LDO_VDDLDO1_VOL_MASK GENMASK(7, 0)
+#define SC2730_LDO_VDDLDO2_VOL_MASK GENMASK(7, 0)
+#define SC2730_LDO_VDDKPLED_VOL_MASK GENMASK(14, 7)
+
+enum sc2730_regulator_id {
+ SC2730_DCDC_CPU,
+ SC2730_DCDC_GPU,
+ SC2730_DCDC_CORE,
+ SC2730_DCDC_MODEM,
+ SC2730_DCDC_MEM,
+ SC2730_DCDC_MEMQ,
+ SC2730_DCDC_GEN0,
+ SC2730_DCDC_GEN1,
+ SC2730_DCDC_SRAM,
+ SC2730_LDO_AVDD18,
+ SC2730_LDO_VDDRF18,
+ SC2730_LDO_VDDCAMIO,
+ SC2730_LDO_VDDWCN,
+ SC2730_LDO_VDDCAMD1,
+ SC2730_LDO_VDDCAMD0,
+ SC2730_LDO_VDDRF1V25,
+ SC2730_LDO_AVDD12,
+ SC2730_LDO_VDDCAMA0,
+ SC2730_LDO_VDDCAMA1,
+ SC2730_LDO_VDDCAMMOT,
+ SC2730_LDO_VDDSIM2,
+ SC2730_LDO_VDDEMMCCORE,
+ SC2730_LDO_VDDSDCORE,
+ SC2730_LDO_VDDSDIO,
+ SC2730_LDO_VDD28,
+ SC2730_LDO_VDDWIFIPA,
+ SC2730_LDO_VDD18_DCXO,
+ SC2730_LDO_VDDUSB33,
+ SC2730_LDO_VDDLDO0,
+ SC2730_LDO_VDDLDO1,
+ SC2730_LDO_VDDLDO2,
+ SC2730_LDO_VDDKPLED,
+};
+
+static const struct regulator_ops sc2730_regu_linear_ops = {
+ .enable = regulator_enable_regmap,
+ .disable = regulator_disable_regmap,
+ .is_enabled = regulator_is_enabled_regmap,
+ .list_voltage = regulator_list_voltage_linear,
+ .get_voltage_sel = regulator_get_voltage_sel_regmap,
+ .set_voltage_sel = regulator_set_voltage_sel_regmap,
+};
+
+#define SC2730_REGU_LINEAR(_id, of_name, en_reg, en_mask, vreg, vmask, \
+ vstep, vmin, vmax) { \
+ .name = #_id, \
+ .of_match = of_name, \
+ .regulators_node = "regulators", \
+ .ops = &sc2730_regu_linear_ops, \
+ .type = REGULATOR_VOLTAGE, \
+ .id = SC2730_##_id, \
+ .owner = THIS_MODULE, \
+ .min_uV = vmin, \
+ .n_voltages = ((vmax) - (vmin)) / (vstep) + 1, \
+ .uV_step = vstep, \
+ .enable_is_inverted = true, \
+ .enable_val = 0, \
+ .enable_reg = en_reg, \
+ .enable_mask = en_mask, \
+ .vsel_reg = vreg, \
+ .vsel_mask = vmask, \
+ .linear_min_sel = 0, \
+}
+
+static const struct regulator_desc regulators[] = {
+ SC2730_REGU_LINEAR(DCDC_CPU, "dcdc-cpu", SC2730_POWER_PD_SW,
+ SC2730_DCDC_CPU_PD_MASK, SC2730_DCDC_CPU_VOL,
+ SC2730_DCDC_CPU_VOL_MASK, 3125, 0, 1596875),
+ SC2730_REGU_LINEAR(DCDC_GPU, "dcdc-gpu", SC2730_POWER_PD_SW,
+ SC2730_DCDC_GPU_PD_MASK, SC2730_DCDC_GPU_VOL,
+ SC2730_DCDC_GPU_VOL_MASK, 3125, 0, 1596875),
+ SC2730_REGU_LINEAR(DCDC_CORE, "dcdc-core", SC2730_POWER_PD_SW,
+ SC2730_DCDC_CORE_PD_MASK, SC2730_DCDC_CORE_VOL,
+ SC2730_DCDC_CORE_VOL_MASK, 3125, 0, 1596875),
+ SC2730_REGU_LINEAR(DCDC_MODEM, "dcdc-modem", SC2730_POWER_PD_SW,
+ SC2730_DCDC_MODEM_PD_MASK, SC2730_DCDC_MODEM_VOL,
+ SC2730_DCDC_MODEM_VOL_MASK, 3125, 0, 1596875),
+ SC2730_REGU_LINEAR(DCDC_MEM, "dcdc-mem", SC2730_POWER_PD_SW,
+ SC2730_DCDC_MEM_PD_MASK, SC2730_DCDC_MEM_VOL,
+ SC2730_DCDC_MEM_VOL_MASK, 6250, 0, 1593750),
+ SC2730_REGU_LINEAR(DCDC_MEMQ, "dcdc-memq", SC2730_POWER_PD_SW,
+ SC2730_DCDC_MEMQ_PD_MASK, SC2730_DCDC_MEMQ_VOL,
+ SC2730_DCDC_MEMQ_VOL_MASK, 3125, 0, 1596875),
+ SC2730_REGU_LINEAR(DCDC_GEN0, "dcdc-gen0", SC2730_POWER_PD_SW,
+ SC2730_DCDC_GEN0_PD_MASK, SC2730_DCDC_GEN0_VOL,
+ SC2730_DCDC_GEN0_VOL_MASK, 9375, 20000, 2410625),
+ SC2730_REGU_LINEAR(DCDC_GEN1, "dcdc-gen1", SC2730_POWER_PD_SW,
+ SC2730_DCDC_GEN1_PD_MASK, SC2730_DCDC_GEN1_VOL,
+ SC2730_DCDC_GEN1_VOL_MASK, 6250, 50000, 1643750),
+ SC2730_REGU_LINEAR(DCDC_SRAM, "dcdc-sram", SC2730_POWER_PD_SW,
+ SC2730_DCDC_SRAM_PD_MASK, SC2730_DCDC_SRAM_VOL,
+ SC2730_DCDC_SRAM_VOL_MASK, 3125, 0, 1596875),
+ SC2730_REGU_LINEAR(LDO_AVDD18, "ldo-avdd18", SC2730_POWER_PD_SW,
+ SC2730_LDO_AVDD18_PD_MASK, SC2730_LDO_AVDD18_VOL,
+ SC2730_LDO_AVDD18_VOL_MASK, 10000, 1175000, 1805000),
+ SC2730_REGU_LINEAR(LDO_VDDRF18, "ldo-vddrf18", SC2730_LDO_VDDRF18_PD,
+ SC2730_LDO_VDDRF18_PD_MASK, SC2730_LDO_VDDRF18_VOL,
+ SC2730_LDO_VDDRF18_VOL_MASK, 10000, 1175000, 1805000),
+ SC2730_REGU_LINEAR(LDO_VDDCAMIO, "ldo-vddcamio", SC2730_LDO_VDDCAMIO_PD,
+ SC2730_LDO_VDDCAMIO_PD_MASK, SC2730_LDO_VDDCAMIO_VOL,
+ SC2730_LDO_VDDCAMIO_VOL_MASK, 10000, 1200000, 1830000),
+ SC2730_REGU_LINEAR(LDO_VDDWCN, "ldo-vddwcn", SC2730_LDO_VDDWCN_PD,
+ SC2730_LDO_VDDWCN_PD_MASK, SC2730_LDO_VDDWCN_VOL,
+ SC2730_LDO_VDDWCN_VOL_MASK, 15000, 900000, 1845000),
+ SC2730_REGU_LINEAR(LDO_VDDCAMD1, "ldo-vddcamd1", SC2730_LDO_VDDCAMD1_PD,
+ SC2730_LDO_VDDCAMD1_PD_MASK, SC2730_LDO_VDDCAMD1_VOL,
+ SC2730_LDO_VDDCAMD1_VOL_MASK, 15000, 900000, 1365000),
+ SC2730_REGU_LINEAR(LDO_VDDCAMD0, "ldo-vddcamd0", SC2730_LDO_VDDCAMD0_PD,
+ SC2730_LDO_VDDCAMD0_PD_MASK, SC2730_LDO_VDDCAMD0_VOL,
+ SC2730_LDO_VDDCAMD0_VOL_MASK, 15000, 900000, 1365000),
+ SC2730_REGU_LINEAR(LDO_VDDRF1V25, "ldo-vddrf1v25", SC2730_LDO_VDDRF1V25_PD,
+ SC2730_LDO_VDDRF1V25_PD_MASK, SC2730_LDO_VDDRF1V25_VOL,
+ SC2730_LDO_VDDRF1V25_VOL_MASK, 15000, 900000, 1365000),
+ SC2730_REGU_LINEAR(LDO_AVDD12, "ldo-avdd12", SC2730_LDO_AVDD12_PD,
+ SC2730_LDO_AVDD12_PD_MASK, SC2730_LDO_AVDD12_VOL,
+ SC2730_LDO_AVDD12_VOL_MASK, 15000, 900000, 1365000),
+ SC2730_REGU_LINEAR(LDO_VDDCAMA0, "ldo-vddcama0", SC2730_LDO_VDDCAMA0_PD,
+ SC2730_LDO_VDDCAMA0_PD_MASK, SC2730_LDO_VDDCAMA0_VOL,
+ SC2730_LDO_VDDCAMA0_VOL_MASK, 10000, 1200000, 3750000),
+ SC2730_REGU_LINEAR(LDO_VDDCAMA1, "ldo-vddcama1", SC2730_LDO_VDDCAMA1_PD,
+ SC2730_LDO_VDDCAMA1_PD_MASK, SC2730_LDO_VDDCAMA1_VOL,
+ SC2730_LDO_VDDCAMA1_VOL_MASK, 10000, 1200000, 3750000),
+ SC2730_REGU_LINEAR(LDO_VDDCAMMOT, "ldo-vddcammot", SC2730_LDO_VDDCAMMOT_PD,
+ SC2730_LDO_VDDCAMMOT_PD_MASK, SC2730_LDO_VDDCAMMOT_VOL,
+ SC2730_LDO_VDDCAMMOT_VOL_MASK, 10000, 1200000, 3750000),
+ SC2730_REGU_LINEAR(LDO_VDDSIM2, "ldo-vddsim2", SC2730_LDO_VDDSIM2_PD,
+ SC2730_LDO_VDDSIM2_PD_MASK, SC2730_LDO_VDDSIM2_VOL,
+ SC2730_LDO_VDDSIM2_VOL_MASK, 10000, 1200000, 3750000),
+ SC2730_REGU_LINEAR(LDO_VDDEMMCCORE, "ldo-vddemmccore", SC2730_LDO_VDDEMMCCORE_PD,
+ SC2730_LDO_VDDEMMCCORE_PD_MASK, SC2730_LDO_VDDEMMCCORE_VOL,
+ SC2730_LDO_VDDEMMCCORE_VOL_MASK, 10000, 1200000, 3750000),
+ SC2730_REGU_LINEAR(LDO_VDDSDCORE, "ldo-vddsdcore", SC2730_LDO_VDDSDCORE_PD,
+ SC2730_LDO_VDDSDCORE_PD_MASK, SC2730_LDO_VDDSDCORE_VOL,
+ SC2730_LDO_VDDSDCORE_VOL_MASK, 10000, 1200000, 3750000),
+ SC2730_REGU_LINEAR(LDO_VDDSDIO, "ldo-vddsdio", SC2730_LDO_VDDSDIO_PD,
+ SC2730_LDO_VDDSDIO_PD_MASK, SC2730_LDO_VDDSDIO_VOL,
+ SC2730_LDO_VDDSDIO_VOL_MASK, 10000, 1200000, 3750000),
+ SC2730_REGU_LINEAR(LDO_VDD28, "ldo-vdd28", SC2730_POWER_PD_SW,
+ SC2730_LDO_VDD28_PD_MASK, SC2730_LDO_VDD28_VOL,
+ SC2730_LDO_VDD28_VOL_MASK, 10000, 1200000, 3750000),
+ SC2730_REGU_LINEAR(LDO_VDDWIFIPA, "ldo-vddwifipa", SC2730_LDO_VDDWIFIPA_PD,
+ SC2730_LDO_VDDWIFIPA_PD_MASK, SC2730_LDO_VDDWIFIPA_VOL,
+ SC2730_LDO_VDDWIFIPA_VOL_MASK, 10000, 1200000, 3750000),
+ SC2730_REGU_LINEAR(LDO_VDD18_DCXO, "ldo-vdd18-dcxo", SC2730_POWER_PD_SW,
+ SC2730_LDO_VDD18_DCXO_PD_MASK, SC2730_LDO_VDD18_DCXO_VOL,
+ SC2730_LDO_VDD18_DCXO_VOL_MASK, 10000, 1200000, 3750000),
+ SC2730_REGU_LINEAR(LDO_VDDUSB33, "ldo-vddusb33", SC2730_LDO_VDDUSB33_PD,
+ SC2730_LDO_VDDUSB33_PD_MASK, SC2730_LDO_VDDUSB33_VOL,
+ SC2730_LDO_VDDUSB33_VOL_MASK, 10000, 1200000, 3750000),
+ SC2730_REGU_LINEAR(LDO_VDDLDO0, "ldo-vddldo0", SC2730_LDO_VDDLDO0_PD,
+ SC2730_LDO_VDDLDO0_PD_MASK, SC2730_LDO_VDDLDO0_VOL,
+ SC2730_LDO_VDDLDO0_VOL_MASK, 10000, 1200000, 3750000),
+ SC2730_REGU_LINEAR(LDO_VDDLDO1, "ldo-vddldo1", SC2730_LDO_VDDLDO1_PD,
+ SC2730_LDO_VDDLDO1_PD_MASK, SC2730_LDO_VDDLDO1_VOL,
+ SC2730_LDO_VDDLDO1_VOL_MASK, 10000, 1200000, 3750000),
+ SC2730_REGU_LINEAR(LDO_VDDLDO2, "ldo-vddldo2", SC2730_LDO_VDDLDO2_PD,
+ SC2730_LDO_VDDLDO2_PD_MASK, SC2730_LDO_VDDLDO2_VOL,
+ SC2730_LDO_VDDLDO2_VOL_MASK, 10000, 1200000, 3750000),
+ SC2730_REGU_LINEAR(LDO_VDDKPLED, "ldo-vddkpled", SC2730_LDO_VDDKPLED_PD,
+ SC2730_LDO_VDDKPLED_PD_MASK, SC2730_LDO_VDDKPLED_VOL,
+ SC2730_LDO_VDDKPLED_VOL_MASK, 10000, 1200000, 3750000),
+};
+
+static int sc2730_regulator_unlock(struct regmap *regmap)
+{
+ return regmap_write(regmap, SC2730_PWR_WR_PROT, SC2730_WR_UNLOCK_VALUE);
+}
+
+static int sc2730_regulator_probe(struct platform_device *pdev)
+{
+ int i, ret;
+ struct regmap *regmap;
+ struct regulator_config config = { };
+ struct regulator_dev *rdev;
+
+ regmap = dev_get_regmap(pdev->dev.parent, NULL);
+ if (!regmap)
+ return dev_err_probe(&pdev->dev, -ENODEV, "failed to get regmap\n");
+
+ ret = sc2730_regulator_unlock(regmap);
+ if (ret)
+ return dev_err_probe(&pdev->dev, ret, "failed to release regulator lock\n");
+
+ config.dev = pdev->dev.parent;
+ config.regmap = regmap;
+
+ for (i = 0; i < ARRAY_SIZE(regulators); i++) {
+ rdev = devm_regulator_register(&pdev->dev, &regulators[i], &config);
+ if (IS_ERR(rdev)) {
+ return dev_err_probe(&pdev->dev, PTR_ERR(rdev),
+ "failed to register regulator %s\n",
+ regulators[i].name);
+ }
+ }
+
+ return 0;
+}
+
+static const struct platform_device_id sc2730_regulator_id_table[] = {
+ { .name = "sc2730-regulator" },
+ { }
+};
+MODULE_DEVICE_TABLE(platform, sc2730_regulator_id_table);
+
+static struct platform_driver sc2730_regulator_driver = {
+ .driver = {
+ .name = "sc2730-regulator",
+ .probe_type = PROBE_PREFER_ASYNCHRONOUS,
+ },
+ .probe = sc2730_regulator_probe,
+ .id_table = sc2730_regulator_id_table,
+};
+
+module_platform_driver(sc2730_regulator_driver);
+
+MODULE_AUTHOR("Zhongfa Wang <zhongfa.wang@unisoc.com>");
+MODULE_DESCRIPTION("Spreadtrum SC2730 regulator driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/regulator/sgm3804-regulator.c b/drivers/regulator/sgm3804-regulator.c
index c3406cfb73d0..a34c9418b275 100644
--- a/drivers/regulator/sgm3804-regulator.c
+++ b/drivers/regulator/sgm3804-regulator.c
@@ -285,7 +285,7 @@ static int sgm3804_probe(struct i2c_client *i2c)
}
static const struct i2c_device_id sgm3804_id[] = {
- { "sgm3804" },
+ { .name = "sgm3804" },
{ }
};
MODULE_DEVICE_TABLE(i2c, sgm3804_id);
diff --git a/drivers/regulator/slg51000-regulator.c b/drivers/regulator/slg51000-regulator.c
index 3bbd4a29e6d3..d682764cdbf8 100644
--- a/drivers/regulator/slg51000-regulator.c
+++ b/drivers/regulator/slg51000-regulator.c
@@ -497,8 +497,8 @@ static int slg51000_i2c_probe(struct i2c_client *client)
}
static const struct i2c_device_id slg51000_i2c_id[] = {
- { "slg51000" },
- {}
+ { .name = "slg51000" },
+ { }
};
MODULE_DEVICE_TABLE(i2c, slg51000_i2c_id);
diff --git a/drivers/regulator/sy8106a-regulator.c b/drivers/regulator/sy8106a-regulator.c
index d79a4cc25a0d..b2b835c60262 100644
--- a/drivers/regulator/sy8106a-regulator.c
+++ b/drivers/regulator/sy8106a-regulator.c
@@ -130,7 +130,7 @@ static const struct of_device_id sy8106a_i2c_of_match[] = {
MODULE_DEVICE_TABLE(of, sy8106a_i2c_of_match);
static const struct i2c_device_id sy8106a_i2c_id[] = {
- { "sy8106a" },
+ { .name = "sy8106a" },
{ }
};
MODULE_DEVICE_TABLE(i2c, sy8106a_i2c_id);
diff --git a/drivers/regulator/sy8824x.c b/drivers/regulator/sy8824x.c
index 5bec84db25f1..3f07e7da90cb 100644
--- a/drivers/regulator/sy8824x.c
+++ b/drivers/regulator/sy8824x.c
@@ -213,10 +213,10 @@ static const struct of_device_id sy8824_dt_ids[] = {
MODULE_DEVICE_TABLE(of, sy8824_dt_ids);
static const struct i2c_device_id sy8824_id[] = {
- { "sy8824c", (kernel_ulong_t)&sy8824c_cfg },
- { "sy8824e", (kernel_ulong_t)&sy8824e_cfg },
- { "sy20276", (kernel_ulong_t)&sy20276_cfg },
- { "sy20278", (kernel_ulong_t)&sy20278_cfg },
+ { .name = "sy8824c", .driver_data = (kernel_ulong_t)&sy8824c_cfg },
+ { .name = "sy8824e", .driver_data = (kernel_ulong_t)&sy8824e_cfg },
+ { .name = "sy20276", .driver_data = (kernel_ulong_t)&sy20276_cfg },
+ { .name = "sy20278", .driver_data = (kernel_ulong_t)&sy20278_cfg },
{ }
};
MODULE_DEVICE_TABLE(i2c, sy8824_id);
diff --git a/drivers/regulator/sy8827n.c b/drivers/regulator/sy8827n.c
index 0b811514782f..a1cac8cc3d96 100644
--- a/drivers/regulator/sy8827n.c
+++ b/drivers/regulator/sy8827n.c
@@ -180,8 +180,8 @@ static const struct of_device_id sy8827n_dt_ids[] = {
MODULE_DEVICE_TABLE(of, sy8827n_dt_ids);
static const struct i2c_device_id sy8827n_id[] = {
- { "sy8827n", },
- { },
+ { .name = "sy8827n" },
+ { }
};
MODULE_DEVICE_TABLE(i2c, sy8827n_id);
diff --git a/drivers/regulator/tps51632-regulator.c b/drivers/regulator/tps51632-regulator.c
index 3a384bf9d2c5..8459b49ec26e 100644
--- a/drivers/regulator/tps51632-regulator.c
+++ b/drivers/regulator/tps51632-regulator.c
@@ -331,8 +331,8 @@ static int tps51632_probe(struct i2c_client *client)
}
static const struct i2c_device_id tps51632_id[] = {
- {.name = "tps51632",},
- {},
+ { .name = "tps51632" },
+ { }
};
MODULE_DEVICE_TABLE(i2c, tps51632_id);
diff --git a/drivers/regulator/tps62360-regulator.c b/drivers/regulator/tps62360-regulator.c
index be6a6702cbfa..00f19082c1da 100644
--- a/drivers/regulator/tps62360-regulator.c
+++ b/drivers/regulator/tps62360-regulator.c
@@ -476,11 +476,11 @@ static void tps62360_shutdown(struct i2c_client *client)
}
static const struct i2c_device_id tps62360_id[] = {
- {.name = "tps62360", .driver_data = TPS62360},
- {.name = "tps62361", .driver_data = TPS62361},
- {.name = "tps62362", .driver_data = TPS62362},
- {.name = "tps62363", .driver_data = TPS62363},
- {},
+ { .name = "tps62360", .driver_data = TPS62360 },
+ { .name = "tps62361", .driver_data = TPS62361 },
+ { .name = "tps62362", .driver_data = TPS62362 },
+ { .name = "tps62363", .driver_data = TPS62363 },
+ { }
};
MODULE_DEVICE_TABLE(i2c, tps62360_id);
diff --git a/drivers/regulator/tps6286x-regulator.c b/drivers/regulator/tps6286x-regulator.c
index e29aab06bf79..1ab53bee9f6e 100644
--- a/drivers/regulator/tps6286x-regulator.c
+++ b/drivers/regulator/tps6286x-regulator.c
@@ -145,11 +145,11 @@ static int tps6286x_i2c_probe(struct i2c_client *i2c)
}
static const struct i2c_device_id tps6286x_i2c_id[] = {
- { "tps62864" },
- { "tps62866" },
- { "tps62868" },
- { "tps62869" },
- {}
+ { .name = "tps62864" },
+ { .name = "tps62866" },
+ { .name = "tps62868" },
+ { .name = "tps62869" },
+ { }
};
MODULE_DEVICE_TABLE(i2c, tps6286x_i2c_id);
diff --git a/drivers/regulator/tps6287x-regulator.c b/drivers/regulator/tps6287x-regulator.c
index 9df104cb6bd2..e6403398facc 100644
--- a/drivers/regulator/tps6287x-regulator.c
+++ b/drivers/regulator/tps6287x-regulator.c
@@ -228,11 +228,11 @@ static const struct of_device_id tps6287x_dt_ids[] = {
MODULE_DEVICE_TABLE(of, tps6287x_dt_ids);
static const struct i2c_device_id tps6287x_i2c_id[] = {
- { "tps62870" },
- { "tps62871" },
- { "tps62872" },
- { "tps62873" },
- {}
+ { .name = "tps62870" },
+ { .name = "tps62871" },
+ { .name = "tps62872" },
+ { .name = "tps62873" },
+ { }
};
MODULE_DEVICE_TABLE(i2c, tps6287x_i2c_id);
diff --git a/drivers/regulator/tps65023-regulator.c b/drivers/regulator/tps65023-regulator.c
index 3334b5b7d907..5a2fc57cddf6 100644
--- a/drivers/regulator/tps65023-regulator.c
+++ b/drivers/regulator/tps65023-regulator.c
@@ -319,13 +319,13 @@ MODULE_DEVICE_TABLE(of, tps65023_of_match);
static const struct i2c_device_id tps_65023_id[] = {
{
.name = "tps65023",
- .driver_data = (kernel_ulong_t)&tps65023_drv_data
+ .driver_data = (kernel_ulong_t)&tps65023_drv_data,
}, {
.name = "tps65021",
- .driver_data = (kernel_ulong_t)&tps65021_drv_data
+ .driver_data = (kernel_ulong_t)&tps65021_drv_data,
}, {
.name = "tps65020",
- .driver_data = (kernel_ulong_t)&tps65020_drv_data
+ .driver_data = (kernel_ulong_t)&tps65020_drv_data,
},
{ },
};
diff --git a/drivers/regulator/tps65132-regulator.c b/drivers/regulator/tps65132-regulator.c
index 9c2f0dd42613..fecda3fd8ebc 100644
--- a/drivers/regulator/tps65132-regulator.c
+++ b/drivers/regulator/tps65132-regulator.c
@@ -262,8 +262,8 @@ static int tps65132_probe(struct i2c_client *client)
}
static const struct i2c_device_id tps65132_id[] = {
- {.name = "tps65132",},
- {},
+ { .name = "tps65132" },
+ { }
};
MODULE_DEVICE_TABLE(i2c, tps65132_id);
diff --git a/drivers/regulator/tps65185.c b/drivers/regulator/tps65185.c
index 786622d8d598..1f13e4156cab 100644
--- a/drivers/regulator/tps65185.c
+++ b/drivers/regulator/tps65185.c
@@ -183,7 +183,10 @@ static int tps65185_vposneg_enable(struct regulator_dev *rdev)
wait_for_completion_timeout(&data->pgood_completion,
msecs_to_jiffies(PGOOD_TIMEOUT_MSECS));
dev_dbg(data->dev, "turned on");
- if (gpiod_get_value_cansleep(data->pgood_gpio) != 1)
+ ret = gpiod_get_value_cansleep(data->pgood_gpio);
+ if (ret < 0)
+ return ret;
+ if (!ret)
return -ETIMEDOUT;
return 0;
diff --git a/drivers/regulator/tps6594-regulator.c b/drivers/regulator/tps6594-regulator.c
index 645e83462c64..31a5218d5510 100644
--- a/drivers/regulator/tps6594-regulator.c
+++ b/drivers/regulator/tps6594-regulator.c
@@ -669,13 +669,20 @@ static int tps6594_regulator_probe(struct platform_device *pdev)
* buck_configured to avoid creating bucks for every buck in multiphase
*/
for (multi = 0; multi < desc->num_multi_phase_regs; multi++) {
+ struct device_node *np_parent;
+
multi_regs = &desc->multi_phase_regs[multi];
np = of_find_node_by_name(tps->dev->of_node, multi_regs->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))
+ if (!np)
continue;
- if (strcmp(npname, multi_regs->supply_name) == 0) {
+
+ npname = of_node_full_name(np);
+ np_parent = of_get_parent(np);
+ np_pmic_parent = of_get_parent(np_parent);
+
+ if (np_pmic_parent &&
+ !of_node_cmp(of_node_full_name(np_pmic_parent), tps->dev->of_node->full_name) &&
+ strcmp(npname, multi_regs->supply_name) == 0) {
switch (multi) {
case MULTI_BUCK12:
buck_multi[0] = true;
@@ -706,6 +713,10 @@ static int tps6594_regulator_probe(struct platform_device *pdev)
break;
}
}
+
+ of_node_put(np_pmic_parent);
+ of_node_put(np_parent);
+ of_node_put(np);
}
reg_irq_nb = desc->num_irq_types * (desc->num_buck_regs + desc->num_ldo_regs);
diff --git a/drivers/regulator/wm831x-isink.c b/drivers/regulator/wm831x-isink.c
index 43f220cea21c..b46e2cde5e9d 100644
--- a/drivers/regulator/wm831x-isink.c
+++ b/drivers/regulator/wm831x-isink.c
@@ -62,11 +62,7 @@ static int wm831x_isink_disable(struct regulator_dev *rdev)
if (ret < 0)
return ret;
- ret = wm831x_set_bits(wm831x, isink->reg, WM831X_CS1_ENA, 0);
- if (ret < 0)
- return ret;
-
- return ret;
+ return wm831x_set_bits(wm831x, isink->reg, WM831X_CS1_ENA, 0);
}