All of lore.kernel.org
 help / color / mirror / Atom feed
* I2C TWL4030 Keypad
@ 2007-02-16 11:25 Ram
  2007-02-16 14:31 ` G, Manjunath Kondaiah
                   ` (2 more replies)
  0 siblings, 3 replies; 13+ messages in thread
From: Ram @ 2007-02-16 11:25 UTC (permalink / raw)
  To: linux-omap-open-source

Hi,
   Im using omap2430 SDP.
   Im trying to get TWL4030 Keypad to work on 2.6.19. Im using 2.6.14 for
omap2430 as a reference.

   Im using the following files:
        1) i2c-omap.c which exists on 2.6.19
        2) twl4030_core.c
        3) twl4030_gpio.c (taken from 2.6.14)
        4) omap-twl4030keypad.c (taken from 2.6.14)

   made  changes  to support generic interrupts in 2.6.19.

   Im able to read the value of registers using  twl4030_kpread_u8
    TWL4030_MODULE_KEYPAD, REG_KEYP_EDR, REG_LK_PTV_REG, REG_KEY_DEB_REG,
REG_LONG_KEY_REG1, REG_KEYP_SIH_CTRL, REG_KEYP_IMR1

  However, im not able to recieve interrupts. upon pressing keys in keypad.
i dont observe
  any change in interrupts count. when i do a cat /proc/interrupts.

Im not sure if im missing something.


  I also observe randomly (say 3 out of 10 times), my i2c bus times out and
im unable to read or write TWL4030 registers. i get an return value of
-110.

i2c_omap i2c_omap.2: timeout waiting for bus ready

Please Advice,

Regards,
sriram

^ permalink raw reply	[flat|nested] 13+ messages in thread
* RE: I2C TWL4030 Keypad
@ 2007-02-28  1:02 Syed Mohammed, Khasim
  0 siblings, 0 replies; 13+ messages in thread
From: Syed Mohammed, Khasim @ 2007-02-28  1:02 UTC (permalink / raw)
  To: Ram, Cantu Castillo, Arturo; +Cc: linux-omap-open-source

