Index: linux-2.6.15-rc2/include/sound/soc.h
===================================================================
--- linux-2.6.15-rc2.orig/include/sound/soc.h	2005-12-01 12:25:15.000000000 +0000
+++ linux-2.6.15-rc2/include/sound/soc.h	2005-12-03 13:49:43.000000000 +0000
@@ -117,10 +117,7 @@
 typedef int (*hw_write_t)(void *,const char* ,int);
 typedef int (*hw_read_t)(void *,char* ,int);
 
-extern struct bus_type soc_bus_type;
-
-int snd_soc_register_machine(struct snd_soc_machine *machine);
-void snd_soc_unregister_machine(struct snd_soc_machine *machine);
+extern struct bus_type soc_bus_type; /* FIXME - remove me */
 
 /* pcm <-> interface connect */
 void snd_soc_free_pcms(struct snd_soc_codec *codec);
@@ -219,10 +216,10 @@
 	unsigned int id;
 	unsigned char type;
 	
-	int (*probe)(struct device *dev);
-	void (*remove)(struct device *dev);
-	int (*suspend)(struct device *dev, pm_message_t state);
-	int (*resume)(struct device *dev);
+	int (*probe)(struct platform_device *pdev);
+	void (*remove)(struct platform_device *pdev);
+	int (*suspend)(struct platform_device *pdev, struct snd_soc_pcm_interface *iface);
+	int (*resume)(struct platform_device *pdev, struct snd_soc_pcm_interface *iface);
 	
 	/* interface pcm capabilities */
 	struct snd_soc_pcm_stream capture;
@@ -235,7 +232,7 @@
 	struct snd_soc_ops ops;
 	snd_pcm_runtime_t *runtime;
 	snd_card_t *card;
-	struct snd_soc_machine* machine;
+	struct snd_soc_machine* machine; /* FIXME - remove me */
 	unsigned char active:1;
 	
 	/* private data */
@@ -254,9 +251,9 @@
 	/* runtime */
 	snd_card_t *card;
 	ac97_t *ac97;
-	struct device *dev;
+	struct platform_device *pdev; /* FIXME - remove me */
 	void *private_data;
-	struct snd_soc_machine *machine;
+	struct snd_soc_machine *machine; /* FIXME - remove me */
 	int active_streams;
 	int pcm_devs;
 	int dpm_state;
@@ -276,16 +273,25 @@
 	struct snd_soc_pcm_codec *pcms;
 	int	npcms;
 };
-	
+
+struct snd_soc_codec_device {
+	struct platform_device *pdev;
+	int (*probe)(struct platform_device *pdev);
+	int (*remove)(struct platform_device *pdev);
+	int (*suspend)(struct platform_device *pdev, pm_message_t state);
+	int (*resume)(struct platform_device *pdev);
+	void *codec_data;
+};
+
+
 /* SoC platform interface */
 struct snd_soc_platform {
 	char *name;
 	
-	int	(*probe)(struct device * dev);
-	int	(*remove)(struct device * dev);
-	int (*suspend)(struct device *dev, pm_message_t state);
-	int (*resume)(struct device *dev);
-	struct bus_type	* bus;
+	int (*probe)(struct platform_device *pdev);
+	int (*remove)(struct platform_device *pdev);
+	int (*suspend)(struct platform_device *pdev, struct snd_soc_pcm_interface *iface);
+	int (*resume)(struct platform_device *pdev, struct snd_soc_pcm_interface *iface);
 	int (*pcm_new)(snd_card_t *, struct snd_soc_pcm_codec *, snd_pcm_t *);
 	void (*pcm_free)(snd_pcm_t *);
 	snd_pcm_ops_t *pcm_ops;
@@ -308,17 +314,25 @@
 struct snd_soc_machine {
 	char *name;
 	
-	int	(*probe)(struct device *dev);
-	int	(*remove)(struct device *dev);
-	int (*suspend)(struct device *dev, pm_message_t state);
-	int (*resume)(struct device *dev);
+	int (*probe)(struct platform_device *pdev);
+	int (*remove)(struct platform_device *pdev);
+	int (*suspend)(struct platform_device *pdev, pm_message_t state);
+	int (*resume)(struct platform_device *pdev);
 	
 	struct snd_soc_ops *ops;
 	struct snd_soc_machine_config *config;
 	int nconfigs;
-	struct device *dev;
 	
-	struct snd_soc_platform* platform;
+	struct snd_soc_platform* platform; /* FIXME - remove me */
+};
+
+/* SoC Device */
+struct snd_soc_platdev_data {
+	struct device *dev;
+	struct snd_soc_machine *machine;
+	struct snd_soc_platform *platform;
+	struct snd_soc_codec *codec;
+	struct snd_soc_codec_device *codec_dev;
 };
 
 /* enamerated kcontrol */
Index: linux-2.6.15-rc2/sound/soc/Makefile
===================================================================
--- linux-2.6.15-rc2.orig/sound/soc/Makefile	2005-12-01 12:25:15.000000000 +0000
+++ linux-2.6.15-rc2/sound/soc/Makefile	2005-12-02 23:28:04.000000000 +0000
@@ -1,5 +1,5 @@
 
-snd-soc-core-objs := soc-core.o soc-dpm.o soc-bus.o
+snd-soc-core-objs := soc-core.o soc-dpm.o
 
 obj-$(CONFIG_SND_SOC)	+= snd-soc-core.o
 obj-$(CONFIG_SND_SOC)	+= pxa/ codecs/
Index: linux-2.6.15-rc2/sound/soc/pxa/Kconfig
===================================================================
--- linux-2.6.15-rc2.orig/sound/soc/pxa/Kconfig	2005-12-01 12:25:15.000000000 +0000
+++ linux-2.6.15-rc2/sound/soc/pxa/Kconfig	2005-12-03 13:05:36.000000000 +0000
@@ -1,3 +1,5 @@
+menu "SoC Audio for the Intel PXA2xx"
+
 config SND_PXA2xx_SOC
 	tristate "SoC Audio for the Intel PXA2xx chip"
 	depends on ARCH_PXA && SND
@@ -8,51 +10,45 @@
 	  to select the audio interfaces to support below.
 
 config SND_PXA2xx_SOC_AC97
-	bool
+	tristate
 	select SND_AC97_CODEC
 	  
 config SND_PXA2xx_SOC_I2S
-	bool
+	tristate
 
 config SND_PXA2xx_SOC_SSP
-	bool
+	tristate
 	select PXA_SSP
-
-
-# Supported machines
-choice
-	prompt "PXA Audio Machine"
-	depends on SND_PXA2xx_SOC
-	default SND_PXA2xx_SOC_MAINSTONE
 	
 config SND_PXA2xx_SOC_MAINSTONE
-	bool "SoC AC97 Audio support for Intel Mainstone"
+	tristate "SoC AC97 Audio support for Intel Mainstone"
 	depends on SND_PXA2xx_SOC
 	select SND_PXA2xx_SOC_AC97
 	help
 	  Say Y if you want to add support for SoC audio on Mainstone.
 
 config SND_PXA2xx_SOC_MAINSTONE_TEST
-	bool "SoC I2S/SSP Audio support for Intel Mainstone - testing"
+	tristate "SoC I2S/SSP Audio support for Intel Mainstone - testing"
 	depends on SND_PXA2xx_SOC
 	select SND_PXA2xx_SOC_I2S
 	select SND_PXA2xx_SOC_SSP
 	help
 	  Say Y if you want to add support for SoC audio on Mainstone.
 
-config SND_PXA2xx_SOC_TOSA
-	bool "SoC AC97 Audio support for tosa"
-	depends on SND_PXA2xx_SOC
-	select SND_PXA2xx_SOC_AC97
-	help
-	  Say Y if you want to add support for SoC audio on tosa.
-	  
 config SND_PXA2xx_SOC_CORGI
-	bool "SoC Audio support for corgi"
+	tristate "SoC Audio support for Corgi"
 	depends on SND_PXA2xx_SOC
 	select SND_PXA2xx_SOC_I2S
 	help
-	  Say Y if you want to add support for SoC audio on corgi.
-	  
+	  Say Y if you want to add support for SoC audio on Sharp
+	  Zaurus SL-C7x0 models.
+
+config SND_PXA2xx_SOC_TOSA
+	tristate "SoC AC97 Audio support for Tosa"
+	depends on SND_PXA2xx_SOC
+	select SND_PXA2xx_SOC_AC97
+	help
+	  Say Y if you want to add support for SoC audio on Sharp
+	  Zaurus SL-C6000x models.
 
-endchoice
+endmenu
Index: linux-2.6.15-rc2/sound/soc/pxa/pxa2xx-pcm.c
===================================================================
--- linux-2.6.15-rc2.orig/sound/soc/pxa/pxa2xx-pcm.c	2005-12-01 12:25:15.000000000 +0000
+++ linux-2.6.15-rc2/sound/soc/pxa/pxa2xx-pcm.c	2005-12-02 23:42:45.000000000 +0000
@@ -353,10 +353,9 @@
 	return ret;
 }
 
