Merge tag 'sound-4.7-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai...
[sfrench/cifs-2.6.git] / sound / soc / davinci / davinci-i2s.c
index ec98548a5fc9282b9c0b47abd354f22d8d95cb38..3849616519048401a44e691db64945050b7a8d68 100644 (file)
@@ -4,9 +4,15 @@
  * Author:      Vladimir Barinov, <vbarinov@embeddedalley.com>
  * Copyright:   (C) 2007 MontaVista Software, Inc., <source@mvista.com>
  *
+ * DT support  (c) 2016 Petr Kulhavy, Barix AG <petr@barix.com>
+ *             based on davinci-mcasp.c DT support
+ *
  * 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.
+ *
+ * TODO:
+ * on DA850 implement HW FIFOs instead of DMA into DXR and DRR registers
  */
 
 #include <linux/init.h>
@@ -650,13 +656,24 @@ static const struct snd_soc_component_driver davinci_i2s_component = {
 
 static int davinci_i2s_probe(struct platform_device *pdev)
 {
+       struct snd_dmaengine_dai_dma_data *dma_data;
        struct davinci_mcbsp_dev *dev;
        struct resource *mem, *res;
        void __iomem *io_base;
        int *dma;
        int ret;
 
-       mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       mem = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mpu");
+       if (!mem) {
+               dev_warn(&pdev->dev,
+                        "\"mpu\" mem resource not found, using index 0\n");
+               mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+               if (!mem) {
+                       dev_err(&pdev->dev, "no mem resource?\n");
+                       return -ENODEV;
+               }
+       }
+
        io_base = devm_ioremap_resource(&pdev->dev, mem);
        if (IS_ERR(io_base))
                return PTR_ERR(io_base);
@@ -666,39 +683,43 @@ static int davinci_i2s_probe(struct platform_device *pdev)
        if (!dev)
                return -ENOMEM;
 
-       dev->clk = clk_get(&pdev->dev, NULL);
-       if (IS_ERR(dev->clk))
-               return -ENODEV;
-       clk_enable(dev->clk);
-
        dev->base = io_base;
 
-       dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK].addr =
-           (dma_addr_t)(mem->start + DAVINCI_MCBSP_DXR_REG);
+       /* setup DMA, first TX, then RX */
+       dma_data = &dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK];
+       dma_data->addr = (dma_addr_t)(mem->start + DAVINCI_MCBSP_DXR_REG);
 
-       dev->dma_data[SNDRV_PCM_STREAM_CAPTURE].addr =
-           (dma_addr_t)(mem->start + 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_release_clk;
+       if (res) {
+               dma = &dev->dma_request[SNDRV_PCM_STREAM_PLAYBACK];
+               *dma = res->start;
+               dma_data->filter_data = dma;
+       } else if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node) {
+               dma_data->filter_data = "tx";
+       } else {
+               dev_err(&pdev->dev, "Missing DMA tx resource\n");
+               return -ENODEV;
        }
-       dma = &dev->dma_request[SNDRV_PCM_STREAM_PLAYBACK];
-       *dma = res->start;
-       dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK].filter_data = dma;
+
+       dma_data = &dev->dma_data[SNDRV_PCM_STREAM_CAPTURE];
+       dma_data->addr = (dma_addr_t)(mem->start + DAVINCI_MCBSP_DRR_REG);
 
        res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
-       if (!res) {
-               dev_err(&pdev->dev, "no DMA resource\n");
-               ret = -ENXIO;
-               goto err_release_clk;
+       if (res) {
+               dma = &dev->dma_request[SNDRV_PCM_STREAM_CAPTURE];
+               *dma = res->start;
+               dma_data->filter_data = dma;
+       } else if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node) {
+               dma_data->filter_data = "rx";
+       } else {
+               dev_err(&pdev->dev, "Missing DMA rx resource\n");
+               return -ENODEV;
        }
-       dma = &dev->dma_request[SNDRV_PCM_STREAM_CAPTURE];
-       *dma = res->start;
-       dev->dma_data[SNDRV_PCM_STREAM_CAPTURE].filter_data = dma;
+
+       dev->clk = clk_get(&pdev->dev, NULL);
+       if (IS_ERR(dev->clk))
+               return -ENODEV;
+       clk_enable(dev->clk);
 
        dev->dev = &pdev->dev;
        dev_set_drvdata(&pdev->dev, dev);
@@ -737,11 +758,18 @@ static int davinci_i2s_remove(struct platform_device *pdev)
        return 0;
 }
 
+static const struct of_device_id davinci_i2s_match[] = {
+       { .compatible = "ti,da850-mcbsp" },
+       {},
+};
+MODULE_DEVICE_TABLE(of, davinci_i2s_match);
+
 static struct platform_driver davinci_mcbsp_driver = {
        .probe          = davinci_i2s_probe,
        .remove         = davinci_i2s_remove,
        .driver         = {
                .name   = "davinci-mcbsp",
+               .of_match_table = of_match_ptr(davinci_i2s_match),
        },
 };