From 600d0a432adf899a8b265c089db40002d0c4cbc1 Mon Sep 17 00:00:00 2001 From: Emmanuel Vadot Date: Sun, 5 Jul 2020 20:09:33 +0200 Subject: [PATCH 1/2] Rework twsi Content-Type: text/plain; charset=UTF-8 --- sys/dev/iicbus/twsi/twsi.c | 45 ++++++++++++++++++------- sys/dts/arm/overlays/sun8i-h3-i2c0.dtso | 5 +++ sys/modules/dtb/allwinner/Makefile | 1 + 3 files changed, 39 insertions(+), 12 deletions(-) diff --git a/sys/dev/iicbus/twsi/twsi.c b/sys/dev/iicbus/twsi/twsi.c index 8124b9a1367a..ab6355e7104a 100644 --- a/sys/dev/iicbus/twsi/twsi.c +++ b/sys/dev/iicbus/twsi/twsi.c @@ -499,6 +499,10 @@ twsi_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs) sc->msg_idx = 0; sc->transfer = 1; +#ifdef TWSI_DEBUG + for (int i = 0; i < nmsgs; i++) + debugf(sc->dev, "msg %d is %d bytes long\n", i, msgs[i].len); +#endif /* Send start and re-enable interrupts */ sc->control_val = TWSI_CONTROL_TWSIEN | TWSI_CONTROL_INTEN | TWSI_CONTROL_ACK; @@ -535,13 +539,13 @@ twsi_intr(void *arg) debugf(sc->dev, "Got interrupt Current msg=%x\n", sc->msg_idx); status = TWSI_READ(sc, sc->reg_status); - debugf(sc->dev, "initial status=%x\n", status); + debugf(sc->dev, "reg control=%x\n", TWSI_READ(sc, sc->reg_control)); switch (status) { case TWSI_STATUS_START: case TWSI_STATUS_RPTD_START: /* Transmit the address */ - debugf(sc->dev, "Send the address\n"); + debugf(sc->dev, "Send the address (%x)", sc->msgs[sc->msg_idx].slave); if (sc->msgs[sc->msg_idx].flags & IIC_M_RD) TWSI_WRITE(sc, sc->reg_data, @@ -555,8 +559,10 @@ twsi_intr(void *arg) case TWSI_STATUS_ADDR_W_ACK: debugf(sc->dev, "Ack received after transmitting the address (write)\n"); /* Directly send the first byte */ - sc->sent_bytes = 0; - debugf(sc->dev, "Sending byte 0 = %x\n", sc->msgs[sc->msg_idx].buf[0]); + sc->sent_bytes = 1; + debugf(sc->dev, "Sending byte 0 (of %d) = %x\n", + sc->msgs[sc->msg_idx].len, + sc->msgs[sc->msg_idx].buf[0]); TWSI_WRITE(sc, sc->reg_data, sc->msgs[sc->msg_idx].buf[0]); TWSI_WRITE(sc, sc->reg_control, sc->control_val); @@ -580,7 +586,7 @@ twsi_intr(void *arg) case TWSI_STATUS_DATA_WR_ACK: debugf(sc->dev, "Ack received after transmitting data\n"); - if (sc->sent_bytes++ == (sc->msgs[sc->msg_idx].len - 1)) { + if (sc->sent_bytes == sc->msgs[sc->msg_idx].len) { debugf(sc->dev, "Done sending all the bytes for msg %d\n", sc->msg_idx); /* Send stop, no interrupts on stop */ if (!(sc->msgs[sc->msg_idx].flags & IIC_M_NOSTOP)) { @@ -595,30 +601,40 @@ twsi_intr(void *arg) if (sc->msg_idx == sc->nmsgs) { debugf(sc->dev, "transfer_done=1\n"); transfer_done = 1; + sc->error = 0; + } else { + debugf(sc->dev, "Send repeated start\n"); + TWSI_WRITE(sc, sc->reg_control, sc->control_val | TWSI_CONTROL_START); } } else { - debugf(sc->dev, "Sending byte %d = %x\n", + debugf(sc->dev, "Sending byte %d (of %d) = %x\n", sc->sent_bytes, + sc->msgs[sc->msg_idx].len, sc->msgs[sc->msg_idx].buf[sc->sent_bytes]); TWSI_WRITE(sc, sc->reg_data, sc->msgs[sc->msg_idx].buf[sc->sent_bytes]); TWSI_WRITE(sc, sc->reg_control, sc->control_val); + sc->sent_bytes++; } break; case TWSI_STATUS_DATA_RD_ACK: debugf(sc->dev, "Ack received after receiving data\n"); - debugf(sc->dev, "msg_len=%d recv_bytes=%d\n", sc->msgs[sc->msg_idx].len, sc->recv_bytes); sc->msgs[sc->msg_idx].buf[sc->recv_bytes++] = TWSI_READ(sc, sc->reg_data); + debugf(sc->dev, "msg_len=%d recv_bytes=%d\n", sc->msgs[sc->msg_idx].len, sc->recv_bytes); /* If we only have one byte left, disable ACK */ if (sc->msgs[sc->msg_idx].len - sc->recv_bytes == 1) sc->control_val &= ~TWSI_CONTROL_ACK; - if (sc->msgs[sc->msg_idx].len - sc->recv_bytes) { + if (sc->msgs[sc->msg_idx].len == sc->recv_bytes) { + debugf(sc->dev, "Done with msg %d\n", sc->msg_idx); sc->msg_idx++; - if (sc->msg_idx == sc->nmsgs - 1) + if (sc->msg_idx == sc->nmsgs - 1) { + debugf(sc->dev, "No more msgs\n"); transfer_done = 1; + sc->error = 0; + } } TWSI_WRITE(sc, sc->reg_control, sc->control_val); break; @@ -631,12 +647,14 @@ twsi_intr(void *arg) TWSI_WRITE(sc, sc->reg_control, sc->control_val | TWSI_CONTROL_STOP); } else { - debugf(sc->dev, "No ack when receiving data\n"); - sc->error = ENXIO; - sc->control_val = 0; + debugf(sc->dev, "No ack when receiving data, sending stop anyway\n"); + if (!(sc->msgs[sc->msg_idx].flags & IIC_M_NOSTOP)) + TWSI_WRITE(sc, sc->reg_control, + sc->control_val | TWSI_CONTROL_STOP); } sc->transfer = 0; transfer_done = 1; + sc->error = 0; break; default: @@ -647,6 +665,9 @@ twsi_intr(void *arg) wakeup(sc); break; } + debugf(sc->dev, "Refresh reg_control\n"); + TWSI_WRITE(sc, sc->reg_control, + sc->control_val | TWSI_CONTROL_IFLG); debugf(sc->dev, "Done with interrupts\n\n"); if (transfer_done == 1) { diff --git a/sys/dts/arm/overlays/sun8i-h3-i2c0.dtso b/sys/dts/arm/overlays/sun8i-h3-i2c0.dtso index f98ba2e5b81c..6d8b7beb35fd 100644 --- a/sys/dts/arm/overlays/sun8i-h3-i2c0.dtso +++ b/sys/dts/arm/overlays/sun8i-h3-i2c0.dtso @@ -9,4 +9,9 @@ status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&i2c0_pins>; + + eeprom: eeprom@50 { + compatible = "atmel,24c32"; + reg = <0x68>; + }; }; diff --git a/sys/modules/dtb/allwinner/Makefile b/sys/modules/dtb/allwinner/Makefile index cee789010b36..362441d89d09 100644 --- a/sys/modules/dtb/allwinner/Makefile +++ b/sys/modules/dtb/allwinner/Makefile @@ -24,6 +24,7 @@ DTS= \ sun8i-h3-orangepi-plus2e.dts DTSO= sun8i-a83t-sid.dtso \ + sun7i-a20-icee.dtso \ sun8i-h3-i2c0.dtso LINKS= \ -- 2.26.2