summaryrefslogtreecommitdiffstats
path: root/sys/dev/iicbus/icee.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/iicbus/icee.c')
-rw-r--r--sys/dev/iicbus/icee.c49
1 files changed, 25 insertions, 24 deletions
diff --git a/sys/dev/iicbus/icee.c b/sys/dev/iicbus/icee.c
index 2e26d0e..800ec4c 100644
--- a/sys/dev/iicbus/icee.c
+++ b/sys/dev/iicbus/icee.c
@@ -48,7 +48,7 @@ __FBSDID("$FreeBSD$");
struct icee_softc {
device_t sc_dev; /* Myself */
- struct sx sc_lock; /* basically a perimeter lock */
+ device_t sc_busdev; /* Parent bus */
struct cdev *cdev; /* user interface */
int addr;
int size; /* How big am I? */
@@ -57,12 +57,6 @@ struct icee_softc {
int wr_sz; /* What's the write page size */
};
-#define ICEE_LOCK(_sc) sx_xlock(&(_sc)->sc_lock)
-#define ICEE_UNLOCK(_sc) sx_xunlock(&(_sc)->sc_lock)
-#define ICEE_LOCK_INIT(_sc) sx_init(&_sc->sc_lock, "icee")
-#define ICEE_LOCK_DESTROY(_sc) sx_destroy(&_sc->sc_lock);
-#define ICEE_ASSERT_LOCKED(_sc) sx_assert(&_sc->sc_lock, SA_XLOCKED);
-#define ICEE_ASSERT_UNLOCKED(_sc) sx_assert(&_sc->sc_lock, SA_UNLOCKED);
#define CDEV2SOFTC(dev) ((dev)->si_drv1)
/* cdev routines */
@@ -84,7 +78,7 @@ static struct cdevsw icee_cdevsw =
static int
icee_probe(device_t dev)
{
- /* XXX really probe? -- not until we know the size... */
+
device_set_desc(dev, "I2C EEPROM");
return (BUS_PROBE_NOWILDCARD);
}
@@ -97,6 +91,7 @@ icee_attach(device_t dev)
int dunit, err;
sc->sc_dev = dev;
+ sc->sc_busdev = device_get_parent(sc->sc_dev);
sc->addr = iicbus_get_addr(dev);
err = 0;
dname = device_get_name(dev);
@@ -117,8 +112,7 @@ icee_attach(device_t dev)
goto out;
}
sc->cdev->si_drv1 = sc;
- ICEE_LOCK_INIT(sc);
-out:;
+out:
return (err);
}
@@ -126,7 +120,7 @@ static int
icee_open(struct cdev *dev, int oflags, int devtype, struct thread *td)
{
- return (0);
+ return (0);
}
static int
@@ -155,7 +149,9 @@ icee_read(struct cdev *dev, struct uio *uio, int ioflag)
return (EIO);
if (sc->type != 8 && sc->type != 16)
return (EINVAL);
- ICEE_LOCK(sc);
+ error = iicbus_request_bus(sc->sc_busdev, sc->sc_dev, IIC_INTRWAIT);
+ if (error!= 0)
+ return (iic2errno(error));
slave = error = 0;
while (uio->uio_resid > 0) {
if (uio->uio_offset >= sc->size)
@@ -180,13 +176,15 @@ icee_read(struct cdev *dev, struct uio *uio, int ioflag)
for (i = 0; i < 2; i++)
msgs[i].slave = slave;
error = iicbus_transfer(sc->sc_dev, msgs, 2);
- if (error)
+ if (error) {
+ error = iic2errno(error);
break;
+ }
error = uiomove(data, len, uio);
if (error)
break;
}
- ICEE_UNLOCK(sc);
+ iicbus_release_bus(sc->sc_busdev, sc->sc_dev);
return (error);
}
@@ -214,7 +212,10 @@ icee_write(struct cdev *dev, struct uio *uio, int ioflag)
return (EIO);
if (sc->type != 8 && sc->type != 16)
return (EINVAL);
- ICEE_LOCK(sc);
+
+ error = iicbus_request_bus(sc->sc_busdev, sc->sc_dev, IIC_INTRWAIT);
+ if (error!= 0)
+ return (iic2errno(error));
slave = error = 0;
while (uio->uio_resid > 0) {
if (uio->uio_offset >= sc->size)
@@ -239,22 +240,22 @@ icee_write(struct cdev *dev, struct uio *uio, int ioflag)
if (error)
break;
error = iicbus_transfer(sc->sc_dev, wr, 1);
- if (error)
+ if (error) {
+ error = iic2errno(error);
break;
- // Now wait for the write to be done by trying to read
- // the part.
+ }
+ /* Read after write to wait for write-done. */
waitlimit = 10000;
rd[0].slave = slave;
- do
- {
- error = iicbus_transfer(sc->sc_dev, rd, 1);
+ do {
+ error = iicbus_transfer(sc->sc_dev, rd, 1);
} while (waitlimit-- > 0 && error != 0);
if (error) {
- printf("waiting for write failed %d\n", error);
- break;
+ error = iic2errno(error);
+ break;
}
}
- ICEE_UNLOCK(sc);
+ iicbus_release_bus(sc->sc_busdev, sc->sc_dev);
return error;
}
OpenPOWER on IntegriCloud