From patchwork Tue Jul 10 19:56:35 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Herton Ronaldo Krzesinski X-Patchwork-Id: 170274 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from chlorine.canonical.com (chlorine.canonical.com [91.189.94.204]) by ozlabs.org (Postfix) with ESMTP id 2EABF2C007F for ; Wed, 11 Jul 2012 06:08:46 +1000 (EST) Received: from localhost ([127.0.0.1] helo=chlorine.canonical.com) by chlorine.canonical.com with esmtp (Exim 4.71) (envelope-from ) id 1SogYq-0007O0-04; Tue, 10 Jul 2012 19:57:28 +0000 Received: from youngberry.canonical.com ([91.189.89.112]) by chlorine.canonical.com with esmtp (Exim 4.71) (envelope-from ) id 1SogYX-0007GW-T6 for kernel-team@lists.ubuntu.com; Tue, 10 Jul 2012 19:57:16 +0000 Received: from 189.114.237.155.dynamic.adsl.gvt.net.br ([189.114.237.155] helo=canonical.com) by youngberry.canonical.com with esmtpsa (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1SogY2-0007cI-TP for kernel-team@lists.ubuntu.com; Tue, 10 Jul 2012 19:56:39 +0000 From: Herton Ronaldo Krzesinski To: kernel-team@lists.ubuntu.com Subject: [Precise/SRU][PATCH] UBUNTU: SAUCE: (drop after 3.2) ALSA: hda - restrict bass configuration on Dell Inspiron 17 Date: Tue, 10 Jul 2012 16:56:35 -0300 Message-Id: <1341950195-15691-1-git-send-email-herton.krzesinski@canonical.com> X-Mailer: git-send-email 1.7.9.5 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.13 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: kernel-team-bounces@lists.ubuntu.com Errors-To: kernel-team-bounces@lists.ubuntu.com The ALC269VB configuration on Dell Inspiron 17 results in mixer volume controls only for the main and "bass"/surround speakers, lacking a separate volume control for headphones, due to the lack of DACs available. Realtek auto config avoids to create an duplicate volume slider for the same nid (DAC), so as headphone and first set of speakers share the same DAC, and the volume control is done on DAC amp, only one volume slider with the name "Speaker Playback Volume" is created. The problem is that on Ubuntu pulse configuration also uses control names to do automute. So when you insert a headphone, it goes there and mutes and lowers volumes of all Speaker controls. As Speaker volume slider also controls the volume on headphones, this ends up also "muting" the headphone output, and you have bug 994685 reported. This change workarounds the issue, forcing the current auto config code in 3.2 kernel to allocate an exclusive DAC for headphones, which allows the creation of separate Headphone and Speaker controls. We do that forcing the headphone pins and speaker pins to "see" only the mixers routing to DACs we want, and after the setup is done we undo the hidden connections. Also we make sure to add a mixer item back to control the second speaker pin, otherwise it is gone with the workaround in place. And as it happens sometimes, where manufactures end up using their same subvendor and subdevice ids for different setups/hardware, we play safe and do some sanity checks first before applying the fixup. BugLink: http://bugs.launchpad.net/bugs/994685 Signed-off-by: Herton Ronaldo Krzesinski Acked-by: Andy Whitcroft --- sound/pci/hda/patch_realtek.c | 72 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 491dc2f..b63f2fc 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -4868,6 +4868,72 @@ static void alc269_fixup_quanta_mute(struct hda_codec *codec, spec->automute_hook = alc269_quanta_automute; } +/* Hide the connection of speakers and headphone pins to specific DACs, + * so we prevent autoconfig to make headphone pin share the same DAC + * with the first set of speakers, which in the end makes the mixer lack + * a headphone volume control (as speaker volume slider controls the DAC + * amp, and the code prevents adding another volume slider to do the + * same thing). This means user space (pulse), depending on + * configuration, can foolish think that it can turn the speaker volume + * down to 0, while in practice it's also turning down the volume for + * headphone pin... http://bugs.launchpad.net/bugs/994685 */ +static void alc269vb_fixup_restrict_bass(struct hda_codec *codec, + const struct alc_fixup *fix, + int action) +{ + unsigned int defcfg, i; + short dev, con; + struct alc_spec *spec = codec->spec; + int spk_nids[] = { 0x14, 0x1a }; + int clear_nids[] = { 0x17, 0x18, 0x1b }; + static const struct snd_kcontrol_new alc269vb_bass_switch[] = { + HDA_CODEC_MUTE("Bass Speaker Playback Switch", 0x1a, 0x0, HDA_OUTPUT), + { } + }; + + /* Do some sanity checks first. If we don't find pins where they + * should be, just do nothing */ + defcfg = snd_hda_codec_get_pincfg(codec, 0x21); + if (get_defcfg_device(defcfg) != AC_JACK_HP_OUT || + get_defcfg_connect(defcfg) == AC_JACK_PORT_NONE) + return; + for (i = 0; i < ARRAY_SIZE(spk_nids); i++) { + defcfg = snd_hda_codec_get_pincfg(codec, spk_nids[i]); + dev = get_defcfg_device(defcfg); + con = get_defcfg_connect(defcfg); + if (dev == AC_JACK_LINE_OUT) { + if (con == AC_JACK_PORT_FIXED) + dev = AC_JACK_SPEAKER; + } + if (dev != AC_JACK_SPEAKER || con == AC_JACK_PORT_NONE) + return; + } + for (i = 0; i < ARRAY_SIZE(clear_nids); i++) { + defcfg = snd_hda_codec_get_pincfg(codec, clear_nids[i]); + dev = get_defcfg_device(defcfg); + con = get_defcfg_connect(defcfg); + if ((dev == AC_JACK_SPEAKER || dev == AC_JACK_LINE_OUT || + dev == AC_JACK_HP_OUT) && con != AC_JACK_PORT_NONE) + return; + } + + if (action == ALC_FIXUP_ACT_PRE_PROBE) { + /* fake the connections during parsing the tree */ + hda_nid_t conn1[1] = { 0x0c }; + hda_nid_t conn2[1] = { 0x0d }; + snd_hda_override_conn_list(codec, 0x14, 1, conn2); + snd_hda_override_conn_list(codec, 0x1a, 1, conn2); + snd_hda_override_conn_list(codec, 0x21, 1, conn1); + } else if (action == ALC_FIXUP_ACT_PROBE) { + /* restore the connections */ + hda_nid_t conn[2] = { 0x0c, 0x0d }; + snd_hda_override_conn_list(codec, 0x14, 2, conn); + snd_hda_override_conn_list(codec, 0x1a, 2, conn); + snd_hda_override_conn_list(codec, 0x21, 2, conn); + add_mixer(spec, alc269vb_bass_switch); + } +} + enum { ALC269_FIXUP_SONY_VAIO, ALC275_FIXUP_SONY_VAIO_GPIO2, @@ -4885,6 +4951,7 @@ enum { ALC269_FIXUP_DMIC, ALC269VB_FIXUP_AMIC, ALC269VB_FIXUP_DMIC, + ALC269VB_FIXUP_RESTRICT_BASS, }; static const struct alc_fixup alc269_fixups[] = { @@ -5005,6 +5072,10 @@ static const struct alc_fixup alc269_fixups[] = { { } }, }, + [ALC269VB_FIXUP_RESTRICT_BASS] = { + .type = ALC_FIXUP_FUNC, + .v.func = alc269vb_fixup_restrict_bass, + }, }; static const struct snd_pci_quirk alc269_fixup_tbl[] = { @@ -5020,6 +5091,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ), SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO), SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z), + SND_PCI_QUIRK(0x1028, 0x04d8, "Dell Inspiron 17", ALC269VB_FIXUP_RESTRICT_BASS), SND_PCI_QUIRK_VENDOR(0x1025, "Acer Aspire", ALC271_FIXUP_DMIC), SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook", ALC269_FIXUP_LIFEBOOK), SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE),