]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - sound/soc/sh/rcar/gen.c
Merge remote-tracking branches 'asoc/topic/omap' and 'asoc/topic/rcar' into asoc...
[karo-tx-linux.git] / sound / soc / sh / rcar / gen.c
index 50a1ef3eb1c6e243e7c749824c23acbd447fb9e5..1dd2b7d38c2cd6e7045f4a5cff9c05076bd9fef2 100644 (file)
@@ -155,6 +155,101 @@ static int rsnd_gen_regmap_init(struct rsnd_priv *priv,
        return 0;
 }
 
+/*
+ *     DMA read/write register offset
+ *
+ *     RSND_xxx_I_N    for Audio DMAC input
+ *     RSND_xxx_O_N    for Audio DMAC output
+ *     RSND_xxx_I_P    for Audio DMAC peri peri input
+ *     RSND_xxx_O_P    for Audio DMAC peri peri output
+ *
+ *     ex) R-Car H2 case
+ *           mod        / DMAC in    / DMAC out   / DMAC PP in / DMAC pp out
+ *     SSI : 0xec541000 / 0xec241008 / 0xec24100c / 0xec400000 / 0xec400000
+ *     SCU : 0xec500000 / 0xec000000 / 0xec004000 / 0xec300000 / 0xec304000
+ *     CMD : 0xec500000 / 0xec008000                             0xec308000
+ */
+#define RDMA_SSI_I_N(addr, i)  (addr ##_reg - 0x00300000 + (0x40 * i) + 0x8)
+#define RDMA_SSI_O_N(addr, i)  (addr ##_reg - 0x00300000 + (0x40 * i) + 0xc)
+
+#define RDMA_SSI_I_P(addr, i)  (addr ##_reg - 0x00141000 + (0x1000 * i))
+#define RDMA_SSI_O_P(addr, i)  (addr ##_reg - 0x00141000 + (0x1000 * i))
+
+#define RDMA_SRC_I_N(addr, i)  (addr ##_reg - 0x00500000 + (0x400 * i))
+#define RDMA_SRC_O_N(addr, i)  (addr ##_reg - 0x004fc000 + (0x400 * i))
+
+#define RDMA_SRC_I_P(addr, i)  (addr ##_reg - 0x00200000 + (0x400 * i))
+#define RDMA_SRC_O_P(addr, i)  (addr ##_reg - 0x001fc000 + (0x400 * i))
+
+#define RDMA_CMD_O_N(addr, i)  (addr ##_reg - 0x004f8000 + (0x400 * i))
+#define RDMA_CMD_O_P(addr, i)  (addr ##_reg - 0x001f8000 + (0x400 * i))
+
+void rsnd_gen_dma_addr(struct rsnd_priv *priv,
+                      struct rsnd_dma *dma,
+                      struct dma_slave_config *cfg,
+                      int is_play, int slave_id)
+{
+       struct platform_device *pdev = rsnd_priv_to_pdev(priv);
+       struct device *dev = rsnd_priv_to_dev(priv);
+       struct rsnd_mod *mod = rsnd_dma_to_mod(dma);
+       struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
+       dma_addr_t ssi_reg = platform_get_resource(pdev,
+                               IORESOURCE_MEM, RSND_GEN2_SSI)->start;
+       dma_addr_t src_reg = platform_get_resource(pdev,
+                               IORESOURCE_MEM, RSND_GEN2_SCU)->start;
+       int is_ssi = !!(rsnd_io_to_mod_ssi(io) == mod);
+       int use_src = !!rsnd_io_to_mod_src(io);
+       int use_dvc = !!rsnd_io_to_mod_dvc(io);
+       int id = rsnd_mod_id(mod);
+       struct dma_addr {
+               dma_addr_t src_addr;
+               dma_addr_t dst_addr;
+       } dma_addrs[2][2][3] = {
+               { /* SRC */
+                       /* Capture */
+                       {{ 0,                           0 },
+                        { RDMA_SRC_O_N(src, id),       0 },
+                        { RDMA_CMD_O_N(src, id),       0 }},
+                       /* Playback */
+                       {{ 0,                           0, },
+                        { 0,                           RDMA_SRC_I_N(src, id) },
+                        { 0,                           RDMA_SRC_I_N(src, id) }}
+               }, { /* SSI */
+                       /* Capture */
+                       {{ RDMA_SSI_O_N(ssi, id),       0 },
+                        { RDMA_SSI_O_P(ssi, id),       RDMA_SRC_I_P(src, id) },
+                        { RDMA_SSI_O_P(ssi, id),       RDMA_SRC_I_P(src, id) }},
+                       /* Playback */
+                       {{ 0,                           RDMA_SSI_I_N(ssi, id) },
+                        { RDMA_SRC_O_P(src, id),       RDMA_SSI_I_P(ssi, id) },
+                        { RDMA_CMD_O_P(src, id),       RDMA_SSI_I_P(ssi, id) }}
+               }
+       };
+
+       cfg->slave_id   = slave_id;
+       cfg->src_addr   = 0;
+       cfg->dst_addr   = 0;
+       cfg->direction  = is_play ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM;
+
+       /*
+        * gen1 uses default DMA addr
+        */
+       if (rsnd_is_gen1(priv))
+               return;
+
+       /* it shouldn't happen */
+       if (use_dvc & !use_src) {
+               dev_err(dev, "DVC is selected without SRC\n");
+               return;
+       }
+
+       cfg->src_addr = dma_addrs[is_ssi][is_play][use_src + use_dvc].src_addr;
+       cfg->dst_addr = dma_addrs[is_ssi][is_play][use_src + use_dvc].dst_addr;
+
+       dev_dbg(dev, "dma%d addr - src : %x / dst : %x\n",
+               id, cfg->src_addr, cfg->dst_addr);
+}
+
 /*
  *             Gen2
  */
