[PATCH 0/6] ASoC: SOF: Clean up the probe support
Hi,
The probe debug feature of SOF can be used to extract streams of data from a given point of a pipeline for analysis.
The support is implemented by using the ALSA/ASoC compress support for the capture stream, but the code can not be used by/for a normal compressed data stream. It is a debug feature.
Merge the probe implementation in the core (compress.c/h and probe.c/h) into one file: sof-probes.c/h
Rename the Intel HDA specific probe implementation from hda-compressc.c to hda-probes.c
We also need to add IPC logging support for the probes messages and drop the unused references to SOF compress to have reasonably clean code.
Regards, Peter --- Peter Ujfalusi (5): ASoC: SOF: ipc: Add probe message logging to ipc_log_header() ASoC: SOF: pcm: Remove non existent CONFIG_SND_SOC_SOF_COMPRESS reference ASoC: SOF: probe: Merge and clean up the probe and compress files ASoC: SOF: Intel: Rename hda-compress.c to hda-probes.c ASoC: SOF: sof-probes: Correct the function names used for snd_soc_cdai_ops
Ranjani Sridharan (1): ASoC: SOF: compress: move and export sof_probe_compr_ops
sound/soc/sof/Makefile | 3 +- sound/soc/sof/compress.c | 147 --------- sound/soc/sof/compress.h | 32 -- sound/soc/sof/core.c | 2 +- sound/soc/sof/debug.c | 2 +- sound/soc/sof/intel/Makefile | 2 +- sound/soc/sof/intel/hda-dai.c | 16 +- .../intel/{hda-compress.c => hda-probes.c} | 0 sound/soc/sof/ipc.c | 23 ++ sound/soc/sof/pcm.c | 6 +- sound/soc/sof/probe.h | 85 ------ sound/soc/sof/sof-priv.h | 5 - sound/soc/sof/{probe.c => sof-probes.c} | 280 +++++++++++------- sound/soc/sof/sof-probes.h | 38 +++ 14 files changed, 248 insertions(+), 393 deletions(-) delete mode 100644 sound/soc/sof/compress.c delete mode 100644 sound/soc/sof/compress.h rename sound/soc/sof/intel/{hda-compress.c => hda-probes.c} (100%) delete mode 100644 sound/soc/sof/probe.h rename sound/soc/sof/{probe.c => sof-probes.c} (52%) create mode 100644 sound/soc/sof/sof-probes.h
Probe related messages are missing from the logging, for example the PROBE_INIT would show up as:
ipc tx: 0xc0010000: unknown GLB command ipc tx succeeded: 0xc0010000: unknown GLB command
Add code to handle the probe messages to have human readable output
Signed-off-by: Peter Ujfalusi peter.ujfalusi@linux.intel.com Reviewed-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Reviewed-by: Kai Vehmanen kai.vehmanen@linux.intel.com Reviewed-by: Ranjani Sridharan ranjani.sridharan@linux.intel.com --- sound/soc/sof/ipc.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+)
diff --git a/sound/soc/sof/ipc.c b/sound/soc/sof/ipc.c index a4fe007a0e4d..32c139631f11 100644 --- a/sound/soc/sof/ipc.c +++ b/sound/soc/sof/ipc.c @@ -192,6 +192,29 @@ static void ipc_log_header(struct device *dev, u8 *text, u32 cmd) str2 = "unknown type"; break; } break; + case SOF_IPC_GLB_PROBE: + str = "GLB_PROBE"; + switch (type) { + case SOF_IPC_PROBE_INIT: + str2 = "INIT"; break; + case SOF_IPC_PROBE_DEINIT: + str2 = "DEINIT"; break; + case SOF_IPC_PROBE_DMA_ADD: + str2 = "DMA_ADD"; break; + case SOF_IPC_PROBE_DMA_INFO: + str2 = "DMA_INFO"; break; + case SOF_IPC_PROBE_DMA_REMOVE: + str2 = "DMA_REMOVE"; break; + case SOF_IPC_PROBE_POINT_ADD: + str2 = "POINT_ADD"; break; + case SOF_IPC_PROBE_POINT_INFO: + str2 = "POINT_INFO"; break; + case SOF_IPC_PROBE_POINT_REMOVE: + str2 = "POINT_REMOVE"; break; + default: + str2 = "unknown type"; break; + } + break; default: str = "unknown GLB command"; break; }
The SND_SOC_SOF_COMPRESS is not valid Kconfig option, remove it.
At the same time remove the also the declaration of the non existent sof_compressed_ops.
Signed-off-by: Peter Ujfalusi peter.ujfalusi@linux.intel.com Reviewed-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Reviewed-by: Kai Vehmanen kai.vehmanen@linux.intel.com Reviewed-by: Ranjani Sridharan ranjani.sridharan@linux.intel.com --- sound/soc/sof/pcm.c | 4 ---- sound/soc/sof/sof-priv.h | 5 ----- 2 files changed, 9 deletions(-)
diff --git a/sound/soc/sof/pcm.c b/sound/soc/sof/pcm.c index 9893b182da43..2cfc0e24fec1 100644 --- a/sound/soc/sof/pcm.c +++ b/sound/soc/sof/pcm.c @@ -829,11 +829,7 @@ void snd_sof_new_platform_drv(struct snd_sof_dev *sdev) pd->trigger = sof_pcm_trigger; pd->pointer = sof_pcm_pointer;
-#if IS_ENABLED(CONFIG_SND_SOC_SOF_COMPRESS) - pd->compress_ops = &sof_compressed_ops; -#endif #if IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG_PROBES) - /* override cops when probe support is enabled */ pd->compress_ops = &sof_probe_compressed_ops; #endif pd->pcm_construct = sof_pcm_new; diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h index fd8423172d8f..3172722fd5b8 100644 --- a/sound/soc/sof/sof-priv.h +++ b/sound/soc/sof/sof-priv.h @@ -540,11 +540,6 @@ int snd_sof_init_trace_ipc(struct snd_sof_dev *sdev); void snd_sof_handle_fw_exception(struct snd_sof_dev *sdev); int snd_sof_dbg_memory_info_init(struct snd_sof_dev *sdev);
-/* - * Platform specific ops. - */ -extern struct snd_compress_ops sof_compressed_ops; - /* * DSP Architectures. */
From: Ranjani Sridharan ranjani.sridharan@linux.intel.com
sof_probe_compr_ops are not platform-specific. So move it to common compress code and export the symbol. The compilation of the common compress code is already dependent on the selection of CONFIG_SND_SOC_SOF_DEBUG_PROBES, so no need to check the Kconfig section for defining sof_probe_compr_ops again.
Signed-off-by: Ranjani Sridharan ranjani.sridharan@linux.intel.com Reviewed-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Reviewed-by: Kai Vehmanen kai.vehmanen@linux.intel.com Signed-off-by: Peter Ujfalusi peter.ujfalusi@linux.intel.com --- sound/soc/sof/compress.c | 53 +++++++++++++++++++---------------- sound/soc/sof/compress.h | 15 +--------- sound/soc/sof/intel/hda-dai.c | 16 +++-------- 3 files changed, 34 insertions(+), 50 deletions(-)
diff --git a/sound/soc/sof/compress.c b/sound/soc/sof/compress.c index 57d5bf0a171e..3d12851dc6b3 100644 --- a/sound/soc/sof/compress.c +++ b/sound/soc/sof/compress.c @@ -13,13 +13,8 @@ #include "ops.h" #include "probe.h"
-const struct snd_compress_ops sof_probe_compressed_ops = { - .copy = sof_probe_compr_copy, -}; -EXPORT_SYMBOL(sof_probe_compressed_ops); - -int sof_probe_compr_open(struct snd_compr_stream *cstream, - struct snd_soc_dai *dai) +static int sof_probe_compr_open(struct snd_compr_stream *cstream, + struct snd_soc_dai *dai) { struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(dai->component); @@ -34,10 +29,9 @@ int sof_probe_compr_open(struct snd_compr_stream *cstream, sdev->extractor_stream_tag = ret; return 0; } -EXPORT_SYMBOL(sof_probe_compr_open);
-int sof_probe_compr_free(struct snd_compr_stream *cstream, - struct snd_soc_dai *dai) +static int sof_probe_compr_free(struct snd_compr_stream *cstream, + struct snd_soc_dai *dai) { struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(dai->component); @@ -66,10 +60,10 @@ int sof_probe_compr_free(struct snd_compr_stream *cstream,
return snd_sof_probe_compr_free(sdev, cstream, dai); } -EXPORT_SYMBOL(sof_probe_compr_free);
-int sof_probe_compr_set_params(struct snd_compr_stream *cstream, - struct snd_compr_params *params, struct snd_soc_dai *dai) +static int sof_probe_compr_set_params(struct snd_compr_stream *cstream, + struct snd_compr_params *params, + struct snd_soc_dai *dai) { struct snd_compr_runtime *rtd = cstream->runtime; struct snd_sof_dev *sdev = @@ -95,31 +89,38 @@ int sof_probe_compr_set_params(struct snd_compr_stream *cstream,
return 0; } -EXPORT_SYMBOL(sof_probe_compr_set_params);
-int sof_probe_compr_trigger(struct snd_compr_stream *cstream, int cmd, - struct snd_soc_dai *dai) +static int sof_probe_compr_trigger(struct snd_compr_stream *cstream, int cmd, + struct snd_soc_dai *dai) { struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(dai->component);
return snd_sof_probe_compr_trigger(sdev, cstream, cmd, dai); } -EXPORT_SYMBOL(sof_probe_compr_trigger);
-int sof_probe_compr_pointer(struct snd_compr_stream *cstream, - struct snd_compr_tstamp *tstamp, struct snd_soc_dai *dai) +static int sof_probe_compr_pointer(struct snd_compr_stream *cstream, + struct snd_compr_tstamp *tstamp, + struct snd_soc_dai *dai) { struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(dai->component);
return snd_sof_probe_compr_pointer(sdev, cstream, tstamp, dai); } -EXPORT_SYMBOL(sof_probe_compr_pointer);
-int sof_probe_compr_copy(struct snd_soc_component *component, - struct snd_compr_stream *cstream, - char __user *buf, size_t count) +struct snd_soc_cdai_ops sof_probe_compr_ops = { + .startup = sof_probe_compr_open, + .shutdown = sof_probe_compr_free, + .set_params = sof_probe_compr_set_params, + .trigger = sof_probe_compr_trigger, + .pointer = sof_probe_compr_pointer, +}; +EXPORT_SYMBOL(sof_probe_compr_ops); + +static int sof_probe_compr_copy(struct snd_soc_component *component, + struct snd_compr_stream *cstream, + char __user *buf, size_t count) { struct snd_compr_runtime *rtd = cstream->runtime; unsigned int offset, n; @@ -144,4 +145,8 @@ int sof_probe_compr_copy(struct snd_soc_component *component, return count - ret; return count; } -EXPORT_SYMBOL(sof_probe_compr_copy); + +const struct snd_compress_ops sof_probe_compressed_ops = { + .copy = sof_probe_compr_copy, +}; +EXPORT_SYMBOL(sof_probe_compressed_ops); diff --git a/sound/soc/sof/compress.h b/sound/soc/sof/compress.h index 4448c799e14b..f49b3ddb4403 100644 --- a/sound/soc/sof/compress.h +++ b/sound/soc/sof/compress.h @@ -13,20 +13,7 @@
#include <sound/compress_driver.h>
+extern struct snd_soc_cdai_ops sof_probe_compr_ops; extern const struct snd_compress_ops sof_probe_compressed_ops;
-int sof_probe_compr_open(struct snd_compr_stream *cstream, - struct snd_soc_dai *dai); -int sof_probe_compr_free(struct snd_compr_stream *cstream, - struct snd_soc_dai *dai); -int sof_probe_compr_set_params(struct snd_compr_stream *cstream, - struct snd_compr_params *params, struct snd_soc_dai *dai); -int sof_probe_compr_trigger(struct snd_compr_stream *cstream, int cmd, - struct snd_soc_dai *dai); -int sof_probe_compr_pointer(struct snd_compr_stream *cstream, - struct snd_compr_tstamp *tstamp, struct snd_soc_dai *dai); -int sof_probe_compr_copy(struct snd_soc_component *component, - struct snd_compr_stream *cstream, - char __user *buf, size_t count); - #endif diff --git a/sound/soc/sof/intel/hda-dai.c b/sound/soc/sof/intel/hda-dai.c index c1f9f0f58464..46fb8add237e 100644 --- a/sound/soc/sof/intel/hda-dai.c +++ b/sound/soc/sof/intel/hda-dai.c @@ -16,6 +16,10 @@
#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
+#if IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG_PROBES) +#include "../compress.h" +#endif + struct hda_pipe_params { u8 host_dma_id; u8 link_dma_id; @@ -400,18 +404,6 @@ static const struct snd_soc_dai_ops hda_link_dai_ops = { .prepare = hda_link_pcm_prepare, };
-#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_PROBES) -#include "../compress.h" - -static struct snd_soc_cdai_ops sof_probe_compr_ops = { - .startup = sof_probe_compr_open, - .shutdown = sof_probe_compr_free, - .set_params = sof_probe_compr_set_params, - .trigger = sof_probe_compr_trigger, - .pointer = sof_probe_compr_pointer, -}; - -#endif #endif
static int ssp_dai_hw_params(struct snd_pcm_substream *substream,
The probe debug functionality is implemented via compress support and it was spread across two set of files: probe.c/h compress.c/h
Merge the two files into sof-probes.s/h and clean them up by removing unused struct definitions, functions. We can also move most of the functions static as they are only used internally.
Signed-off-by: Peter Ujfalusi peter.ujfalusi@linux.intel.com Reviewed-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Reviewed-by: Kai Vehmanen kai.vehmanen@linux.intel.com Reviewed-by: Ranjani Sridharan ranjani.sridharan@linux.intel.com --- sound/soc/sof/Makefile | 3 +- sound/soc/sof/compress.c | 152 ------------- sound/soc/sof/compress.h | 19 -- sound/soc/sof/core.c | 2 +- sound/soc/sof/debug.c | 2 +- sound/soc/sof/intel/hda-dai.c | 2 +- sound/soc/sof/pcm.c | 2 +- sound/soc/sof/probe.h | 85 ------- sound/soc/sof/{probe.c => sof-probes.c} | 280 +++++++++++++++--------- sound/soc/sof/sof-probes.h | 38 ++++ 10 files changed, 221 insertions(+), 364 deletions(-) delete mode 100644 sound/soc/sof/compress.c delete mode 100644 sound/soc/sof/compress.h delete mode 100644 sound/soc/sof/probe.h rename sound/soc/sof/{probe.c => sof-probes.c} (52%) create mode 100644 sound/soc/sof/sof-probes.h
diff --git a/sound/soc/sof/Makefile b/sound/soc/sof/Makefile index 606d8137cd98..bdea0faac117 100644 --- a/sound/soc/sof/Makefile +++ b/sound/soc/sof/Makefile @@ -2,7 +2,8 @@
snd-sof-objs := core.o ops.o loader.o ipc.o pcm.o pm.o debug.o topology.o\ control.o trace.o utils.o sof-audio.o -snd-sof-$(CONFIG_SND_SOC_SOF_DEBUG_PROBES) += probe.o compress.o + +snd-sof-$(CONFIG_SND_SOC_SOF_DEBUG_PROBES) += sof-probes.o
snd-sof-pci-objs := sof-pci-dev.o snd-sof-acpi-objs := sof-acpi-dev.o diff --git a/sound/soc/sof/compress.c b/sound/soc/sof/compress.c deleted file mode 100644 index 3d12851dc6b3..000000000000 --- a/sound/soc/sof/compress.c +++ /dev/null @@ -1,152 +0,0 @@ -// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) -// -// This file is provided under a dual BSD/GPLv2 license. When using or -// redistributing this file, you may do so under either license. -// -// Copyright(c) 2019-2020 Intel Corporation. All rights reserved. -// -// Author: Cezary Rojewski cezary.rojewski@intel.com -// - -#include <sound/soc.h> -#include "compress.h" -#include "ops.h" -#include "probe.h" - -static int sof_probe_compr_open(struct snd_compr_stream *cstream, - struct snd_soc_dai *dai) -{ - struct snd_sof_dev *sdev = - snd_soc_component_get_drvdata(dai->component); - int ret; - - ret = snd_sof_probe_compr_assign(sdev, cstream, dai); - if (ret < 0) { - dev_err(dai->dev, "Failed to assign probe stream: %d\n", ret); - return ret; - } - - sdev->extractor_stream_tag = ret; - return 0; -} - -static int sof_probe_compr_free(struct snd_compr_stream *cstream, - struct snd_soc_dai *dai) -{ - struct snd_sof_dev *sdev = - snd_soc_component_get_drvdata(dai->component); - struct sof_probe_point_desc *desc; - size_t num_desc; - int i, ret; - - /* disconnect all probe points */ - ret = sof_ipc_probe_points_info(sdev, &desc, &num_desc); - if (ret < 0) { - dev_err(dai->dev, "Failed to get probe points: %d\n", ret); - goto exit; - } - - for (i = 0; i < num_desc; i++) - sof_ipc_probe_points_remove(sdev, &desc[i].buffer_id, 1); - kfree(desc); - -exit: - ret = sof_ipc_probe_deinit(sdev); - if (ret < 0) - dev_err(dai->dev, "Failed to deinit probe: %d\n", ret); - - sdev->extractor_stream_tag = SOF_PROBE_INVALID_NODE_ID; - snd_compr_free_pages(cstream); - - return snd_sof_probe_compr_free(sdev, cstream, dai); -} - -static int sof_probe_compr_set_params(struct snd_compr_stream *cstream, - struct snd_compr_params *params, - struct snd_soc_dai *dai) -{ - struct snd_compr_runtime *rtd = cstream->runtime; - struct snd_sof_dev *sdev = - snd_soc_component_get_drvdata(dai->component); - int ret; - - cstream->dma_buffer.dev.type = SNDRV_DMA_TYPE_DEV_SG; - cstream->dma_buffer.dev.dev = sdev->dev; - ret = snd_compr_malloc_pages(cstream, rtd->buffer_size); - if (ret < 0) - return ret; - - ret = snd_sof_probe_compr_set_params(sdev, cstream, params, dai); - if (ret < 0) - return ret; - - ret = sof_ipc_probe_init(sdev, sdev->extractor_stream_tag, - rtd->dma_bytes); - if (ret < 0) { - dev_err(dai->dev, "Failed to init probe: %d\n", ret); - return ret; - } - - return 0; -} - -static int sof_probe_compr_trigger(struct snd_compr_stream *cstream, int cmd, - struct snd_soc_dai *dai) -{ - struct snd_sof_dev *sdev = - snd_soc_component_get_drvdata(dai->component); - - return snd_sof_probe_compr_trigger(sdev, cstream, cmd, dai); -} - -static int sof_probe_compr_pointer(struct snd_compr_stream *cstream, - struct snd_compr_tstamp *tstamp, - struct snd_soc_dai *dai) -{ - struct snd_sof_dev *sdev = - snd_soc_component_get_drvdata(dai->component); - - return snd_sof_probe_compr_pointer(sdev, cstream, tstamp, dai); -} - -struct snd_soc_cdai_ops sof_probe_compr_ops = { - .startup = sof_probe_compr_open, - .shutdown = sof_probe_compr_free, - .set_params = sof_probe_compr_set_params, - .trigger = sof_probe_compr_trigger, - .pointer = sof_probe_compr_pointer, -}; -EXPORT_SYMBOL(sof_probe_compr_ops); - -static int sof_probe_compr_copy(struct snd_soc_component *component, - struct snd_compr_stream *cstream, - char __user *buf, size_t count) -{ - struct snd_compr_runtime *rtd = cstream->runtime; - unsigned int offset, n; - void *ptr; - int ret; - - if (count > rtd->buffer_size) - count = rtd->buffer_size; - - div_u64_rem(rtd->total_bytes_transferred, rtd->buffer_size, &offset); - ptr = rtd->dma_area + offset; - n = rtd->buffer_size - offset; - - if (count < n) { - ret = copy_to_user(buf, ptr, count); - } else { - ret = copy_to_user(buf, ptr, n); - ret += copy_to_user(buf + n, rtd->dma_area, count - n); - } - - if (ret) - return count - ret; - return count; -} - -const struct snd_compress_ops sof_probe_compressed_ops = { - .copy = sof_probe_compr_copy, -}; -EXPORT_SYMBOL(sof_probe_compressed_ops); diff --git a/sound/soc/sof/compress.h b/sound/soc/sof/compress.h deleted file mode 100644 index f49b3ddb4403..000000000000 --- a/sound/soc/sof/compress.h +++ /dev/null @@ -1,19 +0,0 @@ -/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */ -/* - * This file is provided under a dual BSD/GPLv2 license. When using or - * redistributing this file, you may do so under either license. - * - * Copyright(c) 2019-2020 Intel Corporation. All rights reserved. - * - * Author: Cezary Rojewski cezary.rojewski@intel.com - */ - -#ifndef __SOF_COMPRESS_H -#define __SOF_COMPRESS_H - -#include <sound/compress_driver.h> - -extern struct snd_soc_cdai_ops sof_probe_compr_ops; -extern const struct snd_compress_ops sof_probe_compressed_ops; - -#endif diff --git a/sound/soc/sof/core.c b/sound/soc/sof/core.c index 6be4f159ee35..b8989f926f8f 100644 --- a/sound/soc/sof/core.c +++ b/sound/soc/sof/core.c @@ -15,7 +15,7 @@ #include "sof-priv.h" #include "ops.h" #if IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG_PROBES) -#include "probe.h" +#include "sof-probes.h" #endif
/* see SOF_DBG_ flags */ diff --git a/sound/soc/sof/debug.c b/sound/soc/sof/debug.c index a51a928ea40a..d85ca9f3fc38 100644 --- a/sound/soc/sof/debug.c +++ b/sound/soc/sof/debug.c @@ -20,7 +20,7 @@ #include "ops.h"
#if IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG_PROBES) -#include "probe.h" +#include "sof-probes.h"
/** * strsplit_u32 - Split string into sequence of u32 tokens diff --git a/sound/soc/sof/intel/hda-dai.c b/sound/soc/sof/intel/hda-dai.c index 46fb8add237e..2f54a659b78a 100644 --- a/sound/soc/sof/intel/hda-dai.c +++ b/sound/soc/sof/intel/hda-dai.c @@ -17,7 +17,7 @@ #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
#if IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG_PROBES) -#include "../compress.h" +#include "../sof-probes.h" #endif
struct hda_pipe_params { diff --git a/sound/soc/sof/pcm.c b/sound/soc/sof/pcm.c index 2cfc0e24fec1..b4280459e5db 100644 --- a/sound/soc/sof/pcm.c +++ b/sound/soc/sof/pcm.c @@ -17,7 +17,7 @@ #include "sof-audio.h" #include "ops.h" #if IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG_PROBES) -#include "compress.h" +#include "sof-probes.h" #endif
/* Create DMA buffer page table for DSP */ diff --git a/sound/soc/sof/probe.h b/sound/soc/sof/probe.h deleted file mode 100644 index 5e159ab239fa..000000000000 --- a/sound/soc/sof/probe.h +++ /dev/null @@ -1,85 +0,0 @@ -/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */ -/* - * This file is provided under a dual BSD/GPLv2 license. When using or - * redistributing this file, you may do so under either license. - * - * Copyright(c) 2019-2020 Intel Corporation. All rights reserved. - * - * Author: Cezary Rojewski cezary.rojewski@intel.com - */ - -#ifndef __SOF_PROBE_H -#define __SOF_PROBE_H - -#include <sound/sof/header.h> - -struct snd_sof_dev; - -#define SOF_PROBE_INVALID_NODE_ID UINT_MAX - -struct sof_probe_dma { - unsigned int stream_tag; - unsigned int dma_buffer_size; -} __packed; - -enum sof_connection_purpose { - SOF_CONNECTION_PURPOSE_EXTRACT = 1, - SOF_CONNECTION_PURPOSE_INJECT, -}; - -struct sof_probe_point_desc { - unsigned int buffer_id; - unsigned int purpose; - unsigned int stream_tag; -} __packed; - -struct sof_ipc_probe_dma_add_params { - struct sof_ipc_cmd_hdr hdr; - unsigned int num_elems; - struct sof_probe_dma dma[]; -} __packed; - -struct sof_ipc_probe_info_params { - struct sof_ipc_reply rhdr; - unsigned int num_elems; - union { - struct sof_probe_dma dma[0]; - struct sof_probe_point_desc desc[0]; - }; -} __packed; - -struct sof_ipc_probe_dma_remove_params { - struct sof_ipc_cmd_hdr hdr; - unsigned int num_elems; - unsigned int stream_tag[]; -} __packed; - -struct sof_ipc_probe_point_add_params { - struct sof_ipc_cmd_hdr hdr; - unsigned int num_elems; - struct sof_probe_point_desc desc[]; -} __packed; - -struct sof_ipc_probe_point_remove_params { - struct sof_ipc_cmd_hdr hdr; - unsigned int num_elems; - unsigned int buffer_id[]; -} __packed; - -int sof_ipc_probe_init(struct snd_sof_dev *sdev, - u32 stream_tag, size_t buffer_size); -int sof_ipc_probe_deinit(struct snd_sof_dev *sdev); -int sof_ipc_probe_dma_info(struct snd_sof_dev *sdev, - struct sof_probe_dma **dma, size_t *num_dma); -int sof_ipc_probe_dma_add(struct snd_sof_dev *sdev, - struct sof_probe_dma *dma, size_t num_dma); -int sof_ipc_probe_dma_remove(struct snd_sof_dev *sdev, - unsigned int *stream_tag, size_t num_stream_tag); -int sof_ipc_probe_points_info(struct snd_sof_dev *sdev, - struct sof_probe_point_desc **desc, size_t *num_desc); -int sof_ipc_probe_points_add(struct snd_sof_dev *sdev, - struct sof_probe_point_desc *desc, size_t num_desc); -int sof_ipc_probe_points_remove(struct snd_sof_dev *sdev, - unsigned int *buffer_id, size_t num_buffer_id); - -#endif diff --git a/sound/soc/sof/probe.c b/sound/soc/sof/sof-probes.c similarity index 52% rename from sound/soc/sof/probe.c rename to sound/soc/sof/sof-probes.c index 14509f4d3f86..e394fc524445 100644 --- a/sound/soc/sof/probe.c +++ b/sound/soc/sof/sof-probes.c @@ -3,13 +3,46 @@ // This file is provided under a dual BSD/GPLv2 license. When using or // redistributing this file, you may do so under either license. // -// Copyright(c) 2019-2020 Intel Corporation. All rights reserved. -// +// Copyright(c) 2019-2021 Intel Corporation. All rights reserved. // Author: Cezary Rojewski cezary.rojewski@intel.com //
+#include <sound/soc.h> +#include "ops.h" #include "sof-priv.h" -#include "probe.h" +#include "sof-probes.h" + +struct sof_probe_dma { + unsigned int stream_tag; + unsigned int dma_buffer_size; +} __packed; + +struct sof_ipc_probe_dma_add_params { + struct sof_ipc_cmd_hdr hdr; + unsigned int num_elems; + struct sof_probe_dma dma[]; +} __packed; + +struct sof_ipc_probe_info_params { + struct sof_ipc_reply rhdr; + unsigned int num_elems; + union { + struct sof_probe_dma dma[0]; + struct sof_probe_point_desc desc[0]; + }; +} __packed; + +struct sof_ipc_probe_point_add_params { + struct sof_ipc_cmd_hdr hdr; + unsigned int num_elems; + struct sof_probe_point_desc desc[]; +} __packed; + +struct sof_ipc_probe_point_remove_params { + struct sof_ipc_cmd_hdr hdr; + unsigned int num_elems; + unsigned int buffer_id[]; +} __packed;
/** * sof_ipc_probe_init - initialize data probing @@ -25,8 +58,8 @@ * Probing is initialized only once and each INIT request must be * matched by DEINIT call. */ -int sof_ipc_probe_init(struct snd_sof_dev *sdev, - u32 stream_tag, size_t buffer_size) +static int sof_ipc_probe_init(struct snd_sof_dev *sdev, u32 stream_tag, + size_t buffer_size) { struct sof_ipc_probe_dma_add_params *msg; struct sof_ipc_reply reply; @@ -47,7 +80,6 @@ int sof_ipc_probe_init(struct snd_sof_dev *sdev, kfree(msg); return ret; } -EXPORT_SYMBOL(sof_ipc_probe_init);
/** * sof_ipc_probe_deinit - cleanup after data probing @@ -57,7 +89,7 @@ EXPORT_SYMBOL(sof_ipc_probe_init); * on DSP side once it is no longer needed. DEINIT only when there * are no probes connected and with all injectors detached. */ -int sof_ipc_probe_deinit(struct snd_sof_dev *sdev) +static int sof_ipc_probe_deinit(struct snd_sof_dev *sdev) { struct sof_ipc_cmd_hdr msg; struct sof_ipc_reply reply; @@ -68,10 +100,9 @@ int sof_ipc_probe_deinit(struct snd_sof_dev *sdev) return sof_ipc_tx_message(sdev->ipc, msg.cmd, &msg, msg.size, &reply, sizeof(reply)); } -EXPORT_SYMBOL(sof_ipc_probe_deinit);
static int sof_ipc_probe_info(struct snd_sof_dev *sdev, unsigned int cmd, - void **params, size_t *num_params) + void **params, size_t *num_params) { struct sof_ipc_probe_info_params msg = {{{0}}}; struct sof_ipc_probe_info_params *reply; @@ -112,97 +143,6 @@ static int sof_ipc_probe_info(struct snd_sof_dev *sdev, unsigned int cmd, return ret; }
-/** - * sof_ipc_probe_dma_info - retrieve list of active injection dmas - * @sdev: SOF sound device - * @dma: Returned list of active dmas - * @num_dma: Returned count of active dmas - * - * Host sends DMA_INFO request to obtain list of injection dmas it - * can use to transfer data over with. - * - * Note that list contains only injection dmas as there is only one - * extractor (dma) and it is always assigned on probing init. - * DSP knows exactly where data from extraction probes is going to, - * which is not the case for injection where multiple streams - * could be engaged. - */ -int sof_ipc_probe_dma_info(struct snd_sof_dev *sdev, - struct sof_probe_dma **dma, size_t *num_dma) -{ - return sof_ipc_probe_info(sdev, SOF_IPC_PROBE_DMA_INFO, - (void **)dma, num_dma); -} -EXPORT_SYMBOL(sof_ipc_probe_dma_info); - -/** - * sof_ipc_probe_dma_add - attach to specified dmas - * @sdev: SOF sound device - * @dma: List of streams (dmas) to attach to - * @num_dma: Number of elements in @dma - * - * Contrary to extraction, injection streams are never assigned - * on init. Before attempting any data injection, host is responsible - * for specifying streams which will be later used to transfer data - * to connected probe points. - */ -int sof_ipc_probe_dma_add(struct snd_sof_dev *sdev, - struct sof_probe_dma *dma, size_t num_dma) -{ - struct sof_ipc_probe_dma_add_params *msg; - struct sof_ipc_reply reply; - size_t size = struct_size(msg, dma, num_dma); - int ret; - - msg = kmalloc(size, GFP_KERNEL); - if (!msg) - return -ENOMEM; - msg->hdr.size = size; - msg->num_elems = num_dma; - msg->hdr.cmd = SOF_IPC_GLB_PROBE | SOF_IPC_PROBE_DMA_ADD; - memcpy(&msg->dma[0], dma, size - sizeof(*msg)); - - ret = sof_ipc_tx_message(sdev->ipc, msg->hdr.cmd, msg, msg->hdr.size, - &reply, sizeof(reply)); - kfree(msg); - return ret; -} -EXPORT_SYMBOL(sof_ipc_probe_dma_add); - -/** - * sof_ipc_probe_dma_remove - detach from specified dmas - * @sdev: SOF sound device - * @stream_tag: List of stream tags to detach from - * @num_stream_tag: Number of elements in @stream_tag - * - * Host sends DMA_REMOVE request to free previously attached stream - * from being occupied for injection. Each detach operation should - * match equivalent DMA_ADD. Detach only when all probes tied to - * given stream have been disconnected. - */ -int sof_ipc_probe_dma_remove(struct snd_sof_dev *sdev, - unsigned int *stream_tag, size_t num_stream_tag) -{ - struct sof_ipc_probe_dma_remove_params *msg; - struct sof_ipc_reply reply; - size_t size = struct_size(msg, stream_tag, num_stream_tag); - int ret; - - msg = kmalloc(size, GFP_KERNEL); - if (!msg) - return -ENOMEM; - msg->hdr.size = size; - msg->num_elems = num_stream_tag; - msg->hdr.cmd = SOF_IPC_GLB_PROBE | SOF_IPC_PROBE_DMA_REMOVE; - memcpy(&msg->stream_tag[0], stream_tag, size - sizeof(*msg)); - - ret = sof_ipc_tx_message(sdev->ipc, msg->hdr.cmd, msg, msg->hdr.size, - &reply, sizeof(reply)); - kfree(msg); - return ret; -} -EXPORT_SYMBOL(sof_ipc_probe_dma_remove); - /** * sof_ipc_probe_points_info - retrieve list of active probe points * @sdev: SOF sound device @@ -214,7 +154,8 @@ EXPORT_SYMBOL(sof_ipc_probe_dma_remove); * required. */ int sof_ipc_probe_points_info(struct snd_sof_dev *sdev, - struct sof_probe_point_desc **desc, size_t *num_desc) + struct sof_probe_point_desc **desc, + size_t *num_desc) { return sof_ipc_probe_info(sdev, SOF_IPC_PROBE_POINT_INFO, (void **)desc, num_desc); @@ -235,7 +176,7 @@ EXPORT_SYMBOL(sof_ipc_probe_points_info); * request when no longer needed. */ int sof_ipc_probe_points_add(struct snd_sof_dev *sdev, - struct sof_probe_point_desc *desc, size_t num_desc) + struct sof_probe_point_desc *desc, size_t num_desc) { struct sof_ipc_probe_point_add_params *msg; struct sof_ipc_reply reply; @@ -267,7 +208,7 @@ EXPORT_SYMBOL(sof_ipc_probe_points_add); * points and frees all resources on DSP side. */ int sof_ipc_probe_points_remove(struct snd_sof_dev *sdev, - unsigned int *buffer_id, size_t num_buffer_id) + unsigned int *buffer_id, size_t num_buffer_id) { struct sof_ipc_probe_point_remove_params *msg; struct sof_ipc_reply reply; @@ -288,3 +229,136 @@ int sof_ipc_probe_points_remove(struct snd_sof_dev *sdev, return ret; } EXPORT_SYMBOL(sof_ipc_probe_points_remove); + +static int sof_probe_compr_open(struct snd_compr_stream *cstream, + struct snd_soc_dai *dai) +{ + struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(dai->component); + int ret; + + ret = snd_sof_probe_compr_assign(sdev, cstream, dai); + if (ret < 0) { + dev_err(dai->dev, "Failed to assign probe stream: %d\n", ret); + return ret; + } + + sdev->extractor_stream_tag = ret; + return 0; +} + +static int sof_probe_compr_free(struct snd_compr_stream *cstream, + struct snd_soc_dai *dai) +{ + struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(dai->component); + struct sof_probe_point_desc *desc; + size_t num_desc; + int i, ret; + + /* disconnect all probe points */ + ret = sof_ipc_probe_points_info(sdev, &desc, &num_desc); + if (ret < 0) { + dev_err(dai->dev, "Failed to get probe points: %d\n", ret); + goto exit; + } + + for (i = 0; i < num_desc; i++) + sof_ipc_probe_points_remove(sdev, &desc[i].buffer_id, 1); + kfree(desc); + +exit: + ret = sof_ipc_probe_deinit(sdev); + if (ret < 0) + dev_err(dai->dev, "Failed to deinit probe: %d\n", ret); + + sdev->extractor_stream_tag = SOF_PROBE_INVALID_NODE_ID; + snd_compr_free_pages(cstream); + + return snd_sof_probe_compr_free(sdev, cstream, dai); +} + +static int sof_probe_compr_set_params(struct snd_compr_stream *cstream, + struct snd_compr_params *params, + struct snd_soc_dai *dai) +{ + struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(dai->component); + struct snd_compr_runtime *rtd = cstream->runtime; + int ret; + + cstream->dma_buffer.dev.type = SNDRV_DMA_TYPE_DEV_SG; + cstream->dma_buffer.dev.dev = sdev->dev; + ret = snd_compr_malloc_pages(cstream, rtd->buffer_size); + if (ret < 0) + return ret; + + ret = snd_sof_probe_compr_set_params(sdev, cstream, params, dai); + if (ret < 0) + return ret; + + ret = sof_ipc_probe_init(sdev, sdev->extractor_stream_tag, + rtd->dma_bytes); + if (ret < 0) { + dev_err(dai->dev, "Failed to init probe: %d\n", ret); + return ret; + } + + return 0; +} + +static int sof_probe_compr_trigger(struct snd_compr_stream *cstream, int cmd, + struct snd_soc_dai *dai) +{ + struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(dai->component); + + return snd_sof_probe_compr_trigger(sdev, cstream, cmd, dai); +} + +static int sof_probe_compr_pointer(struct snd_compr_stream *cstream, + struct snd_compr_tstamp *tstamp, + struct snd_soc_dai *dai) +{ + struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(dai->component); + + return snd_sof_probe_compr_pointer(sdev, cstream, tstamp, dai); +} + +struct snd_soc_cdai_ops sof_probe_compr_ops = { + .startup = sof_probe_compr_open, + .shutdown = sof_probe_compr_free, + .set_params = sof_probe_compr_set_params, + .trigger = sof_probe_compr_trigger, + .pointer = sof_probe_compr_pointer, +}; +EXPORT_SYMBOL(sof_probe_compr_ops); + +static int sof_probe_compr_copy(struct snd_soc_component *component, + struct snd_compr_stream *cstream, + char __user *buf, size_t count) +{ + struct snd_compr_runtime *rtd = cstream->runtime; + unsigned int offset, n; + void *ptr; + int ret; + + if (count > rtd->buffer_size) + count = rtd->buffer_size; + + div_u64_rem(rtd->total_bytes_transferred, rtd->buffer_size, &offset); + ptr = rtd->dma_area + offset; + n = rtd->buffer_size - offset; + + if (count < n) { + ret = copy_to_user(buf, ptr, count); + } else { + ret = copy_to_user(buf, ptr, n); + ret += copy_to_user(buf + n, rtd->dma_area, count - n); + } + + if (ret) + return count - ret; + return count; +} + +const struct snd_compress_ops sof_probe_compressed_ops = { + .copy = sof_probe_compr_copy, +}; +EXPORT_SYMBOL(sof_probe_compressed_ops); diff --git a/sound/soc/sof/sof-probes.h b/sound/soc/sof/sof-probes.h new file mode 100644 index 000000000000..35e1dd8d9e03 --- /dev/null +++ b/sound/soc/sof/sof-probes.h @@ -0,0 +1,38 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */ +/* + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * Copyright(c) 2019-2021 Intel Corporation. All rights reserved. + * Author: Cezary Rojewski cezary.rojewski@intel.com + */ + +#ifndef __SOF_PROBES_H +#define __SOF_PROBES_H + +#include <sound/compress_driver.h> +#include <sound/sof/header.h> + +struct snd_sof_dev; + +#define SOF_PROBE_INVALID_NODE_ID UINT_MAX + +struct sof_probe_point_desc { + unsigned int buffer_id; + unsigned int purpose; + unsigned int stream_tag; +} __packed; + +int sof_ipc_probe_points_info(struct snd_sof_dev *sdev, + struct sof_probe_point_desc **desc, + size_t *num_desc); +int sof_ipc_probe_points_add(struct snd_sof_dev *sdev, + struct sof_probe_point_desc *desc, + size_t num_desc); +int sof_ipc_probe_points_remove(struct snd_sof_dev *sdev, + unsigned int *buffer_id, size_t num_buffer_id); + +extern struct snd_soc_cdai_ops sof_probe_compr_ops; +extern const struct snd_compress_ops sof_probe_compressed_ops; + +#endif
The hda-compress.c is implementing the SOF probe support for intel HDA platforms using compress API.
To avoid the confusion, rename it to reflect this.
Signed-off-by: Peter Ujfalusi peter.ujfalusi@linux.intel.com Reviewed-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Reviewed-by: Kai Vehmanen kai.vehmanen@linux.intel.com Reviewed-by: Ranjani Sridharan ranjani.sridharan@linux.intel.com --- sound/soc/sof/intel/Makefile | 2 +- sound/soc/sof/intel/{hda-compress.c => hda-probes.c} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename sound/soc/sof/intel/{hda-compress.c => hda-probes.c} (100%)
diff --git a/sound/soc/sof/intel/Makefile b/sound/soc/sof/intel/Makefile index feae487f0227..9635dd47a17d 100644 --- a/sound/soc/sof/intel/Makefile +++ b/sound/soc/sof/intel/Makefile @@ -9,7 +9,7 @@ snd-sof-intel-hda-common-objs := hda.o hda-loader.o hda-stream.o hda-trace.o \ hda-dsp.o hda-ipc.o hda-ctrl.o hda-pcm.o \ hda-dai.o hda-bus.o \ apl.o cnl.o tgl.o icl.o -snd-sof-intel-hda-common-$(CONFIG_SND_SOC_SOF_HDA_PROBES) += hda-compress.o +snd-sof-intel-hda-common-$(CONFIG_SND_SOC_SOF_HDA_PROBES) += hda-probes.o
snd-sof-intel-hda-objs := hda-codec.o
diff --git a/sound/soc/sof/intel/hda-compress.c b/sound/soc/sof/intel/hda-probes.c similarity index 100% rename from sound/soc/sof/intel/hda-compress.c rename to sound/soc/sof/intel/hda-probes.c
The snd_soc_cdai_ops have startup and shutdown callbacks defined unlike the component callbacks where open and free is used.
Signed-off-by: Peter Ujfalusi peter.ujfalusi@linux.intel.com Reviewed-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Reviewed-by: Kai Vehmanen kai.vehmanen@linux.intel.com Reviewed-by: Ranjani Sridharan ranjani.sridharan@linux.intel.com --- sound/soc/sof/sof-probes.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/sound/soc/sof/sof-probes.c b/sound/soc/sof/sof-probes.c index e394fc524445..5586af9f1a25 100644 --- a/sound/soc/sof/sof-probes.c +++ b/sound/soc/sof/sof-probes.c @@ -230,8 +230,8 @@ int sof_ipc_probe_points_remove(struct snd_sof_dev *sdev, } EXPORT_SYMBOL(sof_ipc_probe_points_remove);
-static int sof_probe_compr_open(struct snd_compr_stream *cstream, - struct snd_soc_dai *dai) +static int sof_probe_compr_startup(struct snd_compr_stream *cstream, + struct snd_soc_dai *dai) { struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(dai->component); int ret; @@ -246,8 +246,8 @@ static int sof_probe_compr_open(struct snd_compr_stream *cstream, return 0; }
-static int sof_probe_compr_free(struct snd_compr_stream *cstream, - struct snd_soc_dai *dai) +static int sof_probe_compr_shutdown(struct snd_compr_stream *cstream, + struct snd_soc_dai *dai) { struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(dai->component); struct sof_probe_point_desc *desc; @@ -322,8 +322,8 @@ static int sof_probe_compr_pointer(struct snd_compr_stream *cstream, }
struct snd_soc_cdai_ops sof_probe_compr_ops = { - .startup = sof_probe_compr_open, - .shutdown = sof_probe_compr_free, + .startup = sof_probe_compr_startup, + .shutdown = sof_probe_compr_shutdown, .set_params = sof_probe_compr_set_params, .trigger = sof_probe_compr_trigger, .pointer = sof_probe_compr_pointer,
On Thu, 16 Sep 2021 13:32:05 +0300, Peter Ujfalusi wrote:
The probe debug feature of SOF can be used to extract streams of data from a given point of a pipeline for analysis.
The support is implemented by using the ALSA/ASoC compress support for the capture stream, but the code can not be used by/for a normal compressed data stream. It is a debug feature.
[...]
Applied to
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next
Thanks!
[1/6] ASoC: SOF: ipc: Add probe message logging to ipc_log_header() commit: 4ba344dc792fc665c6e95d08ac13ba30f908bbf7 [2/6] ASoC: SOF: pcm: Remove non existent CONFIG_SND_SOC_SOF_COMPRESS reference commit: 8a720724589e8d782ad3ad4e0f08977de00bea5f [3/6] ASoC: SOF: compress: move and export sof_probe_compr_ops commit: 2dc51106ccc6c64b9ea68ddd9ec533f7e67e081d [4/6] ASoC: SOF: probe: Merge and clean up the probe and compress files commit: 7bbdda8009001d66611314e67a3f498d4b412c64 [5/6] ASoC: SOF: Intel: Rename hda-compress.c to hda-probes.c commit: f95b4152ad75274734ed23d0546d24f5e7fc9c3c [6/6] ASoC: SOF: sof-probes: Correct the function names used for snd_soc_cdai_ops commit: 49efed50588547b0f13897b6fc69f155c2e2af50
All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying to this mail.
Thanks, Mark
participants (2)
-
Mark Brown
-
Peter Ujfalusi