PERFORCE change 196654 for review
Jakub Wojciech Klama
jceel at FreeBSD.org
Sun Jul 24 22:47:10 UTC 2011
http://p4web.freebsd.org/@@196654?ac=10
Change 196654 by jceel at 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 */
More information about the p4-projects
mailing list