diff options
Diffstat (limited to 'sound/pci/hda/patch_sigmatel.c')
| -rw-r--r-- | sound/pci/hda/patch_sigmatel.c | 75 | 
1 files changed, 35 insertions, 40 deletions
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 470f6f286e8..616678fde48 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -215,6 +215,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 */ @@ -1641,6 +1642,8 @@ static const struct snd_pci_quirk stac92hd73xx_codec_id_cfg_tbl[] = {  		      "Alienware M17x", STAC_ALIENWARE_M17X),  	SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x043a,  		      "Alienware M17x", STAC_ALIENWARE_M17X), +	SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0490, +		      "Alienware M17x", STAC_ALIENWARE_M17X),  	{} /* terminator */  }; @@ -4316,12 +4319,10 @@ static void stac_store_hints(struct hda_codec *codec)  		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;  	}  } @@ -4439,7 +4440,9 @@ static int stac92xx_init(struct hda_codec *codec)  		int pinctl, def_conf;  		/* power on when no jack detection is available */ -		if (!spec->hp_detect) { +		/* or when the VREF is used for controlling LED */ +		if (!spec->hp_detect || +		    spec->vref_mute_led_nid == nid) {  			stac_toggle_power_map(codec, nid, 1);  			continue;  		} @@ -4911,8 +4914,14 @@ static int find_mute_led_gpio(struct hda_codec *codec, int default_polarity)  			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", @@ -4920,6 +4929,12 @@ static int find_mute_led_gpio(struct hda_codec *codec, int default_polarity)  				set_hp_led_gpio(codec);  				return 1;  			} +			/* BIOS bug: unfilled OEM string */ +			if (strstr(dev->name, "HP_Mute_LED_P_G")) { +				set_hp_led_gpio(codec); +				spec->gpio_led_polarity = 1; +				return 1; +			}  		}  		/* @@ -5041,29 +5056,12 @@ static int stac92xx_pre_resume(struct hda_codec *codec)  	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); -		} -	} -	return 0; -} - -static int stac92xx_post_suspend(struct hda_codec *codec) -{ -	struct sigmatel_spec *spec = codec->spec; -	if (spec->gpio_led > 8) { -		/* with vref-out pin used for mute led control -		 * codec AFG is prevented from D3 state, but on -		 * system suspend it can (and should) be used -		 */ -		snd_hda_codec_read(codec, codec->afg, 0, -				AC_VERB_SET_POWER_STATE, AC_PWRST_D3); -	} +	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;  } @@ -5074,7 +5072,7 @@ static void stac92xx_set_power_state(struct hda_codec *codec, hda_nid_t fg,  	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  			 */ @@ -5127,7 +5125,7 @@ static int stac92xx_update_led_status(struct hda_codec *codec)  		}  	}  	/*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 @@ -5145,7 +5143,8 @@ static int stac92xx_update_led_status(struct hda_codec *codec)  		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;  } @@ -5659,15 +5658,13 @@ 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;  		} else {  			codec->patch_ops.set_power_state =  					stac92xx_set_power_state; -			codec->patch_ops.post_suspend = -					stac92xx_post_suspend;  		}  		codec->patch_ops.pre_resume = stac92xx_pre_resume;  		codec->patch_ops.check_power_status = @@ -5974,15 +5971,13 @@ 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;  		} else {  			codec->patch_ops.set_power_state =  					stac92xx_set_power_state; -			codec->patch_ops.post_suspend = -					stac92xx_post_suspend;  		}  		codec->patch_ops.pre_resume = stac92xx_pre_resume;  		codec->patch_ops.check_power_status =  |