Skip to content

Commit cefdaa2

Browse files
committed
ASoC: SOF: Convert the generic probe support to SOF client
Add a new client driver for probes support and move all the probes-related code from the core to the client driver. The probes client driver registers a component driver with one CPU DAI driver for extraction and creates a new sound card with one DUMMY DAI link with a dummy codec that will be used for extracting audio data from specific points in the audio pipeline. The probes debugfs ops are based on the initial implementation by Cezary Rojewski and have been moved out of the SOF core into the client driver making it easier to maintain. This change will make it easier for the probes functionality to be added for all platforms without having the need to modify the existing(15+) machine drivers. Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com> Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
1 parent 738c930 commit cefdaa2

File tree

19 files changed

+993
-826
lines changed

19 files changed

+993
-826
lines changed

sound/soc/sof/Kconfig

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,13 +51,14 @@ config SND_SOC_SOF_COMPRESS
5151
select SND_SOC_COMPRESS
5252

5353
config SND_SOC_SOF_DEBUG_PROBES
54-
bool "SOF enable data probing"
54+
tristate
55+
select SND_SOC_SOF_CLIENT
5556
select SND_SOC_COMPRESS
5657
help
5758
This option enables the data probing feature that can be used to
5859
gather data directly from specific points of the audio pipeline.
59-
Say Y if you want to enable probes.
60-
If unsure, select "N".
60+
This option is not user-selectable but automagically handled by
61+
'select' statements at a higher level.
6162

6263
config SND_SOC_SOF_CLIENT
6364
tristate

sound/soc/sof/Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@ snd-sof-objs := core.o ops.o loader.o ipc.o pcm.o pm.o debug.o topology.o\
44
control.o trace.o iomem-utils.o sof-audio.o stream-ipc.o
55
snd-sof-$(CONFIG_SND_SOC_SOF_CLIENT) += sof-client.o
66

7-
snd-sof-$(CONFIG_SND_SOC_SOF_DEBUG_PROBES) += sof-probes.o
87
snd-sof-$(CONFIG_SND_SOC_SOF_COMPRESS) += compress.o
98

109
snd-sof-pci-objs := sof-pci-dev.o
1110
snd-sof-acpi-objs := sof-acpi-dev.o
1211
snd-sof-of-objs := sof-of-dev.o
1312

1413
snd-sof-ipc-test-objs := sof-client-ipc-test.o
14+
snd-sof-probes-objs := sof-client-probes.o
1515

1616
snd-sof-nocodec-objs := nocodec.o
1717

@@ -27,6 +27,7 @@ obj-$(CONFIG_SND_SOC_SOF_OF) += snd-sof-of.o
2727
obj-$(CONFIG_SND_SOC_SOF_PCI_DEV) += snd-sof-pci.o
2828

2929
obj-$(CONFIG_SND_SOC_SOF_DEBUG_IPC_FLOOD_TEST) += snd-sof-ipc-test.o
30+
obj-$(CONFIG_SND_SOC_SOF_DEBUG_PROBES) += snd-sof-probes.o
3031

3132
obj-$(CONFIG_SND_SOC_SOF_INTEL_TOPLEVEL) += intel/
3233
obj-$(CONFIG_SND_SOC_SOF_IMX_TOPLEVEL) += imx/

sound/soc/sof/core.c

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,6 @@
1414
#include <sound/sof.h>
1515
#include "sof-priv.h"
1616
#include "ops.h"
17-
#if IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG_PROBES)
18-
#include "sof-probes.h"
19-
#endif
2017

2118
/* see SOF_DBG_ flags */
2219
int sof_core_debug = IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG_ENABLE_FIRMWARE_TRACE);
@@ -325,9 +322,6 @@ int snd_sof_device_probe(struct device *dev, struct snd_sof_pdata *plat_data)
325322

326323
sdev->pdata = plat_data;
327324
sdev->first_boot = true;
328-
#if IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG_PROBES)
329-
sdev->extractor_stream_tag = SOF_PROBE_INVALID_NODE_ID;
330-
#endif
331325
dev_set_drvdata(dev, sdev);
332326

333327
/* check all mandatory ops */

sound/soc/sof/debug.c

