Skip to content

Commit

Permalink
ALSA: hda - Support multiple headphone auto-mute
Browse files Browse the repository at this point in the history
Currently headphone auto-mute using alc_automute_pin() assumes only
the single pin used for the headphone output.  Since there are devices
with multiple headphone jacks, we need to check all these pins there,
too.

Also this patch merges the common code between alc_automute_pin() and
alc_automute_amp() helper functions.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
  • Loading branch information
Takashi Iwai committed Sep 8, 2010
1 parent 03642c9 commit bb35feb
Showing 1 changed file with 50 additions and 42 deletions.
92 changes: 50 additions & 42 deletions sound/pci/hda/patch_realtek.c
Original file line number Diff line number Diff line change
Expand Up @@ -990,25 +990,46 @@ static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
alc_fix_pll(codec);
}

static void alc_automute_pin(struct hda_codec *codec)
static void alc_automute_speaker(struct hda_codec *codec, int pinctl)
{
struct alc_spec *spec = codec->spec;
unsigned int nid = spec->autocfg.hp_pins[0];
unsigned int mute;
hda_nid_t nid;
int i;

if (!nid)
return;
spec->jack_present = snd_hda_jack_detect(codec, nid);
spec->jack_present = 0;
for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) {
nid = spec->autocfg.hp_pins[i];
if (!nid)
break;
if (snd_hda_jack_detect(codec, nid)) {
spec->jack_present = 1;
break;
}
}

mute = spec->jack_present ? HDA_AMP_MUTE : 0;
/* Toggle internal speakers muting */
for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
nid = spec->autocfg.speaker_pins[i];
if (!nid)
break;
snd_hda_codec_write(codec, nid, 0,
if (pinctl) {
snd_hda_codec_write(codec, nid, 0,
AC_VERB_SET_PIN_WIDGET_CONTROL,
spec->jack_present ? 0 : PIN_OUT);
} else {
snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
HDA_AMP_MUTE, mute);
}
}
}

static void alc_automute_pin(struct hda_codec *codec)
{
alc_automute_speaker(codec, 1);
}

static int get_connection_index(struct hda_codec *codec, hda_nid_t mux,
hda_nid_t nid)
{
Expand Down Expand Up @@ -1236,24 +1257,35 @@ static void alc_auto_init_amp(struct hda_codec *codec, int type)
static void alc_init_auto_hp(struct hda_codec *codec)
{
struct alc_spec *spec = codec->spec;
struct auto_pin_cfg *cfg = &spec->autocfg;
int i;

if (!spec->autocfg.hp_pins[0])
return;
if (!cfg->hp_pins[0]) {
if (cfg->line_out_type != AUTO_PIN_HP_OUT)
return;
}

if (!spec->autocfg.speaker_pins[0]) {
if (spec->autocfg.line_out_pins[0] &&
spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT)
spec->autocfg.speaker_pins[0] =
spec->autocfg.line_out_pins[0];
else
if (!cfg->speaker_pins[0]) {
if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT)
return;
memcpy(cfg->speaker_pins, cfg->line_out_pins,
sizeof(cfg->speaker_pins));
cfg->speaker_outs = cfg->line_outs;
}

if (!cfg->hp_pins[0]) {
memcpy(cfg->hp_pins, cfg->line_out_pins,
sizeof(cfg->hp_pins));
cfg->hp_outs = cfg->line_outs;
}

snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n",
spec->autocfg.hp_pins[0]);
snd_hda_codec_write_cache(codec, spec->autocfg.hp_pins[0], 0,
for (i = 0; i < cfg->hp_outs; i++) {
snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n",
cfg->hp_pins[i]);
snd_hda_codec_write_cache(codec, cfg->hp_pins[i], 0,
AC_VERB_SET_UNSOLICITED_ENABLE,
AC_USRSP_EN | ALC880_HP_EVENT);
}
spec->unsol_event = alc_sku_unsol_event;
}

Expand Down Expand Up @@ -1711,31 +1743,7 @@ static struct hda_verb alc888_fujitsu_xa3530_verbs[] = {

static void alc_automute_amp(struct hda_codec *codec)
{
struct alc_spec *spec = codec->spec;
unsigned int mute;
hda_nid_t nid;
int i;

spec->jack_present = 0;
for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) {
nid = spec->autocfg.hp_pins[i];
if (!nid)
break;
if (snd_hda_jack_detect(codec, nid)) {
spec->jack_present = 1;
break;
}
}

mute = spec->jack_present ? HDA_AMP_MUTE : 0;
/* Toggle internal speakers muting */
for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
nid = spec->autocfg.speaker_pins[i];
if (!nid)
break;
snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
HDA_AMP_MUTE, mute);
}
alc_automute_speaker(codec, 0);
}

static void alc_automute_amp_unsol_event(struct hda_codec *codec,
Expand Down

0 comments on commit bb35feb

Please sign in to comment.