ASoC: Register the CODEC in WM8727

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Acked-by: Liam Girdwood <lrg@slimlogic.co.uk>
diff --git a/sound/soc/codecs/wm8727.c b/sound/soc/codecs/wm8727.c
index d8ffbd6..63a254e 100644
--- a/sound/soc/codecs/wm8727.c
+++ b/sound/soc/codecs/wm8727.c
@@ -44,23 +44,16 @@
 };
 EXPORT_SYMBOL_GPL(wm8727_dai);
 
+static struct snd_soc_codec *wm8727_codec;
+
 static int wm8727_soc_probe(struct platform_device *pdev)
 {
 	struct snd_soc_device *socdev = platform_get_drvdata(pdev);
-	struct snd_soc_codec *codec;
 	int ret = 0;
 
-	codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
-	if (codec == NULL)
-		return -ENOMEM;
-	mutex_init(&codec->mutex);
-	codec->name = "WM8727";
-	codec->owner = THIS_MODULE;
-	codec->dai = &wm8727_dai;
-	codec->num_dai = 1;
-	socdev->card->codec = codec;
-	INIT_LIST_HEAD(&codec->dapm_widgets);
-	INIT_LIST_HEAD(&codec->dapm_paths);
+	BUG_ON(!wm8727_codec);
+
+	socdev->card->codec = wm8727_codec;
 
 	/* register pcms */
 	ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
@@ -80,12 +73,9 @@
 static int wm8727_soc_remove(struct platform_device *pdev)
 {
 	struct snd_soc_device *socdev = platform_get_drvdata(pdev);
-	struct snd_soc_codec *codec = socdev->card->codec;
 
-	if (codec == NULL)
-		return 0;
 	snd_soc_free_pcms(socdev);
-	kfree(codec);
+
 	return 0;
 }
 
@@ -98,13 +88,55 @@
 
 static __devinit int wm8727_platform_probe(struct platform_device *pdev)
 {
+	struct snd_soc_codec *codec;
+	int ret;
+
+	if (wm8727_codec) {
+		dev_err(&pdev->dev, "Another WM8727 is registered\n");
+		return -EBUSY;
+	}
+
+	codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
+	if (codec == NULL)
+		return -ENOMEM;
+	wm8727_codec = codec;
+
+	platform_set_drvdata(pdev, codec);
+
+	mutex_init(&codec->mutex);
+	codec->dev = &pdev->dev;
+	codec->name = "WM8727";
+	codec->owner = THIS_MODULE;
+	codec->dai = &wm8727_dai;
+	codec->num_dai = 1;
+	INIT_LIST_HEAD(&codec->dapm_widgets);
+	INIT_LIST_HEAD(&codec->dapm_paths);
+
 	wm8727_dai.dev = &pdev->dev;
-	return snd_soc_register_dai(&wm8727_dai);
+
+	ret = snd_soc_register_codec(codec);
+	if (ret != 0) {
+		dev_err(&pdev->dev, "Failed to register CODEC: %d\n", ret);
+		goto err;
+	}
+
+	ret = snd_soc_register_dai(&wm8727_dai);
+	if (ret != 0) {
+		dev_err(&pdev->dev, "Failed to register DAI: %d\n", ret);
+		goto err_codec;
+	}
+
+err_codec:
+	snd_soc_unregister_codec(codec);
+err:
+	kfree(codec);
+	return ret;
 }
 
 static int __devexit wm8727_platform_remove(struct platform_device *pdev)
 {
 	snd_soc_unregister_dai(&wm8727_dai);
+	snd_soc_unregister_codec(platform_get_drvdata(pdev));
 	return 0;
 }