Skip to content

Commit 69e23a6

Browse files
committed
ASoC: SOF: ipc4-pcm: Look for best matching hw_config for SSP
Instead of just looking for a hw_config with matching rate only it sounds better to try to find the best matching configuration. If we have multiple hw_configurations with the same rate, but each with different format for example then we have been picking the first config with the matching rate, which can be a problem and it wil depend on how the configs are ordered. Instead we should be trying to find the best match out of the configs 1. rate + format + channels are matching 2. rate + format are matching 3. rate matching Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
1 parent 08e627b commit 69e23a6

File tree

1 file changed

+38
-5
lines changed

1 file changed

+38
-5
lines changed

sound/soc/sof/ipc4-pcm.c

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -563,6 +563,8 @@ static void ipc4_ssp_dai_config_pcm_params_match(struct snd_sof_dev *sdev, const
563563
struct snd_sof_dai_link *slink;
564564
struct snd_sof_dai *dai;
565565
bool dai_link_found = false;
566+
int current_config = -1;
567+
int matching_params = 0;
566568
int i;
567569

568570
list_for_each_entry(slink, &sdev->dai_link_list, list) {
@@ -575,17 +577,48 @@ static void ipc4_ssp_dai_config_pcm_params_match(struct snd_sof_dev *sdev, const
575577
if (!dai_link_found)
576578
return;
577579

580+
/*
581+
* Find the first best matching hardware config:
582+
* rate + format + channels are matching
583+
* rate + format are matching
584+
* rate matching
585+
*/
578586
for (i = 0; i < slink->num_hw_configs; i++) {
579587
struct snd_soc_tplg_hw_config *hw_config = &slink->hw_configs[i];
580588

581-
if (params_rate(params) == le32_to_cpu(hw_config->fsync_rate)) {
582-
/* set current config for all DAI's with matching name */
583-
list_for_each_entry(dai, &sdev->dai_list, list)
584-
if (!strcmp(slink->link->name, dai->name))
585-
dai->current_config = le32_to_cpu(hw_config->id);
589+
if (params_rate(params) == le32_to_cpu(hw_config->fsync_rate) &&
590+
params_width(params) == le32_to_cpu(hw_config->tdm_slot_width) &&
591+
params_channels(params) == le32_to_cpu(hw_config->tdm_slots)) {
592+
current_config = le32_to_cpu(hw_config->id);
593+
matching_params = 3;
594+
/* best match found */
586595
break;
596+
} else if (matching_params < 2 &&
597+
params_rate(params) == le32_to_cpu(hw_config->fsync_rate) &&
598+
params_width(params) == le32_to_cpu(hw_config->tdm_slot_width)) {
599+
current_config = le32_to_cpu(hw_config->id);
600+
matching_params = 2;
601+
/* keep looking for better match */
602+
} else if (matching_params < 1 &&
603+
params_rate(params) == le32_to_cpu(hw_config->fsync_rate)) {
604+
current_config = le32_to_cpu(hw_config->id);
605+
matching_params = 1;
606+
/* keep looking for better match */
587607
}
588608
}
609+
610+
if (current_config < 0) {
611+
dev_dbg(sdev->dev, "No suitable hw_config found for %s\n",
612+
slink->link->name);
613+
return;
614+
}
615+
616+
dev_dbg(sdev->dev,
617+
"hw_config for %s: %d (num_hw_configs: %d) with %d matching params\n",
618+
slink->link->name, current_config, slink->num_hw_configs, matching_params);
619+
list_for_each_entry(dai, &sdev->dai_list, list)
620+
if (!strcmp(slink->link->name, dai->name))
621+
dai->current_config = current_config;
589622
}
590623

591624
/*

0 commit comments

Comments
 (0)