Commit 87b132bc authored by Vasily Khoruzhick's avatar Vasily Khoruzhick Committed by Mark Brown

ASoC: samsung: s3c24{xx,12}-i2s: port to use generic dmaengine API

Use dmaengine instead of legacy s3c24xx DMA API for s3c24xx and s3c2412
Signed-off-by: default avatarVasily Khoruzhick <anarsoul@gmail.com>
Signed-off-by: default avatarMark Brown <broonie@linaro.org>
parent 5264d0e6
config SND_SOC_SAMSUNG config SND_SOC_SAMSUNG
tristate "ASoC support for Samsung" tristate "ASoC support for Samsung"
depends on PLAT_SAMSUNG depends on PLAT_SAMSUNG
select S3C2410_DMA if ARCH_S3C24XX select S3C24XX_DMAC if ARCH_S3C24XX
select S3C64XX_PL080 if ARCH_S3C64XX select S3C64XX_PL080 if ARCH_S3C64XX
select SND_S3C_DMA if !ARCH_S3C24XX select SND_S3C_DMA
select SND_S3C_DMA_LEGACY if ARCH_S3C24XX select SND_SOC_GENERIC_DMAENGINE_PCM
select SND_SOC_GENERIC_DMAENGINE_PCM if !ARCH_S3C24XX
help help
Say Y or M if you want to add support for codecs attached to Say Y or M if you want to add support for codecs attached to
the Samsung SoCs' Audio interfaces. You will also need to the Samsung SoCs' Audio interfaces. You will also need to
...@@ -19,7 +18,6 @@ config SND_S3C_DMA_LEGACY ...@@ -19,7 +18,6 @@ config SND_S3C_DMA_LEGACY
config SND_S3C24XX_I2S config SND_S3C24XX_I2S
tristate tristate
select S3C24XX_DMA
config SND_S3C_I2SV2_SOC config SND_S3C_I2SV2_SOC
tristate tristate
...@@ -27,7 +25,6 @@ config SND_S3C_I2SV2_SOC ...@@ -27,7 +25,6 @@ config SND_S3C_I2SV2_SOC
config SND_S3C2412_SOC_I2S config SND_S3C2412_SOC_I2S
tristate tristate
select SND_S3C_I2SV2_SOC select SND_S3C_I2SV2_SOC
select S3C2410_DMA
config SND_SAMSUNG_PCM config SND_SAMSUNG_PCM
tristate tristate
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/amba/pl08x.h> #include <linux/amba/pl08x.h>
#include <linux/platform_data/dma-s3c24xx.h>
#include <sound/core.h> #include <sound/core.h>
#include <sound/pcm.h> #include <sound/pcm.h>
...@@ -29,6 +30,8 @@ ...@@ -29,6 +30,8 @@
#ifdef CONFIG_ARCH_S3C64XX #ifdef CONFIG_ARCH_S3C64XX
#define filter_fn pl08x_filter_id #define filter_fn pl08x_filter_id
#elif defined(CONFIG_ARCH_S3C24XX)
#define filter_fn s3c24xx_dma_filter
#else #else
#define filter_fn NULL #define filter_fn NULL
#endif #endif
......
...@@ -392,8 +392,6 @@ static int s3c2412_i2s_trigger(struct snd_pcm_substream *substream, int cmd, ...@@ -392,8 +392,6 @@ static int s3c2412_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
int capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE); int capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE);
unsigned long irqs; unsigned long irqs;
int ret = 0; 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__); pr_debug("Entered %s\n", __func__);
...@@ -424,13 +422,6 @@ static int s3c2412_i2s_trigger(struct snd_pcm_substream *substream, int cmd, ...@@ -424,13 +422,6 @@ static int s3c2412_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
local_irq_restore(irqs); 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; break;
case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_STOP:
...@@ -644,12 +635,6 @@ int s3c_i2sv2_probe(struct snd_soc_dai *dai, ...@@ -644,12 +635,6 @@ int s3c_i2sv2_probe(struct snd_soc_dai *dai,
/* record our i2s structure for later use in the callbacks */ /* record our i2s structure for later use in the callbacks */
snd_soc_dai_set_drvdata(dai, i2s); 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"); i2s->iis_pclk = clk_get(dev, "iis");
if (IS_ERR(i2s->iis_pclk)) { if (IS_ERR(i2s->iis_pclk)) {
dev_err(dev, "failed to get iis_clock\n"); dev_err(dev, "failed to get iis_clock\n");
...@@ -729,7 +714,7 @@ int s3c_i2sv2_register_component(struct device *dev, int id, ...@@ -729,7 +714,7 @@ int s3c_i2sv2_register_component(struct device *dev, int id,
struct snd_soc_component_driver *cmp_drv, struct snd_soc_component_driver *cmp_drv,
struct snd_soc_dai_driver *dai_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; ops->trigger = s3c2412_i2s_trigger;
if (!ops->hw_params) if (!ops->hw_params)
......
...@@ -33,25 +33,19 @@ ...@@ -33,25 +33,19 @@
#include "regs-i2s-v2.h" #include "regs-i2s-v2.h"
#include "s3c2412-i2s.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 = { 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, .channel = DMACH_I2S_OUT,
.dma_addr = S3C2410_PA_IIS + S3C2412_IISTXD, .ch_name = "tx",
.dma_size = 4, .dma_size = 4,
}; };
static struct s3c_dma_params s3c2412_i2s_pcm_stereo_in = { 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, .channel = DMACH_I2S_IN,
.dma_addr = S3C2410_PA_IIS + S3C2412_IISRXD, .ch_name = "rx",
.dma_size = 4, .dma_size = 4,
}; };
...@@ -63,6 +57,9 @@ static int s3c2412_i2s_probe(struct snd_soc_dai *dai) ...@@ -63,6 +57,9 @@ static int s3c2412_i2s_probe(struct snd_soc_dai *dai)
pr_debug("Entered %s\n", __func__); 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); ret = s3c_i2sv2_probe(dai, &s3c2412_i2s, S3C2410_PA_IIS);
if (ret) if (ret)
return ret; return ret;
...@@ -70,10 +67,9 @@ static int s3c2412_i2s_probe(struct snd_soc_dai *dai) ...@@ -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_capture = &s3c2412_i2s_pcm_stereo_in;
s3c2412_i2s.dma_playback = &s3c2412_i2s_pcm_stereo_out; 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)) { if (IS_ERR(s3c2412_i2s.iis_cclk)) {
pr_err("failed to get i2sclk clock\n"); pr_err("failed to get i2sclk clock\n");
iounmap(s3c2412_i2s.regs);
return PTR_ERR(s3c2412_i2s.iis_cclk); return PTR_ERR(s3c2412_i2s.iis_cclk);
} }
...@@ -94,8 +90,6 @@ static int s3c2412_i2s_probe(struct snd_soc_dai *dai) ...@@ -94,8 +90,6 @@ static int s3c2412_i2s_probe(struct snd_soc_dai *dai)
static int s3c2412_i2s_remove(struct snd_soc_dai *dai) static int s3c2412_i2s_remove(struct snd_soc_dai *dai)
{ {
clk_disable(s3c2412_i2s.iis_cclk); clk_disable(s3c2412_i2s.iis_cclk);
clk_put(s3c2412_i2s.iis_cclk);
iounmap(s3c2412_i2s.regs);
return 0; return 0;
} }
...@@ -105,18 +99,10 @@ static int s3c2412_i2s_hw_params(struct snd_pcm_substream *substream, ...@@ -105,18 +99,10 @@ static int s3c2412_i2s_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_dai *cpu_dai) struct snd_soc_dai *cpu_dai)
{ {
struct s3c_i2sv2_info *i2s = snd_soc_dai_get_drvdata(cpu_dai); struct s3c_i2sv2_info *i2s = snd_soc_dai_get_drvdata(cpu_dai);
struct s3c_dma_params *dma_data;
u32 iismod; u32 iismod;
pr_debug("Entered %s\n", __func__); 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); iismod = readl(i2s->regs + S3C2412_IISMOD);
pr_debug("%s: r: IISMOD: %x\n", __func__, iismod); pr_debug("%s: r: IISMOD: %x\n", __func__, iismod);
...@@ -169,6 +155,19 @@ static const struct snd_soc_component_driver s3c2412_i2s_component = { ...@@ -169,6 +155,19 @@ static const struct snd_soc_component_driver s3c2412_i2s_component = {
static int s3c2412_iis_dev_probe(struct platform_device *pdev) static int s3c2412_iis_dev_probe(struct platform_device *pdev)
{ {
int ret = 0; 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, ret = s3c_i2sv2_register_component(&pdev->dev, -1,
&s3c2412_i2s_component, &s3c2412_i2s_component,
......
...@@ -31,25 +31,19 @@ ...@@ -31,25 +31,19 @@
#include "dma.h" #include "dma.h"
#include "s3c24xx-i2s.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 = { 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, .channel = DMACH_I2S_OUT,
.dma_addr = S3C2410_PA_IIS + S3C2410_IISFIFO, .ch_name = "tx",
.dma_size = 2, .dma_size = 2,
}; };
static struct s3c_dma_params s3c24xx_i2s_pcm_stereo_in = { 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, .channel = DMACH_I2S_IN,
.dma_addr = S3C2410_PA_IIS + S3C2410_IISFIFO, .ch_name = "rx",
.dma_size = 2, .dma_size = 2,
}; };
...@@ -231,18 +225,12 @@ static int s3c24xx_i2s_hw_params(struct snd_pcm_substream *substream, ...@@ -231,18 +225,12 @@ static int s3c24xx_i2s_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params, struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai) struct snd_soc_dai *dai)
{ {
struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_dmaengine_dai_dma_data *dma_data;
struct s3c_dma_params *dma_data;
u32 iismod; u32 iismod;
pr_debug("Entered %s\n", __func__); pr_debug("Entered %s\n", __func__);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) dma_data = snd_soc_dai_get_dma_data(dai, substream);
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);
/* Working copies of register */ /* Working copies of register */
iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD); iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD);
...@@ -251,11 +239,11 @@ static int s3c24xx_i2s_hw_params(struct snd_pcm_substream *substream, ...@@ -251,11 +239,11 @@ static int s3c24xx_i2s_hw_params(struct snd_pcm_substream *substream,
switch (params_width(params)) { switch (params_width(params)) {
case 8: case 8:
iismod &= ~S3C2410_IISMOD_16BIT; iismod &= ~S3C2410_IISMOD_16BIT;
dma_data->dma_size = 1; dma_data->addr_width = 1;
break; break;
case 16: case 16:
iismod |= S3C2410_IISMOD_16BIT; iismod |= S3C2410_IISMOD_16BIT;
dma_data->dma_size = 2; dma_data->addr_width = 2;
break; break;
default: default:
return -EINVAL; return -EINVAL;
...@@ -270,8 +258,6 @@ static int s3c24xx_i2s_trigger(struct snd_pcm_substream *substream, int cmd, ...@@ -270,8 +258,6 @@ static int s3c24xx_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
struct snd_soc_dai *dai) struct snd_soc_dai *dai)
{ {
int ret = 0; int ret = 0;
struct s3c_dma_params *dma_data =
snd_soc_dai_get_dma_data(dai, substream);
pr_debug("Entered %s\n", __func__); pr_debug("Entered %s\n", __func__);
...@@ -290,7 +276,6 @@ static int s3c24xx_i2s_trigger(struct snd_pcm_substream *substream, int cmd, ...@@ -290,7 +276,6 @@ static int s3c24xx_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
else else
s3c24xx_snd_txctrl(1); s3c24xx_snd_txctrl(1);
s3c2410_dma_ctrl(dma_data->channel, S3C2410_DMAOP_STARTED);
break; break;
case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_STOP:
case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_SUSPEND:
...@@ -380,14 +365,12 @@ static int s3c24xx_i2s_probe(struct snd_soc_dai *dai) ...@@ -380,14 +365,12 @@ static int s3c24xx_i2s_probe(struct snd_soc_dai *dai)
{ {
pr_debug("Entered %s\n", __func__); pr_debug("Entered %s\n", __func__);
s3c24xx_i2s.regs = ioremap(S3C2410_PA_IIS, 0x100); samsung_asoc_init_dma_data(dai, &s3c24xx_i2s_pcm_stereo_out,
if (s3c24xx_i2s.regs == NULL) &s3c24xx_i2s_pcm_stereo_in);
return -ENXIO;
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)) { if (IS_ERR(s3c24xx_i2s.iis_clk)) {
pr_err("failed to get iis_clock\n"); pr_err("failed to get iis_clock\n");
iounmap(s3c24xx_i2s.regs);
return PTR_ERR(s3c24xx_i2s.iis_clk); return PTR_ERR(s3c24xx_i2s.iis_clk);
} }
clk_enable(s3c24xx_i2s.iis_clk); clk_enable(s3c24xx_i2s.iis_clk);
...@@ -474,6 +457,19 @@ static const struct snd_soc_component_driver s3c24xx_i2s_component = { ...@@ -474,6 +457,19 @@ static const struct snd_soc_component_driver s3c24xx_i2s_component = {
static int s3c24xx_iis_dev_probe(struct platform_device *pdev) static int s3c24xx_iis_dev_probe(struct platform_device *pdev)
{ {
int ret = 0; 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, ret = devm_snd_soc_register_component(&pdev->dev,
&s3c24xx_i2s_component, &s3c24xx_i2s_dai, 1); &s3c24xx_i2s_component, &s3c24xx_i2s_dai, 1);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment