Skip to content

ASUS M5650GA Digital Microphone Fix — Complete Issue Report #5833

Description

@zz6zz666

Device: ASUS Vivobook S16 M5650GA
DMI: ASUSTeK COMPUTER INC. / M5650GA / Vivobook S16 M5650GA
BIOS: M5650GA.315 (2026-05-20)
Audio DSP: AMD ACP70 [1022:15e2] rev 0x70, subsystem [1043:17b4]
HDA Codec: Realtek ALC233/ALC235 [10ec:0235], subsystem [1043:17b4]
DMIC: MEMS dual-mic array, physically wired to Realtek ALC235 HDA DMIC pins


Problem 1: ACP70 raw PDM DMA incorrectly bound — 0x80000000 saturation

Root Cause

The ACPI table (SSDT6) sets acp-audio-config-flag = 0x10 (FLAG_AMD_LEGACY_ONLY_DMIC).
This causes acp_pci_probe()acp_machine_select() in acp-legacy-common.c to create
an acp-pdm-mach platform device, which loads snd_acp_legacy_mach. That driver initializes
the ACP70 raw PDM DMA engine (ps-pdm-dma.c), driving the PDM clock via ACP_WOV_CLK_CTRL
and reading from the PDM data pins.

The PDM data pins are NOT connected to any microphone on this board.

The DMIC MEMS chips are wired to the Realtek ALC235 HDA codec's internal DMIC interface
(node 0x12, Pin Default 0x90a60130, Conn=Digital). Windows confirms this: no
ACP\DEVTYPE_0002 (PDM endpoint) exists in Windows Device Manager; all microphone
endpoints parent to HDAUDIO\FUNC_01&VEN_10EC&DEV_0235&SUBSYS_104317B4.

Result: The raw PDM DMA reads from floating I/O pins, producing a constant 0x80000000
(S32_LE saturation pattern) across the entire capture stream. Additionally, the PDM
DMA's clock control interferes with the HDA DMIC path on the ALC233, causing the HDA
DMIC to also malfunction when both paths are active simultaneously.

Fix

Skip acp-pdm-mach creation for this board, while keeping snd_acp_pdm loaded (it
provides the PDM clock from ACP70 GPIO to the Realtek codec's DMIC clock input).

File: sound/soc/amd/acp/acp-legacy-common.c

Change 1 — Add include

 #include "amd.h"
 #include <linux/acpi.h>
+#include <linux/dmi.h>
 #include <linux/pci.h>
 #include <linux/export.h>

Change 2 — Add DMI skip table

Insert before int acp_machine_select(struct acp_chip_info *chip):

static const struct dmi_system_id acp_pdm_skip_table[] = {
	{
		.matches = {
			DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK COMPUTER INC."),
			DMI_MATCH(DMI_PRODUCT_NAME, "M5650GA"),
		},
	},
	{}
};

Change 3 — Check table before creating acp-pdm-mach

Inside acp_machine_select(), modify:

	// BEFORE:
	if (chip->flag == FLAG_AMD_LEGACY_ONLY_DMIC && chip->is_pdm_dev) {
		platform = chip->acp_rev;
		chip->mach_dev = platform_device_register_data(...);

	// AFTER:
	if (chip->flag == FLAG_AMD_LEGACY_ONLY_DMIC && chip->is_pdm_dev) {
		if (dmi_check_system(acp_pdm_skip_table))
			return 0;
		platform = chip->acp_rev;
		chip->mach_dev = platform_device_register_data(...);

Expected behavior after fix

  • acp-pdm-mach platform device NOT created
  • snd_acp_legacy_mach NOT loaded
  • snd_acp_pdm STILL LOADED (dep of snd_acp70, provides PDM clock)
  • Sound card acppdmmach disappears
  • HDA DMIC (card 1, node 0x12) becomes the sole microphone source

Also affected (same root cause)

Module to recompile

sound/soc/amd/acp/acp-legacy-common.csnd-acp-legacy-common

Compile: make -C /lib/modules/$(uname -r)/build M=$PWD/sound/soc/amd/acp acp-legacy-common.ko


Problem 2: Internal Mic Boost breaks DMIC at any gain above 0dB

Root Cause

The Realtek ALC233/ALC235 HDA codec exposes an "Internal Mic Boost" ALSA control
(node 0x12 Amp-In, 0–3 steps, ~10dB/step). WirePlumber binds the GNOME microphone
volume slider directly to this hardware control.

Raising the slider above ~10dB hardware boost causes the DMIC to fail catastrophically:

  • 0dB (Step 0): Clean audio, quiet
  • 10dB (Step 1): Clean audio, usable
  • 20dB (Step 2): Heavy clipping (694 rail hits in 5s recording)
  • 30dB (Step 3): Audio STUTTERS/BREAKS UP (not normal clipping; the DMIC
    interface appears to FAIL at this level, producing corrupted PCM packets)

This is NOT normal analog clipping behavior. It suggests the PDM clock frequency
from ACP70 (hardcoded mask 0x7 in ps-pdm-dma.c) does not match what the ALC233
DMIC expects, and at higher internal gain the clock/data timing margins collapse.

Windows confirmation: Windows uses NO hardware boost for the DMIC. The Realtek
driver INF contains zero MicBoost/MicGain settings for SUBSYS_104317B4. The
DefaultDefaultMicGain = 8900 is a software APO reference value, not a hardware
boost. Windows applies all DMIC gain via software APO (REALTEKREC_VOLMFX).
The hardware is always at 0dB.

Fix

Add a fixup in the Realtek HDA codec driver (alc269.c) for SUBSYS_104317B4
that disables the Internal Mic Boost entirely (0 steps = only 0dB, control removed).

File: sound/hda/codecs/realtek/alc269.c

Change 1 — Add fixup enum value

In the enum list, before the closing };:

	ALC236_FIXUP_HP_DMIC,
+	ALC269_FIXUP_M5650GA_DMIC_BOOST,
};

Change 2 — Add fixup function

Insert after alc269_fixup_limit_int_mic_boost():

static void alc269_fixup_disable_int_mic_boost(struct hda_codec *codec,
					       const struct hda_fixup *fix,
					       int action)
{
	struct alc_spec *spec = codec->spec;
	struct auto_pin_cfg *cfg = &spec->gen.autocfg;
	int i;

	/* The DMIC on M5650GA (SUBSYS_104317B4) breaks at any
	   hardware boost above 0dB. Lock to 0dB (0 steps). */

	if (action != HDA_FIXUP_ACT_PROBE)
		return;

	for (i = 0; i < cfg->num_inputs; i++) {
		hda_nid_t nid = cfg->inputs[i].pin;
		unsigned int defcfg;
		if (cfg->inputs[i].type != AUTO_PIN_MIC)
			continue;
		defcfg = snd_hda_codec_get_pincfg(codec, nid);
		if (snd_hda_get_input_pin_attr(defcfg) != INPUT_PIN_ATTR_INT)
			continue;

		snd_hda_override_amp_caps(codec, nid, HDA_INPUT,
					  (0x00 << AC_AMPCAP_OFFSET_SHIFT) |
					  (0x00 << AC_AMPCAP_NUM_STEPS_SHIFT) |
					  (0x00 << AC_AMPCAP_STEP_SIZE_SHIFT) |
					  (0 << AC_AMPCAP_MUTE_SHIFT));
	}
}

Change 3 — Add fixup table entry

In alc269_fixups[], add before closing };:

	[ALC269_FIXUP_M5650GA_DMIC_BOOST] = {
		.type = HDA_FIXUP_FUNC,
		.v.func = alc269_fixup_disable_int_mic_boost,
	},
};

