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>