diff -purN linux-omap/drivers/i2c/busses/Makefile lin_for_twl/drivers/i2c/busses/Makefile
--- linux-omap/drivers/i2c/busses/Makefile	2007-01-08 18:56:31.000000000 -0600
+++ lin_for_twl/drivers/i2c/busses/Makefile	2007-02-27 15:38:53.000000000 -0600
@@ -46,7 +46,7 @@ obj-$(CONFIG_I2C_VIAPRO)	+= i2c-viapro.o
 obj-$(CONFIG_I2C_VOODOO3)	+= i2c-voodoo3.o
 obj-$(CONFIG_SCx200_ACB)	+= scx200_acb.o
 obj-$(CONFIG_SCx200_I2C)	+= scx200_i2c.o
-obj-$(CONFIG_I2C_OMAP)          += i2c-omap.o
+obj-$(CONFIG_I2C_OMAP)          += i2c-omap_hs.o
 
 ifeq ($(CONFIG_I2C_DEBUG_BUS),y)
 EXTRA_CFLAGS += -DDEBUG
diff -purN linux-omap/drivers/i2c/busses/i2c-omap.c lin_for_twl/drivers/i2c/busses/i2c-omap.c
--- linux-omap/drivers/i2c/busses/i2c-omap.c	2007-01-08 18:56:31.000000000 -0600
+++ lin_for_twl/drivers/i2c/busses/i2c-omap.c	2007-02-27 14:34:00.000000000 -0600
@@ -115,7 +115,7 @@
 
 /* REVISIT: Use platform_data instead of module parameters */
 /* Fast Mode = 400 kHz, Standard = 100 kHz */
-static int clock = 100; /* Default: 100 kHz */
+static int clock = 400; /* Default: 100 kHz */
 module_param(clock, int, 0);
 MODULE_PARM_DESC(clock, "Set I2C clock in kHz: 400=fast mode (default == 100)");
 
