|
14 | 14 | #include <linux/soundwire/sdw_type.h> |
15 | 15 | #include <linux/soundwire/sdw_intel.h> |
16 | 16 | #include <sound/core.h> |
| 17 | +#include <sound/sdca.h> |
| 18 | +#include <sound/sdca_function.h> |
| 19 | +#include <sound/soc.h> |
17 | 20 | #include <sound/soc-acpi.h> |
18 | 21 | #include "sof_sdw_common.h" |
19 | 22 | #include "../../codecs/rt711.h" |
@@ -900,6 +903,23 @@ static const struct snd_soc_ops sdw_ops = { |
900 | 903 |
|
901 | 904 | static const char * const type_strings[] = {"SimpleJack", "SmartAmp", "SmartMic"}; |
902 | 905 |
|
| 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 | + |
903 | 923 | static int create_sdw_dailink(struct snd_soc_card *card, |
904 | 924 | struct asoc_sdw_dailink *sof_dai, |
905 | 925 | struct snd_soc_dai_link **dai_links, |
@@ -1011,12 +1031,69 @@ static int create_sdw_dailink(struct snd_soc_card *card, |
1011 | 1031 |
|
1012 | 1032 | codecs[j].name = sof_end->codec_name; |
1013 | 1033 | codecs[j].dai_name = sof_end->dai_info->dai_name; |
| 1034 | + |
1014 | 1035 | if (sof_end->dai_info->dai_type == SOC_SDW_DAI_TYPE_MIC && |
1015 | 1036 | mach_params->dmic_num > 0) { |
1016 | 1037 | dev_warn(dev, |
1017 | 1038 | "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"); |
1018 | 1039 | } |
1019 | 1040 | 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 | + |
| 1076 | + if (strstr(name, "ch")) |
| 1077 | + continue; |
| 1078 | + |
| 1079 | + if (sdw_mic_num != 1 && sdw_mic_num != 2 && |
| 1080 | + sdw_mic_num != 4 && sdw_mic_num != 8) { |
| 1081 | + dev_warn(dev, |
| 1082 | + "%s mic count %d is not supported\n", |
| 1083 | + sof_end->codec_name, sdw_mic_num); |
| 1084 | + continue; |
| 1085 | + } |
| 1086 | + |
| 1087 | + name = devm_kasprintf(dev, GFP_KERNEL, "%s-%dch", |
| 1088 | + name, sdw_mic_num); |
| 1089 | + if (!name) |
| 1090 | + return -ENOMEM; |
| 1091 | + |
| 1092 | + devm_kfree(dev, tmp); |
| 1093 | + break; |
| 1094 | + } |
| 1095 | + } |
| 1096 | + |
1020 | 1097 | } |
1021 | 1098 |
|
1022 | 1099 | WARN_ON(i != num_cpus || j != num_codecs); |
@@ -1582,3 +1659,4 @@ MODULE_AUTHOR("Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>"); |
1582 | 1659 | MODULE_LICENSE("GPL v2"); |
1583 | 1660 | MODULE_IMPORT_NS("SND_SOC_INTEL_HDA_DSP_COMMON"); |
1584 | 1661 | MODULE_IMPORT_NS("SND_SOC_SDW_UTILS"); |
| 1662 | +MODULE_IMPORT_NS("SND_SOC_SDCA"); |
0 commit comments