From 4c294d144bd479c6269e183215fa0f9cfbe49f8d Mon Sep 17 00:00:00 2001 From: Shawn Nematbakhsh Date: Mon, 28 Mar 2016 05:50:18 -0700 Subject: [PATCH] npcx: gpio: Configure pin attributes before setting as output When a pin power-on default is input, it is necessary to configure output level, pull up, etc. before setting the pin to output. Otherwise, the pin may be set to an undesired logic level for a short time. BUG=chrome-os-partner:51722 TEST=Power-up kevin, verify that CR50_RESET_L (default input, configured as high + open drain output by default) does not go low for a short period at boot. BRANCH=None Signed-off-by: Shawn Nematbakhsh Change-Id: Ieaa08e14e6ea15a908f3ff4ee9188e14b17583cf Reviewed-on: https://chromium-review.googlesource.com/335344 Commit-Ready: Shawn N Tested-by: Shawn N Reviewed-by: Randall Spangler Reviewed-by: Mulin Chao --- chip/npcx/gpio.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/chip/npcx/gpio.c b/chip/npcx/gpio.c index 9dae6d0f6f..1bca7b7d03 100644 --- a/chip/npcx/gpio.c +++ b/chip/npcx/gpio.c @@ -583,20 +583,19 @@ void gpio_set_level(enum gpio_signal signal, int value) void gpio_set_flags_by_mask(uint32_t port, uint32_t mask, uint32_t flags) { /* - * Select open drain first, so that we don't glitch the signal - * when changing the line to an output. 0:push-pull 1:open-drain + * Configure pin as input, if requested. Output is configured only + * after setting all other attributes, so as not to create a + * temporary incorrect logic state 0:input 1:output */ + if (!(flags & GPIO_OUTPUT)) + NPCX_PDIR(port) &= ~mask; + + /* Select open drain 0:push-pull 1:open-drain */ if (flags & GPIO_OPEN_DRAIN) NPCX_PTYPE(port) |= mask; else NPCX_PTYPE(port) &= ~mask; - /* Select direction of GPIO 0:input 1:output */ - if (flags & GPIO_OUTPUT) - NPCX_PDIR(port) |= mask; - else - NPCX_PDIR(port) &= ~mask; - /* Select pull-up/down of GPIO 0:pull-up 1:pull-down */ if (flags & GPIO_PULL_UP) { NPCX_PPUD(port) &= ~mask; @@ -631,6 +630,9 @@ void gpio_set_flags_by_mask(uint32_t port, uint32_t mask, uint32_t flags) else if (flags & GPIO_LOW) NPCX_PDOUT(port) &= ~mask; + /* Configure pin as output, if requested 0:input 1:output */ + if (flags & GPIO_OUTPUT) + NPCX_PDIR(port) |= mask; } int gpio_enable_interrupt(enum gpio_signal signal)