Re: Fwd: [PATCH] ALSA: hda/generic: Add mic autoswitch support for dyn_adc_switch mode
From: Zhang Heng
Date: Thu May 07 2026 - 22:23:03 EST
My idea is to dynamically switch ADC connections to different input pins.
For desktop designs, sometimes there is only one ADC or no ADC that can
connect to all input pins. For example, my SN6186:
Node 0x13 [Audio Input] wcaps 0x10051b: Stereo Amp-In
Control: name="Capture Volume", index=0, device=0
ControlAmp: chs=3, dir=In, idx=1, ofs=0
Control: name="Capture Switch", index=0, device=0
ControlAmp: chs=3, dir=In, idx=1, ofs=0
Device: name="SN6186 Analog", type="Audio", device=0
Amp-In caps: ofs=0x4a, nsteps=0x50, stepsize=0x03, mute=1
Amp-In vals: [0x80 0x80] [0x50 0x50] [0x50 0x50] [0x80 0x80] [0x80 0x80]
Converter: stream=1, channel=0
SDI-Select: 0
PCM:
rates [0x540]: 48000 96000 192000
bits [0xe]: 16 20 24
formats [0x1]: PCM
Power states: D0 D1 D2 D3 EPSS
Power: setting=D0, actual=D0
Connection: 5
0x18 0x24 0x19* 0x25 0x1f
Node 0x14 [Audio Input] wcaps 0x10051b: Stereo Amp-In
Amp-In caps: ofs=0x4a, nsteps=0x50, stepsize=0x03, mute=1
Amp-In vals: [0x80 0x80] [0x50 0x50] [0x80 0x80] [0x80 0x80] [0x80 0x80]
Converter: stream=0, channel=0
SDI-Select: 0
PCM:
rates [0x540]: 48000 96000 192000
bits [0xe]: 16 20 24
formats [0x1]: PCM
Power states: D0 D1 D2 D3 EPSS
Power: setting=D0, actual=D0
Connection: 5
0x18* 0x1a 0x24 0x25 0x1f
On this machine, 0x1a is LINE IN, 0x19 is Mic, 0x24 is Rear Mic.
Therefore, a "Capture Source" control is generated.
After deleting the current user config and rebooting (rm -rf ~/.config/pulse/*
~/.config/audio.json, Ubuntu 20.04 does not need to delete user config
to reproduce this issue), this situation occurs: even after inserting
the rear mic or LINE, neither alsamixer nor the codec switches to the
corresponding input path.
Node 0x19 [Pin Complex] wcaps 0x40048b: Stereo Amp-In
Amp-In caps: ofs=0x00, nsteps=0x07, stepsize=0x17, mute=1
Amp-In vals: [0x06 0x06]
Pincap 0x00003324: IN Detect
Vref caps: HIZ 50 80 100
Pin Default 0x02a1104e: [Jack] Mic at Ext Front
Conn = 1/8, Color = Black
DefAssociation = 0x4, Sequence = 0xe
Pin-ctls: 0x25: IN VREF_100
Unsolicited: tag=03, enabled=1
Power states: D0 D1 D2 D3 EPSS
Power: setting=D0, actual=D0
Node 0x24 [Pin Complex] wcaps 0x40058b: Stereo Amp-In
Amp-In caps: ofs=0x00, nsteps=0x07, stepsize=0x17, mute=1
Amp-In vals: [0x80 0x80]
Pincap 0x00013334: IN OUT EAPD Detect
Vref caps: HIZ 50 80 100
EAPD 0x0:
Pin Default 0x01a19040: [Jack] Mic at Ext Rear
Conn = 1/8, Color = Pink
DefAssociation = 0x4, Sequence = 0x0
Pin-ctls: 0x24: IN VREF_80
Unsolicited: tag=04, enabled=1
Power states: D0 D1 D2 D3 EPSS
Power: setting=D0, actual=D0
Connection: 3
0x10* 0x11 0x23
The information below will always be preserved. Even after inserting
the rear mic and rechecking the codec info, it remains the same.
This is related to upper-layer design, but I have no research in this
area, so I am very confused. My opinion is that the kernel should at
least support dynamic switching of ADC and paths. If user-space handles
this, could you please let me know which component?
In create_capture_mixers:
- if (spec->dyn_adc_switch)
- nums = 1;
- else
nums = spec->num_adc_nids;
After this, dynamic switching works. Although the generated control is
forced to "Input Source", at least it is usable. So the next step is
to look at this part of the code.
I have another desktop with SN6186 that has only one ADC capable of
connecting to all input pins, which results in nums=1, so the generated
control is still "Capture Source"...
Due to my lack of understanding of the upper layer, I really do not
know whether this should be handled by the kernel or user-space. But
I will first examine the kernel's handling of this with a critical eye.