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 */