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,
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;
unsigned int present;
unsigned int hp_nid = spec->autocfg.hp_pins[0];
unsigned int sp_nid = spec->autocfg.speaker_pins[0];
unsigned int nid = spec->autocfg.hp_pins[0];
int i;
/* need to execute and sync at first */
snd_hda_codec_read(codec, hp_nid, 0, AC_VERB_SET_PIN_SENSE, 0);
present = snd_hda_codec_read(codec, hp_nid, 0,
snd_hda_codec_read(codec, nid, 0, AC_VERB_SET_PIN_SENSE, 0);
present = snd_hda_codec_read(codec, nid, 0,
AC_VERB_GET_PIN_SENSE, 0);
spec->jack_present = (present & 0x80000000) != 0;
snd_hda_codec_write(codec, sp_nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
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);
}
}
#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)
res >>= 28;
else
res >>= 26;
if (res == ALC880_HP_EVENT)
alc_sku_automute(codec);
if (res == ALC880_MIC_EVENT)
switch (res) {
case ALC880_HP_EVENT:
alc_automute_pin(codec);
break;
case ALC880_MIC_EVENT:
alc_mic_automute(codec);
break;
}
}
static void alc_inithook(struct hda_codec *codec)
{
alc_sku_automute(codec);
alc_automute_pin(codec);
alc_mic_automute(codec);
}
......@@ -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;
unsigned int bits;
/* Line out presence */
present = snd_hda_codec_read(codec, 0x17, 0,
AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
/* HP out presence */
present = present || snd_hda_codec_read(codec, 0x1b, 0,
AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
bits = present ? HDA_AMP_MUTE : 0;
struct alc_spec *spec = codec->spec;
unsigned int val, 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;
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 */
snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
HDA_AMP_MUTE, bits);
/* Toggle internal bass muting */
snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
HDA_AMP_MUTE, bits);
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);
}
}
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)
{
if (res >> 26 == ALC880_HP_EVENT)
alc888_fujitsu_xa3530_automute(codec);
if (codec->vendor_id == 0x10ec0880)
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
......@@ -1456,22 +1491,13 @@ static struct snd_kcontrol_new alc888_base_mixer[] = {
{ } /* 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;
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);
}
struct alc_spec *spec = codec->spec;
static void alc888_acer_aspire_4930g_unsol_event(struct hda_codec *codec,
unsigned int res)
{
if (res >> 26 == ALC880_HP_EVENT)
alc888_acer_aspire_4930g_automute(codec);
spec->autocfg.hp_pins[0] = 0x15;
spec->autocfg.speaker_pins[0] = 0x14;
alc_automute_amp(codec);
}
/*
......@@ -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 */
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);
}
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);
}
......@@ -2479,24 +2495,22 @@ static void alc880_uniwill_unsol_event(struct hda_codec *codec,
* definition. 4bit tag is placed at 28 bit!
*/
switch (res >> 28) {
case ALC880_HP_EVENT:
alc880_uniwill_hp_automute(codec);
break;
case ALC880_MIC_EVENT:
alc880_uniwill_mic_automute(codec);
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;
unsigned char bits;
struct alc_spec *spec = codec->spec;
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);
spec->autocfg.hp_pins[0] = 0x14;
spec->autocfg.speaker_pins[0] = 0x15;
alc_automute_amp(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,
/* Looks like the unsol event is incompatible with the standard
* 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)
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[] = {
{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
/* 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 */
static void alc880_lg_automute(struct hda_codec *codec)
static void alc880_lg_init_hook(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, 0x17, HDA_OUTPUT, 0,
HDA_AMP_MUTE, bits);
}
struct alc_spec *spec = codec->spec;
static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res)
{
/* Looks like the unsol event is incompatible with the standard
* definition. 4bit tag is placed at 28 bit!
*/
if ((res >> 28) == 0x01)
alc880_lg_automute(codec);
spec->autocfg.hp_pins[0] = 0x1b;
spec->autocfg.speaker_pins[0] = 0x17;
alc_automute_amp(codec);
}
/*
......@@ -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_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
/* 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 */
static void alc880_lg_lw_automute(struct hda_codec *codec)
static void alc880_lg_lw_init_hook(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);
}
struct alc_spec *spec = codec->spec;
static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res)
{
/* Looks like the unsol event is incompatible with the standard
* definition. 4bit tag is placed at 28 bit!
*/
if ((res >> 28) == 0x01)
alc880_lg_lw_automute(codec);
spec->autocfg.hp_pins[0] = 0x1b;
spec->autocfg.speaker_pins[0] = 0x14;
alc_automute_amp(codec);
}
static struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
......@@ -2920,16 +2910,10 @@ static struct hda_verb alc880_medion_rim_init_verbs[] = {
/* toggle speaker-output according to the hp-jack state */
static void alc880_medion_rim_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 ? HDA_AMP_MUTE : 0;
snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
HDA_AMP_MUTE, bits);
if (present)
struct alc_spec *spec = codec->spec;
alc_automute_amp(codec);
/* toggle EAPD */
if (spec->jack_present)
snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
else
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,
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
static struct hda_amp_list alc880_loopbacks[] = {
{ 0x0b, HDA_INPUT, 0 },
......@@ -3803,7 +3796,7 @@ static struct alc_config_preset alc880_presets[] = {
.channel_mode = alc880_2_jack_modes,
.input_mux = &alc880_f1734_capture_source,
.unsol_event = alc880_uniwill_p53_unsol_event,
.init_hook = alc880_uniwill_p53_hp_automute,
.init_hook = alc880_uniwill_p53_init_hook,
},
[ALC880_ASUS] = {
.mixers = { alc880_asus_mixer },
......@@ -3880,7 +3873,7 @@ static struct alc_config_preset alc880_presets[] = {
.need_dac_fix = 1,
.input_mux = &alc880_capture_source,
.unsol_event = alc880_uniwill_unsol_event,
.init_hook = alc880_uniwill_automute,
.init_hook = alc880_uniwill_init_hook,
},
[ALC880_UNIWILL_P53] = {
.mixers = { alc880_uniwill_p53_mixer },
......@@ -3892,7 +3885,7 @@ static struct alc_config_preset alc880_presets[] = {
.channel_mode = alc880_threestack_modes,
.input_mux = &alc880_capture_source,
.unsol_event = alc880_uniwill_p53_unsol_event,
.init_hook = alc880_uniwill_p53_hp_automute,
.init_hook = alc880_uniwill_p53_init_hook,
},
[ALC880_FUJITSU] = {
.mixers = { alc880_fujitsu_mixer },
......@@ -3906,7 +3899,7 @@ static struct alc_config_preset alc880_presets[] = {
.channel_mode = alc880_2_jack_modes,
.input_mux = &alc880_capture_source,
.unsol_event = alc880_uniwill_p53_unsol_event,
.init_hook = alc880_uniwill_p53_hp_automute,
.init_hook = alc880_uniwill_p53_init_hook,
},
[ALC880_CLEVO] = {
.mixers = { alc880_three_stack_mixer },
......@@ -3931,8 +3924,8 @@ static struct alc_config_preset alc880_presets[] = {
.channel_mode = alc880_lg_ch_modes,
.need_dac_fix = 1,
.input_mux = &alc880_lg_capture_source,
.unsol_event = alc880_lg_unsol_event,
.init_hook = alc880_lg_automute,
.unsol_event = alc_automute_amp_unsol_event,
.init_hook = alc880_lg_init_hook,
#ifdef CONFIG_SND_HDA_POWER_SAVE
.loopbacks = alc880_lg_loopbacks,
#endif
......@@ -3947,8 +3940,8 @@ static struct alc_config_preset alc880_presets[] = {
.num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
.channel_mode = alc880_lg_lw_modes,
.input_mux = &alc880_lg_lw_capture_source,
.unsol_event = alc880_lg_lw_unsol_event,
.init_hook = alc880_lg_lw_automute,
.unsol_event = alc_automute_amp_unsol_event,
.init_hook = alc880_lg_lw_init_hook,
},
[ALC880_MEDION_RIM] = {
.mixers = { alc880_medion_rim_mixer },
......@@ -3962,7 +3955,7 @@ static struct alc_config_preset alc880_presets[] = {
.channel_mode = alc880_2_jack_modes,
.input_mux = &alc880_medion_rim_capture_source,
.unsol_event = alc880_medion_rim_unsol_event,
.init_hook = alc880_medion_rim_automute,
.init_hook = alc880_medion_rim_init_hook,
},
#ifdef CONFIG_SND_DEBUG
[ALC880_TEST] = {
......@@ -6666,45 +6659,23 @@ static struct hda_verb alc885_imac24_init_verbs[] = {
};
/* 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;
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);
}
struct alc_spec *spec = codec->spec;
/* Processes unsolicited events. */
static void alc885_imac24_unsol_event(struct hda_codec *codec,
unsigned int res)
{
/* Headphone insertion or removal. */
if ((res >> 26) == ALC880_HP_EVENT)
alc885_imac24_automute(codec);
spec->autocfg.hp_pins[0] = 0x14;
spec->autocfg.speaker_pins[0] = 0x18;
spec->autocfg.speaker_pins[1] = 0x1a;
alc_automute_amp(codec);
}
static void alc885_mbp3_automute(struct hda_codec *codec)
static void alc885_mbp3_init_hook(struct hda_codec *codec)
{
unsigned int present;
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);
struct alc_spec *spec = codec->spec;
}
static void alc885_mbp3_unsol_event(struct hda_codec *codec,
unsigned int res)
{
/* Headphone insertion or removal. */
if ((res >> 26) == ALC880_HP_EVENT)
alc885_mbp3_automute(codec);
spec->autocfg.hp_pins[0] = 0x15;
spec->autocfg.speaker_pins[0] = 0x14;
alc_automute_amp(codec);
}
......@@ -6729,24 +6700,25 @@ static struct hda_verb alc882_targa_verbs[] = {
/* toggle speaker-output according to the hp-jack state */
static void alc882_targa_automute(struct hda_codec *codec)
{
unsigned int present;
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);
struct alc_spec *spec = codec->spec;
alc_automute_amp(codec);
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)
{
/* Looks like the unsol event is incompatible with the standard
* definition. 4bit tag is placed at 26 bit!
*/
if (((res >> 26) == ALC880_HP_EVENT)) {
if ((res >> 26) == ALC880_HP_EVENT)
alc882_targa_automute(codec);
}
}
static struct hda_verb alc882_asus_a7j_verbs[] = {
......@@ -6828,7 +6800,7 @@ static void alc885_macpro_init_hook(struct hda_codec *codec)
static void alc885_imac24_init_hook(struct hda_codec *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[] = {
.input_mux = &alc882_capture_source,
.dig_out_nid = ALC882_DIGOUT_NID,
.dig_in_nid = ALC882_DIGIN_NID,
.unsol_event = alc885_mbp3_unsol_event,
.init_hook = alc885_mbp3_automute,
.unsol_event = alc_automute_amp_unsol_event,
.init_hook = alc885_mbp3_init_hook,
},
[ALC885_MB5] = {
.mixers = { alc885_mb5_mixer },
......@@ -7036,7 +7008,7 @@ static struct alc_config_preset alc882_presets[] = {
.num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
.channel_mode = alc882_ch_modes,
.input_mux = &alc882_capture_source,
.unsol_event = alc885_imac24_unsol_event,
.unsol_event = alc_automute_amp_unsol_event,
.init_hook = alc885_imac24_init_hook,
},
[ALC882_TARGA] = {
......@@ -7053,7 +7025,7 @@ static struct alc_config_preset alc882_presets[] = {
.need_dac_fix = 1,
.input_mux = &alc882_capture_source,
.unsol_event = alc882_targa_unsol_event,
.init_hook = alc882_targa_automute,
.init_hook = alc882_targa_init_hook,
},
[ALC882_ASUS_A7J] = {
.mixers = { alc882_asus_a7j_mixer, alc882_chmode_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_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
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_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
......@@ -8053,16 +8023,14 @@ static struct hda_verb alc883_init_verbs[] = {
};
/* 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,
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, 0x17, HDA_OUTPUT, 0,
HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
spec->autocfg.hp_pins[0] = 0x15;
spec->autocfg.speaker_pins[0] = 0x14;
spec->autocfg.speaker_pins[1] = 0x17;
alc_automute_amp(codec);
}
/* auto-toggle front mic */
......@@ -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[] = {
/* HP */
{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
......@@ -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;
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);
}
struct alc_spec *spec = codec->spec;
static void alc888_3st_hp_unsol_event(struct hda_codec *codec,
unsigned int res)
{
switch (res >> 26) {
case ALC880_HP_EVENT:
alc888_3st_hp_front_automute(codec);
break;
}
spec->autocfg.hp_pins[0] = 0x1b;
spec->autocfg.speaker_pins[0] = 0x14;
spec->autocfg.speaker_pins[1] = 0x16;
spec->autocfg.speaker_pins[2] = 0x18;
alc_automute_amp(codec);
}
static struct hda_verb alc888_3st_hp_verbs[] = {
......@@ -8334,70 +8269,36 @@ static struct hda_verb alc883_medion_md2_verbs[] = {
};
/* 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;
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);
}
struct alc_spec *spec = codec->spec;
static void alc883_medion_md2_unsol_event(struct hda_codec *codec,
unsigned int res)
{
if ((res >> 26) == ALC880_HP_EVENT)
alc883_medion_md2_automute(codec);
spec->autocfg.hp_pins[0] = 0x14;
spec->autocfg.speaker_pins[0] = 0x15;
alc_automute_amp(codec);
}
/* 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 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;
bits = present ? HDA_AMP_MUTE : 0;
snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
HDA_AMP_MUTE, bits);
snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
present ? 1 : 3);
snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
}
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)
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);
}
struct alc_spec *spec = codec->spec;
static void alc883_clevo_m720_automute(struct hda_codec *codec)
{
alc883_clevo_m720_hp_automute(codec);
spec->autocfg.hp_pins[0] = 0x15;
spec->autocfg.speaker_pins[0] = 0x14;
alc_automute_amp(codec);
alc883_clevo_m720_mic_automute(codec);
}
......@@ -8405,52 +8306,32 @@ static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
unsigned int res)
{
switch (res >> 26) {
case ALC880_HP_EVENT:
alc883_clevo_m720_hp_automute(codec);
break;
case ALC880_MIC_EVENT:
alc883_clevo_m720_mic_automute(codec);
break;
default:
alc_automute_amp_unsol_event(codec, res);
break;
}
}
/* 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;
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);
}
struct alc_spec *spec = codec->spec;
static void alc883_2ch_fujitsu_pi2515_unsol_event(struct hda_codec *codec,
unsigned int res)
{
if ((res >> 26) == ALC880_HP_EVENT)
alc883_2ch_fujitsu_pi2515_automute(codec);
spec->autocfg.hp_pins[0] = 0x14;
spec->autocfg.speaker_pins[0] = 0x15;
alc_automute_amp(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;
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);
}
struct alc_spec *spec = codec->spec;
static void alc883_haier_w66_unsol_event(struct hda_codec *codec,
unsigned int res)
{
if ((res >> 26) == ALC880_HP_EVENT)
alc883_haier_w66_automute(codec);
spec->autocfg.hp_pins[0] = 0x1b;
spec->autocfg.speaker_pins[0] = 0x14;
alc_automute_amp(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,
}
/* 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;
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);
}
struct alc_spec *spec = codec->spec;
static void alc883_acer_aspire_unsol_event(struct hda_codec *codec,
unsigned int res)
{
if ((res >> 26) == ALC880_HP_EVENT)
alc883_acer_aspire_automute(codec);
spec->autocfg.hp_pins[0] = 0x14;
spec->autocfg.speaker_pins[0] = 0x15;
spec->autocfg.speaker_pins[1] = 0x16;
alc_automute_amp(codec);
}
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;
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);
}
struct alc_spec *spec = codec->spec;
static void alc888_6st_dell_unsol_event(struct hda_codec *codec,
unsigned int res)
{
switch (res >> 26) {
case ALC880_HP_EVENT:
/* printk(KERN_DEBUG "hp_event\n"); */
alc888_6st_dell_front_automute(codec);
break;
}
spec->autocfg.hp_pins[0] = 0x1b;
spec->autocfg.speaker_pins[0] = 0x14;
spec->autocfg.speaker_pins[1] = 0x15;
spec->autocfg.speaker_pins[2] = 0x16;
spec->autocfg.speaker_pins[3] = 0x17;
alc_automute_amp(codec);
}
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;
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);
}
}
struct alc_spec *spec = codec->spec;
static void alc883_lenovo_sky_unsol_event(struct hda_codec *codec,
unsigned int res)
{
if ((res >> 26) == ALC880_HP_EVENT)
alc888_lenovo_sky_front_automute(codec);
spec->autocfg.hp_pins[0] = 0x1b;
spec->autocfg.speaker_pins[0] = 0x14;
spec->autocfg.speaker_pins[1] = 0x15;
spec->autocfg.speaker_pins[2] = 0x16;
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)
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;
unsigned char bits;
struct alc_spec *spec = codec->spec;
present = snd_hda_codec_read(codec, 0x1b, 0,
AC_VERB_GET_PIN_SENSE, 0)
& AC_PINSENSE_PRESENCE;
bits = present ? 0 : PIN_OUT;
snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
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);
spec->autocfg.hp_pins[0] = 0x1b;
spec->autocfg.speaker_pins[0] = 0x14;
spec->autocfg.speaker_pins[1] = 0x15;
spec->autocfg.speaker_pins[2] = 0x16;
alc_automute_pin(codec);
}
static void alc883_mode2_unsol_event(struct hda_codec *codec,
unsigned int res)
{
switch (res >> 26) {
case ALC880_HP_EVENT:
alc883_M90V_speaker_automute(codec);
break;
case ALC880_MIC_EVENT:
alc883_nb_mic_automute(codec);
break;
default:
alc_sku_unsol_event(codec, res);
break;
}
}
static void alc883_mode2_inithook(struct hda_codec *codec)
{
alc883_M90V_speaker_automute(codec);
alc883_M90V_init_hook(codec);
alc883_nb_mic_automute(codec);
}
......@@ -8731,32 +8551,13 @@ static struct hda_verb alc888_asus_eee1601_verbs[] = {
{ } /* 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)
{
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
......@@ -8969,7 +8770,7 @@ static struct alc_config_preset alc883_presets[] = {
.need_dac_fix = 1,
.input_mux = &alc883_capture_source,
.unsol_event = alc883_tagra_unsol_event,
.init_hook = alc883_tagra_automute,
.init_hook = alc883_tagra_init_hook,
},
[ALC883_TARGA_2ch_DIG] = {
.mixers = { alc883_tagra_2ch_mixer},
......@@ -8983,7 +8784,7 @@ static struct alc_config_preset alc883_presets[] = {
.channel_mode = alc883_3ST_2ch_modes,
.input_mux = &alc883_capture_source,
.unsol_event = alc883_tagra_unsol_event,
.init_hook = alc883_tagra_automute,
.init_hook = alc883_tagra_init_hook,
},
[ALC883_ACER] = {
.mixers = { alc883_base_mixer },
......@@ -9008,8 +8809,8 @@ static struct alc_config_preset alc883_presets[] = {
.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
.channel_mode = alc883_3ST_2ch_modes,
.input_mux = &alc883_capture_source,
.unsol_event = alc883_acer_aspire_unsol_event,
.init_hook = alc883_acer_aspire_automute,
.unsol_event = alc_automute_amp_unsol_event,
.init_hook = alc883_acer_aspire_init_hook,
},
[ALC888_ACER_ASPIRE_4930G] = {
.mixers = { alc888_base_mixer,
......@@ -9028,8 +8829,8 @@ static struct alc_config_preset alc883_presets[] = {
.num_mux_defs =
ARRAY_SIZE(alc888_2_capture_sources),
.input_mux = alc888_2_capture_sources,
.unsol_event = alc888_acer_aspire_4930g_unsol_event,
.init_hook = alc888_acer_aspire_4930g_automute,
.unsol_event = alc_automute_amp_unsol_event,
.init_hook = alc888_acer_aspire_4930g_init_hook,
},
[ALC883_MEDION] = {
.mixers = { alc883_fivestack_mixer,
......@@ -9053,8 +8854,8 @@ static struct alc_config_preset alc883_presets[] = {
.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
.channel_mode = alc883_3ST_2ch_modes,
.input_mux = &alc883_capture_source,
.unsol_event = alc883_medion_md2_unsol_event,
.init_hook = alc883_medion_md2_automute,
.unsol_event = alc_automute_amp_unsol_event,
.init_hook = alc883_medion_md2_init_hook,
},
[ALC883_LAPTOP_EAPD] = {
.mixers = { alc883_base_mixer },
......@@ -9075,7 +8876,7 @@ static struct alc_config_preset alc883_presets[] = {
.channel_mode = alc883_3ST_2ch_modes,
.input_mux = &alc883_capture_source,
.unsol_event = alc883_clevo_m720_unsol_event,
.init_hook = alc883_clevo_m720_automute,
.init_hook = alc883_clevo_m720_init_hook,
},
[ALC883_LENOVO_101E_2ch] = {
.mixers = { alc883_lenovo_101e_2ch_mixer},
......@@ -9099,8 +8900,8 @@ static struct alc_config_preset alc883_presets[] = {
.channel_mode = alc883_3ST_2ch_modes,
.need_dac_fix = 1,
.input_mux = &alc883_lenovo_nb0763_capture_source,
.unsol_event = alc883_medion_md2_unsol_event,
.init_hook = alc883_medion_md2_automute,
.unsol_event = alc_automute_amp_unsol_event,
.init_hook = alc883_medion_md2_init_hook,
},
[ALC888_LENOVO_MS7195_DIG] = {
.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
......@@ -9124,8 +8925,8 @@ static struct alc_config_preset alc883_presets[] = {
.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
.channel_mode = alc883_3ST_2ch_modes,
.input_mux = &alc883_capture_source,
.unsol_event = alc883_haier_w66_unsol_event,
.init_hook = alc883_haier_w66_automute,
.unsol_event = alc_automute_amp_unsol_event,
.init_hook = alc883_haier_w66_init_hook,
},
[ALC888_3ST_HP] = {
.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
......@@ -9136,8 +8937,8 @@ static struct alc_config_preset alc883_presets[] = {
.channel_mode = alc888_3st_hp_modes,
.need_dac_fix = 1,
.input_mux = &alc883_capture_source,
.unsol_event = alc888_3st_hp_unsol_event,
.init_hook = alc888_3st_hp_front_automute,
.unsol_event = alc_automute_amp_unsol_event,
.init_hook = alc888_3st_hp_init_hook,
},
[ALC888_6ST_DELL] = {
.mixers = { alc883_base_mixer, alc883_chmode_mixer },
......@@ -9149,8 +8950,8 @@ static struct alc_config_preset alc883_presets[] = {
.num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
.channel_mode = alc883_sixstack_modes,
.input_mux = &alc883_capture_source,
.unsol_event = alc888_6st_dell_unsol_event,
.init_hook = alc888_6st_dell_front_automute,
.unsol_event = alc_automute_amp_unsol_event,
.init_hook = alc888_6st_dell_init_hook,
},
[ALC883_MITAC] = {
.mixers = { alc883_mitac_mixer },
......@@ -9160,8 +8961,8 @@ static struct alc_config_preset alc883_presets[] = {
.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
.channel_mode = alc883_3ST_2ch_modes,
.input_mux = &alc883_capture_source,
.unsol_event = alc883_mitac_unsol_event,
.init_hook = alc883_mitac_automute,
.unsol_event = alc_automute_amp_unsol_event,
.init_hook = alc883_mitac_init_hook,
},
[ALC883_FUJITSU_PI2515] = {
.mixers = { alc883_2ch_fujitsu_pi2515_mixer },
......@@ -9173,8 +8974,8 @@ static struct alc_config_preset alc883_presets[] = {
.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
.channel_mode = alc883_3ST_2ch_modes,
.input_mux = &alc883_fujitsu_pi2515_capture_source,
.unsol_event = alc883_2ch_fujitsu_pi2515_unsol_event,
.init_hook = alc883_2ch_fujitsu_pi2515_automute,
.unsol_event = alc_automute_amp_unsol_event,
.init_hook = alc883_2ch_fujitsu_pi2515_init_hook,
},
[ALC888_FUJITSU_XA3530] = {
.mixers = { alc888_base_mixer, alc883_chmode_mixer },
......@@ -9191,8 +8992,8 @@ static struct alc_config_preset alc883_presets[] = {
.num_mux_defs =
ARRAY_SIZE(alc888_2_capture_sources),
.input_mux = alc888_2_capture_sources,
.unsol_event = alc888_fujitsu_xa3530_unsol_event,
.init_hook = alc888_fujitsu_xa3530_automute,
.unsol_event = alc_automute_amp_unsol_event,
.init_hook = alc888_fujitsu_xa3530_init_hook,
},
[ALC888_LENOVO_SKY] = {
.mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
......@@ -9204,8 +9005,8 @@ static struct alc_config_preset alc883_presets[] = {
.channel_mode = alc883_sixstack_modes,
.need_dac_fix = 1,
.input_mux = &alc883_lenovo_sky_capture_source,
.unsol_event = alc883_lenovo_sky_unsol_event,
.init_hook = alc888_lenovo_sky_front_automute,
.unsol_event = alc_automute_amp_unsol_event,
.init_hook = alc888_lenovo_sky_init_hook,
},
[ALC888_ASUS_M90V] = {
.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
......@@ -9233,7 +9034,7 @@ static struct alc_config_preset alc883_presets[] = {
.channel_mode = alc883_3ST_2ch_modes,
.need_dac_fix = 1,
.input_mux = &alc883_asus_eee1601_capture_source,
.unsol_event = alc883_eee1601_unsol_event,
.unsol_event = alc_sku_unsol_event,
.init_hook = alc883_eee1601_inithook,
},
[ALC1200_ASUS_P5Q] = {
......@@ -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 */
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;
unsigned int present;
present = snd_hda_codec_read(codec, 0x15, 0,
AC_VERB_GET_PIN_SENSE, 0);
spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
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);
spec->autocfg.hp_pins[0] = 0x15;
spec->autocfg.speaker_pins[0] = 0x0c; /* HACK: not actually a pin */
alc_automute_amp(codec);
}
#define alc262_hp_t5735_init_hook alc262_hp_t5735_automute
static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
......@@ -9914,34 +9702,15 @@ static struct hda_verb alc262_tyan_verbs[] = {
};
/* 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;
unsigned int present;
struct alc_spec *spec = codec->spec;
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 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);
}
spec->autocfg.hp_pins[0] = 0x1b;
spec->autocfg.speaker_pins[0] = 0x15;
alc_automute_amp(codec);
}
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_alt_mixer alc882_capture_alt_mixer
......@@ -10096,35 +9865,24 @@ static void alc262_dmic_automute(struct hda_codec *codec)
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 */
static void alc262_toshiba_s06_unsol_event(struct hda_codec *codec,
unsigned int res)
{
if ((res >> 26) == ALC880_HP_EVENT)
alc262_toshiba_s06_speaker_automute(codec);
if ((res >> 26) == ALC880_MIC_EVENT)
alc262_dmic_automute(codec);
else
alc_sku_unsol_event(codec, res);
}
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);
}
......@@ -11135,7 +10893,7 @@ static struct alc_config_preset alc262_presets[] = {
.num_channel_mode = ARRAY_SIZE(alc262_modes),
.channel_mode = alc262_modes,
.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,
},
[ALC262_HP_RP5700] = {
......@@ -11256,8 +11014,8 @@ static struct alc_config_preset alc262_presets[] = {
.num_channel_mode = ARRAY_SIZE(alc262_modes),
.channel_mode = alc262_modes,
.input_mux = &alc262_capture_source,
.unsol_event = alc262_tyan_unsol_event,
.init_hook = alc262_tyan_automute,
.unsol_event = alc_automute_amp_unsol_event,
.init_hook = alc262_tyan_init_hook,
},
};
......@@ -11646,30 +11404,15 @@ static struct hda_verb alc268_dell_verbs[] = {
};
/* 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;
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);
}
struct alc_spec *spec = codec->spec;
static void alc268_dell_unsol_event(struct hda_codec *codec,
unsigned int res)
{
if ((res >> 26) != ALC880_HP_EVENT)
return;
alc268_dell_automute(codec);
spec->autocfg.hp_pins[0] = 0x15;
spec->autocfg.speaker_pins[0] = 0x14;
alc_automute_pin(codec);
}
#define alc268_dell_init_hook alc268_dell_automute
static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 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[] = {
{ }
};
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)
{
unsigned int present;
......@@ -11709,9 +11442,13 @@ static void alc267_quanta_il1_mic_automute(struct hda_codec *codec)
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);
}
......@@ -11719,12 +11456,12 @@ static void alc267_quanta_il1_unsol_event(struct hda_codec *codec,
unsigned int res)
{
switch (res >> 26) {
case ALC880_HP_EVENT:
alc267_quanta_il1_hp_automute(codec);
break;
case ALC880_MIC_EVENT:
alc267_quanta_il1_mic_automute(codec);
break;
default:
alc_sku_unsol_event(codec, res);
break;
}
}
......@@ -12198,7 +11935,7 @@ static struct alc_config_preset alc268_presets[] = {
.channel_mode = alc268_modes,
.input_mux = &alc268_capture_source,
.unsol_event = alc267_quanta_il1_unsol_event,
.init_hook = alc267_quanta_il1_automute,
.init_hook = alc267_quanta_il1_init_hook,
},
[ALC268_3ST] = {
.mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
......@@ -12293,7 +12030,7 @@ static struct alc_config_preset alc268_presets[] = {
.hp_nid = 0x02,
.num_channel_mode = ARRAY_SIZE(alc268_modes),
.channel_mode = alc268_modes,
.unsol_event = alc268_dell_unsol_event,
.unsol_event = alc_sku_unsol_event,
.init_hook = alc268_dell_init_hook,
.input_mux = &alc268_capture_source,
},
......@@ -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)
{
unsigned int present;
......@@ -14752,9 +14476,13 @@ static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
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);
}
......@@ -14762,12 +14490,12 @@ static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
unsigned int res)
{
switch (res >> 26) {
case ALC880_HP_EVENT:
alc861vd_lenovo_hp_automute(codec);
break;
case ALC880_MIC_EVENT:
alc861vd_lenovo_mic_automute(codec);
break;
default:
alc_automute_amp_unsol_event(codec, res);
break;
}
}
......@@ -14817,20 +14545,13 @@ static struct hda_verb alc861vd_dallas_verbs[] = {
};
/* 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;
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);
}
struct alc_spec *spec = codec->spec;
static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int res)
{
if ((res >> 26) == ALC880_HP_EVENT)
alc861vd_dallas_automute(codec);
spec->autocfg.hp_pins[0] = 0x15;
spec->autocfg.speaker_pins[0] = 0x14;
alc_automute_amp(codec);
}
#ifdef CONFIG_SND_HDA_POWER_SAVE
......@@ -14944,7 +14665,7 @@ static struct alc_config_preset alc861vd_presets[] = {
.channel_mode = alc861vd_3stack_2ch_modes,
.input_mux = &alc861vd_capture_source,
.unsol_event = alc861vd_lenovo_unsol_event,
.init_hook = alc861vd_lenovo_automute,
.init_hook = alc861vd_lenovo_init_hook,
},
[ALC861VD_DALLAS] = {
.mixers = { alc861vd_dallas_mixer },
......@@ -14954,8 +14675,8 @@ static struct alc_config_preset alc861vd_presets[] = {
.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
.channel_mode = alc861vd_3stack_2ch_modes,
.input_mux = &alc861vd_dallas_capture_source,
.unsol_event = alc861vd_dallas_unsol_event,
.init_hook = alc861vd_dallas_automute,
.unsol_event = alc_automute_amp_unsol_event,
.init_hook = alc861vd_dallas_init_hook,
},
[ALC861VD_HP] = {
.mixers = { alc861vd_hp_mixer },
......@@ -14966,8 +14687,8 @@ static struct alc_config_preset alc861vd_presets[] = {
.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
.channel_mode = alc861vd_3stack_2ch_modes,
.input_mux = &alc861vd_hp_capture_source,
.unsol_event = alc861vd_dallas_unsol_event,
.init_hook = alc861vd_dallas_automute,
.unsol_event = alc_automute_amp_unsol_event,
.init_hook = alc861vd_dallas_init_hook,
},
[ALC660VD_ASUS_V1S] = {
.mixers = { alc861vd_lenovo_mixer },
......@@ -14982,7 +14703,7 @@ static struct alc_config_preset alc861vd_presets[] = {
.channel_mode = alc861vd_3stack_2ch_modes,
.input_mux = &alc861vd_capture_source,
.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