diff --git a/common/gpio.c b/common/gpio.c index b0200facfd..0fa949dedb 100644 --- a/common/gpio.c +++ b/common/gpio.c @@ -168,4 +168,38 @@ int gpio_get_ternary(enum gpio_signal signal) return pu && !pd ? 2 : pd; } +#ifdef CONFIG_GPIO_POWER_DOWN +/* + * Power down a group of GPIO pins marked with a module ID + * in board/board_name/gpio.inc + * Hibernation/sleep entry: + * gpio_power_down_module(MODULE_xxxx) + * Chip level code will power down all pins in module. + * Wake: + * Use gpio_config_module to put the module pin(s) + * back to enabled state. Chip level code will re-power + * and configure the pin(s). + * This mechanism does not handle dynamic changing of + * pin configuration at run time. + */ +int gpio_power_down_module(enum module_id id) +{ + const struct gpio_alt_func *af; + int rv = EC_ERROR_INVAL; + + /* Find pins and power down */ + for (af = gpio_alt_funcs; + af < gpio_alt_funcs + ARRAY_SIZE(gpio_alt_funcs); + af++) { + if (af->module_id != id) + continue; /* Pins for some other module */ + + gpio_set_flags_by_mask(af->port, af->mask, GPIO_POWER_DOWN); + rv = EC_SUCCESS; + } + + return rv; +} +#endif /* #ifdef CONFIG_GPIO_POWER_DOWN */ + /*****************************************************************************/ diff --git a/include/config.h b/include/config.h index 7cbe9ab957..7c5a1db832 100644 --- a/include/config.h +++ b/include/config.h @@ -828,6 +828,12 @@ */ #undef CONFIG_COMMON_GPIO_SHORTNAMES +/* + * EC's supporting powering down GPIO pins. + * Add flag GPIO_POWER_DOWN and additional API's. + */ +#undef CONFIG_GPIO_POWER_DOWN + /* * Provide common runtime layer code (tasks, hooks ...) * You want this unless you are doing a really tiny firmware. diff --git a/include/gpio.h b/include/gpio.h index 195f644d67..1c80f7e32d 100644 --- a/include/gpio.h +++ b/include/gpio.h @@ -33,6 +33,9 @@ #define GPIO_ALTERNATE (1 << 17) /* GPIO used for alternate function. */ #define GPIO_LOCKED (1 << 18) /* Lock GPIO output and configuration */ #define GPIO_HIB_WAKE_HIGH (1 << 19) /* Hibernate wake on high level */ +#ifdef CONFIG_GPIO_POWER_DOWN +#define GPIO_POWER_DOWN (1 << 20) /* Pin and pad is powered off */ +#endif /* Common flag combinations */ #define GPIO_OUT_LOW (GPIO_OUTPUT | GPIO_LOW) @@ -266,4 +269,14 @@ void gpio_set_flags_by_mask(uint32_t port, uint32_t mask, uint32_t flags); */ void gpio_set_alternate_function(uint32_t port, uint32_t mask, int func); +#ifdef CONFIG_GPIO_POWER_DOWN +/** + * Power down all GPIO pins in a module. + * + * @param id Module ID to initialize + * @return EC_SUCCESS, or non-zero if module_id is not found. + */ +int gpio_power_down_module(enum module_id id); +#endif + #endif /* __CROS_EC_GPIO_H */