extern void aml_spdif_play(void); static void aml_dai_i2s_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct snd_pcm_runtime *runtime = substream->runtime; if (runtime->channels == 8 || IEC958_mode_codec == 0) { aml_spdif_play();
printk("alloc aml_runtime_data error\n"); ret = -ENOMEM; goto out; } prtd->substream = substream; runtime->private_data = prtd; } s = &prtd->s; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { s->device_type = AML_AUDIO_SPDIFOUT; audio_spdifout_pg_enable(1); /* aml_spdif_play_stop(); */ } else { s->device_type = AML_AUDIO_SPDIFIN; } return 0; out: return ret; }
static int aml_dai_spdif_remove(struct platform_device *pdev) { snd_soc_unregister_component(&pdev->dev); return 0; }
static int aml_dai_spdif_probe(struct platform_device *pdev) { int i, ret; struct reset_control *spdif_reset; struct aml_spdif *spdif_priv; pr_info("aml_spdif_probe\n"); /* enable spdif power gate first */ for (i = 0; i < ARRAY_SIZE(gate_names); i++) { spdif_reset = devm_reset_control_get(&pdev->dev, gate_names[i]); if (IS_ERR(spdif_reset)) { dev_err(&pdev->dev, "Can't get aml audio gate\n"); return PTR_ERR(spdif_reset); } reset_control_deassert(spdif_reset); } spdif_priv = devm_kzalloc(&pdev->dev, sizeof(struct aml_spdif), GFP_KERNEL); if (!spdif_priv) { dev_err(&pdev->dev, "Can't allocate spdif_priv\n"); ret = -ENOMEM; goto err; } dev_set_drvdata(&pdev->dev, spdif_priv); spdif_p = spdif_priv; spdif_priv->clk_mpl1 = devm_clk_get(&pdev->dev, "mpll1"); if (IS_ERR(spdif_priv->clk_mpl1)) { dev_err(&pdev->dev, "Can't retrieve mpll1 clock\n"); ret = PTR_ERR(spdif_priv->clk_mpl1); goto err; } spdif_priv->clk_i958 = devm_clk_get(&pdev->dev, "i958"); if (IS_ERR(spdif_priv->clk_i958)) { dev_err(&pdev->dev, "Can't retrieve spdif clk_i958 clock\n"); ret = PTR_ERR(spdif_priv->clk_i958); goto err; } spdif_priv->clk_mclk = devm_clk_get(&pdev->dev, "mclk"); if (IS_ERR(spdif_priv->clk_mclk)) { dev_err(&pdev->dev, "Can't retrieve spdif clk_mclk clock\n"); ret = PTR_ERR(spdif_priv->clk_mclk); goto err; } spdif_priv->clk_spdif = devm_clk_get(&pdev->dev, "spdif"); if (IS_ERR(spdif_priv->clk_spdif)) { dev_err(&pdev->dev, "Can't retrieve spdif clock\n"); ret = PTR_ERR(spdif_priv->clk_spdif); goto err; } ret = clk_set_parent(spdif_priv->clk_i958, spdif_priv->clk_mpl1); if (ret) { pr_err("Can't set i958 clk parent: %d\n", ret); return ret; } ret = clk_set_parent(spdif_priv->clk_spdif, spdif_priv->clk_i958); if (ret) { pr_err("Can't set spdif clk parent: %d\n", ret); return ret; } ret = clk_prepare_enable(spdif_priv->clk_spdif); if (ret) { pr_err("Can't enable spdif clock: %d\n", ret); goto err; } aml_spdif_play(); ret = snd_soc_register_component(&pdev->dev, &aml_component, aml_spdif_dai, ARRAY_SIZE(aml_spdif_dai)); if (ret) { pr_err("Can't register spdif dai: %d\n", ret); goto err_clk_dis; } return 0; err_clk_dis: clk_disable_unprepare(spdif_priv->clk_spdif); err: return ret; }