| From 6a6ca7881b1ab1c13fe0d70bae29211a65dd90de Mon Sep 17 00:00:00 2001 |
| From: Hui Wang <hui.wang@canonical.com> |
| Date: Thu, 25 Jun 2020 16:38:33 +0800 |
| Subject: ALSA: hda - let hs_mic be picked ahead of hp_mic |
| |
| From: Hui Wang <hui.wang@canonical.com> |
| |
| commit 6a6ca7881b1ab1c13fe0d70bae29211a65dd90de upstream. |
| |
| We have a Dell AIO, there is neither internal speaker nor internal |
| mic, only a multi-function audio jack on it. |
| |
| Users reported that after freshly installing the OS and plug |
| a headset to the audio jack, the headset can't output sound. I |
| reproduced this bug, at that moment, the Input Source is as below: |
| Simple mixer control 'Input Source',0 |
| Capabilities: cenum |
| Items: 'Headphone Mic' 'Headset Mic' |
| Item0: 'Headphone Mic' |
| |
| That is because the patch_realtek will set this audio jack as mic_in |
| mode if Input Source's value is hp_mic. |
| |
| If it is not fresh installing, this issue will not happen since the |
| systemd will run alsactl restore -f /var/lib/alsa/asound.state, this |
| will set the 'Input Source' according to history value. |
| |
| If there is internal speaker or internal mic, this issue will not |
| happen since there is valid sink/source in the pulseaudio, the PA will |
| set the 'Input Source' according to active_port. |
| |
| To fix this issue, change the parser function to let the hs_mic be |
| stored ahead of hp_mic. |
| |
| Cc: stable@vger.kernel.org |
| Signed-off-by: Hui Wang <hui.wang@canonical.com> |
| Link: https://lore.kernel.org/r/20200625083833.11264-1-hui.wang@canonical.com |
| Signed-off-by: Takashi Iwai <tiwai@suse.de> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| sound/pci/hda/hda_auto_parser.c | 6 ++++++ |
| 1 file changed, 6 insertions(+) |
| |
| --- a/sound/pci/hda/hda_auto_parser.c |
| +++ b/sound/pci/hda/hda_auto_parser.c |
| @@ -72,6 +72,12 @@ static int compare_input_type(const void |
| if (a->type != b->type) |
| return (int)(a->type - b->type); |
| |
| + /* If has both hs_mic and hp_mic, pick the hs_mic ahead of hp_mic. */ |
| + if (a->is_headset_mic && b->is_headphone_mic) |
| + return -1; /* don't swap */ |
| + else if (a->is_headphone_mic && b->is_headset_mic) |
| + return 1; /* swap */ |
| + |
| /* In case one has boost and the other one has not, |
| pick the one with boost first. */ |
| return (int)(b->has_boost_on_pin - a->has_boost_on_pin); |