Skip to content

Commit

Permalink
ASoC: SOF: sof-client-probes-ipc4: Human readable debugfs "probe_points"
Browse files Browse the repository at this point in the history
The current output of three integers is not very human readable. Use
ipc4 functions to describe in more detail what the struct
sof_probe_point_desc buffer_id is actually referring to in an ipc4 SOF
system.

Before this commit the "probe_points" debugfs file could read as:

Id: 0x01000004  Purpose: 0  Node id: 0x100
Id: 0x00000006  Purpose: 0  Node id: 0x100

And after in the same situation in an ipc4 system it reads:

16777220,0,256	host-copier.0.playback output buf idx 0 (probed)
6,0,256	gain.1.1 input buf idx 0 (probed)

The triplet in the beginning of the line can be used to reinserted the
probe point again by writing it into "probe_points" debugfs file, if
its first removed by writing the fist number in "probe_points_remove".
The last number is ignored when creating a probe point.

Signed-off-by: Jyri Sarha <[email protected]>
  • Loading branch information
Jyri Sarha committed Jan 15, 2025
1 parent 7b0b5e7 commit 25d2e12
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 3 deletions.
60 changes: 60 additions & 0 deletions sound/soc/sof/sof-client-probes-ipc4.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <sound/soc.h>
#include <sound/sof/ipc4/header.h>
#include <uapi/sound/sof/header.h>
#include "sof-audio.h"
#include "sof-priv.h"
#include "ipc4-priv.h"
#include "sof-client.h"
Expand Down Expand Up @@ -49,6 +50,15 @@ enum sof_ipc4_probe_type {
SOF_IPC4_PROBE_TYPE_INTERNAL
};

#define SOF_IPC4_PROBE_TYPE_SHIFT 24
#define SOF_IPC4_PROBE_TYPE_MASK GENMASK(25, 24)
#define SOF_IPC4_PROBE_TYPE_GET(x) (((x) & SOF_IPC4_PROBE_TYPE_MASK) \
>> SOF_IPC4_PROBE_TYPE_SHIFT)
#define SOF_IPC4_PROBE_IDX_SHIFT 26
#define SOF_IPC4_PROBE_IDX_MASK GENMASK(31, 26)
#define SOF_IPC4_PROBE_IDX_GET(x) (((x) & SOF_IPC4_PROBE_IDX_MASK) \
>> SOF_IPC4_PROBE_IDX_SHIFT)

struct sof_ipc4_probe_point {
u32 point_id;
u32 purpose;
Expand All @@ -62,6 +72,20 @@ struct sof_ipc4_probe_info {

#define INVALID_PIPELINE_ID 0xFF

static const char *sof_probe_ipc4_type_string(u32 type)
{
switch (type) {
case SOF_IPC4_PROBE_TYPE_INPUT:
return "input";
case SOF_IPC4_PROBE_TYPE_OUTPUT:
return "output";
case SOF_IPC4_PROBE_TYPE_INTERNAL:
return "internal";
default:
return "UNKNOWN";
}
}

/**
* sof_ipc4_probe_get_module_info - Get IPC4 module info for probe module
* @cdev: SOF client device
Expand Down Expand Up @@ -224,6 +248,41 @@ static int ipc4_probes_points_info(struct sof_client_dev *cdev,
return 0;
}

/**
* ipc4_probes_point_print - Human readable print of probe point descriptor
* @cdev: SOF client device
* @buf: Buffer to print to
* @size: Available bytes in buffer
* @desc: Describes the probe point to print
* @return: Number of bytes printed or an error code (snprintf return value)
*/
static int ipc4_probes_point_print(struct sof_client_dev *cdev, char *buf, size_t size,
struct sof_probe_point_desc *desc)
{
struct device *dev = &cdev->auxdev.dev;
struct snd_sof_widget *swidget;
int ret;

swidget = sof_client_ipc4_find_swidget_by_id(cdev, SOF_IPC4_MOD_ID_GET(desc->buffer_id),
SOF_IPC4_MOD_INSTANCE_GET(desc->buffer_id));
if (!swidget) {
dev_err(dev, "%s: Failed to find widget for module %lu.%lu\n",
__func__, SOF_IPC4_MOD_ID_GET(desc->buffer_id),
SOF_IPC4_MOD_INSTANCE_GET(desc->buffer_id));
ret = snprintf(buf, size, "%u,%u,%u\tUNKNOWN buffer_id 0x%08x\n",
desc->buffer_id, desc->purpose, desc->stream_tag,
desc->buffer_id);
return ret;
}

ret = snprintf(buf, size, "%u,%u,%u\t%s %s buf idx %lu %s\n",
desc->buffer_id, desc->purpose, desc->stream_tag, swidget->widget->name,
sof_probe_ipc4_type_string(SOF_IPC4_PROBE_TYPE_GET(desc->buffer_id)),
SOF_IPC4_PROBE_IDX_GET(desc->buffer_id),
desc->stream_tag ? "(connected)" : "");
return ret;
}

/**
* ipc4_probes_points_add - connect specified probes
* @cdev: SOF client device
Expand Down Expand Up @@ -328,6 +387,7 @@ const struct sof_probes_ipc_ops ipc4_probe_ops = {
.init = ipc4_probes_init,
.deinit = ipc4_probes_deinit,
.points_info = ipc4_probes_points_info,
.point_print = ipc4_probes_point_print,
.points_add = ipc4_probes_points_add,
.points_remove = ipc4_probes_points_remove,
};
16 changes: 13 additions & 3 deletions sound/soc/sof/sof-client-probes.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,14 @@

#include <sound/soc.h>
#include <sound/sof/header.h>
#include <sound/sof/ipc4/header.h>
#include "sof-client.h"
#include "sof-client-probes.h"
#include "sof-audio.h"

#ifdef CONFIG_SND_SOC_SOF_IPC4
#include "ipc4-priv.h"
#endif

#define SOF_PROBES_SUSPEND_DELAY_MS 3000
/* only extraction supported for now */
Expand Down Expand Up @@ -223,9 +229,13 @@ static ssize_t sof_probes_dfs_points_read(struct file *file, char __user *to,
for (i = 0; i < num_desc; i++) {
offset = strlen(buf);
remaining = PAGE_SIZE - offset;
ret = snprintf(buf + offset, remaining,
"Id: %#010x Purpose: %u Node id: %#x\n",
desc[i].buffer_id, desc[i].purpose, desc[i].stream_tag);
if (ipc->point_print)
ret = ipc->point_print(cdev, buf + offset, remaining, &desc[i]);
else
ret = snprintf(buf + offset, remaining,
"Id: %#010x Purpose: %u Node id: %#x\n",
desc[i].buffer_id, desc[i].purpose, desc[i].stream_tag);

if (ret < 0 || ret >= remaining) {
/* truncate the output buffer at the last full line */
buf[offset] = '\0';
Expand Down
2 changes: 2 additions & 0 deletions sound/soc/sof/sof-client-probes.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ struct sof_probes_ipc_ops {
int (*points_info)(struct sof_client_dev *cdev,
struct sof_probe_point_desc **desc,
size_t *num_desc);
int (*point_print)(struct sof_client_dev *cdev, char *buf, size_t size,
struct sof_probe_point_desc *desc);
int (*points_add)(struct sof_client_dev *cdev,
struct sof_probe_point_desc *desc,
size_t num_desc);
Expand Down

0 comments on commit 25d2e12

Please sign in to comment.