xref: /rk3399_rockchip-uboot/drivers/power/regulator/rk8xx.c (revision e17ddcea32b2fa7b82fb079f37195855a55e39a2)
1 /*
2  * Copyright (C) 2015 Google, Inc
3  * Written by Simon Glass <sjg@chromium.org>
4  *
5  * Based on Rockchip's drivers/power/pmic/pmic_rk808.c:
6  * Copyright (C) 2012 rockchips
7  * zyw <zyw@rock-chips.com>
8  *
9  * SPDX-License-Identifier:	GPL-2.0+
10  */
11 
12 #include <common.h>
13 #include <dm.h>
14 #include <errno.h>
15 #include <power/rk8xx_pmic.h>
16 #include <power/pmic.h>
17 #include <power/regulator.h>
18 
19 #ifndef CONFIG_SPL_BUILD
20 #define ENABLE_DRIVER
21 #endif
22 
23 /* Field Definitions */
24 #define RK808_BUCK_VSEL_MASK	0x3f
25 #define RK808_BUCK4_VSEL_MASK	0xf
26 #define RK808_LDO_VSEL_MASK	0x1f
27 
28 #define RK818_BUCK_VSEL_MASK		0x3f
29 #define RK818_BUCK4_VSEL_MASK		0x1f
30 #define RK818_LDO_VSEL_MASK		0x1f
31 #define RK818_LDO3_ON_VSEL_MASK	0xf
32 #define RK818_BOOST_ON_VSEL_MASK	0xe0
33 #define RK818_USB_ILIM_SEL_MASK		0x0f
34 #define RK818_USB_CHG_SD_VSEL_MASK	0x70
35 
36 /* RK809 BUCK5 */
37 #define RK809_BUCK5_CONFIG(n)		(0xde + (n) * 1)
38 #define RK809_BUCK5_VSEL_MASK		0x07
39 
40 /* RK817 BUCK */
41 #define RK817_BUCK_ON_VSEL(n)		(0xbb + 3 * (n - 1))
42 #define RK817_BUCK_SLP_VSEL(n)		(0xbc + 3 * (n - 1))
43 #define RK817_BUCK_VSEL_MASK		0x7f
44 
45 /* RK817 LDO */
46 #define RK817_LDO_ON_VSEL(n)		(0xcc + 2 * (n - 1))
47 #define RK817_LDO_SLP_VSEL(n)		(0xcd + 2 * (n - 1))
48 #define RK817_LDO_VSEL_MASK		0x7f
49 
50 /* RK817 ENABLE */
51 #define RK817_POWER_EN(n)		(0xb1 + (n))
52 #define RK817_POWER_SLP_EN(n)		(0xb5 + (n))
53 
54 struct rk8xx_reg_info {
55 	uint min_uv;
56 	uint step_uv;
57 	u8 vsel_reg;
58 	u8 vsel_sleep_reg;
59 	u8 vsel_mask;
60 	u8 min_sel;
61 };
62 
63 static const struct rk8xx_reg_info rk808_buck[] = {
64 	{ 712500,   12500, REG_BUCK1_ON_VSEL, REG_BUCK1_SLP_VSEL, RK808_BUCK_VSEL_MASK, },
65 	{ 712500,   12500, REG_BUCK2_ON_VSEL, REG_BUCK2_SLP_VSEL, RK808_BUCK_VSEL_MASK, },
66 	{ 712500,   12500, -1, -1, RK808_BUCK_VSEL_MASK, },
67 	{ 1800000, 100000, REG_BUCK4_ON_VSEL, REG_BUCK4_SLP_VSEL, RK808_BUCK4_VSEL_MASK, },
68 };
69 
70 static const struct rk8xx_reg_info rk816_buck[] = {
71 	/* buck 1 */
72 	{  712500,  12500, REG_BUCK1_ON_VSEL, REG_BUCK1_SLP_VSEL, RK818_BUCK_VSEL_MASK, 0x00, },
73 	{ 1800000, 200000, REG_BUCK1_ON_VSEL, REG_BUCK1_SLP_VSEL, RK818_BUCK_VSEL_MASK, 0x3c, },
74 	{ 2300000,      0, REG_BUCK1_ON_VSEL, REG_BUCK1_SLP_VSEL, RK818_BUCK_VSEL_MASK, 0x3f, },
75 	/* buck 2 */
76 	{  712500,  12500, REG_BUCK2_ON_VSEL, REG_BUCK2_SLP_VSEL, RK818_BUCK_VSEL_MASK, 0x00, },
77 	{ 1800000, 200000, REG_BUCK2_ON_VSEL, REG_BUCK2_SLP_VSEL, RK818_BUCK_VSEL_MASK, 0x3c, },
78 	{ 2300000,      0, REG_BUCK2_ON_VSEL, REG_BUCK2_SLP_VSEL, RK818_BUCK_VSEL_MASK, 0x3f, },
79 	/* buck 3 */
80 	{ 712500, 12500, -1, -1, RK818_BUCK_VSEL_MASK, },
81 	/* buck 4 */
82 	{  800000, 100000, REG_BUCK4_ON_VSEL, REG_BUCK4_SLP_VSEL, RK818_BUCK4_VSEL_MASK, },
83 };
84 
85 static const struct rk8xx_reg_info rk809_buck5[] = {
86 	/* buck 5 */
87 	{ 1500000,	0, RK809_BUCK5_CONFIG(0), RK809_BUCK5_CONFIG(1), RK809_BUCK5_VSEL_MASK, 0x00, },
88 	{ 1800000, 200000, RK809_BUCK5_CONFIG(0), RK809_BUCK5_CONFIG(1), RK809_BUCK5_VSEL_MASK, 0x01, },
89 	{ 2800000, 200000, RK809_BUCK5_CONFIG(0), RK809_BUCK5_CONFIG(1), RK809_BUCK5_VSEL_MASK, 0x04, },
90 	{ 3300000, 300000, RK809_BUCK5_CONFIG(0), RK809_BUCK5_CONFIG(1), RK809_BUCK5_VSEL_MASK, 0x06, },
91 };
92 
93 static const struct rk8xx_reg_info rk817_buck[] = {
94 	/* buck 1 */
95 	{  500000,  12500, RK817_BUCK_ON_VSEL(1), RK817_BUCK_SLP_VSEL(1), RK817_BUCK_VSEL_MASK, 0x00, },
96 	{ 1500000, 100000, RK817_BUCK_ON_VSEL(1), RK817_BUCK_SLP_VSEL(1), RK817_BUCK_VSEL_MASK, 0x50, },
97 	{ 2400000,	0, RK817_BUCK_ON_VSEL(1), RK817_BUCK_SLP_VSEL(1), RK817_BUCK_VSEL_MASK, 0x59, },
98 	/* buck 2 */
99 	{  500000,  12500, RK817_BUCK_ON_VSEL(2), RK817_BUCK_SLP_VSEL(2), RK817_BUCK_VSEL_MASK, 0x00, },
100 	{ 1500000, 100000, RK817_BUCK_ON_VSEL(2), RK817_BUCK_SLP_VSEL(2), RK817_BUCK_VSEL_MASK, 0x50, },
101 	{ 2400000,	0, RK817_BUCK_ON_VSEL(2), RK817_BUCK_SLP_VSEL(2), RK817_BUCK_VSEL_MASK, 0x59, },
102 	/* buck 3 */
103 	{  500000,  12500, RK817_BUCK_ON_VSEL(3), RK817_BUCK_SLP_VSEL(3), RK817_BUCK_VSEL_MASK, 0x00, },
104 	{ 1500000, 100000, RK817_BUCK_ON_VSEL(3), RK817_BUCK_SLP_VSEL(3), RK817_BUCK_VSEL_MASK, 0x50, },
105 	{ 2400000,	0, RK817_BUCK_ON_VSEL(3), RK817_BUCK_SLP_VSEL(3), RK817_BUCK_VSEL_MASK, 0x59, },
106 	/* buck 4 */
107 	{  500000,  12500, RK817_BUCK_ON_VSEL(4), RK817_BUCK_SLP_VSEL(4), RK817_BUCK_VSEL_MASK, 0x00, },
108 	{ 1500000, 100000, RK817_BUCK_ON_VSEL(4), RK817_BUCK_SLP_VSEL(4), RK817_BUCK_VSEL_MASK, 0x50, },
109 	{ 3400000,	0, RK817_BUCK_ON_VSEL(4), RK817_BUCK_SLP_VSEL(4), RK817_BUCK_VSEL_MASK, 0x63, },
110 };
111 
112 static const struct rk8xx_reg_info rk818_buck[] = {
113 	{ 712500,   12500, REG_BUCK1_ON_VSEL, REG_BUCK1_SLP_VSEL, RK818_BUCK_VSEL_MASK, },
114 	{ 712500,   12500, REG_BUCK2_ON_VSEL, REG_BUCK2_SLP_VSEL, RK818_BUCK_VSEL_MASK, },
115 	{ 712500,   12500, -1, -1, RK818_BUCK_VSEL_MASK, },
116 	{ 1800000, 100000, REG_BUCK4_ON_VSEL, REG_BUCK4_SLP_VSEL, RK818_BUCK4_VSEL_MASK, },
117 };
118 
119 #ifdef ENABLE_DRIVER
120 static const struct rk8xx_reg_info rk808_ldo[] = {
121 	{ 1800000, 100000, REG_LDO1_ON_VSEL, REG_LDO1_SLP_VSEL, RK808_LDO_VSEL_MASK, },
122 	{ 1800000, 100000, REG_LDO2_ON_VSEL, REG_LDO2_SLP_VSEL, RK808_LDO_VSEL_MASK, },
123 	{  800000, 100000, REG_LDO3_ON_VSEL, REG_LDO3_SLP_VSEL, RK808_BUCK4_VSEL_MASK, },
124 	{ 1800000, 100000, REG_LDO4_ON_VSEL, REG_LDO4_SLP_VSEL, RK808_LDO_VSEL_MASK, },
125 	{ 1800000, 100000, REG_LDO5_ON_VSEL, REG_LDO5_SLP_VSEL, RK808_LDO_VSEL_MASK, },
126 	{  800000, 100000, REG_LDO6_ON_VSEL, REG_LDO6_SLP_VSEL, RK808_LDO_VSEL_MASK, },
127 	{  800000, 100000, REG_LDO7_ON_VSEL, REG_LDO7_SLP_VSEL, RK808_LDO_VSEL_MASK, },
128 	{ 1800000, 100000, REG_LDO8_ON_VSEL, REG_LDO8_SLP_VSEL, RK808_LDO_VSEL_MASK, },
129 };
130 
131 static const struct rk8xx_reg_info rk816_ldo[] = {
132 	{ 800000, 100000, REG_LDO1_ON_VSEL, REG_LDO1_SLP_VSEL, RK818_LDO_VSEL_MASK, },
133 	{ 800000, 100000, REG_LDO2_ON_VSEL, REG_LDO2_SLP_VSEL, RK818_LDO_VSEL_MASK, },
134 	{ 800000, 100000, REG_LDO3_ON_VSEL, REG_LDO3_SLP_VSEL, RK818_LDO_VSEL_MASK, },
135 	{ 800000, 100000, REG_LDO4_ON_VSEL, REG_LDO4_SLP_VSEL, RK818_LDO_VSEL_MASK, },
136 	{ 800000, 100000, REG_LDO5_ON_VSEL, REG_LDO5_SLP_VSEL, RK818_LDO_VSEL_MASK, },
137 	{ 800000, 100000, REG_LDO6_ON_VSEL, REG_LDO6_SLP_VSEL, RK818_LDO_VSEL_MASK, },
138 };
139 
140 static const struct rk8xx_reg_info rk817_ldo[] = {
141 	/* ldo1 */
142 	{  600000, 25000, RK817_LDO_ON_VSEL(1), RK817_LDO_SLP_VSEL(1), RK817_LDO_VSEL_MASK, 0x00, },
143 	{ 3400000,     0, RK817_LDO_ON_VSEL(1), RK817_LDO_SLP_VSEL(1), RK817_LDO_VSEL_MASK, 0x70, },
144 	/* ldo2 */
145 	{  600000, 25000, RK817_LDO_ON_VSEL(2), RK817_LDO_SLP_VSEL(2), RK817_LDO_VSEL_MASK, 0x00, },
146 	{ 3400000,     0, RK817_LDO_ON_VSEL(2), RK817_LDO_SLP_VSEL(2), RK817_LDO_VSEL_MASK, 0x70, },
147 	/* ldo3 */
148 	{  600000, 25000, RK817_LDO_ON_VSEL(3), RK817_LDO_SLP_VSEL(3), RK817_LDO_VSEL_MASK, 0x00, },
149 	{ 3400000,     0, RK817_LDO_ON_VSEL(3), RK817_LDO_SLP_VSEL(3), RK817_LDO_VSEL_MASK, 0x70, },
150 	/* ldo4 */
151 	{  600000, 25000, RK817_LDO_ON_VSEL(4), RK817_LDO_SLP_VSEL(4), RK817_LDO_VSEL_MASK, 0x00, },
152 	{ 3400000,     0, RK817_LDO_ON_VSEL(4), RK817_LDO_SLP_VSEL(4), RK817_LDO_VSEL_MASK, 0x70, },
153 	/* ldo5 */
154 	{  600000, 25000, RK817_LDO_ON_VSEL(5), RK817_LDO_SLP_VSEL(5), RK817_LDO_VSEL_MASK, 0x00, },
155 	{ 3400000,     0, RK817_LDO_ON_VSEL(5), RK817_LDO_SLP_VSEL(5), RK817_LDO_VSEL_MASK, 0x70, },
156 	/* ldo6 */
157 	{  600000, 25000, RK817_LDO_ON_VSEL(6), RK817_LDO_SLP_VSEL(6), RK817_LDO_VSEL_MASK, 0x00, },
158 	{ 3400000,     0, RK817_LDO_ON_VSEL(6), RK817_LDO_SLP_VSEL(6), RK817_LDO_VSEL_MASK, 0x70, },
159 	/* ldo7 */
160 	{  600000, 25000, RK817_LDO_ON_VSEL(7), RK817_LDO_SLP_VSEL(7), RK817_LDO_VSEL_MASK, 0x00, },
161 	{ 3400000,     0, RK817_LDO_ON_VSEL(7), RK817_LDO_SLP_VSEL(7), RK817_LDO_VSEL_MASK, 0x70, },
162 	/* ldo8 */
163 	{  600000, 25000, RK817_LDO_ON_VSEL(8), RK817_LDO_SLP_VSEL(8), RK817_LDO_VSEL_MASK, 0x00, },
164 	{ 3400000,     0, RK817_LDO_ON_VSEL(8), RK817_LDO_SLP_VSEL(8), RK817_LDO_VSEL_MASK, 0x70, },
165 	/* ldo9 */
166 	{  600000, 25000, RK817_LDO_ON_VSEL(9), RK817_LDO_SLP_VSEL(9), RK817_LDO_VSEL_MASK, 0x00, },
167 	{ 3400000,     0, RK817_LDO_ON_VSEL(9), RK817_LDO_SLP_VSEL(9), RK817_LDO_VSEL_MASK, 0x70, },
168 };
169 
170 static const struct rk8xx_reg_info rk818_ldo[] = {
171 	{ 1800000, 100000, REG_LDO1_ON_VSEL, REG_LDO1_SLP_VSEL, RK818_LDO_VSEL_MASK, },
172 	{ 1800000, 100000, REG_LDO2_ON_VSEL, REG_LDO2_SLP_VSEL, RK818_LDO_VSEL_MASK, },
173 	{  800000, 100000, REG_LDO3_ON_VSEL, REG_LDO3_SLP_VSEL, RK818_LDO3_ON_VSEL_MASK, },
174 	{ 1800000, 100000, REG_LDO4_ON_VSEL, REG_LDO4_SLP_VSEL, RK818_LDO_VSEL_MASK, },
175 	{ 1800000, 100000, REG_LDO5_ON_VSEL, REG_LDO5_SLP_VSEL, RK818_LDO_VSEL_MASK, },
176 	{  800000, 100000, REG_LDO6_ON_VSEL, REG_LDO6_SLP_VSEL, RK818_LDO_VSEL_MASK, },
177 	{  800000, 100000, REG_LDO7_ON_VSEL, REG_LDO7_SLP_VSEL, RK818_LDO_VSEL_MASK, },
178 	{ 1800000, 100000, REG_LDO8_ON_VSEL, REG_LDO8_SLP_VSEL, RK818_LDO_VSEL_MASK, },
179 };
180 #endif
181 
182 static const u16 rk818_chrg_cur_input_array[] = {
183 	450, 800, 850, 1000, 1250, 1500, 1750, 2000, 2250, 2500, 2750, 3000
184 };
185 
186 static const uint rk818_chrg_shutdown_vsel_array[] = {
187 	2780000, 2850000, 2920000, 2990000, 3060000, 3130000, 3190000, 3260000
188 };
189 
190 static const struct rk8xx_reg_info *get_buck_reg(struct udevice *pmic,
191 						 int num, int uvolt)
192 {
193 	struct rk8xx_priv *priv = dev_get_priv(pmic);
194 
195 	switch (priv->variant) {
196 	case RK805_ID:
197 	case RK816_ID:
198 		switch (num) {
199 		case 0:
200 		case 1:
201 			if (uvolt <= 1450000)
202 				return &rk816_buck[num * 3 + 0];
203 			else if (uvolt <= 2200000)
204 				return &rk816_buck[num * 3 + 1];
205 			else
206 				return &rk816_buck[num * 3 + 2];
207 		default:
208 			return &rk816_buck[num + 4];
209 		}
210 
211 	case RK809_ID:
212 	case RK817_ID:
213 		switch (num) {
214 		case 0 ... 2:
215 			if (uvolt < 1500000)
216 				return &rk817_buck[num * 3 + 0];
217 			else if (uvolt < 2400000)
218 				return &rk817_buck[num * 3 + 1];
219 			else
220 				return &rk817_buck[num * 3 + 2];
221 		case 3:
222 			if (uvolt < 1500000)
223 				return &rk817_buck[num * 3 + 0];
224 			else if (uvolt < 3400000)
225 				return &rk817_buck[num * 3 + 1];
226 			else
227 				return &rk817_buck[num * 3 + 2];
228 		/* BUCK5 for RK809 */
229 		default:
230 			if (uvolt < 1800000)
231 				return &rk809_buck5[0];
232 			else if (uvolt < 2800000)
233 				return &rk809_buck5[1];
234 			else if (uvolt < 3300000)
235 				return &rk809_buck5[2];
236 			else
237 				return &rk809_buck5[3];
238 		}
239 	case RK818_ID:
240 		return &rk818_buck[num];
241 	default:
242 		return &rk808_buck[num];
243 	}
244 }
245 
246 static int _buck_set_value(struct udevice *pmic, int buck, int uvolt)
247 {
248 	const struct rk8xx_reg_info *info = get_buck_reg(pmic, buck, uvolt);
249 	int mask = info->vsel_mask;
250 	int val;
251 
252 	if (info->vsel_reg == -1)
253 		return -ENOSYS;
254 
255 	if (info->step_uv == 0)	/* Fixed voltage */
256 		val = info->min_sel;
257 	else
258 		val = ((uvolt - info->min_uv) / info->step_uv) + info->min_sel;
259 
260 	debug("%s: volt=%d, buck=%d, reg=0x%x, mask=0x%x, val=0x%x\n",
261 	      __func__, uvolt, buck+1, info->vsel_reg, mask, val);
262 
263 	return pmic_clrsetbits(pmic, info->vsel_reg, mask, val);
264 }
265 
266 static int _buck_set_enable(struct udevice *pmic, int buck, bool enable)
267 {
268 	uint mask, value, en_reg;
269 	int ret;
270 	struct rk8xx_priv *priv = dev_get_priv(pmic);
271 
272 	switch (priv->variant) {
273 	case RK805_ID:
274 	case RK816_ID:
275 		if (buck >= 4) {
276 			buck -= 4;
277 			en_reg = RK816_REG_DCDC_EN2;
278 		} else {
279 			en_reg = RK816_REG_DCDC_EN1;
280 		}
281 		if (enable)
282 			value = ((1 << buck) | (1 << (buck + 4)));
283 		else
284 			value = ((0 << buck) | (1 << (buck + 4)));
285 		ret = pmic_reg_write(pmic, en_reg, value);
286 		break;
287 
288 	case RK808_ID:
289 	case RK818_ID:
290 		mask = 1 << buck;
291 		if (enable) {
292 			ret = pmic_clrsetbits(pmic, REG_DCDC_ILMAX,
293 					      0, 3 << (buck * 2));
294 			if (ret)
295 				return ret;
296 			ret = pmic_clrsetbits(pmic, REG_DCDC_UV_ACT,
297 					      1 << buck, 0);
298 			if (ret)
299 				return ret;
300 		}
301 		ret = pmic_clrsetbits(pmic, REG_DCDC_EN, mask,
302 				      enable ? mask : 0);
303 		break;
304 	case RK809_ID:
305 	case RK817_ID:
306 		if (buck < 4) {
307 			if (enable)
308 				value = ((1 << buck) | (1 << (buck + 4)));
309 			else
310 				value = ((0 << buck) | (1 << (buck + 4)));
311 			ret = pmic_reg_write(pmic, RK817_POWER_EN(0), value);
312 		/* BUCK5 for RK809 */
313 		} else {
314 			if (enable)
315 				value = ((1 << 1) | (1 << 5));
316 			else
317 				value = ((0 << 1) | (1 << 5));
318 			ret = pmic_reg_write(pmic, RK817_POWER_EN(3), value);
319 		}
320 		break;
321 	default:
322 		ret = -EINVAL;
323 	}
324 
325 	return ret;
326 }
327 
328 #ifdef ENABLE_DRIVER
329 static int _buck_set_suspend_value(struct udevice *pmic, int buck, int uvolt)
330 {
331 	const struct rk8xx_reg_info *info = get_buck_reg(pmic, buck, uvolt);
332 	int mask = info->vsel_mask;
333 	int val;
334 
335 	if (info->vsel_sleep_reg == -1)
336 		return -ENOSYS;
337 
338 	if (info->step_uv == 0)
339 		val = info->min_sel;
340 	else
341 		val = ((uvolt - info->min_uv) / info->step_uv) + info->min_sel;
342 
343 	debug("%s: volt=%d, buck=%d, reg=0x%x, mask=0x%x, val=0x%x\n",
344 	      __func__, uvolt, buck+1, info->vsel_sleep_reg, mask, val);
345 
346 	return pmic_clrsetbits(pmic, info->vsel_sleep_reg, mask, val);
347 }
348 
349 static int _buck_get_enable(struct udevice *pmic, int buck)
350 {
351 	struct rk8xx_priv *priv = dev_get_priv(pmic);
352 	uint mask = 0;
353 	int ret = 0;
354 
355 	switch (priv->variant) {
356 	case RK805_ID:
357 	case RK816_ID:
358 		if (buck >= 4) {
359 			mask = 1 << (buck - 4);
360 			ret = pmic_reg_read(pmic, RK816_REG_DCDC_EN2);
361 		} else {
362 			mask = 1 << buck;
363 			ret = pmic_reg_read(pmic, RK816_REG_DCDC_EN1);
364 		}
365 		break;
366 	case RK808_ID:
367 	case RK818_ID:
368 		mask = 1 << buck;
369 		ret = pmic_reg_read(pmic, REG_DCDC_EN);
370 		if (ret < 0)
371 			return ret;
372 		break;
373 	case RK809_ID:
374 	case RK817_ID:
375 		if (buck < 4) {
376 			mask = 1 << buck;
377 			ret = pmic_reg_read(pmic, RK817_POWER_EN(0));
378 		/* BUCK5 for RK809 */
379 		} else {
380 			mask = 1 << 1;
381 			ret = pmic_reg_read(pmic, RK817_POWER_EN(3));
382 		}
383 		break;
384 	}
385 
386 	if (ret < 0)
387 		return ret;
388 
389 	return ret & mask ? true : false;
390 }
391 
392 static int _buck_set_suspend_enable(struct udevice *pmic, int buck, bool enable)
393 {
394 	uint mask;
395 	int ret;
396 	struct rk8xx_priv *priv = dev_get_priv(pmic);
397 
398 	switch (priv->variant) {
399 	case RK805_ID:
400 	case RK816_ID:
401 		mask = 1 << buck;
402 		ret = pmic_clrsetbits(pmic, RK816_REG_DCDC_SLP_EN, mask,
403 				      enable ? mask : 0);
404 		break;
405 	case RK808_ID:
406 	case RK818_ID:
407 		mask = 1 << buck;
408 		ret = pmic_clrsetbits(pmic, REG_SLEEP_SET_OFF1, mask,
409 				      enable ? 0 : mask);
410 		break;
411 	case RK809_ID:
412 	case RK817_ID:
413 		if (buck < 4)
414 			mask = 1 << buck;
415 		else
416 			mask = 1 << 5;	/* BUCK5 for RK809 */
417 		ret = pmic_clrsetbits(pmic, RK817_POWER_SLP_EN(0), mask,
418 				      enable ? mask : 0);
419 		break;
420 	default:
421 		ret = -EINVAL;
422 	}
423 
424 	return ret;
425 }
426 
427 static const struct rk8xx_reg_info *get_ldo_reg(struct udevice *pmic,
428 						int num, int uvolt)
429 {
430 	struct rk8xx_priv *priv = dev_get_priv(pmic);
431 
432 	switch (priv->variant) {
433 	case RK805_ID:
434 	case RK816_ID:
435 		return &rk816_ldo[num];
436 	case RK809_ID:
437 	case RK817_ID:
438 		if (uvolt < 3400000)
439 			return &rk817_ldo[num * 2 + 0];
440 		else
441 			return &rk817_ldo[num * 2 + 1];
442 	case RK818_ID:
443 		return &rk818_ldo[num];
444 	default:
445 		return &rk808_ldo[num];
446 	}
447 }
448 
449 static int _ldo_get_enable(struct udevice *pmic, int ldo)
450 {
451 	struct rk8xx_priv *priv = dev_get_priv(pmic);
452 	uint mask = 0;
453 	int ret = 0;
454 
455 	switch (priv->variant) {
456 	case RK805_ID:
457 	case RK816_ID:
458 		if (ldo >= 4) {
459 			mask = 1 << (ldo - 4);
460 			ret = pmic_reg_read(pmic, RK816_REG_LDO_EN2);
461 		} else {
462 			mask = 1 << ldo;
463 			ret = pmic_reg_read(pmic, RK816_REG_LDO_EN1);
464 		}
465 		break;
466 	case RK808_ID:
467 	case RK818_ID:
468 		mask = 1 << ldo;
469 		ret = pmic_reg_read(pmic, REG_LDO_EN);
470 		if (ret < 0)
471 			return ret;
472 		break;
473 	case RK809_ID:
474 	case RK817_ID:
475 		if (ldo < 4) {
476 			mask = 1 << ldo;
477 			ret = pmic_reg_read(pmic, RK817_POWER_EN(1));
478 		} else if (ldo < 8) {
479 			mask = 1 << (ldo - 4);
480 			ret = pmic_reg_read(pmic, RK817_POWER_EN(2));
481 		} else if (ldo == 8) {
482 			mask = 1 << 0;
483 			ret = pmic_reg_read(pmic, RK817_POWER_EN(3));
484 		} else {
485 			return false;
486 		}
487 		break;
488 	}
489 
490 	if (ret < 0)
491 		return ret;
492 
493 	return ret & mask ? true : false;
494 }
495 
496 static int _ldo_set_enable(struct udevice *pmic, int ldo, bool enable)
497 {
498 	struct rk8xx_priv *priv = dev_get_priv(pmic);
499 	uint mask, value, en_reg;
500 	int ret = 0;
501 
502 	switch (priv->variant) {
503 	case RK805_ID:
504 	case RK816_ID:
505 		if (ldo >= 4) {
506 			ldo -= 4;
507 			en_reg = RK816_REG_LDO_EN2;
508 		} else {
509 			en_reg = RK816_REG_LDO_EN1;
510 		}
511 		if (enable)
512 			value = ((1 << ldo) | (1 << (ldo + 4)));
513 		else
514 			value = ((0 << ldo) | (1 << (ldo + 4)));
515 
516 		ret = pmic_reg_write(pmic, en_reg, value);
517 		break;
518 	case RK808_ID:
519 	case RK818_ID:
520 		mask = 1 << ldo;
521 		ret = pmic_clrsetbits(pmic, REG_LDO_EN, mask,
522 				       enable ? mask : 0);
523 		break;
524 	case RK809_ID:
525 	case RK817_ID:
526 		if (ldo < 4) {
527 			en_reg = RK817_POWER_EN(1);
528 		} else if (ldo < 8) {
529 			ldo -= 4;
530 			en_reg = RK817_POWER_EN(2);
531 		} else if (ldo == 8) {
532 			ldo = 0;	/* BIT 0 */
533 			en_reg = RK817_POWER_EN(3);
534 		} else {
535 			return -EINVAL;
536 		}
537 		if (enable)
538 			value = ((1 << ldo) | (1 << (ldo + 4)));
539 		else
540 			value = ((0 << ldo) | (1 << (ldo + 4)));
541 		ret = pmic_reg_write(pmic, en_reg, value);
542 		break;
543 	}
544 
545 	return ret;
546 }
547 
548 static int _ldo_set_suspend_enable(struct udevice *pmic, int ldo, bool enable)
549 {
550 	struct rk8xx_priv *priv = dev_get_priv(pmic);
551 	uint mask;
552 	int ret = 0;
553 
554 	switch (priv->variant) {
555 	case RK805_ID:
556 	case RK816_ID:
557 		mask = 1 << ldo;
558 		ret = pmic_clrsetbits(pmic, RK816_REG_LDO_SLP_EN, mask,
559 				      enable ? mask : 0);
560 		break;
561 	case RK808_ID:
562 	case RK818_ID:
563 		mask = 1 << ldo;
564 		ret = pmic_clrsetbits(pmic, REG_SLEEP_SET_OFF2, mask,
565 				      enable ? 0 : mask);
566 		break;
567 	case RK809_ID:
568 	case RK817_ID:
569 		if (ldo == 8) {
570 			mask = 1 << 4;	/* LDO9 */
571 			ret = pmic_clrsetbits(pmic, RK817_POWER_SLP_EN(0), mask,
572 					      enable ? mask : 0);
573 		} else {
574 			mask = 1 << ldo;
575 			ret = pmic_clrsetbits(pmic, RK817_POWER_SLP_EN(1), mask,
576 					      enable ? mask : 0);
577 		}
578 		break;
579 	}
580 
581 	return ret;
582 }
583 
584 static int buck_get_value(struct udevice *dev)
585 {
586 	int buck = dev->driver_data - 1;
587 	/* We assume level-1 voltage is enough for usage in U-Boot */
588 	const struct rk8xx_reg_info *info = get_buck_reg(dev->parent, buck, 0);
589 	int mask = info->vsel_mask;
590 	int ret, val;
591 
592 	if (info->vsel_reg == -1)
593 		return -ENOSYS;
594 
595 	ret = pmic_reg_read(dev->parent, info->vsel_reg);
596 	if (ret < 0)
597 		return ret;
598 	val = ret & mask;
599 
600 	return info->min_uv + val * info->step_uv;
601 }
602 
603 static int buck_set_value(struct udevice *dev, int uvolt)
604 {
605 	int buck = dev->driver_data - 1;
606 
607 	return _buck_set_value(dev->parent, buck, uvolt);
608 }
609 
610 static int buck_set_suspend_value(struct udevice *dev, int uvolt)
611 {
612 	int buck = dev->driver_data - 1;
613 
614 	return _buck_set_suspend_value(dev->parent, buck, uvolt);
615 }
616 
617 static int buck_set_enable(struct udevice *dev, bool enable)
618 {
619 	int buck = dev->driver_data - 1;
620 
621 	return _buck_set_enable(dev->parent, buck, enable);
622 }
623 
624 static int buck_set_suspend_enable(struct udevice *dev, bool enable)
625 {
626 	int buck = dev->driver_data - 1;
627 
628 	return _buck_set_suspend_enable(dev->parent, buck, enable);
629 }
630 
631 static int buck_get_enable(struct udevice *dev)
632 {
633 	int buck = dev->driver_data - 1;
634 
635 	return _buck_get_enable(dev->parent, buck);
636 }
637 
638 static int ldo_get_value(struct udevice *dev)
639 {
640 	int ldo = dev->driver_data - 1;
641 	const struct rk8xx_reg_info *info = get_ldo_reg(dev->parent, ldo, 0);
642 	int mask = info->vsel_mask;
643 	int ret, val;
644 
645 	if (info->vsel_reg == -1)
646 		return -ENOSYS;
647 	ret = pmic_reg_read(dev->parent, info->vsel_reg);
648 	if (ret < 0)
649 		return ret;
650 	val = ret & mask;
651 
652 	return info->min_uv + val * info->step_uv;
653 }
654 
655 static int ldo_set_value(struct udevice *dev, int uvolt)
656 {
657 	int ldo = dev->driver_data - 1;
658 	const struct rk8xx_reg_info *info = get_ldo_reg(dev->parent, ldo, uvolt);
659 	int mask = info->vsel_mask;
660 	int val;
661 
662 	if (info->vsel_reg == -1)
663 		return -ENOSYS;
664 
665 	if (info->step_uv == 0)
666 		val = info->min_sel;
667 	else
668 		val = ((uvolt - info->min_uv) / info->step_uv) + info->min_sel;
669 
670 	debug("%s: volt=%d, ldo=%d, reg=0x%x, mask=0x%x, val=0x%x\n",
671 	      __func__, uvolt, ldo+1, info->vsel_reg, mask, val);
672 
673 	return pmic_clrsetbits(dev->parent, info->vsel_reg, mask, val);
674 }
675 
676 static int ldo_set_suspend_value(struct udevice *dev, int uvolt)
677 {
678 	int ldo = dev->driver_data - 1;
679 	const struct rk8xx_reg_info *info = get_ldo_reg(dev->parent, ldo, uvolt);
680 	int mask = info->vsel_mask;
681 	int val;
682 
683 	if (info->vsel_sleep_reg == -1)
684 		return -ENOSYS;
685 
686 	if (info->step_uv == 0)
687 		val = info->min_sel;
688 	else
689 		val = ((uvolt - info->min_uv) / info->step_uv) + info->min_sel;
690 
691 	debug("%s: volt=%d, ldo=%d, reg=0x%x, mask=0x%x, val=0x%x\n",
692 	      __func__, uvolt, ldo+1, info->vsel_sleep_reg, mask, val);
693 
694 	return pmic_clrsetbits(dev->parent, info->vsel_sleep_reg, mask, val);
695 }
696 
697 static int ldo_set_enable(struct udevice *dev, bool enable)
698 {
699 	int ldo = dev->driver_data - 1;
700 
701 	return _ldo_set_enable(dev->parent, ldo, enable);
702 }
703 
704 static int ldo_set_suspend_enable(struct udevice *dev, bool enable)
705 {
706 	int ldo = dev->driver_data - 1;
707 
708 	return _ldo_set_suspend_enable(dev->parent, ldo, enable);
709 }
710 
711 static int ldo_get_enable(struct udevice *dev)
712 {
713 	int ldo = dev->driver_data - 1;
714 
715 	return _ldo_get_enable(dev->parent, ldo);
716 }
717 
718 static int switch_set_enable(struct udevice *dev, bool enable)
719 {
720 	struct rk8xx_priv *priv = dev_get_priv(dev->parent);
721 	int ret = 0, sw = dev->driver_data - 1;
722 	uint mask = 0;
723 
724 	switch (priv->variant) {
725 	case RK808_ID:
726 		mask = 1 << (sw + 5);
727 		ret = pmic_clrsetbits(dev->parent, REG_DCDC_EN, mask,
728 				      enable ? mask : 0);
729 		break;
730 	case RK809_ID:
731 		mask = (1 << (sw + 2)) | (1 << (sw + 6));
732 		ret = pmic_clrsetbits(dev->parent, RK817_POWER_EN(3), mask,
733 				      enable ? mask : 0);
734 		break;
735 	case RK818_ID:
736 		mask = 1 << 6;
737 		ret = pmic_clrsetbits(dev->parent, REG_DCDC_EN, mask,
738 				      enable ? mask : 0);
739 		break;
740 	}
741 
742 	debug("%s: switch%d, enable=%d, mask=0x%x\n",
743 	      __func__, sw + 1, enable, mask);
744 
745 	return ret;
746 }
747 
748 static int switch_get_enable(struct udevice *dev)
749 {
750 	struct rk8xx_priv *priv = dev_get_priv(dev->parent);
751 	int ret = 0, sw = dev->driver_data - 1;
752 	uint mask = 0;
753 
754 	switch (priv->variant) {
755 	case RK808_ID:
756 		mask = 1 << (sw + 5);
757 		ret = pmic_reg_read(dev->parent, REG_DCDC_EN);
758 		break;
759 	case RK809_ID:
760 		mask = 1 << (sw + 2);
761 		ret = pmic_reg_read(dev->parent, RK817_POWER_EN(3));
762 		break;
763 	case RK818_ID:
764 		mask = 1 << 6;
765 		ret = pmic_reg_read(dev->parent, REG_DCDC_EN);
766 		break;
767 	}
768 
769 	if (ret < 0)
770 		return ret;
771 
772 	return ret & mask ? true : false;
773 }
774 
775 static int switch_set_suspend_value(struct udevice *dev, int uvolt)
776 {
777 	return 0;
778 }
779 
780 static int switch_set_suspend_enable(struct udevice *dev, bool enable)
781 {
782 	struct rk8xx_priv *priv = dev_get_priv(dev->parent);
783 	int ret = 0, sw = dev->driver_data - 1;
784 	uint mask = 0;
785 
786 	switch (priv->variant) {
787 	case RK808_ID:
788 		mask = 1 << (sw + 5);
789 		ret = pmic_clrsetbits(dev->parent, REG_SLEEP_SET_OFF1, mask,
790 				      enable ? 0 : mask);
791 		break;
792 	case RK809_ID:
793 		mask = 1 << (sw + 6);
794 		ret = pmic_clrsetbits(dev->parent, RK817_POWER_SLP_EN(0), mask,
795 				      enable ? mask : 0);
796 		break;
797 	case RK818_ID:
798 		mask = 1 << 6;
799 		ret = pmic_clrsetbits(dev->parent, REG_SLEEP_SET_OFF1, mask,
800 				      enable ? 0 : mask);
801 		break;
802 	}
803 
804 	debug("%s: switch%d, enable=%d, mask=0x%x\n",
805 	      __func__, sw + 1, enable, mask);
806 
807 	return ret;
808 }
809 
810 static int rk8xx_buck_probe(struct udevice *dev)
811 {
812 	struct dm_regulator_uclass_platdata *uc_pdata;
813 
814 	uc_pdata = dev_get_uclass_platdata(dev);
815 
816 	uc_pdata->type = REGULATOR_TYPE_BUCK;
817 	uc_pdata->mode_count = 0;
818 
819 	return 0;
820 }
821 
822 static int rk8xx_ldo_probe(struct udevice *dev)
823 {
824 	struct dm_regulator_uclass_platdata *uc_pdata;
825 
826 	uc_pdata = dev_get_uclass_platdata(dev);
827 
828 	uc_pdata->type = REGULATOR_TYPE_LDO;
829 	uc_pdata->mode_count = 0;
830 
831 	return 0;
832 }
833 
834 static int rk8xx_switch_probe(struct udevice *dev)
835 {
836 	struct dm_regulator_uclass_platdata *uc_pdata;
837 
838 	uc_pdata = dev_get_uclass_platdata(dev);
839 
840 	uc_pdata->type = REGULATOR_TYPE_FIXED;
841 	uc_pdata->mode_count = 0;
842 
843 	return 0;
844 }
845 
846 static const struct dm_regulator_ops rk8xx_buck_ops = {
847 	.get_value  = buck_get_value,
848 	.set_value  = buck_set_value,
849 	.set_suspend_value = buck_set_suspend_value,
850 	.get_enable = buck_get_enable,
851 	.set_enable = buck_set_enable,
852 	.set_suspend_enable = buck_set_suspend_enable,
853 };
854 
855 static const struct dm_regulator_ops rk8xx_ldo_ops = {
856 	.get_value  = ldo_get_value,
857 	.set_value  = ldo_set_value,
858 	.set_suspend_value = ldo_set_suspend_value,
859 	.get_enable = ldo_get_enable,
860 	.set_enable = ldo_set_enable,
861 	.set_suspend_enable = ldo_set_suspend_enable,
862 };
863 
864 static const struct dm_regulator_ops rk8xx_switch_ops = {
865 	.get_enable = switch_get_enable,
866 	.set_enable = switch_set_enable,
867 	.set_suspend_enable = switch_set_suspend_enable,
868 	.set_suspend_value = switch_set_suspend_value,
869 };
870 
871 U_BOOT_DRIVER(rk8xx_buck) = {
872 	.name = "rk8xx_buck",
873 	.id = UCLASS_REGULATOR,
874 	.ops = &rk8xx_buck_ops,
875 	.probe = rk8xx_buck_probe,
876 };
877 
878 U_BOOT_DRIVER(rk8xx_ldo) = {
879 	.name = "rk8xx_ldo",
880 	.id = UCLASS_REGULATOR,
881 	.ops = &rk8xx_ldo_ops,
882 	.probe = rk8xx_ldo_probe,
883 };
884 
885 U_BOOT_DRIVER(rk8xx_switch) = {
886 	.name = "rk8xx_switch",
887 	.id = UCLASS_REGULATOR,
888 	.ops = &rk8xx_switch_ops,
889 	.probe = rk8xx_switch_probe,
890 };
891 #endif
892 
893 int rk8xx_spl_configure_buck(struct udevice *pmic, int buck, int uvolt)
894 {
895 	int ret;
896 
897 	ret = _buck_set_value(pmic, buck, uvolt);
898 	if (ret)
899 		return ret;
900 
901 	return _buck_set_enable(pmic, buck, true);
902 }
903 
904 int rk818_spl_configure_usb_input_current(struct udevice *pmic, int current_ma)
905 {
906 	uint i;
907 
908 	for (i = 0; i < ARRAY_SIZE(rk818_chrg_cur_input_array); i++)
909 		if (current_ma <= rk818_chrg_cur_input_array[i])
910 			break;
911 
912 	return pmic_clrsetbits(pmic, REG_USB_CTRL, RK818_USB_ILIM_SEL_MASK, i);
913 }
914 
915 int rk818_spl_configure_usb_chrg_shutdown(struct udevice *pmic, int uvolt)
916 {
917 	uint i;
918 
919 	for (i = 0; i < ARRAY_SIZE(rk818_chrg_shutdown_vsel_array); i++)
920 		if (uvolt <= rk818_chrg_shutdown_vsel_array[i])
921 			break;
922 
923 	return pmic_clrsetbits(pmic, REG_USB_CTRL, RK818_USB_CHG_SD_VSEL_MASK,
924 			       i);
925 }
926