1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2018-2021 Emmanuel Vadot <manu@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/bus.h> 31 #include <sys/systm.h> 32 #include <sys/clock.h> 33 34 #include <dev/ofw/ofw_bus.h> 35 #include <dev/ofw/ofw_bus_subr.h> 36 37 #include <dev/extres/regulator/regulator.h> 38 39 #include <dev/iicbus/pmic/rockchip/rk8xx.h> 40 41 #include "regdev_if.h" 42 43 static int rk8xx_regnode_status(struct regnode *regnode, int *status); 44 static int rk8xx_regnode_set_voltage(struct regnode *regnode, int min_uvolt, 45 int max_uvolt, int *udelay); 46 static int rk8xx_regnode_get_voltage(struct regnode *regnode, int *uvolt); 47 48 /* #define dprintf(sc, format, arg...) device_printf(sc->base_dev, "%s: " format, __func__, arg) */ 49 #define dprintf(sc, format, arg...) (sc = sc) 50 51 static int 52 rk8xx_regnode_init(struct regnode *regnode) 53 { 54 struct rk8xx_reg_sc *sc; 55 struct regnode_std_param *param; 56 int rv, udelay, uvolt, status; 57 58 sc = regnode_get_softc(regnode); 59 dprintf(sc, "Regulator %s init called\n", sc->def->name); 60 param = regnode_get_stdparam(regnode); 61 if (param->min_uvolt == 0) 62 return (0); 63 64 /* Check that the regulator is preset to the correct voltage */ 65 rv = rk8xx_regnode_get_voltage(regnode, &uvolt); 66 if (rv != 0) 67 return(rv); 68 69 if (uvolt >= param->min_uvolt && uvolt <= param->max_uvolt) 70 return(0); 71 /* 72 * Set the regulator at the correct voltage if it is not enabled. 73 * Do not enable it, this is will be done either by a 74 * consumer or by regnode_set_constraint if boot_on is true 75 */ 76 rv = rk8xx_regnode_status(regnode, &status); 77 if (rv != 0 || status == REGULATOR_STATUS_ENABLED) 78 return (rv); 79 80 rv = rk8xx_regnode_set_voltage(regnode, param->min_uvolt, 81 param->max_uvolt, &udelay); 82 if (udelay != 0) 83 DELAY(udelay); 84 85 return (rv); 86 } 87 88 static int 89 rk8xx_regnode_enable(struct regnode *regnode, bool enable, int *udelay) 90 { 91 struct rk8xx_reg_sc *sc; 92 uint8_t val; 93 94 sc = regnode_get_softc(regnode); 95 96 dprintf(sc, "%sabling regulator %s\n", 97 enable ? "En" : "Dis", 98 sc->def->name); 99 rk8xx_read(sc->base_dev, sc->def->enable_reg, &val, 1); 100 if (enable) 101 val |= sc->def->enable_mask; 102 else 103 val &= ~sc->def->enable_mask; 104 rk8xx_write(sc->base_dev, sc->def->enable_reg, &val, 1); 105 106 *udelay = 0; 107 108 return (0); 109 } 110 111 static void 112 rk8xx_regnode_reg_to_voltage(struct rk8xx_reg_sc *sc, uint8_t val, int *uv) 113 { 114 struct rk8xx_softc *sc1; 115 116 sc1 = device_get_softc(sc->base_dev); 117 if (sc1->type == RK809 || sc1->type == RK817) { 118 if (sc->def->voltage_step2) { 119 int change; 120 121 change = 122 ((sc->def->voltage_min2 - sc->def->voltage_min) / 123 sc->def->voltage_step); 124 if (val > change) { 125 if (val < sc->def->voltage_nstep) { 126 *uv = sc->def->voltage_min2 + 127 (val - change) * 128 sc->def->voltage_step2; 129 } else 130 *uv = sc->def->voltage_max2; 131 return; 132 } 133 } 134 if (val < sc->def->voltage_nstep) 135 *uv = sc->def->voltage_min + val * sc->def->voltage_step; 136 else 137 *uv = sc->def->voltage_max; 138 139 } else { 140 if (val < sc->def->voltage_nstep) 141 *uv = sc->def->voltage_min + val * sc->def->voltage_step; 142 else 143 *uv = sc->def->voltage_min + 144 (sc->def->voltage_nstep * sc->def->voltage_step); 145 } 146 } 147 148 static int 149 rk8xx_regnode_voltage_to_reg(struct rk8xx_reg_sc *sc, int min_uvolt, 150 int max_uvolt, uint8_t *val) 151 { 152 uint8_t nval; 153 int nstep, uvolt; 154 struct rk8xx_softc *sc1; 155 156 sc1 = device_get_softc(sc->base_dev); 157 nval = 0; 158 uvolt = sc->def->voltage_min; 159 160 for (nstep = 0; nstep < sc->def->voltage_nstep && uvolt < min_uvolt; 161 nstep++) { 162 ++nval; 163 if (sc1->type == RK809 || sc1->type == RK817) { 164 if (sc->def->voltage_step2) { 165 if (uvolt < sc->def->voltage_min2) 166 uvolt += sc->def->voltage_step; 167 else 168 uvolt += sc->def->voltage_step2; 169 } else 170 uvolt += sc->def->voltage_step; 171 } else 172 uvolt += sc->def->voltage_step; 173 } 174 if (uvolt > max_uvolt) 175 return (EINVAL); 176 177 *val = nval; 178 return (0); 179 } 180 181 static int 182 rk8xx_regnode_status(struct regnode *regnode, int *status) 183 { 184 struct rk8xx_reg_sc *sc; 185 uint8_t val; 186 187 sc = regnode_get_softc(regnode); 188 189 *status = 0; 190 rk8xx_read(sc->base_dev, sc->def->enable_reg, &val, 1); 191 if (val & sc->def->enable_mask) 192 *status = REGULATOR_STATUS_ENABLED; 193 194 return (0); 195 } 196 197 static int 198 rk8xx_regnode_set_voltage(struct regnode *regnode, int min_uvolt, 199 int max_uvolt, int *udelay) 200 { 201 struct rk8xx_reg_sc *sc; 202 uint8_t val, old; 203 int uvolt; 204 struct rk8xx_softc *sc1; 205 206 sc = regnode_get_softc(regnode); 207 sc1 = device_get_softc(sc->base_dev); 208 209 if (!sc->def->voltage_step) 210 return (ENXIO); 211 212 dprintf(sc, "Setting %s to %d<->%d uvolts\n", 213 sc->def->name, 214 min_uvolt, 215 max_uvolt); 216 rk8xx_read(sc->base_dev, sc->def->voltage_reg, &val, 1); 217 old = val; 218 if (rk8xx_regnode_voltage_to_reg(sc, min_uvolt, max_uvolt, &val) != 0) 219 return (ERANGE); 220 221 if (sc1->type == RK809 || sc1->type == RK817) 222 val |= (old &= ~sc->def->voltage_mask); 223 224 rk8xx_write(sc->base_dev, sc->def->voltage_reg, &val, 1); 225 226 rk8xx_read(sc->base_dev, sc->def->voltage_reg, &val, 1); 227 228 *udelay = 0; 229 230 rk8xx_regnode_reg_to_voltage(sc, val, &uvolt); 231 dprintf(sc, "Regulator %s set to %d uvolt\n", 232 sc->def->name, 233 uvolt); 234 235 return (0); 236 } 237 238 static int 239 rk8xx_regnode_get_voltage(struct regnode *regnode, int *uvolt) 240 { 241 struct rk8xx_reg_sc *sc; 242 uint8_t val; 243 244 sc = regnode_get_softc(regnode); 245 246 if (sc->def->voltage_min == sc->def->voltage_max) { 247 *uvolt = sc->def->voltage_min; 248 return (0); 249 } 250 251 if (!sc->def->voltage_step) 252 return (ENXIO); 253 254 rk8xx_read(sc->base_dev, sc->def->voltage_reg, &val, 1); 255 rk8xx_regnode_reg_to_voltage(sc, val & sc->def->voltage_mask, uvolt); 256 257 dprintf(sc, "Regulator %s is at %d uvolt\n", 258 sc->def->name, 259 *uvolt); 260 261 return (0); 262 } 263 264 static regnode_method_t rk8xx_regnode_methods[] = { 265 /* Regulator interface */ 266 REGNODEMETHOD(regnode_init, rk8xx_regnode_init), 267 REGNODEMETHOD(regnode_enable, rk8xx_regnode_enable), 268 REGNODEMETHOD(regnode_status, rk8xx_regnode_status), 269 REGNODEMETHOD(regnode_set_voltage, rk8xx_regnode_set_voltage), 270 REGNODEMETHOD(regnode_get_voltage, rk8xx_regnode_get_voltage), 271 REGNODEMETHOD(regnode_check_voltage, regnode_method_check_voltage), 272 REGNODEMETHOD_END 273 }; 274 DEFINE_CLASS_1(rk8xx_regnode, rk8xx_regnode_class, rk8xx_regnode_methods, 275 sizeof(struct rk8xx_reg_sc), regnode_class); 276 277 static struct rk8xx_reg_sc * 278 rk8xx_reg_attach(device_t dev, phandle_t node, 279 struct rk8xx_regdef *def) 280 { 281 struct rk8xx_reg_sc *reg_sc; 282 struct regnode_init_def initdef; 283 struct regnode *regnode; 284 285 memset(&initdef, 0, sizeof(initdef)); 286 if (regulator_parse_ofw_stdparam(dev, node, &initdef) != 0) { 287 device_printf(dev, "cannot create regulator\n"); 288 return (NULL); 289 } 290 if (initdef.std_param.min_uvolt == 0) 291 initdef.std_param.min_uvolt = def->voltage_min; 292 if (initdef.std_param.max_uvolt == 0) 293 initdef.std_param.max_uvolt = def->voltage_max; 294 initdef.id = def->id; 295 initdef.ofw_node = node; 296 297 regnode = regnode_create(dev, &rk8xx_regnode_class, &initdef); 298 if (regnode == NULL) { 299 device_printf(dev, "cannot create regulator\n"); 300 return (NULL); 301 } 302 303 reg_sc = regnode_get_softc(regnode); 304 reg_sc->regnode = regnode; 305 reg_sc->base_dev = dev; 306 reg_sc->def = def; 307 reg_sc->xref = OF_xref_from_node(node); 308 reg_sc->param = regnode_get_stdparam(regnode); 309 310 regnode_register(regnode); 311 312 return (reg_sc); 313 } 314 315 void 316 rk8xx_attach_regulators(struct rk8xx_softc *sc) 317 { 318 struct rk8xx_reg_sc *reg; 319 struct reg_list *regp; 320 phandle_t rnode, child; 321 int i; 322 323 TAILQ_INIT(&sc->regs); 324 325 rnode = ofw_bus_find_child(ofw_bus_get_node(sc->dev), "regulators"); 326 if (rnode > 0) { 327 for (i = 0; i < sc->nregs; i++) { 328 child = ofw_bus_find_child(rnode, 329 sc->regdefs[i].name); 330 if (child == 0) 331 continue; 332 if (OF_hasprop(child, "regulator-name") != 1) 333 continue; 334 reg = rk8xx_reg_attach(sc->dev, child, &sc->regdefs[i]); 335 if (reg == NULL) { 336 device_printf(sc->dev, 337 "cannot attach regulator %s\n", 338 sc->regdefs[i].name); 339 continue; 340 } 341 regp = malloc(sizeof(*regp), M_DEVBUF, M_WAITOK | M_ZERO); 342 regp->reg = reg; 343 TAILQ_INSERT_TAIL(&sc->regs, regp, next); 344 if (bootverbose) 345 device_printf(sc->dev, "Regulator %s attached\n", 346 sc->regdefs[i].name); 347 } 348 } 349 } 350 351 int 352 rk8xx_map(device_t dev, phandle_t xref, int ncells, 353 pcell_t *cells, intptr_t *id) 354 { 355 struct rk8xx_softc *sc; 356 struct reg_list *regp; 357 358 sc = device_get_softc(dev); 359 360 TAILQ_FOREACH(regp, &sc->regs, next) { 361 if (regp->reg->xref == xref) { 362 *id = regp->reg->def->id; 363 return (0); 364 } 365 } 366 367 return (ERANGE); 368 } 369