[PATCH 3/3] ASoC: SOF: match SSP config with pcm hw params

Kai Vehmanen kai.vehmanen at linux.intel.com
Fri Mar 26 17:51:50 CET 2021


From: Jaska Uimonen <jaska.uimonen at linux.intel.com>

This patch adds a function to find a match between pcm hw params and SSP
DAI config. Config is matched against sample rate and if match is found
current config is set. If match isn't found last matched config is left
as current i.e. current config is not touched. Functionality for SSP
DAIs with 1 config remains the same as before.

Signed-off-by: Jaska Uimonen <jaska.uimonen at linux.intel.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan at linux.intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart at linux.intel.com>
Reviewed-by: Guennadi Liakhovetski <guennadi.liakhovetski at linux.intel.com>
Signed-off-by: Kai Vehmanen <kai.vehmanen at linux.intel.com>
---
 sound/soc/sof/pcm.c | 29 +++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)

diff --git a/sound/soc/sof/pcm.c b/sound/soc/sof/pcm.c
index c3dc533f2627..d6b1c8b7bdfb 100644
--- a/sound/soc/sof/pcm.c
+++ b/sound/soc/sof/pcm.c
@@ -619,6 +619,31 @@ static int sof_pcm_new(struct snd_soc_component *component,
 	return 0;
 }
 
+static void ssp_dai_config_pcm_params_match(struct snd_sof_dev *sdev, const char *link_name,
+					    struct snd_pcm_hw_params *params)
+{
+	struct sof_ipc_dai_config *config;
+	struct snd_sof_dai *dai;
+	int i;
+
+	/*
+	 * Search for all matching DAIs as we can have both playback and capture DAI
+	 * associated with the same link.
+	 */
+	list_for_each_entry(dai, &sdev->dai_list, list) {
+		if (!dai->name || strcmp(link_name, dai->name))
+			continue;
+		for (i = 0; i < dai->number_configs; i++) {
+			config = &dai->dai_config[i];
+			if (config->ssp.fsync_rate == params_rate(params)) {
+				dev_dbg(sdev->dev, "DAI config %d matches pcm hw params\n", i);
+				dai->current_config = i;
+				break;
+			}
+		}
+	}
+}
+
 /* fixup the BE DAI link to match any values from topology */
 int sof_pcm_dai_link_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_params *params)
 {
@@ -631,6 +656,7 @@ int sof_pcm_dai_link_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_pa
 		snd_soc_rtdcom_lookup(rtd, SOF_AUDIO_PCM_DRV_NAME);
 	struct snd_sof_dai *dai =
 		snd_sof_find_dai(component, (char *)rtd->dai_link->name);
+	struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component);
 	struct snd_soc_dpcm *dpcm;
 
 	/* no topology exists for this BE, try a common configuration */
@@ -673,6 +699,9 @@ int sof_pcm_dai_link_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_pa
 	/* read rate and channels from topology */
 	switch (dai->dai_config->type) {
 	case SOF_DAI_INTEL_SSP:
+		/* search for config to pcm params match, if not found use default */
+		ssp_dai_config_pcm_params_match(sdev, (char *)rtd->dai_link->name, params);
+
 		rate->min = dai->dai_config[dai->current_config].ssp.fsync_rate;
 		rate->max = dai->dai_config[dai->current_config].ssp.fsync_rate;
 		channels->min = dai->dai_config[dai->current_config].ssp.tdm_slots;
-- 
2.31.0



More information about the Alsa-devel mailing list