ASoC: rsnd: Get correct SCU ID
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Tue, 4 Mar 2014 04:50:00 +0000 (20:50 -0800)
committerSimon Horman <horms@verge.net.au>
Fri, 5 Dec 2014 00:21:18 +0000 (09:21 +0900)
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
sound/soc/sh/rcar/core.c
sound/soc/sh/rcar/rsnd.h
sound/soc/sh/rcar/scu.c
sound/soc/sh/rcar/ssi.c

index 698f7b5..1d8c683 100644 (file)
@@ -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 {
index 4504726..7316d10 100644 (file)
        (!(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);
                }
 
index d5afdee..3472631 100644 (file)
@@ -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
  */
index 1073d35..b517300 100644 (file)
@@ -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;
 
index 3423481..9162c2b 100644 (file)
@@ -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");