Exemplo n.º 1
0
/*
 * iicbus_write_byte()
 *
 * Write a byte to the slave previously started by iicbus_start() call
 */
int
iicbus_write_byte(device_t bus, char byte, int timeout)
{
	char data = byte;
	int sent;

	return (iicbus_write(bus, &data, 1, &sent, timeout));
}
Exemplo n.º 2
0
Arquivo: iic.c Projeto: MarginC/kame
static int
iicioctl(dev_t dev, u_long cmd, caddr_t data, int flags, struct thread *td)
{
    device_t iicdev = IIC_DEVICE(minor(dev));
    struct iic_softc *sc = IIC_SOFTC(minor(dev));
    device_t parent = device_get_parent(iicdev);
    struct iiccmd *s = (struct iiccmd *)data;
    int error, count;

    if (!sc)
        return (EINVAL);

    if ((error = iicbus_request_bus(device_get_parent(iicdev), iicdev,
                                    (flags & O_NONBLOCK) ? IIC_DONTWAIT :
                                    (IIC_WAIT | IIC_INTR))))
        return (error);

    switch (cmd) {
    case I2CSTART:
        error = iicbus_start(parent, s->slave, 0);

        /*
         * Implicitly set the chip addr to the slave addr passed as
         * parameter. Consequently, start/stop shall be called before
         * the read or the write of a block.
         */
        if (!error)
            sc->sc_addr = s->slave;

        break;

    case I2CSTOP:
        error = iicbus_stop(parent);
        break;

    case I2CRSTCARD:
        error = iicbus_reset(parent, 0, 0, NULL);
        break;

    case I2CWRITE:
        error = iicbus_write(parent, s->buf, s->count, &count, 10);
        break;

    case I2CREAD:
        error = iicbus_read(parent, s->buf, s->count, &count, s->last, 10);
        break;

    default:
        error = ENODEV;
    }

    iicbus_release_bus(device_get_parent(iicdev), iicdev);

    return (error);
}
Exemplo n.º 3
0
/*
 * Generic version of iicbus_transfer that calls the appropriate
 * routines to accomplish this.  See note above about acceptable
 * buffer addresses.
 */
int
iicbus_transfer_gen(device_t dev, struct iic_msg *msgs, uint32_t nmsgs)
{
    int i, error, lenread, lenwrote, nkid, rpstart, addr;
    device_t *children, bus;
    bool nostop;

    if ((error = device_get_children(dev, &children, &nkid)) != 0)
        return (IIC_ERESOURCE);
    if (nkid != 1) {
        free(children, M_TEMP);
        return (IIC_ENOTSUPP);
    }
    bus = children[0];
    rpstart = 0;
    free(children, M_TEMP);
    nostop = iicbus_get_nostop(dev);
    for (i = 0, error = 0; i < nmsgs && error == 0; i++) {
        addr = msgs[i].slave;
        if (msgs[i].flags & IIC_M_RD)
            addr |= LSB;
        else
            addr &= ~LSB;

        if (!(msgs[i].flags & IIC_M_NOSTART)) {
            if (rpstart)
                error = iicbus_repeated_start(bus, addr, 0);
            else
                error = iicbus_start(bus, addr, 0);
        }
        if (error != 0)
            break;

        if (msgs[i].flags & IIC_M_RD)
            error = iicbus_read(bus, msgs[i].buf, msgs[i].len,
                                &lenread, IIC_LAST_READ, 0);
        else
            error = iicbus_write(bus, msgs[i].buf, msgs[i].len,
                                 &lenwrote, 0);
        if (error != 0)
            break;

        if ((msgs[i].flags & IIC_M_NOSTOP) != 0 ||
                (nostop && i + 1 < nmsgs)) {
            rpstart = 1;	/* Next message gets repeated start */
        } else {
            rpstart = 0;
            iicbus_stop(bus);
        }
    }
    if (error != 0 && !nostop)
        iicbus_stop(bus);
    return (error);
}
Exemplo n.º 4
0
/*
 * iicbus_write_byte()
 *
 * Write a byte to the slave previously started by iicbus_start() call
 */
int
iicbus_write_byte(device_t bus, char byte, int timeout)
{
    struct iicbus_softc *sc = device_get_softc(bus);
    char data = byte;
    int sent;

    /* a slave must have been started for writing */
    if (sc->started == 0 || (sc->strict != 0 && (sc->started & LSB) != 0))
        return (IIC_ESTATUS);

    return (iicbus_write(bus, &data, 1, &sent, timeout));
}
Exemplo n.º 5
0
/*
 * iicbus_block_write()
 *
 * Write a block of data to slave ; start/stop protocol managed
 */
int
iicbus_block_write(device_t bus, u_char slave, char *buf, int len, int *sent)
{
	u_char addr = slave & ~LSB;
	int error;

	if ((error = iicbus_start(bus, addr, 0)))
		return (error);

	error = iicbus_write(bus, buf, len, sent, 0);

	iicbus_stop(bus);

	return (error);
}
Exemplo n.º 6
0
static int
iicuio_move(struct iic_cdevpriv *priv, struct uio *uio, int last)
{
	device_t parent;
	int error, num_bytes, transferred_bytes, written_bytes;
	char buffer[128];

	parent = device_get_parent(priv->sc->sc_dev);
	error = 0;

	/*
	 * We can only transfer up to sizeof(buffer) bytes in 1 shot, so loop until
	 * everything has been transferred.
	*/
	while ((error == 0) && (uio->uio_resid > 0)) {

		num_bytes = MIN(uio->uio_resid, sizeof(buffer));
		transferred_bytes = 0;

		if (uio->uio_rw == UIO_WRITE) {
			error = uiomove(buffer, num_bytes, uio);

			while ((error == 0) && (transferred_bytes < num_bytes)) {
				written_bytes = 0;
				error = iicbus_write(parent, &buffer[transferred_bytes],
				    num_bytes - transferred_bytes, &written_bytes, 0);
				transferred_bytes += written_bytes;
			}
				
		} else if (uio->uio_rw == UIO_READ) {
			error = iicbus_read(parent, buffer,
			    num_bytes, &transferred_bytes,
			    ((uio->uio_resid <= sizeof(buffer)) ? last : 0), 0);
			if (error == 0)
				error = uiomove(buffer, transferred_bytes, uio);
		}
	}

	return (error);
}