aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/hda')
-rw-r--r--sound/pci/hda/hda_codec.c3
-rw-r--r--sound/pci/hda/hda_local.h14
-rw-r--r--sound/pci/hda/patch_sigmatel.c6
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
994static struct snd_kcontrol_new stac9200_mixer[] = { 994static 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
1022static struct snd_kcontrol_new stac925x_mixer[] = { 1022static 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)