From patchwork Tue Feb 25 08:17:43 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Luke Jones X-Patchwork-Id: 13989504 Received: from fhigh-a2-smtp.messagingengine.com (fhigh-a2-smtp.messagingengine.com [103.168.172.153]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 577BB266F0C; Tue, 25 Feb 2025 08:17:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=103.168.172.153 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740471479; cv=none; b=XVw9l9PwgMXdvwMudov6tmSklWrHe/I7ygGoDbtXql5n0u95+X94G+TNKD3ZjeP5lFuXXijKdF1cqgE4ebMQ+CxnIjiU0Nv/HciF13a1ur2P22YnLzXYrJ+0Ip26c7/impdEG21h3ttmUW7u5bCC5lDrgsLDkCXiUJ4FvAE+OSM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740471479; c=relaxed/simple; bh=DF0yJCSgWku2Qh+hjwAfly4BrXeaV02IL45lb7rnNFk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=psS2F3hpUV9oyA7P5fGlRU9DY4+6ZE5Of9QqgJJe//HjVlX3VNCvnhA6J1kJACVKeYPkSUuRUjNsw+M29KptA6urwPgV8sZT/ExGn1TO7B6nP/feFbWSSp8hWUs0fJ/Q3aUmdLy4ke/V6unBsDloZ0sajZp7D0NbYtKBp3iovGk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ljones.dev; spf=none smtp.mailfrom=ljones.dev; dkim=pass (2048-bit key) header.d=ljones.dev header.i=@ljones.dev header.b=hU4J+QEe; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=XXisPTtr; arc=none smtp.client-ip=103.168.172.153 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ljones.dev Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=ljones.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=ljones.dev header.i=@ljones.dev header.b="hU4J+QEe"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="XXisPTtr" Received: from phl-compute-09.internal (phl-compute-09.phl.internal [10.202.2.49]) by mailfhigh.phl.internal (Postfix) with ESMTP id 4AE531140117; Tue, 25 Feb 2025 03:17:56 -0500 (EST) Received: from phl-mailfrontend-01 ([10.202.2.162]) by phl-compute-09.internal (MEProxy); Tue, 25 Feb 2025 03:17:56 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ljones.dev; h=cc :cc:content-transfer-encoding:content-type:date:date:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:subject:subject:to:to; s=fm2; t=1740471476; x= 1740557876; bh=PXVJmloJsQF5heTHD5DBkxvBIpoRIMfclHE+NbIcyi4=; b=h U4J+QEeoXmvsonRbJ6uSqv968rv0jAC5gOgrXouJ/IkiSYSUIpUihwngHUwo5p/y XEFzydeL8+Etoq2hNUg7pMWw1MC0mvRCMe3CWZ8/TON2vrlev9YV9PMonaptHcNh R9RojhXcmiGHExZ0Al9fGL4irLaC9yRGfP+8onbiBqJ7g79VOvKa8suBDCxaOLDf w6ZBo9lxG12wZMVHaiRGk8qqbA/80E6nR0llzth3G73pCoe8wpuZbA3n4EB2/rlG rzqHCJLuWoEiSm9f70o48yHSSXsObJnfB2ZZ9uRSbGFX3OF8hub9JlSOlWvWaubz bZtCOolc9ElsDJm6e8dWg== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding :content-type:date:date:feedback-id:feedback-id:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:subject:subject:to:to:x-me-proxy:x-me-sender :x-me-sender:x-sasl-enc; s=fm1; t=1740471476; x=1740557876; bh=P XVJmloJsQF5heTHD5DBkxvBIpoRIMfclHE+NbIcyi4=; b=XXisPTtrlafiCJlTo 9KSxzGYUkrTBPJz/JY1ruo3VhKT3uFBoUM8MYVkTvsxGvBd6uzer8+W2bXkSi9b4 D7v26o9EnKvrZgwuR+NzgJyl/i6nra6UxsBTcr1zAFpcIriHXGCVdXNkrj3+g91W DFeDC3dTI+We+FWi2Bra8zgXL71ODCuypFZ0WYfQmhleQIRutR/bg2+gPOtzm2xx 8nhBi4kocPe2fjFOxeiKQmyWku5//MJ7YGN3mKRZ4RYTEAKq8Rb00b4jIVm55RJh Oo2IUKKYCbAD+yKeXcng/hVjca8cbizoyGRz6vJeqln8AdAdgGku5N/kO6+kJm2B BqnDQ== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeefvddrtddtgdekuddvtdcutefuodetggdotefrod ftvfcurfhrohhfihhlvgemucfhrghsthforghilhdpggftfghnshhusghstghrihgsvgdp uffrtefokffrpgfnqfghnecuuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivg hnthhsucdlqddutddtmdenucfjughrpefhvfevufffkffojghfggfgsedtkeertdertddt necuhfhrohhmpefnuhhkvgculfhonhgvshcuoehluhhkvgeslhhjohhnvghsrdguvghvqe enucggtffrrghtthgvrhhnpeeuueelfeefiefhlefhhfehleefffegteeuhfehveekteeu udfgteefteelhfeijeenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepmhgrih hlfhhrohhmpehluhhkvgeslhhjohhnvghsrdguvghvpdhnsggprhgtphhtthhopeekpdhm ohguvgepshhmthhpohhuthdprhgtphhtthhopehlihhnuhigqdhkvghrnhgvlhesvhhgvg hrrdhkvghrnhgvlhdrohhrghdprhgtphhtthhopehhuggvghhovgguvgesrhgvughhrght rdgtohhmpdhrtghpthhtohepihhlphhordhjrghrvhhinhgvnheslhhinhhugidrihhnth gvlhdrtghomhdprhgtphhtthhopehplhgrthhfohhrmhdqughrihhvvghrqdigkeeisehv ghgvrhdrkhgvrhhnvghlrdhorhhgpdhrtghpthhtoheplhhinhhugidqihhnphhuthesvh hgvghrrdhkvghrnhgvlhdrohhrghdprhgtphhtthhopegsvghnthhishhssehkvghrnhgv lhdrohhrghdprhgtphhtthhopehjihhkohhssehkvghrnhgvlhdrohhrghdprhgtphhtth hopehluhhkvgeslhhjohhnvghsrdguvghv X-ME-Proxy: Feedback-ID: i5ec1447f:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Tue, 25 Feb 2025 03:17:52 -0500 (EST) From: Luke Jones To: linux-kernel@vger.kernel.org Cc: hdegoede@redhat.com, ilpo.jarvinen@linux.intel.com, platform-driver-x86@vger.kernel.org, linux-input@vger.kernel.org, bentiss@kernel.org, jikos@kernel.org, "Luke D. Jones" Subject: [PATCH 1/2] hid-asus: check ROG Ally MCU version and warn Date: Tue, 25 Feb 2025 21:17:43 +1300 Message-ID: <20250225081744.92841-2-luke@ljones.dev> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250225081744.92841-1-luke@ljones.dev> References: <20250225081744.92841-1-luke@ljones.dev> Precedence: bulk X-Mailing-List: platform-driver-x86@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: "Luke D. Jones" ASUS have fixed suspend issues arising from a flag not being cleared in the MCU FW in both the ROG Ally 1 and the ROG Ally X. Implement a check and a warning to encourage users to update the FW to a minimum supported version. Signed-off-by: Luke D. Jones --- drivers/hid/hid-asus.c | 97 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 95 insertions(+), 2 deletions(-) diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c index 46e3e42f9eb5..e1e60b80115a 100644 --- a/drivers/hid/hid-asus.c +++ b/drivers/hid/hid-asus.c @@ -52,6 +52,10 @@ MODULE_DESCRIPTION("Asus HID Keyboard and TouchPad"); #define FEATURE_KBD_LED_REPORT_ID1 0x5d #define FEATURE_KBD_LED_REPORT_ID2 0x5e +#define ROG_ALLY_REPORT_SIZE 64 +#define ROG_ALLY_X_MIN_MCU 313 +#define ROG_ALLY_MIN_MCU 319 + #define SUPPORT_KBD_BACKLIGHT BIT(0) #define MAX_TOUCH_MAJOR 8 @@ -84,6 +88,7 @@ MODULE_DESCRIPTION("Asus HID Keyboard and TouchPad"); #define QUIRK_MEDION_E1239T BIT(10) #define QUIRK_ROG_NKEY_KEYBOARD BIT(11) #define QUIRK_ROG_CLAYMORE_II_KEYBOARD BIT(12) +#define QUIRK_ROG_ALLY_XPAD BIT(13) #define I2C_KEYBOARD_QUIRKS (QUIRK_FIX_NOTEBOOK_REPORT | \ QUIRK_NO_INIT_REPORTS | \ @@ -534,9 +539,89 @@ static bool asus_kbd_wmi_led_control_present(struct hid_device *hdev) return !!(value & ASUS_WMI_DSTS_PRESENCE_BIT); } +/* + * We don't care about any other part of the string except the version section. + * Example strings: FGA80100.RC72LA.312_T01, FGA80100.RC71LS.318_T01 + */ +static int mcu_parse_version_string(const u8 *response, size_t response_size) +{ + const u8 *end = response + response_size; + const u8 *p = response; + int dots, err; + long version; + + dots = 0; + while (p < end && dots < 2) { + if (*p++ == '.') + dots++; + } + + if (dots != 2 || p >= end) + return -EINVAL; + + err = kstrtol((const char *)p, 10, &version); + if (err || version < 0) + return -EINVAL; + + return version; +} + +static int mcu_request_version(struct hid_device *hdev) +{ + const u8 request[] = { 0x5a, 0x05, 0x03, 0x31, 0x00, 0x20 }; + u8 *response; + int ret; + + response = kzalloc(ROG_ALLY_REPORT_SIZE, GFP_KERNEL); + if (!response) + return -ENOMEM; + + ret = asus_kbd_set_report(hdev, request, sizeof(request)); + if (ret < 0) + goto out; + + ret = hid_hw_raw_request(hdev, FEATURE_REPORT_ID, response, + ROG_ALLY_REPORT_SIZE, HID_FEATURE_REPORT, + HID_REQ_GET_REPORT); + if (ret < 0) + goto out; + + ret = mcu_parse_version_string(response, ROG_ALLY_REPORT_SIZE); + +out: + if (ret < 0) + hid_err(hdev, "Failed to get MCU version: %d, response: %*ph\n", + ret, ROG_ALLY_REPORT_SIZE, response); + kfree(response); + return ret; +} + +static void validate_mcu_fw_version(struct hid_device *hdev, int idProduct) +{ + int min_version = ROG_ALLY_X_MIN_MCU; + int version; + + version = mcu_request_version(hdev); + if (version < 0) + return; + + if (idProduct == USB_DEVICE_ID_ASUSTEK_ROG_NKEY_ALLY) + min_version = ROG_ALLY_MIN_MCU; + + hid_info(hdev, "Ally device MCU version: %d\n", version); + if (version < min_version) { + hid_warn(hdev, + "The MCU firmware version must be %d or greater\n" + "Please update your MCU with official ASUS firmware release\n", + min_version); + } +} + static int asus_kbd_register_leds(struct hid_device *hdev) { struct asus_drvdata *drvdata = hid_get_drvdata(hdev); + struct usb_interface *intf; + struct usb_device *udev; unsigned char kbd_func; int ret; @@ -560,6 +645,14 @@ static int asus_kbd_register_leds(struct hid_device *hdev) if (ret < 0) return ret; } + + if (drvdata->quirks & QUIRK_ROG_ALLY_XPAD) { + intf = to_usb_interface(hdev->dev.parent); + udev = interface_to_usbdev(intf); + validate_mcu_fw_version(hdev, + le16_to_cpu(udev->descriptor.idProduct)); + } + } else { /* Initialize keyboard */ ret = asus_kbd_init(hdev, FEATURE_KBD_REPORT_ID); @@ -1280,10 +1373,10 @@ static const struct hid_device_id asus_devices[] = { QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD }, { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_ROG_NKEY_ALLY), - QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD }, + QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD | QUIRK_ROG_ALLY_XPAD}, { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_ROG_NKEY_ALLY_X), - QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD }, + QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD | QUIRK_ROG_ALLY_XPAD }, { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_ROG_CLAYMORE_II_KEYBOARD), QUIRK_ROG_CLAYMORE_II_KEYBOARD }, From patchwork Tue Feb 25 08:17:44 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Luke Jones X-Patchwork-Id: 13989505 Received: from fout-a7-smtp.messagingengine.com (fout-a7-smtp.messagingengine.com [103.168.172.150]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7ED12261377; Tue, 25 Feb 2025 08:18:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=103.168.172.150 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740471482; cv=none; b=QkV/dqTmfcYlIz5LJYLvY2N+yEA8UyTgma2qXjoI65+x/tMN7O8MZxzP2aFACgxPKblXHFKmZgW8PZaESGK2HArPfRzu2AkPxgdM87SewHYSE5rNEuttJe4iErgGciZtEpybG4xKfc/9Mu1D0lypDjTmjREwP/PH5uTwGu39sS4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740471482; c=relaxed/simple; bh=VUp8bNV+GFGcNCI8h7tFXGBM0/wXWX070QhhoojNIRA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=AdxufgOUj46vb46Nr+7fYyPXSxEs5/JEPIhRsox+a/QrH0dLiPfowgU32cleDUxQk053yH87yb/Iv97LXgz+mSvU4Lnjrmu0sUNieKlSNkLRLiTEEtNILx1G7H4nqUf1iCMyM0jTFRQ3WoKFnumAwx/IZBmOo8M9/nxGcGvMaaM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ljones.dev; spf=none smtp.mailfrom=ljones.dev; dkim=pass (2048-bit key) header.d=ljones.dev header.i=@ljones.dev header.b=Nor43NIa; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=b1KlRVqS; arc=none smtp.client-ip=103.168.172.150 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ljones.dev Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=ljones.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=ljones.dev header.i=@ljones.dev header.b="Nor43NIa"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="b1KlRVqS" Received: from phl-compute-09.internal (phl-compute-09.phl.internal [10.202.2.49]) by mailfout.phl.internal (Postfix) with ESMTP id 7879A1381682; Tue, 25 Feb 2025 03:17:59 -0500 (EST) Received: from phl-mailfrontend-01 ([10.202.2.162]) by phl-compute-09.internal (MEProxy); Tue, 25 Feb 2025 03:17:59 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ljones.dev; h=cc :cc:content-transfer-encoding:content-type:date:date:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:subject:subject:to:to; s=fm2; t=1740471479; x= 1740557879; bh=v96XIckUQWSgWykGqEZgEzBKx2e/5JT0EzSkfUb0ReI=; b=N or43NIaRpB8/YAptmz1JOFvvPq+iPTtAXy7fjtsmpFtyGw7JVX1eSFTBTtMdsAvc Ll/I089p8XtcKDMPTEJKgd5hbzj2fffx/VXyyePQjxk+YyCN6U1EwdTIcr2y7GUa NYPfvDnr77kIIWqpQLt/K5lFXwi4G7T6aBFPe2PyoPKfgJLG6i4cz3t2bxtnTe3g Z1KGVbjNrE2yA84d8uxD3kSSFhK7xWVFnfMtI3R2jjkLvf0GLSxOGeaUdUQuDQXX ypLACjPF1DwbzRDy2hCVWrCHQsK/P13H/2L1AxoYGIQsKxhvlIZceooFiqwKiTRP 1E4q4ibYDMJNeF9D/8Dig== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding :content-type:date:date:feedback-id:feedback-id:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:subject:subject:to:to:x-me-proxy:x-me-sender :x-me-sender:x-sasl-enc; s=fm1; t=1740471479; x=1740557879; bh=v 96XIckUQWSgWykGqEZgEzBKx2e/5JT0EzSkfUb0ReI=; b=b1KlRVqSYZhfe/EfS GUd0ml7xC64oZZ1rfzQtzwHJ1k7kAPmgJexpljvPGZ2SeG7Zc+8np32boW7mr+fF EsftutFIw5Y7Upgg8krDNRlOqfwRKAQOysLgguB7lkoxN8fXYpwgJU4vxnJWzQo7 mUczofRI08lrvFk1Qr1aPxnSYeM6jX4YRUlxopMpl6RoSPs5ia+Vp/M1bXzfmGUF FAXe6EPoiegB4jt6zwaeqjsdEwJCTvS55h+UxoIOm7AOf1E+2ezuthAO43lgXTlJ 6zkmNwkLXuTZflzDiq9aJHp59XEoYMQGYZCUqvDLqIVTm6hLAAH9qxrt5X6qZibm 4BLTw== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeefvddrtddtgdekuddvtdcutefuodetggdotefrod ftvfcurfhrohhfihhlvgemucfhrghsthforghilhdpggftfghnshhusghstghrihgsvgdp uffrtefokffrpgfnqfghnecuuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivg hnthhsucdlqddutddtmdenucfjughrpefhvfevufffkffojghfggfgsedtkeertdertddt necuhfhrohhmpefnuhhkvgculfhonhgvshcuoehluhhkvgeslhhjohhnvghsrdguvghvqe enucggtffrrghtthgvrhhnpeeuueelfeefiefhlefhhfehleefffegteeuhfehveekteeu udfgteefteelhfeijeenucevlhhushhtvghrufhiiigvpedunecurfgrrhgrmhepmhgrih hlfhhrohhmpehluhhkvgeslhhjohhnvghsrdguvghvpdhnsggprhgtphhtthhopeekpdhm ohguvgepshhmthhpohhuthdprhgtphhtthhopehlihhnuhigqdhkvghrnhgvlhesvhhgvg hrrdhkvghrnhgvlhdrohhrghdprhgtphhtthhopehhuggvghhovgguvgesrhgvughhrght rdgtohhmpdhrtghpthhtohepihhlphhordhjrghrvhhinhgvnheslhhinhhugidrihhnth gvlhdrtghomhdprhgtphhtthhopehplhgrthhfohhrmhdqughrihhvvghrqdigkeeisehv ghgvrhdrkhgvrhhnvghlrdhorhhgpdhrtghpthhtoheplhhinhhugidqihhnphhuthesvh hgvghrrdhkvghrnhgvlhdrohhrghdprhgtphhtthhopegsvghnthhishhssehkvghrnhgv lhdrohhrghdprhgtphhtthhopehjihhkohhssehkvghrnhgvlhdrohhrghdprhgtphhtth hopehluhhkvgeslhhjohhnvghsrdguvghv X-ME-Proxy: Feedback-ID: i5ec1447f:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Tue, 25 Feb 2025 03:17:56 -0500 (EST) From: Luke Jones To: linux-kernel@vger.kernel.org Cc: hdegoede@redhat.com, ilpo.jarvinen@linux.intel.com, platform-driver-x86@vger.kernel.org, linux-input@vger.kernel.org, bentiss@kernel.org, jikos@kernel.org, "Luke D. Jones" Subject: [PATCH 2/2] platform/x86: asus-wmi: Refactor Ally suspend/resume Date: Tue, 25 Feb 2025 21:17:44 +1300 Message-ID: <20250225081744.92841-3-luke@ljones.dev> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250225081744.92841-1-luke@ljones.dev> References: <20250225081744.92841-1-luke@ljones.dev> Precedence: bulk X-Mailing-List: platform-driver-x86@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: "Luke D. Jones" Adjust how the CSEE direct call hack is used. The results of months of testing combined with help from ASUS to determine the actual cause of suspend issues has resulted in this refactoring which immensely improves the reliability for devices which do not have the following minimum MCU FW version: - ROG Ally X: 313 - ROG Ally 1: 319 For MCU FW versions that match the minimum or above the CSEE hack is disabled and mcu_powersave set to on by default as there are no negatives beyond a slightly slower device reinitialization due to the MCU being powered off. As this is set only at module load time, it is still possible for mcu_powersave sysfs attributes to change it at runtime if so desired. Signed-off-by: Luke D. Jones --- drivers/hid/hid-asus.c | 4 + drivers/platform/x86/asus-wmi.c | 124 ++++++++++++++------- include/linux/platform_data/x86/asus-wmi.h | 15 +++ 3 files changed, 104 insertions(+), 39 deletions(-) diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c index e1e60b80115a..58794c9024cf 100644 --- a/drivers/hid/hid-asus.c +++ b/drivers/hid/hid-asus.c @@ -614,6 +614,9 @@ static void validate_mcu_fw_version(struct hid_device *hdev, int idProduct) "The MCU firmware version must be %d or greater\n" "Please update your MCU with official ASUS firmware release\n", min_version); + } else { + set_ally_mcu_hack(false); + set_ally_mcu_powersave(true); } } @@ -1420,4 +1423,5 @@ static struct hid_driver asus_driver = { }; module_hid_driver(asus_driver); +MODULE_IMPORT_NS("ASUS_WMI"); MODULE_LICENSE("GPL"); diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c index 38ef778e8c19..9dba88a29e2c 100644 --- a/drivers/platform/x86/asus-wmi.c +++ b/drivers/platform/x86/asus-wmi.c @@ -142,16 +142,20 @@ module_param(fnlock_default, bool, 0444); #define ASUS_MINI_LED_2024_STRONG 0x01 #define ASUS_MINI_LED_2024_OFF 0x02 -/* Controls the power state of the USB0 hub on ROG Ally which input is on */ #define ASUS_USB0_PWR_EC0_CSEE "\\_SB.PCI0.SBRG.EC0.CSEE" -/* 300ms so far seems to produce a reliable result on AC and battery */ -#define ASUS_USB0_PWR_EC0_CSEE_WAIT 1500 +/* + * The period required to wait after screen off/on/s2idle.check in MS. + * Time here greatly impacts the wake behaviour. Used in suspend/wake. + */ +#define ASUS_USB0_PWR_EC0_CSEE_WAIT 600 +#define ASUS_USB0_PWR_EC0_CSEE_OFF 0xB7 +#define ASUS_USB0_PWR_EC0_CSEE_ON 0xB8 static const char * const ashs_ids[] = { "ATK4001", "ATK4002", NULL }; static int throttle_thermal_policy_write(struct asus_wmi *); -static const struct dmi_system_id asus_ally_mcu_quirk[] = { +static const struct dmi_system_id asus_rog_ally_device[] = { { .matches = { DMI_MATCH(DMI_BOARD_NAME, "RC71L"), @@ -274,9 +278,6 @@ struct asus_wmi { u32 tablet_switch_dev_id; bool tablet_switch_inverted; - /* The ROG Ally device requires the MCU USB device be disconnected before suspend */ - bool ally_mcu_usb_switch; - enum fan_type fan_type; enum fan_type gpu_fan_type; enum fan_type mid_fan_type; @@ -335,6 +336,9 @@ struct asus_wmi { struct asus_wmi_driver *driver; }; +/* Global to allow setting externally without requiring driver data */ +static bool use_ally_mcu_hack; + /* WMI ************************************************************************/ static int asus_wmi_evaluate_method3(u32 method_id, @@ -549,7 +553,7 @@ static int asus_wmi_get_devstate(struct asus_wmi *asus, u32 dev_id, u32 *retval) return 0; } -static int asus_wmi_set_devstate(u32 dev_id, u32 ctrl_param, +int asus_wmi_set_devstate(u32 dev_id, u32 ctrl_param, u32 *retval) { return asus_wmi_evaluate_method(ASUS_WMI_METHODID_DEVS, dev_id, @@ -1343,6 +1347,38 @@ static ssize_t nv_temp_target_show(struct device *dev, static DEVICE_ATTR_RW(nv_temp_target); /* Ally MCU Powersave ********************************************************/ + +/* + * The HID driver needs to check MCU version and set this to false if the MCU FW + * version is >= the minimum requirements. New FW do not need the hacks. + */ +void set_ally_mcu_hack(bool enabled) +{ + use_ally_mcu_hack = enabled; + pr_info("Disabled Ally MCU suspend quirks"); +} +EXPORT_SYMBOL_NS_GPL(set_ally_mcu_hack, "ASUS_WMI"); + +/* + * mcu_powersave should be enabled always, as it is fixed in MCU FW versions: + * - v313 for Ally X + * - v319 for Ally 1 + * The HID driver checks MCU versions and so should set this if requirements match + */ +void set_ally_mcu_powersave(bool enabled) +{ + int result, err; + + err = asus_wmi_set_devstate(ASUS_WMI_DEVID_MCU_POWERSAVE, enabled, &result); + if (err) + pr_warn("Failed to set MCU powersave: %d\n", err); + if (result > 1) + pr_warn("Failed to set MCU powersave (result): 0x%x\n", result); + + pr_info("Set mcu_powersave to enabled"); +} +EXPORT_SYMBOL_NS_GPL(set_ally_mcu_powersave, "ASUS_WMI"); + static ssize_t mcu_powersave_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -4711,6 +4747,18 @@ static int asus_wmi_add(struct platform_device *pdev) if (err) goto fail_platform; + use_ally_mcu_hack = acpi_has_method(NULL, ASUS_USB0_PWR_EC0_CSEE) + && dmi_check_system(asus_rog_ally_device); + if (use_ally_mcu_hack && dmi_match(DMI_BOARD_NAME, "RC71")) { + /* + * These steps ensure the device is in a valid good state, this is + * especially important for the Ally 1 after a reboot. + */ + acpi_execute_simple_method(NULL, ASUS_USB0_PWR_EC0_CSEE, + ASUS_USB0_PWR_EC0_CSEE_ON); + msleep(ASUS_USB0_PWR_EC0_CSEE_WAIT); + } + /* ensure defaults for tunables */ asus->ppt_pl2_sppt = 5; asus->ppt_pl1_spl = 5; @@ -4723,8 +4771,6 @@ static int asus_wmi_add(struct platform_device *pdev) asus->egpu_enable_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_EGPU); asus->dgpu_disable_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_DGPU); asus->kbd_rgb_state_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_TUF_RGB_STATE); - asus->ally_mcu_usb_switch = acpi_has_method(NULL, ASUS_USB0_PWR_EC0_CSEE) - && dmi_check_system(asus_ally_mcu_quirk); if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_MINI_LED_MODE)) asus->mini_led_dev_id = ASUS_WMI_DEVID_MINI_LED_MODE; @@ -4910,34 +4956,6 @@ static int asus_hotk_resume(struct device *device) return 0; } -static int asus_hotk_resume_early(struct device *device) -{ - struct asus_wmi *asus = dev_get_drvdata(device); - - if (asus->ally_mcu_usb_switch) { - /* sleep required to prevent USB0 being yanked then reappearing rapidly */ - if (ACPI_FAILURE(acpi_execute_simple_method(NULL, ASUS_USB0_PWR_EC0_CSEE, 0xB8))) - dev_err(device, "ROG Ally MCU failed to connect USB dev\n"); - else - msleep(ASUS_USB0_PWR_EC0_CSEE_WAIT); - } - return 0; -} - -static int asus_hotk_prepare(struct device *device) -{ - struct asus_wmi *asus = dev_get_drvdata(device); - - if (asus->ally_mcu_usb_switch) { - /* sleep required to ensure USB0 is disabled before sleep continues */ - if (ACPI_FAILURE(acpi_execute_simple_method(NULL, ASUS_USB0_PWR_EC0_CSEE, 0xB7))) - dev_err(device, "ROG Ally MCU failed to disconnect USB dev\n"); - else - msleep(ASUS_USB0_PWR_EC0_CSEE_WAIT); - } - return 0; -} - static int asus_hotk_restore(struct device *device) { struct asus_wmi *asus = dev_get_drvdata(device); @@ -4978,11 +4996,34 @@ static int asus_hotk_restore(struct device *device) return 0; } +static void asus_ally_s2idle_restore(void) +{ + if (use_ally_mcu_hack) { + acpi_execute_simple_method(NULL, ASUS_USB0_PWR_EC0_CSEE, + ASUS_USB0_PWR_EC0_CSEE_ON); + msleep(ASUS_USB0_PWR_EC0_CSEE_WAIT); + } +} + +static int asus_hotk_prepare(struct device *device) +{ + if (use_ally_mcu_hack) { + acpi_execute_simple_method(NULL, ASUS_USB0_PWR_EC0_CSEE, + ASUS_USB0_PWR_EC0_CSEE_OFF); + msleep(ASUS_USB0_PWR_EC0_CSEE_WAIT); + } + return 0; +} + +/* Use only for Ally devices due to the wake_on_ac */ +static struct acpi_s2idle_dev_ops asus_ally_s2idle_dev_ops = { + .restore = asus_ally_s2idle_restore, +}; + static const struct dev_pm_ops asus_pm_ops = { .thaw = asus_hotk_thaw, .restore = asus_hotk_restore, .resume = asus_hotk_resume, - .resume_early = asus_hotk_resume_early, .prepare = asus_hotk_prepare, }; @@ -5010,6 +5051,10 @@ static int asus_wmi_probe(struct platform_device *pdev) return ret; } + ret = acpi_register_lps0_dev(&asus_ally_s2idle_dev_ops); + if (ret) + pr_warn("failed to register LPS0 sleep handler in asus-wmi\n"); + return asus_wmi_add(pdev); } @@ -5042,6 +5087,7 @@ EXPORT_SYMBOL_GPL(asus_wmi_register_driver); void asus_wmi_unregister_driver(struct asus_wmi_driver *driver) { + acpi_unregister_lps0_dev(&asus_ally_s2idle_dev_ops); platform_device_unregister(driver->platform_device); platform_driver_unregister(&driver->platform_driver); used = false; diff --git a/include/linux/platform_data/x86/asus-wmi.h b/include/linux/platform_data/x86/asus-wmi.h index 783e2a336861..a32cb8865b2f 100644 --- a/include/linux/platform_data/x86/asus-wmi.h +++ b/include/linux/platform_data/x86/asus-wmi.h @@ -158,8 +158,23 @@ #define ASUS_WMI_DSTS_LIGHTBAR_MASK 0x0000000F #if IS_REACHABLE(CONFIG_ASUS_WMI) +void set_ally_mcu_hack(bool enabled); +void set_ally_mcu_powersave(bool enabled); +int asus_wmi_set_devstate(u32 dev_id, u32 ctrl_param, u32 *retval); int asus_wmi_evaluate_method(u32 method_id, u32 arg0, u32 arg1, u32 *retval); #else +static inline void set_ally_mcu_hack(bool enabled) +{ + return -ENODEV; +} +static inline void set_ally_mcu_powersave(bool enabled) +{ + return -ENODEV; +} +static inline int asus_wmi_set_devstate(u32 dev_id, u32 ctrl_param, u32 *retval) +{ + return -ENODEV; +} static inline int asus_wmi_evaluate_method(u32 method_id, u32 arg0, u32 arg1, u32 *retval) {