aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/samsung
diff options
context:
space:
mode:
authorVasily Khoruzhick <anarsoul@gmail.com>2014-06-23 16:24:04 -0400
committerMark Brown <broonie@linaro.org>2014-06-24 06:57:43 -0400
commit87b132bc0315fdfe7677449da1fb1ce12c5dda35 (patch)
treed2944094dfb897bd1bd6d7212b5cc33f34fdc9b8 /sound/soc/samsung
parent5264d0e6ef0a926eaf11313715c15de737b2f0b3 (diff)
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: Vasily Khoruzhick <anarsoul@gmail.com> Signed-off-by: Mark Brown <broonie@linaro.org>
Diffstat (limited to 'sound/soc/samsung')
-rw-r--r--sound/soc/samsung/Kconfig9
-rw-r--r--sound/soc/samsung/dmaengine.c3
-rw-r--r--sound/soc/samsung/s3c-i2s-v2.c17
-rw-r--r--sound/soc/samsung/s3c2412-i2s.c47
-rw-r--r--sound/soc/samsung/s3c24xx-i2s.c56
5 files changed, 56 insertions, 76 deletions
diff --git a/sound/soc/samsung/Kconfig b/sound/soc/samsung/Kconfig
index 7745629e2c88..e88e598fbe0c 100644
--- a/sound/soc/samsung/Kconfig
+++ b/sound/soc/samsung/Kconfig
@@ -1,11 +1,10 @@
1config SND_SOC_SAMSUNG 1config SND_SOC_SAMSUNG
2 tristate "ASoC support for Samsung" 2 tristate "ASoC support for Samsung"
3 depends on PLAT_SAMSUNG 3 depends on PLAT_SAMSUNG
4 select S3C2410_DMA if ARCH_S3C24XX 4 select S3C24XX_DMAC if ARCH_S3C24XX
5 select S3C64XX_PL080 if ARCH_S3C64XX 5 select S3C64XX_PL080 if ARCH_S3C64XX
6 select SND_S3C_DMA if !ARCH_S3C24XX 6 select SND_S3C_DMA
7 select SND_S3C_DMA_LEGACY if ARCH_S3C24XX 7 select SND_SOC_GENERIC_DMAENGINE_PCM
8 select SND_SOC_GENERIC_DMAENGINE_PCM if !ARCH_S3C24XX
9 help 8 help
10 Say Y or M if you want to add support for codecs attached to 9 Say Y or M if you want to add support for codecs attached to
11 the Samsung SoCs' Audio interfaces. You will also need to 10 the Samsung SoCs' Audio interfaces. You will also need to
@@ -19,7 +18,6 @@ config SND_S3C_DMA_LEGACY
19 18
20config SND_S3C24XX_I2S 19config SND_S3C24XX_I2S
21 tristate 20 tristate
22 select S3C24XX_DMA
23 21
24config SND_S3C_I2SV2_SOC 22config SND_S3C_I2SV2_SOC
25 tristate 23 tristate
@@ -27,7 +25,6 @@ config SND_S3C_I2SV2_SOC
27config SND_S3C2412_SOC_I2S 25config SND_S3C2412_SOC_I2S
28 tristate 26 tristate
29 select SND_S3C_I2SV2_SOC 27 select SND_S3C_I2SV2_SOC
30 select S3C2410_DMA
31 28
32config SND_SAMSUNG_PCM 29config SND_SAMSUNG_PCM
33 tristate 30 tristate
diff --git a/sound/soc/samsung/dmaengine.c b/sound/soc/samsung/dmaengine.c
index a0e4e7948909..506f5bf6d082 100644
--- a/sound/soc/samsung/dmaengine.c
+++ b/sound/soc/samsung/dmaengine.c
@@ -17,6 +17,7 @@
17 17
18#include <linux/module.h> 18#include <linux/module.h>
19#include <linux/amba/pl08x.h> 19#include <linux/amba/pl08x.h>
20#include <linux/platform_data/dma-s3c24xx.h>
20 21
21#include <sound/core.h> 22#include <sound/core.h>
22#include <sound/pcm.h> 23#include <sound/pcm.h>
@@ -29,6 +30,8 @@
29 30
30#ifdef CONFIG_ARCH_S3C64XX 31#ifdef CONFIG_ARCH_S3C64XX
31#define filter_fn pl08x_filter_id 32#define filter_fn pl08x_filter_id
33#elif defined(CONFIG_ARCH_S3C24XX)
34#define filter_fn s3c24xx_dma_filter
32#else 35#else
33#define filter_fn NULL 36#define filter_fn NULL
34#endif 37#endif
diff --git a/sound/soc/samsung/s3c-i2s-v2.c b/sound/soc/samsung/s3c-i2s-v2.c
index 0ff4bbe23af3..de6c321b8b68 100644
--- a/sound/soc/samsung/s3c-i2s-v2.c
+++ b/sound/soc/samsung/s3c-i2s-v2.c
@@ -392,8 +392,6 @@ static int s3c2412_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
392 int capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE); 392 int capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE);
393 unsigned long irqs; 393 unsigned long irqs;
394 int ret = 0; 394 int ret = 0;
395 struct s3c_dma_params *dma_data =
396 snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
397 395
398 pr_debug("Entered %s\n", __func__); 396 pr_debug("Entered %s\n", __func__);
399 397
@@ -424,13 +422,6 @@ static int s3c2412_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
424 422
425 local_irq_restore(irqs); 423 local_irq_restore(irqs);
426 424
427 /*
428 * Load the next buffer to DMA to meet the reqirement
429 * of the auto reload mechanism of S3C24XX.
430 * This call won't bother S3C64XX.
431 */
432 s3c2410_dma_ctrl(dma_data->channel, S3C2410_DMAOP_STARTED);
433
434 break; 425 break;
435 426
436 case SNDRV_PCM_TRIGGER_STOP: 427 case SNDRV_PCM_TRIGGER_STOP:
@@ -644,12 +635,6 @@ int s3c_i2sv2_probe(struct snd_soc_dai *dai,
644 /* record our i2s structure for later use in the callbacks */ 635 /* record our i2s structure for later use in the callbacks */
645 snd_soc_dai_set_drvdata(dai, i2s); 636 snd_soc_dai_set_drvdata(dai, i2s);
646 637
647 i2s->regs = ioremap(base, 0x100);
648 if (i2s->regs == NULL) {
649 dev_err(dev, "cannot ioremap registers\n");
650 return -ENXIO;
651 }
652
653 i2s->iis_pclk = clk_get(dev, "iis"); 638 i2s->iis_pclk = clk_get(dev, "iis");
654 if (IS_ERR(i2s->iis_pclk)) { 639 if (IS_ERR(i2s->iis_pclk)) {
655 dev_err(dev, "failed to get iis_clock\n"); 640 dev_err(dev, "failed to get iis_clock\n");
@@ -729,7 +714,7 @@ int s3c_i2sv2_register_component(struct device *dev, int id,
729 struct snd_soc_component_driver *cmp_drv, 714 struct snd_soc_component_driver *cmp_drv,
730 struct snd_soc_dai_driver *dai_drv) 715 struct snd_soc_dai_driver *dai_drv)
731{ 716{
732 struct snd_soc_dai_ops *ops = dai_drv->ops; 717 struct snd_soc_dai_ops *ops = (struct snd_soc_dai_ops *)dai_drv->ops;
733 718
734 ops->trigger = s3c2412_i2s_trigger; 719 ops->trigger = s3c2412_i2s_trigger;
735 if (!ops->hw_params) 720 if (!ops->hw_params)
diff --git a/sound/soc/samsung/s3c2412-i2s.c b/sound/soc/samsung/s3c2412-i2s.c
index 08c059be9104..d9d27cc0657c 100644
--- a/sound/soc/samsung/s3c2412-i2s.c
+++ b/sound/soc/samsung/s3c2412-i2s.c
@@ -33,25 +33,19 @@
33#include "regs-i2s-v2.h" 33#include "regs-i2s-v2.h"
34#include "s3c2412-i2s.h" 34#include "s3c2412-i2s.h"
35 35
36static struct s3c_dma_client s3c2412_dma_client_out = {
37 .name = "I2S PCM Stereo out"
38};
39
40static struct s3c_dma_client s3c2412_dma_client_in = {
41 .name = "I2S PCM Stereo in"
42};
43
44static struct s3c_dma_params s3c2412_i2s_pcm_stereo_out = { 36static struct s3c_dma_params s3c2412_i2s_pcm_stereo_out = {
45 .client = &s3c2412_dma_client_out, 37 .client =
38 (struct s3c_dma_client *)&s3c2412_i2s_pcm_stereo_out,
46 .channel = DMACH_I2S_OUT, 39 .channel = DMACH_I2S_OUT,
47 .dma_addr = S3C2410_PA_IIS + S3C2412_IISTXD, 40 .ch_name = "tx",
48 .dma_size = 4, 41 .dma_size = 4,
49}; 42};
50 43
51static struct s3c_dma_params s3c2412_i2s_pcm_stereo_in = { 44static struct s3c_dma_params s3c2412_i2s_pcm_stereo_in = {
52 .client = &s3c2412_dma_client_in, 45 .client =
46 (struct s3c_dma_client *)&s3c2412_i2s_pcm_stereo_in,
53 .channel = DMACH_I2S_IN, 47 .channel = DMACH_I2S_IN,
54 .dma_addr = S3C2410_PA_IIS + S3C2412_IISRXD, 48 .ch_name = "rx",
55 .dma_size = 4, 49 .dma_size = 4,
56}; 50};
57 51
@@ -63,6 +57,9 @@ static int s3c2412_i2s_probe(struct snd_soc_dai *dai)
63 57
64 pr_debug("Entered %s\n", __func__); 58 pr_debug("Entered %s\n", __func__);
65 59
60 samsung_asoc_init_dma_data(dai, &s3c2412_i2s_pcm_stereo_out,
61 &s3c2412_i2s_pcm_stereo_in);
62
66 ret = s3c_i2sv2_probe(dai, &s3c2412_i2s, S3C2410_PA_IIS); 63 ret = s3c_i2sv2_probe(dai, &s3c2412_i2s, S3C2410_PA_IIS);
67 if (ret) 64 if (ret)
68 return ret; 65 return ret;
@@ -70,10 +67,9 @@ static int s3c2412_i2s_probe(struct snd_soc_dai *dai)
70 s3c2412_i2s.dma_capture = &s3c2412_i2s_pcm_stereo_in; 67 s3c2412_i2s.dma_capture = &s3c2412_i2s_pcm_stereo_in;
71 s3c2412_i2s.dma_playback = &s3c2412_i2s_pcm_stereo_out; 68 s3c2412_i2s.dma_playback = &s3c2412_i2s_pcm_stereo_out;
72 69
73 s3c2412_i2s.iis_cclk = clk_get(dai->dev, "i2sclk"); 70 s3c2412_i2s.iis_cclk = devm_clk_get(dai->dev, "i2sclk");
74 if (IS_ERR(s3c2412_i2s.iis_cclk)) { 71 if (IS_ERR(s3c2412_i2s.iis_cclk)) {
75 pr_err("failed to get i2sclk clock\n"); 72 pr_err("failed to get i2sclk clock\n");
76 iounmap(s3c2412_i2s.regs);
77 return PTR_ERR(s3c2412_i2s.iis_cclk); 73 return PTR_ERR(s3c2412_i2s.iis_cclk);
78 } 74 }
79 75
@@ -94,8 +90,6 @@ static int s3c2412_i2s_probe(struct snd_soc_dai *dai)
94static int s3c2412_i2s_remove(struct snd_soc_dai *dai) 90static int s3c2412_i2s_remove(struct snd_soc_dai *dai)
95{ 91{
96 clk_disable(s3c2412_i2s.iis_cclk); 92 clk_disable(s3c2412_i2s.iis_cclk);
97 clk_put(s3c2412_i2s.iis_cclk);
98 iounmap(s3c2412_i2s.regs);
99 93
100 return 0; 94 return 0;
101} 95}
@@ -105,18 +99,10 @@ static int s3c2412_i2s_hw_params(struct snd_pcm_substream *substream,
105 struct snd_soc_dai *cpu_dai) 99 struct snd_soc_dai *cpu_dai)
106{ 100{
107 struct s3c_i2sv2_info *i2s = snd_soc_dai_get_drvdata(cpu_dai); 101 struct s3c_i2sv2_info *i2s = snd_soc_dai_get_drvdata(cpu_dai);
108 struct s3c_dma_params *dma_data;
109 u32 iismod; 102 u32 iismod;
110 103
111 pr_debug("Entered %s\n", __func__); 104 pr_debug("Entered %s\n", __func__);
112 105
113 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
114 dma_data = i2s->dma_playback;
115 else
116 dma_data = i2s->dma_capture;
117
118 snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data);
119
120 iismod = readl(i2s->regs + S3C2412_IISMOD); 106 iismod = readl(i2s->regs + S3C2412_IISMOD);
121 pr_debug("%s: r: IISMOD: %x\n", __func__, iismod); 107 pr_debug("%s: r: IISMOD: %x\n", __func__, iismod);
122 108
@@ -169,6 +155,19 @@ static const struct snd_soc_component_driver s3c2412_i2s_component = {
169static int s3c2412_iis_dev_probe(struct platform_device *pdev) 155static int s3c2412_iis_dev_probe(struct platform_device *pdev)
170{ 156{
171 int ret = 0; 157 int ret = 0;
158 struct resource *res;
159
160 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
161 if (!res) {
162 dev_err(&pdev->dev, "Can't get IO resource.\n");
163 return -ENOENT;
164 }
165 s3c2412_i2s.regs = devm_ioremap_resource(&pdev->dev, res);
166 if (s3c2412_i2s.regs == NULL)
167 return -ENXIO;
168
169 s3c2412_i2s_pcm_stereo_out.dma_addr = res->start + S3C2412_IISTXD;
170 s3c2412_i2s_pcm_stereo_in.dma_addr = res->start + S3C2412_IISRXD;
172 171
173 ret = s3c_i2sv2_register_component(&pdev->dev, -1, 172 ret = s3c_i2sv2_register_component(&pdev->dev, -1,
174 &s3c2412_i2s_component, 173 &s3c2412_i2s_component,
diff --git a/sound/soc/samsung/s3c24xx-i2s.c b/sound/soc/samsung/s3c24xx-i2s.c
index 9aba9fb7df0e..6f3ee87da722 100644
--- a/sound/soc/samsung/s3c24xx-i2s.c
+++ b/sound/soc/samsung/s3c24xx-i2s.c
@@ -31,25 +31,19 @@
31#include "dma.h" 31#include "dma.h"
32#include "s3c24xx-i2s.h" 32#include "s3c24xx-i2s.h"
33 33
34static struct s3c_dma_client s3c24xx_dma_client_out = {
35 .name = "I2S PCM Stereo out"
36};
37
38static struct s3c_dma_client s3c24xx_dma_client_in = {
39 .name = "I2S PCM Stereo in"
40};
41
42static struct s3c_dma_params s3c24xx_i2s_pcm_stereo_out = { 34static struct s3c_dma_params s3c24xx_i2s_pcm_stereo_out = {
43 .client = &s3c24xx_dma_client_out, 35 .client =
36 (struct s3c_dma_client *)&s3c24xx_i2s_pcm_stereo_out,
44 .channel = DMACH_I2S_OUT, 37 .channel = DMACH_I2S_OUT,
45 .dma_addr = S3C2410_PA_IIS + S3C2410_IISFIFO, 38 .ch_name = "tx",
46 .dma_size = 2, 39 .dma_size = 2,
47}; 40};
48 41
49static struct s3c_dma_params s3c24xx_i2s_pcm_stereo_in = { 42static struct s3c_dma_params s3c24xx_i2s_pcm_stereo_in = {
50 .client = &s3c24xx_dma_client_in, 43 .client =
44 (struct s3c_dma_client *)&s3c24xx_i2s_pcm_stereo_in,
51 .channel = DMACH_I2S_IN, 45 .channel = DMACH_I2S_IN,
52 .dma_addr = S3C2410_PA_IIS + S3C2410_IISFIFO, 46 .ch_name = "rx",
53 .dma_size = 2, 47 .dma_size = 2,
54}; 48};
55 49
@@ -231,18 +225,12 @@ static int s3c24xx_i2s_hw_params(struct snd_pcm_substream *substream,
231 struct snd_pcm_hw_params *params, 225 struct snd_pcm_hw_params *params,
232 struct snd_soc_dai *dai) 226 struct snd_soc_dai *dai)
233{ 227{
234 struct snd_soc_pcm_runtime *rtd = substream->private_data; 228 struct snd_dmaengine_dai_dma_data *dma_data;
235 struct s3c_dma_params *dma_data;
236 u32 iismod; 229 u32 iismod;
237 230
238 pr_debug("Entered %s\n", __func__); 231 pr_debug("Entered %s\n", __func__);
239 232
240 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 233 dma_data = snd_soc_dai_get_dma_data(dai, substream);
241 dma_data = &s3c24xx_i2s_pcm_stereo_out;
242 else
243 dma_data = &s3c24xx_i2s_pcm_stereo_in;
244
245 snd_soc_dai_set_dma_data(rtd->cpu_dai, substream, dma_data);
246 234
247 /* Working copies of register */ 235 /* Working copies of register */
248 iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD); 236 iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD);
@@ -251,11 +239,11 @@ static int s3c24xx_i2s_hw_params(struct snd_pcm_substream *substream,
251 switch (params_width(params)) { 239 switch (params_width(params)) {
252 case 8: 240 case 8:
253 iismod &= ~S3C2410_IISMOD_16BIT; 241 iismod &= ~S3C2410_IISMOD_16BIT;
254 dma_data->dma_size = 1; 242 dma_data->addr_width = 1;
255 break; 243 break;
256 case 16: 244 case 16:
257 iismod |= S3C2410_IISMOD_16BIT; 245 iismod |= S3C2410_IISMOD_16BIT;
258 dma_data->dma_size = 2; 246 dma_data->addr_width = 2;
259 break; 247 break;
260 default: 248 default:
261 return -EINVAL; 249 return -EINVAL;
@@ -270,8 +258,6 @@ static int s3c24xx_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
270 struct snd_soc_dai *dai) 258 struct snd_soc_dai *dai)
271{ 259{
272 int ret = 0; 260 int ret = 0;
273 struct s3c_dma_params *dma_data =
274 snd_soc_dai_get_dma_data(dai, substream);
275 261
276 pr_debug("Entered %s\n", __func__); 262 pr_debug("Entered %s\n", __func__);
277 263
@@ -290,7 +276,6 @@ static int s3c24xx_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
290 else 276 else
291 s3c24xx_snd_txctrl(1); 277 s3c24xx_snd_txctrl(1);
292 278
293 s3c2410_dma_ctrl(dma_data->channel, S3C2410_DMAOP_STARTED);
294 break; 279 break;
295 case SNDRV_PCM_TRIGGER_STOP: 280 case SNDRV_PCM_TRIGGER_STOP:
296 case SNDRV_PCM_TRIGGER_SUSPEND: 281 case SNDRV_PCM_TRIGGER_SUSPEND:
@@ -380,14 +365,12 @@ static int s3c24xx_i2s_probe(struct snd_soc_dai *dai)
380{ 365{
381 pr_debug("Entered %s\n", __func__); 366 pr_debug("Entered %s\n", __func__);
382 367
383 s3c24xx_i2s.regs = ioremap(S3C2410_PA_IIS, 0x100); 368 samsung_asoc_init_dma_data(dai, &s3c24xx_i2s_pcm_stereo_out,
384 if (s3c24xx_i2s.regs == NULL) 369 &s3c24xx_i2s_pcm_stereo_in);
385 return -ENXIO;
386 370
387 s3c24xx_i2s.iis_clk = clk_get(dai->dev, "iis"); 371 s3c24xx_i2s.iis_clk = devm_clk_get(dai->dev, "iis");
388 if (IS_ERR(s3c24xx_i2s.iis_clk)) { 372 if (IS_ERR(s3c24xx_i2s.iis_clk)) {
389 pr_err("failed to get iis_clock\n"); 373 pr_err("failed to get iis_clock\n");
390 iounmap(s3c24xx_i2s.regs);
391 return PTR_ERR(s3c24xx_i2s.iis_clk); 374 return PTR_ERR(s3c24xx_i2s.iis_clk);
392 } 375 }
393 clk_enable(s3c24xx_i2s.iis_clk); 376 clk_enable(s3c24xx_i2s.iis_clk);
@@ -474,6 +457,19 @@ static const struct snd_soc_component_driver s3c24xx_i2s_component = {
474static int s3c24xx_iis_dev_probe(struct platform_device *pdev) 457static int s3c24xx_iis_dev_probe(struct platform_device *pdev)
475{ 458{
476 int ret = 0; 459 int ret = 0;
460 struct resource *res;
461
462 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
463 if (!res) {
464 dev_err(&pdev->dev, "Can't get IO resource.\n");
465 return -ENOENT;
466 }
467 s3c24xx_i2s.regs = devm_ioremap_resource(&pdev->dev, res);
468 if (s3c24xx_i2s.regs == NULL)
469 return -ENXIO;
470
471 s3c24xx_i2s_pcm_stereo_out.dma_addr = res->start + S3C2410_IISFIFO;
472 s3c24xx_i2s_pcm_stereo_in.dma_addr = res->start + S3C2410_IISFIFO;
477 473
478 ret = devm_snd_soc_register_component(&pdev->dev, 474 ret = devm_snd_soc_register_component(&pdev->dev,
479 &s3c24xx_i2s_component, &s3c24xx_i2s_dai, 1); 475 &s3c24xx_i2s_component, &s3c24xx_i2s_dai, 1);