diff --git a/sound/soc/intel/boards/sof_rt5682.c b/sound/soc/intel/boards/sof_rt5682.c index 99735cc247c02f..007cf94c0d5d73 100644 --- a/sound/soc/intel/boards/sof_rt5682.c +++ b/sound/soc/intel/boards/sof_rt5682.c @@ -285,22 +285,43 @@ static const struct x86_cpu_id legacy_cpi_ids[] = { {} }; +static struct snd_soc_dai_link_component rt5682_component[] = { + { + .name = "i2c-10EC5682:00", + .dai_name = "rt5682-aif1", + } +}; + +static struct snd_soc_dai_link_component dmic_component[] = { + { + .name = "dmic-codec", + .dai_name = "dmic-hifi", + } +}; + static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev, int ssp_port, int dmic_num, int hdmi_num) { + struct snd_soc_dai_link_component *idisp_components; struct snd_soc_dai_link *links; int i, id = 0; links = devm_kzalloc(dev, sizeof(struct snd_soc_dai_link) * (1 + dmic_num + hdmi_num), GFP_KERNEL); + if (!links) + goto devm_err; + /* SSP */ links[id].name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-Codec", ssp_port); + if (!links[id].name) + goto devm_err; + links[id].id = id; - links[id].codec_name = "i2c-10EC5682:00"; - links[id].codec_dai_name = "rt5682-aif1"; + links[id].codecs = rt5682_component; + links[id].num_codecs = ARRAY_SIZE(rt5682_component); links[id].platforms = platform_component; links[id].num_platforms = ARRAY_SIZE(platform_component); links[id].init = sof_rt5682_codec_init; @@ -312,9 +333,23 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev, if (is_legacy_cpu) { links[id].cpu_dai_name = devm_kasprintf(dev, GFP_KERNEL, "ssp%d-port", ssp_port); + if (!links[id].cpu_dai_name) + goto devm_err; } else { + /* + * Currently, On SKL+ platforms MCLK will be turned off in sof + * runtime suspended, and it will go into runtime suspended + * right after playback is stop. However, rt5682 will output + * static noise if sysclk turns off during playback. Set + * ignore_pmdown_time to power down rt5682 immediately and + * avoid the noise. + * It can be removed once we can control MCLK by driver. + */ + links[id].ignore_pmdown_time = 1; links[id].cpu_dai_name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d Pin", ssp_port); + if (!links[id].cpu_dai_name) + goto devm_err; } id++; @@ -322,11 +357,17 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev, for (i = 1; i <= dmic_num; i++) { links[id].name = devm_kasprintf(dev, GFP_KERNEL, "dmic%02d", i); + if (!links[id].name) + goto devm_err; + links[id].id = id; links[id].cpu_dai_name = devm_kasprintf(dev, GFP_KERNEL, "DMIC%02d Pin", i); - links[id].codec_name = "dmic-codec"; - links[id].codec_dai_name = "dmic-hifi"; + if (!links[id].cpu_dai_name) + goto devm_err; + + links[id].codecs = dmic_component; + links[id].num_codecs = ARRAY_SIZE(dmic_component); links[id].platforms = platform_component; links[id].num_platforms = ARRAY_SIZE(platform_component); links[id].ignore_suspend = 1; @@ -336,16 +377,34 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev, } /* HDMI */ + if (hdmi_num > 0) { + idisp_components = devm_kzalloc(dev, + sizeof(struct snd_soc_dai_link_component) * + hdmi_num, GFP_KERNEL); + if (!idisp_components) + goto devm_err; + } for (i = 1; i <= hdmi_num; i++) { links[id].name = devm_kasprintf(dev, GFP_KERNEL, "iDisp%d", i); + if (!links[id].name) + goto devm_err; + links[id].id = id; links[id].cpu_dai_name = devm_kasprintf(dev, GFP_KERNEL, "iDisp%d Pin", i); - links[id].codec_name = "ehdaudio0D2"; - links[id].codec_dai_name = devm_kasprintf(dev, GFP_KERNEL, - "intel-hdmi-hifi%d", - i); + if (!links[id].cpu_dai_name) + goto devm_err; + + idisp_components[i-1].name = "ehdaudio0D2"; + idisp_components[i-1].dai_name = devm_kasprintf(dev, GFP_KERNEL, + "intel-hdmi-" + "hifi%d", i); + if (!idisp_components[i-1].dai_name) + goto devm_err; + + links[id].codecs = &idisp_components[i-1]; + links[id].num_codecs = 1; links[id].platforms = platform_component; links[id].num_platforms = ARRAY_SIZE(platform_component); links[id].init = sof_hdmi_init; @@ -355,6 +414,9 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev, } return links; + +devm_err: + return NULL; } static int sof_audio_probe(struct platform_device *pdev) @@ -388,6 +450,9 @@ static int sof_audio_probe(struct platform_device *pdev) dai_links = sof_card_dai_links_create(&pdev->dev, sof_rt5682_quirk & SOF_RT5682_SSP_MASK, dmic_num, hdmi_num); + if (!dai_links) + return -ENOMEM; + sof_audio_card_rt5682.dai_link = dai_links; sof_audio_card_rt5682.num_links = 1 + dmic_num + hdmi_num;