1010#include <linux/module.h>
1111#include <linux/soundwire/sdw.h>
1212#include <linux/soundwire/sdw_type.h>
13+ #include <sound/sdca_function.h>
1314#include <sound/soc_sdw_utils.h>
1415
1516static const struct snd_soc_dapm_widget generic_dmic_widgets [] = {
@@ -1132,6 +1133,24 @@ struct asoc_sdw_dailink *asoc_sdw_find_dailink(struct asoc_sdw_dailink *dailinks
11321133}
11331134EXPORT_SYMBOL_NS (asoc_sdw_find_dailink , "SND_SOC_SDW_UTILS" );
11341135
1136+ static int asoc_sdw_get_dai_type (u32 type ) {
1137+ switch (type ) {
1138+ case SDCA_FUNCTION_TYPE_SMART_AMP :
1139+ case SDCA_FUNCTION_TYPE_SIMPLE_AMP :
1140+ return SOC_SDW_DAI_TYPE_AMP ;
1141+ case SDCA_FUNCTION_TYPE_SMART_MIC :
1142+ case SDCA_FUNCTION_TYPE_SIMPLE_MIC :
1143+ case SDCA_FUNCTION_TYPE_SPEAKER_MIC :
1144+ return SOC_SDW_DAI_TYPE_MIC ;
1145+ case SDCA_FUNCTION_TYPE_UAJ :
1146+ case SDCA_FUNCTION_TYPE_RJ :
1147+ case SDCA_FUNCTION_TYPE_SIMPLE_JACK :
1148+ return SOC_SDW_DAI_TYPE_JACK ;
1149+ default :
1150+ return - EINVAL ;
1151+ }
1152+ }
1153+
11351154int asoc_sdw_parse_sdw_endpoints (struct snd_soc_card * card ,
11361155 struct asoc_sdw_dailink * soc_dais ,
11371156 struct asoc_sdw_endpoint * soc_ends ,
@@ -1143,8 +1162,10 @@ int asoc_sdw_parse_sdw_endpoints(struct snd_soc_card *card,
11431162 struct snd_soc_acpi_mach_params * mach_params = & mach -> mach_params ;
11441163 const struct snd_soc_acpi_link_adr * adr_link ;
11451164 struct asoc_sdw_endpoint * soc_end = soc_ends ;
1165+ struct snd_soc_dai_link_component dlc ;
1166+ struct snd_soc_dai * codec_dai ;
11461167 int num_dais = 0 ;
1147- int i , j ;
1168+ int i , j , k ;
11481169 int ret ;
11491170
11501171 for (adr_link = mach_params -> links ; adr_link -> num_adr ; adr_link ++ ) {
@@ -1194,6 +1215,9 @@ int asoc_sdw_parse_sdw_endpoints(struct snd_soc_card *card,
11941215 const struct snd_soc_acpi_endpoint * adr_end ;
11951216 const struct asoc_sdw_dai_info * dai_info ;
11961217 struct asoc_sdw_dailink * soc_dai ;
1218+ const char * sdw_codec_name ;
1219+ struct sdw_slave * slave ;
1220+ struct device * sdw_dev ;
11971221 int stream ;
11981222
11991223 adr_end = & adr_dev -> endpoints [j ];
@@ -1204,6 +1228,53 @@ int asoc_sdw_parse_sdw_endpoints(struct snd_soc_card *card,
12041228 !(dai_info -> quirk_exclude ^ !!(dai_info -> quirk & ctx -> mc_quirk )))
12051229 continue ;
12061230
1231+ dlc .dai_name = dai_info -> dai_name ;
1232+ codec_dai = snd_soc_find_dai_with_mutex (& dlc );
1233+ if (!codec_dai ) {
1234+ dev_err (dev , "codec dai %s not registered yet\n" ,
1235+ dlc .dai_name );
1236+ return - EPROBE_DEFER ;
1237+ }
1238+
1239+ /* No need to check SDCA functions if there is only 1 endpoint present */
1240+ if (adr_dev -> num_endpoints == 1 )
1241+ goto skip_sdca_function_check ;
1242+
1243+ sdw_codec_name = _asoc_sdw_get_codec_name (dev , codec_info , adr_link , i );
1244+ if (!sdw_codec_name )
1245+ return - ENOMEM ;
1246+
1247+ sdw_dev = bus_find_device_by_name (& sdw_bus_type , NULL , sdw_codec_name );
1248+ if (!sdw_dev ) {
1249+ dev_err (dev , "codec %s not found\n" , sdw_codec_name );
1250+ return - EINVAL ;
1251+ }
1252+
1253+ slave = dev_to_sdw_dev (sdw_dev );
1254+ if (!slave )
1255+ return - EINVAL ;
1256+
1257+ /* Mack sure BIOS provides SDCA properties */
1258+ if (!slave -> sdca_data .interface_revision )
1259+ goto skip_sdca_function_check ;
1260+
1261+ for (k = 0 ; k < slave -> sdca_data .num_functions ; k ++ ) {
1262+ int dai_type = asoc_sdw_get_dai_type (
1263+ slave -> sdca_data .function [k ].type );
1264+ dev_dbg (& slave -> dev , "function: %s dai_type %d\n" ,
1265+ slave -> sdca_data .function [k ].name , dai_type );
1266+ if (dai_type == dai_info -> dai_type ) {
1267+ dev_dbg (& slave -> dev , "DAI type %d found\n" ,
1268+ dai_type );
1269+ break ;
1270+ }
1271+ }
1272+ if (k == slave -> sdca_data .num_functions ) {
1273+ dev_dbg (& slave -> dev , "DAI type %d not found, skip endpoint\n" ,
1274+ dai_info -> dai_type );
1275+ continue ;
1276+ }
1277+ skip_sdca_function_check :
12071278 dev_dbg (dev ,
12081279 "Add dev: %d, 0x%llx end: %d, dai: %d, %c/%c to %s: %d\n" ,
12091280 ffs (adr_link -> mask ) - 1 , adr_dev -> adr ,
0 commit comments