ASoC: multi-component - ASoC Multi-Component Support

This patch extends the ASoC API to allow sound cards to have more than one
CODEC and more than one platform DMA controller. This is achieved by dividing
some current ASoC structures that contain both driver data and device data into
structures that only either contain device data or driver data. i.e.

 struct snd_soc_codec    --->  struct snd_soc_codec (device data)
                          +->  struct snd_soc_codec_driver (driver data)

 struct snd_soc_platform --->  struct snd_soc_platform (device data)
                          +->  struct snd_soc_platform_driver (driver data)

 struct snd_soc_dai      --->  struct snd_soc_dai (device data)
                          +->  struct snd_soc_dai_driver (driver data)

 struct snd_soc_device   --->  deleted

This now allows ASoC to be more tightly aligned with the Linux driver model and
also means that every ASoC codec, platform and (platform) DAI is a kernel
device. ASoC component private data is now stored as device private data.

The ASoC sound card struct snd_soc_card has also been updated to store lists
of it's components rather than a pointer to a codec and platform. The PCM
runtime struct soc_pcm_runtime now has pointers to all its components.

This patch adds DAPM support for ASoC multi-component and removes struct
snd_soc_socdev from DAPM core. All DAPM calls are now made on a card, codec
or runtime PCM level basis rather than using snd_soc_socdev.

Other notable multi-component changes:-

 * Stream operations now de-reference less structures.
 * close_delayed work() now runs on a DAI basis rather than looping all DAIs
   in a card.
 * PM suspend()/resume() operations can now handle N CODECs and Platforms
   per sound card.
 * Added soc_bind_dai_link() to bind the component devices to the sound card.
 * Added soc_dai_link_probe() and soc_dai_link_remove() to probe and remove
   DAI link components.
 * sysfs entries can now be registered per component per card.
 * snd_soc_new_pcms() functionailty rolled into dai_link_probe().
 * snd_soc_register_codec() now does all the codec list and mutex init.

This patch changes the probe() and remove() of the CODEC drivers as follows:-

 o Make CODEC driver a platform driver
 o Moved all struct snd_soc_codec list, mutex, etc initialiasation to core.
 o Removed all static codec pointers (drivers now support > 1 codec dev)
 o snd_soc_register_pcms() now done by core.
 o snd_soc_register_dai() folded into snd_soc_register_codec().

CS4270 portions:
Acked-by: Timur Tabi <timur@freescale.com>

Some TLV320aic23 and Cirrus platform fixes.
Signed-off-by: Ryan Mallon <ryan@bluewatersys.com>

TI CODEC and OMAP fixes
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@nokia.com>
Signed-off-by: Janusz Krzysztofik <jkrzyszt@tis.icnet.pl>
Signed-off-by: Jarkko Nikula <jhnikula@gmail.com>

Samsung platform and misc fixes :-
Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
Signed-off-by: Joonyoung Shim <jy0922.shim@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Reviewed-by: Jassi Brar <jassi.brar@samsung.com>
Signed-off-by: Seungwhan Youn <sw.youn@samsung.com>

MPC8610 and PPC fixes.
Signed-off-by: Timur Tabi <timur@freescale.com>

i.MX fixes and some core fixes.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>

J4740 platform fixes:-
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>

CC: Tony Lindgren <tony@atomide.com>
CC: Nicolas Ferre <nicolas.ferre@atmel.com>
CC: Kevin Hilman <khilman@deeprootsystems.com>
CC: Sascha Hauer <s.hauer@pengutronix.de>
CC: Atsushi Nemoto <anemo@mba.ocn.ne.jp>
CC: Kuninori Morimoto <morimoto.kuninori@renesas.com>
CC: Daniel Gloeckner <dg@emlix.com>
CC: Manuel Lauss <mano@roarinelk.homelinux.net>
CC: Mike Frysinger <vapier.adi@gmail.com>
CC: Arnaud Patard <apatard@mandriva.com>
CC: Wan ZongShun <mcuos.com@gmail.com>

Acked-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Signed-off-by: Liam Girdwood <lrg@slimlogic.co.uk>
diff --git a/sound/soc/pxa/corgi.c b/sound/soc/pxa/corgi.c
index fefe1a5..11c6a49 100644
--- a/sound/soc/pxa/corgi.c
+++ b/sound/soc/pxa/corgi.c
@@ -99,7 +99,7 @@
 static int corgi_startup(struct snd_pcm_substream *substream)
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct snd_soc_codec *codec = rtd->socdev->card->codec;
+	struct snd_soc_codec *codec = rtd->codec;
 
 	/* check the jack status at stream startup */
 	corgi_ext_control(codec);
@@ -118,8 +118,8 @@
 	struct snd_pcm_hw_params *params)
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
-	struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
+	struct snd_soc_dai *codec_dai = rtd->codec_dai;
+	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
 	unsigned int clk = 0;
 	int ret = 0;
 
@@ -272,8 +272,9 @@
 /*
  * Logic for a wm8731 as connected on a Sharp SL-C7x0 Device
  */
-static int corgi_wm8731_init(struct snd_soc_codec *codec)
+static int corgi_wm8731_init(struct snd_soc_pcm_runtime *rtd)
 {
+	struct snd_soc_codec *codec = rtd->codec;
 	int err;
 
 	snd_soc_dapm_nc_pin(codec, "LLINEIN");
@@ -300,8 +301,10 @@
 static struct snd_soc_dai_link corgi_dai = {
 	.name = "WM8731",
 	.stream_name = "WM8731",
-	.cpu_dai = &pxa_i2s_dai,
-	.codec_dai = &wm8731_dai,
+	.cpu_dai_name = "pxa-is2-dai",
+	.codec_dai_name = "wm8731-hifi",
+	.platform_name = "pxa-pcm-audio",
+	.codec_name = "wm8731-codec-0.001a",
 	.init = corgi_wm8731_init,
 	.ops = &corgi_ops,
 };
@@ -309,17 +312,10 @@
 /* corgi audio machine driver */
 static struct snd_soc_card snd_soc_corgi = {
 	.name = "Corgi",
-	.platform = &pxa2xx_soc_platform,
 	.dai_link = &corgi_dai,
 	.num_links = 1,
 };
 
-/* corgi audio subsystem */
-static struct snd_soc_device corgi_snd_devdata = {
-	.card = &snd_soc_corgi,
-	.codec_dev = &soc_codec_dev_wm8731,
-};
-
 static struct platform_device *corgi_snd_device;
 
 static int __init corgi_init(void)
@@ -334,8 +330,7 @@
 	if (!corgi_snd_device)
 		return -ENOMEM;
 
-	platform_set_drvdata(corgi_snd_device, &corgi_snd_devdata);
-	corgi_snd_devdata.dev = &corgi_snd_device->dev;
+	platform_set_drvdata(corgi_snd_device, &snd_soc_corgi);
 	ret = platform_device_add(corgi_snd_device);
 
 	if (ret)
diff --git a/sound/soc/pxa/e740_wm9705.c b/sound/soc/pxa/e740_wm9705.c
index 7cd2f89..f614607 100644
--- a/sound/soc/pxa/e740_wm9705.c
+++ b/sound/soc/pxa/e740_wm9705.c
@@ -24,7 +24,6 @@
 #include <asm/mach-types.h>
 
 #include "../codecs/wm9705.h"
-#include "pxa2xx-pcm.h"
 #include "pxa2xx-ac97.h"
 
 
@@ -90,8 +89,10 @@
 	{"Mic Amp", NULL, "Mic (Internal)"},
 };
 
-static int e740_ac97_init(struct snd_soc_codec *codec)
+static int e740_ac97_init(struct snd_soc_pcm_runtime *rtd)
 {
+	struct snd_soc_codec *codec = rtd->codec;
+
 	snd_soc_dapm_nc_pin(codec, "HPOUTL");
 	snd_soc_dapm_nc_pin(codec, "HPOUTR");
 	snd_soc_dapm_nc_pin(codec, "PHONE");
@@ -116,30 +117,28 @@
 	{
 		.name = "AC97",
 		.stream_name = "AC97 HiFi",
-		.cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_HIFI],
-		.codec_dai = &wm9705_dai[WM9705_DAI_AC97_HIFI],
+		.cpu_dai_name = "pxa-ac97.0",
+		.codec_dai_name = "wm9705-hifi",
+		.platform_name = "pxa-pcm-audio",
+		.codec_name = "wm9705-codec",
 		.init = e740_ac97_init,
 	},
 	{
 		.name = "AC97 Aux",
 		.stream_name = "AC97 Aux",
-		.cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_AUX],
-		.codec_dai = &wm9705_dai[WM9705_DAI_AC97_AUX],
+		.cpu_dai_name = "pxa-ac97.1",
+		.codec_dai_name = "wm9705-aux",
+		.platform_name = "pxa-pcm-audio",
+		.codec_name = "wm9705-codec",
 	},
 };
 
 static struct snd_soc_card e740 = {
 	.name = "Toshiba e740",
-	.platform = &pxa2xx_soc_platform,
 	.dai_link = e740_dai,
 	.num_links = ARRAY_SIZE(e740_dai),
 };
 
-static struct snd_soc_device e740_snd_devdata = {
-	.card = &e740,
-	.codec_dev = &soc_codec_dev_wm9705,
-};
-
 static struct platform_device *e740_snd_device;
 
 static int __init e740_init(void)
@@ -178,8 +177,7 @@
 		goto free_apwr_gpio;
 	}
 
-	platform_set_drvdata(e740_snd_device, &e740_snd_devdata);
-	e740_snd_devdata.dev = &e740_snd_device->dev;
+	platform_set_drvdata(e740_snd_device, &e740);
 	ret = platform_device_add(e740_snd_device);
 
 	if (!ret)
diff --git a/sound/soc/pxa/e750_wm9705.c b/sound/soc/pxa/e750_wm9705.c
index 8dceccc..4c14380 100644
--- a/sound/soc/pxa/e750_wm9705.c
+++ b/sound/soc/pxa/e750_wm9705.c
@@ -24,7 +24,6 @@
 #include <asm/mach-types.h>
 
 #include "../codecs/wm9705.h"
-#include "pxa2xx-pcm.h"
 #include "pxa2xx-ac97.h"
 
 static int e750_spk_amp_event(struct snd_soc_dapm_widget *w,
@@ -72,8 +71,10 @@
 	{"MIC1", NULL, "Mic (Internal)"},
 };
 
