ASoC: rsnd: care DMA slave channel name for DT
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Fri, 23 May 2014 06:25:49 +0000 (23:25 -0700)
committerMark Brown <broonie@linaro.org>
Mon, 26 May 2014 13:34:55 +0000 (14:34 +0100)
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>
Documentation/devicetree/bindings/sound/renesas,rsnd.txt
sound/soc/sh/rcar/core.c
sound/soc/sh/rcar/ssi.c

index a44e9179faf569c7d8f40ab317381d2728398f99..8346cab046cd82d1f57447dffaa0d2354d9746b1 100644 (file)
@@ -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
index 073a29354c8555cce7c2f466ea9877f2059264e6..cddb76d7d96521e34c3fb4a8f2535408889294ae 100644 (file)
@@ -256,11 +256,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;
 
@@ -272,9 +342,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;
index 2d94a62a65777a7ab1c8459b7e516bd62ce92b76..e0a4ba7271e77fe4e0e0b4c7b9de5987978f18a6 100644 (file)
@@ -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: