diff options
author | Jaska Uimonen <jaska.uimonen@linux.intel.com> | 2021-03-26 19:51:50 +0300 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2021-03-29 19:28:19 +0300 |
commit | c943a586f6e49998b323afbd7f788afabf6ed89b (patch) | |
tree | 19b8cb86a570f248740fd09c74ec096caabad6d9 | |
parent | e12be9fbfb91173b3aa358466ce0474823be2695 (diff) | |
download | linux-c943a586f6e49998b323afbd7f788afabf6ed89b.tar.xz |
ASoC: SOF: match SSP config with pcm hw params
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@linux.intel.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Link: https://lore.kernel.org/r/20210326165150.255533-3-kai.vehmanen@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r-- | sound/soc/sof/pcm.c | 29 |
1 files changed, 29 insertions, 0 deletions
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 @@ capture: 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; |