-static int e750_ac97_init(struct snd_soc_codec *codec)
+static int e750_ac97_init(struct snd_soc_pcm_runtime *rtd)
 {
+	struct snd_soc_codec *codec = rtd->codec;
+
 	snd_soc_dapm_nc_pin(codec, "LOUT");
 	snd_soc_dapm_nc_pin(codec, "ROUT");
 	snd_soc_dapm_nc_pin(codec, "PHONE");
@@ -98,31 +99,29 @@
 	{
 		.name = "AC97",
 		.stream_name = "AC97 HiFi",
-		.cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_HIFI],
-		.codec_dai = &wm9705_dai[WM9705_DAI_AC97_HIFI],
+		.cpu_dai_name = "pxa-ac97.0",
+		.codec_dai_name = "wm9705-hifi",
+		.platform_name = "pxa-pcm-audio",
+		.codec_name = "wm9705-codec",
 		.init = e750_ac97_init,
 		/* use ops to check startup state */
 	},
 	{
 		.name = "AC97 Aux",
 		.stream_name = "AC97 Aux",
-		.cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_AUX],
-		.codec_dai = &wm9705_dai[WM9705_DAI_AC97_AUX],
+		.cpu_dai_name = "pxa-ac97.1",
+		.codec_dai_name ="wm9705-aux",
+		.platform_name = "pxa-pcm-audio",
+		.codec_name = "wm9705-codec",
 	},
 };
 
 static struct snd_soc_card e750 = {
 	.name = "Toshiba e750",
-	.platform = &pxa2xx_soc_platform,
 	.dai_link = e750_dai,
 	.num_links = ARRAY_SIZE(e750_dai),
 };
 
-static struct snd_soc_device e750_snd_devdata = {
-	.card = &e750,
-	.codec_dev = &soc_codec_dev_wm9705,
-};
-
 static struct platform_device *e750_snd_device;
 
 static int __init e750_init(void)
@@ -154,8 +153,7 @@
 		goto free_spk_amp_gpio;
 	}
 
-	platform_set_drvdata(e750_snd_device, &e750_snd_devdata);
-	e750_snd_devdata.dev = &e750_snd_device->dev;
+	platform_set_drvdata(e750_snd_device, &e750);
 	ret = platform_device_add(e750_snd_device);
 
 	if (!ret)
diff --git a/sound/soc/pxa/e800_wm9712.c b/sound/soc/pxa/e800_wm9712.c
index bc019cd..d42e5fe 100644
--- a/sound/soc/pxa/e800_wm9712.c
+++ b/sound/soc/pxa/e800_wm9712.c
@@ -23,7 +23,6 @@
 #include <mach/eseries-gpio.h>
 
 #include "../codecs/wm9712.h"
-#include "pxa2xx-pcm.h"
 #include "pxa2xx-ac97.h"
 
 static int e800_spk_amp_event(struct snd_soc_dapm_widget *w,
@@ -73,8 +72,10 @@
 	{"MIC2", NULL, "Mic (Internal2)"},
 };
 
-static int e800_ac97_init(struct snd_soc_codec *codec)
+static int e800_ac97_init(struct snd_soc_pcm_runtime *rtd)
 {
+	struct snd_soc_codec *codec = rtd->codec;
+
 	snd_soc_dapm_new_controls(codec, e800_dapm_widgets,
 					ARRAY_SIZE(e800_dapm_widgets));
 
@@ -88,30 +89,28 @@
 	{
 		.name = "AC97",
 		.stream_name = "AC97 HiFi",
-		.cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_HIFI],
-		.codec_dai = &wm9712_dai[WM9712_DAI_AC97_HIFI],
+		.cpu_dai_name = "pxa-ac97.0",
+		.codec_dai_name = "wm9712-hifi",
+		.platform_name = "pxa-pcm-audio",
+		.codec_name = "wm9712-codec",
 		.init = e800_ac97_init,
 	},
 	{
 		.name = "AC97 Aux",
 		.stream_name = "AC97 Aux",
-		.cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_AUX],
-		.codec_dai = &wm9712_dai[WM9712_DAI_AC97_AUX],
+		.cpu_dai_name = "pxa-ac97.1",
+		.codec_dai_name ="wm9712-aux",
+		.platform_name = "pxa-pcm-audio",
+		.codec_name = "wm9712-codec",
 	},
 };
 
 static struct snd_soc_card e800 = {
 	.name = "Toshiba e800",
-	.platform = &pxa2xx_soc_platform,
 	.dai_link = e800_dai,
 	.num_links = ARRAY_SIZE(e800_dai),
 };
 
-static struct snd_soc_device e800_snd_devdata = {
-	.card = &e800,
-	.codec_dev = &soc_codec_dev_wm9712,
-};
-
 static struct platform_device *e800_snd_device;
 
 static int __init e800_init(void)
@@ -141,8 +140,7 @@
 	if (!e800_snd_device)
 		return -ENOMEM;
 
-	platform_set_drvdata(e800_snd_device, &e800_snd_devdata);
-	e800_snd_devdata.dev = &e800_snd_device->dev;
+	platform_set_drvdata(e800_snd_device, &e800);
 	ret = platform_device_add(e800_snd_device);
 
 	if (!ret)
diff --git a/sound/soc/pxa/em-x270.c b/sound/soc/pxa/em-x270.c
index f4756e4..7046128 100644
--- a/sound/soc/pxa/em-x270.c
+++ b/sound/soc/pxa/em-x270.c
@@ -39,29 +39,27 @@
 	{
 		.name = "AC97",
 		.stream_name = "AC97 HiFi",
-		.cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_HIFI],
-		.codec_dai = &wm9712_dai[WM9712_DAI_AC97_HIFI],
+		.cpu_dai_name = "pxa-ac97.0",
+		.codec_dai_name = "wm9712-hifi",
+		.platform_name = "pxa-pcm-audio",
+		.codec_name = "wm9712-codec",
 	},
 	{
 		.name = "AC97 Aux",
 		.stream_name = "AC97 Aux",
-		.cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_AUX],
-		.codec_dai = &wm9712_dai[WM9712_DAI_AC97_AUX],
+		.cpu_dai_name = "pxa-ac97.1",
+		.codec_dai_name ="wm9712-aux",
+		.platform_name = "pxa-pcm-audio",
+		.codec_name = "wm9712-codec",
 	},
 };
 
 static struct snd_soc_card em_x270 = {
 	.name = "EM-X270",
-	.platform = &pxa2xx_soc_platform,
 	.dai_link = em_x270_dai,
 	.num_links = ARRAY_SIZE(em_x270_dai),
 };
 
-static struct snd_soc_device em_x270_snd_devdata = {
-	.card = &em_x270,
-	.codec_dev = &soc_codec_dev_wm9712,
-};
-
 static struct platform_device *em_x270_snd_device;
 
 static int __init em_x270_init(void)
@@ -76,8 +74,7 @@
 	if (!em_x270_snd_device)
 		return -ENOMEM;
 
-	platform_set_drvdata(em_x270_snd_device, &em_x270_snd_devdata);
-	em_x270_snd_devdata.dev = &em_x270_snd_device->dev;
+	platform_set_drvdata(em_x270_snd_device, &em_x270);
 	ret = platform_device_add(em_x270_snd_device);
 
 	if (ret)
diff --git a/sound/soc/pxa/imote2.c b/sound/soc/pxa/imote2.c
index 405587a..03765fc 100644
--- a/sound/soc/pxa/imote2.c
+++ b/sound/soc/pxa/imote2.c
@@ -6,14 +6,13 @@
 
 #include "../codecs/wm8940.h"
 #include "pxa2xx-i2s.h"
-#include "pxa2xx-pcm.h"
 
 static int imote2_asoc_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_dai *codec_dai = rtd->dai->codec_dai;
-	struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
+	struct snd_soc_dai *codec_dai = rtd->codec_dai;
+	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
 	unsigned int clk = 0;
 	int ret;
 
@@ -64,23 +63,19 @@
 static struct snd_soc_dai_link imote2_dai = {
 	.name = "WM8940",
 	.stream_name = "WM8940",
-	.cpu_dai = &pxa_i2s_dai,
-	.codec_dai = &wm8940_dai,
+	.cpu_dai_name = "pxa-i2s",
+	.codec_dai_name = "wm8940-hifi",
+	.platform_name = "pxa-pcm-audio",
+	.codec_name = "wm8940-codec.0-0034",
 	.ops = &imote2_asoc_ops,
 };
 
 static struct snd_soc_card snd_soc_imote2 = {
 	.name = "Imote2",
-	.platform = &pxa2xx_soc_platform,
 	.dai_link = &imote2_dai,
 	.num_links = 1,
 };
 
-static struct snd_soc_device imote2_snd_devdata = {
-	.card = &snd_soc_imote2,
-	.codec_dev = &soc_codec_dev_wm8940,
-};
-
 static struct platform_device *imote2_snd_device;
 
 static int __init imote2_asoc_init(void)
@@ -93,8 +88,7 @@
 	if (!imote2_snd_device)
 		return -ENOMEM;
 
-	platform_set_drvdata(imote2_snd_device, &imote2_snd_devdata);
-	imote2_snd_devdata.dev = &imote2_snd_device->dev;
+	platform_set_drvdata(imote2_snd_device, &snd_soc_imote2);
 	ret = platform_device_add(imote2_snd_device);
 	if (ret)
 		platform_device_put(imote2_snd_device);
diff --git a/sound/soc/pxa/magician.c b/sound/soc/pxa/magician.c
index 4c8d99a..608bc3d 100644
--- a/sound/soc/pxa/magician.c
+++ b/sound/soc/pxa/magician.c
@@ -32,7 +32,6 @@
 #include <mach/magician.h>
 #include <asm/mach-types.h>
 #include "../codecs/uda1380.h"
-#include "pxa2xx-pcm.h"
 #include "pxa2xx-i2s.h"
 #include "pxa-ssp.h"
 
@@ -71,7 +70,7 @@
 static int magician_startup(struct snd_pcm_substream *substream)
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct snd_soc_codec *codec = rtd->socdev->card->codec;
+	struct snd_soc_codec *codec = rtd->codec;
 
 	/* check the jack status at stream startup */
 	magician_ext_control(codec);
@@ -86,8 +85,8 @@
 				       struct snd_pcm_hw_params *params)
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
-	struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
+	struct snd_soc_dai *codec_dai = rtd->codec_dai;
+	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
 	unsigned int acps, acds, width, rate;
 	unsigned int div4 = PXA_SSP_CLK_SCDB_4;
 	int ret = 0;