Change 4 — Add subsystem match

In alc269_fixup_tbl[], add before the sentinel {}:

	SND_PCI_QUIRK(0x1043, 0x17b4, "ASUS M5650GA", ALC269_FIXUP_M5650GA_DMIC_BOOST),
	{}

Expected behavior after fix

  • "Internal Mic Boost" ALSA control disappears from card 1
  • WirePlumber automatically falls back to PipeWire software volume
  • GNOME slider at 100% = pure software unity gain (no hardware gain risk)
  • DMIC never breaks at any slider position

Module to recompile

sound/hda/codecs/realtek/alc269.csnd-hda-codec-alc269

Compile:

make -C /lib/modules/$(uname -r)/build \
    M=$PWD/sound/hda/codecs/realtek \
    snd-hda-codec-alc269.ko

Software gain workaround (userspace)

After both kernel fixes, the DMIC works correctly through the HDA path with 0dB hardware
gain. However, the raw signal is quiet (~-40 to -50dBFS at normal speaking volume) because
the MEMS microphone output is low-level and there is no analog preamp.

On Windows, this is compensated by software APO gain (Voice Clarity / AGC).

On Linux, add a permanent PipeWire software gain:

# Find the microphone node
NID=$(pw-cli list-objects | grep -B1 'Audio/Source' | head -1 | awk '{print $2}' | tr -d ',')

# Set +10dB permanent software gain (adjust 3.162 to preference)
# +6dB=2.0, +10dB=3.162, +12dB=4.0, +15dB=5.623, +18dB=7.943
pw-cli set-param $NID Props '{ softVolumes: [ 3.162, 3.162 ] }'

For noise reduction and AGC (optional): use EasyEffects with rnnoise + compressor.


How to apply on any Linux distribution

  1. Locate the kernel source for your running kernel
  2. Apply both source changes above to the corresponding files
  3. Recompile just the two affected modules:
    make -C /lib/modules/$(uname -r)/build M=<path> acp-legacy-common.ko
    make -C /lib/modules/$(uname -r)/build M=<path> snd-hda-codec-alc269.ko
    
  4. Replace the modules:
    cp acp-legacy-common.ko /lib/modules/$(uname -r)/kernel/sound/soc/amd/acp/
    cp snd-hda-codec-alc269.ko* /lib/modules/$(uname -r)/kernel/sound/hda/codecs/realtek/
    depmod -a
    update-initramfs -u    # (or dracut -f, mkinitcpio, etc.)
    
  5. Reboot

Note: If Secure Boot is enabled, the modules must be signed or Secure Boot disabled.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions