^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Acer WMI Laptop Extras
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2007-2009 Carlos Corbacho <carlos@strangeworlds.co.uk>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Based on acer_acpi:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Copyright (C) 2005-2007 E.M. Smith
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Copyright (C) 2007-2008 Carlos Corbacho <cathectic@gmail.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/dmi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/fb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/backlight.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/leds.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/acpi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/i8042.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/rfkill.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/workqueue.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/debugfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/input.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/input/sparse-keymap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <acpi/video.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) ACPI_MODULE_NAME(KBUILD_MODNAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) MODULE_AUTHOR("Carlos Corbacho");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) MODULE_DESCRIPTION("Acer Laptop WMI Extras Driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) * Magic Number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) * Meaning is unknown - this number is required for writing to ACPI for AMW0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) * (it's also used in acerhk when directly accessing the BIOS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define ACER_AMW0_WRITE 0x9610
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) * Bit masks for the AMW0 interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define ACER_AMW0_WIRELESS_MASK 0x35
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define ACER_AMW0_BLUETOOTH_MASK 0x34
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define ACER_AMW0_MAILLED_MASK 0x31
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) * Method IDs for WMID interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define ACER_WMID_GET_WIRELESS_METHODID 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define ACER_WMID_GET_BLUETOOTH_METHODID 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define ACER_WMID_GET_BRIGHTNESS_METHODID 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define ACER_WMID_SET_WIRELESS_METHODID 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define ACER_WMID_SET_BLUETOOTH_METHODID 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define ACER_WMID_SET_BRIGHTNESS_METHODID 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define ACER_WMID_GET_THREEG_METHODID 10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define ACER_WMID_SET_THREEG_METHODID 11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) * Acer ACPI method GUIDs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define AMW0_GUID1 "67C3371D-95A3-4C37-BB61-DD47B491DAAB"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define AMW0_GUID2 "431F16ED-0C2B-444C-B267-27DEB140CF9C"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define WMID_GUID1 "6AF4F258-B401-42FD-BE91-3D4AC2D7C0D3"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define WMID_GUID2 "95764E09-FB56-4E83-B31A-37761F60994A"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define WMID_GUID3 "61EF69EA-865C-4BC3-A502-A0DEBA0CB531"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) * Acer ACPI event GUIDs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define ACERWMID_EVENT_GUID "676AA15E-6A47-4D9F-A2CC-1E6D18D14026"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) MODULE_ALIAS("wmi:67C3371D-95A3-4C37-BB61-DD47B491DAAB");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) MODULE_ALIAS("wmi:6AF4F258-B401-42FD-BE91-3D4AC2D7C0D3");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) MODULE_ALIAS("wmi:676AA15E-6A47-4D9F-A2CC-1E6D18D14026");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) enum acer_wmi_event_ids {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) WMID_HOTKEY_EVENT = 0x1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) WMID_ACCEL_OR_KBD_DOCK_EVENT = 0x5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) static const struct key_entry acer_wmi_keymap[] __initconst = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) {KE_KEY, 0x01, {KEY_WLAN} }, /* WiFi */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) {KE_KEY, 0x03, {KEY_WLAN} }, /* WiFi */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) {KE_KEY, 0x04, {KEY_WLAN} }, /* WiFi */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) {KE_KEY, 0x12, {KEY_BLUETOOTH} }, /* BT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) {KE_KEY, 0x21, {KEY_PROG1} }, /* Backup */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) {KE_KEY, 0x22, {KEY_PROG2} }, /* Arcade */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) {KE_KEY, 0x23, {KEY_PROG3} }, /* P_Key */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) {KE_KEY, 0x24, {KEY_PROG4} }, /* Social networking_Key */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) {KE_KEY, 0x29, {KEY_PROG3} }, /* P_Key for TM8372 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) {KE_IGNORE, 0x41, {KEY_MUTE} },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) {KE_IGNORE, 0x42, {KEY_PREVIOUSSONG} },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) {KE_IGNORE, 0x4d, {KEY_PREVIOUSSONG} },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) {KE_IGNORE, 0x43, {KEY_NEXTSONG} },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) {KE_IGNORE, 0x4e, {KEY_NEXTSONG} },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) {KE_IGNORE, 0x44, {KEY_PLAYPAUSE} },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) {KE_IGNORE, 0x4f, {KEY_PLAYPAUSE} },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) {KE_IGNORE, 0x45, {KEY_STOP} },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) {KE_IGNORE, 0x50, {KEY_STOP} },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) {KE_IGNORE, 0x48, {KEY_VOLUMEUP} },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) {KE_IGNORE, 0x49, {KEY_VOLUMEDOWN} },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) {KE_IGNORE, 0x4a, {KEY_VOLUMEDOWN} },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) {KE_IGNORE, 0x61, {KEY_SWITCHVIDEOMODE} },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) {KE_IGNORE, 0x62, {KEY_BRIGHTNESSUP} },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) {KE_IGNORE, 0x63, {KEY_BRIGHTNESSDOWN} },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) {KE_KEY, 0x64, {KEY_SWITCHVIDEOMODE} }, /* Display Switch */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) {KE_IGNORE, 0x81, {KEY_SLEEP} },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) {KE_KEY, 0x82, {KEY_TOUCHPAD_TOGGLE} }, /* Touch Pad Toggle */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) {KE_IGNORE, 0x84, {KEY_KBDILLUMTOGGLE} }, /* Automatic Keyboard background light toggle */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) {KE_KEY, KEY_TOUCHPAD_ON, {KEY_TOUCHPAD_ON} },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) {KE_KEY, KEY_TOUCHPAD_OFF, {KEY_TOUCHPAD_OFF} },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) {KE_IGNORE, 0x83, {KEY_TOUCHPAD_TOGGLE} },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) {KE_KEY, 0x85, {KEY_TOUCHPAD_TOGGLE} },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) {KE_KEY, 0x86, {KEY_WLAN} },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) {KE_KEY, 0x87, {KEY_POWER} },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) {KE_END, 0}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) static struct input_dev *acer_wmi_input_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) static struct input_dev *acer_wmi_accel_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) struct event_return_value {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) u8 function;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) u8 key_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) u16 device_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) u16 reserved1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) u8 kbd_dock_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) u8 reserved2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) } __attribute__((packed));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) * GUID3 Get Device Status device flags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) #define ACER_WMID3_GDS_WIRELESS (1<<0) /* WiFi */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) #define ACER_WMID3_GDS_THREEG (1<<6) /* 3G */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) #define ACER_WMID3_GDS_WIMAX (1<<7) /* WiMAX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) #define ACER_WMID3_GDS_BLUETOOTH (1<<11) /* BT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) #define ACER_WMID3_GDS_RFBTN (1<<14) /* RF Button */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) #define ACER_WMID3_GDS_TOUCHPAD (1<<1) /* Touchpad */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) /* Hotkey Customized Setting and Acer Application Status.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) * Set Device Default Value and Report Acer Application Status.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) * When Acer Application starts, it will run this method to inform
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) * BIOS/EC that Acer Application is on.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) * App Status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) * Bit[0]: Launch Manager Status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) * Bit[1]: ePM Status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) * Bit[2]: Device Control Status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) * Bit[3]: Acer Power Button Utility Status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) * Bit[4]: RF Button Status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) * Bit[5]: ODD PM Status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) * Bit[6]: Device Default Value Control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) * Bit[7]: Hall Sensor Application Status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) struct func_input_params {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) u8 function_num; /* Function Number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) u16 commun_devices; /* Communication type devices default status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) u16 devices; /* Other type devices default status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) u8 app_status; /* Acer Device Status. LM, ePM, RF Button... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) u8 app_mask; /* Bit mask to app_status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) u8 reserved;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) } __attribute__((packed));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) struct func_return_value {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) u8 error_code; /* Error Code */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) u8 ec_return_value; /* EC Return Value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) u16 reserved;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) } __attribute__((packed));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) struct wmid3_gds_set_input_param { /* Set Device Status input parameter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) u8 function_num; /* Function Number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) u8 hotkey_number; /* Hotkey Number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) u16 devices; /* Set Device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) u8 volume_value; /* Volume Value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) } __attribute__((packed));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) struct wmid3_gds_get_input_param { /* Get Device Status input parameter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) u8 function_num; /* Function Number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) u8 hotkey_number; /* Hotkey Number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) u16 devices; /* Get Device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) } __attribute__((packed));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) struct wmid3_gds_return_value { /* Get Device Status return value*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) u8 error_code; /* Error Code */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) u8 ec_return_value; /* EC Return Value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) u16 devices; /* Current Device Status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) u32 reserved;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) } __attribute__((packed));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) struct hotkey_function_type_aa {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) u8 type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) u8 length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) u16 handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) u16 commun_func_bitmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) u16 application_func_bitmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) u16 media_func_bitmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) u16 display_func_bitmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) u16 others_func_bitmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) u8 commun_fn_key_number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) } __attribute__((packed));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) * Interface capability flags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) #define ACER_CAP_MAILLED BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) #define ACER_CAP_WIRELESS BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) #define ACER_CAP_BLUETOOTH BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) #define ACER_CAP_BRIGHTNESS BIT(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) #define ACER_CAP_THREEG BIT(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) #define ACER_CAP_SET_FUNCTION_MODE BIT(5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) #define ACER_CAP_KBD_DOCK BIT(6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) * Interface type flags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) enum interface_flags {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) ACER_AMW0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) ACER_AMW0_V2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) ACER_WMID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) ACER_WMID_v2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) #define ACER_DEFAULT_WIRELESS 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) #define ACER_DEFAULT_BLUETOOTH 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) #define ACER_DEFAULT_MAILLED 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) #define ACER_DEFAULT_THREEG 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) static int max_brightness = 0xF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) static int mailled = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) static int brightness = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) static int threeg = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) static int force_series;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) static int force_caps = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) static bool ec_raw_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) static bool has_type_aa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) static u16 commun_func_bitmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) static u8 commun_fn_key_number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) module_param(mailled, int, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) module_param(brightness, int, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) module_param(threeg, int, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) module_param(force_series, int, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) module_param(force_caps, int, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) module_param(ec_raw_mode, bool, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) MODULE_PARM_DESC(mailled, "Set initial state of Mail LED");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) MODULE_PARM_DESC(brightness, "Set initial LCD backlight brightness");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) MODULE_PARM_DESC(threeg, "Set initial state of 3G hardware");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) MODULE_PARM_DESC(force_series, "Force a different laptop series");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) MODULE_PARM_DESC(force_caps, "Force the capability bitmask to this value");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) MODULE_PARM_DESC(ec_raw_mode, "Enable EC raw mode");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) struct acer_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) int mailled;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) int threeg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) int brightness;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) struct acer_debug {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) struct dentry *root;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) u32 wmid_devices;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) static struct rfkill *wireless_rfkill;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) static struct rfkill *bluetooth_rfkill;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) static struct rfkill *threeg_rfkill;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) static bool rfkill_inited;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) /* Each low-level interface must define at least some of the following */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) struct wmi_interface {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) /* The WMI device type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) u32 type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) /* The capabilities this interface provides */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) u32 capability;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) /* Private data for the current interface */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) struct acer_data data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) /* debugfs entries associated with this interface */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) struct acer_debug debug;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) /* The static interface pointer, points to the currently detected interface */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) static struct wmi_interface *interface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) * Embedded Controller quirks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) * Some laptops require us to directly access the EC to either enable or query
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) * features that are not available through WMI.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) struct quirk_entry {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) u8 wireless;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) u8 mailled;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) s8 brightness;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) u8 bluetooth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) static struct quirk_entry *quirks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) static void __init set_quirks(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) if (!interface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) if (quirks->mailled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) interface->capability |= ACER_CAP_MAILLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) if (quirks->brightness)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) interface->capability |= ACER_CAP_BRIGHTNESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) static int __init dmi_matched(const struct dmi_system_id *dmi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) quirks = dmi->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) static int __init set_force_caps(const struct dmi_system_id *dmi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) if (force_caps == -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) force_caps = (uintptr_t)dmi->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) pr_info("Found %s, set force_caps to 0x%x\n", dmi->ident, force_caps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) static struct quirk_entry quirk_unknown = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) static struct quirk_entry quirk_acer_aspire_1520 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) .brightness = -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) static struct quirk_entry quirk_acer_travelmate_2490 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) .mailled = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) /* This AMW0 laptop has no bluetooth */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) static struct quirk_entry quirk_medion_md_98300 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) .wireless = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) static struct quirk_entry quirk_fujitsu_amilo_li_1718 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) .wireless = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) static struct quirk_entry quirk_lenovo_ideapad_s205 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) .wireless = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) /* The Aspire One has a dummy ACPI-WMI interface - disable it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) static const struct dmi_system_id acer_blacklist[] __initconst = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) .ident = "Acer Aspire One (SSD)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) DMI_MATCH(DMI_PRODUCT_NAME, "AOA110"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) .ident = "Acer Aspire One (HDD)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) DMI_MATCH(DMI_PRODUCT_NAME, "AOA150"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) static const struct dmi_system_id amw0_whitelist[] __initconst = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) .ident = "Acer",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) .ident = "Gateway",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) DMI_MATCH(DMI_SYS_VENDOR, "Gateway"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) .ident = "Packard Bell",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) DMI_MATCH(DMI_SYS_VENDOR, "Packard Bell"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) * This quirk table is only for Acer/Gateway/Packard Bell family
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) * that those machines are supported by acer-wmi driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) static const struct dmi_system_id acer_quirks[] __initconst = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) .callback = dmi_matched,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) .ident = "Acer Aspire 1360",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1360"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) .driver_data = &quirk_acer_aspire_1520,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) .callback = dmi_matched,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) .ident = "Acer Aspire 1520",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1520"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) .driver_data = &quirk_acer_aspire_1520,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) .callback = dmi_matched,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) .ident = "Acer Aspire 3100",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 3100"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) .driver_data = &quirk_acer_travelmate_2490,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) .callback = dmi_matched,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) .ident = "Acer Aspire 3610",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 3610"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) .driver_data = &quirk_acer_travelmate_2490,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) .callback = dmi_matched,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) .ident = "Acer Aspire 5100",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5100"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) .driver_data = &quirk_acer_travelmate_2490,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) .callback = dmi_matched,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) .ident = "Acer Aspire 5610",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5610"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) .driver_data = &quirk_acer_travelmate_2490,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) .callback = dmi_matched,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) .ident = "Acer Aspire 5630",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5630"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) .driver_data = &quirk_acer_travelmate_2490,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) .callback = dmi_matched,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) .ident = "Acer Aspire 5650",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5650"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) .driver_data = &quirk_acer_travelmate_2490,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) .callback = dmi_matched,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) .ident = "Acer Aspire 5680",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5680"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) .driver_data = &quirk_acer_travelmate_2490,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) .callback = dmi_matched,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) .ident = "Acer Aspire 9110",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 9110"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) .driver_data = &quirk_acer_travelmate_2490,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) .callback = dmi_matched,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) .ident = "Acer TravelMate 2490",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 2490"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) .driver_data = &quirk_acer_travelmate_2490,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) .callback = dmi_matched,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) .ident = "Acer TravelMate 4200",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 4200"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) .driver_data = &quirk_acer_travelmate_2490,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) .callback = set_force_caps,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) .ident = "Acer Aspire Switch 10E SW3-016",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) DMI_MATCH(DMI_PRODUCT_NAME, "Aspire SW3-016"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) .driver_data = (void *)ACER_CAP_KBD_DOCK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) .callback = set_force_caps,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) .ident = "Acer Aspire Switch 10 SW5-012",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) DMI_MATCH(DMI_PRODUCT_NAME, "Aspire SW5-012"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) .driver_data = (void *)ACER_CAP_KBD_DOCK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) .callback = set_force_caps,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) .ident = "Acer One 10 (S1003)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Acer"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "One S1003"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) .driver_data = (void *)ACER_CAP_KBD_DOCK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) * This quirk list is for those non-acer machines that have AMW0_GUID1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) * but supported by acer-wmi in past days. Keeping this quirk list here
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) * is only for backward compatible. Please do not add new machine to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) * here anymore. Those non-acer machines should be supported by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) * appropriate wmi drivers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) static const struct dmi_system_id non_acer_quirks[] __initconst = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) .callback = dmi_matched,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) .ident = "Fujitsu Siemens Amilo Li 1718",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Li 1718"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) .driver_data = &quirk_fujitsu_amilo_li_1718,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) .callback = dmi_matched,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) .ident = "Medion MD 98300",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) DMI_MATCH(DMI_SYS_VENDOR, "MEDION"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) DMI_MATCH(DMI_PRODUCT_NAME, "WAM2030"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) .driver_data = &quirk_medion_md_98300,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) .callback = dmi_matched,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) .ident = "Lenovo Ideapad S205",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) DMI_MATCH(DMI_PRODUCT_NAME, "10382LG"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) .driver_data = &quirk_lenovo_ideapad_s205,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) .callback = dmi_matched,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) .ident = "Lenovo Ideapad S205 (Brazos)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) DMI_MATCH(DMI_PRODUCT_NAME, "Brazos"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) .driver_data = &quirk_lenovo_ideapad_s205,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) .callback = dmi_matched,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) .ident = "Lenovo 3000 N200",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) DMI_MATCH(DMI_PRODUCT_NAME, "0687A31"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) .driver_data = &quirk_fujitsu_amilo_li_1718,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) .callback = dmi_matched,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) .ident = "Lenovo Ideapad S205-10382JG",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) DMI_MATCH(DMI_PRODUCT_NAME, "10382JG"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) .driver_data = &quirk_lenovo_ideapad_s205,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) .callback = dmi_matched,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) .ident = "Lenovo Ideapad S205-1038DPG",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) DMI_MATCH(DMI_PRODUCT_NAME, "1038DPG"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) .driver_data = &quirk_lenovo_ideapad_s205,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) static int __init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) video_set_backlight_video_vendor(const struct dmi_system_id *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) interface->capability &= ~ACER_CAP_BRIGHTNESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) pr_info("Brightness must be controlled by generic video driver\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) static const struct dmi_system_id video_vendor_dmi_table[] __initconst = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) .callback = video_set_backlight_video_vendor,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) .ident = "Acer TravelMate 4750",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) DMI_MATCH(DMI_BOARD_VENDOR, "Acer"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 4750"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) .callback = video_set_backlight_video_vendor,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) .ident = "Acer Extensa 5235",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) DMI_MATCH(DMI_BOARD_VENDOR, "Acer"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) DMI_MATCH(DMI_PRODUCT_NAME, "Extensa 5235"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) .callback = video_set_backlight_video_vendor,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) .ident = "Acer TravelMate 5760",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) DMI_MATCH(DMI_BOARD_VENDOR, "Acer"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 5760"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) .callback = video_set_backlight_video_vendor,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) .ident = "Acer Aspire 5750",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) DMI_MATCH(DMI_BOARD_VENDOR, "Acer"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5750"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) .callback = video_set_backlight_video_vendor,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) .ident = "Acer Aspire 5741",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) DMI_MATCH(DMI_BOARD_VENDOR, "Acer"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5741"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) * Note no video_set_backlight_video_vendor, we must use the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) * acer interface, as there is no native backlight interface.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) .ident = "Acer KAV80",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) DMI_MATCH(DMI_PRODUCT_NAME, "KAV80"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) /* Find which quirks are needed for a particular vendor/ model pair */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) static void __init find_quirks(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) if (!force_series) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) dmi_check_system(acer_quirks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) dmi_check_system(non_acer_quirks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) } else if (force_series == 2490) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) quirks = &quirk_acer_travelmate_2490;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) if (quirks == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) quirks = &quirk_unknown;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) set_quirks();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) * General interface convenience methods
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) static bool has_cap(u32 cap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) return interface->capability & cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) * AMW0 (V1) interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) struct wmab_args {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) u32 eax;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) u32 ebx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) u32 ecx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) u32 edx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) struct wmab_ret {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) u32 eax;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) u32 ebx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) u32 ecx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) u32 edx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) u32 eex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) static acpi_status wmab_execute(struct wmab_args *regbuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) struct acpi_buffer *result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) struct acpi_buffer input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) input.length = sizeof(struct wmab_args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) input.pointer = (u8 *)regbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) status = wmi_evaluate_method(AMW0_GUID1, 0, 1, &input, result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) static acpi_status AMW0_get_u32(u32 *value, u32 cap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) u8 result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) switch (cap) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) case ACER_CAP_MAILLED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) switch (quirks->mailled) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) err = ec_read(0xA, &result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) return AE_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) *value = (result >> 7) & 0x1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) return AE_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) case ACER_CAP_WIRELESS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) switch (quirks->wireless) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) err = ec_read(0x7B, &result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) return AE_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) *value = result & 0x1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) return AE_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) err = ec_read(0x71, &result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) return AE_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) *value = result & 0x1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) return AE_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) err = ec_read(0x78, &result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) return AE_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) *value = result & 0x1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) return AE_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) err = ec_read(0xA, &result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) return AE_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) *value = (result >> 2) & 0x1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) return AE_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) case ACER_CAP_BLUETOOTH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) switch (quirks->bluetooth) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) err = ec_read(0xA, &result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) return AE_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) *value = (result >> 4) & 0x1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) return AE_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) case ACER_CAP_BRIGHTNESS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) switch (quirks->brightness) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) err = ec_read(0x83, &result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) return AE_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) *value = result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) return AE_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) return AE_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) return AE_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) static acpi_status AMW0_set_u32(u32 value, u32 cap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) struct wmab_args args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) args.eax = ACER_AMW0_WRITE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) args.ebx = value ? (1<<8) : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) args.ecx = args.edx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) switch (cap) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) case ACER_CAP_MAILLED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) if (value > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) return AE_BAD_PARAMETER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) args.ebx |= ACER_AMW0_MAILLED_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) case ACER_CAP_WIRELESS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) if (value > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) return AE_BAD_PARAMETER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) args.ebx |= ACER_AMW0_WIRELESS_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) case ACER_CAP_BLUETOOTH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) if (value > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) return AE_BAD_PARAMETER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) args.ebx |= ACER_AMW0_BLUETOOTH_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) case ACER_CAP_BRIGHTNESS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) if (value > max_brightness)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) return AE_BAD_PARAMETER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) switch (quirks->brightness) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) return ec_write(0x83, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) return AE_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) /* Actually do the set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) return wmab_execute(&args, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) static acpi_status __init AMW0_find_mailled(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) struct wmab_args args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) struct wmab_ret ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) acpi_status status = AE_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) struct acpi_buffer out = { ACPI_ALLOCATE_BUFFER, NULL };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) union acpi_object *obj;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) args.eax = 0x86;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) args.ebx = args.ecx = args.edx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) status = wmab_execute(&args, &out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) if (ACPI_FAILURE(status))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) obj = (union acpi_object *) out.pointer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) if (obj && obj->type == ACPI_TYPE_BUFFER &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) obj->buffer.length == sizeof(struct wmab_ret)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) ret = *((struct wmab_ret *) obj->buffer.pointer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) kfree(out.pointer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) return AE_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) if (ret.eex & 0x1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) interface->capability |= ACER_CAP_MAILLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) kfree(out.pointer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) return AE_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) static const struct acpi_device_id norfkill_ids[] __initconst = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) { "VPC2004", 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) { "IBM0068", 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) { "LEN0068", 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) { "SNY5001", 0}, /* sony-laptop in charge */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) { "HPQ6601", 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) { "", 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) static int __init AMW0_set_cap_acpi_check_device(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) const struct acpi_device_id *id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) for (id = norfkill_ids; id->id[0]; id++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) if (acpi_dev_found(id->id))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) static acpi_status __init AMW0_set_capabilities(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) struct wmab_args args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) struct wmab_ret ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) struct acpi_buffer out = { ACPI_ALLOCATE_BUFFER, NULL };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) union acpi_object *obj;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) * On laptops with this strange GUID (non Acer), normal probing doesn't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) * work.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) if (wmi_has_guid(AMW0_GUID2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) if ((quirks != &quirk_unknown) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) !AMW0_set_cap_acpi_check_device())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) interface->capability |= ACER_CAP_WIRELESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) return AE_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) args.eax = ACER_AMW0_WRITE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) args.ecx = args.edx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) args.ebx = 0xa2 << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) args.ebx |= ACER_AMW0_WIRELESS_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) status = wmab_execute(&args, &out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) if (ACPI_FAILURE(status))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) obj = out.pointer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) if (obj && obj->type == ACPI_TYPE_BUFFER &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) obj->buffer.length == sizeof(struct wmab_ret)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) ret = *((struct wmab_ret *) obj->buffer.pointer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) status = AE_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) if (ret.eax & 0x1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) interface->capability |= ACER_CAP_WIRELESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) args.ebx = 2 << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) args.ebx |= ACER_AMW0_BLUETOOTH_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) * It's ok to use existing buffer for next wmab_execute call.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) * But we need to kfree(out.pointer) if next wmab_execute fail.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) status = wmab_execute(&args, &out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) if (ACPI_FAILURE(status))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) obj = (union acpi_object *) out.pointer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) if (obj && obj->type == ACPI_TYPE_BUFFER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) && obj->buffer.length == sizeof(struct wmab_ret)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) ret = *((struct wmab_ret *) obj->buffer.pointer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) status = AE_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) if (ret.eax & 0x1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) interface->capability |= ACER_CAP_BLUETOOTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) * This appears to be safe to enable, since all Wistron based laptops
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) * appear to use the same EC register for brightness, even if they
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) * differ for wireless, etc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) if (quirks->brightness >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) interface->capability |= ACER_CAP_BRIGHTNESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) status = AE_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) kfree(out.pointer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) static struct wmi_interface AMW0_interface = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) .type = ACER_AMW0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) static struct wmi_interface AMW0_V2_interface = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) .type = ACER_AMW0_V2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) * New interface (The WMID interface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) static acpi_status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) WMI_execute_u32(u32 method_id, u32 in, u32 *out)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) struct acpi_buffer input = { (acpi_size) sizeof(u32), (void *)(&in) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) struct acpi_buffer result = { ACPI_ALLOCATE_BUFFER, NULL };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) union acpi_object *obj;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) u32 tmp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) status = wmi_evaluate_method(WMID_GUID1, 0, method_id, &input, &result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) if (ACPI_FAILURE(status))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) obj = (union acpi_object *) result.pointer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) if (obj) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) if (obj->type == ACPI_TYPE_BUFFER &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) (obj->buffer.length == sizeof(u32) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) obj->buffer.length == sizeof(u64))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) tmp = *((u32 *) obj->buffer.pointer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) } else if (obj->type == ACPI_TYPE_INTEGER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) tmp = (u32) obj->integer.value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) if (out)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) *out = tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) kfree(result.pointer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) static acpi_status WMID_get_u32(u32 *value, u32 cap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) u8 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) u32 result, method_id = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) switch (cap) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) case ACER_CAP_WIRELESS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) method_id = ACER_WMID_GET_WIRELESS_METHODID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) case ACER_CAP_BLUETOOTH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) method_id = ACER_WMID_GET_BLUETOOTH_METHODID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) case ACER_CAP_BRIGHTNESS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) method_id = ACER_WMID_GET_BRIGHTNESS_METHODID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) case ACER_CAP_THREEG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) method_id = ACER_WMID_GET_THREEG_METHODID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) case ACER_CAP_MAILLED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) if (quirks->mailled == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) ec_read(0x9f, &tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) *value = tmp & 0x1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) return AE_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) status = WMI_execute_u32(method_id, 0, &result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) if (ACPI_SUCCESS(status))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) *value = (u8)result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) static acpi_status WMID_set_u32(u32 value, u32 cap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) u32 method_id = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) char param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) switch (cap) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) case ACER_CAP_BRIGHTNESS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) if (value > max_brightness)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) return AE_BAD_PARAMETER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) method_id = ACER_WMID_SET_BRIGHTNESS_METHODID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) case ACER_CAP_WIRELESS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) if (value > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) return AE_BAD_PARAMETER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) method_id = ACER_WMID_SET_WIRELESS_METHODID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) case ACER_CAP_BLUETOOTH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) if (value > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) return AE_BAD_PARAMETER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) method_id = ACER_WMID_SET_BLUETOOTH_METHODID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) case ACER_CAP_THREEG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) if (value > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) return AE_BAD_PARAMETER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) method_id = ACER_WMID_SET_THREEG_METHODID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) case ACER_CAP_MAILLED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) if (value > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) return AE_BAD_PARAMETER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) if (quirks->mailled == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) param = value ? 0x92 : 0x93;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) i8042_lock_chip();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) i8042_command(¶m, 0x1059);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) i8042_unlock_chip();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) return AE_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) return WMI_execute_u32(method_id, (u32)value, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) static acpi_status wmid3_get_device_status(u32 *value, u16 device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) struct wmid3_gds_return_value return_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) union acpi_object *obj;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) struct wmid3_gds_get_input_param params = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) .function_num = 0x1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) .hotkey_number = commun_fn_key_number,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) .devices = device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) struct acpi_buffer input = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) sizeof(struct wmid3_gds_get_input_param),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) ¶ms
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) status = wmi_evaluate_method(WMID_GUID3, 0, 0x2, &input, &output);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) if (ACPI_FAILURE(status))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) obj = output.pointer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) if (!obj)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) return AE_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) else if (obj->type != ACPI_TYPE_BUFFER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) kfree(obj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) return AE_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) if (obj->buffer.length != 8) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) pr_warn("Unknown buffer length %d\n", obj->buffer.length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) kfree(obj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) return AE_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) return_value = *((struct wmid3_gds_return_value *)obj->buffer.pointer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) kfree(obj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) if (return_value.error_code || return_value.ec_return_value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) pr_warn("Get 0x%x Device Status failed: 0x%x - 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) return_value.error_code,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) return_value.ec_return_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) *value = !!(return_value.devices & device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) static acpi_status wmid_v2_get_u32(u32 *value, u32 cap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) u16 device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) switch (cap) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) case ACER_CAP_WIRELESS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) device = ACER_WMID3_GDS_WIRELESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) case ACER_CAP_BLUETOOTH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) device = ACER_WMID3_GDS_BLUETOOTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) case ACER_CAP_THREEG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) device = ACER_WMID3_GDS_THREEG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) return AE_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) return wmid3_get_device_status(value, device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) static acpi_status wmid3_set_device_status(u32 value, u16 device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) struct wmid3_gds_return_value return_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) union acpi_object *obj;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) u16 devices;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) struct wmid3_gds_get_input_param get_params = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) .function_num = 0x1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) .hotkey_number = commun_fn_key_number,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) .devices = commun_func_bitmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) struct acpi_buffer get_input = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) sizeof(struct wmid3_gds_get_input_param),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) &get_params
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) struct wmid3_gds_set_input_param set_params = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) .function_num = 0x2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) .hotkey_number = commun_fn_key_number,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) .devices = commun_func_bitmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) struct acpi_buffer set_input = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) sizeof(struct wmid3_gds_set_input_param),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) &set_params
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) struct acpi_buffer output2 = { ACPI_ALLOCATE_BUFFER, NULL };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) status = wmi_evaluate_method(WMID_GUID3, 0, 0x2, &get_input, &output);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) if (ACPI_FAILURE(status))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) obj = output.pointer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) if (!obj)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) return AE_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) else if (obj->type != ACPI_TYPE_BUFFER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) kfree(obj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) return AE_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) if (obj->buffer.length != 8) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) pr_warn("Unknown buffer length %d\n", obj->buffer.length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) kfree(obj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) return AE_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) return_value = *((struct wmid3_gds_return_value *)obj->buffer.pointer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) kfree(obj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) if (return_value.error_code || return_value.ec_return_value) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) pr_warn("Get Current Device Status failed: 0x%x - 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) return_value.error_code,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) return_value.ec_return_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) devices = return_value.devices;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) set_params.devices = (value) ? (devices | device) : (devices & ~device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) status = wmi_evaluate_method(WMID_GUID3, 0, 0x1, &set_input, &output2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) if (ACPI_FAILURE(status))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) obj = output2.pointer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) if (!obj)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) return AE_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) else if (obj->type != ACPI_TYPE_BUFFER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) kfree(obj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) return AE_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) if (obj->buffer.length != 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) pr_warn("Unknown buffer length %d\n", obj->buffer.length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) kfree(obj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) return AE_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) return_value = *((struct wmid3_gds_return_value *)obj->buffer.pointer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) kfree(obj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) if (return_value.error_code || return_value.ec_return_value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) pr_warn("Set Device Status failed: 0x%x - 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) return_value.error_code,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) return_value.ec_return_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) static acpi_status wmid_v2_set_u32(u32 value, u32 cap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) u16 device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) switch (cap) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) case ACER_CAP_WIRELESS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) device = ACER_WMID3_GDS_WIRELESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) case ACER_CAP_BLUETOOTH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) device = ACER_WMID3_GDS_BLUETOOTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) case ACER_CAP_THREEG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) device = ACER_WMID3_GDS_THREEG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) return AE_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) return wmid3_set_device_status(value, device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) static void __init type_aa_dmi_decode(const struct dmi_header *header, void *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) struct hotkey_function_type_aa *type_aa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) /* We are looking for OEM-specific Type AAh */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) if (header->type != 0xAA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) has_type_aa = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) type_aa = (struct hotkey_function_type_aa *) header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) pr_info("Function bitmap for Communication Button: 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) type_aa->commun_func_bitmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) commun_func_bitmap = type_aa->commun_func_bitmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) if (type_aa->commun_func_bitmap & ACER_WMID3_GDS_WIRELESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) interface->capability |= ACER_CAP_WIRELESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) if (type_aa->commun_func_bitmap & ACER_WMID3_GDS_THREEG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) interface->capability |= ACER_CAP_THREEG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) if (type_aa->commun_func_bitmap & ACER_WMID3_GDS_BLUETOOTH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) interface->capability |= ACER_CAP_BLUETOOTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) if (type_aa->commun_func_bitmap & ACER_WMID3_GDS_RFBTN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) commun_func_bitmap &= ~ACER_WMID3_GDS_RFBTN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) commun_fn_key_number = type_aa->commun_fn_key_number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) static acpi_status __init WMID_set_capabilities(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) struct acpi_buffer out = {ACPI_ALLOCATE_BUFFER, NULL};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) union acpi_object *obj;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) u32 devices;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) status = wmi_query_block(WMID_GUID2, 0, &out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) if (ACPI_FAILURE(status))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) obj = (union acpi_object *) out.pointer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) if (obj) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) if (obj->type == ACPI_TYPE_BUFFER &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) (obj->buffer.length == sizeof(u32) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) obj->buffer.length == sizeof(u64))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) devices = *((u32 *) obj->buffer.pointer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) } else if (obj->type == ACPI_TYPE_INTEGER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) devices = (u32) obj->integer.value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) kfree(out.pointer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) return AE_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) kfree(out.pointer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) return AE_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) pr_info("Function bitmap for Communication Device: 0x%x\n", devices);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) if (devices & 0x07)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) interface->capability |= ACER_CAP_WIRELESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) if (devices & 0x40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) interface->capability |= ACER_CAP_THREEG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) if (devices & 0x10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) interface->capability |= ACER_CAP_BLUETOOTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) if (!(devices & 0x20))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) max_brightness = 0x9;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) kfree(out.pointer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) static struct wmi_interface wmid_interface = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) .type = ACER_WMID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) static struct wmi_interface wmid_v2_interface = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) .type = ACER_WMID_v2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) * Generic Device (interface-independent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) static acpi_status get_u32(u32 *value, u32 cap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) acpi_status status = AE_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) switch (interface->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) case ACER_AMW0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) status = AMW0_get_u32(value, cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) case ACER_AMW0_V2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) if (cap == ACER_CAP_MAILLED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) status = AMW0_get_u32(value, cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) case ACER_WMID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) status = WMID_get_u32(value, cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) case ACER_WMID_v2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) if (cap & (ACER_CAP_WIRELESS |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) ACER_CAP_BLUETOOTH |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) ACER_CAP_THREEG))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) status = wmid_v2_get_u32(value, cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) else if (wmi_has_guid(WMID_GUID2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) status = WMID_get_u32(value, cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) static acpi_status set_u32(u32 value, u32 cap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) if (interface->capability & cap) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) switch (interface->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) case ACER_AMW0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) return AMW0_set_u32(value, cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) case ACER_AMW0_V2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) if (cap == ACER_CAP_MAILLED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) return AMW0_set_u32(value, cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) * On some models, some WMID methods don't toggle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) * properly. For those cases, we want to run the AMW0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) * method afterwards to be certain we've really toggled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) * the device state.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) if (cap == ACER_CAP_WIRELESS ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) cap == ACER_CAP_BLUETOOTH) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) status = WMID_set_u32(value, cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) if (ACPI_FAILURE(status))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) return AMW0_set_u32(value, cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) case ACER_WMID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) return WMID_set_u32(value, cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) case ACER_WMID_v2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) if (cap & (ACER_CAP_WIRELESS |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) ACER_CAP_BLUETOOTH |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) ACER_CAP_THREEG))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) return wmid_v2_set_u32(value, cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) else if (wmi_has_guid(WMID_GUID2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) return WMID_set_u32(value, cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) return AE_BAD_PARAMETER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) return AE_BAD_PARAMETER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) static void __init acer_commandline_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) * These will all fail silently if the value given is invalid, or the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) * capability isn't available on the given interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) if (mailled >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) set_u32(mailled, ACER_CAP_MAILLED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) if (!has_type_aa && threeg >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) set_u32(threeg, ACER_CAP_THREEG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) if (brightness >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) set_u32(brightness, ACER_CAP_BRIGHTNESS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) * LED device (Mail LED only, no other LEDs known yet)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) static void mail_led_set(struct led_classdev *led_cdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) enum led_brightness value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) set_u32(value, ACER_CAP_MAILLED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) static struct led_classdev mail_led = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) .name = "acer-wmi::mail",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) .brightness_set = mail_led_set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) static int acer_led_init(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) return led_classdev_register(dev, &mail_led);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) static void acer_led_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) set_u32(LED_OFF, ACER_CAP_MAILLED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) led_classdev_unregister(&mail_led);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) * Backlight device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) static struct backlight_device *acer_backlight_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) static int read_brightness(struct backlight_device *bd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) u32 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) get_u32(&value, ACER_CAP_BRIGHTNESS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) return value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) static int update_bl_status(struct backlight_device *bd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) int intensity = bd->props.brightness;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) if (bd->props.power != FB_BLANK_UNBLANK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) intensity = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) if (bd->props.fb_blank != FB_BLANK_UNBLANK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) intensity = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) set_u32(intensity, ACER_CAP_BRIGHTNESS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) static const struct backlight_ops acer_bl_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) .get_brightness = read_brightness,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) .update_status = update_bl_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) static int acer_backlight_init(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) struct backlight_properties props;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) struct backlight_device *bd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) memset(&props, 0, sizeof(struct backlight_properties));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) props.type = BACKLIGHT_PLATFORM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) props.max_brightness = max_brightness;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) bd = backlight_device_register("acer-wmi", dev, NULL, &acer_bl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) &props);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) if (IS_ERR(bd)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) pr_err("Could not register Acer backlight device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) acer_backlight_device = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) return PTR_ERR(bd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) acer_backlight_device = bd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) bd->props.power = FB_BLANK_UNBLANK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) bd->props.brightness = read_brightness(bd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) backlight_update_status(bd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) static void acer_backlight_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) backlight_device_unregister(acer_backlight_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) * Accelerometer device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) static acpi_handle gsensor_handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) static int acer_gsensor_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) struct acpi_buffer output;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) union acpi_object out_obj;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) output.length = sizeof(out_obj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) output.pointer = &out_obj;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) status = acpi_evaluate_object(gsensor_handle, "_INI", NULL, &output);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) if (ACPI_FAILURE(status))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) static int acer_gsensor_open(struct input_dev *input)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) return acer_gsensor_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) static int acer_gsensor_event(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) struct acpi_buffer output;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) union acpi_object out_obj[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) if (!acer_wmi_accel_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) output.length = sizeof(out_obj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) output.pointer = out_obj;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) status = acpi_evaluate_object(gsensor_handle, "RDVL", NULL, &output);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) if (ACPI_FAILURE(status))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) if (out_obj->package.count != 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) input_report_abs(acer_wmi_accel_dev, ABS_X,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) (s16)out_obj->package.elements[0].integer.value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) input_report_abs(acer_wmi_accel_dev, ABS_Y,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) (s16)out_obj->package.elements[1].integer.value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) input_report_abs(acer_wmi_accel_dev, ABS_Z,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) (s16)out_obj->package.elements[2].integer.value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) input_sync(acer_wmi_accel_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) * Switch series keyboard dock status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) static int acer_kbd_dock_state_to_sw_tablet_mode(u8 kbd_dock_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) switch (kbd_dock_state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) case 0x01: /* Docked, traditional clamshell laptop mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) case 0x04: /* Stand-alone tablet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) case 0x40: /* Docked, tent mode, keyboard not usable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) pr_warn("Unknown kbd_dock_state 0x%02x\n", kbd_dock_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) static void acer_kbd_dock_get_initial_state(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) u8 *output, input[8] = { 0x05, 0x00, };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) struct acpi_buffer input_buf = { sizeof(input), input };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) struct acpi_buffer output_buf = { ACPI_ALLOCATE_BUFFER, NULL };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) union acpi_object *obj;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) int sw_tablet_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) status = wmi_evaluate_method(WMID_GUID3, 0, 0x2, &input_buf, &output_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) if (ACPI_FAILURE(status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) ACPI_EXCEPTION((AE_INFO, status, "Error getting keyboard-dock initial status"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) obj = output_buf.pointer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) if (!obj || obj->type != ACPI_TYPE_BUFFER || obj->buffer.length != 8) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) pr_err("Unexpected output format getting keyboard-dock initial status\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) goto out_free_obj;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) output = obj->buffer.pointer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) if (output[0] != 0x00 || (output[3] != 0x05 && output[3] != 0x45)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) pr_err("Unexpected output [0]=0x%02x [3]=0x%02x getting keyboard-dock initial status\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) output[0], output[3]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) goto out_free_obj;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) sw_tablet_mode = acer_kbd_dock_state_to_sw_tablet_mode(output[4]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) input_report_switch(acer_wmi_input_dev, SW_TABLET_MODE, sw_tablet_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) out_free_obj:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) kfree(obj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) static void acer_kbd_dock_event(const struct event_return_value *event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) int sw_tablet_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) if (!has_cap(ACER_CAP_KBD_DOCK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) sw_tablet_mode = acer_kbd_dock_state_to_sw_tablet_mode(event->kbd_dock_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) input_report_switch(acer_wmi_input_dev, SW_TABLET_MODE, sw_tablet_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) input_sync(acer_wmi_input_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) * Rfkill devices
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) static void acer_rfkill_update(struct work_struct *ignored);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) static DECLARE_DELAYED_WORK(acer_rfkill_work, acer_rfkill_update);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) static void acer_rfkill_update(struct work_struct *ignored)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) u32 state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) if (has_cap(ACER_CAP_WIRELESS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) status = get_u32(&state, ACER_CAP_WIRELESS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) if (ACPI_SUCCESS(status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) if (quirks->wireless == 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) rfkill_set_hw_state(wireless_rfkill, !state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) rfkill_set_sw_state(wireless_rfkill, !state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) if (has_cap(ACER_CAP_BLUETOOTH)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) status = get_u32(&state, ACER_CAP_BLUETOOTH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) if (ACPI_SUCCESS(status))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) rfkill_set_sw_state(bluetooth_rfkill, !state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) if (has_cap(ACER_CAP_THREEG) && wmi_has_guid(WMID_GUID3)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) status = get_u32(&state, ACER_WMID3_GDS_THREEG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) if (ACPI_SUCCESS(status))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) rfkill_set_sw_state(threeg_rfkill, !state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) schedule_delayed_work(&acer_rfkill_work, round_jiffies_relative(HZ));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) static int acer_rfkill_set(void *data, bool blocked)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) u32 cap = (unsigned long)data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) if (rfkill_inited) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) status = set_u32(!blocked, cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) if (ACPI_FAILURE(status))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) static const struct rfkill_ops acer_rfkill_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) .set_block = acer_rfkill_set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) static struct rfkill *acer_rfkill_register(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) enum rfkill_type type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) char *name, u32 cap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) struct rfkill *rfkill_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) u32 state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) rfkill_dev = rfkill_alloc(name, dev, type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) &acer_rfkill_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) (void *)(unsigned long)cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) if (!rfkill_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) status = get_u32(&state, cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) err = rfkill_register(rfkill_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) rfkill_destroy(rfkill_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) return ERR_PTR(err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) if (ACPI_SUCCESS(status))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) rfkill_set_sw_state(rfkill_dev, !state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) return rfkill_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) static int acer_rfkill_init(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) if (has_cap(ACER_CAP_WIRELESS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) wireless_rfkill = acer_rfkill_register(dev, RFKILL_TYPE_WLAN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) "acer-wireless", ACER_CAP_WIRELESS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) if (IS_ERR(wireless_rfkill)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) err = PTR_ERR(wireless_rfkill);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) goto error_wireless;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) if (has_cap(ACER_CAP_BLUETOOTH)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) bluetooth_rfkill = acer_rfkill_register(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) RFKILL_TYPE_BLUETOOTH, "acer-bluetooth",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) ACER_CAP_BLUETOOTH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) if (IS_ERR(bluetooth_rfkill)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) err = PTR_ERR(bluetooth_rfkill);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) goto error_bluetooth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) if (has_cap(ACER_CAP_THREEG)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) threeg_rfkill = acer_rfkill_register(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) RFKILL_TYPE_WWAN, "acer-threeg",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) ACER_CAP_THREEG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) if (IS_ERR(threeg_rfkill)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) err = PTR_ERR(threeg_rfkill);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) goto error_threeg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) rfkill_inited = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) if ((ec_raw_mode || !wmi_has_guid(ACERWMID_EVENT_GUID)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) has_cap(ACER_CAP_WIRELESS | ACER_CAP_BLUETOOTH | ACER_CAP_THREEG))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) schedule_delayed_work(&acer_rfkill_work,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) round_jiffies_relative(HZ));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) error_threeg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) if (has_cap(ACER_CAP_BLUETOOTH)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) rfkill_unregister(bluetooth_rfkill);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) rfkill_destroy(bluetooth_rfkill);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) error_bluetooth:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) if (has_cap(ACER_CAP_WIRELESS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) rfkill_unregister(wireless_rfkill);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) rfkill_destroy(wireless_rfkill);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) error_wireless:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) static void acer_rfkill_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) if ((ec_raw_mode || !wmi_has_guid(ACERWMID_EVENT_GUID)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) has_cap(ACER_CAP_WIRELESS | ACER_CAP_BLUETOOTH | ACER_CAP_THREEG))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) cancel_delayed_work_sync(&acer_rfkill_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) if (has_cap(ACER_CAP_WIRELESS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) rfkill_unregister(wireless_rfkill);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) rfkill_destroy(wireless_rfkill);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) if (has_cap(ACER_CAP_BLUETOOTH)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) rfkill_unregister(bluetooth_rfkill);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) rfkill_destroy(bluetooth_rfkill);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) if (has_cap(ACER_CAP_THREEG)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) rfkill_unregister(threeg_rfkill);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) rfkill_destroy(threeg_rfkill);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) static void acer_wmi_notify(u32 value, void *context)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) union acpi_object *obj;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) struct event_return_value return_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) u16 device_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) const struct key_entry *key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) u32 scancode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) status = wmi_get_event_data(value, &response);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) if (status != AE_OK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) pr_warn("bad event status 0x%x\n", status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) obj = (union acpi_object *)response.pointer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) if (!obj)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) if (obj->type != ACPI_TYPE_BUFFER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) pr_warn("Unknown response received %d\n", obj->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) kfree(obj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) if (obj->buffer.length != 8) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) pr_warn("Unknown buffer length %d\n", obj->buffer.length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) kfree(obj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) return_value = *((struct event_return_value *)obj->buffer.pointer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) kfree(obj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) switch (return_value.function) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) case WMID_HOTKEY_EVENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) device_state = return_value.device_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) pr_debug("device state: 0x%x\n", device_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) key = sparse_keymap_entry_from_scancode(acer_wmi_input_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) return_value.key_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) if (!key) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) pr_warn("Unknown key number - 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) return_value.key_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) scancode = return_value.key_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) switch (key->keycode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) case KEY_WLAN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) case KEY_BLUETOOTH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) if (has_cap(ACER_CAP_WIRELESS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) rfkill_set_sw_state(wireless_rfkill,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) !(device_state & ACER_WMID3_GDS_WIRELESS));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) if (has_cap(ACER_CAP_THREEG))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) rfkill_set_sw_state(threeg_rfkill,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) !(device_state & ACER_WMID3_GDS_THREEG));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) if (has_cap(ACER_CAP_BLUETOOTH))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) rfkill_set_sw_state(bluetooth_rfkill,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) !(device_state & ACER_WMID3_GDS_BLUETOOTH));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) case KEY_TOUCHPAD_TOGGLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) scancode = (device_state & ACER_WMID3_GDS_TOUCHPAD) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) KEY_TOUCHPAD_ON : KEY_TOUCHPAD_OFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) sparse_keymap_report_event(acer_wmi_input_dev, scancode, 1, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) case WMID_ACCEL_OR_KBD_DOCK_EVENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) acer_gsensor_event();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) acer_kbd_dock_event(&return_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) pr_warn("Unknown function number - %d - %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) return_value.function, return_value.key_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) static acpi_status __init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) wmid3_set_function_mode(struct func_input_params *params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) struct func_return_value *return_value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) union acpi_object *obj;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) struct acpi_buffer input = { sizeof(struct func_input_params), params };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) status = wmi_evaluate_method(WMID_GUID3, 0, 0x1, &input, &output);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) if (ACPI_FAILURE(status))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) obj = output.pointer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) if (!obj)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) return AE_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) else if (obj->type != ACPI_TYPE_BUFFER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) kfree(obj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) return AE_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) if (obj->buffer.length != 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) pr_warn("Unknown buffer length %d\n", obj->buffer.length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) kfree(obj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) return AE_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) *return_value = *((struct func_return_value *)obj->buffer.pointer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) kfree(obj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) static int __init acer_wmi_enable_ec_raw(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) struct func_return_value return_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) struct func_input_params params = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) .function_num = 0x1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) .commun_devices = 0xFFFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) .devices = 0xFFFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) .app_status = 0x00, /* Launch Manager Deactive */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) .app_mask = 0x01,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) status = wmid3_set_function_mode(¶ms, &return_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) if (return_value.error_code || return_value.ec_return_value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) pr_warn("Enabling EC raw mode failed: 0x%x - 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) return_value.error_code,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) return_value.ec_return_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) pr_info("Enabled EC raw mode\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) static int __init acer_wmi_enable_lm(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) struct func_return_value return_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) struct func_input_params params = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) .function_num = 0x1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) .commun_devices = 0xFFFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) .devices = 0xFFFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) .app_status = 0x01, /* Launch Manager Active */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) .app_mask = 0x01,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) status = wmid3_set_function_mode(¶ms, &return_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) if (return_value.error_code || return_value.ec_return_value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) pr_warn("Enabling Launch Manager failed: 0x%x - 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) return_value.error_code,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) return_value.ec_return_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) static int __init acer_wmi_enable_rf_button(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) struct func_return_value return_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) struct func_input_params params = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) .function_num = 0x1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) .commun_devices = 0xFFFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) .devices = 0xFFFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) .app_status = 0x10, /* RF Button Active */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) .app_mask = 0x10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) status = wmid3_set_function_mode(¶ms, &return_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) if (return_value.error_code || return_value.ec_return_value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) pr_warn("Enabling RF Button failed: 0x%x - 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) return_value.error_code,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) return_value.ec_return_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) static int __init acer_wmi_accel_setup(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) struct acpi_device *adev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) adev = acpi_dev_get_first_match_dev("BST0001", NULL, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) if (!adev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) gsensor_handle = acpi_device_handle(adev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) acpi_dev_put(adev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) acer_wmi_accel_dev = input_allocate_device();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) if (!acer_wmi_accel_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) acer_wmi_accel_dev->open = acer_gsensor_open;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) acer_wmi_accel_dev->name = "Acer BMA150 accelerometer";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) acer_wmi_accel_dev->phys = "wmi/input1";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) acer_wmi_accel_dev->id.bustype = BUS_HOST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) acer_wmi_accel_dev->evbit[0] = BIT_MASK(EV_ABS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) input_set_abs_params(acer_wmi_accel_dev, ABS_X, -16384, 16384, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) input_set_abs_params(acer_wmi_accel_dev, ABS_Y, -16384, 16384, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) input_set_abs_params(acer_wmi_accel_dev, ABS_Z, -16384, 16384, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) err = input_register_device(acer_wmi_accel_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) goto err_free_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) err_free_dev:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) input_free_device(acer_wmi_accel_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) static int __init acer_wmi_input_setup(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) acer_wmi_input_dev = input_allocate_device();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) if (!acer_wmi_input_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) acer_wmi_input_dev->name = "Acer WMI hotkeys";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) acer_wmi_input_dev->phys = "wmi/input0";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) acer_wmi_input_dev->id.bustype = BUS_HOST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) err = sparse_keymap_setup(acer_wmi_input_dev, acer_wmi_keymap, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) goto err_free_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) if (has_cap(ACER_CAP_KBD_DOCK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) input_set_capability(acer_wmi_input_dev, EV_SW, SW_TABLET_MODE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) status = wmi_install_notify_handler(ACERWMID_EVENT_GUID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) acer_wmi_notify, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) if (ACPI_FAILURE(status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) err = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) goto err_free_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) if (has_cap(ACER_CAP_KBD_DOCK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) acer_kbd_dock_get_initial_state();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) err = input_register_device(acer_wmi_input_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) goto err_uninstall_notifier;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) err_uninstall_notifier:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) wmi_remove_notify_handler(ACERWMID_EVENT_GUID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) err_free_dev:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) input_free_device(acer_wmi_input_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) static void acer_wmi_input_destroy(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) wmi_remove_notify_handler(ACERWMID_EVENT_GUID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) input_unregister_device(acer_wmi_input_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) * debugfs functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) static u32 get_wmid_devices(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) struct acpi_buffer out = {ACPI_ALLOCATE_BUFFER, NULL};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) union acpi_object *obj;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) u32 devices = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) status = wmi_query_block(WMID_GUID2, 0, &out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) if (ACPI_FAILURE(status))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) obj = (union acpi_object *) out.pointer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) if (obj) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) if (obj->type == ACPI_TYPE_BUFFER &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) (obj->buffer.length == sizeof(u32) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) obj->buffer.length == sizeof(u64))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) devices = *((u32 *) obj->buffer.pointer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) } else if (obj->type == ACPI_TYPE_INTEGER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) devices = (u32) obj->integer.value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) kfree(out.pointer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) return devices;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) * Platform device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) static int acer_platform_probe(struct platform_device *device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) if (has_cap(ACER_CAP_MAILLED)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) err = acer_led_init(&device->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) goto error_mailled;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) if (has_cap(ACER_CAP_BRIGHTNESS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) err = acer_backlight_init(&device->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) goto error_brightness;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) err = acer_rfkill_init(&device->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) goto error_rfkill;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) error_rfkill:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) if (has_cap(ACER_CAP_BRIGHTNESS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) acer_backlight_exit();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) error_brightness:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) if (has_cap(ACER_CAP_MAILLED))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) acer_led_exit();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) error_mailled:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) static int acer_platform_remove(struct platform_device *device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) if (has_cap(ACER_CAP_MAILLED))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) acer_led_exit();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) if (has_cap(ACER_CAP_BRIGHTNESS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) acer_backlight_exit();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) acer_rfkill_exit();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) #ifdef CONFIG_PM_SLEEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) static int acer_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) u32 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) struct acer_data *data = &interface->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) if (!data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) if (has_cap(ACER_CAP_MAILLED)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) get_u32(&value, ACER_CAP_MAILLED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) set_u32(LED_OFF, ACER_CAP_MAILLED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) data->mailled = value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) if (has_cap(ACER_CAP_BRIGHTNESS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) get_u32(&value, ACER_CAP_BRIGHTNESS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) data->brightness = value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) static int acer_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) struct acer_data *data = &interface->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) if (!data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) if (has_cap(ACER_CAP_MAILLED))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) set_u32(data->mailled, ACER_CAP_MAILLED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) if (has_cap(ACER_CAP_BRIGHTNESS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) set_u32(data->brightness, ACER_CAP_BRIGHTNESS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) if (acer_wmi_accel_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) acer_gsensor_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) #define acer_suspend NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) #define acer_resume NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) static SIMPLE_DEV_PM_OPS(acer_pm, acer_suspend, acer_resume);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) static void acer_platform_shutdown(struct platform_device *device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) struct acer_data *data = &interface->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) if (!data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) if (has_cap(ACER_CAP_MAILLED))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) set_u32(LED_OFF, ACER_CAP_MAILLED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) static struct platform_driver acer_platform_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) .name = "acer-wmi",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) .pm = &acer_pm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) .probe = acer_platform_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) .remove = acer_platform_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) .shutdown = acer_platform_shutdown,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) static struct platform_device *acer_platform_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) static void remove_debugfs(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) debugfs_remove_recursive(interface->debug.root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) static void __init create_debugfs(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) interface->debug.root = debugfs_create_dir("acer-wmi", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) debugfs_create_u32("devices", S_IRUGO, interface->debug.root,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) &interface->debug.wmid_devices);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) static int __init acer_wmi_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) pr_info("Acer Laptop ACPI-WMI Extras\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) if (dmi_check_system(acer_blacklist)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) pr_info("Blacklisted hardware detected - not loading\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) find_quirks();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) * The AMW0_GUID1 wmi is not only found on Acer family but also other
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) * machines like Lenovo, Fujitsu and Medion. In the past days,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) * acer-wmi driver handled those non-Acer machines by quirks list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) * But actually acer-wmi driver was loaded on any machines that have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) * AMW0_GUID1. This behavior is strange because those machines should
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) * be supported by appropriate wmi drivers. e.g. fujitsu-laptop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) * ideapad-laptop. So, here checks the machine that has AMW0_GUID1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) * should be in Acer/Gateway/Packard Bell white list, or it's already
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) * in the past quirk list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) if (wmi_has_guid(AMW0_GUID1) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) !dmi_check_system(amw0_whitelist) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) quirks == &quirk_unknown) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) pr_debug("Unsupported machine has AMW0_GUID1, unable to load\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) * Detect which ACPI-WMI interface we're using.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269) if (wmi_has_guid(AMW0_GUID1) && wmi_has_guid(WMID_GUID1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) interface = &AMW0_V2_interface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272) if (!wmi_has_guid(AMW0_GUID1) && wmi_has_guid(WMID_GUID1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273) interface = &wmid_interface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) if (wmi_has_guid(WMID_GUID3))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) interface = &wmid_v2_interface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278) if (interface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279) dmi_walk(type_aa_dmi_decode, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) if (wmi_has_guid(WMID_GUID2) && interface) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) if (!has_type_aa && ACPI_FAILURE(WMID_set_capabilities())) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) pr_err("Unable to detect available WMID devices\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) /* WMID always provides brightness methods */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) interface->capability |= ACER_CAP_BRIGHTNESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) } else if (!wmi_has_guid(WMID_GUID2) && interface && !has_type_aa && force_caps == -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) pr_err("No WMID device detection method found\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) if (wmi_has_guid(AMW0_GUID1) && !wmi_has_guid(WMID_GUID1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) interface = &AMW0_interface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) if (ACPI_FAILURE(AMW0_set_capabilities())) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297) pr_err("Unable to detect available AMW0 devices\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) if (wmi_has_guid(AMW0_GUID1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) AMW0_find_mailled();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305) if (!interface) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) pr_err("No or unsupported WMI interface, unable to load\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) set_quirks();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) if (dmi_check_system(video_vendor_dmi_table))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) acpi_video_set_dmi_backlight_type(acpi_backlight_vendor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) if (acpi_video_get_backlight_type() != acpi_backlight_vendor)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) interface->capability &= ~ACER_CAP_BRIGHTNESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) if (wmi_has_guid(WMID_GUID3))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) interface->capability |= ACER_CAP_SET_FUNCTION_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) if (force_caps != -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) interface->capability = force_caps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) if (wmi_has_guid(WMID_GUID3) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325) (interface->capability & ACER_CAP_SET_FUNCTION_MODE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) if (ACPI_FAILURE(acer_wmi_enable_rf_button()))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) pr_warn("Cannot enable RF Button Driver\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) if (ec_raw_mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) if (ACPI_FAILURE(acer_wmi_enable_ec_raw())) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) pr_err("Cannot enable EC raw mode\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334) } else if (ACPI_FAILURE(acer_wmi_enable_lm())) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) pr_err("Cannot enable Launch Manager mode\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) } else if (ec_raw_mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) pr_info("No WMID EC raw mode enable method\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) if (wmi_has_guid(ACERWMID_EVENT_GUID)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) err = acer_wmi_input_setup();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346) err = acer_wmi_accel_setup();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) if (err && err != -ENODEV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) pr_warn("Cannot enable accelerometer\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) err = platform_driver_register(&acer_platform_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) pr_err("Unable to register platform driver\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) goto error_platform_register;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357) acer_platform_device = platform_device_alloc("acer-wmi", -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) if (!acer_platform_device) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) goto error_device_alloc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) err = platform_device_add(acer_platform_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) goto error_device_add;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367) if (wmi_has_guid(WMID_GUID2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) interface->debug.wmid_devices = get_wmid_devices();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) create_debugfs();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372) /* Override any initial settings with values from the commandline */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) acer_commandline_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) error_device_add:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378) platform_device_put(acer_platform_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379) error_device_alloc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) platform_driver_unregister(&acer_platform_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381) error_platform_register:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) if (wmi_has_guid(ACERWMID_EVENT_GUID))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383) acer_wmi_input_destroy();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) if (acer_wmi_accel_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385) input_unregister_device(acer_wmi_accel_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390) static void __exit acer_wmi_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392) if (wmi_has_guid(ACERWMID_EVENT_GUID))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) acer_wmi_input_destroy();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395) if (acer_wmi_accel_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396) input_unregister_device(acer_wmi_accel_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) remove_debugfs();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399) platform_device_unregister(acer_platform_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400) platform_driver_unregister(&acer_platform_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402) pr_info("Acer Laptop WMI Extras unloaded\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) module_init(acer_wmi_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407) module_exit(acer_wmi_exit);