Re: Which is the read interface to GPIO?

KIYOHARA Takashi <[email protected]>
Newsgroups gmane.os.netbsd.ports.evbmips
Message-ID <[email protected]>
Hi! Garrett,


The reply apologizes ..slowly...  ;-<


From: "Garrett D'Amore" <[email protected]>
Date: Tue, 21 Mar 2006 21:53:22 -0800

> The reason for this is that there are "ordering constraints" otherwise
> -- how do you augpio has attached before aupcmcia?   This is something
> that I think autoconf lacks support for expressing (at least where the
> dependency is not implied as a result of child-parent relationship.)

Is it a problem in the following methods?  For instance, it can fake attach
it earlier more temporarily than augpio.  Please call augpio_attach_fake()
if you operate augpio earlier than attach of augpio. 
The prototype of the function is assumed to put it in a suitable header
file. 

Thanks,
--
kiyohara
augpio.c.diff (text/plain, 4.2 KB)
Index: dev/augpio.c
===================================================================
RCS file: /cvsroot/src/sys/arch/mips/alchemy/dev/augpio.c,v
retrieving revision 1.3
diff -u -r1.3 augpio.c
--- dev/augpio.c	18 Feb 2006 23:21:06 -0000	1.3
+++ dev/augpio.c	24 Mar 2006 00:30:56 -0000
@@ -41,6 +41,7 @@
 #include <sys/device.h>
 #include <sys/gpio.h>
 #include <sys/kernel.h>
+#include <sys/malloc.h>
 
 #include <dev/gpio/gpiovar.h>
 
@@ -62,6 +63,11 @@
 	const char 			*sc_name;
 	int				(*sc_getctl)(void *, int);
 };
+enum {
+	primary = 0,
+	secondary = 1,
+	ngpio = 2
+};
 
 static int augpio_read(void *, int);
 static void augpio_write(void *, int, int);
@@ -73,6 +79,12 @@
 static void augpio2_ctl(void *, int, int);
 static int augpio2_getctl(void *, int);
 
+int augpio_attach_fake(int);
+int augpioread(int, int);
+void augpiowrite(int, int, int);
+int augpiogetctl(int, int);
+void augpioctl(int, int, int);
+
 static int augpio_match(struct device *, struct cfdata *, void *);
 static void augpio_attach(struct device *, struct device *, void *);
 
@@ -85,6 +97,7 @@
 	((*(volatile uint32_t *)MIPS_PHYS_TO_KSEG1(x)) = (v))
 
 static int augpio_found = 0;
+static struct augpio_softc *softces[ngpio];
 
 int
 augpio_match(struct device *parent, struct cfdata *match, void *aux)
@@ -105,7 +118,7 @@
 {
 	int	pin;
 
-	struct augpio_softc *sc = (struct augpio_softc *)self;
+	struct augpio_softc *sc = (struct augpio_softc *)self, *fakesc;
 	struct aubus_attach_args *aa = aux;
 	struct gpiobus_attach_args gba;
 
@@ -114,6 +127,12 @@
 	sc->sc_gc.gp_cookie = sc;
 
 	if (aa->aa_addrs[0] == GPIO_BASE) {
+		if (softces[primary] != NULL) {
+			fakesc = softces[primary];
+			bus_space_unmap(fakesc->sc_bst,
+			    fakesc->sc_bsh, AUGPIO_SIZE);
+			free(fakesc, M_TEMP);
+		}
 
 		if (bus_space_map(sc->sc_bst, aa->aa_addrs[0],
 			AUGPIO_SIZE, 0, &sc->sc_bsh) != 0) {
@@ -128,6 +147,7 @@
 		sc->sc_getctl = augpio_getctl;
 		sc->sc_name = "primary block";
 
+		softces[primary] = sc;
 	} else if (aa->aa_addrs[0] == GPIO2_BASE) {
 		/*
 		 * We rely on firmware (or platform init code) to initialize
@@ -135,6 +155,12 @@
 		 * resetting the GPIO2 block can have nasty effects (e.g.
 		 * reset PCI bus...)
 		 */
+		if (softces[secondary] != NULL) {
+			fakesc = softces[secondary];
+			bus_space_unmap(fakesc->sc_bst,
+			    fakesc->sc_bsh, AUGPIO2_SIZE);
+			free(fakesc, M_TEMP);
+		}
 		if (bus_space_map(sc->sc_bst, aa->aa_addrs[0],
 			AUGPIO2_SIZE, 0, &sc->sc_bsh) != 0) {
 			printf(": cannot map registers!\n");
@@ -147,6 +173,7 @@
 		sc->sc_getctl = augpio2_getctl;
 		sc->sc_name = "secondary block";
 
+		softces[secondary] = sc;
 	} else {
 		printf(": unidentified block\n");
 		return;
@@ -287,3 +314,71 @@
 	}
 }
 
+int
+augpio_attach_fake(int gpio)
+{
+	struct augpio_softc *fakesc;
+	bus_addr_t address;
+	bus_size_t size;
+
+	if (softces[gpio] == NULL)
+		return 0;
+
+	fakesc = malloc(sizeof (struct augpio_softc), M_TEMP, M_NOWAIT);
+	fakesc->sc_bst = aubus_st;
+	if (gpio == primary) {
+		fakesc->sc_gc.gp_pin_read = augpio_read;
+		fakesc->sc_gc.gp_pin_write = augpio_write;
+		fakesc->sc_gc.gp_pin_ctl = augpio_ctl;
+		fakesc->sc_getctl = augpio_getctl;
+		address = GPIO_BASE;
+		size = AUGPIO_SIZE;
+	} else if (gpio == secondary) {
+		fakesc->sc_gc.gp_pin_read = augpio2_read;
+		fakesc->sc_gc.gp_pin_write = augpio2_write;
+		fakesc->sc_gc.gp_pin_ctl = augpio2_ctl;
+		fakesc->sc_getctl = augpio2_getctl;
+		address = GPIO2_BASE;
+		size = AUGPIO2_SIZE;
+	} else
+		return ~0;
+
+	if (bus_space_map(fakesc->sc_bst,
+	    address, size, 0, &fakesc->sc_bsh) != 0)
+		return ~0;
+	softces[gpio] = fakesc;
+
+	return 0;
+}
+
+int 
+augpioread(int gpio, int pin)
+{
+
+	KASSERT(softces[gpio] != NULL);
+	return softces[gpio]->sc_gc.gp_pin_read(softces[gpio], pin);
+}
+
+void 
+augpiowrite(int gpio, int pin, int value)
+{
+
+	KASSERT(softces[gpio] != NULL);
+	return softces[gpio]->sc_gc.gp_pin_write(softces[gpio], pin, value);
+}
+
+void 
+augpioctl(int gpio, int pin, int flags)
+{
+
+	KASSERT(softces[gpio] != NULL);
+	return softces[gpio]->sc_gc.gp_pin_ctl(softces[gpio], pin, flags);
+}
+
+int 
+augpiogetctl(int gpio, int pin)
+{
+
+	KASSERT(softces[gpio] != NULL);
+	return softces[gpio]->sc_getctl(softces[gpio], pin);
+}
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.