summaryrefslogtreecommitdiff
path: root/sound/soc/sof/ipc3-topology.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/sof/ipc3-topology.c')
-rw-r--r--sound/soc/sof/ipc3-topology.c87
1 files changed, 76 insertions, 11 deletions
diff --git a/sound/soc/sof/ipc3-topology.c b/sound/soc/sof/ipc3-topology.c
index d47698f4be2d..e98b53b67d12 100644
--- a/sound/soc/sof/ipc3-topology.c
+++ b/sound/soc/sof/ipc3-topology.c
@@ -3,7 +3,7 @@
// This file is provided under a dual BSD/GPLv2 license. When using or
// redistributing this file, you may do so under either license.
//
-// Copyright(c) 2021 Intel Corporation. All rights reserved.
+// Copyright(c) 2021 Intel Corporation
//
//
@@ -20,6 +20,9 @@
/* size of tplg ABI in bytes */
#define SOF_IPC3_TPLG_ABI_SIZE 3
+/* Base of SOF_DAI_INTEL_ALH, this should be aligned with SOC_SDW_INTEL_BIDIR_PDI_BASE */
+#define INTEL_ALH_DAI_INDEX_BASE 2
+
struct sof_widget_data {
int ctrl_type;
int ipc_cmd;
@@ -298,6 +301,14 @@ static const struct sof_topology_token micfil_pdm_tokens[] = {
offsetof(struct sof_ipc_dai_micfil_params, pdm_ch)},
};
+/* ACP_SDW */
+static const struct sof_topology_token acp_sdw_tokens[] = {
+ {SOF_TKN_AMD_ACP_SDW_RATE, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
+ offsetof(struct sof_ipc_dai_acp_sdw_params, rate)},
+ {SOF_TKN_AMD_ACP_SDW_CH, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
+ offsetof(struct sof_ipc_dai_acp_sdw_params, channels)},
+};
+
/* Core tokens */
static const struct sof_topology_token core_tokens[] = {
{SOF_TKN_COMP_CORE_ID, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
@@ -336,6 +347,7 @@ static const struct sof_token_info ipc3_token_list[SOF_TOKEN_COUNT] = {
[SOF_ACPI2S_TOKENS] = {"ACPI2S tokens", acpi2s_tokens, ARRAY_SIZE(acpi2s_tokens)},
[SOF_MICFIL_TOKENS] = {"MICFIL PDM tokens",
micfil_pdm_tokens, ARRAY_SIZE(micfil_pdm_tokens)},
+ [SOF_ACP_SDW_TOKENS] = {"ACP_SDW tokens", acp_sdw_tokens, ARRAY_SIZE(acp_sdw_tokens)},
};
/**
@@ -1315,6 +1327,34 @@ static int sof_link_acp_hs_load(struct snd_soc_component *scomp, struct snd_sof_
return 0;
}
+static int sof_link_acp_sdw_load(struct snd_soc_component *scomp, struct snd_sof_dai_link *slink,
+ struct sof_ipc_dai_config *config, struct snd_sof_dai *dai)
+{
+ struct sof_dai_private_data *private = dai->private;
+ u32 size = sizeof(*config);
+ int ret;
+
+ /* parse the required set of ACP_SDW tokens based on num_hw_cfgs */
+ ret = sof_update_ipc_object(scomp, &config->acp_sdw, SOF_ACP_SDW_TOKENS, slink->tuples,
+ slink->num_tuples, size, slink->num_hw_configs);
+ if (ret < 0)
+ return ret;
+
+ /* init IPC */
+ config->hdr.size = size;
+ dev_dbg(scomp->dev, "ACP SDW config rate %d channels %d\n",
+ config->acp_sdw.rate, config->acp_sdw.channels);
+
+ /* set config for all DAI's with name matching the link name */
+ dai->number_configs = 1;
+ dai->current_config = 0;
+ private->dai_config = kmemdup(config, size, GFP_KERNEL);
+ if (!private->dai_config)
+ return -ENOMEM;
+
+ return 0;
+}
+
static int sof_link_afe_load(struct snd_soc_component *scomp, struct snd_sof_dai_link *slink,
struct sof_ipc_dai_config *config, struct snd_sof_dai *dai)
{
@@ -1548,14 +1588,26 @@ static int sof_ipc3_widget_setup_comp_dai(struct snd_sof_widget *swidget)
ret = sof_update_ipc_object(scomp, comp_dai, SOF_DAI_TOKENS, swidget->tuples,
swidget->num_tuples, sizeof(*comp_dai), 1);
if (ret < 0)
- goto free;
+ goto free_comp;
/* update comp_tokens */
ret = sof_update_ipc_object(scomp, &comp_dai->config, SOF_COMP_TOKENS,
swidget->tuples, swidget->num_tuples,
sizeof(comp_dai->config), 1);
if (ret < 0)
- goto free;
+ goto free_comp;
+
+ /* Subtract the base to match the FW dai index. */
+ if (comp_dai->type == SOF_DAI_INTEL_ALH) {
+ if (comp_dai->dai_index < INTEL_ALH_DAI_INDEX_BASE) {
+ dev_err(sdev->dev,
+ "Invalid ALH dai index %d, only Pin numbers >= %d can be used\n",
+ comp_dai->dai_index, INTEL_ALH_DAI_INDEX_BASE);
+ ret = -EINVAL;
+ goto free_comp;
+ }
+ comp_dai->dai_index -= INTEL_ALH_DAI_INDEX_BASE;
+ }
dev_dbg(scomp->dev, "dai %s: type %d index %d\n",
swidget->widget->name, comp_dai->type, comp_dai->dai_index);
@@ -1629,6 +1681,9 @@ static int sof_ipc3_widget_setup_comp_dai(struct snd_sof_widget *swidget)
case SOF_DAI_MEDIATEK_AFE:
ret = sof_link_afe_load(scomp, slink, config, dai);
break;
+ case SOF_DAI_AMD_SDW:
+ ret = sof_link_acp_sdw_load(scomp, slink, config, dai);
+ break;
default:
break;
}
@@ -2127,8 +2182,16 @@ static int sof_ipc3_dai_config(struct snd_sof_dev *sdev, struct snd_sof_widget *
case SOF_DAI_INTEL_ALH:
if (data) {
/* save the dai_index during hw_params and reuse it for hw_free */
- if (flags & SOF_DAI_CONFIG_FLAGS_HW_PARAMS)
- config->dai_index = data->dai_index;
+ if (flags & SOF_DAI_CONFIG_FLAGS_HW_PARAMS) {
+ /* Subtract the base to match the FW dai index. */
+ if (data->dai_index < INTEL_ALH_DAI_INDEX_BASE) {
+ dev_err(sdev->dev,
+ "Invalid ALH dai index %d, only Pin numbers >= %d can be used\n",
+ config->dai_index, INTEL_ALH_DAI_INDEX_BASE);
+ return -EINVAL;
+ }
+ config->dai_index = data->dai_index - INTEL_ALH_DAI_INDEX_BASE;
+ }
config->alh.stream_id = data->dai_data;
}
break;
@@ -2460,7 +2523,7 @@ static int sof_ipc3_tear_down_all_pipelines(struct snd_sof_dev *sdev, bool verif
return 0;
}
-static int sof_ipc3_dai_get_clk(struct snd_sof_dev *sdev, struct snd_sof_dai *dai, int clk_type)
+static int sof_ipc3_dai_get_param(struct snd_sof_dev *sdev, struct snd_sof_dai *dai, int param_type)
{
struct sof_dai_private_data *private = dai->private;
@@ -2469,15 +2532,17 @@ static int sof_ipc3_dai_get_clk(struct snd_sof_dev *sdev, struct snd_sof_dai *da
switch (private->dai_config->type) {
case SOF_DAI_INTEL_SSP:
- switch (clk_type) {
- case SOF_DAI_CLK_INTEL_SSP_MCLK:
+ switch (param_type) {
+ case SOF_DAI_PARAM_INTEL_SSP_MCLK:
return private->dai_config->ssp.mclk_rate;
- case SOF_DAI_CLK_INTEL_SSP_BCLK:
+ case SOF_DAI_PARAM_INTEL_SSP_BCLK:
return private->dai_config->ssp.bclk_rate;
+ case SOF_DAI_PARAM_INTEL_SSP_TDM_SLOTS:
+ return private->dai_config->ssp.tdm_slots;
default:
+ dev_err(sdev->dev, "invalid SSP param %d\n", param_type);
break;
}
- dev_err(sdev->dev, "fail to get SSP clk %d rate\n", clk_type);
break;
default:
/* not yet implemented for platforms other than the above */
@@ -2652,7 +2717,7 @@ const struct sof_ipc_tplg_ops ipc3_tplg_ops = {
.widget_free = sof_ipc3_widget_free,
.widget_setup = sof_ipc3_widget_setup,
.dai_config = sof_ipc3_dai_config,
- .dai_get_clk = sof_ipc3_dai_get_clk,
+ .dai_get_param = sof_ipc3_dai_get_param,
.set_up_all_pipelines = sof_ipc3_set_up_all_pipelines,
.tear_down_all_pipelines = sof_ipc3_tear_down_all_pipelines,
.parse_manifest = sof_ipc3_parse_manifest,