Merge pull request #27 from system76/wip/wake-s3
Wake from S3 using any key
This commit is contained in:
commit
ce3a097b9b
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user