diff options
author | Takashi Iwai <tiwai@suse.de> | 2008-11-25 05:56:25 -0500 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2008-11-25 05:56:25 -0500 |
commit | 0e19e7d2bff0ec04fe4dc920c580d8a321afa07f (patch) | |
tree | 9e784e7556a92172a0b27465e0b081437e44335e /sound/pci/hda/patch_sigmatel.c | |
parent | 82894b6f6f109722070d4d78730fe50cdaba9443 (diff) | |
parent | f73d35853e9263c7c404f0d6c0fe3d83fc6fd5c0 (diff) |
Merge branch 'topic/fix/hda' into topic/hda
Conflicts:
sound/pci/hda/patch_sigmatel.c
Diffstat (limited to 'sound/pci/hda/patch_sigmatel.c')
-rw-r--r-- | sound/pci/hda/patch_sigmatel.c | 78 |
1 files changed, 53 insertions, 25 deletions
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 7cd395a175ef..09b3f4b1db4d 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c | |||
@@ -3829,10 +3829,14 @@ static void stac92xx_power_down(struct hda_codec *codec) | |||
3829 | AC_VERB_SET_POWER_STATE, AC_PWRST_D3); | 3829 | AC_VERB_SET_POWER_STATE, AC_PWRST_D3); |
3830 | } | 3830 | } |
3831 | 3831 | ||
3832 | static void stac_toggle_power_map(struct hda_codec *codec, hda_nid_t nid, | ||
3833 | int enable); | ||
3834 | |||
3832 | static int stac92xx_init(struct hda_codec *codec) | 3835 | static int stac92xx_init(struct hda_codec *codec) |
3833 | { | 3836 | { |
3834 | struct sigmatel_spec *spec = codec->spec; | 3837 | struct sigmatel_spec *spec = codec->spec; |
3835 | struct auto_pin_cfg *cfg = &spec->autocfg; | 3838 | struct auto_pin_cfg *cfg = &spec->autocfg; |
3839 | unsigned int gpio; | ||
3836 | int i; | 3840 | int i; |
3837 | 3841 | ||
3838 | snd_hda_sequence_write(codec, spec->init); | 3842 | snd_hda_sequence_write(codec, spec->init); |
@@ -3843,6 +3847,16 @@ static int stac92xx_init(struct hda_codec *codec) | |||
3843 | snd_hda_codec_write_cache(codec, | 3847 | snd_hda_codec_write_cache(codec, |
3844 | spec->adc_nids[i], 0, | 3848 | spec->adc_nids[i], 0, |
3845 | AC_VERB_SET_POWER_STATE, AC_PWRST_D3); | 3849 | AC_VERB_SET_POWER_STATE, AC_PWRST_D3); |
3850 | |||
3851 | /* set up GPIO */ | ||
3852 | gpio = spec->gpio_data; | ||
3853 | /* turn on EAPD statically when spec->eapd_switch isn't set. | ||
3854 | * otherwise, unsol event will turn it on/off dynamically | ||
3855 | */ | ||
3856 | if (!spec->eapd_switch) | ||
3857 | gpio |= spec->eapd_mask; | ||
3858 | stac_gpio_set(codec, spec->gpio_mask, spec->gpio_dir, gpio); | ||
3859 | |||
3846 | /* set up pins */ | 3860 | /* set up pins */ |
3847 | if (spec->hp_detect) { | 3861 | if (spec->hp_detect) { |
3848 | /* Enable unsolicited responses on the HP widget */ | 3862 | /* Enable unsolicited responses on the HP widget */ |
@@ -3884,39 +3898,43 @@ static int stac92xx_init(struct hda_codec *codec) | |||
3884 | for (i = 0; i < spec->num_dmics; i++) | 3898 | for (i = 0; i < spec->num_dmics; i++) |
3885 | stac92xx_auto_set_pinctl(codec, spec->dmic_nids[i], | 3899 | stac92xx_auto_set_pinctl(codec, spec->dmic_nids[i], |
3886 | AC_PINCTL_IN_EN); | 3900 | AC_PINCTL_IN_EN); |
3901 | if (cfg->dig_out_pin) | ||
3902 | stac92xx_auto_set_pinctl(codec, cfg->dig_out_pin, | ||
3903 | AC_PINCTL_OUT_EN); | ||
3904 | if (cfg->dig_in_pin) | ||
3905 | stac92xx_auto_set_pinctl(codec, cfg->dig_in_pin, | ||
3906 | AC_PINCTL_IN_EN); | ||
3887 | for (i = 0; i < spec->num_pwrs; i++) { | 3907 | for (i = 0; i < spec->num_pwrs; i++) { |
3888 | int event = is_nid_hp_pin(cfg, spec->pwr_nids[i]) | 3908 | hda_nid_t nid = spec->pwr_nids[i]; |
3889 | ? STAC_HP_EVENT : STAC_PWR_EVENT; | 3909 | int pinctl, def_conf; |
3890 | int pinctl = snd_hda_codec_read(codec, spec->pwr_nids[i], | 3910 | int event = STAC_PWR_EVENT; |
3891 | 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0); | 3911 | |
3892 | int def_conf = snd_hda_codec_read(codec, spec->pwr_nids[i], | 3912 | if (is_nid_hp_pin(cfg, nid) && spec->hp_detect) |
3893 | 0, AC_VERB_GET_CONFIG_DEFAULT, 0); | 3913 | continue; /* already has an unsol event */ |
3894 | def_conf = get_defcfg_connect(def_conf); | 3914 | |
3915 | pinctl = snd_hda_codec_read(codec, nid, 0, | ||
3916 | AC_VERB_GET_PIN_WIDGET_CONTROL, 0); | ||
3895 | /* outputs are only ports capable of power management | 3917 | /* outputs are only ports capable of power management |
3896 | * any attempts on powering down a input port cause the | 3918 | * any attempts on powering down a input port cause the |
3897 | * referenced VREF to act quirky. | 3919 | * referenced VREF to act quirky. |
3898 | */ | 3920 | */ |
3899 | if (pinctl & AC_PINCTL_IN_EN) | 3921 | if (pinctl & AC_PINCTL_IN_EN) |
3900 | continue; | 3922 | continue; |
3923 | def_conf = snd_hda_codec_read(codec, nid, 0, | ||
3924 | AC_VERB_GET_CONFIG_DEFAULT, 0); | ||
3925 | def_conf = get_defcfg_connect(def_conf); | ||
3901 | /* skip any ports that don't have jacks since presence | 3926 | /* skip any ports that don't have jacks since presence |
3902 | * detection is useless */ | 3927 | * detection is useless */ |
3903 | if (def_conf && def_conf != AC_JACK_PORT_FIXED) | 3928 | if (def_conf != AC_JACK_PORT_COMPLEX) { |
3929 | if (def_conf != AC_JACK_PORT_NONE) | ||
3930 | stac_toggle_power_map(codec, nid, 1); | ||
3904 | continue; | 3931 | continue; |
3932 | } | ||
3905 | enable_pin_detect(codec, spec->pwr_nids[i], event | i); | 3933 | enable_pin_detect(codec, spec->pwr_nids[i], event | i); |
3906 | codec->patch_ops.unsol_event(codec, (event | i) << 26); | 3934 | codec->patch_ops.unsol_event(codec, (event | i) << 26); |
3907 | } | 3935 | } |
3908 | if (spec->dac_list) | 3936 | if (spec->dac_list) |
3909 | stac92xx_power_down(codec); | 3937 | stac92xx_power_down(codec); |
3910 | if (cfg->dig_out_pin) | ||
3911 | stac92xx_auto_set_pinctl(codec, cfg->dig_out_pin, | ||
3912 | AC_PINCTL_OUT_EN); | ||
3913 | if (cfg->dig_in_pin) | ||
3914 | stac92xx_auto_set_pinctl(codec, cfg->dig_in_pin, | ||
3915 | AC_PINCTL_IN_EN); | ||
3916 | |||
3917 | stac_gpio_set(codec, spec->gpio_mask, | ||
3918 | spec->gpio_dir, spec->gpio_data); | ||
3919 | |||
3920 | return 0; | 3938 | return 0; |
3921 | } | 3939 | } |
3922 | 3940 | ||
@@ -4103,14 +4121,18 @@ static void stac92xx_hp_detect(struct hda_codec *codec, unsigned int res) | |||
4103 | } | 4121 | } |
4104 | } | 4122 | } |
4105 | 4123 | ||
4106 | static void stac92xx_pin_sense(struct hda_codec *codec, int idx) | 4124 | static void stac_toggle_power_map(struct hda_codec *codec, hda_nid_t nid, |
4125 | int enable) | ||
4107 | { | 4126 | { |
4108 | struct sigmatel_spec *spec = codec->spec; | 4127 | struct sigmatel_spec *spec = codec->spec; |
4109 | hda_nid_t nid = spec->pwr_nids[idx]; | 4128 | unsigned int idx, val; |
4110 | int presence, val; | 4129 | |
4111 | val = snd_hda_codec_read(codec, codec->afg, 0, 0x0fec, 0x0) | 4130 | for (idx = 0; idx < spec->num_pwrs; idx++) { |
4112 | & 0x000000ff; | 4131 | if (spec->pwr_nids[idx] == nid) |
4113 | presence = get_hp_pin_presence(codec, nid); | 4132 | break; |
4133 | } | ||
4134 | if (idx >= spec->num_pwrs) | ||
4135 | return; | ||
4114 | 4136 | ||
4115 | /* several codecs have two power down bits */ | 4137 | /* several codecs have two power down bits */ |
4116 | if (spec->pwr_mapping) | 4138 | if (spec->pwr_mapping) |
@@ -4118,7 +4140,8 @@ static void stac92xx_pin_sense(struct hda_codec *codec, int idx) | |||
4118 | else | 4140 | else |
4119 | idx = 1 << idx; | 4141 | idx = 1 << idx; |
4120 | 4142 | ||
4121 | if (presence) | 4143 | val = snd_hda_codec_read(codec, codec->afg, 0, 0x0fec, 0x0) & 0xff; |
4144 | if (enable) | ||
4122 | val &= ~idx; | 4145 | val &= ~idx; |
4123 | else | 4146 | else |
4124 | val |= idx; | 4147 | val |= idx; |
@@ -4127,6 +4150,11 @@ static void stac92xx_pin_sense(struct hda_codec *codec, int idx) | |||
4127 | snd_hda_codec_write(codec, codec->afg, 0, 0x7ec, val); | 4150 | snd_hda_codec_write(codec, codec->afg, 0, 0x7ec, val); |
4128 | } | 4151 | } |
4129 | 4152 | ||
4153 | static void stac92xx_pin_sense(struct hda_codec *codec, hda_nid_t nid) | ||
4154 | { | ||
4155 | stac_toggle_power_map(codec, nid, get_hp_pin_presence(codec, nid)); | ||
4156 | } | ||
4157 | |||
4130 | static void stac92xx_report_jack(struct hda_codec *codec, hda_nid_t nid) | 4158 | static void stac92xx_report_jack(struct hda_codec *codec, hda_nid_t nid) |
4131 | { | 4159 | { |
4132 | struct sigmatel_spec *spec = codec->spec; | 4160 | struct sigmatel_spec *spec = codec->spec; |