-static int pxa2xx_pcm_suspend(struct device *dev, pm_message_t state)
+static int pxa2xx_pcm_suspend(struct platform_device *pdev, struct snd_soc_pcm_interface *iface)
 {
-	struct snd_soc_pcm_interface *pcm_i = dev->driver_data;
-	snd_pcm_runtime_t *runtime = pcm_i->runtime;
+	snd_pcm_runtime_t *runtime = iface->runtime;
 	struct pxa2xx_runtime_data *rtd;
 	
 	if(!runtime)
@@ -368,10 +367,9 @@
 	return 0;
 }
 
-static int pxa2xx_pcm_resume(struct device *dev)
+static int pxa2xx_pcm_resume(struct platform_device *pdev, struct snd_soc_pcm_interface *iface)
 {
-	struct snd_soc_pcm_interface *pcm_i = dev->driver_data;
-	snd_pcm_runtime_t *runtime = pcm_i->runtime;
+	snd_pcm_runtime_t *runtime = iface->runtime;
 	struct pxa2xx_runtime_data *rtd;
 	
 	if(!runtime)
@@ -388,7 +386,7 @@
 
 struct snd_soc_platform pxa2xx_soc_platform = {
 	.name		= "pxa2xx-audio",
-	.bus		= &platform_bus_type,
+//	.bus		= &platform_bus_type,
 	.pcm_ops 	= &pxa2xx_pcm_ops,
 	.pcm_new	= pxa2xx_pcm_new,
 	.pcm_free	= pxa2xx_pcm_free_dma_buffers,
Index: linux-2.6.15-rc2/sound/soc/soc-bus.c
===================================================================
--- linux-2.6.15-rc2.orig/sound/soc/soc-bus.c	2005-12-01 12:25:15.000000000 +0000
+++ /dev/null	1970-01-01 00:00:00.000000000 +0000
@@ -1,81 +0,0 @@
-/*
- * soc-bus.c  --  ALSA Soc Audio Layer
- *
- * Copyright 2005 Wolfson Microelectronics PLC.
- * Author: Liam Girdwood
- *         liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
- *
- *  This program is free software; you can redistribute  it and/or modify it
- *  under  the terms of  the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the  License, or (at your
- *  option) any later version.
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/device.h>
-#include <linux/string.h>
-#include <sound/soc.h>
-
-static int soc_bus_match(struct device *dev, struct device_driver *drv)
-{
-	/* match codec */
-	if(!strcmp(dev->bus_id, drv->name))
-		return 1;
-
-	/* match machine - machine has "-audio" in name */
-	if(strstr(dev->bus_id, "-audio") && !strcmp(drv->name, "soc-audio"))
-		return 1;
-	
-	return 0;
-}
-
-static int soc_bus_suspend(struct device *dev, pm_message_t state)
-{
-	int ret = 0;
-
-	if (dev->driver && dev->driver->suspend)
-		ret = dev->driver->suspend(dev, state);
-
-	return ret;
-}
-
-static int soc_bus_resume(struct device *dev)
-{
-	int ret = 0;
-
-	if (dev->driver && dev->driver->resume)
-		ret = dev->driver->resume(dev);
-
-	return ret;
-}
-
-struct bus_type soc_bus_type = {
-	.name		= "soc-audio",
-	.match		= soc_bus_match,
-	.suspend	= soc_bus_suspend,
-	.resume		= soc_bus_resume,
-};
-
-static int __init soc_bus_init(void)
-{
-	printk(KERN_INFO "soc: version %s liam.girdwood@wolfsonmicro.com\n", 
-		SND_SOC_VERSION);
-	return bus_register(&soc_bus_type);
-}
-
-subsys_initcall(soc_bus_init);
-
-static void __exit soc_bus_exit(void)
-{
-	bus_unregister(&soc_bus_type);
-}
-
-module_exit(soc_bus_exit);
-
-EXPORT_SYMBOL(soc_bus_type);
-
-/* Module information */ 
-MODULE_AUTHOR("Liam Girdwood, liam.girdwood@wolfsonmicro.com, www.wolfsonmicro.com");
-MODULE_DESCRIPTION("ALSA SoC Core");
-MODULE_LICENSE("GPL");
Index: linux-2.6.15-rc2/sound/soc/soc-core.c
===================================================================
--- linux-2.6.15-rc2.orig/sound/soc/soc-core.c	2005-12-01 12:25:15.000000000 +0000
+++ linux-2.6.15-rc2/sound/soc/soc-core.c	2005-12-03 13:47:15.000000000 +0000
@@ -45,8 +45,6 @@
 	((x) == SND_SOC_I2S) ? "i2s" : \
 	((x) == SND_SOC_SSP) ? "ssp" : NULL)
 
