Skip to content

Commit 6297911

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 d18caa1 commit 6297911

File tree

19 files changed

+963
-817
lines changed

19 files changed

+963
-817
lines changed

sound/soc/sof/Kconfig

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,14 @@ config SND_SOC_SOF_OF
4747
Say Y if you need this option. If unsure select "N".
4848

4949
config SND_SOC_SOF_DEBUG_PROBES
50-
bool "SOF enable data probing"
50+
tristate
51+
select SND_SOC_SOF_CLIENT
5152
select SND_SOC_COMPRESS
5253
help
5354
This option enables the data probing feature that can be used to
5455
gather data directly from specific points of the audio pipeline.
55-
Say Y if you want to enable probes.
56-
If unsure, select "N".
56+
This option is not user-selectable but automagically handled by
57+
'select' statements at a higher level.
5758

5859
config SND_SOC_SOF_PCM_DISABLE_PAUSE
5960
bool "SOF disable pause push/release"

sound/soc/sof/Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,12 @@ snd-sof-objs := core.o ops.o loader.o ipc.o pcm.o pm.o debug.o topology.o\
44
control.o trace.o utils.o sof-audio.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
8-
97
snd-sof-pci-objs := sof-pci-dev.o
108
snd-sof-acpi-objs := sof-acpi-dev.o
119
snd-sof-of-objs := sof-of-dev.o
1210

1311
snd-sof-ipc-test-objs := sof-client-ipc-test.o
12+
snd-sof-probes-objs := sof-client-probes.o
1413

1514
snd-sof-nocodec-objs := nocodec.o
1615

@@ -23,6 +22,7 @@ obj-$(CONFIG_SND_SOC_SOF_OF) += snd-sof-of.o
2322
obj-$(CONFIG_SND_SOC_SOF_PCI_DEV) += snd-sof-pci.o
2423

2524
obj-$(CONFIG_SND_SOC_SOF_DEBUG_IPC_FLOOD_TEST) += snd-sof-ipc-test.o
25+
obj-$(CONFIG_SND_SOC_SOF_DEBUG_PROBES) += snd-sof-probes.o
2626

2727
obj-$(CONFIG_SND_SOC_SOF_INTEL_TOPLEVEL) += intel/
2828
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
@@ -15,9 +15,6 @@
1515
#include "sof-client.h"
1616
#include "sof-priv.h"
1717
#include "ops.h"
18-
#if IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG_PROBES)
19-
#include "sof-probes.h"
20-
#endif
2118

2219
/* see SOF_DBG_ flags */
2320
int sof_core_debug;
@@ -311,9 +308,6 @@ int snd_sof_device_probe(struct device *dev, struct snd_sof_pdata *plat_data)
311308
sdev->pdata = plat_data;
312309
sdev->first_boot = true;
313310
sdev->fw_state = SOF_FW_BOOT_NOT_STARTED;
314-
#if IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG_PROBES)
315-
sdev->extractor_stream_tag = SOF_PROBE_INVALID_NODE_ID;
316-
#endif
317311
dev_set_drvdata(dev, sdev);
318312

319313
/* 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: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ config SND_SOC_SOF_HDA_AUDIO_CODEC
242242

243243
config SND_SOC_SOF_HDA_PROBES
244244
bool "SOF enable probes over HDA"
245-
depends on SND_SOC_SOF_DEBUG_PROBES
245+
select SND_SOC_SOF_DEBUG_PROBES
246246
help
247247
This option enables the data probing for Intel(R)
248248
Skylake and newer platforms.

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 */
@@ -76,15 +86,6 @@ const struct snd_sof_dsp_ops sof_apl_ops = {
7686
.pcm_pointer = hda_dsp_pcm_pointer,
7787
.pcm_ack = hda_dsp_pcm_ack,
7888

79-
#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_PROBES)
80-
/* probe callbacks */
81-
.probe_assign = hda_probe_compr_assign,
82-
.probe_free = hda_probe_compr_free,
83-
.probe_set_params = hda_probe_compr_set_params,
84-
.probe_trigger = hda_probe_compr_trigger,
85-
.probe_pointer = hda_probe_compr_pointer,
86-
#endif
87-
8889
/* firmware loading */
8990
.load_firmware = snd_sof_load_firmware_raw,
9091

@@ -107,6 +108,10 @@ const struct snd_sof_dsp_ops sof_apl_ops = {
107108
.trace_release = hda_dsp_trace_release,
108109
.trace_trigger = hda_dsp_trace_trigger,
109110

111+
/* client ops */
112+
.register_ipc_clients = apl_register_clients,
113+
.unregister_ipc_clients = apl_unregister_clients,
114+
110115
/* DAI drivers */
111116
.drv = skl_dai,
112117
.num_drv = SOF_SKL_NUM_DAIS,

sound/soc/sof/intel/cnl.c

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,16 @@ void cnl_ipc_dump(struct snd_sof_dev *sdev)
230230
hipcida, hipctdr, hipcctl);
231231
}
232232

233+
static int cnl_register_clients(struct snd_sof_dev *sdev)
234+
{
235+
return hda_probes_register(sdev);
236+
}
237+
238+
static void cnl_unregister_clients(struct snd_sof_dev *sdev)
239+
{
240+
hda_probes_unregister(sdev);
241+
}
242+
233243
/* cannonlake ops */
234244
const struct snd_sof_dsp_ops sof_cnl_ops = {
235245
/* probe/remove/shutdown */
@@ -281,15 +291,6 @@ const struct snd_sof_dsp_ops sof_cnl_ops = {
281291
.pcm_pointer = hda_dsp_pcm_pointer,
282292
.pcm_ack = hda_dsp_pcm_ack,
283293

284-
#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_PROBES)
285-
/* probe callbacks */
286-
.probe_assign = hda_probe_compr_assign,
287-
.probe_free = hda_probe_compr_free,
288-
.probe_set_params = hda_probe_compr_set_params,
289-
.probe_trigger = hda_probe_compr_trigger,
290-
.probe_pointer = hda_probe_compr_pointer,
291-
#endif
292-
293294
/* firmware loading */
294295
.load_firmware = snd_sof_load_firmware_raw,
295296

@@ -312,6 +313,10 @@ const struct snd_sof_dsp_ops sof_cnl_ops = {
312313
.trace_release = hda_dsp_trace_release,
313314
.trace_trigger = hda_dsp_trace_trigger,
314315

316+
/* client ops */
317+
.register_ipc_clients = cnl_register_clients,
318+
.unregister_ipc_clients = cnl_unregister_clients,
319+
315320
/* DAI drivers */
316321
.drv = skl_dai,
317322
.num_drv = SOF_SKL_NUM_DAIS,

0 commit comments

Comments
 (0)