Skip to content

amd/acp7x: smart_amp: enable Maxim DSM for 2x max98388 on TDM2 - #11249

Closed
LongWang100 wants to merge 309 commits into
thesofproject:origin/amd-acp7b-stablefrom
LongWang100:amd-acp7b-stable-dsm-support
Closed

LongWang100 wants to merge 309 commits into
thesofproject:origin/amd-acp7b-stablefrom
LongWang100:amd-acp7b-stable-dsm-support

Conversation

@LongWang100

Copy link
Copy Markdown
Contributor

Summary

Bring up the Maxim DSM smart amplifier path on ACP7x (Steam Deck /
Gainsborough) with two max98388 amplifiers on a 2-slot TDM2 link.

This patch fixes a series of bugs discovered during hardware bring-up
and wires up the full topology pipeline (playback → smart_amp →
ref-capture → DSM feedback).

Changes

smart_amp.c

  • IPC3 source buffer fix: bound_module is only populated by
    module_bind() in module_adapter_ipc4.c and is NULL on IPC3
    platforms; dereferencing it caused a DSP fault. Switch to comparing
    producer pipeline IDs, which works under both IPC versions.
  • 16-byte DSP buffer alignment: allocate via mod_alloc_align()
    to satisfy Xtensa HiFi AE_L32X2/AE_S64 alignment requirements;
    without this the DSP raises LoadStoreAlignmentCause.
  • Null-guard source_buf after re-prepare to prevent stale pointer
    reuse.

maxim_dsm_stub.c

  • Fix stub output fields: the upstream stub returned DSM_API_OK
    without writing omemsizerequestedbytes, so get_handle_size() returned
    0, the PRIVATE memblk was never allocated, dsmhandle stayed NULL, and
    every subsequent DSM call failed with -EINVAL.
  • The fixed stub also passes audio through (input → output) so the glue
    layer and topology can be validated without libdsm.a.

smart_amp_maxim_dsm.c

  • Fix DSM_FF_BUF_DB_SZ: upstream used FF_BUF_SZ * FF_MAX_CH_NUM
    = 192, too small for a 2 ms period (192 samples) + pre-fill frame (96).
    Change to FF_BUF_SZ * 4 = 384 to cover periods up to 3 ms.
  • Add ivFormat=3 (DSM_IV_FORMAT_INTERLEAVED_16_BIT_MSB) support:
    each max98388 interleaves V and I within one TDM slot using the sample
    MSB as a flag; the upstream 4*idx stride read only one MSB polarity and
    returned INSUFFICIENT_INPUT_DATA.
  • Replace memcpy_s with dsm_buf_shift_down() (memmove-based):
    SOF's memcpy_s rejects overlapping src/dst with -EINVAL, which
    occurs whenever period > 2 ms and caused silent buffer desynchronisation.
  • Change if to while in ff_proc/fb_proc: a 2 ms period
    delivers 2 DSM frames; the previous if drained only one per call,
    causing w_ptr to grow until overflow.
  • Remove duplicate dsm_api_ff_process() call in the 32-bit else
    branch: libdsm decrements *ipNrSamples in-place; a second call would
    double-advance the adaptive state (excursion/thermal model, RDC, LMS).
  • Set ibsamples = fb_fr_sz_samples * nchannels = 96: libdsm divides
    by nChannels internally; passing 48 gave 24 % ffFrameSize != 0 and
    returned INVALID_PARAM on every call.

sof-acp_7_x_i2s.m4

  • Switch TDM2 pipeline from passthrough to smart-amplifier +
    amp-ref-capture.
  • Define all required SMART_* macros for 2-channel configuration.
  • Wire cross-pipeline SectionGraph: demux → smart_amp feedback buffer.
  • Set REF_CHMAP = {0x01, 0x02} so the echo reference second channel
    comes from slot 1 (second amp), not the non-existent slot 2.
  • Declare SMART_UUID explicitly to make the active build mode visible.

pipe-amp-ref-capture.m4

  • Allow platforms to pre-define REF_CHMAP to override the default
    4-slot mapping, which routes ch1 to in ch2 (non-existent on 2-slot
    hardware) and permanently silences ch1 via mux.c:215.

