Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 24 Jul 2011 22:47:08 GMT
From:      Jakub Wojciech Klama <jceel@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 196654 for review
Message-ID:  <201107242247.p6OMl8aX061218@skunkworks.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://p4web.freebsd.org/@@196654?ac=10

Change 196654 by jceel@jceel_cyclone on 2011/07/24 22:46:36

	Update GPIO driver, now complete and working stable.

Affected files ...

.. //depot/projects/soc2011/jceel_lpc/sys/arm/lpc/lpc_gpio.c#3 edit
.. //depot/projects/soc2011/jceel_lpc/sys/arm/lpc/lpcreg.h#5 edit
.. //depot/projects/soc2011/jceel_lpc/sys/arm/lpc/lpcvar.h#3 edit

Differences ...

==== //depot/projects/soc2011/jceel_lpc/sys/arm/lpc/lpc_gpio.c#3 (text+ko) ====

@@ -24,6 +24,31 @@
  * SUCH DAMAGE.
  *
  */
+
+/*
+ * GPIO on LPC32x0 consist of 4 ports:
+ * - Port0 with 8 input/output pins
+ * - Port1 with 24 input/output pins
+ * - Port2 with 13 input/output pins
+ * - Port3 with:
+ *   - 26 input pins (GPI_00..GPI_09 + GPI_15..GPI_23 + GPI_25 + GPI_27..GPI_28)
+ *   - 24 output pins (GPO_00..GPO_23)
+ *   - 6 input/ouput pins (GPIO_00..GPIO_05)
+ *
+ * Pins are mapped to logical pin number as follows:
+ * [0..9] -> GPI_00..GPI_09 		(port 3)
+ * [10..18] -> GPI_15..GPI_23 		(port 3)
+ * [19] -> GPI_25			(port 3)
+ * [20..21] -> GPI_27..GPI_28		(port 3)
+ * [22..45] -> GPO_00..GPO_23		(port 3)
+ * [46..51] -> GPIO_00..GPIO_05		(port 3)
+ * [52..64] -> P2.0..P2.12		(port 2)
+ * [65..88] -> P1.0..P1.23		(port 1)
+ * [89..96] -> P0.0..P0.7		(port 0)
+ *
+ */
+
+
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
@@ -70,7 +95,41 @@
 	bus_space_handle_t	lg_bsh;
 };
 
-#define	LPC_GPIO_NPINS		(32 * 2)
+struct lpc_gpio_pinmap
+{
+	int			lp_start_idx;
+	int			lp_pin_count;
+	int			lp_port;
+	int			lp_start_bit;
+	int			lp_flags;
+};
+
+static const struct lpc_gpio_pinmap lpc_gpio_pins[] = {
+	{ 0,	10,	3,	0,	GPIO_PIN_INPUT },
+	{ 10,	9,	3,	15,	GPIO_PIN_INPUT },
+	{ 19,	1,	3,	25,	GPIO_PIN_INPUT },
+	{ 20,	2,	3,	27,	GPIO_PIN_INPUT },
+	{ 22,	24,	3,	0,	GPIO_PIN_OUTPUT },
+	/*
+	 * -1 below is to mark special case for Port3 GPIO pins, as they
+	 * have other bits in Port 3 registers as inputs and as outputs
+	 */
+	{ 46,	6,	3,	-1,	GPIO_PIN_INPUT | GPIO_PIN_OUTPUT },
+	{ 52,	13,	2,	0,	GPIO_PIN_INPUT | GPIO_PIN_OUTPUT },
+	{ 65,	24,	1,	0,	GPIO_PIN_INPUT | GPIO_PIN_OUTPUT },
+	{ 89,	8,	0,	0,	GPIO_PIN_INPUT | GPIO_PIN_OUTPUT },
+	{ -1,	-1,	-1,	-1,	-1 },
+};
+
+#define	LPC_GPIO_NPINS				\
+    (LPC_GPIO_P0_COUNT + LPC_GPIO_P1_COUNT +	\
+    LPC_GPIO_P2_COUNT + LPC_GPIO_P3_COUNT)
+
+#define	LPC_GPIO_PIN_IDX(_map, _idx)	\
+    (_idx - _map->lp_start_idx)
+
+#define	LPC_GPIO_PIN_BIT(_map, _idx)	\
+    (_map->lp_start_bit + LPC_GPIO_PIN_IDX(_map, _idx))
 
 static int lpc_gpio_probe(device_t);
 static int lpc_gpio_attach(device_t);
@@ -85,10 +144,18 @@
 static int lpc_gpio_pin_set(device_t, uint32_t, uint32_t);
 static int lpc_gpio_pin_toggle(device_t, uint32_t);
 
-#define	lpc_gpio_read_4(_sc, _reg)		\
+static const struct lpc_gpio_pinmap *lpc_gpio_get_pinmap(int);
+
+static struct lpc_gpio_softc *lpc_gpio_sc = NULL;
+
+#define	lpc_gpio_read_4(_sc, _reg) \
     bus_space_read_4(_sc->lg_bst, _sc->lg_bsh, _reg)
