diff --git a/src/board/system76/galp3-c/include/board/kbc.h b/src/board/system76/galp3-c/include/board/kbc.h index 2f0d734..c404ea8 100644 --- a/src/board/system76/galp3-c/include/board/kbc.h +++ b/src/board/system76/galp3-c/include/board/kbc.h @@ -6,7 +6,7 @@ #include void kbc_init(void); -void kbc_key(struct Kbc * kbc, uint16_t key, bool pressed); +bool kbc_scancode(struct Kbc * kbc, uint16_t key, bool pressed); void kbc_event(struct Kbc * kbc); #endif // _BOARD_KBC_H diff --git a/src/board/system76/galp3-c/kbc.c b/src/board/system76/galp3-c/kbc.c index ea85f12..3ee3c9a 100644 --- a/src/board/system76/galp3-c/kbc.c +++ b/src/board/system76/galp3-c/kbc.c @@ -10,20 +10,22 @@ void kbc_init(void) { *(KBC.control) = 0; } +#define KBC_TIMEOUT 1000 + // System flag static bool kbc_system = false; // Translate from scancode set 2 to scancode set 1 // for basically no good reason static bool kbc_translate = true; -void kbc_key(struct Kbc * kbc, uint16_t key, bool pressed) { +bool kbc_scancode(struct Kbc * kbc, uint16_t key, bool pressed) { if (kbc_translate) { key = keymap_translate(key); } switch (key & 0xFF00) { case K_E0: printf(" E0\n"); - kbc_keyboard(kbc, 0xE0); + if (!kbc_keyboard(kbc, 0xE0, KBC_TIMEOUT)) return false; key &= 0xFF; // Fall through case 0x00: @@ -32,13 +34,14 @@ void kbc_key(struct Kbc * kbc, uint16_t key, bool pressed) { key |= 0x80; } else { printf(" F0\n"); - kbc_keyboard(kbc, 0xF0); + if (!kbc_keyboard(kbc, 0xF0, KBC_TIMEOUT)) return false; } } printf(" %02X\n", key); - kbc_keyboard(kbc, (uint8_t)key); + if (!kbc_keyboard(kbc, (uint8_t)key, KBC_TIMEOUT)) return false; break; } + return true; } enum KbcState { @@ -84,12 +87,12 @@ void kbc_event(struct Kbc * kbc) { case 0xAA: printf(" test controller\n"); // Why not pass the test? - kbc_keyboard(kbc, 0x55); + kbc_keyboard(kbc, 0x55, KBC_TIMEOUT); break; case 0xAB: printf(" test first port\n"); // We _ARE_ the keyboard, so everything is good. - kbc_keyboard(kbc, 0x00); + kbc_keyboard(kbc, 0x00, KBC_TIMEOUT); break; case 0xAD: printf(" disable first port\n"); @@ -112,33 +115,34 @@ void kbc_event(struct Kbc * kbc) { case 0xED: printf(" set leds\n"); state = KBC_STATE_SET_LEDS; - kbc_keyboard(kbc, 0xFA); + kbc_keyboard(kbc, 0xFA, KBC_TIMEOUT); break; case 0xEE: printf(" echo\n"); // Hey, this is easy. I like easy commands - kbc_keyboard(kbc, 0xEE); + kbc_keyboard(kbc, 0xEE, KBC_TIMEOUT); break; case 0xF0: printf(" get/set scancode\n"); state = KBC_STATE_SCANCODE; - kbc_keyboard(kbc, 0xFA); + kbc_keyboard(kbc, 0xFA, KBC_TIMEOUT); break; case 0xF4: printf(" enable scanning\n"); kbscan_enabled = true; - kbc_keyboard(kbc, 0xFA); + kbc_keyboard(kbc, 0xFA, KBC_TIMEOUT); break; case 0xF5: printf(" disable scanning\n"); kbscan_enabled = false; - kbc_keyboard(kbc, 0xFA); + kbc_keyboard(kbc, 0xFA, KBC_TIMEOUT); break; case 0xFF: printf(" self test\n"); - kbc_keyboard(kbc, 0xFA); - // Yep, everything is still good, I promise - kbc_keyboard(kbc, 0xAA); + if (kbc_keyboard(kbc, 0xFA, KBC_TIMEOUT)) { + // Yep, everything is still good, I promise + kbc_keyboard(kbc, 0xAA, KBC_TIMEOUT); + } break; } break; @@ -171,7 +175,7 @@ void kbc_event(struct Kbc * kbc) { case KBC_STATE_SET_LEDS: printf(" set leds\n"); state = KBC_STATE_NORMAL; - kbc_keyboard(kbc, 0xFA); + kbc_keyboard(kbc, 0xFA, KBC_TIMEOUT); break; case KBC_STATE_SCANCODE: printf(" get/set scancode\n"); @@ -181,7 +185,7 @@ void kbc_event(struct Kbc * kbc) { printf(" set scancode set 2\n"); break; } - kbc_keyboard(kbc, 0xFA); + kbc_keyboard(kbc, 0xFA, KBC_TIMEOUT); break; case KBC_STATE_WRITE_PORT: printf(" write port byte\n"); diff --git a/src/board/system76/galp3-c/kbscan.c b/src/board/system76/galp3-c/kbscan.c index 576a4af..2882116 100644 --- a/src/board/system76/galp3-c/kbscan.c +++ b/src/board/system76/galp3-c/kbscan.c @@ -51,7 +51,7 @@ void kbscan_event(void) { uint16_t key = keymap(i, j, kbscan_layer); printf("KB %d, %d, %d = 0x%04X, %d\n", i, j, kbscan_layer, key, new_b); if (kbscan_enabled && key) { - kbc_key(&KBC, key, new_b); + kbc_scancode(&KBC, key, new_b); } } } diff --git a/src/ec/it8587e/include/ec/kbc.h b/src/ec/it8587e/include/ec/kbc.h index 1a681fc..b8bd8d9 100644 --- a/src/ec/it8587e/include/ec/kbc.h +++ b/src/ec/it8587e/include/ec/kbc.h @@ -1,6 +1,7 @@ #ifndef _EC_KBC_H #define _EC_KBC_H +#include #include void kbc_init(void); @@ -28,8 +29,8 @@ extern struct Kbc __code KBC; uint8_t kbc_status(struct Kbc * kbc); uint8_t kbc_read(struct Kbc * kbc); -void kbc_keyboard(struct Kbc * kbc, uint8_t data); -void kbc_mouse(struct Kbc * kbc, uint8_t data); +bool kbc_keyboard(struct Kbc * kbc, uint8_t data, int timeout); +bool kbc_mouse(struct Kbc * kbc, uint8_t data, int timeout); volatile uint8_t __xdata __at(0x1300) KBHICR; volatile uint8_t __xdata __at(0x1302) KBIRQR; diff --git a/src/ec/it8587e/include/ec/pmc.h b/src/ec/it8587e/include/ec/pmc.h index 0dbe3d4..e1b3498 100644 --- a/src/ec/it8587e/include/ec/pmc.h +++ b/src/ec/it8587e/include/ec/pmc.h @@ -1,6 +1,7 @@ #ifndef _EC_PMC_H #define _EC_PMC_H +#include #include struct Pmc { @@ -23,7 +24,7 @@ extern struct Pmc __code PMC_2; uint8_t pmc_status(struct Pmc * pmc); uint8_t pmc_read(struct Pmc * pmc); -void pmc_write(struct Pmc * pmc, uint8_t data); +bool pmc_write(struct Pmc * pmc, uint8_t data, int timeout); void pmc_event(struct Pmc * pmc); diff --git a/src/ec/it8587e/kbc.c b/src/ec/it8587e/kbc.c index 7d2de75..98e366b 100644 --- a/src/ec/it8587e/kbc.c +++ b/src/ec/it8587e/kbc.c @@ -17,14 +17,23 @@ uint8_t kbc_read(struct Kbc * kbc) { return *(kbc->data_in); } -void kbc_keyboard(struct Kbc * kbc, uint8_t data) { - //TODO: use timeout - while (kbc_status(kbc) & KBC_STS_OBF) {} - *(kbc->keyboard_out) = data; + +static bool kbc_wait(struct Kbc * kbc, int timeout) { + while (kbc_status(kbc) & KBC_STS_OBF) { + if (timeout == 0) return false; + timeout -= 1; + } + return true; } -void kbc_mouse(struct Kbc * kbc, uint8_t data) { - //TODO: use timeout - while (kbc_status(kbc) & KBC_STS_OBF) {} - *(kbc->mouse_out) = data; +bool kbc_keyboard(struct Kbc * kbc, uint8_t data, int timeout) { + if (!kbc_wait(kbc, timeout)) return false; + *(kbc->keyboard_out) = data; + return true; +} + +bool kbc_mouse(struct Kbc * kbc, uint8_t data, int timeout) { + if (!kbc_wait(kbc, timeout)) return false; + *(kbc->mouse_out) = data; + return true; } diff --git a/src/ec/it8587e/pmc.c b/src/ec/it8587e/pmc.c index af040d9..3b17cf6 100644 --- a/src/ec/it8587e/pmc.c +++ b/src/ec/it8587e/pmc.c @@ -21,12 +21,22 @@ uint8_t pmc_read(struct Pmc * pmc) { return *(pmc->data_in); } -void pmc_write(struct Pmc * pmc, uint8_t data) { - //TODO: use timeout - while (pmc_status(pmc) & PMC_STS_OBF) {} - *(pmc->data_out) = data; +static bool pmc_wait(struct Pmc * pmc, int timeout) { + while (pmc_status(pmc) & PMC_STS_OBF) { + if (timeout == 0) return false; + timeout -= 1; + } + return true; } +bool pmc_write(struct Pmc * pmc, uint8_t data, int timeout) { + if (!pmc_wait(pmc, timeout)) return false; + *(pmc->data_out) = data; + return true; +} + +#define PMC_TIMEOUT 1000 + enum PmcState { PMC_STATE_DEFAULT, PMC_STATE_ACPI_READ, @@ -55,7 +65,7 @@ void pmc_event(struct Pmc * pmc) { case 0x82: printf(" burst enable\n"); // TODO: figure out what burst is - pmc_write(pmc, 0x90); + pmc_write(pmc, 0x90, PMC_TIMEOUT); break; case 0x83: printf(" burst disable\n"); @@ -64,7 +74,7 @@ void pmc_event(struct Pmc * pmc) { case 0x84: printf(" SCI queue\n"); // TODO: queue is always empty - pmc_write(pmc, 0); + pmc_write(pmc, 0, PMC_TIMEOUT); break; } } else { @@ -74,7 +84,7 @@ void pmc_event(struct Pmc * pmc) { case PMC_STATE_ACPI_READ: state = PMC_STATE_DEFAULT; uint8_t value = acpi_read(data); - pmc_write(pmc, value); + pmc_write(pmc, value, PMC_TIMEOUT); break; case PMC_STATE_ACPI_WRITE: state = PMC_STATE_ACPI_WRITE_ADDR;