1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2019 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/kernel.h> 33 #include <sys/module.h> 34 #include <sys/mutex.h> 35 #include <sys/rman.h> 36 #include <machine/bus.h> 37 38 #include <dev/iicbus/iiconf.h> 39 #include <dev/iicbus/iicbus.h> 40 41 #include <dev/ofw/ofw_bus.h> 42 #include <dev/ofw/ofw_bus_subr.h> 43 44 #include <dev/extres/regulator/regulator.h> 45 46 #include <dev/iicbus/pmic/act8846.h> 47 48 #include "regdev_if.h" 49 50 MALLOC_DEFINE(M_ACT8846_REG, "ACT8846 regulator", "ACT8846 power regulator"); 51 52 #if 0 53 #define dprintf(sc, format, arg...) 54 device_printf(sc->base_sc->dev, "%s: " format, __func__, arg) */ 55 #else 56 #define dprintf(sc, format, arg...) 57 #endif 58 59 enum act8846_reg_id { 60 ACT8846_REG_ID_REG1, 61 ACT8846_REG_ID_REG2, 62 ACT8846_REG_ID_REG3, 63 ACT8846_REG_ID_REG4, 64 ACT8846_REG_ID_REG5, 65 ACT8846_REG_ID_REG6, 66 ACT8846_REG_ID_REG7, 67 ACT8846_REG_ID_REG8, 68 ACT8846_REG_ID_REG9, 69 ACT8846_REG_ID_REG10, 70 ACT8846_REG_ID_REG11, 71 ACT8846_REG_ID_REG12, 72 ACT8846_REG_ID_REG13, 73 }; 74 75 struct act8846_regdef { 76 intptr_t id; /* ID */ 77 char *name; /* Regulator name */ 78 char *supply_name; /* Source property name */ 79 uint8_t enable_reg; 80 uint8_t enable_mask; 81 uint8_t voltage_reg; 82 uint8_t voltage_mask; 83 struct regulator_range *ranges; 84 int nranges; 85 }; 86 struct act8846_softc; 87 88 struct act8846_reg_sc { 89 struct regnode *regnode; 90 struct act8846_softc *base_sc; 91 struct act8846_regdef *def; 92 phandle_t xref; 93 struct regnode_std_param *param; 94 }; 95 96 97 static struct regulator_range act8846_ranges[] = { 98 REG_RANGE_INIT( 0, 23, 600000, 25000), 99 REG_RANGE_INIT( 24, 47, 1200000, 50000), 100 REG_RANGE_INIT( 48, 64, 2400000, 100000), 101 }; 102 103 static struct act8846_regdef act8846_regdefs[] = { 104 { 105 .id = ACT8846_REG_ID_REG1, 106 .name = "REG1", 107 .supply_name = "vp1", 108 .enable_reg = ACT8846_REG1_CTRL, 109 .enable_mask = ACT8846_CTRL_ENA, 110 }, 111 { 112 .id = ACT8846_REG_ID_REG2, 113 .name = "REG2", 114 .supply_name = "vp2", 115 .enable_reg = ACT8846_REG2_CTRL, 116 .enable_mask = ACT8846_CTRL_ENA, 117 .voltage_reg = ACT8846_REG2_VSET0, 118 .voltage_mask = ACT8846_VSEL_MASK, 119 .ranges = act8846_ranges, 120 .nranges = nitems(act8846_ranges), 121 }, 122 { 123 .id = ACT8846_REG_ID_REG3, 124 .name = "REG3", 125 .supply_name = "vp3", 126 .enable_reg = ACT8846_REG3_CTRL, 127 .enable_mask = ACT8846_CTRL_ENA, 128 .voltage_reg = ACT8846_REG3_VSET0, 129 .voltage_mask = ACT8846_VSEL_MASK, 130 .ranges = act8846_ranges, 131 .nranges = nitems(act8846_ranges), 132 }, 133 { 134 .id = ACT8846_REG_ID_REG4, 135 .name = "REG4", 136 .supply_name = "vp4", 137 .enable_reg = ACT8846_REG4_CTRL, 138 .enable_mask = ACT8846_CTRL_ENA, 139 .voltage_reg = ACT8846_REG4_VSET0, 140 .voltage_mask = ACT8846_VSEL_MASK, 141 .ranges = act8846_ranges, 142 .nranges = nitems(act8846_ranges), 143 }, 144 { 145 .id = ACT8846_REG_ID_REG5, 146 .name = "REG5", 147 .supply_name = "inl1", 148 .enable_reg = ACT8846_REG5_CTRL, 149 .enable_mask = ACT8846_CTRL_ENA, 150 .voltage_reg = ACT8846_REG5_VSET, 151 .voltage_mask = ACT8846_VSEL_MASK, 152 .ranges = act8846_ranges, 153 .nranges = nitems(act8846_ranges), 154 }, 155 { 156 .id = ACT8846_REG_ID_REG6, 157 .name = "REG6", 158 .supply_name = "inl1", 159 .enable_reg = ACT8846_REG6_CTRL, 160 .enable_mask = ACT8846_CTRL_ENA, 161 .voltage_reg = ACT8846_REG6_VSET, 162 .voltage_mask = ACT8846_VSEL_MASK, 163 .ranges = act8846_ranges, 164 .nranges = nitems(act8846_ranges), 165 }, 166 { 167 .id = ACT8846_REG_ID_REG7, 168 .name = "REG7", 169 .supply_name = "inl1", 170 .enable_reg = ACT8846_REG7_CTRL, 171 .enable_mask = ACT8846_CTRL_ENA, 172 .voltage_reg = ACT8846_REG7_VSET, 173 .voltage_mask = ACT8846_VSEL_MASK, 174 .ranges = act8846_ranges, 175 .nranges = nitems(act8846_ranges), 176 }, 177 { 178 .id = ACT8846_REG_ID_REG8, 179 .name = "REG8", 180 .supply_name = "inl2", 181 .enable_reg = ACT8846_REG8_CTRL, 182 .enable_mask = ACT8846_CTRL_ENA, 183 .voltage_reg = ACT8846_REG8_VSET, 184 .voltage_mask = ACT8846_VSEL_MASK, 185 .ranges = act8846_ranges, 186 .nranges = nitems(act8846_ranges), 187 }, 188 { 189 .id = ACT8846_REG_ID_REG9, 190 .name = "REG9", 191 .supply_name = "inl2", 192 .enable_reg = ACT8846_REG9_CTRL, 193 .enable_mask = ACT8846_CTRL_ENA, 194 .voltage_reg = ACT8846_REG9_VSET, 195 .voltage_mask = ACT8846_VSEL_MASK, 196 .ranges = act8846_ranges, 197 .nranges = nitems(act8846_ranges), 198 }, 199 { 200 .id = ACT8846_REG_ID_REG10, 201 .name = "REG10", 202 .supply_name = "inl3", 203 .enable_reg = ACT8846_REG10_CTRL, 204 .enable_mask = ACT8846_CTRL_ENA, 205 .voltage_reg = ACT8846_REG10_VSET, 206 .voltage_mask = ACT8846_VSEL_MASK, 207 .ranges = act8846_ranges, 208 .nranges = nitems(act8846_ranges), 209 }, 210 { 211 .id = ACT8846_REG_ID_REG11, 212 .name = "REG11", 213 .supply_name = "inl3", 214 .enable_reg = ACT8846_REG11_CTRL, 215 .enable_mask = ACT8846_CTRL_ENA, 216 .voltage_reg = ACT8846_REG11_VSET, 217 .voltage_mask = ACT8846_VSEL_MASK, 218 .ranges = act8846_ranges, 219 .nranges = nitems(act8846_ranges), 220 }, 221 { 222 .id = ACT8846_REG_ID_REG12, 223 .name = "REG12", 224 .supply_name = "inl3", 225 .enable_reg = ACT8846_REG12_CTRL, 226 .enable_mask = ACT8846_CTRL_ENA, 227 .voltage_reg = ACT8846_REG12_VSET, 228 .voltage_mask = ACT8846_VSEL_MASK, 229 .ranges = act8846_ranges, 230 .nranges = nitems(act8846_ranges), 231 }, 232 { 233 .id = ACT8846_REG_ID_REG13, 234 .name = "REG13", 235 .supply_name = "inl1", 236 .enable_reg = ACT8846_REG13_CTRL, 237 .enable_mask = ACT8846_CTRL_ENA, 238 }, 239 }; 240 241 static int 242 act8846_read_sel(struct act8846_reg_sc *sc, uint8_t *sel) 243 { 244 int rv; 245 246 rv = RD1(sc->base_sc, sc->def->voltage_reg, sel); 247 if (rv != 0) 248 return (rv); 249 *sel &= sc->def->voltage_mask; 250 *sel >>= ffs(sc->def->voltage_mask) - 1; 251 return (0); 252 } 253 254 static int 255 act8846_write_sel(struct act8846_reg_sc *sc, uint8_t sel) 256 { 257 int rv; 258 259 sel <<= ffs(sc->def->voltage_mask) - 1; 260 sel &= sc->def->voltage_mask; 261 262 rv = RM1(sc->base_sc, sc->def->voltage_reg, 263 sc->def->voltage_mask, sel); 264 if (rv != 0) 265 return (rv); 266 return (rv); 267 } 268 269 static int 270 act8846_regnode_init(struct regnode *regnode) 271 { 272 return (0); 273 } 274 275 static int 276 act8846_regnode_enable(struct regnode *regnode, bool enable, int *udelay) 277 { 278 struct act8846_reg_sc *sc; 279 int rv; 280 281 sc = regnode_get_softc(regnode); 282 283 dprintf(sc, "%sabling regulator %s\n", 284 enable ? "En" : "Dis", 285 sc->def->name); 286 rv = RM1(sc->base_sc, sc->def->enable_reg, 287 sc->def->enable_mask, enable ? sc->def->enable_mask: 0); 288 *udelay = sc->param->enable_delay; 289 290 return (rv); 291 } 292 293 static int 294 act8846_regnode_set_voltage(struct regnode *regnode, int min_uvolt, 295 int max_uvolt, int *udelay) 296 { 297 struct act8846_reg_sc *sc; 298 uint8_t sel; 299 int uvolt, rv; 300 301 sc = regnode_get_softc(regnode); 302 303 if (sc->def->ranges == NULL) 304 return (ENXIO); 305 306 dprintf(sc, "Setting %s to %d<->%d uvolts\n", 307 sc->def->name, 308 min_uvolt, 309 max_uvolt); 310 rv = regulator_range_volt_to_sel8(sc->def->ranges, sc->def->nranges, 311 min_uvolt, max_uvolt, &sel); 312 if (rv != 0) 313 return (rv); 314 *udelay = sc->param->ramp_delay; 315 rv = act8846_write_sel(sc, sel); 316 317 act8846_read_sel(sc, &sel); 318 regulator_range_sel8_to_volt(sc->def->ranges, sc->def->nranges, 319 sel, &uvolt); 320 dprintf(sc, "Regulator %s set to %d uvolt\n", sc->def->name, 321 uvolt); 322 323 return (rv); 324 } 325 326 static int 327 act8846_regnode_get_voltage(struct regnode *regnode, int *uvolt) 328 { 329 struct act8846_reg_sc *sc; 330 uint8_t sel; 331 int rv; 332 333 sc = regnode_get_softc(regnode); 334 335 if (sc->def->ranges == NULL) { 336 if (sc->def->id == ACT8846_REG_ID_REG13) { 337 *uvolt = 1800000; 338 return (0); 339 } 340 return (ENXIO); 341 } 342 343 rv = act8846_read_sel(sc, &sel); 344 if (rv != 0) 345 return (rv); 346 rv = regulator_range_sel8_to_volt(sc->def->ranges, sc->def->nranges, 347 sel, uvolt); 348 dprintf(sc, "Regulator %s is at %d uvolt\n", sc->def->name, 349 *uvolt); 350 351 return (rv); 352 } 353 354 static regnode_method_t act8846_regnode_methods[] = { 355 /* Regulator interface */ 356 REGNODEMETHOD(regnode_init, act8846_regnode_init), 357 REGNODEMETHOD(regnode_enable, act8846_regnode_enable), 358 REGNODEMETHOD(regnode_set_voltage, act8846_regnode_set_voltage), 359 REGNODEMETHOD(regnode_get_voltage, act8846_regnode_get_voltage), 360 REGNODEMETHOD_END 361 }; 362 DEFINE_CLASS_1(act8846_regnode, act8846_regnode_class, act8846_regnode_methods, 363 sizeof(struct act8846_reg_sc), regnode_class); 364 365 static int 366 act8846_fdt_parse(struct act8846_softc *sc, phandle_t pnode, phandle_t node, 367 struct act8846_regdef *def, struct regnode_init_def *init_def) 368 { 369 int rv; 370 phandle_t supply_node; 371 char prop_name[64]; /* Maximum OFW property name length. */ 372 373 rv = regulator_parse_ofw_stdparam(sc->dev, node, init_def); 374 375 /* Get parent supply. */ 376 if (def->supply_name == NULL) 377 return (0); 378 379 snprintf(prop_name, sizeof(prop_name), "%s-supply", 380 def->supply_name); 381 rv = OF_getencprop(pnode, prop_name, &supply_node, 382 sizeof(supply_node)); 383 if (rv <= 0) 384 return (rv); 385 supply_node = OF_node_from_xref(supply_node); 386 rv = OF_getprop_alloc(supply_node, "regulator-name", 387 (void **)&init_def->parent_name); 388 if (rv <= 0) 389 init_def->parent_name = NULL; 390 return (0); 391 } 392 393 static struct act8846_reg_sc * 394 act8846_attach(struct act8846_softc *sc, phandle_t pnode, phandle_t node, 395 struct act8846_regdef *def) 396 { 397 struct act8846_reg_sc *reg_sc; 398 struct regnode_init_def initdef; 399 struct regnode *regnode; 400 401 memset(&initdef, 0, sizeof(initdef)); 402 if (act8846_fdt_parse(sc, pnode, node, def, &initdef) != 0) { 403 device_printf(sc->dev, "cannot parse FDT data for regulator\n"); 404 return (NULL); 405 } 406 initdef.id = def->id; 407 initdef.ofw_node = node; 408 409 regnode = regnode_create(sc->dev, &act8846_regnode_class, &initdef); 410 if (regnode == NULL) { 411 device_printf(sc->dev, "cannot create regulator\n"); 412 return (NULL); 413 } 414 415 reg_sc = regnode_get_softc(regnode); 416 reg_sc->base_sc = sc; 417 reg_sc->def = def; 418 reg_sc->xref = OF_xref_from_node(node); 419 reg_sc->param = regnode_get_stdparam(regnode); 420 421 regnode_register(regnode); 422 423 if (bootverbose) { 424 int volt, rv; 425 regnode_topo_slock(); 426 rv = regnode_get_voltage(regnode, &volt); 427 if (rv == ENODEV) { 428 device_printf(sc->dev, 429 " Regulator %s: parent doesn't exist yet.\n", 430 regnode_get_name(regnode)); 431 } else if (rv != 0) { 432 device_printf(sc->dev, 433 " Regulator %s: voltage: INVALID!!!\n", 434 regnode_get_name(regnode)); 435 } else { 436 device_printf(sc->dev, 437 " Regulator %s: voltage: %d uV\n", 438 regnode_get_name(regnode), volt); 439 } 440 regnode_topo_unlock(); 441 } 442 443 return (reg_sc); 444 } 445 446 447 int 448 act8846_regulator_attach(struct act8846_softc *sc, phandle_t node) 449 { 450 struct act8846_reg_sc *reg; 451 phandle_t child, rnode; 452 int i; 453 454 rnode = ofw_bus_find_child(node, "regulators"); 455 if (rnode <= 0) { 456 device_printf(sc->dev, " Cannot find regulators subnode\n"); 457 return (ENXIO); 458 } 459 460 /* ACT8846 specific definitio. */ 461 sc->nregs = nitems(act8846_regdefs); 462 sc->regs = malloc(sizeof(struct act8846_reg_sc *) * sc->nregs, 463 M_ACT8846_REG, M_WAITOK | M_ZERO); 464 465 466 /* Attach all known regulators if exist in DT. */ 467 for (i = 0; i < sc->nregs; i++) { 468 child = ofw_bus_find_child(rnode, act8846_regdefs[i].name); 469 if (child == 0) { 470 if (bootverbose) 471 device_printf(sc->dev, 472 "Regulator %s missing in DT\n", 473 act8846_regdefs[i].name); 474 continue; 475 } 476 reg = act8846_attach(sc, node, child, act8846_regdefs + i); 477 if (reg == NULL) { 478 device_printf(sc->dev, "Cannot attach regulator: %s\n", 479 act8846_regdefs[i].name); 480 return (ENXIO); 481 } 482 sc->regs[i] = reg; 483 } 484 return (0); 485 } 486 487 int 488 act8846_regulator_map(device_t dev, phandle_t xref, int ncells, 489 pcell_t *cells, int *num) 490 { 491 struct act8846_softc *sc; 492 int i; 493 494 sc = device_get_softc(dev); 495 for (i = 0; i < sc->nregs; i++) { 496 if (sc->regs[i] == NULL) 497 continue; 498 if (sc->regs[i]->xref == xref) { 499 *num = sc->regs[i]->def->id; 500 return (0); 501 } 502 } 503 return (ENXIO); 504 } 505