diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h
index 689851a..05bc7de 100644
--- a/include/sound/soc-dapm.h
+++ b/include/sound/soc-dapm.h
@@ -38,10 +38,7 @@ #define SND_SOC_NOPM	-1
  *     Enabled when stream playback/capture is started.  
  */
 
-/* codec domain - vmid, vref handled by the codec driver */  
-#define SND_SOC_DAPM_CLOCK(wname, wreg, wshift, winvert) \
-{.id = snd_soc_dapm_clock, .name = wname, .reg = wreg, .shift = wshift, \
- .invert = winvert, .kcontrols = NULL, .num_kcontrols = 0}
+/* codec domain - vmid, vref, clock handled by the codec driver */  
 /* not a true power register, but is used by dapm to minimise pops */ 
 #define SND_SOC_DAPM_MUTE(wname, wreg, wshift, winvert) \
 {.id = snd_soc_dapm_mute, .name = wname, .reg = wreg, .shift = wshift, \
@@ -169,7 +166,6 @@ void snd_soc_dapm_free(struct snd_soc_de
 /* dapm events */
 int snd_soc_dapm_stream_event(struct snd_soc_codec *codec, char *stream, 
 	int event);
-int snd_soc_dapm_codec_event(struct snd_soc_codec *codec, int event);
 int snd_soc_dapm_codec_mute(struct snd_soc_codec *codec, int mute);
 
 /* dapm sys fs - used by the core */
@@ -190,8 +186,6 @@ enum snd_soc_dapm_type {
 	snd_soc_dapm_pga,
 	snd_soc_dapm_adc,
 	snd_soc_dapm_dac,
-	snd_soc_dapm_clock,
-	snd_soc_dapm_vref,
 	snd_soc_dapm_micbias,
 	snd_soc_dapm_mute,
 	snd_soc_dapm_mic,
diff --git a/include/sound/soc.h b/include/sound/soc.h
index bfd1c0b..b6caeab 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -21,7 +21,7 @@ #include <sound/pcm.h>
 #include <sound/control.h>
 #include <sound/ac97_codec.h>
 
-#define SND_SOC_VERSION "0.10rc8"
+#define SND_SOC_VERSION "0.10rc9"
 
 /*
  * Convenience kcontrol builders
@@ -269,6 +269,7 @@ struct snd_soc_pcm_codec {
 		unsigned int clk);
 	unsigned int mclk;
 	unsigned int active;
+	unsigned char pop_wait:1;
 	
 	/* private data */
 	void *priv;
diff --git a/sound/soc/codecs/ak4535.c b/sound/soc/codecs/ak4535.c
index d854bfb..e5167c6 100644
--- a/sound/soc/codecs/ak4535.c
+++ b/sound/soc/codecs/ak4535.c
@@ -205,7 +205,6 @@ static const snd_kcontrol_new_t ak4535_l
 
 /* ak4535 dapm widgets */
 static const struct snd_soc_dapm_widget ak4535_dapm_widgets[] = {	
-	SND_SOC_DAPM_CLOCK("AK4535 Clock", AK4535_PM1, 7, 1),
 	SND_SOC_DAPM_MUTE("DAC Mute", AK4535_DAC, 5, 1),
 	SND_SOC_DAPM_MIXER("Stereo Mixer", SND_SOC_NOPM, 0, 0, 
 		&ak4535_stereo_mixer_controls[0], ARRAY_SIZE(ak4535_stereo_mixer_controls)),
@@ -401,10 +400,12 @@ static int ak4535_dapm_event(struct snd_
 		case SNDRV_CTL_POWER_D3hot: /* Off, with power */
 			/* everything off except vref/vmid, dac mute, inactive */
 			ak4535_write(codec, AK4535_PM1, 0x80);
+			ak4535_write(codec, AK4535_PM2, 0x0);
 			break;
 		case SNDRV_CTL_POWER_D3cold: /* Off, without power */
 			/* everything off, inactive */
 			ak4535_write(codec, AK4535_PM1, 0x0);
+			ak4535_write(codec, AK4535_PM2, 0x80);
 			break;
 	}
 	codec->dapm_state = event;
@@ -516,7 +517,6 @@ static struct i2c_client client_template
 
 /* If the i2c layer weren't so broken, we could pass this kind of data
    around */
-
 static int ak4535_codec_probe(struct i2c_adapter *adap, int addr, int kind)
 {
 	struct snd_soc_device *socdev = ak4535_socdev;
diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c
index ffd0309..bb315cd 100644
--- a/sound/soc/codecs/wm8731.c
+++ b/sound/soc/codecs/wm8731.c
@@ -32,7 +32,7 @@ #include <sound/initval.h>
 #include "wm8731.h"
 
 #define AUDIO_NAME "wm8731"
-#define WM8731_VERSION "0.8"
+#define WM8731_VERSION "0.9"
 
 /*
  * Debug
@@ -242,7 +242,6 @@ static int wm8731_add_controls(struct sn
 	return 0;
 }
 
-
 /* Output Mixer */
 static const snd_kcontrol_new_t wm8731_output_mixer_controls[] = {
 SOC_DAPM_SINGLE("Line Bypass Switch", WM8731_APANA, 3, 1, 0),
@@ -256,8 +255,6 @@ SOC_DAPM_ENUM("Input Select", wm8731_enu
 
 
 static const struct snd_soc_dapm_widget wm8731_dapm_widgets[] = {
-SND_SOC_DAPM_CLOCK("WM8731 Clock", WM8731_PWR, 6, 1),
-SND_SOC_DAPM_CLOCK("WM8731 Osc", WM8731_PWR, 5, 1),
 SND_SOC_DAPM_MUTE("DAC Mute", WM8731_APDIGI, 3, 0),
 SND_SOC_DAPM_MIXER("Output Mixer", WM8731_PWR, 4, 1, &wm8731_output_mixer_controls[0], 
 	ARRAY_SIZE(wm8731_output_mixer_controls)),
@@ -365,12 +362,12 @@ static const struct _coeff_div coeff_div
 static int get_coeff(int mclk, int rate)
 {
 	int i;
-	
+
 	for (i = 0; i < ARRAY_SIZE(coeff_div); i++) {
 		if (coeff_div[i].rate == rate && coeff_div[i].mclk == mclk)
 			return i;
 	}
-	return -EINVAL;
+	return 0;
 }
 
 static unsigned int wm8731_config_sysclk(struct snd_soc_pcm_codec* pcm_codec, 
@@ -392,10 +389,6 @@ static int wm8731_pcm_prepare(snd_pcm_su
 	u16 iface = 0, bfs, srate;
 	int i = get_coeff(rtd->pcm_c->mclk, snd_soc_get_rate(rtd->pcm_c->hw_runtime.hwpcmrate));
 	
-	/* is coefficient valid ? */
-	if(i < 0)
-		return i;
-	
 	bfs = SND_SOC_FSBD_REAL(rtd->pcm_c->hw_runtime.hwbfs);
 	
 	/* set master/slave audio interface */
@@ -459,16 +452,18 @@ static int wm8731_pcm_prepare(snd_pcm_su
 			
 	/* set face */
 	wm8731_write(codec, WM8731_IFACE, iface);
-
 	return 0;
 }
 
 static int wm8731_dapm_event(struct snd_soc_codec *codec, int event)
 {
+	u16 reg = wm8731_read_reg_cache(codec, WM8731_PWR) & 0xff1f;
+	
 	switch (event) {
 		case SNDRV_CTL_POWER_D0: /* full On */
 			/* vref/mid, clk and osc on, dac unmute, active */
 			wm8731_write(codec, WM8731_ACTIVE, 0x0001);
+			wm8731_write(codec, WM8731_PWR, reg);
 			break;
 		case SNDRV_CTL_POWER_D1: /* partial On */
 		case SNDRV_CTL_POWER_D2: /* partial On */
@@ -476,7 +471,7 @@ static int wm8731_dapm_event(struct snd_
 		case SNDRV_CTL_POWER_D3hot: /* Off, with power */
 			/* everything off except vref/vmid, dac mute, inactive */
 			wm8731_write(codec, WM8731_ACTIVE, 0x0);
-			wm8731_write(codec, WM8731_PWR, 0xff7f);
+			wm8731_write(codec, WM8731_PWR, reg | 0x0060);
 			break;
 		case SNDRV_CTL_POWER_D3cold: /* Off, without power */
 			/* everything off, dac mute, inactive */
diff --git a/sound/soc/codecs/wm8750.c b/sound/soc/codecs/wm8750.c
index e417511..d0c4af3 100644
--- a/sound/soc/codecs/wm8750.c
+++ b/sound/soc/codecs/wm8750.c
@@ -32,7 +32,7 @@ #include <sound/initval.h>
 #include "wm8750.h"
 
 #define AUDIO_NAME "WM8750"
-#define WM8750_VERSION "0.7"
+#define WM8750_VERSION "0.8"
 
 /*
  * Debug
@@ -427,7 +427,6 @@ static const snd_kcontrol_new_t wm8750_m
 SOC_DAPM_ENUM("Route", wm8750_enum[16]);
 
 static const struct snd_soc_dapm_widget wm8750_dapm_widgets[] = {
-	SND_SOC_DAPM_CLOCK("WM8750 Clock", WM8750_PWR1, 0, 1),
 	SND_SOC_DAPM_MUTE("DAC Mute", WM8750_ADCDAC, 3, 0),
 	SND_SOC_DAPM_MIXER("Left Mixer", SND_SOC_NOPM, 0, 0,
 		&wm8750_left_mixer_controls[0], ARRAY_SIZE(wm8750_left_mixer_controls)),
@@ -767,7 +766,7 @@ static int wm8750_pcm_prepare(snd_pcm_su
 
 static int wm8750_dapm_event(struct snd_soc_codec *codec, int event)
 {
-	u16 pwr_reg = wm8750_read_reg_cache(codec, WM8750_PWR1) & 0xfe3f;
+	u16 pwr_reg = wm8750_read_reg_cache(codec, WM8750_PWR1) & 0xfe3e;
 	
 	switch (event) {
 		case SNDRV_CTL_POWER_D0: /* full On */
@@ -777,14 +776,14 @@ static int wm8750_dapm_event(struct snd_
 		case SNDRV_CTL_POWER_D1: /* partial On */
 		case SNDRV_CTL_POWER_D2: /* partial On */
 			/* set vmid to 5k for quick power up */
-			wm8750_write(codec, WM8750_PWR1, pwr_reg | 0x01c0);
+			wm8750_write(codec, WM8750_PWR1, pwr_reg | 0x01c1);
 			break;
 		case SNDRV_CTL_POWER_D3hot: /* Off, with power */
 			/* mute dac and set vmid to 500k, enable VREF */
-			wm8750_write(codec, WM8750_PWR1, pwr_reg | 0x0140);
+			wm8750_write(codec, WM8750_PWR1, pwr_reg | 0x0141);
 			break;
 		case SNDRV_CTL_POWER_D3cold: /* Off, without power */
-			wm8750_write(codec, WM8750_PWR1, 0x0000);
+			wm8750_write(codec, WM8750_PWR1, 0x0001);
 			break;
 	}
 	codec->dapm_state = event;
diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c
index d03d700..e39787b 100644
--- a/sound/soc/codecs/wm8753.c
+++ b/sound/soc/codecs/wm8753.c
@@ -38,7 +38,7 @@ #include <sound/initval.h>
 #include "wm8753.h"
 
 #define AUDIO_NAME "wm8753"
-#define WM8753_VERSION "0.9"
+#define WM8753_VERSION "0.10"
 
 /*
  * Debug
@@ -540,7 +540,6 @@ static const snd_kcontrol_new_t wm8753_m
 SOC_DAPM_ENUM("Route", wm8753_enum[25]);
 
 static const struct snd_soc_dapm_widget wm8753_dapm_widgets[] = {
-SND_SOC_DAPM_CLOCK("WM8753 Clock", WM8753_PWR1, 0, 1),
 SND_SOC_DAPM_MUTE("DAC Mute", WM8753_DAC, 3, 0),
 SND_SOC_DAPM_MICBIAS("Mic Bias", WM8753_PWR1, 5, 0),
 SND_SOC_DAPM_MIXER("Left Mixer", WM8753_PWR4, 0, 0, &wm8753_left_mixer_controls[0], 
@@ -815,7 +814,7 @@ static u32 wm8753_config_pll(struct snd_
 	struct snd_soc_pcm_codec *pcm_codec, int pll, u32 speed)
 {
 	u16 reg;
-
+ 
     if (pll == 1) {
 		reg = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0xffef;
         if (!speed || pll == pcm_codec->mclk) {
@@ -832,7 +831,7 @@ static u32 wm8753_config_pll(struct snd_
                 if (pll_div[i].mclk == pcm_codec->mclk && pll_div[i].hz == speed)
                     break;
             }
-    
+
             /* set up N and K PLL divisor ratios */
             /* bits 8:5 = PLL_N, bits 3:0 = PLL_K[21:18] */
             value = (pll_div[i].n << 5) + ((pll_div[i].k & 0x3c0000) >> 18);  
@@ -1127,7 +1126,7 @@ static int wm8753_pcm_hifi_prepare(snd_p
 	/* is coefficient valid ? */
 	if((i = get_coeff(pll, rate)) < 0)
 		return i;
-		
+
 	srate = wm8753_read_reg_cache(codec, WM8753_SRATE1) & 0x01c0;
 	wm8753_write(codec, WM8753_SRATE1, srate | (coeff_div[i].sr << 1) | coeff_div[i].usb);
 
@@ -1189,7 +1188,7 @@ static int wm8753_pcm_hifi_prepare(snd_p
 		break;
 	}
 	wm8753_write(codec, WM8753_SRATE2, srate);
-	
+
 	/* clock inversion */
 	switch(rtd->pcm_c->hw_runtime.hwfmt & SND_SOC_HWFMT_INV_MASK) {
 		case SND_SOC_HWFMT_IB_IF:
@@ -1209,7 +1208,7 @@ static int wm8753_pcm_hifi_prepare(snd_p
 
 static int wm8753_dapm_event(struct snd_soc_codec *codec, int event)
 {
-	u16 pwr_reg = wm8753_read_reg_cache(codec, WM8753_PWR1) & 0xfe3f;
+	u16 pwr_reg = wm8753_read_reg_cache(codec, WM8753_PWR1) & 0xfe3e;
 
 	switch (event) {
 		case SNDRV_CTL_POWER_D0: /* full On */
@@ -1219,11 +1218,11 @@ static int wm8753_dapm_event(struct snd_
 		case SNDRV_CTL_POWER_D1: /* partial On */
 		case SNDRV_CTL_POWER_D2: /* partial On */
 			/* set vmid to 5k for quick power up */
-			wm8753_write(codec, WM8753_PWR1, pwr_reg | 0x01c0);
+			wm8753_write(codec, WM8753_PWR1, pwr_reg | 0x01c1);
 			break;
 		case SNDRV_CTL_POWER_D3hot: /* Off, with power */
 			/* mute dac and set vmid to 500k, enable VREF */
-			wm8753_write(codec, WM8753_PWR1, pwr_reg | 0x0140);
+			wm8753_write(codec, WM8753_PWR1, pwr_reg | 0x0141);
 			break;
 		case SNDRV_CTL_POWER_D3cold: /* Off, without power */
 			wm8753_write(codec, WM8753_PWR1, 0x0001);
diff --git a/sound/soc/codecs/wm8971.c b/sound/soc/codecs/wm8971.c
index 7bc972e..fb9dff2 100644
--- a/sound/soc/codecs/wm8971.c
+++ b/sound/soc/codecs/wm8971.c
@@ -33,7 +33,7 @@ #include <sound/initval.h>
 #include "wm8971.h"
 
 #define AUDIO_NAME "wm8971"
-#define WM8971_VERSION "0.5"
+#define WM8971_VERSION "0.6"
 
 
 #define PFX AUDIO_NAME
@@ -382,7 +382,6 @@ static const snd_kcontrol_new_t wm8971_m
 SOC_DAPM_ENUM("Route", wm8971_enum[13]);
 
 static const struct snd_soc_dapm_widget wm8971_dapm_widgets[] = {
-	SND_SOC_DAPM_CLOCK("WM8971 Clock", WM8971_PWR1, 0, 1),
 	SND_SOC_DAPM_MUTE("DAC Mute", WM8971_ADCDAC, 3, 0),
 	SND_SOC_DAPM_MIXER("Left Mixer", SND_SOC_NOPM, 0, 0, 
 		&wm8971_left_mixer_controls[0], ARRAY_SIZE(wm8971_left_mixer_controls)),
@@ -702,12 +701,12 @@ static int wm8971_pcm_prepare(snd_pcm_su
 
 static int wm8971_dapm_event(struct snd_soc_codec *codec, int event)
 {
-	u16 pwr_reg = wm8971_read_reg_cache(codec, WM8971_PWR1) & 0xfe3f;
+	u16 pwr_reg = wm8971_read_reg_cache(codec, WM8971_PWR1) & 0xfe3e;
 
 	switch (event) {
 		case SNDRV_CTL_POWER_D0: /* full On */
 			/* set vmid to 50k and unmute dac */
-			wm8971_write(codec, WM8971_PWR1, pwr_reg | 0x00c0);
+			wm8971_write(codec, WM8971_PWR1, pwr_reg | 0x00c1);
 			break;
 		case SNDRV_CTL_POWER_D1: /* partial On */
 		case SNDRV_CTL_POWER_D2: /* partial On */
@@ -719,7 +718,7 @@ static int wm8971_dapm_event(struct snd_
 			wm8971_write(codec, WM8971_PWR1, pwr_reg | 0x0140);
 			break;
 		case SNDRV_CTL_POWER_D3cold: /* Off, without power */
-			wm8971_write(codec, WM8971_PWR1, 0x0000);
+			wm8971_write(codec, WM8971_PWR1, 0x0001);
 			break;
 	}
 	codec->dapm_state = event;
diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c
index c680b7c..1f445fc 100644
--- a/sound/soc/codecs/wm9713.c
+++ b/sound/soc/codecs/wm9713.c
@@ -32,7 +32,7 @@ #include <sound/initval.h>
 #include <sound/soc.h>
 #include <sound/soc-dapm.h>
 
-#define WM9713_VERSION "0.3"
+#define WM9713_VERSION "0.4"
 
 static DECLARE_MUTEX(wm9713_sem);
 
@@ -782,6 +782,9 @@ found:
 		/* write the fractional k to the reg 0x46 pages */
 		reg2 = (pll[i].n << 12) | (pll[i].lf << 11) | (pll[i].sdm << 10) |
 			(pll[i].divsel << 9) | (pll[i].divctl << 8);
+#if 0
+		/* liam - I need to work out why we must set SEXT before 
+		 * activating the PLL. */
 		sext = ac97_read(codec, AC97_HANDSET_RATE) >> 8;
 			
 		reg = reg2 | (sext >>  4); /* SEXT [6:4] */
@@ -790,22 +793,23 @@ found:
 		reg = reg2 | (0x1 << 4) | (sext & 0xf); /* SEXT [3:0] */
 		ac97_write(codec, AC97_LINE1_LEVEL, reg);
 		
-		reg = reg2 | (0x2 << 4) | (pll[i].k >> 20); /* K [21:20] */
+#endif
+		reg = reg2 | (0x5 << 4) | (pll[i].k >> 20); /* K [21:20] */
 		ac97_write(codec, AC97_LINE1_LEVEL, reg);
 		
-		reg = reg2 | (0x3 << 4) | ((pll[i].k >> 16) & 0xf); /* K [19:16] */
+		reg = reg2 | (0x4 << 4) | ((pll[i].k >> 16) & 0xf); /* K [19:16] */
 		ac97_write(codec, AC97_LINE1_LEVEL, reg);
 		
-		reg = reg2 | (0x4 << 4) | ((pll[i].k >> 12) & 0xf); /* K [15:12] */
+		reg = reg2 | (0x3 << 4) | ((pll[i].k >> 12) & 0xf); /* K [15:12] */
 		ac97_write(codec, AC97_LINE1_LEVEL, reg);
 		
-		reg = reg2 | (0x5 << 4) | ((pll[i].k >> 8) & 0xf); /* K [11:8] */
+		reg = reg2 | (0x2 << 4) | ((pll[i].k >> 8) & 0xf); /* K [11:8] */
 		ac97_write(codec, AC97_LINE1_LEVEL, reg);
 		
-		reg = reg2 | (0x6 << 4) | ((pll[i].k >> 4) & 0xf); /* K [7:4] */
+		reg = reg2 | (0x1 << 4) | ((pll[i].k >> 4) & 0xf); /* K [7:4] */
 		ac97_write(codec, AC97_LINE1_LEVEL, reg);
 		
-		reg = reg2 | (0x7 << 4) | (pll[i].k & 0xf); /* K [3:0] */
+		reg = reg2 | (0x0 << 4) | (pll[i].k & 0xf); /* K [3:0] */
 		ac97_write(codec, AC97_LINE1_LEVEL, reg);
 	}
 	
diff --git a/sound/soc/pxa/corgi.c b/sound/soc/pxa/corgi.c
index 42b6ff2..cc33533 100644
--- a/sound/soc/pxa/corgi.c
+++ b/sound/soc/pxa/corgi.c
@@ -235,12 +235,17 @@ unsigned int corgi_config_sysclk(struct 
 	int rate, unsigned int hwfmt)
 {
 	if(hwfmt & SND_SOC_HWFMT_CBS_CFS) {
-		if(rtd->pcm_i->config_sysclk)
-			return rtd->pcm_i->config_sysclk(rtd->pcm_i, rate, 0);
+		/* corgi is i2s master */
+		switch(rate){
+		case 44100:
+		case 88200:
+			return rtd->pcm_c->config_sysclk(rtd->pcm_c, rate, 11289600);
+		default:
+			return rtd->pcm_c->config_sysclk(rtd->pcm_c, rate, 12288000);
+		}
 	} else {
 		/* corgi has a 12.235MHz sysclk - we round to a nice audio 12.288 */
-		if(rtd->pcm_c->config_sysclk)
-			return rtd->pcm_c->config_sysclk(rtd->pcm_c, rate, 12288000);
+		return rtd->pcm_c->config_sysclk(rtd->pcm_c, rate, 12288000);
 	}
 	
 	return 0;
diff --git a/sound/soc/pxa/mainstone_baseband.c b/sound/soc/pxa/mainstone_baseband.c
index e2dbea3..44d7355 100644
--- a/sound/soc/pxa/mainstone_baseband.c
+++ b/sound/soc/pxa/mainstone_baseband.c
@@ -220,15 +220,8 @@ static int mainstone_wm9713_init(struct 
 unsigned int mainstone_config_sysclk(struct snd_soc_pcm_runtime *rtd, 
 	int rate, unsigned int hwfmt)
 {
-	if(hwfmt & SND_SOC_HWFMT_CBS_CFS) {
-		if(rtd->pcm_i->config_sysclk)
-			return rtd->pcm_i->config_sysclk(rtd->pcm_i, rate, 0);
-	} else {
-		/* wm9713 has pll that generates mclk from 13MHz xtal */
-		if(rtd->pcm_c->config_sysclk)
-			return rtd->pcm_c->config_sysclk(rtd->pcm_c, rate, 13000000);
-	}
-	return 0;
+	/* wm8753 has pll that generates mclk from 13MHz xtal */
+	return rtd->pcm_c->config_sysclk(rtd->pcm_c, rate, 13000000);
 }
 
 static struct snd_soc_machine_config codecs[] = {
diff --git a/sound/soc/pxa/mainstone_bluetooth.c b/sound/soc/pxa/mainstone_bluetooth.c
index 54997d5..96a4015 100644
--- a/sound/soc/pxa/mainstone_bluetooth.c
+++ b/sound/soc/pxa/mainstone_bluetooth.c
@@ -220,15 +220,8 @@ #endif	
 unsigned int mainstone_config_sysclk(struct snd_soc_pcm_runtime *rtd, 
 	int rate, unsigned int hwfmt)
 {
-	if(hwfmt & SND_SOC_HWFMT_CBS_CFS) {
-		if(rtd->pcm_i->config_sysclk)
-			return rtd->pcm_i->config_sysclk(rtd->pcm_i, rate, 0);
-	} else {
-		/* wm9713 has pll that generates mclk from 13MHz xtal */
-		if(rtd->pcm_c->config_sysclk)
-			return rtd->pcm_c->config_sysclk(rtd->pcm_c, rate, 13000000);
-	}
-	return 0;
+	/* wm9713 has pll that generates mclk from 13MHz xtal */
+	return rtd->pcm_c->config_sysclk(rtd->pcm_c, rate, 13000000);
 }
 
 static struct snd_soc_machine_config codecs[] = {
diff --git a/sound/soc/pxa/mainstone_wm8753.c b/sound/soc/pxa/mainstone_wm8753.c
index 8dda76d..ca490b7 100644
--- a/sound/soc/pxa/mainstone_wm8753.c
+++ b/sound/soc/pxa/mainstone_wm8753.c
@@ -151,26 +151,8 @@ static int mainstone_wm8753_init(struct 
 unsigned int mainstone_config_sysclk(struct snd_soc_pcm_runtime *rtd, 
 	int rate, unsigned int hwfmt)
 {
-	if(hwfmt & SND_SOC_HWFMT_CBS_CFS) {
-		if(rtd->pcm_i->config_sysclk)
-			return rtd->pcm_i->config_sysclk(rtd->pcm_i, rate, 0);
-	} else {
-		/* wm8753 has pll that generates mclk from 13MHz xtal */
-		if(rtd->pcm_c->config_sysclk)
-			return rtd->pcm_c->config_sysclk(rtd->pcm_c, rate, 13000000);
-	}
-	
-	return 0;
-}
-
-unsigned int mainstone_config_vsysclk(struct snd_soc_pcm_runtime *rtd, 
-	int rate, unsigned int hwfmt)
-{
 	/* wm8753 has pll that generates mclk from 13MHz xtal */
-	if(rtd->pcm_c->config_sysclk)
-		return rtd->pcm_c->config_sysclk(rtd->pcm_c, rate, 13000000);
-	
-	return 0;
+	return rtd->pcm_c->config_sysclk(rtd->pcm_c, rate, 13000000);
 }
 
 static struct snd_soc_machine_config codecs[] = {
@@ -185,7 +167,7 @@ static struct snd_soc_machine_config cod
 	.name = "WM8753", 
 	.sname = "WM8753 Voice",
 	.iface = &pxa_ssp_interface[1],
-	.config_sysclk = mainstone_config_vsysclk,
+	.config_sysclk = mainstone_config_sysclk,
 },
 };
 
diff --git a/sound/soc/pxa/mainstone_wm8974.c b/sound/soc/pxa/mainstone_wm8974.c
index 0c72f03..b0cbc52 100644
--- a/sound/soc/pxa/mainstone_wm8974.c
+++ b/sound/soc/pxa/mainstone_wm8974.c
@@ -153,16 +153,10 @@ #endif
 unsigned int mainstone_config_sysclk(struct snd_soc_pcm_runtime *rtd, 
 	int rate, unsigned int hwfmt)
 {
-	//if(hwfmt & SND_SOC_HWFMT_CBS_CFS) {
-		if(rtd->pcm_i->config_sysclk)
-			rtd->pcm_i->config_sysclk(rtd->pcm_i, rate, 0);
-//	} else {
-		/* wm8974 has pll that generates mclk from 13MHz xtal */
-		if(rtd->pcm_c->config_sysclk)
-			return rtd->pcm_c->config_sysclk(rtd->pcm_c, rate, 12288000);
-	//}
+	/* we have a PLL */
+	if(rtd->pcm_c->config_sysclk)
+		return rtd->pcm_c->config_sysclk(rtd->pcm_c, rate, 12288000);
 	
-	return 0;
 }
 
 static struct snd_soc_machine_config codecs[] = {
diff --git a/sound/soc/pxa/mainstone_wm9713.c b/sound/soc/pxa/mainstone_wm9713.c
index db0e4bf..f5393a0 100644
--- a/sound/soc/pxa/mainstone_wm9713.c
+++ b/sound/soc/pxa/mainstone_wm9713.c
@@ -143,9 +143,7 @@ static int mainstone_wm9713_init(struct 
 unsigned int mainstone_config_sysclk(struct snd_soc_pcm_runtime *rtd, 
 	int rate, unsigned int hwfmt)
 {
-	if(rtd->pcm_c->config_sysclk)
-		return rtd->pcm_c->config_sysclk(rtd->pcm_c, rate, 24576000);
-	return 0;
+	return rtd->pcm_c->config_sysclk(rtd->pcm_c, rate, 24576000);
 }
 
 static struct snd_soc_machine_config codecs[] = {
diff --git a/sound/soc/pxa/pxa2xx-i2s.c b/sound/soc/pxa/pxa2xx-i2s.c
index 0a0b61e..fa29966 100644
--- a/sound/soc/pxa/pxa2xx-i2s.c
+++ b/sound/soc/pxa/pxa2xx-i2s.c
@@ -151,7 +151,6 @@ static int pxa2xx_i2s_hw_params(snd_pcm_
 		pxa_i2s.master = 1;
 	
 	if (pxa_i2s.master && !extclk){
-		printk("master\n");
 		pxa_gpio_mode(gpio_bus[pxa_i2s.master].sys);
 	}
 	
diff --git a/sound/soc/pxa/spitz.c b/sound/soc/pxa/spitz.c
index 3d9d6e9..c756ce5 100644
--- a/sound/soc/pxa/spitz.c
+++ b/sound/soc/pxa/spitz.c
@@ -259,16 +259,8 @@ static int spitz_wm8750_init(struct snd_
 unsigned int spitz_config_sysclk(struct snd_soc_pcm_runtime *rtd, 
 	int rate, unsigned int hwfmt)
 {
-	if(hwfmt & SND_SOC_HWFMT_CBS_CFS) {
-		if(rtd->pcm_i->config_sysclk)
-			return rtd->pcm_i->config_sysclk(rtd->pcm_i, rate, 0);
-	} else {
-		/* spitz has a 12.235MHz sysclk - we round to a nice audio 12.288 */
-		if(rtd->pcm_c->config_sysclk)
-			return rtd->pcm_c->config_sysclk(rtd->pcm_c, rate, 12288000);
-	}
-	
-	return 0;
+	/* spitz has a 12.235MHz sysclk - we round to a nice audio 12.288 */
+	return rtd->pcm_c->config_sysclk(rtd->pcm_c, rate, 12288000);
 }
 
 static struct snd_soc_machine_config codecs = {
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 55663b5..2491bb6 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -52,6 +52,9 @@ #define iface_name(x) \
 	((x) == SND_SOC_SSP) ? "ssp" : NULL)
 	
 static DECLARE_MUTEX(soc_pcm_sem);
+static struct workqueue_struct *soc_workq = NULL;
+static struct work_struct soc_stream_work;
+static DECLARE_WAIT_QUEUE_HEAD(soc_pm_waitq);
 
 static const unsigned int rates[] = {
 	5512, 8000, 11025, 16000, 22050, 32000, 44100,
@@ -64,6 +67,16 @@ static const unsigned char formats[] = {
 	18, 18, 18, 18
 };
 
+/*
+ * This is a timeout to powerdown a DAPM after a stream is finished - closed().
+ * It can be used to eliminate pops between different playback streams, e.g.
+ * between two audio tracks.
+ */  
+static int pmdown_time = 5000;
+module_param(pmdown_time, int, 0);
+MODULE_PARM_DESC(pmdown_time, "DAPM stream powerdown time (msecs)");
+
+
 #ifdef CONFIG_SND_AC97_BUS
 /* unregister ac97 codec */
 static int soc_ac97_dev_unregister(struct snd_soc_codec *codec)
@@ -430,9 +443,9 @@ static int soc_pcm_open(snd_pcm_substrea
 		up(&soc_pcm_sem);
 		return -ENODEV;
 	}
-	printk(KERN_INFO "soc: %s <-> %s info:\n", rtd->pcm_c->name, rtd->pcm_i->name);
-	/* tmp debug */
-	printk(KERN_INFO "soc: rate mask 0x%x \nsoc: min ch %d max ch %d\nsoc: min rate %d max rate %d\n",
+	
+	dbg("soc: %s <-> %s info:\n", rtd->pcm_c->name, rtd->pcm_i->name);
+	dbg("soc: rate mask 0x%x \nsoc: min ch %d max ch %d\nsoc: min rate %d max rate %d\n",
 		runtime->hw.rates, runtime->hw.channels_min,
 		runtime->hw.channels_max, runtime->hw.rate_min, runtime->hw.rate_max);
 
@@ -589,29 +602,39 @@ static int soc_pcm_hw_params(snd_pcm_sub
 		rtd->pcm_c->capture.active = 1;
 	rtd->pcm_c->active = 1;
 	
-	if(codec->dapm_state != SNDRV_CTL_POWER_D0) {
-
-		if(codec->dapm_event)
-			codec->dapm_event(codec, SNDRV_CTL_POWER_D1);
-		snd_soc_dapm_codec_event(codec, SNDRV_CTL_POWER_D0);
-		if(substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-			snd_soc_dapm_stream_event(codec, rtd->pcm_c->playback.sname, 
-				SND_SOC_DAPM_STREAM_START);
+	/* we only want to start a DAPM playback stream if we are not waiting
+	 * on an existing one stopping */
+	if(rtd->pcm_c->pop_wait) {
+		if(substream->stream == SNDRV_PCM_STREAM_CAPTURE)
+				snd_soc_dapm_stream_event(codec, rtd->pcm_c->capture.sname, 
+					SND_SOC_DAPM_STREAM_START);
 		else
-			snd_soc_dapm_stream_event(codec, rtd->pcm_c->capture.sname, 
-				SND_SOC_DAPM_STREAM_START);
-		
-		if(codec->dapm_event)
-			codec->dapm_event(codec, SNDRV_CTL_POWER_D0);
-		snd_soc_dapm_codec_mute(codec, 0);
-		codec->dapm_state = SNDRV_CTL_POWER_D0;
+			rtd->pcm_c->pop_wait = 0;
 	} else {
-		if(substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-			snd_soc_dapm_stream_event(codec, rtd->pcm_c->playback.sname, 
-				SND_SOC_DAPM_STREAM_START);
-		else
-			snd_soc_dapm_stream_event(codec, rtd->pcm_c->capture.sname, 
-				SND_SOC_DAPM_STREAM_START);
+		if(codec->dapm_state != SNDRV_CTL_POWER_D0) {
+	
+			if(codec->dapm_event)
+				codec->dapm_event(codec, SNDRV_CTL_POWER_D1);
+		
+			if(substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+				snd_soc_dapm_stream_event(codec, rtd->pcm_c->playback.sname, 
+					SND_SOC_DAPM_STREAM_START);
+			else
+				snd_soc_dapm_stream_event(codec, rtd->pcm_c->capture.sname, 
+					SND_SOC_DAPM_STREAM_START);
+			
+			if(codec->dapm_event)
+				codec->dapm_event(codec, SNDRV_CTL_POWER_D0);
+			snd_soc_dapm_codec_mute(codec, 0);
+			codec->dapm_state = SNDRV_CTL_POWER_D0;
+		} else {
+			if(substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+				snd_soc_dapm_stream_event(codec, rtd->pcm_c->playback.sname, 
+					SND_SOC_DAPM_STREAM_START);
+			else
+				snd_soc_dapm_stream_event(codec, rtd->pcm_c->capture.sname, 
+					SND_SOC_DAPM_STREAM_START);
+		}
 	}
 out:
 	up(&soc_pcm_sem);
@@ -633,6 +656,46 @@ codec_err:
 	return ret;
 }
 
+/* This shuts down the audio subsytem at a given time after a playback stream
+ * stops iff there no other playback streams running. It useful in stopping
+ * pops between audio tracks 
+ */
+static void asoc_work(void *data)
+{
+	struct snd_soc_device *socdev = data;
+	struct snd_soc_codec *codec = socdev->codec;
+	struct snd_soc_pcm_codec *pcm_c;
+	int i;
+
+	down(&soc_pcm_sem);
+	for(i = 0; i < codec->npcms; i++) {
+		pcm_c = &codec->pcms[i];
+		dbg("pop wq checking %s %s waiting: %s\n", pcm_c->playback.sname, 
+			pcm_c->playback.active ? "active" : "inactive",
+			pcm_c->pop_wait ? "yes" : "no");
+		
+		if(pcm_c->pop_wait == 1) {
+			
+			if(codec->active == 0){
+				dbg("pop wq mute %s %s\n", codec->name, pcm_c->playback.sname);
+				snd_soc_dapm_codec_mute(codec, 1);
+			}
+
+			pcm_c->pop_wait = 0;			
+			snd_soc_dapm_stream_event(codec, pcm_c->playback.sname, 
+				SND_SOC_DAPM_STREAM_STOP);
+	
+			if(codec->active == 0) {
+				dbg("pop wq D3 %s %s\n", codec->name, pcm_c->playback.sname);
+			 	if(codec->dapm_event)
+					codec->dapm_event(codec, SNDRV_CTL_POWER_D3hot);
+				codec->dapm_state = SNDRV_CTL_POWER_D3hot;
+			}
+		}
+	}
+	up(&soc_pcm_sem);
+}
+
 /* free buffers, can be called multiple times */
 static int soc_pcm_hw_free(snd_pcm_substream_t *substream)
 {
@@ -664,30 +727,35 @@ static int soc_pcm_hw_free(snd_pcm_subst
 		rtd->pcm_c->active = 0;
 		codec->active--;
 	}
-
+	
 	if(codec->active == 0) {
-		snd_soc_dapm_codec_mute(codec, 1);
-		snd_soc_dapm_codec_event(codec, SNDRV_CTL_POWER_D3hot);
+		if(substream->stream == SNDRV_PCM_STREAM_PLAYBACK){
+			/* start delayed pop wq here */
+			rtd->pcm_c->pop_wait = 1;
+			queue_delayed_work(soc_workq, &soc_stream_work, 
+				msecs_to_jiffies(pmdown_time));
 		
-		if(substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-			snd_soc_dapm_stream_event(codec, rtd->pcm_c->playback.sname, 
-				SND_SOC_DAPM_STREAM_STOP);
-		else
+		} else {
 			snd_soc_dapm_stream_event(codec, rtd->pcm_c->capture.sname, 
 				SND_SOC_DAPM_STREAM_STOP);
 	
-		if(codec->dapm_event)
-			codec->dapm_event(codec, SNDRV_CTL_POWER_D3hot);
-		codec->dapm_state = SNDRV_CTL_POWER_D3hot;
+			if(rtd->pcm_c->pop_wait == 0){
+				if(codec->dapm_event)
+					codec->dapm_event(codec, SNDRV_CTL_POWER_D3hot);
+				codec->dapm_state = SNDRV_CTL_POWER_D3hot;
+			}
+		}
 	} else {
-		if(substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-			snd_soc_dapm_stream_event(codec, rtd->pcm_c->playback.sname, 
-				SND_SOC_DAPM_STREAM_STOP);
-		else
+		if(substream->stream == SNDRV_PCM_STREAM_PLAYBACK){
+			/* start delayed pop wq here */
+			rtd->pcm_c->pop_wait = 1;
+			queue_delayed_work(soc_workq, &soc_stream_work, 
+				msecs_to_jiffies(pmdown_time));
+		} else
 			snd_soc_dapm_stream_event(codec, rtd->pcm_c->capture.sname, 
 				SND_SOC_DAPM_STREAM_STOP);
 	}
-	
+
 out:
 	up(&soc_pcm_sem);
 	return 0;
@@ -713,7 +781,6 @@ static int soc_suspend(struct platform_d
 	int i;
 	
 	snd_soc_dapm_codec_mute(codec, 1);
-	codec->suspend_dapm_state = codec->dapm_state;
 
 	if (machine->suspend_pre)
 		machine->suspend_pre(pdev, state);
@@ -728,6 +795,10 @@ static int soc_suspend(struct platform_d
 			iface->suspend(pdev, iface);
 	}
 
+	/* close any waiting streams and save state */
+	asoc_work(socdev);
+	codec->suspend_dapm_state = codec->dapm_state;
+	
 	for(i = 0; i < codec->npcms; i++) {
 		char *stream = codec->pcms[i].playback.sname;
 		if(stream != NULL)
@@ -771,7 +842,6 @@ static int soc_resume(struct platform_de
 			iface->resume(pdev, iface);
 	}
 
-	snd_soc_dapm_codec_event(codec, SNDRV_CTL_POWER_D3hot);
 	if (codec_dev->resume)
 		codec_dev->resume(pdev);
 
@@ -784,10 +854,8 @@ static int soc_resume(struct platform_de
 			snd_soc_dapm_stream_event(codec, stream, SND_SOC_DAPM_STREAM_RESUME);	
 	}
 
-	if(codec->active) {
-		snd_soc_dapm_codec_event(codec, SNDRV_CTL_POWER_D0);
+	if(codec->active)
 		snd_soc_dapm_codec_mute(codec, 0);
-	}
 
 	for(i = 0; i < machine->nconfigs; i++) {
 		struct snd_soc_pcm_interface  *iface = machine->config[i].iface;
@@ -831,6 +899,10 @@ static int soc_probe(struct platform_dev
 
 	if (platform->probe && ((ret = platform->probe(pdev)) < 0))
 		goto platform_err;
+		
+	INIT_WORK(&soc_stream_work, asoc_work, socdev);
+	if((soc_workq = create_workqueue("asoc")) == NULL)
+		goto platform_err;
 
 	return 0;
 	
@@ -864,6 +936,9 @@ static int soc_remove(struct platform_de
 	struct snd_soc_platform *platform = socdev->platform;
 	struct snd_soc_codec_device* codec_dev = socdev->codec_dev;
 
+	if(soc_workq)
+		destroy_workqueue(soc_workq);
+
 	if (platform->remove)
 		platform->remove(pdev);
 
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 39e4364..41913b5 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -69,16 +69,6 @@ #define pop_dbg(format, arg...)
 #define pop_wait(time)
 #endif
 
-/*
- * This is a timeout to powerdown a DAPM after a stream is finished - closed().
- * It can be used to eliminate pops between different playback streams, e.g.
- * between two audio tracks.
- * TODO
- */  
-static int pmdown_time = 5;
-module_param(pmdown_time, int, 0);
-MODULE_PARM_DESC(pmdown_time, "DAPM stream powerdown time (secs)");
-
 /* dapm power sequences - make this per codec in the future */
 static int dapm_up_seq[] = {
 	snd_soc_dapm_micbias, snd_soc_dapm_adc, snd_soc_dapm_mux,
@@ -151,8 +141,6 @@ static void dapm_set_path_status(struct 
 	case snd_soc_dapm_adc:
 	case snd_soc_dapm_input:
 	case snd_soc_dapm_dac:
-	case snd_soc_dapm_clock:
-	case snd_soc_dapm_vref:	
 	case snd_soc_dapm_micbias:
 		p->connect = 1;
 	case snd_soc_dapm_mute:
@@ -234,7 +222,8 @@ static int dapm_update_bits(struct snd_s
 	
 	change = old != new;
 	if (change) {
-		pop_dbg("pop test %s in %d ms\n", widget->name, POP_TIME);
+		pop_dbg("pop test %s : %s in %d ms\n", widget->name, 
+			widget->power ? "on" : "off", POP_TIME);
 		snd_soc_write(codec, widget->reg, new);
 		pop_wait(POP_TIME);
 	}
@@ -494,8 +483,7 @@ int dapm_power_widgets(struct snd_soc_co
 			if(seq && seq[i] && w->id != seq[i])
 				continue;
 			
-			if(w->id == snd_soc_dapm_vref || w->id == snd_soc_dapm_clock ||
-				w->id == snd_soc_dapm_mute)
+			if(w->id == snd_soc_dapm_mute)
 				continue;
 			
 			if(w->id == snd_soc_dapm_adc && w->active) {
@@ -893,8 +881,6 @@ int snd_soc_dapm_connect_input(struct sn
 	case snd_soc_dapm_pga:
 	case snd_soc_dapm_input:
 	case snd_soc_dapm_output:
-	case snd_soc_dapm_clock:
-	case snd_soc_dapm_vref:
 	case snd_soc_dapm_micbias:
 	case snd_soc_dapm_mute:
 		list_add(&path->list, &codec->dapm_paths);
@@ -968,8 +954,6 @@ int snd_soc_dapm_new_widgets(struct snd_
 			break;
 		case snd_soc_dapm_input:
 		case snd_soc_dapm_output:
-		case snd_soc_dapm_clock:
-		case snd_soc_dapm_vref:
 		case snd_soc_dapm_micbias:
 		case snd_soc_dapm_mute:
 		case snd_soc_dapm_spk:
@@ -1243,47 +1227,12 @@ int snd_soc_dapm_stream_event(struct snd
 EXPORT_SYMBOL_GPL(snd_soc_dapm_stream_event);
 
 /**
- * snd_soc_dapm_codec_event - send a codec event to the dapm core
- * @codec: audio codec
- * @event: codec event
- *
- * Sends a codec event to the dapm core. The core then makes any
- * necessary widget power changes. Codec power domain is changed
- * i.e. clocks, core voltage
- *
- * Returns 0 for success else error.
- */
-int snd_soc_dapm_codec_event(struct snd_soc_codec *codec, int event)
-{
-	struct snd_soc_dapm_widget *w;
-	struct list_head *l = NULL;
-	int power = 0;
-
-	if(event == SNDRV_CTL_POWER_D0)
-		power = 1;
-	else if(event == SNDRV_CTL_POWER_D3hot)
-		power = 0;
-		
-	list_for_each(l, &codec->dapm_widgets)
-	{
-		w = list_entry(l, struct snd_soc_dapm_widget, list);
-		if(w->id == snd_soc_dapm_vref || w->id == snd_soc_dapm_clock)
-			dapm_update_bits(w);
-	}
-	
-	dump_dapm(codec, __FUNCTION__);
-	return 0;
-}
-EXPORT_SYMBOL_GPL(snd_soc_dapm_codec_event);
-
-
-/**
  * snd_soc_dapm_codec_mute - control the codec digital mute
  * @codec: audio codec
- * @mute: mute/unmute
+ * @mute: mute = 1 / unmute = 0
  *
  * Controls the codec digital mute - used to reduce pop and click noises.
- *
+ * 
  * Returns 0 for success else error.
  */
 int snd_soc_dapm_codec_mute(struct snd_soc_codec *codec, int mute)
@@ -1301,7 +1250,7 @@ int snd_soc_dapm_codec_mute(struct snd_s
 			if(!mute && codec->dmute_wait){
 				schedule_timeout_interruptible(msecs_to_jiffies(codec->dmute_wait));
 			}
-			w->power = ~mute;
+			w->power = mute;
 			dapm_update_bits(w);
 		}
 	}
