FreeBSD/sys/dev/iicbus/icee.c
/*
 * 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...
 */
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
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, slave, waitlimit;
	uint8_t data[MAX_WR_SZ + 2];
	struct iic_msg wr[1] = {
	     { 0, IIC_M_WR, 0, data },
	};
	struct iic_msg rd[1] = {
	     { 0, IIC_M_RD, 1, data },
	};
	sc = CDEV2SOFTC(dev);
	if (uio->uio_offset >= sc->size)
		return (EIO);
	if (sc->type != 8 && sc->type != 16)
		return (EINVAL);
	slave = error = 0;
	while (uio->uio_resid > 0) {
		if (uio->uio_offset >= sc->size)
			break;
		len = MIN(sc->wr_sz - (uio->uio_offset & (sc->wr_sz - 1)),
		    uio->uio_resid);
		switch (sc->type) {
		case 8:
			slave = (uio->uio_offset >> 7) | sc->addr;
			wr[0].len = 1 + len;
			data[0] = uio->uio_offset & 0xff;
			break;
		case 16:
			slave = sc->addr | (uio->uio_offset >> 15);
			wr[0].len = 2 + len;
			data[0] = (uio->uio_offset >> 8) & 0xff;
			data[1] = uio->uio_offset & 0xff;
			break;
		}
		wr[0].slave = slave;
		error = uiomove(data + sc->type / 8, len, uio);
		if (error)
			break;
		error = iicbus_transfer_excl(sc->dev, wr, 1, IIC_INTRWAIT);
		if (error) {
			error = iic2errno(error);
			break;
		}
		waitlimit = 10000;
		rd[0].slave = slave;
		do {
			error = iicbus_transfer_excl(sc->dev, rd, 1,
			    IIC_INTRWAIT);
		} while (waitlimit-- > 0 && error != 0);
		if (error) {
			error = iic2errno(error);
			break;
		}
	}
	return error;
}
static int icee_write ( struct cdev * dev , struct uio * uio , int ioflag ) { struct icee_softc * sc ; int error , len , slave , waitlimit ; uint8_t data [ MAX_WR_SZ + 2 ] ; struct iic_msg wr [ 1 ] = { { 0 , IIC_M_WR , 0 , data } , } ; struct iic_msg rd [ 1 ] = { { 0 , IIC_M_RD , 1 , data } , } ; sc = CDEV2SOFTC ( dev ) ; if ( uio -> uio_offset >= sc -> size ) return ( EIO ) ; if ( sc -> type != 8 && sc -> type != 16 ) return ( EINVAL ) ; slave = error = 0 ; while ( uio -> uio_resid > 0 ) { if ( uio -> uio_offset >= sc -> size ) break ; len = MIN ( sc -> wr_sz - ( uio -> uio_offset & ( sc -> wr_sz - 1 ) ) , uio -> uio_resid ) ; switch ( sc -> type ) { case 8 : slave = ( uio -> uio_offset >> 7 ) | sc -> addr ; wr [ 0 ] . len = 1 + len ; data [ 0 ] = uio -> uio_offset & 0xff ; break ; case 16 : slave = sc -> addr | ( uio -> uio_offset >> 15 ) ; wr [ 0 ] . len = 2 + len ; data [ 0 ] = ( uio -> uio_offset >> 8 ) & 0xff ; data [ 1 ] = uio -> uio_offset & 0xff ; break ; } wr [ 0 ] . slave = slave ; error = uiomove ( data + sc -> type / 8 , len , uio ) ; if ( error ) break ; error = iicbus_transfer_excl ( sc -> dev , wr , 1 , IIC_INTRWAIT ) ; if ( error ) { error = iic2errno ( error ) ; break ; } waitlimit = 10000 ; rd [ 0 ] . slave = slave ; do { error = iicbus_transfer_excl ( sc -> dev , rd , 1 , IIC_INTRWAIT ) ; } while ( waitlimit -- > 0 && error != 0 ) ; if ( error ) { error = iic2errno ( error ) ; break ; } } return error ; }
Write to the part.
Write to the part .
/* Read after write to wait for write-done. */