aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2011-12-04 07:44:06 -0500
committerTakashi Iwai <tiwai@suse.de>2011-12-06 07:18:46 -0500
commitf1a73746c6664442082e3d53e1804f46e1910436 (patch)
tree08d21f39323f9b47ef2652a5d7fa2e4934a574f4 /sound/pci/hda
parent77088cc97315e9bc713e335fb082ad26d065a4cf (diff)
ALSA: hda - Fix GPIO LED setup for IDT 92HD75 codecs
Some HP laptops with IDT 92HD75 codecs may use a GPIO > 4 for the mute LED, but currently the driver doesn't check this properly, and confuses the mute LED behavior. This ended up with the silent output on some HP laptops due to having another GPIO used as external amp control. This patch fixes the problem by checking the max GPIO count and comparing with the given value from DMI entry instead of magic fixed value 4 and 8, and adding a new field to indicate the VREF mute-LED behavior. Reported-and-tested-by: Vitaliy Kulikov <Vitaliy.Kulikov@idt.com> Cc: <stable@kernel.org> [v3.1] Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/hda')
-rw-r--r--sound/pci/hda/patch_sigmatel.c45
1 files changed, 24 insertions, 21 deletions
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index f3658658548e..e035cf6de278 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
@@ -4913,8 +4912,14 @@ static int find_mute_led_gpio(struct hda_codec *codec, int default_polarity)
4913 if (sscanf(dev->name, "HP_Mute_LED_%d_%x", 4912 if (sscanf(dev->name, "HP_Mute_LED_%d_%x",
4914 &spec->gpio_led_polarity, 4913 &spec->gpio_led_polarity,
4915 &spec->gpio_led) == 2) { 4914 &spec->gpio_led) == 2) {
4916 if (spec->gpio_led < 4) 4915 unsigned int max_gpio;
4916 max_gpio = snd_hda_param_read(codec, codec->afg,
4917 AC_PAR_GPIO_CAP);
4918 max_gpio &= AC_GPIO_IO_COUNT;
4919 if (spec->gpio_led < max_gpio)
4917 spec->gpio_led = 1 << spec->gpio_led; 4920 spec->gpio_led = 1 << spec->gpio_led;
4921 else
4922 spec->vref_mute_led_nid = spec->gpio_led;
4918 return 1; 4923 return 1;
4919 } 4924 }
4920 if (sscanf(dev->name, "HP_Mute_LED_%d", 4925 if (sscanf(dev->name, "HP_Mute_LED_%d",
@@ -5043,15 +5048,12 @@ static int stac92xx_pre_resume(struct hda_codec *codec)
5043 struct sigmatel_spec *spec = codec->spec; 5048 struct sigmatel_spec *spec = codec->spec;
5044 5049
5045 /* sync mute LED */ 5050 /* sync mute LED */
5046 if (spec->gpio_led) { 5051 if (spec->vref_mute_led_nid)
5047 if (spec->gpio_led <= 8) { 5052 stac_vrefout_set(codec, spec->vref_mute_led_nid,
5048 stac_gpio_set(codec, spec->gpio_mask, 5053 spec->vref_led);
5049 spec->gpio_dir, spec->gpio_data); 5054 else if (spec->gpio_led)
5050 } else { 5055 stac_gpio_set(codec, spec->gpio_mask,
5051 stac_vrefout_set(codec, 5056 spec->gpio_dir, spec->gpio_data);
5052 spec->gpio_led, spec->vref_led);
5053 }
5054 }
5055 return 0; 5057 return 0;
5056} 5058}
5057 5059
@@ -5076,7 +5078,7 @@ static void stac92xx_set_power_state(struct hda_codec *codec, hda_nid_t fg,
5076 struct sigmatel_spec *spec = codec->spec; 5078 struct sigmatel_spec *spec = codec->spec;
5077 5079
5078 if (power_state == AC_PWRST_D3) { 5080 if (power_state == AC_PWRST_D3) {
5079 if (spec->gpio_led > 8) { 5081 if (spec->vref_mute_led_nid) {
5080 /* with vref-out pin used for mute led control 5082 /* with vref-out pin used for mute led control
5081 * codec AFG is prevented from D3 state 5083 * codec AFG is prevented from D3 state
5082 */ 5084 */
@@ -5129,7 +5131,7 @@ static int stac92xx_update_led_status(struct hda_codec *codec)
5129 } 5131 }
5130 } 5132 }
5131 /*polarity defines *not* muted state level*/ 5133 /*polarity defines *not* muted state level*/
5132 if (spec->gpio_led <= 8) { 5134 if (!spec->vref_mute_led_nid) {
5133 if (muted) 5135 if (muted)
5134 spec->gpio_data &= ~spec->gpio_led; /* orange */ 5136 spec->gpio_data &= ~spec->gpio_led; /* orange */
5135 else 5137 else
@@ -5147,7 +5149,8 @@ static int stac92xx_update_led_status(struct hda_codec *codec)
5147 muted_lvl = spec->gpio_led_polarity ? 5149 muted_lvl = spec->gpio_led_polarity ?
5148 AC_PINCTL_VREF_GRD : AC_PINCTL_VREF_HIZ; 5150 AC_PINCTL_VREF_GRD : AC_PINCTL_VREF_HIZ;
5149 spec->vref_led = muted ? muted_lvl : notmtd_lvl; 5151 spec->vref_led = muted ? muted_lvl : notmtd_lvl;
5150 stac_vrefout_set(codec, spec->gpio_led, spec->vref_led); 5152 stac_vrefout_set(codec, spec->vref_mute_led_nid,
5153 spec->vref_led);
5151 } 5154 }
5152 return 0; 5155 return 0;
5153} 5156}
@@ -5661,7 +5664,7 @@ again:
5661 5664
5662#ifdef CONFIG_SND_HDA_POWER_SAVE 5665#ifdef CONFIG_SND_HDA_POWER_SAVE
5663 if (spec->gpio_led) { 5666 if (spec->gpio_led) {
5664 if (spec->gpio_led <= 8) { 5667 if (!spec->vref_mute_led_nid) {
5665 spec->gpio_mask |= spec->gpio_led; 5668 spec->gpio_mask |= spec->gpio_led;
5666 spec->gpio_dir |= spec->gpio_led; 5669 spec->gpio_dir |= spec->gpio_led;
5667 spec->gpio_data |= spec->gpio_led; 5670 spec->gpio_data |= spec->gpio_led;
@@ -5976,7 +5979,7 @@ again:
5976 5979
5977#ifdef CONFIG_SND_HDA_POWER_SAVE 5980#ifdef CONFIG_SND_HDA_POWER_SAVE
5978 if (spec->gpio_led) { 5981 if (spec->gpio_led) {
5979 if (spec->gpio_led <= 8) { 5982 if (!spec->vref_mute_led_nid) {
5980 spec->gpio_mask |= spec->gpio_led; 5983 spec->gpio_mask |= spec->gpio_led;
5981 spec->gpio_dir |= spec->gpio_led; 5984 spec->gpio_dir |= spec->gpio_led;
5982 spec->gpio_data |= spec->gpio_led; 5985 spec->gpio_data |= spec->gpio_led;