summaryrefslogtreecommitdiffstats
path: root/drivers/regulator
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/regulator')
-rw-r--r--drivers/regulator/88pm800.c1
-rw-r--r--drivers/regulator/88pm8607.c4
-rw-r--r--drivers/regulator/Kconfig37
-rw-r--r--drivers/regulator/Makefile3
-rw-r--r--drivers/regulator/aat2870-regulator.c1
-rw-r--r--drivers/regulator/ab3100.c1
-rw-r--r--drivers/regulator/ab8500-ext.c1
-rw-r--r--drivers/regulator/ab8500.c1
-rw-r--r--drivers/regulator/act8865-regulator.c31
-rw-r--r--drivers/regulator/anatop-regulator.c19
-rw-r--r--drivers/regulator/arizona-ldo1.c11
-rw-r--r--drivers/regulator/arizona-micsupp.c9
-rw-r--r--drivers/regulator/as3711-regulator.c1
-rw-r--r--drivers/regulator/as3722-regulator.c1
-rw-r--r--drivers/regulator/axp20x-regulator.c94
-rw-r--r--drivers/regulator/bcm590xx-regulator.c1
-rw-r--r--drivers/regulator/core.c402
-rw-r--r--drivers/regulator/da903x.c1
-rw-r--r--drivers/regulator/da9052-regulator.c4
-rw-r--r--drivers/regulator/da9055-regulator.c1
-rw-r--r--drivers/regulator/da9063-regulator.c20
-rw-r--r--drivers/regulator/da9210-regulator.c2
-rw-r--r--drivers/regulator/da9211-regulator.c16
-rw-r--r--drivers/regulator/db8500-prcmu.c1
-rw-r--r--drivers/regulator/dummy.c3
-rw-r--r--drivers/regulator/fan53555.c21
-rw-r--r--drivers/regulator/fixed.c25
-rw-r--r--drivers/regulator/gpio-regulator.c116
-rw-r--r--drivers/regulator/hi6421-regulator.c1
-rw-r--r--drivers/regulator/internal.h2
-rw-r--r--drivers/regulator/isl9305.c6
-rw-r--r--drivers/regulator/lp872x.c24
-rw-r--r--drivers/regulator/lp8788-buck.c1
-rw-r--r--drivers/regulator/lp8788-ldo.c2
-rw-r--r--drivers/regulator/max14577.c63
-rw-r--r--drivers/regulator/max1586.c2
-rw-r--r--drivers/regulator/max77686.c237
-rw-r--r--drivers/regulator/max77693.c5
-rw-r--r--drivers/regulator/max77802.c255
-rw-r--r--drivers/regulator/max77843.c227
-rw-r--r--drivers/regulator/max8649.c4
-rw-r--r--drivers/regulator/max8660.c2
-rw-r--r--drivers/regulator/max8907-regulator.c1
-rw-r--r--drivers/regulator/max8925-regulator.c1
-rw-r--r--drivers/regulator/max8952.c4
-rw-r--r--drivers/regulator/max8973-regulator.c3
-rw-r--r--drivers/regulator/max8997.c4
-rw-r--r--drivers/regulator/max8998.c6
-rw-r--r--drivers/regulator/mc13783-regulator.c1
-rw-r--r--drivers/regulator/mc13892-regulator.c1
-rw-r--r--drivers/regulator/mc13xxx-regulator-core.c3
-rw-r--r--drivers/regulator/mt6397-regulator.c332
-rw-r--r--drivers/regulator/of_regulator.c101
-rw-r--r--drivers/regulator/palmas-regulator.c1
-rw-r--r--drivers/regulator/pbias-regulator.c1
-rw-r--r--drivers/regulator/pcap-regulator.c1
-rw-r--r--drivers/regulator/pfuze100-regulator.c134
-rw-r--r--drivers/regulator/pwm-regulator.c4
-rw-r--r--drivers/regulator/qcom_rpm-regulator.c44
-rw-r--r--drivers/regulator/rc5t583-regulator.c1
-rw-r--r--drivers/regulator/rk808-regulator.c3
-rw-r--r--drivers/regulator/rn5t618-regulator.c51
-rw-r--r--drivers/regulator/rt5033-regulator.c129
-rw-r--r--drivers/regulator/s2mpa01.c5
-rw-r--r--drivers/regulator/s2mps11.c159
-rw-r--r--drivers/regulator/s5m8767.c5
-rw-r--r--drivers/regulator/sky81452-regulator.c46
-rw-r--r--drivers/regulator/stw481x-vmmc.c4
-rw-r--r--drivers/regulator/ti-abb-regulator.c4
-rw-r--r--drivers/regulator/tps51632-regulator.c43
-rw-r--r--drivers/regulator/tps6105x-regulator.c1
-rw-r--r--drivers/regulator/tps62360-regulator.c31
-rw-r--r--drivers/regulator/tps65023-regulator.c6
-rw-r--r--drivers/regulator/tps6507x-regulator.c1
-rw-r--r--drivers/regulator/tps65090-regulator.c5
-rw-r--r--drivers/regulator/tps65218-regulator.c4
-rw-r--r--drivers/regulator/tps6586x-regulator.c1
-rw-r--r--drivers/regulator/tps65910-regulator.c1
-rw-r--r--drivers/regulator/tps65912-regulator.c1
-rw-r--r--drivers/regulator/tps80031-regulator.c1
-rw-r--r--drivers/regulator/twl-regulator.c4
-rw-r--r--drivers/regulator/vexpress.c4
-rw-r--r--drivers/regulator/virtual.c1
-rw-r--r--drivers/regulator/wm831x-dcdc.c4
-rw-r--r--drivers/regulator/wm831x-isink.c1
-rw-r--r--drivers/regulator/wm831x-ldo.c3
-rw-r--r--drivers/regulator/wm8994-regulator.c7
87 files changed, 1929 insertions, 898 deletions
diff --git a/drivers/regulator/88pm800.c b/drivers/regulator/88pm800.c
index 4e6c8c6..832932b 100644
--- a/drivers/regulator/88pm800.c
+++ b/drivers/regulator/88pm800.c
@@ -362,7 +362,6 @@ static int pm800_regulator_remove(struct platform_device *pdev)
static struct platform_driver pm800_regulator_driver = {
.driver = {
.name = "88pm80x-regulator",
- .owner = THIS_MODULE,
},
.probe = pm800_regulator_probe,
.remove = pm800_regulator_remove,
diff --git a/drivers/regulator/88pm8607.c b/drivers/regulator/88pm8607.c
index 6d77dcd..c3d1542 100644
--- a/drivers/regulator/88pm8607.c
+++ b/drivers/regulator/88pm8607.c
@@ -330,7 +330,8 @@ static int pm8607_regulator_dt_init(struct platform_device *pdev,
for_each_child_of_node(nproot, np) {
if (!of_node_cmp(np->name, info->desc.name)) {
config->init_data =
- of_get_regulator_init_data(&pdev->dev, np);
+ of_get_regulator_init_data(&pdev->dev, np,
+ &info->desc);
config->of_node = np;
break;
}
@@ -418,7 +419,6 @@ MODULE_DEVICE_TABLE(platform, pm8607_regulator_driver_ids);
static struct platform_driver pm8607_regulator_driver = {
.driver = {
.name = "88pm860x-regulator",
- .owner = THIS_MODULE,
},
.probe = pm8607_regulator_probe,
.id_table = pm8607_regulator_driver_ids,
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 55d7b7b..a6f116a 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -414,6 +414,14 @@ config REGULATOR_MAX77802
Exynos5420/Exynos5800 SoCs to control various voltages.
It includes support for control of voltage and ramp speed.
+config REGULATOR_MAX77843
+ tristate "Maxim 77843 regulator"
+ depends on MFD_MAX77843
+ help
+ This driver controls a Maxim 77843 regulator.
+ The regulator include two 'SAFEOUT' for USB(Universal Serial Bus)
+ This is suitable for Exynos5433 SoC chips.
+
config REGULATOR_MC13XXX_CORE
tristate
@@ -433,6 +441,15 @@ config REGULATOR_MC13892
Say y here to support the regulators found on the Freescale MC13892
PMIC.
+config REGULATOR_MT6397
+ tristate "MediaTek MT6397 PMIC"
+ depends on MFD_MT6397
+ help
+ Say y here to select this option to enable the power regulator of
+ MediaTek MT6397 PMIC.
+ This driver supports the control of different power rails of device
+ through regulator interface.
+
config REGULATOR_PALMAS
tristate "TI Palmas PMIC Regulators"
depends on MFD_PALMAS
@@ -521,6 +538,14 @@ config REGULATOR_RN5T618
help
Say y here to support the regulators found on Ricoh RN5T618 PMIC.
+config REGULATOR_RT5033
+ tristate "Richtek RT5033 Regulators"
+ depends on MFD_RT5033
+ help
+ This adds support for voltage and current regulators in Richtek
+ RT5033 PMIC. The device supports multiple regulators like
+ current source, LDO and Buck.
+
config REGULATOR_S2MPA01
tristate "Samsung S2MPA01 voltage regulator"
depends on MFD_SEC_CORE
@@ -529,13 +554,13 @@ config REGULATOR_S2MPA01
via I2C bus. S2MPA01 has 10 Bucks and 26 LDO outputs.
config REGULATOR_S2MPS11
- tristate "Samsung S2MPS11/S2MPS14/S2MPU02 voltage regulator"
+ tristate "Samsung S2MPS11/S2MPS13/S2MPS14/S2MPU02 voltage regulator"
depends on MFD_SEC_CORE
help
- This driver supports a Samsung S2MPS11/S2MPS14/S2MPU02 voltage output
- regulator via I2C bus. The chip is comprised of high efficient Buck
- converters including Dual-Phase Buck converter, Buck-Boost converter,
- various LDOs.
+ This driver supports a Samsung S2MPS11/S2MPS13/S2MPS14/S2MPU02 voltage
+ output regulator via I2C bus. The chip is comprised of high efficient
+ Buck converters including Dual-Phase Buck converter, Buck-Boost
+ converter, various LDOs.
config REGULATOR_S5M8767
tristate "Samsung S5M8767A voltage regulator"
@@ -547,7 +572,7 @@ config REGULATOR_S5M8767
config REGULATOR_SKY81452
tristate "Skyworks Solutions SKY81452 voltage regulator"
- depends on SKY81452
+ depends on MFD_SKY81452
help
This driver supports Skyworks SKY81452 voltage output regulator
via I2C bus. SKY81452 has one voltage linear regulator can be
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 1029ed3..2c4da15 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -55,9 +55,11 @@ obj-$(CONFIG_REGULATOR_MAX8998) += max8998.o
obj-$(CONFIG_REGULATOR_MAX77686) += max77686.o
obj-$(CONFIG_REGULATOR_MAX77693) += max77693.o
obj-$(CONFIG_REGULATOR_MAX77802) += max77802.o
+obj-$(CONFIG_REGULATOR_MAX77843) += max77843.o
obj-$(CONFIG_REGULATOR_MC13783) += mc13783-regulator.o
obj-$(CONFIG_REGULATOR_MC13892) += mc13892-regulator.o
obj-$(CONFIG_REGULATOR_MC13XXX_CORE) += mc13xxx-regulator-core.o
+obj-$(CONFIG_REGULATOR_MT6397) += mt6397-regulator.o
obj-$(CONFIG_REGULATOR_QCOM_RPM) += qcom_rpm-regulator.o
obj-$(CONFIG_REGULATOR_PALMAS) += palmas-regulator.o
obj-$(CONFIG_REGULATOR_PFUZE100) += pfuze100-regulator.o
@@ -69,6 +71,7 @@ obj-$(CONFIG_REGULATOR_PCF50633) += pcf50633-regulator.o
obj-$(CONFIG_REGULATOR_RC5T583) += rc5t583-regulator.o
obj-$(CONFIG_REGULATOR_RK808) += rk808-regulator.o
obj-$(CONFIG_REGULATOR_RN5T618) += rn5t618-regulator.o
+obj-$(CONFIG_REGULATOR_RT5033) += rt5033-regulator.o
obj-$(CONFIG_REGULATOR_S2MPA01) += s2mpa01.o
obj-$(CONFIG_REGULATOR_S2MPS11) += s2mps11.o
obj-$(CONFIG_REGULATOR_S5M8767) += s5m8767.o
diff --git a/drivers/regulator/aat2870-regulator.c b/drivers/regulator/aat2870-regulator.c
index c873ee0..9dfabda 100644
--- a/drivers/regulator/aat2870-regulator.c
+++ b/drivers/regulator/aat2870-regulator.c
@@ -191,7 +191,6 @@ static int aat2870_regulator_probe(struct platform_device *pdev)
static struct platform_driver aat2870_regulator_driver = {
.driver = {
.name = "aat2870-regulator",
- .owner = THIS_MODULE,
},
.probe = aat2870_regulator_probe,
};
diff --git a/drivers/regulator/ab3100.c b/drivers/regulator/ab3100.c
index e10febe..de26444 100644
--- a/drivers/regulator/ab3100.c
+++ b/drivers/regulator/ab3100.c
@@ -721,7 +721,6 @@ static int ab3100_regulators_probe(struct platform_device *pdev)
static struct platform_driver ab3100_regulators_driver = {
.driver = {
.name = "ab3100-regulators",
- .owner = THIS_MODULE,
},
.probe = ab3100_regulators_probe,
.remove = ab3100_regulators_remove,
diff --git a/drivers/regulator/ab8500-ext.c b/drivers/regulator/ab8500-ext.c
index 29c0faa..84c1ee3 100644
--- a/drivers/regulator/ab8500-ext.c
+++ b/drivers/regulator/ab8500-ext.c
@@ -433,7 +433,6 @@ static struct platform_driver ab8500_ext_regulator_driver = {
.probe = ab8500_ext_regulator_probe,
.driver = {
.name = "ab8500-ext-regulator",
- .owner = THIS_MODULE,
},
};
diff --git a/drivers/regulator/ab8500.c b/drivers/regulator/ab8500.c
index 1fda14e..0f97514 100644
--- a/drivers/regulator/ab8500.c
+++ b/drivers/regulator/ab8500.c
@@ -3075,7 +3075,6 @@ static struct platform_driver ab8500_regulator_driver = {
.probe = ab8500_regulator_probe,
.driver = {
.name = "ab8500-regulator",
- .owner = THIS_MODULE,
},
};
diff --git a/drivers/regulator/act8865-regulator.c b/drivers/regulator/act8865-regulator.c
index afd06f9..9eec453 100644
--- a/drivers/regulator/act8865-regulator.c
+++ b/drivers/regulator/act8865-regulator.c
@@ -61,6 +61,8 @@
#define ACT8846_REG12_VSET 0xa0
#define ACT8846_REG12_CTRL 0xa1
#define ACT8846_REG13_CTRL 0xb1
+#define ACT8846_GLB_OFF_CTRL 0xc3
+#define ACT8846_OFF_SYSMASK 0x18
/*
* ACT8865 Global Register Map.
@@ -84,6 +86,7 @@
#define ACT8865_LDO3_CTRL 0x61
#define ACT8865_LDO4_VSET 0x64
#define ACT8865_LDO4_CTRL 0x65
+#define ACT8865_MSTROFF 0x20
/*
* Field Definitions.
@@ -98,6 +101,8 @@
struct act8865 {
struct regmap *regmap;
+ int off_reg;
+ int off_mask;
};
static const struct regmap_config act8865_regmap_config = {
@@ -275,6 +280,16 @@ static struct regulator_init_data
return NULL;
}
+static struct i2c_client *act8865_i2c_client;
+static void act8865_power_off(void)
+{
+ struct act8865 *act8865;
+
+ act8865 = i2c_get_clientdata(act8865_i2c_client);
+ regmap_write(act8865->regmap, act8865->off_reg, act8865->off_mask);
+ while (1);
+}
+
static int act8865_pmic_probe(struct i2c_client *client,
const struct i2c_device_id *i2c_id)
{
@@ -285,6 +300,7 @@ static int act8865_pmic_probe(struct i2c_client *client,
int i, ret, num_regulators;
struct act8865 *act8865;
unsigned long type;
+ int off_reg, off_mask;
pdata = dev_get_platdata(dev);
@@ -304,10 +320,14 @@ static int act8865_pmic_probe(struct i2c_client *client,
case ACT8846:
regulators = act8846_regulators;
num_regulators = ARRAY_SIZE(act8846_regulators);
+ off_reg = ACT8846_GLB_OFF_CTRL;
+ off_mask = ACT8846_OFF_SYSMASK;
break;
case ACT8865:
regulators = act8865_regulators;
num_regulators = ARRAY_SIZE(act8865_regulators);
+ off_reg = ACT8865_SYS_CTRL;
+ off_mask = ACT8865_MSTROFF;
break;
default:
dev_err(dev, "invalid device id %lu\n", type);
@@ -345,6 +365,17 @@ static int act8865_pmic_probe(struct i2c_client *client,
return ret;
}
+ if (of_device_is_system_power_controller(dev->of_node)) {
+ if (!pm_power_off) {
+ act8865_i2c_client = client;
+ act8865->off_reg = off_reg;
+ act8865->off_mask = off_mask;
+ pm_power_off = act8865_power_off;
+ } else {
+ dev_err(dev, "Failed to set poweroff capability, already defined\n");
+ }
+ }
+
/* Finally register devices */
for (i = 0; i < num_regulators; i++) {
const struct regulator_desc *desc = &regulators[i];
diff --git a/drivers/regulator/anatop-regulator.c b/drivers/regulator/anatop-regulator.c
index 4f730af..738adfa 100644
--- a/drivers/regulator/anatop-regulator.c
+++ b/drivers/regulator/anatop-regulator.c
@@ -189,17 +189,18 @@ static int anatop_regulator_probe(struct platform_device *pdev)
int ret = 0;
u32 val;
- initdata = of_get_regulator_init_data(dev, np);
sreg = devm_kzalloc(dev, sizeof(*sreg), GFP_KERNEL);
if (!sreg)
return -ENOMEM;
- sreg->initdata = initdata;
sreg->name = of_get_property(np, "regulator-name", NULL);
rdesc = &sreg->rdesc;
rdesc->name = sreg->name;
rdesc->type = REGULATOR_VOLTAGE;
rdesc->owner = THIS_MODULE;
+ initdata = of_get_regulator_init_data(dev, np, rdesc);
+ sreg->initdata = initdata;
+
anatop_np = of_get_parent(np);
if (!anatop_np)
return -ENODEV;
@@ -283,6 +284,19 @@ static int anatop_regulator_probe(struct platform_device *pdev)
sreg->sel = 0;
sreg->bypass = true;
}
+
+ /*
+ * In case vddpu was disabled by the bootloader, we need to set
+ * a sane default until imx6-cpufreq was probed and changes the
+ * voltage to the correct value. In this case we set 1.25V.
+ */
+ if (!sreg->sel && !strcmp(sreg->name, "vddpu"))
+ sreg->sel = 22;
+
+ if (!sreg->sel) {
+ dev_err(&pdev->dev, "Failed to read a valid default voltage selector.\n");
+ return -EINVAL;
+ }
} else {
rdesc->ops = &anatop_rops;
}
@@ -308,7 +322,6 @@ static const struct of_device_id of_anatop_regulator_match_tbl[] = {
static struct platform_driver anatop_regulator_driver = {
.driver = {
.name = "anatop_regulator",
- .owner = THIS_MODULE,
.of_match_table = of_anatop_regulator_match_tbl,
},
.probe = anatop_regulator_probe,
diff --git a/drivers/regulator/arizona-ldo1.c b/drivers/regulator/arizona-ldo1.c
index 4c9db58..8169165 100644
--- a/drivers/regulator/arizona-ldo1.c
+++ b/drivers/regulator/arizona-ldo1.c
@@ -179,7 +179,8 @@ static const struct regulator_init_data arizona_ldo1_default = {
};
static int arizona_ldo1_of_get_pdata(struct arizona *arizona,
- struct regulator_config *config)
+ struct regulator_config *config,
+ const struct regulator_desc *desc)
{
struct arizona_pdata *pdata = &arizona->pdata;
struct arizona_ldo1 *ldo1 = config->driver_data;
@@ -194,7 +195,8 @@ static int arizona_ldo1_of_get_pdata(struct arizona *arizona,
if (init_node) {
config->of_node = init_node;
- init_data = of_get_regulator_init_data(arizona->dev, init_node);
+ init_data = of_get_regulator_init_data(arizona->dev, init_node,
+ desc);
if (init_data) {
init_data->consumer_supplies = &ldo1->supply;
@@ -257,9 +259,11 @@ static int arizona_ldo1_probe(struct platform_device *pdev)
if (IS_ENABLED(CONFIG_OF)) {
if (!dev_get_platdata(arizona->dev)) {
- ret = arizona_ldo1_of_get_pdata(arizona, &config);
+ ret = arizona_ldo1_of_get_pdata(arizona, &config, desc);
if (ret < 0)
return ret;
+
+ config.ena_gpio_initialized = true;
}
}
@@ -296,7 +300,6 @@ static struct platform_driver arizona_ldo1_driver = {
.probe = arizona_ldo1_probe,
.driver = {
.name = "arizona-ldo1",
- .owner = THIS_MODULE,
},
};
diff --git a/drivers/regulator/arizona-micsupp.c b/drivers/regulator/arizona-micsupp.c
index ce9aca5..2007900 100644
--- a/drivers/regulator/arizona-micsupp.c
+++ b/drivers/regulator/arizona-micsupp.c
@@ -198,7 +198,8 @@ static const struct regulator_init_data arizona_micsupp_ext_default = {
};
static int arizona_micsupp_of_get_pdata(struct arizona *arizona,
- struct regulator_config *config)
+ struct regulator_config *config,
+ const struct regulator_desc *desc)
{
struct arizona_pdata *pdata = &arizona->pdata;
struct arizona_micsupp *micsupp = config->driver_data;
@@ -210,7 +211,7 @@ static int arizona_micsupp_of_get_pdata(struct arizona *arizona,
if (np) {
config->of_node = np;
- init_data = of_get_regulator_init_data(arizona->dev, np);
+ init_data = of_get_regulator_init_data(arizona->dev, np, desc);
if (init_data) {
init_data->consumer_supplies = &micsupp->supply;
@@ -264,7 +265,8 @@ static int arizona_micsupp_probe(struct platform_device *pdev)
if (IS_ENABLED(CONFIG_OF)) {
if (!dev_get_platdata(arizona->dev)) {
- ret = arizona_micsupp_of_get_pdata(arizona, &config);
+ ret = arizona_micsupp_of_get_pdata(arizona, &config,
+ desc);
if (ret < 0)
return ret;
}
@@ -300,7 +302,6 @@ static struct platform_driver arizona_micsupp_driver = {
.probe = arizona_micsupp_probe,
.driver = {
.name = "arizona-micsupp",
- .owner = THIS_MODULE,
},
};
diff --git a/drivers/regulator/as3711-regulator.c b/drivers/regulator/as3711-regulator.c
index 8459b0b..c0e93b1 100644
--- a/drivers/regulator/as3711-regulator.c
+++ b/drivers/regulator/as3711-regulator.c
@@ -267,7 +267,6 @@ static int as3711_regulator_probe(struct platform_device *pdev)
static struct platform_driver as3711_regulator_driver = {
.driver = {
.name = "as3711-regulator",
- .owner = THIS_MODULE,
},
.probe = as3711_regulator_probe,
};
diff --git a/drivers/regulator/as3722-regulator.c b/drivers/regulator/as3722-regulator.c
index b68f05f..8b046ee 100644
--- a/drivers/regulator/as3722-regulator.c
+++ b/drivers/regulator/as3722-regulator.c
@@ -916,7 +916,6 @@ MODULE_DEVICE_TABLE(of, of_as3722_regulator_match);
static struct platform_driver as3722_regulator_driver = {
.driver = {
.name = "as3722-regulator",
- .owner = THIS_MODULE,
.of_match_table = of_as3722_regulator_match,
},
.probe = as3722_regulator_probe,
diff --git a/drivers/regulator/axp20x-regulator.c b/drivers/regulator/axp20x-regulator.c
index 2e1010a..e4331f5 100644
--- a/drivers/regulator/axp20x-regulator.c
+++ b/drivers/regulator/axp20x-regulator.c
@@ -32,11 +32,13 @@
#define AXP20X_FREQ_DCDC_MASK 0x0f
-#define AXP20X_DESC_IO(_id, _supply, _min, _max, _step, _vreg, _vmask, _ereg, \
- _emask, _enable_val, _disable_val) \
+#define AXP20X_DESC_IO(_id, _match, _supply, _min, _max, _step, _vreg, _vmask, \
+ _ereg, _emask, _enable_val, _disable_val) \
[AXP20X_##_id] = { \
.name = #_id, \
.supply_name = (_supply), \
+ .of_match = of_match_ptr(_match), \
+ .regulators_node = of_match_ptr("regulators"), \
.type = REGULATOR_VOLTAGE, \
.id = AXP20X_##_id, \
.n_voltages = (((_max) - (_min)) / (_step) + 1), \
@@ -52,11 +54,13 @@
.ops = &axp20x_ops, \
}
-#define AXP20X_DESC(_id, _supply, _min, _max, _step, _vreg, _vmask, _ereg, \
- _emask) \
+#define AXP20X_DESC(_id, _match, _supply, _min, _max, _step, _vreg, _vmask, \
+ _ereg, _emask) \
[AXP20X_##_id] = { \
.name = #_id, \
.supply_name = (_supply), \
+ .of_match = of_match_ptr(_match), \
+ .regulators_node = of_match_ptr("regulators"), \
.type = REGULATOR_VOLTAGE, \
.id = AXP20X_##_id, \
.n_voltages = (((_max) - (_min)) / (_step) + 1), \
@@ -70,10 +74,12 @@
.ops = &axp20x_ops, \
}
-#define AXP20X_DESC_FIXED(_id, _supply, _volt) \
+#define AXP20X_DESC_FIXED(_id, _match, _supply, _volt) \
[AXP20X_##_id] = { \
.name = #_id, \
.supply_name = (_supply), \
+ .of_match = of_match_ptr(_match), \
+ .regulators_node = of_match_ptr("regulators"), \
.type = REGULATOR_VOLTAGE, \
.id = AXP20X_##_id, \
.n_voltages = 1, \
@@ -82,10 +88,13 @@
.ops = &axp20x_ops_fixed \
}
-#define AXP20X_DESC_TABLE(_id, _supply, _table, _vreg, _vmask, _ereg, _emask) \
+#define AXP20X_DESC_TABLE(_id, _match, _supply, _table, _vreg, _vmask, _ereg, \
+ _emask) \
[AXP20X_##_id] = { \
.name = #_id, \
.supply_name = (_supply), \
+ .of_match = of_match_ptr(_match), \
+ .regulators_node = of_match_ptr("regulators"), \
.type = REGULATOR_VOLTAGE, \
.id = AXP20X_##_id, \
.n_voltages = ARRAY_SIZE(_table), \
@@ -127,36 +136,20 @@ static struct regulator_ops axp20x_ops = {
};
static const struct regulator_desc axp20x_regulators[] = {
- AXP20X_DESC(DCDC2, "vin2", 700, 2275, 25, AXP20X_DCDC2_V_OUT, 0x3f,
- AXP20X_PWR_OUT_CTRL, 0x10),
- AXP20X_DESC(DCDC3, "vin3", 700, 3500, 25, AXP20X_DCDC3_V_OUT, 0x7f,
- AXP20X_PWR_OUT_CTRL, 0x02),
- AXP20X_DESC_FIXED(LDO1, "acin", 1300),
- AXP20X_DESC(LDO2, "ldo24in", 1800, 3300, 100, AXP20X_LDO24_V_OUT, 0xf0,
- AXP20X_PWR_OUT_CTRL, 0x04),
- AXP20X_DESC(LDO3, "ldo3in", 700, 3500, 25, AXP20X_LDO3_V_OUT, 0x7f,
- AXP20X_PWR_OUT_CTRL, 0x40),
- AXP20X_DESC_TABLE(LDO4, "ldo24in", axp20x_ldo4_data, AXP20X_LDO24_V_OUT, 0x0f,
- AXP20X_PWR_OUT_CTRL, 0x08),
- AXP20X_DESC_IO(LDO5, "ldo5in", 1800, 3300, 100, AXP20X_LDO5_V_OUT, 0xf0,
- AXP20X_GPIO0_CTRL, 0x07, AXP20X_IO_ENABLED,
- AXP20X_IO_DISABLED),
-};
-
-#define AXP_MATCH(_name, _id) \
- [AXP20X_##_id] = { \
- .name = #_name, \
- .driver_data = (void *) &axp20x_regulators[AXP20X_##_id], \
- }
-
-static struct of_regulator_match axp20x_matches[] = {
- AXP_MATCH(dcdc2, DCDC2),
- AXP_MATCH(dcdc3, DCDC3),
- AXP_MATCH(ldo1, LDO1),
- AXP_MATCH(ldo2, LDO2),
- AXP_MATCH(ldo3, LDO3),
- AXP_MATCH(ldo4, LDO4),
- AXP_MATCH(ldo5, LDO5),
+ AXP20X_DESC(DCDC2, "dcdc2", "vin2", 700, 2275, 25, AXP20X_DCDC2_V_OUT,
+ 0x3f, AXP20X_PWR_OUT_CTRL, 0x10),
+ AXP20X_DESC(DCDC3, "dcdc3", "vin3", 700, 3500, 25, AXP20X_DCDC3_V_OUT,
+ 0x7f, AXP20X_PWR_OUT_CTRL, 0x02),
+ AXP20X_DESC_FIXED(LDO1, "ldo1", "acin", 1300),
+ AXP20X_DESC(LDO2, "ldo2", "ldo24in", 1800, 3300, 100,
+ AXP20X_LDO24_V_OUT, 0xf0, AXP20X_PWR_OUT_CTRL, 0x04),
+ AXP20X_DESC(LDO3, "ldo3", "ldo3in", 700, 3500, 25, AXP20X_LDO3_V_OUT,
+ 0x7f, AXP20X_PWR_OUT_CTRL, 0x40),
+ AXP20X_DESC_TABLE(LDO4, "ldo4", "ldo24in", axp20x_ldo4_data,
+ AXP20X_LDO24_V_OUT, 0x0f, AXP20X_PWR_OUT_CTRL, 0x08),
+ AXP20X_DESC_IO(LDO5, "ldo5", "ldo5in", 1800, 3300, 100,
+ AXP20X_LDO5_V_OUT, 0xf0, AXP20X_GPIO0_CTRL, 0x07,
+ AXP20X_IO_ENABLED, AXP20X_IO_DISABLED),
};
static int axp20x_set_dcdc_freq(struct platform_device *pdev, u32 dcdcfreq)
@@ -193,13 +186,6 @@ static int axp20x_regulator_parse_dt(struct platform_device *pdev)
if (!regulators) {
dev_warn(&pdev->dev, "regulators node not found\n");
} else {
- ret = of_regulator_match(&pdev->dev, regulators, axp20x_matches,
- ARRAY_SIZE(axp20x_matches));
- if (ret < 0) {
- dev_err(&pdev->dev, "Error parsing regulator init data: %d\n", ret);
- return ret;
- }
-
dcdcfreq = 1500;
of_property_read_u32(regulators, "x-powers,dcdc-freq", &dcdcfreq);
ret = axp20x_set_dcdc_freq(pdev, dcdcfreq);
@@ -233,23 +219,17 @@ static int axp20x_regulator_probe(struct platform_device *pdev)
{
struct regulator_dev *rdev;
struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent);
- struct regulator_config config = { };
- struct regulator_init_data *init_data;
+ struct regulator_config config = {
+ .dev = pdev->dev.parent,
+ .regmap = axp20x->regmap,
+ };
int ret, i;
u32 workmode;
- ret = axp20x_regulator_parse_dt(pdev);
- if (ret)
- return ret;
+ /* This only sets the dcdc freq. Ignore any errors */
+ axp20x_regulator_parse_dt(pdev);
for (i = 0; i < AXP20X_REG_ID_MAX; i++) {
- init_data = axp20x_matches[i].init_data;
-
- config.dev = pdev->dev.parent;
- config.init_data = init_data;
- config.regmap = axp20x->regmap;
- config.of_node = axp20x_matches[i].of_node;
-
rdev = devm_regulator_register(&pdev->dev, &axp20x_regulators[i],
&config);
if (IS_ERR(rdev)) {
@@ -259,7 +239,8 @@ static int axp20x_regulator_probe(struct platform_device *pdev)
return PTR_ERR(rdev);
}
- ret = of_property_read_u32(axp20x_matches[i].of_node, "x-powers,dcdc-workmode",
+ ret = of_property_read_u32(rdev->dev.of_node,
+ "x-powers,dcdc-workmode",
&workmode);
if (!ret) {
if (axp20x_set_dcdc_workmode(rdev, i, workmode))
@@ -275,7 +256,6 @@ static struct platform_driver axp20x_regulator_driver = {
.probe = axp20x_regulator_probe,
.driver = {
.name = "axp20x-regulator",
- .owner = THIS_MODULE,
},
};
diff --git a/drivers/regulator/bcm590xx-regulator.c b/drivers/regulator/bcm590xx-regulator.c
index fe6ac69..628430b 100644
--- a/drivers/regulator/bcm590xx-regulator.c
+++ b/drivers/regulator/bcm590xx-regulator.c
@@ -453,7 +453,6 @@ static int bcm590xx_probe(struct platform_device *pdev)
static struct platform_driver bcm590xx_regulator_driver = {
.driver = {
.name = "bcm590xx-vregs",
- .owner = THIS_MODULE,
},
.probe = bcm590xx_probe,
};
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index cd87c0c..b899947 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -632,49 +632,34 @@ static ssize_t regulator_bypass_show(struct device *dev,
static DEVICE_ATTR(bypass, 0444,
regulator_bypass_show, NULL);
-/*
- * These are the only attributes are present for all regulators.
- * Other attributes are a function of regulator functionality.
- */
-static struct attribute *regulator_dev_attrs[] = {
- &dev_attr_name.attr,
- &dev_attr_num_users.attr,
- &dev_attr_type.attr,
- NULL,
-};
-ATTRIBUTE_GROUPS(regulator_dev);
-
-static void regulator_dev_release(struct device *dev)
-{
- struct regulator_dev *rdev = dev_get_drvdata(dev);
- kfree(rdev);
-}
-
-static struct class regulator_class = {
- .name = "regulator",
- .dev_release = regulator_dev_release,
- .dev_groups = regulator_dev_groups,
-};
-
/* Calculate the new optimum regulator operating mode based on the new total
* consumer load. All locks held by caller */
-static void drms_uA_update(struct regulator_dev *rdev)
+static int drms_uA_update(struct regulator_dev *rdev)
{
struct regulator *sibling;
int current_uA = 0, output_uV, input_uV, err;
unsigned int mode;
+ /*
+ * first check to see if we can set modes at all, otherwise just
+ * tell the consumer everything is OK.
+ */
err = regulator_check_drms(rdev);
- if (err < 0 || !rdev->desc->ops->get_optimum_mode ||
- (!rdev->desc->ops->get_voltage &&
- !rdev->desc->ops->get_voltage_sel) ||
- !rdev->desc->ops->set_mode)
- return;
+ if (err < 0)
+ return 0;
+
+ if (!rdev->desc->ops->get_optimum_mode)
+ return 0;
+
+ if (!rdev->desc->ops->set_mode)
+ return -EINVAL;
/* get output voltage */
output_uV = _regulator_get_voltage(rdev);
- if (output_uV <= 0)
- return;
+ if (output_uV <= 0) {
+ rdev_err(rdev, "invalid output voltage found\n");
+ return -EINVAL;
+ }
/* get input voltage */
input_uV = 0;
@@ -682,8 +667,10 @@ static void drms_uA_update(struct regulator_dev *rdev)
input_uV = regulator_get_voltage(rdev->supply);
if (input_uV <= 0)
input_uV = rdev->constraints->input_uV;
- if (input_uV <= 0)
- return;
+ if (input_uV <= 0) {
+ rdev_err(rdev, "invalid input voltage found\n");
+ return -EINVAL;
+ }
/* calc total requested load */
list_for_each_entry(sibling, &rdev->consumer_list, list)
@@ -695,8 +682,17 @@ static void drms_uA_update(struct regulator_dev *rdev)
/* check the new mode is allowed */
err = regulator_mode_constrain(rdev, &mode);
- if (err == 0)
- rdev->desc->ops->set_mode(rdev, mode);
+ if (err < 0) {
+ rdev_err(rdev, "failed to get optimum mode @ %d uA %d -> %d uV\n",
+ current_uA, input_uV, output_uV);
+ return err;
+ }
+
+ err = rdev->desc->ops->set_mode(rdev, mode);
+ if (err < 0)
+ rdev_err(rdev, "failed to set optimum mode %x\n", mode);
+
+ return err;
}
static int suspend_set_state(struct regulator_dev *rdev,
@@ -828,7 +824,7 @@ static void print_constraints(struct regulator_dev *rdev)
if (!count)
sprintf(buf, "no parameters");
- rdev_info(rdev, "%s\n", buf);
+ rdev_dbg(rdev, "%s\n", buf);
if ((constraints->min_uV != constraints->max_uV) &&
!(constraints->valid_ops_mask & REGULATOR_CHANGE_VOLTAGE))
@@ -1488,7 +1484,7 @@ struct regulator *regulator_get_optional(struct device *dev, const char *id)
}
EXPORT_SYMBOL_GPL(regulator_get_optional);
-/* Locks held by regulator_put() */
+/* regulator_list_mutex lock held by regulator_put() */
static void _regulator_put(struct regulator *regulator)
{
struct regulator_dev *rdev;
@@ -1503,12 +1499,14 @@ static void _regulator_put(struct regulator *regulator)
/* remove any sysfs entries */
if (regulator->dev)
sysfs_remove_link(&rdev->dev.kobj, regulator->supply_name);
+ mutex_lock(&rdev->mutex);
kfree(regulator->supply_name);
list_del(&regulator->list);
kfree(regulator);
rdev->open_count--;
rdev->exclusive = 0;
+ mutex_unlock(&rdev->mutex);
module_put(rdev->owner);
}
@@ -1713,6 +1711,8 @@ static void regulator_ena_gpio_free(struct regulator_dev *rdev)
gpiod_put(pin->gpiod);
list_del(&pin->list);
kfree(pin);
+ rdev->ena_pin = NULL;
+ return;
} else {
pin->request_count--;
}
@@ -1976,9 +1976,18 @@ static int _regulator_disable(struct regulator_dev *rdev)
/* we are last user */
if (_regulator_can_change_status(rdev)) {
+ ret = _notifier_call_chain(rdev,
+ REGULATOR_EVENT_PRE_DISABLE,
+ NULL);
+ if (ret & NOTIFY_STOP_MASK)
+ return -EINVAL;
+
ret = _regulator_do_disable(rdev);
if (ret < 0) {
rdev_err(rdev, "failed to disable\n");
+ _notifier_call_chain(rdev,
+ REGULATOR_EVENT_ABORT_DISABLE,
+ NULL);
return ret;
}
_notifier_call_chain(rdev, REGULATOR_EVENT_DISABLE,
@@ -2035,9 +2044,16 @@ static int _regulator_force_disable(struct regulator_dev *rdev)
{
int ret = 0;
+ ret = _notifier_call_chain(rdev, REGULATOR_EVENT_FORCE_DISABLE |
+ REGULATOR_EVENT_PRE_DISABLE, NULL);
+ if (ret & NOTIFY_STOP_MASK)
+ return -EINVAL;
+
ret = _regulator_do_disable(rdev);
if (ret < 0) {
rdev_err(rdev, "failed to force disable\n");
+ _notifier_call_chain(rdev, REGULATOR_EVENT_FORCE_DISABLE |
+ REGULATOR_EVENT_ABORT_DISABLE, NULL);
return ret;
}
@@ -3006,75 +3022,13 @@ EXPORT_SYMBOL_GPL(regulator_get_mode);
int regulator_set_optimum_mode(struct regulator *regulator, int uA_load)
{
struct regulator_dev *rdev = regulator->rdev;
- struct regulator *consumer;
- int ret, output_uV, input_uV = 0, total_uA_load = 0;
- unsigned int mode;
-
- if (rdev->supply)
- input_uV = regulator_get_voltage(rdev->supply);
+ int ret;
mutex_lock(&rdev->mutex);
-
- /*
- * first check to see if we can set modes at all, otherwise just
- * tell the consumer everything is OK.
- */
regulator->uA_load = uA_load;
- ret = regulator_check_drms(rdev);
- if (ret < 0) {
- ret = 0;
- goto out;
- }
-
- if (!rdev->desc->ops->get_optimum_mode)
- goto out;
-
- /*
- * we can actually do this so any errors are indicators of
- * potential real failure.
- */
- ret = -EINVAL;
-
- if (!rdev->desc->ops->set_mode)
- goto out;
-
- /* get output voltage */
- output_uV = _regulator_get_voltage(rdev);
- if (output_uV <= 0) {
- rdev_err(rdev, "invalid output voltage found\n");
- goto out;
- }
-
- /* No supply? Use constraint voltage */
- if (input_uV <= 0)
- input_uV = rdev->constraints->input_uV;
- if (input_uV <= 0) {
- rdev_err(rdev, "invalid input voltage found\n");
- goto out;
- }
-
- /* calc total requested load for this regulator */
- list_for_each_entry(consumer, &rdev->consumer_list, list)
- total_uA_load += consumer->uA_load;
-
- mode = rdev->desc->ops->get_optimum_mode(rdev,
- input_uV, output_uV,
- total_uA_load);
- ret = regulator_mode_constrain(rdev, &mode);
- if (ret < 0) {
- rdev_err(rdev, "failed to get optimum mode @ %d uA %d -> %d uV\n",
- total_uA_load, input_uV, output_uV);
- goto out;
- }
-
- ret = rdev->desc->ops->set_mode(rdev, mode);
- if (ret < 0) {
- rdev_err(rdev, "failed to set optimum mode %x\n", mode);
- goto out;
- }
- ret = mode;
-out:
+ ret = drms_uA_update(rdev);
mutex_unlock(&rdev->mutex);
+
return ret;
}
EXPORT_SYMBOL_GPL(regulator_set_optimum_mode);
@@ -3416,126 +3370,136 @@ int regulator_mode_to_status(unsigned int mode)
}
EXPORT_SYMBOL_GPL(regulator_mode_to_status);
+static struct attribute *regulator_dev_attrs[] = {
+ &dev_attr_name.attr,
+ &dev_attr_num_users.attr,
+ &dev_attr_type.attr,
+ &dev_attr_microvolts.attr,
+ &dev_attr_microamps.attr,
+ &dev_attr_opmode.attr,
+ &dev_attr_state.attr,
+ &dev_attr_status.attr,
+ &dev_attr_bypass.attr,
+ &dev_attr_requested_microamps.attr,
+ &dev_attr_min_microvolts.attr,
+ &dev_attr_max_microvolts.attr,
+ &dev_attr_min_microamps.attr,
+ &dev_attr_max_microamps.attr,
+ &dev_attr_suspend_standby_state.attr,
+ &dev_attr_suspend_mem_state.attr,
+ &dev_attr_suspend_disk_state.attr,
+ &dev_attr_suspend_standby_microvolts.attr,
+ &dev_attr_suspend_mem_microvolts.attr,
+ &dev_attr_suspend_disk_microvolts.attr,
+ &dev_attr_suspend_standby_mode.attr,
+ &dev_attr_suspend_mem_mode.attr,
+ &dev_attr_suspend_disk_mode.attr,
+ NULL
+};
+
/*
* To avoid cluttering sysfs (and memory) with useless state, only
* create attributes that can be meaningfully displayed.
*/
-static int add_regulator_attributes(struct regulator_dev *rdev)
+static umode_t regulator_attr_is_visible(struct kobject *kobj,
+ struct attribute *attr, int idx)
{
- struct device *dev = &rdev->dev;
+ struct device *dev = kobj_to_dev(kobj);
+ struct regulator_dev *rdev = container_of(dev, struct regulator_dev, dev);
const struct regulator_ops *ops = rdev->desc->ops;
- int status = 0;
+ umode_t mode = attr->mode;
+
+ /* these three are always present */
+ if (attr == &dev_attr_name.attr ||
+ attr == &dev_attr_num_users.attr ||
+ attr == &dev_attr_type.attr)
+ return mode;
/* some attributes need specific methods to be displayed */
- if ((ops->get_voltage && ops->get_voltage(rdev) >= 0) ||
- (ops->get_voltage_sel && ops->get_voltage_sel(rdev) >= 0) ||
- (ops->list_voltage && ops->list_voltage(rdev, 0) >= 0) ||
- (rdev->desc->fixed_uV && (rdev->desc->n_voltages == 1))) {
- status = device_create_file(dev, &dev_attr_microvolts);
- if (status < 0)
- return status;
- }
- if (ops->get_current_limit) {
- status = device_create_file(dev, &dev_attr_microamps);
- if (status < 0)
- return status;
- }
- if (ops->get_mode) {
- status = device_create_file(dev, &dev_attr_opmode);
- if (status < 0)
- return status;
- }
- if (rdev->ena_pin || ops->is_enabled) {
- status = device_create_file(dev, &dev_attr_state);
- if (status < 0)
- return status;
- }
- if (ops->get_status) {
- status = device_create_file(dev, &dev_attr_status);
- if (status < 0)
- return status;
- }
- if (ops->get_bypass) {
- status = device_create_file(dev, &dev_attr_bypass);
- if (status < 0)
- return status;
+ if (attr == &dev_attr_microvolts.attr) {
+ if ((ops->get_voltage && ops->get_voltage(rdev) >= 0) ||
+ (ops->get_voltage_sel && ops->get_voltage_sel(rdev) >= 0) ||
+ (ops->list_voltage && ops->list_voltage(rdev, 0) >= 0) ||
+ (rdev->desc->fixed_uV && rdev->desc->n_voltages == 1))
+ return mode;
+ return 0;
}
+ if (attr == &dev_attr_microamps.attr)
+ return ops->get_current_limit ? mode : 0;
+
+ if (attr == &dev_attr_opmode.attr)
+ return ops->get_mode ? mode : 0;
+
+ if (attr == &dev_attr_state.attr)
+ return (rdev->ena_pin || ops->is_enabled) ? mode : 0;
+
+ if (attr == &dev_attr_status.attr)
+ return ops->get_status ? mode : 0;
+
+ if (attr == &dev_attr_bypass.attr)
+ return ops->get_bypass ? mode : 0;
+
/* some attributes are type-specific */
- if (rdev->desc->type == REGULATOR_CURRENT) {
- status = device_create_file(dev, &dev_attr_requested_microamps);
- if (status < 0)
- return status;
- }
+ if (attr == &dev_attr_requested_microamps.attr)
+ return rdev->desc->type == REGULATOR_CURRENT ? mode : 0;
/* all the other attributes exist to support constraints;
* don't show them if there are no constraints, or if the
* relevant supporting methods are missing.
*/
if (!rdev->constraints)
- return status;
+ return 0;
/* constraints need specific supporting methods */
- if (ops->set_voltage || ops->set_voltage_sel) {
- status = device_create_file(dev, &dev_attr_min_microvolts);
- if (status < 0)
- return status;
- status = device_create_file(dev, &dev_attr_max_microvolts);
- if (status < 0)
- return status;
- }
- if (ops->set_current_limit) {
- status = device_create_file(dev, &dev_attr_min_microamps);
- if (status < 0)
- return status;
- status = device_create_file(dev, &dev_attr_max_microamps);
- if (status < 0)
- return status;
- }
-
- status = device_create_file(dev, &dev_attr_suspend_standby_state);
- if (status < 0)
- return status;
- status = device_create_file(dev, &dev_attr_suspend_mem_state);
- if (status < 0)
- return status;
- status = device_create_file(dev, &dev_attr_suspend_disk_state);
- if (status < 0)
- return status;
+ if (attr == &dev_attr_min_microvolts.attr ||
+ attr == &dev_attr_max_microvolts.attr)
+ return (ops->set_voltage || ops->set_voltage_sel) ? mode : 0;
+
+ if (attr == &dev_attr_min_microamps.attr ||
+ attr == &dev_attr_max_microamps.attr)
+ return ops->set_current_limit ? mode : 0;
+
+ if (attr == &dev_attr_suspend_standby_state.attr ||
+ attr == &dev_attr_suspend_mem_state.attr ||
+ attr == &dev_attr_suspend_disk_state.attr)
+ return mode;
+
+ if (attr == &dev_attr_suspend_standby_microvolts.attr ||
+ attr == &dev_attr_suspend_mem_microvolts.attr ||
+ attr == &dev_attr_suspend_disk_microvolts.attr)
+ return ops->set_suspend_voltage ? mode : 0;
+
+ if (attr == &dev_attr_suspend_standby_mode.attr ||
+ attr == &dev_attr_suspend_mem_mode.attr ||
+ attr == &dev_attr_suspend_disk_mode.attr)
+ return ops->set_suspend_mode ? mode : 0;
- if (ops->set_suspend_voltage) {
- status = device_create_file(dev,
- &dev_attr_suspend_standby_microvolts);
- if (status < 0)
- return status;
- status = device_create_file(dev,
- &dev_attr_suspend_mem_microvolts);
- if (status < 0)
- return status;
- status = device_create_file(dev,
- &dev_attr_suspend_disk_microvolts);
- if (status < 0)
- return status;
- }
-
- if (ops->set_suspend_mode) {
- status = device_create_file(dev,
- &dev_attr_suspend_standby_mode);
- if (status < 0)
- return status;
- status = device_create_file(dev,
- &dev_attr_suspend_mem_mode);
- if (status < 0)
- return status;
- status = device_create_file(dev,
- &dev_attr_suspend_disk_mode);
- if (status < 0)
- return status;
- }
-
- return status;
+ return mode;
}
+static const struct attribute_group regulator_dev_group = {
+ .attrs = regulator_dev_attrs,
+ .is_visible = regulator_attr_is_visible,
+};
+
+static const struct attribute_group *regulator_dev_groups[] = {
+ &regulator_dev_group,
+ NULL
+};
+
+static void regulator_dev_release(struct device *dev)
+{
+ struct regulator_dev *rdev = dev_get_drvdata(dev);
+ kfree(rdev);
+}
+
+static struct class regulator_class = {
+ .name = "regulator",
+ .dev_release = regulator_dev_release,
+ .dev_groups = regulator_dev_groups,
+};
+
static void rdev_init_debugfs(struct regulator_dev *rdev)
{
rdev->debugfs = debugfs_create_dir(rdev_get_name(rdev), debugfs_root);
@@ -3555,7 +3519,7 @@ static void rdev_init_debugfs(struct regulator_dev *rdev)
/**
* regulator_register - register regulator
* @regulator_desc: regulator to register
- * @config: runtime configuration for regulator
+ * @cfg: runtime configuration for regulator
*
* Called by regulator drivers to register a regulator.
* Returns a valid pointer to struct regulator_dev on success
@@ -3563,20 +3527,21 @@ static void rdev_init_debugfs(struct regulator_dev *rdev)
*/
struct regulator_dev *
regulator_register(const struct regulator_desc *regulator_desc,
- const struct regulator_config *config)
+ const struct regulator_config *cfg)
{
const struct regulation_constraints *constraints = NULL;
const struct regulator_init_data *init_data;
- static atomic_t regulator_no = ATOMIC_INIT(0);
+ struct regulator_config *config = NULL;
+ static atomic_t regulator_no = ATOMIC_INIT(-1);
struct regulator_dev *rdev;
struct device *dev;
int ret, i;
const char *supply = NULL;
- if (regulator_desc == NULL || config == NULL)
+ if (regulator_desc == NULL || cfg == NULL)
return ERR_PTR(-EINVAL);
- dev = config->dev;
+ dev = cfg->dev;
WARN_ON(!dev);
if (regulator_desc->name == NULL || regulator_desc->ops == NULL)
@@ -3606,7 +3571,17 @@ regulator_register(const struct regulator_desc *regulator_desc,
if (rdev == NULL)
return ERR_PTR(-ENOMEM);
- init_data = regulator_of_get_init_data(dev, regulator_desc,
+ /*
+ * Duplicate the config so the driver could override it after
+ * parsing init data.
+ */
+ config = kmemdup(cfg, sizeof(*cfg), GFP_KERNEL);
+ if (config == NULL) {
+ kfree(rdev);
+ return ERR_PTR(-ENOMEM);
+ }
+
+ init_data = regulator_of_get_init_data(dev, regulator_desc, config,
&rdev->dev.of_node);
if (!init_data) {
init_data = config->init_data;
@@ -3640,8 +3615,8 @@ regulator_register(const struct regulator_desc *regulator_desc,
/* register with sysfs */
rdev->dev.class = &regulator_class;
rdev->dev.parent = dev;
- dev_set_name(&rdev->dev, "regulator.%d",
- atomic_inc_return(&regulator_no) - 1);
+ dev_set_name(&rdev->dev, "regulator.%lu",
+ (unsigned long) atomic_inc_return(&regulator_no));
ret = device_register(&rdev->dev);
if (ret != 0) {
put_device(&rdev->dev);
@@ -3650,7 +3625,8 @@ regulator_register(const struct regulator_desc *regulator_desc,
dev_set_drvdata(&rdev->dev, rdev);
- if (config->ena_gpio && gpio_is_valid(config->ena_gpio)) {
+ if ((config->ena_gpio || config->ena_gpio_initialized) &&
+ gpio_is_valid(config->ena_gpio)) {
ret = regulator_ena_gpio_request(rdev, config);
if (ret != 0) {
rdev_err(rdev, "Failed to request enable GPIO%d: %d\n",
@@ -3673,11 +3649,6 @@ regulator_register(const struct regulator_desc *regulator_desc,
if (ret < 0)
goto scrub;
- /* add attributes supported by this regulator */
- ret = add_regulator_attributes(rdev);
- if (ret < 0)
- goto scrub;
-
if (init_data && init_data->supply_regulator)
supply = init_data->supply_regulator;
else if (regulator_desc->supply_name)
@@ -3733,6 +3704,7 @@ add_dev:
rdev_init_debugfs(rdev);
out:
mutex_unlock(&regulator_list_mutex);
+ kfree(config);
return rdev;
unset_supplies:
diff --git a/drivers/regulator/da903x.c b/drivers/regulator/da903x.c
index b431ae3..affa1b1 100644
--- a/drivers/regulator/da903x.c
+++ b/drivers/regulator/da903x.c
@@ -475,7 +475,6 @@ static int da903x_regulator_probe(struct platform_device *pdev)
static struct platform_driver da903x_regulator_driver = {
.driver = {
.name = "da903x-regulator",
- .owner = THIS_MODULE,
},
.probe = da903x_regulator_probe,
};
diff --git a/drivers/regulator/da9052-regulator.c b/drivers/regulator/da9052-regulator.c
index 0003362..8a4df7a 100644
--- a/drivers/regulator/da9052-regulator.c
+++ b/drivers/regulator/da9052-regulator.c
@@ -436,7 +436,8 @@ static int da9052_regulator_probe(struct platform_device *pdev)
if (!of_node_cmp(np->name,
regulator->info->reg_desc.name)) {
config.init_data = of_get_regulator_init_data(
- &pdev->dev, np);
+ &pdev->dev, np,
+ &regulator->info->reg_desc);
config.of_node = np;
break;
}
@@ -463,7 +464,6 @@ static struct platform_driver da9052_regulator_driver = {
.probe = da9052_regulator_probe,
.driver = {
.name = "da9052-regulator",
- .owner = THIS_MODULE,
},
};
diff --git a/drivers/regulator/da9055-regulator.c b/drivers/regulator/da9055-regulator.c
index 9516317..cafdafb 100644
--- a/drivers/regulator/da9055-regulator.c
+++ b/drivers/regulator/da9055-regulator.c
@@ -665,7 +665,6 @@ static struct platform_driver da9055_regulator_driver = {
.probe = da9055_regulator_probe,
.driver = {
.name = "da9055-regulator",
- .owner = THIS_MODULE,
},
};
diff --git a/drivers/regulator/da9063-regulator.c b/drivers/regulator/da9063-regulator.c
index 7c9461d..31c2c59 100644
--- a/drivers/regulator/da9063-regulator.c
+++ b/drivers/regulator/da9063-regulator.c
@@ -867,17 +867,14 @@ static int da9063_regulator_probe(struct platform_device *pdev)
return irq;
}
- regulators->irq_ldo_lim = regmap_irq_get_virq(da9063->regmap_irq, irq);
- if (regulators->irq_ldo_lim >= 0) {
- ret = request_threaded_irq(regulators->irq_ldo_lim,
- NULL, da9063_ldo_lim_event,
- IRQF_TRIGGER_LOW | IRQF_ONESHOT,
- "LDO_LIM", regulators);
- if (ret) {
- dev_err(&pdev->dev,
- "Failed to request LDO_LIM IRQ.\n");
- regulators->irq_ldo_lim = -ENXIO;
- }
+ ret = request_threaded_irq(irq,
+ NULL, da9063_ldo_lim_event,
+ IRQF_TRIGGER_LOW | IRQF_ONESHOT,
+ "LDO_LIM", regulators);
+ if (ret) {
+ dev_err(&pdev->dev,
+ "Failed to request LDO_LIM IRQ.\n");
+ regulators->irq_ldo_lim = -ENXIO;
}
return 0;
@@ -896,7 +893,6 @@ static int da9063_regulator_remove(struct platform_device *pdev)
static struct platform_driver da9063_regulator_driver = {
.driver = {
.name = DA9063_DRVNAME_REGULATORS,
- .owner = THIS_MODULE,
},
.probe = da9063_regulator_probe,
.remove = da9063_regulator_remove,
diff --git a/drivers/regulator/da9210-regulator.c b/drivers/regulator/da9210-regulator.c
index 7a320dd..bc61001 100644
--- a/drivers/regulator/da9210-regulator.c
+++ b/drivers/regulator/da9210-regulator.c
@@ -147,7 +147,7 @@ static int da9210_i2c_probe(struct i2c_client *i2c,
config.dev = &i2c->dev;
config.init_data = pdata ? &pdata->da9210_constraints :
- of_get_regulator_init_data(dev, dev->of_node);
+ of_get_regulator_init_data(dev, dev->of_node, &da9210_reg);
config.driver_data = chip;
config.regmap = chip->regmap;
config.of_node = dev->of_node;
diff --git a/drivers/regulator/da9211-regulator.c b/drivers/regulator/da9211-regulator.c
index c78d210..0134341 100644
--- a/drivers/regulator/da9211-regulator.c
+++ b/drivers/regulator/da9211-regulator.c
@@ -24,6 +24,7 @@
#include <linux/regmap.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
+#include <linux/of_gpio.h>
#include <linux/regulator/of_regulator.h>
#include <linux/regulator/da9211.h>
#include "da9211-regulator.h"
@@ -276,7 +277,10 @@ static struct da9211_pdata *da9211_parse_regulators_dt(
continue;
pdata->init_data[n] = da9211_matches[i].init_data;
-
+ pdata->reg_node[n] = da9211_matches[i].of_node;
+ pdata->gpio_ren[n] =
+ of_get_named_gpio(da9211_matches[i].of_node,
+ "enable-gpios", 0);
n++;
}
@@ -364,7 +368,15 @@ static int da9211_regulator_init(struct da9211 *chip)
config.dev = chip->dev;
config.driver_data = chip;
config.regmap = chip->regmap;
- config.of_node = chip->dev->of_node;
+ config.of_node = chip->pdata->reg_node[i];
+
+ if (gpio_is_valid(chip->pdata->gpio_ren[i])) {
+ config.ena_gpio = chip->pdata->gpio_ren[i];
+ config.ena_gpio_initialized = true;
+ } else {
+ config.ena_gpio = -EINVAL;
+ config.ena_gpio_initialized = false;
+ }
chip->rdev[i] = devm_regulator_register(chip->dev,
&da9211_regulators[i], &config);
diff --git a/drivers/regulator/db8500-prcmu.c b/drivers/regulator/db8500-prcmu.c
index 617c1ad..7cec535 100644
--- a/drivers/regulator/db8500-prcmu.c
+++ b/drivers/regulator/db8500-prcmu.c
@@ -534,7 +534,6 @@ static int db8500_regulator_remove(struct platform_device *pdev)
static struct platform_driver db8500_regulator_driver = {
.driver = {
.name = "db8500-prcmu-regulators",
- .owner = THIS_MODULE,
},
.probe = db8500_regulator_probe,
.remove = db8500_regulator_remove,
diff --git a/drivers/regulator/dummy.c b/drivers/regulator/dummy.c
index 2436db9..cde7497 100644
--- a/drivers/regulator/dummy.c
+++ b/drivers/regulator/dummy.c
@@ -33,7 +33,7 @@ static struct regulator_init_data dummy_initdata = {
static struct regulator_ops dummy_ops;
-static struct regulator_desc dummy_desc = {
+static const struct regulator_desc dummy_desc = {
.name = "regulator-dummy",
.id = -1,
.type = REGULATOR_VOLTAGE,
@@ -63,7 +63,6 @@ static struct platform_driver dummy_regulator_driver = {
.probe = dummy_regulator_probe,
.driver = {
.name = "reg-dummy",
- .owner = THIS_MODULE,
},
};
diff --git a/drivers/regulator/fan53555.c b/drivers/regulator/fan53555.c
index f8e4257..3c25db8 100644
--- a/drivers/regulator/fan53555.c
+++ b/drivers/regulator/fan53555.c
@@ -147,7 +147,7 @@ static unsigned int fan53555_get_mode(struct regulator_dev *rdev)
return REGULATOR_MODE_NORMAL;
}
-static int slew_rates[] = {
+static const int slew_rates[] = {
64000,
32000,
16000,
@@ -296,13 +296,14 @@ static int fan53555_regulator_register(struct fan53555_device_info *di,
return PTR_ERR_OR_ZERO(di->rdev);
}
-static struct regmap_config fan53555_regmap_config = {
+static const struct regmap_config fan53555_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
};
static struct fan53555_platform_data *fan53555_parse_dt(struct device *dev,
- struct device_node *np)
+ struct device_node *np,
+ const struct regulator_desc *desc)
{
struct fan53555_platform_data *pdata;
int ret;
@@ -312,7 +313,7 @@ static struct fan53555_platform_data *fan53555_parse_dt(struct device *dev,
if (!pdata)
return NULL;
- pdata->regulator = of_get_regulator_init_data(dev, np);
+ pdata->regulator = of_get_regulator_init_data(dev, np, desc);
ret = of_property_read_u32(np, "fcs,suspend-voltage-selector",
&tmp);
@@ -347,20 +348,20 @@ static int fan53555_regulator_probe(struct i2c_client *client,
unsigned int val;
int ret;
+ di = devm_kzalloc(&client->dev, sizeof(struct fan53555_device_info),
+ GFP_KERNEL);
+ if (!di)
+ return -ENOMEM;
+
pdata = dev_get_platdata(&client->dev);
if (!pdata)
- pdata = fan53555_parse_dt(&client->dev, np);
+ pdata = fan53555_parse_dt(&client->dev, np, &di->desc);
if (!pdata || !pdata->regulator) {
dev_err(&client->dev, "Platform data not found!\n");
return -ENODEV;
}
- di = devm_kzalloc(&client->dev, sizeof(struct fan53555_device_info),
- GFP_KERNEL);
- if (!di)
- return -ENOMEM;
-
di->regulator = pdata->regulator;
if (client->dev.of_node) {
const struct of_device_id *match;
diff --git a/drivers/regulator/fixed.c b/drivers/regulator/fixed.c
index 354105e..ff62d69 100644
--- a/drivers/regulator/fixed.c
+++ b/drivers/regulator/fixed.c
@@ -40,13 +40,15 @@ struct fixed_voltage_data {
/**
* of_get_fixed_voltage_config - extract fixed_voltage_config structure info
* @dev: device requesting for fixed_voltage_config
+ * @desc: regulator description
*
* Populates fixed_voltage_config structure by extracting data from device
* tree node, returns a pointer to the populated structure of NULL if memory
* alloc fails.
*/
static struct fixed_voltage_config *
-of_get_fixed_voltage_config(struct device *dev)
+of_get_fixed_voltage_config(struct device *dev,
+ const struct regulator_desc *desc)
{
struct fixed_voltage_config *config;
struct device_node *np = dev->of_node;
@@ -57,7 +59,7 @@ of_get_fixed_voltage_config(struct device *dev)
if (!config)
return ERR_PTR(-ENOMEM);
- config->init_data = of_get_regulator_init_data(dev, dev->of_node);
+ config->init_data = of_get_regulator_init_data(dev, dev->of_node, desc);
if (!config->init_data)
return ERR_PTR(-EINVAL);
@@ -112,8 +114,14 @@ static int reg_fixed_voltage_probe(struct platform_device *pdev)
struct regulator_config cfg = { };
int ret;
+ drvdata = devm_kzalloc(&pdev->dev, sizeof(struct fixed_voltage_data),
+ GFP_KERNEL);
+ if (!drvdata)
+ return -ENOMEM;
+
if (pdev->dev.of_node) {
- config = of_get_fixed_voltage_config(&pdev->dev);
+ config = of_get_fixed_voltage_config(&pdev->dev,
+ &drvdata->desc);
if (IS_ERR(config))
return PTR_ERR(config);
} else {
@@ -123,11 +131,6 @@ static int reg_fixed_voltage_probe(struct platform_device *pdev)
if (!config)
return -ENOMEM;
- drvdata = devm_kzalloc(&pdev->dev, sizeof(struct fixed_voltage_data),
- GFP_KERNEL);
- if (!drvdata)
- return -ENOMEM;
-
drvdata->desc.name = devm_kstrdup(&pdev->dev,
config->supply_name,
GFP_KERNEL);
@@ -157,8 +160,11 @@ static int reg_fixed_voltage_probe(struct platform_device *pdev)
drvdata->desc.fixed_uV = config->microvolts;
- if (config->gpio >= 0)
+ if (gpio_is_valid(config->gpio)) {
cfg.ena_gpio = config->gpio;
+ if (pdev->dev.of_node)
+ cfg.ena_gpio_initialized = true;
+ }
cfg.ena_gpio_invert = !config->enable_high;
if (config->enabled_at_boot) {
if (config->enable_high)
@@ -207,7 +213,6 @@ static struct platform_driver regulator_fixed_voltage_driver = {
.probe = reg_fixed_voltage_probe,
.driver = {
.name = "reg-fixed-voltage",
- .owner = THIS_MODULE,
.of_match_table = of_match_ptr(fixed_of_match),
},
};
diff --git a/drivers/regulator/gpio-regulator.c b/drivers/regulator/gpio-regulator.c
index 989b23b..464018d 100644
--- a/drivers/regulator/gpio-regulator.c
+++ b/drivers/regulator/gpio-regulator.c
@@ -133,7 +133,8 @@ static struct regulator_ops gpio_regulator_voltage_ops = {
};
static struct gpio_regulator_config *
-of_get_gpio_regulator_config(struct device *dev, struct device_node *np)
+of_get_gpio_regulator_config(struct device *dev, struct device_node *np,
+ const struct regulator_desc *desc)
{
struct gpio_regulator_config *config;
const char *regtype;
@@ -146,7 +147,7 @@ of_get_gpio_regulator_config(struct device *dev, struct device_node *np)
if (!config)
return ERR_PTR(-ENOMEM);
- config->init_data = of_get_regulator_init_data(dev, np);
+ config->init_data = of_get_regulator_init_data(dev, np, desc);
if (!config->init_data)
return ERR_PTR(-EINVAL);
@@ -162,34 +163,41 @@ of_get_gpio_regulator_config(struct device *dev, struct device_node *np)
config->enable_gpio = of_get_named_gpio(np, "enable-gpio", 0);
- /* Fetch GPIOs. */
- config->nr_gpios = of_gpio_count(np);
-
- config->gpios = devm_kzalloc(dev,
- sizeof(struct gpio) * config->nr_gpios,
- GFP_KERNEL);
- if (!config->gpios)
- return ERR_PTR(-ENOMEM);
-
- proplen = of_property_count_u32_elems(np, "gpios-states");
- /* optional property */
- if (proplen < 0)
- proplen = 0;
-
- if (proplen > 0 && proplen != config->nr_gpios) {
- dev_warn(dev, "gpios <-> gpios-states mismatch\n");
- proplen = 0;
- }
+ /* Fetch GPIOs. - optional property*/
+ ret = of_gpio_count(np);
+ if ((ret < 0) && (ret != -ENOENT))
+ return ERR_PTR(ret);
+
+ if (ret > 0) {
+ config->nr_gpios = ret;
+ config->gpios = devm_kzalloc(dev,
+ sizeof(struct gpio) * config->nr_gpios,
+ GFP_KERNEL);
+ if (!config->gpios)
+ return ERR_PTR(-ENOMEM);
+
+ proplen = of_property_count_u32_elems(np, "gpios-states");
+ /* optional property */
+ if (proplen < 0)
+ proplen = 0;
+
+ if (proplen > 0 && proplen != config->nr_gpios) {
+ dev_warn(dev, "gpios <-> gpios-states mismatch\n");
+ proplen = 0;
+ }
- for (i = 0; i < config->nr_gpios; i++) {
- gpio = of_get_named_gpio(np, "gpios", i);
- if (gpio < 0)
- break;
- config->gpios[i].gpio = gpio;
- if (proplen > 0) {
- of_property_read_u32_index(np, "gpios-states", i, &ret);
- if (ret)
- config->gpios[i].flags = GPIOF_OUT_INIT_HIGH;
+ for (i = 0; i < config->nr_gpios; i++) {
+ gpio = of_get_named_gpio(np, "gpios", i);
+ if (gpio < 0)
+ break;
+ config->gpios[i].gpio = gpio;
+ if (proplen > 0) {
+ of_property_read_u32_index(np, "gpios-states",
+ i, &ret);
+ if (ret)
+ config->gpios[i].flags =
+ GPIOF_OUT_INIT_HIGH;
+ }
}
}
@@ -243,17 +251,18 @@ static int gpio_regulator_probe(struct platform_device *pdev)
struct regulator_config cfg = { };
int ptr, ret, state;
- if (np) {
- config = of_get_gpio_regulator_config(&pdev->dev, np);
- if (IS_ERR(config))
- return PTR_ERR(config);
- }
-
drvdata = devm_kzalloc(&pdev->dev, sizeof(struct gpio_regulator_data),
GFP_KERNEL);
if (drvdata == NULL)
return -ENOMEM;
+ if (np) {
+ config = of_get_gpio_regulator_config(&pdev->dev, np,
+ &drvdata->desc);
+ if (IS_ERR(config))
+ return PTR_ERR(config);
+ }
+
drvdata->desc.name = kstrdup(config->supply_name, GFP_KERNEL);
if (drvdata->desc.name == NULL) {
dev_err(&pdev->dev, "Failed to allocate supply name\n");
@@ -261,13 +270,23 @@ static int gpio_regulator_probe(struct platform_device *pdev)
goto err;
}
- drvdata->gpios = kmemdup(config->gpios,
- config->nr_gpios * sizeof(struct gpio),
- GFP_KERNEL);
- if (drvdata->gpios == NULL) {
- dev_err(&pdev->dev, "Failed to allocate gpio data\n");
- ret = -ENOMEM;
- goto err_name;
+ if (config->nr_gpios != 0) {
+ drvdata->gpios = kmemdup(config->gpios,
+ config->nr_gpios * sizeof(struct gpio),
+ GFP_KERNEL);
+ if (drvdata->gpios == NULL) {
+ dev_err(&pdev->dev, "Failed to allocate gpio data\n");
+ ret = -ENOMEM;
+ goto err_name;
+ }
+
+ drvdata->nr_gpios = config->nr_gpios;
+ ret = gpio_request_array(drvdata->gpios, drvdata->nr_gpios);
+ if (ret) {
+ dev_err(&pdev->dev,
+ "Could not obtain regulator setting GPIOs: %d\n", ret);
+ goto err_memstate;
+ }
}
drvdata->states = kmemdup(config->states,
@@ -301,14 +320,6 @@ static int gpio_regulator_probe(struct platform_device *pdev)
goto err_memgpio;
}
- drvdata->nr_gpios = config->nr_gpios;
- ret = gpio_request_array(drvdata->gpios, drvdata->nr_gpios);
- if (ret) {
- dev_err(&pdev->dev,
- "Could not obtain regulator setting GPIOs: %d\n", ret);
- goto err_memstate;
- }
-
/* build initial state from gpio init data. */
state = 0;
for (ptr = 0; ptr < drvdata->nr_gpios; ptr++) {
@@ -322,8 +333,10 @@ static int gpio_regulator_probe(struct platform_device *pdev)
cfg.driver_data = drvdata;
cfg.of_node = np;
- if (config->enable_gpio >= 0)
+ if (gpio_is_valid(config->enable_gpio)) {
cfg.ena_gpio = config->enable_gpio;
+ cfg.ena_gpio_initialized = true;
+ }
cfg.ena_gpio_invert = !config->enable_high;
if (config->enabled_at_boot) {
if (config->enable_high)
@@ -388,7 +401,6 @@ static struct platform_driver gpio_regulator_driver = {
.remove = gpio_regulator_remove,
.driver = {
.name = "gpio-regulator",
- .owner = THIS_MODULE,
.of_match_table = of_match_ptr(regulator_gpio_of_match),
},
};
diff --git a/drivers/regulator/hi6421-regulator.c b/drivers/regulator/hi6421-regulator.c
index 156d0d1..42dc5fb 100644
--- a/drivers/regulator/hi6421-regulator.c
+++ b/drivers/regulator/hi6421-regulator.c
@@ -623,7 +623,6 @@ static int hi6421_regulator_probe(struct platform_device *pdev)
static struct platform_driver hi6421_regulator_driver = {
.driver = {
.name = "hi6421-regulator",
- .owner = THIS_MODULE,
},
.probe = hi6421_regulator_probe,
};
diff --git a/drivers/regulator/internal.h b/drivers/regulator/internal.h
index 80ba2a3..c74ac87 100644
--- a/drivers/regulator/internal.h
+++ b/drivers/regulator/internal.h
@@ -38,11 +38,13 @@ struct regulator {
#ifdef CONFIG_OF
struct regulator_init_data *regulator_of_get_init_data(struct device *dev,
const struct regulator_desc *desc,
+ struct regulator_config *config,
struct device_node **node);
#else
static inline struct regulator_init_data *
regulator_of_get_init_data(struct device *dev,
const struct regulator_desc *desc,
+ struct regulator_config *config,
struct device_node **node)
{
return NULL;
diff --git a/drivers/regulator/isl9305.c b/drivers/regulator/isl9305.c
index 92fefd9..6e3a15f 100644
--- a/drivers/regulator/isl9305.c
+++ b/drivers/regulator/isl9305.c
@@ -177,8 +177,10 @@ static int isl9305_i2c_probe(struct i2c_client *i2c,
#ifdef CONFIG_OF
static const struct of_device_id isl9305_dt_ids[] = {
- { .compatible = "isl,isl9305" },
- { .compatible = "isl,isl9305h" },
+ { .compatible = "isl,isl9305" }, /* for backward compat., don't use */
+ { .compatible = "isil,isl9305" },
+ { .compatible = "isl,isl9305h" }, /* for backward compat., don't use */
+ { .compatible = "isil,isl9305h" },
{},
};
#endif
diff --git a/drivers/regulator/lp872x.c b/drivers/regulator/lp872x.c
index 021d64d..3de328a 100644
--- a/drivers/regulator/lp872x.c
+++ b/drivers/regulator/lp872x.c
@@ -106,7 +106,6 @@ struct lp872x {
struct device *dev;
enum lp872x_id chipid;
struct lp872x_platform_data *pdata;
- struct regulator_dev **regulators;
int num_regulators;
enum lp872x_dvs_state dvs_pin;
int dvs_gpio;
@@ -801,8 +800,6 @@ static int lp872x_regulator_register(struct lp872x *lp)
dev_err(lp->dev, "regulator register err");
return PTR_ERR(rdev);
}
-
- *(lp->regulators + i) = rdev;
}
return 0;
@@ -906,7 +903,7 @@ static struct lp872x_platform_data
static int lp872x_probe(struct i2c_client *cl, const struct i2c_device_id *id)
{
struct lp872x *lp;
- int ret, size, num_regulators;
+ int ret;
const int lp872x_num_regulators[] = {
[LP8720] = LP8720_NUM_REGULATORS,
[LP8725] = LP8725_NUM_REGULATORS,
@@ -918,38 +915,27 @@ static int lp872x_probe(struct i2c_client *cl, const struct i2c_device_id *id)
lp = devm_kzalloc(&cl->dev, sizeof(struct lp872x), GFP_KERNEL);
if (!lp)
- goto err_mem;
-
- num_regulators = lp872x_num_regulators[id->driver_data];
- size = sizeof(struct regulator_dev *) * num_regulators;
+ return -ENOMEM;
- lp->regulators = devm_kzalloc(&cl->dev, size, GFP_KERNEL);
- if (!lp->regulators)
- goto err_mem;
+ lp->num_regulators = lp872x_num_regulators[id->driver_data];
lp->regmap = devm_regmap_init_i2c(cl, &lp872x_regmap_config);
if (IS_ERR(lp->regmap)) {
ret = PTR_ERR(lp->regmap);
dev_err(&cl->dev, "regmap init i2c err: %d\n", ret);
- goto err_dev;
+ return ret;
}
lp->dev = &cl->dev;
lp->pdata = dev_get_platdata(&cl->dev);
lp->chipid = id->driver_data;
- lp->num_regulators = num_regulators;
i2c_set_clientdata(cl, lp);
ret = lp872x_config(lp);
if (ret)
- goto err_dev;
+ return ret;
return lp872x_regulator_register(lp);
-
-err_mem:
- return -ENOMEM;
-err_dev:
- return ret;
}
static const struct of_device_id lp872x_dt_ids[] = {
diff --git a/drivers/regulator/lp8788-buck.c b/drivers/regulator/lp8788-buck.c
index 948afc2..a97bed9 100644
--- a/drivers/regulator/lp8788-buck.c
+++ b/drivers/regulator/lp8788-buck.c
@@ -533,7 +533,6 @@ static struct platform_driver lp8788_buck_driver = {
.probe = lp8788_buck_probe,
.driver = {
.name = LP8788_DEV_BUCK,
- .owner = THIS_MODULE,
},
};
diff --git a/drivers/regulator/lp8788-ldo.c b/drivers/regulator/lp8788-ldo.c
index b9a29a2..9f22d07 100644
--- a/drivers/regulator/lp8788-ldo.c
+++ b/drivers/regulator/lp8788-ldo.c
@@ -561,7 +561,6 @@ static struct platform_driver lp8788_dldo_driver = {
.probe = lp8788_dldo_probe,
.driver = {
.name = LP8788_DEV_DLDO,
- .owner = THIS_MODULE,
},
};
@@ -611,7 +610,6 @@ static struct platform_driver lp8788_aldo_driver = {
.probe = lp8788_aldo_probe,
.driver = {
.name = LP8788_DEV_ALDO,
- .owner = THIS_MODULE,
},
};
diff --git a/drivers/regulator/max14577.c b/drivers/regulator/max14577.c
index 0ff5a20..b3678d2 100644
--- a/drivers/regulator/max14577.c
+++ b/drivers/regulator/max14577.c
@@ -103,6 +103,8 @@ static struct regulator_ops max14577_charger_ops = {
static const struct regulator_desc max14577_supported_regulators[] = {
[MAX14577_SAFEOUT] = {
.name = "SAFEOUT",
+ .of_match = of_match_ptr("SAFEOUT"),
+ .regulators_node = of_match_ptr("regulators"),
.id = MAX14577_SAFEOUT,
.ops = &max14577_safeout_ops,
.type = REGULATOR_VOLTAGE,
@@ -114,6 +116,8 @@ static const struct regulator_desc max14577_supported_regulators[] = {
},
[MAX14577_CHARGER] = {
.name = "CHARGER",
+ .of_match = of_match_ptr("CHARGER"),
+ .regulators_node = of_match_ptr("regulators"),
.id = MAX14577_CHARGER,
.ops = &max14577_charger_ops,
.type = REGULATOR_CURRENT,
@@ -137,6 +141,8 @@ static struct regulator_ops max77836_ldo_ops = {
static const struct regulator_desc max77836_supported_regulators[] = {
[MAX14577_SAFEOUT] = {
.name = "SAFEOUT",
+ .of_match = of_match_ptr("SAFEOUT"),
+ .regulators_node = of_match_ptr("regulators"),
.id = MAX14577_SAFEOUT,
.ops = &max14577_safeout_ops,
.type = REGULATOR_VOLTAGE,
@@ -148,6 +154,8 @@ static const struct regulator_desc max77836_supported_regulators[] = {
},
[MAX14577_CHARGER] = {
.name = "CHARGER",
+ .of_match = of_match_ptr("CHARGER"),
+ .regulators_node = of_match_ptr("regulators"),
.id = MAX14577_CHARGER,
.ops = &max14577_charger_ops,
.type = REGULATOR_CURRENT,
@@ -157,6 +165,8 @@ static const struct regulator_desc max77836_supported_regulators[] = {
},
[MAX77836_LDO1] = {
.name = "LDO1",
+ .of_match = of_match_ptr("LDO1"),
+ .regulators_node = of_match_ptr("regulators"),
.id = MAX77836_LDO1,
.ops = &max77836_ldo_ops,
.type = REGULATOR_VOLTAGE,
@@ -171,6 +181,8 @@ static const struct regulator_desc max77836_supported_regulators[] = {
},
[MAX77836_LDO2] = {
.name = "LDO2",
+ .of_match = of_match_ptr("LDO2"),
+ .regulators_node = of_match_ptr("regulators"),
.id = MAX77836_LDO2,
.ops = &max77836_ldo_ops,
.type = REGULATOR_VOLTAGE,
@@ -198,43 +210,6 @@ static struct of_regulator_match max77836_regulator_matches[] = {
{ .name = "LDO2", },
};
-static int max14577_regulator_dt_parse_pdata(struct platform_device *pdev,
- enum maxim_device_type dev_type)
-{
- int ret;
- struct device_node *np;
- struct of_regulator_match *regulator_matches;
- unsigned int regulator_matches_size;
-
- np = of_get_child_by_name(pdev->dev.parent->of_node, "regulators");
- if (!np) {
- dev_err(&pdev->dev, "Failed to get child OF node for regulators\n");
- return -EINVAL;
- }
-
- switch (dev_type) {
- case MAXIM_DEVICE_TYPE_MAX77836:
- regulator_matches = max77836_regulator_matches;
- regulator_matches_size = ARRAY_SIZE(max77836_regulator_matches);
- break;
- case MAXIM_DEVICE_TYPE_MAX14577:
- default:
- regulator_matches = max14577_regulator_matches;
- regulator_matches_size = ARRAY_SIZE(max14577_regulator_matches);
- }
-
- ret = of_regulator_match(&pdev->dev, np, regulator_matches,
- regulator_matches_size);
- if (ret < 0)
- dev_err(&pdev->dev, "Error parsing regulator init data: %d\n", ret);
- else
- ret = 0;
-
- of_node_put(np);
-
- return ret;
-}
-
static inline struct regulator_init_data *match_init_data(int index,
enum maxim_device_type dev_type)
{
@@ -261,11 +236,6 @@ static inline struct device_node *match_of_node(int index,
}
}
#else /* CONFIG_OF */
-static int max14577_regulator_dt_parse_pdata(struct platform_device *pdev,
- enum maxim_device_type dev_type)
-{
- return 0;
-}
static inline struct regulator_init_data *match_init_data(int index,
enum maxim_device_type dev_type)
{
@@ -308,16 +278,12 @@ static int max14577_regulator_probe(struct platform_device *pdev)
{
struct max14577 *max14577 = dev_get_drvdata(pdev->dev.parent);
struct max14577_platform_data *pdata = dev_get_platdata(max14577->dev);
- int i, ret;
+ int i, ret = 0;
struct regulator_config config = {};
const struct regulator_desc *supported_regulators;
unsigned int supported_regulators_size;
enum maxim_device_type dev_type = max14577->dev_type;
- ret = max14577_regulator_dt_parse_pdata(pdev, dev_type);
- if (ret)
- return ret;
-
switch (dev_type) {
case MAXIM_DEVICE_TYPE_MAX77836:
supported_regulators = max77836_supported_regulators;
@@ -329,7 +295,7 @@ static int max14577_regulator_probe(struct platform_device *pdev)
supported_regulators_size = ARRAY_SIZE(max14577_supported_regulators);
}
- config.dev = &pdev->dev;
+ config.dev = max14577->dev;
config.driver_data = max14577;
for (i = 0; i < supported_regulators_size; i++) {
@@ -371,7 +337,6 @@ MODULE_DEVICE_TABLE(platform, max14577_regulator_id);
static struct platform_driver max14577_regulator_driver = {
.driver = {
- .owner = THIS_MODULE,
.name = "max14577-regulator",
},
.probe = max14577_regulator_probe,
diff --git a/drivers/regulator/max1586.c b/drivers/regulator/max1586.c
index 86db310..d2a8c64c 100644
--- a/drivers/regulator/max1586.c
+++ b/drivers/regulator/max1586.c
@@ -163,7 +163,7 @@ static int of_get_max1586_platform_data(struct device *dev,
struct max1586_platform_data *pdata)
{
struct max1586_subdev_data *sub;
- struct of_regulator_match rmatch[ARRAY_SIZE(max1586_reg)];
+ struct of_regulator_match rmatch[ARRAY_SIZE(max1586_reg)] = { };
struct device_node *np = dev->of_node;
int i, matched;
diff --git a/drivers/regulator/max77686.c b/drivers/regulator/max77686.c
index ef1af2d..15fb141 100644
--- a/drivers/regulator/max77686.c
+++ b/drivers/regulator/max77686.c
@@ -26,6 +26,7 @@
#include <linux/bug.h>
#include <linux/err.h>
#include <linux/gpio.h>
+#include <linux/of_gpio.h>
#include <linux/slab.h>
#include <linux/platform_device.h>
#include <linux/regulator/driver.h>
@@ -45,6 +46,28 @@
#define MAX77686_DVS_MINUV 600000
#define MAX77686_DVS_UVSTEP 12500
+/*
+ * Value for configuring buck[89] and LDO{20,21,22} as GPIO control.
+ * It is the same as 'off' for other regulators.
+ */
+#define MAX77686_GPIO_CONTROL 0x0
+/*
+ * Values used for configuring LDOs and bucks.
+ * Forcing low power mode: LDO1, 3-5, 9, 13, 17-26
+ */
+#define MAX77686_LDO_LOWPOWER 0x1
+/*
+ * On/off controlled by PWRREQ:
+ * - LDO2, 6-8, 10-12, 14-16
+ * - buck[1234]
+ */
+#define MAX77686_OFF_PWRREQ 0x1
+/* Low power mode controlled by PWRREQ: All LDOs */
+#define MAX77686_LDO_LOWPOWER_PWRREQ 0x2
+/* Forcing low power mode: buck[234] */
+#define MAX77686_BUCK_LOWPOWER 0x2
+#define MAX77686_NORMAL 0x3
+
#define MAX77686_OPMODE_SHIFT 6
#define MAX77686_OPMODE_BUCK234_SHIFT 4
#define MAX77686_OPMODE_MASK 0x3
@@ -65,23 +88,58 @@ enum max77686_ramp_rate {
};
struct max77686_data {
+ u64 gpio_enabled:MAX77686_REGULATORS;
+
+ /* Array indexed by regulator id */
unsigned int opmode[MAX77686_REGULATORS];
};
-/* Some BUCKS supports Normal[ON/OFF] mode during suspend */
-static int max77686_buck_set_suspend_disable(struct regulator_dev *rdev)
+static unsigned int max77686_get_opmode_shift(int id)
{
- unsigned int val;
+ switch (id) {
+ case MAX77686_BUCK1:
+ case MAX77686_BUCK5 ... MAX77686_BUCK9:
+ return 0;
+ case MAX77686_BUCK2 ... MAX77686_BUCK4:
+ return MAX77686_OPMODE_BUCK234_SHIFT;
+ default:
+ /* all LDOs */
+ return MAX77686_OPMODE_SHIFT;
+ }
+}
+
+/*
+ * When regulator is configured for GPIO control then it
+ * replaces "normal" mode. Any change from low power mode to normal
+ * should actually change to GPIO control.
+ * Map normal mode to proper value for such regulators.
+ */
+static unsigned int max77686_map_normal_mode(struct max77686_data *max77686,
+ int id)
+{
+ switch (id) {
+ case MAX77686_BUCK8:
+ case MAX77686_BUCK9:
+ case MAX77686_LDO20 ... MAX77686_LDO22:
+ if (max77686->gpio_enabled & (1 << id))
+ return MAX77686_GPIO_CONTROL;
+ }
+
+ return MAX77686_NORMAL;
+}
+
+/* Some BUCKs and LDOs supports Normal[ON/OFF] mode during suspend */
+static int max77686_set_suspend_disable(struct regulator_dev *rdev)
+{
+ unsigned int val, shift;
struct max77686_data *max77686 = rdev_get_drvdata(rdev);
int ret, id = rdev_get_id(rdev);
- if (id == MAX77686_BUCK1)
- val = 0x1;
- else
- val = 0x1 << MAX77686_OPMODE_BUCK234_SHIFT;
+ shift = max77686_get_opmode_shift(id);
+ val = MAX77686_OFF_PWRREQ;
ret = regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
- rdev->desc->enable_mask, val);
+ rdev->desc->enable_mask, val << shift);
if (ret)
return ret;
@@ -103,10 +161,10 @@ static int max77686_set_suspend_mode(struct regulator_dev *rdev,
switch (mode) {
case REGULATOR_MODE_IDLE: /* ON in LP Mode */
- val = 0x2 << MAX77686_OPMODE_SHIFT;
+ val = MAX77686_LDO_LOWPOWER_PWRREQ;
break;
case REGULATOR_MODE_NORMAL: /* ON in Normal Mode */
- val = 0x3 << MAX77686_OPMODE_SHIFT;
+ val = max77686_map_normal_mode(max77686, id);
break;
default:
pr_warn("%s: regulator_suspend_mode : 0x%x not supported\n",
@@ -115,7 +173,8 @@ static int max77686_set_suspend_mode(struct regulator_dev *rdev,
}
ret = regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
- rdev->desc->enable_mask, val);
+ rdev->desc->enable_mask,
+ val << MAX77686_OPMODE_SHIFT);
if (ret)
return ret;
@@ -129,17 +188,17 @@ static int max77686_ldo_set_suspend_mode(struct regulator_dev *rdev,
{
unsigned int val;
struct max77686_data *max77686 = rdev_get_drvdata(rdev);
- int ret;
+ int ret, id = rdev_get_id(rdev);
switch (mode) {
case REGULATOR_MODE_STANDBY: /* switch off */
- val = 0x1 << MAX77686_OPMODE_SHIFT;
+ val = MAX77686_OFF_PWRREQ;
break;
case REGULATOR_MODE_IDLE: /* ON in LP Mode */
- val = 0x2 << MAX77686_OPMODE_SHIFT;
+ val = MAX77686_LDO_LOWPOWER_PWRREQ;
break;
case REGULATOR_MODE_NORMAL: /* ON in Normal Mode */
- val = 0x3 << MAX77686_OPMODE_SHIFT;
+ val = max77686_map_normal_mode(max77686, id);
break;
default:
pr_warn("%s: regulator_suspend_mode : 0x%x not supported\n",
@@ -148,21 +207,29 @@ static int max77686_ldo_set_suspend_mode(struct regulator_dev *rdev,
}
ret = regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
- rdev->desc->enable_mask, val);
+ rdev->desc->enable_mask,
+ val << MAX77686_OPMODE_SHIFT);
if (ret)
return ret;
- max77686->opmode[rdev_get_id(rdev)] = val;
+ max77686->opmode[id] = val;
return 0;
}
static int max77686_enable(struct regulator_dev *rdev)
{
struct max77686_data *max77686 = rdev_get_drvdata(rdev);
+ unsigned int shift;
+ int id = rdev_get_id(rdev);
+
+ shift = max77686_get_opmode_shift(id);
+
+ if (max77686->opmode[id] == MAX77686_OFF_PWRREQ)
+ max77686->opmode[id] = max77686_map_normal_mode(max77686, id);
return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
rdev->desc->enable_mask,
- max77686->opmode[rdev_get_id(rdev)]);
+ max77686->opmode[id] << shift);
}
static int max77686_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay)
@@ -190,6 +257,36 @@ static int max77686_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay)
MAX77686_RAMP_RATE_MASK, ramp_value << 6);
}
+static int max77686_of_parse_cb(struct device_node *np,
+ const struct regulator_desc *desc,
+ struct regulator_config *config)
+{
+ struct max77686_data *max77686 = config->driver_data;
+
+ switch (desc->id) {
+ case MAX77686_BUCK8:
+ case MAX77686_BUCK9:
+ case MAX77686_LDO20 ... MAX77686_LDO22:
+ config->ena_gpio = of_get_named_gpio(np,
+ "maxim,ena-gpios", 0);
+ config->ena_gpio_flags = GPIOF_OUT_INIT_HIGH;
+ config->ena_gpio_initialized = true;
+ break;
+ default:
+ return 0;
+ }
+
+ if (gpio_is_valid(config->ena_gpio)) {
+ max77686->gpio_enabled |= (1 << desc->id);
+
+ return regmap_update_bits(config->regmap, desc->enable_reg,
+ desc->enable_mask,
+ MAX77686_GPIO_CONTROL);
+ }
+
+ return 0;
+}
+
static struct regulator_ops max77686_ops = {
.list_voltage = regulator_list_voltage_linear,
.map_voltage = regulator_map_voltage_linear,
@@ -212,6 +309,7 @@ static struct regulator_ops max77686_ldo_ops = {
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.set_voltage_time_sel = regulator_set_voltage_time_sel,
.set_suspend_mode = max77686_ldo_set_suspend_mode,
+ .set_suspend_disable = max77686_set_suspend_disable,
};
static struct regulator_ops max77686_buck1_ops = {
@@ -223,7 +321,7 @@ static struct regulator_ops max77686_buck1_ops = {
.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,
- .set_suspend_disable = max77686_buck_set_suspend_disable,
+ .set_suspend_disable = max77686_set_suspend_disable,
};
static struct regulator_ops max77686_buck_dvs_ops = {
@@ -236,11 +334,14 @@ static struct regulator_ops max77686_buck_dvs_ops = {
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.set_voltage_time_sel = regulator_set_voltage_time_sel,
.set_ramp_delay = max77686_set_ramp_delay,
- .set_suspend_disable = max77686_buck_set_suspend_disable,
+ .set_suspend_disable = max77686_set_suspend_disable,
};
#define regulator_desc_ldo(num) { \
.name = "LDO"#num, \
+ .of_match = of_match_ptr("LDO"#num), \
+ .regulators_node = of_match_ptr("voltage-regulators"), \
+ .of_parse_cb = max77686_of_parse_cb, \
.id = MAX77686_LDO##num, \
.ops = &max77686_ops, \
.type = REGULATOR_VOLTAGE, \
@@ -257,6 +358,8 @@ static struct regulator_ops max77686_buck_dvs_ops = {
}
#define regulator_desc_lpm_ldo(num) { \
.name = "LDO"#num, \
+ .of_match = of_match_ptr("LDO"#num), \
+ .regulators_node = of_match_ptr("voltage-regulators"), \
.id = MAX77686_LDO##num, \
.ops = &max77686_ldo_ops, \
.type = REGULATOR_VOLTAGE, \
@@ -273,6 +376,8 @@ static struct regulator_ops max77686_buck_dvs_ops = {
}
#define regulator_desc_ldo_low(num) { \
.name = "LDO"#num, \
+ .of_match = of_match_ptr("LDO"#num), \
+ .regulators_node = of_match_ptr("voltage-regulators"), \
.id = MAX77686_LDO##num, \
.ops = &max77686_ldo_ops, \
.type = REGULATOR_VOLTAGE, \
@@ -289,6 +394,8 @@ static struct regulator_ops max77686_buck_dvs_ops = {
}
#define regulator_desc_ldo1_low(num) { \
.name = "LDO"#num, \
+ .of_match = of_match_ptr("LDO"#num), \
+ .regulators_node = of_match_ptr("voltage-regulators"), \
.id = MAX77686_LDO##num, \
.ops = &max77686_ops, \
.type = REGULATOR_VOLTAGE, \
@@ -305,6 +412,9 @@ static struct regulator_ops max77686_buck_dvs_ops = {
}
#define regulator_desc_buck(num) { \
.name = "BUCK"#num, \
+ .of_match = of_match_ptr("BUCK"#num), \
+ .regulators_node = of_match_ptr("voltage-regulators"), \
+ .of_parse_cb = max77686_of_parse_cb, \
.id = MAX77686_BUCK##num, \
.ops = &max77686_ops, \
.type = REGULATOR_VOLTAGE, \
@@ -320,6 +430,8 @@ static struct regulator_ops max77686_buck_dvs_ops = {
}
#define regulator_desc_buck1(num) { \
.name = "BUCK"#num, \
+ .of_match = of_match_ptr("BUCK"#num), \
+ .regulators_node = of_match_ptr("voltage-regulators"), \
.id = MAX77686_BUCK##num, \
.ops = &max77686_buck1_ops, \
.type = REGULATOR_VOLTAGE, \
@@ -335,6 +447,8 @@ static struct regulator_ops max77686_buck_dvs_ops = {
}
#define regulator_desc_buck_dvs(num) { \
.name = "BUCK"#num, \
+ .of_match = of_match_ptr("BUCK"#num), \
+ .regulators_node = of_match_ptr("voltage-regulators"), \
.id = MAX77686_BUCK##num, \
.ops = &max77686_buck_dvs_ops, \
.type = REGULATOR_VOLTAGE, \
@@ -350,7 +464,7 @@ static struct regulator_ops max77686_buck_dvs_ops = {
<< MAX77686_OPMODE_BUCK234_SHIFT, \
}
-static struct regulator_desc regulators[] = {
+static const struct regulator_desc regulators[] = {
regulator_desc_ldo1_low(1),
regulator_desc_ldo_low(2),
regulator_desc_ldo(3),
@@ -388,103 +502,37 @@ static struct regulator_desc regulators[] = {
regulator_desc_buck(9),
};
-#ifdef CONFIG_OF
-static int max77686_pmic_dt_parse_pdata(struct platform_device *pdev,
- struct max77686_platform_data *pdata)
-{
- struct max77686_dev *iodev = dev_get_drvdata(pdev->dev.parent);
- struct device_node *pmic_np, *regulators_np;
- struct max77686_regulator_data *rdata;
- struct of_regulator_match rmatch;
- unsigned int i;
-
- pmic_np = iodev->dev->of_node;
- regulators_np = of_get_child_by_name(pmic_np, "voltage-regulators");
- if (!regulators_np) {
- dev_err(&pdev->dev, "could not find regulators sub-node\n");
- return -EINVAL;
- }
-
- pdata->num_regulators = ARRAY_SIZE(regulators);
- rdata = devm_kzalloc(&pdev->dev, sizeof(*rdata) *
- pdata->num_regulators, GFP_KERNEL);
- if (!rdata) {
- of_node_put(regulators_np);
- return -ENOMEM;
- }
-
- for (i = 0; i < pdata->num_regulators; i++) {
- rmatch.name = regulators[i].name;
- rmatch.init_data = NULL;
- rmatch.of_node = NULL;
- of_regulator_match(&pdev->dev, regulators_np, &rmatch, 1);
- rdata[i].initdata = rmatch.init_data;
- rdata[i].of_node = rmatch.of_node;
- }
-
- pdata->regulators = rdata;
- of_node_put(regulators_np);
-
- return 0;
-}
-#else
-static int max77686_pmic_dt_parse_pdata(struct platform_device *pdev,
- struct max77686_platform_data *pdata)
-{
- return 0;
-}
-#endif /* CONFIG_OF */
-
static int max77686_pmic_probe(struct platform_device *pdev)
{
struct max77686_dev *iodev = dev_get_drvdata(pdev->dev.parent);
- struct max77686_platform_data *pdata = dev_get_platdata(iodev->dev);
struct max77686_data *max77686;
- int i, ret = 0;
+ int i;
struct regulator_config config = { };
dev_dbg(&pdev->dev, "%s\n", __func__);
- if (!pdata) {
- dev_err(&pdev->dev, "no platform data found for regulator\n");
- return -ENODEV;
- }
-
- if (iodev->dev->of_node) {
- ret = max77686_pmic_dt_parse_pdata(pdev, pdata);
- if (ret)
- return ret;
- }
-
- if (pdata->num_regulators != MAX77686_REGULATORS) {
- dev_err(&pdev->dev,
- "Invalid initial data for regulator's initialiation\n");
- return -EINVAL;
- }
-
max77686 = devm_kzalloc(&pdev->dev, sizeof(struct max77686_data),
GFP_KERNEL);
if (!max77686)
return -ENOMEM;
- config.dev = &pdev->dev;
+ config.dev = iodev->dev;
config.regmap = iodev->regmap;
config.driver_data = max77686;
platform_set_drvdata(pdev, max77686);
for (i = 0; i < MAX77686_REGULATORS; i++) {
struct regulator_dev *rdev;
+ int id = regulators[i].id;
- config.init_data = pdata->regulators[i].initdata;
- config.of_node = pdata->regulators[i].of_node;
-
- max77686->opmode[i] = regulators[i].enable_mask;
+ max77686->opmode[id] = MAX77686_NORMAL;
rdev = devm_regulator_register(&pdev->dev,
&regulators[i], &config);
if (IS_ERR(rdev)) {
+ int ret = PTR_ERR(rdev);
dev_err(&pdev->dev,
- "regulator init failed for %d\n", i);
- return PTR_ERR(rdev);
+ "regulator init failed for %d: %d\n", i, ret);
+ return ret;
}
}
@@ -500,7 +548,6 @@ MODULE_DEVICE_TABLE(platform, max77686_pmic_id);
static struct platform_driver max77686_pmic_driver = {
.driver = {
.name = "max77686-pmic",
- .owner = THIS_MODULE,
},
.probe = max77686_pmic_probe,
.id_table = max77686_pmic_id,
diff --git a/drivers/regulator/max77693.c b/drivers/regulator/max77693.c
index c67ff05..07b313e 100644
--- a/drivers/regulator/max77693.c
+++ b/drivers/regulator/max77693.c
@@ -139,7 +139,7 @@ static struct regulator_ops max77693_charger_ops = {
.enable_mask = SAFEOUT_CTRL_ENSAFEOUT##_num##_MASK , \
}
-static struct regulator_desc regulators[] = {
+static const struct regulator_desc regulators[] = {
regulator_desc_esafeout(1),
regulator_desc_esafeout(2),
{
@@ -227,7 +227,7 @@ static int max77693_pmic_probe(struct platform_device *pdev)
struct max77693_dev *iodev = dev_get_drvdata(pdev->dev.parent);
struct max77693_regulator_data *rdata = NULL;
int num_rdata, i;
- struct regulator_config config;
+ struct regulator_config config = { };
num_rdata = max77693_pmic_init_rdata(&pdev->dev, &rdata);
if (!rdata || num_rdata <= 0) {
@@ -267,7 +267,6 @@ MODULE_DEVICE_TABLE(platform, max77693_pmic_id);
static struct platform_driver max77693_pmic_driver = {
.driver = {
.name = "max77693-pmic",
- .owner = THIS_MODULE,
},
.probe = max77693_pmic_probe,
.id_table = max77693_pmic_id,
diff --git a/drivers/regulator/max77802.c b/drivers/regulator/max77802.c
index d89792b..6af41ab 100644
--- a/drivers/regulator/max77802.c
+++ b/drivers/regulator/max77802.c
@@ -33,6 +33,7 @@
#include <linux/regulator/of_regulator.h>
#include <linux/mfd/max77686.h>
#include <linux/mfd/max77686-private.h>
+#include <dt-bindings/regulator/maxim,max77802.h>
/* Default ramp delay in case it is not manually set */
#define MAX77802_RAMP_DELAY 100000 /* uV/us */
@@ -49,6 +50,10 @@
#define MAX77802_RAMP_RATE_MASK_4BIT 0xF0
#define MAX77802_RAMP_RATE_SHIFT_4BIT 4
+#define MAX77802_STATUS_OFF 0x0
+#define MAX77802_OFF_PWRREQ 0x1
+#define MAX77802_LP_PWRREQ 0x2
+
/* MAX77802 has two register formats: 2-bit and 4-bit */
static const unsigned int ramp_table_77802_2bit[] = {
12500,
@@ -65,9 +70,16 @@ static unsigned int ramp_table_77802_4bit[] = {
};
struct max77802_regulator_prv {
+ /* Array indexed by regulator id */
unsigned int opmode[MAX77802_REG_MAX];
};
+static inline unsigned int max77802_map_mode(unsigned int mode)
+{
+ return mode == MAX77802_OPMODE_NORMAL ?
+ REGULATOR_MODE_NORMAL : REGULATOR_MODE_STANDBY;
+}
+
static int max77802_get_opmode_shift(int id)
{
if (id == MAX77802_BUCK1 || (id >= MAX77802_BUCK5 &&
@@ -83,17 +95,16 @@ static int max77802_get_opmode_shift(int id)
return -EINVAL;
}
-/*
- * Some BUCKS supports Normal[ON/OFF] mode during suspend
+/**
+ * max77802_set_suspend_disable - Disable the regulator during system suspend
+ * @rdev: regulator to mark as disabled
*
- * BUCK 1, 6, 2-4, 5, 7-10 (all)
- *
- * The other mode (0x02) will make PWRREQ switch between normal
- * and low power.
+ * All regulators expect LDO 1, 3, 20 and 21 support OFF by PWRREQ.
+ * Configure the regulator so the PMIC will turn it OFF during system suspend.
*/
-static int max77802_buck_set_suspend_disable(struct regulator_dev *rdev)
+static int max77802_set_suspend_disable(struct regulator_dev *rdev)
{
- unsigned int val = MAX77802_OPMODE_STANDBY;
+ unsigned int val = MAX77802_OFF_PWRREQ;
struct max77802_regulator_prv *max77802 = rdev_get_drvdata(rdev);
int id = rdev_get_id(rdev);
int shift = max77802_get_opmode_shift(id);
@@ -104,14 +115,11 @@ static int max77802_buck_set_suspend_disable(struct regulator_dev *rdev)
}
/*
- * Some LDOs supports LPM-ON/OFF/Normal-ON mode during suspend state
- * (Enable Control Logic1 by PWRREQ)
- *
- * LDOs 2, 4-19, 22-35.
+ * Some LDOs support Low Power Mode while the system is running.
*
+ * LDOs 1, 3, 20, 21.
*/
-static int max77802_ldo_set_suspend_mode_logic1(struct regulator_dev *rdev,
- unsigned int mode)
+static int max77802_set_mode(struct regulator_dev *rdev, unsigned int mode)
{
struct max77802_regulator_prv *max77802 = rdev_get_drvdata(rdev);
int id = rdev_get_id(rdev);
@@ -119,14 +127,11 @@ static int max77802_ldo_set_suspend_mode_logic1(struct regulator_dev *rdev,
int shift = max77802_get_opmode_shift(id);
switch (mode) {
- case REGULATOR_MODE_IDLE: /* ON in LP Mode */
- val = MAX77802_OPMODE_LP;
+ case REGULATOR_MODE_STANDBY:
+ val = MAX77802_OPMODE_LP; /* ON in Low Power Mode */
break;
- case REGULATOR_MODE_NORMAL: /* ON in Normal Mode */
- val = MAX77802_OPMODE_NORMAL;
- break;
- case REGULATOR_MODE_STANDBY: /* ON/OFF by PWRREQ */
- val = MAX77802_OPMODE_STANDBY;
+ case REGULATOR_MODE_NORMAL:
+ val = MAX77802_OPMODE_NORMAL; /* ON in Normal Mode */
break;
default:
dev_warn(&rdev->dev, "%s: regulator mode: 0x%x not supported\n",
@@ -139,35 +144,76 @@ static int max77802_ldo_set_suspend_mode_logic1(struct regulator_dev *rdev,
rdev->desc->enable_mask, val << shift);
}
-/*
- * Mode 1 (Output[ON/OFF] by PWRREQ) is not supported on some LDOs
- * (Enable Control Logic2 by PWRREQ)
+static unsigned max77802_get_mode(struct regulator_dev *rdev)
+{
+ struct max77802_regulator_prv *max77802 = rdev_get_drvdata(rdev);
+ int id = rdev_get_id(rdev);
+
+ return max77802_map_mode(max77802->opmode[id]);
+}
+
+/**
+ * max77802_set_suspend_mode - set regulator opmode when the system is suspended
+ * @rdev: regulator to change mode
+ * @mode: operating mode to be set
*
- * LDOs 1, 20, 21, and 3,
+ * Will set the operating mode for the regulators during system suspend.
+ * This function is valid for the three different enable control logics:
*
+ * Enable Control Logic1 by PWRREQ (BUCK 2-4 and LDOs 2, 4-19, 22-35)
+ * Enable Control Logic2 by PWRREQ (LDOs 1, 20, 21)
+ * Enable Control Logic3 by PWRREQ (LDO 3)
+ *
+ * If setting the regulator mode fails, the function only warns but does
+ * not return an error code to avoid the regulator core to stop setting
+ * the operating mode for the remaining regulators.
*/
-static int max77802_ldo_set_suspend_mode_logic2(struct regulator_dev *rdev,
- unsigned int mode)
+static int max77802_set_suspend_mode(struct regulator_dev *rdev,
+ unsigned int mode)
{
struct max77802_regulator_prv *max77802 = rdev_get_drvdata(rdev);
int id = rdev_get_id(rdev);
unsigned int val;
int shift = max77802_get_opmode_shift(id);
+ /*
+ * If the regulator has been disabled for suspend
+ * then is invalid to try setting a suspend mode.
+ */
+ if (max77802->opmode[id] == MAX77802_OFF_PWRREQ) {
+ dev_warn(&rdev->dev, "%s: is disabled, mode: 0x%x not set\n",
+ rdev->desc->name, mode);
+ return 0;
+ }
+
switch (mode) {
- case REGULATOR_MODE_IDLE: /* ON in LP Mode */
- val = MAX77802_OPMODE_LP;
- break;
- case REGULATOR_MODE_NORMAL: /* ON in Normal Mode */
- val = MAX77802_OPMODE_NORMAL;
+ case REGULATOR_MODE_STANDBY:
+ /*
+ * If the regulator opmode is normal then enable
+ * ON in Low Power Mode by PWRREQ. If the mode is
+ * already Low Power then no action is required.
+ */
+ if (max77802->opmode[id] == MAX77802_OPMODE_NORMAL)
+ val = MAX77802_LP_PWRREQ;
+ else
+ return 0;
break;
+ case REGULATOR_MODE_NORMAL:
+ /*
+ * If the regulator operating mode is Low Power then
+ * normal is not a valid opmode in suspend. If the
+ * mode is already normal then no action is required.
+ */
+ if (max77802->opmode[id] == MAX77802_OPMODE_LP)
+ dev_warn(&rdev->dev, "%s: in Low Power: 0x%x invalid\n",
+ rdev->desc->name, mode);
+ return 0;
default:
dev_warn(&rdev->dev, "%s: regulator mode: 0x%x not supported\n",
rdev->desc->name, mode);
return -EINVAL;
}
- max77802->opmode[id] = val;
return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
rdev->desc->enable_mask, val << shift);
}
@@ -178,6 +224,9 @@ static int max77802_enable(struct regulator_dev *rdev)
int id = rdev_get_id(rdev);
int shift = max77802_get_opmode_shift(id);
+ if (max77802->opmode[id] == MAX77802_OFF_PWRREQ)
+ max77802->opmode[id] = MAX77802_OPMODE_NORMAL;
+
return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
rdev->desc->enable_mask,
max77802->opmode[id] << shift);
@@ -247,7 +296,8 @@ static struct regulator_ops max77802_ldo_ops_logic1 = {
.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,
- .set_suspend_mode = max77802_ldo_set_suspend_mode_logic1,
+ .set_suspend_disable = max77802_set_suspend_disable,
+ .set_suspend_mode = max77802_set_suspend_mode,
};
/*
@@ -262,7 +312,9 @@ static struct regulator_ops max77802_ldo_ops_logic2 = {
.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,
- .set_suspend_mode = max77802_ldo_set_suspend_mode_logic2,
+ .set_mode = max77802_set_mode,
+ .get_mode = max77802_get_mode,
+ .set_suspend_mode = max77802_set_suspend_mode,
};
/* BUCKS 1, 6 */
@@ -276,10 +328,25 @@ static struct regulator_ops max77802_buck_16_dvs_ops = {
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.set_voltage_time_sel = regulator_set_voltage_time_sel,
.set_ramp_delay = max77802_set_ramp_delay_4bit,
- .set_suspend_disable = max77802_buck_set_suspend_disable,
+ .set_suspend_disable = max77802_set_suspend_disable,
};
-/* BUCKs 2-4, 5, 7-10 */
+/* BUCKs 2-4 */
+static struct regulator_ops max77802_buck_234_ops = {
+ .list_voltage = regulator_list_voltage_linear,
+ .map_voltage = regulator_map_voltage_linear,
+ .is_enabled = regulator_is_enabled_regmap,
+ .enable = max77802_enable,
+ .disable = regulator_disable_regmap,
+ .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,
+ .set_ramp_delay = max77802_set_ramp_delay_2bit,
+ .set_suspend_disable = max77802_set_suspend_disable,
+ .set_suspend_mode = max77802_set_suspend_mode,
+};
+
+/* BUCKs 5, 7-10 */
static struct regulator_ops max77802_buck_dvs_ops = {
.list_voltage = regulator_list_voltage_linear,
.map_voltage = regulator_map_voltage_linear,
@@ -290,12 +357,14 @@ static struct regulator_ops max77802_buck_dvs_ops = {
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.set_voltage_time_sel = regulator_set_voltage_time_sel,
.set_ramp_delay = max77802_set_ramp_delay_2bit,
- .set_suspend_disable = max77802_buck_set_suspend_disable,
+ .set_suspend_disable = max77802_set_suspend_disable,
};
/* LDOs 3-7, 9-14, 18-26, 28, 29, 32-34 */
#define regulator_77802_desc_p_ldo(num, supply, log) { \
.name = "LDO"#num, \
+ .of_match = of_match_ptr("LDO"#num), \
+ .regulators_node = of_match_ptr("regulators"), \
.id = MAX77802_LDO##num, \
.supply_name = "inl"#supply, \
.ops = &max77802_ldo_ops_logic##log, \
@@ -309,11 +378,14 @@ static struct regulator_ops max77802_buck_dvs_ops = {
.vsel_mask = MAX77802_VSEL_MASK, \
.enable_reg = MAX77802_REG_LDO1CTRL1 + num - 1, \
.enable_mask = MAX77802_OPMODE_MASK << MAX77802_OPMODE_SHIFT_LDO, \
+ .of_map_mode = max77802_map_mode, \
}
/* LDOs 1, 2, 8, 15, 17, 27, 30, 35 */
#define regulator_77802_desc_n_ldo(num, supply, log) { \
.name = "LDO"#num, \
+ .of_match = of_match_ptr("LDO"#num), \
+ .regulators_node = of_match_ptr("regulators"), \
.id = MAX77802_LDO##num, \
.supply_name = "inl"#supply, \
.ops = &max77802_ldo_ops_logic##log, \
@@ -327,11 +399,14 @@ static struct regulator_ops max77802_buck_dvs_ops = {
.vsel_mask = MAX77802_VSEL_MASK, \
.enable_reg = MAX77802_REG_LDO1CTRL1 + num - 1, \
.enable_mask = MAX77802_OPMODE_MASK << MAX77802_OPMODE_SHIFT_LDO, \
+ .of_map_mode = max77802_map_mode, \
}
/* BUCKs 1, 6 */
#define regulator_77802_desc_16_buck(num) { \
.name = "BUCK"#num, \
+ .of_match = of_match_ptr("BUCK"#num), \
+ .regulators_node = of_match_ptr("regulators"), \
.id = MAX77802_BUCK##num, \
.supply_name = "inb"#num, \
.ops = &max77802_buck_16_dvs_ops, \
@@ -345,14 +420,17 @@ static struct regulator_ops max77802_buck_dvs_ops = {
.vsel_mask = MAX77802_DVS_VSEL_MASK, \
.enable_reg = MAX77802_REG_BUCK ## num ## CTRL, \
.enable_mask = MAX77802_OPMODE_MASK, \
+ .of_map_mode = max77802_map_mode, \
}
/* BUCKS 2-4 */
#define regulator_77802_desc_234_buck(num) { \
.name = "BUCK"#num, \
+ .of_match = of_match_ptr("BUCK"#num), \
+ .regulators_node = of_match_ptr("regulators"), \
.id = MAX77802_BUCK##num, \
.supply_name = "inb"#num, \
- .ops = &max77802_buck_dvs_ops, \
+ .ops = &max77802_buck_234_ops, \
.type = REGULATOR_VOLTAGE, \
.owner = THIS_MODULE, \
.min_uV = 600000, \
@@ -364,11 +442,14 @@ static struct regulator_ops max77802_buck_dvs_ops = {
.enable_reg = MAX77802_REG_BUCK ## num ## CTRL1, \
.enable_mask = MAX77802_OPMODE_MASK << \
MAX77802_OPMODE_BUCK234_SHIFT, \
+ .of_map_mode = max77802_map_mode, \
}
/* BUCK 5 */
#define regulator_77802_desc_buck5(num) { \
.name = "BUCK"#num, \
+ .of_match = of_match_ptr("BUCK"#num), \
+ .regulators_node = of_match_ptr("regulators"), \
.id = MAX77802_BUCK##num, \
.supply_name = "inb"#num, \
.ops = &max77802_buck_dvs_ops, \
@@ -382,11 +463,14 @@ static struct regulator_ops max77802_buck_dvs_ops = {
.vsel_mask = MAX77802_VSEL_MASK, \
.enable_reg = MAX77802_REG_BUCK5CTRL, \
.enable_mask = MAX77802_OPMODE_MASK, \
+ .of_map_mode = max77802_map_mode, \
}
/* BUCKs 7-10 */
#define regulator_77802_desc_buck7_10(num) { \
.name = "BUCK"#num, \
+ .of_match = of_match_ptr("BUCK"#num), \
+ .regulators_node = of_match_ptr("regulators"), \
.id = MAX77802_BUCK##num, \
.supply_name = "inb"#num, \
.ops = &max77802_buck_dvs_ops, \
@@ -400,9 +484,10 @@ static struct regulator_ops max77802_buck_dvs_ops = {
.vsel_mask = MAX77802_VSEL_MASK, \
.enable_reg = MAX77802_REG_BUCK7CTRL + (num - 7) * 3, \
.enable_mask = MAX77802_OPMODE_MASK, \
+ .of_map_mode = max77802_map_mode, \
}
-static struct regulator_desc regulators[] = {
+static const struct regulator_desc regulators[] = {
regulator_77802_desc_16_buck(1),
regulator_77802_desc_234_buck(2),
regulator_77802_desc_234_buck(3),
@@ -447,85 +532,19 @@ static struct regulator_desc regulators[] = {
regulator_77802_desc_n_ldo(35, 2, 1),
};
-#ifdef CONFIG_OF
-static int max77802_pmic_dt_parse_pdata(struct platform_device *pdev,
- struct max77686_platform_data *pdata)
-{
- struct max77686_dev *iodev = dev_get_drvdata(pdev->dev.parent);
- struct device_node *pmic_np, *regulators_np;
- struct max77686_regulator_data *rdata;
- struct of_regulator_match rmatch;
- unsigned int i;
-
- pmic_np = iodev->dev->of_node;
- regulators_np = of_get_child_by_name(pmic_np, "regulators");
- if (!regulators_np) {
- dev_err(&pdev->dev, "could not find regulators sub-node\n");
- return -EINVAL;
- }
-
- pdata->num_regulators = ARRAY_SIZE(regulators);
- rdata = devm_kzalloc(&pdev->dev, sizeof(*rdata) *
- pdata->num_regulators, GFP_KERNEL);
- if (!rdata) {
- of_node_put(regulators_np);
- return -ENOMEM;
- }
-
- for (i = 0; i < pdata->num_regulators; i++) {
- rmatch.name = regulators[i].name;
- rmatch.init_data = NULL;
- rmatch.of_node = NULL;
- if (of_regulator_match(&pdev->dev, regulators_np, &rmatch,
- 1) != 1) {
- dev_warn(&pdev->dev, "No matching regulator for '%s'\n",
- rmatch.name);
- continue;
- }
- rdata[i].initdata = rmatch.init_data;
- rdata[i].of_node = rmatch.of_node;
- rdata[i].id = regulators[i].id;
- }
-
- pdata->regulators = rdata;
- of_node_put(regulators_np);
-
- return 0;
-}
-#else
-static int max77802_pmic_dt_parse_pdata(struct platform_device *pdev,
- struct max77686_platform_data *pdata)
-{
- return 0;
-}
-#endif /* CONFIG_OF */
-
static int max77802_pmic_probe(struct platform_device *pdev)
{
struct max77686_dev *iodev = dev_get_drvdata(pdev->dev.parent);
- struct max77686_platform_data *pdata = dev_get_platdata(iodev->dev);
struct max77802_regulator_prv *max77802;
- int i, ret = 0, val;
+ int i, val;
struct regulator_config config = { };
- /* This is allocated by the MFD driver */
- if (!pdata) {
- dev_err(&pdev->dev, "no platform data found for regulator\n");
- return -ENODEV;
- }
-
max77802 = devm_kzalloc(&pdev->dev,
sizeof(struct max77802_regulator_prv),
GFP_KERNEL);
if (!max77802)
return -ENOMEM;
- if (iodev->dev->of_node) {
- ret = max77802_pmic_dt_parse_pdata(pdev, pdata);
- if (ret)
- return ret;
- }
-
config.dev = iodev->dev;
config.regmap = iodev->regmap;
config.driver_data = max77802;
@@ -533,21 +552,25 @@ static int max77802_pmic_probe(struct platform_device *pdev)
for (i = 0; i < MAX77802_REG_MAX; i++) {
struct regulator_dev *rdev;
- int id = pdata->regulators[i].id;
+ int id = regulators[i].id;
int shift = max77802_get_opmode_shift(id);
-
- config.init_data = pdata->regulators[i].initdata;
- config.of_node = pdata->regulators[i].of_node;
+ int ret;
ret = regmap_read(iodev->regmap, regulators[i].enable_reg, &val);
- val = val >> shift & MAX77802_OPMODE_MASK;
+ if (ret < 0) {
+ dev_warn(&pdev->dev,
+ "cannot read current mode for %d\n", i);
+ val = MAX77802_OPMODE_NORMAL;
+ } else {
+ val = val >> shift & MAX77802_OPMODE_MASK;
+ }
/*
* If the regulator is disabled and the system warm rebooted,
* the hardware reports OFF as the regulator operating mode.
* Default to operating mode NORMAL in that case.
*/
- if (val == MAX77802_OPMODE_OFF)
+ if (val == MAX77802_STATUS_OFF)
max77802->opmode[id] = MAX77802_OPMODE_NORMAL;
else
max77802->opmode[id] = val;
@@ -555,9 +578,10 @@ static int max77802_pmic_probe(struct platform_device *pdev)
rdev = devm_regulator_register(&pdev->dev,
&regulators[i], &config);
if (IS_ERR(rdev)) {
+ ret = PTR_ERR(rdev);
dev_err(&pdev->dev,
- "regulator init failed for %d\n", i);
- return PTR_ERR(rdev);
+ "regulator init failed for %d: %d\n", i, ret);
+ return ret;
}
}
@@ -573,7 +597,6 @@ MODULE_DEVICE_TABLE(platform, max77802_pmic_id);
static struct platform_driver max77802_pmic_driver = {
.driver = {
.name = "max77802-pmic",
- .owner = THIS_MODULE,
},
.probe = max77802_pmic_probe,
.id_table = max77802_pmic_id,
diff --git a/drivers/regulator/max77843.c b/drivers/regulator/max77843.c
new file mode 100644
index 0000000..c132ef5
--- /dev/null
+++ b/drivers/regulator/max77843.c
@@ -0,0 +1,227 @@
+/*
+ * max77843.c - Regulator driver for the Maxim MAX77843
+ *
+ * Copyright (C) 2015 Samsung Electronics
+ * Author: Jaewon Kim <jaewon02.kim@samsung.com>
+ * Author: Beomho Seo <beomho.seo@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/mfd/max77843-private.h>
+#include <linux/regulator/of_regulator.h>
+
+enum max77843_regulator_type {
+ MAX77843_SAFEOUT1 = 0,
+ MAX77843_SAFEOUT2,
+ MAX77843_CHARGER,
+
+ MAX77843_NUM,
+};
+
+static const unsigned int max77843_safeout_voltage_table[] = {
+ 4850000,
+ 4900000,
+ 4950000,
+ 3300000,
+};
+
+static int max77843_reg_is_enabled(struct regulator_dev *rdev)
+{
+ struct regmap *regmap = rdev->regmap;
+ int ret;
+ unsigned int reg;
+
+ ret = regmap_read(regmap, rdev->desc->enable_reg, &reg);
+ if (ret) {
+ dev_err(&rdev->dev, "Fialed to read charger register\n");
+ return ret;
+ }
+
+ return (reg & rdev->desc->enable_mask) == rdev->desc->enable_mask;
+}
+
+static int max77843_reg_get_current_limit(struct regulator_dev *rdev)
+{
+ struct regmap *regmap = rdev->regmap;
+ unsigned int chg_min_uA = rdev->constraints->min_uA;
+ unsigned int chg_max_uA = rdev->constraints->max_uA;
+ unsigned int val;
+ int ret;
+ unsigned int reg, sel;
+
+ ret = regmap_read(regmap, MAX77843_CHG_REG_CHG_CNFG_02, &reg);
+ if (ret) {
+ dev_err(&rdev->dev, "Failed to read charger register\n");
+ return ret;
+ }
+
+ sel = reg & MAX77843_CHG_FAST_CHG_CURRENT_MASK;
+
+ if (sel < 0x03)
+ sel = 0;
+ else
+ sel -= 2;
+
+ val = chg_min_uA + MAX77843_CHG_FAST_CHG_CURRENT_STEP * sel;
+ if (val > chg_max_uA)
+ return -EINVAL;
+
+ return val;
+}
+
+static int max77843_reg_set_current_limit(struct regulator_dev *rdev,
+ int min_uA, int max_uA)
+{
+ struct regmap *regmap = rdev->regmap;
+ unsigned int chg_min_uA = rdev->constraints->min_uA;
+ int sel = 0;
+
+ while (chg_min_uA + MAX77843_CHG_FAST_CHG_CURRENT_STEP * sel < min_uA)
+ sel++;
+
+ if (chg_min_uA + MAX77843_CHG_FAST_CHG_CURRENT_STEP * sel > max_uA)
+ return -EINVAL;
+
+ sel += 2;
+
+ return regmap_write(regmap, MAX77843_CHG_REG_CHG_CNFG_02, sel);
+}
+
+static struct regulator_ops max77843_charger_ops = {
+ .is_enabled = max77843_reg_is_enabled,
+ .enable = regulator_enable_regmap,
+ .disable = regulator_disable_regmap,
+ .get_current_limit = max77843_reg_get_current_limit,
+ .set_current_limit = max77843_reg_set_current_limit,
+};
+
+static struct regulator_ops max77843_regulator_ops = {
+ .is_enabled = regulator_is_enabled_regmap,
+ .enable = regulator_enable_regmap,
+ .disable = regulator_disable_regmap,
+ .list_voltage = regulator_list_voltage_table,
+ .get_voltage_sel = regulator_get_voltage_sel_regmap,
+ .set_voltage_sel = regulator_set_voltage_sel_regmap,
+};
+
+static const struct regulator_desc max77843_supported_regulators[] = {
+ [MAX77843_SAFEOUT1] = {
+ .name = "SAFEOUT1",
+ .id = MAX77843_SAFEOUT1,
+ .ops = &max77843_regulator_ops,
+ .of_match = of_match_ptr("SAFEOUT1"),
+ .regulators_node = of_match_ptr("regulators"),
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE,
+ .n_voltages = ARRAY_SIZE(max77843_safeout_voltage_table),
+ .volt_table = max77843_safeout_voltage_table,
+ .enable_reg = MAX77843_SYS_REG_SAFEOUTCTRL,
+ .enable_mask = MAX77843_REG_SAFEOUTCTRL_ENSAFEOUT1,
+ .vsel_reg = MAX77843_SYS_REG_SAFEOUTCTRL,
+ .vsel_mask = MAX77843_REG_SAFEOUTCTRL_SAFEOUT1_MASK,
+ },
+ [MAX77843_SAFEOUT2] = {
+ .name = "SAFEOUT2",
+ .id = MAX77843_SAFEOUT2,
+ .ops = &max77843_regulator_ops,
+ .of_match = of_match_ptr("SAFEOUT2"),
+ .regulators_node = of_match_ptr("regulators"),
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE,
+ .n_voltages = ARRAY_SIZE(max77843_safeout_voltage_table),
+ .volt_table = max77843_safeout_voltage_table,
+ .enable_reg = MAX77843_SYS_REG_SAFEOUTCTRL,
+ .enable_mask = MAX77843_REG_SAFEOUTCTRL_ENSAFEOUT2,
+ .vsel_reg = MAX77843_SYS_REG_SAFEOUTCTRL,
+ .vsel_mask = MAX77843_REG_SAFEOUTCTRL_SAFEOUT2_MASK,
+ },
+ [MAX77843_CHARGER] = {
+ .name = "CHARGER",
+ .id = MAX77843_CHARGER,
+ .ops = &max77843_charger_ops,
+ .of_match = of_match_ptr("CHARGER"),
+ .regulators_node = of_match_ptr("regulators"),
+ .type = REGULATOR_CURRENT,
+ .owner = THIS_MODULE,
+ .enable_reg = MAX77843_CHG_REG_CHG_CNFG_00,
+ .enable_mask = MAX77843_CHG_MASK,
+ },
+};
+
+static struct regmap *max77843_get_regmap(struct max77843 *max77843, int reg_id)
+{
+ switch (reg_id) {
+ case MAX77843_SAFEOUT1:
+ case MAX77843_SAFEOUT2:
+ return max77843->regmap;
+ case MAX77843_CHARGER:
+ return max77843->regmap_chg;
+ default:
+ return max77843->regmap;
+ }
+}
+
+static int max77843_regulator_probe(struct platform_device *pdev)
+{
+ struct max77843 *max77843 = dev_get_drvdata(pdev->dev.parent);
+ struct regulator_config config = {};
+ int i;
+
+ config.dev = max77843->dev;
+ config.driver_data = max77843;
+
+ for (i = 0; i < ARRAY_SIZE(max77843_supported_regulators); i++) {
+ struct regulator_dev *regulator;
+
+ config.regmap = max77843_get_regmap(max77843,
+ max77843_supported_regulators[i].id);
+
+ regulator = devm_regulator_register(&pdev->dev,
+ &max77843_supported_regulators[i], &config);
+ if (IS_ERR(regulator)) {
+ dev_err(&pdev->dev,
+ "Failed to regiser regulator-%d\n", i);
+ return PTR_ERR(regulator);
+ }
+ }
+
+ return 0;
+}
+
+static const struct platform_device_id max77843_regulator_id[] = {
+ { "max77843-regulator", },
+ { /* sentinel */ },
+};
+
+static struct platform_driver max77843_regulator_driver = {
+ .driver = {
+ .name = "max77843-regulator",
+ },
+ .probe = max77843_regulator_probe,
+ .id_table = max77843_regulator_id,
+};
+
+static int __init max77843_regulator_init(void)
+{
+ return platform_driver_register(&max77843_regulator_driver);
+}
+subsys_initcall(max77843_regulator_init);
+
+static void __exit max77843_regulator_exit(void)
+{
+ platform_driver_unregister(&max77843_regulator_driver);
+}
+module_exit(max77843_regulator_exit);
+
+MODULE_AUTHOR("Jaewon Kim <jaewon02.kim@samsung.com>");
+MODULE_AUTHOR("Beomho Seo <beomho.seo@samsung.com>");
+MODULE_DESCRIPTION("Maxim MAX77843 regulator driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/regulator/max8649.c b/drivers/regulator/max8649.c
index c8bddcc..8122957 100644
--- a/drivers/regulator/max8649.c
+++ b/drivers/regulator/max8649.c
@@ -115,7 +115,7 @@ static unsigned int max8649_get_mode(struct regulator_dev *rdev)
return REGULATOR_MODE_NORMAL;
}
-static struct regulator_ops max8649_dcdc_ops = {
+static const struct regulator_ops max8649_dcdc_ops = {
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.list_voltage = regulator_list_voltage_linear,
@@ -143,7 +143,7 @@ static struct regulator_desc dcdc_desc = {
.enable_is_inverted = true,
};
-static struct regmap_config max8649_regmap_config = {
+static const struct regmap_config max8649_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
};
diff --git a/drivers/regulator/max8660.c b/drivers/regulator/max8660.c
index 2fc4111..7eee2ca 100644
--- a/drivers/regulator/max8660.c
+++ b/drivers/regulator/max8660.c
@@ -335,7 +335,7 @@ static int max8660_pdata_from_dt(struct device *dev,
int matched, i;
struct device_node *np;
struct max8660_subdev_data *sub;
- struct of_regulator_match rmatch[ARRAY_SIZE(max8660_reg)];
+ struct of_regulator_match rmatch[ARRAY_SIZE(max8660_reg)] = { };
np = of_get_child_by_name(dev->of_node, "regulators");
if (!np) {
diff --git a/drivers/regulator/max8907-regulator.c b/drivers/regulator/max8907-regulator.c
index 3426be8..5e941db 100644
--- a/drivers/regulator/max8907-regulator.c
+++ b/drivers/regulator/max8907-regulator.c
@@ -366,7 +366,6 @@ static int max8907_regulator_probe(struct platform_device *pdev)
static struct platform_driver max8907_regulator_driver = {
.driver = {
.name = "max8907-regulator",
- .owner = THIS_MODULE,
},
.probe = max8907_regulator_probe,
};
diff --git a/drivers/regulator/max8925-regulator.c b/drivers/regulator/max8925-regulator.c
index 7770777..c802f02 100644
--- a/drivers/regulator/max8925-regulator.c
+++ b/drivers/regulator/max8925-regulator.c
@@ -324,7 +324,6 @@ static int max8925_regulator_probe(struct platform_device *pdev)
static struct platform_driver max8925_regulator_driver = {
.driver = {
.name = "max8925-regulator",
- .owner = THIS_MODULE,
},
.probe = max8925_regulator_probe,
};
diff --git a/drivers/regulator/max8952.c b/drivers/regulator/max8952.c
index f7f9efc..1af8f4a 100644
--- a/drivers/regulator/max8952.c
+++ b/drivers/regulator/max8952.c
@@ -174,7 +174,7 @@ static struct max8952_platform_data *max8952_parse_dt(struct device *dev)
if (of_property_read_u32(np, "max8952,ramp-speed", &pd->ramp_speed))
dev_warn(dev, "max8952,ramp-speed property not specified, defaulting to 32mV/us\n");
- pd->reg_data = of_get_regulator_init_data(dev, np);
+ pd->reg_data = of_get_regulator_init_data(dev, np, &regulator);
if (!pd->reg_data) {
dev_err(dev, "Failed to parse regulator init data\n");
return NULL;
@@ -225,6 +225,8 @@ static int max8952_pmic_probe(struct i2c_client *client,
config.of_node = client->dev.of_node;
config.ena_gpio = pdata->gpio_en;
+ if (client->dev.of_node)
+ config.ena_gpio_initialized = true;
if (pdata->reg_data->constraints.boot_on)
config.ena_gpio_flags |= GPIOF_OUT_INIT_HIGH;
diff --git a/drivers/regulator/max8973-regulator.c b/drivers/regulator/max8973-regulator.c
index dbedf17..c3d55c2 100644
--- a/drivers/regulator/max8973-regulator.c
+++ b/drivers/regulator/max8973-regulator.c
@@ -458,7 +458,8 @@ static int max8973_probe(struct i2c_client *client,
config.dev = &client->dev;
config.init_data = pdata ? pdata->reg_init_data :
- of_get_regulator_init_data(&client->dev, client->dev.of_node);
+ of_get_regulator_init_data(&client->dev, client->dev.of_node,
+ &max->desc);
config.driver_data = max;
config.of_node = client->dev.of_node;
config.regmap = max->regmap;
diff --git a/drivers/regulator/max8997.c b/drivers/regulator/max8997.c
index 9c31e21..ea0196d 100644
--- a/drivers/regulator/max8997.c
+++ b/drivers/regulator/max8997.c
@@ -953,7 +953,8 @@ static int max8997_pmic_dt_parse_pdata(struct platform_device *pdev,
rdata->id = i;
rdata->initdata = of_get_regulator_init_data(&pdev->dev,
- reg_np);
+ reg_np,
+ &regulators[i]);
rdata->reg_node = reg_np;
rdata++;
}
@@ -1218,7 +1219,6 @@ MODULE_DEVICE_TABLE(platform, max8997_pmic_id);
static struct platform_driver max8997_pmic_driver = {
.driver = {
.name = "max8997-pmic",
- .owner = THIS_MODULE,
},
.probe = max8997_pmic_probe,
.id_table = max8997_pmic_id,
diff --git a/drivers/regulator/max8998.c b/drivers/regulator/max8998.c
index 961091b..3027e7c 100644
--- a/drivers/regulator/max8998.c
+++ b/drivers/regulator/max8998.c
@@ -686,8 +686,9 @@ static int max8998_pmic_dt_parse_pdata(struct max8998_dev *iodev,
continue;
rdata->id = regulators[i].id;
- rdata->initdata = of_get_regulator_init_data(
- iodev->dev, reg_np);
+ rdata->initdata = of_get_regulator_init_data(iodev->dev,
+ reg_np,
+ &regulators[i]);
rdata->reg_node = reg_np;
++rdata;
}
@@ -894,7 +895,6 @@ MODULE_DEVICE_TABLE(platform, max8998_pmic_id);
static struct platform_driver max8998_pmic_driver = {
.driver = {
.name = "max8998-pmic",
- .owner = THIS_MODULE,
},
.probe = max8998_pmic_probe,
.id_table = max8998_pmic_id,
diff --git a/drivers/regulator/mc13783-regulator.c b/drivers/regulator/mc13783-regulator.c
index 7f4a67e..fe4c7d6 100644
--- a/drivers/regulator/mc13783-regulator.c
+++ b/drivers/regulator/mc13783-regulator.c
@@ -459,7 +459,6 @@ static int mc13783_regulator_probe(struct platform_device *pdev)
static struct platform_driver mc13783_regulator_driver = {
.driver = {
.name = "mc13783-regulator",
- .owner = THIS_MODULE,
},
.probe = mc13783_regulator_probe,
};
diff --git a/drivers/regulator/mc13892-regulator.c b/drivers/regulator/mc13892-regulator.c
index 793b662..0d17c92 100644
--- a/drivers/regulator/mc13892-regulator.c
+++ b/drivers/regulator/mc13892-regulator.c
@@ -633,7 +633,6 @@ err_unlock:
static struct platform_driver mc13892_regulator_driver = {
.driver = {
.name = "mc13892-regulator",
- .owner = THIS_MODULE,
},
.probe = mc13892_regulator_probe,
};
diff --git a/drivers/regulator/mc13xxx-regulator-core.c b/drivers/regulator/mc13xxx-regulator-core.c
index afba024..0281c31 100644
--- a/drivers/regulator/mc13xxx-regulator-core.c
+++ b/drivers/regulator/mc13xxx-regulator-core.c
@@ -194,7 +194,8 @@ struct mc13xxx_regulator_init_data *mc13xxx_parse_regulators_dt(
regulators[i].desc.name)) {
p->id = i;
p->init_data = of_get_regulator_init_data(
- &pdev->dev, child);
+ &pdev->dev, child,
+ &regulators[i].desc);
p->node = child;
p++;
diff --git a/drivers/regulator/mt6397-regulator.c b/drivers/regulator/mt6397-regulator.c
new file mode 100644
index 0000000..a5b2f47
--- /dev/null
+++ b/drivers/regulator/mt6397-regulator.c
@@ -0,0 +1,332 @@
+/*
+ * Copyright (c) 2014 MediaTek Inc.
+ * Author: Flora Fu <flora.fu@mediatek.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/mfd/mt6397/core.h>
+#include <linux/mfd/mt6397/registers.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/mt6397-regulator.h>
+#include <linux/regulator/of_regulator.h>
+
+/*
+ * MT6397 regulators' information
+ *
+ * @desc: standard fields of regulator description.
+ * @qi: Mask for query enable signal status of regulators
+ * @vselon_reg: Register sections for hardware control mode of bucks
+ * @vselctrl_reg: Register for controlling the buck control mode.
+ * @vselctrl_mask: Mask for query buck's voltage control mode.
+ */
+struct mt6397_regulator_info {
+ struct regulator_desc desc;
+ u32 qi;
+ u32 vselon_reg;
+ u32 vselctrl_reg;
+ u32 vselctrl_mask;
+};
+
+#define MT6397_BUCK(match, vreg, min, max, step, volt_ranges, enreg, \
+ vosel, vosel_mask, voselon, vosel_ctrl) \
+[MT6397_ID_##vreg] = { \
+ .desc = { \
+ .name = #vreg, \
+ .of_match = of_match_ptr(match), \
+ .ops = &mt6397_volt_range_ops, \
+ .type = REGULATOR_VOLTAGE, \
+ .id = MT6397_ID_##vreg, \
+ .owner = THIS_MODULE, \
+ .n_voltages = (max - min)/step + 1, \
+ .linear_ranges = volt_ranges, \
+ .n_linear_ranges = ARRAY_SIZE(volt_ranges), \
+ .vsel_reg = vosel, \
+ .vsel_mask = vosel_mask, \
+ .enable_reg = enreg, \
+ .enable_mask = BIT(0), \
+ }, \
+ .qi = BIT(13), \
+ .vselon_reg = voselon, \
+ .vselctrl_reg = vosel_ctrl, \
+ .vselctrl_mask = BIT(1), \
+}
+
+#define MT6397_LDO(match, vreg, ldo_volt_table, enreg, enbit, vosel, \
+ vosel_mask) \
+[MT6397_ID_##vreg] = { \
+ .desc = { \
+ .name = #vreg, \
+ .of_match = of_match_ptr(match), \
+ .ops = &mt6397_volt_table_ops, \
+ .type = REGULATOR_VOLTAGE, \
+ .id = MT6397_ID_##vreg, \
+ .owner = THIS_MODULE, \
+ .n_voltages = ARRAY_SIZE(ldo_volt_table), \
+ .volt_table = ldo_volt_table, \
+ .vsel_reg = vosel, \
+ .vsel_mask = vosel_mask, \
+ .enable_reg = enreg, \
+ .enable_mask = BIT(enbit), \
+ }, \
+ .qi = BIT(15), \
+}
+
+#define MT6397_REG_FIXED(match, vreg, enreg, enbit, volt) \
+[MT6397_ID_##vreg] = { \
+ .desc = { \
+ .name = #vreg, \
+ .of_match = of_match_ptr(match), \
+ .ops = &mt6397_volt_fixed_ops, \
+ .type = REGULATOR_VOLTAGE, \
+ .id = MT6397_ID_##vreg, \
+ .owner = THIS_MODULE, \
+ .n_voltages = 1, \
+ .enable_reg = enreg, \
+ .enable_mask = BIT(enbit), \
+ .min_uV = volt, \
+ }, \
+ .qi = BIT(15), \
+}
+
+static const struct regulator_linear_range buck_volt_range1[] = {
+ REGULATOR_LINEAR_RANGE(700000, 0, 0x7f, 6250),
+};
+
+static const struct regulator_linear_range buck_volt_range2[] = {
+ REGULATOR_LINEAR_RANGE(800000, 0, 0x7f, 6250),
+};
+
+static const struct regulator_linear_range buck_volt_range3[] = {
+ REGULATOR_LINEAR_RANGE(1500000, 0, 0x1f, 20000),
+};
+
+static const u32 ldo_volt_table1[] = {
+ 1500000, 1800000, 2500000, 2800000,
+};
+
+static const u32 ldo_volt_table2[] = {
+ 1800000, 3300000,
+};
+
+static const u32 ldo_volt_table3[] = {
+ 3000000, 3300000,
+};
+
+static const u32 ldo_volt_table4[] = {
+ 1220000, 1300000, 1500000, 1800000, 2500000, 2800000, 3000000, 3300000,
+};
+
+static const u32 ldo_volt_table5[] = {
+ 1200000, 1300000, 1500000, 1800000, 2500000, 2800000, 3000000, 3300000,
+};
+
+static const u32 ldo_volt_table5_v2[] = {
+ 1200000, 1000000, 1500000, 1800000, 2500000, 2800000, 3000000, 3300000,
+};
+
+static const u32 ldo_volt_table6[] = {
+ 1200000, 1300000, 1500000, 1800000, 2500000, 2800000, 3000000, 2000000,
+};
+
+static const u32 ldo_volt_table7[] = {
+ 1300000, 1500000, 1800000, 2000000, 2500000, 2800000, 3000000, 3300000,
+};
+
+static int mt6397_get_status(struct regulator_dev *rdev)
+{
+ int ret;
+ u32 regval;
+ struct mt6397_regulator_info *info = rdev_get_drvdata(rdev);
+
+ ret = regmap_read(rdev->regmap, info->desc.enable_reg, &regval);
+ if (ret != 0) {
+ dev_err(&rdev->dev, "Failed to get enable reg: %d\n", ret);
+ return ret;
+ }
+
+ return (regval & info->qi) ? REGULATOR_STATUS_ON : REGULATOR_STATUS_OFF;
+}
+
+static struct regulator_ops mt6397_volt_range_ops = {
+ .list_voltage = regulator_list_voltage_linear_range,
+ .map_voltage = regulator_map_voltage_linear_range,
+ .set_voltage_sel = regulator_set_voltage_sel_regmap,
+ .get_voltage_sel = regulator_get_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,
+ .get_status = mt6397_get_status,
+};
+
+static struct regulator_ops mt6397_volt_table_ops = {
+ .list_voltage = regulator_list_voltage_table,
+ .map_voltage = regulator_map_voltage_iterate,
+ .set_voltage_sel = regulator_set_voltage_sel_regmap,
+ .get_voltage_sel = regulator_get_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,
+ .get_status = mt6397_get_status,
+};
+
+static struct regulator_ops mt6397_volt_fixed_ops = {
+ .list_voltage = regulator_list_voltage_linear,
+ .enable = regulator_enable_regmap,
+ .disable = regulator_disable_regmap,
+ .is_enabled = regulator_is_enabled_regmap,
+ .get_status = mt6397_get_status,
+};
+
+/* The array is indexed by id(MT6397_ID_XXX) */
+static struct mt6397_regulator_info mt6397_regulators[] = {
+ MT6397_BUCK("buck_vpca15", VPCA15, 700000, 1493750, 6250,
+ buck_volt_range1, MT6397_VCA15_CON7, MT6397_VCA15_CON9, 0x7f,
+ MT6397_VCA15_CON10, MT6397_VCA15_CON5),
+ MT6397_BUCK("buck_vpca7", VPCA7, 700000, 1493750, 6250,
+ buck_volt_range1, MT6397_VPCA7_CON7, MT6397_VPCA7_CON9, 0x7f,
+ MT6397_VPCA7_CON10, MT6397_VPCA7_CON5),
+ MT6397_BUCK("buck_vsramca15", VSRAMCA15, 700000, 1493750, 6250,
+ buck_volt_range1, MT6397_VSRMCA15_CON7, MT6397_VSRMCA15_CON9,
+ 0x7f, MT6397_VSRMCA15_CON10, MT6397_VSRMCA15_CON5),
+ MT6397_BUCK("buck_vsramca7", VSRAMCA7, 700000, 1493750, 6250,
+ buck_volt_range1, MT6397_VSRMCA7_CON7, MT6397_VSRMCA7_CON9,
+ 0x7f, MT6397_VSRMCA7_CON10, MT6397_VSRMCA7_CON5),
+ MT6397_BUCK("buck_vcore", VCORE, 700000, 1493750, 6250,
+ buck_volt_range1, MT6397_VCORE_CON7, MT6397_VCORE_CON9, 0x7f,
+ MT6397_VCORE_CON10, MT6397_VCORE_CON5),
+ MT6397_BUCK("buck_vgpu", VGPU, 700000, 1493750, 6250, buck_volt_range1,
+ MT6397_VGPU_CON7, MT6397_VGPU_CON9, 0x7f,
+ MT6397_VGPU_CON10, MT6397_VGPU_CON5),
+ MT6397_BUCK("buck_vdrm", VDRM, 800000, 1593750, 6250, buck_volt_range2,
+ MT6397_VDRM_CON7, MT6397_VDRM_CON9, 0x7f,
+ MT6397_VDRM_CON10, MT6397_VDRM_CON5),
+ MT6397_BUCK("buck_vio18", VIO18, 1500000, 2120000, 20000,
+ buck_volt_range3, MT6397_VIO18_CON7, MT6397_VIO18_CON9, 0x1f,
+ MT6397_VIO18_CON10, MT6397_VIO18_CON5),
+ MT6397_REG_FIXED("ldo_vtcxo", VTCXO, MT6397_ANALDO_CON0, 10, 2800000),
+ MT6397_REG_FIXED("ldo_va28", VA28, MT6397_ANALDO_CON1, 14, 2800000),
+ MT6397_LDO("ldo_vcama", VCAMA, ldo_volt_table1,
+ MT6397_ANALDO_CON2, 15, MT6397_ANALDO_CON6, 0xC0),
+ MT6397_REG_FIXED("ldo_vio28", VIO28, MT6397_DIGLDO_CON0, 14, 2800000),
+ MT6397_REG_FIXED("ldo_vusb", VUSB, MT6397_DIGLDO_CON1, 14, 3300000),
+ MT6397_LDO("ldo_vmc", VMC, ldo_volt_table2,
+ MT6397_DIGLDO_CON2, 12, MT6397_DIGLDO_CON29, 0x10),
+ MT6397_LDO("ldo_vmch", VMCH, ldo_volt_table3,
+ MT6397_DIGLDO_CON3, 14, MT6397_DIGLDO_CON17, 0x80),
+ MT6397_LDO("ldo_vemc3v3", VEMC3V3, ldo_volt_table3,
+ MT6397_DIGLDO_CON4, 14, MT6397_DIGLDO_CON18, 0x10),
+ MT6397_LDO("ldo_vgp1", VGP1, ldo_volt_table4,
+ MT6397_DIGLDO_CON5, 15, MT6397_DIGLDO_CON19, 0xE0),
+ MT6397_LDO("ldo_vgp2", VGP2, ldo_volt_table5,
+ MT6397_DIGLDO_CON6, 15, MT6397_DIGLDO_CON20, 0xE0),
+ MT6397_LDO("ldo_vgp3", VGP3, ldo_volt_table5,
+ MT6397_DIGLDO_CON7, 15, MT6397_DIGLDO_CON21, 0xE0),
+ MT6397_LDO("ldo_vgp4", VGP4, ldo_volt_table5,
+ MT6397_DIGLDO_CON8, 15, MT6397_DIGLDO_CON22, 0xE0),
+ MT6397_LDO("ldo_vgp5", VGP5, ldo_volt_table6,
+ MT6397_DIGLDO_CON9, 15, MT6397_DIGLDO_CON23, 0xE0),
+ MT6397_LDO("ldo_vgp6", VGP6, ldo_volt_table5,
+ MT6397_DIGLDO_CON10, 15, MT6397_DIGLDO_CON33, 0xE0),
+ MT6397_LDO("ldo_vibr", VIBR, ldo_volt_table7,
+ MT6397_DIGLDO_CON24, 15, MT6397_DIGLDO_CON25, 0xE00),
+};
+
+static int mt6397_set_buck_vosel_reg(struct platform_device *pdev)
+{
+ struct mt6397_chip *mt6397 = dev_get_drvdata(pdev->dev.parent);
+ int i;
+ u32 regval;
+
+ for (i = 0; i < MT6397_MAX_REGULATOR; i++) {
+ if (mt6397_regulators[i].vselctrl_reg) {
+ if (regmap_read(mt6397->regmap,
+ mt6397_regulators[i].vselctrl_reg,
+ &regval) < 0) {
+ dev_err(&pdev->dev,
+ "Failed to read buck ctrl\n");
+ return -EIO;
+ }
+
+ if (regval & mt6397_regulators[i].vselctrl_mask) {
+ mt6397_regulators[i].desc.vsel_reg =
+ mt6397_regulators[i].vselon_reg;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int mt6397_regulator_probe(struct platform_device *pdev)
+{
+ struct mt6397_chip *mt6397 = dev_get_drvdata(pdev->dev.parent);
+ struct regulator_config config = {};
+ struct regulator_dev *rdev;
+ int i;
+ u32 reg_value, version;
+
+ /* Query buck controller to select activated voltage register part */
+ if (mt6397_set_buck_vosel_reg(pdev))
+ return -EIO;
+
+ /* Read PMIC chip revision to update constraints and voltage table */
+ if (regmap_read(mt6397->regmap, MT6397_CID, &reg_value) < 0) {
+ dev_err(&pdev->dev, "Failed to read Chip ID\n");
+ return -EIO;
+ }
+ dev_info(&pdev->dev, "Chip ID = 0x%x\n", reg_value);
+
+ version = (reg_value & 0xFF);
+ switch (version) {
+ case MT6397_REGULATOR_ID91:
+ mt6397_regulators[MT6397_ID_VGP2].desc.volt_table =
+ ldo_volt_table5_v2;
+ break;
+ default:
+ break;
+ }
+
+ for (i = 0; i < MT6397_MAX_REGULATOR; i++) {
+ config.dev = &pdev->dev;
+ config.driver_data = &mt6397_regulators[i];
+ config.regmap = mt6397->regmap;
+ rdev = devm_regulator_register(&pdev->dev,
+ &mt6397_regulators[i].desc, &config);
+ if (IS_ERR(rdev)) {
+ dev_err(&pdev->dev, "failed to register %s\n",
+ mt6397_regulators[i].desc.name);
+ return PTR_ERR(rdev);
+ }
+ }
+
+ return 0;
+}
+
+static struct platform_driver mt6397_regulator_driver = {
+ .driver = {
+ .name = "mt6397-regulator",
+ },
+ .probe = mt6397_regulator_probe,
+};
+
+module_platform_driver(mt6397_regulator_driver);
+
+MODULE_AUTHOR("Flora Fu <flora.fu@mediatek.com>");
+MODULE_DESCRIPTION("Regulator Driver for MediaTek MT6397 PMIC");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:mt6397-regulator");
diff --git a/drivers/regulator/of_regulator.c b/drivers/regulator/of_regulator.c
index 7a51814..24e812c 100644
--- a/drivers/regulator/of_regulator.c
+++ b/drivers/regulator/of_regulator.c
@@ -19,12 +19,20 @@
#include "internal.h"
+static const char *const regulator_states[PM_SUSPEND_MAX + 1] = {
+ [PM_SUSPEND_MEM] = "regulator-state-mem",
+ [PM_SUSPEND_MAX] = "regulator-state-disk",
+};
+
static void of_get_regulation_constraints(struct device_node *np,
- struct regulator_init_data **init_data)
+ struct regulator_init_data **init_data,
+ const struct regulator_desc *desc)
{
const __be32 *min_uV, *max_uV;
struct regulation_constraints *constraints = &(*init_data)->constraints;
- int ret;
+ struct regulator_state *suspend_state;
+ struct device_node *suspend_np;
+ int ret, i;
u32 pval;
constraints->name = of_get_property(np, "regulator-name", NULL);
@@ -73,18 +81,84 @@ static void of_get_regulation_constraints(struct device_node *np,
ret = of_property_read_u32(np, "regulator-enable-ramp-delay", &pval);
if (!ret)
constraints->enable_time = pval;
+
+ if (!of_property_read_u32(np, "regulator-initial-mode", &pval)) {
+ if (desc && desc->of_map_mode) {
+ ret = desc->of_map_mode(pval);
+ if (ret == -EINVAL)
+ pr_err("%s: invalid mode %u\n", np->name, pval);
+ else
+ constraints->initial_mode = ret;
+ } else {
+ pr_warn("%s: mapping for mode %d not defined\n",
+ np->name, pval);
+ }
+ }
+
+ for (i = 0; i < ARRAY_SIZE(regulator_states); i++) {
+ switch (i) {
+ case PM_SUSPEND_MEM:
+ suspend_state = &constraints->state_mem;
+ break;
+ case PM_SUSPEND_MAX:
+ suspend_state = &constraints->state_disk;
+ break;
+ case PM_SUSPEND_ON:
+ case PM_SUSPEND_FREEZE:
+ case PM_SUSPEND_STANDBY:
+ default:
+ continue;
+ };
+
+ suspend_np = of_get_child_by_name(np, regulator_states[i]);
+ if (!suspend_np || !suspend_state)
+ continue;
+
+ if (!of_property_read_u32(suspend_np, "regulator-mode",
+ &pval)) {
+ if (desc && desc->of_map_mode) {
+ ret = desc->of_map_mode(pval);
+ if (ret == -EINVAL)
+ pr_err("%s: invalid mode %u\n",
+ np->name, pval);
+ else
+ suspend_state->mode = ret;
+ } else {
+ pr_warn("%s: mapping for mode %d not defined\n",
+ np->name, pval);
+ }
+ }
+
+ if (of_property_read_bool(suspend_np,
+ "regulator-on-in-suspend"))
+ suspend_state->enabled = true;
+ else if (of_property_read_bool(suspend_np,
+ "regulator-off-in-suspend"))
+ suspend_state->disabled = true;
+
+ if (!of_property_read_u32(suspend_np,
+ "regulator-suspend-microvolt", &pval))
+ suspend_state->uV = pval;
+
+ of_node_put(suspend_np);
+ suspend_state = NULL;
+ suspend_np = NULL;
+ }
}
/**
* of_get_regulator_init_data - extract regulator_init_data structure info
* @dev: device requesting for regulator_init_data
+ * @node: regulator device node
+ * @desc: regulator description
*
* Populates regulator_init_data structure by extracting data from device
* tree node, returns a pointer to the populated struture or NULL if memory
* alloc fails.
*/
struct regulator_init_data *of_get_regulator_init_data(struct device *dev,
- struct device_node *node)
+ struct device_node *node,
+ const struct regulator_desc *desc)
{
struct regulator_init_data *init_data;
@@ -95,7 +169,7 @@ struct regulator_init_data *of_get_regulator_init_data(struct device *dev,
if (!init_data)
return NULL; /* Out of memory? */
- of_get_regulation_constraints(node, &init_data);
+ of_get_regulation_constraints(node, &init_data, desc);
return init_data;
}
EXPORT_SYMBOL_GPL(of_get_regulator_init_data);
@@ -176,7 +250,8 @@ int of_regulator_match(struct device *dev, struct device_node *node,
continue;
match->init_data =
- of_get_regulator_init_data(dev, child);
+ of_get_regulator_init_data(dev, child,
+ match->desc);
if (!match->init_data) {
dev_err(dev,
"failed to parse DT for regulator %s\n",
@@ -195,6 +270,7 @@ EXPORT_SYMBOL_GPL(of_regulator_match);
struct regulator_init_data *regulator_of_get_init_data(struct device *dev,
const struct regulator_desc *desc,
+ struct regulator_config *config,
struct device_node **node)
{
struct device_node *search, *child;
@@ -211,7 +287,8 @@ struct regulator_init_data *regulator_of_get_init_data(struct device *dev,
search = dev->of_node;
if (!search) {
- dev_err(dev, "Failed to find regulator container node\n");
+ dev_dbg(dev, "Failed to find regulator container node '%s'\n",
+ desc->regulators_node);
return NULL;
}
@@ -223,7 +300,7 @@ struct regulator_init_data *regulator_of_get_init_data(struct device *dev,
if (strcmp(desc->of_match, name))
continue;
- init_data = of_get_regulator_init_data(dev, child);
+ init_data = of_get_regulator_init_data(dev, child, desc);
if (!init_data) {
dev_err(dev,
"failed to parse DT for regulator %s\n",
@@ -231,6 +308,16 @@ struct regulator_init_data *regulator_of_get_init_data(struct device *dev,
break;
}
+ if (desc->of_parse_cb) {
+ if (desc->of_parse_cb(child, desc, config)) {
+ dev_err(dev,
+ "driver callback failed to parse DT for regulator %s\n",
+ child->name);
+ init_data = NULL;
+ break;
+ }
+ }
+
of_node_get(child);
*node = child;
break;
diff --git a/drivers/regulator/palmas-regulator.c b/drivers/regulator/palmas-regulator.c
index 1878e5b..9205f43 100644
--- a/drivers/regulator/palmas-regulator.c
+++ b/drivers/regulator/palmas-regulator.c
@@ -1610,7 +1610,6 @@ static struct platform_driver palmas_driver = {
.driver = {
.name = "palmas-pmic",
.of_match_table = of_palmas_match_tbl,
- .owner = THIS_MODULE,
},
.probe = palmas_regulators_probe,
};
diff --git a/drivers/regulator/pbias-regulator.c b/drivers/regulator/pbias-regulator.c
index 6d02d68..bd2b75c 100644
--- a/drivers/regulator/pbias-regulator.c
+++ b/drivers/regulator/pbias-regulator.c
@@ -185,7 +185,6 @@ static struct platform_driver pbias_regulator_driver = {
.probe = pbias_regulator_probe,
.driver = {
.name = "pbias-regulator",
- .owner = THIS_MODULE,
.of_match_table = of_match_ptr(pbias_of_match),
},
};
diff --git a/drivers/regulator/pcap-regulator.c b/drivers/regulator/pcap-regulator.c
index 3727b7d..9b16e61 100644
--- a/drivers/regulator/pcap-regulator.c
+++ b/drivers/regulator/pcap-regulator.c
@@ -259,7 +259,6 @@ static int pcap_regulator_probe(struct platform_device *pdev)
static struct platform_driver pcap_regulator_driver = {
.driver = {
.name = "pcap-regulator",
- .owner = THIS_MODULE,
},
.probe = pcap_regulator_probe,
};
diff --git a/drivers/regulator/pfuze100-regulator.c b/drivers/regulator/pfuze100-regulator.c
index c879dff..8cc8d18 100644
--- a/drivers/regulator/pfuze100-regulator.c
+++ b/drivers/regulator/pfuze100-regulator.c
@@ -56,7 +56,7 @@
#define PFUZE100_VGEN5VOL 0x70
#define PFUZE100_VGEN6VOL 0x71
-enum chips { PFUZE100, PFUZE200 };
+enum chips { PFUZE100, PFUZE200, PFUZE3000 = 3 };
struct pfuze_regulator {
struct regulator_desc desc;
@@ -80,9 +80,18 @@ static const int pfuze100_vsnvs[] = {
1000000, 1100000, 1200000, 1300000, 1500000, 1800000, 3000000,
};
+static const int pfuze3000_sw2lo[] = {
+ 1500000, 1550000, 1600000, 1650000, 1700000, 1750000, 1800000, 1850000,
+};
+
+static const int pfuze3000_sw2hi[] = {
+ 2500000, 2800000, 2850000, 3000000, 3100000, 3150000, 3200000, 3300000,
+};
+
static const struct i2c_device_id pfuze_device_id[] = {
{.name = "pfuze100", .driver_data = PFUZE100},
{.name = "pfuze200", .driver_data = PFUZE200},
+ {.name = "pfuze3000", .driver_data = PFUZE3000},
{ }
};
MODULE_DEVICE_TABLE(i2c, pfuze_device_id);
@@ -90,6 +99,7 @@ MODULE_DEVICE_TABLE(i2c, pfuze_device_id);
static const struct of_device_id pfuze_dt_ids[] = {
{ .compatible = "fsl,pfuze100", .data = (void *)PFUZE100},
{ .compatible = "fsl,pfuze200", .data = (void *)PFUZE200},
+ { .compatible = "fsl,pfuze3000", .data = (void *)PFUZE3000},
{ }
};
MODULE_DEVICE_TABLE(of, pfuze_dt_ids);
@@ -219,6 +229,60 @@ static struct regulator_ops pfuze100_swb_regulator_ops = {
.stby_mask = 0x20, \
}
+#define PFUZE3000_VCC_REG(_chip, _name, base, min, max, step) { \
+ .desc = { \
+ .name = #_name, \
+ .n_voltages = ((max) - (min)) / (step) + 1, \
+ .ops = &pfuze100_ldo_regulator_ops, \
+ .type = REGULATOR_VOLTAGE, \
+ .id = _chip ## _ ## _name, \
+ .owner = THIS_MODULE, \
+ .min_uV = (min), \
+ .uV_step = (step), \
+ .vsel_reg = (base), \
+ .vsel_mask = 0x3, \
+ .enable_reg = (base), \
+ .enable_mask = 0x10, \
+ }, \
+ .stby_reg = (base), \
+ .stby_mask = 0x20, \
+}
+
+
+#define PFUZE3000_SW2_REG(_chip, _name, base, min, max, step) { \
+ .desc = { \
+ .name = #_name,\
+ .n_voltages = ((max) - (min)) / (step) + 1, \
+ .ops = &pfuze100_sw_regulator_ops, \
+ .type = REGULATOR_VOLTAGE, \
+ .id = _chip ## _ ## _name, \
+ .owner = THIS_MODULE, \
+ .min_uV = (min), \
+ .uV_step = (step), \
+ .vsel_reg = (base) + PFUZE100_VOL_OFFSET, \
+ .vsel_mask = 0x7, \
+ }, \
+ .stby_reg = (base) + PFUZE100_STANDBY_OFFSET, \
+ .stby_mask = 0x7, \
+}
+
+#define PFUZE3000_SW3_REG(_chip, _name, base, min, max, step) { \
+ .desc = { \
+ .name = #_name,\
+ .n_voltages = ((max) - (min)) / (step) + 1, \
+ .ops = &pfuze100_sw_regulator_ops, \
+ .type = REGULATOR_VOLTAGE, \
+ .id = _chip ## _ ## _name, \
+ .owner = THIS_MODULE, \
+ .min_uV = (min), \
+ .uV_step = (step), \
+ .vsel_reg = (base) + PFUZE100_VOL_OFFSET, \
+ .vsel_mask = 0xf, \
+ }, \
+ .stby_reg = (base) + PFUZE100_STANDBY_OFFSET, \
+ .stby_mask = 0xf, \
+}
+
/* PFUZE100 */
static struct pfuze_regulator pfuze100_regulators[] = {
PFUZE100_SW_REG(PFUZE100, SW1AB, PFUZE100_SW1ABVOL, 300000, 1875000, 25000),
@@ -254,6 +318,22 @@ static struct pfuze_regulator pfuze200_regulators[] = {
PFUZE100_VGEN_REG(PFUZE200, VGEN6, PFUZE100_VGEN6VOL, 1800000, 3300000, 100000),
};
+static struct pfuze_regulator pfuze3000_regulators[] = {
+ PFUZE100_SW_REG(PFUZE3000, SW1A, PFUZE100_SW1ABVOL, 700000, 1475000, 25000),
+ PFUZE100_SW_REG(PFUZE3000, SW1B, PFUZE100_SW1CVOL, 700000, 1475000, 25000),
+ PFUZE100_SWB_REG(PFUZE3000, SW2, PFUZE100_SW2VOL, 0x7, pfuze3000_sw2lo),
+ PFUZE3000_SW3_REG(PFUZE3000, SW3, PFUZE100_SW3AVOL, 900000, 1650000, 50000),
+ PFUZE100_SWB_REG(PFUZE3000, SWBST, PFUZE100_SWBSTCON1, 0x3, pfuze100_swbst),
+ PFUZE100_SWB_REG(PFUZE3000, VSNVS, PFUZE100_VSNVSVOL, 0x7, pfuze100_vsnvs),
+ PFUZE100_FIXED_REG(PFUZE3000, VREFDDR, PFUZE100_VREFDDRCON, 750000),
+ PFUZE100_VGEN_REG(PFUZE3000, VLDO1, PFUZE100_VGEN1VOL, 1800000, 3300000, 100000),
+ PFUZE100_VGEN_REG(PFUZE3000, VLDO2, PFUZE100_VGEN2VOL, 800000, 1550000, 50000),
+ PFUZE3000_VCC_REG(PFUZE3000, VCCSD, PFUZE100_VGEN3VOL, 2850000, 3300000, 150000),
+ PFUZE3000_VCC_REG(PFUZE3000, V33, PFUZE100_VGEN4VOL, 2850000, 3300000, 150000),
+ PFUZE100_VGEN_REG(PFUZE3000, VLDO3, PFUZE100_VGEN5VOL, 1800000, 3300000, 100000),
+ PFUZE100_VGEN_REG(PFUZE3000, VLDO4, PFUZE100_VGEN6VOL, 1800000, 3300000, 100000),
+};
+
static struct pfuze_regulator *pfuze_regulators;
#ifdef CONFIG_OF
@@ -294,6 +374,24 @@ static struct of_regulator_match pfuze200_matches[] = {
{ .name = "vgen6", },
};
+/* PFUZE3000 */
+static struct of_regulator_match pfuze3000_matches[] = {
+
+ { .name = "sw1a", },
+ { .name = "sw1b", },
+ { .name = "sw2", },
+ { .name = "sw3", },
+ { .name = "swbst", },
+ { .name = "vsnvs", },
+ { .name = "vrefddr", },
+ { .name = "vldo1", },
+ { .name = "vldo2", },
+ { .name = "vccsd", },
+ { .name = "v33", },
+ { .name = "vldo3", },
+ { .name = "vldo4", },
+};
+
static struct of_regulator_match *pfuze_matches;
static int pfuze_parse_regulators_dt(struct pfuze_chip *chip)
@@ -313,6 +411,11 @@ static int pfuze_parse_regulators_dt(struct pfuze_chip *chip)
}
switch (chip->chip_id) {
+ case PFUZE3000:
+ pfuze_matches = pfuze3000_matches;
+ ret = of_regulator_match(dev, parent, pfuze3000_matches,
+ ARRAY_SIZE(pfuze3000_matches));
+ break;
case PFUZE200:
pfuze_matches = pfuze200_matches;
ret = of_regulator_match(dev, parent, pfuze200_matches,
@@ -378,7 +481,8 @@ static int pfuze_identify(struct pfuze_chip *pfuze_chip)
* as ID=8 in PFUZE100
*/
dev_info(pfuze_chip->dev, "Assuming misprogrammed ID=0x8");
- } else if ((value & 0x0f) != pfuze_chip->chip_id) {
+ } else if ((value & 0x0f) != pfuze_chip->chip_id &&
+ (value & 0xf0) >> 4 != pfuze_chip->chip_id) {
/* device id NOT match with your setting */
dev_warn(pfuze_chip->dev, "Illegal ID: %x\n", value);
return -ENODEV;
@@ -417,7 +521,7 @@ static int pfuze100_regulator_probe(struct i2c_client *client,
int i, ret;
const struct of_device_id *match;
u32 regulator_num;
- u32 sw_check_start, sw_check_end;
+ u32 sw_check_start, sw_check_end, sw_hi = 0x40;
pfuze_chip = devm_kzalloc(&client->dev, sizeof(*pfuze_chip),
GFP_KERNEL);
@@ -458,13 +562,19 @@ static int pfuze100_regulator_probe(struct i2c_client *client,
/* use the right regulators after identify the right device */
switch (pfuze_chip->chip_id) {
+ case PFUZE3000:
+ pfuze_regulators = pfuze3000_regulators;
+ regulator_num = ARRAY_SIZE(pfuze3000_regulators);
+ sw_check_start = PFUZE3000_SW2;
+ sw_check_end = PFUZE3000_SW2;
+ sw_hi = 1 << 3;
+ break;
case PFUZE200:
pfuze_regulators = pfuze200_regulators;
regulator_num = ARRAY_SIZE(pfuze200_regulators);
sw_check_start = PFUZE200_SW2;
sw_check_end = PFUZE200_SW3B;
break;
-
case PFUZE100:
default:
pfuze_regulators = pfuze100_regulators;
@@ -474,7 +584,8 @@ static int pfuze100_regulator_probe(struct i2c_client *client,
break;
}
dev_info(&client->dev, "pfuze%s found.\n",
- (pfuze_chip->chip_id == PFUZE100) ? "100" : "200");
+ (pfuze_chip->chip_id == PFUZE100) ? "100" :
+ ((pfuze_chip->chip_id == PFUZE200) ? "200" : "3000"));
memcpy(pfuze_chip->regulator_descs, pfuze_regulators,
sizeof(pfuze_chip->regulator_descs));
@@ -498,10 +609,15 @@ static int pfuze100_regulator_probe(struct i2c_client *client,
/* SW2~SW4 high bit check and modify the voltage value table */
if (i >= sw_check_start && i <= sw_check_end) {
regmap_read(pfuze_chip->regmap, desc->vsel_reg, &val);
- if (val & 0x40) {
- desc->min_uV = 800000;
- desc->uV_step = 50000;
- desc->n_voltages = 51;
+ if (val & sw_hi) {
+ if (pfuze_chip->chip_id == PFUZE3000) {
+ desc->volt_table = pfuze3000_sw2hi;
+ desc->n_voltages = ARRAY_SIZE(pfuze3000_sw2hi);
+ } else {
+ desc->min_uV = 800000;
+ desc->uV_step = 50000;
+ desc->n_voltages = 51;
+ }
}
}
diff --git a/drivers/regulator/pwm-regulator.c b/drivers/regulator/pwm-regulator.c
index d3f55ea..253833a 100644
--- a/drivers/regulator/pwm-regulator.c
+++ b/drivers/regulator/pwm-regulator.c
@@ -149,7 +149,8 @@ static int pwm_regulator_probe(struct platform_device *pdev)
return ret;
}
- config.init_data = of_get_regulator_init_data(&pdev->dev, np);
+ config.init_data = of_get_regulator_init_data(&pdev->dev, np,
+ &drvdata->desc);
if (!config.init_data)
return -ENOMEM;
@@ -183,7 +184,6 @@ MODULE_DEVICE_TABLE(of, pwm_of_match);
static struct platform_driver pwm_regulator_driver = {
.driver = {
.name = "pwm-regulator",
- .owner = THIS_MODULE,
.of_match_table = of_match_ptr(pwm_of_match),
},
.probe = pwm_regulator_probe,
diff --git a/drivers/regulator/qcom_rpm-regulator.c b/drivers/regulator/qcom_rpm-regulator.c
index b55cd5b..e8647f7 100644
--- a/drivers/regulator/qcom_rpm-regulator.c
+++ b/drivers/regulator/qcom_rpm-regulator.c
@@ -183,6 +183,13 @@ static const struct regulator_linear_range ftsmps_ranges[] = {
REGULATOR_LINEAR_RANGE(1500000, 64, 100, 50000),
};
+static const struct regulator_linear_range smb208_ranges[] = {
+ REGULATOR_LINEAR_RANGE( 375000, 0, 29, 12500),
+ REGULATOR_LINEAR_RANGE( 750000, 30, 89, 12500),
+ REGULATOR_LINEAR_RANGE(1500000, 90, 153, 25000),
+ REGULATOR_LINEAR_RANGE(3100000, 154, 234, 25000),
+};
+
static const struct regulator_linear_range ncp_ranges[] = {
REGULATOR_LINEAR_RANGE(1500000, 0, 31, 50000),
};
@@ -220,9 +227,11 @@ static int rpm_reg_set_mV_sel(struct regulator_dev *rdev,
return uV;
mutex_lock(&vreg->lock);
- vreg->uV = uV;
if (vreg->is_enabled)
- ret = rpm_reg_write(vreg, req, vreg->uV / 1000);
+ ret = rpm_reg_write(vreg, req, uV / 1000);
+
+ if (!ret)
+ vreg->uV = uV;
mutex_unlock(&vreg->lock);
return ret;
@@ -245,9 +254,11 @@ static int rpm_reg_set_uV_sel(struct regulator_dev *rdev,
return uV;
mutex_lock(&vreg->lock);
- vreg->uV = uV;
if (vreg->is_enabled)
- ret = rpm_reg_write(vreg, req, vreg->uV);
+ ret = rpm_reg_write(vreg, req, uV);
+
+ if (!ret)
+ vreg->uV = uV;
mutex_unlock(&vreg->lock);
return ret;
@@ -559,6 +570,16 @@ static const struct qcom_rpm_reg pm8921_switch = {
.parts = &rpm8960_switch_parts,
};
+static const struct qcom_rpm_reg smb208_smps = {
+ .desc.linear_ranges = smb208_ranges,
+ .desc.n_linear_ranges = ARRAY_SIZE(smb208_ranges),
+ .desc.n_voltages = 235,
+ .desc.ops = &uV_ops,
+ .parts = &rpm8960_smps_parts,
+ .supports_force_mode_auto = false,
+ .supports_force_mode_bypass = false,
+};
+
static const struct of_device_id rpm_of_match[] = {
{ .compatible = "qcom,rpm-pm8058-pldo", .data = &pm8058_pldo },
{ .compatible = "qcom,rpm-pm8058-nldo", .data = &pm8058_nldo },
@@ -578,6 +599,8 @@ static const struct of_device_id rpm_of_match[] = {
{ .compatible = "qcom,rpm-pm8921-ftsmps", .data = &pm8921_ftsmps },
{ .compatible = "qcom,rpm-pm8921-ncp", .data = &pm8921_ncp },
{ .compatible = "qcom,rpm-pm8921-switch", .data = &pm8921_switch },
+
+ { .compatible = "qcom,rpm-smb208", .data = &smb208_smps },
{ }
};
MODULE_DEVICE_TABLE(of, rpm_of_match);
@@ -643,10 +666,6 @@ static int rpm_reg_probe(struct platform_device *pdev)
match = of_match_device(rpm_of_match, &pdev->dev);
template = match->data;
- initdata = of_get_regulator_init_data(&pdev->dev, pdev->dev.of_node);
- if (!initdata)
- return -EINVAL;
-
vreg = devm_kmalloc(&pdev->dev, sizeof(*vreg), GFP_KERNEL);
if (!vreg) {
dev_err(&pdev->dev, "failed to allocate vreg\n");
@@ -659,6 +678,7 @@ static int rpm_reg_probe(struct platform_device *pdev)
vreg->desc.owner = THIS_MODULE;
vreg->desc.type = REGULATOR_VOLTAGE;
vreg->desc.name = pdev->dev.of_node->name;
+ vreg->desc.supply_name = "vin";
vreg->rpm = dev_get_drvdata(pdev->dev.parent);
if (!vreg->rpm) {
@@ -666,6 +686,11 @@ static int rpm_reg_probe(struct platform_device *pdev)
return -ENODEV;
}
+ initdata = of_get_regulator_init_data(&pdev->dev, pdev->dev.of_node,
+ &vreg->desc);
+ if (!initdata)
+ return -EINVAL;
+
key = "reg";
ret = of_property_read_u32(pdev->dev.of_node, key, &val);
if (ret) {
@@ -748,7 +773,7 @@ static int rpm_reg_probe(struct platform_device *pdev)
break;
}
- if (force_mode < 0) {
+ if (force_mode == -1) {
dev_err(&pdev->dev, "invalid force mode\n");
return -EINVAL;
}
@@ -777,7 +802,6 @@ static struct platform_driver rpm_reg_driver = {
.probe = rpm_reg_probe,
.driver = {
.name = "qcom_rpm_reg",
- .owner = THIS_MODULE,
.of_match_table = of_match_ptr(rpm_of_match),
},
};
diff --git a/drivers/regulator/rc5t583-regulator.c b/drivers/regulator/rc5t583-regulator.c
index 4c414ae..d2e67c5 100644
--- a/drivers/regulator/rc5t583-regulator.c
+++ b/drivers/regulator/rc5t583-regulator.c
@@ -179,7 +179,6 @@ skip_ext_pwr_config:
static struct platform_driver rc5t583_regulator_driver = {
.driver = {
.name = "rc5t583-regulator",
- .owner = THIS_MODULE,
},
.probe = rc5t583_regulator_probe,
};
diff --git a/drivers/regulator/rk808-regulator.c b/drivers/regulator/rk808-regulator.c
index 33042eb..1f93b75 100644
--- a/drivers/regulator/rk808-regulator.c
+++ b/drivers/regulator/rk808-regulator.c
@@ -50,7 +50,7 @@ static const int rk808_buck_config_regs[] = {
};
static const struct regulator_linear_range rk808_buck_voltage_ranges[] = {
- REGULATOR_LINEAR_RANGE(700000, 0, 63, 12500),
+ REGULATOR_LINEAR_RANGE(712500, 0, 63, 12500),
};
static const struct regulator_linear_range rk808_buck4_voltage_ranges[] = {
@@ -419,7 +419,6 @@ static struct platform_driver rk808_regulator_driver = {
.probe = rk808_regulator_probe,
.driver = {
.name = "rk808-regulator",
- .owner = THIS_MODULE,
},
};
diff --git a/drivers/regulator/rn5t618-regulator.c b/drivers/regulator/rn5t618-regulator.c
index e58d79a..b85ceb8 100644
--- a/drivers/regulator/rn5t618-regulator.c
+++ b/drivers/regulator/rn5t618-regulator.c
@@ -31,6 +31,8 @@ static struct regulator_ops rn5t618_reg_ops = {
#define REG(rid, ereg, emask, vreg, vmask, min, max, step) \
[RN5T618_##rid] = { \
.name = #rid, \
+ .of_match = of_match_ptr(#rid), \
+ .regulators_node = of_match_ptr("regulators"), \
.id = RN5T618_##rid, \
.type = REGULATOR_VOLTAGE, \
.owner = THIS_MODULE, \
@@ -60,60 +62,15 @@ static struct regulator_desc rn5t618_regulators[] = {
REG(LDORTC2, LDOEN2, BIT(5), LDORTC2DAC, 0x7f, 900000, 3500000, 25000),
};
-static struct of_regulator_match rn5t618_matches[] = {
- [RN5T618_DCDC1] = { .name = "DCDC1" },
- [RN5T618_DCDC2] = { .name = "DCDC2" },
- [RN5T618_DCDC3] = { .name = "DCDC3" },
- [RN5T618_LDO1] = { .name = "LDO1" },
- [RN5T618_LDO2] = { .name = "LDO2" },
- [RN5T618_LDO3] = { .name = "LDO3" },
- [RN5T618_LDO4] = { .name = "LDO4" },
- [RN5T618_LDO5] = { .name = "LDO5" },
- [RN5T618_LDORTC1] = { .name = "LDORTC1" },
- [RN5T618_LDORTC2] = { .name = "LDORTC2" },
-};
-
-static int rn5t618_regulator_parse_dt(struct platform_device *pdev)
-{
- struct device_node *np, *regulators;
- int ret;
-
- np = of_node_get(pdev->dev.parent->of_node);
- if (!np)
- return 0;
-
- regulators = of_get_child_by_name(np, "regulators");
- if (!regulators) {
- dev_err(&pdev->dev, "regulators node not found\n");
- return -EINVAL;
- }
-
- ret = of_regulator_match(&pdev->dev, regulators, rn5t618_matches,
- ARRAY_SIZE(rn5t618_matches));
- of_node_put(regulators);
- if (ret < 0) {
- dev_err(&pdev->dev, "error parsing regulator init data: %d\n",
- ret);
- }
-
- return 0;
-}
-
static int rn5t618_regulator_probe(struct platform_device *pdev)
{
struct rn5t618 *rn5t618 = dev_get_drvdata(pdev->dev.parent);
struct regulator_config config = { };
struct regulator_dev *rdev;
- int ret, i;
-
- ret = rn5t618_regulator_parse_dt(pdev);
- if (ret)
- return ret;
+ int i;
for (i = 0; i < RN5T618_REG_NUM; i++) {
- config.dev = &pdev->dev;
- config.init_data = rn5t618_matches[i].init_data;
- config.of_node = rn5t618_matches[i].of_node;
+ config.dev = pdev->dev.parent;
config.regmap = rn5t618->regmap;
rdev = devm_regulator_register(&pdev->dev,
diff --git a/drivers/regulator/rt5033-regulator.c b/drivers/regulator/rt5033-regulator.c
new file mode 100644
index 0000000..96d2c18
--- /dev/null
+++ b/drivers/regulator/rt5033-regulator.c
@@ -0,0 +1,129 @@
+/*
+ * Regulator driver for the Richtek RT5033
+ *
+ * Copyright (C) 2014 Samsung Electronics, Co., Ltd.
+ * Author: Beomho Seo <beomho.seo@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published bythe Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/driver.h>
+#include <linux/mfd/rt5033.h>
+#include <linux/mfd/rt5033-private.h>
+#include <linux/regulator/of_regulator.h>
+
+static struct regulator_ops rt5033_safe_ldo_ops = {
+ .is_enabled = regulator_is_enabled_regmap,
+ .enable = regulator_enable_regmap,
+ .disable = regulator_disable_regmap,
+ .list_voltage = regulator_list_voltage_linear,
+};
+
+static struct regulator_ops rt5033_buck_ops = {
+ .is_enabled = regulator_is_enabled_regmap,
+ .enable = regulator_enable_regmap,
+ .disable = regulator_disable_regmap,
+ .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,
+};
+
+static const struct regulator_desc rt5033_supported_regulators[] = {
+ [RT5033_BUCK] = {
+ .name = "BUCK",
+ .of_match = of_match_ptr("BUCK"),
+ .regulators_node = of_match_ptr("regulators"),
+ .id = RT5033_BUCK,
+ .ops = &rt5033_buck_ops,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE,
+ .n_voltages = RT5033_REGULATOR_BUCK_VOLTAGE_STEP_NUM,
+ .min_uV = RT5033_REGULATOR_BUCK_VOLTAGE_MIN,
+ .uV_step = RT5033_REGULATOR_BUCK_VOLTAGE_STEP,
+ .enable_reg = RT5033_REG_CTRL,
+ .enable_mask = RT5033_CTRL_EN_BUCK_MASK,
+ .vsel_reg = RT5033_REG_BUCK_CTRL,
+ .vsel_mask = RT5033_BUCK_CTRL_MASK,
+ },
+ [RT5033_LDO] = {
+ .name = "LDO",
+ .of_match = of_match_ptr("LDO"),
+ .regulators_node = of_match_ptr("regulators"),
+ .id = RT5033_LDO,
+ .ops = &rt5033_buck_ops,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE,
+ .n_voltages = RT5033_REGULATOR_LDO_VOLTAGE_STEP_NUM,
+ .min_uV = RT5033_REGULATOR_LDO_VOLTAGE_MIN,
+ .uV_step = RT5033_REGULATOR_LDO_VOLTAGE_STEP,
+ .enable_reg = RT5033_REG_CTRL,
+ .enable_mask = RT5033_CTRL_EN_LDO_MASK,
+ .vsel_reg = RT5033_REG_LDO_CTRL,
+ .vsel_mask = RT5033_LDO_CTRL_MASK,
+ },
+ [RT5033_SAFE_LDO] = {
+ .name = "SAFE_LDO",
+ .of_match = of_match_ptr("SAFE_LDO"),
+ .regulators_node = of_match_ptr("regulators"),
+ .id = RT5033_SAFE_LDO,
+ .ops = &rt5033_safe_ldo_ops,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE,
+ .n_voltages = 1,
+ .min_uV = RT5033_REGULATOR_SAFE_LDO_VOLTAGE,
+ .enable_reg = RT5033_REG_CTRL,
+ .enable_mask = RT5033_CTRL_EN_SAFE_LDO_MASK,
+ },
+};
+
+static int rt5033_regulator_probe(struct platform_device *pdev)
+{
+ struct rt5033_dev *rt5033 = dev_get_drvdata(pdev->dev.parent);
+ int ret, i;
+ struct regulator_config config = {};
+
+ config.dev = rt5033->dev;
+ config.driver_data = rt5033;
+
+ for (i = 0; i < ARRAY_SIZE(rt5033_supported_regulators); i++) {
+ struct regulator_dev *regulator;
+
+ config.regmap = rt5033->regmap;
+
+ regulator = devm_regulator_register(&pdev->dev,
+ &rt5033_supported_regulators[i], &config);
+ if (IS_ERR(regulator)) {
+ ret = PTR_ERR(regulator);
+ dev_err(&pdev->dev,
+ "Regulator init failed %d: with error: %d\n",
+ i, ret);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static const struct platform_device_id rt5033_regulator_id[] = {
+ { "rt5033-regulator", },
+ { }
+};
+MODULE_DEVICE_TABLE(platform, rt5033_regulator_id);
+
+static struct platform_driver rt5033_regulator_driver = {
+ .driver = {
+ .name = "rt5033-regulator",
+ },
+ .probe = rt5033_regulator_probe,
+ .id_table = rt5033_regulator_id,
+};
+module_platform_driver(rt5033_regulator_driver);
+
+MODULE_DESCRIPTION("Richtek RT5033 Regulator driver");
+MODULE_AUTHOR("Beomho Seo <beomho.seo@samsung.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/regulator/s2mpa01.c b/drivers/regulator/s2mpa01.c
index 4acefa6..92f8875 100644
--- a/drivers/regulator/s2mpa01.c
+++ b/drivers/regulator/s2mpa01.c
@@ -298,7 +298,7 @@ static struct regulator_ops s2mpa01_buck_ops = {
.enable_mask = S2MPA01_ENABLE_MASK \
}
-static struct regulator_desc regulators[] = {
+static const struct regulator_desc regulators[] = {
regulator_desc_ldo(1, STEP_25_MV),
regulator_desc_ldo(2, STEP_50_MV),
regulator_desc_ldo(3, STEP_50_MV),
@@ -341,7 +341,7 @@ static int s2mpa01_pmic_probe(struct platform_device *pdev)
{
struct sec_pmic_dev *iodev = dev_get_drvdata(pdev->dev.parent);
struct sec_platform_data *pdata = dev_get_platdata(iodev->dev);
- struct of_regulator_match rdata[S2MPA01_REGULATOR_MAX];
+ struct of_regulator_match rdata[S2MPA01_REGULATOR_MAX] = { };
struct device_node *reg_np = NULL;
struct regulator_config config = { };
struct s2mpa01_info *s2mpa01;
@@ -405,7 +405,6 @@ MODULE_DEVICE_TABLE(platform, s2mpa01_pmic_id);
static struct platform_driver s2mpa01_pmic_driver = {
.driver = {
.name = "s2mpa01-pmic",
- .owner = THIS_MODULE,
},
.probe = s2mpa01_pmic_probe,
.id_table = s2mpa01_pmic_id,
diff --git a/drivers/regulator/s2mps11.c b/drivers/regulator/s2mps11.c
index adab82d..ff82811 100644
--- a/drivers/regulator/s2mps11.c
+++ b/drivers/regulator/s2mps11.c
@@ -30,6 +30,7 @@
#include <linux/of_gpio.h>
#include <linux/mfd/samsung/core.h>
#include <linux/mfd/samsung/s2mps11.h>
+#include <linux/mfd/samsung/s2mps13.h>
#include <linux/mfd/samsung/s2mps14.h>
#include <linux/mfd/samsung/s2mpu02.h>
@@ -45,10 +46,10 @@ struct s2mps11_info {
enum sec_device_type dev_type;
/*
- * One bit for each S2MPS14/S2MPU02 regulator whether the suspend mode
- * was enabled.
+ * One bit for each S2MPS13/S2MPS14/S2MPU02 regulator whether
+ * the suspend mode was enabled.
*/
- unsigned long long s2mps14_suspend_state:35;
+ unsigned long long s2mps14_suspend_state:50;
/* Array of size rdev_num with GPIO-s for external sleep control */
int *ext_control_gpio;
@@ -369,12 +370,135 @@ static const struct regulator_desc s2mps11_regulators[] = {
regulator_desc_s2mps11_buck6_10(10, MIN_750_MV, STEP_12_5_MV),
};
+static struct regulator_ops s2mps14_reg_ops;
+
+#define regulator_desc_s2mps13_ldo(num, min, step, min_sel) { \
+ .name = "LDO"#num, \
+ .id = S2MPS13_LDO##num, \
+ .ops = &s2mps14_reg_ops, \
+ .type = REGULATOR_VOLTAGE, \
+ .owner = THIS_MODULE, \
+ .min_uV = min, \
+ .uV_step = step, \
+ .linear_min_sel = min_sel, \
+ .n_voltages = S2MPS14_LDO_N_VOLTAGES, \
+ .vsel_reg = S2MPS13_REG_L1CTRL + num - 1, \
+ .vsel_mask = S2MPS14_LDO_VSEL_MASK, \
+ .enable_reg = S2MPS13_REG_L1CTRL + num - 1, \
+ .enable_mask = S2MPS14_ENABLE_MASK \
+}
+
+#define regulator_desc_s2mps13_buck(num, min, step, min_sel) { \
+ .name = "BUCK"#num, \
+ .id = S2MPS13_BUCK##num, \
+ .ops = &s2mps14_reg_ops, \
+ .type = REGULATOR_VOLTAGE, \
+ .owner = THIS_MODULE, \
+ .min_uV = min, \
+ .uV_step = step, \
+ .linear_min_sel = min_sel, \
+ .n_voltages = S2MPS14_BUCK_N_VOLTAGES, \
+ .ramp_delay = S2MPS13_BUCK_RAMP_DELAY, \
+ .vsel_reg = S2MPS13_REG_B1OUT + (num - 1) * 2, \
+ .vsel_mask = S2MPS14_BUCK_VSEL_MASK, \
+ .enable_reg = S2MPS13_REG_B1CTRL + (num - 1) * 2, \
+ .enable_mask = S2MPS14_ENABLE_MASK \
+}
+
+#define regulator_desc_s2mps13_buck7(num, min, step, min_sel) { \
+ .name = "BUCK"#num, \
+ .id = S2MPS13_BUCK##num, \
+ .ops = &s2mps14_reg_ops, \
+ .type = REGULATOR_VOLTAGE, \
+ .owner = THIS_MODULE, \
+ .min_uV = min, \
+ .uV_step = step, \
+ .linear_min_sel = min_sel, \
+ .n_voltages = S2MPS14_BUCK_N_VOLTAGES, \
+ .ramp_delay = S2MPS13_BUCK_RAMP_DELAY, \
+ .vsel_reg = S2MPS13_REG_B1OUT + (num) * 2 - 1, \
+ .vsel_mask = S2MPS14_BUCK_VSEL_MASK, \
+ .enable_reg = S2MPS13_REG_B1CTRL + (num - 1) * 2, \
+ .enable_mask = S2MPS14_ENABLE_MASK \
+}
+
+#define regulator_desc_s2mps13_buck8_10(num, min, step, min_sel) { \
+ .name = "BUCK"#num, \
+ .id = S2MPS13_BUCK##num, \
+ .ops = &s2mps14_reg_ops, \
+ .type = REGULATOR_VOLTAGE, \
+ .owner = THIS_MODULE, \
+ .min_uV = min, \
+ .uV_step = step, \
+ .linear_min_sel = min_sel, \
+ .n_voltages = S2MPS14_BUCK_N_VOLTAGES, \
+ .ramp_delay = S2MPS13_BUCK_RAMP_DELAY, \
+ .vsel_reg = S2MPS13_REG_B1OUT + (num) * 2 - 1, \
+ .vsel_mask = S2MPS14_BUCK_VSEL_MASK, \
+ .enable_reg = S2MPS13_REG_B1CTRL + (num) * 2 - 1, \
+ .enable_mask = S2MPS14_ENABLE_MASK \
+}
+
+static const struct regulator_desc s2mps13_regulators[] = {
+ regulator_desc_s2mps13_ldo(1, MIN_800_MV, STEP_12_5_MV, 0x00),
+ regulator_desc_s2mps13_ldo(2, MIN_1400_MV, STEP_50_MV, 0x0C),
+ regulator_desc_s2mps13_ldo(3, MIN_1000_MV, STEP_25_MV, 0x08),
+ regulator_desc_s2mps13_ldo(4, MIN_800_MV, STEP_12_5_MV, 0x00),
+ regulator_desc_s2mps13_ldo(5, MIN_800_MV, STEP_12_5_MV, 0x00),
+ regulator_desc_s2mps13_ldo(6, MIN_800_MV, STEP_12_5_MV, 0x00),
+ regulator_desc_s2mps13_ldo(7, MIN_1000_MV, STEP_25_MV, 0x08),
+ regulator_desc_s2mps13_ldo(8, MIN_1000_MV, STEP_25_MV, 0x08),
+ regulator_desc_s2mps13_ldo(9, MIN_1000_MV, STEP_25_MV, 0x08),
+ regulator_desc_s2mps13_ldo(10, MIN_1400_MV, STEP_50_MV, 0x0C),
+ regulator_desc_s2mps13_ldo(11, MIN_800_MV, STEP_25_MV, 0x10),
+ regulator_desc_s2mps13_ldo(12, MIN_800_MV, STEP_25_MV, 0x10),
+ regulator_desc_s2mps13_ldo(13, MIN_800_MV, STEP_25_MV, 0x10),
+ regulator_desc_s2mps13_ldo(14, MIN_800_MV, STEP_12_5_MV, 0x00),
+ regulator_desc_s2mps13_ldo(15, MIN_800_MV, STEP_12_5_MV, 0x00),
+ regulator_desc_s2mps13_ldo(16, MIN_1400_MV, STEP_50_MV, 0x0C),
+ regulator_desc_s2mps13_ldo(17, MIN_1400_MV, STEP_50_MV, 0x0C),
+ regulator_desc_s2mps13_ldo(18, MIN_1000_MV, STEP_25_MV, 0x08),
+ regulator_desc_s2mps13_ldo(19, MIN_1000_MV, STEP_25_MV, 0x08),
+ regulator_desc_s2mps13_ldo(20, MIN_1400_MV, STEP_50_MV, 0x0C),
+ regulator_desc_s2mps13_ldo(21, MIN_1000_MV, STEP_25_MV, 0x08),
+ regulator_desc_s2mps13_ldo(22, MIN_1000_MV, STEP_25_MV, 0x08),
+ regulator_desc_s2mps13_ldo(23, MIN_800_MV, STEP_12_5_MV, 0x00),
+ regulator_desc_s2mps13_ldo(24, MIN_800_MV, STEP_12_5_MV, 0x00),
+ regulator_desc_s2mps13_ldo(25, MIN_1400_MV, STEP_50_MV, 0x0C),
+ regulator_desc_s2mps13_ldo(26, MIN_1400_MV, STEP_50_MV, 0x0C),
+ regulator_desc_s2mps13_ldo(27, MIN_1400_MV, STEP_50_MV, 0x0C),
+ regulator_desc_s2mps13_ldo(28, MIN_1000_MV, STEP_25_MV, 0x08),
+ regulator_desc_s2mps13_ldo(29, MIN_1400_MV, STEP_50_MV, 0x0C),
+ regulator_desc_s2mps13_ldo(30, MIN_1400_MV, STEP_50_MV, 0x0C),
+ regulator_desc_s2mps13_ldo(31, MIN_1000_MV, STEP_25_MV, 0x08),
+ regulator_desc_s2mps13_ldo(32, MIN_1000_MV, STEP_25_MV, 0x08),
+ regulator_desc_s2mps13_ldo(33, MIN_1400_MV, STEP_50_MV, 0x0C),
+ regulator_desc_s2mps13_ldo(34, MIN_1000_MV, STEP_25_MV, 0x08),
+ regulator_desc_s2mps13_ldo(35, MIN_1400_MV, STEP_50_MV, 0x0C),
+ regulator_desc_s2mps13_ldo(36, MIN_800_MV, STEP_12_5_MV, 0x00),
+ regulator_desc_s2mps13_ldo(37, MIN_1000_MV, STEP_25_MV, 0x08),
+ regulator_desc_s2mps13_ldo(38, MIN_1400_MV, STEP_50_MV, 0x0C),
+ regulator_desc_s2mps13_ldo(39, MIN_1000_MV, STEP_25_MV, 0x08),
+ regulator_desc_s2mps13_ldo(40, MIN_1400_MV, STEP_50_MV, 0x0C),
+ regulator_desc_s2mps13_buck(1, MIN_500_MV, STEP_6_25_MV, 0x10),
+ regulator_desc_s2mps13_buck(2, MIN_500_MV, STEP_6_25_MV, 0x10),
+ regulator_desc_s2mps13_buck(3, MIN_500_MV, STEP_6_25_MV, 0x10),
+ regulator_desc_s2mps13_buck(4, MIN_500_MV, STEP_6_25_MV, 0x10),
+ regulator_desc_s2mps13_buck(5, MIN_500_MV, STEP_6_25_MV, 0x10),
+ regulator_desc_s2mps13_buck(6, MIN_500_MV, STEP_6_25_MV, 0x10),
+ regulator_desc_s2mps13_buck7(7, MIN_500_MV, STEP_6_25_MV, 0x10),
+ regulator_desc_s2mps13_buck8_10(8, MIN_1000_MV, STEP_12_5_MV, 0x20),
+ regulator_desc_s2mps13_buck8_10(9, MIN_1000_MV, STEP_12_5_MV, 0x20),
+ regulator_desc_s2mps13_buck8_10(10, MIN_500_MV, STEP_6_25_MV, 0x10),
+};
+
static int s2mps14_regulator_enable(struct regulator_dev *rdev)
{
struct s2mps11_info *s2mps11 = rdev_get_drvdata(rdev);
unsigned int val;
switch (s2mps11->dev_type) {
+ case S2MPS13X:
case S2MPS14X:
if (s2mps11->s2mps14_suspend_state & (1 << rdev_get_id(rdev)))
val = S2MPS14_ENABLE_SUSPEND;
@@ -406,6 +530,7 @@ static int s2mps14_regulator_set_suspend_disable(struct regulator_dev *rdev)
/* Below LDO should be always on or does not support suspend mode. */
switch (s2mps11->dev_type) {
+ case S2MPS13X:
case S2MPS14X:
switch (rdev_id) {
case S2MPS14_LDO3:
@@ -479,7 +604,7 @@ static struct regulator_ops s2mps14_reg_ops = {
.enable_mask = S2MPS14_ENABLE_MASK \
}
-#define regulator_desc_s2mps14_buck(num, min, step) { \
+#define regulator_desc_s2mps14_buck(num, min, step, min_sel) { \
.name = "BUCK"#num, \
.id = S2MPS14_BUCK##num, \
.ops = &s2mps14_reg_ops, \
@@ -488,7 +613,7 @@ static struct regulator_ops s2mps14_reg_ops = {
.min_uV = min, \
.uV_step = step, \
.n_voltages = S2MPS14_BUCK_N_VOLTAGES, \
- .linear_min_sel = S2MPS14_BUCK1235_START_SEL, \
+ .linear_min_sel = min_sel, \
.ramp_delay = S2MPS14_BUCK_RAMP_DELAY, \
.vsel_reg = S2MPS14_REG_B1CTRL2 + (num - 1) * 2, \
.vsel_mask = S2MPS14_BUCK_VSEL_MASK, \
@@ -522,11 +647,16 @@ static const struct regulator_desc s2mps14_regulators[] = {
regulator_desc_s2mps14_ldo(23, MIN_800_MV, STEP_25_MV),
regulator_desc_s2mps14_ldo(24, MIN_1800_MV, STEP_25_MV),
regulator_desc_s2mps14_ldo(25, MIN_1800_MV, STEP_25_MV),
- regulator_desc_s2mps14_buck(1, MIN_600_MV, STEP_6_25_MV),
- regulator_desc_s2mps14_buck(2, MIN_600_MV, STEP_6_25_MV),
- regulator_desc_s2mps14_buck(3, MIN_600_MV, STEP_6_25_MV),
- regulator_desc_s2mps14_buck(4, MIN_1400_MV, STEP_12_5_MV),
- regulator_desc_s2mps14_buck(5, MIN_600_MV, STEP_6_25_MV),
+ regulator_desc_s2mps14_buck(1, MIN_600_MV, STEP_6_25_MV,
+ S2MPS14_BUCK1235_START_SEL),
+ regulator_desc_s2mps14_buck(2, MIN_600_MV, STEP_6_25_MV,
+ S2MPS14_BUCK1235_START_SEL),
+ regulator_desc_s2mps14_buck(3, MIN_600_MV, STEP_6_25_MV,
+ S2MPS14_BUCK1235_START_SEL),
+ regulator_desc_s2mps14_buck(4, MIN_1400_MV, STEP_12_5_MV,
+ S2MPS14_BUCK4_START_SEL),
+ regulator_desc_s2mps14_buck(5, MIN_600_MV, STEP_6_25_MV,
+ S2MPS14_BUCK1235_START_SEL),
};
static int s2mps14_pmic_enable_ext_control(struct s2mps11_info *s2mps11,
@@ -831,6 +961,10 @@ static int s2mps11_pmic_probe(struct platform_device *pdev)
s2mps11->rdev_num = ARRAY_SIZE(s2mps11_regulators);
regulators = s2mps11_regulators;
break;
+ case S2MPS13X:
+ s2mps11->rdev_num = ARRAY_SIZE(s2mps13_regulators);
+ regulators = s2mps13_regulators;
+ break;
case S2MPS14X:
s2mps11->rdev_num = ARRAY_SIZE(s2mps14_regulators);
regulators = s2mps14_regulators;
@@ -845,7 +979,7 @@ static int s2mps11_pmic_probe(struct platform_device *pdev)
return -EINVAL;
};
- s2mps11->ext_control_gpio = devm_kzalloc(&pdev->dev,
+ s2mps11->ext_control_gpio = devm_kmalloc(&pdev->dev,
sizeof(*s2mps11->ext_control_gpio) * s2mps11->rdev_num,
GFP_KERNEL);
if (!s2mps11->ext_control_gpio)
@@ -886,6 +1020,7 @@ common_reg:
config.regmap = iodev->regmap_pmic;
config.driver_data = s2mps11;
config.ena_gpio_flags = GPIOF_OUT_INIT_HIGH;
+ config.ena_gpio_initialized = true;
for (i = 0; i < s2mps11->rdev_num; i++) {
struct regulator_dev *regulator;
@@ -927,6 +1062,7 @@ out:
static const struct platform_device_id s2mps11_pmic_id[] = {
{ "s2mps11-pmic", S2MPS11X},
+ { "s2mps13-pmic", S2MPS13X},
{ "s2mps14-pmic", S2MPS14X},
{ "s2mpu02-pmic", S2MPU02},
{ },
@@ -936,7 +1072,6 @@ MODULE_DEVICE_TABLE(platform, s2mps11_pmic_id);
static struct platform_driver s2mps11_pmic_driver = {
.driver = {
.name = "s2mps11-pmic",
- .owner = THIS_MODULE,
},
.probe = s2mps11_pmic_probe,
.id_table = s2mps11_pmic_id,
diff --git a/drivers/regulator/s5m8767.c b/drivers/regulator/s5m8767.c
index 0ab5cbe..58f5d3b 100644
--- a/drivers/regulator/s5m8767.c
+++ b/drivers/regulator/s5m8767.c
@@ -581,7 +581,8 @@ static int s5m8767_pmic_dt_parse_pdata(struct platform_device *pdev,
rdata->id = i;
rdata->initdata = of_get_regulator_init_data(
- &pdev->dev, reg_np);
+ &pdev->dev, reg_np,
+ &regulators[i]);
rdata->reg_node = reg_np;
rdata++;
rmode->id = i;
@@ -950,6 +951,7 @@ static int s5m8767_pmic_probe(struct platform_device *pdev)
config.of_node = pdata->regulators[i].reg_node;
config.ena_gpio = -EINVAL;
config.ena_gpio_flags = 0;
+ config.ena_gpio_initialized = true;
if (gpio_is_valid(pdata->regulators[i].ext_control_gpio))
s5m8767_regulator_config_ext_control(s5m8767,
&pdata->regulators[i], &config);
@@ -986,7 +988,6 @@ MODULE_DEVICE_TABLE(platform, s5m8767_pmic_id);
static struct platform_driver s5m8767_pmic_driver = {
.driver = {
.name = "s5m8767-pmic",
- .owner = THIS_MODULE,
},
.probe = s5m8767_pmic_probe,
.id_table = s5m8767_pmic_id,
diff --git a/drivers/regulator/sky81452-regulator.c b/drivers/regulator/sky81452-regulator.c
index 97aff0c..6478606 100644
--- a/drivers/regulator/sky81452-regulator.c
+++ b/drivers/regulator/sky81452-regulator.c
@@ -5,9 +5,8 @@
* Author : Gyungoh Yoo <jack.yoo@skyworksinc.com>
*
* This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
+ * under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -52,6 +51,8 @@ static const struct regulator_linear_range sky81452_reg_ranges[] = {
static const struct regulator_desc sky81452_reg = {
.name = "LOUT",
+ .of_match = of_match_ptr("lout"),
+ .regulators_node = of_match_ptr("regulator"),
.ops = &sky81452_reg_ops,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
@@ -64,30 +65,6 @@ static const struct regulator_desc sky81452_reg = {
.enable_mask = SKY81452_LEN,
};
-#ifdef CONFIG_OF
-static struct regulator_init_data *sky81452_reg_parse_dt(struct device *dev)
-{
- struct regulator_init_data *init_data;
- struct device_node *np;
-
- np = of_get_child_by_name(dev->parent->of_node, "regulator");
- if (unlikely(!np)) {
- dev_err(dev, "regulator node not found");
- return NULL;
- }
-
- init_data = of_get_regulator_init_data(dev, np);
-
- of_node_put(np);
- return init_data;
-}
-#else
-static struct regulator_init_data *sky81452_reg_parse_dt(struct device *dev)
-{
- return ERR_PTR(-EINVAL);
-}
-#endif
-
static int sky81452_reg_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
@@ -95,20 +72,16 @@ static int sky81452_reg_probe(struct platform_device *pdev)
struct regulator_config config = { };
struct regulator_dev *rdev;
- if (!init_data) {
- init_data = sky81452_reg_parse_dt(dev);
- if (IS_ERR(init_data))
- return PTR_ERR(init_data);
- }
-
- config.dev = dev;
+ config.dev = dev->parent;
config.init_data = init_data;
config.of_node = dev->of_node;
config.regmap = dev_get_drvdata(dev->parent);
rdev = devm_regulator_register(dev, &sky81452_reg, &config);
- if (IS_ERR(rdev))
+ if (IS_ERR(rdev)) {
+ dev_err(dev, "failed to register. err=%ld\n", PTR_ERR(rdev));
return PTR_ERR(rdev);
+ }
platform_set_drvdata(pdev, rdev);
@@ -126,5 +99,4 @@ module_platform_driver(sky81452_reg_driver);
MODULE_DESCRIPTION("Skyworks SKY81452 Regulator driver");
MODULE_AUTHOR("Gyungoh Yoo <jack.yoo@skyworksinc.com>");
-MODULE_LICENSE("GPL");
-MODULE_VERSION("1.0");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/regulator/stw481x-vmmc.c b/drivers/regulator/stw481x-vmmc.c
index a7e1526..89025f5 100644
--- a/drivers/regulator/stw481x-vmmc.c
+++ b/drivers/regulator/stw481x-vmmc.c
@@ -72,7 +72,8 @@ static int stw481x_vmmc_regulator_probe(struct platform_device *pdev)
config.regmap = stw481x->map;
config.of_node = pdev->dev.of_node;
config.init_data = of_get_regulator_init_data(&pdev->dev,
- pdev->dev.of_node);
+ pdev->dev.of_node,
+ &vmmc_regulator);
stw481x->vmmc_regulator = devm_regulator_register(&pdev->dev,
&vmmc_regulator, &config);
@@ -94,7 +95,6 @@ static const struct of_device_id stw481x_vmmc_match[] = {
static struct platform_driver stw481x_vmmc_regulator_driver = {
.driver = {
.name = "stw481x-vmmc-regulator",
- .owner = THIS_MODULE,
.of_match_table = stw481x_vmmc_match,
},
.probe = stw481x_vmmc_regulator_probe,
diff --git a/drivers/regulator/ti-abb-regulator.c b/drivers/regulator/ti-abb-regulator.c
index a2dabb5..d2f9942 100644
--- a/drivers/regulator/ti-abb-regulator.c
+++ b/drivers/regulator/ti-abb-regulator.c
@@ -837,7 +837,8 @@ skip_opt:
return -EINVAL;
}
- initdata = of_get_regulator_init_data(dev, pdev->dev.of_node);
+ initdata = of_get_regulator_init_data(dev, pdev->dev.of_node,
+ &abb->rdesc);
if (!initdata) {
dev_err(dev, "%s: Unable to alloc regulator init data\n",
__func__);
@@ -891,7 +892,6 @@ static struct platform_driver ti_abb_driver = {
.probe = ti_abb_probe,
.driver = {
.name = "ti_abb",
- .owner = THIS_MODULE,
.of_match_table = of_match_ptr(ti_abb_of_match),
},
};
diff --git a/drivers/regulator/tps51632-regulator.c b/drivers/regulator/tps51632-regulator.c
index f31f22e..c213e37 100644
--- a/drivers/regulator/tps51632-regulator.c
+++ b/drivers/regulator/tps51632-regulator.c
@@ -221,7 +221,8 @@ static const struct of_device_id tps51632_of_match[] = {
MODULE_DEVICE_TABLE(of, tps51632_of_match);
static struct tps51632_regulator_platform_data *
- of_get_tps51632_platform_data(struct device *dev)
+ of_get_tps51632_platform_data(struct device *dev,
+ const struct regulator_desc *desc)
{
struct tps51632_regulator_platform_data *pdata;
struct device_node *np = dev->of_node;
@@ -230,7 +231,8 @@ static struct tps51632_regulator_platform_data *
if (!pdata)
return NULL;
- pdata->reg_init_data = of_get_regulator_init_data(dev, dev->of_node);
+ pdata->reg_init_data = of_get_regulator_init_data(dev, dev->of_node,
+ desc);
if (!pdata->reg_init_data) {
dev_err(dev, "Not able to get OF regulator init data\n");
return NULL;
@@ -248,7 +250,8 @@ static struct tps51632_regulator_platform_data *
}
#else
static struct tps51632_regulator_platform_data *
- of_get_tps51632_platform_data(struct device *dev)
+ of_get_tps51632_platform_data(struct device *dev,
+ const struct regulator_desc *desc)
{
return NULL;
}
@@ -273,9 +276,25 @@ static int tps51632_probe(struct i2c_client *client,
}
}
+ tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL);
+ if (!tps)
+ return -ENOMEM;
+
+ tps->dev = &client->dev;
+ tps->desc.name = client->name;
+ tps->desc.id = 0;
+ tps->desc.ramp_delay = TPS51632_DEFAULT_RAMP_DELAY;
+ tps->desc.min_uV = TPS51632_MIN_VOLTAGE;
+ tps->desc.uV_step = TPS51632_VOLTAGE_STEP_10mV;
+ tps->desc.linear_min_sel = TPS51632_MIN_VSEL;
+ tps->desc.n_voltages = TPS51632_MAX_VSEL + 1;
+ tps->desc.ops = &tps51632_dcdc_ops;
+ tps->desc.type = REGULATOR_VOLTAGE;
+ tps->desc.owner = THIS_MODULE;
+
pdata = dev_get_platdata(&client->dev);
if (!pdata && client->dev.of_node)
- pdata = of_get_tps51632_platform_data(&client->dev);
+ pdata = of_get_tps51632_platform_data(&client->dev, &tps->desc);
if (!pdata) {
dev_err(&client->dev, "No Platform data\n");
return -EINVAL;
@@ -296,22 +315,6 @@ static int tps51632_probe(struct i2c_client *client,
}
}
- tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL);
- if (!tps)
- return -ENOMEM;
-
- tps->dev = &client->dev;
- tps->desc.name = client->name;
- tps->desc.id = 0;
- tps->desc.ramp_delay = TPS51632_DEFAULT_RAMP_DELAY;
- tps->desc.min_uV = TPS51632_MIN_VOLTAGE;
- tps->desc.uV_step = TPS51632_VOLTAGE_STEP_10mV;
- tps->desc.linear_min_sel = TPS51632_MIN_VSEL;
- tps->desc.n_voltages = TPS51632_MAX_VSEL + 1;
- tps->desc.ops = &tps51632_dcdc_ops;
- tps->desc.type = REGULATOR_VOLTAGE;
- tps->desc.owner = THIS_MODULE;
-
if (pdata->enable_pwm_dvfs)
tps->desc.vsel_reg = TPS51632_VOLTAGE_BASE_REG;
else
diff --git a/drivers/regulator/tps6105x-regulator.c b/drivers/regulator/tps6105x-regulator.c
index c1e33a3..3510b3e 100644
--- a/drivers/regulator/tps6105x-regulator.c
+++ b/drivers/regulator/tps6105x-regulator.c
@@ -163,7 +163,6 @@ static int tps6105x_regulator_probe(struct platform_device *pdev)
static struct platform_driver tps6105x_regulator_driver = {
.driver = {
.name = "tps6105x-regulator",
- .owner = THIS_MODULE,
},
.probe = tps6105x_regulator_probe,
};
diff --git a/drivers/regulator/tps62360-regulator.c b/drivers/regulator/tps62360-regulator.c
index a167204..a1fd626 100644
--- a/drivers/regulator/tps62360-regulator.c
+++ b/drivers/regulator/tps62360-regulator.c
@@ -293,7 +293,8 @@ static const struct regmap_config tps62360_regmap_config = {
};
static struct tps62360_regulator_platform_data *
- of_get_tps62360_platform_data(struct device *dev)
+ of_get_tps62360_platform_data(struct device *dev,
+ const struct regulator_desc *desc)
{
struct tps62360_regulator_platform_data *pdata;
struct device_node *np = dev->of_node;
@@ -302,7 +303,8 @@ static struct tps62360_regulator_platform_data *
if (!pdata)
return NULL;
- pdata->reg_init_data = of_get_regulator_init_data(dev, dev->of_node);
+ pdata->reg_init_data = of_get_regulator_init_data(dev, dev->of_node,
+ desc);
if (!pdata->reg_init_data) {
dev_err(dev, "Not able to get OF regulator init data\n");
return NULL;
@@ -350,6 +352,17 @@ static int tps62360_probe(struct i2c_client *client,
pdata = dev_get_platdata(&client->dev);
+ tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL);
+ if (!tps)
+ return -ENOMEM;
+
+ tps->desc.name = client->name;
+ tps->desc.id = 0;
+ tps->desc.ops = &tps62360_dcdc_ops;
+ tps->desc.type = REGULATOR_VOLTAGE;
+ tps->desc.owner = THIS_MODULE;
+ tps->desc.uV_step = 10000;
+
if (client->dev.of_node) {
const struct of_device_id *match;
match = of_match_device(of_match_ptr(tps62360_of_match),
@@ -360,7 +373,8 @@ static int tps62360_probe(struct i2c_client *client,
}
chip_id = (int)(long)match->data;
if (!pdata)
- pdata = of_get_tps62360_platform_data(&client->dev);
+ pdata = of_get_tps62360_platform_data(&client->dev,
+ &tps->desc);
} else if (id) {
chip_id = id->driver_data;
} else {
@@ -374,10 +388,6 @@ static int tps62360_probe(struct i2c_client *client,
return -EIO;
}
- tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL);
- if (!tps)
- return -ENOMEM;
-
tps->en_discharge = pdata->en_discharge;
tps->en_internal_pulldn = pdata->en_internal_pulldn;
tps->vsel0_gpio = pdata->vsel0_gpio;
@@ -401,13 +411,6 @@ static int tps62360_probe(struct i2c_client *client,
return -ENODEV;
}
- tps->desc.name = client->name;
- tps->desc.id = 0;
- tps->desc.ops = &tps62360_dcdc_ops;
- tps->desc.type = REGULATOR_VOLTAGE;
- tps->desc.owner = THIS_MODULE;
- tps->desc.uV_step = 10000;
-
tps->regmap = devm_regmap_init_i2c(client, &tps62360_regmap_config);
if (IS_ERR(tps->regmap)) {
ret = PTR_ERR(tps->regmap);
diff --git a/drivers/regulator/tps65023-regulator.c b/drivers/regulator/tps65023-regulator.c
index 7380af8..b941e56 100644
--- a/drivers/regulator/tps65023-regulator.c
+++ b/drivers/regulator/tps65023-regulator.c
@@ -173,7 +173,7 @@ static int tps65023_dcdc_set_voltage_sel(struct regulator_dev *dev,
}
/* Operations permitted on VDCDCx */
-static struct regulator_ops tps65023_dcdc_ops = {
+static const struct regulator_ops tps65023_dcdc_ops = {
.is_enabled = regulator_is_enabled_regmap,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
@@ -184,7 +184,7 @@ static struct regulator_ops tps65023_dcdc_ops = {
};
/* Operations permitted on LDOx */
-static struct regulator_ops tps65023_ldo_ops = {
+static const struct regulator_ops tps65023_ldo_ops = {
.is_enabled = regulator_is_enabled_regmap,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
@@ -194,7 +194,7 @@ static struct regulator_ops tps65023_ldo_ops = {
.map_voltage = regulator_map_voltage_ascend,
};
-static struct regmap_config tps65023_regmap_config = {
+static const struct regmap_config tps65023_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
};
diff --git a/drivers/regulator/tps6507x-regulator.c b/drivers/regulator/tps6507x-regulator.c
index 98e66ce..dad0bac 100644
--- a/drivers/regulator/tps6507x-regulator.c
+++ b/drivers/regulator/tps6507x-regulator.c
@@ -519,7 +519,6 @@ static int tps6507x_pmic_probe(struct platform_device *pdev)
static struct platform_driver tps6507x_pmic_driver = {
.driver = {
.name = "tps6507x-pmic",
- .owner = THIS_MODULE,
},
.probe = tps6507x_pmic_probe,
};
diff --git a/drivers/regulator/tps65090-regulator.c b/drivers/regulator/tps65090-regulator.c
index d5df1e9..395f35d 100644
--- a/drivers/regulator/tps65090-regulator.c
+++ b/drivers/regulator/tps65090-regulator.c
@@ -312,7 +312,11 @@ static void tps65090_configure_regulator_config(
gpio_flag = GPIOF_OUT_INIT_HIGH;
config->ena_gpio = tps_pdata->gpio;
+ config->ena_gpio_initialized = true;
config->ena_gpio_flags = gpio_flag;
+ } else {
+ config->ena_gpio = -EINVAL;
+ config->ena_gpio_initialized = false;
}
}
@@ -507,7 +511,6 @@ static int tps65090_regulator_probe(struct platform_device *pdev)
static struct platform_driver tps65090_regulator_driver = {
.driver = {
.name = "tps65090-pmic",
- .owner = THIS_MODULE,
},
.probe = tps65090_regulator_probe,
};
diff --git a/drivers/regulator/tps65218-regulator.c b/drivers/regulator/tps65218-regulator.c
index f0a4028..7f97223 100644
--- a/drivers/regulator/tps65218-regulator.c
+++ b/drivers/regulator/tps65218-regulator.c
@@ -231,7 +231,8 @@ static int tps65218_regulator_probe(struct platform_device *pdev)
template = match->data;
id = template->id;
- init_data = of_get_regulator_init_data(&pdev->dev, pdev->dev.of_node);
+ init_data = of_get_regulator_init_data(&pdev->dev, pdev->dev.of_node,
+ &regulators[id]);
platform_set_drvdata(pdev, tps);
@@ -255,7 +256,6 @@ static int tps65218_regulator_probe(struct platform_device *pdev)
static struct platform_driver tps65218_regulator_driver = {
.driver = {
.name = "tps65218-pmic",
- .owner = THIS_MODULE,
.of_match_table = tps65218_of_match,
},
.probe = tps65218_regulator_probe,
diff --git a/drivers/regulator/tps6586x-regulator.c b/drivers/regulator/tps6586x-regulator.c
index ccbb9f1..2852de0 100644
--- a/drivers/regulator/tps6586x-regulator.c
+++ b/drivers/regulator/tps6586x-regulator.c
@@ -522,7 +522,6 @@ static int tps6586x_regulator_probe(struct platform_device *pdev)
static struct platform_driver tps6586x_regulator_driver = {
.driver = {
.name = "tps6586x-regulator",
- .owner = THIS_MODULE,
},
.probe = tps6586x_regulator_probe,
};
diff --git a/drivers/regulator/tps65910-regulator.c b/drivers/regulator/tps65910-regulator.c
index 18fc991..e2cffe0 100644
--- a/drivers/regulator/tps65910-regulator.c
+++ b/drivers/regulator/tps65910-regulator.c
@@ -1245,7 +1245,6 @@ static void tps65910_shutdown(struct platform_device *pdev)
static struct platform_driver tps65910_driver = {
.driver = {
.name = "tps65910-pmic",
- .owner = THIS_MODULE,
},
.probe = tps65910_probe,
.shutdown = tps65910_shutdown,
diff --git a/drivers/regulator/tps65912-regulator.c b/drivers/regulator/tps65912-regulator.c
index 9cafaa0..9503d54 100644
--- a/drivers/regulator/tps65912-regulator.c
+++ b/drivers/regulator/tps65912-regulator.c
@@ -519,7 +519,6 @@ static int tps65912_probe(struct platform_device *pdev)
static struct platform_driver tps65912_driver = {
.driver = {
.name = "tps65912-pmic",
- .owner = THIS_MODULE,
},
.probe = tps65912_probe,
};
diff --git a/drivers/regulator/tps80031-regulator.c b/drivers/regulator/tps80031-regulator.c
index 26aa6d9..d4cc60a 100644
--- a/drivers/regulator/tps80031-regulator.c
+++ b/drivers/regulator/tps80031-regulator.c
@@ -746,7 +746,6 @@ static int tps80031_regulator_probe(struct platform_device *pdev)
static struct platform_driver tps80031_regulator_driver = {
.driver = {
.name = "tps80031-pmic",
- .owner = THIS_MODULE,
},
.probe = tps80031_regulator_probe,
};
diff --git a/drivers/regulator/twl-regulator.c b/drivers/regulator/twl-regulator.c
index 0b4f866..955a6fb 100644
--- a/drivers/regulator/twl-regulator.c
+++ b/drivers/regulator/twl-regulator.c
@@ -1104,7 +1104,8 @@ static int twlreg_probe(struct platform_device *pdev)
template = match->data;
id = template->desc.id;
initdata = of_get_regulator_init_data(&pdev->dev,
- pdev->dev.of_node);
+ pdev->dev.of_node,
+ &template->desc);
drvdata = NULL;
} else {
id = pdev->id;
@@ -1220,7 +1221,6 @@ static struct platform_driver twlreg_driver = {
*/
.driver = {
.name = "twl_reg",
- .owner = THIS_MODULE,
.of_match_table = of_match_ptr(twl_of_match),
},
};
diff --git a/drivers/regulator/vexpress.c b/drivers/regulator/vexpress.c
index 02e7267..bed9d3e 100644
--- a/drivers/regulator/vexpress.c
+++ b/drivers/regulator/vexpress.c
@@ -74,7 +74,8 @@ static int vexpress_regulator_probe(struct platform_device *pdev)
reg->desc.owner = THIS_MODULE;
reg->desc.continuous_voltage_range = true;
- init_data = of_get_regulator_init_data(&pdev->dev, pdev->dev.of_node);
+ init_data = of_get_regulator_init_data(&pdev->dev, pdev->dev.of_node,
+ &reg->desc);
if (!init_data)
return -EINVAL;
@@ -107,7 +108,6 @@ static struct platform_driver vexpress_regulator_driver = {
.probe = vexpress_regulator_probe,
.driver = {
.name = DRVNAME,
- .owner = THIS_MODULE,
.of_match_table = vexpress_regulator_of_match,
},
};
diff --git a/drivers/regulator/virtual.c b/drivers/regulator/virtual.c
index 6ff95b0..a6f1c7a 100644
--- a/drivers/regulator/virtual.c
+++ b/drivers/regulator/virtual.c
@@ -338,7 +338,6 @@ static struct platform_driver regulator_virtual_consumer_driver = {
.remove = regulator_virtual_remove,
.driver = {
.name = "reg-virt-consumer",
- .owner = THIS_MODULE,
},
};
diff --git a/drivers/regulator/wm831x-dcdc.c b/drivers/regulator/wm831x-dcdc.c
index 0d88a82..0d7e164 100644
--- a/drivers/regulator/wm831x-dcdc.c
+++ b/drivers/regulator/wm831x-dcdc.c
@@ -562,7 +562,6 @@ static struct platform_driver wm831x_buckv_driver = {
.probe = wm831x_buckv_probe,
.driver = {
.name = "wm831x-buckv",
- .owner = THIS_MODULE,
},
};
@@ -689,7 +688,6 @@ static struct platform_driver wm831x_buckp_driver = {
.probe = wm831x_buckp_probe,
.driver = {
.name = "wm831x-buckp",
- .owner = THIS_MODULE,
},
};
@@ -804,7 +802,6 @@ static struct platform_driver wm831x_boostp_driver = {
.probe = wm831x_boostp_probe,
.driver = {
.name = "wm831x-boostp",
- .owner = THIS_MODULE,
},
};
@@ -880,7 +877,6 @@ static struct platform_driver wm831x_epe_driver = {
.probe = wm831x_epe_probe,
.driver = {
.name = "wm831x-epe",
- .owner = THIS_MODULE,
},
};
diff --git a/drivers/regulator/wm831x-isink.c b/drivers/regulator/wm831x-isink.c
index 72e385e..1e88391 100644
--- a/drivers/regulator/wm831x-isink.c
+++ b/drivers/regulator/wm831x-isink.c
@@ -224,7 +224,6 @@ static struct platform_driver wm831x_isink_driver = {
.probe = wm831x_isink_probe,
.driver = {
.name = "wm831x-isink",
- .owner = THIS_MODULE,
},
};
diff --git a/drivers/regulator/wm831x-ldo.c b/drivers/regulator/wm831x-ldo.c
index eca0eeb..7ae2dc8 100644
--- a/drivers/regulator/wm831x-ldo.c
+++ b/drivers/regulator/wm831x-ldo.c
@@ -307,7 +307,6 @@ static struct platform_driver wm831x_gp_ldo_driver = {
.probe = wm831x_gp_ldo_probe,
.driver = {
.name = "wm831x-ldo",
- .owner = THIS_MODULE,
},
};
@@ -516,7 +515,6 @@ static struct platform_driver wm831x_aldo_driver = {
.probe = wm831x_aldo_probe,
.driver = {
.name = "wm831x-aldo",
- .owner = THIS_MODULE,
},
};
@@ -650,7 +648,6 @@ static struct platform_driver wm831x_alive_ldo_driver = {
.probe = wm831x_alive_ldo_probe,
.driver = {
.name = "wm831x-alive-ldo",
- .owner = THIS_MODULE,
},
};
diff --git a/drivers/regulator/wm8994-regulator.c b/drivers/regulator/wm8994-regulator.c
index c24346d..750e0bd 100644
--- a/drivers/regulator/wm8994-regulator.c
+++ b/drivers/regulator/wm8994-regulator.c
@@ -145,10 +145,12 @@ static int wm8994_ldo_probe(struct platform_device *pdev)
config.driver_data = ldo;
config.regmap = wm8994->regmap;
config.init_data = &ldo->init_data;
- if (pdata)
+ if (pdata) {
config.ena_gpio = pdata->ldo[id].enable;
- else if (wm8994->dev->of_node)
+ } else if (wm8994->dev->of_node) {
config.ena_gpio = wm8994->pdata.ldo[id].enable;
+ config.ena_gpio_initialized = true;
+ }
/* Use default constraints if none set up */
if (!pdata || !pdata->ldo[id].init_data || wm8994->dev->of_node) {
@@ -185,7 +187,6 @@ static struct platform_driver wm8994_ldo_driver = {
.probe = wm8994_ldo_probe,
.driver = {
.name = "wm8994-ldo",
- .owner = THIS_MODULE,
},
};
OpenPOWER on IntegriCloud