Module Name: src Committed By: phx Date: Sun Apr 17 15:15:00 UTC 2011
Modified Files: src/sys/dev/i2c: motoi2c.c motoi2cvar.h Log Message: Suppressing the ACK after the last byte read must not depend on I2C_OP_STOP_P(), but all read-transfers have to be finished that way. Otherwise a chip might hang after a read-operation without stop. Removed sc_start from the softc structure, which is unused. To generate a diff of this commit: cvs rdiff -u -r1.3 -r1.4 src/sys/dev/i2c/motoi2c.c \ src/sys/dev/i2c/motoi2cvar.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/i2c/motoi2c.c diff -u src/sys/dev/i2c/motoi2c.c:1.3 src/sys/dev/i2c/motoi2c.c:1.4 --- src/sys/dev/i2c/motoi2c.c:1.3 Wed Jan 12 18:06:26 2011 +++ src/sys/dev/i2c/motoi2c.c Sun Apr 17 15:14:59 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: motoi2c.c,v 1.3 2011/01/12 18:06:26 phx Exp $ */ +/* $NetBSD: motoi2c.c,v 1.4 2011/04/17 15:14:59 phx Exp $ */ /*- * Copyright (c) 2007, 2010 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: motoi2c.c,v 1.3 2011/01/12 18:06:26 phx Exp $"); +__KERNEL_RCSID(0, "$NetBSD: motoi2c.c,v 1.4 2011/04/17 15:14:59 phx Exp $"); #include <sys/param.h> #include <sys/device.h> @@ -98,7 +98,6 @@ sc->sc_i2c = motoi2c; sc->sc_i2c.ic_cookie = sc; - sc->sc_start = false; if (sc->sc_iord == NULL) sc->sc_iord = motoi2c_iord1; if (sc->sc_iowr == NULL) @@ -131,7 +130,6 @@ { struct motoi2c_softc * const sc = v; - sc->sc_start = false; I2C_WRITE(I2CCR, 0); /* reset before changing anything */ mutex_exit(&sc->sc_buslock); } @@ -289,9 +287,8 @@ if (I2C_OP_READ_P(op)) { uint8_t *dataptr = databuf; cr &= ~CR_MTX; /* clear transmit flags */ - if (datalen <= 1 && I2C_OP_STOP_P(op)) { + if (datalen <= 1) cr |= CR_TXAK; - } I2C_WRITE(I2CCR, cr); DELAY(10); (void)I2C_READ(I2CDR); /* dummy read */ @@ -309,19 +306,20 @@ __func__, i, error)); goto out; } - if (I2C_OP_STOP_P(op)) { - if (i == datalen - 2) { - cr |= CR_TXAK; - I2C_WRITE(I2CCR, cr); - } else if (i == datalen - 1) { - cr = CR_MEN; - I2C_WRITE(I2CCR, cr); - sc->sc_start = false; - } + if (i == datalen - 2) { + cr |= CR_TXAK; + I2C_WRITE(I2CCR, cr); + } else if (i == datalen - 1 && I2C_OP_STOP_P(op)) { + cr = CR_MEN; + I2C_WRITE(I2CCR, cr); } *dataptr++ = I2C_READ(I2CDR); } if (datalen == 0) { + if (I2C_OP_STOP_P(op)) { + cr = CR_MEN; + I2C_WRITE(I2CCR, cr); + } (void)I2C_READ(I2CDR); /* dummy read */ error = motoi2c_busy_wait(sc, cr); if (error) { Index: src/sys/dev/i2c/motoi2cvar.h diff -u src/sys/dev/i2c/motoi2cvar.h:1.3 src/sys/dev/i2c/motoi2cvar.h:1.4 --- src/sys/dev/i2c/motoi2cvar.h:1.3 Wed Jan 12 18:05:18 2011 +++ src/sys/dev/i2c/motoi2cvar.h Sun Apr 17 15:14:59 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: motoi2cvar.h,v 1.3 2011/01/12 18:05:18 phx Exp $ */ +/* $NetBSD: motoi2cvar.h,v 1.4 2011/04/17 15:14:59 phx Exp $ */ /*- * Copyright (c) 2007, 2010 The NetBSD Foundation, Inc. @@ -49,7 +49,6 @@ bus_space_handle_t sc_ioh; struct i2c_controller sc_i2c; kmutex_t sc_buslock; - bool sc_start; motoi2c_iord_t sc_iord; motoi2c_iowr_t sc_iowr; };