@@ -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,
943952static 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