ASoC: Minor fixes to DaVinci I2S probe function
[pandora-kernel.git] / sound / soc / davinci / davinci-i2s.c
index ffdb943..2f11970 100644 (file)
 
 #include "davinci-pcm.h"
 
+
+/*
+ * NOTE:  terminology here is confusing.
+ *
+ *  - This driver supports the "Audio Serial Port" (ASP),
+ *    found on dm6446, dm355, and other DaVinci chips.
+ *
+ *  - But it labels it a "Multi-channel Buffered Serial Port"
+ *    (McBSP) as on older chips like the dm642 ... which was
+ *    backward-compatible, possibly explaining that confusion.
+ *
+ *  - OMAP chips have a controller called McBSP, which is
+ *    incompatible with the DaVinci flavor of McBSP.
+ *
+ *  - Newer DaVinci chips have a controller called McASP,
+ *    incompatible with ASP and with either McBSP.
+ *
+ * In short:  this uses ASP to implement I2S, not McBSP.
+ * And it won't be the only DaVinci implemention of I2S.
+ */
 #define DAVINCI_MCBSP_DRR_REG  0x00
 #define DAVINCI_MCBSP_DXR_REG  0x04
 #define DAVINCI_MCBSP_SPCR_REG 0x08
@@ -416,15 +436,39 @@ static int davinci_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
        return ret;
 }
 
-static int davinci_i2s_probe(struct platform_device *pdev,
-                            struct snd_soc_dai *dai)
+#define DAVINCI_I2S_RATES      SNDRV_PCM_RATE_8000_96000
+
+static struct snd_soc_dai_ops davinci_i2s_dai_ops = {
+       .startup        = davinci_i2s_startup,
+       .trigger        = davinci_i2s_trigger,
+       .hw_params      = davinci_i2s_hw_params,
+       .set_fmt        = davinci_i2s_set_dai_fmt,
+
+};
+
+struct snd_soc_dai davinci_i2s_dai = {
+       .name = "davinci-i2s",
+       .id = 0,
+       .playback = {
+               .channels_min = 2,
+               .channels_max = 2,
+               .rates = DAVINCI_I2S_RATES,
+               .formats = SNDRV_PCM_FMTBIT_S16_LE,},
+       .capture = {
+               .channels_min = 2,
+               .channels_max = 2,
+               .rates = DAVINCI_I2S_RATES,
+               .formats = SNDRV_PCM_FMTBIT_S16_LE,},
+       .ops = &davinci_i2s_dai_ops,
+
+};
+EXPORT_SYMBOL_GPL(davinci_i2s_dai);
+
+static int davinci_i2s_probe(struct platform_device *pdev)
 {
-       struct snd_soc_device *socdev = platform_get_drvdata(pdev);
-       struct snd_soc_card *card = socdev->card;
-       struct snd_soc_dai *cpu_dai = card->dai_link[pdev->id].cpu_dai;
+       struct snd_platform_data *pdata = pdev->dev.platform_data;
        struct davinci_mcbsp_dev *dev;
-       struct resource *mem, *ioarea;
-       struct evm_snd_platform_data *pdata;
+       struct resource *mem, *ioarea, *res;
        int ret;
 
        mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -446,9 +490,7 @@ static int davinci_i2s_probe(struct platform_device *pdev,
                goto err_release_region;
        }
 
-       cpu_dai->private_data = dev;
-
-       dev->clk = clk_get(&pdev->dev, "McBSPCLK");
+       dev->clk = clk_get(&pdev->dev, pdata->clk_name);
        if (IS_ERR(dev->clk)) {
                ret = -ENODEV;
                goto err_free_mem;
@@ -456,18 +498,37 @@ static int davinci_i2s_probe(struct platform_device *pdev,
        clk_enable(dev->clk);
 
        dev->base = (void __iomem *)IO_ADDRESS(mem->start);
-       pdata = pdev->dev.platform_data;
 
        dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK] = &davinci_i2s_pcm_out;
-       dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK]->channel = pdata->tx_dma_ch;
        dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK]->dma_addr =
            (dma_addr_t)(io_v2p(dev->base) + DAVINCI_MCBSP_DXR_REG);
 
        dev->dma_params[SNDRV_PCM_STREAM_CAPTURE] = &davinci_i2s_pcm_in;
