drivers: i2c: omap24xx_i2c: prepare driver for DM conversion
authorMugunthan V N <mugunthanvnm@ti.com>
Mon, 18 Jul 2016 09:41:00 +0000 (15:11 +0530)
committerHeiko Schocher <hs@denx.de>
Tue, 26 Jul 2016 06:39:57 +0000 (08:39 +0200)
Prepare the driver for DM conversion.

Signed-off-by: Mugunthan V N <mugunthanvnm@ti.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
drivers/i2c/omap24xx_i2c.c

index a7f3fb4..8dea5fa 100644 (file)
@@ -53,10 +53,6 @@ DECLARE_GLOBAL_DATA_PTR;
 /* Absolutely safe for status update at 100 kHz I2C: */
 #define I2C_WAIT       200
 
-static int wait_for_bb(struct i2c_adapter *adap);
-static struct i2c *omap24_get_base(struct i2c_adapter *adap);
-static u16 wait_for_event(struct i2c_adapter *adap);
-static void flush_fifo(struct i2c_adapter *adap);
 static int omap24_i2c_findpsc(u32 *pscl, u32 *psch, uint speed)
 {
        unsigned int sampleclk, prescaler;
@@ -90,9 +86,96 @@ static int omap24_i2c_findpsc(u32 *pscl, u32 *psch, uint speed)
        }
        return -1;
 }
-static uint omap24_i2c_setspeed(struct i2c_adapter *adap, uint speed)
+
+/*
+ * Wait for the bus to be free by checking the Bus Busy (BB)
+ * bit to become clear
+ */
+static int wait_for_bb(struct i2c *i2c_base, int waitdelay)
+{
+       int timeout = I2C_TIMEOUT;
+       u16 stat;
+
+       writew(0xFFFF, &i2c_base->stat);        /* clear current interrupts...*/
+#if defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX)
+       while ((stat = readw(&i2c_base->stat) & I2C_STAT_BB) && timeout--) {
+#else
+       /* Read RAW status */
+       while ((stat = readw(&i2c_base->irqstatus_raw) &
+               I2C_STAT_BB) && timeout--) {
+#endif
+               writew(stat, &i2c_base->stat);
+               udelay(waitdelay);
+       }
+
+       if (timeout <= 0) {
+               printf("Timed out in wait_for_bb: status=%04x\n",
+                      stat);
+               return 1;
+       }
+       writew(0xFFFF, &i2c_base->stat);         /* clear delayed stuff*/
+       return 0;
+}
+
+/*
+ * Wait for the I2C controller to complete current action
+ * and update status
+ */
+static u16 wait_for_event(struct i2c *i2c_base, int waitdelay)
+{
+       u16 status;
+       int timeout = I2C_TIMEOUT;
+
+       do {
+               udelay(waitdelay);
+#if defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX)
+               status = readw(&i2c_base->stat);
+#else
+               /* Read RAW status */
+               status = readw(&i2c_base->irqstatus_raw);
+#endif
+       } while (!(status &
+                  (I2C_STAT_ROVR | I2C_STAT_XUDF | I2C_STAT_XRDY |
+                   I2C_STAT_RRDY | I2C_STAT_ARDY | I2C_STAT_NACK |
+                   I2C_STAT_AL)) && timeout--);
+
+       if (timeout <= 0) {
+               printf("Timed out in wait_for_event: status=%04x\n",
+                      status);
+               /*
+                * If status is still 0 here, probably the bus pads have
+                * not been configured for I2C, and/or pull-ups are missing.
+                */
+               printf("Check if pads/pull-ups of bus are properly configured\n");
+               writew(0xFFFF, &i2c_base->stat);
+               status = 0;
+       }
+
+       return status;
+}
+
+static void flush_fifo(struct i2c *i2c_base)
+{
+       u16 stat;
+
+       /*
+        * note: if you try and read data when its not there or ready
+        * you get a bus error
+        */
+       while (1) {
+               stat = readw(&i2c_base->stat);
+               if (stat == I2C_STAT_RRDY) {
+                       readb(&i2c_base->data);
+                       writew(I2C_STAT_RRDY, &i2c_base->stat);
+                       udelay(1000);
+               } else
+                       break;
+       }
+}
+
+static int __omap24_i2c_setspeed(struct i2c *i2c_base, uint speed,
+                                int *waitdelay)
 {
-       struct i2c *i2c_base = omap24_get_base(adap);
        int psc, fsscll = 0, fssclh = 0;
        int hsscll = 0, hssclh = 0;
        u32 scll = 0, sclh = 0;
@@ -142,8 +225,7 @@ static uint omap24_i2c_setspeed(struct i2c_adapter *adap, uint speed)
                }
        }
 
