summaryrefslogtreecommitdiff
path: root/sound
diff options
context:
space:
mode:
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/sof/amd/acp-common.c1
-rw-r--r--sound/soc/sof/amd/acp-ipc.c30
-rw-r--r--sound/soc/sof/amd/acp.h4
3 files changed, 34 insertions, 1 deletions
diff --git a/sound/soc/sof/amd/acp-common.c b/sound/soc/sof/amd/acp-common.c
index 27b95187356e..150e042e4039 100644
--- a/sound/soc/sof/amd/acp-common.c
+++ b/sound/soc/sof/amd/acp-common.c
@@ -76,6 +76,7 @@ struct snd_sof_dsp_ops sof_acp_common_ops = {
/*IPC */
.send_msg = acp_sof_ipc_send_msg,
.ipc_msg_data = acp_sof_ipc_msg_data,
+ .set_stream_data_offset = acp_set_stream_data_offset,
.get_mailbox_offset = acp_sof_ipc_get_mailbox_offset,
.get_window_offset = acp_sof_ipc_get_window_offset,
.irq_thread = acp_sof_ipc_irq_thread,
diff --git a/sound/soc/sof/amd/acp-ipc.c b/sound/soc/sof/amd/acp-ipc.c
index dd030566e372..dd6e53c63407 100644
--- a/sound/soc/sof/amd/acp-ipc.c
+++ b/sound/soc/sof/amd/acp-ipc.c
@@ -192,13 +192,41 @@ int acp_sof_ipc_msg_data(struct snd_sof_dev *sdev, struct snd_pcm_substream *sub
{
unsigned int offset = sdev->dsp_box.offset;
- if (!substream || !sdev->stream_box.size)
+ if (!substream || !sdev->stream_box.size) {
acp_mailbox_read(sdev, offset, p, sz);
+ } else {
+ struct acp_dsp_stream *stream = substream->runtime->private_data;
+
+ if (!stream)
+ return -ESTRPIPE;
+
+ acp_mailbox_read(sdev, stream->posn_offset, p, sz);
+ }
return 0;
}
EXPORT_SYMBOL_NS(acp_sof_ipc_msg_data, SND_SOC_SOF_AMD_COMMON);
+int acp_set_stream_data_offset(struct snd_sof_dev *sdev,
+ struct snd_pcm_substream *substream,
+ size_t posn_offset)
+{
+ struct acp_dsp_stream *stream = substream->runtime->private_data;
+
+ /* check for unaligned offset or overflow */
+ if (posn_offset > sdev->stream_box.size ||
+ posn_offset % sizeof(struct sof_ipc_stream_posn) != 0)
+ return -EINVAL;
+
+ stream->posn_offset = sdev->stream_box.offset + posn_offset;
+
+ dev_dbg(sdev->dev, "pcm: stream dir %d, posn mailbox offset is %zu",
+ substream->stream, stream->posn_offset);
+
+ return 0;
+}
+EXPORT_SYMBOL_NS(acp_set_stream_data_offset, SND_SOC_SOF_AMD_COMMON);
+
int acp_sof_ipc_get_mailbox_offset(struct snd_sof_dev *sdev)
{
const struct sof_amd_acp_desc *desc = get_chip_info(sdev->pdata);
diff --git a/sound/soc/sof/amd/acp.h b/sound/soc/sof/amd/acp.h
index dd3c072d0172..1529c6d9bf9b 100644
--- a/sound/soc/sof/amd/acp.h
+++ b/sound/soc/sof/amd/acp.h
@@ -138,6 +138,7 @@ struct acp_dsp_stream {
int stream_tag;
int active;
unsigned int reg_offset;
+ size_t posn_offset;
};
struct sof_amd_acp_desc {
@@ -199,6 +200,9 @@ int acp_dsp_block_read(struct snd_sof_dev *sdev, enum snd_sof_fw_blk_type blk_ty
irqreturn_t acp_sof_ipc_irq_thread(int irq, void *context);
int acp_sof_ipc_msg_data(struct snd_sof_dev *sdev, struct snd_pcm_substream *substream,
void *p, size_t sz);
+int acp_set_stream_data_offset(struct snd_sof_dev *sdev,
+ struct snd_pcm_substream *substream,
+ size_t posn_offset);
int acp_sof_ipc_send_msg(struct snd_sof_dev *sdev,
struct snd_sof_ipc_msg *msg);
int acp_sof_ipc_get_mailbox_offset(struct snd_sof_dev *sdev);