diff --git a/src/board/system76/common/kbc.c b/src/board/system76/common/kbc.c index 96c12d8ea..2a3500935 100644 --- a/src/board/system76/common/kbc.c +++ b/src/board/system76/common/kbc.c @@ -24,10 +24,12 @@ void kbc_init(void) { #define KBC_TIMEOUT 1000 -// Enable first port - TODO +// Enable first port static bool kbc_first = false; -// Enable second port - TODO +// Enable second port static bool kbc_second = false; +// Second port input timeout +static uint8_t kbc_second_wait = 0; // Translate from scancode set 2 to scancode set 1 // for basically no good reason static bool kbc_translate = true; @@ -359,7 +361,15 @@ static void kbc_on_input_data(struct Kbc * kbc, uint8_t data) { case KBC_STATE_SECOND_PORT_INPUT: TRACE(" write second port input\n"); state = KBC_STATE_NORMAL; - ps2_write(&PS2_TOUCHPAD, &data, 1); + // Begin write + *(PS2_TOUCHPAD.control) = 0x0D; + *(PS2_TOUCHPAD.data) = data; + // Pull data line low + *(PS2_TOUCHPAD.control) = 0x0C; + // Pull clock line high + *(PS2_TOUCHPAD.control) = 0x0E; + // Set wait timeout of 100 cycles + kbc_second_wait = 100; break; } } @@ -408,12 +418,37 @@ void kbc_event(struct Kbc * kbc) { // Read from touchpad when possible if (kbc_second) { - *(PS2_TOUCHPAD.control) = 0x07; - if (state == KBC_STATE_NORMAL) { + if (kbc_second_wait > 0) { + // Wait for touchpad write transaction to finish + kbc_second_wait -= 1; uint8_t sts = *(PS2_TOUCHPAD.status); - *(PS2_TOUCHPAD.status) = sts; - if (sts & BIT(3)) { - state = KBC_STATE_TOUCHPAD; + // If transaction is done, stop waiting + if (sts & PSSTS_DONE) { + kbc_second_wait = 0; + } + // If an error happened, clear status, print error, and stop waiting + else if (sts & PSSTS_ALL_ERR) { + ps2_reset(&PS2_TOUCHPAD); + TRACE(" write second port input ERROR %02X\n", sts); + kbc_second_wait = 0; + } + // If a timeout occurs, clear status, print error, and stop waiting + else if (kbc_second_wait == 0) { + ps2_reset(&PS2_TOUCHPAD); + TRACE(" write second port input TIMEOUT\n"); + kbc_second_wait = 0; + } + } + + if (kbc_second_wait == 0) { + // Attempt to read from touchpad + *(PS2_TOUCHPAD.control) = 0x07; + if (state == KBC_STATE_NORMAL) { + uint8_t sts = *(PS2_TOUCHPAD.status); + *(PS2_TOUCHPAD.status) = sts; + if (sts & PSSTS_DONE) { + state = KBC_STATE_TOUCHPAD; + } } } } else { diff --git a/src/ec/it5570e/include/ec/ps2.h b/src/ec/it5570e/include/ec/ps2.h index 757f17765..fc7316560 100644 --- a/src/ec/it5570e/include/ec/ps2.h +++ b/src/ec/it5570e/include/ec/ps2.h @@ -5,6 +5,12 @@ #include +#define PSSTS_TIMEOUT_ERR BIT(6) +#define PSSTS_FRAME_ERR BIT(5) +#define PSSTS_PARITY_ERR BIT(4) +#define PSSTS_ALL_ERR (PSSTS_TIMEOUT_ERR | PSSTS_FRAME_ERR | PSSTS_PARITY_ERR) +#define PSSTS_DONE BIT(3) + struct Ps2 { volatile uint8_t * control; volatile uint8_t * interrupt; @@ -17,8 +23,6 @@ extern struct Ps2 __code PS2_2; extern struct Ps2 __code PS2_3; void ps2_reset(struct Ps2 * ps2); -int ps2_read(struct Ps2 * ps2, uint8_t * data, int length); -int ps2_write(struct Ps2 * ps2, uint8_t * data, int length); volatile uint8_t __xdata __at(0x1700) PSCTL1; volatile uint8_t __xdata __at(0x1701) PSCTL2; diff --git a/src/ec/it5570e/ps2.c b/src/ec/it5570e/ps2.c index eadea39cd..ed2282008 100644 --- a/src/ec/it5570e/ps2.c +++ b/src/ec/it5570e/ps2.c @@ -1,8 +1,5 @@ // SPDX-License-Identifier: GPL-3.0-only -#include - -#include #include #define PS2(NUM) { \ @@ -12,14 +9,6 @@ .data = &PSDAT ## NUM, \ } -#define PS2_TIMEOUT 10000 - -#define PSSTS_TIMEOUT_ERR BIT(6) -#define PSSTS_FRAME_ERR BIT(5) -#define PSSTS_PARITY_ERR BIT(4) -#define PSSTS_ALL_ERR (PSSTS_TIMEOUT_ERR | PSSTS_FRAME_ERR | PSSTS_PARITY_ERR) -#define PSSTS_DONE BIT(3) - struct Ps2 __code PS2_1 = PS2(1); struct Ps2 __code PS2_2 = PS2(2); struct Ps2 __code PS2_3 = PS2(3); @@ -30,55 +19,3 @@ void ps2_reset(struct Ps2 * ps2) { // Clear status *(ps2->status) = *(ps2->status); } - -static int ps2_transaction(struct Ps2 * ps2, uint8_t * data, int length, bool read) { - int i; - for (i = 0; i < length; i++) { - if (read) { - // Begin read - *(ps2->control) = 0x07; - } else { - // Begin write - *(ps2->control) = 0x0D; - *(ps2->data) = data[i]; - // Pull data line low - *(ps2->control) = 0x0C; - // Pull clock line high - *(ps2->control) = 0x0E; - } - - uint32_t timeout; - for (timeout = PS2_TIMEOUT; timeout > 0; timeout--) { - uint8_t status = *(ps2->status); - // If an error happened, clear status and return the error - if (status & PSSTS_ALL_ERR) { - ps2_reset(ps2); - return -(int)status; - } - // If transaction is done, break - if (status & PSSTS_DONE) { - break; - } - } - // If a timeout happened, return the error - if (timeout == 0) { - ps2_reset(ps2); - return -0x1000; - } - if (read) { - data[i] = *(ps2->data); - } - // Set interface to defaults - ps2_reset(ps2); - } - - return i; -} - -int ps2_read(struct Ps2 * ps2, uint8_t * data, int length) { - return ps2_transaction(ps2, data, length, true); -} - -int ps2_write(struct Ps2 * ps2, uint8_t * data, int length) { - return ps2_transaction(ps2, data, length, false); -} diff --git a/src/ec/it8587e/include/ec/ps2.h b/src/ec/it8587e/include/ec/ps2.h index 757f17765..fc7316560 100644 --- a/src/ec/it8587e/include/ec/ps2.h +++ b/src/ec/it8587e/include/ec/ps2.h @@ -5,6 +5,12 @@ #include +#define PSSTS_TIMEOUT_ERR BIT(6) +#define PSSTS_FRAME_ERR BIT(5) +#define PSSTS_PARITY_ERR BIT(4) +#define PSSTS_ALL_ERR (PSSTS_TIMEOUT_ERR | PSSTS_FRAME_ERR | PSSTS_PARITY_ERR) +#define PSSTS_DONE BIT(3) + struct Ps2 { volatile uint8_t * control; volatile uint8_t * interrupt; @@ -17,8 +23,6 @@ extern struct Ps2 __code PS2_2; extern struct Ps2 __code PS2_3; void ps2_reset(struct Ps2 * ps2); -int ps2_read(struct Ps2 * ps2, uint8_t * data, int length); -int ps2_write(struct Ps2 * ps2, uint8_t * data, int length); volatile uint8_t __xdata __at(0x1700) PSCTL1; volatile uint8_t __xdata __at(0x1701) PSCTL2; diff --git a/src/ec/it8587e/ps2.c b/src/ec/it8587e/ps2.c index eadea39cd..ed2282008 100644 --- a/src/ec/it8587e/ps2.c +++ b/src/ec/it8587e/ps2.c @@ -1,8 +1,5 @@ // SPDX-License-Identifier: GPL-3.0-only -#include - -#include #include #define PS2(NUM) { \ @@ -12,14 +9,6 @@ .data = &PSDAT ## NUM, \ } -#define PS2_TIMEOUT 10000 - -#define PSSTS_TIMEOUT_ERR BIT(6) -#define PSSTS_FRAME_ERR BIT(5) -#define PSSTS_PARITY_ERR BIT(4) -#define PSSTS_ALL_ERR (PSSTS_TIMEOUT_ERR | PSSTS_FRAME_ERR | PSSTS_PARITY_ERR) -#define PSSTS_DONE BIT(3) - struct Ps2 __code PS2_1 = PS2(1); struct Ps2 __code PS2_2 = PS2(2); struct Ps2 __code PS2_3 = PS2(3); @@ -30,55 +19,3 @@ void ps2_reset(struct Ps2 * ps2) { // Clear status *(ps2->status) = *(ps2->status); } - -static int ps2_transaction(struct Ps2 * ps2, uint8_t * data, int length, bool read) { - int i; - for (i = 0; i < length; i++) { - if (read) { - // Begin read - *(ps2->control) = 0x07; - } else { - // Begin write - *(ps2->control) = 0x0D; - *(ps2->data) = data[i]; - // Pull data line low - *(ps2->control) = 0x0C; - // Pull clock line high - *(ps2->control) = 0x0E; - } - - uint32_t timeout; - for (timeout = PS2_TIMEOUT; timeout > 0; timeout--) { - uint8_t status = *(ps2->status); - // If an error happened, clear status and return the error - if (status & PSSTS_ALL_ERR) { - ps2_reset(ps2); - return -(int)status; - } - // If transaction is done, break - if (status & PSSTS_DONE) { - break; - } - } - // If a timeout happened, return the error - if (timeout == 0) { - ps2_reset(ps2); - return -0x1000; - } - if (read) { - data[i] = *(ps2->data); - } - // Set interface to defaults - ps2_reset(ps2); - } - - return i; -} - -int ps2_read(struct Ps2 * ps2, uint8_t * data, int length) { - return ps2_transaction(ps2, data, length, true); -} - -int ps2_write(struct Ps2 * ps2, uint8_t * data, int length) { - return ps2_transaction(ps2, data, length, false); -}