xref: /openbmc/u-boot/drivers/power/regulator/rk8xx.c (revision 87a62bce)
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) 2015 Google, Inc
4  * Written by Simon Glass <sjg@chromium.org>
5  *
6  * Based on Rockchip's drivers/power/pmic/pmic_rk808.c:
7  * Copyright (C) 2012 rockchips
8  * zyw <zyw@rock-chips.com>
9  */
10 
11 #include <common.h>
12 #include <dm.h>
13 #include <errno.h>
14 #include <power/rk8xx_pmic.h>
15 #include <power/pmic.h>
16 #include <power/regulator.h>
17 
18 #ifndef CONFIG_SPL_BUILD
19 #define ENABLE_DRIVER
20 #endif
21 
22 /* Field Definitions */
23 #define RK808_BUCK_VSEL_MASK	0x3f
24 #define RK808_BUCK4_VSEL_MASK	0xf
25 #define RK808_LDO_VSEL_MASK	0x1f
26 
27 #define RK818_BUCK_VSEL_MASK		0x3f
28 #define RK818_BUCK4_VSEL_MASK		0x1f
29 #define RK818_LDO_VSEL_MASK		0x1f
30 #define RK818_LDO3_ON_VSEL_MASK	0xf
31 #define RK818_BOOST_ON_VSEL_MASK	0xe0
32 #define RK818_USB_ILIM_SEL_MASK		0x0f
33 #define RK818_USB_CHG_SD_VSEL_MASK	0x70
34 
35 
36 struct rk8xx_reg_info {
37 	uint min_uv;
38 	uint step_uv;
39 	s8 vsel_reg;
40 	u8 vsel_mask;
41 };
42 
43 static const struct rk8xx_reg_info rk808_buck[] = {
44 	{ 712500, 12500, REG_BUCK1_ON_VSEL, RK808_BUCK_VSEL_MASK, },
45 	{ 712500, 12500, REG_BUCK2_ON_VSEL, RK808_BUCK_VSEL_MASK, },
46 	{ 712500, 12500, -1, RK808_BUCK_VSEL_MASK, },
47 	{ 1800000, 100000, REG_BUCK4_ON_VSEL, RK808_BUCK4_VSEL_MASK, },
48 };
49 
50 static const struct rk8xx_reg_info rk818_buck[] = {
51 	{ 712500, 12500, REG_BUCK1_ON_VSEL, RK818_BUCK_VSEL_MASK, },
52 	{ 712500, 12500, REG_BUCK2_ON_VSEL, RK818_BUCK_VSEL_MASK, },
53 	{ 712500, 12500, -1, RK818_BUCK_VSEL_MASK, },
54 	{ 1800000, 100000, REG_BUCK4_ON_VSEL, RK818_BUCK4_VSEL_MASK, },
55 };
56 
57 #ifdef ENABLE_DRIVER
58 static const struct rk8xx_reg_info rk808_ldo[] = {
59 	{ 1800000, 100000, REG_LDO1_ON_VSEL, RK808_LDO_VSEL_MASK, },
60 	{ 1800000, 100000, REG_LDO2_ON_VSEL, RK808_LDO_VSEL_MASK, },
61 	{ 800000, 100000, REG_LDO3_ON_VSEL, RK808_BUCK4_VSEL_MASK, },
62 	{ 1800000, 100000, REG_LDO4_ON_VSEL, RK808_LDO_VSEL_MASK, },
63 	{ 1800000, 100000, REG_LDO5_ON_VSEL, RK808_LDO_VSEL_MASK, },
64 	{ 800000, 100000, REG_LDO6_ON_VSEL, RK808_LDO_VSEL_MASK, },
65 	{ 800000, 100000, REG_LDO7_ON_VSEL, RK808_LDO_VSEL_MASK, },
66 	{ 1800000, 100000, REG_LDO8_ON_VSEL, RK808_LDO_VSEL_MASK, },
67 };
68 
69 static const struct rk8xx_reg_info rk818_ldo[] = {
70 	{ 1800000, 100000, REG_LDO1_ON_VSEL, RK818_LDO_VSEL_MASK, },
71 	{ 1800000, 100000, REG_LDO2_ON_VSEL, RK818_LDO_VSEL_MASK, },
72 	{ 800000, 100000, REG_LDO3_ON_VSEL, RK818_LDO3_ON_VSEL_MASK, },
73 	{ 1800000, 100000, REG_LDO4_ON_VSEL, RK818_LDO_VSEL_MASK, },
74 	{ 1800000, 100000, REG_LDO5_ON_VSEL, RK818_LDO_VSEL_MASK, },
75 	{ 800000, 100000, REG_LDO6_ON_VSEL, RK818_LDO_VSEL_MASK, },
76 	{ 800000, 100000, REG_LDO7_ON_VSEL, RK818_LDO_VSEL_MASK, },
77 	{ 1800000, 100000, REG_LDO8_ON_VSEL, RK818_LDO_VSEL_MASK, },
78 };
79 #endif
80 
81 static const u16 rk818_chrg_cur_input_array[] = {
82 	450, 800, 850, 1000, 1250, 1500, 1750, 2000, 2250, 2500, 2750, 3000
83 };
84 
85 static const uint rk818_chrg_shutdown_vsel_array[] = {
86 	2780000, 2850000, 2920000, 2990000, 3060000, 3130000, 3190000, 3260000
87 };
88 
89 static const struct rk8xx_reg_info *get_buck_reg(struct udevice *pmic,
90 					     int num)
91 {
92 	struct rk8xx_priv *priv = dev_get_priv(pmic);
93 	switch (priv->variant) {
94 	case RK818_ID:
95 		return &rk818_buck[num];
96 	default:
97 		return &rk808_buck[num];
98 	}
99 }
100 
101 static int _buck_set_value(struct udevice *pmic, int buck, int uvolt)
102 {
103 	const struct rk8xx_reg_info *info = get_buck_reg(pmic, buck - 1);
104 	int mask = info->vsel_mask;
105 	int val;
106 
107 	if (info->vsel_reg == -1)
108 		return -ENOSYS;
109 	val = (uvolt - info->min_uv) / info->step_uv;
110 	debug("%s: reg=%x, mask=%x, val=%x\n", __func__, info->vsel_reg, mask,
111 	      val);
112 
113 	return pmic_clrsetbits(pmic, info->vsel_reg, mask, val);
114 }
115 
116 static int _buck_set_enable(struct udevice *pmic, int buck, bool enable)
117 {
118 	uint mask;
119 	int ret;
120 
121 	buck--;
122 	mask = 1 << buck;
123 	if (enable) {
124 		ret = pmic_clrsetbits(pmic, REG_DCDC_ILMAX, 0, 3 << (buck * 2));
125 		if (ret)
126 			return ret;
127 		ret = pmic_clrsetbits(pmic, REG_DCDC_UV_ACT, 1 << buck, 0);
128 		if (ret)
129 			return ret;
130 	}
131 
132 	return pmic_clrsetbits(pmic, REG_DCDC_EN, mask, enable ? mask : 0);
133 }
134 
135 #ifdef ENABLE_DRIVER
136 static const struct rk8xx_reg_info *get_ldo_reg(struct udevice *pmic,
137 					     int num)
138 {
139 	struct rk8xx_priv *priv = dev_get_priv(pmic);
140 	switch (priv->variant) {
141 	case RK818_ID:
142 		return &rk818_ldo[num];
143 	default:
144 		return &rk808_ldo[num];
145 	}
146 }
147 
148 static int buck_get_value(struct udevice *dev)
149 {
150 	int buck = dev->driver_data - 1;
151 	const struct rk8xx_reg_info *info = get_buck_reg(dev->parent, buck);
152 	int mask = info->vsel_mask;
153 	int ret, val;
154 
155 	if (info->vsel_reg == -1)
156 		return -ENOSYS;
157 	ret = pmic_reg_read(dev->parent, info->vsel_reg);
158 	if (ret < 0)
159 		return ret;
160 	val = ret & mask;
161 
162 	return info->min_uv + val * info->step_uv;
163 }
164 
165 static int buck_set_value(struct udevice *dev, int uvolt)
166 {
167 	int buck = dev->driver_data;
168 
169 	return _buck_set_value(dev->parent, buck, uvolt);
170 }
171 
172 static int buck_set_enable(struct udevice *dev, bool enable)
173 {
174 	int buck = dev->driver_data;
175 
176 	return _buck_set_enable(dev->parent, buck, enable);
177 }
178 
179 static int buck_get_enable(struct udevice *dev)
180 {
181 	int buck = dev->driver_data - 1;
182 	int ret;
183 	uint mask;
184 
185 	mask = 1 << buck;
186 
187 	ret = pmic_reg_read(dev->parent, REG_DCDC_EN);
188 	if (ret < 0)
189 		return ret;
190 
191 	return ret & mask ? true : false;
192 }
193 
194 static int ldo_get_value(struct udevice *dev)
195 {
196 	int ldo = dev->driver_data - 1;
197 	const struct rk8xx_reg_info *info = get_ldo_reg(dev->parent, ldo);
198 	int mask = info->vsel_mask;
199 	int ret, val;
200 
201 	if (info->vsel_reg == -1)
202 		return -ENOSYS;
203 	ret = pmic_reg_read(dev->parent, info->vsel_reg);
204 	if (ret < 0)
205 		return ret;
206 	val = ret & mask;
207 
208 	return info->min_uv + val * info->step_uv;
209 }
210 
211 static int ldo_set_value(struct udevice *dev, int uvolt)
212 {
213 	int ldo = dev->driver_data - 1;
214 	const struct rk8xx_reg_info *info = get_ldo_reg(dev->parent, ldo);
215 	int mask = info->vsel_mask;
216 	int val;
217 
218 	if (info->vsel_reg == -1)
219 		return -ENOSYS;
220 	val = (uvolt - info->min_uv) / info->step_uv;
221 	debug("%s: reg=%x, mask=%x, val=%x\n", __func__, info->vsel_reg, mask,
222 	      val);
223 
224 	return pmic_clrsetbits(dev->parent, info->vsel_reg, mask, val);
225 }
226 
227 static int ldo_set_enable(struct udevice *dev, bool enable)
228 {
229 	int ldo = dev->driver_data - 1;
230 	uint mask;
231 
232 	mask = 1 << ldo;
233 
234 	return pmic_clrsetbits(dev->parent, REG_LDO_EN, mask,
235 			       enable ? mask : 0);
236 }
237 
238 static int ldo_get_enable(struct udevice *dev)
239 {
240 	int ldo = dev->driver_data - 1;
241 	int ret;
242 	uint mask;
243 
244 	mask = 1 << ldo;
245 
246 	ret = pmic_reg_read(dev->parent, REG_LDO_EN);
247 	if (ret < 0)
248 		return ret;
249 
250 	return ret & mask ? true : false;
251 }
252 
253 static int switch_set_enable(struct udevice *dev, bool enable)
254 {
255 	int sw = dev->driver_data - 1;
256 	uint mask;
257 
258 	mask = 1 << (sw + 5);
259 
260 	return pmic_clrsetbits(dev->parent, REG_DCDC_EN, mask,
261 			       enable ? mask : 0);
262 }
263 
264 static int switch_get_enable(struct udevice *dev)
265 {
266 	int sw = dev->driver_data - 1;
267 	int ret;
268 	uint mask;
269 
270 	mask = 1 << (sw + 5);
271 
272 	ret = pmic_reg_read(dev->parent, REG_DCDC_EN);
273 	if (ret < 0)
274 		return ret;
275 
276 	return ret & mask ? true : false;
277 }
278 
279 static int rk8xx_buck_probe(struct udevice *dev)
280 {
281 	struct dm_regulator_uclass_platdata *uc_pdata;
282 
283 	uc_pdata = dev_get_uclass_platdata(dev);
284 
285 	uc_pdata->type = REGULATOR_TYPE_BUCK;
286 	uc_pdata->mode_count = 0;
287 
288 	return 0;
289 }
290 
291 static int rk8xx_ldo_probe(struct udevice *dev)
292 {
293 	struct dm_regulator_uclass_platdata *uc_pdata;
294 
295 	uc_pdata = dev_get_uclass_platdata(dev);
296 
297 	uc_pdata->type = REGULATOR_TYPE_LDO;
298 	uc_pdata->mode_count = 0;
299 
300 	return 0;
301 }
302 
303 static int rk8xx_switch_probe(struct udevice *dev)
304 {
305 	struct dm_regulator_uclass_platdata *uc_pdata;
306 
307 	uc_pdata = dev_get_uclass_platdata(dev);
308 
309 	uc_pdata->type = REGULATOR_TYPE_FIXED;
310 	uc_pdata->mode_count = 0;
311 
312 	return 0;
313 }
314 
315 static const struct dm_regulator_ops rk8xx_buck_ops = {
316 	.get_value  = buck_get_value,
317 	.set_value  = buck_set_value,
318 	.get_enable = buck_get_enable,
319 	.set_enable = buck_set_enable,
320 };
321 
322 static const struct dm_regulator_ops rk8xx_ldo_ops = {
323 	.get_value  = ldo_get_value,
324 	.set_value  = ldo_set_value,
325 	.get_enable = ldo_get_enable,
326 	.set_enable = ldo_set_enable,
327 };
328 
329 static const struct dm_regulator_ops rk8xx_switch_ops = {
330 	.get_enable = switch_get_enable,
331 	.set_enable = switch_set_enable,
332 };
333 
334 U_BOOT_DRIVER(rk8xx_buck) = {
335 	.name = "rk8xx_buck",
336 	.id = UCLASS_REGULATOR,
337 	.ops = &rk8xx_buck_ops,
338 	.probe = rk8xx_buck_probe,
339 };
340 
341 U_BOOT_DRIVER(rk8xx_ldo) = {
342 	.name = "rk8xx_ldo",
343 	.id = UCLASS_REGULATOR,
344 	.ops = &rk8xx_ldo_ops,
345 	.probe = rk8xx_ldo_probe,
346 };
347 
348 U_BOOT_DRIVER(rk8xx_switch) = {
349 	.name = "rk8xx_switch",
350 	.id = UCLASS_REGULATOR,
351 	.ops = &rk8xx_switch_ops,
352 	.probe = rk8xx_switch_probe,
353 };
354 #endif
355 
356 int rk8xx_spl_configure_buck(struct udevice *pmic, int buck, int uvolt)
357 {
358 	int ret;
359 
360 	ret = _buck_set_value(pmic, buck, uvolt);
361 	if (ret)
362 		return ret;
363 
364 	return _buck_set_enable(pmic, buck, true);
365 }
366 
367 int rk818_spl_configure_usb_input_current(struct udevice *pmic, int current_ma)
368 {
369 	uint i;
370 
371 	for (i = 0; i < ARRAY_SIZE(rk818_chrg_cur_input_array); i++)
372 		if (current_ma <= rk818_chrg_cur_input_array[i])
373 			break;
374 
375 	return pmic_clrsetbits(pmic, REG_USB_CTRL, RK818_USB_ILIM_SEL_MASK, i);
376 }
377 
378 int rk818_spl_configure_usb_chrg_shutdown(struct udevice *pmic, int uvolt)
379 {
380 	uint i;
381 
382 	for (i = 0; i < ARRAY_SIZE(rk818_chrg_shutdown_vsel_array); i++)
383 		if (uvolt <= rk818_chrg_shutdown_vsel_array[i])
384 			break;
385 
386 	return pmic_clrsetbits(pmic, REG_USB_CTRL, RK818_USB_CHG_SD_VSEL_MASK,
387 			       i);
388 }
389