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,62 @@ 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+ /* No need to check SDCA functions if there is only 1 endpoint present */
1232+ if (adr_dev -> num_endpoints == 1 ) {
1233+ dev_dbg (dev ,
1234+ "%#llx: Only 1 endpoint with DAI type %d is found\n" ,
1235+ adr_dev -> adr , dai_info -> dai_type );
1236+ goto skip_sdca_function_check ;
1237+ }
1238+
1239+ dlc .dai_name = dai_info -> dai_name ;
1240+ codec_dai = snd_soc_find_dai_with_mutex (& dlc );
1241+ if (!codec_dai ) {
1242+ dev_warn (dev , "codec dai %s not registered yet\n" ,
1243+ dlc .dai_name );
1244+ return - EPROBE_DEFER ;
1245+ }
1246+
1247+ sdw_codec_name = _asoc_sdw_get_codec_name (dev , codec_info , adr_link , i );
1248+ if (!sdw_codec_name )
1249+ return - ENOMEM ;
1250+
1251+ sdw_dev = bus_find_device_by_name (& sdw_bus_type , NULL , sdw_codec_name );
1252+ if (!sdw_dev ) {
1253+ dev_err (dev , "codec %s not found\n" , sdw_codec_name );
1254+ return - EINVAL ;
1255+ }
1256+
1257+ slave = dev_to_sdw_dev (sdw_dev );
1258+ if (!slave )
1259+ return - EINVAL ;
1260+
1261+ /* Make sure BIOS provides SDCA properties */
1262+ if (!slave -> sdca_data .interface_revision ) {
1263+ dev_warn (& slave -> dev ,
1264+ "SDCA properties not found in the BIOS\n" );
1265+ goto skip_sdca_function_check ;
1266+ }
1267+
1268+ for (k = 0 ; k < slave -> sdca_data .num_functions ; k ++ ) {
1269+ int dai_type = asoc_sdw_get_dai_type (
1270+ slave -> sdca_data .function [k ].type );
1271+
1272+ if (dai_type == dai_info -> dai_type ) {
1273+ dev_dbg (& slave -> dev ,
1274+ "DAI type %d sdca function %s found\n" ,
1275+ dai_type ,
1276+ slave -> sdca_data .function [k ].name );
1277+ break ;
1278+ }
1279+ }
1280+ if (k == slave -> sdca_data .num_functions ) {
1281+ dev_dbg (& slave -> dev ,
1282+ "SDCA device function for DAI type %d not supported, skip endpoint\n" ,
1283+ dai_info -> dai_type );
1284+ continue ;
1285+ }
1286+ skip_sdca_function_check :
12071287 dev_dbg (dev ,
12081288 "Add dev: %d, 0x%llx end: %d, dai: %d, %c/%c to %s: %d\n" ,
12091289 ffs (adr_link -> mask ) - 1 , adr_dev -> adr ,
0 commit comments