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