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",
504 .dai_name = "cs35l56-sdw1c",
517 .dai_name = "cs42l42-sdw",
531 .codec_name = "cs42l43-codec",
537 .dai_name = "cs42l43-dp5",
548 .dai_name = "cs42l43-dp1",
559 .dai_name = "cs42l43-dp2",
565 .dai_name = "cs42l43-dp6",
580 .part_id = 0xaaaa, /* generic codec mockup */
585 .dai_name = "sdw-mockup-aif1",
593 .part_id = 0xaa55, /* headset codec mockup */
598 .dai_name = "sdw-mockup-aif1",
611 .dai_name = "sdw-mockup-aif1",
623 .dai_name = "sdw-mockup-aif1",
649 * A codec info is for all sdw version with the part id if in asoc_sdw_find_codec_info_part()
650 * version_id is not specified in the codec info. in asoc_sdw_find_codec_info_part()
695 struct snd_soc_card *card = rtd->card; in asoc_sdw_rtd_init()
703 codec_info = asoc_sdw_find_codec_info_dai(dai->name, &dai_index); in asoc_sdw_rtd_init()
705 return -EINVAL; in asoc_sdw_rtd_init()
708 * A codec dai can be connected to different dai links for capture and playback, in asoc_sdw_rtd_init()
710 * The rtd_init for each codec dai is independent. So, the order of rtd_init in asoc_sdw_rtd_init()
713 if (codec_info->dais[dai_index].rtd_init_done) in asoc_sdw_rtd_init()
717 * Add card controls and dapm widgets for the first codec dai. in asoc_sdw_rtd_init()
718 * The controls and widgets will be used for all codec dais. in asoc_sdw_rtd_init()
724 if (codec_info->dais[dai_index].controls) { in asoc_sdw_rtd_init()
725 ret = snd_soc_add_card_controls(card, codec_info->dais[dai_index].controls, in asoc_sdw_rtd_init()
726 codec_info->dais[dai_index].num_controls); in asoc_sdw_rtd_init()
728 dev_err(card->dev, "%#x controls addition failed: %d\n", in asoc_sdw_rtd_init()
729 codec_info->part_id, ret); in asoc_sdw_rtd_init()
733 if (codec_info->dais[dai_index].widgets) { in asoc_sdw_rtd_init()
734 ret = snd_soc_dapm_new_controls(&card->dapm, in asoc_sdw_rtd_init()
735 codec_info->dais[dai_index].widgets, in asoc_sdw_rtd_init()
736 codec_info->dais[dai_index].num_widgets); in asoc_sdw_rtd_init()
738 dev_err(card->dev, "%#x widgets addition failed: %d\n", in asoc_sdw_rtd_init()
739 codec_info->part_id, ret); in asoc_sdw_rtd_init()
745 if (codec_info->dais[dai_index].rtd_init) { in asoc_sdw_rtd_init()
746 ret = codec_info->dais[dai_index].rtd_init(rtd, dai); in asoc_sdw_rtd_init()
750 codec_info->dais[dai_index].rtd_init_done = true; in asoc_sdw_rtd_init()
773 sdw_stream = snd_soc_dai_get_stream(dai, substream->stream); in asoc_sdw_prepare()
775 dev_err(rtd->dev, "no stream found for DAI %s\n", dai->name); in asoc_sdw_prepare()
793 sdw_stream = snd_soc_dai_get_stream(dai, substream->stream); in asoc_sdw_trigger()
795 dev_err(rtd->dev, "no stream found for DAI %s\n", dai->name); in asoc_sdw_trigger()
812 ret = -EINVAL; in asoc_sdw_trigger()
817 dev_err(rtd->dev, "%s trigger %d failed: %d\n", __func__, cmd, ret); in asoc_sdw_trigger()
834 if (!rtd->dai_link->ch_maps) in asoc_sdw_hw_params()
838 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { in asoc_sdw_hw_params()
839 ch_mask = GENMASK(ch - 1, 0); in asoc_sdw_hw_params()
842 num_codecs = rtd->dai_link->num_codecs; in asoc_sdw_hw_params()
845 dev_err(rtd->dev, "Channels number %d is invalid when codec number = %d\n", in asoc_sdw_hw_params()
847 return -EINVAL; in asoc_sdw_hw_params()
850 ch_mask = GENMASK(ch / num_codecs - 1, 0); in asoc_sdw_hw_params()
856 * link has more than one codec DAIs. Set codec channel mask and in asoc_sdw_hw_params()
859 for_each_link_ch_maps(rtd->dai_link, i, ch_maps) in asoc_sdw_hw_params()
860 ch_maps->ch_mask = ch_mask << (i * step); in asoc_sdw_hw_params()
875 sdw_stream = snd_soc_dai_get_stream(dai, substream->stream); in asoc_sdw_hw_free()
877 dev_err(rtd->dev, "no stream found for DAI %s\n", dai->name); in asoc_sdw_hw_free()
900 for (i = 0; i < adr_link->num_adr; i++) { in asoc_sdw_is_unique_device()
908 adr = adr_link->adr_d[i].adr; in asoc_sdw_is_unique_device()
930 u64 adr = adr_link->adr_d[adr_index].adr; in asoc_sdw_get_codec_name()
938 if (codec_info->codec_name) in asoc_sdw_get_codec_name()
939 return devm_kstrdup(dev, codec_info->codec_name, GFP_KERNEL); in asoc_sdw_get_codec_name()
952 /* helper to get the link that the codec DAI is used */
961 for (j = 0; j < dai_link->num_codecs; j++) { in asoc_sdw_mc_find_codec_dai_used()
962 /* Check each codec in a link */ in asoc_sdw_mc_find_codec_dai_used()
963 if (!strcmp(dai_link->codecs[j].dai_name, dai_name)) in asoc_sdw_mc_find_codec_dai_used()
978 for (i = 0; i < ctx->codec_info_list_count; i++) { in asoc_sdw_mc_dailink_exit_loop()
991 /* Do the .exit function if the codec dai is used in the link */ in asoc_sdw_mc_dailink_exit_loop()
994 dev_warn(card->dev, in asoc_sdw_mc_dailink_exit_loop()
995 "codec exit failed %d\n", in asoc_sdw_mc_dailink_exit_loop()
1030 dai_links->id = (*be_id)++; in asoc_sdw_init_dai_link()
1031 dai_links->name = name; in asoc_sdw_init_dai_link()
1032 dai_links->stream_name = name; in asoc_sdw_init_dai_link()
1033 dai_links->platforms = platform_component; in asoc_sdw_init_dai_link()
1034 dai_links->num_platforms = num_platforms; in asoc_sdw_init_dai_link()
1035 dai_links->no_pcm = no_pcm; in asoc_sdw_init_dai_link()
1036 dai_links->cpus = cpus; in asoc_sdw_init_dai_link()
1037 dai_links->num_cpus = cpus_num; in asoc_sdw_init_dai_link()
1038 dai_links->codecs = codecs; in asoc_sdw_init_dai_link()
1039 dai_links->num_codecs = codecs_num; in asoc_sdw_init_dai_link()
1040 dai_links->playback_only = playback && !capture; in asoc_sdw_init_dai_link()
1041 dai_links->capture_only = !playback && capture; in asoc_sdw_init_dai_link()
1042 dai_links->init = init; in asoc_sdw_init_dai_link()
1043 dai_links->ops = ops; in asoc_sdw_init_dai_link()
1057 /* Allocate three DLCs one for the CPU, one for platform and one for the CODEC */ in asoc_sdw_init_simple_dai_link()
1060 return -ENOMEM; in asoc_sdw_init_simple_dai_link()
1078 struct device *dev = card->dev; in asoc_sdw_count_sdw_endpoints()
1080 struct snd_soc_acpi_mach_params *mach_params = &mach->mach_params; in asoc_sdw_count_sdw_endpoints()
1084 for (adr_link = mach_params->links; adr_link->num_adr; adr_link++) { in asoc_sdw_count_sdw_endpoints()
1085 *num_devs += adr_link->num_adr; in asoc_sdw_count_sdw_endpoints()
1087 for (i = 0; i < adr_link->num_adr; i++) in asoc_sdw_count_sdw_endpoints()
1088 *num_ends += adr_link->adr_d[i].num_endpoints; in asoc_sdw_count_sdw_endpoints()
1100 while (dailinks->initialised) { in asoc_sdw_find_dailink()
1101 if (new->aggregated && dailinks->group_id == new->group_id) in asoc_sdw_find_dailink()
1107 INIT_LIST_HEAD(&dailinks->endpoints); in asoc_sdw_find_dailink()
1108 dailinks->group_id = new->group_id; in asoc_sdw_find_dailink()
1109 dailinks->initialised = true; in asoc_sdw_find_dailink()
1120 struct device *dev = card->dev; in asoc_sdw_parse_sdw_endpoints()
1123 struct snd_soc_acpi_mach_params *mach_params = &mach->mach_params; in asoc_sdw_parse_sdw_endpoints()
1130 for (adr_link = mach_params->links; adr_link->num_adr; adr_link++) { in asoc_sdw_parse_sdw_endpoints()
1133 if (!is_power_of_2(adr_link->mask)) { in asoc_sdw_parse_sdw_endpoints()
1135 adr_link->mask); in asoc_sdw_parse_sdw_endpoints()
1136 return -EINVAL; in asoc_sdw_parse_sdw_endpoints()
1139 for (i = 0; i < adr_link->num_adr; i++) { in asoc_sdw_parse_sdw_endpoints()
1140 const struct snd_soc_acpi_adr_device *adr_dev = &adr_link->adr_d[i]; in asoc_sdw_parse_sdw_endpoints()
1144 if (!adr_dev->name_prefix) { in asoc_sdw_parse_sdw_endpoints()
1145 dev_err(dev, "codec 0x%llx does not have a name prefix\n", in asoc_sdw_parse_sdw_endpoints()
1146 adr_dev->adr); in asoc_sdw_parse_sdw_endpoints()
1147 return -EINVAL; in asoc_sdw_parse_sdw_endpoints()
1150 codec_info = asoc_sdw_find_codec_info_part(adr_dev->adr); in asoc_sdw_parse_sdw_endpoints()
1152 return -EINVAL; in asoc_sdw_parse_sdw_endpoints()
1154 ctx->ignore_internal_dmic |= codec_info->ignore_internal_dmic; in asoc_sdw_parse_sdw_endpoints()
1158 return -ENOMEM; in asoc_sdw_parse_sdw_endpoints()
1161 adr_dev->name_prefix, codec_name); in asoc_sdw_parse_sdw_endpoints()
1163 soc_end->name_prefix = adr_dev->name_prefix; in asoc_sdw_parse_sdw_endpoints()
1165 if (codec_info->count_sidecar && codec_info->add_sidecar) { in asoc_sdw_parse_sdw_endpoints()
1166 ret = codec_info->count_sidecar(card, &num_dais, num_devs); in asoc_sdw_parse_sdw_endpoints()
1170 soc_end->include_sidecar = true; in asoc_sdw_parse_sdw_endpoints()
1173 for (j = 0; j < adr_dev->num_endpoints; j++) { in asoc_sdw_parse_sdw_endpoints()
1179 adr_end = &adr_dev->endpoints[j]; in asoc_sdw_parse_sdw_endpoints()
1180 dai_info = &codec_info->dais[adr_end->num]; in asoc_sdw_parse_sdw_endpoints()
1183 if (dai_info->quirk && in asoc_sdw_parse_sdw_endpoints()
1184 !(dai_info->quirk_exclude ^ !!(dai_info->quirk & ctx->mc_quirk))) in asoc_sdw_parse_sdw_endpoints()
1189 ffs(adr_link->mask) - 1, adr_dev->adr, in asoc_sdw_parse_sdw_endpoints()
1190 adr_end->num, dai_info->dai_type, in asoc_sdw_parse_sdw_endpoints()
1191 dai_info->direction[SNDRV_PCM_STREAM_PLAYBACK] ? 'P' : '-', in asoc_sdw_parse_sdw_endpoints()
1192 dai_info->direction[SNDRV_PCM_STREAM_CAPTURE] ? 'C' : '-', in asoc_sdw_parse_sdw_endpoints()
1193 adr_end->aggregated ? "group" : "solo", in asoc_sdw_parse_sdw_endpoints()
1194 adr_end->group_id); in asoc_sdw_parse_sdw_endpoints()
1196 if (adr_end->num >= codec_info->dai_num) { in asoc_sdw_parse_sdw_endpoints()
1198 "%d is too many endpoints for codec: 0x%x\n", in asoc_sdw_parse_sdw_endpoints()
1199 adr_end->num, codec_info->part_id); in asoc_sdw_parse_sdw_endpoints()
1200 return -EINVAL; in asoc_sdw_parse_sdw_endpoints()
1204 if (dai_info->direction[stream] && in asoc_sdw_parse_sdw_endpoints()
1205 dai_info->dailink[stream] < 0) { in asoc_sdw_parse_sdw_endpoints()
1207 "Invalid dailink id %d for codec: 0x%x\n", in asoc_sdw_parse_sdw_endpoints()
1208 dai_info->dailink[stream], in asoc_sdw_parse_sdw_endpoints()
1209 codec_info->part_id); in asoc_sdw_parse_sdw_endpoints()
1210 return -EINVAL; in asoc_sdw_parse_sdw_endpoints()
1213 if (dai_info->direction[stream]) { in asoc_sdw_parse_sdw_endpoints()
1214 num_dais += !soc_dai->num_devs[stream]; in asoc_sdw_parse_sdw_endpoints()
1215 soc_dai->num_devs[stream]++; in asoc_sdw_parse_sdw_endpoints()
1216 soc_dai->link_mask[stream] |= adr_link->mask; in asoc_sdw_parse_sdw_endpoints()
1220 num_link_dailinks += !!list_empty(&soc_dai->endpoints); in asoc_sdw_parse_sdw_endpoints()
1221 list_add_tail(&soc_end->list, &soc_dai->endpoints); in asoc_sdw_parse_sdw_endpoints()
1223 soc_end->link_mask = adr_link->mask; in asoc_sdw_parse_sdw_endpoints()
1224 soc_end->codec_name = codec_name; in asoc_sdw_parse_sdw_endpoints()
1225 soc_end->codec_info = codec_info; in asoc_sdw_parse_sdw_endpoints()
1226 soc_end->dai_info = dai_info; in asoc_sdw_parse_sdw_endpoints()
1231 ctx->append_dai_type |= (num_link_dailinks > 1); in asoc_sdw_parse_sdw_endpoints()