Unverified Commit 89ef4208 authored by Daniel Baluta's avatar Daniel Baluta Committed by Mark Brown
Browse files

ASoC: SOF: Add support for configuring PDM interface from topology



Currently we only support configuration for number of channels and
sample rate.

Reviewed-by: default avatarPéter Ujfalusi <peter.ujfalusi@linux.intel.com>
Reviewed-by: default avatarIuliana Prodan <iuliana.prodan@nxp.com>
Signed-off-by: default avatarDaniel Baluta <daniel.baluta@nxp.com>
Link: https://lore.kernel.org/r/20231109135900.88310-3-daniel.baluta@oss.nxp.com


Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent fc85d9d0
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -51,4 +51,11 @@ struct sof_ipc_dai_sai_params {
	uint16_t tdm_slot_width;
	uint16_t reserved2;	/* alignment */
} __packed;

/* MICFIL Configuration Request - SOF_IPC_DAI_MICFIL_CONFIG */
struct sof_ipc_dai_micfil_params {
	uint32_t pdm_rate;
	uint32_t pdm_ch;
} __packed;

#endif
+2 −0
Original line number Diff line number Diff line
@@ -88,6 +88,7 @@ enum sof_ipc_dai_type {
	SOF_DAI_AMD_HS,			/**< Amd HS */
	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 */
};

/* general purpose DAI configuration */
@@ -117,6 +118,7 @@ struct sof_ipc_dai_config {
		struct sof_ipc_dai_acpdmic_params acpdmic;
		struct sof_ipc_dai_acp_params acphs;
		struct sof_ipc_dai_mtk_afe_params afe;
		struct sof_ipc_dai_micfil_params micfil;
	};
} __packed;

+4 −0
Original line number Diff line number Diff line
@@ -213,4 +213,8 @@
#define SOF_TKN_AMD_ACPI2S_CH			1701
#define SOF_TKN_AMD_ACPI2S_TDM_MODE		1702

/* MICFIL PDM */
#define SOF_TKN_IMX_MICFIL_RATE			2000
#define SOF_TKN_IMX_MICFIL_CH			2001

#endif
+11 −0
Original line number Diff line number Diff line
@@ -384,6 +384,17 @@ static int sof_ipc3_pcm_dai_link_fixup(struct snd_soc_pcm_runtime *rtd,
		dev_dbg(component->dev, "AMD_DMIC channels_min: %d channels_max: %d\n",
			channels->min, channels->max);
		break;
	case SOF_DAI_IMX_MICFIL:
		rate->min = private->dai_config->micfil.pdm_rate;
		rate->max = private->dai_config->micfil.pdm_rate;
		channels->min = private->dai_config->micfil.pdm_ch;
		channels->max = private->dai_config->micfil.pdm_ch;

		dev_dbg(component->dev,
			"MICFIL PDM rate_min: %d rate_max: %d\n", rate->min, rate->max);
		dev_dbg(component->dev, "MICFIL PDM 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;
+46 −0
Original line number Diff line number Diff line
@@ -286,6 +286,16 @@ static const struct sof_topology_token acpi2s_tokens[] = {
		offsetof(struct sof_ipc_dai_acp_params, tdm_mode)},
};

/* MICFIL PDM */
static const struct sof_topology_token micfil_pdm_tokens[] = {
	{SOF_TKN_IMX_MICFIL_RATE,
		SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
		offsetof(struct sof_ipc_dai_micfil_params, pdm_rate)},
	{SOF_TKN_IMX_MICFIL_CH,
		SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
		offsetof(struct sof_ipc_dai_micfil_params, pdm_ch)},
};

/* Core tokens */
static const struct sof_topology_token core_tokens[] = {
	{SOF_TKN_COMP_CORE_ID, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
@@ -322,6 +332,8 @@ static const struct sof_token_info ipc3_token_list[SOF_TOKEN_COUNT] = {
	[SOF_AFE_TOKENS] = {"AFE tokens", afe_tokens, ARRAY_SIZE(afe_tokens)},
	[SOF_ACPDMIC_TOKENS] = {"ACPDMIC tokens", acpdmic_tokens, ARRAY_SIZE(acpdmic_tokens)},
	[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)},
};

/**
@@ -1136,6 +1148,37 @@ static int sof_link_esai_load(struct snd_soc_component *scomp, struct snd_sof_da
	return 0;
}

static int sof_link_micfil_load(struct snd_soc_component *scomp, struct snd_sof_dai_link *slink,
				struct sof_ipc_dai_config *config, struct snd_sof_dai *dai)
{
	struct snd_soc_tplg_hw_config *hw_config = slink->hw_configs;
	struct sof_dai_private_data *private = dai->private;
	u32 size = sizeof(*config);
	int ret;

       /* handle master/slave and inverted clocks */
	sof_dai_set_format(hw_config, config);

	config->hdr.size = size;

	/* parse the required set of MICFIL PDM tokens based on num_hw_cfgs */
	ret = sof_update_ipc_object(scomp, &config->micfil, SOF_MICFIL_TOKENS, slink->tuples,
				    slink->num_tuples, size, slink->num_hw_configs);
	if (ret < 0)
		return ret;

	dev_info(scomp->dev, "MICFIL PDM config dai_index %d channel %d rate %d\n",
		 config->dai_index, config->micfil.pdm_ch, config->micfil.pdm_rate);

	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_acp_dmic_load(struct snd_soc_component *scomp, struct snd_sof_dai_link *slink,
				  struct sof_ipc_dai_config *config, struct snd_sof_dai *dai)
{
@@ -1559,6 +1602,9 @@ static int sof_ipc3_widget_setup_comp_dai(struct snd_sof_widget *swidget)
		case SOF_DAI_IMX_ESAI:
			ret = sof_link_esai_load(scomp, slink, config, dai);
			break;
		case SOF_DAI_IMX_MICFIL:
			ret = sof_link_micfil_load(scomp, slink, config, dai);
			break;
		case SOF_DAI_AMD_BT:
			ret = sof_link_acp_bt_load(scomp, slink, config, dai);
			break;
Loading