Skip to content

Commit 5d085d0

Browse files
authored
Merge pull request #490 from FrameworkComputer/hx20.i2c_port_workaround
Fixed touchpad cannot work due to i2c bus error
2 parents 9f8cf53 + 0b1e076 commit 5d085d0

File tree

2 files changed

+63
-11
lines changed

2 files changed

+63
-11
lines changed

board/hx20/ps2mouse.c

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -305,7 +305,7 @@ void setup_touchpad(void)
305305
/* These are touchpad firmware dependent
306306
* They set the touchpad into the mouse device mode, instead of PTP mode
307307
* And are based on the HID descriptor for our unique device */
308-
const static uint16_t cmd[5] = {0x0336, 0x0023, 0x0004, 0x0006};
308+
const static uint16_t cmd[4] = {0x0336, 0x0023, 0x0004, 0x0006};
309309

310310
rv = i2c_write_offset16_block(I2C_PORT_TOUCHPAD,
311311
TOUCHPAD_I2C_HID_EP | I2C_FLAG_ADDR16_LITTLE_ENDIAN,
@@ -326,6 +326,7 @@ static int inreport_retries;
326326
void read_touchpad_in_report(void)
327327
{
328328
int rv = EC_SUCCESS;
329+
int need_reset = 0;
329330
uint8_t data[128];
330331
int xfer_len = 0;
331332
int16_t x, y;
@@ -340,6 +341,8 @@ void read_touchpad_in_report(void)
340341

341342
/*dont trigger disable state during our own transactions*/
342343
gpio_disable_interrupt(GPIO_EC_I2C_3_SDA);
344+
/* need to disable SOC_TP_INT_L if we need to setup touchpad */
345+
gpio_disable_interrupt(GPIO_SOC_TP_INT_L);
343346
i2c_set_timeout(I2C_PORT_TOUCHPAD, 25*MSEC);
344347
i2c_lock(I2C_PORT_TOUCHPAD, 1);
345348
rv = i2c_xfer_unlocked(I2C_PORT_TOUCHPAD,
@@ -349,9 +352,14 @@ void read_touchpad_in_report(void)
349352
goto read_failed;
350353
xfer_len = (data[1]<<8) + data[0];
351354
if (xfer_len == 0) {
352-
/* touchpad has reset per i2c-hid-protocol 7.3 */
353-
CPRINTS("PS2M Touchpad Reset");
354-
goto read_failed;
355+
/**
356+
* touchpad has reset per i2c-hid-protocol 7.3
357+
* We need to complete the read protocol to make sure i2c state machine
358+
* is correct.
359+
*/
360+
CPRINTS("PS2M Touchpad need to reset");
361+
xfer_len = 6;
362+
need_reset = 1;
355363
}
356364
xfer_len = MIN(126, xfer_len-2);
357365
rv = i2c_xfer_unlocked(I2C_PORT_TOUCHPAD,
@@ -385,7 +393,7 @@ void read_touchpad_in_report(void)
385393
}
386394
i2c_lock(I2C_PORT_TOUCHPAD, 0);
387395
gpio_enable_interrupt(GPIO_EC_I2C_3_SDA);
388-
396+
gpio_enable_interrupt(GPIO_SOC_TP_INT_L);
389397
if (mouse_state == PS2MSTATE_RESET) {
390398
return;
391399
}
@@ -416,13 +424,13 @@ void read_touchpad_in_report(void)
416424
current_pos[1] = x;
417425
current_pos[2] = y;
418426
send_movement_packet();
419-
} else {
420-
if (rv == EC_SUCCESS) {
421-
CPRINTS("PS2M Unexpected Report ID %d reconfiguring", data[2]);
422-
setup_touchpad();
423-
}
424427
}
425428

429+
if (need_reset) {
430+
CPRINTS("PS2M Unexpected Report ID %d reconfiguring", data[2]);
431+
setup_touchpad();
432+
need_reset = 0;
433+
}
426434
}
427435
/*
428436
* Looking at timing it takes the SOC about 2ms to grab a tp packet from start of

chip/mchp/i2c.c

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,10 @@
8080
#define CFG_ENABLE BIT(10) /* enable controller */
8181
#define CFG_GC_DIS BIT(14) /* disable general call address */
8282
#define CFG_PROM_EN BIT(15) /* enable Promiscuous mode */
83+
#define CFG_FLUSH_SXBUF (16) /* clear slave Tx buffer */
84+
#define CFG_FLUSH_SRBUF (17) /* clear slave Rx buffer */
85+
#define CFG_FLUSH_MXBUF (18) /* clear master Tx buffer */
86+
#define CFG_FLUSH_MRBUF (19) /* clear master Rx buffer */
8387
#define CFG_ENIDI BIT(29) /* Enable I2C idle interrupt */
8488
/* Enable network layer master done interrupt */
8589
#define CFG_ENMI BIT(30)
@@ -617,6 +621,21 @@ static int i2c_mtx(int ctrl)
617621
cdata[ctrl].transaction_state = I2C_TRANSACTION_OPEN;
618622
}
619623

