diff --git a/include/sound/soc.h b/include/sound/soc.h
index 36c547f..e952b52 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -21,7 +21,7 @@
 #include <sound/control.h>
 #include <sound/ac97_codec.h>
 
-#define SND_SOC_VERSION "0.9rc2"
+#define SND_SOC_VERSION "0.9rc4"
 
 /*
  * Convenience kcontrol builders
@@ -52,10 +52,10 @@
 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .info = snd_soc_info_volsw_ext, \
   .get = xhandler_get, .put = xhandler_put, \
   .private_value =  SOC_SINGLE_VALUE_EXT(xreg, xmask, xinvert) }
-#define SOC_SINGLE_BOOL_EXT(xname, xreg, xinvert, xhandler_get, xhandler_put) \
+#define SOC_SINGLE_BOOL_EXT(xname, xdata, xhandler_get, xhandler_put) \
 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .info = snd_soc_info_bool_ext, \
   .get = xhandler_get, .put = xhandler_put, \
-  .private_value =  SOC_SINGLE_VALUE_EXT(xreg, 0, xinvert) }
+  .private_value = xdata }
 #define SOC_ENUM_EXT(xname, xenum, xhandler_get, xhandler_put) \
 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .info = snd_soc_info_enum_ext, \
   .get = xhandler_get, .put = xhandler_put, \
diff --git a/sound/soc/pxa/Kconfig b/sound/soc/pxa/Kconfig
index 183acd7..8b3ba9c 100644
--- a/sound/soc/pxa/Kconfig
+++ b/sound/soc/pxa/Kconfig
@@ -28,12 +28,13 @@ config SND_PXA2xx_SOC_MAINSTONE
 	  Say Y if you want to add support for SoC audio on Mainstone.
 
 config SND_PXA2xx_SOC_MAINSTONE_WM8753
-	tristate "SoC I2S/SSP Audio support for Intel Mainstone - testing"
+	tristate "SoC I2S/SSP Audio support for Intel Mainstone - WM8753"
 	depends on SND_PXA2xx_SOC
 	select SND_PXA2xx_SOC_I2S
 	select SND_PXA2xx_SOC_SSP
 	help
-	  Say Y if you want to add support for SoC audio on Mainstone.
+	  Say Y if you want to add support for SoC audio on Mainstone
+	  with the WM8753.
 
 config SND_PXA2xx_SOC_CORGI
 	tristate "SoC Audio support for Corgi"
diff --git a/sound/soc/pxa/Makefile b/sound/soc/pxa/Makefile
index 7b2c7ba..91c72d9 100644
--- a/sound/soc/pxa/Makefile
+++ b/sound/soc/pxa/Makefile
@@ -12,12 +12,12 @@ obj-$(CONFIG_SND_PXA2xx_SOC_SSP) += snd-
 # PXA Machine Support
 snd-soc-corgi-objs := corgi.o
 snd-soc-mainstone-objs := mainstone.o
-snd-soc-mainstone-test-objs := mainstone.o
+snd-soc-mainstone-wm8753-objs := mainstone_wm8753.o
 snd-soc-tosa-objs := tosa.o
 snd-soc-spitz-objs := spitz.o
 
 obj-$(CONFIG_SND_PXA2xx_SOC_CORGI) += snd-soc-corgi.o
-obj-$(CONFIG_SND_PXA2xx_MAINSTONE) += snd-soc-mainstone.o
-obj-$(CONFIG_SND_PXA2xx_MAINSTONE_TEST) += snd-soc-mainstone.o
+obj-$(CONFIG_SND_PXA2xx_SOC_MAINSTONE) += snd-soc-mainstone.o
+obj-$(CONFIG_SND_PXA2xx_SOC_MAINSTONE_WM8753) += snd-soc-mainstone-wm8753.o
 obj-$(CONFIG_SND_PXA2xx_SOC_TOSA) += snd-soc-tosa.o
 obj-$(CONFIG_SND_PXA2xx_SOC_SPITZ) += snd-soc-spitz.o
diff --git a/sound/soc/pxa/corgi.c b/sound/soc/pxa/corgi.c
index 75eb086..3d1226b 100644
--- a/sound/soc/pxa/corgi.c
+++ b/sound/soc/pxa/corgi.c
@@ -39,47 +39,30 @@
 #include <asm/arch/corgi.h>
 //#include <asm/arch/spitz.h>
 
-
 #include <asm/arch/audio.h>
 
 #include "../codecs/wm8731.h"
 #include "pxa2xx-pcm.h"
 
-/*
- * Debug
- */
- 
-#define PFX "corgi-soc"
-#define CORGI_DEBUG 0
-
-#ifdef CORGI_DEBUG
-#define dbg(format, arg...) printk(KERN_DEBUG PFX ": " format "\n" , ## arg)
-#else
-#define dbg(format, arg...) do {} while (0)
-#endif
-#define err(format, arg...) printk(KERN_ERR PFX ": " format "\n" , ## arg)
-#define info(format, arg...) printk(KERN_INFO PFX ": " format "\n" , ## arg)
-#define warn(format, arg...) printk(KERN_WARNING PFX ": " format "\n" , ## arg)
-
-static struct timer_list corgi_hp_timer;
+static struct workqueue_struct *corgi_hp_workq = NULL;
+static struct work_struct corgi_hp_event_work;
 
 static irqreturn_t corgi_hp_isr(int irq, void *dev_id, struct pt_regs *fp)
 {
 	/* Delay the event slightly to debounce */
-	mod_timer(&corgi_hp_timer, jiffies + msecs_to_jiffies(500));
+	queue_delayed_work(corgi_hp_workq, &corgi_hp_event_work, jiffies + msecs_to_jiffies(500));
 
 	return IRQ_HANDLED;
 }
 
 #define READ_GPIO_BIT(x)    (GPLR(x) & GPIO_bit(x))
 