-#define	lpc_gpio_write_4(_sc, _reg, _val)	\
+#define	lpc_gpio_write_4(_sc, _reg, _val) \
     bus_space_write_4(_sc->lg_bst, _sc->lg_bsh, _reg, _val)
+#define	lpc_gpio_get_4(_sc, _test, _reg1, _reg2) \
+    lpc_gpio_read_4(_sc, ((_test) ? _reg1 : _reg2))
+#define	lpc_gpio_set_4(_sc, _test, _reg1, _reg2, _val) \
+    lpc_gpio_write_4(_sc, ((_test) ? _reg1 : _reg2), _val)
 
 static int
 lpc_gpio_probe(device_t dev)
@@ -96,6 +163,7 @@
 	if (!ofw_bus_is_compatible(dev, "lpc,gpio"))
 		return (ENXIO);
 
+	device_set_desc(dev, "LPC32x0 GPIO");
 	return (BUS_PROBE_DEFAULT);
 }
 
@@ -118,6 +186,8 @@
 	sc->lg_bst = rman_get_bustag(sc->lg_res);
 	sc->lg_bsh = rman_get_bushandle(sc->lg_res);
 
+	lpc_gpio_sc = sc;
+
 	device_add_child(dev, "gpioc", device_get_unit(dev));
 	device_add_child(dev, "gpiobus", device_get_unit(dev));
 
@@ -134,18 +204,21 @@
 static int
 lpc_gpio_pin_max(device_t dev, int *npins)
 {
-	/* Currently supports only P0 and P1 */
-	*npins = LPC_GPIO_NPINS;
+	*npins = LPC_GPIO_NPINS - 1;
 	return (0);
 }
 
 static int
 lpc_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps)
 {
+	const struct lpc_gpio_pinmap *map;
+
 	if (pin > LPC_GPIO_NPINS)
 		return (ENODEV);
 
-	*caps = GPIO_PIN_INPUT | GPIO_PIN_OUTPUT;
+	map = lpc_gpio_get_pinmap(pin);
+
+	*caps = map->lp_flags;
 	return (0);
 }
 
