PERFORCE change 105736 for review
Warner Losh
imp at FreeBSD.org
Wed Sep 6 20:30:37 UTC 2006
http://perforce.freebsd.org/chv.cgi?CH=105736
Change 105736 by imp at imp_lighthouse on 2006/09/06 20:30:12
make twi support bulk transfer. I'm not sure that the 'broken down'
elements of a iic transfer work with this driver, but the bulk transfer
should work.
Affected files ...
.. //depot/projects/arm/src/sys/arm/at91/at91_twi.c#20 edit
Differences ...
==== //depot/projects/arm/src/sys/arm/at91/at91_twi.c#20 (text+ko) ====
@@ -228,12 +228,15 @@
}
static int
-at91_twi_wait_stop_done(struct at91_twi_softc *sc)
+at91_twi_wait(struct at91_twi_softc *sc, uint32_t bit)
{
int err = 0;
+ int counter = 10000;
- while (!(RD4(sc, TWI_SR) & TWI_SR_TXCOMP))
+ while (!(RD4(sc, TWI_SR) & bit) && counter-- != 0)
continue;
+ if (counter == 0)
+ err = EIO;
return (err);
}
@@ -252,7 +255,7 @@
sc = device_get_softc(dev);
if (sc->sc_started) {
WR4(sc, TWI_CR, TWI_CR_STOP);
- err = at91_twi_wait_stop_done(sc);
+ err = at91_twi_wait(sc, TWI_SR_TXCOMP);
}
return (err);
}
@@ -345,7 +348,7 @@
if (!last)
goto errout;
WR4(sc, TWI_CR, TWI_CR_STOP);
- err = at91_twi_wait_stop_done(sc);
+ err = at91_twi_wait(sc, TWI_SR_TXCOMP);
*walker = RD4(sc, TWI_RHR) & 0xff;
if (read)
*read = walker - buf;
@@ -419,6 +422,53 @@
return (error);
}
+static int
+at91_twi_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs)
+{
+ struct at91_twi_softc *sc;
+ int i, len;
+ uint32_t rdwr;
+ uint8_t *buf;
+
+ sc = device_get_softc(dev);
+ for (i = 0; i < nmsgs; i++) {
+ /*
+ * The linux atmel driver doesn't use the internal device
+ * address feature of twi. A separate i2c message needs to
+ * be written to use this.
+ * See http://lists.arm.linux.org.uk/pipermail/linux-arm-kernel/2004-September/024411.html
+ * for details.
+ */
+ rdwr = (msgs[i].flags & IIC_M_RD) ? TWI_MMR_MREAD : 0;
+ WR4(sc, TWI_MMR, TWI_MMR_DADR(msgs[i].slave) | rdwr);
+ len = msgs[i].len;
+ buf = msgs[i].buf;
+ if (len != 0 || buf == NULL)
+ return EINVAL;
+ WR4(sc, TWI_CR, TWI_CR_START);
+ if (msgs[i].flags & IIC_M_RD) {
+ while (len--) {
+ if (len == 0)
+ WR4(sc, TWI_CR, TWI_CR_STOP);
+ if (!at91_twi_wait(sc, TWI_SR_RXRDY))
+ return EIO;
+ *buf++ = RD4(sc, TWI_RHR) & 0xff;
+ }
+ } else {
+ while (len--) {
+ WR4(sc, TWI_THR, *buf++);
+ if (len == 0)
+ WR4(sc, TWI_CR, TWI_CR_STOP);
+ if (!at91_twi_wait(sc, TWI_SR_TXRDY))
+ return EIO;
+ }
+ }
+ if (!at91_twi_wait(sc, TWI_SR_TXCOMP))
+ return EIO;
+ }
+ return 0;
+}
+
static device_method_t at91_twi_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, at91_twi_probe),
@@ -433,6 +483,7 @@
DEVMETHOD(iicbus_write, at91_twi_write),
DEVMETHOD(iicbus_read, at91_twi_read),
DEVMETHOD(iicbus_reset, at91_twi_rst_card),
+ DEVMETHOD(iicbus_transfer, at91_twi_transfer),
{ 0, 0 }
};
More information about the p4-projects
mailing list