|
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) |
@@ -619,6 +623,21 @@ static int i2c_mtx(int ctrl) |
619 | 623 | cdata[ctrl].transaction_state = I2C_TRANSACTION_OPEN; |
620 | 624 | } |
621 | 625 |
|
| 626 | + /* Workaround to revocer the LAB flag error */ |
| 627 | + while (MCHP_I2C_STATUS(ctrl) & STS_LAB) { |
| 628 | + CPRINTS("I2C%d wSTS LAB error, doing reset!", ctrl); |
| 629 | + MCHP_I2C_CONFIG(ctrl) |= CFG_FLUSH_MRBUF | CFG_FLUSH_MXBUF | |
| 630 | + CFG_FLUSH_SRBUF | CFG_FLUSH_SXBUF; |
| 631 | + reset_controller(ctrl); |
| 632 | + usleep(1000); |
| 633 | + |
| 634 | + MCHP_I2C_DATA(ctrl) = cdata[ctrl].slv_addr_8bit; |
| 635 | + /* Clock out the slave address, sending START bit */ |
| 636 | + MCHP_I2C_CTRL(ctrl) = CTRL_PIN | CTRL_ESO | CTRL_ENI | |
| 637 | + CTRL_ACK | CTRL_STA; |
| 638 | + cdata[ctrl].transaction_state = I2C_TRANSACTION_OPEN; |
| 639 | + } |
| 640 | + |
622 | 641 | for (i = 0; i < cdata[ctrl].out_size; ++i) { |
623 | 642 | rv = wait_byte_done(ctrl, 0xff, 0x00); |
624 | 643 | if (rv) { |
@@ -702,6 +721,30 @@ static int i2c_mrx_start(int ctrl) |
702 | 721 | /* address then START */ |
703 | 722 | MCHP_I2C_CTRL(ctrl) = u8 | CTRL_PIN; |
704 | 723 | } |
| 724 | + |
| 725 | + /* Workaround to revocer the LAB flag error */ |
| 726 | + while (MCHP_I2C_STATUS(ctrl) & STS_LAB) { |
| 727 | + CPRINTS("I2C%d rSTS LAB error, doing reset!", ctrl); |
| 728 | + MCHP_I2C_CONFIG(ctrl) |= CFG_FLUSH_MRBUF | CFG_FLUSH_MXBUF | |
| 729 | + CFG_FLUSH_SRBUF | CFG_FLUSH_SXBUF; |
| 730 | + reset_controller(ctrl); |
| 731 | + usleep(1000); |
| 732 | + |
| 733 | + if (cdata[ctrl].transaction_state == I2C_TRANSACTION_OPEN) { |
| 734 | + cdata[ctrl].flags |= (1ul << 5); |
| 735 | + /* Repeated-START then address */ |
| 736 | + MCHP_I2C_CTRL(ctrl) = u8; |
| 737 | + } |
| 738 | + |
| 739 | + MCHP_I2C_DATA(ctrl) = cdata[ctrl].slv_addr_8bit | 0x01; |
| 740 | + if (cdata[ctrl].transaction_state == I2C_TRANSACTION_STOPPED) { |
| 741 | + cdata[ctrl].flags |= (1ul << 6); |
| 742 | + /* address then START */ |
| 743 | + MCHP_I2C_CTRL(ctrl) = u8 | CTRL_PIN; |
| 744 | + } |
| 745 | + } |
| 746 | + |
| 747 | + |
705 | 748 | cdata[ctrl].transaction_state = I2C_TRANSACTION_OPEN; |
706 | 749 | /* Controller generates START, transmits data(address) capturing |
707 | 750 | * 9-bits from SDA (8-bit address + (N)Ack bit). |
@@ -843,8 +886,10 @@ int chip_i2c_xfer(int port, uint16_t slave_addr_flags, |
843 | 886 |
|
844 | 887 | cdata[ctrl].flags |= (1ul << 15); |
845 | 888 | /* MCHP wait for STOP to complete */ |
846 | | - if (cdata[ctrl].xflags & I2C_XFER_STOP) |
| 889 | + if (cdata[ctrl].xflags & I2C_XFER_STOP) { |
| 890 | + cdata[ctrl].transaction_state = I2C_TRANSACTION_STOPPED; |
847 | 891 | wait_idle(ctrl); |
| 892 | + } |
848 | 893 |
|
849 | 894 | /* Check for error conditions */ |
850 | 895 | if (MCHP_I2C_STATUS(ctrl) & (STS_LAB | STS_BER)) { |
|
0 commit comments