diff options
Diffstat (limited to 'sound/pci/hda')
-rw-r--r-- | sound/pci/hda/hda_controller.c | 2 | ||||
-rw-r--r-- | sound/pci/hda/hda_generic.c | 47 | ||||
-rw-r--r-- | sound/pci/hda/hda_proc.c | 38 | ||||
-rw-r--r-- | sound/pci/hda/patch_cirrus.c | 2 | ||||
-rw-r--r-- | sound/pci/hda/patch_conexant.c | 11 |
5 files changed, 83 insertions, 17 deletions
diff --git a/sound/pci/hda/hda_controller.c b/sound/pci/hda/hda_controller.c index a2ce773bdc62..17c2637d842c 100644 --- a/sound/pci/hda/hda_controller.c +++ b/sound/pci/hda/hda_controller.c | |||
@@ -1164,7 +1164,7 @@ static unsigned int azx_rirb_get_response(struct hda_bus *bus, | |||
1164 | } | 1164 | } |
1165 | } | 1165 | } |
1166 | 1166 | ||
1167 | if (!bus->no_response_fallback) | 1167 | if (bus->no_response_fallback) |
1168 | return -1; | 1168 | return -1; |
1169 | 1169 | ||
1170 | if (!chip->polling_mode && chip->poll_count < 2) { | 1170 | if (!chip->polling_mode && chip->poll_count < 2) { |
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c index b680b4ec6331..8ec5289f8e05 100644 --- a/sound/pci/hda/hda_generic.c +++ b/sound/pci/hda/hda_generic.c | |||
@@ -687,12 +687,45 @@ static int get_amp_val_to_activate(struct hda_codec *codec, hda_nid_t nid, | |||
687 | return val; | 687 | return val; |
688 | } | 688 | } |
689 | 689 | ||
690 | /* is this a stereo widget or a stereo-to-mono mix? */ | ||
691 | static bool is_stereo_amps(struct hda_codec *codec, hda_nid_t nid, int dir) | ||
692 | { | ||
693 | unsigned int wcaps = get_wcaps(codec, nid); | ||
694 | hda_nid_t conn; | ||
695 | |||
696 | if (wcaps & AC_WCAP_STEREO) | ||
697 | return true; | ||
698 | if (dir != HDA_INPUT || get_wcaps_type(wcaps) != AC_WID_AUD_MIX) | ||
699 | return false; | ||
700 | if (snd_hda_get_num_conns(codec, nid) != 1) | ||
701 | return false; | ||
702 | if (snd_hda_get_connections(codec, nid, &conn, 1) < 0) | ||
703 | return false; | ||
704 | return !!(get_wcaps(codec, conn) & AC_WCAP_STEREO); | ||
705 | } | ||
706 | |||
690 | /* initialize the amp value (only at the first time) */ | 707 | /* initialize the amp value (only at the first time) */ |
691 | static void init_amp(struct hda_codec *codec, hda_nid_t nid, int dir, int idx) | 708 | static void init_amp(struct hda_codec *codec, hda_nid_t nid, int dir, int idx) |
692 | { | 709 | { |
693 | unsigned int caps = query_amp_caps(codec, nid, dir); | 710 | unsigned int caps = query_amp_caps(codec, nid, dir); |
694 | int val = get_amp_val_to_activate(codec, nid, dir, caps, false); | 711 | int val = get_amp_val_to_activate(codec, nid, dir, caps, false); |
695 | snd_hda_codec_amp_init_stereo(codec, nid, dir, idx, 0xff, val); | 712 | |
713 | if (is_stereo_amps(codec, nid, dir)) | ||
714 | snd_hda_codec_amp_init_stereo(codec, nid, dir, idx, 0xff, val); | ||
715 | else | ||
716 | snd_hda_codec_amp_init(codec, nid, 0, dir, idx, 0xff, val); | ||
717 | } | ||
718 | |||
719 | /* update the amp, doing in stereo or mono depending on NID */ | ||
720 | static int update_amp(struct hda_codec *codec, hda_nid_t nid, int dir, int idx, | ||
721 | unsigned int mask, unsigned int val) | ||
722 | { | ||
723 | if (is_stereo_amps(codec, nid, dir)) | ||
724 | return snd_hda_codec_amp_stereo(codec, nid, dir, idx, | ||
725 | mask, val); | ||
726 | else | ||
727 | return snd_hda_codec_amp_update(codec, nid, 0, dir, idx, | ||
728 | mask, val); | ||
696 | } | 729 | } |
697 | 730 | ||
698 | /* calculate amp value mask we can modify; | 731 | /* calculate amp value mask we can modify; |
@@ -732,7 +765,7 @@ static void activate_amp(struct hda_codec *codec, hda_nid_t nid, int dir, | |||
732 | return; | 765 | return; |
733 | 766 | ||
734 | val &= mask; | 767 | val &= mask; |
735 | snd_hda_codec_amp_stereo(codec, nid, dir, idx, mask, val); | 768 | update_amp(codec, nid, dir, idx, mask, val); |
736 | } | 769 | } |
737 | 770 | ||
738 | static void activate_amp_out(struct hda_codec *codec, struct nid_path *path, | 771 | static void activate_amp_out(struct hda_codec *codec, struct nid_path *path, |
@@ -4424,13 +4457,11 @@ static void mute_all_mixer_nid(struct hda_codec *codec, hda_nid_t mix) | |||
4424 | has_amp = nid_has_mute(codec, mix, HDA_INPUT); | 4457 | has_amp = nid_has_mute(codec, mix, HDA_INPUT); |
4425 | for (i = 0; i < nums; i++) { | 4458 | for (i = 0; i < nums; i++) { |
4426 | if (has_amp) | 4459 | if (has_amp) |
4427 | snd_hda_codec_amp_stereo(codec, mix, | 4460 | update_amp(codec, mix, HDA_INPUT, i, |
4428 | HDA_INPUT, i, | 4461 | 0xff, HDA_AMP_MUTE); |
4429 | 0xff, HDA_AMP_MUTE); | ||
4430 | else if (nid_has_volume(codec, conn[i], HDA_OUTPUT)) | 4462 | else if (nid_has_volume(codec, conn[i], HDA_OUTPUT)) |
4431 | snd_hda_codec_amp_stereo(codec, conn[i], | 4463 | update_amp(codec, conn[i], HDA_OUTPUT, 0, |
4432 | HDA_OUTPUT, 0, | 4464 | 0xff, HDA_AMP_MUTE); |
4433 | 0xff, HDA_AMP_MUTE); | ||
4434 | } | 4465 | } |
4435 | } | 4466 | } |
4436 | 4467 | ||
diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c index ce5a6da83419..05e19f78b4cb 100644 --- a/sound/pci/hda/hda_proc.c +++ b/sound/pci/hda/hda_proc.c | |||
@@ -134,13 +134,38 @@ static void print_amp_caps(struct snd_info_buffer *buffer, | |||
134 | (caps & AC_AMPCAP_MUTE) >> AC_AMPCAP_MUTE_SHIFT); | 134 | (caps & AC_AMPCAP_MUTE) >> AC_AMPCAP_MUTE_SHIFT); |
135 | } | 135 | } |
136 | 136 | ||
137 | /* is this a stereo widget or a stereo-to-mono mix? */ | ||
138 | static bool is_stereo_amps(struct hda_codec *codec, hda_nid_t nid, | ||
139 | int dir, unsigned int wcaps, int indices) | ||
140 | { | ||
141 | hda_nid_t conn; | ||
142 | |||
143 | if (wcaps & AC_WCAP_STEREO) | ||
144 | return true; | ||
145 | /* check for a stereo-to-mono mix; it must be: | ||
146 | * only a single connection, only for input, and only a mixer widget | ||
147 | */ | ||
148 | if (indices != 1 || dir != HDA_INPUT || | ||
149 | get_wcaps_type(wcaps) != AC_WID_AUD_MIX) | ||
150 | return false; | ||
151 | |||
152 | if (snd_hda_get_raw_connections(codec, nid, &conn, 1) < 0) | ||
153 | return false; | ||
154 | /* the connection source is a stereo? */ | ||
155 | wcaps = snd_hda_param_read(codec, conn, AC_PAR_AUDIO_WIDGET_CAP); | ||
156 | return !!(wcaps & AC_WCAP_STEREO); | ||
157 | } | ||
158 | |||
137 | static void print_amp_vals(struct snd_info_buffer *buffer, | 159 | static void print_amp_vals(struct snd_info_buffer *buffer, |
138 | struct hda_codec *codec, hda_nid_t nid, | 160 | struct hda_codec *codec, hda_nid_t nid, |
139 | int dir, int stereo, int indices) | 161 | int dir, unsigned int wcaps, int indices) |
140 | { | 162 | { |
141 | unsigned int val; | 163 | unsigned int val; |
164 | bool stereo; | ||
142 | int i; | 165 | int i; |
143 | 166 | ||
167 | stereo = is_stereo_amps(codec, nid, dir, wcaps, indices); | ||
168 | |||
144 | dir = dir == HDA_OUTPUT ? AC_AMP_GET_OUTPUT : AC_AMP_GET_INPUT; | 169 | dir = dir == HDA_OUTPUT ? AC_AMP_GET_OUTPUT : AC_AMP_GET_INPUT; |
145 | for (i = 0; i < indices; i++) { | 170 | for (i = 0; i < indices; i++) { |
146 | snd_iprintf(buffer, " ["); | 171 | snd_iprintf(buffer, " ["); |
@@ -757,12 +782,10 @@ static void print_codec_info(struct snd_info_entry *entry, | |||
757 | (codec->single_adc_amp && | 782 | (codec->single_adc_amp && |
758 | wid_type == AC_WID_AUD_IN)) | 783 | wid_type == AC_WID_AUD_IN)) |
759 | print_amp_vals(buffer, codec, nid, HDA_INPUT, | 784 | print_amp_vals(buffer, codec, nid, HDA_INPUT, |
760 | wid_caps & AC_WCAP_STEREO, | 785 | wid_caps, 1); |
761 | 1); | ||
762 | else | 786 | else |
763 | print_amp_vals(buffer, codec, nid, HDA_INPUT, | 787 | print_amp_vals(buffer, codec, nid, HDA_INPUT, |
764 | wid_caps & AC_WCAP_STEREO, | 788 | wid_caps, conn_len); |
765 | conn_len); | ||
766 | } | 789 | } |
767 | if (wid_caps & AC_WCAP_OUT_AMP) { | 790 | if (wid_caps & AC_WCAP_OUT_AMP) { |
768 | snd_iprintf(buffer, " Amp-Out caps: "); | 791 | snd_iprintf(buffer, " Amp-Out caps: "); |
@@ -771,11 +794,10 @@ static void print_codec_info(struct snd_info_entry *entry, | |||
771 | if (wid_type == AC_WID_PIN && | 794 | if (wid_type == AC_WID_PIN && |
772 | codec->pin_amp_workaround) | 795 | codec->pin_amp_workaround) |
773 | print_amp_vals(buffer, codec, nid, HDA_OUTPUT, | 796 | print_amp_vals(buffer, codec, nid, HDA_OUTPUT, |
774 | wid_caps & AC_WCAP_STEREO, | 797 | wid_caps, conn_len); |
775 | conn_len); | ||
776 | else | 798 | else |
777 | print_amp_vals(buffer, codec, nid, HDA_OUTPUT, | 799 | print_amp_vals(buffer, codec, nid, HDA_OUTPUT, |
778 | wid_caps & AC_WCAP_STEREO, 1); | 800 | wid_caps, 1); |
779 | } | 801 | } |
780 | 802 | ||
781 | switch (wid_type) { | 803 | switch (wid_type) { |
diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c index 1589c9bcce3e..dd2b3d92071f 100644 --- a/sound/pci/hda/patch_cirrus.c +++ b/sound/pci/hda/patch_cirrus.c | |||
@@ -393,6 +393,7 @@ static const struct snd_pci_quirk cs420x_fixup_tbl[] = { | |||
393 | SND_PCI_QUIRK(0x106b, 0x1c00, "MacBookPro 8,1", CS420X_MBP81), | 393 | SND_PCI_QUIRK(0x106b, 0x1c00, "MacBookPro 8,1", CS420X_MBP81), |
394 | SND_PCI_QUIRK(0x106b, 0x2000, "iMac 12,2", CS420X_IMAC27_122), | 394 | SND_PCI_QUIRK(0x106b, 0x2000, "iMac 12,2", CS420X_IMAC27_122), |
395 | SND_PCI_QUIRK(0x106b, 0x2800, "MacBookPro 10,1", CS420X_MBP101), | 395 | SND_PCI_QUIRK(0x106b, 0x2800, "MacBookPro 10,1", CS420X_MBP101), |
396 | SND_PCI_QUIRK(0x106b, 0x5600, "MacBookAir 5,2", CS420X_MBP81), | ||
396 | SND_PCI_QUIRK(0x106b, 0x5b00, "MacBookAir 4,2", CS420X_MBA42), | 397 | SND_PCI_QUIRK(0x106b, 0x5b00, "MacBookAir 4,2", CS420X_MBA42), |
397 | SND_PCI_QUIRK_VENDOR(0x106b, "Apple", CS420X_APPLE), | 398 | SND_PCI_QUIRK_VENDOR(0x106b, "Apple", CS420X_APPLE), |
398 | {} /* terminator */ | 399 | {} /* terminator */ |
@@ -584,6 +585,7 @@ static int patch_cs420x(struct hda_codec *codec) | |||
584 | return -ENOMEM; | 585 | return -ENOMEM; |
585 | 586 | ||
586 | spec->gen.automute_hook = cs_automute; | 587 | spec->gen.automute_hook = cs_automute; |
588 | codec->single_adc_amp = 1; | ||
587 | 589 | ||
588 | snd_hda_pick_fixup(codec, cs420x_models, cs420x_fixup_tbl, | 590 | snd_hda_pick_fixup(codec, cs420x_models, cs420x_fixup_tbl, |
589 | cs420x_fixups); | 591 | cs420x_fixups); |
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index fd3ed18670e9..da67ea8645a6 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c | |||
@@ -223,6 +223,7 @@ enum { | |||
223 | CXT_PINCFG_LENOVO_TP410, | 223 | CXT_PINCFG_LENOVO_TP410, |
224 | CXT_PINCFG_LEMOTE_A1004, | 224 | CXT_PINCFG_LEMOTE_A1004, |
225 | CXT_PINCFG_LEMOTE_A1205, | 225 | CXT_PINCFG_LEMOTE_A1205, |
226 | CXT_PINCFG_COMPAQ_CQ60, | ||
226 | CXT_FIXUP_STEREO_DMIC, | 227 | CXT_FIXUP_STEREO_DMIC, |
227 | CXT_FIXUP_INC_MIC_BOOST, | 228 | CXT_FIXUP_INC_MIC_BOOST, |
228 | CXT_FIXUP_HEADPHONE_MIC_PIN, | 229 | CXT_FIXUP_HEADPHONE_MIC_PIN, |
@@ -660,6 +661,15 @@ static const struct hda_fixup cxt_fixups[] = { | |||
660 | .type = HDA_FIXUP_PINS, | 661 | .type = HDA_FIXUP_PINS, |
661 | .v.pins = cxt_pincfg_lemote, | 662 | .v.pins = cxt_pincfg_lemote, |
662 | }, | 663 | }, |
664 | [CXT_PINCFG_COMPAQ_CQ60] = { | ||
665 | .type = HDA_FIXUP_PINS, | ||
666 | .v.pins = (const struct hda_pintbl[]) { | ||
667 | /* 0x17 was falsely set up as a mic, it should 0x1d */ | ||
668 | { 0x17, 0x400001f0 }, | ||
669 | { 0x1d, 0x97a70120 }, | ||
670 | { } | ||
671 | } | ||
672 | }, | ||
663 | [CXT_FIXUP_STEREO_DMIC] = { | 673 | [CXT_FIXUP_STEREO_DMIC] = { |
664 | .type = HDA_FIXUP_FUNC, | 674 | .type = HDA_FIXUP_FUNC, |
665 | .v.func = cxt_fixup_stereo_dmic, | 675 | .v.func = cxt_fixup_stereo_dmic, |
@@ -769,6 +779,7 @@ static const struct hda_model_fixup cxt5047_fixup_models[] = { | |||
769 | }; | 779 | }; |
770 | 780 | ||
771 | static const struct snd_pci_quirk cxt5051_fixups[] = { | 781 | static const struct snd_pci_quirk cxt5051_fixups[] = { |
782 | SND_PCI_QUIRK(0x103c, 0x360b, "Compaq CQ60", CXT_PINCFG_COMPAQ_CQ60), | ||
772 | SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo X200", CXT_PINCFG_LENOVO_X200), | 783 | SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo X200", CXT_PINCFG_LENOVO_X200), |
773 | {} | 784 | {} |
774 | }; | 785 | }; |