+ return &((struct rsnd_ssi *)(priv->ssi) + id)->mod;
+}
+
+int rsnd_ssi_is_pin_sharing(struct rsnd_mod *mod)
+{
+ struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
+
+ return !!(rsnd_ssi_mode_flags(ssi) & RSND_SSI_CLK_PIN_SHARE);
+}
+
+int rsnd_ssi_is_play(struct rsnd_mod *mod)
+{
+ struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
+
+ return !!(rsnd_ssi_mode_flags(ssi) & RSND_SSI_PLAY);
+}
+
+static void rsnd_ssi_parent_clk_setup(struct rsnd_priv *priv, struct rsnd_ssi *ssi)
+{
+ if (!rsnd_ssi_is_pin_sharing(&ssi->mod))
+ return;
+
+ switch (rsnd_mod_id(&ssi->mod)) {
+ case 1:
+ case 2:
+ ssi->parent = rsnd_mod_to_ssi(rsnd_ssi_mod_get(priv, 0));
+ break;
+ case 4:
+ ssi->parent = rsnd_mod_to_ssi(rsnd_ssi_mod_get(priv, 3));
+ break;
+ case 8:
+ ssi->parent = rsnd_mod_to_ssi(rsnd_ssi_mod_get(priv, 7));
+ break;
+ }
+}
+
+
+static void rsnd_of_parse_ssi(struct platform_device *pdev,
+ const struct rsnd_of_data *of_data,
+ struct rsnd_priv *priv)
+{
+ struct device_node *node;
+ struct device_node *np;
+ struct rsnd_ssi_platform_info *ssi_info;
+ struct rcar_snd_info *info = rsnd_priv_to_info(priv);
+ struct device *dev = &pdev->dev;
+ int nr, i;
+
+ if (!of_data)
+ return;
+
+ node = of_get_child_by_name(dev->of_node, "rcar_sound,ssi");
+ if (!node)
+ return;
+
+ nr = of_get_child_count(node);
+ if (!nr)
+ return;
+
+ ssi_info = devm_kzalloc(dev,
+ sizeof(struct rsnd_ssi_platform_info) * nr,
+ GFP_KERNEL);
+ if (!ssi_info) {
+ dev_err(dev, "ssi info allocation error\n");
+ return;
+ }
+
+ info->ssi_info = ssi_info;
+ info->ssi_info_nr = nr;
+
+ i = -1;
+ for_each_child_of_node(node, np) {
+ i++;
+
+ ssi_info = info->ssi_info + i;
+
+ /*
+ * pin settings
+ */
+ if (of_get_property(np, "shared-pin", NULL))
+ ssi_info->flags |= RSND_SSI_CLK_PIN_SHARE;
+
+ /*
+ * irq
+ */
+ ssi_info->pio_irq = irq_of_parse_and_map(np, 0);
+ }