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 [] = {
@@ -1131,6 +1132,25 @@ struct asoc_sdw_dailink *asoc_sdw_find_dailink(struct asoc_sdw_dailink *dailinks
11311132}
11321133EXPORT_SYMBOL_NS (asoc_sdw_find_dailink , "SND_SOC_SDW_UTILS" );
11331134
1135+ static int asoc_sdw_get_dai_type (u32 type )
1136+ {
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+
11341154int asoc_sdw_parse_sdw_endpoints (struct snd_soc_card * card ,
11351155 struct asoc_sdw_dailink * soc_dais ,
11361156 struct asoc_sdw_endpoint * soc_ends ,
@@ -1142,8 +1162,10 @@ int asoc_sdw_parse_sdw_endpoints(struct snd_soc_card *card,
11421162 struct snd_soc_acpi_mach_params * mach_params = & mach -> mach_params ;
11431163 const struct snd_soc_acpi_link_adr * adr_link ;
11441164 struct asoc_sdw_endpoint * soc_end = soc_ends ;
1165+ struct snd_soc_dai_link_component dlc ;
1166+ struct snd_soc_dai * codec_dai ;
11451167 int num_dais = 0 ;
1146- int i , j ;
1168+ int i , j , k ;
11471169 int ret ;
11481170
11491171 for (adr_link = mach_params -> links ; adr_link -> num_adr ; adr_link ++ ) {
@@ -1193,6 +1215,9 @@ int asoc_sdw_parse_sdw_endpoints(struct snd_soc_card *card,
11931215 const struct snd_soc_acpi_endpoint * adr_end ;
11941216 const struct asoc_sdw_dai_info * dai_info ;
11951217 struct asoc_sdw_dailink * soc_dai ;
1218+ const char * sdw_codec_name ;
1219+ struct sdw_slave * slave ;
1220+ struct device * sdw_dev ;
11961221 int stream ;
11971222
11981223 adr_end = & adr_dev -> endpoints [j ];
@@ -1203,6 +1228,67 @@ int asoc_sdw_parse_sdw_endpoints(struct snd_soc_card *card,
12031228 !(dai_info -> quirk_exclude ^ !!(dai_info -> quirk & ctx -> mc_quirk )))
12041229 continue ;
12051230
1231+ /*
1232+ * No need to check SDCA functions if there is only 1 endpoint
1233+ * present.
1234+ */
1235+ if (adr_dev -> num_endpoints == 1 ) {
1236+ dev_dbg (dev ,
1237+ "%#llx: Only 1 endpoint with DAI type %d is found\n" ,
1238+ adr_dev -> adr , dai_info -> dai_type );
1239+ goto skip_sdca_function_check ;
1240+ }
1241+
1242+ dlc .dai_name = dai_info -> dai_name ;
1243+ codec_dai = snd_soc_find_dai_with_mutex (& dlc );
1244+ if (!codec_dai ) {
1245+ dev_warn (dev , "codec dai %s not registered yet\n" ,
1246+ dlc .dai_name );
1247+ return - EPROBE_DEFER ;
1248+ }
1249+
1250+ sdw_codec_name = _asoc_sdw_get_codec_name (dev , codec_info ,
1251+ adr_link , i );
1252+ if (!sdw_codec_name )
1253+ return - ENOMEM ;
1254+
1255+ sdw_dev = bus_find_device_by_name (& sdw_bus_type , NULL ,
1256+ sdw_codec_name );
1257+ if (!sdw_dev ) {
1258+ dev_err (dev , "codec %s not found\n" , sdw_codec_name );
1259+ return - EINVAL ;
1260+ }
1261+
1262+ slave = dev_to_sdw_dev (sdw_dev );
1263+ if (!slave )
1264+ return - EINVAL ;
1265+
1266+ /* Make sure BIOS provides SDCA properties */
1267+ if (!slave -> sdca_data .interface_revision ) {
1268+ dev_warn (& slave -> dev ,
1269+ "SDCA properties not found in the BIOS\n" );
1270+ goto skip_sdca_function_check ;
1271+ }
1272+
1273+ for (k = 0 ; k < slave -> sdca_data .num_functions ; k ++ ) {
1274+ int dai_type = asoc_sdw_get_dai_type (
1275+ slave -> sdca_data .function [k ].type );
1276+
1277+ if (dai_type == dai_info -> dai_type ) {
1278+ dev_dbg (& slave -> dev ,
1279+ "DAI type %d sdca function %s found\n" ,
1280+ dai_type ,
1281+ slave -> sdca_data .function [k ].name );
1282+ break ;
1283+ }
1284+ }
1285+ if (k == slave -> sdca_data .num_functions ) {
1286+ dev_dbg (& slave -> dev ,
1287+ "SDCA device function for DAI type %d not supported, skip endpoint\n" ,
1288+ dai_info -> dai_type );
1289+ continue ;
1290+ }
1291+ skip_sdca_function_check :
12061292 dev_dbg (dev ,
12071293 "Add dev: %d, 0x%llx end: %d, dai: %d, %c/%c to %s: %d\n" ,
12081294 ffs (adr_link -> mask ) - 1 , adr_dev -> adr ,
0 commit comments