diff options
author | Charles Chin <Charles.Chin@idt.com> | 2010-09-17 04:22:32 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2010-09-17 04:22:32 -0400 |
commit | 9907790aa06bfc04bf78b445e732ea10039c61e4 (patch) | |
tree | 786b7b9a31095278019d2389ed1980e8bbf71eef /sound/pci/hda/patch_sigmatel.c | |
parent | 30ea098fc000bb05081a1999269658f1a88af36a (diff) |
ALSA: hda - Fix automatic MIC switching and include dock MIC for IDT codecs
Signed-off-by: Charles Chin <Charles.Chin@idt.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/hda/patch_sigmatel.c')
-rw-r--r-- | sound/pci/hda/patch_sigmatel.c | 40 |
1 files changed, 29 insertions, 11 deletions
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index e4e7d43f911e..7eb359a030de 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c | |||
@@ -263,6 +263,7 @@ struct sigmatel_spec { | |||
263 | 263 | ||
264 | struct sigmatel_mic_route ext_mic; | 264 | struct sigmatel_mic_route ext_mic; |
265 | struct sigmatel_mic_route int_mic; | 265 | struct sigmatel_mic_route int_mic; |
266 | struct sigmatel_mic_route dock_mic; | ||
266 | 267 | ||
267 | const char **spdif_labels; | 268 | const char **spdif_labels; |
268 | 269 | ||
@@ -3488,7 +3489,7 @@ static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec, | |||
3488 | } | 3489 | } |
3489 | 3490 | ||
3490 | static int check_mic_pin(struct hda_codec *codec, hda_nid_t nid, | 3491 | static int check_mic_pin(struct hda_codec *codec, hda_nid_t nid, |
3491 | hda_nid_t *fixed, hda_nid_t *ext) | 3492 | hda_nid_t *fixed, hda_nid_t *ext, hda_nid_t *dock) |
3492 | { | 3493 | { |
3493 | unsigned int cfg; | 3494 | unsigned int cfg; |
3494 | 3495 | ||
@@ -3496,15 +3497,22 @@ static int check_mic_pin(struct hda_codec *codec, hda_nid_t nid, | |||
3496 | return 0; | 3497 | return 0; |
3497 | cfg = snd_hda_codec_get_pincfg(codec, nid); | 3498 | cfg = snd_hda_codec_get_pincfg(codec, nid); |
3498 | switch (get_defcfg_connect(cfg)) { | 3499 | switch (get_defcfg_connect(cfg)) { |
3500 | case AC_JACK_PORT_BOTH: | ||
3499 | case AC_JACK_PORT_FIXED: | 3501 | case AC_JACK_PORT_FIXED: |
3500 | if (*fixed) | 3502 | if (*fixed) |
3501 | return 1; /* already occupied */ | 3503 | return 1; /* already occupied */ |
3502 | *fixed = nid; | 3504 | *fixed = nid; |
3503 | break; | 3505 | break; |
3504 | case AC_JACK_PORT_COMPLEX: | 3506 | case AC_JACK_PORT_COMPLEX: |
3505 | if (*ext) | 3507 | if ((get_defcfg_location(cfg) & 0xF0) == AC_JACK_LOC_SEPARATE) { |
3506 | return 1; /* already occupied */ | 3508 | if (*dock) |
3507 | *ext = nid; | 3509 | return 1; /* already occupied */ |
3510 | *dock = nid; | ||
3511 | } else { | ||
3512 | if (*ext) | ||
3513 | return 1; /* already occupied */ | ||
3514 | *ext = nid; | ||
3515 | } | ||
3508 | break; | 3516 | break; |
3509 | } | 3517 | } |
3510 | return 0; | 3518 | return 0; |
@@ -3519,6 +3527,8 @@ static int set_mic_route(struct hda_codec *codec, | |||
3519 | int i; | 3527 | int i; |
3520 | 3528 | ||
3521 | mic->pin = pin; | 3529 | mic->pin = pin; |
3530 | if (pin == 0) | ||
3531 | return 0; | ||
3522 | for (i = 0; i < cfg->num_inputs; i++) { | 3532 | for (i = 0; i < cfg->num_inputs; i++) { |
3523 | if (pin == cfg->inputs[i].pin) | 3533 | if (pin == cfg->inputs[i].pin) |
3524 | break; | 3534 | break; |
@@ -3554,26 +3564,29 @@ static int stac_check_auto_mic(struct hda_codec *codec) | |||
3554 | { | 3564 | { |
3555 | struct sigmatel_spec *spec = codec->spec; | 3565 | struct sigmatel_spec *spec = codec->spec; |
3556 | struct auto_pin_cfg *cfg = &spec->autocfg; | 3566 | struct auto_pin_cfg *cfg = &spec->autocfg; |
3557 | hda_nid_t fixed, ext; | 3567 | hda_nid_t fixed, ext, dock; |
3558 | int i; | 3568 | int i; |
3559 | 3569 | ||
3560 | for (i = 0; i < cfg->num_inputs; i++) { | 3570 | for (i = 0; i < cfg->num_inputs; i++) { |
3561 | if (cfg->inputs[i].type >= AUTO_PIN_LINE_IN) | 3571 | if (cfg->inputs[i].type >= AUTO_PIN_LINE_IN) |
3562 | return 0; /* must be exclusively mics */ | 3572 | return 0; /* must be exclusively mics */ |
3563 | } | 3573 | } |
3564 | fixed = ext = 0; | 3574 | fixed = ext = dock = 0; |
3565 | for (i = 0; i < cfg->num_inputs; i++) | 3575 | for (i = 0; i < cfg->num_inputs; i++) |
3566 | if (check_mic_pin(codec, cfg->inputs[i].pin, &fixed, &ext)) | 3576 | if (check_mic_pin(codec, cfg->inputs[i].pin, |
3577 | &fixed, &ext, &dock)) | ||
3567 | return 0; | 3578 | return 0; |
3568 | for (i = 0; i < spec->num_dmics; i++) | 3579 | for (i = 0; i < spec->num_dmics; i++) |
3569 | if (check_mic_pin(codec, spec->dmic_nids[i], &fixed, &ext)) | 3580 | if (check_mic_pin(codec, spec->dmic_nids[i], |
3581 | &fixed, &ext, &dock)) | ||
3570 | return 0; | 3582 | return 0; |
3571 | if (!fixed || !ext) | 3583 | if (!fixed && !ext && !dock) |
3572 | return 0; | 3584 | return 0; /* no input to switch */ |
3573 | if (!(get_wcaps(codec, ext) & AC_WCAP_UNSOL_CAP)) | 3585 | if (!(get_wcaps(codec, ext) & AC_WCAP_UNSOL_CAP)) |
3574 | return 0; /* no unsol support */ | 3586 | return 0; /* no unsol support */ |
3575 | if (set_mic_route(codec, &spec->ext_mic, ext) || | 3587 | if (set_mic_route(codec, &spec->ext_mic, ext) || |
3576 | set_mic_route(codec, &spec->int_mic, fixed)) | 3588 | set_mic_route(codec, &spec->int_mic, fixed) || |
3589 | set_mic_route(codec, &spec->dock_mic, dock)) | ||
3577 | return 0; /* something is wrong */ | 3590 | return 0; /* something is wrong */ |
3578 | return 1; | 3591 | return 1; |
3579 | } | 3592 | } |
@@ -4281,6 +4294,9 @@ static int stac92xx_init(struct hda_codec *codec) | |||
4281 | AC_VERB_SET_CONNECT_SEL, 0); | 4294 | AC_VERB_SET_CONNECT_SEL, 0); |
4282 | if (enable_pin_detect(codec, spec->ext_mic.pin, STAC_MIC_EVENT)) | 4295 | if (enable_pin_detect(codec, spec->ext_mic.pin, STAC_MIC_EVENT)) |
4283 | stac_issue_unsol_event(codec, spec->ext_mic.pin); | 4296 | stac_issue_unsol_event(codec, spec->ext_mic.pin); |
4297 | if (enable_pin_detect(codec, spec->dock_mic.pin, | ||
4298 | STAC_MIC_EVENT)) | ||
4299 | stac_issue_unsol_event(codec, spec->dock_mic.pin); | ||
4284 | } | 4300 | } |
4285 | for (i = 0; i < cfg->num_inputs; i++) { | 4301 | for (i = 0; i < cfg->num_inputs; i++) { |
4286 | hda_nid_t nid = cfg->inputs[i].pin; | 4302 | hda_nid_t nid = cfg->inputs[i].pin; |
@@ -4698,6 +4714,8 @@ static void stac92xx_mic_detect(struct hda_codec *codec) | |||
4698 | 4714 | ||
4699 | if (get_pin_presence(codec, spec->ext_mic.pin)) | 4715 | if (get_pin_presence(codec, spec->ext_mic.pin)) |
4700 | mic = &spec->ext_mic; | 4716 | mic = &spec->ext_mic; |
4717 | else if (get_pin_presence(codec, spec->dock_mic.pin)) | ||
4718 | mic = &spec->dock_mic; | ||
4701 | else | 4719 | else |
4702 | mic = &spec->int_mic; | 4720 | mic = &spec->int_mic; |
4703 | if (mic->dmux_idx >= 0) | 4721 | if (mic->dmux_idx >= 0) |