-static DECLARE_MUTEX(soc_sem);
-
 int snd_soc_update_bits(struct snd_soc_codec *codec, unsigned short reg,
 				unsigned short mask, unsigned short value)
 {
@@ -431,7 +429,6 @@
 	.trigger	= soc_pcm_trigger,
 };
 
-
 static void soc_free_dpm_widgets(struct snd_soc_codec *codec)
 {
 	struct snd_soc_dpm_widget *w, *lw = NULL;
@@ -464,44 +461,50 @@
  * SUSPEND_NOTIFY - mute outputs
  * SUSPEND_DISABLE - power down chip
  */
-static int soc_suspend(struct device * dev, pm_message_t state)
+static int soc_suspend(struct platform_device *pdev, pm_message_t state)
 {
-	struct snd_soc_machine * machine = 
-		(struct snd_soc_machine*)dev->platform_data;
-	struct snd_soc_platform *platform = machine->platform;
+	struct snd_soc_platdev_data *devdata = platform_get_drvdata(pdev);
+	struct snd_soc_machine *machine = devdata->machine;
+	struct snd_soc_platform *platform = devdata->platform;
+	struct snd_soc_codec_device* codec_dev = devdata->codec_dev;
 	int i;
 	
-	for(i = 0; platform->iface[i] != NULL; i++) {
-		dev->driver_data = platform->iface[i];
-		if(platform->suspend)
-			platform->suspend(dev, state);
-		if(platform->iface[i]->suspend)
-			platform->iface[i]->suspend(dev, state);
+	for (i = 0; platform->iface[i] != NULL; i++) {
+		if (platform->suspend)
+			platform->suspend(pdev, platform->iface[i]);
+		if (platform->iface[i]->suspend)
+			platform->iface[i]->suspend(pdev, platform->iface[i]);
 	}
-	dev->driver_data = NULL;
-	if(machine->suspend)
-		machine->suspend(dev, state);
+
+	if (codec_dev->suspend)
+		codec_dev->suspend(pdev, state);
+
+	if (machine->suspend)
+		machine->suspend(pdev, state);
+
 	return 0;
 }
 
-static int soc_resume(struct device * dev)
+static int soc_resume(struct platform_device *pdev)
 {
-	struct snd_soc_machine * machine = 
-		(struct snd_soc_machine*)dev->platform_data;
-	struct snd_soc_platform *platform = machine->platform;
+	struct snd_soc_platdev_data *devdata = platform_get_drvdata(pdev);
+	struct snd_soc_machine *machine = devdata->machine;
+	struct snd_soc_platform *platform = devdata->platform;
+	struct snd_soc_codec_device* codec_dev = devdata->codec_dev;
 	int i;
 	
-	if(machine->resume)
-		machine->resume(dev);
+	if (machine->resume)
+		machine->resume(pdev);
+
+	if (codec_dev->resume)
+		codec_dev->resume(pdev);
 		
-	for(i = 0; platform->iface[i] != NULL; i++) {
-		dev->driver_data = platform->iface[i];
+	for (i = 0; platform->iface[i] != NULL; i++) {
 		if(platform->iface[i]->resume)
-			platform->iface[i]->resume(dev);
+			platform->iface[i]->resume(pdev, platform->iface[i]);
 		if(platform->resume)
-			platform->resume(dev);
+			platform->resume(pdev, platform->iface[i]);
 	}
-	dev->driver_data = NULL;
 
 	return 0;
 }
@@ -511,107 +514,83 @@
 #define soc_resume	NULL
 #endif
 
-static int soc_probe(struct device * dev)
+static int soc_probe(struct platform_device *pdev)
 {
 	int ret = 0, i;
-	struct snd_soc_machine * machine 
-		= (struct snd_soc_machine*)dev->platform_data;
-	struct snd_soc_platform* platform = machine->platform;
+	struct snd_soc_platdev_data *devdata = platform_get_drvdata(pdev);
+	struct snd_soc_machine *machine = devdata->machine;
+	struct snd_soc_platform *platform = devdata->platform;
+	struct snd_soc_codec_device* codec_dev = devdata->codec_dev;
 
-	if(machine->probe && ((ret = machine->probe(dev)) < 0))
+	if (machine->probe && ((ret = machine->probe(pdev)) < 0))
 		return ret;
 
-	if(platform->probe && ((ret = platform->probe(dev)) < 0))
+	if (codec_dev->probe && ((ret = codec_dev->probe(pdev)) < 0))
+		goto codec_err;
+
+	if (platform->probe && ((ret = platform->probe(pdev)) < 0))
 		goto platform_err;
 
-	for(i = 0; platform->iface[i] != NULL; i++){
-		dev->driver_data = platform->iface[i];
+	for (i = 0; platform->iface[i] != NULL; i++) {
 		if(platform->iface[i]->probe && 
-			((ret = platform->iface[i]->probe(dev)) < 0))
+			((ret = platform->iface[i]->probe(pdev)) < 0))
 				goto iface_err;
 	}
-	dev->driver_data = NULL;
 	return 0;
 
 iface_err:
-	for(; i > 0; --i){
+	for (; i > 0; --i){
 		if(platform->iface[i]->remove) 
-			platform->iface[i]->remove(dev);
+			platform->iface[i]->remove(pdev);
 	}
 	
-	if(platform->remove)
-		platform->remove(dev);
-	
+	if (platform->remove)
+		platform->remove(pdev);
 platform_err:
-	if(machine->remove)
-			machine->remove(dev);
+	if (machine->remove)
+		machine->remove(pdev);
+codec_err:
+	if (codec_dev->remove)
+		codec_dev->remove(pdev);
 	
 	return ret;
 }
 
-static int soc_remove(struct device * dev)
+static int soc_remove(struct platform_device *pdev)
 {
 	int i;
-	struct snd_soc_machine * machine 
-		= (struct snd_soc_machine*)dev->platform_data;
-	struct snd_soc_platform * platform = machine->platform;
+	struct snd_soc_platdev_data *devdata = platform_get_drvdata(pdev);
+	struct snd_soc_machine *machine = devdata->machine;
+	struct snd_soc_platform *platform = devdata->platform;
+	struct snd_soc_codec_device* codec_dev = devdata->codec_dev;
 
-	for(i = 0; platform->iface[i] != NULL; i++){
+	for (i = 0; platform->iface[i] != NULL; i++) {
 		if(platform->iface[i]->remove)
-			platform->iface[i]->remove(dev);
+			platform->iface[i]->remove(pdev);
 	}
 
-	if(platform->remove)
-		platform->remove(dev);
+	if (platform->remove)
+		platform->remove(pdev);
+
+	if (codec_dev->remove)
+		codec_dev->remove(pdev);
 
-	if(machine->remove)
-			machine->remove(dev);
+	if (machine->remove)
+		machine->remove(pdev);
 	
 	return 0;
 }
 
-static struct device_driver soc_drv = {
-	.name = "soc-audio",
-	.bus = &soc_bus_type,
-	.probe = soc_probe,
-	.remove = soc_remove,
-	.suspend = soc_suspend,
-	.resume  = soc_resume,
+static struct platform_driver soc_driver = {
+	.driver		= {
+		.name		= "soc-audio",
+	},
+	.probe		= soc_probe,
+	.remove		= soc_remove,
+	.suspend	= soc_suspend,
+	.resume		= soc_resume,
 };
 
-int snd_soc_register_machine(struct snd_soc_machine *m)
-{
-	struct snd_soc_platform* platform = m->platform;
-	int ret = 0;
-
-	down(&soc_sem);
-	if(m->platform == NULL) {
-		up(&soc_sem);
-		return -ENODEV;
-	}
-
-	soc_pcm_ops.mmap = platform->pcm_ops->mmap;
-	soc_pcm_ops.pointer = platform->pcm_ops->pointer;
-	soc_pcm_ops.ioctl = platform->pcm_ops->ioctl;
-
-	if((ret = driver_register(&soc_drv)) < 0) {
-		printk(KERN_ERR "soc: failed to register machine %s\n", platform->name);
-		up(&soc_sem);
-		return ret;
-	}
-
-	up(&soc_sem);
-	return 0;
-}
-
-void snd_soc_unregister_machine(struct snd_soc_machine *m)
-{
-	down(&soc_sem);
-	driver_unregister(&soc_drv);
-	up(&soc_sem);	
-}
-
-
 static int soc_create_pcm(struct snd_soc_codec *codec, 
 	struct snd_soc_pcm_codec *pcm_c, struct snd_soc_pcm_interface *iface, 
 	int num)
@@ -633,6 +612,10 @@
 	iface->pcm_c = pcm_c;
 	pcm->private_data = pcm_c;
 
+	soc_pcm_ops.mmap = codec->machine->platform->pcm_ops->mmap;
+	soc_pcm_ops.pointer = codec->machine->platform->pcm_ops->pointer;
+	soc_pcm_ops.ioctl = codec->machine->platform->pcm_ops->ioctl;
+
 	if (pcm_c->nplayback)
 		snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &soc_pcm_ops);
 
@@ -677,7 +660,7 @@
 		return -ENODEV;
 	}
 
-	codec->card->dev = codec->dev;
+	codec->card->dev = &codec->pdev->dev;
 	codec->card->private_data = codec;
 	strncpy(codec->card->driver, codec->name, sizeof(codec->card->driver));
 	
@@ -708,13 +691,13 @@
 		return ret;
 	}
 	
-	snd_soc_dpm_sys_add(codec->dev);
+	snd_soc_dpm_sys_add(&codec->pdev->dev);
 	return ret;
 }
 
 void snd_soc_free_pcms(struct snd_soc_codec *codec)
 {
-	snd_soc_dpm_sys_remove(codec->dev);
+	snd_soc_dpm_sys_remove(&codec->pdev->dev);
 	soc_free_dpm_widgets(codec);
 	snd_card_free(codec->card);
 }
@@ -875,12 +858,24 @@
 EXPORT_SYMBOL_GPL(snd_soc_put_volsw);
 EXPORT_SYMBOL_GPL(snd_soc_update_bits);
 EXPORT_SYMBOL_GPL(snd_soc_test_bits);
-EXPORT_SYMBOL_GPL(snd_soc_register_machine);
-EXPORT_SYMBOL_GPL(snd_soc_unregister_machine);
 EXPORT_SYMBOL_GPL(snd_soc_register_pcms);
 EXPORT_SYMBOL_GPL(snd_soc_free_pcms);
 EXPORT_SYMBOL_GPL(snd_soc_register_card);
 
+
+static int __devinit snd_soc_init(void)
+{
+	return platform_driver_register(&soc_driver);
+}
+
+static void snd_soc_exit(void)
+{
+ 	platform_driver_unregister(&soc_driver);
+}
+
+module_init(snd_soc_init);
+module_exit(snd_soc_exit);
+
 /* Module information */ 
 MODULE_AUTHOR("Liam Girdwood, liam.girdwood@wolfsonmicro.com, www.wolfsonmicro.com");
 MODULE_DESCRIPTION("ALSA SoC Core");
Index: linux-2.6.15-rc2/sound/soc/pxa/corgi.c
===================================================================
--- linux-2.6.15-rc2.orig/sound/soc/pxa/corgi.c	2005-12-01 12:25:15.000000000 +0000
+++ linux-2.6.15-rc2/sound/soc/pxa/corgi.c	2005-12-03 13:05:36.000000000 +0000
@@ -24,16 +24,19 @@
 #include <linux/moduleparam.h>
 #include <linux/version.h>
 #include <linux/kernel.h>
-#include <linux/device.h>
-#include <linux/i2c.h>
+#include <linux/platform_device.h>
 #include <sound/driver.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/soc.h>
 #include <sound/soc-dpm.h>
 
+#include <asm/hardware/scoop.h>
 #include <asm/arch/pxa-regs.h>
-#include <asm/arch/mainstone.h>
+#include <asm/arch/corgi.h>
+//#include <asm/arch/spitz.h>
+
+
 #include <asm/arch/audio.h>
 
 #include "../codecs/wm8731.h"
@@ -55,22 +58,6 @@
 #define info(format, arg...) printk(KERN_INFO PFX ": " format "\n" , ## arg)
 #define warn(format, arg...) printk(KERN_WARNING PFX ": " format "\n" , ## arg)
 
-/* 
- * WM8731 2 wire address is determined by GPIO5
- * state during powerup.
- *    low  = 0x1a
- *    high = 0x1b
- */
-#define WM8731_2W_ADDR	0x1a
-#define I2C_DRIVERID_CORGI 0xfefe /* liam -  need a proper id */
-
-static unsigned short normal_i2c[] = { WM8731_2W_ADDR, I2C_CLIENT_END };
-
-/* Magic definition of all other variables and things */
-I2C_CLIENT_INSMOD;
-
-static struct i2c_driver wm8731_i2c_driver;
-static struct i2c_client client_template;
 
 static struct snd_soc_machine corgi;
 
@@ -89,26 +76,51 @@
 	.shutdown = corgi_shutdown,
 };
 
-static int corgi_suspend(struct device* dev, pm_message_t state)
+static int corgi_suspend(struct platform_device *pdev, pm_message_t state)
 {
 	return 0;
 }
 
-static int corgi_resume(struct device* dev)
+static int corgi_resume(struct platform_device *pdev)
 {
 	return 0;
 }
 
-static int corgi_probe(struct device* dev)
+static int corgi_probe(struct platform_device *pdev)
 {
 	return 0;
 }
 
-static int corgi_remove(struct device* dev)
+static int corgi_remove(struct platform_device *pdev)
 {
 	return 0;
 }
 
+static void corgi_mute_set(int val)
+{
+	if (val)
+		set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_L | CORGI_SCP_MUTE_R);
+	else
+		reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_L | CORGI_SCP_MUTE_R);
+}
+
+static void corgi_spk_set(int val)
+{
+	if (val)
+		set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_APM_ON);
+	else
+		reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_APM_ON);
+}
+
+//static void spite_mute_set(int val)
+//{
+//	if (val)
+//		set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_L | SPITZ_SCP_MUTE_R);
+//	else
+//		reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_L | SPITZ_SCP_MUTE_R);
+//}
+
+
 #ifdef TODO
 
 /*
@@ -210,121 +222,7 @@
 },
 };
 
-static void corgi_device_release(struct device * dev)
-{
-	kfree(dev);
-}
-
-
-/*
- * Attach WM8731 2 wire client 
- */
-static int corgi_codec_probe(struct i2c_adapter *adap, int addr, int kind)
-{		
-	int ret = 0;
-	struct snd_soc_codec *codec;
-	struct i2c_client *i2c;
-	struct device *dev;
-
-	if(addr != WM8731_2W_ADDR)
-		return -ENODEV;
-
-	client_template.adapter = adap;
-	client_template.addr = addr;
-	
-	if ((codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL)) == NULL)
-		return -ENOMEM;
- 
-	if ((i2c = kzalloc(sizeof(struct i2c_client), GFP_KERNEL)) == NULL){
-		kfree(codec);
-		return -ENOMEM;
-	}
-	memcpy(i2c, &client_template, sizeof(struct i2c_client));
-	codec->control_data = i2c;
-
-	if((ret = i2c_attach_client(i2c)) < 0) {
-		err("failed to attach codec at addr %x\n", addr);
-		kfree(i2c);
-		kfree(codec);
-		return ret;
-	}
-	
-	if((dev = kzalloc(sizeof(struct device), GFP_KERNEL)) == NULL) {
-		i2c_del_driver(&wm8731_i2c_driver);
-		kfree(i2c);
-		kfree(codec);
-		return -ENOMEM;
-	}
-
-	dev->bus = &soc_bus_type;
-	dev->parent = &i2c->dev;
-	dev->release = corgi_device_release;
-	snprintf(dev->bus_id, BUS_ID_SIZE, "WM8731");
-	i2c->dev.platform_data = dev;
-	dev->platform_data = codec;
-	codec->longname = "Corgi Audio Codec";
-	codec->dev = dev;
-	codec->machine = &corgi;
-	codec->hw_write = (hw_write_t)i2c_master_send;
-	INIT_LIST_HEAD(&codec->dpm_widgets);
-	INIT_LIST_HEAD(&codec->dpm_paths);
-
-	if((ret = device_register(dev)) < 0) {
-		err("can't register codec");
-		i2c_del_driver(&wm8731_i2c_driver);
-		kfree(i2c);
-		kfree(dev);
-		kfree(codec);
-	}
-
-	return ret;
-}
-
-static int corgi_i2c_detach(struct i2c_client *client)
-{
-	struct device *dev = (struct device*)client->dev.platform_data;
-	struct snd_soc_codec *codec = 
-		(struct snd_soc_codec*)dev->platform_data;
-
-	device_unregister(dev);
-	i2c_detach_client(client);
-	kfree(codec);
-	kfree(client);
-	return 0;
-}
-
-static int corgi_i2c_attach(struct i2c_adapter *adap)
-{
-	return i2c_probe(adap, &addr_data, corgi_codec_probe);
-}
-
-/* corgi i2c codec control layer */ 
-static struct i2c_driver corgi_i2c_driver = {
-	.name =           "Corgi i2c codec driver",
-	.id =             I2C_DRIVERID_CORGI,
-	.flags =          I2C_DF_NOTIFY,
-	.attach_adapter = corgi_i2c_attach,
-	.detach_client =  corgi_i2c_detach,
-	.command =        NULL,
-};
-
-static struct i2c_client client_template = {
-	.name =   "WM8731",
-	.flags =  I2C_CLIENT_ALLOW_USE,
-	.driver = &corgi_i2c_driver,
-};
-
-static int __init corgi_i2c_init(void)
-{
-	int ret = 0;
-	
-	if ((ret = i2c_add_driver(&corgi_i2c_driver)) != 0)
-		printk(KERN_ERR "can't add i2c driver");
-		
-	return ret;
-}
-
-static struct snd_soc_machine corgi = {
+static struct snd_soc_machine snd_soc_machine_corgi = {
 	.name = "Corgi",
 	.probe = corgi_probe,
 	.remove = corgi_remove,
@@ -336,43 +234,38 @@
 	.nconfigs = ARRAY_SIZE(codecs),
 };
 
+static struct snd_soc_platdev_data corgi_snd_devdata = {
+	.machine = &snd_soc_machine_corgi,
+	.platform = &pxa2xx_soc_platform,
+	.codec_dev = &soc_codec_dev_wm8731,
+};
+
+static struct platform_device *corgi_snd_device;
+
 static int __init corgi_init(void) 
 {
 	int ret;
-	struct device *dev;
 
 	pxa_i2s_interface.machine = &corgi;
-	
-	if((dev = kzalloc(sizeof(struct device), GFP_KERNEL)) == NULL) 
+	soc_codec_dev_wm8731.pdev = corgi_snd_device;
+	soc_codec_dev_wm8731.codec_data = (void *) 0x1a;
+
+	corgi_snd_device = platform_device_alloc("soc-audio", -1);
+	if (!corgi_snd_device)
 		return -ENOMEM;
-	
-	if((ret = snd_soc_register_machine(&corgi)) < 0) {
-		printk(KERN_ERR "can't register corgi soc audio\n");
-		return ret;
-	}
 
-	corgi.dev = dev;
-	dev->bus = &soc_bus_type;
-	dev->parent = NULL;
-	dev->release = corgi_device_release;
-	dev->platform_data = &corgi;
-	snprintf(dev->bus_id, BUS_ID_SIZE, "corgi-audio");
-
-	if((ret = device_register(dev)) < 0) {
-		err("can't register mainstone audio device");
-		kfree(dev);
-		snd_soc_unregister_machine(&corgi);
-	}
-	
-	corgi_i2c_init();
+	corgi_snd_device->dev.platform_data = &corgi_snd_devdata;
+	ret = platform_device_add(corgi_snd_device);
+
+	if (ret)
+		platform_device_put(corgi_snd_device);
+
 	return ret;
 }
 
 static void __exit corgi_exit(void) 
 {
-	device_unregister(corgi.dev);
-	i2c_del_driver(&corgi_i2c_driver);
-	snd_soc_unregister_machine(&corgi);
+	platform_device_unregister(corgi_snd_device);
 }
 
 module_init(corgi_init);
Index: linux-2.6.15-rc2/sound/soc/pxa/pxa2xx-i2s.c
===================================================================
--- linux-2.6.15-rc2.orig/sound/soc/pxa/pxa2xx-i2s.c	2005-12-01 12:25:15.000000000 +0000
+++ linux-2.6.15-rc2/sound/soc/pxa/pxa2xx-i2s.c	2005-12-02 23:43:48.000000000 +0000
@@ -234,10 +234,8 @@
 }
 
 #ifdef CONFIG_PM
