Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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: Bard Liao <yung-chuan.liao@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: Péter Ujfalusi <peter.ujfalusi@linux.intel.com>
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
Link: https://lore.kernel.org/r/20230125141317.30302-1-peter.ujfalusi@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>

authored by

Bard Liao and committed by
Mark Brown
0390a102 167b3a2b

+24 -2
+24 -2
sound/soc/sof/ipc4-topology.c
··· 1241 1241 struct sof_ipc4_copier_data *alh_data; 1242 1242 struct sof_ipc4_copier *alh_copier; 1243 1243 struct snd_sof_widget *w; 1244 + u32 ch_count = 0; 1244 1245 u32 ch_mask = 0; 1245 1246 u32 ch_map; 1247 + u32 step; 1248 + u32 mask; 1246 1249 int i; 1247 1250 1248 1251 blob = (struct sof_ipc4_alh_configuration_blob *)ipc4_copier->copier_config; ··· 1255 1252 /* Get channel_mask from ch_map */ 1256 1253 ch_map = copier_data->base_config.audio_fmt.ch_map; 1257 1254 for (i = 0; ch_map; i++) { 1258 - if ((ch_map & 0xf) != 0xf) 1255 + if ((ch_map & 0xf) != 0xf) { 1259 1256 ch_mask |= BIT(i); 1257 + ch_count++; 1258 + } 1260 1259 ch_map >>= 4; 1261 1260 } 1262 1261 1262 + step = ch_count / blob->alh_cfg.count; 1263 + mask = GENMASK(step - 1, 0); 1263 1264 /* 1264 1265 * Set each gtw_cfg.node_id to blob->alh_cfg.mapping[] 1265 1266 * for all widgets with the same stream name ··· 1278 1271 alh_copier = (struct sof_ipc4_copier *)dai->private; 1279 1272 alh_data = &alh_copier->data; 1280 1273 blob->alh_cfg.mapping[i].alh_id = alh_data->gtw_cfg.node_id; 1281 - blob->alh_cfg.mapping[i].channel_mask = ch_mask; 1274 + /* 1275 + * Set the same channel mask for playback as the audio data is 1276 + * duplicated for all speakers. For capture, split the channels 1277 + * among the aggregated DAIs. For example, with 4 channels on 2 1278 + * aggregated DAIs, the channel_mask should be 0x3 and 0xc for the 1279 + * two DAI's. 1280 + * The channel masks used depend on the cpu_dais used in the 1281 + * dailink at the machine driver level, which actually comes from 1282 + * the tables in soc_acpi files depending on the _ADR and devID 1283 + * registers for each codec. 1284 + */ 1285 + if (w->id == snd_soc_dapm_dai_in) 1286 + blob->alh_cfg.mapping[i].channel_mask = ch_mask; 1287 + else 1288 + blob->alh_cfg.mapping[i].channel_mask = mask << (step * i); 1289 + 1282 1290 i++; 1283 1291 } 1284 1292 if (blob->alh_cfg.count > 1) {