Commit a9fd4f3f authored by Takashi Iwai's avatar Takashi Iwai

ALSA: hda - Clean up Realtek auto-mute unsol routines

Most of unsol handlers defined in patch_realtek.c can be classified to
two types, mute via amp of pins and mute via ctl bits of pins.
Thus there are a big room to generalize each implementation.

This patch creates two generic functions, alc_automute_amp() and
alc_automute_pin().  The latter is actually changed from the previous
alc_sku_automute().  Each caller needs to initialize hp_pins and
speaker_pins properly at own init_hook.
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent b72519b5
...@@ -926,20 +926,26 @@ static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid, ...@@ -926,20 +926,26 @@ static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
alc_fix_pll(codec); alc_fix_pll(codec);
} }
static void alc_sku_automute(struct hda_codec *codec) static void alc_automute_pin(struct hda_codec *codec)
{ {
struct alc_spec *spec = codec->spec; struct alc_spec *spec = codec->spec;
unsigned int present; unsigned int present;
unsigned int hp_nid = spec->autocfg.hp_pins[0]; unsigned int nid = spec->autocfg.hp_pins[0];
unsigned int sp_nid = spec->autocfg.speaker_pins[0]; int i;
/* need to execute and sync at first */ /* need to execute and sync at first */
snd_hda_codec_read(codec, hp_nid, 0, AC_VERB_SET_PIN_SENSE, 0); snd_hda_codec_read(codec, nid, 0, AC_VERB_SET_PIN_SENSE, 0);
present = snd_hda_codec_read(codec, hp_nid, 0, present = snd_hda_codec_read(codec, nid, 0,
AC_VERB_GET_PIN_SENSE, 0); AC_VERB_GET_PIN_SENSE, 0);
spec->jack_present = (present & 0x80000000) != 0; spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
snd_hda_codec_write(codec, sp_nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 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,
AC_VERB_SET_PIN_WIDGET_CONTROL,
spec->jack_present ? 0 : PIN_OUT); spec->jack_present ? 0 : PIN_OUT);
}
} }
#if 0 /* it's broken in some acses -- temporarily disabled */ #if 0 /* it's broken in some acses -- temporarily disabled */
...@@ -974,16 +980,19 @@ static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res) ...@@ -974,16 +980,19 @@ static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
res >>= 28; res >>= 28;
else else
res >>= 26; res >>= 26;
if (res == ALC880_HP_EVENT) switch (res) {
alc_sku_automute(codec); case ALC880_HP_EVENT:
alc_automute_pin(codec);
if (res == ALC880_MIC_EVENT) break;
case ALC880_MIC_EVENT:
alc_mic_automute(codec); alc_mic_automute(codec);
break;
}
} }
static void alc_inithook(struct hda_codec *codec) static void alc_inithook(struct hda_codec *codec)
{ {
alc_sku_automute(codec); alc_automute_pin(codec);
alc_mic_automute(codec); alc_mic_automute(codec);
} }
...@@ -1364,32 +1373,58 @@ static struct hda_verb alc888_fujitsu_xa3530_verbs[] = { ...@@ -1364,32 +1373,58 @@ static struct hda_verb alc888_fujitsu_xa3530_verbs[] = {
{} {}
}; };
static void alc888_fujitsu_xa3530_automute(struct hda_codec *codec) static void alc_automute_amp(struct hda_codec *codec)
{ {
unsigned int present; struct alc_spec *spec = codec->spec;
unsigned int bits; unsigned int val, mute;
/* Line out presence */ hda_nid_t nid;
present = snd_hda_codec_read(codec, 0x17, 0, int i;
AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
/* HP out presence */ spec->jack_present = 0;
present = present || snd_hda_codec_read(codec, 0x1b, 0, for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) {
AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; nid = spec->autocfg.hp_pins[i];
bits = present ? HDA_AMP_MUTE : 0; if (!nid)
break;
val = snd_hda_codec_read(codec, nid, 0,
AC_VERB_GET_PIN_SENSE, 0);
if (val & AC_PINSENSE_PRESENCE) {
spec->jack_present = 1;
break;
}
}
mute = spec->jack_present ? HDA_AMP_MUTE : 0;
/* Toggle internal speakers muting */ /* Toggle internal speakers muting */
snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
HDA_AMP_MUTE, bits); nid = spec->autocfg.speaker_pins[i];
/* Toggle internal bass muting */ if (!nid)
snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, break;
HDA_AMP_MUTE, bits); snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
HDA_AMP_MUTE, mute);
}
} }
static void alc888_fujitsu_xa3530_unsol_event(struct hda_codec *codec, static void alc_automute_amp_unsol_event(struct hda_codec *codec,
unsigned int res) unsigned int res)
{ {
if (res >> 26 == ALC880_HP_EVENT) if (codec->vendor_id == 0x10ec0880)
alc888_fujitsu_xa3530_automute(codec); res >>= 28;
else
res >>= 26;
if (res == ALC880_HP_EVENT)
alc_automute_amp(codec);
} }
static void alc888_fujitsu_xa3530_init_hook(struct hda_codec *codec)
{
struct alc_spec *spec = codec->spec;
spec->autocfg.hp_pins[0] = 0x17; /* line-out */
spec->autocfg.hp_pins[1] = 0x1b; /* hp */
spec->autocfg.speaker_pins[0] = 0x14; /* speaker */
spec->autocfg.speaker_pins[1] = 0x15; /* bass */
alc_automute_amp(codec);
}
/* /*
* ALC888 Acer Aspire 4930G model * ALC888 Acer Aspire 4930G model
...@@ -1456,22 +1491,13 @@ static struct snd_kcontrol_new alc888_base_mixer[] = { ...@@ -1456,22 +1491,13 @@ static struct snd_kcontrol_new alc888_base_mixer[] = {
{ } /* end */ { } /* end */
}; };
static void alc888_acer_aspire_4930g_automute(struct hda_codec *codec) static void alc888_acer_aspire_4930g_init_hook(struct hda_codec *codec)
{ {
unsigned int present; struct alc_spec *spec = codec->spec;
unsigned int bits;
present = snd_hda_codec_read(codec, 0x15, 0,
AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
bits = present ? HDA_AMP_MUTE : 0;
snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
HDA_AMP_MUTE, bits);
}
static void alc888_acer_aspire_4930g_unsol_event(struct hda_codec *codec, spec->autocfg.hp_pins[0] = 0x15;
unsigned int res) spec->autocfg.speaker_pins[0] = 0x14;
{ alc_automute_amp(codec);
if (res >> 26 == ALC880_HP_EVENT)
alc888_acer_aspire_4930g_automute(codec);
} }
/* /*
...@@ -2439,21 +2465,6 @@ static struct hda_verb alc880_beep_init_verbs[] = { ...@@ -2439,21 +2465,6 @@ static struct hda_verb alc880_beep_init_verbs[] = {
{ } { }
}; };
/* toggle speaker-output according to the hp-jack state */
static void alc880_uniwill_hp_automute(struct hda_codec *codec)
{
unsigned int present;
unsigned char bits;
present = snd_hda_codec_read(codec, 0x14, 0,
AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
bits = present ? HDA_AMP_MUTE : 0;
snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
HDA_AMP_MUTE, bits);
snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
HDA_AMP_MUTE, bits);
}
/* auto-toggle front mic */ /* auto-toggle front mic */
static void alc880_uniwill_mic_automute(struct hda_codec *codec) static void alc880_uniwill_mic_automute(struct hda_codec *codec)
{ {
...@@ -2466,9 +2477,14 @@ static void alc880_uniwill_mic_automute(struct hda_codec *codec) ...@@ -2466,9 +2477,14 @@ static void alc880_uniwill_mic_automute(struct hda_codec *codec)
snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits); snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
} }
static void alc880_uniwill_automute(struct hda_codec *codec) static void alc880_uniwill_init_hook(struct hda_codec *codec)
{ {
alc880_uniwill_hp_automute(codec); struct alc_spec *spec = codec->spec;
spec->autocfg.hp_pins[0] = 0x14;
spec->autocfg.speaker_pins[0] = 0x15;
spec->autocfg.speaker_pins[0] = 0x16;
alc_automute_amp(codec);
alc880_uniwill_mic_automute(codec); alc880_uniwill_mic_automute(codec);
} }
...@@ -2479,24 +2495,22 @@ static void alc880_uniwill_unsol_event(struct hda_codec *codec, ...@@ -2479,24 +2495,22 @@ static void alc880_uniwill_unsol_event(struct hda_codec *codec,
* definition. 4bit tag is placed at 28 bit! * definition. 4bit tag is placed at 28 bit!
*/ */
switch (res >> 28) { switch (res >> 28) {
case ALC880_HP_EVENT:
alc880_uniwill_hp_automute(codec);
break;
case ALC880_MIC_EVENT: case ALC880_MIC_EVENT:
alc880_uniwill_mic_automute(codec); alc880_uniwill_mic_automute(codec);
break; break;
default:
alc_automute_amp_unsol_event(codec, res);
break;
} }
} }
static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec) static void alc880_uniwill_p53_init_hook(struct hda_codec *codec)
{ {
unsigned int present; struct alc_spec *spec = codec->spec;
unsigned char bits;
present = snd_hda_codec_read(codec, 0x14, 0, spec->autocfg.hp_pins[0] = 0x14;
AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; spec->autocfg.speaker_pins[0] = 0x15;
bits = present ? HDA_AMP_MUTE : 0; alc_automute_amp(codec);
snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, HDA_AMP_MUTE, bits);
} }
static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec) static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
...@@ -2518,10 +2532,10 @@ static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec, ...@@ -2518,10 +2532,10 @@ static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
/* Looks like the unsol event is incompatible with the standard /* Looks like the unsol event is incompatible with the standard
* definition. 4bit tag is placed at 28 bit! * definition. 4bit tag is placed at 28 bit!
*/ */
if ((res >> 28) == ALC880_HP_EVENT)
alc880_uniwill_p53_hp_automute(codec);
if ((res >> 28) == ALC880_DCVOL_EVENT) if ((res >> 28) == ALC880_DCVOL_EVENT)
alc880_uniwill_p53_dcvol_automute(codec); alc880_uniwill_p53_dcvol_automute(codec);
else
alc_automute_amp_unsol_event(codec, res);
} }
/* /*
...@@ -2753,30 +2767,18 @@ static struct hda_verb alc880_lg_init_verbs[] = { ...@@ -2753,30 +2767,18 @@ static struct hda_verb alc880_lg_init_verbs[] = {
{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
/* jack sense */ /* jack sense */
{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1}, {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
{ } { }
}; };
/* toggle speaker-output according to the hp-jack state */ /* toggle speaker-output according to the hp-jack state */
static void alc880_lg_automute(struct hda_codec *codec) static void alc880_lg_init_hook(struct hda_codec *codec)
{ {
unsigned int present; struct alc_spec *spec = codec->spec;
unsigned char bits;
present = snd_hda_codec_read(codec, 0x1b, 0,
AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
bits = present ? HDA_AMP_MUTE : 0;
snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
HDA_AMP_MUTE, bits);
}
static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res) spec->autocfg.hp_pins[0] = 0x1b;
{ spec->autocfg.speaker_pins[0] = 0x17;
/* Looks like the unsol event is incompatible with the standard alc_automute_amp(codec);
* definition. 4bit tag is placed at 28 bit!
*/
if ((res >> 28) == 0x01)
alc880_lg_automute(codec);
} }
/* /*
...@@ -2850,30 +2852,18 @@ static struct hda_verb alc880_lg_lw_init_verbs[] = { ...@@ -2850,30 +2852,18 @@ static struct hda_verb alc880_lg_lw_init_verbs[] = {
{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
/* jack sense */ /* jack sense */
{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1}, {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
{ } { }
}; };
/* toggle speaker-output according to the hp-jack state */ /* toggle speaker-output according to the hp-jack state */
static void alc880_lg_lw_automute(struct hda_codec *codec) static void alc880_lg_lw_init_hook(struct hda_codec *codec)
{ {
unsigned int present; struct alc_spec *spec = codec->spec;
unsigned char bits;
present = snd_hda_codec_read(codec, 0x1b, 0,
AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
bits = present ? HDA_AMP_MUTE : 0;
snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
HDA_AMP_MUTE, bits);
}
static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res) spec->autocfg.hp_pins[0] = 0x1b;
{ spec->autocfg.speaker_pins[0] = 0x14;
/* Looks like the unsol event is incompatible with the standard alc_automute_amp(codec);
* definition. 4bit tag is placed at 28 bit!
*/
if ((res >> 28) == 0x01)
alc880_lg_lw_automute(codec);
} }
static struct snd_kcontrol_new alc880_medion_rim_mixer[] = { static struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
...@@ -2920,16 +2910,10 @@ static struct hda_verb alc880_medion_rim_init_verbs[] = { ...@@ -2920,16 +2910,10 @@ static struct hda_verb alc880_medion_rim_init_verbs[] = {
/* toggle speaker-output according to the hp-jack state */ /* toggle speaker-output according to the hp-jack state */
static void alc880_medion_rim_automute(struct hda_codec *codec) static void alc880_medion_rim_automute(struct hda_codec *codec)
{ {
unsigned int present; struct alc_spec *spec = codec->spec;
unsigned char bits; alc_automute_amp(codec);
/* toggle EAPD */
present = snd_hda_codec_read(codec, 0x14, 0, if (spec->jack_present)
AC_VERB_GET_PIN_SENSE, 0)
& AC_PINSENSE_PRESENCE;
bits = present ? HDA_AMP_MUTE : 0;
snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
HDA_AMP_MUTE, bits);
if (present)
snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0); snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
else else
snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2); snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
...@@ -2945,6 +2929,15 @@ static void alc880_medion_rim_unsol_event(struct hda_codec *codec, ...@@ -2945,6 +2929,15 @@ static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
alc880_medion_rim_automute(codec); alc880_medion_rim_automute(codec);
} }
static void alc880_medion_rim_init_hook(struct hda_codec *codec)
{
struct alc_spec *spec = codec->spec;
spec->autocfg.hp_pins[0] = 0x14;
spec->autocfg.speaker_pins[0] = 0x1b;
alc880_medion_rim_automute(codec);
}
#ifdef CONFIG_SND_HDA_POWER_SAVE #ifdef CONFIG_SND_HDA_POWER_SAVE
static struct hda_amp_list alc880_loopbacks[] = { static struct hda_amp_list alc880_loopbacks[] = {
{ 0x0b, HDA_INPUT, 0 }, { 0x0b, HDA_INPUT, 0 },
...@@ -3803,7 +3796,7 @@ static struct alc_config_preset alc880_presets[] = { ...@@ -3803,7 +3796,7 @@ static struct alc_config_preset alc880_presets[] = {
.channel_mode = alc880_2_jack_modes, .channel_mode = alc880_2_jack_modes,
.input_mux = &alc880_f1734_capture_source, .input_mux = &alc880_f1734_capture_source,
.unsol_event = alc880_uniwill_p53_unsol_event, .unsol_event = alc880_uniwill_p53_unsol_event,
.init_hook = alc880_uniwill_p53_hp_automute, .init_hook = alc880_uniwill_p53_init_hook,
}, },
[ALC880_ASUS] = { [ALC880_ASUS] = {
.mixers = { alc880_asus_mixer }, .mixers = { alc880_asus_mixer },
...@@ -3880,7 +3873,7 @@ static struct alc_config_preset alc880_presets[] = { ...@@ -3880,7 +3873,7 @@ static struct alc_config_preset alc880_presets[] = {
.need_dac_fix = 1, .need_dac_fix = 1,
.input_mux = &alc880_capture_source, .input_mux = &alc880_capture_source,
.unsol_event = alc880_uniwill_unsol_event, .unsol_event = alc880_uniwill_unsol_event,
.init_hook = alc880_uniwill_automute, .init_hook = alc880_uniwill_init_hook,
}, },
[ALC880_UNIWILL_P53] = { [ALC880_UNIWILL_P53] = {
.mixers = { alc880_uniwill_p53_mixer }, .mixers = { alc880_uniwill_p53_mixer },
...@@ -3892,7 +3885,7 @@ static struct alc_config_preset alc880_presets[] = { ...@@ -3892,7 +3885,7 @@ static struct alc_config_preset alc880_presets[] = {
.channel_mode = alc880_threestack_modes, .channel_mode = alc880_threestack_modes,
.input_mux = &alc880_capture_source, .input_mux = &alc880_capture_source,
.unsol_event = alc880_uniwill_p53_unsol_event, .unsol_event = alc880_uniwill_p53_unsol_event,
.init_hook = alc880_uniwill_p53_hp_automute, .init_hook = alc880_uniwill_p53_init_hook,
}, },
[ALC880_FUJITSU] = { [ALC880_FUJITSU] = {
.mixers = { alc880_fujitsu_mixer }, .mixers = { alc880_fujitsu_mixer },
...@@ -3906,7 +3899,7 @@ static struct alc_config_preset alc880_presets[] = { ...@@ -3906,7 +3899,7 @@ static struct alc_config_preset alc880_presets[] = {
.channel_mode = alc880_2_jack_modes, .channel_mode = alc880_2_jack_modes,
.input_mux = &alc880_capture_source, .input_mux = &alc880_capture_source,
.unsol_event = alc880_uniwill_p53_unsol_event, .unsol_event = alc880_uniwill_p53_unsol_event,
.init_hook = alc880_uniwill_p53_hp_automute, .init_hook = alc880_uniwill_p53_init_hook,
}, },
[ALC880_CLEVO] = { [ALC880_CLEVO] = {
.mixers = { alc880_three_stack_mixer }, .mixers = { alc880_three_stack_mixer },
...@@ -3931,8 +3924,8 @@ static struct alc_config_preset alc880_presets[] = { ...@@ -3931,8 +3924,8 @@ static struct alc_config_preset alc880_presets[] = {
.channel_mode = alc880_lg_ch_modes, .channel_mode = alc880_lg_ch_modes,
.need_dac_fix = 1, .need_dac_fix = 1,
.input_mux = &alc880_lg_capture_source, .input_mux = &alc880_lg_capture_source,
.unsol_event = alc880_lg_unsol_event, .unsol_event = alc_automute_amp_unsol_event,
.init_hook = alc880_lg_automute, .init_hook = alc880_lg_init_hook,
#ifdef CONFIG_SND_HDA_POWER_SAVE #ifdef CONFIG_SND_HDA_POWER_SAVE
.loopbacks = alc880_lg_loopbacks, .loopbacks = alc880_lg_loopbacks,
#endif #endif
...@@ -3947,8 +3940,8 @@ static struct alc_config_preset alc880_presets[] = { ...@@ -3947,8 +3940,8 @@ static struct alc_config_preset alc880_presets[] = {
.num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes), .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
.channel_mode = alc880_lg_lw_modes, .channel_mode = alc880_lg_lw_modes,
.input_mux = &alc880_lg_lw_capture_source, .input_mux = &alc880_lg_lw_capture_source,
.unsol_event = alc880_lg_lw_unsol_event, .unsol_event = alc_automute_amp_unsol_event,
.init_hook = alc880_lg_lw_automute, .init_hook = alc880_lg_lw_init_hook,
}, },
[ALC880_MEDION_RIM] = { [ALC880_MEDION_RIM] = {
.mixers = { alc880_medion_rim_mixer }, .mixers = { alc880_medion_rim_mixer },
...@@ -3962,7 +3955,7 @@ static struct alc_config_preset alc880_presets[] = { ...@@ -3962,7 +3955,7 @@ static struct alc_config_preset alc880_presets[] = {
.channel_mode = alc880_2_jack_modes, .channel_mode = alc880_2_jack_modes,
.input_mux = &alc880_medion_rim_capture_source, .input_mux = &alc880_medion_rim_capture_source,
.unsol_event = alc880_medion_rim_unsol_event, .unsol_event = alc880_medion_rim_unsol_event,
.init_hook = alc880_medion_rim_automute, .init_hook = alc880_medion_rim_init_hook,
}, },
#ifdef CONFIG_SND_DEBUG #ifdef CONFIG_SND_DEBUG
[ALC880_TEST] = { [ALC880_TEST] = {
...@@ -6666,45 +6659,23 @@ static struct hda_verb alc885_imac24_init_verbs[] = { ...@@ -6666,45 +6659,23 @@ static struct hda_verb alc885_imac24_init_verbs[] = {
}; };
/* Toggle speaker-output according to the hp-jack state */ /* Toggle speaker-output according to the hp-jack state */
static void alc885_imac24_automute(struct hda_codec *codec) static void alc885_imac24_automute_init_hook(struct hda_codec *codec)
{ {
unsigned int present; struct alc_spec *spec = codec->spec;
present = snd_hda_codec_read(codec, 0x14, 0,
AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
snd_hda_codec_amp_stereo(codec, 0x18, HDA_OUTPUT, 0,
HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
}
/* Processes unsolicited events. */ spec->autocfg.hp_pins[0] = 0x14;
static void alc885_imac24_unsol_event(struct hda_codec *codec, spec->autocfg.speaker_pins[0] = 0x18;
unsigned int res) spec->autocfg.speaker_pins[1] = 0x1a;
{ alc_automute_amp(codec);
/* Headphone insertion or removal. */
if ((res >> 26) == ALC880_HP_EVENT)
alc885_imac24_automute(codec);
} }
static void alc885_mbp3_automute(struct hda_codec *codec) static void alc885_mbp3_init_hook(struct hda_codec *codec)
{ {
unsigned int present; struct alc_spec *spec = codec->spec;
present = snd_hda_codec_read(codec, 0x15, 0,
AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
} spec->autocfg.hp_pins[0] = 0x15;
static void alc885_mbp3_unsol_event(struct hda_codec *codec, spec->autocfg.speaker_pins[0] = 0x14;
unsigned int res) alc_automute_amp(codec);
{
/* Headphone insertion or removal. */
if ((res >> 26) == ALC880_HP_EVENT)
alc885_mbp3_automute(codec);
} }
...@@ -6729,24 +6700,25 @@ static struct hda_verb alc882_targa_verbs[] = { ...@@ -6729,24 +6700,25 @@ static struct hda_verb alc882_targa_verbs[] = {
/* toggle speaker-output according to the hp-jack state */ /* toggle speaker-output according to the hp-jack state */
static void alc882_targa_automute(struct hda_codec *codec) static void alc882_targa_automute(struct hda_codec *codec)
{ {
unsigned int present; struct alc_spec *spec = codec->spec;
alc_automute_amp(codec);
present = snd_hda_codec_read(codec, 0x14, 0,
AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA, snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
present ? 1 : 3); spec->jack_present ? 1 : 3);
}
static void alc882_targa_init_hook(struct hda_codec *codec)
{
struct alc_spec *spec = codec->spec;
spec->autocfg.hp_pins[0] = 0x14;
spec->autocfg.speaker_pins[0] = 0x1b;
alc882_targa_automute(codec);
} }
static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res) static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
{ {
/* Looks like the unsol event is incompatible with the standard if ((res >> 26) == ALC880_HP_EVENT)
* definition. 4bit tag is placed at 26 bit!
*/
if (((res >> 26) == ALC880_HP_EVENT)) {
alc882_targa_automute(codec); alc882_targa_automute(codec);
}
} }
static struct hda_verb alc882_asus_a7j_verbs[] = { static struct hda_verb alc882_asus_a7j_verbs[] = {
...@@ -6828,7 +6800,7 @@ static void alc885_macpro_init_hook(struct hda_codec *codec) ...@@ -6828,7 +6800,7 @@ static void alc885_macpro_init_hook(struct hda_codec *codec)
static void alc885_imac24_init_hook(struct hda_codec *codec) static void alc885_imac24_init_hook(struct hda_codec *codec)
{ {
alc885_macpro_init_hook(codec); alc885_macpro_init_hook(codec);
alc885_imac24_automute(codec); alc885_imac24_automute_init_hook(codec);
} }
/* /*
...@@ -6999,8 +6971,8 @@ static struct alc_config_preset alc882_presets[] = { ...@@ -6999,8 +6971,8 @@ static struct alc_config_preset alc882_presets[] = {
.input_mux = &alc882_capture_source, .input_mux = &alc882_capture_source,
.dig_out_nid = ALC882_DIGOUT_NID, .dig_out_nid = ALC882_DIGOUT_NID,
.dig_in_nid = ALC882_DIGIN_NID, .dig_in_nid = ALC882_DIGIN_NID,
.unsol_event = alc885_mbp3_unsol_event, .unsol_event = alc_automute_amp_unsol_event,
.init_hook = alc885_mbp3_automute, .init_hook = alc885_mbp3_init_hook,
}, },
[ALC885_MB5] = { [ALC885_MB5] = {
.mixers = { alc885_mb5_mixer }, .mixers = { alc885_mb5_mixer },
...@@ -7036,7 +7008,7 @@ static struct alc_config_preset alc882_presets[] = { ...@@ -7036,7 +7008,7 @@ static struct alc_config_preset alc882_presets[] = {
.num_channel_mode = ARRAY_SIZE(alc882_ch_modes), .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
.channel_mode = alc882_ch_modes, .channel_mode = alc882_ch_modes,
.input_mux = &alc882_capture_source, .input_mux = &alc882_capture_source,
.unsol_event = alc885_imac24_unsol_event, .unsol_event = alc_automute_amp_unsol_event,
.init_hook = alc885_imac24_init_hook, .init_hook = alc885_imac24_init_hook,
}, },
[ALC882_TARGA] = { [ALC882_TARGA] = {
...@@ -7053,7 +7025,7 @@ static struct alc_config_preset alc882_presets[] = { ...@@ -7053,7 +7025,7 @@ static struct alc_config_preset alc882_presets[] = {
.need_dac_fix = 1, .need_dac_fix = 1,
.input_mux = &alc882_capture_source, .input_mux = &alc882_capture_source,
.unsol_event = alc882_targa_unsol_event, .unsol_event = alc882_targa_unsol_event,
.init_hook = alc882_targa_automute, .init_hook = alc882_targa_init_hook,
}, },
[ALC882_ASUS_A7J] = { [ALC882_ASUS_A7J] = {
.mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer }, .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
...@@ -7903,8 +7875,6 @@ static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = { ...@@ -7903,8 +7875,6 @@ static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT), HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
...@@ -8053,16 +8023,14 @@ static struct hda_verb alc883_init_verbs[] = { ...@@ -8053,16 +8023,14 @@ static struct hda_verb alc883_init_verbs[] = {
}; };
/* toggle speaker-output according to the hp-jack state */ /* toggle speaker-output according to the hp-jack state */
static void alc883_mitac_hp_automute(struct hda_codec *codec) static void alc883_mitac_init_hook(struct hda_codec *codec)
{ {
unsigned int present; struct alc_spec *spec = codec->spec;
present = snd_hda_codec_read(codec, 0x15, 0, spec->autocfg.hp_pins[0] = 0x15;
AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; spec->autocfg.speaker_pins[0] = 0x14;
snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, spec->autocfg.speaker_pins[1] = 0x17;
HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); alc_automute_amp(codec);
snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
} }
/* auto-toggle front mic */ /* auto-toggle front mic */
...@@ -8079,25 +8047,6 @@ static void alc883_mitac_mic_automute(struct hda_codec *codec) ...@@ -8079,25 +8047,6 @@ static void alc883_mitac_mic_automute(struct hda_codec *codec)
} }
*/ */
static void alc883_mitac_automute(struct hda_codec *codec)
{
alc883_mitac_hp_automute(codec);
/* alc883_mitac_mic_automute(codec); */
}
static void alc883_mitac_unsol_event(struct hda_codec *codec,
unsigned int res)
{
switch (res >> 26) {
case ALC880_HP_EVENT:
alc883_mitac_hp_automute(codec);
break;
case ALC880_MIC_EVENT:
/* alc883_mitac_mic_automute(codec); */
break;
}
}
static struct hda_verb alc883_mitac_verbs[] = { static struct hda_verb alc883_mitac_verbs[] = {
/* HP */ /* HP */
{0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
...@@ -8215,29 +8164,15 @@ static struct hda_verb alc888_6st_dell_verbs[] = { ...@@ -8215,29 +8164,15 @@ static struct hda_verb alc888_6st_dell_verbs[] = {
{ } { }
}; };
static void alc888_3st_hp_front_automute(struct hda_codec *codec) static void alc888_3st_hp_init_hook(struct hda_codec *codec)
{ {
unsigned int present, bits; struct alc_spec *spec = codec->spec;
present = snd_hda_codec_read(codec, 0x1b, 0,
AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
bits = present ? HDA_AMP_MUTE : 0;
snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
HDA_AMP_MUTE, bits);
snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
HDA_AMP_MUTE, bits);
snd_hda_codec_amp_stereo(codec, 0x18, HDA_OUTPUT, 0,
HDA_AMP_MUTE, bits);
}
static void alc888_3st_hp_unsol_event(struct hda_codec *codec, spec->autocfg.hp_pins[0] = 0x1b;
unsigned int res) spec->autocfg.speaker_pins[0] = 0x14;
{ spec->autocfg.speaker_pins[1] = 0x16;
switch (res >> 26) { spec->autocfg.speaker_pins[2] = 0x18;
case ALC880_HP_EVENT: alc_automute_amp(codec);
alc888_3st_hp_front_automute(codec);
break;
}
} }
static struct hda_verb alc888_3st_hp_verbs[] = { static struct hda_verb alc888_3st_hp_verbs[] = {
...@@ -8334,70 +8269,36 @@ static struct hda_verb alc883_medion_md2_verbs[] = { ...@@ -8334,70 +8269,36 @@ static struct hda_verb alc883_medion_md2_verbs[] = {
}; };
/* toggle speaker-output according to the hp-jack state */ /* toggle speaker-output according to the hp-jack state */
static void alc883_medion_md2_automute(struct hda_codec *codec) static void alc883_medion_md2_init_hook(struct hda_codec *codec)
{ {
unsigned int present; struct alc_spec *spec = codec->spec;
present = snd_hda_codec_read(codec, 0x14, 0,
AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
}
static void alc883_medion_md2_unsol_event(struct hda_codec *codec, spec->autocfg.hp_pins[0] = 0x14;
unsigned int res) spec->autocfg.speaker_pins[0] = 0x15;
{ alc_automute_amp(codec);
if ((res >> 26) == ALC880_HP_EVENT)
alc883_medion_md2_automute(codec);
} }
/* toggle speaker-output according to the hp-jack state */ /* toggle speaker-output according to the hp-jack state */
static void alc883_tagra_automute(struct hda_codec *codec) #define alc883_tagra_init_hook alc882_targa_init_hook
#define alc883_tagra_unsol_event alc882_targa_unsol_event
static void alc883_clevo_m720_mic_automute(struct hda_codec *codec)
{ {
unsigned int present; unsigned int present;
unsigned char bits;
present = snd_hda_codec_read(codec, 0x14, 0, present = snd_hda_codec_read(codec, 0x18, 0,
AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
bits = present ? HDA_AMP_MUTE : 0; snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0, HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
HDA_AMP_MUTE, bits);
snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
present ? 1 : 3);
} }
static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res) static void alc883_clevo_m720_init_hook(struct hda_codec *codec)
{ {
if ((res >> 26) == ALC880_HP_EVENT) struct alc_spec *spec = codec->spec;
alc883_tagra_automute(codec);
}
/* toggle speaker-output according to the hp-jack state */
static void alc883_clevo_m720_hp_automute(struct hda_codec *codec)
{
unsigned int present;
unsigned char bits;
present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0)
& AC_PINSENSE_PRESENCE;
bits = present ? HDA_AMP_MUTE : 0;
snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
HDA_AMP_MUTE, bits);
}
static void alc883_clevo_m720_mic_automute(struct hda_codec *codec)
{
unsigned int present;
present = snd_hda_codec_read(codec, 0x18, 0,
AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
}
static void alc883_clevo_m720_automute(struct hda_codec *codec) spec->autocfg.hp_pins[0] = 0x15;
{ spec->autocfg.speaker_pins[0] = 0x14;
alc883_clevo_m720_hp_automute(codec); alc_automute_amp(codec);
alc883_clevo_m720_mic_automute(codec); alc883_clevo_m720_mic_automute(codec);
} }
...@@ -8405,52 +8306,32 @@ static void alc883_clevo_m720_unsol_event(struct hda_codec *codec, ...@@ -8405,52 +8306,32 @@ static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
unsigned int res) unsigned int res)
{ {
switch (res >> 26) { switch (res >> 26) {
case ALC880_HP_EVENT:
alc883_clevo_m720_hp_automute(codec);
break;
case ALC880_MIC_EVENT: case ALC880_MIC_EVENT:
alc883_clevo_m720_mic_automute(codec); alc883_clevo_m720_mic_automute(codec);
break; break;
default:
alc_automute_amp_unsol_event(codec, res);
break;
} }
} }
/* toggle speaker-output according to the hp-jack state */ /* toggle speaker-output according to the hp-jack state */
static void alc883_2ch_fujitsu_pi2515_automute(struct hda_codec *codec) static void alc883_2ch_fujitsu_pi2515_init_hook(struct hda_codec *codec)
{ {
unsigned int present; struct alc_spec *spec = codec->spec;
unsigned char bits;
present = snd_hda_codec_read(codec, 0x14, 0, AC_VERB_GET_PIN_SENSE, 0)
& AC_PINSENSE_PRESENCE;
bits = present ? HDA_AMP_MUTE : 0;
snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
HDA_AMP_MUTE, bits);
}
static void alc883_2ch_fujitsu_pi2515_unsol_event(struct hda_codec *codec, spec->autocfg.hp_pins[0] = 0x14;
unsigned int res) spec->autocfg.speaker_pins[0] = 0x15;
{ alc_automute_amp(codec);
if ((res >> 26) == ALC880_HP_EVENT)
alc883_2ch_fujitsu_pi2515_automute(codec);
} }
static void alc883_haier_w66_automute(struct hda_codec *codec) static void alc883_haier_w66_init_hook(struct hda_codec *codec)
{ {
unsigned int present; struct alc_spec *spec = codec->spec;
unsigned char bits;
present = snd_hda_codec_read(codec, 0x1b, 0,
AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
bits = present ? 0x80 : 0;
snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
0x80, bits);
}
static void alc883_haier_w66_unsol_event(struct hda_codec *codec, spec->autocfg.hp_pins[0] = 0x1b;
unsigned int res) spec->autocfg.speaker_pins[0] = 0x14;
{ alc_automute_amp(codec);
if ((res >> 26) == ALC880_HP_EVENT)
alc883_haier_w66_automute(codec);
} }
static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec) static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
...@@ -8489,23 +8370,14 @@ static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec, ...@@ -8489,23 +8370,14 @@ static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
} }
/* toggle speaker-output according to the hp-jack state */ /* toggle speaker-output according to the hp-jack state */
static void alc883_acer_aspire_automute(struct hda_codec *codec) static void alc883_acer_aspire_init_hook(struct hda_codec *codec)
{ {
unsigned int present; struct alc_spec *spec = codec->spec;
present = snd_hda_codec_read(codec, 0x14, 0,
AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
}
static void alc883_acer_aspire_unsol_event(struct hda_codec *codec, spec->autocfg.hp_pins[0] = 0x14;
unsigned int res) spec->autocfg.speaker_pins[0] = 0x15;
{ spec->autocfg.speaker_pins[1] = 0x16;
if ((res >> 26) == ALC880_HP_EVENT) alc_automute_amp(codec);
alc883_acer_aspire_automute(codec);
} }
static struct hda_verb alc883_acer_eapd_verbs[] = { static struct hda_verb alc883_acer_eapd_verbs[] = {
...@@ -8526,75 +8398,29 @@ static struct hda_verb alc883_acer_eapd_verbs[] = { ...@@ -8526,75 +8398,29 @@ static struct hda_verb alc883_acer_eapd_verbs[] = {
{ } { }
}; };
static void alc888_6st_dell_front_automute(struct hda_codec *codec) static void alc888_6st_dell_init_hook(struct hda_codec *codec)
{ {
unsigned int present; struct alc_spec *spec = codec->spec;
present = snd_hda_codec_read(codec, 0x1b, 0,
AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
}
static void alc888_6st_dell_unsol_event(struct hda_codec *codec, spec->autocfg.hp_pins[0] = 0x1b;
unsigned int res) spec->autocfg.speaker_pins[0] = 0x14;
{ spec->autocfg.speaker_pins[1] = 0x15;
switch (res >> 26) { spec->autocfg.speaker_pins[2] = 0x16;
case ALC880_HP_EVENT: spec->autocfg.speaker_pins[3] = 0x17;
/* printk(KERN_DEBUG "hp_event\n"); */ alc_automute_amp(codec);
alc888_6st_dell_front_automute(codec);
break;
}
} }
static void alc888_lenovo_sky_front_automute(struct hda_codec *codec) static void alc888_lenovo_sky_init_hook(struct hda_codec *codec)
{ {
unsigned int mute; struct alc_spec *spec = codec->spec;
unsigned int present;
snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
present = snd_hda_codec_read(codec, 0x1b, 0,
AC_VERB_GET_PIN_SENSE, 0);
present = (present & 0x80000000) != 0;
if (present) {
/* mute internal speaker */
snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
HDA_AMP_MUTE, HDA_AMP_MUTE);
snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
HDA_AMP_MUTE, HDA_AMP_MUTE);
snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
HDA_AMP_MUTE, HDA_AMP_MUTE);
snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
HDA_AMP_MUTE, HDA_AMP_MUTE);
snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
HDA_AMP_MUTE, HDA_AMP_MUTE);
} else {
/* unmute internal speaker if necessary */
mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
HDA_AMP_MUTE, mute);
snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
HDA_AMP_MUTE, mute);
snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
HDA_AMP_MUTE, mute);
snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
HDA_AMP_MUTE, mute);
snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
HDA_AMP_MUTE, mute);
}
}
static void alc883_lenovo_sky_unsol_event(struct hda_codec *codec, spec->autocfg.hp_pins[0] = 0x1b;
unsigned int res) spec->autocfg.speaker_pins[0] = 0x14;
{ spec->autocfg.speaker_pins[1] = 0x15;
if ((res >> 26) == ALC880_HP_EVENT) spec->autocfg.speaker_pins[2] = 0x16;
alc888_lenovo_sky_front_automute(codec); spec->autocfg.speaker_pins[3] = 0x17;
spec->autocfg.speaker_pins[4] = 0x1a;
alc_automute_amp(codec);
} }
/* /*
...@@ -8682,39 +8508,33 @@ static void alc883_nb_mic_automute(struct hda_codec *codec) ...@@ -8682,39 +8508,33 @@ static void alc883_nb_mic_automute(struct hda_codec *codec)
0x7000 | (0x01 << 8) | (present ? 0x80 : 0)); 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
} }
static void alc883_M90V_speaker_automute(struct hda_codec *codec) static void alc883_M90V_init_hook(struct hda_codec *codec)
{ {
unsigned int present; struct alc_spec *spec = codec->spec;
unsigned char bits;
present = snd_hda_codec_read(codec, 0x1b, 0, spec->autocfg.hp_pins[0] = 0x1b;
AC_VERB_GET_PIN_SENSE, 0) spec->autocfg.speaker_pins[0] = 0x14;
& AC_PINSENSE_PRESENCE; spec->autocfg.speaker_pins[1] = 0x15;
bits = present ? 0 : PIN_OUT; spec->autocfg.speaker_pins[2] = 0x16;
snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, alc_automute_pin(codec);
bits);
snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
bits);
snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
bits);
} }
static void alc883_mode2_unsol_event(struct hda_codec *codec, static void alc883_mode2_unsol_event(struct hda_codec *codec,
unsigned int res) unsigned int res)
{ {
switch (res >> 26) { switch (res >> 26) {
case ALC880_HP_EVENT:
alc883_M90V_speaker_automute(codec);
break;
case ALC880_MIC_EVENT: case ALC880_MIC_EVENT:
alc883_nb_mic_automute(codec); alc883_nb_mic_automute(codec);
break; break;
default:
alc_sku_unsol_event(codec, res);
break;
} }
} }
static void alc883_mode2_inithook(struct hda_codec *codec) static void alc883_mode2_inithook(struct hda_codec *codec)
{ {
alc883_M90V_speaker_automute(codec); alc883_M90V_init_hook(codec);
alc883_nb_mic_automute(codec); alc883_nb_mic_automute(codec);
} }
...@@ -8731,32 +8551,13 @@ static struct hda_verb alc888_asus_eee1601_verbs[] = { ...@@ -8731,32 +8551,13 @@ static struct hda_verb alc888_asus_eee1601_verbs[] = {
{ } /* end */ { } /* end */
}; };
static void alc883_eee1601_speaker_automute(struct hda_codec *codec)
{
unsigned int present;
unsigned char bits;
present = snd_hda_codec_read(codec, 0x14, 0,
AC_VERB_GET_PIN_SENSE, 0)
& AC_PINSENSE_PRESENCE;
bits = present ? 0 : PIN_OUT;
snd_hda_codec_write(codec, 0x1b, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
bits);
}
static void alc883_eee1601_unsol_event(struct hda_codec *codec,
unsigned int res)
{
switch (res >> 26) {
case ALC880_HP_EVENT:
alc883_eee1601_speaker_automute(codec);
break;
}
}
static void alc883_eee1601_inithook(struct hda_codec *codec) static void alc883_eee1601_inithook(struct hda_codec *codec)
{ {
alc883_eee1601_speaker_automute(codec); struct alc_spec *spec = codec->spec;
spec->autocfg.hp_pins[0] = 0x14;
spec->autocfg.speaker_pins[0] = 0x1b;
alc_automute_pin(codec);
} }
#ifdef CONFIG_SND_HDA_POWER_SAVE #ifdef CONFIG_SND_HDA_POWER_SAVE
...@@ -8969,7 +8770,7 @@ static struct alc_config_preset alc883_presets[] = { ...@@ -8969,7 +8770,7 @@ static struct alc_config_preset alc883_presets[] = {
.need_dac_fix = 1, .need_dac_fix = 1,
.input_mux = &alc883_capture_source, .input_mux = &alc883_capture_source,
.unsol_event = alc883_tagra_unsol_event, .unsol_event = alc883_tagra_unsol_event,
.init_hook = alc883_tagra_automute, .init_hook = alc883_tagra_init_hook,
}, },
[ALC883_TARGA_2ch_DIG] = { [ALC883_TARGA_2ch_DIG] = {
.mixers = { alc883_tagra_2ch_mixer}, .mixers = { alc883_tagra_2ch_mixer},
...@@ -8983,7 +8784,7 @@ static struct alc_config_preset alc883_presets[] = { ...@@ -8983,7 +8784,7 @@ static struct alc_config_preset alc883_presets[] = {
.channel_mode = alc883_3ST_2ch_modes, .channel_mode = alc883_3ST_2ch_modes,
.input_mux = &alc883_capture_source, .input_mux = &alc883_capture_source,
.unsol_event = alc883_tagra_unsol_event, .unsol_event = alc883_tagra_unsol_event,
.init_hook = alc883_tagra_automute, .init_hook = alc883_tagra_init_hook,
}, },
[ALC883_ACER] = { [ALC883_ACER] = {
.mixers = { alc883_base_mixer }, .mixers = { alc883_base_mixer },
...@@ -9008,8 +8809,8 @@ static struct alc_config_preset alc883_presets[] = { ...@@ -9008,8 +8809,8 @@ static struct alc_config_preset alc883_presets[] = {
.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
.channel_mode = alc883_3ST_2ch_modes, .channel_mode = alc883_3ST_2ch_modes,
.input_mux = &alc883_capture_source, .input_mux = &alc883_capture_source,
.unsol_event = alc883_acer_aspire_unsol_event, .unsol_event = alc_automute_amp_unsol_event,
.init_hook = alc883_acer_aspire_automute, .init_hook = alc883_acer_aspire_init_hook,
}, },
[ALC888_ACER_ASPIRE_4930G] = { [ALC888_ACER_ASPIRE_4930G] = {
.mixers = { alc888_base_mixer, .mixers = { alc888_base_mixer,
...@@ -9028,8 +8829,8 @@ static struct alc_config_preset alc883_presets[] = { ...@@ -9028,8 +8829,8 @@ static struct alc_config_preset alc883_presets[] = {
.num_mux_defs = .num_mux_defs =
ARRAY_SIZE(alc888_2_capture_sources), ARRAY_SIZE(alc888_2_capture_sources),
.input_mux = alc888_2_capture_sources, .input_mux = alc888_2_capture_sources,
.unsol_event = alc888_acer_aspire_4930g_unsol_event, .unsol_event = alc_automute_amp_unsol_event,
.init_hook = alc888_acer_aspire_4930g_automute, .init_hook = alc888_acer_aspire_4930g_init_hook,
}, },
[ALC883_MEDION] = { [ALC883_MEDION] = {
.mixers = { alc883_fivestack_mixer, .mixers = { alc883_fivestack_mixer,
...@@ -9053,8 +8854,8 @@ static struct alc_config_preset alc883_presets[] = { ...@@ -9053,8 +8854,8 @@ static struct alc_config_preset alc883_presets[] = {
.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
.channel_mode = alc883_3ST_2ch_modes, .channel_mode = alc883_3ST_2ch_modes,
.input_mux = &alc883_capture_source, .input_mux = &alc883_capture_source,
.unsol_event = alc883_medion_md2_unsol_event, .unsol_event = alc_automute_amp_unsol_event,
.init_hook = alc883_medion_md2_automute, .init_hook = alc883_medion_md2_init_hook,
}, },
[ALC883_LAPTOP_EAPD] = { [ALC883_LAPTOP_EAPD] = {
.mixers = { alc883_base_mixer }, .mixers = { alc883_base_mixer },
...@@ -9075,7 +8876,7 @@ static struct alc_config_preset alc883_presets[] = { ...@@ -9075,7 +8876,7 @@ static struct alc_config_preset alc883_presets[] = {
.channel_mode = alc883_3ST_2ch_modes, .channel_mode = alc883_3ST_2ch_modes,
.input_mux = &alc883_capture_source, .input_mux = &alc883_capture_source,
.unsol_event = alc883_clevo_m720_unsol_event, .unsol_event = alc883_clevo_m720_unsol_event,
.init_hook = alc883_clevo_m720_automute, .init_hook = alc883_clevo_m720_init_hook,
}, },
[ALC883_LENOVO_101E_2ch] = { [ALC883_LENOVO_101E_2ch] = {
.mixers = { alc883_lenovo_101e_2ch_mixer}, .mixers = { alc883_lenovo_101e_2ch_mixer},
...@@ -9099,8 +8900,8 @@ static struct alc_config_preset alc883_presets[] = { ...@@ -9099,8 +8900,8 @@ static struct alc_config_preset alc883_presets[] = {
.channel_mode = alc883_3ST_2ch_modes, .channel_mode = alc883_3ST_2ch_modes,
.need_dac_fix = 1, .need_dac_fix = 1,
.input_mux = &alc883_lenovo_nb0763_capture_source, .input_mux = &alc883_lenovo_nb0763_capture_source,
.unsol_event = alc883_medion_md2_unsol_event, .unsol_event = alc_automute_amp_unsol_event,
.init_hook = alc883_medion_md2_automute, .init_hook = alc883_medion_md2_init_hook,
}, },
[ALC888_LENOVO_MS7195_DIG] = { [ALC888_LENOVO_MS7195_DIG] = {
.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
...@@ -9124,8 +8925,8 @@ static struct alc_config_preset alc883_presets[] = { ...@@ -9124,8 +8925,8 @@ static struct alc_config_preset alc883_presets[] = {
.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
.channel_mode = alc883_3ST_2ch_modes, .channel_mode = alc883_3ST_2ch_modes,
.input_mux = &alc883_capture_source, .input_mux = &alc883_capture_source,
.unsol_event = alc883_haier_w66_unsol_event, .unsol_event = alc_automute_amp_unsol_event,
.init_hook = alc883_haier_w66_automute, .init_hook = alc883_haier_w66_init_hook,
}, },
[ALC888_3ST_HP] = { [ALC888_3ST_HP] = {
.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
...@@ -9136,8 +8937,8 @@ static struct alc_config_preset alc883_presets[] = { ...@@ -9136,8 +8937,8 @@ static struct alc_config_preset alc883_presets[] = {
.channel_mode = alc888_3st_hp_modes, .channel_mode = alc888_3st_hp_modes,
.need_dac_fix = 1, .need_dac_fix = 1,
.input_mux = &alc883_capture_source, .input_mux = &alc883_capture_source,
.unsol_event = alc888_3st_hp_unsol_event, .unsol_event = alc_automute_amp_unsol_event,
.init_hook = alc888_3st_hp_front_automute, .init_hook = alc888_3st_hp_init_hook,
}, },
[ALC888_6ST_DELL] = { [ALC888_6ST_DELL] = {
.mixers = { alc883_base_mixer, alc883_chmode_mixer }, .mixers = { alc883_base_mixer, alc883_chmode_mixer },
...@@ -9149,8 +8950,8 @@ static struct alc_config_preset alc883_presets[] = { ...@@ -9149,8 +8950,8 @@ static struct alc_config_preset alc883_presets[] = {
.num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
.channel_mode = alc883_sixstack_modes, .channel_mode = alc883_sixstack_modes,
.input_mux = &alc883_capture_source, .input_mux = &alc883_capture_source,
.unsol_event = alc888_6st_dell_unsol_event, .unsol_event = alc_automute_amp_unsol_event,
.init_hook = alc888_6st_dell_front_automute, .init_hook = alc888_6st_dell_init_hook,
}, },
[ALC883_MITAC] = { [ALC883_MITAC] = {
.mixers = { alc883_mitac_mixer }, .mixers = { alc883_mitac_mixer },
...@@ -9160,8 +8961,8 @@ static struct alc_config_preset alc883_presets[] = { ...@@ -9160,8 +8961,8 @@ static struct alc_config_preset alc883_presets[] = {
.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
.channel_mode = alc883_3ST_2ch_modes, .channel_mode = alc883_3ST_2ch_modes,
.input_mux = &alc883_capture_source, .input_mux = &alc883_capture_source,
.unsol_event = alc883_mitac_unsol_event, .unsol_event = alc_automute_amp_unsol_event,
.init_hook = alc883_mitac_automute, .init_hook = alc883_mitac_init_hook,
}, },
[ALC883_FUJITSU_PI2515] = { [ALC883_FUJITSU_PI2515] = {
.mixers = { alc883_2ch_fujitsu_pi2515_mixer }, .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
...@@ -9173,8 +8974,8 @@ static struct alc_config_preset alc883_presets[] = { ...@@ -9173,8 +8974,8 @@ static struct alc_config_preset alc883_presets[] = {
.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
.channel_mode = alc883_3ST_2ch_modes, .channel_mode = alc883_3ST_2ch_modes,
.input_mux = &alc883_fujitsu_pi2515_capture_source, .input_mux = &alc883_fujitsu_pi2515_capture_source,
.unsol_event = alc883_2ch_fujitsu_pi2515_unsol_event, .unsol_event = alc_automute_amp_unsol_event,
.init_hook = alc883_2ch_fujitsu_pi2515_automute, .init_hook = alc883_2ch_fujitsu_pi2515_init_hook,
}, },
[ALC888_FUJITSU_XA3530] = { [ALC888_FUJITSU_XA3530] = {
.mixers = { alc888_base_mixer, alc883_chmode_mixer }, .mixers = { alc888_base_mixer, alc883_chmode_mixer },
...@@ -9191,8 +8992,8 @@ static struct alc_config_preset alc883_presets[] = { ...@@ -9191,8 +8992,8 @@ static struct alc_config_preset alc883_presets[] = {
.num_mux_defs = .num_mux_defs =
ARRAY_SIZE(alc888_2_capture_sources), ARRAY_SIZE(alc888_2_capture_sources),
.input_mux = alc888_2_capture_sources, .input_mux = alc888_2_capture_sources,
.unsol_event = alc888_fujitsu_xa3530_unsol_event, .unsol_event = alc_automute_amp_unsol_event,
.init_hook = alc888_fujitsu_xa3530_automute, .init_hook = alc888_fujitsu_xa3530_init_hook,
}, },
[ALC888_LENOVO_SKY] = { [ALC888_LENOVO_SKY] = {
.mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer }, .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
...@@ -9204,8 +9005,8 @@ static struct alc_config_preset alc883_presets[] = { ...@@ -9204,8 +9005,8 @@ static struct alc_config_preset alc883_presets[] = {
.channel_mode = alc883_sixstack_modes, .channel_mode = alc883_sixstack_modes,
.need_dac_fix = 1, .need_dac_fix = 1,
.input_mux = &alc883_lenovo_sky_capture_source, .input_mux = &alc883_lenovo_sky_capture_source,
.unsol_event = alc883_lenovo_sky_unsol_event, .unsol_event = alc_automute_amp_unsol_event,
.init_hook = alc888_lenovo_sky_front_automute, .init_hook = alc888_lenovo_sky_init_hook,
}, },
[ALC888_ASUS_M90V] = { [ALC888_ASUS_M90V] = {
.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
...@@ -9233,7 +9034,7 @@ static struct alc_config_preset alc883_presets[] = { ...@@ -9233,7 +9034,7 @@ static struct alc_config_preset alc883_presets[] = {
.channel_mode = alc883_3ST_2ch_modes, .channel_mode = alc883_3ST_2ch_modes,
.need_dac_fix = 1, .need_dac_fix = 1,
.input_mux = &alc883_asus_eee1601_capture_source, .input_mux = &alc883_asus_eee1601_capture_source,
.unsol_event = alc883_eee1601_unsol_event, .unsol_event = alc_sku_unsol_event,
.init_hook = alc883_eee1601_inithook, .init_hook = alc883_eee1601_inithook,
}, },
[ALC1200_ASUS_P5Q] = { [ALC1200_ASUS_P5Q] = {
...@@ -9666,28 +9467,15 @@ static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = { ...@@ -9666,28 +9467,15 @@ static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
}; };
/* mute/unmute internal speaker according to the hp jack and mute state */ /* mute/unmute internal speaker according to the hp jack and mute state */
static void alc262_hp_t5735_automute(struct hda_codec *codec) static void alc262_hp_t5735_init_hook(struct hda_codec *codec)
{ {
struct alc_spec *spec = codec->spec; struct alc_spec *spec = codec->spec;
unsigned int present;
present = snd_hda_codec_read(codec, 0x15, 0, spec->autocfg.hp_pins[0] = 0x15;
AC_VERB_GET_PIN_SENSE, 0); spec->autocfg.speaker_pins[0] = 0x0c; /* HACK: not actually a pin */
spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0; alc_automute_amp(codec);
snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0, HDA_AMP_MUTE,
spec->jack_present ? HDA_AMP_MUTE : 0);
}
static void alc262_hp_t5735_unsol_event(struct hda_codec *codec,
unsigned int res)
{
if ((res >> 26) != ALC880_HP_EVENT)
return;
alc262_hp_t5735_automute(codec);
} }
#define alc262_hp_t5735_init_hook alc262_hp_t5735_automute
static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = { static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
...@@ -9914,34 +9702,15 @@ static struct hda_verb alc262_tyan_verbs[] = { ...@@ -9914,34 +9702,15 @@ static struct hda_verb alc262_tyan_verbs[] = {
}; };
/* unsolicited event for HP jack sensing */ /* unsolicited event for HP jack sensing */
static void alc262_tyan_automute(struct hda_codec *codec) static void alc262_tyan_init_hook(struct hda_codec *codec)
{ {
unsigned int mute; struct alc_spec *spec = codec->spec;
unsigned int present;
snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0); spec->autocfg.hp_pins[0] = 0x1b;
present = snd_hda_codec_read(codec, 0x1b, 0, spec->autocfg.speaker_pins[0] = 0x15;
AC_VERB_GET_PIN_SENSE, 0); alc_automute_amp(codec);
present = (present & 0x80000000) != 0;
if (present) {
/* mute line output on ATX panel */
snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
HDA_AMP_MUTE, HDA_AMP_MUTE);
} else {
/* unmute line output if necessary */
mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
HDA_AMP_MUTE, mute);
}
} }
static void alc262_tyan_unsol_event(struct hda_codec *codec,
unsigned int res)
{
if ((res >> 26) != ALC880_HP_EVENT)
return;
alc262_tyan_automute(codec);
}
#define alc262_capture_mixer alc882_capture_mixer #define alc262_capture_mixer alc882_capture_mixer
#define alc262_capture_alt_mixer alc882_capture_alt_mixer #define alc262_capture_alt_mixer alc882_capture_alt_mixer
...@@ -10096,35 +9865,24 @@ static void alc262_dmic_automute(struct hda_codec *codec) ...@@ -10096,35 +9865,24 @@ static void alc262_dmic_automute(struct hda_codec *codec)
AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x09); AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x09);
} }
/* toggle speaker-output according to the hp-jack state */
static void alc262_toshiba_s06_speaker_automute(struct hda_codec *codec)
{
unsigned int present;
unsigned char bits;
present = snd_hda_codec_read(codec, 0x15, 0,
AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
bits = present ? 0 : PIN_OUT;
snd_hda_codec_write(codec, 0x14, 0,
AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
}
/* unsolicited event for HP jack sensing */ /* unsolicited event for HP jack sensing */
static void alc262_toshiba_s06_unsol_event(struct hda_codec *codec, static void alc262_toshiba_s06_unsol_event(struct hda_codec *codec,
unsigned int res) unsigned int res)
{ {
if ((res >> 26) == ALC880_HP_EVENT)
alc262_toshiba_s06_speaker_automute(codec);
if ((res >> 26) == ALC880_MIC_EVENT) if ((res >> 26) == ALC880_MIC_EVENT)
alc262_dmic_automute(codec); alc262_dmic_automute(codec);
else
alc_sku_unsol_event(codec, res);
} }
static void alc262_toshiba_s06_init_hook(struct hda_codec *codec) static void alc262_toshiba_s06_init_hook(struct hda_codec *codec)
{ {
alc262_toshiba_s06_speaker_automute(codec); struct alc_spec *spec = codec->spec;
spec->autocfg.hp_pins[0] = 0x15;
spec->autocfg.speaker_pins[0] = 0x14;
alc_automute_pin(codec);
alc262_dmic_automute(codec); alc262_dmic_automute(codec);
} }
...@@ -11135,7 +10893,7 @@ static struct alc_config_preset alc262_presets[] = { ...@@ -11135,7 +10893,7 @@ static struct alc_config_preset alc262_presets[] = {
.num_channel_mode = ARRAY_SIZE(alc262_modes), .num_channel_mode = ARRAY_SIZE(alc262_modes),
.channel_mode = alc262_modes, .channel_mode = alc262_modes,
.input_mux = &alc262_capture_source, .input_mux = &alc262_capture_source,
.unsol_event = alc262_hp_t5735_unsol_event, .unsol_event = alc_automute_amp_unsol_event,
.init_hook = alc262_hp_t5735_init_hook, .init_hook = alc262_hp_t5735_init_hook,
}, },
[ALC262_HP_RP5700] = { [ALC262_HP_RP5700] = {
...@@ -11256,8 +11014,8 @@ static struct alc_config_preset alc262_presets[] = { ...@@ -11256,8 +11014,8 @@ static struct alc_config_preset alc262_presets[] = {
.num_channel_mode = ARRAY_SIZE(alc262_modes), .num_channel_mode = ARRAY_SIZE(alc262_modes),
.channel_mode = alc262_modes, .channel_mode = alc262_modes,
.input_mux = &alc262_capture_source, .input_mux = &alc262_capture_source,
.unsol_event = alc262_tyan_unsol_event, .unsol_event = alc_automute_amp_unsol_event,
.init_hook = alc262_tyan_automute, .init_hook = alc262_tyan_init_hook,
}, },
}; };
...@@ -11646,30 +11404,15 @@ static struct hda_verb alc268_dell_verbs[] = { ...@@ -11646,30 +11404,15 @@ static struct hda_verb alc268_dell_verbs[] = {
}; };
/* mute/unmute internal speaker according to the hp jack and mute state */ /* mute/unmute internal speaker according to the hp jack and mute state */
static void alc268_dell_automute(struct hda_codec *codec) static void alc268_dell_init_hook(struct hda_codec *codec)
{ {
unsigned int present; struct alc_spec *spec = codec->spec;
unsigned int mute;
present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0);
if (present & 0x80000000)
mute = HDA_AMP_MUTE;
else
mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
HDA_AMP_MUTE, mute);
}
static void alc268_dell_unsol_event(struct hda_codec *codec, spec->autocfg.hp_pins[0] = 0x15;
unsigned int res) spec->autocfg.speaker_pins[0] = 0x14;
{ alc_automute_pin(codec);
if ((res >> 26) != ALC880_HP_EVENT)
return;
alc268_dell_automute(codec);
} }
#define alc268_dell_init_hook alc268_dell_automute
static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = { static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
...@@ -11688,16 +11431,6 @@ static struct hda_verb alc267_quanta_il1_verbs[] = { ...@@ -11688,16 +11431,6 @@ static struct hda_verb alc267_quanta_il1_verbs[] = {
{ } { }
}; };
static void alc267_quanta_il1_hp_automute(struct hda_codec *codec)
{
unsigned int present;
present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0)
& AC_PINSENSE_PRESENCE;
snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
present ? 0 : PIN_OUT);
}
static void alc267_quanta_il1_mic_automute(struct hda_codec *codec) static void alc267_quanta_il1_mic_automute(struct hda_codec *codec)
{ {
unsigned int present; unsigned int present;
...@@ -11709,9 +11442,13 @@ static void alc267_quanta_il1_mic_automute(struct hda_codec *codec) ...@@ -11709,9 +11442,13 @@ static void alc267_quanta_il1_mic_automute(struct hda_codec *codec)
present ? 0x00 : 0x01); present ? 0x00 : 0x01);
} }
static void alc267_quanta_il1_automute(struct hda_codec *codec) static void alc267_quanta_il1_init_hook(struct hda_codec *codec)
{ {
alc267_quanta_il1_hp_automute(codec); struct alc_spec *spec = codec->spec;
spec->autocfg.hp_pins[0] = 0x15;
spec->autocfg.speaker_pins[0] = 0x14;
alc_automute_pin(codec);
alc267_quanta_il1_mic_automute(codec); alc267_quanta_il1_mic_automute(codec);
} }
...@@ -11719,12 +11456,12 @@ static void alc267_quanta_il1_unsol_event(struct hda_codec *codec, ...@@ -11719,12 +11456,12 @@ static void alc267_quanta_il1_unsol_event(struct hda_codec *codec,
unsigned int res) unsigned int res)
{ {
switch (res >> 26) { switch (res >> 26) {
case ALC880_HP_EVENT:
alc267_quanta_il1_hp_automute(codec);
break;
case ALC880_MIC_EVENT: case ALC880_MIC_EVENT:
alc267_quanta_il1_mic_automute(codec); alc267_quanta_il1_mic_automute(codec);
break; break;
default:
alc_sku_unsol_event(codec, res);
break;
} }
} }
...@@ -12198,7 +11935,7 @@ static struct alc_config_preset alc268_presets[] = { ...@@ -12198,7 +11935,7 @@ static struct alc_config_preset alc268_presets[] = {
.channel_mode = alc268_modes, .channel_mode = alc268_modes,
.input_mux = &alc268_capture_source, .input_mux = &alc268_capture_source,
.unsol_event = alc267_quanta_il1_unsol_event, .unsol_event = alc267_quanta_il1_unsol_event,
.init_hook = alc267_quanta_il1_automute, .init_hook = alc267_quanta_il1_init_hook,
}, },
[ALC268_3ST] = { [ALC268_3ST] = {
.mixers = { alc268_base_mixer, alc268_capture_alt_mixer, .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
...@@ -12293,7 +12030,7 @@ static struct alc_config_preset alc268_presets[] = { ...@@ -12293,7 +12030,7 @@ static struct alc_config_preset alc268_presets[] = {
.hp_nid = 0x02, .hp_nid = 0x02,
.num_channel_mode = ARRAY_SIZE(alc268_modes), .num_channel_mode = ARRAY_SIZE(alc268_modes),
.channel_mode = alc268_modes, .channel_mode = alc268_modes,
.unsol_event = alc268_dell_unsol_event, .unsol_event = alc_sku_unsol_event,
.init_hook = alc268_dell_init_hook, .init_hook = alc268_dell_init_hook,
.input_mux = &alc268_capture_source, .input_mux = &alc268_capture_source,
}, },
...@@ -14727,19 +14464,6 @@ static struct hda_verb alc861vd_lenovo_unsol_verbs[] = { ...@@ -14727,19 +14464,6 @@ static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
{} {}
}; };
/* toggle speaker-output according to the hp-jack state */
static void alc861vd_lenovo_hp_automute(struct hda_codec *codec)
{
unsigned int present;
unsigned char bits;
present = snd_hda_codec_read(codec, 0x1b, 0,
AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
bits = present ? HDA_AMP_MUTE : 0;
snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
HDA_AMP_MUTE, bits);
}
static void alc861vd_lenovo_mic_automute(struct hda_codec *codec) static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
{ {
unsigned int present; unsigned int present;
...@@ -14752,9 +14476,13 @@ static void alc861vd_lenovo_mic_automute(struct hda_codec *codec) ...@@ -14752,9 +14476,13 @@ static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
HDA_AMP_MUTE, bits); HDA_AMP_MUTE, bits);
} }
static void alc861vd_lenovo_automute(struct hda_codec *codec) static void alc861vd_lenovo_init_hook(struct hda_codec *codec)
{ {
alc861vd_lenovo_hp_automute(codec); struct alc_spec *spec = codec->spec;
spec->autocfg.hp_pins[0] = 0x1b;
spec->autocfg.speaker_pins[0] = 0x14;
alc_automute_amp(codec);
alc861vd_lenovo_mic_automute(codec); alc861vd_lenovo_mic_automute(codec);
} }
...@@ -14762,12 +14490,12 @@ static void alc861vd_lenovo_unsol_event(struct hda_codec *codec, ...@@ -14762,12 +14490,12 @@ static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
unsigned int res) unsigned int res)
{ {
switch (res >> 26) { switch (res >> 26) {
case ALC880_HP_EVENT:
alc861vd_lenovo_hp_automute(codec);
break;
case ALC880_MIC_EVENT: case ALC880_MIC_EVENT:
alc861vd_lenovo_mic_automute(codec); alc861vd_lenovo_mic_automute(codec);
break; break;
default:
alc_automute_amp_unsol_event(codec, res);
break;
} }
} }
...@@ -14817,20 +14545,13 @@ static struct hda_verb alc861vd_dallas_verbs[] = { ...@@ -14817,20 +14545,13 @@ static struct hda_verb alc861vd_dallas_verbs[] = {
}; };
/* toggle speaker-output according to the hp-jack state */ /* toggle speaker-output according to the hp-jack state */
static void alc861vd_dallas_automute(struct hda_codec *codec) static void alc861vd_dallas_init_hook(struct hda_codec *codec)
{ {
unsigned int present; struct alc_spec *spec = codec->spec;
present = snd_hda_codec_read(codec, 0x15, 0,
AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
}
static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int res) spec->autocfg.hp_pins[0] = 0x15;
{ spec->autocfg.speaker_pins[0] = 0x14;
if ((res >> 26) == ALC880_HP_EVENT) alc_automute_amp(codec);
alc861vd_dallas_automute(codec);
} }
#ifdef CONFIG_SND_HDA_POWER_SAVE #ifdef CONFIG_SND_HDA_POWER_SAVE
...@@ -14944,7 +14665,7 @@ static struct alc_config_preset alc861vd_presets[] = { ...@@ -14944,7 +14665,7 @@ static struct alc_config_preset alc861vd_presets[] = {
.channel_mode = alc861vd_3stack_2ch_modes, .channel_mode = alc861vd_3stack_2ch_modes,
.input_mux = &alc861vd_capture_source, .input_mux = &alc861vd_capture_source,
.unsol_event = alc861vd_lenovo_unsol_event, .unsol_event = alc861vd_lenovo_unsol_event,
.init_hook = alc861vd_lenovo_automute, .init_hook = alc861vd_lenovo_init_hook,
}, },
[ALC861VD_DALLAS] = { [ALC861VD_DALLAS] = {
.mixers = { alc861vd_dallas_mixer }, .mixers = { alc861vd_dallas_mixer },
...@@ -14954,8 +14675,8 @@ static struct alc_config_preset alc861vd_presets[] = { ...@@ -14954,8 +14675,8 @@ static struct alc_config_preset alc861vd_presets[] = {
.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
.channel_mode = alc861vd_3stack_2ch_modes, .channel_mode = alc861vd_3stack_2ch_modes,
.input_mux = &alc861vd_dallas_capture_source, .input_mux = &alc861vd_dallas_capture_source,
.unsol_event = alc861vd_dallas_unsol_event, .unsol_event = alc_automute_amp_unsol_event,
.init_hook = alc861vd_dallas_automute, .init_hook = alc861vd_dallas_init_hook,
}, },
[ALC861VD_HP] = { [ALC861VD_HP] = {
.mixers = { alc861vd_hp_mixer }, .mixers = { alc861vd_hp_mixer },
...@@ -14966,8 +14687,8 @@ static struct alc_config_preset alc861vd_presets[] = { ...@@ -14966,8 +14687,8 @@ static struct alc_config_preset alc861vd_presets[] = {
.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
.channel_mode = alc861vd_3stack_2ch_modes, .channel_mode = alc861vd_3stack_2ch_modes,
.input_mux = &alc861vd_hp_capture_source, .input_mux = &alc861vd_hp_capture_source,
.unsol_event = alc861vd_dallas_unsol_event, .unsol_event = alc_automute_amp_unsol_event,
.init_hook = alc861vd_dallas_automute, .init_hook = alc861vd_dallas_init_hook,
}, },
[ALC660VD_ASUS_V1S] = { [ALC660VD_ASUS_V1S] = {
.mixers = { alc861vd_lenovo_mixer }, .mixers = { alc861vd_lenovo_mixer },
...@@ -14982,7 +14703,7 @@ static struct alc_config_preset alc861vd_presets[] = { ...@@ -14982,7 +14703,7 @@ static struct alc_config_preset alc861vd_presets[] = {
.channel_mode = alc861vd_3stack_2ch_modes, .channel_mode = alc861vd_3stack_2ch_modes,
.input_mux = &alc861vd_capture_source, .input_mux = &alc861vd_capture_source,
.unsol_event = alc861vd_lenovo_unsol_event, .unsol_event = alc861vd_lenovo_unsol_event,
.init_hook = alc861vd_lenovo_automute, .init_hook = alc861vd_lenovo_init_hook,
}, },
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment