diff options
author | Kailang Yang <kailang@realtek.com> | 2019-05-06 03:09:42 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2019-05-07 05:18:21 -0400 |
commit | d3ba58bb895915f7f9105e0844441d2ca7d83340 (patch) | |
tree | 935823f39ee4fe1a92df3a441a4c91b936c9babf /sound | |
parent | 7f641e26a6df9269cb25dd7a4b0a91d6586ed441 (diff) |
ALSA: hda/realtek - Support low power consumption for ALC295
Enter to close more power control widgets at suspend.
Remove hp_pin check. Add the default pin 0x21 as headphone.
Supported low power consumption, it must do depop procedure when
headset jack was plugged or unplugged.
So, alc225_init() and alc225_shutup() must run delay when headset
jack was plugged or unplugged.
If depop procedure not run with delay, it will have a chance to let
power consumption raise high.
[ A few compile fixes by tiwai ]
Fixes: 8983eb602af5 ("ALSA: hda/realtek - Move to ACT_INIT state")
Signed-off-by: Kailang Yang <kailang@realtek.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound')
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 46 |
1 files changed, 31 insertions, 15 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index d743f2b0e3cf..e733d323f1a7 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -119,6 +119,7 @@ struct alc_spec { | |||
119 | unsigned int no_depop_delay:1; | 119 | unsigned int no_depop_delay:1; |
120 | unsigned int done_hp_init:1; | 120 | unsigned int done_hp_init:1; |
121 | unsigned int no_shutup_pins:1; | 121 | unsigned int no_shutup_pins:1; |
122 | unsigned int ultra_low_power:1; | ||
122 | 123 | ||
123 | /* for PLL fix */ | 124 | /* for PLL fix */ |
124 | hda_nid_t pll_nid; | 125 | hda_nid_t pll_nid; |
@@ -3269,8 +3270,7 @@ static void alc225_init(struct hda_codec *codec) | |||
3269 | bool hp1_pin_sense, hp2_pin_sense; | 3270 | bool hp1_pin_sense, hp2_pin_sense; |
3270 | 3271 | ||
3271 | if (!hp_pin) | 3272 | if (!hp_pin) |
3272 | return; | 3273 | hp_pin = 0x21; |
3273 | |||
3274 | msleep(30); | 3274 | msleep(30); |
3275 | 3275 | ||
3276 | hp1_pin_sense = snd_hda_jack_detect(codec, hp_pin); | 3276 | hp1_pin_sense = snd_hda_jack_detect(codec, hp_pin); |
@@ -3280,25 +3280,31 @@ static void alc225_init(struct hda_codec *codec) | |||
3280 | msleep(2); | 3280 | msleep(2); |
3281 | 3281 | ||
3282 | alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x1); /* Low power */ | 3282 | alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x1); /* Low power */ |
3283 | if (spec->ultra_low_power) { | ||
3284 | alc_update_coef_idx(codec, 0x08, 0x0f << 2, 3<<2); | ||
3285 | alc_update_coef_idx(codec, 0x0e, 7<<6, 7<<6); | ||
3286 | alc_update_coef_idx(codec, 0x33, 1<<11, 0); | ||
3287 | msleep(30); | ||
3288 | } | ||
3283 | 3289 | ||
3284 | if (hp1_pin_sense) | 3290 | if (hp1_pin_sense || spec->ultra_low_power) |
3285 | snd_hda_codec_write(codec, hp_pin, 0, | 3291 | snd_hda_codec_write(codec, hp_pin, 0, |
3286 | AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); | 3292 | AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); |
3287 | if (hp2_pin_sense) | 3293 | if (hp2_pin_sense) |
3288 | snd_hda_codec_write(codec, 0x16, 0, | 3294 | snd_hda_codec_write(codec, 0x16, 0, |
3289 | AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); | 3295 | AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); |
3290 | 3296 | ||
3291 | if (hp1_pin_sense || hp2_pin_sense) | 3297 | if (hp1_pin_sense || hp2_pin_sense || spec->ultra_low_power) |
3292 | msleep(85); | 3298 | msleep(85); |
3293 | 3299 | ||
3294 | if (hp1_pin_sense) | 3300 | if (hp1_pin_sense || spec->ultra_low_power) |
3295 | snd_hda_codec_write(codec, hp_pin, 0, | 3301 | snd_hda_codec_write(codec, hp_pin, 0, |
3296 | AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); | 3302 | AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); |
3297 | if (hp2_pin_sense) | 3303 | if (hp2_pin_sense) |
3298 | snd_hda_codec_write(codec, 0x16, 0, | 3304 | snd_hda_codec_write(codec, 0x16, 0, |
3299 | AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); | 3305 | AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); |
3300 | 3306 | ||
3301 | if (hp1_pin_sense || hp2_pin_sense) | 3307 | if (hp1_pin_sense || hp2_pin_sense || spec->ultra_low_power) |
3302 | msleep(100); | 3308 | msleep(100); |
3303 | 3309 | ||
3304 | alc_update_coef_idx(codec, 0x4a, 3 << 10, 0); | 3310 | alc_update_coef_idx(codec, 0x4a, 3 << 10, 0); |
@@ -3311,11 +3317,8 @@ static void alc225_shutup(struct hda_codec *codec) | |||
3311 | hda_nid_t hp_pin = alc_get_hp_pin(spec); | 3317 | hda_nid_t hp_pin = alc_get_hp_pin(spec); |
3312 | bool hp1_pin_sense, hp2_pin_sense; | 3318 | bool hp1_pin_sense, hp2_pin_sense; |
3313 | 3319 | ||
3314 | if (!hp_pin) { | 3320 | if (!hp_pin) |
3315 | alc269_shutup(codec); | 3321 | hp_pin = 0x21; |
3316 | return; | ||
3317 | } | ||
3318 | |||
3319 | /* 3k pull low control for Headset jack. */ | 3322 | /* 3k pull low control for Headset jack. */ |
3320 | alc_update_coef_idx(codec, 0x4a, 0, 3 << 10); | 3323 | alc_update_coef_idx(codec, 0x4a, 0, 3 << 10); |
3321 | 3324 | ||
@@ -3325,28 +3328,36 @@ static void alc225_shutup(struct hda_codec *codec) | |||
3325 | if (hp1_pin_sense || hp2_pin_sense) | 3328 | if (hp1_pin_sense || hp2_pin_sense) |
3326 | msleep(2); | 3329 | msleep(2); |
3327 | 3330 | ||
3328 | if (hp1_pin_sense) | 3331 | if (hp1_pin_sense || spec->ultra_low_power) |
3329 | snd_hda_codec_write(codec, hp_pin, 0, | 3332 | snd_hda_codec_write(codec, hp_pin, 0, |
3330 | AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); | 3333 | AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); |
3331 | if (hp2_pin_sense) | 3334 | if (hp2_pin_sense) |
3332 | snd_hda_codec_write(codec, 0x16, 0, | 3335 | snd_hda_codec_write(codec, 0x16, 0, |
3333 | AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); | 3336 | AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); |
3334 | 3337 | ||
3335 | if (hp1_pin_sense || hp2_pin_sense) | 3338 | if (hp1_pin_sense || hp2_pin_sense || spec->ultra_low_power) |
3336 | msleep(85); | 3339 | msleep(85); |
3337 | 3340 | ||
3338 | if (hp1_pin_sense) | 3341 | if (hp1_pin_sense || spec->ultra_low_power) |
3339 | snd_hda_codec_write(codec, hp_pin, 0, | 3342 | snd_hda_codec_write(codec, hp_pin, 0, |
3340 | AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0); | 3343 | AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0); |
3341 | if (hp2_pin_sense) | 3344 | if (hp2_pin_sense) |
3342 | snd_hda_codec_write(codec, 0x16, 0, | 3345 | snd_hda_codec_write(codec, 0x16, 0, |
3343 | AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0); | 3346 | AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0); |
3344 | 3347 | ||
3345 | if (hp1_pin_sense || hp2_pin_sense) | 3348 | if (hp1_pin_sense || hp2_pin_sense || spec->ultra_low_power) |
3346 | msleep(100); | 3349 | msleep(100); |
3347 | 3350 | ||
3348 | alc_auto_setup_eapd(codec, false); | 3351 | alc_auto_setup_eapd(codec, false); |
3349 | alc_shutup_pins(codec); | 3352 | alc_shutup_pins(codec); |
3353 | if (spec->ultra_low_power) { | ||
3354 | msleep(50); | ||
3355 | alc_update_coef_idx(codec, 0x08, 0x0f << 2, 0x0c << 2); | ||
3356 | alc_update_coef_idx(codec, 0x0e, 7<<6, 0); | ||
3357 | alc_update_coef_idx(codec, 0x33, 1<<11, 1<<11); | ||
3358 | alc_update_coef_idx(codec, 0x4a, 3<<4, 2<<4); | ||
3359 | msleep(30); | ||
3360 | } | ||
3350 | } | 3361 | } |
3351 | 3362 | ||
3352 | static void alc_default_init(struct hda_codec *codec) | 3363 | static void alc_default_init(struct hda_codec *codec) |
@@ -5526,7 +5537,12 @@ static void alc_fixup_headset_jack(struct hda_codec *codec, | |||
5526 | static void alc295_fixup_chromebook(struct hda_codec *codec, | 5537 | static void alc295_fixup_chromebook(struct hda_codec *codec, |
5527 | const struct hda_fixup *fix, int action) | 5538 | const struct hda_fixup *fix, int action) |
5528 | { | 5539 | { |
5540 | struct alc_spec *spec = codec->spec; | ||
5541 | |||
5529 | switch (action) { | 5542 | switch (action) { |
5543 | case HDA_FIXUP_ACT_PRE_PROBE: | ||
5544 | spec->ultra_low_power = true; | ||
5545 | break; | ||
5530 | case HDA_FIXUP_ACT_INIT: | 5546 | case HDA_FIXUP_ACT_INIT: |
5531 | switch (codec->core.vendor_id) { | 5547 | switch (codec->core.vendor_id) { |
5532 | case 0x10ec0295: | 5548 | case 0x10ec0295: |