app/maxim_dsm_overlay.conf

  • Add Kconfig overlay documenting the three-step DSM bring-up sequence:
    • Step 1: PASSTHRU_AMP — verify audio path without DSM
    • Step 2: MAXIM_DSM_STUB — validate glue layer and topology
    • Step 3: real libdsm.a — full DSM protection

Test plan

  • Step 1 (PASSTHRU_AMP): stereo playback on ACP7x, no DSP fault
  • Step 2 (MAXIM_DSM_STUB): DSM path exercised, DSM_API_OK returned,
    dsmhandle non-NULL, audio passes through
  • Step 3 (real libdsm): Rdc/excursion monitoring active, V/I sense
    correct on both channels, no INSUFFICIENT_INPUT_DATA / INVALID_PARAM
  • Re-prepare path (suspend/resume): no stale pointer crash
  • Period > 2 ms: buffer pointers stable, no overflow

🤖 Generated with Claude Code

lrgirdwo and others added 30 commits June 15, 2026 15:34
downmix16bit_4ch_mono() loads its coeffs[] array with AE_L16X4_X, an
aligned 64-bit HiFi load that requires 8-byte alignment. The uint16_t
stack array is only 2-byte aligned, so the compiler may place it on a
4-byte boundary and trigger a misaligned access. Force 8-byte alignment
to match the intrinsic's requirement.

Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
When ipc_pipeline_free() frees a pipeline, component devices that
were connected to it retain stale cd->pipeline pointers. If an IPC
(e.g. stream position request) later dereferences that pointer, it
triggers a use-after-free.

Fix this by iterating all components in the IPC comp_list and setting
cd->pipeline = NULL for any component whose pipeline matches the one
being freed. This makes the existing NULL checks in handler.c
effective and prevents the dangling pointer dereference.

Found by fuzzing with AddressSanitizer enabled.

Signed-off-by: Tomasz Leman <tomasz.m.leman@intel.com>
ipc4_set_vendor_config_module_instance() only validated data_off_size in
the bursted-config path (init_block && final_block). The else path with
init_block == 1 && final_block == 0 unconditionally executed:

	data += sizeof(struct sof_tlv);
	data_off_size -= sizeof(struct sof_tlv);

data_off_size is a host-controlled 20-bit field taken straight from the
IPC message. When it is smaller than sizeof(struct sof_tlv) (8) the
subtraction underflows and wraps to a value close to 0xFFFFFFFF, which is
then forwarded as the length to the module's set_large_config() handler.
The actual backing buffer is only the MAILBOX_HOSTBOX_SIZE mailbox, so a
compromised host could trigger out-of-bounds reads of DSP SRAM (and
possible corruption depending on the target module) by sending
MOD_LARGE_CONFIG_SET with init_block=1, final_block=0 and
data_off_size < 8.

Hoist the existing "data_off_size < sizeof(struct sof_tlv) ||
data_off_size > MAILBOX_HOSTBOX_SIZE" bounds check to the top of the
function so it runs for every entry, before any pointer or size
arithmetic. The duplicate check in the bursted-config branch is removed
as it is now covered by the hoisted one.

Signed-off-by: Jyri Sarha <jyri.sarha@linux.intel.com>
ipc4_process_chain_dma() called ipc4_chain_dma_state() and then, on the
deallocate path (allocate == 0 && enable == 0), unconditionally executed
list_item_del(&cdma_comp->list).

However, on that same deallocate path ipc4_chain_dma_state() already
unlinks the matching ipc_comp_dev from ipc->comp_list and frees it with
rfree():

	list_item_del(&icd->list);
	rfree(icd);

Since icd is the same object as cdma_comp, the subsequent
list_item_del(&cdma_comp->list) in the caller dereferenced and wrote to
already-freed memory (prev->next / next->prev), a use-after-free. With
heap grooming a host sending GLB_CHAIN_DMA with allocate=0/enable=0 on an
existing chain could turn this into controlled heap corruption.

The unlink-before-free is already handled correctly by
ipc4_chain_dma_state(), so the duplicate list_item_del() in the caller is
both redundant and unsafe. Remove it.

Signed-off-by: Jyri Sarha <jyri.sarha@linux.intel.com>
Export ds_msg() to allow using it in loadable modules.

Signed-off-by: Jyri Sarha <jyri.sarha@linux.intel.com>
Make debug_stream_slot_send_record() a Zephyr syscall. This allows
user-space threads to send debug stream records directly.

