diff options
author | daichi <daichi@FreeBSD.org> | 2014-06-25 05:39:30 +0000 |
---|---|---|
committer | daichi <daichi@FreeBSD.org> | 2014-06-25 05:39:30 +0000 |
commit | 28db5b9cc68d4f4f318d03b161780d3d29943910 (patch) | |
tree | 306cef2a87105373c92d1770d90df664e5c85d34 | |
parent | 0acfaa5d3d7ca74448a0a62b3f35f1d15c0ce9bd (diff) | |
download | FreeBSD-src-28db5b9cc68d4f4f318d03b161780d3d29943910.zip FreeBSD-src-28db5b9cc68d4f4f318d03b161780d3d29943910.tar.gz |
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
MFC after: 1 week
-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); |