All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
To: alsa-devel@alsa-project.org
Cc: tiwai@suse.de, broonie@kernel.org,
	"Péter Ujfalusi" <peter.ujfalusi@linux.intel.com>,
	"Ranjani Sridharan" <ranjani.sridharan@linux.intel.com>,
	"Pierre-Louis Bossart" <pierre-louis.bossart@linux.intel.com>
Subject: [PATCH 14/19] ASoC: SOF: Define hw_params PCM op for IPC3
Date: Thu, 17 Mar 2022 10:50:39 -0700	[thread overview]
Message-ID: <20220317175044.1752400-15-ranjani.sridharan@linux.intel.com> (raw)
In-Reply-To: <20220317175044.1752400-1-ranjani.sridharan@linux.intel.com>

Add the hw_params op for IPC3 and use it.

Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
---
 sound/soc/sof/ipc3-pcm.c | 100 +++++++++++++++++++++++++++++++++++
 sound/soc/sof/pcm.c      | 110 ++++++---------------------------------
 2 files changed, 115 insertions(+), 95 deletions(-)

diff --git a/sound/soc/sof/ipc3-pcm.c b/sound/soc/sof/ipc3-pcm.c
index 96f498b4b2d6..b715199a2aaa 100644
--- a/sound/soc/sof/ipc3-pcm.c
+++ b/sound/soc/sof/ipc3-pcm.c
@@ -38,6 +38,106 @@ static int sof_ipc3_pcm_hw_free(struct snd_soc_component *component,
 				  sizeof(stream), &reply, sizeof(reply));
 }
 
+static int sof_ipc3_pcm_hw_params(struct snd_soc_component *component,
+				  struct snd_pcm_substream *substream,
+				  struct snd_pcm_hw_params *params,
+				  struct snd_sof_platform_stream_params *platform_params)
+{
+	struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component);
+	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+	struct sof_ipc_fw_version *v = &sdev->fw_ready.version;
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct sof_ipc_pcm_params_reply ipc_params_reply;
+	struct sof_ipc_pcm_params pcm;
+	struct snd_sof_pcm *spcm;
+	int ret;
+
+	spcm = snd_sof_find_spcm_dai(component, rtd);
+	if (!spcm)
+		return -EINVAL;
+
+	memset(&pcm, 0, sizeof(pcm));
+
+	/* number of pages should be rounded up */
+	pcm.params.buffer.pages = PFN_UP(runtime->dma_bytes);
+
+	/* set IPC PCM parameters */
+	pcm.hdr.size = sizeof(pcm);
+	pcm.hdr.cmd = SOF_IPC_GLB_STREAM_MSG | SOF_IPC_STREAM_PCM_PARAMS;
+	pcm.comp_id = spcm->stream[substream->stream].comp_id;
+	pcm.params.hdr.size = sizeof(pcm.params);
+	pcm.params.buffer.phy_addr = spcm->stream[substream->stream].page_table.addr;
+	pcm.params.buffer.size = runtime->dma_bytes;
+	pcm.params.direction = substream->stream;
+	pcm.params.sample_valid_bytes = params_width(params) >> 3;
+	pcm.params.buffer_fmt = SOF_IPC_BUFFER_INTERLEAVED;
+	pcm.params.rate = params_rate(params);
+	pcm.params.channels = params_channels(params);
+	pcm.params.host_period_bytes = params_period_bytes(params);
+
+	/* container size */
+	ret = snd_pcm_format_physical_width(params_format(params));
+	if (ret < 0)
+		return ret;
+	pcm.params.sample_container_bytes = ret >> 3;
+
+	/* format */
+	switch (params_format(params)) {
+	case SNDRV_PCM_FORMAT_S16:
+		pcm.params.frame_fmt = SOF_IPC_FRAME_S16_LE;
+		break;
+	case SNDRV_PCM_FORMAT_S24:
+		pcm.params.frame_fmt = SOF_IPC_FRAME_S24_4LE;
+		break;
+	case SNDRV_PCM_FORMAT_S32:
+		pcm.params.frame_fmt = SOF_IPC_FRAME_S32_LE;
+		break;
+	case SNDRV_PCM_FORMAT_FLOAT:
+		pcm.params.frame_fmt = SOF_IPC_FRAME_FLOAT;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	/* Update the IPC message with information from the platform */
+	pcm.params.stream_tag = platform_params->stream_tag;
+
+	if (platform_params->use_phy_address)
+		pcm.params.buffer.phy_addr = platform_params->phy_addr;
+
+	if (platform_params->no_ipc_position) {
+		/* For older ABIs set host_period_bytes to zero to inform
+		 * FW we don't want position updates. Newer versions use
+		 * no_stream_position for this purpose.
+		 */
+		if (v->abi_version < SOF_ABI_VER(3, 10, 0))
+			pcm.params.host_period_bytes = 0;
+		else
+			pcm.params.no_stream_position = 1;
+	}
+
+	dev_dbg(component->dev, "stream_tag %d", pcm.params.stream_tag);
+
+	/* send hw_params IPC to the DSP */
+	ret = sof_ipc_tx_message(sdev->ipc, pcm.hdr.cmd, &pcm, sizeof(pcm),
+				 &ipc_params_reply, sizeof(ipc_params_reply));
+	if (ret < 0) {
+		dev_err(component->dev, "HW params ipc failed for stream %d\n",
+			pcm.params.stream_tag);
+		return ret;
+	}
+
+	ret = snd_sof_set_stream_data_offset(sdev, substream, ipc_params_reply.posn_offset);
+	if (ret < 0) {
+		dev_err(component->dev, "%s: invalid stream data offset for PCM %d\n",
+			__func__, spcm->pcm.pcm_id);
+		return ret;
+	}
+
+	return ret;
+}
+
 const struct sof_ipc_pcm_ops ipc3_pcm_ops = {
+	.hw_params = sof_ipc3_pcm_hw_params,
 	.hw_free = sof_ipc3_pcm_hw_free,
 };
