aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/patch_sigmatel.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2008-11-25 05:56:25 -0500
committerTakashi Iwai <tiwai@suse.de>2008-11-25 05:56:25 -0500
commit0e19e7d2bff0ec04fe4dc920c580d8a321afa07f (patch)
tree9e784e7556a92172a0b27465e0b081437e44335e /sound/pci/hda/patch_sigmatel.c
parent82894b6f6f109722070d4d78730fe50cdaba9443 (diff)
parentf73d35853e9263c7c404f0d6c0fe3d83fc6fd5c0 (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.c78
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
3832static void stac_toggle_power_map(struct hda_codec *codec, hda_nid_t nid,
3833 int enable);
3834
3832static int stac92xx_init(struct hda_codec *codec) 3835static 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
4106static void stac92xx_pin_sense(struct hda_codec *codec, int idx) 4124static 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
4153static 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
4130static void stac92xx_report_jack(struct hda_codec *codec, hda_nid_t nid) 4158static 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;