summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcin Juszkiewicz <hrw@openembedded.org>2006-04-28 19:06:59 +0000
committerOpenEmbedded Project <openembedded-devel@lists.openembedded.org>2006-04-28 19:06:59 +0000
commit989a3c578011cad60fc167cdb1b9a0e603f43072 (patch)
treeaef515b13e77cda22b30d75295f3aaef16d6c470
parentd775757b77aba05c2766546682db2915b5cc12e1 (diff)
* add initial support for gumstix (xscale pxa255) platform (gumstix.com)
* add GMUstix distro for gumstix (GMU = George Mason University) * add linux-gumstix-2.6.15 with gumstix patchset * close bug #861
-rw-r--r--conf/distro/gmustix.conf27
-rw-r--r--conf/machine/gumstix.conf25
-rw-r--r--packages/linux/linux-gumstix-2.6.15/.mtn2git_empty0
-rw-r--r--packages/linux/linux-gumstix-2.6.15/add_input_randomness_export.patch13
-rw-r--r--packages/linux/linux-gumstix-2.6.15/arch-config.patch55
-rw-r--r--packages/linux/linux-gumstix-2.6.15/audio.patch454
-rw-r--r--packages/linux/linux-gumstix-2.6.15/bkpxa-pxa-ac97.patch1415
-rw-r--r--packages/linux/linux-gumstix-2.6.15/bkpxa-pxa-cpu.patch117
-rw-r--r--packages/linux/linux-gumstix-2.6.15/bkpxa-pxa-cpufreq.patch403
-rw-r--r--packages/linux/linux-gumstix-2.6.15/board-init.patch98
-rw-r--r--packages/linux/linux-gumstix-2.6.15/bugfix-i2c-include.patch12
-rw-r--r--packages/linux/linux-gumstix-2.6.15/bugfix-mmc-clock.patch14
-rw-r--r--packages/linux/linux-gumstix-2.6.15/bugfix-mtd-onenand.patch22
-rw-r--r--packages/linux/linux-gumstix-2.6.15/bugfix-pxa-audio.patch25
-rw-r--r--packages/linux/linux-gumstix-2.6.15/bugfix-pxa-cpufreq.patch64
-rw-r--r--packages/linux/linux-gumstix-2.6.15/bugfix-pxa-serial-mctrl.patch12
-rw-r--r--packages/linux/linux-gumstix-2.6.15/bugfix-rndis.patch14
-rw-r--r--packages/linux/linux-gumstix-2.6.15/bugfix-serial-interrupt.patch25
-rw-r--r--packages/linux/linux-gumstix-2.6.15/bugfix-serial-register-status.patch70
-rw-r--r--packages/linux/linux-gumstix-2.6.15/compact-flash.patch171
-rw-r--r--packages/linux/linux-gumstix-2.6.15/cpufreq-better-freqs.patch53
-rw-r--r--packages/linux/linux-gumstix-2.6.15/cpufreq-ondemand-by-default.patch42
-rw-r--r--packages/linux/linux-gumstix-2.6.15/defconfig-gumstix995
-rw-r--r--packages/linux/linux-gumstix-2.6.15/defconfig.patch766
-rw-r--r--packages/linux/linux-gumstix-2.6.15/disable-uncompress-message.patch32
-rw-r--r--packages/linux/linux-gumstix-2.6.15/ethernet-config.patch26
-rw-r--r--packages/linux/linux-gumstix-2.6.15/flash.patch171
-rw-r--r--packages/linux/linux-gumstix-2.6.15/gumstix-mmc.patch91
-rw-r--r--packages/linux/linux-gumstix-2.6.15/header.patch87
-rw-r--r--packages/linux/linux-gumstix-2.6.15/i2c-gpl-module-fix.patch43
-rw-r--r--packages/linux/linux-gumstix-2.6.15/kconfig-arch-cleanup.patch72
-rw-r--r--packages/linux/linux-gumstix-2.6.15/kernel-osx.patch50
-rw-r--r--packages/linux/linux-gumstix-2.6.15/kobject_get_path_export.patch13
-rw-r--r--packages/linux/linux-gumstix-2.6.15/mach-types-fix.patch13
-rw-r--r--packages/linux/linux-gumstix-2.6.15/mmc-version4.patch12
-rw-r--r--packages/linux/linux-gumstix-2.6.15/modular-init-bluetooth.patch106
-rw-r--r--packages/linux/linux-gumstix-2.6.15/modular-init-smc91x.patch171
-rw-r--r--packages/linux/linux-gumstix-2.6.15/modular-init-usb-gadget.patch105
-rw-r--r--packages/linux/linux-gumstix-2.6.15/proc-gpio.patch401
-rw-r--r--packages/linux/linux-gumstix-2.6.15/pxa255-gpio-count-bugfix.patch13
-rw-r--r--packages/linux/linux-gumstix-2.6.15/pxa2xx_udc.patch57
-rw-r--r--packages/linux/linux-gumstix-2.6.15/rmk-2022-2-rtctime-sa110-pxa255-driver.patch329
-rw-r--r--packages/linux/linux-gumstix-2.6.15/rmk_pxa_mmc_timeout.patch34
-rw-r--r--packages/linux/linux-gumstix-2.6.15/serial-ether-addr.patch46
-rw-r--r--packages/linux/linux-gumstix-2.6.15/smc-ether-addr.patch53
-rw-r--r--packages/linux/linux-gumstix-2.6.15/ucb1400-ac97-audio.patch84
-rw-r--r--packages/linux/linux-gumstix-2.6.15/ucb1400-touchscreen.patch704
-rw-r--r--packages/linux/linux-gumstix_2.6.15.bb109
48 files changed, 7714 insertions, 0 deletions
diff --git a/conf/distro/gmustix.conf b/conf/distro/gmustix.conf
new file mode 100644
index 0000000000..b359c926b0
--- /dev/null
+++ b/conf/distro/gmustix.conf
@@ -0,0 +1,27 @@
+#@TYPE: Distribution
+#@NAME: GMUstix
+#@DESCRIPTION: Gumstix distribution for GMU (George Mason University)
+
+INHERIT += "package_tar package_ipk"
+TARGET_OS = "linux-uclibc"
+TARGET_FPU = "soft"
+IMAGE_FSTYPES = "jffs2"
+
+PREFERRED_PROVIDERS += " virtual/${TARGET_PREFIX}gcc-initial:gcc-cross-initial"
+PREFERRED_PROVIDERS += " virtual/${TARGET_PREFIX}gcc:gcc-cross"
+PREFERRED_PROVIDERS += " virtual/${TARGET_PREFIX}g++:gcc-cross"
+PREFERRED_PROVIDERS += " virtual/${TARGET_PREFIX}libc-for-gcc:uclibc"
+
+PREFERRED_PROVIDER_classpath = "classpath-minimal"
+
+PREFERRED_VERSION_gcc-cross-initial = "3.4.4"
+PREFERRED_VERSION_gcc-cross = "3.4.4"
+PREFERRED_VERSION_gcc-cross-sdk = "3.4.4"
+PREFERRED_VERSION_gcc = "3.4.4"
+
+PREFERRED_VERSION_ipkg-native = "0.99.160"
+PREFERRED_VERSION_qemu-native = "0.8.0"
+
+DISTRO_VERSION = "uno"
+
+IPK_EXCLUDE_SOURCE = "1"
diff --git a/conf/machine/gumstix.conf b/conf/machine/gumstix.conf
new file mode 100644
index 0000000000..8da2f5ca3a
--- /dev/null
+++ b/conf/machine/gumstix.conf
@@ -0,0 +1,25 @@
+TARGET_ARCH = "arm"
+TARGET_VENDOR = "-oe"
+PREFERRED_PROVIDER_virtual/kernel = "linux-gumstix"
+OLDEST_KERNEL = "2.6.15"
+MODUTILS = "26"
+IPKG_ARCHS = "arm ${MACHINE}"
+
+include conf/machine/include/tune-xscale.conf
+TARGET_CC_ARCH = "-Os -pipe -Os -march=armv5te -mtune=xscale -Wa,-mcpu=xscale"
+
+PACKAGE_ARCH = "arm"
+
+EXTRA_IMAGECMD_jffs2 = "--little-endian --eraseblock=0x20000 --squash"
+
+HOTPLUG = "udev"
+udevdir = "/dev"
+
+GUMSTIX_400MHZ = "y"
+
+SERIAL_CONSOLE = "115200 ttyS0 vt100"
+USE_VT = "0"
+
+BOOTSTRAP_EXTRA_RDEPENDS = "kernel-modules-mmc kernel-modules-usb kernel-modules-fat kernel-modules-bluetooth kernel-module-jfs udev lrzsz"
+PREFERRED_VERSION_task-bootstrap = "1.0unionroot"
+
diff --git a/packages/linux/linux-gumstix-2.6.15/.mtn2git_empty b/packages/linux/linux-gumstix-2.6.15/.mtn2git_empty
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/packages/linux/linux-gumstix-2.6.15/.mtn2git_empty
diff --git a/packages/linux/linux-gumstix-2.6.15/add_input_randomness_export.patch b/packages/linux/linux-gumstix-2.6.15/add_input_randomness_export.patch
new file mode 100644
index 0000000000..8829a0cea7
--- /dev/null
+++ b/packages/linux/linux-gumstix-2.6.15/add_input_randomness_export.patch
@@ -0,0 +1,13 @@
+Oddly, drivers/input/input.c seems to reference a symbol which is apparently in another module but not exported.
+Index: linux-2.6.15gum/drivers/char/random.c
+===================================================================
+--- linux-2.6.15gum.orig/drivers/char/random.c
++++ linux-2.6.15gum/drivers/char/random.c
+@@ -646,6 +646,7 @@ extern void add_input_randomness(unsigne
+ add_timer_randomness(&input_timer_state,
+ (type << 4) ^ code ^ (code >> 4) ^ value);
+ }
++EXPORT_SYMBOL(add_input_randomness);
+
+ void add_interrupt_randomness(int irq)
+ {
diff --git a/packages/linux/linux-gumstix-2.6.15/arch-config.patch b/packages/linux/linux-gumstix-2.6.15/arch-config.patch
new file mode 100644
index 0000000000..411a117953
--- /dev/null
+++ b/packages/linux/linux-gumstix-2.6.15/arch-config.patch
@@ -0,0 +1,55 @@
+Index: linux-2.6.15gum/arch/arm/mach-pxa/Kconfig
+===================================================================
+--- linux-2.6.15gum.orig/arch/arm/mach-pxa/Kconfig
++++ linux-2.6.15gum/arch/arm/mach-pxa/Kconfig
+@@ -5,6 +5,10 @@ menu "Intel PXA2xx Implementations"
+ choice
+ prompt "Select target board"
+
++config ARCH_GUMSTIX
++ bool "Gumstix Platform"
++ depends on ARCH_PXA
++
+ config ARCH_LUBBOCK
+ bool "Intel DBPXA250 Development Platform"
+ select PXA25x
+@@ -94,6 +98,27 @@ config MACH_TOSA
+ bool "Enable Sharp SL-6000x (Tosa) Support"
+ depends PXA_SHARPSL_25x
+
++choice
++ depends on ARCH_GUMSTIX
++ prompt "Gumstix Platform Version"
++ default ARCH_GUMSTIX_F
++
++config ARCH_GUMSTIX_ORIG
++ bool "Original Gumstix"
++ select PXA25x
++ help
++ The original gumstix platform, including the gs-200x and gs-400x and the waysmall
++ systems using these boards.
++
++config ARCH_GUMSTIX_F
++ bool "Gumstix-F"
++ select PXA25x
++ help
++ The updated Gumstix boards with 60-pin connector, including gs-200f, gs-400f and the
++ waysmall systems using these boards, including ws-200ax and ws-400ax.
++
++endchoice
++
+ config PXA25x
+ bool
+ help
+Index: linux-2.6.15gum/arch/arm/mach-pxa/Makefile
+===================================================================
+--- linux-2.6.15gum.orig/arch/arm/mach-pxa/Makefile
++++ linux-2.6.15gum/arch/arm/mach-pxa/Makefile
+@@ -8,6 +8,7 @@ obj-$(CONFIG_PXA25x) += pxa25x.o
+ obj-$(CONFIG_PXA27x) += pxa27x.o
+
+ # Specific board support
++obj-$(CONFIG_ARCH_GUMSTIX) += gumstix.o
+ obj-$(CONFIG_ARCH_LUBBOCK) += lubbock.o
+ obj-$(CONFIG_MACH_MAINSTONE) += mainstone.o
+ obj-$(CONFIG_ARCH_PXA_IDP) += idp.o
diff --git a/packages/linux/linux-gumstix-2.6.15/audio.patch b/packages/linux/linux-gumstix-2.6.15/audio.patch
new file mode 100644
index 0000000000..d565b70582
--- /dev/null
+++ b/packages/linux/linux-gumstix-2.6.15/audio.patch
@@ -0,0 +1,454 @@
+Index: linux-2.6.15gum/sound/oss/ac97_codec.c
+===================================================================
+--- linux-2.6.15gum.orig/sound/oss/ac97_codec.c
++++ linux-2.6.15gum/sound/oss/ac97_codec.c
+@@ -59,6 +59,9 @@
+
+ #define CODEC_ID_BUFSZ 14
+
++static int ucb1400_read_mixer(struct ac97_codec *codec, int oss_channel);
++static void ucb1400_write_mixer(struct ac97_codec *codec, int oss_channel,
++ unsigned int left, unsigned int right);
+ static int ac97_read_mixer(struct ac97_codec *codec, int oss_channel);
+ static void ac97_write_mixer(struct ac97_codec *codec, int oss_channel,
+ unsigned int left, unsigned int right);
+@@ -85,6 +88,7 @@ static int cmedia_init(struct ac97_codec
+ static int cmedia_digital_control(struct ac97_codec *codec, int slots, int rate, int mode);
+ static int generic_digital_control(struct ac97_codec *codec, int slots, int rate, int mode);
+ static int ucb1400_init(struct ac97_codec *codec);
++static int ucb1400_control(struct ac97_codec *codec, int on);
+
+
+ /*
+@@ -120,7 +124,7 @@ static struct ac97_ops crystal_digital_o
+ static struct ac97_ops ad1886_ops = { ad1886_init, eapd_control, NULL };
+ static struct ac97_ops cmedia_ops = { NULL, eapd_control, NULL};
+ static struct ac97_ops cmedia_digital_ops = { cmedia_init, eapd_control, cmedia_digital_control};
+-static struct ac97_ops ucb1400_ops = { ucb1400_init, eapd_control, NULL };
++static struct ac97_ops ucb1400_ops = { ucb1400_init, ucb1400_control, NULL };
+
+ /* sorted by vendor/device id */
+ static const struct {
+@@ -309,6 +313,143 @@ static LIST_HEAD(codecs);
+ static LIST_HEAD(codec_drivers);
+ static DECLARE_MUTEX(codec_sem);
+
++// Values of UCB1400 register addresses
++#define AC97_UCB1400_FCR1 (0x6a)
++#define AC97_UCB1400_FCR2 (0x6c)
++// Masks for bits of interest in those registers
++#define AC97_UCB1400_BASS_BOOST_MASK (0xf << 11)
++#define AC97_UCB1400_TREB_BOOST_MASK (0x3 << 9)
++#define AC97_UCB1400_BOOST_MODE_MASK (0x3 << 7)
++// Calculate the boost mode from the register by extracting the bits, then shifting it down
++// Mode 0 == flat, 1 == minimum, 2 == minimum, 3 == maximum
++#define AC97_UCB1400_BOOST_MODE(x) (((x) & AC97_UCB1400_BOOST_MODE_MASK) >> 7)
++// Caculate the treble boost
++#define AC97_UCB1400_TREB_BOOST(x) (((x) & AC97_UCB1400_TREB_BOOST_MASK) >> 9)
++// Calculate the bass boost
++#define AC97_UCB1400_BASS_BOOST(x) (((x) & AC97_UCB1400_BASS_BOOST_MASK) >> 11)
++
++// Use a conversion table to translate from the register values to dB values
++#define AC97_UCB1400_BASS_LOOKUP(x,l) ((l)[AC97_UCB1400_BASS_BOOST(x) | (AC97_UCB1400_BOOST_MODE(x) << 4)])
++#define AC97_UCB1400_TREB_LOOKUP(x,l) ((l)[AC97_UCB1400_TREB_BOOST(x) | (AC97_UCB1400_BOOST_MODE(x) << 4)])
++
++// This lookup table is indexed by a 6 bit number:
++// Two high bits are the boost mode from teh register
++// Four low bits are from the BASS or TREB boost value in the register
++// The lookup value is the dB boost calculated from the UCB1400 spec sheet
++// The lookup values will be calculated and populated during ucb1400_init()
++static const u8 ac97_ucb1400_boost_lookup[] = {
++ [0] = 0, [1] = 0, [2] = 0, [3] = 0,
++ [4] = 0, [5] = 0, [6] = 0, [7] = 0, // flat 00
++ [8] = 0, [9] = 0, [10] = 0, [11] = 0,
++ [12] = 0, [13] = 0, [14] = 0, [15] = 0,
++
++ [16] = 0, [17] = 2, [18] = 4, [19] = 6,
++ [20] = 8, [21] = 10, [22] = 12, [23] = 14, // min 01
++ [24] = 16, [25] = 18, [26] = 18, [27] = 18,
++ [28] = 18, [29] = 18, [30] = 18, [31] = 18,
++
++ [32] = 0, [33] = 2, [34] = 4, [35] = 6,
++ [36] = 8, [37] = 10, [38] = 12, [39] = 14, // min 10
++ [40] = 16, [41] = 18, [42] = 18, [43] = 18,
++ [44] = 18, [45] = 18, [46] = 18, [47] = 18,
++
++ [48] = 0, [49] = 2, [50] = 4, [51] = 6,
++ [52] = 8, [53] = 10, [54] = 12, [55] = 14, // max 11
++ [56] = 16, [57] = 18, [58] = 20, [59] = 22,
++ [60] = 24, [61] = 24, [62] = 24, [63] = 24
++};
++
++static int ucb1400_read_mixer(struct ac97_codec *codec, int oss_channel)
++{
++ u16 val;
++
++ switch(oss_channel)
++ {
++
++ case SOUND_MIXER_BASS:
++ // Convert from the 24-dB max BASS boost level to a %age
++ val = codec->codec_read(codec, AC97_UCB1400_FCR1); // Read the register
++ return (AC97_UCB1400_BASS_LOOKUP(val, ac97_ucb1400_boost_lookup)*100)/24;
++
++ case SOUND_MIXER_TREBLE:
++ // Convert from the 6-dB max TREB boost level to a %age
++ val = codec->codec_read(codec, AC97_UCB1400_FCR1); // Read the register
++ return (AC97_UCB1400_TREB_LOOKUP(val, ac97_ucb1400_boost_lookup)*100)/6;
++
++ case SOUND_MIXER_MIC:
++ val = codec->codec_read(codec, AC97_MIC_VOL);
++ return (val & AC97_MICBOOST ? 100 : 0);
++
++ default:
++ return ac97_read_mixer(codec, oss_channel);
++ }
++}
++
++#ifndef MAX
++#define MAX(a,b) (((a)>(b)) ? (a) : (b))
++#endif
++
++static void ucb1400_write_mixer(struct ac97_codec *codec, int oss_channel,
++ unsigned int left, unsigned int right)
++{
++ u16 old_val,new_val;
++ u8 treb,bass;
++
++ switch(oss_channel)
++ {
++ case SOUND_MIXER_BASS:
++ case SOUND_MIXER_TREBLE:
++ old_val = codec->codec_read(codec, AC97_UCB1400_FCR1); // Read the register
++
++ // Determine which one changed, set old one to old value (or 0 if old mode was flat)
++ bass = (oss_channel==SOUND_MIXER_BASS) ?
++ (left*24)/100 : // Convert from %age to 0-24dB scale for bass
++ AC97_UCB1400_BASS_LOOKUP(old_val, ac97_ucb1400_boost_lookup);
++ treb = (oss_channel==SOUND_MIXER_TREBLE) ?
++ (left*6)/100 : // convert from %age to 0-6dB scale for bass
++ AC97_UCB1400_TREB_LOOKUP(old_val, ac97_ucb1400_boost_lookup);
++
++ // Now convert both treble and bass to values for the register.
++ // If both are 0, then use mode flat
++ // If either is non-zero, then use mode min if bass <=18
++ // Otherwise, use mode max
++ new_val = old_val & ~(AC97_UCB1400_BASS_BOOST_MASK | // First clear the bits
++ AC97_UCB1400_TREB_BOOST_MASK | // which is same as flat mode
++ AC97_UCB1400_BOOST_MODE_MASK); // with both boosts at 0
++ if(bass > 18)
++ {
++ new_val |= (3 << 7); // Set boost mode to 0b11 which is "max"
++ }
++ else if(bass > 0 || treb > 0)
++ {
++ new_val |= (1 << 7); // Set boost mode to 0b01 which is "min"
++ }
++ else
++ {
++ // Set boost mode to 0b00 which is "flat"
++ }
++
++ if(bass || treb)
++ {
++ // The value to stick in the register the boost in dB divided by 2
++ // Dividing by 2 is the same as shifting right by 1
++ // We fix overflows by anding with the mask
++ new_val |= ((bass >> 1) << 11) & AC97_UCB1400_BASS_BOOST_MASK;
++ new_val |= ((treb >> 1) << 9) & AC97_UCB1400_TREB_BOOST_MASK;
++ }
++
++ // Ok, now poke the value back to the codec
++ codec->codec_write(codec, AC97_UCB1400_FCR1, new_val);
++ break;
++
++ case SOUND_MIXER_MIC:
++ codec->codec_write(codec, AC97_MIC_VOL, (left >= 50 ? AC97_MICBOOST : 0));
++ break;
++
++ default: ac97_write_mixer(codec, oss_channel, left, right);
++ }
++}
++
+ /* reads the given OSS mixer from the ac97 the caller must have insured that the ac97 knows
+ about that given mixer, and should be holding a spinlock for the card */
+ static int ac97_read_mixer(struct ac97_codec *codec, int oss_channel)
+@@ -526,6 +667,7 @@ static int ac97_recmask_io(struct ac97_c
+ #endif
+
+ codec->codec_write(codec, AC97_RECORD_SELECT, val);
++ val = codec->codec_read(codec, AC97_RECORD_SELECT);
+
+ return 0;
+ };
+@@ -634,6 +776,8 @@ int ac97_read_proc (char *page, char **s
+ {
+ int len = 0, cap, extid, val, id1, id2;
+ struct ac97_codec *codec;
++ u8 ac97_register_query_list[] = {0x02,0x0e,0x1a,0x1c,0x26,0x2a,0x2c,0x32,0x6a,0x6c,0x00};
++ size_t i=0;
+ int is_ac97_20 = 0;
+
+ if ((codec = data) == NULL)
+@@ -702,6 +846,13 @@ int ac97_read_proc (char *page, char **s
+ codec->codec_read(codec, AC97_PCM_FRONT_DAC_RATE));
+ }
+
++ do
++ {
++ len += sprintf(page+len, "Reg. 0x%02x : 0x%04x\n",
++ ac97_register_query_list[i],
++ codec->codec_read(codec, ac97_register_query_list[i]));
++ i++;
++ } while(ac97_register_query_list[i]);
+ return len;
+ }
+
+@@ -1180,7 +1331,25 @@ static int ad1886_init(struct ac97_codec
+ }
+
+
++static int ucb1400_control(struct ac97_codec *codec, int on)
++{
++ if(on)
++ {
++ codec->codec_write(codec, AC97_POWER_CONTROL, 0x0000); // turn everything on
+
++ // Now we wait for everything to settle
++ udelay(100);
++ }
++ else
++ {
++ codec->codec_write(codec, AC97_POWER_CONTROL,
++ (1 << 11) | // PR3: Audio Vref power-down
++ (1 << 9) | // PR1: Audio DAC and output path power-down
++ (1 << 8) // PR0: Audio ADC and input path power-down
++ );
++ }
++ return 0;
++}
+
+ /*
+ * This is basically standard AC97. It should work as a default for
+@@ -1336,10 +1505,55 @@ static int pt101_init(struct ac97_codec
+
+ static int ucb1400_init(struct ac97_codec *codec)
+ {
+- codec->codec_write(codec,AC97_EXTENDED_STATUS,1);
+- //codec->codec_write(codec, 0x6a, 0x1ff7);
+- codec->codec_write(codec, 0x6a, 0x0050);
+- codec->codec_write(codec, 0x6c, 0x0030);
++ codec->supported_mixers = SOUND_MASK_VOLUME | // Specify what UCB1400 supports
++ SOUND_MASK_BASS |
++ SOUND_MASK_TREBLE |
++ SOUND_MASK_MIC |
++ SOUND_MASK_IGAIN;
++
++ codec->stereo_mixers = SOUND_MASK_VOLUME | // Specify what UCB1400 supports
++ SOUND_MASK_LINE |
++ SOUND_MASK_IGAIN;
++
++ codec->record_sources = SOUND_MASK_MIC | // Specify what UCB1400 supports
++ SOUND_MASK_LINE;
++
++ codec->read_mixer = ucb1400_read_mixer; // The UCB1400 bass and treble implementations
++ codec->write_mixer = ucb1400_write_mixer; // need special code
++
++ codec->codec_write(codec,AC97_EXTENDED_STATUS, 1); // Ensure that VRA is on
++
++ ucb1400_control(codec, 1); // Turn on DAC/ADC paths first to prevent click
++
++ codec->codec_write(codec, AC97_UCB1400_FCR1,
++ (0 << 11) | // 0 base boost
++ (0 << 9) | // 0 treble boost
++ (0 << 7) | // Mode = flat
++ (1 << 6) | // Headphones enable
++ (0 << 5) | // De-emphasis disabled
++ (1 << 4) | // DC filter enabled
++ (1 << 3) | // Hi-pass filter enabled
++ (0 << 2) | // disable interrupt signalling via GPIO_INT
++ (1 << 0) // clear ADC overflow status if set
++ );
++
++ codec->codec_write(codec, AC97_UCB1400_FCR2,
++ (0 << 15) | // must be 0
++ (0 << 13) | // must be 0
++ (1 << 12) | // ADC filter enabled
++ (0 << 10) | // must be 0
++ (0 << 4) | // Smart low power mode on neither Codec nor PLL
++ (0 << 0) // must be 0
++ );
++
++ codec->codec_write(codec, AC97_RECORD_SELECT, 0); // default source is MIC
++
++ codec->codec_write(codec, AC97_MIC_VOL, (1 << 6)); // 20dB MIC boost
++
++ codec->codec_write(codec, AC97_RECORD_GAIN, 0); // no master record gain
++
++ codec->codec_write(codec, AC97_GENERAL_PURPOSE, 0); // no ADC to DAC loopback
++
+ return 0;
+ }
+
+@@ -1368,30 +1582,9 @@ unsigned int ac97_set_dac_rate(struct ac
+
+ if(rate != codec->codec_read(codec, AC97_PCM_FRONT_DAC_RATE))
+ {
+- /* Mute several registers */
+- mast_vol = codec->codec_read(codec, AC97_MASTER_VOL_STEREO);
+- mono_vol = codec->codec_read(codec, AC97_MASTER_VOL_MONO);
+- phone_vol = codec->codec_read(codec, AC97_HEADPHONE_VOL);
+- pcm_vol = codec->codec_read(codec, AC97_PCMOUT_VOL);
+- codec->codec_write(codec, AC97_MASTER_VOL_STEREO, mute_vol);
+- codec->codec_write(codec, AC97_MASTER_VOL_MONO, mute_vol);
+- codec->codec_write(codec, AC97_HEADPHONE_VOL, mute_vol);
+- codec->codec_write(codec, AC97_PCMOUT_VOL, mute_vol);
+-
+- /* Power down the DAC */
+- dacp=codec->codec_read(codec, AC97_POWER_CONTROL);
+- codec->codec_write(codec, AC97_POWER_CONTROL, dacp|0x0200);
+ /* Load the rate and read the effective rate */
+ codec->codec_write(codec, AC97_PCM_FRONT_DAC_RATE, rate);
+ new_rate=codec->codec_read(codec, AC97_PCM_FRONT_DAC_RATE);
+- /* Power it back up */
+- codec->codec_write(codec, AC97_POWER_CONTROL, dacp);
+-
+- /* Restore volumes */
+- codec->codec_write(codec, AC97_MASTER_VOL_STEREO, mast_vol);
+- codec->codec_write(codec, AC97_MASTER_VOL_MONO, mono_vol);
+- codec->codec_write(codec, AC97_HEADPHONE_VOL, phone_vol);
+- codec->codec_write(codec, AC97_PCMOUT_VOL, pcm_vol);
+ }
+ return new_rate;
+ }
+@@ -1414,14 +1607,9 @@ unsigned int ac97_set_adc_rate(struct ac
+
+ if(rate != codec->codec_read(codec, AC97_PCM_LR_ADC_RATE))
+ {
+- /* Power down the ADC */
+- dacp=codec->codec_read(codec, AC97_POWER_CONTROL);
+- codec->codec_write(codec, AC97_POWER_CONTROL, dacp|0x0100);
+ /* Load the rate and read the effective rate */
+ codec->codec_write(codec, AC97_PCM_LR_ADC_RATE, rate);
+ new_rate=codec->codec_read(codec, AC97_PCM_LR_ADC_RATE);
+- /* Power it back up */
+- codec->codec_write(codec, AC97_POWER_CONTROL, dacp);
+ }
+ return new_rate;
+ }
+Index: linux-2.6.15gum/sound/oss/pxa-ac97.c
+===================================================================
+--- linux-2.6.15gum.orig/sound/oss/pxa-ac97.c
++++ linux-2.6.15gum/sound/oss/pxa-ac97.c
+@@ -21,6 +21,7 @@
+ #include <linux/completion.h>
+ #include <linux/delay.h>
+ #include <linux/poll.h>
++#include <linux/proc_fs.h>
+ #include <linux/sound.h>
+ #include <linux/soundcard.h>
+ #include <linux/ac97_codec.h>
+@@ -55,10 +56,10 @@ static u16 pxa_ac97_read(struct ac97_cod
+ if (GSR & GSR_RDCS) {
+ GSR = GSR_RDCS; //write a 1 to clear
+ printk(KERN_CRIT "%s: read codec register timeout.\n", __FUNCTION__);
+- }
++ }
+
+ init_completion(&CAR_completion);
+- val = *reg_addr; //valid data now but we've just started another cycle...
++ val = *reg_addr; //valid data now but we've just started another cycle...
+ wait_for_completion(&CAR_completion);
+
+ } else {
+@@ -116,7 +117,7 @@ int pxa_ac97_get(struct ac97_codec **cod
+ if (ret)
+ return ret;
+
+- CKEN |= CKEN2_AC97;
++ pxa_set_cken(CKEN2_AC97,1);
+
+ pxa_gpio_mode(GPIO31_SYNC_AC97_MD);
+ pxa_gpio_mode(GPIO30_SDATA_OUT_AC97_MD);
+@@ -134,7 +135,7 @@ int pxa_ac97_get(struct ac97_codec **cod
+ if (ret != 1) {
+ free_irq(IRQ_AC97, NULL);
+ GCR = GCR_ACLINK_OFF;
+- CKEN &= ~CKEN2_AC97;
++ pxa_set_cken(CKEN2_AC97,0);
+ return ret;
+ }
+ }
+@@ -151,7 +152,7 @@ void pxa_ac97_put(void)
+ pxa_ac97_refcount--;
+ if (!pxa_ac97_refcount) {
+ GCR = GCR_ACLINK_OFF;
+- CKEN &= ~CKEN2_AC97;
++ pxa_set_cken(CKEN2_AC97,0);
+ free_irq(IRQ_AC97, NULL);
+ }
+ up(&pxa_ac97_mutex);
+@@ -179,7 +180,7 @@ static audio_stream_t ac97_audio_in;
+ */
+ static void update_audio_in (void)
+ {
+-#if 1
++#if 0
+ long val;
+
+ /* Use the value stuffed by ac97_recmask_io()
+@@ -335,6 +336,13 @@ static int __init pxa_ac97_init(void)
+
+ update_audio_in ();
+
++ if(!proc_mkdir("driver/ucb1400",NULL)) return -EIO;
++ if(!create_proc_read_entry("driver/ucb1400/ac97",0,NULL,ac97_read_proc,&pxa_ac97_codec))
++ {
++ remove_proc_entry("driver/ucb1400",NULL);
++ return -EIO;
++ }
++
+ ac97_audio_state.dev_dsp = register_sound_dsp(&ac97_audio_fops, -1);
+ pxa_ac97_codec.dev_mixer = register_sound_mixer(&mixer_fops, -1);
+
+@@ -345,6 +353,8 @@ static void __exit pxa_ac97_exit(void)
+ {
+ unregister_sound_dsp(ac97_audio_state.dev_dsp);
+ unregister_sound_mixer(pxa_ac97_codec.dev_mixer);
++ remove_proc_entry("driver/ucb1400/ac97",NULL);
++ remove_proc_entry("driver/ucb1400",NULL);
+ pxa_ac97_put();
+ }
+
+Index: linux-2.6.15gum/sound/oss/pxa-audio.c
+===================================================================
+--- linux-2.6.15gum.orig/sound/oss/pxa-audio.c
++++ linux-2.6.15gum/sound/oss/pxa-audio.c
+@@ -293,8 +293,6 @@ static int audio_write(struct file *file
+ audio_stream_t *s = state->output_stream;
+ int chunksize, ret = 0;
+
+- if (ppos != &file->f_pos)
+- return -ESPIPE;
+ if (s->mapped)
+ return -ENXIO;
+ if (!s->buffers && audio_setup_buf(s))
+@@ -365,8 +363,6 @@ static int audio_read(struct file *file,
+ audio_stream_t *s = state->input_stream;
+ int chunksize, ret = 0;
+
+- if (ppos != &file->f_pos)
+- return -ESPIPE;
+ if (s->mapped)
+ return -ENXIO;
+ if (!s->buffers && audio_setup_buf(s))
+@@ -684,6 +680,9 @@ static int audio_ioctl( struct inode *in
+ file->f_flags |= O_NONBLOCK;
+ return 0;
+
++ case SNDCTL_DSP_GETODELAY:
++ printk("%s: GETODELAY not implemented!\n",__FILE__);
++
+ case SNDCTL_DSP_RESET:
+ if (file->f_mode & FMODE_WRITE)
+ audio_clear_buf(os);
diff --git a/packages/linux/linux-gumstix-2.6.15/bkpxa-pxa-ac97.patch b/packages/linux/linux-gumstix-2.6.15/bkpxa-pxa-ac97.patch
new file mode 100644
index 0000000000..efb7e73e15
--- /dev/null
+++ b/