diff --git a/sound/soc/sof/pcm.c b/sound/soc/sof/pcm.c
index 8ef477aff938..8a194c130981 100644
--- a/sound/soc/sof/pcm.c
+++ b/sound/soc/sof/pcm.c
@@ -119,15 +119,12 @@ static int sof_pcm_hw_params(struct snd_soc_component *component,
 			     struct snd_pcm_substream *substream,
 			     struct snd_pcm_hw_params *params)
 {
-	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
-	struct snd_pcm_runtime *runtime = substream->runtime;
 	struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component);
-	const struct sof_ipc_pcm_ops *pcm_ops = sdev->ipc->ops->pcm;
+	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
 	struct snd_sof_platform_stream_params platform_params = { 0 };
-	struct sof_ipc_fw_version *v = &sdev->fw_ready.version;
+	const struct sof_ipc_pcm_ops *pcm_ops = sdev->ipc->ops->pcm;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	struct snd_sof_pcm *spcm;
-	struct sof_ipc_pcm_params pcm;
-	struct sof_ipc_pcm_params_reply ipc_params_reply;
 	int ret;
 
 	/* nothing to do for BE */
@@ -153,117 +150,40 @@ static int sof_pcm_hw_params(struct snd_soc_component *component,
 	dev_dbg(component->dev, "pcm: hw params stream %d dir %d\n",
 		spcm->pcm.pcm_id, substream->stream);
 
-	memset(&pcm, 0, sizeof(pcm));
+	/* if this is a repeated hw_params without hw_free, skip setting up widgets */
+	if (!spcm->stream[substream->stream].list) {
+		ret = sof_pcm_setup_connected_widgets(sdev, rtd, spcm, substream->stream);
+		if (ret < 0)
+			return ret;
+	}
 
 	/* create compressed page table for audio firmware */
 	if (runtime->buffer_changed) {
 		ret = create_page_table(component, substream, runtime->dma_area,
 					runtime->dma_bytes);
+
 		if (ret < 0)
 			return ret;
 	}
 
-	/* number of pages should be rounded up */
-	pcm.params.buffer.pages = PFN_UP(runtime->dma_bytes);
-
-	/* set IPC PCM parameters */
-	pcm.hdr.size = sizeof(pcm);
-	pcm.hdr.cmd = SOF_IPC_GLB_STREAM_MSG | SOF_IPC_STREAM_PCM_PARAMS;
-	pcm.comp_id = spcm->stream[substream->stream].comp_id;
-	pcm.params.hdr.size = sizeof(pcm.params);
-	pcm.params.buffer.phy_addr =
-		spcm->stream[substream->stream].page_table.addr;
-	pcm.params.buffer.size = runtime->dma_bytes;
-	pcm.params.direction = substream->stream;
-	pcm.params.sample_valid_bytes = params_width(params) >> 3;
-	pcm.params.buffer_fmt = SOF_IPC_BUFFER_INTERLEAVED;
-	pcm.params.rate = params_rate(params);
-	pcm.params.channels = params_channels(params);
-	pcm.params.host_period_bytes = params_period_bytes(params);
-
-	/* container size */
-	ret = snd_pcm_format_physical_width(params_format(params));
-	if (ret < 0)
-		return ret;
-	pcm.params.sample_container_bytes = ret >> 3;
-
-	/* format */
-	switch (params_format(params)) {
-	case SNDRV_PCM_FORMAT_S16:
-		pcm.params.frame_fmt = SOF_IPC_FRAME_S16_LE;
-		break;
-	case SNDRV_PCM_FORMAT_S24:
-		pcm.params.frame_fmt = SOF_IPC_FRAME_S24_4LE;
-		break;
-	case SNDRV_PCM_FORMAT_S32:
-		pcm.params.frame_fmt = SOF_IPC_FRAME_S32_LE;
-		break;
-	case SNDRV_PCM_FORMAT_FLOAT:
-		pcm.params.frame_fmt = SOF_IPC_FRAME_FLOAT;
-		break;
-	default:
-		return -EINVAL;
-	}
-
-	/* firmware already configured host stream */
-	ret = snd_sof_pcm_platform_hw_params(sdev,
-					     substream,
-					     params,
-					     &platform_params);
+	ret = snd_sof_pcm_platform_hw_params(sdev, substream, params, &platform_params);
 	if (ret < 0) {
-		dev_err(component->dev, "error: platform hw params failed\n");
+		dev_err(component->dev, "platform hw params failed\n");
 		return ret;
 	}
 
-	/* Update the IPC message with information from the platform */
-	pcm.params.stream_tag = platform_params.stream_tag;
-
-	if (platform_params.use_phy_address)
-		pcm.params.buffer.phy_addr = platform_params.phy_addr;
-
-	if (platform_params.no_ipc_position) {
-		/* For older ABIs set host_period_bytes to zero to inform
-		 * FW we don't want position updates. Newer versions use
-		 * no_stream_position for this purpose.
-		 */
-		if (v->abi_version < SOF_ABI_VER(3, 10, 0))
-			pcm.params.host_period_bytes = 0;
-		else
-			pcm.params.no_stream_position = 1;
-	}
-
-	dev_dbg(component->dev, "stream_tag %d", pcm.params.stream_tag);
-
-	/* if this is a repeated hw_params without hw_free, skip setting up widgets */
-	if (!spcm->stream[substream->stream].list) {
-		ret = sof_pcm_setup_connected_widgets(sdev, rtd, spcm, substream->stream);
+	if (pcm_ops->hw_params) {
+		ret = pcm_ops->hw_params(component, substream, params, &platform_params);
 		if (ret < 0)
 			return ret;
 	}
 
-	/* send hw_params IPC to the DSP */
-	ret = sof_ipc_tx_message(sdev->ipc, pcm.hdr.cmd, &pcm, sizeof(pcm),
-				 &ipc_params_reply, sizeof(ipc_params_reply));
-	if (ret < 0) {
-		dev_err(component->dev, "error: hw params ipc failed for stream %d\n",
-			pcm.params.stream_tag);
-		return ret;
-	}
-
-	ret = snd_sof_set_stream_data_offset(sdev, substream,
-					     ipc_params_reply.posn_offset);
-	if (ret < 0) {
-		dev_err(component->dev, "%s: invalid stream data offset for PCM %d\n",
-			__func__, spcm->pcm.pcm_id);
-		return ret;
-	}
-
 	spcm->prepared[substream->stream] = true;
 
 	/* save pcm hw_params */
 	memcpy(&spcm->params[substream->stream], params, sizeof(*params));
 
-	return ret;
+	return 0;
 }
 
 static int sof_pcm_hw_free(struct snd_soc_component *component,
-- 
2.25.1


  parent reply	other threads:[~2022-03-17 17:57 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-03-17 17:50 [PATCH 00/19] Make the SOF control, PCM and PM code IPC agnostic Ranjani Sridharan
2022-03-17 17:50 ` [PATCH 01/19] ASoC: SOF: set up scheduler widget before all other widgets in the pipeline Ranjani Sridharan
2022-03-17 17:50 ` [PATCH 02/19] ASoC: SOF: Make sof_widget_setup/free IPC agnostic Ranjani Sridharan
2022-03-17 17:50 ` [PATCH 03/19] ASoC: SOF: Make sof_suspend/resume " Ranjani Sridharan
2022-03-17 17:50 ` [PATCH 04/19] ASoC: SOF: Introduce IPC ops for kcontrol IO Ranjani Sridharan
2022-03-17 17:50 ` [PATCH 05/19] ASoC: SOF: Add IPC3 topology control ops Ranjani Sridharan
2022-03-17 17:50 ` [PATCH 06/19] ASoC: SOF: Add volume_get/put IPC3 ops Ranjani Sridharan
2022-03-17 17:50 ` [PATCH 07/19] ASoC: SOF: Add switch get/put " Ranjani Sridharan
2022-03-17 17:50 ` [PATCH 08/19] ASoC: SOF: Add enum_get/put control ops for IPC3 Ranjani Sridharan
2022-03-17 17:50 ` [PATCH 09/19] ASoC: SOF: Add bytes_get/put control IPC " Ranjani Sridharan
2022-03-17 17:50 ` [PATCH 10/19] ASoC: SOF: Add bytes_ext " Ranjani Sridharan
2022-03-17 17:50 ` [PATCH 11/19] ASoC: SOF: Introduce IPC-specific PCM ops Ranjani Sridharan
2022-03-17 17:50 ` [PATCH 12/19] ASoC: SOF: pcm: expose the sof_pcm_setup_connected_widgets() function Ranjani Sridharan
2022-03-17 17:50 ` [PATCH 13/19] ASoC: SOF: Introduce IPC3 PCM hw_free op Ranjani Sridharan
2022-03-17 17:50 ` Ranjani Sridharan [this message]
2022-03-17 17:50 ` [PATCH 15/19] ASoC: SOF: Add trigger PCM op for IPC3 Ranjani Sridharan
2022-03-17 17:50 ` [PATCH 16/19] ASoC: SOF: Add dai_link_fixup " Ranjani Sridharan
2022-03-17 17:50 ` [PATCH 17/19] ASoC: SOF: expose sof_route_setup() Ranjani Sridharan
2022-03-17 17:50 ` [PATCH 18/19] ASoC: SOF: topology: Add ops for setting up and tearing down pipelines Ranjani Sridharan
2022-03-17 17:50 ` [PATCH 19/19] ASoC: SOF: Add a new dai_get_clk topology IPC op Ranjani Sridharan
2022-03-18 20:57 ` [PATCH 00/19] Make the SOF control, PCM and PM code IPC agnostic Mark Brown

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220317175044.1752400-15-ranjani.sridharan@linux.intel.com \
    --to=ranjani.sridharan@linux.intel.com \
    --cc=alsa-devel@alsa-project.org \
    --cc=broonie@kernel.org \
    --cc=peter.ujfalusi@linux.intel.com \
    --cc=pierre-louis.bossart@linux.intel.com \
    --cc=tiwai@suse.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.