summaryrefslogtreecommitdiff
path: root/chip
diff options
context:
space:
mode:
authorDavid Hendricks <dhendrix@chromium.org>2012-04-20 14:02:05 -0700
committerDavid Hendricks <dhendrix@chromium.org>2012-04-23 19:18:42 -0700
commit97a49113d937774aacebd2a5c92e2e15d0e39464 (patch)
treecba5aea73fad5d949484d3861ec89debfd920017 /chip
parente8c86b2a6845b5fa9b73a6410c0442a0f03f771d (diff)
downloadchrome-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.c16
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 */