]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - sound/pci/hda/patch_conexant.c
Merge branch 'fix/hda' into topic/hda
[mv-sheeva.git] / sound / pci / hda / patch_conexant.c
index 6361f752b5f35cfddff7f8423f0d5d185a9003d8..e584b3dd7aa8826558bf3b601f985886e1832fbc 100644 (file)
@@ -2111,25 +2111,35 @@ static struct hda_channel_mode cxt5066_modes[1] = {
        { 2, NULL },
 };
 
+#define HP_PRESENT_PORT_A      (1 << 0)
+#define HP_PRESENT_PORT_D      (1 << 1)
+#define hp_port_a_present(spec)        ((spec)->hp_present & HP_PRESENT_PORT_A)
+#define hp_port_d_present(spec)        ((spec)->hp_present & HP_PRESENT_PORT_D)
+
 static void cxt5066_update_speaker(struct hda_codec *codec)
 {
        struct conexant_spec *spec = codec->spec;
        unsigned int pinctl;
 
-       snd_printdd("CXT5066: update speaker, hp_present=%d\n",
-               spec->hp_present);
+       snd_printdd("CXT5066: update speaker, hp_present=%d, cur_eapd=%d\n",
+                   spec->hp_present, spec->cur_eapd);
 
        /* Port A (HP) */
-       pinctl = ((spec->hp_present & 1) && spec->cur_eapd) ? PIN_HP : 0;
+       pinctl = (hp_port_a_present(spec) && spec->cur_eapd) ? PIN_HP : 0;
        snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
                        pinctl);
 
        /* Port D (HP/LO) */
-       pinctl = ((spec->hp_present & 2) && spec->cur_eapd)
-               ? spec->port_d_mode : 0;
-       /* Mute if Port A is connected on Thinkpad */
-       if (spec->thinkpad && (spec->hp_present & 1))
-               pinctl = 0;
+       pinctl = spec->cur_eapd ? spec->port_d_mode : 0;
+       if (spec->dell_automute || spec->thinkpad) {
+               /* Mute if Port A is connected */
+               if (hp_port_a_present(spec))
+                       pinctl = 0;
+       } else {
+               /* Thinkpad/Dell doesn't give pin-D status */
+               if (!hp_port_d_present(spec))
+                       pinctl = 0;
+       }
        snd_hda_codec_write(codec, 0x1c, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
                        pinctl);
 
@@ -2137,14 +2147,6 @@ static void cxt5066_update_speaker(struct hda_codec *codec)
        pinctl = (!spec->hp_present && spec->cur_eapd) ? PIN_OUT : 0;
        snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
                        pinctl);
-
-       if (spec->dell_automute) {
-               /* DELL AIO Port Rule: PortA > PortD > IntSpk */
-               pinctl = (!(spec->hp_present & 1) && spec->cur_eapd)
-                       ? PIN_OUT : 0;
-               snd_hda_codec_write(codec, 0x1c, 0,
-                       AC_VERB_SET_PIN_WIDGET_CONTROL, pinctl);
-       }
 }
 
 /* turn on/off EAPD (+ mute HP) as a master switch */
@@ -2378,8 +2380,8 @@ static void cxt5066_hp_automute(struct hda_codec *codec)
        /* Port D */
        portD = snd_hda_jack_detect(codec, 0x1c);
 
-       spec->hp_present = !!(portA);
-       spec->hp_present |= portD ? 2 : 0;
+       spec->hp_present = portA ? HP_PRESENT_PORT_A : 0;
+       spec->hp_present |= portD ? HP_PRESENT_PORT_D : 0;
        snd_printdd("CXT5066: hp automute portA=%x portD=%x present=%d\n",
                portA, portD, spec->hp_present);
        cxt5066_update_speaker(codec);
@@ -3095,11 +3097,11 @@ static const char *cxt5066_models[CXT5066_MODELS] = {
 static struct snd_pci_quirk cxt5066_cfg_tbl[] = {
        SND_PCI_QUIRK_MASK(0x1025, 0xff00, 0x0400, "Acer", CXT5066_IDEAPAD),
        SND_PCI_QUIRK(0x1028, 0x02d8, "Dell Vostro", CXT5066_DELL_VOSTRO),
-       SND_PCI_QUIRK(0x1028, 0x02f5, "Dell",
-                     CXT5066_DELL_LAPTOP),
+       SND_PCI_QUIRK(0x1028, 0x02f5, "Dell Vostro 320", CXT5066_IDEAPAD),
        SND_PCI_QUIRK(0x1028, 0x0402, "Dell Vostro", CXT5066_DELL_VOSTRO),
        SND_PCI_QUIRK(0x1028, 0x0408, "Dell Inspiron One 19T", CXT5066_IDEAPAD),
        SND_PCI_QUIRK(0x103c, 0x360b, "HP G60", CXT5066_HP_LAPTOP),
+       SND_PCI_QUIRK(0x1043, 0x13f3, "Asus A52J", CXT5066_HP_LAPTOP),
        SND_PCI_QUIRK(0x1179, 0xff1e, "Toshiba Satellite C650D", CXT5066_IDEAPAD),
        SND_PCI_QUIRK(0x1179, 0xff50, "Toshiba Satellite P500-PSPGSC-01800T", CXT5066_OLPC_XO_1_5),
        SND_PCI_QUIRK(0x1179, 0xffe0, "Toshiba Satellite Pro T130-15F", CXT5066_OLPC_XO_1_5),
@@ -3108,8 +3110,10 @@ static struct snd_pci_quirk cxt5066_cfg_tbl[] = {
        SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT5066_OLPC_XO_1_5),
        SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400s", CXT5066_THINKPAD),
        SND_PCI_QUIRK(0x17aa, 0x21b2, "Thinkpad X100e", CXT5066_IDEAPAD),
+       SND_PCI_QUIRK(0x17aa, 0x21c5, "Thinkpad Edge 13", CXT5066_THINKPAD),
        SND_PCI_QUIRK(0x17aa, 0x21b3, "Thinkpad Edge 13 (197)", CXT5066_IDEAPAD),
        SND_PCI_QUIRK(0x17aa, 0x21b4, "Thinkpad Edge", CXT5066_IDEAPAD),
+       SND_PCI_QUIRK(0x17aa, 0x21c8, "Thinkpad Edge 11", CXT5066_IDEAPAD),
        SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo Thinkpad", CXT5066_THINKPAD),
        SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo G series", CXT5066_IDEAPAD),
        SND_PCI_QUIRK(0x17aa, 0x390a, "Lenovo S10-3t", CXT5066_IDEAPAD),
@@ -3419,6 +3423,9 @@ static void cx_auto_hp_automute(struct hda_codec *codec)
                                    AC_VERB_SET_PIN_WIDGET_CONTROL,
                                    present ? 0 : PIN_OUT);
        }
+       for (i = 0; !present && i < cfg->line_outs; i++)
+               if (snd_hda_jack_detect(codec, cfg->line_out_pins[i]))
+                       present = 1;
        for (i = 0; i < cfg->speaker_outs; i++) {
                snd_hda_codec_write(codec, cfg->speaker_pins[i], 0,
                                    AC_VERB_SET_PIN_WIDGET_CONTROL,