]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - sound/soc/codecs/ad1836.c
ASoC: multi-component - ASoC Multi-Component Support
[mv-sheeva.git] / sound / soc / codecs / ad1836.c
index a01006c8c606ffd613b250bf7f95fbc95ebaa05c..d272534c8f8413dba5221dc60d01fdbfb74b72e8 100644 (file)
 
 /* 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)
 {