diff options
author | Tobin Davis <tdavis@dsl-only.net> | 2007-02-13 06:45:44 -0500 |
---|---|---|
committer | Jaroslav Kysela <perex@suse.cz> | 2007-02-14 02:38:26 -0500 |
commit | 82f30040ada635d5d42a244b6eb84607d9881f5a (patch) | |
tree | 1d69f1989f5e7d8153118022f86b93d4d547da0c | |
parent | f38cc317c0a7279bb725ec5c2251726eab3c722b (diff) |
[ALSA] hda-codec - More fixes for Conexant HD Audio support
Renamed Conexant 5045 to CX20549 (Venice) per Conexant Documentation
Renamed Conexant 5047 to CX20551 (Waikiki) per Conexant Documentation
Fixed automute on HP Laptops with CX20551 codec.
Fixed recording issues on Toshiba Satelite P100/P105 series laptops
Added HP DV8000, DV2000Z, Fujitsu Si1520 support
More work to be done on CX20549 based systems, but CX20551 Systems are
much better now.
Signed-off-by: Tobin Davis <tdavis@dsl-only.net>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Jaroslav Kysela <perex@suse.cz>
-rw-r--r-- | sound/pci/hda/patch_conexant.c | 343 |
1 files changed, 221 insertions, 122 deletions
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 73f4668238c6..23a1c75085b5 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c | |||
@@ -57,6 +57,7 @@ struct conexant_spec { | |||
57 | * dig_out_nid and hp_nid are optional | 57 | * dig_out_nid and hp_nid are optional |
58 | */ | 58 | */ |
59 | unsigned int cur_eapd; | 59 | unsigned int cur_eapd; |
60 | unsigned int hp_present; | ||
60 | unsigned int need_dac_fix; | 61 | unsigned int need_dac_fix; |
61 | 62 | ||
62 | /* capture */ | 63 | /* capture */ |
@@ -354,7 +355,7 @@ static struct hda_codec_ops conexant_patch_ops = { | |||
354 | * the private value = nid | (invert << 8) | 355 | * the private value = nid | (invert << 8) |
355 | */ | 356 | */ |
356 | 357 | ||
357 | static int conexant_eapd_info(struct snd_kcontrol *kcontrol, | 358 | static int cxt_eapd_info(struct snd_kcontrol *kcontrol, |
358 | struct snd_ctl_elem_info *uinfo) | 359 | struct snd_ctl_elem_info *uinfo) |
359 | { | 360 | { |
360 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; | 361 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; |
@@ -364,7 +365,7 @@ static int conexant_eapd_info(struct snd_kcontrol *kcontrol, | |||
364 | return 0; | 365 | return 0; |
365 | } | 366 | } |
366 | 367 | ||
367 | static int conexant_eapd_get(struct snd_kcontrol *kcontrol, | 368 | static int cxt_eapd_get(struct snd_kcontrol *kcontrol, |
368 | struct snd_ctl_elem_value *ucontrol) | 369 | struct snd_ctl_elem_value *ucontrol) |
369 | { | 370 | { |
370 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 371 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
@@ -375,9 +376,10 @@ static int conexant_eapd_get(struct snd_kcontrol *kcontrol, | |||
375 | else | 376 | else |
376 | ucontrol->value.integer.value[0] = spec->cur_eapd; | 377 | ucontrol->value.integer.value[0] = spec->cur_eapd; |
377 | return 0; | 378 | return 0; |
379 | |||
378 | } | 380 | } |
379 | 381 | ||
380 | static int conexant_eapd_put(struct snd_kcontrol *kcontrol, | 382 | static int cxt_eapd_put(struct snd_kcontrol *kcontrol, |
381 | struct snd_ctl_elem_value *ucontrol) | 383 | struct snd_ctl_elem_value *ucontrol) |
382 | { | 384 | { |
383 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 385 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
@@ -385,11 +387,13 @@ static int conexant_eapd_put(struct snd_kcontrol *kcontrol, | |||
385 | int invert = (kcontrol->private_value >> 8) & 1; | 387 | int invert = (kcontrol->private_value >> 8) & 1; |
386 | hda_nid_t nid = kcontrol->private_value & 0xff; | 388 | hda_nid_t nid = kcontrol->private_value & 0xff; |
387 | unsigned int eapd; | 389 | unsigned int eapd; |
390 | |||
388 | eapd = ucontrol->value.integer.value[0]; | 391 | eapd = ucontrol->value.integer.value[0]; |
389 | if (invert) | 392 | if (invert) |
390 | eapd = !eapd; | 393 | eapd = !eapd; |
391 | if (eapd == spec->cur_eapd && !codec->in_resume) | 394 | if (eapd == spec->cur_eapd && !codec->in_resume) |
392 | return 0; | 395 | return 0; |
396 | |||
393 | spec->cur_eapd = eapd; | 397 | spec->cur_eapd = eapd; |
394 | snd_hda_codec_write(codec, nid, | 398 | snd_hda_codec_write(codec, nid, |
395 | 0, AC_VERB_SET_EAPD_BTLENABLE, | 399 | 0, AC_VERB_SET_EAPD_BTLENABLE, |
@@ -400,6 +404,15 @@ static int conexant_eapd_put(struct snd_kcontrol *kcontrol, | |||
400 | /* controls for test mode */ | 404 | /* controls for test mode */ |
401 | #ifdef CONFIG_SND_DEBUG | 405 | #ifdef CONFIG_SND_DEBUG |
402 | 406 | ||
407 | #define CXT_EAPD_SWITCH(xname, nid, mask) \ | ||
408 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ | ||
409 | .info = cxt_eapd_info, \ | ||
410 | .get = cxt_eapd_get, \ | ||
411 | .put = cxt_eapd_put, \ | ||
412 | .private_value = nid | (mask<<16) } | ||
413 | |||
414 | |||
415 | |||
403 | static int conexant_ch_mode_info(struct snd_kcontrol *kcontrol, | 416 | static int conexant_ch_mode_info(struct snd_kcontrol *kcontrol, |
404 | struct snd_ctl_elem_info *uinfo) | 417 | struct snd_ctl_elem_info *uinfo) |
405 | { | 418 | { |
@@ -492,7 +505,7 @@ static int cxt_gpio_data_put(struct snd_kcontrol *kcontrol, | |||
492 | .get = cxt_gpio_data_get, \ | 505 | .get = cxt_gpio_data_get, \ |
493 | .put = cxt_gpio_data_put, \ | 506 | .put = cxt_gpio_data_put, \ |
494 | .private_value = nid | (mask<<16) } | 507 | .private_value = nid | (mask<<16) } |
495 | 508 | #if 0 | |
496 | static int cxt_spdif_ctrl_info(struct snd_kcontrol *kcontrol, | 509 | static int cxt_spdif_ctrl_info(struct snd_kcontrol *kcontrol, |
497 | struct snd_ctl_elem_info *uinfo) | 510 | struct snd_ctl_elem_info *uinfo) |
498 | { | 511 | { |
@@ -547,7 +560,7 @@ static int cxt_spdif_ctrl_put(struct snd_kcontrol *kcontrol, | |||
547 | .get = cxt_spdif_ctrl_get, \ | 560 | .get = cxt_spdif_ctrl_get, \ |
548 | .put = cxt_spdif_ctrl_put, \ | 561 | .put = cxt_spdif_ctrl_put, \ |
549 | .private_value = nid | (mask<<16) } | 562 | .private_value = nid | (mask<<16) } |
550 | 563 | #endif | |
551 | #endif /* CONFIG_SND_DEBUG */ | 564 | #endif /* CONFIG_SND_DEBUG */ |
552 | 565 | ||
553 | /* Conexant 5045 specific */ | 566 | /* Conexant 5045 specific */ |
@@ -564,7 +577,7 @@ static struct hda_channel_mode cxt5045_modes[1] = { | |||
564 | static struct hda_input_mux cxt5045_capture_source = { | 577 | static struct hda_input_mux cxt5045_capture_source = { |
565 | .num_items = 2, | 578 | .num_items = 2, |
566 | .items = { | 579 | .items = { |
567 | { "ExtMic", 0x1 }, | 580 | { "IntMic", 0x1 }, |
568 | { "LineIn", 0x2 }, | 581 | { "LineIn", 0x2 }, |
569 | } | 582 | } |
570 | }; | 583 | }; |
@@ -575,15 +588,20 @@ static int cxt5045_hp_master_sw_put(struct snd_kcontrol *kcontrol, | |||
575 | { | 588 | { |
576 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 589 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
577 | struct conexant_spec *spec = codec->spec; | 590 | struct conexant_spec *spec = codec->spec; |
591 | unsigned int bits; | ||
578 | 592 | ||
579 | if (!conexant_eapd_put(kcontrol, ucontrol)) | 593 | if (!cxt_eapd_put(kcontrol, ucontrol)) |
580 | return 0; | 594 | return 0; |
581 | 595 | ||
582 | /* toggle HP mute appropriately */ | 596 | /* toggle internal speakers mute depending of presence of |
583 | snd_hda_codec_amp_update(codec, 0x11, 0, HDA_OUTPUT, 0, | 597 | * the headphone jack |
584 | 0x80, spec->cur_eapd ? 0 : 0x80); | 598 | */ |
585 | snd_hda_codec_amp_update(codec, 0x11, 1, HDA_OUTPUT, 0, | 599 | bits = (!spec->hp_present && spec->cur_eapd) ? 0 : 0x80; |
586 | 0x80, spec->cur_eapd ? 0 : 0x80); | 600 | snd_hda_codec_amp_update(codec, 0x10, 0, HDA_OUTPUT, 0, 0x80, bits); |
601 | snd_hda_codec_amp_update(codec, 0x10, 1, HDA_OUTPUT, 0, 0x80, bits); | ||
602 | bits = spec->cur_eapd ? 0 : 0x80; | ||
603 | snd_hda_codec_amp_update(codec, 0x11, 0, HDA_OUTPUT, 0, 0x80, bits); | ||
604 | snd_hda_codec_amp_update(codec, 0x11, 1, HDA_OUTPUT, 0, 0x80, bits); | ||
587 | return 1; | 605 | return 1; |
588 | } | 606 | } |
589 | 607 | ||
@@ -610,14 +628,13 @@ static int cxt5045_hp_master_vol_put(struct snd_kcontrol *kcontrol, | |||
610 | /* mute internal speaker if HP is plugged */ | 628 | /* mute internal speaker if HP is plugged */ |
611 | static void cxt5045_hp_automute(struct hda_codec *codec) | 629 | static void cxt5045_hp_automute(struct hda_codec *codec) |
612 | { | 630 | { |
613 | unsigned int present; | 631 | struct conexant_spec *spec = codec->spec; |
632 | unsigned int bits = (spec->hp_present || !spec->cur_eapd) ? 0x80 : 0; | ||
614 | 633 | ||
615 | present = snd_hda_codec_read(codec, 0x11, 0, | 634 | spec->hp_present = snd_hda_codec_read(codec, 0x11, 0, |
616 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | 635 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; |
617 | snd_hda_codec_amp_update(codec, 0x10, 0, HDA_OUTPUT, 0, | 636 | snd_hda_codec_amp_update(codec, 0x10, 0, HDA_OUTPUT, 0, 0x80, bits); |
618 | 0x80, present ? 0x80 : 0); | 637 | snd_hda_codec_amp_update(codec, 0x10, 1, HDA_OUTPUT, 0, 0x80, bits); |
619 | snd_hda_codec_amp_update(codec, 0x10, 1, HDA_OUTPUT, 0, | ||
620 | 0x80, present ? 0x80 : 0); | ||
621 | } | 638 | } |
622 | 639 | ||
623 | /* unsolicited event for HP jack sensing */ | 640 | /* unsolicited event for HP jack sensing */ |
@@ -640,25 +657,27 @@ static struct snd_kcontrol_new cxt5045_mixers[] = { | |||
640 | .get = conexant_mux_enum_get, | 657 | .get = conexant_mux_enum_get, |
641 | .put = conexant_mux_enum_put | 658 | .put = conexant_mux_enum_put |
642 | }, | 659 | }, |
643 | HDA_CODEC_VOLUME("Mic Bypass Capture Volume", 0x17, 0x02, HDA_INPUT), | 660 | HDA_CODEC_VOLUME("Int Mic Volume", 0x17, 0x01, HDA_INPUT), |
644 | HDA_CODEC_MUTE("Mic Bypass Capture Switch", 0x17, 0x02, HDA_INPUT), | 661 | HDA_CODEC_MUTE("Int Mic Switch", 0x17, 0x01, HDA_INPUT), |
645 | HDA_CODEC_VOLUME("Capture Volume", 0x1a, 0x02, HDA_INPUT), | 662 | HDA_CODEC_VOLUME("Ext Mic Volume", 0x17, 0x02, HDA_INPUT), |
646 | HDA_CODEC_MUTE("Capture Switch", 0x1a, 0x02, HDA_INPUT), | 663 | HDA_CODEC_MUTE("Ext Mic Switch", 0x17, 0x02, HDA_INPUT), |
664 | HDA_CODEC_VOLUME("Capture Volume", 0x1a, 0x0, HDA_INPUT), | ||
665 | HDA_CODEC_MUTE("Capture Switch", 0x1a, 0x0, HDA_INPUT), | ||
647 | { | 666 | { |
648 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 667 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
649 | .name = "Master Playback Volume", | 668 | .name = "Master Playback Volume", |
650 | .info = snd_hda_mixer_amp_volume_info, | 669 | .info = snd_hda_mixer_amp_volume_info, |
651 | .get = snd_hda_mixer_amp_volume_get, | 670 | .get = snd_hda_mixer_amp_volume_get, |
652 | .put = cxt5045_hp_master_vol_put, | 671 | .put = cxt5045_hp_master_vol_put, |
653 | .private_value = HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT), | 672 | .private_value = HDA_COMPOSE_AMP_VAL(0x10, 3, 0, HDA_OUTPUT), |
654 | }, | 673 | }, |
655 | { | 674 | { |
656 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 675 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
657 | .name = "Master Playback Switch", | 676 | .name = "Master Playback Switch", |
658 | .info = conexant_eapd_info, | 677 | .info = cxt_eapd_info, |
659 | .get = conexant_eapd_get, | 678 | .get = cxt_eapd_get, |
660 | .put = cxt5045_hp_master_sw_put, | 679 | .put = cxt5045_hp_master_sw_put, |
661 | .private_value = 0x11, | 680 | .private_value = 0x10, |
662 | }, | 681 | }, |
663 | 682 | ||
664 | {} | 683 | {} |
@@ -669,22 +688,26 @@ static struct hda_verb cxt5045_init_verbs[] = { | |||
669 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, | 688 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, |
670 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_50 }, | 689 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_50 }, |
671 | /* HP, Amp */ | 690 | /* HP, Amp */ |
672 | {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | 691 | {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, |
673 | {0x1A, AC_VERB_SET_CONNECT_SEL,0x01}, | 692 | {0x17, AC_VERB_SET_CONNECT_SEL,0x01}, |
674 | {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, | 693 | {0x17, AC_VERB_SET_AMP_GAIN_MUTE, |
675 | AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x00}, | 694 | AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x01}, |
676 | {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, | 695 | {0x17, AC_VERB_SET_AMP_GAIN_MUTE, |
696 | AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x02}, | ||
697 | {0x17, AC_VERB_SET_AMP_GAIN_MUTE, | ||
677 | AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x03}, | 698 | AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x03}, |
678 | /* Record selector: Front mic */ | ||
679 | {0x14, AC_VERB_SET_CONNECT_SEL,0x03}, | ||
680 | {0x17, AC_VERB_SET_AMP_GAIN_MUTE, | 699 | {0x17, AC_VERB_SET_AMP_GAIN_MUTE, |
700 | AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x04}, | ||
701 | /* Record selector: Int mic */ | ||
702 | {0x1a, AC_VERB_SET_CONNECT_SEL,0x0}, | ||
703 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, | ||
681 | AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17}, | 704 | AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17}, |
682 | /* SPDIF route: PCM */ | 705 | /* SPDIF route: PCM */ |
683 | { 0x13, AC_VERB_SET_CONNECT_SEL, 0x0 }, | 706 | { 0x13, AC_VERB_SET_CONNECT_SEL, 0x0 }, |
684 | /* pin sensing on HP and Mic jacks */ | 707 | /* pin sensing on HP and Mic jacks */ |
685 | {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT}, | 708 | {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT}, |
686 | /* EAPD */ | 709 | /* EAPD */ |
687 | {0x10, AC_VERB_SET_EAPD_BTLENABLE, 0x0 }, /* default on */ | 710 | {0x10, AC_VERB_SET_EAPD_BTLENABLE, 0x2 }, /* default on */ |
688 | { } /* end */ | 711 | { } /* end */ |
689 | }; | 712 | }; |
690 | 713 | ||
@@ -706,8 +729,6 @@ static struct hda_input_mux cxt5045_test_capture_source = { | |||
706 | static struct snd_kcontrol_new cxt5045_test_mixer[] = { | 729 | static struct snd_kcontrol_new cxt5045_test_mixer[] = { |
707 | 730 | ||
708 | /* Output controls */ | 731 | /* Output controls */ |
709 | HDA_CODEC_VOLUME("OutAmp-1 Volume", 0x19, 0x00, HDA_OUTPUT), | ||
710 | HDA_CODEC_MUTE("OutAmp-1 Switch", 0x19,0x00, HDA_OUTPUT), | ||
711 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x10, 0x0, HDA_OUTPUT), | 732 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x10, 0x0, HDA_OUTPUT), |
712 | HDA_CODEC_MUTE("Speaker Playback Switch", 0x10, 0x0, HDA_OUTPUT), | 733 | HDA_CODEC_MUTE("Speaker Playback Switch", 0x10, 0x0, HDA_OUTPUT), |
713 | 734 | ||
@@ -715,6 +736,9 @@ static struct snd_kcontrol_new cxt5045_test_mixer[] = { | |||
715 | CXT_PIN_MODE("HP-OUT pin mode", 0x11, CXT_PIN_DIR_INOUT), | 736 | CXT_PIN_MODE("HP-OUT pin mode", 0x11, CXT_PIN_DIR_INOUT), |
716 | CXT_PIN_MODE("LINE1 pin mode", 0x12, CXT_PIN_DIR_INOUT), | 737 | CXT_PIN_MODE("LINE1 pin mode", 0x12, CXT_PIN_DIR_INOUT), |
717 | 738 | ||
739 | /* EAPD Switch Control */ | ||
740 | CXT_EAPD_SWITCH("External Amplifier", 0x10, 0x0), | ||
741 | |||
718 | /* Loopback mixer controls */ | 742 | /* Loopback mixer controls */ |
719 | HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x17, 0x01, HDA_INPUT), | 743 | HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x17, 0x01, HDA_INPUT), |
720 | HDA_CODEC_MUTE("MIC1 Playback Switch", 0x17, 0x01, HDA_INPUT), | 744 | HDA_CODEC_MUTE("MIC1 Playback Switch", 0x17, 0x01, HDA_INPUT), |
@@ -725,17 +749,16 @@ static struct snd_kcontrol_new cxt5045_test_mixer[] = { | |||
725 | HDA_CODEC_VOLUME("CD Playback Volume", 0x17, 0x04, HDA_INPUT), | 749 | HDA_CODEC_VOLUME("CD Playback Volume", 0x17, 0x04, HDA_INPUT), |
726 | HDA_CODEC_MUTE("CD Playback Switch", 0x17, 0x04, HDA_INPUT), | 750 | HDA_CODEC_MUTE("CD Playback Switch", 0x17, 0x04, HDA_INPUT), |
727 | 751 | ||
728 | /* Controls for GPIO pins, assuming they exist and are configured as outputs */ | 752 | HDA_CODEC_VOLUME("Capture-1 Volume", 0x17, 0x0, HDA_INPUT), |
729 | CXT_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01), | 753 | HDA_CODEC_MUTE("Capture-1 Switch", 0x17, 0x0, HDA_INPUT), |
730 | #if 0 /* limit this to one GPIO pin for now */ | 754 | HDA_CODEC_VOLUME("Capture-2 Volume", 0x17, 0x1, HDA_INPUT), |
731 | CXT_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02), | 755 | HDA_CODEC_MUTE("Capture-2 Switch", 0x17, 0x1, HDA_INPUT), |
732 | CXT_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04), | 756 | HDA_CODEC_VOLUME("Capture-3 Volume", 0x17, 0x2, HDA_INPUT), |
733 | CXT_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08), | 757 | HDA_CODEC_MUTE("Capture-3 Switch", 0x17, 0x2, HDA_INPUT), |
734 | #endif | 758 | HDA_CODEC_VOLUME("Capture-4 Volume", 0x17, 0x3, HDA_INPUT), |
735 | CXT_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x13, 0x01), | 759 | HDA_CODEC_MUTE("Capture-4 Switch", 0x17, 0x3, HDA_INPUT), |
736 | 760 | HDA_CODEC_VOLUME("Capture-5 Volume", 0x17, 0x4, HDA_INPUT), | |
737 | HDA_CODEC_VOLUME("Capture Volume", 0x17, 0x0, HDA_OUTPUT), | 761 | HDA_CODEC_MUTE("Capture-5 Switch", 0x17, 0x4, HDA_INPUT), |
738 | HDA_CODEC_MUTE("Capture Switch", 0x17, 0x0, HDA_OUTPUT), | ||
739 | { | 762 | { |
740 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 763 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
741 | .name = "Input Source", | 764 | .name = "Input Source", |
@@ -748,14 +771,9 @@ static struct snd_kcontrol_new cxt5045_test_mixer[] = { | |||
748 | }; | 771 | }; |
749 | 772 | ||
750 | static struct hda_verb cxt5045_test_init_verbs[] = { | 773 | static struct hda_verb cxt5045_test_init_verbs[] = { |
751 | /* Enable all GPIOs as outputs with an initial value of 0 */ | ||
752 | {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f}, | ||
753 | {0x01, AC_VERB_SET_GPIO_DATA, 0x00}, | ||
754 | {0x01, AC_VERB_SET_GPIO_MASK, 0x0f}, | ||
755 | |||
756 | /* Enable retasking pins as output, initially without power amp */ | 774 | /* Enable retasking pins as output, initially without power amp */ |
757 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | 775 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, |
758 | {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | 776 | {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, |
759 | 777 | ||
760 | /* Disable digital (SPDIF) pins initially, but users can enable | 778 | /* Disable digital (SPDIF) pins initially, but users can enable |
761 | * them via a mixer switch. In the case of SPDIF-out, this initverb | 779 | * them via a mixer switch. In the case of SPDIF-out, this initverb |
@@ -823,6 +841,8 @@ static const char *cxt5045_models[CXT5045_MODELS] = { | |||
823 | 841 | ||
824 | static struct snd_pci_quirk cxt5045_cfg_tbl[] = { | 842 | static struct snd_pci_quirk cxt5045_cfg_tbl[] = { |
825 | SND_PCI_QUIRK(0x103c, 0x30b7, "HP DV6000Z", CXT5045_LAPTOP), | 843 | SND_PCI_QUIRK(0x103c, 0x30b7, "HP DV6000Z", CXT5045_LAPTOP), |
844 | SND_PCI_QUIRK(0x103c, 0x30bb, "HP DV8000", CXT5045_LAPTOP), | ||
845 | SND_PCI_QUIRK(0x1734, 0x10ad, "Fujitsu Si1520", CXT5045_LAPTOP), | ||
826 | {} | 846 | {} |
827 | }; | 847 | }; |
828 | 848 | ||
@@ -880,11 +900,11 @@ static int patch_cxt5045(struct hda_codec *codec) | |||
880 | 900 | ||
881 | 901 | ||
882 | /* Conexant 5047 specific */ | 902 | /* Conexant 5047 specific */ |
903 | #define CXT5047_SPDIF_OUT 0x11 | ||
883 | 904 | ||
884 | static hda_nid_t cxt5047_dac_nids[1] = { 0x10 }; | 905 | static hda_nid_t cxt5047_dac_nids[2] = { 0x10, 0x1c }; |
885 | static hda_nid_t cxt5047_adc_nids[1] = { 0x12 }; | 906 | static hda_nid_t cxt5047_adc_nids[1] = { 0x12 }; |
886 | static hda_nid_t cxt5047_capsrc_nids[1] = { 0x1a }; | 907 | static hda_nid_t cxt5047_capsrc_nids[1] = { 0x1a }; |
887 | #define CXT5047_SPDIF_OUT 0x11 | ||
888 | 908 | ||
889 | static struct hda_channel_mode cxt5047_modes[1] = { | 909 | static struct hda_channel_mode cxt5047_modes[1] = { |
890 | { 2, NULL }, | 910 | { 2, NULL }, |
@@ -893,15 +913,23 @@ static struct hda_channel_mode cxt5047_modes[1] = { | |||
893 | static struct hda_input_mux cxt5047_capture_source = { | 913 | static struct hda_input_mux cxt5047_capture_source = { |
894 | .num_items = 2, | 914 | .num_items = 2, |
895 | .items = { | 915 | .items = { |
896 | { "ExtMic", 0x1 }, | 916 | { "ExtMic", 0x0 }, |
897 | { "IntMic", 0x2 }, | 917 | { "IntMic", 0x1 }, |
898 | } | 918 | } |
899 | }; | 919 | }; |
900 | 920 | ||
901 | static struct hda_input_mux cxt5047_hp_capture_source = { | 921 | static struct hda_input_mux cxt5047_hp_capture_source = { |
902 | .num_items = 1, | 922 | .num_items = 1, |
903 | .items = { | 923 | .items = { |
904 | { "ExtMic", 0x1 }, | 924 | { "ExtMic", 0x2 }, |
925 | } | ||
926 | }; | ||
927 | |||
928 | static struct hda_input_mux cxt5047_toshiba_capture_source = { | ||
929 | .num_items = 2, | ||
930 | .items = { | ||
931 | { "ExtMic", 0x2 }, | ||
932 | { "Line-In", 0x1 }, | ||
905 | } | 933 | } |
906 | }; | 934 | }; |
907 | 935 | ||
@@ -911,20 +939,24 @@ static int cxt5047_hp_master_sw_put(struct snd_kcontrol *kcontrol, | |||
911 | { | 939 | { |
912 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 940 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
913 | struct conexant_spec *spec = codec->spec; | 941 | struct conexant_spec *spec = codec->spec; |
942 | unsigned int bits; | ||
914 | 943 | ||
915 | if (!conexant_eapd_put(kcontrol, ucontrol)) | 944 | if (!cxt_eapd_put(kcontrol, ucontrol)) |
916 | return 0; | 945 | return 0; |
917 | 946 | ||
918 | /* toggle HP mute appropriately */ | 947 | /* toggle internal speakers mute depending of presence of |
919 | snd_hda_codec_amp_update(codec, 0x13, 0, HDA_OUTPUT, 0, | 948 | * the headphone jack |
920 | 0x80, spec->cur_eapd ? 0 : 0x80); | 949 | */ |
921 | snd_hda_codec_amp_update(codec, 0x13, 1, HDA_OUTPUT, 0, | 950 | bits = (!spec->hp_present && spec->cur_eapd) ? 0 : 0x80; |
922 | 0x80, spec->cur_eapd ? 0 : 0x80); | 951 | snd_hda_codec_amp_update(codec, 0x1d, 0, HDA_OUTPUT, 0, 0x80, bits); |
952 | snd_hda_codec_amp_update(codec, 0x1d, 1, HDA_OUTPUT, 0, 0x80, bits); | ||
953 | bits = spec->cur_eapd ? 0 : 0x80; | ||
954 | snd_hda_codec_amp_update(codec, 0x13, 0, HDA_OUTPUT, 0, 0x80, bits); | ||
955 | snd_hda_codec_amp_update(codec, 0x13, 1, HDA_OUTPUT, 0, 0x80, bits); | ||
923 | return 1; | 956 | return 1; |
924 | } | 957 | } |
925 | 958 | ||
926 | #if 0 | 959 | /* bind volumes of both NID 0x13 (Headphones) and 0x1d (Speakers) */ |
927 | /* bind volumes of both NID 0x13 and 0x1d */ | ||
928 | static int cxt5047_hp_master_vol_put(struct snd_kcontrol *kcontrol, | 960 | static int cxt5047_hp_master_vol_put(struct snd_kcontrol *kcontrol, |
929 | struct snd_ctl_elem_value *ucontrol) | 961 | struct snd_ctl_elem_value *ucontrol) |
930 | { | 962 | { |
@@ -932,9 +964,9 @@ static int cxt5047_hp_master_vol_put(struct snd_kcontrol *kcontrol, | |||
932 | long *valp = ucontrol->value.integer.value; | 964 | long *valp = ucontrol->value.integer.value; |
933 | int change; | 965 | int change; |
934 | 966 | ||
935 | change = snd_hda_codec_amp_update(codec, 0x1c, 0, HDA_OUTPUT, 0, | 967 | change = snd_hda_codec_amp_update(codec, 0x1d, 0, HDA_OUTPUT, 0, |
936 | 0x7f, valp[0] & 0x7f); | 968 | 0x7f, valp[0] & 0x7f); |
937 | change |= snd_hda_codec_amp_update(codec, 0x1c, 1, HDA_OUTPUT, 0, | 969 | change |= snd_hda_codec_amp_update(codec, 0x1d, 1, HDA_OUTPUT, 0, |
938 | 0x7f, valp[1] & 0x7f); | 970 | 0x7f, valp[1] & 0x7f); |
939 | snd_hda_codec_amp_update(codec, 0x13, 0, HDA_OUTPUT, 0, | 971 | snd_hda_codec_amp_update(codec, 0x13, 0, HDA_OUTPUT, 0, |
940 | 0x7f, valp[0] & 0x7f); | 972 | 0x7f, valp[0] & 0x7f); |
@@ -942,19 +974,20 @@ static int cxt5047_hp_master_vol_put(struct snd_kcontrol *kcontrol, | |||
942 | 0x7f, valp[1] & 0x7f); | 974 | 0x7f, valp[1] & 0x7f); |
943 | return change; | 975 | return change; |
944 | } | 976 | } |
945 | #endif | ||
946 | 977 | ||
947 | /* mute internal speaker if HP is plugged */ | 978 | /* mute internal speaker if HP is plugged */ |
948 | static void cxt5047_hp_automute(struct hda_codec *codec) | 979 | static void cxt5047_hp_automute(struct hda_codec *codec) |
949 | { | 980 | { |
950 | unsigned int present; | 981 | struct conexant_spec *spec = codec->spec; |
982 | unsigned int bits = spec->hp_present || !spec->cur_eapd ? 0x80 : 0; | ||
951 | 983 | ||
952 | present = snd_hda_codec_read(codec, 0x13, 0, | 984 | spec->hp_present = snd_hda_codec_read(codec, 0x13, 0, |
953 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | 985 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; |
954 | snd_hda_codec_amp_update(codec, 0x1c, 0, HDA_OUTPUT, 0, | 986 | snd_hda_codec_amp_update(codec, 0x1d, 0, HDA_OUTPUT, 0, 0x80, bits); |
955 | 0x80, present ? 0x80 : 0); | 987 | snd_hda_codec_amp_update(codec, 0x1d, 1, HDA_OUTPUT, 0, 0x80, bits); |
956 | snd_hda_codec_amp_update(codec, 0x1c, 1, HDA_OUTPUT, 0, | 988 | /* Mute/Unmute PCM 2 for good measure - some systems need this */ |
957 | 0x80, present ? 0x80 : 0); | 989 | snd_hda_codec_amp_update(codec, 0x1c, 0, HDA_OUTPUT, 0, 0x80, bits); |
990 | snd_hda_codec_amp_update(codec, 0x1c, 1, HDA_OUTPUT, 0, 0x80, bits); | ||
958 | } | 991 | } |
959 | 992 | ||
960 | /* toggle input of built-in and mic jack appropriately */ | 993 | /* toggle input of built-in and mic jack appropriately */ |
@@ -1009,12 +1042,55 @@ static struct snd_kcontrol_new cxt5047_mixers[] = { | |||
1009 | HDA_CODEC_MUTE("Capture Switch", 0x12, 0x03, HDA_INPUT), | 1042 | HDA_CODEC_MUTE("Capture Switch", 0x12, 0x03, HDA_INPUT), |
1010 | HDA_CODEC_VOLUME("PCM Volume", 0x10, 0x00, HDA_OUTPUT), | 1043 | HDA_CODEC_VOLUME("PCM Volume", 0x10, 0x00, HDA_OUTPUT), |
1011 | HDA_CODEC_MUTE("PCM Switch", 0x10, 0x00, HDA_OUTPUT), | 1044 | HDA_CODEC_MUTE("PCM Switch", 0x10, 0x00, HDA_OUTPUT), |
1012 | HDA_CODEC_VOLUME("Master Playback Volume", 0x13, 0x00, HDA_OUTPUT), | 1045 | HDA_CODEC_VOLUME("PCM-2 Volume", 0x1c, 0x00, HDA_OUTPUT), |
1046 | HDA_CODEC_MUTE("PCM-2 Switch", 0x1c, 0x00, HDA_OUTPUT), | ||
1047 | { | ||
1048 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
1049 | .name = "Master Playback Volume", | ||
1050 | .info = snd_hda_mixer_amp_volume_info, | ||
1051 | .get = snd_hda_mixer_amp_volume_get, | ||
1052 | .put = cxt5047_hp_master_vol_put, | ||
1053 | .private_value = HDA_COMPOSE_AMP_VAL(0x13, 3, 0, HDA_OUTPUT), | ||
1054 | }, | ||
1013 | { | 1055 | { |
1014 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 1056 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
1015 | .name = "Master Playback Switch", | 1057 | .name = "Master Playback Switch", |
1016 | .info = conexant_eapd_info, | 1058 | .info = cxt_eapd_info, |
1017 | .get = conexant_eapd_get, | 1059 | .get = cxt_eapd_get, |
1060 | .put = cxt5047_hp_master_sw_put, | ||
1061 | .private_value = 0x13, | ||
1062 | }, | ||
1063 | |||
1064 | {} | ||
1065 | }; | ||
1066 | |||
1067 | static struct snd_kcontrol_new cxt5047_toshiba_mixers[] = { | ||
1068 | { | ||
1069 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
1070 | .name = "Capture Source", | ||
1071 | .info = conexant_mux_enum_info, | ||
1072 | .get = conexant_mux_enum_get, | ||
1073 | .put = conexant_mux_enum_put | ||
1074 | }, | ||
1075 | HDA_CODEC_VOLUME("Mic Bypass Capture Volume", 0x19, 0x02, HDA_INPUT), | ||
1076 | HDA_CODEC_MUTE("Mic Bypass Capture Switch", 0x19, 0x02, HDA_INPUT), | ||
1077 | HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x03, HDA_INPUT), | ||
1078 | HDA_CODEC_MUTE("Capture Switch", 0x12, 0x03, HDA_INPUT), | ||
1079 | HDA_CODEC_VOLUME("PCM Volume", 0x10, 0x00, HDA_OUTPUT), | ||
1080 | HDA_CODEC_MUTE("PCM Switch", 0x10, 0x00, HDA_OUTPUT), | ||
1081 | { | ||
1082 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
1083 | .name = "Master Playback Volume", | ||
1084 | .info = snd_hda_mixer_amp_volume_info, | ||
1085 | .get = snd_hda_mixer_amp_volume_get, | ||
1086 | .put = cxt5047_hp_master_vol_put, | ||
1087 | .private_value = HDA_COMPOSE_AMP_VAL(0x13, 3, 0, HDA_OUTPUT), | ||
1088 | }, | ||
1089 | { | ||
1090 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
1091 | .name = "Master Playback Switch", | ||
1092 | .info = cxt_eapd_info, | ||
1093 | .get = cxt_eapd_get, | ||
1018 | .put = cxt5047_hp_master_sw_put, | 1094 | .put = cxt5047_hp_master_sw_put, |
1019 | .private_value = 0x13, | 1095 | .private_value = 0x13, |
1020 | }, | 1096 | }, |
@@ -1040,8 +1116,8 @@ static struct snd_kcontrol_new cxt5047_hp_mixers[] = { | |||
1040 | { | 1116 | { |
1041 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 1117 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
1042 | .name = "Master Playback Switch", | 1118 | .name = "Master Playback Switch", |
1043 | .info = conexant_eapd_info, | 1119 | .info = cxt_eapd_info, |
1044 | .get = conexant_eapd_get, | 1120 | .get = cxt_eapd_get, |
1045 | .put = cxt5047_hp_master_sw_put, | 1121 | .put = cxt5047_hp_master_sw_put, |
1046 | .private_value = 0x13, | 1122 | .private_value = 0x13, |
1047 | }, | 1123 | }, |
@@ -1053,19 +1129,23 @@ static struct hda_verb cxt5047_init_verbs[] = { | |||
1053 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, | 1129 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, |
1054 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_50 }, | 1130 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_50 }, |
1055 | {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_50 }, | 1131 | {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_50 }, |
1056 | /* HP, Amp */ | 1132 | /* HP, Amp, Speaker */ |
1057 | {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | 1133 | {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, |
1058 | {0x1A, AC_VERB_SET_CONNECT_SEL,0x03}, | 1134 | {0x1A, AC_VERB_SET_CONNECT_SEL,0x00}, |
1059 | {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, | 1135 | {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, |
1060 | AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x00}, | 1136 | AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x00}, |
1061 | {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, | 1137 | {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, |
1062 | AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x03}, | 1138 | AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x03}, |
1139 | {0x1d, AC_VERB_SET_CONNECT_SEL,0x0}, | ||
1063 | /* Record selector: Front mic */ | 1140 | /* Record selector: Front mic */ |
1064 | {0x12, AC_VERB_SET_CONNECT_SEL,0x03}, | 1141 | {0x12, AC_VERB_SET_CONNECT_SEL,0x03}, |
1065 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, | 1142 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, |
1066 | AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17}, | 1143 | AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17}, |
1067 | /* SPDIF route: PCM */ | 1144 | /* SPDIF route: PCM */ |
1068 | { 0x18, AC_VERB_SET_CONNECT_SEL, 0x0 }, | 1145 | { 0x18, AC_VERB_SET_CONNECT_SEL, 0x0 }, |
1146 | /* Enable unsolicited events */ | ||
1147 | {0x13, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT}, | ||
1148 | {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT}, | ||
1069 | { } /* end */ | 1149 | { } /* end */ |
1070 | }; | 1150 | }; |
1071 | 1151 | ||
@@ -1075,14 +1155,24 @@ static struct hda_verb cxt5047_toshiba_init_verbs[] = { | |||
1075 | /* pin sensing on HP and Mic jacks */ | 1155 | /* pin sensing on HP and Mic jacks */ |
1076 | {0x13, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT}, | 1156 | {0x13, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT}, |
1077 | {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT}, | 1157 | {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT}, |
1158 | /* Speaker routing */ | ||
1159 | {0x1d, AC_VERB_SET_CONNECT_SEL,0x1}, | ||
1160 | /* Change default to ExtMic for recording */ | ||
1161 | {0x1a, AC_VERB_SET_CONNECT_SEL,0x2}, | ||
1078 | {} | 1162 | {} |
1079 | }; | 1163 | }; |
1080 | 1164 | ||
1081 | /* configuration for HP Laptops */ | 1165 | /* configuration for HP Laptops */ |
1082 | static struct hda_verb cxt5047_hp_init_verbs[] = { | 1166 | static struct hda_verb cxt5047_hp_init_verbs[] = { |
1083 | /* pin sensing on HP and Mic jacks */ | 1167 | /* pin sensing on HP jack */ |
1084 | {0x13, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT}, | 1168 | {0x13, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT}, |
1085 | {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT}, | 1169 | /* Record selector: Ext Mic */ |
1170 | {0x12, AC_VERB_SET_CONNECT_SEL,0x03}, | ||
1171 | {0x1a, AC_VERB_SET_CONNECT_SEL,0x02}, | ||
1172 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, | ||
1173 | AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17}, | ||
1174 | /* Speaker routing */ | ||
1175 | {0x1d, AC_VERB_SET_CONNECT_SEL,0x1}, | ||
1086 | {} | 1176 | {} |
1087 | }; | 1177 | }; |
1088 | 1178 | ||
@@ -1091,53 +1181,56 @@ static struct hda_verb cxt5047_hp_init_verbs[] = { | |||
1091 | */ | 1181 | */ |
1092 | #ifdef CONFIG_SND_DEBUG | 1182 | #ifdef CONFIG_SND_DEBUG |
1093 | static struct hda_input_mux cxt5047_test_capture_source = { | 1183 | static struct hda_input_mux cxt5047_test_capture_source = { |
1094 | .num_items = 5, | 1184 | .num_items = 4, |
1095 | .items = { | 1185 | .items = { |
1096 | { "MIXER", 0x0 }, | 1186 | { "LINE1 pin", 0x0 }, |
1097 | { "LINE1 pin", 0x1 }, | 1187 | { "MIC1 pin", 0x1 }, |
1098 | { "MIC1 pin", 0x2 }, | 1188 | { "MIC2 pin", 0x2 }, |
1099 | { "MIC2 pin", 0x3 }, | 1189 | { "CD pin", 0x3 }, |
1100 | { "CD pin", 0x4 }, | ||
1101 | }, | 1190 | }, |
1102 | }; | 1191 | }; |
1103 | 1192 | ||
1104 | static struct snd_kcontrol_new cxt5047_test_mixer[] = { | 1193 | static struct snd_kcontrol_new cxt5047_test_mixer[] = { |
1105 | 1194 | ||
1106 | /* Output only controls */ | 1195 | /* Output only controls */ |
1107 | HDA_CODEC_VOLUME("OutAmp-1 Volume", 0x10, 0x00, HDA_OUTPUT), | 1196 | HDA_CODEC_VOLUME("OutAmp-1 Volume", 0x10, 0x0, HDA_OUTPUT), |
1108 | HDA_CODEC_MUTE("OutAmp-1 Switch", 0x10,0x00, HDA_OUTPUT), | 1197 | HDA_CODEC_MUTE("OutAmp-1 Switch", 0x10,0x0, HDA_OUTPUT), |
1109 | HDA_CODEC_VOLUME("OutAmp-2 Volume", 0x1c, 0x00, HDA_OUTPUT), | 1198 | HDA_CODEC_VOLUME("OutAmp-2 Volume", 0x1c, 0x0, HDA_OUTPUT), |
1110 | HDA_CODEC_MUTE("OutAmp-2 Switch", 0x1c, 0x00, HDA_OUTPUT), | 1199 | HDA_CODEC_MUTE("OutAmp-2 Switch", 0x1c, 0x0, HDA_OUTPUT), |
1111 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x1d, 0x0, HDA_OUTPUT), | 1200 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x1d, 0x0, HDA_OUTPUT), |
1112 | HDA_CODEC_MUTE("Speaker Playback Switch", 0x1d, 0x0, HDA_OUTPUT), | 1201 | HDA_CODEC_MUTE("Speaker Playback Switch", 0x1d, 0x0, HDA_OUTPUT), |
1113 | HDA_CODEC_VOLUME("HeadPhone Playback Volume", 0x13, 0x0, HDA_OUTPUT), | 1202 | HDA_CODEC_VOLUME("HeadPhone Playback Volume", 0x13, 0x0, HDA_OUTPUT), |
1114 | HDA_CODEC_MUTE("HeadPhone Playback Switch", 0x13, 0x0, HDA_OUTPUT), | 1203 | HDA_CODEC_MUTE("HeadPhone Playback Switch", 0x13, 0x0, HDA_OUTPUT), |
1204 | HDA_CODEC_VOLUME("Line1-Out Playback Volume", 0x14, 0x0, HDA_OUTPUT), | ||
1205 | HDA_CODEC_MUTE("Line1-Out Playback Switch", 0x14, 0x0, HDA_OUTPUT), | ||
1206 | HDA_CODEC_VOLUME("Line2-Out Playback Volume", 0x15, 0x0, HDA_OUTPUT), | ||
1207 | HDA_CODEC_MUTE("Line2-Out Playback Switch", 0x15, 0x0, HDA_OUTPUT), | ||
1115 | 1208 | ||
1116 | /* Modes for retasking pin widgets */ | 1209 | /* Modes for retasking pin widgets */ |
1117 | CXT_PIN_MODE("LINE1 pin mode", 0x14, CXT_PIN_DIR_INOUT), | 1210 | CXT_PIN_MODE("LINE1 pin mode", 0x14, CXT_PIN_DIR_INOUT), |
1118 | CXT_PIN_MODE("MIC1 pin mode", 0x15, CXT_PIN_DIR_INOUT), | 1211 | CXT_PIN_MODE("MIC1 pin mode", 0x15, CXT_PIN_DIR_INOUT), |
1119 | 1212 | ||
1120 | /* Loopback mixer controls */ | 1213 | /* EAPD Switch Control */ |
1121 | HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x19, 0x02, HDA_INPUT), | 1214 | CXT_EAPD_SWITCH("External Amplifier", 0x13, 0x0), |
1122 | HDA_CODEC_MUTE("MIC1 Playback Switch", 0x19, 0x02, HDA_INPUT), | ||
1123 | HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x19, 0x03, HDA_INPUT), | ||
1124 | HDA_CODEC_MUTE("MIC2 Playback Switch", 0x19, 0x03, HDA_INPUT), | ||
1125 | HDA_CODEC_VOLUME("LINE Playback Volume", 0x19, 0x01, HDA_INPUT), | ||
1126 | HDA_CODEC_MUTE("LINE Playback Switch", 0x19, 0x01, HDA_INPUT), | ||
1127 | HDA_CODEC_VOLUME("CD Playback Volume", 0x19, 0x04, HDA_INPUT), | ||
1128 | HDA_CODEC_MUTE("CD Playback Switch", 0x19, 0x04, HDA_INPUT), | ||
1129 | |||
1130 | #if 0 | ||
1131 | /* Controls for GPIO pins, assuming they exist and are configured as outputs */ | ||
1132 | CXT_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01), | ||
1133 | CXT_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02), | ||
1134 | CXT_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04), | ||
1135 | CXT_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08), | ||
1136 | #endif | ||
1137 | CXT_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x18, 0x01), | ||
1138 | 1215 | ||
1139 | HDA_CODEC_VOLUME("Capture Volume", 0x19, 0x0, HDA_OUTPUT), | 1216 | /* Loopback mixer controls */ |
1140 | HDA_CODEC_MUTE("Capture Switch", 0x19, 0x0, HDA_OUTPUT), | 1217 | HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x12, 0x01, HDA_INPUT), |
1218 | HDA_CODEC_MUTE("MIC1 Playback Switch", 0x12, 0x01, HDA_INPUT), | ||
1219 | HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x12, 0x02, HDA_INPUT), | ||
1220 | HDA_CODEC_MUTE("MIC2 Playback Switch", 0x12, 0x02, HDA_INPUT), | ||
1221 | HDA_CODEC_VOLUME("LINE Playback Volume", 0x12, 0x0, HDA_INPUT), | ||
1222 | HDA_CODEC_MUTE("LINE Playback Switch", 0x12, 0x0, HDA_INPUT), | ||
1223 | HDA_CODEC_VOLUME("CD Playback Volume", 0x12, 0x04, HDA_INPUT), | ||
1224 | HDA_CODEC_MUTE("CD Playback Switch", 0x12, 0x04, HDA_INPUT), | ||
1225 | |||
1226 | HDA_CODEC_VOLUME("Capture-1 Volume", 0x19, 0x0, HDA_INPUT), | ||
1227 | HDA_CODEC_MUTE("Capture-1 Switch", 0x19, 0x0, HDA_INPUT), | ||
1228 | HDA_CODEC_VOLUME("Capture-2 Volume", 0x19, 0x1, HDA_INPUT), | ||
1229 | HDA_CODEC_MUTE("Capture-2 Switch", 0x19, 0x1, HDA_INPUT), | ||
1230 | HDA_CODEC_VOLUME("Capture-3 Volume", 0x19, 0x2, HDA_INPUT), | ||
1231 | HDA_CODEC_MUTE("Capture-3 Switch", 0x19, 0x2, HDA_INPUT), | ||
1232 | HDA_CODEC_VOLUME("Capture-4 Volume", 0x19, 0x3, HDA_INPUT), | ||
1233 | HDA_CODEC_MUTE("Capture-4 Switch", 0x19, 0x3, HDA_INPUT), | ||
1141 | { | 1234 | { |
1142 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 1235 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
1143 | .name = "Input Source", | 1236 | .name = "Input Source", |
@@ -1145,16 +1238,18 @@ static struct snd_kcontrol_new cxt5047_test_mixer[] = { | |||
1145 | .get = conexant_mux_enum_get, | 1238 | .get = conexant_mux_enum_get, |
1146 | .put = conexant_mux_enum_put, | 1239 | .put = conexant_mux_enum_put, |
1147 | }, | 1240 | }, |
1241 | /* Controls for GPIO pins, assuming they exist and are configured | ||
1242 | * as outputs | ||
1243 | */ | ||
1244 | CXT_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01), | ||
1245 | CXT_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02), | ||
1246 | CXT_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04), | ||
1247 | CXT_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08), | ||
1148 | 1248 | ||
1149 | { } /* end */ | 1249 | { } /* end */ |
1150 | }; | 1250 | }; |
1151 | 1251 | ||
1152 | static struct hda_verb cxt5047_test_init_verbs[] = { | 1252 | static struct hda_verb cxt5047_test_init_verbs[] = { |
1153 | /* Enable all GPIOs as outputs with an initial value of 0 */ | ||
1154 | {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f}, | ||
1155 | {0x01, AC_VERB_SET_GPIO_DATA, 0x00}, | ||
1156 | {0x01, AC_VERB_SET_GPIO_MASK, 0x0f}, | ||
1157 | |||
1158 | /* Enable retasking pins as output, initially without power amp */ | 1253 | /* Enable retasking pins as output, initially without power amp */ |
1159 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | 1254 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, |
1160 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | 1255 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, |
@@ -1215,7 +1310,6 @@ static int cxt5047_hp_init(struct hda_codec *codec) | |||
1215 | { | 1310 | { |
1216 | conexant_init(codec); | 1311 | conexant_init(codec); |
1217 | cxt5047_hp_automute(codec); | 1312 | cxt5047_hp_automute(codec); |
1218 | cxt5047_hp_automic(codec); | ||
1219 | return 0; | 1313 | return 0; |
1220 | } | 1314 | } |
1221 | 1315 | ||
@@ -1242,6 +1336,7 @@ static const char *cxt5047_models[CXT5047_MODELS] = { | |||
1242 | static struct snd_pci_quirk cxt5047_cfg_tbl[] = { | 1336 | static struct snd_pci_quirk cxt5047_cfg_tbl[] = { |
1243 | SND_PCI_QUIRK(0x103c, 0x30a0, "HP DV1000", CXT5047_LAPTOP), | 1337 | SND_PCI_QUIRK(0x103c, 0x30a0, "HP DV1000", CXT5047_LAPTOP), |
1244 | SND_PCI_QUIRK(0x103c, 0x30b2, "HP DV2000T/DV3000T", CXT5047_LAPTOP), | 1338 | SND_PCI_QUIRK(0x103c, 0x30b2, "HP DV2000T/DV3000T", CXT5047_LAPTOP), |
1339 | SND_PCI_QUIRK(0x103c, 0x30b5, "HP DV2000Z", CXT5047_LAPTOP), | ||
1245 | SND_PCI_QUIRK(0x103c, 0x30a5, "HP DV5200T/DV8000T", CXT5047_LAPTOP_HP), | 1340 | SND_PCI_QUIRK(0x103c, 0x30a5, "HP DV5200T/DV8000T", CXT5047_LAPTOP_HP), |
1246 | SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba P100", CXT5047_LAPTOP_EAPD), | 1341 | SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba P100", CXT5047_LAPTOP_EAPD), |
1247 | {} | 1342 | {} |
@@ -1291,8 +1386,10 @@ static int patch_cxt5047(struct hda_codec *codec) | |||
1291 | codec->patch_ops.init = cxt5047_hp_init; | 1386 | codec->patch_ops.init = cxt5047_hp_init; |
1292 | break; | 1387 | break; |
1293 | case CXT5047_LAPTOP_EAPD: | 1388 | case CXT5047_LAPTOP_EAPD: |
1389 | spec->input_mux = &cxt5047_toshiba_capture_source; | ||
1294 | spec->num_init_verbs = 2; | 1390 | spec->num_init_verbs = 2; |
1295 | spec->init_verbs[1] = cxt5047_toshiba_init_verbs; | 1391 | spec->init_verbs[1] = cxt5047_toshiba_init_verbs; |
1392 | spec->mixers[0] = cxt5047_toshiba_mixers; | ||
1296 | break; | 1393 | break; |
1297 | #ifdef CONFIG_SND_DEBUG | 1394 | #ifdef CONFIG_SND_DEBUG |
1298 | case CXT5047_TEST: | 1395 | case CXT5047_TEST: |
@@ -1305,7 +1402,9 @@ static int patch_cxt5047(struct hda_codec *codec) | |||
1305 | } | 1402 | } |
1306 | 1403 | ||
1307 | struct hda_codec_preset snd_hda_preset_conexant[] = { | 1404 | struct hda_codec_preset snd_hda_preset_conexant[] = { |
1308 | { .id = 0x14f15045, .name = "CXT5045", .patch = patch_cxt5045 }, | 1405 | { .id = 0x14f15045, .name = "CX20549 (Venice)", |
1309 | { .id = 0x14f15047, .name = "CXT5047", .patch = patch_cxt5047 }, | 1406 | .patch = patch_cxt5045 }, |
1407 | { .id = 0x14f15047, .name = "CX20551 (Waikiki)", | ||
1408 | .patch = patch_cxt5047 }, | ||
1310 | {} /* terminator */ | 1409 | {} /* terminator */ |
1311 | }; | 1410 | }; |