Skip to content

Commit 4123c24

Browse files
ranj063broonie
authored andcommitted
ASoC: SOF: Introduce IPC3 PCM hw_free op
Add the IPC3 PCM ops, define the hw_free op and modify all users to use the op. 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> Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com> Link: https://lore.kernel.org/r/20220317175044.1752400-14-ranjani.sridharan@linux.intel.com Signed-off-by: Mark Brown <broonie@kernel.org>
1 parent 442c712 commit 4123c24

7 files changed

Lines changed: 72 additions & 35 deletions

File tree

sound/soc/sof/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
snd-sof-objs := core.o ops.o loader.o ipc.o pcm.o pm.o debug.o topology.o\
44
control.o trace.o iomem-utils.o sof-audio.o stream-ipc.o\
5-
ipc3-topology.o ipc3.o ipc3-control.o
5+
ipc3-topology.o ipc3.o ipc3-control.o ipc3-pcm.o
66
ifneq ($(CONFIG_SND_SOC_SOF_CLIENT),)
77
snd-sof-objs += sof-client.o
88
endif

sound/soc/sof/ipc.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1033,8 +1033,9 @@ struct snd_sof_ipc *snd_sof_ipc_init(struct snd_sof_dev *sdev)
10331033
ipc->ops = &ipc3_ops;
10341034

10351035
/* check for mandatory ops */
1036-
if (!ipc->ops->tplg || !ipc->ops->tplg->widget || !ipc->ops->tplg->control) {
1037-
dev_err(sdev->dev, "Invalid topology IPC ops\n");
1036+
if (!ipc->ops->pcm || !ipc->ops->tplg || !ipc->ops->tplg->widget ||
1037+
!ipc->ops->tplg->control) {
1038+
dev_err(sdev->dev, "Invalid IPC ops\n");
10381039
return NULL;
10391040
}
10401041

sound/soc/sof/ipc3-ops.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,6 @@
1616
extern const struct sof_ipc_tplg_ops ipc3_tplg_ops;
1717
extern const struct sof_ipc_ops ipc3_ops;
1818
extern const struct sof_ipc_tplg_control_ops tplg_ipc3_control_ops;
19+
extern const struct sof_ipc_pcm_ops ipc3_pcm_ops;
1920

2021
#endif

sound/soc/sof/ipc3-pcm.c

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
2+
//
3+
// This file is provided under a dual BSD/GPLv2 license. When using or
4+
// redistributing this file, you may do so under either license.
5+
//
6+
// Copyright(c) 2021 Intel Corporation. All rights reserved.
7+
//
8+
//
9+
10+
#include <sound/pcm_params.h>
11+
#include "ipc3-ops.h"
12+
#include "ops.h"
13+
#include "sof-priv.h"
14+
#include "sof-audio.h"
15+
16+
static int sof_ipc3_pcm_hw_free(struct snd_soc_component *component,
17+
struct snd_pcm_substream *substream)
18+
{
19+
struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component);
20+
struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
21+
struct sof_ipc_stream stream;
22+
struct sof_ipc_reply reply;
23+
struct snd_sof_pcm *spcm;
24+
25+
spcm = snd_sof_find_spcm_dai(component, rtd);
26+
if (!spcm)
27+
return -EINVAL;
28+
29+
if (!spcm->prepared[substream->stream])
30+
return 0;
31+
32+
stream.hdr.size = sizeof(stream);
33+
stream.hdr.cmd = SOF_IPC_GLB_STREAM_MSG | SOF_IPC_STREAM_PCM_FREE;
34+
stream.comp_id = spcm->stream[substream->stream].comp_id;
35+
36+
/* send IPC to the DSP */
37+
return sof_ipc_tx_message(sdev->ipc, stream.hdr.cmd, &stream,
38+
sizeof(stream), &reply, sizeof(reply));
39+
}
40+
41+
const struct sof_ipc_pcm_ops ipc3_pcm_ops = {
42+
.hw_free = sof_ipc3_pcm_hw_free,
43+
};

sound/soc/sof/ipc3.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,4 +41,5 @@ static const struct sof_ipc_pm_ops ipc3_pm_ops = {
4141
const struct sof_ipc_ops ipc3_ops = {
4242
.tplg = &ipc3_tplg_ops,
4343
.pm = &ipc3_pm_ops,
44+
.pcm = &ipc3_pcm_ops,
4445
};

sound/soc/sof/pcm.c

Lines changed: 15 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -82,29 +82,6 @@ void snd_sof_pcm_period_elapsed(struct snd_pcm_substream *substream)
8282
}
8383
EXPORT_SYMBOL(snd_sof_pcm_period_elapsed);
8484

85-
int sof_pcm_dsp_pcm_free(struct snd_pcm_substream *substream, struct snd_sof_dev *sdev,
86-
struct snd_sof_pcm *spcm)
87-
{
88-
struct sof_ipc_stream stream;
89-
struct sof_ipc_reply reply;
90-
int ret;
91-
92-
if (!spcm->prepared[substream->stream])
93-
return 0;
94-
95-
stream.hdr.size = sizeof(stream);
96-
stream.hdr.cmd = SOF_IPC_GLB_STREAM_MSG | SOF_IPC_STREAM_PCM_FREE;
97-
stream.comp_id = spcm->stream[substream->stream].comp_id;
98-
99-
/* send IPC to the DSP */
100-
ret = sof_ipc_tx_message(sdev->ipc, stream.hdr.cmd, &stream,
101-
sizeof(stream), &reply, sizeof(reply));
102-
if (!ret)
103-
spcm->prepared[substream->stream] = false;
104-
105-
return ret;
106-
}
107-
10885
int sof_pcm_setup_connected_widgets(struct snd_sof_dev *sdev, struct snd_soc_pcm_runtime *rtd,
10986
struct snd_sof_pcm *spcm, int dir)
11087
{
@@ -145,6 +122,7 @@ static int sof_pcm_hw_params(struct snd_soc_component *component,
145122
struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
146123
struct snd_pcm_runtime *runtime = substream->runtime;
147124
struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component);
125+
const struct sof_ipc_pcm_ops *pcm_ops = sdev->ipc->ops->pcm;
148126
struct snd_sof_platform_stream_params platform_params = { 0 };
149127
struct sof_ipc_fw_version *v = &sdev->fw_ready.version;
150128
struct snd_sof_pcm *spcm;
@@ -164,9 +142,13 @@ static int sof_pcm_hw_params(struct snd_soc_component *component,
164142
* Handle repeated calls to hw_params() without free_pcm() in
165143
* between. At least ALSA OSS emulation depends on this.
166144
*/
167-
ret = sof_pcm_dsp_pcm_free(substream, sdev, spcm);
168-
if (ret < 0)
169-
return ret;
145+
if (pcm_ops->hw_free && spcm->prepared[substream->stream]) {
146+
ret = pcm_ops->hw_free(component, substream);
147+
if (ret < 0)
148+
return ret;
149+
150+
spcm->prepared[substream->stream] = false;
151+
}
170152

171153
dev_dbg(component->dev, "pcm: hw params stream %d dir %d\n",
172154
spcm->pcm.pcm_id, substream->stream);
@@ -289,6 +271,7 @@ static int sof_pcm_hw_free(struct snd_soc_component *component,
289271
{
290272
struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
291273
struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component);
274+
const struct sof_ipc_pcm_ops *pcm_ops = sdev->ipc->ops->pcm;
292275
struct snd_sof_pcm *spcm;
293276
int ret, err = 0;
294277

@@ -304,10 +287,13 @@ static int sof_pcm_hw_free(struct snd_soc_component *component,
304287
spcm->pcm.pcm_id, substream->stream);
305288

306289
/* free PCM in the DSP */
307-
ret = sof_pcm_dsp_pcm_free(substream, sdev, spcm);
308-
if (ret < 0)
309-
err = ret;
290+
if (pcm_ops->hw_free && spcm->prepared[substream->stream]) {
291+
ret = pcm_ops->hw_free(component, substream);
292+
if (ret < 0)
293+
err = ret;
310294

295+
spcm->prepared[substream->stream] = false;
296+
}
311297

312298
/* stop DMA */
313299
ret = snd_sof_pcm_platform_hw_free(sdev, substream);

sound/soc/sof/sof-audio.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -591,12 +591,17 @@ int sof_set_up_pipelines(struct snd_sof_dev *sdev, bool verify)
591591
int sof_pcm_stream_free(struct snd_sof_dev *sdev, struct snd_pcm_substream *substream,
592592
struct snd_sof_pcm *spcm, int dir, bool free_widget_list)
593593
{
594+
const struct sof_ipc_pcm_ops *pcm_ops = sdev->ipc->ops->pcm;
594595
int ret;
595596

596597
/* Send PCM_FREE IPC to reset pipeline */
597-
ret = sof_pcm_dsp_pcm_free(substream, sdev, spcm);
598-
if (ret < 0)
599-
return ret;
598+
if (pcm_ops->hw_free && spcm->prepared[substream->stream]) {
599+
ret = pcm_ops->hw_free(sdev->component, substream);
600+
if (ret < 0)
601+
return ret;
602+
}
603+
604+
spcm->prepared[substream->stream] = false;
600605

601606
/* stop the DMA */
602607
ret = snd_sof_pcm_platform_hw_free(sdev, substream);

0 commit comments

Comments
 (0)