1// SPDX-License-Identifier: GPL-2.0
2/*
3 *  Copyright (C) 2018 Samsung Electronics
4 *  Jaehoon Chung <jh80.chung@samsung.com>
5 */
6
7#include <common.h>
8#include <fdtdec.h>
9#include <errno.h>
10#include <dm.h>
11#include <linux/delay.h>
12#include <linux/printk.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 */
24static 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
30static 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
37static const char s2mps11_buck_ctrl[] = {
38	0xff, 0x25, 0x27, 0x29, 0x2b, 0x2d, 0x33, 0x35, 0x37, 0x39, 0x3b
39};
40
41static const char s2mps11_buck_out[] = {
42	0xff, 0x26, 0x28, 0x2a, 0x2c, 0x2f, 0x34, 0x36, 0x38, 0x3a, 0x3c
43};
44
45static 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;
77bad:
78	pr_err("Value: %#x is wrong for BUCK%d", hex, buck);
79	return -EINVAL;
80}
81
82static 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
112bad:
113	pr_err("Value: %d uV is wrong for BUCK%d", uV, buck);
114	return -EINVAL;
115}
116
117static 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
167static 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
225static 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
257static 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
268static int buck_set_value(struct udevice *dev, int uV)
269{
270	return s2mps11_buck_val(dev, PMIC_OP_SET, &uV);
271}
272
273static 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
284static int buck_set_enable(struct udevice *dev, bool enable)
285{
286	return s2mps11_buck_enable(dev, PMIC_OP_SET, &enable);
287}
288
289static 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
301static int buck_set_mode(struct udevice *dev, int mode)
302{
303	return s2mps11_buck_mode(dev, PMIC_OP_SET, &mode);
304}
305
306static int s2mps11_buck_probe(struct udevice *dev)
307{
308	struct dm_regulator_uclass_plat *uc_pdata;
309
310	uc_pdata = dev_get_uclass_plat(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
319static 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
328U_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
335static 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	case 27:
351	case 35:
352		uV = hex * S2MPS11_LDO_STEP + S2MPS11_LDO_UV_MIN;
353		break;
354	default:
355		uV = hex * S2MPS11_LDO_STEP * 2 + S2MPS11_LDO_UV_MIN;
356		break;
357	}
358
359	return uV;
360}
361
362static int s2mps11_ldo_volt2hex(int ldo, int uV)
363{
364	int hex = 0;
365
366	switch (ldo) {
367	case 1:
368	case 6:
369	case 11:
370	case 22:
371	case 23:
372	case 27:
373	case 35:
374		hex = (uV - S2MPS11_LDO_UV_MIN) / S2MPS11_LDO_STEP;
375		break;
376	default:
377		hex = (uV - S2MPS11_LDO_UV_MIN) / (S2MPS11_LDO_STEP * 2);
378		break;
379	}
380
381	if (hex >= 0 && hex <= S2MPS11_LDO_VOLT_MAX_HEX)
382		return hex;
383
384	pr_err("Value: %d uV is wrong for LDO%d", uV, ldo);
385	return -EINVAL;
386
387	return 0;
388}
389
390static int s2mps11_ldo_val(struct udevice *dev, int op, int *uV)
391{
392	unsigned int addr;
393	unsigned char val;
394	int hex, ldo, ret;
395
396	ldo = dev->driver_data;
397	if (ldo < 1 || ldo > S2MPS11_LDO_NUM) {
398		pr_err("Wrong ldo number: %d\n", ldo);
399		return -EINVAL;
400	}
401
402	addr = S2MPS11_REG_L1CTRL + ldo - 1;
403
404	ret = pmic_read(dev->parent, addr, &val, 1);
405	if (ret)
406		return ret;
407
408	if (op == PMIC_OP_GET) {
409		*uV = 0;
410		val &= S2MPS11_LDO_VOLT_MASK;
411		ret = s2mps11_ldo_hex2volt(ldo, val);
412		if (ret < 0)
413			return ret;
414
415		*uV = ret;
416		return 0;
417	}
418
419	hex = s2mps11_ldo_volt2hex(ldo, *uV);
420	if (hex < 0)
421		return hex;
422
423	val &= ~S2MPS11_LDO_VOLT_MASK;
424	val |= hex;
425	ret = pmic_write(dev->parent, addr, &val, 1);
426
427	return ret;
428}
429
430static int s2mps11_ldo_mode(struct udevice *dev, int op, int *opmode)
431{
432	unsigned int addr, mode;
433	unsigned char val;
434	int ldo, ret;
435
436	ldo = dev->driver_data;
437	if (ldo < 1 || ldo > S2MPS11_LDO_NUM) {
438		pr_err("Wrong ldo number: %d\n", ldo);
439		return -EINVAL;
440	}
441	addr = S2MPS11_REG_L1CTRL + ldo - 1;
442
443	ret = pmic_read(dev->parent, addr, &val, 1);
444	if (ret)
445		return ret;
446
447	if (op == PMIC_OP_GET) {
448		val &= (S2MPS11_LDO_MODE_MASK << S2MPS11_LDO_MODE_SHIFT);
449		switch (val) {
450		case S2MPS11_LDO_MODE_OFF:
451			*opmode = OP_OFF;
452			break;
453		case S2MPS11_LDO_MODE_STANDBY:
454			*opmode = OP_STANDBY;
455			break;
456		case S2MPS11_LDO_MODE_STANDBY_LPM:
457			*opmode = OP_STANDBY_LPM;
458			break;
459		case S2MPS11_LDO_MODE_ON:
460			*opmode = OP_ON;
461			break;
462		default:
463			return -EINVAL;
464		}
465		return 0;
466	}
467
468	switch (*opmode) {
469	case OP_OFF:
470		mode = S2MPS11_LDO_MODE_OFF;
471		break;
472	case OP_STANDBY:
473		mode = S2MPS11_LDO_MODE_STANDBY;
474		break;
475	case OP_STANDBY_LPM:
476		mode = S2MPS11_LDO_MODE_STANDBY_LPM;
477		break;
478	case OP_ON:
479		mode = S2MPS11_LDO_MODE_ON;
480		break;
481	default:
482		pr_err("Wrong mode: %d for ldo: %d\n", *opmode, ldo);
483		return -EINVAL;
484	}
485
486	val &= ~(S2MPS11_LDO_MODE_MASK << S2MPS11_LDO_MODE_SHIFT);
487	val |= mode;
488	ret = pmic_write(dev->parent, addr, &val, 1);
489
490	return ret;
491}
492
493static int s2mps11_ldo_enable(struct udevice *dev, int op, bool *enable)
494{
495	int ret, on_off;
496
497	if (op == PMIC_OP_GET) {
498		ret = s2mps11_ldo_mode(dev, op, &on_off);
499		if (ret)
500			return ret;
501		switch (on_off) {
502		case OP_OFF:
503			*enable = false;
504			break;
505		case OP_ON:
506			*enable = true;
507			break;
508		default:
509			return -EINVAL;
510		}
511	} else if (op == PMIC_OP_SET) {
512		if (*enable)
513			on_off = OP_ON;
514		else
515			on_off = OP_OFF;
516
517		ret = s2mps11_ldo_mode(dev, op, &on_off);
518		if (ret)
519			return ret;
520	}
521
522	return 0;
523}
524
525static int ldo_get_value(struct udevice *dev)
526{
527	int uV;
528	int ret;
529
530	ret = s2mps11_ldo_val(dev, PMIC_OP_GET, &uV);
531	if (ret)
532		return ret;
533
534	return uV;
535}
536
537static int ldo_set_value(struct udevice *dev, int uV)
538{
539	return s2mps11_ldo_val(dev, PMIC_OP_SET, &uV);
540}
541
542static int ldo_get_enable(struct udevice *dev)
543{
544	bool enable = false;
545	int ret;
546
547	ret = s2mps11_ldo_enable(dev, PMIC_OP_GET, &enable);
548	if (ret)
549		return ret;
550	return enable;
551}
552
553static int ldo_set_enable(struct udevice *dev, bool enable)
554{
555	int ret;
556
557	ret = s2mps11_ldo_enable(dev, PMIC_OP_SET, &enable);
558	if (ret)
559		return ret;
560
561	/* Wait the "enable delay" for voltage to start to rise */
562	udelay(15);
563
564	return 0;
565}
566
567static int ldo_get_mode(struct udevice *dev)
568{
569	int mode, ret;
570
571	ret = s2mps11_ldo_mode(dev, PMIC_OP_GET, &mode);
572	if (ret)
573		return ret;
574	return mode;
575}
576
577static int ldo_set_mode(struct udevice *dev, int mode)
578{
579	return s2mps11_ldo_mode(dev, PMIC_OP_SET, &mode);
580}
581
582static int s2mps11_ldo_probe(struct udevice *dev)
583{
584	struct dm_regulator_uclass_plat *uc_pdata;
585
586	uc_pdata = dev_get_uclass_plat(dev);
587	uc_pdata->type = REGULATOR_TYPE_LDO;
588	uc_pdata->mode = s2mps11_ldo_modes;
589	uc_pdata->mode_count = ARRAY_SIZE(s2mps11_ldo_modes);
590
591	return 0;
592}
593
594static const struct dm_regulator_ops s2mps11_ldo_ops = {
595	.get_value	= ldo_get_value,
596	.set_value	= ldo_set_value,
597	.get_enable	= ldo_get_enable,
598	.set_enable	= ldo_set_enable,
599	.get_mode	= ldo_get_mode,
600	.set_mode	= ldo_set_mode,
601};
602
603U_BOOT_DRIVER(s2mps11_ldo) = {
604	.name = S2MPS11_LDO_DRIVER,
605	.id = UCLASS_REGULATOR,
606	.ops = &s2mps11_ldo_ops,
607	.probe = s2mps11_ldo_probe,
608};
609