summaryrefslogtreecommitdiff
path: root/chip
diff options
context:
space:
mode:
authorCHLin <CHLIN56@nuvoton.com>2018-10-26 15:39:06 +0800
committerMartin Roth <martinroth@chromium.org>2018-10-30 22:07:08 +0000
commitc0caf458ead3dbae2bec7b67db4731dfe2861824 (patch)
tree98332de772882acf6039138b1faf57d8c3da30f2 /chip
parentd3d1a45517dfbc384ca35d5c7f10d3a6bd969f94 (diff)
downloadchrome-ec-c0caf458ead3dbae2bec7b67db4731dfe2861824.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> Reviewed-on: https://chromium-review.googlesource.com/c/1309045 Reviewed-by: Martin Roth <martinroth@chromium.org> Tested-by: Martin Roth <martinroth@chromium.org>
Diffstat (limited to 'chip')
-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 f8a17d98a8..212aa996b6 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)