1/*- 2 * Copyright (c) 2006 M. Warner Losh. All rights reserved. 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 AUTHOR AND CONTRIBUTORS ``AS IS'' AND 14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16 * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE 17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 * LIABILITY, 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 26#include <sys/cdefs.h>
| 1/*- 2 * Copyright (c) 2006 M. Warner Losh. All rights reserved. 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 AUTHOR AND CONTRIBUTORS ``AS IS'' AND 14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16 * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE 17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 * LIABILITY, 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 26#include <sys/cdefs.h>
|
27__FBSDID("$FreeBSD: head/sys/arm/at91/at91_pio.c 225882 2011-09-30 04:55:23Z kevlo $");
| 27__FBSDID("$FreeBSD: head/sys/arm/at91/at91_pio.c 234281 2012-04-14 11:29:32Z marius $");
|
28 29#include <sys/param.h> 30#include <sys/systm.h> 31#include <sys/bus.h> 32#include <sys/conf.h> 33#include <sys/kernel.h> 34#include <sys/lock.h> 35#include <sys/mbuf.h> 36#include <sys/malloc.h> 37#include <sys/module.h> 38#include <sys/mutex.h> 39#include <sys/rman.h> 40#include <machine/bus.h> 41 42#include <arm/at91/at91reg.h> 43#include <arm/at91/at91_pioreg.h> 44#include <arm/at91/at91_piovar.h> 45 46struct at91_pio_softc 47{ 48 device_t dev; /* Myself */ 49 void *intrhand; /* Interrupt handle */ 50 struct resource *irq_res; /* IRQ resource */ 51 struct resource *mem_res; /* Memory resource */ 52 struct mtx sc_mtx; /* basically a perimeter lock */ 53 struct cdev *cdev; 54 int flags;
| 28 29#include <sys/param.h> 30#include <sys/systm.h> 31#include <sys/bus.h> 32#include <sys/conf.h> 33#include <sys/kernel.h> 34#include <sys/lock.h> 35#include <sys/mbuf.h> 36#include <sys/malloc.h> 37#include <sys/module.h> 38#include <sys/mutex.h> 39#include <sys/rman.h> 40#include <machine/bus.h> 41 42#include <arm/at91/at91reg.h> 43#include <arm/at91/at91_pioreg.h> 44#include <arm/at91/at91_piovar.h> 45 46struct at91_pio_softc 47{ 48 device_t dev; /* Myself */ 49 void *intrhand; /* Interrupt handle */ 50 struct resource *irq_res; /* IRQ resource */ 51 struct resource *mem_res; /* Memory resource */ 52 struct mtx sc_mtx; /* basically a perimeter lock */ 53 struct cdev *cdev; 54 int flags;
|
55#define OPENED 1
| 55#define OPENED 1
|
56}; 57 58static inline uint32_t 59RD4(struct at91_pio_softc *sc, bus_size_t off) 60{
| 56}; 57 58static inline uint32_t 59RD4(struct at91_pio_softc *sc, bus_size_t off) 60{
|
| 61
|
61 return (bus_read_4(sc->mem_res, off)); 62} 63 64static inline void 65WR4(struct at91_pio_softc *sc, bus_size_t off, uint32_t val) 66{
| 62 return (bus_read_4(sc->mem_res, off)); 63} 64 65static inline void 66WR4(struct at91_pio_softc *sc, bus_size_t off, uint32_t val) 67{
|
| 68
|
67 bus_write_4(sc->mem_res, off, val); 68} 69
| 69 bus_write_4(sc->mem_res, off, val); 70} 71
|
70#define AT91_PIO_LOCK(_sc) mtx_lock_spin(&(_sc)->sc_mtx)
| 72#define AT91_PIO_LOCK(_sc) mtx_lock_spin(&(_sc)->sc_mtx)
|
71#define AT91_PIO_UNLOCK(_sc) mtx_unlock_spin(&(_sc)->sc_mtx)
| 73#define AT91_PIO_UNLOCK(_sc) mtx_unlock_spin(&(_sc)->sc_mtx)
|
72#define AT91_PIO_LOCK_INIT(_sc) \
| 74#define AT91_PIO_LOCK_INIT(_sc) \
|
73 mtx_init(&_sc->sc_mtx, device_get_nameunit(_sc->dev), \ 74 "pio", MTX_SPIN)
| 75 mtx_init(&_sc->sc_mtx, device_get_nameunit(_sc->dev), \ 76 "pio", MTX_SPIN)
|
75#define AT91_PIO_LOCK_DESTROY(_sc) mtx_destroy(&_sc->sc_mtx); 76#define AT91_PIO_ASSERT_LOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_OWNED); 77#define AT91_PIO_ASSERT_UNLOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_NOTOWNED); 78#define CDEV2SOFTC(dev) ((dev)->si_drv1)
| 77#define AT91_PIO_LOCK_DESTROY(_sc) mtx_destroy(&_sc->sc_mtx); 78#define AT91_PIO_ASSERT_LOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_OWNED); 79#define AT91_PIO_ASSERT_UNLOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_NOTOWNED); 80#define CDEV2SOFTC(dev) ((dev)->si_drv1)
|
79 80static devclass_t at91_pio_devclass; 81 82/* bus entry points */ 83 84static int at91_pio_probe(device_t dev); 85static int at91_pio_attach(device_t dev); 86static int at91_pio_detach(device_t dev); 87static int at91_pio_intr(void *); 88 89/* helper routines */ 90static int at91_pio_activate(device_t dev); 91static void at91_pio_deactivate(device_t dev); 92 93/* cdev routines */ 94static d_open_t at91_pio_open; 95static d_close_t at91_pio_close; 96static d_ioctl_t at91_pio_ioctl; 97 98static struct cdevsw at91_pio_cdevsw = 99{ 100 .d_version = D_VERSION, 101 .d_open = at91_pio_open, 102 .d_close = at91_pio_close, 103 .d_ioctl = at91_pio_ioctl 104}; 105 106static int 107at91_pio_probe(device_t dev) 108{ 109 const char *name; 110 111 switch (device_get_unit(dev)) { 112 case 0: 113 name = "PIOA"; 114 break; 115 case 1: 116 name = "PIOB"; 117 break; 118 case 2: 119 name = "PIOC"; 120 break; 121 case 3: 122 name = "PIOD"; 123 break; 124 default: 125 name = "PIO"; 126 break; 127 } 128 device_set_desc(dev, name); 129 return (0); 130} 131 132static int 133at91_pio_attach(device_t dev) 134{
| 81 82static devclass_t at91_pio_devclass; 83 84/* bus entry points */ 85 86static int at91_pio_probe(device_t dev); 87static int at91_pio_attach(device_t dev); 88static int at91_pio_detach(device_t dev); 89static int at91_pio_intr(void *); 90 91/* helper routines */ 92static int at91_pio_activate(device_t dev); 93static void at91_pio_deactivate(device_t dev); 94 95/* cdev routines */ 96static d_open_t at91_pio_open; 97static d_close_t at91_pio_close; 98static d_ioctl_t at91_pio_ioctl; 99 100static struct cdevsw at91_pio_cdevsw = 101{ 102 .d_version = D_VERSION, 103 .d_open = at91_pio_open, 104 .d_close = at91_pio_close, 105 .d_ioctl = at91_pio_ioctl 106}; 107 108static int 109at91_pio_probe(device_t dev) 110{ 111 const char *name; 112 113 switch (device_get_unit(dev)) { 114 case 0: 115 name = "PIOA"; 116 break; 117 case 1: 118 name = "PIOB"; 119 break; 120 case 2: 121 name = "PIOC"; 122 break; 123 case 3: 124 name = "PIOD"; 125 break; 126 default: 127 name = "PIO"; 128 break; 129 } 130 device_set_desc(dev, name); 131 return (0); 132} 133 134static int 135at91_pio_attach(device_t dev) 136{
|
135 struct at91_pio_softc *sc = device_get_softc(dev);
| 137 struct at91_pio_softc *sc;
|
136 int err; 137
| 138 int err; 139
|
| 140 sc = device_get_softc(dev);
|
138 sc->dev = dev; 139 err = at91_pio_activate(dev); 140 if (err) 141 goto out; 142 143 device_printf(dev, "ABSR: %#x OSR: %#x PSR:%#x ODSR: %#x\n", 144 RD4(sc, PIO_ABSR), RD4(sc, PIO_OSR), RD4(sc, PIO_PSR), 145 RD4(sc, PIO_ODSR)); 146 AT91_PIO_LOCK_INIT(sc); 147 148 /*
| 141 sc->dev = dev; 142 err = at91_pio_activate(dev); 143 if (err) 144 goto out; 145 146 device_printf(dev, "ABSR: %#x OSR: %#x PSR:%#x ODSR: %#x\n", 147 RD4(sc, PIO_ABSR), RD4(sc, PIO_OSR), RD4(sc, PIO_PSR), 148 RD4(sc, PIO_ODSR)); 149 AT91_PIO_LOCK_INIT(sc); 150 151 /*
|
149 * Activate the interrupt, but disable all interrupts in the hardware
| 152 * Activate the interrupt, but disable all interrupts in the hardware.
|
150 */ 151 WR4(sc, PIO_IDR, 0xffffffff); 152 err = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_MISC, 153 at91_pio_intr, NULL, sc, &sc->intrhand); 154 if (err) { 155 AT91_PIO_LOCK_DESTROY(sc); 156 goto out; 157 } 158 sc->cdev = make_dev(&at91_pio_cdevsw, device_get_unit(dev), UID_ROOT, 159 GID_WHEEL, 0600, "pio%d", device_get_unit(dev)); 160 if (sc->cdev == NULL) { 161 err = ENOMEM; 162 goto out; 163 } 164 sc->cdev->si_drv1 = sc; 165out: 166 if (err) 167 at91_pio_deactivate(dev); 168 return (err); 169} 170 171static int 172at91_pio_detach(device_t dev) 173{
| 153 */ 154 WR4(sc, PIO_IDR, 0xffffffff); 155 err = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_MISC, 156 at91_pio_intr, NULL, sc, &sc->intrhand); 157 if (err) { 158 AT91_PIO_LOCK_DESTROY(sc); 159 goto out; 160 } 161 sc->cdev = make_dev(&at91_pio_cdevsw, device_get_unit(dev), UID_ROOT, 162 GID_WHEEL, 0600, "pio%d", device_get_unit(dev)); 163 if (sc->cdev == NULL) { 164 err = ENOMEM; 165 goto out; 166 } 167 sc->cdev->si_drv1 = sc; 168out: 169 if (err) 170 at91_pio_deactivate(dev); 171 return (err); 172} 173 174static int 175at91_pio_detach(device_t dev) 176{
|
| 177
|
174 return (EBUSY); /* XXX */ 175} 176 177static int 178at91_pio_activate(device_t dev) 179{ 180 struct at91_pio_softc *sc; 181 int rid; 182 183 sc = device_get_softc(dev); 184 rid = 0; 185 sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, 186 RF_ACTIVE); 187 if (sc->mem_res == NULL) 188 goto errout; 189 rid = 0; 190 sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, 191 RF_ACTIVE | RF_SHAREABLE); 192 if (sc->irq_res == NULL) 193 goto errout; 194 return (0); 195errout: 196 at91_pio_deactivate(dev); 197 return (ENOMEM); 198} 199 200static void 201at91_pio_deactivate(device_t dev) 202{ 203 struct at91_pio_softc *sc; 204 205 sc = device_get_softc(dev); 206 if (sc->intrhand) 207 bus_teardown_intr(dev, sc->irq_res, sc->intrhand); 208 sc->intrhand = 0; 209 bus_generic_detach(sc->dev); 210 if (sc->mem_res) 211 bus_release_resource(dev, SYS_RES_IOPORT, 212 rman_get_rid(sc->mem_res), sc->mem_res); 213 sc->mem_res = 0; 214 if (sc->irq_res) 215 bus_release_resource(dev, SYS_RES_IRQ, 216 rman_get_rid(sc->irq_res), sc->irq_res); 217 sc->irq_res = 0;
| 178 return (EBUSY); /* XXX */ 179} 180 181static int 182at91_pio_activate(device_t dev) 183{ 184 struct at91_pio_softc *sc; 185 int rid; 186 187 sc = device_get_softc(dev); 188 rid = 0; 189 sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, 190 RF_ACTIVE); 191 if (sc->mem_res == NULL) 192 goto errout; 193 rid = 0; 194 sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, 195 RF_ACTIVE | RF_SHAREABLE); 196 if (sc->irq_res == NULL) 197 goto errout; 198 return (0); 199errout: 200 at91_pio_deactivate(dev); 201 return (ENOMEM); 202} 203 204static void 205at91_pio_deactivate(device_t dev) 206{ 207 struct at91_pio_softc *sc; 208 209 sc = device_get_softc(dev); 210 if (sc->intrhand) 211 bus_teardown_intr(dev, sc->irq_res, sc->intrhand); 212 sc->intrhand = 0; 213 bus_generic_detach(sc->dev); 214 if (sc->mem_res) 215 bus_release_resource(dev, SYS_RES_IOPORT, 216 rman_get_rid(sc->mem_res), sc->mem_res); 217 sc->mem_res = 0; 218 if (sc->irq_res) 219 bus_release_resource(dev, SYS_RES_IRQ, 220 rman_get_rid(sc->irq_res), sc->irq_res); 221 sc->irq_res = 0;
|
218 return;
| |
219} 220 221static int 222at91_pio_intr(void *xsc) 223{ 224 struct at91_pio_softc *sc = xsc; 225#if 0 226 uint32_t status; 227
| 222} 223 224static int 225at91_pio_intr(void *xsc) 226{ 227 struct at91_pio_softc *sc = xsc; 228#if 0 229 uint32_t status; 230
|
228 /* Reading the status also clears the interrupt */
| 231 /* Reading the status also clears the interrupt. */
|
229 status = RD4(sc, PIO_SR); 230 if (status == 0) 231 return; 232 AT91_PIO_LOCK(sc); 233 AT91_PIO_UNLOCK(sc); 234#endif 235 wakeup(sc); 236 return (FILTER_HANDLED); 237} 238
| 232 status = RD4(sc, PIO_SR); 233 if (status == 0) 234 return; 235 AT91_PIO_LOCK(sc); 236 AT91_PIO_UNLOCK(sc); 237#endif 238 wakeup(sc); 239 return (FILTER_HANDLED); 240} 241
|
239static int
| 242static int
|
240at91_pio_open(struct cdev *dev, int oflags, int devtype, struct thread *td) 241{ 242 struct at91_pio_softc *sc; 243 244 sc = CDEV2SOFTC(dev); 245 AT91_PIO_LOCK(sc); 246 if (!(sc->flags & OPENED)) { 247 sc->flags |= OPENED; 248#if 0
| 243at91_pio_open(struct cdev *dev, int oflags, int devtype, struct thread *td) 244{ 245 struct at91_pio_softc *sc; 246 247 sc = CDEV2SOFTC(dev); 248 AT91_PIO_LOCK(sc); 249 if (!(sc->flags & OPENED)) { 250 sc->flags |= OPENED; 251#if 0
|
249 // Enable interrupts
| 252 /* Enable interrupts. */
|
250#endif 251 } 252 AT91_PIO_UNLOCK(sc);
| 253#endif 254 } 255 AT91_PIO_UNLOCK(sc);
|
253 return (0);
| 256 return (0);
|
254} 255 256static int 257at91_pio_close(struct cdev *dev, int fflag, int devtype, struct thread *td) 258{ 259 struct at91_pio_softc *sc; 260 261 sc = CDEV2SOFTC(dev); 262 AT91_PIO_LOCK(sc); 263 sc->flags &= ~OPENED; 264#if 0
| 257} 258 259static int 260at91_pio_close(struct cdev *dev, int fflag, int devtype, struct thread *td) 261{ 262 struct at91_pio_softc *sc; 263 264 sc = CDEV2SOFTC(dev); 265 AT91_PIO_LOCK(sc); 266 sc->flags &= ~OPENED; 267#if 0
|
265 // Disable interrupts
| 268 /* Disable interrupts. */
|
266#endif 267 AT91_PIO_UNLOCK(sc); 268 return (0); 269} 270 271static int 272at91_pio_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, 273 struct thread *td) 274{
| 269#endif 270 AT91_PIO_UNLOCK(sc); 271 return (0); 272} 273 274static int 275at91_pio_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, 276 struct thread *td) 277{
|
| 278
|
275 return (ENXIO); 276} 277 278/* 279 * The following functions are called early in the boot process, so 280 * don't use bus_space, as that isn't yet available when we need to use 281 * them. 282 */
| 279 return (ENXIO); 280} 281 282/* 283 * The following functions are called early in the boot process, so 284 * don't use bus_space, as that isn't yet available when we need to use 285 * them. 286 */
|
| 287
|
283void 284at91_pio_use_periph_a(uint32_t pio, uint32_t periph_a_mask, int use_pullup) 285{ 286 uint32_t *PIO = (uint32_t *)(AT91_BASE + pio); 287 288 PIO[PIO_ASR / 4] = periph_a_mask; 289 PIO[PIO_PDR / 4] = periph_a_mask; 290 if (use_pullup) 291 PIO[PIO_PUER / 4] = periph_a_mask; 292 else 293 PIO[PIO_PUDR / 4] = periph_a_mask; 294} 295 296void 297at91_pio_use_periph_b(uint32_t pio, uint32_t periph_b_mask, int use_pullup) 298{ 299 uint32_t *PIO = (uint32_t *)(AT91_BASE + pio); 300 301 PIO[PIO_BSR / 4] = periph_b_mask; 302 PIO[PIO_PDR / 4] = periph_b_mask; 303 if (use_pullup) 304 PIO[PIO_PUER / 4] = periph_b_mask; 305 else 306 PIO[PIO_PUDR / 4] = periph_b_mask; 307} 308 309void 310at91_pio_use_gpio(uint32_t pio, uint32_t gpio_mask) 311{ 312 uint32_t *PIO = (uint32_t *)(AT91_BASE + pio); 313 314 PIO[PIO_PER / 4] = gpio_mask; 315} 316 317void 318at91_pio_gpio_input(uint32_t pio, uint32_t input_enable_mask) 319{ 320 uint32_t *PIO = (uint32_t *)(AT91_BASE + pio); 321 322 PIO[PIO_ODR / 4] = input_enable_mask; 323} 324 325void 326at91_pio_gpio_output(uint32_t pio, uint32_t output_enable_mask, int use_pullup) 327{ 328 uint32_t *PIO = (uint32_t *)(AT91_BASE + pio); 329 330 PIO[PIO_OER / 4] = output_enable_mask; 331 if (use_pullup) 332 PIO[PIO_PUER / 4] = output_enable_mask; 333 else 334 PIO[PIO_PUDR / 4] = output_enable_mask; 335} 336 337void 338at91_pio_gpio_set(uint32_t pio, uint32_t data_mask) 339{ 340 uint32_t *PIO = (uint32_t *)(AT91_BASE + pio); 341 342 PIO[PIO_SODR / 4] = data_mask; 343} 344 345void 346at91_pio_gpio_clear(uint32_t pio, uint32_t data_mask) 347{ 348 uint32_t *PIO = (uint32_t *)(AT91_BASE + pio); 349 350 PIO[PIO_CODR / 4] = data_mask; 351} 352 353uint8_t 354at91_pio_gpio_get(uint32_t pio, uint32_t data_mask) 355{ 356 uint32_t *PIO = (uint32_t *)(AT91_BASE + pio); 357 358 data_mask &= PIO[PIO_PDSR / 4]; 359 360 return (data_mask ? 1 : 0); 361} 362 363void 364at91_pio_gpio_set_deglitch(uint32_t pio, uint32_t data_mask, int use_deglitch) 365{ 366 uint32_t *PIO = (uint32_t *)(AT91_BASE + pio); 367 368 if (use_deglitch) 369 PIO[PIO_IFER / 4] = data_mask; 370 else 371 PIO[PIO_IFDR / 4] = data_mask;
| 288void 289at91_pio_use_periph_a(uint32_t pio, uint32_t periph_a_mask, int use_pullup) 290{ 291 uint32_t *PIO = (uint32_t *)(AT91_BASE + pio); 292 293 PIO[PIO_ASR / 4] = periph_a_mask; 294 PIO[PIO_PDR / 4] = periph_a_mask; 295 if (use_pullup) 296 PIO[PIO_PUER / 4] = periph_a_mask; 297 else 298 PIO[PIO_PUDR / 4] = periph_a_mask; 299} 300 301void 302at91_pio_use_periph_b(uint32_t pio, uint32_t periph_b_mask, int use_pullup) 303{ 304 uint32_t *PIO = (uint32_t *)(AT91_BASE + pio); 305 306 PIO[PIO_BSR / 4] = periph_b_mask; 307 PIO[PIO_PDR / 4] = periph_b_mask; 308 if (use_pullup) 309 PIO[PIO_PUER / 4] = periph_b_mask; 310 else 311 PIO[PIO_PUDR / 4] = periph_b_mask; 312} 313 314void 315at91_pio_use_gpio(uint32_t pio, uint32_t gpio_mask) 316{ 317 uint32_t *PIO = (uint32_t *)(AT91_BASE + pio); 318 319 PIO[PIO_PER / 4] = gpio_mask; 320} 321 322void 323at91_pio_gpio_input(uint32_t pio, uint32_t input_enable_mask) 324{ 325 uint32_t *PIO = (uint32_t *)(AT91_BASE + pio); 326 327 PIO[PIO_ODR / 4] = input_enable_mask; 328} 329 330void 331at91_pio_gpio_output(uint32_t pio, uint32_t output_enable_mask, int use_pullup) 332{ 333 uint32_t *PIO = (uint32_t *)(AT91_BASE + pio); 334 335 PIO[PIO_OER / 4] = output_enable_mask; 336 if (use_pullup) 337 PIO[PIO_PUER / 4] = output_enable_mask; 338 else 339 PIO[PIO_PUDR / 4] = output_enable_mask; 340} 341 342void 343at91_pio_gpio_set(uint32_t pio, uint32_t data_mask) 344{ 345 uint32_t *PIO = (uint32_t *)(AT91_BASE + pio); 346 347 PIO[PIO_SODR / 4] = data_mask; 348} 349 350void 351at91_pio_gpio_clear(uint32_t pio, uint32_t data_mask) 352{ 353 uint32_t *PIO = (uint32_t *)(AT91_BASE + pio); 354 355 PIO[PIO_CODR / 4] = data_mask; 356} 357 358uint8_t 359at91_pio_gpio_get(uint32_t pio, uint32_t data_mask) 360{ 361 uint32_t *PIO = (uint32_t *)(AT91_BASE + pio); 362 363 data_mask &= PIO[PIO_PDSR / 4]; 364 365 return (data_mask ? 1 : 0); 366} 367 368void 369at91_pio_gpio_set_deglitch(uint32_t pio, uint32_t data_mask, int use_deglitch) 370{ 371 uint32_t *PIO = (uint32_t *)(AT91_BASE + pio); 372 373 if (use_deglitch) 374 PIO[PIO_IFER / 4] = data_mask; 375 else 376 PIO[PIO_IFDR / 4] = data_mask;
|
372 return;
| |
373} 374 375void
| 377} 378 379void
|
376at91_pio_gpio_set_interrupt(uint32_t pio, uint32_t data_mask,
| 380at91_pio_gpio_set_interrupt(uint32_t pio, uint32_t data_mask,
|
377 int enable_interrupt) 378{ 379 uint32_t *PIO = (uint32_t *)(AT91_BASE + pio); 380 381 if (enable_interrupt) 382 PIO[PIO_IER / 4] = data_mask; 383 else 384 PIO[PIO_IDR / 4] = data_mask;
| 381 int enable_interrupt) 382{ 383 uint32_t *PIO = (uint32_t *)(AT91_BASE + pio); 384 385 if (enable_interrupt) 386 PIO[PIO_IER / 4] = data_mask; 387 else 388 PIO[PIO_IDR / 4] = data_mask;
|
385 return;
| |
386} 387 388uint32_t 389at91_pio_gpio_clear_interrupt(uint32_t pio) 390{ 391 uint32_t *PIO = (uint32_t *)(AT91_BASE + pio);
| 389} 390 391uint32_t 392at91_pio_gpio_clear_interrupt(uint32_t pio) 393{ 394 uint32_t *PIO = (uint32_t *)(AT91_BASE + pio);
|
392 /* reading this register will clear the interrupts */
| 395 396 /* Reading this register will clear the interrupts. */
|
393 return (PIO[PIO_ISR / 4]); 394} 395 396static device_method_t at91_pio_methods[] = { 397 /* Device interface */ 398 DEVMETHOD(device_probe, at91_pio_probe), 399 DEVMETHOD(device_attach, at91_pio_attach), 400 DEVMETHOD(device_detach, at91_pio_detach), 401
| 397 return (PIO[PIO_ISR / 4]); 398} 399 400static device_method_t at91_pio_methods[] = { 401 /* Device interface */ 402 DEVMETHOD(device_probe, at91_pio_probe), 403 DEVMETHOD(device_attach, at91_pio_attach), 404 DEVMETHOD(device_detach, at91_pio_detach), 405
|
402 { 0, 0 }
| 406 DEVMETHOD_END
|
403}; 404 405static driver_t at91_pio_driver = { 406 "at91_pio", 407 at91_pio_methods, 408 sizeof(struct at91_pio_softc), 409}; 410
| 407}; 408 409static driver_t at91_pio_driver = { 410 "at91_pio", 411 at91_pio_methods, 412 sizeof(struct at91_pio_softc), 413}; 414
|
411DRIVER_MODULE(at91_pio, atmelarm, at91_pio_driver, at91_pio_devclass, 0, 0);
| 415DRIVER_MODULE(at91_pio, atmelarm, at91_pio_driver, at91_pio_devclass, NULL, 416 NULL);
|
| |