Date: Tue, 28 Nov 2006 08:02:23 GMT From: Warner Losh <imp@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 110616 for review Message-ID: <200611280802.kAS82N64005954@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=110616 Change 110616 by imp@imp_lighthouse on 2006/11/28 08:01:24 First stab at a write implementation. This one uses readback to pace itself. Need to read more datasheets to discover some of the tunable parameters. Affected files ... .. //depot/projects/arm/src/sys/dev/iicbus/icee.c#2 edit Differences ... ==== //depot/projects/arm/src/sys/dev/iicbus/icee.c#2 (text+ko) ==== @@ -162,7 +162,7 @@ while (uio->uio_resid > 0) { if (uio->uio_offset >= sc->size) break; - len = MAX(256 - (uio->uio_offset & 0xff), uio->uio_resid); + len = MIN(256 - (uio->uio_offset & 0xff), uio->uio_resid); switch (sc->type) { case 8: for (i = 0; i < 2; i++) @@ -191,10 +191,23 @@ return (error); } +/* + * Write to the part. We use three transfers here since we're actually + * doing a write followed by a read to make sure that the write finished. + * It is easier to encode the dummy read here than to break things up + * into smaller chunks... + */ static int icee_write(struct cdev *dev, struct uio *uio, int ioflag) { struct icee_softc *sc; + int error, len, i; + uint8_t data[16 + 2]; + struct iic_msg msgs[3] = { + { 0, IIC_M_WR, 0, data }, + { 0, IIC_M_WR, 0, data }, + { 0, IIC_M_RD, 0, data }, + }; sc = CDEV2SOFTC(dev); if (uio->uio_offset > sc->size) @@ -202,8 +215,41 @@ if (sc->type != 8 && sc->type != 16) return (EINVAL); ICEE_LOCK(sc); + error = 0; + while (uio->uio_resid > 0) { + if (uio->uio_offset >= sc->size) + break; + len = MIN(16 - (uio->uio_offset & 0xf), uio->uio_resid); + error = uiomove(data + sc->type / 8, len, uio); + if (error) + break; + switch (sc->type) { + case 8: + for (i = 0; i < 3; i++) + msgs[i].slave = uio->uio_offset >> 8 | sc->addr; + msgs[0].len = 1 + len; + msgs[1].len = 1; + msgs[2].len = len; + msgs[2].buf = data + 1; + data[0] = uio->uio_offset & 0xff; + break; + case 16: + for (i = 0; i < 3; i++) + msgs[i].slave = sc->addr; + msgs[0].len = 2 + len; + msgs[1].len = 2; + msgs[2].len = len; + msgs[2].buf = data + 2; + data[0] = uio->uio_offset & 0xff; + data[1] = (uio->uio_offset >> 8) & 0xff; + break; + } + error = iicbus_transfer(sc->sc_dev, msgs, 3); + if (error) + break; + } ICEE_UNLOCK(sc); - return EIO; + return error; } static device_method_t icee_methods[] = {
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200611280802.kAS82N64005954>