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,104 @@ 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 function 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
1169+ is_sdca_endpoint_present (struct device * dev ,
1170+ struct asoc_sdw_codec_info * codec_info ,
1171+ const struct snd_soc_acpi_link_adr * adr_link ,
1172+ int adr_index ,int end_index )
1173+ {
1174+ const struct snd_soc_acpi_adr_device * adr_dev = & adr_link -> adr_d [adr_index ];
1175+ const struct snd_soc_acpi_endpoint * adr_end ;
1176+ const struct asoc_sdw_dai_info * dai_info ;
1177+ struct snd_soc_dai_link_component dlc ;
1178+ struct snd_soc_dai * codec_dai ;
1179+ struct sdw_slave * slave ;
1180+ struct device * sdw_dev ;
1181+ const char * sdw_codec_name ;
1182+ int i ;
1183+
1184+ adr_end = & adr_dev -> endpoints [end_index ];
1185+ dai_info = & codec_info -> dais [adr_end -> num ];
1186+
1187+ dlc .dai_name = dai_info -> dai_name ;
1188+ codec_dai = snd_soc_find_dai_with_mutex (& dlc );
1189+ if (!codec_dai ) {
1190+ dev_warn (dev , "codec dai %s not registered yet\n" , dlc .dai_name );
1191+ return - EPROBE_DEFER ;
1192+ }
1193+
1194+ sdw_codec_name = _asoc_sdw_get_codec_name (dev , codec_info ,
1195+ adr_link , adr_index );
1196+ if (!sdw_codec_name )
1197+ return - ENOMEM ;
1198+
1199+ sdw_dev = bus_find_device_by_name (& sdw_bus_type , NULL , sdw_codec_name );
1200+ if (!sdw_dev ) {
1201+ dev_err (dev , "codec %s not found\n" , sdw_codec_name );
1202+ return - EINVAL ;
1203+ }
1204+
1205+ slave = dev_to_sdw_dev (sdw_dev );
1206+ if (!slave )
1207+ return - EINVAL ;
1208+
1209+ /* Make sure BIOS provides SDCA properties */
1210+ if (!slave -> sdca_data .interface_revision ) {
1211+ dev_warn (& slave -> dev , "SDCA properties not found in the BIOS\n" );
1212+ return 1 ;
1213+ }
1214+
1215+ for (i = 0 ; i < slave -> sdca_data .num_functions ; i ++ ) {
1216+ int dai_type = asoc_sdw_get_dai_type (
1217+ slave -> sdca_data .function [i ].type );
1218+
1219+ if (dai_type == dai_info -> dai_type ) {
1220+ dev_dbg (& slave -> dev , "DAI type %d sdca function %s found\n" ,
1221+ dai_type , slave -> sdca_data .function [i ].name );
1222+ return 1 ;
1223+ }
1224+ }
1225+
1226+ dev_dbg (& slave -> dev ,
1227+ "SDCA device function for DAI type %d not supported, skip endpoint\n" ,
1228+ dai_info -> dai_type );
1229+
1230+ return 0 ;
1231+ }
1232+
11341233int asoc_sdw_parse_sdw_endpoints (struct snd_soc_card * card ,
11351234 struct asoc_sdw_dailink * soc_dais ,
11361235 struct asoc_sdw_endpoint * soc_ends ,
@@ -1159,6 +1258,7 @@ int asoc_sdw_parse_sdw_endpoints(struct snd_soc_card *card,
11591258 const struct snd_soc_acpi_adr_device * adr_dev = & adr_link -> adr_d [i ];
11601259 struct asoc_sdw_codec_info * codec_info ;
11611260 const char * codec_name ;
1261+ bool check_sdca = false;
11621262
11631263 if (!adr_dev -> name_prefix ) {
11641264 dev_err (dev , "codec 0x%llx does not have a name prefix\n" ,
@@ -1189,6 +1289,9 @@ int asoc_sdw_parse_sdw_endpoints(struct snd_soc_card *card,
11891289 soc_end -> include_sidecar = true;
11901290 }
11911291
1292+ if (SDW_CLASS_ID (adr_dev -> adr ) && adr_dev -> num_endpoints > 1 )
1293+ check_sdca = true;
1294+
11921295 for (j = 0 ; j < adr_dev -> num_endpoints ; j ++ ) {
11931296 const struct snd_soc_acpi_endpoint * adr_end ;
11941297 const struct asoc_sdw_dai_info * dai_info ;
@@ -1203,6 +1306,22 @@ int asoc_sdw_parse_sdw_endpoints(struct snd_soc_card *card,
12031306 !(dai_info -> quirk_exclude ^ !!(dai_info -> quirk & ctx -> mc_quirk )))
12041307 continue ;
12051308
1309+ /*
1310+ * Don't check is sdca endpoint present if machine quirk is set
1311+ * In other words, quirk should have higher priority than the sdca
1312+ * properties in the BIOS.
1313+ */
1314+ if (check_sdca && !(dai_info -> quirk & ctx -> mc_quirk )) {
1315+ ret = is_sdca_endpoint_present (dev , codec_info ,
1316+ adr_link , i , j );
1317+ if (ret < 0 )
1318+ return ret ;
1319+
1320+ /* The endpoint is not present, skip */
1321+ if (!ret )
1322+ continue ;
1323+ }
1324+
12061325 dev_dbg (dev ,
12071326 "Add dev: %d, 0x%llx end: %d, dai: %d, %c/%c to %s: %d\n" ,
12081327 ffs (adr_link -> mask ) - 1 , adr_dev -> adr ,
0 commit comments