Commit b72bfcff authored by YC Hung's avatar YC Hung Committed by Mark Brown

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: default avatarYC Hung <yc.hung@mediatek.com>
Reviewed-by: default avatarPéter Ujfalusi <peter.ujfalusi@linux.intel.com>
Reviewed-by: default avatarPierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: default avatarRanjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: default avatarKai Vehmanen <kai.vehmanen@linux.intel.com>
Reviewed-by: default avatarGuennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
Reviewed-by: default avatarDaniel Baluta <daniel.baluta@nxp.com>
Signed-off-by: default avatarDaniel Baluta <daniel.baluta@nxp.com>
Link: https://lore.kernel.org/r/20211118100749.54628-4-daniel.baluta@oss.nxp.comSigned-off-by: default avatarMark Brown <broonie@kernel.org>
parent e6feefa5
/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
/*
* Copyright(c) 2021 Mediatek Corporation. All rights reserved.
*
* Author: Bo Pan <bo.pan@mediatek.com>
*/
#ifndef __INCLUDE_SOUND_SOF_DAI_MEDIATEK_H__
#define __INCLUDE_SOUND_SOF_DAI_MEDIATEK_H__
#include <sound/sof/header.h>
struct sof_ipc_dai_mtk_afe_params {
struct sof_ipc_hdr hdr;
u32 channels;
u32 rate;
u32 format;
u32 stream_id;
u32 reserved[4]; /* reserve for future */
} __packed;
#endif
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include <sound/sof/dai-intel.h> #include <sound/sof/dai-intel.h>
#include <sound/sof/dai-imx.h> #include <sound/sof/dai-imx.h>
#include <sound/sof/dai-amd.h> #include <sound/sof/dai-amd.h>
#include <sound/sof/dai-mediatek.h>
/* /*
* DAI Configuration. * DAI Configuration.
...@@ -70,6 +71,7 @@ enum sof_ipc_dai_type { ...@@ -70,6 +71,7 @@ enum sof_ipc_dai_type {
SOF_DAI_AMD_BT, /**< AMD ACP BT*/ SOF_DAI_AMD_BT, /**< AMD ACP BT*/
SOF_DAI_AMD_SP, /**< AMD ACP SP */ SOF_DAI_AMD_SP, /**< AMD ACP SP */
SOF_DAI_AMD_DMIC, /**< AMD ACP DMIC */ SOF_DAI_AMD_DMIC, /**< AMD ACP DMIC */
SOF_DAI_MEDIATEK_AFE, /**< Mediatek AFE */
}; };
/* general purpose DAI configuration */ /* general purpose DAI configuration */
...@@ -97,6 +99,7 @@ struct sof_ipc_dai_config { ...@@ -97,6 +99,7 @@ struct sof_ipc_dai_config {
struct sof_ipc_dai_acp_params acpbt; struct sof_ipc_dai_acp_params acpbt;
struct sof_ipc_dai_acp_params acpsp; struct sof_ipc_dai_acp_params acpsp;
struct sof_ipc_dai_acp_params acpdmic; struct sof_ipc_dai_acp_params acpdmic;
struct sof_ipc_dai_mtk_afe_params afe;
}; };
} __packed; } __packed;
......
...@@ -808,6 +808,18 @@ int sof_pcm_dai_link_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_pa ...@@ -808,6 +808,18 @@ int sof_pcm_dai_link_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_pa
channels->min = dai->dai_config->esai.tdm_slots; channels->min = dai->dai_config->esai.tdm_slots;
channels->max = dai->dai_config->esai.tdm_slots; channels->max = dai->dai_config->esai.tdm_slots;
dev_dbg(component->dev,
"rate_min: %d rate_max: %d\n", rate->min, rate->max);
dev_dbg(component->dev,
"channels_min: %d channels_max: %d\n",
channels->min, channels->max);
break;
case SOF_DAI_MEDIATEK_AFE:
rate->min = dai->dai_config->afe.rate;
rate->max = dai->dai_config->afe.rate;
channels->min = dai->dai_config->afe.channels;
channels->max = dai->dai_config->afe.channels;
dev_dbg(component->dev, dev_dbg(component->dev,
"rate_min: %d rate_max: %d\n", rate->min, rate->max); "rate_min: %d rate_max: %d\n", rate->min, rate->max);
dev_dbg(component->dev, dev_dbg(component->dev,
......
...@@ -379,6 +379,7 @@ static const struct sof_dai_types sof_dais[] = { ...@@ -379,6 +379,7 @@ static const struct sof_dai_types sof_dais[] = {
{"ACP", SOF_DAI_AMD_BT}, {"ACP", SOF_DAI_AMD_BT},
{"ACPSP", SOF_DAI_AMD_SP}, {"ACPSP", SOF_DAI_AMD_SP},
{"ACPDMIC", SOF_DAI_AMD_DMIC}, {"ACPDMIC", SOF_DAI_AMD_DMIC},
{"AFE", SOF_DAI_MEDIATEK_AFE},
}; };
static enum sof_ipc_dai_type find_dai(const char *name) static enum sof_ipc_dai_type find_dai(const char *name)
...@@ -806,6 +807,19 @@ static const struct sof_topology_token led_tokens[] = { ...@@ -806,6 +807,19 @@ static const struct sof_topology_token led_tokens[] = {
get_token_u32, offsetof(struct snd_sof_led_control, direction), 0}, get_token_u32, offsetof(struct snd_sof_led_control, direction), 0},
}; };
/* AFE */
static const struct sof_topology_token afe_tokens[] = {
{SOF_TKN_MEDIATEK_AFE_RATE,
SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
offsetof(struct sof_ipc_dai_mtk_afe_params, rate), 0},
{SOF_TKN_MEDIATEK_AFE_CH,
SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
offsetof(struct sof_ipc_dai_mtk_afe_params, channels), 0},
{SOF_TKN_MEDIATEK_AFE_FORMAT,
SND_SOC_TPLG_TUPLE_TYPE_STRING, get_token_comp_format,
offsetof(struct sof_ipc_dai_mtk_afe_params, format), 0},
};
static int sof_parse_uuid_tokens(struct snd_soc_component *scomp, static int sof_parse_uuid_tokens(struct snd_soc_component *scomp,
void *object, void *object,
const struct sof_topology_token *tokens, const struct sof_topology_token *tokens,
...@@ -3091,6 +3105,48 @@ static int sof_link_acp_sp_load(struct snd_soc_component *scomp, int index, ...@@ -3091,6 +3105,48 @@ static int sof_link_acp_sp_load(struct snd_soc_component *scomp, int index,
return ret; return ret;
} }
static int sof_link_afe_load(struct snd_soc_component *scomp, int index,
struct snd_soc_dai_link *link,
struct snd_soc_tplg_link_config *cfg,
struct snd_soc_tplg_hw_config *hw_config,
struct sof_ipc_dai_config *config)
{
struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
struct snd_soc_tplg_private *private = &cfg->priv;
struct snd_soc_dai *dai;
u32 size = sizeof(*config);
int ret;
config->hdr.size = size;
/* get any bespoke DAI tokens */
ret = sof_parse_tokens(scomp, &config->afe, afe_tokens,
ARRAY_SIZE(afe_tokens), private->array,
le32_to_cpu(private->size));
if (ret != 0) {
dev_err(scomp->dev, "parse afe tokens failed %d\n",
le32_to_cpu(private->size));
return ret;
}
dev_dbg(scomp->dev, "AFE config rate %d channels %d format:%d\n",
config->afe.rate, config->afe.channels, config->afe.format);
dai = snd_soc_find_dai(link->cpus);
if (!dai) {
dev_err(scomp->dev, "%s: failed to find dai %s", __func__, link->cpus->dai_name);
return -EINVAL;
}
config->afe.stream_id = DMA_CHAN_INVALID;
ret = sof_set_dai_config(sdev, size, link, config);
if (ret < 0)
dev_err(scomp->dev, "failed to process afe dai link %s", link->name);
return ret;
}
static int sof_link_dmic_load(struct snd_soc_component *scomp, int index, static int sof_link_dmic_load(struct snd_soc_component *scomp, int index,
struct snd_soc_dai_link *link, struct snd_soc_dai_link *link,
struct snd_soc_tplg_link_config *cfg, struct snd_soc_tplg_link_config *cfg,
...@@ -3386,6 +3442,9 @@ static int sof_link_load(struct snd_soc_component *scomp, int index, ...@@ -3386,6 +3442,9 @@ static int sof_link_load(struct snd_soc_component *scomp, int index,
ret = sof_link_acp_dmic_load(scomp, index, link, cfg, hw_config + curr_conf, ret = sof_link_acp_dmic_load(scomp, index, link, cfg, hw_config + curr_conf,
config); config);
break; break;
case SOF_DAI_MEDIATEK_AFE:
ret = sof_link_afe_load(scomp, index, link, cfg, hw_config + curr_conf, config);
break;
default: default:
dev_err(scomp->dev, "error: invalid DAI type %d\n", common_config.type); dev_err(scomp->dev, "error: invalid DAI type %d\n", common_config.type);
ret = -EINVAL; ret = -EINVAL;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment