OSDN Git Service

ASoC: samsung: s3c24{xx,12}-i2s: port to use generic dmaengine API
authorVasily Khoruzhick <anarsoul@gmail.com>
Mon, 23 Jun 2014 20:24:04 +0000 (23:24 +0300)
committerMark Brown <broonie@linaro.org>
Tue, 24 Jun 2014 10:57:43 +0000 (11:57 +0100)
Use dmaengine instead of legacy s3c24xx DMA API for s3c24xx and s3c2412

Signed-off-by: Vasily Khoruzhick <anarsoul@gmail.com>
Signed-off-by: Mark Brown <broonie@linaro.org>
sound/soc/samsung/Kconfig
sound/soc/samsung/dmaengine.c
sound/soc/samsung/s3c-i2s-v2.c
sound/soc/samsung/s3c2412-i2s.c
sound/soc/samsung/s3c24xx-i2s.c

index 7745629..e88e598 100644 (file)
@@ -1,11 +1,10 @@
 config SND_SOC_SAMSUNG
        tristate "ASoC support for Samsung"
        depends on PLAT_SAMSUNG
-       select S3C2410_DMA if ARCH_S3C24XX
+       select S3C24XX_DMAC if ARCH_S3C24XX
        select S3C64XX_PL080 if ARCH_S3C64XX
-       select SND_S3C_DMA if !ARCH_S3C24XX
-       select SND_S3C_DMA_LEGACY if ARCH_S3C24XX
-       select SND_SOC_GENERIC_DMAENGINE_PCM if !ARCH_S3C24XX
+       select SND_S3C_DMA
+       select SND_SOC_GENERIC_DMAENGINE_PCM
        help
          Say Y or M if you want to add support for codecs attached to
          the Samsung SoCs' Audio interfaces. You will also need to
@@ -19,7 +18,6 @@ config SND_S3C_DMA_LEGACY
 
 config SND_S3C24XX_I2S
        tristate
-       select S3C24XX_DMA
 
 config SND_S3C_I2SV2_SOC
        tristate
@@ -27,7 +25,6 @@ config SND_S3C_I2SV2_SOC
 config SND_S3C2412_SOC_I2S
        tristate
        select SND_S3C_I2SV2_SOC
-       select S3C2410_DMA
 
 config SND_SAMSUNG_PCM
        tristate
index a0e4e79..506f5bf 100644 (file)
@@ -17,6 +17,7 @@
 
 #include <linux/module.h>
 #include <linux/amba/pl08x.h>
+#include <linux/platform_data/dma-s3c24xx.h>
 
 #include <sound/core.h>
 #include <sound/pcm.h>
@@ -29,6 +30,8 @@
 
 #ifdef CONFIG_ARCH_S3C64XX
 #define filter_fn pl08x_filter_id
+#elif defined(CONFIG_ARCH_S3C24XX)
+#define filter_fn s3c24xx_dma_filter
 #else
 #define filter_fn NULL
 #endif
index 0ff4bbe..de6c321 100644 (file)
@@ -392,8 +392,6 @@ static int s3c2412_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
        int capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE);
        unsigned long irqs;
        int ret = 0;
-       struct s3c_dma_params *dma_data =
-               snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
 
        pr_debug("Entered %s\n", __func__);
 
@@ -424,13 +422,6 @@ static int s3c2412_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
 
                local_irq_restore(irqs);
 
-               /*
-                * Load the next buffer to DMA to meet the reqirement
-                * of the auto reload mechanism of S3C24XX.
-                * This call won't bother S3C64XX.
-                */
-               s3c2410_dma_ctrl(dma_data->channel, S3C2410_DMAOP_STARTED);
-
                break;
 
        case SNDRV_PCM_TRIGGER_STOP:
