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: intel: sof_sdw: Support multiple groups on the same link

The current code checks the first device on a link and assumes
that all the other devices on the link will have the same endpoint
aggregation status and endpoint group ID.

Say for example a system looked like:

SDW0 - Amp 1 (Aggregated, Group 1), Mic 1 (Aggregated, Group 2)
SDW1 - Amp 2 (Aggregated, Group 1), Mic 2 (Aggregated, Group 2)

The current code would create the DAI link for the aggregated amps,
although it is worth noting that the only reason Mic 2 is not added is
the additional check that aborts processing the link when the device
changes. Then when processing the DAI link for the microphones, Mic
2 would not be added, as the check will only be done on the first
device, which would be Amp 2 and thus the wrong group, causing the
whole link to be skipped.

Move the endpoint check to be for each device rather than the first
device on each link.

Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com>
Link: https://lore.kernel.org/r/20230808132013.889419-10-ckeepax@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>

authored by

Charles Keepax and committed by
Mark Brown
f82742dd f3eb3d45

+21 -21
+21 -21
sound/soc/intel/boards/sof_sdw.c
··· 1288 1288 } 1289 1289 1290 1290 /* gather other link ID of slaves in the same group */ 1291 - for (adr_next = adr_link + 1; adr_next && adr_next->num_adr; 1292 - adr_next++) { 1293 - const struct snd_soc_acpi_endpoint *endpoint; 1291 + for (adr_next = adr_link + 1; adr_next && adr_next->num_adr; adr_next++) { 1292 + unsigned int link_codecs = 0; 1294 1293 1295 - endpoint = adr_next->adr_d->endpoints; 1296 - if (!endpoint->aggregated || 1297 - endpoint->group_id != *group_id) 1298 - continue; 1299 - 1300 - if (index >= SDW_MAX_CPU_DAIS) { 1301 - dev_err(dev, "cpu_dai_id array overflows\n"); 1302 - return -EINVAL; 1303 - } 1304 - 1305 - cpu_dai_id[index++] = ffs(adr_next->mask) - 1; 1306 1294 for (i = 0; i < adr_next->num_adr; i++) { 1307 1295 if (adr_next->adr_d[i].endpoints->aggregated && 1308 1296 adr_next->adr_d[i].endpoints->group_id == *group_id) 1309 - (*codec_num)++; 1297 + link_codecs++; 1298 + } 1299 + 1300 + if (link_codecs) { 1301 + *codec_num += link_codecs; 1302 + 1303 + if (index >= SDW_MAX_CPU_DAIS) { 1304 + dev_err(dev, "cpu_dai_id array overflowed\n"); 1305 + return -EINVAL; 1306 + } 1307 + 1308 + cpu_dai_id[index++] = ffs(adr_next->mask) - 1; 1310 1309 } 1311 1310 } 1312 1311 ··· 1368 1369 j = adr_index; 1369 1370 for (adr_link_next = adr_link; adr_link_next && adr_link_next->num_adr && 1370 1371 i < cpu_dai_num; adr_link_next++) { 1371 - const struct snd_soc_acpi_endpoint *endpoints; 1372 1372 int _codec_index = -1; 1373 - 1374 - endpoints = adr_link_next->adr_d->endpoints; 1375 - if (group_id && (!endpoints->aggregated || 1376 - endpoints->group_id != group_id)) 1377 - continue; 1378 1373 1379 1374 /* skip the link excluded by this processed group */ 1380 1375 if (cpu_dai_id[i] != ffs(adr_link_next->mask) - 1) ··· 1376 1383 1377 1384 /* j reset after loop, adr_index only applies to first link */ 1378 1385 for (; j < adr_link_next->num_adr; j++) { 1386 + const struct snd_soc_acpi_endpoint *endpoints; 1379 1387 int codec_index; 1380 1388 u64 adr = adr_link_next->adr_d[j].adr; 1381 1389 ··· 1388 1394 break; 1389 1395 } 1390 1396 _codec_index = codec_index; 1397 + 1398 + endpoints = adr_link_next->adr_d[j].endpoints; 1399 + 1400 + if (group_id && (!endpoints->aggregated || 1401 + endpoints->group_id != group_id)) 1402 + continue; 1391 1403 1392 1404 /* sanity check */ 1393 1405 if (*codec_conf_index >= codec_count) {