From 990c8b39e1134bef2599dfc1402bc24b54a7e824 Mon Sep 17 00:00:00 2001 From: Randall Spangler Date: Mon, 21 May 2012 16:20:33 -0700 Subject: Disable touchscreen when lid is closed and in S3 (Touchscreen was already disabled in S5) Signed-off-by: Randall Spangler BUG=chrome-os-partner:9736 TEST=from console, 'gpioget touchscreen_resetn' in these cases: 1) system is off -> 0 2) system is on with lid open -> 1 3) system is on with lid closed -> 1 4) system is suspended with lid open -> 1 5) system is suspended with lid closed -> 1 6) system is shut back down -> 0 7) suspend system with lid open, THEN close lid -> 0 Change-Id: I5fc80b72ea9dcfbf11f5280d79ae805c2ef1b6df --- chip/lm4/power_button.c | 8 ++++++ common/hooks.c | 1 + common/x86_power.c | 63 ++++++++++++++++++++++++++++++++--------------- core/cortex-m/ec.lds.S | 4 +++ core/cortex-m/link_defs.h | 2 ++ include/hooks.h | 2 ++ include/power_button.h | 4 +++ 7 files changed, 64 insertions(+), 20 deletions(-) diff --git a/chip/lm4/power_button.c b/chip/lm4/power_button.c index 45ef06cde9..66505d3e59 100644 --- a/chip/lm4/power_button.c +++ b/chip/lm4/power_button.c @@ -215,6 +215,7 @@ static void lid_switch_open(uint64_t tnow) debounced_lid_open = 1; *memmap_switches |= EC_SWITCH_LID_OPEN; lpc_set_host_events(EC_HOST_EVENT_MASK(EC_HOST_EVENT_LID_OPEN)); + hook_notify(HOOK_LID_CHANGE, 0); /* If the chipset is off, send a power button pulse to wake up the * chipset. */ @@ -239,6 +240,7 @@ static void lid_switch_close(uint64_t tnow) CPRINTF("[%T PB lid close]\n"); debounced_lid_open = 0; *memmap_switches &= ~EC_SWITCH_LID_OPEN; + hook_notify(HOOK_LID_CHANGE, 0); lpc_set_host_events(EC_HOST_EVENT_MASK(EC_HOST_EVENT_LID_CLOSED)); } @@ -337,6 +339,12 @@ int power_ac_present(void) return gpio_get_level(GPIO_AC_PRESENT); } + +int power_lid_open_debounced(void) +{ + return debounced_lid_open; +} + /*****************************************************************************/ /* Task / state machine */ diff --git a/common/hooks.c b/common/hooks.c index 2ef5310970..30154a1060 100644 --- a/common/hooks.c +++ b/common/hooks.c @@ -25,6 +25,7 @@ static const struct hook_ptrs hook_list[] = { {__hooks_chipset_suspend, __hooks_chipset_suspend_end}, {__hooks_chipset_shutdown, __hooks_chipset_shutdown_end}, {__hooks_ac_change, __hooks_ac_change_end}, + {__hooks_lid_change, __hooks_lid_change_end}, }; diff --git a/common/x86_power.c b/common/x86_power.c index 6f318abeba..9f1fd175d5 100644 --- a/common/x86_power.c +++ b/common/x86_power.c @@ -211,22 +211,6 @@ void x86_power_reset(int cold_reset) } } - -/* Hook notified when AC state changes. */ -static int x86_power_ac_change(void) -{ - if (power_ac_present()) { - CPRINTF("[%T x86 AC on]\n"); - /* TODO: (crosbug.com/p/9609) re-enable turbo? */ - } else { - CPRINTF("[%T x86 AC off]\n"); - /* TODO: (crosbug.com/p/9609) disable turbo */ - } - - return EC_SUCCESS; -} -DECLARE_HOOK(HOOK_AC_CHANGE, x86_power_ac_change, HOOK_PRIO_DEFAULT); - /*****************************************************************************/ /* Chipset interface */ @@ -292,6 +276,34 @@ void chipset_throttle_cpu(int throttle) gpio_set_level(GPIO_CPU_PROCHOT, throttle); } +/*****************************************************************************/ +/* Hooks */ + +/* Hook notified when lid state changes. */ +static int x86_lid_change(void) +{ + /* Wake up the task to update power state */ + task_wake(TASK_ID_X86POWER); + return EC_SUCCESS; +} +DECLARE_HOOK(HOOK_LID_CHANGE, x86_lid_change, HOOK_PRIO_DEFAULT); + + +/* Hook notified when AC state changes. */ +static int x86_power_ac_change(void) +{ + if (power_ac_present()) { + CPRINTF("[%T x86 AC on]\n"); + /* TODO: (crosbug.com/p/9609) re-enable turbo? */ + } else { + CPRINTF("[%T x86 AC off]\n"); + /* TODO: (crosbug.com/p/9609) disable turbo */ + } + + return EC_SUCCESS; +} +DECLARE_HOOK(HOOK_AC_CHANGE, x86_power_ac_change, HOOK_PRIO_DEFAULT); + /*****************************************************************************/ /* Interrupts */ @@ -403,6 +415,13 @@ void x86_power_task(void) break; case X86_S3: + /* If lid is closed; hold touchscreen in reset to cut + * power usage. If lid is open, take touchscreen out + * of reset so it can wake the processor. */ + gpio_set_level(GPIO_TOUCHSCREEN_RESETn, + power_lid_open_debounced()); + + /* Check for state transitions */ if (gpio_get_level(GPIO_PCH_SLP_S3n) == 1) { /* Power up to next state */ state = X86_S3S0; @@ -451,10 +470,9 @@ void x86_power_task(void) /* Wait for the always-on rails to be good */ wait_in_signals(IN_PGOOD_ALWAYS_ON); - /* Take touchscreen and lightbar out of reset, now - * that +5VALW is available and we won't leak +3VALW - * through the reset line. */ - gpio_set_level(GPIO_TOUCHSCREEN_RESETn, 1); + /* Take lightbar out of reset, now that +5VALW is + * available and we won't leak +3VALW through the reset + * line. */ gpio_set_level(GPIO_LIGHTBAR_RESETn, 1); /* Turn on power to RAM */ @@ -479,6 +497,11 @@ void x86_power_task(void) gpio_set_level(GPIO_RADIO_ENABLE_WLAN, 1); gpio_set_level(GPIO_RADIO_ENABLE_BT, 1); + /* Make sure touchscreen is out if reset (even if the + * lid is still closed); it may have been turned off if + * the lid was closed in S3. */ + gpio_set_level(GPIO_TOUCHSCREEN_RESETn, 1); + /* Wait for non-core power rails good */ wait_in_signals(IN_PGOOD_ALL_NONCORE); diff --git a/core/cortex-m/ec.lds.S b/core/cortex-m/ec.lds.S index 910b254f75..30a5446891 100644 --- a/core/cortex-m/ec.lds.S +++ b/core/cortex-m/ec.lds.S @@ -83,6 +83,10 @@ SECTIONS *(.rodata.HOOK_AC_CHANGE) __hooks_ac_change_end = .; + __hooks_lid_change = .; + *(.rodata.HOOK_LID_CHANGE) + __hooks_lid_change_end = .; + . = ALIGN(4); *(.rodata*) diff --git a/core/cortex-m/link_defs.h b/core/cortex-m/link_defs.h index ec6992d8ae..7f029ec667 100644 --- a/core/cortex-m/link_defs.h +++ b/core/cortex-m/link_defs.h @@ -34,6 +34,8 @@ extern const struct hook_data __hooks_chipset_shutdown[]; extern const struct hook_data __hooks_chipset_shutdown_end[]; extern const struct hook_data __hooks_ac_change[]; extern const struct hook_data __hooks_ac_change_end[]; +extern const struct hook_data __hooks_lid_change[]; +extern const struct hook_data __hooks_lid_change_end[]; /* Host commands */ extern const struct host_command __hcmds[]; diff --git a/include/hooks.h b/include/hooks.h index 16cf72d506..b27c52fc66 100644 --- a/include/hooks.h +++ b/include/hooks.h @@ -37,6 +37,8 @@ enum hook_type { HOOK_CHIPSET_SHUTDOWN, /* System is shutting down. All suspend rails * are still on. */ HOOK_AC_CHANGE, /* AC power plugged in or removed */ + HOOK_LID_CHANGE, /* Lid opened or closed. Based on debounced lid + * state, not raw lid GPIO input. */ }; diff --git a/include/power_button.h b/include/power_button.h index 7a2283da9b..3bdb8a639d 100644 --- a/include/power_button.h +++ b/include/power_button.h @@ -21,4 +21,8 @@ void power_button_task(void); /* Return non-zero if AC power is present. */ int power_ac_present(void); +/* Return non-zero if lid is open. Uses the debounced lid state, not the raw + * signal from the GPIO. */ +int power_lid_open_debounced(void); + #endif /* __CROS_EC_POWER_BUTTON_H */ -- cgit v1.2.1