mtw(4) remove misplaced DEBUG_FLAGS
[freebsd/src.git] / sys / arm64 / nvidia / tegra210 / max77620_regulators.c
blobaf1a5af20ec3da365c6841670ae85365c54e691c
1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
4 * Copyright 2020 Michal Meloun <mmel@FreeBSD.org>
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.
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.
28 #include <sys/param.h>
29 #include <sys/systm.h>
30 #include <sys/bus.h>
31 #include <sys/gpio.h>
32 #include <sys/kernel.h>
33 #include <sys/module.h>
34 #include <sys/malloc.h>
35 #include <sys/rman.h>
36 #include <sys/sx.h>
38 #include <machine/bus.h>
40 #include <dev/regulator/regulator.h>
41 #include <dev/gpio/gpiobusvar.h>
43 #include <dt-bindings/mfd/max77620.h>
45 #include "max77620.h"
47 MALLOC_DEFINE(M_MAX77620_REG, "MAX77620 regulator", "MAX77620 power regulator");
49 #define DIV_ROUND_UP(n,d) howmany(n, d)
51 enum max77620_reg_id {
52 MAX77620_REG_ID_SD0,
53 MAX77620_REG_ID_SD1,
54 MAX77620_REG_ID_SD2,
55 MAX77620_REG_ID_SD3,
56 MAX77620_REG_ID_LDO0,
57 MAX77620_REG_ID_LDO1,
58 MAX77620_REG_ID_LDO2,
59 MAX77620_REG_ID_LDO3,
60 MAX77620_REG_ID_LDO4,
61 MAX77620_REG_ID_LDO5,
62 MAX77620_REG_ID_LDO6,
63 MAX77620_REG_ID_LDO7,
64 MAX77620_REG_ID_LDO8,
67 /* Initial configuration. */
68 struct max77620_regnode_init_def {
69 struct regnode_init_def reg_init_def;
70 int active_fps_src;
71 int active_fps_pu_slot;
72 int active_fps_pd_slot;
73 int suspend_fps_src;
74 int suspend_fps_pu_slot;
75 int suspend_fps_pd_slot;
76 int ramp_rate_setting;
79 /* Regulator HW definition. */
80 struct reg_def {
81 intptr_t id; /* ID */
82 char *name; /* Regulator name */
83 char *supply_name; /* Source property name */
84 bool is_sd_reg; /* SD or LDO regulator? */
85 uint8_t volt_reg;
86 uint8_t volt_vsel_mask;
87 uint8_t cfg_reg;
88 uint8_t fps_reg;
89 uint8_t pwr_mode_reg;
90 uint8_t pwr_mode_mask;
91 uint8_t pwr_mode_shift;
92 struct regulator_range *ranges;
93 int nranges;
96 struct max77620_reg_sc {
97 struct regnode *regnode;
98 struct max77620_softc *base_sc;
99 struct reg_def *def;
100 phandle_t xref;
102 struct regnode_std_param *param;
103 /* Configured values */
104 int active_fps_src;
105 int active_fps_pu_slot;
106 int active_fps_pd_slot;
107 int suspend_fps_src;
108 int suspend_fps_pu_slot;
109 int suspend_fps_pd_slot;
110 int ramp_rate_setting;
111 int enable_usec;
112 uint8_t enable_pwr_mode;
114 /* Cached values */
115 uint8_t fps_src;
116 uint8_t pwr_mode;
117 int pwr_ramp_delay;
120 static struct regulator_range max77620_sd0_ranges[] = {
121 REG_RANGE_INIT(0, 64, 600000, 12500), /* 0.6V - 1.4V / 12.5mV */
124 static struct regulator_range max77620_sd1_ranges[] = {
125 REG_RANGE_INIT(0, 76, 600000, 12500), /* 0.6V - 1.55V / 12.5mV */
128 static struct regulator_range max77620_sdx_ranges[] = {
129 REG_RANGE_INIT(0, 255, 600000, 12500), /* 0.6V - 3.7875V / 12.5mV */
132 static struct regulator_range max77620_ldo0_1_ranges[] = {
133 REG_RANGE_INIT(0, 63, 800000, 25000), /* 0.8V - 2.375V / 25mV */
136 static struct regulator_range max77620_ldo4_ranges[] = {
137 REG_RANGE_INIT(0, 63, 800000, 12500), /* 0.8V - 1.5875V / 12.5mV */
140 static struct regulator_range max77620_ldox_ranges[] = {
141 REG_RANGE_INIT(0, 63, 800000, 50000), /* 0.8V - 3.95V / 50mV */
144 static struct reg_def max77620s_def[] = {
146 .id = MAX77620_REG_ID_SD0,
147 .name = "sd0",
148 .supply_name = "in-sd0",
149 .is_sd_reg = true,
150 .volt_reg = MAX77620_REG_SD0,
151 .volt_vsel_mask = MAX77620_SD0_VSEL_MASK,
152 .cfg_reg = MAX77620_REG_CFG_SD0,
153 .fps_reg = MAX77620_REG_FPS_SD0,
154 .pwr_mode_reg = MAX77620_REG_CFG_SD0,
155 .pwr_mode_mask = MAX77620_SD_POWER_MODE_MASK,
156 .pwr_mode_shift = MAX77620_SD_POWER_MODE_SHIFT,
157 .ranges = max77620_sd0_ranges,
158 .nranges = nitems(max77620_sd0_ranges),
161 .id = MAX77620_REG_ID_SD1,
162 .name = "sd1",
163 .supply_name = "in-sd1",
164 .is_sd_reg = true,
165 .volt_reg = MAX77620_REG_SD1,
166 .volt_vsel_mask = MAX77620_SD1_VSEL_MASK,
167 .cfg_reg = MAX77620_REG_CFG_SD1,
168 .fps_reg = MAX77620_REG_FPS_SD1,
169 .pwr_mode_reg = MAX77620_REG_CFG_SD1,
170 .pwr_mode_mask = MAX77620_SD_POWER_MODE_MASK,
171 .pwr_mode_shift = MAX77620_SD_POWER_MODE_SHIFT,
172 .ranges = max77620_sd1_ranges,
173 .nranges = nitems(max77620_sd1_ranges),
176 .id = MAX77620_REG_ID_SD2,
177 .name = "sd2",
178 .supply_name = "in-sd2",
179 .is_sd_reg = true,
180 .volt_reg = MAX77620_REG_SD2,
181 .volt_vsel_mask = MAX77620_SDX_VSEL_MASK,
182 .cfg_reg = MAX77620_REG_CFG_SD2,
183 .fps_reg = MAX77620_REG_FPS_SD2,
184 .pwr_mode_reg = MAX77620_REG_CFG_SD2,
185 .pwr_mode_mask = MAX77620_SD_POWER_MODE_MASK,
186 .pwr_mode_shift = MAX77620_SD_POWER_MODE_SHIFT,
187 .ranges = max77620_sdx_ranges,
188 .nranges = nitems(max77620_sdx_ranges),
191 .id = MAX77620_REG_ID_SD3,
192 .name = "sd3",
193 .supply_name = "in-sd3",
194 .is_sd_reg = true,
195 .volt_reg = MAX77620_REG_SD3,
196 .volt_vsel_mask = MAX77620_SDX_VSEL_MASK,
197 .cfg_reg = MAX77620_REG_CFG_SD3,
198 .fps_reg = MAX77620_REG_FPS_SD3,
199 .pwr_mode_reg = MAX77620_REG_CFG_SD3,
200 .pwr_mode_mask = MAX77620_SD_POWER_MODE_MASK,
201 .pwr_mode_shift = MAX77620_SD_POWER_MODE_SHIFT,
202 .ranges = max77620_sdx_ranges,
203 .nranges = nitems(max77620_sdx_ranges),
206 .id = MAX77620_REG_ID_LDO0,
207 .name = "ldo0",
208 .supply_name = "vin-ldo0-1",
209 .volt_reg = MAX77620_REG_CFG_LDO0,
210 .volt_vsel_mask = MAX77620_LDO_VSEL_MASK,
211 .is_sd_reg = false,
212 .cfg_reg = MAX77620_REG_CFG2_LDO0,
213 .fps_reg = MAX77620_REG_FPS_LDO0,
214 .pwr_mode_reg = MAX77620_REG_CFG_LDO0,
215 .pwr_mode_mask = MAX77620_LDO_POWER_MODE_MASK,
216 .pwr_mode_shift = MAX77620_LDO_POWER_MODE_SHIFT,
217 .ranges = max77620_ldo0_1_ranges,
218 .nranges = nitems(max77620_ldo0_1_ranges),
221 .id = MAX77620_REG_ID_LDO1,
222 .name = "ldo1",
223 .supply_name = "in-ldo0-1",
224 .is_sd_reg = false,
225 .volt_reg = MAX77620_REG_CFG_LDO1,
226 .volt_vsel_mask = MAX77620_LDO_VSEL_MASK,
227 .cfg_reg = MAX77620_REG_CFG2_LDO1,
228 .fps_reg = MAX77620_REG_FPS_LDO1,
229 .pwr_mode_reg = MAX77620_REG_CFG_LDO1,
230 .pwr_mode_mask = MAX77620_LDO_POWER_MODE_MASK,
231 .pwr_mode_shift = MAX77620_LDO_POWER_MODE_SHIFT,
232 .ranges = max77620_ldo0_1_ranges,
233 .nranges = nitems(max77620_ldo0_1_ranges),
236 .id = MAX77620_REG_ID_LDO2,
237 .name = "ldo2",
238 .supply_name = "in-ldo2",
239 .is_sd_reg = false,
240 .volt_reg = MAX77620_REG_CFG_LDO2,
241 .volt_vsel_mask = MAX77620_LDO_VSEL_MASK,
242 .cfg_reg = MAX77620_REG_CFG2_LDO2,
243 .fps_reg = MAX77620_REG_FPS_LDO2,
244 .pwr_mode_reg = MAX77620_REG_CFG_LDO2,
245 .pwr_mode_mask = MAX77620_LDO_POWER_MODE_MASK,
246 .pwr_mode_shift = MAX77620_LDO_POWER_MODE_SHIFT,
247 .ranges = max77620_ldox_ranges,
248 .nranges = nitems(max77620_ldox_ranges),
251 .id = MAX77620_REG_ID_LDO3,
252 .name = "ldo3",
253 .supply_name = "in-ldo3-5",
254 .is_sd_reg = false,
255 .volt_reg = MAX77620_REG_CFG_LDO3,
256 .volt_vsel_mask = MAX77620_LDO_VSEL_MASK,
257 .cfg_reg = MAX77620_REG_CFG2_LDO3,
258 .fps_reg = MAX77620_REG_FPS_LDO3,
259 .pwr_mode_reg = MAX77620_REG_CFG_LDO3,
260 .pwr_mode_mask = MAX77620_LDO_POWER_MODE_MASK,
261 .pwr_mode_shift = MAX77620_LDO_POWER_MODE_SHIFT,
262 .ranges = max77620_ldox_ranges,
263 .nranges = nitems(max77620_ldox_ranges),
266 .id = MAX77620_REG_ID_LDO4,
267 .name = "ldo4",
268 .supply_name = "in-ldo4-6",
269 .is_sd_reg = false,
270 .volt_reg = MAX77620_REG_CFG_LDO4,
271 .volt_vsel_mask = MAX77620_LDO_VSEL_MASK,
272 .cfg_reg = MAX77620_REG_CFG2_LDO4,
273 .fps_reg = MAX77620_REG_FPS_LDO4,
274 .pwr_mode_reg = MAX77620_REG_CFG_LDO4,
275 .pwr_mode_mask = MAX77620_LDO_POWER_MODE_MASK,
276 .pwr_mode_shift = MAX77620_LDO_POWER_MODE_SHIFT,
277 .ranges = max77620_ldo4_ranges,
278 .nranges = nitems(max77620_ldo4_ranges),
281 .id = MAX77620_REG_ID_LDO5,
282 .name = "ldo5",
283 .supply_name = "in-ldo3-5",
284 .is_sd_reg = false,
285 .volt_reg = MAX77620_REG_CFG_LDO5,
286 .volt_vsel_mask = MAX77620_LDO_VSEL_MASK,
287 .cfg_reg = MAX77620_REG_CFG2_LDO5,
288 .fps_reg = MAX77620_REG_FPS_LDO5,
289 .pwr_mode_reg = MAX77620_REG_CFG_LDO5,
290 .pwr_mode_mask = MAX77620_LDO_POWER_MODE_MASK,
291 .pwr_mode_shift = MAX77620_LDO_POWER_MODE_SHIFT,
292 .ranges = max77620_ldox_ranges,
293 .nranges = nitems(max77620_ldox_ranges),
296 .id = MAX77620_REG_ID_LDO6,
297 .name = "ldo6",
298 .supply_name = "in-ldo4-6",
299 .is_sd_reg = false,
300 .volt_reg = MAX77620_REG_CFG_LDO6,
301 .volt_vsel_mask = MAX77620_LDO_VSEL_MASK,
302 .cfg_reg = MAX77620_REG_CFG2_LDO6,
303 .fps_reg = MAX77620_REG_FPS_LDO6,
304 .pwr_mode_reg = MAX77620_REG_CFG_LDO6,
305 .pwr_mode_mask = MAX77620_LDO_POWER_MODE_MASK,
306 .pwr_mode_shift = MAX77620_LDO_POWER_MODE_SHIFT,
307 .ranges = max77620_ldox_ranges,
308 .nranges = nitems(max77620_ldox_ranges),
311 .id = MAX77620_REG_ID_LDO7,
312 .name = "ldo7",
313 .supply_name = "in-ldo7-8",
314 .is_sd_reg = false,
315 .volt_reg = MAX77620_REG_CFG_LDO7,
316 .volt_vsel_mask = MAX77620_LDO_VSEL_MASK,
317 .cfg_reg = MAX77620_REG_CFG2_LDO7,
318 .fps_reg = MAX77620_REG_FPS_LDO7,
319 .pwr_mode_reg = MAX77620_REG_CFG_LDO7,
320 .pwr_mode_mask = MAX77620_LDO_POWER_MODE_MASK,
321 .pwr_mode_shift = MAX77620_LDO_POWER_MODE_SHIFT,
322 .ranges = max77620_ldox_ranges,
323 .nranges = nitems(max77620_ldox_ranges),
326 .id = MAX77620_REG_ID_LDO8,
327 .name = "ldo8",
328 .supply_name = "in-ldo7-8",
329 .is_sd_reg = false,
330 .volt_reg = MAX77620_REG_CFG_LDO8,
331 .volt_vsel_mask = MAX77620_LDO_VSEL_MASK,
332 .cfg_reg = MAX77620_REG_CFG2_LDO8,
333 .fps_reg = MAX77620_REG_FPS_LDO8,
334 .pwr_mode_reg = MAX77620_REG_CFG_LDO8,
335 .pwr_mode_mask = MAX77620_LDO_POWER_MODE_MASK,
336 .pwr_mode_shift = MAX77620_LDO_POWER_MODE_SHIFT,
337 .ranges = max77620_ldox_ranges,
338 .nranges = nitems(max77620_ldox_ranges),
343 static int max77620_regnode_init(struct regnode *regnode);
344 static int max77620_regnode_enable(struct regnode *regnode, bool enable,
345 int *udelay);
346 static int max77620_regnode_set_volt(struct regnode *regnode, int min_uvolt,
347 int max_uvolt, int *udelay);
348 static int max77620_regnode_get_volt(struct regnode *regnode, int *uvolt);
349 static regnode_method_t max77620_regnode_methods[] = {
350 /* Regulator interface */
351 REGNODEMETHOD(regnode_init, max77620_regnode_init),
352 REGNODEMETHOD(regnode_enable, max77620_regnode_enable),
353 REGNODEMETHOD(regnode_set_voltage, max77620_regnode_set_volt),
354 REGNODEMETHOD(regnode_get_voltage, max77620_regnode_get_volt),
355 REGNODEMETHOD_END
357 DEFINE_CLASS_1(max77620_regnode, max77620_regnode_class, max77620_regnode_methods,
358 sizeof(struct max77620_reg_sc), regnode_class);
360 static int
361 max77620_get_sel(struct max77620_reg_sc *sc, uint8_t *sel)
363 int rv;
365 rv = RD1(sc->base_sc, sc->def->volt_reg, sel);
366 if (rv != 0) {
367 printf("%s: cannot read volatge selector: %d\n",
368 regnode_get_name(sc->regnode), rv);
369 return (rv);
371 *sel &= sc->def->volt_vsel_mask;
372 *sel >>= ffs(sc->def->volt_vsel_mask) - 1;
373 return (0);
376 static int
377 max77620_set_sel(struct max77620_reg_sc *sc, uint8_t sel)
379 int rv;
381 sel <<= ffs(sc->def->volt_vsel_mask) - 1;
382 sel &= sc->def->volt_vsel_mask;
384 rv = RM1(sc->base_sc, sc->def->volt_reg,
385 sc->def->volt_vsel_mask, sel);
386 if (rv != 0) {
387 printf("%s: cannot set volatge selector: %d\n",
388 regnode_get_name(sc->regnode), rv);
389 return (rv);
391 return (rv);
394 static int
395 max77620_get_fps_src(struct max77620_reg_sc *sc, uint8_t *fps_src)
397 uint8_t val;
398 int rv;
400 rv = RD1(sc->base_sc, sc->def->fps_reg, &val);
401 if (rv != 0)
402 return (rv);
404 *fps_src = (val & MAX77620_FPS_SRC_MASK) >> MAX77620_FPS_SRC_SHIFT;
405 return (0);
408 static int
409 max77620_set_fps_src(struct max77620_reg_sc *sc, uint8_t fps_src)
411 int rv;
413 rv = RM1(sc->base_sc, sc->def->fps_reg, MAX77620_FPS_SRC_MASK,
414 fps_src << MAX77620_FPS_SRC_SHIFT);
415 if (rv != 0)
416 return (rv);
417 sc->fps_src = fps_src;
418 return (0);
421 static int
422 max77620_set_fps_slots(struct max77620_reg_sc *sc, bool suspend)
424 uint8_t mask, val;
425 int pu_slot, pd_slot, rv;
427 if (suspend) {
428 pu_slot = sc->suspend_fps_pu_slot;
429 pd_slot = sc->suspend_fps_pd_slot;
430 } else {
431 pu_slot = sc->active_fps_pu_slot;
432 pd_slot = sc->active_fps_pd_slot;
435 mask = 0;
436 val = 0;
437 if (pu_slot >= 0) {
438 mask |= MAX77620_FPS_PU_PERIOD_MASK;
439 val |= ((uint8_t)pu_slot << MAX77620_FPS_PU_PERIOD_SHIFT) &
440 MAX77620_FPS_PU_PERIOD_MASK;
442 if (pd_slot >= 0) {
443 mask |= MAX77620_FPS_PD_PERIOD_MASK;
444 val |= ((uint8_t)pd_slot << MAX77620_FPS_PD_PERIOD_SHIFT) &
445 MAX77620_FPS_PD_PERIOD_MASK;
448 rv = RM1(sc->base_sc, sc->def->fps_reg, mask, val);
449 if (rv != 0)
450 return (rv);
451 return (0);
454 static int
455 max77620_get_pwr_mode(struct max77620_reg_sc *sc, uint8_t *pwr_mode)
457 uint8_t val;
458 int rv;
460 rv = RD1(sc->base_sc, sc->def->pwr_mode_reg, &val);
461 if (rv != 0)
462 return (rv);
464 *pwr_mode = (val & sc->def->pwr_mode_mask) >> sc->def->pwr_mode_shift;
465 return (0);
468 static int
469 max77620_set_pwr_mode(struct max77620_reg_sc *sc, uint8_t pwr_mode)
471 int rv;
473 rv = RM1(sc->base_sc, sc->def->pwr_mode_reg, sc->def->pwr_mode_shift,
474 pwr_mode << sc->def->pwr_mode_shift);
475 if (rv != 0)
476 return (rv);
477 sc->pwr_mode = pwr_mode;
478 return (0);
481 static int
482 max77620_get_pwr_ramp_delay(struct max77620_reg_sc *sc, int *rate)
484 uint8_t val;
485 int rv;
487 rv = RD1(sc->base_sc, sc->def->cfg_reg, &val);
488 if (rv != 0)
489 return (rv);
491 if (sc->def->is_sd_reg) {
492 val = (val & MAX77620_SD_SR_MASK) >> MAX77620_SD_SR_SHIFT;
493 if (val == 0)
494 *rate = 13750;
495 else if (val == 1)
496 *rate = 27500;
497 else if (val == 2)
498 *rate = 55000;
499 else
500 *rate = 100000;
501 } else {
502 val = (val & MAX77620_LDO_SLEW_RATE_MASK) >>
503 MAX77620_LDO_SLEW_RATE_SHIFT;
504 if (val == 0)
505 *rate = 100000;
506 else
507 *rate = 5000;
509 sc->pwr_ramp_delay = *rate;
510 return (0);
513 static int
514 max77620_set_pwr_ramp_delay(struct max77620_reg_sc *sc, int rate)
516 uint8_t val, mask;
517 int rv;
519 if (sc->def->is_sd_reg) {
520 if (rate <= 13750)
521 val = 0;
522 else if (rate <= 27500)
523 val = 1;
524 else if (rate <= 55000)
525 val = 2;
526 else
527 val = 3;
528 val <<= MAX77620_SD_SR_SHIFT;
529 mask = MAX77620_SD_SR_MASK;
530 } else {
531 if (rate <= 5000)
532 val = 1;
533 else
534 val = 0;
535 val <<= MAX77620_LDO_SLEW_RATE_SHIFT;
536 mask = MAX77620_LDO_SLEW_RATE_MASK;
538 rv = RM1(sc->base_sc, sc->def->cfg_reg, mask, val);
539 if (rv != 0)
540 return (rv);
541 return (0);
544 static int
545 max77620_regnode_init(struct regnode *regnode)
547 struct max77620_reg_sc *sc;
548 uint8_t val;
549 int intval, rv;
551 sc = regnode_get_softc(regnode);
552 sc->enable_usec = 500;
553 sc->enable_pwr_mode = MAX77620_POWER_MODE_NORMAL;
554 #if 0
556 uint8_t val1, val2, val3;
557 RD1(sc->base_sc, sc->def->volt_reg, &val1);
558 RD1(sc->base_sc, sc->def->cfg_reg, &val2);
559 RD1(sc->base_sc, sc->def->fps_reg, &val3);
560 printf("%s: Volt: 0x%02X, CFG: 0x%02X, FPS: 0x%02X\n", regnode_get_name(sc->regnode), val1, val2, val3);
562 #endif
563 /* Get current power mode */
564 rv = max77620_get_pwr_mode(sc, &val);
565 if (rv != 0) {
566 printf("%s: cannot read current power mode: %d\n",
567 regnode_get_name(sc->regnode), rv);
568 return (rv);
570 sc->pwr_mode = val;
572 /* Get current power ramp delay */
573 rv = max77620_get_pwr_ramp_delay(sc, &intval);
574 if (rv != 0) {
575 printf("%s: cannot read current power mode: %d\n",
576 regnode_get_name(sc->regnode), rv);
577 return (rv);
579 sc->pwr_ramp_delay = intval;
581 /* Get FPS source if is not specified. */
582 if (sc->active_fps_src == -1) {
583 rv = max77620_get_fps_src(sc, &val);
584 if (rv != 0) {
585 printf("%s: cannot read current FPS source: %d\n",
586 regnode_get_name(sc->regnode), rv);
587 return (rv);
589 sc->active_fps_src = val;
592 /* Configure power mode non-FPS controlled regulators. */
593 if (sc->active_fps_src != MAX77620_FPS_SRC_NONE ||
594 (sc->pwr_mode != MAX77620_POWER_MODE_DISABLE &&
595 sc->pwr_mode != sc->enable_pwr_mode)) {
596 rv = max77620_set_pwr_mode(sc, (uint8_t)sc->enable_pwr_mode);
597 if (rv != 0) {
598 printf("%s: cannot set power mode: %d\n",
599 regnode_get_name(sc->regnode), rv);
600 return (rv);
604 /* Set FPS source. */
605 rv = max77620_set_fps_src(sc, sc->active_fps_src);
606 if (rv != 0) {
607 printf("%s: cannot setup FPS source: %d\n",
608 regnode_get_name(sc->regnode), rv);
609 return (rv);
611 /* Set FPS slots. */
612 rv = max77620_set_fps_slots(sc, false);
613 if (rv != 0) {
614 printf("%s: cannot setup power slots: %d\n",
615 regnode_get_name(sc->regnode), rv);
616 return (rv);
618 /* Setup power ramp . */
619 if (sc->ramp_rate_setting != -1) {
620 rv = max77620_set_pwr_ramp_delay(sc, sc->pwr_ramp_delay);
621 if (rv != 0) {
622 printf("%s: cannot set power ramp delay: %d\n",
623 regnode_get_name(sc->regnode), rv);
624 return (rv);
628 return (0);
631 static void
632 max77620_fdt_parse(struct max77620_softc *sc, phandle_t node, struct reg_def *def,
633 struct max77620_regnode_init_def *init_def)
635 int rv;
636 phandle_t parent, supply_node;
637 char prop_name[64]; /* Maximum OFW property name length. */
639 rv = regulator_parse_ofw_stdparam(sc->dev, node,
640 &init_def->reg_init_def);
642 rv = OF_getencprop(node, "maxim,active-fps-source",
643 &init_def->active_fps_src, sizeof(init_def->active_fps_src));
644 if (rv <= 0)
645 init_def->active_fps_src = MAX77620_FPS_SRC_DEF;
647 rv = OF_getencprop(node, "maxim,active-fps-power-up-slot",
648 &init_def->active_fps_pu_slot, sizeof(init_def->active_fps_pu_slot));
649 if (rv <= 0)
650 init_def->active_fps_pu_slot = -1;
652 rv = OF_getencprop(node, "maxim,active-fps-power-down-slot",
653 &init_def->active_fps_pd_slot, sizeof(init_def->active_fps_pd_slot));
654 if (rv <= 0)
655 init_def->active_fps_pd_slot = -1;
657 rv = OF_getencprop(node, "maxim,suspend-fps-source",
658 &init_def->suspend_fps_src, sizeof(init_def->suspend_fps_src));
659 if (rv <= 0)
660 init_def->suspend_fps_src = -1;
662 rv = OF_getencprop(node, "maxim,suspend-fps-power-up-slot",
663 &init_def->suspend_fps_pu_slot, sizeof(init_def->suspend_fps_pu_slot));
664 if (rv <= 0)
665 init_def->suspend_fps_pu_slot = -1;
667 rv = OF_getencprop(node, "maxim,suspend-fps-power-down-slot",
668 &init_def->suspend_fps_pd_slot, sizeof(init_def->suspend_fps_pd_slot));
669 if (rv <= 0)
670 init_def->suspend_fps_pd_slot = -1;
672 rv = OF_getencprop(node, "maxim,ramp-rate-setting",
673 &init_def->ramp_rate_setting, sizeof(init_def->ramp_rate_setting));
674 if (rv <= 0)
675 init_def->ramp_rate_setting = -1;
677 /* Get parent supply. */
678 if (def->supply_name == NULL)
679 return;
681 parent = OF_parent(node);
682 snprintf(prop_name, sizeof(prop_name), "%s-supply",
683 def->supply_name);
684 rv = OF_getencprop(parent, prop_name, &supply_node,
685 sizeof(supply_node));
686 if (rv <= 0)
687 return;
688 supply_node = OF_node_from_xref(supply_node);
689 rv = OF_getprop_alloc(supply_node, "regulator-name",
690 (void **)&init_def->reg_init_def.parent_name);
691 if (rv <= 0)
692 init_def->reg_init_def.parent_name = NULL;
695 static struct max77620_reg_sc *
696 max77620_attach(struct max77620_softc *sc, phandle_t node, struct reg_def *def)
698 struct max77620_reg_sc *reg_sc;
699 struct max77620_regnode_init_def init_def;
700 struct regnode *regnode;
702 bzero(&init_def, sizeof(init_def));
704 max77620_fdt_parse(sc, node, def, &init_def);
705 init_def.reg_init_def.id = def->id;
706 init_def.reg_init_def.ofw_node = node;
707 regnode = regnode_create(sc->dev, &max77620_regnode_class,
708 &init_def.reg_init_def);
709 if (regnode == NULL) {
710 device_printf(sc->dev, "Cannot create regulator.\n");
711 return (NULL);
713 reg_sc = regnode_get_softc(regnode);
715 /* Init regulator softc. */
716 reg_sc->regnode = regnode;
717 reg_sc->base_sc = sc;
718 reg_sc->def = def;
719 reg_sc->xref = OF_xref_from_node(node);
720 reg_sc->param = regnode_get_stdparam(regnode);
721 reg_sc->active_fps_src = init_def.active_fps_src;
722 reg_sc->active_fps_pu_slot = init_def.active_fps_pu_slot;
723 reg_sc->active_fps_pd_slot = init_def.active_fps_pd_slot;
724 reg_sc->suspend_fps_src = init_def.suspend_fps_src;
725 reg_sc->suspend_fps_pu_slot = init_def.suspend_fps_pu_slot;
726 reg_sc->suspend_fps_pd_slot = init_def.suspend_fps_pd_slot;
727 reg_sc->ramp_rate_setting = init_def.ramp_rate_setting;
729 regnode_register(regnode);
730 if (bootverbose) {
731 int volt, rv;
732 regnode_topo_slock();
733 rv = regnode_get_voltage(regnode, &volt);
734 if (rv == ENODEV) {
735 device_printf(sc->dev,
736 " Regulator %s: parent doesn't exist yet.\n",
737 regnode_get_name(regnode));
738 } else if (rv != 0) {
739 device_printf(sc->dev,
740 " Regulator %s: voltage: INVALID!!!\n",
741 regnode_get_name(regnode));
742 } else {
743 device_printf(sc->dev,
744 " Regulator %s: voltage: %d uV\n",
745 regnode_get_name(regnode), volt);
746 device_printf(sc->dev,
747 " FPS source: %d, mode: %d, ramp delay: %d\n",
748 reg_sc->fps_src, reg_sc->pwr_mode,
749 reg_sc->pwr_ramp_delay);
751 regnode_topo_unlock();
754 return (reg_sc);
758 max77620_regulator_attach(struct max77620_softc *sc, phandle_t node)
760 struct max77620_reg_sc *reg;
761 phandle_t child, rnode;
762 int i;
764 rnode = ofw_bus_find_child(node, "regulators");
765 if (rnode <= 0) {
766 device_printf(sc->dev, " Cannot find regulators subnode\n");
767 return (ENXIO);
770 sc->nregs = nitems(max77620s_def);
771 sc->regs = malloc(sizeof(struct max77620_reg_sc *) * sc->nregs,
772 M_MAX77620_REG, M_WAITOK | M_ZERO);
775 /* Attach all known regulators if exist in DT. */
776 for (i = 0; i < sc->nregs; i++) {
777 child = ofw_bus_find_child(rnode, max77620s_def[i].name);
778 if (child == 0) {
779 if (bootverbose)
780 device_printf(sc->dev,
781 "Regulator %s missing in DT\n",
782 max77620s_def[i].name);
783 continue;
785 if (ofw_bus_node_status_okay(child) == 0)
786 continue;
787 reg = max77620_attach(sc, child, max77620s_def + i);
788 if (reg == NULL) {
789 device_printf(sc->dev, "Cannot attach regulator: %s\n",
790 max77620s_def[i].name);
791 return (ENXIO);
793 sc->regs[i] = reg;
795 return (0);
799 max77620_regulator_map(device_t dev, phandle_t xref, int ncells,
800 pcell_t *cells, intptr_t *num)
802 struct max77620_softc *sc;
803 int i;
805 sc = device_get_softc(dev);
806 for (i = 0; i < sc->nregs; i++) {
807 if (sc->regs[i] == NULL)
808 continue;
809 if (sc->regs[i]->xref == xref) {
810 *num = sc->regs[i]->def->id;
811 return (0);
815 return (ENXIO);
818 static int
819 max77620_regnode_enable(struct regnode *regnode, bool val, int *udelay)
822 struct max77620_reg_sc *sc;
823 uint8_t mode;
824 int rv;
826 sc = regnode_get_softc(regnode);
828 if (sc->active_fps_src != MAX77620_FPS_SRC_NONE) {
829 *udelay = 0;
830 return (0);
833 if (val)
834 mode = sc->enable_pwr_mode;
835 else
836 mode = MAX77620_POWER_MODE_DISABLE;
838 rv = max77620_set_pwr_mode(sc, mode);
839 if (rv != 0) {
840 printf("%s: cannot set power mode: %d\n",
841 regnode_get_name(sc->regnode), rv);
842 return (rv);
845 *udelay = sc->enable_usec;
846 return (0);
849 static int
850 max77620_regnode_set_volt(struct regnode *regnode, int min_uvolt, int max_uvolt,
851 int *udelay)
853 struct max77620_reg_sc *sc;
854 uint8_t sel;
855 int rv;
857 sc = regnode_get_softc(regnode);
859 *udelay = 0;
860 rv = regulator_range_volt_to_sel8(sc->def->ranges, sc->def->nranges,
861 min_uvolt, max_uvolt, &sel);
862 if (rv != 0)
863 return (rv);
864 rv = max77620_set_sel(sc, sel);
865 return (rv);
868 static int
869 max77620_regnode_get_volt(struct regnode *regnode, int *uvolt)
872 struct max77620_reg_sc *sc;
873 uint8_t sel;
874 int rv;
876 sc = regnode_get_softc(regnode);
877 rv = max77620_get_sel(sc, &sel);
878 if (rv != 0)
879 return (rv);
881 rv = regulator_range_sel8_to_volt(sc->def->ranges, sc->def->nranges,
882 sel, uvolt);
883 return (rv);
884 return(0);