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