Lines Matching +full:codec +full:- +full:aif3

1 // SPDX-License-Identifier: GPL-2.0-only
6 * soc-sdw-utils.c - common SoundWire machine driver helper functions
66 .dai_name = "rt700-aif1",
84 .dai_name = "rt711-sdca-aif1",
104 .dai_name = "rt711-aif1",
124 .dai_name = "rt712-sdca-aif1",
137 .dai_name = "rt712-sdca-aif2",
151 .dai_name = "rt712-sdca-aif3",
165 .dai_name = "rt712-sdca-dmic-aif1",
179 .dai_name = "rt712-sdca-aif1",
192 .dai_name = "rt712-sdca-aif3",
206 .dai_name = "rt712-sdca-dmic-aif1",
220 .dai_name = "rt1308-aif",
241 .dai_name = "rt1316-aif",
261 .dai_name = "rt1318-aif",
281 .dai_name = "rt1320-aif1",
303 .dai_name = "rt715-sdca-aif2",
318 .dai_name = "rt715-sdca-aif2",
333 .dai_name = "rt715-aif2",
348 .dai_name = "rt715-aif2",
362 .dai_name = "rt721-sdca-aif1",
375 .dai_name = "rt721-sdca-aif2",
378 /* No feedback capability is provided by rt721-sdca codec driver*/
390 .dai_name = "rt721-sdca-aif3",
404 .dai_name = "rt722-sdca-aif1",
417 .dai_name = "rt722-sdca-aif2",
420 /* No feedback capability is provided by rt722-sdca codec driver*/
434 .dai_name = "rt722-sdca-aif3",
447 .dai_name = "max98373-aif1",
466 .dai_name = "max98363-aif1",
485 .dai_name = "rt5682-sdw",
502 .dai_name = "cs35l56-sdw1",
515 .dai_name = "cs35l56-sdw1c",
528 .dai_name = "cs35l56-sdw1",
541 .dai_name = "cs35l56-sdw1c",
554 .dai_name = "cs42l42-sdw",
568 .codec_name = "cs42l43-codec",
574 .dai_name = "cs42l43-dp5",
585 .dai_name = "cs42l43-dp1",
596 .dai_name = "cs42l43-dp2",
602 .dai_name = "cs42l43-dp6",
618 .part_id = 0xaaaa, /* generic codec mockup */
623 .dai_name = "sdw-mockup-aif1",
629 .dai_name = "sdw-mockup-aif1",
635 .dai_name = "sdw-mockup-aif1",
643 .part_id = 0xaa55, /* headset codec mockup */
648 .dai_name = "sdw-mockup-aif1",
661 .dai_name = "sdw-mockup-aif1",
673 .dai_name = "sdw-mockup-aif1",
699 * A codec info is for all sdw version with the part id if in asoc_sdw_find_codec_info_part()
700 * version_id is not specified in the codec info. in asoc_sdw_find_codec_info_part()
745 struct snd_soc_card *card = rtd->card; in asoc_sdw_rtd_init()
754 codec_info = asoc_sdw_find_codec_info_dai(dai->name, &dai_index); in asoc_sdw_rtd_init()
756 return -EINVAL; in asoc_sdw_rtd_init()
759 * A codec dai can be connected to different dai links for capture and playback, in asoc_sdw_rtd_init()
761 * The rtd_init for each codec dai is independent. So, the order of rtd_init in asoc_sdw_rtd_init()
764 if (codec_info->dais[dai_index].rtd_init_done) in asoc_sdw_rtd_init()
768 * Add card controls and dapm widgets for the first codec dai. in asoc_sdw_rtd_init()
769 * The controls and widgets will be used for all codec dais. in asoc_sdw_rtd_init()
775 if (codec_info->dais[dai_index].controls) { in asoc_sdw_rtd_init()
776 ret = snd_soc_add_card_controls(card, codec_info->dais[dai_index].controls, in asoc_sdw_rtd_init()
777 codec_info->dais[dai_index].num_controls); in asoc_sdw_rtd_init()
779 dev_err(card->dev, "%#x controls addition failed: %d\n", in asoc_sdw_rtd_init()
780 codec_info->part_id, ret); in asoc_sdw_rtd_init()
784 if (codec_info->dais[dai_index].widgets) { in asoc_sdw_rtd_init()
785 ret = snd_soc_dapm_new_controls(&card->dapm, in asoc_sdw_rtd_init()
786 codec_info->dais[dai_index].widgets, in asoc_sdw_rtd_init()
787 codec_info->dais[dai_index].num_widgets); in asoc_sdw_rtd_init()
789 dev_err(card->dev, "%#x widgets addition failed: %d\n", in asoc_sdw_rtd_init()
790 codec_info->part_id, ret); in asoc_sdw_rtd_init()
796 if (codec_info->dais[dai_index].rtd_init) { in asoc_sdw_rtd_init()
797 ret = codec_info->dais[dai_index].rtd_init(rtd, dai); in asoc_sdw_rtd_init()
802 /* Generate the spk component string for card->components string */ in asoc_sdw_rtd_init()
803 if (codec_info->dais[dai_index].dai_type == SOC_SDW_DAI_TYPE_AMP && in asoc_sdw_rtd_init()
804 codec_info->dais[dai_index].component_name) { in asoc_sdw_rtd_init()
807 devm_kasprintf(card->dev, GFP_KERNEL, "%s", in asoc_sdw_rtd_init()
808 codec_info->dais[dai_index].component_name); in asoc_sdw_rtd_init()
812 devm_kasprintf(card->dev, GFP_KERNEL, in asoc_sdw_rtd_init()
814 codec_info->dais[dai_index].component_name); in asoc_sdw_rtd_init()
817 codec_info->dais[dai_index].rtd_init_done = true; in asoc_sdw_rtd_init()
823 card->components = devm_kasprintf(card->dev, GFP_KERNEL, "%s spk:%s", in asoc_sdw_rtd_init()
824 card->components, spk_components); in asoc_sdw_rtd_init()
825 if (!card->components) in asoc_sdw_rtd_init()
826 return -ENOMEM; in asoc_sdw_rtd_init()
849 sdw_stream = snd_soc_dai_get_stream(dai, substream->stream); in asoc_sdw_prepare()
851 dev_err(rtd->dev, "no stream found for DAI %s\n", dai->name); in asoc_sdw_prepare()
869 sdw_stream = snd_soc_dai_get_stream(dai, substream->stream); in asoc_sdw_trigger()
871 dev_err(rtd->dev, "no stream found for DAI %s\n", dai->name); in asoc_sdw_trigger()
888 ret = -EINVAL; in asoc_sdw_trigger()
893 dev_err(rtd->dev, "%s trigger %d failed: %d\n", __func__, cmd, ret); in asoc_sdw_trigger()
910 if (!rtd->dai_link->ch_maps) in asoc_sdw_hw_params()
914 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { in asoc_sdw_hw_params()
915 ch_mask = GENMASK(ch - 1, 0); in asoc_sdw_hw_params()
918 num_codecs = rtd->dai_link->num_codecs; in asoc_sdw_hw_params()
921 dev_err(rtd->dev, "Channels number %d is invalid when codec number = %d\n", in asoc_sdw_hw_params()
923 return -EINVAL; in asoc_sdw_hw_params()
926 ch_mask = GENMASK(ch / num_codecs - 1, 0); in asoc_sdw_hw_params()
932 * link has more than one codec DAIs. Set codec channel mask and in asoc_sdw_hw_params()
935 for_each_link_ch_maps(rtd->dai_link, i, ch_maps) in asoc_sdw_hw_params()
936 ch_maps->ch_mask = ch_mask << (i * step); in asoc_sdw_hw_params()
951 sdw_stream = snd_soc_dai_get_stream(dai, substream->stream); in asoc_sdw_hw_free()
953 dev_err(rtd->dev, "no stream found for DAI %s\n", dai->name); in asoc_sdw_hw_free()
976 for (i = 0; i < adr_link->num_adr; i++) { in asoc_sdw_is_unique_device()
984 adr = adr_link->adr_d[i].adr; in asoc_sdw_is_unique_device()
1006 u64 adr = adr_link->adr_d[adr_index].adr; in _asoc_sdw_get_codec_name()
1028 if (codec_info->codec_name) in asoc_sdw_get_codec_name()
1029 return devm_kstrdup(dev, codec_info->codec_name, GFP_KERNEL); in asoc_sdw_get_codec_name()
1035 /* helper to get the link that the codec DAI is used */
1044 for (j = 0; j < dai_link->num_codecs; j++) { in asoc_sdw_mc_find_codec_dai_used()
1045 /* Check each codec in a link */ in asoc_sdw_mc_find_codec_dai_used()
1046 if (!strcmp(dai_link->codecs[j].dai_name, dai_name)) in asoc_sdw_mc_find_codec_dai_used()
1061 for (i = 0; i < ctx->codec_info_list_count; i++) { in asoc_sdw_mc_dailink_exit_loop()
1074 /* Do the .exit function if the codec dai is used in the link */ in asoc_sdw_mc_dailink_exit_loop()
1077 dev_warn(card->dev, in asoc_sdw_mc_dailink_exit_loop()
1078 "codec exit failed %d\n", in asoc_sdw_mc_dailink_exit_loop()
1113 dai_links->id = (*be_id)++; in asoc_sdw_init_dai_link()
1114 dai_links->name = name; in asoc_sdw_init_dai_link()
1115 dai_links->stream_name = name; in asoc_sdw_init_dai_link()
1116 dai_links->platforms = platform_component; in asoc_sdw_init_dai_link()
1117 dai_links->num_platforms = num_platforms; in asoc_sdw_init_dai_link()
1118 dai_links->no_pcm = no_pcm; in asoc_sdw_init_dai_link()
1119 dai_links->cpus = cpus; in asoc_sdw_init_dai_link()
1120 dai_links->num_cpus = cpus_num; in asoc_sdw_init_dai_link()
1121 dai_links->codecs = codecs; in asoc_sdw_init_dai_link()
1122 dai_links->num_codecs = codecs_num; in asoc_sdw_init_dai_link()
1123 dai_links->playback_only = playback && !capture; in asoc_sdw_init_dai_link()
1124 dai_links->capture_only = !playback && capture; in asoc_sdw_init_dai_link()
1125 dai_links->init = init; in asoc_sdw_init_dai_link()
1126 dai_links->ops = ops; in asoc_sdw_init_dai_link()
1139 /* Allocate three DLCs one for the CPU, one for platform and one for the CODEC */ in asoc_sdw_init_simple_dai_link()
1142 return -ENOMEM; in asoc_sdw_init_simple_dai_link()
1160 struct device *dev = card->dev; in asoc_sdw_count_sdw_endpoints()
1162 struct snd_soc_acpi_mach_params *mach_params = &mach->mach_params; in asoc_sdw_count_sdw_endpoints()
1166 for (adr_link = mach_params->links; adr_link->num_adr; adr_link++) { in asoc_sdw_count_sdw_endpoints()
1167 *num_devs += adr_link->num_adr; in asoc_sdw_count_sdw_endpoints()
1169 for (i = 0; i < adr_link->num_adr; i++) in asoc_sdw_count_sdw_endpoints()
1170 *num_ends += adr_link->adr_d[i].num_endpoints; in asoc_sdw_count_sdw_endpoints()
1182 while (dailinks->initialised) { in asoc_sdw_find_dailink()
1183 if (new->aggregated && dailinks->group_id == new->group_id) in asoc_sdw_find_dailink()
1189 INIT_LIST_HEAD(&dailinks->endpoints); in asoc_sdw_find_dailink()
1190 dailinks->group_id = new->group_id; in asoc_sdw_find_dailink()
1191 dailinks->initialised = true; in asoc_sdw_find_dailink()
1212 return -EINVAL; in asoc_sdw_get_dai_type()
1220 * @codec_info: Codec info pointer
1235 const struct snd_soc_acpi_adr_device *adr_dev = &adr_link->adr_d[adr_index]; in is_sdca_endpoint_present()
1247 return -ENOMEM; in is_sdca_endpoint_present()
1249 adr_end = &adr_dev->endpoints[end_index]; in is_sdca_endpoint_present()
1250 dai_info = &codec_info->dais[adr_end->num]; in is_sdca_endpoint_present()
1252 dlc->dai_name = dai_info->dai_name; in is_sdca_endpoint_present()
1255 dev_warn(dev, "codec dai %s not registered yet\n", dlc->dai_name); in is_sdca_endpoint_present()
1257 return -EPROBE_DEFER; in is_sdca_endpoint_present()
1264 return -ENOMEM; in is_sdca_endpoint_present()
1268 dev_err(dev, "codec %s not found\n", sdw_codec_name); in is_sdca_endpoint_present()
1269 return -EINVAL; in is_sdca_endpoint_present()
1274 return -EINVAL; in is_sdca_endpoint_present()
1277 if (!slave->sdca_data.interface_revision) { in is_sdca_endpoint_present()
1278 dev_warn(&slave->dev, "SDCA properties not found in the BIOS\n"); in is_sdca_endpoint_present()
1282 for (i = 0; i < slave->sdca_data.num_functions; i++) { in is_sdca_endpoint_present()
1283 int dai_type = asoc_sdw_get_dai_type(slave->sdca_data.function[i].type); in is_sdca_endpoint_present()
1285 if (dai_type == dai_info->dai_type) { in is_sdca_endpoint_present()
1286 dev_dbg(&slave->dev, "DAI type %d sdca function %s found\n", in is_sdca_endpoint_present()
1287 dai_type, slave->sdca_data.function[i].name); in is_sdca_endpoint_present()
1292 dev_dbg(&slave->dev, in is_sdca_endpoint_present()
1294 dai_info->dai_type); in is_sdca_endpoint_present()
1304 struct device *dev = card->dev; in asoc_sdw_parse_sdw_endpoints()
1307 struct snd_soc_acpi_mach_params *mach_params = &mach->mach_params; in asoc_sdw_parse_sdw_endpoints()
1314 for (adr_link = mach_params->links; adr_link->num_adr; adr_link++) { in asoc_sdw_parse_sdw_endpoints()
1317 if (!is_power_of_2(adr_link->mask)) { in asoc_sdw_parse_sdw_endpoints()
1319 adr_link->mask); in asoc_sdw_parse_sdw_endpoints()
1320 return -EINVAL; in asoc_sdw_parse_sdw_endpoints()
1323 for (i = 0; i < adr_link->num_adr; i++) { in asoc_sdw_parse_sdw_endpoints()
1324 const struct snd_soc_acpi_adr_device *adr_dev = &adr_link->adr_d[i]; in asoc_sdw_parse_sdw_endpoints()
1329 if (!adr_dev->name_prefix) { in asoc_sdw_parse_sdw_endpoints()
1330 dev_err(dev, "codec 0x%llx does not have a name prefix\n", in asoc_sdw_parse_sdw_endpoints()
1331 adr_dev->adr); in asoc_sdw_parse_sdw_endpoints()
1332 return -EINVAL; in asoc_sdw_parse_sdw_endpoints()
1335 codec_info = asoc_sdw_find_codec_info_part(adr_dev->adr); in asoc_sdw_parse_sdw_endpoints()
1337 return -EINVAL; in asoc_sdw_parse_sdw_endpoints()
1339 ctx->ignore_internal_dmic |= codec_info->ignore_internal_dmic; in asoc_sdw_parse_sdw_endpoints()
1343 return -ENOMEM; in asoc_sdw_parse_sdw_endpoints()
1346 adr_dev->name_prefix, codec_name); in asoc_sdw_parse_sdw_endpoints()
1348 soc_end->name_prefix = adr_dev->name_prefix; in asoc_sdw_parse_sdw_endpoints()
1350 if (codec_info->count_sidecar && codec_info->add_sidecar) { in asoc_sdw_parse_sdw_endpoints()
1351 ret = codec_info->count_sidecar(card, &num_dais, num_devs); in asoc_sdw_parse_sdw_endpoints()
1355 soc_end->include_sidecar = true; in asoc_sdw_parse_sdw_endpoints()
1358 if (SDW_CLASS_ID(adr_dev->adr) && adr_dev->num_endpoints > 1) in asoc_sdw_parse_sdw_endpoints()
1361 for (j = 0; j < adr_dev->num_endpoints; j++) { in asoc_sdw_parse_sdw_endpoints()
1367 adr_end = &adr_dev->endpoints[j]; in asoc_sdw_parse_sdw_endpoints()
1368 dai_info = &codec_info->dais[adr_end->num]; in asoc_sdw_parse_sdw_endpoints()
1375 * information. The endpoint will be skipped if the dai_info-> in asoc_sdw_parse_sdw_endpoints()
1382 if (dai_info->quirk & ctx->mc_quirk || !check_sdca) { in asoc_sdw_parse_sdw_endpoints()
1387 if (dai_info->quirk && in asoc_sdw_parse_sdw_endpoints()
1388 !(dai_info->quirk_exclude ^ !!(dai_info->quirk & ctx->mc_quirk))) in asoc_sdw_parse_sdw_endpoints()
1391 /* Check SDCA codec endpoint if there is no matching quirk */ in asoc_sdw_parse_sdw_endpoints()
1403 ffs(adr_link->mask) - 1, adr_dev->adr, in asoc_sdw_parse_sdw_endpoints()
1404 adr_end->num, dai_info->dai_type, in asoc_sdw_parse_sdw_endpoints()
1405 dai_info->direction[SNDRV_PCM_STREAM_PLAYBACK] ? 'P' : '-', in asoc_sdw_parse_sdw_endpoints()
1406 dai_info->direction[SNDRV_PCM_STREAM_CAPTURE] ? 'C' : '-', in asoc_sdw_parse_sdw_endpoints()
1407 adr_end->aggregated ? "group" : "solo", in asoc_sdw_parse_sdw_endpoints()
1408 adr_end->group_id); in asoc_sdw_parse_sdw_endpoints()
1410 if (adr_end->num >= codec_info->dai_num) { in asoc_sdw_parse_sdw_endpoints()
1412 "%d is too many endpoints for codec: 0x%x\n", in asoc_sdw_parse_sdw_endpoints()
1413 adr_end->num, codec_info->part_id); in asoc_sdw_parse_sdw_endpoints()
1414 return -EINVAL; in asoc_sdw_parse_sdw_endpoints()
1418 if (dai_info->direction[stream] && in asoc_sdw_parse_sdw_endpoints()
1419 dai_info->dailink[stream] < 0) { in asoc_sdw_parse_sdw_endpoints()
1421 "Invalid dailink id %d for codec: 0x%x\n", in asoc_sdw_parse_sdw_endpoints()
1422 dai_info->dailink[stream], in asoc_sdw_parse_sdw_endpoints()
1423 codec_info->part_id); in asoc_sdw_parse_sdw_endpoints()
1424 return -EINVAL; in asoc_sdw_parse_sdw_endpoints()
1427 if (dai_info->direction[stream]) { in asoc_sdw_parse_sdw_endpoints()
1428 num_dais += !soc_dai->num_devs[stream]; in asoc_sdw_parse_sdw_endpoints()
1429 soc_dai->num_devs[stream]++; in asoc_sdw_parse_sdw_endpoints()
1430 soc_dai->link_mask[stream] |= adr_link->mask; in asoc_sdw_parse_sdw_endpoints()
1434 num_link_dailinks += !!list_empty(&soc_dai->endpoints); in asoc_sdw_parse_sdw_endpoints()
1435 list_add_tail(&soc_end->list, &soc_dai->endpoints); in asoc_sdw_parse_sdw_endpoints()
1437 soc_end->link_mask = adr_link->mask; in asoc_sdw_parse_sdw_endpoints()
1438 soc_end->codec_name = codec_name; in asoc_sdw_parse_sdw_endpoints()
1439 soc_end->codec_info = codec_info; in asoc_sdw_parse_sdw_endpoints()
1440 soc_end->dai_info = dai_info; in asoc_sdw_parse_sdw_endpoints()
1445 ctx->append_dai_type |= (num_link_dailinks > 1); in asoc_sdw_parse_sdw_endpoints()