| From eef4df7bd7dcef66994207b7dd1f1a0f2b14a412 Mon Sep 17 00:00:00 2001 |
| From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> |
| Date: Thu, 22 May 2014 23:25:49 -0700 |
| Subject: ASoC: rsnd: care DMA slave channel name for DT |
| |
| Renesas sound driver is supporting to use DMAEngine. |
| But, DMA slave channel name "tx", "rx" is not enough |
| in DT case. |
| Becuase, it has many ports and path combination. |
| |
| This patch adds rsnd_dma_of_name() to find |
| DMA channel name, for example |
| memory to SSI0 is "mem_ssi0", |
| SSI0 to memory is "ssi0_mem", |
| SSI0 to SRC0 is "ssi0_src0", |
| SRC0 to SSI0 is "src0_ssi0", |
| SRC0 to DVC0 is "src0_dvc0"... |
| |
| Renesas sound want to use PIO transfer mode for some reasons. |
| It will be PIO tranfer mode if device node doesn't have |
| DMA settings. |
| |
| Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> |
| Signed-off-by: Mark Brown <broonie@linaro.org> |
| (cherry picked from commit 199e7688bdf7d188d70c3432c96ec13d8a14b341) |
| Signed-off-by: Simon Horman <horms+renesas@verge.net.au> |
| --- |
| .../devicetree/bindings/sound/renesas,rsnd.txt | 1 + |
| sound/soc/sh/rcar/core.c | 80 +++++++++++++++++++++- |
| sound/soc/sh/rcar/ssi.c | 6 ++ |
| 3 files changed, 86 insertions(+), 1 deletion(-) |
| |
| diff --git a/Documentation/devicetree/bindings/sound/renesas,rsnd.txt b/Documentation/devicetree/bindings/sound/renesas,rsnd.txt |
| index a44e9179faf5..8346cab046cd 100644 |
| --- a/Documentation/devicetree/bindings/sound/renesas,rsnd.txt |
| +++ b/Documentation/devicetree/bindings/sound/renesas,rsnd.txt |
| @@ -20,6 +20,7 @@ Required properties: |
| SSI subnode properties: |
| - interrupts : Should contain SSI interrupt for PIO transfer |
| - shared-pin : if shared clock pin |
| +- pio-transfer : use PIO transfer mode |
| |
| SRC subnode properties: |
| no properties at this point |
| diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c |
| index 7bb9a2e69ad4..19f44640e1a8 100644 |
| --- a/sound/soc/sh/rcar/core.c |
| +++ b/sound/soc/sh/rcar/core.c |
| @@ -255,11 +255,81 @@ int rsnd_dma_available(struct rsnd_dma *dma) |
| return !!dma->chan; |
| } |
| |
| +#define DMA_NAME_SIZE 16 |
| +#define MOD_MAX 4 /* MEM/SSI/SRC/DVC */ |
| +static int _rsnd_dma_of_name(char *dma_name, struct rsnd_mod *mod) |
| +{ |
| + if (mod) |
| + return snprintf(dma_name, DMA_NAME_SIZE / 2, "%s%d", |
| + rsnd_mod_name(mod), rsnd_mod_id(mod)); |
| + else |
| + return snprintf(dma_name, DMA_NAME_SIZE / 2, "mem"); |
| + |
| +} |
| + |
| +static void rsnd_dma_of_name(struct rsnd_dma *dma, |
| + int is_play, char *dma_name) |
| +{ |
| + struct rsnd_mod *this = rsnd_dma_to_mod(dma); |
| + struct rsnd_dai_stream *io = rsnd_mod_to_io(this); |
| + struct rsnd_mod *ssi = rsnd_io_to_mod_ssi(io); |
| + struct rsnd_mod *src = rsnd_io_to_mod_src(io); |
| + struct rsnd_mod *dvc = rsnd_io_to_mod_dvc(io); |
| + struct rsnd_mod *mod[MOD_MAX]; |
| + struct rsnd_mod *src_mod, *dst_mod; |
| + int i, index; |
| + |
| + |
| + for (i = 0; i < MOD_MAX; i++) |
| + mod[i] = NULL; |
| + |
| + /* |
| + * in play case... |
| + * |
| + * src -> dst |
| + * |
| + * mem -> SSI |
| + * mem -> SRC -> SSI |
| + * mem -> SRC -> DVC -> SSI |
| + */ |
| + mod[0] = NULL; /* for "mem" */ |
| + index = 1; |
| + for (i = 1; i < MOD_MAX; i++) { |
| + if (!src) { |
| + mod[i] = ssi; |
| + break; |
| + } else if (!dvc) { |
| + mod[i] = src; |
| + src = NULL; |
| + } else { |
| + mod[i] = dvc; |
| + dvc = NULL; |
| + } |
| + |
| + if (mod[i] == this) |
| + index = i; |
| + } |
| + |
| + if (is_play) { |
| + src_mod = mod[index - 1]; |
| + dst_mod = mod[index]; |
| + } else { |
| + src_mod = mod[index]; |
| + dst_mod = mod[index + 1]; |
| + } |
| + |
| + index = 0; |
| + index = _rsnd_dma_of_name(dma_name + index, src_mod); |
| + *(dma_name + index++) = '_'; |
| + index = _rsnd_dma_of_name(dma_name + index, dst_mod); |
| +} |
| + |
| int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma, |
| int is_play, int id) |
| { |
| struct device *dev = rsnd_priv_to_dev(priv); |
| struct dma_slave_config cfg; |
| + char dma_name[DMA_NAME_SIZE]; |
| dma_cap_mask_t mask; |
| int ret; |
| |
| @@ -271,9 +341,17 @@ int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma, |
| dma_cap_zero(mask); |
| dma_cap_set(DMA_SLAVE, mask); |
| |
| + if (dev->of_node) |
| + rsnd_dma_of_name(dma, is_play, dma_name); |
| + else |
| + snprintf(dma_name, DMA_NAME_SIZE, |
| + is_play ? "tx" : "rx"); |
| + |
| + dev_dbg(dev, "dma name : %s\n", dma_name); |
| + |
| dma->chan = dma_request_slave_channel_compat(mask, shdma_chan_filter, |
| (void *)id, dev, |
| - is_play ? "tx" : "rx"); |
| + dma_name); |
| if (!dma->chan) { |
| dev_err(dev, "can't get dma channel\n"); |
| return -EIO; |
| diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c |
| index b821ec6683d2..2df723df5d19 100644 |
| --- a/sound/soc/sh/rcar/ssi.c |
| +++ b/sound/soc/sh/rcar/ssi.c |
| @@ -589,6 +589,12 @@ static void rsnd_of_parse_ssi(struct platform_device *pdev, |
| * irq |
| */ |
| ssi_info->pio_irq = irq_of_parse_and_map(np, 0); |
| + |
| + /* |
| + * DMA |
| + */ |
| + ssi_info->dma_id = of_get_property(np, "pio-transfer", NULL) ? |
| + 0 : 1; |
| } |
| |
| rsnd_of_parse_ssi_end: |
| -- |
| 2.1.2 |
| |