ASoC: rsnd: remove platform dai and add dai_id on platform setting
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Mon, 29 Jul 2013 01:58:29 +0000 (18:58 -0700)
committerMark Brown <broonie@linaro.org>
Tue, 6 Aug 2013 16:56:13 +0000 (17:56 +0100)
Current rsnd driver is using struct rsnd_dai_platform_info
so that indicate sound DAI information (playback/capture SSI ID).
But, SSI settings were also required separately.
Thus, platform settings was very un-understandable.
This patch adds dai_id to SSI
settings, and removed rsnd_dai_platform_info.

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

index 99d8dd0..33233ed 100644 (file)
 /*
  * flags
  *
- * 0xA0000000
+ * 0xAB000000
  *
  * A : clock sharing settings
+ * B : SSI direction
  */
 #define RSND_SSI_CLK_PIN_SHARE         (1 << 31)
 #define RSND_SSI_CLK_FROM_ADG          (1 << 30) /* clock parent is master */
 #define RSND_SSI_SYNC                  (1 << 29) /* SSI34_sync etc */
 
+#define RSND_SSI_PLAY                  (1 << 24)
+
+#define RSND_SSI_SET(_dai_id, _pio_irq, _flags) \
+{ .dai_id = _dai_id, .pio_irq = _pio_irq, .flags = _flags }
+#define RSND_SSI_UNUSED \
+{ .dai_id = -1, .pio_irq = -1, .flags = 0 }
+
 struct rsnd_ssi_platform_info {
+       int dai_id;
        int pio_irq;
        u32 flags;
 };
@@ -45,11 +54,6 @@ struct rsnd_scu_platform_info {
        u32 flags;
 };
 
-struct rsnd_dai_platform_info {
-       int ssi_id_playback;
-       int ssi_id_capture;
-};
-
 /*
  * flags
  *
@@ -66,8 +70,6 @@ struct rcar_snd_info {
        int ssi_info_nr;
        struct rsnd_scu_platform_info *scu_info;
        int scu_info_nr;
-       struct rsnd_dai_platform_info *dai_info;
-       int dai_info_nr;
        int (*start)(int id);
        int (*stop)(int id);
 };
index 9a5469d..420d6df 100644 (file)
@@ -219,6 +219,16 @@ int rsnd_dai_disconnect(struct rsnd_mod *mod)
        return 0;
 }
 
+int rsnd_dai_id(struct rsnd_priv *priv, struct rsnd_dai *rdai)
+{
+       int id = rdai - priv->rdai;
+
+       if ((id < 0) || (id >= rsnd_dai_nr(priv)))
+               return -EINVAL;
+
+       return id;
+}
+
 struct rsnd_dai *rsnd_dai_get(struct rsnd_priv *priv, int id)
 {
        return priv->rdai + id;
@@ -315,9 +325,10 @@ static int rsnd_soc_dai_trigger(struct snd_pcm_substream *substream, int cmd,
        struct rsnd_priv *priv = snd_soc_dai_get_drvdata(dai);
        struct rsnd_dai *rdai = rsnd_dai_to_rdai(dai);
        struct rsnd_dai_stream *io = rsnd_rdai_to_io(rdai, substream);
-       struct rsnd_dai_platform_info *info = rsnd_dai_get_platform_info(rdai);
-       int ssi_id = rsnd_dai_is_play(rdai, io) ?       info->ssi_id_playback :
-                                                       info->ssi_id_capture;
+       struct rsnd_mod *mod = rsnd_ssi_mod_get_frm_dai(priv,
+                                               rsnd_dai_id(priv, rdai),
+                                               rsnd_dai_is_play(rdai, io));
+       int ssi_id = rsnd_mod_id(mod);
        int ret;
        unsigned long flags;
 
@@ -439,10 +450,24 @@ static int rsnd_dai_probe(struct platform_device *pdev,
 {
        struct snd_soc_dai_driver *drv;
        struct rsnd_dai *rdai;
+       struct rsnd_mod *pmod, *cmod;
        struct device *dev = rsnd_priv_to_dev(priv);
-       struct rsnd_dai_platform_info *dai_info;
-       int dai_nr = info->dai_info_nr;
-       int i, pid, cid;
+       int dai_nr;
+       int i;
+
+       /* get max dai nr */
+       for (dai_nr = 0; dai_nr < 32; dai_nr++) {
+               pmod = rsnd_ssi_mod_get_frm_dai(priv, dai_nr, 1);
+               cmod = rsnd_ssi_mod_get_frm_dai(priv, dai_nr, 0);
+
+               if (!pmod && !cmod)
+                       break;
+       }
+
+       if (!dai_nr) {
+               dev_err(dev, "no dai\n");
+               return -EIO;
+       }
 
        drv  = devm_kzalloc(dev, sizeof(*drv)  * dai_nr, GFP_KERNEL);
        rdai = devm_kzalloc(dev, sizeof(*rdai) * dai_nr, GFP_KERNEL);
