The branch main has been updated by br:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=38e7025a60b28623b5991622a6efd1b8a329ccb2

commit 38e7025a60b28623b5991622a6efd1b8a329ccb2
Author:     Ruslan Bukin <b...@freebsd.org>
AuthorDate: 2021-05-26 09:55:23 +0000
Commit:     Ruslan Bukin <b...@freebsd.org>
CommitDate: 2021-05-26 09:55:23 +0000

    o Fix i2c read operation for large transfers (more than 32 bytes).
    o Fix slave address setting.
    
    This allows to read the EDID from an HDMI monitor.
    
    Reviewed by:    manu
    Sponsored by:   UKRI
    Differential Revision: https://reviews.freebsd.org/D27139
---
 sys/arm64/rockchip/rk_i2c.c | 33 ++++++++++++++++++++++++++++-----
 1 file changed, 28 insertions(+), 5 deletions(-)

diff --git a/sys/arm64/rockchip/rk_i2c.c b/sys/arm64/rockchip/rk_i2c.c
index fa824c76003b..c54f523088fe 100644
--- a/sys/arm64/rockchip/rk_i2c.c
+++ b/sys/arm64/rockchip/rk_i2c.c
@@ -291,6 +291,7 @@ static void
 rk_i2c_intr_locked(struct rk_i2c_softc *sc)
 {
        uint32_t reg;
+       int transfer_len;
 
        sc->ipd = RK_I2C_READ(sc, RK_I2C_IPD);
 
@@ -324,11 +325,16 @@ rk_i2c_intr_locked(struct rk_i2c_softc *sc)
                        RK_I2C_WRITE(sc, RK_I2C_IEN, RK_I2C_IEN_MBRFIEN |
                            RK_I2C_IEN_NAKRCVIEN);
 
-                       reg = RK_I2C_READ(sc, RK_I2C_CON);
-                       reg |= RK_I2C_CON_LASTACK;
-                       RK_I2C_WRITE(sc, RK_I2C_CON, reg);
+                       if ((sc->msg->len - sc->cnt) > 32)
+                               transfer_len = 32;
+                       else {
+                               transfer_len = sc->msg->len - sc->cnt;
+                               reg = RK_I2C_READ(sc, RK_I2C_CON);
+                               reg |= RK_I2C_CON_LASTACK;
+                               RK_I2C_WRITE(sc, RK_I2C_CON, reg);
+                       }
 
-                       RK_I2C_WRITE(sc, RK_I2C_MRXCNT, sc->msg->len);
+                       RK_I2C_WRITE(sc, RK_I2C_MRXCNT, transfer_len);
                } else {
                        sc->state = STATE_WRITE;
                        RK_I2C_WRITE(sc, RK_I2C_IEN, RK_I2C_IEN_MBTFIEN |
@@ -344,6 +350,23 @@ rk_i2c_intr_locked(struct rk_i2c_softc *sc)
 
                if (sc->cnt == sc->msg->len)
                        rk_i2c_send_stop(sc);
+               else {
+                       sc->mode = RK_I2C_CON_MODE_RX;
+                       reg = RK_I2C_READ(sc, RK_I2C_CON) & \
+                           ~RK_I2C_CON_CTRL_MASK;
+                       reg |= sc->mode << RK_I2C_CON_MODE_SHIFT;
+                       reg |= RK_I2C_CON_EN;
+
+                       if ((sc->msg->len - sc->cnt) > 32)
+                               transfer_len = 32;
+                       else {
+                               transfer_len = sc->msg->len - sc->cnt;
+                               reg |= RK_I2C_CON_LASTACK;
+                       }
+
+                       RK_I2C_WRITE(sc, RK_I2C_CON, reg);
+                       RK_I2C_WRITE(sc, RK_I2C_MRXCNT, transfer_len);
+               }
 
                break;
        case STATE_WRITE:
@@ -509,7 +532,7 @@ rk_i2c_transfer(device_t dev, struct iic_msg *msgs, 
uint32_t nmsgs)
                                        sc->mode = RK_I2C_CON_MODE_RX;
                                } else {
                                        sc->mode = RK_I2C_CON_MODE_RRX;
-                                       reg = msgs[i].slave & LSB;
+                                       reg = msgs[i].slave & ~LSB;
                                        reg |= RK_I2C_MRXADDR_VALID(0);
                                        RK_I2C_WRITE(sc, RK_I2C_MRXADDR, reg);
                                        RK_I2C_WRITE(sc, RK_I2C_MRXRADDR, 0);
_______________________________________________
dev-commits-src-main@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/dev-commits-src-main
To unsubscribe, send any mail to "dev-commits-src-main-unsubscr...@freebsd.org"

Reply via email to