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/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> 37 38 #include <machine/bus.h> 39 40 #include <dev/extres/regulator/regulator.h> 41 #include <dev/gpio/gpiobusvar.h> 42 43 #include <dt-bindings/mfd/max77620.h> 44 45 #include "max77620.h" 46 47 MALLOC_DEFINE(M_MAX77620_REG, "MAX77620 regulator", "MAX77620 power regulator"); 48 49 #define DIV_ROUND_UP(n,d) howmany(n, d) 50 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, 65 }; 66 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; 77 }; 78 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; 94 }; 95 96 struct max77620_reg_sc { 97 struct regnode *regnode; 98 struct max77620_softc *base_sc; 99 struct reg_def *def; 100 phandle_t xref; 101 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; 113 114 /* Cached values */ 115 uint8_t fps_src; 116 uint8_t pwr_mode; 117 int pwr_ramp_delay; 118 }; 119 120 static struct regulator_range max77620_sd0_ranges[] = { 121 REG_RANGE_INIT(0, 64, 600000, 12500), /* 0.6V - 1.4V / 12.5mV */ 122 }; 123 124 static struct regulator_range max77620_sd1_ranges[] = { 125 REG_RANGE_INIT(0, 76, 600000, 12500), /* 0.6V - 1.55V / 12.5mV */ 126 }; 127 128 static struct regulator_range max77620_sdx_ranges[] = { 129 REG_RANGE_INIT(0, 255, 600000, 12500), /* 0.6V - 3.7875V / 12.5mV */ 130 }; 131 132 static struct regulator_range max77620_ldo0_1_ranges[] = { 133 REG_RANGE_INIT(0, 63, 800000, 25000), /* 0.8V - 2.375V / 25mV */ 134 }; 135 136 static struct regulator_range max77620_ldo4_ranges[] = { 137 REG_RANGE_INIT(0, 63, 800000, 12500), /* 0.8V - 1.5875V / 12.5mV */ 138 }; 139 140 static struct regulator_range max77620_ldox_ranges[] = { 141 REG_RANGE_INIT(0, 63, 800000, 50000), /* 0.8V - 3.95V / 50mV */ 142 }; 143 144 static struct reg_def max77620s_def[] = { 145 { 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), 159 }, 160 { 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), 174 }, 175 { 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), 189 }, 190 { 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), 204 }, 205 { 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), 219 }, 220 { 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), 234 }, 235 { 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), 249 }, 250 { 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), 264 }, 265 { 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), 279 }, 280 { 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), 294 }, 295 { 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), 309 }, 310 { 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), 324 }, 325 { 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), 339 }, 340 }; 341 342 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 356 }; 357 DEFINE_CLASS_1(max77620_regnode, max77620_regnode_class, max77620_regnode_methods, 358 sizeof(struct max77620_reg_sc), regnode_class); 359 360 static int 361 max77620_get_sel(struct max77620_reg_sc *sc, uint8_t *sel) 362 { 363 int rv; 364 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); 370 } 371 *sel &= sc->def->volt_vsel_mask; 372 *sel >>= ffs(sc->def->volt_vsel_mask) - 1; 373 return (0); 374 } 375 376 static int 377 max77620_set_sel(struct max77620_reg_sc *sc, uint8_t sel) 378 { 379 int rv; 380 381 sel <<= ffs(sc->def->volt_vsel_mask) - 1; 382 sel &= sc->def->volt_vsel_mask; 383 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); 390 } 391 return (rv); 392 } 393 394 static int 395 max77620_get_fps_src(struct max77620_reg_sc *sc, uint8_t *fps_src) 396 { 397 uint8_t val; 398 int rv; 399 400 rv = RD1(sc->base_sc, sc->def->fps_reg, &val); 401 if (rv != 0) 402 return (rv); 403 404 *fps_src = (val & MAX77620_FPS_SRC_MASK) >> MAX77620_FPS_SRC_SHIFT; 405 return (0); 406 } 407 408 static int 409 max77620_set_fps_src(struct max77620_reg_sc *sc, uint8_t fps_src) 410 { 411 int rv; 412 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); 419 } 420 421 static int 422 max77620_set_fps_slots(struct max77620_reg_sc *sc, bool suspend) 423 { 424 uint8_t mask, val; 425 int pu_slot, pd_slot, rv; 426 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; 433 } 434 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; 441 } 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; 446 } 447 448 rv = RM1(sc->base_sc, sc->def->fps_reg, mask, val); 449 if (rv != 0) 450 return (rv); 451 return (0); 452 } 453 454 static int 455 max77620_get_pwr_mode(struct max77620_reg_sc *sc, uint8_t *pwr_mode) 456 { 457 uint8_t val; 458 int rv; 459 460 rv = RD1(sc->base_sc, sc->def->pwr_mode_reg, &val); 461 if (rv != 0) 462 return (rv); 463 464 *pwr_mode = (val & sc->def->pwr_mode_mask) >> sc->def->pwr_mode_shift; 465 return (0); 466 } 467 468 static int 469 max77620_set_pwr_mode(struct max77620_reg_sc *sc, uint8_t pwr_mode) 470 { 471 int rv; 472 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); 479 } 480 481 static int 482 max77620_get_pwr_ramp_delay(struct max77620_reg_sc *sc, int *rate) 483 { 484 uint8_t val; 485 int rv; 486 487 rv = RD1(sc->base_sc, sc->def->cfg_reg, &val); 488 if (rv != 0) 489 return (rv); 490 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; 508 } 509 sc->pwr_ramp_delay = *rate; 510 return (0); 511 } 512 513 static int 514 max77620_set_pwr_ramp_delay(struct max77620_reg_sc *sc, int rate) 515 { 516 uint8_t val, mask; 517 int rv; 518 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; 537 } 538 rv = RM1(sc->base_sc, sc->def->cfg_reg, mask, val); 539 if (rv != 0) 540 return (rv); 541 return (0); 542 } 543 544 static int 545 max77620_regnode_init(struct regnode *regnode) 546 { 547 struct max77620_reg_sc *sc; 548 uint8_t val; 549 int intval, rv; 550 551 sc = regnode_get_softc(regnode); 552 sc->enable_usec = 500; 553 sc->enable_pwr_mode = MAX77620_POWER_MODE_NORMAL; 554 #if 0 555 { 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); 561 } 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); 569 } 570 sc->pwr_mode = val; 571 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); 578 } 579 sc->pwr_ramp_delay = intval; 580 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); 588 } 589 sc->active_fps_src = val; 590 } 591 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); 601 } 602 } 603 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); 610 } 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); 617 } 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); 625 } 626 } 627 628 return (0); 629 } 630 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) 634 { 635 int rv; 636 phandle_t parent, supply_node; 637 char prop_name[64]; /* Maximum OFW property name length. */ 638 639 rv = regulator_parse_ofw_stdparam(sc->dev, node, 640 &init_def->reg_init_def); 641 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; 646 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; 651 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; 656 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; 661 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; 666 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; 671 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; 676 677 /* Get parent supply. */ 678 if (def->supply_name == NULL) 679 return; 680 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; 693 } 694 695 static struct max77620_reg_sc * 696 max77620_attach(struct max77620_softc *sc, phandle_t node, struct reg_def *def) 697 { 698 struct max77620_reg_sc *reg_sc; 699 struct max77620_regnode_init_def init_def; 700 struct regnode *regnode; 701 702 bzero(&init_def, sizeof(init_def)); 703 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); 712 } 713 reg_sc = regnode_get_softc(regnode); 714 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; 728 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); 750 } 751 regnode_topo_unlock(); 752 } 753 754 return (reg_sc); 755 } 756 757 int 758 max77620_regulator_attach(struct max77620_softc *sc, phandle_t node) 759 { 760 struct max77620_reg_sc *reg; 761 phandle_t child, rnode; 762 int i; 763 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); 768 } 769 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); 773 774 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; 784 } 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); 792 } 793 sc->regs[i] = reg; 794 } 795 return (0); 796 } 797 798 int 799 max77620_regulator_map(device_t dev, phandle_t xref, int ncells, 800 pcell_t *cells, intptr_t *num) 801 { 802 struct max77620_softc *sc; 803 int i; 804 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); 812 } 813 } 814 815 return (ENXIO); 816 } 817 818 static int 819 max77620_regnode_enable(struct regnode *regnode, bool val, int *udelay) 820 { 821 822 struct max77620_reg_sc *sc; 823 uint8_t mode; 824 int rv; 825 826 sc = regnode_get_softc(regnode); 827 828 if (sc->active_fps_src != MAX77620_FPS_SRC_NONE) { 829 *udelay = 0; 830 return (0); 831 } 832 833 if (val) 834 mode = sc->enable_pwr_mode; 835 else 836 mode = MAX77620_POWER_MODE_DISABLE; 837 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); 843 } 844 845 *udelay = sc->enable_usec; 846 return (0); 847 } 848 849 static int 850 max77620_regnode_set_volt(struct regnode *regnode, int min_uvolt, int max_uvolt, 851 int *udelay) 852 { 853 struct max77620_reg_sc *sc; 854 uint8_t sel; 855 int rv; 856 857 sc = regnode_get_softc(regnode); 858 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); 866 } 867 868 static int 869 max77620_regnode_get_volt(struct regnode *regnode, int *uvolt) 870 { 871 872 struct max77620_reg_sc *sc; 873 uint8_t sel; 874 int rv; 875 876 sc = regnode_get_softc(regnode); 877 rv = max77620_get_sel(sc, &sel); 878 if (rv != 0) 879 return (rv); 880 881 rv = regulator_range_sel8_to_volt(sc->def->ranges, sc->def->nranges, 882 sel, uvolt); 883 return (rv); 884 return(0); 885 } 886