diff --git a/include/sound/rcar_snd.h b/include/sound/rcar_snd.h
index 99d8dd0..33233ed 100644
--- a/include/sound/rcar_snd.h
+++ b/include/sound/rcar_snd.h
@@ -28,15 +28,24 @@
 /*
  * 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);
 };
diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c
index 9a5469d..420d6df 100644
--- a/sound/soc/sh/rcar/core.c
+++ b/sound/soc/sh/rcar/core.c
@@ -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
 	 */
diff --git a/sound/soc/sh/rcar/gen.c b/sound/soc/sh/rcar/gen.c
index 61232cd..460c57e 100644
--- a/sound/soc/sh/rcar/gen.c
+++ b/sound/soc/sh/rcar/gen.c
@@ -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);
diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h
index 0e7727c..9243e38 100644
--- a/sound/soc/sh/rcar/rsnd.h
+++ b/sound/soc/sh/rcar/rsnd.h
@@ -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
diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c
index 061ac7e..c48a6c7 100644
--- a/sound/soc/sh/rcar/ssi.c
+++ b/sound/soc/sh/rcar/ssi.c
@@ -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));
