Received: by 10.192.165.148 with SMTP id m20csp322407imm; Thu, 3 May 2018 21:22:45 -0700 (PDT) X-Google-Smtp-Source: AB8JxZqLOMHlb5Ot3wSUvFQALYZz9LGclBKGm1GJucB5D9qJGvK6rnoBK6RT3vAKoLewv46M0JTZ X-Received: by 2002:a17:902:7e05:: with SMTP id b5-v6mr25862622plm.230.1525407765470; Thu, 03 May 2018 21:22:45 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1525407765; cv=none; d=google.com; s=arc-20160816; b=a7YunEFdHBtEiw98D7f4ZLwk0+cgVSSKoIAuNjNL6Qj7J2WLHawx9lNlCPQx9EbFx4 cqwU6x5f7/ynp6oyGLoTBi+rpAaE4zFFRLH4ZRCPuTVZFm7lNZhKJSAdhACRJRu1cXzF 5pkEm5Ydp9bIjS8ac8fghRGNgg+VYDTT6zkDw4Gx/Hw5kIOZj5HN8yEUt6W1jwQBOoRT H28jHUyuXPTGlYQaPMHSxskNqavDcIlqB4hqsZbwbZBS6mjJTstVBVoQlOw4fZHoPyIw XZJKPsGCkvMufPBKpNHKLOFs8U3wq6yebFBy12I3DwCtcMUB/cyydxqDlndNpc9nEssM glFQ== 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=28nsxCBJt8pN0gUe1HwKgAeHlr0Eg8mrMXhI1i1F0x0=; b=qYtxgwdvFZFQF4BkqcPHrqkui3kXaS4XLmcnldQVivaNLsWWnZkp71YVd0ASX6pKjx DY4z4kGNYNeXj7XW9lvQL46606RCJcCL9HhhCFfYYWEGO0YpxxK78tGYmAzCvWR6XeJn yl0p37H7WShvkAJTPrJCRCd78fKipnvRGp4VcWsviBi5BX42K/1z9zaTSmI2ffxN9oUA KtVEQYPBJqX0WWBJEe7LV6QcCh8v//bxVvtrypm4CwWw0yI/3t6mwyE0leTviKOWPuD4 LQu0kx+MY+sn/WI5Y7mBjaDdxWGNmrQn6M8FUoMp2JImg9hkWDOAFxGX+NscCNrkHuui QZ1A== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@gmail.com header.s=20161025 header.b=oSB9RpMh; 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 z19-v6si13314030plo.174.2018.05.03.21.22.31; Thu, 03 May 2018 21:22:45 -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=oSB9RpMh; 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 S1751718AbeEDEVy (ORCPT + 99 others); Fri, 4 May 2018 00:21:54 -0400 Received: from mail-it0-f67.google.com ([209.85.214.67]:52737 "EHLO mail-it0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751324AbeEDEUe (ORCPT ); Fri, 4 May 2018 00:20:34 -0400 Received: by mail-it0-f67.google.com with SMTP id i136-v6so1866874ita.2 for ; Thu, 03 May 2018 21:20:33 -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=28nsxCBJt8pN0gUe1HwKgAeHlr0Eg8mrMXhI1i1F0x0=; b=oSB9RpMhYoWx8E9fx8GwBKsRbYQQ1XJOvIODkZnfJXNgFu6aShJ5kZ7ZlEm5dhezIm /Dcb+3sqdYXAy8zYbfPeU9Fre6h9fwXvhsutdQ0vnga2nn3eRnCf41KtSbFRY0VTn63i E1gosvLcdpzFrULT537esEdPY73kDS8C/9YVbNpy/sSWPyF76tfsTEVMH2cJPgWh9x9a RDJy/msQakI1cFT2dXSJbzJ1oetfr/LC1wcQHPjlU5E8a3xZRcwq3NbnJJfd8SfcGizN FdD8gfwOWMf1oUHH0S0Wy5smnbWPEDoTXTlD70DwuC5CM2pLHAuWpbKsSlusoskDJZTc K9Lg== 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=28nsxCBJt8pN0gUe1HwKgAeHlr0Eg8mrMXhI1i1F0x0=; b=eHhki6rsvlZJJkySpCJqDGWAeNhkuqo0zKx2Czohp+7WiJewRd/NBrJTeLu4S8MlaT mq3fH9COcTwSmmaVFnY+0z9PI2fD64BLreAUYmr+PCFyKLcfideqN2MBwUyCrvopIGAf ww9wgfbVrA7JhNWIZ0YLzrkcOZVxz7c5tRpzCKnNv2iD8zXCQgZLGp5+U4uUDAqlIc57 srJalP16zesoS4Hy1nCy4DeUZRIG54ZQrmzDaj/mgj/dkVd+d5CS6MJnsxWVY3fAfYsv bfKJBOKsrGgStbvP01JotYv7SwI9yDPYZBKEtJ5j/Tie5tRgc0Mc4NCWnsYGm7+yUXtt IctQ== X-Gm-Message-State: ALQs6tDMNlOdQ9+AMP/ps8qmvxuGk8SkUELichw59Qa+Kw5yzpm5E479 0K+akogOsqApVFAc96xah4r4/V3D X-Received: by 2002:a24:8b82:: with SMTP id g124-v6mr25352393ite.56.1525407633224; Thu, 03 May 2018 21:20:33 -0700 (PDT) Received: from localhost.localdomain ([2605:a000:1316:4462:790f:f81c:25a6:fe65]) by smtp.googlemail.com with ESMTPSA id k1-v6sm605341iti.42.2018.05.03.21.20.32 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 03 May 2018 21:20:32 -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 4/9] Add extra exit functions for R3Di and SBZ Date: Fri, 4 May 2018 00:19:47 -0400 Message-Id: <1525407594-25644-4-git-send-email-conmanx360@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1525407594-25644-1-git-send-email-conmanx360@gmail.com> References: <1525407594-25644-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 | 126 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c index 68e5122..3fbbb85 100644 --- a/sound/pci/hda/patch_ca0132.c +++ b/sound/pci/hda/patch_ca0132.c @@ -4641,6 +4641,121 @@ 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) +{ + /* added in later patch. */ +// chipio_set_stream_control(codec, 0x03, 0); +// chipio_set_stream_control(codec, 0x04, 0); + + /* 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_stream_control(codec, 0x14, 0); +// chipio_set_stream_control(codec, 0x0C, 0); + + 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_stream_control(codec, 0x0C, 0); + + 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. */ @@ -4703,7 +4818,12 @@ static void ca0132_free(struct hda_codec *codec) snd_hda_power_up(codec); switch (spec->quirk) { case QUIRK_SBZ: + sbz_exit_chip(codec); + /* unmap BAR region 2. */ iounmap(spec->mem_base); + break; + case QUIRK_R3DI: + r3di_gpio_shutdown(codec); snd_hda_sequence_write(codec, spec->base_exit_verbs); ca0132_exit_chip(codec); break; @@ -4717,12 +4837,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