diff options
author | Takashi Iwai <tiwai@suse.de> | 2014-01-13 10:09:57 -0500 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2014-01-13 10:30:15 -0500 |
commit | dfc6e469b6d1ee5e8c71fa398b7b58fbb600dad8 (patch) | |
tree | 0be5382d677d330bc326f4931cabf0e483d09a52 /sound/pci | |
parent | cbd209f41ea5f39394de5c1fe2dd9aa54a9c5744 (diff) |
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>
Diffstat (limited to 'sound/pci')
-rw-r--r-- | sound/pci/hda/hda_codec.c | 12 | ||||
-rw-r--r-- | sound/pci/hda/hda_generic.c | 5 | ||||
-rw-r--r-- | sound/pci/hda/hda_generic.h | 3 | ||||
-rw-r--r-- | sound/pci/hda/patch_sigmatel.c | 36 |
4 files changed, 27 insertions, 29 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index ab2a991d916f..ec4536c8d8d4 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c | |||
@@ -3927,6 +3927,8 @@ unsigned int snd_hda_codec_eapd_power_filter(struct hda_codec *codec, | |||
3927 | hda_nid_t nid, | 3927 | hda_nid_t nid, |
3928 | unsigned int power_state) | 3928 | unsigned int power_state) |
3929 | { | 3929 | { |
3930 | if (nid == codec->afg || nid == codec->mfg) | ||
3931 | return power_state; | ||
3930 | if (power_state == AC_PWRST_D3 && | 3932 | if (power_state == AC_PWRST_D3 && |
3931 | get_wcaps_type(get_wcaps(codec, nid)) == AC_WID_PIN && | 3933 | get_wcaps_type(get_wcaps(codec, nid)) == AC_WID_PIN && |
3932 | (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)) { | 3934 | (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, | |||
3965 | codec->patch_ops.set_power_state(codec, fg, | 3967 | codec->patch_ops.set_power_state(codec, fg, |
3966 | power_state); | 3968 | power_state); |
3967 | else { | 3969 | else { |
3968 | snd_hda_codec_read(codec, fg, flags, | 3970 | state = power_state; |
3969 | AC_VERB_SET_POWER_STATE, | 3971 | if (codec->power_filter) |
3970 | power_state); | 3972 | state = codec->power_filter(codec, fg, state); |
3973 | if (state == power_state || power_state != AC_PWRST_D3) | ||
3974 | snd_hda_codec_read(codec, fg, flags, | ||
3975 | AC_VERB_SET_POWER_STATE, | ||
3976 | state); | ||
3971 | snd_hda_codec_set_power_to_all(codec, fg, power_state); | 3977 | snd_hda_codec_set_power_to_all(codec, fg, power_state); |
3972 | } | 3978 | } |
3973 | state = hda_sync_power_state(codec, fg, power_state); | 3979 | state = hda_sync_power_state(codec, fg, power_state); |
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c index 7513089c8985..8321a97d5c05 100644 --- a/sound/pci/hda/hda_generic.c +++ b/sound/pci/hda/hda_generic.c | |||
@@ -4312,11 +4312,11 @@ static int check_auto_mic_availability(struct hda_codec *codec) | |||
4312 | } | 4312 | } |
4313 | 4313 | ||
4314 | /* power_filter hook; make inactive widgets into power down */ | 4314 | /* power_filter hook; make inactive widgets into power down */ |
4315 | static unsigned int snd_hda_gen_path_power_filter(struct hda_codec *codec, | 4315 | unsigned int snd_hda_gen_path_power_filter(struct hda_codec *codec, |
4316 | hda_nid_t nid, | 4316 | hda_nid_t nid, |
4317 | unsigned int power_state) | 4317 | unsigned int power_state) |
4318 | { | 4318 | { |
4319 | if (power_state != AC_PWRST_D0) | 4319 | if (power_state != AC_PWRST_D0 || nid == codec->afg) |
4320 | return power_state; | 4320 | return power_state; |
4321 | if (get_wcaps_type(get_wcaps(codec, nid)) >= AC_WID_POWER) | 4321 | if (get_wcaps_type(get_wcaps(codec, nid)) >= AC_WID_POWER) |
4322 | return power_state; | 4322 | return power_state; |
@@ -4324,6 +4324,7 @@ static unsigned int snd_hda_gen_path_power_filter(struct hda_codec *codec, | |||
4324 | return power_state; | 4324 | return power_state; |
4325 | return AC_PWRST_D3; | 4325 | return AC_PWRST_D3; |
4326 | } | 4326 | } |
4327 | EXPORT_SYMBOL_GPL(snd_hda_gen_path_power_filter); | ||
4327 | 4328 | ||
4328 | /* mute all aamix inputs initially; parse up to the first leaves */ | 4329 | /* mute all aamix inputs initially; parse up to the first leaves */ |
4329 | static void mute_all_mixer_nid(struct hda_codec *codec, hda_nid_t mix) | 4330 | static void mute_all_mixer_nid(struct hda_codec *codec, hda_nid_t mix) |
diff --git a/sound/pci/hda/hda_generic.h b/sound/pci/hda/hda_generic.h index 0929a06df812..07f767231c9f 100644 --- a/sound/pci/hda/hda_generic.h +++ b/sound/pci/hda/hda_generic.h | |||
@@ -335,5 +335,8 @@ void snd_hda_gen_update_outputs(struct hda_codec *codec); | |||
335 | #ifdef CONFIG_PM | 335 | #ifdef CONFIG_PM |
336 | int snd_hda_gen_check_power_status(struct hda_codec *codec, hda_nid_t nid); | 336 | int snd_hda_gen_check_power_status(struct hda_codec *codec, hda_nid_t nid); |
337 | #endif | 337 | #endif |
338 | unsigned int snd_hda_gen_path_power_filter(struct hda_codec *codec, | ||
339 | hda_nid_t nid, | ||
340 | unsigned int power_state); | ||
338 | 341 | ||
339 | #endif /* __SOUND_HDA_GENERIC_H */ | 342 | #endif /* __SOUND_HDA_GENERIC_H */ |
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 088a5afbd1b9..6998cf29b9bc 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c | |||
@@ -368,6 +368,17 @@ static int stac_vrefout_set(struct hda_codec *codec, | |||
368 | return 1; | 368 | return 1; |
369 | } | 369 | } |
370 | 370 | ||
371 | /* prevent codec AFG to D3 state when vref-out pin is used for mute LED */ | ||
372 | /* this hook is set in stac_setup_gpio() */ | ||
373 | static unsigned int stac_vref_led_power_filter(struct hda_codec *codec, | ||
374 | hda_nid_t nid, | ||
375 | unsigned int power_state) | ||
376 | { | ||
377 | if (nid == codec->afg && power_state == AC_PWRST_D3) | ||
378 | return AC_PWRST_D1; | ||
379 | return snd_hda_gen_path_power_filter(codec, nid, power_state); | ||
380 | } | ||
381 | |||
371 | /* update mute-LED accoring to the master switch */ | 382 | /* update mute-LED accoring to the master switch */ |
372 | static void stac_update_led_status(struct hda_codec *codec, int enabled) | 383 | static void stac_update_led_status(struct hda_codec *codec, int enabled) |
373 | { | 384 | { |
@@ -4260,30 +4271,8 @@ static int stac_suspend(struct hda_codec *codec) | |||
4260 | stac_shutup(codec); | 4271 | stac_shutup(codec); |
4261 | return 0; | 4272 | return 0; |
4262 | } | 4273 | } |
4263 | |||
4264 | static void stac_set_power_state(struct hda_codec *codec, hda_nid_t fg, | ||
4265 | unsigned int power_state) | ||
4266 | { | ||
4267 | unsigned int afg_power_state = power_state; | ||
4268 | struct sigmatel_spec *spec = codec->spec; | ||
4269 | |||
4270 | if (power_state == AC_PWRST_D3) { | ||
4271 | if (spec->vref_mute_led_nid) { | ||
4272 | /* with vref-out pin used for mute led control | ||
4273 | * codec AFG is prevented from D3 state | ||
4274 | */ | ||
4275 | afg_power_state = AC_PWRST_D1; | ||
4276 | } | ||
4277 | /* this delay seems necessary to avoid click noise at power-down */ | ||
4278 | msleep(100); | ||
4279 | } | ||
4280 | snd_hda_codec_read(codec, fg, 0, AC_VERB_SET_POWER_STATE, | ||
4281 | afg_power_state); | ||
4282 | snd_hda_codec_set_power_to_all(codec, fg, power_state); | ||
4283 | } | ||
4284 | #else | 4274 | #else |
4285 | #define stac_suspend NULL | 4275 | #define stac_suspend NULL |
4286 | #define stac_set_power_state NULL | ||
4287 | #endif /* CONFIG_PM */ | 4276 | #endif /* CONFIG_PM */ |
4288 | 4277 | ||
4289 | static const struct hda_codec_ops stac_patch_ops = { | 4278 | static const struct hda_codec_ops stac_patch_ops = { |
@@ -4466,8 +4455,7 @@ static void stac_setup_gpio(struct hda_codec *codec) | |||
4466 | spec->gpio_dir |= spec->gpio_led; | 4455 | spec->gpio_dir |= spec->gpio_led; |
4467 | spec->gpio_data |= spec->gpio_led; | 4456 | spec->gpio_data |= spec->gpio_led; |
4468 | } else { | 4457 | } else { |
4469 | codec->patch_ops.set_power_state = | 4458 | codec->power_filter = stac_vref_led_power_filter; |
4470 | stac_set_power_state; | ||
4471 | } | 4459 | } |
4472 | } | 4460 | } |
4473 | 4461 | ||