-       adap->speed     = speed;
-       adap->waitdelay = (10000000 / speed) * 2; /* wait for 20 clkperiods */
+       *waitdelay = (10000000 / speed) * 2; /* wait for 20 clkperiods */
        writew(0, &i2c_base->con);
        writew(psc, &i2c_base->psc);
        writew(scll, &i2c_base->scll);
@@ -154,9 +236,8 @@ static uint omap24_i2c_setspeed(struct i2c_adapter *adap, uint speed)
        return 0;
 }
 
-static void omap24_i2c_deblock(struct i2c_adapter *adap)
+static void omap24_i2c_deblock(struct i2c *i2c_base)
 {
-       struct i2c *i2c_base = omap24_get_base(adap);
        int i;
        u16 systest;
        u16 orgsystest;
@@ -200,9 +281,9 @@ static void omap24_i2c_deblock(struct i2c_adapter *adap)
        writew(orgsystest, &i2c_base->systest);
 }
 
-static void omap24_i2c_init(struct i2c_adapter *adap, int speed, int slaveadd)
+static void __omap24_i2c_init(struct i2c *i2c_base, int speed, int slaveadd,
+                             int *waitdelay)
 {
-       struct i2c *i2c_base = omap24_get_base(adap);
        int timeout = I2C_TIMEOUT;
        int deblock = 1;
 
@@ -224,7 +305,7 @@ retry:
                udelay(1000);
        }
 
-       if (0 != omap24_i2c_setspeed(adap, speed)) {
+       if (0 != __omap24_i2c_setspeed(i2c_base, speed, waitdelay)) {
                printf("ERROR: failed to setup I2C bus-speed!\n");
                return;
        }
@@ -241,45 +322,24 @@ retry:
               I2C_IE_NACK_IE | I2C_IE_AL_IE, &i2c_base->ie);
 #endif
        udelay(1000);
-       flush_fifo(adap);
+       flush_fifo(i2c_base);
        writew(0xFFFF, &i2c_base->stat);
 
        /* Handle possible failed I2C state */
-       if (wait_for_bb(adap))
+       if (wait_for_bb(i2c_base, *waitdelay))
                if (deblock == 1) {
-                       omap24_i2c_deblock(adap);
+                       omap24_i2c_deblock(i2c_base);
                        deblock = 0;
                        goto retry;
                }
 }
 
-static void flush_fifo(struct i2c_adapter *adap)
-{
-       struct i2c *i2c_base = omap24_get_base(adap);
-       u16 stat;
-
-       /*
-        * note: if you try and read data when its not there or ready
-        * you get a bus error
-        */
-       while (1) {
-               stat = readw(&i2c_base->stat);
-               if (stat == I2C_STAT_RRDY) {
-                       readb(&i2c_base->data);
-                       writew(I2C_STAT_RRDY, &i2c_base->stat);
-                       udelay(1000);
-               } else
-                       break;
-       }
-}
-
 /*
  * i2c_probe: Use write access. Allows to identify addresses that are
  *            write-only (like the config register of dual-port EEPROMs)
  */
