lkml.org 
[lkml]   [2011]   [Dec]   [16]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
Subject[03/53] ALSA: hda - Fix GPIO LED setup for IDT 92HD75 codecs
3.1-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Takashi Iwai <tiwai@suse.de>

commit f1a73746c6664442082e3d53e1804f46e1910436 upstream.

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>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

---
sound/pci/hda/patch_sigmatel.c | 45 +++++++++++++++++++++--------------------
1 file changed, 24 insertions(+), 21 deletions(-)

--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -214,6 +214,7 @@ struct sigmatel_spec {
unsigned int gpio_mute;
unsigned int gpio_led;
unsigned int gpio_led_polarity;
+ unsigned int vref_mute_led_nid; /* pin NID for mute-LED vref control */
unsigned int vref_led;

/* stream */
@@ -4298,12 +4299,10 @@ static void stac_store_hints(struct hda_
spec->eapd_switch = val;
get_int_hint(codec, "gpio_led_polarity", &spec->gpio_led_polarity);
if (get_int_hint(codec, "gpio_led", &spec->gpio_led)) {
- if (spec->gpio_led <= 8) {
- spec->gpio_mask |= spec->gpio_led;
- spec->gpio_dir |= spec->gpio_led;
- if (spec->gpio_led_polarity)
- spec->gpio_data |= spec->gpio_led;
- }
+ spec->gpio_mask |= spec->gpio_led;
+ spec->gpio_dir |= spec->gpio_led;
+ if (spec->gpio_led_polarity)
+ spec->gpio_data |= spec->gpio_led;
}
}

@@ -4893,8 +4892,14 @@ static int find_mute_led_gpio(struct hda
if (sscanf(dev->name, "HP_Mute_LED_%d_%x",
&spec->gpio_led_polarity,
&spec->gpio_led) == 2) {
- if (spec->gpio_led < 4)
+ unsigned int max_gpio;
+ max_gpio = snd_hda_param_read(codec, codec->afg,
+ AC_PAR_GPIO_CAP);
+ max_gpio &= AC_GPIO_IO_COUNT;
+ if (spec->gpio_led < max_gpio)
spec->gpio_led = 1 << spec->gpio_led;
+ else
+ spec->vref_mute_led_nid = spec->gpio_led;
return 1;
}
if (sscanf(dev->name, "HP_Mute_LED_%d",
@@ -5023,15 +5028,12 @@ static int stac92xx_pre_resume(struct hd
struct sigmatel_spec *spec = codec->spec;

/* sync mute LED */
- if (spec->gpio_led) {
- if (spec->gpio_led <= 8) {
- stac_gpio_set(codec, spec->gpio_mask,
- spec->gpio_dir, spec->gpio_data);
- } else {
- stac_vrefout_set(codec,
- spec->gpio_led, spec->vref_led);
- }
- }
+ if (spec->vref_mute_led_nid)
+ stac_vrefout_set(codec, spec->vref_mute_led_nid,
+ spec->vref_led);
+ else if (spec->gpio_led)
+ stac_gpio_set(codec, spec->gpio_mask,
+ spec->gpio_dir, spec->gpio_data);
return 0;
}

@@ -5042,7 +5044,7 @@ static void stac92xx_set_power_state(str
struct sigmatel_spec *spec = codec->spec;

if (power_state == AC_PWRST_D3) {
- if (spec->gpio_led > 8) {
+ if (spec->vref_mute_led_nid) {
/* with vref-out pin used for mute led control
* codec AFG is prevented from D3 state
*/
@@ -5095,7 +5097,7 @@ static int stac92xx_update_led_status(st
}
}
/*polarity defines *not* muted state level*/
- if (spec->gpio_led <= 8) {
+ if (!spec->vref_mute_led_nid) {
if (muted)
spec->gpio_data &= ~spec->gpio_led; /* orange */
else
@@ -5113,7 +5115,8 @@ static int stac92xx_update_led_status(st
muted_lvl = spec->gpio_led_polarity ?
AC_PINCTL_VREF_GRD : AC_PINCTL_VREF_HIZ;
spec->vref_led = muted ? muted_lvl : notmtd_lvl;
- stac_vrefout_set(codec, spec->gpio_led, spec->vref_led);
+ stac_vrefout_set(codec, spec->vref_mute_led_nid,
+ spec->vref_led);
}
return 0;
}
@@ -5634,7 +5637,7 @@ again:

#ifdef CONFIG_SND_HDA_POWER_SAVE
if (spec->gpio_led) {
- if (spec->gpio_led <= 8) {
+ if (!spec->vref_mute_led_nid) {
spec->gpio_mask |= spec->gpio_led;
spec->gpio_dir |= spec->gpio_led;
spec->gpio_data |= spec->gpio_led;
@@ -5955,7 +5958,7 @@ again:

#ifdef CONFIG_SND_HDA_POWER_SAVE
if (spec->gpio_led) {
- if (spec->gpio_led <= 8) {
+ if (!spec->vref_mute_led_nid) {
spec->gpio_mask |= spec->gpio_led;
spec->gpio_dir |= spec->gpio_led;
spec->gpio_data |= spec->gpio_led;



\
 
 \ /
  Last update: 2011-12-16 20:53    [W:0.245 / U:0.020 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site