@@ -227,8 +226,8 @@
 				      struct snd_pcm_hw_params *params)
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
-	struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
+	struct snd_soc_dai *codec_dai = rtd->codec_dai;
+	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
 	int ret = 0;
 
 	/* set codec DAI configuration */
@@ -393,8 +392,9 @@
 /*
  * Logic for a uda1380 as connected on a HTC Magician
  */
-static int magician_uda1380_init(struct snd_soc_codec *codec)
+static int magician_uda1380_init(struct snd_soc_pcm_runtime *rtd)
 {
+	struct snd_soc_codec *codec = rtd->codec;
 	int err;
 
 	/* NC codec pins */
@@ -427,16 +427,20 @@
 {
 	.name = "uda1380",
 	.stream_name = "UDA1380 Playback",
-	.cpu_dai = &pxa_ssp_dai[PXA_DAI_SSP1],
-	.codec_dai = &uda1380_dai[UDA1380_DAI_PLAYBACK],
+	.cpu_dai_name = "pxa-ssp-dai.0",
+	.codec_dai_name = "uda1380-hifi-playback",
+	.platform_name = "pxa-pcm-audio",
+	.codec_name = "uda1380-codec.0-0018",
 	.init = magician_uda1380_init,
 	.ops = &magician_playback_ops,
 },
 {
 	.name = "uda1380",
 	.stream_name = "UDA1380 Capture",
-	.cpu_dai = &pxa_i2s_dai,
-	.codec_dai = &uda1380_dai[UDA1380_DAI_CAPTURE],
+	.cpu_dai_name = "pxa-i2s",
+	.codec_dai_name = "uda1380-hifi-capture",
+	.platform_name = "pxa-pcm-audio",
+	.codec_name = "uda1380-codec.0-0018",
 	.ops = &magician_capture_ops,
 }
 };
@@ -446,13 +450,7 @@
 	.name = "Magician",
 	.dai_link = magician_dai,
 	.num_links = ARRAY_SIZE(magician_dai),
-	.platform = &pxa2xx_soc_platform,
-};
 
-/* magician audio subsystem */
-static struct snd_soc_device magician_snd_devdata = {
-	.card = &snd_soc_card_magician,
-	.codec_dev = &soc_codec_dev_uda1380,
 };
 
 static struct platform_device *magician_snd_device;
@@ -514,8 +512,7 @@
 		goto err_pdev;
 	}
 
-	platform_set_drvdata(magician_snd_device, &magician_snd_devdata);
-	magician_snd_devdata.dev = &magician_snd_device->dev;
+	platform_set_drvdata(magician_snd_device, &snd_soc_card_magician);
 	ret = platform_device_add(magician_snd_device);
 	if (ret) {
 		platform_device_put(magician_snd_device);
diff --git a/sound/soc/pxa/mioa701_wm9713.c b/sound/soc/pxa/mioa701_wm9713.c
index 19eda8b..f284cc5 100644
--- a/sound/soc/pxa/mioa701_wm9713.c
+++ b/sound/soc/pxa/mioa701_wm9713.c
@@ -54,7 +54,6 @@
 #include <sound/initval.h>
 #include <sound/ac97_codec.h>
 
-#include "pxa2xx-pcm.h"
 #include "pxa2xx-ac97.h"
 #include "../codecs/wm9713.h"
 
@@ -128,8 +127,9 @@
 	{"Rear Speaker", NULL, "SPKR"},
 };
 
-static int mioa701_wm9713_init(struct snd_soc_codec *codec)
+static int mioa701_wm9713_init(struct snd_soc_pcm_runtime *rtd)
 {
+	struct snd_soc_codec *codec = rtd->codec;
 	unsigned short reg;
 
 	/* Add mioa701 specific widgets */
@@ -139,12 +139,12 @@
 	snd_soc_dapm_add_routes(codec, ARRAY_AND_SIZE(audio_map));
 
 	/* Prepare GPIO8 for rear speaker amplifier */
-	reg = codec->read(codec, AC97_GPIO_CFG);
-	codec->write(codec, AC97_GPIO_CFG, reg | 0x0100);
+	reg = codec->driver->read(codec, AC97_GPIO_CFG);
+	codec->driver->write(codec, AC97_GPIO_CFG, reg | 0x0100);
 
 	/* Prepare MIC input */
-	reg = codec->read(codec, AC97_3D_CONTROL);
-	codec->write(codec, AC97_3D_CONTROL, reg | 0xc000);
+	reg = codec->driver->read(codec, AC97_3D_CONTROL);
+	codec->driver->write(codec, AC97_3D_CONTROL, reg | 0xc000);
 
 	snd_soc_dapm_enable_pin(codec, "Front Speaker");
 	snd_soc_dapm_enable_pin(codec, "Rear Speaker");
@@ -162,32 +162,30 @@
 	{
 		.name = "AC97",
 		.stream_name = "AC97 HiFi",
-		.cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_HIFI],
-		.codec_dai = &wm9713_dai[WM9713_DAI_AC97_HIFI],
+		.cpu_dai_name = "pxa-ac97.0",
+		.codec_dai_name = "wm9713-hifi",
+		.codec_name = "wm9713-codec",
 		.init = mioa701_wm9713_init,
+		.platform_name = "pxa-pcm-audio",
 		.ops = &mioa701_ops,
 	},
 	{
 		.name = "AC97 Aux",
 		.stream_name = "AC97 Aux",
-		.cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_AUX],
-		.codec_dai = &wm9713_dai[WM9713_DAI_AC97_AUX],
+		.cpu_dai_name = "pxa-ac97.1",
+		.codec_dai_name ="wm9713-aux",
+		.codec_name = "wm9713-codec",
+		.platform_name = "pxa-pcm-audio",
 		.ops = &mioa701_ops,
 	},
 };
 
 static struct snd_soc_card mioa701 = {
 	.name = "MioA701",
-	.platform = &pxa2xx_soc_platform,
 	.dai_link = mioa701_dai,
 	.num_links = ARRAY_SIZE(mioa701_dai),
 };
 
-static struct snd_soc_device mioa701_snd_devdata = {
-	.card = &mioa701,
-	.codec_dev = &soc_codec_dev_wm9713,
-};
-
 static struct platform_device *mioa701_snd_device;
 
 static int mioa701_wm9713_probe(struct platform_device *pdev)
@@ -205,8 +203,7 @@
 	if (!mioa701_snd_device)
 		return -ENOMEM;
 
-	platform_set_drvdata(mioa701_snd_device, &mioa701_snd_devdata);
-	mioa701_snd_devdata.dev = &mioa701_snd_device->dev;
+	platform_set_drvdata(mioa701_snd_device, &mioa701);
 
 	ret = platform_device_add(mioa701_snd_device);
 	if (!ret)
diff --git a/sound/soc/pxa/palm27x.c b/sound/soc/pxa/palm27x.c
index 1f96e32..13f6d48 100644
--- a/sound/soc/pxa/palm27x.c
+++ b/sound/soc/pxa/palm27x.c
@@ -29,7 +29,6 @@
 #include <mach/palmasoc.h>
 
 #include "../codecs/wm9712.h"
-#include "pxa2xx-pcm.h"
 #include "pxa2xx-ac97.h"
 
 static struct snd_soc_jack hs_jack;
@@ -75,8 +74,9 @@
 
 static struct snd_soc_card palm27x_asoc;
 
-static int palm27x_ac97_init(struct snd_soc_codec *codec)
+static int palm27x_ac97_init(struct snd_soc_pcm_runtime *rtd)
 {
+	struct snd_soc_codec *codec = rtd->codec;
 	int err;
 
 	/* add palm27x specific widgets */
@@ -112,7 +112,7 @@
 		return err;
 
 	/* Jack detection API stuff */
-	err = snd_soc_jack_new(&palm27x_asoc, "Headphone Jack",
+	err = snd_soc_jack_new(codec, "Headphone Jack",
 				SND_JACK_HEADPHONE, &hs_jack);
 	if (err)
 		return err;
@@ -132,30 +132,28 @@
 {
 	.name = "AC97 HiFi",
 	.stream_name = "AC97 HiFi",
-	.cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_HIFI],
-	.codec_dai = &wm9712_dai[WM9712_DAI_AC97_HIFI],
+	.cpu_dai_name = "pxa-ac97.0",
+	.codec_dai_name =  "wm9712-hifi",
+	.codec_name = "wm9712-codec",
+	.platform_name = "pxa-pcm-audio",
 	.init = palm27x_ac97_init,
 },
 {
 	.name = "AC97 Aux",
 	.stream_name = "AC97 Aux",
-	.cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_AUX],
-	.codec_dai = &wm9712_dai[WM9712_DAI_AC97_AUX],
+	.cpu_dai_name = "pxa-ac97.1",
+	.codec_dai_name = "wm9712-aux",
+	.codec_name = "wm9712-codec",
+	.platform_name = "pxa-pcm-audio",
 },
 };
 
 static struct snd_soc_card palm27x_asoc = {
 	.name = "Palm/PXA27x",
-	.platform = &pxa2xx_soc_platform,
 	.dai_link = palm27x_dai,
 	.num_links = ARRAY_SIZE(palm27x_dai),
 };
 
-static struct snd_soc_device palm27x_snd_devdata = {
-	.card = &palm27x_asoc,
-	.codec_dev = &soc_codec_dev_wm9712,
-};
-
 static struct platform_device *palm27x_snd_device;
 
 static int palm27x_asoc_probe(struct platform_device *pdev)
@@ -178,8 +176,7 @@
 	if (!palm27x_snd_device)
 		return -ENOMEM;
 
-	platform_set_drvdata(palm27x_snd_device, &palm27x_snd_devdata);
-	palm27x_snd_devdata.dev = &palm27x_snd_device->dev;
+	platform_set_drvdata(palm27x_snd_device, &palm27x_asoc);
 	ret = platform_device_add(palm27x_snd_device);
 
 	if (ret != 0)
diff --git a/sound/soc/pxa/poodle.c b/sound/soc/pxa/poodle.c
index c5f36e0..3ba5a96 100644
--- a/sound/soc/pxa/poodle.c
+++ b/sound/soc/pxa/poodle.c
@@ -31,7 +31,6 @@
 #include <mach/audio.h>
 
 #include "../codecs/wm8731.h"
-#include "pxa2xx-pcm.h"
 #include "pxa2xx-i2s.h"
 
 #define POODLE_HP        1
@@ -76,7 +75,7 @@
 static int poodle_startup(struct snd_pcm_substream *substream)
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct snd_soc_codec *codec = rtd->socdev->card->codec;
+	struct snd_soc_codec *codec = rtd->codec;
 
 	/* check the jack status at stream startup */
 	poodle_ext_control(codec);
