]> Pileus Git - ~andy/linux/blobdiff - sound/pci/hda/patch_sigmatel.c
ALSA: hda/idt - Clean up power-map check code
[~andy/linux] / sound / pci / hda / patch_sigmatel.c
index 33a9946b492cb333184b1a9405c11f553fc55566..1f6f5202e7b17f84e752dfbebce0624bdb238ae9 100644 (file)
@@ -36,6 +36,7 @@
 #include <sound/tlv.h>
 #include "hda_codec.h"
 #include "hda_local.h"
+#include "hda_auto_parser.h"
 #include "hda_beep.h"
 #include "hda_jack.h"
 
@@ -681,8 +682,7 @@ static int stac_vrefout_set(struct hda_codec *codec,
        pinctl &= ~AC_PINCTL_VREFEN;
        pinctl |= (new_vref & AC_PINCTL_VREFEN);
 
-       error = snd_hda_codec_write_cache(codec, nid, 0,
-                                       AC_VERB_SET_PIN_WIDGET_CONTROL, pinctl);
+       error = snd_hda_set_pin_ctl_cache(codec, nid, pinctl);
        if (error < 0)
                return error;
 
@@ -706,8 +706,7 @@ static unsigned int stac92xx_vref_set(struct hda_codec *codec,
        else
                pincfg |= AC_PINCTL_IN_EN;
 
-       error = snd_hda_codec_write_cache(codec, nid, 0,
-                                       AC_VERB_SET_PIN_WIDGET_CONTROL, pincfg);
+       error = snd_hda_set_pin_ctl_cache(codec, nid, pincfg);
        if (error < 0)
                return error;
        else
@@ -2505,27 +2504,10 @@ static int stac92xx_build_pcms(struct hda_codec *codec)
        return 0;
 }
 
-static unsigned int stac92xx_get_default_vref(struct hda_codec *codec,
-                                       hda_nid_t nid)
-{
-       unsigned int pincap = snd_hda_query_pin_caps(codec, nid);
-       pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
-       if (pincap & AC_PINCAP_VREF_100)
-               return AC_PINCTL_VREF_100;
-       if (pincap & AC_PINCAP_VREF_80)
-               return AC_PINCTL_VREF_80;
-       if (pincap & AC_PINCAP_VREF_50)
-               return AC_PINCTL_VREF_50;
-       if (pincap & AC_PINCAP_VREF_GRD)
-               return AC_PINCTL_VREF_GRD;
-       return 0;
-}
-
 static void stac92xx_auto_set_pinctl(struct hda_codec *codec, hda_nid_t nid, int pin_type)
 
 {
-       snd_hda_codec_write_cache(codec, nid, 0,
-                                 AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
+       snd_hda_set_pin_ctl_cache(codec, nid, pin_type);
 }
 
 #define stac92xx_hp_switch_info                snd_ctl_boolean_mono_info
@@ -2594,7 +2576,7 @@ static int stac92xx_dc_bias_get(struct snd_kcontrol *kcontrol,
        hda_nid_t nid = kcontrol->private_value;
        unsigned int vref = stac92xx_vref_get(codec, nid);
 
-       if (vref == stac92xx_get_default_vref(codec, nid))
+       if (vref == snd_hda_get_default_vref(codec, nid))
                ucontrol->value.enumerated.item[0] = 0;
        else if (vref == AC_PINCTL_VREF_GRD)
                ucontrol->value.enumerated.item[0] = 1;
@@ -2613,7 +2595,7 @@ static int stac92xx_dc_bias_put(struct snd_kcontrol *kcontrol,
        hda_nid_t nid = kcontrol->private_value;
 
        if (ucontrol->value.enumerated.item[0] == 0)
-               new_vref = stac92xx_get_default_vref(codec, nid);
+               new_vref = snd_hda_get_default_vref(codec, nid);
        else if (ucontrol->value.enumerated.item[0] == 1)
                new_vref = AC_PINCTL_VREF_GRD;
        else if (ucontrol->value.enumerated.item[0] == 2)
@@ -2679,7 +2661,7 @@ static int stac92xx_io_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_
        else {
                unsigned int pinctl = AC_PINCTL_IN_EN;
                if (io_idx) /* set VREF for mic */
-                       pinctl |= stac92xx_get_default_vref(codec, nid);
+                       pinctl |= snd_hda_get_default_vref(codec, nid);
                stac92xx_auto_set_pinctl(codec, nid, pinctl);
        }
 
@@ -2847,7 +2829,7 @@ static inline int stac92xx_add_jack_mode_control(struct hda_codec *codec,
        char name[22];
 
        if (snd_hda_get_input_pin_attr(def_conf) != INPUT_PIN_ATTR_INT) {
-               if (stac92xx_get_default_vref(codec, nid) == AC_PINCTL_VREF_GRD
+               if (snd_hda_get_default_vref(codec, nid) == AC_PINCTL_VREF_GRD
                        && nid == spec->line_switch)
                        control = STAC_CTL_WIDGET_IO_SWITCH;
                else if (snd_hda_query_pin_caps(codec, nid)
@@ -4250,13 +4232,6 @@ static void stac_store_hints(struct hda_codec *codec)
        val = snd_hda_get_bool_hint(codec, "eapd_switch");
        if (val >= 0)
                spec->eapd_switch = val;
-       get_int_hint(codec, "gpio_led_polarity", &spec->gpio_led_polarity);
-       if (get_int_hint(codec, "gpio_led", &spec->gpio_led)) {
-               spec->gpio_mask |= spec->gpio_led;
-               spec->gpio_dir |= spec->gpio_led;
-               if (spec->gpio_led_polarity)
-                       spec->gpio_data |= spec->gpio_led;
-       }
 }
 
 static void stac_issue_unsol_events(struct hda_codec *codec, int num_pins,
@@ -4354,7 +4329,7 @@ static int stac92xx_init(struct hda_codec *codec)
                unsigned int pinctl, conf;
                if (type == AUTO_PIN_MIC) {
                        /* for mic pins, force to initialize */
-                       pinctl = stac92xx_get_default_vref(codec, nid);
+                       pinctl = snd_hda_get_default_vref(codec, nid);
                        pinctl |= AC_PINCTL_IN_EN;
                        stac92xx_auto_set_pinctl(codec, nid, pinctl);
                } else {
@@ -4390,10 +4365,18 @@ static int stac92xx_init(struct hda_codec *codec)
                hda_nid_t nid = spec->pwr_nids[i];
                int pinctl, def_conf;
 
+               def_conf = snd_hda_codec_get_pincfg(codec, nid);
+               def_conf = get_defcfg_connect(def_conf);
+               if (def_conf == AC_JACK_PORT_NONE) {
+                       /* power off unused ports */
+                       stac_toggle_power_map(codec, nid, 0);
+                       continue;
+               }
                /* power on when no jack detection is available */
                /* or when the VREF is used for controlling LED */
                if (!spec->hp_detect ||
-                   spec->vref_mute_led_nid == nid) {
+                   spec->vref_mute_led_nid == nid ||
+                   !is_jack_detectable(codec, nid)) {
                        stac_toggle_power_map(codec, nid, 1);
                        continue;
                }
@@ -4411,15 +4394,6 @@ static int stac92xx_init(struct hda_codec *codec)
                        stac_toggle_power_map(codec, nid, 1);
                        continue;
                }
-               def_conf = snd_hda_codec_get_pincfg(codec, nid);
-               def_conf = get_defcfg_connect(def_conf);
-               /* skip any ports that don't have jacks since presence
-                * detection is useless */
-               if (def_conf != AC_JACK_PORT_COMPLEX) {
-                       if (def_conf != AC_JACK_PORT_NONE)
-                               stac_toggle_power_map(codec, nid, 1);
-                       continue;
-               }
                if (enable_pin_detect(codec, nid, STAC_PWR_EVENT)) {
                        stac_issue_unsol_event(codec, nid);
                        continue;
@@ -4460,8 +4434,7 @@ static void stac92xx_shutup_pins(struct hda_codec *codec)
                struct hda_pincfg *pin = snd_array_elem(&codec->init_pins, i);
                def_conf = snd_hda_codec_get_pincfg(codec, pin->nid);
                if (get_defcfg_connect(def_conf) != AC_JACK_PORT_NONE)
-                       snd_hda_codec_write(codec, pin->nid, 0,
-                                   AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
+                       snd_hda_set_pin_ctl(codec, pin->nid, 0);
        }
 }
 
@@ -4517,9 +4490,7 @@ static void stac92xx_set_pinctl(struct hda_codec *codec, hda_nid_t nid,
        
        pin_ctl |= flag;
        if (old_ctl != pin_ctl)
-               snd_hda_codec_write_cache(codec, nid, 0,
-                                         AC_VERB_SET_PIN_WIDGET_CONTROL,
-                                         pin_ctl);
+               snd_hda_set_pin_ctl_cache(codec, nid, pin_ctl);
 }
 
 static void stac92xx_reset_pinctl(struct hda_codec *codec, hda_nid_t nid,
@@ -4528,9 +4499,7 @@ static void stac92xx_reset_pinctl(struct hda_codec *codec, hda_nid_t nid,
        unsigned int pin_ctl = snd_hda_codec_read(codec, nid,
                        0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0x00);
        if (pin_ctl & flag)
-               snd_hda_codec_write_cache(codec, nid, 0,
-                                         AC_VERB_SET_PIN_WIDGET_CONTROL,
-                                         pin_ctl & ~flag);
+               snd_hda_set_pin_ctl_cache(codec, nid, pin_ctl & ~flag);
 }
 
 static inline int get_pin_presence(struct hda_codec *codec, hda_nid_t nid)
@@ -4866,6 +4835,11 @@ static int find_mute_led_cfg(struct hda_codec *codec, int default_polarity)
        struct sigmatel_spec *spec = codec->spec;
        const struct dmi_device *dev = NULL;
 
+       if (get_int_hint(codec, "gpio_led", &spec->gpio_led)) {
+               get_int_hint(codec, "gpio_led_polarity",
+                            &spec->gpio_led_polarity);
+               return 1;
+       }
        if ((codec->subsystem_id >> 16) == PCI_VENDOR_ID_HP) {
                while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING,
                                                                NULL, dev))) {
@@ -5009,20 +4983,6 @@ static int stac92xx_suspend(struct hda_codec *codec, pm_message_t state)
        return 0;
 }
 
-static int stac92xx_pre_resume(struct hda_codec *codec)
-{
-       struct sigmatel_spec *spec = codec->spec;
-
-       /* sync mute LED */
-       if (spec->vref_mute_led_nid)
-               stac_vrefout_set(codec, spec->vref_mute_led_nid,
-                                spec->vref_led);
-       else if (spec->gpio_led)
-               stac_gpio_set(codec, spec->gpio_mask,
-                             spec->gpio_dir, spec->gpio_data);
-       return 0;
-}
-
 static void stac92xx_set_power_state(struct hda_codec *codec, hda_nid_t fg,
                                unsigned int power_state)
 {
@@ -5046,7 +5006,6 @@ static void stac92xx_set_power_state(struct hda_codec *codec, hda_nid_t fg,
 #else
 #define stac92xx_suspend       NULL
 #define stac92xx_resume                NULL
-#define stac92xx_pre_resume    NULL
 #define stac92xx_set_power_state NULL
 #endif /* CONFIG_PM */
 
@@ -5063,12 +5022,11 @@ static void stac92xx_update_led_status(struct hda_codec *codec, int enabled)
        if (spec->gpio_led_polarity)
                muted = !muted;
 
-       /*polarity defines *not* muted state level*/
        if (!spec->vref_mute_led_nid) {
                if (muted)
-                       spec->gpio_data &= ~spec->gpio_led; /* orange */
+                       spec->gpio_data |= spec->gpio_led;
                else
-                       spec->gpio_data |= spec->gpio_led; /* white */
+                       spec->gpio_data &= ~spec->gpio_led;
                stac_gpio_set(codec, spec->gpio_mask,
                                spec->gpio_dir, spec->gpio_data);
        } else {
@@ -5593,9 +5551,6 @@ again:
                        codec->patch_ops.set_power_state =
                                        stac92xx_set_power_state;
                }
-#ifdef CONFIG_PM
-               codec->patch_ops.pre_resume = stac92xx_pre_resume;
-#endif
        }
 
        err = stac92xx_parse_auto_config(codec);
@@ -5902,9 +5857,6 @@ again:
                        codec->patch_ops.set_power_state =
                                        stac92xx_set_power_state;
                }
-#ifdef CONFIG_PM
-               codec->patch_ops.pre_resume = stac92xx_pre_resume;
-#endif
        }
 
        spec->multiout.dac_nids = spec->dac_nids;