Hi,
what's the plan for solving ordering issues for these devices?
could this be attached 'manually' from sunxi_platform_init_mainbus() or
something? What's acceptable?
I'd like to have this for carddetect before moving forward with that.
-Artturi
diff --git a/sys/arch/armv7/conf/GENERIC b/sys/arch/armv7/conf/GENERIC
index f9fdf06..843b002 100644
--- a/sys/arch/armv7/conf/GENERIC
+++ b/sys/arch/armv7/conf/GENERIC
@@ -86,7 +86,7 @@ sunxi0 at mainbus?
# Sunxi on-chip devices
sxiintc* at fdt? # A1x interrupt controller
-sxipio* at sunxi? # GPIO pins for leds & PHYs
+sxipio* at fdt?
gpio* at sxipio?
sxiccmu* at sunxi? # Clock Control Module/Unit
sxitimer* at sunxi?
diff --git a/sys/arch/armv7/conf/RAMDISK b/sys/arch/armv7/conf/RAMDISK
index adbfb82..e517ae2 100644
--- a/sys/arch/armv7/conf/RAMDISK
+++ b/sys/arch/armv7/conf/RAMDISK
@@ -85,7 +85,7 @@ sunxi0 at mainbus?
# Sunxi on-chip devices
sxiintc* at fdt? # A1x interrupt controller
-sxipio* at sunxi? # GPIO pins for leds & PHYs
+sxipio* at fdt?
gpio* at sxipio?
sxiccmu* at sunxi? # Clock Control Module/Unit
sxitimer* at sunxi?
diff --git a/sys/arch/armv7/sunxi/files.sunxi b/sys/arch/armv7/sunxi/files.sunxi
index 9a9c7a4..fde1cb2 100644
--- a/sys/arch/armv7/sunxi/files.sunxi
+++ b/sys/arch/armv7/sunxi/files.sunxi
@@ -13,7 +13,7 @@ attach sxiccmu at sunxi
file arch/armv7/sunxi/sxiccmu.c sxiccmu
device sxipio {}: gpiobus
-attach sxipio at sunxi
+attach sxipio at fdt
file arch/armv7/sunxi/sxipio.c sxipio
device sxiintc
diff --git a/sys/arch/armv7/sunxi/sunxi.c b/sys/arch/armv7/sunxi/sunxi.c
index edfa4fd..9127c29 100644
--- a/sys/arch/armv7/sunxi/sunxi.c
+++ b/sys/arch/armv7/sunxi/sunxi.c
@@ -40,7 +40,6 @@ struct cfdriver sunxi_cd = {
};
struct board_dev sun4i_devs[] = {
- { "sxipio", 0 },
{ "sxiccmu", 0 },
{ "sxitimer", 0 },
{ "sxitimer", 1 },
diff --git a/sys/arch/armv7/sunxi/sxipio.c b/sys/arch/armv7/sunxi/sxipio.c
index 9a49343..8a9d78a 100644
--- a/sys/arch/armv7/sunxi/sxipio.c
+++ b/sys/arch/armv7/sunxi/sxipio.c
@@ -23,6 +23,7 @@
#include <sys/evcount.h>
#include <machine/bus.h>
+#include <machine/fdt.h>
#include <machine/intr.h>
#include <dev/gpio/gpiovar.h>
@@ -31,6 +32,10 @@
#include <armv7/sunxi/sunxireg.h>
#include <armv7/sunxi/sxipiovar.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_gpio.h>
+#include <dev/ofw/fdt.h>
+
#include "gpio.h"
#define SXIPIO_NPORT 9
@@ -73,6 +78,8 @@ struct sxipio_softc {
gpio_pin_t sc_gpio_pins[SXIPIO_NPORT][32];
struct intrhand *sc_handlers[32];
+ int sc_node;
+ struct gpio_controller sc_gc;
};
#define SXIPIO_CFG(port, pin) 0x00 + ((port) * 0x24) + ((pin) << 2)
@@ -87,9 +94,15 @@ struct sxipio_softc {
void sxipio_attach(struct device *, struct device *, void *);
void sxipio_attach_gpio(struct device *);
+int sxipio_match(struct device *, void *, void *);
+
+void sxigpio_config_pin(void *, uint32_t *, int);
+int sxigpio_get_pin(void *, uint32_t *);
+void sxigpio_set_pin(void *, uint32_t *, int);
+
struct cfattach sxipio_ca = {
- sizeof (struct sxipio_softc), NULL, sxipio_attach
+ sizeof (struct sxipio_softc), sxipio_match, sxipio_attach
};
struct cfdriver sxipio_cd = {
@@ -100,29 +113,80 @@ struct sxipio_softc *sxipio_sc = NULL;
bus_space_tag_t sxipio_iot;
bus_space_handle_t sxipio_ioh;
+int
+sxipio_match(struct device *parent, void *match, void *args)
+{
+ struct fdt_attach_args *faa = args;
+
+ return OF_is_compatible(faa->fa_node, "allwinner,sun4i-a10-pinctrl");
+}
+
void
sxipio_attach(struct device *parent, struct device *self, void *args)
{
struct sxipio_softc *sc = (struct sxipio_softc *)self;
- struct armv7_attach_args *aa = args;
-
- /* XXX check unit, bail if != 0 */
+ struct fdt_attach_args *faa = args;
- sc->sc_iot = sxipio_iot = aa->aa_iot;
- if (bus_space_map(sxipio_iot, aa->aa_dev->mem[0].addr,
- aa->aa_dev->mem[0].size, 0, &sc->sc_ioh))
+ sc->sc_node = faa->fa_node;
+ sc->sc_iot = sxipio_iot = faa->fa_iot;
+ if (bus_space_map(sxipio_iot, faa->fa_reg[0].addr,
+ faa->fa_reg[0].size, 0, &sc->sc_ioh))
panic("sxipio_attach: bus_space_map failed!");
sxipio_ioh = sc->sc_ioh;
sxipio_sc = sc;
- sc->sc_irq = aa->aa_dev->irq[0];
+/* XXX sc->sc_irq = aa->aa_dev->irq[0];*/
+
+ sc->sc_gc.gc_node = faa->fa_node;
+ sc->sc_gc.gc_cookie = sc;
+ sc->sc_gc.gc_config_pin = sxigpio_config_pin;
+ sc->sc_gc.gc_get_pin = sxigpio_get_pin;
+ sc->sc_gc.gc_set_pin = sxigpio_set_pin;
+ gpio_controller_register(&sc->sc_gc);
config_defer(self, sxipio_attach_gpio);
printf("\n");
}
+void
+sxigpio_config_pin(void *cookie, uint32_t *cells, int config)
+{
+ uint32_t pin = (cells[0] * 32) + cells[1];
+
+ if (config & GPIO_CONFIG_OUTPUT)
+ sxipio_setcfg(pin, SXIPIO_OUTPUT);
+ else
+ sxipio_setcfg(pin, SXIPIO_INPUT);
+}
+
+int
+sxigpio_get_pin(void *cookie, uint32_t *cells)
+{
+ uint32_t pin = (cells[0] * 32) + cells[1];
+ uint32_t flags = cells[2];
+ int val;
+
+ val = sxipio_getpin(pin);
+ if (flags & GPIO_ACTIVE_LOW)
+ val = !val;
+ return val;
+}
+
+void
+sxigpio_set_pin(void *cookie, uint32_t *cells, int val)
+{
+ uint32_t pin = (cells[0] * 32) + cells[1];
+ uint32_t flags = cells[2];
+
+ if (flags & GPIO_ACTIVE_LOW)
+ val = !val;
+ if (val)
+ sxipio_setpin(pin);
+ else
+ sxipio_clrpin(pin);
+}
/*
* GPIO support code
*/