summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMary Ruthven <mruthven@chromium.org>2017-06-05 20:24:10 -0700
committerCommit Bot <commit-bot@chromium.org>2020-02-07 23:09:55 +0000
commit341cc2da402e23dc9ff09072058f79d5ec0c40c6 (patch)
tree512c995b1c86a6d1dc3bff45eeb58bc6e483b4e4
parentca4bec7b0eab93cc3a0ccd5437e96f650c0274d5 (diff)
downloadchrome-ec-341cc2da402e23dc9ff09072058f79d5ec0c40c6.tar.gz
g: add gpio_set_wakepin() to configure wake pins
Cr50 needs a cleaner way to enable and disable wakepins. This change adds gpio_set_wakepin() to enable the wake pin or disable. The gpio_set_flags() or gpio_set_flags_by_mask() remain unaffecting wake-pin configuration. This patch increases the flash usage by 16 bytes. BUG=b:35587259 BRANCH=cr50 TEST=verify pinmux has the same output before and after the change on octopus. Signed-off-by: Mary Ruthven <mruthven@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/533674 Tested-by: Namyoon Woo <namyoon@chromium.org> Reviewed-by: Namyoon Woo <namyoon@chromium.org> Commit-Queue: Namyoon Woo <namyoon@chromium.org> Change-Id: I0387c673aedc046ce9cf6b5f0d683c40f3079281 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2044355
-rw-r--r--chip/g/gpio.c99
-rw-r--r--common/gpio.c6
-rw-r--r--include/gpio.h20
3 files changed, 104 insertions, 21 deletions
diff --git a/chip/g/gpio.c b/chip/g/gpio.c
index d8ebe42d0d..f55e0fad35 100644
--- a/chip/g/gpio.c
+++ b/chip/g/gpio.c
@@ -51,6 +51,34 @@ void gpio_set_level(enum gpio_signal signal, int value)
set_one_gpio_bit(g->port, g->mask, value);
}
+static void configure_wakepin(int bitmask, uint32_t flags)
+{
+ /* not VIOn ! */
+ if (bitmask > GC_PINMUX_EXITEN0_DIOB7_MASK)
+ return;
+
+ if (!(flags & DIO_WAKE_EN0)) {
+ /* Disable the pin */
+ GREG32(PINMUX, EXITEN0) &= ~bitmask;
+ return;
+ }
+
+ /* level (0) or edge sensitive (1) */
+ if (flags & DIO_WAKE_EDGE0)
+ GREG32(PINMUX, EXITEDGE0) |= bitmask;
+ else
+ GREG32(PINMUX, EXITEDGE0) &= ~bitmask;
+
+ /* high/rising (0) or low/falling (1) */
+ if (flags & DIO_WAKE_INV0)
+ GREG32(PINMUX, EXITINV0) |= bitmask;
+ else
+ GREG32(PINMUX, EXITINV0) &= ~bitmask;
+
+ /* Enable the pin */
+ GREG32(PINMUX, EXITEN0) |= bitmask;
+}
+
int gpio_get_flags_by_mask(uint32_t port, uint32_t mask)
{
uint32_t flags = 0;
@@ -123,6 +151,50 @@ void gpio_set_flags_by_mask(uint32_t port, uint32_t mask, uint32_t flags)
/* No way to trigger on both rising and falling edges, darn it. */
}
+void gpio_set_wakepin(enum gpio_signal signal, uint32_t flags)
+{
+ const struct gpio_info *g = gpio_list + signal;
+ const int gpio_bitnum = GPIO_MASK_TO_NUM(g->mask);
+ const int dio_val = GET_GPIO_SEL_REG(g->port, gpio_bitnum);
+ int dio_mask;
+ int dio_wake_flags;
+
+ /* Can't do anything if the gpio is not connected to a pin */
+ if (!dio_val)
+ return;
+
+ /* Convert the gpio wake flags to the dio wake pin configuration */
+ flags &= GPIO_HIB_WAKE_MASK;
+ switch (flags) {
+ case 0: /* Disable Wakepin */
+ dio_wake_flags = 0;
+ break;
+ case GPIO_HIB_WAKE_HIGH:
+ dio_wake_flags = DIO_WAKE_HIGH;
+ break;
+ case GPIO_HIB_WAKE_LOW:
+ dio_wake_flags = DIO_WAKE_LOW;
+ break;
+ case GPIO_HIB_WAKE_RISING:
+ dio_wake_flags = DIO_WAKE_RISING;
+ break;
+ case GPIO_HIB_WAKE_FALLING:
+ dio_wake_flags = DIO_WAKE_FALLING;
+ break;
+ default:
+ /* Wake contions cannot be more than one. */
+ return;
+ }
+
+ /*
+ * GC_PINMUX_{PIN}_SEL values start from 0x1e (DIOM0)
+ * down to 0x03 (DIOB7). Meanwhile, GC_PINMUX_{wake_cond}_{pin}_MASK
+ * has BIT(0) for DIOM0 and BIT(27) for DIOB7.
+ */
+ dio_mask = 1 << (GC_PINMUX_DIOM0_SEL - dio_val);
+ configure_wakepin(dio_mask, dio_wake_flags);
+}
+
void gpio_set_alternate_function(uint32_t port, uint32_t mask,
enum gpio_alternate_func func)
{
@@ -231,7 +303,6 @@ static int connect_dio_to_gpio(struct pinmux const *p)
static void connect_pinmux(struct pinmux const *p)
{
- uint32_t bitmask;
int is_input;
if (p->flags & DIO_ENABLE_DIRECT_INPUT) {
@@ -265,24 +336,14 @@ static void connect_pinmux(struct pinmux const *p)
DIO_CTL_PD_LSB, 1);
/* Enable any wake pins needed to exit low-power modes */
- if ((p->flags & DIO_WAKE_EN0) &&
- (p->dio.offset <= GC_PINMUX_DIOB7_SEL_OFFSET)) { /* not VIOn ! */
- bitmask = (1 << (p->dio.offset / 8));
-
- /* enable pad as wake source */
- GREG32(PINMUX, EXITEN0) |= bitmask;
-
- /* level (0) or edge sensitive (1) */
- if (p->flags & DIO_WAKE_EDGE0)
- GREG32(PINMUX, EXITEDGE0) |= bitmask;
- else
- GREG32(PINMUX, EXITEDGE0) &= ~bitmask;
-
- /* high/rising (0) or low/falling (1) */
- if (p->flags & DIO_WAKE_INV0)
- GREG32(PINMUX, EXITINV0) |= bitmask;
- else
- GREG32(PINMUX, EXITINV0) &= ~bitmask;
+ if (p->flags & DIO_WAKE_EN0) {
+ /*
+ * p->dio.offset is the offset of GC_PINMUX_*_SEL register.
+ * The next GC_PINMUX_*_SEL register is 8 byte away.
+ */
+ const uint32_t dio_mask = (1 << (p->dio.offset / 8));
+
+ configure_wakepin(dio_mask, p->flags);
}
}
diff --git a/common/gpio.c b/common/gpio.c
index 69aae0572e..c59065a60c 100644
--- a/common/gpio.c
+++ b/common/gpio.c
@@ -218,4 +218,10 @@ int signal_is_gpio(int signal)
&& (signal < GPIO_SIGNAL_START + GPIO_COUNT));
}
+__attribute__((weak)) void gpio_set_wakepin(enum gpio_signal signal,
+ uint32_t flags)
+{
+ /* Some chips may need their own implementations */
+}
+
/*****************************************************************************/
diff --git a/include/gpio.h b/include/gpio.h
index 61329ad758..e1957813e0 100644
--- a/include/gpio.h
+++ b/include/gpio.h
@@ -34,9 +34,12 @@
#define GPIO_SEL_1P8V BIT(16) /* Support 1.8v */
#define GPIO_ALTERNATE BIT(17) /* GPIO used for alternate function. */
#define GPIO_LOCKED BIT(18) /* Lock GPIO output and configuration */
-#define GPIO_HIB_WAKE_HIGH BIT(19) /* Hibernate wake on high level */
+#define GPIO_HIB_WAKE_HIGH BIT(19) /* Hibernate wake on high level */
+#define GPIO_HIB_WAKE_LOW BIT(20) /* Hibernate wake on low level */
+#define GPIO_HIB_WAKE_RISING BIT(21) /* Hibernate wake on rising edge */
+#define GPIO_HIB_WAKE_FALLING BIT(22) /* Hibernate wake on falling edge */
#ifdef CONFIG_GPIO_POWER_DOWN
-#define GPIO_POWER_DOWN BIT(20) /* Pin and pad is powered off */
+#define GPIO_POWER_DOWN BIT(23) /* Pin and pad is powered off */
#endif
/* Common flag combinations */
@@ -53,6 +56,8 @@
#define GPIO_INT_LEVEL (GPIO_INT_LOW | GPIO_INT_HIGH)
#define GPIO_INT_ANY (GPIO_INT_BOTH | GPIO_INT_LEVEL)
#define GPIO_INT_BOTH_DSLEEP (GPIO_INT_BOTH | GPIO_INT_DSLEEP)
+#define GPIO_HIB_WAKE_MASK (GPIO_HIB_WAKE_HIGH | GPIO_HIB_WAKE_LOW | \
+ GPIO_HIB_WAKE_RISING|GPIO_HIB_WAKE_FALLING)
/* Convert GPIO mask to GPIO number / index. */
#define GPIO_MASK_TO_NUM(mask) (__fls(mask))
@@ -343,4 +348,15 @@ int gpio_power_down_module(enum module_id id);
*/
int signal_is_gpio(int signal);
+/**
+ * Configure a GPIO as wake source on a given condition and enable it, or
+ * disable it.
+ *
+ * @param signal GPIO to enable to wake Cr50 up
+ * @param flags Wake condition. Should be one among
+ * GPIO_HIB_WAKE_{HIGH, LOW, RISING, FALLING} to enable it
+ * as a wake pin. 0 to disable it.
+ */
+void gpio_set_wakepin(enum gpio_signal signal, uint32_t flags);
+
#endif /* __CROS_EC_GPIO_H */