On Monday 15 October 2007 23:34:21 Peter Skensved wrote: > > Hmm, the code logic looks correct to me. If HP jack is present, the > > internal speaker should be muted. Otherwise it follows the state of > > HP jack (muted/unmuted, that acts as a master switch) Code logic is broken. Internal speakers muted while jack unplugged and unmuted while it's plugged. See attached original patch.
--- alsa-driver-1.0.14-orig/alsa-kernel/pci/hda/patch_analog.c 2007-06-04 02:28:53.000000000 +0000 +++ alsa-driver-1.0.14/alsa-kernel/pci/hda/patch_analog.c 2007-08-29 00:32:52.000000000 +0000 @@ -497,6 +497,7 @@ /* * mixers */ + static struct snd_kcontrol_new ad1986a_mixers[] = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, @@ -628,18 +629,65 @@ 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; + /* HP (0x1a) */ 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); + + /* Line-Out (0x1b) */ 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 = { @@ -749,6 +797,8 @@ {0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, + /* HP pin event */ + {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN}, { } /* end */ }; @@ -913,6 +963,10 @@ 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; case AD1986A_ULTRA: spec->mixers[0] = ad1986a_laptop_eapd_mixers;
_______________________________________________ Alsa-devel mailing list Alsa-devel@xxxxxxxxxxxxxxxx http://mailman.alsa-project.org/mailman/listinfo/alsa-devel