Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ASoC: SOF: topology: Add support for Mediatek AFE DAI

Add new sof dai and config to pass topology file configuration
to SOF firmware running on Mediatek platform DSP core.
Add mediatek audio front end(AFE) to the list of supported sof_dais

Signed-off-by: YC Hung <yc.hung@mediatek.com>
Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Reviewed-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
Reviewed-by: Daniel Baluta <daniel.baluta@nxp.com>
Signed-off-by: Daniel Baluta <daniel.baluta@nxp.com>
Link: https://lore.kernel.org/r/20211118100749.54628-4-daniel.baluta@oss.nxp.com
Signed-off-by: Mark Brown <broonie@kernel.org>

authored by

YC Hung and committed by
Mark Brown
b72bfcff e6feefa5

+97
+23
include/sound/sof/dai-mediatek.h
··· 1 + /* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */ 2 + /* 3 + * Copyright(c) 2021 Mediatek Corporation. All rights reserved. 4 + * 5 + * Author: Bo Pan <bo.pan@mediatek.com> 6 + */ 7 + 8 + #ifndef __INCLUDE_SOUND_SOF_DAI_MEDIATEK_H__ 9 + #define __INCLUDE_SOUND_SOF_DAI_MEDIATEK_H__ 10 + 11 + #include <sound/sof/header.h> 12 + 13 + struct sof_ipc_dai_mtk_afe_params { 14 + struct sof_ipc_hdr hdr; 15 + u32 channels; 16 + u32 rate; 17 + u32 format; 18 + u32 stream_id; 19 + u32 reserved[4]; /* reserve for future */ 20 + } __packed; 21 + 22 + #endif 23 +
+3
include/sound/sof/dai.h
··· 13 13 #include <sound/sof/dai-intel.h> 14 14 #include <sound/sof/dai-imx.h> 15 15 #include <sound/sof/dai-amd.h> 16 + #include <sound/sof/dai-mediatek.h> 16 17 17 18 /* 18 19 * DAI Configuration. ··· 71 70 SOF_DAI_AMD_BT, /**< AMD ACP BT*/ 72 71 SOF_DAI_AMD_SP, /**< AMD ACP SP */ 73 72 SOF_DAI_AMD_DMIC, /**< AMD ACP DMIC */ 73 + SOF_DAI_MEDIATEK_AFE, /**< Mediatek AFE */ 74 74 }; 75 75 76 76 /* general purpose DAI configuration */ ··· 99 97 struct sof_ipc_dai_acp_params acpbt; 100 98 struct sof_ipc_dai_acp_params acpsp; 101 99 struct sof_ipc_dai_acp_params acpdmic; 100 + struct sof_ipc_dai_mtk_afe_params afe; 102 101 }; 103 102 } __packed; 104 103
+12
sound/soc/sof/pcm.c
··· 814 814 "channels_min: %d channels_max: %d\n", 815 815 channels->min, channels->max); 816 816 break; 817 + case SOF_DAI_MEDIATEK_AFE: 818 + rate->min = dai->dai_config->afe.rate; 819 + rate->max = dai->dai_config->afe.rate; 820 + channels->min = dai->dai_config->afe.channels; 821 + channels->max = dai->dai_config->afe.channels; 822 + 823 + dev_dbg(component->dev, 824 + "rate_min: %d rate_max: %d\n", rate->min, rate->max); 825 + dev_dbg(component->dev, 826 + "channels_min: %d channels_max: %d\n", 827 + channels->min, channels->max); 828 + break; 817 829 case SOF_DAI_IMX_SAI: 818 830 rate->min = dai->dai_config->sai.fsync_rate; 819 831 rate->max = dai->dai_config->sai.fsync_rate;
+59
sound/soc/sof/topology.c
··· 379 379 {"ACP", SOF_DAI_AMD_BT}, 380 380 {"ACPSP", SOF_DAI_AMD_SP}, 381 381 {"ACPDMIC", SOF_DAI_AMD_DMIC}, 382 + {"AFE", SOF_DAI_MEDIATEK_AFE}, 382 383 }; 383 384 384 385 static enum sof_ipc_dai_type find_dai(const char *name) ··· 805 804 offsetof(struct snd_sof_led_control, use_led), 0}, 806 805 {SOF_TKN_MUTE_LED_DIRECTION, SND_SOC_TPLG_TUPLE_TYPE_WORD, 807 806 get_token_u32, offsetof(struct snd_sof_led_control, direction), 0}, 807 + }; 808 + 809 + /* AFE */ 810 + static const struct sof_topology_token afe_tokens[] = { 811 + {SOF_TKN_MEDIATEK_AFE_RATE, 812 + SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 813 + offsetof(struct sof_ipc_dai_mtk_afe_params, rate), 0}, 814 + {SOF_TKN_MEDIATEK_AFE_CH, 815 + SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 816 + offsetof(struct sof_ipc_dai_mtk_afe_params, channels), 0}, 817 + {SOF_TKN_MEDIATEK_AFE_FORMAT, 818 + SND_SOC_TPLG_TUPLE_TYPE_STRING, get_token_comp_format, 819 + offsetof(struct sof_ipc_dai_mtk_afe_params, format), 0}, 808 820 }; 809 821 810 822 static int sof_parse_uuid_tokens(struct snd_soc_component *scomp, ··· 3105 3091 return ret; 3106 3092 } 3107 3093 3094 + static int sof_link_afe_load(struct snd_soc_component *scomp, int index, 3095 + struct snd_soc_dai_link *link, 3096 + struct snd_soc_tplg_link_config *cfg, 3097 + struct snd_soc_tplg_hw_config *hw_config, 3098 + struct sof_ipc_dai_config *config) 3099 + { 3100 + struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); 3101 + struct snd_soc_tplg_private *private = &cfg->priv; 3102 + struct snd_soc_dai *dai; 3103 + u32 size = sizeof(*config); 3104 + int ret; 3105 + 3106 + config->hdr.size = size; 3107 + 3108 + /* get any bespoke DAI tokens */ 3109 + ret = sof_parse_tokens(scomp, &config->afe, afe_tokens, 3110 + ARRAY_SIZE(afe_tokens), private->array, 3111 + le32_to_cpu(private->size)); 3112 + if (ret != 0) { 3113 + dev_err(scomp->dev, "parse afe tokens failed %d\n", 3114 + le32_to_cpu(private->size)); 3115 + return ret; 3116 + } 3117 + 3118 + dev_dbg(scomp->dev, "AFE config rate %d channels %d format:%d\n", 3119 + config->afe.rate, config->afe.channels, config->afe.format); 3120 + 3121 + dai = snd_soc_find_dai(link->cpus); 3122 + if (!dai) { 3123 + dev_err(scomp->dev, "%s: failed to find dai %s", __func__, link->cpus->dai_name); 3124 + return -EINVAL; 3125 + } 3126 + 3127 + config->afe.stream_id = DMA_CHAN_INVALID; 3128 + 3129 + ret = sof_set_dai_config(sdev, size, link, config); 3130 + if (ret < 0) 3131 + dev_err(scomp->dev, "failed to process afe dai link %s", link->name); 3132 + 3133 + return ret; 3134 + } 3135 + 3108 3136 static int sof_link_dmic_load(struct snd_soc_component *scomp, int index, 3109 3137 struct snd_soc_dai_link *link, 3110 3138 struct snd_soc_tplg_link_config *cfg, ··· 3441 3385 case SOF_DAI_AMD_DMIC: 3442 3386 ret = sof_link_acp_dmic_load(scomp, index, link, cfg, hw_config + curr_conf, 3443 3387 config); 3388 + break; 3389 + case SOF_DAI_MEDIATEK_AFE: 3390 + ret = sof_link_afe_load(scomp, index, link, cfg, hw_config + curr_conf, config); 3444 3391 break; 3445 3392 default: 3446 3393 dev_err(scomp->dev, "error: invalid DAI type %d\n", common_config.type);