summaryrefslogtreecommitdiff
path: root/sound/soc
diff options
context:
space:
mode:
authorAjit Kumar Pandey <AjitKumar.Pandey@amd.com>2021-11-17 11:37:24 +0200
committerMark Brown <broonie@kernel.org>2021-11-17 17:35:54 +0000
commitefb931cdc4b94a0f7ed17a76844f08cef1bdffe5 (patch)
tree9fea3536efeecd70f12b5070d19c0a6373552edc /sound/soc
parent63fba90fc88b6cee9f8bead761a419169ecda6cc (diff)
ASoC: SOF: topology: Add support for AMD ACP DAIs
Add new sof dais and config to pass topology file configuration to SOF firmware running on ACP's DSP core. ACP firmware support I2S_BT, I2S_SP and DMIC controller hence add three new dais to the list of supported sof_dais Signed-off-by: Ajit Kumar Pandey <AjitKumar.Pandey@amd.com> Reviewed-by: Bard Liao <bard.liao@intel.com> Reviewed-by: Kai Vehmanen <kai.vehmanen@linux.intel.com> Signed-off-by: Daniel Baluta <daniel.baluta@nxp.com> Link: https://lore.kernel.org/r/20211117093734.17407-12-daniel.baluta@oss.nxp.com Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound/soc')
-rw-r--r--sound/soc/sof/pcm.c36
-rw-r--r--sound/soc/sof/topology.c109
2 files changed, 145 insertions, 0 deletions
diff --git a/sound/soc/sof/pcm.c b/sound/soc/sof/pcm.c
index fa0bfcd2474e..8d313c9862cb 100644
--- a/sound/soc/sof/pcm.c
+++ b/sound/soc/sof/pcm.c
@@ -826,6 +826,42 @@ int sof_pcm_dai_link_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_pa
"channels_min: %d channels_max: %d\n",
channels->min, channels->max);
break;
+ case SOF_DAI_AMD_BT:
+ rate->min = dai->dai_config->acpbt.fsync_rate;
+ rate->max = dai->dai_config->acpbt.fsync_rate;
+ channels->min = dai->dai_config->acpbt.tdm_slots;
+ channels->max = dai->dai_config->acpbt.tdm_slots;
+
+ dev_dbg(component->dev,
+ "AMD_BT rate_min: %d rate_max: %d\n", rate->min, rate->max);
+ dev_dbg(component->dev,
+ "AMD_BT channels_min: %d channels_max: %d\n",
+ channels->min, channels->max);
+ break;
+ case SOF_DAI_AMD_SP:
+ rate->min = dai->dai_config->acpsp.fsync_rate;
+ rate->max = dai->dai_config->acpsp.fsync_rate;
+ channels->min = dai->dai_config->acpsp.tdm_slots;
+ channels->max = dai->dai_config->acpsp.tdm_slots;
+
+ dev_dbg(component->dev,
+ "AMD_SP rate_min: %d rate_max: %d\n", rate->min, rate->max);
+ dev_dbg(component->dev,
+ "AMD_SP channels_min: %d channels_max: %d\n",
+ channels->min, channels->max);
+ break;
+ case SOF_DAI_AMD_DMIC:
+ rate->min = dai->dai_config->acpdmic.fsync_rate;
+ rate->max = dai->dai_config->acpdmic.fsync_rate;
+ channels->min = dai->dai_config->acpdmic.tdm_slots;
+ channels->max = dai->dai_config->acpdmic.tdm_slots;
+
+ dev_dbg(component->dev,
+ "AMD_DMIC rate_min: %d rate_max: %d\n", rate->min, rate->max);
+ dev_dbg(component->dev,
+ "AMD_DMIC channels_min: %d channels_max: %d\n",
+ channels->min, channels->max);
+ break;
default:
dev_err(component->dev, "error: invalid DAI type %d\n",
dai->dai_config->type);
diff --git a/sound/soc/sof/topology.c b/sound/soc/sof/topology.c
index bb9e62bbe5db..72e671c15a34 100644
--- a/sound/soc/sof/topology.c
+++ b/sound/soc/sof/topology.c
@@ -376,6 +376,9 @@ static const struct sof_dai_types sof_dais[] = {
{"ALH", SOF_DAI_INTEL_ALH},
{"SAI", SOF_DAI_IMX_SAI},
{"ESAI", SOF_DAI_IMX_ESAI},
+ {"ACP", SOF_DAI_AMD_BT},
+ {"ACPSP", SOF_DAI_AMD_SP},
+ {"ACPDMIC", SOF_DAI_AMD_DMIC},
};
static enum sof_ipc_dai_type find_dai(const char *name)
@@ -2992,6 +2995,102 @@ static int sof_link_esai_load(struct snd_soc_component *scomp, int index,
return ret;
}
+static int sof_link_acp_dmic_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);
+ u32 size = sizeof(*config);
+ int ret;
+
+ /* handle master/slave and inverted clocks */
+ sof_dai_set_format(hw_config, config);
+
+ /* init IPC */
+ memset(&config->acpdmic, 0, sizeof(struct sof_ipc_dai_acp_params));
+ config->hdr.size = size;
+
+ config->acpdmic.fsync_rate = le32_to_cpu(hw_config->fsync_rate);
+ config->acpdmic.tdm_slots = le32_to_cpu(hw_config->tdm_slots);
+
+ dev_info(scomp->dev, "ACP_DMIC config ACP%d channel %d rate %d\n",
+ config->dai_index, config->acpdmic.tdm_slots,
+ config->acpdmic.fsync_rate);
+
+ /* set config for all DAI's with name matching the link name */
+ ret = sof_set_dai_config(sdev, size, link, config);
+ if (ret < 0)
+ dev_err(scomp->dev, "ACP_DMIC failed to save DAI config for ACP%d\n",
+ config->dai_index);
+ return ret;
+}
+
+static int sof_link_acp_bt_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);
+ u32 size = sizeof(*config);
+ int ret;
+
+ /* handle master/slave and inverted clocks */
+ sof_dai_set_format(hw_config, config);
+
+ /* init IPC */
+ memset(&config->acpbt, 0, sizeof(struct sof_ipc_dai_acp_params));
+ config->hdr.size = size;
+
+ config->acpbt.fsync_rate = le32_to_cpu(hw_config->fsync_rate);
+ config->acpbt.tdm_slots = le32_to_cpu(hw_config->tdm_slots);
+
+ dev_info(scomp->dev, "ACP_BT config ACP%d channel %d rate %d\n",
+ config->dai_index, config->acpbt.tdm_slots,
+ config->acpbt.fsync_rate);
+
+ /* set config for all DAI's with name matching the link name */
+ ret = sof_set_dai_config(sdev, size, link, config);
+ if (ret < 0)
+ dev_err(scomp->dev, "ACP_BT failed to save DAI config for ACP%d\n",
+ config->dai_index);
+ return ret;
+}
+
+static int sof_link_acp_sp_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);
+ u32 size = sizeof(*config);
+ int ret;
+
+ /* handle master/slave and inverted clocks */
+ sof_dai_set_format(hw_config, config);
+
+ /* init IPC */
+ memset(&config->acpsp, 0, sizeof(struct sof_ipc_dai_acp_params));
+ config->hdr.size = size;
+
+ config->acpsp.fsync_rate = le32_to_cpu(hw_config->fsync_rate);
+ config->acpsp.tdm_slots = le32_to_cpu(hw_config->tdm_slots);
+
+ dev_info(scomp->dev, "ACP_SP config ACP%d channel %d rate %d\n",
+ config->dai_index, config->acpsp.tdm_slots,
+ config->acpsp.fsync_rate);
+
+ /* set config for all DAI's with name matching the link name */
+ ret = sof_set_dai_config(sdev, size, link, config);
+ if (ret < 0)
+ dev_err(scomp->dev, "ACP_SP failed to save DAI config for ACP%d\n",
+ config->dai_index);
+ return ret;
+}
+
static int sof_link_dmic_load(struct snd_soc_component *scomp, int index,
struct snd_soc_dai_link *link,
struct snd_soc_tplg_link_config *cfg,
@@ -3277,6 +3376,16 @@ static int sof_link_load(struct snd_soc_component *scomp, int index,
case SOF_DAI_IMX_ESAI:
ret = sof_link_esai_load(scomp, index, link, cfg, hw_config + curr_conf, config);
break;
+ case SOF_DAI_AMD_BT:
+ ret = sof_link_acp_bt_load(scomp, index, link, cfg, hw_config + curr_conf, config);
+ break;
+ case SOF_DAI_AMD_SP:
+ ret = sof_link_acp_sp_load(scomp, index, link, cfg, hw_config + curr_conf, config);
+ break;
+ case SOF_DAI_AMD_DMIC:
+ ret = sof_link_acp_dmic_load(scomp, index, link, cfg, hw_config + curr_conf,
+ config);
+ break;
default:
dev_err(scomp->dev, "error: invalid DAI type %d\n", common_config.type);
ret = -EINVAL;