mirror of https://gitee.com/openkylin/linux.git
ALSA: hda - Don't apply EAPD power filter as default
So far, the driver doesn't power down the widget at going down to D3 when the widget node has an EAPD capability and EAPD is actually set on all codecs unless codec->power_filter is set explicitly. This caused a problem on some Conexant codecs, leading to click noises, and we set it as NULL there. But it is very unlikely that the problem hits only these codecs. Looking back at the development history, this workaround for EAPD was introduced just for some laptops with STAC9200 codec, then we applied it blindly for all. Now, since it's revealed to have an ill effect, we should disable this workaround per default and apply only for the known requiring systems. The EAPD workaround is implemented now as snd_hda_codec_eapd_power_filter(), and this has to be set explicitly by the codec driver when needed. As of now, only patch_stac9200() sets this one. Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
parent
bce0d2a80e
commit
ba615b86d6
|
@ -1296,8 +1296,6 @@ static bool snd_hda_codec_get_supported_ps(struct hda_codec *codec,
|
|||
|
||||
static unsigned int hda_set_power_state(struct hda_codec *codec,
|
||||
unsigned int power_state);
|
||||
static unsigned int default_power_filter(struct hda_codec *codec, hda_nid_t nid,
|
||||
unsigned int power_state);
|
||||
|
||||
/**
|
||||
* snd_hda_codec_new - create a HDA codec
|
||||
|
@ -1418,7 +1416,6 @@ int snd_hda_codec_new(struct hda_bus *bus,
|
|||
#endif
|
||||
codec->epss = snd_hda_codec_get_supported_ps(codec, fg,
|
||||
AC_PWRST_EPSS);
|
||||
codec->power_filter = default_power_filter;
|
||||
|
||||
/* power-up all before initialization */
|
||||
hda_set_power_state(codec, AC_PWRST_D0);
|
||||
|
@ -3759,7 +3756,8 @@ static unsigned int hda_sync_power_state(struct hda_codec *codec,
|
|||
}
|
||||
|
||||
/* don't power down the widget if it controls eapd and EAPD_BTLENABLE is set */
|
||||
static unsigned int default_power_filter(struct hda_codec *codec, hda_nid_t nid,
|
||||
unsigned int snd_hda_codec_eapd_power_filter(struct hda_codec *codec,
|
||||
hda_nid_t nid,
|
||||
unsigned int power_state)
|
||||
{
|
||||
if (power_state == AC_PWRST_D3 &&
|
||||
|
@ -3772,6 +3770,7 @@ static unsigned int default_power_filter(struct hda_codec *codec, hda_nid_t nid,
|
|||
}
|
||||
return power_state;
|
||||
}
|
||||
EXPORT_SYMBOL_HDA(snd_hda_codec_eapd_power_filter);
|
||||
|
||||
/*
|
||||
* set power state of the codec, and return the power state
|
||||
|
@ -3816,8 +3815,8 @@ static void sync_power_up_states(struct hda_codec *codec)
|
|||
hda_nid_t nid = codec->start_nid;
|
||||
int i;
|
||||
|
||||
/* don't care if no or standard filter is used */
|
||||
if (!codec->power_filter || codec->power_filter == default_power_filter)
|
||||
/* don't care if no filter is used */
|
||||
if (!codec->power_filter)
|
||||
return;
|
||||
|
||||
for (i = 0; i < codec->num_nodes; i++, nid++) {
|
||||
|
|
|
@ -670,6 +670,10 @@ snd_hda_check_power_state(struct hda_codec *codec, hda_nid_t nid,
|
|||
return (state != target_state);
|
||||
}
|
||||
|
||||
unsigned int snd_hda_codec_eapd_power_filter(struct hda_codec *codec,
|
||||
hda_nid_t nid,
|
||||
unsigned int power_state);
|
||||
|
||||
/*
|
||||
* AMP control callbacks
|
||||
*/
|
||||
|
|
|
@ -3350,7 +3350,6 @@ static int patch_conexant_auto(struct hda_codec *codec)
|
|||
switch (codec->vendor_id) {
|
||||
case 0x14f15045:
|
||||
codec->single_adc_amp = 1;
|
||||
codec->power_filter = NULL; /* Needs speaker amp to D3 to avoid click */
|
||||
break;
|
||||
case 0x14f15047:
|
||||
codec->pin_amp_workaround = 1;
|
||||
|
|
|
@ -3774,6 +3774,7 @@ static int patch_stac9200(struct hda_codec *codec)
|
|||
spec->gen.own_eapd_ctl = 1;
|
||||
|
||||
codec->patch_ops = stac_patch_ops;
|
||||
codec->power_filter = snd_hda_codec_eapd_power_filter;
|
||||
|
||||
snd_hda_add_verbs(codec, stac9200_eapd_init);
|
||||
|
||||
|
|
Loading…
Reference in New Issue