summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrapha <rapha@openbsd.org>2013-11-20 13:32:40 +0000
committerrapha <rapha@openbsd.org>2013-11-20 13:32:40 +0000
commit85a34ca9b305ae11040412584df147bf357b90ae (patch)
tree9142a35651e96e028c40a899c51c883cad7189ab
parentRework the mda and scheduler to use the holdq mechanism instead of (diff)
downloadwireguard-openbsd-85a34ca9b305ae11040412584df147bf357b90ae.tar.xz
wireguard-openbsd-85a34ca9b305ae11040412584df147bf357b90ae.zip
Add gpio(4) support for omap3/4 and am335x.
Feedback by patrick and syl, tested by syl on BeagleBoard and BBB. ok syl@
-rw-r--r--sys/arch/armv7/armv7/armv7.c6
-rw-r--r--sys/arch/armv7/conf/GENERIC-OMAP5
-rw-r--r--sys/arch/armv7/omap/am335x.c30
-rw-r--r--sys/arch/armv7/omap/files.omap4
-rw-r--r--sys/arch/armv7/omap/omgpio.c417
-rw-r--r--sys/arch/armv7/omap/omgpiovar.h6
6 files changed, 314 insertions, 154 deletions
diff --git a/sys/arch/armv7/armv7/armv7.c b/sys/arch/armv7/armv7/armv7.c
index 3590a2a0a49..cf68e1b212f 100644
--- a/sys/arch/armv7/armv7/armv7.c
+++ b/sys/arch/armv7/armv7/armv7.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: armv7.c,v 1.1 2013/11/06 19:08:06 syl Exp $ */
+/* $OpenBSD: armv7.c,v 1.2 2013/11/20 13:32:40 rapha Exp $ */
/*
* Copyright (c) 2005,2008 Dale Rahn <drahn@openbsd.com>
* Copyright (c) 2012-2013 Patrick Wildt <patrick@blueri.se>
@@ -134,6 +134,10 @@ struct board_dev beaglebone_devs[] = {
{ "dmtimer", 0 },
{ "dmtimer", 1 },
{ "omdog", 0 },
+ { "omgpio", 0 },
+ { "omgpio", 1 },
+ { "omgpio", 2 },
+ { "omgpio", 3 },
{ "ommmc", 0 }, /* HSMMC0 */
{ "ommmc", 1 }, /* HSMMC1 */
{ "com", 0 }, /* UART0 */
diff --git a/sys/arch/armv7/conf/GENERIC-OMAP b/sys/arch/armv7/conf/GENERIC-OMAP
index 37560854401..b6864f5d822 100644
--- a/sys/arch/armv7/conf/GENERIC-OMAP
+++ b/sys/arch/armv7/conf/GENERIC-OMAP
@@ -1,4 +1,4 @@
-# $OpenBSD: GENERIC-OMAP,v 1.4 2013/11/15 19:42:20 sasano Exp $
+# $OpenBSD: GENERIC-OMAP,v 1.5 2013/11/20 13:32:40 rapha Exp $
#
# GENERIC machine description file
#
@@ -30,6 +30,8 @@ options BUILD_STARTUP_PAGETABLE
options STARTUP_PAGETABLE_ADDR=0x80200000
options SDRAM_START="0x80000000"
+option CONF_HAVE_GPIO
+
#options APERTURE
#options BOOT_CONFIG # boot-time kernel config
@@ -71,6 +73,7 @@ prcm* at omap? # power/clock controller
sitaracm* at omap? # sitara control module
omdog* at omap? # watchdog timer
omgpio* at omap? # user-visible GPIO pins?
+gpio* at omgpio?
gptimer* at omap? # general purpose timers
dmtimer* at omap? # am335x dual mode timers
ommmc* at omap? # SD/MMC card controller
diff --git a/sys/arch/armv7/omap/am335x.c b/sys/arch/armv7/omap/am335x.c
index 24302ba11af..1888c29ff46 100644
--- a/sys/arch/armv7/omap/am335x.c
+++ b/sys/arch/armv7/omap/am335x.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: am335x.c,v 1.5 2013/11/06 19:03:07 syl Exp $ */
+/* $OpenBSD: am335x.c,v 1.6 2013/11/20 13:32:40 rapha Exp $ */
/*
* Copyright (c) 2011 Uwe Stuehler <uwe@openbsd.org>
@@ -171,6 +171,34 @@ struct armv7_dev am335x_devs[] = {
},
/*
+ * GPIO
+ */
+
+ { .name = "omgpio",
+ .unit = 0,
+ .mem = { { GPIO0_ADDR, GPIOx_SIZE } },
+ .irq = { GPIO0_IRQ }
+ },
+
+ { .name = "omgpio",
+ .unit = 1,
+ .mem = { { GPIO1_ADDR, GPIOx_SIZE } },
+ .irq = { GPIO1_IRQ }
+ },
+
+ { .name = "omgpio",
+ .unit = 2,
+ .mem = { { GPIO2_ADDR, GPIOx_SIZE } },
+ .irq = { GPIO2_IRQ }
+ },
+
+ { .name = "omgpio",
+ .unit = 3,
+ .mem = { { GPIO3_ADDR, GPIOx_SIZE } },
+ .irq = { GPIO3_IRQ }
+ },
+
+ /*
* MMC
*/
diff --git a/sys/arch/armv7/omap/files.omap b/sys/arch/armv7/omap/files.omap
index 337c558c65d..2c920cd25ce 100644
--- a/sys/arch/armv7/omap/files.omap
+++ b/sys/arch/armv7/omap/files.omap
@@ -1,4 +1,4 @@
-# $OpenBSD: files.omap,v 1.4 2013/11/06 19:03:07 syl Exp $
+# $OpenBSD: files.omap,v 1.5 2013/11/20 13:32:40 rapha Exp $
define omap {}
device omap: omap
@@ -26,7 +26,7 @@ attach sitaracm at omap
file arch/armv7/omap/am335x_cm_padconf.c sitaracm
file arch/armv7/omap/sitara_cm.c sitaracm
-device omgpio
+device omgpio: gpiobus
attach omgpio at omap
file arch/armv7/omap/omgpio.c omgpio
diff --git a/sys/arch/armv7/omap/omgpio.c b/sys/arch/armv7/omap/omgpio.c
index 78ad8c50dae..54138a8d601 100644
--- a/sys/arch/armv7/omap/omgpio.c
+++ b/sys/arch/armv7/omap/omgpio.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: omgpio.c,v 1.2 2013/11/06 19:03:07 syl Exp $ */
+/* $OpenBSD: omgpio.c,v 1.3 2013/11/20 13:32:40 rapha Exp $ */
/*
* Copyright (c) 2007,2009 Dale Rahn <drahn@openbsd.org>
*
@@ -21,15 +21,22 @@
#include <sys/device.h>
#include <sys/malloc.h>
#include <sys/evcount.h>
+#include <sys/gpio.h>
#include <arm/cpufunc.h>
#include <machine/bus.h>
#include <machine/intr.h>
+#include <dev/gpio/gpiovar.h>
+
#include <armv7/armv7/armv7var.h>
+#include <armv7/omap/prcmvar.h>
+#include <armv7/omap/sitara_cm.h>
#include <armv7/omap/omgpiovar.h>
+#include "gpio.h"
+
/* OMAP3 registers */
#define GPIO3_REVISION 0x00
#define GPIO3_SYSCONFIG 0x10
@@ -57,7 +64,6 @@
#define GPIO3_SETWKUENA 0x84
#define GPIO3_CLEARDATAOUT 0x90
#define GPIO3_SETDATAOUT 0x94
-#define GPIO3_SIZE 0x100
/* OMAP4 registers */
#define GPIO4_REVISION 0x00
@@ -73,11 +79,7 @@
#define GPIO4_IRQWAKEN_0 0x44
#define GPIO4_IRQWAKEN_1 0x48
#define GPIO4_SYSSTATUS 0x114
-#define GPIO4_IRQSTATUS1 0x118
-#define GPIO4_IRQENABLE1 0x11C
#define GPIO4_WAKEUPENABLE 0x120
-#define GPIO4_IRQSTATUS2 0x128
-#define GPIO4_IRQENABLE2 0x12C
#define GPIO4_CTRL 0x130
#define GPIO4_OE 0x134
#define GPIO4_DATAIN 0x138
@@ -88,15 +90,38 @@
#define GPIO4_FALLINGDETECT 0x14C
#define GPIO4_DEBOUNCENABLE 0x150
#define GPIO4_DEBOUNCINGTIME 0x154
-#define GPIO4_CLEARIRQENABLE1 0x160
-#define GPIO4_SETIRQENABLE1 0x164
-#define GPIO4_CLEARIRQENABLE2 0x170
-#define GPIO4_SETIRQENABLE2 0x174
#define GPIO4_CLEARWKUPENA 0x180
#define GPIO4_SETWKUENA 0x184
#define GPIO4_CLEARDATAOUT 0x190
#define GPIO4_SETDATAOUT 0x194
+/* AM335X registers */
+#define GPIO_AM335X_REVISION 0x00
+#define GPIO_AM335X_SYSCONFIG 0x10
+#define GPIO_AM335X_IRQSTATUS_RAW_0 0x24
+#define GPIO_AM335X_IRQSTATUS_RAW_1 0x28
+#define GPIO_AM335X_IRQSTATUS_0 0x2C
+#define GPIO_AM335X_IRQSTATUS_1 0x30
+#define GPIO_AM335X_IRQSTATUS_SET_0 0x34
+#define GPIO_AM335X_IRQSTATUS_SET_1 0x38
+#define GPIO_AM335X_IRQSTATUS_CLR_0 0x3c
+#define GPIO_AM335X_IRQSTATUS_CLR_1 0x40
+#define GPIO_AM335X_IRQWAKEN_0 0x44
+#define GPIO_AM335X_IRQWAKEN_1 0x48
+#define GPIO_AM335X_SYSSTATUS 0x114
+#define GPIO_AM335X_CTRL 0x130
+#define GPIO_AM335X_OE 0x134
+#define GPIO_AM335X_DATAIN 0x138
+#define GPIO_AM335X_DATAOUT 0x13C
+#define GPIO_AM335X_LEVELDETECT0 0x140
+#define GPIO_AM335X_LEVELDETECT1 0x144
+#define GPIO_AM335X_RISINGDETECT 0x148
+#define GPIO_AM335X_FALLINGDETECT 0x14C
+#define GPIO_AM335X_DEBOUNCENABLE 0x150
+#define GPIO_AM335X_DEBOUNCINGTIME 0x154
+#define GPIO_AM335X_CLEARDATAOUT 0x190
+#define GPIO_AM335X_SETDATAOUT 0x194
+
#define GPIO_NUM_PINS 32
struct intrhand {
@@ -109,6 +134,37 @@ struct intrhand {
char *ih_name;
};
+struct omgpio_regs {
+ u_int32_t revision;
+ u_int32_t sysconfig;
+ u_int32_t irqstatus_raw0; /* omap4/am335x only */
+ u_int32_t irqstatus_raw1; /* omap4/am335x only */
+ u_int32_t irqstatus0;
+ u_int32_t irqstatus1;
+ u_int32_t irqstatus_set0;
+ u_int32_t irqstatus_set1;
+ u_int32_t irqstatus_clear0;
+ u_int32_t irqstatus_clear1;
+ u_int32_t irqwaken0;
+ u_int32_t irqwaken1;
+ u_int32_t sysstatus;
+ u_int32_t wakeupenable; /* omap3/omap4 only */
+ u_int32_t ctrl;
+ u_int32_t oe;
+ u_int32_t datain;
+ u_int32_t dataout;
+ u_int32_t leveldetect0;
+ u_int32_t leveldetect1;
+ u_int32_t risingdetect;
+ u_int32_t fallingdetect;
+ u_int32_t debounceenable;
+ u_int32_t debouncingtime;
+ u_int32_t clearwkupena; /* omap3/omap4 only */
+ u_int32_t setwkupena; /* omap3/omap4 only */
+ u_int32_t cleardataout;
+ u_int32_t setdataout;
+};
+
struct omgpio_softc {
struct device sc_dev;
bus_space_tag_t sc_iot;
@@ -120,35 +176,26 @@ struct omgpio_softc {
int sc_irq;
struct intrhand *sc_handlers[GPIO_NUM_PINS];
int sc_omap_ver;
- unsigned int (*sc_get_bit)(struct omgpio_softc *sc,
- unsigned int gpio);
- void (*sc_set_bit)(struct omgpio_softc *sc,
- unsigned int gpio);
- void (*sc_clear_bit)(struct omgpio_softc *sc,
- unsigned int gpio);
- void (*sc_set_dir)(struct omgpio_softc *sc,
- unsigned int gpio, unsigned int dir);
+ struct gpio_chipset_tag sc_gpio_gc;
+ gpio_pin_t sc_gpio_pins[GPIO_NUM_PINS];
+ struct omgpio_regs sc_regs;
};
#define GPIO_PIN_TO_INST(x) ((x) >> 5)
#define GPIO_PIN_TO_OFFSET(x) ((x) & 0x1f)
-
-int omgpio_match(struct device *parent, void *v, void *aux);
-void omgpio_attach(struct device *parent, struct device *self, void *args);
-void omgpio_recalc_interrupts(struct omgpio_softc *sc);
+#define DEVNAME(sc) ((sc)->sc_dev.dv_xname)
+#define READ4(sc, reg) omgpio_read4(sc, reg)
+#define WRITE4(sc, reg, val) omgpio_write4(sc, reg, val)
+
+u_int32_t omgpio_read4(struct omgpio_softc *, u_int32_t);
+void omgpio_write4(struct omgpio_softc *, u_int32_t, u_int32_t);
+int omgpio_match(struct device *, void *, void *);
+void omgpio_attach(struct device *, struct device *, void *);
+void omgpio_recalc_interrupts(struct omgpio_softc *);
int omgpio_irq(void *);
int omgpio_irq_dummy(void *);
-
-unsigned int omgpio_v3_get_bit(struct omgpio_softc *, unsigned int);
-void omgpio_v3_set_bit(struct omgpio_softc *, unsigned int);
-void omgpio_v3_clear_bit(struct omgpio_softc *, unsigned int);
-void omgpio_v3_set_dir(struct omgpio_softc *, unsigned int , unsigned int);
-unsigned int omgpio_v4_get_bit(struct omgpio_softc *, unsigned int);
-void omgpio_v4_set_bit(struct omgpio_softc *, unsigned int);
-void omgpio_v4_clear_bit(struct omgpio_softc *, unsigned int);
-void omgpio_v4_set_dir(struct omgpio_softc *, unsigned int, unsigned int);
-unsigned int omgpio_v4_get_dir(struct omgpio_softc *, unsigned int);
-
+int omgpio_pin_dir_read(struct omgpio_softc *, unsigned int);
+void omgpio_pin_dir_write(struct omgpio_softc *, unsigned int, unsigned int);
struct cfattach omgpio_ca = {
sizeof (struct omgpio_softc), omgpio_match, omgpio_attach
@@ -158,13 +205,31 @@ struct cfdriver omgpio_cd = {
NULL, "omgpio", DV_DULL
};
+u_int32_t
+omgpio_read4(struct omgpio_softc *sc, u_int32_t reg)
+{
+ if(reg == -1)
+ panic("%s: Invalid register address", DEVNAME(sc));
+
+ return bus_space_read_4((sc)->sc_iot, (sc)->sc_ioh, (reg));
+}
+
+void
+omgpio_write4(struct omgpio_softc *sc, u_int32_t reg, u_int32_t val)
+{
+ if(reg == -1)
+ panic("%s: Invalid register address", DEVNAME(sc));
+
+ bus_space_write_4((sc)->sc_iot, (sc)->sc_ioh, (reg), (val));
+}
+
int
omgpio_match(struct device *parent, void *v, void *aux)
{
switch (board_id) {
case BOARD_ID_OMAP3_BEAGLE:
case BOARD_ID_OMAP3_OVERO:
- break; /* continue trying */
+ case BOARD_ID_AM335X_BEAGLEBONE:
case BOARD_ID_OMAP4_PANDA:
break; /* continue trying */
default:
@@ -178,49 +243,146 @@ omgpio_attach(struct device *parent, struct device *self, void *args)
{
struct armv7_attach_args *aa = args;
struct omgpio_softc *sc = (struct omgpio_softc *) self;
- u_int32_t rev;
+ struct gpiobus_attach_args gba;
+ u_int32_t rev;
+ int i;
+
+ prcm_enablemodule(PRCM_GPIO0 + aa->aa_dev->unit);
sc->sc_iot = aa->aa_iot;
if (bus_space_map(sc->sc_iot, aa->aa_dev->mem[0].addr,
aa->aa_dev->mem[0].size, 0, &sc->sc_ioh))
- panic("omgpio_attach: bus_space_map failed!");
-
+ panic("%s: bus_space_map failed!", DEVNAME(sc));
switch (board_id) {
case BOARD_ID_OMAP3_BEAGLE:
case BOARD_ID_OMAP3_OVERO:
- sc->sc_omap_ver = 3;
- sc->sc_get_bit = omgpio_v3_get_bit;
- sc->sc_set_bit = omgpio_v3_set_bit;
- sc->sc_clear_bit = omgpio_v3_clear_bit;
- sc->sc_set_dir = omgpio_v3_set_dir;
+ sc->sc_regs.revision = GPIO3_REVISION;
+ sc->sc_regs.sysconfig = GPIO3_SYSCONFIG;
+ sc->sc_regs.irqstatus_raw0 = -1;
+ sc->sc_regs.irqstatus_raw1 = -1;
+ sc->sc_regs.irqstatus0 = GPIO3_IRQSTATUS1;
+ sc->sc_regs.irqstatus1 = GPIO3_IRQSTATUS2;
+ sc->sc_regs.irqstatus_set0 = GPIO3_SETIRQENABLE1;
+ sc->sc_regs.irqstatus_set1 = GPIO3_SETIRQENABLE2;
+ sc->sc_regs.irqstatus_clear0 = GPIO3_CLEARIRQENABLE1;
+ sc->sc_regs.irqstatus_clear1 = GPIO3_CLEARIRQENABLE2;
+ sc->sc_regs.irqwaken0 = -1;
+ sc->sc_regs.irqwaken1 = -1;
+ sc->sc_regs.sysstatus = GPIO3_SYSSTATUS;
+ sc->sc_regs.wakeupenable = GPIO3_WAKEUPENABLE;
+ sc->sc_regs.ctrl = GPIO3_CTRL;
+ sc->sc_regs.oe = GPIO3_OE;
+ sc->sc_regs.datain = GPIO3_DATAIN;
+ sc->sc_regs.dataout = GPIO3_DATAOUT;
+ sc->sc_regs.leveldetect0 = GPIO3_LEVELDETECT0;
+ sc->sc_regs.leveldetect1 = GPIO3_LEVELDETECT1;
+ sc->sc_regs.risingdetect = GPIO3_RISINGDETECT;
+ sc->sc_regs.fallingdetect = GPIO3_FALLINGDETECT;
+ sc->sc_regs.debounceenable = GPIO3_DEBOUNCENABLE;
+ sc->sc_regs.debouncingtime = GPIO3_DEBOUNCINGTIME;
+ sc->sc_regs.clearwkupena = GPIO3_CLEARWKUENA;
+ sc->sc_regs.setwkupena = GPIO3_SETWKUENA;
+ sc->sc_regs.cleardataout = GPIO3_CLEARDATAOUT;
+ sc->sc_regs.setdataout = GPIO3_SETDATAOUT;
break;
case BOARD_ID_OMAP4_PANDA:
- sc->sc_omap_ver = 4;
- sc->sc_get_bit = omgpio_v4_get_bit;
- sc->sc_set_bit = omgpio_v4_set_bit;
- sc->sc_clear_bit = omgpio_v4_clear_bit;
- sc->sc_set_dir = omgpio_v4_set_dir;
+ sc->sc_regs.revision = GPIO4_REVISION;
+ sc->sc_regs.sysconfig = GPIO4_SYSCONFIG;
+ sc->sc_regs.irqstatus_raw0 = GPIO4_IRQSTATUS_RAW_0;
+ sc->sc_regs.irqstatus_raw1 = GPIO4_IRQSTATUS_RAW_1;
+ sc->sc_regs.irqstatus0 = GPIO4_IRQSTATUS_0;
+ sc->sc_regs.irqstatus1 = GPIO4_IRQSTATUS_1;
+ sc->sc_regs.irqstatus_set0 = GPIO4_IRQSTATUS_SET_0;
+ sc->sc_regs.irqstatus_set1 = GPIO4_IRQSTATUS_SET_1;
+ sc->sc_regs.irqstatus_clear0 = GPIO4_IRQSTATUS_CLR_0;
+ sc->sc_regs.irqstatus_clear1 = GPIO4_IRQSTATUS_CLR_1;
+ sc->sc_regs.irqwaken0 = GPIO4_IRQWAKEN_0;
+ sc->sc_regs.irqwaken1 = GPIO4_IRQWAKEN_1;
+ sc->sc_regs.sysstatus = GPIO4_SYSSTATUS;
+ sc->sc_regs.wakeupenable = GPIO4_WAKEUPENABLE;
+ sc->sc_regs.ctrl = GPIO4_CTRL;
+ sc->sc_regs.oe = GPIO4_OE;
+ sc->sc_regs.datain = GPIO4_DATAIN;
+ sc->sc_regs.dataout = GPIO4_DATAOUT;
+ sc->sc_regs.leveldetect0 = GPIO4_LEVELDETECT0;
+ sc->sc_regs.leveldetect1 = GPIO4_LEVELDETECT1;
+ sc->sc_regs.risingdetect = GPIO4_RISINGDETECT;
+ sc->sc_regs.fallingdetect = GPIO4_FALLINGDETECT;
+ sc->sc_regs.debounceenable = GPIO4_DEBOUNCENABLE;
+ sc->sc_regs.debouncingtime = GPIO4_DEBOUNCINGTIME;
+ sc->sc_regs.clearwkupena = GPIO4_CLEARWKUPENA;
+ sc->sc_regs.setwkupena = GPIO4_SETWKUENA;
+ sc->sc_regs.cleardataout = GPIO4_CLEARDATAOUT;
+ sc->sc_regs.setdataout = GPIO4_SETDATAOUT;
+ break;
+ case BOARD_ID_AM335X_BEAGLEBONE:
+ sc->sc_regs.revision = GPIO_AM335X_REVISION;
+ sc->sc_regs.sysconfig = GPIO_AM335X_SYSCONFIG;
+ sc->sc_regs.irqstatus_raw0 = GPIO_AM335X_IRQSTATUS_RAW_0;
+ sc->sc_regs.irqstatus_raw1 = GPIO_AM335X_IRQSTATUS_RAW_1;
+ sc->sc_regs.irqstatus0 = GPIO_AM335X_IRQSTATUS_0;
+ sc->sc_regs.irqstatus1 = GPIO_AM335X_IRQSTATUS_1;
+ sc->sc_regs.irqstatus_set0 = GPIO_AM335X_IRQSTATUS_SET_0;
+ sc->sc_regs.irqstatus_set1 = GPIO_AM335X_IRQSTATUS_SET_1;
+ sc->sc_regs.irqstatus_clear0 = GPIO_AM335X_IRQSTATUS_CLR_0;
+ sc->sc_regs.irqstatus_clear1 = GPIO_AM335X_IRQSTATUS_CLR_1;
+ sc->sc_regs.irqwaken0 = GPIO_AM335X_IRQWAKEN_0;
+ sc->sc_regs.irqwaken1 = GPIO_AM335X_IRQWAKEN_1;
+ sc->sc_regs.sysstatus = GPIO_AM335X_SYSSTATUS;
+ sc->sc_regs.wakeupenable = -1;
+ sc->sc_regs.ctrl = GPIO_AM335X_CTRL;
+ sc->sc_regs.oe = GPIO_AM335X_OE;
+ sc->sc_regs.datain = GPIO_AM335X_DATAIN;
+ sc->sc_regs.dataout = GPIO_AM335X_DATAOUT;
+ sc->sc_regs.leveldetect0 = GPIO_AM335X_LEVELDETECT0;
+ sc->sc_regs.leveldetect1 = GPIO_AM335X_LEVELDETECT1;
+ sc->sc_regs.risingdetect = GPIO_AM335X_RISINGDETECT;
+ sc->sc_regs.fallingdetect = GPIO_AM335X_FALLINGDETECT;
+ sc->sc_regs.debounceenable = GPIO_AM335X_DEBOUNCENABLE;
+ sc->sc_regs.debouncingtime = GPIO_AM335X_DEBOUNCINGTIME;
+ sc->sc_regs.clearwkupena = -1;
+ sc->sc_regs.setwkupena = -1;
+ sc->sc_regs.cleardataout = GPIO_AM335X_CLEARDATAOUT;
+ sc->sc_regs.setdataout = GPIO_AM335X_SETDATAOUT;
break;
}
- rev = bus_space_read_4(sc->sc_iot, sc->sc_ioh, GPIO3_REVISION);
+ rev = READ4(sc, sc->sc_regs.revision);
- printf(" omap%d rev %d.%d\n", sc->sc_omap_ver, rev >> 4 & 0xf,
- rev & 0xf);
+ printf(": rev %d.%d\n", rev >> 4 & 0xf, rev & 0xf);
sc->sc_irq = aa->aa_dev->irq[0];
- if (sc->sc_omap_ver == 3) {
- bus_space_write_4(sc->sc_iot, sc->sc_ioh,
- GPIO3_CLEARIRQENABLE1, ~0);
- } else if (sc->sc_omap_ver == 4) {
- /* XXX - nothing? */
- }
+ WRITE4(sc, sc->sc_regs.irqstatus_clear0, ~0);
+ WRITE4(sc, sc->sc_regs.irqstatus_clear1, ~0);
/* XXX - SYSCONFIG */
/* XXX - CTRL */
/* XXX - DEBOUNCE */
+
+ for (i = 0; i < GPIO_NUM_PINS; i++) {
+ sc->sc_gpio_pins[i].pin_num = i;
+ sc->sc_gpio_pins[i].pin_caps = GPIO_PIN_INPUT |
+ GPIO_PIN_OUTPUT | GPIO_PIN_PULLUP | GPIO_PIN_PULLDOWN;
+ sc->sc_gpio_pins[i].pin_state = omgpio_pin_read(sc, i) ?
+ GPIO_PIN_HIGH : GPIO_PIN_LOW;
+ sc->sc_gpio_pins[i].pin_flags = GPIO_PIN_SET;
+ }
+
+ sc->sc_gpio_gc.gp_cookie = sc;
+ sc->sc_gpio_gc.gp_pin_read = omgpio_pin_read;
+ sc->sc_gpio_gc.gp_pin_write = omgpio_pin_write;
+ sc->sc_gpio_gc.gp_pin_ctl = omgpio_pin_ctl;
+
+ gba.gba_name = "gpio";
+ gba.gba_gc = &sc->sc_gpio_gc;
+ gba.gba_pins = sc->sc_gpio_pins;
+ gba.gba_npins = GPIO_NUM_PINS;
+
+#if NGPIO > 0
+ config_found(&sc->sc_dev, &gba, gpiobus_print);
+#endif
}
/* XXX - This assumes MCU INTERRUPTS are IRQ1, and DSP are IRQ2 */
@@ -239,16 +401,12 @@ omgpio_set_function(unsigned int gpio, unsigned int fn)
}
#endif
-/*
- * get_bit() is not reliable if used on an output pin.
- */
-
unsigned int
omgpio_get_bit(unsigned int gpio)
{
struct omgpio_softc *sc = omgpio_cd.cd_devs[GPIO_PIN_TO_INST(gpio)];
- return sc->sc_get_bit(sc, gpio);
+ return omgpio_pin_read(sc, GPIO_PIN_TO_OFFSET(gpio));
}
void
@@ -256,7 +414,7 @@ omgpio_set_bit(unsigned int gpio)
{
struct omgpio_softc *sc = omgpio_cd.cd_devs[GPIO_PIN_TO_INST(gpio)];
- sc->sc_set_bit(sc, gpio);
+ omgpio_pin_write(sc, GPIO_PIN_TO_OFFSET(gpio), GPIO_PIN_HIGH);
}
void
@@ -264,119 +422,85 @@ omgpio_clear_bit(unsigned int gpio)
{
struct omgpio_softc *sc = omgpio_cd.cd_devs[GPIO_PIN_TO_INST(gpio)];
- sc->sc_clear_bit(sc, gpio);
+ omgpio_pin_write(sc, GPIO_PIN_TO_OFFSET(gpio), GPIO_PIN_LOW);
}
+
void
omgpio_set_dir(unsigned int gpio, unsigned int dir)
{
struct omgpio_softc *sc = omgpio_cd.cd_devs[GPIO_PIN_TO_INST(gpio)];
- sc->sc_set_dir(sc, gpio, dir);
+ omgpio_pin_dir_write(sc, GPIO_PIN_TO_OFFSET(gpio), dir);
}
-unsigned int
-omgpio_v3_get_bit(struct omgpio_softc *sc, unsigned int gpio)
-{
- u_int32_t reg;
-
- reg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, GPIO3_DATAIN);
- return (reg >> GPIO_PIN_TO_OFFSET(gpio)) & 0x1;
-}
-
-void
-omgpio_v3_set_bit(struct omgpio_softc *sc, unsigned int gpio)
-{
- bus_space_write_4(sc->sc_iot, sc->sc_ioh, GPIO3_SETDATAOUT,
- 1 << GPIO_PIN_TO_OFFSET(gpio));
-}
-
-void
-omgpio_v3_clear_bit(struct omgpio_softc *sc, unsigned int gpio)
-{
- bus_space_write_4(sc->sc_iot, sc->sc_ioh, GPIO3_CLEARDATAOUT,
- 1 << GPIO_PIN_TO_OFFSET(gpio));
-}
-
-void
-omgpio_v3_set_dir(struct omgpio_softc *sc, unsigned int gpio, unsigned int dir)
+int
+omgpio_pin_read(void *arg, int pin)
{
- int s;
+ struct omgpio_softc *sc = arg;
u_int32_t reg;
- s = splhigh();
-
- reg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, GPIO3_DATAIN);
- if (dir == OMGPIO_DIR_IN)
- reg |= 1 << GPIO_PIN_TO_OFFSET(gpio);
+ if(omgpio_pin_dir_read(sc, pin) == OMGPIO_DIR_IN)
+ reg = READ4(sc, sc->sc_regs.datain);
else
- reg &= ~(1 << GPIO_PIN_TO_OFFSET(gpio));
- bus_space_write_4(sc->sc_iot, sc->sc_ioh, GPIO3_OE, reg);
-
- splx(s);
+ reg = READ4(sc, sc->sc_regs.dataout);
+ return (reg >> GPIO_PIN_TO_OFFSET(pin)) & 0x1;
}
-unsigned int
-omgpio_v4_get_bit(struct omgpio_softc *sc, unsigned int gpio)
+void
+omgpio_pin_write(void *arg, int pin, int value)
{
- u_int32_t reg;
+ struct omgpio_softc *sc = arg;
- if(omgpio_v4_get_dir(sc, gpio) == OMGPIO_DIR_IN)
- reg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, GPIO4_DATAIN);
+ if (value)
+ WRITE4(sc, sc->sc_regs.setdataout,
+ 1 << GPIO_PIN_TO_OFFSET(pin));
else
- reg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, GPIO4_DATAOUT);
- return (reg >> GPIO_PIN_TO_OFFSET(gpio)) & 0x1;
+ WRITE4(sc, sc->sc_regs.cleardataout,
+ 1 << GPIO_PIN_TO_OFFSET(pin));
}
void
-omgpio_v4_set_bit(struct omgpio_softc *sc, unsigned int gpio)
+omgpio_pin_ctl(void *arg, int pin, int flags)
{
+ struct omgpio_softc *sc = arg;
- bus_space_write_4(sc->sc_iot, sc->sc_ioh, GPIO4_SETDATAOUT,
- 1 << GPIO_PIN_TO_OFFSET(gpio));
-}
+ if (flags & GPIO_PIN_INPUT)
+ omgpio_pin_dir_write(sc, pin, OMGPIO_DIR_IN);
+ else if (flags & GPIO_PIN_OUTPUT)
+ omgpio_pin_dir_write(sc, pin, OMGPIO_DIR_OUT);
-void
-omgpio_v4_clear_bit(struct omgpio_softc *sc, unsigned int gpio)
-{
- bus_space_write_4(sc->sc_iot, sc->sc_ioh, GPIO4_CLEARDATAOUT,
- 1 << GPIO_PIN_TO_OFFSET(gpio));
+ if (board_id == BOARD_ID_AM335X_BEAGLEBONE)
+ sitara_cm_padconf_set_gpioflags(pin, flags);
}
void
-omgpio_v4_set_dir(struct omgpio_softc *sc, unsigned int gpio, unsigned int dir)
+omgpio_pin_dir_write(struct omgpio_softc *sc, unsigned int gpio,
+ unsigned int dir)
{
int s;
u_int32_t reg;
s = splhigh();
- reg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, GPIO4_OE);
+ reg = READ4(sc, sc->sc_regs.oe);
if (dir == OMGPIO_DIR_IN)
reg |= 1 << GPIO_PIN_TO_OFFSET(gpio);
else
reg &= ~(1 << GPIO_PIN_TO_OFFSET(gpio));
- bus_space_write_4(sc->sc_iot, sc->sc_ioh, GPIO4_OE, reg);
+ WRITE4(sc, sc->sc_regs.oe, reg);
splx(s);
}
-unsigned int
-omgpio_v4_get_dir(struct omgpio_softc *sc, unsigned int gpio)
+int
+omgpio_pin_dir_read(struct omgpio_softc *sc, unsigned int gpio)
{
- int s;
- u_int32_t dir, reg;
-
- s = splhigh();
-
- reg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, GPIO4_OE);
+ u_int32_t reg;
+ reg = READ4(sc, sc->sc_regs.oe);
if (reg & (1 << GPIO_PIN_TO_OFFSET(gpio)))
- dir = OMGPIO_DIR_IN;
+ return OMGPIO_DIR_IN;
else
- dir = OMGPIO_DIR_OUT;
-
- splx(s);
-
- return dir;
+ return OMGPIO_DIR_OUT;
}
#if 0
@@ -385,8 +509,7 @@ omgpio_clear_intr(struct omgpio_softc *sc, unsigned int gpio)
{
struct omgpio_softc *sc = omgpio_cd.cd_devs[GPIO_PIN_TO_INST(gpio)];
- bus_space_write_4(sc->sc_iot, sc->sc_ioh, GPIO3_IRQSTATUS1,
- 1 << GPIO_PIN_TO_OFFSET(gpio));
+ WRITE4(sc, sc->sc_regs.irqstatus0, 1 << GPIO_PIN_TO_OFFSET(gpio));
}
void
@@ -394,8 +517,7 @@ omgpio_intr_mask(struct omgpio_softc *sc, unsigned int gpio)
{
struct omgpio_softc *sc = omgpio_cd.cd_devs[GPIO_PIN_TO_INST(gpio)];
- bus_space_write_4(sc->sc_iot, sc->sc_ioh, GPIO3_CLEARIRQENABLE1,
- 1 << GPIO_PIN_TO_OFFSET(gpio));
+ WRITE4(sc, sc->sc_regs.irqstatus_clear0, 1 << GPIO_PIN_TO_OFFSET(gpio));
}
void
@@ -403,8 +525,7 @@ omgpio_intr_unmask(struct omgpio_softc *sc, unsigned int gpio)
{
struct omgpio_softc *sc = omgpio_cd.cd_devs[GPIO_PIN_TO_INST(gpio)];
- bus_space_write_4(sc->sc_iot, sc->sc_ioh, GPIO3_SETIRQENABLE1,
- 1 << GPIO_PIN_TO_OFFSET(gpio));
+ WRITE4(sc, sc->sc_regs.irqstatus_set0, 1 << GPIO_PIN_TO_OFFSET(gpio));
}
void
@@ -416,10 +537,10 @@ omgpio_intr_level(struct omgpio_softc *sc, unsigned int gpio, unsigned int level
s = splhigh();
- fe = bus_space_read_4(sc->sc_iot, sc->sc_ioh, GPIO3_FALLINGDETECT);
- re = bus_space_read_4(sc->sc_iot, sc->sc_ioh, GPIO3_RISINGDETECT);
- l0 = bus_space_read_4(sc->sc_iot, sc->sc_ioh, GPIO3_LEVELDETECT0);
- l1 = bus_space_read_4(sc->sc_iot, sc->sc_ioh, GPIO3_LEVELDETECT1);
+ fe = READ4(sc, sc->sc_regs.fallingdetect);
+ re = READ4(sc, sc->sc_regs.risingdetect);
+ l0 = READ4(sc, sc->sc_regs.leveldetect0);
+ l1 = READ4(sc, sc->sc_regs.leveldetect1);
bit = 1 << GPIO_PIN_TO_OFFSET(gpio);
@@ -467,10 +588,10 @@ omgpio_intr_level(struct omgpio_softc *sc, unsigned int gpio, unsigned int level
break;
}
- bus_space_write_4(sc->sc_iot, sc->sc_ioh, GPIO3_FALLINGDETECT, fe);
- bus_space_write_4(sc->sc_iot, sc->sc_ioh, GPIO3_RISINGDETECT, re);
- bus_space_write_4(sc->sc_iot, sc->sc_ioh, GPIO3_LEVELDETECT0, l0);
- bus_space_write_4(sc->sc_iot, sc->sc_ioh, GPIO3_LEVELDETECT1, l1);
+ WRITE4(sc, sc->sc_regs.fallingdetect, fe);
+ WRITE4(sc, sc->sc_regs.risingdetect, re);
+ WRITE4(sc, sc->sc_regs.leveldetect0, l0);
+ WRITE4(sc, sc->sc_regs.leveldetect1, l1);
splx(s);
}
@@ -560,7 +681,7 @@ omgpio_irq(void *v)
struct intrhand *ih;
int bit;
- pending = bus_space_read_4(sc->sc_iot, sc->sc_ioh, GPIO3_IRQSTATUS1);
+ pending = READ4(sc, omgpio.irqstatus0);
while (pending != 0) {
bit = ffs(pending) - 1;
@@ -573,7 +694,7 @@ omgpio_irq(void *v)
} else {
panic("omgpio: irq fired no handler, gpio %x %x %x",
sc->sc_dev.dv_unit * 32 + bit, pending,
- bus_space_read_4(sc->sc_iot, sc->sc_ioh, GPIO3_IRQENABLE1)
+ READ4(sc, omgpio.irqstatus0)
);
}
diff --git a/sys/arch/armv7/omap/omgpiovar.h b/sys/arch/armv7/omap/omgpiovar.h
index 1a47dd948a9..1c69f1b9841 100644
--- a/sys/arch/armv7/omap/omgpiovar.h
+++ b/sys/arch/armv7/omap/omgpiovar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: omgpiovar.h,v 1.1 2013/09/04 14:38:31 patrick Exp $ */
+/* $OpenBSD: omgpiovar.h,v 1.2 2013/11/20 13:32:40 rapha Exp $ */
/*
* Copyright (c) 2007,2009 Dale Rahn <drahn@openbsd.org>
*
@@ -28,6 +28,10 @@ void omgpio_set_bit(unsigned int gpio);
void omgpio_clear_bit(unsigned int gpio);
void omgpio_set_dir(unsigned int gpio, unsigned int dir);
+int omgpio_pin_read(void *arg, int pin);
+void omgpio_pin_write(void *arg, int pin, int value);
+void omgpio_pin_ctl(void *arg, int pin, int flags);
+
/* interrupts */
void omgpio_clear_intr(unsigned int gpio);
void omgpio_intr_mask(unsigned int gpio);