diff options
author | Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> | 2016-01-20 20:58:33 -0500 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2016-01-22 12:12:25 -0500 |
commit | 355cb84fbe1f098f80c17dad9027ad2c6aec3fa0 (patch) | |
tree | 948f2c374aa16da922943ddb774cc232dfb7e615 | |
parent | 5ba17b42e1755c3c5cfe96370cfd47f34d01f62c (diff) |
ASoC: rsnd: attach Audio-DMAC-periperi correctly
SSI/SRC will try to attach DMAC as Audio-DMAC or Audio-DMAC-periperi.
It is fixed IP, but will be attached to each streams as different module
in case of MUX (= multi sound path will be merged).
This patch solves this issue.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r-- | sound/soc/sh/rcar/dma.c | 56 | ||||
-rw-r--r-- | sound/soc/sh/rcar/rsnd.h | 4 | ||||
-rw-r--r-- | sound/soc/sh/rcar/src.c | 4 | ||||
-rw-r--r-- | sound/soc/sh/rcar/ssi.c | 5 |
4 files changed, 34 insertions, 35 deletions
diff --git a/sound/soc/sh/rcar/dma.c b/sound/soc/sh/rcar/dma.c index d1cb3c177572..7658e8fd7bdc 100644 --- a/sound/soc/sh/rcar/dma.c +++ b/sound/soc/sh/rcar/dma.c | |||
@@ -622,15 +622,13 @@ static void rsnd_dma_of_path(struct rsnd_mod *this, | |||
622 | } | 622 | } |
623 | } | 623 | } |
624 | 624 | ||
625 | struct rsnd_mod *rsnd_dma_attach(struct rsnd_dai_stream *io, | 625 | int rsnd_dma_attach(struct rsnd_dai_stream *io, struct rsnd_mod *mod, |
626 | struct rsnd_mod *mod, int id) | 626 | struct rsnd_mod **dma_mod, int id) |
627 | { | 627 | { |
628 | struct rsnd_mod *dma_mod; | ||
629 | struct rsnd_mod *mod_from = NULL; | 628 | struct rsnd_mod *mod_from = NULL; |
630 | struct rsnd_mod *mod_to = NULL; | 629 | struct rsnd_mod *mod_to = NULL; |
631 | struct rsnd_priv *priv = rsnd_io_to_priv(io); | 630 | struct rsnd_priv *priv = rsnd_io_to_priv(io); |
632 | struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv); | 631 | struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv); |
633 | struct rsnd_dma *dma; | ||
634 | struct device *dev = rsnd_priv_to_dev(priv); | 632 | struct device *dev = rsnd_priv_to_dev(priv); |
635 | struct rsnd_mod_ops *ops; | 633 | struct rsnd_mod_ops *ops; |
636 | enum rsnd_mod_type type; | 634 | enum rsnd_mod_type type; |
@@ -646,17 +644,10 @@ struct rsnd_mod *rsnd_dma_attach(struct rsnd_dai_stream *io, | |||
646 | * rsnd_rdai_continuance_probe() | 644 | * rsnd_rdai_continuance_probe() |
647 | */ | 645 | */ |
648 | if (!dmac) | 646 | if (!dmac) |
649 | return ERR_PTR(-EAGAIN); | 647 | return -EAGAIN; |
650 | |||
651 | dma = devm_kzalloc(dev, sizeof(*dma), GFP_KERNEL); | ||
652 | if (!dma) | ||
653 | return ERR_PTR(-ENOMEM); | ||
654 | 648 | ||
655 | rsnd_dma_of_path(mod, io, is_play, &mod_from, &mod_to); | 649 | rsnd_dma_of_path(mod, io, is_play, &mod_from, &mod_to); |
656 | 650 | ||
657 | dma->src_addr = rsnd_dma_addr(io, mod_from, is_play, 1); | ||
658 | dma->dst_addr = rsnd_dma_addr(io, mod_to, is_play, 0); | ||
659 | |||
660 | /* for Gen2 */ | 651 | /* for Gen2 */ |
661 | if (mod_from && mod_to) { | 652 | if (mod_from && mod_to) { |
662 | ops = &rsnd_dmapp_ops; | 653 | ops = &rsnd_dmapp_ops; |
@@ -678,27 +669,38 @@ struct rsnd_mod *rsnd_dma_attach(struct rsnd_dai_stream *io, | |||
678 | type = RSND_MOD_AUDMA; | 669 | type = RSND_MOD_AUDMA; |
679 | } | 670 | } |
680 | 671 | ||
681 | dma_mod = rsnd_mod_get(dma); | 672 | if (!(*dma_mod)) { |
673 | struct rsnd_dma *dma; | ||
682 | 674 | ||
683 | ret = rsnd_mod_init(priv, dma_mod, | 675 | dma = devm_kzalloc(dev, sizeof(*dma), GFP_KERNEL); |
684 | ops, NULL, rsnd_mod_get_status, type, dma_id); | 676 | if (!dma) |
685 | if (ret < 0) | 677 | return -ENOMEM; |
686 | return ERR_PTR(ret); | ||
687 | 678 | ||
688 | dev_dbg(dev, "%s[%d] %s[%d] -> %s[%d]\n", | 679 | *dma_mod = rsnd_mod_get(dma); |
689 | rsnd_mod_name(dma_mod), rsnd_mod_id(dma_mod), | ||
690 | rsnd_mod_name(mod_from), rsnd_mod_id(mod_from), | ||
691 | rsnd_mod_name(mod_to), rsnd_mod_id(mod_to)); | ||
692 | 680 | ||
693 | ret = attach(io, dma, id, mod_from, mod_to); | 681 | dma->src_addr = rsnd_dma_addr(io, mod_from, is_play, 1); |
694 | if (ret < 0) | 682 | dma->dst_addr = rsnd_dma_addr(io, mod_to, is_play, 0); |
695 | return ERR_PTR(ret); | 683 | |
684 | ret = rsnd_mod_init(priv, *dma_mod, ops, NULL, | ||
685 | rsnd_mod_get_status, type, dma_id); | ||
686 | if (ret < 0) | ||
687 | return ret; | ||
696 | 688 | ||
697 | ret = rsnd_dai_connect(dma_mod, io, type); | 689 | dev_dbg(dev, "%s[%d] %s[%d] -> %s[%d]\n", |
690 | rsnd_mod_name(*dma_mod), rsnd_mod_id(*dma_mod), | ||
691 | rsnd_mod_name(mod_from), rsnd_mod_id(mod_from), | ||
692 | rsnd_mod_name(mod_to), rsnd_mod_id(mod_to)); | ||
693 | |||
694 | ret = attach(io, dma, id, mod_from, mod_to); | ||
695 | if (ret < 0) | ||
696 | return ret; | ||
697 | } | ||
698 | |||
699 | ret = rsnd_dai_connect(*dma_mod, io, type); | ||
698 | if (ret < 0) | 700 | if (ret < 0) |
699 | return ERR_PTR(ret); | 701 | return ret; |
700 | 702 | ||
701 | return rsnd_mod_get(dma); | 703 | return 0; |
702 | } | 704 | } |
703 | 705 | ||
704 | int rsnd_dma_probe(struct rsnd_priv *priv) | 706 | int rsnd_dma_probe(struct rsnd_priv *priv) |
diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h index 28602607cf5e..90c732e265a2 100644 --- a/sound/soc/sh/rcar/rsnd.h +++ b/sound/soc/sh/rcar/rsnd.h | |||
@@ -166,8 +166,8 @@ u32 rsnd_get_dalign(struct rsnd_mod *mod, struct rsnd_dai_stream *io); | |||
166 | /* | 166 | /* |
167 | * R-Car DMA | 167 | * R-Car DMA |
168 | */ | 168 | */ |
169 | struct rsnd_mod *rsnd_dma_attach(struct rsnd_dai_stream *io, | 169 | int rsnd_dma_attach(struct rsnd_dai_stream *io, |
170 | struct rsnd_mod *mod, int id); | 170 | struct rsnd_mod *mod, struct rsnd_mod **dma_mod, int id); |
171 | int rsnd_dma_probe(struct rsnd_priv *priv); | 171 | int rsnd_dma_probe(struct rsnd_priv *priv); |
172 | struct dma_chan *rsnd_dma_request_channel(struct device_node *of_node, | 172 | struct dma_chan *rsnd_dma_request_channel(struct device_node *of_node, |
173 | struct rsnd_mod *mod, char *name); | 173 | struct rsnd_mod *mod, char *name); |
diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c index 516b0c05451c..8dc9b483b5fa 100644 --- a/sound/soc/sh/rcar/src.c +++ b/sound/soc/sh/rcar/src.c | |||
@@ -495,9 +495,7 @@ static int rsnd_src_probe_(struct rsnd_mod *mod, | |||
495 | return ret; | 495 | return ret; |
496 | } | 496 | } |
497 | 497 | ||
498 | src->dma = rsnd_dma_attach(io, mod, 0); | 498 | ret = rsnd_dma_attach(io, mod, &src->dma, 0); |
499 | if (IS_ERR(src->dma)) | ||
500 | return PTR_ERR(src->dma); | ||
501 | 499 | ||
502 | return ret; | 500 | return ret; |
503 | } | 501 | } |
diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c index e68f3a1c9cb4..90674137aa90 100644 --- a/sound/soc/sh/rcar/ssi.c +++ b/sound/soc/sh/rcar/ssi.c | |||
@@ -704,9 +704,8 @@ static int rsnd_ssi_dma_probe(struct rsnd_mod *mod, | |||
704 | if (ret) | 704 | if (ret) |
705 | return ret; | 705 | return ret; |
706 | 706 | ||
707 | ssi->dma = rsnd_dma_attach(io, mod, dma_id); | 707 | /* SSI probe might be called many times in MUX multi path */ |
708 | if (IS_ERR(ssi->dma)) | 708 | ret = rsnd_dma_attach(io, mod, &ssi->dma, dma_id); |
709 | return PTR_ERR(ssi->dma); | ||
710 | 709 | ||
711 | return ret; | 710 | return ret; |
712 | } | 711 | } |