Received: by 10.192.165.148 with SMTP id m20csp4566297imm; Tue, 8 May 2018 10:25:20 -0700 (PDT) X-Google-Smtp-Source: AB8JxZpUz6QnaECRceot0e8IHnZXW9A/BQXsV0vZ2FnSLSu4XOGfCBQ97mP/B5ynJBVdMoNHIvxa X-Received: by 2002:a63:6ec6:: with SMTP id j189-v6mr32686888pgc.86.1525800320343; Tue, 08 May 2018 10:25:20 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1525800320; cv=none; d=google.com; s=arc-20160816; b=RhWjwOAg94TVgo63fdZ0dNT0f/CjhQooBcGQ8RlulVbNIMtjAIZjeiOfAwaTgnsIDz GPk4moFoIcPI/BkC7uWaEbBACM/YKqNWF5WjKLU5bZagqYZxb3nWUimFIJn+g3EXBL6F 1C8hxplsqTF8D2KHqMuIzmooq5T+jScpH8Fbnto93Tyi87faHJi1a1vJh+E0aTC4BHSc WN4sWlvBlxUGfZ3WrQZbrMJvfxmwNAcdTrHUeD59HPzJQfw0e7zU9TYG0YXC9qZlOK+i Oq3/FC90qjvNsonsCIkR5dwptdcyKgayp6OoDkIAxNlXpvsVNICQWga6yQIYu9Bj98RQ 0zbw== 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=c+I7uIL1xM2iupeJgy58u5k1dtYJv0K+A6PH+uqxUzmATUunCoC0gxA9s+2l5iWcxe vbYudKS8kvmy2e0OD4YVUQSd/AInZ7v61dJS3V3pdYQUcGcGp1IGVZzw6DjOwzT0gb9N IXkAJQvHp8LLQPuJobaQ8E3rclZ1UP0Soelf9h/24h5dvUsN+AVK4hBr7EBuUmuKBnfb Z1XN6uiPTRQB4y4s5hiThS0MuciFwID2c/IOj7Rrt3j37qwJdex2n+TIaWK/5KJ4iIiE zuJ2MYC5HRYSPmmXSMcu1romx+8jTzVFN/eEymjhf5LU/5qvQsiGDX1OJwIwItC/qu6Y 3FuA== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@gmail.com header.s=20161025 header.b=HylvokKX; 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 i1-v6si18829473pgq.327.2018.05.08.10.25.05; Tue, 08 May 2018 10:25:20 -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=HylvokKX; 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 S1755517AbeEHRYU (ORCPT + 99 others); Tue, 8 May 2018 13:24:20 -0400 Received: from mail-io0-f194.google.com ([209.85.223.194]:46275 "EHLO mail-io0-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932411AbeEHRUx (ORCPT ); Tue, 8 May 2018 13:20:53 -0400 Received: by mail-io0-f194.google.com with SMTP id f21-v6so39331218iob.13 for ; Tue, 08 May 2018 10:20:53 -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=HylvokKXDgyjDGm/zv7rkvLltg3+okBYY1PBjoGCinJWJSTYmR4bjGZcS1owt8ZLLL zPxWNodoWFX9SnJQBytW+fQZ1MMoEtz4Otpc/uKTdZaYqFKIf2n0GMNCnfoGLYxOsqdo 4DTGHfinblb3S5L1zAg60mEcJ35dWxk/SXZDz0pKIYgB12XT2frahO1z09ZMXzav2Q07 6SutZJz2N1tiOq4X1+O9y+Ok1LeY3i8LDU7SxbMJwrKO7yEdkvVwm+YPQiOY8+oRDrCa 9Uzfrk+KlGSv1/Jkv2HSXfRMUBClXbguuBbpbEBU85Smw0h5tDLrgFYftnr95JMTirBr uX9Q== 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=n4613x/nJfeeB1JbaU0ss6l1Ga2ObgEGS5ReR9mPNC4omv2Xx/WGGvVv4syR0LMkuu yKBlA9WxahKdWfpMqw5Yqr3qY2sz/e9ugkn+4lEaPss2QYjhYEZmT5ot7nnx5ktUxgwu HTEWLwGvZxXbKd/b8xO6JQO3OLSo0QG9r4eQqfLnsl5LIkul6iE1EGrQ0wRwVn2mIqxs Mdm1prM466pCL2z/n6v5vYmEHZaOI94l5qKTMeCW9oPAkgJsZlX4fIwUg44bDR5qktGj LafbqFx6pcJ+UBzD7/1YtOb1ZryJ1LtuNksFVbV9ni+gj3vincFA/0r9H3EUx1QEsaBT RpnA== X-Gm-Message-State: ALQs6tDfztc91L30CNhRNd91Jqj1ZkzCtyrwW3qGY7fT9Ml6n5UDpT1a QNbxabmZnvaMg5RVBcU66i0= X-Received: by 2002:a6b:2a05:: with SMTP id q5-v6mr47069615ioq.252.1525800052842; Tue, 08 May 2018 10:20:52 -0700 (PDT) Received: from localhost.localdomain ([2605:a000:1316:4462:80cc:335d:e307:b5cb]) by smtp.googlemail.com with ESMTPSA id k62-v6sm13160209ioo.23.2018.05.08.10.20.51 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 08 May 2018 10:20:52 -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 v5 04/13] ALSA: hda/ca0132: Add extra exit functions for R3Di and SBZ Date: Tue, 8 May 2018 13:20:04 -0400 Message-Id: <1525800015-2920-5-git-send-email-conmanx360@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1525800015-2920-1-git-send-email-conmanx360@gmail.com> References: <1525800015-2920-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