Skip to content

Commit c8db7b5

Browse files
bardliaobroonie
authored andcommitted
ASoC: Intel: sof_sdw: support different devices on the same sdw link
The existing code assumes all devices on the same soundwire link are the same devices. eg. all rt1316. This commit removes the assumption and supports different devices on the same soundwire link. Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Reviewed-by: Rander Wang <rander.wang@intel.com> Link: https://lore.kernel.org/r/20230419195524.46995-7-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown <broonie@kernel.org>
1 parent 16373f3 commit c8db7b5

1 file changed

Lines changed: 77 additions & 53 deletions

File tree

sound/soc/intel/boards/sof_sdw.c

Lines changed: 77 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -732,34 +732,36 @@ static int get_sdw_dailink_info(struct device *dev, const struct snd_soc_acpi_li
732732
int stream;
733733
u64 adr;
734734

735-
adr = link->adr_d->adr;
736-
codec_index = find_codec_info_part(adr);
737-
if (codec_index < 0)
738-
return codec_index;
735+
for (i = 0; i < link->num_adr; i++) {
736+
adr = link->adr_d[i].adr;
737+
codec_index = find_codec_info_part(adr);
738+
if (codec_index < 0)
739+
return codec_index;
739740

740-
if (codec_info_list[codec_index].codec_type < _codec_type)
741-
dev_warn(dev,
742-
"Unexpected address table ordering. Expected order: jack -> amp -> mic\n");
741+
if (codec_info_list[codec_index].codec_type < _codec_type)
742+
dev_warn(dev,
743+
"Unexpected address table ordering. Expected order: jack -> amp -> mic\n");
743744

744-
_codec_type = codec_info_list[codec_index].codec_type;
745+
_codec_type = codec_info_list[codec_index].codec_type;
745746

746-
endpoint = link->adr_d->endpoints;
747+
endpoint = link->adr_d[i].endpoints;
747748

748-
/* count DAI number for playback and capture */
749-
for_each_pcm_streams(stream) {
750-
if (!codec_info_list[codec_index].direction[stream])
751-
continue;
749+
/* count DAI number for playback and capture */
750+
for_each_pcm_streams(stream) {
751+
if (!codec_info_list[codec_index].direction[stream])
752+
continue;
752753

753-
(*sdw_cpu_dai_num)++;
754+
(*sdw_cpu_dai_num)++;
754755

755-
/* count BE for each non-aggregated slave or group */
756-
if (!endpoint->aggregated || no_aggregation ||
757-
!group_visited[endpoint->group_id])
758-
(*sdw_be_num)++;
759-
}
756+
/* count BE for each non-aggregated slave or group */
757+
if (!endpoint->aggregated || no_aggregation ||
758+
!group_visited[endpoint->group_id])
759+
(*sdw_be_num)++;
760+
}
760761

761-
if (endpoint->aggregated)
762-
group_visited[endpoint->group_id] = true;
762+
if (endpoint->aggregated)
763+
group_visited[endpoint->group_id] = true;
764+
}
763765
}
764766

