summaryrefslogtreecommitdiffstats
path: root/sound/soc/sof/pcm.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/sof/pcm.c')
-rw-r--r--sound/soc/sof/pcm.c38
1 files changed, 34 insertions, 4 deletions
diff --git a/sound/soc/sof/pcm.c b/sound/soc/sof/pcm.c
index 61c3fe17342d..9893b182da43 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,10 +699,13 @@ 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:
- rate->min = dai->dai_config->ssp.fsync_rate;
- rate->max = dai->dai_config->ssp.fsync_rate;
- channels->min = dai->dai_config->ssp.tdm_slots;
- channels->max = dai->dai_config->ssp.tdm_slots;
+ /* 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;
+ channels->max = dai->dai_config[dai->current_config].ssp.tdm_slots;
dev_dbg(component->dev,
"rate_min: %d rate_max: %d\n", rate->min, rate->max);
@@ -746,6 +775,7 @@ int sof_pcm_dai_link_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_pa
return 0;
}
+EXPORT_SYMBOL(sof_pcm_dai_link_fixup);
static int sof_pcm_probe(struct snd_soc_component *component)
{