Skip to content

Commit cf1ba3b

Browse files
committed
Merge remote-tracking branches 'regulator/topic/doc' and 'regulator/topic/sc2731' into regulator-next
3 parents 2755646 + 983ba99 + fa32f7a commit cf1ba3b

File tree

6 files changed

+324
-20
lines changed

6 files changed

+324
-20
lines changed
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
Spreadtrum SC2731 Voltage regulators
2+
3+
The SC2731 integrates low-voltage and low quiescent current DCDC/LDO.
4+
14 LDO and 3 DCDCs are designed for external use. All DCDCs/LDOs have
5+
their own bypass (power-down) control signals. External tantalum or MLCC
6+
ceramic capacitors are recommended to use with these LDOs.
7+
8+
Required properties:
9+
- compatible: should be "sprd,sc27xx-regulator".
10+
11+
List of regulators provided by this controller. It is named according to
12+
its regulator type, BUCK_<name> and LDO_<name>. The definition for each
13+
of these nodes is defined using the standard binding for regulators at
14+
Documentation/devicetree/bindings/regulator/regulator.txt.
15+
16+
The valid names for regulators are:
17+
BUCK:
18+
BUCK_CPU0, BUCK_CPU1, BUCK_RF
19+
LDO:
20+
LDO_CAMA0, LDO_CAMA1, LDO_CAMMOT, LDO_VLDO, LDO_EMMCCORE, LDO_SDCORE,
21+
LDO_SDIO, LDO_WIFIPA, LDO_USB33, LDO_CAMD0, LDO_CAMD1, LDO_CON,
22+
LDO_CAMIO, LDO_SRAM
23+
24+
Example:
25+
regulators {
26+
compatible = "sprd,sc27xx-regulator";
27+
28+
vddarm0: BUCK_CPU0 {
29+
regulator-name = "vddarm0";
30+
regulator-min-microvolt = <400000>;
31+
regulator-max-microvolt = <1996875>;
32+
regulator-ramp-delay = <25000>;
33+
regulator-always-on;
34+
};
35+
36+
vddcama0: LDO_CAMA0 {
37+
regulator-name = "vddcama0";
38+
regulator-min-microvolt = <1200000>;
39+
regulator-max-microvolt = <3750000>;
40+
regulator-enable-ramp-delay = <100>;
41+
};
42+
...
43+
};

Documentation/power/regulator/machine.txt

Lines changed: 16 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,12 @@ struct regulator_consumer_supply {
2323
e.g. for the machine above
2424

2525
static struct regulator_consumer_supply regulator1_consumers[] = {
26-
{
27-
.dev_name = "dev_name(consumer B)",
28-
.supply = "Vcc",
29-
},};
26+
REGULATOR_SUPPLY("Vcc", "consumer B"),
27+
};
3028

3129
static struct regulator_consumer_supply regulator2_consumers[] = {
32-
{
33-
.dev = "dev_name(consumer A"),
34-
.supply = "Vcc",
35-
},};
30+
REGULATOR_SUPPLY("Vcc", "consumer A"),
31+
};
3632

