1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause
3  *
4  * Copyright 2020 Michal Meloun <mmel@FreeBSD.org>
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  */
27 
28 #include <sys/cdefs.h>
29 #include <sys/param.h>
30 #include <sys/systm.h>
31 #include <sys/bus.h>
32 #include <sys/gpio.h>
33 #include <sys/kernel.h>
34 #include <sys/module.h>
35 #include <sys/malloc.h>
36 #include <sys/rman.h>
37 #include <sys/sx.h>
38 
39 #include <machine/bus.h>
40 
41 #include <dev/extres/regulator/regulator.h>
42 #include <dev/gpio/gpiobusvar.h>
43 
44 #include <dt-bindings/mfd/max77620.h>
45 
46 #include "max77620.h"
47 
48 MALLOC_DEFINE(M_MAX77620_REG, "MAX77620 regulator", "MAX77620 power regulator");
49 
50 #define	DIV_ROUND_UP(n,d) howmany(n, d)
51 
52 enum max77620_reg_id {
53 	MAX77620_REG_ID_SD0,
54 	MAX77620_REG_ID_SD1,
55 	MAX77620_REG_ID_SD2,
56 	MAX77620_REG_ID_SD3,
57 	MAX77620_REG_ID_LDO0,
58 	MAX77620_REG_ID_LDO1,
59 	MAX77620_REG_ID_LDO2,
60 	MAX77620_REG_ID_LDO3,
61 	MAX77620_REG_ID_LDO4,
62 	MAX77620_REG_ID_LDO5,
63 	MAX77620_REG_ID_LDO6,
64 	MAX77620_REG_ID_LDO7,
65 	MAX77620_REG_ID_LDO8,
66 };
67 
68 /* Initial configuration. */
69 struct max77620_regnode_init_def {
70 	struct regnode_init_def	reg_init_def;
71 	int active_fps_src;
72 	int active_fps_pu_slot;
73 	int active_fps_pd_slot;
74 	int suspend_fps_src;
75 	int suspend_fps_pu_slot;
76 	int suspend_fps_pd_slot;
77 	int ramp_rate_setting;
78 };
79 
80 /* Regulator HW definition. */
81 struct reg_def {
82 	intptr_t		id;		/* ID */
83 	char			*name;		/* Regulator name */
84 	char			*supply_name;	/* Source property name */
85 	bool 			is_sd_reg; 	/* SD or LDO regulator? */
86 	uint8_t			volt_reg;
87 	uint8_t			volt_vsel_mask;
88 	uint8_t			cfg_reg;
89 	uint8_t			fps_reg;
90 	uint8_t			pwr_mode_reg;
91 	uint8_t			pwr_mode_mask;
92 	uint8_t			pwr_mode_shift;
93 	struct regulator_range	*ranges;
94 	int			nranges;
95 };
96 
97 struct max77620_reg_sc {
98 	struct regnode		*regnode;
99 	struct max77620_softc	*base_sc;
100 	struct reg_def		*def;
101 	phandle_t		xref;
102 
103 	struct regnode_std_param *param;
104 	/* Configured values */
105 	int			active_fps_src;
106 	int			active_fps_pu_slot;
107 	int			active_fps_pd_slot;
108 	int			suspend_fps_src;
109 	int			suspend_fps_pu_slot;
110 	int			suspend_fps_pd_slot;
111 	int			ramp_rate_setting;
112 	int			enable_usec;
113 	uint8_t			enable_pwr_mode;
114 
115 	/* Cached values */
116 	uint8_t			fps_src;
117 	uint8_t			pwr_mode;
118 	int			pwr_ramp_delay;
119 };
120 
121 static struct regulator_range max77620_sd0_ranges[] = {
122 	REG_RANGE_INIT(0, 64, 600000, 12500),  /* 0.6V - 1.4V / 12.5mV */
123 };
124 
125 static struct regulator_range max77620_sd1_ranges[] = {
126 	REG_RANGE_INIT(0, 76, 600000, 12500),  /* 0.6V - 1.55V / 12.5mV */
127 };
128 
129 static struct regulator_range max77620_sdx_ranges[] = {
130 	REG_RANGE_INIT(0, 255, 600000, 12500),  /* 0.6V - 3.7875V / 12.5mV */
131 };
132 
133 static struct regulator_range max77620_ldo0_1_ranges[] = {
134 	REG_RANGE_INIT(0, 63, 800000, 25000),  /* 0.8V - 2.375V / 25mV */
135 };
136 
137 static struct regulator_range max77620_ldo4_ranges[] = {
138 	REG_RANGE_INIT(0, 63, 800000, 12500),  /* 0.8V - 1.5875V / 12.5mV */
139 };
140 
141 static struct regulator_range max77620_ldox_ranges[] = {
142 	REG_RANGE_INIT(0, 63, 800000, 50000),  /* 0.8V - 3.95V / 50mV */
143 };
144 
145 static struct reg_def max77620s_def[] = {
146 	{
147 		.id = MAX77620_REG_ID_SD0,
148 		.name = "sd0",
149 		.supply_name = "in-sd0",
150 		.is_sd_reg = true,
151 		.volt_reg = MAX77620_REG_SD0,
152 		.volt_vsel_mask = MAX77620_SD0_VSEL_MASK,
153 		.cfg_reg = MAX77620_REG_CFG_SD0,
154 		.fps_reg = MAX77620_REG_FPS_SD0,
155 		.pwr_mode_reg = MAX77620_REG_CFG_SD0,
156 		.pwr_mode_mask = MAX77620_SD_POWER_MODE_MASK,
157 		.pwr_mode_shift = MAX77620_SD_POWER_MODE_SHIFT,
158 		.ranges = max77620_sd0_ranges,
159 		.nranges = nitems(max77620_sd0_ranges),
160 	},
161 	{
162 		.id = MAX77620_REG_ID_SD1,
163 		.name = "sd1",
164 		.supply_name = "in-sd1",
165 		.is_sd_reg = true,
166 		.volt_reg = MAX77620_REG_SD1,
167 		.volt_vsel_mask = MAX77620_SD1_VSEL_MASK,
168 		.cfg_reg = MAX77620_REG_CFG_SD1,
169 		.fps_reg = MAX77620_REG_FPS_SD1,
170 		.pwr_mode_reg = MAX77620_REG_CFG_SD1,
171 		.pwr_mode_mask = MAX77620_SD_POWER_MODE_MASK,
172 		.pwr_mode_shift = MAX77620_SD_POWER_MODE_SHIFT,
173 		.ranges = max77620_sd1_ranges,
174 		.nranges = nitems(max77620_sd1_ranges),
175 	},
176 	{
177 		.id = MAX77620_REG_ID_SD2,
178 		.name = "sd2",
179 		.supply_name = "in-sd2",
180 		.is_sd_reg = true,
181 		.volt_reg = MAX77620_REG_SD2,
182 		.volt_vsel_mask = MAX77620_SDX_VSEL_MASK,
183 		.cfg_reg = MAX77620_REG_CFG_SD2,
184 		.fps_reg = MAX77620_REG_FPS_SD2,
185 		.pwr_mode_reg = MAX77620_REG_CFG_SD2,
186 		.pwr_mode_mask = MAX77620_SD_POWER_MODE_MASK,
187 		.pwr_mode_shift = MAX77620_SD_POWER_MODE_SHIFT,
188 		.ranges = max77620_sdx_ranges,
189 		.nranges = nitems(max77620_sdx_ranges),
190 	},
191 	{
192 		.id = MAX77620_REG_ID_SD3,
193 		.name = "sd3",
194 		.supply_name = "in-sd3",
195 		.is_sd_reg = true,
196 		.volt_reg = MAX77620_REG_SD3,
197 		.volt_vsel_mask = MAX77620_SDX_VSEL_MASK,
198 		.cfg_reg = MAX77620_REG_CFG_SD3,
199 		.fps_reg = MAX77620_REG_FPS_SD3,
200 		.pwr_mode_reg = MAX77620_REG_CFG_SD3,
201 		.pwr_mode_mask = MAX77620_SD_POWER_MODE_MASK,
202 		.pwr_mode_shift = MAX77620_SD_POWER_MODE_SHIFT,
203 		.ranges = max77620_sdx_ranges,
204 		.nranges = nitems(max77620_sdx_ranges),
205 	},
206 	{
207 		.id = MAX77620_REG_ID_LDO0,
208 		.name = "ldo0",
209 		.supply_name = "vin-ldo0-1",
210 		.volt_reg = MAX77620_REG_CFG_LDO0,
211 		.volt_vsel_mask = MAX77620_LDO_VSEL_MASK,
212 		.is_sd_reg = false,
213 		.cfg_reg = MAX77620_REG_CFG2_LDO0,
214 		.fps_reg = MAX77620_REG_FPS_LDO0,
215 		.pwr_mode_reg = MAX77620_REG_CFG_LDO0,
216 		.pwr_mode_mask = MAX77620_LDO_POWER_MODE_MASK,
217 		.pwr_mode_shift = MAX77620_LDO_POWER_MODE_SHIFT,
218 		.ranges = max77620_ldo0_1_ranges,
219 		.nranges = nitems(max77620_ldo0_1_ranges),
220 	},
221 	{
222 		.id = MAX77620_REG_ID_LDO1,
223 		.name = "ldo1",
224 		.supply_name = "in-ldo0-1",
225 		.is_sd_reg = false,
226 		.volt_reg = MAX77620_REG_CFG_LDO1,
227 		.volt_vsel_mask = MAX77620_LDO_VSEL_MASK,
228 		.cfg_reg = MAX77620_REG_CFG2_LDO1,
229 		.fps_reg = MAX77620_REG_FPS_LDO1,
230 		.pwr_mode_reg = MAX77620_REG_CFG_LDO1,
231 		.pwr_mode_mask = MAX77620_LDO_POWER_MODE_MASK,
232 		.pwr_mode_shift = MAX77620_LDO_POWER_MODE_SHIFT,
233 		.ranges = max77620_ldo0_1_ranges,
234 		.nranges = nitems(max77620_ldo0_1_ranges),
235 	},
236 	{
237 		.id = MAX77620_REG_ID_LDO2,
238 		.name = "ldo2",
239 		.supply_name = "in-ldo2",
240 		.is_sd_reg = false,
241 		.volt_reg = MAX77620_REG_CFG_LDO2,
242 		.volt_vsel_mask = MAX77620_LDO_VSEL_MASK,
243 		.cfg_reg = MAX77620_REG_CFG2_LDO2,
244 		.fps_reg = MAX77620_REG_FPS_LDO2,
245 		.pwr_mode_reg = MAX77620_REG_CFG_LDO2,
246 		.pwr_mode_mask = MAX77620_LDO_POWER_MODE_MASK,
247 		.pwr_mode_shift = MAX77620_LDO_POWER_MODE_SHIFT,
248 		.ranges = max77620_ldox_ranges,
249 		.nranges = nitems(max77620_ldox_ranges),
250 	},
251 	{
252 		.id = MAX77620_REG_ID_LDO3,
253 		.name = "ldo3",
254 		.supply_name = "in-ldo3-5",
255 		.is_sd_reg = false,
256 		.volt_reg = MAX77620_REG_CFG_LDO3,
257 		.volt_vsel_mask = MAX77620_LDO_VSEL_MASK,
258 		.cfg_reg = MAX77620_REG_CFG2_LDO3,
259 		.fps_reg = MAX77620_REG_FPS_LDO3,
260 		.pwr_mode_reg = MAX77620_REG_CFG_LDO3,
261 		.pwr_mode_mask = MAX77620_LDO_POWER_MODE_MASK,
262 		.pwr_mode_shift = MAX77620_LDO_POWER_MODE_SHIFT,
263 		.ranges = max77620_ldox_ranges,
264 		.nranges = nitems(max77620_ldox_ranges),
265 	},
266 	{
267 		.id = MAX77620_REG_ID_LDO4,
268 		.name = "ldo4",
269 		.supply_name = "in-ldo4-6",
270 		.is_sd_reg = false,
271 		.volt_reg = MAX77620_REG_CFG_LDO4,
272 		.volt_vsel_mask = MAX77620_LDO_VSEL_MASK,
273 		.cfg_reg = MAX77620_REG_CFG2_LDO4,
274 		.fps_reg = MAX77620_REG_FPS_LDO4,
275 		.pwr_mode_reg = MAX77620_REG_CFG_LDO4,
276 		.pwr_mode_mask = MAX77620_LDO_POWER_MODE_MASK,
277 		.pwr_mode_shift = MAX77620_LDO_POWER_MODE_SHIFT,
278 		.ranges = max77620_ldo4_ranges,
279 		.nranges = nitems(max77620_ldo4_ranges),
280 	},
281 	{
282 		.id = MAX77620_REG_ID_LDO5,
283 		.name = "ldo5",
284 		.supply_name = "in-ldo3-5",
285 		.is_sd_reg = false,
286 		.volt_reg = MAX77620_REG_CFG_LDO5,
287 		.volt_vsel_mask = MAX77620_LDO_VSEL_MASK,
288 		.cfg_reg = MAX77620_REG_CFG2_LDO5,
289 		.fps_reg = MAX77620_REG_FPS_LDO5,
290 		.pwr_mode_reg = MAX77620_REG_CFG_LDO5,
291 		.pwr_mode_mask = MAX77620_LDO_POWER_MODE_MASK,
292 		.pwr_mode_shift = MAX77620_LDO_POWER_MODE_SHIFT,
293 		.ranges = max77620_ldox_ranges,
294 		.nranges = nitems(max77620_ldox_ranges),
295 	},
296 	{
297 		.id = MAX77620_REG_ID_LDO6,
298 		.name = "ldo6",
299 		.supply_name = "in-ldo4-6",
300 		.is_sd_reg = false,
301 		.volt_reg = MAX77620_REG_CFG_LDO6,
302 		.volt_vsel_mask = MAX77620_LDO_VSEL_MASK,
303 		.cfg_reg = MAX77620_REG_CFG2_LDO6,
304 		.fps_reg = MAX77620_REG_FPS_LDO6,
305 		.pwr_mode_reg = MAX77620_REG_CFG_LDO6,
306 		.pwr_mode_mask = MAX77620_LDO_POWER_MODE_MASK,
307 		.pwr_mode_shift = MAX77620_LDO_POWER_MODE_SHIFT,
308 		.ranges = max77620_ldox_ranges,
309 		.nranges = nitems(max77620_ldox_ranges),
310 	},
311 	{
312 		.id = MAX77620_REG_ID_LDO7,
313 		.name = "ldo7",
314 		.supply_name = "in-ldo7-8",
315 		.is_sd_reg = false,
316 		.volt_reg = MAX77620_REG_CFG_LDO7,
317 		.volt_vsel_mask = MAX77620_LDO_VSEL_MASK,
318 		.cfg_reg = MAX77620_REG_CFG2_LDO7,
319 		.fps_reg = MAX77620_REG_FPS_LDO7,
320 		.pwr_mode_reg = MAX77620_REG_CFG_LDO7,
321 		.pwr_mode_mask = MAX77620_LDO_POWER_MODE_MASK,
322 		.pwr_mode_shift = MAX77620_LDO_POWER_MODE_SHIFT,
323 		.ranges = max77620_ldox_ranges,
324 		.nranges = nitems(max77620_ldox_ranges),
325 	},
326 	{
327 		.id = MAX77620_REG_ID_LDO8,
328 		.name = "ldo8",
329 		.supply_name = "in-ldo7-8",
330 		.is_sd_reg = false,
331 		.volt_reg = MAX77620_REG_CFG_LDO8,
332 		.volt_vsel_mask = MAX77620_LDO_VSEL_MASK,
333 		.cfg_reg = MAX77620_REG_CFG2_LDO8,
334 		.fps_reg = MAX77620_REG_FPS_LDO8,
335 		.pwr_mode_reg = MAX77620_REG_CFG_LDO8,
336 		.pwr_mode_mask = MAX77620_LDO_POWER_MODE_MASK,
337 		.pwr_mode_shift = MAX77620_LDO_POWER_MODE_SHIFT,
338 		.ranges = max77620_ldox_ranges,
339 		.nranges = nitems(max77620_ldox_ranges),
340 	},
341 };
342 
343 
344 static int max77620_regnode_init(struct regnode *regnode);
345 static int max77620_regnode_enable(struct regnode *regnode, bool enable,
346     int *udelay);
347 static int max77620_regnode_set_volt(struct regnode *regnode, int min_uvolt,
348     int max_uvolt, int *udelay);
349 static int max77620_regnode_get_volt(struct regnode *regnode, int *uvolt);
350 static regnode_method_t max77620_regnode_methods[] = {
351 	/* Regulator interface */
352 	REGNODEMETHOD(regnode_init,		max77620_regnode_init),
353 	REGNODEMETHOD(regnode_enable,		max77620_regnode_enable),
354 	REGNODEMETHOD(regnode_set_voltage,	max77620_regnode_set_volt),
355 	REGNODEMETHOD(regnode_get_voltage,	max77620_regnode_get_volt),
356 	REGNODEMETHOD_END
357 };
358 DEFINE_CLASS_1(max77620_regnode, max77620_regnode_class, max77620_regnode_methods,
359    sizeof(struct max77620_reg_sc), regnode_class);
360 
361 static int
362 max77620_get_sel(struct max77620_reg_sc *sc, uint8_t *sel)
363 {
364 	int rv;
365 
366 	rv = RD1(sc->base_sc, sc->def->volt_reg, sel);
367 	if (rv != 0) {
368 		printf("%s: cannot read volatge selector: %d\n",
369 		    regnode_get_name(sc->regnode), rv);
370 		return (rv);
371 	}
372 	*sel &= sc->def->volt_vsel_mask;
373 	*sel >>= ffs(sc->def->volt_vsel_mask) - 1;
374 	return (0);
375 }
376 
377 static int
378 max77620_set_sel(struct max77620_reg_sc *sc, uint8_t sel)
379 {
380 	int rv;
381 
382 	sel <<= ffs(sc->def->volt_vsel_mask) - 1;
383 	sel &= sc->def->volt_vsel_mask;
384 
385 	rv = RM1(sc->base_sc, sc->def->volt_reg,
386 	    sc->def->volt_vsel_mask, sel);
387 	if (rv != 0) {
388 		printf("%s: cannot set volatge selector: %d\n",
389 		    regnode_get_name(sc->regnode), rv);
390 		return (rv);
391 	}
392 	return (rv);
393 }
394 
395 static int
396 max77620_get_fps_src(struct max77620_reg_sc *sc, uint8_t *fps_src)
397 {
398 	uint8_t val;
399 	int rv;
400 
401 	rv = RD1(sc->base_sc, sc->def->fps_reg, &val);
402 	if (rv != 0)
403 		return (rv);
404 
405 	*fps_src  = (val & MAX77620_FPS_SRC_MASK) >> MAX77620_FPS_SRC_SHIFT;
406 	return (0);
407 }
408 
409 static int
410 max77620_set_fps_src(struct max77620_reg_sc *sc, uint8_t fps_src)
411 {
412 	int rv;
413 
414 	rv = RM1(sc->base_sc, sc->def->fps_reg, MAX77620_FPS_SRC_MASK,
415 	    fps_src << MAX77620_FPS_SRC_SHIFT);
416 	if (rv != 0)
417 		return (rv);
418 	sc->fps_src = fps_src;
419 	return (0);
420 }
421 
422 static int
423 max77620_set_fps_slots(struct max77620_reg_sc *sc, bool suspend)
424 {
425 	uint8_t mask, val;
426 	int pu_slot, pd_slot, rv;
427 
428 	if (suspend) {
429 		pu_slot = sc->suspend_fps_pu_slot;
430 		pd_slot = sc->suspend_fps_pd_slot;
431 	} else {
432 		pu_slot = sc->active_fps_pu_slot;
433 		pd_slot = sc->active_fps_pd_slot;
434 	}
435 
436 	mask = 0;
437 	val = 0;
438 	if (pu_slot >= 0) {
439 		mask |= MAX77620_FPS_PU_PERIOD_MASK;
440 		val |= ((uint8_t)pu_slot << MAX77620_FPS_PU_PERIOD_SHIFT) &
441 		    MAX77620_FPS_PU_PERIOD_MASK;
442 	}
443 	if (pd_slot >= 0) {
444 		mask |= MAX77620_FPS_PD_PERIOD_MASK;
445 		val |= ((uint8_t)pd_slot << MAX77620_FPS_PD_PERIOD_SHIFT) &
446 		    MAX77620_FPS_PD_PERIOD_MASK;
447 	}
448 
449 	rv = RM1(sc->base_sc, sc->def->fps_reg, mask, val);
450 	if (rv != 0)
451 		return (rv);
452 	return (0);
453 }
454 
455 static int
456 max77620_get_pwr_mode(struct max77620_reg_sc *sc, uint8_t *pwr_mode)
457 {
458 	uint8_t val;
459 	int rv;
460 
461 	rv = RD1(sc->base_sc, sc->def->pwr_mode_reg, &val);
462 	if (rv != 0)
463 		return (rv);
464 
465 	*pwr_mode  = (val & sc->def->pwr_mode_mask) >> sc->def->pwr_mode_shift;
466 	return (0);
467 }
468 
469 static int
470 max77620_set_pwr_mode(struct max77620_reg_sc *sc, uint8_t pwr_mode)
471 {
472 	int rv;
473 
474 	rv = RM1(sc->base_sc, sc->def->pwr_mode_reg, sc->def->pwr_mode_shift,
475 	    pwr_mode << sc->def->pwr_mode_shift);
476 	if (rv != 0)
477 		return (rv);
478 	sc->pwr_mode = pwr_mode;
479 	return (0);
480 }
481 
482 static int
483 max77620_get_pwr_ramp_delay(struct max77620_reg_sc *sc, int *rate)
484 {
485 	uint8_t val;
486 	int rv;
487 
488 	rv = RD1(sc->base_sc, sc->def->cfg_reg, &val);
489 	if (rv != 0)
490 		return (rv);
491 
492 	if (sc->def->is_sd_reg) {
493 		val = (val & MAX77620_SD_SR_MASK) >> MAX77620_SD_SR_SHIFT;
494 		if (val == 0)
495 			*rate = 13750;
496 		else if (val == 1)
497 			*rate = 27500;
498 		else if (val == 2)
499 			*rate = 55000;
500 		else
501 			*rate = 100000;
502 	} else {
503 		val = (val & MAX77620_LDO_SLEW_RATE_MASK) >>
504 		    MAX77620_LDO_SLEW_RATE_SHIFT;
505 		if (val == 0)
506 			*rate = 100000;
507 		else
508 			*rate = 5000;
509 	}
510 	sc->pwr_ramp_delay = *rate;
511 	return (0);
512 }
513 
514 static int
515 max77620_set_pwr_ramp_delay(struct max77620_reg_sc *sc, int rate)
516 {
517 	uint8_t val, mask;
518 	int rv;
519 
520 	if (sc->def->is_sd_reg) {
521 		if (rate <= 13750)
522 			val = 0;
523 		else if (rate <= 27500)
524 			val = 1;
525 		else if (rate <= 55000)
526 			val = 2;
527 		else
528 			val = 3;
529 		val <<= MAX77620_SD_SR_SHIFT;
530 		mask = MAX77620_SD_SR_MASK;
531 	} else {
532 		if (rate <= 5000)
533 			val = 1;
534 		else
535 			val = 0;
536 		val <<= MAX77620_LDO_SLEW_RATE_SHIFT;
537 		mask = MAX77620_LDO_SLEW_RATE_MASK;
538 	}
539 	rv = RM1(sc->base_sc, sc->def->cfg_reg, mask, val);
540 	if (rv != 0)
541 		return (rv);
542 	return (0);
543 }
544 
545 static int
546 max77620_regnode_init(struct regnode *regnode)
547 {
548 	struct max77620_reg_sc *sc;
549 	uint8_t val;
550 	int intval, rv;
551 
552 	sc = regnode_get_softc(regnode);
553 	sc->enable_usec = 500;
554 	sc->enable_pwr_mode = MAX77620_POWER_MODE_NORMAL;
555 #if 0
556 {
557 uint8_t val1, val2, val3;
558 RD1(sc->base_sc, sc->def->volt_reg, &val1);
559 RD1(sc->base_sc, sc->def->cfg_reg, &val2);
560 RD1(sc->base_sc, sc->def->fps_reg, &val3);
561 printf("%s: Volt: 0x%02X, CFG: 0x%02X, FPS: 0x%02X\n", regnode_get_name(sc->regnode), val1, val2, val3);
562 }
563 #endif
564 	/* Get current power mode */
565 	rv = max77620_get_pwr_mode(sc, &val);
566 	if (rv != 0) {
567 		printf("%s: cannot read current power mode: %d\n",
568 		    regnode_get_name(sc->regnode), rv);
569 		return (rv);
570 	}
571 	sc->pwr_mode = val;
572 
573 	/* Get current power ramp delay */
574 	rv = max77620_get_pwr_ramp_delay(sc, &intval);
575 	if (rv != 0) {
576 		printf("%s: cannot read current power mode: %d\n",
577 		    regnode_get_name(sc->regnode), rv);
578 		return (rv);
579 	}
580 	sc->pwr_ramp_delay = intval;
581 
582 	/* Get FPS source if is not specified. */
583 	if (sc->active_fps_src == -1) {
584 		rv = max77620_get_fps_src(sc, &val);
585 		if (rv != 0) {
586 			printf("%s: cannot read current FPS source: %d\n",
587 			    regnode_get_name(sc->regnode), rv);
588 			return (rv);
589 		}
590 		sc->active_fps_src = val;
591 	}
592 
593 	/* Configure power mode non-FPS controlled regulators. */
594 	if (sc->active_fps_src != MAX77620_FPS_SRC_NONE ||
595 	    (sc->pwr_mode != MAX77620_POWER_MODE_DISABLE &&
596 	    sc->pwr_mode != sc->enable_pwr_mode)) {
597 		rv = max77620_set_pwr_mode(sc, (uint8_t)sc->enable_pwr_mode);
598 		if (rv != 0) {
599 			printf("%s: cannot set power mode: %d\n",
600 			    regnode_get_name(sc->regnode), rv);
601 			return (rv);
602 		}
603 	}
604 
605 	/* Set FPS source. */
606 	rv = max77620_set_fps_src(sc, sc->active_fps_src);
607 	if (rv != 0) {
608 		printf("%s: cannot setup FPS source: %d\n",
609 		    regnode_get_name(sc->regnode), rv);
610 		return (rv);
611 	}
612 	/* Set FPS slots. */
613 	rv = max77620_set_fps_slots(sc, false);
614 	if (rv != 0) {
615 		printf("%s: cannot setup power slots: %d\n",
616 		    regnode_get_name(sc->regnode), rv);
617 		return (rv);
618 	}
619 	/* Setup power ramp . */
620 	if (sc->ramp_rate_setting != -1) {
621 		rv = max77620_set_pwr_ramp_delay(sc, sc->pwr_ramp_delay);
622 		if (rv != 0) {
623 			printf("%s: cannot set power ramp delay: %d\n",
624 			    regnode_get_name(sc->regnode), rv);
625 			return (rv);
626 		}
627 	}
628 
629 	return (0);
630 }
631 
632 static void
633 max77620_fdt_parse(struct max77620_softc *sc, phandle_t node, struct reg_def *def,
634 struct max77620_regnode_init_def *init_def)
635 {
636 	int rv;
637 	phandle_t parent, supply_node;
638 	char prop_name[64]; /* Maximum OFW property name length. */
639 
640 	rv = regulator_parse_ofw_stdparam(sc->dev, node,
641 	    &init_def->reg_init_def);
642 
643 	rv = OF_getencprop(node, "maxim,active-fps-source",
644 	    &init_def->active_fps_src, sizeof(init_def->active_fps_src));
645 	if (rv <= 0)
646 		init_def->active_fps_src = MAX77620_FPS_SRC_DEF;
647 
648 	rv = OF_getencprop(node, "maxim,active-fps-power-up-slot",
649 	    &init_def->active_fps_pu_slot, sizeof(init_def->active_fps_pu_slot));
650 	if (rv <= 0)
651 		init_def->active_fps_pu_slot = -1;
652 
653 	rv = OF_getencprop(node, "maxim,active-fps-power-down-slot",
654 	    &init_def->active_fps_pd_slot, sizeof(init_def->active_fps_pd_slot));
655 	if (rv <= 0)
656 		init_def->active_fps_pd_slot = -1;
657 
658 	rv = OF_getencprop(node, "maxim,suspend-fps-source",
659 	    &init_def->suspend_fps_src, sizeof(init_def->suspend_fps_src));
660 	if (rv <= 0)
661 		init_def->suspend_fps_src = -1;
662 
663 	rv = OF_getencprop(node, "maxim,suspend-fps-power-up-slot",
664 	    &init_def->suspend_fps_pu_slot, sizeof(init_def->suspend_fps_pu_slot));
665 	if (rv <= 0)
666 		init_def->suspend_fps_pu_slot = -1;
667 
668 	rv = OF_getencprop(node, "maxim,suspend-fps-power-down-slot",
669 	    &init_def->suspend_fps_pd_slot, sizeof(init_def->suspend_fps_pd_slot));
670 	if (rv <= 0)
671 		init_def->suspend_fps_pd_slot = -1;
672 
673 	rv = OF_getencprop(node, "maxim,ramp-rate-setting",
674 	    &init_def->ramp_rate_setting, sizeof(init_def->ramp_rate_setting));
675 	if (rv <= 0)
676 		init_def->ramp_rate_setting = -1;
677 
678 	/* Get parent supply. */
679 	if (def->supply_name == NULL)
680 		 return;
681 
682 	parent = OF_parent(node);
683 	snprintf(prop_name, sizeof(prop_name), "%s-supply",
684 	    def->supply_name);
685 	rv = OF_getencprop(parent, prop_name, &supply_node,
686 	    sizeof(supply_node));
687 	if (rv <= 0)
688 		return;
689 	supply_node = OF_node_from_xref(supply_node);
690 	rv = OF_getprop_alloc(supply_node, "regulator-name",
691 	    (void **)&init_def->reg_init_def.parent_name);
692 	if (rv <= 0)
693 		init_def->reg_init_def.parent_name = NULL;
694 }
695 
696 static struct max77620_reg_sc *
697 max77620_attach(struct max77620_softc *sc, phandle_t node, struct reg_def *def)
698 {
699 	struct max77620_reg_sc *reg_sc;
700 	struct max77620_regnode_init_def init_def;
701 	struct regnode *regnode;
702 
703 	bzero(&init_def, sizeof(init_def));
704 
705 	max77620_fdt_parse(sc, node, def, &init_def);
706 	init_def.reg_init_def.id = def->id;
707 	init_def.reg_init_def.ofw_node = node;
708 	regnode = regnode_create(sc->dev, &max77620_regnode_class,
709 	    &init_def.reg_init_def);
710 	if (regnode == NULL) {
711 		device_printf(sc->dev, "Cannot create regulator.\n");
712 		return (NULL);
713 	}
714 	reg_sc = regnode_get_softc(regnode);
715 
716 	/* Init regulator softc. */
717 	reg_sc->regnode = regnode;
718 	reg_sc->base_sc = sc;
719 	reg_sc->def = def;
720 	reg_sc->xref = OF_xref_from_node(node);
721 	reg_sc->param = regnode_get_stdparam(regnode);
722 	reg_sc->active_fps_src = init_def.active_fps_src;
723 	reg_sc->active_fps_pu_slot = init_def.active_fps_pu_slot;
724 	reg_sc->active_fps_pd_slot = init_def.active_fps_pd_slot;
725 	reg_sc->suspend_fps_src = init_def.suspend_fps_src;
726 	reg_sc->suspend_fps_pu_slot = init_def.suspend_fps_pu_slot;
727 	reg_sc->suspend_fps_pd_slot = init_def.suspend_fps_pd_slot;
728 	reg_sc->ramp_rate_setting = init_def.ramp_rate_setting;
729 
730 	regnode_register(regnode);
731 	if (bootverbose) {
732 		int volt, rv;
733 		regnode_topo_slock();
734 		rv = regnode_get_voltage(regnode, &volt);
735 		if (rv == ENODEV) {
736 			device_printf(sc->dev,
737 			   " Regulator %s: parent doesn't exist yet.\n",
738 			   regnode_get_name(regnode));
739 		} else if (rv != 0) {
740 			device_printf(sc->dev,
741 			   " Regulator %s: voltage: INVALID!!!\n",
742 			   regnode_get_name(regnode));
743 		} else {
744 			device_printf(sc->dev,
745 			    " Regulator %s: voltage: %d uV\n",
746 			    regnode_get_name(regnode), volt);
747 			device_printf(sc->dev,
748 			    "  FPS source: %d, mode: %d, ramp delay: %d\n",
749 			    reg_sc->fps_src, reg_sc->pwr_mode,
750 			    reg_sc->pwr_ramp_delay);
751 		}
752 		regnode_topo_unlock();
753 	}
754 
755 	return (reg_sc);
756 }
757 
758 int
759 max77620_regulator_attach(struct max77620_softc *sc, phandle_t node)
760 {
761 	struct max77620_reg_sc *reg;
762 	phandle_t child, rnode;
763 	int i;
764 
765 	rnode = ofw_bus_find_child(node, "regulators");
766 	if (rnode <= 0) {
767 		device_printf(sc->dev, " Cannot find regulators subnode\n");
768 		return (ENXIO);
769 	}
770 
771 	sc->nregs = nitems(max77620s_def);
772 	sc->regs = malloc(sizeof(struct max77620_reg_sc *) * sc->nregs,
773 	    M_MAX77620_REG, M_WAITOK | M_ZERO);
774 
775 
776 	/* Attach all known regulators if exist in DT. */
777 	for (i = 0; i < sc->nregs; i++) {
778 		child = ofw_bus_find_child(rnode, max77620s_def[i].name);
779 		if (child == 0) {
780 			if (bootverbose)
781 				device_printf(sc->dev,
782 				    "Regulator %s missing in DT\n",
783 				    max77620s_def[i].name);
784 			continue;
785 		}
786 		if (ofw_bus_node_status_okay(child) == 0)
787 			continue;
788 		reg = max77620_attach(sc, child, max77620s_def + i);
789 		if (reg == NULL) {
790 			device_printf(sc->dev, "Cannot attach regulator: %s\n",
791 			    max77620s_def[i].name);
792 			return (ENXIO);
793 		}
794 		sc->regs[i] = reg;
795 	}
796 	return (0);
797 }
798 
799 int
800 max77620_regulator_map(device_t dev, phandle_t xref, int ncells,
801     pcell_t *cells, intptr_t *num)
802 {
803 	struct max77620_softc *sc;
804 	int i;
805 
806 	sc = device_get_softc(dev);
807 	for (i = 0; i < sc->nregs; i++) {
808 		if (sc->regs[i] == NULL)
809 			continue;
810 		if (sc->regs[i]->xref == xref) {
811 			*num = sc->regs[i]->def->id;
812 			return (0);
813 		}
814 	}
815 
816 	return (ENXIO);
817 }
818 
819 static int
820 max77620_regnode_enable(struct regnode *regnode, bool val, int *udelay)
821 {
822 
823 	struct max77620_reg_sc *sc;
824 	uint8_t mode;
825 	int rv;
826 
827 	sc = regnode_get_softc(regnode);
828 
829 	if (sc->active_fps_src != MAX77620_FPS_SRC_NONE) {
830 		*udelay = 0;
831 		return (0);
832 	}
833 
834 	if (val)
835 		mode = sc->enable_pwr_mode;
836 	else
837 		mode = MAX77620_POWER_MODE_DISABLE;
838 
839 	rv = max77620_set_pwr_mode(sc, mode);
840 	if (rv != 0) {
841 		printf("%s: cannot set power mode: %d\n",
842 		    regnode_get_name(sc->regnode), rv);
843 		return (rv);
844 	}
845 
846 	*udelay = sc->enable_usec;
847 	return (0);
848 }
849 
850 static int
851 max77620_regnode_set_volt(struct regnode *regnode, int min_uvolt, int max_uvolt,
852     int *udelay)
853 {
854 	struct max77620_reg_sc *sc;
855 	uint8_t sel;
856 	int rv;
857 
858 	sc = regnode_get_softc(regnode);
859 
860 	*udelay = 0;
861 	rv = regulator_range_volt_to_sel8(sc->def->ranges, sc->def->nranges,
862 	    min_uvolt, max_uvolt, &sel);
863 	if (rv != 0)
864 		return (rv);
865 	rv = max77620_set_sel(sc, sel);
866 	return (rv);
867 }
868 
869 static int
870 max77620_regnode_get_volt(struct regnode *regnode, int *uvolt)
871 {
872 
873 	struct max77620_reg_sc *sc;
874 	uint8_t sel;
875 	int rv;
876 
877 	sc = regnode_get_softc(regnode);
878 	rv = max77620_get_sel(sc, &sel);
879 	if (rv != 0)
880 		return (rv);
881 
882 	rv = regulator_range_sel8_to_volt(sc->def->ranges, sc->def->nranges,
883 	    sel, uvolt);
884 	return (rv);
885 	return(0);
886 }
887