-static int pxa2xx_i2s_suspend(struct device *dev, pm_message_t state)
+static int pxa2xx_i2s_suspend(struct platform_device *dev, struct snd_soc_pcm_interface *pcm_i)
 {
-	struct snd_soc_pcm_interface *pcm_i = dev->driver_data;
-	
 	if(!pcm_i->active)
 		return 0;
 		
@@ -252,10 +250,8 @@
 	return 0;
 }
 
-static int pxa2xx_i2s_resume(struct device *dev)
+static int pxa2xx_i2s_resume(struct platform_device *pdev, struct snd_soc_pcm_interface *pcm_i)
 {
-	struct snd_soc_pcm_interface *pcm_i = dev->driver_data;
-	
 	if(!pcm_i->active)
 		return 0;
 		
Index: linux-2.6.15-rc2/sound/soc/codecs/wm8731.c
===================================================================
--- linux-2.6.15-rc2.orig/sound/soc/codecs/wm8731.c	2005-12-01 12:25:15.000000000 +0000
+++ linux-2.6.15-rc2/sound/soc/codecs/wm8731.c	2005-12-03 13:05:36.000000000 +0000
@@ -19,7 +19,8 @@
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/pm.h>
-#include <linux/device.h>
+#include <linux/i2c.h>
+#include <linux/platform_device.h>
 #include <sound/driver.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
@@ -33,6 +34,8 @@
 #define AUDIO_NAME "wm8731"
 #define WM8731_VERSION "0.5"
 
+struct snd_soc_codec_device soc_codec_dev_wm8731;
+
 /*
  * Debug
  */
@@ -402,16 +405,20 @@
 		.hmodes = &wm8731_hwfmt[0],
 	},
 };
