--- patch_analog.c.old 2007-03-25 22:13:06.000000000 -0300 +++ patch_analog.c 2007-03-25 17:01:03.000000000 -0300 @@ -613,18 +613,62 @@ struct hda_codec *codec = snd_kcontrol_chip(kcontrol); long *valp = ucontrol->value.integer.value; int change; + unsigned int present; + + present = snd_hda_codec_read(codec, 0x1a, 0, + AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; change = snd_hda_codec_amp_update(codec, 0x1a, 0, HDA_OUTPUT, 0, 0x80, valp[0] ? 0 : 0x80); change |= snd_hda_codec_amp_update(codec, 0x1a, 1, HDA_OUTPUT, 0, 0x80, valp[1] ? 0 : 0x80); snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0, - 0x80, valp[0] ? 0 : 0x80); + 0x80, (valp[0] && present) ? 0 : 0x80); snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0, - 0x80, valp[1] ? 0 : 0x80); + 0x80, (valp[1] && present) ? 0 : 0x80); return change; } +/* mute internal speakers if HP is plugged */ +static void ad1986a_laptop_eapd_automute(struct hda_codec *codec) +{ + unsigned int present, sw; + + present = snd_hda_codec_read(codec, 0x1a, 0, + AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; + + /* + * TODO: get kcontrol value for "Master Playback Switch" and + * enable Line-Out only if (present && sw), where sw means "unmute" + * + * Currently the Line-Out is unmuted when we unplug HP jack, even if we + * asked to mute Master Volume. + */ + sw = 1; + + /* Line-Out */ + snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0, + 0x80, (present && sw) ? 0 : 0x80); + snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0, + 0x80, (present && sw) ? 0 : 0x80); +} + +/* unsolicited event for HP jack sensing */ +static void ad1986a_laptop_eapd_unsol_event(struct hda_codec *codec, + unsigned int res) +{ + ad1986a_laptop_eapd_automute(codec); +} + +/* initialize jack-sensing, too */ +static int ad1986a_laptop_eapd_init(struct hda_codec *codec) +{ + ad198x_init(codec); + ad1986a_laptop_eapd_automute(codec); + return 0; +} + + static struct hda_input_mux ad1986a_laptop_eapd_capture_source = { .num_items = 3, .items = { @@ -733,6 +777,7 @@ {0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, + {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN}, { } /* end */ }; @@ -895,6 +940,9 @@ spec->multiout.dac_nids = ad1986a_laptop_dac_nids; spec->multiout.dig_out_nid = 0; spec->input_mux = &ad1986a_laptop_eapd_capture_source; +/* add some ad1986a specific operations */ + codec->patch_ops.init = ad1986a_laptop_eapd_init; + codec->patch_ops.unsol_event = ad1986a_laptop_eapd_unsol_event; break; }