Lines changed: 0 additions & 227 deletions
Original file line numberDiff line numberDiff line change
@@ -19,222 +19,6 @@
1919
#include "sof-priv.h"
2020
#include "ops.h"
2121

22-
#if IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG_PROBES)
23-
#include "sof-probes.h"
24-
25-
/**
26-
* strsplit_u32 - Split string into sequence of u32 tokens
27-
* @buf: String to split into tokens.
28-
* @delim: String containing delimiter characters.
29-
* @tkns: Returned u32 sequence pointer.
30-
* @num_tkns: Returned number of tokens obtained.
31-
*/
32-
static int
33-
strsplit_u32(char **buf, const char *delim, u32 **tkns, size_t *num_tkns)
34-
{
35-
char *s;
36-
u32 *data, *tmp;
37-
size_t count = 0;
38-
size_t cap = 32;
39-
int ret = 0;
40-
41-
*tkns = NULL;
42-
*num_tkns = 0;
43-
data = kcalloc(cap, sizeof(*data), GFP_KERNEL);
44-
if (!data)
45-
return -ENOMEM;
46-
47-
while ((s = strsep(buf, delim)) != NULL) {
48-
ret = kstrtouint(s, 0, data + count);
49-
if (ret)
50-
goto exit;
51-
if (++count >= cap) {
52-
cap *= 2;
53-
tmp = krealloc(data, cap * sizeof(*data), GFP_KERNEL);
54-
if (!tmp) {
55-
ret = -ENOMEM;
56-
goto exit;
57-
}
58-
data = tmp;
59-
}
60-
}
61-
62-
if (!count)
63-
goto exit;
64-
*tkns = kmemdup(data, count * sizeof(*data), GFP_KERNEL);
65-
if (*tkns == NULL) {
66-
ret = -ENOMEM;
67-
goto exit;
68-
}
69-
*num_tkns = count;
70-
71-
exit:
72-
kfree(data);
73-
return ret;
74-
}
75-
76-
static int tokenize_input(const char __user *from, size_t count,
77-
loff_t *ppos, u32 **tkns, size_t *num_tkns)
78-
{
79-
char *buf;
80-
int ret;
81-
82-
buf = kmalloc(count + 1, GFP_KERNEL);
83-
if (!buf)
84-
return -ENOMEM;
85-
86-
ret = simple_write_to_buffer(buf, count, ppos, from, count);
87-
if (ret != count) {
88-
ret = ret >= 0 ? -EIO : ret;
89-
goto exit;
90-
}
91-
92-
buf[count] = '\0';
93-
ret = strsplit_u32((char **)&buf, ",", tkns, num_tkns);
94-
exit:
95-
kfree(buf);
96-
return ret;
97-
}
98-
99-
static ssize_t probe_points_read(struct file *file,
100-
char __user *to, size_t count, loff_t *ppos)
101-
{
102-
struct snd_sof_dfsentry *dfse = file->private_data;
103-
struct snd_sof_dev *sdev = dfse->sdev;
104-
struct sof_probe_point_desc *desc;
105-
size_t num_desc, len = 0;
106-
char *buf;
107-
int i, ret;
108-
109-
if (sdev->extractor_stream_tag == SOF_PROBE_INVALID_NODE_ID) {
110-
dev_warn(sdev->dev, "no extractor stream running\n");
111-
return -ENOENT;
112-
}
113-
114-
buf = kzalloc(PAGE_SIZE, GFP_KERNEL);
115-
if (!buf)
116-
return -ENOMEM;
117-
118-
ret = sof_ipc_probe_points_info(sdev, &desc, &num_desc);
119-
if (ret < 0)
120-
goto exit;
121-
122-
for (i = 0; i < num_desc; i++) {
123-
ret = snprintf(buf + len, PAGE_SIZE - len,
124-
"Id: %#010x Purpose: %d Node id: %#x\n",
125-
desc[i].buffer_id, desc[i].purpose, desc[i].stream_tag);
126-
if (ret < 0)
127-
goto free_desc;
128-
len += ret;
129-
}
130-
131-
ret = simple_read_from_buffer(to, count, ppos, buf, len);
132-
free_desc:
133-
kfree(desc);
134-
exit:
135-
kfree(buf);
136-
return ret;
137-
}
138-
139-
static ssize_t probe_points_write(struct file *file,
140-
const char __user *from, size_t count, loff_t *ppos)
141-
{
142-
struct snd_sof_dfsentry *dfse = file->private_data;
143-
struct snd_sof_dev *sdev = dfse->sdev;
144-
struct sof_probe_point_desc *desc;
145-
size_t num_tkns, bytes;
146-
u32 *tkns;
147-
int ret;
148-
149-
if (sdev->extractor_stream_tag == SOF_PROBE_INVALID_NODE_ID) {
150-
dev_warn(sdev->dev, "no extractor stream running\n");
151-
return -ENOENT;
152-
}
153-
154-
ret = tokenize_input(from, count, ppos, &tkns, &num_tkns);
155-
if (ret < 0)
156-
return ret;
157-
bytes = sizeof(*tkns) * num_tkns;
158-
if (!num_tkns || (bytes % sizeof(*desc))) {
159-
ret = -EINVAL;
160-
goto exit;
161-
}
162-
163-
desc = (struct sof_probe_point_desc *)tkns;
164-
ret = sof_ipc_probe_points_add(sdev,
165-
desc, bytes / sizeof(*desc));
166-
if (!ret)
167-
ret = count;
168-
exit:
169-
kfree(tkns);
170-
return ret;
171-
}
172-
173-
static const struct file_operations probe_points_fops = {
174-
.open = simple_open,
175-
.read = probe_points_read,
176-
.write = probe_points_write,
177-
.llseek = default_llseek,
178-
};
179-
180-
static ssize_t probe_points_remove_write(struct file *file,
181-
const char __user *from, size_t count, loff_t *ppos)
182-
{
183-
struct snd_sof_dfsentry *dfse = file->private_data;
184-
struct snd_sof_dev *sdev = dfse->sdev;
185-
size_t num_tkns;
186-
u32 *tkns;
187-
int ret;
188-
189-
if (sdev->extractor_stream_tag == SOF_PROBE_INVALID_NODE_ID) {
190-
dev_warn(sdev->dev, "no extractor stream running\n");
191-
return -ENOENT;
192-
}
193-
194-
ret = tokenize_input(from, count, ppos, &tkns, &num_tkns);
195-
if (ret < 0)
196-
return ret;
197-
if (!num_tkns) {
198-
ret = -EINVAL;
199-
goto exit;
200-
}
201-
202-
ret = sof_ipc_probe_points_remove(sdev, tkns, num_tkns);
203-
if (!ret)
204-
ret = count;
205-
exit:
206-
kfree(tkns);
207-
return ret;
208-
}
209-
210-
static const struct file_operations probe_points_remove_fops = {
211-
.open = simple_open,
212-
.write = probe_points_remove_write,
213-
.llseek = default_llseek,
214-
};
215-
216-
static int snd_sof_debugfs_probe_item(struct snd_sof_dev *sdev,
217-
const char *name, mode_t mode,
218-
const struct file_operations *fops)
219-
{
220-
struct snd_sof_dfsentry *dfse;
221-
222-
dfse = devm_kzalloc(sdev->dev, sizeof(*dfse), GFP_KERNEL);
223-
if (!dfse)
224-
return -ENOMEM;
225-
226-
dfse->type = SOF_DFSENTRY_TYPE_BUF;
227-
dfse->sdev = sdev;
228-
229-
debugfs_create_file(name, mode, sdev->debugfs_root, dfse, fops);
230-
/* add to dfsentry list */
231-
list_add(&dfse->list, &sdev->dfsentry_list);
232-
233-
return 0;
234-
}
235-
#endif
236-
237-
23822
static ssize_t sof_dfsentry_write(struct file *file, const char __user *buffer,
23923
size_t count, loff_t *ppos)
24024
{
@@ -570,17 +354,6 @@ int snd_sof_dbg_init(struct snd_sof_dev *sdev)
570354
return err;
571355
}
572356

