Allow system to power off, enable logging, change kbc logging from debug to trace

This commit is contained in:
Jeremy Soller
2019-11-23 20:02:52 -07:00
parent 0426c066b6
commit bcd480ec85
4 changed files with 120 additions and 82 deletions

View File

@@ -3,11 +3,11 @@ EC=it8587e
# Add keymaps to include # Add keymaps to include
INCLUDE+=$(wildcard $(BOARD_DIR)/keymap/*.h) INCLUDE+=$(wildcard $(BOARD_DIR)/keymap/*.h)
# Set debug level to warn # Set debug level to debug
CFLAGS+=-DLEVEL=2 CFLAGS+=-DLEVEL=4
# Enable I2C debug on 0x76 # Enable I2C debug on 0x76
# CFLAGS+=-DI2C_DEBUGGER=0x76 CFLAGS+=-DI2C_DEBUGGER=0x76
# Add scratch ROM source # Add scratch ROM source
SCRATCH_DIR=$(BOARD_DIR)/scratch SCRATCH_DIR=$(BOARD_DIR)/scratch

View File

@@ -30,7 +30,7 @@ bool kbc_scancode(struct Kbc * kbc, uint16_t key, bool pressed) {
if (!key) return true; if (!key) return true;
switch (key & 0xFF00) { switch (key & 0xFF00) {
case K_E0: case K_E0:
DEBUG(" E0\n"); TRACE(" E0\n");
if (!kbc_keyboard(kbc, 0xE0, KBC_TIMEOUT)) return false; if (!kbc_keyboard(kbc, 0xE0, KBC_TIMEOUT)) return false;
key &= 0xFF; key &= 0xFF;
// Fall through // Fall through
@@ -39,11 +39,11 @@ bool kbc_scancode(struct Kbc * kbc, uint16_t key, bool pressed) {
if (kbc_translate) { if (kbc_translate) {
key |= 0x80; key |= 0x80;
} else { } else {
DEBUG(" F0\n"); TRACE(" F0\n");
if (!kbc_keyboard(kbc, 0xF0, KBC_TIMEOUT)) return false; 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; if (!kbc_keyboard(kbc, (uint8_t)key, KBC_TIMEOUT)) return false;
break; break;
} }
@@ -69,12 +69,12 @@ void kbc_event(struct Kbc * kbc) {
if (sts & KBC_STS_IBF) { if (sts & KBC_STS_IBF) {
uint8_t data = kbc_read(kbc); uint8_t data = kbc_read(kbc);
if (sts & KBC_STS_CMD) { if (sts & KBC_STS_CMD) {
DEBUG("kbc cmd: %02X\n", data); TRACE("kbc cmd: %02X\n", data);
state = KBC_STATE_NORMAL; state = KBC_STATE_NORMAL;
switch (data) { switch (data) {
case 0x20: case 0x20:
DEBUG(" read configuration byte\n"); TRACE(" read configuration byte\n");
uint8_t config = *kbc->control & 0x03; uint8_t config = *kbc->control & 0x03;
if (kbc_system) { if (kbc_system) {
config |= (1 << 2); config |= (1 << 2);
@@ -91,81 +91,81 @@ void kbc_event(struct Kbc * kbc) {
kbc_keyboard(kbc, config, KBC_TIMEOUT); kbc_keyboard(kbc, config, KBC_TIMEOUT);
break; break;
case 0x60: case 0x60:
DEBUG(" write configuration byte\n"); TRACE(" write configuration byte\n");
state = KBC_STATE_WRITE_CONFIG; state = KBC_STATE_WRITE_CONFIG;
break; break;
case 0xA7: case 0xA7:
DEBUG(" disable second port\n"); TRACE(" disable second port\n");
kbc_second = false; kbc_second = false;
break; break;
case 0xA8: case 0xA8:
DEBUG(" enable second port\n"); TRACE(" enable second port\n");
kbc_second = true; kbc_second = true;
break; break;
case 0xA9: case 0xA9:
DEBUG(" test second port\n"); TRACE(" test second port\n");
// TODO: communicate with touchpad? // TODO: communicate with touchpad?
kbc_keyboard(kbc, 0x00, KBC_TIMEOUT); kbc_keyboard(kbc, 0x00, KBC_TIMEOUT);
break; break;
case 0xAA: case 0xAA:
DEBUG(" test controller\n"); TRACE(" test controller\n");
// Why not pass the test? // Why not pass the test?
kbc_keyboard(kbc, 0x55, KBC_TIMEOUT); kbc_keyboard(kbc, 0x55, KBC_TIMEOUT);
break; break;
case 0xAB: case 0xAB:
DEBUG(" test first port\n"); TRACE(" test first port\n");
// We _ARE_ the keyboard, so everything is good. // We _ARE_ the keyboard, so everything is good.
kbc_keyboard(kbc, 0x00, KBC_TIMEOUT); kbc_keyboard(kbc, 0x00, KBC_TIMEOUT);
break; break;
case 0xAD: case 0xAD:
DEBUG(" disable first port\n"); TRACE(" disable first port\n");
kbc_first = false; kbc_first = false;
break; break;
case 0xAE: case 0xAE:
DEBUG(" enable first port\n"); TRACE(" enable first port\n");
kbc_first = true; kbc_first = true;
break; break;
case 0xD1: case 0xD1:
DEBUG(" write port byte\n"); TRACE(" write port byte\n");
state = KBC_STATE_WRITE_PORT; state = KBC_STATE_WRITE_PORT;
break; break;
case 0xD2: case 0xD2:
DEBUG(" write first port output\n"); TRACE(" write first port output\n");
state = KBC_STATE_FIRST_PORT_OUTPUT; state = KBC_STATE_FIRST_PORT_OUTPUT;
break; break;
case 0xD3: case 0xD3:
DEBUG(" write second port output\n"); TRACE(" write second port output\n");
state = KBC_STATE_SECOND_PORT_OUTPUT; state = KBC_STATE_SECOND_PORT_OUTPUT;
break; break;
case 0xD4: case 0xD4:
DEBUG(" write second port input\n"); TRACE(" write second port input\n");
state = KBC_STATE_SECOND_PORT_INPUT; state = KBC_STATE_SECOND_PORT_INPUT;
break; break;
} }
} else { } else {
DEBUG("kbc data: %02X\n", data); TRACE("kbc data: %02X\n", data);
switch (state) { switch (state) {
case KBC_STATE_NORMAL: case KBC_STATE_NORMAL:
DEBUG(" keyboard command\n"); TRACE(" keyboard command\n");
switch (data) { switch (data) {
case 0xED: case 0xED:
DEBUG(" set leds\n"); TRACE(" set leds\n");
state = KBC_STATE_SET_LEDS; state = KBC_STATE_SET_LEDS;
kbc_keyboard(kbc, 0xFA, KBC_TIMEOUT); kbc_keyboard(kbc, 0xFA, KBC_TIMEOUT);
break; break;
case 0xEE: case 0xEE:
DEBUG(" echo\n"); TRACE(" echo\n");
// Hey, this is easy. I like easy commands // Hey, this is easy. I like easy commands
kbc_keyboard(kbc, 0xEE, KBC_TIMEOUT); kbc_keyboard(kbc, 0xEE, KBC_TIMEOUT);
break; break;
case 0xF0: case 0xF0:
DEBUG(" get/set scancode\n"); TRACE(" get/set scancode\n");
state = KBC_STATE_SCANCODE; state = KBC_STATE_SCANCODE;
kbc_keyboard(kbc, 0xFA, KBC_TIMEOUT); kbc_keyboard(kbc, 0xFA, KBC_TIMEOUT);
break; break;
case 0xF2: case 0xF2:
DEBUG(" identify keyboard\n"); TRACE(" identify keyboard\n");
if (kbc_keyboard(kbc, 0xFA, KBC_TIMEOUT)) { if (kbc_keyboard(kbc, 0xFA, KBC_TIMEOUT)) {
if (kbc_keyboard(kbc, 0xAB, KBC_TIMEOUT)) { if (kbc_keyboard(kbc, 0xAB, KBC_TIMEOUT)) {
kbc_keyboard(kbc, 0x83, KBC_TIMEOUT); kbc_keyboard(kbc, 0x83, KBC_TIMEOUT);
@@ -173,17 +173,17 @@ void kbc_event(struct Kbc * kbc) {
} }
break; break;
case 0xF4: case 0xF4:
DEBUG(" enable scanning\n"); TRACE(" enable scanning\n");
kbscan_enabled = true; kbscan_enabled = true;
kbc_keyboard(kbc, 0xFA, KBC_TIMEOUT); kbc_keyboard(kbc, 0xFA, KBC_TIMEOUT);
break; break;
case 0xF5: case 0xF5:
DEBUG(" disable scanning\n"); TRACE(" disable scanning\n");
kbscan_enabled = false; kbscan_enabled = false;
kbc_keyboard(kbc, 0xFA, KBC_TIMEOUT); kbc_keyboard(kbc, 0xFA, KBC_TIMEOUT);
break; break;
case 0xFF: case 0xFF:
DEBUG(" self test\n"); TRACE(" self test\n");
if (kbc_keyboard(kbc, 0xFA, KBC_TIMEOUT)) { if (kbc_keyboard(kbc, 0xFA, KBC_TIMEOUT)) {
// Yep, everything is still good, I promise // Yep, everything is still good, I promise
kbc_keyboard(kbc, 0xAA, KBC_TIMEOUT); kbc_keyboard(kbc, 0xAA, KBC_TIMEOUT);
@@ -192,7 +192,7 @@ void kbc_event(struct Kbc * kbc) {
} }
break; break;
case KBC_STATE_WRITE_CONFIG: case KBC_STATE_WRITE_CONFIG:
DEBUG(" write configuration byte\n"); TRACE(" write configuration byte\n");
state = KBC_STATE_NORMAL; state = KBC_STATE_NORMAL;
uint8_t control = *kbc->control; uint8_t control = *kbc->control;
if (data & 1) { if (data & 1) {
@@ -212,38 +212,38 @@ void kbc_event(struct Kbc * kbc) {
*kbc->control = control; *kbc->control = control;
break; break;
case KBC_STATE_SET_LEDS: case KBC_STATE_SET_LEDS:
DEBUG(" set leds\n"); TRACE(" set leds\n");
state = KBC_STATE_NORMAL; state = KBC_STATE_NORMAL;
kbc_keyboard(kbc, 0xFA, KBC_TIMEOUT); kbc_keyboard(kbc, 0xFA, KBC_TIMEOUT);
break; break;
case KBC_STATE_SCANCODE: case KBC_STATE_SCANCODE:
DEBUG(" get/set scancode\n"); TRACE(" get/set scancode\n");
state = KBC_STATE_NORMAL; state = KBC_STATE_NORMAL;
#if LEVEL >= LEVEL_DEBUG #if LEVEL >= LEVEL_TRACE
switch (data) { switch (data) {
case 0x02: case 0x02:
DEBUG(" set scancode set 2\n"); TRACE(" set scancode set 2\n");
break; break;
} }
#endif #endif
kbc_keyboard(kbc, 0xFA, KBC_TIMEOUT); kbc_keyboard(kbc, 0xFA, KBC_TIMEOUT);
break; break;
case KBC_STATE_WRITE_PORT: case KBC_STATE_WRITE_PORT:
DEBUG(" write port byte\n"); TRACE(" write port byte\n");
state = KBC_STATE_NORMAL; state = KBC_STATE_NORMAL;
break; break;
case KBC_STATE_FIRST_PORT_OUTPUT: case KBC_STATE_FIRST_PORT_OUTPUT:
DEBUG(" write first port output\n"); TRACE(" write first port output\n");
state = KBC_STATE_NORMAL; state = KBC_STATE_NORMAL;
kbc_keyboard(kbc, data, KBC_TIMEOUT); kbc_keyboard(kbc, data, KBC_TIMEOUT);
break; break;
case KBC_STATE_SECOND_PORT_OUTPUT: case KBC_STATE_SECOND_PORT_OUTPUT:
DEBUG(" write second port output\n"); TRACE(" write second port output\n");
state = KBC_STATE_NORMAL; state = KBC_STATE_NORMAL;
kbc_mouse(kbc, data, KBC_TIMEOUT); kbc_mouse(kbc, data, KBC_TIMEOUT);
break; break;
case KBC_STATE_SECOND_PORT_INPUT: case KBC_STATE_SECOND_PORT_INPUT:
DEBUG(" write second port input\n"); TRACE(" write second port input\n");
state = KBC_STATE_NORMAL; state = KBC_STATE_NORMAL;
ps2_write(&PS2_3, &data, 1); ps2_write(&PS2_3, &data, 1);
break; break;

View File

@@ -17,7 +17,7 @@
#include <common/debug.h> #include <common/debug.h>
#include <common/macro.h> #include <common/macro.h>
static uint8_t main_cycle = 0; uint8_t main_cycle = 0;
void external_0(void) __interrupt(0) { void external_0(void) __interrupt(0) {
TRACE("external_0\n"); TRACE("external_0\n");

View File

@@ -7,6 +7,8 @@
// Platform does not currently support Deep Sx // Platform does not currently support Deep Sx
#define DEEP_SX 0 #define DEEP_SX 0
extern uint8_t main_cycle;
static struct Gpio __code PCH_DPWROK_EC = GPIO(A, 3); static struct Gpio __code PCH_DPWROK_EC = GPIO(A, 3);
static struct Gpio __code PCH_PWROK_EC = GPIO(A, 4); static struct Gpio __code PCH_PWROK_EC = GPIO(A, 4);
static struct Gpio __code LED_PWR = GPIO(A, 7); static struct Gpio __code LED_PWR = GPIO(A, 7);
@@ -61,10 +63,12 @@ static struct Gpio __code SUS_PWR_ACK = GPIO(J, 0);
#endif #endif
// DSW_PWROK assertion to SLP_SUS# de-assertion // DSW_PWROK assertion to SLP_SUS# de-assertion
#define tPCH32 delay_ms(95) #define tPCH32 delay_ms(95)
// RSMRST# de-assertion to SUSPWRDNACK valid
#define tPLT01 delay_ms(200)
// Enable deep sleep well power // Enable deep sleep well power
void power_on_ds5() { void power_on_ds5() {
DEBUG("power_on_ds5\n"); DEBUG("%02X: power_on_ds5\n", main_cycle);
#if DEEP_SX #if DEEP_SX
// See Figure 12-18 in Whiskey Lake Platform Design Guide // See Figure 12-18 in Whiskey Lake Platform Design Guide
@@ -95,7 +99,7 @@ void power_on_ds5() {
// Enable S5 power // Enable S5 power
void power_on_s5() { void power_on_s5() {
DEBUG("power_on_s5\n"); DEBUG("%02X: power_on_s5\n", main_cycle);
#if DEEP_SX #if DEEP_SX
// See Figure 12-18 in Whiskey Lake Platform Design Guide // See Figure 12-18 in Whiskey Lake Platform Design Guide
@@ -126,7 +130,8 @@ void power_on_s5() {
gpio_set(&EC_RSMRST_N, true); gpio_set(&EC_RSMRST_N, true);
// Wait for PCH stability // Wait for PCH stability
tPCH18; //tPCH18;
tPLT01;
// Allow processor to control SUSB# and SUSC# // Allow processor to control SUSB# and SUSC#
gpio_set(&EC_EN, true); gpio_set(&EC_EN, true);
@@ -134,7 +139,7 @@ void power_on_s5() {
} }
void power_off_s5() { void power_off_s5() {
DEBUG("power_off_s5\n"); DEBUG("%02X: power_off_s5\n", main_cycle);
#if DEEP_SX #if DEEP_SX
// TODO // TODO
@@ -176,42 +181,40 @@ enum PowerState {
void power_event(void) { void power_event(void) {
static enum PowerState state = POWER_STATE_DEFAULT; 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 // Always switch to ds5 if EC is running
if (state == POWER_STATE_DEFAULT) { if (state == POWER_STATE_DEFAULT) {
power_on_ds5(); power_on_ds5();
state = POWER_STATE_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 #if DEEP_SX
//TODO //TODO
@@ -222,7 +225,9 @@ void power_event(void) {
static bool pg_last = false; static bool pg_last = false;
bool pg_new = gpio_get(&ALL_SYS_PWRGD); bool pg_new = gpio_get(&ALL_SYS_PWRGD);
if (pg_new && !pg_last) { 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 // Allow H_VR_READY to set PCH_PWROK
gpio_set(&PM_PWROK, true); gpio_set(&PM_PWROK, true);
@@ -233,7 +238,7 @@ void power_event(void) {
// Assert SYS_PWROK, system can finally perform PLT_RST# and boot // Assert SYS_PWROK, system can finally perform PLT_RST# and boot
gpio_set(&PCH_PWROK_EC, true); gpio_set(&PCH_PWROK_EC, true);
} else if(!pg_new && pg_last) { } 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 // De-assert SYS_PWROK
gpio_set(&PCH_PWROK_EC, false); gpio_set(&PCH_PWROK_EC, false);
@@ -245,25 +250,58 @@ void power_event(void) {
static bool rst_last = false; static bool rst_last = false;
bool rst_new = gpio_get(&BUF_PLT_RST_N); 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 // LPC was just reset, enable PNP devices
pnp_enable(); pnp_enable();
//TODO: reset KBC and touchpad states //TODO: reset KBC and touchpad states
} }
rst_last = rst_new; 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 // EC must keep VccPRIM powered if SUSPWRDNACK is de-asserted low or system
// state is S3 // state is S3
if (!gpio_get(&SUSWARN_N)) { static bool ack_last = false;
if (state == POWER_STATE_DS5) { bool ack_new = gpio_get(&SUSWARN_N);
power_on_s5(); if (ack_new && !ack_last) {
state = POWER_STATE_DS5; DEBUG("%02X: SUSPWRDNACK asserted\n", main_cycle);
}
} else {
if (state == POWER_STATE_S5) { if (state == POWER_STATE_S5) {
power_off_s5(); power_off_s5();
state = POWER_STATE_DS5; 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 #endif // DEEP_SX
} }