Skip to content

Commit

Permalink
ASoC: soc_sdw_utils: skip the endpoint that doesn't present
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
bardliao committed Sep 26, 2024
1 parent 7a40aaf commit 8cdf02c
Showing 1 changed file with 53 additions and 1 deletion.
54 changes: 53 additions & 1 deletion sound/soc/sdw_utils/soc_sdw_utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <linux/module.h>
#include <linux/soundwire/sdw.h>
#include <linux/soundwire/sdw_type.h>
#include <sound/sdca_function.h>
#include <sound/soc_sdw_utils.h>

static const struct snd_soc_dapm_widget generic_dmic_widgets[] = {
Expand Down Expand Up @@ -1051,6 +1052,24 @@ struct asoc_sdw_dailink *asoc_sdw_find_dailink(struct asoc_sdw_dailink *dailinks
}
EXPORT_SYMBOL_NS(asoc_sdw_find_dailink, SND_SOC_SDW_UTILS);

static int asoc_sdw_get_dai_type(u32 type) {
switch (type) {
case SDCA_FUNCTION_TYPE_SMART_AMP:
case SDCA_FUNCTION_TYPE_SIMPLE_AMP:
return SOC_SDW_DAI_TYPE_AMP;
case SDCA_FUNCTION_TYPE_SMART_MIC:
case SDCA_FUNCTION_TYPE_SIMPLE_MIC:
case SDCA_FUNCTION_TYPE_SPEAKER_MIC:
return SOC_SDW_DAI_TYPE_MIC;
case SDCA_FUNCTION_TYPE_UAJ:
case SDCA_FUNCTION_TYPE_RJ:
case SDCA_FUNCTION_TYPE_SIMPLE_JACK:
return SOC_SDW_DAI_TYPE_JACK;
default:
return -EINVAL;
}
}

int asoc_sdw_parse_sdw_endpoints(struct snd_soc_card *card,
struct asoc_sdw_dailink *soc_dais,
struct asoc_sdw_endpoint *soc_ends,
Expand All @@ -1062,8 +1081,10 @@ int asoc_sdw_parse_sdw_endpoints(struct snd_soc_card *card,
struct snd_soc_acpi_mach_params *mach_params = &mach->mach_params;
const struct snd_soc_acpi_link_adr *adr_link;
struct asoc_sdw_endpoint *soc_end = soc_ends;
struct snd_soc_dai_link_component dlc;
struct snd_soc_dai *codec_dai;
int num_dais = 0;
int i, j;
int i, j, k;
int ret;

for (adr_link = mach_params->links; adr_link->num_adr; adr_link++) {
Expand Down Expand Up @@ -1096,6 +1117,7 @@ int asoc_sdw_parse_sdw_endpoints(struct snd_soc_card *card,
if (!codec_name)
return -ENOMEM;

dlc.name = codec_name;
dev_dbg(dev, "Adding prefix %s for %s\n",
adr_dev->name_prefix, codec_name);

Expand All @@ -1113,6 +1135,7 @@ int asoc_sdw_parse_sdw_endpoints(struct snd_soc_card *card,
const struct snd_soc_acpi_endpoint *adr_end;
const struct asoc_sdw_dai_info *dai_info;
struct asoc_sdw_dailink *soc_dai;
struct sdw_slave *slave;
int stream;

adr_end = &adr_dev->endpoints[j];
Expand All @@ -1122,6 +1145,35 @@ int asoc_sdw_parse_sdw_endpoints(struct snd_soc_card *card,
if (dai_info->quirk && !(dai_info->quirk & ctx->mc_quirk))
continue;

dlc.dai_name = dai_info->dai_name;
codec_dai = snd_soc_find_dai_with_mutex(&dlc);
if (!codec_dai) {
dev_err(dev, "codec dai %s not registered yet\n",
dlc.dai_name);
return -EPROBE_DEFER;
}

slave = dev_to_sdw_dev(codec_dai->dev);
if (!slave)
return -EINVAL;

for (k = 0; k < slave->sdca_data.num_functions; k++) {
int dai_type = asoc_sdw_get_dai_type(
slave->sdca_data.sdca_func[k].type);
dev_dbg(&slave->dev, "function: %s dai_type %d\n",
slave->sdca_data.sdca_func[k].name, dai_type);
if (dai_type == dai_info->dai_type) {
dev_dbg(&slave->dev, "DAI type %d found\n",
dai_type);
break;
}
}
if (k == slave->sdca_data.num_functions) {
dev_dbg(&slave->dev, "DAI type %d not found, skip endpoint\n",
dai_info->dai_type);
continue;
}

dev_dbg(dev,
"Add dev: %d, 0x%llx end: %d, dai: %d, %c/%c to %s: %d\n",
ffs(adr_link->mask) - 1, adr_dev->adr,
Expand Down

0 comments on commit 8cdf02c

Please sign in to comment.