-static int omap24_i2c_probe(struct i2c_adapter *adap, uchar chip)
+static int __omap24_i2c_probe(struct i2c *i2c_base, int waitdelay, uchar chip)
 {
-       struct i2c *i2c_base = omap24_get_base(adap);
        u16 status;
        int res = 1; /* default = fail */
 
@@ -287,7 +347,7 @@ static int omap24_i2c_probe(struct i2c_adapter *adap, uchar chip)
                return res;
 
        /* Wait until bus is free */
-       if (wait_for_bb(adap))
+       if (wait_for_bb(i2c_base, waitdelay))
                return res;
 
        /* No data transfer, slave addr only */
@@ -296,7 +356,7 @@ static int omap24_i2c_probe(struct i2c_adapter *adap, uchar chip)
        writew(I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX |
               I2C_CON_STP, &i2c_base->con);
 
-       status = wait_for_event(adap);
+       status = wait_for_event(i2c_base, waitdelay);
 
        if ((status & ~I2C_STAT_XRDY) == 0 || (status & I2C_STAT_AL)) {
                /*
@@ -306,8 +366,8 @@ static int omap24_i2c_probe(struct i2c_adapter *adap, uchar chip)
                 * following 'if' section:
                 */
                if (status == I2C_STAT_XRDY)
-                       printf("i2c_probe: pads on bus %d probably not configured (status=0x%x)\n",
-                              adap->hwadapnr, status);
+                       printf("i2c_probe: pads on bus probably not configured (status=0x%x)\n",
+                              status);
 
                goto pr_exit;
        }
@@ -315,7 +375,7 @@ static int omap24_i2c_probe(struct i2c_adapter *adap, uchar chip)
        /* Check for ACK (!NAK) */
        if (!(status & I2C_STAT_NACK)) {
                res = 0;                                /* Device found */
-               udelay(adap->waitdelay);/* Required by AM335X in SPL */
+               udelay(waitdelay);/* Required by AM335X in SPL */
                /* Abort transfer (force idle state) */
                writew(I2C_CON_MST | I2C_CON_TRX, &i2c_base->con); /* Reset */
                udelay(1000);
@@ -323,7 +383,7 @@ static int omap24_i2c_probe(struct i2c_adapter *adap, uchar chip)
                       I2C_CON_STP, &i2c_base->con);            /* STP */
        }
 pr_exit:
-       flush_fifo(adap);
+       flush_fifo(i2c_base);
        writew(0xFFFF, &i2c_base->stat);
        return res;
 }
@@ -341,10 +401,9 @@ pr_exit:
  *           or that do not need a register address at all (such as some clock
  *           distributors).
  */
