summaryrefslogtreecommitdiffstats
path: root/sys/dev/glxiic
diff options
context:
space:
mode:
authordaichi <daichi@FreeBSD.org>2014-07-03 10:59:42 +0000
committerdaichi <daichi@FreeBSD.org>2014-07-03 10:59:42 +0000
commitae7f3947da353afd9f1cae6fc79782260a040376 (patch)
tree01409047dc6532e2147bed73b2eae052081173f9 /sys/dev/glxiic
parent0553ac94fa339d7dd6192dd23056b8fd3c5daffa (diff)
downloadFreeBSD-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.c22
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);
OpenPOWER on IntegriCloud