diff options
author | Shawn Nematbakhsh <shawnn@chromium.org> | 2015-08-10 15:26:03 -0700 |
---|---|---|
committer | ChromeOS Commit Bot <chromeos-commit-bot@chromium.org> | 2015-08-11 21:21:28 +0000 |
commit | 5b93f04c195675c8ad093bd2c36c85088e68ab74 (patch) | |
tree | a307cc07989047b263dee827e9b4317a16a80b43 | |
parent | fba4f335a9a78f4112980fcf1cc36d44cfda0406 (diff) | |
download | chrome-ec-5b93f04c195675c8ad093bd2c36c85088e68ab74.tar.gz |
mec1322: Allow GPIO hibernate state to be specified at board-level
Add a new board-level function board_get_gpio_hibernate_state which can
optionally be defined to set the desired state of a GPIO during
hibernate.
BUG=chrome-os-partner:43807
TEST=Manual on Glados with subsequent commit. Run 'hibernate' on console,
verify that LED remains off. Press power button, verify that board wakes.
BRANCH=None
Change-Id: Ica11554e231e88773c3e139fea4622377ebe1e42
Signed-off-by: Shawn Nematbakhsh <shawnn@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/292471
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
-rw-r--r-- | chip/mec1322/registers.h | 7 | ||||
-rw-r--r-- | chip/mec1322/system.c | 73 | ||||
-rw-r--r-- | include/gpio.h | 5 |
3 files changed, 48 insertions, 37 deletions
diff --git a/chip/mec1322/registers.h b/chip/mec1322/registers.h index 7da25ae059..6854735fd5 100644 --- a/chip/mec1322/registers.h +++ b/chip/mec1322/registers.h @@ -486,4 +486,11 @@ typedef volatile struct mec1322_dma_regs mec1322_dma_regs_t; extern const enum gpio_signal hibernate_wake_pins[]; extern const int hibernate_wake_pins_used; +/* + * Optional board-level function to get hibernate GPIO state. + * Returns desired GPIO state in hibernate, or 0 to skip reconfiguration. + */ +uint32_t board_get_gpio_hibernate_state(uint32_t port, uint32_t pin) + __attribute__((weak)); + #endif /* __CROS_EC_REGISTERS_H */ diff --git a/chip/mec1322/system.c b/chip/mec1322/system.c index acbbe0320f..e8d4b0e9ba 100644 --- a/chip/mec1322/system.c +++ b/chip/mec1322/system.c @@ -182,23 +182,10 @@ uint32_t system_get_scratchpad(void) return MEC1322_VBAT_RAM(HIBDATA_INDEX_SCRATCHPAD); } -/* Convert a GPIO to a port + mask, used in the skip table below. */ -#define PORT_MASK_PAIR(gpio) \ - { gpio_list[(gpio)].port, \ - GPIO_MASK_TO_NUM(gpio_list[(gpio)].mask) } - -static void system_set_gpio_power(int enabled, uint32_t *backup_gpio_ctl) +/* Returns desired GPIO state in hibernate, or 0 to skip reconfiguration */ +static uint32_t system_get_gpio_hibernate_state(uint32_t port, uint32_t pin) { - int i, j, k; - uint32_t val; - int want_skip; - - const int pins[][2] = { - {0, 7}, {1, 7}, {2, 7}, {3, 6}, {4, 7}, {5, 7}, - {6, 7}, {10, 7}, {11, 7}, {12, 7}, {13, 6}, - {14, 7}, {15, 7}, {16, 5}, {20, 6}, {21, 1} - }; - + int i; const int skip[][2] = { #ifdef GLADOS_BOARD_V1 /* @@ -206,21 +193,20 @@ static void system_set_gpio_power(int enabled, uint32_t *backup_gpio_ctl) * TODO(crosbug.com/p/42774): Remove this once we have a * pull-down on PCH_RTCRST. */ - PORT_MASK_PAIR(GPIO_PCH_RTCRST), + GPIO_TO_PORT_MASK_PAIR(GPIO_PCH_RTCRST), #endif - /* * Leave USB-C charging enabled in hibernate, in order to * allow wake-on-plug. 5V enable must be pulled low. */ #ifdef CONFIG_USB_PD_PORT_COUNT #if CONFIG_USB_PD_PORT_COUNT > 0 - PORT_MASK_PAIR(GPIO_USB_C0_5V_EN), - PORT_MASK_PAIR(GPIO_USB_C0_CHARGE_EN_L), + GPIO_TO_PORT_MASK_PAIR(GPIO_USB_C0_5V_EN), + GPIO_TO_PORT_MASK_PAIR(GPIO_USB_C0_CHARGE_EN_L), #endif #if CONFIG_USB_PD_PORT_COUNT > 1 - PORT_MASK_PAIR(GPIO_USB_C1_5V_EN), - PORT_MASK_PAIR(GPIO_USB_C1_CHARGE_EN_L), + GPIO_TO_PORT_MASK_PAIR(GPIO_USB_C1_5V_EN), + GPIO_TO_PORT_MASK_PAIR(GPIO_USB_C1_CHARGE_EN_L), #endif #endif /* CONFIG_USB_PD_PORT_COUNT */ @@ -233,29 +219,42 @@ static void system_set_gpio_power(int enabled, uint32_t *backup_gpio_ctl) {20, 5}, }; + for (i = 0; i < ARRAY_SIZE(skip); ++i) + if (port == skip[i][0] && pin == skip[i][1]) + return 0; + + if (board_get_gpio_hibernate_state) + return board_get_gpio_hibernate_state(port, pin); + else + return GPIO_INPUT | GPIO_PULL_UP; +} + +static void system_set_gpio_power(int enabled, uint32_t *backup_gpio_ctl) +{ + int i, j; + uint32_t port, flags; + + const int pins[][2] = { + {0, 7}, {1, 7}, {2, 7}, {3, 6}, {4, 7}, {5, 7}, + {6, 7}, {10, 7}, {11, 7}, {12, 7}, {13, 6}, + {14, 7}, {15, 7}, {16, 5}, {20, 6}, {21, 1} + }; + for (i = 0; i < ARRAY_SIZE(pins); ++i) { + port = pins[i][0]; for (j = 0; j <= pins[i][1]; ++j) { - want_skip = 0; - for (k = 0; k < ARRAY_SIZE(skip); ++k) - if (skip[k][0] == pins[i][0] && - skip[k][1] == j) - want_skip = 1; - if (want_skip) + flags = system_get_gpio_hibernate_state(port, j); + if (flags == 0) continue; if (enabled) { - MEC1322_GPIO_CTL(pins[i][0], j) = + MEC1322_GPIO_CTL(port, j) = backup_gpio_ctl[i * 8 + j]; } else { - /* GPIO Input, pull-high, interrupt disabled */ - val = MEC1322_GPIO_CTL(pins[i][0], j); if (backup_gpio_ctl != NULL) - backup_gpio_ctl[i * 8 + j] = val; - val &= ~((1 << 12) | (1 << 13)); - val &= ~(1 << 9); - val = (val & ~(0xf << 4)) | (0x4 << 4); - val = (val & ~0x3) | 0x1; - MEC1322_GPIO_CTL(pins[i][0], j) = val; + backup_gpio_ctl[i * 8 + j] = + MEC1322_GPIO_CTL(port, j); + gpio_set_flags_by_mask(port, 1 << j, flags); } } } diff --git a/include/gpio.h b/include/gpio.h index 5ffb1bd0ab..2e7555d241 100644 --- a/include/gpio.h +++ b/include/gpio.h @@ -49,6 +49,11 @@ /* Convert GPIO mask to GPIO number / index. */ #define GPIO_MASK_TO_NUM(mask) (31 - __builtin_clz(mask)) +/* Convert a GPIO to a port + mask pair */ +#define GPIO_TO_PORT_MASK_PAIR(gpio) \ + { gpio_list[(gpio)].port, \ + GPIO_MASK_TO_NUM(gpio_list[(gpio)].mask) } + /* NOTE: This is normally included from board.h, thru config.h and common.h But, * some boards and unit tests don't have a gpio_signal enum defined, so we * define an emtpy one here.*/ |