summaryrefslogtreecommitdiff
path: root/sound/soc/sof/intel/hda.c
diff options
context:
space:
mode:
authorPierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>2019-08-12 19:06:23 +0300
committerMark Brown <broonie@kernel.org>2019-08-12 20:40:54 +0300
commit68b953aeb50d9206de27d6c216e301f01dfac34d (patch)
treeeef0013c2017cbe94d520a49c87428b9a535a5af /sound/soc/sof/intel/hda.c
parent6fa4e0cae684d268d309d1b1f929d52e3df5649c (diff)
downloadlinux-68b953aeb50d9206de27d6c216e301f01dfac34d.tar.xz
ASoC: SOF: Intel: hda: fixup HDaudio topology name with DMIC number
The SOF project maintains 6 topologies for HDaudio (iDisp or HDaudio+iDisp, no DMIC, 2 DMICs, 4 DMICs). The user is currently required to manually rename the topology file used in /lib/firmware/intel/sof-tplg. We can do better to avoid such renames and use logic to select the relevant file. The NHLT information can be used to figure out which topology file should be used. Alternatively, when NHLT is not present in ACPI tables or is possibly incorrect, a module parameter can provide that information, e.g. on Up^2 board with the test DMIC kit. Tested on Up^2 board and Acer Swift-SF314-55 Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Link: https://lore.kernel.org/r/20190812160623.20821-1-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound/soc/sof/intel/hda.c')
-rw-r--r--sound/soc/sof/intel/hda.c75
1 files changed, 63 insertions, 12 deletions
diff --git a/sound/soc/sof/intel/hda.c b/sound/soc/sof/intel/hda.c
index 28eb780494aa..c97c004afa43 100644
--- a/sound/soc/sof/intel/hda.c
+++ b/sound/soc/sof/intel/hda.c
@@ -19,6 +19,7 @@
#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"
@@ -49,6 +50,12 @@ module_param_named(use_msi, hda_use_msi, bool, 0444);
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"},
@@ -283,8 +290,26 @@ static int hda_init(struct snd_sof_dev *sdev)
#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;
@@ -298,7 +323,8 @@ static const char *fixup_tplg_name(struct snd_sof_dev *sdev,
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;
}
@@ -317,6 +343,9 @@ static int hda_init_caps(struct snd_sof_dev *sdev)
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
@@ -381,17 +410,39 @@ static int hda_init_caps(struct snd_sof_dev *sdev)
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;
}
}