diff options
author | Bill Richardson <wfrichar@chromium.org> | 2016-04-15 15:52:26 -0700 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2016-04-15 21:29:25 -0700 |
commit | 9c2cbb6b5d958419d193ba22119c722208955911 (patch) | |
tree | dc199fbb10406b492154c32394cf404dd51e499a /chip | |
parent | 910312f8561ec3863f704305fb159a312bdf31e8 (diff) | |
download | chrome-ec-9c2cbb6b5d958419d193ba22119c722208955911.tar.gz |
Cr50: Add DIO_PULL_UP and DIO_PULL_DOWN flags
In board/*/gpio.inc, we can specify pullups and pulldowns on pads
connected to GPIOs, like so:
GPIO(SOME_BUTTON, PIN(0,0), GPIO_INPUT | GPIO_PULL_UP)
This adds flags to do the same thing for pads that connect to
internal periperals:
PINMUX(FUNC(UART0_RX), A1, DIO_PULL_UP)
BUG=chrome-os-partner:51410
BRANCH=none
TEST=make buildall; manual test on Cr50
I added these flags to the gpio.inc file and tested the result:
PINMUX(FUNC(I2C0_SCL), B0, DIO_INPUT | DIO_PULL_UP)
PINMUX(FUNC(I2C0_SDA), B1, DIO_INPUT | DIO_PULL_DOWN)
The "pinmux" console command showed that the new flags took effect:
Before:
400600a0: DIOB0 0 IN
400600a8: DIOB1 0 IN
After:
400600a0: DIOB0 0 IN PU
400600a8: DIOB1 0 IN PD
Change-Id: I1d212331431ef67b2f1bcece8729d092b9ad5ba8
Signed-off-by: Bill Richardson <wfrichar@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/339254
Reviewed-by: Dominic Rizzo <domrizzo@google.com>
Diffstat (limited to 'chip')
-rw-r--r-- | chip/g/gpio.c | 33 | ||||
-rw-r--r-- | chip/g/registers.h | 7 |
2 files changed, 32 insertions, 8 deletions
diff --git a/chip/g/gpio.c b/chip/g/gpio.c index 64c441bcbd..b03d951258 100644 --- a/chip/g/gpio.c +++ b/chip/g/gpio.c @@ -188,16 +188,37 @@ static int connect_dio_to_gpio(struct pinmux const *p) static void connect_pinmux(struct pinmux const *p) { uint32_t bitmask; + int is_input; + + if (p->flags & DIO_ENABLE_DIRECT_INPUT) { + /* We don't have to setup any muxes for directly connected + * pads. The only ones that we are likely to ever care about + * are tied to the SPS and SPI peripherals, and they're all + * inouts, so we can just enable the digital input for them + * regardless. */ + is_input = 1; + } else { + /* Pads that must be muxed to specific GPIOs or peripherals may + * or may not be inputs. We'll check those individually. */ + if (p->flags & DIO_TO_PERIPHERAL) + is_input = connect_dio_to_peripheral(p); + else + is_input = connect_dio_to_gpio(p); + } - /* Connect the pinmux DIO to the right thing */ - if ((p->flags & DIO_ENABLE_DIRECT_INPUT) || - ((p->flags & DIO_TO_PERIPHERAL) ? - connect_dio_to_peripheral(p) : - connect_dio_to_gpio(p))) - /* and maybe enable the pin as an input */ + /* Configure the DIO pad controls */ + if (is_input) REG_WRITE_MLV(DIO_CTL_REG(p->dio.offset), DIO_CTL_IE_MASK, DIO_CTL_IE_LSB, 1); + if (p->flags & DIO_PULL_UP) + REG_WRITE_MLV(DIO_CTL_REG(p->dio.offset), + DIO_CTL_PU_MASK, + DIO_CTL_PU_LSB, 1); + if (p->flags & DIO_PULL_DOWN) + REG_WRITE_MLV(DIO_CTL_REG(p->dio.offset), + DIO_CTL_PD_MASK, + DIO_CTL_PD_LSB, 1); /* Enable any wake pins needed to exit low-power modes */ if ((p->flags & DIO_WAKE_EN0) && diff --git a/chip/g/registers.h b/chip/g/registers.h index 5ecd12fa34..8ce2e90d7b 100644 --- a/chip/g/registers.h +++ b/chip/g/registers.h @@ -181,14 +181,17 @@ static inline int x_uart_addr(int ch, int offset) #define DIO_ENABLE_DIRECT_INPUT 0x0004 #define DIO_TO_PERIPHERAL 0x0008 /* Bits to indicate pinmux wake-from-sleep controls */ -#define DIO_WAKE_EN0 0x0040 -#define DIO_WAKE_EDGE0 0x0020 #define DIO_WAKE_INV0 0x0010 +#define DIO_WAKE_EDGE0 0x0020 +#define DIO_WAKE_EN0 0x0040 /* Use these combinations in gpio.inc for clarity */ #define DIO_WAKE_HIGH (DIO_WAKE_EN0) #define DIO_WAKE_LOW (DIO_WAKE_EN0 | DIO_WAKE_INV0) #define DIO_WAKE_RISING (DIO_WAKE_EN0 | DIO_WAKE_EDG0) #define DIO_WAKE_FALLING (DIO_WAKE_EN0 | DIO_WAKE_EDG0 | DIO_WAKE_INV0) +/* Flags for pullup/pulldowns */ +#define DIO_PULL_UP 0x0080 +#define DIO_PULL_DOWN 0x0100 /* Generate the MUX selector register address for the DIO */ #define DIO_SEL_REG(offset) REG32(GC_PINMUX_BASE_ADDR + offset) |