xref: /linux/drivers/regulator/sc2730-regulator.c (revision b3438e5ca785565a65ef231bc03cd5a05c3be5c7)
1*4c40e28eSOtto Pflüger // SPDX-License-Identifier: GPL-2.0
2*4c40e28eSOtto Pflüger /*
3*4c40e28eSOtto Pflüger  * Copyright (C) 2018-2021 Unisoc Inc.
4*4c40e28eSOtto Pflüger  */
5*4c40e28eSOtto Pflüger 
6*4c40e28eSOtto Pflüger #include <linux/module.h>
7*4c40e28eSOtto Pflüger #include <linux/of.h>
8*4c40e28eSOtto Pflüger #include <linux/platform_device.h>
9*4c40e28eSOtto Pflüger #include <linux/regmap.h>
10*4c40e28eSOtto Pflüger #include <linux/regulator/driver.h>
11*4c40e28eSOtto Pflüger #include <linux/regulator/of_regulator.h>
12*4c40e28eSOtto Pflüger 
13*4c40e28eSOtto Pflüger /*
14*4c40e28eSOtto Pflüger  * SC2730 regulator base address
15*4c40e28eSOtto Pflüger  */
16*4c40e28eSOtto Pflüger #define SC2730_REGULATOR_BASE		0x1800
17*4c40e28eSOtto Pflüger 
18*4c40e28eSOtto Pflüger /*
19*4c40e28eSOtto Pflüger  * SC2730 regulator lock register
20*4c40e28eSOtto Pflüger  */
21*4c40e28eSOtto Pflüger #define SC2730_WR_UNLOCK_VALUE		0x6e7f
22*4c40e28eSOtto Pflüger #define SC2730_PWR_WR_PROT		(SC2730_REGULATOR_BASE + 0x3d0)
23*4c40e28eSOtto Pflüger 
24*4c40e28eSOtto Pflüger /*
25*4c40e28eSOtto Pflüger  * SC2730 enable register
26*4c40e28eSOtto Pflüger  */
27*4c40e28eSOtto Pflüger #define SC2730_POWER_PD_SW		(SC2730_REGULATOR_BASE + 0x01c)
28*4c40e28eSOtto Pflüger #define SC2730_LDO_VDDRF18_PD		(SC2730_REGULATOR_BASE + 0x10c)
29*4c40e28eSOtto Pflüger #define SC2730_LDO_VDDCAMIO_PD		(SC2730_REGULATOR_BASE + 0x118)
30*4c40e28eSOtto Pflüger #define SC2730_LDO_VDDWCN_PD		(SC2730_REGULATOR_BASE + 0x11c)
31*4c40e28eSOtto Pflüger #define SC2730_LDO_VDDCAMD1_PD		(SC2730_REGULATOR_BASE + 0x128)
32*4c40e28eSOtto Pflüger #define SC2730_LDO_VDDCAMD0_PD		(SC2730_REGULATOR_BASE + 0x134)
33*4c40e28eSOtto Pflüger #define SC2730_LDO_VDDRF1V25_PD		(SC2730_REGULATOR_BASE + 0x140)
34*4c40e28eSOtto Pflüger #define SC2730_LDO_AVDD12_PD		(SC2730_REGULATOR_BASE + 0x14c)
35*4c40e28eSOtto Pflüger #define SC2730_LDO_VDDCAMA0_PD		(SC2730_REGULATOR_BASE + 0x158)
36*4c40e28eSOtto Pflüger #define SC2730_LDO_VDDCAMA1_PD		(SC2730_REGULATOR_BASE + 0x164)
37*4c40e28eSOtto Pflüger #define SC2730_LDO_VDDCAMMOT_PD		(SC2730_REGULATOR_BASE + 0x170)
38*4c40e28eSOtto Pflüger #define SC2730_LDO_VDDSIM2_PD		(SC2730_REGULATOR_BASE + 0x194)
39*4c40e28eSOtto Pflüger #define SC2730_LDO_VDDEMMCCORE_PD	(SC2730_REGULATOR_BASE + 0x1a0)
40*4c40e28eSOtto Pflüger #define SC2730_LDO_VDDSDCORE_PD		(SC2730_REGULATOR_BASE + 0x1ac)
41*4c40e28eSOtto Pflüger #define SC2730_LDO_VDDSDIO_PD		(SC2730_REGULATOR_BASE + 0x1b8)
42*4c40e28eSOtto Pflüger #define SC2730_LDO_VDDWIFIPA_PD		(SC2730_REGULATOR_BASE + 0x1d0)
43*4c40e28eSOtto Pflüger #define SC2730_LDO_VDDUSB33_PD		(SC2730_REGULATOR_BASE + 0x1e8)
44*4c40e28eSOtto Pflüger #define SC2730_LDO_VDDLDO0_PD		(SC2730_REGULATOR_BASE + 0x1f4)
45*4c40e28eSOtto Pflüger #define SC2730_LDO_VDDLDO1_PD		(SC2730_REGULATOR_BASE + 0x200)
46*4c40e28eSOtto Pflüger #define SC2730_LDO_VDDLDO2_PD		(SC2730_REGULATOR_BASE + 0x20c)
47*4c40e28eSOtto Pflüger #define SC2730_LDO_VDDKPLED_PD		(SC2730_REGULATOR_BASE + 0x38c)
48*4c40e28eSOtto Pflüger 
49*4c40e28eSOtto Pflüger /*
50*4c40e28eSOtto Pflüger  * SC2730 enable mask
51*4c40e28eSOtto Pflüger  */
52*4c40e28eSOtto Pflüger #define SC2730_DCDC_CPU_PD_MASK		BIT(4)
53*4c40e28eSOtto Pflüger #define SC2730_DCDC_GPU_PD_MASK		BIT(3)
54*4c40e28eSOtto Pflüger #define SC2730_DCDC_CORE_PD_MASK	BIT(5)
55*4c40e28eSOtto Pflüger #define SC2730_DCDC_MODEM_PD_MASK	BIT(11)
56*4c40e28eSOtto Pflüger #define SC2730_DCDC_MEM_PD_MASK		BIT(6)
57*4c40e28eSOtto Pflüger #define SC2730_DCDC_MEMQ_PD_MASK	BIT(12)
58*4c40e28eSOtto Pflüger #define SC2730_DCDC_GEN0_PD_MASK	BIT(8)
59*4c40e28eSOtto Pflüger #define SC2730_DCDC_GEN1_PD_MASK	BIT(7)
60*4c40e28eSOtto Pflüger #define SC2730_DCDC_SRAM_PD_MASK	BIT(13)
61*4c40e28eSOtto Pflüger #define SC2730_LDO_AVDD18_PD_MASK	BIT(2)
62*4c40e28eSOtto Pflüger #define SC2730_LDO_VDDRF18_PD_MASK	BIT(0)
63*4c40e28eSOtto Pflüger #define SC2730_LDO_VDDCAMIO_PD_MASK	BIT(0)
64*4c40e28eSOtto Pflüger #define SC2730_LDO_VDDWCN_PD_MASK	BIT(0)
65*4c40e28eSOtto Pflüger #define SC2730_LDO_VDDCAMD1_PD_MASK	BIT(0)
66*4c40e28eSOtto Pflüger #define SC2730_LDO_VDDCAMD0_PD_MASK	BIT(0)
67*4c40e28eSOtto Pflüger #define SC2730_LDO_VDDRF1V25_PD_MASK	BIT(0)
68*4c40e28eSOtto Pflüger #define SC2730_LDO_AVDD12_PD_MASK	BIT(0)
69*4c40e28eSOtto Pflüger #define SC2730_LDO_VDDCAMA0_PD_MASK	BIT(0)
70*4c40e28eSOtto Pflüger #define SC2730_LDO_VDDCAMA1_PD_MASK	BIT(0)
71*4c40e28eSOtto Pflüger #define SC2730_LDO_VDDCAMMOT_PD_MASK	BIT(0)
72*4c40e28eSOtto Pflüger #define SC2730_LDO_VDDSIM2_PD_MASK	BIT(0)
73*4c40e28eSOtto Pflüger #define SC2730_LDO_VDDEMMCCORE_PD_MASK	BIT(0)
74*4c40e28eSOtto Pflüger #define SC2730_LDO_VDDSDCORE_PD_MASK	BIT(0)
75*4c40e28eSOtto Pflüger #define SC2730_LDO_VDDSDIO_PD_MASK	BIT(0)
76*4c40e28eSOtto Pflüger #define SC2730_LDO_VDD28_PD_MASK	BIT(1)
77*4c40e28eSOtto Pflüger #define SC2730_LDO_VDDWIFIPA_PD_MASK	BIT(0)
78*4c40e28eSOtto Pflüger #define SC2730_LDO_VDD18_DCXO_PD_MASK	BIT(10)
79*4c40e28eSOtto Pflüger #define SC2730_LDO_VDDUSB33_PD_MASK	BIT(0)
80*4c40e28eSOtto Pflüger #define SC2730_LDO_VDDLDO0_PD_MASK	BIT(0)
81*4c40e28eSOtto Pflüger #define SC2730_LDO_VDDLDO1_PD_MASK	BIT(0)
82*4c40e28eSOtto Pflüger #define SC2730_LDO_VDDLDO2_PD_MASK	BIT(0)
83*4c40e28eSOtto Pflüger #define SC2730_LDO_VDDKPLED_PD_MASK	BIT(15)
84*4c40e28eSOtto Pflüger 
85*4c40e28eSOtto Pflüger /*
86*4c40e28eSOtto Pflüger  * SC2730 vsel register
87*4c40e28eSOtto Pflüger  */
88*4c40e28eSOtto Pflüger #define SC2730_DCDC_CPU_VOL		(SC2730_REGULATOR_BASE + 0x44)
89*4c40e28eSOtto Pflüger #define SC2730_DCDC_GPU_VOL		(SC2730_REGULATOR_BASE + 0x54)
90*4c40e28eSOtto Pflüger #define SC2730_DCDC_CORE_VOL		(SC2730_REGULATOR_BASE + 0x64)
91*4c40e28eSOtto Pflüger #define SC2730_DCDC_MODEM_VOL		(SC2730_REGULATOR_BASE + 0x74)
92*4c40e28eSOtto Pflüger #define SC2730_DCDC_MEM_VOL		(SC2730_REGULATOR_BASE + 0x84)
93*4c40e28eSOtto Pflüger #define SC2730_DCDC_MEMQ_VOL		(SC2730_REGULATOR_BASE + 0x94)
94*4c40e28eSOtto Pflüger #define SC2730_DCDC_GEN0_VOL		(SC2730_REGULATOR_BASE + 0xa4)
95*4c40e28eSOtto Pflüger #define SC2730_DCDC_GEN1_VOL		(SC2730_REGULATOR_BASE + 0xb4)
96*4c40e28eSOtto Pflüger #define SC2730_DCDC_SRAM_VOL		(SC2730_REGULATOR_BASE + 0xdc)
97*4c40e28eSOtto Pflüger #define SC2730_LDO_AVDD18_VOL		(SC2730_REGULATOR_BASE + 0x104)
98*4c40e28eSOtto Pflüger #define SC2730_LDO_VDDRF18_VOL		(SC2730_REGULATOR_BASE + 0x110)
99*4c40e28eSOtto Pflüger #define SC2730_LDO_VDDCAMIO_VOL		(SC2730_REGULATOR_BASE + 0x28)
100*4c40e28eSOtto Pflüger #define SC2730_LDO_VDDWCN_VOL		(SC2730_REGULATOR_BASE + 0x120)
101*4c40e28eSOtto Pflüger #define SC2730_LDO_VDDCAMD1_VOL		(SC2730_REGULATOR_BASE + 0x12c)
102*4c40e28eSOtto Pflüger #define SC2730_LDO_VDDCAMD0_VOL		(SC2730_REGULATOR_BASE + 0x138)
103*4c40e28eSOtto Pflüger #define SC2730_LDO_VDDRF1V25_VOL	(SC2730_REGULATOR_BASE + 0x144)
104*4c40e28eSOtto Pflüger #define SC2730_LDO_AVDD12_VOL		(SC2730_REGULATOR_BASE + 0x150)
105*4c40e28eSOtto Pflüger #define SC2730_LDO_VDDCAMA0_VOL		(SC2730_REGULATOR_BASE + 0x15c)
106*4c40e28eSOtto Pflüger #define SC2730_LDO_VDDCAMA1_VOL		(SC2730_REGULATOR_BASE + 0x168)
107*4c40e28eSOtto Pflüger #define SC2730_LDO_VDDCAMMOT_VOL	(SC2730_REGULATOR_BASE + 0x174)
108*4c40e28eSOtto Pflüger #define SC2730_LDO_VDDSIM2_VOL		(SC2730_REGULATOR_BASE + 0x198)
109*4c40e28eSOtto Pflüger #define SC2730_LDO_VDDEMMCCORE_VOL	(SC2730_REGULATOR_BASE + 0x1a4)
110*4c40e28eSOtto Pflüger #define SC2730_LDO_VDDSDCORE_VOL	(SC2730_REGULATOR_BASE + 0x1b0)
111*4c40e28eSOtto Pflüger #define SC2730_LDO_VDDSDIO_VOL		(SC2730_REGULATOR_BASE + 0x1bc)
112*4c40e28eSOtto Pflüger #define SC2730_LDO_VDD28_VOL		(SC2730_REGULATOR_BASE + 0x1c8)
113*4c40e28eSOtto Pflüger #define SC2730_LDO_VDDWIFIPA_VOL	(SC2730_REGULATOR_BASE + 0x1d4)
114*4c40e28eSOtto Pflüger #define SC2730_LDO_VDD18_DCXO_VOL	(SC2730_REGULATOR_BASE + 0x1e0)
115*4c40e28eSOtto Pflüger #define SC2730_LDO_VDDUSB33_VOL		(SC2730_REGULATOR_BASE + 0x1ec)
116*4c40e28eSOtto Pflüger #define SC2730_LDO_VDDLDO0_VOL		(SC2730_REGULATOR_BASE + 0x1f8)
117*4c40e28eSOtto Pflüger #define SC2730_LDO_VDDLDO1_VOL		(SC2730_REGULATOR_BASE + 0x204)
118*4c40e28eSOtto Pflüger #define SC2730_LDO_VDDLDO2_VOL		(SC2730_REGULATOR_BASE + 0x210)
119*4c40e28eSOtto Pflüger #define SC2730_LDO_VDDKPLED_VOL		(SC2730_REGULATOR_BASE + 0x38c)
120*4c40e28eSOtto Pflüger 
121*4c40e28eSOtto Pflüger /*
122*4c40e28eSOtto Pflüger  * SC2730 vsel register mask
123*4c40e28eSOtto Pflüger  */
124*4c40e28eSOtto Pflüger #define SC2730_DCDC_CPU_VOL_MASK	GENMASK(8, 0)
125*4c40e28eSOtto Pflüger #define SC2730_DCDC_GPU_VOL_MASK	GENMASK(8, 0)
126*4c40e28eSOtto Pflüger #define SC2730_DCDC_CORE_VOL_MASK	GENMASK(8, 0)
127*4c40e28eSOtto Pflüger #define SC2730_DCDC_MODEM_VOL_MASK	GENMASK(8, 0)
128*4c40e28eSOtto Pflüger #define SC2730_DCDC_MEM_VOL_MASK	GENMASK(7, 0)
129*4c40e28eSOtto Pflüger #define SC2730_DCDC_MEMQ_VOL_MASK	GENMASK(8, 0)
130*4c40e28eSOtto Pflüger #define SC2730_DCDC_GEN0_VOL_MASK	GENMASK(7, 0)
131*4c40e28eSOtto Pflüger #define SC2730_DCDC_GEN1_VOL_MASK	GENMASK(7, 0)
132*4c40e28eSOtto Pflüger #define SC2730_DCDC_SRAM_VOL_MASK	GENMASK(8, 0)
133*4c40e28eSOtto Pflüger #define SC2730_LDO_AVDD18_VOL_MASK	GENMASK(5, 0)
134*4c40e28eSOtto Pflüger #define SC2730_LDO_VDDRF18_VOL_MASK	GENMASK(5, 0)
135*4c40e28eSOtto Pflüger #define SC2730_LDO_VDDCAMIO_VOL_MASK	GENMASK(5, 0)
136*4c40e28eSOtto Pflüger #define SC2730_LDO_VDDWCN_VOL_MASK	GENMASK(5, 0)
137*4c40e28eSOtto Pflüger #define SC2730_LDO_VDDCAMD1_VOL_MASK	GENMASK(4, 0)
138*4c40e28eSOtto Pflüger #define SC2730_LDO_VDDCAMD0_VOL_MASK	GENMASK(4, 0)
139*4c40e28eSOtto Pflüger #define SC2730_LDO_VDDRF1V25_VOL_MASK	GENMASK(4, 0)
140*4c40e28eSOtto Pflüger #define SC2730_LDO_AVDD12_VOL_MASK	GENMASK(4, 0)
141*4c40e28eSOtto Pflüger #define SC2730_LDO_VDDCAMA0_VOL_MASK	GENMASK(7, 0)
142*4c40e28eSOtto Pflüger #define SC2730_LDO_VDDCAMA1_VOL_MASK	GENMASK(7, 0)
143*4c40e28eSOtto Pflüger #define SC2730_LDO_VDDCAMMOT_VOL_MASK	GENMASK(7, 0)
144*4c40e28eSOtto Pflüger #define SC2730_LDO_VDDSIM2_VOL_MASK	GENMASK(7, 0)
145*4c40e28eSOtto Pflüger #define SC2730_LDO_VDDEMMCCORE_VOL_MASK	GENMASK(7, 0)
146*4c40e28eSOtto Pflüger #define SC2730_LDO_VDDSDCORE_VOL_MASK	GENMASK(7, 0)
147*4c40e28eSOtto Pflüger #define SC2730_LDO_VDDSDIO_VOL_MASK	GENMASK(7, 0)
148*4c40e28eSOtto Pflüger #define SC2730_LDO_VDD28_VOL_MASK	GENMASK(7, 0)
149*4c40e28eSOtto Pflüger #define SC2730_LDO_VDDWIFIPA_VOL_MASK	GENMASK(7, 0)
150*4c40e28eSOtto Pflüger #define SC2730_LDO_VDD18_DCXO_VOL_MASK	GENMASK(7, 0)
151*4c40e28eSOtto Pflüger #define SC2730_LDO_VDDUSB33_VOL_MASK	GENMASK(7, 0)
152*4c40e28eSOtto Pflüger #define SC2730_LDO_VDDLDO0_VOL_MASK	GENMASK(7, 0)
153*4c40e28eSOtto Pflüger #define SC2730_LDO_VDDLDO1_VOL_MASK	GENMASK(7, 0)
154*4c40e28eSOtto Pflüger #define SC2730_LDO_VDDLDO2_VOL_MASK	GENMASK(7, 0)
155*4c40e28eSOtto Pflüger #define SC2730_LDO_VDDKPLED_VOL_MASK	GENMASK(14, 7)
156*4c40e28eSOtto Pflüger 
157*4c40e28eSOtto Pflüger enum sc2730_regulator_id {
158*4c40e28eSOtto Pflüger 	SC2730_DCDC_CPU,
159*4c40e28eSOtto Pflüger 	SC2730_DCDC_GPU,
160*4c40e28eSOtto Pflüger 	SC2730_DCDC_CORE,
161*4c40e28eSOtto Pflüger 	SC2730_DCDC_MODEM,
162*4c40e28eSOtto Pflüger 	SC2730_DCDC_MEM,
163*4c40e28eSOtto Pflüger 	SC2730_DCDC_MEMQ,
164*4c40e28eSOtto Pflüger 	SC2730_DCDC_GEN0,
165*4c40e28eSOtto Pflüger 	SC2730_DCDC_GEN1,
166*4c40e28eSOtto Pflüger 	SC2730_DCDC_SRAM,
167*4c40e28eSOtto Pflüger 	SC2730_LDO_AVDD18,
168*4c40e28eSOtto Pflüger 	SC2730_LDO_VDDRF18,
169*4c40e28eSOtto Pflüger 	SC2730_LDO_VDDCAMIO,
170*4c40e28eSOtto Pflüger 	SC2730_LDO_VDDWCN,
171*4c40e28eSOtto Pflüger 	SC2730_LDO_VDDCAMD1,
172*4c40e28eSOtto Pflüger 	SC2730_LDO_VDDCAMD0,
173*4c40e28eSOtto Pflüger 	SC2730_LDO_VDDRF1V25,
174*4c40e28eSOtto Pflüger 	SC2730_LDO_AVDD12,
175*4c40e28eSOtto Pflüger 	SC2730_LDO_VDDCAMA0,
176*4c40e28eSOtto Pflüger 	SC2730_LDO_VDDCAMA1,
177*4c40e28eSOtto Pflüger 	SC2730_LDO_VDDCAMMOT,
178*4c40e28eSOtto Pflüger 	SC2730_LDO_VDDSIM2,
179*4c40e28eSOtto Pflüger 	SC2730_LDO_VDDEMMCCORE,
180*4c40e28eSOtto Pflüger 	SC2730_LDO_VDDSDCORE,
181*4c40e28eSOtto Pflüger 	SC2730_LDO_VDDSDIO,
182*4c40e28eSOtto Pflüger 	SC2730_LDO_VDD28,
183*4c40e28eSOtto Pflüger 	SC2730_LDO_VDDWIFIPA,
184*4c40e28eSOtto Pflüger 	SC2730_LDO_VDD18_DCXO,
185*4c40e28eSOtto Pflüger 	SC2730_LDO_VDDUSB33,
186*4c40e28eSOtto Pflüger 	SC2730_LDO_VDDLDO0,
187*4c40e28eSOtto Pflüger 	SC2730_LDO_VDDLDO1,
188*4c40e28eSOtto Pflüger 	SC2730_LDO_VDDLDO2,
189*4c40e28eSOtto Pflüger 	SC2730_LDO_VDDKPLED,
190*4c40e28eSOtto Pflüger };
191*4c40e28eSOtto Pflüger 
192*4c40e28eSOtto Pflüger static const struct regulator_ops sc2730_regu_linear_ops = {
193*4c40e28eSOtto Pflüger 	.enable = regulator_enable_regmap,
194*4c40e28eSOtto Pflüger 	.disable = regulator_disable_regmap,
195*4c40e28eSOtto Pflüger 	.is_enabled = regulator_is_enabled_regmap,
196*4c40e28eSOtto Pflüger 	.list_voltage = regulator_list_voltage_linear,
197*4c40e28eSOtto Pflüger 	.get_voltage_sel = regulator_get_voltage_sel_regmap,
198*4c40e28eSOtto Pflüger 	.set_voltage_sel = regulator_set_voltage_sel_regmap,
199*4c40e28eSOtto Pflüger };
200*4c40e28eSOtto Pflüger 
201*4c40e28eSOtto Pflüger #define SC2730_REGU_LINEAR(_id, of_name, en_reg, en_mask, vreg, vmask,	\
202*4c40e28eSOtto Pflüger 			   vstep, vmin, vmax) {				\
203*4c40e28eSOtto Pflüger 	.name			= #_id,					\
204*4c40e28eSOtto Pflüger 	.of_match		= of_name,				\
205*4c40e28eSOtto Pflüger 	.regulators_node	= "regulators",				\
206*4c40e28eSOtto Pflüger 	.ops			= &sc2730_regu_linear_ops,		\
207*4c40e28eSOtto Pflüger 	.type			= REGULATOR_VOLTAGE,			\
208*4c40e28eSOtto Pflüger 	.id			= SC2730_##_id,				\
209*4c40e28eSOtto Pflüger 	.owner			= THIS_MODULE,				\
210*4c40e28eSOtto Pflüger 	.min_uV			= vmin,					\
211*4c40e28eSOtto Pflüger 	.n_voltages		= ((vmax) - (vmin)) / (vstep) + 1,	\
212*4c40e28eSOtto Pflüger 	.uV_step		= vstep,				\
213*4c40e28eSOtto Pflüger 	.enable_is_inverted	= true,					\
214*4c40e28eSOtto Pflüger 	.enable_val		= 0,					\
215*4c40e28eSOtto Pflüger 	.enable_reg		= en_reg,				\
216*4c40e28eSOtto Pflüger 	.enable_mask		= en_mask,				\
217*4c40e28eSOtto Pflüger 	.vsel_reg		= vreg,					\
218*4c40e28eSOtto Pflüger 	.vsel_mask		= vmask,				\
219*4c40e28eSOtto Pflüger 	.linear_min_sel		= 0,					\
220*4c40e28eSOtto Pflüger }
221*4c40e28eSOtto Pflüger 
222*4c40e28eSOtto Pflüger static const struct regulator_desc regulators[] = {
223*4c40e28eSOtto Pflüger 	SC2730_REGU_LINEAR(DCDC_CPU, "dcdc-cpu", SC2730_POWER_PD_SW,
224*4c40e28eSOtto Pflüger 			   SC2730_DCDC_CPU_PD_MASK, SC2730_DCDC_CPU_VOL,
225*4c40e28eSOtto Pflüger 			   SC2730_DCDC_CPU_VOL_MASK, 3125, 0, 1596875),
226*4c40e28eSOtto Pflüger 	SC2730_REGU_LINEAR(DCDC_GPU, "dcdc-gpu", SC2730_POWER_PD_SW,
227*4c40e28eSOtto Pflüger 			   SC2730_DCDC_GPU_PD_MASK, SC2730_DCDC_GPU_VOL,
228*4c40e28eSOtto Pflüger 			   SC2730_DCDC_GPU_VOL_MASK, 3125, 0, 1596875),
229*4c40e28eSOtto Pflüger 	SC2730_REGU_LINEAR(DCDC_CORE, "dcdc-core", SC2730_POWER_PD_SW,
230*4c40e28eSOtto Pflüger 			   SC2730_DCDC_CORE_PD_MASK, SC2730_DCDC_CORE_VOL,
231*4c40e28eSOtto Pflüger 			   SC2730_DCDC_CORE_VOL_MASK, 3125, 0, 1596875),
232*4c40e28eSOtto Pflüger 	SC2730_REGU_LINEAR(DCDC_MODEM, "dcdc-modem", SC2730_POWER_PD_SW,
233*4c40e28eSOtto Pflüger 			   SC2730_DCDC_MODEM_PD_MASK, SC2730_DCDC_MODEM_VOL,
234*4c40e28eSOtto Pflüger 			   SC2730_DCDC_MODEM_VOL_MASK, 3125, 0, 1596875),
235*4c40e28eSOtto Pflüger 	SC2730_REGU_LINEAR(DCDC_MEM, "dcdc-mem", SC2730_POWER_PD_SW,
236*4c40e28eSOtto Pflüger 			   SC2730_DCDC_MEM_PD_MASK, SC2730_DCDC_MEM_VOL,
237*4c40e28eSOtto Pflüger 			   SC2730_DCDC_MEM_VOL_MASK, 6250, 0, 1593750),
238*4c40e28eSOtto Pflüger 	SC2730_REGU_LINEAR(DCDC_MEMQ, "dcdc-memq", SC2730_POWER_PD_SW,
239*4c40e28eSOtto Pflüger 			   SC2730_DCDC_MEMQ_PD_MASK, SC2730_DCDC_MEMQ_VOL,
240*4c40e28eSOtto Pflüger 			   SC2730_DCDC_MEMQ_VOL_MASK, 3125, 0, 1596875),
241*4c40e28eSOtto Pflüger 	SC2730_REGU_LINEAR(DCDC_GEN0, "dcdc-gen0", SC2730_POWER_PD_SW,
242*4c40e28eSOtto Pflüger 			   SC2730_DCDC_GEN0_PD_MASK, SC2730_DCDC_GEN0_VOL,
243*4c40e28eSOtto Pflüger 			   SC2730_DCDC_GEN0_VOL_MASK, 9375, 20000, 2410625),
244*4c40e28eSOtto Pflüger 	SC2730_REGU_LINEAR(DCDC_GEN1, "dcdc-gen1", SC2730_POWER_PD_SW,
245*4c40e28eSOtto Pflüger 			   SC2730_DCDC_GEN1_PD_MASK, SC2730_DCDC_GEN1_VOL,
246*4c40e28eSOtto Pflüger 			   SC2730_DCDC_GEN1_VOL_MASK, 6250, 50000, 1643750),
247*4c40e28eSOtto Pflüger 	SC2730_REGU_LINEAR(DCDC_SRAM, "dcdc-sram", SC2730_POWER_PD_SW,
248*4c40e28eSOtto Pflüger 			   SC2730_DCDC_SRAM_PD_MASK, SC2730_DCDC_SRAM_VOL,
249*4c40e28eSOtto Pflüger 			   SC2730_DCDC_SRAM_VOL_MASK, 3125, 0, 1596875),
250*4c40e28eSOtto Pflüger 	SC2730_REGU_LINEAR(LDO_AVDD18, "ldo-avdd18", SC2730_POWER_PD_SW,
251*4c40e28eSOtto Pflüger 			   SC2730_LDO_AVDD18_PD_MASK, SC2730_LDO_AVDD18_VOL,
252*4c40e28eSOtto Pflüger 			   SC2730_LDO_AVDD18_VOL_MASK, 10000, 1175000, 1805000),
253*4c40e28eSOtto Pflüger 	SC2730_REGU_LINEAR(LDO_VDDRF18, "ldo-vddrf18", SC2730_LDO_VDDRF18_PD,
254*4c40e28eSOtto Pflüger 			   SC2730_LDO_VDDRF18_PD_MASK, SC2730_LDO_VDDRF18_VOL,
255*4c40e28eSOtto Pflüger 			   SC2730_LDO_VDDRF18_VOL_MASK, 10000, 1175000, 1805000),
256*4c40e28eSOtto Pflüger 	SC2730_REGU_LINEAR(LDO_VDDCAMIO, "ldo-vddcamio", SC2730_LDO_VDDCAMIO_PD,
257*4c40e28eSOtto Pflüger 			   SC2730_LDO_VDDCAMIO_PD_MASK, SC2730_LDO_VDDCAMIO_VOL,
258*4c40e28eSOtto Pflüger 			   SC2730_LDO_VDDCAMIO_VOL_MASK, 10000, 1200000, 1830000),
259*4c40e28eSOtto Pflüger 	SC2730_REGU_LINEAR(LDO_VDDWCN, "ldo-vddwcn", SC2730_LDO_VDDWCN_PD,
260*4c40e28eSOtto Pflüger 			   SC2730_LDO_VDDWCN_PD_MASK, SC2730_LDO_VDDWCN_VOL,
261*4c40e28eSOtto Pflüger 			   SC2730_LDO_VDDWCN_VOL_MASK, 15000, 900000, 1845000),
262*4c40e28eSOtto Pflüger 	SC2730_REGU_LINEAR(LDO_VDDCAMD1, "ldo-vddcamd1", SC2730_LDO_VDDCAMD1_PD,
263*4c40e28eSOtto Pflüger 			   SC2730_LDO_VDDCAMD1_PD_MASK, SC2730_LDO_VDDCAMD1_VOL,
264*4c40e28eSOtto Pflüger 			   SC2730_LDO_VDDCAMD1_VOL_MASK, 15000, 900000, 1365000),
265*4c40e28eSOtto Pflüger 	SC2730_REGU_LINEAR(LDO_VDDCAMD0, "ldo-vddcamd0", SC2730_LDO_VDDCAMD0_PD,
266*4c40e28eSOtto Pflüger 			   SC2730_LDO_VDDCAMD0_PD_MASK, SC2730_LDO_VDDCAMD0_VOL,
267*4c40e28eSOtto Pflüger 			   SC2730_LDO_VDDCAMD0_VOL_MASK, 15000, 900000, 1365000),
268*4c40e28eSOtto Pflüger 	SC2730_REGU_LINEAR(LDO_VDDRF1V25, "ldo-vddrf1v25", SC2730_LDO_VDDRF1V25_PD,
269*4c40e28eSOtto Pflüger 			   SC2730_LDO_VDDRF1V25_PD_MASK, SC2730_LDO_VDDRF1V25_VOL,
270*4c40e28eSOtto Pflüger 			   SC2730_LDO_VDDRF1V25_VOL_MASK, 15000, 900000, 1365000),
271*4c40e28eSOtto Pflüger 	SC2730_REGU_LINEAR(LDO_AVDD12, "ldo-avdd12", SC2730_LDO_AVDD12_PD,
272*4c40e28eSOtto Pflüger 			   SC2730_LDO_AVDD12_PD_MASK, SC2730_LDO_AVDD12_VOL,
273*4c40e28eSOtto Pflüger 			   SC2730_LDO_AVDD12_VOL_MASK, 15000, 900000, 1365000),
274*4c40e28eSOtto Pflüger 	SC2730_REGU_LINEAR(LDO_VDDCAMA0, "ldo-vddcama0", SC2730_LDO_VDDCAMA0_PD,
275*4c40e28eSOtto Pflüger 			   SC2730_LDO_VDDCAMA0_PD_MASK, SC2730_LDO_VDDCAMA0_VOL,
276*4c40e28eSOtto Pflüger 			   SC2730_LDO_VDDCAMA0_VOL_MASK, 10000, 1200000, 3750000),
277*4c40e28eSOtto Pflüger 	SC2730_REGU_LINEAR(LDO_VDDCAMA1, "ldo-vddcama1", SC2730_LDO_VDDCAMA1_PD,
278*4c40e28eSOtto Pflüger 			   SC2730_LDO_VDDCAMA1_PD_MASK, SC2730_LDO_VDDCAMA1_VOL,
279*4c40e28eSOtto Pflüger 			   SC2730_LDO_VDDCAMA1_VOL_MASK, 10000, 1200000, 3750000),
280*4c40e28eSOtto Pflüger 	SC2730_REGU_LINEAR(LDO_VDDCAMMOT, "ldo-vddcammot", SC2730_LDO_VDDCAMMOT_PD,
281*4c40e28eSOtto Pflüger 			   SC2730_LDO_VDDCAMMOT_PD_MASK, SC2730_LDO_VDDCAMMOT_VOL,
282*4c40e28eSOtto Pflüger 			   SC2730_LDO_VDDCAMMOT_VOL_MASK, 10000, 1200000, 3750000),
283*4c40e28eSOtto Pflüger 	SC2730_REGU_LINEAR(LDO_VDDSIM2, "ldo-vddsim2", SC2730_LDO_VDDSIM2_PD,
284*4c40e28eSOtto Pflüger 			   SC2730_LDO_VDDSIM2_PD_MASK, SC2730_LDO_VDDSIM2_VOL,
285*4c40e28eSOtto Pflüger 			   SC2730_LDO_VDDSIM2_VOL_MASK, 10000, 1200000, 3750000),
286*4c40e28eSOtto Pflüger 	SC2730_REGU_LINEAR(LDO_VDDEMMCCORE, "ldo-vddemmccore", SC2730_LDO_VDDEMMCCORE_PD,
287*4c40e28eSOtto Pflüger 			   SC2730_LDO_VDDEMMCCORE_PD_MASK, SC2730_LDO_VDDEMMCCORE_VOL,
288*4c40e28eSOtto Pflüger 			   SC2730_LDO_VDDEMMCCORE_VOL_MASK, 10000, 1200000, 3750000),
289*4c40e28eSOtto Pflüger 	SC2730_REGU_LINEAR(LDO_VDDSDCORE, "ldo-vddsdcore", SC2730_LDO_VDDSDCORE_PD,
290*4c40e28eSOtto Pflüger 			   SC2730_LDO_VDDSDCORE_PD_MASK, SC2730_LDO_VDDSDCORE_VOL,
291*4c40e28eSOtto Pflüger 			   SC2730_LDO_VDDSDCORE_VOL_MASK, 10000, 1200000, 3750000),
292*4c40e28eSOtto Pflüger 	SC2730_REGU_LINEAR(LDO_VDDSDIO, "ldo-vddsdio", SC2730_LDO_VDDSDIO_PD,
293*4c40e28eSOtto Pflüger 			   SC2730_LDO_VDDSDIO_PD_MASK, SC2730_LDO_VDDSDIO_VOL,
294*4c40e28eSOtto Pflüger 			   SC2730_LDO_VDDSDIO_VOL_MASK, 10000, 1200000, 3750000),
295*4c40e28eSOtto Pflüger 	SC2730_REGU_LINEAR(LDO_VDD28, "ldo-vdd28", SC2730_POWER_PD_SW,
296*4c40e28eSOtto Pflüger 			   SC2730_LDO_VDD28_PD_MASK, SC2730_LDO_VDD28_VOL,
297*4c40e28eSOtto Pflüger 			   SC2730_LDO_VDD28_VOL_MASK, 10000, 1200000, 3750000),
298*4c40e28eSOtto Pflüger 	SC2730_REGU_LINEAR(LDO_VDDWIFIPA, "ldo-vddwifipa", SC2730_LDO_VDDWIFIPA_PD,
299*4c40e28eSOtto Pflüger 			   SC2730_LDO_VDDWIFIPA_PD_MASK, SC2730_LDO_VDDWIFIPA_VOL,
300*4c40e28eSOtto Pflüger 			   SC2730_LDO_VDDWIFIPA_VOL_MASK, 10000, 1200000, 3750000),
301*4c40e28eSOtto Pflüger 	SC2730_REGU_LINEAR(LDO_VDD18_DCXO, "ldo-vdd18-dcxo", SC2730_POWER_PD_SW,
302*4c40e28eSOtto Pflüger 			   SC2730_LDO_VDD18_DCXO_PD_MASK, SC2730_LDO_VDD18_DCXO_VOL,
303*4c40e28eSOtto Pflüger 			   SC2730_LDO_VDD18_DCXO_VOL_MASK, 10000, 1200000, 3750000),
304*4c40e28eSOtto Pflüger 	SC2730_REGU_LINEAR(LDO_VDDUSB33, "ldo-vddusb33", SC2730_LDO_VDDUSB33_PD,
305*4c40e28eSOtto Pflüger 			   SC2730_LDO_VDDUSB33_PD_MASK, SC2730_LDO_VDDUSB33_VOL,
306*4c40e28eSOtto Pflüger 			   SC2730_LDO_VDDUSB33_VOL_MASK, 10000, 1200000, 3750000),
307*4c40e28eSOtto Pflüger 	SC2730_REGU_LINEAR(LDO_VDDLDO0, "ldo-vddldo0", SC2730_LDO_VDDLDO0_PD,
308*4c40e28eSOtto Pflüger 			   SC2730_LDO_VDDLDO0_PD_MASK, SC2730_LDO_VDDLDO0_VOL,
309*4c40e28eSOtto Pflüger 			   SC2730_LDO_VDDLDO0_VOL_MASK, 10000, 1200000, 3750000),
310*4c40e28eSOtto Pflüger 	SC2730_REGU_LINEAR(LDO_VDDLDO1, "ldo-vddldo1", SC2730_LDO_VDDLDO1_PD,
311*4c40e28eSOtto Pflüger 			   SC2730_LDO_VDDLDO1_PD_MASK, SC2730_LDO_VDDLDO1_VOL,
312*4c40e28eSOtto Pflüger 			   SC2730_LDO_VDDLDO1_VOL_MASK, 10000, 1200000, 3750000),
313*4c40e28eSOtto Pflüger 	SC2730_REGU_LINEAR(LDO_VDDLDO2, "ldo-vddldo2", SC2730_LDO_VDDLDO2_PD,
314*4c40e28eSOtto Pflüger 			   SC2730_LDO_VDDLDO2_PD_MASK, SC2730_LDO_VDDLDO2_VOL,
315*4c40e28eSOtto Pflüger 			   SC2730_LDO_VDDLDO2_VOL_MASK, 10000, 1200000, 3750000),
316*4c40e28eSOtto Pflüger 	SC2730_REGU_LINEAR(LDO_VDDKPLED, "ldo-vddkpled", SC2730_LDO_VDDKPLED_PD,
317*4c40e28eSOtto Pflüger 			   SC2730_LDO_VDDKPLED_PD_MASK, SC2730_LDO_VDDKPLED_VOL,
318*4c40e28eSOtto Pflüger 			   SC2730_LDO_VDDKPLED_VOL_MASK, 10000, 1200000, 3750000),
319*4c40e28eSOtto Pflüger };
320*4c40e28eSOtto Pflüger 
321*4c40e28eSOtto Pflüger static int sc2730_regulator_unlock(struct regmap *regmap)
322*4c40e28eSOtto Pflüger {
323*4c40e28eSOtto Pflüger 	return regmap_write(regmap, SC2730_PWR_WR_PROT, SC2730_WR_UNLOCK_VALUE);
324*4c40e28eSOtto Pflüger }
325*4c40e28eSOtto Pflüger 
326*4c40e28eSOtto Pflüger static int sc2730_regulator_probe(struct platform_device *pdev)
327*4c40e28eSOtto Pflüger {
328*4c40e28eSOtto Pflüger 	int i, ret;
329*4c40e28eSOtto Pflüger 	struct regmap *regmap;
330*4c40e28eSOtto Pflüger 	struct regulator_config config = { };
331*4c40e28eSOtto Pflüger 	struct regulator_dev *rdev;
332*4c40e28eSOtto Pflüger 
333*4c40e28eSOtto Pflüger 	regmap = dev_get_regmap(pdev->dev.parent, NULL);
334*4c40e28eSOtto Pflüger 	if (!regmap)
335*4c40e28eSOtto Pflüger 		return dev_err_probe(&pdev->dev, -ENODEV, "failed to get regmap\n");
336*4c40e28eSOtto Pflüger 
337*4c40e28eSOtto Pflüger 	ret = sc2730_regulator_unlock(regmap);
338*4c40e28eSOtto Pflüger 	if (ret)
339*4c40e28eSOtto Pflüger 		return dev_err_probe(&pdev->dev, ret, "failed to release regulator lock\n");
340*4c40e28eSOtto Pflüger 
341*4c40e28eSOtto Pflüger 	config.dev = pdev->dev.parent;
342*4c40e28eSOtto Pflüger 	config.regmap = regmap;
343*4c40e28eSOtto Pflüger 
344*4c40e28eSOtto Pflüger 	for (i = 0; i < ARRAY_SIZE(regulators); i++) {
345*4c40e28eSOtto Pflüger 		rdev = devm_regulator_register(&pdev->dev, &regulators[i], &config);
346*4c40e28eSOtto Pflüger 		if (IS_ERR(rdev)) {
347*4c40e28eSOtto Pflüger 			return dev_err_probe(&pdev->dev, PTR_ERR(rdev),
348*4c40e28eSOtto Pflüger 					     "failed to register regulator %s\n",
349*4c40e28eSOtto Pflüger 					     regulators[i].name);
350*4c40e28eSOtto Pflüger 		}
351*4c40e28eSOtto Pflüger 	}
352*4c40e28eSOtto Pflüger 
353*4c40e28eSOtto Pflüger 	return 0;
354*4c40e28eSOtto Pflüger }
355*4c40e28eSOtto Pflüger 
356*4c40e28eSOtto Pflüger static const struct platform_device_id sc2730_regulator_id_table[] = {
357*4c40e28eSOtto Pflüger 	{ .name = "sc2730-regulator" },
358*4c40e28eSOtto Pflüger 	{ }
359*4c40e28eSOtto Pflüger };
360*4c40e28eSOtto Pflüger MODULE_DEVICE_TABLE(platform, sc2730_regulator_id_table);
361*4c40e28eSOtto Pflüger 
362*4c40e28eSOtto Pflüger static struct platform_driver sc2730_regulator_driver = {
363*4c40e28eSOtto Pflüger 	.driver = {
364*4c40e28eSOtto Pflüger 		.name = "sc2730-regulator",
365*4c40e28eSOtto Pflüger 		.probe_type = PROBE_PREFER_ASYNCHRONOUS,
366*4c40e28eSOtto Pflüger 	},
367*4c40e28eSOtto Pflüger 	.probe = sc2730_regulator_probe,
368*4c40e28eSOtto Pflüger 	.id_table = sc2730_regulator_id_table,
369*4c40e28eSOtto Pflüger };
370*4c40e28eSOtto Pflüger 
371*4c40e28eSOtto Pflüger module_platform_driver(sc2730_regulator_driver);
372*4c40e28eSOtto Pflüger 
373*4c40e28eSOtto Pflüger MODULE_AUTHOR("Zhongfa Wang <zhongfa.wang@unisoc.com>");
374*4c40e28eSOtto Pflüger MODULE_DESCRIPTION("Spreadtrum SC2730 regulator driver");
375*4c40e28eSOtto Pflüger MODULE_LICENSE("GPL");
376