-static int wm8731_suspend(struct device *dev, pm_message_t state)
+static int wm8731_suspend(struct platform_device *pdev, pm_message_t state)
 {
-	struct snd_soc_codec* codec = (struct snd_soc_codec*)dev->platform_data;
+	struct snd_soc_platdev_data *devdata = platform_get_drvdata(pdev);
+	struct snd_soc_codec* codec = devdata->codec;
+
 	wm8731_dpm_event(codec, SNDRV_CTL_POWER_D3cold);
 	return 0;
 }
 
-static int wm8731_resume(struct device *dev)
+static int wm8731_resume(struct platform_device *pdev)
 {
-	struct snd_soc_codec* codec = (struct snd_soc_codec*)dev->platform_data;
+	struct snd_soc_platdev_data *devdata = platform_get_drvdata(pdev);
+	struct snd_soc_codec* codec = devdata->codec;
+
 	wm8731_dpm_event(codec, SNDRV_CTL_POWER_D3hot);
 	return 0;
 }
@@ -420,9 +427,8 @@
  * initialise the WM8731 driver
  * register the mixer and dsp interfaces with the kernel 
  */
-static int wm8731_probe(struct device *dev)
+static int wm8731_init(struct snd_soc_codec* codec)
 {
-	struct snd_soc_codec* codec = (struct snd_soc_codec*)dev->platform_data;
 	int reg, ret = 0;
 
 	codec->name = "WM8731";
@@ -466,39 +472,149 @@
 	return 0;
 }
 
