aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBo Shen <voice.shen@atmel.com>2013-07-03 04:38:00 -0400
committerMark Brown <broonie@linaro.org>2013-07-15 06:07:56 -0400
commit95e0e07e710e24a240f2c9645ecaad3559d6040d (patch)
tree05aef6424b4b67f43eee5e926a90c91b474ede95
parent10175b3b2fdd287515db4c103d96b323bb4cd690 (diff)
ASoC: atmel-pcm: use generic dmaengine framework
Align atmel pcm to use ASoC generic dmaengine framework DMA is fully device tree based Signed-off-by: Bo Shen <voice.shen@atmel.com> Reviewed-by: Lars-Peter Clausen <lars@metafoo.de> Signed-off-by: Mark Brown <broonie@linaro.org>
-rw-r--r--sound/soc/atmel/Kconfig1
-rw-r--r--sound/soc/atmel/atmel-pcm-dma.c104
2 files changed, 17 insertions, 88 deletions
diff --git a/sound/soc/atmel/Kconfig b/sound/soc/atmel/Kconfig
index 3fdd87fa18a9..1c0b1858638c 100644
--- a/sound/soc/atmel/Kconfig
+++ b/sound/soc/atmel/Kconfig
@@ -13,6 +13,7 @@ config SND_ATMEL_SOC_PDC
13config SND_ATMEL_SOC_DMA 13config SND_ATMEL_SOC_DMA
14 tristate 14 tristate
15 depends on SND_ATMEL_SOC 15 depends on SND_ATMEL_SOC
16 select SND_SOC_GENERIC_DMAENGINE_PCM
16 17
17config SND_ATMEL_SOC_SSC 18config SND_ATMEL_SOC_SSC
18 tristate 19 tristate
diff --git a/sound/soc/atmel/atmel-pcm-dma.c b/sound/soc/atmel/atmel-pcm-dma.c
index 5a57803cb180..3ff5601eef10 100644
--- a/sound/soc/atmel/atmel-pcm-dma.c
+++ b/sound/soc/atmel/atmel-pcm-dma.c
@@ -89,124 +89,52 @@ static void atmel_pcm_dma_irq(u32 ssc_sr,
89 } 89 }
90} 90}
91 91
92/*--------------------------------------------------------------------------*\
93 * DMAENGINE operations
94\*--------------------------------------------------------------------------*/
95static bool filter(struct dma_chan *chan, void *slave)
96{
97 struct at_dma_slave *sl = slave;
98
99 if (sl->dma_dev == chan->device->dev) {
100 chan->private = sl;
101 return true;
102 } else {
103 return false;
104 }
105}
106
107static int atmel_pcm_configure_dma(struct snd_pcm_substream *substream, 92static int atmel_pcm_configure_dma(struct snd_pcm_substream *substream,
108 struct snd_pcm_hw_params *params, struct atmel_pcm_dma_params *prtd) 93 struct snd_pcm_hw_params *params, struct dma_slave_config *slave_config)
109{ 94{
95 struct snd_soc_pcm_runtime *rtd = substream->private_data;
96 struct atmel_pcm_dma_params *prtd;
110 struct ssc_device *ssc; 97 struct ssc_device *ssc;
111 struct dma_chan *dma_chan;
112 struct dma_slave_config slave_config;
113 int ret; 98 int ret;
114 99
100 prtd = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
115 ssc = prtd->ssc; 101 ssc = prtd->ssc;
116 102
117 ret = snd_hwparams_to_dma_slave_config(substream, params, 103 ret = snd_hwparams_to_dma_slave_config(substream, params, slave_config);
118 &slave_config);
119 if (ret) { 104 if (ret) {
120 pr_err("atmel-pcm: hwparams to dma slave configure failed\n"); 105 pr_err("atmel-pcm: hwparams to dma slave configure failed\n");
121 return ret; 106 return ret;
122 } 107 }
123 108
124 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 109 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
125 slave_config.dst_addr = (dma_addr_t)ssc->phybase + SSC_THR; 110 slave_config->dst_addr = ssc->phybase + SSC_THR;
126 slave_config.dst_maxburst = 1; 111 slave_config->dst_maxburst = 1;
127 } else { 112 } else {
128 slave_config.src_addr = (dma_addr_t)ssc->phybase + SSC_RHR; 113 slave_config->src_addr = ssc->phybase + SSC_RHR;
129 slave_config.src_maxburst = 1; 114 slave_config->src_maxburst = 1;
130 }
131
132 dma_chan = snd_dmaengine_pcm_get_chan(substream);
133 if (dmaengine_slave_config(dma_chan, &slave_config)) {
134 pr_err("atmel-pcm: failed to configure dma channel\n");
135 ret = -EBUSY;
136 return ret;
137 }
138
139 return 0;
140}
141
142static int atmel_pcm_hw_params(struct snd_pcm_substream *substream,
143 struct snd_pcm_hw_params *params)
144{
145 struct snd_soc_pcm_runtime *rtd = substream->private_data;
146 struct atmel_pcm_dma_params *prtd;
147 struct ssc_device *ssc;
148 struct at_dma_slave *sdata = NULL;
149 int ret;
150
151 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
152
153 prtd = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
154 ssc = prtd->ssc;
155 if (ssc->pdev)
156 sdata = ssc->pdev->dev.platform_data;
157
158 ret = snd_dmaengine_pcm_open_request_chan(substream, filter, sdata);
159 if (ret) {
160 pr_err("atmel-pcm: dmaengine pcm open failed\n");
161 return -EINVAL;
162 }
163
164 ret = atmel_pcm_configure_dma(substream, params, prtd);
165 if (ret) {
166 pr_err("atmel-pcm: failed to configure dmai\n");
167 goto err;
168 } 115 }
169 116
170 prtd->dma_intr_handler = atmel_pcm_dma_irq; 117 prtd->dma_intr_handler = atmel_pcm_dma_irq;
171 118
172 return 0; 119 return 0;
173err:
174 snd_dmaengine_pcm_close_release_chan(substream);
175 return ret;
176}
177
178static int atmel_pcm_open(struct snd_pcm_substream *substream)
179{
180 snd_soc_set_runtime_hwparams(substream, &atmel_pcm_dma_hardware);
181
182 return 0;
183} 120}
184 121
185static struct snd_pcm_ops atmel_pcm_ops = { 122static const struct snd_dmaengine_pcm_config atmel_dmaengine_pcm_config = {
186 .open = atmel_pcm_open, 123 .prepare_slave_config = atmel_pcm_configure_dma,
187 .close = snd_dmaengine_pcm_close_release_chan, 124 .pcm_hardware = &atmel_pcm_dma_hardware,
188 .ioctl = snd_pcm_lib_ioctl, 125 .prealloc_buffer_size = ATMEL_SSC_DMABUF_SIZE,
189 .hw_params = atmel_pcm_hw_params,
190 .trigger = snd_dmaengine_pcm_trigger,
191 .pointer = snd_dmaengine_pcm_pointer_no_residue,
192 .mmap = atmel_pcm_mmap,
193};
194
195static struct snd_soc_platform_driver atmel_soc_platform = {
196 .ops = &atmel_pcm_ops,
197 .pcm_new = atmel_pcm_new,
198 .pcm_free = atmel_pcm_free,
199}; 126};
200 127
201int atmel_pcm_dma_platform_register(struct device *dev) 128int atmel_pcm_dma_platform_register(struct device *dev)
202{ 129{
203 return snd_soc_register_platform(dev, &atmel_soc_platform); 130 return snd_dmaengine_pcm_register(dev, &atmel_dmaengine_pcm_config,
131 SND_DMAENGINE_PCM_FLAG_NO_RESIDUE);
204} 132}
205EXPORT_SYMBOL(atmel_pcm_dma_platform_register); 133EXPORT_SYMBOL(atmel_pcm_dma_platform_register);
206 134
207void atmel_pcm_dma_platform_unregister(struct device *dev) 135void atmel_pcm_dma_platform_unregister(struct device *dev)
208{ 136{
209 snd_soc_unregister_platform(dev); 137 snd_dmaengine_pcm_unregister(dev);
210} 138}
211EXPORT_SYMBOL(atmel_pcm_dma_platform_unregister); 139EXPORT_SYMBOL(atmel_pcm_dma_platform_unregister);
212 140