ASoC: atmel-ssc-dai: register dai and pcm directly
authorBo Shen <voice.shen@atmel.com>
Wed, 14 Nov 2012 10:09:09 +0000 (18:09 +0800)
committerMark Brown <broonie@opensource.wolfsonmicro.com>
Fri, 16 Nov 2012 01:24:38 +0000 (10:24 +0900)
change the method for register dai and pcm
  - let the atmel-ssc-dai no longer as a standalone platform device
  - remap ssc and then register dai directly
  - register pcm from dai directly
  - modify the code which related with this change

Signed-off-by: Bo Shen <voice.shen@atmel.com>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
sound/soc/atmel/atmel-pcm.c
sound/soc/atmel/atmel-pcm.h
sound/soc/atmel/atmel_ssc_dai.c
sound/soc/atmel/atmel_ssc_dai.h

index 9b84f985770ee4e09ca1d7a8ab04cbe410fda037..40e17d13d78abc9549c2d21c757bbffcb65d4479 100644 (file)
@@ -473,28 +473,17 @@ static struct snd_soc_platform_driver atmel_soc_platform = {
        .resume         = atmel_pcm_resume,
 };
 
-static int __devinit atmel_soc_platform_probe(struct platform_device *pdev)
+int atmel_pcm_platform_register(struct device *dev)
 {
-       return snd_soc_register_platform(&pdev->dev, &atmel_soc_platform);
+       return snd_soc_register_platform(dev, &atmel_soc_platform);
 }
+EXPORT_SYMBOL(atmel_pcm_platform_register);
 
-static int __devexit atmel_soc_platform_remove(struct platform_device *pdev)
+void atmel_pcm_platform_unregister(struct device *dev)
 {
-       snd_soc_unregister_platform(&pdev->dev);
-       return 0;
+       snd_soc_unregister_platform(dev);
 }
-
-static struct platform_driver atmel_pcm_driver = {
-       .driver = {
-                       .name = "atmel-pcm-audio",
-                       .owner = THIS_MODULE,
-       },
-
-       .probe = atmel_soc_platform_probe,
-       .remove = __devexit_p(atmel_soc_platform_remove),
-};
-
-module_platform_driver(atmel_pcm_driver);
+EXPORT_SYMBOL(atmel_pcm_platform_unregister);
 
 MODULE_AUTHOR("Sedji Gaouaou <sedji.gaouaou@atmel.com>");
 MODULE_DESCRIPTION("Atmel PCM module");
index 5e0a95e643298b8f5210e7619139b48a02ae939f..e6d67b3dddd103c27eb4c34788d4f6ae17c45b24 100644 (file)
@@ -80,4 +80,7 @@ struct atmel_pcm_dma_params {
 #define ssc_readx(base, reg)            (__raw_readl((base) + (reg)))
 #define ssc_writex(base, reg, value)    __raw_writel((value), (base) + (reg))
 
+int atmel_pcm_platform_register(struct device *dev);
+void atmel_pcm_platform_unregister(struct device *dev);
+
 #endif /* _ATMEL_PCM_H */
index 354341ec0f42f1129adbaaf310366af46b866229..7932c052b736f2d13ccd0bf309fc48ef5464d26d 100644 (file)
 #include "atmel_ssc_dai.h"
 
 
-#if defined(CONFIG_ARCH_AT91SAM9260) || defined(CONFIG_ARCH_AT91SAM9G20)
-#define NUM_SSC_DEVICES                1
-#else
 #define NUM_SSC_DEVICES                3
-#endif
 
 /*
  * SSC PDC registers required by the PCM DMA engine.
@@ -107,7 +103,6 @@ static struct atmel_pcm_dma_params ssc_dma_params[NUM_SSC_DEVICES][2] = {
        .pdc            = &pdc_rx_reg,
        .mask           = &ssc_rx_mask,
        } },
-#if NUM_SSC_DEVICES == 3
        {{
        .name           = "SSC1 PCM out",
        .pdc            = &pdc_tx_reg,
@@ -128,7 +123,6 @@ static struct atmel_pcm_dma_params ssc_dma_params[NUM_SSC_DEVICES][2] = {
        .pdc            = &pdc_rx_reg,
        .mask           = &ssc_rx_mask,
        } },
-#endif
 };
 
 
@@ -139,7 +133,6 @@ static struct atmel_ssc_info ssc_info[NUM_SSC_DEVICES] = {
        .dir_mask       = SSC_DIR_MASK_UNUSED,
        .initialized    = 0,
        },
-#if NUM_SSC_DEVICES == 3
        {
        .name           = "ssc1",
        .lock           = __SPIN_LOCK_UNLOCKED(ssc_info[1].lock),
@@ -152,7 +145,6 @@ static struct atmel_ssc_info ssc_info[NUM_SSC_DEVICES] = {
        .dir_mask       = SSC_DIR_MASK_UNUSED,
        .initialized    = 0,
        },
-#endif
 };
 
 
@@ -690,27 +682,9 @@ static int atmel_ssc_resume(struct snd_soc_dai *cpu_dai)
 static int atmel_ssc_probe(struct snd_soc_dai *dai)
 {
        struct atmel_ssc_info *ssc_p = &ssc_info[dai->id];
-       int ret = 0;
 
        snd_soc_dai_set_drvdata(dai, ssc_p);
 
-       /*
-        * Request SSC device
-        */
-       ssc_p->ssc = ssc_request(dai->id);
-       if (IS_ERR(ssc_p->ssc)) {
-               printk(KERN_ERR "ASoC: Failed to request SSC %d\n", dai->id);
-               ret = PTR_ERR(ssc_p->ssc);
-       }
-
-       return ret;
-}
-
-static int atmel_ssc_remove(struct snd_soc_dai *dai)
-{
-       struct atmel_ssc_info *ssc_p = snd_soc_dai_get_drvdata(dai);
-
-       ssc_free(ssc_p->ssc);
        return 0;
 }
 
