summaryrefslogtreecommitdiff
path: root/sound/soc
diff options
context:
space:
mode:
authorMark Brown <broonie@kernel.org>2022-09-20 12:25:56 +0100
committerMark Brown <broonie@kernel.org>2022-09-20 12:25:56 +0100
commit3c193b5f530e32dfb4aeb845678ed30aa60b67c1 (patch)
tree3b02a26bdcb4476949129e7ea0c26e5c95655033 /sound/soc
parent78091edc1c7806846049e1d480f6a8051507ed94 (diff)
parentd9252772cdc811beedabbcf21ef856d09b87d1dd (diff)
downloadlinux-next-3c193b5f530e32dfb4aeb845678ed30aa60b67c1.tar.gz
ASoC: SOF: Intel: override mclk_id for ES8336 support
Merge series from Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>: This patchset solves a known issue with ES8336 platforms wrt MCLK selection. Most of the devices use the MCLK0 signal, but some devices do use the MCLK1 signal. The MCLK is defined in the topology, it would be a nightmare to generate more topology files just for one MCLK difference. With a minor extension to the intel-nhlt library, the MCLK information can be found by parsing the NHLT table, and we can override the mclk_id at boot time. The only known issues for this platform remain the detection of GPIO and microphone connections, currently only possible with manual quirks. Thanks to Eugene J. Markow for testing this patchset.
Diffstat (limited to 'sound/soc')
-rw-r--r--sound/soc/sof/intel/hda.c39
-rw-r--r--sound/soc/sof/intel/hda.h2
-rw-r--r--sound/soc/sof/intel/mtl.c2
-rw-r--r--sound/soc/sof/intel/tgl.c8
-rw-r--r--sound/soc/sof/ipc3-topology.c7
-rw-r--r--sound/soc/sof/sof-priv.h4
6 files changed, 57 insertions, 5 deletions
diff --git a/sound/soc/sof/intel/hda.c b/sound/soc/sof/intel/hda.c
index 79df990da1ea..eec54c8bb0e9 100644
--- a/sound/soc/sof/intel/hda.c
+++ b/sound/soc/sof/intel/hda.c
@@ -379,6 +379,10 @@ static int dmic_num_override = -1;
module_param_named(dmic_num, dmic_num_override, int, 0444);
MODULE_PARM_DESC(dmic_num, "SOF HDA DMIC number");
+static int mclk_id_override = -1;
+module_param_named(mclk_id, mclk_id_override, int, 0444);
+MODULE_PARM_DESC(mclk_id, "SOF SSP mclk_id");
+
#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
static bool hda_codec_use_common_hdmi = IS_ENABLED(CONFIG_SND_HDA_CODEC_HDMI);
module_param_named(use_common_hdmi, hda_codec_use_common_hdmi, bool, 0444);
@@ -752,6 +756,18 @@ static int check_nhlt_ssp_mask(struct snd_sof_dev *sdev)
return ssp_mask;
}
+static int check_nhlt_ssp_mclk_mask(struct snd_sof_dev *sdev, int ssp_num)
+{
+ struct sof_intel_hda_dev *hdev = sdev->pdata->hw_pdata;
+ struct nhlt_acpi_table *nhlt;
+
+ nhlt = hdev->nhlt;
+ if (!nhlt)
+ return 0;
+
+ return intel_nhlt_ssp_mclk_mask(nhlt, ssp_num);
+}
+
#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) || IS_ENABLED(CONFIG_SND_SOC_SOF_INTEL_SOUNDWIRE)
static const char *fixup_tplg_name(struct snd_sof_dev *sdev,
@@ -1540,6 +1556,7 @@ struct snd_soc_acpi_mach *hda_machine_select(struct snd_sof_dev *sdev)
mach->mach_params.i2s_link_mask) {
const struct sof_intel_dsp_desc *chip = get_chip_info(sdev->pdata);
int ssp_num;
+ int mclk_mask;
if (hweight_long(mach->mach_params.i2s_link_mask) > 1 &&
!(mach->tplg_quirk_mask & SND_SOC_ACPI_TPLG_INTEL_SSP_MSB))
@@ -1564,6 +1581,21 @@ struct snd_soc_acpi_mach *hda_machine_select(struct snd_sof_dev *sdev)
sof_pdata->tplg_filename = tplg_filename;
add_extension = true;
+
+ mclk_mask = check_nhlt_ssp_mclk_mask(sdev, ssp_num);
+
+ if (mclk_mask < 0) {
+ dev_err(sdev->dev, "Invalid MCLK configuration\n");
+ return NULL;
+ }
+
+ dev_dbg(sdev->dev, "MCLK mask %#x found in NHLT\n", mclk_mask);
+
+ if (mclk_mask) {
+ dev_info(sdev->dev, "Overriding topology with MCLK mask %#x from NHLT\n", mclk_mask);
+ sdev->mclk_id_override = true;
+ sdev->mclk_id_quirk = (mclk_mask & BIT(0)) ? 0 : 1;
+ }
}
if (tplg_fixup && add_extension) {
@@ -1576,6 +1608,13 @@ struct snd_soc_acpi_mach *hda_machine_select(struct snd_sof_dev *sdev)
sof_pdata->tplg_filename = tplg_filename;
}
+
+ /* check if mclk_id should be modified from topology defaults */
+ if (mclk_id_override >= 0) {
+ dev_info(sdev->dev, "Overriding topology with MCLK %d from kernel_parameter\n", mclk_id_override);
+ sdev->mclk_id_override = true;
+ sdev->mclk_id_quirk = mclk_id_override;
+ }
}
/*
diff --git a/sound/soc/sof/intel/hda.h b/sound/soc/sof/intel/hda.h
index ba6feb1b0d3b..bb9d2af06530 100644
--- a/sound/soc/sof/intel/hda.h
+++ b/sound/soc/sof/intel/hda.h
@@ -435,6 +435,8 @@
#define APL_SSP_COUNT 6
#define CNL_SSP_COUNT 3
#define ICL_SSP_COUNT 6
+#define TGL_SSP_COUNT 3
+#define MTL_SSP_COUNT 3
/* SSP Registers */
#define SSP_SSC1_OFFSET 0x4
diff --git a/sound/soc/sof/intel/mtl.c b/sound/soc/sof/intel/mtl.c
index 406d58804b50..5408c34b04ef 100644
--- a/sound/soc/sof/intel/mtl.c
+++ b/sound/soc/sof/intel/mtl.c
@@ -785,7 +785,7 @@ const struct sof_intel_dsp_desc mtl_chip_info = {
.ipc_ctl = MTL_DSP_REG_HFIPCXCTL,
.rom_status_reg = MTL_DSP_ROM_STS,
.rom_init_timeout = 300,
- .ssp_count = ICL_SSP_COUNT,
+ .ssp_count = MTL_SSP_COUNT,
.ssp_base_offset = CNL_SSP_BASE_OFFSET,
.sdw_shim_base = SDW_SHIM_BASE_ACE,
.sdw_alh_base = SDW_ALH_BASE_ACE,
diff --git a/sound/soc/sof/intel/tgl.c b/sound/soc/sof/intel/tgl.c
index 017bf331ed5a..5135e1c7e6cf 100644
--- a/sound/soc/sof/intel/tgl.c
+++ b/sound/soc/sof/intel/tgl.c
@@ -123,7 +123,7 @@ const struct sof_intel_dsp_desc tgl_chip_info = {
.ipc_ctl = CNL_DSP_REG_HIPCCTL,
.rom_status_reg = HDA_DSP_SRAM_REG_ROM_STATUS,
.rom_init_timeout = 300,
- .ssp_count = ICL_SSP_COUNT,
+ .ssp_count = TGL_SSP_COUNT,
.ssp_base_offset = CNL_SSP_BASE_OFFSET,
.sdw_shim_base = SDW_SHIM_BASE,
.sdw_alh_base = SDW_ALH_BASE,
@@ -146,7 +146,7 @@ const struct sof_intel_dsp_desc tglh_chip_info = {
.ipc_ctl = CNL_DSP_REG_HIPCCTL,
.rom_status_reg = HDA_DSP_SRAM_REG_ROM_STATUS,
.rom_init_timeout = 300,
- .ssp_count = ICL_SSP_COUNT,
+ .ssp_count = TGL_SSP_COUNT,
.ssp_base_offset = CNL_SSP_BASE_OFFSET,
.sdw_shim_base = SDW_SHIM_BASE,
.sdw_alh_base = SDW_ALH_BASE,
@@ -169,7 +169,7 @@ const struct sof_intel_dsp_desc ehl_chip_info = {
.ipc_ctl = CNL_DSP_REG_HIPCCTL,
.rom_status_reg = HDA_DSP_SRAM_REG_ROM_STATUS,
.rom_init_timeout = 300,
- .ssp_count = ICL_SSP_COUNT,
+ .ssp_count = TGL_SSP_COUNT,
.ssp_base_offset = CNL_SSP_BASE_OFFSET,
.sdw_shim_base = SDW_SHIM_BASE,
.sdw_alh_base = SDW_ALH_BASE,
@@ -192,7 +192,7 @@ const struct sof_intel_dsp_desc adls_chip_info = {
.ipc_ctl = CNL_DSP_REG_HIPCCTL,
.rom_status_reg = HDA_DSP_SRAM_REG_ROM_STATUS,
.rom_init_timeout = 300,
- .ssp_count = ICL_SSP_COUNT,
+ .ssp_count = TGL_SSP_COUNT,
.ssp_base_offset = CNL_SSP_BASE_OFFSET,
.sdw_shim_base = SDW_SHIM_BASE,
.sdw_alh_base = SDW_ALH_BASE,
diff --git a/sound/soc/sof/ipc3-topology.c b/sound/soc/sof/ipc3-topology.c
index 65923e7a5976..a39b43850f0e 100644
--- a/sound/soc/sof/ipc3-topology.c
+++ b/sound/soc/sof/ipc3-topology.c
@@ -1249,6 +1249,7 @@ static int sof_link_afe_load(struct snd_soc_component *scomp, struct snd_sof_dai
static int sof_link_ssp_load(struct snd_soc_component *scomp, struct snd_sof_dai_link *slink,
struct sof_ipc_dai_config *config, struct snd_sof_dai *dai)
{
+ struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
struct snd_soc_tplg_hw_config *hw_config = slink->hw_configs;
struct sof_dai_private_data *private = dai->private;
u32 size = sizeof(*config);
@@ -1273,6 +1274,12 @@ static int sof_link_ssp_load(struct snd_soc_component *scomp, struct snd_sof_dai
config[i].hdr.size = size;
+ if (sdev->mclk_id_override) {
+ dev_dbg(scomp->dev, "tplg: overriding topology mclk_id %d by quirk %d\n",
+ config[i].ssp.mclk_id, sdev->mclk_id_quirk);
+ config[i].ssp.mclk_id = sdev->mclk_id_quirk;
+ }
+
/* copy differentiating hw configs to ipc structs */
config[i].ssp.mclk_rate = le32_to_cpu(hw_config[i].mclk_rate);
config[i].ssp.bclk_rate = le32_to_cpu(hw_config[i].bclk_rate);
diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h
index 33165299a20f..de08825915b3 100644
--- a/sound/soc/sof/sof-priv.h
+++ b/sound/soc/sof/sof-priv.h
@@ -601,6 +601,10 @@ struct snd_sof_dev {
/* to protect the ipc_rx_handler_list and dsp_state_handler_list list */
struct mutex client_event_handler_mutex;
+ /* quirks to override topology values */
+ bool mclk_id_override;
+ u16 mclk_id_quirk; /* same size as in IPC3 definitions */
+
void *private; /* core does not touch this */
};