PERFORCE change 111751 for review
Warner Losh
imp at FreeBSD.org
Fri Dec 15 13:23:18 PST 2006
http://perforce.freebsd.org/chv.cgi?CH=111751
Change 111751 by imp at imp_bugs on 2006/12/15 21:22:23
MF FreeBSD-tsc-6:
Bring in Patrick Schweiger's bug fixes:
o use right members
o fix comments
o bit banger!
o add isr to things we can control
Plus my poll routine.
Affected files ...
.. //depot/projects/arm/src/sys/arm/at91/at91_pio.c#25 edit
.. //depot/projects/arm/src/sys/sys/gpio.h#6 edit
Differences ...
==== //depot/projects/arm/src/sys/arm/at91/at91_pio.c#25 (text+ko) ====
@@ -36,7 +36,9 @@
#include <sys/malloc.h>
#include <sys/module.h>
#include <sys/mutex.h>
+#include <sys/poll.h>
#include <sys/rman.h>
+#include <sys/selinfo.h>
#include <sys/uio.h>
#include <machine/bus.h>
@@ -54,6 +56,7 @@
struct resource *mem_res; /* Memory resource */
struct mtx sc_mtx; /* basically a perimeter lock */
struct cdev *cdev;
+ struct selinfo selp;
int buflen;
uint8_t buf[MAX_CHANGE];
int flags;
@@ -99,6 +102,7 @@
static d_open_t at91_pio_open;
static d_close_t at91_pio_close;
static d_read_t at91_pio_read;
+static d_poll_t at91_pio_poll;
static d_ioctl_t at91_pio_ioctl;
static struct cdevsw at91_pio_cdevsw =
@@ -107,6 +111,7 @@
.d_open = at91_pio_open,
.d_close = at91_pio_close,
.d_read = at91_pio_read,
+ .d_poll = at91_pio_poll,
.d_ioctl = at91_pio_ioctl
};
@@ -278,6 +283,25 @@
}
static int
+at91_pio_poll(struct cdev *dev, int events, struct thread *td)
+{
+ struct at91_pio_softc *sc;
+ int revents = 0;
+
+ sc = CDEV2SOFTC(dev);
+ AT91_PIO_LOCK(sc);
+ if (events & (POLLIN | POLLRDNORM)) {
+ if (sc->buflen != 0)
+ revents |= events & (POLLIN | POLLRDNORM);
+ else
+ selrecord(td, &sc->selp);
+ }
+ AT91_PIO_UNLOCK(sc);
+
+ return (revents);
+}
+
+static int
at91_pio_read(struct cdev *dev, struct uio *uio, int flag)
{
struct at91_pio_softc *sc;
@@ -321,6 +345,8 @@
struct at91_pio_softc *sc = CDEV2SOFTC(dev);
struct gpio_cfg *cfg;
struct gpio_info *info;
+ struct gpio_bang *bang;
+ uint32_t bits, i;
switch(cmd) {
case GPIO_SET: /* turn bits on */
@@ -347,20 +373,33 @@
WR4(sc, PIO_PUER, cfg->iomask & cfg->pullup);
}
if (cfg->cfgmask & GPIO_CFG_GLITCH) {
- WR4(sc, PIO_IFDR, cfg->iomask & ~cfg->pullup);
- WR4(sc, PIO_IFER, cfg->iomask & cfg->pullup);
+ WR4(sc, PIO_IFDR, cfg->iomask & ~cfg->glitch);
+ WR4(sc, PIO_IFER, cfg->iomask & cfg->glitch);
}
if (cfg->cfgmask & GPIO_CFG_ENABLED) {
- WR4(sc, PIO_PDR, cfg->iomask & ~cfg->pullup);
- WR4(sc, PIO_PER, cfg->iomask & cfg->pullup);
+ WR4(sc, PIO_PDR, cfg->iomask & ~cfg->enabled);
+ WR4(sc, PIO_PER, cfg->iomask & cfg->enabled);
}
if (cfg->cfgmask & GPIO_CFG_PERIPH) {
- WR4(sc, PIO_ASR, cfg->iomask & ~cfg->pullup);
- WR4(sc, PIO_BSR, cfg->iomask & cfg->pullup);
+ WR4(sc, PIO_ASR, cfg->iomask & ~cfg->periph);
+ WR4(sc, PIO_BSR, cfg->iomask & cfg->periph);
}
if (cfg->cfgmask & GPIO_CFG_ISR) {
- WR4(sc, PIO_IDR, cfg->iomask & ~cfg->pullup);
- WR4(sc, PIO_IER, cfg->iomask & cfg->pullup);
+ WR4(sc, PIO_IDR, cfg->iomask & ~cfg->isr);
+ WR4(sc, PIO_IER, cfg->iomask & cfg->isr);
+ }
+ return (0);
+ case GPIO_BANG:
+ bang = (struct gpio_bang *)data;
+ bits = bang->bits;
+ for (i = 0; i < 32; i++) {
+ if (bits & 0x80000000)
+ WR4(sc, PIO_SODR, bang->datapin);
+ else
+ WR4(sc, PIO_CODR, bang->datapin);
+ bits <<= 1;
+ WR4(sc, PIO_CODR, bang->clockpin);
+ WR4(sc, PIO_SODR, bang->clockpin);
}
return (0);
case GPIO_INFO: /* Learn about this device's GPIO bits */
==== //depot/projects/arm/src/sys/sys/gpio.h#6 (text+ko) ====
@@ -36,9 +36,9 @@
struct gpio_info
{
uint32_t output_status; /* Current state of output pins */
- uint32_t input_status; /* 1->in 0->out bitmask */
+ uint32_t input_status; /* 1->out 0->in bitmask */
uint32_t highz_status; /* 1->highz 0->driven bitmask */
- uint32_t pullup_status; /* 1->pullup engaged 0->floating */
+ uint32_t pullup_status; /* 1->floating 0->pullup engaged */
uint32_t glitch_status; /* 0-> no glitch filter 1->gf */
uint32_t enabled_status; /* 1->used for gpio 0->other */
uint32_t periph_status; /* 0->A periph 1->B periph */
@@ -63,12 +63,21 @@
uint32_t glitch; /* Glitch filtering */
uint32_t enabled; /* Enabled for GPIO (1) or other (0) */
uint32_t periph; /* Select which periph, if possible */
+ uint32_t isr; /* Enable interrupt (1), or not (0) */
};
+struct gpio_bang
+{
+ uint32_t clockpin; /* clock pin MASK */
+ uint32_t datapin; /* Data pin MASK */
+ uint32_t bits; /* bits to clock out (all 32) */
+};
+
#define GPIO_SET _IOW('g', 0, uint32_t) /* Turn bits on */
#define GPIO_CLR _IOW('g', 1, uint32_t) /* Turn bits off */
#define GPIO_READ _IOR('g', 2, uint32_t) /* Read input bit state */
#define GPIO_INFO _IOR('g', 3, struct gpio_info) /* State of gpio cfg */
#define GPIO_CFG _IOW('g', 4, struct gpio_cfg) /* Configure gpio */
+#define GPIO_BANG _IOW('g', 5, struct gpio_bang) /* bit bang 32 bits */
#endif /* _SYS_GPIO_H */
More information about the p4-projects
mailing list