summaryrefslogtreecommitdiff
path: root/chip/npcx/gpio.c
diff options
context:
space:
mode:
authorCHLin <CHLIN56@nuvoton.com>2018-10-31 17:54:10 +0800
committerchrome-bot <chrome-bot@chromium.org>2018-11-05 04:55:03 -0800
commitd607e8e1ac8e44222ce14b23bfc05bf0cba473bf (patch)
tree90564fb156f65a031b4ee3229e2f22809519a277 /chip/npcx/gpio.c
parentefa0cb94e8cb111bb296523402bfa689e97dc92e (diff)
downloadchrome-ec-d607e8e1ac8e44222ce14b23bfc05bf0cba473bf.tar.gz
npcx: gpio: implement the gpio_get_flags_by_mask function
This CL adds the gpio_get_flags_by_mask function which is used to get the flag information of a GPIO when CONFIG_CMD_GPIO_EXTENDED is enabled. BRANCH=none BUG=b:118390658 TEST=No build error for make buildall. TEST=Enable CONFIG_CMD_GPIO_EXTENDED in npcx7_evb/board.h; modify flags of GPIOs in gpio.inc to cover all the flags required to be shown in print_gpio_info(); check the result of "gpioget" is consistent with what is set in the gpio.inc. Change-Id: Icb17e59f959c0d15e95023f27187972f690d88ce Signed-off-by: CHLin <CHLIN56@nuvoton.com> Reviewed-on: https://chromium-review.googlesource.com/1312515 Commit-Ready: CH Lin <chlin56@nuvoton.com> Tested-by: CH Lin <chlin56@nuvoton.com> Reviewed-by: Nicolas Boichat <drinkcat@chromium.org>
Diffstat (limited to 'chip/npcx/gpio.c')
-rw-r--r--chip/npcx/gpio.c88
1 files changed, 85 insertions, 3 deletions
diff --git a/chip/npcx/gpio.c b/chip/npcx/gpio.c
index 1c125c3f57..252b915e45 100644
--- a/chip/npcx/gpio.c
+++ b/chip/npcx/gpio.c
@@ -78,7 +78,6 @@ struct gpio_lvol_item {
/* Constants for GPIO low-voltage mapping */
const struct gpio_lvol_item gpio_lvol_table[] = NPCX_LVOL_TABLE;
-
/*****************************************************************************/
/* Internal functions */
@@ -87,6 +86,33 @@ static int gpio_match(uint8_t port, uint8_t bit, struct npcx_gpio gpio)
return (gpio.valid && (gpio.port == port) && (gpio.bit == bit));
}
+#ifdef CONFIG_CMD_GPIO_EXTENDED
+static uint8_t gpio_is_alt_sel(uint8_t port, uint8_t bit)
+{
+ struct gpio_alt_map const *map;
+ uint8_t alt_mask, devalt;
+
+ for (map = ARRAY_BEGIN(gpio_alt_table);
+ map < ARRAY_END(gpio_alt_table);
+ map++) {
+ if (gpio_match(port, bit, map->gpio)) {
+ alt_mask = 1 << map->alt.bit;
+ devalt = NPCX_DEVALT(map->alt.group);
+ /*
+ * alt.inverted == 0:
+ * !!(devalt & alt_mask) == 0 -> GPIO
+ * !!(devalt & alt_mask) == 1 -> Alternate
+ * alt.inverted == 1:
+ * !!(devalt & alt_mask) == 0 -> Alternate
+ * !!(devalt & alt_mask) == 1 -> GPIO
+ */
+ return !!(devalt & alt_mask) ^ map->alt.inverted;
+ }
+ }
+ return 0;
+}
+#endif
+
static int gpio_alt_sel(uint8_t port, uint8_t bit, int8_t func)
{
struct gpio_alt_map const *map;
@@ -176,6 +202,23 @@ static void gpio_interrupt_type_sel(enum gpio_signal signal, uint32_t flags)
/* No support analog mode */
}
+#ifdef CONFIG_CMD_GPIO_EXTENDED
+static uint8_t gpio_is_low_voltage_level_sel(uint8_t port, uint8_t bit)
+{
+ int i, j;
+
+ for (i = 0; i < ARRAY_SIZE(gpio_lvol_table); i++) {
+ 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, bit, gpio[j]))
+ return IS_BIT_SET(NPCX_LV_GPIO_CTL(i), j);
+ }
+ }
+ return 0;
+}
+#endif
+
/* Select low voltage detection level */
void gpio_low_voltage_level_sel(uint8_t port, uint8_t bit, uint8_t low_voltage)
{
@@ -184,7 +227,7 @@ void gpio_low_voltage_level_sel(uint8_t port, uint8_t bit, uint8_t low_voltage)
for (i = 0; i < ARRAY_SIZE(gpio_lvol_table); i++) {
const struct npcx_gpio *gpio = gpio_lvol_table[i].lvol_gpio;
- for (j = 0; j < ARRAY_SIZE(gpio_lvol_table[0].lvol_gpio); j++)
+ for (j = 0; j < ARRAY_SIZE(gpio_lvol_table[0].lvol_gpio); j++) {
if (gpio_match(port, bit, gpio[j])) {
if (low_voltage)
/* Select vol-detect level for 1.8V */
@@ -194,7 +237,7 @@ void gpio_low_voltage_level_sel(uint8_t port, uint8_t bit, uint8_t low_voltage)
CLEAR_BIT(NPCX_LV_GPIO_CTL(i), j);
return;
}
-
+ }
}
if (low_voltage)
@@ -287,6 +330,45 @@ void gpio_set_level(enum gpio_signal signal, int value)
NPCX_PDOUT(gpio_list[signal].port) &= ~gpio_list[signal].mask;
}
+#ifdef CONFIG_CMD_GPIO_EXTENDED
+int gpio_get_flags_by_mask(uint32_t port, uint32_t mask)
+{
+ uint32_t flags = 0;
+
+ if (NPCX_PDIR(port) & mask)
+ flags |= GPIO_OUTPUT;
+ else
+ flags |= GPIO_INPUT;
+
+ if (NPCX_PDIN(port) & mask)
+ flags |= GPIO_HIGH;
+ else
+ flags |= GPIO_LOW;
+
+ if (NPCX_PTYPE(port) & mask)
+ flags |= GPIO_OPEN_DRAIN;
+
+ /* If internal pulling is enabled */
+ if (NPCX_PPULL(port) & mask) {
+ if (NPCX_PPUD(port) & mask)
+ flags |= GPIO_PULL_DOWN;
+ else
+ flags |= GPIO_PULL_UP;
+ }
+
+ if (gpio_is_alt_sel(port, GPIO_MASK_TO_NUM(mask)))
+ flags |= GPIO_ALTERNATE;
+
+ if (gpio_is_low_voltage_level_sel(port, GPIO_MASK_TO_NUM(mask)))
+ flags |= GPIO_SEL_1P8V;
+
+ if (NPCX_PLOCK_CTL(port) & mask)
+ flags |= GPIO_LOCKED;
+
+ return flags;
+}
+#endif
+
void gpio_set_flags_by_mask(uint32_t port, uint32_t mask, uint32_t flags)
{
/* If all GPIO pins are locked, return directly */