amd/acp7x: smart_amp: enable Maxim DSM for 2x max98388 on TDM2 - #11249
Closed
LongWang100 wants to merge 309 commits into
Closed
LongWang100 wants to merge 309 commits into
LongWang100 wants to merge 309 commits into
Conversation
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>
LongWang100
requested review from
a team,
LaurentiuM1234,
abonislawski,
bardliao,
bhiregoudar,
dabekjakub,
fkwasowi,
iganakov,
iuliana-prodan,
jsarha,
kuanhsuncheng,
kv2019i,
lbetlej,
lgirdwood,
lyakh,
marcinszkudlinski,
mmaka1,
pblaszko,
plbossart,
ranj063,
singalsu,
sunilkumardommati,
tlissows,
tmleman and
yaochunhung
as code owners
September 30, 2026 03:16
Collaborator
|
Can one of the admins verify this patch?
|
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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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.cbound_moduleis only populated bymodule_bind()inmodule_adapter_ipc4.cand is NULL on IPC3platforms; dereferencing it caused a DSP fault. Switch to comparing
producer pipeline IDs, which works under both IPC versions.
mod_alloc_align()to satisfy Xtensa HiFi
AE_L32X2/AE_S64alignment requirements;without this the DSP raises
LoadStoreAlignmentCause.source_bufafter re-prepare to prevent stale pointerreuse.
maxim_dsm_stub.cDSM_API_OKwithout writing
omemsizerequestedbytes, soget_handle_size()returned0, the PRIVATE memblk was never allocated,
dsmhandlestayed NULL, andevery subsequent DSM call failed with
-EINVAL.layer and topology can be validated without
libdsm.a.smart_amp_maxim_dsm.cDSM_FF_BUF_DB_SZ: upstream usedFF_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.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.memcpy_swithdsm_buf_shift_down()(memmove-based):SOF's
memcpy_srejects overlapping src/dst with-EINVAL, whichoccurs whenever period > 2 ms and caused silent buffer desynchronisation.
iftowhileinff_proc/fb_proc: a 2 ms perioddelivers 2 DSM frames; the previous
ifdrained only one per call,causing
w_ptrto grow until overflow.dsm_api_ff_process()call in the 32-bit elsebranch: libdsm decrements
*ipNrSamplesin-place; a second call woulddouble-advance the adaptive state (excursion/thermal model, RDC, LMS).
ibsamples = fb_fr_sz_samples * nchannels= 96: libdsm dividesby
nChannelsinternally; passing 48 gave24 % ffFrameSize != 0andreturned
INVALID_PARAMon every call.sof-acp_7_x_i2s.m4amp-ref-capture.
SMART_*macros for 2-channel configuration.REF_CHMAP = {0x01, 0x02}so the echo reference second channelcomes from slot 1 (second amp), not the non-existent slot 2.
SMART_UUIDexplicitly to make the active build mode visible.pipe-amp-ref-capture.m4REF_CHMAPto override the default4-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.confPASSTHRU_AMP— verify audio path without DSMMAXIM_DSM_STUB— validate glue layer and topologylibdsm.a— full DSM protectionTest plan
DSM_API_OKreturned,dsmhandlenon-NULL, audio passes throughcorrect on both channels, no
INSUFFICIENT_INPUT_DATA/INVALID_PARAM🤖 Generated with Claude Code