aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2014-01-13 10:09:57 -0500
committerTakashi Iwai <tiwai@suse.de>2014-01-13 10:30:15 -0500
commitdfc6e469b6d1ee5e8c71fa398b7b58fbb600dad8 (patch)
tree0be5382d677d330bc326f4931cabf0e483d09a52 /sound/pci
parentcbd209f41ea5f39394de5c1fe2dd9aa54a9c5744 (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.c12
-rw-r--r--sound/pci/hda/hda_generic.c5
-rw-r--r--sound/pci/hda/hda_generic.h3
-rw-r--r--sound/pci/hda/patch_sigmatel.c36
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 */
4315static unsigned int snd_hda_gen_path_power_filter(struct hda_codec *codec, 4315unsigned 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}
4327EXPORT_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 */
4329static void mute_all_mixer_nid(struct hda_codec *codec, hda_nid_t mix) 4330static 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
336int snd_hda_gen_check_power_status(struct hda_codec *codec, hda_nid_t nid); 336int snd_hda_gen_check_power_status(struct hda_codec *codec, hda_nid_t nid);
337#endif 337#endif
338unsigned 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() */
373static 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 */
372static void stac_update_led_status(struct hda_codec *codec, int enabled) 383static 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
4264static 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
4289static const struct hda_codec_ops stac_patch_ops = { 4278static 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