Commit 0390a102 authored by Bard Liao's avatar Bard Liao Committed by Mark Brown

ASoC: SOF: ipc4-topology: use different channel mask for each sdw amp feedback

Currently, we use the same channel mask for aggregated speakers.
It works fine for playback because we duplicate the audio data for all
aggregated speakers. But we need to get audio data from each aggregated
speaker and combine them to the captured audio. So we need to set
non-overlapping channel mask for aggregated ALH DAIs.
Signed-off-by: default avatarBard Liao <yung-chuan.liao@linux.intel.com>
Reviewed-by: default avatarRanjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: default avatarPierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: default avatarPéter Ujfalusi <peter.ujfalusi@linux.intel.com>
Signed-off-by: default avatarPeter Ujfalusi <peter.ujfalusi@linux.intel.com>
Link: https://lore.kernel.org/r/20230125141317.30302-1-peter.ujfalusi@linux.intel.comSigned-off-by: default avatarMark Brown <broonie@kernel.org>
parent 167b3a2b
...@@ -1241,8 +1241,11 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget, ...@@ -1241,8 +1241,11 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget,
struct sof_ipc4_copier_data *alh_data; struct sof_ipc4_copier_data *alh_data;
struct sof_ipc4_copier *alh_copier; struct sof_ipc4_copier *alh_copier;
struct snd_sof_widget *w; struct snd_sof_widget *w;
u32 ch_count = 0;
u32 ch_mask = 0; u32 ch_mask = 0;
u32 ch_map; u32 ch_map;
u32 step;
u32 mask;
int i; int i;
blob = (struct sof_ipc4_alh_configuration_blob *)ipc4_copier->copier_config; blob = (struct sof_ipc4_alh_configuration_blob *)ipc4_copier->copier_config;
...@@ -1252,11 +1255,15 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget, ...@@ -1252,11 +1255,15 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget,
/* Get channel_mask from ch_map */ /* Get channel_mask from ch_map */
ch_map = copier_data->base_config.audio_fmt.ch_map; ch_map = copier_data->base_config.audio_fmt.ch_map;
for (i = 0; ch_map; i++) { for (i = 0; ch_map; i++) {
if ((ch_map & 0xf) != 0xf) if ((ch_map & 0xf) != 0xf) {
ch_mask |= BIT(i); ch_mask |= BIT(i);
ch_count++;
}
ch_map >>= 4; ch_map >>= 4;
} }
step = ch_count / blob->alh_cfg.count;
mask = GENMASK(step - 1, 0);
/* /*
* Set each gtw_cfg.node_id to blob->alh_cfg.mapping[] * Set each gtw_cfg.node_id to blob->alh_cfg.mapping[]
* for all widgets with the same stream name * for all widgets with the same stream name
...@@ -1271,7 +1278,22 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget, ...@@ -1271,7 +1278,22 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget,
alh_copier = (struct sof_ipc4_copier *)dai->private; alh_copier = (struct sof_ipc4_copier *)dai->private;
alh_data = &alh_copier->data; alh_data = &alh_copier->data;
blob->alh_cfg.mapping[i].alh_id = alh_data->gtw_cfg.node_id; blob->alh_cfg.mapping[i].alh_id = alh_data->gtw_cfg.node_id;
/*
* Set the same channel mask for playback as the audio data is
* duplicated for all speakers. For capture, split the channels
* among the aggregated DAIs. For example, with 4 channels on 2
* aggregated DAIs, the channel_mask should be 0x3 and 0xc for the
* two DAI's.
* The channel masks used depend on the cpu_dais used in the
* dailink at the machine driver level, which actually comes from
* the tables in soc_acpi files depending on the _ADR and devID
* registers for each codec.
*/
if (w->id == snd_soc_dapm_dai_in)
blob->alh_cfg.mapping[i].channel_mask = ch_mask; blob->alh_cfg.mapping[i].channel_mask = ch_mask;
else
blob->alh_cfg.mapping[i].channel_mask = mask << (step * i);
i++; i++;
} }
if (blob->alh_cfg.count > 1) { if (blob->alh_cfg.count > 1) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment