diff options
author | David Hendricks <dhendrix@chromium.org> | 2012-04-20 14:02:05 -0700 |
---|---|---|
committer | David Hendricks <dhendrix@chromium.org> | 2012-04-23 19:18:42 -0700 |
commit | 97a49113d937774aacebd2a5c92e2e15d0e39464 (patch) | |
tree | cba5aea73fad5d949484d3861ec89debfd920017 /chip | |
parent | e8c86b2a6845b5fa9b73a6410c0442a0f03f771d (diff) | |
download | chrome-ec-97a49113d937774aacebd2a5c92e2e15d0e39464.tar.gz |
stm32l: clear and then set GPIO mode and pull-up/down settings
GPIO mode and pull-up/down registers do not all get initialized to
zero on reset. This patch ensures that all bits in the those registers
are set explicitly. An intermediate variable is used so that changes
are made atomically.
Note: output speed registers are also not all initialized to zero, but
we don't handle that in gpio_pre_init yet.
BUG=none
TEST=tested on newer daisy boards (which needed this patch to boot)
Change-Id: Ice2795197135dcee8f8484e4908dbfcf90fec2c9
Signed-off-by: David Hendricks <dhendrix@chromium.org>
Diffstat (limited to 'chip')
-rw-r--r-- | chip/stm32l/gpio.c | 16 |
1 files changed, 10 insertions, 6 deletions
diff --git a/chip/stm32l/gpio.c b/chip/stm32l/gpio.c index 0f3e7f44a5..d56efa32d4 100644 --- a/chip/stm32l/gpio.c +++ b/chip/stm32l/gpio.c @@ -29,15 +29,17 @@ int gpio_pre_init(void) */ STM32L_RCC_AHBENR |= 0x3f; - /* Set all GPIOs to defaults */ for (i = 0; i < GPIO_COUNT; i++, g++) { /* bitmask for registers with 2 bits per GPIO pin */ uint32_t mask2 = (g->mask * g->mask) | (g->mask * g->mask * 2); + uint32_t val; + val = STM32L_GPIO_PUPDR_OFF(g->port) & ~mask2; if (g->flags & GPIO_PULL_UP) /* Pull Up = 01 */ - STM32L_GPIO_PUPDR_OFF(g->port) |= 0x55555555 & mask2; + val |= 0x55555555 & mask2; else if (g->flags & GPIO_PULL_DOWN) /* Pull Down = 10 */ - STM32L_GPIO_PUPDR_OFF(g->port) |= 0xaaaaaaaa & mask2; + val |= 0xaaaaaaaa & mask2; + STM32L_GPIO_PUPDR_OFF(g->port) = val; if (g->flags & GPIO_OPEN_DRAIN) STM32L_GPIO_OTYPER_OFF(g->port) |= g->mask; @@ -47,11 +49,13 @@ int gpio_pre_init(void) * potential damage, e.g. driving an open-drain output * high before it has been configured as such. */ + val = STM32L_GPIO_MODER_OFF(g->port) & ~mask2; if (g->flags & GPIO_OUTPUT) { /* General purpose, MODE = 01 */ - STM32L_GPIO_MODER_OFF(g->port) |= 0x55555555 & mask2; + val |= 0x55555555 & mask2; + STM32L_GPIO_MODER_OFF(g->port) = val; gpio_set_level(i, g->flags & GPIO_HIGH); - } else if (g->flags & GPIO_INPUT) { - STM32L_GPIO_MODER_OFF(g->port) &= ~mask2; + } else if (g->flags & GPIO_INPUT) { /* Input, MODE=00 */ + STM32L_GPIO_MODER_OFF(g->port) = val; } /* Set up interrupts if necessary */ |