summaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/ad1836.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/ad1836.c')
-rw-r--r--sound/soc/codecs/ad1836.c191
1 files changed, 55 insertions, 136 deletions
diff --git a/sound/soc/codecs/ad1836.c b/sound/soc/codecs/ad1836.c
index a01006c..d272534 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)
{
OpenPOWER on IntegriCloud