nyan: supports immediate 'power off'.

Poll down AP_RESET_L pin to shutdown AP immediately, instead of
press the power button for 8 secs.

BRANCH=nyan
BUG=chrome-os-partner:23895
TEST=verified on nyan board 2.0 with follwoing tests:
    power off / power on: PASS. Tested 5+ times.
    lid close / power off / lid open: PASS. Tested 5+ times.
    button on / off: PASS. Test 5+ times. ~20% not boot (HOLD=1).
    power off / button on: PASS. Tested 5+ times.
    button off / power on: PASS. Test 5+ times. ~60% not boot (HOLD=1)
    button off / lid open: PASS. Test 5+ times. ~40% not boot (HOLD=1)

Change-Id: Iecc97f38ac7bd923745994594356029836d7b4e6
Signed-off-by: Louis Yung-Chieh Lo <yjlou@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/177241
This commit is contained in:
Louis Yung-Chieh Lo
2013-11-15 15:49:56 -08:00
committed by chrome-internal-fetch
parent 02995b2d6f
commit 082d8b2e2d

View File

@@ -143,6 +143,18 @@ static void set_pmic_pwrok(int asserted)
gpio_set_level(GPIO_PMIC_PWRON_L, asserted ? 0 : 1);
}
/**
* Set the AP RESET signal.
*
* @param asserted Assert (=1) or deassert (=0) the signal. This is the
* logical level of the pin, not the physical level.
*/
static void set_ap_reset(int asserted)
{
/* Signal is active-low */
gpio_set_level(GPIO_AP_RESET_L, asserted ? 0 : 1);
}
/**
* Check for some event triggering the shutdown.
*
@@ -158,19 +170,14 @@ static int check_for_power_off_event(void)
/*
* Check for power button press.
*
* If power_request is POWER_REQ_OFF, simulate the requst as power
* button is pressed. This will casue GPIO_PMIC_PWRON_L to be driven
* low (by set_pmic_pwrok(1)) until PMIC automatically turns off power.
* (PMIC turns off power if GPIO_PMIC_PWRON_L is low for >=9 seconds.)
*/
if (gpio_get_level(GPIO_KB_PWR_ON_L) == 0) {
udelay(KB_PWR_ON_DEBOUNCE);
if (gpio_get_level(GPIO_KB_PWR_ON_L) == 0)
pressed = 1;
} else if (power_request == POWER_REQ_OFF) {
pressed = 1;
power_request = POWER_REQ_NONE;
return 4; /* return non-zero for shudown down */
}
#ifdef HAS_TASK_KEYSCAN
@@ -334,6 +341,10 @@ void chipset_reset(int is_cold)
void chipset_force_shutdown(void)
{
/* Assert AP reset to shutdown immediately */
set_ap_reset(1);
/* Release the power button, if it was asserted */
set_pmic_pwrok(0);
}
@@ -349,8 +360,13 @@ void chipset_force_shutdown(void)
*/
static int check_for_power_on_event(void)
{
/* check if system is already ON */
if (gpio_get_level(GPIO_SOC1V8_XPSHOLD)) {
/*
* check if system is already ON:
* 1. XPSHOLD is high (power is supplied), and
* 2. AP_RESET_L is high (not a force shutdown).
*/
if (gpio_get_level(GPIO_SOC1V8_XPSHOLD) &&
gpio_get_level(GPIO_AP_RESET_L)) {
CPRINTF("[%T system is on, thus clear auto_power_on]\n");
auto_power_on = 0; /* no need to arrange another power on */
return 1;
@@ -390,11 +406,14 @@ static int check_for_power_on_event(void)
*/
static int power_on(void)
{
gpio_set_level(GPIO_AP_RESET_L, 1);
/* Make sure we de-assert the AP_RESET_L pin. */
set_ap_reset(0);
/* Push the power button */
set_pmic_pwrok(1);
if (gpio_get_level(GPIO_SOC1V8_XPSHOLD) == 0)
/* Initialize non-AP components */
/* Initialize non-AP components if the AP is off. */
if (!ap_on)
hook_notify(HOOK_CHIPSET_PRE_INIT);
ap_on = 1;