Example #1
0
File: iic.c Project: MarginC/kame
static int
iicread(dev_t dev, struct uio * uio, int ioflag)
{
    device_t iicdev = IIC_DEVICE(minor(dev));
    struct iic_softc *sc = IIC_SOFTC(minor(dev));
    int len, error = 0;
    int bufsize;

    if (!sc || !iicdev || !sc->sc_addr)
        return (EINVAL);

    if (sc->sc_count == 0)
        return (EINVAL);

    if ((error = iicbus_request_bus(device_get_parent(iicdev), iicdev, IIC_DONTWAIT)))
        return (error);

    /* max amount of data to read */
    len = min(uio->uio_resid, BUFSIZE);

    if ((error = iicbus_block_read(device_get_parent(iicdev), sc->sc_addr,
                                   sc->sc_inbuf, len, &bufsize)))
        return (error);

    if (bufsize > uio->uio_resid)
        panic("%s: too much data read!", __func__);

    iicbus_release_bus(device_get_parent(iicdev), iicdev);

    return (uiomove(sc->sc_inbuf, bufsize, uio));
}
Example #2
0
File: iic.c Project: MarginC/kame
static int
iicwrite(dev_t dev, struct uio * uio, int ioflag)
{
    device_t iicdev = IIC_DEVICE(minor(dev));
    struct iic_softc *sc = IIC_SOFTC(minor(dev));
    int sent, error, count;

    if (!sc || !iicdev || !sc->sc_addr)
        return (EINVAL);

    if (sc->sc_count == 0)
        return (EINVAL);

    if ((error = iicbus_request_bus(device_get_parent(iicdev), iicdev, IIC_DONTWAIT)))
        return (error);

    count = min(uio->uio_resid, BUFSIZE);
    uiomove(sc->sc_buffer, count, uio);

    error = iicbus_block_write(device_get_parent(iicdev), sc->sc_addr,
                               sc->sc_buffer, count, &sent);

    iicbus_release_bus(device_get_parent(iicdev), iicdev);

    return(error);
}
Example #3
0
File: iic.c Project: 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);
}
Example #4
0
File: iic.c Project: MarginC/kame
static int
iicopen (dev_t dev, int flags, int fmt, struct thread *td)
{
    struct iic_softc *sc = IIC_SOFTC(minor(dev));

    if (!sc)
        return (EINVAL);

    if (sc->sc_count > 0)
        return (EBUSY);

    sc->sc_count++;

    return (0);
}
Example #5
0
static int
smbclose(dev_t dev, int flags, int fmt, struct proc *p)
{
	struct smb_softc *sc = IIC_SOFTC(minor(dev));

	if (!sc)
		return (EINVAL);

	if (!sc->sc_count)
		return (EINVAL);

	sc->sc_count--;

	return (0);
}
Example #6
0
File: iic.c Project: MarginC/kame
static int
iicclose(dev_t dev, int flags, int fmt, struct thread *td)
{
    struct iic_softc *sc = IIC_SOFTC(minor(dev));

    if (!sc)
        return (EINVAL);

    if (!sc->sc_count)
        return (EINVAL);

    sc->sc_count--;

    if (sc->sc_count < 0)
        panic("%s: iic_count < 0!", __func__);

    return (0);
}
Example #7
0
static int
smbioctl(dev_t dev, u_long cmd, caddr_t data, int flags, struct proc *p)
{
	device_t smbdev = IIC_DEVICE(minor(dev));
	struct smb_softc *sc = IIC_SOFTC(minor(dev));
	device_t parent = device_get_parent(smbdev);

	int error = 0;
	struct smbcmd *s = (struct smbcmd *)data;

	if (!sc || !s)
		return (EINVAL);

	switch (cmd) {
	case SMB_QUICK_WRITE:
		error=smbus_quick(parent, s->slave, SMB_QWRITE);
		goto end;

	case SMB_QUICK_READ:
		error=smbus_quick(parent, s->slave, SMB_QREAD);
		goto end;
	};

	switch (cmd) {
	case SMB_SENDB:
		error=smbus_sendb(parent, s->slave, s->cmd);
		break;

	case SMB_RECVB:
		error=smbus_recvb(parent, s->slave, &s->cmd);
		break;

	case SMB_WRITEB:
		error=smbus_writeb(parent, s->slave, s->cmd, s->data.byte);
		break;

	case SMB_WRITEW:
		error=smbus_writew(parent, s->slave, s->cmd, s->data.word);
		break;

	case SMB_READB:
		if (s->data.byte_ptr)
			error=smbus_readb(parent, s->slave, s->cmd,
							s->data.byte_ptr);
		break;

	case SMB_READW:
		if (s->data.word_ptr)
			error=smbus_readw(parent, s->slave, s->cmd, s->data.word_ptr);
		break;

	case SMB_PCALL:
		if (s->data.process.rdata)
			error=smbus_pcall(parent, s->slave, s->cmd,
				s->data.process.sdata, s->data.process.rdata);
		break;

	case SMB_BWRITE:
		if (s->count && s->data.byte_ptr)
			error=smbus_bwrite(parent, s->slave, s->cmd, s->count,
							s->data.byte_ptr);
		break;

	case SMB_BREAD:
		if (s->count && s->data.byte_ptr)
			error=smbus_bread(parent, s->slave, s->cmd, s->count,
							s->data.byte_ptr);
		break;
		
	default:
		error = ENODEV;
	}

end:
	return (error);
}