@@ -125,6 +125,24 @@ struct snd_soc_acpi_link_adr {
const struct snd_soc_acpi_adr_device *adr_d;
};
+/*
+ * when set the topology uses the -ssp<N> suffix, where N is determined based on
+ * BIOS or DMI information
+ */
+#define SND_SOC_ACPI_TPLG_INTEL_SSP_NUMBER BIT(0)
+
+/*
+ * when more than one SSP is reported in the link mask, use the most significant.
+ * This choice was found to be valid on platforms with ES8336 codecs.
+ */
+#define SND_SOC_ACPI_TPLG_INTEL_SSP_MSB BIT(1)
+
+/*
+ * when set the topology uses the -dmic<N>ch suffix, where N is determined based on
+ * BIOS or DMI information
+ */
+#define SND_SOC_ACPI_TPLG_INTEL_DMIC_NUMBER BIT(2)
+
/**
* snd_soc_acpi_mach: ACPI-based machine descriptor. Most of the fields are
* related to the hardware, except for the firmware and topology file names.
@@ -146,6 +164,7 @@ struct snd_soc_acpi_link_adr {
* @pdata: intended for platform data or machine specific-ops. This structure
* is not constant since this field may be updated at run-time
* @sof_tplg_filename: Sound Open Firmware topology file name, if enabled
+ * @tplg_quirk_mask: quirks to select different topology files dynamically
*/
/* Descriptor for SST ASoC machine driver */
struct snd_soc_acpi_mach {
@@ -161,6 +180,7 @@ struct snd_soc_acpi_mach {
void *pdata;
struct snd_soc_acpi_mach_params mach_params;
const char *sof_tplg_filename;
+ const u32 tplg_quirk_mask;
};
#define SND_SOC_ACPI_MAX_CODECS 3
@@ -80,7 +80,10 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_bxt_machines[] = {
{
.id = "ESSX8336",
.drv_name = "sof-essx8336",
- .sof_tplg_filename = "sof-apl-es8336.tplg",
+ .sof_tplg_filename = "sof-apl-es8336", /* the tplg suffix is added at run time */
+ .tplg_quirk_mask = SND_SOC_ACPI_TPLG_INTEL_SSP_NUMBER |
+ SND_SOC_ACPI_TPLG_INTEL_SSP_MSB |
+ SND_SOC_ACPI_TPLG_INTEL_DMIC_NUMBER,
},
{},
};
@@ -78,7 +78,10 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_cml_machines[] = {
{
.id = "ESSX8336",
.drv_name = "sof-essx8336",
- .sof_tplg_filename = "sof-cml-es8336.tplg",
+ .sof_tplg_filename = "sof-cml-es8336", /* the tplg suffix is added at run time */
+ .tplg_quirk_mask = SND_SOC_ACPI_TPLG_INTEL_SSP_NUMBER |
+ SND_SOC_ACPI_TPLG_INTEL_SSP_MSB |
+ SND_SOC_ACPI_TPLG_INTEL_DMIC_NUMBER,
},
{},
};
@@ -55,7 +55,10 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_glk_machines[] = {
{
.id = "ESSX8336",
.drv_name = "sof-essx8336",
- .sof_tplg_filename = "sof-glk-es8336.tplg",
+ .sof_tplg_filename = "sof-glk-es8336", /* the tplg suffix is added at run time */
+ .tplg_quirk_mask = SND_SOC_ACPI_TPLG_INTEL_SSP_NUMBER |
+ SND_SOC_ACPI_TPLG_INTEL_SSP_MSB |
+ SND_SOC_ACPI_TPLG_INTEL_DMIC_NUMBER,
},
{},
};
@@ -83,7 +83,10 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_jsl_machines[] = {
{
.id = "ESSX8336",
.drv_name = "sof-essx8336",
- .sof_tplg_filename = "sof-jsl-es8336.tplg",
+ .sof_tplg_filename = "sof-jsl-es8336", /* the tplg suffix is added at run time */
+ .tplg_quirk_mask = SND_SOC_ACPI_TPLG_INTEL_SSP_NUMBER |
+ SND_SOC_ACPI_TPLG_INTEL_SSP_MSB |
+ SND_SOC_ACPI_TPLG_INTEL_DMIC_NUMBER,
},
{},
};
@@ -393,7 +393,10 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_tgl_machines[] = {
{
.id = "ESSX8336",
.drv_name = "sof-essx8336",
- .sof_tplg_filename = "sof-tgl-es8336.tplg",
+ .sof_tplg_filename = "sof-tgl-es8336", /* the tplg suffix is added at run time */
+ .tplg_quirk_mask = SND_SOC_ACPI_TPLG_INTEL_SSP_NUMBER |
+ SND_SOC_ACPI_TPLG_INTEL_SSP_MSB |
+ SND_SOC_ACPI_TPLG_INTEL_DMIC_NUMBER,
},
{
.id = "10EC1308",
@@ -1393,9 +1393,12 @@ struct snd_soc_acpi_mach *hda_machine_select(struct snd_sof_dev *sdev)
struct snd_sof_pdata *sof_pdata = sdev->pdata;
const struct sof_dev_desc *desc = sof_pdata->desc;
struct snd_soc_acpi_mach *mach;
+ const char *tplg_filename;
mach = snd_soc_acpi_find_machine(desc->machines);
if (mach) {
+ bool add_extension = false;
+
/*
* If tplg file name is overridden, use it instead of
* the one set in mach table
@@ -1406,6 +1409,21 @@ 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 (mach->tplg_quirk_mask & SND_SOC_ACPI_TPLG_INTEL_DMIC_NUMBER &&
+ mach->mach_params.dmic_num) {
+ tplg_filename = devm_kasprintf(sdev->dev, GFP_KERNEL,
+ "%s%s%d%s",
+ sof_pdata->tplg_filename,
+ "-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) {
mach->mach_params.links = mach->links;
mach->mach_params.link_mask = mach->link_mask;
@@ -1413,6 +1431,40 @@ struct snd_soc_acpi_mach *hda_machine_select(struct snd_sof_dev *sdev)
/* report SSP link mask to machine driver */
mach->mach_params.i2s_link_mask = check_nhlt_ssp_mask(sdev);
+
+ if (mach->tplg_quirk_mask & SND_SOC_ACPI_TPLG_INTEL_SSP_NUMBER &&
+ mach->mach_params.i2s_link_mask) {
+ int ssp_num;
+
+ if (hweight_long(mach->mach_params.i2s_link_mask) > 1 &&
+ !(mach->tplg_quirk_mask & SND_SOC_ACPI_TPLG_INTEL_SSP_MSB))
+ dev_warn(sdev->dev, "More than one SSP exposed by NHLT, choosing MSB\n");
+
+ /* fls returns 1-based results, SSPs indices are 0-based */
+ ssp_num = fls(mach->mach_params.i2s_link_mask) - 1;
+
+ tplg_filename = devm_kasprintf(sdev->dev, GFP_KERNEL,
+ "%s%s%d",
+ sof_pdata->tplg_filename,
+ "-ssp",
+ ssp_num);
+ if (!tplg_filename)
+ return NULL;
+
+ sof_pdata->tplg_filename = tplg_filename;
+ add_extension = true;
+ }
+
+ if (add_extension) {
+ tplg_filename = devm_kasprintf(sdev->dev, GFP_KERNEL,
+ "%s%s",
+ sof_pdata->tplg_filename,
+ ".tplg");
+ if (!tplg_filename)
+ return NULL;
+
+ sof_pdata->tplg_filename = tplg_filename;
+ }
}
/*