From patchwork Mon Dec 16 08:25:39 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hui Wang X-Patchwork-Id: 301532 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) by ozlabs.org (Postfix) with ESMTP id A98F52C00A2 for ; Mon, 16 Dec 2013 19:26:35 +1100 (EST) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.76) (envelope-from ) id 1VsTVW-0001Zt-Hb; Mon, 16 Dec 2013 08:26:30 +0000 Received: from mail-pb0-f53.google.com ([209.85.160.53]) by huckleberry.canonical.com with esmtp (Exim 4.76) (envelope-from ) id 1VsTVF-0001VF-28 for kernel-team@lists.ubuntu.com; Mon, 16 Dec 2013 08:26:13 +0000 Received: by mail-pb0-f53.google.com with SMTP id ma3so5171263pbc.12 for ; Mon, 16 Dec 2013 00:26:12 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=GaFHqKjOHMydgAgOhk8AKQFg2jO9QgDFoHT9lVx6STg=; b=UXSmKulEvWq1IVPKZaEJP491M7J9W1mryUrgtzSI7ukKrJ35rfejZVl/gKZssuCMoV KhuD0YpVLGex2lv+iwRxrbpfDDGEEccpELnG0yxlcOSdx/PG92V9D1qE5LE+nlSXKYCX 5p7V0A2ewH6lzWf4ZjGAL3xsK5GgqiefVTeDI3WG0WnPyrQCxIdEna5/tIlEVDAhSUgw PJK7NRmNaCSFlMkOK4Y8GDYQKKHr/8hEbDg8xB8rPNtlF1ERA/5ZEnfV48nDQhaYzEEz cPhY5BNcIF8xZN7RbPbcEZByePUWllLt4Xw/hsdEWSLLEavWb4h8af8dY96TyQy7FV1p RuSw== X-Gm-Message-State: ALoCoQnPTC/a6IFhuzevT01nGWWl8gy0Q9LYIpYhOKx3EVQHG/7hAR0QPOm3/9F9yVeQeaUQSeih X-Received: by 10.66.197.164 with SMTP id iv4mr18951512pac.18.1387182372142; Mon, 16 Dec 2013 00:26:12 -0800 (PST) Received: from localhost.localdomain ([116.213.97.190]) by mx.google.com with ESMTPSA id xs1sm33421390pac.7.2013.12.16.00.26.10 for (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Mon, 16 Dec 2013 00:26:11 -0800 (PST) From: Hui Wang To: kernel-team@lists.ubuntu.com Subject: [Saucy PATCH 4/8] ALSA: hda - add connection to thinkpad_acpi to control mute/micmute LEDs Date: Mon, 16 Dec 2013 16:25:39 +0800 Message-Id: <1387182343-17346-4-git-send-email-hui.wang@canonical.com> X-Mailer: git-send-email 1.8.1.2 In-Reply-To: <1387182343-17346-1-git-send-email-hui.wang@canonical.com> References: <1387182343-17346-1-git-send-email-hui.wang@canonical.com> X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.14 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: kernel-team-bounces@lists.ubuntu.com From: David Henningsson BugLink: https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1261296 Signed-off-by: David Henningsson Signed-off-by: Takashi Iwai (cherry-picked from commit 08cf680ccafd5df9885fbcd0cab85221df00b44b) --- sound/pci/hda/patch_conexant.c | 92 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 90 insertions(+), 2 deletions(-) diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index ac7697e..811085c 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -3203,11 +3203,17 @@ static int cx_auto_init(struct hda_codec *codec) return 0; } +static void cx_auto_free(struct hda_codec *codec) +{ + snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_FREE); + snd_hda_gen_free(codec); +} + static const struct hda_codec_ops cx_auto_patch_ops = { .build_controls = cx_auto_build_controls, .build_pcms = snd_hda_gen_build_pcms, .init = cx_auto_init, - .free = snd_hda_gen_free, + .free = cx_auto_free, .unsol_event = snd_hda_jack_unsol_event, #ifdef CONFIG_PM .check_power_status = snd_hda_gen_check_power_status, @@ -3225,8 +3231,84 @@ enum { CXT_FIXUP_STEREO_DMIC, CXT_FIXUP_INC_MIC_BOOST, CXT_FIXUP_GPIO1, + CXT_FIXUP_THINKPAD_ACPI, }; +#if IS_ENABLED(CONFIG_THINKPAD_ACPI) + +#include + +static int (*led_set_func)(int, bool); + +static void update_tpacpi_mute_led(void *private_data, int enabled) +{ + struct hda_codec *codec = private_data; + struct conexant_spec *spec = codec->spec; + + if (spec->dynamic_eapd) + cx_auto_vmaster_hook(private_data, enabled); + + if (led_set_func) + led_set_func(TPACPI_LED_MUTE, !enabled); +} + +static void update_tpacpi_micmute_led(struct hda_codec *codec, + struct snd_ctl_elem_value *ucontrol) +{ + if (!ucontrol || !led_set_func) + return; + if (strcmp("Capture Switch", ucontrol->id.name) == 0 && ucontrol->id.index == 0) { + /* TODO: How do I verify if it's a mono or stereo here? */ + bool val = ucontrol->value.integer.value[0] || ucontrol->value.integer.value[1]; + led_set_func(TPACPI_LED_MICMUTE, !val); + } +} + +static void cxt_fixup_thinkpad_acpi(struct hda_codec *codec, + const struct hda_fixup *fix, int action) +{ + struct conexant_spec *spec = codec->spec; + + bool removefunc = false; + + if (action == HDA_FIXUP_ACT_PROBE) { + if (!led_set_func) + led_set_func = symbol_request(tpacpi_led_set); + if (!led_set_func) { + snd_printk(KERN_WARNING "Failed to find thinkpad-acpi symbol tpacpi_led_set\n"); + return; + } + + removefunc = true; + if (led_set_func(TPACPI_LED_MUTE, false) >= 0) { + spec->gen.vmaster_mute.hook = update_tpacpi_mute_led; + removefunc = false; + } + if (led_set_func(TPACPI_LED_MICMUTE, false) >= 0) { + if (spec->gen.num_adc_nids > 1) + snd_printdd("Skipping micmute LED control due to several ADCs"); + else { + spec->gen.cap_sync_hook = update_tpacpi_micmute_led; + removefunc = false; + } + } + } + + if (led_set_func && (action == HDA_FIXUP_ACT_FREE || removefunc)) { + symbol_put(tpacpi_led_set); + led_set_func = NULL; + } +} + +#else + +static void cxt_fixup_thinkpad_acpi(struct hda_codec *codec, + const struct hda_fixup *fix, int action) +{ +} + +#endif + static void cxt_fixup_stereo_dmic(struct hda_codec *codec, const struct hda_fixup *fix, int action) { @@ -3284,6 +3366,8 @@ static const struct hda_fixup cxt_fixups[] = { [CXT_PINCFG_LENOVO_TP410] = { .type = HDA_FIXUP_PINS, .v.pins = cxt_pincfg_lenovo_tp410, + .chained = true, + .chain_id = CXT_FIXUP_THINKPAD_ACPI, }, [CXT_PINCFG_LEMOTE_A1004] = { .type = HDA_FIXUP_PINS, @@ -3312,6 +3396,10 @@ static const struct hda_fixup cxt_fixups[] = { { } }, }, + [CXT_FIXUP_THINKPAD_ACPI] = { + .type = HDA_FIXUP_FUNC, + .v.func = cxt_fixup_thinkpad_acpi, + }, }; static const struct snd_pci_quirk cxt5051_fixups[] = { @@ -3430,7 +3518,7 @@ static int patch_conexant_auto(struct hda_codec *codec) return 0; error: - snd_hda_gen_free(codec); + cx_auto_free(codec); return err; }