Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 26 Apr 2021 16:06:10 +0200
From:      Emmanuel Vadot <manu@bidouilliste.com>
To:        Daniel Braniss <danny@cs.huji.ac.il>
Cc:        Mark Murray <markm@FreeBSD.org>, freebsd-arm <freebsd-arm@freebsd.org>
Subject:   Re: I2C/IIC working on RPI4 8GB?
Message-ID:  <20210426160610.5b91dc44e86ddea169ca8e27@bidouilliste.com>
In-Reply-To: <C0038E5F-F218-425B-AFE6-84537CE10155@cs.huji.ac.il>
References:  <1C2DD11C-B1F6-4C2A-9AB0-5F1553520FF5@FreeBSD.org> <C0038E5F-F218-425B-AFE6-84537CE10155@cs.huji.ac.il>

next in thread | previous in thread | raw e-mail | index | archive | help
On Sun, 25 Apr 2021 18:41:31 +0300
Daniel Braniss <danny@cs.huji.ac.il> wrote:

>=20
>=20
> > On 25 Apr 2021, at 15:32, Mark Murray <markm@FreeBSD.org> wrote:
> >=20
> > Hi All,
> >=20
> > Does anyone here have IIC/I2C working on a CURRENT (I'm running latest)=
 FreeBSD?
> >=20
> > I've never seen it work; Last time I had working IIC was on an RPI3.
> >=20
> > There is a /dev/iic0, and I have a known working RTC on it, but the sca=
n just times out:
> >=20
> > [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>
> >=20
> >=20
> > I suspect something not-quite-right in DTS land, but I lack the knowled=
ge 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 lac=
k of /dev/iic0.
> >=20
> > Thanks!
> >=20
> > M
> > --
> > Mark R V Murray
> >=20
>=20
> Q1: do you see /dev/iic?
> Q2: i2c -s shows anything?
>=20
> fianlly, you can try my patch, it works for me, but I understand it?s a f=
ive kilo hammer :-)

 RPI doesn't uses twsi so that will not change a thing.

> 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
>=20
> +#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;
>=20
> +	DELAY(1000); // danny: needed=20
> 	val =3D 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 /=3D 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=3D%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);
> }
>=20
> @@ -212,7 +214,7 @@ twsi_locked_start(device_t dev, struct twsi_softc *sc=
, int32_t mask,
> 	DELAY(1000);
>=20
> 	if (twsi_poll_ctrl(sc, timeout, TWSI_CONTROL_IFLG)) {
> -		debugf(dev, "timeout sending %sSTART condition\n",
> +		debug_(dev, "timeout sending %sSTART condition\n",
> 		    mask =3D=3D 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=3D%x\n", status);
>=20
> 	if (status !=3D mask) {
> -		debugf(dev, "wrong status (%02x) after sending %sSTART condition\n",
> +		debug_(dev, "wrong status (%02x) after sending %sSTART condition\n",
> 		    status, mask =3D=3D 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);
>=20
> 	if (twsi_poll_ctrl(sc, timeout, TWSI_CONTROL_IFLG)) {
> -		debugf(dev, "timeout sending slave address (timeout=3D%d)\n", timeout);
> +		debug_(dev, "timeout sending slave address (timeout=3D%d)\n", timeout);
> 		return (IIC_ETIMEOUT);
> 	}
>=20
> @@ -239,7 +241,7 @@ twsi_locked_start(device_t dev, struct twsi_softc *sc=
, int32_t mask,
> 	status =3D TWSI_READ(sc, sc->reg_status);
> 	if (status !=3D (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;
>=20
> 	sc =3D device_get_softc(dev);
> -
> +	debug_(dev, "twsi_read: len=3D%d delay=3D%d", len, delay); // danny
> +=09
> 	mtx_lock(&sc->mutex);
> 	*read =3D 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);
>=20
> 		if (twsi_poll_ctrl(sc, delay, TWSI_CONTROL_IFLG)) {
> -			debugf(dev, "timeout reading data (delay=3D%d)\n", delay);
> +			debug_(dev, "timeout reading data (delay=3D%d)\n", delay);
> 			rv =3D IIC_ETIMEOUT;
> 			goto out;
> 		}
> @@ -431,7 +434,7 @@ twsi_read(device_t dev, char *buf, int len, int *read=
, int last, int delay)
> 		status =3D TWSI_READ(sc, sc->reg_status);
> 		if (status !=3D (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 =3D 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=3D%d)\n", timeout);
> +			debug_(dev, "timeout writing data (timeout=3D%d)\n", timeout);
> 			rv =3D IIC_ETIMEOUT;
> 			goto out;
> 		}
>=20
> 		status =3D TWSI_READ(sc, sc->reg_status);
> 		if (status !=3D TWSI_STATUS_DATA_WR_ACK) {
> -			debugf(dev, "wrong status (%02x) while writing\n", status);
> +			debug_(dev, "wrong status (%02x) while writing\n", status);
> 			rv =3D IIC_ESTATUS;
> 			goto out;
> 		}
> @@ -496,8 +499,12 @@ twsi_transfer(device_t dev, struct iic_msg *msgs, ui=
nt32_t nmsgs)
> 	sc->control_val =3D 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=3D%x\n", TWSI_READ(sc, sc->reg_status));
> +#if 0
> +	debug_(dev, "transmitting %d messages\n", nmsgs);
> +	debug_(sc->dev, "status=3D%x\n", TWSI_READ(sc, sc->reg_status));
> +#else
> +	DELAY(8000);
> +#endif
> 	sc->nmsgs =3D nmsgs;
> 	sc->msgs =3D msgs;
> 	sc->msg_idx =3D 0;
> @@ -519,15 +526,24 @@ twsi_transfer(device_t dev, struct iic_msg *msgs, u=
int32_t nmsgs)
> 	debugf(sc->dev, "pause finish\n");
>=20
> 	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);
> 	}
>=20
> 	/* Disable module and interrupts */
> -	debugf(sc->dev, "status=3D%x\n", TWSI_READ(sc, sc->reg_status));
> +#if 0
> +	debug_(sc->dev, "status=3D%x\n", TWSI_READ(sc, sc->reg_status)); //
> 	TWSI_WRITE(sc, sc->reg_control, 0);
> -	debugf(sc->dev, "status=3D%x\n", TWSI_READ(sc, sc->reg_status));
> -
> +	debugf(sc->dev, "status=3D%x\n", TWSI_READ(sc, sc->reg_status)); //
> +	debugf(sc->dev, "error=3D%d\n", sc->error); // danny
> +#else
> +	int status;
> +	DELAY(8000); // danny: works!
> +	status =3D TWSI_READ(sc, sc->reg_status);
> +	TWSI_WRITE(sc, sc->reg_control, 0);
> +	status =3D TWSI_READ(sc, sc->reg_status);
> +	//debug_(sc->dev, "status=3D%x\n", TWSI_READ(sc, sc->reg_status));
> +#endif
> 	return (sc->error);
> }
>=20
> @@ -581,7 +597,7 @@ twsi_intr(void *arg)
>=20
> 	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 =3D 0;
> 		sc->error =3D IIC_ENOACK;
> 		sc->control_val =3D 0;
> @@ -662,7 +678,7 @@ twsi_intr(void *arg)
> 		break;
>=20
> 	default:
> -		debugf(sc->dev, "status=3D%x hot handled\n", status);
> +		debug_(sc->dev, "status=3D%x hot handled\n", status);
> 		sc->transfer =3D 0;
> 		sc->error =3D IIC_EBUSERR;
> 		sc->control_val =3D 0;
> _______________________________________________
> freebsd-arm@freebsd.org mailing list
> https://lists.freebsd.org/mailman/listinfo/freebsd-arm
> To unsubscribe, send any mail to "freebsd-arm-unsubscribe@freebsd.org"


--=20
Emmanuel Vadot <manu@bidouilliste.com> <manu@FreeBSD.org>



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20210426160610.5b91dc44e86ddea169ca8e27>