aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>2014-06-22 20:56:41 -0400
committerMark Brown <broonie@linaro.org>2014-06-28 09:41:19 -0400
commitccd01559ead29b59918458e9b412ff18b88fc6cf (patch)
treedc8e198921c52f35a52c9a58559681768edaefc6
parentd9288d0ba12de1b5efb830b9128e4cc6877318fc (diff)
ASoC: rsnd: use dmaengine_prep_dma_cyclic() instead of original method
Current R-Car sound driver is using DMAEngine directly, but, ASoC is requesting to use common DMA transfer method, like snd_dmaengine_pcm_trigger() or dmaengine_pcm_ops. It is difficult to switch at this point, since Renesas driver is also supporting PIO transfer. This patch uses dmaengine_prep_dma_cyclic() instead of dmaengine_prep_slave_single(). It is used in requested method, and is good first step to switch over. Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Signed-off-by: Mark Brown <broonie@linaro.org>
-rw-r--r--sound/soc/sh/rcar/core.c76
-rw-r--r--sound/soc/sh/rcar/rsnd.h4
2 files changed, 18 insertions, 62 deletions
diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c
index 8c3707a68603..5149fe2dae9f 100644
--- a/sound/soc/sh/rcar/core.c
+++ b/sound/soc/sh/rcar/core.c
@@ -164,26 +164,8 @@ void rsnd_mod_init(struct rsnd_priv *priv,
164/* 164/*
165 * rsnd_dma functions 165 * rsnd_dma functions
166 */ 166 */
167static void __rsnd_dma_start(struct rsnd_dma *dma);
168static void rsnd_dma_continue(struct rsnd_dma *dma)
169{
170 /* push next A or B plane */
171 dma->submit_loop = 1;
172 schedule_work(&dma->work);
173}
174
175void rsnd_dma_start(struct rsnd_dma *dma)
176{
177 /* push both A and B plane*/
178 dma->offset = 0;
179 dma->submit_loop = 2;
180 __rsnd_dma_start(dma);
181}
182
183void rsnd_dma_stop(struct rsnd_dma *dma) 167void rsnd_dma_stop(struct rsnd_dma *dma)
184{ 168{
185 dma->submit_loop = 0;
186 cancel_work_sync(&dma->work);
187 dmaengine_terminate_all(dma->chan); 169 dmaengine_terminate_all(dma->chan);
188} 170}
189 171
@@ -191,11 +173,7 @@ static void rsnd_dma_complete(void *data)
191{ 173{
192 struct rsnd_dma *dma = (struct rsnd_dma *)data; 174 struct rsnd_dma *dma = (struct rsnd_dma *)data;
193 struct rsnd_mod *mod = rsnd_dma_to_mod(dma); 175 struct rsnd_mod *mod = rsnd_dma_to_mod(dma);
194 struct rsnd_priv *priv = rsnd_mod_to_priv(rsnd_dma_to_mod(dma));
195 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); 176 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
196 unsigned long flags;
197
198 rsnd_lock(priv, flags);
199 177
200 /* 178 /*
201 * Renesas sound Gen1 needs 1 DMAC, 179 * Renesas sound Gen1 needs 1 DMAC,
@@ -208,57 +186,40 @@ static void rsnd_dma_complete(void *data)
208 * rsnd_dai_pointer_update() will be called twice, 186 * rsnd_dai_pointer_update() will be called twice,
209 * ant it will breaks io->byte_pos 187 * ant it will breaks io->byte_pos
210 */ 188 */
211 if (dma->submit_loop)
212 rsnd_dma_continue(dma);
213
214 rsnd_unlock(priv, flags);
215 189
216 rsnd_dai_pointer_update(io, io->byte_per_period); 190 rsnd_dai_pointer_update(io, io->byte_per_period);
217} 191}
218 192
219static void __rsnd_dma_start(struct rsnd_dma *dma) 193void rsnd_dma_start(struct rsnd_dma *dma)
220{ 194{
221 struct rsnd_mod *mod = rsnd_dma_to_mod(dma); 195 struct rsnd_mod *mod = rsnd_dma_to_mod(dma);
222 struct rsnd_priv *priv = rsnd_mod_to_priv(mod); 196 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
223 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); 197 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
224 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); 198 struct snd_pcm_substream *substream = io->substream;
225 struct device *dev = rsnd_priv_to_dev(priv); 199 struct device *dev = rsnd_priv_to_dev(priv);
226 struct dma_async_tx_descriptor *desc; 200 struct dma_async_tx_descriptor *desc;
227 dma_addr_t buf;
228 size_t len = io->byte_per_period;
229 int i;
230
231 for (i = 0; i < dma->submit_loop; i++) {
232 201
233 buf = runtime->dma_addr + 202 desc = dmaengine_prep_dma_cyclic(dma->chan,
234 rsnd_dai_pointer_offset(io, dma->offset + len); 203 substream->runtime->dma_addr,
235 dma->offset = len; 204 snd_pcm_lib_buffer_bytes(substream),
205 snd_pcm_lib_period_bytes(substream),
206 dma->dir,
207 DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
236 208
237 desc = dmaengine_prep_slave_single( 209 if (!desc) {
238 dma->chan, buf, len, dma->dir, 210 dev_err(dev, "dmaengine_prep_slave_sg() fail\n");
239 DMA_PREP_INTERRUPT | DMA_CTRL_ACK); 211 return;
240 if (!desc) { 212 }
241 dev_err(dev, "dmaengine_prep_slave_sg() fail\n");
242 return;
243 }
244
245 desc->callback = rsnd_dma_complete;
246 desc->callback_param = dma;
247 213
248 if (dmaengine_submit(desc) < 0) { 214 desc->callback = rsnd_dma_complete;
249 dev_err(dev, "dmaengine_submit() fail\n"); 215 desc->callback_param = dma;
250 return;
251 }
252 216
253 dma_async_issue_pending(dma->chan); 217 if (dmaengine_submit(desc) < 0) {
218 dev_err(dev, "dmaengine_submit() fail\n");
219 return;
254 } 220 }
255}
256
257static void rsnd_dma_do_work(struct work_struct *work)
258{
259 struct rsnd_dma *dma = container_of(work, struct rsnd_dma, work);
260 221
261 __rsnd_dma_start(dma); 222 dma_async_issue_pending(dma->chan);
262} 223}
263 224
264int rsnd_dma_available(struct rsnd_dma *dma) 225int rsnd_dma_available(struct rsnd_dma *dma)
@@ -372,7 +333,6 @@ int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma,
372 goto rsnd_dma_init_err; 333 goto rsnd_dma_init_err;
373 334
374 dma->dir = is_play ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM; 335 dma->dir = is_play ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM;
375 INIT_WORK(&dma->work, rsnd_dma_do_work);
376 336
377 return 0; 337 return 0;
378 338
diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h
index a1466c1570bc..60b5e9260600 100644
--- a/sound/soc/sh/rcar/rsnd.h
+++ b/sound/soc/sh/rcar/rsnd.h
@@ -156,12 +156,8 @@ u32 rsnd_get_adinr(struct rsnd_mod *mod);
156 */ 156 */
157struct rsnd_dma { 157struct rsnd_dma {
158 struct sh_dmae_slave slave; 158 struct sh_dmae_slave slave;
159 struct work_struct work;
160 struct dma_chan *chan; 159 struct dma_chan *chan;
161 enum dma_transfer_direction dir; 160 enum dma_transfer_direction dir;
162
163 int submit_loop;
164 int offset; /* it cares A/B plane */
165}; 161};
166 162
167void rsnd_dma_start(struct rsnd_dma *dma); 163void rsnd_dma_start(struct rsnd_dma *dma);