diff options
author | Jiang Zhe <zhe.jiang@intel.com> | 2007-11-12 07:05:16 -0500 |
---|---|---|
committer | Jaroslav Kysela <perex@perex.cz> | 2008-01-31 11:29:22 -0500 |
commit | 40c1d30871346c7428d3876fc4c6b593b1b875f2 (patch) | |
tree | acc30ea1195b2472ce9fe90286cd6fc5f4912169 /sound/pci | |
parent | bcecd9bd96a5ba598e4b671a55f05b32284987da (diff) |
[ALSA] hda-codec - Avoid wrong speaker-auto mute via mic jack
When a mic jack is set up as the multiple I/O, it may issue the automute
function wrongly. This patch fixes the wrong automute detection.
Signed-off-by: Jiang Zhe <zhe.jiang@intel.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
Diffstat (limited to 'sound/pci')
-rw-r--r-- | sound/pci/hda/patch_sigmatel.c | 24 |
1 files changed, 19 insertions, 5 deletions
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 992568368ef4..c4447b160a5a 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c | |||
@@ -1600,6 +1600,13 @@ static int stac92xx_io_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_ | |||
1600 | pinctl |= stac92xx_get_vref(codec, nid); | 1600 | pinctl |= stac92xx_get_vref(codec, nid); |
1601 | stac92xx_auto_set_pinctl(codec, nid, pinctl); | 1601 | stac92xx_auto_set_pinctl(codec, nid, pinctl); |
1602 | } | 1602 | } |
1603 | |||
1604 | /* check the auto-mute again: we need to mute/unmute the speaker | ||
1605 | * appropriately according to the pin direction | ||
1606 | */ | ||
1607 | if (spec->hp_detect) | ||
1608 | codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26); | ||
1609 | |||
1603 | return 1; | 1610 | return 1; |
1604 | } | 1611 | } |
1605 | 1612 | ||
@@ -2483,13 +2490,20 @@ static void stac92xx_reset_pinctl(struct hda_codec *codec, hda_nid_t nid, | |||
2483 | pin_ctl & ~flag); | 2490 | pin_ctl & ~flag); |
2484 | } | 2491 | } |
2485 | 2492 | ||
2486 | static int get_pin_presence(struct hda_codec *codec, hda_nid_t nid) | 2493 | static int get_hp_pin_presence(struct hda_codec *codec, hda_nid_t nid) |
2487 | { | 2494 | { |
2488 | if (!nid) | 2495 | if (!nid) |
2489 | return 0; | 2496 | return 0; |
2490 | if (snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PIN_SENSE, 0x00) | 2497 | if (snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PIN_SENSE, 0x00) |
2491 | & (1 << 31)) | 2498 | & (1 << 31)) { |
2492 | return 1; | 2499 | unsigned int pinctl; |
2500 | pinctl = snd_hda_codec_read(codec, nid, 0, | ||
2501 | AC_VERB_GET_PIN_WIDGET_CONTROL, 0); | ||
2502 | if (pinctl & AC_PINCTL_IN_EN) | ||
2503 | return 0; /* mic- or line-input */ | ||
2504 | else | ||
2505 | return 1; /* HP-output */ | ||
2506 | } | ||
2493 | return 0; | 2507 | return 0; |
2494 | } | 2508 | } |
2495 | 2509 | ||
@@ -2501,7 +2515,7 @@ static void stac92xx_hp_detect(struct hda_codec *codec, unsigned int res) | |||
2501 | 2515 | ||
2502 | presence = 0; | 2516 | presence = 0; |
2503 | for (i = 0; i < cfg->hp_outs; i++) { | 2517 | for (i = 0; i < cfg->hp_outs; i++) { |
2504 | presence = get_pin_presence(codec, cfg->hp_pins[i]); | 2518 | presence = get_hp_pin_presence(codec, cfg->hp_pins[i]); |
2505 | if (presence) | 2519 | if (presence) |
2506 | break; | 2520 | break; |
2507 | } | 2521 | } |
@@ -3179,7 +3193,7 @@ static int stac9872_vaio_init(struct hda_codec *codec) | |||
3179 | 3193 | ||
3180 | static void stac9872_vaio_hp_detect(struct hda_codec *codec, unsigned int res) | 3194 | static void stac9872_vaio_hp_detect(struct hda_codec *codec, unsigned int res) |
3181 | { | 3195 | { |
3182 | if (get_pin_presence(codec, 0x0a)) { | 3196 | if (get_hp_pin_presence(codec, 0x0a)) { |
3183 | stac92xx_reset_pinctl(codec, 0x0f, AC_PINCTL_OUT_EN); | 3197 | stac92xx_reset_pinctl(codec, 0x0f, AC_PINCTL_OUT_EN); |
3184 | stac92xx_set_pinctl(codec, 0x0a, AC_PINCTL_OUT_EN); | 3198 | stac92xx_set_pinctl(codec, 0x0a, AC_PINCTL_OUT_EN); |
3185 | } else { | 3199 | } else { |