Re: I2C/IIC working on RPI4 8GB?
Daniel Braniss <[email protected]>
| Newsgroups | gmane.os.freebsd.devel.arm |
|---|---|
| Message-ID | <[email protected]> |
> On 25 Apr 2021, at 15:32, Mark Murray <[email protected]> wrote: > > Hi All, > > Does anyone here have IIC/I2C working on a CURRENT (I'm running latest) FreeBSD? > > I've never seen it work; Last time I had working IIC was on an RPI3. > > There is a /dev/iic0, and I have a known working RTC on it, but the scan just times out: > > [root@grasshopper ~]# i2c -s > Hardware may not support START/STOP scanning; trying less-reliable read method. > <TIMEOUT> > Scanning I2C devices on /dev/iic0: <none found> > > > I suspect something not-quite-right in DTS land, but I lack the knowledge to investigate. I've done some random stumbling around in the dark with overlays and the like, but I've either seen the above error, or a total lack of /dev/iic0. > > Thanks! > > M > -- > Mark R V Murray > Q1: do you see /dev/iic? Q2: i2c -s shows anything? fianlly, you can try my patch, it works for me, but I understand it’s a five kilo hammer :-) diff --git a/sys/dev/iicbus/twsi/twsi.c b/sys/dev/iicbus/twsi/twsi.c index a606c2aef..8ede62073 100644 --- a/sys/dev/iicbus/twsi/twsi.c +++ b/sys/dev/iicbus/twsi/twsi.c @@ -86,6 +86,8 @@ __FBSDID("$FreeBSD$"); #define TWSI_DEBUG #undef TWSI_DEBUG +#define debug_(dev, fmt, args...) device_printf(dev, "%s: " fmt, __func__, ##args) + #ifdef TWSI_DEBUG #define debugf(dev, fmt, args...) device_printf(dev, "%s: " fmt, __func__, ##args) #else @@ -103,6 +105,7 @@ TWSI_READ(struct twsi_softc *sc, bus_size_t off) { uint32_t val; + DELAY(1000); // danny: needed val = bus_read_4(sc->res[0], off); debugf(sc->dev, "read %x from %lx\n", val, off); return (val); @@ -165,15 +168,14 @@ twsi_clear_iflg(struct twsi_softc *sc) static int twsi_poll_ctrl(struct twsi_softc *sc, int timeout, uint32_t mask) { - timeout /= 10; - debugf(sc->dev, "Waiting for ctrl reg to match mask %x\n", mask); + debug_(sc->dev, "Waiting for ctrl reg to match mask %x timeout=%d\n", mask, timeout); while (!(TWSI_READ(sc, sc->reg_control) & mask)) { - DELAY(10); + // DELAY(10); if (--timeout < 0) return (timeout); } - debugf(sc->dev, "done\n"); + debug_(sc->dev, "done\n"); return (0); } @@ -212,7 +214,7 @@ twsi_locked_start(device_t dev, struct twsi_softc *sc, int32_t mask, DELAY(1000); if (twsi_poll_ctrl(sc, timeout, TWSI_CONTROL_IFLG)) { - debugf(dev, "timeout sending %sSTART condition\n", + debug_(dev, "timeout sending %sSTART condition\n", mask == TWSI_STATUS_START ? "" : "repeated "); return (IIC_ETIMEOUT); } @@ -221,7 +223,7 @@ twsi_locked_start(device_t dev, struct twsi_softc *sc, int32_t mask, debugf(dev, "status=%x\n", status); if (status != mask) { - debugf(dev, "wrong status (%02x) after sending %sSTART condition\n", + debug_(dev, "wrong status (%02x) after sending %sSTART condition\n", status, mask == TWSI_STATUS_START ? "" : "repeated "); return (IIC_ESTATUS); } @@ -231,7 +233,7 @@ twsi_locked_start(device_t dev, struct twsi_softc *sc, int32_t mask, DELAY(1000); if (twsi_poll_ctrl(sc, timeout, TWSI_CONTROL_IFLG)) { - debugf(dev, "timeout sending slave address (timeout=%d)\n", timeout); + debug_(dev, "timeout sending slave address (timeout=%d)\n", timeout); return (IIC_ETIMEOUT); } @@ -239,7 +241,7 @@ twsi_locked_start(device_t dev, struct twsi_softc *sc, int32_t mask, status = TWSI_READ(sc, sc->reg_status); if (status != (read_access ? TWSI_STATUS_ADDR_R_ACK : TWSI_STATUS_ADDR_W_ACK)) { - debugf(dev, "no ACK (status: %02x) after sending slave address\n", + debug_(dev, "no ACK (status: %02x) after sending slave address\n", status); return (IIC_ENOACK); } @@ -405,7 +407,8 @@ twsi_read(device_t dev, char *buf, int len, int *read, int last, int delay) int last_byte, rv; sc = device_get_softc(dev); - + debug_(dev, "twsi_read: len=%d delay=%d", len, delay); // danny + mtx_lock(&sc->mutex); *read = 0; while (*read < len) { @@ -423,7 +426,7 @@ twsi_read(device_t dev, char *buf, int len, int *read, int last, int delay) DELAY(1000); if (twsi_poll_ctrl(sc, delay, TWSI_CONTROL_IFLG)) { - debugf(dev, "timeout reading data (delay=%d)\n", delay); + debug_(dev, "timeout reading data (delay=%d)\n", delay); rv = IIC_ETIMEOUT; goto out; } @@ -431,7 +434,7 @@ twsi_read(device_t dev, char *buf, int len, int *read, int last, int delay) status = TWSI_READ(sc, sc->reg_status); if (status != (last_byte ? TWSI_STATUS_DATA_RD_NOACK : TWSI_STATUS_DATA_RD_ACK)) { - debugf(dev, "wrong status (%02x) while reading\n", status); + debug_(dev, "wrong status (%02x) while reading\n", status); rv = IIC_ESTATUS; goto out; } @@ -462,14 +465,14 @@ twsi_write(device_t dev, const char *buf, int len, int *sent, int timeout) twsi_clear_iflg(sc); DELAY(1000); if (twsi_poll_ctrl(sc, timeout, TWSI_CONTROL_IFLG)) { - debugf(dev, "timeout writing data (timeout=%d)\n", timeout); + debug_(dev, "timeout writing data (timeout=%d)\n", timeout); rv = IIC_ETIMEOUT; goto out; } status = TWSI_READ(sc, sc->reg_status); if (status != TWSI_STATUS_DATA_WR_ACK) { - debugf(dev, "wrong status (%02x) while writing\n", status); + debug_(dev, "wrong status (%02x) while writing\n", status); rv = IIC_ESTATUS; goto out; } @@ -496,8 +499,12 @@ twsi_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs) sc->control_val = TWSI_CONTROL_TWSIEN | TWSI_CONTROL_INTEN | TWSI_CONTROL_ACK; TWSI_WRITE(sc, sc->reg_control, sc->control_val); - debugf(dev, "transmitting %d messages\n", nmsgs); - debugf(sc->dev, "status=%x\n", TWSI_READ(sc, sc->reg_status)); +#if 0 + debug_(dev, "transmitting %d messages\n", nmsgs); + debug_(sc->dev, "status=%x\n", TWSI_READ(sc, sc->reg_status)); +#else + DELAY(8000); +#endif sc->nmsgs = nmsgs; sc->msgs = msgs; sc->msg_idx = 0; @@ -519,15 +526,24 @@ twsi_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs) debugf(sc->dev, "pause finish\n"); if (sc->error) { - debugf(sc->dev, "Error, aborting (%d)\n", sc->error); + debug_(sc->dev, "Error, aborting (%d)\n", sc->error); TWSI_WRITE(sc, sc->reg_control, 0); } /* Disable module and interrupts */ - debugf(sc->dev, "status=%x\n", TWSI_READ(sc, sc->reg_status)); +#if 0 + debug_(sc->dev, "status=%x\n", TWSI_READ(sc, sc->reg_status)); // TWSI_WRITE(sc, sc->reg_control, 0); - debugf(sc->dev, "status=%x\n", TWSI_READ(sc, sc->reg_status)); - + debugf(sc->dev, "status=%x\n", TWSI_READ(sc, sc->reg_status)); // + debugf(sc->dev, "error=%d\n", sc->error); // danny +#else + int status; + DELAY(8000); // danny: works! + status = TWSI_READ(sc, sc->reg_status); + TWSI_WRITE(sc, sc->reg_control, 0); + status = TWSI_READ(sc, sc->reg_status); + //debug_(sc->dev, "status=%x\n", TWSI_READ(sc, sc->reg_status)); +#endif return (sc->error); } @@ -581,7 +597,7 @@ twsi_intr(void *arg) case TWSI_STATUS_ADDR_W_NACK: case TWSI_STATUS_ADDR_R_NACK: - debugf(sc->dev, "No ack received after transmitting the address\n"); + debug_(sc->dev, "No ack received after transmitting the address\n"); sc->transfer = 0; sc->error = IIC_ENOACK; sc->control_val = 0; @@ -662,7 +678,7 @@ twsi_intr(void *arg) break; default: - debugf(sc->dev, "status=%x hot handled\n", status); + debug_(sc->dev, "status=%x hot handled\n", status); sc->transfer = 0; sc->error = IIC_EBUSERR; sc->control_val = 0; _______________________________________________ [email protected] mailing list https://lists.freebsd.org/mailman/listinfo/freebsd-arm To unsubscribe, send any mail to "[email protected]"