Received: by 10.192.165.148 with SMTP id m20csp53924imm; Thu, 3 May 2018 14:45:10 -0700 (PDT) X-Google-Smtp-Source: AB8JxZrCF0I7HLtH9c5Qwy6CE8UtVSyZAWuPY+sC0f0G/KfZ0oQOiKtHMTfomnBnKqe/EQR0Fk/J X-Received: by 2002:a65:4488:: with SMTP id l8-v6mr10583379pgq.239.1525383910764; Thu, 03 May 2018 14:45:10 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1525383910; cv=none; d=google.com; s=arc-20160816; b=AUP/OyVSFGO8fW6FidlY/fjY36N0ezv6Zwh9fjsX7JY0W42r26hpv56Yrl/GYXWSwj O5oIsGkWzJeVGg829svOwgKa/CvR8LOR8wfUiHNnVuvWSdFoizLXNPoYPEUmyLyQq3BU SkZS3qe2TBpHm7OL/ZrkpZmIo10DnrlMv/GAw6SfkmiAoTW2WxvVpoxyvJ0BhHKFJ5y3 b5OQ+z290Ep+fWcP8E+Qhagq/Hp6IFAm4IUBF0iRcAiz5+eNxUjZoO5e6DRujA7J7nu/ K+q89BcxWN7h+u8sU/Dp6yNfurQ24bdLA2JH+iqBRn3oMTySdJmHqMinPOi6hv33Cqvm 2G3w== 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=bZdIQe2PLljxWDWNlBwLJiE/02KMsF+YwDwvPm9cPpU=; b=P1dlx9gtxrTX16Zdhq9nFXOZyi7atJYyNW3UCpwFdfO82VnN6pcz5Z2Gvbi4prfcqZ XXgJQiMzBfAoHt88eNbD+Ns7Em/ugWq2jMCxzLpYhz25bOOq0kep/pSkcQ32AWmFNsPn jsG8meYGK+h+TQV1sipal3qsV1Rn4JN3vx8zDVQsmaPq84p3nY/a8swUM1F4dpZT5ifH teDgAa/XlAr0h5JlzYl8Ere1IqcNJXrvJMvoR5Yb3G7GaLHXl4DzH4ccK5xu8Qw0FRl5 XTDo/KEVrW3bvLZNbD6u9g1QN1qxuf2+gjhA0RTqNhs8ui/EHbp69PaBkrzhRKkW/77+ NhGg== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@gmail.com header.s=20161025 header.b=tZZfiVZB; 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 y139si15019757pfc.163.2018.05.03.14.44.56; Thu, 03 May 2018 14:45:10 -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=tZZfiVZB; 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 S1751461AbeECVnX (ORCPT + 99 others); Thu, 3 May 2018 17:43:23 -0400 Received: from mail-it0-f66.google.com ([209.85.214.66]:55822 "EHLO mail-it0-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751195AbeECVnT (ORCPT ); Thu, 3 May 2018 17:43:19 -0400 Received: by mail-it0-f66.google.com with SMTP id 144-v6so1042454iti.5 for ; Thu, 03 May 2018 14:43:18 -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=bZdIQe2PLljxWDWNlBwLJiE/02KMsF+YwDwvPm9cPpU=; b=tZZfiVZB+1NinIuKUk/hzSvy2ci9KcXPBLs1RU3NT3B7K5s7jOdcjpXHSecuRJHm9o KriNmdee0pPKxmDQYo3tyU+JnQUK0GRAyRuuwCpUVfEZHRLwhBhLBuHcIw2BV/5ijIoi DPAK77/OX9IeAmnKtgFiK+y6gjJODIJXlwH8KJSYfN+HYncOccr8nOkVsKs9QhGTgqqd VAwCepn3KWakZIl3iOCprOUMd1+bck38p5W7J8uee0wtUO37CmocLk8NKyTpH9ZGX9xd t/w6Hrm+rinPGf9qyAtnmfm880nImTXDZavzyqa/1guVDRyioHxZBWJg1ZVkyinNv3Ex YPvA== 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=bZdIQe2PLljxWDWNlBwLJiE/02KMsF+YwDwvPm9cPpU=; b=km6YpDosZ0aXW1ZLD7YjeAj/WVHOWnmvvnddtwdaO1xDmZwiW+yiSlj9cmPRT5kD7v 5HKhph3YE/Ht4TSeP4tpkFW812j2r5dT0GEYELiROhRtwQxHX3t7DQrLF78qZhazOiWk hC2JXVpBxWbgkielGVPtN6vpF4FwwomadowZl2+cKCmFz9CD/Bd6bGVUcjtauTQkzDs8 b5Sd+YzjQQxln+7803Z7ReJfBgw1tsFQqgjG2x2ETL9KKz9/1pWQzx1aAx0n7HLeZByT W2C4eDXI/+35uP4J2htIIJDAP/yhGcTof0k1AhCwyNAFOjBhqlei83lq56A6KJNiwDT5 j5mw== X-Gm-Message-State: ALQs6tCaSBnLeICfhafMd5tf8UPQc9NGzxPv2Z0/5SNxUMMapvU+KJog sh8akPdcfU8xkRbxWxYLpLo= X-Received: by 2002:a24:ded4:: with SMTP id d203-v6mr16756475itg.100.1525383798332; Thu, 03 May 2018 14:43:18 -0700 (PDT) Received: from localhost.localdomain ([2605:a000:1316:4462:30e7:9a4b:7da5:3c1c]) by smtp.googlemail.com with ESMTPSA id u77-v6sm263119ita.30.2018.05.03.14.43.17 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 03 May 2018 14:43:17 -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: Thu, 3 May 2018 17:42:45 -0400 Message-Id: <1525383771-11105-4-git-send-email-conmanx360@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1525383771-11105-1-git-send-email-conmanx360@gmail.com> References: <1525383771-11105-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 | 136 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 136 insertions(+) diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c index 2f7f964..23a8e79 100644 --- a/sound/pci/hda/patch_ca0132.c +++ b/sound/pci/hda/patch_ca0132.c @@ -4639,6 +4639,130 @@ 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. */ @@ -4701,7 +4825,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; @@ -4715,12 +4844,19 @@ 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); + return; +} + 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