Unverified Commit 839e484f authored by Ranjani Sridharan's avatar Ranjani Sridharan Committed by Mark Brown
Browse files

ASoC: SOF: make struct snd_sof_dai IPC agnostic



Remove the comp_dai and dai_config members of struct snd_sof_dai and
replace it with a void *private field. Introduce a new struct
sof_dai_private_data that will contain the pointer to these two fields.
The topology parser will populate this structure and save it as part of
the "private" member in snd_sof_dai. Change all users of these fields to
use the private member instead.

Signed-off-by: default avatarRanjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: default avatarBard Liao <yung-chuan.liao@linux.intel.com>
Reviewed-by: default avatarPéter Ujfalusi <peter.ujfalusi@linux.intel.com>
Reviewed-by: default avatarPierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Link: https://lore.kernel.org/r/20220308164344.577647-18-ranjani.sridharan@linux.intel.com


Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 5f8333f6
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -116,4 +116,9 @@ struct sof_ipc_dai_config {
	};
} __packed;

struct sof_dai_private_data {
	struct sof_ipc_comp_dai *comp_dai;
	struct sof_ipc_dai_config *dai_config;
};

#endif
+21 −6
Original line number Diff line number Diff line
@@ -167,6 +167,7 @@ static struct sof_ipc_dai_config *hda_dai_update_config(struct snd_soc_dapm_widg
							int channel)
{
	struct snd_sof_widget *swidget = w->dobj.private;
	struct sof_dai_private_data *private;
	struct sof_ipc_dai_config *config;
	struct snd_sof_dai *sof_dai;

@@ -175,12 +176,19 @@ static struct sof_ipc_dai_config *hda_dai_update_config(struct snd_soc_dapm_widg

	sof_dai = swidget->private;

	if (!sof_dai || !sof_dai->dai_config) {
		dev_err(swidget->scomp->dev, "error: No config for DAI %s\n", w->name);
	if (!sof_dai || !sof_dai->private) {
		dev_err(swidget->scomp->dev, "%s: No private data for DAI %s\n", __func__,
			w->name);
		return NULL;
	}

	config = &sof_dai->dai_config[sof_dai->current_config];
	private = sof_dai->private;
	if (!private->dai_config) {
		dev_err(swidget->scomp->dev, "%s: No config for DAI %s\n", __func__, w->name);
		return NULL;
	}

	config = &private->dai_config[sof_dai->current_config];

	/* update config with stream tag */
	config->hda.link_dma_ch = channel;
@@ -294,6 +302,7 @@ static int hda_link_dai_config_pause_push_ipc(struct snd_soc_dapm_widget *w)
	struct snd_sof_widget *swidget = w->dobj.private;
	struct snd_soc_component *component = swidget->scomp;
	struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component);
	struct sof_dai_private_data *private;
	struct sof_ipc_dai_config *config;
	struct snd_sof_dai *sof_dai;
	struct sof_ipc_reply reply;
@@ -301,12 +310,18 @@ static int hda_link_dai_config_pause_push_ipc(struct snd_soc_dapm_widget *w)

	sof_dai = swidget->private;

	if (!sof_dai || !sof_dai->dai_config) {
		dev_err(sdev->dev, "No config for DAI %s\n", w->name);
	if (!sof_dai || !sof_dai->private) {
		dev_err(sdev->dev, "%s: No private data for DAI %s\n", __func__, w->name);
		return -EINVAL;
	}

	private = sof_dai->private;
	if (!private->dai_config) {
		dev_err(sdev->dev, "%s: No config for DAI %s\n", __func__, w->name);
		return -EINVAL;
	}

	config = &sof_dai->dai_config[sof_dai->current_config];
	config = &private->dai_config[sof_dai->current_config];

	/* set PAUSE command flag */
	config->flags = FIELD_PREP(SOF_DAI_CONFIG_FLAGS_CMD_MASK, SOF_DAI_CONFIG_FLAGS_PAUSE);
+30 −9
Original line number Diff line number Diff line
@@ -47,14 +47,21 @@ int hda_ctrl_dai_widget_setup(struct snd_soc_dapm_widget *w, unsigned int quirk_
	struct snd_soc_component *component = swidget->scomp;
	struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component);
	struct sof_ipc_dai_config *config;
	struct sof_dai_private_data *private;
	struct snd_sof_dai *sof_dai;
	struct sof_ipc_reply reply;
	int ret;

	sof_dai = swidget->private;

	if (!sof_dai || !sof_dai->dai_config) {
		dev_err(sdev->dev, "No config for DAI %s\n", w->name);
	if (!sof_dai || !sof_dai->private) {
		dev_err(sdev->dev, "%s: No private data for DAI %s\n", __func__, w->name);
		return -EINVAL;
	}

	private = sof_dai->private;
	if (!private->dai_config) {
		dev_err(sdev->dev, "%s: No config for DAI %s\n", __func__, w->name);
		return -EINVAL;
	}

@@ -65,7 +72,7 @@ int hda_ctrl_dai_widget_setup(struct snd_soc_dapm_widget *w, unsigned int quirk_
			return ret;
	}

	config = &sof_dai->dai_config[sof_dai->current_config];
	config = &private->dai_config[sof_dai->current_config];

	/*
	 * For static pipelines, the DAI widget would already be set up and calling
@@ -101,6 +108,7 @@ int hda_ctrl_dai_widget_free(struct snd_soc_dapm_widget *w, unsigned int quirk_f
	struct snd_sof_widget *swidget = w->dobj.private;
	struct snd_soc_component *component = swidget->scomp;
	struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component);
	struct sof_dai_private_data *private;
	struct sof_ipc_dai_config *config;
	struct snd_sof_dai *sof_dai;
	struct sof_ipc_reply reply;
@@ -108,8 +116,14 @@ int hda_ctrl_dai_widget_free(struct snd_soc_dapm_widget *w, unsigned int quirk_f

	sof_dai = swidget->private;

	if (!sof_dai || !sof_dai->dai_config) {
		dev_err(sdev->dev, "error: No config to free DAI %s\n", w->name);
	if (!sof_dai || !sof_dai->private) {
		dev_err(sdev->dev, "%s: No private data for DAI %s\n", __func__, w->name);
		return -EINVAL;
	}

	private = sof_dai->private;
	if (!private->dai_config) {
		dev_err(sdev->dev, "%s: No config for DAI %s\n", __func__, w->name);
		return -EINVAL;
	}

@@ -117,7 +131,7 @@ int hda_ctrl_dai_widget_free(struct snd_soc_dapm_widget *w, unsigned int quirk_f
	if (!sof_dai->configured)
		return 0;

	config = &sof_dai->dai_config[sof_dai->current_config];
	config = &private->dai_config[sof_dai->current_config];

	/* set HW_FREE flag along with any quirks */
	config->flags = SOF_DAI_CONFIG_FLAGS_HW_FREE |
@@ -154,6 +168,7 @@ static int sdw_dai_config_ipc(struct snd_sof_dev *sdev,
			      int link_id, int alh_stream_id, int dai_id, bool setup)
{
	struct snd_sof_widget *swidget = w->dobj.private;
	struct sof_dai_private_data *private;
	struct sof_ipc_dai_config *config;
	struct snd_sof_dai *sof_dai;

@@ -164,12 +179,18 @@ static int sdw_dai_config_ipc(struct snd_sof_dev *sdev,

	sof_dai = swidget->private;

	if (!sof_dai || !sof_dai->dai_config) {
		dev_err(sdev->dev, "error: No config for DAI %s\n", w->name);
	if (!sof_dai || !sof_dai->private) {
		dev_err(sdev->dev, "%s: No private data for DAI %s\n", __func__, w->name);
		return -EINVAL;
	}

	private = sof_dai->private;
	if (!private->dai_config) {
		dev_err(sdev->dev, "%s: No config for DAI %s\n", __func__, w->name);
		return -EINVAL;
	}

	config = &sof_dai->dai_config[sof_dai->current_config];
	config = &private->dai_config[sof_dai->current_config];

	/* update config with link and stream ID */
	config->dai_index = (link_id << 8) | dai_id;
+40 −37
Original line number Diff line number Diff line
@@ -670,7 +670,9 @@ static void ssp_dai_config_pcm_params_match(struct snd_sof_dev *sdev, const char
		if (!dai->name || strcmp(link_name, dai->name))
			continue;
		for (i = 0; i < dai->number_configs; i++) {
			config = &dai->dai_config[i];
			struct sof_dai_private_data *private = dai->private;

			config = &private->dai_config[i];
			if (config->ssp.fsync_rate == params_rate(params)) {
				dev_dbg(sdev->dev, "DAI config %d matches pcm hw params\n", i);
				dai->current_config = i;
@@ -693,6 +695,7 @@ int sof_pcm_dai_link_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_pa
	struct snd_sof_dai *dai =
		snd_sof_find_dai(component, (char *)rtd->dai_link->name);
	struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component);
	struct sof_dai_private_data *private = dai->private;
	struct snd_soc_dpcm *dpcm;

	/* no topology exists for this BE, try a common configuration */
@@ -717,7 +720,7 @@ int sof_pcm_dai_link_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_pa
	/* read format from topology */
	snd_mask_none(fmt);

	switch (dai->comp_dai->config.frame_fmt) {
	switch (private->comp_dai->config.frame_fmt) {
	case SOF_IPC_FRAME_S16_LE:
		snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S16_LE);
		break;
@@ -733,15 +736,15 @@ int sof_pcm_dai_link_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_pa
	}

	/* read rate and channels from topology */
	switch (dai->dai_config->type) {
	switch (private->dai_config->type) {
	case SOF_DAI_INTEL_SSP:
		/* search for config to pcm params match, if not found use default */
		ssp_dai_config_pcm_params_match(sdev, (char *)rtd->dai_link->name, params);

		rate->min = dai->dai_config[dai->current_config].ssp.fsync_rate;
		rate->max = dai->dai_config[dai->current_config].ssp.fsync_rate;
		channels->min = dai->dai_config[dai->current_config].ssp.tdm_slots;
		channels->max = dai->dai_config[dai->current_config].ssp.tdm_slots;
		rate->min = private->dai_config[dai->current_config].ssp.fsync_rate;
		rate->max = private->dai_config[dai->current_config].ssp.fsync_rate;
		channels->min = private->dai_config[dai->current_config].ssp.tdm_slots;
		channels->max = private->dai_config[dai->current_config].ssp.tdm_slots;

		dev_dbg(component->dev,
			"rate_min: %d rate_max: %d\n", rate->min, rate->max);
@@ -752,11 +755,11 @@ int sof_pcm_dai_link_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_pa
		break;
	case SOF_DAI_INTEL_DMIC:
		/* DMIC only supports 16 or 32 bit formats */
		if (dai->comp_dai->config.frame_fmt == SOF_IPC_FRAME_S24_4LE) {
		if (private->comp_dai->config.frame_fmt == SOF_IPC_FRAME_S24_4LE) {
			dev_err(component->dev,
				"error: invalid fmt %d for DAI type %d\n",
				dai->comp_dai->config.frame_fmt,
				dai->dai_config->type);
				private->comp_dai->config.frame_fmt,
				private->dai_config->type);
		}
		break;
	case SOF_DAI_INTEL_HDA:
@@ -776,14 +779,14 @@ int sof_pcm_dai_link_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_pa
		 * Dai could run with different channel count compared with
		 * front end, so get dai channel count from topology
		 */
		channels->min = dai->dai_config->alh.channels;
		channels->max = dai->dai_config->alh.channels;
		channels->min = private->dai_config->alh.channels;
		channels->max = private->dai_config->alh.channels;
		break;
	case SOF_DAI_IMX_ESAI:
		rate->min = dai->dai_config->esai.fsync_rate;
		rate->max = dai->dai_config->esai.fsync_rate;
		channels->min = dai->dai_config->esai.tdm_slots;
		channels->max = dai->dai_config->esai.tdm_slots;
		rate->min = private->dai_config->esai.fsync_rate;
		rate->max = private->dai_config->esai.fsync_rate;
		channels->min = private->dai_config->esai.tdm_slots;
		channels->max = private->dai_config->esai.tdm_slots;

		dev_dbg(component->dev,
			"rate_min: %d rate_max: %d\n", rate->min, rate->max);
@@ -792,10 +795,10 @@ int sof_pcm_dai_link_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_pa
			channels->min, channels->max);
		break;
	case SOF_DAI_MEDIATEK_AFE:
		rate->min = dai->dai_config->afe.rate;
		rate->max = dai->dai_config->afe.rate;
		channels->min = dai->dai_config->afe.channels;
		channels->max = dai->dai_config->afe.channels;
		rate->min = private->dai_config->afe.rate;
		rate->max = private->dai_config->afe.rate;
		channels->min = private->dai_config->afe.channels;
		channels->max = private->dai_config->afe.channels;

		dev_dbg(component->dev,
			"rate_min: %d rate_max: %d\n", rate->min, rate->max);
@@ -804,10 +807,10 @@ int sof_pcm_dai_link_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_pa
			channels->min, channels->max);
		break;
	case SOF_DAI_IMX_SAI:
		rate->min = dai->dai_config->sai.fsync_rate;
		rate->max = dai->dai_config->sai.fsync_rate;
		channels->min = dai->dai_config->sai.tdm_slots;
		channels->max = dai->dai_config->sai.tdm_slots;
		rate->min = private->dai_config->sai.fsync_rate;
		rate->max = private->dai_config->sai.fsync_rate;
		channels->min = private->dai_config->sai.tdm_slots;
		channels->max = private->dai_config->sai.tdm_slots;

		dev_dbg(component->dev,
			"rate_min: %d rate_max: %d\n", rate->min, rate->max);
@@ -816,10 +819,10 @@ int sof_pcm_dai_link_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_pa
			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;
		rate->min = private->dai_config->acpbt.fsync_rate;
		rate->max = private->dai_config->acpbt.fsync_rate;
		channels->min = private->dai_config->acpbt.tdm_slots;
		channels->max = private->dai_config->acpbt.tdm_slots;

		dev_dbg(component->dev,
			"AMD_BT rate_min: %d rate_max: %d\n", rate->min, rate->max);
@@ -828,10 +831,10 @@ int sof_pcm_dai_link_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_pa
			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;
		rate->min = private->dai_config->acpsp.fsync_rate;
		rate->max = private->dai_config->acpsp.fsync_rate;
		channels->min = private->dai_config->acpsp.tdm_slots;
		channels->max = private->dai_config->acpsp.tdm_slots;

		dev_dbg(component->dev,
			"AMD_SP rate_min: %d rate_max: %d\n", rate->min, rate->max);
@@ -840,10 +843,10 @@ int sof_pcm_dai_link_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_pa
			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;
		rate->min = private->dai_config->acpdmic.fsync_rate;
		rate->max = private->dai_config->acpdmic.fsync_rate;
		channels->min = private->dai_config->acpdmic.tdm_slots;
		channels->max = private->dai_config->acpdmic.tdm_slots;

		dev_dbg(component->dev,
			"AMD_DMIC rate_min: %d rate_max: %d\n", rate->min, rate->max);
@@ -853,7 +856,7 @@ int sof_pcm_dai_link_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_pa
		break;
	default:
		dev_err(component->dev, "error: invalid DAI type %d\n",
			dai->dai_config->type);
			private->dai_config->type);
		break;
	}

+19 −11
Original line number Diff line number Diff line
@@ -29,11 +29,12 @@ static int sof_kcontrol_setup(struct snd_sof_dev *sdev, struct snd_sof_control *

static int sof_dai_config_setup(struct snd_sof_dev *sdev, struct snd_sof_dai *dai)
{
	struct sof_dai_private_data *private = dai->private;
	struct sof_ipc_dai_config *config;
	struct sof_ipc_reply reply;
	int ret;

	config = &dai->dai_config[dai->current_config];
	config = &private->dai_config[dai->current_config];
	if (!config) {
		dev_err(sdev->dev, "error: no config for DAI %s\n", dai->name);
		return -EINVAL;
@@ -191,12 +192,16 @@ int sof_widget_setup(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget)
	switch (swidget->id) {
	case snd_soc_dapm_dai_in:
	case snd_soc_dapm_dai_out:
	{
		struct sof_dai_private_data *dai_data;

		dai = swidget->private;
		comp = &dai->comp_dai->comp;
		dai_data = dai->private;
		comp = &dai_data->comp_dai->comp;
		dai->configured = false;

		ret = sof_ipc_tx_message(sdev->ipc, comp->hdr.cmd, dai->comp_dai, comp->hdr.size,
					 &r, sizeof(r));
		ret = sof_ipc_tx_message(sdev->ipc, comp->hdr.cmd, dai_data->comp_dai,
					 comp->hdr.size, &r, sizeof(r));
		if (ret < 0) {
			dev_err(sdev->dev, "error: failed to load widget %s\n",
				swidget->widget->name);
@@ -216,6 +221,7 @@ int sof_widget_setup(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget)
			return ret;
		}
		break;
	}
	case snd_soc_dapm_scheduler:
		pipeline = swidget->private;
		ret = sof_ipc_tx_message(sdev->ipc, pipeline->hdr.cmd, pipeline,
@@ -620,12 +626,13 @@ int sof_set_up_pipelines(struct snd_sof_dev *sdev, bool verify)
		/* update DAI config. The IPC will be sent in sof_widget_setup() */
		if (WIDGET_IS_DAI(swidget->id)) {
			struct snd_sof_dai *dai = swidget->private;
			struct sof_dai_private_data *private = dai->private;
			struct sof_ipc_dai_config *config;

			if (!dai || !dai->dai_config)
			if (!dai || !private || !private->dai_config)
				continue;

			config = dai->dai_config;
			config = private->dai_config;
			/*
			 * The link DMA channel would be invalidated for running
			 * streams but not for streams that were in the PAUSED
@@ -911,18 +918,19 @@ static int sof_dai_get_clk(struct snd_soc_pcm_runtime *rtd, int clk_type)
		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;

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

	switch (dai->dai_config->type) {
	switch (private->dai_config->type) {
	case SOF_DAI_INTEL_SSP:
		switch (clk_type) {
		case SOF_DAI_CLK_INTEL_SSP_MCLK:
			return dai->dai_config->ssp.mclk_rate;
			return private->dai_config->ssp.mclk_rate;
		case SOF_DAI_CLK_INTEL_SSP_BCLK:
			return dai->dai_config->ssp.bclk_rate;
			return private->dai_config->ssp.bclk_rate;
		default:
			dev_err(rtd->dev, "fail to get SSP clk %d rate\n",
				clk_type);
@@ -932,7 +940,7 @@ static int sof_dai_get_clk(struct snd_soc_pcm_runtime *rtd, int clk_type)
	default:
		/* not yet implemented for platforms other than the above */
		dev_err(rtd->dev, "DAI type %d not supported yet!\n",
			dai->dai_config->type);
			private->dai_config->type);
		return -EINVAL;
	}
}
Loading