diff options
author | Takashi Iwai <tiwai@suse.de> | 2009-07-30 12:03:05 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2009-07-30 12:08:46 -0400 |
commit | fefd67f31ee7f5259344e36a237d59b47e8715cf (patch) | |
tree | 40df7e13cd28e49bf097cc609d18c83e86903898 /sound/pci | |
parent | bf677bd8fbd5dc06ead5511cf9fa76d090856c6a (diff) |
ALSA: hda - Add line-out jack detection on IDT/STAC codecs
Add the automatic mute of speakers via line-out jack plugging on
STAC/IDT codecs. The feature is enabled when the HP detect is present.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci')
-rw-r--r-- | sound/pci/hda/patch_sigmatel.c | 70 |
1 files changed, 56 insertions, 14 deletions
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 9e192529e807..c7e5de6e394e 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c | |||
@@ -40,6 +40,7 @@ enum { | |||
40 | STAC_INSERT_EVENT, | 40 | STAC_INSERT_EVENT, |
41 | STAC_PWR_EVENT, | 41 | STAC_PWR_EVENT, |
42 | STAC_HP_EVENT, | 42 | STAC_HP_EVENT, |
43 | STAC_LO_EVENT, | ||
43 | STAC_MIC_EVENT, | 44 | STAC_MIC_EVENT, |
44 | }; | 45 | }; |
45 | 46 | ||
@@ -4345,6 +4346,14 @@ static int stac92xx_init(struct hda_codec *codec) | |||
4345 | hda_nid_t nid = cfg->hp_pins[i]; | 4346 | hda_nid_t nid = cfg->hp_pins[i]; |
4346 | enable_pin_detect(codec, nid, STAC_HP_EVENT); | 4347 | enable_pin_detect(codec, nid, STAC_HP_EVENT); |
4347 | } | 4348 | } |
4349 | if (cfg->line_out_type == AUTO_PIN_LINE_OUT) { | ||
4350 | /* enable pin-detect for line-outs as well */ | ||
4351 | for (i = 0; i < cfg->hp_outs; i++) { | ||
4352 | hda_nid_t nid = cfg->hp_pins[i]; | ||
4353 | enable_pin_detect(codec, nid, STAC_LO_EVENT); | ||
4354 | } | ||
4355 | } | ||
4356 | |||
4348 | /* force to enable the first line-out; the others are set up | 4357 | /* force to enable the first line-out; the others are set up |
4349 | * in unsol_event | 4358 | * in unsol_event |
4350 | */ | 4359 | */ |
@@ -4543,6 +4552,48 @@ static int get_pin_presence(struct hda_codec *codec, hda_nid_t nid) | |||
4543 | return 0; | 4552 | return 0; |
4544 | } | 4553 | } |
4545 | 4554 | ||
4555 | static void stac92xx_line_out_detect(struct hda_codec *codec, | ||
4556 | int presence) | ||
4557 | { | ||
4558 | struct sigmatel_spec *spec = codec->spec; | ||
4559 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
4560 | int i; | ||
4561 | |||
4562 | for (i = 0; i < cfg->line_outs; i++) { | ||
4563 | if (presence) | ||
4564 | break; | ||
4565 | presence = get_pin_presence(codec, cfg->line_out_pins[i]); | ||
4566 | if (presence) { | ||
4567 | unsigned int pinctl; | ||
4568 | pinctl = snd_hda_codec_read(codec, | ||
4569 | cfg->line_out_pins[i], 0, | ||
4570 | AC_VERB_GET_PIN_WIDGET_CONTROL, 0); | ||
4571 | if (pinctl & AC_PINCTL_IN_EN) | ||
4572 | presence = 0; /* mic- or line-input */ | ||
4573 | } | ||
4574 | } | ||
4575 | |||
4576 | if (presence) { | ||
4577 | /* disable speakers */ | ||
4578 | for (i = 0; i < cfg->speaker_outs; i++) | ||
4579 | stac92xx_reset_pinctl(codec, cfg->speaker_pins[i], | ||
4580 | AC_PINCTL_OUT_EN); | ||
4581 | if (spec->eapd_mask && spec->eapd_switch) | ||
4582 | stac_gpio_set(codec, spec->gpio_mask, | ||
4583 | spec->gpio_dir, spec->gpio_data & | ||
4584 | ~spec->eapd_mask); | ||
4585 | } else { | ||
4586 | /* enable speakers */ | ||
4587 | for (i = 0; i < cfg->speaker_outs; i++) | ||
4588 | stac92xx_set_pinctl(codec, cfg->speaker_pins[i], | ||
4589 | AC_PINCTL_OUT_EN); | ||
4590 | if (spec->eapd_mask && spec->eapd_switch) | ||
4591 | stac_gpio_set(codec, spec->gpio_mask, | ||
4592 | spec->gpio_dir, spec->gpio_data | | ||
4593 | spec->eapd_mask); | ||
4594 | } | ||
4595 | } | ||
4596 | |||
4546 | /* return non-zero if the hp-pin of the given array index isn't | 4597 | /* return non-zero if the hp-pin of the given array index isn't |
4547 | * a jack-detection target | 4598 | * a jack-detection target |
4548 | */ | 4599 | */ |
@@ -4595,13 +4646,6 @@ static void stac92xx_hp_detect(struct hda_codec *codec) | |||
4595 | for (i = 0; i < cfg->line_outs; i++) | 4646 | for (i = 0; i < cfg->line_outs; i++) |
4596 | stac92xx_reset_pinctl(codec, cfg->line_out_pins[i], | 4647 | stac92xx_reset_pinctl(codec, cfg->line_out_pins[i], |
4597 | AC_PINCTL_OUT_EN); | 4648 | AC_PINCTL_OUT_EN); |
4598 | for (i = 0; i < cfg->speaker_outs; i++) | ||
4599 | stac92xx_reset_pinctl(codec, cfg->speaker_pins[i], | ||
4600 | AC_PINCTL_OUT_EN); | ||
4601 | if (spec->eapd_mask && spec->eapd_switch) | ||
4602 | stac_gpio_set(codec, spec->gpio_mask, | ||
4603 | spec->gpio_dir, spec->gpio_data & | ||
4604 | ~spec->eapd_mask); | ||
4605 | } else { | 4649 | } else { |
4606 | /* enable lineouts */ | 4650 | /* enable lineouts */ |
4607 | if (spec->hp_switch) | 4651 | if (spec->hp_switch) |
@@ -4610,14 +4654,8 @@ static void stac92xx_hp_detect(struct hda_codec *codec) | |||
4610 | for (i = 0; i < cfg->line_outs; i++) | 4654 | for (i = 0; i < cfg->line_outs; i++) |
4611 | stac92xx_set_pinctl(codec, cfg->line_out_pins[i], | 4655 | stac92xx_set_pinctl(codec, cfg->line_out_pins[i], |
4612 | AC_PINCTL_OUT_EN); | 4656 | AC_PINCTL_OUT_EN); |
4613 | for (i = 0; i < cfg->speaker_outs; i++) | ||
4614 | stac92xx_set_pinctl(codec, cfg->speaker_pins[i], | ||
4615 | AC_PINCTL_OUT_EN); | ||
4616 | if (spec->eapd_mask && spec->eapd_switch) | ||
4617 | stac_gpio_set(codec, spec->gpio_mask, | ||
4618 | spec->gpio_dir, spec->gpio_data | | ||
4619 | spec->eapd_mask); | ||
4620 | } | 4657 | } |
4658 | stac92xx_line_out_detect(codec, presence); | ||
4621 | /* toggle hp outs */ | 4659 | /* toggle hp outs */ |
4622 | for (i = 0; i < cfg->hp_outs; i++) { | 4660 | for (i = 0; i < cfg->hp_outs; i++) { |
4623 | unsigned int val = AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN; | 4661 | unsigned int val = AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN; |
@@ -4744,6 +4782,9 @@ static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res) | |||
4744 | case STAC_HP_EVENT: | 4782 | case STAC_HP_EVENT: |
4745 | stac92xx_hp_detect(codec); | 4783 | stac92xx_hp_detect(codec); |
4746 | break; | 4784 | break; |
4785 | case STAC_LO_EVENT: | ||
4786 | stac92xx_line_out_detect(codec, 0); | ||
4787 | break; | ||
4747 | case STAC_MIC_EVENT: | 4788 | case STAC_MIC_EVENT: |
4748 | stac92xx_mic_detect(codec); | 4789 | stac92xx_mic_detect(codec); |
4749 | break; | 4790 | break; |
@@ -4751,6 +4792,7 @@ static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res) | |||
4751 | 4792 | ||
4752 | switch (event->type) { | 4793 | switch (event->type) { |
4753 | case STAC_HP_EVENT: | 4794 | case STAC_HP_EVENT: |
4795 | case STAC_LO_EVENT: | ||
4754 | case STAC_MIC_EVENT: | 4796 | case STAC_MIC_EVENT: |
4755 | case STAC_INSERT_EVENT: | 4797 | case STAC_INSERT_EVENT: |
4756 | case STAC_PWR_EVENT: | 4798 | case STAC_PWR_EVENT: |