-/* power down chip */
-static int wm8731_remove(struct device *dev)
+
+#ifdef CONFIG_I2C
+
+/*
+ * WM8731 2 wire address is determined by GPIO5
+ * state during powerup.
+ *    low  = 0x1a
+ *    high = 0x1b
+ */
+#define I2C_DRIVERID_WM8731 0xfefe /* liam -  need a proper id */
+
+static unsigned short normal_i2c[] = { 0, I2C_CLIENT_END };
+
+/* Magic definition of all other variables and things */
+I2C_CLIENT_INSMOD;
+
+static struct i2c_driver wm8731_i2c_driver;
+static struct i2c_client client_template;
+
+static int corgi_codec_probe(struct i2c_adapter *adap, int addr, int kind)
 {
-	struct snd_soc_codec* codec = (struct snd_soc_codec*)dev->platform_data;
-	wm8731_dpm_event(codec, SNDRV_CTL_POWER_D3cold);
-	snd_soc_free_pcms(codec);
+	struct snd_soc_platdev_data *devdata = platform_get_drvdata(soc_codec_dev_wm8731.pdev);
+	struct snd_soc_codec* codec = devdata->codec;
+	struct i2c_client *i2c;
+	int ret;
+
+	if (addr != (int)soc_codec_dev_wm8731.codec_data)
+		return -ENODEV;
+
+	client_template.adapter = adap;
+	client_template.addr = addr;
+
+	if ((i2c = kzalloc(sizeof(struct i2c_client), GFP_KERNEL)) == NULL){
+		kfree(codec);
+		return -ENOMEM;
+	}
+	memcpy(i2c, &client_template, sizeof(struct i2c_client));
+
+	i2c_set_clientdata(i2c, codec);
+
+	codec->control_data = i2c;
+
+	if((ret = i2c_attach_client(i2c)) < 0) {
+		err("failed to attach codec at addr %x\n", addr);
+		kfree(i2c);
+		return ret;
+	}
+
+	wm8731_init(codec);
+
+	return 0;
+}
+
+static int wm8731_i2c_detach(struct i2c_client *client)
+{
+	struct snd_soc_codec* codec = i2c_get_clientdata(client);
+
+	i2c_detach_client(client);
+
 	kfree(codec->reg_cache);
+	kfree(client);
+
 	return 0;
 }
 
