This patch Updates I2C register offset addresses and adds support for OMAP4430
development platform.

Signed-off-by: Syed Rafiuddin <[email protected]>
---
 arch/arm/mach-omap2/board-4430sdp.c |    9 +++-
 arch/arm/plat-omap/i2c.c            |   21 +++++++--
 drivers/i2c/busses/i2c-omap.c       |   78 +++++++++++++++++++++++++-----------
 3 files changed, 80 insertions(+), 28 deletions(-)

Index: omap4_dev/arch/arm/mach-omap2/board-4430sdp.c
===================================================================
--- omap4_dev.orig/arch/arm/mach-omap2/board-4430sdp.c
+++ omap4_dev/arch/arm/mach-omap2/board-4430sdp.c
@@ -66,10 +66,17 @@ static void __init omap_4430sdp_init_irq
        gic_init_irq();
        omap_gpio_init();
 }
-
+static int __init omap4_i2c_init(void)
+{
+       omap_register_i2c_bus(1, 2600, NULL, 0);
+       omap_register_i2c_bus(2, 400, NULL, 0);
+       omap_register_i2c_bus(3, 400, NULL, 0);
+       return 0;
+}

 static void __init omap_4430sdp_init(void)
 {
+       omap4_i2c_init();
        platform_add_devices(sdp4430_devices, ARRAY_SIZE(sdp4430_devices));
        omap_board_config = sdp4430_config;
        omap_board_config_size = ARRAY_SIZE(sdp4430_config);
Index: omap4_dev/arch/arm/plat-omap/i2c.c
===================================================================
--- omap4_dev.orig/arch/arm/plat-omap/i2c.c
+++ omap4_dev/arch/arm/plat-omap/i2c.c
@@ -53,9 +53,15 @@ static struct resource i2c_resources[][2
 #if    defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
        { I2C_RESOURCE_BUILDER(OMAP2_I2C_BASE2, INT_24XX_I2C2_IRQ) },
 #endif
+#if    defined(CONFIG_ARCH_OMAP4)
+       { I2C_RESOURCE_BUILDER(OMAP2_I2C_BASE2, INT_44XX_I2C2_IRQ) },
+#endif
 #if    defined(CONFIG_ARCH_OMAP34XX)
        { I2C_RESOURCE_BUILDER(OMAP2_I2C_BASE3, INT_34XX_I2C3_IRQ) },
 #endif
+#if    defined(CONFIG_ARCH_OMAP4)
+       { I2C_RESOURCE_BUILDER(OMAP2_I2C_BASE3, INT_44XX_I2C3_IRQ) },
+#endif
 };

 #define I2C_DEV_BUILDER(bus_id, res, data)             \
@@ -72,10 +78,11 @@ static struct resource i2c_resources[][2
 static u32 i2c_rate[ARRAY_SIZE(i2c_resources)];
 static struct platform_device omap_i2c_devices[] = {
        I2C_DEV_BUILDER(1, i2c_resources[0], &i2c_rate[0]),
-#if    defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
+#if    defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \
+defined(CONFIG_ARCH_OMAP4)
        I2C_DEV_BUILDER(2, i2c_resources[1], &i2c_rate[1]),
 #endif
-#if    defined(CONFIG_ARCH_OMAP34XX)
+#if    defined(CONFIG_ARCH_OMAP34XX) || defined(CONFIG_ARCH_OMAP4)
        I2C_DEV_BUILDER(3, i2c_resources[2], &i2c_rate[2]),
 #endif
 };
@@ -88,7 +95,7 @@ static const int omap24xx_pins[][2] = {
 #else
 static const int omap24xx_pins[][2] = {};
 #endif
-#if defined(CONFIG_ARCH_OMAP34XX)
+#if defined(CONFIG_ARCH_OMAP34XX) || defined(CONFIG_ARCH_OMAP4)
 static const int omap34xx_pins[][2] = {
        { K21_34XX_I2C1_SCL, J21_34XX_I2C1_SDA},
        { AF15_34XX_I2C2_SCL, AE15_34XX_I2C2_SDA},
@@ -110,7 +117,7 @@ static void __init omap_i2c_mux_pins(int
        } else if (cpu_is_omap24xx()) {
                scl = omap24xx_pins[bus][0];
                sda = omap24xx_pins[bus][1];
-       } else if (cpu_is_omap34xx()) {
+       } else if (cpu_is_omap34xx() || cpu_is_omap44xx()) {
                scl = omap34xx_pins[bus][0];
                sda = omap34xx_pins[bus][1];
        } else {
@@ -129,7 +136,7 @@ static int __init omap_i2c_nr_ports(void
                ports = 1;
        else if (cpu_is_omap24xx())
                ports = 2;
-       else if (cpu_is_omap34xx())
+       else if (cpu_is_omap34xx() || cpu_is_omap44xx())
                ports = 3;

        return ports;
@@ -151,6 +158,10 @@ static int __init omap_i2c_add_bus(int b
                        base = OMAP2_I2C_BASE1;
                        irq = INT_24XX_I2C1_IRQ;
                }
+               if (cpu_is_omap44xx()) {
+                       base = OMAP2_I2C_BASE1;
+                       irq = INT_44XX_I2C1_IRQ;
+               }
                res[0].start = base;
                res[0].end = base + OMAP_I2C_SIZE;
                res[1].start = irq;
Index: omap4_dev/drivers/i2c/busses/i2c-omap.c
===================================================================
--- omap4_dev.orig/drivers/i2c/busses/i2c-omap.c
+++ omap4_dev/drivers/i2c/busses/i2c-omap.c
@@ -27,7 +27,6 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-
 #include <linux/module.h>
 #include <linux/delay.h>
 #include <linux/i2c.h>
@@ -48,12 +47,36 @@
 /* timeout waiting for the controller to respond */
 #define OMAP_I2C_TIMEOUT (msecs_to_jiffies(1000))

+#define OMAP_I2C_WE_REG                        0x0c
+#ifdef CONFIG_ARCH_OMAP4
+#define OMAP_I2C_REVNB_LO               0x00
+#define OMAP_I2C_REVNB_HI               0x04
+#define OMAP_I2C_IV_REG                 0x34
+#define OMAP_I2C_IRQSTATUS_RAW          0x24
+#define OMAP_I2C_STAT_REG               0x28
+#define OMAP_I2C_IRQENABLE_SET          0x2C
+#define OMAP_I2C_IRQENABLE_CLR          0x30
+#define OMAP_I2C_SYSS_REG               0x90
+#define OMAP_I2C_BUF_REG                0x94
+#define OMAP_I2C_CNT_REG                0x98
+#define OMAP_I2C_DATA_REG               0x9C
+#define OMAP_I2C_SYSC_REG               0x10
+#define OMAP_I2C_CON_REG                0xA4
+#define OMAP_I2C_OA_REG                 0xA8
+#define OMAP_I2C_SA_REG                 0xAC
+#define OMAP_I2C_PSC_REG                0xB0
+#define OMAP_I2C_SCLL_REG               0xB4
+#define OMAP_I2C_SCLH_REG               0xB8
+#define OMAP_I2C_SYSTEST_REG            0xBC
+#define OMAP_I2C_BUFSTAT_REG            0xC0
+#define OMAP_I2C_IE_REG                 OMAP_I2C_IRQENABLE_SET
+#define OMAP_I2C_REV_REG               OMAP_I2C_REVNB_HI
+#else
 #define OMAP_I2C_REV_REG               0x00
 #define OMAP_I2C_IE_REG                        0x04
 #define OMAP_I2C_STAT_REG              0x08
 #define OMAP_I2C_IV_REG                        0x0c
 /* For OMAP3 I2C_IV has changed to I2C_WE (wakeup enable) */
-#define OMAP_I2C_WE_REG                        0x0c
 #define OMAP_I2C_SYSS_REG              0x10
 #define OMAP_I2C_BUF_REG               0x14
 #define OMAP_I2C_CNT_REG               0x18
@@ -67,7 +90,8 @@
 #define OMAP_I2C_SCLH_REG              0x38
 #define OMAP_I2C_SYSTEST_REG           0x3c
 #define OMAP_I2C_BUFSTAT_REG           0x40
-
+#define OMAP_I2C_IRQENABLE_CLR          OMAP_I2C_IE_REG
+#endif
 /* I2C Interrupt Enable Register (OMAP_I2C_IE): */
 #define OMAP_I2C_IE_XDR                (1 << 14)       /* TX Buffer drain int 
enable */
 #define OMAP_I2C_IE_RDR                (1 << 13)       /* RX Buffer drain int 
enable */
@@ -242,7 +266,10 @@ static void omap_i2c_idle(struct omap_i2
        WARN_ON(dev->idle);

        dev->iestate = omap_i2c_read_reg(dev, OMAP_I2C_IE_REG);
-       omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, 0);
+       if (cpu_is_omap44xx())
+               omap_i2c_write_reg(dev, OMAP_I2C_IRQENABLE_CLR, 1);
+       else
+               omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, 0);
        if (dev->rev < OMAP_I2C_REV_2) {
                iv = omap_i2c_read_reg(dev, OMAP_I2C_IV_REG); /* Read clears */
        } else {
@@ -282,10 +309,8 @@ static int omap_i2c_init(struct omap_i2c

                /* SYSC register is cleared by the reset; rewrite it */
                if (dev->rev == OMAP_I2C_REV_ON_2430) {
-
                        omap_i2c_write_reg(dev, OMAP_I2C_SYSC_REG,
                                           SYSC_AUTOIDLE_MASK);
-
                } else if (dev->rev >= OMAP_I2C_REV_ON_3430) {
                        u32 v;

@@ -302,6 +327,7 @@ static int omap_i2c_init(struct omap_i2c
                         * WFI instruction.
                         * REVISIT: Some wkup sources might not be needed.
                         */
+                       if (!cpu_is_omap44xx())
                        omap_i2c_write_reg(dev, OMAP_I2C_WE_REG,
                                                        OMAP_I2C_WE_ALL);

@@ -331,11 +357,14 @@ static int omap_i2c_init(struct omap_i2c
                        psc = fclk_rate / 12000000;
        }

-       if (cpu_is_omap2430() || cpu_is_omap34xx()) {
+       if (cpu_is_omap2430() || cpu_is_omap34xx() || cpu_is_omap44xx()) {

                /* HSI2C controller internal clk rate should be 19.2 Mhz */
                internal_clk = 19200;
-               fclk_rate = clk_get_rate(dev->fclk) / 1000;
+               if (cpu_is_omap44xx())
+                       fclk_rate = 96000;
+               else
+                       fclk_rate = clk_get_rate(dev->fclk) / 1000;

                /* Compute prescaler divisor */
                psc = fclk_rate / internal_clk;
@@ -650,14 +679,12 @@ omap_i2c_isr(int this_irq, void *dev_id)
                        dev_warn(dev->dev, "Too much work in one IRQ\n");
                        break;
                }
-
                omap_i2c_write_reg(dev, OMAP_I2C_STAT_REG, stat);
-
                err = 0;
                if (stat & OMAP_I2C_STAT_NACK) {
                        err |= OMAP_I2C_STAT_NACK;
                        omap_i2c_write_reg(dev, OMAP_I2C_CON_REG,
-                                          OMAP_I2C_CON_STP);
+                                       OMAP_I2C_CON_STP);
                }
                if (stat & OMAP_I2C_STAT_AL) {
                        dev_err(dev->dev, "Arbitration lost\n");
@@ -683,7 +710,8 @@ omap_i2c_isr(int this_irq, void *dev_id)
                                        dev->buf_len--;
                                        /* Data reg from 2430 is 8 bit wide */
                                        if (!cpu_is_omap2430() &&
-                                                       !cpu_is_omap34xx()) {
+                                               !cpu_is_omap34xx()
+                                                       && !cpu_is_omap44xx()) {
                                                if (dev->buf_len) {
                                                        *dev->buf++ = w >> 8;
                                                        dev->buf_len--;
@@ -710,9 +738,10 @@ omap_i2c_isr(int this_irq, void *dev_id)
                        if (dev->fifo_size) {
                                if (stat & OMAP_I2C_STAT_XRDY)
                                        num_bytes = dev->fifo_size;
-                               else
+                               else {
                                        num_bytes = omap_i2c_read_reg(dev,
                                                        OMAP_I2C_BUFSTAT_REG);
+                               }
                        }
                        while (num_bytes) {
                                num_bytes--;
@@ -722,7 +751,8 @@ omap_i2c_isr(int this_irq, void *dev_id)
                                        dev->buf_len--;
                                        /* Data reg from  2430 is 8 bit wide */
                                        if (!cpu_is_omap2430() &&
-                                                       !cpu_is_omap34xx()) {
+                                               !cpu_is_omap34xx() &&
+                                                       !cpu_is_omap44xx()) {
                                                if (dev->buf_len) {
                                                        w |= *dev->buf++ << 8;
                                                        dev->buf_len--;
@@ -733,10 +763,10 @@ omap_i2c_isr(int this_irq, void *dev_id)
                                                dev_err(dev->dev,
                                                        "XRDY IRQ while no "
                                                        "data to send\n");
-                                       if (stat & OMAP_I2C_STAT_XDR)
-                                               dev_err(dev->dev,
-                                                       "XDR IRQ while no "
-                                                       "data to send\n");
+                                               if (stat & OMAP_I2C_STAT_XDR)
+                                                       dev_err(dev->dev,
+                                                               "XDR IRQ while 
no "
+                                                               "data to 
send\n");
                                        break;
                                }
                                omap_i2c_write_reg(dev, OMAP_I2C_DATA_REG, w);
@@ -754,7 +784,6 @@ omap_i2c_isr(int this_irq, void *dev_id)
                        dev->cmd_err |= OMAP_I2C_STAT_XUDF;
                }
        }
-
        return count ? IRQ_HANDLED : IRQ_NONE;
 }

@@ -822,7 +851,7 @@ omap_i2c_probe(struct platform_device *p

        dev->rev = omap_i2c_read_reg(dev, OMAP_I2C_REV_REG) & 0xff;

-       if (cpu_is_omap2430() || cpu_is_omap34xx()) {
+       if (cpu_is_omap2430() || cpu_is_omap34xx() ||  cpu_is_omap44xx()) {
                u16 s;

                /* Set up the fifo size - Get total size */
@@ -834,8 +863,13 @@ omap_i2c_probe(struct platform_device *p
                 * size. This is to ensure that we can handle the status on int
                 * call back latencies.
                 */
-               dev->fifo_size = (dev->fifo_size / 2);
-               dev->b_hw = 1; /* Enable hardware fixes */
+               if (cpu_is_omap44xx()) {
+                       dev->fifo_size = 0;
+                       dev->b_hw = 0; /* Enable hardware fixes */
+               } else {
+                       dev->fifo_size = (dev->fifo_size / 2);
+                       dev->b_hw = 1; /* Enable hardware fixes */
+               }
        }

        /* reset ASAP, clearing any IRQs */


---
Syed Rafiuddin

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to