Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 6 Sep 2006 20:30:36 GMT
From:      Warner Losh <imp@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 105736 for review
Message-ID:  <200609062030.k86KUak9053400@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=105736

Change 105736 by imp@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 }
 };
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200609062030.k86KUak9053400>