-static struct device_driver wm8731_driver = {
-	.name = 	"WM8731", 
-	.bus = 		&soc_bus_type, 
-	.owner = 	THIS_MODULE, 
-	.probe = 	wm8731_probe, 
-	.remove = 	wm8731_remove, 
-	.suspend = 	wm8731_suspend, 
-	.resume =	wm8731_resume, 
+static int wm8731_i2c_attach(struct i2c_adapter *adap)
+{
+	return i2c_probe(adap, &addr_data, corgi_codec_probe);
+}
+
+/* corgi i2c codec control layer */
+static struct i2c_driver wm8731_i2c_driver = {
+	.name =           "WM8731 I2C Codec",
+	.id =             I2C_DRIVERID_WM8731,
+	.flags =          I2C_DF_NOTIFY,
+	.attach_adapter = wm8731_i2c_attach,
+	.detach_client =  wm8731_i2c_detach,
+	.command =        NULL,
+};
+
+static struct i2c_client client_template = {
+	.name =   "WM8731",
+	.flags =  I2C_CLIENT_ALLOW_USE,
+	.driver = &wm8731_i2c_driver,
 };
 
-static int __init wm8731_init(void)
+static int wm8731_probe(struct platform_device *pdev)
 {
+	struct snd_soc_platdev_data *devdata = platform_get_drvdata(pdev);
+	struct snd_soc_codec* codec;
+	int codec_data = (int) soc_codec_dev_wm8731.codec_data;
+	int ret = 0;
+
 	info("WM8731 Audio Codec %s", WM8731_VERSION);
-	return driver_register(&wm8731_driver);
+
+	if ((codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL)) == NULL)
+		return -ENOMEM;
+
+	devdata->codec = codec;
+	codec->longname = "Corgi Audio Codec";
+	codec->pdev = pdev;
+	codec->machine = devdata->machine;
+	INIT_LIST_HEAD(&codec->dpm_widgets);
+	INIT_LIST_HEAD(&codec->dpm_paths);
+
+	if (codec_data) {
+		normal_i2c[0] = (int)codec_data;
+		codec->hw_write = (hw_write_t)i2c_master_send;
+		if ((ret = i2c_add_driver(&wm8731_i2c_driver)) != 0)
+			printk(KERN_ERR "can't add i2c driver");
+	} else {
+		/* Add other interfaces here */
+	}
+
+	return ret;
 }
 
