summaryrefslogtreecommitdiff
path: root/sound/soc/codecs
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs')
-rw-r--r--sound/soc/codecs/ac97.c124
-rw-r--r--sound/soc/codecs/ac97.h19
-rw-r--r--sound/soc/codecs/ad1836.c191
-rw-r--r--sound/soc/codecs/ad1836.h2
-rw-r--r--sound/soc/codecs/ad193x.c217
-rw-r--r--sound/soc/codecs/ad193x.h3
-rw-r--r--sound/soc/codecs/ad1980.c107
-rw-r--r--sound/soc/codecs/ad1980.h3
-rw-r--r--sound/soc/codecs/ad73311.c66
-rw-r--r--sound/soc/codecs/ad73311.h2
-rw-r--r--sound/soc/codecs/ads117x.c72
-rw-r--r--sound/soc/codecs/ads117x.h4
-rw-r--r--sound/soc/codecs/ak4104.c149
-rw-r--r--sound/soc/codecs/ak4104.h7
-rw-r--r--sound/soc/codecs/ak4535.c236
-rw-r--r--sound/soc/codecs/ak4535.h8
-rw-r--r--sound/soc/codecs/ak4642.c175
-rw-r--r--sound/soc/codecs/ak4642.h20
-rw-r--r--sound/soc/codecs/ak4671.c141
-rw-r--r--sound/soc/codecs/ak4671.h3
-rw-r--r--sound/soc/codecs/cq93vc.c132
-rw-r--r--sound/soc/codecs/cq93vc.h29
-rw-r--r--sound/soc/codecs/cs4270.c393
-rw-r--r--sound/soc/codecs/cs4270.h28
-rw-r--r--sound/soc/codecs/cs42l51.c293
-rw-r--r--sound/soc/codecs/cs42l51.h2
-rw-r--r--sound/soc/codecs/cx20442.c173
-rw-r--r--sound/soc/codecs/cx20442.h2
-rw-r--r--sound/soc/codecs/da7210.c157
-rw-r--r--sound/soc/codecs/da7210.h24
-rw-r--r--sound/soc/codecs/jz4740.c116
-rw-r--r--sound/soc/codecs/jz4740.h20
-rw-r--r--sound/soc/codecs/pcm3008.c92
-rw-r--r--sound/soc/codecs/pcm3008.h3
-rw-r--r--sound/soc/codecs/spdif_transciever.c102
-rw-r--r--sound/soc/codecs/spdif_transciever.h18
-rw-r--r--sound/soc/codecs/ssm2602.c219
-rw-r--r--sound/soc/codecs/ssm2602.h3
-rw-r--r--sound/soc/codecs/stac9766.c118
-rw-r--r--sound/soc/codecs/stac9766.h4
-rw-r--r--sound/soc/codecs/tlv320aic23.c182
-rw-r--r--sound/soc/codecs/tlv320aic23.h3
-rw-r--r--sound/soc/codecs/tlv320aic26.c180
-rw-r--r--sound/soc/codecs/tlv320aic26.h3
-rw-r--r--sound/soc/codecs/tlv320aic3x.c223
-rw-r--r--sound/soc/codecs/tlv320aic3x.h43
-rw-r--r--sound/soc/codecs/tlv320dac33.c249
-rw-r--r--sound/soc/codecs/tlv320dac33.h3
-rw-r--r--sound/soc/codecs/twl4030.c231
-rw-r--r--sound/soc/codecs/twl4030.h55
-rw-r--r--sound/soc/codecs/twl6040.c170
-rw-r--r--sound/soc/codecs/twl6040.h3
-rw-r--r--sound/soc/codecs/uda134x.c154
-rw-r--r--sound/soc/codecs/uda134x.h3
-rw-r--r--sound/soc/codecs/uda1380.c211
-rw-r--r--sound/soc/codecs/uda1380.h3
-rw-r--r--sound/soc/codecs/wm2000.h3
-rw-r--r--sound/soc/codecs/wm8350.c231
-rw-r--r--sound/soc/codecs/wm8350.h3
-rw-r--r--sound/soc/codecs/wm8400.c181
-rw-r--r--sound/soc/codecs/wm8400.h3
-rw-r--r--sound/soc/codecs/wm8510.c290
-rw-r--r--sound/soc/codecs/wm8510.h3
-rw-r--r--sound/soc/codecs/wm8523.c180
-rw-r--r--sound/soc/codecs/wm8523.h3
-rw-r--r--sound/soc/codecs/wm8580.c186
-rw-r--r--sound/soc/codecs/wm8580.h3
-rw-r--r--sound/soc/codecs/wm8711.c206
-rw-r--r--sound/soc/codecs/wm8711.h3
-rw-r--r--sound/soc/codecs/wm8727.c106
-rw-r--r--sound/soc/codecs/wm8727.h21
-rw-r--r--sound/soc/codecs/wm8728.c294
-rw-r--r--sound/soc/codecs/wm8728.h9
-rw-r--r--sound/soc/codecs/wm8731.c217
-rw-r--r--sound/soc/codecs/wm8731.h3
-rw-r--r--sound/soc/codecs/wm8741.c204
-rw-r--r--sound/soc/codecs/wm8741.h3
-rw-r--r--sound/soc/codecs/wm8750.c269
-rw-r--r--sound/soc/codecs/wm8750.h9
-rw-r--r--sound/soc/codecs/wm8753.c407
-rw-r--r--sound/soc/codecs/wm8753.h3
-rw-r--r--sound/soc/codecs/wm8776.c251
-rw-r--r--sound/soc/codecs/wm8776.h3
-rw-r--r--sound/soc/codecs/wm8900.c251
-rw-r--r--sound/soc/codecs/wm8900.h3
-rw-r--r--sound/soc/codecs/wm8903.c268
-rw-r--r--sound/soc/codecs/wm8903.h3
-rw-r--r--sound/soc/codecs/wm8904.c208
-rw-r--r--sound/soc/codecs/wm8904.h3
-rw-r--r--sound/soc/codecs/wm8940.c199
-rw-r--r--sound/soc/codecs/wm8940.h2
-rw-r--r--sound/soc/codecs/wm8955.c184
-rw-r--r--sound/soc/codecs/wm8955.h3
-rw-r--r--sound/soc/codecs/wm8960.c209
-rw-r--r--sound/soc/codecs/wm8960.h3
-rw-r--r--sound/soc/codecs/wm8961.c241
-rw-r--r--sound/soc/codecs/wm8961.h3
-rw-r--r--sound/soc/codecs/wm8971.c250
-rw-r--r--sound/soc/codecs/wm8971.h8
-rw-r--r--sound/soc/codecs/wm8974.c171
-rw-r--r--sound/soc/codecs/wm8974.h3
-rw-r--r--sound/soc/codecs/wm8978.c190
-rw-r--r--sound/soc/codecs/wm8978.h3
-rw-r--r--sound/soc/codecs/wm8988.c266
-rw-r--r--sound/soc/codecs/wm8988.h3
-rw-r--r--sound/soc/codecs/wm8990.c226
-rw-r--r--sound/soc/codecs/wm8990.h8
-rw-r--r--sound/soc/codecs/wm8993.c307
-rw-r--r--sound/soc/codecs/wm8993.h3
-rw-r--r--sound/soc/codecs/wm8994.c230
-rw-r--r--sound/soc/codecs/wm8994.h3
-rw-r--r--sound/soc/codecs/wm9081.c208
-rw-r--r--sound/soc/codecs/wm9081.h3
-rw-r--r--sound/soc/codecs/wm9090.c183
-rw-r--r--sound/soc/codecs/wm9090.h2
-rw-r--r--sound/soc/codecs/wm9705.c116
-rw-r--r--sound/soc/codecs/wm9705.h3
-rw-r--r--sound/soc/codecs/wm9712.c124
-rw-r--r--sound/soc/codecs/wm9712.h3
-rw-r--r--sound/soc/codecs/wm9713.c131
-rw-r--r--sound/soc/codecs/wm9713.h3
121 files changed, 3703 insertions, 8611 deletions
diff --git a/sound/soc/codecs/ac97.c b/sound/soc/codecs/ac97.c
index 1f5e57a4bb7a..12c87d37eba1 100644
--- a/sound/soc/codecs/ac97.c
+++ b/sound/soc/codecs/ac97.c
@@ -21,7 +21,6 @@
#include <sound/ac97_codec.h>
#include <sound/initval.h>
#include <sound/soc.h>
-#include "ac97.h"
#define AC97_VERSION "0.6"
@@ -30,8 +29,7 @@ static int ac97_prepare(struct snd_pcm_substream *substream,
{
struct snd_pcm_runtime *runtime = substream->runtime;
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;
int reg = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
AC97_PCM_FRONT_DAC_RATE : AC97_PCM_LR_ADC_RATE;
@@ -46,8 +44,8 @@ static struct snd_soc_dai_ops ac97_dai_ops = {
.prepare = ac97_prepare,
};
-struct snd_soc_dai ac97_dai = {
- .name = "AC97 HiFi",
+static struct snd_soc_dai_driver ac97_dai = {
+ .name = "ac97-hifi",
.ac97_control = 1,
.playback = {
.stream_name = "AC97 Playback",
@@ -63,7 +61,6 @@ struct snd_soc_dai ac97_dai = {
.formats = SND_SOC_STD_AC97_FMTS,},
.ops = &ac97_dai_ops,
};
-EXPORT_SYMBOL_GPL(ac97_dai);
static unsigned int ac97_read(struct snd_soc_codec *codec,
unsigned int reg)
@@ -78,95 +75,49 @@ static int ac97_write(struct snd_soc_codec *codec, unsigned int reg,
return 0;
}
-static int ac97_soc_probe(struct platform_device *pdev)
+static int ac97_soc_probe(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_card *card = socdev->card;
- struct snd_soc_codec *codec;
struct snd_ac97_bus *ac97_bus;
struct snd_ac97_template ac97_template;
- int i;
- int ret = 0;
+ int ret;
printk(KERN_INFO "AC97 SoC Audio Codec %s\n", AC97_VERSION);
- socdev->card->codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
- if (!socdev->card->codec)
- return -ENOMEM;
- codec = socdev->card->codec;
- mutex_init(&codec->mutex);
-
- codec->name = "AC97";
- codec->owner = THIS_MODULE;
- codec->dai = &ac97_dai;
- codec->num_dai = 1;
- codec->write = ac97_write;
- codec->read = ac97_read;
- INIT_LIST_HEAD(&codec->dapm_widgets);
- INIT_LIST_HEAD(&codec->dapm_paths);
-
- /* register pcms */
- ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
- if (ret < 0)
- goto err;
+ ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0);
+ if (ret < 0) {
+ printk(KERN_ERR "ASoC: failed to init gen ac97 glue\n");
+ return ret;
+ }
/* add codec as bus device for standard ac97 */
- ret = snd_ac97_bus(codec->card, 0, &soc_ac97_ops, NULL, &ac97_bus);
+ ret = snd_ac97_bus(codec->card->snd_card, 0, &soc_ac97_ops, NULL, &ac97_bus);
if (ret < 0)
- goto bus_err;
+ return ret;
memset(&ac97_template, 0, sizeof(struct snd_ac97_template));
ret = snd_ac97_mixer(ac97_bus, &ac97_template, &codec->ac97);
if (ret < 0)
- goto bus_err;
-
- for (i = 0; i < card->num_links; i++) {
- if (card->dai_link[i].codec_dai->ac97_control) {
- snd_ac97_dev_add_pdata(codec->ac97,
- card->dai_link[i].cpu_dai->ac97_pdata);
- }
- }
+ return ret;
return 0;
-
-bus_err:
- snd_soc_free_pcms(socdev);
-
-err:
- kfree(socdev->card->codec);
- socdev->card->codec = NULL;
- return ret;
}
-static int ac97_soc_remove(struct platform_device *pdev)
+static int ac97_soc_remove(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec = socdev->card->codec;
-
- if (!codec)
- return 0;
-
- snd_soc_free_pcms(socdev);
- kfree(socdev->card->codec);
-
return 0;
}
#ifdef CONFIG_PM
-static int ac97_soc_suspend(struct platform_device *pdev, pm_message_t msg)
+static int ac97_soc_suspend(struct snd_soc_codec *codec, pm_message_t msg)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
-
- snd_ac97_suspend(socdev->card->codec->ac97);
+ snd_ac97_suspend(codec->ac97);
return 0;
}
-static int ac97_soc_resume(struct platform_device *pdev)
+static int ac97_soc_resume(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
-
- snd_ac97_resume(socdev->card->codec->ac97);
+ snd_ac97_resume(codec->ac97);
return 0;
}
@@ -175,13 +126,48 @@ static int ac97_soc_resume(struct platform_device *pdev)
#define ac97_soc_resume NULL
#endif
-struct snd_soc_codec_device soc_codec_dev_ac97 = {
+static struct snd_soc_codec_driver soc_codec_dev_ac97 = {
+ .write = ac97_write,
+ .read = ac97_read,
.probe = ac97_soc_probe,
.remove = ac97_soc_remove,
.suspend = ac97_soc_suspend,
.resume = ac97_soc_resume,
};
-EXPORT_SYMBOL_GPL(soc_codec_dev_ac97);
+
+static __devinit int ac97_probe(struct platform_device *pdev)
+{
+ return snd_soc_register_codec(&pdev->dev,
+ &soc_codec_dev_ac97, &ac97_dai, 1);
+}
+
+static int __devexit ac97_remove(struct platform_device *pdev)
+{
+ snd_soc_unregister_codec(&pdev->dev);
+ return 0;
+}
+
+static struct platform_driver ac97_codec_driver = {
+ .driver = {
+ .name = "ac97-codec",
+ .owner = THIS_MODULE,
+ },
+
+ .probe = ac97_probe,
+ .remove = __devexit_p(ac97_remove),
+};
+
+static int __init ac97_init(void)
+{
+ return platform_driver_register(&ac97_codec_driver);
+}
+module_init(ac97_init);
+
+static void __exit ac97_exit(void)
+{
+ platform_driver_unregister(&ac97_codec_driver);
+}
+module_exit(ac97_exit);
MODULE_DESCRIPTION("Soc Generic AC97 driver");
MODULE_AUTHOR("Liam Girdwood");
diff --git a/sound/soc/codecs/ac97.h b/sound/soc/codecs/ac97.h
deleted file mode 100644
index 281aa42e2bbb..000000000000
--- a/sound/soc/codecs/ac97.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * linux/sound/codecs/ac97.h -- ALSA SoC Layer
- *
- * Author: Liam Girdwood
- * Created: Dec 1st 2005
- * Copyright: Wolfson Microelectronics. PLC.
- *
- * 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 __LINUX_SND_SOC_AC97_H
-#define __LINUX_SND_SOC_AC97_H
-
-extern struct snd_soc_codec_device soc_codec_dev_ac97;
-extern struct snd_soc_dai ac97_dai;
-
-#endif
diff --git a/sound/soc/codecs/ad1836.c b/sound/soc/codecs/ad1836.c
index a01006c8c606..d272534c8f84 100644
--- a/sound/soc/codecs/ad1836.c
+++ b/sound/soc/codecs/ad1836.c
@@ -33,15 +33,10 @@
/* codec private data */
struct ad1836_priv {
- struct snd_soc_codec codec;
- u16 reg_cache[AD1836_NUM_REGS];
+ enum snd_soc_control_type control_type;
+ void *control_data;
};
-static struct snd_soc_codec *ad1836_codec;
-struct snd_soc_codec_device soc_codec_dev_ad1836;
-static int ad1836_register(struct ad1836_priv *ad1836);
-static void ad1836_unregister(struct ad1836_priv *ad1836);
-
/*
* AD1836 volume/mute/de-emphasis etc. controls
*/
@@ -146,8 +141,7 @@ static int ad1836_hw_params(struct snd_pcm_substream *substream,
int word_len = 0;
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;
/* bit size */
switch (params_format(params)) {
@@ -173,12 +167,9 @@ static int ad1836_hw_params(struct snd_pcm_substream *substream,
}
#ifdef CONFIG_PM
-static int ad1836_soc_suspend(struct platform_device *pdev,
+static int ad1836_soc_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;
-
/* reset clock control mode */
u16 adc_ctrl2 = snd_soc_read(codec, AD1836_ADC_CTRL2);
adc_ctrl2 &= ~AD1836_ADC_SERFMT_MASK;
@@ -186,11 +177,8 @@ static int ad1836_soc_suspend(struct platform_device *pdev,
return snd_soc_write(codec, AD1836_ADC_CTRL2, adc_ctrl2);
}
-static int ad1836_soc_resume(struct platform_device *pdev)
+static int ad1836_soc_resume(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec = socdev->card->codec;
-
/* restore clock control mode */
u16 adc_ctrl2 = snd_soc_read(codec, AD1836_ADC_CTRL2);
adc_ctrl2 |= AD1836_ADC_AUX;
@@ -202,49 +190,14 @@ static int ad1836_soc_resume(struct platform_device *pdev)
#define ad1836_soc_resume NULL
#endif
-static int __devinit ad1836_spi_probe(struct spi_device *spi)
-{
- struct snd_soc_codec *codec;
- struct ad1836_priv *ad1836;
-
- ad1836 = kzalloc(sizeof(struct ad1836_priv), GFP_KERNEL);
- if (ad1836 == NULL)
- return -ENOMEM;
-
- codec = &ad1836->codec;
- codec->control_data = spi;
- codec->dev = &spi->dev;
-
- dev_set_drvdata(&spi->dev, ad1836);
-
- return ad1836_register(ad1836);
-}
-
-static int __devexit ad1836_spi_remove(struct spi_device *spi)
-{
- struct ad1836_priv *ad1836 = dev_get_drvdata(&spi->dev);
-
- ad1836_unregister(ad1836);
- return 0;
-}
-
-static struct spi_driver ad1836_spi_driver = {
- .driver = {
- .name = "ad1836",
- .owner = THIS_MODULE,
- },
- .probe = ad1836_spi_probe,
- .remove = __devexit_p(ad1836_spi_remove),
-};
-
static struct snd_soc_dai_ops ad1836_dai_ops = {
.hw_params = ad1836_hw_params,
.set_fmt = ad1836_set_dai_fmt,
};
/* codec DAI instance */
-struct snd_soc_dai ad1836_dai = {
- .name = "AD1836",
+static struct snd_soc_dai_driver ad1836_dai = {
+ .name = "ad1836-hifi",
.playback = {
.stream_name = "Playback",
.channels_min = 2,
@@ -263,35 +216,13 @@ struct snd_soc_dai ad1836_dai = {
},
.ops = &ad1836_dai_ops,
};
-EXPORT_SYMBOL_GPL(ad1836_dai);
-static int ad1836_register(struct ad1836_priv *ad1836)
+static int ad1836_probe(struct snd_soc_codec *codec)
{
- int ret;
- struct snd_soc_codec *codec = &ad1836->codec;
-
- if (ad1836_codec) {
- dev_err(codec->dev, "Another ad1836 is registered\n");
- kfree(ad1836);
- return -EINVAL;
- }
-
- mutex_init(&codec->mutex);
- INIT_LIST_HEAD(&codec->dapm_widgets);
- INIT_LIST_HEAD(&codec->dapm_paths);
- snd_soc_codec_set_drvdata(codec, ad1836);
- codec->reg_cache = ad1836->reg_cache;
- codec->reg_cache_size = AD1836_NUM_REGS;
- codec->name = "AD1836";
- codec->owner = THIS_MODULE;
- codec->dai = &ad1836_dai;
- codec->num_dai = 1;
- INIT_LIST_HEAD(&codec->dapm_widgets);
- INIT_LIST_HEAD(&codec->dapm_paths);
-
- ad1836_dai.dev = codec->dev;
- ad1836_codec = codec;
+ struct ad1836_priv *ad1836 = snd_soc_codec_get_drvdata(codec);
+ int ret = 0;
+ codec->control_data = ad1836->control_data;
ret = snd_soc_codec_set_cache_io(codec, 4, 12, SND_SOC_SPI);
if (ret < 0) {
dev_err(codec->dev, "failed to set cache I/O: %d\n",
@@ -319,81 +250,69 @@ static int ad1836_register(struct ad1836_priv *ad1836)
snd_soc_write(codec, AD1836_DAC_L3_VOL, 0x3FF);
snd_soc_write(codec, AD1836_DAC_R3_VOL, 0x3FF);
- ret = snd_soc_register_codec(codec);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to register codec: %d\n", ret);
- kfree(ad1836);
- return ret;
- }
-
- ret = snd_soc_register_dai(&ad1836_dai);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
- snd_soc_unregister_codec(codec);
- kfree(ad1836);
- return ret;
- }
-
- return 0;
-}
-
-static void ad1836_unregister(struct ad1836_priv *ad1836)
-{
- snd_soc_unregister_dai(&ad1836_dai);
- snd_soc_unregister_codec(&ad1836->codec);
- kfree(ad1836);
- ad1836_codec = NULL;
-}
-
-static int ad1836_probe(struct platform_device *pdev)
-{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec;
- int ret = 0;
-
- if (ad1836_codec == NULL) {
- dev_err(&pdev->dev, "Codec device not registered\n");
- return -ENODEV;
- }
-
- socdev->card->codec = ad1836_codec;
- codec = ad1836_codec;
-
- /* register pcms */
- ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
- if (ret < 0) {
- dev_err(codec->dev, "failed to create pcms: %d\n", ret);
- goto pcm_err;
- }
-
snd_soc_add_controls(codec, ad1836_snd_controls,
ARRAY_SIZE(ad1836_snd_controls));
snd_soc_dapm_new_controls(codec, ad1836_dapm_widgets,
ARRAY_SIZE(ad1836_dapm_widgets));
snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths));
-pcm_err:
return ret;
}
/* power down chip */
-static int ad1836_remove(struct platform_device *pdev)
+static int ad1836_remove(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
-
- snd_soc_free_pcms(socdev);
- snd_soc_dapm_free(socdev);
+ /* reset clock control mode */
+ u16 adc_ctrl2 = snd_soc_read(codec, AD1836_ADC_CTRL2);
+ adc_ctrl2 &= ~AD1836_ADC_SERFMT_MASK;
- return 0;
+ return snd_soc_write(codec, AD1836_ADC_CTRL2, adc_ctrl2);
}
-struct snd_soc_codec_device soc_codec_dev_ad1836 = {
+static struct snd_soc_codec_driver soc_codec_dev_ad1836 = {
.probe = ad1836_probe,
.remove = ad1836_remove,
.suspend = ad1836_soc_suspend,
.resume = ad1836_soc_resume,
+ .reg_cache_size = AD1836_NUM_REGS,
+ .reg_word_size = sizeof(u16),
+};
+
+static int __devinit ad1836_spi_probe(struct spi_device *spi)
+{
+ struct ad1836_priv *ad1836;
+ int ret;
+
+ ad1836 = kzalloc(sizeof(struct ad1836_priv), GFP_KERNEL);
+ if (ad1836 == NULL)
+ return -ENOMEM;
+
+ spi_set_drvdata(spi, ad1836);
+ ad1836->control_data = spi;
+ ad1836->control_type = SND_SOC_SPI;
+
+ ret = snd_soc_register_codec(&spi->dev,
+ &soc_codec_dev_ad1836, &ad1836_dai, 1);
+ if (ret < 0)
+ kfree(ad1836);
+ return ret;
+}
+
+static int __devexit ad1836_spi_remove(struct spi_device *spi)
+{
+ snd_soc_unregister_codec(&spi->dev);
+ kfree(spi_get_drvdata(spi));
+ return 0;
+}
+
+static struct spi_driver ad1836_spi_driver = {
+ .driver = {
+ .name = "ad1836-codec",
+ .owner = THIS_MODULE,
+ },
+ .probe = ad1836_spi_probe,
+ .remove = __devexit_p(ad1836_spi_remove),
};
-EXPORT_SYMBOL_GPL(soc_codec_dev_ad1836);
static int __init ad1836_init(void)
{
diff --git a/sound/soc/codecs/ad1836.h b/sound/soc/codecs/ad1836.h
index e9d90d3951c5..845596717fdf 100644
--- a/sound/soc/codecs/ad1836.h
+++ b/sound/soc/codecs/ad1836.h
@@ -60,6 +60,4 @@
#define AD1836_NUM_REGS 16
-extern struct snd_soc_dai ad1836_dai;
-extern struct snd_soc_codec_device soc_codec_dev_ad1836;
#endif
diff --git a/sound/soc/codecs/ad193x.c b/sound/soc/codecs/ad193x.c
index 1def75e4862f..fa2834c91b9f 100644
--- a/sound/soc/codecs/ad193x.c
+++ b/sound/soc/codecs/ad193x.c
@@ -24,9 +24,10 @@
/* codec private data */
struct ad193x_priv {
- unsigned int sysclk;
- struct snd_soc_codec codec;
u8 reg_cache[AD193X_NUM_REGS];
+ enum snd_soc_control_type bus_type;
+ void *control_data;
+ int sysclk;
};
/* ad193x register cache & default register settings */
@@ -34,9 +35,6 @@ static const u8 ad193x_reg[AD193X_NUM_REGS] = {
0, 0, 0, 0, 0, 0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0, 0,
};
-static struct snd_soc_codec *ad193x_codec;
-struct snd_soc_codec_device soc_codec_dev_ad193x;
-
/*
* AD193X volume/mute/de-emphasis etc. controls
*/
@@ -275,8 +273,7 @@ static int ad193x_hw_params(struct snd_pcm_substream *substream,
int word_len = 0, reg = 0, master_rate = 0;
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 ad193x_priv *ad193x = snd_soc_codec_get_drvdata(codec);
/* bit size */
@@ -323,100 +320,6 @@ static int ad193x_hw_params(struct snd_pcm_substream *substream,
return 0;
}
-static int ad193x_bus_probe(struct device *dev, void *ctrl_data, int bus_type)
-{
- struct snd_soc_codec *codec;
- struct ad193x_priv *ad193x;
- int ret;
-
- if (ad193x_codec) {
- dev_err(dev, "Another ad193x is registered\n");
- return -EINVAL;
- }
-
- ad193x = kzalloc(sizeof(struct ad193x_priv), GFP_KERNEL);
- if (ad193x == NULL)
- return -ENOMEM;
-
- dev_set_drvdata(dev, ad193x);
-
- codec = &ad193x->codec;
- mutex_init(&codec->mutex);
- codec->control_data = ctrl_data;
- codec->dev = dev;
- snd_soc_codec_set_drvdata(codec, ad193x);
- codec->reg_cache = ad193x->reg_cache;
- codec->reg_cache_size = AD193X_NUM_REGS;
- codec->name = "AD193X";
- codec->owner = THIS_MODULE;
- codec->dai = &ad193x_dai;
- codec->num_dai = 1;
- INIT_LIST_HEAD(&codec->dapm_widgets);
- INIT_LIST_HEAD(&codec->dapm_paths);
-
- ad193x_dai.dev = codec->dev;
- ad193x_codec = codec;
-
- memcpy(codec->reg_cache, ad193x_reg, AD193X_NUM_REGS);
-
- if (bus_type == SND_SOC_I2C)
- ret = snd_soc_codec_set_cache_io(codec, 8, 8, bus_type);
- else
- ret = snd_soc_codec_set_cache_io(codec, 16, 8, bus_type);
- if (ret < 0) {
- dev_err(codec->dev, "failed to set cache I/O: %d\n",
- ret);
- kfree(ad193x);
- return ret;
- }
-
- /* default setting for ad193x */
-
- /* unmute dac channels */
- snd_soc_write(codec, AD193X_DAC_CHNL_MUTE, 0x0);
- /* de-emphasis: 48kHz, powedown dac */
- snd_soc_write(codec, AD193X_DAC_CTRL2, 0x1A);
- /* powerdown dac, dac in tdm mode */
- snd_soc_write(codec, AD193X_DAC_CTRL0, 0x41);
- /* high-pass filter enable */
- snd_soc_write(codec, AD193X_ADC_CTRL0, 0x3);
- /* sata delay=1, adc aux mode */
- snd_soc_write(codec, AD193X_ADC_CTRL1, 0x43);
- /* pll input: mclki/xi */
- snd_soc_write(codec, AD193X_PLL_CLK_CTRL0, 0x99); /* mclk=24.576Mhz: 0x9D; mclk=12.288Mhz: 0x99 */
- snd_soc_write(codec, AD193X_PLL_CLK_CTRL1, 0x04);
- ad193x->sysclk = 12288000;
-
- ret = snd_soc_register_codec(codec);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to register codec: %d\n", ret);
- kfree(ad193x);
- return ret;
- }
-
- ret = snd_soc_register_dai(&ad193x_dai);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
- snd_soc_unregister_codec(codec);
- kfree(ad193x);
- return ret;
- }
-
- return 0;
-}
-
-static int ad193x_bus_remove(struct device *dev)
-{
- struct ad193x_priv *ad193x = dev_get_drvdata(dev);
-
- snd_soc_unregister_dai(&ad193x_dai);
- snd_soc_unregister_codec(&ad193x->codec);
- kfree(ad193x);
- ad193x_codec = NULL;
-
- return 0;
-}
-
static struct snd_soc_dai_ops ad193x_dai_ops = {
.hw_params = ad193x_hw_params,
.digital_mute = ad193x_mute,
@@ -426,8 +329,8 @@ static struct snd_soc_dai_ops ad193x_dai_ops = {
};
/* codec DAI instance */
-struct snd_soc_dai ad193x_dai = {
- .name = "AD193X",
+static struct snd_soc_dai_driver ad193x_dai = {
+ .name = "ad193x-hifi",
.playback = {
.stream_name = "Playback",
.channels_min = 2,
@@ -446,28 +349,39 @@ struct snd_soc_dai ad193x_dai = {
},
.ops = &ad193x_dai_ops,
};
-EXPORT_SYMBOL_GPL(ad193x_dai);
-static int ad193x_probe(struct platform_device *pdev)
+static int ad193x_probe(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec;
- int ret = 0;
+ struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(codec);
+ int ret;
- if (ad193x_codec == NULL) {
- dev_err(&pdev->dev, "Codec device not registered\n");
- return -ENODEV;
+ codec->control_data = ad193x->control_data;
+ if (ad193x->bus_type == SND_SOC_I2C)
+ ret = snd_soc_codec_set_cache_io(codec, 8, 8, ad193x->bus_type);
+ else
+ ret = snd_soc_codec_set_cache_io(codec, 16, 8, ad193x->bus_type);
+ if (ret < 0) {
+ dev_err(codec->dev, "failed to set cache I/O: %d\n",
+ ret);
+ kfree(ad193x);
+ return ret;
}
- socdev->card->codec = ad193x_codec;
- codec = ad193x_codec;
+ /* default setting for ad193x */
- /* register pcms */
- ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
- if (ret < 0) {
- dev_err(codec->dev, "failed to create pcms: %d\n", ret);
- goto pcm_err;
- }
+ /* unmute dac channels */
+ snd_soc_write(codec, AD193X_DAC_CHNL_MUTE, 0x0);
+ /* de-emphasis: 48kHz, powedown dac */
+ snd_soc_write(codec, AD193X_DAC_CTRL2, 0x1A);
+ /* powerdown dac, dac in tdm mode */
+ snd_soc_write(codec, AD193X_DAC_CTRL0, 0x41);
+ /* high-pass filter enable */
+ snd_soc_write(codec, AD193X_ADC_CTRL0, 0x3);
+ /* sata delay=1, adc aux mode */
+ snd_soc_write(codec, AD193X_ADC_CTRL1, 0x43);
+ /* pll input: mclki/xi */
+ snd_soc_write(codec, AD193X_PLL_CLK_CTRL0, 0x99); /* mclk=24.576Mhz: 0x9D; mclk=12.288Mhz: 0x99 */
+ snd_soc_write(codec, AD193X_PLL_CLK_CTRL1, 0x04);
snd_soc_add_controls(codec, ad193x_snd_controls,
ARRAY_SIZE(ad193x_snd_controls));
@@ -475,41 +389,47 @@ static int ad193x_probe(struct platform_device *pdev)
ARRAY_SIZE(ad193x_dapm_widgets));
snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths));
-pcm_err:
return ret;
}
-/* power down chip */
-static int ad193x_remove(struct platform_device *pdev)
-{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
-
- snd_soc_free_pcms(socdev);
- snd_soc_dapm_free(socdev);
-
- return 0;
-}
-
-struct snd_soc_codec_device soc_codec_dev_ad193x = {
+static struct snd_soc_codec_driver soc_codec_dev_ad193x = {
.probe = ad193x_probe,
- .remove = ad193x_remove,
+ .reg_cache_default = ad193x_reg,
+ .reg_cache_size = AD193X_NUM_REGS,
+ .reg_word_size = sizeof(u16),
};
-EXPORT_SYMBOL_GPL(soc_codec_dev_ad193x);
#if defined(CONFIG_SPI_MASTER)
static int __devinit ad193x_spi_probe(struct spi_device *spi)
{
- return ad193x_bus_probe(&spi->dev, spi, SND_SOC_SPI);
+ struct ad193x_priv *ad193x;
+ int ret;
+
+ ad193x = kzalloc(sizeof(struct ad193x_priv), GFP_KERNEL);
+ if (ad193x == NULL)
+ return -ENOMEM;
+
+ spi_set_drvdata(spi, ad193x);
+ ad193x->control_data = spi;
+ ad193x->bus_type = SND_SOC_SPI;
+
+ ret = snd_soc_register_codec(&spi->dev,
+ &soc_codec_dev_ad193x, &ad193x_dai, 1);
+ if (ret < 0)
+ kfree(ad193x);
+ return ret;
}
static int __devexit ad193x_spi_remove(struct spi_device *spi)
{
- return ad193x_bus_remove(&spi->dev);
+ snd_soc_unregister_codec(&spi->dev);
+ kfree(spi_get_drvdata(spi));
+ return 0;
}
static struct spi_driver ad193x_spi_driver = {
.driver = {
- .name = "ad193x",
+ .name = "ad193x-codec",
.owner = THIS_MODULE,
},
.probe = ad193x_spi_probe,
@@ -528,17 +448,34 @@ MODULE_DEVICE_TABLE(i2c, ad193x_id);
static int __devinit ad193x_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
- return ad193x_bus_probe(&client->dev, client, SND_SOC_I2C);
+ struct ad193x_priv *ad193x;
+ int ret;
+
+ ad193x = kzalloc(sizeof(struct ad193x_priv), GFP_KERNEL);
+ if (ad193x == NULL)
+ return -ENOMEM;
+
+ i2c_set_clientdata(client, ad193x);
+ ad193x->control_data = client;
+ ad193x->bus_type = SND_SOC_I2C;
+
+ ret = snd_soc_register_codec(&client->dev,
+ &soc_codec_dev_ad193x, &ad193x_dai, 1);
+ if (ret < 0)
+ kfree(ad193x);
+ return ret;
}
static int __devexit ad193x_i2c_remove(struct i2c_client *client)
{
- return ad193x_bus_remove(&client->dev);
+ snd_soc_unregister_codec(&client->dev);
+ kfree(i2c_get_clientdata(client));
+ return 0;
}
static struct i2c_driver ad193x_i2c_driver = {
.driver = {
- .name = "ad193x",
+ .name = "ad193x-codec",
},
.probe = ad193x_i2c_probe,
.remove = __devexit_p(ad193x_i2c_remove),
diff --git a/sound/soc/codecs/ad193x.h b/sound/soc/codecs/ad193x.h
index 654ba64ae04c..9747b5497877 100644
--- a/sound/soc/codecs/ad193x.h
+++ b/sound/soc/codecs/ad193x.h
@@ -80,7 +80,4 @@
#define AD193X_NUM_REGS 17
-extern struct snd_soc_dai ad193x_dai;
-extern struct snd_soc_codec_device soc_codec_dev_ad193x;
-
#endif
diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c
index 042072738cdc..1371afac657b 100644
--- a/sound/soc/codecs/ad1980.c
+++ b/sound/soc/codecs/ad1980.c
@@ -130,8 +130,8 @@ static int ac97_write(struct snd_soc_codec *codec, unsigned int reg,
return 0;
}
-struct snd_soc_dai ad1980_dai = {
- .name = "AC97",
+struct snd_soc_dai_driver ad1980_dai = {
+ .name = "ad1980-hifi",
.ac97_control = 1,
.playback = {
.stream_name = "Playback",
@@ -177,53 +177,20 @@ err:
return -EIO;
}
-static int ad1980_soc_probe(struct platform_device *pdev)
+static int ad1980_soc_probe(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec;
- int ret = 0;
+ int ret;
u16 vendor_id2;
u16 ext_status;
printk(KERN_INFO "AD1980 SoC Audio Codec\n");
- socdev->card->codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
- if (socdev->card->codec == NULL)
- return -ENOMEM;
- codec = socdev->card->codec;
- mutex_init(&codec->mutex);
-
- codec->reg_cache =
- kzalloc(sizeof(u16) * ARRAY_SIZE(ad1980_reg), GFP_KERNEL);
- if (codec->reg_cache == NULL) {
- ret = -ENOMEM;
- goto cache_err;
- }
- memcpy(codec->reg_cache, ad1980_reg, sizeof(u16) * \
- ARRAY_SIZE(ad1980_reg));
- codec->reg_cache_size = sizeof(u16) * ARRAY_SIZE(ad1980_reg);
- codec->reg_cache_step = 2;
- codec->name = "AD1980";
- codec->owner = THIS_MODULE;
- codec->dai = &ad1980_dai;
- codec->num_dai = 1;
- codec->write = ac97_write;
- codec->read = ac97_read;
- INIT_LIST_HEAD(&codec->dapm_widgets);
- INIT_LIST_HEAD(&codec->dapm_paths);
-
ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0);
if (ret < 0) {
printk(KERN_ERR "ad1980: failed to register AC97 codec\n");
- goto codec_err;
+ return ret;
}
- /* register pcms */
- ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
- if (ret < 0)
- goto pcm_err;
-
-
ret = ad1980_reset(codec, 0);
if (ret < 0) {
printk(KERN_ERR "Failed to reset AD1980: AC97 link error\n");
@@ -262,41 +229,59 @@ static int ad1980_soc_probe(struct platform_device *pdev)
return 0;
reset_err:
- snd_soc_free_pcms(socdev);
-
-pcm_err:
snd_soc_free_ac97_codec(codec);
-
-codec_err:
- kfree(codec->reg_cache);
-
-cache_err:
- kfree(socdev->card->codec);
- socdev->card->codec = NULL;
return ret;
}
-static int ad1980_soc_remove(struct platform_device *pdev)
+static int ad1980_soc_remove(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec = socdev->card->codec;
-
- if (codec == NULL)
- return 0;
-
- snd_soc_dapm_free(socdev);
- snd_soc_free_pcms(socdev);
snd_soc_free_ac97_codec(codec);
- kfree(codec->reg_cache);
- kfree(codec);
return 0;
}
-struct snd_soc_codec_device soc_codec_dev_ad1980 = {
+static struct snd_soc_codec_driver soc_codec_dev_ad1980 = {
.probe = ad1980_soc_probe,
.remove = ad1980_soc_remove,
+ .reg_cache_size = ARRAY_SIZE(ad1980_reg),
+ .reg_word_size = sizeof(u16),
+ .reg_cache_step = 2,
+ .write = ac97_write,
+ .read = ac97_read,
};
-EXPORT_SYMBOL_GPL(soc_codec_dev_ad1980);
+
+static __devinit int ad1980_probe(struct platform_device *pdev)
+{
+ return snd_soc_register_codec(&pdev->dev,
+ &soc_codec_dev_ad1980, &ad1980_dai, 1);
+}
+
+static int __devexit ad1980_remove(struct platform_device *pdev)
+{
+ snd_soc_unregister_codec(&pdev->dev);
+ return 0;
+}
+
+static struct platform_driver ad1980_codec_driver = {
+ .driver = {
+ .name = "ad1980-codec",
+ .owner = THIS_MODULE,
+ },
+
+ .probe = ad1980_probe,
+ .remove = __devexit_p(ad1980_remove),
+};
+
+static int __init ad1980_init(void)
+{
+ return platform_driver_register(&ad1980_codec_driver);
+}
+module_init(ad1980_init);
+
+static void __exit ad1980_exit(void)
+{
+ platform_driver_unregister(&ad1980_codec_driver);
+}
+module_exit(ad1980_exit);
MODULE_DESCRIPTION("ASoC ad1980 driver");
MODULE_AUTHOR("Roy Huang, Cliff Cai");
diff --git a/sound/soc/codecs/ad1980.h b/sound/soc/codecs/ad1980.h
index db6c8500d66b..29b5a8750926 100644
--- a/sound/soc/codecs/ad1980.h
+++ b/sound/soc/codecs/ad1980.h
@@ -17,7 +17,4 @@
#define PR5 0x2000
#define PR6 0x4000
-extern struct snd_soc_dai ad1980_dai;
-extern struct snd_soc_codec_device soc_codec_dev_ad1980;
-
#endif
diff --git a/sound/soc/codecs/ad73311.c b/sound/soc/codecs/ad73311.c
index 475807bea2c2..c53955fe17b6 100644
--- a/sound/soc/codecs/ad73311.c
+++ b/sound/soc/codecs/ad73311.c
@@ -23,8 +23,8 @@
#include "ad73311.h"
-struct snd_soc_dai ad73311_dai = {
- .name = "AD73311",
+static struct snd_soc_dai_driver ad73311_dai = {
+ .name = "ad73311-hifi",
.playback = {
.stream_name = "Playback",
.channels_min = 1,
@@ -38,68 +38,40 @@ struct snd_soc_dai ad73311_dai = {
.rates = SNDRV_PCM_RATE_8000,
.formats = SNDRV_PCM_FMTBIT_S16_LE, },
};
-EXPORT_SYMBOL_GPL(ad73311_dai);
-static int ad73311_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 = "AD73311";
- codec->owner = THIS_MODULE;
- codec->dai = &ad73311_dai;
- codec->num_dai = 1;
- socdev->card->codec = codec;
- INIT_LIST_HEAD(&codec->dapm_widgets);
- INIT_LIST_HEAD(&codec->dapm_paths);
-
- /* register pcms */
- ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
- if (ret < 0) {
- printk(KERN_ERR "ad73311: failed to create pcms\n");
- goto pcm_err;
- }
-
- return ret;
+static struct snd_soc_codec_driver soc_codec_dev_ad73311;
-pcm_err:
- kfree(socdev->card->codec);
- socdev->card->codec = NULL;
- return ret;
+static int ad73311_probe(struct platform_device *pdev)
+{
+ return snd_soc_register_codec(&pdev->dev,
+ &soc_codec_dev_ad73311, &ad73311_dai, 1);
}
-static int ad73311_soc_remove(struct platform_device *pdev)
+static int ad73311_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);
+ snd_soc_unregister_codec(&pdev->dev);
return 0;
}
-struct snd_soc_codec_device soc_codec_dev_ad73311 = {
- .probe = ad73311_soc_probe,
- .remove = ad73311_soc_remove,
+static struct platform_driver ad73311_codec_driver = {
+ .driver = {
+ .name = "ad73311-codec",
+ .owner = THIS_MODULE,
+ },
+
+ .probe = ad73311_probe,
+ .remove = __devexit_p(ad73311_remove),
};
-EXPORT_SYMBOL_GPL(soc_codec_dev_ad73311);
static int __init ad73311_init(void)
{
- return snd_soc_register_dai(&ad73311_dai);
+ return platform_driver_register(&ad73311_codec_driver);
}
module_init(ad73311_init);
static void __exit ad73311_exit(void)
{
- snd_soc_unregister_dai(&ad73311_dai);
+ platform_driver_unregister(&ad73311_codec_driver);
}
module_exit(ad73311_exit);
diff --git a/sound/soc/codecs/ad73311.h b/sound/soc/codecs/ad73311.h
index 569573d2d4d7..4b353eefc0bf 100644
--- a/sound/soc/codecs/ad73311.h
+++ b/sound/soc/codecs/ad73311.h
@@ -85,6 +85,4 @@
#define REGF_INV (1 << 6)
#define REGF_ALB (1 << 7)
-extern struct snd_soc_dai ad73311_dai;
-extern struct snd_soc_codec_device soc_codec_dev_ad73311;
#endif
diff --git a/sound/soc/codecs/ads117x.c b/sound/soc/codecs/ads117x.c
index f8e75edb27b7..8402854ec15e 100644
--- a/sound/soc/codecs/ads117x.c
+++ b/sound/soc/codecs/ads117x.c
@@ -19,16 +19,12 @@
#include <sound/initval.h>
#include <sound/soc.h>
-#include "ads117x.h"
-
#define ADS117X_RATES (SNDRV_PCM_RATE_8000_48000)
-
#define ADS117X_FORMATS (SNDRV_PCM_FMTBIT_S16_LE)
-struct snd_soc_dai ads117x_dai = {
+static struct snd_soc_dai_driver ads117x_dai = {
/* ADC */
- .name = "ADS117X ADC",
- .id = 1,
+ .name = "ads117x-hifi",
.capture = {
.stream_name = "Capture",
.channels_min = 1,
@@ -36,75 +32,29 @@ struct snd_soc_dai ads117x_dai = {
.rates = ADS117X_RATES,
.formats = ADS117X_FORMATS,},
};
-EXPORT_SYMBOL_GPL(ads117x_dai);
-
-static int ads117x_probe(struct platform_device *pdev)
-{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec;
- int ret;
-
- codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
- if (codec == NULL)
- return -ENOMEM;
- socdev->card->codec = codec;
- mutex_init(&codec->mutex);
- INIT_LIST_HEAD(&codec->dapm_widgets);
- INIT_LIST_HEAD(&codec->dapm_paths);
- codec->name = "ADS117X";
- codec->owner = THIS_MODULE;
- codec->dai = &ads117x_dai;
- codec->num_dai = 1;
-
- /* register pcms */
- ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
- if (ret < 0) {
- printk(KERN_ERR "ads117x: failed to create pcms\n");
- kfree(codec);
- return ret;
- }
-
- return 0;
-}
-
-static int ads117x_remove(struct platform_device *pdev)
-{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec = socdev->card->codec;
-
- snd_soc_free_pcms(socdev);
- kfree(codec);
-
- return 0;
-}
-
-struct snd_soc_codec_device soc_codec_dev_ads117x = {
- .probe = ads117x_probe,
- .remove = ads117x_remove,
-};
-EXPORT_SYMBOL_GPL(soc_codec_dev_ads117x);
+static struct snd_soc_codec_driver soc_codec_dev_ads117x;
-static __devinit int ads117x_platform_probe(struct platform_device *pdev)
+static __devinit int ads117x_probe(struct platform_device *pdev)
{
- ads117x_dai.dev = &pdev->dev;
- return snd_soc_register_dai(&ads117x_dai);
+ return snd_soc_register_codec(&pdev->dev,
+ &soc_codec_dev_ads117x, &ads117x_dai, 1);
}
-static int __devexit ads117x_platform_remove(struct platform_device *pdev)
+static int __devexit ads117x_remove(struct platform_device *pdev)
{
- snd_soc_unregister_dai(&ads117x_dai);
+ snd_soc_unregister_codec(&pdev->dev);
return 0;
}
static struct platform_driver ads117x_codec_driver = {
.driver = {
- .name = "ads117x",
+ .name = "ads117x-codec",
.owner = THIS_MODULE,
},
- .probe = ads117x_platform_probe,
- .remove = __devexit_p(ads117x_platform_remove),
+ .probe = ads117x_probe,
+ .remove = __devexit_p(ads117x_remove),
};
static int __init ads117x_init(void)
diff --git a/sound/soc/codecs/ads117x.h b/sound/soc/codecs/ads117x.h
index dbcf50ec9bd1..3ce028614002 100644
--- a/sound/soc/codecs/ads117x.h
+++ b/sound/soc/codecs/ads117x.h
@@ -9,5 +9,5 @@
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*/
-extern struct snd_soc_dai ads117x_dai;
-extern struct snd_soc_codec_device soc_codec_dev_ads117x;
+extern struct snd_soc_dai_driver ads117x_dai;
+extern struct snd_soc_codec_driver soc_codec_dev_ads117x;
diff --git a/sound/soc/codecs/ak4104.c b/sound/soc/codecs/ak4104.c
index 192aebda3029..c27f8f59dc66 100644
--- a/sound/soc/codecs/ak4104.c
+++ b/sound/soc/codecs/ak4104.c
@@ -17,8 +17,6 @@
#include <linux/spi/spi.h>
#include <sound/asoundef.h>
-#include "ak4104.h"
-
/* AK4104 registers addresses */
#define AK4104_REG_CONTROL1 0x00
#define AK4104_REG_RESERVED 0x01
@@ -45,11 +43,11 @@
#define AK4104_TX_TXE (1 << 0)
#define AK4104_TX_V (1 << 1)
-#define DRV_NAME "ak4104"
+#define DRV_NAME "ak4104-codec"
struct ak4104_private {
- struct snd_soc_codec codec;
- u8 reg_cache[AK4104_NUM_REGS];
+ enum snd_soc_control_type control_type;
+ void *control_data;
};
static int ak4104_fill_cache(struct snd_soc_codec *codec)
@@ -58,7 +56,7 @@ static int ak4104_fill_cache(struct snd_soc_codec *codec)
u8 *reg_cache = codec->reg_cache;
struct spi_device *spi = codec->control_data;
- for (i = 0; i < codec->reg_cache_size; i++) {
+ for (i = 0; i < codec->driver->reg_cache_size; i++) {
int ret = spi_w8r8(spi, i | AK4104_READ);
if (ret < 0) {
dev_err(&spi->dev, "SPI write failure\n");
@@ -76,7 +74,7 @@ static unsigned int ak4104_read_reg_cache(struct snd_soc_codec *codec,
{
u8 *reg_cache = codec->reg_cache;
- if (reg >= codec->reg_cache_size)
+ if (reg >= codec->driver->reg_cache_size)
return -EINVAL;
return reg_cache[reg];
@@ -88,7 +86,7 @@ static int ak4104_spi_write(struct snd_soc_codec *codec, unsigned int reg,
u8 *cache = codec->reg_cache;
struct spi_device *spi = codec->control_data;
- if (reg >= codec->reg_cache_size)
+ if (reg >= codec->driver->reg_cache_size)
return -EINVAL;
/* only write to the hardware if value has changed */
@@ -145,8 +143,7 @@ static int ak4104_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;
int val = 0;
/* set the IEC958 bits: consumer mode, no copyright bit */
@@ -178,8 +175,8 @@ static struct snd_soc_dai_ops ak4101_dai_ops = {
.set_fmt = ak4104_set_dai_fmt,
};
-struct snd_soc_dai ak4104_dai = {
- .name = DRV_NAME,
+static struct snd_soc_dai_driver ak4104_dai = {
+ .name = "ak4104-hifi",
.playback = {
.stream_name = "Playback",
.channels_min = 2,
@@ -192,45 +189,17 @@ struct snd_soc_dai ak4104_dai = {
.ops = &ak4101_dai_ops,
};
-static struct snd_soc_codec *ak4104_codec;
-
-static int ak4104_spi_probe(struct spi_device *spi)
+static int ak4104_probe(struct snd_soc_codec *codec)
{
- struct snd_soc_codec *codec;
- struct ak4104_private *ak4104;
+ struct ak4104_private *ak4104 = snd_soc_codec_get_drvdata(codec);
int ret, val;
- spi->bits_per_word = 8;
- spi->mode = SPI_MODE_0;
- ret = spi_setup(spi);
- if (ret < 0)
- return ret;
-
- ak4104 = kzalloc(sizeof(struct ak4104_private), GFP_KERNEL);
- if (!ak4104) {
- dev_err(&spi->dev, "could not allocate codec\n");
- return -ENOMEM;
- }
-
- codec = &ak4104->codec;
- mutex_init(&codec->mutex);
- INIT_LIST_HEAD(&codec->dapm_widgets);
- INIT_LIST_HEAD(&codec->dapm_paths);
-
- codec->dev = &spi->dev;
- codec->name = DRV_NAME;
- codec->owner = THIS_MODULE;
- codec->dai = &ak4104_dai;
- codec->num_dai = 1;
- snd_soc_codec_set_drvdata(codec, ak4104);
- codec->control_data = spi;
- codec->reg_cache = ak4104->reg_cache;
- codec->reg_cache_size = AK4104_NUM_REGS;
+ codec->control_data = ak4104->control_data;
/* read all regs and fill the cache */
ret = ak4104_fill_cache(codec);
if (ret < 0) {
- dev_err(&spi->dev, "failed to fill register cache\n");
+ dev_err(codec->dev, "failed to fill register cache\n");
return ret;
}
@@ -238,93 +207,81 @@ static int ak4104_spi_probe(struct spi_device *spi)
* should contain 0x5b. Not a good way to verify the presence of
* the device, but there is no hardware ID register. */
if (ak4104_read_reg_cache(codec, AK4104_REG_RESERVED) !=
- AK4104_RESERVED_VAL) {
- ret = -ENODEV;
- goto error_free_codec;
- }
+ AK4104_RESERVED_VAL)
+ return -ENODEV;
/* set power-up and non-reset bits */
val = ak4104_read_reg_cache(codec, AK4104_REG_CONTROL1);
val |= AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN;
ret = ak4104_spi_write(codec, AK4104_REG_CONTROL1, val);
if (ret < 0)
- goto error_free_codec;
+ return ret;
/* enable transmitter */
val = ak4104_read_reg_cache(codec, AK4104_REG_TX);
val |= AK4104_TX_TXE;
ret = ak4104_spi_write(codec, AK4104_REG_TX, val);
if (ret < 0)
- goto error_free_codec;
-
- ak4104_codec = codec;
- ret = snd_soc_register_dai(&ak4104_dai);
- if (ret < 0) {
- dev_err(&spi->dev, "failed to register DAI\n");
- goto error_free_codec;
- }
+ return ret;
- spi_set_drvdata(spi, ak4104);
- dev_info(&spi->dev, "SPI device initialized\n");
+ dev_info(codec->dev, "SPI device initialized\n");
return 0;
-
-error_free_codec:
- kfree(ak4104);
- ak4104_dai.dev = NULL;
- return ret;
}
-static int __devexit ak4104_spi_remove(struct spi_device *spi)
+static int ak4104_remove(struct snd_soc_codec *codec)
{
- int ret, val;
- struct ak4104_private *ak4104 = spi_get_drvdata(spi);
+ int val, ret;
- val = ak4104_read_reg_cache(&ak4104->codec, AK4104_REG_CONTROL1);
+ val = ak4104_read_reg_cache(codec, AK4104_REG_CONTROL1);
if (val < 0)
return val;
/* clear power-up and non-reset bits */
val &= ~(AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN);
- ret = ak4104_spi_write(&ak4104->codec, AK4104_REG_CONTROL1, val);
- if (ret < 0)
- return ret;
+ ret = ak4104_spi_write(codec, AK4104_REG_CONTROL1, val);
- ak4104_codec = NULL;
- kfree(ak4104);
- return 0;
+ return ret;
}
-static int ak4104_probe(struct platform_device *pdev)
+static struct snd_soc_codec_driver soc_codec_device_ak4104 = {
+ .probe = ak4104_probe,
+ .remove = ak4104_remove,
+ .reg_cache_size = AK4104_NUM_REGS,
+ .reg_word_size = sizeof(u16),
+};
+
+static int ak4104_spi_probe(struct spi_device *spi)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec = ak4104_codec;
+ struct ak4104_private *ak4104;
int ret;
- /* Connect the codec to the socdev. snd_soc_new_pcms() needs this. */
- socdev->card->codec = codec;
-
- /* Register PCMs */
- ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
- if (ret < 0) {
- dev_err(codec->dev, "failed to create pcms\n");
+ spi->bits_per_word = 8;
+ spi->mode = SPI_MODE_0;
+ ret = spi_setup(spi);
+ if (ret < 0)
return ret;
- }
- return 0;
+ ak4104 = kzalloc(sizeof(struct ak4104_private), GFP_KERNEL);
+ if (ak4104 == NULL)
+ return -ENOMEM;
+
+ ak4104->control_data = spi;
+ ak4104->control_type = SND_SOC_SPI;
+ spi_set_drvdata(spi, ak4104);
+
+ ret = snd_soc_register_codec(&spi->dev,
+ &soc_codec_device_ak4104, &ak4104_dai, 1);
+ if (ret < 0)
+ kfree(ak4104);
+ return ret;
}
-static int ak4104_remove(struct platform_device *pdev)
+static int __devexit ak4104_spi_remove(struct spi_device *spi)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- snd_soc_free_pcms(socdev);
+ snd_soc_unregister_codec(&spi->dev);
+ kfree(spi_get_drvdata(spi));
return 0;
-};
-
-struct snd_soc_codec_device soc_codec_device_ak4104 = {
- .probe = ak4104_probe,
- .remove = ak4104_remove
-};
-EXPORT_SYMBOL_GPL(soc_codec_device_ak4104);
+}
static struct spi_driver ak4104_spi_driver = {
.driver = {
diff --git a/sound/soc/codecs/ak4104.h b/sound/soc/codecs/ak4104.h
deleted file mode 100644
index eb88fe7e4def..000000000000
--- a/sound/soc/codecs/ak4104.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef _AK4104_H
-#define _AK4104_H
-
-extern struct snd_soc_dai ak4104_dai;
-extern struct snd_soc_codec_device soc_codec_device_ak4104;
-
-#endif
diff --git a/sound/soc/codecs/ak4535.c b/sound/soc/codecs/ak4535.c
index d4253675b2d3..cd88c8f32a38 100644
--- a/sound/soc/codecs/ak4535.c
+++ b/sound/soc/codecs/ak4535.c
@@ -31,11 +31,11 @@
#define AK4535_VERSION "0.3"
-struct snd_soc_codec_device soc_codec_dev_ak4535;
-
/* codec private data */
struct ak4535_priv {
unsigned int sysclk;
+ enum snd_soc_control_type control_type;
+ void *control_data;
};
/*
@@ -313,8 +313,7 @@ static int ak4535_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 ak4535_priv *ak4535 = snd_soc_codec_get_drvdata(codec);
u8 mode2 = ak4535_read_reg_cache(codec, AK4535_MODE2) & ~(0x3 << 5);
int rate = params_rate(params), fs = 256;
@@ -378,14 +377,16 @@ static int ak4535_mute(struct snd_soc_dai *dai, int mute)
static int ak4535_set_bias_level(struct snd_soc_codec *codec,
enum snd_soc_bias_level level)
{
- u16 i;
+ u16 i, mute_reg;
switch (level) {
case SND_SOC_BIAS_ON:
- ak4535_mute(codec->dai, 0);
+ mute_reg = ak4535_read_reg_cache(codec, AK4535_DAC) & 0xffdf;
+ ak4535_write(codec, AK4535_DAC, mute_reg);
break;
case SND_SOC_BIAS_PREPARE:
- ak4535_mute(codec->dai, 1);
+ mute_reg = ak4535_read_reg_cache(codec, AK4535_DAC) & 0xffdf;
+ ak4535_write(codec, AK4535_DAC, mute_reg | 0x20);
break;
case SND_SOC_BIAS_STANDBY:
i = ak4535_read_reg_cache(codec, AK4535_PM1);
@@ -413,8 +414,8 @@ static struct snd_soc_dai_ops ak4535_dai_ops = {
.set_sysclk = ak4535_set_dai_sysclk,
};
-struct snd_soc_dai ak4535_dai = {
- .name = "AK4535",
+static struct snd_soc_dai_driver ak4535_dai = {
+ .name = "ak4535-hifi",
.playback = {
.stream_name = "Playback",
.channels_min = 1,
@@ -429,54 +430,27 @@ struct snd_soc_dai ak4535_dai = {
.formats = SNDRV_PCM_FMTBIT_S16_LE,},
.ops = &ak4535_dai_ops,
};
-EXPORT_SYMBOL_GPL(ak4535_dai);
-static int ak4535_suspend(struct platform_device *pdev, pm_message_t state)
+static int ak4535_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;
-
ak4535_set_bias_level(codec, SND_SOC_BIAS_OFF);
return 0;
}
-static int ak4535_resume(struct platform_device *pdev)
+static int ak4535_resume(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec = socdev->card->codec;
ak4535_sync(codec);
ak4535_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
return 0;
}
-/*
- * initialise the AK4535 driver
- * register the mixer and dsp interfaces with the kernel
- */
-static int ak4535_init(struct snd_soc_device *socdev)
+static int ak4535_probe(struct snd_soc_codec *codec)
{
- struct snd_soc_codec *codec = socdev->card->codec;
- int ret = 0;
+ struct ak4535_priv *ak4535 = snd_soc_codec_get_drvdata(codec);
- codec->name = "AK4535";
- codec->owner = THIS_MODULE;
- codec->read = ak4535_read_reg_cache;
- codec->write = ak4535_write;
- codec->set_bias_level = ak4535_set_bias_level;
- codec->dai = &ak4535_dai;
- codec->num_dai = 1;
- codec->reg_cache_size = ARRAY_SIZE(ak4535_reg);
- codec->reg_cache = kmemdup(ak4535_reg, sizeof(ak4535_reg), GFP_KERNEL);
-
- if (codec->reg_cache == NULL)
- return -ENOMEM;
+ printk(KERN_INFO "AK4535 Audio Codec %s", AK4535_VERSION);
- /* register pcms */
- ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
- if (ret < 0) {
- printk(KERN_ERR "ak4535: failed to create pcms\n");
- goto pcm_err;
- }
+ codec->control_data = ak4535->control_data;
/* power on device */
ak4535_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
@@ -485,39 +459,55 @@ static int ak4535_init(struct snd_soc_device *socdev)
ARRAY_SIZE(ak4535_snd_controls));
ak4535_add_widgets(codec);
- return ret;
-
-pcm_err:
- kfree(codec->reg_cache);
+ return 0;
+}
- return ret;
+/* power down chip */
+static int ak4535_remove(struct snd_soc_codec *codec)
+{
+ ak4535_set_bias_level(codec, SND_SOC_BIAS_OFF);
+ return 0;
}
-static struct snd_soc_device *ak4535_socdev;
+static struct snd_soc_codec_driver soc_codec_dev_ak4535 = {
+ .probe = ak4535_probe,
+ .remove = ak4535_remove,
+ .suspend = ak4535_suspend,
+ .resume = ak4535_resume,
+ .read = ak4535_read_reg_cache,
+ .write = ak4535_write,
+ .set_bias_level = ak4535_set_bias_level,
+ .reg_cache_size = ARRAY_SIZE(ak4535_reg),
+ .reg_word_size = sizeof(u8),
+ .reg_cache_default = ak4535_reg,
+};
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
-
-static int ak4535_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
+static __devinit int ak4535_i2c_probe(struct i2c_client *i2c,
+ const struct i2c_device_id *id)
{
- struct snd_soc_device *socdev = ak4535_socdev;
- struct snd_soc_codec *codec = socdev->card->codec;
+ struct ak4535_priv *ak4535;
int ret;
- i2c_set_clientdata(i2c, codec);
- codec->control_data = i2c;
+ ak4535 = kzalloc(sizeof(struct ak4535_priv), GFP_KERNEL);
+ if (ak4535 == NULL)
+ return -ENOMEM;
- ret = ak4535_init(socdev);
- if (ret < 0)
- printk(KERN_ERR "failed to initialise AK4535\n");
+ i2c_set_clientdata(i2c, ak4535);
+ ak4535->control_data = i2c;
+ ak4535->control_type = SND_SOC_I2C;
+ ret = snd_soc_register_codec(&i2c->dev,
+ &soc_codec_dev_ak4535, &ak4535_dai, 1);
+ if (ret < 0)
+ kfree(ak4535);
return ret;
}
-static int ak4535_i2c_remove(struct i2c_client *client)
+static __devexit int ak4535_i2c_remove(struct i2c_client *client)
{
- struct snd_soc_codec *codec = i2c_get_clientdata(client);
- kfree(codec->reg_cache);
+ snd_soc_unregister_codec(&client->dev);
+ kfree(i2c_get_clientdata(client));
return 0;
}
@@ -529,138 +519,34 @@ MODULE_DEVICE_TABLE(i2c, ak4535_i2c_id);
static struct i2c_driver ak4535_i2c_driver = {
.driver = {
- .name = "AK4535 I2C Codec",
+ .name = "ak4535-codec",
.owner = THIS_MODULE,
},
.probe = ak4535_i2c_probe,
- .remove = ak4535_i2c_remove,
+ .remove = __devexit_p(ak4535_i2c_remove),
.id_table = ak4535_i2c_id,
};
-
-static int ak4535_add_i2c_device(struct platform_device *pdev,
- const struct ak4535_setup_data *setup)
-{
- struct i2c_board_info info;
- struct i2c_adapter *adapter;
- struct i2c_client *client;
- int ret;
-
- ret = i2c_add_driver(&ak4535_i2c_driver);
- if (ret != 0) {
- dev_err(&pdev->dev, "can't add i2c driver\n");
- return ret;
- }
-
- memset(&info, 0, sizeof(struct i2c_board_info));
- info.addr = setup->i2c_address;
- strlcpy(info.type, "ak4535", I2C_NAME_SIZE);
-
- adapter = i2c_get_adapter(setup->i2c_bus);
- if (!adapter) {
- dev_err(&pdev->dev, "can't get i2c adapter %d\n",
- setup->i2c_bus);
- goto err_driver;
- }
-
- client = i2c_new_device(adapter, &info);
- i2c_put_adapter(adapter);
- if (!client) {
- dev_err(&pdev->dev, "can't add i2c device at 0x%x\n",
- (unsigned int)info.addr);
- goto err_driver;
- }
-
- return 0;
-
-err_driver:
- i2c_del_driver(&ak4535_i2c_driver);
- return -ENODEV;
-}
#endif
-static int ak4535_probe(struct platform_device *pdev)
+static int __init ak4535_modinit(void)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct ak4535_setup_data *setup;
- struct snd_soc_codec *codec;
- struct ak4535_priv *ak4535;
- int ret;
-
- printk(KERN_INFO "AK4535 Audio Codec %s", AK4535_VERSION);
-
- setup = socdev->codec_data;
- codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
- if (codec == NULL)
- return -ENOMEM;
-
- ak4535 = kzalloc(sizeof(struct ak4535_priv), GFP_KERNEL);
- if (ak4535 == NULL) {
- kfree(codec);
- return -ENOMEM;
- }
-
- snd_soc_codec_set_drvdata(codec, ak4535);
- socdev->card->codec = codec;
- mutex_init(&codec->mutex);
- INIT_LIST_HEAD(&codec->dapm_widgets);
- INIT_LIST_HEAD(&codec->dapm_paths);
-
- ak4535_socdev = socdev;
- ret = -ENODEV;
-
+ int ret = 0;
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
- if (setup->i2c_address) {
- codec->hw_write = (hw_write_t)i2c_master_send;
- ret = ak4535_add_i2c_device(pdev, setup);
- }
-#endif
-
+ ret = i2c_add_driver(&ak4535_i2c_driver);
if (ret != 0) {
- kfree(snd_soc_codec_get_drvdata(codec));
- kfree(codec);
+ printk(KERN_ERR "Failed to register AK4535 I2C driver: %d\n",
+ ret);
}
+#endif
return ret;
}
+module_init(ak4535_modinit);
-/* power down chip */
-static int ak4535_remove(struct platform_device *pdev)
+static void __exit ak4535_exit(void)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec = socdev->card->codec;
-
- if (codec->control_data)
- ak4535_set_bias_level(codec, SND_SOC_BIAS_OFF);
-
- snd_soc_free_pcms(socdev);
- snd_soc_dapm_free(socdev);
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
- if (codec->control_data)
- i2c_unregister_device(codec->control_data);
i2c_del_driver(&ak4535_i2c_driver);
#endif
- kfree(snd_soc_codec_get_drvdata(codec));
- kfree(codec);
-
- return 0;
-}
-
-struct snd_soc_codec_device soc_codec_dev_ak4535 = {
- .probe = ak4535_probe,
- .remove = ak4535_remove,
- .suspend = ak4535_suspend,
- .resume = ak4535_resume,
-};
-EXPORT_SYMBOL_GPL(soc_codec_dev_ak4535);
-
-static int __init ak4535_modinit(void)
-{
- return snd_soc_register_dai(&ak4535_dai);
-}
-module_init(ak4535_modinit);
-
-static void __exit ak4535_exit(void)
-{
- snd_soc_unregister_dai(&ak4535_dai);
}
module_exit(ak4535_exit);
diff --git a/sound/soc/codecs/ak4535.h b/sound/soc/codecs/ak4535.h
index c7a58703ea39..0431e5f634a2 100644
--- a/sound/soc/codecs/ak4535.h
+++ b/sound/soc/codecs/ak4535.h
@@ -36,12 +36,4 @@
#define AK4535_CACHEREGNUM 0x10
-struct ak4535_setup_data {
- int i2c_bus;
- unsigned short i2c_address;
-};
-
-extern struct snd_soc_dai ak4535_dai;
-extern struct snd_soc_codec_device soc_codec_dev_ak4535;
-
#endif
diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c
index 3d7dc55305ec..31b35e967398 100644
--- a/sound/soc/codecs/ak4642.c
+++ b/sound/soc/codecs/ak4642.c
@@ -30,8 +30,6 @@
#include <sound/initval.h>
#include <sound/tlv.h>
-#include "ak4642.h"
-
#define AK4642_VERSION "0.0.1"
#define PW_MGMT1 0x00
@@ -102,7 +100,6 @@
#define FS3 (1 << 5)
#define FS_MASK (FS0 | FS1 | FS2 | FS3)
-struct snd_soc_codec_device soc_codec_dev_ak4642;
/*
* Playback Volume (table 39)
@@ -123,11 +120,11 @@ static const struct snd_kcontrol_new ak4642_snd_controls[] = {
/* codec private data */
struct ak4642_priv {
- struct snd_soc_codec codec;
+ unsigned int sysclk;
+ enum snd_soc_control_type control_type;
+ void *control_data;
};
-static struct snd_soc_codec *ak4642_codec;
-
/*
* ak4642 register cache
*/
@@ -393,8 +390,8 @@ static struct snd_soc_dai_ops ak4642_dai_ops = {
.hw_params = ak4642_dai_hw_params,
};
-struct snd_soc_dai ak4642_dai = {
- .name = "AK4642",
+static struct snd_soc_dai_driver ak4642_dai = {
+ .name = "ak4642-hifi",
.playback = {
.stream_name = "Playback",
.channels_min = 1,
@@ -410,112 +407,63 @@ struct snd_soc_dai ak4642_dai = {
.ops = &ak4642_dai_ops,
.symmetric_rates = 1,
};
-EXPORT_SYMBOL_GPL(ak4642_dai);
-static int ak4642_resume(struct platform_device *pdev)
+static int ak4642_resume(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec = socdev->card->codec;
-
ak4642_sync(codec);
return 0;
}
-/*
- * initialise the AK4642 driver
- * register the mixer and dsp interfaces with the kernel
- */
-static int ak4642_init(struct ak4642_priv *ak4642)
+
+static int ak4642_probe(struct snd_soc_codec *codec)
{
- struct snd_soc_codec *codec = &ak4642->codec;
- int ret = 0;
+ struct ak4642_priv *ak4642 = snd_soc_codec_get_drvdata(codec);
- if (ak4642_codec) {
- dev_err(codec->dev, "Another ak4642 is registered\n");
- return -EINVAL;
- }
+ dev_info(codec->dev, "AK4642 Audio Codec %s", AK4642_VERSION);
- mutex_init(&codec->mutex);
- INIT_LIST_HEAD(&codec->dapm_widgets);
- INIT_LIST_HEAD(&codec->dapm_paths);
-
- snd_soc_codec_set_drvdata(codec, ak4642);
- codec->name = "AK4642";
- codec->owner = THIS_MODULE;
- codec->read = ak4642_read_reg_cache;
- codec->write = ak4642_write;
- codec->dai = &ak4642_dai;
- codec->num_dai = 1;
codec->hw_write = (hw_write_t)i2c_master_send;
- codec->reg_cache_size = ARRAY_SIZE(ak4642_reg);
- codec->reg_cache = kmemdup(ak4642_reg,
- sizeof(ak4642_reg), GFP_KERNEL);
-
- if (!codec->reg_cache)
- return -ENOMEM;
-
- ak4642_dai.dev = codec->dev;
- ak4642_codec = codec;
-
- ret = snd_soc_register_codec(codec);
- if (ret) {
- dev_err(codec->dev, "Failed to register codec: %d\n", ret);
- goto reg_cache_err;
- }
+ codec->control_data = ak4642->control_data;
- ret = snd_soc_register_dai(&ak4642_dai);
- if (ret) {
- dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
- snd_soc_unregister_codec(codec);
- goto reg_cache_err;
- }
-
- return ret;
-
-reg_cache_err:
- kfree(codec->reg_cache);
- codec->reg_cache = NULL;
- return ret;
+ return 0;
}
+static struct snd_soc_codec_driver soc_codec_dev_ak4642 = {
+ .probe = ak4642_probe,
+ .resume = ak4642_resume,
+ .read = ak4642_read_reg_cache,
+ .write = ak4642_write,
+ .reg_cache_size = ARRAY_SIZE(ak4642_reg),
+ .reg_word_size = sizeof(u8),
+ .reg_cache_default = ak4642_reg,
+};
+
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
-static int ak4642_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
+static __devinit int ak4642_i2c_probe(struct i2c_client *i2c,
+ const struct i2c_device_id *id)
{
struct ak4642_priv *ak4642;
- struct snd_soc_codec *codec;
int ret;
ak4642 = kzalloc(sizeof(struct ak4642_priv), GFP_KERNEL);
- if (!ak4642)
+ if (ak4642 == NULL)
return -ENOMEM;
- codec = &ak4642->codec;
- codec->dev = &i2c->dev;
-
i2c_set_clientdata(i2c, ak4642);
- codec->control_data = i2c;
+ ak4642->control_data = i2c;
+ ak4642->control_type = SND_SOC_I2C;
- ret = ak4642_init(ak4642);
- if (ret < 0) {
- printk(KERN_ERR "failed to initialise AK4642\n");
+ ret = snd_soc_register_codec(&i2c->dev,
+ &soc_codec_dev_ak4642, &ak4642_dai, 1);
+ if (ret < 0)
kfree(ak4642);
- }
-
return ret;
}
-static int ak4642_i2c_remove(struct i2c_client *client)
+static __devexit int ak4642_i2c_remove(struct i2c_client *client)
{
- struct ak4642_priv *ak4642 = i2c_get_clientdata(client);
-
- snd_soc_unregister_dai(&ak4642_dai);
- snd_soc_unregister_codec(&ak4642->codec);
- kfree(ak4642->codec.reg_cache);
- kfree(ak4642);
- ak4642_codec = NULL;
-
+ snd_soc_unregister_codec(&client->dev);
+ kfree(i2c_get_clientdata(client));
return 0;
}
@@ -528,64 +476,15 @@ MODULE_DEVICE_TABLE(i2c, ak4642_i2c_id);
static struct i2c_driver ak4642_i2c_driver = {
.driver = {
- .name = "AK4642 I2C Codec",
+ .name = "ak4642-codec",
.owner = THIS_MODULE,
},
- .probe = ak4642_i2c_probe,
- .remove = ak4642_i2c_remove,
- .id_table = ak4642_i2c_id,
+ .probe = ak4642_i2c_probe,
+ .remove = __devexit_p(ak4642_i2c_remove),
+ .id_table = ak4642_i2c_id,
};
-
#endif
-static int ak4642_probe(struct platform_device *pdev)
-{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- int ret;
-
- if (!ak4642_codec) {
- dev_err(&pdev->dev, "Codec device not registered\n");
- return -ENODEV;
- }
-
- socdev->card->codec = ak4642_codec;
-
- /* register pcms */
- ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
- if (ret < 0) {
- printk(KERN_ERR "ak4642: failed to create pcms\n");
- goto pcm_err;
- }
-
- snd_soc_add_controls(ak4642_codec, ak4642_snd_controls,
- ARRAY_SIZE(ak4642_snd_controls));
-
- dev_info(&pdev->dev, "AK4642 Audio Codec %s", AK4642_VERSION);
- return ret;
-
-pcm_err:
- return ret;
-
-}
-
-/* power down chip */
-static int ak4642_remove(struct platform_device *pdev)
-{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
-
- snd_soc_free_pcms(socdev);
- snd_soc_dapm_free(socdev);
-
- return 0;
-}
-
-struct snd_soc_codec_device soc_codec_dev_ak4642 = {
- .probe = ak4642_probe,
- .remove = ak4642_remove,
- .resume = ak4642_resume,
-};
-EXPORT_SYMBOL_GPL(soc_codec_dev_ak4642);
-
static int __init ak4642_modinit(void)
{
int ret = 0;
diff --git a/sound/soc/codecs/ak4642.h b/sound/soc/codecs/ak4642.h
deleted file mode 100644
index e476833d314e..000000000000
--- a/sound/soc/codecs/ak4642.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * ak4642.h -- AK4642 Soc Audio driver
- *
- * Copyright (C) 2009 Renesas Solutions Corp.
- * Kuninori Morimoto <morimoto.kuninori@renesas.com>
- *
- * Based on ak4535.c
- *
- * 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 _AK4642_H
-#define _AK4642_H
-
-extern struct snd_soc_dai ak4642_dai;
-extern struct snd_soc_codec_device soc_codec_dev_ak4642;
-
-#endif
diff --git a/sound/soc/codecs/ak4671.c b/sound/soc/codecs/ak4671.c
index 87566932a3b1..239f0562003c 100644
--- a/sound/soc/codecs/ak4671.c
+++ b/sound/soc/codecs/ak4671.c
@@ -23,11 +23,11 @@
#include "ak4671.h"
-static struct snd_soc_codec *ak4671_codec;
/* codec private data */
struct ak4671_priv {
- struct snd_soc_codec codec;
+ enum snd_soc_control_type control_type;
+ void *control_data;
u8 reg_cache[AK4671_CACHEREGNUM];
};
@@ -619,8 +619,8 @@ static struct snd_soc_dai_ops ak4671_dai_ops = {
.set_fmt = ak4671_set_dai_fmt,
};
-struct snd_soc_dai ak4671_dai = {
- .name = "AK4671",
+static struct snd_soc_dai_driver ak4671_dai = {
+ .name = "ak4671-hifi",
.playback = {
.stream_name = "Playback",
.channels_min = 1,
@@ -635,27 +635,19 @@ struct snd_soc_dai ak4671_dai = {
.formats = AK4671_FORMATS,},
.ops = &ak4671_dai_ops,
};
-EXPORT_SYMBOL_GPL(ak4671_dai);
-static int ak4671_probe(struct platform_device *pdev)
+static int ak4671_probe(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec;
- int ret = 0;
-
- if (ak4671_codec == NULL) {
- dev_err(&pdev->dev, "Codec device not registered\n");
- return -ENODEV;
- }
+ struct ak4671_priv *ak4671 = snd_soc_codec_get_drvdata(codec);
+ int ret;
- socdev->card->codec = ak4671_codec;
- codec = ak4671_codec;
+ codec->hw_write = (hw_write_t)i2c_master_send;
+ codec->bias_level = SND_SOC_BIAS_OFF;
- /* register pcms */
- ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
+ ret = snd_soc_codec_set_cache_io(codec, 8, 8, ak4671->control_type);
if (ret < 0) {
- dev_err(codec->dev, "failed to create pcms: %d\n", ret);
- goto pcm_err;
+ dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
+ return ret;
}
snd_soc_add_controls(codec, ak4671_snd_controls,
@@ -665,121 +657,48 @@ static int ak4671_probe(struct platform_device *pdev)
ak4671_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
return ret;
-
-pcm_err:
- return ret;
}
-static int ak4671_remove(struct platform_device *pdev)
+static int ak4671_remove(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
-
- snd_soc_free_pcms(socdev);
- snd_soc_dapm_free(socdev);
-
+ ak4671_set_bias_level(codec, SND_SOC_BIAS_OFF);
return 0;
}
-struct snd_soc_codec_device soc_codec_dev_ak4671 = {
+static struct snd_soc_codec_driver soc_codec_dev_ak4671 = {
.probe = ak4671_probe,
.remove = ak4671_remove,
+ .set_bias_level = ak4671_set_bias_level,
+ .reg_cache_size = AK4671_CACHEREGNUM,
+ .reg_word_size = sizeof(u8),
+ .reg_cache_default = ak4671_reg,
};
-EXPORT_SYMBOL_GPL(soc_codec_dev_ak4671);
-
-static int ak4671_register(struct ak4671_priv *ak4671,
- enum snd_soc_control_type control)
-{
- int ret;
- struct snd_soc_codec *codec = &ak4671->codec;
-
- if (ak4671_codec) {
- dev_err(codec->dev, "Another AK4671 is registered\n");
- ret = -EINVAL;
- goto err;
- }
-
- mutex_init(&codec->mutex);
- INIT_LIST_HEAD(&codec->dapm_widgets);
- INIT_LIST_HEAD(&codec->dapm_paths);
-
- snd_soc_codec_set_drvdata(codec, ak4671);
- codec->name = "AK4671";
- codec->owner = THIS_MODULE;
- codec->bias_level = SND_SOC_BIAS_OFF;
- codec->set_bias_level = ak4671_set_bias_level;
- codec->dai = &ak4671_dai;
- codec->num_dai = 1;
- codec->reg_cache_size = AK4671_CACHEREGNUM;
- codec->reg_cache = &ak4671->reg_cache;
-
- memcpy(codec->reg_cache, ak4671_reg, sizeof(ak4671_reg));
-
- ret = snd_soc_codec_set_cache_io(codec, 8, 8, control);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- goto err;
- }
-
- ak4671_dai.dev = codec->dev;
- ak4671_codec = codec;
-
- ret = snd_soc_register_codec(codec);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to register codec: %d\n", ret);
- goto err;
- }
-
- ret = snd_soc_register_dai(&ak4671_dai);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
- goto err_codec;
- }
-
- return 0;
-
-err_codec:
- snd_soc_unregister_codec(codec);
-err:
- kfree(ak4671);
- return ret;
-}
-
-static void ak4671_unregister(struct ak4671_priv *ak4671)
-{
- ak4671_set_bias_level(&ak4671->codec, SND_SOC_BIAS_OFF);
- snd_soc_unregister_dai(&ak4671_dai);
- snd_soc_unregister_codec(&ak4671->codec);
- kfree(ak4671);
- ak4671_codec = NULL;
-}
static int __devinit ak4671_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct ak4671_priv *ak4671;
- struct snd_soc_codec *codec;
+ int ret;
ak4671 = kzalloc(sizeof(struct ak4671_priv), GFP_KERNEL);
if (ak4671 == NULL)
return -ENOMEM;
- codec = &ak4671->codec;
- codec->hw_write = (hw_write_t)i2c_master_send;
-
i2c_set_clientdata(client, ak4671);
- codec->control_data = client;
-
- codec->dev = &client->dev;
+ ak4671->control_data = client;
+ ak4671->control_type = SND_SOC_I2C;
- return ak4671_register(ak4671, SND_SOC_I2C);
+ ret = snd_soc_register_codec(&client->dev,
+ &soc_codec_dev_ak4671, &ak4671_dai, 1);
+ if (ret < 0)
+ kfree(ak4671);
+ return ret;
}
static __devexit int ak4671_i2c_remove(struct i2c_client *client)
{
- struct ak4671_priv *ak4671 = i2c_get_clientdata(client);
-
- ak4671_unregister(ak4671);
-
+ snd_soc_unregister_codec(&client->dev);
+ kfree(i2c_get_clientdata(client));
return 0;
}
@@ -791,7 +710,7 @@ MODULE_DEVICE_TABLE(i2c, ak4671_i2c_id);
static struct i2c_driver ak4671_i2c_driver = {
.driver = {
- .name = "ak4671",
+ .name = "ak4671-codec",
.owner = THIS_MODULE,
},
.probe = ak4671_i2c_probe,
diff --git a/sound/soc/codecs/ak4671.h b/sound/soc/codecs/ak4671.h
index e2fad964e88b..61cb7ab7552c 100644
--- a/sound/soc/codecs/ak4671.h
+++ b/sound/soc/codecs/ak4671.h
@@ -150,7 +150,4 @@
/* AK4671_LOUT2_POWER_MANAGEMENT (0x10) Fields */
#define AK4671_MUTEN 0x04
-extern struct snd_soc_dai ak4671_dai;
-extern struct snd_soc_codec_device soc_codec_dev_ak4671;
-
#endif
diff --git a/sound/soc/codecs/cq93vc.c b/sound/soc/codecs/cq93vc.c
index a320fb5a0e26..823643932dde 100644
--- a/sound/soc/codecs/cq93vc.c
+++ b/sound/soc/codecs/cq93vc.c
@@ -30,6 +30,7 @@
#include <linux/slab.h>
#include <linux/clk.h>
#include <linux/mfd/davinci_voicecodec.h>
+#include <linux/spi/spi.h>
#include <sound/core.h>
#include <sound/pcm.h>
@@ -41,8 +42,6 @@
#include <mach/dm365.h>
-#include "cq93vc.h"
-
static inline unsigned int cq93vc_read(struct snd_soc_codec *codec,
unsigned int reg)
{
@@ -130,8 +129,8 @@ static struct snd_soc_dai_ops cq93vc_dai_ops = {
.set_sysclk = cq93vc_set_dai_sysclk,
};
-struct snd_soc_dai cq93vc_dai = {
- .name = "CQ93VC",
+static struct snd_soc_dai_driver cq93vc_dai = {
+ .name = "cq93vc-hifi",
.playback = {
.stream_name = "Playback",
.channels_min = 1,
@@ -146,36 +145,20 @@ struct snd_soc_dai cq93vc_dai = {
.formats = CQ93VC_FORMATS,},
.ops = &cq93vc_dai_ops,
};
-EXPORT_SYMBOL_GPL(cq93vc_dai);
-static int cq93vc_resume(struct platform_device *pdev)
+static int cq93vc_resume(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec = socdev->card->codec;
-
cq93vc_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
return 0;
}
-static struct snd_soc_codec *cq93vc_codec;
-
-static int cq93vc_probe(struct platform_device *pdev)
+static int cq93vc_probe(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct device *dev = &pdev->dev;
- struct snd_soc_codec *codec;
- int ret;
-
- socdev->card->codec = cq93vc_codec;
- codec = socdev->card->codec;
-
- /* Register pcms */
- ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
- if (ret < 0) {
- dev_err(dev, "%s: failed to create pcms\n", pdev->name);
- return ret;
- }
+ struct davinci_vc *davinci_vc = codec->dev->platform_data;
+
+ davinci_vc->cq93vc.codec = codec;
+ codec->control_data = davinci_vc;
/* Set controls */
snd_soc_add_controls(codec, cq93vc_snd_controls,
@@ -187,108 +170,51 @@ static int cq93vc_probe(struct platform_device *pdev)
return 0;
}
-static int cq93vc_remove(struct platform_device *pdev)
+static int cq93vc_remove(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
-
- snd_soc_free_pcms(socdev);
- snd_soc_dapm_free(socdev);
+ cq93vc_set_bias_level(codec, SND_SOC_BIAS_OFF);
return 0;
}
-struct snd_soc_codec_device soc_codec_dev_cq93vc = {
+static struct snd_soc_codec_driver soc_codec_dev_cq93vc = {
+ .read = cq93vc_read,
+ .write = cq93vc_write,
+ .set_bias_level = cq93vc_set_bias_level,
.probe = cq93vc_probe,
.remove = cq93vc_remove,
.resume = cq93vc_resume,
};
-EXPORT_SYMBOL_GPL(soc_codec_dev_cq93vc);
-static __init int cq93vc_codec_probe(struct platform_device *pdev)
+static int cq93vc_platform_probe(struct platform_device *pdev)
{
- struct davinci_vc *davinci_vc = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec;
- int ret;
-
- codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
- if (codec == NULL) {
- dev_dbg(davinci_vc->dev,
- "could not allocate memory for codec data\n");
- return -ENOMEM;
- }
-
- davinci_vc->cq93vc.codec = codec;
-
- cq93vc_dai.dev = &pdev->dev;
-
- mutex_init(&codec->mutex);
- INIT_LIST_HEAD(&codec->dapm_widgets);
- INIT_LIST_HEAD(&codec->dapm_paths);
- codec->dev = &pdev->dev;
- codec->name = "CQ93VC";
- codec->owner = THIS_MODULE;
- codec->read = cq93vc_read;
- codec->write = cq93vc_write;
- codec->set_bias_level = cq93vc_set_bias_level;
- codec->dai = &cq93vc_dai;
- codec->num_dai = 1;
- codec->control_data = davinci_vc;
-
- cq93vc_codec = codec;
-
- ret = snd_soc_register_codec(codec);
- if (ret) {
- dev_err(davinci_vc->dev, "failed to register codec\n");
- goto fail1;
- }
-
- ret = snd_soc_register_dai(&cq93vc_dai);
- if (ret) {
- dev_err(davinci_vc->dev, "could register dai\n");
- goto fail2;
- }
- return 0;
-
-fail2:
- snd_soc_unregister_codec(codec);
-
-fail1:
- kfree(codec);
- cq93vc_codec = NULL;
-
- return ret;
+ return snd_soc_register_codec(&pdev->dev,
+ &soc_codec_dev_cq93vc, &cq93vc_dai, 1);
}
-static int __devexit cq93vc_codec_remove(struct platform_device *pdev)
+static int cq93vc_platform_remove(struct platform_device *pdev)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec = socdev->card->codec;
-
- snd_soc_unregister_dai(&cq93vc_dai);
- snd_soc_unregister_codec(&codec);
-
- kfree(codec);
- cq93vc_codec = NULL;
-
+ snd_soc_unregister_codec(&pdev->dev);
return 0;
}
static struct platform_driver cq93vc_codec_driver = {
.driver = {
- .name = "cq93vc",
- .owner = THIS_MODULE,
- },
- .probe = cq93vc_codec_probe,
- .remove = __devexit_p(cq93vc_codec_remove),
+ .name = "cq93vc-codec",
+ .owner = THIS_MODULE,
+ },
+
+ .probe = cq93vc_platform_probe,
+ .remove = __devexit_p(cq93vc_platform_remove),
};
-static __init int cq93vc_init(void)
+static int __init cq93vc_init(void)
{
- return platform_driver_probe(&cq93vc_codec_driver, cq93vc_codec_probe);
+ return platform_driver_register(&cq93vc_codec_driver);
}
module_init(cq93vc_init);
-static __exit void cq93vc_exit(void)
+static void __exit cq93vc_exit(void)
{
platform_driver_unregister(&cq93vc_codec_driver);
}
diff --git a/sound/soc/codecs/cq93vc.h b/sound/soc/codecs/cq93vc.h
deleted file mode 100644
index 845b1968ef9c..000000000000
--- a/sound/soc/codecs/cq93vc.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * ALSA SoC CQ0093 Voice Codec Driver for DaVinci platforms
- *
- * Copyright (C) 2010 Texas Instruments, Inc
- *
- * Author: Miguel Aguilar <miguel.aguilar@ridgerun.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.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef _CQ93VC_H
-#define _CQ93VC_H
-
-extern struct snd_soc_dai cq93vc_dai;
-extern struct snd_soc_codec_device soc_codec_dev_cq93vc;
-
-#endif
diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c
index 30d949239def..6542dc038951 100644
--- a/sound/soc/codecs/cs4270.c
+++ b/sound/soc/codecs/cs4270.c
@@ -31,8 +31,6 @@
#include <linux/delay.h>
#include <linux/regulator/consumer.h>
-#include "cs4270.h"
-
/*
* The codec isn't really big-endian or little-endian, since the I2S
* interface requires data to be sent serially with the MSbit first.
@@ -114,7 +112,8 @@ static const char *supply_names[] = {
/* Private data for the CS4270 */
struct cs4270_private {
- struct snd_soc_codec codec;
+ enum snd_soc_control_type control_type;
+ void *control_data;
u8 reg_cache[CS4270_NUMREGS];
unsigned int mclk; /* Input frequency of the MCLK pin */
unsigned int mode; /* The mode (I2S or left-justified) */
@@ -212,44 +211,8 @@ static int cs4270_set_dai_sysclk(struct snd_soc_dai *codec_dai,
{
struct snd_soc_codec *codec = codec_dai->codec;
struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
- unsigned int rates = 0;
- unsigned int rate_min = -1;
- unsigned int rate_max = 0;
- unsigned int i;
cs4270->mclk = freq;
-
- if (cs4270->mclk) {
- for (i = 0; i < NUM_MCLK_RATIOS; i++) {
- unsigned int rate = freq / cs4270_mode_ratios[i].ratio;
- rates |= snd_pcm_rate_to_rate_bit(rate);
- if (rate < rate_min)
- rate_min = rate;
- if (rate > rate_max)
- rate_max = rate;
- }
- /* FIXME: soc should support a rate list */
- rates &= ~SNDRV_PCM_RATE_KNOT;
-
- if (!rates) {
- dev_err(codec->dev, "could not find a valid sample rate\n");
- return -EINVAL;
- }
- } else {
- /* enable all possible rates */
- rates = SNDRV_PCM_RATE_8000_192000;
- rate_min = 8000;
- rate_max = 192000;
- }
-
- codec_dai->playback.rates = rates;
- codec_dai->playback.rate_min = rate_min;
- codec_dai->playback.rate_max = rate_max;
-
- codec_dai->capture.rates = rates;
- codec_dai->capture.rate_min = rate_min;
- codec_dai->capture.rate_max = rate_max;
-
return 0;
}
@@ -410,8 +373,7 @@ static int cs4270_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 cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
int ret;
unsigned int i;
@@ -549,19 +511,6 @@ static const struct snd_kcontrol_new cs4270_snd_controls[] = {
snd_soc_get_volsw, cs4270_soc_put_mute),
};
-/*
- * cs4270_codec - global variable to store codec for the ASoC probe function
- *
- * If struct i2c_driver had a private_data field, we wouldn't need to use
- * cs4270_codec. This is the only way to pass the codec structure from
- * cs4270_i2c_probe() to cs4270_probe(). Unfortunately, there is no good
- * way to synchronize these two functions. cs4270_i2c_probe() can be called
- * multiple times before cs4270_probe() is called even once. So for now, we
- * also only allow cs4270_i2c_probe() to be run once. That means that we do
- * not support more than one cs4270 device in the system, at least for now.
- */
-static struct snd_soc_codec *cs4270_codec;
-
static struct snd_soc_dai_ops cs4270_dai_ops = {
.hw_params = cs4270_hw_params,
.set_sysclk = cs4270_set_dai_sysclk,
@@ -569,20 +518,24 @@ static struct snd_soc_dai_ops cs4270_dai_ops = {
.digital_mute = cs4270_dai_mute,
};
-struct snd_soc_dai cs4270_dai = {
- .name = "cs4270",
+struct snd_soc_dai_driver cs4270_dai = {
+ .name = "cs4270-hifi",
.playback = {
.stream_name = "Playback",
.channels_min = 1,
.channels_max = 2,
- .rates = 0,
+ .rates = SNDRV_PCM_RATE_CONTINUOUS,
+ .rate_min = 4000,
+ .rate_max = 216000,
.formats = CS4270_FORMATS,
},
.capture = {
.stream_name = "Capture",
.channels_min = 1,
.channels_max = 2,
- .rates = 0,
+ .rates = SNDRV_PCM_RATE_CONTINUOUS,
+ .rate_min = 4000,
+ .rate_max = 216000,
.formats = CS4270_FORMATS,
},
.ops = &cs4270_dai_ops,
@@ -596,153 +549,19 @@ EXPORT_SYMBOL_GPL(cs4270_dai);
* This function is called when ASoC has all the pieces it needs to
* instantiate a sound driver.
*/
-static int cs4270_probe(struct platform_device *pdev)
-{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec = cs4270_codec;
- struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
- int i, ret;
-
- /* Connect the codec to the socdev. snd_soc_new_pcms() needs this. */
- socdev->card->codec = codec;
-
- /* Register PCMs */
- ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
- if (ret < 0) {
- dev_err(codec->dev, "failed to create pcms\n");
- return ret;
- }
-
- /* Add the non-DAPM controls */
- ret = snd_soc_add_controls(codec, cs4270_snd_controls,
- ARRAY_SIZE(cs4270_snd_controls));
- if (ret < 0) {
- dev_err(codec->dev, "failed to add controls\n");
- goto error_free_pcms;
- }
-
- /* get the power supply regulators */
- for (i = 0; i < ARRAY_SIZE(supply_names); i++)
- cs4270->supplies[i].supply = supply_names[i];
-
- ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(cs4270->supplies),
- cs4270->supplies);
- if (ret < 0)
- goto error_free_pcms;
-
- ret = regulator_bulk_enable(ARRAY_SIZE(cs4270->supplies),
- cs4270->supplies);
- if (ret < 0)
- goto error_free_regulators;
-
- return 0;
-
-error_free_regulators:
- regulator_bulk_free(ARRAY_SIZE(cs4270->supplies),
- cs4270->supplies);
-
-error_free_pcms:
- snd_soc_free_pcms(socdev);
-
- return ret;
-}
-
-/**
- * cs4270_remove - ASoC remove function
- * @pdev: platform device
- *
- * This function is the counterpart to cs4270_probe().
- */
-static int cs4270_remove(struct platform_device *pdev)
+static int cs4270_probe(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec = cs4270_codec;
struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
+ int i, ret, reg;
- snd_soc_free_pcms(socdev);
- regulator_bulk_disable(ARRAY_SIZE(cs4270->supplies), cs4270->supplies);
- regulator_bulk_free(ARRAY_SIZE(cs4270->supplies), cs4270->supplies);
-
- return 0;
-};
-
-/**
- * cs4270_i2c_probe - initialize the I2C interface of the CS4270
- * @i2c_client: the I2C client object
- * @id: the I2C device ID (ignored)
- *
- * This function is called whenever the I2C subsystem finds a device that
- * matches the device ID given via a prior call to i2c_add_driver().
- */
-static int cs4270_i2c_probe(struct i2c_client *i2c_client,
- const struct i2c_device_id *id)
-{
- struct snd_soc_codec *codec;
- struct cs4270_private *cs4270;
- unsigned int reg;
- int ret;
-
- /* For now, we only support one cs4270 device in the system. See the
- * comment for cs4270_codec.
- */
- if (cs4270_codec) {
- dev_err(&i2c_client->dev, "ignoring CS4270 at addr %X\n",
- i2c_client->addr);
- dev_err(&i2c_client->dev, "only one per board allowed\n");
- /* Should we return something other than ENODEV here? */
- return -ENODEV;
- }
-
- /* Verify that we have a CS4270 */
-
- ret = i2c_smbus_read_byte_data(i2c_client, CS4270_CHIPID);
- if (ret < 0) {
- dev_err(&i2c_client->dev, "failed to read i2c at addr %X\n",
- i2c_client->addr);
- return ret;
- }
- /* The top four bits of the chip ID should be 1100. */
- if ((ret & 0xF0) != 0xC0) {
- dev_err(&i2c_client->dev, "device at addr %X is not a CS4270\n",
- i2c_client->addr);
- return -ENODEV;
- }
-
- dev_info(&i2c_client->dev, "found device at i2c address %X\n",
- i2c_client->addr);
- dev_info(&i2c_client->dev, "hardware revision %X\n", ret & 0xF);
-
- /* Allocate enough space for the snd_soc_codec structure
- and our private data together. */
- cs4270 = kzalloc(sizeof(struct cs4270_private), GFP_KERNEL);
- if (!cs4270) {
- dev_err(&i2c_client->dev, "could not allocate codec\n");
- return -ENOMEM;
- }
- codec = &cs4270->codec;
-
- mutex_init(&codec->mutex);
- INIT_LIST_HEAD(&codec->dapm_widgets);
- INIT_LIST_HEAD(&codec->dapm_paths);
-
- codec->dev = &i2c_client->dev;
- codec->name = "CS4270";
- codec->owner = THIS_MODULE;
- codec->dai = &cs4270_dai;
- codec->num_dai = 1;
- snd_soc_codec_set_drvdata(codec, cs4270);
- codec->control_data = i2c_client;
- codec->read = cs4270_read_reg_cache;
- codec->write = cs4270_i2c_write;
- codec->reg_cache = cs4270->reg_cache;
- codec->reg_cache_size = CS4270_NUMREGS;
+ codec->control_data = cs4270->control_data;
/* The I2C interface is set up, so pre-fill our register cache */
ret = cs4270_fill_cache(codec);
if (ret < 0) {
- dev_err(&i2c_client->dev, "failed to fill register cache\n");
- goto error_free_codec;
+ dev_err(codec->dev, "failed to fill register cache\n");
+ return ret;
}
/* Disable auto-mute. This feature appears to be buggy. In some
@@ -755,7 +574,7 @@ static int cs4270_i2c_probe(struct i2c_client *i2c_client,
reg &= ~CS4270_MUTE_AUTO;
ret = cs4270_i2c_write(codec, CS4270_MUTE, reg);
if (ret < 0) {
- dev_err(&i2c_client->dev, "i2c write failed\n");
+ dev_err(codec->dev, "i2c write failed\n");
return ret;
}
@@ -769,65 +588,56 @@ static int cs4270_i2c_probe(struct i2c_client *i2c_client,
reg &= ~(CS4270_TRANS_SOFT | CS4270_TRANS_ZERO);
ret = cs4270_i2c_write(codec, CS4270_TRANS, reg);
if (ret < 0) {
- dev_err(&i2c_client->dev, "i2c write failed\n");
+ dev_err(codec->dev, "i2c write failed\n");
return ret;
}
- /* Initialize the DAI. Normally, we'd prefer to have a kmalloc'd DAI
- * structure for each CS4270 device, but the machine driver needs to
- * have a pointer to the DAI structure, so for now it must be a global
- * variable.
- */
- cs4270_dai.dev = &i2c_client->dev;
-
- /* Register the DAI. If all the other ASoC driver have already
- * registered, then this will call our probe function, so
- * cs4270_codec needs to be ready.
- */
- cs4270_codec = codec;
- ret = snd_soc_register_dai(&cs4270_dai);
+ /* Add the non-DAPM controls */
+ ret = snd_soc_add_controls(codec, cs4270_snd_controls,
+ ARRAY_SIZE(cs4270_snd_controls));
if (ret < 0) {
- dev_err(&i2c_client->dev, "failed to register DAIe\n");
- goto error_free_codec;
+ dev_err(codec->dev, "failed to add controls\n");
+ return ret;
}
- i2c_set_clientdata(i2c_client, cs4270);
+ /* get the power supply regulators */
+ for (i = 0; i < ARRAY_SIZE(supply_names); i++)
+ cs4270->supplies[i].supply = supply_names[i];
+
+ ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(cs4270->supplies),
+ cs4270->supplies);
+ if (ret < 0)
+ return ret;
+
+ ret = regulator_bulk_enable(ARRAY_SIZE(cs4270->supplies),
+ cs4270->supplies);
+ if (ret < 0)
+ goto error_free_regulators;
return 0;
-error_free_codec:
- kfree(cs4270);
- cs4270_codec = NULL;
- cs4270_dai.dev = NULL;
+error_free_regulators:
+ regulator_bulk_free(ARRAY_SIZE(cs4270->supplies),
+ cs4270->supplies);
return ret;
}
/**
- * cs4270_i2c_remove - remove an I2C device
- * @i2c_client: the I2C client object
+ * cs4270_remove - ASoC remove function
+ * @pdev: platform device
*
- * This function is the counterpart to cs4270_i2c_probe().
+ * This function is the counterpart to cs4270_probe().
*/
-static int cs4270_i2c_remove(struct i2c_client *i2c_client)
+static int cs4270_remove(struct snd_soc_codec *codec)
{
- struct cs4270_private *cs4270 = i2c_get_clientdata(i2c_client);
+ struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
- kfree(cs4270);
- cs4270_codec = NULL;
- cs4270_dai.dev = NULL;
+ regulator_bulk_disable(ARRAY_SIZE(cs4270->supplies), cs4270->supplies);
+ regulator_bulk_free(ARRAY_SIZE(cs4270->supplies), cs4270->supplies);
return 0;
-}
-
-/*
- * cs4270_id - I2C device IDs supported by this driver
- */
-static struct i2c_device_id cs4270_id[] = {
- {"cs4270", 0},
- {}
};
-MODULE_DEVICE_TABLE(i2c, cs4270_id);
#ifdef CONFIG_PM
@@ -840,9 +650,8 @@ MODULE_DEVICE_TABLE(i2c, cs4270_id);
* and all registers are written back to the hardware when resuming.
*/
-static int cs4270_soc_suspend(struct platform_device *pdev, pm_message_t mesg)
+static int cs4270_soc_suspend(struct snd_soc_codec *codec, pm_message_t mesg)
{
- struct snd_soc_codec *codec = cs4270_codec;
struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
int reg, ret;
@@ -860,9 +669,8 @@ static int cs4270_soc_suspend(struct platform_device *pdev, pm_message_t mesg)
return 0;
}
-static int cs4270_soc_resume(struct platform_device *pdev)
+static int cs4270_soc_resume(struct snd_soc_codec *codec)
{
- struct snd_soc_codec *codec = cs4270_codec;
struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
struct i2c_client *i2c_client = codec->control_data;
int reg;
@@ -896,6 +704,95 @@ static int cs4270_soc_resume(struct platform_device *pdev)
#endif /* CONFIG_PM */
/*
+ * ASoC codec device structure
+ *
+ * Assign this variable to the codec_dev field of the machine driver's
+ * snd_soc_device structure.
+ */
+static struct snd_soc_codec_driver soc_codec_device_cs4270 = {
+ .probe = cs4270_probe,
+ .remove = cs4270_remove,
+ .suspend = cs4270_soc_suspend,
+ .resume = cs4270_soc_resume,
+ .read = cs4270_read_reg_cache,
+ .write = cs4270_i2c_write,
+ .reg_cache_size = CS4270_NUMREGS,
+ .reg_word_size = sizeof(u8),
+};
+
+/**
+ * cs4270_i2c_probe - initialize the I2C interface of the CS4270
+ * @i2c_client: the I2C client object
+ * @id: the I2C device ID (ignored)
+ *
+ * This function is called whenever the I2C subsystem finds a device that
+ * matches the device ID given via a prior call to i2c_add_driver().
+ */
+static int cs4270_i2c_probe(struct i2c_client *i2c_client,
+ const struct i2c_device_id *id)
+{
+ struct cs4270_private *cs4270;
+ int ret;
+
+ /* Verify that we have a CS4270 */
+
+ ret = i2c_smbus_read_byte_data(i2c_client, CS4270_CHIPID);
+ if (ret < 0) {
+ dev_err(&i2c_client->dev, "failed to read i2c at addr %X\n",
+ i2c_client->addr);
+ return ret;
+ }
+ /* The top four bits of the chip ID should be 1100. */
+ if ((ret & 0xF0) != 0xC0) {
+ dev_err(&i2c_client->dev, "device at addr %X is not a CS4270\n",
+ i2c_client->addr);
+ return -ENODEV;
+ }
+
+ dev_info(&i2c_client->dev, "found device at i2c address %X\n",
+ i2c_client->addr);
+ dev_info(&i2c_client->dev, "hardware revision %X\n", ret & 0xF);
+
+ cs4270 = kzalloc(sizeof(struct cs4270_private), GFP_KERNEL);
+ if (!cs4270) {
+ dev_err(&i2c_client->dev, "could not allocate codec\n");
+ return -ENOMEM;
+ }
+
+ i2c_set_clientdata(i2c_client, cs4270);
+ cs4270->control_data = i2c_client;
+ cs4270->control_type = SND_SOC_I2C;
+
+ ret = snd_soc_register_codec(&i2c_client->dev,
+ &soc_codec_device_cs4270, &cs4270_dai, 1);
+ if (ret < 0)
+ kfree(cs4270);
+ return ret;
+}
+
+/**
+ * cs4270_i2c_remove - remove an I2C device
+ * @i2c_client: the I2C client object
+ *
+ * This function is the counterpart to cs4270_i2c_probe().
+ */
+static int cs4270_i2c_remove(struct i2c_client *i2c_client)
+{
+ snd_soc_unregister_codec(&i2c_client->dev);
+ kfree(i2c_get_clientdata(i2c_client));
+ return 0;
+}
+
+/*
+ * cs4270_id - I2C device IDs supported by this driver
+ */
+static struct i2c_device_id cs4270_id[] = {
+ {"cs4270", 0},
+ {}
+};
+MODULE_DEVICE_TABLE(i2c, cs4270_id);
+
+/*
* cs4270_i2c_driver - I2C device identification
*
* This structure tells the I2C subsystem how to identify and support a
@@ -903,7 +800,7 @@ static int cs4270_soc_resume(struct platform_device *pdev)
*/
static struct i2c_driver cs4270_i2c_driver = {
.driver = {
- .name = "cs4270",
+ .name = "cs4270-codec",
.owner = THIS_MODULE,
},
.id_table = cs4270_id,
@@ -911,20 +808,6 @@ static struct i2c_driver cs4270_i2c_driver = {
.remove = cs4270_i2c_remove,
};
-/*
- * ASoC codec device structure
- *
- * Assign this variable to the codec_dev field of the machine driver's
- * snd_soc_device structure.
- */
-struct snd_soc_codec_device soc_codec_device_cs4270 = {
- .probe = cs4270_probe,
- .remove = cs4270_remove,
- .suspend = cs4270_soc_suspend,
- .resume = cs4270_soc_resume,
-};
-EXPORT_SYMBOL_GPL(soc_codec_device_cs4270);
-
static int __init cs4270_init(void)
{
pr_info("Cirrus Logic CS4270 ALSA SoC Codec Driver\n");
diff --git a/sound/soc/codecs/cs4270.h b/sound/soc/codecs/cs4270.h
deleted file mode 100644
index adc6cd9667d4..000000000000
--- a/sound/soc/codecs/cs4270.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Cirrus Logic CS4270 ALSA SoC Codec Driver
- *
- * Author: Timur Tabi <timur@freescale.com>
- *
- * Copyright 2007 Freescale Semiconductor, Inc. This file is licensed under
- * the terms of the GNU General Public License version 2. This program
- * is licensed "as is" without any warranty of any kind, whether express
- * or implied.
- */
-
-#ifndef _CS4270_H
-#define _CS4270_H
-
-/*
- * The ASoC codec DAI structure for the CS4270. Assign this structure to
- * the .codec_dai field of your machine driver's snd_soc_dai_link structure.
- */
-extern struct snd_soc_dai cs4270_dai;
-
-/*
- * The ASoC codec device structure for the CS4270. Assign this structure
- * to the .codec_dev field of your machine driver's snd_soc_device
- * structure.
- */
-extern struct snd_soc_codec_device soc_codec_device_cs4270;
-
-#endif
diff --git a/sound/soc/codecs/cs42l51.c b/sound/soc/codecs/cs42l51.c
index dd9b8550c402..8a25743870c2 100644
--- a/sound/soc/codecs/cs42l51.c
+++ b/sound/soc/codecs/cs42l51.c
@@ -42,15 +42,14 @@ enum master_slave_mode {
};
struct cs42l51_private {
+ enum snd_soc_control_type control_type;
+ void *control_data;
unsigned int mclk;
unsigned int audio_mode; /* The mode (I2S or left-justified) */
enum master_slave_mode func;
- struct snd_soc_codec codec;
u8 reg_cache[CS42L51_NUMREGS];
};
-static struct snd_soc_codec *cs42l51_codec;
-
#define CS42L51_FORMATS ( \
SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE | \
SNDRV_PCM_FMTBIT_S18_3LE | SNDRV_PCM_FMTBIT_S18_3BE | \
@@ -75,134 +74,6 @@ static int cs42l51_fill_cache(struct snd_soc_codec *codec)
return 0;
}
-static int cs42l51_i2c_probe(struct i2c_client *i2c_client,
- const struct i2c_device_id *id)
-{
- struct snd_soc_codec *codec;
- struct cs42l51_private *cs42l51;
- int ret = 0;
- int reg;
-
- if (cs42l51_codec)
- return -EBUSY;
-
- /* Verify that we have a CS42L51 */
- ret = i2c_smbus_read_byte_data(i2c_client, CS42L51_CHIP_REV_ID);
- if (ret < 0) {
- dev_err(&i2c_client->dev, "failed to read I2C\n");
- goto error;
- }
-
- if ((ret != CS42L51_MK_CHIP_REV(CS42L51_CHIP_ID, CS42L51_CHIP_REV_A)) &&
- (ret != CS42L51_MK_CHIP_REV(CS42L51_CHIP_ID, CS42L51_CHIP_REV_B))) {
- dev_err(&i2c_client->dev, "Invalid chip id\n");
- ret = -ENODEV;
- goto error;
- }
-
- dev_info(&i2c_client->dev, "found device cs42l51 rev %d\n",
- ret & 7);
-
- cs42l51 = kzalloc(sizeof(struct cs42l51_private), GFP_KERNEL);
- if (!cs42l51) {
- dev_err(&i2c_client->dev, "could not allocate codec\n");
- return -ENOMEM;
- }
- codec = &cs42l51->codec;
-
- mutex_init(&codec->mutex);
- INIT_LIST_HEAD(&codec->dapm_widgets);
- INIT_LIST_HEAD(&codec->dapm_paths);
-
- codec->dev = &i2c_client->dev;
- codec->name = "CS42L51";
- codec->owner = THIS_MODULE;
- codec->dai = &cs42l51_dai;
- codec->num_dai = 1;
- snd_soc_codec_set_drvdata(codec, cs42l51);
-
- codec->control_data = i2c_client;
- codec->reg_cache = cs42l51->reg_cache;
- codec->reg_cache_size = CS42L51_NUMREGS;
- i2c_set_clientdata(i2c_client, codec);
-
- ret = cs42l51_fill_cache(codec);
- if (ret < 0) {
- dev_err(&i2c_client->dev, "failed to fill register cache\n");
- goto error_alloc;
- }
-
- ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C);
- if (ret < 0) {
- dev_err(&i2c_client->dev, "Failed to set cache I/O: %d\n", ret);
- goto error_alloc;
- }
-
- /*
- * DAC configuration
- * - Use signal processor
- * - auto mute
- * - vol changes immediate
- * - no de-emphasize
- */
- reg = CS42L51_DAC_CTL_DATA_SEL(1)
- | CS42L51_DAC_CTL_AMUTE | CS42L51_DAC_CTL_DACSZ(0);
- ret = snd_soc_write(codec, CS42L51_DAC_CTL, reg);
- if (ret < 0)
- goto error_alloc;
-
- cs42l51_dai.dev = codec->dev;
- cs42l51_codec = codec;
-
- ret = snd_soc_register_codec(codec);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to register codec: %d\n", ret);
- goto error_alloc;
- }
-
- ret = snd_soc_register_dai(&cs42l51_dai);
- if (ret < 0) {
- dev_err(&i2c_client->dev, "failed to register DAIe\n");
- goto error_reg;
- }
-
- return 0;
-
-error_reg:
- snd_soc_unregister_codec(codec);
-error_alloc:
- kfree(cs42l51);
-error:
- return ret;
-}
-
-static int cs42l51_i2c_remove(struct i2c_client *client)
-{
- struct cs42l51_private *cs42l51 = i2c_get_clientdata(client);
- snd_soc_unregister_dai(&cs42l51_dai);
- snd_soc_unregister_codec(cs42l51_codec);
- cs42l51_codec = NULL;
- kfree(cs42l51);
- return 0;
-}
-
-
-static const struct i2c_device_id cs42l51_id[] = {
- {"cs42l51", 0},
- {}
-};
-MODULE_DEVICE_TABLE(i2c, cs42l51_id);
-
-static struct i2c_driver cs42l51_i2c_driver = {
- .driver = {
- .name = "CS42L51 I2C",
- .owner = THIS_MODULE,
- },
- .id_table = cs42l51_id,
- .probe = cs42l51_i2c_probe,
- .remove = cs42l51_i2c_remove,
-};
-
static int cs42l51_get_chan_mix(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
@@ -484,51 +355,8 @@ static int cs42l51_set_dai_sysclk(struct snd_soc_dai *codec_dai,
{
struct snd_soc_codec *codec = codec_dai->codec;
struct cs42l51_private *cs42l51 = snd_soc_codec_get_drvdata(codec);
- struct cs42l51_ratios *ratios = NULL;
- int nr_ratios = 0;
- unsigned int rates = 0;
- unsigned int rate_min = -1;
- unsigned int rate_max = 0;
- int i;
cs42l51->mclk = freq;
-
- switch (cs42l51->func) {
- case MODE_MASTER:
- return -EINVAL;
- case MODE_SLAVE:
- ratios = slave_ratios;
- nr_ratios = ARRAY_SIZE(slave_ratios);
- break;
- case MODE_SLAVE_AUTO:
- ratios = slave_auto_ratios;
- nr_ratios = ARRAY_SIZE(slave_auto_ratios);
- break;
- }
-
- for (i = 0; i < nr_ratios; i++) {
- unsigned int rate = freq / ratios[i].ratio;
- rates |= snd_pcm_rate_to_rate_bit(rate);
- if (rate < rate_min)
- rate_min = rate;
- if (rate > rate_max)
- rate_max = rate;
- }
- rates &= ~SNDRV_PCM_RATE_KNOT;
-
- if (!rates) {
- dev_err(codec->dev, "could not find a valid sample rate\n");
- return -EINVAL;
- }
-
- codec_dai->playback.rates = rates;
- codec_dai->playback.rate_min = rate_min;
- codec_dai->playback.rate_max = rate_max;
-
- codec_dai->capture.rates = rates;
- codec_dai->capture.rate_min = rate_min;
- codec_dai->capture.rate_max = rate_max;
-
return 0;
}
@@ -537,8 +365,7 @@ static int cs42l51_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 cs42l51_private *cs42l51 = snd_soc_codec_get_drvdata(codec);
int ret;
unsigned int i;
@@ -670,8 +497,8 @@ static struct snd_soc_dai_ops cs42l51_dai_ops = {
.digital_mute = cs42l51_dai_mute,
};
-struct snd_soc_dai cs42l51_dai = {
- .name = "CS42L51 HiFi",
+static struct snd_soc_dai_driver cs42l51_dai = {
+ .name = "cs42l51-hifi",
.playback = {
.stream_name = "Playback",
.channels_min = 1,
@@ -688,30 +515,39 @@ struct snd_soc_dai cs42l51_dai = {
},
.ops = &cs42l51_dai_ops,
};
-EXPORT_SYMBOL_GPL(cs42l51_dai);
-
-static int cs42l51_probe(struct platform_device *pdev)
+static int cs42l51_probe(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec;
- int ret = 0;
+ struct cs42l51_private *cs42l51 = snd_soc_codec_get_drvdata(codec);
+ int ret, reg;
- if (!cs42l51_codec) {
- dev_err(&pdev->dev, "CS42L51 codec not yet registered\n");
- return -EINVAL;
- }
+ codec->control_data = cs42l51->control_data;
- socdev->card->codec = cs42l51_codec;
- codec = socdev->card->codec;
+ ret = cs42l51_fill_cache(codec);
+ if (ret < 0) {
+ dev_err(codec->dev, "failed to fill register cache\n");
+ return ret;
+ }
- /* Register PCMs */
- ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
+ ret = snd_soc_codec_set_cache_io(codec, 8, 8, cs42l51->control_type);
if (ret < 0) {
- dev_err(&pdev->dev, "failed to create PCMs\n");
+ dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
return ret;
}
+ /*
+ * DAC configuration
+ * - Use signal processor
+ * - auto mute
+ * - vol changes immediate
+ * - no de-emphasize
+ */
+ reg = CS42L51_DAC_CTL_DATA_SEL(1)
+ | CS42L51_DAC_CTL_AMUTE | CS42L51_DAC_CTL_DACSZ(0);
+ ret = snd_soc_write(codec, CS42L51_DAC_CTL, reg);
+ if (ret < 0)
+ return ret;
+
snd_soc_add_controls(codec, cs42l51_snd_controls,
ARRAY_SIZE(cs42l51_snd_controls));
snd_soc_dapm_new_controls(codec, cs42l51_dapm_widgets,
@@ -722,22 +558,77 @@ static int cs42l51_probe(struct platform_device *pdev)
return 0;
}
+static struct snd_soc_codec_driver soc_codec_device_cs42l51 = {
+ .probe = cs42l51_probe,
+ .reg_cache_size = CS42L51_NUMREGS,
+ .reg_word_size = sizeof(u8),
+};
-static int cs42l51_remove(struct platform_device *pdev)
+static int cs42l51_i2c_probe(struct i2c_client *i2c_client,
+ const struct i2c_device_id *id)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
+ struct cs42l51_private *cs42l51;
+ int ret;
- snd_soc_free_pcms(socdev);
- snd_soc_dapm_free(socdev);
+ /* Verify that we have a CS42L51 */
+ ret = i2c_smbus_read_byte_data(i2c_client, CS42L51_CHIP_REV_ID);
+ if (ret < 0) {
+ dev_err(&i2c_client->dev, "failed to read I2C\n");
+ goto error;
+ }
+
+ if ((ret != CS42L51_MK_CHIP_REV(CS42L51_CHIP_ID, CS42L51_CHIP_REV_A)) &&
+ (ret != CS42L51_MK_CHIP_REV(CS42L51_CHIP_ID, CS42L51_CHIP_REV_B))) {
+ dev_err(&i2c_client->dev, "Invalid chip id\n");
+ ret = -ENODEV;
+ goto error;
+ }
+
+ dev_info(&i2c_client->dev, "found device cs42l51 rev %d\n",
+ ret & 7);
+
+ cs42l51 = kzalloc(sizeof(struct cs42l51_private), GFP_KERNEL);
+ if (!cs42l51) {
+ dev_err(&i2c_client->dev, "could not allocate codec\n");
+ return -ENOMEM;
+ }
+
+ i2c_set_clientdata(i2c_client, cs42l51);
+ cs42l51->control_data = i2c_client;
+ cs42l51->control_type = SND_SOC_I2C;
+ ret = snd_soc_register_codec(&i2c_client->dev,
+ &soc_codec_device_cs42l51, &cs42l51_dai, 1);
+ if (ret < 0)
+ kfree(cs42l51);
+error:
+ return ret;
+}
+
+static int cs42l51_i2c_remove(struct i2c_client *client)
+{
+ struct cs42l51_private *cs42l51 = i2c_get_clientdata(client);
+
+ snd_soc_unregister_codec(&client->dev);
+ kfree(cs42l51);
return 0;
}
-struct snd_soc_codec_device soc_codec_device_cs42l51 = {
- .probe = cs42l51_probe,
- .remove = cs42l51_remove
+static const struct i2c_device_id cs42l51_id[] = {
+ {"cs42l51", 0},
+ {}
+};
+MODULE_DEVICE_TABLE(i2c, cs42l51_id);
+
+static struct i2c_driver cs42l51_i2c_driver = {
+ .driver = {
+ .name = "cs42L51-codec",
+ .owner = THIS_MODULE,
+ },
+ .id_table = cs42l51_id,
+ .probe = cs42l51_i2c_probe,
+ .remove = cs42l51_i2c_remove,
};
-EXPORT_SYMBOL_GPL(soc_codec_device_cs42l51);
static int __init cs42l51_init(void)
{
diff --git a/sound/soc/codecs/cs42l51.h b/sound/soc/codecs/cs42l51.h
index 8f0bd9786ad2..2beeb171db4b 100644
--- a/sound/soc/codecs/cs42l51.h
+++ b/sound/soc/codecs/cs42l51.h
@@ -158,6 +158,4 @@
#define CS42L51_LASTREG 0x20
#define CS42L51_NUMREGS (CS42L51_LASTREG - CS42L51_FIRSTREG + 1)
-extern struct snd_soc_dai cs42l51_dai;
-extern struct snd_soc_codec_device soc_codec_device_cs42l51;
#endif
diff --git a/sound/soc/codecs/cx20442.c b/sound/soc/codecs/cx20442.c
index f07a415c753f..cf4323dbf9c4 100644
--- a/sound/soc/codecs/cx20442.c
+++ b/sound/soc/codecs/cx20442.c
@@ -24,7 +24,8 @@
struct cx20442_priv {
- struct snd_soc_codec codec;
+ enum snd_soc_control_type control_type;
+ void *control_data;
u8 reg_cache[1];
};
@@ -102,7 +103,7 @@ static unsigned int cx20442_read_reg_cache(struct snd_soc_codec *codec,
{
u8 *reg_cache = codec->reg_cache;
- if (reg >= codec->reg_cache_size)
+ if (reg >= codec->driver->reg_cache_size)
return -EINVAL;
return reg_cache[reg];
@@ -164,16 +165,17 @@ static int cx20442_pm_to_v253_vsp(u8 value)
static int cx20442_write(struct snd_soc_codec *codec, unsigned int reg,
unsigned int value)
{
+ struct cx20442_priv *cx20442 = snd_soc_codec_get_drvdata(codec);
u8 *reg_cache = codec->reg_cache;
int vls, vsp, old, len;
char buf[18];
- if (reg >= codec->reg_cache_size)
+ if (reg >= codec->driver->reg_cache_size)
return -EINVAL;
/* hw_write and control_data pointers required for talking to the modem
* are expected to be set by the line discipline initialization code */
- if (!codec->hw_write || !codec->control_data)
+ if (!codec->hw_write || !cx20442->control_data)
return -EIO;
old = reg_cache[reg];
@@ -202,17 +204,13 @@ static int cx20442_write(struct snd_soc_codec *codec, unsigned int reg,
return -ENOMEM;
dev_dbg(codec->dev, "%s: %s\n", __func__, buf);
- if (codec->hw_write(codec->control_data, buf, len) != len)
+ if (codec->hw_write(cx20442->control_data, buf, len) != len)
return -EIO;
return 0;
}
-/* Moved up here as line discipline referres it during initialization */
-static struct snd_soc_codec *cx20442_codec;
-
-
/*
* Line discpline related code
*
@@ -228,15 +226,15 @@ static const char *v253_init = "ate0m0q0+fclass=8\r";
/* Line discipline .open() */
static int v253_open(struct tty_struct *tty)
{
- struct snd_soc_codec *codec = cx20442_codec;
int ret, len = strlen(v253_init);
/* Doesn't make sense without write callback */
if (!tty->ops->write)
return -EINVAL;
- /* Pass the codec structure address for use by other ldisc callbacks */
- tty->disc_data = codec;
+ /* Won't work if no codec pointer has been passed by a card driver */
+ if (!tty->disc_data)
+ return -ENODEV;
if (tty->ops->write(tty, v253_init, len) != len) {
ret = -EIO;
@@ -253,15 +251,18 @@ err:
static void v253_close(struct tty_struct *tty)
{
struct snd_soc_codec *codec = tty->disc_data;
+ struct cx20442_priv *cx20442;
tty->disc_data = NULL;
if (!codec)
return;
+ cx20442 = snd_soc_codec_get_drvdata(codec);
+
/* Prevent the codec driver from further accessing the modem */
codec->hw_write = NULL;
- codec->control_data = NULL;
+ cx20442->control_data = NULL;
codec->pop_time = 0;
}
@@ -277,15 +278,18 @@ static void v253_receive(struct tty_struct *tty,
const unsigned char *cp, char *fp, int count)
{
struct snd_soc_codec *codec = tty->disc_data;
+ struct cx20442_priv *cx20442;
if (!codec)
return;
- if (!codec->control_data) {
+ cx20442 = snd_soc_codec_get_drvdata(codec);
+
+ if (!cx20442->control_data) {
/* First modem response, complete setup procedure */
/* Set up codec driver access to modem controls */
- codec->control_data = tty;
+ cx20442->control_data = tty;
codec->hw_write = (hw_write_t)tty->ops->write;
codec->pop_time = 1;
}
@@ -313,8 +317,8 @@ EXPORT_SYMBOL_GPL(v253_ops);
* Codec DAI
*/
-struct snd_soc_dai cx20442_dai = {
- .name = "CX20442",
+static struct snd_soc_dai_driver cx20442_dai = {
+ .name = "cx20442-hifi",
.playback = {
.stream_name = "Playback",
.channels_min = 1,
@@ -330,142 +334,63 @@ struct snd_soc_dai cx20442_dai = {
.formats = SNDRV_PCM_FMTBIT_S16_LE,
},
};
-EXPORT_SYMBOL_GPL(cx20442_dai);
-static int cx20442_codec_probe(struct platform_device *pdev)
+static int cx20442_codec_probe(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec;
- int ret;
-
- if (!cx20442_codec) {
- dev_err(&pdev->dev, "cx20442 not yet discovered\n");
- return -ENODEV;
- }
- codec = cx20442_codec;
-
- socdev->card->codec = codec;
+ struct cx20442_priv *cx20442;
- /* 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");
- goto pcm_err;
- }
+ cx20442 = kzalloc(sizeof(struct cx20442_priv), GFP_KERNEL);
+ if (cx20442 == NULL)
+ return -ENOMEM;
+ snd_soc_codec_set_drvdata(codec, cx20442);
cx20442_add_widgets(codec);
-pcm_err:
- return ret;
+ cx20442->control_data = NULL;
+ codec->hw_write = NULL;
+ codec->pop_time = 0;
+
+ return 0;
}
/* power down chip */
-static int cx20442_codec_remove(struct platform_device *pdev)
+static int cx20442_codec_remove(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
+ struct cx20442_priv *cx20442 = snd_soc_codec_get_drvdata(codec);
- snd_soc_free_pcms(socdev);
- snd_soc_dapm_free(socdev);
+ if (cx20442->control_data) {
+ struct tty_struct *tty = cx20442->control_data;
+ tty_hangup(tty);
+ }
+ kfree(cx20442);
return 0;
}
-struct snd_soc_codec_device cx20442_codec_dev = {
+static struct snd_soc_codec_driver cx20442_codec_dev = {
.probe = cx20442_codec_probe,
.remove = cx20442_codec_remove,
+ .reg_cache_size = 1,
+ .reg_word_size = sizeof(u8),
+ .read = cx20442_read_reg_cache,
+ .write = cx20442_write,
};
-EXPORT_SYMBOL_GPL(cx20442_codec_dev);
-
-static int cx20442_register(struct cx20442_priv *cx20442)
-{
- struct snd_soc_codec *codec = &cx20442->codec;
- int ret;
-
- mutex_init(&codec->mutex);
- INIT_LIST_HEAD(&codec->dapm_widgets);
- INIT_LIST_HEAD(&codec->dapm_paths);
-
- codec->name = "CX20442";
- codec->owner = THIS_MODULE;
- snd_soc_codec_set_drvdata(codec, cx20442);
-
- codec->dai = &cx20442_dai;
- codec->num_dai = 1;
-
- codec->reg_cache = &cx20442->reg_cache;
- codec->reg_cache_size = ARRAY_SIZE(cx20442->reg_cache);
- codec->read = cx20442_read_reg_cache;
- codec->write = cx20442_write;
-
- codec->bias_level = SND_SOC_BIAS_OFF;
-
- cx20442_dai.dev = codec->dev;
-
- cx20442_codec = codec;
-
- ret = snd_soc_register_codec(codec);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to register codec: %d\n", ret);
- goto err;
- }
-
- ret = snd_soc_register_dai(&cx20442_dai);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
- goto err_codec;
- }
-
- return 0;
-
-err_codec:
- snd_soc_unregister_codec(codec);
-err:
- cx20442_codec = NULL;
- kfree(cx20442);
- return ret;
-}
-
-static void cx20442_unregister(struct cx20442_priv *cx20442)
-{
- snd_soc_unregister_dai(&cx20442_dai);
- snd_soc_unregister_codec(&cx20442->codec);
-
- cx20442_codec = NULL;
- kfree(cx20442);
-}
static int cx20442_platform_probe(struct platform_device *pdev)
{
- struct cx20442_priv *cx20442;
- struct snd_soc_codec *codec;
-
- cx20442 = kzalloc(sizeof(struct cx20442_priv), GFP_KERNEL);
- if (cx20442 == NULL)
- return -ENOMEM;
-
- codec = &cx20442->codec;
-
- codec->control_data = NULL;
- codec->hw_write = NULL;
- codec->pop_time = 0;
-
- codec->dev = &pdev->dev;
- platform_set_drvdata(pdev, cx20442);
-
- return cx20442_register(cx20442);
+ return snd_soc_register_codec(&pdev->dev,
+ &cx20442_codec_dev, &cx20442_dai, 1);
}
static int __exit cx20442_platform_remove(struct platform_device *pdev)
{
- struct cx20442_priv *cx20442 = platform_get_drvdata(pdev);
-
- cx20442_unregister(cx20442);
+ snd_soc_unregister_codec(&pdev->dev);
return 0;
}
static struct platform_driver cx20442_platform_driver = {
.driver = {
- .name = "cx20442",
+ .name = "cx20442-codec",
.owner = THIS_MODULE,
},
.probe = cx20442_platform_probe,
@@ -487,4 +412,4 @@ module_exit(cx20442_exit);
MODULE_DESCRIPTION("ASoC CX20442-11 voice modem codec driver");
MODULE_AUTHOR("Janusz Krzysztofik");
MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:cx20442");
+MODULE_ALIAS("platform:cx20442-codec");
diff --git a/sound/soc/codecs/cx20442.h b/sound/soc/codecs/cx20442.h
index 688a5eb62e17..c7a7c79ef0cd 100644
--- a/sound/soc/codecs/cx20442.h
+++ b/sound/soc/codecs/cx20442.h
@@ -13,8 +13,6 @@
#ifndef _CX20442_CODEC_H
#define _CX20442_CODEC_H
-extern struct snd_soc_dai cx20442_dai;
-extern struct snd_soc_codec_device cx20442_codec_dev;
extern struct tty_ldisc_ops v253_ops;
#endif
diff --git a/sound/soc/codecs/da7210.c b/sound/soc/codecs/da7210.c
index 3c51d6a57523..eabf3c062500 100644
--- a/sound/soc/codecs/da7210.c
+++ b/sound/soc/codecs/da7210.c
@@ -25,8 +25,6 @@
#include <sound/initval.h>
#include <sound/tlv.h>
-#include "da7210.h"
-
/* DA7210 register space */
#define DA7210_STATUS 0x02
#define DA7210_STARTUP1 0x03
@@ -162,11 +160,10 @@ static const struct snd_kcontrol_new da7210_snd_controls[] = {
/* Codec private data */
struct da7210_priv {
- struct snd_soc_codec codec;
+ enum snd_soc_control_type control_type;
+ void *control_data;
};
-static struct snd_soc_codec *da7210_codec;
-
/*
* Register cache
*/
@@ -209,12 +206,12 @@ static int da7210_write(struct snd_soc_codec *codec, u32 reg, u32 value)
u8 *cache = codec->reg_cache;
u8 data[2];
- BUG_ON(codec->volatile_register);
+ BUG_ON(codec->driver->volatile_register);
data[0] = reg & 0xff;
data[1] = value & 0xff;
- if (reg >= codec->reg_cache_size)
+ if (reg >= codec->driver->reg_cache_size)
return -EIO;
if (2 != codec->hw_write(codec->control_data, data, 2))
@@ -267,8 +264,7 @@ static int da7210_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;
u32 dai_cfg1;
u32 hpf_reg, hpf_mask, hpf_value;
u32 fs, bypass;
@@ -430,9 +426,8 @@ static struct snd_soc_dai_ops da7210_dai_ops = {
.set_fmt = da7210_set_dai_fmt,
};
-struct snd_soc_dai da7210_dai = {
- .name = "DA7210 IIS",
- .id = 0,
+static struct snd_soc_dai_driver da7210_dai = {
+ .name = "da7210-hifi",
/* playback capabilities */
.playback = {
.stream_name = "Playback",
@@ -452,55 +447,15 @@ struct snd_soc_dai da7210_dai = {
.ops = &da7210_dai_ops,
.symmetric_rates = 1,
};
-EXPORT_SYMBOL_GPL(da7210_dai);
-/*
- * Initialize the DA7210 driver
- * register the mixer and dsp interfaces with the kernel
- */
-static int da7210_init(struct da7210_priv *da7210)
+static int da7210_probe(struct snd_soc_codec *codec)
{
- struct snd_soc_codec *codec = &da7210->codec;
- int ret = 0;
+ struct da7210_priv *da7210 = snd_soc_codec_get_drvdata(codec);
- if (da7210_codec) {
- dev_err(codec->dev, "Another da7210 is registered\n");
- return -EINVAL;
- }
+ dev_info(codec->dev, "DA7210 Audio Codec %s\n", DA7210_VERSION);
- mutex_init(&codec->mutex);
- INIT_LIST_HEAD(&codec->dapm_widgets);
- INIT_LIST_HEAD(&codec->dapm_paths);
-
- snd_soc_codec_set_drvdata(codec, da7210);
- codec->name = "DA7210";
- codec->owner = THIS_MODULE;
- codec->read = da7210_read;
- codec->write = da7210_write;
- codec->dai = &da7210_dai;
- codec->num_dai = 1;
+ codec->control_data = da7210->control_data;
codec->hw_write = (hw_write_t)i2c_master_send;
- codec->reg_cache_size = ARRAY_SIZE(da7210_reg);
- codec->reg_cache = kmemdup(da7210_reg,
- sizeof(da7210_reg), GFP_KERNEL);
-
- if (!codec->reg_cache)
- return -ENOMEM;
-
- da7210_dai.dev = codec->dev;
- da7210_codec = codec;
-
- ret = snd_soc_register_codec(codec);
- if (ret) {
- dev_err(codec->dev, "Failed to register CODEC: %d\n", ret);
- goto init_err;
- }
-
- ret = snd_soc_register_dai(&da7210_dai);
- if (ret) {
- dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
- goto codec_err;
- }
/* FIXME
*
@@ -583,54 +538,50 @@ static int da7210_init(struct da7210_priv *da7210)
/* Activate all enabled subsystem */
da7210_write(codec, DA7210_STARTUP1, DA7210_SC_MST_EN);
- return ret;
-
-codec_err:
- snd_soc_unregister_codec(codec);
-init_err:
- kfree(codec->reg_cache);
- codec->reg_cache = NULL;
+ snd_soc_add_controls(codec, da7210_snd_controls,
+ ARRAY_SIZE(da7210_snd_controls));
- return ret;
+ dev_info(codec->dev, "DA7210 Audio Codec %s\n", DA7210_VERSION);
+ return 0;
}
+static struct snd_soc_codec_driver soc_codec_dev_da7210 = {
+ .probe = da7210_probe,
+ .read = da7210_read,
+ .write = da7210_write,
+ .reg_cache_size = ARRAY_SIZE(da7210_reg),
+ .reg_word_size = sizeof(u8),
+ .reg_cache_default = da7210_reg,
+};
+
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
static int __devinit da7210_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
struct da7210_priv *da7210;
- struct snd_soc_codec *codec;
int ret;
da7210 = kzalloc(sizeof(struct da7210_priv), GFP_KERNEL);
if (!da7210)
return -ENOMEM;
- codec = &da7210->codec;
- codec->dev = &i2c->dev;
-
i2c_set_clientdata(i2c, da7210);
- codec->control_data = i2c;
+ da7210->control_data = i2c;
+ da7210->control_type = SND_SOC_I2C;
- ret = da7210_init(da7210);
- if (ret < 0) {
- pr_err("Failed to initialise da7210 audio codec\n");
+ ret = snd_soc_register_codec(&i2c->dev,
+ &soc_codec_dev_da7210, &da7210_dai, 1);
+ if (ret < 0)
kfree(da7210);
- }
return ret;
}
static int __devexit da7210_i2c_remove(struct i2c_client *client)
{
- struct da7210_priv *da7210 = i2c_get_clientdata(client);
-
- snd_soc_unregister_dai(&da7210_dai);
- kfree(da7210->codec.reg_cache);
- kfree(da7210);
- da7210_codec = NULL;
-
+ snd_soc_unregister_codec(&client->dev);
+ kfree(i2c_get_clientdata(client));
return 0;
}
@@ -643,7 +594,7 @@ MODULE_DEVICE_TABLE(i2c, da7210_i2c_id);
/* I2C codec control layer */
static struct i2c_driver da7210_i2c_driver = {
.driver = {
- .name = "DA7210 I2C Codec",
+ .name = "da7210-codec",
.owner = THIS_MODULE,
},
.probe = da7210_i2c_probe,
@@ -652,50 +603,6 @@ static struct i2c_driver da7210_i2c_driver = {
};
#endif
-static int da7210_probe(struct platform_device *pdev)
-{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec;
- int ret;
-
- if (!da7210_codec) {
- dev_err(&pdev->dev, "Codec device not registered\n");
- return -ENODEV;
- }
-
- socdev->card->codec = da7210_codec;
- codec = da7210_codec;
-
- /* Register pcms */
- ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
- if (ret < 0)
- goto pcm_err;
-
- snd_soc_add_controls(da7210_codec, da7210_snd_controls,
- ARRAY_SIZE(da7210_snd_controls));
-
- dev_info(&pdev->dev, "DA7210 Audio Codec %s\n", DA7210_VERSION);
-
-pcm_err:
- return ret;
-}
-
-static int da7210_remove(struct platform_device *pdev)
-{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
-
- snd_soc_free_pcms(socdev);
- snd_soc_dapm_free(socdev);
-
- return 0;
-}
-
-struct snd_soc_codec_device soc_codec_dev_da7210 = {
- .probe = da7210_probe,
- .remove = da7210_remove,
-};
-EXPORT_SYMBOL_GPL(soc_codec_dev_da7210);
-
static int __init da7210_modinit(void)
{
int ret = 0;
diff --git a/sound/soc/codecs/da7210.h b/sound/soc/codecs/da7210.h
deleted file mode 100644
index 390d621eb742..000000000000
--- a/sound/soc/codecs/da7210.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * da7210.h -- audio driver for da7210
- *
- * Copyright (c) 2009 Dialog Semiconductor
- * Written by David Chen <Dajun.chen@diasemi.com>
- *
- * Copyright (C) 2009 Renesas Solutions Corp.
- * Cleanups by Kuninori Morimoto <morimoto.kuninori@renesas.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.
- *
- */
-
-#ifndef _DA7210_H
-#define _DA7210_H
-
-extern struct snd_soc_dai da7210_dai;
-extern struct snd_soc_codec_device soc_codec_dev_da7210;
-
-#endif
-
diff --git a/sound/soc/codecs/jz4740.c b/sound/soc/codecs/jz4740.c
index 66557de1e4fe..16253ec9b022 100644
--- a/sound/soc/codecs/jz4740.c
+++ b/sound/soc/codecs/jz4740.c
@@ -74,29 +74,22 @@ static const uint32_t jz4740_codec_regs[] = {
struct jz4740_codec {
void __iomem *base;
struct resource *mem;
-
- uint32_t reg_cache[2];
- struct snd_soc_codec codec;
};
-static inline struct jz4740_codec *codec_to_jz4740(struct snd_soc_codec *codec)
-{
- return container_of(codec, struct jz4740_codec, codec);
-}
-
static unsigned int jz4740_codec_read(struct snd_soc_codec *codec,
unsigned int reg)
{
- struct jz4740_codec *jz4740_codec = codec_to_jz4740(codec);
+ struct jz4740_codec *jz4740_codec = snd_soc_codec_get_drvdata(codec);
return readl(jz4740_codec->base + (reg << 2));
}
static int jz4740_codec_write(struct snd_soc_codec *codec, unsigned int reg,
unsigned int val)
{
- struct jz4740_codec *jz4740_codec = codec_to_jz4740(codec);
+ struct jz4740_codec *jz4740_codec = snd_soc_codec_get_drvdata(codec);
+ u32 *cache = codec->reg_cache;
- jz4740_codec->reg_cache[reg] = val;
+ cache[reg] = val;
writel(val, jz4740_codec->base + (reg << 2));
return 0;
@@ -172,8 +165,7 @@ static int jz4740_codec_hw_params(struct snd_pcm_substream *substream,
{
uint32_t val;
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;
switch (params_rate(params)) {
case 8000:
@@ -219,8 +211,8 @@ static struct snd_soc_dai_ops jz4740_codec_dai_ops = {
.hw_params = jz4740_codec_hw_params,
};
-struct snd_soc_dai jz4740_codec_dai = {
- .name = "jz4740",
+static struct snd_soc_dai_driver jz4740_codec_dai = {
+ .name = "jz4740-hifi",
.playback = {
.stream_name = "Playback",
.channels_min = 2,
@@ -238,7 +230,6 @@ struct snd_soc_dai jz4740_codec_dai = {
.ops = &jz4740_codec_dai_ops,
.symmetric_rates = 1,
};
-EXPORT_SYMBOL_GPL(jz4740_codec_dai);
static void jz4740_codec_wakeup(struct snd_soc_codec *codec)
{
@@ -302,23 +293,10 @@ static int jz4740_codec_set_bias_level(struct snd_soc_codec *codec,
return 0;
}
-static struct snd_soc_codec *jz4740_codec_codec;
-
-static int jz4740_codec_dev_probe(struct platform_device *pdev)
+static int jz4740_codec_dev_probe(struct snd_soc_codec *codec)
{
- int ret;
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec = jz4740_codec_codec;
-
- BUG_ON(!codec);
-
- socdev->card->codec = codec;
-
- ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
- if (ret) {
- dev_err(&pdev->dev, "Failed to create pcms: %d\n", ret);
- return ret;
- }
+ snd_soc_update_bits(codec, JZ4740_REG_CODEC_1,
+ JZ4740_CODEC_1_SW2_ENABLE, JZ4740_CODEC_1_SW2_ENABLE);
snd_soc_add_controls(codec, jz4740_codec_controls,
ARRAY_SIZE(jz4740_codec_controls));
@@ -331,34 +309,27 @@ static int jz4740_codec_dev_probe(struct platform_device *pdev)
snd_soc_dapm_new_widgets(codec);
+ jz4740_codec_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+
return 0;
}
-static int jz4740_codec_dev_remove(struct platform_device *pdev)
+static int jz4740_codec_dev_remove(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
-
- snd_soc_free_pcms(socdev);
- snd_soc_dapm_free(socdev);
+ jz4740_codec_set_bias_level(codec, SND_SOC_BIAS_OFF);
return 0;
}
#ifdef CONFIG_PM_SLEEP
-static int jz4740_codec_suspend(struct platform_device *pdev, pm_message_t state)
+static int jz4740_codec_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;
-
return jz4740_codec_set_bias_level(codec, SND_SOC_BIAS_OFF);
}
-static int jz4740_codec_resume(struct platform_device *pdev)
+static int jz4740_codec_resume(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec = socdev->card->codec;
-
return jz4740_codec_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
}
@@ -367,19 +338,23 @@ static int jz4740_codec_resume(struct platform_device *pdev)
#define jz4740_codec_resume NULL
#endif
-struct snd_soc_codec_device soc_codec_dev_jz4740_codec = {
+static struct snd_soc_codec_driver soc_codec_dev_jz4740_codec = {
.probe = jz4740_codec_dev_probe,
.remove = jz4740_codec_dev_remove,
.suspend = jz4740_codec_suspend,
.resume = jz4740_codec_resume,
+ .read = jz4740_codec_read,
+ .write = jz4740_codec_write,
+ .set_bias_level = jz4740_codec_set_bias_level,
+ .reg_cache_default = jz4740_codec_regs,
+ .reg_word_size = sizeof(u32),
+ .reg_cache_size = 2,
};
-EXPORT_SYMBOL_GPL(soc_codec_dev_jz4740_codec);
static int __devinit jz4740_codec_probe(struct platform_device *pdev)
{
int ret;
struct jz4740_codec *jz4740_codec;
- struct snd_soc_codec *codec;
struct resource *mem;
jz4740_codec = kzalloc(sizeof(*jz4740_codec), GFP_KERNEL);
@@ -408,55 +383,17 @@ static int __devinit jz4740_codec_probe(struct platform_device *pdev)
}
jz4740_codec->mem = mem;
- jz4740_codec_dai.dev = &pdev->dev;
-
- codec = &jz4740_codec->codec;
-
- codec->dev = &pdev->dev;
- codec->name = "jz4740";
- codec->owner = THIS_MODULE;
-
- codec->read = jz4740_codec_read;
- codec->write = jz4740_codec_write;
- codec->set_bias_level = jz4740_codec_set_bias_level;
- codec->bias_level = SND_SOC_BIAS_OFF;
-
- codec->dai = &jz4740_codec_dai;
- codec->num_dai = 1;
-
- codec->reg_cache = jz4740_codec->reg_cache;
- codec->reg_cache_size = 2;
- memcpy(codec->reg_cache, jz4740_codec_regs, sizeof(jz4740_codec_regs));
-
- mutex_init(&codec->mutex);
- INIT_LIST_HEAD(&codec->dapm_widgets);
- INIT_LIST_HEAD(&codec->dapm_paths);
-
- jz4740_codec_codec = codec;
-
- snd_soc_update_bits(codec, JZ4740_REG_CODEC_1,
- JZ4740_CODEC_1_SW2_ENABLE, JZ4740_CODEC_1_SW2_ENABLE);
-
platform_set_drvdata(pdev, jz4740_codec);
- ret = snd_soc_register_codec(codec);
+ ret = snd_soc_register_codec(&pdev->dev,
+ &soc_codec_dev_jz4740_codec, &jz4740_codec_dai, 1);
if (ret) {
dev_err(&pdev->dev, "Failed to register codec\n");
goto err_iounmap;
}
- ret = snd_soc_register_dai(&jz4740_codec_dai);
- if (ret) {
- dev_err(&pdev->dev, "Failed to register codec dai\n");
- goto err_unregister_codec;
- }
-
- jz4740_codec_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
return 0;
-err_unregister_codec:
- snd_soc_unregister_codec(codec);
err_iounmap:
iounmap(jz4740_codec->base);
err_release_mem_region:
@@ -472,8 +409,7 @@ static int __devexit jz4740_codec_remove(struct platform_device *pdev)
struct jz4740_codec *jz4740_codec = platform_get_drvdata(pdev);
struct resource *mem = jz4740_codec->mem;
- snd_soc_unregister_dai(&jz4740_codec_dai);
- snd_soc_unregister_codec(&jz4740_codec->codec);
+ snd_soc_unregister_codec(&pdev->dev);
iounmap(jz4740_codec->base);
release_mem_region(mem->start, resource_size(mem));
diff --git a/sound/soc/codecs/jz4740.h b/sound/soc/codecs/jz4740.h
deleted file mode 100644
index b5a0691be763..000000000000
--- a/sound/soc/codecs/jz4740.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright (C) 2009, Lars-Peter Clausen <lars@metafoo.de>
- *
- * 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.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#ifndef __SND_SOC_CODECS_JZ4740_CODEC_H__
-#define __SND_SOC_CODECS_JZ4740_CODEC_H__
-
-extern struct snd_soc_dai jz4740_codec_dai;
-extern struct snd_soc_codec_device soc_codec_dev_jz4740_codec;
-
-#endif
diff --git a/sound/soc/codecs/pcm3008.c b/sound/soc/codecs/pcm3008.c
index 5a5f187a2657..bd8f26e41602 100644
--- a/sound/soc/codecs/pcm3008.c
+++ b/sound/soc/codecs/pcm3008.c
@@ -32,8 +32,8 @@
#define PCM3008_RATES (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \
SNDRV_PCM_RATE_48000)
-struct snd_soc_dai pcm3008_dai = {
- .name = "PCM3008 HiFi",
+static struct snd_soc_dai_driver pcm3008_dai = {
+ .name = "pcm3008-hifi",
.playback = {
.stream_name = "PCM3008 Playback",
.channels_min = 1,
@@ -49,7 +49,6 @@ struct snd_soc_dai pcm3008_dai = {
.formats = SNDRV_PCM_FMTBIT_S16_LE,
},
};
-EXPORT_SYMBOL_GPL(pcm3008_dai);
static void pcm3008_gpio_free(struct pcm3008_setup_data *setup)
{
@@ -59,38 +58,13 @@ static void pcm3008_gpio_free(struct pcm3008_setup_data *setup)
gpio_free(setup->pdda_pin);
}
-static int pcm3008_soc_probe(struct platform_device *pdev)
+static int pcm3008_soc_probe(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec;
- struct pcm3008_setup_data *setup = socdev->codec_data;
+ struct pcm3008_setup_data *setup = codec->dev->platform_data;
int ret = 0;
printk(KERN_INFO "PCM3008 SoC Audio Codec %s\n", PCM3008_VERSION);
- socdev->card->codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
- if (!socdev->card->codec)
- return -ENOMEM;
-
- codec = socdev->card->codec;
- mutex_init(&codec->mutex);
-
- codec->name = "PCM3008";
- codec->owner = THIS_MODULE;
- codec->dai = &pcm3008_dai;
- codec->num_dai = 1;
- codec->write = NULL;
- codec->read = NULL;
- INIT_LIST_HEAD(&codec->dapm_widgets);
- INIT_LIST_HEAD(&codec->dapm_paths);
-
- /* Register PCMs. */
- ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
- if (ret < 0) {
- printk(KERN_ERR "pcm3008: failed to create pcms\n");
- goto pcm_err;
- }
-
/* DEM1 DEM0 DE-EMPHASIS_MODE
* Low Low De-emphasis 44.1 kHz ON
* Low High De-emphasis OFF
@@ -130,33 +104,22 @@ static int pcm3008_soc_probe(struct platform_device *pdev)
gpio_err:
pcm3008_gpio_free(setup);
-pcm_err:
- kfree(socdev->card->codec);
return ret;
}
-static int pcm3008_soc_remove(struct platform_device *pdev)
+static int pcm3008_soc_remove(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec = socdev->card->codec;
- struct pcm3008_setup_data *setup = socdev->codec_data;
-
- if (!codec)
- return 0;
+ struct pcm3008_setup_data *setup = codec->dev->platform_data;
pcm3008_gpio_free(setup);
- snd_soc_free_pcms(socdev);
- kfree(socdev->card->codec);
-
return 0;
}
#ifdef CONFIG_PM
-static int pcm3008_soc_suspend(struct platform_device *pdev, pm_message_t msg)
+static int pcm3008_soc_suspend(struct snd_soc_codec *codec, pm_message_t msg)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct pcm3008_setup_data *setup = socdev->codec_data;
+ struct pcm3008_setup_data *setup = codec->dev->platform_data;
gpio_set_value(setup->pdad_pin, 0);
gpio_set_value(setup->pdda_pin, 0);
@@ -164,10 +127,9 @@ static int pcm3008_soc_suspend(struct platform_device *pdev, pm_message_t msg)
return 0;
}
-static int pcm3008_soc_resume(struct platform_device *pdev)
+static int pcm3008_soc_resume(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct pcm3008_setup_data *setup = socdev->codec_data;
+ struct pcm3008_setup_data *setup = codec->dev->platform_data;
gpio_set_value(setup->pdad_pin, 1);
gpio_set_value(setup->pdda_pin, 1);
@@ -179,23 +141,45 @@ static int pcm3008_soc_resume(struct platform_device *pdev)
#define pcm3008_soc_resume NULL
#endif
-struct snd_soc_codec_device soc_codec_dev_pcm3008 = {
+static struct snd_soc_codec_driver soc_codec_dev_pcm3008 = {
.probe = pcm3008_soc_probe,
.remove = pcm3008_soc_remove,
.suspend = pcm3008_soc_suspend,
.resume = pcm3008_soc_resume,
};
-EXPORT_SYMBOL_GPL(soc_codec_dev_pcm3008);
-static int __init pcm3008_init(void)
+static int __devinit pcm3008_codec_probe(struct platform_device *pdev)
+{
+ return snd_soc_register_codec(&pdev->dev,
+ &soc_codec_dev_pcm3008, &pcm3008_dai, 1);
+}
+
+static int __devexit pcm3008_codec_remove(struct platform_device *pdev)
+{
+ snd_soc_unregister_codec(&pdev->dev);
+ return 0;
+}
+
+MODULE_ALIAS("platform:pcm3008-codec");
+
+static struct platform_driver pcm3008_codec_driver = {
+ .probe = pcm3008_codec_probe,
+ .remove = __devexit_p(pcm3008_codec_remove),
+ .driver = {
+ .name = "pcm3008-codec",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init pcm3008_modinit(void)
{
- return snd_soc_register_dai(&pcm3008_dai);
+ return platform_driver_register(&pcm3008_codec_driver);
}
-module_init(pcm3008_init);
+module_init(pcm3008_modinit);
static void __exit pcm3008_exit(void)
{
- snd_soc_unregister_dai(&pcm3008_dai);
+ platform_driver_unregister(&pcm3008_codec_driver);
}
module_exit(pcm3008_exit);
diff --git a/sound/soc/codecs/pcm3008.h b/sound/soc/codecs/pcm3008.h
index d04e87d3c060..7e5489ab4812 100644
--- a/sound/soc/codecs/pcm3008.h
+++ b/sound/soc/codecs/pcm3008.h
@@ -19,7 +19,4 @@ struct pcm3008_setup_data {
unsigned pdda_pin;
};
-extern struct snd_soc_codec_device soc_codec_dev_pcm3008;
-extern struct snd_soc_dai pcm3008_dai;
-
#endif
diff --git a/sound/soc/codecs/spdif_transciever.c b/sound/soc/codecs/spdif_transciever.c
index 9119836051a4..4c32b54913ad 100644
--- a/sound/soc/codecs/spdif_transciever.c
+++ b/sound/soc/codecs/spdif_transciever.c
@@ -21,57 +21,16 @@
#include <sound/pcm.h>
#include <sound/initval.h>
-#include "spdif_transciever.h"
-
MODULE_LICENSE("GPL");
#define STUB_RATES SNDRV_PCM_RATE_8000_96000
#define STUB_FORMATS SNDRV_PCM_FMTBIT_S16_LE
-static struct snd_soc_codec *spdif_dit_codec;
-
-static int spdif_dit_codec_probe(struct platform_device *pdev)
-{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec;
- int ret;
-
- if (spdif_dit_codec == NULL) {
- dev_err(&pdev->dev, "Codec device not registered\n");
- return -ENODEV;
- }
-
- socdev->card->codec = spdif_dit_codec;
- codec = spdif_dit_codec;
-
- ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
- if (ret < 0) {
- dev_err(codec->dev, "failed to create pcms: %d\n", ret);
- goto err_create_pcms;
- }
-
- return 0;
-
-err_create_pcms:
- return ret;
-}
-
-static int spdif_dit_codec_remove(struct platform_device *pdev)
-{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
-
- snd_soc_free_pcms(socdev);
-
- return 0;
-}
-struct snd_soc_codec_device soc_codec_dev_spdif_dit = {
- .probe = spdif_dit_codec_probe,
- .remove = spdif_dit_codec_remove,
-}; EXPORT_SYMBOL_GPL(soc_codec_dev_spdif_dit);
+static struct snd_soc_codec_driver soc_codec_spdif_dit;
-struct snd_soc_dai dit_stub_dai = {
- .name = "DIT",
+static struct snd_soc_dai_driver dit_stub_dai = {
+ .name = "dit-hifi",
.playback = {
.stream_name = "Playback",
.channels_min = 1,
@@ -80,65 +39,16 @@ struct snd_soc_dai dit_stub_dai = {
.formats = STUB_FORMATS,
},
};
-EXPORT_SYMBOL_GPL(dit_stub_dai);
static int spdif_dit_probe(struct platform_device *pdev)
{
- struct snd_soc_codec *codec;
- int ret;
-
- if (spdif_dit_codec) {
- dev_err(&pdev->dev, "Another Codec is registered\n");
- ret = -EINVAL;
- goto err_reg_codec;
- }
-
- codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
- if (codec == NULL)
- return -ENOMEM;
-
- codec->dev = &pdev->dev;
-
- mutex_init(&codec->mutex);
-
- INIT_LIST_HEAD(&codec->dapm_widgets);
- INIT_LIST_HEAD(&codec->dapm_paths);
-
- codec->name = "spdif-dit";
- codec->owner = THIS_MODULE;
- codec->dai = &dit_stub_dai;
- codec->num_dai = 1;
-
- spdif_dit_codec = codec;
-
- ret = snd_soc_register_codec(codec);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to register codec: %d\n", ret);
- goto err_reg_codec;
- }
-
- dit_stub_dai.dev = &pdev->dev;
- ret = snd_soc_register_dai(&dit_stub_dai);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to register dai: %d\n", ret);
- goto err_reg_dai;
- }
-
- return 0;
-
-err_reg_dai:
- snd_soc_unregister_codec(codec);
-err_reg_codec:
- kfree(spdif_dit_codec);
- return ret;
+ return snd_soc_register_codec(&pdev->dev, &soc_codec_spdif_dit,
+ &dit_stub_dai, 1);
}
static int spdif_dit_remove(struct platform_device *pdev)
{
- snd_soc_unregister_dai(&dit_stub_dai);
- snd_soc_unregister_codec(spdif_dit_codec);
- kfree(spdif_dit_codec);
- spdif_dit_codec = NULL;
+ snd_soc_unregister_codec(&pdev->dev);
return 0;
}
diff --git a/sound/soc/codecs/spdif_transciever.h b/sound/soc/codecs/spdif_transciever.h
deleted file mode 100644
index 1e102124f546..000000000000
--- a/sound/soc/codecs/spdif_transciever.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * ALSA SoC DIT/DIR driver header
- *
- * Author: Steve Chen, <schen@mvista.com>
- * Copyright: (C) 2008 MontaVista Software, Inc., <source@mvista.com>
- *
- * 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 CODEC_STUBS_H
-#define CODEC_STUBS_H
-
-extern struct snd_soc_codec_device soc_codec_dev_spdif_dit;
-extern struct snd_soc_dai dit_stub_dai;
-
-#endif /* CODEC_STUBS_H */
diff --git a/sound/soc/codecs/ssm2602.c b/sound/soc/codecs/ssm2602.c
index b47ed4f6ab20..67d8c044ca04 100644
--- a/sound/soc/codecs/ssm2602.c
+++ b/sound/soc/codecs/ssm2602.c
@@ -45,11 +45,11 @@
#define SSM2602_VERSION "0.1"
-struct snd_soc_codec_device soc_codec_dev_ssm2602;
-
/* codec private data */
struct ssm2602_priv {
unsigned int sysclk;
+ enum snd_soc_control_type control_type;
+ void *control_data;
struct snd_pcm_substream *master_substream;
struct snd_pcm_substream *slave_substream;
};
@@ -276,8 +276,7 @@ static int ssm2602_hw_params(struct snd_pcm_substream *substream,
{
u16 srate;
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 ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec);
struct i2c_client *i2c = codec->control_data;
u16 iface = ssm2602_read_reg_cache(codec, SSM2602_IFACE) & 0xfff3;
@@ -321,8 +320,7 @@ static int ssm2602_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 ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec);
struct i2c_client *i2c = codec->control_data;
struct snd_pcm_runtime *master_runtime;
@@ -360,8 +358,7 @@ static int ssm2602_pcm_prepare(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;
/* set active */
ssm2602_write(codec, SSM2602_ACTIVE, ACTIVE_ACTIVATE_CODEC);
@@ -372,8 +369,7 @@ static void ssm2602_shutdown(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 ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec);
/* deactivate */
@@ -518,8 +514,8 @@ static struct snd_soc_dai_ops ssm2602_dai_ops = {
.set_fmt = ssm2602_set_dai_fmt,
};
-struct snd_soc_dai ssm2602_dai = {
- .name = "SSM2602",
+static struct snd_soc_dai_driver ssm2602_dai = {
+ .name = "ssm2602-hifi",
.playback = {
.stream_name = "Playback",
.channels_min = 2,
@@ -534,21 +530,15 @@ struct snd_soc_dai ssm2602_dai = {
.formats = SSM2602_FORMATS,},
.ops = &ssm2602_dai_ops,
};
-EXPORT_SYMBOL_GPL(ssm2602_dai);
-static int ssm2602_suspend(struct platform_device *pdev, pm_message_t state)
+static int ssm2602_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;
-
ssm2602_set_bias_level(codec, SND_SOC_BIAS_OFF);
return 0;
}
-static int ssm2602_resume(struct platform_device *pdev)
+static int ssm2602_resume(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec = socdev->card->codec;
int i;
u8 data[2];
u16 *cache = codec->reg_cache;
@@ -563,36 +553,18 @@ static int ssm2602_resume(struct platform_device *pdev)
return 0;
}
-/*
- * initialise the ssm2602 driver
- * register the mixer and dsp interfaces with the kernel
- */
-static int ssm2602_init(struct snd_soc_device *socdev)
+static int ssm2602_probe(struct snd_soc_codec *codec)
{
- struct snd_soc_codec *codec = socdev->card->codec;
- int reg, ret = 0;
-
- codec->name = "SSM2602";
- codec->owner = THIS_MODULE;
- codec->read = ssm2602_read_reg_cache;
- codec->write = ssm2602_write;
- codec->set_bias_level = ssm2602_set_bias_level;
- codec->dai = &ssm2602_dai;
- codec->num_dai = 1;
- codec->reg_cache_size = sizeof(ssm2602_reg);
- codec->reg_cache = kmemdup(ssm2602_reg, sizeof(ssm2602_reg),
- GFP_KERNEL);
- if (codec->reg_cache == NULL)
- return -ENOMEM;
+ struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec);
+ int ret = 0, reg;
+
+ pr_info("ssm2602 Audio Codec %s", SSM2602_VERSION);
+
+ codec->bias_level = SND_SOC_BIAS_OFF,
+ codec->control_data = ssm2602->control_data;
ssm2602_reset(codec);
- /* register pcms */
- ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
- if (ret < 0) {
- pr_err("ssm2602: failed to create pcms\n");
- goto pcm_err;
- }
/*power on device*/
ssm2602_write(codec, SSM2602_ACTIVE, 0);
/* set the update bits */
@@ -614,13 +586,27 @@ static int ssm2602_init(struct snd_soc_device *socdev)
ssm2602_add_widgets(codec);
return ret;
+}
-pcm_err:
- kfree(codec->reg_cache);
- return ret;
+/* remove everything here */
+static int ssm2602_remove(struct snd_soc_codec *codec)
+{
+ ssm2602_set_bias_level(codec, SND_SOC_BIAS_OFF);
+ return 0;
}
-static struct snd_soc_device *ssm2602_socdev;
+static struct snd_soc_codec_driver soc_codec_dev_ssm2602 = {
+ .probe = ssm2602_probe,
+ .remove = ssm2602_remove,
+ .suspend = ssm2602_suspend,
+ .resume = ssm2602_resume,
+ .read = ssm2602_read_reg_cache,
+ .write = ssm2602_write,
+ .set_bias_level = ssm2602_set_bias_level,
+ .reg_cache_size = sizeof(ssm2602_reg),
+ .reg_word_size = sizeof(u16),
+ .reg_cache_default = ssm2602_reg,
+};
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
/*
@@ -632,24 +618,28 @@ static struct snd_soc_device *ssm2602_socdev;
static int ssm2602_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
- struct snd_soc_device *socdev = ssm2602_socdev;
- struct snd_soc_codec *codec = socdev->card->codec;
+ struct ssm2602_priv *ssm2602;
int ret;
- i2c_set_clientdata(i2c, codec);
- codec->control_data = i2c;
+ ssm2602 = kzalloc(sizeof(struct ssm2602_priv), GFP_KERNEL);
+ if (ssm2602 == NULL)
+ return -ENOMEM;
- ret = ssm2602_init(socdev);
- if (ret < 0)
- pr_err("failed to initialise SSM2602\n");
+ i2c_set_clientdata(i2c, ssm2602);
+ ssm2602->control_data = i2c;
+ ssm2602->control_type = SND_SOC_I2C;
+ ret = snd_soc_register_codec(&i2c->dev,
+ &soc_codec_dev_ssm2602, &ssm2602_dai, 1);
+ if (ret < 0)
+ kfree(ssm2602);
return ret;
}
static int ssm2602_i2c_remove(struct i2c_client *client)
{
- struct snd_soc_codec *codec = i2c_get_clientdata(client);
- kfree(codec->reg_cache);
+ snd_soc_unregister_codec(&client->dev);
+ kfree(i2c_get_clientdata(client));
return 0;
}
@@ -658,130 +648,39 @@ static const struct i2c_device_id ssm2602_i2c_id[] = {
{ }
};
MODULE_DEVICE_TABLE(i2c, ssm2602_i2c_id);
+
/* corgi i2c codec control layer */
static struct i2c_driver ssm2602_i2c_driver = {
.driver = {
- .name = "SSM2602 I2C Codec",
+ .name = "ssm2602-codec",
.owner = THIS_MODULE,
},
.probe = ssm2602_i2c_probe,
.remove = ssm2602_i2c_remove,
.id_table = ssm2602_i2c_id,
};
-
-static int ssm2602_add_i2c_device(struct platform_device *pdev,
- const struct ssm2602_setup_data *setup)
-{
- struct i2c_board_info info;
- struct i2c_adapter *adapter;
- struct i2c_client *client;
- int ret;
-
- ret = i2c_add_driver(&ssm2602_i2c_driver);
- if (ret != 0) {
- dev_err(&pdev->dev, "can't add i2c driver\n");
- return ret;
- }
- memset(&info, 0, sizeof(struct i2c_board_info));
- info.addr = setup->i2c_address;
- strlcpy(info.type, "ssm2602", I2C_NAME_SIZE);
- adapter = i2c_get_adapter(setup->i2c_bus);
- if (!adapter) {
- dev_err(&pdev->dev, "can't get i2c adapter %d\n",
- setup->i2c_bus);
- goto err_driver;
- }
- client = i2c_new_device(adapter, &info);
- i2c_put_adapter(adapter);
- if (!client) {
- dev_err(&pdev->dev, "can't add i2c device at 0x%x\n",
- (unsigned int)info.addr);
- goto err_driver;
- }
- return 0;
-err_driver:
- i2c_del_driver(&ssm2602_i2c_driver);
- return -ENODEV;
-}
#endif
-static int ssm2602_probe(struct platform_device *pdev)
+
+static int __init ssm2602_modinit(void)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct ssm2602_setup_data *setup;
- struct snd_soc_codec *codec;
- struct ssm2602_priv *ssm2602;
int ret = 0;
-
- pr_info("ssm2602 Audio Codec %s", SSM2602_VERSION);
-
- setup = socdev->codec_data;
- codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
- if (codec == NULL)
- return -ENOMEM;
-
- ssm2602 = kzalloc(sizeof(struct ssm2602_priv), GFP_KERNEL);
- if (ssm2602 == NULL) {
- kfree(codec);
- return -ENOMEM;
- }
-
- snd_soc_codec_set_drvdata(codec, ssm2602);
- socdev->card->codec = codec;
- mutex_init(&codec->mutex);
- INIT_LIST_HEAD(&codec->dapm_widgets);
- INIT_LIST_HEAD(&codec->dapm_paths);
-
- ssm2602_socdev = socdev;
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
- if (setup->i2c_address) {
- codec->hw_write = (hw_write_t)i2c_master_send;
- ret = ssm2602_add_i2c_device(pdev, setup);
+ ret = i2c_add_driver(&ssm2602_i2c_driver);
+ if (ret != 0) {
+ printk(KERN_ERR "Failed to register SSM2602 I2C driver: %d\n",
+ ret);
}
-#else
- /* other interfaces */
#endif
return ret;
}
+module_init(ssm2602_modinit);
-/* remove everything here */
-static int ssm2602_remove(struct platform_device *pdev)
+static void __exit ssm2602_exit(void)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec = socdev->card->codec;
-
- if (codec->control_data)
- ssm2602_set_bias_level(codec, SND_SOC_BIAS_OFF);
-
- snd_soc_free_pcms(socdev);
- snd_soc_dapm_free(socdev);
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
- i2c_unregister_device(codec->control_data);
i2c_del_driver(&ssm2602_i2c_driver);
#endif
- kfree(snd_soc_codec_get_drvdata(codec));
- kfree(codec);
-
- return 0;
-}
-
-struct snd_soc_codec_device soc_codec_dev_ssm2602 = {
- .probe = ssm2602_probe,
- .remove = ssm2602_remove,
- .suspend = ssm2602_suspend,
- .resume = ssm2602_resume,
-};
-EXPORT_SYMBOL_GPL(soc_codec_dev_ssm2602);
-
-static int __init ssm2602_modinit(void)
-{
- return snd_soc_register_dai(&ssm2602_dai);
-}
-module_init(ssm2602_modinit);
-
-static void __exit ssm2602_exit(void)
-{
- snd_soc_unregister_dai(&ssm2602_dai);
}
module_exit(ssm2602_exit);
diff --git a/sound/soc/codecs/ssm2602.h b/sound/soc/codecs/ssm2602.h
index f344e6d76e31..42a47d0f8e25 100644
--- a/sound/soc/codecs/ssm2602.h
+++ b/sound/soc/codecs/ssm2602.h
@@ -124,7 +124,4 @@ struct ssm2602_setup_data {
unsigned short i2c_address;
};
-extern struct snd_soc_dai ssm2602_dai;
-extern struct snd_soc_codec_device soc_codec_dev_ssm2602;
-
#endif
diff --git a/sound/soc/codecs/stac9766.c b/sound/soc/codecs/stac9766.c
index ee86568545c2..00d67cc8e206 100644
--- a/sound/soc/codecs/stac9766.c
+++ b/sound/soc/codecs/stac9766.c
@@ -25,7 +25,6 @@
#include <sound/pcm_params.h>
#include <sound/soc.h>
#include <sound/tlv.h>
-#include <sound/soc-of-simple.h>
#include "stac9766.h"
@@ -257,20 +256,15 @@ static int stac9766_reset(struct snd_soc_codec *codec, int try_warm)
return 0;
}
-static int stac9766_codec_suspend(struct platform_device *pdev,
+static int stac9766_codec_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;
-
stac9766_set_bias_level(codec, SND_SOC_BIAS_OFF);
return 0;
}
-static int stac9766_codec_resume(struct platform_device *pdev)
+static int stac9766_codec_resume(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec = socdev->card->codec;
u16 id, reset;
reset = 0;
@@ -300,10 +294,9 @@ static struct snd_soc_dai_ops stac9766_dai_ops_digital = {
.prepare = ac97_digital_prepare,
};
-struct snd_soc_dai stac9766_dai[] = {
+static struct snd_soc_dai_driver stac9766_dai[] = {
{
- .name = "stac9766 analog",
- .id = 0,
+ .name = "stac9766-hifi-analog",
.ac97_control = 1,
/* stream cababilities */
@@ -325,8 +318,7 @@ struct snd_soc_dai stac9766_dai[] = {
.ops = &stac9766_dai_ops_analog,
},
{
- .name = "stac9766 IEC958",
- .id = 1,
+ .name = "stac9766-hifi-IEC958",
.ac97_control = 1,
/* stream cababilities */
@@ -342,57 +334,24 @@ struct snd_soc_dai stac9766_dai[] = {
.ops = &stac9766_dai_ops_digital,
}
};
-EXPORT_SYMBOL_GPL(stac9766_dai);
-static int stac9766_codec_probe(struct platform_device *pdev)
+static int stac9766_codec_probe(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec;
int ret = 0;
printk(KERN_INFO "STAC9766 SoC Audio Codec %s\n", STAC9766_VERSION);
- socdev->card->codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
- if (socdev->card->codec == NULL)
- return -ENOMEM;
- codec = socdev->card->codec;
- mutex_init(&codec->mutex);
-
- codec->reg_cache = kmemdup(stac9766_reg, sizeof(stac9766_reg),
- GFP_KERNEL);
- if (codec->reg_cache == NULL) {
- ret = -ENOMEM;
- goto cache_err;
- }
- codec->reg_cache_size = sizeof(stac9766_reg);
- codec->reg_cache_step = 2;
-
- codec->name = "STAC9766";
- codec->owner = THIS_MODULE;
- codec->dai = stac9766_dai;
- codec->num_dai = ARRAY_SIZE(stac9766_dai);
- codec->write = stac9766_ac97_write;
- codec->read = stac9766_ac97_read;
- codec->set_bias_level = stac9766_set_bias_level;
- INIT_LIST_HEAD(&codec->dapm_widgets);
- INIT_LIST_HEAD(&codec->dapm_paths);
-
ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0);
if (ret < 0)
goto codec_err;
- /* register pcms */
- ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
- if (ret < 0)
- goto pcm_err;
-
/* do a cold reset for the controller and then try
* a warm reset followed by an optional cold reset for codec */
stac9766_reset(codec, 0);
ret = stac9766_reset(codec, 1);
if (ret < 0) {
printk(KERN_ERR "Failed to reset STAC9766: AC97 link error\n");
- goto reset_err;
+ goto codec_err;
}
stac9766_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
@@ -402,40 +361,63 @@ static int stac9766_codec_probe(struct platform_device *pdev)
return 0;
-reset_err:
- snd_soc_free_pcms(socdev);
-pcm_err:
- snd_soc_free_ac97_codec(codec);
codec_err:
- kfree(snd_soc_codec_get_drvdata(codec));
-cache_err:
- kfree(socdev->card->codec);
- socdev->card->codec = NULL;
+ snd_soc_free_ac97_codec(codec);
return ret;
}
-static int stac9766_codec_remove(struct platform_device *pdev)
+static int stac9766_codec_remove(struct snd_soc_codec *codec)
{
- 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);
snd_soc_free_ac97_codec(codec);
- kfree(codec->reg_cache);
- kfree(codec);
return 0;
}
-struct snd_soc_codec_device soc_codec_dev_stac9766 = {
+static struct snd_soc_codec_driver soc_codec_dev_stac9766 = {
+ .write = stac9766_ac97_write,
+ .read = stac9766_ac97_read,
+ .set_bias_level = stac9766_set_bias_level,
.probe = stac9766_codec_probe,
.remove = stac9766_codec_remove,
.suspend = stac9766_codec_suspend,
.resume = stac9766_codec_resume,
+ .reg_cache_size = sizeof(stac9766_reg),
+ .reg_word_size = sizeof(u16),
+ .reg_cache_step = 2,
+};
+
+static __devinit int stac9766_probe(struct platform_device *pdev)
+{
+ return snd_soc_register_codec(&pdev->dev,
+ &soc_codec_dev_stac9766, stac9766_dai, ARRAY_SIZE(stac9766_dai));
+}
+
+static int __devexit stac9766_remove(struct platform_device *pdev)
+{
+ snd_soc_unregister_codec(&pdev->dev);
+ return 0;
+}
+
+static struct platform_driver stac9766_codec_driver = {
+ .driver = {
+ .name = "stac9766-codec",
+ .owner = THIS_MODULE,
+ },
+
+ .probe = stac9766_probe,
+ .remove = __devexit_p(stac9766_remove),
};
-EXPORT_SYMBOL_GPL(soc_codec_dev_stac9766);
+
+static int __init stac9766_init(void)
+{
+ return platform_driver_register(&stac9766_codec_driver);
+}
+module_init(stac9766_init);
+
+static void __exit stac9766_exit(void)
+{
+ platform_driver_unregister(&stac9766_codec_driver);
+}
+module_exit(stac9766_exit);
MODULE_DESCRIPTION("ASoC stac9766 driver");
MODULE_AUTHOR("Jon Smirl <jonsmirl@gmail.com>");
diff --git a/sound/soc/codecs/stac9766.h b/sound/soc/codecs/stac9766.h
index 65642eb8393e..c726f907e2c0 100644
--- a/sound/soc/codecs/stac9766.h
+++ b/sound/soc/codecs/stac9766.h
@@ -14,8 +14,4 @@
#define STAC9766_DAI_AC97_ANALOG 0
#define STAC9766_DAI_AC97_DIGITAL 1
-extern struct snd_soc_dai stac9766_dai[];
-extern struct snd_soc_codec_device soc_codec_dev_stac9766;
-
-
#endif
diff --git a/sound/soc/codecs/tlv320aic23.c b/sound/soc/codecs/tlv320aic23.c
index 0a4b0fef3355..e8652b1ae326 100644
--- a/sound/soc/codecs/tlv320aic23.c
+++ b/sound/soc/codecs/tlv320aic23.c
@@ -240,7 +240,8 @@ static const struct snd_soc_dapm_route intercon[] = {
/* AIC23 driver data */
struct aic23 {
- struct snd_soc_codec codec;
+ enum snd_soc_control_type control_type;
+ void *control_data;
int mclk;
int requested_adc;
int requested_dac;
@@ -404,11 +405,10 @@ static int tlv320aic23_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;
u16 iface_reg;
int ret;
- struct aic23 *aic23 = container_of(codec, struct aic23, codec);
+ struct aic23 *aic23 = snd_soc_codec_get_drvdata(codec);
u32 sample_rate_adc = aic23->requested_adc;
u32 sample_rate_dac = aic23->requested_dac;
u32 sample_rate = params_rate(params);
@@ -452,8 +452,7 @@ static int tlv320aic23_pcm_prepare(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;
/* set active */
tlv320aic23_write(codec, TLV320AIC23_ACTIVE, 0x0001);
@@ -465,9 +464,8 @@ static void tlv320aic23_shutdown(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 aic23 *aic23 = container_of(codec, struct aic23, codec);
+ struct snd_soc_codec *codec = rtd->codec;
+ struct aic23 *aic23 = snd_soc_codec_get_drvdata(codec);
/* deactivate */
if (!codec->active) {
@@ -546,8 +544,7 @@ static int tlv320aic23_set_dai_fmt(struct snd_soc_dai *codec_dai,
static int tlv320aic23_set_dai_sysclk(struct snd_soc_dai *codec_dai,
int clk_id, unsigned int freq, int dir)
{
- struct snd_soc_codec *codec = codec_dai->codec;
- struct aic23 *aic23 = container_of(codec, struct aic23, codec);
+ struct aic23 *aic23 = snd_soc_dai_get_drvdata(codec_dai);
aic23->mclk = freq;
return 0;
}
@@ -594,8 +591,8 @@ static struct snd_soc_dai_ops tlv320aic23_dai_ops = {
.set_sysclk = tlv320aic23_set_dai_sysclk,
};
-struct snd_soc_dai tlv320aic23_dai = {
- .name = "tlv320aic23",
+static struct snd_soc_dai_driver tlv320aic23_dai = {
+ .name = "tlv320aic23-hifi",
.playback = {
.stream_name = "Playback",
.channels_min = 2,
@@ -610,23 +607,17 @@ struct snd_soc_dai tlv320aic23_dai = {
.formats = AIC23_FORMATS,},
.ops = &tlv320aic23_dai_ops,
};
-EXPORT_SYMBOL_GPL(tlv320aic23_dai);
-static int tlv320aic23_suspend(struct platform_device *pdev,
+static int tlv320aic23_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;
-
tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_OFF);
return 0;
}
-static int tlv320aic23_resume(struct platform_device *pdev)
+static int tlv320aic23_resume(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec = socdev->card->codec;
u16 reg;
/* Sync reg_cache with the hardware */
@@ -639,39 +630,19 @@ static int tlv320aic23_resume(struct platform_device *pdev)
return 0;
}
-/*
- * initialise the AIC23 driver
- * register the mixer and dsp interfaces with the kernel
- */
-static int tlv320aic23_init(struct snd_soc_device *socdev)
+static int tlv320aic23_probe(struct snd_soc_codec *codec)
{
- struct snd_soc_codec *codec = socdev->card->codec;
- int ret = 0;
- u16 reg;
+ struct aic23 *aic23 = snd_soc_codec_get_drvdata(codec);
+ int reg;
- codec->name = "tlv320aic23";
- codec->owner = THIS_MODULE;
- codec->read = tlv320aic23_read_reg_cache;
- codec->write = tlv320aic23_write;
- codec->set_bias_level = tlv320aic23_set_bias_level;
- codec->dai = &tlv320aic23_dai;
- codec->num_dai = 1;
- codec->reg_cache_size = ARRAY_SIZE(tlv320aic23_reg);
- codec->reg_cache =
- kmemdup(tlv320aic23_reg, sizeof(tlv320aic23_reg), GFP_KERNEL);
- if (codec->reg_cache == NULL)
- return -ENOMEM;
+ printk(KERN_INFO "AIC23 Audio Codec %s\n", AIC23_VERSION);
+ codec->control_data = aic23->control_data;
+ codec->hw_write = (hw_write_t)i2c_master_send;
+ codec->hw_read = NULL;
/* Reset codec */
tlv320aic23_write(codec, TLV320AIC23_RESET, 0);
- /* register pcms */
- ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
- if (ret < 0) {
- printk(KERN_ERR "tlv320aic23: failed to create pcms\n");
- goto pcm_err;
- }
-
/* power on device */
tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
@@ -707,13 +678,27 @@ static int tlv320aic23_init(struct snd_soc_device *socdev)
ARRAY_SIZE(tlv320aic23_snd_controls));
tlv320aic23_add_widgets(codec);
- return ret;
+ return 0;
+}
-pcm_err:
- kfree(codec->reg_cache);
- return ret;
+static int tlv320aic23_remove(struct snd_soc_codec *codec)
+{
+ tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_OFF);
+ return 0;
}
-static struct snd_soc_device *tlv320aic23_socdev;
+
+static struct snd_soc_codec_driver soc_codec_dev_tlv320aic23 = {
+ .reg_cache_size = ARRAY_SIZE(tlv320aic23_reg),
+ .reg_word_size = sizeof(u16),
+ .reg_cache_default = tlv320aic23_reg,
+ .probe = tlv320aic23_probe,
+ .remove = tlv320aic23_remove,
+ .suspend = tlv320aic23_suspend,
+ .resume = tlv320aic23_resume,
+ .read = tlv320aic23_read_reg_cache,
+ .write = tlv320aic23_write,
+ .set_bias_level = tlv320aic23_set_bias_level,
+};
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
/*
@@ -723,31 +708,30 @@ static struct snd_soc_device *tlv320aic23_socdev;
static int tlv320aic23_codec_probe(struct i2c_client *i2c,
const struct i2c_device_id *i2c_id)
{
- struct snd_soc_device *socdev = tlv320aic23_socdev;
- struct snd_soc_codec *codec = socdev->card->codec;
+ struct aic23 *aic23;
int ret;
if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
return -EINVAL;
- i2c_set_clientdata(i2c, codec);
- codec->control_data = i2c;
+ aic23 = kzalloc(sizeof(struct aic23), GFP_KERNEL);
+ if (aic23 == NULL)
+ return -ENOMEM;
- ret = tlv320aic23_init(socdev);
- if (ret < 0) {
- printk(KERN_ERR "tlv320aic23: failed to initialise AIC23\n");
- goto err;
- }
- return ret;
+ i2c_set_clientdata(i2c, aic23);
+ aic23->control_data = i2c;
+ aic23->control_type = SND_SOC_I2C;
-err:
- kfree(codec);
- kfree(i2c);
+ ret = snd_soc_register_codec(&i2c->dev,
+ &soc_codec_dev_tlv320aic23, &tlv320aic23_dai, 1);
+ if (ret < 0)
+ kfree(aic23);
return ret;
}
static int __exit tlv320aic23_i2c_remove(struct i2c_client *i2c)
{
- put_device(&i2c->dev);
+ snd_soc_unregister_codec(&i2c->dev);
+ kfree(i2c_get_clientdata(i2c));
return 0;
}
@@ -760,7 +744,7 @@ MODULE_DEVICE_TABLE(i2c, tlv320aic23_id);
static struct i2c_driver tlv320aic23_i2c_driver = {
.driver = {
- .name = "tlv320aic23",
+ .name = "tlv320aic23-codec",
},
.probe = tlv320aic23_codec_probe,
.remove = __exit_p(tlv320aic23_i2c_remove),
@@ -769,71 +753,25 @@ static struct i2c_driver tlv320aic23_i2c_driver = {
#endif
-static int tlv320aic23_probe(struct platform_device *pdev)
+static int __init tlv320aic23_modinit(void)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec;
- struct aic23 *aic23;
- int ret = 0;
-
- printk(KERN_INFO "AIC23 Audio Codec %s\n", AIC23_VERSION);
-
- aic23 = kzalloc(sizeof(struct aic23), GFP_KERNEL);
- if (aic23 == NULL)
- return -ENOMEM;
- codec = &aic23->codec;
- socdev->card->codec = codec;
- mutex_init(&codec->mutex);
- INIT_LIST_HEAD(&codec->dapm_widgets);
- INIT_LIST_HEAD(&codec->dapm_paths);
-
- tlv320aic23_socdev = socdev;
+ int ret;
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
- codec->hw_write = (hw_write_t) i2c_master_send;
- codec->hw_read = NULL;
ret = i2c_add_driver(&tlv320aic23_i2c_driver);
- if (ret != 0)
- printk(KERN_ERR "can't add i2c driver");
+ if (ret != 0) {
+ printk(KERN_ERR "Failed to register TLV320AIC23 I2C driver: %d\n",
+ ret);
+ }
#endif
return ret;
}
+module_init(tlv320aic23_modinit);
-static int tlv320aic23_remove(struct platform_device *pdev)
+static void __exit tlv320aic23_exit(void)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec = socdev->card->codec;
- struct aic23 *aic23 = container_of(codec, struct aic23, codec);
-
- if (codec->control_data)
- tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_OFF);
-
- snd_soc_free_pcms(socdev);
- snd_soc_dapm_free(socdev);
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
i2c_del_driver(&tlv320aic23_i2c_driver);
#endif
- kfree(codec->reg_cache);
- kfree(aic23);
-
- return 0;
-}
-struct snd_soc_codec_device soc_codec_dev_tlv320aic23 = {
- .probe = tlv320aic23_probe,
- .remove = tlv320aic23_remove,
- .suspend = tlv320aic23_suspend,
- .resume = tlv320aic23_resume,
-};
-EXPORT_SYMBOL_GPL(soc_codec_dev_tlv320aic23);
-
-static int __init tlv320aic23_modinit(void)
-{
- return snd_soc_register_dai(&tlv320aic23_dai);
-}
-module_init(tlv320aic23_modinit);
-
-static void __exit tlv320aic23_exit(void)
-{
- snd_soc_unregister_dai(&tlv320aic23_dai);
}
module_exit(tlv320aic23_exit);
diff --git a/sound/soc/codecs/tlv320aic23.h b/sound/soc/codecs/tlv320aic23.h
index 79d1faf8e570..e804120bd3da 100644
--- a/sound/soc/codecs/tlv320aic23.h
+++ b/sound/soc/codecs/tlv320aic23.h
@@ -116,7 +116,4 @@
#define TLV320AIC23_SIDETONE_12 0x080
#define TLV320AIC23_SIDETONE_18 0x0c0
-extern struct snd_soc_dai tlv320aic23_dai;
-extern struct snd_soc_codec_device soc_codec_dev_tlv320aic23;
-
#endif /* _TLV320AIC23_H */
diff --git a/sound/soc/codecs/tlv320aic26.c b/sound/soc/codecs/tlv320aic26.c
index f0e00fd4b435..6b7d71ec0004 100644
--- a/sound/soc/codecs/tlv320aic26.c
+++ b/sound/soc/codecs/tlv320aic26.c
@@ -19,7 +19,6 @@
#include <sound/pcm_params.h>
#include <sound/soc.h>
#include <sound/soc-dapm.h>
-#include <sound/soc-of-simple.h>
#include <sound/initval.h>
#include "tlv320aic26.h"
@@ -130,8 +129,7 @@ static int aic26_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 aic26 *aic26 = snd_soc_codec_get_drvdata(codec);
int fsref, divisor, wlen, pval, jval, dval, qval;
u16 reg;
@@ -278,8 +276,8 @@ static struct snd_soc_dai_ops aic26_dai_ops = {
.set_fmt = aic26_set_fmt,
};
-struct snd_soc_dai aic26_dai = {
- .name = "tlv320aic26",
+static struct snd_soc_dai_driver aic26_dai = {
+ .name = "tlv320aic26-hifi",
.playback = {
.stream_name = "Playback",
.channels_min = 2,
@@ -296,7 +294,6 @@ struct snd_soc_dai aic26_dai = {
},
.ops = &aic26_dai_ops,
};
-EXPORT_SYMBOL_GPL(aic26_dai);
/* ---------------------------------------------------------------------
* ALSA controls
@@ -319,61 +316,6 @@ static const struct snd_kcontrol_new aic26_snd_controls[] = {
};
/* ---------------------------------------------------------------------
- * SoC CODEC portion of driver: probe and release routines
- */
-static int aic26_probe(struct platform_device *pdev)
-{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec;
- struct aic26 *aic26;
- int ret, err;
-
- dev_info(&pdev->dev, "Probing AIC26 SoC CODEC driver\n");
- dev_dbg(&pdev->dev, "socdev=%p\n", socdev);
- dev_dbg(&pdev->dev, "codec_data=%p\n", socdev->codec_data);
-
- /* Fetch the relevant aic26 private data here (it's already been
- * stored in the .codec pointer) */
- aic26 = socdev->codec_data;
- if (aic26 == NULL) {
- dev_err(&pdev->dev, "aic26: missing codec pointer\n");
- return -ENODEV;
- }
- codec = &aic26->codec;
- socdev->card->codec = codec;
-
- dev_dbg(&pdev->dev, "Registering PCMs, dev=%p, socdev->dev=%p\n",
- &pdev->dev, socdev->dev);
- /* register pcms */
- ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
- if (ret < 0) {
- dev_err(&pdev->dev, "aic26: failed to create pcms\n");
- return -ENODEV;
- }
-
- /* register controls */
- dev_dbg(&pdev->dev, "Registering controls\n");
- err = snd_soc_add_controls(codec, aic26_snd_controls,
- ARRAY_SIZE(aic26_snd_controls));
- WARN_ON(err < 0);
-
- return 0;
-}
-
-static int aic26_remove(struct platform_device *pdev)
-{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- snd_soc_free_pcms(socdev);
- return 0;
-}
-
-struct snd_soc_codec_device aic26_soc_codec_dev = {
- .probe = aic26_probe,
- .remove = aic26_remove,
-};
-EXPORT_SYMBOL_GPL(aic26_soc_codec_dev);
-
-/* ---------------------------------------------------------------------
* SPI device portion of driver: sysfs files for debugging
*/
@@ -409,95 +351,95 @@ static ssize_t aic26_keyclick_set(struct device *dev,
static DEVICE_ATTR(keyclick, 0644, aic26_keyclick_show, aic26_keyclick_set);
/* ---------------------------------------------------------------------
- * SPI device portion of driver: probe and release routines and SPI
- * driver registration.
+ * SoC CODEC portion of driver: probe and release routines
*/
-static int aic26_spi_probe(struct spi_device *spi)
+static int aic26_probe(struct snd_soc_codec *codec)
{
- struct aic26 *aic26;
- int ret, i, reg;
-
- dev_dbg(&spi->dev, "probing tlv320aic26 spi device\n");
-
- /* Allocate driver data */
- aic26 = kzalloc(sizeof *aic26, GFP_KERNEL);
- if (!aic26)
- return -ENOMEM;
-
- /* Initialize the driver data */
- aic26->spi = spi;
- dev_set_drvdata(&spi->dev, aic26);
+ struct aic26 *aic26 = snd_soc_codec_get_drvdata(codec);
+ int ret, err, i, reg;
- /* Setup what we can in the codec structure so that the register
- * access functions will work as expected. More will be filled
- * out when it is probed by the SoC CODEC part of this driver */
- snd_soc_codec_set_drvdata(&aic26->codec, aic26);
- aic26->codec.name = "aic26";
- aic26->codec.owner = THIS_MODULE;
- aic26->codec.dai = &aic26_dai;
- aic26->codec.num_dai = 1;
- aic26->codec.read = aic26_reg_read;
- aic26->codec.write = aic26_reg_write;
- aic26->master = 1;
- mutex_init(&aic26->codec.mutex);
- INIT_LIST_HEAD(&aic26->codec.dapm_widgets);
- INIT_LIST_HEAD(&aic26->codec.dapm_paths);
- aic26->codec.reg_cache_size = AIC26_NUM_REGS;
- aic26->codec.reg_cache = aic26->reg_cache;
-
- aic26_dai.dev = &spi->dev;
- ret = snd_soc_register_dai(&aic26_dai);
- if (ret != 0) {
- dev_err(&spi->dev, "Failed to register DAI: %d\n", ret);
- kfree(aic26);
- return ret;
- }
+ dev_info(codec->dev, "Probing AIC26 SoC CODEC driver\n");
/* Reset the codec to power on defaults */
- aic26_reg_write(&aic26->codec, AIC26_REG_RESET, 0xBB00);
+ aic26_reg_write(codec, AIC26_REG_RESET, 0xBB00);
/* Power up CODEC */
- aic26_reg_write(&aic26->codec, AIC26_REG_POWER_CTRL, 0);
+ aic26_reg_write(codec, AIC26_REG_POWER_CTRL, 0);
/* Audio Control 3 (master mode, fsref rate) */
- reg = aic26_reg_read(&aic26->codec, AIC26_REG_AUDIO_CTRL3);
+ reg = aic26_reg_read(codec, AIC26_REG_AUDIO_CTRL3);
reg &= ~0xf800;
reg |= 0x0800; /* set master mode */
- aic26_reg_write(&aic26->codec, AIC26_REG_AUDIO_CTRL3, reg);
+ aic26_reg_write(codec, AIC26_REG_AUDIO_CTRL3, reg);
/* Fill register cache */
for (i = 0; i < ARRAY_SIZE(aic26->reg_cache); i++)
- aic26_reg_read(&aic26->codec, i);
+ aic26_reg_read(codec, i);
/* Register the sysfs files for debugging */
/* Create SysFS files */
- ret = device_create_file(&spi->dev, &dev_attr_keyclick);
+ ret = device_create_file(codec->dev, &dev_attr_keyclick);
if (ret)
- dev_info(&spi->dev, "error creating sysfs files\n");
+ dev_info(codec->dev, "error creating sysfs files\n");
-#if defined(CONFIG_SND_SOC_OF_SIMPLE)
- /* Tell the of_soc helper about this codec */
- of_snd_soc_register_codec(&aic26_soc_codec_dev, aic26, &aic26_dai,
- spi->dev.archdata.of_node);
-#endif
+ /* register controls */
+ dev_dbg(codec->dev, "Registering controls\n");
+ err = snd_soc_add_controls(codec, aic26_snd_controls,
+ ARRAY_SIZE(aic26_snd_controls));
+ WARN_ON(err < 0);
- dev_dbg(&spi->dev, "SPI device initialized\n");
return 0;
}
-static int aic26_spi_remove(struct spi_device *spi)
+static struct snd_soc_codec_driver aic26_soc_codec_dev = {
+ .probe = aic26_probe,
+ .read = aic26_reg_read,
+ .write = aic26_reg_write,
+ .reg_cache_size = AIC26_NUM_REGS,
+ .reg_word_size = sizeof(u16),
+};
+
+/* ---------------------------------------------------------------------
+ * SPI device portion of driver: probe and release routines and SPI
+ * driver registration.
+ */
+static int aic26_spi_probe(struct spi_device *spi)
{
- struct aic26 *aic26 = dev_get_drvdata(&spi->dev);
+ struct aic26 *aic26;
+ int ret;
- snd_soc_unregister_dai(&aic26_dai);
- kfree(aic26);
+ dev_dbg(&spi->dev, "probing tlv320aic26 spi device\n");
+
+ /* Allocate driver data */
+ aic26 = kzalloc(sizeof *aic26, GFP_KERNEL);
+ if (!aic26)
+ return -ENOMEM;
+ /* Initialize the driver data */
+ aic26->spi = spi;
+ dev_set_drvdata(&spi->dev, aic26);
+ aic26->master = 1;
+
+ ret = snd_soc_register_codec(&spi->dev,
+ &aic26_soc_codec_dev, &aic26_dai, 1);
+ if (ret < 0)
+ kfree(aic26);
+ return ret;
+
+ dev_dbg(&spi->dev, "SPI device initialized\n");
+ return 0;
+}
+
+static int aic26_spi_remove(struct spi_device *spi)
+{
+ snd_soc_unregister_codec(&spi->dev);
+ kfree(spi_get_drvdata(spi));
return 0;
}
static struct spi_driver aic26_spi = {
.driver = {
- .name = "tlv320aic26",
+ .name = "tlv320aic26-codec",
.owner = THIS_MODULE,
},
.probe = aic26_spi_probe,
diff --git a/sound/soc/codecs/tlv320aic26.h b/sound/soc/codecs/tlv320aic26.h
index 786ba16c945f..62b1f2261429 100644
--- a/sound/soc/codecs/tlv320aic26.h
+++ b/sound/soc/codecs/tlv320aic26.h
@@ -90,7 +90,4 @@ enum aic26_wlen {
AIC26_WLEN_32 = 3 << 10,
};
-extern struct snd_soc_dai aic26_dai;
-extern struct snd_soc_codec_device aic26_soc_codec_dev;
-
#endif /* _TLV320AIC16_H_ */
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c
index 71a69908ccf6..43fd9c171742 100644
--- a/sound/soc/codecs/tlv320aic3x.c
+++ b/sound/soc/codecs/tlv320aic3x.c
@@ -63,8 +63,10 @@ static const char *aic3x_supply_names[AIC3X_NUM_SUPPLIES] = {
/* codec private data */
struct aic3x_priv {
- struct snd_soc_codec codec;
struct regulator_bulk_data supplies[AIC3X_NUM_SUPPLIES];
+ enum snd_soc_control_type control_type;
+ struct aic3x_setup_data *setup;
+ void *control_data;
unsigned int sysclk;
int master;
int gpio_reset;
@@ -773,8 +775,7 @@ static int aic3x_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 aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
int codec_clk = 0, bypass_pll = 0, fsref, last_clk = 0;
u8 data, j, r, p, pll_q, pll_p = 1, pll_r = 1, pll_j = 1;
@@ -1101,8 +1102,8 @@ static struct snd_soc_dai_ops aic3x_dai_ops = {
.set_fmt = aic3x_set_dai_fmt,
};
-struct snd_soc_dai aic3x_dai = {
- .name = "tlv320aic3x",
+static struct snd_soc_dai_driver aic3x_dai = {
+ .name = "tlv320aic3x-hifi",
.playback = {
.stream_name = "Playback",
.channels_min = 1,
@@ -1117,22 +1118,16 @@ struct snd_soc_dai aic3x_dai = {
.formats = AIC3X_FORMATS,},
.ops = &aic3x_dai_ops,
};
-EXPORT_SYMBOL_GPL(aic3x_dai);
-static int aic3x_suspend(struct platform_device *pdev, pm_message_t state)
+static int aic3x_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;
-
aic3x_set_bias_level(codec, SND_SOC_BIAS_OFF);
return 0;
}
-static int aic3x_resume(struct platform_device *pdev)
+static int aic3x_resume(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec = socdev->card->codec;
int i;
u8 data[2];
u8 *cache = codec->reg_cache;
@@ -1157,22 +1152,6 @@ static int aic3x_init(struct snd_soc_codec *codec)
{
int reg;
- mutex_init(&codec->mutex);
- INIT_LIST_HEAD(&codec->dapm_widgets);
- INIT_LIST_HEAD(&codec->dapm_paths);
-
- codec->name = "tlv320aic3x";
- codec->owner = THIS_MODULE;
- codec->read = aic3x_read_reg_cache;
- codec->write = aic3x_write;
- codec->set_bias_level = aic3x_set_bias_level;
- codec->dai = &aic3x_dai;
- codec->num_dai = 1;
- codec->reg_cache_size = ARRAY_SIZE(aic3x_reg);
- codec->reg_cache = kmemdup(aic3x_reg, sizeof(aic3x_reg), GFP_KERNEL);
- if (codec->reg_cache == NULL)
- return -ENOMEM;
-
aic3x_write(codec, AIC3X_PAGE_SELECT, PAGE0_SELECT);
aic3x_write(codec, AIC3X_RESET, SOFT_RESET);
@@ -1245,56 +1224,50 @@ static int aic3x_init(struct snd_soc_codec *codec)
return 0;
}
-static struct snd_soc_codec *aic3x_codec;
-
-static int aic3x_register(struct snd_soc_codec *codec)
+static int aic3x_probe(struct snd_soc_codec *codec)
{
- int ret;
+ struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
+
+ codec->hw_write = (hw_write_t) i2c_master_send;
+ codec->control_data = aic3x->control_data;
- ret = aic3x_init(codec);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to initialise device\n");
- return ret;
+ if (aic3x->setup) {
+ /* setup GPIO functions */
+ aic3x_write(codec, AIC3X_GPIO1_REG,
+ (aic3x->setup->gpio_func[0] & 0xf) << 4);
+ aic3x_write(codec, AIC3X_GPIO2_REG,
+ (aic3x->setup->gpio_func[1] & 0xf) << 4);
}
- aic3x_codec = codec;
+ aic3x_init(codec);
- ret = snd_soc_register_codec(codec);
- if (ret) {
- dev_err(codec->dev, "Failed to register codec\n");
- return ret;
- }
+ snd_soc_add_controls(codec, aic3x_snd_controls,
+ ARRAY_SIZE(aic3x_snd_controls));
- ret = snd_soc_register_dai(&aic3x_dai);
- if (ret) {
- dev_err(codec->dev, "Failed to register dai\n");
- snd_soc_unregister_codec(codec);
- return ret;
- }
+ aic3x_add_widgets(codec);
return 0;
}
-static int aic3x_unregister(struct aic3x_priv *aic3x)
+static int aic3x_remove(struct snd_soc_codec *codec)
{
- aic3x_set_bias_level(&aic3x->codec, SND_SOC_BIAS_OFF);
-
- snd_soc_unregister_dai(&aic3x_dai);
- snd_soc_unregister_codec(&aic3x->codec);
-
- if (aic3x->gpio_reset >= 0) {
- gpio_set_value(aic3x->gpio_reset, 0);
- gpio_free(aic3x->gpio_reset);
- }
- regulator_bulk_disable(ARRAY_SIZE(aic3x->supplies), aic3x->supplies);
- regulator_bulk_free(ARRAY_SIZE(aic3x->supplies), aic3x->supplies);
-
- kfree(aic3x);
- aic3x_codec = NULL;
-
+ aic3x_set_bias_level(codec, SND_SOC_BIAS_OFF);
return 0;
}
+static struct snd_soc_codec_driver soc_codec_dev_aic3x = {
+ .read = aic3x_read_reg_cache,
+ .write = aic3x_write,
+ .set_bias_level = aic3x_set_bias_level,
+ .reg_cache_size = ARRAY_SIZE(aic3x_reg),
+ .reg_word_size = sizeof(u8),
+ .reg_cache_default = aic3x_reg,
+ .probe = aic3x_probe,
+ .remove = aic3x_remove,
+ .suspend = aic3x_suspend,
+ .resume = aic3x_resume,
+};
+
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
/*
* AIC3X 2 wire address can be up to 4 devices with device addresses
@@ -1308,9 +1281,9 @@ static int aic3x_unregister(struct aic3x_priv *aic3x)
static int aic3x_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
- struct snd_soc_codec *codec;
- struct aic3x_priv *aic3x;
struct aic3x_pdata *pdata = i2c->dev.platform_data;
+ struct aic3x_setup_data *setup = pdata->setup;
+ struct aic3x_priv *aic3x;
int ret, i;
aic3x = kzalloc(sizeof(struct aic3x_priv), GFP_KERNEL);
@@ -1319,12 +1292,8 @@ static int aic3x_i2c_probe(struct i2c_client *i2c,
return -ENOMEM;
}
- codec = &aic3x->codec;
- codec->dev = &i2c->dev;
- snd_soc_codec_set_drvdata(codec, aic3x);
- codec->control_data = i2c;
- codec->hw_write = (hw_write_t) i2c_master_send;
-
+ aic3x->control_data = i2c;
+ aic3x->setup = setup;
i2c_set_clientdata(i2c, aic3x);
aic3x->gpio_reset = -1;
@@ -1339,17 +1308,17 @@ static int aic3x_i2c_probe(struct i2c_client *i2c,
for (i = 0; i < ARRAY_SIZE(aic3x->supplies); i++)
aic3x->supplies[i].supply = aic3x_supply_names[i];
- ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(aic3x->supplies),
+ ret = regulator_bulk_get(&i2c->dev, ARRAY_SIZE(aic3x->supplies),
aic3x->supplies);
if (ret != 0) {
- dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
+ dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret);
goto err_get;
}
ret = regulator_bulk_enable(ARRAY_SIZE(aic3x->supplies),
aic3x->supplies);
if (ret != 0) {
- dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
+ dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret);
goto err_enable;
}
@@ -1358,7 +1327,11 @@ static int aic3x_i2c_probe(struct i2c_client *i2c,
gpio_set_value(aic3x->gpio_reset, 1);
}
- return aic3x_register(codec);
+ ret = snd_soc_register_codec(&i2c->dev,
+ &soc_codec_dev_aic3x, &aic3x_dai, 1);
+ if (ret < 0)
+ goto err_enable;
+ return ret;
err_enable:
regulator_bulk_free(ARRAY_SIZE(aic3x->supplies), aic3x->supplies);
@@ -1374,7 +1347,16 @@ static int aic3x_i2c_remove(struct i2c_client *client)
{
struct aic3x_priv *aic3x = i2c_get_clientdata(client);
- return aic3x_unregister(aic3x);
+ if (aic3x->gpio_reset >= 0) {
+ gpio_set_value(aic3x->gpio_reset, 0);
+ gpio_free(aic3x->gpio_reset);
+ }
+ regulator_bulk_disable(ARRAY_SIZE(aic3x->supplies), aic3x->supplies);
+ regulator_bulk_free(ARRAY_SIZE(aic3x->supplies), aic3x->supplies);
+
+ snd_soc_unregister_codec(&client->dev);
+ kfree(i2c_get_clientdata(client));
+ return 0;
}
static const struct i2c_device_id aic3x_i2c_id[] = {
@@ -1387,7 +1369,7 @@ MODULE_DEVICE_TABLE(i2c, aic3x_i2c_id);
/* machine i2c codec control layer */
static struct i2c_driver aic3x_i2c_driver = {
.driver = {
- .name = "aic3x I2C Codec",
+ .name = "tlv320aic3x-codec",
.owner = THIS_MODULE,
},
.probe = aic3x_i2c_probe,
@@ -1409,90 +1391,27 @@ static inline void aic3x_i2c_exit(void)
{
i2c_del_driver(&aic3x_i2c_driver);
}
-#else
-static inline void aic3x_i2c_init(void) { }
-static inline void aic3x_i2c_exit(void) { }
#endif
-static int aic3x_probe(struct platform_device *pdev)
+static int __init aic3x_modinit(void)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct aic3x_setup_data *setup;
- struct snd_soc_codec *codec;
int ret = 0;
-
- codec = aic3x_codec;
- if (!codec) {
- dev_err(&pdev->dev, "Codec not registered\n");
- return -ENODEV;
- }
-
- socdev->card->codec = codec;
- setup = socdev->codec_data;
-
- if (setup) {
- /* setup GPIO functions */
- aic3x_write(codec, AIC3X_GPIO1_REG,
- (setup->gpio_func[0] & 0xf) << 4);
- aic3x_write(codec, AIC3X_GPIO2_REG,
- (setup->gpio_func[1] & 0xf) << 4);
- }
-
- /* register pcms */
- ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
- if (ret < 0) {
- printk(KERN_ERR "aic3x: failed to create pcms\n");
- goto pcm_err;
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+ ret = i2c_add_driver(&aic3x_i2c_driver);
+ if (ret != 0) {
+ printk(KERN_ERR "Failed to register TLV320AIC3x I2C driver: %d\n",
+ ret);
}
-
- snd_soc_add_controls(codec, aic3x_snd_controls,
- ARRAY_SIZE(aic3x_snd_controls));
-
- aic3x_add_widgets(codec);
-
- return ret;
-
-pcm_err:
- kfree(codec->reg_cache);
+#endif
return ret;
}
-
-static int aic3x_remove(struct platform_device *pdev)
-{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec = socdev->card->codec;
-
- /* power down chip */
- if (codec->control_data)
- aic3x_set_bias_level(codec, SND_SOC_BIAS_OFF);
-
- snd_soc_free_pcms(socdev);
- snd_soc_dapm_free(socdev);
-
- kfree(codec->reg_cache);
-
- return 0;
-}
-
-struct snd_soc_codec_device soc_codec_dev_aic3x = {
- .probe = aic3x_probe,
- .remove = aic3x_remove,
- .suspend = aic3x_suspend,
- .resume = aic3x_resume,
-};
-EXPORT_SYMBOL_GPL(soc_codec_dev_aic3x);
-
-static int __init aic3x_modinit(void)
-{
- aic3x_i2c_init();
-
- return 0;
-}
module_init(aic3x_modinit);
static void __exit aic3x_exit(void)
{
- aic3x_i2c_exit();
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+ i2c_del_driver(&aic3x_i2c_driver);
+#endif
}
module_exit(aic3x_exit);
diff --git a/sound/soc/codecs/tlv320aic3x.h b/sound/soc/codecs/tlv320aic3x.h
index 9af1c886213c..f6e3d9b42daf 100644
--- a/sound/soc/codecs/tlv320aic3x.h
+++ b/sound/soc/codecs/tlv320aic3x.h
@@ -199,42 +199,6 @@
/* Default input volume */
#define DEFAULT_GAIN 0x20
-/* GPIO API */
-enum {
- AIC3X_GPIO1_FUNC_DISABLED = 0,
- AIC3X_GPIO1_FUNC_AUDIO_WORDCLK_ADC = 1,
- AIC3X_GPIO1_FUNC_CLOCK_MUX = 2,
- AIC3X_GPIO1_FUNC_CLOCK_MUX_DIV2 = 3,
- AIC3X_GPIO1_FUNC_CLOCK_MUX_DIV4 = 4,
- AIC3X_GPIO1_FUNC_CLOCK_MUX_DIV8 = 5,
- AIC3X_GPIO1_FUNC_SHORT_CIRCUIT_IRQ = 6,
- AIC3X_GPIO1_FUNC_AGC_NOISE_IRQ = 7,
- AIC3X_GPIO1_FUNC_INPUT = 8,
- AIC3X_GPIO1_FUNC_OUTPUT = 9,
- AIC3X_GPIO1_FUNC_DIGITAL_MIC_MODCLK = 10,
- AIC3X_GPIO1_FUNC_AUDIO_WORDCLK = 11,
- AIC3X_GPIO1_FUNC_BUTTON_IRQ = 12,
- AIC3X_GPIO1_FUNC_HEADSET_DETECT_IRQ = 13,
- AIC3X_GPIO1_FUNC_HEADSET_DETECT_OR_BUTTON_IRQ = 14,
- AIC3X_GPIO1_FUNC_ALL_IRQ = 16
-};
-
-enum {
- AIC3X_GPIO2_FUNC_DISABLED = 0,
- AIC3X_GPIO2_FUNC_HEADSET_DETECT_IRQ = 2,
- AIC3X_GPIO2_FUNC_INPUT = 3,
- AIC3X_GPIO2_FUNC_OUTPUT = 4,
- AIC3X_GPIO2_FUNC_DIGITAL_MIC_INPUT = 5,
- AIC3X_GPIO2_FUNC_AUDIO_BITCLK = 8,
- AIC3X_GPIO2_FUNC_HEADSET_DETECT_OR_BUTTON_IRQ = 9,
- AIC3X_GPIO2_FUNC_ALL_IRQ = 10,
- AIC3X_GPIO2_FUNC_SHORT_CIRCUIT_OR_AGC_IRQ = 11,
- AIC3X_GPIO2_FUNC_HEADSET_OR_BUTTON_PRESS_OR_SHORT_CIRCUIT_IRQ = 12,
- AIC3X_GPIO2_FUNC_SHORT_CIRCUIT_IRQ = 13,
- AIC3X_GPIO2_FUNC_AGC_NOISE_IRQ = 14,
- AIC3X_GPIO2_FUNC_BUTTON_PRESS_IRQ = 15
-};
-
void aic3x_set_gpio(struct snd_soc_codec *codec, int gpio, int state);
int aic3x_get_gpio(struct snd_soc_codec *codec, int gpio);
@@ -281,11 +245,4 @@ void aic3x_set_headset_detection(struct snd_soc_codec *codec, int detect,
int aic3x_headset_detected(struct snd_soc_codec *codec);
int aic3x_button_pressed(struct snd_soc_codec *codec);
-struct aic3x_setup_data {
- unsigned int gpio_func[2];
-};
-
-extern struct snd_soc_dai aic3x_dai;
-extern struct snd_soc_codec_device soc_codec_dev_aic3x;
-
#endif /* _AIC3X_H */
diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c
index 8651b01ed223..a3c5b521da6a 100644
--- a/sound/soc/codecs/tlv320dac33.c
+++ b/sound/soc/codecs/tlv320dac33.c
@@ -66,8 +66,6 @@
static void dac33_calculate_times(struct snd_pcm_substream *substream);
static int dac33_prepare_chip(struct snd_pcm_substream *substream);
-static struct snd_soc_codec *tlv320dac33_codec;
-
enum dac33_state {
DAC33_IDLE = 0,
DAC33_PREFILL,
@@ -93,7 +91,7 @@ struct tlv320dac33_priv {
struct mutex mutex;
struct workqueue_struct *dac33_wq;
struct work_struct work;
- struct snd_soc_codec codec;
+ struct snd_soc_codec *codec;
struct regulator_bulk_data supplies[DAC33_NUM_SUPPLIES];
struct snd_pcm_substream *substream;
int power_gpio;
@@ -128,6 +126,8 @@ struct tlv320dac33_priv {
unsigned int uthr;
enum dac33_state state;
+ enum snd_soc_control_type control_type;
+ void *control_data;
};
static const u8 dac33_reg[DAC33_CACHEREGNUM] = {
@@ -650,9 +650,7 @@ static int dac33_set_bias_level(struct snd_soc_codec *codec,
static inline void dac33_prefill_handler(struct tlv320dac33_priv *dac33)
{
- struct snd_soc_codec *codec;
-
- codec = &dac33->codec;
+ struct snd_soc_codec *codec = dac33->codec;
switch (dac33->fifo_mode) {
case DAC33_FIFO_MODE1:
@@ -695,9 +693,7 @@ static inline void dac33_prefill_handler(struct tlv320dac33_priv *dac33)
static inline void dac33_playback_handler(struct tlv320dac33_priv *dac33)
{
- struct snd_soc_codec *codec;
-
- codec = &dac33->codec;
+ struct snd_soc_codec *codec = dac33->codec;
switch (dac33->fifo_mode) {
case DAC33_FIFO_MODE1:
@@ -726,7 +722,7 @@ static void dac33_work(struct work_struct *work)
u8 reg;
dac33 = container_of(work, struct tlv320dac33_priv, work);
- codec = &dac33->codec;
+ codec = dac33->codec;
mutex_lock(&dac33->mutex);
switch (dac33->state) {
@@ -787,8 +783,7 @@ static int dac33_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 tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
/* Stream started, save the substream pointer */
@@ -801,8 +796,7 @@ static void dac33_shutdown(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 tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
dac33->substream = NULL;
@@ -817,8 +811,7 @@ static int dac33_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;
/* Check parameters for validity */
switch (params_rate(params)) {
@@ -856,8 +849,7 @@ static int dac33_hw_params(struct snd_pcm_substream *substream,
static int dac33_prepare_chip(struct snd_pcm_substream *substream)
{
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 tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
unsigned int oscset, ratioset, pwr_ctrl, reg_tmp;
u8 aictrl_a, aictrl_b, fifoctrl_a;
@@ -1049,8 +1041,7 @@ static int dac33_prepare_chip(struct snd_pcm_substream *substream)
static void dac33_calculate_times(struct snd_pcm_substream *substream)
{
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 tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
unsigned int period_size = substream->runtime->period_size;
unsigned int rate = substream->runtime->rate;
@@ -1129,8 +1120,7 @@ static int dac33_pcm_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 tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
int ret = 0;
@@ -1163,8 +1153,7 @@ static snd_pcm_sframes_t dac33_dai_delay(
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 tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
unsigned long long t0, t1, t_now;
unsigned int time_delta, uthr;
@@ -1389,24 +1378,47 @@ static int dac33_set_dai_fmt(struct snd_soc_dai *codec_dai,
return 0;
}
-static int dac33_soc_probe(struct platform_device *pdev)
+static int dac33_soc_probe(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec;
- struct tlv320dac33_priv *dac33;
+ struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
int ret = 0;
- BUG_ON(!tlv320dac33_codec);
+ codec->control_data = dac33->control_data;
+ codec->hw_write = (hw_write_t) i2c_master_send;
+ codec->bias_level = SND_SOC_BIAS_OFF;
+ codec->idle_bias_off = 1;
+ dac33->codec = codec;
- codec = tlv320dac33_codec;
- socdev->card->codec = codec;
- dac33 = snd_soc_codec_get_drvdata(codec);
+ /* Read the tlv320dac33 ID registers */
+ ret = dac33_hard_power(codec, 1);
+ if (ret != 0) {
+ dev_err(codec->dev, "Failed to power up codec: %d\n", ret);
+ goto err_power;
+ }
+ dac33_read_id(codec);
+ dac33_hard_power(codec, 0);
- /* register pcms */
- ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
- if (ret < 0) {
- dev_err(codec->dev, "failed to create pcms\n");
- goto pcm_err;
+ /* Check if the IRQ number is valid and request it */
+ if (dac33->irq >= 0) {
+ ret = request_irq(dac33->irq, dac33_interrupt_handler,
+ IRQF_TRIGGER_RISING | IRQF_DISABLED,
+ codec->name, codec);
+ if (ret < 0) {
+ dev_err(codec->dev, "Could not request IRQ%d (%d)\n",
+ dac33->irq, ret);
+ dac33->irq = -1;
+ }
+ if (dac33->irq != -1) {
+ /* Setup work queue */
+ dac33->dac33_wq =
+ create_singlethread_workqueue("tlv320dac33");
+ if (dac33->dac33_wq == NULL) {
+ free_irq(dac33->irq, codec);
+ return -ENOMEM;
+ }
+
+ INIT_WORK(&dac33->work, dac33_work);
+ }
}
snd_soc_add_controls(codec, dac33_snd_controls,
@@ -1420,56 +1432,51 @@ static int dac33_soc_probe(struct platform_device *pdev)
snd_soc_add_controls(codec, dac33_fifo_snd_controls,
ARRAY_SIZE(dac33_fifo_snd_controls));
}
-
dac33_add_widgets(codec);
- return 0;
-
-pcm_err:
- dac33_hard_power(codec, 0);
+err_power:
return ret;
}
-static int dac33_soc_remove(struct platform_device *pdev)
+static int dac33_soc_remove(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec = socdev->card->codec;
+ struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
dac33_set_bias_level(codec, SND_SOC_BIAS_OFF);
- snd_soc_free_pcms(socdev);
- snd_soc_dapm_free(socdev);
-
+ if (dac33->irq >= 0) {
+ free_irq(dac33->irq, dac33->codec);
+ destroy_workqueue(dac33->dac33_wq);
+ }
return 0;
}
-static int dac33_soc_suspend(struct platform_device *pdev, pm_message_t state)
+static int dac33_soc_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;
-
dac33_set_bias_level(codec, SND_SOC_BIAS_OFF);
return 0;
}
-static int dac33_soc_resume(struct platform_device *pdev)
+static int dac33_soc_resume(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec = socdev->card->codec;
-
dac33_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
return 0;
}
-struct snd_soc_codec_device soc_codec_dev_tlv320dac33 = {
+static struct snd_soc_codec_driver soc_codec_dev_tlv320dac33 = {
+ .read = dac33_read_reg_cache,
+ .write = dac33_write_locked,
+ .set_bias_level = dac33_set_bias_level,
+ .reg_cache_size = ARRAY_SIZE(dac33_reg),
+ .reg_word_size = sizeof(u8),
+ .reg_cache_default = dac33_reg,
.probe = dac33_soc_probe,
.remove = dac33_soc_remove,
.suspend = dac33_soc_suspend,
.resume = dac33_soc_resume,
};
-EXPORT_SYMBOL_GPL(soc_codec_dev_tlv320dac33);
#define DAC33_RATES (SNDRV_PCM_RATE_44100 | \
SNDRV_PCM_RATE_48000)
@@ -1485,8 +1492,8 @@ static struct snd_soc_dai_ops dac33_dai_ops = {
.set_fmt = dac33_set_dai_fmt,
};
-struct snd_soc_dai dac33_dai = {
- .name = "tlv320dac33",
+static struct snd_soc_dai_driver dac33_dai = {
+ .name = "tlv320dac33-hifi",
.playback = {
.stream_name = "Playback",
.channels_min = 2,
@@ -1495,14 +1502,12 @@ struct snd_soc_dai dac33_dai = {
.formats = DAC33_FORMATS,},
.ops = &dac33_dai_ops,
};
-EXPORT_SYMBOL_GPL(dac33_dai);
static int __devinit dac33_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct tlv320dac33_platform_data *pdata;
struct tlv320dac33_priv *dac33;
- struct snd_soc_codec *codec;
int ret, i;
if (client->dev.platform_data == NULL) {
@@ -1515,33 +1520,9 @@ static int __devinit dac33_i2c_probe(struct i2c_client *client,
if (dac33 == NULL)
return -ENOMEM;
- codec = &dac33->codec;
- snd_soc_codec_set_drvdata(codec, dac33);
- codec->control_data = client;
-
- mutex_init(&codec->mutex);
+ dac33->control_data = client;
mutex_init(&dac33->mutex);
spin_lock_init(&dac33->lock);
- INIT_LIST_HEAD(&codec->dapm_widgets);
- INIT_LIST_HEAD(&codec->dapm_paths);
-
- codec->name = "tlv320dac33";
- codec->owner = THIS_MODULE;
- codec->read = dac33_read_reg_cache;
- codec->write = dac33_write_locked;
- codec->hw_write = (hw_write_t) i2c_master_send;
- codec->bias_level = SND_SOC_BIAS_OFF;
- codec->set_bias_level = dac33_set_bias_level;
- codec->idle_bias_off = 1;
- codec->dai = &dac33_dai;
- codec->num_dai = 1;
- codec->reg_cache_size = ARRAY_SIZE(dac33_reg);
- codec->reg_cache = kmemdup(dac33_reg, ARRAY_SIZE(dac33_reg),
- GFP_KERNEL);
- if (codec->reg_cache == NULL) {
- ret = -ENOMEM;
- goto error_reg;
- }
i2c_set_clientdata(client, dac33);
@@ -1561,125 +1542,59 @@ static int __devinit dac33_i2c_probe(struct i2c_client *client,
/* Disable FIFO use by default */
dac33->fifo_mode = DAC33_FIFO_BYPASS;
- tlv320dac33_codec = codec;
-
- codec->dev = &client->dev;
- dac33_dai.dev = codec->dev;
-
/* Check if the reset GPIO number is valid and request it */
if (dac33->power_gpio >= 0) {
ret = gpio_request(dac33->power_gpio, "tlv320dac33 reset");
if (ret < 0) {
- dev_err(codec->dev,
+ dev_err(&client->dev,
"Failed to request reset GPIO (%d)\n",
dac33->power_gpio);
- snd_soc_unregister_dai(&dac33_dai);
- snd_soc_unregister_codec(codec);
- goto error_gpio;
+ goto err_gpio;
}
gpio_direction_output(dac33->power_gpio, 0);
}
- /* Check if the IRQ number is valid and request it */
- if (dac33->irq >= 0) {
- ret = request_irq(dac33->irq, dac33_interrupt_handler,
- IRQF_TRIGGER_RISING | IRQF_DISABLED,
- codec->name, codec);
- if (ret < 0) {
- dev_err(codec->dev, "Could not request IRQ%d (%d)\n",
- dac33->irq, ret);
- dac33->irq = -1;
- }
- if (dac33->irq != -1) {
- /* Setup work queue */
- dac33->dac33_wq =
- create_singlethread_workqueue("tlv320dac33");
- if (dac33->dac33_wq == NULL) {
- free_irq(dac33->irq, &dac33->codec);
- ret = -ENOMEM;
- goto error_wq;
- }
-
- INIT_WORK(&dac33->work, dac33_work);
- }
- }
-
for (i = 0; i < ARRAY_SIZE(dac33->supplies); i++)
dac33->supplies[i].supply = dac33_supply_names[i];
- ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(dac33->supplies),
+ ret = regulator_bulk_get(&client->dev, ARRAY_SIZE(dac33->supplies),
dac33->supplies);
if (ret != 0) {
- dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
+ dev_err(&client->dev, "Failed to request supplies: %d\n", ret);
goto err_get;
}
- /* Read the tlv320dac33 ID registers */
- ret = dac33_hard_power(codec, 1);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to power up codec: %d\n", ret);
- goto error_codec;
- }
- dac33_read_id(codec);
- dac33_hard_power(codec, 0);
-
- ret = snd_soc_register_codec(codec);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to register codec: %d\n", ret);
- goto error_codec;
- }
-
- ret = snd_soc_register_dai(&dac33_dai);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
- snd_soc_unregister_codec(codec);
- goto error_codec;
- }
+ ret = snd_soc_register_codec(&client->dev,
+ &soc_codec_dev_tlv320dac33, &dac33_dai, 1);
+ if (ret < 0)
+ goto err_register;
return ret;
-
-error_codec:
+err_register:
regulator_bulk_free(ARRAY_SIZE(dac33->supplies), dac33->supplies);
err_get:
- if (dac33->irq >= 0) {
- free_irq(dac33->irq, &dac33->codec);
- destroy_workqueue(dac33->dac33_wq);
- }
-error_wq:
if (dac33->power_gpio >= 0)
gpio_free(dac33->power_gpio);
-error_gpio:
- kfree(codec->reg_cache);
-error_reg:
- tlv320dac33_codec = NULL;
+err_gpio:
kfree(dac33);
-
return ret;
}
static int __devexit dac33_i2c_remove(struct i2c_client *client)
{
- struct tlv320dac33_priv *dac33;
-
- dac33 = i2c_get_clientdata(client);
+ struct tlv320dac33_priv *dac33 = i2c_get_clientdata(client);
if (unlikely(dac33->chip_power))
- dac33_hard_power(&dac33->codec, 0);
+ dac33_hard_power(dac33->codec, 0);
if (dac33->power_gpio >= 0)
gpio_free(dac33->power_gpio);
- if (dac33->irq >= 0)
- free_irq(dac33->irq, &dac33->codec);
regulator_bulk_free(ARRAY_SIZE(dac33->supplies), dac33->supplies);
- destroy_workqueue(dac33->dac33_wq);
- snd_soc_unregister_dai(&dac33_dai);
- snd_soc_unregister_codec(&dac33->codec);
- kfree(dac33->codec.reg_cache);
+ snd_soc_unregister_codec(&client->dev);
kfree(dac33);
- tlv320dac33_codec = NULL;
return 0;
}
@@ -1694,7 +1609,7 @@ static const struct i2c_device_id tlv320dac33_i2c_id[] = {
static struct i2c_driver tlv320dac33_i2c_driver = {
.driver = {
- .name = "tlv320dac33",
+ .name = "tlv320dac33-codec",
.owner = THIS_MODULE,
},
.probe = dac33_i2c_probe,
diff --git a/sound/soc/codecs/tlv320dac33.h b/sound/soc/codecs/tlv320dac33.h
index eb8ae07f0bd2..7c318b5da437 100644
--- a/sound/soc/codecs/tlv320dac33.h
+++ b/sound/soc/codecs/tlv320dac33.h
@@ -261,7 +261,4 @@
#define TLV320DAC33_MCLK 0
#define TLV320DAC33_SLEEPCLK 1
-extern struct snd_soc_dai dac33_dai;
-extern struct snd_soc_codec_device soc_codec_dev_tlv320dac33;
-
#endif /* __TLV320DAC33_H */
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c
index 7b618bbff884..898430f44f9d 100644
--- a/sound/soc/codecs/twl4030.c
+++ b/sound/soc/codecs/twl4030.c
@@ -36,7 +36,16 @@
#include <sound/initval.h>
#include <sound/tlv.h>
-#include "twl4030.h"
+/* Register descriptions are here */
+#include <linux/mfd/twl4030-codec.h>
+
+/* Shadow register used by the audio driver */
+#define TWL4030_REG_SW_SHADOW 0x4A
+#define TWL4030_CACHEREGNUM (TWL4030_REG_SW_SHADOW + 1)
+
+/* TWL4030_REG_SW_SHADOW (0x4A) Fields */
+#define TWL4030_HFL_EN 0x01
+#define TWL4030_HFR_EN 0x02
/*
* twl4030 register cache & default register settings
@@ -277,21 +286,19 @@ static inline void twl4030_reset_registers(struct snd_soc_codec *codec)
}
-static void twl4030_init_chip(struct platform_device *pdev)
+static void twl4030_init_chip(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct twl4030_setup_data *setup = socdev->codec_data;
- struct snd_soc_codec *codec = socdev->card->codec;
+ struct twl4030_codec_audio_data *pdata = dev_get_platdata(codec->dev);
struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
u8 reg, byte;
int i = 0;
/* Check defaults, if instructed before anything else */
- if (setup && setup->check_defaults)
+ if (pdata && pdata->check_defaults)
twl4030_check_defaults(codec);
/* Reset registers, if no setup data or if instructed to do so */
- if (!setup || (setup && setup->reset_registers))
+ if (!pdata || (pdata && pdata->reset_registers))
twl4030_reset_registers(codec);
/* Refresh APLL_CTL register from HW */
@@ -312,20 +319,14 @@ static void twl4030_init_chip(struct platform_device *pdev)
twl4030_write(codec, TWL4030_REG_ARXR2_APGA_CTL, 0x32);
/* Machine dependent setup */
- if (!setup)
+ if (!pdata)
return;
- twl4030->digimic_delay = setup->digimic_delay;
-
- /* Configuration for headset ramp delay from setup data */
- if (setup->sysclk != twl4030->sysclk)
- dev_warn(codec->dev,
- "Mismatch in APLL mclk: %u (configured: %u)\n",
- setup->sysclk, twl4030->sysclk);
+ twl4030->digimic_delay = pdata->digimic_delay;
reg = twl4030_read_reg_cache(codec, TWL4030_REG_HS_POPN_SET);
reg &= ~TWL4030_RAMP_DELAY;
- reg |= (setup->ramp_delay_value << 2);
+ reg |= (pdata->ramp_delay_value << 2);
twl4030_write_reg_cache(codec, TWL4030_REG_HS_POPN_SET, reg);
/* initiate offset cancellation */
@@ -333,7 +334,7 @@ static void twl4030_init_chip(struct platform_device *pdev)
reg = twl4030_read_reg_cache(codec, TWL4030_REG_ANAMICL);
reg &= ~TWL4030_OFFSET_CNCL_SEL;
- reg |= setup->offset_cncl_path;
+ reg |= pdata->offset_cncl_path;
twl4030_write(codec, TWL4030_REG_ANAMICL,
reg | TWL4030_CNCL_OFFSET_START);
@@ -718,9 +719,7 @@ static int aif_event(struct snd_soc_dapm_widget *w,
static void headset_ramp(struct snd_soc_codec *codec, int ramp)
{
- struct snd_soc_device *socdev = codec->socdev;
- struct twl4030_setup_data *setup = socdev->codec_data;
-
+ struct twl4030_codec_audio_data *pdata = codec->dev->platform_data;
unsigned char hs_gain, hs_pop;
struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
/* Base values for ramp delay calculation: 2^19 - 2^26 */
@@ -732,9 +731,9 @@ static void headset_ramp(struct snd_soc_codec *codec, int ramp)
/* Enable external mute control, this dramatically reduces
* the pop-noise */
- if (setup && setup->hs_extmute) {
- if (setup->set_hs_extmute) {
- setup->set_hs_extmute(1);
+ if (pdata && pdata->hs_extmute) {
+ if (pdata->set_hs_extmute) {
+ pdata->set_hs_extmute(1);
} else {
hs_pop |= TWL4030_EXTMUTE;
twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
@@ -772,9 +771,9 @@ static void headset_ramp(struct snd_soc_codec *codec, int ramp)
}
/* Disable external mute */
- if (setup && setup->hs_extmute) {
- if (setup->set_hs_extmute) {
- setup->set_hs_extmute(0);
+ if (pdata && pdata->hs_extmute) {
+ if (pdata->set_hs_extmute) {
+ pdata->set_hs_extmute(0);
} else {
hs_pop &= ~TWL4030_EXTMUTE;
twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
@@ -1707,8 +1706,7 @@ static int twl4030_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 twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
if (twl4030->master_substream) {
@@ -1738,8 +1736,7 @@ static void twl4030_shutdown(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 twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
if (twl4030->master_substream == substream)
@@ -1764,8 +1761,7 @@ static int twl4030_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 twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
u8 mode, old_mode, format, old_format;
@@ -1999,8 +1995,7 @@ static int twl4030_voice_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 twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
u8 mode;
@@ -2033,8 +2028,7 @@ static void twl4030_voice_shutdown(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;
/* Enable voice digital filters */
twl4030_voice_enable(codec, substream->stream, 0);
@@ -2044,8 +2038,7 @@ static int twl4030_voice_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params, 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 twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
u8 old_mode, mode;
@@ -2175,7 +2168,7 @@ static int twl4030_voice_set_tristate(struct snd_soc_dai *dai, int tristate)
#define TWL4030_RATES (SNDRV_PCM_RATE_8000_48000)
#define TWL4030_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FORMAT_S24_LE)
-static struct snd_soc_dai_ops twl4030_dai_ops = {
+static struct snd_soc_dai_ops twl4030_dai_hifi_ops = {
.startup = twl4030_startup,
.shutdown = twl4030_shutdown,
.hw_params = twl4030_hw_params,
@@ -2193,9 +2186,9 @@ static struct snd_soc_dai_ops twl4030_dai_voice_ops = {
.set_tristate = twl4030_voice_set_tristate,
};
-struct snd_soc_dai twl4030_dai[] = {
+static struct snd_soc_dai_driver twl4030_dai[] = {
{
- .name = "twl4030",
+ .name = "twl4030-hifi",
.playback = {
.stream_name = "HiFi Playback",
.channels_min = 2,
@@ -2208,10 +2201,10 @@ struct snd_soc_dai twl4030_dai[] = {
.channels_max = 4,
.rates = TWL4030_RATES,
.formats = TWL4030_FORMATS,},
- .ops = &twl4030_dai_ops,
+ .ops = &twl4030_dai_hifi_ops,
},
{
- .name = "twl4030 Voice",
+ .name = "twl4030-voice",
.playback = {
.stream_name = "Voice Playback",
.channels_min = 1,
@@ -2227,164 +2220,90 @@ struct snd_soc_dai twl4030_dai[] = {
.ops = &twl4030_dai_voice_ops,
},
};
-EXPORT_SYMBOL_GPL(twl4030_dai);
-static int twl4030_soc_suspend(struct platform_device *pdev, pm_message_t state)
+static int twl4030_soc_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;
-
twl4030_set_bias_level(codec, SND_SOC_BIAS_OFF);
-
return 0;
}
-static int twl4030_soc_resume(struct platform_device *pdev)
+static int twl4030_soc_resume(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec = socdev->card->codec;
-
twl4030_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
return 0;
}
-static struct snd_soc_codec *twl4030_codec;
-
-static int twl4030_soc_probe(struct platform_device *pdev)
+static int twl4030_soc_probe(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec;
- int ret;
-
- BUG_ON(!twl4030_codec);
-
- codec = twl4030_codec;
- socdev->card->codec = codec;
-
- twl4030_init_chip(pdev);
+ struct twl4030_priv *twl4030;
- /* 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;
+ twl4030 = kzalloc(sizeof(struct twl4030_priv), GFP_KERNEL);
+ if (twl4030 == NULL) {
+ printk("Can not allocate memroy\n");
+ return -ENOMEM;
}
+ snd_soc_codec_set_drvdata(codec, twl4030);
+ /* Set the defaults, and power up the codec */
+ twl4030->sysclk = twl4030_codec_get_mclk() / 1000;
+ codec->bias_level = SND_SOC_BIAS_OFF;
+ codec->idle_bias_off = 1;
+
+ twl4030_init_chip(codec);
snd_soc_add_controls(codec, twl4030_snd_controls,
ARRAY_SIZE(twl4030_snd_controls));
twl4030_add_widgets(codec);
-
return 0;
}
-static int twl4030_soc_remove(struct platform_device *pdev)
+static int twl4030_soc_remove(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec = socdev->card->codec;
-
- /* Reset registers to their chip default before leaving */
- twl4030_reset_registers(codec);
twl4030_set_bias_level(codec, SND_SOC_BIAS_OFF);
- snd_soc_free_pcms(socdev);
- snd_soc_dapm_free(socdev);
-
return 0;
}
+static struct snd_soc_codec_driver soc_codec_dev_twl4030 = {
+ .probe = twl4030_soc_probe,
+ .remove = twl4030_soc_remove,
+ .suspend = twl4030_soc_suspend,
+ .resume = twl4030_soc_resume,
+ .read = twl4030_read_reg_cache,
+ .write = twl4030_write,
+ .set_bias_level = twl4030_set_bias_level,
+ .reg_cache_size = sizeof(twl4030_reg),
+ .reg_word_size = sizeof(u8),
+ .reg_cache_default = twl4030_reg,
+};
+
static int __devinit twl4030_codec_probe(struct platform_device *pdev)
{
struct twl4030_codec_audio_data *pdata = pdev->dev.platform_data;
- struct snd_soc_codec *codec;
- struct twl4030_priv *twl4030;
- int ret;
if (!pdata) {
dev_err(&pdev->dev, "platform_data is missing\n");
return -EINVAL;
}
- twl4030 = kzalloc(sizeof(struct twl4030_priv), GFP_KERNEL);
- if (twl4030 == NULL) {
- dev_err(&pdev->dev, "Can not allocate memroy\n");
- return -ENOMEM;
- }
-
- codec = &twl4030->codec;
- snd_soc_codec_set_drvdata(codec, twl4030);
- codec->dev = &pdev->dev;
- twl4030_dai[0].dev = &pdev->dev;
- twl4030_dai[1].dev = &pdev->dev;
-
- mutex_init(&codec->mutex);
- INIT_LIST_HEAD(&codec->dapm_widgets);
- INIT_LIST_HEAD(&codec->dapm_paths);
-
- codec->name = "twl4030";
- codec->owner = THIS_MODULE;
- codec->read = twl4030_read_reg_cache;
- codec->write = twl4030_write;
- codec->set_bias_level = twl4030_set_bias_level;
- codec->idle_bias_off = 1;
- codec->dai = twl4030_dai;
- codec->num_dai = ARRAY_SIZE(twl4030_dai);
- codec->reg_cache_size = sizeof(twl4030_reg);
- codec->reg_cache = kmemdup(twl4030_reg, sizeof(twl4030_reg),
- GFP_KERNEL);
- if (codec->reg_cache == NULL) {
- ret = -ENOMEM;
- goto error_cache;
- }
-
- platform_set_drvdata(pdev, twl4030);
- twl4030_codec = codec;
-
- /* Set the defaults, and power up the codec */
- twl4030->sysclk = twl4030_codec_get_mclk() / 1000;
- codec->bias_level = SND_SOC_BIAS_OFF;
-
- ret = snd_soc_register_codec(codec);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to register codec: %d\n", ret);
- goto error_codec;
- }
-
- ret = snd_soc_register_dais(&twl4030_dai[0], ARRAY_SIZE(twl4030_dai));
- if (ret != 0) {
- dev_err(codec->dev, "Failed to register DAIs: %d\n", ret);
- snd_soc_unregister_codec(codec);
- goto error_codec;
- }
-
- return 0;
-
-error_codec:
- twl4030_codec_enable(codec, 0);
- kfree(codec->reg_cache);
-error_cache:
- kfree(twl4030);
- return ret;
+ return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_twl4030,
+ twl4030_dai, ARRAY_SIZE(twl4030_dai));
}
static int __devexit twl4030_codec_remove(struct platform_device *pdev)
{
- struct twl4030_priv *twl4030 = platform_get_drvdata(pdev);
+ struct twl4030_priv *twl4030 = dev_get_drvdata(&pdev->dev);
- snd_soc_unregister_dais(&twl4030_dai[0], ARRAY_SIZE(twl4030_dai));
- snd_soc_unregister_codec(&twl4030->codec);
- kfree(twl4030->codec.reg_cache);
+ snd_soc_unregister_codec(&pdev->dev);
kfree(twl4030);
-
- twl4030_codec = NULL;
return 0;
}
-MODULE_ALIAS("platform:twl4030_codec_audio");
+MODULE_ALIAS("platform:twl4030-codec");
static struct platform_driver twl4030_codec_driver = {
.probe = twl4030_codec_probe,
.remove = __devexit_p(twl4030_codec_remove),
.driver = {
- .name = "twl4030_codec_audio",
+ .name = "twl4030-codec",
.owner = THIS_MODULE,
},
};
@@ -2401,14 +2320,6 @@ static void __exit twl4030_exit(void)
}
module_exit(twl4030_exit);
-struct snd_soc_codec_device soc_codec_dev_twl4030 = {
- .probe = twl4030_soc_probe,
- .remove = twl4030_soc_remove,
- .suspend = twl4030_soc_suspend,
- .resume = twl4030_soc_resume,
-};
-EXPORT_SYMBOL_GPL(soc_codec_dev_twl4030);
-
MODULE_DESCRIPTION("ASoC TWL4030 codec driver");
MODULE_AUTHOR("Steve Sakoman");
MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/twl4030.h b/sound/soc/codecs/twl4030.h
deleted file mode 100644
index 6c57430f6e24..000000000000
--- a/sound/soc/codecs/twl4030.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * ALSA SoC TWL4030 codec driver
- *
- * Author: Steve Sakoman <steve@sakoman.com>
- *
- * 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.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef __TWL4030_AUDIO_H__
-#define __TWL4030_AUDIO_H__
-
-/* Register descriptions are here */
-#include <linux/mfd/twl4030-codec.h>
-
-/* Shadow register used by the audio driver */
-#define TWL4030_REG_SW_SHADOW 0x4A
-#define TWL4030_CACHEREGNUM (TWL4030_REG_SW_SHADOW + 1)
-
-/* TWL4030_REG_SW_SHADOW (0x4A) Fields */
-#define TWL4030_HFL_EN 0x01
-#define TWL4030_HFR_EN 0x02
-
-#define TWL4030_DAI_HIFI 0
-#define TWL4030_DAI_VOICE 1
-
-extern struct snd_soc_dai twl4030_dai[2];
-extern struct snd_soc_codec_device soc_codec_dev_twl4030;
-
-struct twl4030_setup_data {
- unsigned int ramp_delay_value;
- unsigned int digimic_delay; /* in ms */
- unsigned int sysclk;
- unsigned int offset_cncl_path;
- unsigned int check_defaults:1;
- unsigned int reset_registers:1;
- unsigned int hs_extmute:1;
- void (*set_hs_extmute)(int mute);
-};
-
-#endif /* End of __TWL4030_AUDIO_H__ */
-
-
diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c
index 64a807f1a8a1..10f6e5214511 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,
diff --git a/sound/soc/codecs/twl6040.h b/sound/soc/codecs/twl6040.h
index c472070a1da2..f7c77fa58a3c 100644
--- a/sound/soc/codecs/twl6040.h
+++ b/sound/soc/codecs/twl6040.h
@@ -135,7 +135,4 @@
#define TWL6040_HPPLL_ID 1
#define TWL6040_LPPLL_ID 2
-extern struct snd_soc_dai twl6040_dai;
-extern struct snd_soc_codec_device soc_codec_dev_twl6040;
-
#endif /* End of __TWL6040_H__ */
diff --git a/sound/soc/codecs/uda134x.c b/sound/soc/codecs/uda134x.c
index f3b4c1d6a82d..7540a509a6f5 100644
--- a/sound/soc/codecs/uda134x.c
+++ b/sound/soc/codecs/uda134x.c
@@ -161,8 +161,7 @@ static int uda134x_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 uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec);
struct snd_pcm_runtime *master_runtime;
@@ -194,8 +193,7 @@ static void uda134x_shutdown(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 uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec);
if (uda134x->master_substream == substream)
@@ -209,8 +207,7 @@ static int uda134x_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 uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec);
u8 hw_params;
@@ -364,7 +361,7 @@ static int uda134x_set_bias_level(struct snd_soc_codec *codec,
pd->power(1);
/* Sync reg_cache with the hardware */
for (i = 0; i < ARRAY_SIZE(uda134x_reg); i++)
- codec->write(codec, i, *cache++);
+ codec->driver->write(codec, i, *cache++);
}
break;
case SND_SOC_BIAS_STANDBY:
@@ -465,8 +462,8 @@ static struct snd_soc_dai_ops uda134x_dai_ops = {
.set_fmt = uda134x_set_dai_fmt,
};
-struct snd_soc_dai uda134x_dai = {
- .name = "UDA134X",
+static struct snd_soc_dai_driver uda134x_dai = {
+ .name = "uda134x-hifi",
/* playback capabilities */
.playback = {
.stream_name = "Playback",
@@ -486,27 +483,21 @@ struct snd_soc_dai uda134x_dai = {
/* pcm operations */
.ops = &uda134x_dai_ops,
};
-EXPORT_SYMBOL(uda134x_dai);
-
-static int uda134x_soc_probe(struct platform_device *pdev)
+static int uda134x_soc_probe(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec;
struct uda134x_priv *uda134x;
- void *codec_setup_data = socdev->codec_data;
- int ret = -ENOMEM;
- struct uda134x_platform_data *pd;
+ struct uda134x_platform_data *pd = dev_get_drvdata(codec->card->dev);
+ int ret;
printk(KERN_INFO "UDA134X SoC Audio Codec\n");
- if (!codec_setup_data) {
+ if (!pd) {
printk(KERN_ERR "UDA134X SoC codec: "
"missing L3 bitbang function\n");
return -ENODEV;
}
- pd = codec_setup_data;
switch (pd->model) {
case UDA134X_UDA1340:
case UDA134X_UDA1341:
@@ -520,58 +511,22 @@ static int uda134x_soc_probe(struct platform_device *pdev)
return -EINVAL;
}
- socdev->card->codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
- if (socdev->card->codec == NULL)
- return ret;
-
- codec = socdev->card->codec;
-
uda134x = kzalloc(sizeof(struct uda134x_priv), GFP_KERNEL);
if (uda134x == NULL)
- goto priv_err;
+ return -ENOMEM;
snd_soc_codec_set_drvdata(codec, uda134x);
- codec->reg_cache = kmemdup(uda134x_reg, sizeof(uda134x_reg),
- GFP_KERNEL);
- if (codec->reg_cache == NULL)
- goto reg_err;
-
- mutex_init(&codec->mutex);
-
- codec->reg_cache_size = sizeof(uda134x_reg);
- codec->reg_cache_step = 1;
-
- codec->name = "UDA134X";
- codec->owner = THIS_MODULE;
- codec->dai = &uda134x_dai;
- codec->num_dai = 1;
- codec->read = uda134x_read_reg_cache;
- codec->write = uda134x_write;
-
- INIT_LIST_HEAD(&codec->dapm_widgets);
- INIT_LIST_HEAD(&codec->dapm_paths);
-
- codec->control_data = codec_setup_data;
+ codec->control_data = pd;
if (pd->power)
pd->power(1);
uda134x_reset(codec);
- if (pd->is_powered_on_standby) {
- codec->set_bias_level = NULL;
+ if (pd->is_powered_on_standby)
uda134x_set_bias_level(codec, SND_SOC_BIAS_ON);
- } else {
- codec->set_bias_level = uda134x_set_bias_level;
+ else
uda134x_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
- }
-
- /* register pcms */
- ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
- if (ret < 0) {
- printk(KERN_ERR "UDA134X: failed to register pcms\n");
- goto pcm_err;
- }
switch (pd->model) {
case UDA134X_UDA1340:
@@ -590,61 +545,42 @@ static int uda134x_soc_probe(struct platform_device *pdev)
default:
printk(KERN_ERR "%s unknown codec type: %d",
__func__, pd->model);
- return -EINVAL;
+ kfree(uda134x);
+ return -EINVAL;
}
if (ret < 0) {
printk(KERN_ERR "UDA134X: failed to register controls\n");
- goto pcm_err;
+ kfree(uda134x);
+ return ret;
}
return 0;
-
-pcm_err:
- kfree(codec->reg_cache);
-reg_err:
- kfree(snd_soc_codec_get_drvdata(codec));
-priv_err:
- kfree(codec);
- return ret;
}
/* power down chip */
-static int uda134x_soc_remove(struct platform_device *pdev)
+static int uda134x_soc_remove(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec = socdev->card->codec;
+ struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec);
uda134x_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
uda134x_set_bias_level(codec, SND_SOC_BIAS_OFF);
- snd_soc_free_pcms(socdev);
- snd_soc_dapm_free(socdev);
-
- kfree(snd_soc_codec_get_drvdata(codec));
- kfree(codec->reg_cache);
- kfree(codec);
-
+ kfree(uda134x);
return 0;
}
#if defined(CONFIG_PM)
-static int uda134x_soc_suspend(struct platform_device *pdev,
+static int uda134x_soc_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;
-
uda134x_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
uda134x_set_bias_level(codec, SND_SOC_BIAS_OFF);
return 0;
}
-static int uda134x_soc_resume(struct platform_device *pdev)
+static int uda134x_soc_resume(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec = socdev->card->codec;
-
uda134x_set_bias_level(codec, SND_SOC_BIAS_PREPARE);
uda134x_set_bias_level(codec, SND_SOC_BIAS_ON);
return 0;
@@ -654,25 +590,53 @@ static int uda134x_soc_resume(struct platform_device *pdev)
#define uda134x_soc_resume NULL
#endif /* CONFIG_PM */
-struct snd_soc_codec_device soc_codec_dev_uda134x = {
+static struct snd_soc_codec_driver soc_codec_dev_uda134x = {
.probe = uda134x_soc_probe,
.remove = uda134x_soc_remove,
.suspend = uda134x_soc_suspend,
.resume = uda134x_soc_resume,
+ .reg_cache_size = sizeof(uda134x_reg),
+ .reg_word_size = sizeof(u8),
+ .reg_cache_step = 1,
+ .read = uda134x_read_reg_cache,
+ .write = uda134x_write,
+#ifdef POWER_OFF_ON_STANDBY
+ .set_bias_level = uda134x_set_bias_level,
+#endif
+};
+
+static int __devinit uda134x_codec_probe(struct platform_device *pdev)
+{
+ return snd_soc_register_codec(&pdev->dev,
+ &soc_codec_dev_uda134x, &uda134x_dai, 1);
+}
+
+static int __devexit uda134x_codec_remove(struct platform_device *pdev)
+{
+ snd_soc_unregister_codec(&pdev->dev);
+ return 0;
+}
+
+static struct platform_driver uda134x_codec_driver = {
+ .driver = {
+ .name = "uda134x-codec",
+ .owner = THIS_MODULE,
+ },
+ .probe = uda134x_codec_probe,
+ .remove = __devexit_p(uda134x_codec_remove),
};
-EXPORT_SYMBOL_GPL(soc_codec_dev_uda134x);
-static int __init uda134x_init(void)
+static int __init uda134x_codec_init(void)
{
- return snd_soc_register_dai(&uda134x_dai);
+ return platform_driver_register(&uda134x_codec_driver);
}
-module_init(uda134x_init);
+module_init(uda134x_codec_init);
-static void __exit uda134x_exit(void)
+static void __exit uda134x_codec_exit(void)
{
- snd_soc_unregister_dai(&uda134x_dai);
+ platform_driver_unregister(&uda134x_codec_driver);
}
-module_exit(uda134x_exit);
+module_exit(uda134x_codec_exit);
MODULE_DESCRIPTION("UDA134X ALSA soc codec driver");
MODULE_AUTHOR("Zoltan Devai, Christian Pellegrin <chripell@evolware.org>");
diff --git a/sound/soc/codecs/uda134x.h b/sound/soc/codecs/uda134x.h
index 205f03b3eaf8..9faae06972b3 100644
--- a/sound/soc/codecs/uda134x.h
+++ b/sound/soc/codecs/uda134x.h
@@ -31,7 +31,4 @@
#define STATUS0_DAIFMT_MASK (~(7<<1))
#define STATUS0_SYSCLK_MASK (~(3<<4))
-extern struct snd_soc_dai uda134x_dai;
-extern struct snd_soc_codec_device soc_codec_dev_uda134x;
-
#endif
diff --git a/sound/soc/codecs/uda1380.c b/sound/soc/codecs/uda1380.c
index 2f925a27dcde..1a51c816e542 100644
--- a/sound/soc/codecs/uda1380.c
+++ b/sound/soc/codecs/uda1380.c
@@ -33,11 +33,9 @@
#include "uda1380.h"
-static struct snd_soc_codec *uda1380_codec;
-
/* codec private data */
struct uda1380_priv {
- struct snd_soc_codec codec;
+ struct snd_soc_codec *codec;
u16 reg_cache[UDA1380_CACHEREGNUM];
unsigned int dac_clk;
struct work_struct work;
@@ -135,6 +133,8 @@ static int uda1380_write(struct snd_soc_codec *codec, unsigned int reg,
static void uda1380_flush_work(struct work_struct *work)
{
+ struct uda1380_priv *uda1380 = container_of(work, struct uda1380_priv, work);
+ struct snd_soc_codec *uda1380_codec = uda1380->codec;
int bit, reg;
for_each_set_bit(bit, &uda1380_cache_dirty, UDA1380_CACHEREGNUM - 0x10) {
@@ -145,6 +145,7 @@ static void uda1380_flush_work(struct work_struct *work)
uda1380_read_reg_cache(uda1380_codec, reg));
clear_bit(bit, &uda1380_cache_dirty);
}
+
}
/* declarations of ALSA reg_elem_REAL controls */
@@ -474,8 +475,7 @@ static int uda1380_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 uda1380_priv *uda1380 = snd_soc_codec_get_drvdata(codec);
int mixer = uda1380_read_reg_cache(codec, UDA1380_MIXER);
@@ -501,8 +501,7 @@ static int uda1380_pcm_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;
u16 clk = uda1380_read_reg_cache(codec, UDA1380_CLK);
/* set WSPLL power and divider if running from this clock */
@@ -540,8 +539,7 @@ static void uda1380_pcm_shutdown(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;
u16 clk = uda1380_read_reg_cache(codec, UDA1380_CLK);
/* shut down WSPLL power if running from this clock */
@@ -604,9 +602,9 @@ static struct snd_soc_dai_ops uda1380_dai_ops_capture = {
.set_fmt = uda1380_set_dai_fmt_capture,
};
-struct snd_soc_dai uda1380_dai[] = {
+static struct snd_soc_dai_driver uda1380_dai[] = {
{
- .name = "UDA1380",
+ .name = "uda1380-hifi",
.playback = {
.stream_name = "Playback",
.channels_min = 1,
@@ -622,7 +620,7 @@ struct snd_soc_dai uda1380_dai[] = {
.ops = &uda1380_dai_ops,
},
{ /* playback only - dual interface */
- .name = "UDA1380",
+ .name = "uda1380-hifi-playback",
.playback = {
.stream_name = "Playback",
.channels_min = 1,
@@ -633,7 +631,7 @@ struct snd_soc_dai uda1380_dai[] = {
.ops = &uda1380_dai_ops_playback,
},
{ /* capture only - dual interface*/
- .name = "UDA1380",
+ .name = "uda1380-hifi-capture",
.capture = {
.stream_name = "Capture",
.channels_min = 1,
@@ -644,21 +642,15 @@ struct snd_soc_dai uda1380_dai[] = {
.ops = &uda1380_dai_ops_capture,
},
};
-EXPORT_SYMBOL_GPL(uda1380_dai);
-static int uda1380_suspend(struct platform_device *pdev, pm_message_t state)
+static int uda1380_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;
-
uda1380_set_bias_level(codec, SND_SOC_BIAS_OFF);
return 0;
}
-static int uda1380_resume(struct platform_device *pdev)
+static int uda1380_resume(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec = socdev->card->codec;
int i;
u8 data[2];
u16 *cache = codec->reg_cache;
@@ -673,91 +665,20 @@ static int uda1380_resume(struct platform_device *pdev)
return 0;
}
-static int uda1380_probe(struct platform_device *pdev)
-{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec;
- struct uda1380_platform_data *pdata;
- int ret = 0;
-
- if (uda1380_codec == NULL) {
- dev_err(&pdev->dev, "Codec device not registered\n");
- return -ENODEV;
- }
-
- socdev->card->codec = uda1380_codec;
- codec = uda1380_codec;
- pdata = codec->dev->platform_data;
-
- /* register pcms */
- ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
- if (ret < 0) {
- dev_err(codec->dev, "failed to create pcms: %d\n", ret);
- goto pcm_err;
- }
-
- /* power on device */
- uda1380_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
- /* set clock input */
- switch (pdata->dac_clk) {
- case UDA1380_DAC_CLK_SYSCLK:
- uda1380_write(codec, UDA1380_CLK, 0);
- break;
- case UDA1380_DAC_CLK_WSPLL:
- uda1380_write(codec, UDA1380_CLK, R00_DAC_CLK);
- break;
- }
-
- snd_soc_add_controls(codec, uda1380_snd_controls,
- ARRAY_SIZE(uda1380_snd_controls));
- uda1380_add_widgets(codec);
-
- return ret;
-
-pcm_err:
- return ret;
-}
-
-/* power down chip */
-static int uda1380_remove(struct platform_device *pdev)
-{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec = socdev->card->codec;
-
- if (codec->control_data)
- uda1380_set_bias_level(codec, SND_SOC_BIAS_OFF);
-
- snd_soc_free_pcms(socdev);
- snd_soc_dapm_free(socdev);
-
- return 0;
-}
-
-struct snd_soc_codec_device soc_codec_dev_uda1380 = {
- .probe = uda1380_probe,
- .remove = uda1380_remove,
- .suspend = uda1380_suspend,
- .resume = uda1380_resume,
-};
-EXPORT_SYMBOL_GPL(soc_codec_dev_uda1380);
-
-static int uda1380_register(struct uda1380_priv *uda1380)
+static int uda1380_probe(struct snd_soc_codec *codec)
{
- int ret, i;
- struct snd_soc_codec *codec = &uda1380->codec;
- struct uda1380_platform_data *pdata = codec->dev->platform_data;
+ struct uda1380_platform_data *pdata =codec->dev->platform_data;
+ struct uda1380_priv *uda1380 = snd_soc_codec_get_drvdata(codec);
+ int ret;
- if (uda1380_codec) {
- dev_err(codec->dev, "Another UDA1380 is registered\n");
- return -EINVAL;
- }
+ codec->hw_write = (hw_write_t)i2c_master_send;
if (!pdata || !pdata->gpio_power || !pdata->gpio_reset)
return -EINVAL;
ret = gpio_request(pdata->gpio_power, "uda1380 power");
if (ret)
- goto err_out;
+ return ret;
ret = gpio_request(pdata->gpio_reset, "uda1380 reset");
if (ret)
goto err_gpio;
@@ -769,25 +690,6 @@ static int uda1380_register(struct uda1380_priv *uda1380)
udelay(5);
gpio_set_value(pdata->gpio_reset, 0);
- mutex_init(&codec->mutex);
- INIT_LIST_HEAD(&codec->dapm_widgets);
- INIT_LIST_HEAD(&codec->dapm_paths);
-
- snd_soc_codec_set_drvdata(codec, uda1380);
- codec->name = "UDA1380";
- codec->owner = THIS_MODULE;
- codec->read = uda1380_read_reg_cache;
- codec->write = uda1380_write;
- codec->bias_level = SND_SOC_BIAS_OFF;
- codec->set_bias_level = uda1380_set_bias_level;
- codec->dai = uda1380_dai;
- codec->num_dai = ARRAY_SIZE(uda1380_dai);
- codec->reg_cache_size = ARRAY_SIZE(uda1380_reg);
- codec->reg_cache = &uda1380->reg_cache;
- codec->reg_cache_step = 1;
-
- memcpy(codec->reg_cache, uda1380_reg, sizeof(uda1380_reg));
-
ret = uda1380_reset(codec);
if (ret < 0) {
dev_err(codec->dev, "Failed to issue reset\n");
@@ -796,83 +698,84 @@ static int uda1380_register(struct uda1380_priv *uda1380)
INIT_WORK(&uda1380->work, uda1380_flush_work);
- for (i = 0; i < ARRAY_SIZE(uda1380_dai); i++)
- uda1380_dai[i].dev = codec->dev;
-
- uda1380_codec = codec;
-
- ret = snd_soc_register_codec(codec);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to register codec: %d\n", ret);
- goto err_reset;
+ /* power on device */
+ uda1380_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+ /* set clock input */
+ switch (pdata->dac_clk) {
+ case UDA1380_DAC_CLK_SYSCLK:
+ uda1380_write(codec, UDA1380_CLK, 0);
+ break;
+ case UDA1380_DAC_CLK_WSPLL:
+ uda1380_write(codec, UDA1380_CLK, R00_DAC_CLK);
+ break;
}
- ret = snd_soc_register_dais(uda1380_dai, ARRAY_SIZE(uda1380_dai));
- if (ret != 0) {
- dev_err(codec->dev, "Failed to register DAIs: %d\n", ret);
- goto err_dai;
- }
+ snd_soc_add_controls(codec, uda1380_snd_controls,
+ ARRAY_SIZE(uda1380_snd_controls));
+ uda1380_add_widgets(codec);
return 0;
-err_dai:
- snd_soc_unregister_codec(codec);
err_reset:
gpio_set_value(pdata->gpio_power, 0);
gpio_free(pdata->gpio_reset);
err_gpio:
gpio_free(pdata->gpio_power);
-err_out:
return ret;
}
-static void uda1380_unregister(struct uda1380_priv *uda1380)
+/* power down chip */
+static int uda1380_remove(struct snd_soc_codec *codec)
{
- struct snd_soc_codec *codec = &uda1380->codec;
- struct uda1380_platform_data *pdata = codec->dev->platform_data;
+ struct uda1380_platform_data *pdata =codec->dev->platform_data;
- snd_soc_unregister_dais(uda1380_dai, ARRAY_SIZE(uda1380_dai));
- snd_soc_unregister_codec(&uda1380->codec);
+ uda1380_set_bias_level(codec, SND_SOC_BIAS_OFF);
gpio_set_value(pdata->gpio_power, 0);
gpio_free(pdata->gpio_reset);
gpio_free(pdata->gpio_power);
- kfree(uda1380);
- uda1380_codec = NULL;
+ return 0;
}
+static struct snd_soc_codec_driver soc_codec_dev_uda1380 = {
+ .probe = uda1380_probe,
+ .remove = uda1380_remove,
+ .suspend = uda1380_suspend,
+ .resume = uda1380_resume,
+ .read = uda1380_read_reg_cache,
+ .write = uda1380_write,
+ .set_bias_level = uda1380_set_bias_level,
+ .reg_cache_size = ARRAY_SIZE(uda1380_reg),
+ .reg_word_size = sizeof(u16),
+ .reg_cache_default = uda1380_reg,
+ .reg_cache_step = 1,
+};
+
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
static __devinit int uda1380_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
struct uda1380_priv *uda1380;
- struct snd_soc_codec *codec;
int ret;
uda1380 = kzalloc(sizeof(struct uda1380_priv), GFP_KERNEL);
if (uda1380 == NULL)
return -ENOMEM;
- codec = &uda1380->codec;
- codec->hw_write = (hw_write_t)i2c_master_send;
-
i2c_set_clientdata(i2c, uda1380);
- codec->control_data = i2c;
-
- codec->dev = &i2c->dev;
- ret = uda1380_register(uda1380);
- if (ret != 0)
+ ret = snd_soc_register_codec(&i2c->dev,
+ &soc_codec_dev_uda1380, uda1380_dai, ARRAY_SIZE(uda1380_dai));
+ if (ret < 0)
kfree(uda1380);
-
return ret;
}
static int __devexit uda1380_i2c_remove(struct i2c_client *i2c)
{
- struct uda1380_priv *uda1380 = i2c_get_clientdata(i2c);
- uda1380_unregister(uda1380);
+ snd_soc_unregister_codec(&i2c->dev);
+ kfree(i2c_get_clientdata(i2c));
return 0;
}
@@ -884,7 +787,7 @@ MODULE_DEVICE_TABLE(i2c, uda1380_i2c_id);
static struct i2c_driver uda1380_i2c_driver = {
.driver = {
- .name = "UDA1380 I2C Codec",
+ .name = "uda1380-codec",
.owner = THIS_MODULE,
},
.probe = uda1380_i2c_probe,
diff --git a/sound/soc/codecs/uda1380.h b/sound/soc/codecs/uda1380.h
index 9cefa8a54770..942e3927c72b 100644
--- a/sound/soc/codecs/uda1380.h
+++ b/sound/soc/codecs/uda1380.h
@@ -76,7 +76,4 @@
#define UDA1380_DAI_PLAYBACK 1 /* playback DAI */
#define UDA1380_DAI_CAPTURE 2 /* capture DAI */
-extern struct snd_soc_dai uda1380_dai[3];
-extern struct snd_soc_codec_device soc_codec_dev_uda1380;
-
#endif /* _UDA1380_H */
diff --git a/sound/soc/codecs/wm2000.h b/sound/soc/codecs/wm2000.h
index c18e261c3c7f..0b6f056f73cc 100644
--- a/sound/soc/codecs/wm2000.h
+++ b/sound/soc/codecs/wm2000.h
@@ -16,9 +16,6 @@ struct wm2000_setup_data {
extern int wm2000_add_controls(struct snd_soc_codec *codec);
-extern struct snd_soc_dai wm2000_dai;
-extern struct snd_soc_codec_device soc_codec_dev_wm2000;
-
#define WM2000_REG_SYS_START 0x8000
#define WM2000_REG_SPEECH_CLARITY 0x8fef
#define WM2000_REG_SYS_WATCHDOG 0x8ff6
diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c
index 0221ca79b3ae..f4f1fba38eb9 100644
--- a/sound/soc/codecs/wm8350.c
+++ b/sound/soc/codecs/wm8350.c
@@ -1321,20 +1321,14 @@ static int wm8350_set_bias_level(struct snd_soc_codec *codec,
return 0;
}
-static int wm8350_suspend(struct platform_device *pdev, pm_message_t state)
+static int wm8350_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;
-
wm8350_set_bias_level(codec, SND_SOC_BIAS_OFF);
return 0;
}
-static int wm8350_resume(struct platform_device *pdev)
+static int wm8350_resume(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec = socdev->card->codec;
-
wm8350_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
return 0;
@@ -1489,24 +1483,74 @@ int wm8350_mic_jack_detect(struct snd_soc_codec *codec,
}
EXPORT_SYMBOL_GPL(wm8350_mic_jack_detect);
-static struct snd_soc_codec *wm8350_codec;
+#define WM8350_RATES (SNDRV_PCM_RATE_8000_96000)
+
+#define WM8350_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
+ SNDRV_PCM_FMTBIT_S20_3LE |\
+ SNDRV_PCM_FMTBIT_S24_LE)
+
+static struct snd_soc_dai_ops wm8350_dai_ops = {
+ .hw_params = wm8350_pcm_hw_params,
+ .digital_mute = wm8350_mute,
+ .trigger = wm8350_pcm_trigger,
+ .set_fmt = wm8350_set_dai_fmt,
+ .set_sysclk = wm8350_set_dai_sysclk,
+ .set_pll = wm8350_set_fll,
+ .set_clkdiv = wm8350_set_clkdiv,
+};
+
+static struct snd_soc_dai_driver wm8350_dai = {
+ .name = "wm8350-hifi",
+ .playback = {
+ .stream_name = "Playback",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = WM8350_RATES,
+ .formats = WM8350_FORMATS,
+ },
+ .capture = {
+ .stream_name = "Capture",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = WM8350_RATES,
+ .formats = WM8350_FORMATS,
+ },
+ .ops = &wm8350_dai_ops,
+};
-static int wm8350_probe(struct platform_device *pdev)
+static int wm8350_codec_probe(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec;
- struct wm8350 *wm8350;
+ struct wm8350 *wm8350 = dev_get_platdata(codec->dev);
struct wm8350_data *priv;
- int ret;
struct wm8350_output *out1;
struct wm8350_output *out2;
+ int ret, i;
- BUG_ON(!wm8350_codec);
+ if (wm8350->codec.platform_data == NULL) {
+ dev_err(codec->dev, "No audio platform data supplied\n");
+ return -EINVAL;
+ }
+
+ priv = kzalloc(sizeof(struct wm8350_data), GFP_KERNEL);
+ if (priv == NULL)
+ return -ENOMEM;
+ snd_soc_codec_set_drvdata(codec, priv);
+
+ for (i = 0; i < ARRAY_SIZE(supply_names); i++)
+ priv->supplies[i].supply = supply_names[i];
+
+ ret = regulator_bulk_get(wm8350->dev, ARRAY_SIZE(priv->supplies),
+ priv->supplies);
+ if (ret != 0)
+ goto err_priv;
+
+ wm8350->codec.codec = codec;
+ codec->control_data = wm8350;
- socdev->card->codec = wm8350_codec;
- codec = socdev->card->codec;
- wm8350 = codec->control_data;
- priv = snd_soc_codec_get_drvdata(codec);
+ /* Put the codec into reset if it wasn't already */
+ wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA);
+
+ INIT_DELAYED_WORK(&codec->delayed_work, wm8350_pga_work);
/* Enable the codec */
wm8350_set_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA);
@@ -1557,11 +1601,6 @@ static int wm8350_probe(struct platform_device *pdev)
wm8350_register_irq(wm8350, WM8350_IRQ_CODEC_MICD,
wm8350_mic_handler, 0, "Microphone detect", priv);
- 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, wm8350_snd_controls,
ARRAY_SIZE(wm8350_snd_controls));
@@ -1570,14 +1609,16 @@ static int wm8350_probe(struct platform_device *pdev)
wm8350_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
return 0;
+
+err_priv:
+ kfree(priv);
+ return ret;
}
-static int wm8350_remove(struct platform_device *pdev)
+static int wm8350_codec_remove(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec = socdev->card->codec;
- struct wm8350 *wm8350 = codec->control_data;
struct wm8350_data *priv = snd_soc_codec_get_drvdata(codec);
+ struct wm8350 *wm8350 = dev_get_platdata(codec->dev);
int ret;
wm8350_clear_bits(wm8350, WM8350_JACK_DETECT,
@@ -1607,134 +1648,30 @@ static int wm8350_remove(struct platform_device *pdev)
wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA);
+ regulator_bulk_free(ARRAY_SIZE(priv->supplies), priv->supplies);
+ kfree(priv);
return 0;
}
-#define WM8350_RATES (SNDRV_PCM_RATE_8000_96000)
-
-#define WM8350_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
- SNDRV_PCM_FMTBIT_S20_3LE |\
- SNDRV_PCM_FMTBIT_S24_LE)
-
-static struct snd_soc_dai_ops wm8350_dai_ops = {
- .hw_params = wm8350_pcm_hw_params,
- .digital_mute = wm8350_mute,
- .trigger = wm8350_pcm_trigger,
- .set_fmt = wm8350_set_dai_fmt,
- .set_sysclk = wm8350_set_dai_sysclk,
- .set_pll = wm8350_set_fll,
- .set_clkdiv = wm8350_set_clkdiv,
-};
-
-struct snd_soc_dai wm8350_dai = {
- .name = "WM8350",
- .playback = {
- .stream_name = "Playback",
- .channels_min = 1,
- .channels_max = 2,
- .rates = WM8350_RATES,
- .formats = WM8350_FORMATS,
- },
- .capture = {
- .stream_name = "Capture",
- .channels_min = 1,
- .channels_max = 2,
- .rates = WM8350_RATES,
- .formats = WM8350_FORMATS,
- },
- .ops = &wm8350_dai_ops,
-};
-EXPORT_SYMBOL_GPL(wm8350_dai);
-
-struct snd_soc_codec_device soc_codec_dev_wm8350 = {
- .probe = wm8350_probe,
- .remove = wm8350_remove,
+static struct snd_soc_codec_driver soc_codec_dev_wm8350 = {
+ .probe = wm8350_codec_probe,
+ .remove = wm8350_codec_remove,
.suspend = wm8350_suspend,
.resume = wm8350_resume,
+ .read = wm8350_codec_read,
+ .write = wm8350_codec_write,
+ .set_bias_level = wm8350_set_bias_level,
};
-EXPORT_SYMBOL_GPL(soc_codec_dev_wm8350);
-static __devinit int wm8350_codec_probe(struct platform_device *pdev)
+static int __devinit wm8350_probe(struct platform_device *pdev)
{
- struct wm8350 *wm8350 = platform_get_drvdata(pdev);
- struct wm8350_data *priv;
- struct snd_soc_codec *codec;
- int ret, i;
-
- if (wm8350->codec.platform_data == NULL) {
- dev_err(&pdev->dev, "No audio platform data supplied\n");
- return -EINVAL;
- }
-
- priv = kzalloc(sizeof(struct wm8350_data), GFP_KERNEL);
- if (priv == NULL)
- return -ENOMEM;
-
- for (i = 0; i < ARRAY_SIZE(supply_names); i++)
- priv->supplies[i].supply = supply_names[i];
-
- ret = regulator_bulk_get(wm8350->dev, ARRAY_SIZE(priv->supplies),
- priv->supplies);
- if (ret != 0)
- goto err_priv;
-
- codec = &priv->codec;
- wm8350->codec.codec = codec;
-
- wm8350_dai.dev = &pdev->dev;
-
- mutex_init(&codec->mutex);
- INIT_LIST_HEAD(&codec->dapm_widgets);
- INIT_LIST_HEAD(&codec->dapm_paths);
- codec->dev = &pdev->dev;
- codec->name = "WM8350";
- codec->owner = THIS_MODULE;
- codec->read = wm8350_codec_read;
- codec->write = wm8350_codec_write;
- codec->bias_level = SND_SOC_BIAS_OFF;
- codec->set_bias_level = wm8350_set_bias_level;
- codec->dai = &wm8350_dai;
- codec->num_dai = 1;
- codec->reg_cache_size = WM8350_MAX_REGISTER;
- snd_soc_codec_set_drvdata(codec, priv);
- codec->control_data = wm8350;
-
- /* Put the codec into reset if it wasn't already */
- wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA);
-
- INIT_DELAYED_WORK(&codec->delayed_work, wm8350_pga_work);
- ret = snd_soc_register_codec(codec);
- if (ret != 0)
- goto err_supply;
-
- wm8350_codec = codec;
-
- ret = snd_soc_register_dai(&wm8350_dai);
- if (ret != 0)
- goto err_codec;
- return 0;
-
-err_codec:
- snd_soc_unregister_codec(codec);
-err_supply:
- regulator_bulk_free(ARRAY_SIZE(priv->supplies), priv->supplies);
-err_priv:
- kfree(priv);
- wm8350_codec = NULL;
- return ret;
+ return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wm8350,
+ &wm8350_dai, 1);
}
-static int __devexit wm8350_codec_remove(struct platform_device *pdev)
+static int __devexit wm8350_remove(struct platform_device *pdev)
{
- struct wm8350 *wm8350 = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec = wm8350->codec.codec;
- struct wm8350_data *priv = snd_soc_codec_get_drvdata(codec);
-
- snd_soc_unregister_dai(&wm8350_dai);
- snd_soc_unregister_codec(codec);
- regulator_bulk_free(ARRAY_SIZE(priv->supplies), priv->supplies);
- kfree(priv);
- wm8350_codec = NULL;
+ snd_soc_unregister_codec(&pdev->dev);
return 0;
}
@@ -1743,8 +1680,8 @@ static struct platform_driver wm8350_codec_driver = {
.name = "wm8350-codec",
.owner = THIS_MODULE,
},
- .probe = wm8350_codec_probe,
- .remove = __devexit_p(wm8350_codec_remove),
+ .probe = wm8350_probe,
+ .remove = __devexit_p(wm8350_remove),
};
static __init int wm8350_init(void)
diff --git a/sound/soc/codecs/wm8350.h b/sound/soc/codecs/wm8350.h
index 9ed0467c71db..74108eb82938 100644
--- a/sound/soc/codecs/wm8350.h
+++ b/sound/soc/codecs/wm8350.h
@@ -15,9 +15,6 @@
#include <sound/soc.h>
#include <linux/mfd/wm8350/audio.h>
-extern struct snd_soc_dai wm8350_dai;
-extern struct snd_soc_codec_device soc_codec_dev_wm8350;
-
enum wm8350_jack {
WM8350_JDL = 1,
WM8350_JDR = 2,
diff --git a/sound/soc/codecs/wm8400.c b/sound/soc/codecs/wm8400.c
index 8f294066b0ed..850299786e02 100644
--- a/sound/soc/codecs/wm8400.c
+++ b/sound/soc/codecs/wm8400.c
@@ -65,7 +65,7 @@ static struct regulator_bulk_data power[] = {
/* codec private data */
struct wm8400_priv {
- struct snd_soc_codec codec;
+ struct snd_soc_codec *codec;
struct wm8400 *wm8400;
u16 fake_register;
unsigned int sysclk;
@@ -1163,8 +1163,7 @@ static int wm8400_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;
u16 audio1 = wm8400_read(codec, WM8400_AUDIO_INTERFACE_1);
audio1 &= ~WM8400_AIF_WL_MASK;
@@ -1332,10 +1331,9 @@ static struct snd_soc_dai_ops wm8400_dai_ops = {
* 1. ADC/DAC on Primary Interface
* 2. ADC on Primary Interface/DAC on secondary
*/
-struct snd_soc_dai wm8400_dai = {
+static struct snd_soc_dai_driver wm8400_dai = {
/* ADC/DAC on primary */
- .name = "WM8400 ADC/DAC Primary",
- .id = 1,
+ .name = "wm8400-hifi",
.playback = {
.stream_name = "Playback",
.channels_min = 1,
@@ -1352,147 +1350,53 @@ struct snd_soc_dai wm8400_dai = {
},
.ops = &wm8400_dai_ops,
};
-EXPORT_SYMBOL_GPL(wm8400_dai);
-static int wm8400_suspend(struct platform_device *pdev, pm_message_t state)
+static int wm8400_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;
-
wm8400_set_bias_level(codec, SND_SOC_BIAS_OFF);
return 0;
}
-static int wm8400_resume(struct platform_device *pdev)
+static int wm8400_resume(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec = socdev->card->codec;
-
wm8400_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
return 0;
}
-static struct snd_soc_codec *wm8400_codec;
-
-static int wm8400_probe(struct platform_device *pdev)
-{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec;
- int ret;
-
- if (!wm8400_codec) {
- dev_err(&pdev->dev, "wm8400 not yet discovered\n");
- return -ENODEV;
- }
- codec = wm8400_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");
- goto pcm_err;
- }
-
- wm8400_add_controls(codec);
- wm8400_add_widgets(codec);
-
-pcm_err:
- return ret;
-}
-
-/* power down chip */
-static int wm8400_remove(struct platform_device *pdev)
-{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
-
- snd_soc_free_pcms(socdev);
- snd_soc_dapm_free(socdev);
-
- return 0;
-}
-
-struct snd_soc_codec_device soc_codec_dev_wm8400 = {
- .probe = wm8400_probe,
- .remove = wm8400_remove,
- .suspend = wm8400_suspend,
- .resume = wm8400_resume,
-};
-
static void wm8400_probe_deferred(struct work_struct *work)
{
struct wm8400_priv *priv = container_of(work, struct wm8400_priv,
work);
- struct snd_soc_codec *codec = &priv->codec;
- int ret;
+ struct snd_soc_codec *codec = priv->codec;
/* charge output caps */
wm8400_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
- /* We're done, tell the subsystem. */
- ret = snd_soc_register_codec(codec);
- if (ret != 0) {
- dev_err(priv->wm8400->dev,
- "Failed to register codec: %d\n", ret);
- goto err;
- }
-
- ret = snd_soc_register_dai(&wm8400_dai);
- if (ret != 0) {
- dev_err(priv->wm8400->dev,
- "Failed to register DAI: %d\n", ret);
- goto err_codec;
- }
-
- return;
-
-err_codec:
- snd_soc_unregister_codec(codec);
-err:
- wm8400_set_bias_level(codec, SND_SOC_BIAS_OFF);
}
-static int wm8400_codec_probe(struct platform_device *dev)
+static int wm8400_codec_probe(struct snd_soc_codec *codec)
{
+ struct wm8400 *wm8400 = dev_get_platdata(codec->dev);
struct wm8400_priv *priv;
int ret;
u16 reg;
- struct snd_soc_codec *codec;
priv = kzalloc(sizeof(struct wm8400_priv), GFP_KERNEL);
if (priv == NULL)
return -ENOMEM;
- codec = &priv->codec;
snd_soc_codec_set_drvdata(codec, priv);
- codec->control_data = dev_get_drvdata(&dev->dev);
- priv->wm8400 = dev_get_drvdata(&dev->dev);
+ codec->control_data = priv->wm8400 = wm8400;
+ priv->codec = codec;
- ret = regulator_bulk_get(priv->wm8400->dev,
+ ret = regulator_bulk_get(wm8400->dev,
ARRAY_SIZE(power), &power[0]);
if (ret != 0) {
- dev_err(&dev->dev, "Failed to get regulators: %d\n", ret);
+ dev_err(codec->dev, "Failed to get regulators: %d\n", ret);
goto err;
}
- codec->dev = &dev->dev;
- wm8400_dai.dev = &dev->dev;
-
- codec->name = "WM8400";
- codec->owner = THIS_MODULE;
- codec->read = wm8400_read;
- codec->write = wm8400_write;
- codec->bias_level = SND_SOC_BIAS_OFF;
- codec->set_bias_level = wm8400_set_bias_level;
- codec->dai = &wm8400_dai;
- codec->num_dai = 1;
- codec->reg_cache_size = WM8400_REGISTER_COUNT;
- mutex_init(&codec->mutex);
- INIT_LIST_HEAD(&codec->dapm_widgets);
- INIT_LIST_HEAD(&codec->dapm_paths);
INIT_WORK(&priv->work, wm8400_probe_deferred);
wm8400_codec_reset(codec);
@@ -1511,65 +1415,78 @@ static int wm8400_codec_probe(struct platform_device *dev)
wm8400_write(codec, WM8400_LEFT_OUTPUT_VOLUME, 0x50 | (1<<8));
wm8400_write(codec, WM8400_RIGHT_OUTPUT_VOLUME, 0x50 | (1<<8));
- wm8400_codec = codec;
-
if (!schedule_work(&priv->work)) {
ret = -EINVAL;
goto err_regulator;
}
-
+ wm8400_add_controls(codec);
+ wm8400_add_widgets(codec);
return 0;
err_regulator:
- wm8400_codec = NULL;
regulator_bulk_free(ARRAY_SIZE(power), power);
err:
kfree(priv);
return ret;
}
-static int __exit wm8400_codec_remove(struct platform_device *dev)
+static int wm8400_codec_remove(struct snd_soc_codec *codec)
{
- struct wm8400_priv *priv = snd_soc_codec_get_drvdata(wm8400_codec);
+ struct wm8400_priv *priv = snd_soc_codec_get_drvdata(codec);
u16 reg;
- snd_soc_unregister_dai(&wm8400_dai);
- snd_soc_unregister_codec(wm8400_codec);
-
- reg = wm8400_read(wm8400_codec, WM8400_POWER_MANAGEMENT_1);
- wm8400_write(wm8400_codec, WM8400_POWER_MANAGEMENT_1,
+ reg = wm8400_read(codec, WM8400_POWER_MANAGEMENT_1);
+ wm8400_write(codec, WM8400_POWER_MANAGEMENT_1,
reg & (~WM8400_CODEC_ENA));
regulator_bulk_free(ARRAY_SIZE(power), power);
kfree(priv);
- wm8400_codec = NULL;
+ return 0;
+}
+
+static struct snd_soc_codec_driver soc_codec_dev_wm8400 = {
+ .probe = wm8400_codec_probe,
+ .remove = wm8400_codec_remove,
+ .suspend = wm8400_suspend,
+ .resume = wm8400_resume,
+ .read = wm8400_read,
+ .write = wm8400_write,
+ .set_bias_level = wm8400_set_bias_level,
+};
+
+static int __devinit wm8400_probe(struct platform_device *pdev)
+{
+ return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wm8400,
+ &wm8400_dai, 1);
+}
+static int __devexit wm8400_remove(struct platform_device *pdev)
+{
+ snd_soc_unregister_codec(&pdev->dev);
return 0;
}
static struct platform_driver wm8400_codec_driver = {
.driver = {
- .name = "wm8400-codec",
- .owner = THIS_MODULE,
- },
- .probe = wm8400_codec_probe,
- .remove = __exit_p(wm8400_codec_remove),
+ .name = "wm8400-codec",
+ .owner = THIS_MODULE,
+ },
+ .probe = wm8400_probe,
+ .remove = __devexit_p(wm8400_remove),
};
-static int __init wm8400_codec_init(void)
+static __init int wm8400_init(void)
{
return platform_driver_register(&wm8400_codec_driver);
}
-module_init(wm8400_codec_init);
+module_init(wm8400_init);
-static void __exit wm8400_codec_exit(void)
+static __exit void wm8400_exit(void)
{
platform_driver_unregister(&wm8400_codec_driver);
}
-module_exit(wm8400_codec_exit);
-
-EXPORT_SYMBOL_GPL(soc_codec_dev_wm8400);
+module_exit(wm8400_exit);
MODULE_DESCRIPTION("ASoC WM8400 driver");
MODULE_AUTHOR("Mark Brown");
diff --git a/sound/soc/codecs/wm8400.h b/sound/soc/codecs/wm8400.h
index 79c5934d4776..521adb193870 100644
--- a/sound/soc/codecs/wm8400.h
+++ b/sound/soc/codecs/wm8400.h
@@ -56,7 +56,4 @@
#define WM8400_BCLK_DIV_44 (0xE << 1)
#define WM8400_BCLK_DIV_48 (0xF << 1)
-extern struct snd_soc_dai wm8400_dai;
-extern struct snd_soc_codec_device soc_codec_dev_wm8400;
-
#endif
diff --git a/sound/soc/codecs/wm8510.c b/sound/soc/codecs/wm8510.c
index 0f7bcb61071a..dbfa05d2cb92 100644
--- a/sound/soc/codecs/wm8510.c
+++ b/sound/soc/codecs/wm8510.c
@@ -31,8 +31,6 @@
#define WM8510_VERSION "0.6"
-struct snd_soc_codec_device soc_codec_dev_wm8510;
-
/*
* wm8510 register cache
* We can't read the WM8510 register space when we are
@@ -61,6 +59,12 @@ static const u16 wm8510_reg[WM8510_CACHEREGNUM] = {
#define wm8510_reset(c) snd_soc_write(c, WM8510_RESET, 0)
+/* codec private data */
+struct wm8510_priv {
+ enum snd_soc_control_type control_type;
+ void *control_data;
+};
+
static const char *wm8510_companding[] = { "Off", "NC", "u-law", "A-law" };
static const char *wm8510_deemp[] = { "None", "32kHz", "44.1kHz", "48kHz" };
static const char *wm8510_alc[] = { "ALC", "Limiter" };
@@ -403,8 +407,7 @@ static int wm8510_pcm_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;
u16 iface = snd_soc_read(codec, WM8510_IFACE) & 0x19f;
u16 adn = snd_soc_read(codec, WM8510_ADD) & 0x1f1;
@@ -514,8 +517,8 @@ static struct snd_soc_dai_ops wm8510_dai_ops = {
.set_pll = wm8510_set_dai_pll,
};
-struct snd_soc_dai wm8510_dai = {
- .name = "WM8510 HiFi",
+static struct snd_soc_dai_driver wm8510_dai = {
+ .name = "wm8510-hifi",
.playback = {
.stream_name = "Playback",
.channels_min = 2,
@@ -531,21 +534,15 @@ struct snd_soc_dai wm8510_dai = {
.ops = &wm8510_dai_ops,
.symmetric_rates = 1,
};
-EXPORT_SYMBOL_GPL(wm8510_dai);
-static int wm8510_suspend(struct platform_device *pdev, pm_message_t state)
+static int wm8510_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;
-
wm8510_set_bias_level(codec, SND_SOC_BIAS_OFF);
return 0;
}
-static int wm8510_resume(struct platform_device *pdev)
+static int wm8510_resume(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec = socdev->card->codec;
int i;
u8 data[2];
u16 *cache = codec->reg_cache;
@@ -561,43 +558,22 @@ static int wm8510_resume(struct platform_device *pdev)
return 0;
}
-/*
- * initialise the WM8510 driver
- * register the mixer and dsp interfaces with the kernel
- */
-static int wm8510_init(struct snd_soc_device *socdev,
- enum snd_soc_control_type control)
+static int wm8510_probe(struct snd_soc_codec *codec)
{
- struct snd_soc_codec *codec = socdev->card->codec;
- int ret = 0;
-
- codec->name = "WM8510";
- codec->owner = THIS_MODULE;
- codec->set_bias_level = wm8510_set_bias_level;
- codec->dai = &wm8510_dai;
- codec->num_dai = 1;
- codec->reg_cache_size = ARRAY_SIZE(wm8510_reg);
- codec->reg_cache = kmemdup(wm8510_reg, sizeof(wm8510_reg), GFP_KERNEL);
+ struct wm8510_priv *wm8510 = snd_soc_codec_get_drvdata(codec);
+ int ret;
- if (codec->reg_cache == NULL)
- return -ENOMEM;
+ pr_info("WM8510 Audio Codec %s", WM8510_VERSION);
- ret = snd_soc_codec_set_cache_io(codec, 7, 9, control);
+ codec->control_data = wm8510->control_data;
+ ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8510->control_type);
if (ret < 0) {
- printk(KERN_ERR "wm8510: failed to set cache I/O: %d\n",
- ret);
- goto err;
+ printk(KERN_ERR "wm8510: failed to set cache I/O: %d\n", ret);
+ return ret;
}
wm8510_reset(codec);
- /* register pcms */
- ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
- if (ret < 0) {
- printk(KERN_ERR "wm8510: failed to create pcms\n");
- goto err;
- }
-
/* power on device */
codec->bias_level = SND_SOC_BIAS_OFF;
wm8510_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
@@ -606,119 +582,53 @@ static int wm8510_init(struct snd_soc_device *socdev,
wm8510_add_widgets(codec);
return ret;
-
-err:
- kfree(codec->reg_cache);
- return ret;
}
-static struct snd_soc_device *wm8510_socdev;
-
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
-
-/*
- * WM8510 2 wire address is 0x1a
- */
-
-static int wm8510_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
+/* power down chip */
+static int wm8510_remove(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = wm8510_socdev;
- struct snd_soc_codec *codec = socdev->card->codec;
- int ret;
-
- i2c_set_clientdata(i2c, codec);
- codec->control_data = i2c;
-
- ret = wm8510_init(socdev, SND_SOC_I2C);
- if (ret < 0)
- pr_err("failed to initialise WM8510\n");
-
- return ret;
-}
+ struct wm8510_priv *wm8510 = snd_soc_codec_get_drvdata(codec);
-static int wm8510_i2c_remove(struct i2c_client *client)
-{
- struct snd_soc_codec *codec = i2c_get_clientdata(client);
- kfree(codec->reg_cache);
+ wm8510_set_bias_level(codec, SND_SOC_BIAS_OFF);
+ kfree(wm8510);
return 0;
}
-static const struct i2c_device_id wm8510_i2c_id[] = {
- { "wm8510", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, wm8510_i2c_id);
-
-static struct i2c_driver wm8510_i2c_driver = {
- .driver = {
- .name = "WM8510 I2C Codec",
- .owner = THIS_MODULE,
- },
- .probe = wm8510_i2c_probe,
- .remove = wm8510_i2c_remove,
- .id_table = wm8510_i2c_id,
+static struct snd_soc_codec_driver soc_codec_dev_wm8510 = {
+ .probe = wm8510_probe,
+ .remove = wm8510_remove,
+ .suspend = wm8510_suspend,
+ .resume = wm8510_resume,
+ .set_bias_level = wm8510_set_bias_level,
+ .reg_cache_size = ARRAY_SIZE(wm8510_reg),
+ .reg_word_size = sizeof(u16),
+ .reg_cache_default =wm8510_reg,
};
-static int wm8510_add_i2c_device(struct platform_device *pdev,
- const struct wm8510_setup_data *setup)
-{
- struct i2c_board_info info;
- struct i2c_adapter *adapter;
- struct i2c_client *client;
- int ret;
-
- ret = i2c_add_driver(&wm8510_i2c_driver);
- if (ret != 0) {
- dev_err(&pdev->dev, "can't add i2c driver\n");
- return ret;
- }
-
- memset(&info, 0, sizeof(struct i2c_board_info));
- info.addr = setup->i2c_address;
- strlcpy(info.type, "wm8510", I2C_NAME_SIZE);
-
- adapter = i2c_get_adapter(setup->i2c_bus);
- if (!adapter) {
- dev_err(&pdev->dev, "can't get i2c adapter %d\n",
- setup->i2c_bus);
- goto err_driver;
- }
-
- client = i2c_new_device(adapter, &info);
- i2c_put_adapter(adapter);
- if (!client) {
- dev_err(&pdev->dev, "can't add i2c device at 0x%x\n",
- (unsigned int)info.addr);
- goto err_driver;
- }
-
- return 0;
-
-err_driver:
- i2c_del_driver(&wm8510_i2c_driver);
- return -ENODEV;
-}
-#endif
-
#if defined(CONFIG_SPI_MASTER)
static int __devinit wm8510_spi_probe(struct spi_device *spi)
{
- struct snd_soc_device *socdev = wm8510_socdev;
- struct snd_soc_codec *codec = socdev->card->codec;
+ struct wm8510_priv *wm8510;
int ret;
- codec->control_data = spi;
+ wm8510 = kzalloc(sizeof(struct wm8510_priv), GFP_KERNEL);
+ if (wm8510 == NULL)
+ return -ENOMEM;
+
+ wm8510->control_data = spi;
+ wm8510->control_type = SND_SOC_SPI;
+ spi_set_drvdata(spi, wm8510);
- ret = wm8510_init(socdev, SND_SOC_SPI);
+ ret = snd_soc_register_codec(&spi->dev,
+ &soc_codec_dev_wm8510, &wm8510_dai, 1);
if (ret < 0)
- dev_err(&spi->dev, "failed to initialise WM8510\n");
-
+ kfree(wm8510);
return ret;
}
static int __devexit wm8510_spi_remove(struct spi_device *spi)
{
+ snd_soc_unregister_codec(&spi->dev);
return 0;
}
@@ -733,84 +643,80 @@ static struct spi_driver wm8510_spi_driver = {
};
#endif /* CONFIG_SPI_MASTER */
-static int wm8510_probe(struct platform_device *pdev)
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+static __devinit int wm8510_i2c_probe(struct i2c_client *i2c,
+ const struct i2c_device_id *id)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct wm8510_setup_data *setup;
- struct snd_soc_codec *codec;
- int ret = 0;
-
- pr_info("WM8510 Audio Codec %s", WM8510_VERSION);
+ struct wm8510_priv *wm8510;
+ int ret;
- setup = socdev->codec_data;
- codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
- if (codec == NULL)
+ wm8510 = kzalloc(sizeof(struct wm8510_priv), GFP_KERNEL);
+ if (wm8510 == NULL)
return -ENOMEM;
- socdev->card->codec = codec;
- mutex_init(&codec->mutex);
- INIT_LIST_HEAD(&codec->dapm_widgets);
- INIT_LIST_HEAD(&codec->dapm_paths);
+ i2c_set_clientdata(i2c, wm8510);
+ wm8510->control_data = i2c;
+ wm8510->control_type = SND_SOC_I2C;
- wm8510_socdev = socdev;
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
- if (setup->i2c_address) {
- ret = wm8510_add_i2c_device(pdev, setup);
- }
-#endif
-#if defined(CONFIG_SPI_MASTER)
- if (setup->spi) {
- ret = spi_register_driver(&wm8510_spi_driver);
- if (ret != 0)
- printk(KERN_ERR "can't add spi driver");
- }
-#endif
-
- if (ret != 0)
- kfree(codec);
+ ret = snd_soc_register_codec(&i2c->dev,
+ &soc_codec_dev_wm8510, &wm8510_dai, 1);
+ if (ret < 0)
+ kfree(wm8510);
return ret;
}
-/* power down chip */
-static int wm8510_remove(struct platform_device *pdev)
+static __devexit int wm8510_i2c_remove(struct i2c_client *client)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec = socdev->card->codec;
-
- if (codec->control_data)
- wm8510_set_bias_level(codec, SND_SOC_BIAS_OFF);
-
- snd_soc_free_pcms(socdev);
- snd_soc_dapm_free(socdev);
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
- i2c_unregister_device(codec->control_data);
- i2c_del_driver(&wm8510_i2c_driver);
-#endif
-#if defined(CONFIG_SPI_MASTER)
- spi_unregister_driver(&wm8510_spi_driver);
-#endif
- kfree(codec);
-
+ snd_soc_unregister_codec(&client->dev);
return 0;
}
-struct snd_soc_codec_device soc_codec_dev_wm8510 = {
- .probe = wm8510_probe,
- .remove = wm8510_remove,
- .suspend = wm8510_suspend,
- .resume = wm8510_resume,
+static const struct i2c_device_id wm8510_i2c_id[] = {
+ { "wm8510", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, wm8510_i2c_id);
+
+static struct i2c_driver wm8510_i2c_driver = {
+ .driver = {
+ .name = "wm8510-codec",
+ .owner = THIS_MODULE,
+ },
+ .probe = wm8510_i2c_probe,
+ .remove = __devexit_p(wm8510_i2c_remove),
+ .id_table = wm8510_i2c_id,
};
-EXPORT_SYMBOL_GPL(soc_codec_dev_wm8510);
+#endif
static int __init wm8510_modinit(void)
{
- return snd_soc_register_dai(&wm8510_dai);
+ int ret = 0;
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+ ret = i2c_add_driver(&wm8510_i2c_driver);
+ if (ret != 0) {
+ printk(KERN_ERR "Failed to register WM8510 I2C driver: %d\n",
+ ret);
+ }
+#endif
+#if defined(CONFIG_SPI_MASTER)
+ ret = spi_register_driver(&wm8510_spi_driver);
+ if (ret != 0) {
+ printk(KERN_ERR "Failed to register WM8510 SPI driver: %d\n",
+ ret);
+ }
+#endif
+ return ret;
}
module_init(wm8510_modinit);
static void __exit wm8510_exit(void)
{
- snd_soc_unregister_dai(&wm8510_dai);
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+ i2c_del_driver(&wm8510_i2c_driver);
+#endif
+#if defined(CONFIG_SPI_MASTER)
+ spi_unregister_driver(&wm8510_spi_driver);
+#endif
}
module_exit(wm8510_exit);
diff --git a/sound/soc/codecs/wm8510.h b/sound/soc/codecs/wm8510.h
index bdefcf5c69ff..b3e26ed9f2d0 100644
--- a/sound/soc/codecs/wm8510.h
+++ b/sound/soc/codecs/wm8510.h
@@ -99,7 +99,4 @@ struct wm8510_setup_data {
unsigned short i2c_address;
};
-extern struct snd_soc_dai wm8510_dai;
-extern struct snd_soc_codec_device soc_codec_dev_wm8510;
-
#endif
diff --git a/sound/soc/codecs/wm8523.c b/sound/soc/codecs/wm8523.c
index 0ad039b4adf5..58d411b6faaf 100644
--- a/sound/soc/codecs/wm8523.c
+++ b/sound/soc/codecs/wm8523.c
@@ -30,9 +30,6 @@
#include "wm8523.h"
-static struct snd_soc_codec *wm8523_codec;
-struct snd_soc_codec_device soc_codec_dev_wm8523;
-
#define WM8523_NUM_SUPPLIES 2
static const char *wm8523_supply_names[WM8523_NUM_SUPPLIES] = {
"AVDD",
@@ -43,7 +40,8 @@ static const char *wm8523_supply_names[WM8523_NUM_SUPPLIES] = {
/* codec private data */
struct wm8523_priv {
- struct snd_soc_codec codec;
+ enum snd_soc_control_type control_type;
+ void *control_data;
u16 reg_cache[WM8523_REGISTER_COUNT];
struct regulator_bulk_data supplies[WM8523_NUM_SUPPLIES];
unsigned int sysclk;
@@ -162,8 +160,7 @@ static int wm8523_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 wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec);
int i;
u16 aifctrl1 = snd_soc_read(codec, WM8523_AIF_CTRL1);
@@ -387,8 +384,8 @@ static struct snd_soc_dai_ops wm8523_dai_ops = {
.set_fmt = wm8523_set_dai_fmt,
};
-struct snd_soc_dai wm8523_dai = {
- .name = "WM8523",
+static struct snd_soc_dai_driver wm8523_dai = {
+ .name = "wm8523-hifi",
.playback = {
.stream_name = "Playback",
.channels_min = 2, /* Mono modes not yet supported */
@@ -398,25 +395,17 @@ struct snd_soc_dai wm8523_dai = {
},
.ops = &wm8523_dai_ops,
};
-EXPORT_SYMBOL_GPL(wm8523_dai);
#ifdef CONFIG_PM
-static int wm8523_suspend(struct platform_device *pdev, pm_message_t state)
+static int wm8523_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;
-
wm8523_set_bias_level(codec, SND_SOC_BIAS_OFF);
return 0;
}
-static int wm8523_resume(struct platform_device *pdev)
+static int wm8523_resume(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec = socdev->card->codec;
-
wm8523_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
return 0;
}
#else
@@ -424,93 +413,21 @@ static int wm8523_resume(struct platform_device *pdev)
#define wm8523_resume NULL
#endif
-static int wm8523_probe(struct platform_device *pdev)
-{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec;
- int ret = 0;
-
- if (wm8523_codec == NULL) {
- dev_err(&pdev->dev, "Codec device not registered\n");
- return -ENODEV;
- }
-
- socdev->card->codec = wm8523_codec;
- codec = wm8523_codec;
-
- /* register pcms */
- ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
- if (ret < 0) {
- dev_err(codec->dev, "failed to create pcms: %d\n", ret);
- goto pcm_err;
- }
-
- snd_soc_add_controls(codec, wm8523_snd_controls,
- ARRAY_SIZE(wm8523_snd_controls));
- wm8523_add_widgets(codec);
-
- return ret;
-
-pcm_err:
- return ret;
-}
-
-static int wm8523_remove(struct platform_device *pdev)
-{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
-
- snd_soc_free_pcms(socdev);
- snd_soc_dapm_free(socdev);
-
- return 0;
-}
-
-struct snd_soc_codec_device soc_codec_dev_wm8523 = {
- .probe = wm8523_probe,
- .remove = wm8523_remove,
- .suspend = wm8523_suspend,
- .resume = wm8523_resume,
-};
-EXPORT_SYMBOL_GPL(soc_codec_dev_wm8523);
-
-static int wm8523_register(struct wm8523_priv *wm8523,
- enum snd_soc_control_type control)
+static int wm8523_probe(struct snd_soc_codec *codec)
{
- int ret;
- struct snd_soc_codec *codec = &wm8523->codec;
- int i;
-
- if (wm8523_codec) {
- dev_err(codec->dev, "Another WM8523 is registered\n");
- ret = -EINVAL;
- goto err;
- }
-
- mutex_init(&codec->mutex);
- INIT_LIST_HEAD(&codec->dapm_widgets);
- INIT_LIST_HEAD(&codec->dapm_paths);
-
- snd_soc_codec_set_drvdata(codec, wm8523);
- codec->name = "WM8523";
- codec->owner = THIS_MODULE;
- codec->bias_level = SND_SOC_BIAS_OFF;
- codec->set_bias_level = wm8523_set_bias_level;
- codec->dai = &wm8523_dai;
- codec->num_dai = 1;
- codec->reg_cache_size = WM8523_REGISTER_COUNT;
- codec->reg_cache = &wm8523->reg_cache;
- codec->volatile_register = wm8523_volatile_register;
+ struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec);
+ int ret, i;
+ codec->hw_write = (hw_write_t)i2c_master_send;
+ codec->control_data = wm8523->control_data;
wm8523->rate_constraint.list = &wm8523->rate_constraint_list[0];
wm8523->rate_constraint.count =
ARRAY_SIZE(wm8523->rate_constraint_list);
- memcpy(codec->reg_cache, wm8523_reg, sizeof(wm8523_reg));
-
- ret = snd_soc_codec_set_cache_io(codec, 8, 16, control);
+ ret = snd_soc_codec_set_cache_io(codec, 8, 16, wm8523->control_type);
if (ret != 0) {
dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- goto err;
+ return ret;
}
for (i = 0; i < ARRAY_SIZE(wm8523->supplies); i++)
@@ -520,7 +437,7 @@ static int wm8523_register(struct wm8523_priv *wm8523,
wm8523->supplies);
if (ret != 0) {
dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
- goto err;
+ return ret;
}
ret = regulator_bulk_enable(ARRAY_SIZE(wm8523->supplies),
@@ -555,8 +472,6 @@ static int wm8523_register(struct wm8523_priv *wm8523,
goto err_enable;
}
- wm8523_dai.dev = codec->dev;
-
/* Change some default settings - latch VU and enable ZC */
wm8523->reg_cache[WM8523_DAC_GAINR] |= WM8523_DACR_VU;
wm8523->reg_cache[WM8523_DAC_CTRL3] |= WM8523_ZC;
@@ -566,69 +481,68 @@ static int wm8523_register(struct wm8523_priv *wm8523,
/* Bias level configuration will have done an extra enable */
regulator_bulk_disable(ARRAY_SIZE(wm8523->supplies), wm8523->supplies);
- wm8523_codec = codec;
-
- ret = snd_soc_register_codec(codec);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to register codec: %d\n", ret);
- goto err_enable;
- }
-
- ret = snd_soc_register_dai(&wm8523_dai);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
- goto err_codec;
- }
+ snd_soc_add_controls(codec, wm8523_snd_controls,
+ ARRAY_SIZE(wm8523_snd_controls));
+ wm8523_add_widgets(codec);
return 0;
-err_codec:
- snd_soc_unregister_codec(codec);
err_enable:
regulator_bulk_disable(ARRAY_SIZE(wm8523->supplies), wm8523->supplies);
err_get:
regulator_bulk_free(ARRAY_SIZE(wm8523->supplies), wm8523->supplies);
-err:
- kfree(wm8523);
+
return ret;
}
-static void wm8523_unregister(struct wm8523_priv *wm8523)
+static int wm8523_remove(struct snd_soc_codec *codec)
{
- wm8523_set_bias_level(&wm8523->codec, SND_SOC_BIAS_OFF);
+ struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec);
+
+ wm8523_set_bias_level(codec, SND_SOC_BIAS_OFF);
regulator_bulk_free(ARRAY_SIZE(wm8523->supplies), wm8523->supplies);
- snd_soc_unregister_dai(&wm8523_dai);
- snd_soc_unregister_codec(&wm8523->codec);
- kfree(wm8523);
- wm8523_codec = NULL;
+ return 0;
}
+static struct snd_soc_codec_driver soc_codec_dev_wm8523 = {
+ .probe = wm8523_probe,
+ .remove = wm8523_remove,
+ .suspend = wm8523_suspend,
+ .resume = wm8523_resume,
+ .set_bias_level = wm8523_set_bias_level,
+ .reg_cache_size = WM8523_REGISTER_COUNT,
+ .reg_word_size = sizeof(u16),
+ .reg_cache_default = wm8523_reg,
+ .volatile_register = wm8523_volatile_register,
+};
+
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
static __devinit int wm8523_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
struct wm8523_priv *wm8523;
- struct snd_soc_codec *codec;
+ int ret;
wm8523 = kzalloc(sizeof(struct wm8523_priv), GFP_KERNEL);
if (wm8523 == NULL)
return -ENOMEM;
- codec = &wm8523->codec;
- codec->hw_write = (hw_write_t)i2c_master_send;
-
i2c_set_clientdata(i2c, wm8523);
- codec->control_data = i2c;
+ wm8523->control_data = i2c;
+ wm8523->control_type = SND_SOC_I2C;
- codec->dev = &i2c->dev;
+ ret = snd_soc_register_codec(&i2c->dev,
+ &soc_codec_dev_wm8523, &wm8523_dai, 1);
+ if (ret < 0)
+ kfree(wm8523);
+ return ret;
- return wm8523_register(wm8523, SND_SOC_I2C);
}
static __devexit int wm8523_i2c_remove(struct i2c_client *client)
{
- struct wm8523_priv *wm8523 = i2c_get_clientdata(client);
- wm8523_unregister(wm8523);
+ snd_soc_unregister_codec(&client->dev);
+ kfree(i2c_get_clientdata(client));
return 0;
}
@@ -640,7 +554,7 @@ MODULE_DEVICE_TABLE(i2c, wm8523_i2c_id);
static struct i2c_driver wm8523_i2c_driver = {
.driver = {
- .name = "WM8523",
+ .name = "wm8523-codec",
.owner = THIS_MODULE,
},
.probe = wm8523_i2c_probe,
diff --git a/sound/soc/codecs/wm8523.h b/sound/soc/codecs/wm8523.h
index 1aa9ce3e1357..4d5b1eb8f2fc 100644
--- a/sound/soc/codecs/wm8523.h
+++ b/sound/soc/codecs/wm8523.h
@@ -154,7 +154,4 @@
#define WM8523_ZD_COUNT_SHIFT 0 /* ZD_COUNT - [1:0] */
#define WM8523_ZD_COUNT_WIDTH 2 /* ZD_COUNT - [1:0] */
-extern struct snd_soc_dai wm8523_dai;
-extern struct snd_soc_codec_device soc_codec_dev_wm8523;
-
#endif
diff --git a/sound/soc/codecs/wm8580.c b/sound/soc/codecs/wm8580.c
index c3571ee5c11b..cae58941a32f 100644
--- a/sound/soc/codecs/wm8580.c
+++ b/sound/soc/codecs/wm8580.c
@@ -199,7 +199,8 @@ static const char *wm8580_supply_names[WM8580_NUM_SUPPLIES] = {
/* codec private data */
struct wm8580_priv {
- struct snd_soc_codec codec;
+ enum snd_soc_control_type control_type;
+ void *control_data;
struct regulator_bulk_data supplies[WM8580_NUM_SUPPLIES];
u16 reg_cache[WM8580_MAX_REGISTER + 1];
struct pll_state a;
@@ -484,9 +485,8 @@ static int wm8580_paif_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;
- u16 paifb = snd_soc_read(codec, WM8580_PAIF3 + dai->id);
+ struct snd_soc_codec *codec = rtd->codec;
+ u16 paifb = snd_soc_read(codec, WM8580_PAIF3 + dai->driver->id);
paifb &= ~WM8580_AIF_LENGTH_MASK;
/* bit size */
@@ -506,7 +506,7 @@ static int wm8580_paif_hw_params(struct snd_pcm_substream *substream,
return -EINVAL;
}
- snd_soc_write(codec, WM8580_PAIF3 + dai->id, paifb);
+ snd_soc_write(codec, WM8580_PAIF3 + dai->driver->id, paifb);
return 0;
}
@@ -518,8 +518,8 @@ static int wm8580_set_paif_dai_fmt(struct snd_soc_dai *codec_dai,
unsigned int aifb;
int can_invert_lrclk;
- aifa = snd_soc_read(codec, WM8580_PAIF1 + codec_dai->id);
- aifb = snd_soc_read(codec, WM8580_PAIF3 + codec_dai->id);
+ aifa = snd_soc_read(codec, WM8580_PAIF1 + codec_dai->driver->id);
+ aifb = snd_soc_read(codec, WM8580_PAIF3 + codec_dai->driver->id);
aifb &= ~(WM8580_AIF_FMT_MASK | WM8580_AIF_LRP | WM8580_AIF_BCP);
@@ -585,8 +585,8 @@ static int wm8580_set_paif_dai_fmt(struct snd_soc_dai *codec_dai,
return -EINVAL;
}
- snd_soc_write(codec, WM8580_PAIF1 + codec_dai->id, aifa);
- snd_soc_write(codec, WM8580_PAIF3 + codec_dai->id, aifb);
+ snd_soc_write(codec, WM8580_PAIF1 + codec_dai->driver->id, aifa);
+ snd_soc_write(codec, WM8580_PAIF3 + codec_dai->driver->id, aifb);
return 0;
}
@@ -746,10 +746,10 @@ static struct snd_soc_dai_ops wm8580_dai_ops_capture = {
.set_pll = wm8580_set_dai_pll,
};
-struct snd_soc_dai wm8580_dai[] = {
+static struct snd_soc_dai_driver wm8580_dai[] = {
{
- .name = "WM8580 PAIFRX",
- .id = 0,
+ .name = "wm8580-hifi-playback",
+ .id = WM8580_DAI_PAIFRX,
.playback = {
.stream_name = "Playback",
.channels_min = 1,
@@ -760,8 +760,8 @@ struct snd_soc_dai wm8580_dai[] = {
.ops = &wm8580_dai_ops_playback,
},
{
- .name = "WM8580 PAIFTX",
- .id = 1,
+ .name = "wm8580-hifi-capture",
+ .id = WM8580_DAI_PAIFTX,
.capture = {
.stream_name = "Capture",
.channels_min = 2,
@@ -772,90 +772,17 @@ struct snd_soc_dai wm8580_dai[] = {
.ops = &wm8580_dai_ops_capture,
},
};
-EXPORT_SYMBOL_GPL(wm8580_dai);
-static struct snd_soc_codec *wm8580_codec;
-
-static int wm8580_probe(struct platform_device *pdev)
+static int wm8580_probe(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec;
- int ret = 0;
-
- if (wm8580_codec == NULL) {
- dev_err(&pdev->dev, "Codec device not registered\n");
- return -ENODEV;
- }
-
- socdev->card->codec = wm8580_codec;
- codec = wm8580_codec;
-
- /* register pcms */
- ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
- if (ret < 0) {
- dev_err(codec->dev, "failed to create pcms: %d\n", ret);
- goto pcm_err;
- }
-
- snd_soc_add_controls(codec, wm8580_snd_controls,
- ARRAY_SIZE(wm8580_snd_controls));
- wm8580_add_widgets(codec);
-
- return ret;
-
-pcm_err:
- return ret;
-}
-
-/* power down chip */
-static int wm8580_remove(struct platform_device *pdev)
-{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
-
- snd_soc_free_pcms(socdev);
- snd_soc_dapm_free(socdev);
-
- return 0;
-}
-
-struct snd_soc_codec_device soc_codec_dev_wm8580 = {
- .probe = wm8580_probe,
- .remove = wm8580_remove,
-};
-EXPORT_SYMBOL_GPL(soc_codec_dev_wm8580);
-
-static int wm8580_register(struct wm8580_priv *wm8580,
- enum snd_soc_control_type control)
-{
- int ret, i;
- struct snd_soc_codec *codec = &wm8580->codec;
-
- if (wm8580_codec) {
- dev_err(codec->dev, "Another WM8580 is registered\n");
- ret = -EINVAL;
- goto err;
- }
-
- mutex_init(&codec->mutex);
- INIT_LIST_HEAD(&codec->dapm_widgets);
- INIT_LIST_HEAD(&codec->dapm_paths);
-
- snd_soc_codec_set_drvdata(codec, wm8580);
- codec->name = "WM8580";
- codec->owner = THIS_MODULE;
- codec->bias_level = SND_SOC_BIAS_OFF;
- codec->set_bias_level = wm8580_set_bias_level;
- codec->dai = wm8580_dai;
- codec->num_dai = ARRAY_SIZE(wm8580_dai);
- codec->reg_cache_size = ARRAY_SIZE(wm8580->reg_cache);
- codec->reg_cache = &wm8580->reg_cache;
-
- memcpy(codec->reg_cache, wm8580_reg, sizeof(wm8580_reg));
+ struct wm8580_priv *wm8580 = snd_soc_codec_get_drvdata(codec);
+ int ret = 0,i;
- ret = snd_soc_codec_set_cache_io(codec, 7, 9, control);
+ codec->control_data = wm8580->control_data;
+ ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8580->control_type);
if (ret < 0) {
dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- goto err;
+ return ret;
}
for (i = 0; i < ARRAY_SIZE(wm8580->supplies); i++)
@@ -865,7 +792,7 @@ static int wm8580_register(struct wm8580_priv *wm8580,
wm8580->supplies);
if (ret != 0) {
dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
- goto err;
+ return ret;
}
ret = regulator_bulk_enable(ARRAY_SIZE(wm8580->supplies),
@@ -882,74 +809,69 @@ static int wm8580_register(struct wm8580_priv *wm8580,
goto err_regulator_enable;
}
- for (i = 0; i < ARRAY_SIZE(wm8580_dai); i++)
- wm8580_dai[i].dev = codec->dev;
-
wm8580_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
- wm8580_codec = codec;
-
- ret = snd_soc_register_codec(codec);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to register codec: %d\n", ret);
- goto err_regulator_enable;
- }
-
- ret = snd_soc_register_dais(wm8580_dai, ARRAY_SIZE(wm8580_dai));
- if (ret != 0) {
- dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
- goto err_codec;
- }
+ snd_soc_add_controls(codec, wm8580_snd_controls,
+ ARRAY_SIZE(wm8580_snd_controls));
+ wm8580_add_widgets(codec);
return 0;
-err_codec:
- snd_soc_unregister_codec(codec);
err_regulator_enable:
regulator_bulk_disable(ARRAY_SIZE(wm8580->supplies), wm8580->supplies);
err_regulator_get:
regulator_bulk_free(ARRAY_SIZE(wm8580->supplies), wm8580->supplies);
-err:
- kfree(wm8580);
return ret;
}
-static void wm8580_unregister(struct wm8580_priv *wm8580)
+/* power down chip */
+static int wm8580_remove(struct snd_soc_codec *codec)
{
- wm8580_set_bias_level(&wm8580->codec, SND_SOC_BIAS_OFF);
- snd_soc_unregister_dais(wm8580_dai, ARRAY_SIZE(wm8580_dai));
- snd_soc_unregister_codec(&wm8580->codec);
+ struct wm8580_priv *wm8580 = snd_soc_codec_get_drvdata(codec);
+
+ wm8580_set_bias_level(codec, SND_SOC_BIAS_OFF);
+
regulator_bulk_disable(ARRAY_SIZE(wm8580->supplies), wm8580->supplies);
regulator_bulk_free(ARRAY_SIZE(wm8580->supplies), wm8580->supplies);
- kfree(wm8580);
- wm8580_codec = NULL;
+
+ return 0;
}
+static struct snd_soc_codec_driver soc_codec_dev_wm8580 = {
+ .probe = wm8580_probe,
+ .remove = wm8580_remove,
+ .set_bias_level = wm8580_set_bias_level,
+ .reg_cache_size = sizeof(wm8580_reg),
+ .reg_word_size = sizeof(u16),
+ .reg_cache_default = &wm8580_reg,
+};
+
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
static int wm8580_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
struct wm8580_priv *wm8580;
- struct snd_soc_codec *codec;
+ int ret;
wm8580 = kzalloc(sizeof(struct wm8580_priv), GFP_KERNEL);
if (wm8580 == NULL)
return -ENOMEM;
- codec = &wm8580->codec;
-
i2c_set_clientdata(i2c, wm8580);
- codec->control_data = i2c;
-
- codec->dev = &i2c->dev;
+ wm8580->control_data = i2c;
+ wm8580->control_type = SND_SOC_I2C;
- return wm8580_register(wm8580, SND_SOC_I2C);
+ ret = snd_soc_register_codec(&i2c->dev,
+ &soc_codec_dev_wm8580, wm8580_dai, ARRAY_SIZE(wm8580_dai));
+ if (ret < 0)
+ kfree(wm8580);
+ return ret;
}
static int wm8580_i2c_remove(struct i2c_client *client)
{
- struct wm8580_priv *wm8580 = i2c_get_clientdata(client);
- wm8580_unregister(wm8580);
+ snd_soc_unregister_codec(&client->dev);
+ kfree(i2c_get_clientdata(client));
return 0;
}
@@ -961,7 +883,7 @@ MODULE_DEVICE_TABLE(i2c, wm8580_i2c_id);
static struct i2c_driver wm8580_i2c_driver = {
.driver = {
- .name = "wm8580",
+ .name = "wm8580-codec",
.owner = THIS_MODULE,
},
.probe = wm8580_i2c_probe,
@@ -972,7 +894,7 @@ static struct i2c_driver wm8580_i2c_driver = {
static int __init wm8580_modinit(void)
{
- int ret;
+ int ret = 0;
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
ret = i2c_add_driver(&wm8580_i2c_driver);
@@ -981,7 +903,7 @@ static int __init wm8580_modinit(void)
}
#endif
- return 0;
+ return ret;
}
module_init(wm8580_modinit);
diff --git a/sound/soc/codecs/wm8580.h b/sound/soc/codecs/wm8580.h
index 0dfb5ddde6a2..8328ef667593 100644
--- a/sound/soc/codecs/wm8580.h
+++ b/sound/soc/codecs/wm8580.h
@@ -31,8 +31,5 @@
#define WM8580_DAI_PAIFRX 0
#define WM8580_DAI_PAIFTX 1
-extern struct snd_soc_dai wm8580_dai[];
-extern struct snd_soc_codec_device soc_codec_dev_wm8580;
-
#endif
diff --git a/sound/soc/codecs/wm8711.c b/sound/soc/codecs/wm8711.c
index e2dba07f0260..8d942b3b111f 100644
--- a/sound/soc/codecs/wm8711.c
+++ b/sound/soc/codecs/wm8711.c
@@ -31,11 +31,10 @@
#include "wm8711.h"
-static struct snd_soc_codec *wm8711_codec;
-
/* codec private data */
struct wm8711_priv {
- struct snd_soc_codec codec;
+ enum snd_soc_control_type bus_type;
+ void *control_data;
u16 reg_cache[WM8711_CACHEREGNUM];
unsigned int sysclk;
};
@@ -163,7 +162,7 @@ static int wm8711_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct snd_soc_codec *codec = dai->codec;
- struct wm8711_priv *wm8711 = snd_soc_codec_get_drvdata(codec);
+ struct wm8711_priv *wm8711 = snd_soc_codec_get_drvdata(codec);
u16 iface = snd_soc_read(codec, WM8711_IFACE) & 0xfffc;
int i = get_coeff(wm8711->sysclk, params_rate(params));
u16 srate = (coeff_div[i].sr << 2) |
@@ -227,7 +226,7 @@ static int wm8711_set_dai_sysclk(struct snd_soc_dai *codec_dai,
int clk_id, unsigned int freq, int dir)
{
struct snd_soc_codec *codec = codec_dai->codec;
- struct wm8711_priv *wm8711 = snd_soc_codec_get_drvdata(codec);
+ struct wm8711_priv *wm8711 = snd_soc_codec_get_drvdata(codec);
switch (freq) {
case 11289600:
@@ -338,8 +337,8 @@ static struct snd_soc_dai_ops wm8711_ops = {
.set_fmt = wm8711_set_dai_fmt,
};
-struct snd_soc_dai wm8711_dai = {
- .name = "WM8711",
+static struct snd_soc_dai_driver wm8711_dai = {
+ .name = "wm8711-hifi",
.playback = {
.stream_name = "Playback",
.channels_min = 1,
@@ -349,22 +348,16 @@ struct snd_soc_dai wm8711_dai = {
},
.ops = &wm8711_ops,
};
-EXPORT_SYMBOL_GPL(wm8711_dai);
-static int wm8711_suspend(struct platform_device *pdev, pm_message_t state)
+static int wm8711_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;
-
snd_soc_write(codec, WM8711_ACTIVE, 0x0);
wm8711_set_bias_level(codec, SND_SOC_BIAS_OFF);
return 0;
}
-static int wm8711_resume(struct platform_device *pdev)
+static int wm8711_resume(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec = socdev->card->codec;
int i;
u8 data[2];
u16 *cache = codec->reg_cache;
@@ -380,99 +373,24 @@ static int wm8711_resume(struct platform_device *pdev)
return 0;
}
-static int wm8711_probe(struct platform_device *pdev)
+static int wm8711_probe(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec;
- int ret = 0;
-
- if (wm8711_codec == NULL) {
- dev_err(&pdev->dev, "Codec device not registered\n");
- return -ENODEV;
- }
-
- socdev->card->codec = wm8711_codec;
- codec = wm8711_codec;
-
- /* register pcms */
- ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
- if (ret < 0) {
- dev_err(codec->dev, "failed to create pcms: %d\n", ret);
- goto pcm_err;
- }
-
- snd_soc_add_controls(codec, wm8711_snd_controls,
- ARRAY_SIZE(wm8711_snd_controls));
- wm8711_add_widgets(codec);
-
- return ret;
-
-pcm_err:
- return ret;
-}
-
-/* power down chip */
-static int wm8711_remove(struct platform_device *pdev)
-{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
-
- snd_soc_free_pcms(socdev);
- snd_soc_dapm_free(socdev);
-
- return 0;
-}
-
-struct snd_soc_codec_device soc_codec_dev_wm8711 = {
- .probe = wm8711_probe,
- .remove = wm8711_remove,
- .suspend = wm8711_suspend,
- .resume = wm8711_resume,
-};
-EXPORT_SYMBOL_GPL(soc_codec_dev_wm8711);
-
-static int wm8711_register(struct wm8711_priv *wm8711,
- enum snd_soc_control_type control)
-{
- int ret;
- struct snd_soc_codec *codec = &wm8711->codec;
- u16 reg;
-
- if (wm8711_codec) {
- dev_err(codec->dev, "Another WM8711 is registered\n");
- ret = -EINVAL;
- goto err;
- }
-
- mutex_init(&codec->mutex);
- INIT_LIST_HEAD(&codec->dapm_widgets);
- INIT_LIST_HEAD(&codec->dapm_paths);
-
- snd_soc_codec_set_drvdata(codec, wm8711);
- codec->name = "WM8711";
- codec->owner = THIS_MODULE;
- codec->bias_level = SND_SOC_BIAS_OFF;
- codec->set_bias_level = wm8711_set_bias_level;
- codec->dai = &wm8711_dai;
- codec->num_dai = 1;
- codec->reg_cache_size = WM8711_CACHEREGNUM;
- codec->reg_cache = &wm8711->reg_cache;
-
- memcpy(codec->reg_cache, wm8711_reg, sizeof(wm8711_reg));
+ struct wm8711_priv *wm8711 = snd_soc_codec_get_drvdata(codec);
+ int ret, reg;
- ret = snd_soc_codec_set_cache_io(codec, 7, 9, control);
+ codec->control_data = wm8711->control_data;
+ ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8711->bus_type);
if (ret < 0) {
dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- goto err;
+ return ret;
}
ret = wm8711_reset(codec);
if (ret < 0) {
dev_err(codec->dev, "Failed to issue reset\n");
- goto err;
+ return ret;
}
- wm8711_dai.dev = codec->dev;
-
wm8711_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
/* Latch the update bits */
@@ -481,69 +399,63 @@ static int wm8711_register(struct wm8711_priv *wm8711,
reg = snd_soc_read(codec, WM8711_ROUT1V);
snd_soc_write(codec, WM8711_ROUT1V, reg | 0x0100);
- wm8711_codec = codec;
-
- ret = snd_soc_register_codec(codec);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to register codec: %d\n", ret);
- goto err;
- }
-
- ret = snd_soc_register_dai(&wm8711_dai);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
- goto err_codec;
- }
-
- return 0;
+ snd_soc_add_controls(codec, wm8711_snd_controls,
+ ARRAY_SIZE(wm8711_snd_controls));
+ wm8711_add_widgets(codec);
-err_codec:
- snd_soc_unregister_codec(codec);
-err:
- kfree(wm8711);
return ret;
+
}
-static void wm8711_unregister(struct wm8711_priv *wm8711)
+/* power down chip */
+static int wm8711_remove(struct snd_soc_codec *codec)
{
- wm8711_set_bias_level(&wm8711->codec, SND_SOC_BIAS_OFF);
- snd_soc_unregister_dai(&wm8711_dai);
- snd_soc_unregister_codec(&wm8711->codec);
- kfree(wm8711);
- wm8711_codec = NULL;
+ wm8711_set_bias_level(codec, SND_SOC_BIAS_OFF);
+ return 0;
}
+static struct snd_soc_codec_driver soc_codec_dev_wm8711 = {
+ .probe = wm8711_probe,
+ .remove = wm8711_remove,
+ .suspend = wm8711_suspend,
+ .resume = wm8711_resume,
+ .set_bias_level = wm8711_set_bias_level,
+ .reg_cache_size = sizeof(wm8711_reg),
+ .reg_word_size = sizeof(u16),
+ .reg_cache_default = wm8711_reg,
+};
+
#if defined(CONFIG_SPI_MASTER)
static int __devinit wm8711_spi_probe(struct spi_device *spi)
{
- struct snd_soc_codec *codec;
struct wm8711_priv *wm8711;
+ int ret;
wm8711 = kzalloc(sizeof(struct wm8711_priv), GFP_KERNEL);
if (wm8711 == NULL)
return -ENOMEM;
- codec = &wm8711->codec;
- codec->control_data = spi;
- codec->dev = &spi->dev;
+ spi_set_drvdata(spi, wm8711);
+ wm8711->control_data = spi;
+ wm8711->bus_type = SND_SOC_SPI;
- dev_set_drvdata(&spi->dev, wm8711);
-
- return wm8711_register(wm8711, SND_SOC_SPI);
+ ret = snd_soc_register_codec(&spi->dev,
+ &soc_codec_dev_wm8711, &wm8711_dai, 1);
+ if (ret < 0)
+ kfree(wm8711);
+ return ret;
}
static int __devexit wm8711_spi_remove(struct spi_device *spi)
{
- struct wm8711_priv *wm8711 = dev_get_drvdata(&spi->dev);
-
- wm8711_unregister(wm8711);
-
+ snd_soc_unregister_codec(&spi->dev);
+ kfree(spi_get_drvdata(spi));
return 0;
}
static struct spi_driver wm8711_spi_driver = {
.driver = {
- .name = "wm8711",
+ .name = "wm8711-codec",
.bus = &spi_bus_type,
.owner = THIS_MODULE,
},
@@ -553,31 +465,31 @@ static struct spi_driver wm8711_spi_driver = {
#endif /* CONFIG_SPI_MASTER */
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
-static __devinit int wm8711_i2c_probe(struct i2c_client *i2c,
+static __devinit int wm8711_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct wm8711_priv *wm8711;
- struct snd_soc_codec *codec;
+ int ret;
wm8711 = kzalloc(sizeof(struct wm8711_priv), GFP_KERNEL);
if (wm8711 == NULL)
return -ENOMEM;
- codec = &wm8711->codec;
- codec->hw_write = (hw_write_t)i2c_master_send;
-
- i2c_set_clientdata(i2c, wm8711);
- codec->control_data = i2c;
+ i2c_set_clientdata(client, wm8711);
+ wm8711->control_data = client;
+ wm8711->bus_type = SND_SOC_I2C;
- codec->dev = &i2c->dev;
-
- return wm8711_register(wm8711, SND_SOC_I2C);
+ ret = snd_soc_register_codec(&client->dev,
+ &soc_codec_dev_wm8711, &wm8711_dai, 1);
+ if (ret < 0)
+ kfree(wm8711);
+ return ret;
}
static __devexit int wm8711_i2c_remove(struct i2c_client *client)
{
- struct wm8711_priv *wm8711 = i2c_get_clientdata(client);
- wm8711_unregister(wm8711);
+ snd_soc_unregister_codec(&client->dev);
+ kfree(i2c_get_clientdata(client));
return 0;
}
@@ -589,7 +501,7 @@ MODULE_DEVICE_TABLE(i2c, wm8711_i2c_id);
static struct i2c_driver wm8711_i2c_driver = {
.driver = {
- .name = "WM8711 I2C Codec",
+ .name = "wm8711-codec",
.owner = THIS_MODULE,
},
.probe = wm8711_i2c_probe,
diff --git a/sound/soc/codecs/wm8711.h b/sound/soc/codecs/wm8711.h
index 381e84a43816..a61db985499f 100644
--- a/sound/soc/codecs/wm8711.h
+++ b/sound/soc/codecs/wm8711.h
@@ -36,7 +36,4 @@ struct wm8711_setup_data {
unsigned short i2c_address;
};
-extern struct snd_soc_dai wm8711_dai;
-extern struct snd_soc_codec_device soc_codec_dev_wm8711;
-
#endif
diff --git a/sound/soc/codecs/wm8727.c b/sound/soc/codecs/wm8727.c
index 9d1df2628136..6a40080ba701 100644
--- a/sound/soc/codecs/wm8727.c
+++ b/sound/soc/codecs/wm8727.c
@@ -23,7 +23,6 @@
#include <sound/initval.h>
#include <sound/soc.h>
-#include "wm8727.h"
/*
* Note this is a simple chip with no configuration interface, sample rate is
* determined automatically by examining the Master clock and Bit clock ratios
@@ -33,8 +32,8 @@
SNDRV_PCM_RATE_192000)
-struct snd_soc_dai wm8727_dai = {
- .name = "WM8727",
+static struct snd_soc_dai_driver wm8727_dai = {
+ .name = "wm8727-hifi",
.playback = {
.stream_name = "Playback",
.channels_min = 2,
@@ -43,103 +42,18 @@ struct snd_soc_dai wm8727_dai = {
.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
},
};
-EXPORT_SYMBOL_GPL(wm8727_dai);
-static struct snd_soc_codec *wm8727_codec;
+struct snd_soc_codec_driver soc_codec_dev_wm8727;
-static int wm8727_soc_probe(struct platform_device *pdev)
+static __devinit int wm8727_probe(struct platform_device *pdev)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- int ret = 0;
-
- BUG_ON(!wm8727_codec);
-
- socdev->card->codec = wm8727_codec;
-
- /* register pcms */
- ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
- if (ret < 0) {
- printk(KERN_ERR "wm8727: failed to create pcms\n");
- goto pcm_err;
- }
-
- return ret;
-
-pcm_err:
- kfree(socdev->card->codec);
- socdev->card->codec = NULL;
- return ret;
-}
-
-static int wm8727_soc_remove(struct platform_device *pdev)
-{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
-
- snd_soc_free_pcms(socdev);
-
- return 0;
-}
-
-struct snd_soc_codec_device soc_codec_dev_wm8727 = {
- .probe = wm8727_soc_probe,
- .remove = wm8727_soc_remove,
-};
-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;
-
- 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;
- }
-
- return 0;
-
-err_codec:
- snd_soc_unregister_codec(codec);
-err:
- kfree(codec);
- return ret;
+ return snd_soc_register_codec(&pdev->dev,
+ &soc_codec_dev_wm8727, &wm8727_dai, 1);
}
-static int __devexit wm8727_platform_remove(struct platform_device *pdev)
+static int __devexit wm8727_remove(struct platform_device *pdev)
{
- snd_soc_unregister_dai(&wm8727_dai);
- snd_soc_unregister_codec(platform_get_drvdata(pdev));
+ snd_soc_unregister_codec(&pdev->dev);
return 0;
}
@@ -149,8 +63,8 @@ static struct platform_driver wm8727_codec_driver = {
.owner = THIS_MODULE,
},
- .probe = wm8727_platform_probe,
- .remove = __devexit_p(wm8727_platform_remove),
+ .probe = wm8727_probe,
+ .remove = __devexit_p(wm8727_remove),
};
static int __init wm8727_init(void)
diff --git a/sound/soc/codecs/wm8727.h b/sound/soc/codecs/wm8727.h
deleted file mode 100644
index ee19aa71bcdc..000000000000
--- a/sound/soc/codecs/wm8727.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * wm8727.h
- *
- * Created on: 15-Oct-2009
- * Author: neil.jones@imgtec.com
- *
- * Copyright (C) 2009 Imagination Technologies Ltd.
- *
- * 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.
- */
-
-#ifndef WM8727_H_
-#define WM8727_H_
-
-extern struct snd_soc_dai wm8727_dai;
-extern struct snd_soc_codec_device soc_codec_dev_wm8727;
-
-#endif /* WM8727_H_ */
diff --git a/sound/soc/codecs/wm8728.c b/sound/soc/codecs/wm8728.c
index 34be2d2b69ef..ae2292444783 100644
--- a/sound/soc/codecs/wm8728.c
+++ b/sound/soc/codecs/wm8728.c
@@ -29,8 +29,6 @@
#include "wm8728.h"
-struct snd_soc_codec_device soc_codec_dev_wm8728;
-
/*
* We can't read the WM8728 register space so we cache them instead.
* Note that the defaults here aren't the physical defaults, we latch
@@ -44,6 +42,12 @@ static const u16 wm8728_reg_defaults[] = {
0x100,
};
+/* codec private data */
+struct wm8728_priv {
+ enum snd_soc_control_type control_type;
+ void *control_data;
+};
+
static const DECLARE_TLV_DB_SCALE(wm8728_tlv, -12750, 50, 1);
static const struct snd_kcontrol_new wm8728_snd_controls[] = {
@@ -96,8 +100,7 @@ static int wm8728_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;
u16 dac = snd_soc_read(codec, WM8728_DACCTL);
dac &= ~0x18;
@@ -210,8 +213,8 @@ static struct snd_soc_dai_ops wm8728_dai_ops = {
.set_fmt = wm8728_set_dai_fmt,
};
-struct snd_soc_dai wm8728_dai = {
- .name = "WM8728",
+static struct snd_soc_dai_driver wm8728_dai = {
+ .name = "wm8728-hifi",
.playback = {
.stream_name = "Playback",
.channels_min = 2,
@@ -221,63 +224,32 @@ struct snd_soc_dai wm8728_dai = {
},
.ops = &wm8728_dai_ops,
};
-EXPORT_SYMBOL_GPL(wm8728_dai);
-static int wm8728_suspend(struct platform_device *pdev, pm_message_t state)
+static int wm8728_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;
-
wm8728_set_bias_level(codec, SND_SOC_BIAS_OFF);
return 0;
}
-static int wm8728_resume(struct platform_device *pdev)
+static int wm8728_resume(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec = socdev->card->codec;
-
wm8728_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
return 0;
}
-/*
- * initialise the WM8728 driver
- * register the mixer and dsp interfaces with the kernel
- */
-static int wm8728_init(struct snd_soc_device *socdev,
- enum snd_soc_control_type control)
+static int wm8728_probe(struct snd_soc_codec *codec)
{
- struct snd_soc_codec *codec = socdev->card->codec;
- int ret = 0;
-
- codec->name = "WM8728";
- codec->owner = THIS_MODULE;
- codec->set_bias_level = wm8728_set_bias_level;
- codec->dai = &wm8728_dai;
- codec->num_dai = 1;
- codec->bias_level = SND_SOC_BIAS_OFF;
- codec->reg_cache_size = ARRAY_SIZE(wm8728_reg_defaults);
- codec->reg_cache = kmemdup(wm8728_reg_defaults,
- sizeof(wm8728_reg_defaults),
- GFP_KERNEL);
- if (codec->reg_cache == NULL)
- return -ENOMEM;
+ struct wm8728_priv *wm8728 = snd_soc_codec_get_drvdata(codec);
+ int ret;
- ret = snd_soc_codec_set_cache_io(codec, 7, 9, control);
+ codec->control_data = wm8728->control_data;
+ ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8728->control_type);
if (ret < 0) {
printk(KERN_ERR "wm8728: failed to configure cache I/O: %d\n",
ret);
- goto err;
- }
-
- /* register pcms */
- ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
- if (ret < 0) {
- printk(KERN_ERR "wm8728: failed to create pcms\n");
- goto err;
+ return ret;
}
/* power on device */
@@ -288,128 +260,56 @@ static int wm8728_init(struct snd_soc_device *socdev,
wm8728_add_widgets(codec);
return ret;
-
-err:
- kfree(codec->reg_cache);
- return ret;
}
-static struct snd_soc_device *wm8728_socdev;
-
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
-
-/*
- * WM8728 2 wire address is determined by GPIO5
- * state during powerup.
- * low = 0x1a
- * high = 0x1b
- */
-
-static int wm8728_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
+static int wm8728_remove(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = wm8728_socdev;
- struct snd_soc_codec *codec = socdev->card->codec;
- int ret;
-
- i2c_set_clientdata(i2c, codec);
- codec->control_data = i2c;
-
- ret = wm8728_init(socdev, SND_SOC_I2C);
- if (ret < 0)
- pr_err("failed to initialise WM8728\n");
-
- return ret;
-}
-
-static int wm8728_i2c_remove(struct i2c_client *client)
-{
- struct snd_soc_codec *codec = i2c_get_clientdata(client);
- kfree(codec->reg_cache);
+ wm8728_set_bias_level(codec, SND_SOC_BIAS_OFF);
return 0;
}
-static const struct i2c_device_id wm8728_i2c_id[] = {
- { "wm8728", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, wm8728_i2c_id);
-
-static struct i2c_driver wm8728_i2c_driver = {
- .driver = {
- .name = "WM8728 I2C Codec",
- .owner = THIS_MODULE,
- },
- .probe = wm8728_i2c_probe,
- .remove = wm8728_i2c_remove,
- .id_table = wm8728_i2c_id,
+static struct snd_soc_codec_driver soc_codec_dev_wm8728 = {
+ .probe = wm8728_probe,
+ .remove = wm8728_remove,
+ .suspend = wm8728_suspend,
+ .resume = wm8728_resume,
+ .set_bias_level = wm8728_set_bias_level,
+ .reg_cache_size = sizeof(wm8728_reg_defaults),
+ .reg_word_size = sizeof(u16),
+ .reg_cache_default = wm8728_reg_defaults,
};
-static int wm8728_add_i2c_device(struct platform_device *pdev,
- const struct wm8728_setup_data *setup)
-{
- struct i2c_board_info info;
- struct i2c_adapter *adapter;
- struct i2c_client *client;
- int ret;
-
- ret = i2c_add_driver(&wm8728_i2c_driver);
- if (ret != 0) {
- dev_err(&pdev->dev, "can't add i2c driver\n");
- return ret;
- }
-
- memset(&info, 0, sizeof(struct i2c_board_info));
- info.addr = setup->i2c_address;
- strlcpy(info.type, "wm8728", I2C_NAME_SIZE);
-
- adapter = i2c_get_adapter(setup->i2c_bus);
- if (!adapter) {
- dev_err(&pdev->dev, "can't get i2c adapter %d\n",
- setup->i2c_bus);
- goto err_driver;
- }
-
- client = i2c_new_device(adapter, &info);
- i2c_put_adapter(adapter);
- if (!client) {
- dev_err(&pdev->dev, "can't add i2c device at 0x%x\n",
- (unsigned int)info.addr);
- goto err_driver;
- }
-
- return 0;
-
-err_driver:
- i2c_del_driver(&wm8728_i2c_driver);
- return -ENODEV;
-}
-#endif
-
#if defined(CONFIG_SPI_MASTER)
static int __devinit wm8728_spi_probe(struct spi_device *spi)
{
- struct snd_soc_device *socdev = wm8728_socdev;
- struct snd_soc_codec *codec = socdev->card->codec;
+ struct wm8728_priv *wm8728;
int ret;
- codec->control_data = spi;
+ wm8728 = kzalloc(sizeof(struct wm8728_priv), GFP_KERNEL);
+ if (wm8728 == NULL)
+ return -ENOMEM;
- ret = wm8728_init(socdev, SND_SOC_SPI);
- if (ret < 0)
- dev_err(&spi->dev, "failed to initialise WM8728\n");
+ wm8728->control_data = spi;
+ wm8728->control_type = SND_SOC_SPI;
+ spi_set_drvdata(spi, wm8728);
+ ret = snd_soc_register_codec(&spi->dev,
+ &soc_codec_dev_wm8728, &wm8728_dai, 1);
+ if (ret < 0)
+ kfree(wm8728);
return ret;
}
static int __devexit wm8728_spi_remove(struct spi_device *spi)
{
+ snd_soc_unregister_codec(&spi->dev);
+ kfree(spi_get_drvdata(spi));
return 0;
}
static struct spi_driver wm8728_spi_driver = {
.driver = {
- .name = "wm8728",
+ .name = "wm8728-codec",
.bus = &spi_bus_type,
.owner = THIS_MODULE,
},
@@ -418,85 +318,81 @@ static struct spi_driver wm8728_spi_driver = {
};
#endif /* CONFIG_SPI_MASTER */
-static int wm8728_probe(struct platform_device *pdev)
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+static __devinit int wm8728_i2c_probe(struct i2c_client *i2c,
+ const struct i2c_device_id *id)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct wm8728_setup_data *setup;
- struct snd_soc_codec *codec;
- int ret = 0;
+ struct wm8728_priv *wm8728;
+ int ret;
- setup = socdev->codec_data;
- codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
- if (codec == NULL)
+ wm8728 = kzalloc(sizeof(struct wm8728_priv), GFP_KERNEL);
+ if (wm8728 == NULL)
return -ENOMEM;
- socdev->card->codec = codec;
- mutex_init(&codec->mutex);
- INIT_LIST_HEAD(&codec->dapm_widgets);
- INIT_LIST_HEAD(&codec->dapm_paths);
+ i2c_set_clientdata(i2c, wm8728);
+ wm8728->control_data = i2c;
+ wm8728->control_type = SND_SOC_I2C;
+
+ ret = snd_soc_register_codec(&i2c->dev,
+ &soc_codec_dev_wm8728, &wm8728_dai, 1);
+ if (ret < 0)
+ kfree(wm8728);
+ return ret;
+}
+
+static __devexit int wm8728_i2c_remove(struct i2c_client *client)
+{
+ snd_soc_unregister_codec(&client->dev);
+ kfree(i2c_get_clientdata(client));
+ return 0;
+}
- wm8728_socdev = socdev;
- ret = -ENODEV;
+static const struct i2c_device_id wm8728_i2c_id[] = {
+ { "wm8728", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, wm8728_i2c_id);
+
+static struct i2c_driver wm8728_i2c_driver = {
+ .driver = {
+ .name = "wm8728-codec",
+ .owner = THIS_MODULE,
+ },
+ .probe = wm8728_i2c_probe,
+ .remove = __devexit_p(wm8728_i2c_remove),
+ .id_table = wm8728_i2c_id,
+};
+#endif
+static int __init wm8728_modinit(void)
+{
+ int ret = 0;
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
- if (setup->i2c_address) {
- ret = wm8728_add_i2c_device(pdev, setup);
+ ret = i2c_add_driver(&wm8728_i2c_driver);
+ if (ret != 0) {
+ printk(KERN_ERR "Failed to register wm8728 I2C driver: %d\n",
+ ret);
}
#endif
#if defined(CONFIG_SPI_MASTER)
- if (setup->spi) {
- ret = spi_register_driver(&wm8728_spi_driver);
- if (ret != 0)
- printk(KERN_ERR "can't add spi driver");
+ ret = spi_register_driver(&wm8728_spi_driver);
+ if (ret != 0) {
+ printk(KERN_ERR "Failed to register wm8728 SPI driver: %d\n",
+ ret);
}
#endif
-
- if (ret != 0)
- kfree(codec);
-
return ret;
}
+module_init(wm8728_modinit);
-/* power down chip */
-static int wm8728_remove(struct platform_device *pdev)
+static void __exit wm8728_exit(void)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec = socdev->card->codec;
-
- if (codec->control_data)
- wm8728_set_bias_level(codec, SND_SOC_BIAS_OFF);
-
- snd_soc_free_pcms(socdev);
- snd_soc_dapm_free(socdev);
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
- i2c_unregister_device(codec->control_data);
i2c_del_driver(&wm8728_i2c_driver);
#endif
#if defined(CONFIG_SPI_MASTER)
spi_unregister_driver(&wm8728_spi_driver);
#endif
- kfree(codec);
-
- return 0;
-}
-
-struct snd_soc_codec_device soc_codec_dev_wm8728 = {
- .probe = wm8728_probe,
- .remove = wm8728_remove,
- .suspend = wm8728_suspend,
- .resume = wm8728_resume,
-};
-EXPORT_SYMBOL_GPL(soc_codec_dev_wm8728);
-
-static int __init wm8728_modinit(void)
-{
- return snd_soc_register_dai(&wm8728_dai);
-}
-module_init(wm8728_modinit);
-
-static void __exit wm8728_exit(void)
-{
- snd_soc_unregister_dai(&wm8728_dai);
}
module_exit(wm8728_exit);
diff --git a/sound/soc/codecs/wm8728.h b/sound/soc/codecs/wm8728.h
index d269c132474b..8aea362ffd47 100644
--- a/sound/soc/codecs/wm8728.h
+++ b/sound/soc/codecs/wm8728.h
@@ -18,13 +18,4 @@
#define WM8728_DACCTL 0x02
#define WM8728_IFCTL 0x03
-struct wm8728_setup_data {
- int spi;
- int i2c_bus;
- unsigned short i2c_address;
-};
-
-extern struct snd_soc_dai wm8728_dai;
-extern struct snd_soc_codec_device soc_codec_dev_wm8728;
-
#endif
diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c
index 0ab9b6355297..7da360ee1fee 100644
--- a/sound/soc/codecs/wm8731.c
+++ b/sound/soc/codecs/wm8731.c
@@ -32,9 +32,6 @@
#include "wm8731.h"
-static struct snd_soc_codec *wm8731_codec;
-struct snd_soc_codec_device soc_codec_dev_wm8731;
-
#define WM8731_NUM_SUPPLIES 4
static const char *wm8731_supply_names[WM8731_NUM_SUPPLIES] = {
"AVDD",
@@ -45,7 +42,8 @@ static const char *wm8731_supply_names[WM8731_NUM_SUPPLIES] = {
/* codec private data */
struct wm8731_priv {
- struct snd_soc_codec codec;
+ enum snd_soc_control_type control_type;
+ void *control_data;
struct regulator_bulk_data supplies[WM8731_NUM_SUPPLIES];
u16 reg_cache[WM8731_CACHEREGNUM];
unsigned int sysclk;
@@ -222,9 +220,7 @@ static int wm8731_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
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 = dai->codec;
struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec);
u16 iface = snd_soc_read(codec, WM8731_IFACE) & 0xfff3;
int i = get_coeff(wm8731->sysclk, params_rate(params));
@@ -252,9 +248,7 @@ static int wm8731_hw_params(struct snd_pcm_substream *substream,
static int wm8731_pcm_prepare(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 = dai->codec;
/* set active */
snd_soc_write(codec, WM8731_ACTIVE, 0x0001);
@@ -265,9 +259,7 @@ static int wm8731_pcm_prepare(struct snd_pcm_substream *substream,
static void wm8731_shutdown(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 = dai->codec;
/* deactivate */
if (!codec->active) {
@@ -428,8 +420,8 @@ static struct snd_soc_dai_ops wm8731_dai_ops = {
.set_fmt = wm8731_set_dai_fmt,
};
-struct snd_soc_dai wm8731_dai = {
- .name = "WM8731",
+static struct snd_soc_dai_driver wm8731_dai = {
+ .name = "wm8731-hifi",
.playback = {
.stream_name = "Playback",
.channels_min = 1,
@@ -445,24 +437,17 @@ struct snd_soc_dai wm8731_dai = {
.ops = &wm8731_dai_ops,
.symmetric_rates = 1,
};
-EXPORT_SYMBOL_GPL(wm8731_dai);
#ifdef CONFIG_PM
-static int wm8731_suspend(struct platform_device *pdev, pm_message_t state)
+static int wm8731_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;
-
wm8731_set_bias_level(codec, SND_SOC_BIAS_OFF);
return 0;
}
-static int wm8731_resume(struct platform_device *pdev)
+static int wm8731_resume(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec = socdev->card->codec;
-
wm8731_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
return 0;
@@ -472,88 +457,18 @@ static int wm8731_resume(struct platform_device *pdev)
#define wm8731_resume NULL
#endif
-static int wm8731_probe(struct platform_device *pdev)
-{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec;
- int ret = 0;
-
- if (wm8731_codec == NULL) {
- dev_err(&pdev->dev, "Codec device not registered\n");
- return -ENODEV;
- }
-
- socdev->card->codec = wm8731_codec;
- codec = wm8731_codec;
-
- /* register pcms */
- ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
- if (ret < 0) {
- dev_err(codec->dev, "failed to create pcms: %d\n", ret);
- goto pcm_err;
- }
-
- snd_soc_add_controls(codec, wm8731_snd_controls,
- ARRAY_SIZE(wm8731_snd_controls));
- wm8731_add_widgets(codec);
-
- return ret;
-
-pcm_err:
- return ret;
-}
-
-/* power down chip */
-static int wm8731_remove(struct platform_device *pdev)
+static int wm8731_probe(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
-
- snd_soc_free_pcms(socdev);
- snd_soc_dapm_free(socdev);
-
- return 0;
-}
-
-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);
-
-static int wm8731_register(struct wm8731_priv *wm8731,
- enum snd_soc_control_type control)
-{
- int ret, i;
- struct snd_soc_codec *codec = &wm8731->codec;
-
- if (wm8731_codec) {
- dev_err(codec->dev, "Another WM8731 is registered\n");
- ret = -EINVAL;
- goto err;
- }
-
- mutex_init(&codec->mutex);
- INIT_LIST_HEAD(&codec->dapm_widgets);
- INIT_LIST_HEAD(&codec->dapm_paths);
-
- snd_soc_codec_set_drvdata(codec, wm8731);
- codec->name = "WM8731";
- codec->owner = THIS_MODULE;
- codec->bias_level = SND_SOC_BIAS_OFF;
- codec->set_bias_level = wm8731_set_bias_level;
- codec->dai = &wm8731_dai;
- codec->num_dai = 1;
- codec->reg_cache_size = WM8731_CACHEREGNUM;
- codec->reg_cache = &wm8731->reg_cache;
+ struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec);
+ int ret = 0, i;
- memcpy(codec->reg_cache, wm8731_reg, sizeof(wm8731_reg));
+ codec->bias_level = SND_SOC_BIAS_OFF,
+ codec->control_data = wm8731->control_data;
- ret = snd_soc_codec_set_cache_io(codec, 7, 9, control);
+ ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8731->control_type);
if (ret < 0) {
dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- goto err;
+ return ret;
}
for (i = 0; i < ARRAY_SIZE(wm8731->supplies); i++)
@@ -563,7 +478,7 @@ static int wm8731_register(struct wm8731_priv *wm8731,
wm8731->supplies);
if (ret != 0) {
dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
- goto err;
+ return ret;
}
ret = regulator_bulk_enable(ARRAY_SIZE(wm8731->supplies),
@@ -579,8 +494,6 @@ static int wm8731_register(struct wm8731_priv *wm8731,
goto err_regulator_enable;
}
- wm8731_dai.dev = codec->dev;
-
wm8731_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
/* Latch the update bits */
@@ -592,78 +505,79 @@ static int wm8731_register(struct wm8731_priv *wm8731,
/* Disable bypass path by default */
snd_soc_update_bits(codec, WM8731_APANA, 0x4, 0);
- wm8731_codec = codec;
-
- ret = snd_soc_register_codec(codec);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to register codec: %d\n", ret);
- goto err_regulator_enable;
- }
-
- ret = snd_soc_register_dai(&wm8731_dai);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
- snd_soc_unregister_codec(codec);
- goto err_codec;
- }
+ snd_soc_add_controls(codec, wm8731_snd_controls,
+ ARRAY_SIZE(wm8731_snd_controls));
+ wm8731_add_widgets(codec);
/* Regulators will have been enabled by bias management */
regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), wm8731->supplies);
return 0;
-err_codec:
- snd_soc_unregister_codec(codec);
err_regulator_enable:
regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), wm8731->supplies);
err_regulator_get:
regulator_bulk_free(ARRAY_SIZE(wm8731->supplies), wm8731->supplies);
-err:
+
kfree(wm8731);
return ret;
}
-static void wm8731_unregister(struct wm8731_priv *wm8731)
+/* power down chip */
+static int wm8731_remove(struct snd_soc_codec *codec)
{
- wm8731_set_bias_level(&wm8731->codec, SND_SOC_BIAS_OFF);
- snd_soc_unregister_dai(&wm8731_dai);
- snd_soc_unregister_codec(&wm8731->codec);
+ struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec);
+
+ wm8731_set_bias_level(codec, SND_SOC_BIAS_OFF);
+
+ regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), wm8731->supplies);
regulator_bulk_free(ARRAY_SIZE(wm8731->supplies), wm8731->supplies);
- kfree(wm8731);
- wm8731_codec = NULL;
+
+ return 0;
}
+static struct snd_soc_codec_driver soc_codec_dev_wm8731 = {
+ .probe = wm8731_probe,
+ .remove = wm8731_remove,
+ .suspend = wm8731_suspend,
+ .resume = wm8731_resume,
+ .set_bias_level = wm8731_set_bias_level,
+ .reg_cache_size = sizeof(wm8731_reg),
+ .reg_word_size = sizeof(u16),
+ .reg_cache_default = wm8731_reg,
+};
+
#if defined(CONFIG_SPI_MASTER)
static int __devinit wm8731_spi_probe(struct spi_device *spi)
{
- struct snd_soc_codec *codec;
struct wm8731_priv *wm8731;
+ int ret;
wm8731 = kzalloc(sizeof(struct wm8731_priv), GFP_KERNEL);
if (wm8731 == NULL)
return -ENOMEM;
- codec = &wm8731->codec;
- codec->control_data = spi;
- codec->dev = &spi->dev;
-
- dev_set_drvdata(&spi->dev, wm8731);
+ wm8731->control_data = spi;
+ wm8731->control_type = SND_SOC_SPI;
+ spi_set_drvdata(spi, wm8731);
- return wm8731_register(wm8731, SND_SOC_SPI);
+ ret = snd_soc_register_codec(&spi->dev,
+ &soc_codec_dev_wm8731, &wm8731_dai, 1);
+ if (ret < 0)
+ kfree(wm8731);
+ return ret;
}
static int __devexit wm8731_spi_remove(struct spi_device *spi)
{
- struct wm8731_priv *wm8731 = dev_get_drvdata(&spi->dev);
-
- wm8731_unregister(wm8731);
-
+ snd_soc_unregister_codec(&spi->dev);
+ kfree(spi_get_drvdata(spi));
return 0;
}
static struct spi_driver wm8731_spi_driver = {
.driver = {
- .name = "wm8731",
+ .name = "wm8731-codec",
.bus = &spi_bus_type,
.owner = THIS_MODULE,
},
@@ -677,26 +591,27 @@ static __devinit int wm8731_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
struct wm8731_priv *wm8731;
- struct snd_soc_codec *codec;
+ int ret;
wm8731 = kzalloc(sizeof(struct wm8731_priv), GFP_KERNEL);
if (wm8731 == NULL)
return -ENOMEM;
- codec = &wm8731->codec;
-
i2c_set_clientdata(i2c, wm8731);
- codec->control_data = i2c;
+ wm8731->control_data = i2c;
+ wm8731->control_type = SND_SOC_I2C;
- codec->dev = &i2c->dev;
-
- return wm8731_register(wm8731, SND_SOC_I2C);
+ ret = snd_soc_register_codec(&i2c->dev,
+ &soc_codec_dev_wm8731, &wm8731_dai, 1);
+ if (ret < 0)
+ kfree(wm8731);
+ return ret;
}
static __devexit int wm8731_i2c_remove(struct i2c_client *client)
{
- struct wm8731_priv *wm8731 = i2c_get_clientdata(client);
- wm8731_unregister(wm8731);
+ snd_soc_unregister_codec(&client->dev);
+ kfree(i2c_get_clientdata(client));
return 0;
}
@@ -708,7 +623,7 @@ MODULE_DEVICE_TABLE(i2c, wm8731_i2c_id);
static struct i2c_driver wm8731_i2c_driver = {
.driver = {
- .name = "wm8731",
+ .name = "wm8731-codec",
.owner = THIS_MODULE,
},
.probe = wm8731_i2c_probe,
@@ -719,7 +634,7 @@ static struct i2c_driver wm8731_i2c_driver = {
static int __init wm8731_modinit(void)
{
- int ret;
+ int ret = 0;
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
ret = i2c_add_driver(&wm8731_i2c_driver);
if (ret != 0) {
@@ -734,7 +649,7 @@ static int __init wm8731_modinit(void)
ret);
}
#endif
- return 0;
+ return ret;
}
module_init(wm8731_modinit);
diff --git a/sound/soc/codecs/wm8731.h b/sound/soc/codecs/wm8731.h
index cd7b806e8ad0..73a70e206ba9 100644
--- a/sound/soc/codecs/wm8731.h
+++ b/sound/soc/codecs/wm8731.h
@@ -34,7 +34,4 @@
#define WM8731_SYSCLK 0
#define WM8731_DAI 0
-extern struct snd_soc_dai wm8731_dai;
-extern struct snd_soc_codec_device soc_codec_dev_wm8731;
-
#endif
diff --git a/sound/soc/codecs/wm8741.c b/sound/soc/codecs/wm8741.c
index b9ea8904ad4b..0c6d59e4d226 100644
--- a/sound/soc/codecs/wm8741.c
+++ b/sound/soc/codecs/wm8741.c
@@ -30,9 +30,6 @@
#include "wm8741.h"
-static struct snd_soc_codec *wm8741_codec;
-struct snd_soc_codec_device soc_codec_dev_wm8741;
-
#define WM8741_NUM_SUPPLIES 2
static const char *wm8741_supply_names[WM8741_NUM_SUPPLIES] = {
"AVDD",
@@ -43,7 +40,8 @@ static const char *wm8741_supply_names[WM8741_NUM_SUPPLIES] = {
/* codec private data */
struct wm8741_priv {
- struct snd_soc_codec codec;
+ enum snd_soc_control_type control_type;
+ void *control_data;
u16 reg_cache[WM8741_REGISTER_COUNT];
struct regulator_bulk_data supplies[WM8741_NUM_SUPPLIES];
unsigned int sysclk;
@@ -145,8 +143,7 @@ static int wm8741_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 wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec);
u16 iface = snd_soc_read(codec, WM8741_FORMAT_CONTROL) & 0x1FC;
int i;
@@ -314,7 +311,7 @@ static struct snd_soc_dai_ops wm8741_dai_ops = {
.set_fmt = wm8741_set_dai_fmt,
};
-struct snd_soc_dai wm8741_dai = {
+static struct snd_soc_dai_driver wm8741_dai = {
.name = "WM8741",
.playback = {
.stream_name = "Playback",
@@ -325,13 +322,10 @@ struct snd_soc_dai wm8741_dai = {
},
.ops = &wm8741_dai_ops,
};
-EXPORT_SYMBOL_GPL(wm8741_dai);
#ifdef CONFIG_PM
-static int wm8741_resume(struct platform_device *pdev)
+static int wm8741_resume(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec = socdev->card->codec;
u16 *cache = codec->reg_cache;
int i;
@@ -348,189 +342,105 @@ static int wm8741_resume(struct platform_device *pdev)
#define wm8741_resume NULL
#endif
-static int wm8741_probe(struct platform_device *pdev)
+static int wm8741_probe(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec;
+ struct wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec);
int ret = 0;
- if (wm8741_codec == NULL) {
- dev_err(&pdev->dev, "Codec device not registered\n");
- return -ENODEV;
+ codec->control_data = wm8741->control_data;
+ ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8741->control_type);
+ if (ret != 0) {
+ dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
+ return ret;
}
- socdev->card->codec = wm8741_codec;
- codec = wm8741_codec;
-
- /* register pcms */
- ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
+ ret = wm8741_reset(codec);
if (ret < 0) {
- dev_err(codec->dev, "failed to create pcms: %d\n", ret);
- goto pcm_err;
+ dev_err(codec->dev, "Failed to issue reset\n");
+ return ret;
}
+ /* Change some default settings - latch VU */
+ wm8741->reg_cache[WM8741_DACLLSB_ATTENUATION] |= WM8741_UPDATELL;
+ wm8741->reg_cache[WM8741_DACLMSB_ATTENUATION] |= WM8741_UPDATELM;
+ wm8741->reg_cache[WM8741_DACRLSB_ATTENUATION] |= WM8741_UPDATERL;
+ wm8741->reg_cache[WM8741_DACRLSB_ATTENUATION] |= WM8741_UPDATERM;
+
snd_soc_add_controls(codec, wm8741_snd_controls,
ARRAY_SIZE(wm8741_snd_controls));
wm8741_add_widgets(codec);
+ dev_dbg(codec->dev, "Successful registration\n");
return ret;
-
-pcm_err:
- return ret;
-}
-
-static int wm8741_remove(struct platform_device *pdev)
-{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
-
- snd_soc_free_pcms(socdev);
- snd_soc_dapm_free(socdev);
-
- return 0;
}
-struct snd_soc_codec_device soc_codec_dev_wm8741 = {
+static struct snd_soc_codec_driver soc_codec_dev_wm8741 = {
.probe = wm8741_probe,
- .remove = wm8741_remove,
.resume = wm8741_resume,
+ .reg_cache_size = sizeof(wm8741_reg_defaults),
+ .reg_word_size = sizeof(u16),
+ .reg_cache_default = &wm8741_reg_defaults,
};
-EXPORT_SYMBOL_GPL(soc_codec_dev_wm8741);
-static int wm8741_register(struct wm8741_priv *wm8741,
- enum snd_soc_control_type control)
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+static int wm8741_i2c_probe(struct i2c_client *i2c,
+ const struct i2c_device_id *id)
{
- int ret;
- struct snd_soc_codec *codec = &wm8741->codec;
- int i;
-
- if (wm8741_codec) {
- dev_err(codec->dev, "Another WM8741 is registered\n");
- return -EINVAL;
- }
-
- mutex_init(&codec->mutex);
- INIT_LIST_HEAD(&codec->dapm_widgets);
- INIT_LIST_HEAD(&codec->dapm_paths);
+ struct wm8741_priv *wm8741;
+ int ret, i;
- snd_soc_codec_set_drvdata(codec, wm8741);
- codec->name = "WM8741";
- codec->owner = THIS_MODULE;
- codec->bias_level = SND_SOC_BIAS_OFF;
- codec->set_bias_level = NULL;
- codec->dai = &wm8741_dai;
- codec->num_dai = 1;
- codec->reg_cache_size = WM8741_REGISTER_COUNT;
- codec->reg_cache = &wm8741->reg_cache;
+ wm8741 = kzalloc(sizeof(struct wm8741_priv), GFP_KERNEL);
+ if (wm8741 == NULL)
+ return -ENOMEM;
wm8741->rate_constraint.list = &wm8741->rate_constraint_list[0];
wm8741->rate_constraint.count =
ARRAY_SIZE(wm8741->rate_constraint_list);
- memcpy(codec->reg_cache, wm8741_reg_defaults,
- sizeof(wm8741->reg_cache));
-
- ret = snd_soc_codec_set_cache_io(codec, 7, 9, control);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- goto err;
- }
-
for (i = 0; i < ARRAY_SIZE(wm8741->supplies); i++)
wm8741->supplies[i].supply = wm8741_supply_names[i];
- ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8741->supplies),
+ ret = regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm8741->supplies),
wm8741->supplies);
if (ret != 0) {
- dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
+ dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret);
goto err;
}
ret = regulator_bulk_enable(ARRAY_SIZE(wm8741->supplies),
wm8741->supplies);
if (ret != 0) {
- dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
+ dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret);
goto err_get;
}
- ret = wm8741_reset(codec);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to issue reset\n");
- goto err_enable;
- }
-
- wm8741_dai.dev = codec->dev;
-
- /* Change some default settings - latch VU */
- wm8741->reg_cache[WM8741_DACLLSB_ATTENUATION] |= WM8741_UPDATELL;
- wm8741->reg_cache[WM8741_DACLMSB_ATTENUATION] |= WM8741_UPDATELM;
- wm8741->reg_cache[WM8741_DACRLSB_ATTENUATION] |= WM8741_UPDATERL;
- wm8741->reg_cache[WM8741_DACRLSB_ATTENUATION] |= WM8741_UPDATERM;
-
- wm8741_codec = codec;
-
- ret = snd_soc_register_codec(codec);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to register codec: %d\n", ret);
- return ret;
- }
-
- ret = snd_soc_register_dai(&wm8741_dai);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
- snd_soc_unregister_codec(codec);
- return ret;
- }
+ i2c_set_clientdata(i2c, wm8741);
+ wm8741->control_data = i2c;
+ wm8741->control_type = SND_SOC_I2C;
- dev_dbg(codec->dev, "Successful registration\n");
- return 0;
+ ret = snd_soc_register_codec(&i2c->dev,
+ &soc_codec_dev_wm8741, &wm8741_dai, 1);
+ if (ret < 0)
+ goto err_enable;
+ return ret;
err_enable:
regulator_bulk_disable(ARRAY_SIZE(wm8741->supplies), wm8741->supplies);
err_get:
regulator_bulk_free(ARRAY_SIZE(wm8741->supplies), wm8741->supplies);
-
err:
kfree(wm8741);
return ret;
}
-static void wm8741_unregister(struct wm8741_priv *wm8741)
-{
- regulator_bulk_free(ARRAY_SIZE(wm8741->supplies), wm8741->supplies);
-
- snd_soc_unregister_dai(&wm8741_dai);
- snd_soc_unregister_codec(&wm8741->codec);
- kfree(wm8741);
- wm8741_codec = NULL;
-}
-
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
-static __devinit int wm8741_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
-{
- struct wm8741_priv *wm8741;
- struct snd_soc_codec *codec;
-
- wm8741 = kzalloc(sizeof(struct wm8741_priv), GFP_KERNEL);
- if (wm8741 == NULL)
- return -ENOMEM;
-
- codec = &wm8741->codec;
- codec->hw_write = (hw_write_t)i2c_master_send;
-
- i2c_set_clientdata(i2c, wm8741);
- codec->control_data = i2c;
-
- codec->dev = &i2c->dev;
-
- return wm8741_register(wm8741, SND_SOC_I2C);
-}
-
-static __devexit int wm8741_i2c_remove(struct i2c_client *client)
+static int wm8741_i2c_remove(struct i2c_client *client)
{
struct wm8741_priv *wm8741 = i2c_get_clientdata(client);
- wm8741_unregister(wm8741);
+
+ snd_soc_unregister_codec(&client->dev);
+ regulator_bulk_free(ARRAY_SIZE(wm8741->supplies), wm8741->supplies);
+ kfree(i2c_get_clientdata(client));
return 0;
}
@@ -540,29 +450,29 @@ static const struct i2c_device_id wm8741_i2c_id[] = {
};
MODULE_DEVICE_TABLE(i2c, wm8741_i2c_id);
-
static struct i2c_driver wm8741_i2c_driver = {
.driver = {
- .name = "WM8741",
+ .name = "wm8741-codec",
.owner = THIS_MODULE,
},
.probe = wm8741_i2c_probe,
- .remove = __devexit_p(wm8741_i2c_remove),
+ .remove = wm8741_i2c_remove,
.id_table = wm8741_i2c_id,
};
#endif
static int __init wm8741_modinit(void)
{
- int ret;
+ int ret = 0;
+
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
ret = i2c_add_driver(&wm8741_i2c_driver);
if (ret != 0) {
- printk(KERN_ERR "Failed to register WM8741 I2C driver: %d\n",
- ret);
+ pr_err("Failed to register WM8741 I2C driver: %d\n", ret);
}
#endif
- return 0;
+
+ return ret;
}
module_init(wm8741_modinit);
diff --git a/sound/soc/codecs/wm8741.h b/sound/soc/codecs/wm8741.h
index fdef6ecd1f6f..56c1b1d4a681 100644
--- a/sound/soc/codecs/wm8741.h
+++ b/sound/soc/codecs/wm8741.h
@@ -208,7 +208,4 @@
#define WM8741_SYSCLK 0
-extern struct snd_soc_dai wm8741_dai;
-extern struct snd_soc_codec_device soc_codec_dev_wm8741;
-
#endif
diff --git a/sound/soc/codecs/wm8750.c b/sound/soc/codecs/wm8750.c
index e2c05e3e323a..89863a5bc830 100644
--- a/sound/soc/codecs/wm8750.c
+++ b/sound/soc/codecs/wm8750.c
@@ -52,7 +52,8 @@ static const u16 wm8750_reg[] = {
/* codec private data */
struct wm8750_priv {
unsigned int sysclk;
- struct snd_soc_codec codec;
+ enum snd_soc_control_type control_type;
+ void *control_data;
u16 reg_cache[ARRAY_SIZE(wm8750_reg)];
};
@@ -560,8 +561,7 @@ static int wm8750_pcm_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 wm8750_priv *wm8750 = snd_soc_codec_get_drvdata(codec);
u16 iface = snd_soc_read(codec, WM8750_IFACE) & 0x1f3;
u16 srate = snd_soc_read(codec, WM8750_SRATE) & 0x1c0;
@@ -649,8 +649,8 @@ static struct snd_soc_dai_ops wm8750_dai_ops = {
.set_sysclk = wm8750_set_dai_sysclk,
};
-struct snd_soc_dai wm8750_dai = {
- .name = "WM8750",
+static struct snd_soc_dai_driver wm8750_dai = {
+ .name = "wm8750-hifi",
.playback = {
.stream_name = "Playback",
.channels_min = 1,
@@ -665,21 +665,15 @@ struct snd_soc_dai wm8750_dai = {
.formats = WM8750_FORMATS,},
.ops = &wm8750_dai_ops,
};
-EXPORT_SYMBOL_GPL(wm8750_dai);
-static int wm8750_suspend(struct platform_device *pdev, pm_message_t state)
+static int wm8750_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;
-
wm8750_set_bias_level(codec, SND_SOC_BIAS_OFF);
return 0;
}
-static int wm8750_resume(struct platform_device *pdev)
+static int wm8750_resume(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec = socdev->card->codec;
int i;
u8 data[2];
u16 *cache = codec->reg_cache;
@@ -698,100 +692,22 @@ static int wm8750_resume(struct platform_device *pdev)
return 0;
}
-static struct snd_soc_codec *wm8750_codec;
-
-static int wm8750_probe(struct platform_device *pdev)
+static int wm8750_probe(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec;
- int ret = 0;
-
- if (!wm8750_codec) {
- dev_err(&pdev->dev, "WM8750 codec not yet registered\n");
- return -EINVAL;
- }
-
- socdev->card->codec = wm8750_codec;
- codec = wm8750_codec;
-
- /* register pcms */
- ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
- if (ret < 0) {
- printk(KERN_ERR "wm8750: failed to create pcms\n");
- goto err;
- }
-
- snd_soc_add_controls(codec, wm8750_snd_controls,
- ARRAY_SIZE(wm8750_snd_controls));
- wm8750_add_widgets(codec);
-
- return 0;
-
-err:
- return ret;
-}
-
-/* power down chip */
-static int wm8750_remove(struct platform_device *pdev)
-{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
-
- snd_soc_free_pcms(socdev);
- snd_soc_dapm_free(socdev);
-
- return 0;
-}
-
-struct snd_soc_codec_device soc_codec_dev_wm8750 = {
- .probe = wm8750_probe,
- .remove = wm8750_remove,
- .suspend = wm8750_suspend,
- .resume = wm8750_resume,
-};
-EXPORT_SYMBOL_GPL(soc_codec_dev_wm8750);
-
-/*
- * initialise the WM8750 driver
- * register the mixer and dsp interfaces with the kernel
- */
-static int wm8750_register(struct wm8750_priv *wm8750,
- enum snd_soc_control_type control)
-{
- struct snd_soc_codec *codec = &wm8750->codec;
- int reg, ret = 0;
-
- if (wm8750_codec) {
- dev_err(codec->dev, "Multiple WM8750 devices not supported\n");
- ret = -EINVAL;
- goto err;
- }
-
- mutex_init(&codec->mutex);
- INIT_LIST_HEAD(&codec->dapm_widgets);
- INIT_LIST_HEAD(&codec->dapm_paths);
-
- codec->name = "WM8750";
- codec->owner = THIS_MODULE;
- codec->bias_level = SND_SOC_BIAS_STANDBY;
- codec->set_bias_level = wm8750_set_bias_level;
- codec->dai = &wm8750_dai;
- codec->num_dai = 1;
- codec->reg_cache_size = ARRAY_SIZE(wm8750->reg_cache) + 1;
- codec->reg_cache = &wm8750->reg_cache;
- snd_soc_codec_set_drvdata(codec, wm8750);
-
- memcpy(codec->reg_cache, wm8750_reg, sizeof(wm8750->reg_cache));
+ struct wm8750_priv *wm8750 = snd_soc_codec_get_drvdata(codec);
+ int reg, ret;
- ret = snd_soc_codec_set_cache_io(codec, 7, 9, control);
+ codec->control_data = wm8750->control_data;
+ ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8750->control_type);
if (ret < 0) {
printk(KERN_ERR "wm8750: failed to set cache I/O: %d\n", ret);
- goto err;
+ return ret;
}
ret = wm8750_reset(codec);
if (ret < 0) {
printk(KERN_ERR "wm8750: failed to reset: %d\n", ret);
- goto err;
+ return ret;
}
/* charge output caps */
@@ -815,150 +731,133 @@ static int wm8750_register(struct wm8750_priv *wm8750,
reg = snd_soc_read(codec, WM8750_RINVOL);
snd_soc_write(codec, WM8750_RINVOL, reg | 0x0100);
- wm8750_codec = codec;
-
- ret = snd_soc_register_codec(codec);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to register codec: %d\n", ret);
- goto err;
- }
-
- ret = snd_soc_register_dais(&wm8750_dai, 1);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to register DAIs: %d\n", ret);
- goto err_codec;
- }
-
- return 0;
-
-err_codec:
- snd_soc_unregister_codec(codec);
-err:
- kfree(wm8750);
+ snd_soc_add_controls(codec, wm8750_snd_controls,
+ ARRAY_SIZE(wm8750_snd_controls));
+ wm8750_add_widgets(codec);
return ret;
}
-static void wm8750_unregister(struct wm8750_priv *wm8750)
+static int wm8750_remove(struct snd_soc_codec *codec)
{
- wm8750_set_bias_level(&wm8750->codec, SND_SOC_BIAS_OFF);
- snd_soc_unregister_dais(&wm8750_dai, 1);
- snd_soc_unregister_codec(&wm8750->codec);
- kfree(wm8750);
- wm8750_codec = NULL;
+ wm8750_set_bias_level(codec, SND_SOC_BIAS_OFF);
+ return 0;
}
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
-
-/*
- * WM8750 2 wire address is determined by GPIO5
- * state during powerup.
- * low = 0x1a
- * high = 0x1b
- */
+static struct snd_soc_codec_driver soc_codec_dev_wm8750 = {
+ .probe = wm8750_probe,
+ .remove = wm8750_remove,
+ .suspend = wm8750_suspend,
+ .resume = wm8750_resume,
+ .set_bias_level = wm8750_set_bias_level,
+ .reg_cache_size = sizeof(wm8750_reg),
+ .reg_word_size = sizeof(u16),
+ .reg_cache_default = wm8750_reg,
+};
-static int wm8750_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
+#if defined(CONFIG_SPI_MASTER)
+static int __devinit wm8750_spi_probe(struct spi_device *spi)
{
- struct snd_soc_codec *codec;
struct wm8750_priv *wm8750;
+ int ret;
wm8750 = kzalloc(sizeof(struct wm8750_priv), GFP_KERNEL);
if (wm8750 == NULL)
return -ENOMEM;
- codec = &wm8750->codec;
- codec->control_data = i2c;
- i2c_set_clientdata(i2c, wm8750);
-
- codec->dev = &i2c->dev;
+ wm8750->control_data = spi;
+ wm8750->control_type = SND_SOC_SPI;
+ spi_set_drvdata(spi, wm8750);
- return wm8750_register(wm8750, SND_SOC_I2C);
+ ret = snd_soc_register_codec(&spi->dev,
+ &soc_codec_dev_wm8750, &wm8750_dai, 1);
+ if (ret < 0)
+ kfree(wm8750);
+ return ret;
}
-static int wm8750_i2c_remove(struct i2c_client *client)
+static int __devexit wm8750_spi_remove(struct spi_device *spi)
{
- struct wm8750_priv *wm8750 = i2c_get_clientdata(client);
- wm8750_unregister(wm8750);
+ snd_soc_unregister_codec(&spi->dev);
+ kfree(spi_get_drvdata(spi));
return 0;
}
-static const struct i2c_device_id wm8750_i2c_id[] = {
- { "wm8750", 0 },
- { "wm8987", 0 }, /* WM8987 is register compatible with WM8750 */
- { }
-};
-MODULE_DEVICE_TABLE(i2c, wm8750_i2c_id);
-
-static struct i2c_driver wm8750_i2c_driver = {
+static struct spi_driver wm8750_spi_driver = {
.driver = {
- .name = "WM8750 I2C Codec",
- .owner = THIS_MODULE,
+ .name = "wm8750-codec",
+ .bus = &spi_bus_type,
+ .owner = THIS_MODULE,
},
- .probe = wm8750_i2c_probe,
- .remove = wm8750_i2c_remove,
- .id_table = wm8750_i2c_id,
+ .probe = wm8750_spi_probe,
+ .remove = __devexit_p(wm8750_spi_remove),
};
-#endif
+#endif /* CONFIG_SPI_MASTER */
-#if defined(CONFIG_SPI_MASTER)
-static int __devinit wm8750_spi_probe(struct spi_device *spi)
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+static __devinit int wm8750_i2c_probe(struct i2c_client *i2c,
+ const struct i2c_device_id *id)
{
- struct snd_soc_codec *codec;
struct wm8750_priv *wm8750;
+ int ret;
wm8750 = kzalloc(sizeof(struct wm8750_priv), GFP_KERNEL);
if (wm8750 == NULL)
return -ENOMEM;
- codec = &wm8750->codec;
- codec->control_data = spi;
- codec->dev = &spi->dev;
-
- dev_set_drvdata(&spi->dev, wm8750);
+ i2c_set_clientdata(i2c, wm8750);
+ wm8750->control_data = i2c;
+ wm8750->control_type = SND_SOC_I2C;
- return wm8750_register(wm8750, SND_SOC_SPI);
+ ret = snd_soc_register_codec(&i2c->dev,
+ &soc_codec_dev_wm8750, &wm8750_dai, 1);
+ if (ret < 0)
+ kfree(wm8750);
+ return ret;
}
-static int __devexit wm8750_spi_remove(struct spi_device *spi)
+static __devexit int wm8750_i2c_remove(struct i2c_client *client)
{
- struct wm8750_priv *wm8750 = dev_get_drvdata(&spi->dev);
- wm8750_unregister(wm8750);
+ snd_soc_unregister_codec(&client->dev);
+ kfree(i2c_get_clientdata(client));
return 0;
}
-static const struct spi_device_id wm8750_spi_id[] = {
+static const struct i2c_device_id wm8750_i2c_id[] = {
{ "wm8750", 0 },
{ "wm8987", 0 },
{ }
};
-MODULE_DEVICE_TABLE(spi, wm8750_spi_id);
+MODULE_DEVICE_TABLE(i2c, wm8750_i2c_id);
-static struct spi_driver wm8750_spi_driver = {
+static struct i2c_driver wm8750_i2c_driver = {
.driver = {
- .name = "WM8750 SPI Codec",
- .bus = &spi_bus_type,
- .owner = THIS_MODULE,
+ .name = "wm8750-codec",
+ .owner = THIS_MODULE,
},
- .probe = wm8750_spi_probe,
- .remove = __devexit_p(wm8750_spi_remove),
- .id_table = wm8750_spi_id,
+ .probe = wm8750_i2c_probe,
+ .remove = __devexit_p(wm8750_i2c_remove),
+ .id_table = wm8750_i2c_id,
};
#endif
static int __init wm8750_modinit(void)
{
- int ret;
+ int ret = 0;
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
ret = i2c_add_driver(&wm8750_i2c_driver);
- if (ret != 0)
- pr_err("Failed to register WM8750 I2C driver: %d\n", ret);
+ if (ret != 0) {
+ printk(KERN_ERR "Failed to register wm8750 I2C driver: %d\n",
+ ret);
+ }
#endif
#if defined(CONFIG_SPI_MASTER)
ret = spi_register_driver(&wm8750_spi_driver);
- if (ret != 0)
- pr_err("Failed to register WM8750 SPI driver: %d\n", ret);
+ if (ret != 0) {
+ printk(KERN_ERR "Failed to register wm8750 SPI driver: %d\n",
+ ret);
+ }
#endif
- return 0;
+ return ret;
}
module_init(wm8750_modinit);
diff --git a/sound/soc/codecs/wm8750.h b/sound/soc/codecs/wm8750.h
index 1dc100e19cfe..121427c047fb 100644
--- a/sound/soc/codecs/wm8750.h
+++ b/sound/soc/codecs/wm8750.h
@@ -57,13 +57,4 @@
#define WM8750_SYSCLK 0
-struct wm8750_setup_data {
- int spi;
- int i2c_bus;
- unsigned short i2c_address;
-};
-
-extern struct snd_soc_dai wm8750_dai;
-extern struct snd_soc_codec_device soc_codec_dev_wm8750;
-
#endif
diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c
index b59f349c5218..976e408b3616 100644
--- a/sound/soc/codecs/wm8753.c
+++ b/sound/soc/codecs/wm8753.c
@@ -57,7 +57,7 @@ module_param(caps_charge, int, 0);
MODULE_PARM_DESC(caps_charge, "WM8753 cap charge time (msecs)");
static void wm8753_set_dai_mode(struct snd_soc_codec *codec,
- unsigned int mode);
+ struct snd_soc_dai *dai, unsigned int hifi);
/*
* wm8753 register cache
@@ -85,10 +85,12 @@ static const u16 wm8753_reg[] = {
/* codec private data */
struct wm8753_priv {
+ enum snd_soc_control_type control_type;
+ void *control_data;
unsigned int sysclk;
unsigned int pcmclk;
- struct snd_soc_codec codec;
u16 reg_cache[ARRAY_SIZE(wm8753_reg)];
+ int dai_func;
};
/*
@@ -228,6 +230,7 @@ static int wm8753_set_dai(struct snd_kcontrol *kcontrol,
{
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
int mode = wm8753_read_reg_cache(codec, WM8753_IOCTL);
+ struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
if (((mode & 0xc) >> 2) == ucontrol->value.integer.value[0])
return 0;
@@ -235,8 +238,7 @@ static int wm8753_set_dai(struct snd_kcontrol *kcontrol,
mode &= 0xfff3;
mode |= (ucontrol->value.integer.value[0] << 2);
- wm8753_write(codec, WM8753_IOCTL, mode);
- wm8753_set_dai_mode(codec, ucontrol->value.integer.value[0]);
+ wm8753->dai_func = ucontrol->value.integer.value[0];
return 1;
}
@@ -904,6 +906,13 @@ static int wm8753_vdac_adc_set_dai_fmt(struct snd_soc_dai *codec_dai,
return 0;
}
+static int wm8753_pcm_startup(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ wm8753_set_dai_mode(dai->codec, dai, 0);
+ return 0;
+}
+
/*
* Set PCM DAI bit size and sample rate.
*/
@@ -912,8 +921,7 @@ static int wm8753_pcm_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 wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
u16 voice = wm8753_read_reg_cache(codec, WM8753_PCM) & 0x01f3;
u16 srate = wm8753_read_reg_cache(codec, WM8753_SRATE1) & 0x017f;
@@ -1138,6 +1146,13 @@ static int wm8753_i2s_set_dai_fmt(struct snd_soc_dai *codec_dai,
return 0;
}
+static int wm8753_i2s_startup(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ wm8753_set_dai_mode(dai->codec, dai, 1);
+ return 0;
+}
+
/*
* Set PCM DAI bit size and sample rate.
*/
@@ -1146,8 +1161,7 @@ static int wm8753_i2s_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 wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
u16 srate = wm8753_read_reg_cache(codec, WM8753_SRATE1) & 0x01c0;
u16 hifi = wm8753_read_reg_cache(codec, WM8753_HIFI) & 0x01f3;
@@ -1240,12 +1254,12 @@ static int wm8753_mute(struct snd_soc_dai *dai, int mute)
{
struct snd_soc_codec *codec = dai->codec;
u16 mute_reg = wm8753_read_reg_cache(codec, WM8753_DAC) & 0xfff7;
+ struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
/* the digital mute covers the HiFi and Voice DAC's on the WM8753.
* make sure we check if they are not both active when we mute */
- if (mute && dai->id == 1) {
- if (!wm8753_dai[WM8753_DAI_VOICE].playback.active ||
- !wm8753_dai[WM8753_DAI_HIFI].playback.active)
+ if (mute && wm8753->dai_func == 1) {
+ if (!codec->active)
wm8753_write(codec, WM8753_DAC, mute_reg | 0x8);
} else {
if (mute)
@@ -1303,6 +1317,7 @@ static int wm8753_set_bias_level(struct snd_soc_codec *codec,
* 4. Voice disabled - HIFI over HIFI, uses voice DAI LRC for capture
*/
static struct snd_soc_dai_ops wm8753_dai_ops_hifi_mode1 = {
+ .startup = wm8753_i2s_startup,
.hw_params = wm8753_i2s_hw_params,
.digital_mute = wm8753_mute,
.set_fmt = wm8753_mode1h_set_dai_fmt,
@@ -1312,6 +1327,7 @@ static struct snd_soc_dai_ops wm8753_dai_ops_hifi_mode1 = {
};
static struct snd_soc_dai_ops wm8753_dai_ops_voice_mode1 = {
+ .startup = wm8753_pcm_startup,
.hw_params = wm8753_pcm_hw_params,
.digital_mute = wm8753_mute,
.set_fmt = wm8753_mode1v_set_dai_fmt,
@@ -1321,6 +1337,7 @@ static struct snd_soc_dai_ops wm8753_dai_ops_voice_mode1 = {
};
static struct snd_soc_dai_ops wm8753_dai_ops_voice_mode2 = {
+ .startup = wm8753_pcm_startup,
.hw_params = wm8753_pcm_hw_params,
.digital_mute = wm8753_mute,
.set_fmt = wm8753_mode2_set_dai_fmt,
@@ -1330,6 +1347,7 @@ static struct snd_soc_dai_ops wm8753_dai_ops_voice_mode2 = {
};
static struct snd_soc_dai_ops wm8753_dai_ops_hifi_mode3 = {
+ .startup = wm8753_i2s_startup,
.hw_params = wm8753_i2s_hw_params,
.digital_mute = wm8753_mute,
.set_fmt = wm8753_mode3_4_set_dai_fmt,
@@ -1339,6 +1357,7 @@ static struct snd_soc_dai_ops wm8753_dai_ops_hifi_mode3 = {
};
static struct snd_soc_dai_ops wm8753_dai_ops_hifi_mode4 = {
+ .startup = wm8753_i2s_startup,
.hw_params = wm8753_i2s_hw_params,
.digital_mute = wm8753_mute,
.set_fmt = wm8753_mode3_4_set_dai_fmt,
@@ -1347,10 +1366,9 @@ static struct snd_soc_dai_ops wm8753_dai_ops_hifi_mode4 = {
.set_sysclk = wm8753_set_dai_sysclk,
};
-static const struct snd_soc_dai wm8753_all_dai[] = {
+static struct snd_soc_dai_driver wm8753_all_dai[] = {
/* DAI HiFi mode 1 */
-{ .name = "WM8753 HiFi",
- .id = 1,
+{ .name = "wm8753-hifi",
.playback = {
.stream_name = "HiFi Playback",
.channels_min = 1,
@@ -1366,8 +1384,7 @@ static const struct snd_soc_dai wm8753_all_dai[] = {
.ops = &wm8753_dai_ops_hifi_mode1,
},
/* DAI Voice mode 1 */
-{ .name = "WM8753 Voice",
- .id = 1,
+{ .name = "wm8753-voice",
.playback = {
.stream_name = "Voice Playback",
.channels_min = 1,
@@ -1383,12 +1400,10 @@ static const struct snd_soc_dai wm8753_all_dai[] = {
.ops = &wm8753_dai_ops_voice_mode1,
},
/* DAI HiFi mode 2 - dummy */
-{ .name = "WM8753 HiFi",
- .id = 2,
+{ .name = "wm8753-hifi",
},
/* DAI Voice mode 2 */
-{ .name = "WM8753 Voice",
- .id = 2,
+{ .name = "wm8753-voice",
.playback = {
.stream_name = "Voice Playback",
.channels_min = 1,
@@ -1404,8 +1419,7 @@ static const struct snd_soc_dai wm8753_all_dai[] = {
.ops = &wm8753_dai_ops_voice_mode2,
},
/* DAI HiFi mode 3 */
-{ .name = "WM8753 HiFi",
- .id = 3,
+{ .name = "wm8753-hifi",
.playback = {
.stream_name = "HiFi Playback",
.channels_min = 1,
@@ -1421,12 +1435,10 @@ static const struct snd_soc_dai wm8753_all_dai[] = {
.ops = &wm8753_dai_ops_hifi_mode3,
},
/* DAI Voice mode 3 - dummy */
-{ .name = "WM8753 Voice",
- .id = 3,
+{ .name = "wm8753-voice",
},
/* DAI HiFi mode 4 */
-{ .name = "WM8753 HiFi",
- .id = 4,
+{ .name = "wm8753-hifi",
.playback = {
.stream_name = "HiFi Playback",
.channels_min = 1,
@@ -1442,58 +1454,31 @@ static const struct snd_soc_dai wm8753_all_dai[] = {
.ops = &wm8753_dai_ops_hifi_mode4,
},
/* DAI Voice mode 4 - dummy */
-{ .name = "WM8753 Voice",
- .id = 4,
+{ .name = "wm8753-voice",
},
};
-struct snd_soc_dai wm8753_dai[] = {
+static struct snd_soc_dai_driver wm8753_dai[] = {
{
- .name = "WM8753 DAI 0",
+ .name = "wm8753-aif0",
},
{
- .name = "WM8753 DAI 1",
+ .name = "wm8753-aif1",
},
};
-EXPORT_SYMBOL_GPL(wm8753_dai);
-static void wm8753_set_dai_mode(struct snd_soc_codec *codec, unsigned int mode)
+static void wm8753_set_dai_mode(struct snd_soc_codec *codec,
+ struct snd_soc_dai *dai, unsigned int hifi)
{
- if (mode < 4) {
- int playback_active, capture_active, codec_active, pop_wait;
- void *private_data;
- struct list_head list;
-
- playback_active = wm8753_dai[0].playback.active;
- capture_active = wm8753_dai[0].capture.active;
- codec_active = wm8753_dai[0].active;
- private_data = wm8753_dai[0].private_data;
- pop_wait = wm8753_dai[0].pop_wait;
- list = wm8753_dai[0].list;
- wm8753_dai[0] = wm8753_all_dai[mode << 1];
- wm8753_dai[0].playback.active = playback_active;
- wm8753_dai[0].capture.active = capture_active;
- wm8753_dai[0].active = codec_active;
- wm8753_dai[0].private_data = private_data;
- wm8753_dai[0].pop_wait = pop_wait;
- wm8753_dai[0].list = list;
-
- playback_active = wm8753_dai[1].playback.active;
- capture_active = wm8753_dai[1].capture.active;
- codec_active = wm8753_dai[1].active;
- private_data = wm8753_dai[1].private_data;
- pop_wait = wm8753_dai[1].pop_wait;
- list = wm8753_dai[1].list;
- wm8753_dai[1] = wm8753_all_dai[(mode << 1) + 1];
- wm8753_dai[1].playback.active = playback_active;
- wm8753_dai[1].capture.active = capture_active;
- wm8753_dai[1].active = codec_active;
- wm8753_dai[1].private_data = private_data;
- wm8753_dai[1].pop_wait = pop_wait;
- wm8753_dai[1].list = list;
+ struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
+
+ if (wm8753->dai_func < 4) {
+ if (hifi)
+ dai->driver = &wm8753_all_dai[wm8753->dai_func << 1];
+ else
+ dai->driver = &wm8753_all_dai[(wm8753->dai_func << 1) + 1];
}
- wm8753_dai[0].codec = codec;
- wm8753_dai[1].codec = codec;
+ wm8753_write(codec, WM8753_IOCTL, wm8753->dai_func);
}
static void wm8753_work(struct work_struct *work)
@@ -1503,19 +1488,14 @@ static void wm8753_work(struct work_struct *work)
wm8753_set_bias_level(codec, codec->bias_level);
}
-static int wm8753_suspend(struct platform_device *pdev, pm_message_t state)
+static int wm8753_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;
-
wm8753_set_bias_level(codec, SND_SOC_BIAS_OFF);
return 0;
}
-static int wm8753_resume(struct platform_device *pdev)
+static int wm8753_resume(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec = socdev->card->codec;
int i;
u8 data[2];
u16 *cache = codec->reg_cache;
@@ -1547,41 +1527,6 @@ static int wm8753_resume(struct platform_device *pdev)
return 0;
}
-static struct snd_soc_codec *wm8753_codec;
-
-static int wm8753_probe(struct platform_device *pdev)
-{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec;
- int ret = 0;
-
- if (!wm8753_codec) {
- dev_err(&pdev->dev, "WM8753 codec not yet registered\n");
- return -EINVAL;
- }
-
- socdev->card->codec = wm8753_codec;
- codec = wm8753_codec;
-
- wm8753_set_dai_mode(codec, 0);
-
- /* register pcms */
- ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
- if (ret < 0) {
- printk(KERN_ERR "wm8753: failed to create pcms\n");
- goto pcm_err;
- }
-
- snd_soc_add_controls(codec, wm8753_snd_controls,
- ARRAY_SIZE(wm8753_snd_controls));
- wm8753_add_widgets(codec);
-
- return 0;
-
-pcm_err:
- return ret;
-}
-
/*
* This function forces any delayed work to be queued and run.
*/
@@ -1601,62 +1546,30 @@ static int run_delayed_work(struct delayed_work *dwork)
return ret;
}
-/* power down chip */
-static int wm8753_remove(struct platform_device *pdev)
+static int wm8753_probe(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
-
- snd_soc_free_pcms(socdev);
- snd_soc_dapm_free(socdev);
-
- return 0;
-}
-
-struct snd_soc_codec_device soc_codec_dev_wm8753 = {
- .probe = wm8753_probe,
- .remove = wm8753_remove,
- .suspend = wm8753_suspend,
- .resume = wm8753_resume,
-};
-EXPORT_SYMBOL_GPL(soc_codec_dev_wm8753);
+ struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
+ int ret = 0, reg;
-static int wm8753_register(struct wm8753_priv *wm8753)
-{
- int ret, i;
- struct snd_soc_codec *codec = &wm8753->codec;
- u16 reg;
+ codec->bias_level = SND_SOC_BIAS_OFF,
+ codec->control_data = wm8753->control_data;
+ INIT_DELAYED_WORK(&codec->delayed_work, wm8753_work);
- if (wm8753_codec) {
- dev_err(codec->dev, "Multiple WM8753 devices not supported\n");
- ret = -EINVAL;
- goto err;
+ ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8753->control_type);
+ if (ret < 0) {
+ dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
+ return ret;
}
- mutex_init(&codec->mutex);
- INIT_LIST_HEAD(&codec->dapm_widgets);
- INIT_LIST_HEAD(&codec->dapm_paths);
-
- codec->name = "WM8753";
- codec->owner = THIS_MODULE;
- codec->read = wm8753_read_reg_cache;
- codec->write = wm8753_write;
- codec->bias_level = SND_SOC_BIAS_STANDBY;
- codec->set_bias_level = wm8753_set_bias_level;
- codec->dai = wm8753_dai;
- codec->num_dai = 2;
- codec->reg_cache_size = ARRAY_SIZE(wm8753->reg_cache) + 1;
- codec->reg_cache = &wm8753->reg_cache;
- snd_soc_codec_set_drvdata(codec, wm8753);
-
- memcpy(codec->reg_cache, wm8753_reg, sizeof(wm8753->reg_cache));
- INIT_DELAYED_WORK(&codec->delayed_work, wm8753_work);
-
ret = wm8753_reset(codec);
if (ret < 0) {
- dev_err(codec->dev, "Failed to issue reset\n");
- goto err;
+ dev_err(codec->dev, "Failed to issue reset: %d\n", ret);
+ return ret;
}
+ wm8753_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+ wm8753->dai_func = 0;
+
/* charge output caps */
wm8753_set_bias_level(codec, SND_SOC_BIAS_PREPARE);
schedule_delayed_work(&codec->delayed_work,
@@ -1684,165 +1597,139 @@ static int wm8753_register(struct wm8753_priv *wm8753)
reg = wm8753_read_reg_cache(codec, WM8753_RINVOL);
wm8753_write(codec, WM8753_RINVOL, reg | 0x0100);
- wm8753_codec = codec;
-
- for (i = 0; i < ARRAY_SIZE(wm8753_dai); i++)
- wm8753_dai[i].dev = codec->dev;
-
- ret = snd_soc_register_codec(codec);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to register codec: %d\n", ret);
- goto err;
- }
-
- ret = snd_soc_register_dais(&wm8753_dai[0], ARRAY_SIZE(wm8753_dai));
- if (ret != 0) {
- dev_err(codec->dev, "Failed to register DAIs: %d\n", ret);
- goto err_codec;
- }
+ snd_soc_add_controls(codec, wm8753_snd_controls,
+ ARRAY_SIZE(wm8753_snd_controls));
+ wm8753_add_widgets(codec);
return 0;
-err_codec:
run_delayed_work(&codec->delayed_work);
- snd_soc_unregister_codec(codec);
-err:
- kfree(wm8753);
return ret;
}
-static void wm8753_unregister(struct wm8753_priv *wm8753)
+/* power down chip */
+static int wm8753_remove(struct snd_soc_codec *codec)
{
- wm8753_set_bias_level(&wm8753->codec, SND_SOC_BIAS_OFF);
- run_delayed_work(&wm8753->codec.delayed_work);
- snd_soc_unregister_dais(&wm8753_dai[0], ARRAY_SIZE(wm8753_dai));
- snd_soc_unregister_codec(&wm8753->codec);
- kfree(wm8753);
- wm8753_codec = NULL;
+ run_delayed_work(&codec->delayed_work);
+ wm8753_set_bias_level(codec, SND_SOC_BIAS_OFF);
+
+ return 0;
}
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+static struct snd_soc_codec_driver soc_codec_dev_wm8753 = {
+ .probe = wm8753_probe,
+ .remove = wm8753_remove,
+ .suspend = wm8753_suspend,
+ .resume = wm8753_resume,
+ .set_bias_level = wm8753_set_bias_level,
+ .reg_cache_size = sizeof(wm8753_reg),
+ .reg_word_size = sizeof(u16),
+ .reg_cache_default = wm8753_reg,
+};
-static int wm8753_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
+#if defined(CONFIG_SPI_MASTER)
+static int __devinit wm8753_spi_probe(struct spi_device *spi)
{
- struct snd_soc_codec *codec;
struct wm8753_priv *wm8753;
+ int ret;
wm8753 = kzalloc(sizeof(struct wm8753_priv), GFP_KERNEL);
if (wm8753 == NULL)
return -ENOMEM;
- codec = &wm8753->codec;
- codec->hw_write = (hw_write_t)i2c_master_send;
- codec->control_data = i2c;
- i2c_set_clientdata(i2c, wm8753);
-
- codec->dev = &i2c->dev;
+ wm8753->control_data = spi;
+ wm8753->control_type = SND_SOC_SPI;
+ spi_set_drvdata(spi, wm8753);
- return wm8753_register(wm8753);
+ ret = snd_soc_register_codec(&spi->dev,
+ &soc_codec_dev_wm8753, wm8753_dai, ARRAY_SIZE(wm8753_dai));
+ if (ret < 0)
+ kfree(wm8753);
+ return ret;
}
-static int wm8753_i2c_remove(struct i2c_client *client)
+static int __devexit wm8753_spi_remove(struct spi_device *spi)
{
- struct wm8753_priv *wm8753 = i2c_get_clientdata(client);
- wm8753_unregister(wm8753);
- return 0;
+ snd_soc_unregister_codec(&spi->dev);
+ kfree(spi_get_drvdata(spi));
+ return 0;
}
-static const struct i2c_device_id wm8753_i2c_id[] = {
- { "wm8753", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, wm8753_i2c_id);
-
-static struct i2c_driver wm8753_i2c_driver = {
+static struct spi_driver wm8753_spi_driver = {
.driver = {
- .name = "wm8753",
- .owner = THIS_MODULE,
+ .name = "wm8753-codec",
+ .bus = &spi_bus_type,
+ .owner = THIS_MODULE,
},
- .probe = wm8753_i2c_probe,
- .remove = wm8753_i2c_remove,
- .id_table = wm8753_i2c_id,
+ .probe = wm8753_spi_probe,
+ .remove = __devexit_p(wm8753_spi_remove),
};
-#endif
-
-#if defined(CONFIG_SPI_MASTER)
-static int wm8753_spi_write(struct spi_device *spi, const char *data, int len)
-{
- struct spi_transfer t;
- struct spi_message m;
- u8 msg[2];
-
- if (len <= 0)
- return 0;
-
- msg[0] = data[0];
- msg[1] = data[1];
+#endif /* CONFIG_SPI_MASTER */
- spi_message_init(&m);
- memset(&t, 0, (sizeof t));
-
- t.tx_buf = &msg[0];
- t.len = len;
-
- spi_message_add_tail(&t, &m);
- spi_sync(spi, &m);
-
- return len;
-}
-
-static int __devinit wm8753_spi_probe(struct spi_device *spi)
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+static __devinit int wm8753_i2c_probe(struct i2c_client *i2c,
+ const struct i2c_device_id *id)
{
- struct snd_soc_codec *codec;
struct wm8753_priv *wm8753;
+ int ret;
wm8753 = kzalloc(sizeof(struct wm8753_priv), GFP_KERNEL);
if (wm8753 == NULL)
return -ENOMEM;
- codec = &wm8753->codec;
- codec->control_data = spi;
- codec->hw_write = (hw_write_t)wm8753_spi_write;
- codec->dev = &spi->dev;
-
- dev_set_drvdata(&spi->dev, wm8753);
+ i2c_set_clientdata(i2c, wm8753);
+ wm8753->control_data = i2c;
+ wm8753->control_type = SND_SOC_I2C;
- return wm8753_register(wm8753);
+ ret = snd_soc_register_codec(&i2c->dev,
+ &soc_codec_dev_wm8753, wm8753_dai, ARRAY_SIZE(wm8753_dai));
+ if (ret < 0)
+ kfree(wm8753);
+ return ret;
}
-static int __devexit wm8753_spi_remove(struct spi_device *spi)
+static __devexit int wm8753_i2c_remove(struct i2c_client *client)
{
- struct wm8753_priv *wm8753 = dev_get_drvdata(&spi->dev);
- wm8753_unregister(wm8753);
+ snd_soc_unregister_codec(&client->dev);
+ kfree(i2c_get_clientdata(client));
return 0;
}
-static struct spi_driver wm8753_spi_driver = {
+static const struct i2c_device_id wm8753_i2c_id[] = {
+ { "wm8753", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, wm8753_i2c_id);
+
+static struct i2c_driver wm8753_i2c_driver = {
.driver = {
- .name = "wm8753",
- .bus = &spi_bus_type,
- .owner = THIS_MODULE,
+ .name = "wm8753-codec",
+ .owner = THIS_MODULE,
},
- .probe = wm8753_spi_probe,
- .remove = __devexit_p(wm8753_spi_remove),
+ .probe = wm8753_i2c_probe,
+ .remove = __devexit_p(wm8753_i2c_remove),
+ .id_table = wm8753_i2c_id,
};
#endif
static int __init wm8753_modinit(void)
{
- int ret;
+ int ret = 0;
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
ret = i2c_add_driver(&wm8753_i2c_driver);
- if (ret != 0)
- pr_err("Failed to register WM8753 I2C driver: %d\n", ret);
+ if (ret != 0) {
+ printk(KERN_ERR "Failed to register wm8753 I2C driver: %d\n",
+ ret);
+ }
#endif
#if defined(CONFIG_SPI_MASTER)
ret = spi_register_driver(&wm8753_spi_driver);
- if (ret != 0)
- pr_err("Failed to register WM8753 SPI driver: %d\n", ret);
+ if (ret != 0) {
+ printk(KERN_ERR "Failed to register wm8753 SPI driver: %d\n",
+ ret);
+ }
#endif
- return 0;
+ return ret;
}
module_init(wm8753_modinit);
diff --git a/sound/soc/codecs/wm8753.h b/sound/soc/codecs/wm8753.h
index 57b2ba244040..94edac144bcb 100644
--- a/sound/soc/codecs/wm8753.h
+++ b/sound/soc/codecs/wm8753.h
@@ -115,7 +115,4 @@
#define WM8753_DAI_HIFI 0
#define WM8753_DAI_VOICE 1
-extern struct snd_soc_dai wm8753_dai[2];
-extern struct snd_soc_codec_device soc_codec_dev_wm8753;
-
#endif
diff --git a/sound/soc/codecs/wm8776.c b/sound/soc/codecs/wm8776.c
index 4e212ed62ea6..51a2d265d40e 100644
--- a/sound/soc/codecs/wm8776.c
+++ b/sound/soc/codecs/wm8776.c
@@ -31,20 +31,14 @@
#include "wm8776.h"
-static struct snd_soc_codec *wm8776_codec;
-struct snd_soc_codec_device soc_codec_dev_wm8776;
-
/* codec private data */
struct wm8776_priv {
- struct snd_soc_codec codec;
+ enum snd_soc_control_type control_type;
+ void *control_data;
u16 reg_cache[WM8776_CACHEREGNUM];
int sysclk[2];
};
-#ifdef CONFIG_SPI_MASTER
-static int wm8776_spi_write(struct spi_device *spi, const char *data, int len);
-#endif
-
static const u16 wm8776_reg[WM8776_CACHEREGNUM] = {
0x79, 0x79, 0x79, 0xff, 0xff, /* 4 */
0xff, 0x00, 0x90, 0x00, 0x00, /* 9 */
@@ -144,7 +138,7 @@ static int wm8776_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
struct snd_soc_codec *codec = dai->codec;
int reg, iface, master;
- switch (dai->id) {
+ switch (dai->driver->id) {
case WM8776_DAI_DAC:
reg = WM8776_DACIFCTRL;
master = 0x80;
@@ -233,7 +227,7 @@ static int wm8776_hw_params(struct snd_pcm_substream *substream,
iface = 0;
- switch (dai->id) {
+ switch (dai->driver->id) {
case WM8776_DAI_DAC:
iface_reg = WM8776_DACIFCTRL;
master = 0x80;
@@ -267,7 +261,7 @@ static int wm8776_hw_params(struct snd_pcm_substream *substream,
/* Only need to set MCLK/LRCLK ratio if we're master */
if (snd_soc_read(codec, WM8776_MSTRCTRL) & master) {
for (i = 0; i < ARRAY_SIZE(mclk_ratios); i++) {
- if (wm8776->sysclk[dai->id] / params_rate(params)
+ if (wm8776->sysclk[dai->driver->id] / params_rate(params)
== mclk_ratios[i])
break;
}
@@ -275,7 +269,7 @@ static int wm8776_hw_params(struct snd_pcm_substream *substream,
if (i == ARRAY_SIZE(mclk_ratios)) {
dev_err(codec->dev,
"Unable to configure MCLK ratio %d/%d\n",
- wm8776->sysclk[dai->id], params_rate(params));
+ wm8776->sysclk[dai->driver->id], params_rate(params));
return -EINVAL;
}
@@ -305,9 +299,9 @@ static int wm8776_set_sysclk(struct snd_soc_dai *dai,
struct snd_soc_codec *codec = dai->codec;
struct wm8776_priv *wm8776 = snd_soc_codec_get_drvdata(codec);
- BUG_ON(dai->id >= ARRAY_SIZE(wm8776->sysclk));
+ BUG_ON(dai->driver->id >= ARRAY_SIZE(wm8776->sysclk));
- wm8776->sysclk[dai->id] = freq;
+ wm8776->sysclk[dai->driver->id] = freq;
return 0;
}
@@ -357,10 +351,10 @@ static struct snd_soc_dai_ops wm8776_adc_ops = {
.set_sysclk = wm8776_set_sysclk,
};
-struct snd_soc_dai wm8776_dai[] = {
+static struct snd_soc_dai_driver wm8776_dai[] = {
{
- .name = "WM8776 Playback",
- .id = WM8776_DAI_DAC,
+ .name = "wm8776-hifi-playback",
+ .id = WM8776_DAI_DAC,
.playback = {
.stream_name = "Playback",
.channels_min = 2,
@@ -371,8 +365,8 @@ struct snd_soc_dai wm8776_dai[] = {
.ops = &wm8776_dac_ops,
},
{
- .name = "WM8776 Capture",
- .id = WM8776_DAI_ADC,
+ .name = "wm8776-hifi-capture",
+ .id = WM8776_DAI_ADC,
.capture = {
.stream_name = "Capture",
.channels_min = 2,
@@ -383,23 +377,17 @@ struct snd_soc_dai wm8776_dai[] = {
.ops = &wm8776_adc_ops,
},
};
-EXPORT_SYMBOL_GPL(wm8776_dai);
#ifdef CONFIG_PM
-static int wm8776_suspend(struct platform_device *pdev, pm_message_t state)
+static int wm8776_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;
-
wm8776_set_bias_level(codec, SND_SOC_BIAS_OFF);
return 0;
}
-static int wm8776_resume(struct platform_device *pdev)
+static int wm8776_resume(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec = socdev->card->codec;
int i;
u8 data[2];
u16 *cache = codec->reg_cache;
@@ -422,27 +410,31 @@ static int wm8776_resume(struct platform_device *pdev)
#define wm8776_resume NULL
#endif
-static int wm8776_probe(struct platform_device *pdev)
+static int wm8776_probe(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec;
+ struct wm8776_priv *wm8776 = snd_soc_codec_get_drvdata(codec);
int ret = 0;
- if (wm8776_codec == NULL) {
- dev_err(&pdev->dev, "Codec device not registered\n");
- return -ENODEV;
+ codec->control_data = wm8776->control_data;
+ ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8776->control_type);
+ if (ret < 0) {
+ dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
+ return ret;
}
- socdev->card->codec = wm8776_codec;
- codec = wm8776_codec;
-
- /* register pcms */
- ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
+ ret = wm8776_reset(codec);
if (ret < 0) {
- dev_err(codec->dev, "failed to create pcms: %d\n", ret);
- goto pcm_err;
+ dev_err(codec->dev, "Failed to issue reset: %d\n", ret);
+ return ret;
}
+ wm8776_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+
+ /* Latch the update bits; right channel only since we always
+ * update both. */
+ snd_soc_update_bits(codec, WM8776_HPRVOL, 0x100, 0x100);
+ snd_soc_update_bits(codec, WM8776_DACRVOL, 0x100, 0x100);
+
snd_soc_add_controls(codec, wm8776_snd_controls,
ARRAY_SIZE(wm8776_snd_controls));
snd_soc_dapm_new_controls(codec, wm8776_dapm_widgets,
@@ -450,168 +442,57 @@ static int wm8776_probe(struct platform_device *pdev)
snd_soc_dapm_add_routes(codec, routes, ARRAY_SIZE(routes));
return ret;
-
-pcm_err:
- return ret;
}
/* power down chip */
-static int wm8776_remove(struct platform_device *pdev)
+static int wm8776_remove(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
-
- snd_soc_free_pcms(socdev);
- snd_soc_dapm_free(socdev);
-
+ wm8776_set_bias_level(codec, SND_SOC_BIAS_OFF);
return 0;
}
-struct snd_soc_codec_device soc_codec_dev_wm8776 = {
+static struct snd_soc_codec_driver soc_codec_dev_wm8776 = {
.probe = wm8776_probe,
.remove = wm8776_remove,
.suspend = wm8776_suspend,
.resume = wm8776_resume,
+ .set_bias_level = wm8776_set_bias_level,
+ .reg_cache_size = sizeof(wm8776_reg),
+ .reg_word_size = sizeof(u16),
+ .reg_cache_default = wm8776_reg,
};
-EXPORT_SYMBOL_GPL(soc_codec_dev_wm8776);
-
-static int wm8776_register(struct wm8776_priv *wm8776,
- enum snd_soc_control_type control)
-{
- int ret, i;
- struct snd_soc_codec *codec = &wm8776->codec;
-
- if (wm8776_codec) {
- dev_err(codec->dev, "Another WM8776 is registered\n");
- ret = -EINVAL;
- goto err;
- }
-
- mutex_init(&codec->mutex);
- INIT_LIST_HEAD(&codec->dapm_widgets);
- INIT_LIST_HEAD(&codec->dapm_paths);
-
- snd_soc_codec_set_drvdata(codec, wm8776);
- codec->name = "WM8776";
- codec->owner = THIS_MODULE;
- codec->bias_level = SND_SOC_BIAS_OFF;
- codec->set_bias_level = wm8776_set_bias_level;
- codec->dai = wm8776_dai;
- codec->num_dai = ARRAY_SIZE(wm8776_dai);
- codec->reg_cache_size = WM8776_CACHEREGNUM;
- codec->reg_cache = &wm8776->reg_cache;
-
- memcpy(codec->reg_cache, wm8776_reg, sizeof(wm8776_reg));
-
- ret = snd_soc_codec_set_cache_io(codec, 7, 9, control);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- goto err;
- }
-
- for (i = 0; i < ARRAY_SIZE(wm8776_dai); i++)
- wm8776_dai[i].dev = codec->dev;
-
- ret = wm8776_reset(codec);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to issue reset: %d\n", ret);
- goto err;
- }
-
- wm8776_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
- /* Latch the update bits; right channel only since we always
- * update both. */
- snd_soc_update_bits(codec, WM8776_HPRVOL, 0x100, 0x100);
- snd_soc_update_bits(codec, WM8776_DACRVOL, 0x100, 0x100);
-
- wm8776_codec = codec;
-
- ret = snd_soc_register_codec(codec);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to register codec: %d\n", ret);
- goto err;
- }
-
- ret = snd_soc_register_dais(wm8776_dai, ARRAY_SIZE(wm8776_dai));
- if (ret != 0) {
- dev_err(codec->dev, "Failed to register DAIs: %d\n", ret);
- goto err_codec;
- }
-
- return 0;
-
-err_codec:
- snd_soc_unregister_codec(codec);
-err:
- kfree(wm8776);
- return ret;
-}
-
-static void wm8776_unregister(struct wm8776_priv *wm8776)
-{
- wm8776_set_bias_level(&wm8776->codec, SND_SOC_BIAS_OFF);
- snd_soc_unregister_dais(wm8776_dai, ARRAY_SIZE(wm8776_dai));
- snd_soc_unregister_codec(&wm8776->codec);
- kfree(wm8776);
- wm8776_codec = NULL;
-}
#if defined(CONFIG_SPI_MASTER)
-static int wm8776_spi_write(struct spi_device *spi, const char *data, int len)
-{
- struct spi_transfer t;
- struct spi_message m;
- u8 msg[2];
-
- if (len <= 0)
- return 0;
-
- msg[0] = data[0];
- msg[1] = data[1];
-
- spi_message_init(&m);
- memset(&t, 0, (sizeof t));
-
- t.tx_buf = &msg[0];
- t.len = len;
-
- spi_message_add_tail(&t, &m);
- spi_sync(spi, &m);
-
- return len;
-}
-
static int __devinit wm8776_spi_probe(struct spi_device *spi)
{
- struct snd_soc_codec *codec;
struct wm8776_priv *wm8776;
+ int ret;
wm8776 = kzalloc(sizeof(struct wm8776_priv), GFP_KERNEL);
if (wm8776 == NULL)
return -ENOMEM;
- codec = &wm8776->codec;
- codec->control_data = spi;
- codec->hw_write = (hw_write_t)wm8776_spi_write;
- codec->dev = &spi->dev;
+ wm8776->control_data = spi;
+ wm8776->control_type = SND_SOC_SPI;
+ spi_set_drvdata(spi, wm8776);
- dev_set_drvdata(&spi->dev, wm8776);
-
- return wm8776_register(wm8776, SND_SOC_SPI);
+ ret = snd_soc_register_codec(&spi->dev,
+ &soc_codec_dev_wm8776, wm8776_dai, ARRAY_SIZE(wm8776_dai));
+ if (ret < 0)
+ kfree(wm8776);
+ return ret;
}
static int __devexit wm8776_spi_remove(struct spi_device *spi)
{
- struct wm8776_priv *wm8776 = dev_get_drvdata(&spi->dev);
-
- wm8776_unregister(wm8776);
-
+ snd_soc_unregister_codec(&spi->dev);
+ kfree(spi_get_drvdata(spi));
return 0;
}
static struct spi_driver wm8776_spi_driver = {
.driver = {
- .name = "wm8776",
+ .name = "wm8776-codec",
.bus = &spi_bus_type,
.owner = THIS_MODULE,
},
@@ -625,27 +506,27 @@ static __devinit int wm8776_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
struct wm8776_priv *wm8776;
- struct snd_soc_codec *codec;
+ int ret;
wm8776 = kzalloc(sizeof(struct wm8776_priv), GFP_KERNEL);
if (wm8776 == NULL)
return -ENOMEM;
- codec = &wm8776->codec;
- codec->hw_write = (hw_write_t)i2c_master_send;
-
i2c_set_clientdata(i2c, wm8776);
- codec->control_data = i2c;
-
- codec->dev = &i2c->dev;
+ wm8776->control_data = i2c;
+ wm8776->control_type = SND_SOC_I2C;
- return wm8776_register(wm8776, SND_SOC_I2C);
+ ret = snd_soc_register_codec(&i2c->dev,
+ &soc_codec_dev_wm8776, wm8776_dai, ARRAY_SIZE(wm8776_dai));
+ if (ret < 0)
+ kfree(wm8776);
+ return ret;
}
static __devexit int wm8776_i2c_remove(struct i2c_client *client)
{
- struct wm8776_priv *wm8776 = i2c_get_clientdata(client);
- wm8776_unregister(wm8776);
+ snd_soc_unregister_codec(&client->dev);
+ kfree(i2c_get_clientdata(client));
return 0;
}
@@ -657,7 +538,7 @@ MODULE_DEVICE_TABLE(i2c, wm8776_i2c_id);
static struct i2c_driver wm8776_i2c_driver = {
.driver = {
- .name = "wm8776",
+ .name = "wm8776-codec",
.owner = THIS_MODULE,
},
.probe = wm8776_i2c_probe,
@@ -668,22 +549,22 @@ static struct i2c_driver wm8776_i2c_driver = {
static int __init wm8776_modinit(void)
{
- int ret;
+ int ret = 0;
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
ret = i2c_add_driver(&wm8776_i2c_driver);
if (ret != 0) {
- printk(KERN_ERR "Failed to register WM8776 I2C driver: %d\n",
+ printk(KERN_ERR "Failed to register wm8776 I2C driver: %d\n",
ret);
}
#endif
#if defined(CONFIG_SPI_MASTER)
ret = spi_register_driver(&wm8776_spi_driver);
if (ret != 0) {
- printk(KERN_ERR "Failed to register WM8776 SPI driver: %d\n",
+ printk(KERN_ERR "Failed to register wm8776 SPI driver: %d\n",
ret);
}
#endif
- return 0;
+ return ret;
}
module_init(wm8776_modinit);
diff --git a/sound/soc/codecs/wm8776.h b/sound/soc/codecs/wm8776.h
index 6606d25d2d83..4cf1c8e0bfc9 100644
--- a/sound/soc/codecs/wm8776.h
+++ b/sound/soc/codecs/wm8776.h
@@ -45,7 +45,4 @@
#define WM8776_DAI_DAC 0
#define WM8776_DAI_ADC 1
-extern struct snd_soc_dai wm8776_dai[];
-extern struct snd_soc_codec_device soc_codec_dev_wm8776;
-
#endif
diff --git a/sound/soc/codecs/wm8900.c b/sound/soc/codecs/wm8900.c
index 5da17a704e5a..33c3b57f3f66 100644
--- a/sound/soc/codecs/wm8900.c
+++ b/sound/soc/codecs/wm8900.c
@@ -23,6 +23,7 @@
#include <linux/delay.h>
#include <linux/pm.h>
#include <linux/i2c.h>
+#include <linux/spi/spi.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <sound/core.h>
@@ -137,11 +138,9 @@
#define WM8900_LRC_MASK 0xfc00
-struct snd_soc_codec_device soc_codec_dev_wm8900;
-
struct wm8900_priv {
- struct snd_soc_codec codec;
-
+ enum snd_soc_control_type control_type;
+ void *control_data;
u16 reg_cache[WM8900_MAXREG];
u32 fll_in; /* FLL input frequency */
@@ -627,8 +626,7 @@ static int wm8900_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;
u16 reg;
reg = snd_soc_read(codec, WM8900_REG_AUDIO1) & ~0x60;
@@ -1015,8 +1013,8 @@ static struct snd_soc_dai_ops wm8900_dai_ops = {
.digital_mute = wm8900_digital_mute,
};
-struct snd_soc_dai wm8900_dai = {
- .name = "WM8900 HiFi",
+static struct snd_soc_dai_driver wm8900_dai = {
+ .name = "wm8900-hifi",
.playback = {
.stream_name = "HiFi Playback",
.channels_min = 1,
@@ -1033,7 +1031,6 @@ struct snd_soc_dai wm8900_dai = {
},
.ops = &wm8900_dai_ops,
};
-EXPORT_SYMBOL_GPL(wm8900_dai);
static int wm8900_set_bias_level(struct snd_soc_codec *codec,
enum snd_soc_bias_level level)
@@ -1128,10 +1125,8 @@ static int wm8900_set_bias_level(struct snd_soc_codec *codec,
return 0;
}
-static int wm8900_suspend(struct platform_device *pdev, pm_message_t state)
+static int wm8900_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;
struct wm8900_priv *wm8900 = snd_soc_codec_get_drvdata(codec);
int fll_out = wm8900->fll_out;
int fll_in = wm8900->fll_in;
@@ -1140,7 +1135,7 @@ static int wm8900_suspend(struct platform_device *pdev, pm_message_t state)
/* Stop the FLL in an orderly fashion */
ret = wm8900_set_fll(codec, 0, 0, 0);
if (ret != 0) {
- dev_err(&pdev->dev, "Failed to stop FLL\n");
+ dev_err(codec->dev, "Failed to stop FLL\n");
return ret;
}
@@ -1152,10 +1147,8 @@ static int wm8900_suspend(struct platform_device *pdev, pm_message_t state)
return 0;
}
-static int wm8900_resume(struct platform_device *pdev)
+static int wm8900_resume(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec = socdev->card->codec;
struct wm8900_priv *wm8900 = snd_soc_codec_get_drvdata(codec);
u16 *cache;
int i, ret;
@@ -1176,7 +1169,7 @@ static int wm8900_resume(struct platform_device *pdev)
ret = wm8900_set_fll(codec, 0, fll_in, fll_out);
if (ret != 0) {
- dev_err(&pdev->dev, "Failed to restart FLL\n");
+ dev_err(codec->dev, "Failed to restart FLL\n");
return ret;
}
}
@@ -1186,60 +1179,33 @@ static int wm8900_resume(struct platform_device *pdev)
snd_soc_write(codec, i, cache[i]);
kfree(cache);
} else
- dev_err(&pdev->dev, "Unable to allocate register cache\n");
+ dev_err(codec->dev, "Unable to allocate register cache\n");
return 0;
}
-static struct snd_soc_codec *wm8900_codec;
-
-static __devinit int wm8900_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
+static int wm8900_probe(struct snd_soc_codec *codec)
{
- struct wm8900_priv *wm8900;
- struct snd_soc_codec *codec;
- unsigned int reg;
- int ret;
-
- wm8900 = kzalloc(sizeof(struct wm8900_priv), GFP_KERNEL);
- if (wm8900 == NULL)
- return -ENOMEM;
+ struct wm8900_priv *wm8900 = snd_soc_codec_get_drvdata(codec);
+ int ret = 0, reg;
- codec = &wm8900->codec;
- snd_soc_codec_set_drvdata(codec, wm8900);
- codec->reg_cache = &wm8900->reg_cache[0];
- codec->reg_cache_size = WM8900_MAXREG;
-
- mutex_init(&codec->mutex);
- INIT_LIST_HEAD(&codec->dapm_widgets);
- INIT_LIST_HEAD(&codec->dapm_paths);
-
- codec->name = "WM8900";
- codec->owner = THIS_MODULE;
- codec->dai = &wm8900_dai;
- codec->num_dai = 1;
- codec->control_data = i2c;
- codec->set_bias_level = wm8900_set_bias_level;
- codec->volatile_register = wm8900_volatile_register;
- codec->dev = &i2c->dev;
-
- ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
+ codec->control_data = wm8900->control_data;
+ ret = snd_soc_codec_set_cache_io(codec, 8, 16, wm8900->control_type);
if (ret != 0) {
- dev_err(&i2c->dev, "Failed to set cache I/O: %d\n", ret);
- goto err;
+ dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
+ return ret;
}
reg = snd_soc_read(codec, WM8900_REG_ID);
if (reg != 0x8900) {
- dev_err(&i2c->dev, "Device is not a WM8900 - ID %x\n", reg);
- ret = -ENODEV;
- goto err;
+ dev_err(codec->dev, "Device is not a WM8900 - ID %x\n", reg);
+ return -ENODEV;
}
/* Read back from the chip */
reg = snd_soc_read(codec, WM8900_REG_POWER1);
reg = (reg >> 12) & 0xf;
- dev_info(&i2c->dev, "WM8900 revision %d\n", reg);
+ dev_info(codec->dev, "WM8900 revision %d\n", reg);
wm8900_reset(codec);
@@ -1271,43 +1237,97 @@ static __devinit int wm8900_i2c_probe(struct i2c_client *i2c,
/* Set the DAC and mixer output bias */
snd_soc_write(codec, WM8900_REG_OUTBIASCTL, 0x81);
- wm8900_dai.dev = &i2c->dev;
+ snd_soc_add_controls(codec, wm8900_snd_controls,
+ ARRAY_SIZE(wm8900_snd_controls));
+ wm8900_add_widgets(codec);
- wm8900_codec = codec;
+ return 0;
+}
- ret = snd_soc_register_codec(codec);
- if (ret != 0) {
- dev_err(&i2c->dev, "Failed to register codec: %d\n", ret);
- goto err;
- }
+/* power down chip */
+static int wm8900_remove(struct snd_soc_codec *codec)
+{
+ wm8900_set_bias_level(codec, SND_SOC_BIAS_OFF);
+ return 0;
+}
- ret = snd_soc_register_dai(&wm8900_dai);
- if (ret != 0) {
- dev_err(&i2c->dev, "Failed to register DAI: %d\n", ret);
- goto err_codec;
- }
+static struct snd_soc_codec_driver soc_codec_dev_wm8900 = {
+ .probe = wm8900_probe,
+ .remove = wm8900_remove,
+ .suspend = wm8900_suspend,
+ .resume = wm8900_resume,
+ .set_bias_level = wm8900_set_bias_level,
+ .volatile_register = wm8900_volatile_register,
+ .reg_cache_size = sizeof(wm8900_reg_defaults),
+ .reg_word_size = sizeof(u16),
+ .reg_cache_default = wm8900_reg_defaults,
+};
- return ret;
+#if defined(CONFIG_SPI_MASTER)
+static int __devinit wm8900_spi_probe(struct spi_device *spi)
+{
+ struct wm8900_priv *wm8900;
+ int ret;
+
+ wm8900 = kzalloc(sizeof(struct wm8900_priv), GFP_KERNEL);
+ if (wm8900 == NULL)
+ return -ENOMEM;
-err_codec:
- snd_soc_unregister_codec(codec);
-err:
- kfree(wm8900);
- wm8900_codec = NULL;
+ wm8900->control_data = spi;
+ wm8900->control_type = SND_SOC_SPI;
+ spi_set_drvdata(spi, wm8900);
+
+ ret = snd_soc_register_codec(&spi->dev,
+ &soc_codec_dev_wm8900, &wm8900_dai, 1);
+ if (ret < 0)
+ kfree(wm8900);
return ret;
}
-static __devexit int wm8900_i2c_remove(struct i2c_client *client)
+static int __devexit wm8900_spi_remove(struct spi_device *spi)
{
- snd_soc_unregister_dai(&wm8900_dai);
- snd_soc_unregister_codec(wm8900_codec);
+ snd_soc_unregister_codec(&spi->dev);
+ kfree(spi_get_drvdata(spi));
+ return 0;
+}
- wm8900_set_bias_level(wm8900_codec, SND_SOC_BIAS_OFF);
+static struct spi_driver wm8900_spi_driver = {
+ .driver = {
+ .name = "wm8900-codec",
+ .bus = &spi_bus_type,
+ .owner = THIS_MODULE,
+ },
+ .probe = wm8900_spi_probe,
+ .remove = __devexit_p(wm8900_spi_remove),
+};
+#endif /* CONFIG_SPI_MASTER */
+
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+static __devinit int wm8900_i2c_probe(struct i2c_client *i2c,
+ const struct i2c_device_id *id)
+{
+ struct wm8900_priv *wm8900;
+ int ret;
+
+ wm8900 = kzalloc(sizeof(struct wm8900_priv), GFP_KERNEL);
+ if (wm8900 == NULL)
+ return -ENOMEM;
+
+ i2c_set_clientdata(i2c, wm8900);
+ wm8900->control_data = i2c;
+ wm8900->control_type = SND_SOC_I2C;
- wm8900_dai.dev = NULL;
- kfree(snd_soc_codec_get_drvdata(wm8900_codec));
- wm8900_codec = NULL;
+ ret = snd_soc_register_codec(&i2c->dev,
+ &soc_codec_dev_wm8900, &wm8900_dai, 1);
+ if (ret < 0)
+ kfree(wm8900);
+ return ret;
+}
+static __devexit int wm8900_i2c_remove(struct i2c_client *client)
+{
+ snd_soc_unregister_codec(&client->dev);
+ kfree(i2c_get_clientdata(client));
return 0;
}
@@ -1319,71 +1339,44 @@ MODULE_DEVICE_TABLE(i2c, wm8900_i2c_id);
static struct i2c_driver wm8900_i2c_driver = {
.driver = {
- .name = "WM8900",
+ .name = "wm8900-codec",
.owner = THIS_MODULE,
},
- .probe = wm8900_i2c_probe,
- .remove = __devexit_p(wm8900_i2c_remove),
+ .probe = wm8900_i2c_probe,
+ .remove = __devexit_p(wm8900_i2c_remove),
.id_table = wm8900_i2c_id,
};
+#endif
-static int wm8900_probe(struct platform_device *pdev)
+static int __init wm8900_modinit(void)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec;
int ret = 0;
-
- if (!wm8900_codec) {
- dev_err(&pdev->dev, "I2C client not yet instantiated\n");
- return -ENODEV;
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+ ret = i2c_add_driver(&wm8900_i2c_driver);
+ if (ret != 0) {
+ printk(KERN_ERR "Failed to register wm8900 I2C driver: %d\n",
+ ret);
}
-
- codec = wm8900_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 register new PCMs\n");
- goto pcm_err;
+#endif
+#if defined(CONFIG_SPI_MASTER)
+ ret = spi_register_driver(&wm8900_spi_driver);
+ if (ret != 0) {
+ printk(KERN_ERR "Failed to register wm8900 SPI driver: %d\n",
+ ret);
}
-
- snd_soc_add_controls(codec, wm8900_snd_controls,
- ARRAY_SIZE(wm8900_snd_controls));
- wm8900_add_widgets(codec);
-
-pcm_err:
+#endif
return ret;
}
-
-/* power down chip */
-static int wm8900_remove(struct platform_device *pdev)
-{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
-
- snd_soc_free_pcms(socdev);
- snd_soc_dapm_free(socdev);
-
- return 0;
-}
-
-struct snd_soc_codec_device soc_codec_dev_wm8900 = {
- .probe = wm8900_probe,
- .remove = wm8900_remove,
- .suspend = wm8900_suspend,
- .resume = wm8900_resume,
-};
-EXPORT_SYMBOL_GPL(soc_codec_dev_wm8900);
-
-static int __init wm8900_modinit(void)
-{
- return i2c_add_driver(&wm8900_i2c_driver);
-}
module_init(wm8900_modinit);
static void __exit wm8900_exit(void)
{
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
i2c_del_driver(&wm8900_i2c_driver);
+#endif
+#if defined(CONFIG_SPI_MASTER)
+ spi_unregister_driver(&wm8900_spi_driver);
+#endif
}
module_exit(wm8900_exit);
diff --git a/sound/soc/codecs/wm8900.h b/sound/soc/codecs/wm8900.h
index fd15007d10c7..583f257e799b 100644
--- a/sound/soc/codecs/wm8900.h
+++ b/sound/soc/codecs/wm8900.h
@@ -52,7 +52,4 @@
#define WM8900_DAC_CLKDIV_5_5 0x14
#define WM8900_DAC_CLKDIV_6 0x18
-extern struct snd_soc_dai wm8900_dai;
-extern struct snd_soc_codec_device soc_codec_dev_wm8900;
-
#endif
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c
index bf08282d5ee5..f5d73ed72cbd 100644
--- a/sound/soc/codecs/wm8903.c
+++ b/sound/soc/codecs/wm8903.c
@@ -213,10 +213,12 @@ static u16 wm8903_reg_defaults[] = {
};
struct wm8903_priv {
- struct snd_soc_codec codec;
+
u16 reg_cache[ARRAY_SIZE(wm8903_reg_defaults)];
int sysclk;
+ struct i2c_client *control_data;
+ int irq;
/* Reference counts */
int class_w_users;
@@ -252,7 +254,6 @@ static int wm8903_volatile_register(unsigned int reg)
static int wm8903_run_sequence(struct snd_soc_codec *codec, unsigned int start)
{
u16 reg[5];
- struct i2c_client *i2c = codec->control_data;
struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
BUG_ON(start > 48);
@@ -262,7 +263,7 @@ static int wm8903_run_sequence(struct snd_soc_codec *codec, unsigned int start)
snd_soc_write(codec, WM8903_WRITE_SEQUENCER_0,
reg[0] | WM8903_WSEQ_ENA);
- dev_dbg(&i2c->dev, "Starting sequence at %d\n", start);
+ dev_dbg(codec->dev, "Starting sequence at %d\n", start);
snd_soc_write(codec, WM8903_WRITE_SEQUENCER_3,
start | WM8903_WSEQ_START);
@@ -277,7 +278,7 @@ static int wm8903_run_sequence(struct snd_soc_codec *codec, unsigned int start)
reg[4] = snd_soc_read(codec, WM8903_WRITE_SEQUENCER_4);
} while (reg[4] & WM8903_WSEQ_BUSY);
- dev_dbg(&i2c->dev, "Sequence complete\n");
+ dev_dbg(codec->dev, "Sequence complete\n");
/* Disable the sequencer again if we enabled it */
snd_soc_write(codec, WM8903_WRITE_SEQUENCER_0, reg[0]);
@@ -422,7 +423,6 @@ static int wm8903_class_w_put(struct snd_kcontrol *kcontrol,
struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol);
struct snd_soc_codec *codec = widget->codec;
struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
- struct i2c_client *i2c = codec->control_data;
u16 reg;
int ret;
@@ -431,7 +431,7 @@ static int wm8903_class_w_put(struct snd_kcontrol *kcontrol,
/* Turn it off if we're about to enable bypass */
if (ucontrol->value.integer.value[0]) {
if (wm8903->class_w_users == 0) {
- dev_dbg(&i2c->dev, "Disabling Class W\n");
+ dev_dbg(codec->dev, "Disabling Class W\n");
snd_soc_write(codec, WM8903_CLASS_W_0, reg &
~(WM8903_CP_DYN_FREQ | WM8903_CP_DYN_V));
}
@@ -444,14 +444,14 @@ static int wm8903_class_w_put(struct snd_kcontrol *kcontrol,
/* If we've just disabled the last bypass path turn Class W on */
if (!ucontrol->value.integer.value[0]) {
if (wm8903->class_w_users == 1) {
- dev_dbg(&i2c->dev, "Enabling Class W\n");
+ dev_dbg(codec->dev, "Enabling Class W\n");
snd_soc_write(codec, WM8903_CLASS_W_0, reg |
WM8903_CP_DYN_FREQ | WM8903_CP_DYN_V);
}
wm8903->class_w_users--;
}
- dev_dbg(&i2c->dev, "Bypass use count now %d\n",
+ dev_dbg(codec->dev, "Bypass use count now %d\n",
wm8903->class_w_users);
return ret;
@@ -935,7 +935,6 @@ static int wm8903_add_widgets(struct snd_soc_codec *codec)
static int wm8903_set_bias_level(struct snd_soc_codec *codec,
enum snd_soc_bias_level level)
{
- struct i2c_client *i2c = codec->control_data;
u16 reg, reg2;
switch (level) {
@@ -974,7 +973,7 @@ static int wm8903_set_bias_level(struct snd_soc_codec *codec,
/* By default no bypass paths are enabled so
* enable Class W support.
*/
- dev_dbg(&i2c->dev, "Enabling Class W\n");
+ dev_dbg(codec->dev, "Enabling Class W\n");
snd_soc_write(codec, WM8903_CLASS_W_0, reg |
WM8903_CP_DYN_FREQ | WM8903_CP_DYN_V);
}
@@ -1228,10 +1227,8 @@ static int wm8903_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 wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
- struct i2c_client *i2c = codec->control_data;
struct snd_pcm_runtime *master_runtime;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
@@ -1245,7 +1242,7 @@ static int wm8903_startup(struct snd_pcm_substream *substream,
if (wm8903->master_substream) {
master_runtime = wm8903->master_substream->runtime;
- dev_dbg(&i2c->dev, "Constraining to %d bits\n",
+ dev_dbg(codec->dev, "Constraining to %d bits\n",
master_runtime->sample_bits);
snd_pcm_hw_constraint_minmax(substream->runtime,
@@ -1264,8 +1261,7 @@ static void wm8903_shutdown(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 wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
@@ -1284,10 +1280,8 @@ static int wm8903_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 wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
- struct i2c_client *i2c = codec->control_data;
int fs = params_rate(params);
int bclk;
int bclk_div;
@@ -1306,7 +1300,7 @@ static int wm8903_hw_params(struct snd_pcm_substream *substream,
u16 dac_digital1 = snd_soc_read(codec, WM8903_DAC_DIGITAL_1);
if (substream == wm8903->slave_substream) {
- dev_dbg(&i2c->dev, "Ignoring hw_params for slave substream\n");
+ dev_dbg(codec->dev, "Ignoring hw_params for slave substream\n");
return 0;
}
@@ -1332,7 +1326,7 @@ static int wm8903_hw_params(struct snd_pcm_substream *substream,
switch (sample_rates[dsp_config].rate) {
case 88200:
case 96000:
- dev_err(&i2c->dev, "%dHz unsupported by ADC\n",
+ dev_err(codec->dev, "%dHz unsupported by ADC\n",
fs);
return -EINVAL;
@@ -1340,7 +1334,7 @@ static int wm8903_hw_params(struct snd_pcm_substream *substream,
break;
}
- dev_dbg(&i2c->dev, "DSP fs = %dHz\n", sample_rates[dsp_config].rate);
+ dev_dbg(codec->dev, "DSP fs = %dHz\n", sample_rates[dsp_config].rate);
clock1 &= ~WM8903_SAMPLE_RATE_MASK;
clock1 |= sample_rates[dsp_config].value;
@@ -1366,7 +1360,7 @@ static int wm8903_hw_params(struct snd_pcm_substream *substream,
return -EINVAL;
}
- dev_dbg(&i2c->dev, "MCLK = %dHz, target sample rate = %dHz\n",
+ dev_dbg(codec->dev, "MCLK = %dHz, target sample rate = %dHz\n",
wm8903->sysclk, fs);
/* We may not have an MCLK which allows us to generate exactly
@@ -1401,12 +1395,12 @@ static int wm8903_hw_params(struct snd_pcm_substream *substream,
clock1 |= clk_sys_ratios[clk_config].rate << WM8903_CLK_SYS_RATE_SHIFT;
clock1 |= clk_sys_ratios[clk_config].mode << WM8903_CLK_SYS_MODE_SHIFT;
- dev_dbg(&i2c->dev, "CLK_SYS_RATE=%x, CLK_SYS_MODE=%x div=%d\n",
+ dev_dbg(codec->dev, "CLK_SYS_RATE=%x, CLK_SYS_MODE=%x div=%d\n",
clk_sys_ratios[clk_config].rate,
clk_sys_ratios[clk_config].mode,
clk_sys_ratios[clk_config].div);
- dev_dbg(&i2c->dev, "Actual CLK_SYS = %dHz\n", clk_sys);
+ dev_dbg(codec->dev, "Actual CLK_SYS = %dHz\n", clk_sys);
/* We may not get quite the right frequency if using
* approximate clocks so look for the closest match that is
@@ -1428,7 +1422,7 @@ static int wm8903_hw_params(struct snd_pcm_substream *substream,
aif2 &= ~WM8903_BCLK_DIV_MASK;
aif3 &= ~WM8903_LRCLK_RATE_MASK;
- dev_dbg(&i2c->dev, "BCLK ratio %d for %dHz - actual BCLK = %dHz\n",
+ dev_dbg(codec->dev, "BCLK ratio %d for %dHz - actual BCLK = %dHz\n",
bclk_divs[bclk_div].ratio / 10, bclk,
(clk_sys * 10) / bclk_divs[bclk_div].ratio);
@@ -1504,8 +1498,8 @@ EXPORT_SYMBOL_GPL(wm8903_mic_detect);
static irqreturn_t wm8903_irq(int irq, void *data)
{
- struct wm8903_priv *wm8903 = data;
- struct snd_soc_codec *codec = &wm8903->codec;
+ struct snd_soc_codec *codec = data;
+ struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
int mic_report;
int int_pol;
int int_val = 0;
@@ -1586,8 +1580,8 @@ static struct snd_soc_dai_ops wm8903_dai_ops = {
.set_sysclk = wm8903_set_dai_sysclk,
};
-struct snd_soc_dai wm8903_dai = {
- .name = "WM8903",
+static struct snd_soc_dai_driver wm8903_dai = {
+ .name = "wm8903-hifi",
.playback = {
.stream_name = "Playback",
.channels_min = 2,
@@ -1605,23 +1599,16 @@ struct snd_soc_dai wm8903_dai = {
.ops = &wm8903_dai_ops,
.symmetric_rates = 1,
};
-EXPORT_SYMBOL_GPL(wm8903_dai);
-static int wm8903_suspend(struct platform_device *pdev, pm_message_t state)
+static int wm8903_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;
-
wm8903_set_bias_level(codec, SND_SOC_BIAS_OFF);
return 0;
}
-static int wm8903_resume(struct platform_device *pdev)
+static int wm8903_resume(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec = socdev->card->codec;
- struct i2c_client *i2c = codec->control_data;
int i;
u16 *reg_cache = codec->reg_cache;
u16 *tmp_cache = kmemdup(reg_cache, sizeof(wm8903_reg_defaults),
@@ -1637,65 +1624,38 @@ static int wm8903_resume(struct platform_device *pdev)
snd_soc_write(codec, i, tmp_cache[i]);
kfree(tmp_cache);
} else {
- dev_err(&i2c->dev, "Failed to allocate temporary cache\n");
+ dev_err(codec->dev, "Failed to allocate temporary cache\n");
}
return 0;
}
-static struct snd_soc_codec *wm8903_codec;
-
-static __devinit int wm8903_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
+static int wm8903_probe(struct snd_soc_codec *codec)
{
- struct wm8903_platform_data *pdata = dev_get_platdata(&i2c->dev);
- struct wm8903_priv *wm8903;
- struct snd_soc_codec *codec;
+ struct wm8903_platform_data *pdata = dev_get_platdata(codec->dev);
+ struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
int ret, i;
int trigger, irq_pol;
u16 val;
- wm8903 = kzalloc(sizeof(struct wm8903_priv), GFP_KERNEL);
- if (wm8903 == NULL)
- return -ENOMEM;
-
- codec = &wm8903->codec;
-
- mutex_init(&codec->mutex);
- INIT_LIST_HEAD(&codec->dapm_widgets);
- INIT_LIST_HEAD(&codec->dapm_paths);
-
- codec->dev = &i2c->dev;
- codec->name = "WM8903";
- codec->owner = THIS_MODULE;
- codec->bias_level = SND_SOC_BIAS_OFF;
- codec->set_bias_level = wm8903_set_bias_level;
- codec->dai = &wm8903_dai;
- codec->num_dai = 1;
- codec->reg_cache_size = ARRAY_SIZE(wm8903->reg_cache);
- codec->reg_cache = &wm8903->reg_cache[0];
- snd_soc_codec_set_drvdata(codec, wm8903);
- codec->volatile_register = wm8903_volatile_register;
init_completion(&wm8903->wseq);
-
- i2c_set_clientdata(i2c, codec);
- codec->control_data = i2c;
+ codec->control_data = wm8903->control_data;
ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
if (ret != 0) {
- dev_err(&i2c->dev, "Failed to set cache I/O: %d\n", ret);
- goto err;
+ dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
+ return ret;
}
val = snd_soc_read(codec, WM8903_SW_RESET_AND_ID);
if (val != wm8903_reg_defaults[WM8903_SW_RESET_AND_ID]) {
- dev_err(&i2c->dev,
+ dev_err(codec->dev,
"Device with ID register %x is not a WM8903\n", val);
return -ENODEV;
}
val = snd_soc_read(codec, WM8903_REVISION_NUMBER);
- dev_info(&i2c->dev, "WM8903 revision %d\n",
+ dev_info(codec->dev, "WM8903 revision %d\n",
val & WM8903_CHIP_REV_MASK);
wm8903_reset(codec);
@@ -1721,7 +1681,7 @@ static __devinit int wm8903_i2c_probe(struct i2c_client *i2c,
wm8903->mic_delay = pdata->micdet_delay;
}
- if (i2c->irq) {
+ if (wm8903->irq) {
if (pdata && pdata->irq_active_low) {
trigger = IRQF_TRIGGER_LOW;
irq_pol = WM8903_IRQ_POL;
@@ -1733,13 +1693,13 @@ static __devinit int wm8903_i2c_probe(struct i2c_client *i2c,
snd_soc_update_bits(codec, WM8903_INTERRUPT_CONTROL,
WM8903_IRQ_POL, irq_pol);
- ret = request_threaded_irq(i2c->irq, NULL, wm8903_irq,
+ ret = request_threaded_irq(wm8903->irq, NULL, wm8903_irq,
trigger | IRQF_ONESHOT,
- "wm8903", wm8903);
+ "wm8903", codec);
if (ret != 0) {
- dev_err(&i2c->dev, "Failed to request IRQ: %d\n",
+ dev_err(codec->dev, "Failed to request IRQ: %d\n",
ret);
- goto err;
+ return ret;
}
/* Enable write sequencer interrupts */
@@ -1781,133 +1741,97 @@ static __devinit int wm8903_i2c_probe(struct i2c_client *i2c,
val |= WM8903_DAC_MUTEMODE;
snd_soc_write(codec, WM8903_DAC_DIGITAL_1, val);
- wm8903_dai.dev = &i2c->dev;
- wm8903_codec = codec;
-
- ret = snd_soc_register_codec(codec);
- if (ret != 0) {
- dev_err(&i2c->dev, "Failed to register codec: %d\n", ret);
- goto err_irq;
- }
-
- ret = snd_soc_register_dai(&wm8903_dai);
- if (ret != 0) {
- dev_err(&i2c->dev, "Failed to register DAI: %d\n", ret);
- goto err_codec;
- }
-
- return ret;
+ snd_soc_add_controls(codec, wm8903_snd_controls,
+ ARRAY_SIZE(wm8903_snd_controls));
+ wm8903_add_widgets(codec);
-err_codec:
- snd_soc_unregister_codec(codec);
-err_irq:
- if (i2c->irq)
- free_irq(i2c->irq, wm8903);
-err:
- wm8903_codec = NULL;
- kfree(wm8903);
return ret;
}
-static __devexit int wm8903_i2c_remove(struct i2c_client *client)
+/* power down chip */
+static int wm8903_remove(struct snd_soc_codec *codec)
{
- struct snd_soc_codec *codec = i2c_get_clientdata(client);
- struct wm8903_priv *priv = snd_soc_codec_get_drvdata(codec);
+ wm8903_set_bias_level(codec, SND_SOC_BIAS_OFF);
+ return 0;
+}
- snd_soc_unregister_dai(&wm8903_dai);
- snd_soc_unregister_codec(codec);
+static struct snd_soc_codec_driver soc_codec_dev_wm8903 = {
+ .probe = wm8903_probe,
+ .remove = wm8903_remove,
+ .suspend = wm8903_suspend,
+ .resume = wm8903_resume,
+ .set_bias_level = wm8903_set_bias_level,
+ .reg_cache_size = ARRAY_SIZE(wm8903_reg_defaults),
+ .reg_word_size = sizeof(u16),
+ .reg_cache_default = wm8903_reg_defaults,
+ .volatile_register = wm8903_volatile_register,
+};
- wm8903_set_bias_level(codec, SND_SOC_BIAS_OFF);
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+static __devinit int wm8903_i2c_probe(struct i2c_client *i2c,
+ const struct i2c_device_id *id)
+{
+ struct wm8903_priv *wm8903;
+ int ret;
- if (client->irq)
- free_irq(client->irq, priv);
+ wm8903 = kzalloc(sizeof(struct wm8903_priv), GFP_KERNEL);
+ if (wm8903 == NULL)
+ return -ENOMEM;
- kfree(priv);
+ i2c_set_clientdata(i2c, wm8903);
+ wm8903->control_data = i2c;
+ wm8903->irq = i2c->irq;
- wm8903_codec = NULL;
- wm8903_dai.dev = NULL;
+ ret = snd_soc_register_codec(&i2c->dev,
+ &soc_codec_dev_wm8903, &wm8903_dai, 1);
+ if (ret < 0)
+ kfree(wm8903);
+ return ret;
+}
+static __devexit int wm8903_i2c_remove(struct i2c_client *client)
+{
+ snd_soc_unregister_codec(&client->dev);
+ kfree(i2c_get_clientdata(client));
return 0;
}
-/* i2c codec control layer */
static const struct i2c_device_id wm8903_i2c_id[] = {
- { "wm8903", 0 },
- { }
+ { "wm8903", 0 },
+ { }
};
MODULE_DEVICE_TABLE(i2c, wm8903_i2c_id);
static struct i2c_driver wm8903_i2c_driver = {
.driver = {
- .name = "WM8903",
+ .name = "wm8903-codec",
.owner = THIS_MODULE,
},
- .probe = wm8903_i2c_probe,
- .remove = __devexit_p(wm8903_i2c_remove),
+ .probe = wm8903_i2c_probe,
+ .remove = __devexit_p(wm8903_i2c_remove),
.id_table = wm8903_i2c_id,
};
+#endif
-static int wm8903_probe(struct platform_device *pdev)
+static int __init wm8903_modinit(void)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
int ret = 0;
-
- if (!wm8903_codec) {
- dev_err(&pdev->dev, "I2C device not yet probed\n");
- goto err;
- }
-
- socdev->card->codec = wm8903_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");
- goto err;
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+ ret = i2c_add_driver(&wm8903_i2c_driver);
+ if (ret != 0) {
+ printk(KERN_ERR "Failed to register wm8903 I2C driver: %d\n",
+ ret);
}
-
- snd_soc_add_controls(socdev->card->codec, wm8903_snd_controls,
- ARRAY_SIZE(wm8903_snd_controls));
- wm8903_add_widgets(socdev->card->codec);
-
+#endif
return ret;
-
-err:
- return ret;
-}
-
-/* power down chip */
-static int wm8903_remove(struct platform_device *pdev)
-{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec = socdev->card->codec;
-
- if (codec->control_data)
- wm8903_set_bias_level(codec, SND_SOC_BIAS_OFF);
-
- snd_soc_free_pcms(socdev);
- snd_soc_dapm_free(socdev);
-
- return 0;
-}
-
-struct snd_soc_codec_device soc_codec_dev_wm8903 = {
- .probe = wm8903_probe,
- .remove = wm8903_remove,
- .suspend = wm8903_suspend,
- .resume = wm8903_resume,
-};
-EXPORT_SYMBOL_GPL(soc_codec_dev_wm8903);
-
-static int __init wm8903_modinit(void)
-{
- return i2c_add_driver(&wm8903_i2c_driver);
}
module_init(wm8903_modinit);
static void __exit wm8903_exit(void)
{
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
i2c_del_driver(&wm8903_i2c_driver);
+#endif
}
module_exit(wm8903_exit);
diff --git a/sound/soc/codecs/wm8903.h b/sound/soc/codecs/wm8903.h
index ce384a2ad820..996435e681e5 100644
--- a/sound/soc/codecs/wm8903.h
+++ b/sound/soc/codecs/wm8903.h
@@ -15,9 +15,6 @@
#include <linux/i2c.h>
-extern struct snd_soc_dai wm8903_dai;
-extern struct snd_soc_codec_device soc_codec_dev_wm8903;
-
extern int wm8903_mic_detect(struct snd_soc_codec *codec,
struct snd_soc_jack *jack,
int det, int shrt);
diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c
index f7dcabf6283c..33be84e506ea 100644
--- a/sound/soc/codecs/wm8904.c
+++ b/sound/soc/codecs/wm8904.c
@@ -31,9 +31,6 @@
#include "wm8904.h"
-static struct snd_soc_codec *wm8904_codec;
-struct snd_soc_codec_device soc_codec_dev_wm8904;
-
enum wm8904_type {
WM8904,
WM8912,
@@ -52,10 +49,11 @@ static const char *wm8904_supply_names[WM8904_NUM_SUPPLIES] = {
/* codec private data */
struct wm8904_priv {
- struct snd_soc_codec codec;
+
u16 reg_cache[WM8904_MAX_REGISTER + 1];
enum wm8904_type devtype;
+ void *control_data;
struct regulator_bulk_data supplies[WM8904_NUM_SUPPLIES];
@@ -689,7 +687,7 @@ static int wm8904_put_drc_enum(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
+ struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
struct wm8904_pdata *pdata = wm8904->pdata;
int value = ucontrol->value.integer.value[0];
@@ -760,7 +758,7 @@ static int wm8904_put_retune_mobile_enum(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
+ struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
struct wm8904_pdata *pdata = wm8904->pdata;
int value = ucontrol->value.integer.value[0];
@@ -2218,8 +2216,8 @@ static struct snd_soc_dai_ops wm8904_dai_ops = {
.digital_mute = wm8904_digital_mute,
};
-struct snd_soc_dai wm8904_dai = {
- .name = "WM8904",
+static struct snd_soc_dai_driver wm8904_dai = {
+ .name = "wm8904-hifi",
.playback = {
.stream_name = "Playback",
.channels_min = 2,
@@ -2237,24 +2235,17 @@ struct snd_soc_dai wm8904_dai = {
.ops = &wm8904_dai_ops,
.symmetric_rates = 1,
};
-EXPORT_SYMBOL_GPL(wm8904_dai);
#ifdef CONFIG_PM
-static int wm8904_suspend(struct platform_device *pdev, pm_message_t state)
+static int wm8904_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;
-
wm8904_set_bias_level(codec, SND_SOC_BIAS_OFF);
return 0;
}
-static int wm8904_resume(struct platform_device *pdev)
+static int wm8904_resume(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec = socdev->card->codec;
-
wm8904_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
return 0;
@@ -2264,9 +2255,9 @@ static int wm8904_resume(struct platform_device *pdev)
#define wm8904_resume NULL
#endif
-static void wm8904_handle_retune_mobile_pdata(struct wm8904_priv *wm8904)
+static void wm8904_handle_retune_mobile_pdata(struct snd_soc_codec *codec)
{
- struct snd_soc_codec *codec = &wm8904->codec;
+ struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
struct wm8904_pdata *pdata = wm8904->pdata;
struct snd_kcontrol_new control =
SOC_ENUM_EXT("EQ Mode",
@@ -2315,20 +2306,20 @@ static void wm8904_handle_retune_mobile_pdata(struct wm8904_priv *wm8904)
wm8904->retune_mobile_enum.max = wm8904->num_retune_mobile_texts;
wm8904->retune_mobile_enum.texts = wm8904->retune_mobile_texts;
- ret = snd_soc_add_controls(&wm8904->codec, &control, 1);
+ ret = snd_soc_add_controls(codec, &control, 1);
if (ret != 0)
- dev_err(wm8904->codec.dev,
+ dev_err(codec->dev,
"Failed to add ReTune Mobile control: %d\n", ret);
}
-static void wm8904_handle_pdata(struct wm8904_priv *wm8904)
+static void wm8904_handle_pdata(struct snd_soc_codec *codec)
{
- struct snd_soc_codec *codec = &wm8904->codec;
+ struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
struct wm8904_pdata *pdata = wm8904->pdata;
int ret, i;
if (!pdata) {
- snd_soc_add_controls(&wm8904->codec, wm8904_eq_controls,
+ snd_soc_add_controls(codec, wm8904_eq_controls,
ARRAY_SIZE(wm8904_eq_controls));
return;
}
@@ -2344,7 +2335,7 @@ static void wm8904_handle_pdata(struct wm8904_priv *wm8904)
wm8904->drc_texts = kmalloc(sizeof(char *)
* pdata->num_drc_cfgs, GFP_KERNEL);
if (!wm8904->drc_texts) {
- dev_err(wm8904->codec.dev,
+ dev_err(codec->dev,
"Failed to allocate %d DRC config texts\n",
pdata->num_drc_cfgs);
return;
@@ -2356,9 +2347,9 @@ static void wm8904_handle_pdata(struct wm8904_priv *wm8904)
wm8904->drc_enum.max = pdata->num_drc_cfgs;
wm8904->drc_enum.texts = wm8904->drc_texts;
- ret = snd_soc_add_controls(&wm8904->codec, &control, 1);
+ ret = snd_soc_add_controls(codec, &control, 1);
if (ret != 0)
- dev_err(wm8904->codec.dev,
+ dev_err(codec->dev,
"Failed to add DRC mode control: %d\n", ret);
wm8904_set_drc(codec);
@@ -2368,89 +2359,19 @@ static void wm8904_handle_pdata(struct wm8904_priv *wm8904)
pdata->num_retune_mobile_cfgs);
if (pdata->num_retune_mobile_cfgs)
- wm8904_handle_retune_mobile_pdata(wm8904);
+ wm8904_handle_retune_mobile_pdata(codec);
else
- snd_soc_add_controls(&wm8904->codec, wm8904_eq_controls,
+ snd_soc_add_controls(codec, wm8904_eq_controls,
ARRAY_SIZE(wm8904_eq_controls));
}
-static int wm8904_probe(struct platform_device *pdev)
-{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec;
- int ret = 0;
-
- if (wm8904_codec == NULL) {
- dev_err(&pdev->dev, "Codec device not registered\n");
- return -ENODEV;
- }
- socdev->card->codec = wm8904_codec;
- codec = wm8904_codec;
-
- /* register pcms */
- ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
- if (ret < 0) {
- dev_err(codec->dev, "failed to create pcms: %d\n", ret);
- goto pcm_err;
- }
-
- wm8904_handle_pdata(snd_soc_codec_get_drvdata(codec));
-
- wm8904_add_widgets(codec);
-
- return ret;
-
-pcm_err:
- return ret;
-}
-
-static int wm8904_remove(struct platform_device *pdev)
-{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
-
- snd_soc_free_pcms(socdev);
- snd_soc_dapm_free(socdev);
-
- return 0;
-}
-
-struct snd_soc_codec_device soc_codec_dev_wm8904 = {
- .probe = wm8904_probe,
- .remove = wm8904_remove,
- .suspend = wm8904_suspend,
- .resume = wm8904_resume,
-};
-EXPORT_SYMBOL_GPL(soc_codec_dev_wm8904);
-
-static int wm8904_register(struct wm8904_priv *wm8904,
- enum snd_soc_control_type control)
+static int wm8904_probe(struct snd_soc_codec *codec)
{
+ struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
struct wm8904_pdata *pdata = wm8904->pdata;
- int ret;
- struct snd_soc_codec *codec = &wm8904->codec;
- int i;
-
- if (wm8904_codec) {
- dev_err(codec->dev, "Another WM8904 is registered\n");
- ret = -EINVAL;
- goto err;
- }
+ int ret, i;
- mutex_init(&codec->mutex);
- INIT_LIST_HEAD(&codec->dapm_widgets);
- INIT_LIST_HEAD(&codec->dapm_paths);
-
- snd_soc_codec_set_drvdata(codec, wm8904);
- codec->name = "WM8904";
- codec->owner = THIS_MODULE;
- codec->bias_level = SND_SOC_BIAS_OFF;
- codec->set_bias_level = wm8904_set_bias_level;
- codec->dai = &wm8904_dai;
- codec->num_dai = 1;
- codec->reg_cache_size = WM8904_MAX_REGISTER;
- codec->reg_cache = &wm8904->reg_cache;
- codec->volatile_register = wm8904_volatile_register;
codec->cache_sync = 1;
codec->idle_bias_off = 1;
@@ -2463,16 +2384,13 @@ static int wm8904_register(struct wm8904_priv *wm8904,
default:
dev_err(codec->dev, "Unknown device type %d\n",
wm8904->devtype);
- ret = -EINVAL;
- goto err;
+ return -EINVAL;
}
- memcpy(codec->reg_cache, wm8904_reg, sizeof(wm8904_reg));
-
- ret = snd_soc_codec_set_cache_io(codec, 8, 16, control);
+ ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
if (ret != 0) {
dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- goto err;
+ return ret;
}
for (i = 0; i < ARRAY_SIZE(wm8904->supplies); i++)
@@ -2482,7 +2400,7 @@ static int wm8904_register(struct wm8904_priv *wm8904,
wm8904->supplies);
if (ret != 0) {
dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
- goto err;
+ return ret;
}
ret = regulator_bulk_enable(ARRAY_SIZE(wm8904->supplies),
@@ -2517,8 +2435,6 @@ static int wm8904_register(struct wm8904_priv *wm8904,
goto err_enable;
}
- wm8904_dai.dev = codec->dev;
-
/* Change some default settings - latch VU and enable ZC */
wm8904->reg_cache[WM8904_ADC_DIGITAL_VOLUME_LEFT] |= WM8904_ADC_VU;
wm8904->reg_cache[WM8904_ADC_DIGITAL_VOLUME_RIGHT] |= WM8904_ADC_VU;
@@ -2563,72 +2479,68 @@ static int wm8904_register(struct wm8904_priv *wm8904,
/* Bias level configuration will have done an extra enable */
regulator_bulk_disable(ARRAY_SIZE(wm8904->supplies), wm8904->supplies);
- wm8904_codec = codec;
+ wm8904_handle_pdata(codec);
- ret = snd_soc_register_codec(codec);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to register codec: %d\n", ret);
- goto err_enable;
- }
-
- ret = snd_soc_register_dai(&wm8904_dai);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
- goto err_codec;
- }
+ wm8904_add_widgets(codec);
return 0;
-err_codec:
- snd_soc_unregister_codec(codec);
err_enable:
regulator_bulk_disable(ARRAY_SIZE(wm8904->supplies), wm8904->supplies);
err_get:
regulator_bulk_free(ARRAY_SIZE(wm8904->supplies), wm8904->supplies);
-err:
- kfree(wm8904);
return ret;
}
-static void wm8904_unregister(struct wm8904_priv *wm8904)
+static int wm8904_remove(struct snd_soc_codec *codec)
{
- wm8904_set_bias_level(&wm8904->codec, SND_SOC_BIAS_OFF);
+ struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
+
+ wm8904_set_bias_level(codec, SND_SOC_BIAS_OFF);
regulator_bulk_free(ARRAY_SIZE(wm8904->supplies), wm8904->supplies);
- snd_soc_unregister_dai(&wm8904_dai);
- snd_soc_unregister_codec(&wm8904->codec);
- kfree(wm8904);
- wm8904_codec = NULL;
+
+ return 0;
}
+static struct snd_soc_codec_driver soc_codec_dev_wm8904 = {
+ .probe = wm8904_probe,
+ .remove = wm8904_remove,
+ .suspend = wm8904_suspend,
+ .resume = wm8904_resume,
+ .set_bias_level = wm8904_set_bias_level,
+ .reg_cache_size = ARRAY_SIZE(wm8904_reg),
+ .reg_word_size = sizeof(u16),
+ .reg_cache_default = wm8904_reg,
+ .volatile_register = wm8904_volatile_register,
+};
+
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
static __devinit int wm8904_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
struct wm8904_priv *wm8904;
- struct snd_soc_codec *codec;
+ int ret;
wm8904 = kzalloc(sizeof(struct wm8904_priv), GFP_KERNEL);
if (wm8904 == NULL)
return -ENOMEM;
- codec = &wm8904->codec;
- codec->hw_write = (hw_write_t)i2c_master_send;
-
wm8904->devtype = id->driver_data;
-
i2c_set_clientdata(i2c, wm8904);
- codec->control_data = i2c;
+ wm8904->control_data = i2c;
wm8904->pdata = i2c->dev.platform_data;
- codec->dev = &i2c->dev;
-
- return wm8904_register(wm8904, SND_SOC_I2C);
+ ret = snd_soc_register_codec(&i2c->dev,
+ &soc_codec_dev_wm8904, &wm8904_dai, 1);
+ if (ret < 0)
+ kfree(wm8904);
+ return ret;
}
static __devexit int wm8904_i2c_remove(struct i2c_client *client)
{
- struct wm8904_priv *wm8904 = i2c_get_clientdata(client);
- wm8904_unregister(wm8904);
+ snd_soc_unregister_codec(&client->dev);
+ kfree(i2c_get_clientdata(client));
return 0;
}
@@ -2641,7 +2553,7 @@ MODULE_DEVICE_TABLE(i2c, wm8904_i2c_id);
static struct i2c_driver wm8904_i2c_driver = {
.driver = {
- .name = "WM8904",
+ .name = "wm8904-codec",
.owner = THIS_MODULE,
},
.probe = wm8904_i2c_probe,
@@ -2652,15 +2564,15 @@ static struct i2c_driver wm8904_i2c_driver = {
static int __init wm8904_modinit(void)
{
- int ret;
+ int ret = 0;
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
ret = i2c_add_driver(&wm8904_i2c_driver);
if (ret != 0) {
- printk(KERN_ERR "Failed to register WM8904 I2C driver: %d\n",
+ printk(KERN_ERR "Failed to register wm8904 I2C driver: %d\n",
ret);
}
#endif
- return 0;
+ return ret;
}
module_init(wm8904_modinit);
diff --git a/sound/soc/codecs/wm8904.h b/sound/soc/codecs/wm8904.h
index abe5059b3004..9e8c84188ba7 100644
--- a/sound/soc/codecs/wm8904.h
+++ b/sound/soc/codecs/wm8904.h
@@ -21,9 +21,6 @@
#define WM8904_FLL_LRCLK 3
#define WM8904_FLL_FREE_RUNNING 4
-extern struct snd_soc_dai wm8904_dai;
-extern struct snd_soc_codec_device soc_codec_dev_wm8904;
-
/*
* Register values.
*/
diff --git a/sound/soc/codecs/wm8940.c b/sound/soc/codecs/wm8940.c
index f0c11138e610..d28bf0dfdb1d 100644
--- a/sound/soc/codecs/wm8940.c
+++ b/sound/soc/codecs/wm8940.c
@@ -44,7 +44,8 @@
struct wm8940_priv {
unsigned int sysclk;
u16 reg_cache[WM8940_CACHEREGNUM];
- struct snd_soc_codec codec;
+ enum snd_soc_control_type control_type;
+ void *control_data;
};
static u16 wm8940_reg_defaults[] = {
@@ -365,8 +366,7 @@ static int wm8940_i2s_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;
u16 iface = snd_soc_read(codec, WM8940_IFACE) & 0xFD9F;
u16 addcntrl = snd_soc_read(codec, WM8940_ADDCNTRL) & 0xFFF1;
u16 companding = snd_soc_read(codec,
@@ -636,8 +636,8 @@ static struct snd_soc_dai_ops wm8940_dai_ops = {
.set_pll = wm8940_set_dai_pll,
};
-struct snd_soc_dai wm8940_dai = {
- .name = "WM8940",
+static struct snd_soc_dai_driver wm8940_dai = {
+ .name = "wm8940-hifi",
.playback = {
.stream_name = "Playback",
.channels_min = 1,
@@ -655,20 +655,14 @@ struct snd_soc_dai wm8940_dai = {
.ops = &wm8940_dai_ops,
.symmetric_rates = 1,
};
-EXPORT_SYMBOL_GPL(wm8940_dai);
-static int wm8940_suspend(struct platform_device *pdev, pm_message_t state)
+static int wm8940_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;
-
return wm8940_set_bias_level(codec, SND_SOC_BIAS_OFF);
}
-static int wm8940_resume(struct platform_device *pdev)
+static int wm8940_resume(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec = socdev->card->codec;
int i;
int ret;
u8 data[3];
@@ -697,108 +691,26 @@ error_ret:
return ret;
}
-static struct snd_soc_codec *wm8940_codec;
-
-static int wm8940_probe(struct platform_device *pdev)
-{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec;
-
- int ret = 0;
-
- if (wm8940_codec == NULL) {
- dev_err(&pdev->dev, "Codec device not registered\n");
- return -ENODEV;
- }
-
- socdev->card->codec = wm8940_codec;
- codec = wm8940_codec;
-
- mutex_init(&codec->mutex);
- /* register pcms */
- ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
- if (ret < 0) {
- dev_err(codec->dev, "failed to create pcms: %d\n", ret);
- goto pcm_err;
- }
-
- ret = snd_soc_add_controls(codec, wm8940_snd_controls,
- ARRAY_SIZE(wm8940_snd_controls));
- if (ret)
- goto error_free_pcms;
- ret = wm8940_add_widgets(codec);
- if (ret)
- goto error_free_pcms;
-
- return ret;
-
-error_free_pcms:
- snd_soc_free_pcms(socdev);
- snd_soc_dapm_free(socdev);
-pcm_err:
- return ret;
-}
-
-static int wm8940_remove(struct platform_device *pdev)
-{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
-
- snd_soc_free_pcms(socdev);
- snd_soc_dapm_free(socdev);
-
- return 0;
-}
-
-struct snd_soc_codec_device soc_codec_dev_wm8940 = {
- .probe = wm8940_probe,
- .remove = wm8940_remove,
- .suspend = wm8940_suspend,
- .resume = wm8940_resume,
-};
-EXPORT_SYMBOL_GPL(soc_codec_dev_wm8940);
-
-static int wm8940_register(struct wm8940_priv *wm8940,
- enum snd_soc_control_type control)
+static int wm8940_probe(struct snd_soc_codec *codec)
{
- struct wm8940_setup_data *pdata = wm8940->codec.dev->platform_data;
- struct snd_soc_codec *codec = &wm8940->codec;
+ struct wm8940_priv *wm8940 = snd_soc_codec_get_drvdata(codec);
+ struct wm8940_setup_data *pdata = codec->dev->platform_data;
int ret;
u16 reg;
- if (wm8940_codec) {
- dev_err(codec->dev, "Another WM8940 is registered\n");
- return -EINVAL;
- }
-
- INIT_LIST_HEAD(&codec->dapm_widgets);
- INIT_LIST_HEAD(&codec->dapm_paths);
-
- snd_soc_codec_set_drvdata(codec, wm8940);
- codec->name = "WM8940";
- codec->owner = THIS_MODULE;
- codec->bias_level = SND_SOC_BIAS_OFF;
- codec->set_bias_level = wm8940_set_bias_level;
- codec->dai = &wm8940_dai;
- codec->num_dai = 1;
- codec->reg_cache_size = ARRAY_SIZE(wm8940_reg_defaults);
- codec->reg_cache = &wm8940->reg_cache;
- ret = snd_soc_codec_set_cache_io(codec, 8, 16, control);
+ codec->control_data = wm8940->control_data;
+ ret = snd_soc_codec_set_cache_io(codec, 8, 16, wm8940->control_type);
if (ret < 0) {
dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
return ret;
}
- memcpy(codec->reg_cache, wm8940_reg_defaults,
- sizeof(wm8940_reg_defaults));
-
ret = wm8940_reset(codec);
if (ret < 0) {
dev_err(codec->dev, "Failed to issue reset\n");
return ret;
}
- wm8940_dai.dev = codec->dev;
-
wm8940_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
ret = snd_soc_write(codec, WM8940_POWER1, 0x180);
@@ -814,64 +726,60 @@ static int wm8940_register(struct wm8940_priv *wm8940,
return ret;
}
-
- wm8940_codec = codec;
-
- ret = snd_soc_register_codec(codec);
- if (ret) {
- dev_err(codec->dev, "Failed to register codec: %d\n", ret);
+ ret = snd_soc_add_controls(codec, wm8940_snd_controls,
+ ARRAY_SIZE(wm8940_snd_controls));
+ if (ret)
return ret;
- }
-
- ret = snd_soc_register_dai(&wm8940_dai);
- if (ret) {
- dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
- snd_soc_unregister_codec(codec);
+ ret = wm8940_add_widgets(codec);
+ if (ret)
return ret;
- }
- return 0;
+ return ret;
+;
}
-static void wm8940_unregister(struct wm8940_priv *wm8940)
+static int wm8940_remove(struct snd_soc_codec *codec)
{
- wm8940_set_bias_level(&wm8940->codec, SND_SOC_BIAS_OFF);
- snd_soc_unregister_dai(&wm8940_dai);
- snd_soc_unregister_codec(&wm8940->codec);
- kfree(wm8940);
- wm8940_codec = NULL;
+ wm8940_set_bias_level(codec, SND_SOC_BIAS_OFF);
+ return 0;
}
-static int wm8940_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
+static struct snd_soc_codec_driver soc_codec_dev_wm8940 = {
+ .probe = wm8940_probe,
+ .remove = wm8940_remove,
+ .suspend = wm8940_suspend,
+ .resume = wm8940_resume,
+ .set_bias_level = wm8940_set_bias_level,
+ .reg_cache_size = sizeof(wm8940_reg_defaults),
+ .reg_word_size = sizeof(u16),
+ .reg_cache_default = wm8940_reg_defaults,
+};
+
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+static __devinit int wm8940_i2c_probe(struct i2c_client *i2c,
+ const struct i2c_device_id *id)
{
- int ret;
struct wm8940_priv *wm8940;
- struct snd_soc_codec *codec;
+ int ret;
- wm8940 = kzalloc(sizeof *wm8940, GFP_KERNEL);
+ wm8940 = kzalloc(sizeof(struct wm8940_priv), GFP_KERNEL);
if (wm8940 == NULL)
return -ENOMEM;
- codec = &wm8940->codec;
- codec->hw_write = (hw_write_t)i2c_master_send;
i2c_set_clientdata(i2c, wm8940);
- codec->control_data = i2c;
- codec->dev = &i2c->dev;
+ wm8940->control_data = i2c;
- ret = wm8940_register(wm8940, SND_SOC_I2C);
+ ret = snd_soc_register_codec(&i2c->dev,
+ &soc_codec_dev_wm8940, &wm8940_dai, 1);
if (ret < 0)
kfree(wm8940);
-
return ret;
}
-static int __devexit wm8940_i2c_remove(struct i2c_client *client)
+static __devexit int wm8940_i2c_remove(struct i2c_client *client)
{
- struct wm8940_priv *wm8940 = i2c_get_clientdata(client);
-
- wm8940_unregister(wm8940);
-
+ snd_soc_unregister_codec(&client->dev);
+ kfree(i2c_get_clientdata(client));
return 0;
}
@@ -883,29 +791,34 @@ MODULE_DEVICE_TABLE(i2c, wm8940_i2c_id);
static struct i2c_driver wm8940_i2c_driver = {
.driver = {
- .name = "WM8940 I2C Codec",
+ .name = "wm8940-codec",
.owner = THIS_MODULE,
},
- .probe = wm8940_i2c_probe,
- .remove = __devexit_p(wm8940_i2c_remove),
+ .probe = wm8940_i2c_probe,
+ .remove = __devexit_p(wm8940_i2c_remove),
.id_table = wm8940_i2c_id,
};
+#endif
static int __init wm8940_modinit(void)
{
- int ret;
-
+ int ret = 0;
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
ret = i2c_add_driver(&wm8940_i2c_driver);
- if (ret)
- printk(KERN_ERR "Failed to register WM8940 I2C driver: %d\n",
+ if (ret != 0) {
+ printk(KERN_ERR "Failed to register wm8940 I2C driver: %d\n",
ret);
+ }
+#endif
return ret;
}
module_init(wm8940_modinit);
static void __exit wm8940_exit(void)
{
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
i2c_del_driver(&wm8940_i2c_driver);
+#endif
}
module_exit(wm8940_exit);
diff --git a/sound/soc/codecs/wm8940.h b/sound/soc/codecs/wm8940.h
index 8410eed3ef84..907fe192e9e0 100644
--- a/sound/soc/codecs/wm8940.h
+++ b/sound/soc/codecs/wm8940.h
@@ -15,8 +15,6 @@ struct wm8940_setup_data {
#define WM8940_VROI_30K 1
unsigned int vroi:1;
};
-extern struct snd_soc_dai wm8940_dai;
-extern struct snd_soc_codec_device soc_codec_dev_wm8940;
/* WM8940 register space */
#define WM8940_SOFTRESET 0x00
diff --git a/sound/soc/codecs/wm8955.c b/sound/soc/codecs/wm8955.c
index 5f025593d84d..a5a9f8ef5771 100644
--- a/sound/soc/codecs/wm8955.c
+++ b/sound/soc/codecs/wm8955.c
@@ -30,9 +30,6 @@
#include "wm8955.h"
-static struct snd_soc_codec *wm8955_codec;
-struct snd_soc_codec_device soc_codec_dev_wm8955;
-
#define WM8955_NUM_SUPPLIES 4
static const char *wm8955_supply_names[WM8955_NUM_SUPPLIES] = {
"DCVDD",
@@ -43,7 +40,9 @@ static const char *wm8955_supply_names[WM8955_NUM_SUPPLIES] = {
/* codec private data */
struct wm8955_priv {
- struct snd_soc_codec codec;
+ enum snd_soc_control_type control_type;
+ void *control_data;
+
u16 reg_cache[WM8955_MAX_REGISTER + 1];
unsigned int mclk_rate;
@@ -52,8 +51,6 @@ struct wm8955_priv {
int fs;
struct regulator_bulk_data supplies[WM8955_NUM_SUPPLIES];
-
- struct wm8955_pdata *pdata;
};
static const u16 wm8955_reg[WM8955_MAX_REGISTER + 1] = {
@@ -870,8 +867,8 @@ static struct snd_soc_dai_ops wm8955_dai_ops = {
.digital_mute = wm8955_digital_mute,
};
-struct snd_soc_dai wm8955_dai = {
- .name = "WM8955",
+static struct snd_soc_dai_driver wm8955_dai = {
+ .name = "wm8955-hifi",
.playback = {
.stream_name = "Playback",
.channels_min = 2,
@@ -881,24 +878,17 @@ struct snd_soc_dai wm8955_dai = {
},
.ops = &wm8955_dai_ops,
};
-EXPORT_SYMBOL_GPL(wm8955_dai);
#ifdef CONFIG_PM
-static int wm8955_suspend(struct platform_device *pdev, pm_message_t state)
+static int wm8955_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;
-
wm8955_set_bias_level(codec, SND_SOC_BIAS_OFF);
return 0;
}
-static int wm8955_resume(struct platform_device *pdev)
+static int wm8955_resume(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec = socdev->card->codec;
-
wm8955_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
return 0;
@@ -908,86 +898,17 @@ static int wm8955_resume(struct platform_device *pdev)
#define wm8955_resume NULL
#endif
-static int wm8955_probe(struct platform_device *pdev)
-{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec;
- int ret = 0;
-
- if (wm8955_codec == NULL) {
- dev_err(&pdev->dev, "Codec device not registered\n");
- return -ENODEV;
- }
-
- socdev->card->codec = wm8955_codec;
- codec = wm8955_codec;
-
- /* register pcms */
- ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
- if (ret < 0) {
- dev_err(codec->dev, "failed to create pcms: %d\n", ret);
- goto pcm_err;
- }
-
- wm8955_add_widgets(codec);
-
- return ret;
-
-pcm_err:
- return ret;
-}
-
-static int wm8955_remove(struct platform_device *pdev)
+static int wm8955_probe(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
-
- snd_soc_free_pcms(socdev);
- snd_soc_dapm_free(socdev);
-
- return 0;
-}
-
-struct snd_soc_codec_device soc_codec_dev_wm8955 = {
- .probe = wm8955_probe,
- .remove = wm8955_remove,
- .suspend = wm8955_suspend,
- .resume = wm8955_resume,
-};
-EXPORT_SYMBOL_GPL(soc_codec_dev_wm8955);
-
-static int wm8955_register(struct wm8955_priv *wm8955,
- enum snd_soc_control_type control)
-{
- int ret;
- struct snd_soc_codec *codec = &wm8955->codec;
- int i;
-
- if (wm8955_codec) {
- dev_err(codec->dev, "Another WM8955 is registered\n");
- ret = -EINVAL;
- goto err;
- }
-
- mutex_init(&codec->mutex);
- INIT_LIST_HEAD(&codec->dapm_widgets);
- INIT_LIST_HEAD(&codec->dapm_paths);
-
- snd_soc_codec_set_drvdata(codec, wm8955);
- codec->name = "WM8955";
- codec->owner = THIS_MODULE;
- codec->bias_level = SND_SOC_BIAS_OFF;
- codec->set_bias_level = wm8955_set_bias_level;
- codec->dai = &wm8955_dai;
- codec->num_dai = 1;
- codec->reg_cache_size = WM8955_MAX_REGISTER;
- codec->reg_cache = &wm8955->reg_cache;
-
- memcpy(codec->reg_cache, wm8955_reg, sizeof(wm8955_reg));
+ struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec);
+ struct wm8955_pdata *pdata = dev_get_platdata(codec->dev);
+ int ret, i;
- ret = snd_soc_codec_set_cache_io(codec, 7, 9, control);
+ codec->control_data = wm8955->control_data;
+ ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8955->control_type);
if (ret != 0) {
dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- goto err;
+ return ret;
}
for (i = 0; i < ARRAY_SIZE(wm8955->supplies); i++)
@@ -997,7 +918,7 @@ static int wm8955_register(struct wm8955_priv *wm8955,
wm8955->supplies);
if (ret != 0) {
dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
- goto err;
+ return ret;
}
ret = regulator_bulk_enable(ARRAY_SIZE(wm8955->supplies),
@@ -1013,8 +934,6 @@ static int wm8955_register(struct wm8955_priv *wm8955,
goto err_enable;
}
- wm8955_dai.dev = codec->dev;
-
/* Change some default settings - latch VU and enable ZC */
wm8955->reg_cache[WM8955_LEFT_DAC_VOLUME] |= WM8955_LDVU;
wm8955->reg_cache[WM8955_RIGHT_DAC_VOLUME] |= WM8955_RDVU;
@@ -1028,12 +947,12 @@ static int wm8955_register(struct wm8955_priv *wm8955,
wm8955->reg_cache[WM8955_BASS_CONTROL] |= WM8955_BB;
/* Set platform data values */
- if (wm8955->pdata) {
- if (wm8955->pdata->out2_speaker)
+ if (pdata) {
+ if (pdata->out2_speaker)
wm8955->reg_cache[WM8955_ADDITIONAL_CONTROL_2]
|= WM8955_ROUT2INV;
- if (wm8955->pdata->monoin_diff)
+ if (pdata->monoin_diff)
wm8955->reg_cache[WM8955_MONO_OUT_MIX_1]
|= WM8955_DMEN;
}
@@ -1043,70 +962,61 @@ static int wm8955_register(struct wm8955_priv *wm8955,
/* Bias level configuration will have done an extra enable */
regulator_bulk_disable(ARRAY_SIZE(wm8955->supplies), wm8955->supplies);
- wm8955_codec = codec;
-
- ret = snd_soc_register_codec(codec);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to register codec: %d\n", ret);
- goto err_enable;
- }
-
- ret = snd_soc_register_dai(&wm8955_dai);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
- goto err_codec;
- }
-
+ wm8955_add_widgets(codec);
return 0;
-err_codec:
- snd_soc_unregister_codec(codec);
err_enable:
regulator_bulk_disable(ARRAY_SIZE(wm8955->supplies), wm8955->supplies);
err_get:
regulator_bulk_free(ARRAY_SIZE(wm8955->supplies), wm8955->supplies);
-err:
- kfree(wm8955);
return ret;
}
-static void wm8955_unregister(struct wm8955_priv *wm8955)
+static int wm8955_remove(struct snd_soc_codec *codec)
{
- wm8955_set_bias_level(&wm8955->codec, SND_SOC_BIAS_OFF);
+ struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec);
+
+ wm8955_set_bias_level(codec, SND_SOC_BIAS_OFF);
regulator_bulk_free(ARRAY_SIZE(wm8955->supplies), wm8955->supplies);
- snd_soc_unregister_dai(&wm8955_dai);
- snd_soc_unregister_codec(&wm8955->codec);
- kfree(wm8955);
- wm8955_codec = NULL;
+ return 0;
}
+static struct snd_soc_codec_driver soc_codec_dev_wm8955 = {
+ .probe = wm8955_probe,
+ .remove = wm8955_remove,
+ .suspend = wm8955_suspend,
+ .resume = wm8955_resume,
+ .set_bias_level = wm8955_set_bias_level,
+ .reg_cache_size = ARRAY_SIZE(wm8955_reg),
+ .reg_word_size = sizeof(u16),
+ .reg_cache_default = wm8955_reg,
+};
+
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
static __devinit int wm8955_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
struct wm8955_priv *wm8955;
- struct snd_soc_codec *codec;
+ int ret;
wm8955 = kzalloc(sizeof(struct wm8955_priv), GFP_KERNEL);
if (wm8955 == NULL)
return -ENOMEM;
- codec = &wm8955->codec;
- codec->hw_write = (hw_write_t)i2c_master_send;
-
i2c_set_clientdata(i2c, wm8955);
- codec->control_data = i2c;
- wm8955->pdata = i2c->dev.platform_data;
-
- codec->dev = &i2c->dev;
+ wm8955->control_data = i2c;
- return wm8955_register(wm8955, SND_SOC_I2C);
+ ret = snd_soc_register_codec(&i2c->dev,
+ &soc_codec_dev_wm8955, &wm8955_dai, 1);
+ if (ret < 0)
+ kfree(wm8955);
+ return ret;
}
static __devexit int wm8955_i2c_remove(struct i2c_client *client)
{
- struct wm8955_priv *wm8955 = i2c_get_clientdata(client);
- wm8955_unregister(wm8955);
+ snd_soc_unregister_codec(&client->dev);
+ kfree(i2c_get_clientdata(client));
return 0;
}
@@ -1118,7 +1028,7 @@ MODULE_DEVICE_TABLE(i2c, wm8955_i2c_id);
static struct i2c_driver wm8955_i2c_driver = {
.driver = {
- .name = "wm8955",
+ .name = "wm8955-codec",
.owner = THIS_MODULE,
},
.probe = wm8955_i2c_probe,
@@ -1129,7 +1039,7 @@ static struct i2c_driver wm8955_i2c_driver = {
static int __init wm8955_modinit(void)
{
- int ret;
+ int ret = 0;
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
ret = i2c_add_driver(&wm8955_i2c_driver);
if (ret != 0) {
@@ -1137,7 +1047,7 @@ static int __init wm8955_modinit(void)
ret);
}
#endif
- return 0;
+ return ret;
}
module_init(wm8955_modinit);
diff --git a/sound/soc/codecs/wm8955.h b/sound/soc/codecs/wm8955.h
index ae349c8531f6..d13fd5c5fa63 100644
--- a/sound/soc/codecs/wm8955.h
+++ b/sound/soc/codecs/wm8955.h
@@ -15,9 +15,6 @@
#define WM8955_CLK_MCLK 1
-extern struct snd_soc_dai wm8955_dai;
-extern struct snd_soc_codec_device soc_codec_dev_wm8955;
-
/*
* Register values.
*/
diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c
index 3c6ee61f6c95..8d5efb333c33 100644
--- a/sound/soc/codecs/wm8960.c
+++ b/sound/soc/codecs/wm8960.c
@@ -29,8 +29,6 @@
#define AUDIO_NAME "wm8960"
-struct snd_soc_codec_device soc_codec_dev_wm8960;
-
/* R25 - Power 1 */
#define WM8960_VMID_MASK 0x180
#define WM8960_VREF 0x40
@@ -75,7 +73,10 @@ static const u16 wm8960_reg[WM8960_CACHEREGNUM] = {
struct wm8960_priv {
u16 reg_cache[WM8960_CACHEREGNUM];
- struct snd_soc_codec codec;
+ enum snd_soc_control_type control_type;
+ void *control_data;
+ int (*set_bias_level)(struct snd_soc_codec *,
+ enum snd_soc_bias_level level);
struct snd_soc_dapm_widget *lout1;
struct snd_soc_dapm_widget *rout1;
struct snd_soc_dapm_widget *out3;
@@ -507,8 +508,7 @@ static int wm8960_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 wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
u16 iface = snd_soc_read(codec, WM8960_IFACE1) & 0xfff3;
int i;
@@ -849,6 +849,14 @@ static int wm8960_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
return 0;
}
+static int wm8960_set_bias_level(struct snd_soc_codec *codec,
+ enum snd_soc_bias_level level)
+{
+ struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
+
+ return wm8960->set_bias_level(codec, level);
+}
+
#define WM8960_RATES SNDRV_PCM_RATE_8000_48000
#define WM8960_FORMATS \
@@ -863,8 +871,8 @@ static struct snd_soc_dai_ops wm8960_dai_ops = {
.set_pll = wm8960_set_dai_pll,
};
-struct snd_soc_dai wm8960_dai = {
- .name = "WM8960",
+static struct snd_soc_dai_driver wm8960_dai = {
+ .name = "wm8960-hifi",
.playback = {
.stream_name = "Playback",
.channels_min = 1,
@@ -880,21 +888,18 @@ struct snd_soc_dai wm8960_dai = {
.ops = &wm8960_dai_ops,
.symmetric_rates = 1,
};
-EXPORT_SYMBOL_GPL(wm8960_dai);
-static int wm8960_suspend(struct platform_device *pdev, pm_message_t state)
+static int wm8960_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;
+ struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
- codec->set_bias_level(codec, SND_SOC_BIAS_OFF);
+ wm8960->set_bias_level(codec, SND_SOC_BIAS_OFF);
return 0;
}
-static int wm8960_resume(struct platform_device *pdev)
+static int wm8960_resume(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec = socdev->card->codec;
+ struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
int i;
u8 data[2];
u16 *cache = codec->reg_cache;
@@ -906,78 +911,19 @@ static int wm8960_resume(struct platform_device *pdev)
codec->hw_write(codec->control_data, data, 2);
}
- codec->set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
+ wm8960->set_bias_level(codec, SND_SOC_BIAS_STANDBY);
return 0;
}
-static struct snd_soc_codec *wm8960_codec;
-
-static int wm8960_probe(struct platform_device *pdev)
-{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec;
- int ret = 0;
-
- if (wm8960_codec == NULL) {
- dev_err(&pdev->dev, "Codec device not registered\n");
- return -ENODEV;
- }
-
- socdev->card->codec = wm8960_codec;
- codec = wm8960_codec;
-
- /* register pcms */
- ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
- if (ret < 0) {
- dev_err(codec->dev, "failed to create pcms: %d\n", ret);
- goto pcm_err;
- }
-
- snd_soc_add_controls(codec, wm8960_snd_controls,
- ARRAY_SIZE(wm8960_snd_controls));
- wm8960_add_widgets(codec);
-
- return ret;
-
-pcm_err:
- return ret;
-}
-
-/* power down chip */
-static int wm8960_remove(struct platform_device *pdev)
-{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
-
- snd_soc_free_pcms(socdev);
- snd_soc_dapm_free(socdev);
-
- return 0;
-}
-
-struct snd_soc_codec_device soc_codec_dev_wm8960 = {
- .probe = wm8960_probe,
- .remove = wm8960_remove,
- .suspend = wm8960_suspend,
- .resume = wm8960_resume,
-};
-EXPORT_SYMBOL_GPL(soc_codec_dev_wm8960);
-
-static int wm8960_register(struct wm8960_priv *wm8960,
- enum snd_soc_control_type control)
+static int wm8960_probe(struct snd_soc_codec *codec)
{
- struct wm8960_data *pdata = wm8960->codec.dev->platform_data;
- struct snd_soc_codec *codec = &wm8960->codec;
+ struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
+ struct wm8960_data *pdata = dev_get_platdata(codec->dev);
int ret;
u16 reg;
- if (wm8960_codec) {
- dev_err(codec->dev, "Another WM8960 is registered\n");
- ret = -EINVAL;
- goto err;
- }
-
- codec->set_bias_level = wm8960_set_bias_level_out3;
+ wm8960->set_bias_level = wm8960_set_bias_level_out3;
+ codec->control_data = wm8960->control_data;
if (!pdata) {
dev_warn(codec->dev, "No platform data supplied\n");
@@ -988,39 +934,22 @@ static int wm8960_register(struct wm8960_priv *wm8960,
}
if (pdata->capless)
- codec->set_bias_level = wm8960_set_bias_level_capless;
+ wm8960->set_bias_level = wm8960_set_bias_level_capless;
}
- mutex_init(&codec->mutex);
- INIT_LIST_HEAD(&codec->dapm_widgets);
- INIT_LIST_HEAD(&codec->dapm_paths);
-
- snd_soc_codec_set_drvdata(codec, wm8960);
- codec->name = "WM8960";
- codec->owner = THIS_MODULE;
- codec->bias_level = SND_SOC_BIAS_OFF;
- codec->dai = &wm8960_dai;
- codec->num_dai = 1;
- codec->reg_cache_size = WM8960_CACHEREGNUM;
- codec->reg_cache = &wm8960->reg_cache;
-
- memcpy(codec->reg_cache, wm8960_reg, sizeof(wm8960_reg));
-
- ret = snd_soc_codec_set_cache_io(codec, 7, 9, control);
+ ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8960->control_type);
if (ret < 0) {
dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- goto err;
+ return ret;
}
ret = wm8960_reset(codec);
if (ret < 0) {
dev_err(codec->dev, "Failed to issue reset\n");
- goto err;
+ return ret;
}
- wm8960_dai.dev = codec->dev;
-
- codec->set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+ wm8960->set_bias_level(codec, SND_SOC_BIAS_STANDBY);
/* Latch the update bits */
reg = snd_soc_read(codec, WM8960_LINVOL);
@@ -1044,62 +973,58 @@ static int wm8960_register(struct wm8960_priv *wm8960,
reg = snd_soc_read(codec, WM8960_ROUT2);
snd_soc_write(codec, WM8960_ROUT2, reg | 0x100);
- wm8960_codec = codec;
-
- ret = snd_soc_register_codec(codec);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to register codec: %d\n", ret);
- goto err;
- }
-
- ret = snd_soc_register_dai(&wm8960_dai);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
- goto err_codec;
- }
+ snd_soc_add_controls(codec, wm8960_snd_controls,
+ ARRAY_SIZE(wm8960_snd_controls));
+ wm8960_add_widgets(codec);
return 0;
-
-err_codec:
- snd_soc_unregister_codec(codec);
-err:
- kfree(wm8960);
- return ret;
}
-static void wm8960_unregister(struct wm8960_priv *wm8960)
+/* power down chip */
+static int wm8960_remove(struct snd_soc_codec *codec)
{
- wm8960->codec.set_bias_level(&wm8960->codec, SND_SOC_BIAS_OFF);
- snd_soc_unregister_dai(&wm8960_dai);
- snd_soc_unregister_codec(&wm8960->codec);
- kfree(wm8960);
- wm8960_codec = NULL;
+ struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
+
+ wm8960->set_bias_level(codec, SND_SOC_BIAS_OFF);
+ return 0;
}
+static struct snd_soc_codec_driver soc_codec_dev_wm8960 = {
+ .probe = wm8960_probe,
+ .remove = wm8960_remove,
+ .suspend = wm8960_suspend,
+ .resume = wm8960_resume,
+ .set_bias_level = wm8960_set_bias_level,
+ .reg_cache_size = ARRAY_SIZE(wm8960_reg),
+ .reg_word_size = sizeof(u16),
+ .reg_cache_default = wm8960_reg,
+};
+
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
static __devinit int wm8960_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
struct wm8960_priv *wm8960;
- struct snd_soc_codec *codec;
+ int ret;
wm8960 = kzalloc(sizeof(struct wm8960_priv), GFP_KERNEL);
if (wm8960 == NULL)
return -ENOMEM;
- codec = &wm8960->codec;
-
i2c_set_clientdata(i2c, wm8960);
- codec->control_data = i2c;
-
- codec->dev = &i2c->dev;
+ wm8960->control_data = i2c;
- return wm8960_register(wm8960, SND_SOC_I2C);
+ ret = snd_soc_register_codec(&i2c->dev,
+ &soc_codec_dev_wm8960, &wm8960_dai, 1);
+ if (ret < 0)
+ kfree(wm8960);
+ return ret;
}
static __devexit int wm8960_i2c_remove(struct i2c_client *client)
{
- struct wm8960_priv *wm8960 = i2c_get_clientdata(client);
- wm8960_unregister(wm8960);
+ snd_soc_unregister_codec(&client->dev);
+ kfree(i2c_get_clientdata(client));
return 0;
}
@@ -1111,35 +1036,37 @@ MODULE_DEVICE_TABLE(i2c, wm8960_i2c_id);
static struct i2c_driver wm8960_i2c_driver = {
.driver = {
- .name = "wm8960",
+ .name = "wm8960-codec",
.owner = THIS_MODULE,
},
.probe = wm8960_i2c_probe,
.remove = __devexit_p(wm8960_i2c_remove),
.id_table = wm8960_i2c_id,
};
+#endif
static int __init wm8960_modinit(void)
{
- int ret;
-
+ int ret = 0;
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
ret = i2c_add_driver(&wm8960_i2c_driver);
if (ret != 0) {
printk(KERN_ERR "Failed to register WM8960 I2C driver: %d\n",
ret);
}
-
+#endif
return ret;
}
module_init(wm8960_modinit);
static void __exit wm8960_exit(void)
{
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
i2c_del_driver(&wm8960_i2c_driver);
+#endif
}
module_exit(wm8960_exit);
-
MODULE_DESCRIPTION("ASoC WM8960 driver");
MODULE_AUTHOR("Liam Girdwood");
MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8960.h b/sound/soc/codecs/wm8960.h
index a5ef65481b86..2d8163d7004b 100644
--- a/sound/soc/codecs/wm8960.h
+++ b/sound/soc/codecs/wm8960.h
@@ -110,7 +110,4 @@
#define WM8960_OPCLK_DIV_5_5 (4 << 0)
#define WM8960_OPCLK_DIV_6 (5 << 0)
-extern struct snd_soc_dai wm8960_dai;
-extern struct snd_soc_codec_device soc_codec_dev_wm8960;
-
#endif
diff --git a/sound/soc/codecs/wm8961.c b/sound/soc/codecs/wm8961.c
index 2549d3a297ab..5ebe2c04e5cf 100644
--- a/sound/soc/codecs/wm8961.c
+++ b/sound/soc/codecs/wm8961.c
@@ -288,7 +288,8 @@ static u16 wm8961_reg_defaults[] = {
};
struct wm8961_priv {
- struct snd_soc_codec codec;
+ enum snd_soc_control_type control_type;
+ void *control_data;
int sysclk;
u16 reg_cache[WM8961_MAX_REGISTER];
};
@@ -940,8 +941,8 @@ static struct snd_soc_dai_ops wm8961_dai_ops = {
.set_clkdiv = wm8961_set_clkdiv,
};
-struct snd_soc_dai wm8961_dai = {
- .name = "WM8961",
+static struct snd_soc_dai_driver wm8961_dai = {
+ .name = "wm8961-hifi",
.playback = {
.stream_name = "HiFi Playback",
.channels_min = 1,
@@ -956,140 +957,24 @@ struct snd_soc_dai wm8961_dai = {
.formats = WM8961_FORMATS,},
.ops = &wm8961_dai_ops,
};
-EXPORT_SYMBOL_GPL(wm8961_dai);
-
-static struct snd_soc_codec *wm8961_codec;
-
-static int wm8961_probe(struct platform_device *pdev)
+static int wm8961_probe(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec;
+ struct wm8961_priv *wm8961 = snd_soc_codec_get_drvdata(codec);
int ret = 0;
-
- if (wm8961_codec == NULL) {
- dev_err(&pdev->dev, "Codec device not registered\n");
- return -ENODEV;
- }
-
- socdev->card->codec = wm8961_codec;
- codec = wm8961_codec;
-
- /* register pcms */
- ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
- if (ret < 0) {
- dev_err(codec->dev, "failed to create pcms: %d\n", ret);
- goto pcm_err;
- }
-
- snd_soc_add_controls(codec, wm8961_snd_controls,
- ARRAY_SIZE(wm8961_snd_controls));
- snd_soc_dapm_new_controls(codec, wm8961_dapm_widgets,
- ARRAY_SIZE(wm8961_dapm_widgets));
- snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths));
-
- return ret;
-
-pcm_err:
- return ret;
-}
-
-static int wm8961_remove(struct platform_device *pdev)
-{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
-
- snd_soc_free_pcms(socdev);
- snd_soc_dapm_free(socdev);
-
- return 0;
-}
-
-#ifdef CONFIG_PM
-static int wm8961_suspend(struct platform_device *pdev, pm_message_t state)
-{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec = socdev->card->codec;
-
- wm8961_set_bias_level(codec, SND_SOC_BIAS_OFF);
-
- return 0;
-}
-
-static int wm8961_resume(struct platform_device *pdev)
-{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec = socdev->card->codec;
- u16 *reg_cache = codec->reg_cache;
- int i;
-
- for (i = 0; i < codec->reg_cache_size; i++) {
- if (reg_cache[i] == wm8961_reg_defaults[i])
- continue;
-
- if (i == WM8961_SOFTWARE_RESET)
- continue;
-
- snd_soc_write(codec, i, reg_cache[i]);
- }
-
- wm8961_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
- return 0;
-}
-#else
-#define wm8961_suspend NULL
-#define wm8961_resume NULL
-#endif
-
-struct snd_soc_codec_device soc_codec_dev_wm8961 = {
- .probe = wm8961_probe,
- .remove = wm8961_remove,
- .suspend = wm8961_suspend,
- .resume = wm8961_resume,
-};
-EXPORT_SYMBOL_GPL(soc_codec_dev_wm8961);
-
-static int wm8961_register(struct wm8961_priv *wm8961)
-{
- struct snd_soc_codec *codec = &wm8961->codec;
- int ret;
u16 reg;
- if (wm8961_codec) {
- dev_err(codec->dev, "Another WM8961 is registered\n");
- ret = -EINVAL;
- goto err;
- }
-
- mutex_init(&codec->mutex);
- INIT_LIST_HEAD(&codec->dapm_widgets);
- INIT_LIST_HEAD(&codec->dapm_paths);
-
- snd_soc_codec_set_drvdata(codec, wm8961);
- codec->name = "WM8961";
- codec->owner = THIS_MODULE;
- codec->dai = &wm8961_dai;
- codec->num_dai = 1;
- codec->reg_cache_size = ARRAY_SIZE(wm8961->reg_cache);
- codec->reg_cache = &wm8961->reg_cache;
- codec->bias_level = SND_SOC_BIAS_OFF;
- codec->set_bias_level = wm8961_set_bias_level;
- codec->volatile_register = wm8961_volatile_register;
-
- memcpy(codec->reg_cache, wm8961_reg_defaults,
- sizeof(wm8961_reg_defaults));
-
+ codec->control_data = wm8961->control_data;
ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
if (ret != 0) {
dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- goto err;
+ return ret;
}
reg = snd_soc_read(codec, WM8961_SOFTWARE_RESET);
if (reg != 0x1801) {
dev_err(codec->dev, "Device is not a WM8961: ID=0x%x\n", reg);
- ret = -EINVAL;
- goto err;
+ return -EINVAL;
}
/* This isn't volatile - readback doesn't correspond to write */
@@ -1102,7 +987,7 @@ static int wm8961_register(struct wm8961_priv *wm8961)
ret = wm8961_reset(codec);
if (ret < 0) {
dev_err(codec->dev, "Failed to issue reset\n");
- goto err;
+ return ret;
}
/* Enable class W */
@@ -1140,64 +1025,90 @@ static int wm8961_register(struct wm8961_priv *wm8961)
wm8961_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
- wm8961_dai.dev = codec->dev;
+ snd_soc_add_controls(codec, wm8961_snd_controls,
+ ARRAY_SIZE(wm8961_snd_controls));
+ snd_soc_dapm_new_controls(codec, wm8961_dapm_widgets,
+ ARRAY_SIZE(wm8961_dapm_widgets));
+ snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths));
- wm8961_codec = codec;
+ return 0;
+}
- ret = snd_soc_register_codec(codec);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to register codec: %d\n", ret);
- goto err;
- }
+static int wm8961_remove(struct snd_soc_codec *codec)
+{
+ wm8961_set_bias_level(codec, SND_SOC_BIAS_OFF);
+ return 0;
+}
- ret = snd_soc_register_dai(&wm8961_dai);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
- goto err_codec;
- }
+#ifdef CONFIG_PM
+static int wm8961_suspend(struct snd_soc_codec *codec, pm_message_t state)
+{
+ wm8961_set_bias_level(codec, SND_SOC_BIAS_OFF);
return 0;
-
-err_codec:
- snd_soc_unregister_codec(codec);
-err:
- kfree(wm8961);
- return ret;
}
-static void wm8961_unregister(struct wm8961_priv *wm8961)
+static int wm8961_resume(struct snd_soc_codec *codec)
{
- wm8961_set_bias_level(&wm8961->codec, SND_SOC_BIAS_OFF);
- snd_soc_unregister_dai(&wm8961_dai);
- snd_soc_unregister_codec(&wm8961->codec);
- kfree(wm8961);
- wm8961_codec = NULL;
+ u16 *reg_cache = codec->reg_cache;
+ int i;
+
+ for (i = 0; i < codec->driver->reg_cache_size; i++) {
+ if (reg_cache[i] == wm8961_reg_defaults[i])
+ continue;
+
+ if (i == WM8961_SOFTWARE_RESET)
+ continue;
+
+ snd_soc_write(codec, i, reg_cache[i]);
+ }
+
+ wm8961_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+
+ return 0;
}
+#else
+#define wm8961_suspend NULL
+#define wm8961_resume NULL
+#endif
+static struct snd_soc_codec_driver soc_codec_dev_wm8961 = {
+ .probe = wm8961_probe,
+ .remove = wm8961_remove,
+ .suspend = wm8961_suspend,
+ .resume = wm8961_resume,
+ .set_bias_level = wm8961_set_bias_level,
+ .reg_cache_size = sizeof(wm8961_reg_defaults),
+ .reg_word_size = sizeof(u16),
+ .reg_cache_default = wm8961_reg_defaults,
+ .volatile_register = wm8961_volatile_register,
+};
+
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
static __devinit int wm8961_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
struct wm8961_priv *wm8961;
- struct snd_soc_codec *codec;
+ int ret;
wm8961 = kzalloc(sizeof(struct wm8961_priv), GFP_KERNEL);
if (wm8961 == NULL)
return -ENOMEM;
- codec = &wm8961->codec;
-
i2c_set_clientdata(i2c, wm8961);
- codec->control_data = i2c;
-
- codec->dev = &i2c->dev;
+ wm8961->control_data = i2c;
- return wm8961_register(wm8961);
+ ret = snd_soc_register_codec(&i2c->dev,
+ &soc_codec_dev_wm8961, &wm8961_dai, 1);
+ if (ret < 0)
+ kfree(wm8961);
+ return ret;
}
static __devexit int wm8961_i2c_remove(struct i2c_client *client)
{
- struct wm8961_priv *wm8961 = i2c_get_clientdata(client);
- wm8961_unregister(wm8961);
+ snd_soc_unregister_codec(&client->dev);
+ kfree(i2c_get_clientdata(client));
return 0;
}
@@ -1209,35 +1120,37 @@ MODULE_DEVICE_TABLE(i2c, wm8961_i2c_id);
static struct i2c_driver wm8961_i2c_driver = {
.driver = {
- .name = "wm8961",
+ .name = "wm8961-codec",
.owner = THIS_MODULE,
},
.probe = wm8961_i2c_probe,
.remove = __devexit_p(wm8961_i2c_remove),
.id_table = wm8961_i2c_id,
};
+#endif
static int __init wm8961_modinit(void)
{
- int ret;
-
+ int ret = 0;
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
ret = i2c_add_driver(&wm8961_i2c_driver);
if (ret != 0) {
- printk(KERN_ERR "Failed to register WM8961 I2C driver: %d\n",
+ printk(KERN_ERR "Failed to register wm8961 I2C driver: %d\n",
ret);
}
-
+#endif
return ret;
}
module_init(wm8961_modinit);
static void __exit wm8961_exit(void)
{
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
i2c_del_driver(&wm8961_i2c_driver);
+#endif
}
module_exit(wm8961_exit);
-
MODULE_DESCRIPTION("ASoC WM8961 driver");
MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8961.h b/sound/soc/codecs/wm8961.h
index 5513bfd720d6..1d736e5701c8 100644
--- a/sound/soc/codecs/wm8961.h
+++ b/sound/soc/codecs/wm8961.h
@@ -11,9 +11,6 @@
#include <sound/soc.h>
-extern struct snd_soc_codec_device soc_codec_dev_wm8961;
-extern struct snd_soc_dai wm8961_dai;
-
#define WM8961_BCLK 1
#define WM8961_LRCLK 2
diff --git a/sound/soc/codecs/wm8971.c b/sound/soc/codecs/wm8971.c
index a99620f335d2..ad2692afbb31 100644
--- a/sound/soc/codecs/wm8971.c
+++ b/sound/soc/codecs/wm8971.c
@@ -38,6 +38,8 @@ static struct workqueue_struct *wm8971_workq = NULL;
/* codec private data */
struct wm8971_priv {
+ enum snd_soc_control_type control_type;
+ void *control_data;
unsigned int sysclk;
};
@@ -492,8 +494,7 @@ static int wm8971_pcm_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 wm8971_priv *wm8971 = snd_soc_codec_get_drvdata(codec);
u16 iface = snd_soc_read(codec, WM8971_IFACE) & 0x1f3;
u16 srate = snd_soc_read(codec, WM8971_SRATE) & 0x1c0;
@@ -573,8 +574,8 @@ static struct snd_soc_dai_ops wm8971_dai_ops = {
.set_sysclk = wm8971_set_dai_sysclk,
};
-struct snd_soc_dai wm8971_dai = {
- .name = "WM8971",
+static struct snd_soc_dai_driver wm8971_dai = {
+ .name = "wm8971-hifi",
.playback = {
.stream_name = "Playback",
.channels_min = 1,
@@ -589,7 +590,6 @@ struct snd_soc_dai wm8971_dai = {
.formats = WM8971_FORMATS,},
.ops = &wm8971_dai_ops,
};
-EXPORT_SYMBOL_GPL(wm8971_dai);
static void wm8971_work(struct work_struct *work)
{
@@ -598,19 +598,14 @@ static void wm8971_work(struct work_struct *work)
wm8971_set_bias_level(codec, codec->bias_level);
}
-static int wm8971_suspend(struct platform_device *pdev, pm_message_t state)
+static int wm8971_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;
-
wm8971_set_bias_level(codec, SND_SOC_BIAS_OFF);
return 0;
}
-static int wm8971_resume(struct platform_device *pdev)
+static int wm8971_resume(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec = socdev->card->codec;
int i;
u8 data[2];
u16 *cache = codec->reg_cache;
@@ -639,37 +634,27 @@ static int wm8971_resume(struct platform_device *pdev)
return 0;
}
-static int wm8971_init(struct snd_soc_device *socdev,
- enum snd_soc_control_type control)
+static int wm8971_probe(struct snd_soc_codec *codec)
{
- struct snd_soc_codec *codec = socdev->card->codec;
- int reg, ret = 0;
-
- codec->name = "WM8971";
- codec->owner = THIS_MODULE;
- codec->set_bias_level = wm8971_set_bias_level;
- codec->dai = &wm8971_dai;
- codec->reg_cache_size = ARRAY_SIZE(wm8971_reg);
- codec->num_dai = 1;
- codec->reg_cache = kmemdup(wm8971_reg, sizeof(wm8971_reg), GFP_KERNEL);
-
- if (codec->reg_cache == NULL)
- return -ENOMEM;
+ struct wm8971_priv *wm8971 = snd_soc_codec_get_drvdata(codec);
+ int ret = 0;
+ u16 reg;
+
+ pr_info("WM8971 Audio Codec %s", WM8971_VERSION);
- ret = snd_soc_codec_set_cache_io(codec, 7, 9, control);
+ codec->control_data = wm8971->control_data;
+ ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8971->control_type);
if (ret < 0) {
printk(KERN_ERR "wm8971: failed to set cache I/O: %d\n", ret);
- goto err;
+ return ret;
}
- wm8971_reset(codec);
+ INIT_DELAYED_WORK(&codec->delayed_work, wm8971_work);
+ wm8971_workq = create_workqueue("wm8971");
+ if (wm8971_workq == NULL)
+ return -ENOMEM;
- /* register pcms */
- ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
- if (ret < 0) {
- printk(KERN_ERR "wm8971: failed to create pcms\n");
- goto err;
- }
+ wm8971_reset(codec);
/* charge output caps - set vmid to 5k for quick power up */
reg = snd_soc_read(codec, WM8971_PWR1) & 0xfe3e;
@@ -704,40 +689,55 @@ static int wm8971_init(struct snd_soc_device *socdev,
wm8971_add_widgets(codec);
return ret;
-
-err:
- kfree(codec->reg_cache);
- return ret;
}
-/* If the i2c layer weren't so broken, we could pass this kind of data
- around */
-static struct snd_soc_device *wm8971_socdev;
-#if defined (CONFIG_I2C) || defined (CONFIG_I2C_MODULE)
+/* power down chip */
+static int wm8971_remove(struct snd_soc_codec *codec)
+{
+ wm8971_set_bias_level(codec, SND_SOC_BIAS_OFF);
+
+ if (wm8971_workq)
+ destroy_workqueue(wm8971_workq);
+ return 0;
+}
+
+static struct snd_soc_codec_driver soc_codec_dev_wm8971 = {
+ .probe = wm8971_probe,
+ .remove = wm8971_remove,
+ .suspend = wm8971_suspend,
+ .resume = wm8971_resume,
+ .set_bias_level = wm8971_set_bias_level,
+ .reg_cache_size = ARRAY_SIZE(wm8971_reg),
+ .reg_word_size = sizeof(u16),
+ .reg_cache_default = wm8971_reg,
+};
-static int wm8971_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+static __devinit int wm8971_i2c_probe(struct i2c_client *i2c,
+ const struct i2c_device_id *id)
{
- struct snd_soc_device *socdev = wm8971_socdev;
- struct snd_soc_codec *codec = socdev->card->codec;
+ struct wm8971_priv *wm8971;
int ret;
- i2c_set_clientdata(i2c, codec);
+ wm8971 = kzalloc(sizeof(struct wm8971_priv), GFP_KERNEL);
+ if (wm8971 == NULL)
+ return -ENOMEM;
- codec->control_data = i2c;
+ i2c_set_clientdata(i2c, wm8971);
+ wm8971->control_data = i2c;
- ret = wm8971_init(socdev, SND_SOC_I2C);
+ ret = snd_soc_register_codec(&i2c->dev,
+ &soc_codec_dev_wm8971, &wm8971_dai, 1);
if (ret < 0)
- pr_err("failed to initialise WM8971\n");
-
+ kfree(wm8971);
return ret;
}
-static int wm8971_i2c_remove(struct i2c_client *client)
+static __devexit int wm8971_i2c_remove(struct i2c_client *client)
{
- struct snd_soc_codec *codec = i2c_get_clientdata(client);
- kfree(codec->reg_cache);
+ snd_soc_unregister_codec(&client->dev);
+ kfree(i2c_get_clientdata(client));
return 0;
}
@@ -749,148 +749,34 @@ MODULE_DEVICE_TABLE(i2c, wm8971_i2c_id);
static struct i2c_driver wm8971_i2c_driver = {
.driver = {
- .name = "WM8971 I2C Codec",
+ .name = "wm8971-codec",
.owner = THIS_MODULE,
},
- .probe = wm8971_i2c_probe,
- .remove = wm8971_i2c_remove,
+ .probe = wm8971_i2c_probe,
+ .remove = __devexit_p(wm8971_i2c_remove),
.id_table = wm8971_i2c_id,
};
-
-static int wm8971_add_i2c_device(struct platform_device *pdev,
- const struct wm8971_setup_data *setup)
-{
- struct i2c_board_info info;
- struct i2c_adapter *adapter;
- struct i2c_client *client;
- int ret;
-
- ret = i2c_add_driver(&wm8971_i2c_driver);
- if (ret != 0) {
- dev_err(&pdev->dev, "can't add i2c driver\n");
- return ret;
- }
-
- memset(&info, 0, sizeof(struct i2c_board_info));
- info.addr = setup->i2c_address;
- strlcpy(info.type, "wm8971", I2C_NAME_SIZE);
-
- adapter = i2c_get_adapter(setup->i2c_bus);
- if (!adapter) {
- dev_err(&pdev->dev, "can't get i2c adapter %d\n",
- setup->i2c_bus);
- goto err_driver;
- }
-
- client = i2c_new_device(adapter, &info);
- i2c_put_adapter(adapter);
- if (!client) {
- dev_err(&pdev->dev, "can't add i2c device at 0x%x\n",
- (unsigned int)info.addr);
- goto err_driver;
- }
-
- return 0;
-
-err_driver:
- i2c_del_driver(&wm8971_i2c_driver);
- return -ENODEV;
-}
-
#endif
-static int wm8971_probe(struct platform_device *pdev)
+static int __init wm8971_modinit(void)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct wm8971_setup_data *setup;
- struct snd_soc_codec *codec;
- struct wm8971_priv *wm8971;
int ret = 0;
-
- pr_info("WM8971 Audio Codec %s", WM8971_VERSION);
-
- setup = socdev->codec_data;
- codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
- if (codec == NULL)
- return -ENOMEM;
-
- wm8971 = kzalloc(sizeof(struct wm8971_priv), GFP_KERNEL);
- if (wm8971 == NULL) {
- kfree(codec);
- return -ENOMEM;
- }
-
- snd_soc_codec_set_drvdata(codec, wm8971);
- socdev->card->codec = codec;
- mutex_init(&codec->mutex);
- INIT_LIST_HEAD(&codec->dapm_widgets);
- INIT_LIST_HEAD(&codec->dapm_paths);
- wm8971_socdev = socdev;
-
- INIT_DELAYED_WORK(&codec->delayed_work, wm8971_work);
- wm8971_workq = create_workqueue("wm8971");
- if (wm8971_workq == NULL) {
- kfree(snd_soc_codec_get_drvdata(codec));
- kfree(codec);
- return -ENOMEM;
- }
-
-#if defined (CONFIG_I2C) || defined (CONFIG_I2C_MODULE)
- if (setup->i2c_address) {
- ret = wm8971_add_i2c_device(pdev, setup);
- }
-#endif
- /* Add other interfaces here */
-
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+ ret = i2c_add_driver(&wm8971_i2c_driver);
if (ret != 0) {
- destroy_workqueue(wm8971_workq);
- kfree(snd_soc_codec_get_drvdata(codec));
- kfree(codec);
+ printk(KERN_ERR "Failed to register WM8971 I2C driver: %d\n",
+ ret);
}
-
- return ret;
-}
-
-/* power down chip */
-static int wm8971_remove(struct platform_device *pdev)
-{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec = socdev->card->codec;
-
- if (codec->control_data)
- wm8971_set_bias_level(codec, SND_SOC_BIAS_OFF);
- if (wm8971_workq)
- destroy_workqueue(wm8971_workq);
- snd_soc_free_pcms(socdev);
- snd_soc_dapm_free(socdev);
-#if defined (CONFIG_I2C) || defined (CONFIG_I2C_MODULE)
- i2c_unregister_device(codec->control_data);
- i2c_del_driver(&wm8971_i2c_driver);
#endif
- kfree(snd_soc_codec_get_drvdata(codec));
- kfree(codec);
-
- return 0;
-}
-
-struct snd_soc_codec_device soc_codec_dev_wm8971 = {
- .probe = wm8971_probe,
- .remove = wm8971_remove,
- .suspend = wm8971_suspend,
- .resume = wm8971_resume,
-};
-
-EXPORT_SYMBOL_GPL(soc_codec_dev_wm8971);
-
-static int __init wm8971_modinit(void)
-{
- return snd_soc_register_dai(&wm8971_dai);
+ return ret;
}
module_init(wm8971_modinit);
static void __exit wm8971_exit(void)
{
- snd_soc_unregister_dai(&wm8971_dai);
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+ i2c_del_driver(&wm8971_i2c_driver);
+#endif
}
module_exit(wm8971_exit);
diff --git a/sound/soc/codecs/wm8971.h b/sound/soc/codecs/wm8971.h
index ef4f08f9f344..f31c38fddfc4 100644
--- a/sound/soc/codecs/wm8971.h
+++ b/sound/soc/codecs/wm8971.h
@@ -53,12 +53,4 @@
#define WM8971_SYSCLK 0
-struct wm8971_setup_data {
- int i2c_bus;
- unsigned short i2c_address;
-};
-
-extern struct snd_soc_dai wm8971_dai;
-extern struct snd_soc_codec_device soc_codec_dev_wm8971;
-
#endif
diff --git a/sound/soc/codecs/wm8974.c b/sound/soc/codecs/wm8974.c
index 1468fe10cbbe..52f631c62e29 100644
--- a/sound/soc/codecs/wm8974.c
+++ b/sound/soc/codecs/wm8974.c
@@ -51,12 +51,11 @@ static const u16 wm8974_reg[WM8974_CACHEREGNUM] = {
#define WM8974_POWER1_BUFIOEN 0x04
struct wm8974_priv {
- struct snd_soc_codec codec;
+ enum snd_soc_control_type control_type;
+ void *control_data;
u16 reg_cache[WM8974_CACHEREGNUM];
};
-static struct snd_soc_codec *wm8974_codec;
-
#define wm8974_reset(c) snd_soc_write(c, WM8974_RESET, 0)
static const char *wm8974_companding[] = {"Off", "NC", "u-law", "A-law" };
@@ -566,8 +565,8 @@ static struct snd_soc_dai_ops wm8974_ops = {
.set_pll = wm8974_set_dai_pll,
};
-struct snd_soc_dai wm8974_dai = {
- .name = "WM8974 HiFi",
+static struct snd_soc_dai_driver wm8974_dai = {
+ .name = "wm8974-hifi",
.playback = {
.stream_name = "Playback",
.channels_min = 1,
@@ -583,21 +582,15 @@ struct snd_soc_dai wm8974_dai = {
.ops = &wm8974_ops,
.symmetric_rates = 1,
};
-EXPORT_SYMBOL_GPL(wm8974_dai);
-static int wm8974_suspend(struct platform_device *pdev, pm_message_t state)
+static int wm8974_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;
-
wm8974_set_bias_level(codec, SND_SOC_BIAS_OFF);
return 0;
}
-static int wm8974_resume(struct platform_device *pdev)
+static int wm8974_resume(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec = socdev->card->codec;
int i;
u8 data[2];
u16 *cache = codec->reg_cache;
@@ -613,156 +606,75 @@ static int wm8974_resume(struct platform_device *pdev)
return 0;
}
-static int wm8974_probe(struct platform_device *pdev)
+static int wm8974_probe(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec;
+ struct wm8974_priv *wm8974 = snd_soc_codec_get_drvdata(codec);
int ret = 0;
- if (wm8974_codec == NULL) {
- dev_err(&pdev->dev, "Codec device not registered\n");
- return -ENODEV;
+ codec->control_data = wm8974->control_data;
+ ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_I2C);
+ if (ret < 0) {
+ dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
+ return ret;
}
- socdev->card->codec = wm8974_codec;
- codec = wm8974_codec;
-
- /* register pcms */
- ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
+ ret = wm8974_reset(codec);
if (ret < 0) {
- dev_err(codec->dev, "failed to create pcms: %d\n", ret);
- goto pcm_err;
+ dev_err(codec->dev, "Failed to issue reset\n");
+ return ret;
}
+ wm8974_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
snd_soc_add_controls(codec, wm8974_snd_controls,
ARRAY_SIZE(wm8974_snd_controls));
wm8974_add_widgets(codec);
return ret;
-
-pcm_err:
- return ret;
}
/* power down chip */
-static int wm8974_remove(struct platform_device *pdev)
+static int wm8974_remove(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
-
- snd_soc_free_pcms(socdev);
- snd_soc_dapm_free(socdev);
-
+ wm8974_set_bias_level(codec, SND_SOC_BIAS_OFF);
return 0;
}
-struct snd_soc_codec_device soc_codec_dev_wm8974 = {
+static struct snd_soc_codec_driver soc_codec_dev_wm8974 = {
.probe = wm8974_probe,
.remove = wm8974_remove,
.suspend = wm8974_suspend,
.resume = wm8974_resume,
+ .set_bias_level = wm8974_set_bias_level,
+ .reg_cache_size = ARRAY_SIZE(wm8974_reg),
+ .reg_word_size = sizeof(u16),
+ .reg_cache_default = wm8974_reg,
};
-EXPORT_SYMBOL_GPL(soc_codec_dev_wm8974);
-
-static __devinit int wm8974_register(struct wm8974_priv *wm8974)
-{
- int ret;
- struct snd_soc_codec *codec = &wm8974->codec;
-
- if (wm8974_codec) {
- dev_err(codec->dev, "Another WM8974 is registered\n");
- ret = -EINVAL;
- goto err;
- }
-
- mutex_init(&codec->mutex);
- INIT_LIST_HEAD(&codec->dapm_widgets);
- INIT_LIST_HEAD(&codec->dapm_paths);
-
- snd_soc_codec_set_drvdata(codec, wm8974);
- codec->name = "WM8974";
- codec->owner = THIS_MODULE;
- codec->bias_level = SND_SOC_BIAS_OFF;
- codec->set_bias_level = wm8974_set_bias_level;
- codec->dai = &wm8974_dai;
- codec->num_dai = 1;
- codec->reg_cache_size = WM8974_CACHEREGNUM;
- codec->reg_cache = &wm8974->reg_cache;
-
- ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_I2C);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- goto err;
- }
-
- memcpy(codec->reg_cache, wm8974_reg, sizeof(wm8974_reg));
-
- ret = wm8974_reset(codec);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to issue reset\n");
- goto err;
- }
-
- wm8974_dai.dev = codec->dev;
-
- wm8974_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
- wm8974_codec = codec;
-
- ret = snd_soc_register_codec(codec);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to register codec: %d\n", ret);
- goto err;
- }
-
- ret = snd_soc_register_dai(&wm8974_dai);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
- goto err_codec;
- }
-
- return 0;
-
-err_codec:
- snd_soc_unregister_codec(codec);
-err:
- kfree(wm8974);
- return ret;
-}
-
-static __devexit void wm8974_unregister(struct wm8974_priv *wm8974)
-{
- wm8974_set_bias_level(&wm8974->codec, SND_SOC_BIAS_OFF);
- snd_soc_unregister_dai(&wm8974_dai);
- snd_soc_unregister_codec(&wm8974->codec);
- kfree(wm8974);
- wm8974_codec = NULL;
-}
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
static __devinit int wm8974_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
struct wm8974_priv *wm8974;
- struct snd_soc_codec *codec;
+ int ret;
wm8974 = kzalloc(sizeof(struct wm8974_priv), GFP_KERNEL);
if (wm8974 == NULL)
return -ENOMEM;
- codec = &wm8974->codec;
- codec->hw_write = (hw_write_t)i2c_master_send;
-
i2c_set_clientdata(i2c, wm8974);
- codec->control_data = i2c;
-
- codec->dev = &i2c->dev;
+ wm8974->control_data = i2c;
- return wm8974_register(wm8974);
+ ret = snd_soc_register_codec(&i2c->dev,
+ &soc_codec_dev_wm8974, &wm8974_dai, 1);
+ if (ret < 0)
+ kfree(wm8974);
+ return ret;
}
static __devexit int wm8974_i2c_remove(struct i2c_client *client)
{
- struct wm8974_priv *wm8974 = i2c_get_clientdata(client);
- wm8974_unregister(wm8974);
+ snd_soc_unregister_codec(&client->dev);
+ kfree(i2c_get_clientdata(client));
return 0;
}
@@ -774,23 +686,34 @@ MODULE_DEVICE_TABLE(i2c, wm8974_i2c_id);
static struct i2c_driver wm8974_i2c_driver = {
.driver = {
- .name = "WM8974",
+ .name = "wm8974-codec",
.owner = THIS_MODULE,
},
.probe = wm8974_i2c_probe,
.remove = __devexit_p(wm8974_i2c_remove),
.id_table = wm8974_i2c_id,
};
+#endif
static int __init wm8974_modinit(void)
{
- return i2c_add_driver(&wm8974_i2c_driver);
+ int ret = 0;
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+ ret = i2c_add_driver(&wm8974_i2c_driver);
+ if (ret != 0) {
+ printk(KERN_ERR "Failed to register wm8974 I2C driver: %d\n",
+ ret);
+ }
+#endif
+ return ret;
}
module_init(wm8974_modinit);
static void __exit wm8974_exit(void)
{
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
i2c_del_driver(&wm8974_i2c_driver);
+#endif
}
module_exit(wm8974_exit);
diff --git a/sound/soc/codecs/wm8974.h b/sound/soc/codecs/wm8974.h
index 896a7f0f3fc4..3c94e7bb55a6 100644
--- a/sound/soc/codecs/wm8974.h
+++ b/sound/soc/codecs/wm8974.h
@@ -83,7 +83,4 @@
#define WM8974_MCLKDIV_8 (6 << 5)
#define WM8974_MCLKDIV_12 (7 << 5)
-extern struct snd_soc_dai wm8974_dai;
-extern struct snd_soc_codec_device soc_codec_dev_wm8974;
-
#endif
diff --git a/sound/soc/codecs/wm8978.c b/sound/soc/codecs/wm8978.c
index 8a1ad778e7e3..676a4306cc87 100644
--- a/sound/soc/codecs/wm8978.c
+++ b/sound/soc/codecs/wm8978.c
@@ -31,8 +31,6 @@
#include "wm8978.h"
-static struct snd_soc_codec *wm8978_codec;
-
/* wm8978 register cache. Note that register 0 is not included in the cache. */
static const u16 wm8978_reg[WM8978_CACHEREGNUM] = {
0x0000, 0x0000, 0x0000, 0x0000, /* 0x00...0x03 */
@@ -54,7 +52,8 @@ static const u16 wm8978_reg[WM8978_CACHEREGNUM] = {
/* codec private data */
struct wm8978_priv {
- struct snd_soc_codec codec;
+ enum snd_soc_control_type control_type;
+ void *control_data;
unsigned int f_pllout;
unsigned int f_mclk;
unsigned int f_256fs;
@@ -374,8 +373,8 @@ struct wm8978_pll_div {
#define FIXED_PLL_SIZE (1 << 24)
-static void pll_factors(struct wm8978_pll_div *pll_div, unsigned int target,
- unsigned int source)
+static void pll_factors(struct snd_soc_codec *codec,
+ struct wm8978_pll_div *pll_div, unsigned int target, unsigned int source)
{
u64 k_part;
unsigned int k, n_div, n_mod;
@@ -390,7 +389,7 @@ static void pll_factors(struct wm8978_pll_div *pll_div, unsigned int target,
}
if (n_div < 6 || n_div > 12)
- dev_warn(wm8978_codec->dev,
+ dev_warn(codec->dev,
"WM8978 N value exceeds recommended range! N = %u\n",
n_div);
@@ -505,7 +504,7 @@ static int wm8978_configure_pll(struct snd_soc_codec *codec)
dev_dbg(codec->dev, "%s: f_MCLK=%uHz, f_PLLOUT=%uHz\n", __func__,
wm8978->f_mclk, wm8978->f_pllout);
- pll_factors(&pll_div, f2, wm8978->f_mclk);
+ pll_factors(codec, &pll_div, f2, wm8978->f_mclk);
dev_dbg(codec->dev, "%s: calculated PLL N=0x%x, K=0x%x, div2=%d\n",
__func__, pll_div.n, pll_div.k, pll_div.div2);
@@ -690,8 +689,7 @@ static int wm8978_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 wm8978_priv *wm8978 = snd_soc_codec_get_drvdata(codec);
/* Word length mask = 0x60 */
u16 iface_ctl = snd_soc_read(codec, WM8978_AUDIO_INTERFACE) & ~0x60;
@@ -875,9 +873,8 @@ static struct snd_soc_dai_ops wm8978_dai_ops = {
};
/* Also supports 12kHz */
-struct snd_soc_dai wm8978_dai = {
- .name = "WM8978 HiFi",
- .id = 1,
+static struct snd_soc_dai_driver wm8978_dai = {
+ .name = "wm8978-hifi",
.playback = {
.stream_name = "Playback",
.channels_min = 1,
@@ -894,13 +891,9 @@ struct snd_soc_dai wm8978_dai = {
},
.ops = &wm8978_dai_ops,
};
-EXPORT_SYMBOL_GPL(wm8978_dai);
-static int wm8978_suspend(struct platform_device *pdev, pm_message_t state)
+static int wm8978_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;
-
wm8978_set_bias_level(codec, SND_SOC_BIAS_OFF);
/* Also switch PLL off */
snd_soc_write(codec, WM8978_POWER_MANAGEMENT_1, 0);
@@ -908,10 +901,8 @@ static int wm8978_suspend(struct platform_device *pdev, pm_message_t state)
return 0;
}
-static int wm8978_resume(struct platform_device *pdev)
+static int wm8978_resume(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec = socdev->card->codec;
struct wm8978_priv *wm8978 = snd_soc_codec_get_drvdata(codec);
int i;
u16 *cache = codec->reg_cache;
@@ -933,54 +924,6 @@ static int wm8978_resume(struct platform_device *pdev)
return 0;
}
-static int wm8978_probe(struct platform_device *pdev)
-{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec;
- int ret = 0;
-
- if (wm8978_codec == NULL) {
- dev_err(&pdev->dev, "Codec device not registered\n");
- return -ENODEV;
- }
-
- socdev->card->codec = wm8978_codec;
- codec = wm8978_codec;
-
- /* register pcms */
- ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
- if (ret < 0) {
- dev_err(codec->dev, "failed to create pcms: %d\n", ret);
- goto pcm_err;
- }
-
- snd_soc_add_controls(codec, wm8978_snd_controls,
- ARRAY_SIZE(wm8978_snd_controls));
- wm8978_add_widgets(codec);
-
-pcm_err:
- return ret;
-}
-
-/* power down chip */
-static int wm8978_remove(struct platform_device *pdev)
-{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
-
- snd_soc_free_pcms(socdev);
- snd_soc_dapm_free(socdev);
-
- return 0;
-}
-
-struct snd_soc_codec_device soc_codec_dev_wm8978 = {
- .probe = wm8978_probe,
- .remove = wm8978_remove,
- .suspend = wm8978_suspend,
- .resume = wm8978_resume,
-};
-EXPORT_SYMBOL_GPL(soc_codec_dev_wm8978);
-
/*
* These registers contain an "update" bit - bit 8. This means, for example,
* that one can write new DAC digital volume for both channels, but only when
@@ -1000,44 +943,23 @@ static const int update_reg[] = {
WM8978_ROUT2_SPK_CONTROL,
};
-static __devinit int wm8978_register(struct wm8978_priv *wm8978)
+static int wm8978_probe(struct snd_soc_codec *codec)
{
- int ret, i;
- struct snd_soc_codec *codec = &wm8978->codec;
-
- if (wm8978_codec) {
- dev_err(codec->dev, "Another WM8978 is registered\n");
- return -EINVAL;
- }
+ struct wm8978_priv *wm8978 = snd_soc_codec_get_drvdata(codec);
+ int ret = 0, i;
/*
* Set default system clock to PLL, it is more precise, this is also the
* default hardware setting
*/
wm8978->sysclk = WM8978_PLL;
-
- mutex_init(&codec->mutex);
- INIT_LIST_HEAD(&codec->dapm_widgets);
- INIT_LIST_HEAD(&codec->dapm_paths);
-
- snd_soc_codec_set_drvdata(codec, wm8978);
- codec->name = "WM8978";
- codec->owner = THIS_MODULE;
- codec->bias_level = SND_SOC_BIAS_OFF;
- codec->set_bias_level = wm8978_set_bias_level;
- codec->dai = &wm8978_dai;
- codec->num_dai = 1;
- codec->reg_cache_size = WM8978_CACHEREGNUM;
- codec->reg_cache = &wm8978->reg_cache;
-
+ codec->control_data = wm8978->control_data;
ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_I2C);
if (ret < 0) {
dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- goto err;
+ return ret;
}
- memcpy(codec->reg_cache, wm8978_reg, sizeof(wm8978_reg));
-
/*
* Set the update bit in all registers, that have one. This way all
* writes to those registers will also cause the update bit to be
@@ -1050,74 +972,61 @@ static __devinit int wm8978_register(struct wm8978_priv *wm8978)
ret = snd_soc_write(codec, WM8978_RESET, 0);
if (ret < 0) {
dev_err(codec->dev, "Failed to issue reset\n");
- goto err;
+ return ret;
}
- wm8978_dai.dev = codec->dev;
-
wm8978_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
- wm8978_codec = codec;
-
- ret = snd_soc_register_codec(codec);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to register codec: %d\n", ret);
- goto err;
- }
-
- ret = snd_soc_register_dai(&wm8978_dai);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
- goto err_codec;
- }
+ snd_soc_add_controls(codec, wm8978_snd_controls,
+ ARRAY_SIZE(wm8978_snd_controls));
+ wm8978_add_widgets(codec);
return 0;
-
-err_codec:
- snd_soc_unregister_codec(codec);
-err:
- return ret;
}
-static __devexit void wm8978_unregister(struct wm8978_priv *wm8978)
+/* power down chip */
+static int wm8978_remove(struct snd_soc_codec *codec)
{
- wm8978_set_bias_level(&wm8978->codec, SND_SOC_BIAS_OFF);
- snd_soc_unregister_dai(&wm8978_dai);
- snd_soc_unregister_codec(&wm8978->codec);
- wm8978_codec = NULL;
+ wm8978_set_bias_level(codec, SND_SOC_BIAS_OFF);
+ return 0;
}
+static struct snd_soc_codec_driver soc_codec_dev_wm8978 = {
+ .probe = wm8978_probe,
+ .remove = wm8978_remove,
+ .suspend = wm8978_suspend,
+ .resume = wm8978_resume,
+ .set_bias_level = wm8978_set_bias_level,
+ .reg_cache_size = ARRAY_SIZE(wm8978_reg),
+ .reg_word_size = sizeof(u16),
+ .reg_cache_default = wm8978_reg,
+};
+
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
static __devinit int wm8978_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
- int ret;
struct wm8978_priv *wm8978;
- struct snd_soc_codec *codec;
+ int ret;
wm8978 = kzalloc(sizeof(struct wm8978_priv), GFP_KERNEL);
if (wm8978 == NULL)
return -ENOMEM;
- codec = &wm8978->codec;
- codec->hw_write = (hw_write_t)i2c_master_send;
-
i2c_set_clientdata(i2c, wm8978);
- codec->control_data = i2c;
-
- codec->dev = &i2c->dev;
+ wm8978->control_data = i2c;
- ret = wm8978_register(wm8978);
+ ret = snd_soc_register_codec(&i2c->dev,
+ &soc_codec_dev_wm8978, &wm8978_dai, 1);
if (ret < 0)
kfree(wm8978);
-
return ret;
}
static __devexit int wm8978_i2c_remove(struct i2c_client *client)
{
- struct wm8978_priv *wm8978 = i2c_get_clientdata(client);
- wm8978_unregister(wm8978);
- kfree(wm8978);
+ snd_soc_unregister_codec(&client->dev);
+ kfree(i2c_get_clientdata(client));
return 0;
}
@@ -1129,23 +1038,34 @@ MODULE_DEVICE_TABLE(i2c, wm8978_i2c_id);
static struct i2c_driver wm8978_i2c_driver = {
.driver = {
- .name = "WM8978",
+ .name = "WM8978-codec",
.owner = THIS_MODULE,
},
.probe = wm8978_i2c_probe,
.remove = __devexit_p(wm8978_i2c_remove),
.id_table = wm8978_i2c_id,
};
+#endif
static int __init wm8978_modinit(void)
{
- return i2c_add_driver(&wm8978_i2c_driver);
+ int ret = 0;
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+ ret = i2c_add_driver(&wm8978_i2c_driver);
+ if (ret != 0) {
+ printk(KERN_ERR "Failed to register WM8978 I2C driver: %d\n",
+ ret);
+ }
+#endif
+ return ret;
}
module_init(wm8978_modinit);
static void __exit wm8978_exit(void)
{
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
i2c_del_driver(&wm8978_i2c_driver);
+#endif
}
module_exit(wm8978_exit);
diff --git a/sound/soc/codecs/wm8978.h b/sound/soc/codecs/wm8978.h
index 56ec83270917..c75525b7f154 100644
--- a/sound/soc/codecs/wm8978.h
+++ b/sound/soc/codecs/wm8978.h
@@ -80,7 +80,4 @@ enum wm8978_sysclk_src {
WM8978_MCLK
};
-extern struct snd_soc_dai wm8978_dai;
-extern struct snd_soc_codec_device soc_codec_dev_wm8978;
-
#endif /* __WM8978_H__ */
diff --git a/sound/soc/codecs/wm8988.c b/sound/soc/codecs/wm8988.c
index 19ad590ca0b3..ecbffcea71db 100644
--- a/sound/soc/codecs/wm8988.c
+++ b/sound/soc/codecs/wm8988.c
@@ -52,7 +52,8 @@ static const u16 wm8988_reg[] = {
/* codec private data */
struct wm8988_priv {
unsigned int sysclk;
- struct snd_soc_codec codec;
+ enum snd_soc_control_type control_type;
+ void *control_data;
struct snd_pcm_hw_constraint_list *sysclk_constraints;
u16 reg_cache[WM8988_NUM_REG];
};
@@ -608,8 +609,7 @@ static int wm8988_pcm_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 wm8988_priv *wm8988 = snd_soc_codec_get_drvdata(codec);
u16 iface = snd_soc_read(codec, WM8988_IFACE) & 0x1f3;
u16 srate = snd_soc_read(codec, WM8988_SRATE) & 0x180;
@@ -711,8 +711,8 @@ static struct snd_soc_dai_ops wm8988_ops = {
.digital_mute = wm8988_mute,
};
-struct snd_soc_dai wm8988_dai = {
- .name = "WM8988",
+static struct snd_soc_dai_driver wm8988_dai = {
+ .name = "wm8988-hifi",
.playback = {
.stream_name = "Playback",
.channels_min = 1,
@@ -730,21 +730,15 @@ struct snd_soc_dai wm8988_dai = {
.ops = &wm8988_ops,
.symmetric_rates = 1,
};
-EXPORT_SYMBOL_GPL(wm8988_dai);
-static int wm8988_suspend(struct platform_device *pdev, pm_message_t state)
+static int wm8988_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;
-
wm8988_set_bias_level(codec, SND_SOC_BIAS_OFF);
return 0;
}
-static int wm8988_resume(struct platform_device *pdev)
+static int wm8988_resume(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec = socdev->card->codec;
int i;
u8 data[2];
u16 *cache = codec->reg_cache;
@@ -763,99 +757,23 @@ static int wm8988_resume(struct platform_device *pdev)
return 0;
}
-static struct snd_soc_codec *wm8988_codec;
-
-static int wm8988_probe(struct platform_device *pdev)
+static int wm8988_probe(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec;
+ struct wm8988_priv *wm8988 = snd_soc_codec_get_drvdata(codec);
int ret = 0;
-
- if (wm8988_codec == NULL) {
- dev_err(&pdev->dev, "Codec device not registered\n");
- return -ENODEV;
- }
-
- socdev->card->codec = wm8988_codec;
- codec = wm8988_codec;
-
- /* register pcms */
- ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
- if (ret < 0) {
- dev_err(codec->dev, "failed to create pcms: %d\n", ret);
- goto pcm_err;
- }
-
- snd_soc_add_controls(codec, wm8988_snd_controls,
- ARRAY_SIZE(wm8988_snd_controls));
- snd_soc_dapm_new_controls(codec, wm8988_dapm_widgets,
- ARRAY_SIZE(wm8988_dapm_widgets));
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
-
- return ret;
-
-pcm_err:
- return ret;
-}
-
-static int wm8988_remove(struct platform_device *pdev)
-{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
-
- snd_soc_free_pcms(socdev);
- snd_soc_dapm_free(socdev);
-
- return 0;
-}
-
-struct snd_soc_codec_device soc_codec_dev_wm8988 = {
- .probe = wm8988_probe,
- .remove = wm8988_remove,
- .suspend = wm8988_suspend,
- .resume = wm8988_resume,
-};
-EXPORT_SYMBOL_GPL(soc_codec_dev_wm8988);
-
-static int wm8988_register(struct wm8988_priv *wm8988,
- enum snd_soc_control_type control)
-{
- struct snd_soc_codec *codec = &wm8988->codec;
- int ret;
u16 reg;
- if (wm8988_codec) {
- dev_err(codec->dev, "Another WM8988 is registered\n");
- ret = -EINVAL;
- goto err;
- }
-
- mutex_init(&codec->mutex);
- INIT_LIST_HEAD(&codec->dapm_widgets);
- INIT_LIST_HEAD(&codec->dapm_paths);
-
- snd_soc_codec_set_drvdata(codec, wm8988);
- codec->name = "WM8988";
- codec->owner = THIS_MODULE;
- codec->dai = &wm8988_dai;
- codec->num_dai = 1;
- codec->reg_cache_size = ARRAY_SIZE(wm8988->reg_cache);
- codec->reg_cache = &wm8988->reg_cache;
- codec->bias_level = SND_SOC_BIAS_OFF;
- codec->set_bias_level = wm8988_set_bias_level;
-
- memcpy(codec->reg_cache, wm8988_reg,
- sizeof(wm8988_reg));
-
- ret = snd_soc_codec_set_cache_io(codec, 7, 9, control);
+ codec->control_data = wm8988->control_data;
+ ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8988->control_type);
if (ret < 0) {
dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- goto err;
+ return ret;
}
ret = wm8988_reset(codec);
if (ret < 0) {
dev_err(codec->dev, "Failed to issue reset\n");
- goto err;
+ return ret;
}
/* set the update bits (we always update left then right) */
@@ -870,139 +788,135 @@ static int wm8988_register(struct wm8988_priv *wm8988,
reg = snd_soc_read(codec, WM8988_RINVOL);
snd_soc_write(codec, WM8988_RINVOL, reg | 0x0100);
- wm8988_set_bias_level(&wm8988->codec, SND_SOC_BIAS_STANDBY);
-
- wm8988_dai.dev = codec->dev;
-
- wm8988_codec = codec;
-
- ret = snd_soc_register_codec(codec);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to register codec: %d\n", ret);
- goto err;
- }
+ wm8988_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
- ret = snd_soc_register_dai(&wm8988_dai);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
- goto err_codec;
- }
+ snd_soc_add_controls(codec, wm8988_snd_controls,
+ ARRAY_SIZE(wm8988_snd_controls));
+ snd_soc_dapm_new_controls(codec, wm8988_dapm_widgets,
+ ARRAY_SIZE(wm8988_dapm_widgets));
+ snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
return 0;
-
-err_codec:
- snd_soc_unregister_codec(codec);
-err:
- kfree(wm8988);
- return ret;
}
-static void wm8988_unregister(struct wm8988_priv *wm8988)
+static int wm8988_remove(struct snd_soc_codec *codec)
{
- wm8988_set_bias_level(&wm8988->codec, SND_SOC_BIAS_OFF);
- snd_soc_unregister_dai(&wm8988_dai);
- snd_soc_unregister_codec(&wm8988->codec);
- kfree(wm8988);
- wm8988_codec = NULL;
+ wm8988_set_bias_level(codec, SND_SOC_BIAS_OFF);
+ return 0;
}
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
-static int wm8988_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
+static struct snd_soc_codec_driver soc_codec_dev_wm8988 = {
+ .probe = wm8988_probe,
+ .remove = wm8988_remove,
+ .suspend = wm8988_suspend,
+ .resume = wm8988_resume,
+ .set_bias_level = wm8988_set_bias_level,
+ .reg_cache_size = sizeof(wm8988_reg),
+ .reg_word_size = sizeof(u16),
+ .reg_cache_default = wm8988_reg,
+};
+
+#if defined(CONFIG_SPI_MASTER)
+static int __devinit wm8988_spi_probe(struct spi_device *spi)
{
struct wm8988_priv *wm8988;
- struct snd_soc_codec *codec;
+ int ret;
wm8988 = kzalloc(sizeof(struct wm8988_priv), GFP_KERNEL);
if (wm8988 == NULL)
return -ENOMEM;
- codec = &wm8988->codec;
-
- i2c_set_clientdata(i2c, wm8988);
- codec->control_data = i2c;
-
- codec->dev = &i2c->dev;
+ wm8988->control_data = spi;
+ wm8988->control_type = SND_SOC_SPI;
+ spi_set_drvdata(spi, wm8988);
- return wm8988_register(wm8988, SND_SOC_I2C);
+ ret = snd_soc_register_codec(&spi->dev,
+ &soc_codec_dev_wm8988, &wm8988_dai, 1);
+ if (ret < 0)
+ kfree(wm8988);
+ return ret;
}
-static int wm8988_i2c_remove(struct i2c_client *client)
+static int __devexit wm8988_spi_remove(struct spi_device *spi)
{
- struct wm8988_priv *wm8988 = i2c_get_clientdata(client);
- wm8988_unregister(wm8988);
+ snd_soc_unregister_codec(&spi->dev);
+ kfree(spi_get_drvdata(spi));
return 0;
}
-static const struct i2c_device_id wm8988_i2c_id[] = {
- { "wm8988", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, wm8988_i2c_id);
-
-static struct i2c_driver wm8988_i2c_driver = {
+static struct spi_driver wm8988_spi_driver = {
.driver = {
- .name = "WM8988",
- .owner = THIS_MODULE,
+ .name = "wm8988-codec",
+ .bus = &spi_bus_type,
+ .owner = THIS_MODULE,
},
- .probe = wm8988_i2c_probe,
- .remove = wm8988_i2c_remove,
- .id_table = wm8988_i2c_id,
+ .probe = wm8988_spi_probe,
+ .remove = __devexit_p(wm8988_spi_remove),
};
-#endif
+#endif /* CONFIG_SPI_MASTER */
-#if defined(CONFIG_SPI_MASTER)
-static int __devinit wm8988_spi_probe(struct spi_device *spi)
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+static __devinit int wm8988_i2c_probe(struct i2c_client *i2c,
+ const struct i2c_device_id *id)
{
struct wm8988_priv *wm8988;
- struct snd_soc_codec *codec;
+ int ret;
wm8988 = kzalloc(sizeof(struct wm8988_priv), GFP_KERNEL);
if (wm8988 == NULL)
return -ENOMEM;
- codec = &wm8988->codec;
- codec->control_data = spi;
- codec->dev = &spi->dev;
-
- dev_set_drvdata(&spi->dev, wm8988);
+ i2c_set_clientdata(i2c, wm8988);
+ wm8988->control_data = i2c;
+ wm8988->control_type = SND_SOC_I2C;
- return wm8988_register(wm8988, SND_SOC_SPI);
+ ret = snd_soc_register_codec(&i2c->dev,
+ &soc_codec_dev_wm8988, &wm8988_dai, 1);
+ if (ret < 0)
+ kfree(wm8988);
+ return ret;
}
-static int __devexit wm8988_spi_remove(struct spi_device *spi)
+static __devexit int wm8988_i2c_remove(struct i2c_client *client)
{
- struct wm8988_priv *wm8988 = dev_get_drvdata(&spi->dev);
-
- wm8988_unregister(wm8988);
-
+ snd_soc_unregister_codec(&client->dev);
+ kfree(i2c_get_clientdata(client));
return 0;
}
-static struct spi_driver wm8988_spi_driver = {
+static const struct i2c_device_id wm8988_i2c_id[] = {
+ { "wm8988", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, wm8988_i2c_id);
+
+static struct i2c_driver wm8988_i2c_driver = {
.driver = {
- .name = "wm8988",
- .bus = &spi_bus_type,
- .owner = THIS_MODULE,
+ .name = "wm8988-codec",
+ .owner = THIS_MODULE,
},
- .probe = wm8988_spi_probe,
- .remove = __devexit_p(wm8988_spi_remove),
+ .probe = wm8988_i2c_probe,
+ .remove = __devexit_p(wm8988_i2c_remove),
+ .id_table = wm8988_i2c_id,
};
#endif
static int __init wm8988_modinit(void)
{
- int ret;
-
+ int ret = 0;
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
ret = i2c_add_driver(&wm8988_i2c_driver);
- if (ret != 0)
- pr_err("WM8988: Unable to register I2C driver: %d\n", ret);
+ if (ret != 0) {
+ printk(KERN_ERR "Failed to register WM8988 I2C driver: %d\n",
+ ret);
+ }
#endif
#if defined(CONFIG_SPI_MASTER)
ret = spi_register_driver(&wm8988_spi_driver);
- if (ret != 0)
- pr_err("WM8988: Unable to register SPI driver: %d\n", ret);
+ if (ret != 0) {
+ printk(KERN_ERR "Failed to register WM8988 SPI driver: %d\n",
+ ret);
+ }
#endif
return ret;
}
diff --git a/sound/soc/codecs/wm8988.h b/sound/soc/codecs/wm8988.h
index 4552d37fdd41..5c04024e5f9f 100644
--- a/sound/soc/codecs/wm8988.h
+++ b/sound/soc/codecs/wm8988.h
@@ -54,7 +54,4 @@
#define WM8988_SYSCLK 0
-extern struct snd_soc_dai wm8988_dai;
-extern struct snd_soc_codec_device soc_codec_dev_wm8988;
-
#endif
diff --git a/sound/soc/codecs/wm8990.c b/sound/soc/codecs/wm8990.c
index dd8d909788c1..b25243382966 100644
--- a/sound/soc/codecs/wm8990.c
+++ b/sound/soc/codecs/wm8990.c
@@ -32,6 +32,8 @@
/* codec private data */
struct wm8990_priv {
+ enum snd_soc_control_type control_type;
+ void *control_data;
unsigned int sysclk;
unsigned int pcmclk;
};
@@ -1114,8 +1116,7 @@ static int wm8990_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;
u16 audio1 = snd_soc_read(codec, WM8990_AUDIO_INTERFACE_1);
audio1 &= ~WM8990_AIF_WL_MASK;
@@ -1293,10 +1294,9 @@ static struct snd_soc_dai_ops wm8990_dai_ops = {
.set_sysclk = wm8990_set_dai_sysclk,
};
-struct snd_soc_dai wm8990_dai = {
+static struct snd_soc_dai_driver wm8990_dai = {
/* ADC/DAC on primary */
- .name = "WM8990 ADC/DAC Primary",
- .id = 1,
+ .name = "wm8990-hifi",
.playback = {
.stream_name = "Playback",
.channels_min = 1,
@@ -1311,21 +1311,15 @@ struct snd_soc_dai wm8990_dai = {
.formats = WM8990_FORMATS,},
.ops = &wm8990_dai_ops,
};
-EXPORT_SYMBOL_GPL(wm8990_dai);
-static int wm8990_suspend(struct platform_device *pdev, pm_message_t state)
+static int wm8990_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;
-
wm8990_set_bias_level(codec, SND_SOC_BIAS_OFF);
return 0;
}
-static int wm8990_resume(struct platform_device *pdev)
+static int wm8990_resume(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec = socdev->card->codec;
int i;
u8 data[2];
u16 *cache = codec->reg_cache;
@@ -1347,38 +1341,21 @@ static int wm8990_resume(struct platform_device *pdev)
* initialise the WM8990 driver
* register the mixer and dsp interfaces with the kernel
*/
-static int wm8990_init(struct snd_soc_device *socdev)
+static int wm8990_probe(struct snd_soc_codec *codec)
{
- struct snd_soc_codec *codec = socdev->card->codec;
+ struct wm8990_priv *wm8990 = snd_soc_codec_get_drvdata(codec);
+ int ret;
u16 reg;
- int ret = 0;
-
- codec->name = "WM8990";
- codec->owner = THIS_MODULE;
- codec->set_bias_level = wm8990_set_bias_level;
- codec->dai = &wm8990_dai;
- codec->num_dai = 2;
- codec->reg_cache_size = ARRAY_SIZE(wm8990_reg);
- codec->reg_cache = kmemdup(wm8990_reg, sizeof(wm8990_reg), GFP_KERNEL);
-
- if (codec->reg_cache == NULL)
- return -ENOMEM;
+ codec->control_data = wm8990->control_data;
ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
if (ret < 0) {
printk(KERN_ERR "wm8990: failed to set cache I/O: %d\n", ret);
- goto pcm_err;
+ return ret;
}
wm8990_reset(codec);
- /* register pcms */
- ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
- if (ret < 0) {
- printk(KERN_ERR "wm8990: failed to create pcms\n");
- goto pcm_err;
- }
-
/* charge output caps */
codec->bias_level = SND_SOC_BIAS_OFF;
wm8990_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
@@ -1400,47 +1377,52 @@ static int wm8990_init(struct snd_soc_device *socdev)
ARRAY_SIZE(wm8990_snd_controls));
wm8990_add_widgets(codec);
- return ret;
+ return 0;
+}
-pcm_err:
- kfree(codec->reg_cache);
- return ret;
+/* power down chip */
+static int wm8990_remove(struct snd_soc_codec *codec)
+{
+ wm8990_set_bias_level(codec, SND_SOC_BIAS_OFF);
+ return 0;
}
-/* If the i2c layer weren't so broken, we could pass this kind of data
- around */
-static struct snd_soc_device *wm8990_socdev;
+static struct snd_soc_codec_driver soc_codec_dev_wm8990 = {
+ .probe = wm8990_probe,
+ .remove = wm8990_remove,
+ .suspend = wm8990_suspend,
+ .resume = wm8990_resume,
+ .set_bias_level = wm8990_set_bias_level,
+ .reg_cache_size = ARRAY_SIZE(wm8990_reg),
+ .reg_word_size = sizeof(u16),
+ .reg_cache_default = wm8990_reg,
+};
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
-
-/*
- * WM891 2 wire address is determined by GPIO5
- * state during powerup.
- * low = 0x34
- * high = 0x36
- */
-
-static int wm8990_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
+static __devinit int wm8990_i2c_probe(struct i2c_client *i2c,
+ const struct i2c_device_id *id)
{
- struct snd_soc_device *socdev = wm8990_socdev;
- struct snd_soc_codec *codec = socdev->card->codec;
+ struct wm8990_priv *wm8990;
int ret;
- i2c_set_clientdata(i2c, codec);
- codec->control_data = i2c;
+ wm8990 = kzalloc(sizeof(struct wm8990_priv), GFP_KERNEL);
+ if (wm8990 == NULL)
+ return -ENOMEM;
- ret = wm8990_init(socdev);
- if (ret < 0)
- pr_err("failed to initialise WM8990\n");
+ i2c_set_clientdata(i2c, wm8990);
+ wm8990->control_data = i2c;
+ ret = snd_soc_register_codec(&i2c->dev,
+ &soc_codec_dev_wm8990, &wm8990_dai, 1);
+ if (ret < 0)
+ kfree(wm8990);
return ret;
}
-static int wm8990_i2c_remove(struct i2c_client *client)
+static __devexit int wm8990_i2c_remove(struct i2c_client *client)
{
- struct snd_soc_codec *codec = i2c_get_clientdata(client);
- kfree(codec->reg_cache);
+ snd_soc_unregister_codec(&client->dev);
+ kfree(i2c_get_clientdata(client));
return 0;
}
@@ -1452,134 +1434,34 @@ MODULE_DEVICE_TABLE(i2c, wm8990_i2c_id);
static struct i2c_driver wm8990_i2c_driver = {
.driver = {
- .name = "WM8990 I2C Codec",
+ .name = "wm8990-codec",
.owner = THIS_MODULE,
},
.probe = wm8990_i2c_probe,
- .remove = wm8990_i2c_remove,
+ .remove = __devexit_p(wm8990_i2c_remove),
.id_table = wm8990_i2c_id,
};
-
-static int wm8990_add_i2c_device(struct platform_device *pdev,
- const struct wm8990_setup_data *setup)
-{
- struct i2c_board_info info;
- struct i2c_adapter *adapter;
- struct i2c_client *client;
- int ret;
-
- ret = i2c_add_driver(&wm8990_i2c_driver);
- if (ret != 0) {
- dev_err(&pdev->dev, "can't add i2c driver\n");
- return ret;
- }
-
- memset(&info, 0, sizeof(struct i2c_board_info));
- info.addr = setup->i2c_address;
- strlcpy(info.type, "wm8990", I2C_NAME_SIZE);
-
- adapter = i2c_get_adapter(setup->i2c_bus);
- if (!adapter) {
- dev_err(&pdev->dev, "can't get i2c adapter %d\n",
- setup->i2c_bus);
- goto err_driver;
- }
-
- client = i2c_new_device(adapter, &info);
- i2c_put_adapter(adapter);
- if (!client) {
- dev_err(&pdev->dev, "can't add i2c device at 0x%x\n",
- (unsigned int)info.addr);
- goto err_driver;
- }
-
- return 0;
-
-err_driver:
- i2c_del_driver(&wm8990_i2c_driver);
- return -ENODEV;
-}
#endif
-static int wm8990_probe(struct platform_device *pdev)
+static int __init wm8990_modinit(void)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct wm8990_setup_data *setup;
- struct snd_soc_codec *codec;
- struct wm8990_priv *wm8990;
- int ret;
-
- setup = socdev->codec_data;
- codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
- if (codec == NULL)
- return -ENOMEM;
-
- wm8990 = kzalloc(sizeof(struct wm8990_priv), GFP_KERNEL);
- if (wm8990 == NULL) {
- kfree(codec);
- return -ENOMEM;
- }
-
- snd_soc_codec_set_drvdata(codec, wm8990);
- socdev->card->codec = codec;
- mutex_init(&codec->mutex);
- INIT_LIST_HEAD(&codec->dapm_widgets);
- INIT_LIST_HEAD(&codec->dapm_paths);
- wm8990_socdev = socdev;
-
- ret = -ENODEV;
-
+ int ret = 0;
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
- if (setup->i2c_address) {
- codec->hw_write = (hw_write_t)i2c_master_send;
- ret = wm8990_add_i2c_device(pdev, setup);
- }
-#endif
-
+ ret = i2c_add_driver(&wm8990_i2c_driver);
if (ret != 0) {
- kfree(snd_soc_codec_get_drvdata(codec));
- kfree(codec);
+ printk(KERN_ERR "Failed to register wm8990 I2C driver: %d\n",
+ ret);
}
+#endif
return ret;
}
+module_init(wm8990_modinit);
-/* power down chip */
-static int wm8990_remove(struct platform_device *pdev)
+static void __exit wm8990_exit(void)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec = socdev->card->codec;
-
- if (codec->control_data)
- wm8990_set_bias_level(codec, SND_SOC_BIAS_OFF);
- snd_soc_free_pcms(socdev);
- snd_soc_dapm_free(socdev);
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
- i2c_unregister_device(codec->control_data);
i2c_del_driver(&wm8990_i2c_driver);
#endif
- kfree(snd_soc_codec_get_drvdata(codec));
- kfree(codec);
-
- return 0;
-}
-
-struct snd_soc_codec_device soc_codec_dev_wm8990 = {
- .probe = wm8990_probe,
- .remove = wm8990_remove,
- .suspend = wm8990_suspend,
- .resume = wm8990_resume,
-};
-EXPORT_SYMBOL_GPL(soc_codec_dev_wm8990);
-
-static int __init wm8990_modinit(void)
-{
- return snd_soc_register_dai(&wm8990_dai);
-}
-module_init(wm8990_modinit);
-
-static void __exit wm8990_exit(void)
-{
- snd_soc_unregister_dai(&wm8990_dai);
}
module_exit(wm8990_exit);
diff --git a/sound/soc/codecs/wm8990.h b/sound/soc/codecs/wm8990.h
index 7114ddc88b4b..77c98a4bfe9c 100644
--- a/sound/soc/codecs/wm8990.h
+++ b/sound/soc/codecs/wm8990.h
@@ -826,18 +826,10 @@
#define WM8990_INMIXR_PWR_BIT 2
#define WM8990_AINRMUX_PWR_BIT 3
-struct wm8990_setup_data {
- unsigned i2c_bus;
- unsigned short i2c_address;
-};
-
#define WM8990_MCLK_DIV 0
#define WM8990_DACCLK_DIV 1
#define WM8990_ADCCLK_DIV 2
#define WM8990_BCLK_DIV 3
-extern struct snd_soc_dai wm8990_dai;
-extern struct snd_soc_codec_device soc_codec_dev_wm8990;
-
#endif /* __WM8990REGISTERDEFS_H__ */
/*------------------------------ END OF FILE ---------------------------------*/
diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c
index d8d300c6175f..1d9e1837a2df 100644
--- a/sound/soc/codecs/wm8993.c
+++ b/sound/soc/codecs/wm8993.c
@@ -229,7 +229,8 @@ struct wm8993_priv {
u16 reg_cache[WM8993_REGISTER_COUNT];
struct regulator_bulk_data supplies[WM8993_NUM_SUPPLIES];
struct wm8993_platform_data pdata;
- struct snd_soc_codec codec;
+ enum snd_soc_control_type control_type;
+ void *control_data;
int master;
int sysclk_source;
int tdm_slots;
@@ -367,10 +368,9 @@ static int fll_factors(struct _fll_div *fll_div, unsigned int Fref,
return 0;
}
-static int wm8993_set_fll(struct snd_soc_dai *dai, int fll_id, int source,
+static int _wm8993_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
unsigned int Fref, unsigned int Fout)
{
- struct snd_soc_codec *codec = dai->codec;
struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec);
u16 reg1, reg4, reg5;
struct _fll_div fll_div;
@@ -456,6 +456,12 @@ static int wm8993_set_fll(struct snd_soc_dai *dai, int fll_id, int source,
return 0;
}
+static int wm8993_set_fll(struct snd_soc_dai *dai, int fll_id, int source,
+ unsigned int Fref, unsigned int Fout)
+{
+ return _wm8993_set_fll(dai->codec, fll_id, source, Fref, Fout);
+}
+
static int configure_clock(struct snd_soc_codec *codec)
{
struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec);
@@ -1394,8 +1400,8 @@ static struct snd_soc_dai_ops wm8993_ops = {
SNDRV_PCM_FMTBIT_S24_LE |\
SNDRV_PCM_FMTBIT_S32_LE)
-struct snd_soc_dai wm8993_dai = {
- .name = "WM8993",
+static struct snd_soc_dai_driver wm8993_dai = {
+ .name = "wm8993-hifi",
.playback = {
.stream_name = "Playback",
.channels_min = 1,
@@ -1413,32 +1419,82 @@ struct snd_soc_dai wm8993_dai = {
.ops = &wm8993_ops,
.symmetric_rates = 1,
};
-EXPORT_SYMBOL_GPL(wm8993_dai);
-
-static struct snd_soc_codec *wm8993_codec;
-static int wm8993_probe(struct platform_device *pdev)
+static int wm8993_probe(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec;
- struct wm8993_priv *wm8993;
- int ret = 0;
+ struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec);
+ int ret, i, val;
+
+ codec->control_data = wm8993->control_data;
+ wm8993->hubs_data.hp_startup_mode = 1;
+ wm8993->hubs_data.dcs_codes = -2;
+
+ ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
+ if (ret != 0) {
+ dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
+ return ret;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(wm8993->supplies); i++)
+ wm8993->supplies[i].supply = wm8993_supply_names[i];
- if (!wm8993_codec) {
- dev_err(&pdev->dev, "I2C device not yet probed\n");
- goto err;
+ ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8993->supplies),
+ wm8993->supplies);
+ if (ret != 0) {
+ dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
+ return ret;
}
- socdev->card->codec = wm8993_codec;
- codec = wm8993_codec;
- wm8993 = snd_soc_codec_get_drvdata(codec);
+ ret = regulator_bulk_enable(ARRAY_SIZE(wm8993->supplies),
+ wm8993->supplies);
+ if (ret != 0) {
+ dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
+ goto err_get;
+ }
- ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
- if (ret < 0) {
- dev_err(codec->dev, "failed to create pcms\n");
- goto err;
+ val = snd_soc_read(codec, WM8993_SOFTWARE_RESET);
+ if (val != wm8993_reg_defaults[WM8993_SOFTWARE_RESET]) {
+ dev_err(codec->dev, "Invalid ID register value %x\n", val);
+ ret = -EINVAL;
+ goto err_enable;
}
+ ret = snd_soc_write(codec, WM8993_SOFTWARE_RESET, 0xffff);
+ if (ret != 0)
+ goto err_enable;
+
+ codec->cache_only = 1;
+
+ /* By default we're using the output mixers */
+ wm8993->class_w_users = 2;
+
+ /* Latch volume update bits and default ZC on */
+ snd_soc_update_bits(codec, WM8993_RIGHT_DAC_DIGITAL_VOLUME,
+ WM8993_DAC_VU, WM8993_DAC_VU);
+ snd_soc_update_bits(codec, WM8993_RIGHT_ADC_DIGITAL_VOLUME,
+ WM8993_ADC_VU, WM8993_ADC_VU);
+
+ /* Manualy manage the HPOUT sequencing for independent stereo
+ * control. */
+ snd_soc_update_bits(codec, WM8993_ANALOGUE_HP_0,
+ WM8993_HPOUT1_AUTO_PU, 0);
+
+ /* Use automatic clock configuration */
+ snd_soc_update_bits(codec, WM8993_CLOCKING_4, WM8993_SR_MODE, 0);
+
+ wm_hubs_handle_analogue_pdata(codec, wm8993->pdata.lineout1_diff,
+ wm8993->pdata.lineout2_diff,
+ wm8993->pdata.lineout1fb,
+ wm8993->pdata.lineout2fb,
+ wm8993->pdata.jd_scthr,
+ wm8993->pdata.jd_thr,
+ wm8993->pdata.micbias1_lvl,
+ wm8993->pdata.micbias2_lvl);
+
+ ret = wm8993_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+ if (ret != 0)
+ goto err_enable;
+
snd_soc_add_controls(codec, wm8993_snd_controls,
ARRAY_SIZE(wm8993_snd_controls));
if (wm8993->pdata.num_retune_configs != 0) {
@@ -1457,36 +1513,36 @@ static int wm8993_probe(struct platform_device *pdev)
wm_hubs_add_analogue_routes(codec, wm8993->pdata.lineout1_diff,
wm8993->pdata.lineout2_diff);
- return ret;
+ return 0;
-err:
+err_enable:
+ regulator_bulk_disable(ARRAY_SIZE(wm8993->supplies), wm8993->supplies);
+err_get:
+ regulator_bulk_free(ARRAY_SIZE(wm8993->supplies), wm8993->supplies);
return ret;
}
-static int wm8993_remove(struct platform_device *pdev)
+static int wm8993_remove(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
-
- snd_soc_free_pcms(socdev);
- snd_soc_dapm_free(socdev);
+ struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec);
+ wm8993_set_bias_level(codec, SND_SOC_BIAS_OFF);
+ regulator_bulk_free(ARRAY_SIZE(wm8993->supplies), wm8993->supplies);
return 0;
}
#ifdef CONFIG_PM
-static int wm8993_suspend(struct platform_device *pdev, pm_message_t state)
+static int wm8993_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;
struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec);
int fll_fout = wm8993->fll_fout;
int fll_fref = wm8993->fll_fref;
int ret;
/* Stop the FLL in an orderly fashion */
- ret = wm8993_set_fll(codec->dai, 0, 0, 0, 0);
+ ret = _wm8993_set_fll(codec, 0, 0, 0, 0);
if (ret != 0) {
- dev_err(&pdev->dev, "Failed to stop FLL\n");
+ dev_err(codec->dev, "Failed to stop FLL\n");
return ret;
}
@@ -1498,10 +1554,8 @@ static int wm8993_suspend(struct platform_device *pdev, pm_message_t state)
return 0;
}
-static int wm8993_resume(struct platform_device *pdev)
+static int wm8993_resume(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec = socdev->card->codec;
struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec);
int ret;
@@ -1515,7 +1569,7 @@ static int wm8993_resume(struct platform_device *pdev)
wm8993->fll_fref = 0;
wm8993->fll_fout = 0;
- ret = wm8993_set_fll(codec->dai, 0, wm8993->fll_src,
+ ret = _wm8993_set_fll(codec, 0, wm8993->fll_src,
fll_fref, fll_fout);
if (ret != 0)
dev_err(codec->dev, "Failed to restart FLL\n");
@@ -1528,162 +1582,43 @@ static int wm8993_resume(struct platform_device *pdev)
#define wm8993_resume NULL
#endif
-struct snd_soc_codec_device soc_codec_dev_wm8993 = {
+static struct snd_soc_codec_driver soc_codec_dev_wm8993 = {
.probe = wm8993_probe,
.remove = wm8993_remove,
.suspend = wm8993_suspend,
.resume = wm8993_resume,
+ .set_bias_level = wm8993_set_bias_level,
+ .reg_cache_size = sizeof(wm8993_reg_defaults),
+ .reg_word_size = sizeof(u16),
+ .reg_cache_default = wm8993_reg_defaults,
+ .volatile_register = wm8993_volatile,
};
-EXPORT_SYMBOL_GPL(soc_codec_dev_wm8993);
-static int wm8993_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+static __devinit int wm8993_i2c_probe(struct i2c_client *i2c,
+ const struct i2c_device_id *id)
{
struct wm8993_priv *wm8993;
- struct snd_soc_codec *codec;
- unsigned int val;
int ret;
- int i;
-
- if (wm8993_codec) {
- dev_err(&i2c->dev, "A WM8993 is already registered\n");
- return -EINVAL;
- }
wm8993 = kzalloc(sizeof(struct wm8993_priv), GFP_KERNEL);
if (wm8993 == NULL)
return -ENOMEM;
- codec = &wm8993->codec;
- if (i2c->dev.platform_data)
- memcpy(&wm8993->pdata, i2c->dev.platform_data,
- sizeof(wm8993->pdata));
-
- mutex_init(&codec->mutex);
- INIT_LIST_HEAD(&codec->dapm_widgets);
- INIT_LIST_HEAD(&codec->dapm_paths);
-
- codec->name = "WM8993";
- codec->volatile_register = wm8993_volatile;
- codec->reg_cache = wm8993->reg_cache;
- codec->reg_cache_size = ARRAY_SIZE(wm8993->reg_cache);
- codec->bias_level = SND_SOC_BIAS_OFF;
- codec->set_bias_level = wm8993_set_bias_level;
- codec->dai = &wm8993_dai;
- codec->num_dai = 1;
- snd_soc_codec_set_drvdata(codec, wm8993);
-
- wm8993->hubs_data.hp_startup_mode = 1;
- wm8993->hubs_data.dcs_codes = -2;
-
- memcpy(wm8993->reg_cache, wm8993_reg_defaults,
- sizeof(wm8993->reg_cache));
-
- ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- goto err;
- }
-
i2c_set_clientdata(i2c, wm8993);
- codec->control_data = i2c;
- wm8993_codec = codec;
-
- codec->dev = &i2c->dev;
-
- for (i = 0; i < ARRAY_SIZE(wm8993->supplies); i++)
- wm8993->supplies[i].supply = wm8993_supply_names[i];
-
- ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8993->supplies),
- wm8993->supplies);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
- goto err;
- }
-
- ret = regulator_bulk_enable(ARRAY_SIZE(wm8993->supplies),
- wm8993->supplies);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
- goto err_get;
- }
-
- val = snd_soc_read(codec, WM8993_SOFTWARE_RESET);
- if (val != wm8993_reg_defaults[WM8993_SOFTWARE_RESET]) {
- dev_err(codec->dev, "Invalid ID register value %x\n", val);
- ret = -EINVAL;
- goto err_enable;
- }
-
- ret = snd_soc_write(codec, WM8993_SOFTWARE_RESET, 0xffff);
- if (ret != 0)
- goto err_enable;
-
- codec->cache_only = 1;
-
- /* By default we're using the output mixers */
- wm8993->class_w_users = 2;
-
- /* Latch volume update bits and default ZC on */
- snd_soc_update_bits(codec, WM8993_RIGHT_DAC_DIGITAL_VOLUME,
- WM8993_DAC_VU, WM8993_DAC_VU);
- snd_soc_update_bits(codec, WM8993_RIGHT_ADC_DIGITAL_VOLUME,
- WM8993_ADC_VU, WM8993_ADC_VU);
+ wm8993->control_data = i2c;
- /* Manualy manage the HPOUT sequencing for independent stereo
- * control. */
- snd_soc_update_bits(codec, WM8993_ANALOGUE_HP_0,
- WM8993_HPOUT1_AUTO_PU, 0);
-
- /* Use automatic clock configuration */
- snd_soc_update_bits(codec, WM8993_CLOCKING_4, WM8993_SR_MODE, 0);
-
- wm_hubs_handle_analogue_pdata(codec, wm8993->pdata.lineout1_diff,
- wm8993->pdata.lineout2_diff,
- wm8993->pdata.lineout1fb,
- wm8993->pdata.lineout2fb,
- wm8993->pdata.jd_scthr,
- wm8993->pdata.jd_thr,
- wm8993->pdata.micbias1_lvl,
- wm8993->pdata.micbias2_lvl);
-
- ret = wm8993_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
- if (ret != 0)
- goto err_enable;
-
- wm8993_dai.dev = codec->dev;
-
- ret = snd_soc_register_dai(&wm8993_dai);
- if (ret != 0)
- goto err_bias;
-
- ret = snd_soc_register_codec(codec);
-
- return 0;
-
-err_bias:
- wm8993_set_bias_level(codec, SND_SOC_BIAS_OFF);
-err_enable:
- regulator_bulk_disable(ARRAY_SIZE(wm8993->supplies), wm8993->supplies);
-err_get:
- regulator_bulk_free(ARRAY_SIZE(wm8993->supplies), wm8993->supplies);
-err:
- wm8993_codec = NULL;
- kfree(wm8993);
+ ret = snd_soc_register_codec(&i2c->dev,
+ &soc_codec_dev_wm8993, &wm8993_dai, 1);
+ if (ret < 0)
+ kfree(wm8993);
return ret;
}
-static int wm8993_i2c_remove(struct i2c_client *client)
+static __devexit int wm8993_i2c_remove(struct i2c_client *client)
{
- struct wm8993_priv *wm8993 = i2c_get_clientdata(client);
-
- snd_soc_unregister_codec(&wm8993->codec);
- snd_soc_unregister_dai(&wm8993_dai);
-
- wm8993_set_bias_level(&wm8993->codec, SND_SOC_BIAS_OFF);
- regulator_bulk_free(ARRAY_SIZE(wm8993->supplies), wm8993->supplies);
- kfree(wm8993);
-
+ snd_soc_unregister_codec(&client->dev);
+ kfree(i2c_get_clientdata(client));
return 0;
}
@@ -1695,30 +1630,34 @@ MODULE_DEVICE_TABLE(i2c, wm8993_i2c_id);
static struct i2c_driver wm8993_i2c_driver = {
.driver = {
- .name = "WM8993",
+ .name = "wm8993-codec",
.owner = THIS_MODULE,
},
- .probe = wm8993_i2c_probe,
- .remove = wm8993_i2c_remove,
+ .probe = wm8993_i2c_probe,
+ .remove = __devexit_p(wm8993_i2c_remove),
.id_table = wm8993_i2c_id,
};
-
+#endif
static int __init wm8993_modinit(void)
{
- int ret;
-
+ int ret = 0;
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
ret = i2c_add_driver(&wm8993_i2c_driver);
- if (ret != 0)
- pr_err("WM8993: Unable to register I2C driver: %d\n", ret);
-
+ if (ret != 0) {
+ pr_err("WM8993: Unable to register I2C driver: %d\n",
+ ret);
+ }
+#endif
return ret;
}
module_init(wm8993_modinit);
static void __exit wm8993_exit(void)
{
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
i2c_del_driver(&wm8993_i2c_driver);
+#endif
}
module_exit(wm8993_exit);
diff --git a/sound/soc/codecs/wm8993.h b/sound/soc/codecs/wm8993.h
index 30e71ca88dad..2184617b9611 100644
--- a/sound/soc/codecs/wm8993.h
+++ b/sound/soc/codecs/wm8993.h
@@ -1,9 +1,6 @@
#ifndef WM8993_H
#define WM8993_H
-extern struct snd_soc_dai wm8993_dai;
-extern struct snd_soc_codec_device soc_codec_dev_wm8993;
-
#define WM8993_SYSCLK_MCLK 1
#define WM8993_SYSCLK_FLL 2
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
index a87046a96f2a..7823f92413f3 100644
--- a/sound/soc/codecs/wm8994.c
+++ b/sound/soc/codecs/wm8994.c
@@ -36,9 +36,6 @@
#include "wm8994.h"
#include "wm_hubs.h"
-static struct snd_soc_codec *wm8994_codec;
-struct snd_soc_codec_device soc_codec_dev_wm8994;
-
struct fll_config {
int src;
int in;
@@ -71,7 +68,9 @@ struct wm8994_micdet {
/* codec private data */
struct wm8994_priv {
struct wm_hubs_data hubs;
- struct snd_soc_codec codec;
+ enum snd_soc_control_type control_type;
+ void *control_data;
+ struct snd_soc_codec *codec;
u16 reg_cache[WM8994_REG_CACHE_SIZE + 1];
int sysclk[2];
int sysclk_rate[2];
@@ -1901,8 +1900,6 @@ static int wm8994_put_drc_sw(struct snd_kcontrol *kcontrol,
return snd_soc_put_volsw(kcontrol, ucontrol);
}
-
-
static void wm8994_set_drc(struct snd_soc_codec *codec, int drc)
{
struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
@@ -1941,7 +1938,7 @@ static int wm8994_put_drc_enum(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+ struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
struct wm8994_pdata *pdata = wm8994->pdata;
int drc = wm8994_get_drc(kcontrol->id.name);
int value = ucontrol->value.integer.value[0];
@@ -2044,7 +2041,7 @@ static int wm8994_put_retune_mobile_enum(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+ struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
struct wm8994_pdata *pdata = wm8994->pdata;
int block = wm8994_get_retune_mobile_block(kcontrol->id.name);
int value = ucontrol->value.integer.value[0];
@@ -2066,7 +2063,7 @@ static int wm8994_get_retune_mobile_enum(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+ struct wm8994_priv *wm8994 =snd_soc_codec_get_drvdata(codec);
int block = wm8994_get_retune_mobile_block(kcontrol->id.name);
ucontrol->value.enumerated.item[0] = wm8994->retune_mobile_cfg[block];
@@ -2880,10 +2877,9 @@ static int wm8994_get_fll_config(struct fll_div *fll,
return 0;
}
-static int wm8994_set_fll(struct snd_soc_dai *dai, int id, int src,
+static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src,
unsigned int freq_in, unsigned int freq_out)
{
- struct snd_soc_codec *codec = dai->codec;
struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
int reg_offset, ret;
struct fll_div fll;
@@ -2994,8 +2990,15 @@ static int wm8994_set_fll(struct snd_soc_dai *dai, int id, int src,
return 0;
}
+
static int opclk_divs[] = { 10, 20, 30, 40, 55, 60, 80, 120, 160 };
+static int wm8994_set_fll(struct snd_soc_dai *dai, int id, int src,
+ unsigned int freq_in, unsigned int freq_out)
+{
+ return _wm8994_set_fll(dai->codec, id, src, freq_in, freq_out);
+}
+
static int wm8994_set_dai_sysclk(struct snd_soc_dai *dai,
int clk_id, unsigned int freq, int dir)
{
@@ -3507,10 +3510,9 @@ static struct snd_soc_dai_ops wm8994_aif3_dai_ops = {
.set_tristate = wm8994_set_tristate,
};
-struct snd_soc_dai wm8994_dai[] = {
+static struct snd_soc_dai_driver wm8994_dai[] = {
{
- .name = "WM8994 AIF1",
- .id = 1,
+ .name = "wm8994-aif1",
.playback = {
.stream_name = "AIF1 Playback",
.channels_min = 2,
@@ -3528,8 +3530,7 @@ struct snd_soc_dai wm8994_dai[] = {
.ops = &wm8994_aif1_dai_ops,
},
{
- .name = "WM8994 AIF2",
- .id = 2,
+ .name = "wm8994-aif2",
.playback = {
.stream_name = "AIF2 Playback",
.channels_min = 2,
@@ -3547,8 +3548,7 @@ struct snd_soc_dai wm8994_dai[] = {
.ops = &wm8994_aif2_dai_ops,
},
{
- .name = "WM8994 AIF3",
- .id = 3,
+ .name = "wm8994-aif3",
.playback = {
.stream_name = "AIF3 Playback",
.channels_min = 2,
@@ -3566,20 +3566,17 @@ struct snd_soc_dai wm8994_dai[] = {
.ops = &wm8994_aif3_dai_ops,
}
};
-EXPORT_SYMBOL_GPL(wm8994_dai);
#ifdef CONFIG_PM
-static int wm8994_suspend(struct platform_device *pdev, pm_message_t state)
+static int wm8994_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;
struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
int i, ret;
for (i = 0; i < ARRAY_SIZE(wm8994->fll); i++) {
memcpy(&wm8994->fll_suspend[i], &wm8994->fll[i],
sizeof(struct fll_config));
- ret = wm8994_set_fll(&codec->dai[0], i + 1, 0, 0, 0);
+ ret = _wm8994_set_fll(codec, i + 1, 0, 0, 0);
if (ret < 0)
dev_warn(codec->dev, "Failed to stop FLL%d: %d\n",
i + 1, ret);
@@ -3590,10 +3587,8 @@ static int wm8994_suspend(struct platform_device *pdev, pm_message_t state)
return 0;
}
-static int wm8994_resume(struct platform_device *pdev)
+static int wm8994_resume(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec = socdev->card->codec;
struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
u16 *reg_cache = codec->reg_cache;
int i, ret;
@@ -3622,7 +3617,7 @@ static int wm8994_resume(struct platform_device *pdev)
if (!wm8994->fll_suspend[i].out)
continue;
- ret = wm8994_set_fll(&codec->dai[0], i + 1,
+ ret = _wm8994_set_fll(codec, i + 1,
wm8994->fll_suspend[i].src,
wm8994->fll_suspend[i].in,
wm8994->fll_suspend[i].out);
@@ -3640,7 +3635,7 @@ static int wm8994_resume(struct platform_device *pdev)
static void wm8994_handle_retune_mobile_pdata(struct wm8994_priv *wm8994)
{
- struct snd_soc_codec *codec = &wm8994->codec;
+ struct snd_soc_codec *codec = wm8994->codec;
struct wm8994_pdata *pdata = wm8994->pdata;
struct snd_kcontrol_new controls[] = {
SOC_ENUM_EXT("AIF1.1 EQ Mode",
@@ -3698,16 +3693,16 @@ static void wm8994_handle_retune_mobile_pdata(struct wm8994_priv *wm8994)
wm8994->retune_mobile_enum.max = wm8994->num_retune_mobile_texts;
wm8994->retune_mobile_enum.texts = wm8994->retune_mobile_texts;
- ret = snd_soc_add_controls(&wm8994->codec, controls,
+ ret = snd_soc_add_controls(wm8994->codec, controls,
ARRAY_SIZE(controls));
if (ret != 0)
- dev_err(wm8994->codec.dev,
+ dev_err(wm8994->codec->dev,
"Failed to add ReTune Mobile controls: %d\n", ret);
}
static void wm8994_handle_pdata(struct wm8994_priv *wm8994)
{
- struct snd_soc_codec *codec = &wm8994->codec;
+ struct snd_soc_codec *codec = wm8994->codec;
struct wm8994_pdata *pdata = wm8994->pdata;
int ret, i;
@@ -3739,7 +3734,7 @@ static void wm8994_handle_pdata(struct wm8994_priv *wm8994)
wm8994->drc_texts = kmalloc(sizeof(char *)
* pdata->num_drc_cfgs, GFP_KERNEL);
if (!wm8994->drc_texts) {
- dev_err(wm8994->codec.dev,
+ dev_err(wm8994->codec->dev,
"Failed to allocate %d DRC config texts\n",
pdata->num_drc_cfgs);
return;
@@ -3751,10 +3746,10 @@ static void wm8994_handle_pdata(struct wm8994_priv *wm8994)
wm8994->drc_enum.max = pdata->num_drc_cfgs;
wm8994->drc_enum.texts = wm8994->drc_texts;
- ret = snd_soc_add_controls(&wm8994->codec, controls,
+ ret = snd_soc_add_controls(wm8994->codec, controls,
ARRAY_SIZE(controls));
if (ret != 0)
- dev_err(wm8994->codec.dev,
+ dev_err(wm8994->codec->dev,
"Failed to add DRC mode controls: %d\n", ret);
for (i = 0; i < WM8994_NUM_DRC; i++)
@@ -3767,62 +3762,10 @@ static void wm8994_handle_pdata(struct wm8994_priv *wm8994)
if (pdata->num_retune_mobile_cfgs)
wm8994_handle_retune_mobile_pdata(wm8994);
else
- snd_soc_add_controls(&wm8994->codec, wm8994_eq_controls,
+ snd_soc_add_controls(wm8994->codec, wm8994_eq_controls,
ARRAY_SIZE(wm8994_eq_controls));
}
-static int wm8994_probe(struct platform_device *pdev)
-{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec;
- int ret = 0;
-
- if (wm8994_codec == NULL) {
- dev_err(&pdev->dev, "Codec device not registered\n");
- return -ENODEV;
- }
-
- socdev->card->codec = wm8994_codec;
- codec = wm8994_codec;
-
- /* register pcms */
- ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
- if (ret < 0) {
- dev_err(codec->dev, "failed to create pcms: %d\n", ret);
- return ret;
- }
-
- wm8994_handle_pdata(snd_soc_codec_get_drvdata(codec));
-
- wm_hubs_add_analogue_controls(codec);
- snd_soc_add_controls(codec, wm8994_snd_controls,
- ARRAY_SIZE(wm8994_snd_controls));
- snd_soc_dapm_new_controls(codec, wm8994_dapm_widgets,
- ARRAY_SIZE(wm8994_dapm_widgets));
- wm_hubs_add_analogue_routes(codec, 0, 0);
- snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
-
- return 0;
-}
-
-static int wm8994_remove(struct platform_device *pdev)
-{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
-
- snd_soc_free_pcms(socdev);
- snd_soc_dapm_free(socdev);
-
- return 0;
-}
-
-struct snd_soc_codec_device soc_codec_dev_wm8994 = {
- .probe = wm8994_probe,
- .remove = wm8994_remove,
- .suspend = wm8994_suspend,
- .resume = wm8994_resume,
-};
-EXPORT_SYMBOL_GPL(soc_codec_dev_wm8994);
-
/**
* wm8994_mic_detect - Enable microphone detection via the WM8994 IRQ
*
@@ -3881,7 +3824,7 @@ EXPORT_SYMBOL_GPL(wm8994_mic_detect);
static irqreturn_t wm8994_mic_irq(int irq, void *data)
{
struct wm8994_priv *priv = data;
- struct snd_soc_codec *codec = &priv->codec;
+ struct snd_soc_codec *codec = priv->codec;
int reg;
int report;
@@ -3913,47 +3856,20 @@ static irqreturn_t wm8994_mic_irq(int irq, void *data)
return IRQ_HANDLED;
}
-static int wm8994_codec_probe(struct platform_device *pdev)
+static int wm8994_codec_probe(struct snd_soc_codec *codec)
{
- int ret;
struct wm8994_priv *wm8994;
- struct snd_soc_codec *codec;
- int i;
- u16 rev;
+ int ret, i, rev;
- if (wm8994_codec) {
- dev_err(&pdev->dev, "Another WM8994 is registered\n");
- return -EINVAL;
- }
+ codec->control_data = dev_get_drvdata(codec->dev->parent);
wm8994 = kzalloc(sizeof(struct wm8994_priv), GFP_KERNEL);
- if (!wm8994) {
- dev_err(&pdev->dev, "Failed to allocate private data\n");
+ if (wm8994 == NULL)
return -ENOMEM;
- }
-
- codec = &wm8994->codec;
-
- mutex_init(&codec->mutex);
- INIT_LIST_HEAD(&codec->dapm_widgets);
- INIT_LIST_HEAD(&codec->dapm_paths);
-
snd_soc_codec_set_drvdata(codec, wm8994);
- codec->control_data = dev_get_drvdata(pdev->dev.parent);
- codec->name = "WM8994";
- codec->owner = THIS_MODULE;
- codec->read = wm8994_read;
- codec->write = wm8994_write;
- codec->readable_register = wm8994_readable;
- codec->bias_level = SND_SOC_BIAS_OFF;
- codec->set_bias_level = wm8994_set_bias_level;
- codec->dai = &wm8994_dai[0];
- codec->num_dai = 3;
- codec->reg_cache_size = WM8994_MAX_REGISTER;
- codec->reg_cache = &wm8994->reg_cache;
- codec->dev = &pdev->dev;
-
- wm8994->pdata = pdev->dev.parent->platform_data;
+
+ wm8994->pdata = dev_get_platdata(codec->dev->parent);
+ wm8994->codec = codec;
/* Fill the cache with physical values we inherited; don't reset */
ret = wm8994_bulk_read(codec->control_data, 0,
@@ -3989,25 +3905,25 @@ static int wm8994_codec_probe(struct platform_device *pdev)
ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_MIC1_DET,
wm8994_mic_irq, "Mic 1 detect", wm8994);
if (ret != 0)
- dev_warn(&pdev->dev,
+ dev_warn(codec->dev,
"Failed to request Mic1 detect IRQ: %d\n", ret);
ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_MIC1_SHRT,
wm8994_mic_irq, "Mic 1 short", wm8994);
if (ret != 0)
- dev_warn(&pdev->dev,
+ dev_warn(codec->dev,
"Failed to request Mic1 short IRQ: %d\n", ret);
ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_MIC2_DET,
wm8994_mic_irq, "Mic 2 detect", wm8994);
if (ret != 0)
- dev_warn(&pdev->dev,
+ dev_warn(codec->dev,
"Failed to request Mic2 detect IRQ: %d\n", ret);
ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_MIC2_SHRT,
wm8994_mic_irq, "Mic 2 short", wm8994);
if (ret != 0)
- dev_warn(&pdev->dev,
+ dev_warn(codec->dev,
"Failed to request Mic2 short IRQ: %d\n", ret);
/* Remember if AIFnLRCLK is configured as a GPIO. This should be
@@ -4038,13 +3954,8 @@ static int wm8994_codec_probe(struct platform_device *pdev)
wm8994->lrclk_shared[1] = 0;
}
- for (i = 0; i < ARRAY_SIZE(wm8994_dai); i++)
- wm8994_dai[i].dev = codec->dev;
-
wm8994_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
- wm8994_codec = codec;
-
/* Latch volume updates (right only; we always do left then right). */
snd_soc_update_bits(codec, WM8994_AIF1_DAC1_RIGHT_VOLUME,
WM8994_AIF1DAC1_VU, WM8994_AIF1DAC1_VU);
@@ -4081,24 +3992,18 @@ static int wm8994_codec_probe(struct platform_device *pdev)
wm8994_update_class_w(codec);
- ret = snd_soc_register_codec(codec);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to register codec: %d\n", ret);
- goto err_irq;
- }
-
- ret = snd_soc_register_dais(wm8994_dai, ARRAY_SIZE(wm8994_dai));
- if (ret != 0) {
- dev_err(codec->dev, "Failed to register DAIs: %d\n", ret);
- goto err_codec;
- }
+ wm8994_handle_pdata(wm8994);
- platform_set_drvdata(pdev, wm8994);
+ wm_hubs_add_analogue_controls(codec);
+ snd_soc_add_controls(codec, wm8994_snd_controls,
+ ARRAY_SIZE(wm8994_snd_controls));
+ snd_soc_dapm_new_controls(codec, wm8994_dapm_widgets,
+ ARRAY_SIZE(wm8994_dapm_widgets));
+ wm_hubs_add_analogue_routes(codec, 0, 0);
+ snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
return 0;
-err_codec:
- snd_soc_unregister_codec(codec);
err_irq:
wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_SHRT, wm8994);
wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_DET, wm8994);
@@ -4109,31 +4014,50 @@ err:
return ret;
}
-static int __devexit wm8994_codec_remove(struct platform_device *pdev)
+static int wm8994_codec_remove(struct snd_soc_codec *codec)
{
- struct wm8994_priv *wm8994 = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec = &wm8994->codec;
+ struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
wm8994_set_bias_level(codec, SND_SOC_BIAS_OFF);
- snd_soc_unregister_dais(wm8994_dai, ARRAY_SIZE(wm8994_dai));
- snd_soc_unregister_codec(&wm8994->codec);
+
wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_SHRT, wm8994);
wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_DET, wm8994);
wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_SHRT, wm8994);
wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_DET, wm8994);
kfree(wm8994);
- wm8994_codec = NULL;
return 0;
}
+static struct snd_soc_codec_driver soc_codec_dev_wm8994 = {
+ .probe = wm8994_codec_probe,
+ .remove = wm8994_codec_remove,
+ .suspend = wm8994_suspend,
+ .resume = wm8994_resume,
+ .read = wm8994_read,
+ .write = wm8994_write,
+ .set_bias_level = wm8994_set_bias_level,
+};
+
+static int __devinit wm8994_probe(struct platform_device *pdev)
+{
+ return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wm8994,
+ wm8994_dai, ARRAY_SIZE(wm8994_dai));
+}
+
+static int __devexit wm8994_remove(struct platform_device *pdev)
+{
+ snd_soc_unregister_codec(&pdev->dev);
+ return 0;
+}
+
static struct platform_driver wm8994_codec_driver = {
.driver = {
.name = "wm8994-codec",
.owner = THIS_MODULE,
},
- .probe = wm8994_codec_probe,
- .remove = __devexit_p(wm8994_codec_remove),
+ .probe = wm8994_probe,
+ .remove = __devexit_p(wm8994_remove),
};
static __init int wm8994_init(void)
diff --git a/sound/soc/codecs/wm8994.h b/sound/soc/codecs/wm8994.h
index 2e0ca67a8df7..d8dce260c430 100644
--- a/sound/soc/codecs/wm8994.h
+++ b/sound/soc/codecs/wm8994.h
@@ -11,9 +11,6 @@
#include <sound/soc.h>
-extern struct snd_soc_codec_device soc_codec_dev_wm8994;
-extern struct snd_soc_dai wm8994_dai[];
-
/* Sources for AIF1/2 SYSCLK - use with set_dai_sysclk() */
#define WM8994_SYSCLK_MCLK1 1
#define WM8994_SYSCLK_MCLK2 2
diff --git a/sound/soc/codecs/wm9081.c b/sound/soc/codecs/wm9081.c
index 76b37ff6c264..00249d5b6793 100644
--- a/sound/soc/codecs/wm9081.c
+++ b/sound/soc/codecs/wm9081.c
@@ -156,7 +156,8 @@ static struct {
};
struct wm9081_priv {
- struct snd_soc_codec codec;
+ enum snd_soc_control_type control_type;
+ void *control_data;
u16 reg_cache[WM9081_MAX_REGISTER + 1];
int sysclk_source;
int mclk_rate;
@@ -1212,8 +1213,8 @@ static struct snd_soc_dai_ops wm9081_dai_ops = {
/* We report two channels because the CODEC processes a stereo signal, even
* though it is only capable of handling a mono output.
*/
-struct snd_soc_dai wm9081_dai = {
- .name = "WM9081",
+static struct snd_soc_dai_driver wm9081_dai = {
+ .name = "wm9081-hifi",
.playback = {
.stream_name = "HiFi Playback",
.channels_min = 1,
@@ -1223,34 +1224,42 @@ struct snd_soc_dai wm9081_dai = {
},
.ops = &wm9081_dai_ops,
};
-EXPORT_SYMBOL_GPL(wm9081_dai);
-
-static struct snd_soc_codec *wm9081_codec;
-
-static int wm9081_probe(struct platform_device *pdev)
+static int wm9081_probe(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec;
- struct wm9081_priv *wm9081;
- int ret = 0;
+ struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec);
+ int ret;
+ u16 reg;
- if (wm9081_codec == NULL) {
- dev_err(&pdev->dev, "Codec device not registered\n");
- return -ENODEV;
+ codec->control_data = wm9081->control_data;
+ ret = snd_soc_codec_set_cache_io(codec, 8, 16, wm9081->control_type);
+ if (ret != 0) {
+ dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
+ return ret;
}
- socdev->card->codec = wm9081_codec;
- codec = wm9081_codec;
- wm9081 = snd_soc_codec_get_drvdata(codec);
+ reg = snd_soc_read(codec, WM9081_SOFTWARE_RESET);
+ if (reg != 0x9081) {
+ dev_err(codec->dev, "Device is not a WM9081: ID=0x%x\n", reg);
+ ret = -EINVAL;
+ return ret;
+ }
- /* register pcms */
- ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
+ ret = wm9081_reset(codec);
if (ret < 0) {
- dev_err(codec->dev, "failed to create pcms: %d\n", ret);
- goto pcm_err;
+ dev_err(codec->dev, "Failed to issue reset\n");
+ return ret;
}
+ wm9081_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+
+ /* Enable zero cross by default */
+ reg = snd_soc_read(codec, WM9081_ANALOGUE_LINEOUT);
+ snd_soc_write(codec, WM9081_ANALOGUE_LINEOUT, reg | WM9081_LINEOUTZC);
+ reg = snd_soc_read(codec, WM9081_ANALOGUE_SPEAKER_PGA);
+ snd_soc_write(codec, WM9081_ANALOGUE_SPEAKER_PGA,
+ reg | WM9081_SPKPGAZC);
+
snd_soc_add_controls(codec, wm9081_snd_controls,
ARRAY_SIZE(wm9081_snd_controls));
if (!wm9081->retune) {
@@ -1265,40 +1274,28 @@ static int wm9081_probe(struct platform_device *pdev)
snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths));
return ret;
-
-pcm_err:
- return ret;
}
-static int wm9081_remove(struct platform_device *pdev)
+static int wm9081_remove(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
-
- snd_soc_free_pcms(socdev);
- snd_soc_dapm_free(socdev);
-
+ wm9081_set_bias_level(codec, SND_SOC_BIAS_OFF);
return 0;
}
#ifdef CONFIG_PM
-static int wm9081_suspend(struct platform_device *pdev, pm_message_t state)
+static int wm9081_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;
-
wm9081_set_bias_level(codec, SND_SOC_BIAS_OFF);
return 0;
}
-static int wm9081_resume(struct platform_device *pdev)
+static int wm9081_resume(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec = socdev->card->codec;
u16 *reg_cache = codec->reg_cache;
int i;
- for (i = 0; i < codec->reg_cache_size; i++) {
+ for (i = 0; i < codec->driver->reg_cache_size; i++) {
if (i == WM9081_SOFTWARE_RESET)
continue;
@@ -1314,133 +1311,43 @@ static int wm9081_resume(struct platform_device *pdev)
#define wm9081_resume NULL
#endif
-struct snd_soc_codec_device soc_codec_dev_wm9081 = {
+static struct snd_soc_codec_driver soc_codec_dev_wm9081 = {
.probe = wm9081_probe,
.remove = wm9081_remove,
.suspend = wm9081_suspend,
.resume = wm9081_resume,
+ .set_bias_level = wm9081_set_bias_level,
+ .reg_cache_size = sizeof(wm9081_reg_defaults),
+ .reg_word_size = sizeof(u16),
+ .reg_cache_default = wm9081_reg_defaults,
+ .volatile_register = wm9081_volatile_register,
};
-EXPORT_SYMBOL_GPL(soc_codec_dev_wm9081);
-
-static int wm9081_register(struct wm9081_priv *wm9081,
- enum snd_soc_control_type control)
-{
- struct snd_soc_codec *codec = &wm9081->codec;
- int ret;
- u16 reg;
-
- if (wm9081_codec) {
- dev_err(codec->dev, "Another WM9081 is registered\n");
- ret = -EINVAL;
- goto err;
- }
-
- mutex_init(&codec->mutex);
- INIT_LIST_HEAD(&codec->dapm_widgets);
- INIT_LIST_HEAD(&codec->dapm_paths);
-
- snd_soc_codec_set_drvdata(codec, wm9081);
- codec->name = "WM9081";
- codec->owner = THIS_MODULE;
- codec->dai = &wm9081_dai;
- codec->num_dai = 1;
- codec->reg_cache_size = ARRAY_SIZE(wm9081->reg_cache);
- codec->reg_cache = &wm9081->reg_cache;
- codec->bias_level = SND_SOC_BIAS_OFF;
- codec->set_bias_level = wm9081_set_bias_level;
- codec->volatile_register = wm9081_volatile_register;
-
- memcpy(codec->reg_cache, wm9081_reg_defaults,
- sizeof(wm9081_reg_defaults));
-
- ret = snd_soc_codec_set_cache_io(codec, 8, 16, control);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- goto err;
- }
-
- reg = snd_soc_read(codec, WM9081_SOFTWARE_RESET);
- if (reg != 0x9081) {
- dev_err(codec->dev, "Device is not a WM9081: ID=0x%x\n", reg);
- ret = -EINVAL;
- goto err;
- }
-
- ret = wm9081_reset(codec);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to issue reset\n");
- goto err;
- }
-
- wm9081_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
- /* Enable zero cross by default */
- reg = snd_soc_read(codec, WM9081_ANALOGUE_LINEOUT);
- snd_soc_write(codec, WM9081_ANALOGUE_LINEOUT, reg | WM9081_LINEOUTZC);
- reg = snd_soc_read(codec, WM9081_ANALOGUE_SPEAKER_PGA);
- snd_soc_write(codec, WM9081_ANALOGUE_SPEAKER_PGA,
- reg | WM9081_SPKPGAZC);
-
- wm9081_dai.dev = codec->dev;
-
- wm9081_codec = codec;
-
- ret = snd_soc_register_codec(codec);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to register codec: %d\n", ret);
- goto err;
- }
-
- ret = snd_soc_register_dai(&wm9081_dai);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
- goto err_codec;
- }
-
- return 0;
-
-err_codec:
- snd_soc_unregister_codec(codec);
-err:
- kfree(wm9081);
- return ret;
-}
-
-static void wm9081_unregister(struct wm9081_priv *wm9081)
-{
- wm9081_set_bias_level(&wm9081->codec, SND_SOC_BIAS_OFF);
- snd_soc_unregister_dai(&wm9081_dai);
- snd_soc_unregister_codec(&wm9081->codec);
- kfree(wm9081);
- wm9081_codec = NULL;
-}
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
static __devinit int wm9081_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
struct wm9081_priv *wm9081;
- struct snd_soc_codec *codec;
+ int ret;
wm9081 = kzalloc(sizeof(struct wm9081_priv), GFP_KERNEL);
if (wm9081 == NULL)
return -ENOMEM;
- codec = &wm9081->codec;
- codec->hw_write = (hw_write_t)i2c_master_send;
- wm9081->retune = i2c->dev.platform_data;
-
i2c_set_clientdata(i2c, wm9081);
- codec->control_data = i2c;
-
- codec->dev = &i2c->dev;
+ wm9081->control_data = i2c;
- return wm9081_register(wm9081, SND_SOC_I2C);
+ ret = snd_soc_register_codec(&i2c->dev,
+ &soc_codec_dev_wm9081, &wm9081_dai, 1);
+ if (ret < 0)
+ kfree(wm9081);
+ return ret;
}
static __devexit int wm9081_i2c_remove(struct i2c_client *client)
{
- struct wm9081_priv *wm9081 = i2c_get_clientdata(client);
- wm9081_unregister(wm9081);
+ snd_soc_unregister_codec(&client->dev);
+ kfree(i2c_get_clientdata(client));
return 0;
}
@@ -1452,31 +1359,34 @@ MODULE_DEVICE_TABLE(i2c, wm9081_i2c_id);
static struct i2c_driver wm9081_i2c_driver = {
.driver = {
- .name = "wm9081",
+ .name = "wm9081-codec",
.owner = THIS_MODULE,
},
.probe = wm9081_i2c_probe,
.remove = __devexit_p(wm9081_i2c_remove),
.id_table = wm9081_i2c_id,
};
+#endif
static int __init wm9081_modinit(void)
{
- int ret;
-
+ int ret = 0;
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
ret = i2c_add_driver(&wm9081_i2c_driver);
if (ret != 0) {
printk(KERN_ERR "Failed to register WM9081 I2C driver: %d\n",
ret);
}
-
+#endif
return ret;
}
module_init(wm9081_modinit);
static void __exit wm9081_exit(void)
{
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
i2c_del_driver(&wm9081_i2c_driver);
+#endif
}
module_exit(wm9081_exit);
diff --git a/sound/soc/codecs/wm9081.h b/sound/soc/codecs/wm9081.h
index 42d3bc757021..871cccb066dc 100644
--- a/sound/soc/codecs/wm9081.h
+++ b/sound/soc/codecs/wm9081.h
@@ -15,9 +15,6 @@
#include <sound/soc.h>
-extern struct snd_soc_dai wm9081_dai;
-extern struct snd_soc_codec_device soc_codec_dev_wm9081;
-
/*
* SYSCLK sources
*/
diff --git a/sound/soc/codecs/wm9090.c b/sound/soc/codecs/wm9090.c
index 1592250daec0..7a1825418ee4 100644
--- a/sound/soc/codecs/wm9090.c
+++ b/sound/soc/codecs/wm9090.c
@@ -34,8 +34,6 @@
#include "wm9090.h"
-static struct snd_soc_codec *wm9090_codec;
-
static const u16 wm9090_reg_defaults[] = {
0x9093, /* R0 - Software Reset */
0x0006, /* R1 - Power Management (1) */
@@ -142,15 +140,10 @@ static const u16 wm9090_reg_defaults[] = {
/* This struct is used to save the context */
struct wm9090_priv {
- /* We're not really registering as a CODEC since ASoC core
- * does not yet support multiple CODECs but having the CODEC
- * structure means we can reuse some of the ASoC core
- * features.
- */
- struct snd_soc_codec codec;
struct mutex mutex;
u16 reg_cache[WM9090_MAX_REGISTER + 1];
struct wm9090_platform_data pdata;
+ void *control_data;
};
static int wm9090_volatile(unsigned int reg)
@@ -523,7 +516,7 @@ static int wm9090_set_bias_level(struct snd_soc_codec *codec,
case SND_SOC_BIAS_STANDBY:
if (codec->bias_level == SND_SOC_BIAS_OFF) {
/* Restore the register cache */
- for (i = 1; i < codec->reg_cache_size; i++) {
+ for (i = 1; i < codec->driver->reg_cache_size; i++) {
if (reg_cache[i] == wm9090_reg_defaults[i])
continue;
if (wm9090_volatile(i))
@@ -556,51 +549,67 @@ static int wm9090_set_bias_level(struct snd_soc_codec *codec,
return 0;
}
-static int wm9090_probe(struct platform_device *pdev)
+static int wm9090_probe(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec;
- int ret = 0;
+ struct wm9090_priv *wm9090 = snd_soc_codec_get_drvdata(codec);
+ int ret;
- if (wm9090_codec == NULL) {
- dev_err(&pdev->dev, "Codec device not registered\n");
- return -ENODEV;
+ codec->control_data = wm9090->control_data;
+ ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
+ if (ret != 0) {
+ dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
+ return ret;
}
- socdev->card->codec = wm9090_codec;
- codec = wm9090_codec;
-
- /* register pcms */
- ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
- if (ret < 0) {
- dev_err(codec->dev, "failed to create pcms: %d\n", ret);
- goto pcm_err;
+ ret = snd_soc_read(codec, WM9090_SOFTWARE_RESET);
+ if (ret < 0)
+ return ret;
+ if (ret != wm9090_reg_defaults[WM9090_SOFTWARE_RESET]) {
+ dev_err(codec->dev, "Device is not a WM9090, ID=%x\n", ret);
+ return -EINVAL;
}
+ ret = snd_soc_write(codec, WM9090_SOFTWARE_RESET, 0);
+ if (ret < 0)
+ return ret;
+
+ /* Configure some defaults; they will be written out when we
+ * bring the bias up.
+ */
+ wm9090->reg_cache[WM9090_IN1_LINE_INPUT_A_VOLUME] |= WM9090_IN1_VU
+ | WM9090_IN1A_ZC;
+ wm9090->reg_cache[WM9090_IN1_LINE_INPUT_B_VOLUME] |= WM9090_IN1_VU
+ | WM9090_IN1B_ZC;
+ wm9090->reg_cache[WM9090_IN2_LINE_INPUT_A_VOLUME] |= WM9090_IN2_VU
+ | WM9090_IN2A_ZC;
+ wm9090->reg_cache[WM9090_IN2_LINE_INPUT_B_VOLUME] |= WM9090_IN2_VU
+ | WM9090_IN2B_ZC;
+ wm9090->reg_cache[WM9090_SPEAKER_VOLUME_LEFT] |=
+ WM9090_SPKOUT_VU | WM9090_SPKOUTL_ZC;
+ wm9090->reg_cache[WM9090_LEFT_OUTPUT_VOLUME] |=
+ WM9090_HPOUT1_VU | WM9090_HPOUT1L_ZC;
+ wm9090->reg_cache[WM9090_RIGHT_OUTPUT_VOLUME] |=
+ WM9090_HPOUT1_VU | WM9090_HPOUT1R_ZC;
+
+ wm9090->reg_cache[WM9090_CLOCKING_1] |= WM9090_TOCLK_ENA;
+
+ wm9090_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+
wm9090_add_controls(codec);
return 0;
-
-pcm_err:
- return ret;
}
#ifdef CONFIG_PM
-static int wm9090_suspend(struct platform_device *pdev, pm_message_t state)
+static int wm9090_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;
-
wm9090_set_bias_level(codec, SND_SOC_BIAS_OFF);
return 0;
}
-static int wm9090_resume(struct platform_device *pdev)
+static int wm9090_resume(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec = socdev->card->codec;
-
wm9090_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
return 0;
@@ -610,29 +619,29 @@ static int wm9090_resume(struct platform_device *pdev)
#define wm9090_resume NULL
#endif
-static int wm9090_remove(struct platform_device *pdev)
+static int wm9090_remove(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
-
- snd_soc_free_pcms(socdev);
- snd_soc_dapm_free(socdev);
+ wm9090_set_bias_level(codec, SND_SOC_BIAS_OFF);
return 0;
}
-struct snd_soc_codec_device soc_codec_dev_wm9090 = {
+static struct snd_soc_codec_driver soc_codec_dev_wm9090 = {
.probe = wm9090_probe,
.remove = wm9090_remove,
.suspend = wm9090_suspend,
.resume = wm9090_resume,
+ .set_bias_level = wm9090_set_bias_level,
+ .reg_cache_size = (WM9090_MAX_REGISTER + 1),
+ .reg_word_size = sizeof(u16),
+ .reg_cache_default = wm9090_reg_defaults,
+ .volatile_register = wm9090_volatile,
};
-EXPORT_SYMBOL_GPL(soc_codec_dev_wm9090);
static int wm9090_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
struct wm9090_priv *wm9090;
- struct snd_soc_codec *codec;
int ret;
wm9090 = kzalloc(sizeof(*wm9090), GFP_KERNEL);
@@ -640,102 +649,28 @@ static int wm9090_i2c_probe(struct i2c_client *i2c,
dev_err(&i2c->dev, "Can not allocate memory\n");
return -ENOMEM;
}
- codec = &wm9090->codec;
if (i2c->dev.platform_data)
memcpy(&wm9090->pdata, i2c->dev.platform_data,
sizeof(wm9090->pdata));
- wm9090_codec = codec;
-
i2c_set_clientdata(i2c, wm9090);
+ wm9090->control_data = i2c;
+ mutex_init(&wm9090->mutex);
- mutex_init(&codec->mutex);
- INIT_LIST_HEAD(&codec->dapm_widgets);
- INIT_LIST_HEAD(&codec->dapm_paths);
-
- codec->control_data = i2c;
- snd_soc_codec_set_drvdata(codec, wm9090);
- codec->dev = &i2c->dev;
- codec->name = "WM9090";
- codec->owner = THIS_MODULE;
- codec->bias_level = SND_SOC_BIAS_OFF;
- codec->set_bias_level = wm9090_set_bias_level,
- codec->reg_cache_size = WM9090_MAX_REGISTER + 1;
- codec->reg_cache = &wm9090->reg_cache;
- codec->volatile_register = wm9090_volatile;
-
- ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
- if (ret != 0) {
- dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
- goto err;
- }
-
- memcpy(&wm9090->reg_cache, wm9090_reg_defaults,
- sizeof(wm9090->reg_cache));
-
- ret = snd_soc_read(codec, WM9090_SOFTWARE_RESET);
- if (ret < 0)
- goto err;
- if (ret != wm9090_reg_defaults[WM9090_SOFTWARE_RESET]) {
- dev_err(&i2c->dev, "Device is not a WM9090, ID=%x\n", ret);
- ret = -EINVAL;
- goto err;
- }
-
- ret = snd_soc_write(codec, WM9090_SOFTWARE_RESET, 0);
+ ret = snd_soc_register_codec(&i2c->dev,
+ &soc_codec_dev_wm9090, NULL, 0);
if (ret < 0)
- goto err;
-
- /* Configure some defaults; they will be written out when we
- * bring the bias up.
- */
- wm9090->reg_cache[WM9090_IN1_LINE_INPUT_A_VOLUME] |= WM9090_IN1_VU
- | WM9090_IN1A_ZC;
- wm9090->reg_cache[WM9090_IN1_LINE_INPUT_B_VOLUME] |= WM9090_IN1_VU
- | WM9090_IN1B_ZC;
- wm9090->reg_cache[WM9090_IN2_LINE_INPUT_A_VOLUME] |= WM9090_IN2_VU
- | WM9090_IN2A_ZC;
- wm9090->reg_cache[WM9090_IN2_LINE_INPUT_B_VOLUME] |= WM9090_IN2_VU
- | WM9090_IN2B_ZC;
- wm9090->reg_cache[WM9090_SPEAKER_VOLUME_LEFT] |=
- WM9090_SPKOUT_VU | WM9090_SPKOUTL_ZC;
- wm9090->reg_cache[WM9090_LEFT_OUTPUT_VOLUME] |=
- WM9090_HPOUT1_VU | WM9090_HPOUT1L_ZC;
- wm9090->reg_cache[WM9090_RIGHT_OUTPUT_VOLUME] |=
- WM9090_HPOUT1_VU | WM9090_HPOUT1R_ZC;
-
- wm9090->reg_cache[WM9090_CLOCKING_1] |= WM9090_TOCLK_ENA;
-
- wm9090_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
- ret = snd_soc_register_codec(codec);
- if (ret != 0) {
- dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret);
- goto err_bias;
- }
-
- return 0;
-
-err_bias:
- wm9090_set_bias_level(codec, SND_SOC_BIAS_OFF);
-err:
- kfree(wm9090);
- i2c_set_clientdata(i2c, NULL);
- wm9090_codec = NULL;
-
+ kfree(wm9090);
return ret;
}
static int wm9090_i2c_remove(struct i2c_client *i2c)
{
struct wm9090_priv *wm9090 = i2c_get_clientdata(i2c);
- struct snd_soc_codec *codec = &wm9090->codec;
- snd_soc_unregister_codec(codec);
- wm9090_set_bias_level(codec, SND_SOC_BIAS_OFF);
+ snd_soc_unregister_codec(&i2c->dev);
kfree(wm9090);
- wm9090_codec = NULL;
return 0;
}
@@ -748,7 +683,7 @@ MODULE_DEVICE_TABLE(i2c, wm9090_id);
static struct i2c_driver wm9090_i2c_driver = {
.driver = {
- .name = "wm9090",
+ .name = "wm9090-codec",
.owner = THIS_MODULE,
},
.probe = wm9090_i2c_probe,
diff --git a/sound/soc/codecs/wm9090.h b/sound/soc/codecs/wm9090.h
index b08eab932a5b..29b9d9fc70b4 100644
--- a/sound/soc/codecs/wm9090.h
+++ b/sound/soc/codecs/wm9090.h
@@ -23,8 +23,6 @@
#ifndef __WM9090_H
#define __WM9090_H
-extern struct snd_soc_codec_device soc_codec_dev_wm9090;
-
/*
* Register values.
*/
diff --git a/sound/soc/codecs/wm9705.c b/sound/soc/codecs/wm9705.c
index 8793341849d1..e4d8f5339c51 100644
--- a/sound/soc/codecs/wm9705.c
+++ b/sound/soc/codecs/wm9705.c
@@ -248,8 +248,7 @@ static int ac97_prepare(struct snd_pcm_substream *substream,
{
struct snd_pcm_runtime *runtime = substream->runtime;
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;
int reg;
u16 vra;
@@ -273,9 +272,9 @@ static struct snd_soc_dai_ops wm9705_dai_ops = {
.prepare = ac97_prepare,
};
-struct snd_soc_dai wm9705_dai[] = {
+static struct snd_soc_dai_driver wm9705_dai[] = {
{
- .name = "AC97 HiFi",
+ .name = "wm9705-hifi",
.ac97_control = 1,
.playback = {
.stream_name = "HiFi Playback",
@@ -294,7 +293,7 @@ struct snd_soc_dai wm9705_dai[] = {
.ops = &wm9705_dai_ops,
},
{
- .name = "AC97 Aux",
+ .name = "wm9705-aux",
.playback = {
.stream_name = "Aux Playback",
.channels_min = 1,
@@ -304,7 +303,6 @@ struct snd_soc_dai wm9705_dai[] = {
},
}
};
-EXPORT_SYMBOL_GPL(wm9705_dai);
static int wm9705_reset(struct snd_soc_codec *codec)
{
@@ -318,20 +316,15 @@ static int wm9705_reset(struct snd_soc_codec *codec)
}
#ifdef CONFIG_PM
-static int wm9705_soc_suspend(struct platform_device *pdev, pm_message_t msg)
+static int wm9705_soc_suspend(struct snd_soc_codec *codec, pm_message_t msg)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec = socdev->card->codec;
-
soc_ac97_ops.write(codec->ac97, AC97_POWERDOWN, 0xffff);
return 0;
}
-static int wm9705_soc_resume(struct platform_device *pdev)
+static int wm9705_soc_resume(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec = socdev->card->codec;
int i, ret;
u16 *cache = codec->reg_cache;
@@ -352,49 +345,18 @@ static int wm9705_soc_resume(struct platform_device *pdev)
#define wm9705_soc_resume NULL
#endif
-static int wm9705_soc_probe(struct platform_device *pdev)
+static int wm9705_soc_probe(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec;
int ret = 0;
printk(KERN_INFO "WM9705 SoC Audio Codec\n");
- socdev->card->codec = kzalloc(sizeof(struct snd_soc_codec),
- GFP_KERNEL);
- if (socdev->card->codec == NULL)
- return -ENOMEM;
- codec = socdev->card->codec;
- mutex_init(&codec->mutex);
-
- codec->reg_cache = kmemdup(wm9705_reg, sizeof(wm9705_reg), GFP_KERNEL);
- if (codec->reg_cache == NULL) {
- ret = -ENOMEM;
- goto cache_err;
- }
- codec->reg_cache_size = sizeof(wm9705_reg);
- codec->reg_cache_step = 2;
-
- codec->name = "WM9705";
- codec->owner = THIS_MODULE;
- codec->dai = wm9705_dai;
- codec->num_dai = ARRAY_SIZE(wm9705_dai);
- codec->write = ac97_write;
- codec->read = ac97_read;
- INIT_LIST_HEAD(&codec->dapm_widgets);
- INIT_LIST_HEAD(&codec->dapm_paths);
-
ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0);
if (ret < 0) {
printk(KERN_ERR "wm9705: failed to register AC97 codec\n");
- goto codec_err;
+ return ret;
}
- /* register pcms */
- ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
- if (ret < 0)
- goto pcm_err;
-
ret = wm9705_reset(codec);
if (ret)
goto reset_err;
@@ -406,40 +368,62 @@ static int wm9705_soc_probe(struct platform_device *pdev)
return 0;
reset_err:
- snd_soc_free_pcms(socdev);
-pcm_err:
snd_soc_free_ac97_codec(codec);
-codec_err:
- kfree(codec->reg_cache);
-cache_err:
- kfree(socdev->card->codec);
- socdev->card->codec = NULL;
return ret;
}
-static int wm9705_soc_remove(struct platform_device *pdev)
+static int wm9705_soc_remove(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec = socdev->card->codec;
-
- if (codec == NULL)
- return 0;
-
- snd_soc_dapm_free(socdev);
- snd_soc_free_pcms(socdev);
snd_soc_free_ac97_codec(codec);
- kfree(codec->reg_cache);
- kfree(codec);
return 0;
}
-struct snd_soc_codec_device soc_codec_dev_wm9705 = {
+static struct snd_soc_codec_driver soc_codec_dev_wm9705 = {
.probe = wm9705_soc_probe,
.remove = wm9705_soc_remove,
.suspend = wm9705_soc_suspend,
.resume = wm9705_soc_resume,
+ .read = ac97_read,
+ .write = ac97_write,
+ .reg_cache_size = sizeof(wm9705_reg),
+ .reg_word_size = sizeof(u16),
+ .reg_cache_step = 2,
+ .reg_cache_default = wm9705_reg,
+};
+
+static __devinit int wm9705_probe(struct platform_device *pdev)
+{
+ return snd_soc_register_codec(&pdev->dev,
+ &soc_codec_dev_wm9705, wm9705_dai, ARRAY_SIZE(wm9705_dai));
+}
+
+static int __devexit wm9705_remove(struct platform_device *pdev)
+{
+ snd_soc_unregister_codec(&pdev->dev);
+ return 0;
+}
+
+static struct platform_driver wm9705_codec_driver = {
+ .driver = {
+ .name = "wm9705-codec",
+ .owner = THIS_MODULE,
+ },
+
+ .probe = wm9705_probe,
+ .remove = __devexit_p(wm9705_remove),
};
-EXPORT_SYMBOL_GPL(soc_codec_dev_wm9705);
+
+static int __init wm9705_init(void)
+{
+ return platform_driver_register(&wm9705_codec_driver);
+}
+module_init(wm9705_init);
+
+static void __exit wm9705_exit(void)
+{
+ platform_driver_unregister(&wm9705_codec_driver);
+}
+module_exit(wm9705_exit);
MODULE_DESCRIPTION("ASoC WM9705 driver");
MODULE_AUTHOR("Ian Molton");
diff --git a/sound/soc/codecs/wm9705.h b/sound/soc/codecs/wm9705.h
index d380f110f9e2..23ea9ce47359 100644
--- a/sound/soc/codecs/wm9705.h
+++ b/sound/soc/codecs/wm9705.h
@@ -8,7 +8,4 @@
#define WM9705_DAI_AC97_HIFI 0
#define WM9705_DAI_AC97_AUX 1
-extern struct snd_soc_dai wm9705_dai[2];
-extern struct snd_soc_codec_device soc_codec_dev_wm9705;
-
#endif
diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c
index 28790a2ffe8d..f8f37ae30910 100644
--- a/sound/soc/codecs/wm9712.c
+++ b/sound/soc/codecs/wm9712.c
@@ -478,8 +478,7 @@ static int ac97_prepare(struct snd_pcm_substream *substream,
{
struct snd_pcm_runtime *runtime = substream->runtime;
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;
int reg;
u16 vra;
@@ -499,8 +498,7 @@ static int ac97_aux_prepare(struct snd_pcm_substream *substream,
{
struct snd_pcm_runtime *runtime = substream->runtime;
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;
u16 vra, xsle;
vra = ac97_read(codec, AC97_EXTENDED_STATUS);
@@ -526,9 +524,9 @@ static struct snd_soc_dai_ops wm9712_dai_ops_aux = {
.prepare = ac97_aux_prepare,
};
-struct snd_soc_dai wm9712_dai[] = {
+struct snd_soc_dai_driver wm9712_dai[] = {
{
- .name = "AC97 HiFi",
+ .name = "wm9712-hifi",
.ac97_control = 1,
.playback = {
.stream_name = "HiFi Playback",
@@ -545,7 +543,7 @@ struct snd_soc_dai wm9712_dai[] = {
.ops = &wm9712_dai_ops_hifi,
},
{
- .name = "AC97 Aux",
+ .name = "wm9712-aux",
.playback = {
.stream_name = "Aux Playback",
.channels_min = 1,
@@ -555,7 +553,6 @@ struct snd_soc_dai wm9712_dai[] = {
.ops = &wm9712_dai_ops_aux,
}
};
-EXPORT_SYMBOL_GPL(wm9712_dai);
static int wm9712_set_bias_level(struct snd_soc_codec *codec,
enum snd_soc_bias_level level)
@@ -597,20 +594,15 @@ err:
return -EIO;
}
-static int wm9712_soc_suspend(struct platform_device *pdev,
+static int wm9712_soc_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;
-
wm9712_set_bias_level(codec, SND_SOC_BIAS_OFF);
return 0;
}
-static int wm9712_soc_resume(struct platform_device *pdev)
+static int wm9712_soc_resume(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec = socdev->card->codec;
int i, ret;
u16 *cache = codec->reg_cache;
@@ -635,51 +627,18 @@ static int wm9712_soc_resume(struct platform_device *pdev)
return ret;
}
-static int wm9712_soc_probe(struct platform_device *pdev)
+static int wm9712_soc_probe(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec;
int ret = 0;
printk(KERN_INFO "WM9711/WM9712 SoC Audio Codec %s\n", WM9712_VERSION);
- socdev->card->codec = kzalloc(sizeof(struct snd_soc_codec),
- GFP_KERNEL);
- if (socdev->card->codec == NULL)
- return -ENOMEM;
- codec = socdev->card->codec;
- mutex_init(&codec->mutex);
-
- codec->reg_cache = kmemdup(wm9712_reg, sizeof(wm9712_reg), GFP_KERNEL);
-
- if (codec->reg_cache == NULL) {
- ret = -ENOMEM;
- goto cache_err;
- }
- codec->reg_cache_size = sizeof(wm9712_reg);
- codec->reg_cache_step = 2;
-
- codec->name = "WM9712";
- codec->owner = THIS_MODULE;
- codec->dai = wm9712_dai;
- codec->num_dai = ARRAY_SIZE(wm9712_dai);
- codec->write = ac97_write;
- codec->read = ac97_read;
- codec->set_bias_level = wm9712_set_bias_level;
- INIT_LIST_HEAD(&codec->dapm_widgets);
- INIT_LIST_HEAD(&codec->dapm_paths);
-
ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0);
if (ret < 0) {
printk(KERN_ERR "wm9712: failed to register AC97 codec\n");
- goto codec_err;
+ return ret;
}
- /* register pcms */
- ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
- if (ret < 0)
- goto pcm_err;
-
ret = wm9712_reset(codec, 0);
if (ret < 0) {
printk(KERN_ERR "Failed to reset WM9712: AC97 link error\n");
@@ -697,42 +656,63 @@ static int wm9712_soc_probe(struct platform_device *pdev)
return 0;
reset_err:
- snd_soc_free_pcms(socdev);
-pcm_err:
snd_soc_free_ac97_codec(codec);
-
-codec_err:
- kfree(codec->reg_cache);
-
-cache_err:
- kfree(socdev->card->codec);
- socdev->card->codec = NULL;
return ret;
}
-static int wm9712_soc_remove(struct platform_device *pdev)
+static int wm9712_soc_remove(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec = socdev->card->codec;
-
- if (codec == NULL)
- return 0;
-
- snd_soc_dapm_free(socdev);
- snd_soc_free_pcms(socdev);
snd_soc_free_ac97_codec(codec);
- kfree(codec->reg_cache);
- kfree(codec);
return 0;
}
-struct snd_soc_codec_device soc_codec_dev_wm9712 = {
+static struct snd_soc_codec_driver soc_codec_dev_wm9712 = {
.probe = wm9712_soc_probe,
.remove = wm9712_soc_remove,
.suspend = wm9712_soc_suspend,
.resume = wm9712_soc_resume,
+ .read = ac97_read,
+ .write = ac97_write,
+ .set_bias_level = wm9712_set_bias_level,
+ .reg_cache_size = sizeof(wm9712_reg),
+ .reg_word_size = sizeof(u16),
+ .reg_cache_step = 2,
+ .reg_cache_default = wm9712_reg,
};
-EXPORT_SYMBOL_GPL(soc_codec_dev_wm9712);
+
+static __devinit int wm9712_probe(struct platform_device *pdev)
+{
+ return snd_soc_register_codec(&pdev->dev,
+ &soc_codec_dev_wm9712, wm9712_dai, ARRAY_SIZE(wm9712_dai));
+}
+
+static int __devexit wm9712_remove(struct platform_device *pdev)
+{
+ snd_soc_unregister_codec(&pdev->dev);
+ return 0;
+}
+
+static struct platform_driver wm9712_codec_driver = {
+ .driver = {
+ .name = "wm9712-codec",
+ .owner = THIS_MODULE,
+ },
+
+ .probe = wm9712_probe,
+ .remove = __devexit_p(wm9712_remove),
+};
+
+static int __init wm9712_init(void)
+{
+ return platform_driver_register(&wm9712_codec_driver);
+}
+module_init(wm9712_init);
+
+static void __exit wm9712_exit(void)
+{
+ platform_driver_unregister(&wm9712_codec_driver);
+}
+module_exit(wm9712_exit);
MODULE_DESCRIPTION("ASoC WM9711/WM9712 driver");
MODULE_AUTHOR("Liam Girdwood");
diff --git a/sound/soc/codecs/wm9712.h b/sound/soc/codecs/wm9712.h
index d29e8a18ca6d..fb69c3aa4ed0 100644
--- a/sound/soc/codecs/wm9712.h
+++ b/sound/soc/codecs/wm9712.h
@@ -8,7 +8,4 @@
#define WM9712_DAI_AC97_HIFI 0
#define WM9712_DAI_AC97_AUX 1
-extern struct snd_soc_dai wm9712_dai[2];
-extern struct snd_soc_codec_device soc_codec_dev_wm9712;
-
#endif
diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c
index 34e0c91092fa..463917e762b5 100644
--- a/sound/soc/codecs/wm9713.c
+++ b/sound/soc/codecs/wm9713.c
@@ -1057,9 +1057,9 @@ static struct snd_soc_dai_ops wm9713_dai_ops_voice = {
.set_tristate = wm9713_set_dai_tristate,
};
-struct snd_soc_dai wm9713_dai[] = {
+static struct snd_soc_dai_driver wm9713_dai[] = {
{
- .name = "AC97 HiFi",
+ .name = "wm9713-hifi",
.ac97_control = 1,
.playback = {
.stream_name = "HiFi Playback",
@@ -1076,7 +1076,7 @@ struct snd_soc_dai wm9713_dai[] = {
.ops = &wm9713_dai_ops_hifi,
},
{
- .name = "AC97 Aux",
+ .name = "wm9713-aux",
.playback = {
.stream_name = "Aux Playback",
.channels_min = 1,
@@ -1086,7 +1086,7 @@ struct snd_soc_dai wm9713_dai[] = {
.ops = &wm9713_dai_ops_aux,
},
{
- .name = "WM9713 Voice",
+ .name = "wm9713-voice",
.playback = {
.stream_name = "Voice Playback",
.channels_min = 1,
@@ -1103,7 +1103,6 @@ struct snd_soc_dai wm9713_dai[] = {
.symmetric_rates = 1,
},
};
-EXPORT_SYMBOL_GPL(wm9713_dai);
int wm9713_reset(struct snd_soc_codec *codec, int try_warm)
{
@@ -1152,11 +1151,9 @@ static int wm9713_set_bias_level(struct snd_soc_codec *codec,
return 0;
}
-static int wm9713_soc_suspend(struct platform_device *pdev,
+static int wm9713_soc_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;
u16 reg;
/* Disable everything except touchpanel - that will be handled
@@ -1171,10 +1168,8 @@ static int wm9713_soc_suspend(struct platform_device *pdev,
return 0;
}
-static int wm9713_soc_resume(struct platform_device *pdev)
+static int wm9713_soc_resume(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec = socdev->card->codec;
struct wm9713_priv *wm9713 = snd_soc_codec_get_drvdata(codec);
int i, ret;
u16 *cache = codec->reg_cache;
@@ -1204,53 +1199,20 @@ static int wm9713_soc_resume(struct platform_device *pdev)
return ret;
}
-static int wm9713_soc_probe(struct platform_device *pdev)
+static int wm9713_soc_probe(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec;
+ struct wm9713_priv *wm9713;
int ret = 0, reg;
- socdev->card->codec = kzalloc(sizeof(struct snd_soc_codec),
- GFP_KERNEL);
- if (socdev->card->codec == NULL)
+ wm9713 = kzalloc(sizeof(struct wm9713_priv), GFP_KERNEL);
+ if (wm9713 == NULL)
return -ENOMEM;
- codec = socdev->card->codec;
- mutex_init(&codec->mutex);
-
- codec->reg_cache = kmemdup(wm9713_reg, sizeof(wm9713_reg), GFP_KERNEL);
- if (codec->reg_cache == NULL) {
- ret = -ENOMEM;
- goto cache_err;
- }
- codec->reg_cache_size = sizeof(wm9713_reg);
- codec->reg_cache_step = 2;
-
- snd_soc_codec_set_drvdata(codec, kzalloc(sizeof(struct wm9713_priv),
- GFP_KERNEL));
- if (snd_soc_codec_get_drvdata(codec) == NULL) {
- ret = -ENOMEM;
- goto priv_err;
- }
-
- codec->name = "WM9713";
- codec->owner = THIS_MODULE;
- codec->dai = wm9713_dai;
- codec->num_dai = ARRAY_SIZE(wm9713_dai);
- codec->write = ac97_write;
- codec->read = ac97_read;
- codec->set_bias_level = wm9713_set_bias_level;
- INIT_LIST_HEAD(&codec->dapm_widgets);
- INIT_LIST_HEAD(&codec->dapm_paths);
+ snd_soc_codec_set_drvdata(codec, wm9713);
ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0);
if (ret < 0)
goto codec_err;
- /* register pcms */
- ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
- if (ret < 0)
- goto pcm_err;
-
/* do a cold reset for the controller and then try
* a warm reset followed by an optional cold reset for codec */
wm9713_reset(codec, 0);
@@ -1273,46 +1235,67 @@ static int wm9713_soc_probe(struct platform_device *pdev)
return 0;
reset_err:
- snd_soc_free_pcms(socdev);
-pcm_err:
snd_soc_free_ac97_codec(codec);
-
codec_err:
- kfree(snd_soc_codec_get_drvdata(codec));
-
-priv_err:
- kfree(codec->reg_cache);
-
-cache_err:
- kfree(socdev->card->codec);
- socdev->card->codec = NULL;
+ kfree(wm9713);
return ret;
}
-static int wm9713_soc_remove(struct platform_device *pdev)
+static int wm9713_soc_remove(struct snd_soc_codec *codec)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec = socdev->card->codec;
-
- if (codec == NULL)
- return 0;
-
- snd_soc_dapm_free(socdev);
- snd_soc_free_pcms(socdev);
+ struct wm9713_priv *wm9713 = snd_soc_codec_get_drvdata(codec);
snd_soc_free_ac97_codec(codec);
- kfree(snd_soc_codec_get_drvdata(codec));
- kfree(codec->reg_cache);
- kfree(codec);
+ kfree(wm9713);
return 0;
}
-struct snd_soc_codec_device soc_codec_dev_wm9713 = {
+static struct snd_soc_codec_driver soc_codec_dev_wm9713 = {
.probe = wm9713_soc_probe,
.remove = wm9713_soc_remove,
.suspend = wm9713_soc_suspend,
.resume = wm9713_soc_resume,
+ .read = ac97_read,
+ .write = ac97_write,
+ .set_bias_level = wm9713_set_bias_level,
+ .reg_cache_size = sizeof(wm9713_reg),
+ .reg_word_size = sizeof(u16),
+ .reg_cache_step = 2,
+ .reg_cache_default = wm9713_reg,
+};
+
+static __devinit int wm9713_probe(struct platform_device *pdev)
+{
+ return snd_soc_register_codec(&pdev->dev,
+ &soc_codec_dev_wm9713, wm9713_dai, ARRAY_SIZE(wm9713_dai));
+}
+
+static int __devexit wm9713_remove(struct platform_device *pdev)
+{
+ snd_soc_unregister_codec(&pdev->dev);
+ return 0;
+}
+
+static struct platform_driver wm9713_codec_driver = {
+ .driver = {
+ .name = "wm9713-codec",
+ .owner = THIS_MODULE,
+ },
+
+ .probe = wm9713_probe,
+ .remove = __devexit_p(wm9713_remove),
};
-EXPORT_SYMBOL_GPL(soc_codec_dev_wm9713);
+
+static int __init wm9713_init(void)
+{
+ return platform_driver_register(&wm9713_codec_driver);
+}
+module_init(wm9713_init);
+
+static void __exit wm9713_exit(void)
+{
+ platform_driver_unregister(&wm9713_codec_driver);
+}
+module_exit(wm9713_exit);
MODULE_DESCRIPTION("ASoC WM9713/WM9714 driver");
MODULE_AUTHOR("Liam Girdwood");
diff --git a/sound/soc/codecs/wm9713.h b/sound/soc/codecs/wm9713.h
index 63b8d81756e3..793da863a03d 100644
--- a/sound/soc/codecs/wm9713.h
+++ b/sound/soc/codecs/wm9713.h
@@ -45,9 +45,6 @@
#define WM9713_DAI_AC97_AUX 1
#define WM9713_DAI_PCM_VOICE 2
-extern struct snd_soc_codec_device soc_codec_dev_wm9713;
-extern struct snd_soc_dai wm9713_dai[3];
-
int wm9713_reset(struct snd_soc_codec *codec, int try_warm);
#endif