diff options
author | Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> | 2015-07-15 03:16:56 -0400 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2015-07-17 14:26:06 -0400 |
commit | 7dfb49194557ccf27ab99c8c04c021320e7ae458 (patch) | |
tree | 917fdb057107b94f27cdf8519d05e803caf9078e | |
parent | 78edead4494219640d9fdf37d76beae24f79de9e (diff) |
ASoC: rsnd: update Audio DMA path search method
Current rsnd driver is assuming Audio DMAC / Audio DMAC peri peri
are used from SSI/SSIU/SRC/DVC. But we will add CTU/MIX to this driver.
Then, current DMA path searching method is not understandable, and good
enough for this purpose. This patch update DMA path search method, more
simply.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Tested-by: Keita Kobayashi <keita.kobayashi.ym@renesas.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r-- | sound/soc/sh/rcar/dma.c | 88 |
1 files changed, 53 insertions, 35 deletions
diff --git a/sound/soc/sh/rcar/dma.c b/sound/soc/sh/rcar/dma.c index a175863d239c..23282f48f71f 100644 --- a/sound/soc/sh/rcar/dma.c +++ b/sound/soc/sh/rcar/dma.c | |||
@@ -494,7 +494,7 @@ static dma_addr_t rsnd_dma_addr(struct rsnd_dai_stream *io, | |||
494 | return rsnd_gen2_dma_addr(io, mod, is_play, is_from); | 494 | return rsnd_gen2_dma_addr(io, mod, is_play, is_from); |
495 | } | 495 | } |
496 | 496 | ||
497 | #define MOD_MAX 4 /* MEM/SSI/SRC/DVC */ | 497 | #define MOD_MAX (RSND_MOD_MAX + 1) /* +Memory */ |
498 | static void rsnd_dma_of_path(struct rsnd_dma *dma, | 498 | static void rsnd_dma_of_path(struct rsnd_dma *dma, |
499 | struct rsnd_dai_stream *io, | 499 | struct rsnd_dai_stream *io, |
500 | int is_play, | 500 | int is_play, |
@@ -506,53 +506,71 @@ static void rsnd_dma_of_path(struct rsnd_dma *dma, | |||
506 | struct rsnd_mod *src = rsnd_io_to_mod_src(io); | 506 | struct rsnd_mod *src = rsnd_io_to_mod_src(io); |
507 | struct rsnd_mod *dvc = rsnd_io_to_mod_dvc(io); | 507 | struct rsnd_mod *dvc = rsnd_io_to_mod_dvc(io); |
508 | struct rsnd_mod *mod[MOD_MAX]; | 508 | struct rsnd_mod *mod[MOD_MAX]; |
509 | int i, index; | 509 | struct rsnd_mod *mod_start, *mod_end; |
510 | struct rsnd_priv *priv = rsnd_mod_to_priv(this); | ||
511 | struct device *dev = rsnd_priv_to_dev(priv); | ||
512 | int nr, i; | ||
510 | 513 | ||
514 | if (!ssi) | ||
515 | return; | ||
511 | 516 | ||
512 | for (i = 0; i < MOD_MAX; i++) | 517 | nr = 0; |
518 | for (i = 0; i < MOD_MAX; i++) { | ||
513 | mod[i] = NULL; | 519 | mod[i] = NULL; |
520 | nr += !!rsnd_io_to_mod(io, i); | ||
521 | } | ||
514 | 522 | ||
515 | /* | 523 | /* |
516 | * in play case... | 524 | * [S] -*-> [E] |
525 | * [S] -*-> SRC -o-> [E] | ||
526 | * [S] -*-> SRC -> DVC -o-> [E] | ||
527 | * [S] -*-> SRC -> CTU -> MIX -> DVC -o-> [E] | ||
528 | * | ||
529 | * playback [S] = mem | ||
530 | * [E] = SSI | ||
517 | * | 531 | * |
518 | * src -> dst | 532 | * capture [S] = SSI |
533 | * [E] = mem | ||
519 | * | 534 | * |
520 | * mem -> SSI | 535 | * -*-> Audio DMAC |
521 | * mem -> SRC -> SSI | 536 | * -o-> Audio DMAC peri peri |
522 | * mem -> SRC -> DVC -> SSI | ||
523 | */ | 537 | */ |
524 | mod[0] = NULL; /* for "mem" */ | 538 | mod_start = (is_play) ? NULL : ssi; |
525 | index = 1; | 539 | mod_end = (is_play) ? ssi : NULL; |
526 | for (i = 1; i < MOD_MAX; i++) { | ||
527 | if (!src) { | ||
528 | mod[i] = ssi; | ||
529 | } else if (!dvc) { | ||
530 | mod[i] = src; | ||
531 | src = NULL; | ||
532 | } else { | ||
533 | if ((!is_play) && (this == src)) | ||
534 | this = dvc; | ||
535 | 540 | ||
536 | mod[i] = (is_play) ? src : dvc; | 541 | mod[0] = mod_start; |
537 | i++; | 542 | for (i = 1; i < nr; i++) { |
538 | mod[i] = (is_play) ? dvc : src; | 543 | if (src) { |
544 | mod[i] = src; | ||
539 | src = NULL; | 545 | src = NULL; |
546 | } else if (dvc) { | ||
547 | mod[i] = dvc; | ||
540 | dvc = NULL; | 548 | dvc = NULL; |
541 | } | 549 | } |
542 | |||
543 | if (mod[i] == this) | ||
544 | index = i; | ||
545 | |||
546 | if (mod[i] == ssi) | ||
547 | break; | ||
548 | } | 550 | } |
551 | mod[i] = mod_end; | ||
549 | 552 | ||
550 | if (is_play) { | 553 | /* |
551 | *mod_from = mod[index - 1]; | 554 | * | SSI | SRC | |
552 | *mod_to = mod[index]; | 555 | * -------------+-----+-----+ |
556 | * is_play | o | * | | ||
557 | * !is_play | * | o | | ||
558 | */ | ||
559 | if ((this == ssi) == (is_play)) { | ||
560 | *mod_from = mod[nr - 1]; | ||
561 | *mod_to = mod[nr]; | ||
553 | } else { | 562 | } else { |
554 | *mod_from = mod[index]; | 563 | *mod_from = mod[0]; |
555 | *mod_to = mod[index - 1]; | 564 | *mod_to = mod[1]; |
565 | } | ||
566 | |||
567 | dev_dbg(dev, "module connection (this is %s[%d])\n", | ||
568 | rsnd_mod_name(this), rsnd_mod_id(this)); | ||
569 | for (i = 0; i <= nr; i++) { | ||
570 | dev_dbg(dev, " %s[%d]%s\n", | ||
571 | rsnd_mod_name(mod[i]), rsnd_mod_id(mod[i]), | ||
572 | (mod[i] == *mod_from) ? " from" : | ||
573 | (mod[i] == *mod_to) ? " to" : ""); | ||
556 | } | 574 | } |
557 | } | 575 | } |
558 | 576 | ||
@@ -580,8 +598,8 @@ void rsnd_dma_quit(struct rsnd_dai_stream *io, struct rsnd_dma *dma) | |||
580 | 598 | ||
581 | int rsnd_dma_init(struct rsnd_dai_stream *io, struct rsnd_dma *dma, int id) | 599 | int rsnd_dma_init(struct rsnd_dai_stream *io, struct rsnd_dma *dma, int id) |
582 | { | 600 | { |
583 | struct rsnd_mod *mod_from; | 601 | struct rsnd_mod *mod_from = NULL; |
584 | struct rsnd_mod *mod_to; | 602 | struct rsnd_mod *mod_to = NULL; |
585 | struct rsnd_priv *priv = rsnd_io_to_priv(io); | 603 | struct rsnd_priv *priv = rsnd_io_to_priv(io); |
586 | struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv); | 604 | struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv); |
587 | struct device *dev = rsnd_priv_to_dev(priv); | 605 | struct device *dev = rsnd_priv_to_dev(priv); |