From 8ba955cef30921417dffba901a8af5a2662a1dec Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 7 Mar 2013 18:40:58 +0100 Subject: [PATCH] ALSA: hda - Avoid automatic pin-ctl update for hp/mic when jack ctl exists When the headphone mic jack enum control is created (via explicitly specification by user), it doesn't make much sense to change the I/O direction dynamically per capture source change, since the I/O direction is rather controlled over the enum ctl. This also reduces the implicit dependency between the capture source and the hp mic jack enum ctls, which might confuse a program accessing the whole control elements at once like alsactl. In addition, this patch introduces update_hp_automute_hook() function to call the proper hook function. It's just to remove the open codes in multiple places in hda_generic.c. Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_generic.c | 45 ++++++++++++++++++++----------------- sound/pci/hda/hda_generic.h | 1 + 2 files changed, 25 insertions(+), 21 deletions(-) diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c index c8791225b2ba..fb232c118e91 100644 --- a/sound/pci/hda/hda_generic.c +++ b/sound/pci/hda/hda_generic.c @@ -1890,6 +1890,17 @@ static int create_speaker_out_ctls(struct hda_codec *codec) * independent HP controls */ +/* update HP auto-mute state too */ +static void update_hp_automute_hook(struct hda_codec *codec) +{ + struct hda_gen_spec *spec = codec->spec; + + if (spec->hp_automute_hook) + spec->hp_automute_hook(codec, NULL); + else + snd_hda_gen_hp_automute(codec, NULL); +} + static int indep_hp_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { @@ -1950,12 +1961,7 @@ static int indep_hp_put(struct snd_kcontrol *kcontrol, else *dacp = spec->alt_dac_nid; - /* update HP auto-mute state too */ - if (spec->hp_automute_hook) - spec->hp_automute_hook(codec, NULL); - else - snd_hda_gen_hp_automute(codec, NULL); - + update_hp_automute_hook(codec); ret = 1; } unlock: @@ -2237,17 +2243,14 @@ static void update_hp_mic(struct hda_codec *codec, int adc_mux, bool force) PIN_IN | (as_mic ? vref_val : 0)); } - if (as_mic) - val |= PIN_IN; - else - val = PIN_HP; - set_pin_target(codec, pin, val, true); - - /* update HP auto-mute state too */ - if (spec->hp_automute_hook) - spec->hp_automute_hook(codec, NULL); - else - snd_hda_gen_hp_automute(codec, NULL); + if (!spec->hp_mic_jack_modes) { + if (as_mic) + val |= PIN_IN; + else + val = PIN_HP; + set_pin_target(codec, pin, val, true); + update_hp_automute_hook(codec); + } } /* create a shared input with the headphone out */ @@ -2654,6 +2657,8 @@ static int hp_mic_jack_mode_put(struct snd_kcontrol *kcontrol, val = snd_hda_get_default_vref(codec, nid); } snd_hda_set_pin_ctl_cache(codec, nid, val); + update_hp_automute_hook(codec); + return 1; } @@ -2677,6 +2682,7 @@ static int create_hp_mic_jack_mode(struct hda_codec *codec, hda_nid_t pin) if (!knew) return -ENOMEM; knew->private_value = pin; + spec->hp_mic_jack_modes = 1; return 0; } @@ -3800,10 +3806,7 @@ static void update_automute_all(struct hda_codec *codec) { struct hda_gen_spec *spec = codec->spec; - if (spec->hp_automute_hook) - spec->hp_automute_hook(codec, NULL); - else - snd_hda_gen_hp_automute(codec, NULL); + update_hp_automute_hook(codec); if (spec->line_automute_hook) spec->line_automute_hook(codec, NULL); else diff --git a/sound/pci/hda/hda_generic.h b/sound/pci/hda/hda_generic.h index 984bf301ebbb..094e6af7a107 100644 --- a/sound/pci/hda/hda_generic.h +++ b/sound/pci/hda/hda_generic.h @@ -221,6 +221,7 @@ struct hda_gen_spec { unsigned int dyn_adc_switch:1; /* switch ADCs (for ALC275) */ unsigned int indep_hp_enabled:1; /* independent HP enabled */ unsigned int have_aamix_ctl:1; + unsigned int hp_mic_jack_modes:1; /* loopback mixing mode */ bool aamix_mode;