lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Message-Id: <1349256392-20320-9-git-send-email-corentin.chary@gmail.com>
Date:	Wed,  3 Oct 2012 11:26:31 +0200
From:	Corentin Chary <corentin.chary@...il.com>
To:	Matthew Garrett <mjg59@...f.ucam.org>
Cc:	platform-driver-x86@...r.kernel.org,
	AceLan Kao <acelan.kao@...onical.com>,
	Corentin Chary <corentincj@...aif.net>,
	Corentin Chary <corentin.chary@...il.com>,
	Matthew Garrett <mjg@...hat.com>,
	acpi4asus-user@...ts.sourceforge.net, linux-kernel@...r.kernel.org
Subject: [PATCH 8/8] asus-wmi: add display toggle quirk

From: AceLan Kao <acelan.kao@...onical.com>

For machines with AMD graphic chips, it will send out WMI event and ACPI
interrupt at the same time while hitting the hotkey. BIOS will notify the
system the next display output mode throught WMI event code, so that
windows' application can show an OSD to tell the user which mode will be
taken effect. User can hit the display toggle key many times within 2
seconds to choose the mode they want. After 2 seconds, WMI dirver should
send a WMIMethod(SDSP) command to tell the BIOS which mode the user chose.
And then BIOS will raise another ACPI interrupt to tell the system to
really switch the display mode.

In Linux desktop, we don't have this kind of OSD to let users to choose
the mode they want, so we don't need to call WMIMethod(SDSP) to have
another ACPI interrupt. To simplify the problem, we just have to ignore
the WMI event, and let the first ACPI interrupt to send out the key event.

For the need, here comes another quirk to add machines with this kind of
behavior. When the WMI driver receives the display toggle WMI event, and
found the machin is in the list, it will do nothing and let ACPI video
driver to report the key event.

Signed-off-by: AceLan Kao <acelan.kao@...onical.com>
Signed-off-by: Corentin Chary <corentincj@...aif.net>
---
 drivers/platform/x86/asus-nb-wmi.c |   31 ++++++++++++++++++++++++++++++-
 drivers/platform/x86/asus-wmi.c    |   31 ++++++++++++++++++++++++++++---
 drivers/platform/x86/asus-wmi.h    |    7 +++++++
 3 files changed, 65 insertions(+), 4 deletions(-)

diff --git a/drivers/platform/x86/asus-nb-wmi.c b/drivers/platform/x86/asus-nb-wmi.c
index 87d45e0..9aa6642 100644
--- a/drivers/platform/x86/asus-nb-wmi.c
+++ b/drivers/platform/x86/asus-nb-wmi.c
@@ -59,6 +59,17 @@ static struct quirk_entry quirk_asus_unknown = {
 	.wapf = 0,
 };
 
+/*
+ * For those machines that need software to control bt/wifi status
+ * and can't adjust brightness through ACPI interface
+ * and have duplicate events(ACPI and WMI) for display toggle
+ */
+static struct quirk_entry quirk_asus_x55u = {
+	.wapf = 4,
+	.wmi_backlight_power = true,
+	.no_display_toggle = true,
+};
+
 static struct quirk_entry quirk_asus_x401u = {
 	.wapf = 4,
 };
@@ -77,6 +88,15 @@ static struct dmi_system_id asus_quirks[] = {
 			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
 			DMI_MATCH(DMI_PRODUCT_NAME, "X401U"),
 		},
+		.driver_data = &quirk_asus_x55u,
+	},
+	{
+		.callback = dmi_matched,
+		.ident = "ASUSTeK COMPUTER INC. X401A",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "X401A"),
+		},
 		.driver_data = &quirk_asus_x401u,
 	},
 	{
@@ -95,6 +115,15 @@ static struct dmi_system_id asus_quirks[] = {
 			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
 			DMI_MATCH(DMI_PRODUCT_NAME, "X501U"),
 		},
+		.driver_data = &quirk_asus_x55u,
+	},
+	{
+		.callback = dmi_matched,
+		.ident = "ASUSTeK COMPUTER INC. X501A",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "X501A"),
+		},
 		.driver_data = &quirk_asus_x401u,
 	},
 	{
@@ -131,7 +160,7 @@ static struct dmi_system_id asus_quirks[] = {
 			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
 			DMI_MATCH(DMI_PRODUCT_NAME, "X55U"),
 		},
-		.driver_data = &quirk_asus_x401u,
+		.driver_data = &quirk_asus_x55u,
 	},
 	{
 		.callback = dmi_matched,
diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
index 912ec7d..b4db530 100644
--- a/drivers/platform/x86/asus-wmi.c
+++ b/drivers/platform/x86/asus-wmi.c
@@ -1341,6 +1341,23 @@ static void asus_wmi_backlight_exit(struct asus_wmi *asus)
 	asus->backlight_device = NULL;
 }
 
+static int is_display_toggle(int code)
+{
+	/* display toggle keys */
+	if ((code >= 0x61 && code <= 0x67) ||
+	    (code >= 0x8c && code <= 0x93) ||
+	    (code >= 0xa0 && code <= 0xa7) ||
+	    (code >= 0xd0 && code <= 0xd5))
+		return 1;
+
+	return 0;
+}
+
+static void do_nothing(void)
+{
+	return;
+}
+
 static void asus_wmi_notify(u32 value, void *context)
 {
 	struct asus_wmi *asus = context;
@@ -1380,10 +1397,18 @@ static void asus_wmi_notify(u32 value, void *context)
 		code = NOTIFY_BRNDOWN_MIN;
 
 	if (code == NOTIFY_BRNUP_MIN || code == NOTIFY_BRNDOWN_MIN) {
-		if (!acpi_video_backlight_support())
+		if (!acpi_video_backlight_support()) {
 			asus_wmi_backlight_notify(asus, orig_code);
-	} else if (!sparse_keymap_report_event(asus->inputdev, code,
-					       key_value, autorelease))
+		}
+		goto exit;
+	}
+
+	if (is_display_toggle(code) &&
+	    asus->driver->quirks->no_display_toggle) {
+		goto exit;
+
+	if (!sparse_keymap_report_event(asus->inputdev, code,
+					key_value, autorelease))
 		pr_info("Unknown key %x pressed\n", code);
 
 exit:
diff --git a/drivers/platform/x86/asus-wmi.h b/drivers/platform/x86/asus-wmi.h
index 4c9bd38..776524c 100644
--- a/drivers/platform/x86/asus-wmi.h
+++ b/drivers/platform/x86/asus-wmi.h
@@ -41,6 +41,13 @@ struct quirk_entry {
 	bool store_backlight_power;
 	bool wmi_backlight_power;
 	int wapf;
+	/*
+	 * For machines with AMD graphic chips, it will send out WMI event
+	 * and ACPI interrupt at the same time while hitting the hotkey.
+	 * To simplify the problem, we just have to ignore the WMI event,
+	 * and let the ACPI interrupt to send out the key event.
+	 */
+	int no_display_toggle;
 };
 
 struct asus_wmi_driver {
-- 
1.7.8.6

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