Subject: [PATCH 10/13 v3] ARM: OMAP3: Add I2C support

From: Dirk Behme <[EMAIL PROTECTED]>

Add I2C support

Signed-off-by: Dirk Behme <[EMAIL PROTECTED]>

---
Changes in version v2:

- Remove SMC911X network init as proposed by Ben Warren. Thanks!

 drivers/i2c/Makefile       |    1 
 drivers/i2c/omap24xx_i2c.c |  132 ++++++++++++++++++++++++++-------------------
 drivers/net/Makefile       |    1 
 3 files changed, 80 insertions(+), 54 deletions(-)

Index: u-boot-arm/drivers/i2c/Makefile
===================================================================
--- u-boot-arm.orig/drivers/i2c/Makefile
+++ u-boot-arm/drivers/i2c/Makefile
@@ -29,6 +29,7 @@ COBJS-$(CONFIG_FSL_I2C) += fsl_i2c.o
 COBJS-$(CONFIG_I2C_MXC) += mxc_i2c.o
 COBJS-$(CONFIG_DRIVER_OMAP1510_I2C) += omap1510_i2c.o
 COBJS-$(CONFIG_DRIVER_OMAP24XX_I2C) += omap24xx_i2c.o
+COBJS-$(CONFIG_DRIVER_OMAP34XX_I2C) += omap24xx_i2c.o
 COBJS-$(CONFIG_SOFT_I2C) += soft_i2c.o
 COBJS-$(CONFIG_TSI108_I2C) += tsi108_i2c.o
 
Index: u-boot-arm/drivers/i2c/omap24xx_i2c.c
===================================================================
--- u-boot-arm.orig/drivers/i2c/omap24xx_i2c.c
+++ u-boot-arm/drivers/i2c/omap24xx_i2c.c
@@ -25,8 +25,10 @@
 #include <asm/arch/i2c.h>
 #include <asm/io.h>
 
+#define inb(a) __raw_readb(a)
+#define outb(a, v) __raw_writeb(a, v)
 #define inw(a) __raw_readw(a)
-#define outw(a,v) __raw_writew(a,v)
+#define outw(a, v) __raw_writew(a, v)
 
 static void wait_for_bb (void);
 static u16 wait_for_pin (void);
@@ -40,28 +42,28 @@ void i2c_init (int speed, int slaveadd)
        udelay(1000);
        outw(0x0, I2C_SYSC); /* will probably self clear but */
 
-       if (inw (I2C_CON) & I2C_CON_EN) {
-               outw (0, I2C_CON);
+       if (inw(I2C_CON) & I2C_CON_EN) {
+               outw(0, I2C_CON);
                udelay (50000);
        }
 
        /* 12Mhz I2C module clock */
-       outw (0, I2C_PSC);
+       outw(0, I2C_PSC);
        speed = speed/1000;                 /* 100 or 400 */
        scl = ((12000/(speed*2)) - 7);  /* use 7 when PSC = 0 */
-       outw (scl, I2C_SCLL);
-       outw (scl, I2C_SCLH);
+       outw(scl, I2C_SCLL);
+       outw(scl, I2C_SCLH);
        /* own address */
-       outw (slaveadd, I2C_OA);
-       outw (I2C_CON_EN, I2C_CON);
+       outw(slaveadd, I2C_OA);
+       outw(I2C_CON_EN, I2C_CON);
 
        /* have to enable intrrupts or OMAP i2c module doesn't work */
-       outw (I2C_IE_XRDY_IE | I2C_IE_RRDY_IE | I2C_IE_ARDY_IE |
-             I2C_IE_NACK_IE | I2C_IE_AL_IE, I2C_IE);
+       outw(I2C_IE_XRDY_IE | I2C_IE_RRDY_IE | I2C_IE_ARDY_IE |
+            I2C_IE_NACK_IE | I2C_IE_AL_IE, I2C_IE);
        udelay (1000);
        flush_fifo();
-       outw (0xFFFF, I2C_STAT);
-       outw (0, I2C_CNT);
+       outw(0xFFFF, I2C_STAT);
+       outw(0, I2C_CNT);
 }
 
 static int i2c_read_byte (u8 devaddr, u8 regoffset, u8 * value)
