aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/sh/rcar
diff options
context:
space:
mode:
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>2014-01-23 21:41:44 -0500
committerMark Brown <broonie@linaro.org>2014-02-03 07:41:38 -0500
commit4686a0ad9aaee89495f181e5755d153e7fe7ffe6 (patch)
tree3178ccef2d15a26fa40ffffcfa26a2513434683e /sound/soc/sh/rcar
parent1b7b08efbe7419cc3e082f2b5ec8ae89f7af43d1 (diff)
ASoC: rsnd: remove SSI dependent DMAEngine callback
Renesas Gen2 sound will use 2 DMAC which are Audio-DMAC, and Audio-DMAC-peri-peri. Current driver has callback function for each DMAC, because it assumed each DMAC needs special settings. But it became clear that these can share settings. This patch removes unnecessary callback Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Signed-off-by: Mark Brown <broonie@linaro.org>
Diffstat (limited to 'sound/soc/sh/rcar')
-rw-r--r--sound/soc/sh/rcar/core.c38
-rw-r--r--sound/soc/sh/rcar/rsnd.h10
-rw-r--r--sound/soc/sh/rcar/ssi.c47
3 files changed, 40 insertions, 55 deletions
diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c
index 11eb0e35b9ce..b5af6f5145ea 100644
--- a/sound/soc/sh/rcar/core.c
+++ b/sound/soc/sh/rcar/core.c
@@ -143,6 +143,7 @@ static void rsnd_dma_continue(struct rsnd_dma *dma)
143void rsnd_dma_start(struct rsnd_dma *dma) 143void rsnd_dma_start(struct rsnd_dma *dma)
144{ 144{
145 /* push both A and B plane*/ 145 /* push both A and B plane*/
146 dma->offset = 0;
146 dma->submit_loop = 2; 147 dma->submit_loop = 2;
147 __rsnd_dma_start(dma); 148 __rsnd_dma_start(dma);
148} 149}
@@ -157,12 +158,26 @@ void rsnd_dma_stop(struct rsnd_dma *dma)
157static void rsnd_dma_complete(void *data) 158static void rsnd_dma_complete(void *data)
158{ 159{
159 struct rsnd_dma *dma = (struct rsnd_dma *)data; 160 struct rsnd_dma *dma = (struct rsnd_dma *)data;
161 struct rsnd_mod *mod = rsnd_dma_to_mod(dma);
160 struct rsnd_priv *priv = rsnd_mod_to_priv(rsnd_dma_to_mod(dma)); 162 struct rsnd_priv *priv = rsnd_mod_to_priv(rsnd_dma_to_mod(dma));
163 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
161 unsigned long flags; 164 unsigned long flags;
162 165
163 rsnd_lock(priv, flags); 166 rsnd_lock(priv, flags);
164 167
165 dma->complete(dma); 168 /*
169 * Renesas sound Gen1 needs 1 DMAC,
170 * Gen2 needs 2 DMAC.
171 * In Gen2 case, it are Audio-DMAC, and Audio-DMAC-peri-peri.
172 * But, Audio-DMAC-peri-peri doesn't have interrupt,
173 * and this driver is assuming that here.
174 *
175 * If Audio-DMAC-peri-peri has interrpt,
176 * rsnd_dai_pointer_update() will be called twice,
177 * ant it will breaks io->byte_pos
178 */
179
180 rsnd_dai_pointer_update(io, io->byte_per_period);
166 181
167 if (dma->submit_loop) 182 if (dma->submit_loop)
168 rsnd_dma_continue(dma); 183 rsnd_dma_continue(dma);
@@ -172,17 +187,21 @@ static void rsnd_dma_complete(void *data)
172 187
173static void __rsnd_dma_start(struct rsnd_dma *dma) 188static void __rsnd_dma_start(struct rsnd_dma *dma)
174{ 189{
175 struct rsnd_priv *priv = rsnd_mod_to_priv(rsnd_dma_to_mod(dma)); 190 struct rsnd_mod *mod = rsnd_dma_to_mod(dma);
191 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
192 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
193 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
176 struct device *dev = rsnd_priv_to_dev(priv); 194 struct device *dev = rsnd_priv_to_dev(priv);
177 struct dma_async_tx_descriptor *desc; 195 struct dma_async_tx_descriptor *desc;
178 dma_addr_t buf; 196 dma_addr_t buf;
179 size_t len; 197 size_t len = io->byte_per_period;
180 int i; 198 int i;
181 199
182 for (i = 0; i < dma->submit_loop; i++) { 200 for (i = 0; i < dma->submit_loop; i++) {
183 201
184 if (dma->inquiry(dma, &buf, &len) < 0) 202 buf = runtime->dma_addr +
185 return; 203 rsnd_dai_pointer_offset(io, dma->offset + len);
204 dma->offset = len;
186 205
187 desc = dmaengine_prep_slave_single( 206 desc = dmaengine_prep_slave_single(
188 dma->chan, buf, len, dma->dir, 207 dma->chan, buf, len, dma->dir,
@@ -217,10 +236,7 @@ int rsnd_dma_available(struct rsnd_dma *dma)
217} 236}
218 237
219int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma, 238int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma,
220 int is_play, int id, 239 int is_play, int id)
221 int (*inquiry)(struct rsnd_dma *dma,
222 dma_addr_t *buf, int *len),
223 int (*complete)(struct rsnd_dma *dma))
224{ 240{
225 struct device *dev = rsnd_priv_to_dev(priv); 241 struct device *dev = rsnd_priv_to_dev(priv);
226 struct dma_slave_config cfg; 242 struct dma_slave_config cfg;
@@ -253,8 +269,6 @@ int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma,
253 goto rsnd_dma_init_err; 269 goto rsnd_dma_init_err;
254 270
255 dma->dir = is_play ? DMA_TO_DEVICE : DMA_FROM_DEVICE; 271 dma->dir = is_play ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
256 dma->inquiry = inquiry;
257 dma->complete = complete;
258 INIT_WORK(&dma->work, rsnd_dma_do_work); 272 INIT_WORK(&dma->work, rsnd_dma_do_work);
259 273
260 return 0; 274 return 0;
@@ -307,6 +321,7 @@ int rsnd_dai_connect(struct rsnd_dai *rdai,
307 } 321 }
308 322
309 list_add_tail(&mod->list, &io->head); 323 list_add_tail(&mod->list, &io->head);
324 mod->io = io;
310 325
311 return 0; 326 return 0;
312} 327}
@@ -314,6 +329,7 @@ int rsnd_dai_connect(struct rsnd_dai *rdai,
314int rsnd_dai_disconnect(struct rsnd_mod *mod) 329int rsnd_dai_disconnect(struct rsnd_mod *mod)
315{ 330{
316 list_del_init(&mod->list); 331 list_del_init(&mod->list);
332 mod->io = NULL;
317 333
318 return 0; 334 return 0;
319} 335}
diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h
index c397dc8edee5..b2c717d2ba7e 100644
--- a/sound/soc/sh/rcar/rsnd.h
+++ b/sound/soc/sh/rcar/rsnd.h
@@ -100,19 +100,16 @@ struct rsnd_dma {
100 struct work_struct work; 100 struct work_struct work;
101 struct dma_chan *chan; 101 struct dma_chan *chan;
102 enum dma_data_direction dir; 102 enum dma_data_direction dir;
103 int (*inquiry)(struct rsnd_dma *dma, dma_addr_t *buf, int *len);
104 int (*complete)(struct rsnd_dma *dma);
105 103
106 int submit_loop; 104 int submit_loop;
105 int offset; /* it cares A/B plane */
107}; 106};
108 107
109void rsnd_dma_start(struct rsnd_dma *dma); 108void rsnd_dma_start(struct rsnd_dma *dma);
110void rsnd_dma_stop(struct rsnd_dma *dma); 109void rsnd_dma_stop(struct rsnd_dma *dma);
111int rsnd_dma_available(struct rsnd_dma *dma); 110int rsnd_dma_available(struct rsnd_dma *dma);
112int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma, 111int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma,
113 int is_play, int id, 112 int is_play, int id);
114 int (*inquiry)(struct rsnd_dma *dma, dma_addr_t *buf, int *len),
115 int (*complete)(struct rsnd_dma *dma));
116void rsnd_dma_quit(struct rsnd_priv *priv, 113void rsnd_dma_quit(struct rsnd_priv *priv,
117 struct rsnd_dma *dma); 114 struct rsnd_dma *dma);
118 115
@@ -137,17 +134,20 @@ struct rsnd_mod_ops {
137 struct rsnd_dai_stream *io); 134 struct rsnd_dai_stream *io);
138}; 135};
139 136
137struct rsnd_dai_stream;
140struct rsnd_mod { 138struct rsnd_mod {
141 int id; 139 int id;
142 struct rsnd_priv *priv; 140 struct rsnd_priv *priv;
143 struct rsnd_mod_ops *ops; 141 struct rsnd_mod_ops *ops;
144 struct list_head list; /* connect to rsnd_dai playback/capture */ 142 struct list_head list; /* connect to rsnd_dai playback/capture */
145 struct rsnd_dma dma; 143 struct rsnd_dma dma;
144 struct rsnd_dai_stream *io;
146}; 145};
147 146
148#define rsnd_mod_to_priv(mod) ((mod)->priv) 147#define rsnd_mod_to_priv(mod) ((mod)->priv)
149#define rsnd_mod_to_dma(mod) (&(mod)->dma) 148#define rsnd_mod_to_dma(mod) (&(mod)->dma)
150#define rsnd_dma_to_mod(_dma) container_of((_dma), struct rsnd_mod, dma) 149#define rsnd_dma_to_mod(_dma) container_of((_dma), struct rsnd_mod, dma)
150#define rsnd_mod_to_io(mod) ((mod)->io)
151#define rsnd_mod_id(mod) ((mod)->id) 151#define rsnd_mod_id(mod) ((mod)->id)
152#define for_each_rsnd_mod(pos, n, io) \ 152#define for_each_rsnd_mod(pos, n, io) \
153 list_for_each_entry_safe(pos, n, &(io)->head, list) 153 list_for_each_entry_safe(pos, n, &(io)->head, list)
diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c
index b7f464ebcdc0..d3371d798d54 100644
--- a/sound/soc/sh/rcar/ssi.c
+++ b/sound/soc/sh/rcar/ssi.c
@@ -64,12 +64,10 @@ struct rsnd_ssi {
64 struct rsnd_mod mod; 64 struct rsnd_mod mod;
65 65
66 struct rsnd_dai *rdai; 66 struct rsnd_dai *rdai;
67 struct rsnd_dai_stream *io;
68 u32 cr_own; 67 u32 cr_own;
69 u32 cr_clk; 68 u32 cr_clk;
70 u32 cr_etc; 69 u32 cr_etc;
71 int err; 70 int err;
72 int dma_offset;
73 unsigned int usrcnt; 71 unsigned int usrcnt;
74 unsigned int rate; 72 unsigned int rate;
75}; 73};
@@ -286,7 +284,6 @@ static int rsnd_ssi_init(struct rsnd_mod *mod,
286 * set ssi parameter 284 * set ssi parameter
287 */ 285 */
288 ssi->rdai = rdai; 286 ssi->rdai = rdai;
289 ssi->io = io;
290 ssi->cr_own = cr; 287 ssi->cr_own = cr;
291 ssi->err = -1; /* ignore 1st error */ 288 ssi->err = -1; /* ignore 1st error */
292 289
@@ -305,7 +302,6 @@ static int rsnd_ssi_quit(struct rsnd_mod *mod,
305 dev_warn(dev, "ssi under/over flow err = %d\n", ssi->err); 302 dev_warn(dev, "ssi under/over flow err = %d\n", ssi->err);
306 303
307 ssi->rdai = NULL; 304 ssi->rdai = NULL;
308 ssi->io = NULL;
309 ssi->cr_own = 0; 305 ssi->cr_own = 0;
310 ssi->err = 0; 306 ssi->err = 0;
311 307
@@ -329,8 +325,9 @@ static void rsnd_ssi_record_error(struct rsnd_ssi *ssi, u32 status)
329static irqreturn_t rsnd_ssi_pio_interrupt(int irq, void *data) 325static irqreturn_t rsnd_ssi_pio_interrupt(int irq, void *data)
330{ 326{
331 struct rsnd_ssi *ssi = data; 327 struct rsnd_ssi *ssi = data;
332 struct rsnd_dai_stream *io = ssi->io; 328 struct rsnd_mod *mod = &ssi->mod;
333 u32 status = rsnd_mod_read(&ssi->mod, SSISR); 329 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
330 u32 status = rsnd_mod_read(mod, SSISR);
334 irqreturn_t ret = IRQ_NONE; 331 irqreturn_t ret = IRQ_NONE;
335 332
336 if (io && (status & DIRQ)) { 333 if (io && (status & DIRQ)) {
@@ -347,9 +344,9 @@ static irqreturn_t rsnd_ssi_pio_interrupt(int irq, void *data)
347 * see rsnd_ssi_init() 344 * see rsnd_ssi_init()
348 */ 345 */
349 if (rsnd_dai_is_play(rdai, io)) 346 if (rsnd_dai_is_play(rdai, io))
350 rsnd_mod_write(&ssi->mod, SSITDR, *buf); 347 rsnd_mod_write(mod, SSITDR, *buf);
351 else 348 else
352 *buf = rsnd_mod_read(&ssi->mod, SSIRDR); 349 *buf = rsnd_mod_read(mod, SSIRDR);
353 350
354 rsnd_dai_pointer_update(io, sizeof(*buf)); 351 rsnd_dai_pointer_update(io, sizeof(*buf));
355 352
@@ -394,33 +391,6 @@ static struct rsnd_mod_ops rsnd_ssi_pio_ops = {
394 .stop = rsnd_ssi_pio_stop, 391 .stop = rsnd_ssi_pio_stop,
395}; 392};
396 393
397static int rsnd_ssi_dma_inquiry(struct rsnd_dma *dma, dma_addr_t *buf, int *len)
398{
399 struct rsnd_ssi *ssi = rsnd_dma_to_ssi(dma);
400 struct rsnd_dai_stream *io = ssi->io;
401 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
402
403 *len = io->byte_per_period;
404 *buf = runtime->dma_addr +
405 rsnd_dai_pointer_offset(io, ssi->dma_offset + *len);
406 ssi->dma_offset = *len; /* it cares A/B plane */
407
408 return 0;
409}
410
411static int rsnd_ssi_dma_complete(struct rsnd_dma *dma)
412{
413 struct rsnd_ssi *ssi = rsnd_dma_to_ssi(dma);
414 struct rsnd_dai_stream *io = ssi->io;
415 u32 status = rsnd_mod_read(&ssi->mod, SSISR);
416
417 rsnd_ssi_record_error(ssi, status);
418
419 rsnd_dai_pointer_update(ssi->io, io->byte_per_period);
420
421 return 0;
422}
423
424static int rsnd_ssi_dma_start(struct rsnd_mod *mod, 394static int rsnd_ssi_dma_start(struct rsnd_mod *mod,
425 struct rsnd_dai *rdai, 395 struct rsnd_dai *rdai,
426 struct rsnd_dai_stream *io) 396 struct rsnd_dai_stream *io)
@@ -430,7 +400,6 @@ static int rsnd_ssi_dma_start(struct rsnd_mod *mod,
430 400
431 /* enable DMA transfer */ 401 /* enable DMA transfer */
432 ssi->cr_etc = DMEN; 402 ssi->cr_etc = DMEN;
433 ssi->dma_offset = 0;
434 403
435 rsnd_dma_start(dma); 404 rsnd_dma_start(dma);
436 405
@@ -452,6 +421,8 @@ static int rsnd_ssi_dma_stop(struct rsnd_mod *mod,
452 421
453 ssi->cr_etc = 0; 422 ssi->cr_etc = 0;
454 423
424 rsnd_ssi_record_error(ssi, rsnd_mod_read(mod, SSISR));
425
455 rsnd_ssi_hw_stop(ssi, rdai); 426 rsnd_ssi_hw_stop(ssi, rdai);
456 427
457 rsnd_dma_stop(dma); 428 rsnd_dma_stop(dma);
@@ -585,9 +556,7 @@ int rsnd_ssi_probe(struct platform_device *pdev,
585 ret = rsnd_dma_init( 556 ret = rsnd_dma_init(
586 priv, rsnd_mod_to_dma(&ssi->mod), 557 priv, rsnd_mod_to_dma(&ssi->mod),
587 rsnd_ssi_is_play(&ssi->mod), 558 rsnd_ssi_is_play(&ssi->mod),
588 pinfo->dma_id, 559 pinfo->dma_id);
589 rsnd_ssi_dma_inquiry,
590 rsnd_ssi_dma_complete);
591 if (ret < 0) 560 if (ret < 0)
592 dev_info(dev, "SSI DMA failed. try PIO transter\n"); 561 dev_info(dev, "SSI DMA failed. try PIO transter\n");
593 else 562 else