summaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/twl6040.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/twl6040.c')
-rw-r--r--sound/soc/codecs/twl6040.c170
1 files changed, 44 insertions, 126 deletions
diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c
index 64a807f1a8a..10f6e521451 100644
--- a/sound/soc/codecs/twl6040.c
+++ b/sound/soc/codecs/twl6040.c
@@ -45,7 +45,6 @@
/* codec private data */
struct twl6040_data {
- struct snd_soc_codec codec;
int audpwron;
int naudint;
int codec_powered;
@@ -770,8 +769,7 @@ static int twl6040_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_device *socdev = rtd->socdev;
- struct snd_soc_codec *codec = socdev->card->codec;
+ struct snd_soc_codec *codec = rtd->codec;
struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
if (!priv->sysclk) {
@@ -803,8 +801,7 @@ static int twl6040_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_device *socdev = rtd->socdev;
- struct snd_soc_codec *codec = socdev->card->codec;
+ struct snd_soc_codec *codec = rtd->codec;
struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
u8 lppllctl;
int rate;
@@ -839,8 +836,7 @@ static int twl6040_trigger(struct snd_pcm_substream *substream,
int cmd, struct snd_soc_dai *dai)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_device *socdev = rtd->socdev;
- struct snd_soc_codec *codec = socdev->card->codec;
+ struct snd_soc_codec *codec = rtd->codec;
struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
switch (cmd) {
@@ -978,8 +974,8 @@ static struct snd_soc_dai_ops twl6040_dai_ops = {
.set_sysclk = twl6040_set_dai_sysclk,
};
-struct snd_soc_dai twl6040_dai = {
- .name = "twl6040",
+static struct snd_soc_dai_driver twl6040_dai = {
+ .name = "twl6040-hifi",
.playback = {
.stream_name = "Playback",
.channels_min = 1,
@@ -996,24 +992,17 @@ struct snd_soc_dai twl6040_dai = {
},
.ops = &twl6040_dai_ops,
};
-EXPORT_SYMBOL_GPL(twl6040_dai);
#ifdef CONFIG_PM
-static int twl6040_suspend(struct platform_device *pdev, pm_message_t state)
+static int twl6040_suspend(struct snd_soc_codec *codec, pm_message_t state)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec = socdev->card->codec;
-
twl6040_set_bias_level(codec, SND_SOC_BIAS_OFF);
return 0;
}
-static int twl6040_resume(struct platform_device *pdev)
+static int twl6040_resume(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec = socdev->card->codec;
-
twl6040_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
return 0;
@@ -1023,68 +1012,9 @@ static int twl6040_resume(struct platform_device *pdev)
#define twl6040_resume NULL
#endif
-static struct snd_soc_codec *twl6040_codec;
-
-static int twl6040_probe(struct platform_device *pdev)
-{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec;
- int ret = 0;
-
- BUG_ON(!twl6040_codec);
-
- codec = twl6040_codec;
- socdev->card->codec = codec;
-
- /* register pcms */
- ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
- if (ret < 0) {
- dev_err(&pdev->dev, "failed to create pcms\n");
- return ret;
- }
-
- snd_soc_add_controls(codec, twl6040_snd_controls,
- ARRAY_SIZE(twl6040_snd_controls));
- twl6040_add_widgets(codec);
-
- if (ret < 0) {
- dev_err(&pdev->dev, "failed to register card\n");
- goto card_err;
- }
-
- return ret;
-
-card_err:
- snd_soc_free_pcms(socdev);
- snd_soc_dapm_free(socdev);
- return ret;
-}
-
-static int twl6040_remove(struct platform_device *pdev)
-{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec = socdev->card->codec;
-
- twl6040_set_bias_level(codec, SND_SOC_BIAS_OFF);
- snd_soc_free_pcms(socdev);
- snd_soc_dapm_free(socdev);
- kfree(codec);
-
- return 0;
-}
-
-struct snd_soc_codec_device soc_codec_dev_twl6040 = {
- .probe = twl6040_probe,
- .remove = twl6040_remove,
- .suspend = twl6040_suspend,
- .resume = twl6040_resume,
-};
-EXPORT_SYMBOL_GPL(soc_codec_dev_twl6040);
-
-static int __devinit twl6040_codec_probe(struct platform_device *pdev)
+static int twl6040_probe(struct snd_soc_codec *codec)
{
- struct twl4030_codec_data *twl_codec = pdev->dev.platform_data;
- struct snd_soc_codec *codec;
+ struct twl4030_codec_data *twl_codec = codec->dev->platform_data;
struct twl6040_data *priv;
int audpwron, naudint;
int ret = 0;
@@ -1092,6 +1022,7 @@ static int __devinit twl6040_codec_probe(struct platform_device *pdev)
priv = kzalloc(sizeof(struct twl6040_data), GFP_KERNEL);
if (priv == NULL)
return -ENOMEM;
+ snd_soc_codec_set_drvdata(codec, priv);
if (twl_codec) {
audpwron = twl_codec->audpwron_gpio;
@@ -1104,29 +1035,6 @@ static int __devinit twl6040_codec_probe(struct platform_device *pdev)
priv->audpwron = audpwron;
priv->naudint = naudint;
- codec = &priv->codec;
- codec->dev = &pdev->dev;
- twl6040_dai.dev = &pdev->dev;
-
- codec->name = "twl6040";
- codec->owner = THIS_MODULE;
- codec->read = twl6040_read_reg_cache;
- codec->write = twl6040_write;
- codec->set_bias_level = twl6040_set_bias_level;
- snd_soc_codec_set_drvdata(codec, priv);
- codec->dai = &twl6040_dai;
- codec->num_dai = 1;
- codec->reg_cache_size = ARRAY_SIZE(twl6040_reg);
- codec->reg_cache = kmemdup(twl6040_reg, sizeof(twl6040_reg),
- GFP_KERNEL);
- if (codec->reg_cache == NULL) {
- ret = -ENOMEM;
- goto cache_err;
- }
-
- mutex_init(&codec->mutex);
- INIT_LIST_HEAD(&codec->dapm_widgets);
- INIT_LIST_HEAD(&codec->dapm_paths);
init_completion(&priv->ready);
if (gpio_is_valid(audpwron)) {
@@ -1169,23 +1077,12 @@ static int __devinit twl6040_codec_probe(struct platform_device *pdev)
if (ret)
goto irq_err;
- ret = snd_soc_register_codec(codec);
- if (ret)
- goto reg_err;
-
- twl6040_codec = codec;
-
- ret = snd_soc_register_dai(&twl6040_dai);
- if (ret)
- goto dai_err;
+ snd_soc_add_controls(codec, twl6040_snd_controls,
+ ARRAY_SIZE(twl6040_snd_controls));
+ twl6040_add_widgets(codec);
return 0;
-dai_err:
- snd_soc_unregister_codec(codec);
- twl6040_codec = NULL;
-reg_err:
- twl6040_set_bias_level(codec, SND_SOC_BIAS_OFF);
irq_err:
if (naudint)
free_irq(naudint, codec);
@@ -1193,36 +1090,57 @@ gpio2_err:
if (gpio_is_valid(audpwron))
gpio_free(audpwron);
gpio1_err:
- kfree(codec->reg_cache);
-cache_err:
kfree(priv);
return ret;
}
-static int __devexit twl6040_codec_remove(struct platform_device *pdev)
+static int twl6040_remove(struct snd_soc_codec *codec)
{
- struct twl6040_data *priv = snd_soc_codec_get_drvdata(twl6040_codec);
+ struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
int audpwron = priv->audpwron;
int naudint = priv->naudint;
+ twl6040_set_bias_level(codec, SND_SOC_BIAS_OFF);
+
if (gpio_is_valid(audpwron))
gpio_free(audpwron);
if (naudint)
- free_irq(naudint, twl6040_codec);
+ free_irq(naudint, codec);
- snd_soc_unregister_dai(&twl6040_dai);
- snd_soc_unregister_codec(twl6040_codec);
+ kfree(priv);
- kfree(twl6040_codec);
- twl6040_codec = NULL;
+ return 0;
+}
+static struct snd_soc_codec_driver soc_codec_dev_twl6040 = {
+ .probe = twl6040_probe,
+ .remove = twl6040_remove,
+ .suspend = twl6040_suspend,
+ .resume = twl6040_resume,
+ .read = twl6040_read_reg_cache,
+ .write = twl6040_write,
+ .set_bias_level = twl6040_set_bias_level,
+ .reg_cache_size = ARRAY_SIZE(twl6040_reg),
+ .reg_word_size = sizeof(u8),
+ .reg_cache_default = twl6040_reg,
+};
+
+static int __devinit twl6040_codec_probe(struct platform_device *pdev)
+{
+ return snd_soc_register_codec(&pdev->dev,
+ &soc_codec_dev_twl6040, &twl6040_dai, 1);
+}
+
+static int __devexit twl6040_codec_remove(struct platform_device *pdev)
+{
+ snd_soc_unregister_codec(&pdev->dev);
return 0;
}
static struct platform_driver twl6040_codec_driver = {
.driver = {
- .name = "twl6040_codec",
+ .name = "twl6040-codec",
.owner = THIS_MODULE,
},
.probe = twl6040_codec_probe,