aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2013-04-12 08:57:04 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2013-04-12 08:57:04 -0400
commit38e8c895d33b0642dc341f83cce0adde4cffbc82 (patch)
tree3657c043986d5c944f971c9685ae4a68f5a5b035
parentd66e065c5b8b64b03a9d9b8a7c5d674c7dfa2e3d (diff)
parent69b6f19622ce0aef41df884b75e3f789c64b89c0 (diff)
Merge remote-tracking branch 'asoc/topic/dma' into asoc-next
-rw-r--r--include/sound/dmaengine_pcm.h27
-rw-r--r--sound/soc/atmel/atmel-pcm-dma.c25
-rw-r--r--sound/soc/cirrus/edb93xx.c1
-rw-r--r--sound/soc/cirrus/ep93xx-ac97.c9
-rw-r--r--sound/soc/cirrus/ep93xx-i2s.c16
-rw-r--r--sound/soc/cirrus/ep93xx-pcm.c37
-rw-r--r--sound/soc/cirrus/ep93xx-pcm.h20
-rw-r--r--sound/soc/cirrus/simone.c2
-rw-r--r--sound/soc/cirrus/snappercl15.c1
-rw-r--r--sound/soc/fsl/fsl_ssi.c36
-rw-r--r--sound/soc/fsl/imx-pcm-dma.c58
-rw-r--r--sound/soc/fsl/imx-pcm-fiq.c4
-rw-r--r--sound/soc/fsl/imx-pcm.h19
-rw-r--r--sound/soc/fsl/imx-ssi.c29
-rw-r--r--sound/soc/fsl/imx-ssi.h7
-rw-r--r--sound/soc/mxs/mxs-pcm.c43
-rw-r--r--sound/soc/mxs/mxs-pcm.h4
-rw-r--r--sound/soc/mxs/mxs-saif.c6
-rw-r--r--sound/soc/omap/am3517evm.c1
-rw-r--r--sound/soc/omap/ams-delta.c1
-rw-r--r--sound/soc/omap/mcbsp.c14
-rw-r--r--sound/soc/omap/mcbsp.h7
-rw-r--r--sound/soc/omap/n810.c1
-rw-r--r--sound/soc/omap/omap-abe-twl6040.c1
-rw-r--r--sound/soc/omap/omap-dmic.c38
-rw-r--r--sound/soc/omap/omap-hdmi.c24
-rw-r--r--sound/soc/omap/omap-mcbsp.c18
-rw-r--r--sound/soc/omap/omap-mcpdm.c109
-rw-r--r--sound/soc/omap/omap-pcm.c83
-rw-r--r--sound/soc/omap/omap-pcm.h40
-rw-r--r--sound/soc/omap/omap-twl4030.c1
-rw-r--r--sound/soc/omap/omap3pandora.c9
-rw-r--r--sound/soc/omap/osk5912.c1
-rw-r--r--sound/soc/omap/rx51.c1
-rw-r--r--sound/soc/pxa/mmp-pcm.c33
-rw-r--r--sound/soc/soc-dmaengine-pcm.c68
-rw-r--r--sound/soc/spear/spear_pcm.c18
-rw-r--r--sound/soc/tegra/tegra20_ac97.c13
-rw-r--r--sound/soc/tegra/tegra20_ac97.h4
-rw-r--r--sound/soc/tegra/tegra20_i2s.c13
-rw-r--r--sound/soc/tegra/tegra20_i2s.h4
-rw-r--r--sound/soc/tegra/tegra20_spdif.c7
-rw-r--r--sound/soc/tegra/tegra20_spdif.h4
-rw-r--r--sound/soc/tegra/tegra30_ahub.c8
-rw-r--r--sound/soc/tegra/tegra30_ahub.h8
-rw-r--r--sound/soc/tegra/tegra30_i2s.c13
-rw-r--r--sound/soc/tegra/tegra30_i2s.h4
-rw-r--r--sound/soc/tegra/tegra_pcm.c24
-rw-r--r--sound/soc/tegra/tegra_pcm.h7
-rw-r--r--sound/soc/ux500/ux500_pcm.c76
-rw-r--r--sound/soc/ux500/ux500_pcm.h14
51 files changed, 356 insertions, 655 deletions
diff --git a/include/sound/dmaengine_pcm.h b/include/sound/dmaengine_pcm.h
index b877334bbb0f..95620428a59b 100644
--- a/include/sound/dmaengine_pcm.h
+++ b/include/sound/dmaengine_pcm.h
@@ -32,9 +32,6 @@ snd_pcm_substream_to_dma_direction(const struct snd_pcm_substream *substream)
32 return DMA_DEV_TO_MEM; 32 return DMA_DEV_TO_MEM;
33} 33}
34 34
35void snd_dmaengine_pcm_set_data(struct snd_pcm_substream *substream, void *data);
36void *snd_dmaengine_pcm_get_data(struct snd_pcm_substream *substream);
37
38int snd_hwparams_to_dma_slave_config(const struct snd_pcm_substream *substream, 35int snd_hwparams_to_dma_slave_config(const struct snd_pcm_substream *substream,
39 const struct snd_pcm_hw_params *params, struct dma_slave_config *slave_config); 36 const struct snd_pcm_hw_params *params, struct dma_slave_config *slave_config);
40int snd_dmaengine_pcm_trigger(struct snd_pcm_substream *substream, int cmd); 37int snd_dmaengine_pcm_trigger(struct snd_pcm_substream *substream, int cmd);
@@ -47,4 +44,28 @@ int snd_dmaengine_pcm_close(struct snd_pcm_substream *substream);
47 44
48struct dma_chan *snd_dmaengine_pcm_get_chan(struct snd_pcm_substream *substream); 45struct dma_chan *snd_dmaengine_pcm_get_chan(struct snd_pcm_substream *substream);
49 46
47/**
48 * struct snd_dmaengine_dai_dma_data - DAI DMA configuration data
49 * @addr: Address of the DAI data source or destination register.
50 * @addr_width: Width of the DAI data source or destination register.
51 * @maxburst: Maximum number of words(note: words, as in units of the
52 * src_addr_width member, not bytes) that can be send to or received from the
53 * DAI in one burst.
54 * @slave_id: Slave requester id for the DMA channel.
55 * @filter_data: Custom DMA channel filter data, this will usually be used when
56 * requesting the DMA channel.
57 */
58struct snd_dmaengine_dai_dma_data {
59 dma_addr_t addr;
60 enum dma_slave_buswidth addr_width;
61 u32 maxburst;
62 unsigned int slave_id;
63 void *filter_data;
64};
65
66void snd_dmaengine_pcm_set_config_from_dai_data(
67 const struct snd_pcm_substream *substream,
68 const struct snd_dmaengine_dai_dma_data *dma_data,
69 struct dma_slave_config *config);
70
50#endif 71#endif
diff --git a/sound/soc/atmel/atmel-pcm-dma.c b/sound/soc/atmel/atmel-pcm-dma.c
index 30184a4a147a..bb07989762d5 100644
--- a/sound/soc/atmel/atmel-pcm-dma.c
+++ b/sound/soc/atmel/atmel-pcm-dma.c
@@ -67,9 +67,10 @@ static const struct snd_pcm_hardware atmel_pcm_dma_hardware = {
67static void atmel_pcm_dma_irq(u32 ssc_sr, 67static void atmel_pcm_dma_irq(u32 ssc_sr,
68 struct snd_pcm_substream *substream) 68 struct snd_pcm_substream *substream)
69{ 69{
70 struct snd_soc_pcm_runtime *rtd = substream->private_data;
70 struct atmel_pcm_dma_params *prtd; 71 struct atmel_pcm_dma_params *prtd;
71 72
72 prtd = snd_dmaengine_pcm_get_data(substream); 73 prtd = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
73 74
74 if (ssc_sr & prtd->mask->ssc_error) { 75 if (ssc_sr & prtd->mask->ssc_error) {
75 if (snd_pcm_running(substream)) 76 if (snd_pcm_running(substream))
@@ -104,15 +105,13 @@ static bool filter(struct dma_chan *chan, void *slave)
104} 105}
105 106
106static int atmel_pcm_configure_dma(struct snd_pcm_substream *substream, 107static int atmel_pcm_configure_dma(struct snd_pcm_substream *substream,
107 struct snd_pcm_hw_params *params) 108 struct snd_pcm_hw_params *params, struct atmel_pcm_dma_params *prtd)
108{ 109{
109 struct atmel_pcm_dma_params *prtd;
110 struct ssc_device *ssc; 110 struct ssc_device *ssc;
111 struct dma_chan *dma_chan; 111 struct dma_chan *dma_chan;
112 struct dma_slave_config slave_config; 112 struct dma_slave_config slave_config;
113 int ret; 113 int ret;
114 114
115 prtd = snd_dmaengine_pcm_get_data(substream);
116 ssc = prtd->ssc; 115 ssc = prtd->ssc;
117 116
118 ret = snd_hwparams_to_dma_slave_config(substream, params, 117 ret = snd_hwparams_to_dma_slave_config(substream, params,
@@ -130,8 +129,6 @@ static int atmel_pcm_configure_dma(struct snd_pcm_substream *substream,
130 slave_config.src_maxburst = 1; 129 slave_config.src_maxburst = 1;
131 } 130 }
132 131
133 slave_config.device_fc = false;
134
135 dma_chan = snd_dmaengine_pcm_get_chan(substream); 132 dma_chan = snd_dmaengine_pcm_get_chan(substream);
136 if (dmaengine_slave_config(dma_chan, &slave_config)) { 133 if (dmaengine_slave_config(dma_chan, &slave_config)) {
137 pr_err("atmel-pcm: failed to configure dma channel\n"); 134 pr_err("atmel-pcm: failed to configure dma channel\n");
@@ -164,9 +161,7 @@ static int atmel_pcm_hw_params(struct snd_pcm_substream *substream,
164 return -EINVAL; 161 return -EINVAL;
165 } 162 }
166 163
167 snd_dmaengine_pcm_set_data(substream, prtd); 164 ret = atmel_pcm_configure_dma(substream, params, prtd);
168
169 ret = atmel_pcm_configure_dma(substream, params);
170 if (ret) { 165 if (ret) {
171 pr_err("atmel-pcm: failed to configure dmai\n"); 166 pr_err("atmel-pcm: failed to configure dmai\n");
172 goto err; 167 goto err;
@@ -182,9 +177,10 @@ err:
182 177
183static int atmel_pcm_dma_prepare(struct snd_pcm_substream *substream) 178static int atmel_pcm_dma_prepare(struct snd_pcm_substream *substream)
184{ 179{
180 struct snd_soc_pcm_runtime *rtd = substream->private_data;
185 struct atmel_pcm_dma_params *prtd; 181 struct atmel_pcm_dma_params *prtd;
186 182
187 prtd = snd_dmaengine_pcm_get_data(substream); 183 prtd = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
188 184
189 ssc_writex(prtd->ssc->regs, SSC_IER, prtd->mask->ssc_error); 185 ssc_writex(prtd->ssc->regs, SSC_IER, prtd->mask->ssc_error);
190 ssc_writex(prtd->ssc->regs, SSC_CR, prtd->mask->ssc_enable); 186 ssc_writex(prtd->ssc->regs, SSC_CR, prtd->mask->ssc_enable);
@@ -199,16 +195,9 @@ static int atmel_pcm_open(struct snd_pcm_substream *substream)
199 return 0; 195 return 0;
200} 196}
201 197
202static int atmel_pcm_close(struct snd_pcm_substream *substream)
203{
204 snd_dmaengine_pcm_close(substream);
205
206 return 0;
207}
208
209static struct snd_pcm_ops atmel_pcm_ops = { 198static struct snd_pcm_ops atmel_pcm_ops = {
210 .open = atmel_pcm_open, 199 .open = atmel_pcm_open,
211 .close = atmel_pcm_close, 200 .close = snd_dmaengine_pcm_close,
212 .ioctl = snd_pcm_lib_ioctl, 201 .ioctl = snd_pcm_lib_ioctl,
213 .hw_params = atmel_pcm_hw_params, 202 .hw_params = atmel_pcm_hw_params,
214 .prepare = atmel_pcm_dma_prepare, 203 .prepare = atmel_pcm_dma_prepare,
diff --git a/sound/soc/cirrus/edb93xx.c b/sound/soc/cirrus/edb93xx.c
index 5db68cf7b281..c43fb214558a 100644
--- a/sound/soc/cirrus/edb93xx.c
+++ b/sound/soc/cirrus/edb93xx.c
@@ -27,7 +27,6 @@
27#include <sound/soc.h> 27#include <sound/soc.h>
28#include <asm/mach-types.h> 28#include <asm/mach-types.h>
29#include <mach/hardware.h> 29#include <mach/hardware.h>
30#include "ep93xx-pcm.h"
31 30
32static int edb93xx_hw_params(struct snd_pcm_substream *substream, 31static int edb93xx_hw_params(struct snd_pcm_substream *substream,
33 struct snd_pcm_hw_params *params) 32 struct snd_pcm_hw_params *params)
diff --git a/sound/soc/cirrus/ep93xx-ac97.c b/sound/soc/cirrus/ep93xx-ac97.c
index e593c1e4e1dd..7798fbd5e81d 100644
--- a/sound/soc/cirrus/ep93xx-ac97.c
+++ b/sound/soc/cirrus/ep93xx-ac97.c
@@ -23,7 +23,6 @@
23#include <sound/soc.h> 23#include <sound/soc.h>
24 24
25#include <linux/platform_data/dma-ep93xx.h> 25#include <linux/platform_data/dma-ep93xx.h>
26#include "ep93xx-pcm.h"
27 26
28/* 27/*
29 * Per channel (1-4) registers. 28 * Per channel (1-4) registers.
@@ -101,14 +100,16 @@ struct ep93xx_ac97_info {
101/* currently ALSA only supports a single AC97 device */ 100/* currently ALSA only supports a single AC97 device */
102static struct ep93xx_ac97_info *ep93xx_ac97_info; 101static struct ep93xx_ac97_info *ep93xx_ac97_info;
103 102
104static struct ep93xx_pcm_dma_params ep93xx_ac97_pcm_out = { 103static struct ep93xx_dma_data ep93xx_ac97_pcm_out = {
105 .name = "ac97-pcm-out", 104 .name = "ac97-pcm-out",
106 .dma_port = EP93XX_DMA_AAC1, 105 .dma_port = EP93XX_DMA_AAC1,
106 .direction = DMA_MEM_TO_DEV,
107}; 107};
108 108
109static struct ep93xx_pcm_dma_params ep93xx_ac97_pcm_in = { 109static struct ep93xx_dma_data ep93xx_ac97_pcm_in = {
110 .name = "ac97-pcm-in", 110 .name = "ac97-pcm-in",
111 .dma_port = EP93XX_DMA_AAC1, 111 .dma_port = EP93XX_DMA_AAC1,
112 .direction = DMA_DEV_TO_MEM,
112}; 113};
113 114
114static inline unsigned ep93xx_ac97_read_reg(struct ep93xx_ac97_info *info, 115static inline unsigned ep93xx_ac97_read_reg(struct ep93xx_ac97_info *info,
@@ -316,7 +317,7 @@ static int ep93xx_ac97_trigger(struct snd_pcm_substream *substream,
316static int ep93xx_ac97_startup(struct snd_pcm_substream *substream, 317static int ep93xx_ac97_startup(struct snd_pcm_substream *substream,
317 struct snd_soc_dai *dai) 318 struct snd_soc_dai *dai)
318{ 319{
319 struct ep93xx_pcm_dma_params *dma_data; 320 struct ep93xx_dma_data *dma_data;
320 321
321 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 322 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
322 dma_data = &ep93xx_ac97_pcm_out; 323 dma_data = &ep93xx_ac97_pcm_out;
diff --git a/sound/soc/cirrus/ep93xx-i2s.c b/sound/soc/cirrus/ep93xx-i2s.c
index 8d244be275d6..5c1102e9e159 100644
--- a/sound/soc/cirrus/ep93xx-i2s.c
+++ b/sound/soc/cirrus/ep93xx-i2s.c
@@ -30,8 +30,6 @@
30#include <mach/ep93xx-regs.h> 30#include <mach/ep93xx-regs.h>
31#include <linux/platform_data/dma-ep93xx.h> 31#include <linux/platform_data/dma-ep93xx.h>
32 32
33#include "ep93xx-pcm.h"
34
35#define EP93XX_I2S_TXCLKCFG 0x00 33#define EP93XX_I2S_TXCLKCFG 0x00
36#define EP93XX_I2S_RXCLKCFG 0x04 34#define EP93XX_I2S_RXCLKCFG 0x04
37#define EP93XX_I2S_GLCTRL 0x0C 35#define EP93XX_I2S_GLCTRL 0x0C
@@ -62,18 +60,20 @@ struct ep93xx_i2s_info {
62 struct clk *mclk; 60 struct clk *mclk;
63 struct clk *sclk; 61 struct clk *sclk;
64 struct clk *lrclk; 62 struct clk *lrclk;
65 struct ep93xx_pcm_dma_params *dma_params; 63 struct ep93xx_dma_data *dma_data;
66 void __iomem *regs; 64 void __iomem *regs;
67}; 65};
68 66
69struct ep93xx_pcm_dma_params ep93xx_i2s_dma_params[] = { 67struct ep93xx_dma_data ep93xx_i2s_dma_data[] = {
70 [SNDRV_PCM_STREAM_PLAYBACK] = { 68 [SNDRV_PCM_STREAM_PLAYBACK] = {
71 .name = "i2s-pcm-out", 69 .name = "i2s-pcm-out",
72 .dma_port = EP93XX_DMA_I2S1, 70 .port = EP93XX_DMA_I2S1,
71 .direction = DMA_MEM_TO_DEV,
73 }, 72 },
74 [SNDRV_PCM_STREAM_CAPTURE] = { 73 [SNDRV_PCM_STREAM_CAPTURE] = {
75 .name = "i2s-pcm-in", 74 .name = "i2s-pcm-in",
76 .dma_port = EP93XX_DMA_I2S1, 75 .port = EP93XX_DMA_I2S1,
76 .direction = DMA_DEV_TO_MEM,
77 }, 77 },
78}; 78};
79 79
@@ -147,7 +147,7 @@ static int ep93xx_i2s_startup(struct snd_pcm_substream *substream,
147 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 147 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
148 148
149 snd_soc_dai_set_dma_data(cpu_dai, substream, 149 snd_soc_dai_set_dma_data(cpu_dai, substream,
150 &info->dma_params[substream->stream]); 150 &info->dma_data[substream->stream]);
151 return 0; 151 return 0;
152} 152}
153 153
@@ -407,7 +407,7 @@ static int ep93xx_i2s_probe(struct platform_device *pdev)
407 } 407 }
408 408
409 dev_set_drvdata(&pdev->dev, info); 409 dev_set_drvdata(&pdev->dev, info);
410 info->dma_params = ep93xx_i2s_dma_params; 410 info->dma_data = ep93xx_i2s_dma_data;
411 411
412 err = snd_soc_register_component(&pdev->dev, &ep93xx_i2s_component, 412 err = snd_soc_register_component(&pdev->dev, &ep93xx_i2s_component,
413 &ep93xx_i2s_dai, 1); 413 &ep93xx_i2s_dai, 1);
diff --git a/sound/soc/cirrus/ep93xx-pcm.c b/sound/soc/cirrus/ep93xx-pcm.c
index 72eb7a49e16a..298946f790eb 100644
--- a/sound/soc/cirrus/ep93xx-pcm.c
+++ b/sound/soc/cirrus/ep93xx-pcm.c
@@ -29,8 +29,6 @@
29#include <mach/hardware.h> 29#include <mach/hardware.h>
30#include <mach/ep93xx-regs.h> 30#include <mach/ep93xx-regs.h>
31 31
32#include "ep93xx-pcm.h"
33
34static const struct snd_pcm_hardware ep93xx_pcm_hardware = { 32static const struct snd_pcm_hardware ep93xx_pcm_hardware = {
35 .info = (SNDRV_PCM_INFO_MMAP | 33 .info = (SNDRV_PCM_INFO_MMAP |
36 SNDRV_PCM_INFO_MMAP_VALID | 34 SNDRV_PCM_INFO_MMAP_VALID |
@@ -68,40 +66,11 @@ static bool ep93xx_pcm_dma_filter(struct dma_chan *chan, void *filter_param)
68static int ep93xx_pcm_open(struct snd_pcm_substream *substream) 66static int ep93xx_pcm_open(struct snd_pcm_substream *substream)
69{ 67{
70 struct snd_soc_pcm_runtime *rtd = substream->private_data; 68 struct snd_soc_pcm_runtime *rtd = substream->private_data;
71 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
72 struct ep93xx_pcm_dma_params *dma_params;
73 struct ep93xx_dma_data *dma_data;
74 int ret;
75 69
76 snd_soc_set_runtime_hwparams(substream, &ep93xx_pcm_hardware); 70 snd_soc_set_runtime_hwparams(substream, &ep93xx_pcm_hardware);
77 71
78 dma_data = kmalloc(sizeof(*dma_data), GFP_KERNEL); 72 return snd_dmaengine_pcm_open(substream, ep93xx_pcm_dma_filter,
79 if (!dma_data) 73 snd_soc_dai_get_dma_data(rtd->cpu_dai, substream));
80 return -ENOMEM;
81
82 dma_params = snd_soc_dai_get_dma_data(cpu_dai, substream);
83 dma_data->port = dma_params->dma_port;
84 dma_data->name = dma_params->name;
85 dma_data->direction = snd_pcm_substream_to_dma_direction(substream);
86
87 ret = snd_dmaengine_pcm_open(substream, ep93xx_pcm_dma_filter, dma_data);
88 if (ret) {
89 kfree(dma_data);
90 return ret;
91 }
92
93 snd_dmaengine_pcm_set_data(substream, dma_data);
94
95 return 0;
96}
97
98static int ep93xx_pcm_close(struct snd_pcm_substream *substream)
99{
100 struct dma_data *dma_data = snd_dmaengine_pcm_get_data(substream);
101
102 snd_dmaengine_pcm_close(substream);
103 kfree(dma_data);
104 return 0;
105} 74}
106 75
107static int ep93xx_pcm_hw_params(struct snd_pcm_substream *substream, 76static int ep93xx_pcm_hw_params(struct snd_pcm_substream *substream,
@@ -131,7 +100,7 @@ static int ep93xx_pcm_mmap(struct snd_pcm_substream *substream,
131 100
132static struct snd_pcm_ops ep93xx_pcm_ops = { 101static struct snd_pcm_ops ep93xx_pcm_ops = {
133 .open = ep93xx_pcm_open, 102 .open = ep93xx_pcm_open,
134 .close = ep93xx_pcm_close, 103 .close = snd_dmaengine_pcm_close,
135 .ioctl = snd_pcm_lib_ioctl, 104 .ioctl = snd_pcm_lib_ioctl,
136 .hw_params = ep93xx_pcm_hw_params, 105 .hw_params = ep93xx_pcm_hw_params,
137 .hw_free = ep93xx_pcm_hw_free, 106 .hw_free = ep93xx_pcm_hw_free,
diff --git a/sound/soc/cirrus/ep93xx-pcm.h b/sound/soc/cirrus/ep93xx-pcm.h
deleted file mode 100644
index 111e1121ecb8..000000000000
--- a/sound/soc/cirrus/ep93xx-pcm.h
+++ /dev/null
@@ -1,20 +0,0 @@
1/*
2 * sound/soc/ep93xx/ep93xx-pcm.h - EP93xx ALSA PCM interface
3 *
4 * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org>
5 * Copyright (C) 2006 Applied Data Systems
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#ifndef _EP93XX_SND_SOC_PCM_H
13#define _EP93XX_SND_SOC_PCM_H
14
15struct ep93xx_pcm_dma_params {
16 char *name;
17 int dma_port;
18};
19
20#endif /* _EP93XX_SND_SOC_PCM_H */
diff --git a/sound/soc/cirrus/simone.c b/sound/soc/cirrus/simone.c
index a397bb0d8179..4d094d00c34a 100644
--- a/sound/soc/cirrus/simone.c
+++ b/sound/soc/cirrus/simone.c
@@ -21,8 +21,6 @@
21#include <asm/mach-types.h> 21#include <asm/mach-types.h>
22#include <mach/hardware.h> 22#include <mach/hardware.h>
23 23
24#include "ep93xx-pcm.h"
25
26static struct snd_soc_dai_link simone_dai = { 24static struct snd_soc_dai_link simone_dai = {
27 .name = "AC97", 25 .name = "AC97",
28 .stream_name = "AC97 HiFi", 26 .stream_name = "AC97 HiFi",
diff --git a/sound/soc/cirrus/snappercl15.c b/sound/soc/cirrus/snappercl15.c
index 9d77fe28dfcc..69041074f2c1 100644
--- a/sound/soc/cirrus/snappercl15.c
+++ b/sound/soc/cirrus/snappercl15.c
@@ -21,7 +21,6 @@
21#include <mach/hardware.h> 21#include <mach/hardware.h>
22 22
23#include "../codecs/tlv320aic23.h" 23#include "../codecs/tlv320aic23.h"
24#include "ep93xx-pcm.h"
25 24
26#define CODEC_CLOCK 5644800 25#define CODEC_CLOCK 5644800
27 26
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index fe04c67f8fb8..42366d776f62 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -27,6 +27,7 @@
27#include <sound/pcm_params.h> 27#include <sound/pcm_params.h>
28#include <sound/initval.h> 28#include <sound/initval.h>
29#include <sound/soc.h> 29#include <sound/soc.h>
30#include <sound/dmaengine_pcm.h>
30 31
31#include "fsl_ssi.h" 32#include "fsl_ssi.h"
32#include "imx-pcm.h" 33#include "imx-pcm.h"
@@ -122,8 +123,10 @@ struct fsl_ssi_private {
122 bool ssi_on_imx; 123 bool ssi_on_imx;
123 struct clk *clk; 124 struct clk *clk;
124 struct platform_device *imx_pcm_pdev; 125 struct platform_device *imx_pcm_pdev;
125 struct imx_pcm_dma_params dma_params_tx; 126 struct snd_dmaengine_dai_dma_data dma_params_tx;
126 struct imx_pcm_dma_params dma_params_rx; 127 struct snd_dmaengine_dai_dma_data dma_params_rx;
128 struct imx_dma_data filter_data_tx;
129 struct imx_dma_data filter_data_rx;
127 130
128 struct { 131 struct {
129 unsigned int rfrc; 132 unsigned int rfrc;
@@ -653,6 +656,7 @@ static int fsl_ssi_probe(struct platform_device *pdev)
653 const uint32_t *iprop; 656 const uint32_t *iprop;
654 struct resource res; 657 struct resource res;
655 char name[64]; 658 char name[64];
659 bool shared;
656 660
657 /* SSIs that are not connected on the board should have a 661 /* SSIs that are not connected on the board should have a
658 * status = "disabled" 662 * status = "disabled"
@@ -741,14 +745,18 @@ static int fsl_ssi_probe(struct platform_device *pdev)
741 * We have burstsize be "fifo_depth - 2" to match the SSI 745 * We have burstsize be "fifo_depth - 2" to match the SSI
742 * watermark setting in fsl_ssi_startup(). 746 * watermark setting in fsl_ssi_startup().
743 */ 747 */
744 ssi_private->dma_params_tx.burstsize = 748 ssi_private->dma_params_tx.maxburst =
745 ssi_private->fifo_depth - 2; 749 ssi_private->fifo_depth - 2;
746 ssi_private->dma_params_rx.burstsize = 750 ssi_private->dma_params_rx.maxburst =
747 ssi_private->fifo_depth - 2; 751 ssi_private->fifo_depth - 2;
748 ssi_private->dma_params_tx.dma_addr = 752 ssi_private->dma_params_tx.addr =
749 ssi_private->ssi_phys + offsetof(struct ccsr_ssi, stx0); 753 ssi_private->ssi_phys + offsetof(struct ccsr_ssi, stx0);
750 ssi_private->dma_params_rx.dma_addr = 754 ssi_private->dma_params_rx.addr =
751 ssi_private->ssi_phys + offsetof(struct ccsr_ssi, srx0); 755 ssi_private->ssi_phys + offsetof(struct ccsr_ssi, srx0);
756 ssi_private->dma_params_tx.filter_data =
757 &ssi_private->filter_data_tx;
758 ssi_private->dma_params_rx.filter_data =
759 &ssi_private->filter_data_rx;
752 /* 760 /*
753 * TODO: This is a temporary solution and should be changed 761 * TODO: This is a temporary solution and should be changed
754 * to use generic DMA binding later when the helplers get in. 762 * to use generic DMA binding later when the helplers get in.
@@ -759,14 +767,14 @@ static int fsl_ssi_probe(struct platform_device *pdev)
759 dev_err(&pdev->dev, "could not get dma events\n"); 767 dev_err(&pdev->dev, "could not get dma events\n");
760 goto error_clk; 768 goto error_clk;
761 } 769 }
762 ssi_private->dma_params_tx.dma = dma_events[0]; 770
763 ssi_private->dma_params_rx.dma = dma_events[1]; 771 shared = of_device_is_compatible(of_get_parent(np),
764 772 "fsl,spba-bus");
765 ssi_private->dma_params_tx.shared_peripheral = 773
766 of_device_is_compatible(of_get_parent(np), 774 imx_pcm_dma_params_init_data(&ssi_private->filter_data_tx,
767 "fsl,spba-bus"); 775 dma_events[0], shared);
768 ssi_private->dma_params_rx.shared_peripheral = 776 imx_pcm_dma_params_init_data(&ssi_private->filter_data_rx,
769 ssi_private->dma_params_tx.shared_peripheral; 777 dma_events[1], shared);
770 } 778 }
771 779
772 /* Initialize the the device_attribute structure */ 780 /* Initialize the the device_attribute structure */
diff --git a/sound/soc/fsl/imx-pcm-dma.c b/sound/soc/fsl/imx-pcm-dma.c
index 500f8ce55d78..ee838c8a3b11 100644
--- a/sound/soc/fsl/imx-pcm-dma.c
+++ b/sound/soc/fsl/imx-pcm-dma.c
@@ -30,16 +30,16 @@
30#include <sound/soc.h> 30#include <sound/soc.h>
31#include <sound/dmaengine_pcm.h> 31#include <sound/dmaengine_pcm.h>
32 32
33#include <linux/platform_data/dma-imx.h>
34
35#include "imx-pcm.h" 33#include "imx-pcm.h"
36 34
37static bool filter(struct dma_chan *chan, void *param) 35static bool filter(struct dma_chan *chan, void *param)
38{ 36{
37 struct snd_dmaengine_dai_dma_data *dma_data = param;
38
39 if (!imx_dma_is_general_purpose(chan)) 39 if (!imx_dma_is_general_purpose(chan))
40 return false; 40 return false;
41 41
42 chan->private = param; 42 chan->private = dma_data->filter_data;
43 43
44 return true; 44 return true;
45} 45}
@@ -49,25 +49,16 @@ static int snd_imx_pcm_hw_params(struct snd_pcm_substream *substream,
49{ 49{
50 struct snd_soc_pcm_runtime *rtd = substream->private_data; 50 struct snd_soc_pcm_runtime *rtd = substream->private_data;
51 struct dma_chan *chan = snd_dmaengine_pcm_get_chan(substream); 51 struct dma_chan *chan = snd_dmaengine_pcm_get_chan(substream);
52 struct imx_pcm_dma_params *dma_params;
53 struct dma_slave_config slave_config; 52 struct dma_slave_config slave_config;
54 int ret; 53 int ret;
55 54
56 dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
57
58 ret = snd_hwparams_to_dma_slave_config(substream, params, &slave_config); 55 ret = snd_hwparams_to_dma_slave_config(substream, params, &slave_config);
59 if (ret) 56 if (ret)
60 return ret; 57 return ret;
61 58
62 slave_config.device_fc = false; 59 snd_dmaengine_pcm_set_config_from_dai_data(substream,
63 60 snd_soc_dai_get_dma_data(rtd->cpu_dai, substream),
64 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 61 &slave_config);
65 slave_config.dst_addr = dma_params->dma_addr;
66 slave_config.dst_maxburst = dma_params->burstsize;
67 } else {
68 slave_config.src_addr = dma_params->dma_addr;
69 slave_config.src_maxburst = dma_params->burstsize;
70 }
71 62
72 ret = dmaengine_slave_config(chan, &slave_config); 63 ret = dmaengine_slave_config(chan, &slave_config);
73 if (ret) 64 if (ret)
@@ -100,47 +91,16 @@ static struct snd_pcm_hardware snd_imx_hardware = {
100static int snd_imx_open(struct snd_pcm_substream *substream) 91static int snd_imx_open(struct snd_pcm_substream *substream)
101{ 92{
102 struct snd_soc_pcm_runtime *rtd = substream->private_data; 93 struct snd_soc_pcm_runtime *rtd = substream->private_data;
103 struct imx_pcm_dma_params *dma_params;
104 struct imx_dma_data *dma_data;
105 int ret;
106 94
107 snd_soc_set_runtime_hwparams(substream, &snd_imx_hardware); 95 snd_soc_set_runtime_hwparams(substream, &snd_imx_hardware);
108 96
109 dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); 97 return snd_dmaengine_pcm_open(substream, filter,
110 98 snd_soc_dai_get_dma_data(rtd->cpu_dai, substream));
111 dma_data = kzalloc(sizeof(*dma_data), GFP_KERNEL);
112 if (!dma_data)
113 return -ENOMEM;
114
115 dma_data->peripheral_type = dma_params->shared_peripheral ?
116 IMX_DMATYPE_SSI_SP : IMX_DMATYPE_SSI;
117 dma_data->priority = DMA_PRIO_HIGH;
118 dma_data->dma_request = dma_params->dma;
119
120 ret = snd_dmaengine_pcm_open(substream, filter, dma_data);
121 if (ret) {
122 kfree(dma_data);
123 return ret;
124 }
125
126 snd_dmaengine_pcm_set_data(substream, dma_data);
127
128 return 0;
129}
130
131static int snd_imx_close(struct snd_pcm_substream *substream)
132{
133 struct imx_dma_data *dma_data = snd_dmaengine_pcm_get_data(substream);
134
135 snd_dmaengine_pcm_close(substream);
136 kfree(dma_data);
137
138 return 0;
139} 99}
140 100
141static struct snd_pcm_ops imx_pcm_ops = { 101static struct snd_pcm_ops imx_pcm_ops = {
142 .open = snd_imx_open, 102 .open = snd_imx_open,
143 .close = snd_imx_close, 103 .close = snd_dmaengine_pcm_close,
144 .ioctl = snd_pcm_lib_ioctl, 104 .ioctl = snd_pcm_lib_ioctl,
145 .hw_params = snd_imx_pcm_hw_params, 105 .hw_params = snd_imx_pcm_hw_params,
146 .trigger = snd_dmaengine_pcm_trigger, 106 .trigger = snd_dmaengine_pcm_trigger,
diff --git a/sound/soc/fsl/imx-pcm-fiq.c b/sound/soc/fsl/imx-pcm-fiq.c
index 920f945cb2f4..025d0d9494f4 100644
--- a/sound/soc/fsl/imx-pcm-fiq.c
+++ b/sound/soc/fsl/imx-pcm-fiq.c
@@ -299,8 +299,8 @@ int imx_pcm_fiq_init(struct platform_device *pdev)
299 299
300 imx_ssi_fiq_base = (unsigned long)ssi->base; 300 imx_ssi_fiq_base = (unsigned long)ssi->base;
301 301
302 ssi->dma_params_tx.burstsize = 4; 302 ssi->dma_params_tx.maxburst = 4;
303 ssi->dma_params_rx.burstsize = 6; 303 ssi->dma_params_rx.maxburst = 6;
304 304
305 ret = snd_soc_register_platform(&pdev->dev, &imx_soc_platform_fiq); 305 ret = snd_soc_register_platform(&pdev->dev, &imx_soc_platform_fiq);
306 if (ret) 306 if (ret)
diff --git a/sound/soc/fsl/imx-pcm.h b/sound/soc/fsl/imx-pcm.h
index 5ae13a13a353..be9cc64a208b 100644
--- a/sound/soc/fsl/imx-pcm.h
+++ b/sound/soc/fsl/imx-pcm.h
@@ -13,17 +13,24 @@
13#ifndef _IMX_PCM_H 13#ifndef _IMX_PCM_H
14#define _IMX_PCM_H 14#define _IMX_PCM_H
15 15
16#include <linux/platform_data/dma-imx.h>
17
16/* 18/*
17 * Do not change this as the FIQ handler depends on this size 19 * Do not change this as the FIQ handler depends on this size
18 */ 20 */
19#define IMX_SSI_DMABUF_SIZE (64 * 1024) 21#define IMX_SSI_DMABUF_SIZE (64 * 1024)
20 22
21struct imx_pcm_dma_params { 23static inline void
22 int dma; 24imx_pcm_dma_params_init_data(struct imx_dma_data *dma_data,
23 unsigned long dma_addr; 25 int dma, bool shared)
24 int burstsize; 26{
25 bool shared_peripheral; /* The peripheral is on SPBA bus */ 27 dma_data->dma_request = dma;
26}; 28 dma_data->priority = DMA_PRIO_HIGH;
29 if (shared)
30 dma_data->peripheral_type = IMX_DMATYPE_SSI_SP;
31 else
32 dma_data->peripheral_type = IMX_DMATYPE_SSI;
33}
27 34
28int snd_imx_pcm_mmap(struct snd_pcm_substream *substream, 35int snd_imx_pcm_mmap(struct snd_pcm_substream *substream,
29 struct vm_area_struct *vma); 36 struct vm_area_struct *vma);
diff --git a/sound/soc/fsl/imx-ssi.c b/sound/soc/fsl/imx-ssi.c
index 4a26d88d7236..77300d163b96 100644
--- a/sound/soc/fsl/imx-ssi.c
+++ b/sound/soc/fsl/imx-ssi.c
@@ -236,7 +236,7 @@ static int imx_ssi_startup(struct snd_pcm_substream *substream,
236 struct snd_soc_dai *cpu_dai) 236 struct snd_soc_dai *cpu_dai)
237{ 237{
238 struct imx_ssi *ssi = snd_soc_dai_get_drvdata(cpu_dai); 238 struct imx_ssi *ssi = snd_soc_dai_get_drvdata(cpu_dai);
239 struct imx_pcm_dma_params *dma_data; 239 struct snd_dmaengine_dai_dma_data *dma_data;
240 240
241 /* Tx/Rx config */ 241 /* Tx/Rx config */
242 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 242 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
@@ -369,8 +369,8 @@ static int imx_ssi_dai_probe(struct snd_soc_dai *dai)
369 369
370 snd_soc_dai_set_drvdata(dai, ssi); 370 snd_soc_dai_set_drvdata(dai, ssi);
371 371
372 val = SSI_SFCSR_TFWM0(ssi->dma_params_tx.burstsize) | 372 val = SSI_SFCSR_TFWM0(ssi->dma_params_tx.maxburst) |
373 SSI_SFCSR_RFWM0(ssi->dma_params_rx.burstsize); 373 SSI_SFCSR_RFWM0(ssi->dma_params_rx.maxburst);
374 writel(val, ssi->base + SSI_SFCSR); 374 writel(val, ssi->base + SSI_SFCSR);
375 375
376 return 0; 376 return 0;
@@ -579,19 +579,26 @@ static int imx_ssi_probe(struct platform_device *pdev)
579 579
580 writel(0x0, ssi->base + SSI_SIER); 580 writel(0x0, ssi->base + SSI_SIER);
581 581
582 ssi->dma_params_rx.dma_addr = res->start + SSI_SRX0; 582 ssi->dma_params_rx.addr = res->start + SSI_SRX0;
583 ssi->dma_params_tx.dma_addr = res->start + SSI_STX0; 583 ssi->dma_params_tx.addr = res->start + SSI_STX0;
584 584
585 ssi->dma_params_tx.burstsize = 6; 585 ssi->dma_params_tx.maxburst = 6;
586 ssi->dma_params_rx.burstsize = 4; 586 ssi->dma_params_rx.maxburst = 4;
587
588 ssi->dma_params_tx.filter_data = &ssi->filter_data_tx;
589 ssi->dma_params_rx.filter_data = &ssi->filter_data_rx;
587 590
588 res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx0"); 591 res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx0");
589 if (res) 592 if (res) {
590 ssi->dma_params_tx.dma = res->start; 593 imx_pcm_dma_params_init_data(&ssi->filter_data_tx, res->start,
594 false);
595 }
591 596
592 res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "rx0"); 597 res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "rx0");
593 if (res) 598 if (res) {
594 ssi->dma_params_rx.dma = res->start; 599 imx_pcm_dma_params_init_data(&ssi->filter_data_rx, res->start,
600 false);
601 }
595 602
596 platform_set_drvdata(pdev, ssi); 603 platform_set_drvdata(pdev, ssi);
597 604
diff --git a/sound/soc/fsl/imx-ssi.h b/sound/soc/fsl/imx-ssi.h
index dc114bdedce5..bb6b3dbb13fd 100644
--- a/sound/soc/fsl/imx-ssi.h
+++ b/sound/soc/fsl/imx-ssi.h
@@ -187,6 +187,7 @@
187 187
188#include <linux/dmaengine.h> 188#include <linux/dmaengine.h>
189#include <linux/platform_data/dma-imx.h> 189#include <linux/platform_data/dma-imx.h>
190#include <sound/dmaengine_pcm.h>
190#include "imx-pcm.h" 191#include "imx-pcm.h"
191 192
192struct imx_ssi { 193struct imx_ssi {
@@ -204,8 +205,10 @@ struct imx_ssi {
204 void (*ac97_reset) (struct snd_ac97 *ac97); 205 void (*ac97_reset) (struct snd_ac97 *ac97);
205 void (*ac97_warm_reset)(struct snd_ac97 *ac97); 206 void (*ac97_warm_reset)(struct snd_ac97 *ac97);
206 207
207 struct imx_pcm_dma_params dma_params_rx; 208 struct snd_dmaengine_dai_dma_data dma_params_rx;
208 struct imx_pcm_dma_params dma_params_tx; 209 struct snd_dmaengine_dai_dma_data dma_params_tx;
210 struct imx_dma_data filter_data_tx;
211 struct imx_dma_data filter_data_rx;
209 212
210 int enabled; 213 int enabled;
211 214
diff --git a/sound/soc/mxs/mxs-pcm.c b/sound/soc/mxs/mxs-pcm.c
index 564b5b60319d..ebbef8597554 100644
--- a/sound/soc/mxs/mxs-pcm.c
+++ b/sound/soc/mxs/mxs-pcm.c
@@ -28,7 +28,6 @@
28#include <linux/platform_device.h> 28#include <linux/platform_device.h>
29#include <linux/slab.h> 29#include <linux/slab.h>
30#include <linux/dmaengine.h> 30#include <linux/dmaengine.h>
31#include <linux/fsl/mxs-dma.h>
32 31
33#include <sound/core.h> 32#include <sound/core.h>
34#include <sound/initval.h> 33#include <sound/initval.h>
@@ -39,11 +38,6 @@
39 38
40#include "mxs-pcm.h" 39#include "mxs-pcm.h"
41 40
42struct mxs_pcm_dma_data {
43 struct mxs_dma_data dma_data;
44 struct mxs_pcm_dma_params *dma_params;
45};
46
47static struct snd_pcm_hardware snd_mxs_hardware = { 41static struct snd_pcm_hardware snd_mxs_hardware = {
48 .info = SNDRV_PCM_INFO_MMAP | 42 .info = SNDRV_PCM_INFO_MMAP |
49 SNDRV_PCM_INFO_MMAP_VALID | 43 SNDRV_PCM_INFO_MMAP_VALID |
@@ -66,8 +60,7 @@ static struct snd_pcm_hardware snd_mxs_hardware = {
66 60
67static bool filter(struct dma_chan *chan, void *param) 61static bool filter(struct dma_chan *chan, void *param)
68{ 62{
69 struct mxs_pcm_dma_data *pcm_dma_data = param; 63 struct mxs_pcm_dma_params *dma_params = param;
70 struct mxs_pcm_dma_params *dma_params = pcm_dma_data->dma_params;
71 64
72 if (!mxs_dma_is_apbx(chan)) 65 if (!mxs_dma_is_apbx(chan))
73 return false; 66 return false;
@@ -75,7 +68,7 @@ static bool filter(struct dma_chan *chan, void *param)
75 if (chan->chan_id != dma_params->chan_num) 68 if (chan->chan_id != dma_params->chan_num)
76 return false; 69 return false;
77 70
78 chan->private = &pcm_dma_data->dma_data; 71 chan->private = &dma_params->dma_data;
79 72
80 return true; 73 return true;
81} 74}
@@ -91,37 +84,11 @@ static int snd_mxs_pcm_hw_params(struct snd_pcm_substream *substream,
91static int snd_mxs_open(struct snd_pcm_substream *substream) 84static int snd_mxs_open(struct snd_pcm_substream *substream)
92{ 85{
93 struct snd_soc_pcm_runtime *rtd = substream->private_data; 86 struct snd_soc_pcm_runtime *rtd = substream->private_data;
94 struct mxs_pcm_dma_data *pcm_dma_data;
95 int ret;
96
97 pcm_dma_data = kzalloc(sizeof(*pcm_dma_data), GFP_KERNEL);
98 if (pcm_dma_data == NULL)
99 return -ENOMEM;
100
101 pcm_dma_data->dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
102 pcm_dma_data->dma_data.chan_irq = pcm_dma_data->dma_params->chan_irq;
103
104 ret = snd_dmaengine_pcm_open(substream, filter, pcm_dma_data);
105 if (ret) {
106 kfree(pcm_dma_data);
107 return ret;
108 }
109 87
110 snd_soc_set_runtime_hwparams(substream, &snd_mxs_hardware); 88 snd_soc_set_runtime_hwparams(substream, &snd_mxs_hardware);
111 89
112 snd_dmaengine_pcm_set_data(substream, pcm_dma_data); 90 return snd_dmaengine_pcm_open(substream, filter,
113 91 snd_soc_dai_get_dma_data(rtd->cpu_dai, substream));
114 return 0;
115}
116
117static int snd_mxs_close(struct snd_pcm_substream *substream)
118{
119 struct mxs_pcm_dma_data *pcm_dma_data = snd_dmaengine_pcm_get_data(substream);
120
121 snd_dmaengine_pcm_close(substream);
122 kfree(pcm_dma_data);
123
124 return 0;
125} 92}
126 93
127static int snd_mxs_pcm_mmap(struct snd_pcm_substream *substream, 94static int snd_mxs_pcm_mmap(struct snd_pcm_substream *substream,
@@ -137,7 +104,7 @@ static int snd_mxs_pcm_mmap(struct snd_pcm_substream *substream,
137 104
138static struct snd_pcm_ops mxs_pcm_ops = { 105static struct snd_pcm_ops mxs_pcm_ops = {
139 .open = snd_mxs_open, 106 .open = snd_mxs_open,
140 .close = snd_mxs_close, 107 .close = snd_dmaengine_pcm_close,
141 .ioctl = snd_pcm_lib_ioctl, 108 .ioctl = snd_pcm_lib_ioctl,
142 .hw_params = snd_mxs_pcm_hw_params, 109 .hw_params = snd_mxs_pcm_hw_params,
143 .trigger = snd_dmaengine_pcm_trigger, 110 .trigger = snd_dmaengine_pcm_trigger,
diff --git a/sound/soc/mxs/mxs-pcm.h b/sound/soc/mxs/mxs-pcm.h
index 35ba2ca42384..3aa918f9ed3e 100644
--- a/sound/soc/mxs/mxs-pcm.h
+++ b/sound/soc/mxs/mxs-pcm.h
@@ -19,8 +19,10 @@
19#ifndef _MXS_PCM_H 19#ifndef _MXS_PCM_H
20#define _MXS_PCM_H 20#define _MXS_PCM_H
21 21
22#include <linux/fsl/mxs-dma.h>
23
22struct mxs_pcm_dma_params { 24struct mxs_pcm_dma_params {
23 int chan_irq; 25 struct mxs_dma_data dma_data;
24 int chan_num; 26 int chan_num;
25}; 27};
26 28
diff --git a/sound/soc/mxs/mxs-saif.c b/sound/soc/mxs/mxs-saif.c
index 3e78ba866681..abf4ddf4ed89 100644
--- a/sound/soc/mxs/mxs-saif.c
+++ b/sound/soc/mxs/mxs-saif.c
@@ -757,9 +757,9 @@ static int mxs_saif_probe(struct platform_device *pdev)
757 return ret; 757 return ret;
758 } 758 }
759 759
760 saif->dma_param.chan_irq = platform_get_irq(pdev, 1); 760 saif->dma_param.dma_data.chan_irq = platform_get_irq(pdev, 1);
761 if (saif->dma_param.chan_irq < 0) { 761 if (saif->dma_param.dma_data.chan_irq < 0) {
762 ret = saif->dma_param.chan_irq; 762 ret = saif->dma_param.dma_data.chan_irq;
763 dev_err(&pdev->dev, "failed to get dma irq resource: %d\n", 763 dev_err(&pdev->dev, "failed to get dma irq resource: %d\n",
764 ret); 764 ret);
765 return ret; 765 return ret;
diff --git a/sound/soc/omap/am3517evm.c b/sound/soc/omap/am3517evm.c
index c1900b2a6f28..994dcf345975 100644
--- a/sound/soc/omap/am3517evm.c
+++ b/sound/soc/omap/am3517evm.c
@@ -28,7 +28,6 @@
28#include <linux/platform_data/asoc-ti-mcbsp.h> 28#include <linux/platform_data/asoc-ti-mcbsp.h>
29 29
30#include "omap-mcbsp.h" 30#include "omap-mcbsp.h"
31#include "omap-pcm.h"
32 31
33#include "../codecs/tlv320aic23.h" 32#include "../codecs/tlv320aic23.h"
34 33
diff --git a/sound/soc/omap/ams-delta.c b/sound/soc/omap/ams-delta.c
index 2600447fa74f..629446482a91 100644
--- a/sound/soc/omap/ams-delta.c
+++ b/sound/soc/omap/ams-delta.c
@@ -36,7 +36,6 @@
36#include <linux/platform_data/asoc-ti-mcbsp.h> 36#include <linux/platform_data/asoc-ti-mcbsp.h>
37 37
38#include "omap-mcbsp.h" 38#include "omap-mcbsp.h"
39#include "omap-pcm.h"
40#include "../codecs/cx20442.h" 39#include "../codecs/cx20442.h"
41 40
42 41
diff --git a/sound/soc/omap/mcbsp.c b/sound/soc/omap/mcbsp.c
index 285c8368cb47..eb68c7db1cf3 100644
--- a/sound/soc/omap/mcbsp.c
+++ b/sound/soc/omap/mcbsp.c
@@ -1018,9 +1018,10 @@ int omap_mcbsp_init(struct platform_device *pdev)
1018 return -ENODEV; 1018 return -ENODEV;
1019 } 1019 }
1020 /* RX DMA request number, and port address configuration */ 1020 /* RX DMA request number, and port address configuration */
1021 mcbsp->dma_data[1].name = "Audio Capture"; 1021 mcbsp->dma_req[1] = res->start;
1022 mcbsp->dma_data[1].dma_req = res->start; 1022 mcbsp->dma_data[1].filter_data = &mcbsp->dma_req[1];
1023 mcbsp->dma_data[1].port_addr = omap_mcbsp_dma_reg_params(mcbsp, 1); 1023 mcbsp->dma_data[1].addr = omap_mcbsp_dma_reg_params(mcbsp, 1);
1024 mcbsp->dma_data[1].maxburst = 4;
1024 1025
1025 res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx"); 1026 res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx");
1026 if (!res) { 1027 if (!res) {
@@ -1028,9 +1029,10 @@ int omap_mcbsp_init(struct platform_device *pdev)
1028 return -ENODEV; 1029 return -ENODEV;
1029 } 1030 }
1030 /* TX DMA request number, and port address configuration */ 1031 /* TX DMA request number, and port address configuration */
1031 mcbsp->dma_data[0].name = "Audio Playback"; 1032 mcbsp->dma_req[0] = res->start;
1032 mcbsp->dma_data[0].dma_req = res->start; 1033 mcbsp->dma_data[0].filter_data = &mcbsp->dma_req[0];
1033 mcbsp->dma_data[0].port_addr = omap_mcbsp_dma_reg_params(mcbsp, 0); 1034 mcbsp->dma_data[0].addr = omap_mcbsp_dma_reg_params(mcbsp, 0);
1035 mcbsp->dma_data[0].maxburst = 4;
1034 1036
1035 mcbsp->fclk = clk_get(&pdev->dev, "fck"); 1037 mcbsp->fclk = clk_get(&pdev->dev, "fck");
1036 if (IS_ERR(mcbsp->fclk)) { 1038 if (IS_ERR(mcbsp->fclk)) {
diff --git a/sound/soc/omap/mcbsp.h b/sound/soc/omap/mcbsp.h
index f93e0b0af303..96d1b086bcf8 100644
--- a/sound/soc/omap/mcbsp.h
+++ b/sound/soc/omap/mcbsp.h
@@ -24,14 +24,14 @@
24#ifndef __ASOC_MCBSP_H 24#ifndef __ASOC_MCBSP_H
25#define __ASOC_MCBSP_H 25#define __ASOC_MCBSP_H
26 26
27#include "omap-pcm.h"
28
29#ifdef CONFIG_ARCH_OMAP1 27#ifdef CONFIG_ARCH_OMAP1
30#define mcbsp_omap1() 1 28#define mcbsp_omap1() 1
31#else 29#else
32#define mcbsp_omap1() 0 30#define mcbsp_omap1() 0
33#endif 31#endif
34 32
33#include <sound/dmaengine_pcm.h>
34
35/* McBSP register numbers. Register address offset = num * reg_step */ 35/* McBSP register numbers. Register address offset = num * reg_step */
36enum { 36enum {
37 /* Common registers */ 37 /* Common registers */
@@ -312,7 +312,8 @@ struct omap_mcbsp {
312 struct omap_mcbsp_platform_data *pdata; 312 struct omap_mcbsp_platform_data *pdata;
313 struct omap_mcbsp_st_data *st_data; 313 struct omap_mcbsp_st_data *st_data;
314 struct omap_mcbsp_reg_cfg cfg_regs; 314 struct omap_mcbsp_reg_cfg cfg_regs;
315 struct omap_pcm_dma_data dma_data[2]; 315 struct snd_dmaengine_dai_dma_data dma_data[2];
316 unsigned int dma_req[2];
316 int dma_op_mode; 317 int dma_op_mode;
317 u16 max_tx_thres; 318 u16 max_tx_thres;
318 u16 max_rx_thres; 319 u16 max_rx_thres;
diff --git a/sound/soc/omap/n810.c b/sound/soc/omap/n810.c
index ee7cd53aa3ee..5e8d640d314f 100644
--- a/sound/soc/omap/n810.c
+++ b/sound/soc/omap/n810.c
@@ -34,7 +34,6 @@
34#include <linux/platform_data/asoc-ti-mcbsp.h> 34#include <linux/platform_data/asoc-ti-mcbsp.h>
35 35
36#include "omap-mcbsp.h" 36#include "omap-mcbsp.h"
37#include "omap-pcm.h"
38 37
39#define N810_HEADSET_AMP_GPIO 10 38#define N810_HEADSET_AMP_GPIO 10
40#define N810_SPEAKER_AMP_GPIO 101 39#define N810_SPEAKER_AMP_GPIO 101
diff --git a/sound/soc/omap/omap-abe-twl6040.c b/sound/soc/omap/omap-abe-twl6040.c
index e7d93fa412a9..70cd5c7b2e14 100644
--- a/sound/soc/omap/omap-abe-twl6040.c
+++ b/sound/soc/omap/omap-abe-twl6040.c
@@ -34,7 +34,6 @@
34 34
35#include "omap-dmic.h" 35#include "omap-dmic.h"
36#include "omap-mcpdm.h" 36#include "omap-mcpdm.h"
37#include "omap-pcm.h"
38#include "../codecs/twl6040.h" 37#include "../codecs/twl6040.h"
39 38
40struct abe_twl6040 { 39struct abe_twl6040 {
diff --git a/sound/soc/omap/omap-dmic.c b/sound/soc/omap/omap-dmic.c
index 4c54542895b0..2ad0370146fd 100644
--- a/sound/soc/omap/omap-dmic.c
+++ b/sound/soc/omap/omap-dmic.c
@@ -39,8 +39,8 @@
39#include <sound/pcm_params.h> 39#include <sound/pcm_params.h>
40#include <sound/initval.h> 40#include <sound/initval.h>
41#include <sound/soc.h> 41#include <sound/soc.h>
42#include <sound/dmaengine_pcm.h>
42 43
43#include "omap-pcm.h"
44#include "omap-dmic.h" 44#include "omap-dmic.h"
45 45
46struct omap_dmic { 46struct omap_dmic {
@@ -55,13 +55,9 @@ struct omap_dmic {
55 u32 ch_enabled; 55 u32 ch_enabled;
56 bool active; 56 bool active;
57 struct mutex mutex; 57 struct mutex mutex;
58};
59 58
60/* 59 struct snd_dmaengine_dai_dma_data dma_data;
61 * Stream DMA parameters 60 unsigned int dma_req;
62 */
63static struct omap_pcm_dma_data omap_dmic_dai_dma_params = {
64 .name = "DMIC capture",
65}; 61};
66 62
67static inline void omap_dmic_write(struct omap_dmic *dmic, u16 reg, u32 val) 63static inline void omap_dmic_write(struct omap_dmic *dmic, u16 reg, u32 val)
@@ -118,7 +114,7 @@ static int omap_dmic_dai_startup(struct snd_pcm_substream *substream,
118 114
119 mutex_unlock(&dmic->mutex); 115 mutex_unlock(&dmic->mutex);
120 116
121 snd_soc_dai_set_dma_data(dai, substream, &omap_dmic_dai_dma_params); 117 snd_soc_dai_set_dma_data(dai, substream, &dmic->dma_data);
122 return ret; 118 return ret;
123} 119}
124 120
@@ -203,7 +199,7 @@ static int omap_dmic_dai_hw_params(struct snd_pcm_substream *substream,
203 struct snd_soc_dai *dai) 199 struct snd_soc_dai *dai)
204{ 200{
205 struct omap_dmic *dmic = snd_soc_dai_get_drvdata(dai); 201 struct omap_dmic *dmic = snd_soc_dai_get_drvdata(dai);
206 struct omap_pcm_dma_data *dma_data; 202 struct snd_dmaengine_dai_dma_data *dma_data;
207 int channels; 203 int channels;
208 204
209 dmic->clk_div = omap_dmic_select_divider(dmic, params_rate(params)); 205 dmic->clk_div = omap_dmic_select_divider(dmic, params_rate(params));
@@ -230,7 +226,7 @@ static int omap_dmic_dai_hw_params(struct snd_pcm_substream *substream,
230 226
231 /* packet size is threshold * channels */ 227 /* packet size is threshold * channels */
232 dma_data = snd_soc_dai_get_dma_data(dai, substream); 228 dma_data = snd_soc_dai_get_dma_data(dai, substream);
233 dma_data->packet_size = dmic->threshold * channels; 229 dma_data->maxburst = dmic->threshold * channels;
234 230
235 return 0; 231 return 0;
236} 232}
@@ -480,7 +476,7 @@ static int asoc_dmic_probe(struct platform_device *pdev)
480 ret = -ENODEV; 476 ret = -ENODEV;
481 goto err_put_clk; 477 goto err_put_clk;
482 } 478 }
483 omap_dmic_dai_dma_params.port_addr = res->start + OMAP_DMIC_DATA_REG; 479 dmic->dma_data.addr = res->start + OMAP_DMIC_DATA_REG;
484 480
485 res = platform_get_resource(pdev, IORESOURCE_DMA, 0); 481 res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
486 if (!res) { 482 if (!res) {
@@ -488,7 +484,9 @@ static int asoc_dmic_probe(struct platform_device *pdev)
488 ret = -ENODEV; 484 ret = -ENODEV;
489 goto err_put_clk; 485 goto err_put_clk;
490 } 486 }
491 omap_dmic_dai_dma_params.dma_req = res->start; 487
488 dmic->dma_req = res->start;
489 dmic->dma_data.filter_data = &dmic->dma_req;
492 490
493 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mpu"); 491 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mpu");
494 if (!res) { 492 if (!res) {
@@ -497,19 +495,9 @@ static int asoc_dmic_probe(struct platform_device *pdev)
497 goto err_put_clk; 495 goto err_put_clk;
498 } 496 }
499 497
500 if (!devm_request_mem_region(&pdev->dev, res->start, 498 dmic->io_base = devm_ioremap_resource(&pdev->dev, res);
501 resource_size(res), pdev->name)) { 499 if (IS_ERR(dmic->io_base))
502 dev_err(dmic->dev, "memory region already claimed\n"); 500 return PTR_ERR(dmic->io_base);
503 ret = -ENODEV;
504 goto err_put_clk;
505 }
506
507 dmic->io_base = devm_ioremap(&pdev->dev, res->start,
508 resource_size(res));
509 if (!dmic->io_base) {
510 ret = -ENOMEM;
511 goto err_put_clk;
512 }
513 501
514 ret = snd_soc_register_component(&pdev->dev, &omap_dmic_component, 502 ret = snd_soc_register_component(&pdev->dev, &omap_dmic_component,
515 &omap_dmic_dai, 1); 503 &omap_dmic_dai, 1);
diff --git a/sound/soc/omap/omap-hdmi.c b/sound/soc/omap/omap-hdmi.c
index 7e120ccc20e1..ced3b88b44d4 100644
--- a/sound/soc/omap/omap-hdmi.c
+++ b/sound/soc/omap/omap-hdmi.c
@@ -32,15 +32,16 @@
32#include <sound/soc.h> 32#include <sound/soc.h>
33#include <sound/asound.h> 33#include <sound/asound.h>
34#include <sound/asoundef.h> 34#include <sound/asoundef.h>
35#include <sound/dmaengine_pcm.h>
35#include <video/omapdss.h> 36#include <video/omapdss.h>
36 37
37#include "omap-pcm.h"
38#include "omap-hdmi.h" 38#include "omap-hdmi.h"
39 39
40#define DRV_NAME "omap-hdmi-audio-dai" 40#define DRV_NAME "omap-hdmi-audio-dai"
41 41
42struct hdmi_priv { 42struct hdmi_priv {
43 struct omap_pcm_dma_data dma_params; 43 struct snd_dmaengine_dai_dma_data dma_data;
44 unsigned int dma_req;
44 struct omap_dss_audio dss_audio; 45 struct omap_dss_audio dss_audio;
45 struct snd_aes_iec958 iec; 46 struct snd_aes_iec958 iec;
46 struct snd_cea_861_aud_if cea; 47 struct snd_cea_861_aud_if cea;
@@ -68,7 +69,7 @@ static int omap_hdmi_dai_startup(struct snd_pcm_substream *substream,
68 return -ENODEV; 69 return -ENODEV;
69 } 70 }
70 71
71 snd_soc_dai_set_dma_data(dai, substream, &priv->dma_params); 72 snd_soc_dai_set_dma_data(dai, substream, &priv->dma_data);
72 73
73 return 0; 74 return 0;
74} 75}
@@ -88,25 +89,20 @@ static int omap_hdmi_dai_hw_params(struct snd_pcm_substream *substream,
88 struct hdmi_priv *priv = snd_soc_dai_get_drvdata(dai); 89 struct hdmi_priv *priv = snd_soc_dai_get_drvdata(dai);
89 struct snd_aes_iec958 *iec = &priv->iec; 90 struct snd_aes_iec958 *iec = &priv->iec;
90 struct snd_cea_861_aud_if *cea = &priv->cea; 91 struct snd_cea_861_aud_if *cea = &priv->cea;
91 struct omap_pcm_dma_data *dma_data;
92 int err = 0; 92 int err = 0;
93 93
94 dma_data = snd_soc_dai_get_dma_data(dai, substream);
95
96 switch (params_format(params)) { 94 switch (params_format(params)) {
97 case SNDRV_PCM_FORMAT_S16_LE: 95 case SNDRV_PCM_FORMAT_S16_LE:
98 dma_data->packet_size = 16; 96 priv->dma_data.maxburst = 16;
99 break; 97 break;
100 case SNDRV_PCM_FORMAT_S24_LE: 98 case SNDRV_PCM_FORMAT_S24_LE:
101 dma_data->packet_size = 32; 99 priv->dma_data.maxburst = 32;
102 break; 100 break;
103 default: 101 default:
104 dev_err(dai->dev, "format not supported!\n"); 102 dev_err(dai->dev, "format not supported!\n");
105 return -EINVAL; 103 return -EINVAL;
106 } 104 }
107 105
108 dma_data->data_type = 32;
109
110 /* 106 /*
111 * fill the IEC-60958 channel status word 107 * fill the IEC-60958 channel status word
112 */ 108 */
@@ -287,8 +283,7 @@ static int omap_hdmi_probe(struct platform_device *pdev)
287 return -ENODEV; 283 return -ENODEV;
288 } 284 }
289 285
290 hdmi_data->dma_params.port_addr = hdmi_rsrc->start 286 hdmi_data->dma_data.addr = hdmi_rsrc->start + OMAP_HDMI_AUDIO_DMA_PORT;
291 + OMAP_HDMI_AUDIO_DMA_PORT;
292 287
293 hdmi_rsrc = platform_get_resource(pdev, IORESOURCE_DMA, 0); 288 hdmi_rsrc = platform_get_resource(pdev, IORESOURCE_DMA, 0);
294 if (!hdmi_rsrc) { 289 if (!hdmi_rsrc) {
@@ -296,8 +291,9 @@ static int omap_hdmi_probe(struct platform_device *pdev)
296 return -ENODEV; 291 return -ENODEV;
297 } 292 }
298 293
299 hdmi_data->dma_params.dma_req = hdmi_rsrc->start; 294 hdmi_data->dma_req = hdmi_rsrc->start;
300 hdmi_data->dma_params.name = "HDMI playback"; 295 hdmi_data->dma_data.filter_data = &hdmi_data->dma_req;
296 hdmi_data->dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
301 297
302 /* 298 /*
303 * TODO: We assume that there is only one DSS HDMI device. Future 299 * TODO: We assume that there is only one DSS HDMI device. Future
diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c
index f51685d72fdb..eadbfb6b5000 100644
--- a/sound/soc/omap/omap-mcbsp.c
+++ b/sound/soc/omap/omap-mcbsp.c
@@ -33,11 +33,11 @@
33#include <sound/pcm_params.h> 33#include <sound/pcm_params.h>
34#include <sound/initval.h> 34#include <sound/initval.h>
35#include <sound/soc.h> 35#include <sound/soc.h>
36#include <sound/dmaengine_pcm.h>
36 37
37#include <linux/platform_data/asoc-ti-mcbsp.h> 38#include <linux/platform_data/asoc-ti-mcbsp.h>
38#include "mcbsp.h" 39#include "mcbsp.h"
39#include "omap-mcbsp.h" 40#include "omap-mcbsp.h"
40#include "omap-pcm.h"
41 41
42#define OMAP_MCBSP_RATES (SNDRV_PCM_RATE_8000_96000) 42#define OMAP_MCBSP_RATES (SNDRV_PCM_RATE_8000_96000)
43 43
@@ -62,24 +62,22 @@ enum {
62 * Stream DMA parameters. DMA request line and port address are set runtime 62 * Stream DMA parameters. DMA request line and port address are set runtime
63 * since they are different between OMAP1 and later OMAPs 63 * since they are different between OMAP1 and later OMAPs
64 */ 64 */
65static void omap_mcbsp_set_threshold(struct snd_pcm_substream *substream) 65static void omap_mcbsp_set_threshold(struct snd_pcm_substream *substream,
66 unsigned int packet_size)
66{ 67{
67 struct snd_soc_pcm_runtime *rtd = substream->private_data; 68 struct snd_soc_pcm_runtime *rtd = substream->private_data;
68 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 69 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
69 struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai); 70 struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai);
70 struct omap_pcm_dma_data *dma_data;
71 int words; 71 int words;
72 72
73 dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
74
75 /* 73 /*
76 * Configure McBSP threshold based on either: 74 * Configure McBSP threshold based on either:
77 * packet_size, when the sDMA is in packet mode, or based on the 75 * packet_size, when the sDMA is in packet mode, or based on the
78 * period size in THRESHOLD mode, otherwise use McBSP threshold = 1 76 * period size in THRESHOLD mode, otherwise use McBSP threshold = 1
79 * for mono streams. 77 * for mono streams.
80 */ 78 */
81 if (dma_data->packet_size) 79 if (packet_size)
82 words = dma_data->packet_size; 80 words = packet_size;
83 else 81 else
84 words = 1; 82 words = 1;
85 83
@@ -226,7 +224,7 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
226{ 224{
227 struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai); 225 struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai);
228 struct omap_mcbsp_reg_cfg *regs = &mcbsp->cfg_regs; 226 struct omap_mcbsp_reg_cfg *regs = &mcbsp->cfg_regs;
229 struct omap_pcm_dma_data *dma_data; 227 struct snd_dmaengine_dai_dma_data *dma_data;
230 int wlen, channels, wpf; 228 int wlen, channels, wpf;
231 int pkt_size = 0; 229 int pkt_size = 0;
232 unsigned int format, div, framesize, master; 230 unsigned int format, div, framesize, master;
@@ -245,7 +243,6 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
245 return -EINVAL; 243 return -EINVAL;
246 } 244 }
247 if (mcbsp->pdata->buffer_size) { 245 if (mcbsp->pdata->buffer_size) {
248 dma_data->set_threshold = omap_mcbsp_set_threshold;
249 if (mcbsp->dma_op_mode == MCBSP_DMA_MODE_THRESHOLD) { 246 if (mcbsp->dma_op_mode == MCBSP_DMA_MODE_THRESHOLD) {
250 int period_words, max_thrsh; 247 int period_words, max_thrsh;
251 int divider = 0; 248 int divider = 0;
@@ -276,9 +273,10 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
276 /* Use packet mode for non mono streams */ 273 /* Use packet mode for non mono streams */
277 pkt_size = channels; 274 pkt_size = channels;
278 } 275 }
276 omap_mcbsp_set_threshold(substream, pkt_size);
279 } 277 }
280 278
281 dma_data->packet_size = pkt_size; 279 dma_data->maxburst = pkt_size;
282 280
283 if (mcbsp->configured) { 281 if (mcbsp->configured) {
284 /* McBSP already configured by another stream */ 282 /* McBSP already configured by another stream */
diff --git a/sound/soc/omap/omap-mcpdm.c b/sound/soc/omap/omap-mcpdm.c
index 4cc98071aa91..eb05c7ed6d05 100644
--- a/sound/soc/omap/omap-mcpdm.c
+++ b/sound/soc/omap/omap-mcpdm.c
@@ -39,11 +39,14 @@
39#include <sound/pcm.h> 39#include <sound/pcm.h>
40#include <sound/pcm_params.h> 40#include <sound/pcm_params.h>
41#include <sound/soc.h> 41#include <sound/soc.h>
42#include <sound/dmaengine_pcm.h>
42 43
43#include "omap-mcpdm.h" 44#include "omap-mcpdm.h"
44#include "omap-pcm.h"
45 45
46#define OMAP44XX_MCPDM_L3_BASE 0x49032000 46struct mcpdm_link_config {
47 u32 link_mask; /* channel mask for the direction */
48 u32 threshold; /* FIFO threshold */
49};
47 50
48struct omap_mcpdm { 51struct omap_mcpdm {
49 struct device *dev; 52 struct device *dev;
@@ -53,29 +56,22 @@ struct omap_mcpdm {
53 56
54 struct mutex mutex; 57 struct mutex mutex;
55 58
56 /* channel data */ 59 /* Playback/Capture configuration */
57 u32 dn_channels; 60 struct mcpdm_link_config config[2];
58 u32 up_channels;
59
60 /* McPDM FIFO thresholds */
61 u32 dn_threshold;
62 u32 up_threshold;
63 61
64 /* McPDM dn offsets for rx1, and 2 channels */ 62 /* McPDM dn offsets for rx1, and 2 channels */
65 u32 dn_rx_offset; 63 u32 dn_rx_offset;
64
65 /* McPDM needs to be restarted due to runtime reconfiguration */
66 bool restart;
67
68 struct snd_dmaengine_dai_dma_data dma_data[2];
69 unsigned int dma_req[2];
66}; 70};
67 71
68/* 72/*
69 * Stream DMA parameters 73 * Stream DMA parameters
70 */ 74 */
71static struct omap_pcm_dma_data omap_mcpdm_dai_dma_params[] = {
72 {
73 .name = "Audio playback",
74 },
75 {
76 .name = "Audio capture",
77 },
78};
79 75
80static inline void omap_mcpdm_write(struct omap_mcpdm *mcpdm, u16 reg, u32 val) 76static inline void omap_mcpdm_write(struct omap_mcpdm *mcpdm, u16 reg, u32 val)
81{ 77{
@@ -130,11 +126,12 @@ static void omap_mcpdm_reg_dump(struct omap_mcpdm *mcpdm) {}
130static void omap_mcpdm_start(struct omap_mcpdm *mcpdm) 126static void omap_mcpdm_start(struct omap_mcpdm *mcpdm)
131{ 127{
132 u32 ctrl = omap_mcpdm_read(mcpdm, MCPDM_REG_CTRL); 128 u32 ctrl = omap_mcpdm_read(mcpdm, MCPDM_REG_CTRL);
129 u32 link_mask = mcpdm->config[0].link_mask | mcpdm->config[1].link_mask;
133 130
134 ctrl |= (MCPDM_SW_DN_RST | MCPDM_SW_UP_RST); 131 ctrl |= (MCPDM_SW_DN_RST | MCPDM_SW_UP_RST);
135 omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, ctrl); 132 omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, ctrl);
136 133
137 ctrl |= mcpdm->dn_channels | mcpdm->up_channels; 134 ctrl |= link_mask;
138 omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, ctrl); 135 omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, ctrl);
139 136
140 ctrl &= ~(MCPDM_SW_DN_RST | MCPDM_SW_UP_RST); 137 ctrl &= ~(MCPDM_SW_DN_RST | MCPDM_SW_UP_RST);
@@ -148,11 +145,12 @@ static void omap_mcpdm_start(struct omap_mcpdm *mcpdm)
148static void omap_mcpdm_stop(struct omap_mcpdm *mcpdm) 145static void omap_mcpdm_stop(struct omap_mcpdm *mcpdm)
149{ 146{
150 u32 ctrl = omap_mcpdm_read(mcpdm, MCPDM_REG_CTRL); 147 u32 ctrl = omap_mcpdm_read(mcpdm, MCPDM_REG_CTRL);
148 u32 link_mask = MCPDM_PDM_DN_MASK | MCPDM_PDM_UP_MASK;
151 149
152 ctrl |= (MCPDM_SW_DN_RST | MCPDM_SW_UP_RST); 150 ctrl |= (MCPDM_SW_DN_RST | MCPDM_SW_UP_RST);
153 omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, ctrl); 151 omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, ctrl);
154 152
155 ctrl &= ~(mcpdm->dn_channels | mcpdm->up_channels); 153 ctrl &= ~(link_mask);
156 omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, ctrl); 154 omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, ctrl);
157 155
158 ctrl &= ~(MCPDM_SW_DN_RST | MCPDM_SW_UP_RST); 156 ctrl &= ~(MCPDM_SW_DN_RST | MCPDM_SW_UP_RST);
@@ -188,8 +186,10 @@ static void omap_mcpdm_open_streams(struct omap_mcpdm *mcpdm)
188 omap_mcpdm_write(mcpdm, MCPDM_REG_DN_OFFSET, dn_offset); 186 omap_mcpdm_write(mcpdm, MCPDM_REG_DN_OFFSET, dn_offset);
189 } 187 }
190 188
191 omap_mcpdm_write(mcpdm, MCPDM_REG_FIFO_CTRL_DN, mcpdm->dn_threshold); 189 omap_mcpdm_write(mcpdm, MCPDM_REG_FIFO_CTRL_DN,
192 omap_mcpdm_write(mcpdm, MCPDM_REG_FIFO_CTRL_UP, mcpdm->up_threshold); 190 mcpdm->config[SNDRV_PCM_STREAM_PLAYBACK].threshold);
191 omap_mcpdm_write(mcpdm, MCPDM_REG_FIFO_CTRL_UP,
192 mcpdm->config[SNDRV_PCM_STREAM_CAPTURE].threshold);
193 193
194 omap_mcpdm_write(mcpdm, MCPDM_REG_DMAENABLE_SET, 194 omap_mcpdm_write(mcpdm, MCPDM_REG_DMAENABLE_SET,
195 MCPDM_DMA_DN_ENABLE | MCPDM_DMA_UP_ENABLE); 195 MCPDM_DMA_DN_ENABLE | MCPDM_DMA_UP_ENABLE);
@@ -267,7 +267,7 @@ static int omap_mcpdm_dai_startup(struct snd_pcm_substream *substream,
267 mutex_unlock(&mcpdm->mutex); 267 mutex_unlock(&mcpdm->mutex);
268 268
269 snd_soc_dai_set_dma_data(dai, substream, 269 snd_soc_dai_set_dma_data(dai, substream,
270 &omap_mcpdm_dai_dma_params[substream->stream]); 270 &mcpdm->dma_data[substream->stream]);
271 271
272 return 0; 272 return 0;
273} 273}
@@ -283,6 +283,8 @@ static void omap_mcpdm_dai_shutdown(struct snd_pcm_substream *substream,
283 if (omap_mcpdm_active(mcpdm)) { 283 if (omap_mcpdm_active(mcpdm)) {
284 omap_mcpdm_stop(mcpdm); 284 omap_mcpdm_stop(mcpdm);
285 omap_mcpdm_close_streams(mcpdm); 285 omap_mcpdm_close_streams(mcpdm);
286 mcpdm->config[0].link_mask = 0;
287 mcpdm->config[1].link_mask = 0;
286 } 288 }
287 } 289 }
288 290
@@ -295,7 +297,8 @@ static int omap_mcpdm_dai_hw_params(struct snd_pcm_substream *substream,
295{ 297{
296 struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai); 298 struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai);
297 int stream = substream->stream; 299 int stream = substream->stream;
298 struct omap_pcm_dma_data *dma_data; 300 struct snd_dmaengine_dai_dma_data *dma_data;
301 u32 threshold;
299 int channels; 302 int channels;
300 int link_mask = 0; 303 int link_mask = 0;
301 304
@@ -325,16 +328,32 @@ static int omap_mcpdm_dai_hw_params(struct snd_pcm_substream *substream,
325 328
326 dma_data = snd_soc_dai_get_dma_data(dai, substream); 329 dma_data = snd_soc_dai_get_dma_data(dai, substream);
327 330
331 threshold = mcpdm->config[stream].threshold;
328 /* Configure McPDM channels, and DMA packet size */ 332 /* Configure McPDM channels, and DMA packet size */
329 if (stream == SNDRV_PCM_STREAM_PLAYBACK) { 333 if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
330 mcpdm->dn_channels = link_mask << 3; 334 link_mask <<= 3;
331 dma_data->packet_size = 335
332 (MCPDM_DN_THRES_MAX - mcpdm->dn_threshold) * channels; 336 /* If capture is not running assume a stereo stream to come */
337 if (!mcpdm->config[!stream].link_mask)
338 mcpdm->config[!stream].link_mask = 0x3;
339
340 dma_data->maxburst =
341 (MCPDM_DN_THRES_MAX - threshold) * channels;
333 } else { 342 } else {
334 mcpdm->up_channels = link_mask << 0; 343 /* If playback is not running assume a stereo stream to come */
335 dma_data->packet_size = mcpdm->up_threshold * channels; 344 if (!mcpdm->config[!stream].link_mask)
345 mcpdm->config[!stream].link_mask = (0x3 << 3);
346
347 dma_data->maxburst = threshold * channels;
336 } 348 }
337 349
350 /* Check if we need to restart McPDM with this stream */
351 if (mcpdm->config[stream].link_mask &&
352 mcpdm->config[stream].link_mask != link_mask)
353 mcpdm->restart = true;
354
355 mcpdm->config[stream].link_mask = link_mask;
356
338 return 0; 357 return 0;
339} 358}
340 359
@@ -346,6 +365,11 @@ static int omap_mcpdm_prepare(struct snd_pcm_substream *substream,
346 if (!omap_mcpdm_active(mcpdm)) { 365 if (!omap_mcpdm_active(mcpdm)) {
347 omap_mcpdm_start(mcpdm); 366 omap_mcpdm_start(mcpdm);
348 omap_mcpdm_reg_dump(mcpdm); 367 omap_mcpdm_reg_dump(mcpdm);
368 } else if (mcpdm->restart) {
369 omap_mcpdm_stop(mcpdm);
370 omap_mcpdm_start(mcpdm);
371 mcpdm->restart = false;
372 omap_mcpdm_reg_dump(mcpdm);
349 } 373 }
350 374
351 return 0; 375 return 0;
@@ -369,7 +393,7 @@ static int omap_mcpdm_probe(struct snd_soc_dai *dai)
369 pm_runtime_get_sync(mcpdm->dev); 393 pm_runtime_get_sync(mcpdm->dev);
370 omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, 0x00); 394 omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, 0x00);
371 395
372 ret = request_irq(mcpdm->irq, omap_mcpdm_irq_handler, 396 ret = devm_request_irq(mcpdm->dev, mcpdm->irq, omap_mcpdm_irq_handler,
373 0, "McPDM", (void *)mcpdm); 397 0, "McPDM", (void *)mcpdm);
374 398
375 pm_runtime_put_sync(mcpdm->dev); 399 pm_runtime_put_sync(mcpdm->dev);
@@ -380,8 +404,9 @@ static int omap_mcpdm_probe(struct snd_soc_dai *dai)
380 } 404 }
381 405
382 /* Configure McPDM threshold values */ 406 /* Configure McPDM threshold values */
383 mcpdm->dn_threshold = 2; 407 mcpdm->config[SNDRV_PCM_STREAM_PLAYBACK].threshold = 2;
384 mcpdm->up_threshold = MCPDM_UP_THRES_MAX - 3; 408 mcpdm->config[SNDRV_PCM_STREAM_CAPTURE].threshold =
409 MCPDM_UP_THRES_MAX - 3;
385 return ret; 410 return ret;
386} 411}
387 412
@@ -389,7 +414,6 @@ static int omap_mcpdm_remove(struct snd_soc_dai *dai)
389{ 414{
390 struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai); 415 struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai);
391 416
392 free_irq(mcpdm->irq, (void *)mcpdm);
393 pm_runtime_disable(mcpdm->dev); 417 pm_runtime_disable(mcpdm->dev);
394 418
395 return 0; 419 return 0;
@@ -450,33 +474,30 @@ static int asoc_mcpdm_probe(struct platform_device *pdev)
450 if (res == NULL) 474 if (res == NULL)
451 return -ENOMEM; 475 return -ENOMEM;
452 476
453 omap_mcpdm_dai_dma_params[0].port_addr = res->start + MCPDM_REG_DN_DATA; 477 mcpdm->dma_data[0].addr = res->start + MCPDM_REG_DN_DATA;
454 omap_mcpdm_dai_dma_params[1].port_addr = res->start + MCPDM_REG_UP_DATA; 478 mcpdm->dma_data[1].addr = res->start + MCPDM_REG_UP_DATA;
455 479
456 res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "dn_link"); 480 res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "dn_link");
457 if (!res) 481 if (!res)
458 return -ENODEV; 482 return -ENODEV;
459 483
460 omap_mcpdm_dai_dma_params[0].dma_req = res->start; 484 mcpdm->dma_req[0] = res->start;
485 mcpdm->dma_data[0].filter_data = &mcpdm->dma_req[0];
461 486
462 res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "up_link"); 487 res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "up_link");
463 if (!res) 488 if (!res)
464 return -ENODEV; 489 return -ENODEV;
465 490
466 omap_mcpdm_dai_dma_params[1].dma_req = res->start; 491 mcpdm->dma_req[1] = res->start;
492 mcpdm->dma_data[1].filter_data = &mcpdm->dma_req[1];
467 493
468 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mpu"); 494 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mpu");
469 if (res == NULL) 495 if (res == NULL)
470 return -ENOMEM; 496 return -ENOMEM;
471 497
472 if (!devm_request_mem_region(&pdev->dev, res->start, 498 mcpdm->io_base = devm_ioremap_resource(&pdev->dev, res);
473 resource_size(res), "McPDM")) 499 if (IS_ERR(mcpdm->io_base))
474 return -EBUSY; 500 return PTR_ERR(mcpdm->io_base);
475
476 mcpdm->io_base = devm_ioremap(&pdev->dev, res->start,
477 resource_size(res));
478 if (!mcpdm->io_base)
479 return -ENOMEM;
480 501
481 mcpdm->irq = platform_get_irq(pdev, 0); 502 mcpdm->irq = platform_get_irq(pdev, 0);
482 if (mcpdm->irq < 0) 503 if (mcpdm->irq < 0)
diff --git a/sound/soc/omap/omap-pcm.c b/sound/soc/omap/omap-pcm.c
index c722c2ef9665..c8e272f9c2de 100644
--- a/sound/soc/omap/omap-pcm.c
+++ b/sound/soc/omap/omap-pcm.c
@@ -32,8 +32,6 @@
32#include <sound/dmaengine_pcm.h> 32#include <sound/dmaengine_pcm.h>
33#include <sound/soc.h> 33#include <sound/soc.h>
34 34
35#include "omap-pcm.h"
36
37#ifdef CONFIG_ARCH_OMAP1 35#ifdef CONFIG_ARCH_OMAP1
38#define pcm_omap1510() cpu_is_omap1510() 36#define pcm_omap1510() cpu_is_omap1510()
39#else 37#else
@@ -56,25 +54,6 @@ static const struct snd_pcm_hardware omap_pcm_hardware = {
56 .buffer_bytes_max = 128 * 1024, 54 .buffer_bytes_max = 128 * 1024,
57}; 55};
58 56
59static int omap_pcm_get_dma_buswidth(int num_bits)
60{
61 int buswidth;
62
63 switch (num_bits) {
64 case 16:
65 buswidth = DMA_SLAVE_BUSWIDTH_2_BYTES;
66 break;
67 case 32:
68 buswidth = DMA_SLAVE_BUSWIDTH_4_BYTES;
69 break;
70 default:
71 buswidth = -EINVAL;
72 break;
73 }
74 return buswidth;
75}
76
77
78/* this may get called several times by oss emulation */ 57/* this may get called several times by oss emulation */
79static int omap_pcm_hw_params(struct snd_pcm_substream *substream, 58static int omap_pcm_hw_params(struct snd_pcm_substream *substream,
80 struct snd_pcm_hw_params *params) 59 struct snd_pcm_hw_params *params)
@@ -105,20 +84,9 @@ static int omap_pcm_hw_params(struct snd_pcm_substream *substream,
105 if (err) 84 if (err)
106 return err; 85 return err;
107 86
108 /* Override the *_dma addr_width if requested by the DAI driver */ 87 snd_dmaengine_pcm_set_config_from_dai_data(substream,
109 if (dma_data->data_type) { 88 snd_soc_dai_get_dma_data(rtd->cpu_dai, substream),
110 int buswidth = omap_pcm_get_dma_buswidth(dma_data->data_type); 89 &config);
111
112 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
113 config.dst_addr_width = buswidth;
114 else
115 config.src_addr_width = buswidth;
116 }
117
118 config.src_addr = dma_data->port_addr;
119 config.dst_addr = dma_data->port_addr;
120 config.src_maxburst = dma_data->packet_size;
121 config.dst_maxburst = dma_data->packet_size;
122 90
123 return dmaengine_slave_config(chan, &config); 91 return dmaengine_slave_config(chan, &config);
124} 92}
@@ -129,37 +97,6 @@ static int omap_pcm_hw_free(struct snd_pcm_substream *substream)
129 return 0; 97 return 0;
130} 98}
131 99
132static int omap_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
133{
134 struct snd_soc_pcm_runtime *rtd = substream->private_data;
135 struct omap_pcm_dma_data *dma_data;
136 int ret = 0;
137
138 dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
139
140 switch (cmd) {
141 case SNDRV_PCM_TRIGGER_START:
142 case SNDRV_PCM_TRIGGER_RESUME:
143 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
144 /* Configure McBSP internal buffer usage */
145 if (dma_data->set_threshold)
146 dma_data->set_threshold(substream);
147 break;
148
149 case SNDRV_PCM_TRIGGER_STOP:
150 case SNDRV_PCM_TRIGGER_SUSPEND:
151 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
152 break;
153 default:
154 ret = -EINVAL;
155 }
156
157 if (ret == 0)
158 ret = snd_dmaengine_pcm_trigger(substream, cmd);
159
160 return ret;
161}
162
163static snd_pcm_uframes_t omap_pcm_pointer(struct snd_pcm_substream *substream) 100static snd_pcm_uframes_t omap_pcm_pointer(struct snd_pcm_substream *substream)
164{ 101{
165 snd_pcm_uframes_t offset; 102 snd_pcm_uframes_t offset;
@@ -175,20 +112,14 @@ static snd_pcm_uframes_t omap_pcm_pointer(struct snd_pcm_substream *substream)
175static int omap_pcm_open(struct snd_pcm_substream *substream) 112static int omap_pcm_open(struct snd_pcm_substream *substream)
176{ 113{
177 struct snd_soc_pcm_runtime *rtd = substream->private_data; 114 struct snd_soc_pcm_runtime *rtd = substream->private_data;
178 struct omap_pcm_dma_data *dma_data; 115 struct snd_dmaengine_dai_dma_data *dma_data;
179 116
180 snd_soc_set_runtime_hwparams(substream, &omap_pcm_hardware); 117 snd_soc_set_runtime_hwparams(substream, &omap_pcm_hardware);
181 118
182 dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); 119 dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
183 120
184 return snd_dmaengine_pcm_open(substream, omap_dma_filter_fn, 121 return snd_dmaengine_pcm_open(substream, omap_dma_filter_fn,
185 &dma_data->dma_req); 122 dma_data->filter_data);
186}
187
188static int omap_pcm_close(struct snd_pcm_substream *substream)
189{
190 snd_dmaengine_pcm_close(substream);
191 return 0;
192} 123}
193 124
194static int omap_pcm_mmap(struct snd_pcm_substream *substream, 125static int omap_pcm_mmap(struct snd_pcm_substream *substream,
@@ -204,11 +135,11 @@ static int omap_pcm_mmap(struct snd_pcm_substream *substream,
204 135
205static struct snd_pcm_ops omap_pcm_ops = { 136static struct snd_pcm_ops omap_pcm_ops = {
206 .open = omap_pcm_open, 137 .open = omap_pcm_open,
207 .close = omap_pcm_close, 138 .close = snd_dmaengine_pcm_close,
208 .ioctl = snd_pcm_lib_ioctl, 139 .ioctl = snd_pcm_lib_ioctl,
209 .hw_params = omap_pcm_hw_params, 140 .hw_params = omap_pcm_hw_params,
210 .hw_free = omap_pcm_hw_free, 141 .hw_free = omap_pcm_hw_free,
211 .trigger = omap_pcm_trigger, 142 .trigger = snd_dmaengine_pcm_trigger,
212 .pointer = omap_pcm_pointer, 143 .pointer = omap_pcm_pointer,
213 .mmap = omap_pcm_mmap, 144 .mmap = omap_pcm_mmap,
214}; 145};
diff --git a/sound/soc/omap/omap-pcm.h b/sound/soc/omap/omap-pcm.h
deleted file mode 100644
index cabe74c4068b..000000000000
--- a/sound/soc/omap/omap-pcm.h
+++ /dev/null
@@ -1,40 +0,0 @@
1/*
2 * omap-pcm.h
3 *
4 * Copyright (C) 2008 Nokia Corporation
5 *
6 * Contact: Jarkko Nikula <jarkko.nikula@bitmer.com>
7 * Peter Ujfalusi <peter.ujfalusi@ti.com>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * version 2 as published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
21 * 02110-1301 USA
22 *
23 */
24
25#ifndef __OMAP_PCM_H__
26#define __OMAP_PCM_H__
27
28struct snd_pcm_substream;
29
30struct omap_pcm_dma_data {
31 char *name; /* stream identifier */
32 int dma_req; /* DMA request line */
33 unsigned long port_addr; /* transmit/receive register */
34 void (*set_threshold)(struct snd_pcm_substream *substream);
35 int data_type; /* 8, 16, 32 (bits) or 0 to let omap-pcm
36 * to decide the sDMA data type */
37 int packet_size; /* packet size only in PACKET mode */
38};
39
40#endif
diff --git a/sound/soc/omap/omap-twl4030.c b/sound/soc/omap/omap-twl4030.c
index fd98509d0f49..2a9324f794d8 100644
--- a/sound/soc/omap/omap-twl4030.c
+++ b/sound/soc/omap/omap-twl4030.c
@@ -43,7 +43,6 @@
43#include <sound/jack.h> 43#include <sound/jack.h>
44 44
45#include "omap-mcbsp.h" 45#include "omap-mcbsp.h"
46#include "omap-pcm.h"
47 46
48struct omap_twl4030 { 47struct omap_twl4030 {
49 int jack_detect; /* board can detect jack events */ 48 int jack_detect; /* board can detect jack events */
diff --git a/sound/soc/omap/omap3pandora.c b/sound/soc/omap/omap3pandora.c
index 805512f2555a..cf604a2faa18 100644
--- a/sound/soc/omap/omap3pandora.c
+++ b/sound/soc/omap/omap3pandora.c
@@ -34,7 +34,6 @@
34#include <linux/platform_data/asoc-ti-mcbsp.h> 34#include <linux/platform_data/asoc-ti-mcbsp.h>
35 35
36#include "omap-mcbsp.h" 36#include "omap-mcbsp.h"
37#include "omap-pcm.h"
38 37
39#define OMAP3_PANDORA_DAC_POWER_GPIO 118 38#define OMAP3_PANDORA_DAC_POWER_GPIO 118
40#define OMAP3_PANDORA_AMP_POWER_GPIO 14 39#define OMAP3_PANDORA_AMP_POWER_GPIO 14
@@ -80,12 +79,18 @@ static int omap3pandora_hw_params(struct snd_pcm_substream *substream,
80static int omap3pandora_dac_event(struct snd_soc_dapm_widget *w, 79static int omap3pandora_dac_event(struct snd_soc_dapm_widget *w,
81 struct snd_kcontrol *k, int event) 80 struct snd_kcontrol *k, int event)
82{ 81{
82 int ret;
83
83 /* 84 /*
84 * The PCM1773 DAC datasheet requires 1ms delay between switching 85 * The PCM1773 DAC datasheet requires 1ms delay between switching
85 * VCC power on/off and /PD pin high/low 86 * VCC power on/off and /PD pin high/low
86 */ 87 */
87 if (SND_SOC_DAPM_EVENT_ON(event)) { 88 if (SND_SOC_DAPM_EVENT_ON(event)) {
88 regulator_enable(omap3pandora_dac_reg); 89 ret = regulator_enable(omap3pandora_dac_reg);
90 if (ret) {
91 dev_err(w->dapm->dev, "Failed to power DAC: %d\n", ret);
92 return ret;
93 }
89 mdelay(1); 94 mdelay(1);
90 gpio_set_value(OMAP3_PANDORA_DAC_POWER_GPIO, 1); 95 gpio_set_value(OMAP3_PANDORA_DAC_POWER_GPIO, 1);
91 } else { 96 } else {
diff --git a/sound/soc/omap/osk5912.c b/sound/soc/omap/osk5912.c
index 06ef8d67ed1c..d03e57da7708 100644
--- a/sound/soc/omap/osk5912.c
+++ b/sound/soc/omap/osk5912.c
@@ -33,7 +33,6 @@
33#include <linux/platform_data/asoc-ti-mcbsp.h> 33#include <linux/platform_data/asoc-ti-mcbsp.h>
34 34
35#include "omap-mcbsp.h" 35#include "omap-mcbsp.h"
36#include "omap-pcm.h"
37#include "../codecs/tlv320aic23.h" 36#include "../codecs/tlv320aic23.h"
38 37
39#define CODEC_CLOCK 12000000 38#define CODEC_CLOCK 12000000
diff --git a/sound/soc/omap/rx51.c b/sound/soc/omap/rx51.c
index 3cd525748975..249cd230ad8f 100644
--- a/sound/soc/omap/rx51.c
+++ b/sound/soc/omap/rx51.c
@@ -37,7 +37,6 @@
37#include <asm/mach-types.h> 37#include <asm/mach-types.h>
38 38
39#include "omap-mcbsp.h" 39#include "omap-mcbsp.h"
40#include "omap-pcm.h"
41 40
42#define RX51_TVOUT_SEL_GPIO 40 41#define RX51_TVOUT_SEL_GPIO 40
43#define RX51_JACK_DETECT_GPIO 177 42#define RX51_JACK_DETECT_GPIO 177
diff --git a/sound/soc/pxa/mmp-pcm.c b/sound/soc/pxa/mmp-pcm.c
index 190eb0bccf5f..6c3980252bf6 100644
--- a/sound/soc/pxa/mmp-pcm.c
+++ b/sound/soc/pxa/mmp-pcm.c
@@ -118,9 +118,8 @@ static int mmp_pcm_open(struct snd_pcm_substream *substream)
118 struct snd_soc_pcm_runtime *rtd = substream->private_data; 118 struct snd_soc_pcm_runtime *rtd = substream->private_data;
119 struct platform_device *pdev = to_platform_device(rtd->platform->dev); 119 struct platform_device *pdev = to_platform_device(rtd->platform->dev);
120 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 120 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
121 struct mmp_dma_data *dma_data; 121 struct mmp_dma_data dma_data;
122 struct resource *r; 122 struct resource *r;
123 int ret;
124 123
125 r = platform_get_resource(pdev, IORESOURCE_DMA, substream->stream); 124 r = platform_get_resource(pdev, IORESOURCE_DMA, substream->stream);
126 if (!r) 125 if (!r)
@@ -128,33 +127,11 @@ static int mmp_pcm_open(struct snd_pcm_substream *substream)
128 127
129 snd_soc_set_runtime_hwparams(substream, 128 snd_soc_set_runtime_hwparams(substream,
130 &mmp_pcm_hardware[substream->stream]); 129 &mmp_pcm_hardware[substream->stream]);
131 dma_data = devm_kzalloc(&pdev->dev,
132 sizeof(struct mmp_dma_data), GFP_KERNEL);
133 if (dma_data == NULL)
134 return -ENOMEM;
135 130
136 dma_data->dma_res = r; 131 dma_data.dma_res = r;
137 dma_data->ssp_id = cpu_dai->id; 132 dma_data.ssp_id = cpu_dai->id;
138 133
139 ret = snd_dmaengine_pcm_open(substream, filter, dma_data); 134 return snd_dmaengine_pcm_open(substream, filter, &dma_data);
140 if (ret) {
141 devm_kfree(&pdev->dev, dma_data);
142 return ret;
143 }
144
145 snd_dmaengine_pcm_set_data(substream, dma_data);
146 return 0;
147}
148
149static int mmp_pcm_close(struct snd_pcm_substream *substream)
150{
151 struct mmp_dma_data *dma_data = snd_dmaengine_pcm_get_data(substream);
152 struct snd_soc_pcm_runtime *rtd = substream->private_data;
153 struct platform_device *pdev = to_platform_device(rtd->platform->dev);
154
155 snd_dmaengine_pcm_close(substream);
156 devm_kfree(&pdev->dev, dma_data);
157 return 0;
158} 135}
159 136
160static int mmp_pcm_mmap(struct snd_pcm_substream *substream, 137static int mmp_pcm_mmap(struct snd_pcm_substream *substream,
@@ -171,7 +148,7 @@ static int mmp_pcm_mmap(struct snd_pcm_substream *substream,
171 148
172struct snd_pcm_ops mmp_pcm_ops = { 149struct snd_pcm_ops mmp_pcm_ops = {
173 .open = mmp_pcm_open, 150 .open = mmp_pcm_open,
174 .close = mmp_pcm_close, 151 .close = snd_dmaengine_pcm_close,
175 .ioctl = snd_pcm_lib_ioctl, 152 .ioctl = snd_pcm_lib_ioctl,
176 .hw_params = mmp_pcm_hw_params, 153 .hw_params = mmp_pcm_hw_params,
177 .trigger = snd_dmaengine_pcm_trigger, 154 .trigger = snd_dmaengine_pcm_trigger,
diff --git a/sound/soc/soc-dmaengine-pcm.c b/sound/soc/soc-dmaengine-pcm.c
index 111b7d921e89..a9a300acb506 100644
--- a/sound/soc/soc-dmaengine-pcm.c
+++ b/sound/soc/soc-dmaengine-pcm.c
@@ -33,8 +33,6 @@ struct dmaengine_pcm_runtime_data {
33 dma_cookie_t cookie; 33 dma_cookie_t cookie;
34 34
35 unsigned int pos; 35 unsigned int pos;
36
37 void *data;
38}; 36};
39 37
40static inline struct dmaengine_pcm_runtime_data *substream_to_prtd( 38static inline struct dmaengine_pcm_runtime_data *substream_to_prtd(
@@ -43,33 +41,6 @@ static inline struct dmaengine_pcm_runtime_data *substream_to_prtd(
43 return substream->runtime->private_data; 41 return substream->runtime->private_data;
44} 42}
45 43
46/**
47 * snd_dmaengine_pcm_set_data - Set dmaengine substream private data
48 * @substream: PCM substream
49 * @data: Data to set
50 */
51void snd_dmaengine_pcm_set_data(struct snd_pcm_substream *substream, void *data)
52{
53 struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream);
54
55 prtd->data = data;
56}
57EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_set_data);
58
59/**
60 * snd_dmaengine_pcm_get_data - Get dmaeinge substream private data
61 * @substream: PCM substream
62 *
63 * Returns the data previously set with snd_dmaengine_pcm_set_data
64 */
65void *snd_dmaengine_pcm_get_data(struct snd_pcm_substream *substream)
66{
67 struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream);
68
69 return prtd->data;
70}
71EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_get_data);
72
73struct dma_chan *snd_dmaengine_pcm_get_chan(struct snd_pcm_substream *substream) 44struct dma_chan *snd_dmaengine_pcm_get_chan(struct snd_pcm_substream *substream)
74{ 45{
75 struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream); 46 struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream);
@@ -118,10 +89,49 @@ int snd_hwparams_to_dma_slave_config(const struct snd_pcm_substream *substream,
118 slave_config->src_addr_width = buswidth; 89 slave_config->src_addr_width = buswidth;
119 } 90 }
120 91
92 slave_config->device_fc = false;
93
121 return 0; 94 return 0;
122} 95}
123EXPORT_SYMBOL_GPL(snd_hwparams_to_dma_slave_config); 96EXPORT_SYMBOL_GPL(snd_hwparams_to_dma_slave_config);
124 97
98/**
99 * snd_dmaengine_pcm_set_config_from_dai_data() - Initializes a dma slave config
100 * using DAI DMA data.
101 * @substream: PCM substream
102 * @dma_data: DAI DMA data
103 * @slave_config: DMA slave configuration
104 *
105 * Initializes the {dst,src}_addr, {dst,src}_maxburst, {dst,src}_addr_width and
106 * slave_id fields of the DMA slave config from the same fields of the DAI DMA
107 * data struct. The src and dst fields will be initialized depending on the
108 * direction of the substream. If the substream is a playback stream the dst
109 * fields will be initialized, if it is a capture stream the src fields will be
110 * initialized. The {dst,src}_addr_width field will only be initialized if the
111 * addr_width field of the DAI DMA data struct is not equal to
112 * DMA_SLAVE_BUSWIDTH_UNDEFINED.
113 */
114void snd_dmaengine_pcm_set_config_from_dai_data(
115 const struct snd_pcm_substream *substream,
116 const struct snd_dmaengine_dai_dma_data *dma_data,
117 struct dma_slave_config *slave_config)
118{
119 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
120 slave_config->dst_addr = dma_data->addr;
121 slave_config->dst_maxburst = dma_data->maxburst;
122 if (dma_data->addr_width != DMA_SLAVE_BUSWIDTH_UNDEFINED)
123 slave_config->dst_addr_width = dma_data->addr_width;
124 } else {
125 slave_config->src_addr = dma_data->addr;
126 slave_config->src_maxburst = dma_data->maxburst;
127 if (dma_data->addr_width != DMA_SLAVE_BUSWIDTH_UNDEFINED)
128 slave_config->src_addr_width = dma_data->addr_width;
129 }
130
131 slave_config->slave_id = dma_data->slave_id;
132}
133EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_set_config_from_dai_data);
134
125static void dmaengine_pcm_dma_complete(void *arg) 135static void dmaengine_pcm_dma_complete(void *arg)
126{ 136{
127 struct snd_pcm_substream *substream = arg; 137 struct snd_pcm_substream *substream = arg;
diff --git a/sound/soc/spear/spear_pcm.c b/sound/soc/spear/spear_pcm.c
index 5e7aebe1e664..23fb09addd21 100644
--- a/sound/soc/spear/spear_pcm.c
+++ b/sound/soc/spear/spear_pcm.c
@@ -64,21 +64,7 @@ static int spear_pcm_open(struct snd_pcm_substream *substream)
64 if (ret) 64 if (ret)
65 return ret; 65 return ret;
66 66
67 ret = snd_dmaengine_pcm_open(substream, dma_data->filter, dma_data); 67 return snd_dmaengine_pcm_open(substream, dma_data->filter, dma_data)
68 if (ret)
69 return ret;
70
71 snd_dmaengine_pcm_set_data(substream, dma_data);
72
73 return 0;
74}
75
76static int spear_pcm_close(struct snd_pcm_substream *substream)
77{
78
79 snd_dmaengine_pcm_close(substream);
80
81 return 0;
82} 68}
83 69
84static int spear_pcm_mmap(struct snd_pcm_substream *substream, 70static int spear_pcm_mmap(struct snd_pcm_substream *substream,
@@ -93,7 +79,7 @@ static int spear_pcm_mmap(struct snd_pcm_substream *substream,
93 79
94static struct snd_pcm_ops spear_pcm_ops = { 80static struct snd_pcm_ops spear_pcm_ops = {
95 .open = spear_pcm_open, 81 .open = spear_pcm_open,
96 .close = spear_pcm_close, 82 .close = snd_dmaengine_pcm_close,
97 .ioctl = snd_pcm_lib_ioctl, 83 .ioctl = snd_pcm_lib_ioctl,
98 .hw_params = spear_pcm_hw_params, 84 .hw_params = spear_pcm_hw_params,
99 .hw_free = spear_pcm_hw_free, 85 .hw_free = spear_pcm_hw_free,
diff --git a/sound/soc/tegra/tegra20_ac97.c b/sound/soc/tegra/tegra20_ac97.c
index b5cee92f82e8..2f70ea7f6618 100644
--- a/sound/soc/tegra/tegra20_ac97.c
+++ b/sound/soc/tegra/tegra20_ac97.c
@@ -35,6 +35,7 @@
35#include <sound/pcm.h> 35#include <sound/pcm.h>
36#include <sound/pcm_params.h> 36#include <sound/pcm_params.h>
37#include <sound/soc.h> 37#include <sound/soc.h>
38#include <sound/dmaengine_pcm.h>
38 39
39#include "tegra_asoc_utils.h" 40#include "tegra_asoc_utils.h"
40#include "tegra20_ac97.h" 41#include "tegra20_ac97.h"
@@ -393,14 +394,14 @@ static int tegra20_ac97_platform_probe(struct platform_device *pdev)
393 } 394 }
394 395
395 ac97->capture_dma_data.addr = mem->start + TEGRA20_AC97_FIFO_RX1; 396 ac97->capture_dma_data.addr = mem->start + TEGRA20_AC97_FIFO_RX1;
396 ac97->capture_dma_data.wrap = 4; 397 ac97->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
397 ac97->capture_dma_data.width = 32; 398 ac97->capture_dma_data.maxburst = 4;
398 ac97->capture_dma_data.req_sel = of_dma[1]; 399 ac97->capture_dma_data.slave_id = of_dma[1];
399 400
400 ac97->playback_dma_data.addr = mem->start + TEGRA20_AC97_FIFO_TX1; 401 ac97->playback_dma_data.addr = mem->start + TEGRA20_AC97_FIFO_TX1;
401 ac97->playback_dma_data.wrap = 4; 402 ac97->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
402 ac97->playback_dma_data.width = 32; 403 ac97->capture_dma_data.maxburst = 4;
403 ac97->playback_dma_data.req_sel = of_dma[1]; 404 ac97->capture_dma_data.slave_id = of_dma[0];
404 405
405 ret = snd_soc_register_component(&pdev->dev, &tegra20_ac97_component, 406 ret = snd_soc_register_component(&pdev->dev, &tegra20_ac97_component,
406 &tegra20_ac97_dai, 1); 407 &tegra20_ac97_dai, 1);
diff --git a/sound/soc/tegra/tegra20_ac97.h b/sound/soc/tegra/tegra20_ac97.h
index dddc6828004e..4acb3aaba29b 100644
--- a/sound/soc/tegra/tegra20_ac97.h
+++ b/sound/soc/tegra/tegra20_ac97.h
@@ -85,8 +85,8 @@
85 85
86struct tegra20_ac97 { 86struct tegra20_ac97 {
87 struct clk *clk_ac97; 87 struct clk *clk_ac97;
88 struct tegra_pcm_dma_params capture_dma_data; 88 struct snd_dmaengine_dai_dma_data capture_dma_data;
89 struct tegra_pcm_dma_params playback_dma_data; 89 struct snd_dmaengine_dai_dma_data playback_dma_data;
90 struct regmap *regmap; 90 struct regmap *regmap;
91 int reset_gpio; 91 int reset_gpio;
92 int sync_gpio; 92 int sync_gpio;
diff --git a/sound/soc/tegra/tegra20_i2s.c b/sound/soc/tegra/tegra20_i2s.c
index 8b1ceb82c86f..52af7f6fb37f 100644
--- a/sound/soc/tegra/tegra20_i2s.c
+++ b/sound/soc/tegra/tegra20_i2s.c
@@ -41,6 +41,7 @@
41#include <sound/pcm.h> 41#include <sound/pcm.h>
42#include <sound/pcm_params.h> 42#include <sound/pcm_params.h>
43#include <sound/soc.h> 43#include <sound/soc.h>
44#include <sound/dmaengine_pcm.h>
44 45
45#include "tegra20_i2s.h" 46#include "tegra20_i2s.h"
46 47
@@ -407,14 +408,14 @@ static int tegra20_i2s_platform_probe(struct platform_device *pdev)
407 } 408 }
408 409
409 i2s->capture_dma_data.addr = mem->start + TEGRA20_I2S_FIFO2; 410 i2s->capture_dma_data.addr = mem->start + TEGRA20_I2S_FIFO2;
410 i2s->capture_dma_data.wrap = 4; 411 i2s->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
411 i2s->capture_dma_data.width = 32; 412 i2s->capture_dma_data.maxburst = 4;
412 i2s->capture_dma_data.req_sel = dma_ch; 413 i2s->capture_dma_data.slave_id = dma_ch;
413 414
414 i2s->playback_dma_data.addr = mem->start + TEGRA20_I2S_FIFO1; 415 i2s->playback_dma_data.addr = mem->start + TEGRA20_I2S_FIFO1;
415 i2s->playback_dma_data.wrap = 4; 416 i2s->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
416 i2s->playback_dma_data.width = 32; 417 i2s->playback_dma_data.maxburst = 4;
417 i2s->playback_dma_data.req_sel = dma_ch; 418 i2s->playback_dma_data.slave_id = dma_ch;
418 419
419 pm_runtime_enable(&pdev->dev); 420 pm_runtime_enable(&pdev->dev);
420 if (!pm_runtime_enabled(&pdev->dev)) { 421 if (!pm_runtime_enabled(&pdev->dev)) {
diff --git a/sound/soc/tegra/tegra20_i2s.h b/sound/soc/tegra/tegra20_i2s.h
index 729958713cd4..fa6c29cc12b9 100644
--- a/sound/soc/tegra/tegra20_i2s.h
+++ b/sound/soc/tegra/tegra20_i2s.h
@@ -155,8 +155,8 @@
155struct tegra20_i2s { 155struct tegra20_i2s {
156 struct snd_soc_dai_driver dai; 156 struct snd_soc_dai_driver dai;
157 struct clk *clk_i2s; 157 struct clk *clk_i2s;
158 struct tegra_pcm_dma_params capture_dma_data; 158 struct snd_dmaengine_dai_dma_data capture_dma_data;
159 struct tegra_pcm_dma_params playback_dma_data; 159 struct snd_dmaengine_dai_dma_data playback_dma_data;
160 struct regmap *regmap; 160 struct regmap *regmap;
161}; 161};
162 162
diff --git a/sound/soc/tegra/tegra20_spdif.c b/sound/soc/tegra/tegra20_spdif.c
index 6fce0be5eaa3..5eaa12cdc6eb 100644
--- a/sound/soc/tegra/tegra20_spdif.c
+++ b/sound/soc/tegra/tegra20_spdif.c
@@ -32,6 +32,7 @@
32#include <sound/pcm.h> 32#include <sound/pcm.h>
33#include <sound/pcm_params.h> 33#include <sound/pcm_params.h>
34#include <sound/soc.h> 34#include <sound/soc.h>
35#include <sound/dmaengine_pcm.h>
35 36
36#include "tegra20_spdif.h" 37#include "tegra20_spdif.h"
37 38
@@ -322,9 +323,9 @@ static int tegra20_spdif_platform_probe(struct platform_device *pdev)
322 } 323 }
323 324
324 spdif->playback_dma_data.addr = mem->start + TEGRA20_SPDIF_DATA_OUT; 325 spdif->playback_dma_data.addr = mem->start + TEGRA20_SPDIF_DATA_OUT;
325 spdif->playback_dma_data.wrap = 4; 326 spdif->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
326 spdif->playback_dma_data.width = 32; 327 spdif->capture_dma_data.maxburst = 4;
327 spdif->playback_dma_data.req_sel = dmareq->start; 328 spdif->playback_dma_data.slave_id = dmareq->start;
328 329
329 pm_runtime_enable(&pdev->dev); 330 pm_runtime_enable(&pdev->dev);
330 if (!pm_runtime_enabled(&pdev->dev)) { 331 if (!pm_runtime_enabled(&pdev->dev)) {
diff --git a/sound/soc/tegra/tegra20_spdif.h b/sound/soc/tegra/tegra20_spdif.h
index b48d699fd583..85a9aefcc287 100644
--- a/sound/soc/tegra/tegra20_spdif.h
+++ b/sound/soc/tegra/tegra20_spdif.h
@@ -462,8 +462,8 @@
462 462
463struct tegra20_spdif { 463struct tegra20_spdif {
464 struct clk *clk_spdif_out; 464 struct clk *clk_spdif_out;
465 struct tegra_pcm_dma_params capture_dma_data; 465 struct snd_dmaengine_dai_dma_data capture_dma_data;
466 struct tegra_pcm_dma_params playback_dma_data; 466 struct snd_dmaengine_dai_dma_data playback_dma_data;
467 struct regmap *regmap; 467 struct regmap *regmap;
468}; 468};
469 469
diff --git a/sound/soc/tegra/tegra30_ahub.c b/sound/soc/tegra/tegra30_ahub.c
index e5cfb4ac41ba..5e08f3e7e6cf 100644
--- a/sound/soc/tegra/tegra30_ahub.c
+++ b/sound/soc/tegra/tegra30_ahub.c
@@ -95,8 +95,8 @@ static int tegra30_ahub_runtime_resume(struct device *dev)
95} 95}
96 96
97int tegra30_ahub_allocate_rx_fifo(enum tegra30_ahub_rxcif *rxcif, 97int tegra30_ahub_allocate_rx_fifo(enum tegra30_ahub_rxcif *rxcif,
98 unsigned long *fiforeg, 98 dma_addr_t *fiforeg,
99 unsigned long *reqsel) 99 unsigned int *reqsel)
100{ 100{
101 int channel; 101 int channel;
102 u32 reg, val; 102 u32 reg, val;
@@ -178,8 +178,8 @@ int tegra30_ahub_free_rx_fifo(enum tegra30_ahub_rxcif rxcif)
178EXPORT_SYMBOL_GPL(tegra30_ahub_free_rx_fifo); 178EXPORT_SYMBOL_GPL(tegra30_ahub_free_rx_fifo);
179 179
180int tegra30_ahub_allocate_tx_fifo(enum tegra30_ahub_txcif *txcif, 180int tegra30_ahub_allocate_tx_fifo(enum tegra30_ahub_txcif *txcif,
181 unsigned long *fiforeg, 181 dma_addr_t *fiforeg,
182 unsigned long *reqsel) 182 unsigned int *reqsel)
183{ 183{
184 int channel; 184 int channel;
185 u32 reg, val; 185 u32 reg, val;
diff --git a/sound/soc/tegra/tegra30_ahub.h b/sound/soc/tegra/tegra30_ahub.h
index e690e2eecc92..b7d7c1a30302 100644
--- a/sound/soc/tegra/tegra30_ahub.h
+++ b/sound/soc/tegra/tegra30_ahub.h
@@ -451,15 +451,15 @@ enum tegra30_ahub_rxcif {
451}; 451};
452 452
453extern int tegra30_ahub_allocate_rx_fifo(enum tegra30_ahub_rxcif *rxcif, 453extern int tegra30_ahub_allocate_rx_fifo(enum tegra30_ahub_rxcif *rxcif,
454 unsigned long *fiforeg, 454 dma_addr_t *fiforeg,
455 unsigned long *reqsel); 455 unsigned int *reqsel);
456extern int tegra30_ahub_enable_rx_fifo(enum tegra30_ahub_rxcif rxcif); 456extern int tegra30_ahub_enable_rx_fifo(enum tegra30_ahub_rxcif rxcif);
457extern int tegra30_ahub_disable_rx_fifo(enum tegra30_ahub_rxcif rxcif); 457extern int tegra30_ahub_disable_rx_fifo(enum tegra30_ahub_rxcif rxcif);
458extern int tegra30_ahub_free_rx_fifo(enum tegra30_ahub_rxcif rxcif); 458extern int tegra30_ahub_free_rx_fifo(enum tegra30_ahub_rxcif rxcif);
459 459
460extern int tegra30_ahub_allocate_tx_fifo(enum tegra30_ahub_txcif *txcif, 460extern int tegra30_ahub_allocate_tx_fifo(enum tegra30_ahub_txcif *txcif,
461 unsigned long *fiforeg, 461 dma_addr_t *fiforeg,
462 unsigned long *reqsel); 462 unsigned int *reqsel);
463extern int tegra30_ahub_enable_tx_fifo(enum tegra30_ahub_txcif txcif); 463extern int tegra30_ahub_enable_tx_fifo(enum tegra30_ahub_txcif txcif);
464extern int tegra30_ahub_disable_tx_fifo(enum tegra30_ahub_txcif txcif); 464extern int tegra30_ahub_disable_tx_fifo(enum tegra30_ahub_txcif txcif);
465extern int tegra30_ahub_free_tx_fifo(enum tegra30_ahub_txcif txcif); 465extern int tegra30_ahub_free_tx_fifo(enum tegra30_ahub_txcif txcif);
diff --git a/sound/soc/tegra/tegra30_i2s.c b/sound/soc/tegra/tegra30_i2s.c
index f138d8fea977..31d092d83c71 100644
--- a/sound/soc/tegra/tegra30_i2s.c
+++ b/sound/soc/tegra/tegra30_i2s.c
@@ -38,6 +38,7 @@
38#include <sound/pcm.h> 38#include <sound/pcm.h>
39#include <sound/pcm_params.h> 39#include <sound/pcm_params.h>
40#include <sound/soc.h> 40#include <sound/soc.h>
41#include <sound/dmaengine_pcm.h>
41 42
42#include "tegra30_ahub.h" 43#include "tegra30_ahub.h"
43#include "tegra30_i2s.h" 44#include "tegra30_i2s.h"
@@ -80,17 +81,17 @@ static int tegra30_i2s_startup(struct snd_pcm_substream *substream,
80 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 81 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
81 ret = tegra30_ahub_allocate_tx_fifo(&i2s->playback_fifo_cif, 82 ret = tegra30_ahub_allocate_tx_fifo(&i2s->playback_fifo_cif,
82 &i2s->playback_dma_data.addr, 83 &i2s->playback_dma_data.addr,
83 &i2s->playback_dma_data.req_sel); 84 &i2s->playback_dma_data.slave_id);
84 i2s->playback_dma_data.wrap = 4; 85 i2s->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
85 i2s->playback_dma_data.width = 32; 86 i2s->playback_dma_data.maxburst = 4;
86 tegra30_ahub_set_rx_cif_source(i2s->playback_i2s_cif, 87 tegra30_ahub_set_rx_cif_source(i2s->playback_i2s_cif,
87 i2s->playback_fifo_cif); 88 i2s->playback_fifo_cif);
88 } else { 89 } else {
89 ret = tegra30_ahub_allocate_rx_fifo(&i2s->capture_fifo_cif, 90 ret = tegra30_ahub_allocate_rx_fifo(&i2s->capture_fifo_cif,
90 &i2s->capture_dma_data.addr, 91 &i2s->capture_dma_data.addr,
91 &i2s->capture_dma_data.req_sel); 92 &i2s->capture_dma_data.slave_id);
92 i2s->capture_dma_data.wrap = 4; 93 i2s->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
93 i2s->capture_dma_data.width = 32; 94 i2s->capture_dma_data.maxburst = 4;
94 tegra30_ahub_set_rx_cif_source(i2s->capture_fifo_cif, 95 tegra30_ahub_set_rx_cif_source(i2s->capture_fifo_cif,
95 i2s->capture_i2s_cif); 96 i2s->capture_i2s_cif);
96 } 97 }
diff --git a/sound/soc/tegra/tegra30_i2s.h b/sound/soc/tegra/tegra30_i2s.h
index a294d942b9f7..bea23afe3b9f 100644
--- a/sound/soc/tegra/tegra30_i2s.h
+++ b/sound/soc/tegra/tegra30_i2s.h
@@ -231,10 +231,10 @@ struct tegra30_i2s {
231 struct clk *clk_i2s; 231 struct clk *clk_i2s;
232 enum tegra30_ahub_txcif capture_i2s_cif; 232 enum tegra30_ahub_txcif capture_i2s_cif;
233 enum tegra30_ahub_rxcif capture_fifo_cif; 233 enum tegra30_ahub_rxcif capture_fifo_cif;
234 struct tegra_pcm_dma_params capture_dma_data; 234 struct snd_dmaengine_dai_dma_data capture_dma_data;
235 enum tegra30_ahub_rxcif playback_i2s_cif; 235 enum tegra30_ahub_rxcif playback_i2s_cif;
236 enum tegra30_ahub_txcif playback_fifo_cif; 236 enum tegra30_ahub_txcif playback_fifo_cif;
237 struct tegra_pcm_dma_params playback_dma_data; 237 struct snd_dmaengine_dai_dma_data playback_dma_data;
238 struct regmap *regmap; 238 struct regmap *regmap;
239}; 239};
240 240
diff --git a/sound/soc/tegra/tegra_pcm.c b/sound/soc/tegra/tegra_pcm.c
index 5e2c55c5b255..6d1c70c3d753 100644
--- a/sound/soc/tegra/tegra_pcm.c
+++ b/sound/soc/tegra/tegra_pcm.c
@@ -73,24 +73,15 @@ static int tegra_pcm_open(struct snd_pcm_substream *substream)
73 return 0; 73 return 0;
74} 74}
75 75
76static int tegra_pcm_close(struct snd_pcm_substream *substream)
77{
78 snd_dmaengine_pcm_close(substream);
79 return 0;
80}
81
82static int tegra_pcm_hw_params(struct snd_pcm_substream *substream, 76static int tegra_pcm_hw_params(struct snd_pcm_substream *substream,
83 struct snd_pcm_hw_params *params) 77 struct snd_pcm_hw_params *params)
84{ 78{
85 struct snd_soc_pcm_runtime *rtd = substream->private_data; 79 struct snd_soc_pcm_runtime *rtd = substream->private_data;
86 struct device *dev = rtd->platform->dev; 80 struct device *dev = rtd->platform->dev;
87 struct dma_chan *chan = snd_dmaengine_pcm_get_chan(substream); 81 struct dma_chan *chan = snd_dmaengine_pcm_get_chan(substream);
88 struct tegra_pcm_dma_params *dmap;
89 struct dma_slave_config slave_config; 82 struct dma_slave_config slave_config;
90 int ret; 83 int ret;
91 84
92 dmap = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
93
94 ret = snd_hwparams_to_dma_slave_config(substream, params, 85 ret = snd_hwparams_to_dma_slave_config(substream, params,
95 &slave_config); 86 &slave_config);
96 if (ret) { 87 if (ret) {
@@ -98,16 +89,9 @@ static int tegra_pcm_hw_params(struct snd_pcm_substream *substream,
98 return ret; 89 return ret;
99 } 90 }
100 91
101 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 92 snd_dmaengine_pcm_set_config_from_dai_data(substream,
102 slave_config.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; 93 snd_soc_dai_get_dma_data(rtd->cpu_dai, substream),
103 slave_config.dst_addr = dmap->addr; 94 &slave_config);
104 slave_config.dst_maxburst = 4;
105 } else {
106 slave_config.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
107 slave_config.src_addr = dmap->addr;
108 slave_config.src_maxburst = 4;
109 }
110 slave_config.slave_id = dmap->req_sel;
111 95
112 ret = dmaengine_slave_config(chan, &slave_config); 96 ret = dmaengine_slave_config(chan, &slave_config);
113 if (ret < 0) { 97 if (ret < 0) {
@@ -138,7 +122,7 @@ static int tegra_pcm_mmap(struct snd_pcm_substream *substream,
138 122
139static struct snd_pcm_ops tegra_pcm_ops = { 123static struct snd_pcm_ops tegra_pcm_ops = {
140 .open = tegra_pcm_open, 124 .open = tegra_pcm_open,
141 .close = tegra_pcm_close, 125 .close = snd_dmaengine_pcm_close,
142 .ioctl = snd_pcm_lib_ioctl, 126 .ioctl = snd_pcm_lib_ioctl,
143 .hw_params = tegra_pcm_hw_params, 127 .hw_params = tegra_pcm_hw_params,
144 .hw_free = tegra_pcm_hw_free, 128 .hw_free = tegra_pcm_hw_free,
diff --git a/sound/soc/tegra/tegra_pcm.h b/sound/soc/tegra/tegra_pcm.h
index bc8b46af928e..68ad901714a9 100644
--- a/sound/soc/tegra/tegra_pcm.h
+++ b/sound/soc/tegra/tegra_pcm.h
@@ -31,13 +31,6 @@
31#ifndef __TEGRA_PCM_H__ 31#ifndef __TEGRA_PCM_H__
32#define __TEGRA_PCM_H__ 32#define __TEGRA_PCM_H__
33 33
34struct tegra_pcm_dma_params {
35 unsigned long addr;
36 unsigned long wrap;
37 unsigned long width;
38 unsigned long req_sel;
39};
40
41int tegra_pcm_platform_register(struct device *dev); 34int tegra_pcm_platform_register(struct device *dev);
42void tegra_pcm_platform_unregister(struct device *dev); 35void tegra_pcm_platform_unregister(struct device *dev);
43 36
diff --git a/sound/soc/ux500/ux500_pcm.c b/sound/soc/ux500/ux500_pcm.c
index 846fa82a58d0..09b5364e5095 100644
--- a/sound/soc/ux500/ux500_pcm.c
+++ b/sound/soc/ux500/ux500_pcm.c
@@ -28,28 +28,19 @@
28#include "ux500_msp_i2s.h" 28#include "ux500_msp_i2s.h"
29#include "ux500_pcm.h" 29#include "ux500_pcm.h"
30 30
31static struct snd_pcm_hardware ux500_pcm_hw_playback = { 31#define UX500_PLATFORM_MIN_RATE 8000
32 .info = SNDRV_PCM_INFO_INTERLEAVED | 32#define UX500_PLATFORM_MAX_RATE 48000
33 SNDRV_PCM_INFO_MMAP | 33
34 SNDRV_PCM_INFO_RESUME | 34#define UX500_PLATFORM_MIN_CHANNELS 1
35 SNDRV_PCM_INFO_PAUSE, 35#define UX500_PLATFORM_MAX_CHANNELS 8
36 .formats = SNDRV_PCM_FMTBIT_S16_LE |
37 SNDRV_PCM_FMTBIT_U16_LE |
38 SNDRV_PCM_FMTBIT_S16_BE |
39 SNDRV_PCM_FMTBIT_U16_BE,
40 .rates = SNDRV_PCM_RATE_KNOT,
41 .rate_min = UX500_PLATFORM_MIN_RATE_PLAYBACK,
42 .rate_max = UX500_PLATFORM_MAX_RATE_PLAYBACK,
43 .channels_min = UX500_PLATFORM_MIN_CHANNELS,
44 .channels_max = UX500_PLATFORM_MAX_CHANNELS,
45 .buffer_bytes_max = UX500_PLATFORM_BUFFER_BYTES_MAX,
46 .period_bytes_min = UX500_PLATFORM_PERIODS_BYTES_MIN,
47 .period_bytes_max = UX500_PLATFORM_PERIODS_BYTES_MAX,
48 .periods_min = UX500_PLATFORM_PERIODS_MIN,
49 .periods_max = UX500_PLATFORM_PERIODS_MAX,
50};
51 36
52static struct snd_pcm_hardware ux500_pcm_hw_capture = { 37#define UX500_PLATFORM_PERIODS_BYTES_MIN 128
38#define UX500_PLATFORM_PERIODS_BYTES_MAX (64 * PAGE_SIZE)
39#define UX500_PLATFORM_PERIODS_MIN 2
40#define UX500_PLATFORM_PERIODS_MAX 48
41#define UX500_PLATFORM_BUFFER_BYTES_MAX (2048 * PAGE_SIZE)
42
43static struct snd_pcm_hardware ux500_pcm_hw = {
53 .info = SNDRV_PCM_INFO_INTERLEAVED | 44 .info = SNDRV_PCM_INFO_INTERLEAVED |
54 SNDRV_PCM_INFO_MMAP | 45 SNDRV_PCM_INFO_MMAP |
55 SNDRV_PCM_INFO_RESUME | 46 SNDRV_PCM_INFO_RESUME |
@@ -59,8 +50,8 @@ static struct snd_pcm_hardware ux500_pcm_hw_capture = {
59 SNDRV_PCM_FMTBIT_S16_BE | 50 SNDRV_PCM_FMTBIT_S16_BE |
60 SNDRV_PCM_FMTBIT_U16_BE, 51 SNDRV_PCM_FMTBIT_U16_BE,
61 .rates = SNDRV_PCM_RATE_KNOT, 52 .rates = SNDRV_PCM_RATE_KNOT,
62 .rate_min = UX500_PLATFORM_MIN_RATE_CAPTURE, 53 .rate_min = UX500_PLATFORM_MIN_RATE,
63 .rate_max = UX500_PLATFORM_MAX_RATE_CAPTURE, 54 .rate_max = UX500_PLATFORM_MAX_RATE,
64 .channels_min = UX500_PLATFORM_MIN_CHANNELS, 55 .channels_min = UX500_PLATFORM_MIN_CHANNELS,
65 .channels_max = UX500_PLATFORM_MAX_CHANNELS, 56 .channels_max = UX500_PLATFORM_MAX_CHANNELS,
66 .buffer_bytes_max = UX500_PLATFORM_BUFFER_BYTES_MAX, 57 .buffer_bytes_max = UX500_PLATFORM_BUFFER_BYTES_MAX,
@@ -90,8 +81,6 @@ static void ux500_pcm_dma_hw_free(struct device *dev,
90 81
91static int ux500_pcm_open(struct snd_pcm_substream *substream) 82static int ux500_pcm_open(struct snd_pcm_substream *substream)
92{ 83{
93 int stream_id = substream->pstr->stream;
94 struct snd_pcm_runtime *runtime = substream->runtime;
95 struct snd_soc_pcm_runtime *rtd = substream->private_data; 84 struct snd_soc_pcm_runtime *rtd = substream->private_data;
96 struct snd_soc_dai *dai = rtd->cpu_dai; 85 struct snd_soc_dai *dai = rtd->cpu_dai;
97 struct device *dev = dai->dev; 86 struct device *dev = dai->dev;
@@ -104,26 +93,7 @@ static int ux500_pcm_open(struct snd_pcm_substream *substream)
104 snd_pcm_stream_str(substream)); 93 snd_pcm_stream_str(substream));
105 94
106 dev_dbg(dev, "%s: Set runtime hwparams.\n", __func__); 95 dev_dbg(dev, "%s: Set runtime hwparams.\n", __func__);
107 if (stream_id == SNDRV_PCM_STREAM_PLAYBACK) 96 snd_soc_set_runtime_hwparams(substream, &ux500_pcm_hw);
108 snd_soc_set_runtime_hwparams(substream,
109 &ux500_pcm_hw_playback);
110 else
111 snd_soc_set_runtime_hwparams(substream,
112 &ux500_pcm_hw_capture);
113
114 /* ensure that buffer size is a multiple of period size */
115 ret = snd_pcm_hw_constraint_integer(runtime,
116 SNDRV_PCM_HW_PARAM_PERIODS);
117 if (ret < 0) {
118 dev_err(dev, "%s: Error: snd_pcm_hw_constraints failed (%d)\n",
119 __func__, ret);
120 return ret;
121 }
122
123 dev_dbg(dev, "%s: Set hw-struct for %s.\n", __func__,
124 snd_pcm_stream_str(substream));
125 runtime->hw = (stream_id == SNDRV_PCM_STREAM_PLAYBACK) ?
126 ux500_pcm_hw_playback : ux500_pcm_hw_capture;
127 97
128 mem_data_width = STEDMA40_HALFWORD_WIDTH; 98 mem_data_width = STEDMA40_HALFWORD_WIDTH;
129 99
@@ -164,20 +134,6 @@ static int ux500_pcm_open(struct snd_pcm_substream *substream)
164 return ret; 134 return ret;
165 } 135 }
166 136
167 snd_dmaengine_pcm_set_data(substream, dma_cfg);
168
169 return 0;
170}
171
172static int ux500_pcm_close(struct snd_pcm_substream *substream)
173{
174 struct snd_soc_pcm_runtime *rtd = substream->private_data;
175 struct snd_soc_dai *dai = rtd->cpu_dai;
176
177 dev_dbg(dai->dev, "%s: Enter\n", __func__);
178
179 snd_dmaengine_pcm_close(substream);
180
181 return 0; 137 return 0;
182} 138}
183 139
@@ -255,7 +211,7 @@ static int ux500_pcm_mmap(struct snd_pcm_substream *substream,
255 211
256static struct snd_pcm_ops ux500_pcm_ops = { 212static struct snd_pcm_ops ux500_pcm_ops = {
257 .open = ux500_pcm_open, 213 .open = ux500_pcm_open,
258 .close = ux500_pcm_close, 214 .close = snd_dmaengine_pcm_close,
259 .ioctl = snd_pcm_lib_ioctl, 215 .ioctl = snd_pcm_lib_ioctl,
260 .hw_params = ux500_pcm_hw_params, 216 .hw_params = ux500_pcm_hw_params,
261 .hw_free = ux500_pcm_hw_free, 217 .hw_free = ux500_pcm_hw_free,
diff --git a/sound/soc/ux500/ux500_pcm.h b/sound/soc/ux500/ux500_pcm.h
index 76d344476afc..d76e1aff6458 100644
--- a/sound/soc/ux500/ux500_pcm.h
+++ b/sound/soc/ux500/ux500_pcm.h
@@ -18,20 +18,6 @@
18 18
19#include <linux/workqueue.h> 19#include <linux/workqueue.h>
20 20
21#define UX500_PLATFORM_MIN_RATE_PLAYBACK 8000
22#define UX500_PLATFORM_MAX_RATE_PLAYBACK 48000
23#define UX500_PLATFORM_MIN_RATE_CAPTURE 8000
24#define UX500_PLATFORM_MAX_RATE_CAPTURE 48000
25
26#define UX500_PLATFORM_MIN_CHANNELS 1
27#define UX500_PLATFORM_MAX_CHANNELS 8
28
29#define UX500_PLATFORM_PERIODS_BYTES_MIN 128
30#define UX500_PLATFORM_PERIODS_BYTES_MAX (64 * PAGE_SIZE)
31#define UX500_PLATFORM_PERIODS_MIN 2
32#define UX500_PLATFORM_PERIODS_MAX 48
33#define UX500_PLATFORM_BUFFER_BYTES_MAX (2048 * PAGE_SIZE)
34
35int ux500_pcm_register_platform(struct platform_device *pdev); 21int ux500_pcm_register_platform(struct platform_device *pdev);
36int ux500_pcm_unregister_platform(struct platform_device *pdev); 22int ux500_pcm_unregister_platform(struct platform_device *pdev);
37 23