aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAceLan Kao <acelan.kao@canonical.com>2012-10-03 05:26:31 -0400
committerMatthew Garrett <matthew.garrett@nebula.com>2013-02-24 17:49:55 -0500
commita2a96f0c7221806c8a8072b662e6deaa119833da (patch)
treea82f6c25dab4f4b906275e28909ce3d0d939cd20
parent3da4cd2015630f50d8d80c6ff5089d3daa2306c6 (diff)
asus-wmi: add display toggle quirk
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@canonical.com> Signed-off-by: Corentin Chary <corentincj@iksaif.net> Signed-off-by: Matthew Garrett <matthew.garrett@nebula.com>
-rw-r--r--drivers/platform/x86/asus-nb-wmi.c31
-rw-r--r--drivers/platform/x86/asus-wmi.c31
-rw-r--r--drivers/platform/x86/asus-wmi.h7
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 75ce18c671ff..73e082609755 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 = {
59 .wapf = 0, 59 .wapf = 0,
60}; 60};
61 61
62/*
63 * For those machines that need software to control bt/wifi status
64 * and can't adjust brightness through ACPI interface
65 * and have duplicate events(ACPI and WMI) for display toggle
66 */
67static struct quirk_entry quirk_asus_x55u = {
68 .wapf = 4,
69 .wmi_backlight_power = true,
70 .no_display_toggle = true,
71};
72
62static struct quirk_entry quirk_asus_x401u = { 73static struct quirk_entry quirk_asus_x401u = {
63 .wapf = 4, 74 .wapf = 4,
64}; 75};
@@ -77,6 +88,15 @@ static struct dmi_system_id asus_quirks[] = {
77 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 88 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
78 DMI_MATCH(DMI_PRODUCT_NAME, "X401U"), 89 DMI_MATCH(DMI_PRODUCT_NAME, "X401U"),
79 }, 90 },
91 .driver_data = &quirk_asus_x55u,
92 },
93 {
94 .callback = dmi_matched,
95 .ident = "ASUSTeK COMPUTER INC. X401A",
96 .matches = {
97 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
98 DMI_MATCH(DMI_PRODUCT_NAME, "X401A"),
99 },
80 .driver_data = &quirk_asus_x401u, 100 .driver_data = &quirk_asus_x401u,
81 }, 101 },
82 { 102 {
@@ -95,6 +115,15 @@ static struct dmi_system_id asus_quirks[] = {
95 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 115 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
96 DMI_MATCH(DMI_PRODUCT_NAME, "X501U"), 116 DMI_MATCH(DMI_PRODUCT_NAME, "X501U"),
97 }, 117 },
118 .driver_data = &quirk_asus_x55u,
119 },
120 {
121 .callback = dmi_matched,
122 .ident = "ASUSTeK COMPUTER INC. X501A",
123 .matches = {
124 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
125 DMI_MATCH(DMI_PRODUCT_NAME, "X501A"),
126 },
98 .driver_data = &quirk_asus_x401u, 127 .driver_data = &quirk_asus_x401u,
99 }, 128 },
100 { 129 {
@@ -131,7 +160,7 @@ static struct dmi_system_id asus_quirks[] = {
131 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 160 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
132 DMI_MATCH(DMI_PRODUCT_NAME, "X55U"), 161 DMI_MATCH(DMI_PRODUCT_NAME, "X55U"),
133 }, 162 },
134 .driver_data = &quirk_asus_x401u, 163 .driver_data = &quirk_asus_x55u,
135 }, 164 },
136 { 165 {
137 .callback = dmi_matched, 166 .callback = dmi_matched,
diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
index 912ec7de71f4..208e71c61847 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)
1341 asus->backlight_device = NULL; 1341 asus->backlight_device = NULL;
1342} 1342}
1343 1343
1344static int is_display_toggle(int code)
1345{
1346 /* display toggle keys */
1347 if ((code >= 0x61 && code <= 0x67) ||
1348 (code >= 0x8c && code <= 0x93) ||
1349 (code >= 0xa0 && code <= 0xa7) ||
1350 (code >= 0xd0 && code <= 0xd5))
1351 return 1;
1352
1353 return 0;
1354}
1355
1356static void do_nothing(void)
1357{
1358 return;
1359}
1360
1344static void asus_wmi_notify(u32 value, void *context) 1361static void asus_wmi_notify(u32 value, void *context)
1345{ 1362{
1346 struct asus_wmi *asus = context; 1363 struct asus_wmi *asus = context;
@@ -1380,10 +1397,18 @@ static void asus_wmi_notify(u32 value, void *context)
1380 code = NOTIFY_BRNDOWN_MIN; 1397 code = NOTIFY_BRNDOWN_MIN;
1381 1398
1382 if (code == NOTIFY_BRNUP_MIN || code == NOTIFY_BRNDOWN_MIN) { 1399 if (code == NOTIFY_BRNUP_MIN || code == NOTIFY_BRNDOWN_MIN) {
1383 if (!acpi_video_backlight_support()) 1400 if (!acpi_video_backlight_support()) {
1384 asus_wmi_backlight_notify(asus, orig_code); 1401 asus_wmi_backlight_notify(asus, orig_code);
1385 } else if (!sparse_keymap_report_event(asus->inputdev, code, 1402 }
1386 key_value, autorelease)) 1403 goto exit;
1404 }
1405
1406 if (is_display_toggle(code) &&
1407 asus->driver->quirks->no_display_toggle)
1408 goto exit;
1409
1410 if (!sparse_keymap_report_event(asus->inputdev, code,
1411 key_value, autorelease))
1387 pr_info("Unknown key %x pressed\n", code); 1412 pr_info("Unknown key %x pressed\n", code);
1388 1413
1389exit: 1414exit:
diff --git a/drivers/platform/x86/asus-wmi.h b/drivers/platform/x86/asus-wmi.h
index 4c9bd38bb0a2..776524c725de 100644
--- a/drivers/platform/x86/asus-wmi.h
+++ b/drivers/platform/x86/asus-wmi.h
@@ -41,6 +41,13 @@ struct quirk_entry {
41 bool store_backlight_power; 41 bool store_backlight_power;
42 bool wmi_backlight_power; 42 bool wmi_backlight_power;
43 int wapf; 43 int wapf;
44 /*
45 * For machines with AMD graphic chips, it will send out WMI event
46 * and ACPI interrupt at the same time while hitting the hotkey.
47 * To simplify the problem, we just have to ignore the WMI event,
48 * and let the ACPI interrupt to send out the key event.
49 */
50 int no_display_toggle;
44}; 51};
45 52
46struct asus_wmi_driver { 53struct asus_wmi_driver {