From 1f891055c7d0ce665247c09e97db927f2db37ce7 Mon Sep 17 00:00:00 2001 From: Bard Liao Date: Fri, 17 Jul 2020 16:13:32 -0500 Subject: ASoC: Intel: sof_sdw_rt711: remove hard-coded codec name We can get codec name from dai link. Suggested-by: Rander Wang Signed-off-by: Bard Liao Signed-off-by: Pierre-Louis Bossart Reviewed-by: Kai Vehmanen Link: https://lore.kernel.org/r/20200717211337.31956-2-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/sof_sdw_rt711.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/intel/boards/sof_sdw_rt711.c b/sound/soc/intel/boards/sof_sdw_rt711.c index d4d75c8dc6b7..c8f84e9a3e4e 100644 --- a/sound/soc/intel/boards/sof_sdw_rt711.c +++ b/sound/soc/intel/boards/sof_sdw_rt711.c @@ -147,7 +147,7 @@ int sof_sdw_rt711_init(const struct snd_soc_acpi_link_adr *link, if (!playback) return 0; - ret = rt711_add_codec_device_props("sdw:0:25d:711:0"); + ret = rt711_add_codec_device_props(dai_links->codecs[0].name); if (ret < 0) return ret; -- cgit From cf0418cd06ce42fcf35beb33e315b5a77e596926 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Fri, 17 Jul 2020 16:13:33 -0500 Subject: ASoC: Intel: sof_sdw_rt711: remove properties in card remove The rt711 jack detection properties are set from the machine drivers during the card probe, as done in other ASoC examples. KASAN reports a use-after-free error when unbinding drivers due to a confusing sequence between the ACPI core, the device core and the SoundWire device cleanups. Rather than fixing this sequence, follow the recommendation to have the same caller add and remove properties, add an explicit device_remove_properties() in the card .remove() callback. In future patches the use of device_add/remove_properties will be replaced by a direct handling of a swnode, but the sequence will remain the same. Signed-off-by: Bard Liao Signed-off-by: Pierre-Louis Bossart Reviewed-by: Kai Vehmanen Link: https://lore.kernel.org/r/20200717211337.31956-3-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/sof_sdw.c | 1 + sound/soc/intel/boards/sof_sdw_common.h | 1 + sound/soc/intel/boards/sof_sdw_rt711.c | 15 +++++++++++++++ 3 files changed, 17 insertions(+) diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c index be8eccb50450..9b6059905dbe 100644 --- a/sound/soc/intel/boards/sof_sdw.c +++ b/sound/soc/intel/boards/sof_sdw.c @@ -217,6 +217,7 @@ static struct sof_sdw_codec_info codec_info_list[] = { .direction = {true, true}, .dai_name = "rt711-aif1", .init = sof_sdw_rt711_init, + .exit = sof_sdw_rt711_exit, }, { .id = 0x1308, diff --git a/sound/soc/intel/boards/sof_sdw_common.h b/sound/soc/intel/boards/sof_sdw_common.h index 426017626b16..c64c5d801d26 100644 --- a/sound/soc/intel/boards/sof_sdw_common.h +++ b/sound/soc/intel/boards/sof_sdw_common.h @@ -91,6 +91,7 @@ int sof_sdw_rt711_init(const struct snd_soc_acpi_link_adr *link, struct snd_soc_dai_link *dai_links, struct sof_sdw_codec_info *info, bool playback); +int sof_sdw_rt711_exit(struct device *dev, struct snd_soc_dai_link *dai_link); /* RT700 support */ int sof_sdw_rt700_init(const struct snd_soc_acpi_link_adr *link, diff --git a/sound/soc/intel/boards/sof_sdw_rt711.c b/sound/soc/intel/boards/sof_sdw_rt711.c index c8f84e9a3e4e..606009fa3901 100644 --- a/sound/soc/intel/boards/sof_sdw_rt711.c +++ b/sound/soc/intel/boards/sof_sdw_rt711.c @@ -133,6 +133,21 @@ static int rt711_rtd_init(struct snd_soc_pcm_runtime *rtd) return ret; } +int sof_sdw_rt711_exit(struct device *dev, struct snd_soc_dai_link *dai_link) +{ + struct device *sdw_dev; + + sdw_dev = bus_find_device_by_name(&sdw_bus_type, NULL, + dai_link->codecs[0].name); + if (!sdw_dev) + return -EINVAL; + + device_remove_properties(sdw_dev); + put_device(sdw_dev); + + return 0; +} + int sof_sdw_rt711_init(const struct snd_soc_acpi_link_adr *link, struct snd_soc_dai_link *dai_links, struct sof_sdw_codec_info *info, -- cgit From 15ef2ea035db7bcb9a9d0bf3747fbb7dde67dd97 Mon Sep 17 00:00:00 2001 From: Kai Vehmanen Date: Fri, 17 Jul 2020 16:13:34 -0500 Subject: ASoC: Intel: sof_sdw: add support for systems without i915 audio Extend the generic SOF Soundwire machine driver to support systems where iDisp HDMI/DP audio codec is disabled for some reason (i915 driver disabled, HDMI/DP implemented with a discrete GPU, etc). Switch codecs to SoC dummy in the affected DAI links. This allows to reuse existing topologies for this case. Signed-off-by: Kai Vehmanen Signed-off-by: Pierre-Louis Bossart Reviewed-by: Guennadi Liakhovetski Reviewed-by: Rander Wang Link: https://lore.kernel.org/r/20200717211337.31956-4-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/sof_sdw.c | 30 ++++++++++++++++++++---------- sound/soc/intel/boards/sof_sdw_common.h | 1 + sound/soc/intel/boards/sof_sdw_hdmi.c | 3 +++ 3 files changed, 24 insertions(+), 10 deletions(-) diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c index 9b6059905dbe..2463d432bf4d 100644 --- a/sound/soc/intel/boards/sof_sdw.c +++ b/sound/soc/intel/boards/sof_sdw.c @@ -699,11 +699,14 @@ static inline int get_next_be_id(struct snd_soc_dai_link *links, return links[be_id - 1].id + 1; } +#define IDISP_CODEC_MASK 0x4 + static int sof_card_dai_links_create(struct device *dev, struct snd_soc_acpi_mach *mach, struct snd_soc_card *card) { int ssp_num, sdw_be_num = 0, hdmi_num = 0, dmic_num; + struct mc_private *ctx = snd_soc_card_get_drvdata(card); struct snd_soc_dai_link_component *idisp_components; struct snd_soc_dai_link_component *ssp_components; struct snd_soc_acpi_mach_params *mach_params; @@ -747,12 +750,15 @@ static int sof_card_dai_links_create(struct device *dev, return ret; } + if (mach_params->codec_mask & IDISP_CODEC_MASK) + ctx->idisp_codec = true; + /* enable dmic01 & dmic16k */ dmic_num = (sof_sdw_quirk & SOF_SDW_PCH_DMIC) ? 2 : 0; comp_num += dmic_num; dev_dbg(dev, "sdw %d, ssp %d, dmic %d, hdmi %d", sdw_be_num, ssp_num, - dmic_num, hdmi_num); + dmic_num, ctx->idisp_codec ? hdmi_num : 0); /* allocate BE dailinks */ num_links = comp_num + sdw_be_num; @@ -901,13 +907,18 @@ DMIC: if (!name) return -ENOMEM; - idisp_components[i].name = "ehdaudio0D2"; - idisp_components[i].dai_name = devm_kasprintf(dev, - GFP_KERNEL, - "intel-hdmi-hifi%d", - i + 1); - if (!idisp_components[i].dai_name) - return -ENOMEM; + if (ctx->idisp_codec) { + idisp_components[i].name = "ehdaudio0D2"; + idisp_components[i].dai_name = devm_kasprintf(dev, + GFP_KERNEL, + "intel-hdmi-hifi%d", + i + 1); + if (!idisp_components[i].dai_name) + return -ENOMEM; + } else { + idisp_components[i].name = "snd-soc-dummy"; + idisp_components[i].dai_name = "snd-soc-dummy-dai"; + } cpu_name = devm_kasprintf(dev, GFP_KERNEL, "iDisp%d Pin", i + 1); @@ -982,6 +993,7 @@ static int mc_probe(struct platform_device *pdev) INIT_LIST_HEAD(&ctx->hdmi_pcm_list); card->dev = &pdev->dev; + snd_soc_card_set_drvdata(card, ctx); mach = pdev->dev.platform_data; ret = sof_card_dai_links_create(&pdev->dev, mach, @@ -991,8 +1003,6 @@ static int mc_probe(struct platform_device *pdev) ctx->common_hdmi_codec_drv = mach->mach_params.common_hdmi_codec_drv; - snd_soc_card_set_drvdata(card, ctx); - /* * the default amp_num is zero for each codec and * amp_num will only be increased for active amp diff --git a/sound/soc/intel/boards/sof_sdw_common.h b/sound/soc/intel/boards/sof_sdw_common.h index c64c5d801d26..12e32439ba46 100644 --- a/sound/soc/intel/boards/sof_sdw_common.h +++ b/sound/soc/intel/boards/sof_sdw_common.h @@ -70,6 +70,7 @@ struct sof_sdw_codec_info { struct mc_private { struct list_head hdmi_pcm_list; bool common_hdmi_codec_drv; + bool idisp_codec; struct snd_soc_jack sdw_headset; }; diff --git a/sound/soc/intel/boards/sof_sdw_hdmi.c b/sound/soc/intel/boards/sof_sdw_hdmi.c index 0654b38a7e0d..72316d34eed6 100644 --- a/sound/soc/intel/boards/sof_sdw_hdmi.c +++ b/sound/soc/intel/boards/sof_sdw_hdmi.c @@ -52,6 +52,9 @@ int sof_sdw_hdmi_card_late_probe(struct snd_soc_card *card) int err, i = 0; char jack_name[NAME_SIZE]; + if (!ctx->idisp_codec) + return 0; + pcm = list_first_entry(&ctx->hdmi_pcm_list, struct hdmi_pcm, head); component = pcm->codec_dai->component; -- cgit From 6b540ac763e9d11506ec1eb6b0fadc70292bb4a6 Mon Sep 17 00:00:00 2001 From: Kai Vehmanen Date: Fri, 17 Jul 2020 16:13:35 -0500 Subject: ASoC: Intel: sof_sdw: avoid crash if invalid DSP topology loaded The mc_private->hdmi_pcm_list is populated by elements loaded during DSP topology load. Valid topologies for this machine driver will always have PCM nodes for HDMI, but driver should fail gracefully even in the case this is not true. Add a sanity check to sof_sdw_hdmi_card_late_probe() for this case. Without the fix, a null pcm handle gets dereferenced. Signed-off-by: Kai Vehmanen Signed-off-by: Pierre-Louis Bossart Reviewed-by: Guennadi Liakhovetski Reviewed-by: Rander Wang Link: https://lore.kernel.org/r/20200717211337.31956-5-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/sof_sdw_hdmi.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sound/soc/intel/boards/sof_sdw_hdmi.c b/sound/soc/intel/boards/sof_sdw_hdmi.c index 72316d34eed6..99b04bb2f3a0 100644 --- a/sound/soc/intel/boards/sof_sdw_hdmi.c +++ b/sound/soc/intel/boards/sof_sdw_hdmi.c @@ -55,6 +55,9 @@ int sof_sdw_hdmi_card_late_probe(struct snd_soc_card *card) if (!ctx->idisp_codec) return 0; + if (list_empty(&ctx->hdmi_pcm_list)) + return -EINVAL; + pcm = list_first_entry(&ctx->hdmi_pcm_list, struct hdmi_pcm, head); component = pcm->codec_dai->component; -- cgit From 0d95d06a7aae38f3bd61582e00f0cc06b35ca0ab Mon Sep 17 00:00:00 2001 From: Yong Zhi Date: Fri, 17 Jul 2020 16:13:36 -0500 Subject: ASoC: intel: board: sof_rt5682: Update rt1015 pll input clk freq In commit d696a61413b4 ("ASoC: rt1015: Add condition to prevent SoC providing bclk in ratio of 50 times of sample rate."), PLL input at 50fs is no longer supported, the new recommended settings at 48Khz rate are: PLL input SSP bclk ------------------------ 64fs 3.073Mhz 100fs 4.8Mhz (bclk update is reflected in topoplogy.) Signed-off-by: Yong Zhi Signed-off-by: Pierre-Louis Bossart Reviewed-by: Kai Vehmanen Link: https://lore.kernel.org/r/20200717211337.31956-6-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/sof_rt5682.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/sound/soc/intel/boards/sof_rt5682.c b/sound/soc/intel/boards/sof_rt5682.c index cc8b0f26f724..61a61dcca82a 100644 --- a/sound/soc/intel/boards/sof_rt5682.c +++ b/sound/soc/intel/boards/sof_rt5682.c @@ -284,8 +284,15 @@ static int sof_rt1015_hw_params(struct snd_pcm_substream *substream, return 0; for_each_rtd_codec_dais(rtd, i, codec_dai) { + /* Set tdm/i2s1 master bclk ratio */ + ret = snd_soc_dai_set_bclk_ratio(codec_dai, 64); + if (ret < 0) { + dev_err(card->dev, "failed to set bclk ratio\n"); + return ret; + } + ret = snd_soc_dai_set_pll(codec_dai, 0, RT1015_PLL_S_BCLK, - params_rate(params) * 50, + params_rate(params) * 64, params_rate(params) * 256); if (ret < 0) { dev_err(card->dev, "failed to set pll\n"); -- cgit