765767
return 0;
@@ -829,17 +831,19 @@ static int create_codec_dai_name(struct device *dev,
829831
int offset,
830832
struct snd_soc_codec_conf *codec_conf,
831833
int codec_count,
832-
int *codec_conf_index)
834+
int *codec_conf_index,
835+
int adr_index)
833836
{
837+
int _codec_index = -1;
834838
int i;
835839

836840
/* sanity check */
837-
if (*codec_conf_index + link->num_adr > codec_count) {
841+
if (*codec_conf_index + link->num_adr - adr_index > codec_count) {
838842
dev_err(dev, "codec_conf: out-of-bounds access requested\n");
839843
return -EINVAL;
840844
}
841845

842-
for (i = 0; i < link->num_adr; i++) {
846+
for (i = adr_index; i < link->num_adr; i++) {
843847
unsigned int sdw_version, unique_id, mfg_id;
844848
unsigned int link_id, part_id, class_id;
845849
int codec_index, comp_index;
@@ -855,7 +859,7 @@ static int create_codec_dai_name(struct device *dev,
855859
part_id = SDW_PART_ID(adr);
856860
class_id = SDW_CLASS_ID(adr);
857861

858-
comp_index = i + offset;
862+
comp_index = i - adr_index + offset;
859863
if (is_unique_device(link, sdw_version, mfg_id, part_id,
860864
class_id, i)) {
861865
codec_str = "sdw:%01x:%04x:%04x:%02x";
@@ -877,6 +881,11 @@ static int create_codec_dai_name(struct device *dev,
877881
codec_index = find_codec_info_part(adr);
878882
if (codec_index < 0)
879883
return codec_index;
884+
if (_codec_index != -1 && codec_index != _codec_index) {
885+
dev_dbg(dev, "Different devices on the same sdw link\n");
886+
break;
887+
}
888+
_codec_index = codec_index;
880889

881890
codec[comp_index].dai_name =
882891
codec_info_list[codec_index].dai_name;
@@ -943,16 +952,16 @@ static int set_codec_init_func(struct snd_soc_card *card,
943952
static int get_slave_info(const struct snd_soc_acpi_link_adr *adr_link,
944953
struct device *dev, int *cpu_dai_id, int *cpu_dai_num,
945954
int *codec_num, unsigned int *group_id,
946-
bool *group_generated)
955+
bool *group_generated, int adr_index)
947956
{
948957
const struct snd_soc_acpi_adr_device *adr_d;
949958
const struct snd_soc_acpi_link_adr *adr_next;
950959
bool no_aggregation;
951960
int index = 0;
961+
int i;
952962

953963
no_aggregation = sof_sdw_quirk & SOF_SDW_NO_AGGREGATION;
954-
*codec_num = adr_link->num_adr;
955-
adr_d = adr_link->adr_d;
964+
adr_d = &adr_link->adr_d[adr_index];
956965

957966
/* make sure the link mask has a single bit set */
958967
if (!is_power_of_2(adr_link->mask))
@@ -968,6 +977,14 @@ static int get_slave_info(const struct snd_soc_acpi_link_adr *adr_link,
968977

969978
*group_id = adr_d->endpoints->group_id;
970979

980+
/* Count endpoints with the same group_id in the adr_link */
981+
*codec_num = 0;
982+
for (i = 0; i < adr_link->num_adr; i++) {
983+
if (adr_link->adr_d[i].endpoints->aggregated &&
984+
adr_link->adr_d[i].endpoints->group_id == *group_id)
985+
(*codec_num)++;
986+
}
987+
971988
/* gather other link ID of slaves in the same group */
972989
for (adr_next = adr_link + 1; adr_next && adr_next->num_adr;
973990
adr_next++) {
@@ -988,7 +1005,11 @@ static int get_slave_info(const struct snd_soc_acpi_link_adr *adr_link,
9881005
}
9891006

9901007
cpu_dai_id[index++] = ffs(adr_next->mask) - 1;
991-
*codec_num += adr_next->num_adr;
1008+
for (i = 0; i < adr_next->num_adr; i++) {
1009+
if (adr_next->adr_d[i].endpoints->aggregated &&
1010+
adr_next->adr_d[i].endpoints->group_id == *group_id)
1011+
(*codec_num)++;
1012+
}
9921013
}
9931014

9941015
/*
@@ -1011,7 +1032,8 @@ static int create_sdw_dailink(struct snd_soc_card *card,
10111032
struct snd_soc_codec_conf *codec_conf,
10121033
int codec_count, int *link_id,
10131034
int *codec_conf_index,
1014-
bool *ignore_pch_dmic)
1035+
bool *ignore_pch_dmic,
1036+
int adr_index)
10151037
{
10161038
const struct snd_soc_acpi_link_adr *link_next;
10171039
struct snd_soc_dai_link_component *codecs;
@@ -1027,7 +1049,7 @@ static int create_sdw_dailink(struct snd_soc_card *card,
10271049
int k;
10281050

10291051
ret = get_slave_info(link, dev, cpu_dai_id, &cpu_dai_num, &codec_num,
1030-
&group_id, group_generated);
1052+
&group_id, group_generated, adr_index);
10311053
if (ret)
10321054
return ret;
10331055

@@ -1050,7 +1072,7 @@ static int create_sdw_dailink(struct snd_soc_card *card,
10501072
continue;
10511073

10521074
ret = create_codec_dai_name(dev, link_next, codecs, codec_idx,
1053-
codec_conf, codec_count, codec_conf_index);
1075+
codec_conf, codec_count, codec_conf_index, adr_index);
10541076
if (ret < 0)
10551077
return ret;
10561078

@@ -1060,7 +1082,7 @@ static int create_sdw_dailink(struct snd_soc_card *card,
10601082
}
10611083

10621084
/* find codec info to create BE DAI */
1063-
codec_index = find_codec_info_part(link->adr_d[0].adr);
1085+
codec_index = find_codec_info_part(link->adr_d[adr_index].adr);
10641086
if (codec_index < 0)
10651087
return codec_index;
10661088

@@ -1303,29 +1325,31 @@ static int sof_card_dai_links_create(struct device *dev,
13031325

13041326
/* generate DAI links by each sdw link */
13051327
for (; adr_link->num_adr; adr_link++) {
1306-
const struct snd_soc_acpi_endpoint *endpoint;
1328+
for (i = 0; i < adr_link->num_adr; i++) {
1329+
const struct snd_soc_acpi_endpoint *endpoint;
13071330

1308-
endpoint = adr_link->adr_d->endpoints;
1309-
if (endpoint->aggregated && !endpoint->group_id) {
1310-
dev_err(dev, "invalid group id on link %x",
1311-
adr_link->mask);
1312-
continue;
1313-
}
1331+
endpoint = adr_link->adr_d[i].endpoints;
1332+
if (endpoint->aggregated && !endpoint->group_id) {
1333+
dev_err(dev, "invalid group id on link %x",
1334+
adr_link->mask);
1335+
continue;
1336+
}
13141337

1315-
/* this group has been generated */
1316-
if (endpoint->aggregated &&
1317-
group_generated[endpoint->group_id])
1318-
continue;
1338+
/* this group has been generated */
1339+
if (endpoint->aggregated &&
1340+
group_generated[endpoint->group_id])
1341+
continue;
13191342

1320-
ret = create_sdw_dailink(card, dev, &link_index, links, sdw_be_num,
1321-
sdw_cpu_dai_num, cpus, adr_link,
1322-
&cpu_id, group_generated,
1323-
codec_conf, codec_conf_count,
1324-
&be_id, &codec_conf_index,
1325-
&ignore_pch_dmic);
1326-
if (ret < 0) {
1327-
dev_err(dev, "failed to create dai link %d", link_index);
1328-
return ret;
1343+
ret = create_sdw_dailink(card, dev, &link_index, links, sdw_be_num,
1344+
sdw_cpu_dai_num, cpus, adr_link,
1345+
&cpu_id, group_generated,
1346+
codec_conf, codec_conf_count,
1347+
&be_id, &codec_conf_index,
1348+
&ignore_pch_dmic, i);
1349+
if (ret < 0) {
1350+
dev_err(dev, "failed to create dai link %d", link_index);
1351+
return ret;
1352+
}
13291353
}
13301354
}
13311355

0 commit comments

Comments
 (0)