Skip to content

Commit

Permalink
Make touchpad access non-blocking
Browse files Browse the repository at this point in the history
  • Loading branch information
jackpot51 committed May 25, 2021
1 parent 532219c commit 1b539e1
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 138 deletions.
51 changes: 43 additions & 8 deletions src/board/system76/common/kbc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}
}
Expand Down Expand Up @@ -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 {
Expand Down
8 changes: 6 additions & 2 deletions src/ec/it5570e/include/ec/ps2.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@

#include <stdint.h>

#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;
Expand All @@ -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;
Expand Down
63 changes: 0 additions & 63 deletions src/ec/it5570e/ps2.c
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
// SPDX-License-Identifier: GPL-3.0-only

#include <stdbool.h>

#include <common/macro.h>
#include <ec/ps2.h>

#define PS2(NUM) { \
Expand All @@ -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);
Expand All @@ -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);
}
8 changes: 6 additions & 2 deletions src/ec/it8587e/include/ec/ps2.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@

#include <stdint.h>

#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;
Expand All @@ -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;
Expand Down
63 changes: 0 additions & 63 deletions src/ec/it8587e/ps2.c
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
// SPDX-License-Identifier: GPL-3.0-only

#include <stdbool.h>

#include <common/macro.h>
#include <ec/ps2.h>

#define PS2(NUM) { \
Expand All @@ -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);
Expand All @@ -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);
}

0 comments on commit 1b539e1

Please sign in to comment.