@@ -621,7 +621,6 @@ static struct sof_sdw_codec_info codec_info_list[] = {
621621 .direction = {true, true},
622622 .dai_name = "max98373-aif1" ,
623623 .init = sof_sdw_mx8373_init ,
624- .codec_card_late_probe = sof_sdw_mx8373_late_probe ,
625624 .codec_type = SOF_SDW_CODEC_TYPE_AMP ,
626625 },
627626 {
@@ -733,34 +732,36 @@ static int get_sdw_dailink_info(struct device *dev, const struct snd_soc_acpi_li
733732 int stream ;
734733 u64 adr ;
735734
736- adr = link -> adr_d -> adr ;
737- codec_index = find_codec_info_part (adr );
738- if (codec_index < 0 )
739- 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 ;
740740
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" );
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" );
744744
745- _codec_type = codec_info_list [codec_index ].codec_type ;
745+ _codec_type = codec_info_list [codec_index ].codec_type ;
746746
747- endpoint = link -> adr_d -> endpoints ;
747+ endpoint = link -> adr_d [ i ]. endpoints ;
748748
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 ;
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 ;
753753
754- (* sdw_cpu_dai_num )++ ;
754+ (* sdw_cpu_dai_num )++ ;
755755
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- }
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+ }
761761
762- if (endpoint -> aggregated )
763- group_visited [endpoint -> group_id ] = true;
762+ if (endpoint -> aggregated )
763+ group_visited [endpoint -> group_id ] = true;
764+ }
764765 }
765766
766767 return 0 ;
@@ -830,17 +831,19 @@ static int create_codec_dai_name(struct device *dev,
830831 int offset ,
831832 struct snd_soc_codec_conf * codec_conf ,
832833 int codec_count ,
833- int * codec_conf_index )
834+ int * codec_conf_index ,
835+ int adr_index )
834836{
837+ int _codec_index = -1 ;
835838 int i ;
836839
837840 /* sanity check */
838- if (* codec_conf_index + link -> num_adr > codec_count ) {
841+ if (* codec_conf_index + link -> num_adr - adr_index > codec_count ) {
839842 dev_err (dev , "codec_conf: out-of-bounds access requested\n" );
840843 return - EINVAL ;
841844 }
842845
843- for (i = 0 ; i < link -> num_adr ; i ++ ) {
846+ for (i = adr_index ; i < link -> num_adr ; i ++ ) {
844847 unsigned int sdw_version , unique_id , mfg_id ;
845848 unsigned int link_id , part_id , class_id ;
846849 int codec_index , comp_index ;
@@ -856,7 +859,7 @@ static int create_codec_dai_name(struct device *dev,
856859 part_id = SDW_PART_ID (adr );
857860 class_id = SDW_CLASS_ID (adr );
858861
859- comp_index = i + offset ;
862+ comp_index = i - adr_index + offset ;
860863 if (is_unique_device (link , sdw_version , mfg_id , part_id ,
861864 class_id , i )) {
862865 codec_str = "sdw:%01x:%04x:%04x:%02x" ;
@@ -878,6 +881,11 @@ static int create_codec_dai_name(struct device *dev,
878881 codec_index = find_codec_info_part (adr );
879882 if (codec_index < 0 )
880883 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 ;
881889
882890 codec [comp_index ].dai_name =
883891 codec_info_list [codec_index ].dai_name ;
@@ -944,16 +952,16 @@ static int set_codec_init_func(struct snd_soc_card *card,
944952static int get_slave_info (const struct snd_soc_acpi_link_adr * adr_link ,
945953 struct device * dev , int * cpu_dai_id , int * cpu_dai_num ,
946954 int * codec_num , unsigned int * group_id ,
947- bool * group_generated )
955+ bool * group_generated , int adr_index )
948956{
949957 const struct snd_soc_acpi_adr_device * adr_d ;
950958 const struct snd_soc_acpi_link_adr * adr_next ;
951959 bool no_aggregation ;
952960 int index = 0 ;
961+ int i ;
953962
954963 no_aggregation = sof_sdw_quirk & SOF_SDW_NO_AGGREGATION ;
955- * codec_num = adr_link -> num_adr ;
956- adr_d = adr_link -> adr_d ;
964+ adr_d = & adr_link -> adr_d [adr_index ];
957965
958966 /* make sure the link mask has a single bit set */
959967 if (!is_power_of_2 (adr_link -> mask ))
@@ -962,12 +970,21 @@ static int get_slave_info(const struct snd_soc_acpi_link_adr *adr_link,
962970 cpu_dai_id [index ++ ] = ffs (adr_link -> mask ) - 1 ;
963971 if (!adr_d -> endpoints -> aggregated || no_aggregation ) {
964972 * cpu_dai_num = 1 ;
973+ * codec_num = 1 ;
965974 * group_id = 0 ;
966975 return 0 ;
967976 }
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 /*
@@ -1001,6 +1022,8 @@ static int get_slave_info(const struct snd_soc_acpi_link_adr *adr_link,
10011022 return 0 ;
10021023}
10031024
1025+ static const char * const type_strings [] = {"SimpleJack" , "SmartAmp" , "SmartMic" };
1026+
10041027static int create_sdw_dailink (struct snd_soc_card * card ,
10051028 struct device * dev , int * link_index ,
10061029 struct snd_soc_dai_link * dai_links ,
@@ -1011,7 +1034,9 @@ static int create_sdw_dailink(struct snd_soc_card *card,
10111034 struct snd_soc_codec_conf * codec_conf ,
10121035 int codec_count , int * link_id ,
10131036 int * codec_conf_index ,
1014- bool * ignore_pch_dmic )
1037+ bool * ignore_pch_dmic ,
1038+ bool append_codec_type ,
1039+ int adr_index )
10151040{
10161041 const struct snd_soc_acpi_link_adr * link_next ;
10171042 struct snd_soc_dai_link_component * codecs ;
@@ -1027,7 +1052,7 @@ static int create_sdw_dailink(struct snd_soc_card *card,
10271052 int k ;
10281053
10291054 ret = get_slave_info (link , dev , cpu_dai_id , & cpu_dai_num , & codec_num ,
1030- & group_id , group_generated );
1055+ & group_id , group_generated , adr_index );
10311056 if (ret )
10321057 return ret ;
10331058
@@ -1050,7 +1075,7 @@ static int create_sdw_dailink(struct snd_soc_card *card,
10501075 continue ;
10511076
10521077 ret = create_codec_dai_name (dev , link_next , codecs , codec_idx ,
1053- codec_conf , codec_count , codec_conf_index );
1078+ codec_conf , codec_count , codec_conf_index , adr_index );
10541079 if (ret < 0 )
10551080 return ret ;
10561081
@@ -1060,7 +1085,7 @@ static int create_sdw_dailink(struct snd_soc_card *card,
10601085 }
10611086
10621087 /* find codec info to create BE DAI */
1063- codec_index = find_codec_info_part (link -> adr_d [0 ].adr );
1088+ codec_index = find_codec_info_part (link -> adr_d [adr_index ].adr );
10641089 if (codec_index < 0 )
10651090 return codec_index ;
10661091
@@ -1087,14 +1112,22 @@ static int create_sdw_dailink(struct snd_soc_card *card,
10871112 static const char * const sdw_stream_name [] = {
10881113 "SDW%d-Playback" ,
10891114 "SDW%d-Capture" ,
1115+ "SDW%d-Playback-%s" ,
1116+ "SDW%d-Capture-%s" ,
10901117 };
10911118
10921119 if (!codec_info_list [codec_index ].direction [stream ])
10931120 continue ;
10941121
10951122 /* create stream name according to first link id */
1096- name = devm_kasprintf (dev , GFP_KERNEL ,
1097- sdw_stream_name [stream ], cpu_dai_id [0 ]);
1123+ if (append_codec_type ) {
1124+ name = devm_kasprintf (dev , GFP_KERNEL ,
1125+ sdw_stream_name [stream + 2 ], cpu_dai_id [0 ],
1126+ type_strings [codec_info_list [codec_index ].codec_type ]);
1127+ } else {
1128+ name = devm_kasprintf (dev , GFP_KERNEL ,
1129+ sdw_stream_name [stream ], cpu_dai_id [0 ]);
1130+ }
10981131 if (!name )
10991132 return - ENOMEM ;
11001133
@@ -1210,6 +1243,7 @@ static int sof_card_dai_links_create(struct device *dev,
12101243 const struct snd_soc_acpi_link_adr * adr_link ;
12111244 struct snd_soc_dai_link_component * cpus ;
12121245 struct snd_soc_codec_conf * codec_conf ;
1246+ bool append_codec_type = false;
12131247 bool ignore_pch_dmic = false;
12141248 int codec_conf_count ;
12151249 int codec_conf_index = 0 ;
@@ -1301,31 +1335,54 @@ static int sof_card_dai_links_create(struct device *dev,
13011335 for (i = 0 ; i < SDW_MAX_GROUPS ; i ++ )
13021336 group_generated [i ] = false;
13031337
1304- /* generate DAI links by each sdw link */
13051338 for (; adr_link -> num_adr ; adr_link ++ ) {
1306- const struct snd_soc_acpi_endpoint * endpoint ;
1307-
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 ;
1339+ /*
1340+ * If there are two or more different devices on the same sdw link, we have to
1341+ * append the codec type to the dai link name to prevent duplicated dai link name.
1342+ * The same type devices on the same sdw link will be in the same
1343+ * snd_soc_acpi_adr_device array. They won't be described in different adr_links.
1344+ */
1345+ for (i = 0 ; i < adr_link -> num_adr ; i ++ ) {
1346+ for (j = 0 ; j < i ; j ++ ) {
1347+ if ((SDW_PART_ID (adr_link -> adr_d [i ].adr ) !=
1348+ SDW_PART_ID (adr_link -> adr_d [j ].adr )) ||
1349+ (SDW_MFG_ID (adr_link -> adr_d [i ].adr ) !=
1350+ SDW_MFG_ID (adr_link -> adr_d [i ].adr ))) {
1351+ append_codec_type = true;
1352+ goto out ;
1353+ }
1354+ }
13131355 }
1356+ }
1357+ out :
13141358
1315- /* this group has been generated */
1316- if ( endpoint -> aggregated &&
1317- group_generated [ endpoint -> group_id ])
1318- continue ;
1359+ /* generate DAI links by each sdw link */
1360+ for ( adr_link = mach_params -> links ; adr_link -> num_adr ; adr_link ++ ) {
1361+ for ( i = 0 ; i < adr_link -> num_adr ; i ++ ) {
1362+ const struct snd_soc_acpi_endpoint * endpoint ;
13191363
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 ;
1364+ endpoint = adr_link -> adr_d [i ].endpoints ;
1365+ if (endpoint -> aggregated && !endpoint -> group_id ) {
1366+ dev_err (dev , "invalid group id on link %x" ,
1367+ adr_link -> mask );
1368+ continue ;
1369+ }
1370+
1371+ /* this group has been generated */
1372+ if (endpoint -> aggregated &&
1373+ group_generated [endpoint -> group_id ])
1374+ continue ;
1375+
1376+ ret = create_sdw_dailink (card , dev , & link_index , links , sdw_be_num ,
1377+ sdw_cpu_dai_num , cpus , adr_link ,
1378+ & cpu_id , group_generated ,
1379+ codec_conf , codec_conf_count ,
1380+ & be_id , & codec_conf_index ,
1381+ & ignore_pch_dmic , append_codec_type , i );
1382+ if (ret < 0 ) {
1383+ dev_err (dev , "failed to create dai link %d" , link_index );
1384+ return ret ;
1385+ }
13291386 }
13301387 }
13311388
@@ -1490,12 +1547,12 @@ static int sof_sdw_card_late_probe(struct snd_soc_card *card)
14901547 int i ;
14911548
14921549 for (i = 0 ; i < ARRAY_SIZE (codec_info_list ); i ++ ) {
1493- if (! codec_info_list [i ].late_probe )
1494- continue ;
1550+ if (codec_info_list [i ].codec_card_late_probe ) {
1551+ ret = codec_info_list [ i ]. codec_card_late_probe ( card ) ;
14951552
1496- ret = codec_info_list [ i ]. codec_card_late_probe ( card );
1497- if ( ret < 0 )
1498- return ret ;
1553+ if ( ret < 0 )
1554+ return ret ;
1555+ }
14991556 }
15001557
15011558 if (ctx -> idisp_codec )
0 commit comments