diff options
author | Takashi Iwai <tiwai@suse.de> | 2011-05-13 10:24:15 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2011-05-13 10:24:15 -0400 |
commit | da33986651e137b1ea2ec21794e32bc5c57b03d0 (patch) | |
tree | cf7f01f3f6119ea8dcd331c0527920d09767e497 /sound | |
parent | 2557f7427d4bd1fc00166556e3047c5f3ed91958 (diff) |
ALSA: hda - Turn on EAPD dynamically per jack plug in Conexant auto mode
Instead of keeping always EAPD on, turn on/off appropriately at jack
plugging in Conexant auto-parser mode.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound')
-rw-r--r-- | sound/pci/hda/patch_conexant.c | 25 |
1 files changed, 17 insertions, 8 deletions
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index eecc154d0b63..d63e15b8937a 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c | |||
@@ -3325,6 +3325,9 @@ static void cx_auto_parse_output(struct hda_codec *codec) | |||
3325 | spec->vmaster_nid = spec->private_dac_nids[0]; | 3325 | spec->vmaster_nid = spec->private_dac_nids[0]; |
3326 | } | 3326 | } |
3327 | 3327 | ||
3328 | static void cx_auto_turn_eapd(struct hda_codec *codec, int num_pins, | ||
3329 | hda_nid_t *pins, bool on); | ||
3330 | |||
3328 | /* auto-mute/unmute speaker and line outs according to headphone jack */ | 3331 | /* auto-mute/unmute speaker and line outs according to headphone jack */ |
3329 | static void cx_auto_hp_automute(struct hda_codec *codec) | 3332 | static void cx_auto_hp_automute(struct hda_codec *codec) |
3330 | { | 3333 | { |
@@ -3341,11 +3344,13 @@ static void cx_auto_hp_automute(struct hda_codec *codec) | |||
3341 | break; | 3344 | break; |
3342 | } | 3345 | } |
3343 | } | 3346 | } |
3347 | cx_auto_turn_eapd(codec, cfg->hp_outs, cfg->hp_pins, present); | ||
3344 | for (i = 0; i < cfg->line_outs; i++) { | 3348 | for (i = 0; i < cfg->line_outs; i++) { |
3345 | snd_hda_codec_write(codec, cfg->line_out_pins[i], 0, | 3349 | snd_hda_codec_write(codec, cfg->line_out_pins[i], 0, |
3346 | AC_VERB_SET_PIN_WIDGET_CONTROL, | 3350 | AC_VERB_SET_PIN_WIDGET_CONTROL, |
3347 | present ? 0 : PIN_OUT); | 3351 | present ? 0 : PIN_OUT); |
3348 | } | 3352 | } |
3353 | cx_auto_turn_eapd(codec, cfg->line_outs, cfg->line_out_pins, !present); | ||
3349 | for (i = 0; !present && i < cfg->line_outs; i++) | 3354 | for (i = 0; !present && i < cfg->line_outs; i++) |
3350 | if (snd_hda_jack_detect(codec, cfg->line_out_pins[i])) | 3355 | if (snd_hda_jack_detect(codec, cfg->line_out_pins[i])) |
3351 | present = 1; | 3356 | present = 1; |
@@ -3354,6 +3359,7 @@ static void cx_auto_hp_automute(struct hda_codec *codec) | |||
3354 | AC_VERB_SET_PIN_WIDGET_CONTROL, | 3359 | AC_VERB_SET_PIN_WIDGET_CONTROL, |
3355 | present ? 0 : PIN_OUT); | 3360 | present ? 0 : PIN_OUT); |
3356 | } | 3361 | } |
3362 | cx_auto_turn_eapd(codec, cfg->speaker_outs, cfg->speaker_pins, !present); | ||
3357 | } | 3363 | } |
3358 | 3364 | ||
3359 | /* automatic switch internal and external mic */ | 3365 | /* automatic switch internal and external mic */ |
@@ -3517,14 +3523,15 @@ static int cx_auto_parse_auto_config(struct hda_codec *codec) | |||
3517 | return 0; | 3523 | return 0; |
3518 | } | 3524 | } |
3519 | 3525 | ||
3520 | static void cx_auto_turn_on_eapd(struct hda_codec *codec, int num_pins, | 3526 | static void cx_auto_turn_eapd(struct hda_codec *codec, int num_pins, |
3521 | hda_nid_t *pins) | 3527 | hda_nid_t *pins, bool on) |
3522 | { | 3528 | { |
3523 | int i; | 3529 | int i; |
3524 | for (i = 0; i < num_pins; i++) { | 3530 | for (i = 0; i < num_pins; i++) { |
3525 | if (snd_hda_query_pin_caps(codec, pins[i]) & AC_PINCAP_EAPD) | 3531 | if (snd_hda_query_pin_caps(codec, pins[i]) & AC_PINCAP_EAPD) |
3526 | snd_hda_codec_write(codec, pins[i], 0, | 3532 | snd_hda_codec_write(codec, pins[i], 0, |
3527 | AC_VERB_SET_EAPD_BTLENABLE, 0x02); | 3533 | AC_VERB_SET_EAPD_BTLENABLE, |
3534 | on ? 0x02 : 0); | ||
3528 | } | 3535 | } |
3529 | } | 3536 | } |
3530 | 3537 | ||
@@ -3565,6 +3572,13 @@ static void cx_auto_init_output(struct hda_codec *codec) | |||
3565 | for (i = 0; i < cfg->speaker_outs; i++) | 3572 | for (i = 0; i < cfg->speaker_outs; i++) |
3566 | snd_hda_codec_write(codec, cfg->speaker_pins[i], 0, | 3573 | snd_hda_codec_write(codec, cfg->speaker_pins[i], 0, |
3567 | AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); | 3574 | AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); |
3575 | /* turn on EAPD */ | ||
3576 | cx_auto_turn_eapd(codec, cfg->line_outs, cfg->line_out_pins, | ||
3577 | true); | ||
3578 | cx_auto_turn_eapd(codec, cfg->hp_outs, cfg->hp_pins, | ||
3579 | true); | ||
3580 | cx_auto_turn_eapd(codec, cfg->speaker_outs, cfg->speaker_pins, | ||
3581 | true); | ||
3568 | } | 3582 | } |
3569 | 3583 | ||
3570 | for (i = 0; i < spec->dac_info_filled; i++) { | 3584 | for (i = 0; i < spec->dac_info_filled; i++) { |
@@ -3573,11 +3587,6 @@ static void cx_auto_init_output(struct hda_codec *codec) | |||
3573 | nid = spec->multiout.dac_nids[0]; | 3587 | nid = spec->multiout.dac_nids[0]; |
3574 | select_connection(codec, spec->dac_info[i].pin, nid); | 3588 | select_connection(codec, spec->dac_info[i].pin, nid); |
3575 | } | 3589 | } |
3576 | |||
3577 | /* turn on EAPD */ | ||
3578 | cx_auto_turn_on_eapd(codec, cfg->line_outs, cfg->line_out_pins); | ||
3579 | cx_auto_turn_on_eapd(codec, cfg->hp_outs, cfg->hp_pins); | ||
3580 | cx_auto_turn_on_eapd(codec, cfg->speaker_outs, cfg->speaker_pins); | ||
3581 | } | 3590 | } |
3582 | 3591 | ||
3583 | static void cx_auto_init_input(struct hda_codec *codec) | 3592 | static void cx_auto_init_input(struct hda_codec *codec) |