From e2059c89237414006d0090d9e6e1e7f1c8213693 Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Fri, 23 Jan 2026 09:55:28 -0700 Subject: [PATCH 1/5] Use defines for PSCTL bits --- src/app/main/kbc.c | 8 ++++---- src/ec/ite/include/ec/ps2.h | 12 ++++++++++++ src/ec/ite/ps2.c | 2 +- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/app/main/kbc.c b/src/app/main/kbc.c index 3ad324d25..5648a9a1f 100644 --- a/src/app/main/kbc.c +++ b/src/app/main/kbc.c @@ -402,13 +402,13 @@ static void kbc_on_input_data(struct Kbc *const kbc, uint8_t data) { TRACE(" write second port input\n"); state = KBC_STATE_NORMAL; // Begin write - *(PS2_TOUCHPAD.control) = 0x1D; + *(PS2_TOUCHPAD.control) = PSCTL_DCEN | PSCTL_TRMS | PSCTL_PSHE | PSCTL_CDAT; // Write the data *(PS2_TOUCHPAD.data) = data; // Pull data line low - *(PS2_TOUCHPAD.control) = 0x1C; + *(PS2_TOUCHPAD.control) = PSCTL_DCEN | PSCTL_TRMS | PSCTL_PSHE; // Pull clock line high - *(PS2_TOUCHPAD.control) = 0x1E; + *(PS2_TOUCHPAD.control) = PSCTL_DCEN | PSCTL_TRMS | PSCTL_PSHE | PSCTL_CCLK; // Set wait timeout of 100 cycles kbc_second_wait = 100; break; @@ -494,7 +494,7 @@ void kbc_event(struct Kbc *const kbc) { if (kbc_second_wait == 0) { // Attempt to read from touchpad - *(PS2_TOUCHPAD.control) = 0x17; + *(PS2_TOUCHPAD.control) = PSCTL_DCEN | PSCTL_PSHE | PSCTL_CCLK | PSCTL_CDAT; if (state == KBC_STATE_NORMAL) { uint8_t sts = *(PS2_TOUCHPAD.status); *(PS2_TOUCHPAD.status) = sts; diff --git a/src/ec/ite/include/ec/ps2.h b/src/ec/ite/include/ec/ps2.h index e8feeb924..22ed59741 100644 --- a/src/ec/ite/include/ec/ps2.h +++ b/src/ec/ite/include/ec/ps2.h @@ -3,8 +3,20 @@ #ifndef _EC_PS2_H #define _EC_PS2_H +#include #include +// Debounce circuit enable +#define PSCTL_DCEN BIT(4) +// Transmit/receive mode selection +#define PSCTL_TRMS BIT(3) +// PS/2 hardware enable +#define PSCTL_PSHE BIT(2) +// Control CLK line +#define PSCTL_CCLK BIT(1) +// Control DATA line +#define PSCTL_CDAT BIT(0) + #define PSSTS_TIMEOUT_ERR BIT(6) #define PSSTS_FRAME_ERR BIT(5) #define PSSTS_PARITY_ERR BIT(4) diff --git a/src/ec/ite/ps2.c b/src/ec/ite/ps2.c index ada30ae25..610292491 100644 --- a/src/ec/ite/ps2.c +++ b/src/ec/ite/ps2.c @@ -15,7 +15,7 @@ struct Ps2 __code PS2_3 = PS2(3); void ps2_reset(struct Ps2 *const ps2) { // Reset interface to defaults - *(ps2->control) = 1; + *(ps2->control) = PSCTL_CDAT; // Clear status *(ps2->status) = *(ps2->status); } From 5b357e6e774483d5023cbcda538d66315d9ddfc4 Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Sat, 24 Jan 2026 09:36:46 -0700 Subject: [PATCH 2/5] Buffer touchpad data --- src/app/main/kbc.c | 73 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 51 insertions(+), 22 deletions(-) diff --git a/src/app/main/kbc.c b/src/app/main/kbc.c index 5648a9a1f..25184d3a9 100644 --- a/src/app/main/kbc.c +++ b/src/app/main/kbc.c @@ -136,6 +136,34 @@ bool kbc_scancode(uint16_t key, bool pressed) { return kbc_buffer_push(scancodes, scancodes_len); } +static uint8_t kbc_second_buffer[16] = { 0 }; +static uint8_t kbc_second_buffer_head = 0; +static uint8_t kbc_second_buffer_tail = 0; + +static bool kbc_second_buffer_pop(uint8_t *const scancode) { + if (kbc_second_buffer_head == kbc_second_buffer_tail) { + return false; + } + *scancode = kbc_second_buffer[kbc_second_buffer_head]; + kbc_second_buffer_head = (kbc_second_buffer_head + 1U) % ARRAY_SIZE(kbc_second_buffer); + return true; +} + +static bool kbc_second_buffer_push(uint8_t data) { + uint8_t next = (kbc_second_buffer_tail + 1U) % ARRAY_SIZE(kbc_second_buffer); + if (next == kbc_second_buffer_head) { + return false; + } + kbc_second_buffer[kbc_second_buffer_tail] = data; + kbc_second_buffer_tail = next; + return true; +} + +static void kbc_second_buffer_clear(void) { + kbc_second_buffer_head = 0; + kbc_second_buffer_tail = 0; +} + enum KbcState { // Input buffer states KBC_STATE_NORMAL, @@ -149,7 +177,6 @@ enum KbcState { KBC_STATE_SECOND_PORT_INPUT, // Output buffer states KBC_STATE_KEYBOARD, - KBC_STATE_TOUCHPAD, KBC_STATE_MOUSE, // After output buffer states KBC_STATE_IDENTIFY_0, @@ -256,10 +283,6 @@ static void kbc_on_input_command(struct Kbc *const kbc, uint8_t data) { static void kbc_on_input_data(struct Kbc *const kbc, uint8_t data) { TRACE("kbc data: %02X\n", data); switch (state) { - case KBC_STATE_TOUCHPAD: - // Interrupt touchpad command - state = KBC_STATE_NORMAL; - // Fall through case KBC_STATE_NORMAL: TRACE(" keyboard command\n"); // Keyboard commands clear output buffer @@ -411,11 +434,26 @@ static void kbc_on_input_data(struct Kbc *const kbc, uint8_t data) { *(PS2_TOUCHPAD.control) = PSCTL_DCEN | PSCTL_TRMS | PSCTL_PSHE | PSCTL_CCLK; // Set wait timeout of 100 cycles kbc_second_wait = 100; + + // Reset command should clear buffer + if (data == 0xFF) { + kbc_second_buffer_clear(); + } + break; } } static void kbc_on_output_empty(struct Kbc *const kbc) { + // Read from scancode or mouse buffer when possible + if (state == KBC_STATE_NORMAL) { + if (kbc_buffer_pop(&state_data)) { + state = KBC_STATE_KEYBOARD; + } else if (kbc_second_buffer_pop(&state_data)) { + state = KBC_STATE_MOUSE; + } + } + switch (state) { case KBC_STATE_KEYBOARD: TRACE("kbc keyboard: %02X\n", state_data); @@ -424,9 +462,6 @@ static void kbc_on_output_empty(struct Kbc *const kbc) { state_next = KBC_STATE_NORMAL; } break; - case KBC_STATE_TOUCHPAD: - state_data = *(PS2_TOUCHPAD.data); - // Fall through case KBC_STATE_MOUSE: TRACE("kbc mouse: %02X\n", state_data); if (kbc_mouse(kbc, state_data, KBC_TIMEOUT)) { @@ -460,19 +495,14 @@ static void kbc_on_output_empty(struct Kbc *const kbc) { } void kbc_event(struct Kbc *const kbc) { - uint8_t sts; - - // Read from scancode buffer when possible - if (state == KBC_STATE_NORMAL && kbc_buffer_pop(&state_data)) { - state = KBC_STATE_KEYBOARD; - } + uint8_t sts, data; // Read from touchpad when possible if (kbc_second) { if (kbc_second_wait > 0) { // Wait for touchpad write transaction to finish kbc_second_wait -= 1; - uint8_t sts = *(PS2_TOUCHPAD.status); + sts = *(PS2_TOUCHPAD.status); *(PS2_TOUCHPAD.status) = sts; // If transaction is done, stop waiting if (sts & PSSTS_DONE) { @@ -495,12 +525,11 @@ void kbc_event(struct Kbc *const kbc) { if (kbc_second_wait == 0) { // Attempt to read from touchpad *(PS2_TOUCHPAD.control) = PSCTL_DCEN | PSCTL_PSHE | PSCTL_CCLK | PSCTL_CDAT; - if (state == KBC_STATE_NORMAL) { - uint8_t sts = *(PS2_TOUCHPAD.status); - *(PS2_TOUCHPAD.status) = sts; - if (sts & PSSTS_DONE) { - state = KBC_STATE_TOUCHPAD; - } + sts = *(PS2_TOUCHPAD.status); + *(PS2_TOUCHPAD.status) = sts; + if (sts & PSSTS_DONE) { + data = *(PS2_TOUCHPAD.data); + kbc_second_buffer_push(data); } } } else { @@ -510,7 +539,7 @@ void kbc_event(struct Kbc *const kbc) { // Read command/data while available sts = kbc_status(kbc); if (sts & KBC_STS_IBF) { - uint8_t data = kbc_read(kbc); + data = kbc_read(kbc); if (sts & KBC_STS_CMD) { kbc_on_input_command(kbc, data); } else { From 4f1216e1f08e94d0f446e491a09a424ad8388b0c Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Sat, 24 Jan 2026 10:48:53 -0700 Subject: [PATCH 3/5] Reset PS2 bus after touchpad write finishes --- src/app/main/kbc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/app/main/kbc.c b/src/app/main/kbc.c index 25184d3a9..cdb48f95c 100644 --- a/src/app/main/kbc.c +++ b/src/app/main/kbc.c @@ -506,6 +506,7 @@ void kbc_event(struct Kbc *const kbc) { *(PS2_TOUCHPAD.status) = sts; // If transaction is done, stop waiting if (sts & PSSTS_DONE) { + ps2_reset(&PS2_TOUCHPAD); kbc_second_wait = 0; } // If an error happened, clear status, print error, and stop waiting From 79b6434be107ae31db81e96d66a163d77b405c6f Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Sat, 24 Jan 2026 17:07:55 -0700 Subject: [PATCH 4/5] Try touchpad read on cycle after reset --- src/app/main/kbc.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/app/main/kbc.c b/src/app/main/kbc.c index cdb48f95c..0fa62d101 100644 --- a/src/app/main/kbc.c +++ b/src/app/main/kbc.c @@ -521,9 +521,7 @@ void kbc_event(struct Kbc *const kbc) { TRACE(" write second port input TIMEOUT\n"); kbc_second_wait = 0; } - } - - if (kbc_second_wait == 0) { + } else if (kbc_second_wait == 0) { // Attempt to read from touchpad *(PS2_TOUCHPAD.control) = PSCTL_DCEN | PSCTL_PSHE | PSCTL_CCLK | PSCTL_CDAT; sts = *(PS2_TOUCHPAD.status); From 39f1a9e24f87e9c3a729692221371631d6832c42 Mon Sep 17 00:00:00 2001 From: Tim Crawford Date: Mon, 26 Jan 2026 09:22:34 -0700 Subject: [PATCH 5/5] Format Signed-off-by: Tim Crawford --- src/app/main/kbc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/main/kbc.c b/src/app/main/kbc.c index 0fa62d101..c60ea2138 100644 --- a/src/app/main/kbc.c +++ b/src/app/main/kbc.c @@ -434,7 +434,7 @@ static void kbc_on_input_data(struct Kbc *const kbc, uint8_t data) { *(PS2_TOUCHPAD.control) = PSCTL_DCEN | PSCTL_TRMS | PSCTL_PSHE | PSCTL_CCLK; // Set wait timeout of 100 cycles kbc_second_wait = 100; - + // Reset command should clear buffer if (data == 0xFF) { kbc_second_buffer_clear();