]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
ASoC: rcar: add Gen2 sound support
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Fri, 29 Nov 2013 02:43:45 +0000 (18:43 -0800)
committerMark Brown <broonie@linaro.org>
Fri, 29 Nov 2013 12:09:54 +0000 (12:09 +0000)
This patch adds Gen2 sound support for Renesas R-Car.
But, it is supporting PIO transfer only at this point

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: Mark Brown <broonie@linaro.org>
sound/soc/sh/rcar/gen.c
sound/soc/sh/rcar/rsnd.h
sound/soc/sh/rcar/ssi.c

index a29e36eb1a308ac2cbfa2ba4c22d901c53fc42e8..bf066f73ef054e2b7c21c021bb333deb2496daff 100644 (file)
@@ -213,9 +213,88 @@ int rsnd_gen_path_exit(struct rsnd_priv *priv,
 
 /*
  *             Gen2
- *             will be filled in the future
  */
 
+/* single address mapping */
+#define RSND_GEN2_S_REG(gen, reg, id, offset)                          \
+       RSND_REG_SET(gen, RSND_REG_##id, RSND_GEN2_##reg, offset, 0, 9)
+
+/* multi address mapping */
+#define RSND_GEN2_M_REG(gen, reg, id, offset, _id_offset)              \
+       RSND_REG_SET(gen, RSND_REG_##id, RSND_GEN2_##reg, offset, _id_offset, 9)
+
+static int rsnd_gen2_regmap_init(struct rsnd_priv *priv, struct rsnd_gen *gen)
+{
+       struct reg_field regf[RSND_REG_MAX] = {
+               RSND_GEN2_S_REG(gen, SSIU,      SSI_MODE0,      0x800),
+               RSND_GEN2_S_REG(gen, SSIU,      SSI_MODE1,      0x804),
+               /* FIXME: it needs SSI_MODE2/3 in the future */
+               RSND_GEN2_M_REG(gen, SSIU,      INT_ENABLE,     0x18,   0x80),
+
+               RSND_GEN2_S_REG(gen, ADG,       BRRA,           0x00),
+               RSND_GEN2_S_REG(gen, ADG,       BRRB,           0x04),
+               RSND_GEN2_S_REG(gen, ADG,       SSICKR,         0x08),
+               RSND_GEN2_S_REG(gen, ADG,       AUDIO_CLK_SEL0, 0x0c),
+               RSND_GEN2_S_REG(gen, ADG,       AUDIO_CLK_SEL1, 0x10),
+               RSND_GEN2_S_REG(gen, ADG,       AUDIO_CLK_SEL2, 0x14),
+
+               RSND_GEN2_M_REG(gen, SSI,       SSICR,          0x00,   0x40),
+               RSND_GEN2_M_REG(gen, SSI,       SSISR,          0x04,   0x40),
+               RSND_GEN2_M_REG(gen, SSI,       SSITDR,         0x08,   0x40),
+               RSND_GEN2_M_REG(gen, SSI,       SSIRDR,         0x0c,   0x40),
+               RSND_GEN2_M_REG(gen, SSI,       SSIWSR,         0x20,   0x40),
+       };
+
+       return rsnd_gen_regmap_init(priv, gen, regf);
+}
+
+static int rsnd_gen2_probe(struct platform_device *pdev,
+                          struct rcar_snd_info *info,
+                          struct rsnd_priv *priv)
+{
+       struct device *dev = rsnd_priv_to_dev(priv);
+       struct rsnd_gen *gen = rsnd_priv_to_gen(priv);
+       struct resource *scu_res;
+       struct resource *adg_res;
+       struct resource *ssiu_res;
+       struct resource *ssi_res;
+       int ret;
+
+       /*
+        * map address
+        */
+       scu_res  = platform_get_resource(pdev, IORESOURCE_MEM, RSND_GEN2_SCU);
+       adg_res  = platform_get_resource(pdev, IORESOURCE_MEM, RSND_GEN2_ADG);
+       ssiu_res = platform_get_resource(pdev, IORESOURCE_MEM, RSND_GEN2_SSIU);
+       ssi_res  = platform_get_resource(pdev, IORESOURCE_MEM, RSND_GEN2_SSI);
+
+       gen->base[RSND_GEN2_SCU]  = devm_ioremap_resource(dev, scu_res);
+       gen->base[RSND_GEN2_ADG]  = devm_ioremap_resource(dev, adg_res);
+       gen->base[RSND_GEN2_SSIU] = devm_ioremap_resource(dev, ssiu_res);
+       gen->base[RSND_GEN2_SSI]  = devm_ioremap_resource(dev, ssi_res);
+       if (IS_ERR(gen->base[RSND_GEN2_SCU])  ||
+           IS_ERR(gen->base[RSND_GEN2_ADG])  ||
+           IS_ERR(gen->base[RSND_GEN2_SSIU]) ||
+           IS_ERR(gen->base[RSND_GEN2_SSI]))
+               return -ENODEV;
+
+       ret = rsnd_gen2_regmap_init(priv, gen);
+       if (ret < 0)
+               return ret;
+
+       dev_dbg(dev, "Gen2 device probed\n");
+       dev_dbg(dev, "SRU  : %08x => %p\n", scu_res->start,
+               gen->base[RSND_GEN2_SCU]);
+       dev_dbg(dev, "ADG  : %08x => %p\n", adg_res->start,
+               gen->base[RSND_GEN2_ADG]);
+       dev_dbg(dev, "SSIU : %08x => %p\n", ssiu_res->start,
+               gen->base[RSND_GEN2_SSIU]);
+       dev_dbg(dev, "SSI  : %08x => %p\n", ssi_res->start,
+               gen->base[RSND_GEN2_SSI]);
+
+       return 0;
+}
+
 /*
  *             Gen1
  */
@@ -318,12 +397,14 @@ int rsnd_gen_probe(struct platform_device *pdev,
 
        priv->gen = gen;
 
-       if (rsnd_is_gen1(priv)) {
+       ret = -ENODEV;
+       if (rsnd_is_gen1(priv))
                ret = rsnd_gen1_probe(pdev, info, priv);
-       } else {
+       else if (rsnd_is_gen2(priv))
+               ret = rsnd_gen2_probe(pdev, info, priv);
+
+       if (ret < 0)
                dev_err(dev, "unknown generation R-Car sound device\n");
-               return -ENODEV;
-       }
 
        return ret;
 }
index 63a9d7081c609c92304fcd8feac1b41c61172158..bff7b9e5306656a55e6686142f4602be5c859b8a 100644 (file)
@@ -31,7 +31,7 @@
  * see gen1/gen2 for detail
  */
 enum rsnd_reg {
-       /* SRU/SCU */
+       /* SRU/SCU/SSIU */
        RSND_REG_SRC_ROUTE_SEL,
        RSND_REG_SRC_TMG_SEL0,
        RSND_REG_SRC_TMG_SEL1,
@@ -41,6 +41,7 @@ enum rsnd_reg {
        RSND_REG_SSI_MODE1,
        RSND_REG_BUSIF_MODE,
        RSND_REG_BUSIF_ADINR,
+       RSND_REG_INT_ENABLE,
 
        /* ADG */
        RSND_REG_BRRA,
index b71cf9d7dd3febe600465b40cdc5dcaaedb5b6fb..477465f9507b975d19cb70a96d6cc9dbc9f4df92 100644 (file)
@@ -457,6 +457,9 @@ static int rsnd_ssi_pio_start(struct rsnd_mod *mod,
        /* enable PIO IRQ */
        ssi->cr_etc = UIEN | OIEN | DIEN;
 
+       /* enable PIO interrupt */
+       rsnd_mod_write(&ssi->mod, INT_ENABLE, 0x0f000000);
+
        rsnd_ssi_hw_start(ssi, rdai, io);
 
        dev_dbg(dev, "%s.%d start\n", rsnd_mod_name(mod), rsnd_mod_id(mod));