summaryrefslogtreecommitdiff
path: root/sound/soc/sh/rcar/ssi.c
diff options
context:
space:
mode:
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>2016-02-18 11:19:12 +0300
committerMark Brown <broonie@kernel.org>2016-02-19 18:53:02 +0300
commitfd9adcfdc1434fdd4d0a14ddfe686449a6ffeeb3 (patch)
treee8020e92bd2bf5784c8e1c4a9f2c32c52aa3e110 /sound/soc/sh/rcar/ssi.c
parent4f5c634d58e71963d3c34a0a4af9ec71785f094f (diff)
downloadlinux-fd9adcfdc1434fdd4d0a14ddfe686449a6ffeeb3.tar.xz
ASoC: rsnd: judge work SSI in runtime
Current rsnd supports multi SSI (maximum 4 SSI for 8ch), and, it should determine whether using each SSI or not in runtime. All SSIs are not used even if there are 4 SSI in case of stereo. Current driver setups un-used SSI in such case. It is no problem, but not needed. This patch judges it. Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound/soc/sh/rcar/ssi.c')
-rw-r--r--sound/soc/sh/rcar/ssi.c27
1 files changed, 27 insertions, 0 deletions
diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c
index 32f1f5fb82b6..0979db8af8f9 100644
--- a/sound/soc/sh/rcar/ssi.c
+++ b/sound/soc/sh/rcar/ssi.c
@@ -96,6 +96,8 @@ struct rsnd_ssi {
#define rsnd_ssi_is_parent(ssi, io) ((ssi) == rsnd_io_to_mod_ssip(io))
#define rsnd_ssi_is_multi_slave(mod, io) \
(rsnd_ssi_multi_slaves(io) & (1 << rsnd_mod_id(mod)))
+#define rsnd_ssi_is_run_mods(mod, io) \
+ (rsnd_ssi_run_mods(io) & (1 << rsnd_mod_id(mod)))
int rsnd_ssi_use_busif(struct rsnd_dai_stream *io)
{
@@ -166,6 +168,16 @@ static u32 rsnd_ssi_multi_slaves(struct rsnd_dai_stream *io)
return mask;
}
+static u32 rsnd_ssi_run_mods(struct rsnd_dai_stream *io)
+{
+ struct rsnd_mod *ssi_mod = rsnd_io_to_mod_ssi(io);
+ struct rsnd_mod *ssi_parent_mod = rsnd_io_to_mod_ssip(io);
+
+ return rsnd_ssi_multi_slaves_runtime(io) |
+ 1 << rsnd_mod_id(ssi_mod) |
+ 1 << rsnd_mod_id(ssi_parent_mod);
+}
+
u32 rsnd_ssi_multi_slaves_runtime(struct rsnd_dai_stream *io)
{
struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
@@ -348,6 +360,9 @@ static int rsnd_ssi_init(struct rsnd_mod *mod,
struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
int ret;
+ if (!rsnd_ssi_is_run_mods(mod, io))
+ return 0;
+
ssi->usrcnt++;
rsnd_mod_power_on(mod);
@@ -374,6 +389,9 @@ static int rsnd_ssi_quit(struct rsnd_mod *mod,
struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
struct device *dev = rsnd_priv_to_dev(priv);
+ if (!rsnd_ssi_is_run_mods(mod, io))
+ return 0;
+
if (!ssi->usrcnt) {
dev_err(dev, "%s[%d] usrcnt error\n",
rsnd_mod_name(mod), rsnd_mod_id(mod));
@@ -422,6 +440,9 @@ static int rsnd_ssi_start(struct rsnd_mod *mod,
struct rsnd_dai_stream *io,
struct rsnd_priv *priv)
{
+ if (!rsnd_ssi_is_run_mods(mod, io))
+ return 0;
+
/*
* EN will be set via SSIU :: SSI_CONTROL
* if Multi channel mode
@@ -441,6 +462,9 @@ static int rsnd_ssi_stop(struct rsnd_mod *mod,
struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
u32 cr;
+ if (!rsnd_ssi_is_run_mods(mod, io))
+ return 0;
+
/*
* don't stop if not last user
* see also
@@ -483,6 +507,9 @@ static int rsnd_ssi_irq(struct rsnd_mod *mod,
if (rsnd_ssi_is_parent(mod, io))
return 0;
+ if (!rsnd_ssi_is_run_mods(mod, io))
+ return 0;
+
if (enable)
val = rsnd_ssi_is_dma_mode(mod) ? 0x0e000000 : 0x0f000000;