diff --git a/sound/soc/intel/common/soc-acpi-intel-hda-match.c b/sound/soc/intel/common/soc-acpi-intel-hda-match.c index 2017fd0d676f1b..e93336e27bebd7 100644 --- a/sound/soc/intel/common/soc-acpi-intel-hda-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-hda-match.c @@ -8,27 +8,13 @@ #include #include -#include "../skylake/skl.h" - -static struct skl_machine_pdata hda_pdata = { - .use_tplg_pcm = true, -}; struct snd_soc_acpi_mach snd_soc_acpi_intel_hda_machines[] = { { /* .id is not used in this file */ .drv_name = "skl_hda_dsp_generic", - - /* .fw_filename is dynamically set in skylake driver */ - - .sof_tplg_filename = "sof-hda-generic.tplg", - - /* - * .machine_quirk and .quirk_data are not used here but - * can be used if we need a more complicated machine driver - * combining HDA+other device (e.g. DMIC). - */ - .pdata = &hda_pdata, + .sof_tplg_filename = "sof-hda-generic", /* the tplg suffix is added at run time */ + .tplg_quirk_mask = SND_SOC_ACPI_TPLG_INTEL_DMIC_NUMBER, }, {}, }; diff --git a/sound/soc/intel/skylake/skl.c b/sound/soc/intel/skylake/skl.c index 11712518779324..96c71c9a2681fb 100644 --- a/sound/soc/intel/skylake/skl.c +++ b/sound/soc/intel/skylake/skl.c @@ -471,20 +471,6 @@ static struct skl_ssp_clk skl_ssp_clks[] = { {.name = "ssp5_sclkfs"}, }; -static struct snd_soc_acpi_mach *skl_find_hda_machine(struct skl_dev *skl, - struct snd_soc_acpi_mach *machines) -{ - struct snd_soc_acpi_mach *mach; - - /* point to common table */ - mach = snd_soc_acpi_intel_hda_machines; - - /* all entries in the machine table use the same firmware */ - mach->fw_filename = machines->fw_filename; - - return mach; -} - static int skl_find_machine(struct skl_dev *skl, void *driver_data) { struct hdac_bus *bus = skl_to_bus(skl); @@ -493,12 +479,8 @@ static int skl_find_machine(struct skl_dev *skl, void *driver_data) mach = snd_soc_acpi_find_machine(mach); if (!mach) { - dev_dbg(bus->dev, "No matching I2S machine driver found\n"); - mach = skl_find_hda_machine(skl, driver_data); - if (!mach) { - dev_err(bus->dev, "No matching machine driver found\n"); - return -ENODEV; - } + dev_err(bus->dev, "No matching I2S machine driver found\n"); + return -ENODEV; } skl->mach = mach; diff --git a/sound/soc/sof/intel/hda.c b/sound/soc/sof/intel/hda.c index 7a63818d507b3a..b98b8c41dc0802 100644 --- a/sound/soc/sof/intel/hda.c +++ b/sound/soc/sof/intel/hda.c @@ -511,6 +511,8 @@ static int check_dmic_num(struct snd_sof_dev *sdev) if (nhlt) dmic_num = intel_nhlt_get_dmic_geo(sdev->dev, nhlt); + dev_info(sdev->dev, "DMICs detected in NHLT tables: %d\n", dmic_num); + /* allow for module parameter override */ if (dmic_num_override != -1) { dev_dbg(sdev->dev, @@ -558,82 +560,6 @@ static int check_nhlt_ssp_mclk_mask(struct snd_sof_dev *sdev, int ssp_num) return intel_nhlt_ssp_mclk_mask(nhlt, ssp_num); } -#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC) || IS_ENABLED(CONFIG_SND_SOC_SOF_INTEL_SOUNDWIRE) - -static const char *fixup_tplg_name(struct snd_sof_dev *sdev, - const char *sof_tplg_filename, - const char *idisp_str, - const char *dmic_str) -{ - const char *tplg_filename = NULL; - char *filename, *tmp; - const char *split_ext; - - filename = kstrdup(sof_tplg_filename, GFP_KERNEL); - if (!filename) - return NULL; - - /* this assumes a .tplg extension */ - tmp = filename; - split_ext = strsep(&tmp, "."); - if (split_ext) - tplg_filename = devm_kasprintf(sdev->dev, GFP_KERNEL, - "%s%s%s.tplg", - split_ext, idisp_str, dmic_str); - kfree(filename); - - return tplg_filename; -} - -static int dmic_detect_topology_fixup(struct snd_sof_dev *sdev, - const char **tplg_filename, - const char *idisp_str, - int *dmic_found, - bool tplg_fixup) -{ - const char *dmic_str; - int dmic_num; - - /* first check for DMICs (using NHLT or module parameter) */ - dmic_num = check_dmic_num(sdev); - - switch (dmic_num) { - case 1: - dmic_str = "-1ch"; - break; - case 2: - dmic_str = "-2ch"; - break; - case 3: - dmic_str = "-3ch"; - break; - case 4: - dmic_str = "-4ch"; - break; - default: - dmic_num = 0; - dmic_str = ""; - break; - } - - if (tplg_fixup) { - const char *default_tplg_filename = *tplg_filename; - const char *fixed_tplg_filename; - - fixed_tplg_filename = fixup_tplg_name(sdev, default_tplg_filename, - idisp_str, dmic_str); - if (!fixed_tplg_filename) - return -ENOMEM; - *tplg_filename = fixed_tplg_filename; - } - - dev_info(sdev->dev, "DMICs detected in NHLT tables: %d\n", dmic_num); - *dmic_found = dmic_num; - - return 0; -} -#endif - static int hda_init_caps(struct snd_sof_dev *sdev) { u32 interface_mask = hda_get_interface_mask(sdev); @@ -1043,10 +969,7 @@ static void hda_generic_machine_select(struct snd_sof_dev *sdev, struct snd_soc_acpi_mach *hda_mach; struct snd_sof_pdata *pdata = sdev->pdata; const char *tplg_filename; - const char *idisp_str; - int dmic_num = 0; int codec_num = 0; - int ret; int i; /* codec detection */ @@ -1069,33 +992,30 @@ static void hda_generic_machine_select(struct snd_sof_dev *sdev, * - one external HDAudio codec */ if (!*mach && codec_num <= 2) { - bool tplg_fixup; + bool tplg_fixup = false; hda_mach = snd_soc_acpi_intel_hda_machines; dev_info(bus->dev, "using HDA machine driver %s now\n", hda_mach->drv_name); - if (codec_num == 1 && HDA_IDISP_CODEC(bus->codec_mask)) - idisp_str = "-idisp"; - else - idisp_str = ""; - - /* topology: use the info from hda_machines */ - if (pdata->tplg_filename) { - tplg_fixup = false; - tplg_filename = pdata->tplg_filename; - } else { + /* + * topology: use the info from hda_machines since tplg file name + * is not overwritten + */ + if (!pdata->tplg_filename) tplg_fixup = true; - tplg_filename = hda_mach->sof_tplg_filename; - } - ret = dmic_detect_topology_fixup(sdev, &tplg_filename, idisp_str, &dmic_num, - tplg_fixup); - if (ret < 0) - return; - hda_mach->mach_params.dmic_num = dmic_num; - pdata->tplg_filename = tplg_filename; + if (tplg_fixup && + codec_num == 1 && HDA_IDISP_CODEC(bus->codec_mask)) { + tplg_filename = devm_kasprintf(sdev->dev, GFP_KERNEL, + "%s-idisp", + hda_mach->sof_tplg_filename); + if (!tplg_filename) + return; + + hda_mach->sof_tplg_filename = tplg_filename; + } if (codec_num == 2 || (codec_num == 1 && !HDA_IDISP_CODEC(bus->codec_mask))) { @@ -1203,45 +1123,10 @@ static struct snd_soc_acpi_mach *hda_sdw_machine_select(struct snd_sof_dev *sdev break; } if (mach && mach->link_mask) { - int dmic_num = 0; - bool tplg_fixup; - const char *tplg_filename; - mach->mach_params.links = mach->links; mach->mach_params.link_mask = mach->link_mask; mach->mach_params.platform = dev_name(sdev->dev); - if (pdata->tplg_filename) { - tplg_fixup = false; - } else { - tplg_fixup = true; - tplg_filename = mach->sof_tplg_filename; - } - - /* - * DMICs use up to 4 pins and are typically pin-muxed with SoundWire - * link 2 and 3, or link 1 and 2, thus we only try to enable dmics - * if all conditions are true: - * a) 2 or fewer links are used by SoundWire - * b) the NHLT table reports the presence of microphones - */ - if (hweight_long(mach->link_mask) <= 2) { - int ret; - - ret = dmic_detect_topology_fixup(sdev, &tplg_filename, "", - &dmic_num, tplg_fixup); - if (ret < 0) - return NULL; - } - if (tplg_fixup) - pdata->tplg_filename = tplg_filename; - mach->mach_params.dmic_num = dmic_num; - - dev_dbg(sdev->dev, - "SoundWire machine driver %s topology %s\n", - mach->drv_name, - pdata->tplg_filename); - return mach; } @@ -1298,6 +1183,19 @@ static int check_tplg_quirk_mask(struct snd_soc_acpi_mach *mach) return 0; } +static char *remove_file_ext(const char *tplg_filename) +{ + char *filename, *tmp; + + filename = kstrdup(tplg_filename, GFP_KERNEL); + if (!filename) + return NULL; + + /* remove file extension if exist */ + tmp = filename; + return strsep(&tmp, "."); +} + struct snd_soc_acpi_mach *hda_machine_select(struct snd_sof_dev *sdev) { u32 interface_mask = hda_get_interface_mask(sdev); @@ -1309,21 +1207,54 @@ struct snd_soc_acpi_mach *hda_machine_select(struct snd_sof_dev *sdev) const char *tplg_filename; const char *tplg_suffix; bool amp_name_valid; + bool i2s_mach_found = false; + bool sdw_mach_found = false; /* Try I2S or DMIC if it is supported */ - if (interface_mask & (BIT(SOF_DAI_INTEL_SSP) | BIT(SOF_DAI_INTEL_DMIC))) + if (interface_mask & (BIT(SOF_DAI_INTEL_SSP) | BIT(SOF_DAI_INTEL_DMIC))) { mach = snd_soc_acpi_find_machine(desc->machines); + if (mach) + i2s_mach_found = true; + } + /* + * If I2S fails and no external HDaudio codec is detected, + * try SoundWire if it is supported + */ + if (!mach && !HDA_EXT_CODEC(bus->codec_mask) && + (interface_mask & BIT(SOF_DAI_INTEL_ALH))) { + mach = hda_sdw_machine_select(sdev); + if (mach) + sdw_mach_found = true; + } + + /* + * Choose HDA generic machine driver if mach is NULL. + * Otherwise, set certain mach params. + */ + hda_generic_machine_select(sdev, &mach); + if (!mach) + dev_warn(sdev->dev, "warning: No matching ASoC machine driver found\n"); + + /* + * Fixup tplg file name by appending dmic num, ssp num, codec/amplifier + * name string if quirk flag is set. + */ if (mach) { - bool add_extension = false; bool tplg_fixup = false; + bool dmic_fixup = false; /* * If tplg file name is overridden, use it instead of * the one set in mach table */ if (!sof_pdata->tplg_filename) { - sof_pdata->tplg_filename = mach->sof_tplg_filename; + /* remove file extension if it exists */ + tplg_filename = remove_file_ext(mach->sof_tplg_filename); + if (!tplg_filename) + return NULL; + + sof_pdata->tplg_filename = tplg_filename; tplg_fixup = true; } @@ -1341,20 +1272,34 @@ struct snd_soc_acpi_mach *hda_machine_select(struct snd_sof_dev *sdev) /* report to machine driver if any DMICs are found */ mach->mach_params.dmic_num = check_dmic_num(sdev); + if (sdw_mach_found) { + /* + * DMICs use up to 4 pins and are typically pin-muxed with SoundWire + * link 2 and 3, or link 1 and 2, thus we only try to enable dmics + * if all conditions are true: + * a) 2 or fewer links are used by SoundWire + * b) the NHLT table reports the presence of microphones + */ + if (hweight_long(mach->link_mask) <= 2) + dmic_fixup = true; + } else { + if (mach->tplg_quirk_mask & SND_SOC_ACPI_TPLG_INTEL_DMIC_NUMBER) + dmic_fixup = true; + } + if (tplg_fixup && - mach->tplg_quirk_mask & SND_SOC_ACPI_TPLG_INTEL_DMIC_NUMBER && + dmic_fixup && mach->mach_params.dmic_num) { tplg_filename = devm_kasprintf(sdev->dev, GFP_KERNEL, "%s%s%d%s", sof_pdata->tplg_filename, - "-dmic", + i2s_mach_found ? "-dmic" : "-", mach->mach_params.dmic_num, "ch"); if (!tplg_filename) return NULL; sof_pdata->tplg_filename = tplg_filename; - add_extension = true; } if (mach->link_mask) { @@ -1394,7 +1339,6 @@ struct snd_soc_acpi_mach *hda_machine_select(struct snd_sof_dev *sdev) return NULL; sof_pdata->tplg_filename = tplg_filename; - add_extension = true; mclk_mask = check_nhlt_ssp_mclk_mask(sdev, ssp_num); @@ -1433,7 +1377,6 @@ struct snd_soc_acpi_mach *hda_machine_select(struct snd_sof_dev *sdev) return NULL; sof_pdata->tplg_filename = tplg_filename; - add_extension = true; } @@ -1455,10 +1398,9 @@ struct snd_soc_acpi_mach *hda_machine_select(struct snd_sof_dev *sdev) return NULL; sof_pdata->tplg_filename = tplg_filename; - add_extension = true; } - if (tplg_fixup && add_extension) { + if (tplg_fixup) { tplg_filename = devm_kasprintf(sdev->dev, GFP_KERNEL, "%s%s", sof_pdata->tplg_filename, @@ -1477,22 +1419,6 @@ struct snd_soc_acpi_mach *hda_machine_select(struct snd_sof_dev *sdev) } } - /* - * If I2S fails and no external HDaudio codec is detected, - * try SoundWire if it is supported - */ - if (!mach && !HDA_EXT_CODEC(bus->codec_mask) && - (interface_mask & BIT(SOF_DAI_INTEL_ALH))) - mach = hda_sdw_machine_select(sdev); - - /* - * Choose HDA generic machine driver if mach is NULL. - * Otherwise, set certain mach params. - */ - hda_generic_machine_select(sdev, &mach); - if (!mach) - dev_warn(sdev->dev, "warning: No matching ASoC machine driver found\n"); - return mach; }