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