From owner-p4-projects@FreeBSD.ORG Wed Sep 6 20:30:37 2006 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 90F3C16A509; Wed, 6 Sep 2006 20:30:37 +0000 (UTC) X-Original-To: perforce@freebsd.org Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 4E04F16A506 for ; Wed, 6 Sep 2006 20:30:37 +0000 (UTC) (envelope-from imp@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 7631B43D70 for ; Wed, 6 Sep 2006 20:30:36 +0000 (GMT) (envelope-from imp@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.6/8.13.6) with ESMTP id k86KUaRq053403 for ; Wed, 6 Sep 2006 20:30:36 GMT (envelope-from imp@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.6/8.13.4/Submit) id k86KUak9053400 for perforce@freebsd.org; Wed, 6 Sep 2006 20:30:36 GMT (envelope-from imp@freebsd.org) Date: Wed, 6 Sep 2006 20:30:36 GMT Message-Id: <200609062030.k86KUak9053400@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to imp@freebsd.org using -f From: Warner Losh To: Perforce Change Reviews Cc: Subject: PERFORCE change 105736 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 06 Sep 2006 20:30:37 -0000 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 } };