-static void corgi_hp_event(unsigned long data)
+static void corgi_hp_work(void *data)
 {
 	int hp_status = (READ_GPIO_BIT(CORGI_GPIO_AK_INT) != 0);
 	struct snd_soc_codec *codec = (struct snd_soc_codec *)data;
 	
 	printk("HP Status: %d\n", hp_status);
-
 	corgikbd_report_hp(hp_status);
 	
 	/* FIXME - Richard can you check, this will change dpm status */
@@ -100,18 +83,19 @@ static void corgi_hp_event(unsigned long
 int corgi_get_snd_scoop(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
 {
 	unsigned short reg = kcontrol->private_value;
-	ucontrol->value.integer.value[0] = ((read_scoop_reg(&corgiscoop_device.dev, SCOOP_GPWR) & reg) != 0);
+	
+	ucontrol->value.integer.value[0] = ((read_scoop_reg(&corgiscoop_device.dev, SCOOP_GPWR) & reg) != 1);
 	return 0;
 }
 
 int corgi_put_snd_scoop(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
 {
-	unsigned short reg = kcontrol->private_value;
-
+	unsigned short reg = kcontrol->private_value & 0xffff;
+	
 	if (ucontrol->value.integer.value[0])
-		set_scoop_gpio(&corgiscoop_device.dev, reg);
-	else
 		reset_scoop_gpio(&corgiscoop_device.dev, reg);
+	else
+		set_scoop_gpio(&corgiscoop_device.dev, reg);
 	return 0;
 }
 
@@ -141,10 +125,10 @@ static const char* intercon[][3] = {
 };
 
 static const snd_kcontrol_new_t wm8731_corgi_controls[] = {
-	SOC_SINGLE_BOOL_EXT("Left Mute Switch", CORGI_SCP_MUTE_L, 1, corgi_get_snd_scoop, corgi_put_snd_scoop),
-	SOC_SINGLE_BOOL_EXT("Right Mute Switch", CORGI_SCP_MUTE_R, 1, corgi_get_snd_scoop, corgi_put_snd_scoop),
-	SOC_SINGLE_BOOL_EXT("Speaker Mute Switch", CORGI_SCP_APM_ON, 1, corgi_get_snd_scoop, corgi_put_snd_scoop),
-	SOC_SINGLE_BOOL_EXT("Mic Bias Switch", CORGI_SCP_MIC_BIAS, 1, corgi_get_snd_scoop, corgi_put_snd_scoop),
+	SOC_SINGLE_BOOL_EXT("Left Mute Switch", CORGI_SCP_MUTE_L, corgi_get_snd_scoop, corgi_put_snd_scoop),
+	SOC_SINGLE_BOOL_EXT("Right Mute Switch", CORGI_SCP_MUTE_R, corgi_get_snd_scoop, corgi_put_snd_scoop),
+	SOC_SINGLE_BOOL_EXT("Speaker Mute Switch", CORGI_SCP_APM_ON, corgi_get_snd_scoop, corgi_put_snd_scoop),
+	SOC_SINGLE_BOOL_EXT("Mic Bias Switch", CORGI_SCP_MIC_BIAS, corgi_get_snd_scoop, corgi_put_snd_scoop),
 };
 
 /*
@@ -173,7 +157,8 @@ static int corgi_wm8731_init(struct snd_
 		snd_soc_dpm_connect_input(codec, intercon[i][0], intercon[i][1], intercon[i][2]);
 	}
 	
-	corgi_hp_timer.data = (unsigned long)codec;
+	INIT_WORK(&corgi_hp_event_work, corgi_hp_work, codec);
+	corgi_hp_workq = create_singlethread_workqueue("corgihp");
 	snd_soc_dpm_sync(codec);
 	return 0;
 }
@@ -216,9 +201,6 @@ static int __init corgi_init(void) 
 	}
 	set_irq_type(CORGI_IRQ_GPIO_AK_INT, IRQT_BOTHEDGE);
 
-	init_timer(&corgi_hp_timer);
-	corgi_hp_timer.function = corgi_hp_event;
-
 	corgi_snd_device = platform_device_alloc("soc-audio", -1);
 	if (!corgi_snd_device) {
 		free_irq(CORGI_IRQ_GPIO_AK_INT, corgi_snd_device);
@@ -238,7 +220,8 @@ static int __init corgi_init(void) 
 static void __exit corgi_exit(void) 
 {
 	free_irq(CORGI_IRQ_GPIO_AK_INT, corgi_snd_device);
-	del_timer_sync(&corgi_hp_timer);
+	if(corgi_hp_workq)
+		destroy_workqueue(corgi_hp_workq);
 	platform_device_unregister(corgi_snd_device);
 }
 
diff --git a/sound/soc/pxa/spitz.c b/sound/soc/pxa/spitz.c
index 9e0c929..27f6f50 100644
--- a/sound/soc/pxa/spitz.c
+++ b/sound/soc/pxa/spitz.c
@@ -141,10 +141,10 @@ static const char* intercon[][3] = {
 };
 
 static const snd_kcontrol_new_t wm8750_corgi_controls[] = {
-	SOC_SINGLE_BOOL_EXT("Left Mute Switch", CORGI_SCP_MUTE_L, 1, corgi_get_snd_scoop, corgi_put_snd_scoop),
-	SOC_SINGLE_BOOL_EXT("Right Mute Switch", CORGI_SCP_MUTE_R, 1, corgi_get_snd_scoop, corgi_put_snd_scoop),
-	SOC_SINGLE_BOOL_EXT("Speaker Mute Switch", CORGI_SCP_APM_ON, 1, corgi_get_snd_scoop, corgi_put_snd_scoop),
-	SOC_SINGLE_BOOL_EXT("Mic Bias Switch", CORGI_SCP_MIC_BIAS, 1, corgi_get_snd_scoop, corgi_put_snd_scoop),
+	SOC_SINGLE_BOOL_EXT("Left Mute Switch", CORGI_SCP_MUTE_L, corgi_get_snd_scoop, corgi_put_snd_scoop),
+	SOC_SINGLE_BOOL_EXT("Right Mute Switch", CORGI_SCP_MUTE_R, corgi_get_snd_scoop, corgi_put_snd_scoop),
+	SOC_SINGLE_BOOL_EXT("Speaker Mute Switch", CORGI_SCP_APM_ON, corgi_get_snd_scoop, corgi_put_snd_scoop),
+	SOC_SINGLE_BOOL_EXT("Mic Bias Switch", CORGI_SCP_MIC_BIAS, corgi_get_snd_scoop, corgi_put_snd_scoop),
 };
 
 /*
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 31325e7..04c9b13 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -205,7 +205,7 @@ static int soc_pcm_open(snd_pcm_substrea
 		}
 	}
 
-	if(machine->ops->startup) {
+	if(machine->ops && machine->ops->startup) {
 		if((ret = machine->ops->startup(substream)) < 0) {
 			printk(KERN_ERR "soc: %s startup failed\n", machine->name);
 			goto machine_err;
@@ -227,7 +227,7 @@ pcm_err:
 		rtd->pcm_c->ops.shutdown(substream);
 	
 machine_err:
-	if(machine->ops->shutdown)
+	if(machine->ops && machine->ops->shutdown)
 		machine->ops->shutdown(substream);
 	
 platform_err:
@@ -255,7 +255,7 @@ static int soc_pcm_close(snd_pcm_substre
 	if(rtd->pcm_c->ops.shutdown)
 		rtd->pcm_c->ops.shutdown(substream);
 	
-	if(machine->ops->shutdown)
+	if(machine->ops && machine->ops->shutdown)
 		machine->ops->shutdown(substream);
 	
 	if(platform->pcm_ops->close)
@@ -353,7 +353,7 @@ static int soc_pcm_hw_params(snd_pcm_sub
 	if(codec->dpm_event)
 		codec->dpm_event(codec, SNDRV_CTL_POWER_D1);
 	
-	snd_soc_dpm_codec_event(codec, SNDRV_CTL_POWER_D1);
+	snd_soc_dpm_codec_event(codec, SNDRV_CTL_POWER_D0);
 	if(substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
 		snd_soc_dpm_stream_event(codec, rtd->pcm_c->playback.sname, SND_SOC_DPM_STREAM_START);
 	else
@@ -362,7 +362,7 @@ static int soc_pcm_hw_params(snd_pcm_sub
 	if(codec->dpm_event)
 		codec->dpm_event(codec, SNDRV_CTL_POWER_D0);
 	snd_soc_dpm_codec_mute(codec, 0);
-	codec->dpm_state = SNDRV_CTL_POWER_D0;//liam
+	codec->dpm_state = SNDRV_CTL_POWER_D0;
 	return ret;
 	
 platform_err:
@@ -411,7 +411,7 @@ static int soc_pcm_hw_free(snd_pcm_subst
 	if(codec->dpm_event)
 		codec->dpm_event(codec, SNDRV_CTL_POWER_D3hot);
 	
-	codec->dpm_state = SNDRV_CTL_POWER_D3hot;//liam
+	codec->dpm_state = SNDRV_CTL_POWER_D3hot;
 	return 0;
 }
 
@@ -520,7 +520,7 @@ static int soc_resume(struct platform_de
 	}
 	
 	if(codec->suspend_streams) {
-		snd_soc_dpm_codec_event(codec, SNDRV_CTL_POWER_D1);
+		snd_soc_dpm_codec_event(codec, SNDRV_CTL_POWER_D0);
 		snd_soc_dpm_codec_mute(codec, 0);
 	}
 	
diff --git a/sound/soc/soc-dpm.c b/sound/soc/soc-dpm.c
index 6a023ee..27d6364 100644
--- a/sound/soc/soc-dpm.c
+++ b/sound/soc/soc-dpm.c
@@ -917,7 +917,7 @@ int snd_soc_dpm_codec_event(struct snd_s
 	struct list_head *l = NULL;	
 	int pm = 0, active = 0;
 
-	if(event == SNDRV_CTL_POWER_D1) {
+	if(event == SNDRV_CTL_POWER_D0) {
 		if(codec->active_streams)
 			return 0;
 		pm = 1;