Rename the implementation to z_impl_debug_stream_slot_send_record() and
add z_vrfy_debug_stream_slot_send_record() with K_SYSCALL_MEMORY_READ
validation of the record buffer. Register the syscall header in
CMakeLists.txt.

Signed-off-by: Jyri Sarha <jyri.sarha@linux.intel.com>
kpb_set_micselect() computed mic_cnt = channels -
KPB_REFERENCE_SUPPORT_CHANNELS without checking the lower bound. With
a host-configured channel count below 2 the unsigned subtraction
wraps, producing a huge loop bound and out-of-bounds writes to the
fixed offsets[] array.

Reject payloads smaller than the config struct and channel counts
outside the supported range before computing mic_cnt, and bound the
offsets[] index inside the loop.

Signed-off-by: Tomasz Leman <tomasz.m.leman@intel.com>
The KP_BUF_CFG_FM_MODULE large-config path cast the host payload to
struct kpb_task_params and iterated dev_ids[] for number_of_modules
entries without checking it against the declared payload length, so a
number_of_modules larger than the payload caused out-of-bounds reads.

Verify the payload covers the header and all declared dev_ids[]
entries before processing the list.

Signed-off-by: Tomasz Leman <tomasz.m.leman@intel.com>
prepare_fmt_modules_list() populates kpb_list_item[], device_list[]
and modules_list_item[] entries as it walks the module list. On any
mid-loop failure it returned without undoing those entries, while the
caller had already cleared the previous list, leaving a
half-configured Fast Mode Task list with stale component references.

Roll back the touched entries via clear_fmt_modules_list() on the
error path, and add a defensive bound check on outpin_idx.

Signed-off-by: Tomasz Leman <tomasz.m.leman@intel.com>
SOF does not use the Zephyr LLEXT Extension Development Kit. The EDK
target is automatically enabled by Kconfig (default y if LLEXT) but
serves no purpose for SOF builds and adds unnecessary build steps.