@@ -153,19 +226,44 @@
 lpc_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags)
 {
 	struct lpc_gpio_softc *sc = device_get_softc(dev);
-	uint32_t direction;
+	const struct lpc_gpio_pinmap *map;
+	uint32_t state;
+	int dir;
+
+	if (pin > LPC_GPIO_NPINS)
+		return (ENODEV);
+
+	map = lpc_gpio_get_pinmap(pin);
+
+	/* Check whether it's bidirectional pin */
+	if ((map->lp_flags & (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT)) != 
+	    (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT)) {
+		*flags = map->lp_flags;
+		return (0);
+	}
 
-	if (pin >= 32) {
-		pin -= 32;
-		direction = lpc_gpio_read_4(sc, LPC_GPIO_P1_DIR_STATE);
-	} else {
-		direction = lpc_gpio_read_4(sc, LPC_GPIO_P1_DIR_STATE);
+	switch (map->lp_port) {
+	case 0:
+		state = lpc_gpio_read_4(sc, LPC_GPIO_P0_DIR_STATE);
+		dir = (state & (1 << LPC_GPIO_PIN_BIT(map, pin)));
+		break;
+	case 1:
+		state = lpc_gpio_read_4(sc, LPC_GPIO_P1_DIR_STATE);
+		dir = (state & (1 << LPC_GPIO_PIN_BIT(map, pin)));
+		break;
+	case 2:
+		state = lpc_gpio_read_4(sc, LPC_GPIO_P2_DIR_STATE);
+		dir = (state & (1 << LPC_GPIO_PIN_BIT(map, pin)));
+		break;
+	case 3:
+		state = lpc_gpio_read_4(sc, LPC_GPIO_P2_DIR_STATE);
+		dir = (state & (1 << (25 + LPC_GPIO_PIN_IDX(map, pin))));
+		break;
+	default:
+		panic("unknown GPIO port");
 	}
 
-	if (direction & (1 << pin))
-		*flags = GPIO_PIN_OUTPUT;
-	else
-		*flags = GPIO_PIN_INPUT;
+	*flags = dir ? GPIO_PIN_OUTPUT : GPIO_PIN_INPUT;
 
 	return (0);
 }
@@ -174,31 +272,79 @@
 lpc_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags)
 {
 	struct lpc_gpio_softc *sc = device_get_softc(dev);
-	uint32_t direction, state;
+	const struct lpc_gpio_pinmap *map;
+	uint32_t dir, state;
+
+	if (pin > LPC_GPIO_NPINS)
+		return (ENODEV);
+
+	map = lpc_gpio_get_pinmap(pin);
 
+	/* Check whether it's bidirectional pin */
+	if ((map->lp_flags & (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT)) != 
+	    (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT))
+		return (ENOTSUP);
+	
 	if (flags & GPIO_PIN_INPUT)
-		direction = 0;
+		dir = 0;
 
 	if (flags & GPIO_PIN_OUTPUT)
-		direction = 1;
+		dir = 1;
 
-	if (pin >= 32) {
-		pin -= 32;
-		state = lpc_gpio_read_4(sc, LPC_GPIO_P1_DIR_STATE);
-		lpc_gpio_write_4(sc, LPC_GPIO_P1_DIR_SET, state | (direction << pin));
-	} else {
-		state = lpc_gpio_read_4(sc, LPC_GPIO_P1_DIR_STATE);
-		lpc_gpio_write_4(sc, LPC_GPIO_P1_DIR_SET, state | (direction << pin));
+	switch (map->lp_port) {
+	case 0:
+		state = (1 << LPC_GPIO_PIN_IDX(map, pin));
+		lpc_gpio_set_4(sc, dir, LPC_GPIO_P0_DIR_SET, 
+		    LPC_GPIO_P0_DIR_CLR, state);
+		break;
+	case 1:
+		state = (1 << LPC_GPIO_PIN_IDX(map, pin));
+		lpc_gpio_set_4(sc, dir, LPC_GPIO_P1_DIR_SET, 
+		    LPC_GPIO_P0_DIR_CLR, state);
+		break;
+	case 2:
+		state = (1 << LPC_GPIO_PIN_IDX(map, pin));
+		lpc_gpio_set_4(sc, dir, LPC_GPIO_P2_DIR_SET, 
+		    LPC_GPIO_P0_DIR_CLR, state);
+		break;
+	case 3:
+		state = (1 << (25 + (pin - map->lp_start_idx)));
+		lpc_gpio_set_4(sc, dir, LPC_GPIO_P2_DIR_SET, 
+		    LPC_GPIO_P0_DIR_CLR, state);
+		break;
+	}
 
-	}
-	
 	return (0);
 }
 
 static int
 lpc_gpio_pin_getname(device_t dev, uint32_t pin, char *name)
 {
-	snprintf(name, GPIOMAXNAME - 1, "pin%d", pin);
+	const struct lpc_gpio_pinmap *map;
+	int idx;
+
+	map = lpc_gpio_get_pinmap(pin);
+	idx = LPC_GPIO_PIN_IDX(map, pin);
+
+	switch (map->lp_port) {
+	case 0:
+	case 1:
+	case 2:
+		snprintf(name, GPIOMAXNAME - 1, "P%d.%d", map->lp_port, 
+		    map->lp_start_bit + LPC_GPIO_PIN_IDX(map, pin));
+		break;
+	case 3:
+		if (map->lp_start_bit == -1) {
+			snprintf(name, GPIOMAXNAME - 1, "GPIO_%02d", idx);
+			break;
+		}
+
+		snprintf(name, GPIOMAXNAME - 1, "GP%c_%02d",
+		    (map->lp_flags & GPIO_PIN_INPUT) ? 'I' : 'O',
+		    map->lp_start_bit + idx);
+		break;
+	}
+
 	return (0);
 }
 
