diff options
Diffstat (limited to 'sound/pci/hda')
-rw-r--r-- | sound/pci/hda/hda_codec.c | 3 | ||||
-rw-r--r-- | sound/pci/hda/hda_local.h | 14 | ||||
-rw-r--r-- | sound/pci/hda/patch_sigmatel.c | 6 |
3 files changed, 17 insertions, 6 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 053f827d2c2c..8c933c8006f4 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c | |||
@@ -1831,6 +1831,7 @@ int snd_hda_mixer_amp_tlv(struct snd_kcontrol *kcontrol, int op_flag, | |||
1831 | hda_nid_t nid = get_amp_nid(kcontrol); | 1831 | hda_nid_t nid = get_amp_nid(kcontrol); |
1832 | int dir = get_amp_direction(kcontrol); | 1832 | int dir = get_amp_direction(kcontrol); |
1833 | unsigned int ofs = get_amp_offset(kcontrol); | 1833 | unsigned int ofs = get_amp_offset(kcontrol); |
1834 | bool min_mute = get_amp_min_mute(kcontrol); | ||
1834 | u32 caps, val1, val2; | 1835 | u32 caps, val1, val2; |
1835 | 1836 | ||
1836 | if (size < 4 * sizeof(unsigned int)) | 1837 | if (size < 4 * sizeof(unsigned int)) |
@@ -1841,6 +1842,8 @@ int snd_hda_mixer_amp_tlv(struct snd_kcontrol *kcontrol, int op_flag, | |||
1841 | val1 = -((caps & AC_AMPCAP_OFFSET) >> AC_AMPCAP_OFFSET_SHIFT); | 1842 | val1 = -((caps & AC_AMPCAP_OFFSET) >> AC_AMPCAP_OFFSET_SHIFT); |
1842 | val1 += ofs; | 1843 | val1 += ofs; |
1843 | val1 = ((int)val1) * ((int)val2); | 1844 | val1 = ((int)val1) * ((int)val2); |
1845 | if (min_mute) | ||
1846 | val2 |= 0x10000; | ||
1844 | if (put_user(SNDRV_CTL_TLVT_DB_SCALE, _tlv)) | 1847 | if (put_user(SNDRV_CTL_TLVT_DB_SCALE, _tlv)) |
1845 | return -EFAULT; | 1848 | return -EFAULT; |
1846 | if (put_user(2 * sizeof(unsigned int), _tlv + 1)) | 1849 | if (put_user(2 * sizeof(unsigned int), _tlv + 1)) |
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h index d7dfa547e2d8..46bbefe2e4a9 100644 --- a/sound/pci/hda/hda_local.h +++ b/sound/pci/hda/hda_local.h | |||
@@ -38,10 +38,11 @@ | |||
38 | */ | 38 | */ |
39 | #define HDA_COMPOSE_AMP_VAL_OFS(nid,chs,idx,dir,ofs) \ | 39 | #define HDA_COMPOSE_AMP_VAL_OFS(nid,chs,idx,dir,ofs) \ |
40 | ((nid) | ((chs)<<16) | ((dir)<<18) | ((idx)<<19) | ((ofs)<<23)) | 40 | ((nid) | ((chs)<<16) | ((dir)<<18) | ((idx)<<19) | ((ofs)<<23)) |
41 | #define HDA_AMP_VAL_MIN_MUTE (1<<29) | ||
41 | #define HDA_COMPOSE_AMP_VAL(nid,chs,idx,dir) \ | 42 | #define HDA_COMPOSE_AMP_VAL(nid,chs,idx,dir) \ |
42 | HDA_COMPOSE_AMP_VAL_OFS(nid, chs, idx, dir, 0) | 43 | HDA_COMPOSE_AMP_VAL_OFS(nid, chs, idx, dir, 0) |
43 | /* mono volume with index (index=0,1,...) (channel=1,2) */ | 44 | /* mono volume with index (index=0,1,...) (channel=1,2) */ |
44 | #define HDA_CODEC_VOLUME_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \ | 45 | #define HDA_CODEC_VOLUME_MONO_IDX(xname, xcidx, nid, channel, xindex, dir, flags) \ |
45 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \ | 46 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \ |
46 | .subdevice = HDA_SUBDEV_AMP_FLAG, \ | 47 | .subdevice = HDA_SUBDEV_AMP_FLAG, \ |
47 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \ | 48 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \ |
@@ -51,16 +52,20 @@ | |||
51 | .get = snd_hda_mixer_amp_volume_get, \ | 52 | .get = snd_hda_mixer_amp_volume_get, \ |
52 | .put = snd_hda_mixer_amp_volume_put, \ | 53 | .put = snd_hda_mixer_amp_volume_put, \ |
53 | .tlv = { .c = snd_hda_mixer_amp_tlv }, \ | 54 | .tlv = { .c = snd_hda_mixer_amp_tlv }, \ |
54 | .private_value = HDA_COMPOSE_AMP_VAL(nid, channel, xindex, direction) } | 55 | .private_value = HDA_COMPOSE_AMP_VAL(nid, channel, xindex, dir) | flags } |
55 | /* stereo volume with index */ | 56 | /* stereo volume with index */ |
56 | #define HDA_CODEC_VOLUME_IDX(xname, xcidx, nid, xindex, direction) \ | 57 | #define HDA_CODEC_VOLUME_IDX(xname, xcidx, nid, xindex, direction) \ |
57 | HDA_CODEC_VOLUME_MONO_IDX(xname, xcidx, nid, 3, xindex, direction) | 58 | HDA_CODEC_VOLUME_MONO_IDX(xname, xcidx, nid, 3, xindex, direction, 0) |
58 | /* mono volume */ | 59 | /* mono volume */ |
59 | #define HDA_CODEC_VOLUME_MONO(xname, nid, channel, xindex, direction) \ | 60 | #define HDA_CODEC_VOLUME_MONO(xname, nid, channel, xindex, direction) \ |
60 | HDA_CODEC_VOLUME_MONO_IDX(xname, 0, nid, channel, xindex, direction) | 61 | HDA_CODEC_VOLUME_MONO_IDX(xname, 0, nid, channel, xindex, direction, 0) |
61 | /* stereo volume */ | 62 | /* stereo volume */ |
62 | #define HDA_CODEC_VOLUME(xname, nid, xindex, direction) \ | 63 | #define HDA_CODEC_VOLUME(xname, nid, xindex, direction) \ |
63 | HDA_CODEC_VOLUME_MONO(xname, nid, 3, xindex, direction) | 64 | HDA_CODEC_VOLUME_MONO(xname, nid, 3, xindex, direction) |
65 | /* stereo volume with min=mute */ | ||
66 | #define HDA_CODEC_VOLUME_MIN_MUTE(xname, nid, xindex, direction) \ | ||
67 | HDA_CODEC_VOLUME_MONO_IDX(xname, 0, nid, 3, xindex, direction, \ | ||
68 | HDA_AMP_VAL_MIN_MUTE) | ||
64 | /* mono mute switch with index (index=0,1,...) (channel=1,2) */ | 69 | /* mono mute switch with index (index=0,1,...) (channel=1,2) */ |
65 | #define HDA_CODEC_MUTE_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \ | 70 | #define HDA_CODEC_MUTE_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \ |
66 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \ | 71 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \ |
@@ -581,6 +586,7 @@ int snd_hda_check_amp_list_power(struct hda_codec *codec, | |||
581 | #define get_amp_direction(kc) (((kc)->private_value >> 18) & 0x1) | 586 | #define get_amp_direction(kc) (((kc)->private_value >> 18) & 0x1) |
582 | #define get_amp_index(kc) (((kc)->private_value >> 19) & 0xf) | 587 | #define get_amp_index(kc) (((kc)->private_value >> 19) & 0xf) |
583 | #define get_amp_offset(kc) (((kc)->private_value >> 23) & 0x3f) | 588 | #define get_amp_offset(kc) (((kc)->private_value >> 23) & 0x3f) |
589 | #define get_amp_min_mute(kc) (((kc)->private_value >> 29) & 0x1) | ||
584 | 590 | ||
585 | /* | 591 | /* |
586 | * CEA Short Audio Descriptor data | 592 | * CEA Short Audio Descriptor data |
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index d8dfafeab80e..1a563a2fbbec 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c | |||
@@ -992,7 +992,7 @@ static struct hda_verb stac9205_core_init[] = { | |||
992 | } | 992 | } |
993 | 993 | ||
994 | static struct snd_kcontrol_new stac9200_mixer[] = { | 994 | static struct snd_kcontrol_new stac9200_mixer[] = { |
995 | HDA_CODEC_VOLUME("Master Playback Volume", 0xb, 0, HDA_OUTPUT), | 995 | HDA_CODEC_VOLUME_MIN_MUTE("Master Playback Volume", 0xb, 0, HDA_OUTPUT), |
996 | HDA_CODEC_MUTE("Master Playback Switch", 0xb, 0, HDA_OUTPUT), | 996 | HDA_CODEC_MUTE("Master Playback Switch", 0xb, 0, HDA_OUTPUT), |
997 | HDA_CODEC_VOLUME("Capture Volume", 0x0a, 0, HDA_OUTPUT), | 997 | HDA_CODEC_VOLUME("Capture Volume", 0x0a, 0, HDA_OUTPUT), |
998 | HDA_CODEC_MUTE("Capture Switch", 0x0a, 0, HDA_OUTPUT), | 998 | HDA_CODEC_MUTE("Capture Switch", 0x0a, 0, HDA_OUTPUT), |
@@ -1020,7 +1020,7 @@ static struct snd_kcontrol_new stac92hd71bxx_loopback[] = { | |||
1020 | }; | 1020 | }; |
1021 | 1021 | ||
1022 | static struct snd_kcontrol_new stac925x_mixer[] = { | 1022 | static struct snd_kcontrol_new stac925x_mixer[] = { |
1023 | HDA_CODEC_VOLUME("Master Playback Volume", 0x0e, 0, HDA_OUTPUT), | 1023 | HDA_CODEC_VOLUME_MIN_MUTE("Master Playback Volume", 0xe, 0, HDA_OUTPUT), |
1024 | HDA_CODEC_MUTE("Master Playback Switch", 0x0e, 0, HDA_OUTPUT), | 1024 | HDA_CODEC_MUTE("Master Playback Switch", 0x0e, 0, HDA_OUTPUT), |
1025 | { } /* end */ | 1025 | { } /* end */ |
1026 | }; | 1026 | }; |
@@ -1144,6 +1144,8 @@ static int stac92xx_build_controls(struct hda_codec *codec) | |||
1144 | HDA_OUTPUT, vmaster_tlv); | 1144 | HDA_OUTPUT, vmaster_tlv); |
1145 | /* correct volume offset */ | 1145 | /* correct volume offset */ |
1146 | vmaster_tlv[2] += vmaster_tlv[3] * spec->volume_offset; | 1146 | vmaster_tlv[2] += vmaster_tlv[3] * spec->volume_offset; |
1147 | /* minimum value is actually mute */ | ||
1148 | vmaster_tlv[3] |= 0x1000; | ||
1147 | err = snd_hda_add_vmaster(codec, "Master Playback Volume", | 1149 | err = snd_hda_add_vmaster(codec, "Master Playback Volume", |
1148 | vmaster_tlv, slave_vols); | 1150 | vmaster_tlv, slave_vols); |
1149 | if (err < 0) | 1151 | if (err < 0) |