1// SPDX-License-Identifier: GPL-2.0+
2/*
3 *  Copyright (C) 2012-2015 Samsung Electronics
4 *
5 *  Rajeshwari Shinde <rajeshwari.s@samsung.com>
6 *  Przemyslaw Marczak <p.marczak@samsung.com>
7 */
8
9#include <common.h>
10#include <fdtdec.h>
11#include <errno.h>
12#include <dm.h>
13#include <linux/printk.h>
14#include <power/pmic.h>
15#include <power/regulator.h>
16#include <power/max77686_pmic.h>
17
18#define MODE(_id, _val, _name) { \
19	.id = _id, \
20	.register_value = _val, \
21	.name = _name, \
22}
23
24/* LDO: 1,3,4,5,9,17,18,19,20,21,22,23,24,26,26,27 */
25static struct dm_regulator_mode max77686_ldo_mode_standby1[] = {
26	MODE(OPMODE_OFF, MAX77686_LDO_MODE_OFF, "OFF"),
27	MODE(OPMODE_LPM, MAX77686_LDO_MODE_LPM, "LPM"),
28	MODE(OPMODE_STANDBY_LPM, MAX77686_LDO_MODE_STANDBY_LPM, "ON/LPM"),
29	MODE(OPMODE_ON, MAX77686_LDO_MODE_ON, "ON"),
30};
31
32/* LDO: 2,6,7,8,10,11,12,14,15,16 */
33static struct dm_regulator_mode max77686_ldo_mode_standby2[] = {
34	MODE(OPMODE_OFF, MAX77686_LDO_MODE_OFF, "OFF"),
35	MODE(OPMODE_STANDBY, MAX77686_LDO_MODE_STANDBY, "ON/OFF"),
36	MODE(OPMODE_STANDBY_LPM, MAX77686_LDO_MODE_STANDBY_LPM, "ON/LPM"),
37	MODE(OPMODE_ON, MAX77686_LDO_MODE_ON, "ON"),
38};
39
40/* Buck: 1 */
41static struct dm_regulator_mode max77686_buck_mode_standby[] = {
42	MODE(OPMODE_OFF, MAX77686_BUCK_MODE_OFF, "OFF"),
43	MODE(OPMODE_STANDBY, MAX77686_BUCK_MODE_STANDBY, "ON/OFF"),
44	MODE(OPMODE_ON, MAX77686_BUCK_MODE_ON, "ON"),
45};
46
47/* Buck: 2,3,4 */
48static struct dm_regulator_mode max77686_buck_mode_lpm[] = {
49	MODE(OPMODE_OFF, MAX77686_BUCK_MODE_OFF, "OFF"),
50	MODE(OPMODE_STANDBY, MAX77686_BUCK_MODE_STANDBY, "ON/OFF"),
51	MODE(OPMODE_LPM, MAX77686_BUCK_MODE_LPM, "LPM"),
52	MODE(OPMODE_ON, MAX77686_BUCK_MODE_ON, "ON"),
53};
54
55/* Buck: 5,6,7,8,9 */
56static struct dm_regulator_mode max77686_buck_mode_onoff[] = {
57	MODE(OPMODE_OFF, MAX77686_BUCK_MODE_OFF, "OFF"),
58	MODE(OPMODE_ON, MAX77686_BUCK_MODE_ON, "ON"),
59};
60
61static const char max77686_buck_ctrl[] = {
62	0xff, 0x10, 0x12, 0x1c, 0x26, 0x30, 0x32, 0x34, 0x36, 0x38
63};
64
65static const char max77686_buck_out[] = {
66	0xff, 0x11, 0x14, 0x1e, 0x28, 0x31, 0x33, 0x35, 0x37, 0x39
67};
68
69static int max77686_buck_volt2hex(int buck, int uV)
70{
71	int hex = 0;
72	int hex_max = 0;
73
74	switch (buck) {
75	case 2:
76	case 3:
77	case 4:
78		/* hex = (uV - 600000) / 12500; */
79		hex = (uV - MAX77686_BUCK_UV_LMIN) / MAX77686_BUCK_UV_LSTEP;
80		hex_max = MAX77686_BUCK234_VOLT_MAX_HEX;
81		break;
82	default:
83		/*
84		 * hex = (uV - 750000) / 50000. We assume that dynamic voltage
85		 * scaling via GPIOs is not enabled and don't support that.
86		 * If this is enabled then the driver will need to take that
87		 * into account and check different registers depending on
88		 * the current setting. See the datasheet for details.
89		 */
90		hex = (uV - MAX77686_BUCK_UV_HMIN) / MAX77686_BUCK_UV_HSTEP;
91		hex_max = MAX77686_BUCK_VOLT_MAX_HEX;
92		break;
93	}
94
95	if (hex >= 0 && hex <= hex_max)
96		return hex;
97
98	pr_err("Value: %d uV is wrong for BUCK%d", uV, buck);
99	return -EINVAL;
100}
101
102static int max77686_buck_hex2volt(int buck, int hex)
103{
104	unsigned uV = 0;
105	int hex_max = 0;
106
107	if (hex < 0)
108		goto bad_hex;
109
110	switch (buck) {
111	case 2:
112	case 3:
113	case 4:
114		hex_max = MAX77686_BUCK234_VOLT_MAX_HEX;
115		if (hex > hex_max)
116			goto bad_hex;
117
118		/* uV = hex * 12500 + 600000; */
119		uV = hex * MAX77686_BUCK_UV_LSTEP + MAX77686_BUCK_UV_LMIN;
120		break;
121	default:
122		hex_max = MAX77686_BUCK_VOLT_MAX_HEX;
123		if (hex > hex_max)
124			goto bad_hex;
125
126		/* uV = hex * 50000 + 750000; */
127		uV = hex * MAX77686_BUCK_UV_HSTEP + MAX77686_BUCK_UV_HMIN;
128		break;
129	}
130
131	return uV;
132
133bad_hex:
134	pr_err("Value: %#x is wrong for BUCK%d", hex, buck);
135	return -EINVAL;
136}
137
138static int max77686_ldo_volt2hex(int ldo, int uV)
139{
140	int hex = 0;
141
142	switch (ldo) {
143	case 1:
144	case 2:
145	case 6:
146	case 7:
147	case 8:
148	case 15:
149		hex = (uV - MAX77686_LDO_UV_MIN) / MAX77686_LDO_UV_LSTEP;
150		/* hex = (uV - 800000) / 25000; */
151		break;
152	default:
153		hex = (uV - MAX77686_LDO_UV_MIN) / MAX77686_LDO_UV_HSTEP;
154		/* hex = (uV - 800000) / 50000; */
155	}
156
157	if (hex >= 0 && hex <= MAX77686_LDO_VOLT_MAX_HEX)
158		return hex;
159
160	pr_err("Value: %d uV is wrong for LDO%d", uV, ldo);
161	return -EINVAL;
162}
163
164static int max77686_ldo_hex2volt(int ldo, int hex)
165{
166	unsigned int uV = 0;
167
168	if (hex > MAX77686_LDO_VOLT_MAX_HEX)
169		goto bad_hex;
170
171	switch (ldo) {
172	case 1:
173	case 2:
174	case 6:
175	case 7:
176	case 8:
177	case 15:
178		/* uV = hex * 25000 + 800000; */
179		uV = hex * MAX77686_LDO_UV_LSTEP + MAX77686_LDO_UV_MIN;
180		break;
181	default:
182		/* uV = hex * 50000 + 800000; */
183		uV = hex * MAX77686_LDO_UV_HSTEP + MAX77686_LDO_UV_MIN;
184	}
185
186	return uV;
187
188bad_hex:
189	pr_err("Value: %#x is wrong for ldo%d", hex, ldo);
190	return -EINVAL;
191}
192
193static int max77686_ldo_hex2mode(int ldo, int hex)
194{
195	if (hex > MAX77686_LDO_MODE_MASK)
196		return -EINVAL;
197
198	switch (hex) {
199	case MAX77686_LDO_MODE_OFF:
200		return OPMODE_OFF;
201	case MAX77686_LDO_MODE_LPM: /* == MAX77686_LDO_MODE_STANDBY: */
202		/* The same mode values but different meaning for each ldo */
203		switch (ldo) {
204		case 2:
205		case 6:
206		case 7:
207		case 8:
208		case 10:
209		case 11:
210		case 12:
211		case 14:
212		case 15:
213		case 16:
214			return OPMODE_STANDBY;
215		default:
216			return OPMODE_LPM;
217		}
218	case MAX77686_LDO_MODE_STANDBY_LPM:
219		return OPMODE_STANDBY_LPM;
220	case MAX77686_LDO_MODE_ON:
221		return OPMODE_ON;
222	default:
223		return -EINVAL;
224	}
225}
226
227static int max77686_buck_hex2mode(int buck, int hex)
228{
229	if (hex > MAX77686_BUCK_MODE_MASK)
230		return -EINVAL;
231
232	switch (hex) {
233	case MAX77686_BUCK_MODE_OFF:
234		return OPMODE_OFF;
235	case MAX77686_BUCK_MODE_ON:
236		return OPMODE_ON;
237	case MAX77686_BUCK_MODE_STANDBY:
238		switch (buck) {
239		case 1:
240		case 2:
241		case 3:
242		case 4:
243			return OPMODE_STANDBY;
244		default:
245			return -EINVAL;
246		}
247	case MAX77686_BUCK_MODE_LPM:
248		switch (buck) {
249		case 2:
250		case 3:
251		case 4:
252			return OPMODE_LPM;
253		default:
254			return -EINVAL;
255		}
256	default:
257		return -EINVAL;
258	}
259}
260
261static int max77686_buck_modes(int buck, struct dm_regulator_mode **modesp)
262{
263	int ret = -EINVAL;
264
265	if (buck < 1 || buck > MAX77686_BUCK_NUM)
266		return ret;
267
268	switch (buck) {
269	case 1:
270		*modesp = max77686_buck_mode_standby;
271		ret = ARRAY_SIZE(max77686_buck_mode_standby);
272		break;
273	case 2:
274	case 3:
275	case 4:
276		*modesp = max77686_buck_mode_lpm;
277		ret = ARRAY_SIZE(max77686_buck_mode_lpm);
278		break;
279	default:
280		*modesp = max77686_buck_mode_onoff;
281		ret = ARRAY_SIZE(max77686_buck_mode_onoff);
282	}
283
284	return ret;
285}
286
287static int max77686_ldo_modes(int ldo, struct dm_regulator_mode **modesp,
288				struct udevice *dev)
289{
290	int ret = -EINVAL;
291
292	if (ldo < 1 || ldo > MAX77686_LDO_NUM)
293		return ret;
294
295	switch (ldo) {
296	case 2:
297	case 6:
298	case 7:
299	case 8:
300	case 10:
301	case 11:
302	case 12:
303	case 14:
304	case 15:
305	case 16:
306		*modesp = max77686_ldo_mode_standby2;
307		ret = ARRAY_SIZE(max77686_ldo_mode_standby2);
308		break;
309	default:
310		*modesp = max77686_ldo_mode_standby1;
311		ret = ARRAY_SIZE(max77686_ldo_mode_standby1);
312	}
313
314	return ret;
315}
316
317static int max77686_ldo_val(struct udevice *dev, int op, int *uV)
318{
319	unsigned int adr;
320	unsigned char val;
321	int hex, ldo, ret;
322
323	if (op == PMIC_OP_GET)
324		*uV = 0;
325
326	ldo = dev->driver_data;
327	if (ldo < 1 || ldo > MAX77686_LDO_NUM) {
328		pr_err("Wrong ldo number: %d", ldo);
329		return -EINVAL;
330	}
331
332	adr = MAX77686_REG_PMIC_LDO1CTRL1 + ldo - 1;
333
334	ret = pmic_read(dev->parent, adr, &val, 1);
335	if (ret)
336		return ret;
337
338	if (op == PMIC_OP_GET) {
339		val &= MAX77686_LDO_VOLT_MASK;
340		ret = max77686_ldo_hex2volt(ldo, val);
341		if (ret < 0)
342			return ret;
343		*uV = ret;
344		return 0;
345	}
346
347	hex = max77686_ldo_volt2hex(ldo, *uV);
348	if (hex < 0)
349		return hex;
350
351	val &= ~MAX77686_LDO_VOLT_MASK;
352	val |= hex;
353	ret = pmic_write(dev->parent, adr, &val, 1);
354
355	return ret;
356}
357
358static int max77686_buck_val(struct udevice *dev, int op, int *uV)
359{
360	unsigned int mask, adr;
361	unsigned char val;
362	int hex, buck, ret;
363
364	buck = dev->driver_data;
365	if (buck < 1 || buck > MAX77686_BUCK_NUM) {
366		pr_err("Wrong buck number: %d", buck);
367		return -EINVAL;
368	}
369
370	if (op == PMIC_OP_GET)
371		*uV = 0;
372
373	/* &buck_out = ctrl + 1 */
374	adr = max77686_buck_out[buck];
375
376	/* mask */
377	switch (buck) {
378	case 2:
379	case 3:
380	case 4:
381		mask = MAX77686_BUCK234_VOLT_MASK;
382		break;
383	default:
384		mask = MAX77686_BUCK_VOLT_MASK;
385		break;
386	}
387
388	ret = pmic_read(dev->parent, adr, &val, 1);
389	if (ret)
390		return ret;
391
392	if (op == PMIC_OP_GET) {
393		val &= mask;
394		ret = max77686_buck_hex2volt(buck, val);
395		if (ret < 0)
396			return ret;
397		*uV = ret;
398		return 0;
399	}
400
401	hex = max77686_buck_volt2hex(buck, *uV);
402	if (hex < 0)
403		return hex;
404
405	val &= ~mask;
406	val |= hex;
407	ret = pmic_write(dev->parent, adr, &val, 1);
408
409	return ret;
410}
411
412static int max77686_ldo_mode(struct udevice *dev, int op, int *opmode)
413{
414	unsigned int adr, mode;
415	unsigned char val;
416	int ldo, ret;
417
418	if (op == PMIC_OP_GET)
419		*opmode = -EINVAL;
420
421	ldo = dev->driver_data;
422	if (ldo < 1 || ldo > MAX77686_LDO_NUM) {
423		pr_err("Wrong ldo number: %d", ldo);
424		return -EINVAL;
425	}
426
427	adr = MAX77686_REG_PMIC_LDO1CTRL1 + ldo - 1;
428
429	ret = pmic_read(dev->parent, adr, &val, 1);
430	if (ret)
431		return ret;
432
433	if (op == PMIC_OP_GET) {
434		val &= MAX77686_LDO_MODE_MASK;
435		ret = max77686_ldo_hex2mode(ldo, val);
436		if (ret < 0)
437			return ret;
438		*opmode = ret;
439		return 0;
440	}
441
442	/* mode */
443	switch (*opmode) {
444	case OPMODE_OFF:
445		mode = MAX77686_LDO_MODE_OFF;
446		break;
447	case OPMODE_LPM:
448		switch (ldo) {
449		case 2:
450		case 6:
451		case 7:
452		case 8:
453		case 10:
454		case 11:
455		case 12:
456		case 14:
457		case 15:
458		case 16:
459			return -EINVAL;
460		default:
461			mode = MAX77686_LDO_MODE_LPM;
462		}
463		break;
464	case OPMODE_STANDBY:
465		switch (ldo) {
466		case 2:
467		case 6:
468		case 7:
469		case 8:
470		case 10:
471		case 11:
472		case 12:
473		case 14:
474		case 15:
475		case 16:
476			mode = MAX77686_LDO_MODE_STANDBY;
477			break;
478		default:
479			return -EINVAL;
480		}
481		break;
482	case OPMODE_STANDBY_LPM:
483		mode = MAX77686_LDO_MODE_STANDBY_LPM;
484		break;
485	case OPMODE_ON:
486		mode = MAX77686_LDO_MODE_ON;
487		break;
488	default:
489		mode = 0xff;
490	}
491
492	if (mode == 0xff) {
493		pr_err("Wrong mode: %d for ldo%d", *opmode, ldo);
494		return -EINVAL;
495	}
496
497	val &= ~MAX77686_LDO_MODE_MASK;
498	val |= mode;
499	ret = pmic_write(dev->parent, adr, &val, 1);
500
501	return ret;
502}
503
504static int max77686_ldo_enable(struct udevice *dev, int op, bool *enable)
505{
506	int ret, on_off;
507
508	if (op == PMIC_OP_GET) {
509		ret = max77686_ldo_mode(dev, op, &on_off);
510		if (ret)
511			return ret;
512
513		switch (on_off) {
514		case OPMODE_OFF:
515			*enable = false;
516			break;
517		case OPMODE_ON:
518			*enable = true;
519			break;
520		default:
521			return -EINVAL;
522		}
523	} else if (op == PMIC_OP_SET) {
524		if (*enable)
525			on_off = OPMODE_ON;
526		else
527			on_off = OPMODE_OFF;
528
529		ret = max77686_ldo_mode(dev, op, &on_off);
530		if (ret)
531			return ret;
532	}
533
534	return 0;
535}
536
537static int max77686_buck_mode(struct udevice *dev, int op, int *opmode)
538{
539	unsigned int mask, adr, mode, mode_shift;
540	unsigned char val;
541	int buck, ret;
542
543	buck = dev->driver_data;
544	if (buck < 1 || buck > MAX77686_BUCK_NUM) {
545		pr_err("Wrong buck number: %d", buck);
546		return -EINVAL;
547	}
548
549	adr = max77686_buck_ctrl[buck];
550
551	/* mask */
552	switch (buck) {
553	case 2:
554	case 3:
555	case 4:
556		mode_shift = MAX77686_BUCK_MODE_SHIFT_2;
557		break;
558	default:
559		mode_shift = MAX77686_BUCK_MODE_SHIFT_1;
560	}
561
562	mask = MAX77686_BUCK_MODE_MASK << mode_shift;
563
564	ret = pmic_read(dev->parent, adr, &val, 1);
565	if (ret)
566		return ret;
567
568	if (op == PMIC_OP_GET) {
569		val &= mask;
570		val >>= mode_shift;
571		ret = max77686_buck_hex2mode(buck, val);
572		if (ret < 0)
573			return ret;
574		*opmode = ret;
575		return 0;
576	}
577
578	/* mode */
579	switch (*opmode) {
580	case OPMODE_OFF:
581		mode = MAX77686_BUCK_MODE_OFF;
582		break;
583	case OPMODE_STANDBY:
584		switch (buck) {
585		case 1:
586		case 2:
587		case 3:
588		case 4:
589			mode = MAX77686_BUCK_MODE_STANDBY << mode_shift;
590			break;
591		default:
592			mode = 0xff;
593		}
594		break;
595	case OPMODE_LPM:
596		switch (buck) {
597		case 2:
598		case 3:
599		case 4:
600			mode = MAX77686_BUCK_MODE_LPM << mode_shift;
601			break;
602		default:
603			mode = 0xff;
604		}
605		break;
606	case OPMODE_ON:
607		mode = MAX77686_BUCK_MODE_ON << mode_shift;
608		break;
609	default:
610		mode = 0xff;
611	}
612
613	if (mode == 0xff) {
614		pr_err("Wrong mode: %d for buck: %d\n", *opmode, buck);
615		return -EINVAL;
616	}
617
618	val &= ~mask;
619	val |= mode;
620	ret = pmic_write(dev->parent, adr, &val, 1);
621
622	return ret;
623}
624
625static int max77686_buck_enable(struct udevice *dev, int op, bool *enable)
626{
627	int ret, on_off;
628
629	if (op == PMIC_OP_GET) {
630		ret = max77686_buck_mode(dev, op, &on_off);
631		if (ret)
632			return ret;
633
634		switch (on_off) {
635		case OPMODE_OFF:
636			*enable = false;
637			break;
638		case OPMODE_ON:
639			*enable = true;
640			break;
641		default:
642			return -EINVAL;
643		}
644	} else if (op == PMIC_OP_SET) {
645		if (*enable)
646			on_off = OPMODE_ON;
647		else
648			on_off = OPMODE_OFF;
649
650		ret = max77686_buck_mode(dev, op, &on_off);
651		if (ret)
652			return ret;
653	}
654
655	return 0;
656}
657
658static int max77686_ldo_probe(struct udevice *dev)
659{
660	struct dm_regulator_uclass_plat *uc_pdata;
661
662	uc_pdata = dev_get_uclass_plat(dev);
663
664	uc_pdata->type = REGULATOR_TYPE_LDO;
665	uc_pdata->mode_count = max77686_ldo_modes(dev->driver_data,
666						  &uc_pdata->mode, dev);
667
668	return 0;
669}
670
671static int ldo_get_value(struct udevice *dev)
672{
673	int uV;
674	int ret;
675
676	ret = max77686_ldo_val(dev, PMIC_OP_GET, &uV);
677	if (ret)
678		return ret;
679
680	return uV;
681}
682
683static int ldo_set_value(struct udevice *dev, int uV)
684{
685	return max77686_ldo_val(dev, PMIC_OP_SET, &uV);
686}
687
688static int ldo_get_enable(struct udevice *dev)
689{
690	bool enable = false;
691	int ret;
692
693	ret = max77686_ldo_enable(dev, PMIC_OP_GET, &enable);
694	if (ret)
695		return ret;
696
697	return enable;
698}
699
700static int ldo_set_enable(struct udevice *dev, bool enable)
701{
702	return max77686_ldo_enable(dev, PMIC_OP_SET, &enable);
703}
704
705static int ldo_get_mode(struct udevice *dev)
706{
707	int mode;
708	int ret;
709
710	ret = max77686_ldo_mode(dev, PMIC_OP_GET, &mode);
711	if (ret)
712		return ret;
713
714	return mode;
715}
716
717static int ldo_set_mode(struct udevice *dev, int mode)
718{
719	return max77686_ldo_mode(dev, PMIC_OP_SET, &mode);
720}
721
722static int max77686_buck_probe(struct udevice *dev)
723{
724	struct dm_regulator_uclass_plat *uc_pdata;
725
726	uc_pdata = dev_get_uclass_plat(dev);
727
728	uc_pdata->type = REGULATOR_TYPE_BUCK;
729	uc_pdata->mode_count = max77686_buck_modes(dev->driver_data,
730						   &uc_pdata->mode);
731
732	return 0;
733}
734
735static int buck_get_value(struct udevice *dev)
736{
737	int uV;
738	int ret;
739
740	ret = max77686_buck_val(dev, PMIC_OP_GET, &uV);
741	if (ret)
742		return ret;
743
744	return uV;
745}
746
747static int buck_set_value(struct udevice *dev, int uV)
748{
749	return max77686_buck_val(dev, PMIC_OP_SET, &uV);
750}
751
752static int buck_get_enable(struct udevice *dev)
753{
754	bool enable = false;
755	int ret;
756
757	ret = max77686_buck_enable(dev, PMIC_OP_GET, &enable);
758	if (ret)
759		return ret;
760
761	return enable;
762}
763
764static int buck_set_enable(struct udevice *dev, bool enable)
765{
766	return max77686_buck_enable(dev, PMIC_OP_SET, &enable);
767}
768
769static int buck_get_mode(struct udevice *dev)
770{
771	int mode;
772	int ret;
773
774	ret = max77686_buck_mode(dev, PMIC_OP_GET, &mode);
775	if (ret)
776		return ret;
777
778	return mode;
779}
780
781static int buck_set_mode(struct udevice *dev, int mode)
782{
783	return max77686_buck_mode(dev, PMIC_OP_SET, &mode);
784}
785
786static const struct dm_regulator_ops max77686_ldo_ops = {
787	.get_value  = ldo_get_value,
788	.set_value  = ldo_set_value,
789	.get_enable = ldo_get_enable,
790	.set_enable = ldo_set_enable,
791	.get_mode   = ldo_get_mode,
792	.set_mode   = ldo_set_mode,
793};
794
795U_BOOT_DRIVER(max77686_ldo) = {
796	.name = MAX77686_LDO_DRIVER,
797	.id = UCLASS_REGULATOR,
798	.ops = &max77686_ldo_ops,
799	.probe = max77686_ldo_probe,
800};
801
802static const struct dm_regulator_ops max77686_buck_ops = {
803	.get_value  = buck_get_value,
804	.set_value  = buck_set_value,
805	.get_enable = buck_get_enable,
806	.set_enable = buck_set_enable,
807	.get_mode   = buck_get_mode,
808	.set_mode   = buck_set_mode,
809};
810
811U_BOOT_DRIVER(max77686_buck) = {
812	.name = MAX77686_BUCK_DRIVER,
813	.id = UCLASS_REGULATOR,
814	.ops = &max77686_buck_ops,
815	.probe = max77686_buck_probe,
816};
817