@@ -181,6 +276,8 @@ static int rsnd_gen2_regmap_init(struct rsnd_priv *priv, struct rsnd_gen *gen)
                RSND_GEN2_M_REG(gen, SCU,       SRC_BUSIF_MODE, 0x0,    0x20),
                RSND_GEN2_M_REG(gen, SCU,       SRC_ROUTE_MODE0,0xc,    0x20),
                RSND_GEN2_M_REG(gen, SCU,       SRC_CTRL,       0x10,   0x20),
+               RSND_GEN2_M_REG(gen, SCU,       CMD_ROUTE_SLCT, 0x18c,  0x20),
+               RSND_GEN2_M_REG(gen, SCU,       CMD_CTRL,       0x190,  0x20),
                RSND_GEN2_M_REG(gen, SCU,       SRC_SWRSR,      0x200,  0x40),
                RSND_GEN2_M_REG(gen, SCU,       SRC_SRCIR,      0x204,  0x40),
                RSND_GEN2_M_REG(gen, SCU,       SRC_ADINR,      0x214,  0x40),
@@ -189,6 +286,14 @@ static int rsnd_gen2_regmap_init(struct rsnd_priv *priv, struct rsnd_gen *gen)
                RSND_GEN2_M_REG(gen, SCU,       SRC_SRCCR,      0x224,  0x40),
                RSND_GEN2_M_REG(gen, SCU,       SRC_BSDSR,      0x22c,  0x40),
                RSND_GEN2_M_REG(gen, SCU,       SRC_BSISR,      0x238,  0x40),
+               RSND_GEN2_M_REG(gen, SCU,       DVC_SWRSR,      0xe00,  0x100),
+               RSND_GEN2_M_REG(gen, SCU,       DVC_DVUIR,      0xe04,  0x100),
+               RSND_GEN2_M_REG(gen, SCU,       DVC_ADINR,      0xe08,  0x100),
+               RSND_GEN2_M_REG(gen, SCU,       DVC_DVUCR,      0xe10,  0x100),
+               RSND_GEN2_M_REG(gen, SCU,       DVC_ZCMCR,      0xe14,  0x100),
+               RSND_GEN2_M_REG(gen, SCU,       DVC_VOL0R,      0xe28,  0x100),
+               RSND_GEN2_M_REG(gen, SCU,       DVC_VOL1R,      0xe2c,  0x100),
+               RSND_GEN2_M_REG(gen, SCU,       DVC_DVUER,      0xe48,  0x100),
 
                RSND_GEN2_S_REG(gen, ADG,       BRRA,           0x00),
                RSND_GEN2_S_REG(gen, ADG,       BRRB,           0x04),
@@ -207,6 +312,7 @@ static int rsnd_gen2_regmap_init(struct rsnd_priv *priv, struct rsnd_gen *gen)
                RSND_GEN2_S_REG(gen, ADG,       SRCOUT_TIMSEL2, 0x50),
                RSND_GEN2_S_REG(gen, ADG,       SRCOUT_TIMSEL3, 0x54),
                RSND_GEN2_S_REG(gen, ADG,       SRCOUT_TIMSEL4, 0x58),
+               RSND_GEN2_S_REG(gen, ADG,       CMDOUT_TIMSEL,  0x5c),
 
                RSND_GEN2_M_REG(gen, SSI,       SSICR,          0x00,   0x40),
                RSND_GEN2_M_REG(gen, SSI,       SSISR,          0x04,   0x40),
@@ -252,13 +358,13 @@ static int rsnd_gen2_probe(struct platform_device *pdev,
                return ret;
 
        dev_dbg(dev, "Gen2 device probed\n");
-       dev_dbg(dev, "SCU  : %08x => %p\n", scu_res->start,
+       dev_dbg(dev, "SCU  : %pap => %p\n", &scu_res->start,
                gen->base[RSND_GEN2_SCU]);
-       dev_dbg(dev, "ADG  : %08x => %p\n", adg_res->start,
+       dev_dbg(dev, "ADG  : %pap => %p\n", &adg_res->start,
                gen->base[RSND_GEN2_ADG]);
-       dev_dbg(dev, "SSIU : %08x => %p\n", ssiu_res->start,
+       dev_dbg(dev, "SSIU : %pap => %p\n", &ssiu_res->start,
                gen->base[RSND_GEN2_SSIU]);
-       dev_dbg(dev, "SSI  : %08x => %p\n", ssi_res->start,
+       dev_dbg(dev, "SSI  : %pap => %p\n", &ssi_res->start,
                gen->base[RSND_GEN2_SSI]);
 
        return 0;
@@ -345,11 +451,11 @@ static int rsnd_gen1_probe(struct platform_device *pdev,
                return ret;
 
        dev_dbg(dev, "Gen1 device probed\n");
-       dev_dbg(dev, "SRU : %08x => %p\n",      sru_res->start,
+       dev_dbg(dev, "SRU : %pap => %p\n",      &sru_res->start,
                                                gen->base[RSND_GEN1_SRU]);
-       dev_dbg(dev, "ADG : %08x => %p\n",      adg_res->start,
+       dev_dbg(dev, "ADG : %pap => %p\n",      &adg_res->start,
                                                gen->base[RSND_GEN1_ADG]);
-       dev_dbg(dev, "SSI : %08x => %p\n",      ssi_res->start,
+       dev_dbg(dev, "SSI : %pap => %p\n",      &ssi_res->start,
                                                gen->base[RSND_GEN1_SSI]);
 
        return 0;