summaryrefslogtreecommitdiff
path: root/chip/npcx/gpio.c
diff options
context:
space:
mode:
authorCHLin <CHLIN56@nuvoton.com>2018-10-26 15:39:06 +0800
committerchrome-bot <chrome-bot@chromium.org>2018-10-30 01:04:58 -0700
commit36190da7c5b8ac47aefc8eaa9fb581b9b77bd26b (patch)
tree68747ff0c584012c0d538d520fbcf1030ebd0784 /chip/npcx/gpio.c
parent09a5e0a9398a1ca9e953969d5c10d3b60cda8eac (diff)
downloadchrome-ec-36190da7c5b8ac47aefc8eaa9fb581b9b77bd26b.tar.gz
npcx: gpio: fix bugs of low voltage level selection
This CL fixed the following bugs of low voltage support of GPIO: 1. fix the mismatch issue of low voltage support GPIOs when the mask passed to gpio_low_voltage_level_sel() has multiple bits set. (see more detail in the bug:118443060.) The idea is to create a new function gpio_low_vol_sel_by_mask() to iterate the match for each bit set in the mask. i.e. while (lv_mask) { bit = get_next_bit(&lv_mask); gpio_low_voltage_level_sel(p, bit, low_vol); }; The second parameter of gpio_match()/gpio_low_voltage_level_sel is also changed from "mask" to "bit" because of above modification. 2. It was observed that there are some errors of the low level mapping table because the older datasheet we used to develop the driver is not correct. After checking the latest datasheets of all EC sku, the low level table should have the following modification: - GPIO65 cannot support low level and should be removed. - GPIO86 can support low level in all EC skus. BRANCH=none BUG=b:118443060 TEST=Add GPIO_SEL_1P8V flag in the ALTERNATE macros which have multiple bits set in the mask field in npcx7_evb board. Flash the image and make sure the warning message doesn't print and the related low level bits are set. Change-Id: I7aa23eb42dda178db34fe44a663df29757910a55 Signed-off-by: CHLin <CHLIN56@nuvoton.com> Reviewed-on: https://chromium-review.googlesource.com/1301674 Commit-Ready: CH Lin <chlin56@nuvoton.com> Tested-by: CH Lin <chlin56@nuvoton.com> Reviewed-by: Wai-Hong Tam <waihong@google.com>
Diffstat (limited to 'chip/npcx/gpio.c')
-rw-r--r--chip/npcx/gpio.c29
1 files changed, 20 insertions, 9 deletions
diff --git a/chip/npcx/gpio.c b/chip/npcx/gpio.c
index 8c3f6cde0a..1c125c3f57 100644
--- a/chip/npcx/gpio.c
+++ b/chip/npcx/gpio.c
@@ -82,9 +82,9 @@ const struct gpio_lvol_item gpio_lvol_table[] = NPCX_LVOL_TABLE;
/*****************************************************************************/
/* Internal functions */
-static int gpio_match(uint8_t port, uint8_t mask, struct npcx_gpio gpio)
+static int gpio_match(uint8_t port, uint8_t bit, struct npcx_gpio gpio)
{
- return (gpio.valid && (gpio.port == port) && ((1 << gpio.bit) == mask));
+ return (gpio.valid && (gpio.port == port) && (gpio.bit == bit));
}
static int gpio_alt_sel(uint8_t port, uint8_t bit, int8_t func)
@@ -94,7 +94,7 @@ static int gpio_alt_sel(uint8_t port, uint8_t bit, int8_t func)
for (map = ARRAY_BEGIN(gpio_alt_table);
map < ARRAY_END(gpio_alt_table);
map++) {
- if (gpio_match(port, 1 << bit, map->gpio)) {
+ if (gpio_match(port, bit, map->gpio)) {
uint8_t alt_mask = 1 << map->alt.bit;
/*
@@ -177,7 +177,7 @@ static void gpio_interrupt_type_sel(enum gpio_signal signal, uint32_t flags)
}
/* Select low voltage detection level */
-void gpio_low_voltage_level_sel(uint8_t port, uint8_t mask, uint8_t low_voltage)
+void gpio_low_voltage_level_sel(uint8_t port, uint8_t bit, uint8_t low_voltage)
{
int i, j;
@@ -185,7 +185,7 @@ void gpio_low_voltage_level_sel(uint8_t port, uint8_t mask, uint8_t low_voltage)
const struct npcx_gpio *gpio = gpio_lvol_table[i].lvol_gpio;
for (j = 0; j < ARRAY_SIZE(gpio_lvol_table[0].lvol_gpio); j++)
- if (gpio_match(port, mask, gpio[j])) {
+ if (gpio_match(port, bit, gpio[j])) {
if (low_voltage)
/* Select vol-detect level for 1.8V */
SET_BIT(NPCX_LV_GPIO_CTL(i), j);
@@ -198,10 +198,21 @@ void gpio_low_voltage_level_sel(uint8_t port, uint8_t mask, uint8_t low_voltage)
}
if (low_voltage)
- CPRINTS("Warn! No low voltage support in port%d, mask%d\n",
- port, mask);
+ CPRINTS("Warn! No low voltage support in port:0x%x, bit:%d",
+ port, bit);
}
+/* Set the low voltage detection level by mask */
+static void gpio_low_vol_sel_by_mask(uint8_t p, uint8_t mask, uint8_t low_vol)
+{
+ int bit;
+ uint32_t lv_mask = mask;
+
+ while (lv_mask) {
+ bit = get_next_bit(&lv_mask);
+ gpio_low_voltage_level_sel(p, bit, low_vol);
+ };
+}
/* The bypass of low voltage IOs for better power consumption */
#ifdef CONFIG_LOW_POWER_IDLE
static int gpio_is_i2c_pin(enum gpio_signal signal)
@@ -322,9 +333,9 @@ void gpio_set_flags_by_mask(uint32_t port, uint32_t mask, uint32_t flags)
* Set IO type to open-drain before selecting low-voltage level
*/
NPCX_PTYPE(port) |= mask;
- gpio_low_voltage_level_sel(port, mask, 1);
+ gpio_low_vol_sel_by_mask(port, mask, 1);
} else
- gpio_low_voltage_level_sel(port, mask, 0);
+ gpio_low_vol_sel_by_mask(port, mask, 0);
/* Set up interrupt type */
if (flags & GPIO_INT_ANY) {