diff options
Diffstat (limited to 'sound/soc/codecs/wm8727.c')
-rw-r--r-- | sound/soc/codecs/wm8727.c | 66 |
1 files changed, 49 insertions, 17 deletions
diff --git a/sound/soc/codecs/wm8727.c b/sound/soc/codecs/wm8727.c index d8ffbd641d71..63a254e293ca 100644 --- a/sound/soc/codecs/wm8727.c +++ b/sound/soc/codecs/wm8727.c @@ -44,23 +44,16 @@ struct snd_soc_dai wm8727_dai = { }; 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 @@ pcm_err: 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 @@ EXPORT_SYMBOL_GPL(soc_codec_dev_wm8727); 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; } |