@@ -73,11 +75,11 @@ static int i2c_read_byte (u8 devaddr, u8
        wait_for_bb ();
 
        /* one byte only */
-       outw (1, I2C_CNT);
+       outw(1, I2C_CNT);
        /* set slave address */
-       outw (devaddr, I2C_SA);
+       outw(devaddr, I2C_SA);
        /* no stop bit needed here */
-       outw (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX, I2C_CON);
+       outw(I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX, I2C_CON);
 
        status = wait_for_pin ();
 
@@ -85,7 +87,7 @@ static int i2c_read_byte (u8 devaddr, u8
                /* Important: have to use byte access */
                *(volatile u8 *) (I2C_DATA) = regoffset;
                udelay (20000);
-               if (inw (I2C_STAT) & I2C_STAT_NACK) {
+               if (inw(I2C_STAT) & I2C_STAT_NACK) {
                        i2c_error = 1;
                }
        } else {
@@ -94,42 +96,46 @@ static int i2c_read_byte (u8 devaddr, u8
 
        if (!i2c_error) {
                /* free bus, otherwise we can't use a combined transction */
-               outw (0, I2C_CON);
-               while (inw (I2C_STAT) || (inw (I2C_CON) & I2C_CON_MST)) {
+               outw(0, I2C_CON);
+               while (inw(I2C_STAT) || (inw(I2C_CON) & I2C_CON_MST)) {
                        udelay (10000);
                        /* Have to clear pending interrupt to clear I2C_STAT */
-                       outw (0xFFFF, I2C_STAT);
+                       outw(0xFFFF, I2C_STAT);
                }
 
                wait_for_bb ();
                /* set slave address */
-               outw (devaddr, I2C_SA);
+               outw(devaddr, I2C_SA);
                /* read one byte from slave */
-               outw (1, I2C_CNT);
+               outw(1, I2C_CNT);
                /* need stop bit here */
-               outw (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_STP,
-                     I2C_CON);
+               outw(I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_STP,
+                    I2C_CON);
 
                status = wait_for_pin ();
                if (status & I2C_STAT_RRDY) {
-                       *value = inw (I2C_DATA);
+#if defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX)
+                       *value = inb(I2C_DATA);
+#else
+                       *value = inw(I2C_DATA);
+#endif
                        udelay (20000);
                } else {
                        i2c_error = 1;
                }
 
                if (!i2c_error) {
-                       outw (I2C_CON_EN, I2C_CON);
-                       while (inw (I2C_STAT)
-                              || (inw (I2C_CON) & I2C_CON_MST)) {
+                       outw(I2C_CON_EN, I2C_CON);
+                       while (inw(I2C_STAT)
+                              || (inw(I2C_CON) & I2C_CON_MST)) {
                                udelay (10000);
-                               outw (0xFFFF, I2C_STAT);
+                               outw(0xFFFF, I2C_STAT);
                        }
                }
        }
        flush_fifo();
-       outw (0xFFFF, I2C_STAT);
-       outw (0, I2C_CNT);
+       outw(0xFFFF, I2C_STAT);
+       outw(0, I2C_CNT);
        return i2c_error;
 }
 
@@ -142,22 +148,37 @@ static int i2c_write_byte (u8 devaddr, u
        wait_for_bb ();
 
        /* two bytes */
-       outw (2, I2C_CNT);
+       outw(2, I2C_CNT);
        /* set slave address */
-       outw (devaddr, I2C_SA);
+       outw(devaddr, I2C_SA);
        /* stop bit needed here */
-       outw (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX |
-             I2C_CON_STP, I2C_CON);
+       outw(I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX |
+            I2C_CON_STP, I2C_CON);
 
        /* wait until state change */
        status = wait_for_pin ();
 
        if (status & I2C_STAT_XRDY) {
+#if defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX)
+               /* send out 1 byte */
+               outb(regoffset, I2C_DATA);
+               outw(I2C_STAT_XRDY, I2C_STAT);
+               status = wait_for_pin();
+               if ((status & I2C_STAT_XRDY)) {
+                       /* send out next 1 byte */
+                       outb(value, I2C_DATA);
+                       outw(I2C_STAT_XRDY, I2C_STAT);
+               } else {
+                       i2c_error = 1;
+               }
+#else
                /* send out two bytes */
-               outw ((value << 8) + regoffset, I2C_DATA);
+               outw((value << 8) + regoffset, I2C_DATA);
+#endif
+
                /* must have enough delay to allow BB bit to go low */
                udelay (50000);
-               if (inw (I2C_STAT) & I2C_STAT_NACK) {
+               if (inw(I2C_STAT) & I2C_STAT_NACK) {
                        i2c_error = 1;
                }
        } else {
@@ -167,18 +188,18 @@ static int i2c_write_byte (u8 devaddr, u
        if (!i2c_error) {
                int eout = 200;
 
-               outw (I2C_CON_EN, I2C_CON);
-               while ((stat = inw (I2C_STAT)) || (inw (I2C_CON) & 
I2C_CON_MST)) {
+               outw(I2C_CON_EN, I2C_CON);
+               while ((stat = inw(I2C_STAT)) || (inw(I2C_CON) & I2C_CON_MST)) {
                        udelay (1000);
                        /* have to read to clear intrrupt */
-                       outw (0xFFFF, I2C_STAT);
+                       outw(0xFFFF, I2C_STAT);
                        if(--eout == 0) /* better leave with error than hang */
                                break;
                }
        }
        flush_fifo();
-       outw (0xFFFF, I2C_STAT);
-       outw (0, I2C_CNT);
+       outw(0xFFFF, I2C_STAT);
+       outw(0, I2C_CNT);
        return i2c_error;
 }
 
@@ -191,7 +212,11 @@ static void flush_fifo(void)
        while(1){
                stat = inw(I2C_STAT);
                if(stat == I2C_STAT_RRDY){
+#if defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX)
+                       inb(I2C_DATA);
+#else
                        inw(I2C_DATA);
+#endif
                        outw(I2C_STAT_RRDY,I2C_STAT);
                        udelay(1000);
                }else
@@ -203,34 +228,33 @@ int i2c_probe (uchar chip)
 {
        int res = 1; /* default = fail */
 
-       if (chip == inw (I2C_OA)) {
+       if (chip == inw(I2C_OA))
                return res;
-       }
 
        /* wait until bus not busy */
        wait_for_bb ();
 
        /* try to read one byte */
-       outw (1, I2C_CNT);
+       outw(1, I2C_CNT);
        /* set slave address */
-       outw (chip, I2C_SA);
+       outw(chip, I2C_SA);
        /* stop bit needed here */
-       outw (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_STP, I2C_CON);
+       outw(I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_STP, I2C_CON);
        /* enough delay for the NACK bit set */
        udelay (50000);
 
-       if (!(inw (I2C_STAT) & I2C_STAT_NACK)) {
+       if (!(inw(I2C_STAT) & I2C_STAT_NACK)) {
                res = 0;      /* success case */
                flush_fifo();
                outw(0xFFFF, I2C_STAT);
        } else {
                outw(0xFFFF, I2C_STAT);  /* failue, clear sources*/
-               outw (inw (I2C_CON) | I2C_CON_STP, I2C_CON); /* finish up xfer 
*/
+               outw(inw(I2C_CON) | I2C_CON_STP, I2C_CON); /* finish up xfer */
                udelay(20000);
                wait_for_bb ();
        }
        flush_fifo();
-       outw (0, I2C_CNT); /* don't allow any more data in...we don't want it.*/
+       outw(0, I2C_CNT); /* don't allow any more data in...we don't want it.*/
        outw(0xFFFF, I2C_STAT);
        return res;
 }
@@ -291,14 +315,14 @@ static void wait_for_bb (void)
        u16 stat;
 
        outw(0xFFFF, I2C_STAT);  /* clear current interruts...*/
-       while ((stat = inw (I2C_STAT) & I2C_STAT_BB) && timeout--) {
-               outw (stat, I2C_STAT);
+       while ((stat = inw(I2C_STAT) & I2C_STAT_BB) && timeout--) {
+               outw(stat, I2C_STAT);
                udelay (50000);
        }
 
        if (timeout <= 0) {
                printf ("timed out in wait_for_bb: I2C_STAT=%x\n",
-                       inw (I2C_STAT));
+                       inw(I2C_STAT));
        }
        outw(0xFFFF, I2C_STAT);  /* clear delayed stuff*/
 }
@@ -310,7 +334,7 @@ static u16 wait_for_pin (void)
 
        do {
                udelay (1000);
-               status = inw (I2C_STAT);
+               status = inw(I2C_STAT);
        } while (  !(status &
                   (I2C_STAT_ROVR | I2C_STAT_XUDF | I2C_STAT_XRDY |
                    I2C_STAT_RRDY | I2C_STAT_ARDY | I2C_STAT_NACK |
@@ -318,7 +342,7 @@ static u16 wait_for_pin (void)
 
        if (timeout <= 0) {
                printf ("timed out in wait_for_pin: I2C_STAT=%x\n",
-                       inw (I2C_STAT));
+                       inw(I2C_STAT));
                        outw(0xFFFF, I2C_STAT);
 }
        return status;

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to