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.c67
1 files changed, 27 insertions, 40 deletions
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index f3658658548e..eeb25d529e30 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",
@@ -5043,29 +5050,12 @@ static int stac92xx_pre_resume(struct hda_codec *codec)
5043 struct sigmatel_spec *spec = codec->spec; 5050 struct sigmatel_spec *spec = codec->spec;
5044 5051
5045 /* sync mute LED */ 5052 /* sync mute LED */
5046 if (spec->gpio_led) { 5053 if (spec->vref_mute_led_nid)
5047 if (spec->gpio_led <= 8) { 5054 stac_vrefout_set(codec, spec->vref_mute_led_nid,
5048 stac_gpio_set(codec, spec->gpio_mask, 5055 spec->vref_led);
5049 spec->gpio_dir, spec->gpio_data); 5056 else if (spec->gpio_led)
5050 } else { 5057 stac_gpio_set(codec, spec->gpio_mask,
5051 stac_vrefout_set(codec, 5058 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; 5059 return 0;
5070} 5060}
5071 5061
@@ -5076,7 +5066,7 @@ static void stac92xx_set_power_state(struct hda_codec *codec, hda_nid_t fg,
5076 struct sigmatel_spec *spec = codec->spec; 5066 struct sigmatel_spec *spec = codec->spec;
5077 5067
5078 if (power_state == AC_PWRST_D3) { 5068 if (power_state == AC_PWRST_D3) {
5079 if (spec->gpio_led > 8) { 5069 if (spec->vref_mute_led_nid) {
5080 /* with vref-out pin used for mute led control 5070 /* with vref-out pin used for mute led control
5081 * codec AFG is prevented from D3 state 5071 * codec AFG is prevented from D3 state
5082 */ 5072 */
@@ -5129,7 +5119,7 @@ static int stac92xx_update_led_status(struct hda_codec *codec)
5129 } 5119 }
5130 } 5120 }
5131 /*polarity defines *not* muted state level*/ 5121 /*polarity defines *not* muted state level*/
5132 if (spec->gpio_led <= 8) { 5122 if (!spec->vref_mute_led_nid) {
5133 if (muted) 5123 if (muted)
5134 spec->gpio_data &= ~spec->gpio_led; /* orange */ 5124 spec->gpio_data &= ~spec->gpio_led; /* orange */
5135 else 5125 else
@@ -5147,7 +5137,8 @@ static int stac92xx_update_led_status(struct hda_codec *codec)
5147 muted_lvl = spec->gpio_led_polarity ? 5137 muted_lvl = spec->gpio_led_polarity ?
5148 AC_PINCTL_VREF_GRD : AC_PINCTL_VREF_HIZ; 5138 AC_PINCTL_VREF_GRD : AC_PINCTL_VREF_HIZ;
5149 spec->vref_led = muted ? muted_lvl : notmtd_lvl; 5139 spec->vref_led = muted ? muted_lvl : notmtd_lvl;
5150 stac_vrefout_set(codec, spec->gpio_led, spec->vref_led); 5140 stac_vrefout_set(codec, spec->vref_mute_led_nid,
5141 spec->vref_led);
5151 } 5142 }
5152 return 0; 5143 return 0;
5153} 5144}
@@ -5661,15 +5652,13 @@ again:
5661 5652
5662#ifdef CONFIG_SND_HDA_POWER_SAVE 5653#ifdef CONFIG_SND_HDA_POWER_SAVE
5663 if (spec->gpio_led) { 5654 if (spec->gpio_led) {
5664 if (spec->gpio_led <= 8) { 5655 if (!spec->vref_mute_led_nid) {
5665 spec->gpio_mask |= spec->gpio_led; 5656 spec->gpio_mask |= spec->gpio_led;
5666 spec->gpio_dir |= spec->gpio_led; 5657 spec->gpio_dir |= spec->gpio_led;
5667 spec->gpio_data |= spec->gpio_led; 5658 spec->gpio_data |= spec->gpio_led;
5668 } else { 5659 } else {
5669 codec->patch_ops.set_power_state = 5660 codec->patch_ops.set_power_state =
5670 stac92xx_set_power_state; 5661 stac92xx_set_power_state;
5671 codec->patch_ops.post_suspend =
5672 stac92xx_post_suspend;
5673 } 5662 }
5674 codec->patch_ops.pre_resume = stac92xx_pre_resume; 5663 codec->patch_ops.pre_resume = stac92xx_pre_resume;
5675 codec->patch_ops.check_power_status = 5664 codec->patch_ops.check_power_status =
@@ -5976,15 +5965,13 @@ again:
5976 5965
5977#ifdef CONFIG_SND_HDA_POWER_SAVE 5966#ifdef CONFIG_SND_HDA_POWER_SAVE
5978 if (spec->gpio_led) { 5967 if (spec->gpio_led) {
5979 if (spec->gpio_led <= 8) { 5968 if (!spec->vref_mute_led_nid) {
5980 spec->gpio_mask |= spec->gpio_led; 5969 spec->gpio_mask |= spec->gpio_led;
5981 spec->gpio_dir |= spec->gpio_led; 5970 spec->gpio_dir |= spec->gpio_led;
5982 spec->gpio_data |= spec->gpio_led; 5971 spec->gpio_data |= spec->gpio_led;
5983 } else { 5972 } else {
5984 codec->patch_ops.set_power_state = 5973 codec->patch_ops.set_power_state =
5985 stac92xx_set_power_state; 5974 stac92xx_set_power_state;
5986 codec->patch_ops.post_suspend =
5987 stac92xx_post_suspend;
5988 } 5975 }
5989 codec->patch_ops.pre_resume = stac92xx_pre_resume; 5976 codec->patch_ops.pre_resume = stac92xx_pre_resume;
5990 codec->patch_ops.check_power_status = 5977 codec->patch_ops.check_power_status =