Skip to content

Commit ddeb264

Browse files
authored
Merge pull request #471 from FrameworkComputer/hx30.fix_ps2_mouse_hang
hx30 fix ps2 mouse emulation not work in winpe
2 parents c709a7e + 2ad97ed commit ddeb264

2 files changed

Lines changed: 41 additions & 15 deletions

File tree

board/hx30/ps2mouse.c

Lines changed: 39 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ void send_data_byte(uint8_t data) {
4646
int timeout = 0;
4747

4848
/* sometimes the host will get behind */
49-
while (aux_buffer_available() < 1 && timeout++ < 25)
49+
while (aux_buffer_available() < 1 && timeout++ < AUX_BUFFER_FULL_RETRIES)
5050
usleep(10*MSEC);
5151
send_aux_data_to_host_interrupt(data);
5252
}
@@ -56,14 +56,16 @@ void send_movement_packet(void)
5656
int max = 3;
5757
int timeout = 0;
5858

59-
6059
if (five_button_mode)
6160
max = 4;
6261
/* sometimes the host will get behind */
63-
while (aux_buffer_available() < max && timeout++ < 25)
62+
while (aux_buffer_available() < max && timeout++ < AUX_BUFFER_FULL_RETRIES &&
63+
(*task_get_event_bitmap(emumouse_task_id) & PS2MOUSE_EVT_AUX_DATA) == 0) {
6464
usleep(10*MSEC);
65+
}
6566

66-
if (timeout == 25) {
67+
if (timeout == AUX_BUFFER_FULL_RETRIES ||
68+
(*task_get_event_bitmap(emumouse_task_id) & PS2MOUSE_EVT_AUX_DATA)) {
6769
CPRINTS("PS2M Dropping");
6870
/*drop mouse packet - host is too far behind */
6971
return;
@@ -328,15 +330,28 @@ void read_touchpad_in_report(void)
328330
int xfer_len = 0;
329331
int16_t x, y;
330332
uint8_t response_byte = 0x08;
333+
334+
/* Make sure report id is set to an invalid value */
335+
data[2] = 0;
336+
337+
if (power_get_state() == POWER_S5)
338+
return;
339+
331340
/*dont trigger disable state during our own transactions*/
332341
gpio_disable_interrupt(GPIO_EC_I2C_3_SDA);
342+
i2c_set_timeout(I2C_PORT_TOUCHPAD, 25*MSEC);
333343
i2c_lock(I2C_PORT_TOUCHPAD, 1);
334344
rv = i2c_xfer_unlocked(I2C_PORT_TOUCHPAD,
335345
TOUCHPAD_I2C_HID_EP | I2C_FLAG_ADDR16_LITTLE_ENDIAN,
336346
NULL, 0, data, 2, I2C_XFER_START);
337347
if (rv != EC_SUCCESS)
338348
goto read_failed;
339349
xfer_len = (data[1]<<8) + data[0];
350+
if (xfer_len == 0) {
351+
/* touchpad has reset per i2c-hid-protocol 7.3 */
352+
CPRINTS("PS2M Touchpad Reset");
353+
goto read_failed;
354+
}
340355
xfer_len = MIN(126, xfer_len-2);
341356
rv = i2c_xfer_unlocked(I2C_PORT_TOUCHPAD,
342357
TOUCHPAD_I2C_HID_EP | I2C_FLAG_ADDR16_LITTLE_ENDIAN,
@@ -353,7 +368,13 @@ void read_touchpad_in_report(void)
353368
/* try again some other time later if the TP keeps interrupting us */
354369
detected_host_packet = true;
355370
inreport_retries = 0;
356-
CPRINTS("PS2M Too many retries");
371+
usleep(10*MSEC);
372+
/*The EC SMB controller sometimes gets in a bad state, so try to recover */
373+
MCHP_I2C_CTRL(MCHP_I2C_CTRL4) = BIT(7) |
374+
BIT(6) |
375+
BIT(3) |
376+
BIT(0);
377+
CPRINTS("PS2M %d Too many retries", rv);
357378
} else {
358379
hook_call_deferred(&retry_tp_read_evt_deferred_data, 25*MSEC);
359380
}
@@ -400,6 +421,7 @@ void read_touchpad_in_report(void)
400421
setup_touchpad();
401422
}
402423
}
424+
403425
}
404426
/*
405427
* Looking at timing it takes the SOC about 2ms to grab a tp packet from start of
@@ -410,6 +432,7 @@ void mouse_interrupt_handler_task(void *p)
410432
{
411433
int power_state = 0;
412434
int evt;
435+
int i;
413436

414437
emumouse_task_id = task_get_current();
415438
while (1) {
@@ -431,19 +454,20 @@ void mouse_interrupt_handler_task(void *p)
431454
if (ec_mode_disabled == false) {
432455
if (evt & PS2MOUSE_EVT_AUX_DATA) {
433456
process_request(aux_data);
434-
}
435-
436-
if (evt & PS2MOUSE_EVT_INTERRUPT) {
437-
usleep(4*MSEC);
457+
} else if (evt & PS2MOUSE_EVT_INTERRUPT) {
438458
/* at the expensive of a slight additional latency
439459
* check to see if the soc has grabbed this out from under us
440460
*/
441-
if (gpio_get_level(GPIO_SOC_TP_INT_L) == 1) {
442-
CPRINTS("PS2M Detected host packet during interrupt handling");
443-
detected_host_packet = true;
444-
} else {
445-
read_touchpad_in_report();
461+
for (i = 0; i < 4; i++) {
462+
usleep(MSEC);
463+
if (gpio_get_level(GPIO_SOC_TP_INT_L) == 1) {
464+
CPRINTS("PS2M Detected host pkt during int");
465+
detected_host_packet = true;
466+
break;
467+
}
446468
}
469+
if (detected_host_packet != true)
470+
read_touchpad_in_report();
447471
}
448472

449473
if (evt & PS2MOUSE_EVT_I2C_INTERRUPT) {
@@ -468,7 +492,7 @@ void mouse_interrupt_handler_task(void *p)
468492
if ((power_state == POWER_S3S0) && gpio_get_level(GPIO_SOC_TP_INT_L) == 0) {
469493
read_touchpad_in_report();
470494
}
471-
if (power_state == POWER_S0S3) {
495+
if (power_state == POWER_S0S3 || power_state == POWER_S5) {
472496
/* Power Down */
473497
gpio_disable_interrupt(GPIO_SOC_TP_INT_L);
474498
gpio_disable_interrupt(GPIO_EC_I2C_3_SDA);

board/hx30/ps2mouse.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ enum ps2_mouse_task_evt {
7070

7171
#define TOUCHPAD_I2C_RETRY_COUNT_TO_RENABLE 6
7272

73+
#define AUX_BUFFER_FULL_RETRIES 25
74+
7375
enum pixart_pct3854_regs {
7476
PCT3854_DESCRIPTOR = 0x0020,
7577
PCT3854_REPORT_DESC = 0x0021,

0 commit comments

Comments
 (0)