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