summaryrefslogtreecommitdiff
path: root/sound/soc/sh
diff options
context:
space:
mode:
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>2013-11-29 06:43:45 +0400
committerMark Brown <broonie@linaro.org>2013-11-29 16:09:54 +0400
commit507d466c733e28d132a7be87040a3da126df7947 (patch)
treecffaa17b4a801ed296fd7af37c02c15ef4029729 /sound/soc/sh
parent531eaf491e25ce215bbcf434e23e77f53fc98171 (diff)
downloadlinux-507d466c733e28d132a7be87040a3da126df7947.tar.xz
ASoC: rcar: add Gen2 sound support
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>
Diffstat (limited to 'sound/soc/sh')
-rw-r--r--sound/soc/sh/rcar/gen.c91
-rw-r--r--sound/soc/sh/rcar/rsnd.h3
-rw-r--r--sound/soc/sh/rcar/ssi.c3
3 files changed, 91 insertions, 6 deletions
diff --git a/sound/soc/sh/rcar/gen.c b/sound/soc/sh/rcar/gen.c
index a29e36eb1a30..bf066f73ef05 100644
--- a/sound/soc/sh/rcar/gen.c
+++ b/sound/soc/sh/rcar/gen.c
@@ -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;
}
diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h
index 63a9d7081c60..bff7b9e53066 100644
--- a/sound/soc/sh/rcar/rsnd.h
+++ b/sound/soc/sh/rcar/rsnd.h
@@ -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,
diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c
index b71cf9d7dd3f..477465f9507b 100644
--- a/sound/soc/sh/rcar/ssi.c
+++ b/sound/soc/sh/rcar/ssi.c
@@ -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));