Unverified Commit 85f7a8b6 authored by Ranjani Sridharan's avatar Ranjani Sridharan Committed by Mark Brown
Browse files

ASoC: SOF: Add a new dai_get_clk topology IPC op



This will help make the code for getting the mclk and bclk IPC specific.
Add the implementation for IPC3 as well.

Signed-off-by: default avatarRanjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: default avatarRander Wang <rander.wang@intel.com>
Reviewed-by: default avatarPierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: default avatarBard Liao <yung-chuan.liao@linux.intel.com>
Link: https://lore.kernel.org/r/20220317175044.1752400-20-ranjani.sridharan@linux.intel.com


Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 31cd6e46
Loading
Loading
Loading
Loading
+29 −0
Original line number Diff line number Diff line
@@ -2252,6 +2252,34 @@ 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)
{
	struct sof_dai_private_data *private = dai->private;

	if (!private || !private->dai_config)
		return 0;

	switch (private->dai_config->type) {
	case SOF_DAI_INTEL_SSP:
		switch (clk_type) {
		case SOF_DAI_CLK_INTEL_SSP_MCLK:
			return private->dai_config->ssp.mclk_rate;
		case SOF_DAI_CLK_INTEL_SSP_BCLK:
			return private->dai_config->ssp.bclk_rate;
		default:
			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 */
		dev_err(sdev->dev, "DAI type %d not supported yet!\n", private->dai_config->type);
		break;
	}

	return -EINVAL;
}

/* token list for each topology object */
static enum sof_tokens host_token_list[] = {
	SOF_CORE_TOKENS,
@@ -2359,6 +2387,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,
	.set_up_all_pipelines = sof_ipc3_set_up_all_pipelines,
	.tear_down_all_pipelines = sof_ipc3_tear_down_all_pipelines,
};
+7 −24
Original line number Diff line number Diff line
@@ -628,40 +628,23 @@ struct snd_sof_dai *snd_sof_find_dai(struct snd_soc_component *scomp,
	return NULL;
}

#define SOF_DAI_CLK_INTEL_SSP_MCLK	0
#define SOF_DAI_CLK_INTEL_SSP_BCLK	1

static int sof_dai_get_clk(struct snd_soc_pcm_runtime *rtd, int clk_type)
{
	struct snd_soc_component *component =
		snd_soc_rtdcom_lookup(rtd, SOF_AUDIO_PCM_DRV_NAME);
	struct snd_sof_dai *dai =
		snd_sof_find_dai(component, (char *)rtd->dai_link->name);
	struct sof_dai_private_data *private = dai->private;
	struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component);
	const struct sof_ipc_tplg_ops *tplg_ops = sdev->ipc->ops->tplg;

	/* use the tplg configured mclk if existed */
	if (!dai || !private || !private->dai_config)
	if (!dai)
		return 0;

	switch (private->dai_config->type) {
	case SOF_DAI_INTEL_SSP:
		switch (clk_type) {
		case SOF_DAI_CLK_INTEL_SSP_MCLK:
			return private->dai_config->ssp.mclk_rate;
		case SOF_DAI_CLK_INTEL_SSP_BCLK:
			return private->dai_config->ssp.bclk_rate;
		default:
			dev_err(rtd->dev, "fail to get SSP clk %d rate\n",
				clk_type);
			return -EINVAL;
		}
		break;
	default:
		/* not yet implemented for platforms other than the above */
		dev_err(rtd->dev, "DAI type %d not supported yet!\n",
			private->dai_config->type);
		return -EINVAL;
	}
	if (tplg_ops->dai_get_clk)
		return tplg_ops->dai_get_clk(sdev, dai, clk_type);

	return 0;
}

/*
+6 −0
Original line number Diff line number Diff line
@@ -30,6 +30,9 @@

#define WIDGET_IS_DAI(id) ((id) == snd_soc_dapm_dai_in || (id) == snd_soc_dapm_dai_out)

#define SOF_DAI_CLK_INTEL_SSP_MCLK	0
#define SOF_DAI_CLK_INTEL_SSP_BCLK	1

/*
 * Volume fractional word length define to 16 sets
 * the volume linear gain value to use Qx.16 format
@@ -39,6 +42,7 @@
struct snd_sof_widget;
struct snd_sof_route;
struct snd_sof_control;
struct snd_sof_dai;

struct snd_sof_dai_config_data {
	int dai_index;
@@ -117,6 +121,7 @@ struct sof_ipc_tplg_widget_ops {
 * @widget_setup: Function pointer for setting up setup in the DSP
 * @widget_free: Function pointer for freeing widget in the DSP
 * @dai_config: Function pointer for sending DAI config IPC to the DSP
 * @dai_get_clk: Function pointer for getting the DAI clock setting
 * @set_up_all_pipelines: Function pointer for setting up all topology pipelines
 * @tear_down_all_pipelines: Function pointer for tearing down all topology pipelines
 */
@@ -132,6 +137,7 @@ struct sof_ipc_tplg_ops {
	int (*widget_free)(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget);
	int (*dai_config)(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget,
			  unsigned int flags, struct snd_sof_dai_config_data *data);
	int (*dai_get_clk)(struct snd_sof_dev *sdev, struct snd_sof_dai *dai, int clk_type);
	int (*set_up_all_pipelines)(struct snd_sof_dev *sdev, bool verify);
	int (*tear_down_all_pipelines)(struct snd_sof_dev *sdev, bool verify);
};