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,106 @@ 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+
1154+ /*
1155+ * Check if the SDCA endpoint is present by the SDW peripheral
1156+ *
1157+ * @dev: Device pointer
1158+ * @codec_info: Codec info pointer
1159+ * @adr_link: ACPI link address
1160+ * @adr_index: Index of the ACPI link address
1161+ * @end_index: Index of the endpoint
1162+ *
1163+ * Return: 1 if the endpoint is present,
1164+ * 0 if the endpoint is not present,
1165+ * negative error code.
1166+ */
1167+
1168+ static int is_sdca_endpoint_present (struct device * dev ,
1169+ struct asoc_sdw_codec_info * codec_info ,
1170+ const struct snd_soc_acpi_link_adr * adr_link ,
1171+ int adr_index , int end_index )
1172+ {
1173+ const struct snd_soc_acpi_adr_device * adr_dev = & adr_link -> adr_d [adr_index ];
1174+ const struct snd_soc_acpi_endpoint * adr_end ;
1175+ const struct asoc_sdw_dai_info * dai_info ;
1176+ struct snd_soc_dai_link_component * dlc ;
1177+ struct snd_soc_dai * codec_dai ;
1178+ struct sdw_slave * slave ;
1179+ struct device * sdw_dev ;
1180+ const char * sdw_codec_name ;
1181+ int i ;
1182+
1183+ dlc = kzalloc (sizeof (* dlc ), GFP_KERNEL );
1184+
1185+ adr_end = & adr_dev -> endpoints [end_index ];
1186+ dai_info = & codec_info -> dais [adr_end -> num ];
1187+
1188+ dlc -> dai_name = dai_info -> dai_name ;
1189+ codec_dai = snd_soc_find_dai_with_mutex (dlc );
1190+ if (!codec_dai ) {
1191+ dev_warn (dev , "codec dai %s not registered yet\n" , dlc -> dai_name );
1192+ kfree (dlc );
1193+ return - EPROBE_DEFER ;
1194+ }
1195+ kfree (dlc );
1196+
1197+ sdw_codec_name = _asoc_sdw_get_codec_name (dev , codec_info ,
1198+ adr_link , adr_index );
1199+ if (!sdw_codec_name )
1200+ return - ENOMEM ;
1201+
1202+ sdw_dev = bus_find_device_by_name (& sdw_bus_type , NULL , sdw_codec_name );
1203+ if (!sdw_dev ) {
1204+ dev_err (dev , "codec %s not found\n" , sdw_codec_name );
1205+ return - EINVAL ;
1206+ }
1207+
1208+ slave = dev_to_sdw_dev (sdw_dev );
1209+ if (!slave )
1210+ return - EINVAL ;
1211+
1212+ /* Make sure BIOS provides SDCA properties */
1213+ if (!slave -> sdca_data .interface_revision ) {
1214+ dev_warn (& slave -> dev , "SDCA properties not found in the BIOS\n" );
1215+ return 1 ;
1216+ }
1217+
1218+ for (i = 0 ; i < slave -> sdca_data .num_functions ; i ++ ) {
1219+ int dai_type = asoc_sdw_get_dai_type (slave -> sdca_data .function [i ].type );
1220+
1221+ if (dai_type == dai_info -> dai_type ) {
1222+ dev_dbg (& slave -> dev , "DAI type %d sdca function %s found\n" ,
1223+ dai_type , slave -> sdca_data .function [i ].name );
1224+ return 1 ;
1225+ }
1226+ }
1227+
1228+ dev_dbg (& slave -> dev ,
1229+ "SDCA device function for DAI type %d not supported, skip endpoint\n" ,
1230+ dai_info -> dai_type );
1231+
1232+ return 0 ;
1233+ }
1234+
11341235int asoc_sdw_parse_sdw_endpoints (struct snd_soc_card * card ,
11351236 struct asoc_sdw_dailink * soc_dais ,
11361237 struct asoc_sdw_endpoint * soc_ends ,
@@ -1159,6 +1260,7 @@ int asoc_sdw_parse_sdw_endpoints(struct snd_soc_card *card,
11591260 const struct snd_soc_acpi_adr_device * adr_dev = & adr_link -> adr_d [i ];
11601261 struct asoc_sdw_codec_info * codec_info ;
11611262 const char * codec_name ;
1263+ bool check_sdca = false;
11621264
11631265 if (!adr_dev -> name_prefix ) {
11641266 dev_err (dev , "codec 0x%llx does not have a name prefix\n" ,
@@ -1189,6 +1291,9 @@ int asoc_sdw_parse_sdw_endpoints(struct snd_soc_card *card,
11891291 soc_end -> include_sidecar = true;
11901292 }
11911293
1294+ if (SDW_CLASS_ID (adr_dev -> adr ) && adr_dev -> num_endpoints > 1 )
1295+ check_sdca = true;
1296+
11921297 for (j = 0 ; j < adr_dev -> num_endpoints ; j ++ ) {
11931298 const struct snd_soc_acpi_endpoint * adr_end ;
11941299 const struct asoc_sdw_dai_info * dai_info ;
@@ -1203,6 +1308,22 @@ int asoc_sdw_parse_sdw_endpoints(struct snd_soc_card *card,
12031308 !(dai_info -> quirk_exclude ^ !!(dai_info -> quirk & ctx -> mc_quirk )))
12041309 continue ;
12051310
1311+ /*
1312+ * Skip the sdca endpoint presence check if machine quirk is set.
1313+ * In other words, quirk should have higher priority than the sdca
1314+ * properties in the BIOS.
1315+ */
1316+ if (check_sdca && !(dai_info -> quirk & ctx -> mc_quirk )) {
1317+ ret = is_sdca_endpoint_present (dev , codec_info ,
1318+ adr_link , i , j );
1319+ if (ret < 0 )
1320+ return ret ;
1321+
1322+ /* The endpoint is not present, skip */
1323+ if (!ret )
1324+ continue ;
1325+ }
1326+
12061327 dev_dbg (dev ,
12071328 "Add dev: %d, 0x%llx end: %d, dai: %d, %c/%c to %s: %d\n" ,
12081329 ffs (adr_link -> mask ) - 1 , adr_dev -> adr ,
0 commit comments