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
|
#ifndef _BOARD_POWER_H
|
||||||
#define _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);
|
void power_event(void);
|
||||||
|
|
||||||
#endif // _BOARD_POWER_H
|
#endif // _BOARD_POWER_H
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include <board/kbscan.h>
|
#include <board/kbscan.h>
|
||||||
#include <board/keymap.h>
|
#include <board/keymap.h>
|
||||||
#include <board/pmc.h>
|
#include <board/pmc.h>
|
||||||
|
#include <board/power.h>
|
||||||
#include <common/debug.h>
|
#include <common/debug.h>
|
||||||
|
|
||||||
bool kbscan_enabled = false;
|
bool kbscan_enabled = false;
|
||||||
@ -29,6 +30,13 @@ void kbscan_init(void) {
|
|||||||
#define DEBOUNCE_DELAY 20
|
#define DEBOUNCE_DELAY 20
|
||||||
|
|
||||||
bool kbscan_press(uint16_t key, bool pressed, uint8_t * layer) {
|
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) {
|
switch (key & KT_MASK) {
|
||||||
case (KT_NORMAL):
|
case (KT_NORMAL):
|
||||||
if (kbscan_enabled) {
|
if (kbscan_enabled) {
|
||||||
|
@ -63,7 +63,7 @@ void pmc_event(struct Pmc * pmc) {
|
|||||||
if (sts & PMC_STS_IBF) {
|
if (sts & PMC_STS_IBF) {
|
||||||
uint8_t data = pmc_read(pmc);
|
uint8_t data = pmc_read(pmc);
|
||||||
if (sts & PMC_STS_CMD) {
|
if (sts & PMC_STS_CMD) {
|
||||||
DEBUG("pmc cmd: %02X\n", data);
|
TRACE("pmc cmd: %02X\n", data);
|
||||||
|
|
||||||
state = PMC_STATE_DEFAULT;
|
state = PMC_STATE_DEFAULT;
|
||||||
switch (data) {
|
switch (data) {
|
||||||
@ -78,7 +78,7 @@ void pmc_event(struct Pmc * pmc) {
|
|||||||
pmc_sci_interrupt();
|
pmc_sci_interrupt();
|
||||||
break;
|
break;
|
||||||
case 0x82:
|
case 0x82:
|
||||||
DEBUG(" burst enable\n");
|
TRACE(" burst enable\n");
|
||||||
// Set burst bit
|
// Set burst bit
|
||||||
pmc_set_status(pmc, sts | (1 << 4));
|
pmc_set_status(pmc, sts | (1 << 4));
|
||||||
// Send acknowledgement byte
|
// Send acknowledgement byte
|
||||||
@ -86,14 +86,14 @@ void pmc_event(struct Pmc * pmc) {
|
|||||||
state_data = 0x90;
|
state_data = 0x90;
|
||||||
break;
|
break;
|
||||||
case 0x83:
|
case 0x83:
|
||||||
DEBUG(" burst disable\n");
|
TRACE(" burst disable\n");
|
||||||
// Clear burst bit
|
// Clear burst bit
|
||||||
pmc_set_status(pmc, sts & ~(1 << 4));
|
pmc_set_status(pmc, sts & ~(1 << 4));
|
||||||
// Send SCI for IBF=0
|
// Send SCI for IBF=0
|
||||||
pmc_sci_interrupt();
|
pmc_sci_interrupt();
|
||||||
break;
|
break;
|
||||||
case 0x84:
|
case 0x84:
|
||||||
DEBUG(" SCI queue\n");
|
TRACE(" SCI queue\n");
|
||||||
// Clear SCI pending bit
|
// Clear SCI pending bit
|
||||||
pmc_set_status(pmc, sts & ~(1 << 5));
|
pmc_set_status(pmc, sts & ~(1 << 5));
|
||||||
// Send SCI queue
|
// Send SCI queue
|
||||||
@ -104,13 +104,13 @@ void pmc_event(struct Pmc * pmc) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xEC:
|
case 0xEC:
|
||||||
DEBUG(" scratch rom\n");
|
TRACE(" scratch rom\n");
|
||||||
pmc_write(pmc, 0x76);
|
pmc_write(pmc, 0x76);
|
||||||
scratch_trampoline();
|
scratch_trampoline();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
DEBUG("pmc data: %02X\n", data);
|
TRACE("pmc data: %02X\n", data);
|
||||||
|
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case PMC_STATE_ACPI_READ:
|
case PMC_STATE_ACPI_READ:
|
||||||
@ -141,7 +141,7 @@ void pmc_event(struct Pmc * pmc) {
|
|||||||
if (!(sts & PMC_STS_OBF)) {
|
if (!(sts & PMC_STS_OBF)) {
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case PMC_STATE_WRITE:
|
case PMC_STATE_WRITE:
|
||||||
DEBUG("pmc write: %02X\n", state_data);
|
TRACE("pmc write: %02X\n", state_data);
|
||||||
state = PMC_STATE_DEFAULT;
|
state = PMC_STATE_DEFAULT;
|
||||||
pmc_write(pmc, state_data);
|
pmc_write(pmc, state_data);
|
||||||
// Send SCI for OBF=1
|
// Send SCI for OBF=1
|
||||||
|
@ -51,6 +51,8 @@ extern uint8_t main_cycle;
|
|||||||
// RSMRST# de-assertion to SUSPWRDNACK valid
|
// RSMRST# de-assertion to SUSPWRDNACK valid
|
||||||
#define tPLT01 delay_ms(200)
|
#define tPLT01 delay_ms(200)
|
||||||
|
|
||||||
|
enum PowerState power_state = POWER_STATE_DEFAULT;
|
||||||
|
|
||||||
// Enable deep sleep well power
|
// Enable deep sleep well power
|
||||||
void power_on_ds5() {
|
void power_on_ds5() {
|
||||||
DEBUG("%02X: power_on_ds5\n", main_cycle);
|
DEBUG("%02X: power_on_ds5\n", main_cycle);
|
||||||
@ -80,6 +82,8 @@ void power_on_ds5() {
|
|||||||
// tPCH04 is the ideal delay
|
// tPCH04 is the ideal delay
|
||||||
tPCH04;
|
tPCH04;
|
||||||
#endif // DEEP_SX
|
#endif // DEEP_SX
|
||||||
|
|
||||||
|
power_state = POWER_STATE_DS5;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enable S5 power
|
// Enable S5 power
|
||||||
@ -126,6 +130,8 @@ void power_on_s5() {
|
|||||||
// Extra wait - TODO remove
|
// Extra wait - TODO remove
|
||||||
delay_ms(200);
|
delay_ms(200);
|
||||||
#endif // DEEP_SX
|
#endif // DEEP_SX
|
||||||
|
|
||||||
|
power_state = POWER_STATE_S5;
|
||||||
}
|
}
|
||||||
|
|
||||||
void power_off_s5() {
|
void power_off_s5() {
|
||||||
@ -157,24 +163,14 @@ void power_off_s5() {
|
|||||||
gpio_set(&PCH_DPWROK_EC, false);
|
gpio_set(&PCH_DPWROK_EC, false);
|
||||||
tPCH14;
|
tPCH14;
|
||||||
#endif // DEEP_SX
|
#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) {
|
void power_event(void) {
|
||||||
static enum PowerState state = POWER_STATE_DEFAULT;
|
|
||||||
|
|
||||||
// Always switch to ds5 if EC is running
|
// Always switch to ds5 if EC is running
|
||||||
if (state == POWER_STATE_DEFAULT) {
|
if (power_state == POWER_STATE_DEFAULT) {
|
||||||
power_on_ds5();
|
power_on_ds5();
|
||||||
state = POWER_STATE_DS5;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the adapter line goes low
|
// Check if the adapter line goes low
|
||||||
@ -223,9 +219,8 @@ void power_event(void) {
|
|||||||
DEBUG("%02X: Power switch press\n", main_cycle);
|
DEBUG("%02X: Power switch press\n", main_cycle);
|
||||||
|
|
||||||
// Enable S5 power if necessary, before sending PWR_BTN
|
// Enable S5 power if necessary, before sending PWR_BTN
|
||||||
if (state == POWER_STATE_DS5) {
|
if (power_state == POWER_STATE_DS5) {
|
||||||
power_on_s5();
|
power_on_s5();
|
||||||
state = POWER_STATE_S5;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -286,6 +281,8 @@ void power_event(void) {
|
|||||||
//TODO: reset KBC and touchpad states
|
//TODO: reset KBC and touchpad states
|
||||||
|
|
||||||
kbled_reset();
|
kbled_reset();
|
||||||
|
|
||||||
|
power_state = POWER_STATE_S0;
|
||||||
}
|
}
|
||||||
rst_last = rst_new;
|
rst_last = rst_new;
|
||||||
|
|
||||||
@ -331,9 +328,9 @@ void power_event(void) {
|
|||||||
|
|
||||||
if (s4_new) {
|
if (s4_new) {
|
||||||
DEBUG("%02X: entering S3 state\n", main_cycle);
|
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();
|
power_off_s5();
|
||||||
state = POWER_STATE_DS5;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#if LEVEL >= LEVEL_DEBUG
|
#if LEVEL >= LEVEL_DEBUG
|
||||||
|
@ -1,6 +1,17 @@
|
|||||||
#ifndef _BOARD_POWER_H
|
#ifndef _BOARD_POWER_H
|
||||||
#define _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);
|
void power_event(void);
|
||||||
|
|
||||||
#endif // _BOARD_POWER_H
|
#endif // _BOARD_POWER_H
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#include <board/kbscan.h>
|
#include <board/kbscan.h>
|
||||||
#include <board/keymap.h>
|
#include <board/keymap.h>
|
||||||
#include <board/pmc.h>
|
#include <board/pmc.h>
|
||||||
|
#include <board/power.h>
|
||||||
#include <common/debug.h>
|
#include <common/debug.h>
|
||||||
|
|
||||||
bool kbscan_enabled = false;
|
bool kbscan_enabled = false;
|
||||||
@ -30,6 +31,13 @@ void kbscan_init(void) {
|
|||||||
#define DEBOUNCE_DELAY 20
|
#define DEBOUNCE_DELAY 20
|
||||||
|
|
||||||
bool kbscan_press(uint16_t key, bool pressed, uint8_t * layer) {
|
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) {
|
switch (key & KT_MASK) {
|
||||||
case (KT_NORMAL):
|
case (KT_NORMAL):
|
||||||
if (kbscan_enabled) {
|
if (kbscan_enabled) {
|
||||||
|
@ -63,7 +63,7 @@ void pmc_event(struct Pmc * pmc) {
|
|||||||
if (sts & PMC_STS_IBF) {
|
if (sts & PMC_STS_IBF) {
|
||||||
uint8_t data = pmc_read(pmc);
|
uint8_t data = pmc_read(pmc);
|
||||||
if (sts & PMC_STS_CMD) {
|
if (sts & PMC_STS_CMD) {
|
||||||
DEBUG("pmc cmd: %02X\n", data);
|
TRACE("pmc cmd: %02X\n", data);
|
||||||
|
|
||||||
state = PMC_STATE_DEFAULT;
|
state = PMC_STATE_DEFAULT;
|
||||||
switch (data) {
|
switch (data) {
|
||||||
@ -78,7 +78,7 @@ void pmc_event(struct Pmc * pmc) {
|
|||||||
pmc_sci_interrupt();
|
pmc_sci_interrupt();
|
||||||
break;
|
break;
|
||||||
case 0x82:
|
case 0x82:
|
||||||
DEBUG(" burst enable\n");
|
TRACE(" burst enable\n");
|
||||||
// Set burst bit
|
// Set burst bit
|
||||||
pmc_set_status(pmc, sts | (1 << 4));
|
pmc_set_status(pmc, sts | (1 << 4));
|
||||||
// Send acknowledgement byte
|
// Send acknowledgement byte
|
||||||
@ -86,14 +86,14 @@ void pmc_event(struct Pmc * pmc) {
|
|||||||
state_data = 0x90;
|
state_data = 0x90;
|
||||||
break;
|
break;
|
||||||
case 0x83:
|
case 0x83:
|
||||||
DEBUG(" burst disable\n");
|
TRACE(" burst disable\n");
|
||||||
// Clear burst bit
|
// Clear burst bit
|
||||||
pmc_set_status(pmc, sts & ~(1 << 4));
|
pmc_set_status(pmc, sts & ~(1 << 4));
|
||||||
// Send SCI for IBF=0
|
// Send SCI for IBF=0
|
||||||
pmc_sci_interrupt();
|
pmc_sci_interrupt();
|
||||||
break;
|
break;
|
||||||
case 0x84:
|
case 0x84:
|
||||||
DEBUG(" SCI queue\n");
|
TRACE(" SCI queue\n");
|
||||||
// Clear SCI pending bit
|
// Clear SCI pending bit
|
||||||
pmc_set_status(pmc, sts & ~(1 << 5));
|
pmc_set_status(pmc, sts & ~(1 << 5));
|
||||||
// Send SCI queue
|
// Send SCI queue
|
||||||
@ -104,13 +104,13 @@ void pmc_event(struct Pmc * pmc) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xEC:
|
case 0xEC:
|
||||||
DEBUG(" scratch rom\n");
|
TRACE(" scratch rom\n");
|
||||||
pmc_write(pmc, 0x76);
|
pmc_write(pmc, 0x76);
|
||||||
scratch_trampoline();
|
scratch_trampoline();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
DEBUG("pmc data: %02X\n", data);
|
TRACE("pmc data: %02X\n", data);
|
||||||
|
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case PMC_STATE_ACPI_READ:
|
case PMC_STATE_ACPI_READ:
|
||||||
@ -141,7 +141,7 @@ void pmc_event(struct Pmc * pmc) {
|
|||||||
if (!(sts & PMC_STS_OBF)) {
|
if (!(sts & PMC_STS_OBF)) {
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case PMC_STATE_WRITE:
|
case PMC_STATE_WRITE:
|
||||||
DEBUG("pmc write: %02X\n", state_data);
|
TRACE("pmc write: %02X\n", state_data);
|
||||||
state = PMC_STATE_DEFAULT;
|
state = PMC_STATE_DEFAULT;
|
||||||
pmc_write(pmc, state_data);
|
pmc_write(pmc, state_data);
|
||||||
// Send SCI for OBF=1
|
// Send SCI for OBF=1
|
||||||
|
@ -50,6 +50,8 @@ extern uint8_t main_cycle;
|
|||||||
// RSMRST# de-assertion to SUSPWRDNACK valid
|
// RSMRST# de-assertion to SUSPWRDNACK valid
|
||||||
#define tPLT01 delay_ms(200)
|
#define tPLT01 delay_ms(200)
|
||||||
|
|
||||||
|
enum PowerState power_state = POWER_STATE_DEFAULT;
|
||||||
|
|
||||||
// Enable deep sleep well power
|
// Enable deep sleep well power
|
||||||
void power_on_ds5() {
|
void power_on_ds5() {
|
||||||
DEBUG("%02X: power_on_ds5\n", main_cycle);
|
DEBUG("%02X: power_on_ds5\n", main_cycle);
|
||||||
@ -79,6 +81,8 @@ void power_on_ds5() {
|
|||||||
// tPCH04 is the ideal delay
|
// tPCH04 is the ideal delay
|
||||||
tPCH04;
|
tPCH04;
|
||||||
#endif // DEEP_SX
|
#endif // DEEP_SX
|
||||||
|
|
||||||
|
power_state = POWER_STATE_DS5;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enable S5 power
|
// Enable S5 power
|
||||||
@ -125,6 +129,8 @@ void power_on_s5() {
|
|||||||
// Extra wait - TODO remove
|
// Extra wait - TODO remove
|
||||||
delay_ms(200);
|
delay_ms(200);
|
||||||
#endif // DEEP_SX
|
#endif // DEEP_SX
|
||||||
|
|
||||||
|
power_state = POWER_STATE_S5;
|
||||||
}
|
}
|
||||||
|
|
||||||
void power_off_s5() {
|
void power_off_s5() {
|
||||||
@ -156,24 +162,14 @@ void power_off_s5() {
|
|||||||
gpio_set(&PCH_DPWROK_EC, false);
|
gpio_set(&PCH_DPWROK_EC, false);
|
||||||
tPCH14;
|
tPCH14;
|
||||||
#endif // DEEP_SX
|
#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) {
|
void power_event(void) {
|
||||||
static enum PowerState state = POWER_STATE_DEFAULT;
|
|
||||||
|
|
||||||
// Always switch to ds5 if EC is running
|
// Always switch to ds5 if EC is running
|
||||||
if (state == POWER_STATE_DEFAULT) {
|
if (power_state == POWER_STATE_DEFAULT) {
|
||||||
power_on_ds5();
|
power_on_ds5();
|
||||||
state = POWER_STATE_DS5;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the adapter line goes low
|
// Check if the adapter line goes low
|
||||||
@ -222,9 +218,8 @@ void power_event(void) {
|
|||||||
DEBUG("%02X: Power switch press\n", main_cycle);
|
DEBUG("%02X: Power switch press\n", main_cycle);
|
||||||
|
|
||||||
// Enable S5 power if necessary, before sending PWR_BTN
|
// Enable S5 power if necessary, before sending PWR_BTN
|
||||||
if (state == POWER_STATE_DS5) {
|
if (power_state == POWER_STATE_DS5) {
|
||||||
power_on_s5();
|
power_on_s5();
|
||||||
state = POWER_STATE_S5;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -283,6 +278,8 @@ void power_event(void) {
|
|||||||
// LPC was just reset, enable PNP devices
|
// LPC was just reset, enable PNP devices
|
||||||
pnp_enable();
|
pnp_enable();
|
||||||
//TODO: reset KBC and touchpad states
|
//TODO: reset KBC and touchpad states
|
||||||
|
|
||||||
|
power_state = POWER_STATE_S0;
|
||||||
}
|
}
|
||||||
rst_last = rst_new;
|
rst_last = rst_new;
|
||||||
|
|
||||||
@ -328,9 +325,9 @@ void power_event(void) {
|
|||||||
|
|
||||||
if (s4_new) {
|
if (s4_new) {
|
||||||
DEBUG("%02X: entering S3 state\n", main_cycle);
|
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();
|
power_off_s5();
|
||||||
state = POWER_STATE_DS5;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#if LEVEL >= LEVEL_DEBUG
|
#if LEVEL >= LEVEL_DEBUG
|
||||||
|
@ -1,6 +1,17 @@
|
|||||||
#ifndef _BOARD_POWER_H
|
#ifndef _BOARD_POWER_H
|
||||||
#define _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);
|
void power_event(void);
|
||||||
|
|
||||||
#endif // _BOARD_POWER_H
|
#endif // _BOARD_POWER_H
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#include <board/kbscan.h>
|
#include <board/kbscan.h>
|
||||||
#include <board/keymap.h>
|
#include <board/keymap.h>
|
||||||
#include <board/pmc.h>
|
#include <board/pmc.h>
|
||||||
|
#include <board/power.h>
|
||||||
#include <common/debug.h>
|
#include <common/debug.h>
|
||||||
|
|
||||||
bool kbscan_enabled = false;
|
bool kbscan_enabled = false;
|
||||||
@ -30,6 +31,13 @@ void kbscan_init(void) {
|
|||||||
#define DEBOUNCE_DELAY 20
|
#define DEBOUNCE_DELAY 20
|
||||||
|
|
||||||
bool kbscan_press(uint16_t key, bool pressed, uint8_t * layer) {
|
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) {
|
switch (key & KT_MASK) {
|
||||||
case (KT_NORMAL):
|
case (KT_NORMAL):
|
||||||
if (kbscan_enabled) {
|
if (kbscan_enabled) {
|
||||||
|
@ -63,7 +63,7 @@ void pmc_event(struct Pmc * pmc) {
|
|||||||
if (sts & PMC_STS_IBF) {
|
if (sts & PMC_STS_IBF) {
|
||||||
uint8_t data = pmc_read(pmc);
|
uint8_t data = pmc_read(pmc);
|
||||||
if (sts & PMC_STS_CMD) {
|
if (sts & PMC_STS_CMD) {
|
||||||
DEBUG("pmc cmd: %02X\n", data);
|
TRACE("pmc cmd: %02X\n", data);
|
||||||
|
|
||||||
state = PMC_STATE_DEFAULT;
|
state = PMC_STATE_DEFAULT;
|
||||||
switch (data) {
|
switch (data) {
|
||||||
@ -78,7 +78,7 @@ void pmc_event(struct Pmc * pmc) {
|
|||||||
pmc_sci_interrupt();
|
pmc_sci_interrupt();
|
||||||
break;
|
break;
|
||||||
case 0x82:
|
case 0x82:
|
||||||
DEBUG(" burst enable\n");
|
TRACE(" burst enable\n");
|
||||||
// Set burst bit
|
// Set burst bit
|
||||||
pmc_set_status(pmc, sts | (1 << 4));
|
pmc_set_status(pmc, sts | (1 << 4));
|
||||||
// Send acknowledgement byte
|
// Send acknowledgement byte
|
||||||
@ -86,14 +86,14 @@ void pmc_event(struct Pmc * pmc) {
|
|||||||
state_data = 0x90;
|
state_data = 0x90;
|
||||||
break;
|
break;
|
||||||
case 0x83:
|
case 0x83:
|
||||||
DEBUG(" burst disable\n");
|
TRACE(" burst disable\n");
|
||||||
// Clear burst bit
|
// Clear burst bit
|
||||||
pmc_set_status(pmc, sts & ~(1 << 4));
|
pmc_set_status(pmc, sts & ~(1 << 4));
|
||||||
// Send SCI for IBF=0
|
// Send SCI for IBF=0
|
||||||
pmc_sci_interrupt();
|
pmc_sci_interrupt();
|
||||||
break;
|
break;
|
||||||
case 0x84:
|
case 0x84:
|
||||||
DEBUG(" SCI queue\n");
|
TRACE(" SCI queue\n");
|
||||||
// Clear SCI pending bit
|
// Clear SCI pending bit
|
||||||
pmc_set_status(pmc, sts & ~(1 << 5));
|
pmc_set_status(pmc, sts & ~(1 << 5));
|
||||||
// Send SCI queue
|
// Send SCI queue
|
||||||
@ -104,13 +104,13 @@ void pmc_event(struct Pmc * pmc) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xEC:
|
case 0xEC:
|
||||||
DEBUG(" scratch rom\n");
|
TRACE(" scratch rom\n");
|
||||||
pmc_write(pmc, 0x76);
|
pmc_write(pmc, 0x76);
|
||||||
scratch_trampoline();
|
scratch_trampoline();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
DEBUG("pmc data: %02X\n", data);
|
TRACE("pmc data: %02X\n", data);
|
||||||
|
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case PMC_STATE_ACPI_READ:
|
case PMC_STATE_ACPI_READ:
|
||||||
@ -141,7 +141,7 @@ void pmc_event(struct Pmc * pmc) {
|
|||||||
if (!(sts & PMC_STS_OBF)) {
|
if (!(sts & PMC_STS_OBF)) {
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case PMC_STATE_WRITE:
|
case PMC_STATE_WRITE:
|
||||||
DEBUG("pmc write: %02X\n", state_data);
|
TRACE("pmc write: %02X\n", state_data);
|
||||||
state = PMC_STATE_DEFAULT;
|
state = PMC_STATE_DEFAULT;
|
||||||
pmc_write(pmc, state_data);
|
pmc_write(pmc, state_data);
|
||||||
// Send SCI for OBF=1
|
// Send SCI for OBF=1
|
||||||
|
@ -50,6 +50,8 @@ extern uint8_t main_cycle;
|
|||||||
// RSMRST# de-assertion to SUSPWRDNACK valid
|
// RSMRST# de-assertion to SUSPWRDNACK valid
|
||||||
#define tPLT01 delay_ms(200)
|
#define tPLT01 delay_ms(200)
|
||||||
|
|
||||||
|
enum PowerState power_state = POWER_STATE_DEFAULT;
|
||||||
|
|
||||||
// Enable deep sleep well power
|
// Enable deep sleep well power
|
||||||
void power_on_ds5() {
|
void power_on_ds5() {
|
||||||
DEBUG("%02X: power_on_ds5\n", main_cycle);
|
DEBUG("%02X: power_on_ds5\n", main_cycle);
|
||||||
@ -79,6 +81,8 @@ void power_on_ds5() {
|
|||||||
// tPCH04 is the ideal delay
|
// tPCH04 is the ideal delay
|
||||||
tPCH04;
|
tPCH04;
|
||||||
#endif // DEEP_SX
|
#endif // DEEP_SX
|
||||||
|
|
||||||
|
power_state = POWER_STATE_DS5;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enable S5 power
|
// Enable S5 power
|
||||||
@ -151,6 +155,8 @@ void power_on_s5() {
|
|||||||
// Extra wait - TODO remove
|
// Extra wait - TODO remove
|
||||||
delay_ms(200);
|
delay_ms(200);
|
||||||
#endif // DEEP_SX
|
#endif // DEEP_SX
|
||||||
|
|
||||||
|
power_state = POWER_STATE_S5;
|
||||||
}
|
}
|
||||||
|
|
||||||
void power_off_s5() {
|
void power_off_s5() {
|
||||||
@ -182,24 +188,14 @@ void power_off_s5() {
|
|||||||
gpio_set(&PCH_DPWROK_EC, false);
|
gpio_set(&PCH_DPWROK_EC, false);
|
||||||
tPCH14;
|
tPCH14;
|
||||||
#endif // DEEP_SX
|
#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) {
|
void power_event(void) {
|
||||||
static enum PowerState state = POWER_STATE_DEFAULT;
|
|
||||||
|
|
||||||
// Always switch to ds5 if EC is running
|
// Always switch to ds5 if EC is running
|
||||||
if (state == POWER_STATE_DEFAULT) {
|
if (power_state == POWER_STATE_DEFAULT) {
|
||||||
power_on_ds5();
|
power_on_ds5();
|
||||||
state = POWER_STATE_DS5;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the adapter line goes low
|
// Check if the adapter line goes low
|
||||||
@ -248,9 +244,8 @@ void power_event(void) {
|
|||||||
DEBUG("%02X: Power switch press\n", main_cycle);
|
DEBUG("%02X: Power switch press\n", main_cycle);
|
||||||
|
|
||||||
// Enable S5 power if necessary, before sending PWR_BTN
|
// Enable S5 power if necessary, before sending PWR_BTN
|
||||||
if (state == POWER_STATE_DS5) {
|
if (power_state == POWER_STATE_DS5) {
|
||||||
power_on_s5();
|
power_on_s5();
|
||||||
state = POWER_STATE_S5;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -309,6 +304,8 @@ void power_event(void) {
|
|||||||
// LPC was just reset, enable PNP devices
|
// LPC was just reset, enable PNP devices
|
||||||
pnp_enable();
|
pnp_enable();
|
||||||
//TODO: reset KBC and touchpad states
|
//TODO: reset KBC and touchpad states
|
||||||
|
|
||||||
|
power_state = POWER_STATE_S0;
|
||||||
}
|
}
|
||||||
rst_last = rst_new;
|
rst_last = rst_new;
|
||||||
|
|
||||||
@ -354,9 +351,9 @@ void power_event(void) {
|
|||||||
|
|
||||||
if (s4_new) {
|
if (s4_new) {
|
||||||
DEBUG("%02X: entering S3 state\n", main_cycle);
|
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();
|
power_off_s5();
|
||||||
state = POWER_STATE_DS5;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#if LEVEL >= LEVEL_DEBUG
|
#if LEVEL >= LEVEL_DEBUG
|
||||||
|
Loading…
x
Reference in New Issue
Block a user