summaryrefslogtreecommitdiff
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
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>
-rw-r--r--chip/npcx/gpio.c29
-rw-r--r--chip/npcx/gpio_chip-npcx7.h6
2 files changed, 21 insertions, 14 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) {
diff --git a/chip/npcx/gpio_chip-npcx7.h b/chip/npcx/gpio_chip-npcx7.h
index 7fe1ee41a3..c8e28c9ddb 100644
--- a/chip/npcx/gpio_chip-npcx7.h
+++ b/chip/npcx/gpio_chip-npcx7.h
@@ -442,7 +442,7 @@
#define NPCX_LVOL_CTRL_1_3 NPCX_GPIO(D, 0)
#define NPCX_LVOL_CTRL_1_4 NPCX_GPIO(3, 6)
#define NPCX_LVOL_CTRL_1_5 NPCX_GPIO(6, 4)
-#define NPCX_LVOL_CTRL_1_6 NPCX_GPIO(6, 5)
+#define NPCX_LVOL_CTRL_1_6 NPCX_GPIO_NONE
#define NPCX_LVOL_CTRL_1_7 NPCX_GPIO_NONE
/* Low-Voltage GPIO Control 2 */
@@ -480,11 +480,7 @@
#define NPCX_LVOL_CTRL_3_7 NPCX_GPIO(C, 5)
/* Low-Voltage GPIO Control 4 */
-#ifdef NPCX_PSL_MODE_SUPPORT
-#define NPCX_LVOL_CTRL_4_0 NPCX_GPIO_NONE /* Remove 1.8V support since PSL */
-#else
#define NPCX_LVOL_CTRL_4_0 NPCX_GPIO(8, 6)
-#endif
#define NPCX_LVOL_CTRL_4_1 NPCX_GPIO(C, 2)
#define NPCX_LVOL_CTRL_4_2 NPCX_GPIO(F, 3)
#define NPCX_LVOL_CTRL_4_3 NPCX_GPIO(F, 2)