diff -purN linux-omap/drivers/i2c/busses/i2c-omap_hs.c lin_for_twl/drivers/i2c/busses/i2c-omap_hs.c
--- linux-omap/drivers/i2c/busses/i2c-omap_hs.c	1969-12-31 18:00:00.000000000 -0600
+++ lin_for_twl/drivers/i2c/busses/i2c-omap_hs.c	2007-02-27 17:48:50.000000000 -0600
@@ -0,0 +1,1487 @@
+/*
+ * linux/drivers/i2c/busses/i2c-omap243x.c
+ *
+ * Unified algorithm/adapter I2C driver for OMAP243x I2C controller.
+ *
+ * Author: Andy Lowe (source@mvista.com)
+ *
+ * Copyright (C) 2004 MontaVista Software, Inc.
+ * Copyright (C) 2005-2006 Texas Instruments.
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ *
+ * History:
+ * -------
+ * Aug 2005 - Copied from drivers/i2c/i2c-omap24xx.c and ported to 
+ *            243X and added support for HSI2C - Texas Instruments 
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/clk.h>
+
+#ifdef CONFIG_PM
+#include <linux/notifier.h>
+#include <linux/device.h>
+#include <asm/arch/bus.h>
+#endif
+#ifdef CONFIG_DPM
+#include <asm/arch/dpm.h>	/* to specify constraints */
+#endif
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/arch/mux.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/hardware.h>
+
+#include "i2c-omap_hs.h"
+
+#define INT_I2C1_IRQ	56
+#define INT_I2C2_IRQ	57
+
+int enable_i2c_clock(int i2c_module, int clocksrc);
+void disable_i2c_clock(int i2c_module);
+
+#ifdef CONFIG_PM
+static int dpm_state[2];
+static int prcm_i2c[2] = {PRCM_I2C1, PRCM_I2C2};
+#endif
+
+/* ----- configuration macros ----------------------------------------- */
+
+#define NUM_I2C_ADAP 2		/* number of I2C adapters */
+
+#define I2C_NAME "i2c-omap243x"
+
+/* The default timeout is for the time allowed for each word (2 bytes) of
+ * an I2C transfer to complete.  This value is converted to ticks and
+ * used to initialize the timeout member of the i2c_adapter struct.
+ * For each byte in the trsh, wait for 100Khz (STD speed)
+ */
+#define I2C_DEFAULT_TIMEOUT_MS	  40
+#define I2C_DEFAULT_RETRIES       2
+
+/* The reset timeout is the time allowed for a reset of the I2C controller
+ * to complete.
+ */
+#define I2C_RESET_TIMEOUT_MS 100
+
+/* The bus busy timeout is the maximum time we will wait for the bus to
+ * become idle before initiating a transfer.
+ */
+#define I2C_BUS_BUSY_TIMEOUT_MS 200
+
+/* This driver doesn't support I2C slave mode, so we set our own address
+ * to zero to make sure it won't conflict with any slave devices on the
+ * bus.
+ */
+#define I2C_OWN_ADDRESS 0
+
+/* MCODE For HS transfers */
+#define I2C_MCODE  0
+
+#define CONTROL_PBIAS_LITE_1  IO_ADDRESS(OMAP24XX_CTRL_BASE+0x4A0)
+#define PULL_HS_BUS0          (0x1<<3)
+#define PULL_HS_BUS1          (0x1<<4)
+#ifdef CONFIG_I2C_OMAP243X_SECONDARY_PULL0
+#    ifdef CONFIG_I2C_OMAP243X_SECONDARY_PULL1 
+#        define I2C_SECONDARY_PULL    (PULL_HS_BUS0|PULL_HS_BUS1)
+#    else
+#        define I2C_SECONDARY_PULL    (PULL_HS_BUS0)
+#    endif
+#elif defined (CONFIG_I2C_OMAP243X_SECONDARY_PULL1)
+#    define I2C_SECONDARY_PULL    (PULL_HS_BUS1)
+#endif
+/* ----- debug defines ----------------------------------------------- */
+/* Debug - four macros:
+ * FN_IN, FN_OUT(value),D1,D2,D3 enabled based on log level
+ */
+
+/* Log level standard used here:
+ * Log level 3 all messages
+ * Log level 2 all entry-exit points
+ * Log level 1 major messages
+ * Log level 0 no messages
+ */
+#define I2C_LOG_LEVEL 0
+/* detail - 0 - no detail
+ *          1 - function name
+ *          2 - function name, line number
+ * prefix is added to every log message
+ */
+#define I2C_DETAIL    2
+
+/* kernel log level*/
+/* #define I2C_K_LOG_LEVEL KERN_DEBUG */
+#define I2C_K_LOG_LEVEL
+
+#if ( I2C_DETAIL > 0 )
+#define DL1 "%s "
+#define DR1 ,__FUNCTION__
+#else
+#define DL1
+#define DR1
+#endif
+#if ( I2C_DETAIL > 1 )
+#define DL2 "[%d] "
+#define DR2 ,__LINE__
+#else
+#define DL2
+#define DR2
+#endif
+
+/* Wanted to reduce printks... at the same time ease development too..
+ * cant do with the format,args version.. does not work with null args :(
+ */
+#define D(format,...)\
+	printk(DL1 DL2 format "\n" DR1 DR2, ## __VA_ARGS__)
+
+#if (I2C_LOG_LEVEL >= 1)
+#define D1(ARGS...) D(ARGS)
+#else
+#define D1(ARGS...)
+#endif
+#if (I2C_LOG_LEVEL >= 2)
+#define D2(ARGS...) D(ARGS)
+#else
+#define D2(ARGS...)
+#endif
+#if (I2C_LOG_LEVEL >= 3)
+#define D3(ARGS...) D(ARGS)
+#else
+#define D3(ARGS...)
+#endif
+
+#if (I2C_LOG_LEVEL >= 2)
+#define FN_IN D("%s Entry",__FUNCTION__);
+#define FN_OUT(ARG) D("%s[%d]:Exit(%d)",__FUNCTION__,__LINE__,ARG);
+#else
+#define FN_IN
+#define FN_OUT(ARG)
+#endif
+
+/* ----- module data structures ---------------------------------------	*/
+
+struct omap24xx_i2c_adapter {
+	struct i2c_adapter adap;
+
+	/* for a given i2c-clock-sclk combination now, only one possible set is possible */
+	unsigned int psc;
+	unsigned int scl_lh;
+
+	unsigned long s_clock;	/* needed for power management */
+#if (I2C_LOG_LEVEL >= 1)
+	unsigned long mmio_base_phys;	/* Just for debug messages */
+#endif
+	unsigned long mmio_base;
+
+	int irq;
+	unsigned short oa;	/* own address */
+	unsigned char mcode;	/* master code */
+	int a_num;	
+	u16 tx_fifo_size;	/* The fifo size of the tx device */
+	u16 rx_fifo_size;	/* The fifo size of the rx device */
+
+	wait_queue_head_t i2c_wait_queue;
+};
+
+static struct omap24xx_i2c_adapter *saved_oadap[NUM_I2C_ADAP];
+
+#ifdef CONFIG_PM
+/* No scaling when we dont do DMA yet */
+#undef I2C_DPM_SCALE
+#ifdef I2C_DPM_SCALE
+static int omap24xx_i2c_scale(struct notifier_block *op, unsigned long level, void * newop);
+static struct notifier_block omap24xxi2c_pre_scale = {
+	         .notifier_call = omap24xx_i2c_scale,
+};
+static struct notifier_block omap24xxi2c_post_scale = {
+	         .notifier_call = omap24xx_i2c_scale,
+};
+#endif
+struct omap24xxi2c_suspend_data {
+	/* Power management suspend lockout stuff */
+	int suspended;
+	wait_queue_head_t suspend_wq;
+};
+static struct omap24xxi2c_suspend_data i2c_suspend_data[NUM_I2C_ADAP];
+/* if suspended, simply return an error */
+#define omap24xx_i2c_suspend_lockout(s,a) \
+	if (((s[a]))->suspended) {\
+		return -EBUSY;\
+	}
+#define omap24xx_i2c_suspend_lockout_queue(s,a) \
+	if (((s[a]))->suspended) {\
+		wait_event((s[a])->suspend_wq,\
+					 (((s[a]))->suspended == 0));\
+	}
+#else
+#define omap24xx_i2c_suspend_lockout(s,a) do {} while(0)
+#define omap24xx_i2c_suspend_lockout_queue(s,a) do {} while(0)
+#endif
+
+/* ----- module params  ---------------------------------------	*/
+
+/* bus 0 clock */
+static int i2c_clock0 = OMAP_I2C_STANDARD;
+static int i2c_clock1 = 2600;
+
+/* ----- Utility functions --------------------------------------------	*/
+
+/*
+ * I2C register I/O routines
+ */
+
+
+/* 16 bit read and writes */
+static __inline__ u16
+omap242x_i2c_readw(const struct omap24xx_i2c_adapter *oadap, u32 offset)
+{
+	unsigned short readv = readw(oadap->mmio_base + offset);
+	D1("R[0x%x]=0x%x\n", (u32) oadap->mmio_base_phys + offset, (u32) readv);
+	return readv;
+}
+
+static __inline__ u16
+omap242x_i2c_writew(const struct omap24xx_i2c_adapter *oadap, u32 offset,
+		    u16 val)
+{
+	writew(val, oadap->mmio_base + offset);
+	D1("W[0x%x]<=0x%x\n", (u32) oadap->mmio_base_phys + offset, (u32) val);
+	return val;
+}
+
+/* 8 bit read and writes */
+static __inline__ u8
+omap242x_i2c_readb(const struct omap24xx_i2c_adapter *oadap, u32 offset)
+{
+	unsigned char readv = readb(oadap->mmio_base + offset);
+	D1("bR[0x%x]=0x%x\n", (u32) (oadap->mmio_base_phys + offset),
+	   (u32) readv);
+	return readv;
+}
+
+static __inline__ u8
+omap242x_i2c_writeb(const struct omap24xx_i2c_adapter *oadap, u32 offset,
+		    u8 val)
+{
+	writeb(val, oadap->mmio_base + offset);
+	D1("bW[0x%x]<=0x%x\n", (u32) oadap->mmio_base_phys + offset, (u32) val);
+	return val;
+}
+
+/** 
+ * @brief i2c_hw_init
+ * Initialize the I2C controller.
+ *
+ * @param oadap 
+ * 
+ * @return intialization status  Returns zero if successful,
+ * non-zero otherwise.
+ */
+static int i2c_hw_init(struct omap24xx_i2c_adapter *oadap)
+{
+	unsigned long timeout;
+	FN_IN;
+
+	/* disable the I2C controller */
+	omap242x_i2c_writew(oadap, I2C_CON, 0);
+
+	/* wait for reset to complete */
+	timeout = jiffies + ((I2C_RESET_TIMEOUT_MS) * HZ) / 1000;
+
+	/* reset the I2C controller */
+	omap242x_i2c_writew(oadap, I2C_SYSC, I2C_SYSC_SRST);
+	/* enable the block to allow reset complete */
+	omap242x_i2c_writew(oadap, I2C_CON, I2C_CON_I2C_EN);
+
+	/* 
+	 * Wait for reset to happen -bit will get set by the h/w once 
+	 * reset is completed 
+	 */
+	while ( 0 == ((omap242x_i2c_readw(oadap, I2C_SYSS) & I2C_SYSS_RDONE))
+	       && time_before(jiffies, timeout)) {
+		if (!in_interrupt()) {
+			if (!signal_pending(current))
+				set_current_state(TASK_INTERRUPTIBLE);
+			else
+				set_current_state(TASK_UNINTERRUPTIBLE);
+			schedule_timeout(1);
+		} else
+			udelay(100);
+	}
+	/* if the i2c controller does not report reset completed... */
+	if (0 == ((omap242x_i2c_readw(oadap, I2C_SYSS) & I2C_SYSS_RDONE))) {
+
+		printk
+		    (KERN_ERR "I2C[%d]:Timeout waiting for I2C controller to reset[%d] %d\n",
+		     oadap->a_num,(u32) I2C_RESET_TIMEOUT_MS, (u32) timeout);
+		FN_OUT(ETIMEDOUT);
+		return -ETIMEDOUT;
+	}
+	/* initialize pre-computed prescalar values */
+	omap242x_i2c_writew(oadap, I2C_PSC, oadap->psc);
+
+	/* program tlow and thigh with equal levels */
+	omap242x_i2c_writew(oadap, I2C_SCLL, oadap->scl_lh);	/* tlow */
+	omap242x_i2c_writew(oadap, I2C_SCLH, oadap->scl_lh);	/* thigh */
+	/* set our own slave address */
+	omap242x_i2c_writew(oadap, I2C_OA,
+			    (((oadap->mcode & I2C_OA_MCODE_M) << I2C_OA_MCODE) |
+			     ((oadap->oa & I2C_OA_OA0_M) << I2C_OA_OA0)));
+
+	/* enable the I2C controller */
+	omap242x_i2c_writew(oadap, I2C_CON, I2C_CON_I2C_EN);
+
+	/* wait for reset to complete */
+	timeout = jiffies + ((I2C_RESET_TIMEOUT_MS) * HZ) / 1000;
+	/* Wait for the Functional module to be enabled. */
+	while (!(omap242x_i2c_readw(oadap, I2C_SYSS) & I2C_SYSS_RDONE)
+	       && time_before(jiffies, timeout)) {
+		if (!in_interrupt()) {
+			if (!signal_pending(current))
+				set_current_state(TASK_INTERRUPTIBLE);
+			else
+				set_current_state(TASK_UNINTERRUPTIBLE);
+			schedule_timeout(1);
+		} else
+			udelay(100);
+	}
+	if (!(omap242x_i2c_readw(oadap, I2C_SYSS) & I2C_SYSS_RDONE)) {
+		D1("timeout waiting for I2C controller to reset[%d]",
+		   I2C_RESET_TIMEOUT_MS);
+		FN_OUT(ETIMEDOUT);
+		return -ETIMEDOUT;
+	}
+	FN_OUT(0);
+	return 0;
+}
+
+/** 
+ * @brief i2c_hw_release
+ * Disable the i2c controller
+ *
+ * @param oadap 
+ */
+static void i2c_hw_release(struct omap24xx_i2c_adapter *oadap)
+{
+	FN_IN;
+	/* disable the I2C controller */
+	omap242x_i2c_writew(oadap, I2C_CON, 0);
+	FN_OUT(0);
+}
+
+/** 
+ * @brief i2c_wait_while_bb
+ * The I2C bus protocol supports multiple masters.  This driver only supports
+ * using the OMAP I2C bus controller as a master, but we want to try to
+ * accommodate situations where there are other I2C masters sharing the bus.
+ * In order to allow for other bus masters, we have to check if the bus is
+ * busy before initiating a transfer.    
+ *
+ * @param oadap 
+ * 
+ * @return This functions returns 0 if the bus is idle, or 
+ * -ETIMEDOUT if a timeout occurs before the bus becomes idle.
+ */
+static int i2c_wait_while_bb(const struct omap24xx_i2c_adapter *oadap)
+{
+	unsigned long timeout = jiffies + (I2C_BUS_BUSY_TIMEOUT_MS * HZ) / 1000;
+	FN_IN;
+
+	while ((omap242x_i2c_readw(oadap, I2C_STAT) & I2C_STAT_BB)
+	       && time_before(jiffies, timeout)) {
+		if (!in_interrupt()) {
+			if (!signal_pending(current))
+				set_current_state(TASK_INTERRUPTIBLE);
+			else
+				set_current_state(TASK_UNINTERRUPTIBLE);
+			schedule_timeout(1);
+		} else
+			udelay(100);
+	}
+	if (omap242x_i2c_readw(oadap, I2C_STAT) & I2C_STAT_BB) {
+		D1("timeout waiting for bus to be idle [%d]", (int)timeout);
+		FN_OUT(ETIMEDOUT);
+		return -ETIMEDOUT;
+	}
+
+	FN_OUT(0);
+	return 0;
+}
+
+/** 
+ * @brief i2c_wait_for_status
+ * Wait for status register update.  
+ * 
+ * @param oadap 
+ * @param poll - do polled wait for status!! max delay 1ms
+ * 
+ * @return  Returns a negative error code or the value of the status 
+ * register.
+ */
+static int i2c_wait_for_status(struct omap24xx_i2c_adapter *oadap, u8 poll,
+			       u32 timeout, int flags)
+{
+	wait_queue_t i2c_wait;
+	u16 status;
+	const u16 ie_mask = I2C_IE_XRDY_IE | I2C_IE_RRDY_IE
+	    | I2C_IE_ARDY_IE | I2C_IE_NACK_IE | I2C_IE_AL_IE | I2C_IE_XDR_IE;
+	const u16 stat_mask = I2C_STAT_XRDY | I2C_STAT_RRDY
+	    | I2C_STAT_ARDY | I2C_STAT_NACK | I2C_STAT_AL | I2C_STAT_XUDF |
+	    I2C_STAT_ROVR | I2C_STAT_XDR | I2C_STAT_RDR;
+	FN_IN;
+
+	status = omap242x_i2c_readw(oadap, I2C_STAT);
+	if ((( flags & I2C_M_PRI) | poll ) && !(status & stat_mask)) {
+		/*  polled mode */
+		typeof(jiffies) new_timeout = jiffies + timeout;
+		while (!(status & stat_mask)
+		       && time_before(jiffies, new_timeout)) {
+			/* Loop as long as we dont timeout-Die CPU Die ;) */
+			status = omap242x_i2c_readw(oadap, I2C_STAT);
+		}
+		if (!(status & stat_mask)) {
+			D1
+			    ("Poll Timedout %s[0x%x] timout=%d\n",
+			     __FUNCTION__, status, (u32) new_timeout);
+			return -ETIMEDOUT;
+		}
+
+	} else if (!(status & stat_mask)) {
+		
+		/* interrupt mode */
+		
+		init_waitqueue_entry(&i2c_wait, current);
+		add_wait_queue(&oadap->i2c_wait_queue, &i2c_wait);
+		
+    
+		/* enable I2C interrupts */
+		omap242x_i2c_writew(oadap, I2C_IE, ie_mask);
+
+		status = omap242x_i2c_readw(oadap, I2C_STAT);
+		if (!(status & stat_mask)) {
+			if (!in_interrupt()){
+				/* no pend signals - wait interruptible/else,
+			 	* wait the required timedelay
+			 	*/
+				if (!signal_pending(current))
+					set_current_state(TASK_INTERRUPTIBLE);
+				else
+					set_current_state(TASK_UNINTERRUPTIBLE);
+				schedule_timeout(timeout);
+				/* guarenteed to be in running state on exit */
+			}
+			else
+				udelay(100);
+		}             
+		remove_wait_queue(&oadap->i2c_wait_queue, &i2c_wait);
+        
+		status = omap242x_i2c_readw(oadap, I2C_STAT);
+		if (!(status & stat_mask)) {
+			/* still no status update */
+			if (signal_pending(current)) {
+				D1("RestartSYS %s\n", __FUNCTION__);
+				FN_OUT(ERESTARTSYS);
+				return -ERESTARTSYS;
+			} else {
+				D1("Timedout %s[0x%x]\n", __FUNCTION__,
+				       status);
+				FN_OUT(ETIMEDOUT);
+				return -ETIMEDOUT;
+			}
+		}
+	}
+
+	FN_OUT(status);
+	return status;
+}
+
+/** 
+ * @brief omap24xx_i2c_handler
+ * 
+ * @param this_irq 
+ * @param dev_id 
+ * @param regs 
+ */
+static irqreturn_t
+omap24xx_i2c_handler(int this_irq, void *dev_id)
+{
+	struct omap24xx_i2c_adapter *oadap =
+	    (struct omap24xx_i2c_adapter *)dev_id;
+
+	FN_IN;
+	/* disable I2C interrupts */
+	omap242x_i2c_writew(oadap, I2C_IE, 0);
+	wake_up_interruptible(&oadap->i2c_wait_queue);
+	return IRQ_HANDLED;
+}
+
+/** 
+ * @brief omap24xx_i2c_xfer_msg
+ * Read or write a single message.  Returns the number of bytes
+ * successfully read or written.  A start (or restart) condition is always
+ * generated first, followed by msg->len data bytes.  A stop condition is
+ * generated if the stop parameter is non-zero.  Otherwise, the bus is left
+ * busy (clock line pulled low) so that the next transfer can begin with a
+ * restart.
+ * 
+ * @param oadap 
+ * @param msg 
+ * @param stop 
+ * 
+ * @return 0 if successful, else the error condition
+ */
+static int
+omap24xx_i2c_xfer_msg(struct omap24xx_i2c_adapter *oadap,
+		      struct i2c_msg *msg, int stop)
+{
+	struct i2c_adapter *adap = &oadap->adap;
+	u16 data;
+	int status;
+	int retries, stt_reset, stt_status;
+	int count;
+	int ret = 0;
+	u16 fifo_sel = 0;
+	typeof(jiffies) timeout;
+	
+	unsigned int control = (I2C_CON_I2C_EN | I2C_CON_MST | I2C_CON_STT |
+				((msg->flags & I2C_M_TEN) ? I2C_CON_XSA : 0) |
+				((msg->flags & I2C_M_RD) ? 0 : I2C_CON_TRX)); 
+
+	FN_IN;
+
+	D1("%s %d\n", (msg->flags & I2C_M_RD) ? "Rd" : "Wr", msg->len);
+	/* The OMAP controller can't generate a message with zero data bytes, so
+	 * return without doing anything in that case.
+	 */
+	if (!msg->len) {
+		D3("Skipping message with zero-length payload at addr"
+		   " 0x%04x.", msg->addr);
+		FN_OUT(0);
+		return 0;
+	}
+
+	omap24xx_i2c_suspend_lockout_queue(&i2c_suspend_data, oadap->a_num);
+
+	/* Do we do HS transfer or not... simple logic for now 
+	 * We need to extend this logic for DMA usage too
+	 * Combine it with overhead of doing HS Transfers
+	 */
+	if (unlikely
+	    ((msg->flags & I2C_M_HS) && !(adap->flags & I2C_FUNC_HIGH_SPEED))) {
+		printk(KERN_WARNING
+		       "Attempt of HS TX ON FS DEVICE-Auto switching to FS transfer!\n");
+		msg->flags &= ~I2C_M_HS;
+	}
+	if (unlikely
+	    (!(msg->flags & I2C_M_HS) && (adap->flags & I2C_FUNC_HIGH_SPEED))) {
+		D1(KERN_INFO "Unoptimal FS attempt on HS Bus!\n");
+	}
+	control |= ((((msg->flags & I2C_M_HS) ? I2C_CON_OP_MODE_HS :
+		      I2C_CON_OP_MODE_FS) & I2C_CON_OP_MODE_M) <<
+		    I2C_CON_OP_MODE);
+
+	/* Choose the proper Fifo Size */
+	fifo_sel =
+	    ((msg->flags & I2C_M_RD) ? oadap->rx_fifo_size : oadap->
+	     tx_fifo_size);
+
+	D1("timeout=%d, fifo_size=%d,len=%d\n", 
+	   (u32) adap->timeout, fifo_sel, msg->len);
+
+	D3("addr: 0x%04x, len: %d, flags: 0x%x, stop: %d control=0x%x",
+	   msg->addr, msg->len, msg->flags, stop, control);
+
+	for (retries = 0; retries <= adap->retries; retries++) {
+		/* Disable the i2c controller */
+		omap242x_i2c_writew(oadap, I2C_CON, 0);
+		/* Disable DMA, enable RX FIFO CLR, TX FIFO CLR - set the threshholds 
+		 * we do it here to flush the FIFOs
+		 */
+		omap242x_i2c_writew(oadap, I2C_BUF,
+				    ((oadap->
+				      rx_fifo_size & I2C_BUF_RXTRSH_M) <<
+				     I2C_BUF_RXTRSH) | ((oadap->
+							 tx_fifo_size &
+							 I2C_BUF_TXTRSH_M) <<
+							I2C_BUF_TXTRSH) |
+				    I2C_BUF_TXFIFO_CL | I2C_BUF_RXFIFO_CL);
+		status = omap242x_i2c_readw(oadap, I2C_STAT);
+		/* clean out all old status */
+		omap242x_i2c_writew(oadap, I2C_STAT, status);
+		omap242x_i2c_writew(oadap, I2C_SA, msg->addr);
+		omap242x_i2c_writew(oadap, I2C_CNT, msg->len);
+      		omap242x_i2c_writew(oadap, I2C_CON, control);
+		/* Work around for HS I2C bug not allowing to set STT
+		   and STP bit at the same time */
+		stt_reset=0;
+		if(stop) {
+			timeout = jiffies + msecs_to_jiffies(60);
+			while (time_before(jiffies, timeout)) {
+				stt_status = omap242x_i2c_readw(oadap, I2C_CON);
+				if(!(stt_status & I2C_CON_STT )){
+					stt_reset=1;
+					control = ((control & ~(I2C_CON_STT)) | I2C_CON_STP);
+       		     			omap242x_i2c_writew(oadap, I2C_CON, control);
+		     			break;
+				}
+		  	}
+			if(!stt_reset){
+				D1("I2C transfer error: STT bit not reset %x", stt_status);
+				ret = -1;
+				goto xfer_exit;
+			}
+		}
+		count = 0;
+		while (count <= msg->len) {
+			status =
+			    i2c_wait_for_status(oadap, (0 == count), adap->timeout, msg->flags);
+			if (status < 0) {
+				D1("I2C transfer aborted with error %d",
+				   status);
+				ret = status;
+				goto xfer_exit;
+			}
+
+			if (status & I2C_STAT_AL) {
+				D1("Arbitration lost, retrying transfer"
+				   "count=%d[%x]\n", count, status);
+				/* We lost control of the bus to another
+				 * bus master.  Try this transfer again if we get bus back.
+				 */
+				omap242x_i2c_writew(oadap, I2C_STAT, status);
+				if (i2c_wait_while_bb(oadap)) {
+					D1 ("Unable to get the bus back[0x%x]!!\n",
+					     omap242x_i2c_readw(oadap,
+								I2C_STAT));
+					ret = -EREMOTEIO;
+					goto xfer_exit;
+				}
+
+				break;
+			}
+			if (status & I2C_STAT_NACK) {
+				omap242x_i2c_writew(oadap, I2C_STAT,
+						    I2C_STAT_NACK);
+				D1("I2C xfer aborted by NAK");
+				ret = -EREMOTEIO;
+				goto xfer_exit;
+			}
+			D1("count=%d,status=0x%x\n", count, status);
+			if (status & I2C_STAT_ARDY) {
+				omap242x_i2c_writew(oadap, I2C_STAT,
+						    I2C_STAT_ARDY);
+				if (count == msg->len) {
+					/* successful completion of transfer */
+					D3("I2C xfer complete");
+					ret = count;
+					goto xfer_exit;
+				} else {
+					D1 ("I2C transfer ended prematurely[0x%x]\n",
+					     status);
+					ret = -EREMOTEIO;
+					goto xfer_exit;
+				}
+				status &= ~I2C_STAT_ARDY;
+			}
+			if (status & (I2C_STAT_XUDF)) {
+				/* we will be handling it in this loop itself */
+				if (status & (I2C_STAT_XDR | I2C_STAT_XRDY)) {
+					D1("UNDF[%d]\n", count);
+					status &= ~I2C_STAT_XUDF;
+				}
+				omap242x_i2c_writew(oadap,
+						    I2C_STAT, I2C_STAT_XUDF);
+				/* Errata: Try the entire transfer again!! */
+				ret = -EAGAIN;
+				goto xfer_exit;
+
+			}
+			if (status & (I2C_STAT_XRDY | I2C_STAT_XDR)) {
+				u16 num_bytes = 0;
+				u16 clr_status = 0;
+				/* Read the num bytes to copy from buf-stat reg */
+				if (status & I2C_STAT_XRDY) {
+					num_bytes = fifo_sel + 1;
+					clr_status = I2C_STAT_XRDY;
+				} else {	/* XDR */
+					u16 reg = omap242x_i2c_readw(oadap,
+								     I2C_BUFSTAT);
+					num_bytes =
+					    (reg >>
+					     I2C_BUFSTAT_TXLEVEL) &
+					    I2C_BUFSTAT_TXLEVEL_M;
+					D1("++[%x,%d]>", reg, num_bytes);
+					clr_status = I2C_STAT_XDR;
+				}
+
+				D1("***I2C ->XDR %d thrsh %d count %d"
+				   " len %d xrdy = 0x%x xdr 0x%x\n", num_bytes,
+				   fifo_sel + 1, count,
+				   msg->len, status & I2C_STAT_XRDY,
+				   status & I2C_STAT_XDR);
+				if (msg->flags & I2C_M_RD) {
+					D1
+					    ("Unexpected Tx interrupt during I2C Read");
+					ret = -EREMOTEIO;
+					goto xfer_exit;
+				}
+				while (num_bytes) {
+					/* Copy as much as required */
+					if (count < msg->len) {
+						data = msg->buf[count++];
+						omap242x_i2c_writeb(oadap,
+								    I2C_DATA,
+								    (u8) (data &
+									  0xFF));
+						D3("I2C data word tx");
+					} else
+						break;
+					num_bytes--;
+				}
+				omap242x_i2c_writew(oadap,
+						    I2C_STAT, clr_status);
+				status &= ~(I2C_STAT_XDR | I2C_STAT_XRDY);
+			}
+			if (status & (I2C_STAT_ROVR)) {
+				/* we will be handling it in this loop itself */
+				if (status & (I2C_STAT_RDR | I2C_STAT_RRDY)) {
+					status &= ~I2C_STAT_ROVR;
+				}
+				D1("ROVR[%d]\n", count);
+				omap242x_i2c_writew(oadap,
+						    I2C_STAT, I2C_STAT_ROVR);
+			}
+			if (status & (I2C_STAT_RDR | I2C_STAT_RRDY)) {
+				/* Read the num bytes to copy from buf-stat reg */
+				u16 num_bytes = 0;
+				u16 clr_status = 0;
+
+				if (status & I2C_STAT_RRDY) {
+					num_bytes = fifo_sel + 1;
+					clr_status = I2C_STAT_RRDY;
+				} else {	/* RDR */
+					clr_status = I2C_STAT_RDR;
+					num_bytes =
+					    (omap242x_i2c_readw
+					     (oadap,
+					      I2C_BUFSTAT) >>
+					     I2C_BUFSTAT_RXLEVEL) &
+					    I2C_BUFSTAT_RXLEVEL_M;
+				}
+				D1("***I2C ->RDR %d thrsh %d count %d len %d"
+				   " stat-rrdy 0x%x rdr 0x%x\n", num_bytes,
+				   fifo_sel, count,
+				   msg->len, status & I2C_STAT_RRDY,
+				   status & I2C_STAT_RDR);
+				if (!(msg->flags & I2C_M_RD)) {
+					D1("Unexpected Rx interrupt during I2C Write");
+					ret = -EREMOTEIO;
+					goto xfer_exit;
+				}
+				while (num_bytes) {
+					if (count < msg->len) {
+						data =
+						    omap242x_i2c_readb(oadap,
+								       I2C_DATA);
+						msg->buf[count++] = (u8) data;
+					} else {
+						/* we might get transient rrdy/rdr */
+						break;
+					}
+					num_bytes--;
+				}
+				omap242x_i2c_writew(oadap,
+						    I2C_STAT, clr_status);
+				status &= ~(I2C_STAT_RDR | I2C_STAT_RRDY);
+			}
+		}
+	}
+	D1("Retry limit reached--I2C xfer aborted");
+	ret = -EREMOTEIO;
+      xfer_exit:
+	if (ret < 0) {
+		/* Disable the controller */
+		omap242x_i2c_writew(oadap, I2C_CON, 0);
+	}
+	FN_OUT(ret);
+	return ret;
+}
+
+/** 
+ * @brief omap24xx_i2c_xfer
+ * Read or write to an I2C device. 
+ *
+ * @param adap 
+ * @param msgs 
+ * @param num 
+ * 
+ * @return Returns num if all messages are transferred successfully, or a 
+ * negative error code otherwise.  
+ */
+static int omap24xx_i2c_xfer(struct
+			     i2c_adapter
+			     *adap, struct i2c_msg msgs[], int num)
+{
+	struct omap24xx_i2c_adapter
+	*oadap = (struct omap24xx_i2c_adapter *)
+	    adap->algo_data;
+	int retries = 0;
+	struct i2c_msg *pmsg;
+	int i, ret;
+	FN_IN;
+	omap24xx_i2c_suspend_lockout_queue(&i2c_suspend_data, oadap->a_num);
+	if (i2c_wait_while_bb(oadap)) {
+		/* The bus is still busy.  We're going to reset our I2C bus
+		 * controller and then go ahead with our transfer regardless.
+		 */
+		D3("Resetting I2C controller.");
+		i2c_hw_init(oadap);
+	}
+
+	for (i = 0; i < num; i++) {
+		pmsg = &msgs[i];
+		ret = omap24xx_i2c_xfer_msg(oadap, pmsg, (i == (num - 1)));
+		/* If retry required */
+		if (ret == -EAGAIN) {
+			retries++;
+			if (retries >= adap->retries) {
+				return -EREMOTEIO;
+			}
+			i2c_hw_init(oadap);
+			i=0;
+			continue;
+		}
+		if (ret < pmsg->len) {
+			D1("I2C transfer failed.  Resetting I2C controller.-[0x%x]\n", -ret);
+			i2c_hw_init(oadap);
+			FN_OUT((ret < 0) ? ret : -EREMOTEIO);
+			return (ret < 0) ? ret : -EREMOTEIO;
+		}
+	}
+	FN_OUT(num);
+	return num;
+}
+
+/** 
+ * @brief omap24xx_i2c_func
+ *  return the functional capability of the adaptor
+ * @param adap 
+ * 
+ * @return Functional capability in the form of the adap flags
+ */
+static u32 omap24xx_i2c_func(struct
+			     i2c_adapter
+			     *adap)
+{
+	FN_IN;
+	FN_OUT(adap->flags);
+	return (adap->flags);
+}
+
+#ifdef CONFIG_PM
+#ifdef I2C_DPM_SCALE
+/** 
+ * @brief omap24xx_i2c_scale
+ * nothing to do in scale() now--placeholder only - need to look once DMA enabled 
+ * 
+ * @param op 
+ * @param level 
+ * 
+ * @return  0
+ */
+static int omap24xx_i2c_scale(struct notifier_block *op, unsigned long level, void * newop)
+{
+	FN_IN;
+	switch (level) {
+	case SCALE_PRECHANGE:
+		break;
+	case SCALE_POSTCHANGE:
+		break;
+	}
+	FN_OUT(0);
+	return 0;
+}
+#endif
+ /** 
+ * @brief omap24xx_i2c_suspend
+ * Disable the i2c controller and shut down the clocks
+ * Currently using the inbuilt LDM. Need to move to CONFIG_DPM style
+ * 
+ * @param odev 
+ * @param state 
+ * @param level 
+ * 
+ * @return 0
+ */
+static int omap24xx_i2c_suspend(struct
+				omap_dev
+				*odev, u32 state)
+{
+	struct omap24xx_i2c_adapter
+	*oadap = omap_get_drvdata(odev);
+	dpm_state[oadap->a_num] = state;
+	FN_IN;
+
+	switch (state) {
+		case 0:
+			break;
+		case 1:		
+		case 2:
+			prcm_autoidle_ctrl(prcm_i2c[oadap->a_num], ENABLE);
+			break;
+		case 3:
+			D3("suspend%d\n", oadap->a_num);
+			i2c_wait_while_bb(oadap);
+			i2c_suspend_data[oadap->a_num].suspended = 1;
+			/* disable the I2C controller */
+			omap242x_i2c_writew(oadap, I2C_CON, 0);
+			/* Down the clocks */
+			disable_i2c_clock(oadap->a_num);
+			break;
+		default:
+			break;
+	}
+	FN_OUT(0);
+	return 0;
+}
+
+/** 
+ * @brief omap24xx_i2c_resume
+ * 
+ * @param odev 
+ * @param level 
+ * 
+ * @return 0
+ */
+static int omap24xx_i2c_resume(struct
+			       omap_dev
+			       *odev)
+{
+	struct omap24xx_i2c_adapter
+	*oadap = omap_get_drvdata(odev);
+	FN_IN;
+
+	switch (dpm_state[oadap->a_num]) {
+		case 0:
+			break;
+		case 1:		
+		case 2:	
+			prcm_autoidle_ctrl(prcm_i2c[oadap->a_num], DISABLE);
+			break;
+		case 3:
+			enable_i2c_clock(oadap->a_num, oadap->s_clock);
+			i2c_hw_init(oadap);
+			i2c_suspend_data[oadap->a_num].suspended = 0;
+			wake_up(&i2c_suspend_data[oadap->a_num].suspend_wq);
+			D3("resume%d\n", oadap->a_num);
+			break;
+		default:
+			break;
+	}
+	return 0;
+}
+
+/** 
+ * @brief omap24xx_i2c_probe
+ * Dummy entry point.. nothing to do
+ * @param odev 
+ * 
+ * @return 
+ */
+static int omap24xx_i2c_probe(struct
+			      omap_dev
+			      *odev)
+{
+	FN_OUT(0);
+	return 0;
+}
+
+static struct omap_driver i2c_driver_ldm = {
+	.drv = {
+		.name = "i2c-adap-omap24xx",
+		},
+
+	.devid = OMAP24xx_I2C_DEVID,
+	.busid = OMAP_BUS_L4,
+	.clocks = 0,
+	.probe = omap24xx_i2c_probe,
+	.suspend = omap24xx_i2c_suspend,
+	.resume = omap24xx_i2c_resume,
+};
+
+#ifdef CONFIG_DPM
+static struct constraints i2c_omap_constraints1 = {
+	.count = 2,
+	.param = {
+		  {DPM_MD_V, 1050, 1300},
+		  {DPM_MD_PWRST_CORE, 1, 1},	/* 1 = PRCM_ON */
+		  },
+};
+
+static struct constraints i2c_omap_constraints2 = {
+	.count = 2,
+	.param = {
+		  {DPM_MD_V, 1050, 1300},
+		  {DPM_MD_PWRST_CORE, 1, 1},	/* 1 = PRCM_ON */
+		  },
+};
+#endif
+
+
+/* require Dummy release */
+static void dummy_release (struct device * dev)
+{
+	/* nothing to do */
+}
+
+static struct omap_dev i2c_device_ldm[NUM_I2C_ADAP] = {
+	{
+	 .name = "OMAP24xx I2C 0",
+	 .devid = OMAP24xx_I2C_DEVID,
+	 .busid = OMAP_BUS_L4,	/* based on L4 Core */
+	 .dev = {
+		 .release = dummy_release,
+#ifdef CONFIG_DPM
+		 .constraints = &i2c_omap_constraints1,
+#endif
+		 },
+	 }, {
+	     .name = "OMAP24xx I2C 1",
+	     .devid = OMAP24xx_I2C_DEVID,
+	     .busid = OMAP_BUS_L4,	/* based on L4 Core */
+	     .dev = {
+		     .release = dummy_release,
+#ifdef CONFIG_DPM
+		     .constraints = &i2c_omap_constraints2,
+#endif
+		     },
+	     },
+};
+
+#endif				/* DPM */
+
+/* -----exported algorithm data: -------------------------------------	*/
+
+static struct i2c_algorithm omap24xx_i2c_algo = {
+	.master_xfer = omap24xx_i2c_xfer,
+	.functionality = omap24xx_i2c_func,
+};
+
+/** 
+ * @brief omap24xx_i2c_add_bus
+ * registering functions to load algorithms at runtime
+ * 
+ * @param adap 
+ * 
+ * @return  status of i2c_add_adaptor
+ */
+static int omap24xx_i2c_add_bus(struct
+				i2c_adapter
+				*adap)
+{
+	FN_IN;
+	adap->algo = &omap24xx_i2c_algo;
+	adap->timeout = (I2C_DEFAULT_TIMEOUT_MS * HZ) / 1000;
+	if (!adap->timeout) {
+		adap->timeout = 1;
+	}
+	adap->retries = I2C_DEFAULT_RETRIES;
+	FN_OUT(0);
+	return i2c_add_adapter(adap);
+}
+
+/** 
+ * @brief omap24xx_i2c_del_bus
+ * 
+ * @param adap 
+ * 
+ * @return 0
+ */
+static int omap24xx_i2c_del_bus(struct
+				i2c_adapter
+				*adap)
+{
+	FN_IN;
+	FN_OUT(0);
+	return i2c_del_adapter(adap);
+}
+
+/** 
+ * @brief omap24xx_i2c_exit
+ * I2C Module Shutdown
+ */
+void omap24xx_i2c_exit(void)
+{
+	struct omap24xx_i2c_adapter
+	*oadap;
+	struct i2c_adapter *adap;
+	int i;
+	FN_IN;
+	for (i = NUM_I2C_ADAP - 1; i >= 0; i--) {
+		oadap = saved_oadap[i];
+		if (!oadap)
+			continue;
+		adap = &oadap->adap;
+		if (oadap->irq) {
+			free_irq(oadap->irq, oadap);
+			oadap->irq = 0;
+			omap24xx_i2c_del_bus(adap);
+		}
+#ifdef CONFIG_PM
+		if (omap_get_drvdata(&i2c_device_ldm[i]) == oadap) {
+			omap_device_unregister(&i2c_device_ldm[i]);
+		}
+#endif
+		if (oadap->scl_lh) {
+			/* shut down i2c only if we were at the last leg */
+			i2c_hw_release(oadap);
+			disable_i2c_clock(i);
+		}
+		kfree(oadap);
+		saved_oadap[i] = NULL;
+	}
+
+#ifdef  CONFIG_PM
+	omap_driver_unregister(&i2c_driver_ldm);
+#ifdef I2C_DPM_SCALE
+	/* To be enabled on implementing DMA */
+	dpm_unregister_scale(&omap24xxi2c_pre_scale,SCALE_PRECHANGE);
+	dpm_unregister_scale(&omap24xxi2c_post_scale,SCALE_POSTCHANGE);
+#endif
+#endif
+	FN_OUT(0);
+}
+
+/** 
+ * @brief omap24xx_i2c_init
+ * I2C Module Startup
+ * 
+ * @return 0 for success, else return error condition
+ */
+int __init omap24xx_i2c_init(void)
+{
+	struct omap24xx_i2c_adapter
+	*oadap;
+	struct i2c_adapter *adap = NULL;
+	int i;
+#ifdef CONFIG_PM
+	int ret;
+#endif
+	const static unsigned long reg_addr[] =
+	    { I2C1_REG_BASE, I2C2_REG_BASE };
+	const static int i2c_irq[] = { INT_I2C1_IRQ, INT_I2C2_IRQ };
+	const static char *i2c_name[] = { I2C_NAME "-1", I2C_NAME "-2" };
+	int i2c_clock = 0, s_clock = 0, psc = 0, scl_lh = 0, iclk = 0;
+	FN_IN;
+#ifdef CONFIG_PM
+	ret = omap_driver_register(&i2c_driver_ldm);
+	if (ret) {
+		FN_OUT(ret);
+		return ret;
+	}
+#ifdef I2C_DPM_SCALE
+	/* To be enabled on implementing DMA */
+	dpm_register_scale(&omap24xxi2c_pre_scale,SCALE_PRECHANGE);
+	dpm_register_scale(&omap24xxi2c_post_scale,SCALE_POSTCHANGE);
+#endif
+	init_waitqueue_head(&i2c_suspend_data[0].suspend_wq);
+	init_waitqueue_head(&i2c_suspend_data[1].suspend_wq);
+#endif
+#ifdef I2C_SECONDARY_PULL
+	/* Enables the internal secondary pull-up inside the HS
+	 * I2C pad when the I2C is in High-Speed mode and the
+	 * bus line capacitance is exceeding 45 pF.
+	 * Valid only for ES2.0 and above
+	 */
+	if (get_cpu_rev()>=2) {
+		u32 reg = readl(CONTROL_PBIAS_LITE_1);
+		reg &=~(PULL_HS_BUS0|PULL_HS_BUS1);
+		reg |= I2C_SECONDARY_PULL;
+		writel(reg, CONTROL_PBIAS_LITE_1);
+	}
+#endif
+	/* initialize each I2C controller */
+	for (i = 0; i < NUM_I2C_ADAP; i++) {
+		int temp_i2c_clk = i2c_clock;
+		oadap =
+		    kmalloc(sizeof(struct omap24xx_i2c_adapter), GFP_KERNEL);
+		if (!oadap) {
+			printk(KERN_ERR I2C_NAME
+			       ": could not allocate memory\n");
+			goto init_error;
+		}
+		memset(oadap, 0, sizeof(struct omap24xx_i2c_adapter));
+		oadap->a_num = i;
+		saved_oadap[i] = oadap;
+		switch (i) {
+		case 0:
+			i2c_clock = i2c_clock0;
+			break;
+		case 1:
+			i2c_clock = i2c_clock1;
+			break;
+		default:
+			printk(KERN_ERR I2C_NAME ": Unknown bus\n");
+			goto init_error;
+		}
+
+		/* initialize the i2c_adapter struct */
+		adap = &oadap->adap;
+		adap->algo_data = oadap;
+		/* Get the default speed of the device */
+		if (i2c_clock > OMAP_I2C_FAST_MODE) {
+			adap->flags |= I2C_FUNC_HIGH_SPEED;
+		}
+
+		/* We delete I2C_FUNC_SMBUS_QUICK from our list of capabilities
+		 * because that requires the ability to generate messages with
+		 * zero bytes of data.  The OMAP I2C controller is not able to do
+		 * this.  The lack of this feature prevents probing for I2C devices.
+		 */
+		adap->flags |=
+		    (((I2C_FUNC_SMBUS_EMUL) & ~(I2C_FUNC_SMBUS_QUICK))
+		     | I2C_FUNC_10BIT_ADDR);
+		strcpy(adap->name, i2c_name[i]);
+#if (I2C_LOG_LEVEL >= 1)
+		oadap->mmio_base_phys = reg_addr[i];
+#endif
+		/* IMP NOTE: Despite what the TRM says as of now, the confirmation 
+		 * from h/w team is that we are to use only the 96 Meg Fn clock 
+		 * and compute based on that. 
+		 */
+		s_clock = SYSTEM_CLOCK_96;
+		/* clock setting is a single time affair */
+		D2("clock(s,i)[%d] -> (%d,%d)\n", i, s_clock, i2c_clock);
+		if (enable_i2c_clock(i, s_clock)) {
+			printk(KERN_ERR
+			       "%s: Could not set Required system clock \n",
+			       adap->name);
+			goto init_error;
+		}
+		/* PSC selection Logic - look for the highest PSC setting
+		 * that returns a non negative dev value for a given iCLK mode
+		 */
+		psc = I2C_PSC_MAX;
+		while (psc >= I2C_PSC_MIN) {
+			temp_i2c_clk = i2c_clock;
+			iclk = s_clock / (psc + 1);
+			/* In HS mode Ignore the FS settting.. look 
+			 * for Fast Mode settings 
+			 */
+			if (i2c_clock > OMAP_I2C_FAST_MODE) {
+				temp_i2c_clk = OMAP_I2C_FAST_MODE;
+			}
+			scl_lh = (iclk * 10 / (temp_i2c_clk * 2));
+			/* Check for decimal places.. if yes, we ignore it
+			 * Need a perfect match for it to work!!
+			 */
+			if (scl_lh % 10) {
+				scl_lh = -1;
+			} else {
+				scl_lh /= 10;
+				/* Thigh and Tlow use 5 and 7 differences, 
+				 * hence use 6 as the difference computation
+				 */
+				scl_lh -= 6;
+			}
+			/* Values for F/S mode and first phase of HS mode */
+			if (((i2c_clock > OMAP_I2C_STANDARD)
+			     && (scl_lh >= I2C_SCLLH_MIN))
+			    || (((i2c_clock <= OMAP_I2C_STANDARD)
+				 && (scl_lh >= 0)))) {
+				D1("Match! sclk=%d psc=0x%x"
+				   " iclk=%d i2c_clk=%d scl_lh=0x%x\n",
+				   s_clock, psc, iclk, i2c_clock, scl_lh);
+				break;
+			}
+			psc--;
+		}
+		/* Did not find an optimal config */
+		if (psc < I2C_PSC_MIN) {
+			printk(KERN_ERR
+			       "%s: Unable to set Prescalar for i2c_clock=%d sys_clock=%d\n",
+			       adap->name, i2c_clock, s_clock);
+			goto init_error;
+		}
+
+		/* Reset the SCL_LH */
+		scl_lh = 0;
+		/* temp_i2c_clk and iclk already set in for loop */
+		if (i2c_clock > OMAP_I2C_FAST_MODE) {
+			scl_lh =
+			    (((s_clock / ((i2c_clock) * 2)) -
+			      6) & I2C_SCLH_HSSCLL_M);
+			if (scl_lh < I2C_HSSCLLH_MIN) {
+				printk(KERN_ERR
+				       "%s: Unable to set HSSCLH for i2c_clock=%d sys_clock=%d scl_lh=0x%x min =0x%x\n",
+				       adap->name, i2c_clock,
+				       s_clock, scl_lh, I2C_HSSCLLH_MIN);
+				goto init_error;
+			}
+			scl_lh = scl_lh << I2C_SCLL_HSSCLL;
+		}
+		scl_lh |=
+		    (((iclk / (temp_i2c_clk * 2)) -
+		      6) & I2C_SCLL_SCLL_M) << I2C_SCLL_SCLL;
+		D2("Match! sclk=%d psc=0x%x iclk=%d temp_i2c_clk=%d "
+		   "i2c_clk=%d scl_lh=0x%x\n", s_clock, psc, iclk, temp_i2c_clk,
+		   i2c_clock, scl_lh);
+		oadap->psc = psc;
+		oadap->scl_lh = scl_lh;
+		oadap->s_clock = s_clock;
+		oadap->oa = I2C_OWN_ADDRESS;
+		oadap->mcode = I2C_MCODE;	/* needed for HS transfer */
+		/* Dont need to re-map an already remapped address 
+		 * L4Core and wakeup are default mapped 
+		 */
+		oadap->mmio_base = (unsigned long)
+		    IO_ADDRESS(reg_addr[i]);
+		D2("PHY=0x%x,IO=0x%x\n",
+		   (unsigned int)reg_addr[i], (unsigned int)oadap->mmio_base);
+
+		/* Grab the adapter fifo size */
+		oadap->rx_fifo_size =
+		    (omap242x_i2c_readw(oadap, I2C_BUFSTAT) >>
+		     I2C_BUFSTAT_FIFO_DEPTH) & I2C_BUFSTAT_FIFO_DEPTH_M;
+		/* Fifo sizes is 2^(buffstat:fifodepth) * 8 */
+		oadap->rx_fifo_size = (0x1 << oadap->rx_fifo_size) * 8;
+		oadap->tx_fifo_size =
+		    (oadap->rx_fifo_size <
+		     I2C_BUF_TRSH_TX) ? oadap->rx_fifo_size : I2C_BUF_TRSH_TX;
+		oadap->rx_fifo_size -=
+		    (oadap->rx_fifo_size <
+		     I2C_BUF_TRSH_RX) ? oadap->rx_fifo_size : I2C_BUF_TRSH_RX;
+
+		adap->retries = I2C_DEFAULT_RETRIES;
+		D1( "%s: %s I2C bus controller at  PA 0x%08lx, VA 0x%08lx, irq %d\n",
+		       adap->name,
+		       (i2c_clock <= OMAP_I2C_STANDARD) ? "STD" :
+		       (i2c_clock <= OMAP_I2C_FAST_MODE) ? "FM" : "HS",
+		       reg_addr[i], oadap->mmio_base, oadap->irq);
+		init_waitqueue_head(&oadap->i2c_wait_queue);
+
+		if (i2c_hw_init(oadap) < 0) {
+			printk(KERN_ERR
+			       "%s: cannot reset I2C controller\n", adap->name);
+			goto init_error;
+		}
+
+		if (request_irq
+		    (i2c_irq[i],
+		     omap24xx_i2c_handler, 0, adap->name, oadap) < 0) {
+			printk(KERN_ERR
+			       "%s: cannot intall handler for irq"
+			       " %d\n", adap->name, i2c_irq[i]);
+			goto init_error;
+		}
+		oadap->irq = i2c_irq[i];
+		if (omap24xx_i2c_add_bus(adap) < 0) {
+			printk(KERN_ERR
+			       "%s: cannot register I2C adapter\n", adap->name);
+			goto init_error;
+		}
+#ifdef CONFIG_PM
+		if (omap_device_register(&i2c_device_ldm[i])) {
+			printk(KERN_ERR
+			       "%s: cannot register I2C adapter with LDM\n",
+			       adap->name);
+			goto init_error;
+		}
+		/* set driver specific data to use in power mgmt functions */
+		omap_set_drvdata(&i2c_device_ldm[i], oadap);
+#endif
+	}
+	FN_OUT(0);
+	return 0;
+      init_error:
+	/* call our exit routine to cleanup */
+	omap24xx_i2c_exit();
+	for (i = 0; i < NUM_I2C_ADAP; i++) {
+		printk(KERN_ERR
+		       "%s: I2C driver installation failed!\n", i2c_name[i]);
+	}
+	FN_OUT(ENODEV);
+	return -ENODEV;
+}
+
+/* i2c functional clock settings */
+/* FS-Standard mode */
+int enable_i2c_clock(int i2c_module, int clocksrc)
+{
+	struct device *dev = NULL;
+	struct clk *i2ci, *i2cf, *i2chsf;
+	char use_i2cf = 1;
+	char use_hsi2cf = 0;
+	if (i2c_module == 0) {
+		i2ci = clk_get(dev, "i2c1_ick");
+		i2cf = clk_get(dev, "i2c1_fck");
+		i2chsf = clk_get(dev, "i2chs1_fck");
+	} else {
+		i2ci = clk_get(dev, "i2c2_ick");
+		i2cf = clk_get(dev, "i2c2_fck");
+		i2chsf = clk_get(dev, "i2chs2_fck");
+	}
+
+	if (clocksrc == 96000) {
+		use_i2cf = 0;
+		use_hsi2cf = 1;
+	}
+
+	/* down them 
+	clk_unuse(i2ci);
+	clk_unuse(i2cf);
+	clk_unuse(i2chsf);
+	*/
+	
+	/* enable them */
+	if (use_i2cf) {
+		clk_enable(i2cf);
+	}
+	if (use_hsi2cf) {
+		clk_enable(i2chsf);
+	}
+
+	clk_enable(i2ci);
+	return 0;
+}
+
+void disable_i2c_clock(int i2c_module)
+{
+	struct device *dev = NULL;
+	struct clk *i2ci, *i2cf, *i2chsf;
+	if (i2c_module == 0) {
+		i2ci = clk_get(dev, "i2c1_ick");
+		i2cf = clk_get(dev, "i2c1_fck");
+		i2chsf = clk_get(dev, "i2chs1_fck");
+	} else {
+		i2ci = clk_get(dev, "i2c2_ick");
+		i2cf = clk_get(dev, "i2c2_fck");
+		i2chsf = clk_get(dev, "i2chs2_fck");
+	}
+
+	/* down them */
+	clk_disable(i2ci);
+	clk_disable(i2cf);
+	clk_disable(i2chsf);
+}
+
+MODULE_AUTHOR("MontaVista Software, Inc.");
+MODULE_DESCRIPTION("OMAP24xx I2C bus adapter");
+MODULE_LICENSE("GPL");
+
+/* i2c may be needed to bring up other drivers */
+subsys_initcall(omap24xx_i2c_init);
+module_exit(omap24xx_i2c_exit);
diff -purN linux-omap/drivers/i2c/busses/i2c-omap_hs.h lin_for_twl/drivers/i2c/busses/i2c-omap_hs.h
--- linux-omap/drivers/i2c/busses/i2c-omap_hs.h	1969-12-31 18:00:00.000000000 -0600
+++ lin_for_twl/drivers/i2c/busses/i2c-omap_hs.h	2007-02-27 17:43:17.000000000 -0600
@@ -0,0 +1,210 @@
+/*
+ * drivers/i2c/i2c-omap243x.h
+ *
+ * I2C driver for OMAP242x I2C controller.
+ *
+ * Author: Andy Lowe (source@mvista.com)
+ *
+ * Copyright (C) 2004 MontaVista Software, Inc.
+ * Copyright (C) 2004 Texas Instruments.
+ *
+ * This file is licensed under the terms of the GNU General Public License 
+ * version 2. This program is licensed "as is" without any warranty of any 
+ * kind, whether express or implied.
+ *
+ * History:
+ * -------
+ * Aug 2005 - Copied from drivers/i2c/i2c-omap24xx.h and ported to 
+ *            243X and added support for HSI2C - Texas Instruments 
+ */
+
+#ifndef OMAP243XI2C_H
+#define OMAP243XI2C_H
+
+/* Grab the base address */
+#include <asm/arch/hardware.h>
+
+/* physical memory map definitions -same for 2420-2430 -HS support in 2430*/
+/* I2C1 module */
+#define I2C1_REG_BASE        (0x48000000 + 0x70000)
+#define I2C1_REG_SIZE        0x00001000 /* unused as of now */
+/* I2C2 module */
+#define I2C2_REG_BASE        (0x48000000 + 0x72000)
+#define I2C2_REG_SIZE        0x00001000 /* unused as of now */
+
+/* define I2C register offsets */
+#define I2C_REV              0x00
+#define I2C_IE               0x04
+#define I2C_STAT             0x08
+#define I2C_WE               0x0C
+#define I2C_SYSS             0x10
+#define I2C_BUF              0x14
+#define I2C_CNT              0x18
+#define I2C_DATA             0x1C
+#define I2C_SYSC             0x20
+#define I2C_CON              0x24
+#define I2C_OA               0x28
+#define I2C_SA               0x2C
+#define I2C_PSC              0x30
+#define I2C_SCLL             0x34
+#define I2C_SCLH             0x38
+#define I2C_SYSTEST          0x3C
+#define I2C_BUFSTAT          0x40
+#define I2C_OA1              0x44
+#define I2C_OA2              0x48
+#define I2C_OA3              0x4C
+#define I2C_ACTOA            0x50
+#define I2C_SBLOCK           0x54
+
+/* Define bit fields within selected registers */
+#define I2C_REV_MAJOR        (15 << 4)
+#define I2C_REV_MAJOR_SHIFT  (4)
+#define I2C_REV_MINOR        (15 << 0)
+#define I2C_REV_MINOR_SHIFT  (0)
+
+#define I2C_IE_XDR_IE        (1 <<  14)
+#define I2C_IE_RDR_IE        (1 <<  13)
+#define I2C_IE_AAS_IE        (1 <<  9)
+#define I2C_IE_BF_IE         (1 <<  8)
+#define I2C_IE_AERR_IE       (1 <<  7)
+#define I2C_IE_STC_IE        (1 <<  6)
+#define I2C_IE_GC_IE         (1 <<  5)
+#define I2C_IE_XRDY_IE       (1 <<  4)
+#define I2C_IE_RRDY_IE       (1 <<  3)
+#define I2C_IE_ARDY_IE       (1 <<  2)
+#define I2C_IE_NACK_IE       (1 <<  1)
+#define I2C_IE_AL_IE         (1 <<  0)
+
+#define I2C_STAT_XDR         (1 << 14)
+#define I2C_STAT_RDR         (1 << 13)
+#define I2C_STAT_BB          (1 << 12)
+#define I2C_STAT_ROVR        (1 << 11)
+#define I2C_STAT_XUDF        (1 << 10)
+#define I2C_STAT_AAS         (1 <<  9)
+#define I2C_STAT_BF          (1 <<  8)
+#define I2C_STAT_AERR        (1 <<  7)
+#define I2C_STAT_STC         (1 <<  6)
+#define I2C_STAT_GC          (1 <<  5)
+#define I2C_STAT_XRDY        (1 <<  4)
+#define I2C_STAT_RRDY        (1 <<  3)
+#define I2C_STAT_ARDY        (1 <<  2)
+#define I2C_STAT_NACK        (1 <<  1)
+#define I2C_STAT_AL          (1 <<  0)
+
+#define I2C_WE_XDR_WE        (1 <<  14)
+#define I2C_WE_RDR_WE        (1 <<  13)
+#define I2C_WE_AAS_WE        (1 <<  9)
+#define I2C_WE_BF_WE         (1 <<  8)
+#define I2C_WE_AERR_WE       (1 <<  7)
+#define I2C_WE_STC_WE        (1 <<  6)
+#define I2C_WE_GC_WE         (1 <<  5)
+#define I2C_WE_XRDY_WE       (1 <<  4)
+#define I2C_WE_RRDY_WE       (1 <<  3)
+#define I2C_WE_ARDY_WE       (1 <<  2)
+#define I2C_WE_NACK_WE       (1 <<  1)
+#define I2C_WE_AL_WE         (1 <<  0)
+
+#define I2C_SYSS_RDONE       (1 <<  0)
+
+#define I2C_BUF_RDMA_EN      (1 << 15)
+#define I2C_BUF_RXFIFO_CL    (1 << 14)
+#define I2C_BUF_RXTRSH       (8)
+#define I2C_BUF_RXTRSH_M     (0x3F)
+#define I2C_BUF_XDMA_EN      (1 <<  7)
+#define I2C_BUF_TXFIFO_CL    (1 <<  6)
+#define I2C_BUF_TXTRSH       (0)
+#define I2C_BUF_TXTRSH_M     (0x3F)
+
+/* FIFO Divisors for threshold -
+ * the Tx fifo should be as low as possible with out causing a undeflow
+ * Rx fifo should be as high as possible without forcing an overflow 
+ * RX Fifo is from FIFO top and tx trsh is from FIFO bottom 
+ */
+#define I2C_BUF_TRSH_TX              1
+#define I2C_BUF_TRSH_RX              5
+
+#define I2C_SYSC_CLKACT      (8)
+#define I2C_SYSC_CLKACT_M    (0x03)
+#define I2C_SYSC_IDLEMODE    (3)
+#define I2C_SYSC_IDLEMODE_M  (0x03)
+#define I2C_SYSC_EN_WK       (1 <<  2)
+#define I2C_SYSC_SRST        (1 <<  1)
+#define I2C_SYSC_AUTO_IDLE   (1 <<  0)
+
+#define I2C_CON_I2C_EN       (1 << 15)
+#define I2C_CON_OP_MODE      (12)
+#define I2C_CON_OP_MODE_M    (0x03)
+/* 00: I2C Fast/Standard mode
+ * 01: I2C High Speed mode
+ * 10: SCCB mode
+ */
+#define I2C_CON_OP_MODE_FS      (0x00)
+#define I2C_CON_OP_MODE_HS      (0x01)
+#define I2C_CON_OP_MODE_SCCB    (0x02) /* not supported as of now */
+#define I2C_CON_STB          (1 << 11)
+#define I2C_CON_MST          (1 << 10)
+#define I2C_CON_TRX          (1 <<  9)
+#define I2C_CON_XSA          (1 <<  8)
+#define I2C_CON_XOA0         (1 <<  7)
+#define I2C_CON_XOA1         (1 <<  6)
+#define I2C_CON_XOA2         (1 <<  5)
+#define I2C_CON_XOA3         (1 <<  4)
+#define I2C_CON_STP          (1 <<  1)
+#define I2C_CON_STT          (1 <<  0)
+
+#define I2C_PSC_MAX          (0x0f)
+#define I2C_PSC_MIN          (0x04)
+
+#define I2C_OA_MCODE         (13)
+#define I2C_OA_MCODE_M       (0x07)
+#define I2C_OA_OA0           (0)
+#define I2C_OA_OA0_M         (0x3FF)
+
+#define I2C_SCLL_SCLL        (0)
+#define I2C_SCLL_SCLL_M      (0xFF)
+#define I2C_SCLL_HSSCLL      (8)
+#define I2C_SCLH_HSSCLL_M    (0xFF)
+#define I2C_SCLH_SCLH        (0)
+#define I2C_SCLH_SCLH_M      (0xFF)
+#define I2C_SCLH_HSSCLH      (8)
+#define I2C_SCLH_HSSCLH_M    (0xFF)
+#define I2C_SCLLH_MIN        (0x12)
+#define I2C_HSSCLLH_MIN      (0x0C)
+
+#define I2C_SYSTEST_ST_EN    (1 << 15)
+#define I2C_SYSTEST_FREE     (1 << 14)
+#define I2C_SYSTEST_TMODE    (3 << 12)
+#define I2C_SYSTEST_TMODE_FUNCTIONAL   (0 << 12)
+#define I2C_SYSTEST_TMODE_CLOCK        (2 << 12)
+#define I2C_SYSTEST_TMODE_LOOPBACK     (3 << 12)
+#define I2C_SYSTEST_SCCB_E_O (1 <<  4)
+#define I2C_SYSTEST_SCL_I    (1 <<  3)
+#define I2C_SYSTEST_SCL_O    (1 <<  2)
+#define I2C_SYSTEST_SDA_I    (1 <<  1)
+#define I2C_SYSTEST_SDA_O    (1 <<  0)
+
+#define I2C_BUFSTAT_FIFO_DEPTH         (14)
+#define I2C_BUFSTAT_FIFO_DEPTH_M       (0x03)
+#define I2C_BUFSTAT_RXLEVEL            (8)
+#define I2C_BUFSTAT_RXLEVEL_M          (0x3F)
+#define I2C_BUFSTAT_TXLEVEL            (0)
+#define I2C_BUFSTAT_TXLEVEL_M          (0x3F)
+
+#define I2C_ACTOA_OA3_ACT     (1 <<  3)
+#define I2C_ACTOA_OA2_ACT     (1 <<  2)
+#define I2C_ACTOA_OA1_ACT     (1 <<  1)
+#define I2C_ACTOA_OA0_ACT     (1 <<  0)
+
+#define I2C_SBLOCK_OA3_EN     (1 <<  3)
+#define I2C_SBLOCK_OA2_EN     (1 <<  2)
+#define I2C_SBLOCK_OA1_EN     (1 <<  1)
+#define I2C_SBLOCK_OA0_EN     (1 <<  0)
+#define OMAP_I2C_STANDARD          100
+#define OMAP_I2C_FAST_MODE         400
+#define OMAP_I2C_HIGH_SPEED        3400
+
+
+#define SYSTEM_CLOCK_12       12000
+#define SYSTEM_CLOCK_96       96000
+
+#endif    /* ifndef OMAP243XI2C_H */
