1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Acer WMI Laptop Extras
5 * Copyright (C) 2007-2009 Carlos Corbacho <carlos@strangeworlds.co.uk>
8 * Copyright (C) 2005-2007 E.M. Smith
9 * Copyright (C) 2007-2008 Carlos Corbacho <cathectic@gmail.com>
12 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
14 #include <linux/kernel.h>
15 #include <linux/module.h>
16 #include <linux/init.h>
17 #include <linux/types.h>
18 #include <linux/dmi.h>
19 #include <linux/backlight.h>
20 #include <linux/leds.h>
21 #include <linux/platform_device.h>
22 #include <linux/platform_profile.h>
23 #include <linux/acpi.h>
24 #include <linux/i8042.h>
25 #include <linux/rfkill.h>
26 #include <linux/workqueue.h>
27 #include <linux/debugfs.h>
28 #include <linux/slab.h>
29 #include <linux/input.h>
30 #include <linux/input/sparse-keymap.h>
31 #include <acpi/video.h>
32 #include <linux/hwmon.h>
33 #include <linux/bitfield.h>
35 MODULE_AUTHOR("Carlos Corbacho");
36 MODULE_DESCRIPTION("Acer Laptop WMI Extras Driver");
37 MODULE_LICENSE("GPL");
41 * Meaning is unknown - this number is required for writing to ACPI for AMW0
42 * (it's also used in acerhk when directly accessing the BIOS)
44 #define ACER_AMW0_WRITE 0x9610
47 * Bit masks for the AMW0 interface
49 #define ACER_AMW0_WIRELESS_MASK 0x35
50 #define ACER_AMW0_BLUETOOTH_MASK 0x34
51 #define ACER_AMW0_MAILLED_MASK 0x31
54 * Method IDs for WMID interface
56 #define ACER_WMID_GET_WIRELESS_METHODID 1
57 #define ACER_WMID_GET_BLUETOOTH_METHODID 2
58 #define ACER_WMID_GET_BRIGHTNESS_METHODID 3
59 #define ACER_WMID_SET_WIRELESS_METHODID 4
60 #define ACER_WMID_SET_BLUETOOTH_METHODID 5
61 #define ACER_WMID_SET_BRIGHTNESS_METHODID 6
62 #define ACER_WMID_GET_THREEG_METHODID 10
63 #define ACER_WMID_SET_THREEG_METHODID 11
65 #define ACER_WMID_SET_GAMING_LED_METHODID 2
66 #define ACER_WMID_GET_GAMING_LED_METHODID 4
67 #define ACER_WMID_GET_GAMING_SYS_INFO_METHODID 5
68 #define ACER_WMID_SET_GAMING_FAN_BEHAVIOR 14
69 #define ACER_WMID_SET_GAMING_MISC_SETTING_METHODID 22
71 #define ACER_PREDATOR_V4_THERMAL_PROFILE_EC_OFFSET 0x54
73 #define ACER_PREDATOR_V4_FAN_SPEED_READ_BIT_MASK GENMASK(20, 8)
76 * Acer ACPI method GUIDs
78 #define AMW0_GUID1 "67C3371D-95A3-4C37-BB61-DD47B491DAAB"
79 #define AMW0_GUID2 "431F16ED-0C2B-444C-B267-27DEB140CF9C"
80 #define WMID_GUID1 "6AF4F258-B401-42FD-BE91-3D4AC2D7C0D3"
81 #define WMID_GUID2 "95764E09-FB56-4E83-B31A-37761F60994A"
82 #define WMID_GUID3 "61EF69EA-865C-4BC3-A502-A0DEBA0CB531"
83 #define WMID_GUID4 "7A4DDFE7-5B5D-40B4-8595-4408E0CC7F56"
86 * Acer ACPI event GUIDs
88 #define ACERWMID_EVENT_GUID "676AA15E-6A47-4D9F-A2CC-1E6D18D14026"
90 MODULE_ALIAS("wmi:67C3371D-95A3-4C37-BB61-DD47B491DAAB");
91 MODULE_ALIAS("wmi:6AF4F258-B401-42FD-BE91-3D4AC2D7C0D3");
92 MODULE_ALIAS("wmi:676AA15E-6A47-4D9F-A2CC-1E6D18D14026");
94 enum acer_wmi_event_ids
{
95 WMID_HOTKEY_EVENT
= 0x1,
96 WMID_ACCEL_OR_KBD_DOCK_EVENT
= 0x5,
97 WMID_GAMING_TURBO_KEY_EVENT
= 0x7,
100 enum acer_wmi_predator_v4_sys_info_command
{
101 ACER_WMID_CMD_GET_PREDATOR_V4_BAT_STATUS
= 0x02,
102 ACER_WMID_CMD_GET_PREDATOR_V4_CPU_FAN_SPEED
= 0x0201,
103 ACER_WMID_CMD_GET_PREDATOR_V4_GPU_FAN_SPEED
= 0x0601,
106 static const struct key_entry acer_wmi_keymap
[] __initconst
= {
107 {KE_KEY
, 0x01, {KEY_WLAN
} }, /* WiFi */
108 {KE_KEY
, 0x03, {KEY_WLAN
} }, /* WiFi */
109 {KE_KEY
, 0x04, {KEY_WLAN
} }, /* WiFi */
110 {KE_KEY
, 0x12, {KEY_BLUETOOTH
} }, /* BT */
111 {KE_KEY
, 0x21, {KEY_PROG1
} }, /* Backup */
112 {KE_KEY
, 0x22, {KEY_PROG2
} }, /* Arcade */
113 {KE_KEY
, 0x23, {KEY_PROG3
} }, /* P_Key */
114 {KE_KEY
, 0x24, {KEY_PROG4
} }, /* Social networking_Key */
115 {KE_KEY
, 0x27, {KEY_HELP
} },
116 {KE_KEY
, 0x29, {KEY_PROG3
} }, /* P_Key for TM8372 */
117 {KE_IGNORE
, 0x41, {KEY_MUTE
} },
118 {KE_IGNORE
, 0x42, {KEY_PREVIOUSSONG
} },
119 {KE_IGNORE
, 0x4d, {KEY_PREVIOUSSONG
} },
120 {KE_IGNORE
, 0x43, {KEY_NEXTSONG
} },
121 {KE_IGNORE
, 0x4e, {KEY_NEXTSONG
} },
122 {KE_IGNORE
, 0x44, {KEY_PLAYPAUSE
} },
123 {KE_IGNORE
, 0x4f, {KEY_PLAYPAUSE
} },
124 {KE_IGNORE
, 0x45, {KEY_STOP
} },
125 {KE_IGNORE
, 0x50, {KEY_STOP
} },
126 {KE_IGNORE
, 0x48, {KEY_VOLUMEUP
} },
127 {KE_IGNORE
, 0x49, {KEY_VOLUMEDOWN
} },
128 {KE_IGNORE
, 0x4a, {KEY_VOLUMEDOWN
} },
130 * 0x61 is KEY_SWITCHVIDEOMODE. Usually this is a duplicate input event
131 * with the "Video Bus" input device events. But sometimes it is not
132 * a dup. Map it to KEY_UNKNOWN instead of using KE_IGNORE so that
133 * udev/hwdb can override it on systems where it is not a dup.
135 {KE_KEY
, 0x61, {KEY_UNKNOWN
} },
136 {KE_IGNORE
, 0x62, {KEY_BRIGHTNESSUP
} },
137 {KE_IGNORE
, 0x63, {KEY_BRIGHTNESSDOWN
} },
138 {KE_KEY
, 0x64, {KEY_SWITCHVIDEOMODE
} }, /* Display Switch */
139 {KE_IGNORE
, 0x81, {KEY_SLEEP
} },
140 {KE_KEY
, 0x82, {KEY_TOUCHPAD_TOGGLE
} }, /* Touch Pad Toggle */
141 {KE_IGNORE
, 0x84, {KEY_KBDILLUMTOGGLE
} }, /* Automatic Keyboard background light toggle */
142 {KE_KEY
, KEY_TOUCHPAD_ON
, {KEY_TOUCHPAD_ON
} },
143 {KE_KEY
, KEY_TOUCHPAD_OFF
, {KEY_TOUCHPAD_OFF
} },
144 {KE_IGNORE
, 0x83, {KEY_TOUCHPAD_TOGGLE
} },
145 {KE_KEY
, 0x85, {KEY_TOUCHPAD_TOGGLE
} },
146 {KE_KEY
, 0x86, {KEY_WLAN
} },
147 {KE_KEY
, 0x87, {KEY_POWER
} },
151 static struct input_dev
*acer_wmi_input_dev
;
152 static struct input_dev
*acer_wmi_accel_dev
;
154 struct event_return_value
{
164 * GUID3 Get Device Status device flags
166 #define ACER_WMID3_GDS_WIRELESS (1<<0) /* WiFi */
167 #define ACER_WMID3_GDS_THREEG (1<<6) /* 3G */
168 #define ACER_WMID3_GDS_WIMAX (1<<7) /* WiMAX */
169 #define ACER_WMID3_GDS_BLUETOOTH (1<<11) /* BT */
170 #define ACER_WMID3_GDS_RFBTN (1<<14) /* RF Button */
172 #define ACER_WMID3_GDS_TOUCHPAD (1<<1) /* Touchpad */
174 /* Hotkey Customized Setting and Acer Application Status.
175 * Set Device Default Value and Report Acer Application Status.
176 * When Acer Application starts, it will run this method to inform
177 * BIOS/EC that Acer Application is on.
179 * Bit[0]: Launch Manager Status
181 * Bit[2]: Device Control Status
182 * Bit[3]: Acer Power Button Utility Status
183 * Bit[4]: RF Button Status
184 * Bit[5]: ODD PM Status
185 * Bit[6]: Device Default Value Control
186 * Bit[7]: Hall Sensor Application Status
188 struct func_input_params
{
189 u8 function_num
; /* Function Number */
190 u16 commun_devices
; /* Communication type devices default status */
191 u16 devices
; /* Other type devices default status */
192 u8 app_status
; /* Acer Device Status. LM, ePM, RF Button... */
193 u8 app_mask
; /* Bit mask to app_status */
197 struct func_return_value
{
198 u8 error_code
; /* Error Code */
199 u8 ec_return_value
; /* EC Return Value */
203 struct wmid3_gds_set_input_param
{ /* Set Device Status input parameter */
204 u8 function_num
; /* Function Number */
205 u8 hotkey_number
; /* Hotkey Number */
206 u16 devices
; /* Set Device */
207 u8 volume_value
; /* Volume Value */
210 struct wmid3_gds_get_input_param
{ /* Get Device Status input parameter */
211 u8 function_num
; /* Function Number */
212 u8 hotkey_number
; /* Hotkey Number */
213 u16 devices
; /* Get Device */
216 struct wmid3_gds_return_value
{ /* Get Device Status return value*/
217 u8 error_code
; /* Error Code */
218 u8 ec_return_value
; /* EC Return Value */
219 u16 devices
; /* Current Device Status */
223 struct hotkey_function_type_aa
{
227 u16 commun_func_bitmap
;
228 u16 application_func_bitmap
;
229 u16 media_func_bitmap
;
230 u16 display_func_bitmap
;
231 u16 others_func_bitmap
;
232 u8 commun_fn_key_number
;
236 * Interface capability flags
238 #define ACER_CAP_MAILLED BIT(0)
239 #define ACER_CAP_WIRELESS BIT(1)
240 #define ACER_CAP_BLUETOOTH BIT(2)
241 #define ACER_CAP_BRIGHTNESS BIT(3)
242 #define ACER_CAP_THREEG BIT(4)
243 #define ACER_CAP_SET_FUNCTION_MODE BIT(5)
244 #define ACER_CAP_KBD_DOCK BIT(6)
245 #define ACER_CAP_TURBO_OC BIT(7)
246 #define ACER_CAP_TURBO_LED BIT(8)
247 #define ACER_CAP_TURBO_FAN BIT(9)
248 #define ACER_CAP_PLATFORM_PROFILE BIT(10)
249 #define ACER_CAP_FAN_SPEED_READ BIT(11)
252 * Interface type flags
254 enum interface_flags
{
261 static int max_brightness
= 0xF;
263 static int mailled
= -1;
264 static int brightness
= -1;
265 static int threeg
= -1;
266 static int force_series
;
267 static int force_caps
= -1;
268 static bool ec_raw_mode
;
269 static bool has_type_aa
;
270 static u16 commun_func_bitmap
;
271 static u8 commun_fn_key_number
;
272 static bool cycle_gaming_thermal_profile
= true;
273 static bool predator_v4
;
275 module_param(mailled
, int, 0444);
276 module_param(brightness
, int, 0444);
277 module_param(threeg
, int, 0444);
278 module_param(force_series
, int, 0444);
279 module_param(force_caps
, int, 0444);
280 module_param(ec_raw_mode
, bool, 0444);
281 module_param(cycle_gaming_thermal_profile
, bool, 0644);
282 module_param(predator_v4
, bool, 0444);
283 MODULE_PARM_DESC(mailled
, "Set initial state of Mail LED");
284 MODULE_PARM_DESC(brightness
, "Set initial LCD backlight brightness");
285 MODULE_PARM_DESC(threeg
, "Set initial state of 3G hardware");
286 MODULE_PARM_DESC(force_series
, "Force a different laptop series");
287 MODULE_PARM_DESC(force_caps
, "Force the capability bitmask to this value");
288 MODULE_PARM_DESC(ec_raw_mode
, "Enable EC raw mode");
289 MODULE_PARM_DESC(cycle_gaming_thermal_profile
,
290 "Set thermal mode key in cycle mode. Disabling it sets the mode key in turbo toggle mode");
291 MODULE_PARM_DESC(predator_v4
,
292 "Enable features for predator laptops that use predator sense v4");
305 static struct rfkill
*wireless_rfkill
;
306 static struct rfkill
*bluetooth_rfkill
;
307 static struct rfkill
*threeg_rfkill
;
308 static bool rfkill_inited
;
310 /* Each low-level interface must define at least some of the following */
311 struct wmi_interface
{
312 /* The WMI device type */
315 /* The capabilities this interface provides */
318 /* Private data for the current interface */
319 struct acer_data data
;
321 /* debugfs entries associated with this interface */
322 struct acer_debug debug
;
325 /* The static interface pointer, points to the currently detected interface */
326 static struct wmi_interface
*interface
;
329 * Embedded Controller quirks
330 * Some laptops require us to directly access the EC to either enable or query
331 * features that are not available through WMI.
345 static struct quirk_entry
*quirks
;
347 static void __init
set_quirks(void)
350 interface
->capability
|= ACER_CAP_MAILLED
;
352 if (quirks
->brightness
)
353 interface
->capability
|= ACER_CAP_BRIGHTNESS
;
356 interface
->capability
|= ACER_CAP_TURBO_OC
| ACER_CAP_TURBO_LED
357 | ACER_CAP_TURBO_FAN
;
359 if (quirks
->predator_v4
)
360 interface
->capability
|= ACER_CAP_PLATFORM_PROFILE
|
361 ACER_CAP_FAN_SPEED_READ
;
364 static int __init
dmi_matched(const struct dmi_system_id
*dmi
)
366 quirks
= dmi
->driver_data
;
370 static int __init
set_force_caps(const struct dmi_system_id
*dmi
)
372 if (force_caps
== -1) {
373 force_caps
= (uintptr_t)dmi
->driver_data
;
374 pr_info("Found %s, set force_caps to 0x%x\n", dmi
->ident
, force_caps
);
379 static struct quirk_entry quirk_unknown
= {
382 static struct quirk_entry quirk_acer_aspire_1520
= {
386 static struct quirk_entry quirk_acer_travelmate_2490
= {
390 static struct quirk_entry quirk_acer_predator_ph315_53
= {
396 static struct quirk_entry quirk_acer_predator_v4
= {
400 /* This AMW0 laptop has no bluetooth */
401 static struct quirk_entry quirk_medion_md_98300
= {
405 static struct quirk_entry quirk_fujitsu_amilo_li_1718
= {
409 static struct quirk_entry quirk_lenovo_ideapad_s205
= {
413 /* The Aspire One has a dummy ACPI-WMI interface - disable it */
414 static const struct dmi_system_id acer_blacklist
[] __initconst
= {
416 .ident
= "Acer Aspire One (SSD)",
418 DMI_MATCH(DMI_SYS_VENDOR
, "Acer"),
419 DMI_MATCH(DMI_PRODUCT_NAME
, "AOA110"),
423 .ident
= "Acer Aspire One (HDD)",
425 DMI_MATCH(DMI_SYS_VENDOR
, "Acer"),
426 DMI_MATCH(DMI_PRODUCT_NAME
, "AOA150"),
432 static const struct dmi_system_id amw0_whitelist
[] __initconst
= {
436 DMI_MATCH(DMI_SYS_VENDOR
, "Acer"),
442 DMI_MATCH(DMI_SYS_VENDOR
, "Gateway"),
446 .ident
= "Packard Bell",
448 DMI_MATCH(DMI_SYS_VENDOR
, "Packard Bell"),
455 * This quirk table is only for Acer/Gateway/Packard Bell family
456 * that those machines are supported by acer-wmi driver.
458 static const struct dmi_system_id acer_quirks
[] __initconst
= {
460 .callback
= dmi_matched
,
461 .ident
= "Acer Aspire 1360",
463 DMI_MATCH(DMI_SYS_VENDOR
, "Acer"),
464 DMI_MATCH(DMI_PRODUCT_NAME
, "Aspire 1360"),
466 .driver_data
= &quirk_acer_aspire_1520
,
469 .callback
= dmi_matched
,
470 .ident
= "Acer Aspire 1520",
472 DMI_MATCH(DMI_SYS_VENDOR
, "Acer"),
473 DMI_MATCH(DMI_PRODUCT_NAME
, "Aspire 1520"),
475 .driver_data
= &quirk_acer_aspire_1520
,
478 .callback
= dmi_matched
,
479 .ident
= "Acer Aspire 3100",
481 DMI_MATCH(DMI_SYS_VENDOR
, "Acer"),
482 DMI_MATCH(DMI_PRODUCT_NAME
, "Aspire 3100"),
484 .driver_data
= &quirk_acer_travelmate_2490
,
487 .callback
= dmi_matched
,
488 .ident
= "Acer Aspire 3610",
490 DMI_MATCH(DMI_SYS_VENDOR
, "Acer"),
491 DMI_MATCH(DMI_PRODUCT_NAME
, "Aspire 3610"),
493 .driver_data
= &quirk_acer_travelmate_2490
,
496 .callback
= dmi_matched
,
497 .ident
= "Acer Aspire 5100",
499 DMI_MATCH(DMI_SYS_VENDOR
, "Acer"),
500 DMI_MATCH(DMI_PRODUCT_NAME
, "Aspire 5100"),
502 .driver_data
= &quirk_acer_travelmate_2490
,
505 .callback
= dmi_matched
,
506 .ident
= "Acer Aspire 5610",
508 DMI_MATCH(DMI_SYS_VENDOR
, "Acer"),
509 DMI_MATCH(DMI_PRODUCT_NAME
, "Aspire 5610"),
511 .driver_data
= &quirk_acer_travelmate_2490
,
514 .callback
= dmi_matched
,
515 .ident
= "Acer Aspire 5630",
517 DMI_MATCH(DMI_SYS_VENDOR
, "Acer"),
518 DMI_MATCH(DMI_PRODUCT_NAME
, "Aspire 5630"),
520 .driver_data
= &quirk_acer_travelmate_2490
,
523 .callback
= dmi_matched
,
524 .ident
= "Acer Aspire 5650",
526 DMI_MATCH(DMI_SYS_VENDOR
, "Acer"),
527 DMI_MATCH(DMI_PRODUCT_NAME
, "Aspire 5650"),
529 .driver_data
= &quirk_acer_travelmate_2490
,
532 .callback
= dmi_matched
,
533 .ident
= "Acer Aspire 5680",
535 DMI_MATCH(DMI_SYS_VENDOR
, "Acer"),
536 DMI_MATCH(DMI_PRODUCT_NAME
, "Aspire 5680"),
538 .driver_data
= &quirk_acer_travelmate_2490
,
541 .callback
= dmi_matched
,
542 .ident
= "Acer Aspire 9110",
544 DMI_MATCH(DMI_SYS_VENDOR
, "Acer"),
545 DMI_MATCH(DMI_PRODUCT_NAME
, "Aspire 9110"),
547 .driver_data
= &quirk_acer_travelmate_2490
,
550 .callback
= dmi_matched
,
551 .ident
= "Acer TravelMate 2490",
553 DMI_MATCH(DMI_SYS_VENDOR
, "Acer"),
554 DMI_MATCH(DMI_PRODUCT_NAME
, "TravelMate 2490"),
556 .driver_data
= &quirk_acer_travelmate_2490
,
559 .callback
= dmi_matched
,
560 .ident
= "Acer TravelMate 4200",
562 DMI_MATCH(DMI_SYS_VENDOR
, "Acer"),
563 DMI_MATCH(DMI_PRODUCT_NAME
, "TravelMate 4200"),
565 .driver_data
= &quirk_acer_travelmate_2490
,
568 .callback
= dmi_matched
,
569 .ident
= "Acer Predator PH315-53",
571 DMI_MATCH(DMI_SYS_VENDOR
, "Acer"),
572 DMI_MATCH(DMI_PRODUCT_NAME
, "Predator PH315-53"),
574 .driver_data
= &quirk_acer_predator_ph315_53
,
577 .callback
= dmi_matched
,
578 .ident
= "Acer Predator PHN16-71",
580 DMI_MATCH(DMI_SYS_VENDOR
, "Acer"),
581 DMI_MATCH(DMI_PRODUCT_NAME
, "Predator PHN16-71"),
583 .driver_data
= &quirk_acer_predator_v4
,
586 .callback
= dmi_matched
,
587 .ident
= "Acer Predator PH16-71",
589 DMI_MATCH(DMI_SYS_VENDOR
, "Acer"),
590 DMI_MATCH(DMI_PRODUCT_NAME
, "Predator PH16-71"),
592 .driver_data
= &quirk_acer_predator_v4
,
595 .callback
= dmi_matched
,
596 .ident
= "Acer Predator PH18-71",
598 DMI_MATCH(DMI_SYS_VENDOR
, "Acer"),
599 DMI_MATCH(DMI_PRODUCT_NAME
, "Predator PH18-71"),
601 .driver_data
= &quirk_acer_predator_v4
,
604 .callback
= set_force_caps
,
605 .ident
= "Acer Aspire Switch 10E SW3-016",
607 DMI_MATCH(DMI_SYS_VENDOR
, "Acer"),
608 DMI_MATCH(DMI_PRODUCT_NAME
, "Aspire SW3-016"),
610 .driver_data
= (void *)ACER_CAP_KBD_DOCK
,
613 .callback
= set_force_caps
,
614 .ident
= "Acer Aspire Switch 10 SW5-012",
616 DMI_MATCH(DMI_SYS_VENDOR
, "Acer"),
617 DMI_MATCH(DMI_PRODUCT_NAME
, "Aspire SW5-012"),
619 .driver_data
= (void *)ACER_CAP_KBD_DOCK
,
622 .callback
= set_force_caps
,
623 .ident
= "Acer Aspire Switch V 10 SW5-017",
625 DMI_EXACT_MATCH(DMI_SYS_VENDOR
, "Acer"),
626 DMI_EXACT_MATCH(DMI_PRODUCT_NAME
, "SW5-017"),
628 .driver_data
= (void *)ACER_CAP_KBD_DOCK
,
631 .callback
= set_force_caps
,
632 .ident
= "Acer One 10 (S1003)",
634 DMI_EXACT_MATCH(DMI_SYS_VENDOR
, "Acer"),
635 DMI_EXACT_MATCH(DMI_PRODUCT_NAME
, "One S1003"),
637 .driver_data
= (void *)ACER_CAP_KBD_DOCK
,
643 * This quirk list is for those non-acer machines that have AMW0_GUID1
644 * but supported by acer-wmi in past days. Keeping this quirk list here
645 * is only for backward compatible. Please do not add new machine to
646 * here anymore. Those non-acer machines should be supported by
647 * appropriate wmi drivers.
649 static const struct dmi_system_id non_acer_quirks
[] __initconst
= {
651 .callback
= dmi_matched
,
652 .ident
= "Fujitsu Siemens Amilo Li 1718",
654 DMI_MATCH(DMI_SYS_VENDOR
, "FUJITSU SIEMENS"),
655 DMI_MATCH(DMI_PRODUCT_NAME
, "AMILO Li 1718"),
657 .driver_data
= &quirk_fujitsu_amilo_li_1718
,
660 .callback
= dmi_matched
,
661 .ident
= "Medion MD 98300",
663 DMI_MATCH(DMI_SYS_VENDOR
, "MEDION"),
664 DMI_MATCH(DMI_PRODUCT_NAME
, "WAM2030"),
666 .driver_data
= &quirk_medion_md_98300
,
669 .callback
= dmi_matched
,
670 .ident
= "Lenovo Ideapad S205",
672 DMI_MATCH(DMI_SYS_VENDOR
, "LENOVO"),
673 DMI_MATCH(DMI_PRODUCT_NAME
, "10382LG"),
675 .driver_data
= &quirk_lenovo_ideapad_s205
,
678 .callback
= dmi_matched
,
679 .ident
= "Lenovo Ideapad S205 (Brazos)",
681 DMI_MATCH(DMI_SYS_VENDOR
, "LENOVO"),
682 DMI_MATCH(DMI_PRODUCT_NAME
, "Brazos"),
684 .driver_data
= &quirk_lenovo_ideapad_s205
,
687 .callback
= dmi_matched
,
688 .ident
= "Lenovo 3000 N200",
690 DMI_MATCH(DMI_SYS_VENDOR
, "LENOVO"),
691 DMI_MATCH(DMI_PRODUCT_NAME
, "0687A31"),
693 .driver_data
= &quirk_fujitsu_amilo_li_1718
,
696 .callback
= dmi_matched
,
697 .ident
= "Lenovo Ideapad S205-10382JG",
699 DMI_MATCH(DMI_SYS_VENDOR
, "LENOVO"),
700 DMI_MATCH(DMI_PRODUCT_NAME
, "10382JG"),
702 .driver_data
= &quirk_lenovo_ideapad_s205
,
705 .callback
= dmi_matched
,
706 .ident
= "Lenovo Ideapad S205-1038DPG",
708 DMI_MATCH(DMI_SYS_VENDOR
, "LENOVO"),
709 DMI_MATCH(DMI_PRODUCT_NAME
, "1038DPG"),
711 .driver_data
= &quirk_lenovo_ideapad_s205
,
716 static struct platform_profile_handler platform_profile_handler
;
717 static bool platform_profile_support
;
720 * The profile used before turbo mode. This variable is needed for
721 * returning from turbo mode when the mode key is in toggle mode.
723 static int last_non_turbo_profile
;
725 enum acer_predator_v4_thermal_profile_ec
{
726 ACER_PREDATOR_V4_THERMAL_PROFILE_ECO
= 0x04,
727 ACER_PREDATOR_V4_THERMAL_PROFILE_TURBO
= 0x03,
728 ACER_PREDATOR_V4_THERMAL_PROFILE_PERFORMANCE
= 0x02,
729 ACER_PREDATOR_V4_THERMAL_PROFILE_QUIET
= 0x01,
730 ACER_PREDATOR_V4_THERMAL_PROFILE_BALANCED
= 0x00,
733 enum acer_predator_v4_thermal_profile_wmi
{
734 ACER_PREDATOR_V4_THERMAL_PROFILE_ECO_WMI
= 0x060B,
735 ACER_PREDATOR_V4_THERMAL_PROFILE_TURBO_WMI
= 0x050B,
736 ACER_PREDATOR_V4_THERMAL_PROFILE_PERFORMANCE_WMI
= 0x040B,
737 ACER_PREDATOR_V4_THERMAL_PROFILE_QUIET_WMI
= 0x0B,
738 ACER_PREDATOR_V4_THERMAL_PROFILE_BALANCED_WMI
= 0x010B,
741 /* Find which quirks are needed for a particular vendor/ model pair */
742 static void __init
find_quirks(void)
745 quirks
= &quirk_acer_predator_v4
;
746 } else if (!force_series
) {
747 dmi_check_system(acer_quirks
);
748 dmi_check_system(non_acer_quirks
);
749 } else if (force_series
== 2490) {
750 quirks
= &quirk_acer_travelmate_2490
;
754 quirks
= &quirk_unknown
;
758 * General interface convenience methods
761 static bool has_cap(u32 cap
)
763 return interface
->capability
& cap
;
767 * AMW0 (V1) interface
784 static acpi_status
wmab_execute(struct wmab_args
*regbuf
,
785 struct acpi_buffer
*result
)
787 struct acpi_buffer input
;
789 input
.length
= sizeof(struct wmab_args
);
790 input
.pointer
= (u8
*)regbuf
;
792 status
= wmi_evaluate_method(AMW0_GUID1
, 0, 1, &input
, result
);
797 static acpi_status
AMW0_get_u32(u32
*value
, u32 cap
)
803 case ACER_CAP_MAILLED
:
804 switch (quirks
->mailled
) {
806 err
= ec_read(0xA, &result
);
809 *value
= (result
>> 7) & 0x1;
813 case ACER_CAP_WIRELESS
:
814 switch (quirks
->wireless
) {
816 err
= ec_read(0x7B, &result
);
819 *value
= result
& 0x1;
822 err
= ec_read(0x71, &result
);
825 *value
= result
& 0x1;
828 err
= ec_read(0x78, &result
);
831 *value
= result
& 0x1;
834 err
= ec_read(0xA, &result
);
837 *value
= (result
>> 2) & 0x1;
841 case ACER_CAP_BLUETOOTH
:
842 switch (quirks
->bluetooth
) {
844 err
= ec_read(0xA, &result
);
847 *value
= (result
>> 4) & 0x1;
851 case ACER_CAP_BRIGHTNESS
:
852 switch (quirks
->brightness
) {
854 err
= ec_read(0x83, &result
);
867 static acpi_status
AMW0_set_u32(u32 value
, u32 cap
)
869 struct wmab_args args
;
871 args
.eax
= ACER_AMW0_WRITE
;
872 args
.ebx
= value
? (1<<8) : 0;
873 args
.ecx
= args
.edx
= 0;
876 case ACER_CAP_MAILLED
:
878 return AE_BAD_PARAMETER
;
879 args
.ebx
|= ACER_AMW0_MAILLED_MASK
;
881 case ACER_CAP_WIRELESS
:
883 return AE_BAD_PARAMETER
;
884 args
.ebx
|= ACER_AMW0_WIRELESS_MASK
;
886 case ACER_CAP_BLUETOOTH
:
888 return AE_BAD_PARAMETER
;
889 args
.ebx
|= ACER_AMW0_BLUETOOTH_MASK
;
891 case ACER_CAP_BRIGHTNESS
:
892 if (value
> max_brightness
)
893 return AE_BAD_PARAMETER
;
894 switch (quirks
->brightness
) {
896 return ec_write(0x83, value
);
902 /* Actually do the set */
903 return wmab_execute(&args
, NULL
);
906 static acpi_status __init
AMW0_find_mailled(void)
908 struct wmab_args args
;
910 acpi_status status
= AE_OK
;
911 struct acpi_buffer out
= { ACPI_ALLOCATE_BUFFER
, NULL
};
912 union acpi_object
*obj
;
915 args
.ebx
= args
.ecx
= args
.edx
= 0;
917 status
= wmab_execute(&args
, &out
);
918 if (ACPI_FAILURE(status
))
921 obj
= (union acpi_object
*) out
.pointer
;
922 if (obj
&& obj
->type
== ACPI_TYPE_BUFFER
&&
923 obj
->buffer
.length
== sizeof(struct wmab_ret
)) {
924 ret
= *((struct wmab_ret
*) obj
->buffer
.pointer
);
931 interface
->capability
|= ACER_CAP_MAILLED
;
938 static const struct acpi_device_id norfkill_ids
[] __initconst
= {
942 { "SNY5001", 0}, /* sony-laptop in charge */
947 static int __init
AMW0_set_cap_acpi_check_device(void)
949 const struct acpi_device_id
*id
;
951 for (id
= norfkill_ids
; id
->id
[0]; id
++)
952 if (acpi_dev_found(id
->id
))
958 static acpi_status __init
AMW0_set_capabilities(void)
960 struct wmab_args args
;
963 struct acpi_buffer out
= { ACPI_ALLOCATE_BUFFER
, NULL
};
964 union acpi_object
*obj
;
967 * On laptops with this strange GUID (non Acer), normal probing doesn't
970 if (wmi_has_guid(AMW0_GUID2
)) {
971 if ((quirks
!= &quirk_unknown
) ||
972 !AMW0_set_cap_acpi_check_device())
973 interface
->capability
|= ACER_CAP_WIRELESS
;
977 args
.eax
= ACER_AMW0_WRITE
;
978 args
.ecx
= args
.edx
= 0;
980 args
.ebx
= 0xa2 << 8;
981 args
.ebx
|= ACER_AMW0_WIRELESS_MASK
;
983 status
= wmab_execute(&args
, &out
);
984 if (ACPI_FAILURE(status
))
988 if (obj
&& obj
->type
== ACPI_TYPE_BUFFER
&&
989 obj
->buffer
.length
== sizeof(struct wmab_ret
)) {
990 ret
= *((struct wmab_ret
*) obj
->buffer
.pointer
);
997 interface
->capability
|= ACER_CAP_WIRELESS
;
1000 args
.ebx
|= ACER_AMW0_BLUETOOTH_MASK
;
1003 * It's ok to use existing buffer for next wmab_execute call.
1004 * But we need to kfree(out.pointer) if next wmab_execute fail.
1006 status
= wmab_execute(&args
, &out
);
1007 if (ACPI_FAILURE(status
))
1010 obj
= (union acpi_object
*) out
.pointer
;
1011 if (obj
&& obj
->type
== ACPI_TYPE_BUFFER
1012 && obj
->buffer
.length
== sizeof(struct wmab_ret
)) {
1013 ret
= *((struct wmab_ret
*) obj
->buffer
.pointer
);
1020 interface
->capability
|= ACER_CAP_BLUETOOTH
;
1023 * This appears to be safe to enable, since all Wistron based laptops
1024 * appear to use the same EC register for brightness, even if they
1025 * differ for wireless, etc
1027 if (quirks
->brightness
>= 0)
1028 interface
->capability
|= ACER_CAP_BRIGHTNESS
;
1036 static struct wmi_interface AMW0_interface
= {
1040 static struct wmi_interface AMW0_V2_interface
= {
1041 .type
= ACER_AMW0_V2
,
1045 * New interface (The WMID interface)
1048 WMI_execute_u32(u32 method_id
, u32 in
, u32
*out
)
1050 struct acpi_buffer input
= { (acpi_size
) sizeof(u32
), (void *)(&in
) };
1051 struct acpi_buffer result
= { ACPI_ALLOCATE_BUFFER
, NULL
};
1052 union acpi_object
*obj
;
1056 status
= wmi_evaluate_method(WMID_GUID1
, 0, method_id
, &input
, &result
);
1058 if (ACPI_FAILURE(status
))
1061 obj
= (union acpi_object
*) result
.pointer
;
1063 if (obj
->type
== ACPI_TYPE_BUFFER
&&
1064 (obj
->buffer
.length
== sizeof(u32
) ||
1065 obj
->buffer
.length
== sizeof(u64
))) {
1066 tmp
= *((u32
*) obj
->buffer
.pointer
);
1067 } else if (obj
->type
== ACPI_TYPE_INTEGER
) {
1068 tmp
= (u32
) obj
->integer
.value
;
1075 kfree(result
.pointer
);
1080 static acpi_status
WMID_get_u32(u32
*value
, u32 cap
)
1084 u32 result
, method_id
= 0;
1087 case ACER_CAP_WIRELESS
:
1088 method_id
= ACER_WMID_GET_WIRELESS_METHODID
;
1090 case ACER_CAP_BLUETOOTH
:
1091 method_id
= ACER_WMID_GET_BLUETOOTH_METHODID
;
1093 case ACER_CAP_BRIGHTNESS
:
1094 method_id
= ACER_WMID_GET_BRIGHTNESS_METHODID
;
1096 case ACER_CAP_THREEG
:
1097 method_id
= ACER_WMID_GET_THREEG_METHODID
;
1099 case ACER_CAP_MAILLED
:
1100 if (quirks
->mailled
== 1) {
1101 ec_read(0x9f, &tmp
);
1109 status
= WMI_execute_u32(method_id
, 0, &result
);
1111 if (ACPI_SUCCESS(status
))
1112 *value
= (u8
)result
;
1117 static acpi_status
WMID_set_u32(u32 value
, u32 cap
)
1123 case ACER_CAP_BRIGHTNESS
:
1124 if (value
> max_brightness
)
1125 return AE_BAD_PARAMETER
;
1126 method_id
= ACER_WMID_SET_BRIGHTNESS_METHODID
;
1128 case ACER_CAP_WIRELESS
:
1130 return AE_BAD_PARAMETER
;
1131 method_id
= ACER_WMID_SET_WIRELESS_METHODID
;
1133 case ACER_CAP_BLUETOOTH
:
1135 return AE_BAD_PARAMETER
;
1136 method_id
= ACER_WMID_SET_BLUETOOTH_METHODID
;
1138 case ACER_CAP_THREEG
:
1140 return AE_BAD_PARAMETER
;
1141 method_id
= ACER_WMID_SET_THREEG_METHODID
;
1143 case ACER_CAP_MAILLED
:
1145 return AE_BAD_PARAMETER
;
1146 if (quirks
->mailled
== 1) {
1147 param
= value
? 0x92 : 0x93;
1149 i8042_command(¶m
, 0x1059);
1150 i8042_unlock_chip();
1157 return WMI_execute_u32(method_id
, (u32
)value
, NULL
);
1160 static acpi_status
wmid3_get_device_status(u32
*value
, u16 device
)
1162 struct wmid3_gds_return_value return_value
;
1164 union acpi_object
*obj
;
1165 struct wmid3_gds_get_input_param params
= {
1166 .function_num
= 0x1,
1167 .hotkey_number
= commun_fn_key_number
,
1170 struct acpi_buffer input
= {
1171 sizeof(struct wmid3_gds_get_input_param
),
1174 struct acpi_buffer output
= { ACPI_ALLOCATE_BUFFER
, NULL
};
1176 status
= wmi_evaluate_method(WMID_GUID3
, 0, 0x2, &input
, &output
);
1177 if (ACPI_FAILURE(status
))
1180 obj
= output
.pointer
;
1184 else if (obj
->type
!= ACPI_TYPE_BUFFER
) {
1188 if (obj
->buffer
.length
!= 8) {
1189 pr_warn("Unknown buffer length %d\n", obj
->buffer
.length
);
1194 return_value
= *((struct wmid3_gds_return_value
*)obj
->buffer
.pointer
);
1197 if (return_value
.error_code
|| return_value
.ec_return_value
)
1198 pr_warn("Get 0x%x Device Status failed: 0x%x - 0x%x\n",
1200 return_value
.error_code
,
1201 return_value
.ec_return_value
);
1203 *value
= !!(return_value
.devices
& device
);
1208 static acpi_status
wmid_v2_get_u32(u32
*value
, u32 cap
)
1213 case ACER_CAP_WIRELESS
:
1214 device
= ACER_WMID3_GDS_WIRELESS
;
1216 case ACER_CAP_BLUETOOTH
:
1217 device
= ACER_WMID3_GDS_BLUETOOTH
;
1219 case ACER_CAP_THREEG
:
1220 device
= ACER_WMID3_GDS_THREEG
;
1225 return wmid3_get_device_status(value
, device
);
1228 static acpi_status
wmid3_set_device_status(u32 value
, u16 device
)
1230 struct wmid3_gds_return_value return_value
;
1232 union acpi_object
*obj
;
1234 struct wmid3_gds_get_input_param get_params
= {
1235 .function_num
= 0x1,
1236 .hotkey_number
= commun_fn_key_number
,
1237 .devices
= commun_func_bitmap
,
1239 struct acpi_buffer get_input
= {
1240 sizeof(struct wmid3_gds_get_input_param
),
1243 struct wmid3_gds_set_input_param set_params
= {
1244 .function_num
= 0x2,
1245 .hotkey_number
= commun_fn_key_number
,
1246 .devices
= commun_func_bitmap
,
1248 struct acpi_buffer set_input
= {
1249 sizeof(struct wmid3_gds_set_input_param
),
1252 struct acpi_buffer output
= { ACPI_ALLOCATE_BUFFER
, NULL
};
1253 struct acpi_buffer output2
= { ACPI_ALLOCATE_BUFFER
, NULL
};
1255 status
= wmi_evaluate_method(WMID_GUID3
, 0, 0x2, &get_input
, &output
);
1256 if (ACPI_FAILURE(status
))
1259 obj
= output
.pointer
;
1263 else if (obj
->type
!= ACPI_TYPE_BUFFER
) {
1267 if (obj
->buffer
.length
!= 8) {
1268 pr_warn("Unknown buffer length %d\n", obj
->buffer
.length
);
1273 return_value
= *((struct wmid3_gds_return_value
*)obj
->buffer
.pointer
);
1276 if (return_value
.error_code
|| return_value
.ec_return_value
) {
1277 pr_warn("Get Current Device Status failed: 0x%x - 0x%x\n",
1278 return_value
.error_code
,
1279 return_value
.ec_return_value
);
1283 devices
= return_value
.devices
;
1284 set_params
.devices
= (value
) ? (devices
| device
) : (devices
& ~device
);
1286 status
= wmi_evaluate_method(WMID_GUID3
, 0, 0x1, &set_input
, &output2
);
1287 if (ACPI_FAILURE(status
))
1290 obj
= output2
.pointer
;
1294 else if (obj
->type
!= ACPI_TYPE_BUFFER
) {
1298 if (obj
->buffer
.length
!= 4) {
1299 pr_warn("Unknown buffer length %d\n", obj
->buffer
.length
);
1304 return_value
= *((struct wmid3_gds_return_value
*)obj
->buffer
.pointer
);
1307 if (return_value
.error_code
|| return_value
.ec_return_value
)
1308 pr_warn("Set Device Status failed: 0x%x - 0x%x\n",
1309 return_value
.error_code
,
1310 return_value
.ec_return_value
);
1315 static acpi_status
wmid_v2_set_u32(u32 value
, u32 cap
)
1320 case ACER_CAP_WIRELESS
:
1321 device
= ACER_WMID3_GDS_WIRELESS
;
1323 case ACER_CAP_BLUETOOTH
:
1324 device
= ACER_WMID3_GDS_BLUETOOTH
;
1326 case ACER_CAP_THREEG
:
1327 device
= ACER_WMID3_GDS_THREEG
;
1332 return wmid3_set_device_status(value
, device
);
1335 static void __init
type_aa_dmi_decode(const struct dmi_header
*header
, void *d
)
1337 struct hotkey_function_type_aa
*type_aa
;
1339 /* We are looking for OEM-specific Type AAh */
1340 if (header
->type
!= 0xAA)
1344 type_aa
= (struct hotkey_function_type_aa
*) header
;
1346 pr_info("Function bitmap for Communication Button: 0x%x\n",
1347 type_aa
->commun_func_bitmap
);
1348 commun_func_bitmap
= type_aa
->commun_func_bitmap
;
1350 if (type_aa
->commun_func_bitmap
& ACER_WMID3_GDS_WIRELESS
)
1351 interface
->capability
|= ACER_CAP_WIRELESS
;
1352 if (type_aa
->commun_func_bitmap
& ACER_WMID3_GDS_THREEG
)
1353 interface
->capability
|= ACER_CAP_THREEG
;
1354 if (type_aa
->commun_func_bitmap
& ACER_WMID3_GDS_BLUETOOTH
)
1355 interface
->capability
|= ACER_CAP_BLUETOOTH
;
1356 if (type_aa
->commun_func_bitmap
& ACER_WMID3_GDS_RFBTN
)
1357 commun_func_bitmap
&= ~ACER_WMID3_GDS_RFBTN
;
1359 commun_fn_key_number
= type_aa
->commun_fn_key_number
;
1362 static acpi_status __init
WMID_set_capabilities(void)
1364 struct acpi_buffer out
= {ACPI_ALLOCATE_BUFFER
, NULL
};
1365 union acpi_object
*obj
;
1369 status
= wmi_query_block(WMID_GUID2
, 0, &out
);
1370 if (ACPI_FAILURE(status
))
1373 obj
= (union acpi_object
*) out
.pointer
;
1375 if (obj
->type
== ACPI_TYPE_BUFFER
&&
1376 (obj
->buffer
.length
== sizeof(u32
) ||
1377 obj
->buffer
.length
== sizeof(u64
))) {
1378 devices
= *((u32
*) obj
->buffer
.pointer
);
1379 } else if (obj
->type
== ACPI_TYPE_INTEGER
) {
1380 devices
= (u32
) obj
->integer
.value
;
1390 pr_info("Function bitmap for Communication Device: 0x%x\n", devices
);
1392 interface
->capability
|= ACER_CAP_WIRELESS
;
1394 interface
->capability
|= ACER_CAP_THREEG
;
1396 interface
->capability
|= ACER_CAP_BLUETOOTH
;
1398 if (!(devices
& 0x20))
1399 max_brightness
= 0x9;
1405 static struct wmi_interface wmid_interface
= {
1409 static struct wmi_interface wmid_v2_interface
= {
1410 .type
= ACER_WMID_v2
,
1414 * WMID Gaming interface
1418 WMI_gaming_execute_u64(u32 method_id
, u64 in
, u64
*out
)
1420 struct acpi_buffer input
= { (acpi_size
) sizeof(u64
), (void *)(&in
) };
1421 struct acpi_buffer result
= { ACPI_ALLOCATE_BUFFER
, NULL
};
1422 union acpi_object
*obj
;
1426 status
= wmi_evaluate_method(WMID_GUID4
, 0, method_id
, &input
, &result
);
1428 if (ACPI_FAILURE(status
))
1430 obj
= (union acpi_object
*) result
.pointer
;
1433 if (obj
->type
== ACPI_TYPE_BUFFER
) {
1434 if (obj
->buffer
.length
== sizeof(u32
))
1435 tmp
= *((u32
*) obj
->buffer
.pointer
);
1436 else if (obj
->buffer
.length
== sizeof(u64
))
1437 tmp
= *((u64
*) obj
->buffer
.pointer
);
1438 } else if (obj
->type
== ACPI_TYPE_INTEGER
) {
1439 tmp
= (u64
) obj
->integer
.value
;
1446 kfree(result
.pointer
);
1451 static acpi_status
WMID_gaming_set_u64(u64 value
, u32 cap
)
1455 if (!(interface
->capability
& cap
))
1456 return AE_BAD_PARAMETER
;
1459 case ACER_CAP_TURBO_LED
:
1460 method_id
= ACER_WMID_SET_GAMING_LED_METHODID
;
1462 case ACER_CAP_TURBO_FAN
:
1463 method_id
= ACER_WMID_SET_GAMING_FAN_BEHAVIOR
;
1465 case ACER_CAP_TURBO_OC
:
1466 method_id
= ACER_WMID_SET_GAMING_MISC_SETTING_METHODID
;
1469 return AE_BAD_PARAMETER
;
1472 return WMI_gaming_execute_u64(method_id
, value
, NULL
);
1475 static acpi_status
WMID_gaming_get_u64(u64
*value
, u32 cap
)
1482 if (!(interface
->capability
& cap
))
1483 return AE_BAD_PARAMETER
;
1486 case ACER_CAP_TURBO_LED
:
1487 method_id
= ACER_WMID_GET_GAMING_LED_METHODID
;
1491 return AE_BAD_PARAMETER
;
1493 status
= WMI_gaming_execute_u64(method_id
, input
, &result
);
1494 if (ACPI_SUCCESS(status
))
1495 *value
= (u64
) result
;
1500 static void WMID_gaming_set_fan_mode(u8 fan_mode
)
1502 /* fan_mode = 1 is used for auto, fan_mode = 2 used for turbo*/
1503 u64 gpu_fan_config1
= 0, gpu_fan_config2
= 0;
1506 if (quirks
->cpu_fans
> 0)
1507 gpu_fan_config2
|= 1;
1508 for (i
= 0; i
< (quirks
->cpu_fans
+ quirks
->gpu_fans
); ++i
)
1509 gpu_fan_config2
|= 1 << (i
+ 1);
1510 for (i
= 0; i
< quirks
->gpu_fans
; ++i
)
1511 gpu_fan_config2
|= 1 << (i
+ 3);
1512 if (quirks
->cpu_fans
> 0)
1513 gpu_fan_config1
|= fan_mode
;
1514 for (i
= 0; i
< (quirks
->cpu_fans
+ quirks
->gpu_fans
); ++i
)
1515 gpu_fan_config1
|= fan_mode
<< (2 * i
+ 2);
1516 for (i
= 0; i
< quirks
->gpu_fans
; ++i
)
1517 gpu_fan_config1
|= fan_mode
<< (2 * i
+ 6);
1518 WMID_gaming_set_u64(gpu_fan_config2
| gpu_fan_config1
<< 16, ACER_CAP_TURBO_FAN
);
1522 * Generic Device (interface-independent)
1525 static acpi_status
get_u32(u32
*value
, u32 cap
)
1527 acpi_status status
= AE_ERROR
;
1529 switch (interface
->type
) {
1531 status
= AMW0_get_u32(value
, cap
);
1534 if (cap
== ACER_CAP_MAILLED
) {
1535 status
= AMW0_get_u32(value
, cap
);
1540 status
= WMID_get_u32(value
, cap
);
1543 if (cap
& (ACER_CAP_WIRELESS
|
1544 ACER_CAP_BLUETOOTH
|
1546 status
= wmid_v2_get_u32(value
, cap
);
1547 else if (wmi_has_guid(WMID_GUID2
))
1548 status
= WMID_get_u32(value
, cap
);
1555 static acpi_status
set_u32(u32 value
, u32 cap
)
1559 if (interface
->capability
& cap
) {
1560 switch (interface
->type
) {
1562 return AMW0_set_u32(value
, cap
);
1564 if (cap
== ACER_CAP_MAILLED
)
1565 return AMW0_set_u32(value
, cap
);
1568 * On some models, some WMID methods don't toggle
1569 * properly. For those cases, we want to run the AMW0
1570 * method afterwards to be certain we've really toggled
1573 if (cap
== ACER_CAP_WIRELESS
||
1574 cap
== ACER_CAP_BLUETOOTH
) {
1575 status
= WMID_set_u32(value
, cap
);
1576 if (ACPI_FAILURE(status
))
1579 return AMW0_set_u32(value
, cap
);
1583 return WMID_set_u32(value
, cap
);
1585 if (cap
& (ACER_CAP_WIRELESS
|
1586 ACER_CAP_BLUETOOTH
|
1588 return wmid_v2_set_u32(value
, cap
);
1589 else if (wmi_has_guid(WMID_GUID2
))
1590 return WMID_set_u32(value
, cap
);
1593 return AE_BAD_PARAMETER
;
1596 return AE_BAD_PARAMETER
;
1599 static void __init
acer_commandline_init(void)
1602 * These will all fail silently if the value given is invalid, or the
1603 * capability isn't available on the given interface
1606 set_u32(mailled
, ACER_CAP_MAILLED
);
1607 if (!has_type_aa
&& threeg
>= 0)
1608 set_u32(threeg
, ACER_CAP_THREEG
);
1609 if (brightness
>= 0)
1610 set_u32(brightness
, ACER_CAP_BRIGHTNESS
);
1614 * LED device (Mail LED only, no other LEDs known yet)
1616 static void mail_led_set(struct led_classdev
*led_cdev
,
1617 enum led_brightness value
)
1619 set_u32(value
, ACER_CAP_MAILLED
);
1622 static struct led_classdev mail_led
= {
1623 .name
= "acer-wmi::mail",
1624 .brightness_set
= mail_led_set
,
1627 static int acer_led_init(struct device
*dev
)
1629 return led_classdev_register(dev
, &mail_led
);
1632 static void acer_led_exit(void)
1634 set_u32(LED_OFF
, ACER_CAP_MAILLED
);
1635 led_classdev_unregister(&mail_led
);
1641 static struct backlight_device
*acer_backlight_device
;
1643 static int read_brightness(struct backlight_device
*bd
)
1646 get_u32(&value
, ACER_CAP_BRIGHTNESS
);
1650 static int update_bl_status(struct backlight_device
*bd
)
1652 int intensity
= backlight_get_brightness(bd
);
1654 set_u32(intensity
, ACER_CAP_BRIGHTNESS
);
1659 static const struct backlight_ops acer_bl_ops
= {
1660 .get_brightness
= read_brightness
,
1661 .update_status
= update_bl_status
,
1664 static int acer_backlight_init(struct device
*dev
)
1666 struct backlight_properties props
;
1667 struct backlight_device
*bd
;
1669 memset(&props
, 0, sizeof(struct backlight_properties
));
1670 props
.type
= BACKLIGHT_PLATFORM
;
1671 props
.max_brightness
= max_brightness
;
1672 bd
= backlight_device_register("acer-wmi", dev
, NULL
, &acer_bl_ops
,
1675 pr_err("Could not register Acer backlight device\n");
1676 acer_backlight_device
= NULL
;
1680 acer_backlight_device
= bd
;
1682 bd
->props
.power
= BACKLIGHT_POWER_ON
;
1683 bd
->props
.brightness
= read_brightness(bd
);
1684 backlight_update_status(bd
);
1688 static void acer_backlight_exit(void)
1690 backlight_device_unregister(acer_backlight_device
);
1694 * Accelerometer device
1696 static acpi_handle gsensor_handle
;
1698 static int acer_gsensor_init(void)
1701 struct acpi_buffer output
;
1702 union acpi_object out_obj
;
1704 output
.length
= sizeof(out_obj
);
1705 output
.pointer
= &out_obj
;
1706 status
= acpi_evaluate_object(gsensor_handle
, "_INI", NULL
, &output
);
1707 if (ACPI_FAILURE(status
))
1713 static int acer_gsensor_open(struct input_dev
*input
)
1715 return acer_gsensor_init();
1718 static int acer_gsensor_event(void)
1721 struct acpi_buffer output
;
1722 union acpi_object out_obj
[5];
1724 if (!acer_wmi_accel_dev
)
1727 output
.length
= sizeof(out_obj
);
1728 output
.pointer
= out_obj
;
1730 status
= acpi_evaluate_object(gsensor_handle
, "RDVL", NULL
, &output
);
1731 if (ACPI_FAILURE(status
))
1734 if (out_obj
->package
.count
!= 4)
1737 input_report_abs(acer_wmi_accel_dev
, ABS_X
,
1738 (s16
)out_obj
->package
.elements
[0].integer
.value
);
1739 input_report_abs(acer_wmi_accel_dev
, ABS_Y
,
1740 (s16
)out_obj
->package
.elements
[1].integer
.value
);
1741 input_report_abs(acer_wmi_accel_dev
, ABS_Z
,
1742 (s16
)out_obj
->package
.elements
[2].integer
.value
);
1743 input_sync(acer_wmi_accel_dev
);
1747 static int acer_get_fan_speed(int fan
)
1749 if (quirks
->predator_v4
) {
1753 status
= WMI_gaming_execute_u64(
1754 ACER_WMID_GET_GAMING_SYS_INFO_METHODID
,
1755 fan
== 0 ? ACER_WMID_CMD_GET_PREDATOR_V4_CPU_FAN_SPEED
:
1756 ACER_WMID_CMD_GET_PREDATOR_V4_GPU_FAN_SPEED
,
1759 if (ACPI_FAILURE(status
))
1762 return FIELD_GET(ACER_PREDATOR_V4_FAN_SPEED_READ_BIT_MASK
, fanspeed
);
1768 * Predator series turbo button
1770 static int acer_toggle_turbo(void)
1772 u64 turbo_led_state
;
1774 /* Get current state from turbo button */
1775 if (ACPI_FAILURE(WMID_gaming_get_u64(&turbo_led_state
, ACER_CAP_TURBO_LED
)))
1778 if (turbo_led_state
) {
1779 /* Turn off turbo led */
1780 WMID_gaming_set_u64(0x1, ACER_CAP_TURBO_LED
);
1782 /* Set FAN mode to auto */
1783 WMID_gaming_set_fan_mode(0x1);
1785 /* Set OC to normal */
1786 WMID_gaming_set_u64(0x5, ACER_CAP_TURBO_OC
);
1787 WMID_gaming_set_u64(0x7, ACER_CAP_TURBO_OC
);
1789 /* Turn on turbo led */
1790 WMID_gaming_set_u64(0x10001, ACER_CAP_TURBO_LED
);
1792 /* Set FAN mode to turbo */
1793 WMID_gaming_set_fan_mode(0x2);
1795 /* Set OC to turbo mode */
1796 WMID_gaming_set_u64(0x205, ACER_CAP_TURBO_OC
);
1797 WMID_gaming_set_u64(0x207, ACER_CAP_TURBO_OC
);
1799 return turbo_led_state
;
1803 acer_predator_v4_platform_profile_get(struct platform_profile_handler
*pprof
,
1804 enum platform_profile_option
*profile
)
1809 err
= ec_read(ACER_PREDATOR_V4_THERMAL_PROFILE_EC_OFFSET
, &tp
);
1815 case ACER_PREDATOR_V4_THERMAL_PROFILE_TURBO
:
1816 *profile
= PLATFORM_PROFILE_PERFORMANCE
;
1818 case ACER_PREDATOR_V4_THERMAL_PROFILE_PERFORMANCE
:
1819 *profile
= PLATFORM_PROFILE_BALANCED_PERFORMANCE
;
1821 case ACER_PREDATOR_V4_THERMAL_PROFILE_BALANCED
:
1822 *profile
= PLATFORM_PROFILE_BALANCED
;
1824 case ACER_PREDATOR_V4_THERMAL_PROFILE_QUIET
:
1825 *profile
= PLATFORM_PROFILE_QUIET
;
1827 case ACER_PREDATOR_V4_THERMAL_PROFILE_ECO
:
1828 *profile
= PLATFORM_PROFILE_LOW_POWER
;
1838 acer_predator_v4_platform_profile_set(struct platform_profile_handler
*pprof
,
1839 enum platform_profile_option profile
)
1845 case PLATFORM_PROFILE_PERFORMANCE
:
1846 tp
= ACER_PREDATOR_V4_THERMAL_PROFILE_TURBO_WMI
;
1848 case PLATFORM_PROFILE_BALANCED_PERFORMANCE
:
1849 tp
= ACER_PREDATOR_V4_THERMAL_PROFILE_PERFORMANCE_WMI
;
1851 case PLATFORM_PROFILE_BALANCED
:
1852 tp
= ACER_PREDATOR_V4_THERMAL_PROFILE_BALANCED_WMI
;
1854 case PLATFORM_PROFILE_QUIET
:
1855 tp
= ACER_PREDATOR_V4_THERMAL_PROFILE_QUIET_WMI
;
1857 case PLATFORM_PROFILE_LOW_POWER
:
1858 tp
= ACER_PREDATOR_V4_THERMAL_PROFILE_ECO_WMI
;
1864 status
= WMI_gaming_execute_u64(
1865 ACER_WMID_SET_GAMING_MISC_SETTING_METHODID
, tp
, NULL
);
1867 if (ACPI_FAILURE(status
))
1870 if (tp
!= ACER_PREDATOR_V4_THERMAL_PROFILE_TURBO_WMI
)
1871 last_non_turbo_profile
= tp
;
1876 static int acer_platform_profile_setup(void)
1878 if (quirks
->predator_v4
) {
1881 platform_profile_handler
.profile_get
=
1882 acer_predator_v4_platform_profile_get
;
1883 platform_profile_handler
.profile_set
=
1884 acer_predator_v4_platform_profile_set
;
1886 set_bit(PLATFORM_PROFILE_PERFORMANCE
,
1887 platform_profile_handler
.choices
);
1888 set_bit(PLATFORM_PROFILE_BALANCED_PERFORMANCE
,
1889 platform_profile_handler
.choices
);
1890 set_bit(PLATFORM_PROFILE_BALANCED
,
1891 platform_profile_handler
.choices
);
1892 set_bit(PLATFORM_PROFILE_QUIET
,
1893 platform_profile_handler
.choices
);
1894 set_bit(PLATFORM_PROFILE_LOW_POWER
,
1895 platform_profile_handler
.choices
);
1897 err
= platform_profile_register(&platform_profile_handler
);
1901 platform_profile_support
= true;
1903 /* Set default non-turbo profile */
1904 last_non_turbo_profile
=
1905 ACER_PREDATOR_V4_THERMAL_PROFILE_BALANCED_WMI
;
1910 static int acer_thermal_profile_change(void)
1913 * This mode key can rotate each mode or toggle turbo mode.
1914 * On battery, only ECO and BALANCED mode are available.
1916 if (quirks
->predator_v4
) {
1922 err
= ec_read(ACER_PREDATOR_V4_THERMAL_PROFILE_EC_OFFSET
,
1928 /* Check power source */
1929 status
= WMI_gaming_execute_u64(
1930 ACER_WMID_GET_GAMING_SYS_INFO_METHODID
,
1931 ACER_WMID_CMD_GET_PREDATOR_V4_BAT_STATUS
, &on_AC
);
1933 if (ACPI_FAILURE(status
))
1936 switch (current_tp
) {
1937 case ACER_PREDATOR_V4_THERMAL_PROFILE_TURBO
:
1939 tp
= ACER_PREDATOR_V4_THERMAL_PROFILE_BALANCED_WMI
;
1940 else if (cycle_gaming_thermal_profile
)
1941 tp
= ACER_PREDATOR_V4_THERMAL_PROFILE_ECO_WMI
;
1943 tp
= last_non_turbo_profile
;
1945 case ACER_PREDATOR_V4_THERMAL_PROFILE_PERFORMANCE
:
1947 tp
= ACER_PREDATOR_V4_THERMAL_PROFILE_BALANCED_WMI
;
1949 tp
= ACER_PREDATOR_V4_THERMAL_PROFILE_TURBO_WMI
;
1951 case ACER_PREDATOR_V4_THERMAL_PROFILE_BALANCED
:
1953 tp
= ACER_PREDATOR_V4_THERMAL_PROFILE_ECO_WMI
;
1954 else if (cycle_gaming_thermal_profile
)
1955 tp
= ACER_PREDATOR_V4_THERMAL_PROFILE_PERFORMANCE_WMI
;
1957 tp
= ACER_PREDATOR_V4_THERMAL_PROFILE_TURBO_WMI
;
1959 case ACER_PREDATOR_V4_THERMAL_PROFILE_QUIET
:
1961 tp
= ACER_PREDATOR_V4_THERMAL_PROFILE_BALANCED_WMI
;
1962 else if (cycle_gaming_thermal_profile
)
1963 tp
= ACER_PREDATOR_V4_THERMAL_PROFILE_BALANCED_WMI
;
1965 tp
= ACER_PREDATOR_V4_THERMAL_PROFILE_TURBO_WMI
;
1967 case ACER_PREDATOR_V4_THERMAL_PROFILE_ECO
:
1969 tp
= ACER_PREDATOR_V4_THERMAL_PROFILE_BALANCED_WMI
;
1970 else if (cycle_gaming_thermal_profile
)
1971 tp
= ACER_PREDATOR_V4_THERMAL_PROFILE_QUIET_WMI
;
1973 tp
= ACER_PREDATOR_V4_THERMAL_PROFILE_TURBO_WMI
;
1979 status
= WMI_gaming_execute_u64(
1980 ACER_WMID_SET_GAMING_MISC_SETTING_METHODID
, tp
, NULL
);
1982 if (ACPI_FAILURE(status
))
1985 /* Store non-turbo profile for turbo mode toggle*/
1986 if (tp
!= ACER_PREDATOR_V4_THERMAL_PROFILE_TURBO_WMI
)
1987 last_non_turbo_profile
= tp
;
1989 platform_profile_notify();
1996 * Switch series keyboard dock status
1998 static int acer_kbd_dock_state_to_sw_tablet_mode(u8 kbd_dock_state
)
2000 switch (kbd_dock_state
) {
2001 case 0x01: /* Docked, traditional clamshell laptop mode */
2003 case 0x04: /* Stand-alone tablet */
2004 case 0x40: /* Docked, tent mode, keyboard not usable */
2007 pr_warn("Unknown kbd_dock_state 0x%02x\n", kbd_dock_state
);
2013 static void acer_kbd_dock_get_initial_state(void)
2015 u8
*output
, input
[8] = { 0x05, 0x00, };
2016 struct acpi_buffer input_buf
= { sizeof(input
), input
};
2017 struct acpi_buffer output_buf
= { ACPI_ALLOCATE_BUFFER
, NULL
};
2018 union acpi_object
*obj
;
2022 status
= wmi_evaluate_method(WMID_GUID3
, 0, 0x2, &input_buf
, &output_buf
);
2023 if (ACPI_FAILURE(status
)) {
2024 pr_err("Error getting keyboard-dock initial status: %s\n",
2025 acpi_format_exception(status
));
2029 obj
= output_buf
.pointer
;
2030 if (!obj
|| obj
->type
!= ACPI_TYPE_BUFFER
|| obj
->buffer
.length
!= 8) {
2031 pr_err("Unexpected output format getting keyboard-dock initial status\n");
2035 output
= obj
->buffer
.pointer
;
2036 if (output
[0] != 0x00 || (output
[3] != 0x05 && output
[3] != 0x45)) {
2037 pr_err("Unexpected output [0]=0x%02x [3]=0x%02x getting keyboard-dock initial status\n",
2038 output
[0], output
[3]);
2042 sw_tablet_mode
= acer_kbd_dock_state_to_sw_tablet_mode(output
[4]);
2043 input_report_switch(acer_wmi_input_dev
, SW_TABLET_MODE
, sw_tablet_mode
);
2049 static void acer_kbd_dock_event(const struct event_return_value
*event
)
2053 if (!has_cap(ACER_CAP_KBD_DOCK
))
2056 sw_tablet_mode
= acer_kbd_dock_state_to_sw_tablet_mode(event
->kbd_dock_state
);
2057 input_report_switch(acer_wmi_input_dev
, SW_TABLET_MODE
, sw_tablet_mode
);
2058 input_sync(acer_wmi_input_dev
);
2064 static void acer_rfkill_update(struct work_struct
*ignored
);
2065 static DECLARE_DELAYED_WORK(acer_rfkill_work
, acer_rfkill_update
);
2066 static void acer_rfkill_update(struct work_struct
*ignored
)
2071 if (has_cap(ACER_CAP_WIRELESS
)) {
2072 status
= get_u32(&state
, ACER_CAP_WIRELESS
);
2073 if (ACPI_SUCCESS(status
)) {
2074 if (quirks
->wireless
== 3)
2075 rfkill_set_hw_state(wireless_rfkill
, !state
);
2077 rfkill_set_sw_state(wireless_rfkill
, !state
);
2081 if (has_cap(ACER_CAP_BLUETOOTH
)) {
2082 status
= get_u32(&state
, ACER_CAP_BLUETOOTH
);
2083 if (ACPI_SUCCESS(status
))
2084 rfkill_set_sw_state(bluetooth_rfkill
, !state
);
2087 if (has_cap(ACER_CAP_THREEG
) && wmi_has_guid(WMID_GUID3
)) {
2088 status
= get_u32(&state
, ACER_WMID3_GDS_THREEG
);
2089 if (ACPI_SUCCESS(status
))
2090 rfkill_set_sw_state(threeg_rfkill
, !state
);
2093 schedule_delayed_work(&acer_rfkill_work
, round_jiffies_relative(HZ
));
2096 static int acer_rfkill_set(void *data
, bool blocked
)
2099 u32 cap
= (unsigned long)data
;
2101 if (rfkill_inited
) {
2102 status
= set_u32(!blocked
, cap
);
2103 if (ACPI_FAILURE(status
))
2110 static const struct rfkill_ops acer_rfkill_ops
= {
2111 .set_block
= acer_rfkill_set
,
2114 static struct rfkill
*acer_rfkill_register(struct device
*dev
,
2115 enum rfkill_type type
,
2116 char *name
, u32 cap
)
2119 struct rfkill
*rfkill_dev
;
2123 rfkill_dev
= rfkill_alloc(name
, dev
, type
,
2125 (void *)(unsigned long)cap
);
2127 return ERR_PTR(-ENOMEM
);
2129 status
= get_u32(&state
, cap
);
2131 err
= rfkill_register(rfkill_dev
);
2133 rfkill_destroy(rfkill_dev
);
2134 return ERR_PTR(err
);
2137 if (ACPI_SUCCESS(status
))
2138 rfkill_set_sw_state(rfkill_dev
, !state
);
2143 static int acer_rfkill_init(struct device
*dev
)
2147 if (has_cap(ACER_CAP_WIRELESS
)) {
2148 wireless_rfkill
= acer_rfkill_register(dev
, RFKILL_TYPE_WLAN
,
2149 "acer-wireless", ACER_CAP_WIRELESS
);
2150 if (IS_ERR(wireless_rfkill
)) {
2151 err
= PTR_ERR(wireless_rfkill
);
2152 goto error_wireless
;
2156 if (has_cap(ACER_CAP_BLUETOOTH
)) {
2157 bluetooth_rfkill
= acer_rfkill_register(dev
,
2158 RFKILL_TYPE_BLUETOOTH
, "acer-bluetooth",
2159 ACER_CAP_BLUETOOTH
);
2160 if (IS_ERR(bluetooth_rfkill
)) {
2161 err
= PTR_ERR(bluetooth_rfkill
);
2162 goto error_bluetooth
;
2166 if (has_cap(ACER_CAP_THREEG
)) {
2167 threeg_rfkill
= acer_rfkill_register(dev
,
2168 RFKILL_TYPE_WWAN
, "acer-threeg",
2170 if (IS_ERR(threeg_rfkill
)) {
2171 err
= PTR_ERR(threeg_rfkill
);
2176 rfkill_inited
= true;
2178 if ((ec_raw_mode
|| !wmi_has_guid(ACERWMID_EVENT_GUID
)) &&
2179 has_cap(ACER_CAP_WIRELESS
| ACER_CAP_BLUETOOTH
| ACER_CAP_THREEG
))
2180 schedule_delayed_work(&acer_rfkill_work
,
2181 round_jiffies_relative(HZ
));
2186 if (has_cap(ACER_CAP_BLUETOOTH
)) {
2187 rfkill_unregister(bluetooth_rfkill
);
2188 rfkill_destroy(bluetooth_rfkill
);
2191 if (has_cap(ACER_CAP_WIRELESS
)) {
2192 rfkill_unregister(wireless_rfkill
);
2193 rfkill_destroy(wireless_rfkill
);
2199 static void acer_rfkill_exit(void)
2201 if ((ec_raw_mode
|| !wmi_has_guid(ACERWMID_EVENT_GUID
)) &&
2202 has_cap(ACER_CAP_WIRELESS
| ACER_CAP_BLUETOOTH
| ACER_CAP_THREEG
))
2203 cancel_delayed_work_sync(&acer_rfkill_work
);
2205 if (has_cap(ACER_CAP_WIRELESS
)) {
2206 rfkill_unregister(wireless_rfkill
);
2207 rfkill_destroy(wireless_rfkill
);
2210 if (has_cap(ACER_CAP_BLUETOOTH
)) {
2211 rfkill_unregister(bluetooth_rfkill
);
2212 rfkill_destroy(bluetooth_rfkill
);
2215 if (has_cap(ACER_CAP_THREEG
)) {
2216 rfkill_unregister(threeg_rfkill
);
2217 rfkill_destroy(threeg_rfkill
);
2221 static void acer_wmi_notify(union acpi_object
*obj
, void *context
)
2223 struct event_return_value return_value
;
2225 const struct key_entry
*key
;
2230 if (obj
->type
!= ACPI_TYPE_BUFFER
) {
2231 pr_warn("Unknown response received %d\n", obj
->type
);
2234 if (obj
->buffer
.length
!= 8) {
2235 pr_warn("Unknown buffer length %d\n", obj
->buffer
.length
);
2239 return_value
= *((struct event_return_value
*)obj
->buffer
.pointer
);
2241 switch (return_value
.function
) {
2242 case WMID_HOTKEY_EVENT
:
2243 device_state
= return_value
.device_state
;
2244 pr_debug("device state: 0x%x\n", device_state
);
2246 key
= sparse_keymap_entry_from_scancode(acer_wmi_input_dev
,
2247 return_value
.key_num
);
2249 pr_warn("Unknown key number - 0x%x\n",
2250 return_value
.key_num
);
2252 scancode
= return_value
.key_num
;
2253 switch (key
->keycode
) {
2256 if (has_cap(ACER_CAP_WIRELESS
))
2257 rfkill_set_sw_state(wireless_rfkill
,
2258 !(device_state
& ACER_WMID3_GDS_WIRELESS
));
2259 if (has_cap(ACER_CAP_THREEG
))
2260 rfkill_set_sw_state(threeg_rfkill
,
2261 !(device_state
& ACER_WMID3_GDS_THREEG
));
2262 if (has_cap(ACER_CAP_BLUETOOTH
))
2263 rfkill_set_sw_state(bluetooth_rfkill
,
2264 !(device_state
& ACER_WMID3_GDS_BLUETOOTH
));
2266 case KEY_TOUCHPAD_TOGGLE
:
2267 scancode
= (device_state
& ACER_WMID3_GDS_TOUCHPAD
) ?
2268 KEY_TOUCHPAD_ON
: KEY_TOUCHPAD_OFF
;
2270 sparse_keymap_report_event(acer_wmi_input_dev
, scancode
, 1, true);
2273 case WMID_ACCEL_OR_KBD_DOCK_EVENT
:
2274 acer_gsensor_event();
2275 acer_kbd_dock_event(&return_value
);
2277 case WMID_GAMING_TURBO_KEY_EVENT
:
2278 if (return_value
.key_num
== 0x4)
2279 acer_toggle_turbo();
2280 if (return_value
.key_num
== 0x5 && has_cap(ACER_CAP_PLATFORM_PROFILE
))
2281 acer_thermal_profile_change();
2284 pr_warn("Unknown function number - %d - %d\n",
2285 return_value
.function
, return_value
.key_num
);
2290 static acpi_status __init
2291 wmid3_set_function_mode(struct func_input_params
*params
,
2292 struct func_return_value
*return_value
)
2295 union acpi_object
*obj
;
2297 struct acpi_buffer input
= { sizeof(struct func_input_params
), params
};
2298 struct acpi_buffer output
= { ACPI_ALLOCATE_BUFFER
, NULL
};
2300 status
= wmi_evaluate_method(WMID_GUID3
, 0, 0x1, &input
, &output
);
2301 if (ACPI_FAILURE(status
))
2304 obj
= output
.pointer
;
2308 else if (obj
->type
!= ACPI_TYPE_BUFFER
) {
2312 if (obj
->buffer
.length
!= 4) {
2313 pr_warn("Unknown buffer length %d\n", obj
->buffer
.length
);
2318 *return_value
= *((struct func_return_value
*)obj
->buffer
.pointer
);
2324 static int __init
acer_wmi_enable_ec_raw(void)
2326 struct func_return_value return_value
;
2328 struct func_input_params params
= {
2329 .function_num
= 0x1,
2330 .commun_devices
= 0xFFFF,
2332 .app_status
= 0x00, /* Launch Manager Deactive */
2336 status
= wmid3_set_function_mode(¶ms
, &return_value
);
2338 if (return_value
.error_code
|| return_value
.ec_return_value
)
2339 pr_warn("Enabling EC raw mode failed: 0x%x - 0x%x\n",
2340 return_value
.error_code
,
2341 return_value
.ec_return_value
);
2343 pr_info("Enabled EC raw mode\n");
2348 static int __init
acer_wmi_enable_lm(void)
2350 struct func_return_value return_value
;
2352 struct func_input_params params
= {
2353 .function_num
= 0x1,
2354 .commun_devices
= 0xFFFF,
2356 .app_status
= 0x01, /* Launch Manager Active */
2360 status
= wmid3_set_function_mode(¶ms
, &return_value
);
2362 if (return_value
.error_code
|| return_value
.ec_return_value
)
2363 pr_warn("Enabling Launch Manager failed: 0x%x - 0x%x\n",
2364 return_value
.error_code
,
2365 return_value
.ec_return_value
);
2370 static int __init
acer_wmi_enable_rf_button(void)
2372 struct func_return_value return_value
;
2374 struct func_input_params params
= {
2375 .function_num
= 0x1,
2376 .commun_devices
= 0xFFFF,
2378 .app_status
= 0x10, /* RF Button Active */
2382 status
= wmid3_set_function_mode(¶ms
, &return_value
);
2384 if (return_value
.error_code
|| return_value
.ec_return_value
)
2385 pr_warn("Enabling RF Button failed: 0x%x - 0x%x\n",
2386 return_value
.error_code
,
2387 return_value
.ec_return_value
);
2392 static int __init
acer_wmi_accel_setup(void)
2394 struct acpi_device
*adev
;
2397 adev
= acpi_dev_get_first_match_dev("BST0001", NULL
, -1);
2401 gsensor_handle
= acpi_device_handle(adev
);
2404 acer_wmi_accel_dev
= input_allocate_device();
2405 if (!acer_wmi_accel_dev
)
2408 acer_wmi_accel_dev
->open
= acer_gsensor_open
;
2410 acer_wmi_accel_dev
->name
= "Acer BMA150 accelerometer";
2411 acer_wmi_accel_dev
->phys
= "wmi/input1";
2412 acer_wmi_accel_dev
->id
.bustype
= BUS_HOST
;
2413 acer_wmi_accel_dev
->evbit
[0] = BIT_MASK(EV_ABS
);
2414 input_set_abs_params(acer_wmi_accel_dev
, ABS_X
, -16384, 16384, 0, 0);
2415 input_set_abs_params(acer_wmi_accel_dev
, ABS_Y
, -16384, 16384, 0, 0);
2416 input_set_abs_params(acer_wmi_accel_dev
, ABS_Z
, -16384, 16384, 0, 0);
2418 err
= input_register_device(acer_wmi_accel_dev
);
2425 input_free_device(acer_wmi_accel_dev
);
2429 static int __init
acer_wmi_input_setup(void)
2434 acer_wmi_input_dev
= input_allocate_device();
2435 if (!acer_wmi_input_dev
)
2438 acer_wmi_input_dev
->name
= "Acer WMI hotkeys";
2439 acer_wmi_input_dev
->phys
= "wmi/input0";
2440 acer_wmi_input_dev
->id
.bustype
= BUS_HOST
;
2442 err
= sparse_keymap_setup(acer_wmi_input_dev
, acer_wmi_keymap
, NULL
);
2446 if (has_cap(ACER_CAP_KBD_DOCK
))
2447 input_set_capability(acer_wmi_input_dev
, EV_SW
, SW_TABLET_MODE
);
2449 status
= wmi_install_notify_handler(ACERWMID_EVENT_GUID
,
2450 acer_wmi_notify
, NULL
);
2451 if (ACPI_FAILURE(status
)) {
2456 if (has_cap(ACER_CAP_KBD_DOCK
))
2457 acer_kbd_dock_get_initial_state();
2459 err
= input_register_device(acer_wmi_input_dev
);
2461 goto err_uninstall_notifier
;
2465 err_uninstall_notifier
:
2466 wmi_remove_notify_handler(ACERWMID_EVENT_GUID
);
2468 input_free_device(acer_wmi_input_dev
);
2472 static void acer_wmi_input_destroy(void)
2474 wmi_remove_notify_handler(ACERWMID_EVENT_GUID
);
2475 input_unregister_device(acer_wmi_input_dev
);
2481 static u32
get_wmid_devices(void)
2483 struct acpi_buffer out
= {ACPI_ALLOCATE_BUFFER
, NULL
};
2484 union acpi_object
*obj
;
2488 status
= wmi_query_block(WMID_GUID2
, 0, &out
);
2489 if (ACPI_FAILURE(status
))
2492 obj
= (union acpi_object
*) out
.pointer
;
2494 if (obj
->type
== ACPI_TYPE_BUFFER
&&
2495 (obj
->buffer
.length
== sizeof(u32
) ||
2496 obj
->buffer
.length
== sizeof(u64
))) {
2497 devices
= *((u32
*) obj
->buffer
.pointer
);
2498 } else if (obj
->type
== ACPI_TYPE_INTEGER
) {
2499 devices
= (u32
) obj
->integer
.value
;
2507 static int acer_wmi_hwmon_init(void);
2512 static int acer_platform_probe(struct platform_device
*device
)
2516 if (has_cap(ACER_CAP_MAILLED
)) {
2517 err
= acer_led_init(&device
->dev
);
2522 if (has_cap(ACER_CAP_BRIGHTNESS
)) {
2523 err
= acer_backlight_init(&device
->dev
);
2525 goto error_brightness
;
2528 err
= acer_rfkill_init(&device
->dev
);
2532 if (has_cap(ACER_CAP_PLATFORM_PROFILE
)) {
2533 err
= acer_platform_profile_setup();
2535 goto error_platform_profile
;
2538 if (has_cap(ACER_CAP_FAN_SPEED_READ
)) {
2539 err
= acer_wmi_hwmon_init();
2547 if (platform_profile_support
)
2548 platform_profile_remove();
2549 error_platform_profile
:
2552 if (has_cap(ACER_CAP_BRIGHTNESS
))
2553 acer_backlight_exit();
2555 if (has_cap(ACER_CAP_MAILLED
))
2561 static void acer_platform_remove(struct platform_device
*device
)
2563 if (has_cap(ACER_CAP_MAILLED
))
2565 if (has_cap(ACER_CAP_BRIGHTNESS
))
2566 acer_backlight_exit();
2570 if (platform_profile_support
)
2571 platform_profile_remove();
2574 #ifdef CONFIG_PM_SLEEP
2575 static int acer_suspend(struct device
*dev
)
2578 struct acer_data
*data
= &interface
->data
;
2583 if (has_cap(ACER_CAP_MAILLED
)) {
2584 get_u32(&value
, ACER_CAP_MAILLED
);
2585 set_u32(LED_OFF
, ACER_CAP_MAILLED
);
2586 data
->mailled
= value
;
2589 if (has_cap(ACER_CAP_BRIGHTNESS
)) {
2590 get_u32(&value
, ACER_CAP_BRIGHTNESS
);
2591 data
->brightness
= value
;
2597 static int acer_resume(struct device
*dev
)
2599 struct acer_data
*data
= &interface
->data
;
2604 if (has_cap(ACER_CAP_MAILLED
))
2605 set_u32(data
->mailled
, ACER_CAP_MAILLED
);
2607 if (has_cap(ACER_CAP_BRIGHTNESS
))
2608 set_u32(data
->brightness
, ACER_CAP_BRIGHTNESS
);
2610 if (acer_wmi_accel_dev
)
2611 acer_gsensor_init();
2616 #define acer_suspend NULL
2617 #define acer_resume NULL
2620 static SIMPLE_DEV_PM_OPS(acer_pm
, acer_suspend
, acer_resume
);
2622 static void acer_platform_shutdown(struct platform_device
*device
)
2624 struct acer_data
*data
= &interface
->data
;
2629 if (has_cap(ACER_CAP_MAILLED
))
2630 set_u32(LED_OFF
, ACER_CAP_MAILLED
);
2633 static struct platform_driver acer_platform_driver
= {
2638 .probe
= acer_platform_probe
,
2639 .remove
= acer_platform_remove
,
2640 .shutdown
= acer_platform_shutdown
,
2643 static struct platform_device
*acer_platform_device
;
2645 static void remove_debugfs(void)
2647 debugfs_remove_recursive(interface
->debug
.root
);
2650 static void __init
create_debugfs(void)
2652 interface
->debug
.root
= debugfs_create_dir("acer-wmi", NULL
);
2654 debugfs_create_u32("devices", S_IRUGO
, interface
->debug
.root
,
2655 &interface
->debug
.wmid_devices
);
2658 static umode_t
acer_wmi_hwmon_is_visible(const void *data
,
2659 enum hwmon_sensor_types type
, u32 attr
,
2664 if (acer_get_fan_speed(channel
) >= 0)
2674 static int acer_wmi_hwmon_read(struct device
*dev
, enum hwmon_sensor_types type
,
2675 u32 attr
, int channel
, long *val
)
2681 ret
= acer_get_fan_speed(channel
);
2693 static const struct hwmon_channel_info
*const acer_wmi_hwmon_info
[] = {
2694 HWMON_CHANNEL_INFO(fan
, HWMON_F_INPUT
, HWMON_F_INPUT
), NULL
2697 static const struct hwmon_ops acer_wmi_hwmon_ops
= {
2698 .read
= acer_wmi_hwmon_read
,
2699 .is_visible
= acer_wmi_hwmon_is_visible
,
2702 static const struct hwmon_chip_info acer_wmi_hwmon_chip_info
= {
2703 .ops
= &acer_wmi_hwmon_ops
,
2704 .info
= acer_wmi_hwmon_info
,
2707 static int acer_wmi_hwmon_init(void)
2709 struct device
*dev
= &acer_platform_device
->dev
;
2710 struct device
*hwmon
;
2712 hwmon
= devm_hwmon_device_register_with_info(dev
, "acer",
2713 &acer_platform_driver
,
2714 &acer_wmi_hwmon_chip_info
,
2717 if (IS_ERR(hwmon
)) {
2718 dev_err(dev
, "Could not register acer hwmon device\n");
2719 return PTR_ERR(hwmon
);
2725 static int __init
acer_wmi_init(void)
2729 pr_info("Acer Laptop ACPI-WMI Extras\n");
2731 if (dmi_check_system(acer_blacklist
)) {
2732 pr_info("Blacklisted hardware detected - not loading\n");
2739 * The AMW0_GUID1 wmi is not only found on Acer family but also other
2740 * machines like Lenovo, Fujitsu and Medion. In the past days,
2741 * acer-wmi driver handled those non-Acer machines by quirks list.
2742 * But actually acer-wmi driver was loaded on any machines that have
2743 * AMW0_GUID1. This behavior is strange because those machines should
2744 * be supported by appropriate wmi drivers. e.g. fujitsu-laptop,
2745 * ideapad-laptop. So, here checks the machine that has AMW0_GUID1
2746 * should be in Acer/Gateway/Packard Bell white list, or it's already
2747 * in the past quirk list.
2749 if (wmi_has_guid(AMW0_GUID1
) &&
2750 !dmi_check_system(amw0_whitelist
) &&
2751 quirks
== &quirk_unknown
) {
2752 pr_debug("Unsupported machine has AMW0_GUID1, unable to load\n");
2757 * Detect which ACPI-WMI interface we're using.
2759 if (wmi_has_guid(AMW0_GUID1
) && wmi_has_guid(WMID_GUID1
))
2760 interface
= &AMW0_V2_interface
;
2762 if (!wmi_has_guid(AMW0_GUID1
) && wmi_has_guid(WMID_GUID1
))
2763 interface
= &wmid_interface
;
2765 if (wmi_has_guid(WMID_GUID3
))
2766 interface
= &wmid_v2_interface
;
2769 dmi_walk(type_aa_dmi_decode
, NULL
);
2771 if (wmi_has_guid(WMID_GUID2
) && interface
) {
2772 if (!has_type_aa
&& ACPI_FAILURE(WMID_set_capabilities())) {
2773 pr_err("Unable to detect available WMID devices\n");
2776 /* WMID always provides brightness methods */
2777 interface
->capability
|= ACER_CAP_BRIGHTNESS
;
2778 } else if (!wmi_has_guid(WMID_GUID2
) && interface
&& !has_type_aa
&& force_caps
== -1) {
2779 pr_err("No WMID device detection method found\n");
2783 if (wmi_has_guid(AMW0_GUID1
) && !wmi_has_guid(WMID_GUID1
)) {
2784 interface
= &AMW0_interface
;
2786 if (ACPI_FAILURE(AMW0_set_capabilities())) {
2787 pr_err("Unable to detect available AMW0 devices\n");
2792 if (wmi_has_guid(AMW0_GUID1
))
2793 AMW0_find_mailled();
2796 pr_err("No or unsupported WMI interface, unable to load\n");
2802 if (acpi_video_get_backlight_type() != acpi_backlight_vendor
)
2803 interface
->capability
&= ~ACER_CAP_BRIGHTNESS
;
2805 if (wmi_has_guid(WMID_GUID3
))
2806 interface
->capability
|= ACER_CAP_SET_FUNCTION_MODE
;
2808 if (force_caps
!= -1)
2809 interface
->capability
= force_caps
;
2811 if (wmi_has_guid(WMID_GUID3
) &&
2812 (interface
->capability
& ACER_CAP_SET_FUNCTION_MODE
)) {
2813 if (ACPI_FAILURE(acer_wmi_enable_rf_button()))
2814 pr_warn("Cannot enable RF Button Driver\n");
2817 if (ACPI_FAILURE(acer_wmi_enable_ec_raw())) {
2818 pr_err("Cannot enable EC raw mode\n");
2821 } else if (ACPI_FAILURE(acer_wmi_enable_lm())) {
2822 pr_err("Cannot enable Launch Manager mode\n");
2825 } else if (ec_raw_mode
) {
2826 pr_info("No WMID EC raw mode enable method\n");
2829 if (wmi_has_guid(ACERWMID_EVENT_GUID
)) {
2830 err
= acer_wmi_input_setup();
2833 err
= acer_wmi_accel_setup();
2834 if (err
&& err
!= -ENODEV
)
2835 pr_warn("Cannot enable accelerometer\n");
2838 err
= platform_driver_register(&acer_platform_driver
);
2840 pr_err("Unable to register platform driver\n");
2841 goto error_platform_register
;
2844 acer_platform_device
= platform_device_alloc("acer-wmi", PLATFORM_DEVID_NONE
);
2845 if (!acer_platform_device
) {
2847 goto error_device_alloc
;
2850 err
= platform_device_add(acer_platform_device
);
2852 goto error_device_add
;
2854 if (wmi_has_guid(WMID_GUID2
)) {
2855 interface
->debug
.wmid_devices
= get_wmid_devices();
2859 /* Override any initial settings with values from the commandline */
2860 acer_commandline_init();
2865 platform_device_put(acer_platform_device
);
2867 platform_driver_unregister(&acer_platform_driver
);
2868 error_platform_register
:
2869 if (wmi_has_guid(ACERWMID_EVENT_GUID
))
2870 acer_wmi_input_destroy();
2871 if (acer_wmi_accel_dev
)
2872 input_unregister_device(acer_wmi_accel_dev
);
2877 static void __exit
acer_wmi_exit(void)
2879 if (wmi_has_guid(ACERWMID_EVENT_GUID
))
2880 acer_wmi_input_destroy();
2882 if (acer_wmi_accel_dev
)
2883 input_unregister_device(acer_wmi_accel_dev
);
2886 platform_device_unregister(acer_platform_device
);
2887 platform_driver_unregister(&acer_platform_driver
);
2889 pr_info("Acer Laptop WMI Extras unloaded\n");
2892 module_init(acer_wmi_init
);
2893 module_exit(acer_wmi_exit
);