From 08ea1e753193d4f6e1b6ab9acb151ddaeeb2b9b2 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Fran=C3=A7ois=20Tigeot?= Date: Sat, 10 Aug 2013 17:15:14 +0200 Subject: [PATCH] iicbb: Update from FreeBSD --- sys/bus/iicbus/iicbb.c | 87 +++++++++++++++++++++++++-------------- sys/bus/iicbus/iicbb_if.m | 42 +++++++++++++++++-- 2 files changed, 96 insertions(+), 33 deletions(-) diff --git a/sys/bus/iicbus/iicbb.c b/sys/bus/iicbus/iicbb.c index b550ca91bd..3fee6d9c21 100644 --- a/sys/bus/iicbus/iicbb.c +++ b/sys/bus/iicbus/iicbb.c @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD: src/sys/dev/iicbus/iicbb.c,v 1.21 2009/02/10 22:50:23 imp Exp $ + * $FreeBSD: head/sys/dev/iicbus/iicbb.c 232365 2012-03-01 20:58:20Z kan $ */ /* @@ -59,6 +59,7 @@ struct iicbb_softc { device_t iicbus; + int udelay; /* signal toggle delay in usec */ }; static int iicbb_attach(device_t); @@ -73,6 +74,7 @@ static int iicbb_stop(device_t); static int iicbb_write(device_t, const char *, int, int *, int); static int iicbb_read(device_t, char *, int, int *, int, int); static int iicbb_reset(device_t, u_char, u_char, u_char *); +static int iicbb_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs); static device_method_t iicbb_methods[] = { /* device interface */ @@ -92,7 +94,7 @@ static device_method_t iicbb_methods[] = { DEVMETHOD(iicbus_write, iicbb_write), DEVMETHOD(iicbus_read, iicbb_read), DEVMETHOD(iicbus_reset, iicbb_reset), - DEVMETHOD(iicbus_transfer, iicbus_transfer_gen), + DEVMETHOD(iicbus_transfer, iicbb_transfer), DEVMETHOD_END }; @@ -121,6 +123,7 @@ iicbb_attach(device_t dev) sc->iicbus = device_add_child(dev, "iicbus", -1); if (!sc->iicbus) return (ENXIO); + sc->udelay = 10; /* 10 uS default */ bus_generic_attach(dev); return (0); @@ -182,20 +185,18 @@ iicbb_print_child(device_t bus, device_t dev) return (retval); } -#define IIC_DELAY 10 - -#define I2C_SETSDA(dev,val) do { \ +#define I2C_SETSDA(sc,dev,val) do { \ IICBB_SETSDA(device_get_parent(dev), val); \ - DELAY(IIC_DELAY); \ + DELAY(sc->udelay); \ } while (0) #define I2C_SETSCL(dev,val) do { \ iicbb_setscl(dev, val, 100); \ } while (0) -#define I2C_SET(dev,ctrl,data) do { \ +#define I2C_SET(sc,dev,ctrl,data) do { \ I2C_SETSCL(dev, ctrl); \ - I2C_SETSDA(dev, data); \ + I2C_SETSDA(sc, dev, data); \ } while (0) #define I2C_GETSDA(dev) (IICBB_GETSDA(device_get_parent(dev))) @@ -214,14 +215,15 @@ static int i2c_debug = 0; static void iicbb_setscl(device_t dev, int val, int timeout) { + struct iicbb_softc *sc = device_get_softc(dev); int k = 0; IICBB_SETSCL(device_get_parent(dev), val); - DELAY(IIC_DELAY); + DELAY(sc->udelay); while (val && !I2C_GETSCL(dev) && k++ < timeout) { IICBB_SETSCL(device_get_parent(dev), val); - DELAY(IIC_DELAY); + DELAY(sc->udelay); } return; @@ -230,18 +232,22 @@ iicbb_setscl(device_t dev, int val, int timeout) static void iicbb_one(device_t dev, int timeout) { - I2C_SET(dev,0,1); - I2C_SET(dev,1,1); - I2C_SET(dev,0,1); + struct iicbb_softc *sc = device_get_softc(dev); + + I2C_SET(sc,dev,0,1); + I2C_SET(sc,dev,1,1); + I2C_SET(sc,dev,0,1); return; } static void iicbb_zero(device_t dev, int timeout) { - I2C_SET(dev,0,0); - I2C_SET(dev,1,0); - I2C_SET(dev,0,0); + struct iicbb_softc *sc = device_get_softc(dev); + + I2C_SET(sc,dev,0,0); + I2C_SET(sc,dev,1,0); + I2C_SET(sc,dev,0,0); return; } @@ -262,20 +268,21 @@ iicbb_zero(device_t dev, int timeout) static int iicbb_ack(device_t dev, int timeout) { + struct iicbb_softc *sc = device_get_softc(dev); int noack; int k = 0; - I2C_SET(dev,0,1); - I2C_SET(dev,1,1); + I2C_SET(sc,dev,0,1); + I2C_SET(sc,dev,1,1); do { noack = I2C_GETSDA(dev); if (!noack) break; - DELAY(10); - k += 10; + DELAY(1); + k++; } while (k < timeout); - I2C_SET(dev,0,1); + I2C_SET(sc,dev,0,1); I2C_DEBUG(kprintf("%c ",noack?'-':'+')); return (noack); @@ -300,16 +307,17 @@ iicbb_sendbyte(device_t dev, u_char data, int timeout) static u_char iicbb_readbyte(device_t dev, int last, int timeout) { + struct iicbb_softc *sc = device_get_softc(dev); int i; unsigned char data=0; - I2C_SET(dev,0,1); + I2C_SET(sc,dev,0,1); for (i=7; i>=0; i--) { - I2C_SET(dev,1,1); + I2C_SET(sc,dev,1,1); if (I2C_GETSDA(dev)) data |= (1<")); + I2C_DEBUG(kprintf("\n")); return (0); } @@ -411,6 +423,21 @@ iicbb_read(device_t dev, char * buf, int len, int *read, int last, int delay) return (0); } +static int +iicbb_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs) +{ + int error; + + error = IICBB_PRE_XFER(device_get_parent(dev)); + if (error) + return (error); + + error = iicbus_transfer_gen(dev, msgs, nmsgs); + + IICBB_POST_XFER(device_get_parent(dev)); + return (error); +} + DRIVER_MODULE(iicbb, bti2c, iicbb_driver, iicbb_devclass, NULL, NULL); DRIVER_MODULE(iicbb, cxm_iic, iicbb_driver, iicbb_devclass, NULL, NULL); DRIVER_MODULE(iicbb, intel_iic, iicbb_driver, iicbb_devclass, NULL, NULL); diff --git a/sys/bus/iicbus/iicbb_if.m b/sys/bus/iicbus/iicbb_if.m index 202c20cf4c..03b9ae4803 100644 --- a/sys/bus/iicbus/iicbb_if.m +++ b/sys/bus/iicbus/iicbb_if.m @@ -23,14 +23,36 @@ # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # -# $FreeBSD: src/sys/dev/iicbus/iicbb_if.m,v 1.6 2005/01/06 01:42:47 imp Exp $ -# $DragonFly: src/sys/bus/iicbus/iicbb_if.m,v 1.3 2003/11/17 00:54:39 asmodai Exp $ +# $FreeBSD: head/sys/dev/iicbus/iicbb_if.m 232365 2012-03-01 20:58:20Z kan $ # #include INTERFACE iicbb; +# +# Default implementation of optional methods +# +CODE { + static int + null_pre_xfer(device_t dev) + { + return 0; + } + + static void + null_post_xfer(device_t dev) + + { + } + + static int + null_callback(device_t dev, int index, caddr_t data) + { + return 0; + } +}; + # # iicbus callback # @@ -38,7 +60,21 @@ METHOD int callback { device_t dev; int index; caddr_t data; -}; +} DEFAULT null_callback; + +# +# Prepare device for I2C transfer +# +METHOD int pre_xfer { + device_t dev; +} DEFAULT null_pre_xfer; + +# +# Cleanup device after I2C transfer +# +METHOD void post_xfer { + device_t dev; +} DEFAULT null_post_xfer; # # Set I2C bus data line -- 2.41.0