summaryrefslogtreecommitdiff
path: root/packages/linux/linux-omap2-git/omap3evm
diff options
context:
space:
mode:
authorMichael Lauer <mickey@vanille-media.de>2008-07-17 00:06:49 +0000
committerMichael Lauer <mickey@vanille-media.de>2008-07-17 00:06:49 +0000
commite5a07e89eee07991812965e5de9855524326046d (patch)
treeaf0292e04acbd90cec81e21a5c10b76731ed7bba /packages/linux/linux-omap2-git/omap3evm
parentaf568c07872e91924a320060b9b651ad23efc67c (diff)
parentce10c417ad24f7d9d1db3e63a076d56ac9143252 (diff)
merge of '4c6f4640a8b948badde77deaaebbfc2c9959ecae'
and 'e5e5a9814f67f07864e0b56012257f49ace89669'
Diffstat (limited to 'packages/linux/linux-omap2-git/omap3evm')
-rw-r--r--packages/linux/linux-omap2-git/omap3evm/0001-omap3-cpuidle.patch900
-rw-r--r--packages/linux/linux-omap2-git/omap3evm/0002-omap3-cpuidle.patch176
-rw-r--r--packages/linux/linux-omap2-git/omap3evm/defconfig177
-rw-r--r--packages/linux/linux-omap2-git/omap3evm/no-empty-flash-warnings.patch15
-rw-r--r--packages/linux/linux-omap2-git/omap3evm/soc.patch1154
-rw-r--r--packages/linux/linux-omap2-git/omap3evm/timer-suppression.patch43
-rw-r--r--packages/linux/linux-omap2-git/omap3evm/touchscreen.patch22
7 files changed, 1888 insertions, 599 deletions
diff --git a/packages/linux/linux-omap2-git/omap3evm/0001-omap3-cpuidle.patch b/packages/linux/linux-omap2-git/omap3evm/0001-omap3-cpuidle.patch
index 28b1ef2214..cdc9447b4c 100644
--- a/packages/linux/linux-omap2-git/omap3evm/0001-omap3-cpuidle.patch
+++ b/packages/linux/linux-omap2-git/omap3evm/0001-omap3-cpuidle.patch
@@ -1,450 +1,450 @@
-From: "Rajendra Nayak" <rnayak@ti.com>
-To: <linux-omap@vger.kernel.org>
-Subject: [PATCH 01/02] OMAP3 CPUidle driver
-Date: Tue, 10 Jun 2008 12:39:00 +0530
-
-This patch adds the OMAP3 cpuidle driver. Irq enable/disable is done in the core cpuidle driver
-before it queries the governor for the next state.
-
-Signed-off-by: Rajendra Nayak <rnayak@ti.com>
-
----
- arch/arm/mach-omap2/Makefile | 2
- arch/arm/mach-omap2/cpuidle34xx.c | 293 ++++++++++++++++++++++++++++++++++++++
- arch/arm/mach-omap2/cpuidle34xx.h | 51 ++++++
- arch/arm/mach-omap2/pm34xx.c | 5
- drivers/cpuidle/cpuidle.c | 10 +
- 5 files changed, 359 insertions(+), 2 deletions(-)
-
-Index: linux-omap-2.6/arch/arm/mach-omap2/Makefile
-===================================================================
---- linux-omap-2.6.orig/arch/arm/mach-omap2/Makefile 2008-06-09 20:15:33.855303920 +0530
-+++ linux-omap-2.6/arch/arm/mach-omap2/Makefile 2008-06-09 20:15:39.569121361 +0530
-@@ -20,7 +20,7 @@ obj-y += pm.o
- obj-$(CONFIG_ARCH_OMAP2) += pm24xx.o
- obj-$(CONFIG_ARCH_OMAP2420) += sleep242x.o
- obj-$(CONFIG_ARCH_OMAP2430) += sleep243x.o
--obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.o
-+obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.o cpuidle34xx.o
- obj-$(CONFIG_PM_DEBUG) += pm-debug.o
- endif
-
-Index: linux-omap-2.6/arch/arm/mach-omap2/cpuidle34xx.c
-===================================================================
---- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ linux-omap-2.6/arch/arm/mach-omap2/cpuidle34xx.c 2008-06-10 11:41:27.644820323 +0530
-@@ -0,0 +1,293 @@
-+/*
-+ * linux/arch/arm/mach-omap2/cpuidle34xx.c
-+ *
-+ * OMAP3 CPU IDLE Routines
-+ *
-+ * Copyright (C) 2007-2008 Texas Instruments, Inc.
-+ * Rajendra Nayak <rnayak@ti.com>
-+ *
-+ * Copyright (C) 2007 Texas Instruments, Inc.
-+ * Karthik Dasu <karthik-dp@ti.com>
-+ *
-+ * Copyright (C) 2006 Nokia Corporation
-+ * Tony Lindgren <tony@atomide.com>
-+ *
-+ * Copyright (C) 2005 Texas Instruments, Inc.
-+ * Richard Woodruff <r-woodruff2@ti.com>
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+
-+#include <linux/cpuidle.h>
-+#include <asm/arch/pm.h>
-+#include <asm/arch/prcm.h>
-+#include <asm/arch/powerdomain.h>
-+#include <asm/arch/clockdomain.h>
-+#include <asm/arch/irqs.h>
-+#include "cpuidle34xx.h"
-+
-+#ifdef CONFIG_CPU_IDLE
-+
-+struct omap3_processor_cx omap3_power_states[OMAP3_MAX_STATES];
-+struct omap3_processor_cx current_cx_state;
-+
-+static int omap3_idle_bm_check(void)
-+{
-+ /* Check for omap3_fclks_active() here once available */
-+ return 0;
-+}
-+
-+/* omap3_enter_idle - Programs OMAP3 to enter the specified state.
-+ * returns the total time during which the system was idle.
-+ */
-+static int omap3_enter_idle(struct cpuidle_device *dev,
-+ struct cpuidle_state *state)
-+{
-+ struct omap3_processor_cx *cx = cpuidle_get_statedata(state);
-+ struct timespec ts_preidle, ts_postidle, ts_idle;
-+ struct powerdomain *mpu_pd, *core_pd, *per_pd, *neon_pd;
-+ int neon_pwrst;
-+
-+ current_cx_state = *cx;
-+
-+ if (cx->type == OMAP3_STATE_C0) {
-+ /* Do nothing for C0, not even a wfi */
-+ return 0;
-+ }
-+
-+ /* Used to keep track of the total time in idle */
-+ getnstimeofday(&ts_preidle);
-+
-+ mpu_pd = pwrdm_lookup("mpu_pwrdm");
-+ core_pd = pwrdm_lookup("core_pwrdm");
-+ per_pd = pwrdm_lookup("per_pwrdm");
-+ neon_pd = pwrdm_lookup("neon_pwrdm");
-+
-+ /* Reset previous power state registers */
-+ pwrdm_clear_all_prev_pwrst(mpu_pd);
-+ pwrdm_clear_all_prev_pwrst(neon_pd);
-+ pwrdm_clear_all_prev_pwrst(core_pd);
-+ pwrdm_clear_all_prev_pwrst(per_pd);
-+
-+ if (omap_irq_pending())
-+ return 0;
-+
-+ neon_pwrst = pwrdm_read_pwrst(neon_pd);
-+
-+ /* Program MPU/NEON to target state */
-+ if (cx->mpu_state < PWRDM_POWER_ON) {
-+ if (neon_pwrst == PWRDM_POWER_ON) {
-+ if (cx->mpu_state == PWRDM_POWER_RET)
-+ pwrdm_set_next_pwrst(neon_pd, PWRDM_POWER_RET);
-+ else if (cx->mpu_state == PWRDM_POWER_OFF)
-+ pwrdm_set_next_pwrst(neon_pd, PWRDM_POWER_OFF);
-+ }
-+ pwrdm_set_next_pwrst(mpu_pd, cx->mpu_state);
-+ }
-+
-+ /* Program CORE to target state */
-+ if (cx->core_state < PWRDM_POWER_ON)
-+ pwrdm_set_next_pwrst(core_pd, cx->core_state);
-+
-+ /* Execute ARM wfi */
-+ omap_sram_idle();
-+
-+ /* Program MPU/NEON to ON */
-+ if (cx->mpu_state < PWRDM_POWER_ON) {
-+ if (neon_pwrst == PWRDM_POWER_ON)
-+ pwrdm_set_next_pwrst(neon_pd, PWRDM_POWER_ON);
-+ pwrdm_set_next_pwrst(mpu_pd, PWRDM_POWER_ON);
-+ }
-+
-+ if (cx->core_state < PWRDM_POWER_ON)
-+ pwrdm_set_next_pwrst(core_pd, PWRDM_POWER_ON);
-+
-+ getnstimeofday(&ts_postidle);
-+ ts_idle = timespec_sub(ts_postidle, ts_preidle);
-+ return timespec_to_ns(&ts_idle);
-+}
-+
-+/*
-+ * omap3_enter_idle_bm - enter function for states with CPUIDLE_FLAG_CHECK_BM
-+ *
-+ * This function checks for all the pre-requisites needed for OMAP3 to enter
-+ * CORE RET/OFF state. It then calls omap3_enter_idle to program the desired
-+ * C state.
-+ */
-+static int omap3_enter_idle_bm(struct cpuidle_device *dev,
-+ struct cpuidle_state *state)
-+{
-+ struct cpuidle_state *new_state = NULL;
-+ int i, j;
-+
-+ if ((state->flags & CPUIDLE_FLAG_CHECK_BM) && omap3_idle_bm_check()) {
-+
-+ /* Find current state in list */
-+ for (i = 0; i < OMAP3_MAX_STATES; i++)
-+ if (state == &dev->states[i])
-+ break;
-+ BUG_ON(i == OMAP3_MAX_STATES);
-+
-+ /* Back up to non 'CHECK_BM' state */
-+ for (j = i - 1; j > 0; j--) {
-+ struct cpuidle_state *s = &dev->states[j];
-+
-+ if (!(s->flags & CPUIDLE_FLAG_CHECK_BM)) {
-+ new_state = s;
-+ break;
-+ }
-+ }
-+
-+ pr_debug("%s: Bus activity: Entering %s (instead of %s)\n",
-+ __FUNCTION__, new_state->name, state->name);
-+ }
-+
-+ return omap3_enter_idle(dev, new_state ? : state);
-+}
-+
-+DEFINE_PER_CPU(struct cpuidle_device, omap3_idle_dev);
-+
-+/* omap3_init_power_states - Initialises the OMAP3 specific C states.
-+ * Below is the desciption of each C state.
-+ *
-+ C0 . System executing code
-+ C1 . MPU WFI + Core active
-+ C2 . MPU CSWR + Core active
-+ C3 . MPU OFF + Core active
-+ C4 . MPU CSWR + Core CSWR
-+ C5 . MPU OFF + Core CSWR
-+ C6 . MPU OFF + Core OFF
-+ */
-+void omap_init_power_states(void)
-+{
-+ /* C0 . System executing code */
-+ omap3_power_states[0].valid = 1;
-+ omap3_power_states[0].type = OMAP3_STATE_C0;
-+ omap3_power_states[0].sleep_latency = 0;
-+ omap3_power_states[0].wakeup_latency = 0;
-+ omap3_power_states[0].threshold = 0;
-+ omap3_power_states[0].mpu_state = PWRDM_POWER_ON;
-+ omap3_power_states[0].core_state = PWRDM_POWER_ON;
-+ omap3_power_states[0].flags = CPUIDLE_FLAG_TIME_VALID |
-+ CPUIDLE_FLAG_SHALLOW;
-+
-+ /* C1 . MPU WFI + Core active */
-+ omap3_power_states[1].valid = 1;
-+ omap3_power_states[1].type = OMAP3_STATE_C1;
-+ omap3_power_states[1].sleep_latency = 10;
-+ omap3_power_states[1].wakeup_latency = 10;
-+ omap3_power_states[1].threshold = 30;
-+ omap3_power_states[1].mpu_state = PWRDM_POWER_ON;
-+ omap3_power_states[1].core_state = PWRDM_POWER_ON;
-+ omap3_power_states[1].flags = CPUIDLE_FLAG_TIME_VALID |
-+ CPUIDLE_FLAG_SHALLOW;
-+
-+ /* C2 . MPU CSWR + Core active */
-+ omap3_power_states[2].valid = 1;
-+ omap3_power_states[2].type = OMAP3_STATE_C2;
-+ omap3_power_states[2].sleep_latency = 50;
-+ omap3_power_states[2].wakeup_latency = 50;
-+ omap3_power_states[2].threshold = 300;
-+ omap3_power_states[2].mpu_state = PWRDM_POWER_RET;
-+ omap3_power_states[2].core_state = PWRDM_POWER_ON;
-+ omap3_power_states[2].flags = CPUIDLE_FLAG_TIME_VALID |
-+ CPUIDLE_FLAG_BALANCED;
-+
-+ /* C3 . MPU OFF + Core active */
-+ omap3_power_states[3].valid = 0;
-+ omap3_power_states[3].type = OMAP3_STATE_C3;
-+ omap3_power_states[3].sleep_latency = 1500;
-+ omap3_power_states[3].wakeup_latency = 1800;
-+ omap3_power_states[3].threshold = 4000;
-+ omap3_power_states[3].mpu_state = PWRDM_POWER_OFF;
-+ omap3_power_states[3].core_state = PWRDM_POWER_RET;
-+ omap3_power_states[3].flags = CPUIDLE_FLAG_TIME_VALID |
-+ CPUIDLE_FLAG_BALANCED;
-+
-+ /* C4 . MPU CSWR + Core CSWR*/
-+ omap3_power_states[4].valid = 1;
-+ omap3_power_states[4].type = OMAP3_STATE_C4;
-+ omap3_power_states[4].sleep_latency = 2500;
-+ omap3_power_states[4].wakeup_latency = 7500;
-+ omap3_power_states[4].threshold = 12000;
-+ omap3_power_states[4].mpu_state = PWRDM_POWER_RET;
-+ omap3_power_states[4].core_state = PWRDM_POWER_RET;
-+ omap3_power_states[4].flags = CPUIDLE_FLAG_TIME_VALID |
-+ CPUIDLE_FLAG_BALANCED | CPUIDLE_FLAG_CHECK_BM;
-+
-+ /* C5 . MPU OFF + Core CSWR */
-+ omap3_power_states[5].valid = 0;
-+ omap3_power_states[5].type = OMAP3_STATE_C5;
-+ omap3_power_states[5].sleep_latency = 3000;
-+ omap3_power_states[5].wakeup_latency = 8500;
-+ omap3_power_states[5].threshold = 15000;
-+ omap3_power_states[5].mpu_state = PWRDM_POWER_OFF;
-+ omap3_power_states[5].core_state = PWRDM_POWER_RET;
-+ omap3_power_states[5].flags = CPUIDLE_FLAG_TIME_VALID |
-+ CPUIDLE_FLAG_BALANCED | CPUIDLE_FLAG_CHECK_BM;
-+
-+ /* C6 . MPU OFF + Core OFF */
-+ omap3_power_states[6].valid = 0;
-+ omap3_power_states[6].type = OMAP3_STATE_C6;
-+ omap3_power_states[6].sleep_latency = 10000;
-+ omap3_power_states[6].wakeup_latency = 30000;
-+ omap3_power_states[6].threshold = 300000;
-+ omap3_power_states[6].mpu_state = PWRDM_POWER_OFF;
-+ omap3_power_states[6].core_state = PWRDM_POWER_OFF;
-+ omap3_power_states[6].flags = CPUIDLE_FLAG_TIME_VALID |
-+ CPUIDLE_FLAG_DEEP | CPUIDLE_FLAG_CHECK_BM;
-+}
-+
-+struct cpuidle_driver omap3_idle_driver = {
-+ .name = "omap3_idle",
-+ .owner = THIS_MODULE,
-+};
-+/*
-+ * omap3_idle_init - Init routine for OMAP3 idle.
-+ * Registers the OMAP3 specific cpuidle driver with the cpuidle f/w
-+ * with the valid set of states.
-+ */
-+int omap3_idle_init(void)
-+{
-+ int i, count = 0;
-+ struct omap3_processor_cx *cx;
-+ struct cpuidle_state *state;
-+ struct cpuidle_device *dev;
-+
-+ omap_init_power_states();
-+ cpuidle_register_driver(&omap3_idle_driver);
-+
-+ dev = &per_cpu(omap3_idle_dev, smp_processor_id());
-+
-+ for (i = 0; i < OMAP3_MAX_STATES; i++) {
-+ cx = &omap3_power_states[i];
-+ state = &dev->states[count];
-+
-+ if (!cx->valid)
-+ continue;
-+ cpuidle_set_statedata(state, cx);
-+ state->exit_latency = cx->sleep_latency + cx->wakeup_latency;
-+ state->target_residency = cx->threshold;
-+ state->flags = cx->flags;
-+ state->enter = (state->flags & CPUIDLE_FLAG_CHECK_BM) ?
-+ omap3_enter_idle_bm : omap3_enter_idle;
-+ sprintf(state->name, "C%d", count+1);
-+ count++;
-+ }
-+
-+ if (!count)
-+ return -EINVAL;
-+ dev->state_count = count;
-+
-+ if (cpuidle_register_device(dev)) {
-+ printk(KERN_ERR "%s: CPUidle register device failed\n",
-+ __FUNCTION__);
-+ return -EIO;
-+ }
-+
-+ return 0;
-+}
-+__initcall(omap3_idle_init);
-+#endif /* CONFIG_CPU_IDLE */
-Index: linux-omap-2.6/arch/arm/mach-omap2/cpuidle34xx.h
-===================================================================
---- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ linux-omap-2.6/arch/arm/mach-omap2/cpuidle34xx.h 2008-06-09 20:15:39.569121361 +0530
-@@ -0,0 +1,51 @@
-+/*
-+ * linux/arch/arm/mach-omap2/cpuidle34xx.h
-+ *
-+ * OMAP3 cpuidle structure definitions
-+ *
-+ * Copyright (C) 2007-2008 Texas Instruments, Inc.
-+ * Written by Rajendra Nayak <rnayak@ti.com>
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
-+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
-+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
-+ *
-+ * History:
-+ *
-+ */
-+
-+#ifndef ARCH_ARM_MACH_OMAP2_CPUIDLE_34XX
-+#define ARCH_ARM_MACH_OMAP2_CPUIDLE_34XX
-+
-+#define OMAP3_MAX_STATES 7
-+#define OMAP3_STATE_C0 0 /* C0 - System executing code */
-+#define OMAP3_STATE_C1 1 /* C1 - MPU WFI + Core active */
-+#define OMAP3_STATE_C2 2 /* C2 - MPU CSWR + Core active */
-+#define OMAP3_STATE_C3 3 /* C3 - MPU OFF + Core active */
-+#define OMAP3_STATE_C4 4 /* C4 - MPU RET + Core RET */
-+#define OMAP3_STATE_C5 5 /* C5 - MPU OFF + Core RET */
-+#define OMAP3_STATE_C6 6 /* C6 - MPU OFF + Core OFF */
-+
-+extern void omap_sram_idle(void);
-+extern int omap3_irq_pending(void);
-+
-+struct omap3_processor_cx {
-+ u8 valid;
-+ u8 type;
-+ u32 sleep_latency;
-+ u32 wakeup_latency;
-+ u32 mpu_state;
-+ u32 core_state;
-+ u32 threshold;
-+ u32 flags;
-+};
-+
-+void omap_init_power_states(void);
-+int omap3_idle_init(void);
-+
-+#endif /* ARCH_ARM_MACH_OMAP2_CPUIDLE_34XX */
-+
-Index: linux-omap-2.6/arch/arm/mach-omap2/pm34xx.c
-===================================================================
---- linux-omap-2.6.orig/arch/arm/mach-omap2/pm34xx.c 2008-06-09 20:15:33.855303920 +0530
-+++ linux-omap-2.6/arch/arm/mach-omap2/pm34xx.c 2008-06-09 20:16:20.976798343 +0530
-@@ -141,7 +141,7 @@ static irqreturn_t prcm_interrupt_handle
- return IRQ_HANDLED;
- }
-
--static void omap_sram_idle(void)
-+void omap_sram_idle(void)
- {
- /* Variable to tell what needs to be saved and restored
- * in omap_sram_idle*/
-@@ -156,6 +156,7 @@ static void omap_sram_idle(void)
-
- mpu_next_state = pwrdm_read_next_pwrst(mpu_pwrdm);
- switch (mpu_next_state) {
-+ case PWRDM_POWER_ON:
- case PWRDM_POWER_RET:
- /* No need to save context */
- save_state = 0;
-@@ -386,7 +387,9 @@ int __init omap3_pm_init(void)
-
- prcm_setup_regs();
-
-+#ifndef CONFIG_CPU_IDLE
- pm_idle = omap3_pm_idle;
-+#endif
-
- err1:
- return ret;
-Index: linux-omap-2.6/drivers/cpuidle/cpuidle.c
-===================================================================
---- linux-omap-2.6.orig/drivers/cpuidle/cpuidle.c 2008-06-09 20:15:33.856303888 +0530
-+++ linux-omap-2.6/drivers/cpuidle/cpuidle.c 2008-06-09 20:15:39.570121329 +0530
-@@ -58,6 +58,11 @@ static void cpuidle_idle_call(void)
- return;
- }
-
-+#ifdef CONFIG_ARCH_OMAP3
-+ local_irq_disable();
-+ local_fiq_disable();
-+#endif
-+
- /* ask the governor for the next state */
- next_state = cpuidle_curr_governor->select(dev);
- if (need_resched())
-@@ -70,6 +75,11 @@ static void cpuidle_idle_call(void)
- target_state->time += (unsigned long long)dev->last_residency;
- target_state->usage++;
-
-+#ifdef CONFIG_ARCH_OMAP3
-+ local_irq_enable();
-+ local_fiq_enable();
-+#endif
-+
- /* give the governor an opportunity to reflect on the outcome */
- if (cpuidle_curr_governor->reflect)
- cpuidle_curr_governor->reflect(dev);
-
---
-To unsubscribe from this list: send the line "unsubscribe linux-omap" in
-the body of a message to majordomo@vger.kernel.org
-More majordomo info at http://vger.kernel.org/majordomo-info.html
-
+From: "Rajendra Nayak" <rnayak@ti.com>
+To: <linux-omap@vger.kernel.org>
+Subject: [PATCH 01/02] OMAP3 CPUidle driver
+Date: Tue, 10 Jun 2008 12:39:00 +0530
+
+This patch adds the OMAP3 cpuidle driver. Irq enable/disable is done in the core cpuidle driver
+before it queries the governor for the next state.
+
+Signed-off-by: Rajendra Nayak <rnayak@ti.com>
+
+---
+ arch/arm/mach-omap2/Makefile | 2
+ arch/arm/mach-omap2/cpuidle34xx.c | 293 ++++++++++++++++++++++++++++++++++++++
+ arch/arm/mach-omap2/cpuidle34xx.h | 51 ++++++
+ arch/arm/mach-omap2/pm34xx.c | 5
+ drivers/cpuidle/cpuidle.c | 10 +
+ 5 files changed, 359 insertions(+), 2 deletions(-)
+
+Index: linux-omap-2.6/arch/arm/mach-omap2/Makefile
+===================================================================
+--- linux-omap-2.6.orig/arch/arm/mach-omap2/Makefile 2008-06-09 20:15:33.855303920 +0530
++++ linux-omap-2.6/arch/arm/mach-omap2/Makefile 2008-06-09 20:15:39.569121361 +0530
+@@ -20,7 +20,7 @@ obj-y += pm.o
+ obj-$(CONFIG_ARCH_OMAP2) += pm24xx.o
+ obj-$(CONFIG_ARCH_OMAP2420) += sleep242x.o
+ obj-$(CONFIG_ARCH_OMAP2430) += sleep243x.o
+-obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.o
++obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.o cpuidle34xx.o
+ obj-$(CONFIG_PM_DEBUG) += pm-debug.o
+ endif
+
+Index: linux-omap-2.6/arch/arm/mach-omap2/cpuidle34xx.c
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ linux-omap-2.6/arch/arm/mach-omap2/cpuidle34xx.c 2008-06-10 11:41:27.644820323 +0530
+@@ -0,0 +1,293 @@
++/*
++ * linux/arch/arm/mach-omap2/cpuidle34xx.c
++ *
++ * OMAP3 CPU IDLE Routines
++ *
++ * Copyright (C) 2007-2008 Texas Instruments, Inc.
++ * Rajendra Nayak <rnayak@ti.com>
++ *
++ * Copyright (C) 2007 Texas Instruments, Inc.
++ * Karthik Dasu <karthik-dp@ti.com>
++ *
++ * Copyright (C) 2006 Nokia Corporation
++ * Tony Lindgren <tony@atomide.com>
++ *
++ * Copyright (C) 2005 Texas Instruments, Inc.
++ * Richard Woodruff <r-woodruff2@ti.com>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++#include <linux/cpuidle.h>
++#include <asm/arch/pm.h>
++#include <asm/arch/prcm.h>
++#include <asm/arch/powerdomain.h>
++#include <asm/arch/clockdomain.h>
++#include <asm/arch/irqs.h>
++#include "cpuidle34xx.h"
++
++#ifdef CONFIG_CPU_IDLE
++
++struct omap3_processor_cx omap3_power_states[OMAP3_MAX_STATES];
++struct omap3_processor_cx current_cx_state;
++
++static int omap3_idle_bm_check(void)
++{
++ /* Check for omap3_fclks_active() here once available */
++ return 0;
++}
++
++/* omap3_enter_idle - Programs OMAP3 to enter the specified state.
++ * returns the total time during which the system was idle.
++ */
++static int omap3_enter_idle(struct cpuidle_device *dev,
++ struct cpuidle_state *state)
++{
++ struct omap3_processor_cx *cx = cpuidle_get_statedata(state);
++ struct timespec ts_preidle, ts_postidle, ts_idle;
++ struct powerdomain *mpu_pd, *core_pd, *per_pd, *neon_pd;
++ int neon_pwrst;
++
++ current_cx_state = *cx;
++
++ if (cx->type == OMAP3_STATE_C0) {
++ /* Do nothing for C0, not even a wfi */
++ return 0;
++ }
++
++ /* Used to keep track of the total time in idle */
++ getnstimeofday(&ts_preidle);
++
++ mpu_pd = pwrdm_lookup("mpu_pwrdm");
++ core_pd = pwrdm_lookup("core_pwrdm");
++ per_pd = pwrdm_lookup("per_pwrdm");
++ neon_pd = pwrdm_lookup("neon_pwrdm");
++
++ /* Reset previous power state registers */
++ pwrdm_clear_all_prev_pwrst(mpu_pd);
++ pwrdm_clear_all_prev_pwrst(neon_pd);
++ pwrdm_clear_all_prev_pwrst(core_pd);
++ pwrdm_clear_all_prev_pwrst(per_pd);
++
++ if (omap_irq_pending())
++ return 0;
++
++ neon_pwrst = pwrdm_read_pwrst(neon_pd);
++
++ /* Program MPU/NEON to target state */
++ if (cx->mpu_state < PWRDM_POWER_ON) {
++ if (neon_pwrst == PWRDM_POWER_ON) {
++ if (cx->mpu_state == PWRDM_POWER_RET)
++ pwrdm_set_next_pwrst(neon_pd, PWRDM_POWER_RET);
++ else if (cx->mpu_state == PWRDM_POWER_OFF)
++ pwrdm_set_next_pwrst(neon_pd, PWRDM_POWER_OFF);
++ }
++ pwrdm_set_next_pwrst(mpu_pd, cx->mpu_state);
++ }
++
++ /* Program CORE to target state */
++ if (cx->core_state < PWRDM_POWER_ON)
++ pwrdm_set_next_pwrst(core_pd, cx->core_state);
++
++ /* Execute ARM wfi */
++ omap_sram_idle();
++
++ /* Program MPU/NEON to ON */
++ if (cx->mpu_state < PWRDM_POWER_ON) {
++ if (neon_pwrst == PWRDM_POWER_ON)
++ pwrdm_set_next_pwrst(neon_pd, PWRDM_POWER_ON);
++ pwrdm_set_next_pwrst(mpu_pd, PWRDM_POWER_ON);
++ }
++
++ if (cx->core_state < PWRDM_POWER_ON)
++ pwrdm_set_next_pwrst(core_pd, PWRDM_POWER_ON);
++
++ getnstimeofday(&ts_postidle);
++ ts_idle = timespec_sub(ts_postidle, ts_preidle);
++ return timespec_to_ns(&ts_idle);
++}
++
++/*
++ * omap3_enter_idle_bm - enter function for states with CPUIDLE_FLAG_CHECK_BM
++ *
++ * This function checks for all the pre-requisites needed for OMAP3 to enter
++ * CORE RET/OFF state. It then calls omap3_enter_idle to program the desired
++ * C state.
++ */
++static int omap3_enter_idle_bm(struct cpuidle_device *dev,
++ struct cpuidle_state *state)
++{
++ struct cpuidle_state *new_state = NULL;
++ int i, j;
++
++ if ((state->flags & CPUIDLE_FLAG_CHECK_BM) && omap3_idle_bm_check()) {
++
++ /* Find current state in list */
++ for (i = 0; i < OMAP3_MAX_STATES; i++)
++ if (state == &dev->states[i])
++ break;
++ BUG_ON(i == OMAP3_MAX_STATES);
++
++ /* Back up to non 'CHECK_BM' state */
++ for (j = i - 1; j > 0; j--) {
++ struct cpuidle_state *s = &dev->states[j];
++
++ if (!(s->flags & CPUIDLE_FLAG_CHECK_BM)) {
++ new_state = s;
++ break;
++ }
++ }
++
++ pr_debug("%s: Bus activity: Entering %s (instead of %s)\n",
++ __FUNCTION__, new_state->name, state->name);
++ }
++
++ return omap3_enter_idle(dev, new_state ? : state);
++}
++
++DEFINE_PER_CPU(struct cpuidle_device, omap3_idle_dev);
++
++/* omap3_init_power_states - Initialises the OMAP3 specific C states.
++ * Below is the desciption of each C state.
++ *
++ C0 . System executing code
++ C1 . MPU WFI + Core active
++ C2 . MPU CSWR + Core active
++ C3 . MPU OFF + Core active
++ C4 . MPU CSWR + Core CSWR
++ C5 . MPU OFF + Core CSWR
++ C6 . MPU OFF + Core OFF
++ */
++void omap_init_power_states(void)
++{
++ /* C0 . System executing code */
++ omap3_power_states[0].valid = 1;
++ omap3_power_states[0].type = OMAP3_STATE_C0;
++ omap3_power_states[0].sleep_latency = 0;
++ omap3_power_states[0].wakeup_latency = 0;
++ omap3_power_states[0].threshold = 0;
++ omap3_power_states[0].mpu_state = PWRDM_POWER_ON;
++ omap3_power_states[0].core_state = PWRDM_POWER_ON;
++ omap3_power_states[0].flags = CPUIDLE_FLAG_TIME_VALID |
++ CPUIDLE_FLAG_SHALLOW;
++
++ /* C1 . MPU WFI + Core active */
++ omap3_power_states[1].valid = 1;
++ omap3_power_states[1].type = OMAP3_STATE_C1;
++ omap3_power_states[1].sleep_latency = 10;
++ omap3_power_states[1].wakeup_latency = 10;
++ omap3_power_states[1].threshold = 30;
++ omap3_power_states[1].mpu_state = PWRDM_POWER_ON;
++ omap3_power_states[1].core_state = PWRDM_POWER_ON;
++ omap3_power_states[1].flags = CPUIDLE_FLAG_TIME_VALID |
++ CPUIDLE_FLAG_SHALLOW;
++
++ /* C2 . MPU CSWR + Core active */
++ omap3_power_states[2].valid = 1;
++ omap3_power_states[2].type = OMAP3_STATE_C2;
++ omap3_power_states[2].sleep_latency = 50;
++ omap3_power_states[2].wakeup_latency = 50;
++ omap3_power_states[2].threshold = 300;
++ omap3_power_states[2].mpu_state = PWRDM_POWER_RET;
++ omap3_power_states[2].core_state = PWRDM_POWER_ON;
++ omap3_power_states[2].flags = CPUIDLE_FLAG_TIME_VALID |
++ CPUIDLE_FLAG_BALANCED;
++
++ /* C3 . MPU OFF + Core active */
++ omap3_power_states[3].valid = 0;
++ omap3_power_states[3].type = OMAP3_STATE_C3;
++ omap3_power_states[3].sleep_latency = 1500;
++ omap3_power_states[3].wakeup_latency = 1800;
++ omap3_power_states[3].threshold = 4000;
++ omap3_power_states[3].mpu_state = PWRDM_POWER_OFF;
++ omap3_power_states[3].core_state = PWRDM_POWER_RET;
++ omap3_power_states[3].flags = CPUIDLE_FLAG_TIME_VALID |
++ CPUIDLE_FLAG_BALANCED;
++
++ /* C4 . MPU CSWR + Core CSWR*/
++ omap3_power_states[4].valid = 1;
++ omap3_power_states[4].type = OMAP3_STATE_C4;
++ omap3_power_states[4].sleep_latency = 2500;
++ omap3_power_states[4].wakeup_latency = 7500;
++ omap3_power_states[4].threshold = 12000;
++ omap3_power_states[4].mpu_state = PWRDM_POWER_RET;
++ omap3_power_states[4].core_state = PWRDM_POWER_RET;
++ omap3_power_states[4].flags = CPUIDLE_FLAG_TIME_VALID |
++ CPUIDLE_FLAG_BALANCED | CPUIDLE_FLAG_CHECK_BM;
++
++ /* C5 . MPU OFF + Core CSWR */
++ omap3_power_states[5].valid = 0;
++ omap3_power_states[5].type = OMAP3_STATE_C5;
++ omap3_power_states[5].sleep_latency = 3000;
++ omap3_power_states[5].wakeup_latency = 8500;
++ omap3_power_states[5].threshold = 15000;
++ omap3_power_states[5].mpu_state = PWRDM_POWER_OFF;
++ omap3_power_states[5].core_state = PWRDM_POWER_RET;
++ omap3_power_states[5].flags = CPUIDLE_FLAG_TIME_VALID |
++ CPUIDLE_FLAG_BALANCED | CPUIDLE_FLAG_CHECK_BM;
++
++ /* C6 . MPU OFF + Core OFF */
++ omap3_power_states[6].valid = 0;
++ omap3_power_states[6].type = OMAP3_STATE_C6;
++ omap3_power_states[6].sleep_latency = 10000;
++ omap3_power_states[6].wakeup_latency = 30000;
++ omap3_power_states[6].threshold = 300000;
++ omap3_power_states[6].mpu_state = PWRDM_POWER_OFF;
++ omap3_power_states[6].core_state = PWRDM_POWER_OFF;
++ omap3_power_states[6].flags = CPUIDLE_FLAG_TIME_VALID |
++ CPUIDLE_FLAG_DEEP | CPUIDLE_FLAG_CHECK_BM;
++}
++
++struct cpuidle_driver omap3_idle_driver = {
++ .name = "omap3_idle",
++ .owner = THIS_MODULE,
++};
++/*
++ * omap3_idle_init - Init routine for OMAP3 idle.
++ * Registers the OMAP3 specific cpuidle driver with the cpuidle f/w
++ * with the valid set of states.
++ */
++int omap3_idle_init(void)
++{
++ int i, count = 0;
++ struct omap3_processor_cx *cx;
++ struct cpuidle_state *state;
++ struct cpuidle_device *dev;
++
++ omap_init_power_states();
++ cpuidle_register_driver(&omap3_idle_driver);
++
++ dev = &per_cpu(omap3_idle_dev, smp_processor_id());
++
++ for (i = 0; i < OMAP3_MAX_STATES; i++) {
++ cx = &omap3_power_states[i];
++ state = &dev->states[count];
++
++ if (!cx->valid)
++ continue;
++ cpuidle_set_statedata(state, cx);
++ state->exit_latency = cx->sleep_latency + cx->wakeup_latency;
++ state->target_residency = cx->threshold;
++ state->flags = cx->flags;
++ state->enter = (state->flags & CPUIDLE_FLAG_CHECK_BM) ?
++ omap3_enter_idle_bm : omap3_enter_idle;
++ sprintf(state->name, "C%d", count+1);
++ count++;
++ }
++
++ if (!count)
++ return -EINVAL;
++ dev->state_count = count;
++
++ if (cpuidle_register_device(dev)) {
++ printk(KERN_ERR "%s: CPUidle register device failed\n",
++ __FUNCTION__);
++ return -EIO;
++ }
++
++ return 0;
++}
++__initcall(omap3_idle_init);
++#endif /* CONFIG_CPU_IDLE */
+Index: linux-omap-2.6/arch/arm/mach-omap2/cpuidle34xx.h
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ linux-omap-2.6/arch/arm/mach-omap2/cpuidle34xx.h 2008-06-09 20:15:39.569121361 +0530
+@@ -0,0 +1,51 @@
++/*
++ * linux/arch/arm/mach-omap2/cpuidle34xx.h
++ *
++ * OMAP3 cpuidle structure definitions
++ *
++ * Copyright (C) 2007-2008 Texas Instruments, Inc.
++ * Written by Rajendra Nayak <rnayak@ti.com>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ *
++ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
++ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
++ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
++ *
++ * History:
++ *
++ */
++
++#ifndef ARCH_ARM_MACH_OMAP2_CPUIDLE_34XX
++#define ARCH_ARM_MACH_OMAP2_CPUIDLE_34XX
++
++#define OMAP3_MAX_STATES 7
++#define OMAP3_STATE_C0 0 /* C0 - System executing code */
++#define OMAP3_STATE_C1 1 /* C1 - MPU WFI + Core active */
++#define OMAP3_STATE_C2 2 /* C2 - MPU CSWR + Core active */
++#define OMAP3_STATE_C3 3 /* C3 - MPU OFF + Core active */
++#define OMAP3_STATE_C4 4 /* C4 - MPU RET + Core RET */
++#define OMAP3_STATE_C5 5 /* C5 - MPU OFF + Core RET */
++#define OMAP3_STATE_C6 6 /* C6 - MPU OFF + Core OFF */
++
++extern void omap_sram_idle(void);
++extern int omap3_irq_pending(void);
++
++struct omap3_processor_cx {
++ u8 valid;
++ u8 type;
++ u32 sleep_latency;
++ u32 wakeup_latency;
++ u32 mpu_state;
++ u32 core_state;
++ u32 threshold;
++ u32 flags;
++};
++
++void omap_init_power_states(void);
++int omap3_idle_init(void);
++
++#endif /* ARCH_ARM_MACH_OMAP2_CPUIDLE_34XX */
++
+Index: linux-omap-2.6/arch/arm/mach-omap2/pm34xx.c
+===================================================================
+--- linux-omap-2.6.orig/arch/arm/mach-omap2/pm34xx.c 2008-06-09 20:15:33.855303920 +0530
++++ linux-omap-2.6/arch/arm/mach-omap2/pm34xx.c 2008-06-09 20:16:20.976798343 +0530
+@@ -141,7 +141,7 @@ static irqreturn_t prcm_interrupt_handle
+ return IRQ_HANDLED;
+ }
+
+-static void omap_sram_idle(void)
++void omap_sram_idle(void)
+ {
+ /* Variable to tell what needs to be saved and restored
+ * in omap_sram_idle*/
+@@ -156,6 +156,7 @@ static void omap_sram_idle(void)
+
+ mpu_next_state = pwrdm_read_next_pwrst(mpu_pwrdm);
+ switch (mpu_next_state) {
++ case PWRDM_POWER_ON:
+ case PWRDM_POWER_RET:
+ /* No need to save context */
+ save_state = 0;
+@@ -386,7 +387,9 @@ int __init omap3_pm_init(void)
+
+ prcm_setup_regs();
+
++#ifndef CONFIG_CPU_IDLE
+ pm_idle = omap3_pm_idle;
++#endif
+
+ err1:
+ return ret;
+Index: linux-omap-2.6/drivers/cpuidle/cpuidle.c
+===================================================================
+--- linux-omap-2.6.orig/drivers/cpuidle/cpuidle.c 2008-06-09 20:15:33.856303888 +0530
++++ linux-omap-2.6/drivers/cpuidle/cpuidle.c 2008-06-09 20:15:39.570121329 +0530
+@@ -58,6 +58,11 @@ static void cpuidle_idle_call(void)
+ return;
+ }
+
++#ifdef CONFIG_ARCH_OMAP3
++ local_irq_disable();
++ local_fiq_disable();
++#endif
++
+ /* ask the governor for the next state */
+ next_state = cpuidle_curr_governor->select(dev);
+ if (need_resched())
+@@ -70,6 +75,11 @@ static void cpuidle_idle_call(void)
+ target_state->time += (unsigned long long)dev->last_residency;
+ target_state->usage++;
+
++#ifdef CONFIG_ARCH_OMAP3
++ local_irq_enable();
++ local_fiq_enable();
++#endif
++
+ /* give the governor an opportunity to reflect on the outcome */
+ if (cpuidle_curr_governor->reflect)
+ cpuidle_curr_governor->reflect(dev);
+
+--
+To unsubscribe from this list: send the line "unsubscribe linux-omap" in
+the body of a message to majordomo@vger.kernel.org
+More majordomo info at http://vger.kernel.org/majordomo-info.html
+
diff --git a/packages/linux/linux-omap2-git/omap3evm/0002-omap3-cpuidle.patch b/packages/linux/linux-omap2-git/omap3evm/0002-omap3-cpuidle.patch
index c17c690fe1..d35fd47567 100644
--- a/packages/linux/linux-omap2-git/omap3evm/0002-omap3-cpuidle.patch
+++ b/packages/linux/linux-omap2-git/omap3evm/0002-omap3-cpuidle.patch
@@ -1,88 +1,88 @@
-From: "Rajendra Nayak" <rnayak@ti.com>
-To: <linux-omap@vger.kernel.org>
-Subject: [PATCH 02/02] Kconfig changes
-Date: Tue, 10 Jun 2008 12:39:02 +0530
-
-Updates the CPUidle Kconfig
-
-Signed-off-by: Rajendra Nayak <rnayak@ti.com>
-
----
- arch/arm/Kconfig | 10 ++++++++++
- drivers/cpuidle/Kconfig | 28 ++++++++++++++++++++++------
- 2 files changed, 32 insertions(+), 6 deletions(-)
-
-Index: linux-omap-2.6/arch/arm/Kconfig
-===================================================================
---- linux-omap-2.6.orig/arch/arm/Kconfig 2008-06-10 11:43:10.790502713 +0530
-+++ linux-omap-2.6/arch/arm/Kconfig 2008-06-10 11:43:38.701604549 +0530
-@@ -954,6 +954,16 @@ config ATAGS_PROC
-
- endmenu
-
-+if (ARCH_OMAP)
-+
-+menu "CPUIdle"
-+
-+source "drivers/cpuidle/Kconfig"
-+
-+endmenu
-+
-+endif
-+
- if (ARCH_SA1100 || ARCH_INTEGRATOR || ARCH_OMAP || ARCH_IMX || ARCH_PXA)
-
- menu "CPU Frequency scaling"
-Index: linux-omap-2.6/drivers/cpuidle/Kconfig
-===================================================================
---- linux-omap-2.6.orig/drivers/cpuidle/Kconfig 2008-06-10 11:43:10.790502713 +0530
-+++ linux-omap-2.6/drivers/cpuidle/Kconfig 2008-06-10 12:06:36.139332151 +0530
-@@ -1,20 +1,36 @@
-+menu "CPU idle PM support"
-
- config CPU_IDLE
- bool "CPU idle PM support"
-- default ACPI
-+ default n
- help
- CPU idle is a generic framework for supporting software-controlled
- idle processor power management. It includes modular cross-platform
- governors that can be swapped during runtime.
-
-- If you're using an ACPI-enabled platform, you should say Y here.
-+ If you're using a mobile platform that supports CPU idle PM (e.g.
-+ an ACPI-capable notebook), you should say Y here.
-+
-+if CPU_IDLE
-+
-+comment "Governors"
-
- config CPU_IDLE_GOV_LADDER
-- bool
-+ bool "ladder"
- depends on CPU_IDLE
-- default y
-+ default n
-
- config CPU_IDLE_GOV_MENU
-- bool
-+ bool "menu"
- depends on CPU_IDLE && NO_HZ
-- default y
-+ default n
-+ help
-+ This cpuidle governor evaluates all available states and chooses the
-+ deepest state that meets all of the following constraints: BM activity,
-+ expected time until next timer interrupt, and last break event time
-+ delta. It is designed to minimize power consumption. Currently
-+ dynticks is required.
-+
-+endif # CPU_IDLE
-+
-+endmenu
-
---
-To unsubscribe from this list: send the line "unsubscribe linux-omap" in
-the body of a message to majordomo@vger.kernel.org
-More majordomo info at http://vger.kernel.org/majordomo-info.html
-
+From: "Rajendra Nayak" <rnayak@ti.com>
+To: <linux-omap@vger.kernel.org>
+Subject: [PATCH 02/02] Kconfig changes
+Date: Tue, 10 Jun 2008 12:39:02 +0530
+
+Updates the CPUidle Kconfig
+
+Signed-off-by: Rajendra Nayak <rnayak@ti.com>
+
+---
+ arch/arm/Kconfig | 10 ++++++++++
+ drivers/cpuidle/Kconfig | 28 ++++++++++++++++++++++------
+ 2 files changed, 32 insertions(+), 6 deletions(-)
+
+Index: linux-omap-2.6/arch/arm/Kconfig
+===================================================================
+--- linux-omap-2.6.orig/arch/arm/Kconfig 2008-06-10 11:43:10.790502713 +0530
++++ linux-omap-2.6/arch/arm/Kconfig 2008-06-10 11:43:38.701604549 +0530
+@@ -954,6 +954,16 @@ config ATAGS_PROC
+
+ endmenu
+
++if (ARCH_OMAP)
++
++menu "CPUIdle"
++
++source "drivers/cpuidle/Kconfig"
++
++endmenu
++
++endif
++
+ if (ARCH_SA1100 || ARCH_INTEGRATOR || ARCH_OMAP || ARCH_IMX || ARCH_PXA)
+
+ menu "CPU Frequency scaling"
+Index: linux-omap-2.6/drivers/cpuidle/Kconfig
+===================================================================
+--- linux-omap-2.6.orig/drivers/cpuidle/Kconfig 2008-06-10 11:43:10.790502713 +0530
++++ linux-omap-2.6/drivers/cpuidle/Kconfig 2008-06-10 12:06:36.139332151 +0530
+@@ -1,20 +1,36 @@
++menu "CPU idle PM support"
+
+ config CPU_IDLE
+ bool "CPU idle PM support"
+- default ACPI
++ default n
+ help
+ CPU idle is a generic framework for supporting software-controlled
+ idle processor power management. It includes modular cross-platform
+ governors that can be swapped during runtime.
+
+- If you're using an ACPI-enabled platform, you should say Y here.
++ If you're using a mobile platform that supports CPU idle PM (e.g.
++ an ACPI-capable notebook), you should say Y here.
++
++if CPU_IDLE
++
++comment "Governors"
+
+ config CPU_IDLE_GOV_LADDER
+- bool
++ bool "ladder"
+ depends on CPU_IDLE
+- default y
++ default n
+
+ config CPU_IDLE_GOV_MENU
+- bool
++ bool "menu"
+ depends on CPU_IDLE && NO_HZ
+- default y
++ default n
++ help
++ This cpuidle governor evaluates all available states and chooses the
++ deepest state that meets all of the following constraints: BM activity,
++ expected time until next timer interrupt, and last break event time
++ delta. It is designed to minimize power consumption. Currently
++ dynticks is required.
++
++endif # CPU_IDLE
++
++endmenu
+
+--
+To unsubscribe from this list: send the line "unsubscribe linux-omap" in
+the body of a message to majordomo@vger.kernel.org
+More majordomo info at http://vger.kernel.org/majordomo-info.html
+
diff --git a/packages/linux/linux-omap2-git/omap3evm/defconfig b/packages/linux/linux-omap2-git/omap3evm/defconfig
index f74cef90ee..e61fad48d9 100644
--- a/packages/linux/linux-omap2-git/omap3evm/defconfig
+++ b/packages/linux/linux-omap2-git/omap3evm/defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.26-rc3-omap1
-# Wed May 21 07:38:41 2008
+# Linux kernel version: 2.6.26-rc5-omap1
+# Sun Jun 15 21:58:01 2008
#
CONFIG_ARM=y
CONFIG_SYS_SUPPORTS_APM_EMULATION=y
@@ -42,7 +42,8 @@ CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
# CONFIG_TASKSTATS is not set
# CONFIG_AUDIT is not set
-# CONFIG_IKCONFIG is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
# CONFIG_CGROUPS is not set
CONFIG_GROUP_SCHED=y
@@ -170,9 +171,9 @@ CONFIG_ARCH_OMAP3=y
#
# OMAP Feature Selections
#
-CONFIG_OMAP_DEBUG_SRAM_PATCH=y
# CONFIG_OMAP_DEBUG_POWERDOMAIN is not set
# CONFIG_OMAP_DEBUG_CLOCKDOMAIN is not set
+# CONFIG_OMAP_SMARTREFLEX is not set
# CONFIG_OMAP_RESET_CLOCKS is not set
CONFIG_OMAP_BOOT_TAG=y
CONFIG_OMAP_BOOT_REASON=y
@@ -186,9 +187,9 @@ CONFIG_OMAP_MCBSP=y
CONFIG_OMAP_32K_TIMER=y
CONFIG_OMAP_32K_TIMER_HZ=128
CONFIG_OMAP_DM_TIMER=y
-# CONFIG_OMAP_LL_DEBUG_UART1 is not set
+CONFIG_OMAP_LL_DEBUG_UART1=y
# CONFIG_OMAP_LL_DEBUG_UART2 is not set
-CONFIG_OMAP_LL_DEBUG_UART3=y
+# CONFIG_OMAP_LL_DEBUG_UART3 is not set
CONFIG_ARCH_OMAP34XX=y
CONFIG_ARCH_OMAP3430=y
@@ -232,10 +233,6 @@ CONFIG_ARM_THUMB=y
# CONFIG_ARM_THUMBEE is not set
# CONFIG_CPU_ICACHE_DISABLE is not set
# CONFIG_CPU_DCACHE_DISABLE is not set
-# CONFIG_CPU_LOCKDOWN_TO_64K_L2 is not set
-# CONFIG_CPU_LOCKDOWN_TO_128K_L2 is not set
-CONFIG_CPU_LOCKDOWN_TO_256K_L2=y
-# CONFIG_CPU_L2CACHE_DISABLE is not set
# CONFIG_CPU_BPREDICT_DISABLE is not set
CONFIG_HAS_TLS_REG=y
# CONFIG_OUTER_CACHE is not set
@@ -257,7 +254,7 @@ CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
# CONFIG_PREEMPT is not set
CONFIG_HZ=128
CONFIG_AEABI=y
-CONFIG_OABI_COMPAT=y
+# CONFIG_OABI_COMPAT is not set
# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
CONFIG_SELECT_MEMORY_MODEL=y
CONFIG_FLATMEM_MANUAL=y
@@ -286,6 +283,15 @@ CONFIG_CMDLINE=" quiet "
# CONFIG_KEXEC is not set
#
+# CPUIdle
+#
+
+#
+# CPU idle PM support
+#
+# CONFIG_CPU_IDLE is not set
+
+#
# CPU Frequency scaling
#
# CONFIG_CPU_FREQ is not set
@@ -297,9 +303,6 @@ CONFIG_CMDLINE=" quiet "
#
# At least one emulation must be selected
#
-CONFIG_FPE_NWFPE=y
-# CONFIG_FPE_NWFPE_XP is not set
-# CONFIG_FPE_FASTFPE is not set
CONFIG_VFP=y
CONFIG_VFPv3=y
# CONFIG_NEON is not set
@@ -593,9 +596,42 @@ CONFIG_HAVE_IDE=y
# SCSI device support
#
# CONFIG_RAID_ATTRS is not set
-# CONFIG_SCSI is not set
-# CONFIG_SCSI_DMA is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_SCSI_DEBUG is not set
# CONFIG_ATA is not set
# CONFIG_MD is not set
CONFIG_NETDEVICES=y
@@ -697,7 +733,10 @@ CONFIG_INPUT=y
#
# Userland interfaces
#
-# CONFIG_INPUT_MOUSEDEV is not set
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# CONFIG_INPUT_JOYDEV is not set
CONFIG_INPUT_EVDEV=y
CONFIG_INPUT_EVBUG=y
@@ -714,7 +753,18 @@ CONFIG_INPUT_KEYBOARD=y
# CONFIG_KEYBOARD_STOWAWAY is not set
# CONFIG_KEYBOARD_LM8323 is not set
# CONFIG_KEYBOARD_GPIO is not set
-# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+CONFIG_MOUSE_PS2_ALPS=y
+CONFIG_MOUSE_PS2_LOGIPS2PP=y
+CONFIG_MOUSE_PS2_SYNAPTICS=y
+CONFIG_MOUSE_PS2_LIFEBOOK=y
+CONFIG_MOUSE_PS2_TRACKPOINT=y
+# CONFIG_MOUSE_PS2_TOUCHKIT is not set
+# CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_APPLETOUCH is not set
+# CONFIG_MOUSE_VSXXXAA is not set
+# CONFIG_MOUSE_GPIO is not set
# CONFIG_INPUT_JOYSTICK is not set
# CONFIG_INPUT_TABLET is not set
CONFIG_INPUT_TOUCHSCREEN=y
@@ -737,7 +787,10 @@ CONFIG_TOUCHSCREEN_ADS7846=y
#
# Hardware I/O ports
#
-# CONFIG_SERIO is not set
+CONFIG_SERIO=y
+CONFIG_SERIO_SERPORT=y
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
# CONFIG_GAMEPORT is not set
#
@@ -950,9 +1003,17 @@ CONFIG_DUMMY_CONSOLE=y
CONFIG_FRAMEBUFFER_CONSOLE=y
# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
-# CONFIG_FONTS is not set
-CONFIG_FONT_8x8=y
+CONFIG_FONTS=y
+# CONFIG_FONT_8x8 is not set
CONFIG_FONT_8x16=y
+# CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_7x14 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_ACORN_8x8 is not set
+# CONFIG_FONT_MINI_4x6 is not set
+# CONFIG_FONT_SUN8x16 is not set
+# CONFIG_FONT_SUN12x22 is not set
+# CONFIG_FONT_10x18 is not set
# CONFIG_LOGO is not set
#
@@ -966,9 +1027,11 @@ CONFIG_SOUND=y
CONFIG_SND=y
CONFIG_SND_TIMER=y
CONFIG_SND_PCM=y
+CONFIG_SND_HWDEP=y
+CONFIG_SND_RAWMIDI=y
# CONFIG_SND_SEQUENCER is not set
CONFIG_SND_OSSEMUL=y
-# CONFIG_SND_MIXER_OSS is not set
+CONFIG_SND_MIXER_OSS=y
CONFIG_SND_PCM_OSS=y
CONFIG_SND_PCM_OSS_PLUGINS=y
# CONFIG_SND_DYNAMIC_MINORS is not set
@@ -1003,7 +1066,7 @@ CONFIG_SND_PCM_XRUN_DEBUG=y
#
# USB devices
#
-# CONFIG_SND_USB_AUDIO is not set
+CONFIG_SND_USB_AUDIO=y
# CONFIG_SND_USB_CAIAQ is not set
#
@@ -1027,8 +1090,6 @@ CONFIG_SND_SOC_TWL4030=y
# Open Sound System
#
CONFIG_SOUND_PRIME=y
-# CONFIG_SOUND_MSNDCLAS is not set
-# CONFIG_SOUND_MSNDPIN is not set
CONFIG_HID_SUPPORT=y
CONFIG_HID=y
# CONFIG_HID_DEBUG is not set
@@ -1077,7 +1138,7 @@ CONFIG_USB_OHCI_HCD=y
CONFIG_USB_OHCI_LITTLE_ENDIAN=y
CONFIG_USB_SL811_HCD=y
CONFIG_USB_R8A66597_HCD=y
-CONFIG_USB_MUSB_HDRC=m
+CONFIG_USB_MUSB_HDRC=y
CONFIG_USB_MUSB_SOC=y
#
@@ -1086,7 +1147,6 @@ CONFIG_USB_MUSB_SOC=y
CONFIG_USB_MUSB_HOST=y
# CONFIG_USB_MUSB_PERIPHERAL is not set
# CONFIG_USB_MUSB_OTG is not set
-# CONFIG_USB_GADGET_MUSB_HDRC is not set
CONFIG_USB_MUSB_HDRC_HCD=y
# CONFIG_MUSB_PIO_ONLY is not set
CONFIG_USB_INVENTRA_DMA=y
@@ -1098,6 +1158,7 @@ CONFIG_USB_MUSB_LOGLEVEL=0
#
# CONFIG_USB_ACM is not set
# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
#
# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
@@ -1106,12 +1167,27 @@ CONFIG_USB_MUSB_LOGLEVEL=0
#
# may also be needed; see USB_STORAGE Help for more information
#
-# CONFIG_USB_LIBUSUAL is not set
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+CONFIG_USB_LIBUSUAL=y
#
# USB Imaging devices
#
# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
CONFIG_USB_MON=y
#
@@ -1142,34 +1218,8 @@ CONFIG_USB_MON=y
# CONFIG_USB_TRANCEVIBRATOR is not set
# CONFIG_USB_IOWARRIOR is not set
# CONFIG_USB_TEST is not set
-CONFIG_USB_GADGET=m
-# CONFIG_USB_GADGET_DEBUG is not set
-# CONFIG_USB_GADGET_DEBUG_FILES is not set
-CONFIG_USB_GADGET_SELECTED=y
-# CONFIG_USB_GADGET_AMD5536UDC is not set
-# CONFIG_USB_GADGET_ATMEL_USBA is not set
-# CONFIG_USB_GADGET_FSL_USB2 is not set
-# CONFIG_USB_GADGET_NET2280 is not set
-# CONFIG_USB_GADGET_PXA2XX is not set
-# CONFIG_USB_GADGET_M66592 is not set
-# CONFIG_USB_GADGET_PXA27X is not set
-# CONFIG_USB_GADGET_GOKU is not set
-# CONFIG_USB_GADGET_LH7A40X is not set
-CONFIG_USB_GADGET_OMAP=y
-CONFIG_USB_OMAP=m
-# CONFIG_USB_GADGET_S3C2410 is not set
-# CONFIG_USB_GADGET_AT91 is not set
-# CONFIG_USB_GADGET_DUMMY_HCD is not set
-# CONFIG_USB_GADGET_DUALSPEED is not set
-# CONFIG_USB_ZERO is not set
-CONFIG_USB_ETH=m
-CONFIG_USB_ETH_RNDIS=y
-CONFIG_USB_GADGETFS=m
-CONFIG_USB_FILE_STORAGE=m
-# CONFIG_USB_FILE_STORAGE_TEST is not set
-CONFIG_USB_G_SERIAL=m
-# CONFIG_USB_MIDI_GADGET is not set
-CONFIG_USB_G_PRINTER=m
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_GADGET is not set
CONFIG_MMC=y
# CONFIG_MMC_DEBUG is not set
CONFIG_MMC_UNSAFE_RESUME=y
@@ -1180,6 +1230,7 @@ CONFIG_MMC_UNSAFE_RESUME=y
CONFIG_MMC_BLOCK=y
CONFIG_MMC_BLOCK_BOUNCE=y
CONFIG_SDIO_UART=m
+# CONFIG_MMC_TEST is not set
#
# MMC/SD Host Controller Drivers
@@ -1259,7 +1310,7 @@ CONFIG_EXT3_FS=y
CONFIG_JBD=y
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
-# CONFIG_FS_POSIX_ACL is not set
+CONFIG_FS_POSIX_ACL=y
CONFIG_XFS_FS=m
CONFIG_XFS_QUOTA=y
# CONFIG_XFS_POSIX_ACL is not set
@@ -1327,12 +1378,14 @@ CONFIG_JFFS2_FS_DEBUG=0
CONFIG_JFFS2_FS_WRITEBUFFER=y
# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
CONFIG_JFFS2_SUMMARY=y
-# CONFIG_JFFS2_FS_XATTR is not set
+CONFIG_JFFS2_FS_XATTR=y
+CONFIG_JFFS2_FS_POSIX_ACL=y
+CONFIG_JFFS2_FS_SECURITY=y
CONFIG_JFFS2_COMPRESSION_OPTIONS=y
CONFIG_JFFS2_ZLIB=y
-# CONFIG_JFFS2_LZO is not set
+CONFIG_JFFS2_LZO=y
CONFIG_JFFS2_RTIME=y
-# CONFIG_JFFS2_RUBIN is not set
+CONFIG_JFFS2_RUBIN=y
# CONFIG_JFFS2_CMODE_NONE is not set
CONFIG_JFFS2_CMODE_PRIORITY=y
# CONFIG_JFFS2_CMODE_SIZE is not set
@@ -1461,7 +1514,7 @@ CONFIG_FRAME_POINTER=y
# CONFIG_DEBUG_USER is not set
# CONFIG_DEBUG_ERRORS is not set
# CONFIG_DEBUG_STACK_USAGE is not set
-CONFIG_DEBUG_LL=y
+# CONFIG_DEBUG_LL is not set
# CONFIG_DEBUG_ICEDCC is not set
#
@@ -1561,6 +1614,8 @@ CONFIG_CRC32=y
CONFIG_LIBCRC32C=y
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=y
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
CONFIG_PLIST=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
diff --git a/packages/linux/linux-omap2-git/omap3evm/no-empty-flash-warnings.patch b/packages/linux/linux-omap2-git/omap3evm/no-empty-flash-warnings.patch
new file mode 100644
index 0000000000..ab344b0449
--- /dev/null
+++ b/packages/linux/linux-omap2-git/omap3evm/no-empty-flash-warnings.patch
@@ -0,0 +1,15 @@
+diff --git a/fs/jffs2/scan.c b/fs/jffs2/scan.c
+index 1d437de..33b3feb 100644
+--- a/fs/jffs2/scan.c
++++ b/fs/jffs2/scan.c
+@@ -647,8 +647,8 @@ scan_more:
+ inbuf_ofs = ofs - buf_ofs;
+ while (inbuf_ofs < scan_end) {
+ if (unlikely(*(uint32_t *)(&buf[inbuf_ofs]) != 0xffffffff)) {
+- printk(KERN_WARNING "Empty flash at 0x%08x ends at 0x%08x\n",
+- empty_start, ofs);
++// printk(KERN_WARNING "Empty flash at 0x%08x ends at 0x%08x\n",
++// empty_start, ofs);
+ if ((err = jffs2_scan_dirty_space(c, jeb, ofs-empty_start)))
+ return err;
+ goto scan_more;
diff --git a/packages/linux/linux-omap2-git/omap3evm/soc.patch b/packages/linux/linux-omap2-git/omap3evm/soc.patch
new file mode 100644
index 0000000000..f4cce21ca7
--- /dev/null
+++ b/packages/linux/linux-omap2-git/omap3evm/soc.patch
@@ -0,0 +1,1154 @@
+diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
+index 3903ab7..468536d 100644
+--- a/sound/soc/codecs/Kconfig
++++ b/sound/soc/codecs/Kconfig
+@@ -44,3 +44,7 @@ config SND_SOC_CS4270_VD33_ERRATA
+ config SND_SOC_TLV320AIC3X
+ tristate
+ depends on SND_SOC && I2C
++
++config SND_SOC_TWL4030
++ tristate
++ depends on SND_SOC && I2C
+diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
+index 4e1314c..d2c0b12 100644
+--- a/sound/soc/codecs/Makefile
++++ b/sound/soc/codecs/Makefile
+@@ -6,6 +6,7 @@ snd-soc-wm9712-objs := wm9712.o
+ snd-soc-wm9713-objs := wm9713.o
+ snd-soc-cs4270-objs := cs4270.o
+ snd-soc-tlv320aic3x-objs := tlv320aic3x.o
++snd-soc-twl4030-objs := twl4030.o
+
+ obj-$(CONFIG_SND_SOC_AC97_CODEC) += snd-soc-ac97.o
+ obj-$(CONFIG_SND_SOC_WM8731) += snd-soc-wm8731.o
+@@ -15,3 +16,4 @@ obj-$(CONFIG_SND_SOC_WM9712) += snd-soc-wm9712.o
+ obj-$(CONFIG_SND_SOC_WM9713) += snd-soc-wm9713.o
+ obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o
+ obj-$(CONFIG_SND_SOC_TLV320AIC3X) += snd-soc-tlv320aic3x.o
++obj-$(CONFIG_SND_SOC_TWL4030) += snd-soc-twl4030.o
+diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c
+new file mode 100644
+index 0000000..eb8370c
+--- /dev/null
++++ b/sound/soc/codecs/twl4030.c
+@@ -0,0 +1,625 @@
++/*
++ * ALSA SoC TWL4030 codec driver
++ *
++ * Author: Steve Sakoman, <steve@sakoman.com>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++#include <linux/module.h>
++#include <linux/moduleparam.h>
++#include <linux/init.h>
++#include <linux/delay.h>
++#include <linux/pm.h>
++#include <linux/i2c.h>
++#include <linux/platform_device.h>
++#include <linux/i2c/twl4030.h>
++#include <sound/core.h>
++#include <sound/pcm.h>
++#include <sound/pcm_params.h>
++#include <sound/soc.h>
++#include <sound/soc-dapm.h>
++#include <sound/initval.h>
++
++#include "twl4030.h"
++
++/*
++ * twl4030 register cache & default register settings
++ */
++static const u8 twl4030_reg[TWL4030_CACHEREGNUM] = {
++ 0x00, // this register not used
++ 0x93, // REG_CODEC_MODE (0x1)
++ 0xc3, // REG_OPTION (0x2)
++ 0x00, // REG_UNKNOWN (0x3)
++ 0x00, // REG_MICBIAS_CTL (0x4)
++ 0x34, // REG_ANAMICL (0x5)
++ 0x14, // REG_ANAMICR (0x6)
++ 0x0a, // REG_AVADC_CTL (0x7)
++ 0x00, // REG_ADCMICSEL (0x8)
++ 0x00, // REG_DIGMIXING (0x9)
++ 0x0c, // REG_ATXL1PGA (0xA)
++ 0x0c, // REG_ATXR1PGA (0xB)
++ 0x00, // REG_AVTXL2PGA (0xC)
++ 0x00, // REG_AVTXR2PGA (0xD)
++ 0x01, // REG_AUDIO_IF (0xE)
++ 0x00, // REG_VOICE_IF (0xF)
++ 0x00, // REG_ARXR1PGA (0x10)
++ 0x00, // REG_ARXL1PGA (0x11)
++ 0x6c, // REG_ARXR2PGA (0x12)
++ 0x6c, // REG_ARXL2PGA (0x13)
++ 0x00, // REG_VRXPGA (0x14)
++ 0x00, // REG_VSTPGA (0x15)
++ 0x00, // REG_VRX2ARXPGA (0x16)
++ 0x0c, // REG_AVDAC_CTL (0x17)
++ 0x00, // REG_ARX2VTXPGA (0x18)
++ 0x00, // REG_ARXL1_APGA_CTL (0x19)
++ 0x00, // REG_ARXR1_APGA_CTL (0x1A)
++ 0x4b, // REG_ARXL2_APGA_CTL (0x1B)
++ 0x4b, // REG_ARXR2_APGA_CTL (0x1C)
++ 0x00, // REG_ATX2ARXPGA (0x1D)
++ 0x00, // REG_BT_IF (0x1E)
++ 0x00, // REG_BTPGA (0x1F)
++ 0x00, // REG_BTSTPGA (0x20)
++ 0x00, // REG_EAR_CTL (0x21)
++ 0x24, // REG_HS_SEL (0x22)
++ 0x0a, // REG_HS_GAIN_SET (0x23)
++ 0x00, // REG_HS_POPN_SET (0x24)
++ 0x00, // REG_PREDL_CTL (0x25)
++ 0x00, // REG_PREDR_CTL (0x26)
++ 0x00, // REG_PRECKL_CTL (0x27)
++ 0x00, // REG_PRECKR_CTL (0x28)
++ 0x00, // REG_HFL_CTL (0x29)
++ 0x00, // REG_HFR_CTL (0x2A)
++ 0x00, // REG_ALC_CTL (0x2B)
++ 0x00, // REG_ALC_SET1 (0x2C)
++ 0x00, // REG_ALC_SET2 (0x2D)
++ 0x00, // REG_BOOST_CTL (0x2E)
++ 0x01, // REG_SOFTVOL_CTL (0x2F)
++ 0x00, // REG_DTMF_FREQSEL (0x30)
++ 0x00, // REG_DTMF_TONEXT1H (0x31)
++ 0x00, // REG_DTMF_TONEXT1L (0x32)
++ 0x00, // REG_DTMF_TONEXT2H (0x33)
++ 0x00, // REG_DTMF_TONEXT2L (0x34)
++ 0x00, // REG_DTMF_TONOFF (0x35)
++ 0x00, // REG_DTMF_WANONOFF (0x36)
++ 0x00, // REG_I2S_RX_SCRAMBLE_H (0x37)
++ 0x00, // REG_I2S_RX_SCRAMBLE_M (0x38)
++ 0x00, // REG_I2S_RX_SCRAMBLE_L (0x39)
++ 0x16, // REG_APLL_CTL (0x3A)
++ 0x00, // REG_DTMF_CTL (0x3B)
++ 0x00, // REG_DTMF_PGA_CTL2 (0x3C)
++ 0x00, // REG_DTMF_PGA_CTL1 (0x3D)
++ 0x00, // REG_MISC_SET_1 (0x3E)
++ 0x00, // REG_PCMBTMUX (0x3F)
++ 0x00, // REG_RX_PATH_SEL (0x43)
++ 0x00, // REG_VDL_APGA_CTL (0x44)
++ 0x00, // REG_VIBRA_CTL (0x45)
++ 0x00, // REG_VIBRA_SET (0x46)
++ 0x00, // REG_VIBRA_PWM_SET (0x47)
++ 0x00, // REG_ANAMIC_GAIN (0x48)
++ 0x00, // REG_MISC_SET_2 (0x49)
++};
++
++static void twl4030_dump_registers(void)
++{
++ int i = 0;
++ u8 data;
++
++ printk(KERN_INFO "TWL 4030 Register dump for Audio Module\n");
++
++ for (i = REG_CODEC_MODE; i <= REG_MISC_SET_2; i++) {
++ twl4030_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &data, i);
++ printk(KERN_INFO "Register[0x%02x]=0x%02x\n", i, data);
++ }
++}
++
++struct twl4030_priv {
++ unsigned int dummy;
++};
++
++/*
++ * read twl4030 register cache
++ */
++static inline unsigned int twl4030_read_reg_cache(struct snd_soc_codec *codec,
++ unsigned int reg)
++{
++ u8 *cache = codec->reg_cache;
++
++ return cache[reg];
++}
++
++/*
++ * write twl4030 register cache
++ */
++static inline void twl4030_write_reg_cache(struct snd_soc_codec *codec,
++ u8 reg, u8 value)
++{
++ u8 *cache = codec->reg_cache;
++
++ if (reg >= TWL4030_CACHEREGNUM)
++ return;
++ cache[reg] = value;
++}
++
++/*
++ * write to the twl4030 register space
++ */
++static int twl4030_write(struct snd_soc_codec *codec,
++ unsigned int reg, unsigned int value)
++{
++ twl4030_write_reg_cache(codec, reg, value);
++ return twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, value, reg);
++}
++
++static void twl4030_init_chip(void)
++{
++ unsigned char byte;
++ int i;
++
++ twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
++ twl4030_reg[REG_CODEC_MODE] & 0xfd, REG_CODEC_MODE);
++
++ udelay(10); /* delay for power settling */
++
++ for (i = REG_OPTION; i <= REG_MISC_SET_2; i++) {
++ twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, twl4030_reg[i], i);
++ }
++
++ twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
++ twl4030_reg[REG_CODEC_MODE], REG_CODEC_MODE);
++
++ udelay(10); /* delay for power settling */
++
++ /* initiate offset cancellation */
++ twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
++ twl4030_reg[REG_ANAMICL] | 0x80, REG_ANAMICL);
++
++ /* wait for offset cancellation to complete */
++ twl4030_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &byte, REG_ANAMICL);
++ while ((byte & 0x80) == 0x80)
++ twl4030_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &byte, REG_ANAMICL);
++
++ twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
++ twl4030_reg[REG_MISC_SET_1] | 0x02, REG_MISC_SET_1);
++
++}
++
++static const struct snd_kcontrol_new twl4030_snd_controls[] = {
++ SOC_DOUBLE_R("Master Playback Volume",
++ REG_ARXL2PGA, REG_ARXR2PGA,
++ 0, 127, 0),
++ SOC_DOUBLE_R("Capture Volume",
++ REG_ATXL1PGA, REG_ATXR1PGA,
++ 0, 127, 0),
++};
++
++/* add non dapm controls */
++static int twl4030_add_controls(struct snd_soc_codec *codec)
++{
++ int err, i;
++
++ for (i = 0; i < ARRAY_SIZE(twl4030_snd_controls); i++) {
++ err = snd_ctl_add(codec->card,
++ snd_soc_cnew(&twl4030_snd_controls[i],
++ codec, NULL));
++ if (err < 0)
++ return err;
++ }
++
++ return 0;
++}
++
++static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
++ SND_SOC_DAPM_INPUT("INL"),
++ SND_SOC_DAPM_INPUT("INR"),
++
++ SND_SOC_DAPM_OUTPUT("OUTL"),
++ SND_SOC_DAPM_OUTPUT("OUTR"),
++
++ SND_SOC_DAPM_DAC("DACL", "Left Playback", SND_SOC_NOPM, 0, 0),
++ SND_SOC_DAPM_DAC("DACR", "Right Playback", SND_SOC_NOPM, 0, 0),
++
++ SND_SOC_DAPM_ADC("ADCL", "Left Capture", SND_SOC_NOPM, 0, 0),
++ SND_SOC_DAPM_ADC("ADCR", "Right Capture", SND_SOC_NOPM, 0, 0),
++};
++
++static const char *intercon[][3] = {
++ /* outputs */
++ {"OUTL", NULL, "DACL"},
++ {"OUTR", NULL, "DACR"},
++
++ /* inputs */
++ {"ADCL", NULL, "INL"},
++ {"ADCR", NULL, "INR"},
++
++ /* terminator */
++ {NULL, NULL, NULL},
++};
++
++static int twl4030_add_widgets(struct snd_soc_codec *codec)
++{
++ int i;
++
++ for (i = 0; i < ARRAY_SIZE(twl4030_dapm_widgets); i++)
++ snd_soc_dapm_new_control(codec, &twl4030_dapm_widgets[i]);
++
++ /* set up audio path interconnects */
++ for (i = 0; intercon[i][0] != NULL; i++)
++ snd_soc_dapm_connect_input(codec, intercon[i][0],
++ intercon[i][1], intercon[i][2]);
++
++ snd_soc_dapm_new_widgets(codec);
++ return 0;
++}
++
++static int twl4030_dapm_event(struct snd_soc_codec *codec, int event)
++{
++
++ printk(KERN_INFO "TWL4030 Audio Codec dapm event\n");
++ switch (event) {
++ case SNDRV_CTL_POWER_D0: /* full On */
++ break;
++ case SNDRV_CTL_POWER_D1: /* partial On */
++ case SNDRV_CTL_POWER_D2: /* partial On */
++ break;
++ case SNDRV_CTL_POWER_D3hot: /* off, with power */
++ break;
++ case SNDRV_CTL_POWER_D3cold: /* off, without power */
++ break;
++ }
++ codec->dapm_state = event;
++
++ return 0;
++}
++
++static void twl4030_power_up (struct snd_soc_codec *codec, u8 mode)
++{
++ u8 popn, hsgain;
++
++ twl4030_write(codec, REG_CODEC_MODE, mode & ~CODECPDZ);
++ twl4030_write(codec, REG_CODEC_MODE, mode | CODECPDZ);
++ udelay(10);
++
++ popn = twl4030_read_reg_cache(codec, REG_HS_POPN_SET);
++ popn &= RAMP_DELAY;
++ popn |= VMID_EN | RAMP_DELAY_161MS;
++ twl4030_write(codec, REG_HS_POPN_SET, popn);
++
++ hsgain = HSR_GAIN_0DB| HSL_GAIN_0DB;
++ twl4030_write(codec, REG_HS_GAIN_SET, hsgain);
++
++ popn |= RAMP_EN;
++ twl4030_write(codec, REG_HS_POPN_SET, popn);
++}
++
++static void twl4030_power_down (struct snd_soc_codec *codec)
++{
++ u8 popn, hsgain, mode;
++
++ popn = twl4030_read_reg_cache(codec, REG_HS_POPN_SET);
++ popn &= ~RAMP_EN;
++ twl4030_write(codec, REG_HS_POPN_SET, popn);
++
++ hsgain = HSR_GAIN_PWR_DOWN | HSL_GAIN_PWR_DOWN;
++ twl4030_write(codec, REG_HS_GAIN_SET, hsgain);
++
++ popn &= ~VMID_EN;
++ twl4030_write(codec, REG_HS_POPN_SET, popn);
++
++ mode = twl4030_read_reg_cache(codec, REG_CODEC_MODE);
++ mode &= ~CODECPDZ;
++ twl4030_write(codec, REG_CODEC_MODE, mode);
++ udelay(10);
++}
++
++
++static int twl4030_hw_params(struct snd_pcm_substream *substream,
++ struct snd_pcm_hw_params *params)
++{
++ struct snd_soc_pcm_runtime *rtd = substream->private_data;
++ struct snd_soc_device *socdev = rtd->socdev;
++ struct snd_soc_codec *codec = socdev->codec;
++ struct twl4030_priv *twl4030 = codec->private_data;
++ u8 mode, old_mode, format, old_format;
++
++
++ /* bit rate */
++ old_mode = twl4030_read_reg_cache(codec, REG_CODEC_MODE) & ~CODECPDZ;
++ mode = old_mode;
++ mode &= ~APLL_RATE;
++ switch (params_rate(params)) {
++ case 44100:
++ mode |= APLL_RATE_44100;
++ break;
++ case 48000:
++ mode |= APLL_RATE_48000;
++ break;
++ default:
++ printk(KERN_INFO "TWL4030 hw params: unknown rate %d\n", params_rate(params));
++ return -EINVAL;
++ }
++
++ if (mode != old_mode) {
++ /* change rate and turn codec back on */
++ twl4030_write(codec, REG_CODEC_MODE, mode);
++ mode |= CODECPDZ;
++ twl4030_write(codec, REG_CODEC_MODE, mode);
++ }
++
++ /* sample size */
++ old_format = twl4030_read_reg_cache(codec, REG_AUDIO_IF);
++ format = old_format;
++ format &= ~DATA_WIDTH;
++ switch (params_format(params)) {
++ case SNDRV_PCM_FORMAT_S16_LE:
++ format |= DATA_WIDTH_16S_16W;
++ break;
++ case SNDRV_PCM_FORMAT_S24_LE:
++ format |= DATA_WIDTH_32S_24W;
++ break;
++ default:
++ printk(KERN_INFO "TWL4030 hw params: unknown format %d\n", params_format(params));
++ return -EINVAL;
++ }
++
++ if (format != old_format) {
++
++ /* turn off codec before changing format */
++ mode = twl4030_read_reg_cache(codec, REG_CODEC_MODE);
++ mode &= ~CODECPDZ;
++ twl4030_write(codec, REG_CODEC_MODE, mode);
++
++ /* change format */
++ twl4030_write(codec, REG_AUDIO_IF, format);
++
++ /* turn on codec */
++ mode |= CODECPDZ;
++ twl4030_write(codec, REG_CODEC_MODE, mode);
++ }
++ return 0;
++}
++
++static int twl4030_mute(struct snd_soc_codec_dai *dai, int mute)
++{
++ struct snd_soc_codec *codec = dai->codec;
++
++ u8 ldac_reg = twl4030_read_reg_cache(codec, REG_ARXL2PGA);
++ u8 rdac_reg = twl4030_read_reg_cache(codec, REG_ARXR2PGA);
++
++ if (mute) {
++ /* printk(KERN_INFO "TWL4030 Audio Codec mute\n"); */
++ twl4030_write(codec, REG_ARXL2PGA, 0x00);
++ twl4030_write(codec, REG_ARXR2PGA, 0x00);
++ twl4030_write_reg_cache(codec, REG_ARXL2PGA, ldac_reg);
++ twl4030_write_reg_cache(codec, REG_ARXR2PGA, rdac_reg);
++ }
++ else {
++ /* printk(KERN_INFO "TWL4030 Audio Codec unmute: %02x/%02x\n", ldac_reg, rdac_reg); */
++ twl4030_write(codec, REG_ARXL2PGA, ldac_reg);
++ twl4030_write(codec, REG_ARXR2PGA, rdac_reg);
++ }
++
++ return 0;
++}
++
++static int twl4030_set_dai_fmt(struct snd_soc_codec_dai *codec_dai,
++ unsigned int fmt)
++{
++ struct snd_soc_codec *codec = codec_dai->codec;
++ struct twl4030_priv *twl4030 = codec->private_data;
++ u8 mode, old_format, format;
++
++ /* get format */
++ old_format = twl4030_read_reg_cache(codec, REG_AUDIO_IF);
++ format = old_format;
++
++ /* set master/slave audio interface */
++ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
++ case SND_SOC_DAIFMT_CBM_CFM:
++ /* printk(KERN_INFO "TWL4030 set dai fmt: master\n"); */
++ format &= ~(AIF_SLAVE_EN);
++ format |= CLK256FS_EN;
++ break;
++ case SND_SOC_DAIFMT_CBS_CFS:
++ /* printk(KERN_INFO "TWL4030 set dai fmt: slave\n"); */
++ format &= ~(CLK256FS_EN);
++ format |= AIF_SLAVE_EN;
++ break;
++ default:
++ return -EINVAL;
++ }
++
++ /* interface format */
++ format &= ~AIF_FORMAT;
++ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
++ case SND_SOC_DAIFMT_I2S:
++ /* printk(KERN_INFO "TWL4030 set dai fmt: i2s\n"); */
++ format |= AIF_FORMAT_CODEC;
++ break;
++ default:
++ return -EINVAL;
++ }
++
++ if (format != old_format) {
++
++ /* turn off codec before changing format */
++ mode = twl4030_read_reg_cache(codec, REG_CODEC_MODE);
++ mode &= ~CODECPDZ;
++ twl4030_write(codec, REG_CODEC_MODE, mode);
++
++ /* change format */
++ twl4030_write(codec, REG_AUDIO_IF, format);
++
++ mode |= CODECPDZ;
++ twl4030_write(codec, REG_CODEC_MODE, mode);
++ }
++
++ return 0;
++}
++
++#define TWL4030_RATES SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000
++#define TWL4030_FORMATS SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FORMAT_S24_LE
++
++struct snd_soc_codec_dai twl4030_dai = {
++ .name = "twl4030",
++ .playback = {
++ .stream_name = "Playback",
++ .channels_min = 2,
++ .channels_max = 2,
++ .rates = TWL4030_RATES,
++ .formats = TWL4030_FORMATS,},
++ .capture = {
++ .stream_name = "Capture",
++ .channels_min = 2,
++ .channels_max = 2,
++ .rates = TWL4030_RATES,
++ .formats = TWL4030_FORMATS,},
++ .ops = {
++ .hw_params = twl4030_hw_params,
++ },
++ .dai_ops = {
++ .digital_mute = twl4030_mute,
++ .set_fmt = twl4030_set_dai_fmt,
++ }
++};
++
++EXPORT_SYMBOL_GPL(twl4030_dai);
++
++static int twl4030_suspend(struct platform_device *pdev, pm_message_t state)
++{
++ struct snd_soc_device *socdev = platform_get_drvdata(pdev);
++ struct snd_soc_codec *codec = socdev->codec;
++
++ printk(KERN_INFO "TWL4030 Audio Codec suspend\n");
++ twl4030_dapm_event(codec, SNDRV_CTL_POWER_D3cold);
++
++ return 0;
++}
++
++static int twl4030_resume(struct platform_device *pdev)
++{
++ struct snd_soc_device *socdev = platform_get_drvdata(pdev);
++ struct snd_soc_codec *codec = socdev->codec;
++ int i;
++ u16 *cache = codec->reg_cache;
++
++ printk(KERN_INFO "TWL4030 Audio Codec resume\n");
++ /* Sync reg_cache with the hardware */
++ for (i = REG_CODEC_MODE; i <= REG_MISC_SET_2; i++) {
++ twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, cache[i], i);
++ }
++ twl4030_dapm_event(codec, SNDRV_CTL_POWER_D3hot);
++ twl4030_dapm_event(codec, codec->suspend_dapm_state);
++ return 0;
++}
++
++/*
++ * initialize the driver
++ * register the mixer and dsp interfaces with the kernel
++ */
++
++static int twl4030_init(struct snd_soc_device *socdev)
++{
++ struct snd_soc_codec *codec = socdev->codec;
++ int ret = 0;
++
++ printk(KERN_INFO "TWL4030 Audio Codec init \n");
++
++ codec->name = "twl4030";
++ codec->owner = THIS_MODULE;
++ codec->read = twl4030_read_reg_cache;
++ codec->write = twl4030_write;
++ codec->dapm_event = twl4030_dapm_event;
++ codec->dai = &twl4030_dai;
++ codec->num_dai = 1;
++ codec->reg_cache_size = sizeof(twl4030_reg);
++ codec->reg_cache = kmemdup(twl4030_reg, sizeof(twl4030_reg), GFP_KERNEL);
++ if (codec->reg_cache == NULL)
++ return -ENOMEM;
++
++ /* register pcms */
++ ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
++ if (ret < 0) {
++ printk(KERN_ERR "twl4030: failed to create pcms\n");
++ goto pcm_err;
++ }
++
++ twl4030_add_controls(codec);
++ twl4030_add_widgets(codec);
++
++ ret = snd_soc_register_card(socdev);
++ if (ret < 0) {
++ printk(KERN_ERR "twl4030: failed to register card\n");
++ goto card_err;
++ }
++
++ twl4030_init_chip();
++ twl4030_power_up(codec, APLL_RATE_44100 | OPT_MODE);
++
++ return ret;
++
++card_err:
++ printk(KERN_INFO "TWL4030 Audio Codec init card error\n");
++ snd_soc_free_pcms(socdev);
++ snd_soc_dapm_free(socdev);
++pcm_err:
++ printk(KERN_INFO "TWL4030 Audio Codec init pcm error\n");
++ kfree(codec->reg_cache);
++ return ret;
++}
++
++static struct snd_soc_device *twl4030_socdev;
++
++static int twl4030_probe(struct platform_device *pdev)
++{
++ struct snd_soc_device *socdev = platform_get_drvdata(pdev);
++ struct snd_soc_codec *codec;
++ struct twl4030_priv *twl4030;
++
++ codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
++ if (codec == NULL)
++ return -ENOMEM;
++
++ twl4030 = kzalloc(sizeof(struct twl4030_priv), GFP_KERNEL);
++ if (twl4030 == NULL) {
++ kfree(codec);
++ return -ENOMEM;
++ }
++
++ codec->private_data = twl4030;
++ socdev->codec = codec;
++ mutex_init(&codec->mutex);
++ INIT_LIST_HEAD(&codec->dapm_widgets);
++ INIT_LIST_HEAD(&codec->dapm_paths);
++
++ twl4030_socdev = socdev;
++ twl4030_init(socdev);
++
++ return 0;
++}
++
++static int twl4030_remove(struct platform_device *pdev)
++{
++ struct snd_soc_device *socdev = platform_get_drvdata(pdev);
++ struct snd_soc_codec *codec = socdev->codec;
++
++ printk(KERN_INFO "TWL4030 Audio Codec remove\n");
++ kfree(codec->private_data);
++ kfree(codec);
++
++ return 0;
++}
++
++struct snd_soc_codec_device soc_codec_dev_twl4030 = {
++ .probe = twl4030_probe,
++ .remove = twl4030_remove,
++ .suspend = twl4030_suspend,
++ .resume = twl4030_resume,
++};
++EXPORT_SYMBOL_GPL(soc_codec_dev_twl4030);
++
++MODULE_DESCRIPTION("ASoC TWL4030 codec driver");
++MODULE_AUTHOR("Steve Sakoman");
++MODULE_LICENSE("GPL");
+diff --git a/sound/soc/codecs/twl4030.h b/sound/soc/codecs/twl4030.h
+new file mode 100644
+index 0000000..e126f96
+--- /dev/null
++++ b/sound/soc/codecs/twl4030.h
+@@ -0,0 +1,152 @@
++/*
++ * ALSA SoC TWL4030 codec driver
++ *
++ * Author: Steve Sakoman, <steve@sakoman.com>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++#ifndef __TWL4030_AUDIO_H__
++#define __TWL4030_AUDIO_H__
++
++#define REG_CODEC_MODE 0x1
++#define REG_OPTION 0x2
++#define REG_UNKNOWN 0x3
++#define REG_MICBIAS_CTL 0x4
++#define REG_ANAMICL 0x5
++#define REG_ANAMICR 0x6
++#define REG_AVADC_CTL 0x7
++#define REG_ADCMICSEL 0x8
++#define REG_DIGMIXING 0x9
++#define REG_ATXL1PGA 0xA
++#define REG_ATXR1PGA 0xB
++#define REG_AVTXL2PGA 0xC
++#define REG_AVTXR2PGA 0xD
++#define REG_AUDIO_IF 0xE
++#define REG_VOICE_IF 0xF
++#define REG_ARXR1PGA 0x10
++#define REG_ARXL1PGA 0x11
++#define REG_ARXR2PGA 0x12
++#define REG_ARXL2PGA 0x13
++#define REG_VRXPGA 0x14
++#define REG_VSTPGA 0x15
++#define REG_VRX2ARXPGA 0x16
++#define REG_AVDAC_CTL 0x17
++#define REG_ARX2VTXPGA 0x18
++#define REG_ARXL1_APGA_CTL 0x19
++#define REG_ARXR1_APGA_CTL 0x1A
++#define REG_ARXL2_APGA_CTL 0x1B
++#define REG_ARXR2_APGA_CTL 0x1C
++#define REG_ATX2ARXPGA 0x1D
++#define REG_BT_IF 0x1E
++#define REG_BTPGA 0x1F
++#define REG_BTSTPGA 0x20
++#define REG_EAR_CTL 0x21
++#define REG_HS_SEL 0x22
++#define REG_HS_GAIN_SET 0x23
++#define REG_HS_POPN_SET 0x24
++#define REG_PREDL_CTL 0x25
++#define REG_PREDR_CTL 0x26
++#define REG_PRECKL_CTL 0x27
++#define REG_PRECKR_CTL 0x28
++#define REG_HFL_CTL 0x29
++#define REG_HFR_CTL 0x2A
++#define REG_ALC_CTL 0x2B
++#define REG_ALC_SET1 0x2C
++#define REG_ALC_SET2 0x2D
++#define REG_BOOST_CTL 0x2E
++#define REG_SOFTVOL_CTL 0x2F
++#define REG_DTMF_FREQSEL 0x30
++#define REG_DTMF_TONEXT1H 0x31
++#define REG_DTMF_TONEXT1L 0x32
++#define REG_DTMF_TONEXT2H 0x33
++#define REG_DTMF_TONEXT2L 0x34
++#define REG_DTMF_TONOFF 0x35
++#define REG_DTMF_WANONOFF 0x36
++#define REG_I2S_RX_SCRAMBLE_H 0x37
++#define REG_I2S_RX_SCRAMBLE_M 0x38
++#define REG_I2S_RX_SCRAMBLE_L 0x39
++#define REG_APLL_CTL 0x3A
++#define REG_DTMF_CTL 0x3B
++#define REG_DTMF_PGA_CTL2 0x3C
++#define REG_DTMF_PGA_CTL1 0x3D
++#define REG_MISC_SET_1 0x3E
++#define REG_PCMBTMUX 0x3F
++#define REG_RX_PATH_SEL 0x43
++#define REG_VDL_APGA_CTL 0x44
++#define REG_VIBRA_CTL 0x45
++#define REG_VIBRA_SET 0x46
++#define REG_VIBRA_PWM_SET 0x47
++#define REG_ANAMIC_GAIN 0x48
++#define REG_MISC_SET_2 0x49
++
++#define TWL4030_CACHEREGNUM REG_MISC_SET_2 + 1
++
++/* Bitfield Definitions */
++
++/* CODEC_MODE (0x01) Fields */
++
++#define APLL_RATE 0xF0
++#define APLL_RATE_8000 0x00
++#define APLL_RATE_11025 0x10
++#define APLL_RATE_12000 0x20
++#define APLL_RATE_16000 0x40
++#define APLL_RATE_22050 0x50
++#define APLL_RATE_24000 0x60
++#define APLL_RATE_32000 0x80
++#define APLL_RATE_44100 0x90
++#define APLL_RATE_48000 0xa0
++#define SEL_16K 0x04
++#define CODECPDZ 0x02
++#define OPT_MODE 0x01
++
++/* AUDIO_IF (0x0E) Fields */
++
++#define AIF_SLAVE_EN 0x80
++#define DATA_WIDTH 0x60
++#define DATA_WIDTH_16S_16W 0x00
++#define DATA_WIDTH_32S_16W 0x40
++#define DATA_WIDTH_32S_24W 0x60
++#define AIF_FORMAT 0x18
++#define AIF_FORMAT_CODEC 0x00
++#define AIF_FORMAT_LEFT 0x08
++#define AIF_FORMAT_RIGHT 0x10
++#define AIF_FORMAT_TDM 0x18
++#define AIF_TRI_EN 0x04
++#define CLK256FS_EN 0x02
++#define AIF_EN 0x01
++
++/* HS_GAIN_SET (0x23) Fields */
++
++#define HSR_GAIN 0x0c
++#define HSR_GAIN_PWR_DOWN 0x00
++#define HSR_GAIN_PLUS_6DB 0x04
++#define HSR_GAIN_0DB 0x08
++#define HSR_GAIN_MINUS_6DB 0x0c
++#define HSL_GAIN 0x0c
++#define HSL_GAIN_PWR_DOWN 0x00
++#define HSL_GAIN_PLUS_6DB 0x01
++#define HSL_GAIN_0DB 0x02
++#define HSL_GAIN_MINUS_6DB 0x03
++
++/* HS_POPN_SET (0x24) Fields */
++
++#define VMID_EN 0x40
++#define EXTMUTE 0x20
++#define RAMP_DELAY 0x1C
++#define RAMP_DELAY_20MS 0x00
++#define RAMP_DELAY_40MS 0x04
++#define RAMP_DELAY_81MS 0x08
++#define RAMP_DELAY_161MS 0x0c
++#define RAMP_DELAY_323MS 0x10
++#define RAMP_DELAY_645MS 0x14
++#define RAMP_DELAY_1291MS 0x18
++#define RAMP_DELAY_2581MS 0x1c
++#define RAMP_EN 0x02
++
++extern struct snd_soc_codec_dai twl4030_dai;
++extern struct snd_soc_codec_device soc_codec_dev_twl4030;
++
++#endif /* End of __TWL4030_AUDIO_H__ */
+diff --git a/sound/soc/omap/Kconfig b/sound/soc/omap/Kconfig
+index 0230d83..8703cea 100644
+--- a/sound/soc/omap/Kconfig
++++ b/sound/soc/omap/Kconfig
+@@ -16,4 +16,20 @@ config SND_OMAP_SOC_N810
+ help
+ Say Y if you want to add support for SoC audio on Nokia N810.
+
++config SND_OMAP_SOC_OMAP3EVM
++ tristate "SoC Audio support for OMAP3 EVM"
++ depends on SND_OMAP_SOC && MACH_OMAP3EVM
++ select SND_OMAP_SOC_MCBSP
++ select SND_SOC_TWL4030
++ help
++ Say Y if you want to add support for SoC audio on the OMAP3 EVM.
++
++config SND_OMAP_SOC_OMAP3BEAGLE
++ tristate "SoC Audio support for OMAP3 Beagle"
++ depends on SND_OMAP_SOC && MACH_OMAP3_BEAGLE
++ select SND_OMAP_SOC_MCBSP
++ select SND_SOC_TWL4030
++ help
++ Say Y if you want to add support for SoC audio on the OMAP3 Beagle.
++
+ endmenu
+diff --git a/sound/soc/omap/Makefile b/sound/soc/omap/Makefile
+index d8d8d58..638a240 100644
+--- a/sound/soc/omap/Makefile
++++ b/sound/soc/omap/Makefile
+@@ -7,5 +7,10 @@ obj-$(CONFIG_SND_OMAP_SOC_MCBSP) += snd-soc-omap-mcbsp.o
+
+ # OMAP Machine Support
+ snd-soc-n810-objs := n810.o
++snd-soc-omap3evm-objs := omap3evm.o
++snd-soc-omap3beagle-objs := omap3beagle.o
+
+ obj-$(CONFIG_SND_OMAP_SOC_N810) += snd-soc-n810.o
++obj-$(CONFIG_SND_OMAP_SOC_OMAP3EVM) += snd-soc-omap3evm.o
++obj-$(CONFIG_SND_OMAP_SOC_OMAP3BEAGLE) += snd-soc-omap3beagle.o
++
+diff --git a/sound/soc/omap/omap3beagle.c b/sound/soc/omap/omap3beagle.c
+new file mode 100644
+index 0000000..878f894
+--- /dev/null
++++ b/sound/soc/omap/omap3beagle.c
+@@ -0,0 +1,142 @@
++/*
++ * omap3beagle.c -- SoC audio for OMAP3 Beagle
++ *
++ * Author: Steve Sakoman <steve@sakoman.com>
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * version 2 as published by the Free Software Foundation.
++ *
++ * 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., 51 Franklin St, Fifth Floor, Boston, MA
++ * 02110-1301 USA
++ *
++ */
++
++#include <linux/clk.h>
++#include <linux/platform_device.h>
++#include <sound/core.h>
++#include <sound/pcm.h>
++#include <sound/soc.h>
++#include <sound/soc-dapm.h>
++
++#include <asm/mach-types.h>
++#include <asm/arch/hardware.h>
++#include <asm/arch/gpio.h>
++#include <asm/arch/mcbsp.h>
++
++#include "omap-mcbsp.h"
++#include "omap-pcm.h"
++#include "../codecs/twl4030.h"
++
++static int omap3beagle_hw_params(struct snd_pcm_substream *substream,
++ struct snd_pcm_hw_params *params)
++{
++ struct snd_soc_pcm_runtime *rtd = substream->private_data;
++ struct snd_soc_codec_dai *codec_dai = rtd->dai->codec_dai;
++ struct snd_soc_cpu_dai *cpu_dai = rtd->dai->cpu_dai;
++ int ret;
++
++ /* Set codec DAI configuration */
++ ret = codec_dai->dai_ops.set_fmt(codec_dai,
++ SND_SOC_DAIFMT_I2S |
++ SND_SOC_DAIFMT_NB_NF |
++ SND_SOC_DAIFMT_CBM_CFM);
++ if (ret < 0) {
++ printk(KERN_INFO "can't set codec DAI configuration\n");
++ return ret;
++ }
++
++ /* Set cpu DAI configuration */
++ ret = cpu_dai->dai_ops.set_fmt(cpu_dai,
++ SND_SOC_DAIFMT_I2S |
++ SND_SOC_DAIFMT_NB_NF |
++ SND_SOC_DAIFMT_CBM_CFM);
++ if (ret < 0) {
++ printk(KERN_INFO "can't set cpu DAI configuration\n");
++ return ret;
++ }
++
++ return 0;
++}
++
++static struct snd_soc_ops omap3beagle_ops = {
++ .hw_params = omap3beagle_hw_params,
++};
++
++/* Digital audio interface glue - connects codec <--> CPU */
++static struct snd_soc_dai_link omap3beagle_dai = {
++ .name = "TWL4030",
++ .stream_name = "TWL4030",
++ .cpu_dai = &omap_mcbsp_dai[0],
++ .codec_dai = &twl4030_dai,
++ .ops = &omap3beagle_ops,
++};
++
++/* Audio machine driver */
++static struct snd_soc_machine snd_soc_machine_omap3beagle = {
++ .name = "omap3beagle",
++ .dai_link = &omap3beagle_dai,
++ .num_links = 1,
++};
++
++/* Audio subsystem */
++static struct snd_soc_device omap3beagle_snd_devdata = {
++ .machine = &snd_soc_machine_omap3beagle,
++ .platform = &omap_soc_platform,
++ .codec_dev = &soc_codec_dev_twl4030,
++};
++
++static struct platform_device *omap3beagle_snd_device;
++
++static int __init omap3beagle_soc_init(void)
++{
++ int ret;
++
++ printk(KERN_INFO "OMAP3 Beagle SoC init\n");
++ if (!machine_is_omap3_beagle()) {
++ printk(KERN_INFO "Not OMAP3 Beagle!\n");
++ return -ENODEV;
++ }
++
++ omap3beagle_snd_device = platform_device_alloc("soc-audio", -1);
++ if (!omap3beagle_snd_device) {
++ printk(KERN_INFO "Platform device allocation failed\n");
++ return -ENOMEM;
++ }
++
++ platform_set_drvdata(omap3beagle_snd_device, &omap3beagle_snd_devdata);
++ omap3beagle_snd_devdata.dev = &omap3beagle_snd_device->dev;
++ *(unsigned int *)omap3beagle_dai.cpu_dai->private_data = 1; /* McBSP2 */
++
++ ret = platform_device_add(omap3beagle_snd_device);
++ if (ret)
++ goto err1;
++
++ return 0;
++
++err1:
++ printk(KERN_INFO "Unable to add platform device\n");
++ platform_device_put(omap3beagle_snd_device);
++
++ return ret;
++}
++
++static void __exit omap3beagle_soc_exit(void)
++{
++ printk(KERN_INFO "OMAP3 Beagle SoC exit\n");
++ platform_device_unregister(omap3beagle_snd_device);
++}
++
++module_init(omap3beagle_soc_init);
++module_exit(omap3beagle_soc_exit);
++
++MODULE_AUTHOR("Steve Sakoman <steve@sakoman.com>");
++MODULE_DESCRIPTION("ALSA SoC OMAP3 Beagle");
++MODULE_LICENSE("GPL");
+diff --git a/sound/soc/omap/omap3evm.c b/sound/soc/omap/omap3evm.c
+new file mode 100644
+index 0000000..a64c788
+--- /dev/null
++++ b/sound/soc/omap/omap3evm.c
+@@ -0,0 +1,142 @@
++/*
++ * omap3evm.c -- SoC audio for OMAP3 EVM
++ *
++ * Author: Steve Sakoman <steve@sakoman.com>
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * version 2 as published by the Free Software Foundation.
++ *
++ * 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., 51 Franklin St, Fifth Floor, Boston, MA
++ * 02110-1301 USA
++ *
++ */
++
++#include <linux/clk.h>
++#include <linux/platform_device.h>
++#include <sound/core.h>
++#include <sound/pcm.h>
++#include <sound/soc.h>
++#include <sound/soc-dapm.h>
++
++#include <asm/mach-types.h>
++#include <asm/arch/hardware.h>
++#include <asm/arch/gpio.h>
++#include <asm/arch/mcbsp.h>
++
++#include "omap-mcbsp.h"
++#include "omap-pcm.h"
++#include "../codecs/twl4030.h"
++
++static int omap3evm_hw_params(struct snd_pcm_substream *substream,
++ struct snd_pcm_hw_params *params)
++{
++ struct snd_soc_pcm_runtime *rtd = substream->private_data;
++ struct snd_soc_codec_dai *codec_dai = rtd->dai->codec_dai;
++ struct snd_soc_cpu_dai *cpu_dai = rtd->dai->cpu_dai;
++ int ret;
++
++ /* Set codec DAI configuration */
++ ret = codec_dai->dai_ops.set_fmt(codec_dai,
++ SND_SOC_DAIFMT_I2S |
++ SND_SOC_DAIFMT_NB_NF |
++ SND_SOC_DAIFMT_CBM_CFM);
++ if (ret < 0) {
++ printk(KERN_INFO "can't set codec DAI configuration\n");
++ return ret;
++ }
++
++ /* Set cpu DAI configuration */
++ ret = cpu_dai->dai_ops.set_fmt(cpu_dai,
++ SND_SOC_DAIFMT_I2S |
++ SND_SOC_DAIFMT_NB_NF |
++ SND_SOC_DAIFMT_CBM_CFM);
++ if (ret < 0) {
++ printk(KERN_INFO "can't set cpu DAI configuration\n");
++ return ret;
++ }
++
++ return 0;
++}
++
++static struct snd_soc_ops omap3evm_ops = {
++ .hw_params = omap3evm_hw_params,
++};
++
++/* Digital audio interface glue - connects codec <--> CPU */
++static struct snd_soc_dai_link omap3evm_dai = {
++ .name = "TWL4030",
++ .stream_name = "TWL4030",
++ .cpu_dai = &omap_mcbsp_dai[0],
++ .codec_dai = &twl4030_dai,
++ .ops = &omap3evm_ops,
++};
++
++/* Audio machine driver */
++static struct snd_soc_machine snd_soc_machine_omap3evm = {
++ .name = "omap3evm",
++ .dai_link = &omap3evm_dai,
++ .num_links = 1,
++};
++
++/* Audio subsystem */
++static struct snd_soc_device omap3evm_snd_devdata = {
++ .machine = &snd_soc_machine_omap3evm,
++ .platform = &omap_soc_platform,
++ .codec_dev = &soc_codec_dev_twl4030,
++};
++
++static struct platform_device *omap3evm_snd_device;
++
++static int __init omap3evm_soc_init(void)
++{
++ int ret;
++
++ printk(KERN_INFO "OMAP3 EVM SoC init\n");
++ if (!machine_is_omap3evm()) {
++ printk(KERN_INFO "Not OMAP3 EVM!\n");
++ return -ENODEV;
++ }
++
++ omap3evm_snd_device = platform_device_alloc("soc-audio", -1);
++ if (!omap3evm_snd_device) {
++ printk(KERN_INFO "Platform device allocation failed\n");
++ return -ENOMEM;
++ }
++
++ platform_set_drvdata(omap3evm_snd_device, &omap3evm_snd_devdata);
++ omap3evm_snd_devdata.dev = &omap3evm_snd_device->dev;
++ *(unsigned int *)omap3evm_dai.cpu_dai->private_data = 1; /* McBSP2 */
++
++ ret = platform_device_add(omap3evm_snd_device);
++ if (ret)
++ goto err1;
++
++ return 0;
++
++err1:
++ printk(KERN_INFO "Unable to add platform device\n");
++ platform_device_put(omap3evm_snd_device);
++
++ return ret;
++}
++
++static void __exit omap3evm_soc_exit(void)
++{
++ printk(KERN_INFO "OMAP3 EVM SoC exit\n");
++ platform_device_unregister(omap3evm_snd_device);
++}
++
++module_init(omap3evm_soc_init);
++module_exit(omap3evm_soc_exit);
++
++MODULE_AUTHOR("Steve Sakoman <steve@sakoman.com>");
++MODULE_DESCRIPTION("ALSA SoC OMAP3 EVM");
++MODULE_LICENSE("GPL");
diff --git a/packages/linux/linux-omap2-git/omap3evm/timer-suppression.patch b/packages/linux/linux-omap2-git/omap3evm/timer-suppression.patch
new file mode 100644
index 0000000000..04362c96e3
--- /dev/null
+++ b/packages/linux/linux-omap2-git/omap3evm/timer-suppression.patch
@@ -0,0 +1,43 @@
+diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
+index b854a89..26f5569 100644
+--- a/kernel/time/tick-sched.c
++++ b/kernel/time/tick-sched.c
+@@ -253,6 +253,16 @@ void tick_nohz_stop_sched_tick(void)
+
+ /* Schedule the tick, if we are at least one jiffie off */
+ if ((long)delta_jiffies >= 1) {
++ /*
++ * calculate the expiry time for the next timer wheel
++ * timer
++ */
++ expires = ktime_add_ns(last_update, tick_period.tv64 *
++ delta_jiffies);
++
++ /* Skip reprogram of event if its not changed */
++ if(ts->tick_stopped && ktime_equal(expires, dev->next_event))
++ goto out2;
+
+ if (delta_jiffies > 1)
+ cpu_set(cpu, nohz_cpu_mask);
+@@ -304,12 +314,7 @@ void tick_nohz_stop_sched_tick(void)
+ goto out;
+ }
+
+- /*
+- * calculate the expiry time for the next timer wheel
+- * timer
+- */
+- expires = ktime_add_ns(last_update, tick_period.tv64 *
+- delta_jiffies);
++ /* Mark expiries */
+ ts->idle_expires = expires;
+
+ if (ts->nohz_mode == NOHZ_MODE_HIGHRES) {
+@@ -328,6 +333,7 @@ void tick_nohz_stop_sched_tick(void)
+ tick_do_update_jiffies64(ktime_get());
+ cpu_clear(cpu, nohz_cpu_mask);
+ }
++out2:
+ raise_softirq_irqoff(TIMER_SOFTIRQ);
+ out:
+ ts->next_jiffies = next_jiffies;
diff --git a/packages/linux/linux-omap2-git/omap3evm/touchscreen.patch b/packages/linux/linux-omap2-git/omap3evm/touchscreen.patch
new file mode 100644
index 0000000000..2325c401e4
--- /dev/null
+++ b/packages/linux/linux-omap2-git/omap3evm/touchscreen.patch
@@ -0,0 +1,22 @@
+diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c
+index d8109ae..f8ce669 100644
+--- a/arch/arm/mach-omap2/board-omap3evm.c
++++ b/arch/arm/mach-omap2/board-omap3evm.c
+@@ -128,8 +128,16 @@ static int ads7846_get_pendown_state(void)
+ }
+
+ struct ads7846_platform_data ads7846_config = {
++ .x_max = 0x0fff,
++ .y_max = 0x0fff,
++ .x_plate_ohms = 180,
++ .pressure_max = 255,
++ .debounce_max = 10,
++ .debounce_tol = 3,
++ .debounce_rep = 1,
+ .get_pendown_state = ads7846_get_pendown_state,
+ .keep_vref_on = 1,
++ .settle_delay_usecs = 150,
+ };
+
+ static struct omap2_mcspi_device_config ads7846_mcspi_config = {
+