-static int omap24_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr,
-                          int alen, uchar *buffer, int len)
+static int __omap24_i2c_read(struct i2c *i2c_base, int waitdelay, uchar chip,
+                            uint addr, int alen, uchar *buffer, int len)
 {
-       struct i2c *i2c_base = omap24_get_base(adap);
        int i2c_error = 0;
        u16 status;
 
@@ -389,7 +448,7 @@ static int omap24_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr,
 #endif
 
        /* Wait until bus not busy */
-       if (wait_for_bb(adap))
+       if (wait_for_bb(i2c_base, waitdelay))
                return 1;
 
        /* Zero, one or two bytes reg address (offset) */
@@ -410,12 +469,12 @@ static int omap24_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr,
 #endif
                /* Send register offset */
                while (1) {
-                       status = wait_for_event(adap);
+                       status = wait_for_event(i2c_base, waitdelay);
                        /* Try to identify bus that is not padconf'd for I2C */
                        if (status == I2C_STAT_XRDY) {
                                i2c_error = 2;
-                               printf("i2c_read (addr phase): pads on bus %d probably not configured (status=0x%x)\n",
-                                      adap->hwadapnr, status);
+                               printf("i2c_read (addr phase): pads on bus probably not configured (status=0x%x)\n",
+                                      status);
                                goto rd_exit;
                        }
                        if (status == 0 || (status & I2C_STAT_NACK)) {
@@ -450,7 +509,7 @@ static int omap24_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr,
 
        /* Receive data */
        while (1) {
-               status = wait_for_event(adap);
+               status = wait_for_event(i2c_base, waitdelay);
                /*
                 * Try to identify bus that is not padconf'd for I2C. This
                 * state could be left over from previous transactions if
@@ -458,8 +517,8 @@ static int omap24_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr,
                 */
                if (status == I2C_STAT_XRDY) {
                        i2c_error = 2;
-                       printf("i2c_read (data phase): pads on bus %d probably not configured (status=0x%x)\n",
-                              adap->hwadapnr, status);
+                       printf("i2c_read (data phase): pads on bus probably not configured (status=0x%x)\n",
+                              status);
                        goto rd_exit;
                }
                if (status == 0 || (status & I2C_STAT_NACK)) {
@@ -477,16 +536,15 @@ static int omap24_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr,
        }
 
 rd_exit:
-       flush_fifo(adap);
+       flush_fifo(i2c_base);
        writew(0xFFFF, &i2c_base->stat);
        return i2c_error;
 }
 
 /* i2c_write: Address (reg offset) may be 0, 1 or 2 bytes long. */
-static int omap24_i2c_write(struct i2c_adapter *adap, uchar chip, uint addr,
-                           int alen, uchar *buffer, int len)
+static int __omap24_i2c_write(struct i2c *i2c_base, int waitdelay, uchar chip,
+                             uint addr, int alen, uchar *buffer, int len)
 {
-       struct i2c *i2c_base = omap24_get_base(adap);
        int i;
        u16 status;
        int i2c_error = 0;
@@ -536,7 +594,7 @@ static int omap24_i2c_write(struct i2c_adapter *adap, uchar chip, uint addr,
 #endif
 
        /* Wait until bus not busy */
-       if (wait_for_bb(adap))
+       if (wait_for_bb(i2c_base, waitdelay))
                return 1;
 
        /* Start address phase - will write regoffset + len bytes data */
@@ -549,12 +607,12 @@ static int omap24_i2c_write(struct i2c_adapter *adap, uchar chip, uint addr,
 
        while (alen) {
                /* Must write reg offset (one or two bytes) */
-               status = wait_for_event(adap);
+               status = wait_for_event(i2c_base, waitdelay);
                /* Try to identify bus that is not padconf'd for I2C */
                if (status == I2C_STAT_XRDY) {
                        i2c_error = 2;
-                       printf("i2c_write: pads on bus %d probably not configured (status=0x%x)\n",
-                              adap->hwadapnr, status);
+                       printf("i2c_write: pads on bus probably not configured (status=0x%x)\n",
+                              status);
                        goto wr_exit;
                }
                if (status == 0 || (status & I2C_STAT_NACK)) {
@@ -576,7 +634,7 @@ static int omap24_i2c_write(struct i2c_adapter *adap, uchar chip, uint addr,
        }
        /* Address phase is over, now write data */
        for (i = 0; i < len; i++) {
-               status = wait_for_event(adap);
+               status = wait_for_event(i2c_base, waitdelay);
                if (status == 0 || (status & I2C_STAT_NACK)) {
                        i2c_error = 1;
                        printf("i2c_write: error waiting for data ACK (status=0x%x)\n",
@@ -598,87 +656,21 @@ static int omap24_i2c_write(struct i2c_adapter *adap, uchar chip, uint addr,
         * transferred on the bus.
         */
        do {
-               status = wait_for_event(adap);
+               status = wait_for_event(i2c_base, waitdelay);
        } while (!(status & I2C_STAT_ARDY) && timeout--);
        if (timeout <= 0)
                printf("i2c_write: timed out writig last byte!\n");
 
 wr_exit:
-       flush_fifo(adap);
+       flush_fifo(i2c_base);
        writew(0xFFFF, &i2c_base->stat);
        return i2c_error;
 }
 
 /*
- * Wait for the bus to be free by checking the Bus Busy (BB)
- * bit to become clear
- */
-static int wait_for_bb(struct i2c_adapter *adap)
-{
-       struct i2c *i2c_base = omap24_get_base(adap);
-       int timeout = I2C_TIMEOUT;
-       u16 stat;
-
-       writew(0xFFFF, &i2c_base->stat);        /* clear current interrupts...*/
-#if defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX)
-       while ((stat = readw(&i2c_base->stat) & I2C_STAT_BB) && timeout--) {
-#else
-       /* Read RAW status */
-       while ((stat = readw(&i2c_base->irqstatus_raw) &
-               I2C_STAT_BB) && timeout--) {
-#endif
-               writew(stat, &i2c_base->stat);
-               udelay(adap->waitdelay);
-       }
-
-       if (timeout <= 0) {
-               printf("Timed out in wait_for_bb: status=%04x\n",
-                      stat);
-               return 1;
-       }
-       writew(0xFFFF, &i2c_base->stat);         /* clear delayed stuff*/
-       return 0;
-}
-
-/*
- * Wait for the I2C controller to complete current action
- * and update status
+ * The legacy I2C functions. These need to get removed once
+ * all users of this driver are converted to DM.
  */
-static u16 wait_for_event(struct i2c_adapter *adap)
-{
-       struct i2c *i2c_base = omap24_get_base(adap);
-       u16 status;
-       int timeout = I2C_TIMEOUT;
-
-       do {
-               udelay(adap->waitdelay);
-#if defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX)
-               status = readw(&i2c_base->stat);
-#else
-               /* Read RAW status */
-               status = readw(&i2c_base->irqstatus_raw);
-#endif
-       } while (!(status &
-                  (I2C_STAT_ROVR | I2C_STAT_XUDF | I2C_STAT_XRDY |
-                   I2C_STAT_RRDY | I2C_STAT_ARDY | I2C_STAT_NACK |
-                   I2C_STAT_AL)) && timeout--);
-
-       if (timeout <= 0) {
-               printf("Timed out in wait_for_event: status=%04x\n",
-                      status);
-               /*
-                * If status is still 0 here, probably the bus pads have
-                * not been configured for I2C, and/or pull-ups are missing.
-                */
-               printf("Check if pads/pull-ups of bus %d are properly configured\n",
-                      adap->hwadapnr);
-               writew(0xFFFF, &i2c_base->stat);
-               status = 0;
-       }
-
-       return status;
-}
-
 static struct i2c *omap24_get_base(struct i2c_adapter *adap)
 {
        switch (adap->hwadapnr) {
@@ -710,6 +702,56 @@ static struct i2c *omap24_get_base(struct i2c_adapter *adap)
        return NULL;
 }
 
+
+static int omap24_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr,
+                          int alen, uchar *buffer, int len)
+{
+       struct i2c *i2c_base = omap24_get_base(adap);
+
+       return __omap24_i2c_read(i2c_base, adap->waitdelay, chip, addr,
+                                alen, buffer, len);
+}
+
+
+static int omap24_i2c_write(struct i2c_adapter *adap, uchar chip, uint addr,
+                           int alen, uchar *buffer, int len)
+{
+       struct i2c *i2c_base = omap24_get_base(adap);
+
+       return __omap24_i2c_write(i2c_base, adap->waitdelay, chip, addr,
+                                 alen, buffer, len);
+}
+
+static uint omap24_i2c_setspeed(struct i2c_adapter *adap, uint speed)
+{
+       struct i2c *i2c_base = omap24_get_base(adap);
+       int ret;
+
+       ret = __omap24_i2c_setspeed(i2c_base, speed, &adap->waitdelay);
+       if (ret) {
+               error("%s: set i2c speed failed\n", __func__);
+               return ret;
+       }
+
+       adap->speed = speed;
+
+       return 0;
+}
+
+static void omap24_i2c_init(struct i2c_adapter *adap, int speed, int slaveadd)
+{
+       struct i2c *i2c_base = omap24_get_base(adap);
+
+       return __omap24_i2c_init(i2c_base, speed, slaveadd, &adap->waitdelay);
+}
+
+static int omap24_i2c_probe(struct i2c_adapter *adap, uchar chip)
+{
+       struct i2c *i2c_base = omap24_get_base(adap);
+
+       return __omap24_i2c_probe(i2c_base, adap->waitdelay, chip);
+}
+
 #if !defined(CONFIG_SYS_OMAP24_I2C_SPEED1)
 #define CONFIG_SYS_OMAP24_I2C_SPEED1 CONFIG_SYS_OMAP24_I2C_SPEED
 #endif