1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
3 *
4 * Copyright 2020 Michal Meloun <[email protected]>
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
max77620_get_sel(struct max77620_reg_sc * sc,uint8_t * sel)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
max77620_set_sel(struct max77620_reg_sc * sc,uint8_t sel)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
max77620_get_fps_src(struct max77620_reg_sc * sc,uint8_t * fps_src)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
max77620_set_fps_src(struct max77620_reg_sc * sc,uint8_t fps_src)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
max77620_set_fps_slots(struct max77620_reg_sc * sc,bool suspend)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
max77620_get_pwr_mode(struct max77620_reg_sc * sc,uint8_t * pwr_mode)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
max77620_set_pwr_mode(struct max77620_reg_sc * sc,uint8_t pwr_mode)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
max77620_get_pwr_ramp_delay(struct max77620_reg_sc * sc,int * rate)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
max77620_set_pwr_ramp_delay(struct max77620_reg_sc * sc,int rate)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
max77620_regnode_init(struct regnode * regnode)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
max77620_fdt_parse(struct max77620_softc * sc,phandle_t node,struct reg_def * def,struct max77620_regnode_init_def * init_def)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 *
max77620_attach(struct max77620_softc * sc,phandle_t node,struct reg_def * def)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
max77620_regulator_attach(struct max77620_softc * sc,phandle_t node)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
max77620_regulator_map(device_t dev,phandle_t xref,int ncells,pcell_t * cells,intptr_t * num)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
max77620_regnode_enable(struct regnode * regnode,bool val,int * udelay)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
max77620_regnode_set_volt(struct regnode * regnode,int min_uvolt,int max_uvolt,int * udelay)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
max77620_regnode_get_volt(struct regnode * regnode,int * uvolt)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