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)); }
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); }
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); }
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); }
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); }
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); }
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); }