Subject: I2C transactions & STOP condition
To: NetBSD kernel <tech-kern@netbsd.org>
From: Nicolas Joly <njoly@pasteur.fr>
List: tech-kern
Date: 07/22/2007 23:31:39
--y0ulUmNC+osPPQO6
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline


Hi,

I recently had a look on i2c devices code, and notices that some
devices transactions does not ends with a STOP conditions.

By example, the adt7463 code should use I2C_OP_{READ,WRITE}_WITH_STOP
instead of I2C_OP_{READ,WRITE} for adt7463c_receive_1(),
adt7463c_send_1() and adt7463c_write_1() functions.

If i understand the i2c specifications correctly, all transferts begin
with a START condition, and terminates with a STOP condition; in
between, the i2c bus remains busy.

Do the attached patch looks correct ?

-- 
Nicolas Joly

Biological Software and Databanks.
Institut Pasteur, Paris.

--y0ulUmNC+osPPQO6
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="netbsd-adt7463i2cstop.diff"

Index: sys/dev/i2c/adt7463.c
===================================================================
RCS file: /cvsroot/src/sys/dev/i2c/adt7463.c,v
retrieving revision 1.11
diff -u -r1.11 adt7463.c
--- sys/dev/i2c/adt7463.c	11 Jul 2007 21:15:54 -0000	1.11
+++ sys/dev/i2c/adt7463.c	22 Jul 2007 21:27:02 -0000
@@ -311,7 +311,7 @@
 	if ((error = iic_acquire_bus(sc->sc_tag, 0)) != 0)
 		return error;
 
-	if ((error = iic_exec(sc->sc_tag, I2C_OP_READ,
+	if ((error = iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
 		 sc->sc_address, NULL, 0, &val, 1, 0)) != 0) {
 		iic_release_bus(sc->sc_tag, 0);
 		return error;
@@ -329,7 +329,7 @@
 	if ((error = iic_acquire_bus(sc->sc_tag, 0)) != 0)
 		return error;
 
-	if ((error = iic_exec(sc->sc_tag, I2C_OP_WRITE,
+	if ((error = iic_exec(sc->sc_tag, I2C_OP_WRITE_WITH_STOP,
 		 sc->sc_address, NULL, 0, &val, 1, 0)) != 0) {
 		iic_release_bus(sc->sc_tag, 0);
 	  	return error;
@@ -347,7 +347,7 @@
 	if ((error = iic_acquire_bus(sc->sc_tag, 0)) != 0)
 		return error;
 
-	if ((error = iic_exec(sc->sc_tag, I2C_OP_WRITE,
+	if ((error = iic_exec(sc->sc_tag, I2C_OP_WRITE_WITH_STOP,
 		 sc->sc_address, &cmd, 1, &val, 1, 0)) != 0) {
 		iic_release_bus(sc->sc_tag, 0);
 	  	return error;

--y0ulUmNC+osPPQO6--