|
80 | 80 | #define CFG_ENABLE BIT(10) /* enable controller */ |
81 | 81 | #define CFG_GC_DIS BIT(14) /* disable general call address */ |
82 | 82 | #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 */ |
83 | 87 | #define CFG_ENIDI BIT(29) /* Enable I2C idle interrupt */ |
84 | 88 | /* Enable network layer master done interrupt */ |
85 | 89 | #define CFG_ENMI BIT(30) |
@@ -617,6 +621,21 @@ static int i2c_mtx(int ctrl) |
617 | 621 | cdata[ctrl].transaction_state = I2C_TRANSACTION_OPEN; |
618 | 622 | } |
619 | 623 |
|
| 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 | + |
620 | 639 | for (i = 0; i < cdata[ctrl].out_size; ++i) { |
621 | 640 | rv = wait_byte_done(ctrl, 0xff, 0x00); |
622 | 641 | if (rv) { |
@@ -700,6 +719,29 @@ static int i2c_mrx_start(int ctrl) |
700 | 719 | /* address then START */ |
701 | 720 | MCHP_I2C_CTRL(ctrl) = u8 | CTRL_PIN; |
702 | 721 | } |
| 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 | + |
703 | 745 | cdata[ctrl].transaction_state = I2C_TRANSACTION_OPEN; |
704 | 746 | /* Controller generates START, transmits data(address) capturing |
705 | 747 | * 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, |
841 | 883 |
|
842 | 884 | cdata[ctrl].flags |= (1ul << 15); |
843 | 885 | /* 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; |
845 | 888 | wait_idle(ctrl); |
| 889 | + } |
846 | 890 |
|
847 | 891 | /* Check for error conditions */ |
848 | 892 | if (MCHP_I2C_STATUS(ctrl) & (STS_LAB | STS_BER)) { |
|
0 commit comments