3733
This maps Regulator-1 to the 'Vcc' supply for Consumer B and maps Regulator-2
3834
to the 'Vcc' supply for Consumer A.
@@ -78,20 +74,20 @@ static struct regulator_init_data regulator2_data = {
7874
Finally the regulator devices must be registered in the usual manner.
7975

8076
static struct platform_device regulator_devices[] = {
81-
{
82-
.name = "regulator",
83-
.id = DCDC_1,
84-
.dev = {
85-
.platform_data = &regulator1_data,
77+
{
78+
.name = "regulator",
79+
.id = DCDC_1,
80+
.dev = {
81+
.platform_data = &regulator1_data,
82+
},
8683
},
87-
},
88-
{
89-
.name = "regulator",
90-
.id = DCDC_2,
91-
.dev = {
92-
.platform_data = &regulator2_data,
84+
{
85+
.name = "regulator",
86+
.id = DCDC_2,
87+
.dev = {
88+
.platform_data = &regulator2_data,
89+
},
9390
},
94-
},
9591
};
9692
/* register regulator 1 device */
9793
platform_device_register(&regulator_devices[0]);

MAINTAINERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14648,6 +14648,7 @@ W: http://www.slimlogic.co.uk/?p=48
1464814648
T: git git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator.git
1464914649
S: Supported
1465014650
F: Documentation/devicetree/bindings/regulator/
14651+
F: Documentation/power/regulator/
1465114652
F: drivers/regulator/
1465214653
F: include/dt-bindings/regulator/
1465314654
F: include/linux/regulator/

drivers/regulator/Kconfig

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -744,6 +744,13 @@ config REGULATOR_S5M8767
744744
via I2C bus. S5M8767A have 9 Bucks and 28 LDOs output and
745745
supports DVS mode with 8bits of output voltage control.
746746

747+
config REGULATOR_SC2731
748+
tristate "Spreadtrum SC2731 power regulator driver"
749+
depends on MFD_SC27XX_PMIC || COMPILE_TEST
750+
help
751+
This driver provides support for the voltage regulators on the
752+
SC2731 PMIC.
753+
747754
config REGULATOR_SKY81452
748755
tristate "Skyworks Solutions SKY81452 voltage regulator"
749756
depends on MFD_SKY81452

drivers/regulator/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ obj-$(CONFIG_REGULATOR_RT5033) += rt5033-regulator.o
9595
obj-$(CONFIG_REGULATOR_S2MPA01) += s2mpa01.o
9696
obj-$(CONFIG_REGULATOR_S2MPS11) += s2mps11.o
9797
obj-$(CONFIG_REGULATOR_S5M8767) += s5m8767.o
98+
obj-$(CONFIG_REGULATOR_SC2731) += sc2731-regulator.o
9899
obj-$(CONFIG_REGULATOR_SKY81452) += sky81452-regulator.o
99100
obj-$(CONFIG_REGULATOR_STM32_VREFBUF) += stm32-vrefbuf.o
100101
obj-$(CONFIG_REGULATOR_STW481X_VMMC) += stw481x-vmmc.o

drivers/regulator/sc2731-regulator.c

Lines changed: 256 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,256 @@
1+
//SPDX-License-Identifier: GPL-2.0
2+
/*
3+
* Copyright (C) 2017 Spreadtrum Communications Inc.
4+
*/
5+
6+
#include <linux/module.h>
7+
#include <linux/of.h>
8+
#include <linux/platform_device.h>
9+
#include <linux/regmap.h>
10+
#include <linux/regulator/driver.h>
11+
#include <linux/regulator/of_regulator.h>
12+
13+
/*
14+
* SC2731 regulator lock register
15+
*/
16+
#define SC2731_PWR_WR_PROT 0xf0c
17+
#define SC2731_WR_UNLOCK_VALUE 0x6e7f
18+
19+
/*
20+
* SC2731 enable register
21+
*/
22+
#define SC2731_POWER_PD_SW 0xc28
23+
#define SC2731_LDO_CAMA0_PD 0xcfc
24+
#define SC2731_LDO_CAMA1_PD 0xd04
25+
#define SC2731_LDO_CAMMOT_PD 0xd0c
26+
#define SC2731_LDO_VLDO_PD 0xd6c
27+
#define SC2731_LDO_EMMCCORE_PD 0xd2c
28+
#define SC2731_LDO_SDCORE_PD 0xd74
29+
#define SC2731_LDO_SDIO_PD 0xd70
30+
#define SC2731_LDO_WIFIPA_PD 0xd4c
31+
#define SC2731_LDO_USB33_PD 0xd5c
32+
#define SC2731_LDO_CAMD0_PD 0xd7c
33+
#define SC2731_LDO_CAMD1_PD 0xd84
34+
#define SC2731_LDO_CON_PD 0xd8c
35+
#define SC2731_LDO_CAMIO_PD 0xd94
36+
#define SC2731_LDO_SRAM_PD 0xd78
37+
38+
/*
39+
* SC2731 enable mask
40+
*/
41+
#define SC2731_DCDC_CPU0_PD_MASK BIT(4)
42+
#define SC2731_DCDC_CPU1_PD_MASK BIT(3)
43+
#define SC2731_DCDC_RF_PD_MASK BIT(11)
44+
#define SC2731_LDO_CAMA0_PD_MASK BIT(0)
45+
#define SC2731_LDO_CAMA1_PD_MASK BIT(0)
46+
#define SC2731_LDO_CAMMOT_PD_MASK BIT(0)
47+
#define SC2731_LDO_VLDO_PD_MASK BIT(0)
48+
#define SC2731_LDO_EMMCCORE_PD_MASK BIT(0)
49+
#define SC2731_LDO_SDCORE_PD_MASK BIT(0)
50+
#define SC2731_LDO_SDIO_PD_MASK BIT(0)
51+
#define SC2731_LDO_WIFIPA_PD_MASK BIT(0)
52+
#define SC2731_LDO_USB33_PD_MASK BIT(0)
53+
#define SC2731_LDO_CAMD0_PD_MASK BIT(0)
54+
#define SC2731_LDO_CAMD1_PD_MASK BIT(0)
55+
#define SC2731_LDO_CON_PD_MASK BIT(0)
56+
#define SC2731_LDO_CAMIO_PD_MASK BIT(0)
57+
#define SC2731_LDO_SRAM_PD_MASK BIT(0)
58+
59+
/*
60+
* SC2731 vsel register
61+
*/
62+
#define SC2731_DCDC_CPU0_VOL 0xc54
63+
#define SC2731_DCDC_CPU1_VOL 0xc64
64+
#define SC2731_DCDC_RF_VOL 0xcb8
65+
#define SC2731_LDO_CAMA0_VOL 0xd00
66+
#define SC2731_LDO_CAMA1_VOL 0xd08
67+
#define SC2731_LDO_CAMMOT_VOL 0xd10
68+
#define SC2731_LDO_VLDO_VOL 0xd28
69+
#define SC2731_LDO_EMMCCORE_VOL 0xd30
70+
#define SC2731_LDO_SDCORE_VOL 0xd38
71+
#define SC2731_LDO_SDIO_VOL 0xd40
72+
#define SC2731_LDO_WIFIPA_VOL 0xd50
73+
#define SC2731_LDO_USB33_VOL 0xd60
74+
#define SC2731_LDO_CAMD0_VOL 0xd80
75+
#define SC2731_LDO_CAMD1_VOL 0xd88
76+
#define SC2731_LDO_CON_VOL 0xd90
77+
#define SC2731_LDO_CAMIO_VOL 0xd98
78+
#define SC2731_LDO_SRAM_VOL 0xdB0
79+
80+
/*
81+
* SC2731 vsel register mask
82+
*/
83+
#define SC2731_DCDC_CPU0_VOL_MASK GENMASK(8, 0)
84+
#define SC2731_DCDC_CPU1_VOL_MASK GENMASK(8, 0)
85+
#define SC2731_DCDC_RF_VOL_MASK GENMASK(8, 0)
86+
#define SC2731_LDO_CAMA0_VOL_MASK GENMASK(7, 0)
87+
#define SC2731_LDO_CAMA1_VOL_MASK GENMASK(7, 0)
88+
#define SC2731_LDO_CAMMOT_VOL_MASK GENMASK(7, 0)
89+
#define SC2731_LDO_VLDO_VOL_MASK GENMASK(7, 0)
90+
#define SC2731_LDO_EMMCCORE_VOL_MASK GENMASK(7, 0)
91+
#define SC2731_LDO_SDCORE_VOL_MASK GENMASK(7, 0)
92+
#define SC2731_LDO_SDIO_VOL_MASK GENMASK(7, 0)
93+
#define SC2731_LDO_WIFIPA_VOL_MASK GENMASK(7, 0)
94+
#define SC2731_LDO_USB33_VOL_MASK GENMASK(7, 0)
95+
#define SC2731_LDO_CAMD0_VOL_MASK GENMASK(6, 0)
96+
#define SC2731_LDO_CAMD1_VOL_MASK GENMASK(6, 0)
97+
#define SC2731_LDO_CON_VOL_MASK GENMASK(6, 0)
98+
#define SC2731_LDO_CAMIO_VOL_MASK GENMASK(6, 0)
99+
#define SC2731_LDO_SRAM_VOL_MASK GENMASK(6, 0)
100+
101+
enum sc2731_regulator_id {
102+
SC2731_BUCK_CPU0,
103+
SC2731_BUCK_CPU1,
104+
SC2731_BUCK_RF,
105+
SC2731_LDO_CAMA0,
106+
SC2731_LDO_CAMA1,
107+
SC2731_LDO_CAMMOT,
108+
SC2731_LDO_VLDO,
109+
SC2731_LDO_EMMCCORE,
110+
SC2731_LDO_SDCORE,
111+
SC2731_LDO_SDIO,
112+
SC2731_LDO_WIFIPA,
113+
SC2731_LDO_USB33,
114+
SC2731_LDO_CAMD0,
115+
SC2731_LDO_CAMD1,
116+
SC2731_LDO_CON,
117+
SC2731_LDO_CAMIO,
118+
SC2731_LDO_SRAM,
119+
};
120+
121+
static const struct regulator_ops sc2731_regu_linear_ops = {
122+
.enable = regulator_enable_regmap,
123+
.disable = regulator_disable_regmap,
124+
.is_enabled = regulator_is_enabled_regmap,
125+
.list_voltage = regulator_list_voltage_linear,
126+
.get_voltage_sel = regulator_get_voltage_sel_regmap,
127+
.set_voltage_sel = regulator_set_voltage_sel_regmap,
128+
};
129+
130+
#define SC2731_REGU_LINEAR(_id, en_reg, en_mask, vreg, vmask, \
131+
vstep, vmin, vmax) { \
132+
.name = #_id, \
133+
.of_match = of_match_ptr(#_id), \
134+
.ops = &sc2731_regu_linear_ops, \
135+
.type = REGULATOR_VOLTAGE, \
136+
.id = SC2731_##_id, \
137+
.owner = THIS_MODULE, \
138+
.min_uV = vmin, \
139+
.n_voltages = ((vmax) - (vmin)) / (vstep) + 1, \
140+
.uV_step = vstep, \
141+
.enable_is_inverted = true, \
142+
.enable_val = 0, \
143+
.enable_reg = en_reg, \
144+
.enable_mask = en_mask, \
145+
.vsel_reg = vreg, \
146+
.vsel_mask = vmask, \
147+
}
148+
149+
static struct regulator_desc regulators[] = {
150+
SC2731_REGU_LINEAR(BUCK_CPU0, SC2731_POWER_PD_SW,
151+
SC2731_DCDC_CPU0_PD_MASK, SC2731_DCDC_CPU0_VOL,
152+
SC2731_DCDC_CPU0_VOL_MASK, 3125, 400000, 1996875),
153+
SC2731_REGU_LINEAR(BUCK_CPU1, SC2731_POWER_PD_SW,
154+
SC2731_DCDC_CPU1_PD_MASK, SC2731_DCDC_CPU1_VOL,
155+
SC2731_DCDC_CPU1_VOL_MASK, 3125, 400000, 1996875),
156+
SC2731_REGU_LINEAR(BUCK_RF, SC2731_POWER_PD_SW, SC2731_DCDC_RF_PD_MASK,
157+
SC2731_DCDC_RF_VOL, SC2731_DCDC_RF_VOL_MASK,
158+
3125, 600000, 2196875),
159+
SC2731_REGU_LINEAR(LDO_CAMA0, SC2731_LDO_CAMA0_PD,
160+
SC2731_LDO_CAMA0_PD_MASK, SC2731_LDO_CAMA0_VOL,
161+
SC2731_LDO_CAMA0_VOL_MASK, 10000, 1200000, 3750000),
162+
SC2731_REGU_LINEAR(LDO_CAMA1, SC2731_LDO_CAMA1_PD,
163+
SC2731_LDO_CAMA1_PD_MASK, SC2731_LDO_CAMA1_VOL,
164+
SC2731_LDO_CAMA1_VOL_MASK, 10000, 1200000, 3750000),
165+
SC2731_REGU_LINEAR(LDO_CAMMOT, SC2731_LDO_CAMMOT_PD,
166+
SC2731_LDO_CAMMOT_PD_MASK, SC2731_LDO_CAMMOT_VOL,
167+
SC2731_LDO_CAMMOT_VOL_MASK, 10000, 1200000, 3750000),
168+
SC2731_REGU_LINEAR(LDO_VLDO, SC2731_LDO_VLDO_PD,
169+
SC2731_LDO_VLDO_PD_MASK, SC2731_LDO_VLDO_VOL,
170+
SC2731_LDO_VLDO_VOL_MASK, 10000, 1200000, 3750000),
171+
SC2731_REGU_LINEAR(LDO_EMMCCORE, SC2731_LDO_EMMCCORE_PD,
172+
SC2731_LDO_EMMCCORE_PD_MASK, SC2731_LDO_EMMCCORE_VOL,
173+
SC2731_LDO_EMMCCORE_VOL_MASK, 10000, 1200000,
174+
3750000),
175+
SC2731_REGU_LINEAR(LDO_SDCORE, SC2731_LDO_SDCORE_PD,
176+
SC2731_LDO_SDCORE_PD_MASK, SC2731_LDO_SDCORE_VOL,
177+
SC2731_LDO_SDCORE_VOL_MASK, 10000, 1200000, 3750000),
178+
SC2731_REGU_LINEAR(LDO_SDIO, SC2731_LDO_SDIO_PD,
179+
SC2731_LDO_SDIO_PD_MASK, SC2731_LDO_SDIO_VOL,
180+
SC2731_LDO_SDIO_VOL_MASK, 10000, 1200000, 3750000),
181+
SC2731_REGU_LINEAR(LDO_WIFIPA, SC2731_LDO_WIFIPA_PD,
182+
SC2731_LDO_WIFIPA_PD_MASK, SC2731_LDO_WIFIPA_VOL,
183+
SC2731_LDO_WIFIPA_VOL_MASK, 10000, 1200000, 3750000),
184+
SC2731_REGU_LINEAR(LDO_USB33, SC2731_LDO_USB33_PD,
185+
SC2731_LDO_USB33_PD_MASK, SC2731_LDO_USB33_VOL,
186+
SC2731_LDO_USB33_VOL_MASK, 10000, 1200000, 3750000),
187+
SC2731_REGU_LINEAR(LDO_CAMD0, SC2731_LDO_CAMD0_PD,
188+
SC2731_LDO_CAMD0_PD_MASK, SC2731_LDO_CAMD0_VOL,
189+
SC2731_LDO_CAMD0_VOL_MASK, 6250, 1000000, 1793750),
190+
SC2731_REGU_LINEAR(LDO_CAMD1, SC2731_LDO_CAMD1_PD,
191+
SC2731_LDO_CAMD1_PD_MASK, SC2731_LDO_CAMD1_VOL,
192+
SC2731_LDO_CAMD1_VOL_MASK, 6250, 1000000, 1793750),
193+
SC2731_REGU_LINEAR(LDO_CON, SC2731_LDO_CON_PD,
194+
SC2731_LDO_CON_PD_MASK, SC2731_LDO_CON_VOL,
195+
SC2731_LDO_CON_VOL_MASK, 6250, 1000000, 1793750),
196+
SC2731_REGU_LINEAR(LDO_CAMIO, SC2731_LDO_CAMIO_PD,
197+
SC2731_LDO_CAMIO_PD_MASK, SC2731_LDO_CAMIO_VOL,
198+
SC2731_LDO_CAMIO_VOL_MASK, 6250, 1000000, 1793750),
199+
SC2731_REGU_LINEAR(LDO_SRAM, SC2731_LDO_SRAM_PD,
200+
SC2731_LDO_SRAM_PD_MASK, SC2731_LDO_SRAM_VOL,
201+
SC2731_LDO_SRAM_VOL_MASK, 6250, 1000000, 1793750),
202+
};
203+
204+
static int sc2731_regulator_unlock(struct regmap *regmap)
205+
{
206+
return regmap_write(regmap, SC2731_PWR_WR_PROT,
207+
SC2731_WR_UNLOCK_VALUE);
208+
}
209+
210+
static int sc2731_regulator_probe(struct platform_device *pdev)
211+
{
212+
int i, ret;
213+
struct regmap *regmap;
214+
struct regulator_config config = { };
215+
struct regulator_dev *rdev;
216+
217+
regmap = dev_get_regmap(pdev->dev.parent, NULL);
218+
if (!regmap) {
219+
dev_err(&pdev->dev, "failed to get regmap.\n");
220+
return -ENODEV;
221+
}
222+
223+
ret = sc2731_regulator_unlock(regmap);
224+
if (ret) {
225+
dev_err(&pdev->dev, "failed to release regulator lock\n");
226+
return ret;
227+
}
228+
229+
config.dev = &pdev->dev;
230+
config.regmap = regmap;
231+
232+
for (i = 0; i < ARRAY_SIZE(regulators); i++) {
233+
rdev = devm_regulator_register(&pdev->dev, &regulators[i],
234+
&config);
235+
if (IS_ERR(rdev)) {
236+
dev_err(&pdev->dev, "failed to register regulator %s\n",
237+
regulators[i].name);
238+
return PTR_ERR(rdev);
239+
}
240+
}
241+
242+
return 0;
243+
}
244+
245+
static struct platform_driver sc2731_regulator_driver = {
246+
.driver = {
247+
.name = "sc27xx-regulator",
248+
},
249+
.probe = sc2731_regulator_probe,
250+
};
251+
252+
module_platform_driver(sc2731_regulator_driver);
253+
254+
MODULE_AUTHOR("Chen Junhui <[email protected]>");
255+
MODULE_DESCRIPTION("Spreadtrum SC2731 regulator driver");
256+
MODULE_LICENSE("GPL v2");

0 commit comments

Comments
 (0)