1 /*- 2 * Copyright (c) 2016 Jared McNeill <jmcneill@invisible.ca> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 19 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 20 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 21 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 22 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 * $FreeBSD$ 27 */ 28 29 /* 30 * GPIO controlled regulators 31 */ 32 33 #include <sys/cdefs.h> 34 __FBSDID("$FreeBSD$"); 35 36 #include <sys/param.h> 37 #include <sys/systm.h> 38 #include <sys/bus.h> 39 #include <sys/rman.h> 40 #include <sys/kernel.h> 41 #include <sys/module.h> 42 #include <sys/gpio.h> 43 44 #include <dev/ofw/ofw_bus.h> 45 #include <dev/ofw/ofw_bus_subr.h> 46 47 #include <dev/gpio/gpiobusvar.h> 48 49 #include <dev/extres/regulator/regulator.h> 50 51 #include "regdev_if.h" 52 53 struct gpioregulator_state { 54 int val; 55 uint32_t mask; 56 }; 57 58 struct gpioregulator_init_def { 59 struct regnode_init_def reg_init_def; 60 struct gpiobus_pin *enable_pin; 61 int enable_pin_valid; 62 int startup_delay_us; 63 int nstates; 64 struct gpioregulator_state *states; 65 int npins; 66 struct gpiobus_pin **pins; 67 }; 68 69 struct gpioregulator_reg_sc { 70 struct regnode *regnode; 71 device_t base_dev; 72 struct regnode_std_param *param; 73 struct gpioregulator_init_def *def; 74 }; 75 76 struct gpioregulator_softc { 77 device_t dev; 78 struct gpioregulator_reg_sc *reg_sc; 79 struct gpioregulator_init_def init_def; 80 }; 81 82 static int 83 gpioregulator_regnode_init(struct regnode *regnode) 84 { 85 struct gpioregulator_reg_sc *sc; 86 int error, n; 87 88 sc = regnode_get_softc(regnode); 89 90 if (sc->def->enable_pin_valid == 1) { 91 error = gpio_pin_setflags(sc->def->enable_pin, GPIO_PIN_OUTPUT); 92 if (error != 0) 93 return (error); 94 } 95 96 for (n = 0; n < sc->def->npins; n++) { 97 error = gpio_pin_setflags(sc->def->pins[n], GPIO_PIN_OUTPUT); 98 if (error != 0) 99 return (error); 100 } 101 102 return (0); 103 } 104 105 static int 106 gpioregulator_regnode_enable(struct regnode *regnode, bool enable, int *udelay) 107 { 108 struct gpioregulator_reg_sc *sc; 109 bool active; 110 int error; 111 112 sc = regnode_get_softc(regnode); 113 114 if (sc->def->enable_pin_valid == 1) { 115 active = enable; 116 if (!sc->param->enable_active_high) 117 active = !active; 118 error = gpio_pin_set_active(sc->def->enable_pin, active); 119 if (error != 0) 120 return (error); 121 } 122 123 *udelay = sc->def->startup_delay_us; 124 125 return (0); 126 } 127 128 static int 129 gpioregulator_regnode_set_voltage(struct regnode *regnode, int min_uvolt, 130 int max_uvolt, int *udelay) 131 { 132 struct gpioregulator_reg_sc *sc; 133 const struct gpioregulator_state *state; 134 int error, n; 135 136 sc = regnode_get_softc(regnode); 137 state = NULL; 138 139 for (n = 0; n < sc->def->nstates; n++) { 140 if (sc->def->states[n].val >= min_uvolt && 141 sc->def->states[n].val <= max_uvolt) { 142 state = &sc->def->states[n]; 143 break; 144 } 145 } 146 if (state == NULL) 147 return (EINVAL); 148 149 for (n = 0; n < sc->def->npins; n++) { 150 error = gpio_pin_set_active(sc->def->pins[n], 151 (state->mask >> n) & 1); 152 if (error != 0) 153 return (error); 154 } 155 156 *udelay = sc->def->startup_delay_us; 157 158 return (0); 159 } 160 161 static int 162 gpioregulator_regnode_get_voltage(struct regnode *regnode, int *uvolt) 163 { 164 struct gpioregulator_reg_sc *sc; 165 uint32_t mask; 166 int error, n; 167 bool active; 168 169 sc = regnode_get_softc(regnode); 170 mask = 0; 171 172 for (n = 0; n < sc->def->npins; n++) { 173 error = gpio_pin_is_active(sc->def->pins[n], &active); 174 if (error != 0) 175 return (error); 176 mask |= (active << n); 177 } 178 179 for (n = 0; n < sc->def->nstates; n++) { 180 if (sc->def->states[n].mask == mask) { 181 *uvolt = sc->def->states[n].val; 182 return (0); 183 } 184 } 185 186 return (EIO); 187 } 188 189 static regnode_method_t gpioregulator_regnode_methods[] = { 190 /* Regulator interface */ 191 REGNODEMETHOD(regnode_init, gpioregulator_regnode_init), 192 REGNODEMETHOD(regnode_enable, gpioregulator_regnode_enable), 193 REGNODEMETHOD(regnode_set_voltage, gpioregulator_regnode_set_voltage), 194 REGNODEMETHOD(regnode_get_voltage, gpioregulator_regnode_get_voltage), 195 REGNODEMETHOD_END 196 }; 197 DEFINE_CLASS_1(gpioregulator_regnode, gpioregulator_regnode_class, 198 gpioregulator_regnode_methods, sizeof(struct gpioregulator_reg_sc), 199 regnode_class); 200 201 static int 202 gpioregulator_parse_fdt(struct gpioregulator_softc *sc) 203 { 204 uint32_t *pstates, mask; 205 phandle_t node; 206 ssize_t len; 207 int error, n; 208 209 node = ofw_bus_get_node(sc->dev); 210 pstates = NULL; 211 mask = 0; 212 213 error = regulator_parse_ofw_stdparam(sc->dev, node, 214 &sc->init_def.reg_init_def); 215 if (error != 0) 216 return (error); 217 218 /* "states" property (required) */ 219 len = OF_getencprop_alloc_multi(node, "states", sizeof(*pstates), 220 (void **)&pstates); 221 if (len < 2) { 222 device_printf(sc->dev, "invalid 'states' property\n"); 223 error = EINVAL; 224 goto done; 225 } 226 sc->init_def.nstates = len / 2; 227 sc->init_def.states = malloc(sc->init_def.nstates * 228 sizeof(*sc->init_def.states), M_DEVBUF, M_WAITOK); 229 for (n = 0; n < sc->init_def.nstates; n++) { 230 sc->init_def.states[n].val = pstates[n * 2 + 0]; 231 sc->init_def.states[n].mask = pstates[n * 2 + 1]; 232 mask |= sc->init_def.states[n].mask; 233 } 234 235 /* "startup-delay-us" property (optional) */ 236 len = OF_getencprop(node, "startup-delay-us", 237 &sc->init_def.startup_delay_us, 238 sizeof(sc->init_def.startup_delay_us)); 239 if (len <= 0) 240 sc->init_def.startup_delay_us = 0; 241 242 /* "enable-gpio" property (optional) */ 243 error = gpio_pin_get_by_ofw_property(sc->dev, node, "enable-gpio", 244 &sc->init_def.enable_pin); 245 if (error == 0) 246 sc->init_def.enable_pin_valid = 1; 247 248 /* "gpios" property */ 249 sc->init_def.npins = 32 - __builtin_clz(mask); 250 sc->init_def.pins = malloc(sc->init_def.npins * 251 sizeof(sc->init_def.pins), M_DEVBUF, M_WAITOK | M_ZERO); 252 for (n = 0; n < sc->init_def.npins; n++) { 253 error = gpio_pin_get_by_ofw_idx(sc->dev, node, n, 254 &sc->init_def.pins[n]); 255 if (error != 0) { 256 device_printf(sc->dev, "cannot get pin %d\n", n); 257 goto done; 258 } 259 } 260 261 done: 262 if (error != 0) { 263 for (n = 0; n < sc->init_def.npins; n++) { 264 if (sc->init_def.pins[n] != NULL) 265 gpio_pin_release(sc->init_def.pins[n]); 266 } 267 268 free(sc->init_def.states, M_DEVBUF); 269 free(sc->init_def.pins, M_DEVBUF); 270 271 } 272 OF_prop_free(pstates); 273 274 return (error); 275 } 276 277 static int 278 gpioregulator_probe(device_t dev) 279 { 280 281 if (!ofw_bus_is_compatible(dev, "regulator-gpio")) 282 return (ENXIO); 283 284 device_set_desc(dev, "GPIO controlled regulator"); 285 return (BUS_PROBE_GENERIC); 286 } 287 288 static int 289 gpioregulator_attach(device_t dev) 290 { 291 struct gpioregulator_softc *sc; 292 struct regnode *regnode; 293 phandle_t node; 294 int error; 295 296 sc = device_get_softc(dev); 297 sc->dev = dev; 298 node = ofw_bus_get_node(dev); 299 300 error = gpioregulator_parse_fdt(sc); 301 if (error != 0) { 302 device_printf(dev, "cannot parse parameters\n"); 303 return (ENXIO); 304 } 305 sc->init_def.reg_init_def.id = 1; 306 sc->init_def.reg_init_def.ofw_node = node; 307 308 regnode = regnode_create(dev, &gpioregulator_regnode_class, 309 &sc->init_def.reg_init_def); 310 if (regnode == NULL) { 311 device_printf(dev, "cannot create regulator\n"); 312 return (ENXIO); 313 } 314 315 sc->reg_sc = regnode_get_softc(regnode); 316 sc->reg_sc->regnode = regnode; 317 sc->reg_sc->base_dev = dev; 318 sc->reg_sc->param = regnode_get_stdparam(regnode); 319 sc->reg_sc->def = &sc->init_def; 320 321 regnode_register(regnode); 322 323 return (0); 324 } 325 326 327 static device_method_t gpioregulator_methods[] = { 328 /* Device interface */ 329 DEVMETHOD(device_probe, gpioregulator_probe), 330 DEVMETHOD(device_attach, gpioregulator_attach), 331 332 /* Regdev interface */ 333 DEVMETHOD(regdev_map, regdev_default_ofw_map), 334 335 DEVMETHOD_END 336 }; 337 338 static driver_t gpioregulator_driver = { 339 "gpioregulator", 340 gpioregulator_methods, 341 sizeof(struct gpioregulator_softc), 342 }; 343 344 static devclass_t gpioregulator_devclass; 345 346 EARLY_DRIVER_MODULE(gpioregulator, simplebus, gpioregulator_driver, 347 gpioregulator_devclass, 0, 0, BUS_PASS_INTERRUPT + BUS_PASS_ORDER_LAST); 348 MODULE_VERSION(gpioregulator, 1); 349