]> www.infradead.org Git - users/hch/misc.git/commitdiff
ASoC: SOF: sof-client-probes-ipc4: Human readable debugfs "probe_points"
authorJyri Sarha <jyri.sarha@linux.intel.com>
Fri, 29 Aug 2025 09:30:21 +0000 (12:30 +0300)
committerMark Brown <broonie@kernel.org>
Fri, 29 Aug 2025 11:34:18 +0000 (13:34 +0200)
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:

0x7,0x0,0x100   gain.1.1 input buf idx 0 (connected)
0x1000005,0x0,0x100     host-copier.0.playback output buf idx 0 (connected)

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 <jyri.sarha@linux.intel.com>
Reviewed-by: Liam Girdwood <liam.r.girdwood@intel.com>
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
Message-ID: <20250829093022.32094-5-peter.ujfalusi@linux.intel.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/sof/sof-client-probes-ipc4.c
sound/soc/sof/sof-client-probes.c
sound/soc/sof/sof-client-probes.h

index b719ffa8051b03b278aa76c4c514869556b7f882..0b974e6268bb7702a963ebbb5200eeda0fd8efb5 100644 (file)
@@ -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 "ipc4-priv.h"
 #include "sof-client.h"
 #include "sof-client-probes.h"
@@ -48,6 +49,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;
@@ -61,6 +71,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
@@ -223,6 +247,38 @@ 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, "%#x,%#x,%#x\t%s %s buf idx %lu %s\n",
+                      desc->buffer_id, desc->purpose, desc->stream_tag,
+                      swidget ? swidget->widget->name : "<unknown>",
+                      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
@@ -327,6 +383,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,
 };
index 663c0d3c314c668507d133a171276e6260fef83b..242fa19a82ec64c121bd285484be8b45b0b43d69 100644 (file)
 
 #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 */
@@ -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';
index da04d65b8d995e5cfb2e5c5ab1610475957868b4..c445e435aa35bdc01fa88ab137ceffc35dd342d7 100644 (file)
@@ -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);