From c1236b9e4a9c7ad7cbdb13a8b58a7a80a0bfef92 Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Mon, 13 Jan 2020 15:51:22 -0700 Subject: [PATCH] Improve power light control --- src/arch/8051/timer.c | 2 +- src/board/system76/lemp9/board.mk | 2 +- src/board/system76/lemp9/main.c | 43 --------------- src/board/system76/lemp9/power.c | 91 +++++++++++++++++++++++++++++-- 4 files changed, 87 insertions(+), 51 deletions(-) diff --git a/src/arch/8051/timer.c b/src/arch/8051/timer.c index 54b0cda..61b98ca 100644 --- a/src/arch/8051/timer.c +++ b/src/arch/8051/timer.c @@ -4,7 +4,7 @@ void timer_mode_1(int value) { timer_stop(); - TMOD = 0x01; + TMOD = (TMOD & 0xF0) | 0x01; TH0 = (unsigned char)(value >> 8); TL0 = (unsigned char)value; TR0 = 1; diff --git a/src/board/system76/lemp9/board.mk b/src/board/system76/lemp9/board.mk index 9e6d1e6..87e81b9 100644 --- a/src/board/system76/lemp9/board.mk +++ b/src/board/system76/lemp9/board.mk @@ -1,7 +1,7 @@ EC=it5570e # Add keymap to src -KEYMAP?=default +KEYMAP?=jeremy SRC+=$(BOARD_DIR)/keymap/$(KEYMAP).c # Set log level diff --git a/src/board/system76/lemp9/main.c b/src/board/system76/lemp9/main.c index 0d42317..9b0c9ae 100644 --- a/src/board/system76/lemp9/main.c +++ b/src/board/system76/lemp9/main.c @@ -56,47 +56,6 @@ void init(void) { //TODO: INTC } -void ac_adapter() { - extern struct Gpio __code ACIN_N; - extern struct Gpio __code LED_ACIN; - - static bool send_sci = true; - static bool last = true; - - // Check if the adapter line goes low - bool new = gpio_get(&ACIN_N); - // Set ACIN LED - gpio_set(&LED_ACIN, !new); - - // If there has been a change, print - if (new != last) { - DEBUG("Power adapter "); - if (new) { - DEBUG("unplugged\n"); - battery_charger_disable(); - } else { - DEBUG("plugged in\n"); - battery_charger_enable(); - } - battery_debug(); - - // Reset main loop cycle to force reading PECI and battery - main_cycle = 0; - - // Send SCI to update AC and battery information - send_sci = true; - } - - if (send_sci) { - // Send SCI 0x16 for AC detect event - if (pmc_sci(&PMC_1, 0x16)) { - send_sci = false; - } - } - - last = new; -} - void touchpad_event(struct Ps2 * ps2) { if (kbc_second) { *(ps2->control) = 0x07; @@ -186,8 +145,6 @@ void main(void) { INFO("Hello from System76 EC for %s!\n", xstr(__BOARD__)); for(main_cycle = 0; ; main_cycle++) { - // Enables or disables battery charging based on AC adapter - ac_adapter(); // Handle power states power_event(); // Scans keyboard and sends keyboard packets diff --git a/src/board/system76/lemp9/power.c b/src/board/system76/lemp9/power.c index bc4db08..38bf008 100644 --- a/src/board/system76/lemp9/power.c +++ b/src/board/system76/lemp9/power.c @@ -1,5 +1,9 @@ +#include + #include +#include #include +#include #include #include #include @@ -9,6 +13,8 @@ extern uint8_t main_cycle; +extern struct Gpio __code ACIN_N; +extern struct Gpio __code LED_ACIN; extern struct Gpio __code PCH_DPWROK_EC; extern struct Gpio __code PCH_PWROK_EC; extern struct Gpio __code LED_PWR; @@ -192,6 +198,35 @@ void power_event(void) { state = POWER_STATE_DS5; } + // Check if the adapter line goes low + static bool ac_send_sci = true; + static bool ac_last = true; + bool ac_new = gpio_get(&ACIN_N); + if (ac_new != ac_last) { + DEBUG("Power adapter "); + if (ac_new) { + DEBUG("unplugged\n"); + battery_charger_disable(); + } else { + DEBUG("plugged in\n"); + battery_charger_enable(); + } + battery_debug(); + + // Reset main loop cycle to force reading PECI and battery + main_cycle = 0; + + // Send SCI to update AC and battery information + ac_send_sci = true; + } + if (ac_send_sci) { + // Send SCI 0x16 for AC detect event + if (pmc_sci(&PMC_1, 0x16)) { + ac_send_sci = false; + } + } + ac_last = ac_new; + // Read power switch state static bool ps_last = true; bool ps_new = gpio_get(&PWR_SW_N); @@ -278,16 +313,20 @@ void power_event(void) { DEBUG("%02X: SLP_S3# de-asserted\n", main_cycle); } s3_last = s3_new; + #endif - static bool s4_last = false; - bool s4_new = gpio_get(&SUSC_N_PCH); + static bool s4_last = false; + bool s4_new = gpio_get(&SUSC_N_PCH); + #if LEVEL >= LEVEL_DEBUG 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; + #endif + s4_last = s4_new; + #if LEVEL >= LEVEL_DEBUG static bool sus_last = false; bool sus_new = gpio_get(&SLP_SUS_N); if (!sus_new && sus_last) { @@ -305,7 +344,7 @@ void power_event(void) { if (ack_new && !ack_last) { DEBUG("%02X: SUSPWRDNACK asserted\n", main_cycle); - if (gpio_get(&SUSC_N_PCH)) { + if (s4_new) { DEBUG("%02X: entering S3 state\n", main_cycle); } else if (state == POWER_STATE_S5) { power_off_s5(); @@ -319,7 +358,47 @@ void power_event(void) { #endif ack_last = ack_new; - //TODO: Better power LED rules - gpio_set(&LED_PWR, rst_new); + if (rst_new) { + // CPU on, green light + gpio_set(&LED_PWR, true); + gpio_set(&LED_ACIN, false); + } else if (s4_new) { + // Suspended, flashing green light + static int8_t suspend_timer = 0; + if (suspend_timer <= 0) { + gpio_set(&LED_PWR, !gpio_get(&LED_PWR)); + // Suspend timer fires every 1 s + suspend_timer = 100; + } + gpio_set(&LED_ACIN, false); + + // If timer 1 is finished + if (TF1) { + // Stop timer 1 running + TR1 = 0; + // Clear timer 1 finished flag + TF1 = 0; + // Decrement suspend timer + suspend_timer -= 1; + } + + // If timer 1 is not running + if (!TR1) { + // Start timer for 10 ms + // 65536-(10000 * 69 + 89)/90 = 0xE20C + TMOD = (TMOD & 0x0F) | 0x10; + TH1 = 0xE2; + TL1 = 0x0C; + TR1 = 1; + } + } else if (!ac_new) { + // AC plugged in, orange light + gpio_set(&LED_PWR, false); + gpio_set(&LED_ACIN, true); + } else { + // CPU off and AC adapter unplugged, no light + gpio_set(&LED_PWR, false); + gpio_set(&LED_ACIN, false); + } #endif // DEEP_SX }