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