Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/arm/rockchip drop clk rate to 100kHz, explicit regi...
details: https://anonhg.NetBSD.org/src/rev/e19db7f4f3d0
branches: trunk
changeset: 335277:e19db7f4f3d0
user: jmcneill <jmcneill%NetBSD.org@localhost>
date: Thu Jan 01 15:18:45 2015 +0000
description:
drop clk rate to 100kHz, explicit register initialization, shift slave addr left 1, add some more debugging, now this works
diffstat:
sys/arch/arm/rockchip/rockchip_i2c.c | 73 +++++++++++++++++++++++++++++------
1 files changed, 59 insertions(+), 14 deletions(-)
diffs (180 lines):
diff -r 2005e8f74f57 -r e19db7f4f3d0 sys/arch/arm/rockchip/rockchip_i2c.c
--- a/sys/arch/arm/rockchip/rockchip_i2c.c Thu Jan 01 13:32:24 2015 +0000
+++ b/sys/arch/arm/rockchip/rockchip_i2c.c Thu Jan 01 15:18:45 2015 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: rockchip_i2c.c,v 1.3 2014/12/30 18:57:36 jmcneill Exp $ */
+/* $NetBSD: rockchip_i2c.c,v 1.4 2015/01/01 15:18:45 jmcneill Exp $ */
/*-
* Copyright (c) 2014 Jared D. McNeill <jmcneill%invisible.ca@localhost>
@@ -30,7 +30,7 @@
#include "opt_rkiic.h"
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rockchip_i2c.c,v 1.3 2014/12/30 18:57:36 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rockchip_i2c.c,v 1.4 2015/01/01 15:18:45 jmcneill Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -48,7 +48,7 @@
#include <dev/i2c/i2cvar.h>
-#define RKIIC_CLOCK_RATE 400000
+#define RKIIC_CLOCK_RATE 100000
struct rkiic_softc {
device_t sc_dev;
@@ -129,6 +129,14 @@
}
}
+ if (rkiic_set_rate(sc, RKIIC_CLOCK_RATE) != 0) {
+ aprint_error_dev(sc->sc_dev, "couldn't set clock rate\n");
+ return;
+ }
+
+ I2C_WRITE(sc, I2C_CON_REG, 0);
+ I2C_WRITE(sc, I2C_IEN_REG, 0);
+
sc->sc_ic.ic_cookie = sc;
sc->sc_ic.ic_acquire_bus = rkiic_acquire_bus;
sc->sc_ic.ic_release_bus = rkiic_release_bus;
@@ -151,6 +159,10 @@
I2C_WRITE(sc, I2C_IPD_REG, ipd);
+#ifdef RKIIC_INTR
+ device_printf(sc->sc_dev, "%s: ipd %#x\n", __func__, ipd);
+#endif
+
mutex_enter(&sc->sc_lock);
sc->sc_intr_ipd |= ipd;
cv_broadcast(&sc->sc_cv);
@@ -183,12 +195,12 @@
{
struct rkiic_softc *sc = priv;
uint32_t con, ien;
- u_int mode;
+ u_int mode, sraddr;
int error;
KASSERT(mutex_owned(&sc->sc_lock));
- if (sc->sc_ih == NULL) {
+ if (sc->sc_ih == NULL || cold) {
flags |= I2C_F_POLL;
}
@@ -199,30 +211,27 @@
if (error)
return error;
- 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_TRX;
} else {
mode = I2C_CON_MODE_TX;
}
- I2C_WRITE(sc, I2C_MRXRADDR_REG, I2C_MRXRADDR_SRADDLVLD |
- __SHIFTIN(reg, I2C_MRXRADDR_SRADDR));
+ sraddr = *(const uint8_t *)cmdbuf;
} 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);
+ sraddr = 0;
}
sc->sc_intr_ipd = 0;
+ I2C_WRITE(sc, I2C_IPD_REG, I2C_READ(sc, I2C_IPD_REG));
- ien = I2C_INT_START | (I2C_OP_READ_P(op) ? I2C_INT_MBRF : I2C_INT_MBTF);
+ ien = I2C_OP_READ_P(op) ? I2C_INT_MBRF : I2C_INT_MBTF;
+ ien |= I2C_INT_START | I2C_INT_STOP | I2C_INT_NAKRCV;
I2C_WRITE(sc, I2C_IEN_REG, ien);
con = I2C_CON_START | I2C_CON_EN | I2C_CON_ACK |
@@ -236,6 +245,13 @@
#endif
goto done;
}
+ con &= ~I2C_CON_START;
+ I2C_WRITE(sc, I2C_CON_REG, con);
+
+ I2C_WRITE(sc, I2C_MRXADDR_REG, I2C_MRXADDR_ADDLVLD |
+ __SHIFTIN((addr << 1), I2C_MRXADDR_SADDR));
+ I2C_WRITE(sc, I2C_MRXRADDR_REG, I2C_MRXRADDR_SRADDLVLD |
+ __SHIFTIN(sraddr, I2C_MRXRADDR_SRADDR));
if (I2C_OP_READ_P(op)) {
error = rkiic_read(sc, addr, buf, len, flags);
@@ -244,10 +260,22 @@
}
if (I2C_OP_STOP_P(op)) {
- I2C_WRITE(sc, I2C_CON_REG, I2C_CON_STOP);
+ con = I2C_READ(sc, I2C_CON_REG);
+ con |= I2C_CON_STOP;
+ I2C_WRITE(sc, I2C_CON_REG, con);
+ if (rkiic_wait(sc, I2C_INT_STOP, hz, flags) != 0) {
+#ifdef RKIIC_DEBUG
+ device_printf(sc->sc_dev, "timeout waiting for stop\n");
+#endif
+ error = ETIMEDOUT;
+ goto done;
+ }
+ con &= ~I2C_CON_STOP;
+ I2C_WRITE(sc, I2C_CON_REG, con);
}
done:
+ I2C_WRITE(sc, I2C_CON_REG, 0);
I2C_WRITE(sc, I2C_IEN_REG, 0);
return error;
}
@@ -283,6 +311,9 @@
}
}
+#ifdef RKIIC_DEBUG
+ device_printf(sc->sc_dev, "%s: ipd %#x\n", __func__, sc->sc_intr_ipd);
+#endif
return ETIMEDOUT;
}
@@ -307,6 +338,13 @@
return error;
}
+ if (sc->sc_intr_ipd & I2C_INT_NAKRCV) {
+#ifdef RKIIC_DEBUG
+ device_printf(sc->sc_dev, "nak received\n");
+#endif
+ return EIO;
+ }
+
for (off = 0, resid = buflen; off < 8 && resid > 0; off++) {
const uint32_t data = I2C_READ(sc, I2C_RXDATA_REG(off));
for (byte = 0; byte < 4 && resid > 0; byte++, resid--) {
@@ -346,6 +384,13 @@
return error;
}
+ if (sc->sc_intr_ipd & I2C_INT_NAKRCV) {
+#ifdef RKIIC_DEBUG
+ device_printf(sc->sc_dev, "nak received\n");
+#endif
+ return EIO;
+ }
+
return 0;
}
Home |
Main Index |
Thread Index |
Old Index