Skip to content

Commit 6c8d63d

Browse files
ujfalusiranj063
authored andcommitted
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 3a6b930 commit 6c8d63d

1 file changed

Lines changed: 46 additions & 15 deletions

File tree

sound/soc/sof/ipc4-pcm.c

Lines changed: 46 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -557,12 +557,15 @@ static int sof_ipc4_pcm_hw_free(struct snd_soc_component *component,
557557
return sof_ipc4_trigger_pipelines(component, substream, SOF_IPC4_PIPE_RESET, 0);
558558
}
559559

560-
static void ipc4_ssp_dai_config_pcm_params_match(struct snd_sof_dev *sdev, const char *link_name,
561-
struct snd_pcm_hw_params *params)
560+
static int ipc4_ssp_dai_config_pcm_params_match(struct snd_sof_dev *sdev,
561+
const char *link_name,
562+
struct snd_pcm_hw_params *params)
562563
{
563564
struct snd_sof_dai_link *slink;
564565
struct snd_sof_dai *dai;
565566
bool dai_link_found = false;
567+
int current_config = -1;
568+
bool partial_match;
566569
int i;
567570

568571
list_for_each_entry(slink, &sdev->dai_link_list, list) {
@@ -573,19 +576,50 @@ static void ipc4_ssp_dai_config_pcm_params_match(struct snd_sof_dev *sdev, const
573576
}
574577

575578
if (!dai_link_found)
576-
return;
579+
return 0;
577580

581+
/*
582+
* Find the first best matching hardware config:
583+
* rate + format + channels are matching
584+
* rate + channel are matching
585+
*
586+
* The copier cannot do rate and/or channel conversion.
587+
*/
578588
for (i = 0; i < slink->num_hw_configs; i++) {
579589
struct snd_soc_tplg_hw_config *hw_config = &slink->hw_configs[i];
580590

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);
591+
if (params_rate(params) == le32_to_cpu(hw_config->fsync_rate) &&
592+
params_width(params) == le32_to_cpu(hw_config->tdm_slot_width) &&
593+
params_channels(params) == le32_to_cpu(hw_config->tdm_slots)) {
594+
current_config = le32_to_cpu(hw_config->id);
595+
partial_match = false;
596+
/* best match found */
586597
break;
598+
} else if (current_config < 0 &&
599+
params_rate(params) == le32_to_cpu(hw_config->fsync_rate) &&
600+
params_channels(params) == le32_to_cpu(hw_config->tdm_slots)) {
601+
current_config = le32_to_cpu(hw_config->id);
602+
partial_match = true;
603+
/* keep looking for better match */
587604
}
588605
}
606+
607+
if (current_config < 0) {
608+
dev_err(sdev->dev,
609+
"%s: No suitable hw_config found for %s (num_hw_configs: %d)\n",
610+
__func__, slink->link->name, slink->num_hw_configs);
611+
return -EINVAL;
612+
}
613+
614+
dev_dbg(sdev->dev,
615+
"hw_config for %s: %d (num_hw_configs: %d) with %s match\n",
616+
slink->link->name, current_config, slink->num_hw_configs,
617+
partial_match ? "partial" : "full");
618+
list_for_each_entry(dai, &sdev->dai_list, list)
619+
if (!strcmp(slink->link->name, dai->name))
620+
dai->current_config = current_config;
621+
622+
return 0;
589623
}
590624

591625
/*
@@ -728,13 +762,10 @@ static int sof_ipc4_pcm_dai_link_fixup(struct snd_soc_pcm_runtime *rtd,
728762
break;
729763
}
730764

731-
switch (ipc4_copier->dai_type) {
732-
case SOF_DAI_INTEL_SSP:
733-
ipc4_ssp_dai_config_pcm_params_match(sdev, (char *)rtd->dai_link->name, params);
734-
break;
735-
default:
736-
break;
737-
}
765+
if (ipc4_copier->dai_type == SOF_DAI_INTEL_SSP)
766+
return ipc4_ssp_dai_config_pcm_params_match(sdev,
767+
(char *)rtd->dai_link->name,
768+
params);
738769

739770
return 0;
740771
}

0 commit comments

Comments
 (0)