@@ -644,12 +635,6 @@ int s3c_i2sv2_probe(struct snd_soc_dai *dai,
        /* record our i2s structure for later use in the callbacks */
        snd_soc_dai_set_drvdata(dai, i2s);
 
-       i2s->regs = ioremap(base, 0x100);
-       if (i2s->regs == NULL) {
-               dev_err(dev, "cannot ioremap registers\n");
-               return -ENXIO;
-       }
-
        i2s->iis_pclk = clk_get(dev, "iis");
        if (IS_ERR(i2s->iis_pclk)) {
                dev_err(dev, "failed to get iis_clock\n");
@@ -729,7 +714,7 @@ int s3c_i2sv2_register_component(struct device *dev, int id,
                           struct snd_soc_component_driver *cmp_drv,
                           struct snd_soc_dai_driver *dai_drv)
 {
-       struct snd_soc_dai_ops *ops = dai_drv->ops;
+       struct snd_soc_dai_ops *ops = (struct snd_soc_dai_ops *)dai_drv->ops;
 
        ops->trigger = s3c2412_i2s_trigger;
        if (!ops->hw_params)
index 08c059b..d9d27cc 100644 (file)
 #include "regs-i2s-v2.h"
 #include "s3c2412-i2s.h"
 
-static struct s3c_dma_client s3c2412_dma_client_out = {
-       .name           = "I2S PCM Stereo out"
-};
-
-static struct s3c_dma_client s3c2412_dma_client_in = {
-       .name           = "I2S PCM Stereo in"
-};
-
 static struct s3c_dma_params s3c2412_i2s_pcm_stereo_out = {
-       .client         = &s3c2412_dma_client_out,
+       .client         =
+               (struct s3c_dma_client *)&s3c2412_i2s_pcm_stereo_out,
        .channel        = DMACH_I2S_OUT,
-       .dma_addr       = S3C2410_PA_IIS + S3C2412_IISTXD,
+       .ch_name        = "tx",
        .dma_size       = 4,
 };
 
 static struct s3c_dma_params s3c2412_i2s_pcm_stereo_in = {
-       .client         = &s3c2412_dma_client_in,
+       .client         =
+               (struct s3c_dma_client *)&s3c2412_i2s_pcm_stereo_in,
        .channel        = DMACH_I2S_IN,
-       .dma_addr       = S3C2410_PA_IIS + S3C2412_IISRXD,
+       .ch_name        = "rx",
        .dma_size       = 4,
 };
 
@@ -63,6 +57,9 @@ static int s3c2412_i2s_probe(struct snd_soc_dai *dai)
 
        pr_debug("Entered %s\n", __func__);
 
+       samsung_asoc_init_dma_data(dai, &s3c2412_i2s_pcm_stereo_out,
+               &s3c2412_i2s_pcm_stereo_in);
+
        ret = s3c_i2sv2_probe(dai, &s3c2412_i2s, S3C2410_PA_IIS);
        if (ret)
                return ret;
@@ -70,10 +67,9 @@ static int s3c2412_i2s_probe(struct snd_soc_dai *dai)
        s3c2412_i2s.dma_capture = &s3c2412_i2s_pcm_stereo_in;
        s3c2412_i2s.dma_playback = &s3c2412_i2s_pcm_stereo_out;
 
-       s3c2412_i2s.iis_cclk = clk_get(dai->dev, "i2sclk");
+       s3c2412_i2s.iis_cclk = devm_clk_get(dai->dev, "i2sclk");
        if (IS_ERR(s3c2412_i2s.iis_cclk)) {
                pr_err("failed to get i2sclk clock\n");
-               iounmap(s3c2412_i2s.regs);
                return PTR_ERR(s3c2412_i2s.iis_cclk);
        }
 
@@ -94,8 +90,6 @@ static int s3c2412_i2s_probe(struct snd_soc_dai *dai)
 static int s3c2412_i2s_remove(struct snd_soc_dai *dai)
 {
        clk_disable(s3c2412_i2s.iis_cclk);
-       clk_put(s3c2412_i2s.iis_cclk);
-       iounmap(s3c2412_i2s.regs);
 
        return 0;
 }
@@ -105,18 +99,10 @@ static int s3c2412_i2s_hw_params(struct snd_pcm_substream *substream,
                                 struct snd_soc_dai *cpu_dai)
 {
        struct s3c_i2sv2_info *i2s = snd_soc_dai_get_drvdata(cpu_dai);
-       struct s3c_dma_params *dma_data;
        u32 iismod;
 
        pr_debug("Entered %s\n", __func__);
 
-       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-               dma_data = i2s->dma_playback;
-       else
-               dma_data = i2s->dma_capture;
-
-       snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data);
-
        iismod = readl(i2s->regs + S3C2412_IISMOD);
        pr_debug("%s: r: IISMOD: %x\n", __func__, iismod);
 
@@ -169,6 +155,19 @@ static const struct snd_soc_component_driver s3c2412_i2s_component = {
 static int s3c2412_iis_dev_probe(struct platform_device *pdev)
 {
        int ret = 0;
+       struct resource *res;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!res) {
+               dev_err(&pdev->dev, "Can't get IO resource.\n");
+               return -ENOENT;
+       }
+       s3c2412_i2s.regs = devm_ioremap_resource(&pdev->dev, res);
+       if (s3c2412_i2s.regs == NULL)
+               return -ENXIO;
+
+       s3c2412_i2s_pcm_stereo_out.dma_addr = res->start + S3C2412_IISTXD;
+       s3c2412_i2s_pcm_stereo_in.dma_addr = res->start + S3C2412_IISRXD;
 
        ret = s3c_i2sv2_register_component(&pdev->dev, -1,
                                           &s3c2412_i2s_component,
index 9aba9fb..6f3ee87 100644 (file)
 #include "dma.h"
 #include "s3c24xx-i2s.h"
 
-static struct s3c_dma_client s3c24xx_dma_client_out = {
-       .name = "I2S PCM Stereo out"
-};
-
-static struct s3c_dma_client s3c24xx_dma_client_in = {
-       .name = "I2S PCM Stereo in"
-};
-
 static struct s3c_dma_params s3c24xx_i2s_pcm_stereo_out = {
-       .client         = &s3c24xx_dma_client_out,
+       .client         =
+               (struct s3c_dma_client *)&s3c24xx_i2s_pcm_stereo_out,
        .channel        = DMACH_I2S_OUT,
-       .dma_addr       = S3C2410_PA_IIS + S3C2410_IISFIFO,
+       .ch_name        = "tx",
        .dma_size       = 2,
 };
 
 static struct s3c_dma_params s3c24xx_i2s_pcm_stereo_in = {
-       .client         = &s3c24xx_dma_client_in,
+       .client         =
+               (struct s3c_dma_client *)&s3c24xx_i2s_pcm_stereo_in,
        .channel        = DMACH_I2S_IN,
-       .dma_addr       = S3C2410_PA_IIS + S3C2410_IISFIFO,
+       .ch_name        = "rx",
        .dma_size       = 2,
 };
 
@@ -231,18 +225,12 @@ static int s3c24xx_i2s_hw_params(struct snd_pcm_substream *substream,
                                 struct snd_pcm_hw_params *params,
                                 struct snd_soc_dai *dai)
 {
-       struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct s3c_dma_params *dma_data;
+       struct snd_dmaengine_dai_dma_data *dma_data;
        u32 iismod;
 
        pr_debug("Entered %s\n", __func__);
 
-       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-               dma_data = &s3c24xx_i2s_pcm_stereo_out;
-       else
-               dma_data = &s3c24xx_i2s_pcm_stereo_in;
-
-       snd_soc_dai_set_dma_data(rtd->cpu_dai, substream, dma_data);
+       dma_data = snd_soc_dai_get_dma_data(dai, substream);
 
        /* Working copies of register */
        iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD);
@@ -251,11 +239,11 @@ static int s3c24xx_i2s_hw_params(struct snd_pcm_substream *substream,
        switch (params_width(params)) {
        case 8:
                iismod &= ~S3C2410_IISMOD_16BIT;
-               dma_data->dma_size = 1;
+               dma_data->addr_width = 1;
                break;
        case 16:
                iismod |= S3C2410_IISMOD_16BIT;
-               dma_data->dma_size = 2;
+               dma_data->addr_width = 2;
                break;
        default:
                return -EINVAL;
@@ -270,8 +258,6 @@ static int s3c24xx_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
                               struct snd_soc_dai *dai)
 {
        int ret = 0;
-       struct s3c_dma_params *dma_data =
-               snd_soc_dai_get_dma_data(dai, substream);
 
        pr_debug("Entered %s\n", __func__);
 
@@ -290,7 +276,6 @@ static int s3c24xx_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
                else
                        s3c24xx_snd_txctrl(1);
 
-               s3c2410_dma_ctrl(dma_data->channel, S3C2410_DMAOP_STARTED);
                break;
        case SNDRV_PCM_TRIGGER_STOP:
        case SNDRV_PCM_TRIGGER_SUSPEND:
@@ -380,14 +365,12 @@ static int s3c24xx_i2s_probe(struct snd_soc_dai *dai)
 {
        pr_debug("Entered %s\n", __func__);
 
-       s3c24xx_i2s.regs = ioremap(S3C2410_PA_IIS, 0x100);
-       if (s3c24xx_i2s.regs == NULL)
-               return -ENXIO;
+       samsung_asoc_init_dma_data(dai, &s3c24xx_i2s_pcm_stereo_out,
+               &s3c24xx_i2s_pcm_stereo_in);
 
-       s3c24xx_i2s.iis_clk = clk_get(dai->dev, "iis");
+       s3c24xx_i2s.iis_clk = devm_clk_get(dai->dev, "iis");
        if (IS_ERR(s3c24xx_i2s.iis_clk)) {
                pr_err("failed to get iis_clock\n");
-               iounmap(s3c24xx_i2s.regs);
                return PTR_ERR(s3c24xx_i2s.iis_clk);
        }
        clk_enable(s3c24xx_i2s.iis_clk);
@@ -474,6 +457,19 @@ static const struct snd_soc_component_driver s3c24xx_i2s_component = {
 static int s3c24xx_iis_dev_probe(struct platform_device *pdev)
 {
        int ret = 0;
+       struct resource *res;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!res) {
+               dev_err(&pdev->dev, "Can't get IO resource.\n");
+               return -ENOENT;
+       }
+       s3c24xx_i2s.regs = devm_ioremap_resource(&pdev->dev, res);
+       if (s3c24xx_i2s.regs == NULL)
+               return -ENXIO;
+
+       s3c24xx_i2s_pcm_stereo_out.dma_addr = res->start + S3C2410_IISFIFO;
+       s3c24xx_i2s_pcm_stereo_in.dma_addr = res->start + S3C2410_IISFIFO;
 
        ret = devm_snd_soc_register_component(&pdev->dev,
                        &s3c24xx_i2s_component, &s3c24xx_i2s_dai, 1);