#include <sound/hda_register.h>
#include <linux/module.h>
+#include <sound/intel-nhlt.h>
#include <sound/sof.h>
#include <sound/sof/xtensa.h>
#include "../ops.h"
MODULE_PARM_DESC(use_msi, "SOF HDA use PCI MSI mode");
#endif
+#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
+static int hda_dmic_num = -1;
+module_param_named(dmic_num, hda_dmic_num, int, 0444);
+MODULE_PARM_DESC(dmic_num, "SOF HDA DMIC number");
+#endif
+
static const struct hda_dsp_msg_code hda_dsp_rom_msg[] = {
{HDA_DSP_ROM_FW_MANIFEST_LOADED, "status: manifest loaded"},
{HDA_DSP_ROM_FW_FW_LOADED, "status: fw loaded"},
#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
+static int check_nhlt_dmic(struct snd_sof_dev *sdev)
+{
+ struct nhlt_acpi_table *nhlt;
+ int dmic_num;
+
+ nhlt = intel_nhlt_init(sdev->dev);
+ if (nhlt) {
+ dmic_num = intel_nhlt_get_dmic_geo(sdev->dev, nhlt);
+ intel_nhlt_free(nhlt);
+ if (dmic_num == 2 || dmic_num == 4)
+ return dmic_num;
+ }
+
+ return 0;
+}
+
static const char *fixup_tplg_name(struct snd_sof_dev *sdev,
- const char *sof_tplg_filename)
+ const char *sof_tplg_filename,
+ const char *idisp_str,
+ const char *dmic_str)
{
const char *tplg_filename = NULL;
char *filename;
split_ext = strsep(&filename, ".");
if (split_ext) {
tplg_filename = devm_kasprintf(sdev->dev, GFP_KERNEL,
- "%s-idisp.tplg", split_ext);
+ "%s%s%s.tplg",
+ split_ext, idisp_str, dmic_str);
if (!tplg_filename)
return NULL;
}
struct snd_sof_pdata *pdata = sdev->pdata;
struct snd_soc_acpi_mach *mach;
const char *tplg_filename;
+ const char *idisp_str;
+ const char *dmic_str;
+ int dmic_num;
int codec_num = 0;
int i;
#endif
dev_info(bus->dev, "using HDA machine driver %s now\n",
hda_mach->drv_name);
- /* fixup topology file for HDMI only platforms */
- if (codec_num == 1) {
- /* use local variable for readability */
- tplg_filename = pdata->tplg_filename;
- tplg_filename = fixup_tplg_name(sdev, tplg_filename);
- if (!tplg_filename) {
- hda_codec_i915_exit(sdev);
- return ret;
- }
- pdata->tplg_filename = tplg_filename;
+ if (codec_num == 1)
+ idisp_str = "-idisp";
+ else
+ idisp_str = "";
+
+ /* first check NHLT for DMICs */
+ dmic_num = check_nhlt_dmic(sdev);
+
+ /* allow for module parameter override */
+ if (hda_dmic_num != -1)
+ dmic_num = hda_dmic_num;
+
+ switch (dmic_num) {
+ case 2:
+ dmic_str = "-2ch";
+ break;
+ case 4:
+ dmic_str = "-4ch";
+ break;
+ default:
+ dmic_num = 0;
+ dmic_str = "";
+ break;
+ }
+
+ tplg_filename = pdata->tplg_filename;
+ tplg_filename = fixup_tplg_name(sdev, tplg_filename,
+ idisp_str, dmic_str);
+ if (!tplg_filename) {
+ hda_codec_i915_exit(sdev);
+ return ret;
}
+ pdata->tplg_filename = tplg_filename;
}
}