ALSA: hda - Use auto-parser for HP laptops with cx20459 codec
[pandora-kernel.git] / sound / pci / hda / patch_conexant.c
index 0c8b5a1..8a32a69 100644 (file)
 #include <linux/delay.h>
 #include <linux/slab.h>
 #include <linux/pci.h>
+#include <linux/module.h>
 #include <sound/core.h>
 #include <sound/jack.h>
 
 #include "hda_codec.h"
 #include "hda_local.h"
 #include "hda_beep.h"
+#include "hda_jack.h"
 
 #define CXT_PIN_DIR_IN              0x00
 #define CXT_PIN_DIR_OUT             0x01
@@ -414,40 +416,6 @@ static int conexant_mux_enum_put(struct snd_kcontrol *kcontrol,
                                     &spec->cur_mux[adc_idx]);
 }
 
-static int conexant_init_jacks(struct hda_codec *codec)
-{
-#ifdef CONFIG_SND_HDA_INPUT_JACK
-       struct conexant_spec *spec = codec->spec;
-       int i;
-
-       for (i = 0; i < spec->num_init_verbs; i++) {
-               const struct hda_verb *hv;
-
-               hv = spec->init_verbs[i];
-               while (hv->nid) {
-                       int err = 0;
-                       switch (hv->param ^ AC_USRSP_EN) {
-                       case CONEXANT_HP_EVENT:
-                               err = snd_hda_input_jack_add(codec, hv->nid,
-                                               SND_JACK_HEADPHONE, NULL);
-                               snd_hda_input_jack_report(codec, hv->nid);
-                               break;
-                       case CXT5051_PORTC_EVENT:
-                       case CONEXANT_MIC_EVENT:
-                               err = snd_hda_input_jack_add(codec, hv->nid,
-                                               SND_JACK_MICROPHONE, NULL);
-                               snd_hda_input_jack_report(codec, hv->nid);
-                               break;
-                       }
-                       if (err < 0)
-                               return err;
-                       ++hv;
-               }
-       }
-#endif /* CONFIG_SND_HDA_INPUT_JACK */
-       return 0;
-}
-
 static void conexant_set_power(struct hda_codec *codec, hda_nid_t fg,
                               unsigned int power_state)
 {
@@ -473,7 +441,6 @@ static int conexant_init(struct hda_codec *codec)
 
 static void conexant_free(struct hda_codec *codec)
 {
-       snd_hda_input_jack_free(codec);
        snd_hda_detach_beep_device(codec);
        kfree(codec->spec);
 }
@@ -1119,8 +1086,6 @@ static const char * const cxt5045_models[CXT5045_MODELS] = {
 
 static const struct snd_pci_quirk cxt5045_cfg_tbl[] = {
        SND_PCI_QUIRK(0x103c, 0x30d5, "HP 530", CXT5045_LAPTOP_HP530),
-       SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP DV Series",
-                          CXT5045_LAPTOP_HPSENSE),
        SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba P105", CXT5045_LAPTOP_MICSENSE),
        SND_PCI_QUIRK(0x152d, 0x0753, "Benq R55E", CXT5045_BENQ),
        SND_PCI_QUIRK(0x1734, 0x10ad, "Fujitsu Si1520", CXT5045_LAPTOP_MICSENSE),
@@ -1749,7 +1714,6 @@ static void cxt5051_hp_automute(struct hda_codec *codec)
 static void cxt5051_hp_unsol_event(struct hda_codec *codec,
                                   unsigned int res)
 {
-       int nid = (res & AC_UNSOL_RES_SUBTAG) >> 20;
        switch (res >> 26) {
        case CONEXANT_HP_EVENT:
                cxt5051_hp_automute(codec);
@@ -1761,7 +1725,6 @@ static void cxt5051_hp_unsol_event(struct hda_codec *codec,
                cxt5051_portc_automic(codec);
                break;
        }
-       snd_hda_input_jack_report(codec, nid);
 }
 
 static const struct snd_kcontrol_new cxt5051_playback_mixers[] = {
@@ -1900,8 +1863,6 @@ static void cxt5051_init_mic_port(struct hda_codec *codec, hda_nid_t nid,
        snd_hda_codec_write(codec, nid, 0,
                            AC_VERB_SET_UNSOLICITED_ENABLE,
                            AC_USRSP_EN | event);
-       snd_hda_input_jack_add(codec, nid, SND_JACK_MICROPHONE, NULL);
-       snd_hda_input_jack_report(codec, nid);
 }
 
 static const struct hda_verb cxt5051_ideapad_init_verbs[] = {
@@ -1917,7 +1878,6 @@ static int cxt5051_init(struct hda_codec *codec)
        struct conexant_spec *spec = codec->spec;
 
        conexant_init(codec);
-       conexant_init_jacks(codec);
 
        if (spec->auto_mic & AUTO_MIC_PORTB)
                cxt5051_init_mic_port(codec, 0x17, CXT5051_PORTB_EVENT);
@@ -3061,7 +3021,6 @@ static const struct snd_pci_quirk cxt5066_cfg_tbl[] = {
        SND_PCI_QUIRK(0x1043, 0x1993, "Asus U50F", CXT5066_ASUS),
        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),
        SND_PCI_QUIRK(0x14f1, 0x0101, "Conexant Reference board",
                      CXT5066_LAPTOP),
        SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT5066_OLPC_XO_1_5),
@@ -3450,7 +3409,6 @@ static int detect_jacks(struct hda_codec *codec, int num_pins, hda_nid_t *pins)
                hda_nid_t nid = pins[i];
                if (!nid || !is_jack_detectable(codec, nid))
                        break;
-               snd_hda_input_jack_report(codec, nid);
                present |= snd_hda_jack_detect(codec, nid);
        }
        return present;
@@ -3755,8 +3713,7 @@ static void cx_auto_automic(struct hda_codec *codec)
 
 static void cx_auto_unsol_event(struct hda_codec *codec, unsigned int res)
 {
-       int nid = (res & AC_UNSOL_RES_SUBTAG) >> 20;
-       switch (res >> 26) {
+       switch (snd_hda_jack_get_action(codec, res >> 26)) {
        case CONEXANT_HP_EVENT:
                cx_auto_hp_automute(codec);
                break;
@@ -3765,9 +3722,9 @@ static void cx_auto_unsol_event(struct hda_codec *codec, unsigned int res)
                break;
        case CONEXANT_MIC_EVENT:
                cx_auto_automic(codec);
-               snd_hda_input_jack_report(codec, nid);
                break;
        }
+       snd_hda_jack_report_sync(codec);
 }
 
 /* check whether the pin config is suitable for auto-mic switching;
@@ -3979,13 +3936,11 @@ static void mute_outputs(struct hda_codec *codec, int num_nids,
 }
 
 static void enable_unsol_pins(struct hda_codec *codec, int num_pins,
-                             hda_nid_t *pins, unsigned int tag)
+                             hda_nid_t *pins, unsigned int action)
 {
        int i;
        for (i = 0; i < num_pins; i++)
-               snd_hda_codec_write(codec, pins[i], 0,
-                                   AC_VERB_SET_UNSOLICITED_ENABLE,
-                                   AC_USRSP_EN | tag);
+               snd_hda_jack_detect_enable(codec, pins[i], action);
 }
 
 static void cx_auto_init_output(struct hda_codec *codec)
@@ -4060,16 +4015,14 @@ static void cx_auto_init_input(struct hda_codec *codec)
 
        if (spec->auto_mic) {
                if (spec->auto_mic_ext >= 0) {
-                       snd_hda_codec_write(codec,
-                               cfg->inputs[spec->auto_mic_ext].pin, 0,
-                               AC_VERB_SET_UNSOLICITED_ENABLE,
-                               AC_USRSP_EN | CONEXANT_MIC_EVENT);
+                       snd_hda_jack_detect_enable(codec,
+                               cfg->inputs[spec->auto_mic_ext].pin,
+                               CONEXANT_MIC_EVENT);
                }
                if (spec->auto_mic_dock >= 0) {
-                       snd_hda_codec_write(codec,
-                               cfg->inputs[spec->auto_mic_dock].pin, 0,
-                               AC_VERB_SET_UNSOLICITED_ENABLE,
-                               AC_USRSP_EN | CONEXANT_MIC_EVENT);
+                       snd_hda_jack_detect_enable(codec,
+                               cfg->inputs[spec->auto_mic_dock].pin,
+                               CONEXANT_MIC_EVENT);
                }
                cx_auto_automic(codec);
        } else {
@@ -4097,6 +4050,7 @@ static int cx_auto_init(struct hda_codec *codec)
        cx_auto_init_output(codec);
        cx_auto_init_input(codec);
        cx_auto_init_digital(codec);
+       snd_hda_jack_report_sync(codec);
        return 0;
 }
 
@@ -4326,6 +4280,7 @@ static int cx_auto_build_input_controls(struct hda_codec *codec)
 
 static int cx_auto_build_controls(struct hda_codec *codec)
 {
+       struct conexant_spec *spec = codec->spec;
        int err;
 
        err = cx_auto_build_output_controls(codec);
@@ -4334,7 +4289,13 @@ static int cx_auto_build_controls(struct hda_codec *codec)
        err = cx_auto_build_input_controls(codec);
        if (err < 0)
                return err;
-       return conexant_build_controls(codec);
+       err = conexant_build_controls(codec);
+       if (err < 0)
+               return err;
+       err = snd_hda_jack_add_kctls(codec, &spec->autocfg);
+       if (err < 0)
+               return err;
+       return 0;
 }
 
 static int cx_auto_search_adcs(struct hda_codec *codec)