diff options
-rw-r--r-- | sound/pci/hda/hda_codec.c | 8 | ||||
-rw-r--r-- | sound/pci/hda/hda_codec.h | 3 | ||||
-rw-r--r-- | sound/pci/hda/patch_conexant.c | 22 |
3 files changed, 30 insertions, 3 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index c2c65f63bf06..0ae6eb20b13b 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c | |||
@@ -1759,7 +1759,11 @@ static void put_vol_mute(struct hda_codec *codec, struct hda_amp_info *info, | |||
1759 | parm = ch ? AC_AMP_SET_RIGHT : AC_AMP_SET_LEFT; | 1759 | parm = ch ? AC_AMP_SET_RIGHT : AC_AMP_SET_LEFT; |
1760 | parm |= direction == HDA_OUTPUT ? AC_AMP_SET_OUTPUT : AC_AMP_SET_INPUT; | 1760 | parm |= direction == HDA_OUTPUT ? AC_AMP_SET_OUTPUT : AC_AMP_SET_INPUT; |
1761 | parm |= index << AC_AMP_SET_INDEX_SHIFT; | 1761 | parm |= index << AC_AMP_SET_INDEX_SHIFT; |
1762 | parm |= val; | 1762 | if ((val & HDA_AMP_MUTE) && !(info->amp_caps & AC_AMPCAP_MUTE) && |
1763 | (info->amp_caps & AC_AMPCAP_MIN_MUTE)) | ||
1764 | ; /* set the zero value as a fake mute */ | ||
1765 | else | ||
1766 | parm |= val; | ||
1763 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, parm); | 1767 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, parm); |
1764 | info->vol[ch] = val; | 1768 | info->vol[ch] = val; |
1765 | } | 1769 | } |
@@ -2026,7 +2030,7 @@ int snd_hda_mixer_amp_tlv(struct snd_kcontrol *kcontrol, int op_flag, | |||
2026 | val1 = -((caps & AC_AMPCAP_OFFSET) >> AC_AMPCAP_OFFSET_SHIFT); | 2030 | val1 = -((caps & AC_AMPCAP_OFFSET) >> AC_AMPCAP_OFFSET_SHIFT); |
2027 | val1 += ofs; | 2031 | val1 += ofs; |
2028 | val1 = ((int)val1) * ((int)val2); | 2032 | val1 = ((int)val1) * ((int)val2); |
2029 | if (min_mute) | 2033 | if (min_mute || (caps & AC_AMPCAP_MIN_MUTE)) |
2030 | val2 |= TLV_DB_SCALE_MUTE; | 2034 | val2 |= TLV_DB_SCALE_MUTE; |
2031 | if (put_user(SNDRV_CTL_TLVT_DB_SCALE, _tlv)) | 2035 | if (put_user(SNDRV_CTL_TLVT_DB_SCALE, _tlv)) |
2032 | return -EFAULT; | 2036 | return -EFAULT; |
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index e9f71dc0d464..f0f1943a4b2c 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h | |||
@@ -298,6 +298,9 @@ enum { | |||
298 | #define AC_AMPCAP_MUTE (1<<31) /* mute capable */ | 298 | #define AC_AMPCAP_MUTE (1<<31) /* mute capable */ |
299 | #define AC_AMPCAP_MUTE_SHIFT 31 | 299 | #define AC_AMPCAP_MUTE_SHIFT 31 |
300 | 300 | ||
301 | /* driver-specific amp-caps: using bits 24-30 */ | ||
302 | #define AC_AMPCAP_MIN_MUTE (1 << 30) /* min-volume = mute */ | ||
303 | |||
301 | /* Connection list */ | 304 | /* Connection list */ |
302 | #define AC_CLIST_LENGTH (0x7f<<0) | 305 | #define AC_CLIST_LENGTH (0x7f<<0) |
303 | #define AC_CLIST_LONG (1<<7) | 306 | #define AC_CLIST_LONG (1<<7) |
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index a7a5733aa4d2..ca117cf5132f 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c | |||
@@ -4079,7 +4079,8 @@ static int cx_auto_add_volume_idx(struct hda_codec *codec, const char *basename, | |||
4079 | err = snd_hda_ctl_add(codec, nid, kctl); | 4079 | err = snd_hda_ctl_add(codec, nid, kctl); |
4080 | if (err < 0) | 4080 | if (err < 0) |
4081 | return err; | 4081 | return err; |
4082 | if (!(query_amp_caps(codec, nid, hda_dir) & AC_AMPCAP_MUTE)) | 4082 | if (!(query_amp_caps(codec, nid, hda_dir) & |
4083 | (AC_AMPCAP_MUTE | AC_AMPCAP_MIN_MUTE))) | ||
4083 | break; | 4084 | break; |
4084 | } | 4085 | } |
4085 | return 0; | 4086 | return 0; |
@@ -4379,6 +4380,22 @@ static const struct snd_pci_quirk cxt_fixups[] = { | |||
4379 | {} | 4380 | {} |
4380 | }; | 4381 | }; |
4381 | 4382 | ||
4383 | /* add "fake" mute amp-caps to DACs on cx5051 so that mixer mute switches | ||
4384 | * can be created (bko#42825) | ||
4385 | */ | ||
4386 | static void add_cx5051_fake_mutes(struct hda_codec *codec) | ||
4387 | { | ||
4388 | static hda_nid_t out_nids[] = { | ||
4389 | 0x10, 0x11, 0 | ||
4390 | }; | ||
4391 | hda_nid_t *p; | ||
4392 | |||
4393 | for (p = out_nids; *p; p++) | ||
4394 | snd_hda_override_amp_caps(codec, *p, HDA_OUTPUT, | ||
4395 | AC_AMPCAP_MIN_MUTE | | ||
4396 | query_amp_caps(codec, *p, HDA_OUTPUT)); | ||
4397 | } | ||
4398 | |||
4382 | static int patch_conexant_auto(struct hda_codec *codec) | 4399 | static int patch_conexant_auto(struct hda_codec *codec) |
4383 | { | 4400 | { |
4384 | struct conexant_spec *spec; | 4401 | struct conexant_spec *spec; |
@@ -4397,6 +4414,9 @@ static int patch_conexant_auto(struct hda_codec *codec) | |||
4397 | case 0x14f15045: | 4414 | case 0x14f15045: |
4398 | spec->single_adc_amp = 1; | 4415 | spec->single_adc_amp = 1; |
4399 | break; | 4416 | break; |
4417 | case 0x14f15051: | ||
4418 | add_cx5051_fake_mutes(codec); | ||
4419 | break; | ||
4400 | } | 4420 | } |
4401 | 4421 | ||
4402 | apply_pin_fixup(codec, cxt_fixups, cxt_pincfg_tbl); | 4422 | apply_pin_fixup(codec, cxt_fixups, cxt_pincfg_tbl); |