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)