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 Support reads of more than 32 bytes in...



details:   https://anonhg.NetBSD.org/src/rev/cabc02b60c3c
branches:  trunk
changeset: 460891:cabc02b60c3c
user:      jmcneill <jmcneill%NetBSD.org@localhost>
date:      Fri Nov 08 00:35:16 2019 +0000

description:
Support reads of more than 32 bytes in a single xfer.

diffstat:

 sys/arch/arm/rockchip/rk_i2c.c |  51 +++++++++++++++++++++++++++++------------
 1 files changed, 36 insertions(+), 15 deletions(-)

diffs (102 lines):

diff -r 226371892992 -r cabc02b60c3c sys/arch/arm/rockchip/rk_i2c.c
--- a/sys/arch/arm/rockchip/rk_i2c.c    Thu Nov 07 22:25:21 2019 +0000
+++ b/sys/arch/arm/rockchip/rk_i2c.c    Fri Nov 08 00:35:16 2019 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: rk_i2c.c,v 1.5 2019/09/18 12:49:34 tnn Exp $ */
+/* $NetBSD: rk_i2c.c,v 1.6 2019/11/08 00:35:16 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2018 Jared McNeill <jmcneill%invisible.ca@localhost>
@@ -28,7 +28,7 @@
 
 #include <sys/cdefs.h>
 
-__KERNEL_RCSID(0, "$NetBSD: rk_i2c.c,v 1.5 2019/09/18 12:49:34 tnn Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rk_i2c.c,v 1.6 2019/11/08 00:35:16 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -284,7 +284,7 @@
 static int
 rk_i2c_read(struct rk_i2c_softc *sc, i2c_addr_t addr,
     const uint8_t *cmd, size_t cmdlen, uint8_t *buf,
-    size_t buflen, int flags, bool send_start)
+    size_t buflen, int flags, bool send_start, bool last_ack)
 {
        uint32_t rxdata[8];
        uint32_t con, mrxaddr, mrxraddr;
@@ -296,24 +296,27 @@
        if (cmdlen > 3)
                return EINVAL;
 
-       mode = RKI2C_CON_I2C_MODE_RTX;
-       con = RKI2C_CON_I2C_EN | RKI2C_CON_ACK | __SHIFTIN(mode, RKI2C_CON_I2C_MODE);
+       mode = send_start ? RKI2C_CON_I2C_MODE_RTX : RKI2C_CON_I2C_MODE_RX;
+       con = RKI2C_CON_I2C_EN | __SHIFTIN(mode, RKI2C_CON_I2C_MODE);
        WR4(sc, RKI2C_CON, con);
 
        if (send_start && (error = rk_i2c_start(sc)) != 0)
                return error;
 
-       mrxaddr = __SHIFTIN((addr << 1) | 1, RKI2C_MRXADDR_SADDR) |
-           RKI2C_MRXADDR_ADDLVLD;
-       WR4(sc, RKI2C_MRXADDR, mrxaddr);
-       for (n = 0, mrxraddr = 0; n < cmdlen; n++) {
-               mrxraddr |= cmd[n] << (n * 8);
-               mrxraddr |= (RKI2C_MRXRADDR_ADDLVLD << n);
+       if (send_start) {
+               mrxaddr = __SHIFTIN((addr << 1) | 1, RKI2C_MRXADDR_SADDR) |
+                   RKI2C_MRXADDR_ADDLVLD;
+               WR4(sc, RKI2C_MRXADDR, mrxaddr);
+               for (n = 0, mrxraddr = 0; n < cmdlen; n++) {
+                       mrxraddr |= cmd[n] << (n * 8);
+                       mrxraddr |= (RKI2C_MRXRADDR_ADDLVLD << n);
+               }
+               WR4(sc, RKI2C_MRXRADDR, mrxraddr);
        }
-       WR4(sc, RKI2C_MRXRADDR, mrxraddr);
 
-       /* Acknowledge last byte read */
-       con |= RKI2C_CON_ACK;
+       if (last_ack) {
+               con |= RKI2C_CON_ACK;
+       }
        WR4(sc, RKI2C_CON, con);
 
        /* Receive data. Slave address goes in the lower 8 bits of MRXADDR */
@@ -321,8 +324,14 @@
        if ((error = rk_i2c_wait(sc, RKI2C_IPD_MBRFIPD)) != 0)
                return error;
 
+#if 0
        bus_space_read_region_4(sc->sc_bst, sc->sc_bsh, RKI2C_RXDATA(0),
            rxdata, howmany(buflen, 4));
+#else
+       for (n = 0; n < roundup(buflen, 4); n += 4)
+               rxdata[n/4] = RD4(sc, RKI2C_RXDATA(n/4));
+#endif
+
        memcpy(buf, rxdata, buflen);
 
        return 0;
@@ -339,7 +348,19 @@
        KASSERT(mutex_owned(&sc->sc_lock));
 
        if (I2C_OP_READ_P(op)) {
-               error = rk_i2c_read(sc, addr, cmdbuf, cmdlen, buf, buflen, flags, send_start);
+               uint8_t *databuf = buf;
+               while (buflen > 0) {
+                       const size_t datalen = uimin(buflen, 32);
+                       const bool last_ack = datalen == buflen;
+                       error = rk_i2c_read(sc, addr, cmdbuf, cmdlen, databuf, datalen, flags, send_start, last_ack);
+                       if (error != 0)
+                               break;
+                       databuf += datalen;
+                       buflen -= datalen;
+                       send_start = false;
+                       cmdbuf = NULL;
+                       cmdlen = 0;
+               }
        } else {
                error = rk_i2c_write(sc, addr, cmdbuf, cmdlen, buf, buflen, flags, send_start);
        }



Home | Main Index | Thread Index | Old Index