ALSA: hda/ca0132: Disable auto-detect on manual output select
Commitmaster778031e165("ALSA: hda/ca0132: Set HP/Speaker auto-detect default from headphone pin verb") enables HP/Speaker auto-detect by default when the headphone pin supports presence detect. With auto-detect enabled, ca0132_select_out() and ca0132_alt_select_out() choose the output from jack presence instead of the manual HP/Speaker selection. This means selecting speaker output while headphones are plugged in updates the control state, but audio still routes to the headphones. Treat an explicit manual output selection as a request to leave auto-detect mode. Clear the HP/Speaker auto-detect switch before applying the manual selection, and notify userspace so the auto-detect control state is updated in mixers. Do this for both the normal HP/Speaker Playback Switch and the alternate Output Select control used by desktop cards. This keeps auto-detect enabled by default for devices with jack presence detection, while preserving the expected behavior that a manual output choice takes effect immediately. Fixes:778031e165("ALSA: hda/ca0132: Set HP/Speaker auto-detect default from headphone pin verb") Signed-off-by: Matt DeVillier <matt.devillier@gmail.com> Link: https://lore.kernel.org/CAFTm+6AfeXKf=b2frG4xC5yC4jjM9TkD6c8+dOWWFw6BDjDESw@mail.gmail.com Signed-off-by: Takashi Iwai <tiwai@suse.de>
parent
7d1051ad68
commit
6fd9f6e870
|
|
@ -5498,6 +5498,30 @@ static int zxr_headphone_gain_set(struct hda_codec *codec, long val)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Manual output selection (HP/Speaker Playback Switch or alt Output Select)
|
||||
* is meaningful only when HP/Speaker auto-detect is disabled, since the
|
||||
* select_out path always prefers jack presence when auto-detect is on. When
|
||||
* the user explicitly chooses an output, turn auto-detect off so the manual
|
||||
* choice actually takes effect, and notify userspace so the auto-detect
|
||||
* control reflects the new state.
|
||||
*/
|
||||
static void ca0132_disable_hp_auto_detect(struct hda_codec *codec)
|
||||
{
|
||||
struct ca0132_spec *spec = codec->spec;
|
||||
struct snd_kcontrol *kctl;
|
||||
|
||||
if (!spec->vnode_lswitch[VNID_HP_ASEL - VNODE_START_NID])
|
||||
return;
|
||||
|
||||
spec->vnode_lswitch[VNID_HP_ASEL - VNODE_START_NID] = 0;
|
||||
kctl = snd_hda_find_mixer_ctl(codec,
|
||||
"HP/Speaker Auto Detect Playback Switch");
|
||||
if (kctl)
|
||||
snd_ctl_notify(codec->card, SNDRV_CTL_EVENT_MASK_VALUE,
|
||||
&kctl->id);
|
||||
}
|
||||
|
||||
static int ca0132_vnode_switch_set(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
|
|
@ -5510,14 +5534,11 @@ static int ca0132_vnode_switch_set(struct snd_kcontrol *kcontrol,
|
|||
int auto_jack;
|
||||
|
||||
if (nid == VNID_HP_SEL) {
|
||||
auto_jack =
|
||||
spec->vnode_lswitch[VNID_HP_ASEL - VNODE_START_NID];
|
||||
if (!auto_jack) {
|
||||
if (ca0132_use_alt_functions(spec))
|
||||
ca0132_alt_select_out(codec);
|
||||
else
|
||||
ca0132_select_out(codec);
|
||||
}
|
||||
ca0132_disable_hp_auto_detect(codec);
|
||||
if (ca0132_use_alt_functions(spec))
|
||||
ca0132_alt_select_out(codec);
|
||||
else
|
||||
ca0132_select_out(codec);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
@ -5978,7 +5999,6 @@ static int ca0132_alt_output_select_put(struct snd_kcontrol *kcontrol,
|
|||
struct ca0132_spec *spec = codec->spec;
|
||||
int sel = ucontrol->value.enumerated.item[0];
|
||||
unsigned int items = NUM_OF_OUTPUTS;
|
||||
unsigned int auto_jack;
|
||||
|
||||
if (sel >= items)
|
||||
return 0;
|
||||
|
|
@ -5988,10 +6008,8 @@ static int ca0132_alt_output_select_put(struct snd_kcontrol *kcontrol,
|
|||
|
||||
spec->out_enum_val = sel;
|
||||
|
||||
auto_jack = spec->vnode_lswitch[VNID_HP_ASEL - VNODE_START_NID];
|
||||
|
||||
if (!auto_jack)
|
||||
ca0132_alt_select_out(codec);
|
||||
ca0132_disable_hp_auto_detect(codec);
|
||||
ca0132_alt_select_out(codec);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue