xref: /openbmc/linux/sound/soc/sof/amd/acp-pcm.c (revision 9f99d983)
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 Advanced Micro Devices, Inc.
7 //
8 // Authors: Ajit Kumar Pandey <AjitKumar.Pandey@amd.com>
9 
10 /*
11  * PCM interface for generic AMD audio ACP DSP block
12  */
13 #include <sound/pcm_params.h>
14 
15 #include "../ops.h"
16 #include "acp.h"
17 #include "acp-dsp-offset.h"
18 
19 int acp_pcm_hw_params(struct snd_sof_dev *sdev, struct snd_pcm_substream *substream,
20 		      struct snd_pcm_hw_params *params, struct sof_ipc_stream_params *ipc_params)
21 {
22 	struct acp_dsp_stream *stream = substream->runtime->private_data;
23 	unsigned int buf_offset, index;
24 	u32 size;
25 	int ret;
26 
27 	size = ipc_params->buffer.size;
28 	stream->num_pages = ipc_params->buffer.pages;
29 	stream->dmab = substream->runtime->dma_buffer_p;
30 
31 	ret = acp_dsp_stream_config(sdev, stream);
32 	if (ret < 0) {
33 		dev_err(sdev->dev, "stream configuration failed\n");
34 		return ret;
35 	}
36 
37 	ipc_params->buffer.phy_addr = stream->reg_offset;
38 	ipc_params->stream_tag = stream->stream_tag;
39 
40 	/* write buffer size of stream in scratch memory */
41 
42 	buf_offset = offsetof(struct scratch_reg_conf, buf_size);
43 	index = stream->stream_tag - 1;
44 	buf_offset = buf_offset + index * 4;
45 
46 	snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_SCRATCH_REG_0 + buf_offset, size);
47 
48 	return 0;
49 }
50 EXPORT_SYMBOL_NS(acp_pcm_hw_params, SND_SOC_SOF_AMD_COMMON);
51 
52 int acp_pcm_open(struct snd_sof_dev *sdev, struct snd_pcm_substream *substream)
53 {
54 	struct acp_dsp_stream *stream;
55 
56 	stream = acp_dsp_stream_get(sdev, 0);
57 	if (!stream)
58 		return -ENODEV;
59 
60 	substream->runtime->private_data = stream;
61 	stream->substream = substream;
62 
63 	return 0;
64 }
65 EXPORT_SYMBOL_NS(acp_pcm_open, SND_SOC_SOF_AMD_COMMON);
66 
67 int acp_pcm_close(struct snd_sof_dev *sdev, struct snd_pcm_substream *substream)
68 {
69 	struct acp_dsp_stream *stream;
70 
71 	stream = substream->runtime->private_data;
72 	if (!stream) {
73 		dev_err(sdev->dev, "No open stream\n");
74 		return -EINVAL;
75 	}
76 
77 	stream->substream = NULL;
78 	substream->runtime->private_data = NULL;
79 
80 	return acp_dsp_stream_put(sdev, stream);
81 }
82 EXPORT_SYMBOL_NS(acp_pcm_close, SND_SOC_SOF_AMD_COMMON);
83