@@ -728,48 +702,8 @@ static const struct snd_soc_dai_ops atmel_ssc_dai_ops = {
        .set_clkdiv     = atmel_ssc_set_dai_clkdiv,
 };
 
-static struct snd_soc_dai_driver atmel_ssc_dai[NUM_SSC_DEVICES] = {
-       {
-               .name = "atmel-ssc-dai.0",
-               .probe = atmel_ssc_probe,
-               .remove = atmel_ssc_remove,
-               .suspend = atmel_ssc_suspend,
-               .resume = atmel_ssc_resume,
-               .playback = {
-                       .channels_min = 1,
-                       .channels_max = 2,
-                       .rates = ATMEL_SSC_RATES,
-                       .formats = ATMEL_SSC_FORMATS,},
-               .capture = {
-                       .channels_min = 1,
-                       .channels_max = 2,
-                       .rates = ATMEL_SSC_RATES,
-                       .formats = ATMEL_SSC_FORMATS,},
-               .ops = &atmel_ssc_dai_ops,
-       },
-#if NUM_SSC_DEVICES == 3
-       {
-               .name = "atmel-ssc-dai.1",
-               .probe = atmel_ssc_probe,
-               .remove = atmel_ssc_remove,
-               .suspend = atmel_ssc_suspend,
-               .resume = atmel_ssc_resume,
-               .playback = {
-                       .channels_min = 1,
-                       .channels_max = 2,
-                       .rates = ATMEL_SSC_RATES,
-                       .formats = ATMEL_SSC_FORMATS,},
-               .capture = {
-                       .channels_min = 1,
-                       .channels_max = 2,
-                       .rates = ATMEL_SSC_RATES,
-                       .formats = ATMEL_SSC_FORMATS,},
-               .ops = &atmel_ssc_dai_ops,
-       },
-       {
-               .name = "atmel-ssc-dai.2",
+static struct snd_soc_dai_driver atmel_ssc_dai = {
                .probe = atmel_ssc_probe,
-               .remove = atmel_ssc_remove,
                .suspend = atmel_ssc_suspend,
                .resume = atmel_ssc_resume,
                .playback = {
@@ -783,32 +717,37 @@ static struct snd_soc_dai_driver atmel_ssc_dai[NUM_SSC_DEVICES] = {
                        .rates = ATMEL_SSC_RATES,
                        .formats = ATMEL_SSC_FORMATS,},
                .ops = &atmel_ssc_dai_ops,
-       },
-#endif
 };
 
-static __devinit int asoc_ssc_probe(struct platform_device *pdev)
+static int asoc_ssc_init(struct device *dev)
 {
-       BUG_ON(pdev->id < 0);
-       BUG_ON(pdev->id >= ARRAY_SIZE(atmel_ssc_dai));
-       return snd_soc_register_dai(&pdev->dev, &atmel_ssc_dai[pdev->id]);
-}
+       int ret;
+
+       ret = snd_soc_register_dai(dev, &atmel_ssc_dai);
+       if (ret) {
+               dev_err(dev, "Could not register DAI: %d\n", ret);
+               goto err;
+       }
+
+       ret = atmel_pcm_platform_register(dev);
+       if (ret) {
+               dev_err(dev, "Could not register PCM: %d\n", ret);
+               goto err_unregister_dai;
+       };
 
-static int __devexit asoc_ssc_remove(struct platform_device *pdev)
-{
-       snd_soc_unregister_dai(&pdev->dev);
        return 0;
-}
 
-static struct platform_driver asoc_ssc_driver = {
-       .driver = {
-                       .name = "atmel-ssc-dai",
-                       .owner = THIS_MODULE,
-       },
+err_unregister_dai:
+       snd_soc_unregister_dai(dev);
+err:
+       return ret;
+}
 
-       .probe = asoc_ssc_probe,
-       .remove = __devexit_p(asoc_ssc_remove),
-};
+static void asoc_ssc_exit(struct device *dev)
+{
+       atmel_pcm_platform_unregister(dev);
+       snd_soc_unregister_dai(dev);
+}
 
 /**
  * atmel_ssc_set_audio - Allocate the specified SSC for audio use.
@@ -816,50 +755,32 @@ static struct platform_driver asoc_ssc_driver = {
 int atmel_ssc_set_audio(int ssc_id)
 {
        struct ssc_device *ssc;
-       static struct platform_device *dma_pdev;
-       struct platform_device *ssc_pdev;
        int ret;
 
-       if (ssc_id < 0 || ssc_id >= ARRAY_SIZE(atmel_ssc_dai))
-               return -EINVAL;
-
-       /* Allocate a dummy device for DMA if we don't have one already */
-       if (!dma_pdev) {
-               dma_pdev = platform_device_alloc("atmel-pcm-audio", -1);
-               if (!dma_pdev)
-                       return -ENOMEM;
-
-               ret = platform_device_add(dma_pdev);
-               if (ret < 0) {
-                       platform_device_put(dma_pdev);
-                       dma_pdev = NULL;
-                       return ret;
-               }
-       }
-
-       ssc_pdev = platform_device_alloc("atmel-ssc-dai", ssc_id);
-       if (!ssc_pdev)
-               return -ENOMEM;
-
        /* If we can grab the SSC briefly to parent the DAI device off it */
        ssc = ssc_request(ssc_id);
-       if (IS_ERR(ssc))
-               pr_warn("Unable to parent ASoC SSC DAI on SSC: %ld\n",
+       if (IS_ERR(ssc)) {
+               pr_err("Unable to parent ASoC SSC DAI on SSC: %ld\n",
                        PTR_ERR(ssc));
-       else {
-               ssc_pdev->dev.parent = &(ssc->pdev->dev);
-               ssc_free(ssc);
+               return PTR_ERR(ssc);
+       } else {
+               ssc_info[ssc_id].ssc = ssc;
        }
 
-       ret = platform_device_add(ssc_pdev);
-       if (ret < 0)
-               platform_device_put(ssc_pdev);
+       ret = asoc_ssc_init(&ssc->pdev->dev);
 
        return ret;
 }
 EXPORT_SYMBOL_GPL(atmel_ssc_set_audio);
 
-module_platform_driver(asoc_ssc_driver);
+void atmel_ssc_put_audio(int ssc_id)
+{
+       struct ssc_device *ssc = ssc_info[ssc_id].ssc;
+
+       ssc_free(ssc);
+       asoc_ssc_exit(&ssc->pdev->dev);
+}
+EXPORT_SYMBOL_GPL(atmel_ssc_put_audio);
 
 /* Module information */
 MODULE_AUTHOR("Sedji Gaouaou, sedji.gaouaou@atmel.com, www.atmel.com");
index 5d4f0f9b4d9a875eb935ec79488b76ff17073ab0..b1f08d51149526006021c7314aa4f3e15847de3d 100644 (file)
@@ -117,6 +117,7 @@ struct atmel_ssc_info {
        struct atmel_ssc_state ssc_state;
 };
 
-int atmel_ssc_set_audio(int ssc);
+int atmel_ssc_set_audio(int ssc_id);
+void atmel_ssc_put_audio(int ssc_id);
 
 #endif /* _AT91_SSC_DAI_H */