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