aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/platform
diff options
context:
space:
mode:
authorAceLan Kao <acelan.kao@canonical.com>2012-07-03 23:19:08 -0400
committerMatthew Garrett <mjg@redhat.com>2012-07-28 00:28:53 -0400
commitd2044c5a3aafac552d28c1add16930821c24cbd0 (patch)
tree79c8c162665f644a3152dbd7f0314d6b71e11f43 /drivers/platform
parent0ece8d515c264078a144bc597d0ffc40645ce378 (diff)
asus-nb-wmi: add wapf quirk for ASUS machines
The BIOS of these machines will try to enable/disable wifi/bt in their own sqeuence. It won't read the enable/disable parameter in WMI command, but just iterates the wifi/bt's status described below 1st. enable wifi, enable bt 2nd. disable wifi, enable bt 3rd. enable wifi, disable bt 4th. disable wifi, disable bt That will totally mess up the rfkill status, since we will try to read wifi and bt's status and reset it again while booting up. To avoid this, these machines should set the wapf value to 4, that will let software totally control the wifi/bt's status and BIOS will do nothing instead of sending out the 0x88(KEY_RFKILL) event instead of 0x5e(wifi enable), 0x5f(wifi diable), 0x7d(bt enable), and 0x7e(bt disable) through WMI. With this patch[1], it will handle the KEY_RFKILL event correctly and will block/unblock wifi and bt together. 1. https://lkml.org/lkml/2012/5/21/75 Signed-off-by: AceLan Kao <acelan.kao@canonical.com> Signed-off-by: Matthew Garrett <mjg@redhat.com>
Diffstat (limited to 'drivers/platform')
-rw-r--r--drivers/platform/x86/asus-nb-wmi.c104
1 files changed, 101 insertions, 3 deletions
diff --git a/drivers/platform/x86/asus-nb-wmi.c b/drivers/platform/x86/asus-nb-wmi.c
index 99a30b513137..57712ff1a1de 100644
--- a/drivers/platform/x86/asus-nb-wmi.c
+++ b/drivers/platform/x86/asus-nb-wmi.c
@@ -26,6 +26,7 @@
26#include <linux/input.h> 26#include <linux/input.h>
27#include <linux/input/sparse-keymap.h> 27#include <linux/input/sparse-keymap.h>
28#include <linux/fb.h> 28#include <linux/fb.h>
29#include <linux/dmi.h>
29 30
30#include "asus-wmi.h" 31#include "asus-wmi.h"
31 32
@@ -48,18 +49,115 @@ MODULE_ALIAS("wmi:"ASUS_NB_WMI_EVENT_GUID);
48 * 1 | Hardware | Software 49 * 1 | Hardware | Software
49 * 4 | Software | Software 50 * 4 | Software | Software
50 */ 51 */
51static uint wapf; 52static int wapf = -1;
52module_param(wapf, uint, 0444); 53module_param(wapf, uint, 0444);
53MODULE_PARM_DESC(wapf, "WAPF value"); 54MODULE_PARM_DESC(wapf, "WAPF value");
54 55
56static struct quirk_entry *quirks;
57
55static struct quirk_entry quirk_asus_unknown = { 58static struct quirk_entry quirk_asus_unknown = {
59 .wapf = 0,
60};
61
62static struct quirk_entry quirk_asus_x401u = {
63 .wapf = 4,
64};
65
66static int dmi_matched(const struct dmi_system_id *dmi)
67{
68 quirks = dmi->driver_data;
69 return 1;
70}
71
72static struct dmi_system_id asus_quirks[] = {
73 {
74 .callback = dmi_matched,
75 .ident = "ASUSTeK COMPUTER INC. X401U",
76 .matches = {
77 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
78 DMI_MATCH(DMI_PRODUCT_NAME, "X401U"),
79 },
80 .driver_data = &quirk_asus_x401u,
81 },
82 {
83 .callback = dmi_matched,
84 .ident = "ASUSTeK COMPUTER INC. X401A1",
85 .matches = {
86 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
87 DMI_MATCH(DMI_PRODUCT_NAME, "X401A1"),
88 },
89 .driver_data = &quirk_asus_x401u,
90 },
91 {
92 .callback = dmi_matched,
93 .ident = "ASUSTeK COMPUTER INC. X501U",
94 .matches = {
95 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
96 DMI_MATCH(DMI_PRODUCT_NAME, "X501U"),
97 },
98 .driver_data = &quirk_asus_x401u,
99 },
100 {
101 .callback = dmi_matched,
102 .ident = "ASUSTeK COMPUTER INC. X501A1",
103 .matches = {
104 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
105 DMI_MATCH(DMI_PRODUCT_NAME, "X501A1"),
106 },
107 .driver_data = &quirk_asus_x401u,
108 },
109 {
110 .callback = dmi_matched,
111 .ident = "ASUSTeK COMPUTER INC. X55A",
112 .matches = {
113 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
114 DMI_MATCH(DMI_PRODUCT_NAME, "X55A"),
115 },
116 .driver_data = &quirk_asus_x401u,
117 },
118 {
119 .callback = dmi_matched,
120 .ident = "ASUSTeK COMPUTER INC. X55C",
121 .matches = {
122 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
123 DMI_MATCH(DMI_PRODUCT_NAME, "X55C"),
124 },
125 .driver_data = &quirk_asus_x401u,
126 },
127 {
128 .callback = dmi_matched,
129 .ident = "ASUSTeK COMPUTER INC. X55U",
130 .matches = {
131 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
132 DMI_MATCH(DMI_PRODUCT_NAME, "X55U"),
133 },
134 .driver_data = &quirk_asus_x401u,
135 },
136 {
137 .callback = dmi_matched,
138 .ident = "ASUSTeK COMPUTER INC. X55VD",
139 .matches = {
140 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
141 DMI_MATCH(DMI_PRODUCT_NAME, "X55VD"),
142 },
143 .driver_data = &quirk_asus_x401u,
144 },
145 {},
56}; 146};
57 147
58static void asus_nb_wmi_quirks(struct asus_wmi_driver *driver) 148static void asus_nb_wmi_quirks(struct asus_wmi_driver *driver)
59{ 149{
60 driver->quirks = &quirk_asus_unknown; 150 quirks = &quirk_asus_unknown;
61 driver->quirks->wapf = wapf; 151 dmi_check_system(asus_quirks);
152
153 driver->quirks = quirks;
62 driver->panel_power = FB_BLANK_UNBLANK; 154 driver->panel_power = FB_BLANK_UNBLANK;
155
156 /* overwrite the wapf setting if the wapf paramater is specified */
157 if (wapf != -1)
158 quirks->wapf = wapf;
159 else
160 wapf = quirks->wapf;
63} 161}
64 162
65static const struct key_entry asus_nb_wmi_keymap[] = { 163static const struct key_entry asus_nb_wmi_keymap[] = {