xref: /openbmc/u-boot/drivers/power/regulator/s2mps11_regulator.c (revision d024236e5a31a2b4b82cbcc98b31b8170fc88d28)
1 /*
2  *  Copyright (C) 2018 Samsung Electronics
3  *  Jaehoon Chung <jh80.chung@samsung.com>
4  *
5  * SPDX-License-Identifier:	GPL-2.0
6  */
7 
8 #include <common.h>
9 #include <fdtdec.h>
10 #include <errno.h>
11 #include <dm.h>
12 #include <i2c.h>
13 #include <power/pmic.h>
14 #include <power/regulator.h>
15 #include <power/s2mps11.h>
16 
17 #define MODE(_id, _val, _name) { \
18 	.id = _id, \
19 	.register_value = _val, \
20 	.name = _name, \
21 }
22 
23 /* BUCK : 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 */
24 static struct dm_regulator_mode s2mps11_buck_modes[] = {
25 	MODE(OP_OFF, S2MPS11_BUCK_MODE_OFF, "OFF"),
26 	MODE(OP_STANDBY, S2MPS11_BUCK_MODE_STANDBY, "ON/OFF"),
27 	MODE(OP_ON, S2MPS11_BUCK_MODE_STANDBY, "ON"),
28 };
29 
30 static struct dm_regulator_mode s2mps11_ldo_modes[] = {
31 	MODE(OP_OFF, S2MPS11_LDO_MODE_OFF, "OFF"),
32 	MODE(OP_STANDBY, S2MPS11_LDO_MODE_STANDBY, "ON/OFF"),
33 	MODE(OP_STANDBY_LPM, S2MPS11_LDO_MODE_STANDBY_LPM, "ON/LPM"),
34 	MODE(OP_ON, S2MPS11_LDO_MODE_ON, "ON"),
35 };
36 
37 static const char s2mps11_buck_ctrl[] = {
38 	0xff, 0x25, 0x27, 0x29, 0x2b, 0x2d, 0x33, 0x35, 0x37, 0x39, 0x3b
39 };
40 
41 static const char s2mps11_buck_out[] = {
42 	0xff, 0x26, 0x28, 0x2a, 0x2c, 0x2f, 0x34, 0x36, 0x38, 0x3a, 0x3c
43 };
44 
45 static int s2mps11_buck_hex2volt(int buck, int hex)
46 {
47 	unsigned int uV = 0;
48 
49 	if (hex < 0)
50 		goto bad;
51 
52 	switch (buck) {
53 	case 7:
54 	case 8:
55 	case 10:
56 		if (hex > S2MPS11_BUCK7_8_10_VOLT_MAX_HEX)
57 			goto bad;
58 
59 		uV = hex * S2MPS11_BUCK_HSTEP + S2MPS11_BUCK_UV_HMIN;
60 		break;
61 	case 9:
62 		if (hex > S2MPS11_BUCK9_VOLT_MAX_HEX)
63 			goto bad;
64 		uV = hex * S2MPS11_BUCK9_STEP * 2 + S2MPS11_BUCK9_UV_MIN;
65 		break;
66 	default:
67 		if (buck == 5 && hex > S2MPS11_BUCK5_VOLT_MAX_HEX)
68 			goto bad;
69 		else if (buck != 5 && hex > S2MPS11_BUCK_VOLT_MAX_HEX)
70 			goto bad;
71 
72 		uV = hex * S2MPS11_BUCK_LSTEP + S2MPS11_BUCK_UV_MIN;
73 		break;
74 	}
75 
76 	return uV;
77 bad:
78 	pr_err("Value: %#x is wrong for BUCK%d", hex, buck);
79 	return -EINVAL;
80 }
81 
82 static int s2mps11_buck_volt2hex(int buck, int uV)
83 {
84 	int hex;
85 
86 	switch (buck) {
87 	case 7:
88 	case 8:
89 	case 10:
90 		hex = (uV - S2MPS11_BUCK_UV_HMIN) / S2MPS11_BUCK_HSTEP;
91 		if (hex > S2MPS11_BUCK7_8_10_VOLT_MAX_HEX)
92 			goto bad;
93 
94 		break;
95 	case 9:
96 		hex = (uV - S2MPS11_BUCK9_UV_MIN) / S2MPS11_BUCK9_STEP;
97 		if (hex > S2MPS11_BUCK9_VOLT_MAX_HEX)
98 			goto bad;
99 		break;
100 	default:
101 		hex = (uV - S2MPS11_BUCK_UV_MIN) / S2MPS11_BUCK_LSTEP;
102 		if (buck == 5 && hex > S2MPS11_BUCK5_VOLT_MAX_HEX)
103 			goto bad;
104 		else if (buck != 5 && hex > S2MPS11_BUCK_VOLT_MAX_HEX)
105 			goto bad;
106 		break;
107 	};
108 
109 	if (hex >= 0)
110 		return hex;
111 
112 bad:
113 	pr_err("Value: %d uV is wrong for BUCK%d", uV, buck);
114 	return -EINVAL;
115 }
116 
117 static int s2mps11_buck_val(struct udevice *dev, int op, int *uV)
118 {
119 	int hex, buck, ret;
120 	u32 mask, addr;
121 	u8 val;
122 
123 	buck = dev->driver_data;
124 	if (buck < 1 || buck > S2MPS11_BUCK_NUM) {
125 		pr_err("Wrong buck number: %d\n", buck);
126 		return -EINVAL;
127 	}
128 
129 	if (op == PMIC_OP_GET)
130 		*uV = 0;
131 
132 	addr = s2mps11_buck_out[buck];
133 
134 	switch (buck) {
135 	case 9:
136 		mask = S2MPS11_BUCK9_VOLT_MASK;
137 		break;
138 	default:
139 		mask = S2MPS11_BUCK_VOLT_MASK;
140 		break;
141 	}
142 
143 	ret = pmic_read(dev->parent, addr, &val, 1);
144 	if (ret)
145 		return ret;
146 
147 	if (op == PMIC_OP_GET) {
148 		val &= mask;
149 		ret = s2mps11_buck_hex2volt(buck, val);
150 		if (ret < 0)
151 			return ret;
152 		*uV = ret;
153 		return 0;
154 	}
155 
156 	hex = s2mps11_buck_volt2hex(buck, *uV);
157 	if (hex < 0)
158 		return hex;
159 
160 	val &= ~mask;
161 	val |= hex;
162 	ret = pmic_write(dev->parent, addr, &val, 1);
163 
164 	return ret;
165 }
166 
167 static int s2mps11_buck_mode(struct udevice *dev, int op, int *opmode)
168 {
169 	unsigned int addr, mode;
170 	unsigned char val;
171 	int buck, ret;
172 
173 	buck = dev->driver_data;
174 	if (buck < 1 || buck > S2MPS11_BUCK_NUM) {
175 		pr_err("Wrong buck number: %d\n", buck);
176 		return -EINVAL;
177 	}
178 
179 	addr = s2mps11_buck_ctrl[buck];
180 
181 	ret = pmic_read(dev->parent, addr, &val, 1);
182 	if (ret)
183 		return ret;
184 
185 	if (op == PMIC_OP_GET) {
186 		val &= (S2MPS11_BUCK_MODE_MASK << S2MPS11_BUCK_MODE_SHIFT);
187 		switch (val) {
188 		case S2MPS11_BUCK_MODE_OFF:
189 			*opmode = OP_OFF;
190 			break;
191 		case S2MPS11_BUCK_MODE_STANDBY:
192 			*opmode = OP_STANDBY;
193 			break;
194 		case S2MPS11_BUCK_MODE_ON:
195 			*opmode = OP_ON;
196 			break;
197 		default:
198 			return -EINVAL;
199 		}
200 		return 0;
201 	}
202 
203 	switch (*opmode) {
204 	case OP_OFF:
205 		mode = S2MPS11_BUCK_MODE_OFF;
206 		break;
207 	case OP_STANDBY:
208 		mode = S2MPS11_BUCK_MODE_STANDBY;
209 		break;
210 	case OP_ON:
211 		mode = S2MPS11_BUCK_MODE_ON;
212 		break;
213 	default:
214 		pr_err("Wrong mode: %d for buck: %d\n", *opmode, buck);
215 		return -EINVAL;
216 	}
217 
218 	val &= ~(S2MPS11_BUCK_MODE_MASK << S2MPS11_BUCK_MODE_SHIFT);
219 	val |= mode;
220 	ret = pmic_write(dev->parent, addr, &val, 1);
221 
222 	return ret;
223 }
224 
225 static int s2mps11_buck_enable(struct udevice *dev, int op, bool *enable)
226 {
227 	int ret, on_off;
228 
229 	if (op == PMIC_OP_GET) {
230 		ret = s2mps11_buck_mode(dev, op, &on_off);
231 		if (ret)
232 			return ret;
233 		switch (on_off) {
234 		case OP_OFF:
235 			*enable = false;
236 			break;
237 		case OP_ON:
238 			*enable = true;
239 			break;
240 		default:
241 			return -EINVAL;
242 		}
243 	} else if (op == PMIC_OP_SET) {
244 		if (*enable)
245 			on_off = OP_ON;
246 		else
247 			on_off = OP_OFF;
248 
249 		ret = s2mps11_buck_mode(dev, op, &on_off);
250 		if (ret)
251 			return ret;
252 	}
253 
254 	return 0;
255 }
256 
257 static int buck_get_value(struct udevice *dev)
258 {
259 	int uV;
260 	int ret;
261 
262 	ret = s2mps11_buck_val(dev, PMIC_OP_GET, &uV);
263 	if (ret)
264 		return ret;
265 	return uV;
266 }
267 
268 static int buck_set_value(struct udevice *dev, int uV)
269 {
270 	return s2mps11_buck_val(dev, PMIC_OP_SET, &uV);
271 }
272 
273 static int buck_get_enable(struct udevice *dev)
274 {
275 	bool enable = false;
276 	int ret;
277 
278 	ret = s2mps11_buck_enable(dev, PMIC_OP_GET, &enable);
279 	if (ret)
280 		return ret;
281 	return enable;
282 }
283 
284 static int buck_set_enable(struct udevice *dev, bool enable)
285 {
286 	return s2mps11_buck_enable(dev, PMIC_OP_SET, &enable);
287 }
288 
289 static int buck_get_mode(struct udevice *dev)
290 {
291 	int mode;
292 	int ret;
293 
294 	ret = s2mps11_buck_mode(dev, PMIC_OP_GET, &mode);
295 	if (ret)
296 		return ret;
297 
298 	return mode;
299 }
300 
301 static int buck_set_mode(struct udevice *dev, int mode)
302 {
303 	return s2mps11_buck_mode(dev, PMIC_OP_SET, &mode);
304 }
305 
306 static int s2mps11_buck_probe(struct udevice *dev)
307 {
308 	struct dm_regulator_uclass_platdata *uc_pdata;
309 
310 	uc_pdata = dev_get_uclass_platdata(dev);
311 
312 	uc_pdata->type = REGULATOR_TYPE_BUCK;
313 	uc_pdata->mode = s2mps11_buck_modes;
314 	uc_pdata->mode_count = ARRAY_SIZE(s2mps11_buck_modes);
315 
316 	return 0;
317 }
318 
319 static const struct dm_regulator_ops s2mps11_buck_ops = {
320 	.get_value	= buck_get_value,
321 	.set_value	= buck_set_value,
322 	.get_enable	= buck_get_enable,
323 	.set_enable	= buck_set_enable,
324 	.get_mode	= buck_get_mode,
325 	.set_mode	= buck_set_mode,
326 };
327 
328 U_BOOT_DRIVER(s2mps11_buck) = {
329 	.name = S2MPS11_BUCK_DRIVER,
330 	.id = UCLASS_REGULATOR,
331 	.ops = &s2mps11_buck_ops,
332 	.probe = s2mps11_buck_probe,
333 };
334 
335 static int s2mps11_ldo_hex2volt(int ldo, int hex)
336 {
337 	unsigned int uV = 0;
338 
339 	if (hex > S2MPS11_LDO_VOLT_MAX_HEX) {
340 		pr_err("Value: %#x is wrong for LDO%d", hex, ldo);
341 		return -EINVAL;
342 	}
343 
344 	switch (ldo) {
345 	case 1:
346 	case 6:
347 	case 11:
348 	case 22:
349 	case 23:
350 		uV = hex * S2MPS11_LDO_STEP + S2MPS11_LDO_UV_MIN;
351 		break;
352 	default:
353 		uV = hex * S2MPS11_LDO_STEP * 2 + S2MPS11_LDO_UV_MIN;
354 		break;
355 	}
356 
357 	return uV;
358 }
359 
360 static int s2mps11_ldo_volt2hex(int ldo, int uV)
361 {
362 	int hex = 0;
363 
364 	switch (ldo) {
365 	case 1:
366 	case 6:
367 	case 11:
368 	case 22:
369 	case 23:
370 		hex = (uV - S2MPS11_LDO_UV_MIN) / S2MPS11_LDO_STEP;
371 		break;
372 	default:
373 		hex = (uV - S2MPS11_LDO_UV_MIN) / (S2MPS11_LDO_STEP * 2);
374 		break;
375 	}
376 
377 	if (hex >= 0 && hex <= S2MPS11_LDO_VOLT_MAX_HEX)
378 		return hex;
379 
380 	pr_err("Value: %d uV is wrong for LDO%d", uV, ldo);
381 	return -EINVAL;
382 
383 	return 0;
384 }
385 
386 static int s2mps11_ldo_val(struct udevice *dev, int op, int *uV)
387 {
388 	unsigned int addr;
389 	unsigned char val;
390 	int hex, ldo, ret;
391 
392 	ldo = dev->driver_data;
393 	if (ldo < 1 || ldo > S2MPS11_LDO_NUM) {
394 		pr_err("Wrong ldo number: %d\n", ldo);
395 		return -EINVAL;
396 	}
397 
398 	addr = S2MPS11_REG_L1CTRL + ldo - 1;
399 
400 	ret = pmic_read(dev->parent, addr, &val, 1);
401 	if (ret)
402 		return ret;
403 
404 	if (op == PMIC_OP_GET) {
405 		*uV = 0;
406 		val &= S2MPS11_LDO_VOLT_MASK;
407 		ret = s2mps11_ldo_hex2volt(ldo, val);
408 		if (ret < 0)
409 			return ret;
410 
411 		*uV = ret;
412 		return 0;
413 	}
414 
415 	hex = s2mps11_ldo_volt2hex(ldo, *uV);
416 	if (hex < 0)
417 		return hex;
418 
419 	val &= ~S2MPS11_LDO_VOLT_MASK;
420 	val |= hex;
421 	ret = pmic_write(dev->parent, addr, &val, 1);
422 
423 	return ret;
424 }
425 
426 static int s2mps11_ldo_mode(struct udevice *dev, int op, int *opmode)
427 {
428 	unsigned int addr, mode;
429 	unsigned char val;
430 	int ldo, ret;
431 
432 	ldo = dev->driver_data;
433 	if (ldo < 1 || ldo > S2MPS11_LDO_NUM) {
434 		pr_err("Wrong ldo number: %d\n", ldo);
435 		return -EINVAL;
436 	}
437 	addr = S2MPS11_REG_L1CTRL + ldo - 1;
438 
439 	ret = pmic_read(dev->parent, addr, &val, 1);
440 	if (ret)
441 		return ret;
442 
443 	if (op == PMIC_OP_GET) {
444 		val &= (S2MPS11_LDO_MODE_MASK << S2MPS11_LDO_MODE_SHIFT);
445 		switch (val) {
446 		case S2MPS11_LDO_MODE_OFF:
447 			*opmode = OP_OFF;
448 			break;
449 		case S2MPS11_LDO_MODE_STANDBY:
450 			*opmode = OP_STANDBY;
451 			break;
452 		case S2MPS11_LDO_MODE_STANDBY_LPM:
453 			*opmode = OP_STANDBY_LPM;
454 			break;
455 		case S2MPS11_LDO_MODE_ON:
456 			*opmode = OP_ON;
457 			break;
458 		default:
459 			return -EINVAL;
460 		}
461 		return 0;
462 	}
463 
464 	switch (*opmode) {
465 	case OP_OFF:
466 		mode = S2MPS11_LDO_MODE_OFF;
467 		break;
468 	case OP_STANDBY:
469 		mode = S2MPS11_LDO_MODE_STANDBY;
470 		break;
471 	case OP_STANDBY_LPM:
472 		mode = S2MPS11_LDO_MODE_STANDBY_LPM;
473 		break;
474 	case OP_ON:
475 		mode = S2MPS11_LDO_MODE_ON;
476 		break;
477 	default:
478 		pr_err("Wrong mode: %d for ldo: %d\n", *opmode, ldo);
479 		return -EINVAL;
480 	}
481 
482 	val &= ~(S2MPS11_LDO_MODE_MASK << S2MPS11_LDO_MODE_SHIFT);
483 	val |= mode;
484 	ret = pmic_write(dev->parent, addr, &val, 1);
485 
486 	return ret;
487 }
488 
489 static int s2mps11_ldo_enable(struct udevice *dev, int op, bool *enable)
490 {
491 	int ret, on_off;
492 
493 	if (op == PMIC_OP_GET) {
494 		ret = s2mps11_ldo_mode(dev, op, &on_off);
495 		if (ret)
496 			return ret;
497 		switch (on_off) {
498 		case OP_OFF:
499 			*enable = false;
500 			break;
501 		case OP_ON:
502 			*enable = true;
503 			break;
504 		default:
505 			return -EINVAL;
506 		}
507 	} else if (op == PMIC_OP_SET) {
508 		if (*enable)
509 			on_off = OP_ON;
510 		else
511 			on_off = OP_OFF;
512 
513 		ret = s2mps11_ldo_mode(dev, op, &on_off);
514 		if (ret)
515 			return ret;
516 	}
517 
518 	return 0;
519 }
520 
521 static int ldo_get_value(struct udevice *dev)
522 {
523 	int uV;
524 	int ret;
525 
526 	ret = s2mps11_ldo_val(dev, PMIC_OP_GET, &uV);
527 	if (ret)
528 		return ret;
529 
530 	return uV;
531 }
532 
533 static int ldo_set_value(struct udevice *dev, int uV)
534 {
535 	return s2mps11_ldo_val(dev, PMIC_OP_SET, &uV);
536 }
537 
538 static int ldo_get_enable(struct udevice *dev)
539 {
540 	bool enable = false;
541 	int ret;
542 
543 	ret = s2mps11_ldo_enable(dev, PMIC_OP_GET, &enable);
544 	if (ret)
545 		return ret;
546 	return enable;
547 }
548 
549 static int ldo_set_enable(struct udevice *dev, bool enable)
550 {
551 	return s2mps11_ldo_enable(dev, PMIC_OP_SET, &enable);
552 }
553 
554 static int ldo_get_mode(struct udevice *dev)
555 {
556 	int mode, ret;
557 
558 	ret = s2mps11_ldo_mode(dev, PMIC_OP_GET, &mode);
559 	if (ret)
560 		return ret;
561 	return mode;
562 }
563 
564 static int ldo_set_mode(struct udevice *dev, int mode)
565 {
566 	return s2mps11_ldo_mode(dev, PMIC_OP_SET, &mode);
567 }
568 
569 static int s2mps11_ldo_probe(struct udevice *dev)
570 {
571 	struct dm_regulator_uclass_platdata *uc_pdata;
572 
573 	uc_pdata = dev_get_uclass_platdata(dev);
574 	uc_pdata->type = REGULATOR_TYPE_LDO;
575 	uc_pdata->mode = s2mps11_ldo_modes;
576 	uc_pdata->mode_count = ARRAY_SIZE(s2mps11_ldo_modes);
577 
578 	return 0;
579 }
580 
581 static const struct dm_regulator_ops s2mps11_ldo_ops = {
582 	.get_value	= ldo_get_value,
583 	.set_value	= ldo_set_value,
584 	.get_enable	= ldo_get_enable,
585 	.set_enable	= ldo_set_enable,
586 	.get_mode	= ldo_get_mode,
587 	.set_mode	= ldo_set_mode,
588 };
589 
590 U_BOOT_DRIVER(s2mps11_ldo) = {
591 	.name = S2MPS11_LDO_DRIVER,
592 	.id = UCLASS_REGULATOR,
593 	.ops = &s2mps11_ldo_ops,
594 	.probe = s2mps11_ldo_probe,
595 };
596