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