summaryrefslogtreecommitdiff
path: root/packages
diff options
context:
space:
mode:
authorKoen Kooi <koen@openembedded.org>2008-09-04 16:39:33 +0000
committerKoen Kooi <koen@openembedded.org>2008-09-04 16:39:33 +0000
commit7a66e7a528dd38a5ea363c30f7110967b6cdd03c (patch)
treeb1bfa7bb4555aec907eea4cd17377829d0894964 /packages
parent474a816e54c0c5e3135e05eb91022024e1e437b5 (diff)
linux-omap: a new recipe to build omap1, omap2 and omap3 kernels
Diffstat (limited to 'packages')
-rw-r--r--packages/linux/linux-omap/.mtn2git_empty0
-rw-r--r--packages/linux/linux-omap/000-mru-make-video-mode-selcatable.diff155
-rw-r--r--packages/linux/linux-omap/0001-ASoC-OMAP-Add-basic-support-for-OMAP34xx-in-McBSP.patch55
-rw-r--r--packages/linux/linux-omap/001-mru-enable-overlay.diff113
-rw-r--r--packages/linux/linux-omap/001-sakoman-twl4030-asoc.diff875
-rw-r--r--packages/linux/linux-omap/002-mru-set-default-800x600.diff61
-rw-r--r--packages/linux/linux-omap/003-mru-omapfb-more-video-modes.diff317
-rw-r--r--packages/linux/linux-omap/004-mru-export-omapfb-register-panel.diff25
-rw-r--r--packages/linux/linux-omap/005-mru-add-omapfb-unregister-panel.diff67
-rw-r--r--packages/linux/linux-omap/006-mru-lcd-as-modules.diff174
-rw-r--r--packages/linux/linux-omap/007-mru-omapfb-as-module.diff50
-rw-r--r--packages/linux/linux-omap/008-mru-lcd-omap3beagle-license.diff22
-rw-r--r--packages/linux/linux-omap/009-mru-unregister-beagle-lcd.diff24
-rw-r--r--packages/linux/linux-omap/01-fix-timing-print.diff23
-rw-r--r--packages/linux/linux-omap/010-mru-fix-video-mode-param.diff35
-rw-r--r--packages/linux/linux-omap/02-set-clkseld11.diff22
-rw-r--r--packages/linux/linux-omap/03-enable-overlay-opt.diff27
-rw-r--r--packages/linux/linux-omap/04-use-pcd.diff28
-rw-r--r--packages/linux/linux-omap/05-fix-display-panning.diff45
-rw-r--r--packages/linux/linux-omap/06-ensure-fclk.diff31
-rw-r--r--packages/linux/linux-omap/07-set-burst-size.diff21
-rw-r--r--packages/linux/linux-omap/16bpp.patch137
-rw-r--r--packages/linux/linux-omap/4bitmmc.diff38
-rw-r--r--packages/linux/linux-omap/beagleboard/.mtn2git_empty0
-rw-r--r--packages/linux/linux-omap/cache-display-fix.patch238
-rw-r--r--packages/linux/linux-omap/mru-clocks1.diff25
-rw-r--r--packages/linux/linux-omap/mru-clocks2.diff62
-rw-r--r--packages/linux/linux-omap/mru-clocks3.diff94
-rw-r--r--packages/linux/linux-omap/musb-dmafix.patch275
-rw-r--r--packages/linux/linux-omap/no-cortex-deadlock.patch75
-rw-r--r--packages/linux/linux-omap/no-empty-flash-warnings.patch15
-rw-r--r--packages/linux/linux-omap/no-harry-potter.diff11
-rw-r--r--packages/linux/linux-omap/omap-2430-lcd.patch11
-rw-r--r--packages/linux/linux-omap/omap1710h3/.mtn2git_empty0
-rw-r--r--packages/linux/linux-omap/omap2420h4/.mtn2git_empty0
-rw-r--r--packages/linux/linux-omap/omap2430sdp/.mtn2git_empty0
-rw-r--r--packages/linux/linux-omap/omap3evm/.mtn2git_empty0
-rw-r--r--packages/linux/linux-omap/omap5912osk/.mtn2git_empty0
-rw-r--r--packages/linux/linux-omap/oprofile-0.9.3.armv7.diff612
-rw-r--r--packages/linux/linux-omap/read_die_ids.patch23
-rw-r--r--packages/linux/linux-omap/soc.patch1154
-rw-r--r--packages/linux/linux-omap/timer-suppression.patch43
-rw-r--r--packages/linux/linux-omap/touchscreen.patch22
-rw-r--r--packages/linux/linux-omap_git.bb63
44 files changed, 5068 insertions, 0 deletions
diff --git a/packages/linux/linux-omap/.mtn2git_empty b/packages/linux/linux-omap/.mtn2git_empty
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/packages/linux/linux-omap/.mtn2git_empty
diff --git a/packages/linux/linux-omap/000-mru-make-video-mode-selcatable.diff b/packages/linux/linux-omap/000-mru-make-video-mode-selcatable.diff
new file mode 100644
index 0000000000..e36aeb5cff
--- /dev/null
+++ b/packages/linux/linux-omap/000-mru-make-video-mode-selcatable.diff
@@ -0,0 +1,155 @@
+From: Mans Rullgard <mans@mansr.com>
+Date: Mon, 18 Aug 2008 22:55:09 +0000 (+0100)
+Subject: OMAP: Make video mode commandline-selectable from pre-defined list
+X-Git-Tag: beagle-9
+X-Git-Url: http://git.mansr.com/?p=linux-omap;a=commitdiff_plain;h=c76a61167997a1dc680c421b1cdb753dfd492b0a
+
+OMAP: Make video mode commandline-selectable from pre-defined list
+
+This adds a (small) list of video modes and allows one to be
+selected with video=omapfb:mode:name on the command line,
+overriding the defaults from lcd_*.c.
+
+Signed-off-by: Mans Rullgard <mans@mansr.com>
+---
+
+diff --git a/arch/arm/plat-omap/include/mach/omapfb.h b/arch/arm/plat-omap/include/mach/omapfb.h
+index a4a84f3..92e9ffd 100644
+--- a/arch/arm/plat-omap/include/mach/omapfb.h
++++ b/arch/arm/plat-omap/include/mach/omapfb.h
+@@ -192,6 +192,20 @@ enum omapfb_update_mode {
+
+ struct omapfb_device;
+
++struct video_mode {
++ const char *name;
++ int x_res, y_res;
++ int pixel_clock; /* In kHz */
++ int hsw; /* Horizontal synchronization
++ pulse width */
++ int hfp; /* Horizontal front porch */
++ int hbp; /* Horizontal back porch */
++ int vsw; /* Vertical synchronization
++ pulse width */
++ int vfp; /* Vertical front porch */
++ int vbp; /* Vertical back porch */
++};
++
+ struct lcd_panel {
+ const char *name;
+ int config; /* TFT/STN, signal inversion */
+diff --git a/drivers/video/omap/omapfb_main.c b/drivers/video/omap/omapfb_main.c
+index 24242b9..f2229b1 100644
+--- a/drivers/video/omap/omapfb_main.c
++++ b/drivers/video/omap/omapfb_main.c
+@@ -40,6 +40,7 @@ static unsigned long def_vxres;
+ static unsigned long def_vyres;
+ static unsigned int def_rotate;
+ static unsigned int def_mirror;
++static int def_mode = -1;
+
+ #ifdef CONFIG_FB_OMAP_MANUAL_UPDATE
+ static int manual_update = 1;
+@@ -80,6 +81,57 @@ static struct caps_table_struct color_caps[] = {
+ { 1 << OMAPFB_COLOR_YUY422, "YUY422", },
+ };
+
++static const struct video_mode video_modes[] = {
++ {
++ .name = "1280x720@50",
++ .x_res = 1280,
++ .y_res = 720,
++ .hfp = 440,
++ .hsw = 40,
++ .hbp = 220,
++ .vfp = 20,
++ .vsw = 5,
++ .vbp = 5,
++ .pixel_clock = 74250,
++ },
++ {
++ .name = "1280x720@60",
++ .x_res = 1280,
++ .y_res = 720,
++ .hfp = 110,
++ .hsw = 40,
++ .hbp = 220,
++ .vfp = 20,
++ .vsw = 5,
++ .vbp = 5,
++ .pixel_clock = 74250,
++ },
++ {
++ .name = "1920x1080@24",
++ .x_res = 1920,
++ .y_res = 1080,
++ .hfp = 148,
++ .hsw = 44,
++ .hbp = 638,
++ .vfp = 36,
++ .vsw = 5,
++ .vbp = 4,
++ .pixel_clock = 74160,
++ },
++ {
++ .name = "1920x1080@25",
++ .x_res = 1920,
++ .y_res = 1080,
++ .hfp = 148,
++ .hsw = 44,
++ .hbp = 528,
++ .vfp = 36,
++ .vsw = 5,
++ .vbp = 4,
++ .pixel_clock = 74250,
++ }
++};
++
+ /*
+ * ---------------------------------------------------------------------------
+ * LCD panel
+@@ -1711,6 +1763,18 @@ static int omapfb_do_probe(struct platform_device *pdev,
+ goto cleanup;
+ }
+
++ if (def_mode != -1) {
++ fbdev->panel->x_res = video_modes[def_mode].x_res;
++ fbdev->panel->y_res = video_modes[def_mode].y_res;
++ fbdev->panel->pixel_clock = video_modes[def_mode].pixel_clock;
++ fbdev->panel->hsw = video_modes[def_mode].hsw;
++ fbdev->panel->hfp = video_modes[def_mode].hfp;
++ fbdev->panel->hbp = video_modes[def_mode].hbp;
++ fbdev->panel->vsw = video_modes[def_mode].vsw;
++ fbdev->panel->vfp = video_modes[def_mode].vfp;
++ fbdev->panel->vbp = video_modes[def_mode].vbp;
++ }
++
+ r = fbdev->panel->init(fbdev->panel, fbdev);
+ if (r)
+ goto cleanup;
+@@ -1867,6 +1931,16 @@ static struct platform_driver omapfb_driver = {
+ },
+ };
+
++static int __init omapfb_find_mode(char *mode)
++{
++ int i;
++
++ for (i = 0; i < sizeof(video_modes)/sizeof(video_modes[0]); i++)
++ if (!strcmp(mode, video_modes[i].name))
++ return i;
++ return -1;
++}
++
+ #ifndef MODULE
+
+ /* Process kernel command line parameters */
+@@ -1915,6 +1989,8 @@ static int __init omapfb_setup(char *options)
+ def_mirror = (simple_strtoul(this_opt + 7, NULL, 0));
+ else if (!strncmp(this_opt, "manual_update", 13))
+ manual_update = 1;
++ else if (!strncmp(this_opt, "mode:", 5))
++ def_mode = omapfb_find_mode(this_opt + 5);
+ else {
+ pr_debug("omapfb: invalid option\n");
+ r = -1;
diff --git a/packages/linux/linux-omap/0001-ASoC-OMAP-Add-basic-support-for-OMAP34xx-in-McBSP.patch b/packages/linux/linux-omap/0001-ASoC-OMAP-Add-basic-support-for-OMAP34xx-in-McBSP.patch
new file mode 100644
index 0000000000..6e31ead2bd
--- /dev/null
+++ b/packages/linux/linux-omap/0001-ASoC-OMAP-Add-basic-support-for-OMAP34xx-in-McBSP.patch
@@ -0,0 +1,55 @@
+From a1dbb6dd28e9815a307b87b8d96dcf371d6cfd58 Mon Sep 17 00:00:00 2001
+From: Jarkko Nikula <jarkko.nikula@nokia.com>
+Date: Mon, 19 May 2008 13:24:41 +0300
+Subject: [PATCH] ASoC: OMAP: Add basic support for OMAP34xx in McBSP DAI driver
+
+This adds support for OMAP34xx McBSP port 1 and 2.
+
+Signed-off-by: Jarkko Nikula <jarkko.nikula@nokia.com>
+---
+ sound/soc/omap/omap-mcbsp.c | 20 +++++++++++++++++++-
+ 1 files changed, 19 insertions(+), 1 deletions(-)
+
+diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c
+index 40d87e6..8e6ec9d 100644
+--- a/sound/soc/omap/omap-mcbsp.c
++++ b/sound/soc/omap/omap-mcbsp.c
+@@ -99,6 +99,21 @@ static const unsigned long omap2420_mcbsp_port[][2] = {
+ static const int omap2420_dma_reqs[][2] = {};
+ static const unsigned long omap2420_mcbsp_port[][2] = {};
+ #endif
++#if defined(CONFIG_ARCH_OMAP34XX)
++static const int omap34xx_dma_reqs[][2] = {
++ { OMAP24XX_DMA_MCBSP1_TX, OMAP24XX_DMA_MCBSP1_RX },
++ { OMAP24XX_DMA_MCBSP2_TX, OMAP24XX_DMA_MCBSP2_RX },
++};
++static const unsigned long omap34xx_mcbsp_port[][2] = {
++ { OMAP34XX_MCBSP1_BASE + OMAP_MCBSP_REG_DXR2,
++ OMAP34XX_MCBSP1_BASE + OMAP_MCBSP_REG_DRR2 },
++ { OMAP34XX_MCBSP2_BASE + OMAP_MCBSP_REG_DXR2,
++ OMAP34XX_MCBSP2_BASE + OMAP_MCBSP_REG_DRR2 },
++};
++#else
++static const int omap34xx_dma_reqs[][2] = {};
++static const unsigned long omap34xx_mcbsp_port[][2] = {};
++#endif
+
+ static int omap_mcbsp_dai_startup(struct snd_pcm_substream *substream)
+ {
+@@ -169,9 +184,12 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
+ } else if (cpu_is_omap2420()) {
+ dma = omap2420_dma_reqs[bus_id][substream->stream];
+ port = omap2420_mcbsp_port[bus_id][substream->stream];
++ } else if (cpu_is_omap343x()) {
++ dma = omap34xx_dma_reqs[bus_id][substream->stream];
++ port = omap34xx_mcbsp_port[bus_id][substream->stream];
+ } else {
+ /*
+- * TODO: Add support for 2430 and 3430
++ * TODO: Add support for 2430
+ */
+ return -ENODEV;
+ }
+--
+1.5.5.1
+
diff --git a/packages/linux/linux-omap/001-mru-enable-overlay.diff b/packages/linux/linux-omap/001-mru-enable-overlay.diff
new file mode 100644
index 0000000000..8666c4ac9a
--- /dev/null
+++ b/packages/linux/linux-omap/001-mru-enable-overlay.diff
@@ -0,0 +1,113 @@
+From: Mans Rullgard <mans@mansr.com>
+Date: Thu, 28 Aug 2008 21:20:39 +0000 (+0100)
+Subject: OMAP: Enable overlay optimisation when possible
+X-Git-Url: http://git.mansr.com/?p=linux-omap;a=commitdiff_plain;h=5a7378bb691e76ce247f39f79e1a928166f1aed9
+
+OMAP: Enable overlay optimisation when possible
+---
+
+diff --git a/drivers/video/omap/dispc.c b/drivers/video/omap/dispc.c
+index 7c525f5..1d56ee0 100644
+--- a/drivers/video/omap/dispc.c
++++ b/drivers/video/omap/dispc.c
+@@ -315,6 +315,60 @@ void omap_dispc_enable_digit_out(int enable)
+ }
+ EXPORT_SYMBOL(omap_dispc_enable_digit_out);
+
++#define MIN(a, b) ((a)<(b)?(a):(b))
++#define MAX(a, b) ((a)>(b)?(a):(b))
++
++static void setup_overlay_opt(void)
++{
++ struct fb_info **fbi = dispc.fbdev->fb_info;
++ struct omapfb_plane_struct *gfx, *vid;
++ struct fb_var_screeninfo *gvar;
++ unsigned gx, gx2, gy, gy2, gw, gh;
++ unsigned vx, vx2, vy, vy2, vw, vh;
++ unsigned bpp, skip;
++ static unsigned last_skip;
++
++ if (!fbi[0] || !fbi[1])
++ return;
++
++ gfx = fbi[0]->par;
++ vid = fbi[1]->par;
++ gvar = &fbi[0]->var;
++
++ gx = gfx->info.pos_x;
++ gy = gfx->info.pos_y;
++ gw = gfx->info.out_width;
++ gh = gfx->info.out_height;
++ vx = vid->info.pos_x;
++ vy = vid->info.pos_y;
++ vw = vid->info.out_width;
++ vh = vid->info.out_height;
++ gx2 = gx + gw;
++ gy2 = gy + gh;
++ vx2 = vx + vw;
++ vy2 = vy + vh;
++ bpp = gvar->bits_per_pixel / 8;
++
++ if (!gfx->info.enabled || !vid->info.enabled ||
++ dispc.color_key.key_type != OMAPFB_COLOR_KEY_DISABLED) {
++ skip = 0;
++ } else if (vx <= gx && vx2 >= gx2) {
++ unsigned y = MIN(gy2, vy2) - MAX(gy, vy);
++ skip = y * gvar->xres_virtual * bpp;
++ } else if (vx <= gx || vx2 >= gx2) {
++ unsigned x = MIN(gx2, vx2) - MAX(gx, vx);
++ skip = x * bpp;
++ } else {
++ skip = vw * bpp + 1;
++ }
++
++ if (skip != last_skip) {
++ last_skip = skip;
++ dispc_write_reg(DISPC_GFX_WINDOW_SKIP, skip);
++ MOD_REG_FLD(DISPC_CONTROL, 1<<12, !!skip<<12);
++ }
++}
++
+ static inline int _setup_plane(int plane, int channel_out,
+ u32 paddr, int screen_width,
+ int pos_x, int pos_y, int width, int height,
+@@ -437,6 +491,9 @@ static inline int _setup_plane(int plane, int channel_out,
+
+ dispc_write_reg(ri_reg[plane], (screen_width - width) * bpp / 8 + 1);
+
++ if (plane < 2)
++ setup_overlay_opt();
++
+ MOD_REG_FLD(DISPC_CONTROL, 1<<5, 1<<5);
+
+ return height * screen_width * bpp / 8;
+@@ -586,13 +643,19 @@ static int omap_dispc_enable_plane(int plane, int enable)
+ const u32 at_reg[] = { DISPC_GFX_ATTRIBUTES,
+ DISPC_VID1_BASE + DISPC_VID_ATTRIBUTES,
+ DISPC_VID2_BASE + DISPC_VID_ATTRIBUTES };
+- unsigned overlay_opt = plane & !!enable & !dispc.color_key.key_type;
++ struct omapfb_plane_struct *pi;
++
+ if ((unsigned int)plane > dispc.mem_desc.region_cnt)
+ return -EINVAL;
+
++ pi = dispc.fbdev->fb_info[plane]->par;
++ pi->info.enabled = enable;
++
+ enable_lcd_clocks(1);
+ MOD_REG_FLD(at_reg[plane], 1, enable ? 1 : 0);
+- MOD_REG_FLD(DISPC_CONTROL, 1<<12 | 1<<5, overlay_opt<<12 | 1<<5);
++ if (plane < 2)
++ setup_overlay_opt();
++ MOD_REG_FLD(DISPC_CONTROL, 1<<5, 1<<5);
+ enable_lcd_clocks(0);
+
+ return 0;
+@@ -636,6 +699,7 @@ static int omap_dispc_set_color_key(struct omapfb_color_key *ck)
+ if (val != 0)
+ dispc_write_reg(tr_reg, ck->trans_key);
+ dispc_write_reg(df_reg, ck->background);
++ setup_overlay_opt();
+ enable_lcd_clocks(0);
+
+ dispc.color_key = *ck;
diff --git a/packages/linux/linux-omap/001-sakoman-twl4030-asoc.diff b/packages/linux/linux-omap/001-sakoman-twl4030-asoc.diff
new file mode 100644
index 0000000000..d9f028a90c
--- /dev/null
+++ b/packages/linux/linux-omap/001-sakoman-twl4030-asoc.diff
@@ -0,0 +1,875 @@
+From: Steve Sakoman <steve@sakoman.com>
+Date: Thu, 4 Sep 2008 04:32:11 +0000 (-0700)
+Subject: SOUND: SOC: CODECS: Add support for the TWL4030 audio codec
+X-Git-Url: http://www.sakoman.net/cgi-bin/gitweb.cgi?p=linux-omap-2.6.git;a=commitdiff_plain;h=16fc70d77268043edb76946e86a3d776bad26a45
+
+SOUND: SOC: CODECS: Add support for the TWL4030 audio codec
+---
+
+diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
+index 1db04a2..2f00e1e 100644
+--- a/sound/soc/codecs/Kconfig
++++ b/sound/soc/codecs/Kconfig
+@@ -50,3 +50,8 @@ config SND_SOC_CS4270_VD33_ERRATA
+ config SND_SOC_TLV320AIC3X
+ tristate
+ depends on I2C
++
++config SND_SOC_TWL4030
++ tristate
++ depends on SND_SOC && I2C
++
+diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
+index d7b97ab..a519ced 100644
+--- a/sound/soc/codecs/Makefile
++++ b/sound/soc/codecs/Makefile
+@@ -10,6 +10,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_AK4535) += snd-soc-ak4535.o
+@@ -23,3 +24,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..683b8a1
+--- /dev/null
++++ b/sound/soc/codecs/twl4030.c
+@@ -0,0 +1,628 @@
++/*
++ * 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.
++ *
++ * 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/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) */
++ 0x24, /* REG_ANAMICL (0x5) */
++ 0x04, /* 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, /* not used (0x40) */
++ 0x00, /* not used (0x41) */
++ 0x00, /* not used (0x42) */
++ 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);
++ }
++}
++
++/*
++ * 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(struct snd_soc_codec *codec)
++{
++ int i;
++ u8 byte;
++
++ /* clear CODECPDZ prior to setting register defaults */
++ twl4030_write(codec, REG_CODEC_MODE,
++ twl4030_reg[REG_CODEC_MODE] & ~CODECPDZ);
++
++ udelay(10);
++
++ /* set all audio section registers to reasonable defaults */
++ for (i = REG_OPTION; i <= REG_MISC_SET_2; i++)
++ twl4030_write(codec, i, twl4030_reg[i]);
++
++}
++
++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 struct snd_soc_dapm_route intercon[] = {
++ /* outputs */
++ {"OUTL", NULL, "DACL"},
++ {"OUTR", NULL, "DACR"},
++
++ /* inputs */
++ {"ADCL", NULL, "INL"},
++ {"ADCR", NULL, "INR"},
++};
++
++static int twl4030_add_widgets(struct snd_soc_codec *codec)
++{
++ snd_soc_dapm_new_controls(codec, twl4030_dapm_widgets,
++ ARRAY_SIZE(twl4030_dapm_widgets));
++
++ snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
++
++ snd_soc_dapm_new_widgets(codec);
++ return 0;
++}
++
++static void twl4030_power_up(struct snd_soc_codec *codec)
++{
++ u8 mode, byte, popn, hsgain;
++
++ /* set CODECPDZ to turn on codec */
++ mode = twl4030_read_reg_cache(codec, REG_CODEC_MODE);
++ twl4030_write(codec, REG_CODEC_MODE, mode | CODECPDZ);
++ udelay(10);
++
++ /* initiate offset cancellation */
++ twl4030_write(codec, REG_ANAMICL,
++ twl4030_reg[REG_ANAMICL] | CNCL_OFFSET_START);
++
++ /* wait for offset cancellation to complete */
++ twl4030_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &byte, REG_ANAMICL);
++ while ((byte & CNCL_OFFSET_START) == CNCL_OFFSET_START)
++ twl4030_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE,
++ &byte, REG_ANAMICL);
++
++ /* anti-pop when changing analog gain */
++ twl4030_write(codec, REG_MISC_SET_1,
++ twl4030_reg[REG_MISC_SET_1] | SMOOTH_ANAVOL_EN);
++
++ /* toggle CODECPDZ as per TRM */
++ twl4030_write(codec, REG_CODEC_MODE, mode & ~CODECPDZ);
++ udelay(10);
++
++ twl4030_write(codec, REG_CODEC_MODE, mode | CODECPDZ);
++ udelay(10);
++
++ /* program anti-pop with bias ramp delay */
++ popn = twl4030_read_reg_cache(codec, REG_HS_POPN_SET);
++ popn &= RAMP_DELAY;
++ popn |= RAMP_DELAY_645MS;
++ twl4030_write(codec, REG_HS_POPN_SET, popn);
++ popn |= VMID_EN;
++ twl4030_write(codec, REG_HS_POPN_SET, popn);
++
++ /* enable output stage and gain setting */
++ hsgain = HSR_GAIN_0DB | HSL_GAIN_0DB;
++ twl4030_write(codec, REG_HS_GAIN_SET, hsgain);
++
++ /* enable anti-pop ramp */
++ 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;
++
++ /* disable anti-pop ramp */
++ popn = twl4030_read_reg_cache(codec, REG_HS_POPN_SET);
++ popn &= ~RAMP_EN;
++ twl4030_write(codec, REG_HS_POPN_SET, popn);
++
++ /* disable output stage and gain setting */
++ hsgain = HSR_GAIN_PWR_DOWN | HSL_GAIN_PWR_DOWN;
++ twl4030_write(codec, REG_HS_GAIN_SET, hsgain);
++
++ /* disable bias out */
++ popn &= ~VMID_EN;
++ twl4030_write(codec, REG_HS_POPN_SET, popn);
++
++ /* power down */
++ mode = twl4030_read_reg_cache(codec, REG_CODEC_MODE);
++ twl4030_write(codec, REG_CODEC_MODE, mode & ~CODECPDZ);
++
++ udelay(10);
++}
++
++static int twl4030_set_bias_level(struct snd_soc_codec *codec,
++ enum snd_soc_bias_level level)
++{
++ switch (level) {
++ case SND_SOC_BIAS_ON:
++ twl4030_power_up(codec);
++ break;
++ case SND_SOC_BIAS_PREPARE:
++ break;
++ case SND_SOC_BIAS_STANDBY:
++ twl4030_power_down(codec);
++ break;
++ case SND_SOC_BIAS_OFF:
++ twl4030_power_down(codec);
++ break;
++ }
++ codec->bias_level = level;
++
++ return 0;
++}
++
++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;
++ 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_ERR "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_ERR "TWL4030 hw params: unknown format %d\n",
++ params_format(params));
++ return -EINVAL;
++ }
++
++ if (format != old_format) {
++
++ /* clear CODECPDZ before changing format (codec requirement) */
++ 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);
++
++ /* set CODECPDZ afterwards */
++ mode |= CODECPDZ;
++ twl4030_write(codec, REG_CODEC_MODE, mode);
++ }
++ return 0;
++}
++
++static int twl4030_set_dai_sysclk(struct snd_soc_dai *codec_dai,
++ int clk_id, unsigned int freq, int dir)
++{
++ struct snd_soc_codec *codec = codec_dai->codec;
++ u8 infreq;
++
++ switch (freq) {
++ case 19200000:
++ infreq = APLL_INFREQ_19200KHZ;
++ break;
++ case 26000000:
++ infreq = APLL_INFREQ_26000KHZ;
++ break;
++ case 38400000:
++ infreq = APLL_INFREQ_38400KHZ;
++ break;
++ default:
++ printk(KERN_ERR "TWL4030 set sysclk: unknown rate %d\n",
++ freq);
++ return -EINVAL;
++ }
++
++ infreq |= APLL_EN;
++ twl4030_write(codec, REG_APLL_CTL, infreq);
++
++ return 0;
++}
++
++static int twl4030_set_dai_fmt(struct snd_soc_dai *codec_dai,
++ unsigned int fmt)
++{
++ struct snd_soc_codec *codec = codec_dai->codec;
++ 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:
++ format &= ~(AIF_SLAVE_EN);
++ format |= CLK256FS_EN;
++ break;
++ case SND_SOC_DAIFMT_CBS_CFS:
++ 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:
++ format |= AIF_FORMAT_CODEC;
++ break;
++ default:
++ return -EINVAL;
++ }
++
++ if (format != old_format) {
++
++ /* clear CODECPDZ before changing format (codec requirement) */
++ 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);
++
++ /* set CODECPDZ afterwards */
++ 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_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 = {
++ .set_sysclk = twl4030_set_dai_sysclk,
++ .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;
++
++ twl4030_set_bias_level(codec, SND_SOC_BIAS_OFF);
++
++ 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;
++
++ twl4030_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
++ twl4030_set_bias_level(codec, codec->suspend_bias_level);
++ 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->set_bias_level = twl4030_set_bias_level;
++ 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_init_chip(codec);
++
++ /* power on device */
++ twl4030_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
++
++ 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;
++ }
++
++ return ret;
++
++card_err:
++ snd_soc_free_pcms(socdev);
++ snd_soc_dapm_free(socdev);
++pcm_err:
++ 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;
++
++ codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
++ if (codec == NULL)
++ return -ENOMEM;
++
++ 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);
++
++ 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..013dabc
+--- /dev/null
++++ b/sound/soc/codecs/twl4030.h
+@@ -0,0 +1,197 @@
++/*
++ * 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.
++ *
++ * 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
++ *
++ */
++
++#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
++
++/* ANAMICL (0x05) Fields */
++#define CNCL_OFFSET_START 0x80
++#define OFFSET_CNCL_SEL 0x60
++#define OFFSET_CNCL_SEL_ARX1 0x00
++#define OFFSET_CNCL_SEL_ARX2 0x20
++#define OFFSET_CNCL_SEL_VRX 0x40
++#define OFFSET_CNCL_SEL_ALL 0x60
++#define MICAMPL_EN 0x10
++#define CKMIC_EN 0x08
++#define AUXL_EN 0x04
++#define HSMIC_EN 0x02
++#define MAINMIC_EN 0x01
++
++/* ANAMICR (0x06) Fields */
++#define MICAMPR_EN 0x10
++#define AUXR_EN 0x04
++#define SUBMIC_EN 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 0x03
++#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
++
++/* APLL_CTL (0x3A) Fields */
++
++#define APLL_EN 0x10
++#define APLL_INFREQ 0x0F
++#define APLL_INFREQ_19200KHZ 0x05
++#define APLL_INFREQ_26000KHZ 0x06
++#define APLL_INFREQ_38400KHZ 0x0F
++
++/* REG_MISC_SET_1 (0x3E) Fields */
++
++#define CLK64_EN 0x80
++#define SCRAMBLE_EN 0x40
++#define FMLOOP_EN 0x20
++#define SMOOTH_ANAVOL_EN 0x02
++#define DIGMIC_LR_SWAP_EN 0x01
++
++extern struct snd_soc_dai twl4030_dai;
++extern struct snd_soc_codec_device soc_codec_dev_twl4030;
++
++#endif /* End of __TWL4030_AUDIO_H__ */
diff --git a/packages/linux/linux-omap/002-mru-set-default-800x600.diff b/packages/linux/linux-omap/002-mru-set-default-800x600.diff
new file mode 100644
index 0000000000..b45f849ba4
--- /dev/null
+++ b/packages/linux/linux-omap/002-mru-set-default-800x600.diff
@@ -0,0 +1,61 @@
+From: Mans Rullgard <mans@mansr.com>
+Date: Fri, 29 Aug 2008 00:42:02 +0000 (+0100)
+Subject: OMAP: Set Beagleboard default video mode to 800x600 60Hz
+X-Git-Url: http://git.mansr.com/?p=linux-omap;a=commitdiff_plain;h=17b546e6d65aee124a2b691727cdb2c1dcadaec5
+
+OMAP: Set Beagleboard default video mode to 800x600 60Hz
+
+This sets the default video mode on the Beagleboard to
+800x600 60Hz VESA CVT 0.48M3-R, 16bpp. This is compatible
+with a wider range of monitors than the old default values.
+
+Signed-off-by: Mans Rullgard <mans@mansr.com>
+---
+
+diff --git a/drivers/video/omap/lcd_omap3beagle.c b/drivers/video/omap/lcd_omap3beagle.c
+index 9637735..f2861ec 100644
+--- a/drivers/video/omap/lcd_omap3beagle.c
++++ b/drivers/video/omap/lcd_omap3beagle.c
+@@ -31,10 +31,6 @@
+
+ #define LCD_PANEL_ENABLE_GPIO 170
+
+-#define LCD_XRES 1024
+-#define LCD_YRES 768
+-#define LCD_PIXCLOCK 64000 /* in kHz */
+-
+ static int omap3beagle_panel_init(struct lcd_panel *panel,
+ struct omapfb_device *fbdev)
+ {
+@@ -65,19 +61,19 @@ static unsigned long omap3beagle_panel_get_caps(struct lcd_panel *panel)
+ struct lcd_panel omap3beagle_panel = {
+ .name = "omap3beagle",
+ .config = OMAP_LCDC_PANEL_TFT,
+-
+- .bpp = 24,
++ .bpp = 16,
+ .data_lines = 24,
+- .x_res = LCD_XRES,
+- .y_res = LCD_YRES,
+- .hsw = 3, /* hsync_len (4) - 1 */
+- .hfp = 3, /* right_margin (4) - 1 */
+- .hbp = 39, /* left_margin (40) - 1 */
+- .vsw = 1, /* vsync_len (2) - 1 */
+- .vfp = 2, /* lower_margin */
+- .vbp = 7, /* upper_margin (8) - 1 */
+-
+- .pixel_clock = LCD_PIXCLOCK,
++
++ /* 800 x 600 @ 60 Hz Reduced blanking VESA CVT 0.48M3-R */
++ .x_res = 800,
++ .y_res = 600,
++ .hfp = 48,
++ .hsw = 32,
++ .hbp = 80,
++ .vfp = 3,
++ .vsw = 4,
++ .vbp = 11,
++ .pixel_clock = 35500,
+
+ .init = omap3beagle_panel_init,
+ .cleanup = omap3beagle_panel_cleanup,
diff --git a/packages/linux/linux-omap/003-mru-omapfb-more-video-modes.diff b/packages/linux/linux-omap/003-mru-omapfb-more-video-modes.diff
new file mode 100644
index 0000000000..34241640eb
--- /dev/null
+++ b/packages/linux/linux-omap/003-mru-omapfb-more-video-modes.diff
@@ -0,0 +1,317 @@
+From: Mans Rullgard <mans@mansr.com>
+Date: Fri, 29 Aug 2008 08:28:31 +0000 (+0100)
+Subject: OMAP: Add more video modes, and make the default configurable
+X-Git-Url: http://git.mansr.com/?p=linux-omap;a=commitdiff_plain;h=ef272670f19fac8fb0ceb82933927dab1fb496b7
+
+OMAP: Add more video modes, and make the default configurable
+---
+
+diff --git a/arch/arm/plat-omap/include/mach/omapfb.h b/arch/arm/plat-omap/include/mach/omapfb.h
+index 92e9ffd..a4a84f3 100644
+--- a/arch/arm/plat-omap/include/mach/omapfb.h
++++ b/arch/arm/plat-omap/include/mach/omapfb.h
+@@ -192,20 +192,6 @@ enum omapfb_update_mode {
+
+ struct omapfb_device;
+
+-struct video_mode {
+- const char *name;
+- int x_res, y_res;
+- int pixel_clock; /* In kHz */
+- int hsw; /* Horizontal synchronization
+- pulse width */
+- int hfp; /* Horizontal front porch */
+- int hbp; /* Horizontal back porch */
+- int vsw; /* Vertical synchronization
+- pulse width */
+- int vfp; /* Vertical front porch */
+- int vbp; /* Vertical back porch */
+-};
+-
+ struct lcd_panel {
+ const char *name;
+ int config; /* TFT/STN, signal inversion */
+diff --git a/drivers/video/omap/Kconfig b/drivers/video/omap/Kconfig
+index bdeb8fb..9977e80 100644
+--- a/drivers/video/omap/Kconfig
++++ b/drivers/video/omap/Kconfig
+@@ -7,6 +7,14 @@ config FB_OMAP
+ help
+ Frame buffer driver for OMAP based boards.
+
++config FB_OMAP_VIDEO_MODE
++ string "Default video mode"
++ depends on FB_OMAP
++ help
++ Enter video mode name to use if none is specified on the kernel
++ command line. If left blank, board-specific default timings
++ will be used. See omapfb_main.c for a list of valid mode names.
++
+ config FB_OMAP_LCDC_EXTERNAL
+ bool "External LCD controller support"
+ depends on FB_OMAP
+diff --git a/drivers/video/omap/omapfb_main.c b/drivers/video/omap/omapfb_main.c
+index f2229b1..2e53d8f 100644
+--- a/drivers/video/omap/omapfb_main.c
++++ b/drivers/video/omap/omapfb_main.c
+@@ -33,6 +33,20 @@
+
+ #define MODULE_NAME "omapfb"
+
++struct video_mode {
++ const char *name;
++ int x_res, y_res;
++ int pixel_clock; /* In kHz */
++ int hsw; /* Horizontal synchronization
++ pulse width */
++ int hfp; /* Horizontal front porch */
++ int hbp; /* Horizontal back porch */
++ int vsw; /* Vertical synchronization
++ pulse width */
++ int vfp; /* Vertical front porch */
++ int vbp; /* Vertical back porch */
++};
++
+ static unsigned int def_accel;
+ static unsigned long def_vram[OMAPFB_PLANE_NUM];
+ static int def_vram_cnt;
+@@ -40,7 +54,7 @@ static unsigned long def_vxres;
+ static unsigned long def_vyres;
+ static unsigned int def_rotate;
+ static unsigned int def_mirror;
+-static int def_mode = -1;
++static char def_mode[16] = CONFIG_FB_OMAP_VIDEO_MODE;
+
+ #ifdef CONFIG_FB_OMAP_MANUAL_UPDATE
+ static int manual_update = 1;
+@@ -51,6 +65,7 @@ static int manual_update;
+ static struct platform_device *fbdev_pdev;
+ static struct lcd_panel *fbdev_panel;
+ static struct omapfb_device *omapfb_dev;
++static struct video_mode video_mode;
+
+ struct caps_table_struct {
+ unsigned long flag;
+@@ -81,9 +96,88 @@ static struct caps_table_struct color_caps[] = {
+ { 1 << OMAPFB_COLOR_YUY422, "YUY422", },
+ };
+
+-static const struct video_mode video_modes[] = {
++static struct video_mode video_modes[] __initdata = {
++ {
++ /* 640 x 480 @ 60 Hz Reduced blanking VESA CVT 0.31M3-R */
++ .name = "640x480@60",
++ .x_res = 640,
++ .y_res = 480,
++ .hfp = 48,
++ .hsw = 32,
++ .hbp = 80,
++ .vfp = 3,
++ .vsw = 4,
++ .vbp = 7,
++ .pixel_clock = 23500,
++ },
++ {
++ /* 800 x 600 @ 60 Hz Reduced blanking VESA CVT 0.48M3-R */
++ .name = "800x600@60",
++ .x_res = 800,
++ .y_res = 600,
++ .hfp = 48,
++ .hsw = 32,
++ .hbp = 80,
++ .vfp = 3,
++ .vsw = 4,
++ .vbp = 11,
++ .pixel_clock = 35500,
++ },
++ {
++ /* 1024 x 768 @ 60 Hz Reduced blanking VESA CVT 0.79M3-R */
++ .name = "1024x768@60",
++ .x_res = 1024,
++ .y_res = 768,
++ .hfp = 48,
++ .hsw = 32,
++ .hbp = 80,
++ .vfp = 3,
++ .vsw = 4,
++ .vbp = 15,
++ .pixel_clock = 56000,
++ },
++ {
++ /* 1280 x 720 @ 60 Hz Reduced blanking VESA CVT 0.92M9-R */
++ .name = "1280x720@60",
++ .x_res = 1280,
++ .y_res = 720,
++ .hfp = 48,
++ .hsw = 32,
++ .hbp = 80,
++ .vfp = 3,
++ .vsw = 5,
++ .vbp = 13,
++ .pixel_clock = 64000,
++ },
++ {
++ /* 720 x 480 @ 60 Hz CEA-861 Format 3 */
++ .name = "480p60",
++ .x_res = 720,
++ .y_res = 480,
++ .hfp = 16,
++ .hsw = 62,
++ .hbp = 60,
++ .vfp = 9,
++ .vsw = 6,
++ .vbp = 30,
++ .pixel_clock = 27027,
++ },
++ {
++ /* 720 x 576 @ 60 Hz CEA-861 Format 18 */
++ .name = "576p50",
++ .x_res = 720,
++ .y_res = 576,
++ .hfp = 12,
++ .hsw = 64,
++ .hbp = 68,
++ .vfp = 5,
++ .vsw = 5,
++ .vbp = 39,
++ .pixel_clock = 27000,
++ },
+ {
+- .name = "1280x720@50",
++ /* 1280 x 720 @ 50 Hz CEA-861B Format 19 */
++ .name = "720p50",
+ .x_res = 1280,
+ .y_res = 720,
+ .hfp = 440,
+@@ -95,7 +189,8 @@ static const struct video_mode video_modes[] = {
+ .pixel_clock = 74250,
+ },
+ {
+- .name = "1280x720@60",
++ /* 1280 x 720 @ 60 Hz CEA-861B Format 4 */
++ .name = "720p60",
+ .x_res = 1280,
+ .y_res = 720,
+ .hfp = 110,
+@@ -107,7 +202,8 @@ static const struct video_mode video_modes[] = {
+ .pixel_clock = 74250,
+ },
+ {
+- .name = "1920x1080@24",
++ /* 1920 x 1080 @ 24 Hz CEA-861B Format 32 */
++ .name = "1080p24",
+ .x_res = 1920,
+ .y_res = 1080,
+ .hfp = 148,
+@@ -116,10 +212,11 @@ static const struct video_mode video_modes[] = {
+ .vfp = 36,
+ .vsw = 5,
+ .vbp = 4,
+- .pixel_clock = 74160,
++ .pixel_clock = 74250,
+ },
+ {
+- .name = "1920x1080@25",
++ /* 1920 x 1080 @ 25 Hz CEA-861B Format 33 */
++ .name = "1080p25",
+ .x_res = 1920,
+ .y_res = 1080,
+ .hfp = 148,
+@@ -129,7 +226,20 @@ static const struct video_mode video_modes[] = {
+ .vsw = 5,
+ .vbp = 4,
+ .pixel_clock = 74250,
+- }
++ },
++ {
++ /* 1920 x 1080 @ 25 Hz CEA-861B Format 34 */
++ .name = "1080p30",
++ .x_res = 1920,
++ .y_res = 1080,
++ .hfp = 148,
++ .hsw = 44,
++ .hbp = 88,
++ .vfp = 36,
++ .vsw = 5,
++ .vbp = 4,
++ .pixel_clock = 74250,
++ },
+ };
+
+ /*
+@@ -1763,16 +1873,18 @@ static int omapfb_do_probe(struct platform_device *pdev,
+ goto cleanup;
+ }
+
+- if (def_mode != -1) {
+- fbdev->panel->x_res = video_modes[def_mode].x_res;
+- fbdev->panel->y_res = video_modes[def_mode].y_res;
+- fbdev->panel->pixel_clock = video_modes[def_mode].pixel_clock;
+- fbdev->panel->hsw = video_modes[def_mode].hsw;
+- fbdev->panel->hfp = video_modes[def_mode].hfp;
+- fbdev->panel->hbp = video_modes[def_mode].hbp;
+- fbdev->panel->vsw = video_modes[def_mode].vsw;
+- fbdev->panel->vfp = video_modes[def_mode].vfp;
+- fbdev->panel->vbp = video_modes[def_mode].vbp;
++ if (video_mode.name) {
++ pr_info("omapfb: using mode %s\n", video_mode.name);
++
++ fbdev->panel->x_res = video_mode.x_res;
++ fbdev->panel->y_res = video_mode.y_res;
++ fbdev->panel->pixel_clock = video_mode.pixel_clock;
++ fbdev->panel->hsw = video_mode.hsw;
++ fbdev->panel->hfp = video_mode.hfp;
++ fbdev->panel->hbp = video_mode.hbp;
++ fbdev->panel->vsw = video_mode.vsw;
++ fbdev->panel->vfp = video_mode.vfp;
++ fbdev->panel->vbp = video_mode.vbp;
+ }
+
+ r = fbdev->panel->init(fbdev->panel, fbdev);
+@@ -1931,14 +2043,15 @@ static struct platform_driver omapfb_driver = {
+ },
+ };
+
+-static int __init omapfb_find_mode(char *mode)
++static void __init omapfb_find_mode(char *name, struct video_mode *vmode)
+ {
+ int i;
+
+ for (i = 0; i < sizeof(video_modes)/sizeof(video_modes[0]); i++)
+- if (!strcmp(mode, video_modes[i].name))
+- return i;
+- return -1;
++ if (!strcmp(name, video_modes[i].name)) {
++ *vmode = video_modes[i];
++ break;
++ }
+ }
+
+ #ifndef MODULE
+@@ -1990,7 +2103,7 @@ static int __init omapfb_setup(char *options)
+ else if (!strncmp(this_opt, "manual_update", 13))
+ manual_update = 1;
+ else if (!strncmp(this_opt, "mode:", 5))
+- def_mode = omapfb_find_mode(this_opt + 5);
++ strncpy(def_mode, this_opt + 5, sizeof(def_mode));
+ else {
+ pr_debug("omapfb: invalid option\n");
+ r = -1;
+@@ -2012,6 +2125,9 @@ static int __init omapfb_init(void)
+ return -ENODEV;
+ omapfb_setup(option);
+ #endif
++
++ omapfb_find_mode(def_mode, &video_mode);
++
+ /* Register the driver with LDM */
+ if (platform_driver_register(&omapfb_driver)) {
+ pr_debug("failed to register omapfb driver\n");
+@@ -2033,6 +2149,7 @@ module_param_named(vyres, def_vyres, long, 0664);
+ module_param_named(rotate, def_rotate, uint, 0664);
+ module_param_named(mirror, def_mirror, uint, 0664);
+ module_param_named(manual_update, manual_update, bool, 0664);
++module_param_string(video_mode, def_mode, sizeof(def_mode), 0664);
+
+ module_init(omapfb_init);
+ module_exit(omapfb_cleanup);
diff --git a/packages/linux/linux-omap/004-mru-export-omapfb-register-panel.diff b/packages/linux/linux-omap/004-mru-export-omapfb-register-panel.diff
new file mode 100644
index 0000000000..24ebcdea52
--- /dev/null
+++ b/packages/linux/linux-omap/004-mru-export-omapfb-register-panel.diff
@@ -0,0 +1,25 @@
+From: Mans Rullgard <mans@mansr.com>
+Date: Wed, 3 Sep 2008 20:56:03 +0000 (+0100)
+Subject: OMAP: Export omapfb_register_panel()
+X-Git-Url: http://git.mansr.com/?p=linux-omap;a=commitdiff_plain;h=44811584aded9e47a83d69ad31002a6bb94730dc
+
+OMAP: Export omapfb_register_panel()
+
+This exports omapfb_register_panel() for use by LCD drivers built
+as modules.
+
+Signed-off-by: Mans Rullgard <mans@mansr.com>
+---
+
+diff --git a/drivers/video/omap/omapfb_main.c b/drivers/video/omap/omapfb_main.c
+index 2e53d8f..912cb0c 100644
+--- a/drivers/video/omap/omapfb_main.c
++++ b/drivers/video/omap/omapfb_main.c
+@@ -1997,6 +1997,7 @@ void omapfb_register_panel(struct lcd_panel *panel)
+ if (fbdev_pdev != NULL)
+ omapfb_do_probe(fbdev_pdev, fbdev_panel);
+ }
++EXPORT_SYMBOL(omapfb_register_panel);
+
+ /* Called when the device is being detached from the driver */
+ static int omapfb_remove(struct platform_device *pdev)
diff --git a/packages/linux/linux-omap/005-mru-add-omapfb-unregister-panel.diff b/packages/linux/linux-omap/005-mru-add-omapfb-unregister-panel.diff
new file mode 100644
index 0000000000..faee384e74
--- /dev/null
+++ b/packages/linux/linux-omap/005-mru-add-omapfb-unregister-panel.diff
@@ -0,0 +1,67 @@
+From: Mans Rullgard <mans@mansr.com>
+Date: Wed, 3 Sep 2008 20:57:59 +0000 (+0100)
+Subject: OMAP: Add omapfb_unregister_panel() function
+X-Git-Url: http://git.mansr.com/?p=linux-omap;a=commitdiff_plain;h=85b5d3ba7221193cb2315256b69e97f34d2ae3b7
+
+OMAP: Add omapfb_unregister_panel() function
+
+This adds the function omapfb_unregister_panel() for use by LCD
+drivers built as modules.
+
+Signed-off-by: Mans Rullgard <mans@mansr.com>
+---
+
+diff --git a/arch/arm/plat-omap/include/mach/omapfb.h b/arch/arm/plat-omap/include/mach/omapfb.h
+index a4a84f3..3ccb076 100644
+--- a/arch/arm/plat-omap/include/mach/omapfb.h
++++ b/arch/arm/plat-omap/include/mach/omapfb.h
+@@ -378,6 +378,7 @@ extern struct lcd_ctrl omap2_disp_ctrl;
+
+ extern void omapfb_reserve_sdram(void);
+ extern void omapfb_register_panel(struct lcd_panel *panel);
++extern void omapfb_unregister_panel(struct lcd_panel *panel);
+ extern void omapfb_write_first_pixel(struct omapfb_device *fbdev, u16 pixval);
+ extern void omapfb_notify_clients(struct omapfb_device *fbdev,
+ unsigned long event);
+diff --git a/drivers/video/omap/omapfb_main.c b/drivers/video/omap/omapfb_main.c
+index 912cb0c..6d09e03 100644
+--- a/drivers/video/omap/omapfb_main.c
++++ b/drivers/video/omap/omapfb_main.c
+@@ -1736,7 +1736,8 @@ static void omapfb_free_resources(struct omapfb_device *fbdev, int state)
+ case 7:
+ omapfb_unregister_sysfs(fbdev);
+ case 6:
+- fbdev->panel->disable(fbdev->panel);
++ if (fbdev->panel)
++ fbdev->panel->disable(fbdev->panel);
+ case 5:
+ omapfb_set_update_mode(fbdev, OMAPFB_UPDATE_DISABLED);
+ case 4:
+@@ -1744,7 +1745,8 @@ static void omapfb_free_resources(struct omapfb_device *fbdev, int state)
+ case 3:
+ ctrl_cleanup(fbdev);
+ case 2:
+- fbdev->panel->cleanup(fbdev->panel);
++ if (fbdev->panel)
++ fbdev->panel->cleanup(fbdev->panel);
+ case 1:
+ dev_set_drvdata(fbdev->dev, NULL);
+ kfree(fbdev);
+@@ -1999,6 +2001,17 @@ void omapfb_register_panel(struct lcd_panel *panel)
+ }
+ EXPORT_SYMBOL(omapfb_register_panel);
+
++void omapfb_unregister_panel(struct lcd_panel *panel)
++{
++ BUG_ON(fbdev_panel != panel);
++
++ panel->disable(panel);
++
++ omapfb_dev->panel = NULL;
++ fbdev_panel = NULL;
++}
++EXPORT_SYMBOL(omapfb_unregister_panel);
++
+ /* Called when the device is being detached from the driver */
+ static int omapfb_remove(struct platform_device *pdev)
+ {
diff --git a/packages/linux/linux-omap/006-mru-lcd-as-modules.diff b/packages/linux/linux-omap/006-mru-lcd-as-modules.diff
new file mode 100644
index 0000000000..e522b3f7bf
--- /dev/null
+++ b/packages/linux/linux-omap/006-mru-lcd-as-modules.diff
@@ -0,0 +1,174 @@
+From: Mans Rullgard <mans@mansr.com>
+Date: Wed, 3 Sep 2008 23:05:33 +0000 (+0100)
+Subject: OMAP: Build LCD drivers as separate modules
+X-Git-Url: http://git.mansr.com/?p=linux-omap;a=commitdiff_plain;h=127dc3100fe9d25ed2b6c0a056e4160cc05db653
+
+OMAP: Build LCD drivers as separate modules
+
+This enables building the various LCD drivers as modules separate
+from omapfb.
+
+Signed-off-by: Mans Rullgard <mans@mansr.com>
+---
+
+diff --git a/drivers/video/omap/Kconfig b/drivers/video/omap/Kconfig
+index 9977e80..93cd760 100644
+--- a/drivers/video/omap/Kconfig
++++ b/drivers/video/omap/Kconfig
+@@ -53,6 +53,70 @@ config FB_OMAP_LCD_MIPID
+ the Mobile Industry Processor Interface DBI-C/DCS
+ specification. (Supported LCDs: Philips LPH8923, Sharp LS041Y3)
+
++config OMAP_FB_LCD_AMS_DELTA
++ tristate "AMS DELTA LCD support"
++ depends on FB_OMAP && MACH_AMS_DELTA
++
++config OMAP_FB_LCD_H2
++ tristate "H2 LCD support"
++ depends on FB_OMAP && MACH_OMAP_H2
++
++config OMAP_FB_LCD_H3
++ tristate "H3 LCD support"
++ depends on FB_OMAP && MACH_OMAP_H3
++
++config OMAP_FB_LCD_H4
++ tristate "OMAP 2420 H4 LCD support"
++ depends on FB_OMAP && MACH_OMAP_H4
++
++config OMAP_FB_LCD_PALMTE
++ tristate "PALMTE LCD support"
++ depends on FB_OMAP && MACH_OMAP_PALMTE
++
++config OMAP_FB_LCD_PALMTT
++ tristate "PALMTT LCD support"
++ depends on FB_OMAP && MACH_OMAP_PALMTT
++
++config OMAP_FB_LCD_PALMZ71
++ tristate "PALMZ71 LCD support"
++ depends on FB_OMAP && MACH_OMAP_PALMZ71
++
++config OMAP_FB_LCD_INN1610
++ tristate "INN1610 LCD support"
++ depends on FB_OMAP && ARCH_OMAP16XX && MACH_OMAP_INNOVATOR
++
++config OMAP_FB_LCD_INN1510
++ tristate "INN1510 LCD support"
++ depends on FB_OMAP && ARCH_OMAP15XX && MACH_OMAP_INNOVATOR
++
++config OMAP_FB_LCD_OSK
++ tristate "OSK LCD support"
++ depends on FB_OMAP && MACH_OMAP_OSK
++
++config OMAP_FB_LCD_SX1
++ tristate "SX1 LCD support"
++ depends on FB_OMAP && MACH_SX1
++
++config OMAP_FB_LCD_APOLLON
++ tristate "OMAP 2420 Apollon LCD support"
++ depends on FB_OMAP && MACH_OMAP_APOLLON
++
++config OMAP_FB_LCD_2430SDP
++ tristate "OMAP 2430/3430 SDP LCD support"
++ depends on FB_OMAP && (MACH_OMAP_2430SDP || MACH_OMAP_3430SDP)
++
++config OMAP_FB_LCD_OMAP2EVM
++ tristate "OMAP 2530 EVM LCD support"
++ depends on FB_OMAP && MACH_OMAP2EVM
++
++config OMAP_FB_LCD_OMAP3EVM
++ tristate "OMAP 3530 EVM LCD support"
++ depends on FB_OMAP && MACH_OMAP3EVM
++
++config OMAP_FB_LCD_OMAP3BEAGLE
++ tristate "Beagle board DVI port support"
++ depends on FB_OMAP && MACH_OMAP3_BEAGLE
++
+ config FB_OMAP_BOOTLOADER_INIT
+ bool "Check bootloader initialization"
+ depends on FB_OMAP
+diff --git a/drivers/video/omap/Makefile b/drivers/video/omap/Makefile
+dissimilarity index 64%
+index f9b5cd4..dbdcd67 100644
+--- a/drivers/video/omap/Makefile
++++ b/drivers/video/omap/Makefile
+@@ -1,40 +1,40 @@
+-#
+-# Makefile for the new OMAP framebuffer device driver
+-#
+-
+-obj-$(CONFIG_FB_OMAP) += omapfb.o
+-
+-objs-yy := omapfb_main.o
+-
+-objs-y$(CONFIG_ARCH_OMAP1) += lcdc.o
+-objs-y$(CONFIG_ARCH_OMAP2) += dispc.o
+-objs-y$(CONFIG_ARCH_OMAP3) += dispc.o
+-
+-objs-$(CONFIG_ARCH_OMAP1)$(CONFIG_FB_OMAP_LCDC_EXTERNAL) += sossi.o
+-objs-$(CONFIG_ARCH_OMAP2)$(CONFIG_FB_OMAP_LCDC_EXTERNAL) += rfbi.o
+-
+-objs-y$(CONFIG_FB_OMAP_LCDC_HWA742) += hwa742.o
+-objs-y$(CONFIG_FB_OMAP_LCDC_BLIZZARD) += blizzard.o
+-
+-objs-y$(CONFIG_MACH_AMS_DELTA) += lcd_ams_delta.o
+-objs-y$(CONFIG_MACH_OMAP_H4) += lcd_h4.o
+-objs-y$(CONFIG_MACH_OMAP_H3) += lcd_h3.o
+-objs-y$(CONFIG_MACH_OMAP_H2) += lcd_h2.o
+-objs-y$(CONFIG_MACH_OMAP_PALMTE) += lcd_palmte.o
+-objs-y$(CONFIG_MACH_OMAP_PALMTT) += lcd_palmtt.o
+-objs-y$(CONFIG_MACH_OMAP_PALMZ71) += lcd_palmz71.o
+-objs-$(CONFIG_ARCH_OMAP16XX)$(CONFIG_MACH_OMAP_INNOVATOR) += lcd_inn1610.o
+-objs-$(CONFIG_ARCH_OMAP15XX)$(CONFIG_MACH_OMAP_INNOVATOR) += lcd_inn1510.o
+-objs-y$(CONFIG_MACH_OMAP_OSK) += lcd_osk.o
+-objs-y$(CONFIG_MACH_SX1) += lcd_sx1.o
+-
+-objs-y$(CONFIG_MACH_OMAP_APOLLON) += lcd_apollon.o
+-objs-y$(CONFIG_MACH_OMAP_2430SDP) += lcd_2430sdp.o
+-objs-y$(CONFIG_MACH_OMAP_3430SDP) += lcd_2430sdp.o
+-objs-y$(CONFIG_MACH_OMAP2EVM) += lcd_omap2evm.o
+-objs-y$(CONFIG_MACH_OMAP3EVM) += lcd_omap3evm.o
+-objs-y$(CONFIG_MACH_OMAP3_BEAGLE) += lcd_omap3beagle.o
+-objs-y$(CONFIG_FB_OMAP_LCD_MIPID) += lcd_mipid.o
+-
+-omapfb-objs := $(objs-yy)
+-
++#
++# Makefile for the new OMAP framebuffer device driver
++#
++
++obj-$(CONFIG_FB_OMAP) += omapfb.o
++
++objs-yy := omapfb_main.o
++
++objs-y$(CONFIG_ARCH_OMAP1) += lcdc.o
++objs-y$(CONFIG_ARCH_OMAP2) += dispc.o
++objs-y$(CONFIG_ARCH_OMAP3) += dispc.o
++
++objs-$(CONFIG_ARCH_OMAP1)$(CONFIG_FB_OMAP_LCDC_EXTERNAL) += sossi.o
++objs-$(CONFIG_ARCH_OMAP2)$(CONFIG_FB_OMAP_LCDC_EXTERNAL) += rfbi.o
++
++objs-y$(CONFIG_FB_OMAP_LCDC_HWA742) += hwa742.o
++objs-y$(CONFIG_FB_OMAP_LCDC_BLIZZARD) += blizzard.o
++
++obj-$(CONFIG_OMAP_FB_LCD_AMS_DELTA) += lcd_ams_delta.o
++obj-$(CONFIG_OMAP_FB_LCD_H4) += lcd_h4.o
++obj-$(CONFIG_OMAP_FB_LCD_H3) += lcd_h3.o
++obj-$(CONFIG_OMAP_FB_LCD_H2) += lcd_h2.o
++obj-$(CONFIG_OMAP_FB_LCD_PALMTE) += lcd_palmte.o
++obj-$(CONFIG_OMAP_FB_LCD_PALMTT) += lcd_palmtt.o
++obj-$(CONFIG_OMAP_FB_LCD_PALMZ71) += lcd_palmz71.o
++obj-$(CONFIG_OMAP_FB_LCD_INN1610) += lcd_inn1610.o
++obj-$(CONFIG_OMAP_FB_LCD_INN1510) += lcd_inn1510.o
++obj-$(CONFIG_OMAP_FB_LCD_OSK) += lcd_osk.o
++obj-$(CONFIG_OMAP_FB_LCD_SX1) += lcd_sx1.o
++
++obj-$(CONFIG_OMAP_FB_LCD_APOLLON) += lcd_apollon.o
++obj-$(CONFIG_OMAP_FB_LCD_2430SDP) += lcd_2430sdp.o
++obj-$(CONFIG_OMAP_FB_LCD_2430SDP) += lcd_2430sdp.o
++obj-$(CONFIG_OMAP_FB_LCD_OMAP2EVM) += lcd_omap2evm.o
++obj-$(CONFIG_OMAP_FB_LCD_OMAP3EVM) += lcd_omap3evm.o
++obj-$(CONFIG_OMAP_FB_LCD_OMAP3BEAGLE) += lcd_omap3beagle.o
++obj-$(CONFIG_OMAP_FB_LCD_MIPID) += lcd_mipid.o
++
++omapfb-objs := $(objs-yy)
++
diff --git a/packages/linux/linux-omap/007-mru-omapfb-as-module.diff b/packages/linux/linux-omap/007-mru-omapfb-as-module.diff
new file mode 100644
index 0000000000..e1eed0d154
--- /dev/null
+++ b/packages/linux/linux-omap/007-mru-omapfb-as-module.diff
@@ -0,0 +1,50 @@
+From: Mans Rullgard <mans@mansr.com>
+Date: Wed, 3 Sep 2008 23:10:08 +0000 (+0100)
+Subject: OMAP: Fix omapfb built as module
+X-Git-Url: http://git.mansr.com/?p=linux-omap;a=commitdiff_plain;h=ae65001ce247e510121bcda21775263bb4c42e05
+
+OMAP: Fix omapfb built as module
+
+This makes it possible to build omapfb as a module.
+
+Signed-off-by: Mans Rullgard <mans@mansr.com>
+---
+
+diff --git a/drivers/video/omap/dispc.c b/drivers/video/omap/dispc.c
+index 6187e8f..4213c4f 100644
+--- a/drivers/video/omap/dispc.c
++++ b/drivers/video/omap/dispc.c
+@@ -1073,7 +1073,8 @@ static int mmap_kern(struct omapfb_mem_region *region)
+ pgprot_t pgprot;
+ unsigned long vaddr;
+
+- kvma = get_vm_area(region->size, VM_IOREMAP);
++ kvma = __get_vm_area(region->size, VM_IOREMAP,
++ VMALLOC_START, VMALLOC_END);
+ if (kvma == NULL) {
+ dev_err(dispc.fbdev->dev, "can't get kernel vm area\n");
+ return -ENOMEM;
+diff --git a/drivers/video/omap/omapfb_main.c b/drivers/video/omap/omapfb_main.c
+index 6d09e03..19a1a83 100644
+--- a/drivers/video/omap/omapfb_main.c
++++ b/drivers/video/omap/omapfb_main.c
+@@ -2016,12 +2016,15 @@ EXPORT_SYMBOL(omapfb_unregister_panel);
+ static int omapfb_remove(struct platform_device *pdev)
+ {
+ struct omapfb_device *fbdev = platform_get_drvdata(pdev);
+- enum omapfb_state saved_state = fbdev->state;
+
+- /* FIXME: wait till completion of pending events */
++ if (fbdev) {
++ enum omapfb_state saved_state = fbdev->state;
+
+- fbdev->state = OMAPFB_DISABLED;
+- omapfb_free_resources(fbdev, saved_state);
++ /* FIXME: wait till completion of pending events */
++
++ fbdev->state = OMAPFB_DISABLED;
++ omapfb_free_resources(fbdev, saved_state);
++ }
+
+ return 0;
+ }
diff --git a/packages/linux/linux-omap/008-mru-lcd-omap3beagle-license.diff b/packages/linux/linux-omap/008-mru-lcd-omap3beagle-license.diff
new file mode 100644
index 0000000000..4f69dd971a
--- /dev/null
+++ b/packages/linux/linux-omap/008-mru-lcd-omap3beagle-license.diff
@@ -0,0 +1,22 @@
+From: Mans Rullgard <mans@mansr.com>
+Date: Wed, 3 Sep 2008 23:12:03 +0000 (+0100)
+Subject: OMAP: Add missing MODULE_LICENSE in lcd_omap3beagle
+X-Git-Url: http://git.mansr.com/?p=linux-omap;a=commitdiff_plain;h=368ba31e3e7dccdcea790c559ad3d3b4a20d924f
+
+OMAP: Add missing MODULE_LICENSE in lcd_omap3beagle
+
+This adds a missing MODULE_LICENSE("GPL") in lcd_omap3beagle.
+
+Signed-off-by: Mans Rullgard <mans@mansr.com>
+---
+
+diff --git a/drivers/video/omap/lcd_omap3beagle.c b/drivers/video/omap/lcd_omap3beagle.c
+index f2861ec..7b63db9 100644
+--- a/drivers/video/omap/lcd_omap3beagle.c
++++ b/drivers/video/omap/lcd_omap3beagle.c
+@@ -127,3 +127,5 @@ static void __exit omap3beagle_panel_drv_exit(void)
+
+ module_init(omap3beagle_panel_drv_init);
+ module_exit(omap3beagle_panel_drv_exit);
++
++MODULE_LICENSE("GPL");
diff --git a/packages/linux/linux-omap/009-mru-unregister-beagle-lcd.diff b/packages/linux/linux-omap/009-mru-unregister-beagle-lcd.diff
new file mode 100644
index 0000000000..c7e94bf3a4
--- /dev/null
+++ b/packages/linux/linux-omap/009-mru-unregister-beagle-lcd.diff
@@ -0,0 +1,24 @@
+From: Mans Rullgard <mans@mansr.com>
+Date: Wed, 3 Sep 2008 23:17:06 +0000 (+0100)
+Subject: OMAP: Fix unloading lcd_omap3beagle module
+X-Git-Url: http://git.mansr.com/?p=linux-omap;a=commitdiff_plain;h=6db3a4c28c6819047362fc8ac460cf8c124c6074
+
+OMAP: Fix unloading lcd_omap3beagle module
+
+Unregister the panel when unloading the lcd_omap3beagle module.
+
+Signed-off-by: Mans Rullgard <mans@mansr.com>
+---
+
+diff --git a/drivers/video/omap/lcd_omap3beagle.c b/drivers/video/omap/lcd_omap3beagle.c
+index 7b63db9..32bd988 100644
+--- a/drivers/video/omap/lcd_omap3beagle.c
++++ b/drivers/video/omap/lcd_omap3beagle.c
+@@ -90,6 +90,7 @@ static int omap3beagle_panel_probe(struct platform_device *pdev)
+
+ static int omap3beagle_panel_remove(struct platform_device *pdev)
+ {
++ omapfb_unregister_panel(&omap3beagle_panel);
+ return 0;
+ }
+
diff --git a/packages/linux/linux-omap/01-fix-timing-print.diff b/packages/linux/linux-omap/01-fix-timing-print.diff
new file mode 100644
index 0000000000..89fbe3a836
--- /dev/null
+++ b/packages/linux/linux-omap/01-fix-timing-print.diff
@@ -0,0 +1,23 @@
+From: Mans Rullgard <mans@mansr.com>
+Date: Sat, 5 Jul 2008 20:31:56 +0000 (+0100)
+Subject: omapfb: fix video timings message
+X-Git-Tag: beagle-5~3
+X-Git-Url: http://git.mansr.com/?p=linux-omap;a=commitdiff_plain;h=2929b75035ebe8702ba2ff2c81b654c487701f64
+
+omapfb: fix video timings message
+---
+
+diff --git a/drivers/video/omap/omapfb_main.c b/drivers/video/omap/omapfb_main.c
+index 418ed9f..1166a01 100644
+--- a/drivers/video/omap/omapfb_main.c
++++ b/drivers/video/omap/omapfb_main.c
+@@ -1789,7 +1789,8 @@ static int omapfb_do_probe(struct platform_device *pdev,
+ vram, fbdev->mem_desc.region_cnt);
+ pr_info("omapfb: Pixclock %lu kHz hfreq %lu.%lu kHz "
+ "vfreq %lu.%lu Hz\n",
+- phz / 1000, hhz / 10000, hhz % 10, vhz / 10, vhz % 10);
++ phz / 1000, hhz / 10000, hhz % 10000,
++ vhz / 10, vhz % 10);
+
+ return 0;
+
diff --git a/packages/linux/linux-omap/010-mru-fix-video-mode-param.diff b/packages/linux/linux-omap/010-mru-fix-video-mode-param.diff
new file mode 100644
index 0000000000..50d69b8b75
--- /dev/null
+++ b/packages/linux/linux-omap/010-mru-fix-video-mode-param.diff
@@ -0,0 +1,35 @@
+From: Mans Rullgard <mans@mansr.com>
+Date: Wed, 3 Sep 2008 23:19:04 +0000 (+0100)
+Subject: OMAP: Fix omapfb video mode selection when built as module
+X-Git-Url: http://git.mansr.com/?p=linux-omap;a=commitdiff_plain;h=9bafff77f3028cd170c605c8d883963522c8546c
+
+OMAP: Fix omapfb video mode selection when built as module
+
+This fixes the video_mode parameter when omapfb is built as a module.
+
+Signed-off-by: Mans Rullgard <mans@mansr.com>
+---
+
+diff --git a/drivers/video/omap/omapfb_main.c b/drivers/video/omap/omapfb_main.c
+index 19a1a83..e0b3642 100644
+--- a/drivers/video/omap/omapfb_main.c
++++ b/drivers/video/omap/omapfb_main.c
+@@ -54,7 +54,7 @@ static unsigned long def_vxres;
+ static unsigned long def_vyres;
+ static unsigned int def_rotate;
+ static unsigned int def_mirror;
+-static char def_mode[16] = CONFIG_FB_OMAP_VIDEO_MODE;
++static char def_mode[16];
+
+ #ifdef CONFIG_FB_OMAP_MANUAL_UPDATE
+ static int manual_update = 1;
+@@ -2143,7 +2143,8 @@ static int __init omapfb_init(void)
+ omapfb_setup(option);
+ #endif
+
+- omapfb_find_mode(def_mode, &video_mode);
++ omapfb_find_mode(def_mode[0]? def_mode : CONFIG_FB_OMAP_VIDEO_MODE,
++ &video_mode);
+
+ /* Register the driver with LDM */
+ if (platform_driver_register(&omapfb_driver)) {
diff --git a/packages/linux/linux-omap/02-set-clkseld11.diff b/packages/linux/linux-omap/02-set-clkseld11.diff
new file mode 100644
index 0000000000..c437f145d3
--- /dev/null
+++ b/packages/linux/linux-omap/02-set-clkseld11.diff
@@ -0,0 +1,22 @@
+From: Mans Rullgard <mans@mansr.com>
+Date: Sat, 5 Jul 2008 20:32:38 +0000 (+0100)
+Subject: omap: set CLKSEL_DSS1 to 2
+X-Git-Tag: beagle-5~2
+X-Git-Url: http://git.mansr.com/?p=linux-omap;a=commitdiff_plain;h=d23f9c3c5c6243b626f7ec4c255469de2536e488
+
+omap: set CLKSEL_DSS1 to 2
+---
+
+diff --git a/arch/arm/mach-omap2/clock34xx.c b/arch/arm/mach-omap2/clock34xx.c
+index 8fdf8f3..04dedec 100644
+--- a/arch/arm/mach-omap2/clock34xx.c
++++ b/arch/arm/mach-omap2/clock34xx.c
+@@ -596,6 +596,8 @@ int __init omap2_clk_init(void)
+ /* u32 clkrate; */
+ u32 cpu_clkflg;
+
++ __raw_writel(0x1002, io_p2v(0x48004e40));
++
+ /* REVISIT: Ultimately this will be used for multiboot */
+ #if 0
+ if (cpu_is_omap242x()) {
diff --git a/packages/linux/linux-omap/03-enable-overlay-opt.diff b/packages/linux/linux-omap/03-enable-overlay-opt.diff
new file mode 100644
index 0000000000..9fa749f5fc
--- /dev/null
+++ b/packages/linux/linux-omap/03-enable-overlay-opt.diff
@@ -0,0 +1,27 @@
+From: Mans Rullgard <mans@mansr.com>
+Date: Sun, 6 Jul 2008 13:15:36 +0000 (+0100)
+Subject: omapfb: enable overlay optimisation when possible
+X-Git-Tag: beagle-5~1
+X-Git-Url: http://git.mansr.com/?p=linux-omap;a=commitdiff_plain;h=a63ac3abdf6781f863112321260fe7a5da757802
+
+omapfb: enable overlay optimisation when possible
+---
+
+diff --git a/drivers/video/omap/dispc.c b/drivers/video/omap/dispc.c
+index 6aff476..3b36227 100644
+--- a/drivers/video/omap/dispc.c
++++ b/drivers/video/omap/dispc.c
+@@ -582,11 +582,13 @@ static int omap_dispc_enable_plane(int plane, int enable)
+ const u32 at_reg[] = { DISPC_GFX_ATTRIBUTES,
+ DISPC_VID1_BASE + DISPC_VID_ATTRIBUTES,
+ DISPC_VID2_BASE + DISPC_VID_ATTRIBUTES };
++ unsigned overlay_opt = plane & !!enable & !dispc.color_key.key_type;
+ if ((unsigned int)plane > dispc.mem_desc.region_cnt)
+ return -EINVAL;
+
+ enable_lcd_clocks(1);
+ MOD_REG_FLD(at_reg[plane], 1, enable ? 1 : 0);
++ MOD_REG_FLD(DISPC_CONTROL, 1<<12 | 1<<5, overlay_opt<<12 | 1<<5);
+ enable_lcd_clocks(0);
+
+ return 0;
diff --git a/packages/linux/linux-omap/04-use-pcd.diff b/packages/linux/linux-omap/04-use-pcd.diff
new file mode 100644
index 0000000000..bdf8ab5f0b
--- /dev/null
+++ b/packages/linux/linux-omap/04-use-pcd.diff
@@ -0,0 +1,28 @@
+From: Mans Rullgard <mans@mansr.com>
+Date: Sun, 6 Jul 2008 13:22:54 +0000 (+0100)
+Subject: omapfb: use PCD if set in panel config
+X-Git-Tag: beagle-5
+X-Git-Url: http://git.mansr.com/?p=linux-omap;a=commitdiff_plain;h=c8060d36ae156771f00a7a27cabf1b4435c378bd
+
+omapfb: use PCD if set in panel config
+---
+
+diff --git a/drivers/video/omap/dispc.c b/drivers/video/omap/dispc.c
+index 3b36227..4e1a8e3 100644
+--- a/drivers/video/omap/dispc.c
++++ b/drivers/video/omap/dispc.c
+@@ -798,7 +798,13 @@ static void set_lcd_timings(void)
+ l |= panel->acb & 0xff;
+ dispc_write_reg(DISPC_POL_FREQ, l);
+
+- calc_ck_div(is_tft, panel->pixel_clock * 1000, &lck_div, &pck_div);
++ if (panel->pcd) {
++ pck_div = panel->pcd;
++ lck_div = 1;
++ } else {
++ calc_ck_div(is_tft, panel->pixel_clock * 1000,
++ &lck_div, &pck_div);
++ }
+
+ l = dispc_read_reg(DISPC_DIVISOR);
+ l &= ~(FLD_MASK(16, 8) | FLD_MASK(0, 8));
diff --git a/packages/linux/linux-omap/05-fix-display-panning.diff b/packages/linux/linux-omap/05-fix-display-panning.diff
new file mode 100644
index 0000000000..d3c9fffcda
--- /dev/null
+++ b/packages/linux/linux-omap/05-fix-display-panning.diff
@@ -0,0 +1,45 @@
+From: Mans Rullgard <mans@mansr.com>
+Date: Mon, 7 Jul 2008 00:13:00 +0000 (+0100)
+Subject: omapfb: fix display panning
+X-Git-Url: http://git.mansr.com/?p=linux-omap;a=commitdiff_plain;h=9fec252c96b0e69bcef0afd9cb9dd72b7179c239
+
+omapfb: fix display panning
+---
+
+diff --git a/drivers/video/omap/dispc.c b/drivers/video/omap/dispc.c
+index 4e1a8e3..c17371c 100644
+--- a/drivers/video/omap/dispc.c
++++ b/drivers/video/omap/dispc.c
+@@ -435,6 +435,8 @@ static inline int _setup_plane(int plane, int channel_out,
+
+ dispc_write_reg(ri_reg[plane], (screen_width - width) * bpp / 8 + 1);
+
++ MOD_REG_FLD(DISPC_CONTROL, 1<<5, 1<<5);
++
+ return height * screen_width * bpp / 8;
+ }
+
+diff --git a/drivers/video/omap/omapfb_main.c b/drivers/video/omap/omapfb_main.c
+index 1166a01..3e4959e 100644
+--- a/drivers/video/omap/omapfb_main.c
++++ b/drivers/video/omap/omapfb_main.c
+@@ -206,8 +206,8 @@ static int ctrl_change_mode(struct fb_info *fbi)
+ struct omapfb_device *fbdev = plane->fbdev;
+ struct fb_var_screeninfo *var = &fbi->var;
+
+- offset = var->yoffset * fbi->fix.line_length +
+- var->xoffset * var->bits_per_pixel / 8;
++ offset = (var->yoffset * var->xres_virtual + var->xoffset) *
++ var->bits_per_pixel / 8;
+
+ if (fbdev->ctrl->sync)
+ fbdev->ctrl->sync();
+@@ -423,6 +423,8 @@ static void set_fb_fix(struct fb_info *fbi)
+ }
+ fix->accel = FB_ACCEL_OMAP1610;
+ fix->line_length = var->xres_virtual * bpp / 8;
++ fix->xpanstep = 1;
++ fix->ypanstep = 1;
+ }
+
+ static int set_color_mode(struct omapfb_plane_struct *plane,
diff --git a/packages/linux/linux-omap/06-ensure-fclk.diff b/packages/linux/linux-omap/06-ensure-fclk.diff
new file mode 100644
index 0000000000..79871a7208
--- /dev/null
+++ b/packages/linux/linux-omap/06-ensure-fclk.diff
@@ -0,0 +1,31 @@
+From: Mans Rullgard <mans@mansr.com>
+Date: Mon, 7 Jul 2008 23:59:08 +0000 (+0100)
+Subject: omapfb: ensure fck/lcd < 173MHz
+X-Git-Url: http://git.mansr.com/?p=linux-omap;a=commitdiff_plain;h=0523ece1bad659c48c66aea364d83f7490e7e5ae
+
+omapfb: ensure fck/lcd < 173MHz
+---
+
+diff --git a/drivers/video/omap/dispc.c b/drivers/video/omap/dispc.c
+index c17371c..85d6cad 100644
+--- a/drivers/video/omap/dispc.c
++++ b/drivers/video/omap/dispc.c
+@@ -738,14 +738,16 @@ static void setup_color_conv_coef(void)
+ MOD_REG_FLD(at2_reg, (1 << 11), ct->full_range);
+ }
+
++#define MAX_FCK_LCD 173000000
++
+ static void calc_ck_div(int is_tft, int pck, int *lck_div, int *pck_div)
+ {
+ unsigned long fck, lck;
+
+- *lck_div = 1;
+ pck = max(1, pck);
+ fck = clk_get_rate(dispc.dss1_fck);
+- lck = fck;
++ *lck_div = (fck + MAX_FCK_LCD - 1) / MAX_FCK_LCD;
++ lck = fck / *lck_div;
+ *pck_div = (lck + pck - 1) / pck;
+ if (is_tft)
+ *pck_div = max(2, *pck_div);
diff --git a/packages/linux/linux-omap/07-set-burst-size.diff b/packages/linux/linux-omap/07-set-burst-size.diff
new file mode 100644
index 0000000000..99bd80eae0
--- /dev/null
+++ b/packages/linux/linux-omap/07-set-burst-size.diff
@@ -0,0 +1,21 @@
+From: Mans Rullgard <mans@mansr.com>
+Date: Tue, 8 Jul 2008 18:26:43 +0000 (+0100)
+Subject: omapfb: set graphics burst size to 16x32
+X-Git-Url: http://git.mansr.com/?p=linux-omap;a=commitdiff_plain;h=4f9e415dfcd5613a8de973f6c9878cab959c5869
+
+omapfb: set graphics burst size to 16x32
+---
+
+diff --git a/drivers/video/omap/dispc.c b/drivers/video/omap/dispc.c
+index 85d6cad..fd06ca2 100644
+--- a/drivers/video/omap/dispc.c
++++ b/drivers/video/omap/dispc.c
+@@ -409,7 +409,7 @@ static inline int _setup_plane(int plane, int channel_out,
+ l |= cconv_en << 9;
+
+ l &= ~(0x03 << burst_shift);
+- l |= DISPC_BURST_8x32 << burst_shift;
++ l |= DISPC_BURST_16x32 << burst_shift;
+
+ l &= ~(1 << chout_shift);
+ l |= chout_val << chout_shift;
diff --git a/packages/linux/linux-omap/16bpp.patch b/packages/linux/linux-omap/16bpp.patch
new file mode 100644
index 0000000000..d2bff4b018
--- /dev/null
+++ b/packages/linux/linux-omap/16bpp.patch
@@ -0,0 +1,137 @@
+diff --git a/drivers/video/omap/Kconfig b/drivers/video/omap/Kconfig
+index bdeb8fb..bf256f3 100644
+--- a/drivers/video/omap/Kconfig
++++ b/drivers/video/omap/Kconfig
+@@ -7,6 +7,27 @@ config FB_OMAP
+ help
+ Frame buffer driver for OMAP based boards.
+
++choice
++ depends on FB_OMAP && MACH_OMAP3_BEAGLE
++ prompt "Screen resolution"
++ default FB_OMAP_079M3R
++ help
++ Selected desired screen resolution
++
++config FB_OMAP_031M3R
++ boolean "640 x 480 @ 60 Hz Reduced blanking"
++
++config FB_OMAP_048M3R
++ boolean "800 x 600 @ 60 Hz Reduced blanking"
++
++config FB_OMAP_079M3R
++ boolean "1024 x 768 @ 60 Hz Reduced blanking"
++
++config FB_OMAP_092M9R
++ boolean "1280 x 720 @ 60 Hz Reduced blanking"
++
++endchoice
++
+ config FB_OMAP_LCDC_EXTERNAL
+ bool "External LCD controller support"
+ depends on FB_OMAP
+diff --git a/drivers/video/omap/lcd_omap3beagle.c b/drivers/video/omap/lcd_omap3beagle.c
+index 69d4e06..5e098c2 100644
+--- a/drivers/video/omap/lcd_omap3beagle.c
++++ b/drivers/video/omap/lcd_omap3beagle.c
+@@ -31,10 +31,6 @@
+
+ #define LCD_PANEL_ENABLE_GPIO 170
+
+-#define LCD_XRES 1024
+-#define LCD_YRES 768
+-#define LCD_PIXCLOCK 64000 /* in kHz */
+-
+ static int omap3beagle_panel_init(struct lcd_panel *panel,
+ struct omapfb_device *fbdev)
+ {
+@@ -65,19 +61,76 @@ static unsigned long omap3beagle_panel_get_caps(struct lcd_panel *panel)
+ struct lcd_panel omap3beagle_panel = {
+ .name = "omap3beagle",
+ .config = OMAP_LCDC_PANEL_TFT,
+-
+- .bpp = 24,
++ .bpp = 16,
+ .data_lines = 24,
+- .x_res = LCD_XRES,
+- .y_res = LCD_YRES,
+- .hsw = 3, /* hsync_len (4) - 1 */
+- .hfp = 3, /* right_margin (4) - 1 */
+- .hbp = 39, /* left_margin (40) - 1 */
+- .vsw = 1, /* vsync_len (2) - 1 */
+- .vfp = 2, /* lower_margin */
+- .vbp = 7, /* upper_margin (8) - 1 */
+-
+- .pixel_clock = LCD_PIXCLOCK,
++
++#if defined CONFIG_FB_OMAP_031M3R
++
++ /* 640 x 480 @ 60 Hz Reduced blanking VESA CVT 0.31M3-R */
++ .x_res = 640,
++ .y_res = 480,
++ .hfp = 48,
++ .hsw = 32,
++ .hbp = 80,
++ .vfp = 3,
++ .vsw = 4,
++ .vbp = 7,
++ .pixel_clock = 23500,
++
++#elif defined CONFIG_FB_OMAP_048M3R
++
++ /* 800 x 600 @ 60 Hz Reduced blanking VESA CVT 0.48M3-R */
++ .x_res = 800,
++ .y_res = 600,
++ .hfp = 48,
++ .hsw = 32,
++ .hbp = 80,
++ .vfp = 3,
++ .vsw = 4,
++ .vbp = 11,
++ .pixel_clock = 35500,
++
++#elif defined CONFIG_FB_OMAP_079M3R
++
++ /* 1024 x 768 @ 60 Hz Reduced blanking VESA CVT 0.79M3-R */
++ .x_res = 1024,
++ .y_res = 768,
++ .hfp = 48,
++ .hsw = 32,
++ .hbp = 80,
++ .vfp = 3,
++ .vsw = 4,
++ .vbp = 15,
++ .pixel_clock = 56000,
++
++#elif defined CONFIG_FB_OMAP_092M9R
++
++ /* 1280 x 720 @ 60 Hz Reduced blanking VESA CVT 0.92M9-R */
++ .x_res = 1280,
++ .y_res = 720,
++ .hfp = 48,
++ .hsw = 32,
++ .hbp = 80,
++ .vfp = 3,
++ .vsw = 5,
++ .vbp = 13,
++ .pixel_clock = 64000,
++
++#else
++
++ /* use 640 x 480 if no config option */
++ /* 640 x 480 @ 60 Hz Reduced blanking VESA CVT 0.31M3-R */
++ .x_res = 640,
++ .y_res = 480,
++ .hfp = 48,
++ .hsw = 32,
++ .hbp = 80,
++ .vfp = 3,
++ .vsw = 4,
++ .vbp = 7,
++ .pixel_clock = 23500,
++
++#endif
+
+ .init = omap3beagle_panel_init,
+ .cleanup = omap3beagle_panel_cleanup,
+
diff --git a/packages/linux/linux-omap/4bitmmc.diff b/packages/linux/linux-omap/4bitmmc.diff
new file mode 100644
index 0000000000..5cd120c544
--- /dev/null
+++ b/packages/linux/linux-omap/4bitmmc.diff
@@ -0,0 +1,38 @@
+From: Purushotam Kumar <purushotam@ti.com>
+Date: Fri, 18 Jul 2008 23:28:57 +0000 (-0700)
+Subject: OMAP3:devices.c:Enabling 4-bit for SD card
+X-Git-Url: http://www.sakoman.net/cgi-bin/gitweb.cgi?p=linux-omap-2.6.git;a=commitdiff_plain;h=6c4d34031c80ca4b50ffe73a4ef7fe197a760a60
+
+OMAP3:devices.c:Enabling 4-bit for SD card
+
+SD card was working in 1-bit mode.This patch will configure SD card in
+4-bit mode and hence performance will increase.
+
+Signed-off-by: Purushotam Kumar <purushotam@ti.com>
+Acked-by: Madhusudhan Chikkature Rajashekar <madhu.cr@ti.com>
+---
+
+diff --git a/arch/arm/plat-omap/devices.c b/arch/arm/plat-omap/devices.c
+index b83f9a6..d0cfceb 100644
+--- a/arch/arm/plat-omap/devices.c
++++ b/arch/arm/plat-omap/devices.c
+@@ -296,13 +296,17 @@ static void __init omap_init_mmc(void)
+ mmc = &mmc_conf->mmc[0];
+
+ if (cpu_is_omap2430() || cpu_is_omap34xx()) {
+- if (mmc->enabled)
++ if (mmc->enabled) {
++ mmc1_data.conf = *mmc;
+ (void) platform_device_register(&mmc_omap_device1);
++ }
+
+ #if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP34XX)
+ mmc = &mmc_conf->mmc[1];
+- if (mmc->enabled)
++ if (mmc->enabled) {
++ mmc2_data.conf = *mmc;
+ (void) platform_device_register(&mmc_omap_device2);
++ }
+ #endif
+
+ return;
diff --git a/packages/linux/linux-omap/beagleboard/.mtn2git_empty b/packages/linux/linux-omap/beagleboard/.mtn2git_empty
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/packages/linux/linux-omap/beagleboard/.mtn2git_empty
diff --git a/packages/linux/linux-omap/cache-display-fix.patch b/packages/linux/linux-omap/cache-display-fix.patch
new file mode 100644
index 0000000000..019fd5acf1
--- /dev/null
+++ b/packages/linux/linux-omap/cache-display-fix.patch
@@ -0,0 +1,238 @@
+On Tue, 2008-07-01 at 06:23 +0100, Dirk Behme wrote:
+> Catalin Marinas wrote:
+> > But, anyway, if you want a patch, Harry is updating it to a recent
+> > kernel.
+>
+> Any news on this? I think there are some people wanting a patch ;)
+
+See below for a preliminary patch updated to 2.6.26-rc8. Note that I
+don't plan to submit it in its current form but clean it up a bit first.
+
+
+Show the cache type of ARMv7 CPUs
+
+From: Catalin Marinas <catalin.marinas@arm.com>
+
+Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
+---
+
+ arch/arm/kernel/setup.c | 137 +++++++++++++++++++++++++++++++++++++++++++++-
+ include/asm-arm/system.h | 18 ++++++
+ 2 files changed, 153 insertions(+), 2 deletions(-)
+
+
+diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
+index 5ae0eb2..0cd238d 100644
+--- a/arch/arm/kernel/setup.c
++++ b/arch/arm/kernel/setup.c
+@@ -256,6 +256,24 @@ static const char *proc_arch[] = {
+ "?(17)",
+ };
+
++static const char *v7_cache_policy[4] = {
++ "reserved",
++ "AVIVT",
++ "VIPT",
++ "PIPT",
++};
++
++static const char *v7_cache_type[8] = {
++ "none",
++ "instruction only",
++ "data only",
++ "separate instruction and data",
++ "unified",
++ "unknown type",
++ "unknown type",
++ "unknown type",
++};
++
+ #define CACHE_TYPE(x) (((x) >> 25) & 15)
+ #define CACHE_S(x) ((x) & (1 << 24))
+ #define CACHE_DSIZE(x) (((x) >> 12) & 4095) /* only if S=1 */
+@@ -266,6 +284,22 @@ static const char *proc_arch[] = {
+ #define CACHE_M(y) ((y) & (1 << 2))
+ #define CACHE_LINE(y) ((y) & 3)
+
++#define CACHE_TYPE_V7(x) (((x) >> 14) & 3)
++#define CACHE_UNIFIED(x) ((((x) >> 27) & 7)+1)
++#define CACHE_COHERENT(x) ((((x) >> 24) & 7)+1)
++
++#define CACHE_ID_LEVEL_MASK 7
++#define CACHE_ID_LEVEL_BITS 3
++
++#define CACHE_LINE_V7(v) ((1 << (((v) & 7)+4)))
++#define CACHE_ASSOC_V7(v) ((((v) >> 3) & ((1<<10)-1))+1)
++#define CACHE_SETS_V7(v) ((((v) >> 13) & ((1<<15)-1))+1)
++#define CACHE_SIZE_V7(v) (CACHE_LINE_V7(v)*CACHE_ASSOC_V7(v)*CACHE_SETS_V7(v))
++#define CACHE_WA_V7(v) (((v) & (1<<28)) != 0)
++#define CACHE_RA_V7(v) (((v) & (1<<29)) != 0)
++#define CACHE_WB_V7(v) (((v) & (1<<30)) != 0)
++#define CACHE_WT_V7(v) (((v) & (1<<31)) != 0)
++
+ static inline void dump_cache(const char *prefix, int cpu, unsigned int cache)
+ {
+ unsigned int mult = 2 + (CACHE_M(cache) ? 1 : 0);
+@@ -279,11 +313,57 @@ static inline void dump_cache(const char *prefix, int cpu, unsigned int cache)
+ CACHE_LINE(cache)));
+ }
+
++static void dump_v7_cache(const char *type, int cpu, unsigned int level)
++{
++ unsigned int cachesize;
++
++ write_extended_cpuid(2,0,0,0,level); /* Set the cache size selection register */
++ write_extended_cpuid(0,7,5,4,0); /* Prefetch flush to wait for above */
++ cachesize = read_extended_cpuid(1,0,0,0);
++
++ printk("CPU%u: %s cache: %d bytes, associativity %d, %d byte lines, %d sets,\n supports%s%s%s%s\n",
++ cpu, type,
++ CACHE_SIZE_V7(cachesize),CACHE_ASSOC_V7(cachesize),
++ CACHE_LINE_V7(cachesize),CACHE_SETS_V7(cachesize),
++ CACHE_WA_V7(cachesize) ? " WA" : "",
++ CACHE_RA_V7(cachesize) ? " RA" : "",
++ CACHE_WB_V7(cachesize) ? " WB" : "",
++ CACHE_WT_V7(cachesize) ? " WT" : "");
++}
++
+ static void __init dump_cpu_info(int cpu)
+ {
+ unsigned int info = read_cpuid(CPUID_CACHETYPE);
+
+- if (info != processor_id) {
++ if (info != processor_id && (info & (1 << 31))) {
++ /* ARMv7 style of cache info register */
++ unsigned int id = read_extended_cpuid(1,0,0,1);
++ unsigned int level = 0;
++ printk("CPU%u: L1 I %s cache. Caches unified at level %u, coherent at level %u\n",
++ cpu,
++ v7_cache_policy[CACHE_TYPE_V7(info)],
++ CACHE_UNIFIED(id),
++ CACHE_COHERENT(id));
++
++ while (id & CACHE_ID_LEVEL_MASK) {
++ printk("CPU%u: Level %u cache is %s\n",
++ cpu, (level >> 1)+1, v7_cache_type[id & CACHE_ID_LEVEL_MASK]);
++
++ if (id & 1) {
++ /* Dump I at this level */
++ dump_v7_cache("I", cpu, level | 1);
++ }
++
++ if (id & (4 | 2)) {
++ /* Dump D or unified at this level */
++ dump_v7_cache((id & 4) ? "unified" : "D", cpu, level);
++ }
++
++ /* Next level out */
++ level += 2;
++ id >>= CACHE_ID_LEVEL_BITS;
++ }
++ } else if (info != processor_id) {
+ printk("CPU%u: D %s %s cache\n", cpu, cache_is_vivt() ? "VIVT" : "VIPT",
+ cache_types[CACHE_TYPE(info)]);
+ if (CACHE_S(info)) {
+@@ -916,6 +996,30 @@ c_show_cache(struct seq_file *m, const char *type, unsigned int cache)
+ CACHE_LINE(cache)));
+ }
+
++static void c_show_v7_cache(struct seq_file *m, const char *type, unsigned int levelselect)
++{
++ unsigned int cachesize;
++ unsigned int level = (levelselect >> 1) + 1;
++
++ write_extended_cpuid(2,0,0,0,levelselect); /* Set the cache size selection register */
++ write_extended_cpuid(0,7,5,4,0); /* Prefetch flush to wait for above */
++ cachesize = read_extended_cpuid(1,0,0,0);
++
++ seq_printf(m, "L%u %s size\t\t: %d bytes\n"
++ "L%u %s assoc\t\t: %d\n"
++ "L%u %s line length\t: %d\n"
++ "L%u %s sets\t\t: %d\n"
++ "L%u %s supports\t\t:%s%s%s%s\n",
++ level, type, CACHE_SIZE_V7(cachesize),
++ level, type, CACHE_ASSOC_V7(cachesize),
++ level, type, CACHE_LINE_V7(cachesize),
++ level, type, CACHE_SETS_V7(cachesize),
++ level, type, CACHE_WA_V7(cachesize) ? " WA" : "",
++ CACHE_RA_V7(cachesize) ? " RA" : "",
++ CACHE_WB_V7(cachesize) ? " WB" : "",
++ CACHE_WT_V7(cachesize) ? " WT" : "");
++}
++
+ static int c_show(struct seq_file *m, void *v)
+ {
+ int i;
+@@ -971,7 +1075,36 @@ static int c_show(struct seq_file *m, void *v)
+
+ {
+ unsigned int cache_info = read_cpuid(CPUID_CACHETYPE);
+- if (cache_info != processor_id) {
++ if (cache_info != processor_id && (cache_info & (1<<31))) {
++ /* V7 style of cache info register */
++ unsigned int id = read_extended_cpuid(1,0,0,1);
++ unsigned int levelselect = 0;
++ seq_printf(m, "L1 I cache\t:%s\n"
++ "Cache unification level\t: %u\n"
++ "Cache coherency level\t: %u\n",
++ v7_cache_policy[CACHE_TYPE_V7(cache_info)],
++ CACHE_UNIFIED(id),
++ CACHE_COHERENT(id));
++
++ while (id & CACHE_ID_LEVEL_MASK) {
++ seq_printf(m, "Level %u cache\t\t: %s\n",
++ (levelselect >> 1)+1, v7_cache_type[id & CACHE_ID_LEVEL_MASK]);
++
++ if (id & 1) {
++ /* Dump I at this level */
++ c_show_v7_cache(m, "I", levelselect | 1);
++ }
++
++ if (id & (4 | 2)) {
++ /* Dump D or unified at this level */
++ c_show_v7_cache(m, (id & 4) ? "cache" : "D", levelselect);
++ }
++
++ /* Next level out */
++ levelselect += 2;
++ id >>= CACHE_ID_LEVEL_BITS;
++ }
++ } else if (cache_info != processor_id) {
+ seq_printf(m, "Cache type\t: %s\n"
+ "Cache clean\t: %s\n"
+ "Cache lockdown\t: %s\n"
+diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h
+index 514af79..704738e 100644
+--- a/arch/arm/include/asm/system.h
++++ b/arch/arm/include/asm/system.h
+@@ -74,6 +74,24 @@
+ : "cc"); \
+ __val; \
+ })
++#define read_extended_cpuid(op1,op2,op3,op4) \
++ ({ \
++ unsigned int __val; \
++ asm("mrc p15," __stringify(op1) ",%0,c" __stringify(op2)",c" __stringify(op3)"," __stringify(op4) \
++ : "=r" (__val) \
++ : \
++ : "cc"); \
++ __val; \
++ })
++
++#define write_extended_cpuid(op1,op2,op3,op4,v) \
++ ({ \
++ unsigned int __val = v; \
++ asm("mcr p15," __stringify(op1) ",%0,c" __stringify(op2)",c" __stringify(op3)"," __stringify(op4) \
++ : \
++ : "r" (__val) \
++ : "cc"); \
++ })
+ #else
+ extern unsigned int processor_id;
+ #define read_cpuid(reg) (processor_id)
+
+
+--
+Catalin
+
+
diff --git a/packages/linux/linux-omap/mru-clocks1.diff b/packages/linux/linux-omap/mru-clocks1.diff
new file mode 100644
index 0000000000..d7dadbc85e
--- /dev/null
+++ b/packages/linux/linux-omap/mru-clocks1.diff
@@ -0,0 +1,25 @@
+From: Mans Rullgard <mans@mansr.com>
+Date: Tue, 22 Jul 2008 00:31:11 +0000 (+0100)
+Subject: ARM: OMAP: make dpll4_m4_ck programmable with clk_set_rate()
+X-Git-Url: http://git.mansr.com/?p=linux-omap;a=commitdiff_plain;h=2b7b958dc79e51127d7a4ecf88ce12dbc6c31426
+
+ARM: OMAP: make dpll4_m4_ck programmable with clk_set_rate()
+
+Filling the set_rate and round_rate fields of dpll4_m4_ck makes
+this clock programmable through clk_set_rate(). This is needed
+to give omapfb control over the dss1_alwon_fck rate.
+---
+
+diff --git a/arch/arm/mach-omap2/clock34xx.h b/arch/arm/mach-omap2/clock34xx.h
+index 161da12..876eb13 100644
+--- a/arch/arm/mach-omap2/clock34xx.h
++++ b/arch/arm/mach-omap2/clock34xx.h
+@@ -815,6 +815,8 @@ static struct clk dpll4_m4_ck = {
+ .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES |
+ PARENT_CONTROLS_CLOCK,
+ .recalc = &omap2_clksel_recalc,
++ .set_rate = &omap2_clksel_set_rate,
++ .round_rate = &omap2_clksel_round_rate,
+ };
+
+ /* The PWRDN bit is apparently only available on 3430ES2 and above */
diff --git a/packages/linux/linux-omap/mru-clocks2.diff b/packages/linux/linux-omap/mru-clocks2.diff
new file mode 100644
index 0000000000..c8b370da03
--- /dev/null
+++ b/packages/linux/linux-omap/mru-clocks2.diff
@@ -0,0 +1,62 @@
+From: Mans Rullgard <mans@mansr.com>
+Date: Tue, 22 Jul 2008 00:58:18 +0000 (+0100)
+Subject: ARM: OMAP: add clk_get_parent() for OMAP2/3
+X-Git-Url: http://git.mansr.com/?p=linux-omap;a=commitdiff_plain;h=e2de5e5578fbaa9b4b75074796da0608fc93e6ae
+
+ARM: OMAP: add clk_get_parent() for OMAP2/3
+
+Signed-off-by: Mans Rullgard <mans@mansr.com>
+---
+
+diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c
+index 577be44..28aec36 100644
+--- a/arch/arm/mach-omap2/clock.c
++++ b/arch/arm/mach-omap2/clock.c
+@@ -824,6 +824,11 @@ int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent)
+ return 0;
+ }
+
++struct clk *omap2_clk_get_parent(struct clk *clk)
++{
++ return clk->parent;
++}
++
+ /* DPLL rate rounding code */
+
+ /**
+diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h
+index 49245f7..4aa69d5 100644
+--- a/arch/arm/mach-omap2/clock.h
++++ b/arch/arm/mach-omap2/clock.h
+@@ -29,6 +29,7 @@ int omap2_clk_set_rate(struct clk *clk, unsigned long rate);
+ int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent);
+ int omap2_dpll_set_rate_tolerance(struct clk *clk, unsigned int tolerance);
+ long omap2_dpll_round_rate(struct clk *clk, unsigned long target_rate);
++struct clk *omap2_clk_get_parent(struct clk *clk);
+
+ #ifdef CONFIG_OMAP_RESET_CLOCKS
+ void omap2_clk_disable_unused(struct clk *clk);
+diff --git a/arch/arm/mach-omap2/clock24xx.c b/arch/arm/mach-omap2/clock24xx.c
+index 54cc6e1..ed7af21 100644
+--- a/arch/arm/mach-omap2/clock24xx.c
++++ b/arch/arm/mach-omap2/clock24xx.c
+@@ -422,6 +422,7 @@ static struct clk_functions omap2_clk_functions = {
+ .clk_round_rate = omap2_clk_round_rate,
+ .clk_set_rate = omap2_clk_set_rate,
+ .clk_set_parent = omap2_clk_set_parent,
++ .clk_get_parent = omap2_clk_get_parent,
+ .clk_disable_unused = omap2_clk_disable_unused,
+ #ifdef CONFIG_CPU_FREQ
+ .clk_init_cpufreq_table = omap2_clk_init_cpufreq_table,
+diff --git a/arch/arm/mach-omap2/clock34xx.c b/arch/arm/mach-omap2/clock34xx.c
+index 04dedec..08c8c46 100644
+--- a/arch/arm/mach-omap2/clock34xx.c
++++ b/arch/arm/mach-omap2/clock34xx.c
+@@ -541,6 +541,7 @@ static struct clk_functions omap2_clk_functions = {
+ .clk_round_rate = omap2_clk_round_rate,
+ .clk_set_rate = omap2_clk_set_rate,
+ .clk_set_parent = omap2_clk_set_parent,
++ .clk_get_parent = omap2_clk_get_parent,
+ .clk_disable_unused = omap2_clk_disable_unused,
+ };
+
diff --git a/packages/linux/linux-omap/mru-clocks3.diff b/packages/linux/linux-omap/mru-clocks3.diff
new file mode 100644
index 0000000000..f8407fc2d5
--- /dev/null
+++ b/packages/linux/linux-omap/mru-clocks3.diff
@@ -0,0 +1,94 @@
+From: Mans Rullgard <mans@mansr.com>
+Date: Wed, 23 Jul 2008 08:40:07 +0000 (+0100)
+Subject: ARM: OMAP: Set DSS1_ALWON_FCLK to a multiple of the pixel clock
+X-Git-Url: http://git.mansr.com/?p=linux-omap;a=commitdiff_plain;h=01ee28c50701caa94739e764c3dae9298edd8216
+
+ARM: OMAP: Set DSS1_ALWON_FCLK to a multiple of the pixel clock
+
+This sets the DSS1_ALWON_FCLK clock as close as possible to a
+multiple of the requested pixel clock, while keeping it below
+the 173MHz limit.
+
+Due to of the structure of the clock tree, dss1_alwon_fck cannot
+be set directly, and we must use dpll4_m4_ck instead.
+
+Signed-off-by: Mans Rullgard <mans@mansr.com>
+---
+
+diff --git a/drivers/video/omap/dispc.c b/drivers/video/omap/dispc.c
+index fd06ca2..e0e8528 100644
+--- a/drivers/video/omap/dispc.c
++++ b/drivers/video/omap/dispc.c
+@@ -176,6 +176,7 @@ static struct {
+
+ struct clk *dss_ick, *dss1_fck;
+ struct clk *dss_54m_fck;
++ struct clk *dpll4_m4_ck;
+
+ enum omapfb_update_mode update_mode;
+ struct omapfb_device *fbdev;
+@@ -738,21 +739,34 @@ static void setup_color_conv_coef(void)
+ MOD_REG_FLD(at2_reg, (1 << 11), ct->full_range);
+ }
+
+-#define MAX_FCK_LCD 173000000
++#define MAX_FCK 173000000
+
+ static void calc_ck_div(int is_tft, int pck, int *lck_div, int *pck_div)
+ {
++ unsigned long prate = clk_get_rate(clk_get_parent(dispc.dpll4_m4_ck));
++ unsigned long pcd_min = is_tft? 2: 3;
++ unsigned long fck_div;
+ unsigned long fck, lck;
+
+ pck = max(1, pck);
++
++ if (pck * pcd_min > MAX_FCK) {
++ dev_warn(dispc.fbdev->dev, "pixclock %d kHz too high.\n",
++ pck / 1000);
++ pck = MAX_FCK / pcd_min;
++ }
++
++ fck = pck * 2;
++ fck_div = (prate + pck) / fck;
++ if (fck_div > 16)
++ fck_div /= (fck_div + 15) / 16;
++ if (fck_div < 1)
++ fck_div = 1;
++ clk_set_rate(dispc.dpll4_m4_ck, prate / fck_div);
+ fck = clk_get_rate(dispc.dss1_fck);
+- *lck_div = (fck + MAX_FCK_LCD - 1) / MAX_FCK_LCD;
+- lck = fck / *lck_div;
+- *pck_div = (lck + pck - 1) / pck;
+- if (is_tft)
+- *pck_div = max(2, *pck_div);
+- else
+- *pck_div = max(3, *pck_div);
++
++ *lck_div = 1;
++ *pck_div = (fck + pck - 1) / pck;
+ if (*pck_div > 255) {
+ *pck_div = 255;
+ lck = pck * *pck_div;
+@@ -914,11 +928,21 @@ static int get_dss_clocks(void)
+ return PTR_ERR(dispc.dss_54m_fck);
+ }
+
++ if (IS_ERR((dispc.dpll4_m4_ck =
++ clk_get(dispc.fbdev->dev, "dpll4_m4_ck")))) {
++ dev_err(dispc.fbdev->dev, "can't get dpll4_m4_ck");
++ clk_put(dispc.dss_ick);
++ clk_put(dispc.dss1_fck);
++ clk_put(dispc.dss_54m_fck);
++ return PTR_ERR(dispc.dss_54m_fck);
++ }
++
+ return 0;
+ }
+
+ static void put_dss_clocks(void)
+ {
++ clk_put(dispc.dpll4_m4_ck);
+ clk_put(dispc.dss_54m_fck);
+ clk_put(dispc.dss1_fck);
+ clk_put(dispc.dss_ick);
diff --git a/packages/linux/linux-omap/musb-dmafix.patch b/packages/linux/linux-omap/musb-dmafix.patch
new file mode 100644
index 0000000000..259b79be59
--- /dev/null
+++ b/packages/linux/linux-omap/musb-dmafix.patch
@@ -0,0 +1,275 @@
+From: Gadiyar, Anand <gadiyar@ti.com>
+Date: Wed, 13 Aug 2008 07:05:29 +0000 (+0530)
+Subject: MUSB: Workaround for simultaneous TX and RX usage
+X-Git-Url: http://git.mansr.com/?p=linux-omap;a=commitdiff_plain;h=2e6aa4efb0e14c51ff0427927b1b38136911fa93
+
+MUSB: Workaround for simultaneous TX and RX usage
+
+MUSB: Workaround for simultaneous TX and RX usage
+
+MUSB RTL V1.4 has a hardware issue which results in a DMA controller
+hang when TX and RX DMA channels are simultaneously enabled. This
+affects at least OMAP2430 and OMAP34XX.
+
+Since RX transfers are in Mode 0 and anyway result in one DMA interrupt
+per packet, we can use System DMA to unload the RX fifos. MUSB DMA can
+be used for all TX channels as before.
+
+Tested with full-duplex TX and RX transfers using g_ether. Runs for 24
+hours without a hang. Without this patch, the hang occurs within minutes.
+
+This issue was first reported by Jon Hunter on [1]
+
+[1] http://marc.info/?l=linux-omap&m=119634480534453&w=2
+
+Signed-off-by: Anand Gadiyar <gadiyar@ti.com>
+---
+
+diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig
+index a485a86..8583e54 100644
+--- a/drivers/usb/musb/Kconfig
++++ b/drivers/usb/musb/Kconfig
+@@ -150,6 +150,14 @@ config USB_INVENTRA_DMA
+ help
+ Enable DMA transfers using Mentor's engine.
+
++config MUSB_USE_SYSTEM_DMA_RX
++ bool 'Use System DMA for RX endpoints'
++ depends on USB_MUSB_HDRC && USB_INVENTRA_DMA
++ help
++ MUSB RTL version 1.4 has a hardware issue when TX and RX DMA
++ channels are simultaneously enabled. To work around this issue,
++ you can choose to use System DMA for RX channels.
++
+ config USB_TI_CPPI_DMA
+ bool
+ depends on USB_MUSB_HDRC && !MUSB_PIO_ONLY
+diff --git a/drivers/usb/musb/musbhsdma.c b/drivers/usb/musb/musbhsdma.c
+index 32bb1e2..d1c1ea0 100644
+--- a/drivers/usb/musb/musbhsdma.c
++++ b/drivers/usb/musb/musbhsdma.c
+@@ -34,6 +34,7 @@
+ #include <linux/interrupt.h>
+ #include <linux/platform_device.h>
+ #include "musb_core.h"
++#include <asm/dma.h>
+
+ #if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3430)
+ #include "omap2430.h"
+@@ -64,6 +65,9 @@
+
+ #define MUSB_HSDMA_CHANNELS 8
+
++#define MUSB_FIFO_ADDRESS(epnum) \
++ ((unsigned long) (OMAP_HSOTG_BASE + MUSB_FIFO_OFFSET(epnum)))
++
+ struct musb_dma_controller;
+
+ struct musb_dma_channel {
+@@ -75,6 +79,8 @@ struct musb_dma_channel {
+ u8 bIndex;
+ u8 epnum;
+ u8 transmit;
++
++ int sysdma_channel;
+ };
+
+ struct musb_dma_controller {
+@@ -93,6 +99,42 @@ static int dma_controller_start(struct dma_controller *c)
+ return 0;
+ }
+
++#ifdef CONFIG_MUSB_USE_SYSTEM_DMA_RX
++static void musb_sysdma_completion(int lch, u16 ch_status, void *data)
++{
++ u32 dwAddress;
++ unsigned long flags;
++
++ struct dma_channel *pChannel;
++
++ struct musb_dma_channel *pImplChannel =
++ (struct musb_dma_channel *) data;
++ struct musb_dma_controller *controller = pImplChannel->controller;
++ struct musb *musb = controller->pDmaPrivate;
++ pChannel = &pImplChannel->Channel;
++
++ DBG(2, "lch = 0x%d, ch_status = 0x%x\n", lch, ch_status);
++ spin_lock_irqsave(&musb->lock, flags);
++
++ dwAddress = (u32) omap_get_dma_dst_pos(pImplChannel->sysdma_channel);
++ pChannel->actual_len = dwAddress - pImplChannel->dwStartAddress;
++
++ DBG(2, "ch %p, 0x%x -> 0x%x (%d / %d) %s\n",
++ pChannel, pImplChannel->dwStartAddress, dwAddress,
++ pChannel->actual_len, pImplChannel->len,
++ (pChannel->actual_len < pImplChannel->len) ?
++ "=> reconfig 0": "=> complete");
++
++ pChannel->status = MUSB_DMA_STATUS_FREE;
++ musb_dma_completion(musb, pImplChannel->epnum, pImplChannel->transmit);
++
++ spin_unlock_irqrestore(&musb->lock, flags);
++ return;
++}
++#else
++#define musb_sysdma_completion NULL
++#endif
++
+ static void dma_channel_release(struct dma_channel *pChannel);
+
+ static int dma_controller_stop(struct dma_controller *c)
+@@ -144,6 +186,29 @@ static struct dma_channel *dma_channel_allocate(struct dma_controller *c,
+ /* Tx => mode 1; Rx => mode 0 */
+ pChannel->desired_mode = transmit;
+ pChannel->actual_len = 0;
++ pImplChannel->sysdma_channel = -1;
++
++#ifdef CONFIG_MUSB_USE_SYSTEM_DMA_RX
++ if (!transmit) {
++ int ret;
++ ret = omap_request_dma(OMAP24XX_DMA_NO_DEVICE,
++ "MUSB SysDMA", musb_sysdma_completion,
++ (void *) pImplChannel,
++ &(pImplChannel->sysdma_channel));
++
++ if (ret) {
++ printk(KERN_ERR "request_dma failed:"
++ " %d\n", ret);
++ controller->bmUsedChannels &=
++ ~(1 << bBit);
++ pChannel->status =
++ MUSB_DMA_STATUS_UNKNOWN;
++ pImplChannel->sysdma_channel = -1;
++ pChannel = NULL;
++ }
++ }
++#endif
++
+ break;
+ }
+ }
+@@ -163,6 +228,12 @@ static void dma_channel_release(struct dma_channel *pChannel)
+ ~(1 << pImplChannel->bIndex);
+
+ pChannel->status = MUSB_DMA_STATUS_UNKNOWN;
++
++ if (pImplChannel->sysdma_channel != -1) {
++ omap_stop_dma(pImplChannel->sysdma_channel);
++ omap_free_dma(pImplChannel->sysdma_channel);
++ pImplChannel->sysdma_channel = -1;
++ }
+ }
+
+ static void configure_channel(struct dma_channel *pChannel,
+@@ -179,41 +250,69 @@ static void configure_channel(struct dma_channel *pChannel,
+ DBG(4, "%p, pkt_sz %d, addr 0x%x, len %d, mode %d\n",
+ pChannel, packet_sz, dma_addr, len, mode);
+
+- if (mode) {
+- csr |= 1 << MUSB_HSDMA_MODE1_SHIFT;
+- BUG_ON(len < packet_sz);
++ if (pImplChannel->sysdma_channel != -1) {
++ /* System DMA */
++ /* RX: set src = FIFO */
++
++ omap_set_dma_transfer_params(pImplChannel->sysdma_channel,
++ OMAP_DMA_DATA_TYPE_S8,
++ len, 1, /* One frame */
++ OMAP_DMA_SYNC_ELEMENT,
++ OMAP24XX_DMA_NO_DEVICE,
++ 0); /* Src Sync */
++
++ omap_set_dma_src_params(pImplChannel->sysdma_channel, 0,
++ OMAP_DMA_AMODE_CONSTANT,
++ MUSB_FIFO_ADDRESS(pImplChannel->epnum),
++ 0, 0);
+
+- if (packet_sz >= 64) {
+- csr |= MUSB_HSDMA_BURSTMODE_INCR16
++ omap_set_dma_dest_params(pImplChannel->sysdma_channel, 0,
++ OMAP_DMA_AMODE_POST_INC, dma_addr,
++ 0, 0);
++
++ omap_set_dma_dest_data_pack(pImplChannel->sysdma_channel, 1);
++ omap_set_dma_dest_burst_mode(pImplChannel->sysdma_channel,
++ OMAP_DMA_DATA_BURST_16);
++
++ omap_start_dma(pImplChannel->sysdma_channel);
++
++ } else { /* Mentor DMA */
++ if (mode) {
++ csr |= 1 << MUSB_HSDMA_MODE1_SHIFT;
++ BUG_ON(len < packet_sz);
++
++ if (packet_sz >= 64) {
++ csr |= MUSB_HSDMA_BURSTMODE_INCR16
+ << MUSB_HSDMA_BURSTMODE_SHIFT;
+- } else if (packet_sz >= 32) {
+- csr |= MUSB_HSDMA_BURSTMODE_INCR8
++ } else if (packet_sz >= 32) {
++ csr |= MUSB_HSDMA_BURSTMODE_INCR8
+ << MUSB_HSDMA_BURSTMODE_SHIFT;
+- } else if (packet_sz >= 16) {
+- csr |= MUSB_HSDMA_BURSTMODE_INCR4
++ } else if (packet_sz >= 16) {
++ csr |= MUSB_HSDMA_BURSTMODE_INCR4
+ << MUSB_HSDMA_BURSTMODE_SHIFT;
++ }
+ }
+- }
+
+- csr |= (pImplChannel->epnum << MUSB_HSDMA_ENDPOINT_SHIFT)
+- | (1 << MUSB_HSDMA_ENABLE_SHIFT)
+- | (1 << MUSB_HSDMA_IRQENABLE_SHIFT)
+- | (pImplChannel->transmit
+- ? (1 << MUSB_HSDMA_TRANSMIT_SHIFT)
+- : 0);
+-
+- /* address/count */
+- musb_writel(mbase,
+- MUSB_HSDMA_CHANNEL_OFFSET(bChannel, MUSB_HSDMA_ADDRESS),
+- dma_addr);
+- musb_writel(mbase,
+- MUSB_HSDMA_CHANNEL_OFFSET(bChannel, MUSB_HSDMA_COUNT),
+- len);
+-
+- /* control (this should start things) */
+- musb_writew(mbase,
+- MUSB_HSDMA_CHANNEL_OFFSET(bChannel, MUSB_HSDMA_CONTROL),
+- csr);
++ csr |= (pImplChannel->epnum << MUSB_HSDMA_ENDPOINT_SHIFT)
++ | (1 << MUSB_HSDMA_ENABLE_SHIFT)
++ | (1 << MUSB_HSDMA_IRQENABLE_SHIFT)
++ | (pImplChannel->transmit
++ ? (1 << MUSB_HSDMA_TRANSMIT_SHIFT)
++ : 0);
++
++ /* address/count */
++ musb_writel(mbase,
++ MUSB_HSDMA_CHANNEL_OFFSET(bChannel, MUSB_HSDMA_ADDRESS),
++ dma_addr);
++ musb_writel(mbase,
++ MUSB_HSDMA_CHANNEL_OFFSET(bChannel, MUSB_HSDMA_COUNT),
++ len);
++
++ /* control (this should start things) */
++ musb_writew(mbase,
++ MUSB_HSDMA_CHANNEL_OFFSET(bChannel, MUSB_HSDMA_CONTROL),
++ csr);
++ } /* Mentor DMA */
+ }
+
+ static int dma_channel_program(struct dma_channel *pChannel,
+@@ -265,6 +364,12 @@ static int dma_channel_abort(struct dma_channel *pChannel)
+ MUSB_EP_OFFSET(pImplChannel->epnum, MUSB_TXCSR),
+ csr);
+ } else {
++ if (pImplChannel->sysdma_channel != -1) {
++ omap_stop_dma(pImplChannel->sysdma_channel);
++ omap_free_dma(pImplChannel->sysdma_channel);
++ pImplChannel->sysdma_channel = -1;
++ }
++
+ csr = musb_readw(mbase,
+ MUSB_EP_OFFSET(pImplChannel->epnum, MUSB_RXCSR));
+ csr &= ~(MUSB_RXCSR_AUTOCLEAR |
diff --git a/packages/linux/linux-omap/no-cortex-deadlock.patch b/packages/linux/linux-omap/no-cortex-deadlock.patch
new file mode 100644
index 0000000000..5bb6d22484
--- /dev/null
+++ b/packages/linux/linux-omap/no-cortex-deadlock.patch
@@ -0,0 +1,75 @@
+From: Mans Rullgard <mans@mansr.com>
+Date: Wed, 30 Jul 2008 08:25:51 +0000 (+0100)
+Subject: ARM: NEON L1 cache bug workaround (erratum 451034)
+X-Git-Url: http://git.mansr.com/?p=linux-omap;a=commitdiff_plain;h=26023493baf13e0a67fd6cf08d87be5ff6f7c56d
+
+ARM: NEON L1 cache bug workaround (erratum 451034)
+
+On Cortex-A8 r1p0 and r1p1, executing a NEON store with an integer
+store in the store buffer, can cause a processor deadlock under
+certain conditions.
+
+Executing a DMB instruction before saving NEON/VFP registers and before
+return to userspace makes it safe to run code which includes similar
+counter-measures. Userspace code can still trigger the deadlock, so
+a different workaround is required to safely run untrusted code.
+
+See ARM Cortex-A8 Errata Notice (PR120-PRDC-008070) for full details.
+---
+
+diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
+index 8c75840..1172e14 100644
+--- a/arch/arm/Kconfig
++++ b/arch/arm/Kconfig
+@@ -1071,6 +1071,22 @@ config NEON
+ Say Y to include support code for NEON, the ARMv7 Advanced SIMD
+ Extension.
+
++config NEON_CACHE_BUG
++ bool "NEON L1 cache bug workaround (erratum 451034)"
++ depends on VFPv3
++ help
++ On Cortex-A8 r1p0 and r1p1, executing a NEON store with an integer
++ store in the store buffer, can cause a processor deadlock under
++ certain conditions.
++
++ See ARM Cortex-A8 Errata Notice (PR120-PRDC-008070) for full details.
++
++ Say Y to include a workaround.
++
++ WARNING: Even with this option enabled, userspace code can trigger
++ the deadlock. To safely run untrusted code, a different fix is
++ required.
++
+ endmenu
+
+ menu "Userspace binary formats"
+diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
+index 597ed00..e50094e 100644
+--- a/arch/arm/kernel/entry-common.S
++++ b/arch/arm/kernel/entry-common.S
+@@ -68,6 +68,10 @@ no_work_pending:
+ /* perform architecture specific actions before user return */
+ arch_ret_to_user r1, lr
+
++#ifdef CONFIG_NEON_CACHE_BUG
++ dmb
++#endif
++
+ @ slow_restore_user_regs
+ ldr r1, [sp, #S_PSR] @ get calling cpsr
+ ldr lr, [sp, #S_PC]! @ get pc
+diff --git a/arch/arm/include/asm/vfpmacros.h b/arch/arm/include/asm/vfpmacros.h
+index cccb389..c9d2976 100644
+--- a/arch/arm/include/asm/vfpmacros.h
++++ b/arch/arm/include/asm/vfpmacros.h
+@@ -32,6 +32,9 @@
+
+ @ write all the working registers out of the VFP
+ .macro VFPFSTMIA, base, tmp
++#ifdef CONFIG_NEON_CACHE_BUG
++ dmb
++#endif
+ #if __LINUX_ARM_ARCH__ < 6
+ STC p11, cr0, [\base],#33*4 @ FSTMIAX \base!, {d0-d15}
+ #else
diff --git a/packages/linux/linux-omap/no-empty-flash-warnings.patch b/packages/linux/linux-omap/no-empty-flash-warnings.patch
new file mode 100644
index 0000000000..ab344b0449
--- /dev/null
+++ b/packages/linux/linux-omap/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-omap/no-harry-potter.diff b/packages/linux/linux-omap/no-harry-potter.diff
new file mode 100644
index 0000000000..2bb20ab9c0
--- /dev/null
+++ b/packages/linux/linux-omap/no-harry-potter.diff
@@ -0,0 +1,11 @@
+--- /tmp/Makefile 2008-04-24 14:36:20.509598016 +0200
++++ git/arch/arm/Makefile 2008-04-24 14:36:31.949546584 +0200
+@@ -47,7 +47,7 @@
+ # Note that GCC does not numerically define an architecture version
+ # macro, but instead defines a whole series of macros which makes
+ # testing for a specific architecture or later rather impossible.
+-arch-$(CONFIG_CPU_32v7) :=-D__LINUX_ARM_ARCH__=7 $(call cc-option,-march=armv7a,-march=armv5t -Wa$(comma)-march=armv7a)
++arch-$(CONFIG_CPU_32v7) :=-D__LINUX_ARM_ARCH__=7 $(call cc-option,-march=armv7-a,-march=armv5t -Wa$(comma)-march=armv7-a)
+ arch-$(CONFIG_CPU_32v6) :=-D__LINUX_ARM_ARCH__=6 $(call cc-option,-march=armv6,-march=armv5t -Wa$(comma)-march=armv6)
+ # Only override the compiler option if ARMv6. The ARMv6K extensions are
+ # always available in ARMv7
diff --git a/packages/linux/linux-omap/omap-2430-lcd.patch b/packages/linux/linux-omap/omap-2430-lcd.patch
new file mode 100644
index 0000000000..8f8a687c06
--- /dev/null
+++ b/packages/linux/linux-omap/omap-2430-lcd.patch
@@ -0,0 +1,11 @@
+--- git/drivers/video/omap/lcd_2430sdp.c.orig 2007-08-13 14:35:17.000000000 -0700
++++ git/drivers/video/omap/lcd_2430sdp.c 2007-08-13 14:35:55.000000000 -0700
+@@ -32,7 +32,7 @@
+ #define LCD_PANEL_BACKLIGHT_GPIO 91
+ #define LCD_PANEL_ENABLE_GPIO 154
+ #define LCD_PIXCLOCK_MAX 5400 /* freq 5.4 MHz */
+-#define PM_RECEIVER TWL4030_MODULE_PM_RECIEVER
++#define PM_RECEIVER TWL4030_MODULE_PM_RECEIVER
+ #define ENABLE_VAUX2_DEDICATED 0x09
+ #define ENABLE_VAUX2_DEV_GRP 0x20
+
diff --git a/packages/linux/linux-omap/omap1710h3/.mtn2git_empty b/packages/linux/linux-omap/omap1710h3/.mtn2git_empty
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/packages/linux/linux-omap/omap1710h3/.mtn2git_empty
diff --git a/packages/linux/linux-omap/omap2420h4/.mtn2git_empty b/packages/linux/linux-omap/omap2420h4/.mtn2git_empty
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/packages/linux/linux-omap/omap2420h4/.mtn2git_empty
diff --git a/packages/linux/linux-omap/omap2430sdp/.mtn2git_empty b/packages/linux/linux-omap/omap2430sdp/.mtn2git_empty
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/packages/linux/linux-omap/omap2430sdp/.mtn2git_empty
diff --git a/packages/linux/linux-omap/omap3evm/.mtn2git_empty b/packages/linux/linux-omap/omap3evm/.mtn2git_empty
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/packages/linux/linux-omap/omap3evm/.mtn2git_empty
diff --git a/packages/linux/linux-omap/omap5912osk/.mtn2git_empty b/packages/linux/linux-omap/omap5912osk/.mtn2git_empty
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/packages/linux/linux-omap/omap5912osk/.mtn2git_empty
diff --git a/packages/linux/linux-omap/oprofile-0.9.3.armv7.diff b/packages/linux/linux-omap/oprofile-0.9.3.armv7.diff
new file mode 100644
index 0000000000..02dc079095
--- /dev/null
+++ b/packages/linux/linux-omap/oprofile-0.9.3.armv7.diff
@@ -0,0 +1,612 @@
+Hi,
+
+This patch adds Oprofile support on ARMv7, using the PMNC unit.
+Tested on OMAP3430 SDP.
+
+Feedback and comments are welcome.
+
+The patch to user space components is attached for reference. It i applies
+against version 0.9.3 of oprofile source
+(http://prdownloads.sourceforge.net/oprofile/oprofile-0.9.3.tar.gz).
+
+Regards,
+Jean.
+
+---
+
+From: Jean Pihet <jpihet@mvista.com>
+Date: Tue, 6 May 2008 17:21:44 +0200
+Subject: [PATCH] ARM: Add ARMv7 oprofile support
+
+Add ARMv7 Oprofile support to kernel
+
+Signed-off-by: Jean Pihet <jpihet@mvista.com>
+---
+
+diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
+index c60a27d..60b50a0 100644
+--- a/arch/arm/Kconfig
++++ b/arch/arm/Kconfig
+@@ -161,6 +161,11 @@ config OPROFILE_MPCORE
+ config OPROFILE_ARM11_CORE
+ bool
+
++config OPROFILE_ARMV7
++ def_bool y
++ depends on CPU_V7 && !SMP
++ bool
++
+ endif
+
+ config VECTORS_BASE
+diff --git a/arch/arm/oprofile/Makefile b/arch/arm/oprofile/Makefile
+index e61d0cc..88e31f5 100644
+--- a/arch/arm/oprofile/Makefile
++++ b/arch/arm/oprofile/Makefile
+@@ -11,3 +11,4 @@ oprofile-$(CONFIG_CPU_XSCALE) += op_model_xscale.o
+ oprofile-$(CONFIG_OPROFILE_ARM11_CORE) += op_model_arm11_core.o
+ oprofile-$(CONFIG_OPROFILE_ARMV6) += op_model_v6.o
+ oprofile-$(CONFIG_OPROFILE_MPCORE) += op_model_mpcore.o
++oprofile-$(CONFIG_OPROFILE_ARMV7) += op_model_v7.o
+diff --git a/arch/arm/oprofile/common.c b/arch/arm/oprofile/common.c
+index 0a5cf3a..3fcd752 100644
+--- a/arch/arm/oprofile/common.c
++++ b/arch/arm/oprofile/common.c
+@@ -145,6 +145,10 @@ int __init oprofile_arch_init(struct oprofile_operations *ops)
+ spec = &op_mpcore_spec;
+ #endif
+
++#ifdef CONFIG_OPROFILE_ARMV7
++ spec = &op_armv7_spec;
++#endif
++
+ if (spec) {
+ ret = spec->init();
+ if (ret < 0)
+diff --git a/arch/arm/oprofile/op_arm_model.h
+b/arch/arm/oprofile/op_arm_model.h
+index 4899c62..8c4e4f6 100644
+--- a/arch/arm/oprofile/op_arm_model.h
++++ b/arch/arm/oprofile/op_arm_model.h
+@@ -26,6 +26,7 @@ extern struct op_arm_model_spec op_xscale_spec;
+
+ extern struct op_arm_model_spec op_armv6_spec;
+ extern struct op_arm_model_spec op_mpcore_spec;
++extern struct op_arm_model_spec op_armv7_spec;
+
+ extern void arm_backtrace(struct pt_regs * const regs, unsigned int depth);
+
+diff --git a/arch/arm/oprofile/op_model_v7.c b/arch/arm/oprofile/op_model_v7.c
+new file mode 100644
+index 0000000..a159bc1
+--- /dev/null
++++ b/arch/arm/oprofile/op_model_v7.c
+@@ -0,0 +1,407 @@
++/**
++ * @file op_model_v7.c
++ * ARM V7 (Cortex A8) Event Monitor Driver
++ *
++ * @remark Copyright 2008 Jean Pihet <jpihet@mvista.com>
++ * @remark Copyright 2004 ARM SMP Development Team
++ */
++#include <linux/types.h>
++#include <linux/errno.h>
++#include <linux/oprofile.h>
++#include <linux/interrupt.h>
++#include <linux/irq.h>
++#include <linux/smp.h>
++
++#include "op_counter.h"
++#include "op_arm_model.h"
++#include "op_model_v7.h"
++
++/* #define DEBUG */
++
++
++/*
++ * ARM V7 PMNC support
++ */
++
++static u32 cnt_en[CNTMAX];
++
++static inline void armv7_pmnc_write(u32 val)
++{
++ val &= PMNC_MASK;
++ asm volatile("mcr p15, 0, %0, c9, c12, 0" : : "r" (val));
++}
++
++static inline u32 armv7_pmnc_read(void)
++{
++ u32 val;
++
++ asm volatile("mrc p15, 0, %0, c9, c12, 0" : "=r" (val));
++ return val;
++}
++
++static inline u32 armv7_pmnc_enable_counter(unsigned int cnt)
++{
++ u32 val;
++
++ if (cnt >= CNTMAX) {
++ printk(KERN_ERR "oprofile: CPU%u enabling wrong PMNC counter"
++ " %d\n", smp_processor_id(), cnt);
++ return -1;
++ }
++
++ if (cnt == CCNT)
++ val = CNTENS_C;
++ else
++ val = (1 << (cnt - CNT0));
++
++ val &= CNTENS_MASK;
++ asm volatile("mcr p15, 0, %0, c9, c12, 1" : : "r" (val));
++
++ return cnt;
++}
++
++static inline u32 armv7_pmnc_disable_counter(unsigned int cnt)
++{
++ u32 val;
++
++ if (cnt >= CNTMAX) {
++ printk(KERN_ERR "oprofile: CPU%u disabling wrong PMNC counter"
++ " %d\n", smp_processor_id(), cnt);
++ return -1;
++ }
++
++ if (cnt == CCNT)
++ val = CNTENC_C;
++ else
++ val = (1 << (cnt - CNT0));
++
++ val &= CNTENC_MASK;
++ asm volatile("mcr p15, 0, %0, c9, c12, 2" : : "r" (val));
++
++ return cnt;
++}
++
++static inline u32 armv7_pmnc_enable_intens(unsigned int cnt)
++{
++ u32 val;
++
++ if (cnt >= CNTMAX) {
++ printk(KERN_ERR "oprofile: CPU%u enabling wrong PMNC counter"
++ " interrupt enable %d\n", smp_processor_id(), cnt);
++ return -1;
++ }
++
++ if (cnt == CCNT)
++ val = INTENS_C;
++ else
++ val = (1 << (cnt - CNT0));
++
++ val &= INTENS_MASK;
++ asm volatile("mcr p15, 0, %0, c9, c14, 1" : : "r" (val));
++
++ return cnt;
++}
++
++static inline u32 armv7_pmnc_getreset_flags(void)
++{
++ u32 val;
++
++ /* Read */
++ asm volatile("mrc p15, 0, %0, c9, c12, 3" : "=r" (val));
++
++ /* Write to clear flags */
++ val &= FLAG_MASK;
++ asm volatile("mcr p15, 0, %0, c9, c12, 3" : : "r" (val));
++
++ return val;
++}
++
++static inline int armv7_pmnc_select_counter(unsigned int cnt)
++{
++ u32 val;
++
++ if ((cnt == CCNT) || (cnt >= CNTMAX)) {
++ printk(KERN_ERR "oprofile: CPU%u selecting wrong PMNC counteri"
++ " %d\n", smp_processor_id(), cnt);
++ return -1;
++ }
++
++ val = (cnt - CNT0) & SELECT_MASK;
++ asm volatile("mcr p15, 0, %0, c9, c12, 5" : : "r" (val));
++
++ return cnt;
++}
++
++static inline void armv7_pmnc_write_evtsel(unsigned int cnt, u32 val)
++{
++ if (armv7_pmnc_select_counter(cnt) == cnt) {
++ val &= EVTSEL_MASK;
++ asm volatile("mcr p15, 0, %0, c9, c13, 1" : : "r" (val));
++ }
++}
++
++static void armv7_pmnc_reset_counter(unsigned int cnt)
++{
++ u32 cpu_cnt = CPU_COUNTER(smp_processor_id(), cnt);
++ u32 val = -(u32)counter_config[cpu_cnt].count;
++
++ switch (cnt) {
++ case CCNT:
++ armv7_pmnc_disable_counter(cnt);
++
++ asm volatile("mcr p15, 0, %0, c9, c13, 0" : : "r" (val));
++
++ if (cnt_en[cnt] != 0)
++ armv7_pmnc_enable_counter(cnt);
++
++ break;
++
++ case CNT0:
++ case CNT1:
++ case CNT2:
++ case CNT3:
++ armv7_pmnc_disable_counter(cnt);
++
++ if (armv7_pmnc_select_counter(cnt) == cnt)
++ asm volatile("mcr p15, 0, %0, c9, c13, 2" : : "r" (val));
++
++ if (cnt_en[cnt] != 0)
++ armv7_pmnc_enable_counter(cnt);
++
++ break;
++
++ default:
++ printk(KERN_ERR "oprofile: CPU%u resetting wrong PMNC counter"
++ " %d\n", smp_processor_id(), cnt);
++ break;
++ }
++}
++
++int armv7_setup_pmnc(void)
++{
++ unsigned int cnt;
++
++ if (armv7_pmnc_read() & PMNC_E) {
++ printk(KERN_ERR "oprofile: CPU%u PMNC still enabled when setup"
++ " new event counter.\n", smp_processor_id());
++ return -EBUSY;
++ }
++
++ /*
++ * Initialize & Reset PMNC: C bit, D bit and P bit.
++ * Note: Using a slower count for CCNT (D bit: divide by 64) results
++ * in a more stable system
++ */
++ armv7_pmnc_write(PMNC_P | PMNC_C | PMNC_D);
++
++
++ for (cnt = CCNT; cnt < CNTMAX; cnt++) {
++ unsigned long event;
++ u32 cpu_cnt = CPU_COUNTER(smp_processor_id(), cnt);
++
++ /*
++ * Disable counter
++ */
++ armv7_pmnc_disable_counter(cnt);
++ cnt_en[cnt] = 0;
++
++ if (!counter_config[cpu_cnt].enabled)
++ continue;
++
++ event = counter_config[cpu_cnt].event & 255;
++
++ /*
++ * Set event (if destined for PMNx counters)
++ * We don't need to set the event if it's a cycle count
++ */
++ if (cnt != CCNT)
++ armv7_pmnc_write_evtsel(cnt, event);
++
++ /*
++ * Enable interrupt for this counter
++ */
++ armv7_pmnc_enable_intens(cnt);
++
++ /*
++ * Reset counter
++ */
++ armv7_pmnc_reset_counter(cnt);
++
++ /*
++ * Enable counter
++ */
++ armv7_pmnc_enable_counter(cnt);
++ cnt_en[cnt] = 1;
++ }
++
++ return 0;
++}
++
++static inline void armv7_start_pmnc(void)
++{
++ armv7_pmnc_write(armv7_pmnc_read() | PMNC_E);
++}
++
++static inline void armv7_stop_pmnc(void)
++{
++ armv7_pmnc_write(armv7_pmnc_read() & ~PMNC_E);
++}
++
++/*
++ * CPU counters' IRQ handler (one IRQ per CPU)
++ */
++static irqreturn_t armv7_pmnc_interrupt(int irq, void *arg)
++{
++ struct pt_regs *regs = get_irq_regs();
++ unsigned int cnt;
++ u32 flags;
++
++
++ /*
++ * Stop IRQ generation
++ */
++ armv7_stop_pmnc();
++
++ /*
++ * Get and reset overflow status flags
++ */
++ flags = armv7_pmnc_getreset_flags();
++
++ /*
++ * Cycle counter
++ */
++ if (flags & FLAG_C) {
++ u32 cpu_cnt = CPU_COUNTER(smp_processor_id(), CCNT);
++ armv7_pmnc_reset_counter(CCNT);
++ oprofile_add_sample(regs, cpu_cnt);
++ }
++
++ /*
++ * PMNC counters 0:3
++ */
++ for (cnt = CNT0; cnt < CNTMAX; cnt++) {
++ if (flags & (1 << (cnt - CNT0))) {
++ u32 cpu_cnt = CPU_COUNTER(smp_processor_id(), cnt);
++ armv7_pmnc_reset_counter(cnt);
++ oprofile_add_sample(regs, cpu_cnt);
++ }
++ }
++
++ /*
++ * Allow IRQ generation
++ */
++ armv7_start_pmnc();
++
++ return IRQ_HANDLED;
++}
++
++int armv7_request_interrupts(int *irqs, int nr)
++{
++ unsigned int i;
++ int ret = 0;
++
++ for (i = 0; i < nr; i++) {
++ ret = request_irq(irqs[i], armv7_pmnc_interrupt,
++ IRQF_DISABLED, "CP15 PMNC", NULL);
++ if (ret != 0) {
++ printk(KERN_ERR "oprofile: unable to request IRQ%u"
++ " for ARMv7\n",
++ irqs[i]);
++ break;
++ }
++ }
++
++ if (i != nr)
++ while (i-- != 0)
++ free_irq(irqs[i], NULL);
++
++ return ret;
++}
++
++void armv7_release_interrupts(int *irqs, int nr)
++{
++ unsigned int i;
++
++ for (i = 0; i < nr; i++)
++ free_irq(irqs[i], NULL);
++}
++
++#ifdef DEBUG
++static void armv7_pmnc_dump_regs(void)
++{
++ u32 val;
++ unsigned int cnt;
++
++ printk(KERN_INFO "PMNC registers dump:\n");
++
++ asm volatile("mrc p15, 0, %0, c9, c12, 0" : "=r" (val));
++ printk(KERN_INFO "PMNC =0x%08x\n", val);
++
++ asm volatile("mrc p15, 0, %0, c9, c12, 1" : "=r" (val));
++ printk(KERN_INFO "CNTENS=0x%08x\n", val);
++
++ asm volatile("mrc p15, 0, %0, c9, c14, 1" : "=r" (val));
++ printk(KERN_INFO "INTENS=0x%08x\n", val);
++
++ asm volatile("mrc p15, 0, %0, c9, c12, 3" : "=r" (val));
++ printk(KERN_INFO "FLAGS =0x%08x\n", val);
++
++ asm volatile("mrc p15, 0, %0, c9, c12, 5" : "=r" (val));
++ printk(KERN_INFO "SELECT=0x%08x\n", val);
++
++ asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r" (val));
++ printk(KERN_INFO "CCNT =0x%08x\n", val);
++
++ for (cnt = CNT0; cnt < CNTMAX; cnt++) {
++ armv7_pmnc_select_counter(cnt);
++ asm volatile("mrc p15, 0, %0, c9, c13, 2" : "=r" (val));
++ printk(KERN_INFO "CNT[%d] count =0x%08x\n", cnt-CNT0, val);
++ asm volatile("mrc p15, 0, %0, c9, c13, 1" : "=r" (val));
++ printk(KERN_INFO "CNT[%d] evtsel=0x%08x\n", cnt-CNT0, val);
++ }
++}
++#endif
++
++
++static int irqs[] = {
++#ifdef CONFIG_ARCH_OMAP3
++ INT_34XX_BENCH_MPU_EMUL,
++#endif
++};
++
++static void armv7_pmnc_stop(void)
++{
++#ifdef DEBUG
++ armv7_pmnc_dump_regs();
++#endif
++ armv7_stop_pmnc();
++ armv7_release_interrupts(irqs, ARRAY_SIZE(irqs));
++}
++
++static int armv7_pmnc_start(void)
++{
++ int ret;
++
++#ifdef DEBUG
++ armv7_pmnc_dump_regs();
++#endif
++ ret = armv7_request_interrupts(irqs, ARRAY_SIZE(irqs));
++ if (ret >= 0)
++ armv7_start_pmnc();
++
++ return ret;
++}
++
++static int armv7_detect_pmnc(void)
++{
++ return 0;
++}
++
++struct op_arm_model_spec op_armv7_spec = {
++ .init = armv7_detect_pmnc,
++ .num_counters = 5,
++ .setup_ctrs = armv7_setup_pmnc,
++ .start = armv7_pmnc_start,
++ .stop = armv7_pmnc_stop,
++ .name = "arm/armv7",
++};
+diff --git a/arch/arm/oprofile/op_model_v7.h b/arch/arm/oprofile/op_model_v7.h
+new file mode 100644
+index 0000000..08f40ea
+--- /dev/null
++++ b/arch/arm/oprofile/op_model_v7.h
+@@ -0,0 +1,101 @@
++/**
++ * @file op_model_v7.h
++ * ARM v7 (Cortex A8) Event Monitor Driver
++ *
++ * @remark Copyright 2008 Jean Pihet <jpihet@mvista.com>
++ * @remark Copyright 2004 ARM SMP Development Team
++ * @remark Copyright 2000-2004 Deepak Saxena <dsaxena@mvista.com>
++ * @remark Copyright 2000-2004 MontaVista Software Inc
++ * @remark Copyright 2004 Dave Jiang <dave.jiang@intel.com>
++ * @remark Copyright 2004 Intel Corporation
++ * @remark Copyright 2004 Zwane Mwaikambo <zwane@arm.linux.org.uk>
++ * @remark Copyright 2004 Oprofile Authors
++ *
++ * @remark Read the file COPYING
++ *
++ * @author Zwane Mwaikambo
++ */
++#ifndef OP_MODEL_V7_H
++#define OP_MODEL_V7_H
++
++/*
++ * Per-CPU PMNC: config reg
++ */
++#define PMNC_E (1 << 0) /* Enable all counters */
++#define PMNC_P (1 << 1) /* Reset all counters */
++#define PMNC_C (1 << 2) /* Cycle counter reset */
++#define PMNC_D (1 << 3) /* CCNT counts every 64th cpu cycle */
++#define PMNC_X (1 << 4) /* Export to ETM */
++#define PMNC_DP (1 << 5) /* Disable CCNT if non-invasive debug*/
++#define PMNC_MASK 0x3f /* Mask for writable bits */
++
++/*
++ * Available counters
++ */
++#define CCNT 0
++#define CNT0 1
++#define CNT1 2
++#define CNT2 3
++#define CNT3 4
++#define CNTMAX 5
++
++#define CPU_COUNTER(cpu, counter) ((cpu) * CNTMAX + (counter))
++
++/*
++ * CNTENS: counters enable reg
++ */
++#define CNTENS_P0 (1 << 0)
++#define CNTENS_P1 (1 << 1)
++#define CNTENS_P2 (1 << 2)
++#define CNTENS_P3 (1 << 3)
++#define CNTENS_C (1 << 31)
++#define CNTENS_MASK 0x8000000f /* Mask for writable bits */
++
++/*
++ * CNTENC: counters disable reg
++ */
++#define CNTENC_P0 (1 << 0)
++#define CNTENC_P1 (1 << 1)
++#define CNTENC_P2 (1 << 2)
++#define CNTENC_P3 (1 << 3)
++#define CNTENC_C (1 << 31)
++#define CNTENC_MASK 0x8000000f /* Mask for writable bits */
++
++/*
++ * INTENS: counters overflow interrupt enable reg
++ */
++#define INTENS_P0 (1 << 0)
++#define INTENS_P1 (1 << 1)
++#define INTENS_P2 (1 << 2)
++#define INTENS_P3 (1 << 3)
++#define INTENS_C (1 << 31)
++#define INTENS_MASK 0x8000000f /* Mask for writable bits */
++
++/*
++ * EVTSEL: Event selection reg
++ */
++#define EVTSEL_MASK 0x7f /* Mask for writable bits */
++
++/*
++ * SELECT: Counter selection reg
++ */
++#define SELECT_MASK 0x1f /* Mask for writable bits */
++
++/*
++ * FLAG: counters overflow flag status reg
++ */
++#define FLAG_P0 (1 << 0)
++#define FLAG_P1 (1 << 1)
++#define FLAG_P2 (1 << 2)
++#define FLAG_P3 (1 << 3)
++#define FLAG_C (1 << 31)
++#define FLAG_MASK 0x8000000f /* Mask for writable bits */
++
++
++int armv7_setup_pmu(void);
++int armv7_start_pmu(void);
++int armv7_stop_pmu(void);
++int armv7_request_interrupts(int *, int);
++void armv7_release_interrupts(int *, int);
++
++#endif
+
+diff --git a/arch/arm/plat-omap/include/mach/irqs.h
+b/arch/arm/plat-omap/include/mach/irqs.h
+index c80e160..89ca90e 100644
+--- a/arch/arm/plat-omap/include/mach/irqs.h
++++ b/arch/arm/plat-omap/include/mach/irqs.h
+@@ -297,6 +297,7 @@
+ #define INT_243X_HS_USB_DMA 93
+ #define INT_243X_CARKIT_IRQ 94
+
++#define INT_34XX_BENCH_MPU_EMUL 3
+ #define INT_34XX_ST_MCBSP2_IRQ 4
+ #define INT_34XX_ST_MCBSP3_IRQ 5
+ #define INT_34XX_SYS_NIRQ 7
diff --git a/packages/linux/linux-omap/read_die_ids.patch b/packages/linux/linux-omap/read_die_ids.patch
new file mode 100644
index 0000000000..3f6c930cc1
--- /dev/null
+++ b/packages/linux/linux-omap/read_die_ids.patch
@@ -0,0 +1,23 @@
+OMAP2/3 TAP: enable debug messages
+
+From: Paul Walmsley <paul@pwsan.com>
+
+This patch causes the OMAP2/3 chip ID code to display the full DIE_ID registers at boot.
+
+---
+
+ arch/arm/mach-omap2/id.c | 1 +
+ 1 files changed, 1 insertions(+), 0 deletions(-)
+
+diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c
+index c7f9ab7..a154b5e 100644
+--- a/arch/arm/mach-omap2/id.c
++++ b/arch/arm/mach-omap2/id.c
+@@ -10,6 +10,7 @@
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
++#define DEBUG
+
+ #include <linux/module.h>
+ #include <linux/kernel.h>
diff --git a/packages/linux/linux-omap/soc.patch b/packages/linux/linux-omap/soc.patch
new file mode 100644
index 0000000000..f4cce21ca7
--- /dev/null
+++ b/packages/linux/linux-omap/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-omap/timer-suppression.patch b/packages/linux/linux-omap/timer-suppression.patch
new file mode 100644
index 0000000000..04362c96e3
--- /dev/null
+++ b/packages/linux/linux-omap/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-omap/touchscreen.patch b/packages/linux/linux-omap/touchscreen.patch
new file mode 100644
index 0000000000..2325c401e4
--- /dev/null
+++ b/packages/linux/linux-omap/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 = {
+
diff --git a/packages/linux/linux-omap_git.bb b/packages/linux/linux-omap_git.bb
new file mode 100644
index 0000000000..c596a95a71
--- /dev/null
+++ b/packages/linux/linux-omap_git.bb
@@ -0,0 +1,63 @@
+require linux.inc
+
+DESCRIPTION = "Linux kernel for OMAP processors"
+KERNEL_IMAGETYPE = "uImage"
+
+COMPATIBLE_MACHINE = "omap5912osk|omap1710h3|omap2430sdp|omap2420h4|beagleboard|omap3evm"
+
+
+SRCREV = "b3f16ee00db9ec6b2ad53fc83fa913b42d3841be"
+
+PV = "2.6.26+2.6.27-rc5+${PR}+git${SRCREV}"
+PR = "r0"
+
+SRC_URI = "git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap-2.6.git;protocol=git \
+ file://defconfig"
+
+SRC_URI_append = " file://no-harry-potter.diff;patch=1 \
+ file://0001-ASoC-OMAP-Add-basic-support-for-OMAP34xx-in-McBSP.patch;patch=1 \
+ file://timer-suppression.patch;patch=1 \
+ file://no-empty-flash-warnings.patch;patch=1 \
+ file://oprofile-0.9.3.armv7.diff;patch=1 \
+ file://01-fix-timing-print.diff;patch=1 \
+ file://02-set-clkseld11.diff;patch=1 \
+ file://03-enable-overlay-opt.diff;patch=1 \
+ file://04-use-pcd.diff;patch=1 \
+ file://05-fix-display-panning.diff;patch=1 \
+ file://06-ensure-fclk.diff;patch=1 \
+ file://07-set-burst-size.diff;patch=1 \
+ file://cache-display-fix.patch;patch=1 \
+ file://mru-clocks1.diff;patch=1 \
+ file://mru-clocks2.diff;patch=1 \
+ file://mru-clocks3.diff;patch=1 \
+ file://4bitmmc.diff;patch=1 \
+ file://no-cortex-deadlock.patch;patch=1 \
+ file://read_die_ids.patch;patch=1 \
+ file://000-mru-make-video-mode-selcatable.diff;patch=1 \
+ file://001-mru-enable-overlay.diff;patch=1 \
+ file://002-mru-set-default-800x600.diff;patch=1 \
+ file://003-mru-omapfb-more-video-modes.diff;patch=1 \
+ file://004-mru-export-omapfb-register-panel.diff;patch=1 \
+ file://005-mru-add-omapfb-unregister-panel.diff;patch=1 \
+ file://006-mru-lcd-as-modules.diff;patch=1 \
+ file://007-mru-omapfb-as-module.diff;patch=1 \
+ file://008-mru-lcd-omap3beagle-license.diff;patch=1 \
+ file://009-mru-unregister-beagle-lcd.diff;patch=1 \
+ file://010-mru-fix-video-mode-param.diff;patch=1 \
+ file://001-sakoman-twl4030-asoc.diff;patch=1 \
+ file://musb-dmafix.patch;patch=1 \
+"
+
+SRC_URI_append_beagleboard = " file://logo_linux_clut224.ppm \
+ "
+
+SRC_URI_append_omap3evm = " \
+ file://touchscreen.patch;patch=1 \
+"
+
+S = "${WORKDIR}/git"
+
+
+module_autoload_ohci-hcd_omap5912osk = "ohci-hcd"
+
+