ALSA: hda - Apply codec power_filter to FG nodes
Apply the codec->power_filter to the FG nodes in general for reducing hackish set_power_state ops override in patch_sigmatel.c. Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
parent
cbd209f41e
commit
dfc6e469b6
@ -3927,6 +3927,8 @@ unsigned int snd_hda_codec_eapd_power_filter(struct hda_codec *codec,
|
|||||||
hda_nid_t nid,
|
hda_nid_t nid,
|
||||||
unsigned int power_state)
|
unsigned int power_state)
|
||||||
{
|
{
|
||||||
|
if (nid == codec->afg || nid == codec->mfg)
|
||||||
|
return power_state;
|
||||||
if (power_state == AC_PWRST_D3 &&
|
if (power_state == AC_PWRST_D3 &&
|
||||||
get_wcaps_type(get_wcaps(codec, nid)) == AC_WID_PIN &&
|
get_wcaps_type(get_wcaps(codec, nid)) == AC_WID_PIN &&
|
||||||
(snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)) {
|
(snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)) {
|
||||||
@ -3965,9 +3967,13 @@ static unsigned int hda_set_power_state(struct hda_codec *codec,
|
|||||||
codec->patch_ops.set_power_state(codec, fg,
|
codec->patch_ops.set_power_state(codec, fg,
|
||||||
power_state);
|
power_state);
|
||||||
else {
|
else {
|
||||||
snd_hda_codec_read(codec, fg, flags,
|
state = power_state;
|
||||||
AC_VERB_SET_POWER_STATE,
|
if (codec->power_filter)
|
||||||
power_state);
|
state = codec->power_filter(codec, fg, state);
|
||||||
|
if (state == power_state || power_state != AC_PWRST_D3)
|
||||||
|
snd_hda_codec_read(codec, fg, flags,
|
||||||
|
AC_VERB_SET_POWER_STATE,
|
||||||
|
state);
|
||||||
snd_hda_codec_set_power_to_all(codec, fg, power_state);
|
snd_hda_codec_set_power_to_all(codec, fg, power_state);
|
||||||
}
|
}
|
||||||
state = hda_sync_power_state(codec, fg, power_state);
|
state = hda_sync_power_state(codec, fg, power_state);
|
||||||
|
@ -4312,11 +4312,11 @@ static int check_auto_mic_availability(struct hda_codec *codec)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* power_filter hook; make inactive widgets into power down */
|
/* power_filter hook; make inactive widgets into power down */
|
||||||
static unsigned int snd_hda_gen_path_power_filter(struct hda_codec *codec,
|
unsigned int snd_hda_gen_path_power_filter(struct hda_codec *codec,
|
||||||
hda_nid_t nid,
|
hda_nid_t nid,
|
||||||
unsigned int power_state)
|
unsigned int power_state)
|
||||||
{
|
{
|
||||||
if (power_state != AC_PWRST_D0)
|
if (power_state != AC_PWRST_D0 || nid == codec->afg)
|
||||||
return power_state;
|
return power_state;
|
||||||
if (get_wcaps_type(get_wcaps(codec, nid)) >= AC_WID_POWER)
|
if (get_wcaps_type(get_wcaps(codec, nid)) >= AC_WID_POWER)
|
||||||
return power_state;
|
return power_state;
|
||||||
@ -4324,6 +4324,7 @@ static unsigned int snd_hda_gen_path_power_filter(struct hda_codec *codec,
|
|||||||
return power_state;
|
return power_state;
|
||||||
return AC_PWRST_D3;
|
return AC_PWRST_D3;
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(snd_hda_gen_path_power_filter);
|
||||||
|
|
||||||
/* mute all aamix inputs initially; parse up to the first leaves */
|
/* mute all aamix inputs initially; parse up to the first leaves */
|
||||||
static void mute_all_mixer_nid(struct hda_codec *codec, hda_nid_t mix)
|
static void mute_all_mixer_nid(struct hda_codec *codec, hda_nid_t mix)
|
||||||
|
@ -335,5 +335,8 @@ void snd_hda_gen_update_outputs(struct hda_codec *codec);
|
|||||||
#ifdef CONFIG_PM
|
#ifdef CONFIG_PM
|
||||||
int snd_hda_gen_check_power_status(struct hda_codec *codec, hda_nid_t nid);
|
int snd_hda_gen_check_power_status(struct hda_codec *codec, hda_nid_t nid);
|
||||||
#endif
|
#endif
|
||||||
|
unsigned int snd_hda_gen_path_power_filter(struct hda_codec *codec,
|
||||||
|
hda_nid_t nid,
|
||||||
|
unsigned int power_state);
|
||||||
|
|
||||||
#endif /* __SOUND_HDA_GENERIC_H */
|
#endif /* __SOUND_HDA_GENERIC_H */
|
||||||
|
@ -368,6 +368,17 @@ static int stac_vrefout_set(struct hda_codec *codec,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* prevent codec AFG to D3 state when vref-out pin is used for mute LED */
|
||||||
|
/* this hook is set in stac_setup_gpio() */
|
||||||
|
static unsigned int stac_vref_led_power_filter(struct hda_codec *codec,
|
||||||
|
hda_nid_t nid,
|
||||||
|
unsigned int power_state)
|
||||||
|
{
|
||||||
|
if (nid == codec->afg && power_state == AC_PWRST_D3)
|
||||||
|
return AC_PWRST_D1;
|
||||||
|
return snd_hda_gen_path_power_filter(codec, nid, power_state);
|
||||||
|
}
|
||||||
|
|
||||||
/* update mute-LED accoring to the master switch */
|
/* update mute-LED accoring to the master switch */
|
||||||
static void stac_update_led_status(struct hda_codec *codec, int enabled)
|
static void stac_update_led_status(struct hda_codec *codec, int enabled)
|
||||||
{
|
{
|
||||||
@ -4260,30 +4271,8 @@ static int stac_suspend(struct hda_codec *codec)
|
|||||||
stac_shutup(codec);
|
stac_shutup(codec);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void stac_set_power_state(struct hda_codec *codec, hda_nid_t fg,
|
|
||||||
unsigned int power_state)
|
|
||||||
{
|
|
||||||
unsigned int afg_power_state = power_state;
|
|
||||||
struct sigmatel_spec *spec = codec->spec;
|
|
||||||
|
|
||||||
if (power_state == AC_PWRST_D3) {
|
|
||||||
if (spec->vref_mute_led_nid) {
|
|
||||||
/* with vref-out pin used for mute led control
|
|
||||||
* codec AFG is prevented from D3 state
|
|
||||||
*/
|
|
||||||
afg_power_state = AC_PWRST_D1;
|
|
||||||
}
|
|
||||||
/* this delay seems necessary to avoid click noise at power-down */
|
|
||||||
msleep(100);
|
|
||||||
}
|
|
||||||
snd_hda_codec_read(codec, fg, 0, AC_VERB_SET_POWER_STATE,
|
|
||||||
afg_power_state);
|
|
||||||
snd_hda_codec_set_power_to_all(codec, fg, power_state);
|
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
#define stac_suspend NULL
|
#define stac_suspend NULL
|
||||||
#define stac_set_power_state NULL
|
|
||||||
#endif /* CONFIG_PM */
|
#endif /* CONFIG_PM */
|
||||||
|
|
||||||
static const struct hda_codec_ops stac_patch_ops = {
|
static const struct hda_codec_ops stac_patch_ops = {
|
||||||
@ -4466,8 +4455,7 @@ static void stac_setup_gpio(struct hda_codec *codec)
|
|||||||
spec->gpio_dir |= spec->gpio_led;
|
spec->gpio_dir |= spec->gpio_led;
|
||||||
spec->gpio_data |= spec->gpio_led;
|
spec->gpio_data |= spec->gpio_led;
|
||||||
} else {
|
} else {
|
||||||
codec->patch_ops.set_power_state =
|
codec->power_filter = stac_vref_led_power_filter;
|
||||||
stac_set_power_state;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user