aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/patch_sigmatel.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/hda/patch_sigmatel.c')
-rw-r--r--sound/pci/hda/patch_sigmatel.c73
1 files changed, 33 insertions, 40 deletions
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index f3658658548e..616678fde486 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -215,6 +215,7 @@ struct sigmatel_spec {
215 unsigned int gpio_mute; 215 unsigned int gpio_mute;
216 unsigned int gpio_led; 216 unsigned int gpio_led;
217 unsigned int gpio_led_polarity; 217 unsigned int gpio_led_polarity;
218 unsigned int vref_mute_led_nid; /* pin NID for mute-LED vref control */
218 unsigned int vref_led; 219 unsigned int vref_led;
219 220
220 /* stream */ 221 /* stream */
@@ -4318,12 +4319,10 @@ static void stac_store_hints(struct hda_codec *codec)
4318 spec->eapd_switch = val; 4319 spec->eapd_switch = val;
4319 get_int_hint(codec, "gpio_led_polarity", &spec->gpio_led_polarity); 4320 get_int_hint(codec, "gpio_led_polarity", &spec->gpio_led_polarity);
4320 if (get_int_hint(codec, "gpio_led", &spec->gpio_led)) { 4321 if (get_int_hint(codec, "gpio_led", &spec->gpio_led)) {
4321 if (spec->gpio_led <= 8) { 4322 spec->gpio_mask |= spec->gpio_led;
4322 spec->gpio_mask |= spec->gpio_led; 4323 spec->gpio_dir |= spec->gpio_led;
4323 spec->gpio_dir |= spec->gpio_led; 4324 if (spec->gpio_led_polarity)
4324 if (spec->gpio_led_polarity) 4325 spec->gpio_data |= spec->gpio_led;
4325 spec->gpio_data |= spec->gpio_led;
4326 }
4327 } 4326 }
4328} 4327}
4329 4328
@@ -4441,7 +4440,9 @@ static int stac92xx_init(struct hda_codec *codec)
4441 int pinctl, def_conf; 4440 int pinctl, def_conf;
4442 4441
4443 /* power on when no jack detection is available */ 4442 /* power on when no jack detection is available */
4444 if (!spec->hp_detect) { 4443 /* or when the VREF is used for controlling LED */
4444 if (!spec->hp_detect ||
4445 spec->vref_mute_led_nid == nid) {
4445 stac_toggle_power_map(codec, nid, 1); 4446 stac_toggle_power_map(codec, nid, 1);
4446 continue; 4447 continue;
4447 } 4448 }
@@ -4913,8 +4914,14 @@ static int find_mute_led_gpio(struct hda_codec *codec, int default_polarity)
4913 if (sscanf(dev->name, "HP_Mute_LED_%d_%x", 4914 if (sscanf(dev->name, "HP_Mute_LED_%d_%x",
4914 &spec->gpio_led_polarity, 4915 &spec->gpio_led_polarity,
4915 &spec->gpio_led) == 2) { 4916 &spec->gpio_led) == 2) {
4916 if (spec->gpio_led < 4) 4917 unsigned int max_gpio;
4918 max_gpio = snd_hda_param_read(codec, codec->afg,
4919 AC_PAR_GPIO_CAP);
4920 max_gpio &= AC_GPIO_IO_COUNT;
4921 if (spec->gpio_led < max_gpio)
4917 spec->gpio_led = 1 << spec->gpio_led; 4922 spec->gpio_led = 1 << spec->gpio_led;
4923 else
4924 spec->vref_mute_led_nid = spec->gpio_led;
4918 return 1; 4925 return 1;
4919 } 4926 }
4920 if (sscanf(dev->name, "HP_Mute_LED_%d", 4927 if (sscanf(dev->name, "HP_Mute_LED_%d",
@@ -4922,6 +4929,12 @@ static int find_mute_led_gpio(struct hda_codec *codec, int default_polarity)
4922 set_hp_led_gpio(codec); 4929 set_hp_led_gpio(codec);
4923 return 1; 4930 return 1;
4924 } 4931 }
4932 /* BIOS bug: unfilled OEM string */
4933 if (strstr(dev->name, "HP_Mute_LED_P_G")) {
4934 set_hp_led_gpio(codec);
4935 spec->gpio_led_polarity = 1;
4936 return 1;
4937 }
4925 } 4938 }
4926 4939
4927 /* 4940 /*
@@ -5043,29 +5056,12 @@ static int stac92xx_pre_resume(struct hda_codec *codec)
5043 struct sigmatel_spec *spec = codec->spec; 5056 struct sigmatel_spec *spec = codec->spec;
5044 5057
5045 /* sync mute LED */ 5058 /* sync mute LED */
5046 if (spec->gpio_led) { 5059 if (spec->vref_mute_led_nid)
5047 if (spec->gpio_led <= 8) { 5060 stac_vrefout_set(codec, spec->vref_mute_led_nid,
5048 stac_gpio_set(codec, spec->gpio_mask, 5061 spec->vref_led);
5049 spec->gpio_dir, spec->gpio_data); 5062 else if (spec->gpio_led)
5050 } else { 5063 stac_gpio_set(codec, spec->gpio_mask,
5051 stac_vrefout_set(codec, 5064 spec->gpio_dir, spec->gpio_data);
5052 spec->gpio_led, spec->vref_led);
5053 }
5054 }
5055 return 0;
5056}
5057
5058static int stac92xx_post_suspend(struct hda_codec *codec)
5059{
5060 struct sigmatel_spec *spec = codec->spec;
5061 if (spec->gpio_led > 8) {
5062 /* with vref-out pin used for mute led control
5063 * codec AFG is prevented from D3 state, but on
5064 * system suspend it can (and should) be used
5065 */
5066 snd_hda_codec_read(codec, codec->afg, 0,
5067 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
5068 }
5069 return 0; 5065 return 0;
5070} 5066}
5071 5067
@@ -5076,7 +5072,7 @@ static void stac92xx_set_power_state(struct hda_codec *codec, hda_nid_t fg,
5076 struct sigmatel_spec *spec = codec->spec; 5072 struct sigmatel_spec *spec = codec->spec;
5077 5073
5078 if (power_state == AC_PWRST_D3) { 5074 if (power_state == AC_PWRST_D3) {
5079 if (spec->gpio_led > 8) { 5075 if (spec->vref_mute_led_nid) {
5080 /* with vref-out pin used for mute led control 5076 /* with vref-out pin used for mute led control
5081 * codec AFG is prevented from D3 state 5077 * codec AFG is prevented from D3 state
5082 */ 5078 */
@@ -5129,7 +5125,7 @@ static int stac92xx_update_led_status(struct hda_codec *codec)
5129 } 5125 }
5130 } 5126 }
5131 /*polarity defines *not* muted state level*/ 5127 /*polarity defines *not* muted state level*/
5132 if (spec->gpio_led <= 8) { 5128 if (!spec->vref_mute_led_nid) {
5133 if (muted) 5129 if (muted)
5134 spec->gpio_data &= ~spec->gpio_led; /* orange */ 5130 spec->gpio_data &= ~spec->gpio_led; /* orange */
5135 else 5131 else
@@ -5147,7 +5143,8 @@ static int stac92xx_update_led_status(struct hda_codec *codec)
5147 muted_lvl = spec->gpio_led_polarity ? 5143 muted_lvl = spec->gpio_led_polarity ?
5148 AC_PINCTL_VREF_GRD : AC_PINCTL_VREF_HIZ; 5144 AC_PINCTL_VREF_GRD : AC_PINCTL_VREF_HIZ;
5149 spec->vref_led = muted ? muted_lvl : notmtd_lvl; 5145 spec->vref_led = muted ? muted_lvl : notmtd_lvl;
5150 stac_vrefout_set(codec, spec->gpio_led, spec->vref_led); 5146 stac_vrefout_set(codec, spec->vref_mute_led_nid,
5147 spec->vref_led);
5151 } 5148 }
5152 return 0; 5149 return 0;
5153} 5150}
@@ -5661,15 +5658,13 @@ again:
5661 5658
5662#ifdef CONFIG_SND_HDA_POWER_SAVE 5659#ifdef CONFIG_SND_HDA_POWER_SAVE
5663 if (spec->gpio_led) { 5660 if (spec->gpio_led) {
5664 if (spec->gpio_led <= 8) { 5661 if (!spec->vref_mute_led_nid) {
5665 spec->gpio_mask |= spec->gpio_led; 5662 spec->gpio_mask |= spec->gpio_led;
5666 spec->gpio_dir |= spec->gpio_led; 5663 spec->gpio_dir |= spec->gpio_led;
5667 spec->gpio_data |= spec->gpio_led; 5664 spec->gpio_data |= spec->gpio_led;
5668 } else { 5665 } else {
5669 codec->patch_ops.set_power_state = 5666 codec->patch_ops.set_power_state =
5670 stac92xx_set_power_state; 5667 stac92xx_set_power_state;
5671 codec->patch_ops.post_suspend =
5672 stac92xx_post_suspend;
5673 } 5668 }
5674 codec->patch_ops.pre_resume = stac92xx_pre_resume; 5669 codec->patch_ops.pre_resume = stac92xx_pre_resume;
5675 codec->patch_ops.check_power_status = 5670 codec->patch_ops.check_power_status =
@@ -5976,15 +5971,13 @@ again:
5976 5971
5977#ifdef CONFIG_SND_HDA_POWER_SAVE 5972#ifdef CONFIG_SND_HDA_POWER_SAVE
5978 if (spec->gpio_led) { 5973 if (spec->gpio_led) {
5979 if (spec->gpio_led <= 8) { 5974 if (!spec->vref_mute_led_nid) {
5980 spec->gpio_mask |= spec->gpio_led; 5975 spec->gpio_mask |= spec->gpio_led;
5981 spec->gpio_dir |= spec->gpio_led; 5976 spec->gpio_dir |= spec->gpio_led;
5982 spec->gpio_data |= spec->gpio_led; 5977 spec->gpio_data |= spec->gpio_led;
5983 } else { 5978 } else {
5984 codec->patch_ops.set_power_state = 5979 codec->patch_ops.set_power_state =
5985 stac92xx_set_power_state; 5980 stac92xx_set_power_state;
5986 codec->patch_ops.post_suspend =
5987 stac92xx_post_suspend;
5988 } 5981 }
5989 codec->patch_ops.pre_resume = stac92xx_pre_resume; 5982 codec->patch_ops.pre_resume = stac92xx_pre_resume;
5990 codec->patch_ops.check_power_status = 5983 codec->patch_ops.check_power_status =