Lines Matching +full:codec +full:- +full:aif2
1 // SPDX-License-Identifier: GPL-2.0-only
6 * soc-sdw-utils.c - common SoundWire machine driver helper functions
65 .dai_name = "rt700-aif1",
83 .dai_name = "rt711-sdca-aif1",
103 .dai_name = "rt711-aif1",
123 .dai_name = "rt712-sdca-aif1",
136 .dai_name = "rt712-sdca-aif2",
149 .dai_name = "rt712-sdca-aif3",
163 .dai_name = "rt712-sdca-dmic-aif1",
177 .dai_name = "rt712-sdca-aif1",
190 .dai_name = "rt712-sdca-aif3",
204 .dai_name = "rt712-sdca-dmic-aif1",
218 .dai_name = "rt1308-aif",
238 .dai_name = "rt1316-aif",
257 .dai_name = "rt1318-aif",
276 .dai_name = "rt1320-aif1",
297 .dai_name = "rt715-sdca-aif2",
312 .dai_name = "rt715-sdca-aif2",
327 .dai_name = "rt715-aif2",
342 .dai_name = "rt715-aif2",
356 .dai_name = "rt721-sdca-aif1",
369 .dai_name = "rt721-sdca-aif2",
371 /* No feedback capability is provided by rt721-sdca codec driver*/
383 .dai_name = "rt721-sdca-aif3",
397 .dai_name = "rt722-sdca-aif1",
410 .dai_name = "rt722-sdca-aif2",
412 /* No feedback capability is provided by rt722-sdca codec driver*/
426 .dai_name = "rt722-sdca-aif3",
439 .dai_name = "max98373-aif1",
457 .dai_name = "max98363-aif1",
475 .dai_name = "rt5682-sdw",
492 .dai_name = "cs35l56-sdw1",
510 .dai_name = "cs42l42-sdw",
524 .codec_name = "cs42l43-codec",
530 .dai_name = "cs42l43-dp5",
541 .dai_name = "cs42l43-dp1",
552 .dai_name = "cs42l43-dp2",
558 .dai_name = "cs42l43-dp6",
573 .part_id = 0xaaaa, /* generic codec mockup */
578 .dai_name = "sdw-mockup-aif1",
586 .part_id = 0xaa55, /* headset codec mockup */
591 .dai_name = "sdw-mockup-aif1",
604 .dai_name = "sdw-mockup-aif1",
616 .dai_name = "sdw-mockup-aif1",
642 * A codec info is for all sdw version with the part id if in asoc_sdw_find_codec_info_part()
643 * version_id is not specified in the codec info. in asoc_sdw_find_codec_info_part()
688 struct snd_soc_card *card = rtd->card; in asoc_sdw_rtd_init()
696 codec_info = asoc_sdw_find_codec_info_dai(dai->name, &dai_index); in asoc_sdw_rtd_init()
698 return -EINVAL; in asoc_sdw_rtd_init()
701 * A codec dai can be connected to different dai links for capture and playback, in asoc_sdw_rtd_init()
703 * The rtd_init for each codec dai is independent. So, the order of rtd_init in asoc_sdw_rtd_init()
706 if (codec_info->dais[dai_index].rtd_init_done) in asoc_sdw_rtd_init()
710 * Add card controls and dapm widgets for the first codec dai. in asoc_sdw_rtd_init()
711 * The controls and widgets will be used for all codec dais. in asoc_sdw_rtd_init()
717 if (codec_info->dais[dai_index].controls) { in asoc_sdw_rtd_init()
718 ret = snd_soc_add_card_controls(card, codec_info->dais[dai_index].controls, in asoc_sdw_rtd_init()
719 codec_info->dais[dai_index].num_controls); in asoc_sdw_rtd_init()
721 dev_err(card->dev, "%#x controls addition failed: %d\n", in asoc_sdw_rtd_init()
722 codec_info->part_id, ret); in asoc_sdw_rtd_init()
726 if (codec_info->dais[dai_index].widgets) { in asoc_sdw_rtd_init()
727 ret = snd_soc_dapm_new_controls(&card->dapm, in asoc_sdw_rtd_init()
728 codec_info->dais[dai_index].widgets, in asoc_sdw_rtd_init()
729 codec_info->dais[dai_index].num_widgets); in asoc_sdw_rtd_init()
731 dev_err(card->dev, "%#x widgets addition failed: %d\n", in asoc_sdw_rtd_init()
732 codec_info->part_id, ret); in asoc_sdw_rtd_init()
738 if (codec_info->dais[dai_index].rtd_init) { in asoc_sdw_rtd_init()
739 ret = codec_info->dais[dai_index].rtd_init(rtd, dai); in asoc_sdw_rtd_init()
743 codec_info->dais[dai_index].rtd_init_done = true; in asoc_sdw_rtd_init()
766 sdw_stream = snd_soc_dai_get_stream(dai, substream->stream); in asoc_sdw_prepare()
768 dev_err(rtd->dev, "no stream found for DAI %s\n", dai->name); in asoc_sdw_prepare()
786 sdw_stream = snd_soc_dai_get_stream(dai, substream->stream); in asoc_sdw_trigger()
788 dev_err(rtd->dev, "no stream found for DAI %s\n", dai->name); in asoc_sdw_trigger()
805 ret = -EINVAL; in asoc_sdw_trigger()
810 dev_err(rtd->dev, "%s trigger %d failed: %d\n", __func__, cmd, ret); in asoc_sdw_trigger()
827 if (!rtd->dai_link->ch_maps) in asoc_sdw_hw_params()
831 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { in asoc_sdw_hw_params()
832 ch_mask = GENMASK(ch - 1, 0); in asoc_sdw_hw_params()
835 num_codecs = rtd->dai_link->num_codecs; in asoc_sdw_hw_params()
838 dev_err(rtd->dev, "Channels number %d is invalid when codec number = %d\n", in asoc_sdw_hw_params()
840 return -EINVAL; in asoc_sdw_hw_params()
843 ch_mask = GENMASK(ch / num_codecs - 1, 0); in asoc_sdw_hw_params()
849 * link has more than one codec DAIs. Set codec channel mask and in asoc_sdw_hw_params()
852 for_each_link_ch_maps(rtd->dai_link, i, ch_maps) in asoc_sdw_hw_params()
853 ch_maps->ch_mask = ch_mask << (i * step); in asoc_sdw_hw_params()
868 sdw_stream = snd_soc_dai_get_stream(dai, substream->stream); in asoc_sdw_hw_free()
870 dev_err(rtd->dev, "no stream found for DAI %s\n", dai->name); in asoc_sdw_hw_free()
893 for (i = 0; i < adr_link->num_adr; i++) { in asoc_sdw_is_unique_device()
901 adr = adr_link->adr_d[i].adr; in asoc_sdw_is_unique_device()
923 u64 adr = adr_link->adr_d[adr_index].adr; in asoc_sdw_get_codec_name()
931 if (codec_info->codec_name) in asoc_sdw_get_codec_name()
932 return devm_kstrdup(dev, codec_info->codec_name, GFP_KERNEL); in asoc_sdw_get_codec_name()
945 /* helper to get the link that the codec DAI is used */
954 for (j = 0; j < dai_link->num_codecs; j++) { in asoc_sdw_mc_find_codec_dai_used()
955 /* Check each codec in a link */ in asoc_sdw_mc_find_codec_dai_used()
956 if (!strcmp(dai_link->codecs[j].dai_name, dai_name)) in asoc_sdw_mc_find_codec_dai_used()
971 for (i = 0; i < ctx->codec_info_list_count; i++) { in asoc_sdw_mc_dailink_exit_loop()
984 /* Do the .exit function if the codec dai is used in the link */ in asoc_sdw_mc_dailink_exit_loop()
987 dev_warn(card->dev, in asoc_sdw_mc_dailink_exit_loop()
988 "codec exit failed %d\n", in asoc_sdw_mc_dailink_exit_loop()
1023 dai_links->id = (*be_id)++; in asoc_sdw_init_dai_link()
1024 dai_links->name = name; in asoc_sdw_init_dai_link()
1025 dai_links->stream_name = name; in asoc_sdw_init_dai_link()
1026 dai_links->platforms = platform_component; in asoc_sdw_init_dai_link()
1027 dai_links->num_platforms = num_platforms; in asoc_sdw_init_dai_link()
1028 dai_links->no_pcm = no_pcm; in asoc_sdw_init_dai_link()
1029 dai_links->cpus = cpus; in asoc_sdw_init_dai_link()
1030 dai_links->num_cpus = cpus_num; in asoc_sdw_init_dai_link()
1031 dai_links->codecs = codecs; in asoc_sdw_init_dai_link()
1032 dai_links->num_codecs = codecs_num; in asoc_sdw_init_dai_link()
1033 dai_links->playback_only = playback && !capture; in asoc_sdw_init_dai_link()
1034 dai_links->capture_only = !playback && capture; in asoc_sdw_init_dai_link()
1035 dai_links->init = init; in asoc_sdw_init_dai_link()
1036 dai_links->ops = ops; in asoc_sdw_init_dai_link()
1050 /* Allocate three DLCs one for the CPU, one for platform and one for the CODEC */ in asoc_sdw_init_simple_dai_link()
1053 return -ENOMEM; in asoc_sdw_init_simple_dai_link()
1071 struct device *dev = card->dev; in asoc_sdw_count_sdw_endpoints()
1073 struct snd_soc_acpi_mach_params *mach_params = &mach->mach_params; in asoc_sdw_count_sdw_endpoints()
1077 for (adr_link = mach_params->links; adr_link->num_adr; adr_link++) { in asoc_sdw_count_sdw_endpoints()
1078 *num_devs += adr_link->num_adr; in asoc_sdw_count_sdw_endpoints()
1080 for (i = 0; i < adr_link->num_adr; i++) in asoc_sdw_count_sdw_endpoints()
1081 *num_ends += adr_link->adr_d[i].num_endpoints; in asoc_sdw_count_sdw_endpoints()
1093 while (dailinks->initialised) { in asoc_sdw_find_dailink()
1094 if (new->aggregated && dailinks->group_id == new->group_id) in asoc_sdw_find_dailink()
1100 INIT_LIST_HEAD(&dailinks->endpoints); in asoc_sdw_find_dailink()
1101 dailinks->group_id = new->group_id; in asoc_sdw_find_dailink()
1102 dailinks->initialised = true; in asoc_sdw_find_dailink()
1113 struct device *dev = card->dev; in asoc_sdw_parse_sdw_endpoints()
1116 struct snd_soc_acpi_mach_params *mach_params = &mach->mach_params; in asoc_sdw_parse_sdw_endpoints()
1123 for (adr_link = mach_params->links; adr_link->num_adr; adr_link++) { in asoc_sdw_parse_sdw_endpoints()
1126 if (!is_power_of_2(adr_link->mask)) { in asoc_sdw_parse_sdw_endpoints()
1128 adr_link->mask); in asoc_sdw_parse_sdw_endpoints()
1129 return -EINVAL; in asoc_sdw_parse_sdw_endpoints()
1132 for (i = 0; i < adr_link->num_adr; i++) { in asoc_sdw_parse_sdw_endpoints()
1133 const struct snd_soc_acpi_adr_device *adr_dev = &adr_link->adr_d[i]; in asoc_sdw_parse_sdw_endpoints()
1137 if (!adr_dev->name_prefix) { in asoc_sdw_parse_sdw_endpoints()
1138 dev_err(dev, "codec 0x%llx does not have a name prefix\n", in asoc_sdw_parse_sdw_endpoints()
1139 adr_dev->adr); in asoc_sdw_parse_sdw_endpoints()
1140 return -EINVAL; in asoc_sdw_parse_sdw_endpoints()
1143 codec_info = asoc_sdw_find_codec_info_part(adr_dev->adr); in asoc_sdw_parse_sdw_endpoints()
1145 return -EINVAL; in asoc_sdw_parse_sdw_endpoints()
1147 ctx->ignore_internal_dmic |= codec_info->ignore_internal_dmic; in asoc_sdw_parse_sdw_endpoints()
1151 return -ENOMEM; in asoc_sdw_parse_sdw_endpoints()
1154 adr_dev->name_prefix, codec_name); in asoc_sdw_parse_sdw_endpoints()
1156 soc_end->name_prefix = adr_dev->name_prefix; in asoc_sdw_parse_sdw_endpoints()
1158 if (codec_info->count_sidecar && codec_info->add_sidecar) { in asoc_sdw_parse_sdw_endpoints()
1159 ret = codec_info->count_sidecar(card, &num_dais, num_devs); in asoc_sdw_parse_sdw_endpoints()
1163 soc_end->include_sidecar = true; in asoc_sdw_parse_sdw_endpoints()
1166 for (j = 0; j < adr_dev->num_endpoints; j++) { in asoc_sdw_parse_sdw_endpoints()
1172 adr_end = &adr_dev->endpoints[j]; in asoc_sdw_parse_sdw_endpoints()
1173 dai_info = &codec_info->dais[adr_end->num]; in asoc_sdw_parse_sdw_endpoints()
1176 if (dai_info->quirk && in asoc_sdw_parse_sdw_endpoints()
1177 !(dai_info->quirk_exclude ^ !!(dai_info->quirk & ctx->mc_quirk))) in asoc_sdw_parse_sdw_endpoints()
1182 ffs(adr_link->mask) - 1, adr_dev->adr, in asoc_sdw_parse_sdw_endpoints()
1183 adr_end->num, dai_info->dai_type, in asoc_sdw_parse_sdw_endpoints()
1184 dai_info->direction[SNDRV_PCM_STREAM_PLAYBACK] ? 'P' : '-', in asoc_sdw_parse_sdw_endpoints()
1185 dai_info->direction[SNDRV_PCM_STREAM_CAPTURE] ? 'C' : '-', in asoc_sdw_parse_sdw_endpoints()
1186 adr_end->aggregated ? "group" : "solo", in asoc_sdw_parse_sdw_endpoints()
1187 adr_end->group_id); in asoc_sdw_parse_sdw_endpoints()
1189 if (adr_end->num >= codec_info->dai_num) { in asoc_sdw_parse_sdw_endpoints()
1191 "%d is too many endpoints for codec: 0x%x\n", in asoc_sdw_parse_sdw_endpoints()
1192 adr_end->num, codec_info->part_id); in asoc_sdw_parse_sdw_endpoints()
1193 return -EINVAL; in asoc_sdw_parse_sdw_endpoints()
1197 if (dai_info->direction[stream] && in asoc_sdw_parse_sdw_endpoints()
1198 dai_info->dailink[stream] < 0) { in asoc_sdw_parse_sdw_endpoints()
1200 "Invalid dailink id %d for codec: 0x%x\n", in asoc_sdw_parse_sdw_endpoints()
1201 dai_info->dailink[stream], in asoc_sdw_parse_sdw_endpoints()
1202 codec_info->part_id); in asoc_sdw_parse_sdw_endpoints()
1203 return -EINVAL; in asoc_sdw_parse_sdw_endpoints()
1206 if (dai_info->direction[stream]) { in asoc_sdw_parse_sdw_endpoints()
1207 num_dais += !soc_dai->num_devs[stream]; in asoc_sdw_parse_sdw_endpoints()
1208 soc_dai->num_devs[stream]++; in asoc_sdw_parse_sdw_endpoints()
1209 soc_dai->link_mask[stream] |= adr_link->mask; in asoc_sdw_parse_sdw_endpoints()
1213 num_link_dailinks += !!list_empty(&soc_dai->endpoints); in asoc_sdw_parse_sdw_endpoints()
1214 list_add_tail(&soc_end->list, &soc_dai->endpoints); in asoc_sdw_parse_sdw_endpoints()
1216 soc_end->link_mask = adr_link->mask; in asoc_sdw_parse_sdw_endpoints()
1217 soc_end->codec_name = codec_name; in asoc_sdw_parse_sdw_endpoints()
1218 soc_end->codec_info = codec_info; in asoc_sdw_parse_sdw_endpoints()
1219 soc_end->dai_info = dai_info; in asoc_sdw_parse_sdw_endpoints()
1224 ctx->append_dai_type |= (num_link_dailinks > 1); in asoc_sdw_parse_sdw_endpoints()