diff options
Diffstat (limited to 'sound/pci/hda/patch_sigmatel.c')
-rw-r--r-- | sound/pci/hda/patch_sigmatel.c | 67 |
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 | |||
5058 | static 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 = |