diff options
-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 | }; |