-       dev->dma_params[SNDRV_PCM_STREAM_CAPTURE]->channel = pdata->rx_dma_ch;
        dev->dma_params[SNDRV_PCM_STREAM_CAPTURE]->dma_addr =
            (dma_addr_t)(io_v2p(dev->base) + DAVINCI_MCBSP_DRR_REG);
 
+       /* first TX, then RX */
+       res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
+       if (!res) {
+               dev_err(&pdev->dev, "no DMA resource\n");
+               ret = -ENXIO;
+               goto err_free_mem;
+       }
+       dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK]->channel = res->start;
+
+       res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
+       if (!res) {
+               dev_err(&pdev->dev, "no DMA resource\n");
+               ret = -ENXIO;
+               goto err_free_mem;
+       }
+       dev->dma_params[SNDRV_PCM_STREAM_CAPTURE]->channel = res->start;
+
+       davinci_i2s_dai.private_data = dev;
+       ret = snd_soc_register_dai(&davinci_i2s_dai);
+       if (ret != 0)
+               goto err_free_mem;
+
        return 0;
 
 err_free_mem:
@@ -478,62 +539,40 @@ err_release_region:
        return ret;
 }
 
-static void davinci_i2s_remove(struct platform_device *pdev,
-                              struct snd_soc_dai *dai)
+static int davinci_i2s_remove(struct platform_device *pdev)
 {
-       struct snd_soc_device *socdev = platform_get_drvdata(pdev);
-       struct snd_soc_card *card = socdev->card;
-       struct snd_soc_dai *cpu_dai = card->dai_link[pdev->id].cpu_dai;
-       struct davinci_mcbsp_dev *dev = cpu_dai->private_data;
+       struct davinci_mcbsp_dev *dev = davinci_i2s_dai.private_data;
        struct resource *mem;
 
+       snd_soc_unregister_dai(&davinci_i2s_dai);
        clk_disable(dev->clk);
        clk_put(dev->clk);
        dev->clk = NULL;
-
        kfree(dev);
-
        mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        release_mem_region(mem->start, (mem->end - mem->start) + 1);
-}
 
-#define DAVINCI_I2S_RATES      SNDRV_PCM_RATE_8000_96000
-
-static struct snd_soc_dai_ops davinci_i2s_dai_ops = {
-       .startup        = davinci_i2s_startup,
-       .trigger        = davinci_i2s_trigger,
-       .hw_params      = davinci_i2s_hw_params,
-       .set_fmt        = davinci_i2s_set_dai_fmt,
-};
+       return 0;
+}
 
-struct snd_soc_dai davinci_i2s_dai = {
-       .name = "davinci-i2s",
-       .id = 0,
-       .probe = davinci_i2s_probe,
-       .remove = davinci_i2s_remove,
-       .playback = {
-               .channels_min = 2,
-               .channels_max = 2,
-               .rates = DAVINCI_I2S_RATES,
-               .formats = SNDRV_PCM_FMTBIT_S16_LE,},
-       .capture = {
-               .channels_min = 2,
-               .channels_max = 2,
-               .rates = DAVINCI_I2S_RATES,
-               .formats = SNDRV_PCM_FMTBIT_S16_LE,},
-       .ops = &davinci_i2s_dai_ops,
+static struct platform_driver davinci_mcbsp_driver = {
+       .probe          = davinci_i2s_probe,
+       .remove         = davinci_i2s_remove,
+       .driver         = {
+               .name   = "davinci-asp",
+               .owner  = THIS_MODULE,
+       },
 };
-EXPORT_SYMBOL_GPL(davinci_i2s_dai);
 
 static int __init davinci_i2s_init(void)
 {
-       return snd_soc_register_dai(&davinci_i2s_dai);
+       return platform_driver_register(&davinci_mcbsp_driver);
 }
 module_init(davinci_i2s_init);
 
 static void __exit davinci_i2s_exit(void)
 {
-       snd_soc_unregister_dai(&davinci_i2s_dai);
+       platform_driver_unregister(&davinci_mcbsp_driver);
 }
 module_exit(davinci_i2s_exit);