diff --git a/sound/soc/renesas/rcar/dma.c b/sound/soc/renesas/rcar/dma.c index d52cada711e5..0ce77eee338d 100644 --- a/sound/soc/renesas/rcar/dma.c +++ b/sound/soc/renesas/rcar/dma.c @@ -481,6 +481,69 @@ static struct rsnd_mod_ops rsnd_dmapp_ops = { DEBUG_INFO }; +struct rsnd_dma_addr { + dma_addr_t out_addr; + dma_addr_t in_addr; +}; + +struct rsnd_dma_addr_dir { + struct rsnd_dma_addr capture[3]; + struct rsnd_dma_addr playback[3]; +}; + +struct rsnd_dma_addr_map { + struct rsnd_dma_addr_dir src; + struct rsnd_dma_addr_dir ssi; + struct rsnd_dma_addr_dir ssiu; +}; + +static dma_addr_t +rsnd_dma_addr_lookup(struct rsnd_dai_stream *io, + struct rsnd_mod *mod, + struct rsnd_priv *priv, + const struct rsnd_dma_addr_map *map, + int is_play, int is_from) +{ + struct device *dev = rsnd_priv_to_dev(priv); + int is_ssi = !!(rsnd_io_to_mod_ssi(io) == mod) || + !!(rsnd_io_to_mod_ssiu(io) == mod); + int use_src = !!rsnd_io_to_mod_src(io); + int use_cmd = !!rsnd_io_to_mod_dvc(io) || + !!rsnd_io_to_mod_mix(io) || + !!rsnd_io_to_mod_ctu(io); + int id = rsnd_mod_id(mod); + const struct rsnd_dma_addr_dir *dir; + const struct rsnd_dma_addr *addr; + + /* it shouldn't happen */ + if (use_cmd && !use_src) + dev_err(dev, "DVC is selected without SRC\n"); + + /* use SSIU or SSI? */ + if (is_ssi && rsnd_ssi_use_busif(io)) + is_ssi++; + + dev_dbg(dev, "dma%d addr : is_ssi=%d use_src=%d use_cmd=%d\n", + id, is_ssi, use_src, use_cmd); + + switch (is_ssi) { + case 2: + dir = &map->ssiu; + break; + case 1: + dir = &map->ssi; + break; + default: + dir = &map->src; + break; + } + + addr = is_play ? &dir->playback[use_src + use_cmd] + : &dir->capture[use_src + use_cmd]; + + return is_from ? addr->out_addr : addr->in_addr; +} + /* * Common DMAC Interface */ @@ -527,47 +590,45 @@ rsnd_gen2_dma_addr(struct rsnd_dai_stream *io, struct device *dev = rsnd_priv_to_dev(priv); phys_addr_t ssi_reg = rsnd_gen_get_phy_addr(priv, RSND_BASE_SSI); phys_addr_t src_reg = rsnd_gen_get_phy_addr(priv, RSND_BASE_SCU); - int is_ssi = !!(rsnd_io_to_mod_ssi(io) == mod) || - !!(rsnd_io_to_mod_ssiu(io) == mod); - int use_src = !!rsnd_io_to_mod_src(io); - int use_cmd = !!rsnd_io_to_mod_dvc(io) || - !!rsnd_io_to_mod_mix(io) || - !!rsnd_io_to_mod_ctu(io); int id = rsnd_mod_id(mod); int busif = rsnd_mod_id_sub(rsnd_io_to_mod_ssiu(io)); - struct dma_addr { - dma_addr_t out_addr; - dma_addr_t in_addr; - } dma_addrs[3][2][3] = { - /* SRC */ - /* Capture */ - {{{ 0, 0 }, - { RDMA_SRC_O_N(src, id), RDMA_SRC_I_P(src, id) }, - { RDMA_CMD_O_N(src, id), RDMA_SRC_I_P(src, id) } }, - /* Playback */ - {{ 0, 0, }, - { RDMA_SRC_O_P(src, id), RDMA_SRC_I_N(src, id) }, - { RDMA_CMD_O_P(src, id), RDMA_SRC_I_N(src, id) } } + const struct rsnd_dma_addr_map map = { + .src = { + .capture = { + { 0, 0 }, + { RDMA_SRC_O_N(src, id), RDMA_SRC_I_P(src, id) }, + { RDMA_CMD_O_N(src, id), RDMA_SRC_I_P(src, id) }, + }, + .playback = { + { 0, 0 }, + { RDMA_SRC_O_P(src, id), RDMA_SRC_I_N(src, id) }, + { RDMA_CMD_O_P(src, id), RDMA_SRC_I_N(src, id) }, + }, }, - /* SSI */ - /* Capture */ - {{{ RDMA_SSI_O_N(ssi, id), 0 }, - { RDMA_SSIU_O_P(ssi, id, busif), 0 }, - { RDMA_SSIU_O_P(ssi, id, busif), 0 } }, - /* Playback */ - {{ 0, RDMA_SSI_I_N(ssi, id) }, - { 0, RDMA_SSIU_I_P(ssi, id, busif) }, - { 0, RDMA_SSIU_I_P(ssi, id, busif) } } + .ssi = { + .capture = { + { RDMA_SSI_O_N(ssi, id), 0 }, + { RDMA_SSIU_O_P(ssi, id, busif), 0 }, + { RDMA_SSIU_O_P(ssi, id, busif), 0 }, + }, + .playback = { + { 0, RDMA_SSI_I_N(ssi, id) }, + { 0, RDMA_SSIU_I_P(ssi, id, busif) }, + { 0, RDMA_SSIU_I_P(ssi, id, busif) }, + }, + }, + .ssiu = { + .capture = { + { RDMA_SSIU_O_N(ssi, id, busif), 0 }, + { RDMA_SSIU_O_P(ssi, id, busif), 0 }, + { RDMA_SSIU_O_P(ssi, id, busif), 0 }, + }, + .playback = { + { 0, RDMA_SSIU_I_N(ssi, id, busif) }, + { 0, RDMA_SSIU_I_P(ssi, id, busif) }, + { 0, RDMA_SSIU_I_P(ssi, id, busif) }, + }, }, - /* SSIU */ - /* Capture */ - {{{ RDMA_SSIU_O_N(ssi, id, busif), 0 }, - { RDMA_SSIU_O_P(ssi, id, busif), 0 }, - { RDMA_SSIU_O_P(ssi, id, busif), 0 } }, - /* Playback */ - {{ 0, RDMA_SSIU_I_N(ssi, id, busif) }, - { 0, RDMA_SSIU_I_P(ssi, id, busif) }, - { 0, RDMA_SSIU_I_P(ssi, id, busif) } } }, }; /* @@ -580,17 +641,7 @@ rsnd_gen2_dma_addr(struct rsnd_dai_stream *io, dev_err(dev, "This driver doesn't support SSI%d-%d, so far", id, busif); - /* it shouldn't happen */ - if (use_cmd && !use_src) - dev_err(dev, "DVC is selected without SRC\n"); - - /* use SSIU or SSI ? */ - if (is_ssi && rsnd_ssi_use_busif(io)) - is_ssi++; - - return (is_from) ? - dma_addrs[is_ssi][is_play][use_src + use_cmd].out_addr : - dma_addrs[is_ssi][is_play][use_src + use_cmd].in_addr; + return rsnd_dma_addr_lookup(io, mod, priv, &map, is_play, is_from); } /*