xref: /openbmc/u-boot/drivers/power/regulator/palmas_regulator.c (revision d024236e5a31a2b4b82cbcc98b31b8170fc88d28)
1 /*
2  * (C) Copyright 2016
3  * Texas Instruments Incorporated, <www.ti.com>
4  *
5  * Keerthy <j-keerthy@ti.com>
6  *
7  * SPDX-License-Identifier:	GPL-2.0+
8  */
9 
10 #include <common.h>
11 #include <fdtdec.h>
12 #include <errno.h>
13 #include <dm.h>
14 #include <i2c.h>
15 #include <power/pmic.h>
16 #include <power/regulator.h>
17 #include <power/palmas.h>
18 
19 #define	REGULATOR_ON		0x1
20 #define	REGULATOR_OFF		0x0
21 
22 #define	SMPS_MODE_MASK		0x3
23 #define	SMPS_MODE_SHIFT		0x0
24 #define	LDO_MODE_MASK		0x1
25 #define	LDO_MODE_SHIFT		0x0
26 
27 static const char palmas_smps_ctrl[][PALMAS_SMPS_NUM] = {
28 	{0x20, 0x24, 0x28, 0x2c, 0x30, 0x34, 0x38, 0x3c},
29 	{0x20, 0x24, 0x28, 0x2c, 0x30, 0x34, 0x38},
30 	{0x20, 0x24, 0x2c, 0x30, 0x38},
31 };
32 
33 static const char palmas_smps_volt[][PALMAS_SMPS_NUM] = {
34 	{0x23, 0x27, 0x2b, 0x2f, 0x33, 0x37, 0x3b, 0x3c},
35 	{0x23, 0x27, 0x2b, 0x2f, 0x33, 0x37, 0x3b},
36 	{0x23, 0x27, 0x2f, 0x33, 0x3B}
37 };
38 
39 static const char palmas_ldo_ctrl[][PALMAS_LDO_NUM] = {
40 	{0x50, 0x52, 0x54, 0x56, 0x58, 0x5a, 0x5c, 0x5e, 0x60, 0x62, 0x64},
41 	{0x50, 0x52, 0x54, 0x56, 0x58, 0x5a, 0x5c, 0x5e, 0x60, 0x62, 0x64},
42 	{0x50, 0x52, 0x54, 0x5e, 0x62}
43 };
44 
45 static const char palmas_ldo_volt[][PALMAS_LDO_NUM] = {
46 	{0x51, 0x53, 0x55, 0x57, 0x59, 0x5b, 0x5d, 0x5f, 0x61, 0x63, 0x65},
47 	{0x51, 0x53, 0x55, 0x57, 0x59, 0x5b, 0x5d, 0x5f, 0x61, 0x63, 0x65},
48 	{0x51, 0x53, 0x55, 0x5f, 0x63}
49 };
50 
51 static int palmas_smps_enable(struct udevice *dev, int op, bool *enable)
52 {
53 	int ret;
54 	unsigned int adr;
55 	struct dm_regulator_uclass_platdata *uc_pdata;
56 
57 	uc_pdata = dev_get_uclass_platdata(dev);
58 	adr = uc_pdata->ctrl_reg;
59 
60 	ret = pmic_reg_read(dev->parent, adr);
61 		if (ret < 0)
62 			return ret;
63 
64 	if (op == PMIC_OP_GET) {
65 		ret &= PALMAS_SMPS_STATUS_MASK;
66 
67 		if (ret)
68 			*enable = true;
69 		else
70 			*enable = false;
71 
72 		return 0;
73 	} else if (op == PMIC_OP_SET) {
74 		if (*enable)
75 			ret |= PALMAS_SMPS_MODE_MASK;
76 		else
77 			ret &= ~(PALMAS_SMPS_MODE_MASK);
78 
79 		ret = pmic_reg_write(dev->parent, adr, ret);
80 		if (ret)
81 			return ret;
82 	}
83 
84 	return 0;
85 }
86 
87 static int palmas_smps_volt2hex(int uV)
88 {
89 	if (uV > PALMAS_LDO_VOLT_MAX)
90 		return -EINVAL;
91 
92 	if (uV > 1650000)
93 		return (uV - 1000000) / 20000 + 0x6;
94 
95 	if (uV == 500000)
96 		return 0x6;
97 	else
98 		return 0x6 + ((uV - 500000) / 10000);
99 }
100 
101 static int palmas_smps_hex2volt(int hex, bool range)
102 {
103 	unsigned int uV = 0;
104 
105 	if (hex > PALMAS_SMPS_VOLT_MAX_HEX)
106 		return -EINVAL;
107 
108 	if (hex < 0x7)
109 		uV = 500000;
110 	else
111 		uV = 500000 + (hex - 0x6) * 10000;
112 
113 	if (range)
114 		uV *= 2;
115 
116 	return uV;
117 }
118 
119 static int palmas_smps_val(struct udevice *dev, int op, int *uV)
120 {
121 	unsigned int hex, adr;
122 	int ret;
123 	bool range;
124 	struct dm_regulator_uclass_platdata *uc_pdata;
125 
126 	uc_pdata = dev_get_uclass_platdata(dev);
127 
128 	if (op == PMIC_OP_GET)
129 		*uV = 0;
130 
131 	adr = uc_pdata->volt_reg;
132 
133 	ret = pmic_reg_read(dev->parent, adr);
134 	if (ret < 0)
135 		return ret;
136 
137 	if (op == PMIC_OP_GET) {
138 		if (ret & PALMAS_SMPS_RANGE_MASK)
139 			range =  true;
140 		else
141 			range = false;
142 
143 		ret &= PALMAS_SMPS_VOLT_MASK;
144 		ret = palmas_smps_hex2volt(ret, range);
145 		if (ret < 0)
146 			return ret;
147 		*uV = ret;
148 
149 		return 0;
150 	}
151 
152 	hex = palmas_smps_volt2hex(*uV);
153 	if (hex < 0)
154 		return hex;
155 
156 	ret &= ~PALMAS_SMPS_VOLT_MASK;
157 	ret |= hex;
158 	if (*uV > 1650000)
159 		ret |= PALMAS_SMPS_RANGE_MASK;
160 
161 	return pmic_reg_write(dev->parent, adr, ret);
162 }
163 
164 static int palmas_ldo_bypass_enable(struct udevice *dev, bool enabled)
165 {
166 	int type = dev_get_driver_data(dev_get_parent(dev));
167 	struct dm_regulator_uclass_platdata *p;
168 	unsigned int adr;
169 	int reg;
170 
171 	if (type == TPS65917) {
172 		/* bypass available only on LDO1 and LDO2 */
173 		if (dev->driver_data > 2)
174 			return -ENOTSUPP;
175 	} else if (type == TPS659038) {
176 		/* bypass available only on LDO9 */
177 		if (dev->driver_data != 9)
178 			return -ENOTSUPP;
179 	}
180 
181 	p = dev_get_uclass_platdata(dev);
182 	adr = p->ctrl_reg;
183 
184 	reg = pmic_reg_read(dev->parent, adr);
185 	if (reg < 0)
186 		return reg;
187 
188 	if (enabled)
189 		reg |= PALMAS_LDO_BYPASS_EN;
190 	else
191 		reg &= ~PALMAS_LDO_BYPASS_EN;
192 
193 	return pmic_reg_write(dev->parent, adr, reg);
194 }
195 
196 static int palmas_ldo_enable(struct udevice *dev, int op, bool *enable)
197 {
198 	int ret;
199 	unsigned int adr;
200 	struct dm_regulator_uclass_platdata *uc_pdata;
201 
202 	uc_pdata = dev_get_uclass_platdata(dev);
203 	adr = uc_pdata->ctrl_reg;
204 
205 	ret = pmic_reg_read(dev->parent, adr);
206 		if (ret < 0)
207 			return ret;
208 
209 	if (op == PMIC_OP_GET) {
210 		ret &= PALMAS_LDO_STATUS_MASK;
211 
212 		if (ret)
213 			*enable = true;
214 		else
215 			*enable = false;
216 
217 		return 0;
218 	} else if (op == PMIC_OP_SET) {
219 		if (*enable)
220 			ret |= PALMAS_LDO_MODE_MASK;
221 		else
222 			ret &= ~(PALMAS_LDO_MODE_MASK);
223 
224 		ret = pmic_reg_write(dev->parent, adr, ret);
225 		if (ret)
226 			return ret;
227 
228 		ret = palmas_ldo_bypass_enable(dev, false);
229 		if (ret && (ret != -ENOTSUPP))
230 			return ret;
231 	}
232 
233 	return 0;
234 }
235 
236 static int palmas_ldo_volt2hex(int uV)
237 {
238 	if (uV > PALMAS_LDO_VOLT_MAX)
239 		return -EINVAL;
240 
241 	return (uV - 850000) / 50000;
242 }
243 
244 static int palmas_ldo_hex2volt(int hex)
245 {
246 	if (hex > PALMAS_LDO_VOLT_MAX_HEX)
247 		return -EINVAL;
248 
249 	if (!hex)
250 		return 0;
251 
252 	return (hex * 50000) + 850000;
253 }
254 
255 static int palmas_ldo_val(struct udevice *dev, int op, int *uV)
256 {
257 	unsigned int hex, adr;
258 	int ret;
259 
260 	struct dm_regulator_uclass_platdata *uc_pdata;
261 
262 	if (op == PMIC_OP_GET)
263 		*uV = 0;
264 
265 	uc_pdata = dev_get_uclass_platdata(dev);
266 
267 	adr = uc_pdata->volt_reg;
268 
269 	ret = pmic_reg_read(dev->parent, adr);
270 	if (ret < 0)
271 		return ret;
272 
273 	if (op == PMIC_OP_GET) {
274 		ret &= PALMAS_LDO_VOLT_MASK;
275 		ret = palmas_ldo_hex2volt(ret);
276 		if (ret < 0)
277 			return ret;
278 		*uV = ret;
279 		return 0;
280 	}
281 
282 	hex = palmas_ldo_volt2hex(*uV);
283 	if (hex < 0)
284 		return hex;
285 
286 	ret &= ~PALMAS_LDO_VOLT_MASK;
287 	ret |= hex;
288 	if (*uV > 1650000)
289 		ret |= 0x80;
290 
291 	return pmic_reg_write(dev->parent, adr, ret);
292 }
293 
294 static int palmas_ldo_probe(struct udevice *dev)
295 {
296 	struct dm_regulator_uclass_platdata *uc_pdata;
297 	struct udevice *parent;
298 
299 	uc_pdata = dev_get_uclass_platdata(dev);
300 
301 	parent = dev_get_parent(dev);
302 	int type = dev_get_driver_data(parent);
303 
304 	uc_pdata->type = REGULATOR_TYPE_LDO;
305 
306 	if (dev->driver_data) {
307 		u8 idx = dev->driver_data - 1;
308 		uc_pdata->ctrl_reg = palmas_ldo_ctrl[type][idx];
309 		uc_pdata->volt_reg = palmas_ldo_volt[type][idx];
310 	} else {
311 		/* check for ldoln and ldousb cases */
312 		if (!strcmp("ldoln", dev->name)) {
313 			uc_pdata->ctrl_reg = palmas_ldo_ctrl[type][9];
314 			uc_pdata->volt_reg = palmas_ldo_volt[type][9];
315 		} else if (!strcmp("ldousb", dev->name)) {
316 			uc_pdata->ctrl_reg = palmas_ldo_ctrl[type][10];
317 			uc_pdata->volt_reg = palmas_ldo_volt[type][10];
318 		}
319 	}
320 
321 	return 0;
322 }
323 
324 static int ldo_get_value(struct udevice *dev)
325 {
326 	int uV;
327 	int ret;
328 
329 	ret = palmas_ldo_val(dev, PMIC_OP_GET, &uV);
330 	if (ret)
331 		return ret;
332 
333 	return uV;
334 }
335 
336 static int ldo_set_value(struct udevice *dev, int uV)
337 {
338 	return palmas_ldo_val(dev, PMIC_OP_SET, &uV);
339 }
340 
341 static int ldo_get_enable(struct udevice *dev)
342 {
343 	bool enable = false;
344 	int ret;
345 
346 	ret = palmas_ldo_enable(dev, PMIC_OP_GET, &enable);
347 	if (ret)
348 		return ret;
349 
350 	return enable;
351 }
352 
353 static int ldo_set_enable(struct udevice *dev, bool enable)
354 {
355 	return palmas_ldo_enable(dev, PMIC_OP_SET, &enable);
356 }
357 
358 static int palmas_smps_probe(struct udevice *dev)
359 {
360 	struct dm_regulator_uclass_platdata *uc_pdata;
361 	struct udevice *parent;
362 	int idx;
363 
364 	uc_pdata = dev_get_uclass_platdata(dev);
365 
366 	parent = dev_get_parent(dev);
367 	int type = dev_get_driver_data(parent);
368 
369 	uc_pdata->type = REGULATOR_TYPE_BUCK;
370 
371 	switch (type) {
372 	case PALMAS:
373 	case TPS659038:
374 		switch (dev->driver_data) {
375 		case 123:
376 		case 12:
377 			uc_pdata->ctrl_reg = palmas_smps_ctrl[type][0];
378 			uc_pdata->volt_reg = palmas_smps_volt[type][0];
379 			break;
380 		case 3:
381 			uc_pdata->ctrl_reg = palmas_smps_ctrl[type][1];
382 			uc_pdata->volt_reg = palmas_smps_volt[type][1];
383 			break;
384 		case 45:
385 			uc_pdata->ctrl_reg = palmas_smps_ctrl[type][2];
386 			uc_pdata->volt_reg = palmas_smps_volt[type][2];
387 			break;
388 		case 6:
389 		case 7:
390 		case 8:
391 		case 9:
392 		case 10:
393 			idx = dev->driver_data - 3;
394 			uc_pdata->ctrl_reg = palmas_smps_ctrl[type][idx];
395 			uc_pdata->volt_reg = palmas_smps_volt[type][idx];
396 			break;
397 
398 		default:
399 			printf("Wrong ID for regulator\n");
400 		}
401 		break;
402 
403 	case TPS65917:
404 		switch (dev->driver_data) {
405 		case 1:
406 		case 2:
407 		case 3:
408 		case 4:
409 		case 5:
410 			idx = dev->driver_data - 1;
411 			uc_pdata->ctrl_reg = palmas_smps_ctrl[type][idx];
412 			uc_pdata->volt_reg = palmas_smps_volt[type][idx];
413 			break;
414 		case 12:
415 			idx = 0;
416 			uc_pdata->ctrl_reg = palmas_smps_ctrl[type][idx];
417 			uc_pdata->volt_reg = palmas_smps_volt[type][idx];
418 			break;
419 		default:
420 			printf("Wrong ID for regulator\n");
421 		}
422 		break;
423 
424 	default:
425 			printf("Invalid PMIC ID\n");
426 	}
427 
428 	return 0;
429 }
430 
431 static int smps_get_value(struct udevice *dev)
432 {
433 	int uV;
434 	int ret;
435 
436 	ret = palmas_smps_val(dev, PMIC_OP_GET, &uV);
437 	if (ret)
438 		return ret;
439 
440 	return uV;
441 }
442 
443 static int smps_set_value(struct udevice *dev, int uV)
444 {
445 	return palmas_smps_val(dev, PMIC_OP_SET, &uV);
446 }
447 
448 static int smps_get_enable(struct udevice *dev)
449 {
450 	bool enable = false;
451 	int ret;
452 
453 	ret = palmas_smps_enable(dev, PMIC_OP_GET, &enable);
454 	if (ret)
455 		return ret;
456 
457 	return enable;
458 }
459 
460 static int smps_set_enable(struct udevice *dev, bool enable)
461 {
462 	return palmas_smps_enable(dev, PMIC_OP_SET, &enable);
463 }
464 
465 static const struct dm_regulator_ops palmas_ldo_ops = {
466 	.get_value  = ldo_get_value,
467 	.set_value  = ldo_set_value,
468 	.get_enable = ldo_get_enable,
469 	.set_enable = ldo_set_enable,
470 };
471 
472 U_BOOT_DRIVER(palmas_ldo) = {
473 	.name = PALMAS_LDO_DRIVER,
474 	.id = UCLASS_REGULATOR,
475 	.ops = &palmas_ldo_ops,
476 	.probe = palmas_ldo_probe,
477 };
478 
479 static const struct dm_regulator_ops palmas_smps_ops = {
480 	.get_value  = smps_get_value,
481 	.set_value  = smps_set_value,
482 	.get_enable = smps_get_enable,
483 	.set_enable = smps_set_enable,
484 };
485 
486 U_BOOT_DRIVER(palmas_smps) = {
487 	.name = PALMAS_SMPS_DRIVER,
488 	.id = UCLASS_REGULATOR,
489 	.ops = &palmas_smps_ops,
490 	.probe = palmas_smps_probe,
491 };
492