Skip to content

Commit cc6bdf1

Browse files
committed
ASoC: soc_sdw_utils: skip the endpoint that doesn't present
A codec endpoint may not be used. We could check the present SDCA functions to know if the endpoint is used or not. Skip the endpoint which is not used. Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
1 parent d7b5461 commit cc6bdf1

File tree

1 file changed

+72
-1
lines changed

1 file changed

+72
-1
lines changed

sound/soc/sdw_utils/soc_sdw_utils.c

Lines changed: 72 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
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

1516
static 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
}
11331134
EXPORT_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+
11351154
int 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

Comments
 (0)