[-- Attachment #1: Type: text/plain, Size: 792 bytes --]

This patch is for HS I2C host driver (same as on linux.omap.com)

Regards,
Khasim

>-----Original Message-----
>From: Syed Mohammed, Khasim
>Sent: Tuesday, February 27, 2007 7:01 PM
>To: 'Ram'; Cantu Castillo, Arturo
>Cc: linux-omap-open-source@linux.omap.com
>Subject: RE: I2C TWL4030 Keypad
>
>Hi Ram,
>
>As I had communicated before, the issue is due to incomplete I2C
driver. We
>were not operating at High speed and T2 needs high speed to work
>efficiently. Apart from high speed we need FIFO handling + errata fixes
>etc.
>
>For now, I have ported high speed I2C driver (from linux.omap.com) to
GIT
>and Keypad works fine. I will send few patches for your reference.
>
>We have to find an optimal way to get this (I2C) code into tree ...
>
>Regards,
>Khasim

[-- Attachment #2: i2c_bus.diff --]
[-- Type: application/octet-stream, Size: 49346 bytes --]

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 */

[-- Attachment #3: Type: text/plain, Size: 0 bytes --]



^ permalink raw reply	[flat|nested] 13+ messages in thread
* RE: I2C TWL4030 Keypad
@ 2007-02-28  1:05 Syed Mohammed, Khasim
  0 siblings, 0 replies; 13+ messages in thread
From: Syed Mohammed, Khasim @ 2007-02-28  1:05 UTC (permalink / raw)
  To: Ram, Cantu Castillo, Arturo; +Cc: linux-omap-open-source

[-- Attachment #1: Type: text/plain, Size: 1202 bytes --]

Few more, with these you should be able to get Keypad working on 2430SDP
with 2.6.20 GIT.

Need some more time to get them on tree :(

Regards,
Khasim

>-----Original Message-----
>From: Syed Mohammed, Khasim
>Sent: Tuesday, February 27, 2007 7:03 PM
>To: 'Ram'; Cantu Castillo, Arturo
>Cc: 'linux-omap-open-source@linux.omap.com'
>Subject: RE: I2C TWL4030 Keypad
>
>This patch is for HS I2C host driver (same as on linux.omap.com)
>
>Regards,
>Khasim
>
>>-----Original Message-----
>>From: Syed Mohammed, Khasim
>>Sent: Tuesday, February 27, 2007 7:01 PM
>>To: 'Ram'; Cantu Castillo, Arturo
>>Cc: linux-omap-open-source@linux.omap.com
>>Subject: RE: I2C TWL4030 Keypad
>>
>>Hi Ram,
>>
>>As I had communicated before, the issue is due to incomplete I2C
driver.
>We
>>were not operating at High speed and T2 needs high speed to work
>>efficiently. Apart from high speed we need FIFO handling + errata
fixes
>>etc.
>>
>>For now, I have ported high speed I2C driver (from linux.omap.com) to
GIT
>>and Keypad works fine. I will send few patches for your reference.
>>
>>We have to find an optimal way to get this (I2C) code into tree ...
>>
>>Regards,
>>Khasim

[-- Attachment #2: include.diff --]
[-- Type: application/octet-stream, Size: 3645 bytes --]

diff -purN linux-omap/include/asm-arm/arch-omap/board-2430sdp.h lin_for_twl/include/asm-arm/arch-omap/board-2430sdp.h
--- linux-omap/include/asm-arm/arch-omap/board-2430sdp.h	2006-12-17 08:56:42.000000000 -0600
+++ lin_for_twl/include/asm-arm/arch-omap/board-2430sdp.h	2007-02-27 10:16:23.000000000 -0600
@@ -39,6 +39,11 @@
 /* TWL4030 Primary Interrupt Handler (PIH) interrupts */
 #define IH_TWL4030_BASE			IH_BOARD_BASE
 #define IH_TWL4030_END			(IH_TWL4030_BASE+8)
-#define NR_IRQS				(IH_TWL4030_END)
+
+/* TWL4030 GPIO Interrupts */
+#define IH_TWL4030_GPIO_BASE		(IH_TWL4030_END)
+#define IH_TWL4030_GPIO_END		(IH_TWL4030_BASE+18)
+
+#define NR_IRQS				(IH_TWL4030_GPIO_END)
 
 #endif /* __ASM_ARCH_OMAP_2430SDP_H */
diff -purN linux-omap/include/asm-arm/arch-omap/twl4030.h lin_for_twl/include/asm-arm/arch-omap/twl4030.h
--- linux-omap/include/asm-arm/arch-omap/twl4030.h	2007-01-08 18:57:20.000000000 -0600
+++ lin_for_twl/include/asm-arm/arch-omap/twl4030.h	2007-02-27 11:12:53.000000000 -0600
@@ -72,6 +72,34 @@
 #define TWL4030_VAUX3_DEV_GRP		0x1F
 #define TWL4030_VAUX3_DEDICATED		0x22
 
+/* TWL4030 GPIO interrupt definitions */
+
+#define TWL4030_GPIO_MIN		0
+#define TWL4030_GPIO_MAX		18
+#define TWL4030_GPIO_MAX_CD		2
+#define TWL4030_GPIO_IRQ_NO(n)		(IH_TWL4030_GPIO_BASE+n)
+#define TWL4030_GPIO_IS_INPUT		1
+#define TWL4030_GPIO_IS_OUTPUT		0
+#define TWL4030_GPIO_IS_ENABLE		1
+#define TWL4030_GPIO_IS_DISABLE		0
+#define TWL4030_GPIO_PULL_UP		0
+#define TWL4030_GPIO_PULL_DOWN		1
+#define TWL4030_GPIO_PULL_NONE		2
+#define TWL4030_GPIO_EDGE_NONE		0
+#define TWL4030_GPIO_EDGE_RISING	1
+#define TWL4030_GPIO_EDGE_FALLING	2
+
+extern int  twl4030_request_gpio(int gpio);
+extern int twl4030_free_gpio(int gpio);
+extern int twl4030_set_gpio_edge_ctrl(int gpio, int edge);
+extern int twl4030_set_gpio_debounce(int gpio, int enable);
+extern int twl4030_set_gpio_card_detect(int gpio, int enable);
+extern int twl4030_gpio_interrupt(int gpio,int enable);
+extern int twl4030_set_gpio_pull(int gpio, int pull_dircn);
+extern int twl4030_set_gpio_dataout(int gpio, int enable);
+extern int  twl4030_get_gpio_datain(int gpio);
+extern int twl4030_set_gpio_direction(int gpio, int is_input);
+
 /* Functions to read and write from TWL4030 */
 
 /*
diff -purN linux-omap/include/linux/i2c.h lin_for_twl/include/linux/i2c.h
--- linux-omap/include/linux/i2c.h	2007-01-08 18:57:30.000000000 -0600
+++ lin_for_twl/include/linux/i2c.h	2007-02-27 15:41:51.000000000 -0600
@@ -210,7 +210,9 @@ struct i2c_adapter {
 	unsigned int class;
 	const struct i2c_algorithm *algo; /* the algorithm to access the bus */
 	void *algo_data;
-
+	
+	unsigned int flags; /* flags specifying div. data FIXME HS-I2C */
+	
 	/* --- administration stuff. */
 	int (*client_register)(struct i2c_client *);
 	int (*client_unregister)(struct i2c_client *);
@@ -356,6 +358,11 @@ struct i2c_msg {
 	__u16 flags;
 #define I2C_M_TEN	0x10	/* we have a ten bit chip address	*/
 #define I2C_M_RD	0x01
+
+#define I2C_M_WR        0x00    /* For readable code! */
+#define I2C_M_HS	0x20
+#define I2C_M_PRI       0x04
+	
 #define I2C_M_NOSTART	0x4000
 #define I2C_M_REV_DIR_ADDR	0x2000
 #define I2C_M_IGNORE_NAK	0x1000
@@ -371,6 +378,7 @@ struct i2c_msg {
 #define I2C_FUNC_PROTOCOL_MANGLING	0x00000004 /* I2C_M_{REV_DIR_ADDR,NOSTART,..} */
 #define I2C_FUNC_SMBUS_HWPEC_CALC	0x00000008 /* SMBus 2.0 */
 #define I2C_FUNC_SMBUS_BLOCK_PROC_CALL	0x00008000 /* SMBus 2.0 */
+#define I2C_FUNC_HIGH_SPEED		0x00000010 /* High Speed Capable */
 #define I2C_FUNC_SMBUS_QUICK		0x00010000
 #define I2C_FUNC_SMBUS_READ_BYTE	0x00020000
 #define I2C_FUNC_SMBUS_WRITE_BYTE	0x00040000

[-- Attachment #3: keypad.diff --]
[-- Type: application/octet-stream, Size: 39173 bytes --]

diff -purN linux-omap/drivers/input/keyboard/Kconfig lin_for_twl/drivers/input/keyboard/Kconfig
--- linux-omap/drivers/input/keyboard/Kconfig	2007-01-08 18:56:34.000000000 -0600
+++ lin_for_twl/drivers/input/keyboard/Kconfig	2007-02-27 13:27:57.000000000 -0600
@@ -203,6 +203,15 @@ config KEYBOARD_OMAP
 	  To compile this driver as a module, choose M here: the
 	  module will be called omap-keypad.
 
+config KEYBOARD_TWL4030
+        tristate "TI TWL4030 keypad support"
+        depends on INPUT_KEYBOARD && TWL4030_CORE && MACH_OMAP_2430SDP
+        help
+          Say Y here if you want to use the OMAP TWL4030 keypad.
+
+          To compile this driver as a module, choose M here: the
+          module will be called omap-twl4030keypad.
+
 config OMAP_PS2
 	tristate "TI OMAP Innovator 1510 PS/2 keyboard & mouse support"
 	depends on ARCH_OMAP15XX && MACH_OMAP_INNOVATOR
diff -purN linux-omap/drivers/input/keyboard/Makefile lin_for_twl/drivers/input/keyboard/Makefile
--- linux-omap/drivers/input/keyboard/Makefile	2007-01-08 18:56:34.000000000 -0600
+++ lin_for_twl/drivers/input/keyboard/Makefile	2007-02-27 13:24:32.000000000 -0600
@@ -19,4 +19,4 @@ obj-$(CONFIG_KEYBOARD_HIL_OLD)		+= hilkb
 obj-$(CONFIG_KEYBOARD_OMAP)             += omap-keypad.o
 obj-$(CONFIG_OMAP_PS2)			+= innovator_ps2.o
 obj-$(CONFIG_KEYBOARD_AAED2000)         += aaed2000_kbd.o
-
+obj-$(CONFIG_KEYBOARD_TWL4030)          += omap-twl4030keypad.o
diff -purN linux-omap/drivers/input/keyboard/omap-twl4030keypad.c lin_for_twl/drivers/input/keyboard/omap-twl4030keypad.c
--- linux-omap/drivers/input/keyboard/omap-twl4030keypad.c	1969-12-31 18:00:00.000000000 -0600
+++ lin_for_twl/drivers/input/keyboard/omap-twl4030keypad.c	2007-02-27 14:22:11.000000000 -0600
@@ -0,0 +1,727 @@
+/*
+ * linux/drivers/input/omap-twl4030keypad.c
+ *
+ * Copyright (C) 2005 Texas Instruments, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/types.h>
+#include <linux/input.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/suspend.h>
+#include <linux/device.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/workqueue.h>
+
+#include <asm/arch/irqs.h>
+#include <asm/arch/hardware.h>
+#include <asm/io.h>
+#include <asm/errno.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/arch/irqs.h>
+#include <asm/arch/twl4030.h>
+#include "twl4030-keypad.h"
+
+/* ----- 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 OMAP_TWL4030KEYPAD_LOG_LEVEL 1
+/* detail - 0 - no detail
+ *          1 - function name
+ *          2 - function name, line number
+ * prefix is added to every log message
+ */
+#define OMAP_TWL4030KEYPAD_DETAIL    4
+
+/* kernel log level*/
+//#define OMAP_TWL4030KEYPAD_K_LOG_LEVEL KERN_DEBUG
+#define OMAP_TWL4030KEYPAD_K_LOG_LEVEL
+
+#if ( OMAP_TWL4030KEYPAD_DETAIL > 0 )
+#define DL1 "%s "
+#define DR1 ,__FUNCTION__
+#define DEBUG
+#else
+#define DL1
+#define DR1
+#endif
+#if ( OMAP_TWL4030KEYPAD_DETAIL > 1 )
+#define DL2 "[%d] "
+#define DR2 ,__LINE__
+#else
+#define DL2
+#define DR2
+#endif
+
+#define D(format,...)\
+	printk(OMAP_TWL4030KEYPAD_K_LOG_LEVEL DL1 DL2 format "\n" DR1 DR2, ## __VA_ARGS__)
+
+#if (OMAP_TWL4030KEYPAD_LOG_LEVEL >= 1)
+#define D1(ARGS...) D(ARGS)
+#else
+#define D1(ARGS...)
+#endif
+#if (OMAP_TWL4030KEYPAD_LOG_LEVEL >= 2)
+#define D2(ARGS...) D(ARGS)
+#else
+#define D2(ARGS...)
+#endif
+#if (OMAP_TWL4030KEYPAD_LOG_LEVEL >= 3)
+#define D3(ARGS...) D(ARGS)
+#else
+#define D3(ARGS...)
+#endif
+
+#if (OMAP_TWL4030KEYPAD_LOG_LEVEL >= 2)
+#define FN_IN printk("%s Entry\n",__FUNCTION__);
+#define FN_OUT(ARG) printk("%s[%d]:Exit(%d)\n",__FUNCTION__,__LINE__,ARG);
+#else
+#define FN_IN
+#define FN_OUT(ARG)
+#endif
+
+#define KEY(col, row, val) (((col) << 28) | ((row) << 24) | (val))
+#define NUM_ROWS 		5
+#define NUM_COLS 		6
+
+#define ROW_MASK 		((1<<NUM_ROWS)-1)
+
+#define SCAN_RATE 		HZ/20
+#define KEYNUM_MASK		0xFF000000
+#define ROWCOL_MASK		0x00FFFFFF
+
+/* Driver Name */
+#define OMAP_TWL4030KEYPAD_NAME "omap_twl4030keypad"
+
+#ifndef CONFIG_TWL4030KEY_AUTORPT
+#define CONFIG_TWL4030KEY_AUTORPT 100
+#endif
+
+#define SCAN_RATE 		HZ/20
+
+/* 
+ * Key mapping for 2430 SDP board
+ */
+
+static int sdp2430_keymap[] = {
+	KEY(0, 0, KEY_LEFT),
+	KEY(0, 1, KEY_RIGHT),
+	KEY(0, 2, KEY_A),
+	KEY(0, 3, KEY_B),
+	KEY(0, 4, KEY_C),
+	KEY(1, 0, KEY_DOWN),
+	KEY(1, 1, KEY_UP),
+	KEY(1, 2, KEY_E),
+	KEY(1, 3, KEY_F),
+	KEY(1, 4, KEY_G),
+	KEY(2, 0, KEY_ENTER),
+	KEY(2, 1, KEY_I),
+	KEY(2, 2, KEY_J),
+	KEY(2, 3, KEY_K),
+	KEY(2, 4, KEY_3),
+	KEY(3, 0, KEY_M),
+	KEY(3, 1, KEY_N),
+	KEY(3, 2, KEY_O),
+	KEY(3, 3, KEY_P),
+	KEY(3, 4, KEY_Q),
+	KEY(4, 0, KEY_R),
+	KEY(4, 1, KEY_4),
+	KEY(4, 2, KEY_T),
+	KEY(4, 3, KEY_U),
+	KEY(4, 4, KEY_D),
+	KEY(5, 0, KEY_V),
+	KEY(5, 1, KEY_W),
+	KEY(5, 2, KEY_L),
+	KEY(5, 3, KEY_S),
+	KEY(5, 4, KEY_H),
+	0
+};
+
+#if (OMAP_TWL4030KEYPAD_LOG_LEVEL >= 1 )
+
+char *switch_name[NUM_ROWS][NUM_COLS] = {
+	{"S2_L", "S2_D", "S2_S", "S3", "S4", "S23"},
+	{"S2_R", "S2_U", "S5", "S6", "S7", "S24"},
+	{"S8", "S9", "S10", "S11", "S12", "S25"},
+	{"S13", "S14", "S15", "S16", "S17", "S26"},
+	{"S18", "S19", "S20", "S21", "S22", "S27"},
+};
+
+#endif
+
+/* Global variables */
+static int *keymap;
+static unsigned char keypad_state[NUM_ROWS];
+
+/* function templates */
+
+static struct input_dev *omap_twl4030kp;
+struct timer_list kptimer;
+static void omap_kp_timer(unsigned long);
+static void twl4030_keypad_scan(void);	
+struct work_struct timer_work;
+void twl4030_kp_work(void *data);
+void twl4030_timer_work(void *data);
+
+#if CONFIG_DPM
+
+static int omap_kp_probe(struct omap_dev *dev);
+static int omap_kp_suspend(struct omap_dev *dev, u32 state);
+static int omap_kp_resume(struct omap_dev *dev);
+
+/* Driver Information */
+static struct omap_driver omap_twl4030kp_driver = {
+	.devid = OMAP24xx_KP_DEVID,
+	.busid = OMAP_BUS_L4,
+	.probe = omap_kp_probe,
+	.suspend = omap_kp_suspend,
+	.resume = omap_kp_resume,
+	.drv = {
+		.name = OMAP_TWL4030KEYPAD_NAME,
+		},
+};
+
+/* Device Information */
+static struct omap_dev omap_twl4030kp_device = {
+	.name = OMAP_TWL4030KEYPAD_NAME,
+	.devid = OMAP24xx_KP_DEVID,
+	.busid = OMAP_BUS_L4,
+};
+
+#endif
+
+static int twl4030_kpread_u8(u32 module, u8 * data, u32 reg)
+{
+	int ret;
+	FN_IN;
+
+	ret = twl4030_i2c_read_u8(module, data, reg);
+	if (ret < 0) {
+		printk(KERN_WARNING
+		       "Could not read TWL4030 register %X - returned %d[%x]\n",
+		       reg, ret, ret);
+		return ret;
+	}
+
+	FN_OUT(ret);
+
+	return ret;
+}
+
+static int twl4030_kpwrite_u8(u32 module, u8 data, u32 reg)
+{
+	int ret;
+	ret = twl4030_i2c_write_u8(module, data, reg);
+	if (ret < 0) {
+		printk(KERN_WARNING
+		       "Could not write TWL4030 register %X - returned %d[%x]\n",
+		       reg, ret, ret);
+		return ret;
+	}
+	FN_OUT(ret);
+	return ret;
+}
+
+/** 
+* brief omap_kp_find_key
+* 
+* param col 
+* param row 
+* 
+* return 
+*/
+static inline int omap_kp_find_key(int col, int row)
+{
+	int i, key;
+
+	FN_IN;
+	key = KEY(col, row, 0);
+	for (i = 0; keymap[i] != 0; i++) {
+		if ((keymap[i] & KEYNUM_MASK) == key) {
+			return keymap[i] & ROWCOL_MASK;
+		}
+	}
+	FN_OUT(0);
+	return -EINVAL;
+}
+
+static void twl4030_keypad_scan(void){
+	unsigned char new_state[NUM_ROWS], changed, key_down = 0;
+	u8 col, row, spurious = 0;
+	u8 code_reg = REG_FULL_CODE_7_0;
+	int ret;
+
+	/* check for any changes */
+	ret =
+	    twl4030_i2c_read(TWL4030_MODULE_KEYPAD, new_state, code_reg,
+			     NUM_ROWS);
+	if (ret < 0) {
+		printk(KERN_WARNING
+		       "Could not read TWL4030 register %X - returned %d[%x]\n",
+		       code_reg, ret, ret);
+	}
+#if ( OMAP_TWL4030KEYPAD_LOG_LEVEL >= 2)
+	printk("\n ***************Full Code Registers Dump*****************");
+	for (row = 0; row < NUM_ROWS; row++)
+		printk("\n Full Code Register[%d] : %X", row, new_state[row]);
+	printk("\n");
+#endif
+
+	/* check for changes and print those */
+	for (row = 0; row < NUM_ROWS; row++) {
+		changed = new_state[row] ^ keypad_state[row];
+		key_down |= new_state[row];
+
+		D3("new_state[%d] : %d\tkeypad_state[%d]:%d\n", row,
+		   new_state[row], row, keypad_state[row]);
+
+		if (changed == 0)
+			continue;
+
+		for (col = 0; col < NUM_COLS; col++) {
+
+			int key;
+			if (!(changed & (1 << col)))
+				continue;
+
+			D1("key %s %s\n", switch_name[row][col],
+			   (new_state[row] & (1 << col)) ? "press" : "release");
+			key = omap_kp_find_key(col, row);
+			if (key < 0) {
+				printk(KERN_WARNING
+				       "omap-keypad: Spurious key event %d-%d\n",
+				       col, row);
+				/* We scan again after a couple of seconds */
+				spurious = 1;
+				continue;
+			}
+
+			input_report_key(omap_twl4030kp, key,
+					 new_state[row] & (1 << col));
+		}
+	}
+	if (key_down) {
+		/* some key is pressed - keep irq disabled and use timer
+		 * to poll for key release */
+		if (spurious)
+			mod_timer(&kptimer, jiffies + SCAN_RATE * 2);
+		else
+			mod_timer(&kptimer, jiffies + SCAN_RATE);
+	} 
+	memcpy(keypad_state, new_state, sizeof(keypad_state));
+}
+
+void twl4030_timer_work(void *data)
+{
+	FN_IN;
+	twl4030_keypad_scan();
+	FN_OUT(0);
+}
+
+void omap_kp_timer(unsigned long data)
+{
+	schedule_work(&timer_work);
+}
+
+/** 
+* brief do_kp_irq
+* 
+* param irq 
+* param dev_id 
+* param regs 
+*/
+static irqreturn_t do_kp_irq(int irq, void *dev_id, struct pt_regs *regs)
+{
+	u8 reg;
+	int ret;
+
+	FN_IN;
+
+	/* Mask keypad interrupts */
+	reg = KEYP_IMR1_MASK;
+	ret = twl4030_kpwrite_u8(TWL4030_MODULE_KEYPAD, reg, REG_KEYP_IMR1);
+	
+	/* Scan keypad for any changes
+	 * in keypad matrix.
+	 */
+	twl4030_keypad_scan();
+
+	/* Clear TWL4030 PIH interrupt */
+	ret = twl4030_kpread_u8(TWL4030_MODULE_KEYPAD, &reg, REG_KEYP_ISR1);
+
+	/* Enable interrupts */
+	reg = KEYP_IMR1_UNMASK;
+	ret = twl4030_kpwrite_u8(TWL4030_MODULE_KEYPAD, reg, REG_KEYP_IMR1);
+	FN_OUT(0);
+
+	return IRQ_HANDLED;
+}
+
+#if CONFIG_DPM
+/** 
+* brief omap_kp_suspend
+* 
+* param dev 
+* param state 
+* param level 
+* 
+* return 
+*/
+static int omap_kp_suspend(struct omap_dev *odev, u32 state)
+{
+
+	u8 reg;
+	int ret = 0;
+	FN_IN;
+
+	/*Disable timer and tasklet
+	 */
+
+	/* Disable all the interrupts
+	 * of T2 - keypad module
+	 */
+#if	BOARD_WAKE_SOURCE == SDP2430_TRITON_KEY_PRESS
+	reg = KEYP_IMR1_UNMASK;
+#else
+	reg = KEYP_IMR1_MASK;
+#endif
+	ret =
+		twl4030_kpwrite_u8(TWL4030_MODULE_KEYPAD, reg,
+				   REG_KEYP_IMR1);
+	del_timer_sync(&kptimer);
+	FN_OUT(ret);
+	return ret;
+}
+
+/** 
+* brief omap_kp_resume
+* 
+* param dev 
+* param level 
+* 
+* return 
+*/
+static int omap_kp_resume(struct omap_dev *odev)
+{
+	u8 reg;
+	int ret = 0;
+	FN_IN;
+
+	/* Enable timer and tasklet, driver is resumes now.
+	 */
+	/* Now it is safe to enable the keypad module interrupts */
+	reg = KEYP_IMR1_UNMASK;
+	ret =
+		twl4030_kpwrite_u8(TWL4030_MODULE_KEYPAD, reg,
+				   REG_KEYP_IMR1);
+	FN_OUT(ret);
+	return ret;
+}
+
+/* Registers keypad device with input sub system 
+ * and configures TWL4030 keypad registers 
+ * */
+
+/** 
+* brief omap_kp_probe
+* 
+* param dev 
+* 
+* return 
+*/
+static int omap_kp_probe(struct omap_dev *odev)
+{
+	FN_OUT(0);
+	return 0;
+}
+
+#endif
+
+/** 
+* brief omap_kp_init
+* 
+* return 
+*/
+static int __init omap_kp_init(void)
+{
+	u8 reg, i;
+	u8 code_reg = REG_FULL_CODE_7_0;
+	int ret = 0;
+#ifdef CONFIG_TWL4030KEYPAD_AUTORPT
+	int keyreptime = 0;
+#endif	
+	FN_IN;
+
+	omap_twl4030kp = input_allocate_device();
+		if (omap_twl4030kp == NULL) {
+		return -ENOMEM;
+	}
+
+
+#if CONFIG_DPM
+	if (omap_device_register(&omap_twl4030kp_device)) {
+		printk(KERN_ERR OMAP_TWL4030KEYPAD_NAME
+		       ": device register Failed ...!!!!\n");
+		goto exit_path1;
+	}
+
+	if (omap_driver_register(&omap_twl4030kp_driver)) {
+		printk(KERN_ERR OMAP_TWL4030KEYPAD_NAME
+		       ": driver register Failed ...!!!!\n");
+		goto exit_path2;
+	}
+#endif
+	keymap = sdp2430_keymap;
+
+	/* setup input device */
+	set_bit(EV_KEY, omap_twl4030kp->evbit);
+
+	/*Enable auto repeat feature of Linux input subsystem
+	 */
+
+	set_bit(EV_REP, omap_twl4030kp->evbit);
+	for (i = 0; keymap[i] != 0; i++)
+		set_bit(keymap[i] & 0x00ffffff, omap_twl4030kp->keybit);
+	omap_twl4030kp->name = OMAP_TWL4030KEYPAD_NAME;
+	input_register_device(omap_twl4030kp);
+
+	init_timer(&kptimer);
+	kptimer.function = omap_kp_timer;
+	
+	/* Since keypad driver uses I2C for reading
+	 * twl4030 keypad registers, tasklets cannot
+	 * be used.
+ 	 */ 	
+
+	INIT_WORK(&timer_work, twl4030_timer_work);
+
+#ifdef CONFIG_TWL4030KEYPAD_AUTORPT
+	keyreptime =
+	    (CONFIG_TWL4030KEY_AUTORPT) / (31.25 * 32 * 0.001) - 1;
+
+	/* Reset keypad module */
+	reg = 0;
+	ret = twl4030_kpwrite_u8(TWL4030_MODULE_KEYPAD, reg, REG_KEYP_CTRL_REG);
+	if (ret < 0)
+		goto exit_path4;
+
+	/* PARANOIA:
+	 *  mask all events - dont care abt result - should
+	 *  be done by default on a reset of KP module.. still..
+	 */
+	(void)twl4030_kpwrite_u8(TWL4030_MODULE_KEYPAD, 0xff, REG_KEYP_IMR1);
+
+	/* Set keypad control register to Normal operation, 
+	 * hardware decoding,hardware key auto repeat feature
+	 * and keypad power on*/
+
+	reg = KEYP_CTRL_REG_MASK_AUTORPT;
+#else
+
+	reg = KEYP_CTRL_REG_MASK_NOAUTORPT;
+
+#endif
+	ret = twl4030_kpwrite_u8(TWL4030_MODULE_KEYPAD, reg, REG_KEYP_CTRL_REG);
+	if (ret < 0)
+		goto exit_path3;
+
+	/* Set all events to Falling Edge detection */
+
+	reg = KEYP_EDR_MASK;
+	ret = twl4030_kpwrite_u8(TWL4030_MODULE_KEYPAD, reg, REG_KEYP_EDR);
+	if (ret < 0)
+		goto exit_path3;
+
+	/* Set Pre Scalar Field PTV to 4
+	 */
+
+	reg = BIT_LK_PTV_REG_PTV_M & (BIT_PTV_REG_PTV4 << BIT_LK_PTV_REG_PTV);
+
+#ifdef CONFIG_TWL4030KEYPAD_AUTORPT
+	/* Set 4 bit MSB auto repeat key value in PTV reg */
+
+	reg |= BIT_LK_PTV_REG_MSB_LK_M & ((keyreptime >> 8)
+					  << BIT_LK_PTV_REG_MSB_LK);
+#endif
+
+	ret = twl4030_kpwrite_u8(TWL4030_MODULE_KEYPAD, reg, REG_LK_PTV_REG);
+	if (ret < 0)
+		goto exit_path3;
+
+	/* Set key debounce time to 10 ms using equation
+	 * Tint = Tclk * (LOAD_TIM+1) * 2^(PTV+1)
+	 * Where Tclk = 31.25 us ( since kbd_if_clk is 32KHz)
+	 * PTV = 4 for all the operations.
+	 * 
+	 */
+	reg =
+	    BIT_KEY_DEB_REG_KEYP_DEB_M &
+	    (BIT_KEY_DEB9 << BIT_KEY_DEB_REG_KEYP_DEB);
+	reg = 0x3f;
+
+	ret = twl4030_kpwrite_u8(TWL4030_MODULE_KEYPAD, reg, REG_KEY_DEB_REG);
+	if (ret < 0)
+		goto exit_path3;
+
+#ifdef CONFIG_TWL4030KEYPAD_AUTORPT
+	reg = 0;
+	/* 
+	 * Set LSB 8 bit timer value for key auto repeat.
+	 * Use the above formula to compute the Timer value
+	 * Ex:
+	 * 100 ms , LOAD_TIM = 63
+	 * 200 ms , LOAD_TIM = c7
+	 * 300 ms , LOAD_TIM = 12B
+	 * 500 ms , LOAD_TIM = 1F3
+	 * 1 sec,   LOAD_TIM = 3E7
+	 * Default is set to 100 ms.
+	 */
+	reg =
+	    BIT_LONG_KEY_REG1_LSB_LK_M &
+	    (keyreptime << BIT_LONG_KEY_REG1_LSB_LK);
+
+	ret = twl4030_kpwrite_u8(TWL4030_MODULE_KEYPAD, reg, REG_LONG_KEY_REG1);
+	if (ret < 0)
+		goto exit_path3;
+#endif
+
+	/* Set SIH Ctrl register */
+
+	reg = KEYP_SIH_CTRL_MASK;
+	ret = twl4030_kpwrite_u8(TWL4030_MODULE_KEYPAD, reg, REG_KEYP_SIH_CTRL);
+	if (ret < 0)
+		goto exit_path3;
+
+	/* Actual Triton2 chip uses 2nd bit 
+	 * PIH register for keypad.
+	 * FPGA uses 1st bit of PIH.
+	 * Update for real hardware later
+	 * Once we have finished config of all regs, enable KP ISR
+	 * before unmasking the interrupt
+	 *
+	 * This ISR will always execute in kernel thread context because of
+	 * the need to access the TWL4030 over the I2C bus.  The SA_NODELAY
+	 * flag is passed to prevent the creation of a harmless but superfluous
+	 * IRQ thread in case the CONFIG_PREEMPT_HARDIRQS kernel configuration
+	 * option is enabled.
+	 */
+	ret = request_irq(TWL4030_MODIRQ_KEYPAD, do_kp_irq,
+		SA_INTERRUPT, "TWL4030 Keypad", omap_twl4030kp);
+	if (ret < 0) {
+		printk(KERN_INFO
+		       "request_irq failed for irq no=%d\n",
+		       TWL4030_MODIRQ_KEYPAD);
+		goto exit_path3;
+	} else {
+		/* Enable keypad module
+		 * interrupts now.
+		 * */
+		reg = KEYP_IMR1_UNMASK;
+		ret =
+		    twl4030_kpwrite_u8(TWL4030_MODULE_KEYPAD, reg,
+				       REG_KEYP_IMR1);
+		if (ret < 0) {
+			/* mask all events - dont care abt result */
+			(void)twl4030_kpwrite_u8(TWL4030_MODULE_KEYPAD, 0xff,
+						 REG_KEYP_IMR1);
+			goto exit_path4;
+		}
+	}
+
+#if (OMAP_TWL4030KEYPAD_LOG_LEVEL >= 1 )
+	printk
+	    ("********TWL4030 keypad module configuration registers dump*********\n");
+	twl4030_kpread_u8(TWL4030_MODULE_KEYPAD, &reg, REG_KEYP_CTRL_REG);
+	printk("Register REG_KEYP_CTRL_REG : %X\n", reg);
+	twl4030_kpread_u8(TWL4030_MODULE_KEYPAD, &reg, REG_KEYP_EDR);
+	printk("Register REG_KEYP_EDR: %X\n", reg);
+	twl4030_kpread_u8(TWL4030_MODULE_KEYPAD, &reg, REG_LK_PTV_REG);
+	printk("Register REG_LK_PTV_REG: %X\n", reg);
+	twl4030_kpread_u8(TWL4030_MODULE_KEYPAD, &reg, REG_KEY_DEB_REG);
+	printk("Register REG_KEY_DEB_REG: %X\n", reg);
+	twl4030_kpread_u8(TWL4030_MODULE_KEYPAD, &reg, REG_LONG_KEY_REG1);
+	printk("Register REG_LONG_KEY_REG1: %X\n", reg);
+	twl4030_kpread_u8(TWL4030_MODULE_KEYPAD, &reg, REG_KEYP_SIH_CTRL);
+	printk("Register REG_KEYP_SIH_CTRL: %X\n", reg);
+	twl4030_kpread_u8(TWL4030_MODULE_KEYPAD, &reg, REG_KEYP_IMR1);
+	printk("Register REG_KEYP_IMR1: %X\n", reg);
+	printk("****************END******************\n");
+#endif
+	/* Read initial state of 
+	 * keypad matrix.
+	 */
+	ret =
+	    twl4030_i2c_read(TWL4030_MODULE_KEYPAD, keypad_state, code_reg,
+			     NUM_ROWS);
+	if (ret < 0) {
+		printk(KERN_WARNING
+		       "Could not read TWL4030 register %X - returned %d[%x]\n",
+		       reg, ret, ret);
+		goto exit_path4;
+	}
+
+	FN_OUT(ret);
+	return (ret);
+      exit_path4:
+	free_irq(TWL4030_MODIRQ_KEYPAD, NULL);
+      exit_path3:
+	input_unregister_device(omap_twl4030kp);
+#if CONFIG_DPM
+      exit_path2:
+	omap_driver_unregister(&omap_twl4030kp_driver);
+      exit_path1:
+	omap_device_unregister(&omap_twl4030kp_device);
+#endif
+	return -ENODEV;
+}
+
+/* On Exit, Un register the device 
+ * and driver with the system
+ */
+
+static void __exit omap_kp_exit(void)
+{
+#if CONFIG_DPM
+	omap_driver_unregister(&omap_twl4030kp_driver);
+	omap_device_register(&omap_twl4030kp_device);
+#endif
+	free_irq(TWL4030_MODIRQ_KEYPAD, NULL);
+	del_timer_sync(&kptimer);
+	/* unregister everything */
+	input_unregister_device(omap_twl4030kp);
+	FN_OUT(0);
+}
+
+module_init(omap_kp_init);
+module_exit(omap_kp_exit);
+MODULE_AUTHOR("TI");
+MODULE_DESCRIPTION("OMAP TWL4030 Keypad Driver");
+MODULE_LICENSE("GPL");
diff -purN linux-omap/drivers/input/keyboard/twl4030-keypad.h lin_for_twl/drivers/input/keyboard/twl4030-keypad.h
--- linux-omap/drivers/input/keyboard/twl4030-keypad.h	1969-12-31 18:00:00.000000000 -0600
+++ lin_for_twl/drivers/input/keyboard/twl4030-keypad.h	2007-02-27 13:26:24.000000000 -0600
@@ -0,0 +1,355 @@
+/*
+ * linux/drivers/input/twl4030-keypad.h - Register defines for TWL4030 keypad module
+ *
+ * Copyright (C) 2005 Texas Instruments, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#ifndef __TWL4030_KEYPAD_H__
+#define __TWL4030_KEYPAD_H__
+
+/****************************************
+ *  keypad                           
+ ****************************************/
+
+/**** Register Definitions */
+
+#define REG_KEYP_CTRL_REG                        (0x0)
+#define REG_KEY_DEB_REG                          (0x1)
+#define REG_LONG_KEY_REG1                        (0x2)
+#define REG_LK_PTV_REG                           (0x3)
+#define REG_TIME_OUT_REG1                        (0x4)
+#define REG_TIME_OUT_REG2                        (0x5)
+#define REG_KBC_REG                              (0x6)
+#define REG_KBR_REG                              (0x7)
+#define REG_KEYP_SMS                             (0x8)
+#define REG_FULL_CODE_7_0                        (0x9)
+#define REG_FULL_CODE_15_8                       (0xA)
+#define REG_FULL_CODE_23_16                      (0xB)
+#define REG_FULL_CODE_31_24                      (0xC)
+#define REG_FULL_CODE_39_32                      (0xD)
+#define REG_FULL_CODE_47_40                      (0xE)
+#define REG_FULL_CODE_55_48                      (0xF)
+#define REG_FULL_CODE_63_56                      (0x10)
+#define REG_KEYP_ISR1                            (0x11)
+#define REG_KEYP_IMR1                            (0x12)
+#define REG_KEYP_ISR2                            (0x13)
+#define REG_KEYP_IMR2                            (0x14)
+#define REG_KEYP_SIR                             (0x15)
+#define REG_KEYP_EDR                             (0x16)
+#define REG_KEYP_SIH_CTRL                        (0x17)
+
+/**** BitField Definitions */
+
+/* KEYP_CTRL_REG Fields */
+#define BIT_KEYP_CTRL_REG_SOFT_NRST              (0x000)
+#define BIT_KEYP_CTRL_REG_SOFT_NRST_M            (0x00000001)
+#define BIT_KEYP_CTRL_REG_SOFTMODEN              (0x001)
+#define BIT_KEYP_CTRL_REG_SOFTMODEN_M            (0x00000002)
+#define BIT_KEYP_CTRL_REG_LK_EN                  (0x002)
+#define BIT_KEYP_CTRL_REG_LK_EN_M                (0x00000004)
+#define BIT_KEYP_CTRL_REG_TOE_EN                 (0x003)
+#define BIT_KEYP_CTRL_REG_TOE_EN_M               (0x00000008)
+#define BIT_KEYP_CTRL_REG_TOLE_EN                (0x004)
+#define BIT_KEYP_CTRL_REG_TOLE_EN_M              (0x00000010)
+#define BIT_KEYP_CTRL_REG_RP_EN                  (0x005)
+#define BIT_KEYP_CTRL_REG_RP_EN_M                (0x00000020)
+#define BIT_KEYP_CTRL_REG_KBD_ON                 (0x006)
+#define BIT_KEYP_CTRL_REG_KBD_ON_M               (0x00000040)
+
+#define KEYP_CTRL_REG_MASK_AUTORPT		 BIT_KEYP_CTRL_REG_SOFT_NRST_M | BIT_KEYP_CTRL_REG_RP_EN_M |\
+						 BIT_KEYP_CTRL_REG_SOFTMODEN_M | BIT_KEYP_CTRL_REG_KBD_ON_M
+
+#define KEYP_CTRL_REG_MASK_NOAUTORPT		 BIT_KEYP_CTRL_REG_SOFT_NRST_M | BIT_KEYP_CTRL_REG_SOFTMODEN_M |\
+						 BIT_KEYP_CTRL_REG_KBD_ON_M
+						 
+/* KEY_DEB_REG Fields */
+#define BIT_KEY_DEB_REG_KEYP_DEB                 (0x000)
+#define BIT_KEY_DEB_REG_KEYP_DEB_M               (0x0000003F)
+#define BIT_KEY_DEB9				 (0x9)
+/* LONG_KEY_REG1 Fields */
+#define BIT_LONG_KEY_REG1_LSB_LK                 (0x000)
+#define BIT_LONG_KEY_REG1_LSB_LK_M               (0x000000FF)
+#define BIT_LONG_KEY_100MS			 (0x63)
+/* LK_PTV_REG Fields */
+#define BIT_LK_PTV_REG_MSB_LK                    (0x000)
+#define BIT_LK_PTV_REG_MSB_LK_M                  (0x0000000F)
+#define BIT_LK_PTV_REG_PTV                       (0x005)
+#define BIT_LK_PTV_REG_PTV_M                     (0x000000E0)
+#define BIT_PTV_REG_PTV4			 (0x4)
+/* TIME_OUT_REG1 Fields */
+#define BIT_TIME_OUT_REG1_LSB_TO                 (0x000)
+#define BIT_TIME_OUT_REG1_LSB_TO_M               (0x000000FF)
+/* TIME_OUT_REG2 Fields */
+#define BIT_TIME_OUT_REG2_MSB_TO                 (0x000)
+#define BIT_TIME_OUT_REG2_MSB_TO_M               (0x000000FF)
+/* KBC_REG Fields */
+#define BIT_KBC_REG_KBC0                         (0x000)
+#define BIT_KBC_REG_KBC0_M                       (0x00000001)
+#define BIT_KBC_REG_KBC1                         (0x001)
+#define BIT_KBC_REG_KBC1_M                       (0x00000002)
+#define BIT_KBC_REG_KBC2                         (0x002)
+#define BIT_KBC_REG_KBC2_M                       (0x00000004)
+#define BIT_KBC_REG_KBC3                         (0x003)
+#define BIT_KBC_REG_KBC3_M                       (0x00000008)
+#define BIT_KBC_REG_KBC4                         (0x004)
+#define BIT_KBC_REG_KBC4_M                       (0x00000010)
+#define BIT_KBC_REG_KBC5                         (0x005)
+#define BIT_KBC_REG_KBC5_M                       (0x00000020)
+#define BIT_KBC_REG_KBC6                         (0x006)
+#define BIT_KBC_REG_KBC6_M                       (0x00000040)
+#define BIT_KBC_REG_KBC7                         (0x007)
+#define BIT_KBC_REG_KBC7_M                       (0x00000080)
+/* KBR_REG Fields */
+#define BIT_KBR_REG_KBR0                         (0x000)
+#define BIT_KBR_REG_KBR0_M                       (0x00000001)
+#define BIT_KBR_REG_KBR1                         (0x001)
+#define BIT_KBR_REG_KBR1_M                       (0x00000002)
+#define BIT_KBR_REG_KBR2                         (0x002)
+#define BIT_KBR_REG_KBR2_M                       (0x00000004)
+#define BIT_KBR_REG_KBR3                         (0x003)
+#define BIT_KBR_REG_KBR3_M                       (0x00000008)
+#define BIT_KBR_REG_KBR4                         (0x004)
+#define BIT_KBR_REG_KBR4_M                       (0x00000010)
+#define BIT_KBR_REG_KBR5                         (0x005)
+#define BIT_KBR_REG_KBR5_M                       (0x00000020)
+#define BIT_KBR_REG_KBR6                         (0x006)
+#define BIT_KBR_REG_KBR6_M                       (0x00000040)
+#define BIT_KBR_REG_KBR7                         (0x007)
+#define BIT_KBR_REG_KBR7_M                       (0x00000080)
+/* KEYP_SMS Fields */
+#define BIT_KEYP_SMS_STMSTS                      (0x000)
+#define BIT_KEYP_SMS_STMSTS_M                    (0x0000000F)
+#define BIT_KEYP_SMS_SIR_EN                      (0x004)
+#define BIT_KEYP_SMS_SIR_EN_M                    (0x00000010)
+#define BIT_KEYP_SMS_MISS_EN                     (0x005)
+#define BIT_KEYP_SMS_MISS_EN_M                   (0x00000020)
+/* FULL_CODE_7_0 Fields */
+#define BIT_FULL_CODE_7_0_FULL_CODE_K0           (0x000)
+#define BIT_FULL_CODE_7_0_FULL_CODE_K0_M         (0x00000001)
+#define BIT_FULL_CODE_7_0_FULL_CODE_K1           (0x001)
+#define BIT_FULL_CODE_7_0_FULL_CODE_K1_M         (0x00000002)
+#define BIT_FULL_CODE_7_0_FULL_CODE_K2           (0x002)
+#define BIT_FULL_CODE_7_0_FULL_CODE_K2_M         (0x00000004)
+#define BIT_FULL_CODE_7_0_FULL_CODE_K3           (0x003)
+#define BIT_FULL_CODE_7_0_FULL_CODE_K3_M         (0x00000008)
+#define BIT_FULL_CODE_7_0_FULL_CODE_K4           (0x004)
+#define BIT_FULL_CODE_7_0_FULL_CODE_K4_M         (0x00000010)
+#define BIT_FULL_CODE_7_0_FULL_CODE_K5           (0x005)
+#define BIT_FULL_CODE_7_0_FULL_CODE_K5_M         (0x00000020)
+#define BIT_FULL_CODE_7_0_FULL_CODE_K6           (0x006)
+#define BIT_FULL_CODE_7_0_FULL_CODE_K6_M         (0x00000040)
+#define BIT_FULL_CODE_7_0_FULL_CODE_K7           (0x007)
+#define BIT_FULL_CODE_7_0_FULL_CODE_K7_M         (0x00000080)
+/* FULL_CODE_15_8 Fields */
+#define BIT_FULL_CODE_15_8_FULL_CODE_K8          (0x000)
+#define BIT_FULL_CODE_15_8_FULL_CODE_K8_M        (0x00000001)
+#define BIT_FULL_CODE_15_8_FULL_CODE_K9          (0x001)
+#define BIT_FULL_CODE_15_8_FULL_CODE_K9_M        (0x00000002)
+#define BIT_FULL_CODE_15_8_FULL_CODE_K10         (0x002)
+#define BIT_FULL_CODE_15_8_FULL_CODE_K10_M       (0x00000004)
+#define BIT_FULL_CODE_15_8_FULL_CODE_K11         (0x003)
+#define BIT_FULL_CODE_15_8_FULL_CODE_K11_M       (0x00000008)
+#define BIT_FULL_CODE_15_8_FULL_CODE_K12         (0x004)
+#define BIT_FULL_CODE_15_8_FULL_CODE_K12_M       (0x00000010)
+#define BIT_FULL_CODE_15_8_FULL_CODE_K13         (0x005)
+#define BIT_FULL_CODE_15_8_FULL_CODE_K13_M       (0x00000020)
+#define BIT_FULL_CODE_15_8_FULL_CODE_K14         (0x006)
+#define BIT_FULL_CODE_15_8_FULL_CODE_K14_M       (0x00000040)
+#define BIT_FULL_CODE_15_8_FULL_CODE_K15         (0x007)
+#define BIT_FULL_CODE_15_8_FULL_CODE_K15_M       (0x00000080)
+/* FULL_CODE_23_16 Fields */
+#define BIT_FULL_CODE_23_16_FULL_CODE_K16        (0x000)
+#define BIT_FULL_CODE_23_16_FULL_CODE_K16_M      (0x00000001)
+#define BIT_FULL_CODE_23_16_FULL_CODE_K17        (0x001)
+#define BIT_FULL_CODE_23_16_FULL_CODE_K17_M      (0x00000002)
+#define BIT_FULL_CODE_23_16_FULL_CODE_K18        (0x002)
+#define BIT_FULL_CODE_23_16_FULL_CODE_K18_M      (0x00000004)
+#define BIT_FULL_CODE_23_16_FULL_CODE_K19        (0x003)
+#define BIT_FULL_CODE_23_16_FULL_CODE_K19_M      (0x00000008)
+#define BIT_FULL_CODE_23_16_FULL_CODE_K20        (0x004)
+#define BIT_FULL_CODE_23_16_FULL_CODE_K20_M      (0x00000010)
+#define BIT_FULL_CODE_23_16_FULL_CODE_K21        (0x005)
+#define BIT_FULL_CODE_23_16_FULL_CODE_K21_M      (0x00000020)
+#define BIT_FULL_CODE_23_16_FULL_CODE_K22        (0x006)
+#define BIT_FULL_CODE_23_16_FULL_CODE_K22_M      (0x00000040)
+#define BIT_FULL_CODE_23_16_FULL_CODE_K23        (0x007)
+#define BIT_FULL_CODE_23_16_FULL_CODE_K23_M      (0x00000080)
+/* FULL_CODE_31_24 Fields */
+#define BIT_FULL_CODE_31_24_FULL_CODE_K24        (0x000)
+#define BIT_FULL_CODE_31_24_FULL_CODE_K24_M      (0x00000001)
+#define BIT_FULL_CODE_31_24_FULL_CODE_K25        (0x001)
+#define BIT_FULL_CODE_31_24_FULL_CODE_K25_M      (0x00000002)
+#define BIT_FULL_CODE_31_24_FULL_CODE_K26        (0x002)
+#define BIT_FULL_CODE_31_24_FULL_CODE_K26_M      (0x00000004)
+#define BIT_FULL_CODE_31_24_FULL_CODE_K27        (0x003)
+#define BIT_FULL_CODE_31_24_FULL_CODE_K27_M      (0x00000008)
+#define BIT_FULL_CODE_31_24_FULL_CODE_K28        (0x004)
+#define BIT_FULL_CODE_31_24_FULL_CODE_K28_M      (0x00000010)
+#define BIT_FULL_CODE_31_24_FULL_CODE_K29        (0x005)
+#define BIT_FULL_CODE_31_24_FULL_CODE_K29_M      (0x00000020)
+#define BIT_FULL_CODE_31_24_FULL_CODE_K30        (0x006)
+#define BIT_FULL_CODE_31_24_FULL_CODE_K30_M      (0x00000040)
+#define BIT_FULL_CODE_31_24_FULL_CODE_K31        (0x007)
+#define BIT_FULL_CODE_31_24_FULL_CODE_K31_M      (0x00000080)
+/* FULL_CODE_39_32 Fields */
+#define BIT_FULL_CODE_39_32_FULL_CODE_K32        (0x000)
+#define BIT_FULL_CODE_39_32_FULL_CODE_K32_M      (0x00000001)
+#define BIT_FULL_CODE_39_32_FULL_CODE_K33        (0x001)
+#define BIT_FULL_CODE_39_32_FULL_CODE_K33_M      (0x00000002)
+#define BIT_FULL_CODE_39_32_FULL_CODE_K34        (0x002)
+#define BIT_FULL_CODE_39_32_FULL_CODE_K34_M      (0x00000004)
+#define BIT_FULL_CODE_39_32_FULL_CODE_K35        (0x003)
+#define BIT_FULL_CODE_39_32_FULL_CODE_K35_M      (0x00000008)
+#define BIT_FULL_CODE_39_32_FULL_CODE_K36        (0x004)
+#define BIT_FULL_CODE_39_32_FULL_CODE_K36_M      (0x00000010)
+#define BIT_FULL_CODE_39_32_FULL_CODE_K37        (0x005)
+#define BIT_FULL_CODE_39_32_FULL_CODE_K37_M      (0x00000020)
+#define BIT_FULL_CODE_39_32_FULL_CODE_K38        (0x006)
+#define BIT_FULL_CODE_39_32_FULL_CODE_K38_M      (0x00000040)
+#define BIT_FULL_CODE_39_32_FULL_CODE_K39        (0x007)
+#define BIT_FULL_CODE_39_32_FULL_CODE_K39_M      (0x00000080)
+/* FULL_CODE_47_40 Fields */
+#define BIT_FULL_CODE_47_40_FULL_CODE_K40        (0x000)
+#define BIT_FULL_CODE_47_40_FULL_CODE_K40_M      (0x00000001)
+#define BIT_FULL_CODE_47_40_FULL_CODE_K41        (0x001)
+#define BIT_FULL_CODE_47_40_FULL_CODE_K41_M      (0x00000002)
+#define BIT_FULL_CODE_47_40_FULL_CODE_K42        (0x002)
+#define BIT_FULL_CODE_47_40_FULL_CODE_K42_M      (0x00000004)
+#define BIT_FULL_CODE_47_40_FULL_CODE_K43        (0x003)
+#define BIT_FULL_CODE_47_40_FULL_CODE_K43_M      (0x00000008)
+#define BIT_FULL_CODE_47_40_FULL_CODE_K44        (0x004)
+#define BIT_FULL_CODE_47_40_FULL_CODE_K44_M      (0x00000010)
+#define BIT_FULL_CODE_47_40_FULL_CODE_K45        (0x005)
+#define BIT_FULL_CODE_47_40_FULL_CODE_K45_M      (0x00000020)
+#define BIT_FULL_CODE_47_40_FULL_CODE_K46        (0x006)
+#define BIT_FULL_CODE_47_40_FULL_CODE_K46_M      (0x00000040)
+#define BIT_FULL_CODE_47_40_FULL_CODE_K47        (0x007)
+#define BIT_FULL_CODE_47_40_FULL_CODE_K47_M      (0x00000080)
+/* FULL_CODE_55_48 Fields */
+#define BIT_FULL_CODE_55_48_FULL_CODE_K48        (0x000)
+#define BIT_FULL_CODE_55_48_FULL_CODE_K48_M      (0x00000001)
+#define BIT_FULL_CODE_55_48_FULL_CODE_K49        (0x001)
+#define BIT_FULL_CODE_55_48_FULL_CODE_K49_M      (0x00000002)
+#define BIT_FULL_CODE_55_48_FULL_CODE_K50        (0x002)
+#define BIT_FULL_CODE_55_48_FULL_CODE_K50_M      (0x00000004)
+#define BIT_FULL_CODE_55_48_FULL_CODE_K51        (0x003)
+#define BIT_FULL_CODE_55_48_FULL_CODE_K51_M      (0x00000008)
+#define BIT_FULL_CODE_55_48_FULL_CODE_K52        (0x004)
+#define BIT_FULL_CODE_55_48_FULL_CODE_K52_M      (0x00000010)
+#define BIT_FULL_CODE_55_48_FULL_CODE_K53        (0x005)
+#define BIT_FULL_CODE_55_48_FULL_CODE_K53_M      (0x00000020)
+#define BIT_FULL_CODE_55_48_FULL_CODE_K54        (0x006)
+#define BIT_FULL_CODE_55_48_FULL_CODE_K54_M      (0x00000040)
+#define BIT_FULL_CODE_55_48_FULL_CODE_K55        (0x007)
+#define BIT_FULL_CODE_55_48_FULL_CODE_K55_M      (0x00000080)
+/* FULL_CODE_63_56 Fields */
+#define BIT_FULL_CODE_63_56_FULL_CODE_K56        (0x000)
+#define BIT_FULL_CODE_63_56_FULL_CODE_K56_M      (0x00000001)
+#define BIT_FULL_CODE_63_56_FULL_CODE_K57        (0x001)
+#define BIT_FULL_CODE_63_56_FULL_CODE_K57_M      (0x00000002)
+#define BIT_FULL_CODE_63_56_FULL_CODE_K58        (0x002)
+#define BIT_FULL_CODE_63_56_FULL_CODE_K58_M      (0x00000004)
+#define BIT_FULL_CODE_63_56_FULL_CODE_K59        (0x003)
+#define BIT_FULL_CODE_63_56_FULL_CODE_K59_M      (0x00000008)
+#define BIT_FULL_CODE_63_56_FULL_CODE_K60        (0x004)
+#define BIT_FULL_CODE_63_56_FULL_CODE_K60_M      (0x00000010)
+#define BIT_FULL_CODE_63_56_FULL_CODE_K61        (0x005)
+#define BIT_FULL_CODE_63_56_FULL_CODE_K61_M      (0x00000020)
+#define BIT_FULL_CODE_63_56_FULL_CODE_K62        (0x006)
+#define BIT_FULL_CODE_63_56_FULL_CODE_K62_M      (0x00000040)
+#define BIT_FULL_CODE_63_56_FULL_CODE_K63        (0x007)
+#define BIT_FULL_CODE_63_56_FULL_CODE_K63_M      (0x00000080)
+/* KEYP_ISR1 Fields */
+#define BIT_KEYP_ISR1_ITKPISR1                   (0x000)
+#define BIT_KEYP_ISR1_ITKPISR1_M                 (0x00000001)
+#define BIT_KEYP_ISR1_ITLKISR1                   (0x001)
+#define BIT_KEYP_ISR1_ITLKISR1_M                 (0x00000002)
+#define BIT_KEYP_ISR1_ITTOISR1                   (0x002)
+#define BIT_KEYP_ISR1_ITTOISR1_M                 (0x00000004)
+#define BIT_KEYP_ISR1_ITMISR1                    (0x003)
+#define BIT_KEYP_ISR1_ITMISR1_M                  (0x00000008)
+#define KEYP_ISR1_CLEAR                          (0x0F)						 
+/* KEYP_IMR1 Fields */
+#define BIT_KEYP_IMR1_ITKPIMR1                   (0x000)
+#define BIT_KEYP_IMR1_ITKPIMR1_M                 (0x00000001)
+#define BIT_KEYP_IMR1_ITLKIMR1                   (0x001)
+#define BIT_KEYP_IMR1_ITLKIMR1_M                 (0x00000002)
+#define BIT_KEYP_IMR1_ITTOIMR1                   (0x002)
+#define BIT_KEYP_IMR1_ITTOIMR1_M                 (0x00000004)
+#define BIT_KEYP_IMR1_ITMISIMR1                  (0x003)
+#define BIT_KEYP_IMR1_ITMISIMR1_M                (0x00000008)
+#define KEYP_IMR1_MASK				 (0x0F)
+#define KEYP_IMR1_UNMASK			 (0x00)			 
+/* KEYP_ISR2 Fields */
+#define BIT_KEYP_ISR2_ITKPISR2                   (0x000)
+#define BIT_KEYP_ISR2_ITKPISR2_M                 (0x00000001)
+#define BIT_KEYP_ISR2_ITLKISR2                   (0x001)
+#define BIT_KEYP_ISR2_ITLKISR2_M                 (0x00000002)
+#define BIT_KEYP_ISR2_ITTOISR2                   (0x002)
+#define BIT_KEYP_ISR2_ITTOISR2_M                 (0x00000004)
+#define BIT_KEYP_ISR2_ITMISR2                    (0x003)
+#define BIT_KEYP_ISR2_ITMISR2_M                  (0x00000008)
+/* KEYP_IMR2 Fields */
+#define BIT_KEYP_IMR2_ITKPIMR2                   (0x000)
+#define BIT_KEYP_IMR2_ITKPIMR2_M                 (0x00000001)
+#define BIT_KEYP_IMR2_ITLKIMR2                   (0x001)
+#define BIT_KEYP_IMR2_ITLKIMR2_M                 (0x00000002)
+#define BIT_KEYP_IMR2_ITTOIMR2                   (0x002)
+#define BIT_KEYP_IMR2_ITTOIMR2_M                 (0x00000004)
+#define BIT_KEYP_IMR2_ITMISIMR2                  (0x003)
+#define BIT_KEYP_IMR2_ITMISIMR2_M                (0x00000008)
+/* KEYP_SIR Fields */
+#define BIT_KEYP_SIR_ITKPSIR                     (0x000)
+#define BIT_KEYP_SIR_ITKPSIR_M                   (0x00000001)
+#define BIT_KEYP_SIR_ITLKSIR                     (0x001)
+#define BIT_KEYP_SIR_ITLKSIR_M                   (0x00000002)
+#define BIT_KEYP_SIR_ITTOSIR                     (0x002)
+#define BIT_KEYP_SIR_ITTOSIR_M                   (0x00000004)
+#define BIT_KEYP_SIR_ITMISSIR                    (0x003)
+#define BIT_KEYP_SIR_ITMISSIR_M                  (0x00000008)
+/* KEYP_EDR Fields */
+#define BIT_KEYP_EDR_ITKPFALLING                 (0x000)
+#define BIT_KEYP_EDR_ITKPFALLING_M               (0x00000001)
+#define BIT_KEYP_EDR_ITKPRISING                  (0x001)
+#define BIT_KEYP_EDR_ITKPRISING_M                (0x00000002)
+#define BIT_KEYP_EDR_ITLKFALLING                 (0x002)
+#define BIT_KEYP_EDR_ITLKFALLING_M               (0x00000004)
+#define BIT_KEYP_EDR_ITLKRISING                  (0x003)
+#define BIT_KEYP_EDR_ITLKRISING_M                (0x00000008)
+#define BIT_KEYP_EDR_ITTOFALLING                 (0x004)
+#define BIT_KEYP_EDR_ITTOFALLING_M               (0x00000010)
+#define BIT_KEYP_EDR_ITTORISING                  (0x005)
+#define BIT_KEYP_EDR_ITTORISING_M                (0x00000020)
+#define BIT_KEYP_EDR_ITMISFALLING                (0x006)
+#define BIT_KEYP_EDR_ITMISFALLING_M              (0x00000040)
+#define BIT_KEYP_EDR_ITMISRISING                 (0x007)
+#define BIT_KEYP_EDR_ITMISRISING_M               (0x00000080)
+
+#define KEYP_EDR_MASK				 BIT_KEYP_EDR_ITKPFALLING_M | BIT_KEYP_EDR_ITLKFALLING_M |\
+						 BIT_KEYP_EDR_ITTOFALLING_M | BIT_KEYP_EDR_ITMISFALLING_M
+
+/* KEYP_SIH_CTRL Fields */
+#define BIT_KEYP_SIH_CTRL_EXCLEN                 (0x000)
+#define BIT_KEYP_SIH_CTRL_EXCLEN_M               (0x00000001)
+#define BIT_KEYP_SIH_CTRL_PENDDIS                (0x001)
+#define BIT_KEYP_SIH_CTRL_PENDDIS_M              (0x00000002)
+#define BIT_KEYP_SIH_CTRL_COR                    (0x002)
+#define BIT_KEYP_SIH_CTRL_COR_M                  (0x00000004)
+#define KEYP_SIH_CTRL_MASK                       (0x04);			
+					
+						 
+#endif		/* End of __TWL4030-KEYPAD_H__ */
+

[-- Attachment #4: arch_mach2.diff --]
[-- Type: application/octet-stream, Size: 1038 bytes --]

diff -purN linux-omap/arch/arm/plat-omap/devices.c lin_for_twl/arch/arm/plat-omap/devices.c
--- linux-omap/arch/arm/plat-omap/devices.c     2006-12-17 08:56:39.000000000 -0600
+++ lin_for_twl/arch/arm/plat-omap/devices.c    2007-02-27 16:33:59.000000000 -0600
@@ -509,7 +509,7 @@ static int __init omap_init_devices(void
        omap_init_wdt();
        omap_init_rng();
 #endif
-       omap_init_i2c();
+       //omap_init_i2c();
        return 0;
 }
 arch_initcall(omap_init_devices);
 
diff -purN linux-omap/arch/arm/mach-omap2/devices.c lin_for_twl/arch/arm/mach-omap2/devices.c
--- linux-omap/arch/arm/mach-omap2/devices.c	2006-11-28 09:59:29.000000000 -0600
+++ lin_for_twl/arch/arm/mach-omap2/devices.c	2007-02-27 16:49:14.000000000 -0600
@@ -208,7 +208,7 @@ static int __init omap2_init_devices(voi
 	/* please keep these calls, and their implementations above,
 	 * in alphabetical order so they're easier to sort through.
 	 */
-	omap_init_i2c();
+	//omap_init_i2c();
 	omap_init_mbox();
 	omap_init_mcspi();
 	omap_init_sti();

[-- Attachment #5: Type: text/plain, Size: 0 bytes --]



^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2007-02-28  1:05 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-02-16 11:25 I2C TWL4030 Keypad Ram
2007-02-16 14:31 ` G, Manjunath Kondaiah
     [not found]   ` <8bf247760702160650s62d2b401lad8746881aedd2aa@mail.gmail.com>
2007-02-16 15:08     ` Ram
2007-02-16 15:38       ` Syed Mohammed, Khasim
2007-02-17 13:45 ` Nishanth Menon
     [not found]   ` <8bf247760702170604h5b2e210cibe4de58d4f898d74@mail.gmail.com>
2007-02-17 14:08     ` Nishanth Menon
2007-02-18  8:00       ` Setting the default state (high or low) of a pin zil iram
2007-02-26 17:38 ` I2C TWL4030 Keypad Cantu Castillo, Arturo
2007-02-27  6:20   ` Ram
2007-02-27 15:09     ` Syed Mohammed, Khasim
2007-02-28  1:00     ` Syed Mohammed, Khasim
2007-02-28  1:02 Syed Mohammed, Khasim
2007-02-28  1:05 Syed Mohammed, Khasim

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.