diff options
| -rw-r--r-- | sound/pci/hda/hda_codec.c | 38 | ||||
| -rw-r--r-- | sound/pci/hda/hda_generic.c | 8 | ||||
| -rw-r--r-- | sound/pci/hda/hda_local.h | 7 | ||||
| -rw-r--r-- | sound/pci/hda/patch_analog.c | 21 | ||||
| -rw-r--r-- | sound/pci/hda/patch_conexant.c | 66 | ||||
| -rw-r--r-- | sound/pci/hda/patch_realtek.c | 325 | ||||
| -rw-r--r-- | sound/pci/hda/patch_sigmatel.c | 18 |
7 files changed, 205 insertions, 278 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 1d31da47bc9b..043529308676 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c | |||
| @@ -842,6 +842,19 @@ int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch, | |||
| 842 | return 1; | 842 | return 1; |
| 843 | } | 843 | } |
| 844 | 844 | ||
| 845 | /* | ||
| 846 | * update the AMP stereo with the same mask and value | ||
| 847 | */ | ||
| 848 | int snd_hda_codec_amp_stereo(struct hda_codec *codec, hda_nid_t nid, | ||
| 849 | int direction, int idx, int mask, int val) | ||
| 850 | { | ||
| 851 | int ch, ret = 0; | ||
| 852 | for (ch = 0; ch < 2; ch++) | ||
| 853 | ret |= snd_hda_codec_amp_update(codec, nid, ch, direction, | ||
| 854 | idx, mask, val); | ||
| 855 | return ret; | ||
| 856 | } | ||
| 857 | |||
| 845 | #ifdef CONFIG_PM | 858 | #ifdef CONFIG_PM |
| 846 | /* resume the all amp commands from the cache */ | 859 | /* resume the all amp commands from the cache */ |
| 847 | void snd_hda_codec_resume_amp(struct hda_codec *codec) | 860 | void snd_hda_codec_resume_amp(struct hda_codec *codec) |
| @@ -913,9 +926,11 @@ int snd_hda_mixer_amp_volume_get(struct snd_kcontrol *kcontrol, | |||
| 913 | long *valp = ucontrol->value.integer.value; | 926 | long *valp = ucontrol->value.integer.value; |
| 914 | 927 | ||
| 915 | if (chs & 1) | 928 | if (chs & 1) |
| 916 | *valp++ = snd_hda_codec_amp_read(codec, nid, 0, dir, idx) & 0x7f; | 929 | *valp++ = snd_hda_codec_amp_read(codec, nid, 0, dir, idx) |
| 930 | & HDA_AMP_VOLMASK; | ||
| 917 | if (chs & 2) | 931 | if (chs & 2) |
| 918 | *valp = snd_hda_codec_amp_read(codec, nid, 1, dir, idx) & 0x7f; | 932 | *valp = snd_hda_codec_amp_read(codec, nid, 1, dir, idx) |
| 933 | & HDA_AMP_VOLMASK; | ||
| 919 | return 0; | 934 | return 0; |
| 920 | } | 935 | } |
| 921 | 936 | ||
| @@ -992,10 +1007,10 @@ int snd_hda_mixer_amp_switch_get(struct snd_kcontrol *kcontrol, | |||
| 992 | 1007 | ||
| 993 | if (chs & 1) | 1008 | if (chs & 1) |
| 994 | *valp++ = (snd_hda_codec_amp_read(codec, nid, 0, dir, idx) & | 1009 | *valp++ = (snd_hda_codec_amp_read(codec, nid, 0, dir, idx) & |
| 995 | 0x80) ? 0 : 1; | 1010 | HDA_AMP_MUTE) ? 0 : 1; |
| 996 | if (chs & 2) | 1011 | if (chs & 2) |
| 997 | *valp = (snd_hda_codec_amp_read(codec, nid, 1, dir, idx) & | 1012 | *valp = (snd_hda_codec_amp_read(codec, nid, 1, dir, idx) & |
| 998 | 0x80) ? 0 : 1; | 1013 | HDA_AMP_MUTE) ? 0 : 1; |
| 999 | return 0; | 1014 | return 0; |
| 1000 | } | 1015 | } |
| 1001 | 1016 | ||
| @@ -1012,12 +1027,14 @@ int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol, | |||
| 1012 | 1027 | ||
| 1013 | if (chs & 1) { | 1028 | if (chs & 1) { |
| 1014 | change = snd_hda_codec_amp_update(codec, nid, 0, dir, idx, | 1029 | change = snd_hda_codec_amp_update(codec, nid, 0, dir, idx, |
| 1015 | 0x80, *valp ? 0 : 0x80); | 1030 | HDA_AMP_MUTE, |
| 1031 | *valp ? 0 : HDA_AMP_MUTE); | ||
| 1016 | valp++; | 1032 | valp++; |
| 1017 | } | 1033 | } |
| 1018 | if (chs & 2) | 1034 | if (chs & 2) |
| 1019 | change |= snd_hda_codec_amp_update(codec, nid, 1, dir, idx, | 1035 | change |= snd_hda_codec_amp_update(codec, nid, 1, dir, idx, |
| 1020 | 0x80, *valp ? 0 : 0x80); | 1036 | HDA_AMP_MUTE, |
| 1037 | *valp ? 0 : HDA_AMP_MUTE); | ||
| 1021 | 1038 | ||
| 1022 | return change; | 1039 | return change; |
| 1023 | } | 1040 | } |
| @@ -1318,12 +1335,9 @@ static int snd_hda_spdif_out_switch_put(struct snd_kcontrol *kcontrol, | |||
| 1318 | val & 0xff); | 1335 | val & 0xff); |
| 1319 | /* unmute amp switch (if any) */ | 1336 | /* unmute amp switch (if any) */ |
| 1320 | if ((get_wcaps(codec, nid) & AC_WCAP_OUT_AMP) && | 1337 | if ((get_wcaps(codec, nid) & AC_WCAP_OUT_AMP) && |
| 1321 | (val & AC_DIG1_ENABLE)) { | 1338 | (val & AC_DIG1_ENABLE)) |
| 1322 | snd_hda_codec_amp_update(codec, nid, 0, HDA_OUTPUT, 0, | 1339 | snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, |
| 1323 | 0x80, 0x00); | 1340 | HDA_AMP_MUTE, 0); |
| 1324 | snd_hda_codec_amp_update(codec, nid, 1, HDA_OUTPUT, 0, | ||
| 1325 | 0x80, 0x00); | ||
| 1326 | } | ||
| 1327 | } | 1341 | } |
| 1328 | mutex_unlock(&codec->spdif_mutex); | 1342 | mutex_unlock(&codec->spdif_mutex); |
| 1329 | return change; | 1343 | return change; |
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c index d5f1180115ce..91cd9b9ea5d1 100644 --- a/sound/pci/hda/hda_generic.c +++ b/sound/pci/hda/hda_generic.c | |||
| @@ -218,8 +218,7 @@ static int unmute_output(struct hda_codec *codec, struct hda_gnode *node) | |||
| 218 | ofs = (node->amp_out_caps & AC_AMPCAP_OFFSET) >> AC_AMPCAP_OFFSET_SHIFT; | 218 | ofs = (node->amp_out_caps & AC_AMPCAP_OFFSET) >> AC_AMPCAP_OFFSET_SHIFT; |
| 219 | if (val >= ofs) | 219 | if (val >= ofs) |
| 220 | val -= ofs; | 220 | val -= ofs; |
| 221 | snd_hda_codec_amp_update(codec, node->nid, 0, HDA_OUTPUT, 0, 0xff, val); | 221 | snd_hda_codec_amp_stereo(codec, node->nid, HDA_OUTPUT, 0, 0xff, val); |
| 222 | snd_hda_codec_amp_update(codec, node->nid, 0, HDA_OUTPUT, 1, 0xff, val); | ||
| 223 | return 0; | 222 | return 0; |
| 224 | } | 223 | } |
| 225 | 224 | ||
| @@ -234,10 +233,7 @@ static int unmute_input(struct hda_codec *codec, struct hda_gnode *node, unsigne | |||
| 234 | ofs = (node->amp_in_caps & AC_AMPCAP_OFFSET) >> AC_AMPCAP_OFFSET_SHIFT; | 233 | ofs = (node->amp_in_caps & AC_AMPCAP_OFFSET) >> AC_AMPCAP_OFFSET_SHIFT; |
| 235 | if (val >= ofs) | 234 | if (val >= ofs) |
| 236 | val -= ofs; | 235 | val -= ofs; |
| 237 | snd_hda_codec_amp_update(codec, node->nid, 0, HDA_INPUT, index, | 236 | snd_hda_codec_amp_stereo(codec, node->nid, HDA_INPUT, index, 0xff, val); |
| 238 | 0xff, val); | ||
| 239 | snd_hda_codec_amp_update(codec, node->nid, 1, HDA_INPUT, index, | ||
| 240 | 0xff, val); | ||
| 241 | return 0; | 237 | return 0; |
| 242 | } | 238 | } |
| 243 | 239 | ||
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h index 8dec32cfdf54..35ea0cf37a27 100644 --- a/sound/pci/hda/hda_local.h +++ b/sound/pci/hda/hda_local.h | |||
| @@ -84,10 +84,17 @@ int snd_hda_codec_amp_read(struct hda_codec *codec, hda_nid_t nid, int ch, | |||
| 84 | int direction, int index); | 84 | int direction, int index); |
| 85 | int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch, | 85 | int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch, |
| 86 | int direction, int idx, int mask, int val); | 86 | int direction, int idx, int mask, int val); |
| 87 | int snd_hda_codec_amp_stereo(struct hda_codec *codec, hda_nid_t nid, | ||
| 88 | int dir, int idx, int mask, int val); | ||
| 87 | #ifdef CONFIG_PM | 89 | #ifdef CONFIG_PM |
| 88 | void snd_hda_codec_resume_amp(struct hda_codec *codec); | 90 | void snd_hda_codec_resume_amp(struct hda_codec *codec); |
| 89 | #endif | 91 | #endif |
| 90 | 92 | ||
| 93 | /* amp value bits */ | ||
| 94 | #define HDA_AMP_MUTE 0x80 | ||
| 95 | #define HDA_AMP_UNMUTE 0x00 | ||
| 96 | #define HDA_AMP_VOLMASK 0x7f | ||
| 97 | |||
| 91 | /* mono switch binding multiple inputs */ | 98 | /* mono switch binding multiple inputs */ |
| 92 | #define HDA_BIND_MUTE_MONO(xname, nid, channel, indices, direction) \ | 99 | #define HDA_BIND_MUTE_MONO(xname, nid, channel, indices, direction) \ |
| 93 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ | 100 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ |
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index f20ddd85db22..febc2053f08e 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c | |||
| @@ -1120,10 +1120,9 @@ static int ad1981_hp_master_sw_put(struct snd_kcontrol *kcontrol, | |||
| 1120 | return 0; | 1120 | return 0; |
| 1121 | 1121 | ||
| 1122 | /* toggle HP mute appropriately */ | 1122 | /* toggle HP mute appropriately */ |
| 1123 | snd_hda_codec_amp_update(codec, 0x06, 0, HDA_OUTPUT, 0, | 1123 | snd_hda_codec_amp_stereo(codec, 0x06, HDA_OUTPUT, 0, |
| 1124 | 0x80, spec->cur_eapd ? 0 : 0x80); | 1124 | HDA_AMP_MUTE, |
| 1125 | snd_hda_codec_amp_update(codec, 0x06, 1, HDA_OUTPUT, 0, | 1125 | spec->cur_eapd ? 0 : HDA_AMP_MUTE); |
| 1126 | 0x80, spec->cur_eapd ? 0 : 0x80); | ||
| 1127 | return 1; | 1126 | return 1; |
| 1128 | } | 1127 | } |
| 1129 | 1128 | ||
| @@ -1136,13 +1135,13 @@ static int ad1981_hp_master_vol_put(struct snd_kcontrol *kcontrol, | |||
| 1136 | int change; | 1135 | int change; |
| 1137 | 1136 | ||
| 1138 | change = snd_hda_codec_amp_update(codec, 0x05, 0, HDA_OUTPUT, 0, | 1137 | change = snd_hda_codec_amp_update(codec, 0x05, 0, HDA_OUTPUT, 0, |
| 1139 | 0x7f, valp[0] & 0x7f); | 1138 | HDA_AMP_VOLMASK, valp[0]); |
| 1140 | change |= snd_hda_codec_amp_update(codec, 0x05, 1, HDA_OUTPUT, 0, | 1139 | change |= snd_hda_codec_amp_update(codec, 0x05, 1, HDA_OUTPUT, 0, |
| 1141 | 0x7f, valp[1] & 0x7f); | 1140 | HDA_AMP_VOLMASK, valp[1]); |
| 1142 | snd_hda_codec_amp_update(codec, 0x06, 0, HDA_OUTPUT, 0, | 1141 | snd_hda_codec_amp_update(codec, 0x06, 0, HDA_OUTPUT, 0, |
| 1143 | 0x7f, valp[0] & 0x7f); | 1142 | HDA_AMP_VOLMASK, valp[0]); |
| 1144 | snd_hda_codec_amp_update(codec, 0x06, 1, HDA_OUTPUT, 0, | 1143 | snd_hda_codec_amp_update(codec, 0x06, 1, HDA_OUTPUT, 0, |
| 1145 | 0x7f, valp[1] & 0x7f); | 1144 | HDA_AMP_VOLMASK, valp[1]); |
| 1146 | return change; | 1145 | return change; |
