SOF_DAI_AMD_SP_VIRTUAL, /**< AMD ACP SP VIRTUAL */
SOF_DAI_AMD_HS_VIRTUAL, /**< AMD ACP HS VIRTUAL */
SOF_DAI_IMX_MICFIL, /** < i.MX MICFIL PDM */
+ SOF_DAI_AMD_SDW, /**< AMD ACP SDW */
};
/* general purpose DAI configuration */
struct sof_ipc_dai_acp_params acphs;
struct sof_ipc_dai_mtk_afe_params afe;
struct sof_ipc_dai_micfil_params micfil;
+ struct sof_ipc_dai_acp_sdw_params acp_sdw;
};
} __packed;
dev_dbg(component->dev, "MICFIL PDM channels_min: %d channels_max: %d\n",
channels->min, channels->max);
break;
+ case SOF_DAI_AMD_SDW:
+ /* change the default trigger sequence as per HW implementation */
+ for_each_dpcm_fe(rtd, SNDRV_PCM_STREAM_PLAYBACK, dpcm) {
+ struct snd_soc_pcm_runtime *fe = dpcm->fe;
+
+ fe->dai_link->trigger[SNDRV_PCM_STREAM_PLAYBACK] =
+ SND_SOC_DPCM_TRIGGER_POST;
+ }
+
+ for_each_dpcm_fe(rtd, SNDRV_PCM_STREAM_CAPTURE, dpcm) {
+ struct snd_soc_pcm_runtime *fe = dpcm->fe;
+
+ fe->dai_link->trigger[SNDRV_PCM_STREAM_CAPTURE] =
+ SND_SOC_DPCM_TRIGGER_POST;
+ }
+ rate->min = private->dai_config->acp_sdw.rate;
+ rate->max = private->dai_config->acp_sdw.rate;
+ channels->min = private->dai_config->acp_sdw.channels;
+ channels->max = private->dai_config->acp_sdw.channels;
+
+ dev_dbg(component->dev,
+ "AMD_SDW rate_min: %d rate_max: %d\n", rate->min, rate->max);
+ dev_dbg(component->dev, "AMD_SDW channels_min: %d channels_max: %d\n",
+ channels->min, channels->max);
+ break;
default:
dev_err(component->dev, "Invalid DAI type %d\n", private->dai_config->type);
break;
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,
[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)},
};
/**
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)
{
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;
}
{"ACPSP_VIRTUAL", SOF_DAI_AMD_SP_VIRTUAL},
{"ACPHS_VIRTUAL", SOF_DAI_AMD_HS_VIRTUAL},
{"MICFIL", SOF_DAI_IMX_MICFIL},
+ {"ACP_SDW", SOF_DAI_AMD_SDW},
};
token_id = SOF_MICFIL_TOKENS;
num_tuples += token_list[SOF_MICFIL_TOKENS].count;
break;
+ case SOF_DAI_AMD_SDW:
+ token_id = SOF_ACP_SDW_TOKENS;
+ num_tuples += token_list[SOF_ACP_SDW_TOKENS].count;
+ break;
default:
break;
}