int rsnd_ssi_probe(struct platform_device *pdev, const struct rsnd_of_data *of_data, struct rsnd_priv *priv) { struct rcar_snd_info *info = rsnd_priv_to_info(priv); struct rsnd_ssi_platform_info *pinfo; struct device *dev = rsnd_priv_to_dev(priv); struct rsnd_mod_ops *ops; struct clk *clk; struct rsnd_ssi *ssi; char name[RSND_SSI_NAME_SIZE]; int i, nr, ret; rsnd_of_parse_ssi(pdev, of_data, priv); /* * init SSI */ nr = info->ssi_info_nr; ssi = devm_kzalloc(dev, sizeof(*ssi) * nr, GFP_KERNEL); if (!ssi) { dev_err(dev, "SSI allocate failed\n"); return -ENOMEM; } priv->ssi = ssi; priv->ssi_nr = nr; for_each_rsnd_ssi(ssi, priv, i) { pinfo = &info->ssi_info[i]; snprintf(name, RSND_SSI_NAME_SIZE, "%s.%d", SSI_NAME, i); clk = devm_clk_get(dev, name); if (IS_ERR(clk)) return PTR_ERR(clk); ssi->info = pinfo; ops = &rsnd_ssi_non_ops; if (pinfo->dma_id > 0) ops = &rsnd_ssi_dma_ops; else if (rsnd_ssi_pio_available(ssi)) ops = &rsnd_ssi_pio_ops; ret = rsnd_mod_init(&ssi->mod, ops, clk, RSND_MOD_SSI, i); if (ret) return ret; rsnd_ssi_parent_clk_setup(priv, ssi); }
int rsnd_ssi_probe(struct platform_device *pdev, struct rcar_snd_info *info, struct rsnd_priv *priv) { struct rsnd_ssi_platform_info *pinfo; struct device *dev = rsnd_priv_to_dev(priv); struct rsnd_mod_ops *ops; struct clk *clk; struct rsnd_ssiu *ssiu; struct rsnd_ssi *ssi; char name[RSND_SSI_NAME_SIZE]; int i, nr, ret; /* * init SSI */ nr = info->ssi_info_nr; ssiu = devm_kzalloc(dev, sizeof(*ssiu) + (sizeof(*ssi) * nr), GFP_KERNEL); if (!ssiu) { dev_err(dev, "SSI allocate failed\n"); return -ENOMEM; } priv->ssiu = ssiu; ssiu->ssi = (struct rsnd_ssi *)(ssiu + 1); ssiu->ssi_nr = nr; for_each_rsnd_ssi(ssi, priv, i) { pinfo = &info->ssi_info[i]; snprintf(name, RSND_SSI_NAME_SIZE, "ssi.%d", i); clk = devm_clk_get(dev, name); if (IS_ERR(clk)) return PTR_ERR(clk); ssi->info = pinfo; ssi->clk = clk; ops = &rsnd_ssi_non_ops; /* * SSI DMA case */ if (pinfo->dma_id > 0) { ret = rsnd_dma_init( priv, rsnd_mod_to_dma(&ssi->mod), (rsnd_ssi_mode_flags(ssi) & RSND_SSI_PLAY), pinfo->dma_id, rsnd_ssi_dma_inquiry, rsnd_ssi_dma_complete); if (ret < 0) dev_info(dev, "SSI DMA failed. try PIO transter\n"); else ops = &rsnd_ssi_dma_ops; dev_dbg(dev, "SSI%d use DMA transfer\n", i); } /* * SSI PIO case */ if (!rsnd_ssi_dma_available(ssi) && rsnd_ssi_pio_available(ssi)) { ret = devm_request_irq(dev, pinfo->pio_irq, &rsnd_ssi_pio_interrupt, IRQF_SHARED, dev_name(dev), ssi); if (ret) { dev_err(dev, "SSI request interrupt failed\n"); return ret; } ops = &rsnd_ssi_pio_ops; dev_dbg(dev, "SSI%d use PIO transfer\n", i); } rsnd_mod_init(priv, &ssi->mod, ops, i); }