-static void __exit wm8731_exit(void)
+#endif
+
+/* power down chip */
+static int wm8731_remove(struct platform_device *pdev)
 {
-	driver_unregister(&wm8731_driver);
+	struct snd_soc_platdev_data *devdata = platform_get_drvdata(pdev);
+	struct snd_soc_codec* codec = devdata->codec;
+
+	i2c_del_driver(&wm8731_i2c_driver);
+
+	wm8731_dpm_event(codec, SNDRV_CTL_POWER_D3cold);
+	snd_soc_free_pcms(codec);
+	kfree(codec);
+
+	return 0;
 }
 
-module_init(wm8731_init);
-module_exit(wm8731_exit);
+
+struct snd_soc_codec_device soc_codec_dev_wm8731 = {
+	.probe = 	wm8731_probe,
+	.remove = 	wm8731_remove,
+	.suspend = 	wm8731_suspend,
+	.resume =	wm8731_resume,
+};
+
+EXPORT_SYMBOL_GPL(soc_codec_dev_wm8731);
 
 MODULE_DESCRIPTION("Soc WM8731 driver");
 MODULE_AUTHOR("Richard Purdie");
Index: linux-2.6.15-rc2/sound/soc/codecs/wm8731.h
===================================================================
--- linux-2.6.15-rc2.orig/sound/soc/codecs/wm8731.h	2005-12-01 12:25:15.000000000 +0000
+++ linux-2.6.15-rc2/sound/soc/codecs/wm8731.h	2005-12-03 01:10:04.000000000 +0000
@@ -31,4 +31,6 @@
 
 #define WM8731_CACHEREGNUM 	10
 
+extern struct snd_soc_codec_device soc_codec_dev_wm8731;
+
 #endif
Index: linux-2.6.15-rc2/sound/soc/pxa/pxa2xx-ac97.c
===================================================================
--- linux-2.6.15-rc2.orig/sound/soc/pxa/pxa2xx-ac97.c	2005-12-01 12:25:15.000000000 +0000
+++ linux-2.6.15-rc2/sound/soc/pxa/pxa2xx-ac97.c	2005-12-03 13:53:36.000000000 +0000
@@ -238,16 +238,15 @@
 
 #ifdef CONFIG_PM
 
-static int pxa2xx_ac97_suspend(struct device *dev, pm_message_t state)
+static int pxa2xx_ac97_suspend(struct platform_device *pdev, struct snd_soc_pcm_interface *pcm_i)
 {
 	GCR |= GCR_ACLINK_OFF;
 	pxa_set_cken(CKEN2_AC97, 0);
 	return 0;
 }
 
-static int pxa2xx_ac97_resume(struct device *dev)
+static int pxa2xx_ac97_resume(struct platform_device *pdev, struct snd_soc_pcm_interface *pcm_i)
 {
-	struct snd_soc_pcm_interface *pcm_i = dev->driver_data;
 	struct snd_soc_pcm_codec *pcm_c = pcm_i->pcm_c;
 	struct snd_soc_codec *codec = pcm_c->codec;
 	
@@ -269,7 +268,7 @@
 #define pxa2xx_ac97_resume	NULL
 #endif
 
-static int pxa2xx_ac97_probe(struct device *dev)
+static int pxa2xx_ac97_probe(struct platform_device *pdev)
 {
 	int ret;
 
@@ -297,7 +296,7 @@
 	return ret;
 }
 
-static void pxa2xx_ac97_remove(struct device *dev)
+static void pxa2xx_ac97_remove(struct platform_device *pdev)
 {
 	GCR |= GCR_ACLINK_OFF;
 	free_irq(IRQ_AC97, NULL);
Index: linux-2.6.15-rc2/sound/soc/pxa/pxa2xx-ssp.c
===================================================================
--- linux-2.6.15-rc2.orig/sound/soc/pxa/pxa2xx-ssp.c	2005-12-01 12:25:15.000000000 +0000
+++ linux-2.6.15-rc2/sound/soc/pxa/pxa2xx-ssp.c	2005-12-03 13:55:09.000000000 +0000
@@ -248,10 +248,9 @@
 }
 
 #ifdef CONFIG_PM
-static int pxa2xx_ssp_suspend(struct device *dev, pm_message_t state)
+static int pxa2xx_ssp_suspend(struct platform_device *pdev, struct snd_soc_pcm_interface *pcm_i)
 {
 	int ret = 0;
-	struct snd_soc_pcm_interface *pcm_i = dev->driver_data;
 	
 	if(!pcm_i->active)
 		return 0;
@@ -261,10 +260,9 @@
 	return ret;
 }
 
-static int pxa2xx_ssp_resume(struct device *dev)
+static int pxa2xx_ssp_resume(struct platform_device *pdev, struct snd_soc_pcm_interface *pcm_i)
 {
 	int ret = 0;
-	struct snd_soc_pcm_interface *pcm_i = dev->driver_data;
 	
 	if(!pcm_i->active)
 		return 0;

