From patchwork Tue May 8 02:31:12 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Connor McAdams X-Patchwork-Id: 10385133 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 85E8660236 for ; Tue, 8 May 2018 02:32:54 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 72D8927F17 for ; Tue, 8 May 2018 02:32:54 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 674522856D; Tue, 8 May 2018 02:32:54 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.8 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE, T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9065027F17 for ; Tue, 8 May 2018 02:32:53 +0000 (UTC) Received: from alsa0.perex.cz (localhost [127.0.0.1]) by alsa0.perex.cz (Postfix) with ESMTP id A2C9426769E; Tue, 8 May 2018 04:32:20 +0200 (CEST) X-Original-To: alsa-devel@alsa-project.org Delivered-To: alsa-devel@alsa-project.org Received: by alsa0.perex.cz (Postfix, from userid 1000) id 05CA126768F; Tue, 8 May 2018 04:32:16 +0200 (CEST) Received: from mail-io0-f193.google.com (mail-io0-f193.google.com [209.85.223.193]) by alsa0.perex.cz (Postfix) with ESMTP id D03D126767D for ; Tue, 8 May 2018 04:32:11 +0200 (CEST) Received: by mail-io0-f193.google.com with SMTP id c9-v6so30247207iob.12 for ; Mon, 07 May 2018 19:32:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=pYtcXV0rG7XIh1Bd08Nby7uouLOXX7XHggaaYEJg7ME=; b=s0JD88EyhdlYSgiCexh9Y8ef5wCVD7RN4mjK5kYEqhxvKIUnBwt2eAn70AV7muE8gG 3rmpANSK+9UVDAVEENc6PTIDQCvScGptReCDT5aPnm3+6kE0/vDLDHIeJlSdT1Rvm4+i ETuyk5T3JMbKtoDtgASH52mRyJsJFE66/y8F905RjiTaWvA+BsJVEDEQhWg0C0Fwq8OX FLHR9BZtEqXlDG9LHDDNKI/V11QCfhr+dVAKZ+1Z9m+gDBMMoiQVyfLljYWOYZaQrbh9 86NDv58rEsp1o07OmcmYo939qlqxBhqbVyCWbNSgEh+6R7Pf9Ls0dhBSWgPGq7ColLmm V4cg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=pYtcXV0rG7XIh1Bd08Nby7uouLOXX7XHggaaYEJg7ME=; b=RA4A5T3dfXR5fJ6BZYK5DJBgq/5mBV+/vcsstx3O5c6cfm3GtKUx19HfcR4sQoEUWD Vq1rIV3+nQ3WaLWk1ONBLekSji6IfDU2Ii8RpaJeUNK8IjuzXOcD/CwY9G/kh0b/Xx8N 9CXOXtDd/sI5+znPUJBiDc4eX7x7LKGLJY66K3a5jldS74W/SsFeIcNvtszIZbWE8cui TwArsPoxwXWYNQD8iXkRzbBOMha7myaiEx521G8mLbvQI86WAAMD4plbR5J1LeTsFZpg RIXize/Me0RJpmhqgI3z1916jkbvOCIjbcipl7hkIpkR1Qt61pYNs2RXCYepscZZojsg xtjg== X-Gm-Message-State: ALQs6tD2Oh9I8T9o+jn8O2+8AZxPKNgtqublLxTgS/S5pVUivdblyKO3 5DvmSKTLPk+4yaKQPWiruVs= X-Google-Smtp-Source: AB8JxZp+Jywm3/oGMnwUTHWvea32ZGfWhz9LAxc4haInIMBAdNDrHe7qFmxNTje7KqyYhzstv32AUA== X-Received: by 2002:a6b:214a:: with SMTP id h71-v6mr39688088ioh.229.1525746730818; Mon, 07 May 2018 19:32:10 -0700 (PDT) Received: from localhost.localdomain ([2605:a000:1316:4462:d951:8657:56b7:4002]) by smtp.googlemail.com with ESMTPSA id l22-v6sm4947954ita.8.2018.05.07.19.32.09 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 07 May 2018 19:32:10 -0700 (PDT) From: Connor McAdams To: Date: Mon, 7 May 2018 22:31:12 -0400 Message-Id: <1525746683-18535-5-git-send-email-conmanx360@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1525746683-18535-1-git-send-email-conmanx360@gmail.com> References: <1525746683-18535-1-git-send-email-conmanx360@gmail.com> Cc: alsa-devel@alsa-project.org, linux-kernel@vger.kernel.org, Takashi Iwai , =?UTF-8?q?J=C3=A9r=C3=A9my=20Lefaure?= , Connor McAdams , o-takashi@sakamocchi.jp Subject: [alsa-devel] [PATCH v4 04/13] ALSA: hda/ca0132: Add extra exit functions for R3Di and SBZ X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: alsa-devel-bounces@alsa-project.org Sender: alsa-devel-bounces@alsa-project.org X-Virus-Scanned: ClamAV using ClamSMTP This patch adds extra functions for shutdown on the Sound Blaster Z and Recon3Di. The Recon3Di only has one specific functions, which sets the GPIO data pins to 0 to prevent a popping noise. The Sound Blaster Z exit sequence was taken from Windows. Without this exit function, the card will not reload properly unless the PC has been shutdown to clear the onboard memory. There are commented out functions currently in the sbz_exit_chip function that are added in a later patch. Also, a reboot notify function has been added, to make sure these functions are ran before a reboot. This helps when using the card through VFIO in a virtual machine, to make sure the card reloads the DSP properly. Signed-off-by: Connor McAdams --- sound/pci/hda/patch_ca0132.c | 131 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 129 insertions(+), 2 deletions(-) diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c index 78d2c26..5cda7a5 100644 --- a/sound/pci/hda/patch_ca0132.c +++ b/sound/pci/hda/patch_ca0132.c @@ -4641,6 +4641,115 @@ static void ca0132_init_chip(struct hda_codec *codec) #endif } +/* + * Recon3Di exit specific commands. + */ +/* prevents popping noise on shutdown */ +static void r3di_gpio_shutdown(struct hda_codec *codec) +{ + snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0x00); +} + +/* + * Sound Blaster Z exit specific commands. + */ +static void sbz_region2_exit(struct hda_codec *codec) +{ + struct ca0132_spec *spec = codec->spec; + unsigned int i; + + for (i = 0; i < 4; i++) + writeb(0x0, spec->mem_base + 0x100); + for (i = 0; i < 8; i++) + writeb(0xb3, spec->mem_base + 0x304); + /* + * I believe these are GPIO, with the right most hex digit being the + * gpio pin, and the second digit being on or off. We see this more in + * the input/output select functions. + */ + writew(0x0000, spec->mem_base + 0x320); + writew(0x0001, spec->mem_base + 0x320); + writew(0x0104, spec->mem_base + 0x320); + writew(0x0005, spec->mem_base + 0x320); + writew(0x0007, spec->mem_base + 0x320); +} + +static void sbz_set_pin_ctl_default(struct hda_codec *codec) +{ + hda_nid_t pins[5] = {0x0B, 0x0C, 0x0E, 0x12, 0x13}; + unsigned int i; + + snd_hda_codec_write(codec, 0x11, 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40); + + for (i = 0; i < 5; i++) + snd_hda_codec_write(codec, pins[i], 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00); +} + +static void sbz_clear_unsolicited(struct hda_codec *codec) +{ + hda_nid_t pins[7] = {0x0B, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13}; + unsigned int i; + + for (i = 0; i < 7; i++) { + snd_hda_codec_write(codec, pins[i], 0, + AC_VERB_SET_UNSOLICITED_ENABLE, 0x00); + } +} + +/* On shutdown, sends commands in sets of three */ +static void sbz_gpio_shutdown_commands(struct hda_codec *codec, int dir, + int mask, int data) +{ + if (dir >= 0) + snd_hda_codec_write(codec, 0x01, 0, + AC_VERB_SET_GPIO_DIRECTION, dir); + if (mask >= 0) + snd_hda_codec_write(codec, 0x01, 0, + AC_VERB_SET_GPIO_MASK, mask); + + if (data >= 0) + snd_hda_codec_write(codec, 0x01, 0, + AC_VERB_SET_GPIO_DATA, data); +} + +static void sbz_exit_chip(struct hda_codec *codec) +{ + + /* Mess with GPIO */ + sbz_gpio_shutdown_commands(codec, 0x07, 0x07, -1); + sbz_gpio_shutdown_commands(codec, 0x07, 0x07, 0x05); + sbz_gpio_shutdown_commands(codec, 0x07, 0x07, 0x01); + + + chipio_set_conn_rate(codec, 0x41, SR_192_000); + chipio_set_conn_rate(codec, 0x91, SR_192_000); + + chipio_write(codec, 0x18a020, 0x00000083); + + sbz_gpio_shutdown_commands(codec, 0x07, 0x07, 0x03); + sbz_gpio_shutdown_commands(codec, 0x07, 0x07, 0x07); + sbz_gpio_shutdown_commands(codec, 0x07, 0x07, 0x06); + + + chipio_set_control_param(codec, 0x0D, 0x24); + + sbz_clear_unsolicited(codec); + sbz_set_pin_ctl_default(codec); + + snd_hda_codec_write(codec, 0x0B, 0, + AC_VERB_SET_EAPD_BTLENABLE, 0x00); + + if (dspload_is_loaded(codec)) + dsp_reset(codec); + + snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0, + VENDOR_CHIPIO_CT_EXTENSIONS_ENABLE, 0x00); + + sbz_region2_exit(codec); +} + static void ca0132_exit_chip(struct hda_codec *codec) { /* put any chip cleanup stuffs here. */ @@ -4701,8 +4810,20 @@ static void ca0132_free(struct hda_codec *codec) cancel_delayed_work_sync(&spec->unsol_hp_work); snd_hda_power_up(codec); - snd_hda_sequence_write(codec, spec->base_exit_verbs); - ca0132_exit_chip(codec); + switch (spec->quirk) { + case QUIRK_SBZ: + sbz_exit_chip(codec); + break; + case QUIRK_R3DI: + r3di_gpio_shutdown(codec); + snd_hda_sequence_write(codec, spec->base_exit_verbs); + ca0132_exit_chip(codec); + break; + default: + snd_hda_sequence_write(codec, spec->base_exit_verbs); + ca0132_exit_chip(codec); + break; + } snd_hda_power_down(codec); if (spec->mem_base) iounmap(spec->mem_base); @@ -4710,12 +4831,18 @@ static void ca0132_free(struct hda_codec *codec) kfree(codec->spec); } +static void ca0132_reboot_notify(struct hda_codec *codec) +{ + codec->patch_ops.free(codec); +} + static const struct hda_codec_ops ca0132_patch_ops = { .build_controls = ca0132_build_controls, .build_pcms = ca0132_build_pcms, .init = ca0132_init, .free = ca0132_free, .unsol_event = snd_hda_jack_unsol_event, + .reboot_notify = ca0132_reboot_notify, }; static void ca0132_config(struct hda_codec *codec)