Additionally, the EDK build infrastructure has a known bug on Windows
with ccache enabled (zephyrproject-rtos/zephyr#109146) that causes CI
failures due to path quoting issues in misc/llext_edk/CMakeLists.txt.

Explicitly disable CONFIG_LLEXT_EDK on all LLEXT-enabled boards to avoid
the broken code path and reduce build time.

Signed-off-by: Tomasz Leman <tomasz.m.leman@intel.com>
Total of 3581 commits.

Changes include:

b6c7c8fff5a5 xtensa: add dedicated NMI handler
94507fc8c0fe soc: imx95: m7: Apply clang-format formatting
c375832244b5 soc: imx95: m7: add SAI clock setup for all enabled SAI
             instances
e5a8c2188555 xtensa: exc: give magic custom exccause names
65a542bd12db arch: xtensa: initialize secondary cpu interrupt stacks on
             smp
53f001200f30 soc: nxp: imx95: Refine condition to enable
             MCUX_LPTMR_TIMER
ff30cf8a3bd8 drivers: audio: add native_sim DMIC driver
2826b086d135 drivers: dai: add AMD ACP 7.X SoundWire DAI support
bcfa5e42c4d5 xtensa: mpu: consolidate map if not enough free slots
064bde92a5b1 xtensa: mpu: consolidate_entries() to return if success
679d3fbc5b83 xtensa: mpu: fix adding to empty MPU map
8eb69ba1c6cb xtensa: mpu: optimize arch_mem_domain_thread_add() a bit
1ed96c9b490f xtensa: mpu: restore boot perms when removing thread from
             domain
7433d1f286b0 xtensa: mpu: limit MPU entries sorting to enabled ones
b92d7325d9ca xtensa: mpu: introduce memory type table
58a5ec11ceca xtensa: mpu: remove xtensa_soc_mpu_ranges[]
acadac7f3e78 xtensa: mpu: extract the MPU region table to its own file
4167d79b71fb xtensa: move MPU code into its own directory
7491f2c62d2a drivers: audio: add dummy codec stub driver
03200bf45774 soc: intel_adsp: ace: remove including manifest.h in sram.c
f329a610ed36 soc: intel_adsp: correct dependency on cached region
             kconfigs
f4fe6aa62b7c soc: intel_adsp/ace: correct CONFIG_XTENSA_CPU_HAS_HIFI*
52a570f308c0 xtensa: add CONFIG_XTENSA_HIFI5
f2b07e6fd28a soc: intel_adsp: use generated linker snippet for vectors
d0b389da9eae kernel: remove redundant kernel_structs.h includes
4dadeb5069aa arch/xtensa: Add CPU load support for Xtensa
e716cf058d2a logging: log_output_custom: drop fatal assert on unset
             callback
39582c1c2fc9 soc: nxp: migrate PM hooks to idle-owned IRQ restore
16d69ce7d082 xtensa: unsupported unsigned load / store emulation
ec8e9a54504b dts: amd: acp_7_x: add devicetree and bindings
cabf34d7dd9b drivers: intc: add AMD ACP 7.X interrupt controller support
b44b52e9c13c soc: amd: acp_7_x: add SoC and board support
4612efcb6ec2 drivers: clock_control: clock update for LPIT instances on
             iMX93 Mcore
45bdb70e1c05 dma: amd: add TDM DMA driver for AMD ACP 7.0
74a32bdff3ca modules: hal_nxp: make MCUX SDK section placement
             configurable
15af50d20252 pm: keep irq restore ownership in idle
0b0b41ce9dad kernel: Initialize timeout.dticks on k_timer_init()
c3f2a6a07ac9 kernel: timeslicing: rearm with slice_size-1 when slicer
             just fired
2ec65238d68a kernel: timeout: make in-announce check CPU-aware
491583951036 kernel: add kobj NULL check in k_thread_name_copy()
3b1bdaf54821 xtensa: mpu: fix arch_buffer_validate() if overflow
fdc42fa256b8 kernel: userspace: fix SMP use-after-free
a13fd968e132 soc: intel: Add support for dts RAM configuration
1d935da70029 kernel: Add support for dts RAM configuration
96d1142210e3 arch: Add support for dts RAM configuration
8509270a0e34 kernel: poll timeout: Fix race condition
1b8c7a3038d9 kernel: thread timeout: Fix race condition
667c3184d6e8 logging: log_output: Fix formatting of function prefix
e1434e141ecf logging: fix immediate clean output locking on SMP
1296dc85e332 kernel: timer: make k_timer_start duration match documented
             semantics
2e2202af616c kernel: timeout: make z_add_timeout round-up conditional on
             announce
d157b3da193d kernel: timeout: keep announce_remaining stable across
             same-tick group
827ce93035bc soc: kernel: use configdefault for CONFIG_SMP
603fa4818e8f drivers: timer: assert sys_clock lock held where required
1dc47344d0a2 kernel: use arch_cpu_irqs_are_enabled() for IRQ-state
             probes
01b3821fd933 kernel: spinlock: provide z_spin_is_locked() for UP builds
c91e5e1390f3 kernel: move atomic_c.c to lib/os
cc6136628341 kernel: move errno from kernel to lib/libc/common
81ccaca788db kernel: ensure kheap.c is linked for static heap
             initialization
39b23fa582d8 kernel: bypass k_heap_free() in k_free() to avoid scheduler
             locking
db7a5e80a47b kernel: move bootargs out of kernel into lib/os.
9fe4cc20a2b5 kernel: move boot banner into lib/os
f7c6f1d92110 soc: intel_adsp: ace30: extend hwreg0 MMU range
814cfb41191a soc: intel_adsp: ace40: extend hwreg0 MMU range
1bc5f0543c4d drivers: counter: introduce counter capture api
e81266be2bfe arch: add arch_cpu_irqs_are_enabled() primitive

Zephyr commit 58e859c5dd37b88 ("boards: nxp: imx95_evk: enable EDMA1 for
M7 core") enables EDMA1 node which in turn enables dma_mcux_edma.c
driver.

dma_mcux_edma.c requires some attention w.r.t cache configuration
options.

SOF doesnt use EDMA1 nodes but inherits edma1 node which selects
DMA_MCUX_EDMA and causes the following compilation errors:

dma_mcux_edma.c:1225:2: error: #error Unexpected or disallowed
cache situation for dma descriptors

So disable edma1 node as we don't use it.

Co-authored-by: Daniel Baluta <daniel.baluta@nxp.com>

Signed-off-by: Tomasz Leman <tomasz.m.leman@intel.com>
Signed-off-by: Daniel Baluta <daniel.baluta@nxp.com>
Reject 0 or > PLATFORM_MAX_CHANNELS before modules index channel-sized arrays.

Signed-off-by: Adrian Bonislawski <adrian.bonislawski@intel.com>
Bound each host-supplied module_param against the bytes remaining
to avoid an OOB read or a stalled loop.

Signed-off-by: Adrian Bonislawski <adrian.bonislawski@intel.com>
lib_manager_get_module_manifest() can return NULL, if it is then
passed to module_is_llext() as an argument, it will lead to an
exception. Check for NULL before calling module_is_llext().

Signed-off-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
Add tplg_check_bounds() macro that validates ctx->tplg_offset + advance
does not exceed ctx->tplg_size before advancing the offset. Apply this
check in all topology object reader macros: tplg_get_hdr,
tplg_skip_hdr_payload, tplg_get_object, tplg_get_object_priv,
tplg_get_widget, tplg_get_graph, and tplg_get_pcm.

Without these checks, a crafted .tplg file with malicious payload_size
or priv.size values can drive the offset past the end of the mapped
topology data, causing out-of-bounds reads in all subsequent object
parsing.

Signed-off-by: Jyri Sarha <jyri.sarha@intel.com>
Add () around all macro argument instances.

Signed-off-by: Jyri Sarha <jyri.sarha@linux.intel.com>
Replace unbounded strcat() calls with snprintf() that tracks remaining
buffer capacity. Add a pipeline_string_size parameter to
tplg_create_graph() so the function knows the buffer limit.

Without this fix, a crafted topology file with many or long graph
element names can overflow the caller's fixed 256-byte pipeline_string
buffer via repeated strcat(), corrupting the host stack.

Signed-off-by: Jyri Sarha <jyri.sarha@intel.com>
…erflow

Add a sanity check in process_sync() to reject packets with
data_size_bytes exceeding 16 MiB before performing the
data_size_bytes + sizeof(uint64_t) addition used for realloc sizing.

Without this check, a crafted probe dump with data_size_bytes near
UINT32_MAX wraps the realloc size to a small value, then the subsequent
data copy writes data_size_bytes into the undersized buffer.

Signed-off-by: Jyri Sarha <jyri.sarha@intel.com>
The gateway configuration length from the init payload was multiplied
and used as a copy length from the mailbox without checking it against
the actual payload size. Reject a configuration that would read past the
init payload.

Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
The multi-gateway count from the gateway config was used to compute
sizes and walk the mapping array before being bounded. Reject a count
above the supported maximum before any arithmetic.

Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
The sink queue id was used directly to index the output format array
when updating parameters, unlike the other call sites which bound it.
Skip a sink whose queue id exceeds the output pin count.

Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
The attenuation setter only rejected oversized payloads, then
dereferenced the data as a 32-bit value; a payload shorter than that
read past the mailbox. Require exactly a 32-bit payload.

Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
The IPC gateway path read a config blob from the gateway data without
checking the declared config length covered it, over-reading the mailbox
tail. Reject a config length too small for the gateway config header and
blob.

Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
The init path read the direction word at a fixed offset past the codec
params without checking the payload was large enough, reading past the
mailbox. Require the payload to cover the field.

Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
The config parse loop read a parameter header before confirming a whole
header remained in the blob, reading past it near the end. Bound the
read by the remaining size.

Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
The reassembly size for fragmented runtime-params transfers was a
file-scope static shared by every component, so interleaved transfers to
different components corrupted each other's state. Move it into
per-instance module state.

Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
dma_request_channel() can return a negative error code. Check for it
before using the returned value as a channel number.

Signed-off-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
The remap routines validated the source channel nibble only with an
assert, which is compiled out in release builds. Fold the bound into the
existing mute path so an out-of-range nibble mutes the output instead of
indexing past the source frame.

Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
The mel-bin loop in mod_psy_get_mel_filterbank() divides by delta_cl and
delta_rc on every FFT bin, and by (right_hz - left_hz) when slaney
normalization is enabled. With unusual configurations these denominators
can become zero or negative — for example when start_freq >= end_freq,
when the requested mel_bins is large enough that integer division
truncates the mel step to zero, or at extreme inputs where psy_mel_to_hz
saturates and right_hz no longer exceeds left_hz.

Reject such configurations explicitly. After computing mel_step, return
-EINVAL if it is not positive, which also covers both delta values
since they equal mel_step. In the slaney_normalize branch, also verify
right_hz > left_hz before computing the scale factor.

Signed-off-by: Seppo Ingalsuo <seppo.ingalsuo@linux.intel.com>
Module instance_max_count should never be 0, assume 1 if such a
module is loaded.

Signed-off-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
@sofci

sofci commented Sep 30, 2026

Copy link
Copy Markdown
Collaborator

Can one of the admins verify this patch?

reply test this please to run this test once

@LongWang100

Copy link
Copy Markdown
Contributor Author

wrong branch

Bring up the Maxim DSM smart amplifier path on ACP7x (Steam Deck /
Gainsborough) with two max98388 amplifiers on a 2-slot TDM2 link.

smart_amp.c:
- Fix source buffer detection on IPC3: bound_module is only assigned by
  module_bind() in module_adapter_ipc4.c and stays NULL on IPC3 platforms,
  so dereferencing it faulted the DSP.  Compare producer pipeline ids
  instead -- works under both IPC versions.
- Add 16-byte alignment for DSP buffers via mod_alloc_align(): without it,
  Xtensa HiFi AE_L32X2/AE_S64 instructions take LoadStoreAlignmentCause.
- Null-guard source_buf after re-prepare to prevent stale pointer reuse.

maxim_dsm_stub.c:
- Fix stub to fill all output fields read by the caller.  The upstream
  stub returned DSM_API_OK without writing omemsizerequestedbytes, so
  get_handle_size() returned 0, the PRIVATE memblk was never allocated,
  dsmhandle stayed NULL and every subsequent DSM call failed with -EINVAL.
  The fixed stub also passes through audio (input -> output) so the glue
  layer and topology can be validated without libdsm.a.

smart_amp_maxim_dsm.c:
- Fix DSM_FF_BUF_DB_SZ: upstream used FF_BUF_SZ * FF_MAX_CH_NUM = 192,
  which is too small for a 2 ms period (192 samples) + pre-fill frame
  (96).  Change to FF_BUF_SZ * 4 = 384 to cover periods up to 3 ms.
- Add ivFormat=3 (DSM_IV_FORMAT_INTERLEAVED_16_BIT_MSB) support for the
  2-slot layout where each max98388 interleaves V and I within one slot
  using the sample MSB as a flag.  The upstream 4*idx de-interleave stride
  reads only one MSB polarity and causes INSUFFICIENT_INPUT_DATA.
- Replace memcpy_s with dsm_buf_shift_down() (memmove-based): SOF's
  memcpy_s detects overlapping src/dst and returns -EINVAL without
  copying, which occurs whenever period > 2 ms and caused silent buffer
  desynchronisation.
- Change if to while in ff_proc and fb_proc: a 2 ms period delivers 2 DSM
  frames; if drained only one per call, causing w_ptr to grow until
  overflow.
- Remove duplicate dsm_api_ff_process() call in the 32-bit else branch:
  libdsm decrements *ipNrSamples in place, making it a no-op today, but
  any code re-arming ifsamples per branch would double-advance the
  adaptive state (excursion/thermal model, RDC, LMS).
- Set ibsamples = fb_fr_sz_samples * nchannels = 96: libdsm divides by
  nChannels internally; passing 48 gives 24 % ffFrameSize != 0 and
  returns INVALID_PARAM on every call.

sof-acp_7_x_i2s.m4:
- Switch TDM2 from pipe-passthrough to pipe-smart-amplifier + pipe-amp-ref-capture.
- Define all required SMART_* macros for 2-channel configuration.
- Add cross-pipeline SectionGraph wiring demux -> smart_amp feedback buffer.
- Define REF_CHMAP = {0x01, 0x02} so the echo reference second channel
  comes from slot 1 (second amp), not the non-existent slot 2.
- Declare SMART_UUID explicitly to make the active build mode visible.

pipe-amp-ref-capture.m4:
- Allow platforms to pre-define REF_CHMAP to override the default 4-slot
  mapping, which routes ch1 to in ch2 (non-existent on 2-slot hardware)
  and permanently silences ch1 via mux.c:215.

app/maxim_dsm_overlay.conf:
- Add Kconfig overlay for the three-step DSM bring-up sequence:
  step 1 PASSTHRU_AMP, step 2 MAXIM_DSM_STUB, step 3 real libdsm.a.

Signed-off-by: Long Wang <long.wang@analog.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.