Date: Tue, 19 Dec 2006 07:57:12 GMT From: Warner Losh <imp@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 111931 for review Message-ID: <200612190757.kBJ7vCq3058570@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=111931 Change 111931 by imp@imp_lighthouse on 2006/12/19 07:57:09 Fix two major bugs, and a bunch of nits: o Eliminate an extra, redundant reading off the sr. o If we don't read enough bytes, don't pretend that we did. Instead, return an error. Maybe we should give an indication of how many bytes were read in this case, but for now we just return the error. o When we encounter an error, use the big hammer of software reset to fix. This may not be entirely necessary but seems to help solve problems we see when reading after there's been an error. o Return ENXIO for NACK. Lame error message, but follows existing practice. o Use #defines for clock speeds rather than hard coding numbers. # this makes it possible to read from existent and then non-existent # devices in a tight loop w/o occasional data corruption of many # flavors. Affected files ... .. //depot/projects/arm/src/sys/arm/at91/at91_twi.c#40 edit Differences ... ==== //depot/projects/arm/src/sys/arm/at91/at91_twi.c#40 (text+ko) ==== @@ -45,6 +45,10 @@ #include <dev/iicbus/iicbus.h> #include "iicbus_if.h" +#define TWI_SLOW_CLOCK 1500 +#define TWI_FAST_CLOCK 45000 +#define TWI_FASTEST_CLOCK 90000 + struct at91_twi_softc { device_t dev; /* Myself */ @@ -123,7 +127,7 @@ AT91_TWI_LOCK_DESTROY(sc); goto out; } - sc->cwgr = TWI_CWGR_CKDIV(8 * AT91C_MASTER_CLOCK / 90000) | + sc->cwgr = TWI_CWGR_CKDIV(8 * AT91C_MASTER_CLOCK / TWI_FASTEST_CLOCK) | TWI_CWGR_CHDIV(TWI_CWGR_DIV(TWI_DEF_CLK)) | TWI_CWGR_CLDIV(TWI_CWGR_DIV(TWI_DEF_CLK)); WR4(sc, TWI_CR, TWI_CR_SWRST); @@ -232,7 +236,7 @@ if (counter <= 0) err = EBUSY; else if (sr & TWI_SR_NACK) - err = EADDRNOTAVAIL; + err = ENXIO; // iic nack convention return (err); } @@ -252,17 +256,17 @@ */ switch (speed) { case IIC_SLOW: - clk = 1500; + clk = TWI_SLOW_CLOCK; break; case IIC_FAST: - clk = 45000; + clk = TWI_FAST_CLOCK; break; case IIC_UNKNOWN: case IIC_FASTEST: default: - clk = 90000; + clk = TWI_FASTEST_CLOCK; break; } sc->cwgr = TWI_CWGR_CKDIV(1) | TWI_CWGR_CHDIV(TWI_CWGR_DIV(clk)) | @@ -332,7 +336,6 @@ if (msgs[i].flags & IIC_M_RD) { sr = RD4(sc, TWI_SR); while (!(sr & TWI_SR_TXCOMP)) { - sr = RD4(sc, TWI_SR); if ((sr = RD4(sc, TWI_SR)) & TWI_SR_RXRDY) { len--; *buf++ = RD4(sc, TWI_RHR) & 0xff; @@ -340,8 +343,8 @@ WR4(sc, TWI_CR, TWI_CR_STOP); } } - if (sr & TWI_SR_NACK) { - err = EADDRNOTAVAIL; + if (len > 0 || (sr & TWI_SR_NACK)) { + err = ENXIO; // iic nack convention goto out; } } else { @@ -357,8 +360,11 @@ break; } out:; - if (err) - WR4(sc, TWI_CR, TWI_CR_STOP); + if (err) { + WR4(sc, TWI_CR, TWI_CR_SWRST); + WR4(sc, TWI_CR, TWI_CR_MSEN | TWI_CR_SVDIS); + WR4(sc, TWI_CWGR, sc->cwgr); + } AT91_TWI_UNLOCK(sc); return (err); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200612190757.kBJ7vCq3058570>