blob: e0eaad884449691ae727b1864eff01d6452e26b9 [file] [log] [blame]
From 32f2350521c74d71d16b2c8e1f4701903fa6c6cf Mon Sep 17 00:00:00 2001
From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Date: Mon, 3 Mar 2014 20:50:00 -0800
Subject: ASoC: rsnd: Get correct SCU ID
Current rsnd driver is assuming that SCU/SRU ID is
same as SSIU/SSI ID, because Gen1 can't select it.
But, Gen2 can select it.
The SCU/SRU/SSIU/SSI pair depends on the platform.
This patch get correct SCU ID from platform info.
To keep compatible, it still assuming SCU ID = SSI ID
if platform doesn't have info
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: Mark Brown <broonie@linaro.org>
(cherry picked from commit 389933d9f6e55a1ef3a71549c36f6283b9f8c145)
Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
---
include/sound/rcar_snd.h | 1 +
sound/soc/sh/rcar/core.c | 47 +++++++++++++++++++++++++++++++++--------------
sound/soc/sh/rcar/rsnd.h | 14 ++++++++++++++
sound/soc/sh/rcar/scu.c | 21 ++++++++++++++++-----
sound/soc/sh/rcar/ssi.c | 9 ++++++++-
5 files changed, 72 insertions(+), 20 deletions(-)
diff --git a/include/sound/rcar_snd.h b/include/sound/rcar_snd.h
index 698f7b5fc76d..1d8c68323f49 100644
--- a/include/sound/rcar_snd.h
+++ b/include/sound/rcar_snd.h
@@ -70,6 +70,7 @@ struct rsnd_scu_platform_info {
struct rsnd_dai_path_info {
struct rsnd_ssi_platform_info *ssi;
+ struct rsnd_scu_platform_info *scu;
};
struct rsnd_dai_platform_info {
diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c
index 450472633eb1..7316d10e4649 100644
--- a/sound/soc/sh/rcar/core.c
+++ b/sound/soc/sh/rcar/core.c
@@ -107,6 +107,11 @@
(!(priv->info->func) ? 0 : \
priv->info->func(param))
+#define rsnd_is_enable_path(io, name) \
+ ((io)->info ? (io)->info->name : NULL)
+#define rsnd_info_id(priv, io, name) \
+ ((io)->info->name - priv->info->name##_info)
+
/*
* rsnd_mod functions
*/
@@ -572,8 +577,10 @@ static int rsnd_path_init(struct rsnd_priv *priv,
struct rsnd_dai_stream *io)
{
struct rsnd_mod *mod;
+ struct rsnd_dai_platform_info *dai_info = rdai->info;
int ret;
- int id;
+ int ssi_id = -1;
+ int scu_id = -1;
/*
* Gen1 is created by SRU/SSI, and this SRU is base module of
@@ -584,29 +591,35 @@ static int rsnd_path_init(struct rsnd_priv *priv,
*
* Gen2 SCU path is very flexible, but, Gen1 SRU (SCU parts) is
* using fixed path.
- *
- * Then, SSI id = SCU id here
*/
- /* get SSI's ID */
- mod = rsnd_ssi_mod_get_frm_dai(priv,
- rsnd_dai_id(priv, rdai),
- rsnd_dai_is_play(rdai, io));
- if (!mod)
- return 0;
- id = rsnd_mod_id(mod);
+ if (dai_info) {
+ if (rsnd_is_enable_path(io, ssi))
+ ssi_id = rsnd_info_id(priv, io, ssi);
+ if (rsnd_is_enable_path(io, scu))
+ scu_id = rsnd_info_id(priv, io, scu);
+ } else {
+ /* get SSI's ID */
+ mod = rsnd_ssi_mod_get_frm_dai(priv,
+ rsnd_dai_id(priv, rdai),
+ rsnd_dai_is_play(rdai, io));
+ if (!mod)
+ return 0;
+ ssi_id = scu_id = rsnd_mod_id(mod);
+ }
+
ret = 0;
/* SCU */
- mod = rsnd_scu_mod_get(priv, id);
- if (mod) {
+ if (scu_id >= 0) {
+ mod = rsnd_scu_mod_get(priv, scu_id);
ret = rsnd_dai_connect(mod, io);
if (ret < 0)
return ret;
}
/* SSI */
- mod = rsnd_ssi_mod_get(priv, id);
- if (mod) {
+ if (ssi_id >= 0) {
+ mod = rsnd_ssi_mod_get(priv, ssi_id);
ret = rsnd_dai_connect(mod, io);
if (ret < 0)
return ret;
@@ -699,6 +712,9 @@ static int rsnd_dai_probe(struct platform_device *pdev,
drv[i].playback.formats = RSND_FMTS;
drv[i].playback.channels_min = 2;
drv[i].playback.channels_max = 2;
+
+ if (info->dai_info)
+ rdai[i].playback.info = &info->dai_info[i].playback;
rsnd_path_init(priv, &rdai[i], &rdai[i].playback);
}
if (cmod) {
@@ -706,6 +722,9 @@ static int rsnd_dai_probe(struct platform_device *pdev,
drv[i].capture.formats = RSND_FMTS;
drv[i].capture.channels_min = 2;
drv[i].capture.channels_max = 2;
+
+ if (info->dai_info)
+ rdai[i].capture.info = &info->dai_info[i].capture;
rsnd_path_init(priv, &rdai[i], &rdai[i].capture);
}
diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h
index d5afdee6b6f2..3472631c7b35 100644
--- a/sound/soc/sh/rcar/rsnd.h
+++ b/sound/soc/sh/rcar/rsnd.h
@@ -211,6 +211,7 @@ char *rsnd_mod_name(struct rsnd_mod *mod);
struct rsnd_dai_stream {
struct snd_pcm_substream *substream;
struct rsnd_mod *mod[RSND_MOD_MAX];
+ struct rsnd_dai_path_info *info; /* rcar_snd.h */
int byte_pos;
int period_pos;
int byte_per_period;
@@ -328,6 +329,19 @@ struct rsnd_priv {
#define rsnd_lock(priv, flags) spin_lock_irqsave(&priv->lock, flags)
#define rsnd_unlock(priv, flags) spin_unlock_irqrestore(&priv->lock, flags)
+#define rsnd_info_is_playback(priv, type) \
+({ \
+ struct rcar_snd_info *info = rsnd_priv_to_info(priv); \
+ int i, is_play = 0; \
+ for (i = 0; i < info->dai_info_nr; i++) { \
+ if (info->dai_info[i].playback.type == (type)->info) { \
+ is_play = 1; \
+ break; \
+ } \
+ } \
+ is_play; \
+})
+
/*
* R-Car SCU
*/
diff --git a/sound/soc/sh/rcar/scu.c b/sound/soc/sh/rcar/scu.c
index 1073d35486e3..b517300f32ce 100644
--- a/sound/soc/sh/rcar/scu.c
+++ b/sound/soc/sh/rcar/scu.c
@@ -620,6 +620,9 @@ int rsnd_scu_probe(struct platform_device *pdev,
* init SCU
*/
nr = info->scu_info_nr;
+ if (!nr)
+ return 0;
+
scu = devm_kzalloc(dev, sizeof(*scu) * nr, GFP_KERNEL);
if (!scu) {
dev_err(dev, "SCU allocate failed\n");
@@ -644,11 +647,19 @@ int rsnd_scu_probe(struct platform_device *pdev,
if (rsnd_is_gen1(priv))
ops = &rsnd_scu_gen1_ops;
if (rsnd_is_gen2(priv)) {
- struct rsnd_mod *ssi = rsnd_ssi_mod_get(priv, i);
- int ret = rsnd_dma_init(priv,
- rsnd_mod_to_dma(&scu->mod),
- rsnd_ssi_is_play(ssi),
- scu->info->dma_id);
+ int ret;
+ int is_play;
+
+ if (info->dai_info) {
+ is_play = rsnd_info_is_playback(priv, scu);
+ } else {
+ struct rsnd_mod *ssi = rsnd_ssi_mod_get(priv, i);
+ is_play = rsnd_ssi_is_play(ssi);
+ }
+ ret = rsnd_dma_init(priv,
+ rsnd_mod_to_dma(&scu->mod),
+ is_play,
+ scu->info->dma_id);
if (ret < 0)
return ret;
diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c
index 34234813f742..9162c2bb6cc5 100644
--- a/sound/soc/sh/rcar/ssi.c
+++ b/sound/soc/sh/rcar/ssi.c
@@ -567,9 +567,16 @@ int rsnd_ssi_probe(struct platform_device *pdev,
* SSI DMA case
*/
if (pinfo->dma_id > 0) {
+ int is_play;
+
+ if (info->dai_info)
+ is_play = rsnd_info_is_playback(priv, ssi);
+ else
+ is_play = rsnd_ssi_is_play(&ssi->mod);
+
ret = rsnd_dma_init(
priv, rsnd_mod_to_dma(&ssi->mod),
- rsnd_ssi_is_play(&ssi->mod),
+ is_play,
pinfo->dma_id);
if (ret < 0)
dev_info(dev, "SSI DMA failed. try PIO transter\n");
--
2.1.2