Date: Fri, 15 Dec 2006 21:23:14 GMT From: Warner Losh <imp@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 111751 for review Message-ID: <200612152123.kBFLNE9K046290@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=111751 Change 111751 by imp@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 */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200612152123.kBFLNE9K046290>