573-
#if IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG_PROBES)
574-
err = snd_sof_debugfs_probe_item(sdev, "probe_points",
575-
0644, &probe_points_fops);
576-
if (err < 0)
577-
return err;
578-
err = snd_sof_debugfs_probe_item(sdev, "probe_points_remove",
579-
0200, &probe_points_remove_fops);
580-
if (err < 0)
581-
return err;
582-
#endif
583-
584357
return 0;
585358
}
586359
EXPORT_SYMBOL_GPL(snd_sof_dbg_init);

sound/soc/sof/intel/Kconfig

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,7 @@ config SND_SOC_SOF_HDA_COMMON
215215
select SND_SOC_SOF_PCI_DEV
216216
select SND_INTEL_DSP_CONFIG
217217
select SND_SOC_SOF_HDA_LINK_BASELINE
218+
select SND_SOC_SOF_HDA_PROBES
218219
help
219220
This option is not user-selectable but automagically handled by
220221
'select' statements at a higher level.
@@ -240,15 +241,6 @@ config SND_SOC_SOF_HDA_AUDIO_CODEC
240241
Say Y if you want to enable HDAudio codecs with SOF.
241242
If unsure select "N".
242243

243-
config SND_SOC_SOF_HDA_PROBES
244-
bool "SOF enable probes over HDA"
245-
depends on SND_SOC_SOF_DEBUG_PROBES
246-
help
247-
This option enables the data probing for Intel(R)
248-
Skylake and newer platforms.
249-
Say Y if you want to enable probes.
250-
If unsure, select "N".
251-
252244
endif ## SND_SOC_SOF_HDA_COMMON
253245

