From: Takashi Iwai <tiwai@suse.de>
To: Zhang Heng <zhangheng@kylinos.cn>
Cc: perex@perex.cz, tiwai@suse.com, linux-sound@vger.kernel.org,
linux-kernel@vger.kernel.org
Subject: Re: Fwd: [PATCH] ALSA: hda/generic: Add mic autoswitch support for dyn_adc_switch mode
Date: Thu, 07 May 2026 17:05:46 +0200 [thread overview]
Message-ID: <87ecjnp8dx.wl-tiwai@suse.de> (raw)
In-Reply-To: <a7daf8a3-559b-4532-a2ee-a211a7e0e0b0@kylinos.cn>
On Wed, 06 May 2026 09:03:52 +0200,
Zhang Heng wrote:
>
>
>
>
> -------- 转发的消息 --------
> 主题: Re: [PATCH] ALSA: hda/generic: Add mic autoswitch support for
> dyn_adc_switch mode
> 日期: Wed, 6 May 2026 14:19:14 +0800
> 发件人: Zhang Heng <zhangheng@kylinos.cn>
> 收件人: Takashi Iwai <tiwai@suse.de>
>
>
>
>
> 在 2026/5/5 0:25, Takashi Iwai 写道:
> > On Sun, 03 May 2026 13:45:12 +0200,
> > Zhang Heng wrote:
> >> When auto_mic is not available but dyn_adc_switch mode is enabled
> >> (e.g., on laptops with both front and rear mic jacks), this patch
> >> enables automatic microphone switching based on jack detection.
> >>
> >> The patch includes three changes:
> >>
> >> 1. In check_dyn_adc_switch(): Register jack detect callbacks for
> >> all input pins when dyn_adc_switch is enabled and auto_mic is
> >> not available.
> >>
> >> 2. In call_mic_autoswitch(): Add handling for dyn_adc_switch mode
> >> to check imux_pins[] for jack presence, searching from back to
> >> front (last inserted wins).
> >>
> >> 3. In mux_select(): Notify Capture Source controls after switching
> >> to sync with user-space (PulseAudio/PipeWire).
> >>
> >> Problem description:
> >> On Ubuntu 20.04 (with older PulseAudio/PipeWire):
> >> - Front mic is unplugged
> >> - Plug in rear mic
> >> - Jack event is reported correctly
> >> - Volume control (PulseAudio/PipeWire) recognizes the rear mic
> >> - But alsamixer does NOT switch to rear mic
> >> - Codec also does NOT perform the switch
> >>
> >> The root cause is that in dyn_adc_switch mode without auto_mic,
> >> the jack detect callback was not properly set up to trigger the
> >> mic autoswitch. The call_mic_autoswitch() function only calls
> >> mic_autoswitch_hook or snd_hda_gen_mic_autoswitch(), which rely
> >> on auto_mic being enabled.
> >>
> >> Additionally, after mux_select() performs the switch, user-space
> >> (PulseAudio/PipeWire) may not be aware of the path change,
> >> causing Capture Switch to show 'off'.
> >>
> >> This patch fixes both issues by:
> >> 1. Registering jack detect callbacks for all input pins in
> >> dyn_adc_switch mode
> >> 2. Notifying Capture Source controls after switching
> >>
> >> Tested on SN6186 codec with Ubuntu 20.04 and 25.10.
> >>
> >> Question to the community: Is this approach correct? Should additional
> >> changes be made to handle mute state preservation, or is this purely
> >> a user-space issue that requires updating PulseAudio/PipeWire?
> >>
> >> Testing and feedback are welcome.
> > I think the basic idea is OK. We can treat the auto-mic with dynamic
> > ADC switches, too.
> >
> > But it's not clear what's the actual intent in your code changes:
> >
> >
> >> Signed-off-by: Zhang Heng <zhangheng@kylinos.cn>
> >> ---
> >> sound/hda/codecs/generic.c | 82 ++++++++++++++++++++++++++++++++++++--
> >> 1 file changed, 79 insertions(+), 3 deletions(-)
> >>
> >> diff --git a/sound/hda/codecs/generic.c b/sound/hda/codecs/generic.c
> >> index 660a9f2c0ded..c536de10d8b8 100644
> >> --- a/sound/hda/codecs/generic.c
> >> +++ b/sound/hda/codecs/generic.c
> >> @@ -27,6 +27,10 @@
> >> #include "hda_beep.h"
> >> #include "generic.h"
> >> +/* Forward declaration */
> >> +static void call_mic_autoswitch(struct hda_codec *codec,
> >> + struct hda_jack_callback *jack);
> >> +
> >> /**
> >> * snd_hda_gen_spec_init - initialize hda_gen_spec struct
> >> @@ -3238,6 +3242,19 @@ static int check_dyn_adc_switch(struct
> >> hda_codec *codec)
> >> if (!spec->dyn_adc_switch && spec->multi_cap_vol)
> >> spec->num_adc_nids = 1;
> >> + /* Enable mic autoswitch for dyn_adc_switch mode when auto_mic is
> >> not available */
> >> + if (!spec->auto_mic && imux->num_items > 1) {
> >> + int i;
> >> + for (i = 0; i < imux->num_items; i++) {
> >> + hda_nid_t pin = spec->imux_pins[i];
> >> + if (!is_jack_detectable(codec, pin))
> >> + continue;
> >> + snd_hda_jack_detect_enable_callback(codec, pin,
> >> + call_mic_autoswitch);
> >> + }
> >> + codec_dbg(codec, "Enable mic autoswitch for input sources\n");
> >> + }
> > IMO, this should be rather put at auto_mic_check_imux() instead,
> > something like:
> >
> > @@ -4789,13 +4789,15 @@ static bool auto_mic_check_imux(struct
> > hda_codec *codec)
> > const struct hda_input_mux *imux;
> > int i;
> > - imux = &spec->input_mux;
> > - for (i = 0; i < spec->am_num_entries; i++) {
> > - spec->am_entry[i].idx =
> > - find_idx_in_nid_list(spec->am_entry[i].pin,
> > - spec->imux_pins, imux->num_items);
> > - if (spec->am_entry[i].idx < 0)
> > - return false; /* no corresponding imux */
> > + if (!spec->dyn_adc_switch) {
> > + imux = &spec->input_mux;
> > + for (i = 0; i < spec->am_num_entries; i++) {
> > + spec->am_entry[i].idx =
> > + find_idx_in_nid_list(spec->am_entry[i].pin,
> > + spec->imux_pins, imux->num_items);
> > + if (spec->am_entry[i].idx < 0)
> > + return false; /* no corresponding imux */
> > + }
> > }
> > /* we don't need the jack detection for the first pin */
> >
> In fact, auto_ic_check_imux cannot be executed on desktop computers at
> all. You can take a look at the check_outo_ic_availability section
> for (int i = 0; i < cfg->num_inputs; i++) {
> hda_nid_t nid = cfg->inputs[i].pin;
> unsigned int attr;
> attr = snd_hda_codec_get_pincfg(codec, nid);
> attr = snd_hda_get_input_pin_attr(attr);
> if (types & (1 << attr)) For desktop computers, the rear
> mic and line are an attr, which will be directly returned here.
Do you mean that the mic is no built-in mic? If so, the auto-mic
isn't the way to go.
The driver can't judge which one has a higher priority between an mic
jack and a line jack. OTOH, in the case of built-in mic vs mic jack,
it's clear who should win, and the driver provides the auto-mic
feature. So, unless this condition is met, leaving the choice to
user-space is the designed behavior.
thanks,
Takashi
next prev parent reply other threads:[~2026-05-07 15:05 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <5b215802-4c94-4f94-9cee-f8e497b31337@kylinos.cn>
2026-05-06 7:03 ` Fwd: [PATCH] ALSA: hda/generic: Add mic autoswitch support for dyn_adc_switch mode Zhang Heng
2026-05-07 15:05 ` Takashi Iwai [this message]
2026-05-08 2:21 ` Zhang Heng
2026-05-08 2:50 ` Zhang Heng
2026-05-15 9:24 ` Takashi Iwai
2026-05-15 11:19 ` Jaroslav Kysela
2026-05-15 11:29 ` Takashi Iwai
2026-05-18 7:03 ` Zhang Heng
2026-05-18 7:07 ` Zhang Heng
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87ecjnp8dx.wl-tiwai@suse.de \
--to=tiwai@suse.de \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-sound@vger.kernel.org \
--cc=perex@perex.cz \
--cc=tiwai@suse.com \
--cc=zhangheng@kylinos.cn \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.