1*1a74b21cSV sujith kumar Reddy // SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
2*1a74b21cSV sujith kumar Reddy //
3*1a74b21cSV sujith kumar Reddy // This file is provided under a dual BSD/GPLv2 license. When using or
4*1a74b21cSV sujith kumar Reddy // redistributing this file, you may do so under either license.
5*1a74b21cSV sujith kumar Reddy //
6*1a74b21cSV sujith kumar Reddy // Copyright(c) 2023 Advanced Micro Devices, Inc.
7*1a74b21cSV sujith kumar Reddy //
8*1a74b21cSV sujith kumar Reddy // Authors: V Sujith Kumar Reddy <Vsujithkumar.Reddy@amd.com>
9*1a74b21cSV sujith kumar Reddy
10*1a74b21cSV sujith kumar Reddy /*
11*1a74b21cSV sujith kumar Reddy * Probe interface for generic AMD audio ACP DSP block
12*1a74b21cSV sujith kumar Reddy */
13*1a74b21cSV sujith kumar Reddy
14*1a74b21cSV sujith kumar Reddy #include <linux/module.h>
15*1a74b21cSV sujith kumar Reddy #include <sound/soc.h>
16*1a74b21cSV sujith kumar Reddy #include "../sof-priv.h"
17*1a74b21cSV sujith kumar Reddy #include "../sof-client-probes.h"
18*1a74b21cSV sujith kumar Reddy #include "../sof-client.h"
19*1a74b21cSV sujith kumar Reddy #include "../ops.h"
20*1a74b21cSV sujith kumar Reddy #include "acp.h"
21*1a74b21cSV sujith kumar Reddy #include "acp-dsp-offset.h"
22*1a74b21cSV sujith kumar Reddy
acp_probes_compr_startup(struct sof_client_dev * cdev,struct snd_compr_stream * cstream,struct snd_soc_dai * dai,u32 * stream_id)23*1a74b21cSV sujith kumar Reddy static int acp_probes_compr_startup(struct sof_client_dev *cdev,
24*1a74b21cSV sujith kumar Reddy struct snd_compr_stream *cstream,
25*1a74b21cSV sujith kumar Reddy struct snd_soc_dai *dai, u32 *stream_id)
26*1a74b21cSV sujith kumar Reddy {
27*1a74b21cSV sujith kumar Reddy struct snd_sof_dev *sdev = sof_client_dev_to_sof_dev(cdev);
28*1a74b21cSV sujith kumar Reddy struct acp_dsp_stream *stream;
29*1a74b21cSV sujith kumar Reddy struct acp_dev_data *adata;
30*1a74b21cSV sujith kumar Reddy
31*1a74b21cSV sujith kumar Reddy adata = sdev->pdata->hw_pdata;
32*1a74b21cSV sujith kumar Reddy stream = acp_dsp_stream_get(sdev, 0);
33*1a74b21cSV sujith kumar Reddy if (!stream)
34*1a74b21cSV sujith kumar Reddy return -ENODEV;
35*1a74b21cSV sujith kumar Reddy
36*1a74b21cSV sujith kumar Reddy stream->cstream = cstream;
37*1a74b21cSV sujith kumar Reddy cstream->runtime->private_data = stream;
38*1a74b21cSV sujith kumar Reddy
39*1a74b21cSV sujith kumar Reddy adata->probe_stream = stream;
40*1a74b21cSV sujith kumar Reddy *stream_id = stream->stream_tag;
41*1a74b21cSV sujith kumar Reddy
42*1a74b21cSV sujith kumar Reddy return 0;
43*1a74b21cSV sujith kumar Reddy }
44*1a74b21cSV sujith kumar Reddy
acp_probes_compr_shutdown(struct sof_client_dev * cdev,struct snd_compr_stream * cstream,struct snd_soc_dai * dai)45*1a74b21cSV sujith kumar Reddy static int acp_probes_compr_shutdown(struct sof_client_dev *cdev,
46*1a74b21cSV sujith kumar Reddy struct snd_compr_stream *cstream,
47*1a74b21cSV sujith kumar Reddy struct snd_soc_dai *dai)
48*1a74b21cSV sujith kumar Reddy {
49*1a74b21cSV sujith kumar Reddy struct snd_sof_dev *sdev = sof_client_dev_to_sof_dev(cdev);
50*1a74b21cSV sujith kumar Reddy struct acp_dsp_stream *stream = cstream->runtime->private_data;
51*1a74b21cSV sujith kumar Reddy struct acp_dev_data *adata;
52*1a74b21cSV sujith kumar Reddy int ret;
53*1a74b21cSV sujith kumar Reddy
54*1a74b21cSV sujith kumar Reddy ret = acp_dsp_stream_put(sdev, stream);
55*1a74b21cSV sujith kumar Reddy if (ret < 0) {
56*1a74b21cSV sujith kumar Reddy dev_err(sdev->dev, "Failed to release probe compress stream\n");
57*1a74b21cSV sujith kumar Reddy return ret;
58*1a74b21cSV sujith kumar Reddy }
59*1a74b21cSV sujith kumar Reddy
60*1a74b21cSV sujith kumar Reddy adata = sdev->pdata->hw_pdata;
61*1a74b21cSV sujith kumar Reddy stream->cstream = NULL;
62*1a74b21cSV sujith kumar Reddy cstream->runtime->private_data = NULL;
63*1a74b21cSV sujith kumar Reddy adata->probe_stream = NULL;
64*1a74b21cSV sujith kumar Reddy
65*1a74b21cSV sujith kumar Reddy return 0;
66*1a74b21cSV sujith kumar Reddy }
67*1a74b21cSV sujith kumar Reddy
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)68*1a74b21cSV sujith kumar Reddy static int acp_probes_compr_set_params(struct sof_client_dev *cdev,
69*1a74b21cSV sujith kumar Reddy struct snd_compr_stream *cstream,
70*1a74b21cSV sujith kumar Reddy struct snd_compr_params *params,
71*1a74b21cSV sujith kumar Reddy struct snd_soc_dai *dai)
72*1a74b21cSV sujith kumar Reddy {
73*1a74b21cSV sujith kumar Reddy struct snd_sof_dev *sdev = sof_client_dev_to_sof_dev(cdev);
74*1a74b21cSV sujith kumar Reddy struct acp_dsp_stream *stream = cstream->runtime->private_data;
75*1a74b21cSV sujith kumar Reddy unsigned int buf_offset, index;
76*1a74b21cSV sujith kumar Reddy u32 size;
77*1a74b21cSV sujith kumar Reddy int ret;
78*1a74b21cSV sujith kumar Reddy
79*1a74b21cSV sujith kumar Reddy stream->dmab = cstream->runtime->dma_buffer_p;
80*1a74b21cSV sujith kumar Reddy stream->num_pages = PFN_UP(cstream->runtime->dma_bytes);
81*1a74b21cSV sujith kumar Reddy size = cstream->runtime->buffer_size;
82*1a74b21cSV sujith kumar Reddy
83*1a74b21cSV sujith kumar Reddy ret = acp_dsp_stream_config(sdev, stream);
84*1a74b21cSV sujith kumar Reddy if (ret < 0) {
85*1a74b21cSV sujith kumar Reddy acp_dsp_stream_put(sdev, stream);
86*1a74b21cSV sujith kumar Reddy return ret;
87*1a74b21cSV sujith kumar Reddy }
88*1a74b21cSV sujith kumar Reddy
89*1a74b21cSV sujith kumar Reddy /* write buffer size of stream in scratch memory */
90*1a74b21cSV sujith kumar Reddy
91*1a74b21cSV sujith kumar Reddy buf_offset = sdev->debug_box.offset +
92*1a74b21cSV sujith kumar Reddy offsetof(struct scratch_reg_conf, buf_size);
93*1a74b21cSV sujith kumar Reddy index = stream->stream_tag - 1;
94*1a74b21cSV sujith kumar Reddy buf_offset = buf_offset + index * 4;
95*1a74b21cSV sujith kumar Reddy
96*1a74b21cSV sujith kumar Reddy snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_SCRATCH_REG_0 + buf_offset, size);
97*1a74b21cSV sujith kumar Reddy
98*1a74b21cSV sujith kumar Reddy return 0;
99*1a74b21cSV sujith kumar Reddy }
100*1a74b21cSV sujith kumar Reddy
acp_probes_compr_trigger(struct sof_client_dev * cdev,struct snd_compr_stream * cstream,int cmd,struct snd_soc_dai * dai)101*1a74b21cSV sujith kumar Reddy static int acp_probes_compr_trigger(struct sof_client_dev *cdev,
102*1a74b21cSV sujith kumar Reddy struct snd_compr_stream *cstream,
103*1a74b21cSV sujith kumar Reddy int cmd, struct snd_soc_dai *dai)
104*1a74b21cSV sujith kumar Reddy {
105*1a74b21cSV sujith kumar Reddy /* Nothing to do here, as it is a mandatory callback just defined */
106*1a74b21cSV sujith kumar Reddy return 0;
107*1a74b21cSV sujith kumar Reddy }
108*1a74b21cSV sujith kumar Reddy
acp_probes_compr_pointer(struct sof_client_dev * cdev,struct snd_compr_stream * cstream,struct snd_compr_tstamp * tstamp,struct snd_soc_dai * dai)109*1a74b21cSV sujith kumar Reddy static int acp_probes_compr_pointer(struct sof_client_dev *cdev,
110*1a74b21cSV sujith kumar Reddy struct snd_compr_stream *cstream,
111*1a74b21cSV sujith kumar Reddy struct snd_compr_tstamp *tstamp,
112*1a74b21cSV sujith kumar Reddy struct snd_soc_dai *dai)
113*1a74b21cSV sujith kumar Reddy {
114*1a74b21cSV sujith kumar Reddy struct acp_dsp_stream *stream = cstream->runtime->private_data;
115*1a74b21cSV sujith kumar Reddy struct snd_soc_pcm_stream *pstream;
116*1a74b21cSV sujith kumar Reddy
117*1a74b21cSV sujith kumar Reddy pstream = &dai->driver->capture;
118*1a74b21cSV sujith kumar Reddy tstamp->copied_total = stream->cstream_posn;
119*1a74b21cSV sujith kumar Reddy tstamp->sampling_rate = snd_pcm_rate_bit_to_rate(pstream->rates);
120*1a74b21cSV sujith kumar Reddy
121*1a74b21cSV sujith kumar Reddy return 0;
122*1a74b21cSV sujith kumar Reddy }
123*1a74b21cSV sujith kumar Reddy
124*1a74b21cSV sujith kumar Reddy /* SOF client implementation */
125*1a74b21cSV sujith kumar Reddy static const struct sof_probes_host_ops acp_probes_ops = {
126*1a74b21cSV sujith kumar Reddy .startup = acp_probes_compr_startup,
127*1a74b21cSV sujith kumar Reddy .shutdown = acp_probes_compr_shutdown,
128*1a74b21cSV sujith kumar Reddy .set_params = acp_probes_compr_set_params,
129*1a74b21cSV sujith kumar Reddy .trigger = acp_probes_compr_trigger,
130*1a74b21cSV sujith kumar Reddy .pointer = acp_probes_compr_pointer,
131*1a74b21cSV sujith kumar Reddy };
132*1a74b21cSV sujith kumar Reddy
acp_probes_register(struct snd_sof_dev * sdev)133*1a74b21cSV sujith kumar Reddy int acp_probes_register(struct snd_sof_dev *sdev)
134*1a74b21cSV sujith kumar Reddy {
135*1a74b21cSV sujith kumar Reddy return sof_client_dev_register(sdev, "acp-probes", 0, &acp_probes_ops,
136*1a74b21cSV sujith kumar Reddy sizeof(acp_probes_ops));
137*1a74b21cSV sujith kumar Reddy }
138*1a74b21cSV sujith kumar Reddy EXPORT_SYMBOL_NS(acp_probes_register, SND_SOC_SOF_AMD_COMMON);
139*1a74b21cSV sujith kumar Reddy
acp_probes_unregister(struct snd_sof_dev * sdev)140*1a74b21cSV sujith kumar Reddy void acp_probes_unregister(struct snd_sof_dev *sdev)
141*1a74b21cSV sujith kumar Reddy {
142*1a74b21cSV sujith kumar Reddy sof_client_dev_unregister(sdev, "acp-probes", 0);
143*1a74b21cSV sujith kumar Reddy }
144*1a74b21cSV sujith kumar Reddy EXPORT_SYMBOL_NS(acp_probes_unregister, SND_SOC_SOF_AMD_COMMON);
145*1a74b21cSV sujith kumar Reddy
146*1a74b21cSV sujith kumar Reddy MODULE_IMPORT_NS(SND_SOC_SOF_CLIENT);
147*1a74b21cSV sujith kumar Reddy
148