Module Name:    src
Committed By:   jmcneill
Date:           Tue Dec 30 18:57:36 UTC 2014

Modified Files:
        src/sys/arch/arm/rockchip: files.rockchip rockchip_i2c.c
            rockchip_i2creg.h

Log Message:
Actually set slave addr / reg. Wait for start irq after sending start before
transferring data. Add RKIIC_DEBUG kernel option.


To generate a diff of this commit:
cvs rdiff -u -r1.4 -r1.5 src/sys/arch/arm/rockchip/files.rockchip
cvs rdiff -u -r1.2 -r1.3 src/sys/arch/arm/rockchip/rockchip_i2c.c
cvs rdiff -u -r1.1 -r1.2 src/sys/arch/arm/rockchip/rockchip_i2creg.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/arch/arm/rockchip/files.rockchip
diff -u src/sys/arch/arm/rockchip/files.rockchip:1.4 src/sys/arch/arm/rockchip/files.rockchip:1.5
--- src/sys/arch/arm/rockchip/files.rockchip:1.4	Tue Dec 30 17:15:31 2014
+++ src/sys/arch/arm/rockchip/files.rockchip	Tue Dec 30 18:57:36 2014
@@ -1,4 +1,4 @@
-#	$NetBSD: files.rockchip,v 1.4 2014/12/30 17:15:31 jmcneill Exp $
+#	$NetBSD: files.rockchip,v 1.5 2014/12/30 18:57:36 jmcneill Exp $
 #
 # Configuration info for Rockchip ARM Peripherals
 #
@@ -49,3 +49,4 @@ defparam opt_rockchip.h			MEMSIZE
 
 # Debugging parameters
 defflag opt_rockchip.h			ROCKCHIP_CLOCK_DEBUG
+defflag opt_rkiic.h			RKIIC_DEBUG

Index: src/sys/arch/arm/rockchip/rockchip_i2c.c
diff -u src/sys/arch/arm/rockchip/rockchip_i2c.c:1.2 src/sys/arch/arm/rockchip/rockchip_i2c.c:1.3
--- src/sys/arch/arm/rockchip/rockchip_i2c.c:1.2	Tue Dec 30 17:28:11 2014
+++ src/sys/arch/arm/rockchip/rockchip_i2c.c	Tue Dec 30 18:57:36 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: rockchip_i2c.c,v 1.2 2014/12/30 17:28:11 jmcneill Exp $ */
+/* $NetBSD: rockchip_i2c.c,v 1.3 2014/12/30 18:57:36 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2014 Jared D. McNeill <jmcne...@invisible.ca>
@@ -27,9 +27,10 @@
  */
 
 #include "locators.h"
