* [PATCH] ALSA: hda - Add a fake mute feature
@ 2012-02-29 16:38 Takashi Iwai
2012-03-01 9:27 ` David Henningsson
0 siblings, 1 reply; 2+ messages in thread
From: Takashi Iwai @ 2012-02-29 16:38 UTC (permalink / raw)
To: alsa-devel; +Cc: David Henningsson
David, I thought you have a machine with Cx20561 (such as Lenovo X200,
T400 or W500)? Could you check whether this really doesn't break?
Thanks,
Takashi
===
Some codecs don't supply the mute amp-capabilities although the lowest
volume gives the mute. It'd be handy if the parser provides the mute
mixers in such a case.
This patch adds an extension amp-cap bit (which is used only in the
driver) to represent the min volume = mute state. Also modified the
amp cache code to support the fake mute feature when this bit is set
but the real mute bit is unset.
In addition, conexant cx5051 parser uses this new feature to implement
the missing mute controls.
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=42825
Cc: <stable@kernel.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
sound/pci/hda/hda_codec.c | 8 ++++++--
sound/pci/hda/hda_codec.h | 3 +++
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 c2c65f6..0ae6eb2 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,
parm = ch ? AC_AMP_SET_RIGHT : AC_AMP_SET_LEFT;
parm |= direction == HDA_OUTPUT ? AC_AMP_SET_OUTPUT : AC_AMP_SET_INPUT;
parm |= index << AC_AMP_SET_INDEX_SHIFT;
- parm |= val;
+ if ((val & HDA_AMP_MUTE) && !(info->amp_caps & AC_AMPCAP_MUTE) &&
+ (info->amp_caps & AC_AMPCAP_MIN_MUTE))
+ ; /* set the zero value as a fake mute */
+ else
+ parm |= val;
snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, parm);
info->vol[ch] = val;
}
@@ -2026,7 +2030,7 @@ int snd_hda_mixer_amp_tlv(struct snd_kcontrol *kcontrol, int op_flag,
val1 = -((caps & AC_AMPCAP_OFFSET) >> AC_AMPCAP_OFFSET_SHIFT);
val1 += ofs;
val1 = ((int)val1) * ((int)val2);
- if (min_mute)
+ if (min_mute || (caps & AC_AMPCAP_MIN_MUTE))
val2 |= TLV_DB_SCALE_MUTE;
if (put_user(SNDRV_CTL_TLVT_DB_SCALE, _tlv))
return -EFAULT;
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index e9f71dc..f0f1943 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -298,6 +298,9 @@ enum {
#define AC_AMPCAP_MUTE (1<<31) /* mute capable */
#define AC_AMPCAP_MUTE_SHIFT 31
+/* driver-specific amp-caps: using bits 24-30 */
+#define AC_AMPCAP_MIN_MUTE (1 << 30) /* min-volume = mute */
+
/* Connection list */
#define AC_CLIST_LENGTH (0x7f<<0)
#define AC_CLIST_LONG (1<<7)
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index a7a5733..ca117cf 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,
err = snd_hda_ctl_add(codec, nid, kctl);
if (err < 0)
return err;
- if (!(query_amp_caps(codec, nid, hda_dir) & AC_AMPCAP_MUTE))
+ if (!(query_amp_caps(codec, nid, hda_dir) &
+ (AC_AMPCAP_MUTE | AC_AMPCAP_MIN_MUTE)))
break;
}
return 0;
@@ -4379,6 +4380,22 @@ static const struct snd_pci_quirk cxt_fixups[] = {
{}
};
+/* add "fake" mute amp-caps to DACs on cx5051 so that mixer mute switches
+ * can be created (bko#42825)
+ */
+static void add_cx5051_fake_mutes(struct hda_codec *codec)
+{
+ static hda_nid_t out_nids[] = {
+ 0x10, 0x11, 0
+ };
+ hda_nid_t *p;
+
+ for (p = out_nids; *p; p++)
+ snd_hda_override_amp_caps(codec, *p, HDA_OUTPUT,
+ AC_AMPCAP_MIN_MUTE |
+ query_amp_caps(codec, *p, HDA_OUTPUT));
+}
+
static int patch_conexant_auto(struct hda_codec *codec)
{
struct conexant_spec *spec;
@@ -4397,6 +4414,9 @@ static int patch_conexant_auto(struct hda_codec *codec)
case 0x14f15045:
spec->single_adc_amp = 1;
break;
+ case 0x14f15051:
+ add_cx5051_fake_mutes(codec);
+ break;
}
apply_pin_fixup(codec, cxt_fixups, cxt_pincfg_tbl);
--
1.7.9
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH] ALSA: hda - Add a fake mute feature
2012-02-29 16:38 [PATCH] ALSA: hda - Add a fake mute feature Takashi Iwai
@ 2012-03-01 9:27 ` David Henningsson
0 siblings, 0 replies; 2+ messages in thread
From: David Henningsson @ 2012-03-01 9:27 UTC (permalink / raw)
To: Takashi Iwai; +Cc: alsa-devel
On 02/29/2012 05:38 PM, Takashi Iwai wrote:
> David, I thought you have a machine with Cx20561 (such as Lenovo X200,
> T400 or W500)?
No, sorry. Also, neither of those three appear to be certified by
Canonical, so not sure if they exist within the company.
--
David Henningsson, Canonical Ltd.
http://launchpad.net/~diwic
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2012-03-01 9:27 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-02-29 16:38 [PATCH] ALSA: hda - Add a fake mute feature Takashi Iwai
2012-03-01 9:27 ` David Henningsson
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).