ASoC: samsung: Modify i2s driver to support idma
authorInha Song <ideal.song@samsung.com>
Wed, 30 Apr 2014 11:09:09 +0000 (20:09 +0900)
committerChanho Park <chanho61.park@samsung.com>
Thu, 7 Aug 2014 05:32:09 +0000 (14:32 +0900)
i2s-sec driver uses the internal dma.

Because ASoC idma devices are not registered as platform device,
asoc_idma_platform_register() should be called for idma registration.

Change-Id: Iaf7b0c0e3cdf66f4eda720cd705cf802c391d76b
Signed-off-by: Inha Song <ideal.song@samsung.com>
sound/soc/samsung/i2s.c

index b6687e3..0a0cdb1 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/of_gpio.h>
+#include <linux/of_irq.h>
 #include <linux/pm_runtime.h>
 
 #include <sound/soc.h>
@@ -998,7 +999,8 @@ static int samsung_i2s_dai_probe(struct snd_soc_dai *dai)
 
        if (i2s->quirks & QUIRK_SEC_DAI)
                idma_reg_addr_init(i2s->addr,
-                                       i2s->sec_dai->idma_playback.dma_addr);
+                                       i2s->sec_dai->idma_playback.dma_addr,
+                                       i2s->sec_dai->idma_playback.irq);
 
 probe_exit:
        /* Reset any constraint on RFS and BFS */
@@ -1149,7 +1151,7 @@ static int samsung_i2s_probe(struct platform_device *pdev)
        struct s3c_audio_pdata *i2s_pdata = pdev->dev.platform_data;
        struct samsung_i2s *i2s_cfg = NULL;
        struct resource *res;
-       u32 regs_base, quirks = 0, idma_addr = 0;
+       u32 regs_base, quirks = 0, idma_addr = 0, idma_irq = 0;
        struct device_node *np = pdev->dev.of_node;
        enum samsung_dai_type samsung_dai_type;
        int ret = 0;
@@ -1163,10 +1165,12 @@ static int samsung_i2s_probe(struct platform_device *pdev)
                        dev_err(&pdev->dev, "Unable to get drvdata\n");
                        return -EFAULT;
                }
+
                snd_soc_register_component(&sec_dai->pdev->dev,
                                           &samsung_i2s_component,
                                           &sec_dai->i2s_dai_drv, 1);
-               asoc_dma_platform_register(&pdev->dev);
+               asoc_idma_platform_register(&pdev->dev);
+
                return 0;
        }
 
@@ -1223,6 +1227,14 @@ static int samsung_i2s_probe(struct platform_device *pdev)
                                return -EINVAL;
                        }
                }
+
+               idma_irq = irq_of_parse_and_map(np, 0);
+               if (idma_irq == NO_IRQ) {
+                       if (quirks & QUIRK_SEC_DAI) {
+                               dev_err(&pdev->dev, "idma irq is not specified");
+                               return -EINVAL;
+                       }
+               }
        }
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -1277,6 +1289,7 @@ static int samsung_i2s_probe(struct platform_device *pdev)
                sec_dai->base = regs_base;
                sec_dai->quirks = quirks;
                sec_dai->idma_playback.dma_addr = idma_addr;
+               sec_dai->idma_playback.irq = idma_irq;
                sec_dai->pri_dai = pri_dai;
                pri_dai->sec_dai = sec_dai;
        }
@@ -1322,7 +1335,11 @@ static int samsung_i2s_remove(struct platform_device *pdev)
        i2s->pri_dai = NULL;
        i2s->sec_dai = NULL;
 
-       asoc_dma_platform_unregister(&pdev->dev);
+       if (other)
+               asoc_idma_platform_unregister(&pdev->dev);
+       else
+               asoc_dma_platform_unregister(&pdev->dev);
+
        snd_soc_unregister_component(&pdev->dev);
 
        return 0;