1 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
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.
6 // Copyright(c) 2021 Advanced Micro Devices, Inc.
8 // Authors: Ajit Kumar Pandey <AjitKumar.Pandey@amd.com>
11 * PCM interface for generic AMD audio ACP DSP block
13 #include <sound/pcm_params.h>
17 #include "acp-dsp-offset.h"
19 int acp_pcm_hw_params(struct snd_sof_dev
*sdev
, struct snd_pcm_substream
*substream
,
20 struct snd_pcm_hw_params
*params
,
21 struct snd_sof_platform_stream_params
*platform_params
)
23 struct snd_pcm_runtime
*runtime
= substream
->runtime
;
24 struct acp_dsp_stream
*stream
= runtime
->private_data
;
25 unsigned int buf_offset
, index
;
29 size
= runtime
->dma_bytes
;
30 stream
->num_pages
= PFN_UP(runtime
->dma_bytes
);
31 stream
->dmab
= substream
->runtime
->dma_buffer_p
;
33 ret
= acp_dsp_stream_config(sdev
, stream
);
35 dev_err(sdev
->dev
, "stream configuration failed\n");
39 platform_params
->use_phy_address
= true;
40 platform_params
->phy_addr
= stream
->reg_offset
;
41 platform_params
->stream_tag
= stream
->stream_tag
;
42 platform_params
->cont_update_posn
= 1;
44 /* write buffer size of stream in scratch memory */
46 buf_offset
= sdev
->debug_box
.offset
+
47 offsetof(struct scratch_reg_conf
, buf_size
);
48 index
= stream
->stream_tag
- 1;
49 buf_offset
= buf_offset
+ index
* 4;
51 snd_sof_dsp_write(sdev
, ACP_DSP_BAR
, ACP_SCRATCH_REG_0
+ buf_offset
, size
);
55 EXPORT_SYMBOL_NS(acp_pcm_hw_params
, "SND_SOC_SOF_AMD_COMMON");
57 int acp_pcm_open(struct snd_sof_dev
*sdev
, struct snd_pcm_substream
*substream
)
59 struct acp_dsp_stream
*stream
;
61 stream
= acp_dsp_stream_get(sdev
, 0);
65 substream
->runtime
->private_data
= stream
;
66 stream
->substream
= substream
;
70 EXPORT_SYMBOL_NS(acp_pcm_open
, "SND_SOC_SOF_AMD_COMMON");
72 int acp_pcm_close(struct snd_sof_dev
*sdev
, struct snd_pcm_substream
*substream
)
74 struct acp_dsp_stream
*stream
;
76 stream
= substream
->runtime
->private_data
;
78 dev_err(sdev
->dev
, "No open stream\n");
82 stream
->substream
= NULL
;
83 substream
->runtime
->private_data
= NULL
;
85 return acp_dsp_stream_put(sdev
, stream
);
87 EXPORT_SYMBOL_NS(acp_pcm_close
, "SND_SOC_SOF_AMD_COMMON");
89 snd_pcm_uframes_t
acp_pcm_pointer(struct snd_sof_dev
*sdev
,
90 struct snd_pcm_substream
*substream
)
92 struct snd_soc_pcm_runtime
*rtd
= snd_soc_substream_to_rtd(substream
);
93 struct snd_soc_component
*scomp
= sdev
->component
;
94 struct snd_sof_pcm_stream
*stream
;
95 struct sof_ipc_stream_posn posn
;
96 struct snd_sof_pcm
*spcm
;
97 snd_pcm_uframes_t pos
;
100 spcm
= snd_sof_find_spcm_dai(scomp
, rtd
);
102 dev_warn_ratelimited(sdev
->dev
, "warn: can't find PCM with DAI ID %d\n",
107 stream
= &spcm
->stream
[substream
->stream
];
108 ret
= snd_sof_ipc_msg_data(sdev
, stream
, &posn
, sizeof(posn
));
110 dev_warn(sdev
->dev
, "failed to read stream position: %d\n", ret
);
114 memcpy(&stream
->posn
, &posn
, sizeof(posn
));
115 pos
= spcm
->stream
[substream
->stream
].posn
.host_posn
;
116 pos
= bytes_to_frames(substream
->runtime
, pos
);
120 EXPORT_SYMBOL_NS(acp_pcm_pointer
, "SND_SOC_SOF_AMD_COMMON");