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
This commit is contained in:
Daichi GOTO 2014-06-25 05:39:30 +00:00
parent a99098e2ba
commit 55e79db6d8

View File

@ -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);