@@ -452,10 +477,9 @@ static int rsnd_dai_probe(struct platform_device *pdev,
        }
 
        for (i = 0; i < dai_nr; i++) {
-               dai_info = &info->dai_info[i];
 
-               pid = dai_info->ssi_id_playback;
-               cid = dai_info->ssi_id_capture;
+               pmod = rsnd_ssi_mod_get_frm_dai(priv, i, 1);
+               cmod = rsnd_ssi_mod_get_frm_dai(priv, i, 0);
 
                /*
                 *      init rsnd_dai
@@ -463,8 +487,6 @@ static int rsnd_dai_probe(struct platform_device *pdev,
                INIT_LIST_HEAD(&rdai[i].playback.head);
                INIT_LIST_HEAD(&rdai[i].capture.head);
 
-               rdai[i].info = dai_info;
-
                snprintf(rdai[i].name, RSND_DAI_NAME_SIZE, "rsnd-dai.%d", i);
 
                /*
@@ -472,20 +494,22 @@ static int rsnd_dai_probe(struct platform_device *pdev,
                 */
                drv[i].name     = rdai[i].name;
                drv[i].ops      = &rsnd_soc_dai_ops;
-               if (pid >= 0) {
+               if (pmod) {
                        drv[i].playback.rates           = RSND_RATES;
                        drv[i].playback.formats         = RSND_FMTS;
                        drv[i].playback.channels_min    = 2;
                        drv[i].playback.channels_max    = 2;
                }
-               if (cid >= 0) {
+               if (cmod) {
                        drv[i].capture.rates            = RSND_RATES;
                        drv[i].capture.formats          = RSND_FMTS;
                        drv[i].capture.channels_min     = 2;
                        drv[i].capture.channels_max     = 2;
                }
 
-               dev_dbg(dev, "%s (%d, %d) probed", rdai[i].name, pid, cid);
+               dev_dbg(dev, "%s (%s/%s)\n", rdai[i].name,
+                       pmod ? "play"    : " -- ",
+                       cmod ? "capture" : "  --   ");
        }
 
        priv->dai_nr    = dai_nr;
@@ -627,10 +651,6 @@ static int rsnd_probe(struct platform_device *pdev)
        if (ret < 0)
                return ret;
 
-       ret = rsnd_dai_probe(pdev, info, priv);
-       if (ret < 0)
-               return ret;
-
        ret = rsnd_scu_probe(pdev, info, priv);
        if (ret < 0)
                return ret;
@@ -643,6 +663,10 @@ static int rsnd_probe(struct platform_device *pdev)
        if (ret < 0)
                return ret;
 
+       ret = rsnd_dai_probe(pdev, info, priv);
+       if (ret < 0)
+               return ret;
+
        /*
         *      asoc register
         */
index 61232cd..460c57e 100644 (file)
@@ -49,7 +49,6 @@ static int rsnd_gen1_path_init(struct rsnd_priv *priv,
                               struct rsnd_dai *rdai,
                               struct rsnd_dai_stream *io)
 {
-       struct rsnd_dai_platform_info *info = rsnd_dai_get_platform_info(rdai);
        struct rsnd_mod *mod;
        int ret;
        int id;
@@ -67,10 +66,11 @@ static int rsnd_gen1_path_init(struct rsnd_priv *priv,
         * Then, SSI id = SCU id here
         */
 
-       if (rsnd_dai_is_play(rdai, io))
-               id = info->ssi_id_playback;
-       else
-               id = info->ssi_id_capture;
+       /* get SSI's ID */
+       mod = rsnd_ssi_mod_get_frm_dai(priv,
+                                      rsnd_dai_id(priv, rdai),
+                                      rsnd_dai_is_play(rdai, io));
+       id = rsnd_mod_id(mod);
 
        /* SSI */
        mod = rsnd_ssi_mod_get(priv, id);
index 0e7727c..9243e38 100644 (file)
@@ -157,6 +157,7 @@ int rsnd_dai_disconnect(struct rsnd_mod *mod);
 int rsnd_dai_connect(struct rsnd_dai *rdai, struct rsnd_mod *mod,
                     struct rsnd_dai_stream *io);
 int rsnd_dai_is_play(struct rsnd_dai *rdai, struct rsnd_dai_stream *io);
+int rsnd_dai_id(struct rsnd_priv *priv, struct rsnd_dai *rdai);
 #define rsnd_dai_get_platform_info(rdai) ((rdai)->info)
 #define rsnd_io_to_runtime(io) ((io)->substream->runtime)
 
@@ -254,5 +255,7 @@ int rsnd_ssi_probe(struct platform_device *pdev,
 void rsnd_ssi_remove(struct platform_device *pdev,
                   struct rsnd_priv *priv);
 struct rsnd_mod *rsnd_ssi_mod_get(struct rsnd_priv *priv, int id);
+struct rsnd_mod *rsnd_ssi_mod_get_frm_dai(struct rsnd_priv *priv,
+                                         int dai_id, int is_play);
 
 #endif
index 061ac7e..c48a6c7 100644 (file)
@@ -87,6 +87,7 @@ struct rsnd_ssiu {
 #define rsnd_ssi_clk_from_parent(ssi) ((ssi)->parent)
 #define rsnd_rdai_is_clk_master(rdai) ((rdai)->clk_master)
 #define rsnd_ssi_mode_flags(p) ((p)->info->flags)
+#define rsnd_ssi_dai_id(ssi) ((ssi)->info->dai_id)
 #define rsnd_ssi_to_ssiu(ssi)\
        (((struct rsnd_ssiu *)((ssi) - rsnd_mod_id(&(ssi)->mod))) - 1)
 
@@ -502,6 +503,27 @@ static struct rsnd_mod_ops rsnd_ssi_non_ops = {
 /*
  *             ssi mod function
  */
+struct rsnd_mod *rsnd_ssi_mod_get_frm_dai(struct rsnd_priv *priv,
+                                         int dai_id, int is_play)
+{
+       struct rsnd_ssi *ssi;
+       int i, has_play;
+
+       is_play = !!is_play;
+
+       for_each_rsnd_ssi(ssi, priv, i) {
+               if (rsnd_ssi_dai_id(ssi) != dai_id)
+                       continue;
+
+               has_play = !!(rsnd_ssi_mode_flags(ssi) & RSND_SSI_PLAY);
+
+               if (is_play == has_play)
+                       return &ssi->mod;
+       }
+
+       return NULL;
+}
+
 struct rsnd_mod *rsnd_ssi_mod_get(struct rsnd_priv *priv, int id)
 {
        BUG_ON(id < 0 || id >= rsnd_ssi_nr(priv));