Merge pull request #27 from system76/wip/wake-s3

Wake from S3 using any key
This commit is contained in:
Jeremy Soller 2020-02-24 09:00:43 -07:00 committed by GitHub
commit ce3a097b9b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 120 additions and 72 deletions

View File

@ -1,6 +1,17 @@
#ifndef _BOARD_POWER_H
#define _BOARD_POWER_H
enum PowerState {
POWER_STATE_DEFAULT,
POWER_STATE_DS5,
POWER_STATE_S5,
POWER_STATE_DS3,
POWER_STATE_S3,
POWER_STATE_S0,
};
extern enum PowerState power_state;
void power_event(void);
#endif // _BOARD_POWER_H

View File

@ -5,6 +5,7 @@
#include <board/kbscan.h>
#include <board/keymap.h>
#include <board/pmc.h>
#include <board/power.h>
#include <common/debug.h>
bool kbscan_enabled = false;
@ -29,6 +30,13 @@ void kbscan_init(void) {
#define DEBOUNCE_DELAY 20
bool kbscan_press(uint16_t key, bool pressed, uint8_t * layer) {
if (pressed &&
(power_state == POWER_STATE_S3 || power_state == POWER_STATE_DS3)) {
gpio_set(&SWI_N, false);
delay_ticks(10); //TODO: find correct delay
gpio_set(&SWI_N, true);
}
switch (key & KT_MASK) {
case (KT_NORMAL):
if (kbscan_enabled) {

View File

@ -63,7 +63,7 @@ void pmc_event(struct Pmc * pmc) {
if (sts & PMC_STS_IBF) {
uint8_t data = pmc_read(pmc);
if (sts & PMC_STS_CMD) {
DEBUG("pmc cmd: %02X\n", data);
TRACE("pmc cmd: %02X\n", data);
state = PMC_STATE_DEFAULT;
switch (data) {
@ -78,7 +78,7 @@ void pmc_event(struct Pmc * pmc) {
pmc_sci_interrupt();
break;
case 0x82:
DEBUG(" burst enable\n");
TRACE(" burst enable\n");
// Set burst bit
pmc_set_status(pmc, sts | (1 << 4));
// Send acknowledgement byte
@ -86,14 +86,14 @@ void pmc_event(struct Pmc * pmc) {
state_data = 0x90;
break;
case 0x83:
DEBUG(" burst disable\n");
TRACE(" burst disable\n");
// Clear burst bit
pmc_set_status(pmc, sts & ~(1 << 4));
// Send SCI for IBF=0
pmc_sci_interrupt();
break;
case 0x84:
DEBUG(" SCI queue\n");
TRACE(" SCI queue\n");
// Clear SCI pending bit
pmc_set_status(pmc, sts & ~(1 << 5));
// Send SCI queue
@ -104,13 +104,13 @@ void pmc_event(struct Pmc * pmc) {
break;
case 0xEC:
DEBUG(" scratch rom\n");
TRACE(" scratch rom\n");
pmc_write(pmc, 0x76);
scratch_trampoline();
break;
}
} else {
DEBUG("pmc data: %02X\n", data);
TRACE("pmc data: %02X\n", data);
switch (state) {
case PMC_STATE_ACPI_READ:
@ -141,7 +141,7 @@ void pmc_event(struct Pmc * pmc) {
if (!(sts & PMC_STS_OBF)) {
switch (state) {
case PMC_STATE_WRITE:
DEBUG("pmc write: %02X\n", state_data);
TRACE("pmc write: %02X\n", state_data);
state = PMC_STATE_DEFAULT;
pmc_write(pmc, state_data);
// Send SCI for OBF=1

View File

@ -51,6 +51,8 @@ extern uint8_t main_cycle;
// RSMRST# de-assertion to SUSPWRDNACK valid
#define tPLT01 delay_ms(200)
enum PowerState power_state = POWER_STATE_DEFAULT;
// Enable deep sleep well power
void power_on_ds5() {
DEBUG("%02X: power_on_ds5\n", main_cycle);
@ -80,6 +82,8 @@ void power_on_ds5() {
// tPCH04 is the ideal delay
tPCH04;
#endif // DEEP_SX
power_state = POWER_STATE_DS5;
}
// Enable S5 power
@ -126,6 +130,8 @@ void power_on_s5() {
// Extra wait - TODO remove
delay_ms(200);
#endif // DEEP_SX
power_state = POWER_STATE_S5;
}
void power_off_s5() {
@ -157,24 +163,14 @@ void power_off_s5() {
gpio_set(&PCH_DPWROK_EC, false);
tPCH14;
#endif // DEEP_SX
power_state = POWER_STATE_DS5;
}
enum PowerState {
POWER_STATE_DEFAULT,
POWER_STATE_DS5,
POWER_STATE_S5,
POWER_STATE_DS3,
POWER_STATE_S3,
POWER_STATE_S0,
};
void power_event(void) {
static enum PowerState state = POWER_STATE_DEFAULT;
// Always switch to ds5 if EC is running
if (state == POWER_STATE_DEFAULT) {
if (power_state == POWER_STATE_DEFAULT) {
power_on_ds5();
state = POWER_STATE_DS5;
}
// Check if the adapter line goes low
@ -223,9 +219,8 @@ void power_event(void) {
DEBUG("%02X: Power switch press\n", main_cycle);
// Enable S5 power if necessary, before sending PWR_BTN
if (state == POWER_STATE_DS5) {
if (power_state == POWER_STATE_DS5) {
power_on_s5();
state = POWER_STATE_S5;
}
}
}
@ -286,6 +281,8 @@ void power_event(void) {
//TODO: reset KBC and touchpad states
kbled_reset();
power_state = POWER_STATE_S0;
}
rst_last = rst_new;
@ -331,9 +328,9 @@ void power_event(void) {
if (s4_new) {
DEBUG("%02X: entering S3 state\n", main_cycle);
} else if (state == POWER_STATE_S5) {
power_state = POWER_STATE_S3;
} else if (power_state == POWER_STATE_S5) {
power_off_s5();
state = POWER_STATE_DS5;
}
}
#if LEVEL >= LEVEL_DEBUG

View File

@ -1,6 +1,17 @@
#ifndef _BOARD_POWER_H
#define _BOARD_POWER_H
enum PowerState {
POWER_STATE_DEFAULT,
POWER_STATE_DS5,
POWER_STATE_S5,
POWER_STATE_DS3,
POWER_STATE_S3,
POWER_STATE_S0,
};
extern enum PowerState power_state;
void power_event(void);
#endif // _BOARD_POWER_H

View File

@ -6,6 +6,7 @@
#include <board/kbscan.h>
#include <board/keymap.h>
#include <board/pmc.h>
#include <board/power.h>
#include <common/debug.h>
bool kbscan_enabled = false;
@ -30,6 +31,13 @@ void kbscan_init(void) {
#define DEBOUNCE_DELAY 20
bool kbscan_press(uint16_t key, bool pressed, uint8_t * layer) {
if (pressed &&
(power_state == POWER_STATE_S3 || power_state == POWER_STATE_DS3)) {
gpio_set(&SWI_N, false);
delay_ticks(10); //TODO: find correct delay
gpio_set(&SWI_N, true);
}
switch (key & KT_MASK) {
case (KT_NORMAL):
if (kbscan_enabled) {

View File

@ -63,7 +63,7 @@ void pmc_event(struct Pmc * pmc) {
if (sts & PMC_STS_IBF) {
uint8_t data = pmc_read(pmc);
if (sts & PMC_STS_CMD) {
DEBUG("pmc cmd: %02X\n", data);
TRACE("pmc cmd: %02X\n", data);
state = PMC_STATE_DEFAULT;
switch (data) {
@ -78,7 +78,7 @@ void pmc_event(struct Pmc * pmc) {
pmc_sci_interrupt();
break;
case 0x82:
DEBUG(" burst enable\n");
TRACE(" burst enable\n");
// Set burst bit
pmc_set_status(pmc, sts | (1 << 4));
// Send acknowledgement byte
@ -86,14 +86,14 @@ void pmc_event(struct Pmc * pmc) {
state_data = 0x90;
break;
case 0x83:
DEBUG(" burst disable\n");
TRACE(" burst disable\n");
// Clear burst bit
pmc_set_status(pmc, sts & ~(1 << 4));
// Send SCI for IBF=0
pmc_sci_interrupt();
break;
case 0x84:
DEBUG(" SCI queue\n");
TRACE(" SCI queue\n");
// Clear SCI pending bit
pmc_set_status(pmc, sts & ~(1 << 5));
// Send SCI queue
@ -104,13 +104,13 @@ void pmc_event(struct Pmc * pmc) {
break;
case 0xEC:
DEBUG(" scratch rom\n");
TRACE(" scratch rom\n");
pmc_write(pmc, 0x76);
scratch_trampoline();
break;
}
} else {
DEBUG("pmc data: %02X\n", data);
TRACE("pmc data: %02X\n", data);
switch (state) {
case PMC_STATE_ACPI_READ:
@ -141,7 +141,7 @@ void pmc_event(struct Pmc * pmc) {
if (!(sts & PMC_STS_OBF)) {
switch (state) {
case PMC_STATE_WRITE:
DEBUG("pmc write: %02X\n", state_data);
TRACE("pmc write: %02X\n", state_data);
state = PMC_STATE_DEFAULT;
pmc_write(pmc, state_data);
// Send SCI for OBF=1

View File

@ -50,6 +50,8 @@ extern uint8_t main_cycle;
// RSMRST# de-assertion to SUSPWRDNACK valid
#define tPLT01 delay_ms(200)
enum PowerState power_state = POWER_STATE_DEFAULT;
// Enable deep sleep well power
void power_on_ds5() {
DEBUG("%02X: power_on_ds5\n", main_cycle);
@ -79,6 +81,8 @@ void power_on_ds5() {
// tPCH04 is the ideal delay
tPCH04;
#endif // DEEP_SX
power_state = POWER_STATE_DS5;
}
// Enable S5 power
@ -125,6 +129,8 @@ void power_on_s5() {
// Extra wait - TODO remove
delay_ms(200);
#endif // DEEP_SX
power_state = POWER_STATE_S5;
}
void power_off_s5() {
@ -156,24 +162,14 @@ void power_off_s5() {
gpio_set(&PCH_DPWROK_EC, false);
tPCH14;
#endif // DEEP_SX
power_state = POWER_STATE_DS5;
}
enum PowerState {
POWER_STATE_DEFAULT,
POWER_STATE_DS5,
POWER_STATE_S5,
POWER_STATE_DS3,
POWER_STATE_S3,
POWER_STATE_S0,
};
void power_event(void) {
static enum PowerState state = POWER_STATE_DEFAULT;
// Always switch to ds5 if EC is running
if (state == POWER_STATE_DEFAULT) {
if (power_state == POWER_STATE_DEFAULT) {
power_on_ds5();
state = POWER_STATE_DS5;
}
// Check if the adapter line goes low
@ -222,9 +218,8 @@ void power_event(void) {
DEBUG("%02X: Power switch press\n", main_cycle);
// Enable S5 power if necessary, before sending PWR_BTN
if (state == POWER_STATE_DS5) {
if (power_state == POWER_STATE_DS5) {
power_on_s5();
state = POWER_STATE_S5;
}
}
}
@ -283,6 +278,8 @@ void power_event(void) {
// LPC was just reset, enable PNP devices
pnp_enable();
//TODO: reset KBC and touchpad states
power_state = POWER_STATE_S0;
}
rst_last = rst_new;
@ -328,9 +325,9 @@ void power_event(void) {
if (s4_new) {
DEBUG("%02X: entering S3 state\n", main_cycle);
} else if (state == POWER_STATE_S5) {
power_state = POWER_STATE_S3;
} else if (power_state == POWER_STATE_S5) {
power_off_s5();
state = POWER_STATE_DS5;
}
}
#if LEVEL >= LEVEL_DEBUG

View File

@ -1,6 +1,17 @@
#ifndef _BOARD_POWER_H
#define _BOARD_POWER_H
enum PowerState {
POWER_STATE_DEFAULT,
POWER_STATE_DS5,
POWER_STATE_S5,
POWER_STATE_DS3,
POWER_STATE_S3,
POWER_STATE_S0,
};
extern enum PowerState power_state;
void power_event(void);
#endif // _BOARD_POWER_H

View File

@ -6,6 +6,7 @@
#include <board/kbscan.h>
#include <board/keymap.h>
#include <board/pmc.h>
#include <board/power.h>
#include <common/debug.h>
bool kbscan_enabled = false;
@ -30,6 +31,13 @@ void kbscan_init(void) {
#define DEBOUNCE_DELAY 20
bool kbscan_press(uint16_t key, bool pressed, uint8_t * layer) {
if (pressed &&
(power_state == POWER_STATE_S3 || power_state == POWER_STATE_DS3)) {
gpio_set(&SWI_N, false);
delay_ticks(10); //TODO: find correct delay
gpio_set(&SWI_N, true);
}
switch (key & KT_MASK) {
case (KT_NORMAL):
if (kbscan_enabled) {

View File

@ -63,7 +63,7 @@ void pmc_event(struct Pmc * pmc) {
if (sts & PMC_STS_IBF) {
uint8_t data = pmc_read(pmc);
if (sts & PMC_STS_CMD) {
DEBUG("pmc cmd: %02X\n", data);
TRACE("pmc cmd: %02X\n", data);
state = PMC_STATE_DEFAULT;
switch (data) {
@ -78,7 +78,7 @@ void pmc_event(struct Pmc * pmc) {
pmc_sci_interrupt();
break;
case 0x82:
DEBUG(" burst enable\n");
TRACE(" burst enable\n");
// Set burst bit
pmc_set_status(pmc, sts | (1 << 4));
// Send acknowledgement byte
@ -86,14 +86,14 @@ void pmc_event(struct Pmc * pmc) {
state_data = 0x90;
break;
case 0x83:
DEBUG(" burst disable\n");
TRACE(" burst disable\n");
// Clear burst bit
pmc_set_status(pmc, sts & ~(1 << 4));
// Send SCI for IBF=0
pmc_sci_interrupt();
break;
case 0x84:
DEBUG(" SCI queue\n");
TRACE(" SCI queue\n");
// Clear SCI pending bit
pmc_set_status(pmc, sts & ~(1 << 5));
// Send SCI queue
@ -104,13 +104,13 @@ void pmc_event(struct Pmc * pmc) {
break;
case 0xEC:
DEBUG(" scratch rom\n");
TRACE(" scratch rom\n");
pmc_write(pmc, 0x76);
scratch_trampoline();
break;
}
} else {
DEBUG("pmc data: %02X\n", data);
TRACE("pmc data: %02X\n", data);
switch (state) {
case PMC_STATE_ACPI_READ:
@ -141,7 +141,7 @@ void pmc_event(struct Pmc * pmc) {
if (!(sts & PMC_STS_OBF)) {
switch (state) {
case PMC_STATE_WRITE:
DEBUG("pmc write: %02X\n", state_data);
TRACE("pmc write: %02X\n", state_data);
state = PMC_STATE_DEFAULT;
pmc_write(pmc, state_data);
// Send SCI for OBF=1

View File

@ -50,6 +50,8 @@ extern uint8_t main_cycle;
// RSMRST# de-assertion to SUSPWRDNACK valid
#define tPLT01 delay_ms(200)
enum PowerState power_state = POWER_STATE_DEFAULT;
// Enable deep sleep well power
void power_on_ds5() {
DEBUG("%02X: power_on_ds5\n", main_cycle);
@ -79,6 +81,8 @@ void power_on_ds5() {
// tPCH04 is the ideal delay
tPCH04;
#endif // DEEP_SX
power_state = POWER_STATE_DS5;
}
// Enable S5 power
@ -151,6 +155,8 @@ void power_on_s5() {
// Extra wait - TODO remove
delay_ms(200);
#endif // DEEP_SX
power_state = POWER_STATE_S5;
}
void power_off_s5() {
@ -182,24 +188,14 @@ void power_off_s5() {
gpio_set(&PCH_DPWROK_EC, false);
tPCH14;
#endif // DEEP_SX
power_state = POWER_STATE_DS5;
}
enum PowerState {
POWER_STATE_DEFAULT,
POWER_STATE_DS5,
POWER_STATE_S5,
POWER_STATE_DS3,
POWER_STATE_S3,
POWER_STATE_S0,
};
void power_event(void) {
static enum PowerState state = POWER_STATE_DEFAULT;
// Always switch to ds5 if EC is running
if (state == POWER_STATE_DEFAULT) {
if (power_state == POWER_STATE_DEFAULT) {
power_on_ds5();
state = POWER_STATE_DS5;
}
// Check if the adapter line goes low
@ -248,9 +244,8 @@ void power_event(void) {
DEBUG("%02X: Power switch press\n", main_cycle);
// Enable S5 power if necessary, before sending PWR_BTN
if (state == POWER_STATE_DS5) {
if (power_state == POWER_STATE_DS5) {
power_on_s5();
state = POWER_STATE_S5;
}
}
}
@ -309,6 +304,8 @@ void power_event(void) {
// LPC was just reset, enable PNP devices
pnp_enable();
//TODO: reset KBC and touchpad states
power_state = POWER_STATE_S0;
}
rst_last = rst_new;
@ -354,9 +351,9 @@ void power_event(void) {
if (s4_new) {
DEBUG("%02X: entering S3 state\n", main_cycle);
} else if (state == POWER_STATE_S5) {
power_state = POWER_STATE_S3;
} else if (power_state == POWER_STATE_S5) {
power_off_s5();
state = POWER_STATE_DS5;
}
}
#if LEVEL >= LEVEL_DEBUG