| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147 |
- // SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
- //
- // This file is provided under a dual BSD/GPLv2 license. When using or
- // redistributing this file, you may do so under either license.
- //
- // Copyright(c) 2023 Advanced Micro Devices, Inc.
- //
- // Authors: V Sujith Kumar Reddy <Vsujithkumar.Reddy@amd.com>
- /*
- * Probe interface for generic AMD audio ACP DSP block
- */
- #include <linux/module.h>
- #include <sound/soc.h>
- #include "../sof-priv.h"
- #include "../sof-client-probes.h"
- #include "../sof-client.h"
- #include "../ops.h"
- #include "acp.h"
- #include "acp-dsp-offset.h"
- static int acp_probes_compr_startup(struct sof_client_dev *cdev,
- struct snd_compr_stream *cstream,
- struct snd_soc_dai *dai, u32 *stream_id)
- {
- struct snd_sof_dev *sdev = sof_client_dev_to_sof_dev(cdev);
- struct acp_dsp_stream *stream;
- struct acp_dev_data *adata;
- adata = sdev->pdata->hw_pdata;
- stream = acp_dsp_stream_get(sdev, 0);
- if (!stream)
- return -ENODEV;
- stream->cstream = cstream;
- cstream->runtime->private_data = stream;
- adata->probe_stream = stream;
- *stream_id = stream->stream_tag;
- return 0;
- }
- static int acp_probes_compr_shutdown(struct sof_client_dev *cdev,
- struct snd_compr_stream *cstream,
- struct snd_soc_dai *dai)
- {
- struct snd_sof_dev *sdev = sof_client_dev_to_sof_dev(cdev);
- struct acp_dsp_stream *stream = cstream->runtime->private_data;
- struct acp_dev_data *adata;
- int ret;
- ret = acp_dsp_stream_put(sdev, stream);
- if (ret < 0) {
- dev_err(sdev->dev, "Failed to release probe compress stream\n");
- return ret;
- }
- adata = sdev->pdata->hw_pdata;
- stream->cstream = NULL;
- cstream->runtime->private_data = NULL;
- adata->probe_stream = NULL;
- return 0;
- }
- static int acp_probes_compr_set_params(struct sof_client_dev *cdev,
- struct snd_compr_stream *cstream,
- struct snd_compr_params *params,
- struct snd_soc_dai *dai)
- {
- struct snd_sof_dev *sdev = sof_client_dev_to_sof_dev(cdev);
- struct acp_dsp_stream *stream = cstream->runtime->private_data;
- unsigned int buf_offset, index;
- u32 size;
- int ret;
- stream->dmab = cstream->runtime->dma_buffer_p;
- stream->num_pages = PFN_UP(cstream->runtime->dma_bytes);
- size = cstream->runtime->buffer_size;
- ret = acp_dsp_stream_config(sdev, stream);
- if (ret < 0) {
- acp_dsp_stream_put(sdev, stream);
- return ret;
- }
- /* write buffer size of stream in scratch memory */
- buf_offset = sdev->debug_box.offset +
- offsetof(struct scratch_reg_conf, buf_size);
- index = stream->stream_tag - 1;
- buf_offset = buf_offset + index * 4;
- snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_SCRATCH_REG_0 + buf_offset, size);
- return 0;
- }
- static int acp_probes_compr_trigger(struct sof_client_dev *cdev,
- struct snd_compr_stream *cstream,
- int cmd, struct snd_soc_dai *dai)
- {
- /* Nothing to do here, as it is a mandatory callback just defined */
- return 0;
- }
- static int acp_probes_compr_pointer(struct sof_client_dev *cdev,
- struct snd_compr_stream *cstream,
- struct snd_compr_tstamp64 *tstamp,
- struct snd_soc_dai *dai)
- {
- struct acp_dsp_stream *stream = cstream->runtime->private_data;
- struct snd_soc_pcm_stream *pstream;
- pstream = &dai->driver->capture;
- tstamp->copied_total = stream->cstream_posn;
- tstamp->sampling_rate = snd_pcm_rate_bit_to_rate(pstream->rates);
- return 0;
- }
- /* SOF client implementation */
- static const struct sof_probes_host_ops acp_probes_ops = {
- .startup = acp_probes_compr_startup,
- .shutdown = acp_probes_compr_shutdown,
- .set_params = acp_probes_compr_set_params,
- .trigger = acp_probes_compr_trigger,
- .pointer = acp_probes_compr_pointer,
- };
- int acp_probes_register(struct snd_sof_dev *sdev)
- {
- return sof_client_dev_register(sdev, "acp-probes", 0, &acp_probes_ops,
- sizeof(acp_probes_ops));
- }
- EXPORT_SYMBOL_NS(acp_probes_register, "SND_SOC_SOF_AMD_COMMON");
- void acp_probes_unregister(struct snd_sof_dev *sdev)
- {
- sof_client_dev_unregister(sdev, "acp-probes", 0);
- }
- EXPORT_SYMBOL_NS(acp_probes_unregister, "SND_SOC_SOF_AMD_COMMON");
- MODULE_IMPORT_NS("SND_SOC_SOF_CLIENT");
|