254246
config SND_SOC_SOF_HDA_LINK_BASELINE
@@ -266,6 +258,15 @@ config SND_SOC_SOF_HDA
266258
This option is not user-selectable but automagically handled by
267259
'select' statements at a higher level.
268260

261+
config SND_SOC_SOF_HDA_PROBES
262+
bool
263+
select SND_SOC_SOF_DEBUG_PROBES
264+
help
265+
The option enables the data probing for Intel(R) Skylake and newer
266+
(HDA) platforms.
267+
This option is not user-selectable but automagically handled by
268+
'select' statements at a higher level.
269+
269270
config SND_SOC_SOF_INTEL_SOUNDWIRE_LINK_BASELINE
270271
tristate
271272
select SOUNDWIRE_INTEL if SND_SOC_SOF_INTEL_SOUNDWIRE

sound/soc/sof/intel/apl.c

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,16 @@ static const struct snd_sof_debugfs_map apl_dsp_debugfs[] = {
2525
{"dsp", HDA_DSP_BAR, 0, 0x10000, SOF_DEBUGFS_ACCESS_ALWAYS},
2626
};
2727

28+
static int apl_register_clients(struct snd_sof_dev *sdev)
29+
{
30+
return hda_probes_register(sdev);
31+
}
32+
33+
static void apl_unregister_clients(struct snd_sof_dev *sdev)
34+
{
35+
hda_probes_unregister(sdev);
36+
}
37+
2838
/* apollolake ops */
2939
const struct snd_sof_dsp_ops sof_apl_ops = {
3040
/* probe/remove/shutdown */
@@ -80,15 +90,6 @@ const struct snd_sof_dsp_ops sof_apl_ops = {
8090
.pcm_pointer = hda_dsp_pcm_pointer,
8191
.pcm_ack = hda_dsp_pcm_ack,
8292

83-
#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_PROBES)
84-
/* probe callbacks */
85-
.probe_assign = hda_probe_compr_assign,
86-
.probe_free = hda_probe_compr_free,
87-
.probe_set_params = hda_probe_compr_set_params,
88-
.probe_trigger = hda_probe_compr_trigger,
89-
.probe_pointer = hda_probe_compr_pointer,
90-
#endif
91-
9293
/* firmware loading */
9394
.load_firmware = snd_sof_load_firmware_raw,
9495

@@ -111,6 +112,10 @@ const struct snd_sof_dsp_ops sof_apl_ops = {
111112
.trace_release = hda_dsp_trace_release,
112113
.trace_trigger = hda_dsp_trace_trigger,
113114

115+
/* client ops */
116+
.register_ipc_clients = apl_register_clients,
117+
.unregister_ipc_clients = apl_unregister_clients,
118+
114119
/* DAI drivers */
115120
.drv = skl_dai,
116121
.num_drv = SOF_SKL_NUM_DAIS,

0 commit comments

Comments
 (0)