summaryrefslogtreecommitdiff
path: root/sound
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2022-12-09 09:50:13 +0100
committerTakashi Iwai <tiwai@suse.de>2022-12-09 09:50:13 +0100
commita587601b55df505f38b18832d941e47dbbf084ce (patch)
tree839fae4220b9fc7b4aee9ac8f45a27496f047414 /sound
parent4bf5bf54476dffe60e6b6d8d539f67309ff599e2 (diff)
parente85b1f5a9769ac30f4d2f6fb1cdcd9570c38e0c1 (diff)
downloadlinux-a587601b55df505f38b18832d941e47dbbf084ce.tar.gz
linux-a587601b55df505f38b18832d941e47dbbf084ce.tar.bz2
linux-a587601b55df505f38b18832d941e47dbbf084ce.zip
Merge tag 'asoc-v6.2-2' of https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-next
ASoC: Updates for v6.2 A few more updates for v6.2 which can hopefully go into a later pull request, the bulk of these are fixes, minor cleanups or new board quirks - the one big bit that isn't is support for getting diagnostic data out of the Intel AVS firmwares.
Diffstat (limited to 'sound')
-rw-r--r--sound/hda/ext/hdac_ext_stream.c41
-rw-r--r--sound/hda/hdac_controller.c4
-rw-r--r--sound/hda/hdac_stream.c51
-rw-r--r--sound/soc/codecs/wcd-clsh-v2.c6
-rw-r--r--sound/soc/fsl/imx-audmux.c3
-rw-r--r--sound/soc/generic/audio-graph-card.c4
-rw-r--r--sound/soc/intel/Kconfig1
-rw-r--r--sound/soc/intel/avs/Makefile4
-rw-r--r--sound/soc/intel/avs/apl.c24
-rw-r--r--sound/soc/intel/avs/avs.h80
-rw-r--r--sound/soc/intel/avs/board_selection.c33
-rw-r--r--sound/soc/intel/avs/boards/Kconfig8
-rw-r--r--sound/soc/intel/avs/boards/Makefile2
-rw-r--r--sound/soc/intel/avs/boards/probe.c64
-rw-r--r--sound/soc/intel/avs/core.c2
-rw-r--r--sound/soc/intel/avs/debugfs.c436
-rw-r--r--sound/soc/intel/avs/ipc.c2
-rw-r--r--sound/soc/intel/avs/messages.c104
-rw-r--r--sound/soc/intel/avs/messages.h53
-rw-r--r--sound/soc/intel/avs/pcm.c6
-rw-r--r--sound/soc/intel/avs/probes.c313
-rw-r--r--sound/soc/intel/avs/registers.h3
-rw-r--r--sound/soc/intel/avs/skl.c17
-rw-r--r--sound/soc/intel/avs/utils.c22
-rw-r--r--sound/soc/intel/boards/Makefile3
-rw-r--r--sound/soc/intel/boards/sof_es8336.c2
-rw-r--r--sound/soc/intel/boards/sof_realtek_common.c3
-rw-r--r--sound/soc/intel/boards/sof_rt5682.c6
-rw-r--r--sound/soc/intel/boards/sof_sdw.c10
-rw-r--r--sound/soc/intel/boards/sof_sdw_common.h20
-rw-r--r--sound/soc/intel/boards/sof_sdw_rt1316.c239
-rw-r--r--sound/soc/intel/boards/sof_sdw_rt1318.c120
-rw-r--r--sound/soc/intel/boards/sof_sdw_rt_amp.c (renamed from sound/soc/intel/boards/sof_sdw_rt1308.c)139
-rw-r--r--sound/soc/intel/common/soc-acpi-intel-jsl-match.c5
-rw-r--r--sound/soc/intel/skylake/skl-sst-cldma.c27
-rw-r--r--sound/soc/intel/skylake/skl-topology.c73
-rw-r--r--sound/soc/intel/skylake/skl-topology.h1
-rw-r--r--sound/soc/intel/skylake/skl.c5
-rw-r--r--sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c7
-rw-r--r--sound/soc/mediatek/mt8183/mt8183-mt6358-ts3a227-max98357.c14
-rw-r--r--sound/soc/rockchip/rockchip_pdm.c1
-rw-r--r--sound/soc/soc-pcm.c20
42 files changed, 1378 insertions, 600 deletions
diff --git a/sound/hda/ext/hdac_ext_stream.c b/sound/hda/ext/hdac_ext_stream.c
index 2a071a09224d..11b7119cc47e 100644
--- a/sound/hda/ext/hdac_ext_stream.c
+++ b/sound/hda/ext/hdac_ext_stream.c
@@ -14,6 +14,7 @@
#include <sound/pcm.h>
#include <sound/hda_register.h>
#include <sound/hdaudio_ext.h>
+#include <sound/compress_driver.h>
/**
* snd_hdac_ext_stream_init - initialize each stream (aka device)
@@ -367,3 +368,43 @@ void snd_hdac_ext_stream_release(struct hdac_ext_stream *hext_stream, int type)
}
EXPORT_SYMBOL_GPL(snd_hdac_ext_stream_release);
+
+/**
+ * snd_hdac_ext_cstream_assign - assign a host stream for compress
+ * @bus: HD-audio core bus
+ * @cstream: Compress stream to assign
+ *
+ * Assign an unused host stream for the given compress stream.
+ * If no stream is free, NULL is returned. Stream is decoupled
+ * before assignment.
+ */
+struct hdac_ext_stream *snd_hdac_ext_cstream_assign(struct hdac_bus *bus,
+ struct snd_compr_stream *cstream)
+{
+ struct hdac_ext_stream *res = NULL;
+ struct hdac_stream *hstream;
+
+ spin_lock_irq(&bus->reg_lock);
+ list_for_each_entry(hstream, &bus->stream_list, list) {
+ struct hdac_ext_stream *hext_stream = stream_to_hdac_ext_stream(hstream);
+
+ if (hstream->direction != cstream->direction)
+ continue;
+
+ if (!hstream->opened) {
+ res = hext_stream;
+ break;
+ }
+ }
+
+ if (res) {
+ snd_hdac_ext_stream_decouple_locked(bus, res, true);
+ res->hstream.opened = 1;
+ res->hstream.running = 0;
+ res->hstream.cstream = cstream;
+ }
+ spin_unlock_irq(&bus->reg_lock);
+
+ return res;
+}
+EXPORT_SYMBOL_GPL(snd_hdac_ext_cstream_assign);
diff --git a/sound/hda/hdac_controller.c b/sound/hda/hdac_controller.c
index 9a60bfdb39ba..3c7af6558249 100644
--- a/sound/hda/hdac_controller.c
+++ b/sound/hda/hdac_controller.c
@@ -578,8 +578,8 @@ int snd_hdac_bus_handle_stream_irq(struct hdac_bus *bus, unsigned int status,
sd_status = snd_hdac_stream_readb(azx_dev, SD_STS);
snd_hdac_stream_writeb(azx_dev, SD_STS, SD_INT_MASK);
handled |= 1 << azx_dev->index;
- if (!azx_dev->substream || !azx_dev->running ||
- !(sd_status & SD_INT_COMPLETE))
+ if ((!azx_dev->substream && !azx_dev->cstream) ||
+ !azx_dev->running || !(sd_status & SD_INT_COMPLETE))
continue;
if (ack)
ack(bus, azx_dev);
diff --git a/sound/hda/hdac_stream.c b/sound/hda/hdac_stream.c
index 3b250ee7f6a7..8f625402505f 100644
--- a/sound/hda/hdac_stream.c
+++ b/sound/hda/hdac_stream.c
@@ -7,6 +7,7 @@
#include <linux/delay.h>
#include <linux/export.h>
#include <linux/clocksource.h>
+#include <sound/compress_driver.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/hdaudio.h>
@@ -487,11 +488,20 @@ int snd_hdac_stream_setup_periods(struct hdac_stream *azx_dev)
{
struct hdac_bus *bus = azx_dev->bus;
struct snd_pcm_substream *substream = azx_dev->substream;
- struct snd_pcm_runtime *runtime = substream->runtime;
+ struct snd_compr_stream *cstream = azx_dev->cstream;
+ struct snd_pcm_runtime *runtime = NULL;
+ struct snd_dma_buffer *dmab;
__le32 *bdl;
int i, ofs, periods, period_bytes;
int pos_adj, pos_align;
+ if (substream) {
+ runtime = substream->runtime;
+ dmab = snd_pcm_get_dma_buf(substream);
+ } else if (cstream) {
+ dmab = snd_pcm_get_dma_buf(cstream);
+ }
+
/* reset BDL address */
snd_hdac_stream_writel(azx_dev, SD_BDLPL, 0);
snd_hdac_stream_writel(azx_dev, SD_BDLPU, 0);
@@ -505,7 +515,7 @@ int snd_hdac_stream_setup_periods(struct hdac_stream *azx_dev)
azx_dev->frags = 0;
pos_adj = bus->bdl_pos_adj;
- if (!azx_dev->no_period_wakeup && pos_adj > 0) {
+ if (runtime && !azx_dev->no_period_wakeup && pos_adj > 0) {
pos_align = pos_adj;
pos_adj = DIV_ROUND_UP(pos_adj * runtime->rate, 48000);
if (!pos_adj)
@@ -518,8 +528,7 @@ int snd_hdac_stream_setup_periods(struct hdac_stream *azx_dev)
pos_adj);
pos_adj = 0;
} else {
- ofs = setup_bdle(bus, snd_pcm_get_dma_buf(substream),
- azx_dev,
+ ofs = setup_bdle(bus, dmab, azx_dev,
&bdl, ofs, pos_adj, true);
if (ofs < 0)
goto error;
@@ -529,13 +538,11 @@ int snd_hdac_stream_setup_periods(struct hdac_stream *azx_dev)
for (i = 0; i < periods; i++) {
if (i == periods - 1 && pos_adj)
- ofs = setup_bdle(bus, snd_pcm_get_dma_buf(substream),
- azx_dev, &bdl, ofs,
- period_bytes - pos_adj, 0);
+ ofs = setup_bdle(bus, dmab, azx_dev,
+ &bdl, ofs, period_bytes - pos_adj, 0);
else
- ofs = setup_bdle(bus, snd_pcm_get_dma_buf(substream),
- azx_dev, &bdl, ofs,
- period_bytes,
+ ofs = setup_bdle(bus, dmab, azx_dev,
+ &bdl, ofs, period_bytes,
!azx_dev->no_period_wakeup);
if (ofs < 0)
goto error;
@@ -560,26 +567,32 @@ EXPORT_SYMBOL_GPL(snd_hdac_stream_setup_periods);
int snd_hdac_stream_set_params(struct hdac_stream *azx_dev,
unsigned int format_val)
{
-
- unsigned int bufsize, period_bytes;
struct snd_pcm_substream *substream = azx_dev->substream;
- struct snd_pcm_runtime *runtime;
+ struct snd_compr_stream *cstream = azx_dev->cstream;
+ unsigned int bufsize, period_bytes;
+ unsigned int no_period_wakeup;
int err;
- if (!substream)
+ if (substream) {
+ bufsize = snd_pcm_lib_buffer_bytes(substream);
+ period_bytes = snd_pcm_lib_period_bytes(substream);
+ no_period_wakeup = substream->runtime->no_period_wakeup;
+ } else if (cstream) {
+ bufsize = cstream->runtime->buffer_size;
+ period_bytes = cstream->runtime->fragment_size;
+ no_period_wakeup = 0;
+ } else {
return -EINVAL;
- runtime = substream->runtime;
- bufsize = snd_pcm_lib_buffer_bytes(substream);
- period_bytes = snd_pcm_lib_period_bytes(substream);
+ }
if (bufsize != azx_dev->bufsize ||
period_bytes != azx_dev->period_bytes ||
format_val != azx_dev->format_val ||
- runtime->no_period_wakeup != azx_dev->no_period_wakeup) {
+ no_period_wakeup != azx_dev->no_period_wakeup) {
azx_dev->bufsize = bufsize;
azx_dev->period_bytes = period_bytes;
azx_dev->format_val = format_val;
- azx_dev->no_period_wakeup = runtime->no_period_wakeup;
+ azx_dev->no_period_wakeup = no_period_wakeup;
err = snd_hdac_stream_setup_periods(azx_dev);
if (err < 0)
return err;
diff --git a/sound/soc/codecs/wcd-clsh-v2.c b/sound/soc/codecs/wcd-clsh-v2.c
index 4c7ebc7fb400..a75db27e5205 100644
--- a/sound/soc/codecs/wcd-clsh-v2.c
+++ b/sound/soc/codecs/wcd-clsh-v2.c
@@ -130,12 +130,6 @@ static inline void wcd_enable_clsh_block(struct wcd_clsh_ctrl *ctrl,
ctrl->clsh_users = 0;
}
-static inline bool wcd_clsh_enable_status(struct snd_soc_component *comp)
-{
- return snd_soc_component_read(comp, WCD9XXX_A_CDC_CLSH_CRC) &
- WCD9XXX_A_CDC_CLSH_CRC_CLK_EN_MASK;
-}
-
static inline void wcd_clsh_set_buck_mode(struct snd_soc_component *comp,
int mode)
{
diff --git a/sound/soc/fsl/imx-audmux.c b/sound/soc/fsl/imx-audmux.c
index 50b71e5d4589..582f1e2431ee 100644
--- a/sound/soc/fsl/imx-audmux.c
+++ b/sound/soc/fsl/imx-audmux.c
@@ -75,8 +75,7 @@ static ssize_t audmux_read_file(struct file *file, char __user *user_buf,
if (!buf)
return -ENOMEM;
- ret = scnprintf(buf, PAGE_SIZE, "PDCR: %08x\nPTCR: %08x\n",
- pdcr, ptcr);
+ ret = sysfs_emit(buf, "PDCR: %08x\nPTCR: %08x\n", pdcr, ptcr);
if (ptcr & IMX_AUDMUX_V2_PTCR_TFSDIR)
ret += scnprintf(buf + ret, PAGE_SIZE - ret,
diff --git a/sound/soc/generic/audio-graph-card.c b/sound/soc/generic/audio-graph-card.c
index fe7cf972d44c..5daa824a4ffc 100644
--- a/sound/soc/generic/audio-graph-card.c
+++ b/sound/soc/generic/audio-graph-card.c
@@ -485,8 +485,10 @@ static int __graph_for_each_link(struct asoc_simple_priv *priv,
of_node_put(codec_ep);
of_node_put(codec_port);
- if (ret < 0)
+ if (ret < 0) {
+ of_node_put(cpu_ep);
return ret;
+ }
codec_port_old = codec_port;
}
diff --git a/sound/soc/intel/Kconfig b/sound/soc/intel/Kconfig
index ac799de4f7fd..4b9e498e3303 100644
--- a/sound/soc/intel/Kconfig
+++ b/sound/soc/intel/Kconfig
@@ -217,6 +217,7 @@ config SND_SOC_INTEL_AVS
select SND_SOC_ACPI if ACPI
select SND_SOC_TOPOLOGY
select SND_SOC_HDA
+ select SND_SOC_COMPRESS if DEBUG_FS
select SND_HDA_EXT_CORE
select SND_HDA_DSP_LOADER
select SND_INTEL_DSP_CONFIG
diff --git a/sound/soc/intel/avs/Makefile b/sound/soc/intel/avs/Makefile
index 919212825f21..1c6924a1ebca 100644
--- a/sound/soc/intel/avs/Makefile
+++ b/sound/soc/intel/avs/Makefile
@@ -9,6 +9,10 @@ snd-soc-avs-objs += trace.o
# tell define_trace.h where to find the trace header
CFLAGS_trace.o := -I$(src)
+ifneq ($(CONFIG_DEBUG_FS),)
+snd-soc-avs-objs += probes.o debugfs.o
+endif
+
obj-$(CONFIG_SND_SOC_INTEL_AVS) += snd-soc-avs.o
# Machine support
diff --git a/sound/soc/intel/avs/apl.c b/sound/soc/intel/avs/apl.c
index 7c8ce98eda9d..02683dce277a 100644
--- a/sound/soc/intel/avs/apl.c
+++ b/sound/soc/intel/avs/apl.c
@@ -13,8 +13,9 @@
#include "path.h"
#include "topology.h"
-static int apl_enable_logs(struct avs_dev *adev, enum avs_log_enable enable, u32 aging_period,
- u32 fifo_full_period, unsigned long resource_mask, u32 *priorities)
+static int __maybe_unused
+apl_enable_logs(struct avs_dev *adev, enum avs_log_enable enable, u32 aging_period,
+ u32 fifo_full_period, unsigned long resource_mask, u32 *priorities)
{
struct apl_log_state_info *info;
u32 size, num_cores = adev->hw_cfg.dsp_cores;
@@ -50,7 +51,6 @@ static int apl_enable_logs(struct avs_dev *adev, enum avs_log_enable enable, u32
static int apl_log_buffer_status(struct avs_dev *adev, union avs_notify_msg *msg)
{
struct apl_log_buffer_layout layout;
- unsigned long flags;
void __iomem *addr, *buf;
addr = avs_log_buffer_addr(adev, msg->log.core);
@@ -59,26 +59,20 @@ static int apl_log_buffer_status(struct avs_dev *adev, union avs_notify_msg *msg
memcpy_fromio(&layout, addr, sizeof(layout));
- spin_lock_irqsave(&adev->dbg.trace_lock, flags);
- if (!kfifo_initialized(&adev->dbg.trace_fifo))
+ if (!avs_logging_fw(adev))
/* consume the logs regardless of consumer presence */
goto update_read_ptr;
buf = apl_log_payload_addr(addr);
if (layout.read_ptr > layout.write_ptr) {
- __kfifo_fromio_locked(&adev->dbg.trace_fifo, buf + layout.read_ptr,
- apl_log_payload_size(adev) - layout.read_ptr,
- &adev->dbg.fifo_lock);
+ avs_dump_fw_log(adev, buf + layout.read_ptr,
+ apl_log_payload_size(adev) - layout.read_ptr);
layout.read_ptr = 0;
}
- __kfifo_fromio_locked(&adev->dbg.trace_fifo, buf + layout.read_ptr,
- layout.write_ptr - layout.read_ptr, &adev->dbg.fifo_lock);
-
- wake_up(&adev->dbg.trace_waitq);
+ avs_dump_fw_log_wakeup(adev, buf + layout.read_ptr, layout.write_ptr - layout.read_ptr);
update_read_ptr:
- spin_unlock_irqrestore(&adev->dbg.trace_lock, flags);
writel(layout.write_ptr, addr);
return 0;
}
@@ -140,7 +134,7 @@ static int apl_coredump(struct avs_dev *adev, union avs_notify_msg *msg)
* gathered before dumping stack
*/
lbs_msg.log.core = msg->ext.coredump.core_id;
- avs_dsp_op(adev, log_buffer_status, &lbs_msg);
+ avs_log_buffer_status_locked(adev, &lbs_msg);
}
pos = dump + AVS_FW_REGS_SIZE;
@@ -243,10 +237,10 @@ const struct avs_dsp_ops apl_dsp_ops = {
.load_basefw = avs_hda_load_basefw,
.load_lib = avs_hda_load_library,
.transfer_mods = avs_hda_transfer_modules,
- .enable_logs = apl_enable_logs,
.log_buffer_offset = skl_log_buffer_offset,
.log_buffer_status = apl_log_buffer_status,
.coredump = apl_coredump,
.d0ix_toggle = apl_d0ix_toggle,
.set_d0ix = apl_set_d0ix,
+ AVS_SET_ENABLE_LOGS_OP(apl)
};
diff --git a/sound/soc/intel/avs/avs.h b/sound/soc/intel/avs/avs.h
index 8d05b27608fe..d7fccdcb9c16 100644
--- a/sound/soc/intel/avs/avs.h
+++ b/sound/soc/intel/avs/avs.h
@@ -9,6 +9,7 @@
#ifndef __SOUND_SOC_INTEL_AVS_H
#define __SOUND_SOC_INTEL_AVS_H
+#include <linux/debugfs.h>
#include <linux/device.h>
#include <linux/firmware.h>
#include <linux/kfifo.h>
@@ -93,16 +94,6 @@ struct avs_fw_entry {
struct list_head node;
};
-struct avs_debug {
- struct kfifo trace_fifo;
- spinlock_t fifo_lock; /* serialize I/O for trace_fifo */
- spinlock_t trace_lock; /* serialize debug window I/O between each LOG_BUFFER_STATUS */
- wait_queue_head_t trace_waitq;
- u32 aging_timer_period;
- u32 fifo_full_timer_period;
- u32 logged_resources; /* context dependent: core or library */
-};
-
/*
* struct avs_dev - Intel HD-Audio driver data
*
@@ -146,7 +137,18 @@ struct avs_dev {
spinlock_t path_list_lock;
struct mutex path_mutex;
- struct avs_debug dbg;
+ spinlock_t trace_lock; /* serialize debug window I/O between each LOG_BUFFER_STATUS */
+#ifdef CONFIG_DEBUG_FS
+ struct kfifo trace_fifo;
+ wait_queue_head_t trace_waitq;
+ u32 aging_timer_period;
+ u32 fifo_full_timer_period;
+ u32 logged_resources; /* context dependent: core or library */
+ struct dentry *debugfs_root;
+ /* probes */
+ struct hdac_ext_stream *extractor;
+ unsigned int num_probe_streams;
+#endif
};
/* from hda_bus to avs_dev */
@@ -321,6 +323,9 @@ struct avs_soc_component {
extern const struct snd_soc_dai_ops avs_dai_fe_ops;
+int avs_soc_component_register(struct device *dev, const char *name,
+ const struct snd_soc_component_driver *drv,
+ struct snd_soc_dai_driver *cpu_dais, int num_cpu_dais);
int avs_dmic_platform_register(struct avs_dev *adev, const char *name);
int avs_i2s_platform_register(struct avs_dev *adev, const char *name, unsigned long port_mask,
unsigned long *tdms);
@@ -331,9 +336,6 @@ void avs_unregister_all_boards(struct avs_dev *adev);
/* Firmware tracing helpers */
-unsigned int __kfifo_fromio_locked(struct kfifo *fifo, const void __iomem *src, unsigned int len,
- spinlock_t *lock);
-
#define avs_log_buffer_size(adev) \
((adev)->fw_cfg.trace_log_bytes / (adev)->hw_cfg.dsp_cores)
@@ -344,6 +346,18 @@ unsigned int __kfifo_fromio_locked(struct kfifo *fifo, const void __iomem *src,
(avs_sram_addr(adev, AVS_DEBUG_WINDOW) + __offset); \
})
+static inline int avs_log_buffer_status_locked(struct avs_dev *adev, union avs_notify_msg *msg)
+{
+ unsigned long flags;
+ int ret;
+
+ spin_lock_irqsave(&adev->trace_lock, flags);
+ ret = avs_dsp_op(adev, log_buffer_status, msg);
+ spin_unlock_irqrestore(&adev->trace_lock, flags);
+
+ return ret;
+}
+
struct apl_log_buffer_layout {
u32 read_ptr;
u32 write_ptr;
@@ -356,4 +370,42 @@ struct apl_log_buffer_layout {
#define apl_log_payload_addr(addr) \
(addr + sizeof(struct apl_log_buffer_layout))
+#ifdef CONFIG_DEBUG_FS
+#define AVS_SET_ENABLE_LOGS_OP(name) \
+ .enable_logs = name##_enable_logs
+
+bool avs_logging_fw(struct avs_dev *adev);
+void avs_dump_fw_log(struct avs_dev *adev, const void __iomem *src, unsigned int len);
+void avs_dump_fw_log_wakeup(struct avs_dev *adev, const void __iomem *src, unsigned int len);
+
+int avs_probe_platform_register(struct avs_dev *adev, const char *name);
+
+void avs_debugfs_init(struct avs_dev *adev);
+void avs_debugfs_exit(struct avs_dev *adev);
+#else
+#define AVS_SET_ENABLE_LOGS_OP(name)
+
+static inline bool avs_logging_fw(struct avs_dev *adev)
+{
+ return false;
+}
+
+static inline void avs_dump_fw_log(struct avs_dev *adev, const void __iomem *src, unsigned int len)
+{
+}
+
+static inline void
+avs_dump_fw_log_wakeup(struct avs_dev *adev, const void __iomem *src, unsigned int len)
+{
+}
+
+static inline int avs_probe_platform_register(struct avs_dev *adev, const char *name)
+{
+ return 0;
+}
+
+static inline void avs_debugfs_init(struct avs_dev *adev) { }
+static inline void avs_debugfs_exit(struct avs_dev *adev) { }
+#endif
+
#endif /* __SOUND_SOC_INTEL_AVS_H */
diff --git a/sound/soc/intel/avs/board_selection.c b/sound/soc/intel/avs/board_selection.c
index 02cc1ce8f5f5..b2823c2107f7 100644
--- a/sound/soc/intel/avs/board_selection.c
+++ b/sound/soc/intel/avs/board_selection.c
@@ -291,6 +291,33 @@ static void board_pdev_unregister(void *data)
platform_device_unregister(data);
}
+static int __maybe_unused avs_register_probe_board(struct avs_dev *adev)
+{
+ struct platform_device *board;
+ struct snd_soc_acpi_mach mach = {{0}};
+ int ret;
+
+ ret = avs_probe_platform_register(adev, "probe-platform");
+ if (ret < 0)
+ return ret;
+
+ mach.mach_params.platform = "probe-platform";
+
+ board = platform_device_register_data(NULL, "avs_probe_mb", PLATFORM_DEVID_NONE,
+ (const void *)&mach, sizeof(mach));
+ if (IS_ERR(board)) {
+ dev_err(adev->dev, "probe board register failed\n");
+ return PTR_ERR(board);
+ }
+
+ ret = devm_add_action(adev->dev, board_pdev_unregister, board);
+ if (ret < 0) {
+ platform_device_unregister(board);
+ return ret;
+ }
+ return 0;
+}
+
static int avs_register_dmic_board(struct avs_dev *adev)
{
struct platform_device *codec, *board;
@@ -500,6 +527,12 @@ int avs_register_all_boards(struct avs_dev *adev)
{
int ret;
+#ifdef CONFIG_DEBUG_FS
+ ret = avs_register_probe_board(adev);
+ if (ret < 0)
+ dev_warn(adev->dev, "enumerate PROBE endpoints failed: %d\n", ret);
+#endif
+
ret = avs_register_dmic_board(adev);
if (ret < 0)
dev_warn(adev->dev, "enumerate DMIC endpoints failed: %d\n",
diff --git a/sound/soc/intel/avs/boards/Kconfig b/sound/soc/intel/avs/boards/Kconfig
index 9bd40fdd9028..e4c230efe8d7 100644
--- a/sound/soc/intel/avs/boards/Kconfig
+++ b/sound/soc/intel/avs/boards/Kconfig
@@ -77,6 +77,14 @@ config SND_SOC_INTEL_AVS_MACH_NAU8825
Say Y or m if you have such a device. This is a recommended option.
If unsure select "N".
+config SND_SOC_INTEL_AVS_MACH_PROBE
+ tristate "Probing (data) board"
+ depends on DEBUG_FS
+ select SND_HWDEP
+ help
+ This adds support for data probing board which can be used to
+ gather data from runtime stream over compress operations.
+
config SND_SOC_INTEL_AVS_MACH_RT274
tristate "rt274 in I2S mode"
depends on I2C
diff --git a/sound/soc/intel/avs/boards/Makefile b/sound/soc/intel/avs/boards/Makefile
index 4d70b8d09ce5..b81343420370 100644
--- a/sound/soc/intel/avs/boards/Makefile
+++ b/sound/soc/intel/avs/boards/Makefile
@@ -8,6 +8,7 @@ snd-soc-avs-max98927-objs := max98927.o
snd-soc-avs-max98357a-objs := max98357a.o
snd-soc-avs-max98373-objs := max98373.o
snd-soc-avs-nau8825-objs := nau8825.o
+snd-soc-avs-probe-objs := probe.o
snd-soc-avs-rt274-objs := rt274.o
snd-soc-avs-rt286-objs := rt286.o
snd-soc-avs-rt298-objs := rt298.o
@@ -22,6 +23,7 @@ obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_MAX98927) += snd-soc-avs-max98927.o
obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_MAX98357A) += snd-soc-avs-max98357a.o
obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_MAX98373) += snd-soc-avs-max98373.o
obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_NAU8825) += snd-soc-avs-nau8825.o
+obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_PROBE) += snd-soc-avs-probe.o
obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_RT274) += snd-soc-avs-rt274.o
obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_RT286) += snd-soc-avs-rt286.o
obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_RT298) += snd-soc-avs-rt298.o
diff --git a/sound/soc/intel/avs/boards/probe.c b/sound/soc/intel/avs/boards/probe.c
new file mode 100644
index 000000000000..411acaee74f9
--- /dev/null
+++ b/sound/soc/intel/avs/boards/probe.c
@@ -0,0 +1,64 @@
+// SPDX-License-Identifier: GPL-2.0-only
+//
+// Copyright(c) 2021-2022 Intel Corporation. All rights reserved.
+//
+// Authors: Cezary Rojewski <cezary.rojewski@intel.com>
+// Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>
+//
+
+#include <linux/device.h>
+#include <linux/module.h>
+#include <sound/soc.h>
+#include <sound/soc-acpi.h>
+
+SND_SOC_DAILINK_DEF(dummy, DAILINK_COMP_ARRAY(COMP_DUMMY()));
+SND_SOC_DAILINK_DEF(probe_cp, DAILINK_COMP_ARRAY(COMP_CPU("Probe Extraction CPU DAI")));
+SND_SOC_DAILINK_DEF(platform, DAILINK_COMP_ARRAY(COMP_PLATFORM("probe-platform")));
+
+static struct snd_soc_dai_link probe_mb_dai_links[] = {
+ {
+ .name = "Compress Probe Capture",
+ .nonatomic = 1,
+ SND_SOC_DAILINK_REG(probe_cp, dummy, platform),
+ },
+};
+
+static int avs_probe_mb_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct snd_soc_acpi_mach *mach;
+ struct snd_soc_card *card;
+ int ret;
+
+ mach = dev_get_platdata(dev);
+
+ card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL);
+ if (!card)
+ return -ENOMEM;
+
+ card->name = "avs_probe_mb";
+ card->dev = dev;
+ card->owner = THIS_MODULE;
+ card->dai_link = probe_mb_dai_links;
+ card->num_links = ARRAY_SIZE(probe_mb_dai_links);
+ card->fully_routed = true;
+
+ ret = snd_soc_fixup_dai_links_platform_name(card, mach->mach_params.platform);
+ if (ret)
+ return ret;
+
+ return devm_snd_soc_register_card(dev, card);
+}
+
+static struct platform_driver avs_probe_mb_driver = {
+ .probe = avs_probe_mb_probe,
+ .driver = {
+ .name = "avs_probe_mb",
+ .pm = &snd_soc_pm_ops,
+ },
+};
+
+module_platform_driver(avs_probe_mb_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:avs_probe_mb");
diff --git a/sound/soc/intel/avs/core.c b/sound/soc/intel/avs/core.c
index f7bc06404dbc..2ca24273c491 100644
--- a/sound/soc/intel/avs/core.c
+++ b/sound/soc/intel/avs/core.c
@@ -214,6 +214,7 @@ static void avs_hda_probe_work(struct work_struct *work)
adev->nhlt = intel_nhlt_init(adev->dev);
if (!adev->nhlt)
dev_info(bus->dev, "platform has no NHLT\n");
+ avs_debugfs_init(adev);
avs_register_all_boards(adev);
@@ -491,6 +492,7 @@ static void avs_pci_remove(struct pci_dev *pci)
avs_unregister_all_boards(adev);
+ avs_debugfs_exit(adev);
if (adev->nhlt)
intel_nhlt_free(adev->nhlt);
diff --git a/sound/soc/intel/avs/debugfs.c b/sound/soc/intel/avs/debugfs.c
new file mode 100644
index 000000000000..bdd388ec01ea
--- /dev/null
+++ b/sound/soc/intel/avs/debugfs.c
@@ -0,0 +1,436 @@
+// SPDX-License-Identifier: GPL-2.0-only
+//
+// Copyright(c) 2021-2022 Intel Corporation. All rights reserved.
+//
+// Authors: Cezary Rojewski <cezary.rojewski@intel.com>
+// Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>
+//
+