@@ -206,15 +352,46 @@
 lpc_gpio_pin_get(device_t dev, uint32_t pin, uint32_t *value)
 {
 	struct lpc_gpio_softc *sc = device_get_softc(dev);
-	uint32_t state;
+	const struct lpc_gpio_pinmap *map;
+	uint32_t state, flags;
+	int dir;
+
+	map = lpc_gpio_get_pinmap(pin);
+
+	if (lpc_gpio_pin_getflags(dev, pin, &flags))
+		return (ENXIO);
+
+	if (flags & GPIO_PIN_OUTPUT)
+		dir = 1;
+
+	if (flags & GPIO_PIN_INPUT)
+		dir = 0;
+
+	switch (map->lp_port) {
+	case 0:
+		state = lpc_gpio_get_4(sc, dir, LPC_GPIO_P0_OUTP_STATE,
+		    LPC_GPIO_P0_INP_STATE);
+		*value = !!(state & (1 << LPC_GPIO_PIN_BIT(map, pin)));
+	case 1:
+		state = lpc_gpio_get_4(sc, dir, LPC_GPIO_P1_OUTP_STATE,
+		    LPC_GPIO_P1_INP_STATE);
+		*value = !!(state & (1 << LPC_GPIO_PIN_BIT(map, pin)));
+	case 2:
+		state = lpc_gpio_read_4(sc, LPC_GPIO_P2_INP_STATE);
+		*value = !!(state & (1 << LPC_GPIO_PIN_BIT(map, pin)));
+	case 3:
+		state = lpc_gpio_get_4(sc, dir, LPC_GPIO_P3_OUTP_STATE,
+		    LPC_GPIO_P3_INP_STATE);
+		if (map->lp_start_bit == -1) {
+			if (dir)
+				*value = !!(state & (1 << (25 + 
+				    LPC_GPIO_PIN_IDX(map, pin))));
+			else
+				*value = !!(state & (1 << (10 + 
+				    LPC_GPIO_PIN_IDX(map, pin))));
+		}
 
-	if (pin >= 32) {
-		pin -= 32;
-		state = lpc_gpio_read_4(sc, LPC_GPIO_P1_INP_STATE);
-		*value = (state & (1 << pin));
-	} else {
-		state = lpc_gpio_read_4(sc, LPC_GPIO_P0_INP_STATE);
-		*value = (state & (1 << pin));
+		*value = !!(state & (1 << LPC_GPIO_PIN_BIT(map, pin)));
 	}
 
 	return (0);
@@ -224,17 +401,39 @@
 lpc_gpio_pin_set(device_t dev, uint32_t pin, uint32_t value)
 {
 	struct lpc_gpio_softc *sc = device_get_softc(dev);
-	uint32_t state;
+	const struct lpc_gpio_pinmap *map;
+	uint32_t state, flags;
+
+	map = lpc_gpio_get_pinmap(pin);
+
+	if (lpc_gpio_pin_getflags(dev, pin, &flags))
+		return (ENXIO);
+
+	if ((flags & GPIO_PIN_OUTPUT) == 0)
+		return (EINVAL);
+
+	state = (1 << LPC_GPIO_PIN_BIT(map, pin));
 
-	if (pin >= 32) {
-		pin -= 32;
-		state = lpc_gpio_read_4(sc, LPC_GPIO_P1_OUTP_STATE);
-		state = value ? state | (1 << pin) : state & ~(1 << pin);
-		lpc_gpio_write_4(sc, LPC_GPIO_P1_OUTP_SET, state);
-	} else {
-		state = lpc_gpio_read_4(sc, LPC_GPIO_P0_OUTP_STATE);
-		state = value ? state | (1 << pin) : state & ~(1 << pin);
-		lpc_gpio_write_4(sc, LPC_GPIO_P0_OUTP_SET, state | (1 << pin));
+	switch (map->lp_port) {
+	case 0:
+		lpc_gpio_set_4(sc, value, LPC_GPIO_P0_OUTP_SET,
+		    LPC_GPIO_P0_OUTP_CLR, state);
+		break;
+	case 1:
+		lpc_gpio_set_4(sc, value, LPC_GPIO_P1_OUTP_SET,
+		    LPC_GPIO_P1_OUTP_CLR, state);
+		break;
+	case 2:
+		lpc_gpio_set_4(sc, value, LPC_GPIO_P2_OUTP_SET,
+		    LPC_GPIO_P2_OUTP_CLR, state);
+		break;
+	case 3:
+		if (map->lp_start_bit == -1)
+			state = (1 << (25 + LPC_GPIO_PIN_IDX(map, pin)));
+		
+		lpc_gpio_set_4(sc, value, LPC_GPIO_P3_OUTP_SET,
+		    LPC_GPIO_P3_OUTP_CLR, state);
+		break;
 	}
 
 	return (0);
@@ -243,22 +442,63 @@
 static int
 lpc_gpio_pin_toggle(device_t dev, uint32_t pin)
 {
-	struct lpc_gpio_softc *sc = device_get_softc(dev);
-	uint32_t state;
+	//struct lpc_gpio_softc *sc = device_get_softc(dev);
+	const struct lpc_gpio_pinmap *map;
+	uint32_t /*state,*/ flags;
+
+	map = lpc_gpio_get_pinmap(pin);
+
+	if (lpc_gpio_pin_getflags(dev, pin, &flags))
+		return (ENXIO);
+
+	if ((flags & GPIO_PIN_OUTPUT) == 0)
+		return (EINVAL);
+	
+	panic("not implemented yet");
+
+	return (0);
+
+}
+
+static const struct lpc_gpio_pinmap *
+lpc_gpio_get_pinmap(int pin)
+{
+	const struct lpc_gpio_pinmap *map;
 
-	if (pin >= 32) {
-		pin -= 32;
-		state = lpc_gpio_read_4(sc, LPC_GPIO_P1_OUTP_STATE);
-		state = (state & (1 << pin)) ? state & ~(1 << pin) : state | (1 << pin);
-		lpc_gpio_write_4(sc, LPC_GPIO_P1_OUTP_SET, state);
-	} else {
-		state = lpc_gpio_read_4(sc, LPC_GPIO_P0_OUTP_STATE);
-		state = (state & (1 << pin)) ? state & ~(1 << pin) : state | (1 << pin);
-		lpc_gpio_write_4(sc, LPC_GPIO_P0_OUTP_SET, state | (1 << pin));
+	for (map = &lpc_gpio_pins[0]; map->lp_start_idx != -1; map++) {
+		if (pin >= map->lp_start_idx &&
+		    pin < map->lp_start_idx + map->lp_pin_count)
+			return map;
 	}
 
-	return (0);
+	panic("pin number %d out of range", pin);
+}
+
+int
+lpc_gpio_set_flags(device_t dev, int pin, int flags)
+{
+	if (lpc_gpio_sc == NULL)
+		return (ENXIO);
+
+	return lpc_gpio_pin_setflags(lpc_gpio_sc->lg_dev, pin, flags);
+}
+
+int
+lpc_gpio_set_state(device_t dev, int pin, int state)
+{
+	if (lpc_gpio_sc == NULL)
+		return (ENXIO);
+
+	return lpc_gpio_pin_set(lpc_gpio_sc->lg_dev, pin, state); 
+}
+
+int
+lpc_gpio_get_state(device_t dev, int pin, int *state)
+{
+	if (lpc_gpio_sc == NULL)
+		return (ENXIO);
 
+	return lpc_gpio_pin_get(lpc_gpio_sc->lg_dev, pin, state);
 }
 
 static device_method_t lpc_gpio_methods[] = {

==== //depot/projects/soc2011/jceel_lpc/sys/arm/lpc/lpcreg.h#5 (text+ko) ====

@@ -27,72 +27,72 @@
 #ifndef	_ARM_LPC_LPCREG_H
 #define	_ARM_LPC_LPCREG_H
 
-#define	LPC_DEV_PHYS_BASE	0x40000000
-#define	LPC_DEV_BASE		0xd0000000
-#define	LPC_DEV_SIZE		0x10000000
+#define	LPC_DEV_PHYS_BASE		0x40000000
+#define	LPC_DEV_BASE			0xd0000000
+#define	LPC_DEV_SIZE			0x10000000
 
 /*
  * Interrupt controller (from UM10326: LPC32x0 User manual, page 87)
 
  */
-#define	LPC_INTC_MIC_ER		0x0000
-#define	LPC_INTC_MIC_RSR	0x0004
-#define	LPC_INTC_MIC_SR		0x0008
-#define	LPC_INTC_MIC_APR	0x000c
-#define	LPC_INTC_MIC_ATR	0x0010
-#define	LPC_INTC_MIC_ITR	0x0014
-#define	LPC_INTC_SIC1_ER	0x4000
-#define	LPC_INTC_SIC1_RSR	0x4004
-#define	LPC_INTC_SIC1_SR	0x4008
-#define	LPC_INTC_SIC1_APR	0x400c
-#define	LPC_INTC_SIC1_ATR	0x4010
-#define	LPC_INTC_SIC1_ITR	0x4014
-#define	LPC_INTC_SIC2_ER	0x8000
-#define	LPC_INTC_SIC2_RSR	0x8004
-#define	LPC_INTC_SIC2_SR	0x8008
-#define	LPC_INTC_SIC2_APR	0x800c
-#define	LPC_INTC_SIC2_ATR	0x8010
-#define	LPC_INTC_SIC2_ITR	0x8014
+#define	LPC_INTC_MIC_ER			0x0000
+#define	LPC_INTC_MIC_RSR		0x0004
+#define	LPC_INTC_MIC_SR			0x0008
+#define	LPC_INTC_MIC_APR		0x000c
+#define	LPC_INTC_MIC_ATR		0x0010
+#define	LPC_INTC_MIC_ITR		0x0014
+#define	LPC_INTC_SIC1_ER		0x4000
+#define	LPC_INTC_SIC1_RSR		0x4004
+#define	LPC_INTC_SIC1_SR		0x4008
+#define	LPC_INTC_SIC1_APR		0x400c
+#define	LPC_INTC_SIC1_ATR		0x4010
+#define	LPC_INTC_SIC1_ITR		0x4014
+#define	LPC_INTC_SIC2_ER		0x8000
+#define	LPC_INTC_SIC2_RSR		0x8004
+#define	LPC_INTC_SIC2_SR		0x8008
+#define	LPC_INTC_SIC2_APR		0x800c
+#define	LPC_INTC_SIC2_ATR		0x8010
+#define	LPC_INTC_SIC2_ITR		0x8014
 
 
 /*
  * Timer 0|1|2|3|4|5. (from UM10326: LPC32x0 User manual, page 540)
  */
-#define	LPC_TIMER_IR		0x00
-#define	LPC_TIMER_TCR		0x04
-#define	LPC_TIMER_TCR_ENABLE	(1 << 0)
-#define	LPC_TIMER_TCR_RESET	(1 << 1)
-#define	LPC_TIMER_TC		0x08
-#define	LPC_TIMER_PR		0x0c
-#define	LPC_TIMER_PC		0x10
-#define	LPC_TIMER_MCR		0x14
-#define	LPC_TIMER_MCR_MR0I	(1 << 0)
-#define	LPC_TIMER_MCR_MR0R	(1 << 1)
-#define	LPC_TIMER_MCR_MR0S	(1 << 2)
-#define	LPC_TIMER_MCR_MR1I	(1 << 3)
-#define	LPC_TIMER_MCR_MR1R	(1 << 4)
-#define	LPC_TIMER_MCR_MR1S	(1 << 5)
-#define	LPC_TIMER_MCR_MR2I	(1 << 6)
-#define	LPC_TIMER_MCR_MR2R	(1 << 7)
-#define	LPC_TIMER_MCR_MR2S	(1 << 8)
-#define	LPC_TIMER_MCR_MR3I	(1 << 9)
-#define	LPC_TIMER_MCR_MR3R	(1 << 10)
-#define	LPC_TIMER_MCR_MR3S	(1 << 11)
-#define	LPC_TIMER_MR0		0x18
-#define	LPC_TIMER_CTCR		0x70
+#define	LPC_TIMER_IR			0x00
+#define	LPC_TIMER_TCR			0x04
+#define	LPC_TIMER_TCR_ENABLE		(1 << 0)
+#define	LPC_TIMER_TCR_RESET		(1 << 1)
+#define	LPC_TIMER_TC			0x08
+#define	LPC_TIMER_PR			0x0c
+#define	LPC_TIMER_PC			0x10
+#define	LPC_TIMER_MCR			0x14
+#define	LPC_TIMER_MCR_MR0I		(1 << 0)
+#define	LPC_TIMER_MCR_MR0R		(1 << 1)
+#define	LPC_TIMER_MCR_MR0S		(1 << 2)
+#define	LPC_TIMER_MCR_MR1I		(1 << 3)
+#define	LPC_TIMER_MCR_MR1R		(1 << 4)
+#define	LPC_TIMER_MCR_MR1S		(1 << 5)
+#define	LPC_TIMER_MCR_MR2I		(1 << 6)
+#define	LPC_TIMER_MCR_MR2R		(1 << 7)
+#define	LPC_TIMER_MCR_MR2S		(1 << 8)
+#define	LPC_TIMER_MCR_MR3I		(1 << 9)
+#define	LPC_TIMER_MCR_MR3R		(1 << 10)
+#define	LPC_TIMER_MCR_MR3S		(1 << 11)
+#define	LPC_TIMER_MR0			0x18
+#define	LPC_TIMER_CTCR			0x70
 
 /*
  * Watchdog timer. (from UM10326: LPC32x0 User manual, page 572)
  */
-#define	LPC_WDTIM_BASE		(LPC_DEV_BASE + 0x3c000)
-#define	LPC_WDTIM_INT		0x00
-#define	LPC_WDTIM_CTRL		0x04
-#define	LPC_WDTIM_COUNTER	0x08
-#define	LPC_WDTIM_MCTRL		0x0c
-#define	LPC_WDTIM_MATCH0	0x10
-#define	LPC_WDTIM_EMR		0x14
-#define	LPC_WDTIM_PULSE		0x18
-#define	LPC_WDTIM_RES		0x1c
+#define	LPC_WDTIM_BASE			(LPC_DEV_BASE + 0x3c000)
+#define	LPC_WDTIM_INT			0x00
+#define	LPC_WDTIM_CTRL			0x04
+#define	LPC_WDTIM_COUNTER		0x08
+#define	LPC_WDTIM_MCTRL			0x0c
+#define	LPC_WDTIM_MATCH0		0x10
+#define	LPC_WDTIM_EMR			0x14
+#define	LPC_WDTIM_PULSE			0x18
+#define	LPC_WDTIM_RES			0x1c
 
 /*
  * Clocking and power control. (from UM10326: LPC32x0 User manual, page 58)
@@ -146,6 +146,12 @@
 #define	LPC_CLKPWR_LCDCLK_CTRL		0x54
 #define	LPC_CLKPWR_I2S_CTRL		0x7c
 #define	LPC_CLKPWR_SSP_CTRL		0x78
+#define	LPC_CLKPWR_SSP_CTRL_SSP1RXDMA	(1 << 5)
+#define	LPC_CLKPWR_SSP_CTRL_SSP1TXDMA	(1 << 4)
+#define	LPC_CLKPWR_SSP_CTRL_SSP0RXDMA	(1 << 3)
+#define	LPC_CLKPWR_SSP_CTRL_SSP0TXDMA	(1 << 2)
+#define	LPC_CLKPWR_SSP_CTRL_SSP1EN	(1 << 1)
+#define	LPC_CLKPWR_SSP_CTRL_SSP0EN	(1 << 0)
 #define	LPC_CLKPWR_SPI_CTRL		0xc4
 #define	LPC_CLKPWR_I2CCLK_CTRL		0xac
 #define	LPC_CLKPWR_TIMCLK_CTRL1		0xc0
@@ -371,8 +377,86 @@
 #define	LPC_LCD_CRSR_INTSTAT		0xc2c
 
 /*
+ * SPI interface (from UM10326: LPC32x0 User manual, page 483)
+ */
+#define	LPC_SPI_GLOBAL			0x00
+#define	LPC_SPI_GLOBAL_RST		(1 << 1)
+#define	LPC_SPI_GLOBAL_ENABLE		(1 << 0)
+#define	LPC_SPI_CON			0x04
+#define	LPC_SPI_CON_UNIDIR		(1 << 23)
+#define	LPC_SPI_CON_BHALT		(1 << 22)
+#define	LPC_SPI_CON_BPOL		(1 << 21)
+#define	LPC_SPI_CON_MSB			(1 << 19)
+#define	LPC_SPI_CON_MODE(_n)		((_n & 0x3) << 16)
+#define	LPC_SPI_CON_RXTX		(1 << 15)
+#define	LPC_SPI_CON_THR			(1 << 14)
+#define	LPC_SPI_CON_SHIFT_OFF		(1 << 13)
+#define	LPC_SPI_CON_BITNUM(_n)		((_n & 0xf) << 9)
+#define	LPC_SPI_CON_MS			(1 << 7)
+#define	LPC_SPI_CON_RATE(_n)		(_n & 0x7f)
+#define	LPC_SPI_FRM			0x08
+#define	LPC_SPI_IER			0x0c
+#define	LPC_SPI_IER_INTEOT		(1 << 1)
+#define	LPC_SPI_IER_INTTHR		(1 << 0)
+#define	LPC_SPI_STAT			0x10
+#define	LPC_SPI_STAT_INTCLR		(1 << 8)
+#define	LPC_SPI_STAT_EOT		(1 << 7)
+#define	LPC_SPI_STAT_BUSYLEV		(1 << 6)
+#define	LPC_SPI_STAT_SHIFTACT		(1 << 3)
+#define	LPC_SPI_STAT_BF			(1 << 2)
+#define	LPC_SPI_STAT_THR		(1 << 1)
+#define	LPC_SPI_STAT_BE			(1 << 0)
+#define	LPC_SPI_DAT			0x14
+#define	LPC_SPI_TIM_CTRL		0x400
+#define	LPC_SPI_TIM_COUNT		0x404
+#define	LPC_SPI_TIM_STAT		0x408
+
+/*
+ * SSP interface (from UM10326: LPC32x0 User manual, page 500)
+ */
+#define	LPC_SSP0_BASE			0x4c00
+#define	LPC_SSP1_BASE			0xc000
+#define	LPC_SSP_CR0			0x00
+#define	LPC_SSP_CR0_DSS(_n)		((_n-1) & 0xf)
+#define	LPC_SSP_CR0_TI			(1 << 4)
+#define	LPC_SSP_CR0_MICROWIRE		(1 << 5)
+#define	LPC_SSP_CR0_CPOL		(1 << 6)
+#define	LPC_SSP_CR0_CPHA		(1 << 7)
+#define	LPC_SSP_CR0_SCR(_n)		((_x & & 0xff) << 8)
+#define	LPC_SSP_CR1			0x04
+#define	LPC_SSP_CR1_LBM			(1 << 0)
+#define	LPC_SSP_CR1_SSE			(1 << 1)
+#define	LPC_SSP_CR1_MS			(1 << 2)
+#define	LPC_SSP_CR1_SOD			(1 << 3)
+#define	LPC_SSP_DR			0x08
+#define	LPC_SSP_SR			0x0c
+#define	LPC_SSP_SR_TFE			(1 << 0)
+#define	LPC_SSP_SR_TNF			(1 << 1)
+#define	LPC_SSP_SR_RNE			(1 << 2)
+#define	LPC_SSP_SR_RFF			(1 << 3)
+#define	LPC_SSP_SR_BSY			(1 << 4)
+#define	LPC_SSP_CPSR			0x10
+#define	LPC_SSP_IMSC			0x14
+#define	LPC_SSP_IMSC_RORIM		(1 << 0)
+#define	LPC_SSP_IMSC_RTIM		(1 << 1)
+#define	LPC_SSP_IMSC_RXIM		(1 << 2)
+#define	LPC_SSP_IMSC_TXIM		(1 << 3)
+#define	LPC_SSP_RIS			0x18
+#define	LPC_SSP_RIS_RORRIS		(1 << 0)
+#define	LPC_SSP_RIS_RTRIS		(1 << 1)
+#define	LPC_SSP_RIS_RXRIS		(1 << 2)
+#define	LPC_SSP_RIS_TXRIS		(1 << 3)
+#define	LPC_SSP_MIS			0x1c
+#define	LPC_SSP_ICR			0x20
+#define	LPC_SSP_DMACR			0x24
+
+/*
  * GPIO (from UM10326: LPC32x0 User manual, page 606)
  */
+#define	LPC_GPIO_P0_COUNT		8
+#define	LPC_GPIO_P1_COUNT		24
+#define	LPC_GPIO_P2_COUNT		13
+#define	LPC_GPIO_P3_COUNT		52
 #define	LPC_GPIO_P0_INP_STATE		0x40
 #define	LPC_GPIO_P0_OUTP_SET		0x44
 #define	LPC_GPIO_P0_OUTP_CLR		0x48
@@ -397,5 +481,55 @@
 #define	LPC_GPIO_P3_OUTP_SET		0x04
 #define	LPC_GPIO_P3_OUTP_CLR		0x08
 #define	LPC_GPIO_P3_OUTP_STATE		0x0c
+/* Aliases for logical pin numbers: */
+#define	LPC_GPIO_GPI_00(_n)		(0 + _n)
+#define	LPC_GPIO_GPI_15(_n)		(10 + _n)
+#define	LPC_GPIO_GPI_25			(19)
+#define	LPC_GPIO_GPI_27(_n)		(20 + _n)
+#define	LPC_GPIO_GPO_00(_n)		(22 + _n)
+#define	LPC_GPIO_GPIO_00(_n)		(46 + _n)
+
+/*
+ * GPDMA controller (from UM10326: LPC32x0 User manual, page 106)
+ */
+#define	LPC_DMAC_INTSTAT		0x00
+#define	LPC_DMAC_INTTCSTAT		0x04
+#define	LPC_DMAC_INTTCCLEAR		0x08
+#define	LPC_DMAC_INTERRSTAT		0x0c
+#define	LPC_DMAC_INTERRCLR		0x10
+#define	LPC_DMAC_RAWINTTCSTAT		0x14
+#define	LPC_DMAC_RAWINTERRSTAT		0x18
+#define	LPC_DMAC_ENABLED_CHANNELS	0x1c
+#define	LPC_DMAC_SOFTBREQ		0x20
+#define	LPC_DMAC_SOFTSREQ		0x24
+#define	LPC_DMAC_SOFTLBREQ		0x28
+#define	LPC_DMAC_SOFTLSREQ		0x2c
+#define	LPC_DMAC_CONFIG			0x30
+#define	LPC_DMAC_CHADDR(_n)		(0x100 + (_n * 0x20))
+#define	LPC_DMAC_CH_SRCADDR		0x00
+#define	LPC_DMAC_CH_DSTADDR		0x04
+#define	LPC_DMAC_CH_LLI			0x08
+#define	LPC_DMAC_CH_LLI_AHB1		(1 << 0)
+#define	LPC_DMAC_CH_CONTROL		0x0c
+#define	LPC_DMAC_CH_CONTROL_I		(1 << 31)
+#define	LPC_DMAC_CH_CONTROL_DI		(1 << 27)
+#define	LPC_DMAC_CH_CONTROL_SI		(1 << 26)
+#define	LPC_DMAC_CH_CONTROL_D		(1 << 25)
+#define	LPC_DMAC_CH_CONTROL_S		(1 << 24)
+#define	LPC_DMAC_CH_CONTROL_DWIDTH(_n)	((_n & 0x7) << 21)
+#define	LPC_DMAC_CH_CONTROL_SWIDTH(_n)	((_n & 0x7) << 18)
+#define	LPC_DMAC_CH_CONTROL_DBSIZE(_n)	((_n & 0x7) << 15)
+#define	LPC_DMAC_CH_CONTROL_SBSIZE(_n)	((_n & 0x7) << 12)
+#define	LPC_DMAC_CH_CONTROL_XFERLEN(_n)	(_n & 0xfff) 
+#define	LPC_DMAC_CH_CONFIG		0x10
+#define	LPC_DMAC_CH_CONFIG_H		(1 << 18)
+#define	LPC_DMAC_CH_CONFIG_A		(1 << 17)
+#define	LPC_DMAC_CH_CONFIG_L		(1 << 16)
+#define	LPC_DMAC_CH_CONFIG_ITC		(1 << 15)
+#define	LPC_DMAC_CH_CONFIG_IE		(1 << 14)
+#define	LPC_DMAC_CH_CONFIG_FLOWCNTL(_n)	((_n & 0x7) << 11)
+#define	LPC_DMAC_CH_CONFIG_DESTP(_n)	((_n & 0x1f) << 6)
+#define	LPC_DMAC_CH_CONFIG_SRCP(_n)	((_n & 0x1f) << 1)
+#define	LPC_DMAC_CH_CONFIG_E		(1 << 0)
 
 #endif	/* _ARM_LPC_LPCREG_H */

==== //depot/projects/soc2011/jceel_lpc/sys/arm/lpc/lpcvar.h#3 (text+ko) ====

@@ -31,7 +31,13 @@
 #include <sys/bus.h>
 #include <machine/bus.h>
 
+/* Clocking and power control */
 uint32_t lpc_pwr_read(device_t, int);
 void lpc_pwr_write(device_t, int, uint32_t);
 
+/* GPIO */
+int lpc_gpio_set_flags(device_t, int, int);
+int lpc_gpio_set_state(device_t, int, int);
+int lpc_gpio_get_state(device_t, int, int *);
+
 #endif	/* _ARM_LPC_LPCVAR_H */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201107242247.p6OMl8aX061218>