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