summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShawn Nematbakhsh <shawnn@chromium.org>2015-08-10 15:26:03 -0700
committerChromeOS Commit Bot <chromeos-commit-bot@chromium.org>2015-08-11 21:21:28 +0000
commit5b93f04c195675c8ad093bd2c36c85088e68ab74 (patch)
treea307cc07989047b263dee827e9b4317a16a80b43
parentfba4f335a9a78f4112980fcf1cc36d44cfda0406 (diff)
downloadchrome-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.h7
-rw-r--r--chip/mec1322/system.c73
-rw-r--r--include/gpio.h5
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.*/