624+
/* Workaround to revocer the LAB flag error */
625+
while (MCHP_I2C_STATUS(ctrl) & STS_LAB) {
626+
CPRINTS("I2C%d wSTS LAB error, doing reset!", ctrl);
627+
MCHP_I2C_CONFIG(ctrl) |= CFG_FLUSH_MRBUF | CFG_FLUSH_MXBUF |
628+
CFG_FLUSH_SRBUF | CFG_FLUSH_SXBUF;
629+
reset_controller(ctrl);
630+
usleep(1000);
631+
632+
MCHP_I2C_DATA(ctrl) = cdata[ctrl].slv_addr_8bit;
633+
/* Clock out the slave address, sending START bit */
634+
MCHP_I2C_CTRL(ctrl) = CTRL_PIN | CTRL_ESO | CTRL_ENI |
635+
CTRL_ACK | CTRL_STA;
636+
cdata[ctrl].transaction_state = I2C_TRANSACTION_OPEN;
637+
}
638+
620639
for (i = 0; i < cdata[ctrl].out_size; ++i) {
621640
rv = wait_byte_done(ctrl, 0xff, 0x00);
622641
if (rv) {
@@ -700,6 +719,29 @@ static int i2c_mrx_start(int ctrl)
700719
/* address then START */
701720
MCHP_I2C_CTRL(ctrl) = u8 | CTRL_PIN;
702721
}
722+
723+
/* Workaround to revocer the LAB flag error */
724+
while (MCHP_I2C_STATUS(ctrl) & STS_LAB) {
725+
CPRINTS("I2C%d rSTS LAB error, doing reset!", ctrl);
726+
MCHP_I2C_CONFIG(ctrl) |= CFG_FLUSH_MRBUF | CFG_FLUSH_MXBUF |
727+
CFG_FLUSH_SRBUF | CFG_FLUSH_SXBUF;
728+
reset_controller(ctrl);
729+
usleep(1000);
730+
731+
if (cdata[ctrl].transaction_state == I2C_TRANSACTION_OPEN) {
732+
cdata[ctrl].flags |= (1ul << 5);
733+
/* Repeated-START then address */
734+
MCHP_I2C_CTRL(ctrl) = u8;
735+
}
736+
737+
MCHP_I2C_DATA(ctrl) = cdata[ctrl].slv_addr_8bit | 0x01;
738+
if (cdata[ctrl].transaction_state == I2C_TRANSACTION_STOPPED) {
739+
cdata[ctrl].flags |= (1ul << 6);
740+
/* address then START */
741+
MCHP_I2C_CTRL(ctrl) = u8 | CTRL_PIN;
742+
}
743+
}
744+
703745
cdata[ctrl].transaction_state = I2C_TRANSACTION_OPEN;
704746
/* Controller generates START, transmits data(address) capturing
705747
* 9-bits from SDA (8-bit address + (N)Ack bit).
@@ -841,8 +883,10 @@ int chip_i2c_xfer(int port, uint16_t slave_addr_flags,
841883

842884
cdata[ctrl].flags |= (1ul << 15);
843885
/* MCHP wait for STOP to complete */
844-
if (cdata[ctrl].xflags & I2C_XFER_STOP)
886+
if (cdata[ctrl].xflags & I2C_XFER_STOP) {
887+
cdata[ctrl].transaction_state = I2C_TRANSACTION_STOPPED;
845888
wait_idle(ctrl);
889+
}
846890

847891
/* Check for error conditions */
848892
if (MCHP_I2C_STATUS(ctrl) & (STS_LAB | STS_BER)) {

0 commit comments

Comments
 (0)