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
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
28 #include <sys/param.h>
29 #include <sys/systm.h>
32 #include <sys/kernel.h>
33 #include <sys/module.h>
34 #include <sys/malloc.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>
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
{
67 /* Initial configuration. */
68 struct max77620_regnode_init_def
{
69 struct regnode_init_def reg_init_def
;
71 int active_fps_pu_slot
;
72 int active_fps_pd_slot
;
74 int suspend_fps_pu_slot
;
75 int suspend_fps_pd_slot
;
76 int ramp_rate_setting
;
79 /* Regulator HW definition. */
82 char *name
; /* Regulator name */
83 char *supply_name
; /* Source property name */
84 bool is_sd_reg
; /* SD or LDO regulator? */
86 uint8_t volt_vsel_mask
;
90 uint8_t pwr_mode_mask
;
91 uint8_t pwr_mode_shift
;
92 struct regulator_range
*ranges
;
96 struct max77620_reg_sc
{
97 struct regnode
*regnode
;
98 struct max77620_softc
*base_sc
;
102 struct regnode_std_param
*param
;
103 /* Configured values */
105 int active_fps_pu_slot
;
106 int active_fps_pd_slot
;
108 int suspend_fps_pu_slot
;
109 int suspend_fps_pd_slot
;
110 int ramp_rate_setting
;
112 uint8_t enable_pwr_mode
;
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
,
148 .supply_name
= "in-sd0",
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
,
163 .supply_name
= "in-sd1",
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
,
178 .supply_name
= "in-sd2",
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
,
193 .supply_name
= "in-sd3",
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
,
208 .supply_name
= "vin-ldo0-1",
209 .volt_reg
= MAX77620_REG_CFG_LDO0
,
210 .volt_vsel_mask
= MAX77620_LDO_VSEL_MASK
,
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
,
223 .supply_name
= "in-ldo0-1",
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
,
238 .supply_name
= "in-ldo2",
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
,
253 .supply_name
= "in-ldo3-5",
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
,
268 .supply_name
= "in-ldo4-6",
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
,
283 .supply_name
= "in-ldo3-5",
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
,
298 .supply_name
= "in-ldo4-6",
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
,
313 .supply_name
= "in-ldo7-8",
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
,
328 .supply_name
= "in-ldo7-8",
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
,
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
),
357 DEFINE_CLASS_1(max77620_regnode
, max77620_regnode_class
, max77620_regnode_methods
,
358 sizeof(struct max77620_reg_sc
), regnode_class
);
361 max77620_get_sel(struct max77620_reg_sc
*sc
, uint8_t *sel
)
365 rv
= RD1(sc
->base_sc
, sc
->def
->volt_reg
, sel
);
367 printf("%s: cannot read volatge selector: %d\n",
368 regnode_get_name(sc
->regnode
), rv
);
371 *sel
&= sc
->def
->volt_vsel_mask
;
372 *sel
>>= ffs(sc
->def
->volt_vsel_mask
) - 1;
377 max77620_set_sel(struct max77620_reg_sc
*sc
, uint8_t sel
)
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
);
387 printf("%s: cannot set volatge selector: %d\n",
388 regnode_get_name(sc
->regnode
), rv
);
395 max77620_get_fps_src(struct max77620_reg_sc
*sc
, uint8_t *fps_src
)
400 rv
= RD1(sc
->base_sc
, sc
->def
->fps_reg
, &val
);
404 *fps_src
= (val
& MAX77620_FPS_SRC_MASK
) >> MAX77620_FPS_SRC_SHIFT
;
409 max77620_set_fps_src(struct max77620_reg_sc
*sc
, uint8_t fps_src
)
413 rv
= RM1(sc
->base_sc
, sc
->def
->fps_reg
, MAX77620_FPS_SRC_MASK
,
414 fps_src
<< MAX77620_FPS_SRC_SHIFT
);
417 sc
->fps_src
= fps_src
;
422 max77620_set_fps_slots(struct max77620_reg_sc
*sc
, bool suspend
)
425 int pu_slot
, pd_slot
, rv
;
428 pu_slot
= sc
->suspend_fps_pu_slot
;
429 pd_slot
= sc
->suspend_fps_pd_slot
;
431 pu_slot
= sc
->active_fps_pu_slot
;
432 pd_slot
= sc
->active_fps_pd_slot
;
438 mask
|= MAX77620_FPS_PU_PERIOD_MASK
;
439 val
|= ((uint8_t)pu_slot
<< MAX77620_FPS_PU_PERIOD_SHIFT
) &
440 MAX77620_FPS_PU_PERIOD_MASK
;
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
);
455 max77620_get_pwr_mode(struct max77620_reg_sc
*sc
, uint8_t *pwr_mode
)
460 rv
= RD1(sc
->base_sc
, sc
->def
->pwr_mode_reg
, &val
);
464 *pwr_mode
= (val
& sc
->def
->pwr_mode_mask
) >> sc
->def
->pwr_mode_shift
;
469 max77620_set_pwr_mode(struct max77620_reg_sc
*sc
, uint8_t pwr_mode
)
473 rv
= RM1(sc
->base_sc
, sc
->def
->pwr_mode_reg
, sc
->def
->pwr_mode_shift
,
474 pwr_mode
<< sc
->def
->pwr_mode_shift
);
477 sc
->pwr_mode
= pwr_mode
;
482 max77620_get_pwr_ramp_delay(struct max77620_reg_sc
*sc
, int *rate
)
487 rv
= RD1(sc
->base_sc
, sc
->def
->cfg_reg
, &val
);
491 if (sc
->def
->is_sd_reg
) {
492 val
= (val
& MAX77620_SD_SR_MASK
) >> MAX77620_SD_SR_SHIFT
;
502 val
= (val
& MAX77620_LDO_SLEW_RATE_MASK
) >>
503 MAX77620_LDO_SLEW_RATE_SHIFT
;
509 sc
->pwr_ramp_delay
= *rate
;
514 max77620_set_pwr_ramp_delay(struct max77620_reg_sc
*sc
, int rate
)
519 if (sc
->def
->is_sd_reg
) {
522 else if (rate
<= 27500)
524 else if (rate
<= 55000)
528 val
<<= MAX77620_SD_SR_SHIFT
;
529 mask
= MAX77620_SD_SR_MASK
;
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
);
545 max77620_regnode_init(struct regnode
*regnode
)
547 struct max77620_reg_sc
*sc
;
551 sc
= regnode_get_softc(regnode
);
552 sc
->enable_usec
= 500;
553 sc
->enable_pwr_mode
= MAX77620_POWER_MODE_NORMAL
;
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
);
563 /* Get current power mode */
564 rv
= max77620_get_pwr_mode(sc
, &val
);
566 printf("%s: cannot read current power mode: %d\n",
567 regnode_get_name(sc
->regnode
), rv
);
572 /* Get current power ramp delay */
573 rv
= max77620_get_pwr_ramp_delay(sc
, &intval
);
575 printf("%s: cannot read current power mode: %d\n",
576 regnode_get_name(sc
->regnode
), 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
);
585 printf("%s: cannot read current FPS source: %d\n",
586 regnode_get_name(sc
->regnode
), 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
);
598 printf("%s: cannot set power mode: %d\n",
599 regnode_get_name(sc
->regnode
), rv
);
604 /* Set FPS source. */
605 rv
= max77620_set_fps_src(sc
, sc
->active_fps_src
);
607 printf("%s: cannot setup FPS source: %d\n",
608 regnode_get_name(sc
->regnode
), rv
);
612 rv
= max77620_set_fps_slots(sc
, false);
614 printf("%s: cannot setup power slots: %d\n",
615 regnode_get_name(sc
->regnode
), rv
);
618 /* Setup power ramp . */
619 if (sc
->ramp_rate_setting
!= -1) {
620 rv
= max77620_set_pwr_ramp_delay(sc
, sc
->pwr_ramp_delay
);
622 printf("%s: cannot set power ramp delay: %d\n",
623 regnode_get_name(sc
->regnode
), rv
);
632 max77620_fdt_parse(struct max77620_softc
*sc
, phandle_t node
, struct reg_def
*def
,
633 struct max77620_regnode_init_def
*init_def
)
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
));
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
));
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
));
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
));
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
));
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
));
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
));
675 init_def
->ramp_rate_setting
= -1;
677 /* Get parent supply. */
678 if (def
->supply_name
== NULL
)
681 parent
= OF_parent(node
);
682 snprintf(prop_name
, sizeof(prop_name
), "%s-supply",
684 rv
= OF_getencprop(parent
, prop_name
, &supply_node
,
685 sizeof(supply_node
));
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
);
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");
713 reg_sc
= regnode_get_softc(regnode
);
715 /* Init regulator softc. */
716 reg_sc
->regnode
= regnode
;
717 reg_sc
->base_sc
= sc
;
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
);
732 regnode_topo_slock();
733 rv
= regnode_get_voltage(regnode
, &volt
);
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
));
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();
758 max77620_regulator_attach(struct max77620_softc
*sc
, phandle_t node
)
760 struct max77620_reg_sc
*reg
;
761 phandle_t child
, rnode
;
764 rnode
= ofw_bus_find_child(node
, "regulators");
766 device_printf(sc
->dev
, " Cannot find regulators subnode\n");
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
);
780 device_printf(sc
->dev
,
781 "Regulator %s missing in DT\n",
782 max77620s_def
[i
].name
);
785 if (ofw_bus_node_status_okay(child
) == 0)
787 reg
= max77620_attach(sc
, child
, max77620s_def
+ i
);
789 device_printf(sc
->dev
, "Cannot attach regulator: %s\n",
790 max77620s_def
[i
].name
);
799 max77620_regulator_map(device_t dev
, phandle_t xref
, int ncells
,
800 pcell_t
*cells
, intptr_t *num
)
802 struct max77620_softc
*sc
;
805 sc
= device_get_softc(dev
);
806 for (i
= 0; i
< sc
->nregs
; i
++) {
807 if (sc
->regs
[i
] == NULL
)
809 if (sc
->regs
[i
]->xref
== xref
) {
810 *num
= sc
->regs
[i
]->def
->id
;
819 max77620_regnode_enable(struct regnode
*regnode
, bool val
, int *udelay
)
822 struct max77620_reg_sc
*sc
;
826 sc
= regnode_get_softc(regnode
);
828 if (sc
->active_fps_src
!= MAX77620_FPS_SRC_NONE
) {
834 mode
= sc
->enable_pwr_mode
;
836 mode
= MAX77620_POWER_MODE_DISABLE
;
838 rv
= max77620_set_pwr_mode(sc
, mode
);
840 printf("%s: cannot set power mode: %d\n",
841 regnode_get_name(sc
->regnode
), rv
);
845 *udelay
= sc
->enable_usec
;
850 max77620_regnode_set_volt(struct regnode
*regnode
, int min_uvolt
, int max_uvolt
,
853 struct max77620_reg_sc
*sc
;
857 sc
= regnode_get_softc(regnode
);
860 rv
= regulator_range_volt_to_sel8(sc
->def
->ranges
, sc
->def
->nranges
,
861 min_uvolt
, max_uvolt
, &sel
);
864 rv
= max77620_set_sel(sc
, sel
);
869 max77620_regnode_get_volt(struct regnode
*regnode
, int *uvolt
)
872 struct max77620_reg_sc
*sc
;
876 sc
= regnode_get_softc(regnode
);
877 rv
= max77620_get_sel(sc
, &sel
);
881 rv
= regulator_range_sel8_to_volt(sc
->def
->ranges
, sc
->def
->nranges
,