Allow system to power off, enable logging, change kbc logging from debug to trace
This commit is contained in:
@ -3,11 +3,11 @@ EC=it8587e
|
||||
# Add keymaps to include
|
||||
INCLUDE+=$(wildcard $(BOARD_DIR)/keymap/*.h)
|
||||
|
||||
# Set debug level to warn
|
||||
CFLAGS+=-DLEVEL=2
|
||||
# Set debug level to debug
|
||||
CFLAGS+=-DLEVEL=4
|
||||
|
||||
# Enable I2C debug on 0x76
|
||||
# CFLAGS+=-DI2C_DEBUGGER=0x76
|
||||
CFLAGS+=-DI2C_DEBUGGER=0x76
|
||||
|
||||
# Add scratch ROM source
|
||||
SCRATCH_DIR=$(BOARD_DIR)/scratch
|
||||
|
@ -30,7 +30,7 @@ bool kbc_scancode(struct Kbc * kbc, uint16_t key, bool pressed) {
|
||||
if (!key) return true;
|
||||
switch (key & 0xFF00) {
|
||||
case K_E0:
|
||||
DEBUG(" E0\n");
|
||||
TRACE(" E0\n");
|
||||
if (!kbc_keyboard(kbc, 0xE0, KBC_TIMEOUT)) return false;
|
||||
key &= 0xFF;
|
||||
// Fall through
|
||||
@ -39,11 +39,11 @@ bool kbc_scancode(struct Kbc * kbc, uint16_t key, bool pressed) {
|
||||
if (kbc_translate) {
|
||||
key |= 0x80;
|
||||
} else {
|
||||
DEBUG(" F0\n");
|
||||
TRACE(" F0\n");
|
||||
if (!kbc_keyboard(kbc, 0xF0, KBC_TIMEOUT)) return false;
|
||||
}
|
||||
}
|
||||
DEBUG(" %02X\n", key);
|
||||
TRACE(" %02X\n", key);
|
||||
if (!kbc_keyboard(kbc, (uint8_t)key, KBC_TIMEOUT)) return false;
|
||||
break;
|
||||
}
|
||||
@ -69,12 +69,12 @@ void kbc_event(struct Kbc * kbc) {
|
||||
if (sts & KBC_STS_IBF) {
|
||||
uint8_t data = kbc_read(kbc);
|
||||
if (sts & KBC_STS_CMD) {
|
||||
DEBUG("kbc cmd: %02X\n", data);
|
||||
TRACE("kbc cmd: %02X\n", data);
|
||||
|
||||
state = KBC_STATE_NORMAL;
|
||||
switch (data) {
|
||||
case 0x20:
|
||||
DEBUG(" read configuration byte\n");
|
||||
TRACE(" read configuration byte\n");
|
||||
uint8_t config = *kbc->control & 0x03;
|
||||
if (kbc_system) {
|
||||
config |= (1 << 2);
|
||||
@ -91,81 +91,81 @@ void kbc_event(struct Kbc * kbc) {
|
||||
kbc_keyboard(kbc, config, KBC_TIMEOUT);
|
||||
break;
|
||||
case 0x60:
|
||||
DEBUG(" write configuration byte\n");
|
||||
TRACE(" write configuration byte\n");
|
||||
state = KBC_STATE_WRITE_CONFIG;
|
||||
break;
|
||||
case 0xA7:
|
||||
DEBUG(" disable second port\n");
|
||||
TRACE(" disable second port\n");
|
||||
kbc_second = false;
|
||||
break;
|
||||
case 0xA8:
|
||||
DEBUG(" enable second port\n");
|
||||
TRACE(" enable second port\n");
|
||||
kbc_second = true;
|
||||
break;
|
||||
case 0xA9:
|
||||
DEBUG(" test second port\n");
|
||||
TRACE(" test second port\n");
|
||||
// TODO: communicate with touchpad?
|
||||
kbc_keyboard(kbc, 0x00, KBC_TIMEOUT);
|
||||
break;
|
||||
case 0xAA:
|
||||
DEBUG(" test controller\n");
|
||||
TRACE(" test controller\n");
|
||||
// Why not pass the test?
|
||||
kbc_keyboard(kbc, 0x55, KBC_TIMEOUT);
|
||||
break;
|
||||
case 0xAB:
|
||||
DEBUG(" test first port\n");
|
||||
TRACE(" test first port\n");
|
||||
// We _ARE_ the keyboard, so everything is good.
|
||||
kbc_keyboard(kbc, 0x00, KBC_TIMEOUT);
|
||||
break;
|
||||
case 0xAD:
|
||||
DEBUG(" disable first port\n");
|
||||
TRACE(" disable first port\n");
|
||||
kbc_first = false;
|
||||
break;
|
||||
case 0xAE:
|
||||
DEBUG(" enable first port\n");
|
||||
TRACE(" enable first port\n");
|
||||
kbc_first = true;
|
||||
break;
|
||||
case 0xD1:
|
||||
DEBUG(" write port byte\n");
|
||||
TRACE(" write port byte\n");
|
||||
state = KBC_STATE_WRITE_PORT;
|
||||
break;
|
||||
case 0xD2:
|
||||
DEBUG(" write first port output\n");
|
||||
TRACE(" write first port output\n");
|
||||
state = KBC_STATE_FIRST_PORT_OUTPUT;
|
||||
break;
|
||||
case 0xD3:
|
||||
DEBUG(" write second port output\n");
|
||||
TRACE(" write second port output\n");
|
||||
state = KBC_STATE_SECOND_PORT_OUTPUT;
|
||||
break;
|
||||
case 0xD4:
|
||||
DEBUG(" write second port input\n");
|
||||
TRACE(" write second port input\n");
|
||||
state = KBC_STATE_SECOND_PORT_INPUT;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
DEBUG("kbc data: %02X\n", data);
|
||||
TRACE("kbc data: %02X\n", data);
|
||||
|
||||
switch (state) {
|
||||
case KBC_STATE_NORMAL:
|
||||
DEBUG(" keyboard command\n");
|
||||
TRACE(" keyboard command\n");
|
||||
switch (data) {
|
||||
case 0xED:
|
||||
DEBUG(" set leds\n");
|
||||
TRACE(" set leds\n");
|
||||
state = KBC_STATE_SET_LEDS;
|
||||
kbc_keyboard(kbc, 0xFA, KBC_TIMEOUT);
|
||||
break;
|
||||
case 0xEE:
|
||||
DEBUG(" echo\n");
|
||||
TRACE(" echo\n");
|
||||
// Hey, this is easy. I like easy commands
|
||||
kbc_keyboard(kbc, 0xEE, KBC_TIMEOUT);
|
||||
break;
|
||||
case 0xF0:
|
||||
DEBUG(" get/set scancode\n");
|
||||
TRACE(" get/set scancode\n");
|
||||
state = KBC_STATE_SCANCODE;
|
||||
kbc_keyboard(kbc, 0xFA, KBC_TIMEOUT);
|
||||
break;
|
||||
case 0xF2:
|
||||
DEBUG(" identify keyboard\n");
|
||||
TRACE(" identify keyboard\n");
|
||||
if (kbc_keyboard(kbc, 0xFA, KBC_TIMEOUT)) {
|
||||
if (kbc_keyboard(kbc, 0xAB, KBC_TIMEOUT)) {
|
||||
kbc_keyboard(kbc, 0x83, KBC_TIMEOUT);
|
||||
@ -173,17 +173,17 @@ void kbc_event(struct Kbc * kbc) {
|
||||
}
|
||||
break;
|
||||
case 0xF4:
|
||||
DEBUG(" enable scanning\n");
|
||||
TRACE(" enable scanning\n");
|
||||
kbscan_enabled = true;
|
||||
kbc_keyboard(kbc, 0xFA, KBC_TIMEOUT);
|
||||
break;
|
||||
case 0xF5:
|
||||
DEBUG(" disable scanning\n");
|
||||
TRACE(" disable scanning\n");
|
||||
kbscan_enabled = false;
|
||||
kbc_keyboard(kbc, 0xFA, KBC_TIMEOUT);
|
||||
break;
|
||||
case 0xFF:
|
||||
DEBUG(" self test\n");
|
||||
TRACE(" self test\n");
|
||||
if (kbc_keyboard(kbc, 0xFA, KBC_TIMEOUT)) {
|
||||
// Yep, everything is still good, I promise
|
||||
kbc_keyboard(kbc, 0xAA, KBC_TIMEOUT);
|
||||
@ -192,7 +192,7 @@ void kbc_event(struct Kbc * kbc) {
|
||||
}
|
||||
break;
|
||||
case KBC_STATE_WRITE_CONFIG:
|
||||
DEBUG(" write configuration byte\n");
|
||||
TRACE(" write configuration byte\n");
|
||||
state = KBC_STATE_NORMAL;
|
||||
uint8_t control = *kbc->control;
|
||||
if (data & 1) {
|
||||
@ -212,38 +212,38 @@ void kbc_event(struct Kbc * kbc) {
|
||||
*kbc->control = control;
|
||||
break;
|
||||
case KBC_STATE_SET_LEDS:
|
||||
DEBUG(" set leds\n");
|
||||
TRACE(" set leds\n");
|
||||
state = KBC_STATE_NORMAL;
|
||||
kbc_keyboard(kbc, 0xFA, KBC_TIMEOUT);
|
||||
break;
|
||||
case KBC_STATE_SCANCODE:
|
||||
DEBUG(" get/set scancode\n");
|
||||
TRACE(" get/set scancode\n");
|
||||
state = KBC_STATE_NORMAL;
|
||||
#if LEVEL >= LEVEL_DEBUG
|
||||
#if LEVEL >= LEVEL_TRACE
|
||||
switch (data) {
|
||||
case 0x02:
|
||||
DEBUG(" set scancode set 2\n");
|
||||
TRACE(" set scancode set 2\n");
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
kbc_keyboard(kbc, 0xFA, KBC_TIMEOUT);
|
||||
break;
|
||||
case KBC_STATE_WRITE_PORT:
|
||||
DEBUG(" write port byte\n");
|
||||
TRACE(" write port byte\n");
|
||||
state = KBC_STATE_NORMAL;
|
||||
break;
|
||||
case KBC_STATE_FIRST_PORT_OUTPUT:
|
||||
DEBUG(" write first port output\n");
|
||||
TRACE(" write first port output\n");
|
||||
state = KBC_STATE_NORMAL;
|
||||
kbc_keyboard(kbc, data, KBC_TIMEOUT);
|
||||
break;
|
||||
case KBC_STATE_SECOND_PORT_OUTPUT:
|
||||
DEBUG(" write second port output\n");
|
||||
TRACE(" write second port output\n");
|
||||
state = KBC_STATE_NORMAL;
|
||||
kbc_mouse(kbc, data, KBC_TIMEOUT);
|
||||
break;
|
||||
case KBC_STATE_SECOND_PORT_INPUT:
|
||||
DEBUG(" write second port input\n");
|
||||
TRACE(" write second port input\n");
|
||||
state = KBC_STATE_NORMAL;
|
||||
ps2_write(&PS2_3, &data, 1);
|
||||
break;
|
||||
|
@ -17,7 +17,7 @@
|
||||
#include <common/debug.h>
|
||||
#include <common/macro.h>
|
||||
|
||||
static uint8_t main_cycle = 0;
|
||||
uint8_t main_cycle = 0;
|
||||
|
||||
void external_0(void) __interrupt(0) {
|
||||
TRACE("external_0\n");
|
||||
|
@ -7,6 +7,8 @@
|
||||
// Platform does not currently support Deep Sx
|
||||
#define DEEP_SX 0
|
||||
|
||||
extern uint8_t main_cycle;
|
||||
|
||||
static struct Gpio __code PCH_DPWROK_EC = GPIO(A, 3);
|
||||
static struct Gpio __code PCH_PWROK_EC = GPIO(A, 4);
|
||||
static struct Gpio __code LED_PWR = GPIO(A, 7);
|
||||
@ -61,10 +63,12 @@ static struct Gpio __code SUS_PWR_ACK = GPIO(J, 0);
|
||||
#endif
|
||||
// DSW_PWROK assertion to SLP_SUS# de-assertion
|
||||
#define tPCH32 delay_ms(95)
|
||||
// RSMRST# de-assertion to SUSPWRDNACK valid
|
||||
#define tPLT01 delay_ms(200)
|
||||
|
||||
// Enable deep sleep well power
|
||||
void power_on_ds5() {
|
||||
DEBUG("power_on_ds5\n");
|
||||
DEBUG("%02X: power_on_ds5\n", main_cycle);
|
||||
|
||||
#if DEEP_SX
|
||||
// See Figure 12-18 in Whiskey Lake Platform Design Guide
|
||||
@ -95,7 +99,7 @@ void power_on_ds5() {
|
||||
|
||||
// Enable S5 power
|
||||
void power_on_s5() {
|
||||
DEBUG("power_on_s5\n");
|
||||
DEBUG("%02X: power_on_s5\n", main_cycle);
|
||||
|
||||
#if DEEP_SX
|
||||
// See Figure 12-18 in Whiskey Lake Platform Design Guide
|
||||
@ -126,7 +130,8 @@ void power_on_s5() {
|
||||
gpio_set(&EC_RSMRST_N, true);
|
||||
|
||||
// Wait for PCH stability
|
||||
tPCH18;
|
||||
//tPCH18;
|
||||
tPLT01;
|
||||
|
||||
// Allow processor to control SUSB# and SUSC#
|
||||
gpio_set(&EC_EN, true);
|
||||
@ -134,7 +139,7 @@ void power_on_s5() {
|
||||
}
|
||||
|
||||
void power_off_s5() {
|
||||
DEBUG("power_off_s5\n");
|
||||
DEBUG("%02X: power_off_s5\n", main_cycle);
|
||||
|
||||
#if DEEP_SX
|
||||
// TODO
|
||||
@ -176,42 +181,40 @@ enum PowerState {
|
||||
void power_event(void) {
|
||||
static enum PowerState state = POWER_STATE_DEFAULT;
|
||||
|
||||
// Sync power button state
|
||||
{
|
||||
// Read power button state
|
||||
static bool last = true;
|
||||
bool new = gpio_get(&PWR_SW_N);
|
||||
if (!new && last) {
|
||||
// Ensure press is not spurious
|
||||
delay_ms(10);
|
||||
if (gpio_get(&PWR_SW_N) != new) {
|
||||
DEBUG("Spurious press\n");
|
||||
new = !new;
|
||||
} else {
|
||||
DEBUG("Power switch press\n");
|
||||
}
|
||||
}
|
||||
#if LEVEL >= LEVEL_DEBUG
|
||||
else if (new && !last) {
|
||||
DEBUG("Power switch release\n");
|
||||
}
|
||||
#endif
|
||||
last = new;
|
||||
|
||||
// Send power signal to PCH
|
||||
gpio_set(&PWR_BTN_N, new);
|
||||
}
|
||||
|
||||
// Always switch to ds5 if EC is running
|
||||
if (state == POWER_STATE_DEFAULT) {
|
||||
power_on_ds5();
|
||||
state = POWER_STATE_DS5;
|
||||
|
||||
//TODO: Logic for switching from ds5 to s5
|
||||
power_on_s5();
|
||||
state = POWER_STATE_S5;
|
||||
}
|
||||
|
||||
// Read power switch state
|
||||
static bool ps_last = true;
|
||||
bool ps_new = gpio_get(&PWR_SW_N);
|
||||
if (!ps_new && ps_last) {
|
||||
// Ensure press is not spurious
|
||||
delay_ms(10);
|
||||
if (gpio_get(&PWR_SW_N) != ps_new) {
|
||||
DEBUG("%02X: Spurious press\n", main_cycle);
|
||||
ps_new = ps_last;
|
||||
} else {
|
||||
DEBUG("%02X: Power switch press\n", main_cycle);
|
||||
|
||||
// Enable S5 power if necessary, before sending PWR_BTN
|
||||
if (state == POWER_STATE_DS5) {
|
||||
power_on_s5();
|
||||
state = POWER_STATE_S5;
|
||||
}
|
||||
}
|
||||
}
|
||||
#if LEVEL >= LEVEL_DEBUG
|
||||
else if (ps_new && !ps_last) {
|
||||
DEBUG("%02X: Power switch release\n", main_cycle);
|
||||
}
|
||||
#endif
|
||||
ps_last = ps_new;
|
||||
|
||||
// Send power signal to PCH
|
||||
gpio_set(&PWR_BTN_N, ps_new);
|
||||
|
||||
#if DEEP_SX
|
||||
//TODO
|
||||
@ -222,7 +225,9 @@ void power_event(void) {
|
||||
static bool pg_last = false;
|
||||
bool pg_new = gpio_get(&ALL_SYS_PWRGD);
|
||||
if (pg_new && !pg_last) {
|
||||
DEBUG("ALL_SYS_PWRGD asserted\n");
|
||||
DEBUG("%02X: ALL_SYS_PWRGD asserted\n", main_cycle);
|
||||
|
||||
//TODO: tPLT04;
|
||||
|
||||
// Allow H_VR_READY to set PCH_PWROK
|
||||
gpio_set(&PM_PWROK, true);
|
||||
@ -233,7 +238,7 @@ void power_event(void) {
|
||||
// Assert SYS_PWROK, system can finally perform PLT_RST# and boot
|
||||
gpio_set(&PCH_PWROK_EC, true);
|
||||
} else if(!pg_new && pg_last) {
|
||||
DEBUG("ALL_SYS_PWRGD de-asserted\n");
|
||||
DEBUG("%02X: ALL_SYS_PWRGD de-asserted\n", main_cycle);
|
||||
|
||||
// De-assert SYS_PWROK
|
||||
gpio_set(&PCH_PWROK_EC, false);
|
||||
@ -245,25 +250,58 @@ void power_event(void) {
|
||||
|
||||
static bool rst_last = false;
|
||||
bool rst_new = gpio_get(&BUF_PLT_RST_N);
|
||||
if (rst_new && !rst_last) {
|
||||
if (!rst_new && rst_last) {
|
||||
DEBUG("%02X: PLT_RST# asserted\n", main_cycle);
|
||||
} else if(rst_new && !rst_last) {
|
||||
DEBUG("%02X: PLT_RST# de-asserted\n", main_cycle);
|
||||
|
||||
// LPC was just reset, enable PNP devices
|
||||
pnp_enable();
|
||||
//TODO: reset KBC and touchpad states
|
||||
}
|
||||
rst_last = rst_new;
|
||||
|
||||
static bool s4_last = false;
|
||||
bool s4_new = gpio_get(&SUSC_N_PCH);
|
||||
if (!s4_new && s4_last) {
|
||||
DEBUG("%02X: SLP_S4# asserted\n", main_cycle);
|
||||
} else if(s4_new && !s4_last) {
|
||||
DEBUG("%02X: SLP_S4# de-asserted\n", main_cycle);
|
||||
}
|
||||
s4_last = s4_new;
|
||||
|
||||
static bool s3_last = false;
|
||||
bool s3_new = gpio_get(&SUSB_N_PCH);
|
||||
if (!s3_new && s3_last) {
|
||||
DEBUG("%02X: SLP_S3# asserted\n", main_cycle);
|
||||
} else if(s3_new && !s3_last) {
|
||||
DEBUG("%02X: SLP_S3# de-asserted\n", main_cycle);
|
||||
}
|
||||
s3_last = s3_new;
|
||||
|
||||
// EC must keep VccPRIM powered if SUSPWRDNACK is de-asserted low or system
|
||||
// state is S3
|
||||
if (!gpio_get(&SUSWARN_N)) {
|
||||
if (state == POWER_STATE_DS5) {
|
||||
power_on_s5();
|
||||
state = POWER_STATE_DS5;
|
||||
}
|
||||
} else {
|
||||
static bool ack_last = false;
|
||||
bool ack_new = gpio_get(&SUSWARN_N);
|
||||
if (ack_new && !ack_last) {
|
||||
DEBUG("%02X: SUSPWRDNACK asserted\n", main_cycle);
|
||||
|
||||
if (state == POWER_STATE_S5) {
|
||||
power_off_s5();
|
||||
state = POWER_STATE_DS5;
|
||||
}
|
||||
} else if (!ack_new && ack_last) {
|
||||
DEBUG("%02X: SUSPWRDNACK de-asserted\n", main_cycle);
|
||||
}
|
||||
ack_last = ack_new;
|
||||
|
||||
static bool sus_last = false;
|
||||
bool sus_new = gpio_get(&SLP_SUS_N);
|
||||
if (!sus_new && sus_last) {
|
||||
DEBUG("%02X: SLP_SUS# asserted\n", main_cycle);
|
||||
} else if (sus_new && !sus_last) {
|
||||
DEBUG("%02X: SLP_SUS# de-asserted\n", main_cycle);
|
||||
}
|
||||
sus_last = sus_new;
|
||||
#endif // DEEP_SX
|
||||
}
|
||||
|
Reference in New Issue
Block a user