Skip to content

Commit 5656b76

Browse files
committed
ASoC: Intel: sof_sdw: get sdw dmic number
The commit get the sdca sdw dmic number form the mipi-sdca-cluster-channel-id property. The dai link name will be used to select the function topology with a proper dmic channel number. Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
1 parent dae132d commit 5656b76

1 file changed

Lines changed: 69 additions & 0 deletions

File tree

sound/soc/intel/boards/sof_sdw.c

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@
1414
#include <linux/soundwire/sdw_type.h>
1515
#include <linux/soundwire/sdw_intel.h>
1616
#include <sound/core.h>
17+
#include <sound/sdca.h>
18+
#include <sound/sdca_function.h>
19+
#include <sound/soc.h>
1720
#include <sound/soc-acpi.h>
1821
#include "sof_sdw_common.h"
1922
#include "../../codecs/rt711.h"
@@ -900,6 +903,23 @@ static const struct snd_soc_ops sdw_ops = {
900903

901904
static const char * const type_strings[] = {"SimpleJack", "SmartAmp", "SmartMic"};
902905

906+
static struct sdw_slave *sof_sdw_get_peripheral_by_codec_name(const char *codec_name)
907+
{
908+
struct snd_soc_component *component;
909+
910+
component = snd_soc_lookup_component_by_name(codec_name);
911+
if (!component)
912+
return NULL;
913+
914+
if (is_sdw_slave(component->dev))
915+
return dev_to_sdw_dev(component->dev);
916+
917+
if (component->dev->parent && is_sdw_slave(component->dev->parent))
918+
return dev_to_sdw_dev(component->dev->parent);
919+
920+
return NULL;
921+
}
922+
903923
static int create_sdw_dailink(struct snd_soc_card *card,
904924
struct asoc_sdw_dailink *sof_dai,
905925
struct snd_soc_dai_link **dai_links,
@@ -1011,12 +1031,60 @@ static int create_sdw_dailink(struct snd_soc_card *card,
10111031

10121032
codecs[j].name = sof_end->codec_name;
10131033
codecs[j].dai_name = sof_end->dai_info->dai_name;
1034+
10141035
if (sof_end->dai_info->dai_type == SOC_SDW_DAI_TYPE_MIC &&
10151036
mach_params->dmic_num > 0) {
10161037
dev_warn(dev,
10171038
"Both SDW DMIC and PCH DMIC are present, if incorrect, please set kernel params snd_sof_intel_hda_generic dmic_num=0 to disable PCH DMIC\n");
10181039
}
10191040
j++;
1041+
1042+
if (sof_end->dai_info->dai_type == SOC_SDW_DAI_TYPE_MIC) {
1043+
struct sdw_slave *peripheral;
1044+
const char *codec_name = sof_end->codec_name;
1045+
int sdw_mic_num;
1046+
int k;
1047+
1048+
peripheral = sof_sdw_get_peripheral_by_codec_name(codec_name);
1049+
if (!peripheral) {
1050+
/*
1051+
* asoc_sdw_parse_sdw_endpoints() is already checked
1052+
* peripheral is not NULL, so this should never happen.
1053+
*/
1054+
dev_err(dev, "Can't get peripheral for codec %s\n",
1055+
sof_end->codec_name);
1056+
return -EINVAL;
1057+
}
1058+
1059+
for (k = 0; k < peripheral->sdca_data.num_functions; k++) {
1060+
struct sdca_function_desc *function =
1061+
&peripheral->sdca_data.function[k];
1062+
char *tmp = name;
1063+
1064+
if (function->type != SDCA_FUNCTION_TYPE_SMART_MIC)
1065+
continue;
1066+
1067+
sdw_mic_num = sdca_get_mic_count(peripheral, function);
1068+
if (sdw_mic_num < 0) {
1069+
dev_dbg(dev, "%s mic count query failed: %d\n",
1070+
sof_end->codec_name, sdw_mic_num);
1071+
continue;
1072+
}
1073+
dev_dbg(dev, "%s mic num %d\n",
1074+
sof_end->codec_name, sdw_mic_num);
1075+
if (sdw_mic_num <= 0 || strstr(name, "ch"))
1076+
continue;
1077+
1078+
name = devm_kasprintf(dev, GFP_KERNEL, "%s-%dch",
1079+
name, sdw_mic_num);
1080+
if (!name)
1081+
return -ENOMEM;
1082+
1083+
devm_kfree(dev, tmp);
1084+
break;
1085+
}
1086+
}
1087+
10201088
}
10211089

10221090
WARN_ON(i != num_cpus || j != num_codecs);
@@ -1582,3 +1650,4 @@ MODULE_AUTHOR("Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>");
15821650
MODULE_LICENSE("GPL v2");
15831651
MODULE_IMPORT_NS("SND_SOC_INTEL_HDA_DSP_COMMON");
15841652
MODULE_IMPORT_NS("SND_SOC_SDW_UTILS");
1653+
MODULE_IMPORT_NS("SND_SOC_SDCA");

0 commit comments

Comments
 (0)