1/*- 2 * Copyright (c) 2009, Oleksandr Tymoshenko <gonzo@FreeBSD.org> 3 * Copyright (c) 2009, Luiz Otavio O Souza. 4 * All rights reserved. 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 unmodified, this list of conditions, and the following 11 * disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29/* 30 * GPIO driver for AR71xx 31 */ 32 33#include <sys/cdefs.h>
| 1/*- 2 * Copyright (c) 2009, Oleksandr Tymoshenko <gonzo@FreeBSD.org> 3 * Copyright (c) 2009, Luiz Otavio O Souza. 4 * All rights reserved. 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 unmodified, this list of conditions, and the following 11 * disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29/* 30 * GPIO driver for AR71xx 31 */ 32 33#include <sys/cdefs.h>
|
50#include <mips/atheros/ar71xx_gpiovar.h> 51 52#include "gpio_if.h" 53 54#define DEFAULT_CAPS (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT) 55 56struct ar71xx_gpio_pin { 57 const char *name; 58 int pin; 59 int flags; 60}; 61 62static struct ar71xx_gpio_pin ar71xx_gpio_pins[] = { 63 { "RFled", 2, GPIO_PIN_OUTPUT}, 64 { "SW4", 8, GPIO_PIN_INPUT}, 65 { NULL, 0, 0}, 66}; 67 68/* 69 * Helpers 70 */ 71static void ar71xx_gpio_function_enable(struct ar71xx_gpio_softc *sc, 72 uint32_t mask); 73static void ar71xx_gpio_function_disable(struct ar71xx_gpio_softc *sc, 74 uint32_t mask); 75static void ar71xx_gpio_pin_configure(struct ar71xx_gpio_softc *sc, 76 struct gpio_pin *pin, uint32_t flags); 77 78/* 79 * Driver stuff 80 */ 81static int ar71xx_gpio_probe(device_t dev); 82static int ar71xx_gpio_attach(device_t dev); 83static int ar71xx_gpio_detach(device_t dev); 84static int ar71xx_gpio_filter(void *arg); 85static void ar71xx_gpio_intr(void *arg); 86 87/* 88 * GPIO interface 89 */ 90static int ar71xx_gpio_pin_max(device_t dev, int *maxpin); 91static int ar71xx_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps); 92static int ar71xx_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t 93 *flags); 94static int ar71xx_gpio_pin_getname(device_t dev, uint32_t pin, char *name); 95static int ar71xx_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags); 96static int ar71xx_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value); 97static int ar71xx_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *val); 98static int ar71xx_gpio_pin_toggle(device_t dev, uint32_t pin); 99 100static void 101ar71xx_gpio_function_enable(struct ar71xx_gpio_softc *sc, uint32_t mask) 102{ 103 GPIO_LOCK(sc); 104 GPIO_SET_BITS(sc, AR71XX_GPIO_FUNCTION, mask); 105 GPIO_UNLOCK(sc); 106} 107 108static void 109ar71xx_gpio_function_disable(struct ar71xx_gpio_softc *sc, uint32_t mask) 110{ 111 GPIO_LOCK(sc); 112 GPIO_CLEAR_BITS(sc, AR71XX_GPIO_FUNCTION, mask); 113 GPIO_UNLOCK(sc); 114} 115 116static void 117ar71xx_gpio_pin_configure(struct ar71xx_gpio_softc *sc, struct gpio_pin *pin, 118 unsigned int flags) 119{ 120 uint32_t mask; 121 122 mask = 1 << pin->gp_pin; 123 GPIO_LOCK(sc); 124 125 /* 126 * Manage input/output 127 */ 128 if (flags & (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) { 129 pin->gp_flags &= ~(GPIO_PIN_INPUT|GPIO_PIN_OUTPUT); 130 if (flags & GPIO_PIN_OUTPUT) { 131 pin->gp_flags |= GPIO_PIN_OUTPUT; 132 GPIO_SET_BITS(sc, AR71XX_GPIO_OE, mask); 133 } 134 else { 135 pin->gp_flags |= GPIO_PIN_INPUT; 136 GPIO_CLEAR_BITS(sc, AR71XX_GPIO_OE, mask); 137 } 138 } 139 140 GPIO_UNLOCK(sc); 141} 142 143static int 144ar71xx_gpio_pin_max(device_t dev, int *maxpin) 145{ 146
| 51#include <mips/atheros/ar71xx_gpiovar.h> 52 53#include "gpio_if.h" 54 55#define DEFAULT_CAPS (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT) 56 57struct ar71xx_gpio_pin { 58 const char *name; 59 int pin; 60 int flags; 61}; 62 63static struct ar71xx_gpio_pin ar71xx_gpio_pins[] = { 64 { "RFled", 2, GPIO_PIN_OUTPUT}, 65 { "SW4", 8, GPIO_PIN_INPUT}, 66 { NULL, 0, 0}, 67}; 68 69/* 70 * Helpers 71 */ 72static void ar71xx_gpio_function_enable(struct ar71xx_gpio_softc *sc, 73 uint32_t mask); 74static void ar71xx_gpio_function_disable(struct ar71xx_gpio_softc *sc, 75 uint32_t mask); 76static void ar71xx_gpio_pin_configure(struct ar71xx_gpio_softc *sc, 77 struct gpio_pin *pin, uint32_t flags); 78 79/* 80 * Driver stuff 81 */ 82static int ar71xx_gpio_probe(device_t dev); 83static int ar71xx_gpio_attach(device_t dev); 84static int ar71xx_gpio_detach(device_t dev); 85static int ar71xx_gpio_filter(void *arg); 86static void ar71xx_gpio_intr(void *arg); 87 88/* 89 * GPIO interface 90 */ 91static int ar71xx_gpio_pin_max(device_t dev, int *maxpin); 92static int ar71xx_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps); 93static int ar71xx_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t 94 *flags); 95static int ar71xx_gpio_pin_getname(device_t dev, uint32_t pin, char *name); 96static int ar71xx_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags); 97static int ar71xx_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value); 98static int ar71xx_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *val); 99static int ar71xx_gpio_pin_toggle(device_t dev, uint32_t pin); 100 101static void 102ar71xx_gpio_function_enable(struct ar71xx_gpio_softc *sc, uint32_t mask) 103{ 104 GPIO_LOCK(sc); 105 GPIO_SET_BITS(sc, AR71XX_GPIO_FUNCTION, mask); 106 GPIO_UNLOCK(sc); 107} 108 109static void 110ar71xx_gpio_function_disable(struct ar71xx_gpio_softc *sc, uint32_t mask) 111{ 112 GPIO_LOCK(sc); 113 GPIO_CLEAR_BITS(sc, AR71XX_GPIO_FUNCTION, mask); 114 GPIO_UNLOCK(sc); 115} 116 117static void 118ar71xx_gpio_pin_configure(struct ar71xx_gpio_softc *sc, struct gpio_pin *pin, 119 unsigned int flags) 120{ 121 uint32_t mask; 122 123 mask = 1 << pin->gp_pin; 124 GPIO_LOCK(sc); 125 126 /* 127 * Manage input/output 128 */ 129 if (flags & (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) { 130 pin->gp_flags &= ~(GPIO_PIN_INPUT|GPIO_PIN_OUTPUT); 131 if (flags & GPIO_PIN_OUTPUT) { 132 pin->gp_flags |= GPIO_PIN_OUTPUT; 133 GPIO_SET_BITS(sc, AR71XX_GPIO_OE, mask); 134 } 135 else { 136 pin->gp_flags |= GPIO_PIN_INPUT; 137 GPIO_CLEAR_BITS(sc, AR71XX_GPIO_OE, mask); 138 } 139 } 140 141 GPIO_UNLOCK(sc); 142} 143 144static int 145ar71xx_gpio_pin_max(device_t dev, int *maxpin) 146{ 147
|
148 return (0); 149} 150 151static int 152ar71xx_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps) 153{ 154 struct ar71xx_gpio_softc *sc = device_get_softc(dev); 155 int i; 156 157 for (i = 0; i < sc->gpio_npins; i++) { 158 if (sc->gpio_pins[i].gp_pin == pin) 159 break; 160 } 161 162 if (i >= sc->gpio_npins) 163 return (EINVAL); 164 165 GPIO_LOCK(sc); 166 *caps = sc->gpio_pins[i].gp_caps; 167 GPIO_UNLOCK(sc); 168 169 return (0); 170} 171 172static int 173ar71xx_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags) 174{ 175 struct ar71xx_gpio_softc *sc = device_get_softc(dev); 176 int i; 177 178 for (i = 0; i < sc->gpio_npins; i++) { 179 if (sc->gpio_pins[i].gp_pin == pin) 180 break; 181 } 182 183 if (i >= sc->gpio_npins) 184 return (EINVAL); 185 186 GPIO_LOCK(sc); 187 *flags = sc->gpio_pins[i].gp_flags; 188 GPIO_UNLOCK(sc); 189 190 return (0); 191} 192 193static int 194ar71xx_gpio_pin_getname(device_t dev, uint32_t pin, char *name) 195{ 196 struct ar71xx_gpio_softc *sc = device_get_softc(dev); 197 int i; 198 199 for (i = 0; i < sc->gpio_npins; i++) { 200 if (sc->gpio_pins[i].gp_pin == pin) 201 break; 202 } 203 204 if (i >= sc->gpio_npins) 205 return (EINVAL); 206 207 GPIO_LOCK(sc); 208 memcpy(name, sc->gpio_pins[i].gp_name, GPIOMAXNAME); 209 GPIO_UNLOCK(sc); 210 211 return (0); 212} 213 214static int 215ar71xx_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags) 216{ 217 int i; 218 struct ar71xx_gpio_softc *sc = device_get_softc(dev); 219 220 for (i = 0; i < sc->gpio_npins; i++) { 221 if (sc->gpio_pins[i].gp_pin == pin) 222 break; 223 } 224 225 if (i >= sc->gpio_npins) 226 return (EINVAL); 227 228 /* Filter out unwanted flags */ 229 if ((flags &= sc->gpio_pins[i].gp_caps) != flags) 230 return (EINVAL); 231 232 /* Can't mix input/output together */ 233 if ((flags & (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) == 234 (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) 235 return (EINVAL); 236 237 ar71xx_gpio_pin_configure(sc, &sc->gpio_pins[i], flags); 238 return (0); 239} 240 241static int 242ar71xx_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value) 243{ 244 struct ar71xx_gpio_softc *sc = device_get_softc(dev); 245 int i; 246 247 for (i = 0; i < sc->gpio_npins; i++) { 248 if (sc->gpio_pins[i].gp_pin == pin) 249 break; 250 } 251 252 if (i >= sc->gpio_npins) 253 return (EINVAL); 254 255 GPIO_LOCK(sc); 256 if (value) 257 GPIO_WRITE(sc, AR71XX_GPIO_SET, (1 << pin)); 258 else 259 GPIO_WRITE(sc, AR71XX_GPIO_CLEAR, (1 << pin)); 260 GPIO_UNLOCK(sc); 261 262 return (0); 263} 264 265static int 266ar71xx_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *val) 267{ 268 struct ar71xx_gpio_softc *sc = device_get_softc(dev); 269 int i; 270 271 for (i = 0; i < sc->gpio_npins; i++) { 272 if (sc->gpio_pins[i].gp_pin == pin) 273 break; 274 } 275 276 if (i >= sc->gpio_npins) 277 return (EINVAL); 278 279 GPIO_LOCK(sc); 280 *val = (GPIO_READ(sc, AR71XX_GPIO_IN) & (1 << pin)) ? 1 : 0; 281 GPIO_UNLOCK(sc); 282 283 return (0); 284} 285 286static int 287ar71xx_gpio_pin_toggle(device_t dev, uint32_t pin) 288{ 289 int res, i; 290 struct ar71xx_gpio_softc *sc = device_get_softc(dev); 291 292 for (i = 0; i < sc->gpio_npins; i++) { 293 if (sc->gpio_pins[i].gp_pin == pin) 294 break; 295 } 296 297 if (i >= sc->gpio_npins) 298 return (EINVAL); 299 300 GPIO_LOCK(sc); 301 res = (GPIO_READ(sc, AR71XX_GPIO_IN) & (1 << pin)) ? 1 : 0; 302 if (res) 303 GPIO_WRITE(sc, AR71XX_GPIO_CLEAR, (1 << pin)); 304 else 305 GPIO_WRITE(sc, AR71XX_GPIO_SET, (1 << pin)); 306 GPIO_UNLOCK(sc); 307 308 return (0); 309} 310 311static int 312ar71xx_gpio_filter(void *arg) 313{ 314 315 /* TODO: something useful */ 316 return (FILTER_STRAY); 317} 318 319 320 321static void 322ar71xx_gpio_intr(void *arg) 323{ 324 struct ar71xx_gpio_softc *sc = arg; 325 GPIO_LOCK(sc); 326 /* TODO: something useful */ 327 GPIO_UNLOCK(sc); 328} 329 330static int 331ar71xx_gpio_probe(device_t dev) 332{ 333 334 device_set_desc(dev, "Atheros AR71XX GPIO driver"); 335 return (0); 336} 337 338static int 339ar71xx_gpio_attach(device_t dev) 340{ 341 struct ar71xx_gpio_softc *sc = device_get_softc(dev); 342 int error = 0; 343 struct ar71xx_gpio_pin *pinp; 344 int i; 345 346 KASSERT((device_get_unit(dev) == 0), 347 ("ar71xx_gpio: Only one gpio module supported")); 348 349 mtx_init(&sc->gpio_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK, 350 MTX_DEF); 351 352 /* Map control/status registers. */ 353 sc->gpio_mem_rid = 0; 354 sc->gpio_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, 355 &sc->gpio_mem_rid, RF_ACTIVE); 356 357 if (sc->gpio_mem_res == NULL) { 358 device_printf(dev, "couldn't map memory\n"); 359 error = ENXIO; 360 ar71xx_gpio_detach(dev); 361 return(error); 362 } 363 364 if ((sc->gpio_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, 365 &sc->gpio_irq_rid, RF_SHAREABLE | RF_ACTIVE)) == NULL) { 366 device_printf(dev, "unable to allocate IRQ resource\n"); 367 return (ENXIO); 368 } 369 370 if ((bus_setup_intr(dev, sc->gpio_irq_res, INTR_TYPE_MISC, 371 ar71xx_gpio_filter, ar71xx_gpio_intr, sc, &sc->gpio_ih))) { 372 device_printf(dev, 373 "WARNING: unable to register interrupt handler\n"); 374 return (ENXIO); 375 } 376 377 sc->dev = dev; 378 ar71xx_gpio_function_enable(sc, GPIO_FUNC_SPI_CS1_EN); 379 ar71xx_gpio_function_enable(sc, GPIO_FUNC_SPI_CS2_EN); 380 /* Configure all pins as input */ 381 /* disable interrupts for all pins */ 382 GPIO_WRITE(sc, AR71XX_GPIO_INT_MASK, 0); 383 pinp = ar71xx_gpio_pins; 384 i = 0; 385 while (pinp->name) { 386 strncpy(sc->gpio_pins[i].gp_name, pinp->name, GPIOMAXNAME); 387 sc->gpio_pins[i].gp_pin = pinp->pin; 388 sc->gpio_pins[i].gp_caps = DEFAULT_CAPS; 389 sc->gpio_pins[i].gp_flags = 0; 390 ar71xx_gpio_pin_configure(sc, &sc->gpio_pins[i], pinp->flags); 391 pinp++; 392 i++; 393 } 394 395 sc->gpio_npins = i; 396 397 device_add_child(dev, "gpioc", device_get_unit(dev)); 398 device_add_child(dev, "gpiobus", device_get_unit(dev)); 399 return (bus_generic_attach(dev)); 400} 401 402static int 403ar71xx_gpio_detach(device_t dev) 404{ 405 struct ar71xx_gpio_softc *sc = device_get_softc(dev); 406 407 KASSERT(mtx_initialized(&sc->gpio_mtx), ("gpio mutex not initialized")); 408 409 ar71xx_gpio_function_disable(sc, GPIO_FUNC_SPI_CS1_EN); 410 ar71xx_gpio_function_disable(sc, GPIO_FUNC_SPI_CS2_EN); 411 bus_generic_detach(dev); 412 413 if (sc->gpio_mem_res) 414 bus_release_resource(dev, SYS_RES_MEMORY, sc->gpio_mem_rid, 415 sc->gpio_mem_res); 416 417 mtx_destroy(&sc->gpio_mtx); 418 419 return(0); 420} 421 422static device_method_t ar71xx_gpio_methods[] = { 423 DEVMETHOD(device_probe, ar71xx_gpio_probe), 424 DEVMETHOD(device_attach, ar71xx_gpio_attach), 425 DEVMETHOD(device_detach, ar71xx_gpio_detach), 426 427 /* GPIO protocol */ 428 DEVMETHOD(gpio_pin_max, ar71xx_gpio_pin_max), 429 DEVMETHOD(gpio_pin_getname, ar71xx_gpio_pin_getname), 430 DEVMETHOD(gpio_pin_getflags, ar71xx_gpio_pin_getflags), 431 DEVMETHOD(gpio_pin_getcaps, ar71xx_gpio_pin_getcaps), 432 DEVMETHOD(gpio_pin_setflags, ar71xx_gpio_pin_setflags), 433 DEVMETHOD(gpio_pin_get, ar71xx_gpio_pin_get), 434 DEVMETHOD(gpio_pin_set, ar71xx_gpio_pin_set), 435 DEVMETHOD(gpio_pin_toggle, ar71xx_gpio_pin_toggle), 436 {0, 0}, 437}; 438 439static driver_t ar71xx_gpio_driver = { 440 "gpio", 441 ar71xx_gpio_methods, 442 sizeof(struct ar71xx_gpio_softc), 443}; 444static devclass_t ar71xx_gpio_devclass; 445 446DRIVER_MODULE(ar71xx_gpio, apb, ar71xx_gpio_driver, ar71xx_gpio_devclass, 0, 0);
| 161 return (0); 162} 163 164static int 165ar71xx_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps) 166{ 167 struct ar71xx_gpio_softc *sc = device_get_softc(dev); 168 int i; 169 170 for (i = 0; i < sc->gpio_npins; i++) { 171 if (sc->gpio_pins[i].gp_pin == pin) 172 break; 173 } 174 175 if (i >= sc->gpio_npins) 176 return (EINVAL); 177 178 GPIO_LOCK(sc); 179 *caps = sc->gpio_pins[i].gp_caps; 180 GPIO_UNLOCK(sc); 181 182 return (0); 183} 184 185static int 186ar71xx_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags) 187{ 188 struct ar71xx_gpio_softc *sc = device_get_softc(dev); 189 int i; 190 191 for (i = 0; i < sc->gpio_npins; i++) { 192 if (sc->gpio_pins[i].gp_pin == pin) 193 break; 194 } 195 196 if (i >= sc->gpio_npins) 197 return (EINVAL); 198 199 GPIO_LOCK(sc); 200 *flags = sc->gpio_pins[i].gp_flags; 201 GPIO_UNLOCK(sc); 202 203 return (0); 204} 205 206static int 207ar71xx_gpio_pin_getname(device_t dev, uint32_t pin, char *name) 208{ 209 struct ar71xx_gpio_softc *sc = device_get_softc(dev); 210 int i; 211 212 for (i = 0; i < sc->gpio_npins; i++) { 213 if (sc->gpio_pins[i].gp_pin == pin) 214 break; 215 } 216 217 if (i >= sc->gpio_npins) 218 return (EINVAL); 219 220 GPIO_LOCK(sc); 221 memcpy(name, sc->gpio_pins[i].gp_name, GPIOMAXNAME); 222 GPIO_UNLOCK(sc); 223 224 return (0); 225} 226 227static int 228ar71xx_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags) 229{ 230 int i; 231 struct ar71xx_gpio_softc *sc = device_get_softc(dev); 232 233 for (i = 0; i < sc->gpio_npins; i++) { 234 if (sc->gpio_pins[i].gp_pin == pin) 235 break; 236 } 237 238 if (i >= sc->gpio_npins) 239 return (EINVAL); 240 241 /* Filter out unwanted flags */ 242 if ((flags &= sc->gpio_pins[i].gp_caps) != flags) 243 return (EINVAL); 244 245 /* Can't mix input/output together */ 246 if ((flags & (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) == 247 (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) 248 return (EINVAL); 249 250 ar71xx_gpio_pin_configure(sc, &sc->gpio_pins[i], flags); 251 return (0); 252} 253 254static int 255ar71xx_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value) 256{ 257 struct ar71xx_gpio_softc *sc = device_get_softc(dev); 258 int i; 259 260 for (i = 0; i < sc->gpio_npins; i++) { 261 if (sc->gpio_pins[i].gp_pin == pin) 262 break; 263 } 264 265 if (i >= sc->gpio_npins) 266 return (EINVAL); 267 268 GPIO_LOCK(sc); 269 if (value) 270 GPIO_WRITE(sc, AR71XX_GPIO_SET, (1 << pin)); 271 else 272 GPIO_WRITE(sc, AR71XX_GPIO_CLEAR, (1 << pin)); 273 GPIO_UNLOCK(sc); 274 275 return (0); 276} 277 278static int 279ar71xx_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *val) 280{ 281 struct ar71xx_gpio_softc *sc = device_get_softc(dev); 282 int i; 283 284 for (i = 0; i < sc->gpio_npins; i++) { 285 if (sc->gpio_pins[i].gp_pin == pin) 286 break; 287 } 288 289 if (i >= sc->gpio_npins) 290 return (EINVAL); 291 292 GPIO_LOCK(sc); 293 *val = (GPIO_READ(sc, AR71XX_GPIO_IN) & (1 << pin)) ? 1 : 0; 294 GPIO_UNLOCK(sc); 295 296 return (0); 297} 298 299static int 300ar71xx_gpio_pin_toggle(device_t dev, uint32_t pin) 301{ 302 int res, i; 303 struct ar71xx_gpio_softc *sc = device_get_softc(dev); 304 305 for (i = 0; i < sc->gpio_npins; i++) { 306 if (sc->gpio_pins[i].gp_pin == pin) 307 break; 308 } 309 310 if (i >= sc->gpio_npins) 311 return (EINVAL); 312 313 GPIO_LOCK(sc); 314 res = (GPIO_READ(sc, AR71XX_GPIO_IN) & (1 << pin)) ? 1 : 0; 315 if (res) 316 GPIO_WRITE(sc, AR71XX_GPIO_CLEAR, (1 << pin)); 317 else 318 GPIO_WRITE(sc, AR71XX_GPIO_SET, (1 << pin)); 319 GPIO_UNLOCK(sc); 320 321 return (0); 322} 323 324static int 325ar71xx_gpio_filter(void *arg) 326{ 327 328 /* TODO: something useful */ 329 return (FILTER_STRAY); 330} 331 332 333 334static void 335ar71xx_gpio_intr(void *arg) 336{ 337 struct ar71xx_gpio_softc *sc = arg; 338 GPIO_LOCK(sc); 339 /* TODO: something useful */ 340 GPIO_UNLOCK(sc); 341} 342 343static int 344ar71xx_gpio_probe(device_t dev) 345{ 346 347 device_set_desc(dev, "Atheros AR71XX GPIO driver"); 348 return (0); 349} 350 351static int 352ar71xx_gpio_attach(device_t dev) 353{ 354 struct ar71xx_gpio_softc *sc = device_get_softc(dev); 355 int error = 0; 356 struct ar71xx_gpio_pin *pinp; 357 int i; 358 359 KASSERT((device_get_unit(dev) == 0), 360 ("ar71xx_gpio: Only one gpio module supported")); 361 362 mtx_init(&sc->gpio_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK, 363 MTX_DEF); 364 365 /* Map control/status registers. */ 366 sc->gpio_mem_rid = 0; 367 sc->gpio_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, 368 &sc->gpio_mem_rid, RF_ACTIVE); 369 370 if (sc->gpio_mem_res == NULL) { 371 device_printf(dev, "couldn't map memory\n"); 372 error = ENXIO; 373 ar71xx_gpio_detach(dev); 374 return(error); 375 } 376 377 if ((sc->gpio_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, 378 &sc->gpio_irq_rid, RF_SHAREABLE | RF_ACTIVE)) == NULL) { 379 device_printf(dev, "unable to allocate IRQ resource\n"); 380 return (ENXIO); 381 } 382 383 if ((bus_setup_intr(dev, sc->gpio_irq_res, INTR_TYPE_MISC, 384 ar71xx_gpio_filter, ar71xx_gpio_intr, sc, &sc->gpio_ih))) { 385 device_printf(dev, 386 "WARNING: unable to register interrupt handler\n"); 387 return (ENXIO); 388 } 389 390 sc->dev = dev; 391 ar71xx_gpio_function_enable(sc, GPIO_FUNC_SPI_CS1_EN); 392 ar71xx_gpio_function_enable(sc, GPIO_FUNC_SPI_CS2_EN); 393 /* Configure all pins as input */ 394 /* disable interrupts for all pins */ 395 GPIO_WRITE(sc, AR71XX_GPIO_INT_MASK, 0); 396 pinp = ar71xx_gpio_pins; 397 i = 0; 398 while (pinp->name) { 399 strncpy(sc->gpio_pins[i].gp_name, pinp->name, GPIOMAXNAME); 400 sc->gpio_pins[i].gp_pin = pinp->pin; 401 sc->gpio_pins[i].gp_caps = DEFAULT_CAPS; 402 sc->gpio_pins[i].gp_flags = 0; 403 ar71xx_gpio_pin_configure(sc, &sc->gpio_pins[i], pinp->flags); 404 pinp++; 405 i++; 406 } 407 408 sc->gpio_npins = i; 409 410 device_add_child(dev, "gpioc", device_get_unit(dev)); 411 device_add_child(dev, "gpiobus", device_get_unit(dev)); 412 return (bus_generic_attach(dev)); 413} 414 415static int 416ar71xx_gpio_detach(device_t dev) 417{ 418 struct ar71xx_gpio_softc *sc = device_get_softc(dev); 419 420 KASSERT(mtx_initialized(&sc->gpio_mtx), ("gpio mutex not initialized")); 421 422 ar71xx_gpio_function_disable(sc, GPIO_FUNC_SPI_CS1_EN); 423 ar71xx_gpio_function_disable(sc, GPIO_FUNC_SPI_CS2_EN); 424 bus_generic_detach(dev); 425 426 if (sc->gpio_mem_res) 427 bus_release_resource(dev, SYS_RES_MEMORY, sc->gpio_mem_rid, 428 sc->gpio_mem_res); 429 430 mtx_destroy(&sc->gpio_mtx); 431 432 return(0); 433} 434 435static device_method_t ar71xx_gpio_methods[] = { 436 DEVMETHOD(device_probe, ar71xx_gpio_probe), 437 DEVMETHOD(device_attach, ar71xx_gpio_attach), 438 DEVMETHOD(device_detach, ar71xx_gpio_detach), 439 440 /* GPIO protocol */ 441 DEVMETHOD(gpio_pin_max, ar71xx_gpio_pin_max), 442 DEVMETHOD(gpio_pin_getname, ar71xx_gpio_pin_getname), 443 DEVMETHOD(gpio_pin_getflags, ar71xx_gpio_pin_getflags), 444 DEVMETHOD(gpio_pin_getcaps, ar71xx_gpio_pin_getcaps), 445 DEVMETHOD(gpio_pin_setflags, ar71xx_gpio_pin_setflags), 446 DEVMETHOD(gpio_pin_get, ar71xx_gpio_pin_get), 447 DEVMETHOD(gpio_pin_set, ar71xx_gpio_pin_set), 448 DEVMETHOD(gpio_pin_toggle, ar71xx_gpio_pin_toggle), 449 {0, 0}, 450}; 451 452static driver_t ar71xx_gpio_driver = { 453 "gpio", 454 ar71xx_gpio_methods, 455 sizeof(struct ar71xx_gpio_softc), 456}; 457static devclass_t ar71xx_gpio_devclass; 458 459DRIVER_MODULE(ar71xx_gpio, apb, ar71xx_gpio_driver, ar71xx_gpio_devclass, 0, 0);
|