ALSA: hda - Turn on EAPD only if available for Realtek codecs
Takashi Iwai [Tue, 19 Jan 2010 14:46:37 +0000 (15:46 +0100)]
Some codecs disable widgets used for output pins and reserve as vendor-
spec widgets.  Thus we need to check the widget type and pin cap before
actually sending SET_EAPD verbs in the auto-configuration mode.

Signed-off-by: Takashi Iwai <tiwai@suse.de>

sound/pci/hda/patch_realtek.c

index 79cdae3..6ae610c 100644 (file)
@@ -1093,6 +1093,16 @@ static void alc889_coef_init(struct hda_codec *codec)
        snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, tmp|0x2010);
 }
 
+/* turn on/off EAPD control (only if available) */
+static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on)
+{
+       if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
+               return;
+       if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)
+               snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
+                                   on ? 2 : 0);
+}
+
 static void alc_auto_init_amp(struct hda_codec *codec, int type)
 {
        unsigned int tmp;
@@ -1110,25 +1120,22 @@ static void alc_auto_init_amp(struct hda_codec *codec, int type)
        case ALC_INIT_DEFAULT:
                switch (codec->vendor_id) {
                case 0x10ec0260:
-                       snd_hda_codec_write(codec, 0x0f, 0,
-                                           AC_VERB_SET_EAPD_BTLENABLE, 2);
-                       snd_hda_codec_write(codec, 0x10, 0,
-                                           AC_VERB_SET_EAPD_BTLENABLE, 2);
+                       set_eapd(codec, 0x0f, 1);
+                       set_eapd(codec, 0x10, 1);
                        break;
                case 0x10ec0262:
                case 0x10ec0267:
                case 0x10ec0268:
                case 0x10ec0269:
+               case 0x10ec0270:
                case 0x10ec0272:
                case 0x10ec0660:
                case 0x10ec0662:
                case 0x10ec0663:
                case 0x10ec0862:
                case 0x10ec0889:
-                       snd_hda_codec_write(codec, 0x14, 0,
-                                           AC_VERB_SET_EAPD_BTLENABLE, 2);
-                       snd_hda_codec_write(codec, 0x15, 0,
-                                           AC_VERB_SET_EAPD_BTLENABLE, 2);
+                       set_eapd(codec, 0x14, 1);
+                       set_eapd(codec, 0x15, 1);
                        break;
                }
                switch (codec->vendor_id) {
@@ -1836,10 +1843,8 @@ static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec)
 #ifdef CONFIG_SND_HDA_POWER_SAVE
 static void alc889_power_eapd(struct hda_codec *codec, int power)
 {
-       snd_hda_codec_write(codec, 0x14, 0,
-                           AC_VERB_SET_EAPD_BTLENABLE, power ? 2 : 0);
-       snd_hda_codec_write(codec, 0x15, 0,
-                           AC_VERB_SET_EAPD_BTLENABLE, power ? 2 : 0);
+       set_eapd(codec, 0x14, power);
+       set_eapd(codec, 0x15, power);
 }
 #endif