Skip to content

Commit 802b1e3

Browse files
author
Josh Tsai
committed
WORKAROUND: avoid the i2c controller no response
When the LAB flag is set in i2c controller status register, we should reset the controller to avoid i2c controller no response. We also need to change the ttansaction_state to stopped when i2c read is completed. Signed-off-by: Josh Tsai <josh_tsai@compal.com>
1 parent 9f8cf53 commit 802b1e3

File tree

2 files changed

+46
-2
lines changed

2 files changed

+46
-2
lines changed

board/hx20/ps2mouse.c

Lines changed: 1 addition & 1 deletion
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,

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)