diff options
Diffstat (limited to 'sys/dev/iicbus/icee.c')
-rw-r--r-- | sys/dev/iicbus/icee.c | 49 |
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; } |