@@ -97,8 +96,8 @@
 	struct snd_pcm_hw_params *params)
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
-	struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
+	struct snd_soc_dai *codec_dai = rtd->codec_dai;
+	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
 	unsigned int clk = 0;
 	int ret = 0;
 
@@ -237,8 +236,9 @@
 /*
  * Logic for a wm8731 as connected on a Sharp SL-C7x0 Device
  */
-static int poodle_wm8731_init(struct snd_soc_codec *codec)
+static int poodle_wm8731_init(struct snd_soc_pcm_runtime *rtd)
 {
+	struct snd_soc_codec *codec = rtd->codec;
 	int err;
 
 	snd_soc_dapm_nc_pin(codec, "LLINEIN");
@@ -266,8 +266,10 @@
 static struct snd_soc_dai_link poodle_dai = {
 	.name = "WM8731",
 	.stream_name = "WM8731",
-	.cpu_dai = &pxa_i2s_dai,
-	.codec_dai = &wm8731_dai,
+	.cpu_dai_name = "pxa-i2s",
+	.codec_dai_name = "wm8731-hifi"
+	.platform_name = "pxa-pcm-audio",
+	.codec_name = "wm8731-codec.0-001a",
 	.init = poodle_wm8731_init,
 	.ops = &poodle_ops,
 };
@@ -275,15 +277,9 @@
 /* poodle audio machine driver */
 static struct snd_soc_card snd_soc_poodle = {
 	.name = "Poodle",
-	.platform = &pxa2xx_soc_platform,
 	.dai_link = &poodle_dai,
 	.num_links = 1,
-};
-
-/* poodle audio subsystem */
-static struct snd_soc_device poodle_snd_devdata = {
-	.card = &snd_soc_poodle,
-	.codec_dev = &soc_codec_dev_wm8731,
+	.owner = THIS_MODULE,
 };
 
 static struct platform_device *poodle_snd_device;
@@ -307,8 +303,7 @@
 	if (!poodle_snd_device)
 		return -ENOMEM;
 
-	platform_set_drvdata(poodle_snd_device, &poodle_snd_devdata);
-	poodle_snd_devdata.dev = &poodle_snd_device->dev;
+	platform_set_drvdata(poodle_snd_device, &snd_soc_poodle);
 	ret = platform_device_add(poodle_snd_device);
 
 	if (ret)
diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c
index a1fd23e..99d80e8 100644
--- a/sound/soc/pxa/pxa-ssp.c
+++ b/sound/soc/pxa/pxa-ssp.c
@@ -108,11 +108,9 @@
 }
 
 static int pxa_ssp_startup(struct snd_pcm_substream *substream,
-			   struct snd_soc_dai *dai)
+			   struct snd_soc_dai *cpu_dai)
 {
-	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
-	struct ssp_priv *priv = cpu_dai->private_data;
+	struct ssp_priv *priv = snd_soc_dai_get_drvdata(cpu_dai);
 	struct ssp_device *ssp = priv->ssp;
 	int ret = 0;
 
@@ -128,11 +126,9 @@
 }
 
 static void pxa_ssp_shutdown(struct snd_pcm_substream *substream,
-			     struct snd_soc_dai *dai)
+			     struct snd_soc_dai *cpu_dai)
 {
-	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
-	struct ssp_priv *priv = cpu_dai->private_data;
+	struct ssp_priv *priv = snd_soc_dai_get_drvdata(cpu_dai);
 	struct ssp_device *ssp = priv->ssp;
 
 	if (!cpu_dai->active) {
@@ -148,7 +144,7 @@
 
 static int pxa_ssp_suspend(struct snd_soc_dai *cpu_dai)
 {
-	struct ssp_priv *priv = cpu_dai->private_data;
+	struct ssp_priv *priv = snd_soc_dai_get_drvdata(cpu_dai);
 	struct ssp_device *ssp = priv->ssp;
 
 	if (!cpu_dai->active)
@@ -166,7 +162,7 @@
 
 static int pxa_ssp_resume(struct snd_soc_dai *cpu_dai)
 {
-	struct ssp_priv *priv = cpu_dai->private_data;
+	struct ssp_priv *priv = snd_soc_dai_get_drvdata(cpu_dai);
 	struct ssp_device *ssp = priv->ssp;
 	uint32_t sssr = SSSR_ROR | SSSR_TUR | SSSR_BCE;
 
@@ -230,7 +226,7 @@
 static int pxa_ssp_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
 	int clk_id, unsigned int freq, int dir)
 {
-	struct ssp_priv *priv = cpu_dai->private_data;
+	struct ssp_priv *priv = snd_soc_dai_get_drvdata(cpu_dai);
 	struct ssp_device *ssp = priv->ssp;
 	int val;
 
@@ -287,7 +283,7 @@
 static int pxa_ssp_set_dai_clkdiv(struct snd_soc_dai *cpu_dai,
 	int div_id, int div)
 {
-	struct ssp_priv *priv = cpu_dai->private_data;
+	struct ssp_priv *priv = snd_soc_dai_get_drvdata(cpu_dai);
 	struct ssp_device *ssp = priv->ssp;
 	int val;
 
@@ -338,7 +334,7 @@
 static int pxa_ssp_set_dai_pll(struct snd_soc_dai *cpu_dai, int pll_id,
 	int source, unsigned int freq_in, unsigned int freq_out)
 {
-	struct ssp_priv *priv = cpu_dai->private_data;
+	struct ssp_priv *priv = snd_soc_dai_get_drvdata(cpu_dai);
 	struct ssp_device *ssp = priv->ssp;
 	u32 ssacd = pxa_ssp_read_reg(ssp, SSACD) & ~0x70;
 
@@ -407,7 +403,7 @@
 static int pxa_ssp_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai,
 	unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width)
 {
-	struct ssp_priv *priv = cpu_dai->private_data;
+	struct ssp_priv *priv = snd_soc_dai_get_drvdata(cpu_dai);
 	struct ssp_device *ssp = priv->ssp;
 	u32 sscr0;
 
@@ -442,7 +438,7 @@
 static int pxa_ssp_set_dai_tristate(struct snd_soc_dai *cpu_dai,
 	int tristate)
 {
-	struct ssp_priv *priv = cpu_dai->private_data;
+	struct ssp_priv *priv = snd_soc_dai_get_drvdata(cpu_dai);
 	struct ssp_device *ssp = priv->ssp;
 	u32 sscr1;
 
@@ -464,7 +460,7 @@
 static int pxa_ssp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
 		unsigned int fmt)
 {
-	struct ssp_priv *priv = cpu_dai->private_data;
+	struct ssp_priv *priv = snd_soc_dai_get_drvdata(cpu_dai);
 	struct ssp_device *ssp = priv->ssp;
 	u32 sscr0;
 	u32 sscr1;
@@ -555,11 +551,9 @@
  */
 static int pxa_ssp_hw_params(struct snd_pcm_substream *substream,
 				struct snd_pcm_hw_params *params,
-				struct snd_soc_dai *dai)
+				struct snd_soc_dai *cpu_dai)
 {
-	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
-	struct ssp_priv *priv = cpu_dai->private_data;
+	struct ssp_priv *priv = snd_soc_dai_get_drvdata(cpu_dai);
 	struct ssp_device *ssp = priv->ssp;
 	int chn = params_channels(params);
 	u32 sscr0;
@@ -568,7 +562,7 @@
 	int ttsa = pxa_ssp_read_reg(ssp, SSTSA) & 0xf;
 	struct pxa2xx_pcm_dma_params *dma_data;
 
-	dma_data = snd_soc_dai_get_dma_data(dai, substream);
+	dma_data = snd_soc_dai_get_dma_data(cpu_dai, substream);
 
 	/* generate correct DMA params */
 	kfree(dma_data);
@@ -581,7 +575,7 @@
 			((chn == 2) && (ttsa != 1)) || (width == 32),
 			substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
 
-	snd_soc_dai_set_dma_data(dai, substream, dma_data);
+	snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data);
 
 	/* we can only change the settings if the port is not in use */
 	if (pxa_ssp_read_reg(ssp, SSCR0) & SSCR0_SSE)
@@ -668,12 +662,10 @@
 }
 
 static int pxa_ssp_trigger(struct snd_pcm_substream *substream, int cmd,
-			   struct snd_soc_dai *dai)
+			   struct snd_soc_dai *cpu_dai)
 {
-	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
 	int ret = 0;
-	struct ssp_priv *priv = cpu_dai->private_data;
+	struct ssp_priv *priv = snd_soc_dai_get_drvdata(cpu_dai);
 	struct ssp_device *ssp = priv->ssp;
 	int val;
 
@@ -729,8 +721,7 @@
 	return ret;
 }
 
-static int pxa_ssp_probe(struct platform_device *pdev,
-			    struct snd_soc_dai *dai)
+static int pxa_ssp_probe(struct snd_soc_dai *dai)
 {
 	struct ssp_priv *priv;
 	int ret;
@@ -746,7 +737,7 @@
 	}
 
 	priv->dai_fmt = (unsigned int) -1;
-	dai->private_data = priv;
+	snd_soc_dai_set_drvdata(dai, priv);
 
 	return 0;
 
@@ -755,11 +746,12 @@
 	return ret;
 }
 
-static void pxa_ssp_remove(struct platform_device *pdev,
-			      struct snd_soc_dai *dai)
+static int pxa_ssp_remove(struct snd_soc_dai *dai)
 {
-	struct ssp_priv *priv = dai->private_data;
+	struct ssp_priv *priv = snd_soc_dai_get_drvdata(dai);
+
 	pxa_ssp_free(priv->ssp);
+	return 0;
 }
 
 #define PXA_SSP_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
@@ -784,10 +776,7 @@
 	.set_tristate	= pxa_ssp_set_dai_tristate,
 };
 
-struct snd_soc_dai pxa_ssp_dai[] = {
-	{
-		.name = "pxa2xx-ssp1",
-		.id = 0,
+static struct snd_soc_dai_driver pxa_ssp_dai = {
 		.probe = pxa_ssp_probe,
 		.remove = pxa_ssp_remove,
 		.suspend = pxa_ssp_suspend,
@@ -805,81 +794,38 @@
 			.formats = PXA_SSP_FORMATS,
 		 },
 		.ops = &pxa_ssp_dai_ops,
-	},
-	{	.name = "pxa2xx-ssp2",
-		.id = 1,
-		.probe = pxa_ssp_probe,
-		.remove = pxa_ssp_remove,
-		.suspend = pxa_ssp_suspend,
-		.resume = pxa_ssp_resume,
-		.playback = {
-			.channels_min = 1,
-			.channels_max = 8,
-			.rates = PXA_SSP_RATES,
-			.formats = PXA_SSP_FORMATS,
-		},
-		.capture = {
-			.channels_min = 1,
-			.channels_max = 8,
-			.rates = PXA_SSP_RATES,
-			.formats = PXA_SSP_FORMATS,
-		 },
-		.ops = &pxa_ssp_dai_ops,
-	},
-	{
-		.name = "pxa2xx-ssp3",
-		.id = 2,
-		.probe = pxa_ssp_probe,
-		.remove = pxa_ssp_remove,
-		.suspend = pxa_ssp_suspend,
-		.resume = pxa_ssp_resume,
-		.playback = {
-			.channels_min = 1,
-			.channels_max = 8,
-			.rates = PXA_SSP_RATES,
-			.formats = PXA_SSP_FORMATS,
-		},
-		.capture = {
-			.channels_min = 1,
-			.channels_max = 8,
-			.rates = PXA_SSP_RATES,
-			.formats = PXA_SSP_FORMATS,
-		 },
-		.ops = &pxa_ssp_dai_ops,
-	},
-	{
-		.name = "pxa2xx-ssp4",
-		.id = 3,
-		.probe = pxa_ssp_probe,
-		.remove = pxa_ssp_remove,
-		.suspend = pxa_ssp_suspend,
-		.resume = pxa_ssp_resume,
-		.playback = {
-			.channels_min = 1,
-			.channels_max = 8,
-			.rates = PXA_SSP_RATES,
-			.formats = PXA_SSP_FORMATS,
-		},
-		.capture = {
-			.channels_min = 1,
-			.channels_max = 8,
-			.rates = PXA_SSP_RATES,
-			.formats = PXA_SSP_FORMATS,
-		 },
-		.ops = &pxa_ssp_dai_ops,
-	},
 };
-EXPORT_SYMBOL_GPL(pxa_ssp_dai);
+
+static __devinit int asoc_ssp_probe(struct platform_device *pdev)
+{
+	return snd_soc_register_dai(&pdev->dev, &pxa_ssp_dai);
+}
+
+static int __devexit asoc_ssp_remove(struct platform_device *pdev)
+{
+	snd_soc_unregister_dai(&pdev->dev);
+	return 0;
+}
+
+static struct platform_driver asoc_ssp_driver = {
+	.driver = {
+			.name = "pxa-ssp-dai",
+			.owner = THIS_MODULE,
+	},
+
+	.probe = asoc_ssp_probe,
+	.remove = __devexit_p(asoc_ssp_remove),
+};
 
 static int __init pxa_ssp_init(void)
 {
-	return snd_soc_register_dais(pxa_ssp_dai, ARRAY_SIZE(pxa_ssp_dai));
+	return platform_driver_register(&asoc_ssp_driver);
 }
 module_init(pxa_ssp_init);
 
 static void __exit pxa_ssp_exit(void)
 {
-	snd_soc_unregister_dais(pxa_ssp_dai, ARRAY_SIZE(pxa_ssp_dai));
+	platform_driver_unregister(&asoc_ssp_driver);
 }
 module_exit(pxa_ssp_exit);
 
diff --git a/sound/soc/pxa/pxa-ssp.h b/sound/soc/pxa/pxa-ssp.h
index 91deadd..bc79da2 100644
--- a/sound/soc/pxa/pxa-ssp.h
+++ b/sound/soc/pxa/pxa-ssp.h
@@ -42,6 +42,4 @@
 
 #define PXA_SSP_PLL_OUT  0
 
-extern struct snd_soc_dai pxa_ssp_dai[4];
-
 #endif
diff --git a/sound/soc/pxa/pxa2xx-ac97.c b/sound/soc/pxa/pxa2xx-ac97.c
index d314115..9c2bafa 100644
--- a/sound/soc/pxa/pxa2xx-ac97.c
+++ b/sound/soc/pxa/pxa2xx-ac97.c
@@ -104,24 +104,21 @@
 #define pxa2xx_ac97_resume	NULL
 #endif
 
-static int pxa2xx_ac97_probe(struct platform_device *pdev,
-			     struct snd_soc_dai *dai)
+static int pxa2xx_ac97_probe(struct snd_soc_dai *dai)
 {
 	return pxa2xx_ac97_hw_probe(to_platform_device(dai->dev));
 }
 
-static void pxa2xx_ac97_remove(struct platform_device *pdev,
-			       struct snd_soc_dai *dai)
+static int pxa2xx_ac97_remove(struct snd_soc_dai *dai)
 {
 	pxa2xx_ac97_hw_remove(to_platform_device(dai->dev));
+	return 0;
 }
 
 static int pxa2xx_ac97_hw_params(struct snd_pcm_substream *substream,
 				 struct snd_pcm_hw_params *params,
-				 struct snd_soc_dai *dai)
+				 struct snd_soc_dai *cpu_dai)
 {
-	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
 	struct pxa2xx_pcm_dma_params *dma_data;
 
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
@@ -136,10 +133,8 @@
 
 static int pxa2xx_ac97_hw_aux_params(struct snd_pcm_substream *substream,
 				     struct snd_pcm_hw_params *params,
-				     struct snd_soc_dai *dai)
+				     struct snd_soc_dai *cpu_dai)
 {
-	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
 	struct pxa2xx_pcm_dma_params *dma_data;
 
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
@@ -154,11 +149,8 @@
 
 static int pxa2xx_ac97_hw_mic_params(struct snd_pcm_substream *substream,
 				     struct snd_pcm_hw_params *params,
-				     struct snd_soc_dai *dai)
+				     struct snd_soc_dai *cpu_dai)
 {
-	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
-
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
 		return -ENODEV;
 	else
@@ -188,10 +180,9 @@
  * There is only 1 physical AC97 interface for pxa2xx, but it
  * has extra fifo's that can be used for aux DACs and ADCs.
  */
-struct snd_soc_dai pxa_ac97_dai[] = {
+static struct snd_soc_dai_driver pxa_ac97_dai[] = {
 {
 	.name = "pxa2xx-ac97",
-	.id = 0,
 	.ac97_control = 1,
 	.probe = pxa2xx_ac97_probe,
 	.remove = pxa2xx_ac97_remove,
@@ -213,7 +204,6 @@
 },
 {
 	.name = "pxa2xx-ac97-aux",
-	.id = 1,
 	.ac97_control = 1,
 	.playback = {
 		.stream_name = "AC97 Aux Playback",
@@ -231,7 +221,6 @@
 },
 {
 	.name = "pxa2xx-ac97-mic",
-	.id = 2,
 	.ac97_control = 1,
 	.capture = {
 		.stream_name = "AC97 Mic Capture",
@@ -243,36 +232,26 @@
 },
 };
 
-EXPORT_SYMBOL_GPL(pxa_ac97_dai);
 EXPORT_SYMBOL_GPL(soc_ac97_ops);
 
-static int __devinit pxa2xx_ac97_dev_probe(struct platform_device *pdev)
+static __devinit int pxa2xx_ac97_dev_probe(struct platform_device *pdev)
 {
-	int i;
-	pxa2xx_audio_ops_t *pdata = pdev->dev.platform_data;
-
-	if (pdev->id >= 0) {
+	if (pdev->id != -1) {
 		dev_err(&pdev->dev, "PXA2xx has only one AC97 port.\n");
 		return -ENXIO;
 	}
 
-	for (i = 0; i < ARRAY_SIZE(pxa_ac97_dai); i++) {
-		pxa_ac97_dai[i].dev = &pdev->dev;
-		if (pdata && pdata->codec_pdata[0])
-			pxa_ac97_dai[i].ac97_pdata = pdata->codec_pdata[0];
-	}
-
 	/* Punt most of the init to the SoC probe; we may need the machine
 	 * driver to do interesting things with the clocking to get us up
 	 * and running.
 	 */
-	return snd_soc_register_dais(pxa_ac97_dai, ARRAY_SIZE(pxa_ac97_dai));
+	return snd_soc_register_dais(&pdev->dev, pxa_ac97_dai,
+			ARRAY_SIZE(pxa_ac97_dai));
 }
 
 static int __devexit pxa2xx_ac97_dev_remove(struct platform_device *pdev)
 {
-	snd_soc_unregister_dais(pxa_ac97_dai, ARRAY_SIZE(pxa_ac97_dai));
-
+	snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(pxa_ac97_dai));
 	return 0;
 }
 
diff --git a/sound/soc/pxa/pxa2xx-ac97.h b/sound/soc/pxa/pxa2xx-ac97.h
index e390de8..eda891e 100644
--- a/sound/soc/pxa/pxa2xx-ac97.h
+++ b/sound/soc/pxa/pxa2xx-ac97.h
@@ -14,8 +14,6 @@
 #define PXA2XX_DAI_AC97_AUX		1
 #define PXA2XX_DAI_AC97_MIC		2
 
-extern struct snd_soc_dai pxa_ac97_dai[3];
-
 /* platform data */
 extern struct snd_ac97_bus_ops pxa2xx_ac97_ops;
 
diff --git a/sound/soc/pxa/pxa2xx-i2s.c b/sound/soc/pxa/pxa2xx-i2s.c
index c1a52757..3b473b2 100644
--- a/sound/soc/pxa/pxa2xx-i2s.c
+++ b/sound/soc/pxa/pxa2xx-i2s.c
@@ -80,6 +80,7 @@
 };
 static struct pxa_i2s_port pxa_i2s;
 static struct clk *clk_i2s;
+static int clk_ena = 0;
 
 static struct pxa2xx_pcm_dma_params pxa2xx_i2s_pcm_stereo_out = {
 	.name			= "I2S PCM Stereo out",
@@ -101,7 +102,7 @@
 			      struct snd_soc_dai *dai)
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
+	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
 
 	if (IS_ERR(clk_i2s))
 		return PTR_ERR(clk_i2s);
@@ -162,13 +163,11 @@
 				struct snd_pcm_hw_params *params,
 				struct snd_soc_dai *dai)
 {
-	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
 	struct pxa2xx_pcm_dma_params *dma_data;
 
 	BUG_ON(IS_ERR(clk_i2s));
 	clk_enable(clk_i2s);
-	dai->private_data = dai;
+	clk_ena = 1;
 	pxa_i2s_wait();
 
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
@@ -176,7 +175,7 @@
 	else
 		dma_data = &pxa2xx_i2s_pcm_stereo_in;
 
-	snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data);
+	snd_soc_dai_set_dma_data(dai, substream, dma_data);
 
 	/* is port used by another stream */
 	if (!(SACR0 & SACR0_ENB)) {
@@ -259,9 +258,9 @@
 	if ((SACR1 & (SACR1_DREC | SACR1_DRPL)) == (SACR1_DREC | SACR1_DRPL)) {
 		SACR0 &= ~SACR0_ENB;
 		pxa_i2s_wait();
-		if (dai->private_data != NULL) {
+		if (clk_ena) {
 			clk_disable(clk_i2s);
-			dai->private_data = NULL;
+			clk_ena = 0;
 		}
 	}
 }
@@ -300,6 +299,35 @@
 #define pxa2xx_i2s_resume	NULL
 #endif
 
+static int pxa2xx_i2s_probe(struct snd_soc_dai *dai)
+{
+	clk_i2s = clk_get(dai->dev, "I2SCLK");
+	if (IS_ERR(clk_i2s))
+		return PTR_ERR(clk_i2s);
+
+	/*
+	 * PXA Developer's Manual:
+	 * If SACR0[ENB] is toggled in the middle of a normal operation,
+	 * the SACR0[RST] bit must also be set and cleared to reset all
+	 * I2S controller registers.
+	 */
+	SACR0 = SACR0_RST;
+	SACR0 = 0;
+	/* Make sure RPL and REC are disabled */
+	SACR1 = SACR1_DRPL | SACR1_DREC;
+	/* Along with FIFO servicing */
+	SAIMR &= ~(SAIMR_RFS | SAIMR_TFS);
+
+	return 0;
+}
+
+static int  pxa2xx_i2s_remove(struct snd_soc_dai *dai)
+{
+	clk_put(clk_i2s);
+	clk_i2s = ERR_PTR(-ENOENT);
+	return 0;
+}
+
 #define PXA2XX_I2S_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
 		SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 | \
 		SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000)
@@ -313,9 +341,9 @@
 	.set_sysclk	= pxa2xx_i2s_set_dai_sysclk,
 };
 
-struct snd_soc_dai pxa_i2s_dai = {
-	.name = "pxa2xx-i2s",
-	.id = 0,
+static struct snd_soc_dai_driver pxa_i2s_dai = {
+	.probe = pxa2xx_i2s_probe,
+	.remove = pxa2xx_i2s_remove,
 	.suspend = pxa2xx_i2s_suspend,
 	.resume = pxa2xx_i2s_resume,
 	.playback = {
@@ -332,49 +360,20 @@
 	.symmetric_rates = 1,
 };
 
-EXPORT_SYMBOL_GPL(pxa_i2s_dai);
-
-static int pxa2xx_i2s_probe(struct platform_device *dev)
+static int pxa2xx_i2s_drv_probe(struct platform_device *pdev)
 {
-	int ret;
-
-	clk_i2s = clk_get(&dev->dev, "I2SCLK");
-	if (IS_ERR(clk_i2s))
-		return PTR_ERR(clk_i2s);
-
-	pxa_i2s_dai.dev = &dev->dev;
-	pxa_i2s_dai.private_data = NULL;
-	ret = snd_soc_register_dai(&pxa_i2s_dai);
-	if (ret != 0)
-		clk_put(clk_i2s);
-
-	/*
-	 * PXA Developer's Manual:
-	 * If SACR0[ENB] is toggled in the middle of a normal operation,
-	 * the SACR0[RST] bit must also be set and cleared to reset all
-	 * I2S controller registers.
-	 */
-	SACR0 = SACR0_RST;
-	SACR0 = 0;
-	/* Make sure RPL and REC are disabled */
-	SACR1 = SACR1_DRPL | SACR1_DREC;
-	/* Along with FIFO servicing */
-	SAIMR &= ~(SAIMR_RFS | SAIMR_TFS);
-
-	return ret;
+	return snd_soc_register_dai(&pdev->dev, &pxa_i2s_dai);
 }
 
-static int __devexit pxa2xx_i2s_remove(struct platform_device *dev)
+static int __devexit pxa2xx_i2s_drv_remove(struct platform_device *pdev)
 {
-	snd_soc_unregister_dai(&pxa_i2s_dai);
-	clk_put(clk_i2s);
-	clk_i2s = ERR_PTR(-ENOENT);
+	snd_soc_unregister_dai(&pdev->dev);
 	return 0;
 }
 
 static struct platform_driver pxa2xx_i2s_driver = {
-	.probe = pxa2xx_i2s_probe,
-	.remove = __devexit_p(pxa2xx_i2s_remove),
+	.probe = pxa2xx_i2s_drv_probe,
+	.remove = __devexit_p(pxa2xx_i2s_drv_remove),
 
 	.driver = {
 		.name = "pxa2xx-i2s",
diff --git a/sound/soc/pxa/pxa2xx-i2s.h b/sound/soc/pxa/pxa2xx-i2s.h
index e2def44..070f3c6 100644
--- a/sound/soc/pxa/pxa2xx-i2s.h
+++ b/sound/soc/pxa/pxa2xx-i2s.h
@@ -15,6 +15,4 @@
 /* I2S clock */
 #define PXA2XX_I2S_SYSCLK		0
 
-extern struct snd_soc_dai pxa_i2s_dai;
-
 #endif
diff --git a/sound/soc/pxa/pxa2xx-pcm.c b/sound/soc/pxa/pxa2xx-pcm.c
index adc7e6f..5127044 100644
--- a/sound/soc/pxa/pxa2xx-pcm.c
+++ b/sound/soc/pxa/pxa2xx-pcm.c
@@ -28,7 +28,7 @@
 	struct pxa2xx_pcm_dma_params *dma;
 	int ret;
 
-	dma = snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream);
+	dma = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
 
 	/* return if this is a bufferless transfer e.g.
 	 * codec <--> BT codec or GSM modem -- lg FIXME */
@@ -95,14 +95,14 @@
 	if (!card->dev->coherent_dma_mask)
 		card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
 
-	if (dai->playback.channels_min) {
+	if (dai->driver->playback.channels_min) {
 		ret = pxa2xx_pcm_preallocate_dma_buffer(pcm,
 			SNDRV_PCM_STREAM_PLAYBACK);
 		if (ret)
 			goto out;
 	}
 
-	if (dai->capture.channels_min) {
+	if (dai->driver->capture.channels_min) {
 		ret = pxa2xx_pcm_preallocate_dma_buffer(pcm,
 			SNDRV_PCM_STREAM_CAPTURE);
 		if (ret)
@@ -112,25 +112,44 @@
 	return ret;
 }
 
-struct snd_soc_platform pxa2xx_soc_platform = {
-	.name		= "pxa2xx-audio",
-	.pcm_ops 	= &pxa2xx_pcm_ops,
+static struct snd_soc_platform_driver pxa2xx_soc_platform = {
+	.ops 	= &pxa2xx_pcm_ops,
 	.pcm_new	= pxa2xx_soc_pcm_new,
 	.pcm_free	= pxa2xx_pcm_free_dma_buffers,
 };
-EXPORT_SYMBOL_GPL(pxa2xx_soc_platform);
 
-static int __init pxa2xx_soc_platform_init(void)
+static int __devinit pxa2xx_soc_platform_probe(struct platform_device *pdev)
 {
-	return snd_soc_register_platform(&pxa2xx_soc_platform);
+	return snd_soc_register_platform(&pdev->dev, &pxa2xx_soc_platform);
 }
-module_init(pxa2xx_soc_platform_init);
 
-static void __exit pxa2xx_soc_platform_exit(void)
+static int __devexit pxa2xx_soc_platform_remove(struct platform_device *pdev)
 {
-	snd_soc_unregister_platform(&pxa2xx_soc_platform);
+	snd_soc_unregister_platform(&pdev->dev);
+	return 0;
 }
-module_exit(pxa2xx_soc_platform_exit);
+
+static struct platform_driver pxa_pcm_driver = {
+	.driver = {
+			.name = "pxa-pcm-audio",
+			.owner = THIS_MODULE,
+	},
+
+	.probe = pxa2xx_soc_platform_probe,
+	.remove = __devexit_p(pxa2xx_soc_platform_remove),
+};
+
+static int __init snd_pxa_pcm_init(void)
+{
+	return platform_driver_register(&pxa_pcm_driver);
+}
+module_init(snd_pxa_pcm_init);
+
+static void __exit snd_pxa_pcm_exit(void)
+{
+	platform_driver_unregister(&pxa_pcm_driver);
+}
+module_exit(snd_pxa_pcm_exit);
 
 MODULE_AUTHOR("Nicolas Pitre");
 MODULE_DESCRIPTION("Intel PXA2xx PCM DMA module");
diff --git a/sound/soc/pxa/pxa2xx-pcm.h b/sound/soc/pxa/pxa2xx-pcm.h
deleted file mode 100644
index 60c3b20..0000000
--- a/sound/soc/pxa/pxa2xx-pcm.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * linux/sound/arm/pxa2xx-pcm.h -- ALSA PCM interface for the Intel PXA2xx chip
- *
- * Author:	Nicolas Pitre
- * Created:	Nov 30, 2004
- * Copyright:	MontaVista Software, Inc.
- *
- * 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 _PXA2XX_PCM_H
-#define _PXA2XX_PCM_H
-
-/* platform data */
-extern struct snd_soc_platform pxa2xx_soc_platform;
-
-#endif
diff --git a/sound/soc/pxa/raumfeld.c b/sound/soc/pxa/raumfeld.c
index 7e3f416..2cda82bc 100644
--- a/sound/soc/pxa/raumfeld.c
+++ b/sound/soc/pxa/raumfeld.c
@@ -26,9 +26,6 @@
 
 #include <asm/mach-types.h>
 
-#include "../codecs/cs4270.h"
-#include "../codecs/ak4104.h"
-#include "pxa2xx-pcm.h"
 #include "pxa-ssp.h"
 
 #define GPIO_SPDIF_RESET	(38)
@@ -71,7 +68,7 @@
 static int raumfeld_cs4270_startup(struct snd_pcm_substream *substream)
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
+	struct snd_soc_dai *codec_dai = rtd->codec_dai;
 
 	/* set freq to 0 to enable all possible codec sample rates */
 	return snd_soc_dai_set_sysclk(codec_dai, 0, 0, 0);
@@ -80,7 +77,7 @@
 static void raumfeld_cs4270_shutdown(struct snd_pcm_substream *substream)
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
+	struct snd_soc_dai *codec_dai = rtd->codec_dai;
 
 	/* set freq to 0 to enable all possible codec sample rates */
 	snd_soc_dai_set_sysclk(codec_dai, 0, 0, 0);
@@ -90,8 +87,8 @@
 				     struct snd_pcm_hw_params *params)
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
-	struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
+	struct snd_soc_dai *codec_dai = rtd->codec_dai;
+	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
 	unsigned int fmt, clk = 0;
 	int ret = 0;
 
@@ -167,32 +164,14 @@
 	return 0;
 }
 
-static struct snd_soc_dai_link raumfeld_line_dai = {
-	.name		= "CS4270",
-	.stream_name	= "CS4270",
-	.cpu_dai	= &pxa_ssp_dai[PXA_DAI_SSP1],
-	.codec_dai	= &cs4270_dai,
-	.ops		= &raumfeld_cs4270_ops,
-};
-
-static struct snd_soc_card snd_soc_line_raumfeld = {
-	.name		= "Raumfeld analog",
-	.platform	= &pxa2xx_soc_platform,
-	.dai_link	= &raumfeld_line_dai,
-	.suspend_post	= raumfeld_line_suspend,
-	.resume_pre	= raumfeld_line_resume,
-	.num_links	= 1,
-};
-
-
 /* AK4104 */
 
 static int raumfeld_ak4104_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_dai *codec_dai = rtd->dai->codec_dai;
-	struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
+	struct snd_soc_dai *codec_dai = rtd->codec_dai;
+	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
 	int fmt, ret = 0, clk = 0;
 
 	switch (params_rate(params)) {
@@ -247,34 +226,35 @@
 	.hw_params = raumfeld_ak4104_hw_params,
 };
 
-static struct snd_soc_dai_link raumfeld_spdif_dai = {
+static struct snd_soc_dai_link raumfeld_dai[] = {
+{
 	.name		= "ak4104",
 	.stream_name	= "Playback",
-	.cpu_dai	= &pxa_ssp_dai[PXA_DAI_SSP2],
-	.codec_dai	= &ak4104_dai,
+	.cpu_dai_name = "pxa-ssp-dai.1",
+	.codec_dai_name = "ak4104-hifi",
+	.platform_name = "pxa-pcm-audio",
 	.ops		= &raumfeld_ak4104_ops,
+	.codec_name = "ak4104-codec.0",
+},
+{
+	.name		= "CS4270",
+	.stream_name	= "CS4270",
+	.cpu_dai_name = "pxa-ssp-dai.0",
+	.platform_name = "pxa-pcm-audio",
+	.codec_dai_name = "cs4270-hifi",
+	.codec_name = "cs4270-codec.0-0048",
+	.ops		= &raumfeld_cs4270_ops,
+},};
+
+static struct snd_soc_card snd_soc_raumfeld = {
+	.name		= "Raumfeld",
+	.dai_link	= raumfeld_dai,
+	.suspend_post	= raumfeld_line_suspend,
+	.resume_pre	= raumfeld_line_resume,
+	.num_links	= ARRAY_SIZE(raumfeld_dai),
 };
 
-static struct snd_soc_card snd_soc_spdif_raumfeld = {
-	.name		= "Raumfeld S/PDIF",
-	.platform	= &pxa2xx_soc_platform,
-	.dai_link	= &raumfeld_spdif_dai,
-	.num_links	= 1
-};
-
-/* raumfeld_audio audio subsystem */
-static struct snd_soc_device raumfeld_line_devdata = {
-	.card = &snd_soc_line_raumfeld,
-	.codec_dev = &soc_codec_device_cs4270,
-};
-
-static struct snd_soc_device raumfeld_spdif_devdata = {
-	.card = &snd_soc_spdif_raumfeld,
-	.codec_dev = &soc_codec_device_ak4104,
-};
-
-static struct platform_device *raumfeld_audio_line_device;
-static struct platform_device *raumfeld_audio_spdif_device;
+static struct platform_device *raumfeld_audio_device;
 
 static int __init raumfeld_audio_init(void)
 {
@@ -292,38 +272,19 @@
 
 	set_max9485_clk(MAX9485_MCLK_FREQ_122880);
 
-	/* LINE */
-	raumfeld_audio_line_device = platform_device_alloc("soc-audio", 0);
-	if (!raumfeld_audio_line_device)
+	/* Register LINE and SPDIF */
+	raumfeld_audio_device = platform_device_alloc("soc-audio", 0);
+	if (!raumfeld_audio_device)
 		return -ENOMEM;
 
-	platform_set_drvdata(raumfeld_audio_line_device,
-			     &raumfeld_line_devdata);
-	raumfeld_line_devdata.dev = &raumfeld_audio_line_device->dev;
-	ret = platform_device_add(raumfeld_audio_line_device);
-	if (ret)
-		platform_device_put(raumfeld_audio_line_device);
+	platform_set_drvdata(raumfeld_audio_device,
+			     &snd_soc_raumfeld);
+	ret = platform_device_add(raumfeld_audio_device);
 
 	/* no S/PDIF on Speakers */
 	if (machine_is_raumfeld_speaker())
 		return ret;
 
-	/* S/PDIF */
-	raumfeld_audio_spdif_device = platform_device_alloc("soc-audio", 1);
-	if (!raumfeld_audio_spdif_device) {
-		platform_device_put(raumfeld_audio_line_device);
-		return -ENOMEM;
-	}
-
-	platform_set_drvdata(raumfeld_audio_spdif_device,
-			     &raumfeld_spdif_devdata);
-	raumfeld_spdif_devdata.dev = &raumfeld_audio_spdif_device->dev;
-	ret = platform_device_add(raumfeld_audio_spdif_device);
-	if (ret) {
-		platform_device_put(raumfeld_audio_line_device);
-		platform_device_put(raumfeld_audio_spdif_device);
-	}
-
 	raumfeld_enable_audio(true);
 
 	return ret;
@@ -333,10 +294,7 @@
 {
 	raumfeld_enable_audio(false);
 
-	platform_device_unregister(raumfeld_audio_line_device);
-
-	if (machine_is_raumfeld_connector())
-		platform_device_unregister(raumfeld_audio_spdif_device);
+	platform_device_unregister(raumfeld_audio_device);
 
 	i2c_unregister_device(max9486_client);
 
diff --git a/sound/soc/pxa/spitz.c b/sound/soc/pxa/spitz.c
index 1941a35..f470f36 100644
--- a/sound/soc/pxa/spitz.c
+++ b/sound/soc/pxa/spitz.c
@@ -28,7 +28,6 @@
 #include <asm/mach-types.h>
 #include <mach/spitz.h>
 #include "../codecs/wm8750.h"
-#include "pxa2xx-pcm.h"
 #include "pxa2xx-i2s.h"
 
 #define SPITZ_HP        0
@@ -107,7 +106,7 @@
 static int spitz_startup(struct snd_pcm_substream *substream)
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct snd_soc_codec *codec = rtd->socdev->card->codec;
+	struct snd_soc_codec *codec = rtd->codec;
 
 	/* check the jack status at stream startup */
 	spitz_ext_control(codec);
@@ -118,8 +117,8 @@
 	struct snd_pcm_hw_params *params)
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
-	struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
+	struct snd_soc_dai *codec_dai = rtd->codec_dai;
+	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
 	unsigned int clk = 0;
 	int ret = 0;
 
@@ -274,8 +273,9 @@
 /*
  * Logic for a wm8750 as connected on a Sharp SL-Cxx00 Device
  */
-static int spitz_wm8750_init(struct snd_soc_codec *codec)
+static int spitz_wm8750_init(struct snd_soc_pcm_runtime *rtd)
 {
+	struct snd_soc_codec *codec = rtd->codec;
 	int err;
 
 	/* NC codec pins */
@@ -308,8 +308,10 @@
 static struct snd_soc_dai_link spitz_dai = {
 	.name = "wm8750",
 	.stream_name = "WM8750",
-	.cpu_dai = &pxa_i2s_dai,
-	.codec_dai = &wm8750_dai,
+	.cpu_dai_name = "pxa-is2",
+	.codec_dai_name = "wm8750-hifi",
+	.platform_name = "pxa-pcm-audio",
+	.codec_name = "wm8750-codec.0-001a",
 	.init = spitz_wm8750_init,
 	.ops = &spitz_ops,
 };
@@ -317,49 +319,10 @@
 /* spitz audio machine driver */
 static struct snd_soc_card snd_soc_spitz = {
 	.name = "Spitz",
-	.platform = &pxa2xx_soc_platform,
 	.dai_link = &spitz_dai,
 	.num_links = 1,
 };
 
-/* spitz audio subsystem */
-static struct snd_soc_device spitz_snd_devdata = {
-	.card = &snd_soc_spitz,
-	.codec_dev = &soc_codec_dev_wm8750,
-};
-
-/*
- * FIXME: This is a temporary bodge to avoid cross-tree merge issues.
- * New drivers should register the wm8750 I2C device in the machine
- * setup code (under arch/arm for ARM systems).
- */
-static int wm8750_i2c_register(void)
-{
-	struct i2c_board_info info;
-	struct i2c_adapter *adapter;
-	struct i2c_client *client;
-
-	memset(&info, 0, sizeof(struct i2c_board_info));
-	info.addr = 0x1b;
-	strlcpy(info.type, "wm8750", I2C_NAME_SIZE);
-
-	adapter = i2c_get_adapter(0);
-	if (!adapter) {
-		printk(KERN_ERR "can't get i2c adapter 0\n");
-		return -ENODEV;
-	}
-
-	client = i2c_new_device(adapter, &info);
-	i2c_put_adapter(adapter);
-	if (!client) {
-		printk(KERN_ERR "can't add i2c device at 0x%x\n",
-		(unsigned int)info.addr);
-		return -ENODEV;
-	}
-
-	return 0;
-}
-
 static struct platform_device *spitz_snd_device;
 
 static int __init spitz_init(void)
@@ -369,16 +332,11 @@
 	if (!(machine_is_spitz() || machine_is_borzoi() || machine_is_akita()))
 		return -ENODEV;
 
-	ret = wm8750_i2c_setup();
-	if (ret != 0)
-		return ret;
-
 	spitz_snd_device = platform_device_alloc("soc-audio", -1);
 	if (!spitz_snd_device)
 		return -ENOMEM;
 
-	platform_set_drvdata(spitz_snd_device, &spitz_snd_devdata);
-	spitz_snd_devdata.dev = &spitz_snd_device->dev;
+	platform_set_drvdata(spitz_snd_device, &snd_soc_spitz);
 	ret = platform_device_add(spitz_snd_device);
 
 	if (ret)
diff --git a/sound/soc/pxa/tosa.c b/sound/soc/pxa/tosa.c
index dbbd3e9..a3bfb2e 100644
--- a/sound/soc/pxa/tosa.c
+++ b/sound/soc/pxa/tosa.c
@@ -33,7 +33,6 @@
 #include <mach/audio.h>
 
 #include "../codecs/wm9712.h"
-#include "pxa2xx-pcm.h"
 #include "pxa2xx-ac97.h"
 
 static struct snd_soc_card tosa;
@@ -80,7 +79,7 @@
 static int tosa_startup(struct snd_pcm_substream *substream)
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct snd_soc_codec *codec = rtd->socdev->card->codec;
+	struct snd_soc_codec *codec = rtd->card->codec;
 
 	/* check the jack status at stream startup */
 	tosa_ext_control(codec);
@@ -184,8 +183,9 @@
 		tosa_set_spk),
 };
 
-static int tosa_ac97_init(struct snd_soc_codec *codec)
+static int tosa_ac97_init(struct snd_soc_pcm_runtime *rtd)
 {
+	struct snd_soc_codec *codec = rtd->codec;
 	int err;
 
 	snd_soc_dapm_nc_pin(codec, "OUT3");
@@ -212,16 +212,20 @@
 {
 	.name = "AC97",
 	.stream_name = "AC97 HiFi",
-	.cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_HIFI],
-	.codec_dai = &wm9712_dai[WM9712_DAI_AC97_HIFI],
+	.cpu_dai_name = "pxa-ac97.0",
+	.codec_dai_name = "wm9712-hifi",
+	.platform_name = "pxa-pcm-audio",
+	.codec_name = "wm9712-codec",
 	.init = tosa_ac97_init,
 	.ops = &tosa_ops,
 },
 {
 	.name = "AC97 Aux",
 	.stream_name = "AC97 Aux",
-	.cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_AUX],
-	.codec_dai = &wm9712_dai[WM9712_DAI_AC97_AUX],
+	.cpu_dai_name = "pxa-ac97.1",
+	.codec_dai_name = "wm9712-aux",
+	.platform_name = "pxa-pcm-audio",
+	.codec_name = "wm9712-codec",
 	.ops = &tosa_ops,
 },
 };
@@ -248,18 +252,12 @@
 
 static struct snd_soc_card tosa = {
 	.name = "Tosa",
-	.platform = &pxa2xx_soc_platform,
 	.dai_link = tosa_dai,
 	.num_links = ARRAY_SIZE(tosa_dai),
 	.probe = tosa_probe,
 	.remove = tosa_remove,
 };
 
-static struct snd_soc_device tosa_snd_devdata = {
-	.card = &tosa,
-	.codec_dev = &soc_codec_dev_wm9712,
-};
-
 static struct platform_device *tosa_snd_device;
 
 static int __init tosa_init(void)
@@ -275,8 +273,7 @@
 		goto err_alloc;
 	}
 
-	platform_set_drvdata(tosa_snd_device, &tosa_snd_devdata);
-	tosa_snd_devdata.dev = &tosa_snd_device->dev;
+	platform_set_drvdata(tosa_snd_device, &tosa);
 	ret = platform_device_add(tosa_snd_device);
 
 	if (!ret)
diff --git a/sound/soc/pxa/z2.c b/sound/soc/pxa/z2.c
index 4e4d2fa..704f74b 100644
--- a/sound/soc/pxa/z2.c
+++ b/sound/soc/pxa/z2.c
@@ -30,7 +30,6 @@
 #include <mach/z2.h>
 
 #include "../codecs/wm8750.h"
-#include "pxa2xx-pcm.h"
 #include "pxa2xx-i2s.h"
 
 static struct snd_soc_card snd_soc_z2;
@@ -39,8 +38,8 @@
 	struct snd_pcm_hw_params *params)
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
-	struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
+	struct snd_soc_dai *codec_dai = rtd->codec_dai;
+	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
 	unsigned int clk = 0;
 	int ret = 0;
 
@@ -138,8 +137,9 @@
 /*
  * Logic for a wm8750 as connected on a Z2 Device
  */
-static int z2_wm8750_init(struct snd_soc_codec *codec)
+static int z2_wm8750_init(struct snd_soc_pcm_runtime *rtd)
 {
+	struct snd_soc_codec *codec = rtd->codec;
 	int ret;
 
 	/* NC codec pins */
@@ -160,7 +160,7 @@
 		goto err;
 
 	/* Jack detection API stuff */
-	ret = snd_soc_jack_new(&snd_soc_z2, "Headset Jack", SND_JACK_HEADSET,
+	ret = snd_soc_jack_new(codec, "Headset Jack", SND_JACK_HEADSET,
 				&hs_jack);
 	if (ret)
 		goto err;
@@ -189,8 +189,10 @@
 static struct snd_soc_dai_link z2_dai = {
 	.name		= "wm8750",
 	.stream_name	= "WM8750",
-	.cpu_dai	= &pxa_i2s_dai,
-	.codec_dai	= &wm8750_dai,
+	.cpu_dai_name	= "pxa-i2s",
+	.codec_dai_name	= "wm8750-hifi",
+	.platform_name = "pxa-pcm-audio",
+	.codec_name	= "wm8750-codec.0-001a",
 	.init		= z2_wm8750_init,
 	.ops		= &z2_ops,
 };
@@ -198,17 +200,10 @@
 /* z2 audio machine driver */
 static struct snd_soc_card snd_soc_z2 = {
 	.name		= "Z2",
-	.platform	= &pxa2xx_soc_platform,
 	.dai_link	= &z2_dai,
 	.num_links	= 1,
 };
 
-/* z2 audio subsystem */
-static struct snd_soc_device z2_snd_devdata = {
-	.card		= &snd_soc_z2,
-	.codec_dev	= &soc_codec_dev_wm8750,
-};
-
 static struct platform_device *z2_snd_device;
 
 static int __init z2_init(void)
@@ -222,8 +217,7 @@
 	if (!z2_snd_device)
 		return -ENOMEM;
 
-	platform_set_drvdata(z2_snd_device, &z2_snd_devdata);
-	z2_snd_devdata.dev = &z2_snd_device->dev;
+	platform_set_drvdata(z2_snd_device, &snd_soc_z2);
 	ret = platform_device_add(z2_snd_device);
 
 	if (ret)
diff --git a/sound/soc/pxa/zylonite.c b/sound/soc/pxa/zylonite.c
index dd678ae..d27e05a 100644
--- a/sound/soc/pxa/zylonite.c
+++ b/sound/soc/pxa/zylonite.c
@@ -23,7 +23,6 @@
 #include <sound/soc-dapm.h>
 
 #include "../codecs/wm9713.h"
-#include "pxa2xx-pcm.h"
 #include "pxa2xx-ac97.h"
 #include "pxa-ssp.h"
 
@@ -71,10 +70,12 @@
 	{ "Multiactor", NULL, "SPKR" },
 };
 
-static int zylonite_wm9713_init(struct snd_soc_codec *codec)
+static int zylonite_wm9713_init(struct snd_soc_pcm_runtime *rtd)
 {
+	struct snd_soc_codec *codec = rtd->codec;
+
 	if (clk_pout)
-		snd_soc_dai_set_pll(&codec->dai[0], 0, 0,
+		snd_soc_dai_set_pll(rtd->codec_dai, 0, 0,
 				    clk_get_rate(pout), 0);
 
 	snd_soc_dapm_new_controls(codec, zylonite_dapm_widgets,
@@ -94,8 +95,8 @@
 				    struct snd_pcm_hw_params *params)
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
-	struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
+	struct snd_soc_dai *codec_dai = rtd->codec_dai;
+	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
 	unsigned int pll_out = 0;
 	unsigned int wm9713_div = 0;
 	int ret = 0;
@@ -163,21 +164,27 @@
 {
 	.name = "AC97",
 	.stream_name = "AC97 HiFi",
-	.cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_HIFI],
-	.codec_dai = &wm9713_dai[WM9713_DAI_AC97_HIFI],
+	.codec_name = "wm9713-codec",
+	.platform_name = "pxa-pcm-audio",
+	.cpu_dai_name = "pxa-ac97.0",
+	.codec_name = "wm9713-hifi",
 	.init = zylonite_wm9713_init,
 },
 {
 	.name = "AC97 Aux",
 	.stream_name = "AC97 Aux",
-	.cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_AUX],
-	.codec_dai = &wm9713_dai[WM9713_DAI_AC97_AUX],
+	.codec_name = "wm9713-codec",
+	.platform_name = "pxa-pcm-audio",
+	.cpu_dai_name = "pxa-ac97.1",
+	.codec_name = "wm9713-aux",
 },
 {
 	.name = "WM9713 Voice",
 	.stream_name = "WM9713 Voice",
-	.cpu_dai = &pxa_ssp_dai[PXA_DAI_SSP3],
-	.codec_dai = &wm9713_dai[WM9713_DAI_PCM_VOICE],
+	.codec_name = "wm9713-codec",
+	.platform_name = "pxa-pcm-audio",
+	.cpu_dai_name = "pxa-ssp-dai.2",
+	.codec_name = "wm9713-voice",
 	.ops = &zylonite_voice_ops,
 },
 };
@@ -248,14 +255,9 @@
 	.remove = &zylonite_remove,
 	.suspend_post = &zylonite_suspend_post,
 	.resume_pre = &zylonite_resume_pre,
-	.platform = &pxa2xx_soc_platform,
 	.dai_link = zylonite_dai,
 	.num_links = ARRAY_SIZE(zylonite_dai),
-};
-
-static struct snd_soc_device zylonite_snd_ac97_devdata = {
-	.card = &zylonite,
-	.codec_dev = &soc_codec_dev_wm9713,
+	.owner = THIS_MODULE,
 };
 
 static struct platform_device *zylonite_snd_ac97_device;
@@ -268,9 +270,7 @@
 	if (!zylonite_snd_ac97_device)
 		return -ENOMEM;
 
-	platform_set_drvdata(zylonite_snd_ac97_device,
-			     &zylonite_snd_ac97_devdata);
-	zylonite_snd_ac97_devdata.dev = &zylonite_snd_ac97_device->dev;
+	platform_set_drvdata(zylonite_snd_ac97_device, &zylonite);
 
 	ret = platform_device_add(zylonite_snd_ac97_device);
 	if (ret != 0)