Received: by 10.192.165.148 with SMTP id m20csp3776587imm; Mon, 7 May 2018 19:36:27 -0700 (PDT) X-Google-Smtp-Source: AB8JxZoTvkFnzA7oErosHKhMF1qOZtiHlc91JDB5Saz24THKgxquG1+eqeG5T9ZOn9HqFMg3Cl8R X-Received: by 2002:a63:7e58:: with SMTP id o24-v6mr32072696pgn.325.1525746987110; Mon, 07 May 2018 19:36:27 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1525746987; cv=none; d=google.com; s=arc-20160816; b=Rz+3gS5NdGVa/fcRUNPyNSFHYxeosiZZce9FmxDJgTP+bAmx3PMLbQY0bNhJ0BekTL mdwAgTv9JreD2/d9EAh3Y3mIpC7J37ElUYenYYqZ4TZygfDrm/bMGf7luZoqC89DAIL8 C9PlhwM/wtwfSi0ptDNMZdpk5UvQ4gzkjaV0sqsDE9nNAc0kD41HBsqzxxgxhr90sHLH 24OegGUeSdYy8W0OyGNv5+OjWFxO/WfSelTp1kaDTN++EQyRlAFT2AddPi6lIT7Yi8QR KbFDxpkBon9KDEZmfkMB9iIwI0n35lUVFk+qvgQbFydjEfCIO8GftdY0urxZ5mVgs3QY LH2g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:to:references:in-reply-to:message-id:date :subject:cc:from:dkim-signature:arc-authentication-results; bh=pYtcXV0rG7XIh1Bd08Nby7uouLOXX7XHggaaYEJg7ME=; b=MY8ZLYEIw6oiB2ApoN5hjNFQ7O55vhH0Urn89WoFc3VrMzeVXrW6hDQSSYf/X5hyBz TNiZpdzXwUclytRmqPrqJI2SLwkHWzegVvXtl6tPz/FhULHBdQ7ZJbOLNDI2vt0BowHI ptayJ0cG11oQhujPB3gigq5TBzIJihX6V3vAaq5IbCLit2I4CfA+uLNZCRGg568Rozua YHgDqFK9p5T35613zrklk9rY4rI0PXHek8nwdAiQcOOGxxtymCXwjqMs3ZoaN7rQoQGT 97hUl4hnyUJDwwFk3TL74ZUbRrpSrjWV6NPAkYQVxLcRoyXqkcwok/bC4eXD4jltIk79 ldBA== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@gmail.com header.s=20161025 header.b=s0JD88Ey; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 1-v6si22621545plp.532.2018.05.07.19.36.12; Mon, 07 May 2018 19:36:27 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=fail header.i=@gmail.com header.s=20161025 header.b=s0JD88Ey; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753963AbeEHCfT (ORCPT + 99 others); Mon, 7 May 2018 22:35:19 -0400 Received: from mail-io0-f193.google.com ([209.85.223.193]:41618 "EHLO mail-io0-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753971AbeEHCcL (ORCPT ); Mon, 7 May 2018 22:32:11 -0400 Received: by mail-io0-f193.google.com with SMTP id e12-v6so36616158iob.8 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=Q63v4Oabi+JwaF1F+V6zAKfgMilLdamDytMI1SmZAr8XBZvqi1f/R8vM1xXSVFDCQa qOW3Y0cBiUFGJ1BBSKO1JtAFsHw0e+KHn822d0tbKqzjc7k5C3cuPX+AEIPmtAL9m0Zf RQN3PDj+au2dogjHvkbXildHj9IzEp7c+IJN0eBxHcOw6rPSgW6Yxu/Iwv60UtB7S6cB D1ZMtQP4WpIDQriDOsEvQSxqGwc8Xg3c2DHv5HQM4mEtw/HD6j7zAWDKHZhpxzlZ5PHD 75CNNYOUYgP48h2HP7fAP9/F7HYPkqO18nT6+Wa/hBHsRVcXqLg3CzpEg/c+40JhI2PS AFYQ== X-Gm-Message-State: ALQs6tDvae8PYHFuPX1apiOlAuUlAxZqtHHa/QreCmq8B+GVWzmFo+5X r9Yuj98QO/WNV3PpRkQ9Sy4= 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 Cc: o-takashi@sakamocchi.jp, Connor McAdams , Jaroslav Kysela , Takashi Iwai , =?UTF-8?q?J=C3=A9r=C3=A9my=20Lefaure?= , alsa-devel@alsa-project.org, linux-kernel@vger.kernel.org Subject: [PATCH v4 04/13] ALSA: hda/ca0132: Add extra exit functions for R3Di and SBZ 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> To: unlisted-recipients:; (no To-header on input) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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) -- 2.7.4