+#include "opt_rkiic.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rockchip_i2c.c,v 1.2 2014/12/30 17:28:11 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rockchip_i2c.c,v 1.3 2014/12/30 18:57:36 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -181,7 +182,7 @@ rkiic_exec(void *priv, i2c_op_t op, i2c_
     const void *cmdbuf, size_t cmdlen, void *buf, size_t len, int flags)
 {
 	struct rkiic_softc *sc = priv;
-	uint32_t con;
+	uint32_t con, ien;
 	u_int mode;
 	int error;
 
@@ -191,32 +192,49 @@ rkiic_exec(void *priv, i2c_op_t op, i2c_
 		flags |= I2C_F_POLL;
 	}
 
+	if (cmdlen != 0 && cmdlen != 1)
+		return EINVAL;
+
 	error = rkiic_set_rate(sc, RKIIC_CLOCK_RATE);
 	if (error)
 		return error;
 
-	if (cmdlen > 0) {
+	I2C_WRITE(sc, I2C_MRXADDR_REG, I2C_MRXADDR_ADDLVLD |
+	    __SHIFTIN(addr, I2C_MRXADDR_SADDR));
+
+	if (cmdlen == 1) {
+		const uint8_t reg = *(const uint8_t *)cmdbuf;
 		if (I2C_OP_READ_P(op)) {
-			mode = I2C_CON_MODE_RRX;
-		} else {
 			mode = I2C_CON_MODE_TRX;
+		} else {
+			mode = I2C_CON_MODE_TX;
 		}
+		I2C_WRITE(sc, I2C_MRXRADDR_REG, I2C_MRXRADDR_SRADDLVLD |
+		    __SHIFTIN(reg, I2C_MRXRADDR_SRADDR));
 	} else {
 		if (I2C_OP_READ_P(op)) {
 			mode = I2C_CON_MODE_RX;
 		} else {
 			mode = I2C_CON_MODE_TX;
 		}
+		I2C_WRITE(sc, I2C_MRXRADDR_REG, 0);
 	}
-	con = I2C_CON_START | I2C_CON_EN | __SHIFTIN(mode, I2C_CON_MODE);
 
+	sc->sc_intr_ipd = 0;
+
+	ien = I2C_INT_START | (I2C_OP_READ_P(op) ? I2C_INT_MBRF : I2C_INT_MBTF);
+	I2C_WRITE(sc, I2C_IEN_REG, ien);
+
+	con = I2C_CON_START | I2C_CON_EN | I2C_CON_ACK |
+	    __SHIFTIN(mode, I2C_CON_MODE);
 	I2C_WRITE(sc, I2C_CON_REG, con);
 
-	if (cmdlen > 0) {
-		error = rkiic_write(sc, addr, cmdbuf, cmdlen, flags);
-		if (error) {
-			goto done;
-		}
+	error = rkiic_wait(sc, I2C_INT_START, hz, flags);
+	if (error) {
+#ifdef RKIIC_DEBUG
+		device_printf(sc->sc_dev, "timeout waiting for start\n");
+#endif
+		goto done;
 	}
 
 	if (I2C_OP_READ_P(op)) {
@@ -225,11 +243,12 @@ rkiic_exec(void *priv, i2c_op_t op, i2c_
 		error = rkiic_write(sc, addr, buf, len, flags);
 	}
 
-done:
 	if (I2C_OP_STOP_P(op)) {
 		I2C_WRITE(sc, I2C_CON_REG, I2C_CON_STOP);
 	}
 
+done:
+	I2C_WRITE(sc, I2C_IEN_REG, 0);
 	return error;
 }
 
@@ -246,14 +265,14 @@ rkiic_wait(struct rkiic_softc *sc, uint3
 	if (flags & I2C_F_POLL) {
 		retry = (timeout / hz) * 1000000;
 		while (retry > 0) {
-			if (I2C_READ(sc, I2C_IPD_REG) & mask)
+			sc->sc_intr_ipd |= I2C_READ(sc, I2C_IPD_REG);
+			if (sc->sc_intr_ipd & mask)
 				return 0;
 			delay(1);
 			--retry;
 		}
 	} else {
 		retry = timeout / hz;
-
 		while (retry > 0) {
 			error = cv_timedwait(&sc->sc_cv, &sc->sc_lock, hz);
 			if (error && error != EWOULDBLOCK)
@@ -278,17 +297,15 @@ rkiic_read(struct rkiic_softc *sc, i2c_a
 	if (buflen > 32)
 		return EINVAL;
 
-	sc->sc_intr_ipd = 0;
-
-	if (!(flags & I2C_F_POLL)) {
-		I2C_WRITE(sc, I2C_IEN_REG, I2C_INT_MBRF);
-	}
-
 	I2C_WRITE(sc, I2C_MRXCNT_REG, __SHIFTIN(buflen, I2C_MRXCNT_COUNT));
 
 	error = rkiic_wait(sc, I2C_INT_MBRF, hz, flags);
-	if (error)
-		goto done;
+	if (error) {
+#ifdef RKIIC_DEBUG
+		device_printf(sc->sc_dev, "read timeout\n");
+#endif
+		return error;
+	}
 
 	for (off = 0, resid = buflen; off < 8 && resid > 0; off++) {
 		const uint32_t data = I2C_READ(sc, I2C_RXDATA_REG(off));
@@ -297,12 +314,7 @@ rkiic_read(struct rkiic_softc *sc, i2c_a
 		}
 	}
 
-done:
-	if (!(flags & I2C_F_POLL)) {
-		I2C_WRITE(sc, I2C_IEN_REG, 0);
-	}
-
-	return error;
+	return 0;
 }
 
 static int
@@ -316,12 +328,6 @@ rkiic_write(struct rkiic_softc *sc, i2c_
 	if (buflen > 32)
 		return EINVAL;
 
-	sc->sc_intr_ipd = 0;
-
-	if (!(flags & I2C_F_POLL)) {
-		I2C_WRITE(sc, I2C_IEN_REG, I2C_INT_MBTF);
-	}
-
 	for (off = 0, resid = buflen; off < 8 && resid > 0; off++) {
 		uint32_t data = 0;
 		for (byte = 0; byte < 4 && resid > 0; byte++, resid--) {
@@ -333,15 +339,14 @@ rkiic_write(struct rkiic_softc *sc, i2c_
 	I2C_WRITE(sc, I2C_MTXCNT_REG, __SHIFTIN(buflen, I2C_MTXCNT_COUNT));
 
 	error = rkiic_wait(sc, I2C_INT_MBTF, hz, flags);
-	if (error)
-		goto done;
-
-done:
-	if (!(flags & I2C_F_POLL)) {
-		I2C_WRITE(sc, I2C_IEN_REG, 0);
+	if (error) {
+#ifdef RKIIC_DEBUG
+		device_printf(sc->sc_dev, "write timeout\n");
+#endif
+		return error;
 	}
 
-	return error;
+	return 0;
 
 }
 

Index: src/sys/arch/arm/rockchip/rockchip_i2creg.h
diff -u src/sys/arch/arm/rockchip/rockchip_i2creg.h:1.1 src/sys/arch/arm/rockchip/rockchip_i2creg.h:1.2
--- src/sys/arch/arm/rockchip/rockchip_i2creg.h:1.1	Tue Dec 30 17:15:31 2014
+++ src/sys/arch/arm/rockchip/rockchip_i2creg.h	Tue Dec 30 18:57:36 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: rockchip_i2creg.h,v 1.1 2014/12/30 17:15:31 jmcneill Exp $ */
+/* $NetBSD: rockchip_i2creg.h,v 1.2 2014/12/30 18:57:36 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2014 Jared D. McNeill <jmcne...@invisible.ca>
@@ -63,7 +63,7 @@
 #define I2C_MRXRADDR_SRADDHVLD	__BIT(26)
 #define I2C_MRXRADDR_SRADDMVLD	__BIT(25)
 #define I2C_MRXRADDR_SRADDLVLD	__BIT(24)
-#define I2C_MRXADDR_SADDR	__BITS(23,0)
+#define I2C_MRXRADDR_SRADDR	__BITS(23,0)
 
 #define I2C_MTXCNT_COUNT	__BITS(5,0)
 

Reply via email to