diff options
author | daichi <daichi@FreeBSD.org> | 2014-07-03 10:59:42 +0000 |
---|---|---|
committer | daichi <daichi@FreeBSD.org> | 2014-07-03 10:59:42 +0000 |
commit | ae7f3947da353afd9f1cae6fc79782260a040376 (patch) | |
tree | 01409047dc6532e2147bed73b2eae052081173f9 /sys/dev/glxiic | |
parent | 0553ac94fa339d7dd6192dd23056b8fd3c5daffa (diff) | |
download | FreeBSD-src-ae7f3947da353afd9f1cae6fc79782260a040376.zip FreeBSD-src-ae7f3947da353afd9f1cae6fc79782260a040376.tar.gz |
MFC: r267852
Fixed an IIC timing issue between the glxiic master and a slave of
peripheral devices. When transmitting (rx) from slave to master,
sometimes nAKC delays. As a result, some slaves fails their
transmission.
Submitted by: Masanori OZAWA <ozawa@ongs.co.jp>
Reviewed by: brix
Diffstat (limited to 'sys/dev/glxiic')
-rw-r--r-- | sys/dev/glxiic/glxiic.c | 22 |
1 files changed, 15 insertions, 7 deletions
diff --git a/sys/dev/glxiic/glxiic.c b/sys/dev/glxiic/glxiic.c index 6eeac7c..939c32d 100644 --- a/sys/dev/glxiic/glxiic.c +++ b/sys/dev/glxiic/glxiic.c @@ -711,6 +711,7 @@ static int glxiic_state_master_addr_callback(struct glxiic_softc *sc, uint8_t status) { uint8_t slave; + uint8_t ctrl1; GLXIIC_ASSERT_LOCKED(sc); @@ -746,6 +747,13 @@ glxiic_state_master_addr_callback(struct glxiic_softc *sc, uint8_t status) bus_write_1(sc->smb_res, GLXIIC_SMB_SDA, slave); + if ((sc->msg->flags & IIC_M_RD) != 0 && sc->ndata == 1) { + /* Last byte from slave, set NACK. */ + ctrl1 = bus_read_1(sc->smb_res, GLXIIC_SMB_CTRL1); + bus_write_1(sc->smb_res, GLXIIC_SMB_CTRL1, + ctrl1 | GLXIIC_SMB_CTRL1_ACK_BIT); + } + return (IIC_NOERR); } @@ -811,13 +819,6 @@ glxiic_state_master_rx_callback(struct glxiic_softc *sc, uint8_t status) return (IIC_ENOACK); } - if (sc->ndata == 1) { - /* Last byte from slave, set NACK. */ - ctrl1 = bus_read_1(sc->smb_res, GLXIIC_SMB_CTRL1); - bus_write_1(sc->smb_res, GLXIIC_SMB_CTRL1, - ctrl1 | GLXIIC_SMB_CTRL1_ACK_BIT); - } - if ((status & GLXIIC_SMB_STS_STASTR_BIT) != 0) { /* Bus is stalled, clear and wait for data. */ bus_write_1(sc->smb_res, GLXIIC_SMB_STS, @@ -837,6 +838,13 @@ glxiic_state_master_rx_callback(struct glxiic_softc *sc, uint8_t status) return (glxiic_state_table[sc->state].callback(sc, status)); } + if (sc->ndata == 1) { + /* Last byte from slave, set NACK. */ + ctrl1 = bus_read_1(sc->smb_res, GLXIIC_SMB_CTRL1); + bus_write_1(sc->smb_res, GLXIIC_SMB_CTRL1, + ctrl1 | GLXIIC_SMB_CTRL1_ACK_BIT); + } + glxiic_start_timeout_locked(sc); return (IIC_NOERR); |