162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Asus Notebooks WMI hotkey driver 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright(C) 2010 Corentin Chary <corentin.chary@gmail.com> 662306a36Sopenharmony_ci */ 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci#include <linux/kernel.h> 1162306a36Sopenharmony_ci#include <linux/module.h> 1262306a36Sopenharmony_ci#include <linux/init.h> 1362306a36Sopenharmony_ci#include <linux/input.h> 1462306a36Sopenharmony_ci#include <linux/input/sparse-keymap.h> 1562306a36Sopenharmony_ci#include <linux/fb.h> 1662306a36Sopenharmony_ci#include <linux/dmi.h> 1762306a36Sopenharmony_ci#include <linux/i8042.h> 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_ci#include "asus-wmi.h" 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ci#define ASUS_NB_WMI_FILE "asus-nb-wmi" 2262306a36Sopenharmony_ci 2362306a36Sopenharmony_ciMODULE_AUTHOR("Corentin Chary <corentin.chary@gmail.com>"); 2462306a36Sopenharmony_ciMODULE_DESCRIPTION("Asus Notebooks WMI Hotkey Driver"); 2562306a36Sopenharmony_ciMODULE_LICENSE("GPL"); 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_ci#define ASUS_NB_WMI_EVENT_GUID "0B3CBB35-E3C2-45ED-91C2-4C5A6D195D1C" 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_ciMODULE_ALIAS("wmi:"ASUS_NB_WMI_EVENT_GUID); 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_ci/* 3262306a36Sopenharmony_ci * WAPF defines the behavior of the Fn+Fx wlan key 3362306a36Sopenharmony_ci * The significance of values is yet to be found, but 3462306a36Sopenharmony_ci * most of the time: 3562306a36Sopenharmony_ci * Bit | Bluetooth | WLAN 3662306a36Sopenharmony_ci * 0 | Hardware | Hardware 3762306a36Sopenharmony_ci * 1 | Hardware | Software 3862306a36Sopenharmony_ci * 4 | Software | Software 3962306a36Sopenharmony_ci */ 4062306a36Sopenharmony_cistatic int wapf = -1; 4162306a36Sopenharmony_cimodule_param(wapf, uint, 0444); 4262306a36Sopenharmony_ciMODULE_PARM_DESC(wapf, "WAPF value"); 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_cistatic int tablet_mode_sw = -1; 4562306a36Sopenharmony_cimodule_param(tablet_mode_sw, uint, 0444); 4662306a36Sopenharmony_ciMODULE_PARM_DESC(tablet_mode_sw, "Tablet mode detect: -1:auto 0:disable 1:kbd-dock 2:lid-flip 3:lid-flip-rog"); 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_cistatic struct quirk_entry *quirks; 4962306a36Sopenharmony_ci 5062306a36Sopenharmony_cistatic bool asus_q500a_i8042_filter(unsigned char data, unsigned char str, 5162306a36Sopenharmony_ci struct serio *port) 5262306a36Sopenharmony_ci{ 5362306a36Sopenharmony_ci static bool extended; 5462306a36Sopenharmony_ci bool ret = false; 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_ci if (str & I8042_STR_AUXDATA) 5762306a36Sopenharmony_ci return false; 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_ci if (unlikely(data == 0xe1)) { 6062306a36Sopenharmony_ci extended = true; 6162306a36Sopenharmony_ci ret = true; 6262306a36Sopenharmony_ci } else if (unlikely(extended)) { 6362306a36Sopenharmony_ci extended = false; 6462306a36Sopenharmony_ci ret = true; 6562306a36Sopenharmony_ci } 6662306a36Sopenharmony_ci 6762306a36Sopenharmony_ci return ret; 6862306a36Sopenharmony_ci} 6962306a36Sopenharmony_ci 7062306a36Sopenharmony_cistatic struct quirk_entry quirk_asus_unknown = { 7162306a36Sopenharmony_ci .wapf = 0, 7262306a36Sopenharmony_ci .wmi_backlight_set_devstate = true, 7362306a36Sopenharmony_ci}; 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_cistatic struct quirk_entry quirk_asus_q500a = { 7662306a36Sopenharmony_ci .i8042_filter = asus_q500a_i8042_filter, 7762306a36Sopenharmony_ci .wmi_backlight_set_devstate = true, 7862306a36Sopenharmony_ci}; 7962306a36Sopenharmony_ci 8062306a36Sopenharmony_ci/* 8162306a36Sopenharmony_ci * For those machines that need software to control bt/wifi status 8262306a36Sopenharmony_ci * and have duplicate events(ACPI and WMI) for display toggle 8362306a36Sopenharmony_ci */ 8462306a36Sopenharmony_cistatic struct quirk_entry quirk_asus_x55u = { 8562306a36Sopenharmony_ci .wapf = 4, 8662306a36Sopenharmony_ci .wmi_backlight_set_devstate = true, 8762306a36Sopenharmony_ci .no_display_toggle = true, 8862306a36Sopenharmony_ci}; 8962306a36Sopenharmony_ci 9062306a36Sopenharmony_cistatic struct quirk_entry quirk_asus_wapf4 = { 9162306a36Sopenharmony_ci .wapf = 4, 9262306a36Sopenharmony_ci .wmi_backlight_set_devstate = true, 9362306a36Sopenharmony_ci}; 9462306a36Sopenharmony_ci 9562306a36Sopenharmony_cistatic struct quirk_entry quirk_asus_x200ca = { 9662306a36Sopenharmony_ci .wapf = 2, 9762306a36Sopenharmony_ci .wmi_backlight_set_devstate = true, 9862306a36Sopenharmony_ci}; 9962306a36Sopenharmony_ci 10062306a36Sopenharmony_cistatic struct quirk_entry quirk_asus_x550lb = { 10162306a36Sopenharmony_ci .wmi_backlight_set_devstate = true, 10262306a36Sopenharmony_ci .xusb2pr = 0x01D9, 10362306a36Sopenharmony_ci}; 10462306a36Sopenharmony_ci 10562306a36Sopenharmony_cistatic struct quirk_entry quirk_asus_forceals = { 10662306a36Sopenharmony_ci .wmi_backlight_set_devstate = true, 10762306a36Sopenharmony_ci .wmi_force_als_set = true, 10862306a36Sopenharmony_ci}; 10962306a36Sopenharmony_ci 11062306a36Sopenharmony_cistatic struct quirk_entry quirk_asus_use_kbd_dock_devid = { 11162306a36Sopenharmony_ci .tablet_switch_mode = asus_wmi_kbd_dock_devid, 11262306a36Sopenharmony_ci}; 11362306a36Sopenharmony_ci 11462306a36Sopenharmony_cistatic struct quirk_entry quirk_asus_use_lid_flip_devid = { 11562306a36Sopenharmony_ci .wmi_backlight_set_devstate = true, 11662306a36Sopenharmony_ci .tablet_switch_mode = asus_wmi_lid_flip_devid, 11762306a36Sopenharmony_ci}; 11862306a36Sopenharmony_ci 11962306a36Sopenharmony_cistatic struct quirk_entry quirk_asus_tablet_mode = { 12062306a36Sopenharmony_ci .wmi_backlight_set_devstate = true, 12162306a36Sopenharmony_ci .tablet_switch_mode = asus_wmi_lid_flip_rog_devid, 12262306a36Sopenharmony_ci}; 12362306a36Sopenharmony_ci 12462306a36Sopenharmony_cistatic struct quirk_entry quirk_asus_ignore_fan = { 12562306a36Sopenharmony_ci .wmi_ignore_fan = true, 12662306a36Sopenharmony_ci}; 12762306a36Sopenharmony_ci 12862306a36Sopenharmony_cistatic int dmi_matched(const struct dmi_system_id *dmi) 12962306a36Sopenharmony_ci{ 13062306a36Sopenharmony_ci pr_info("Identified laptop model '%s'\n", dmi->ident); 13162306a36Sopenharmony_ci quirks = dmi->driver_data; 13262306a36Sopenharmony_ci return 1; 13362306a36Sopenharmony_ci} 13462306a36Sopenharmony_ci 13562306a36Sopenharmony_cistatic const struct dmi_system_id asus_quirks[] = { 13662306a36Sopenharmony_ci { 13762306a36Sopenharmony_ci .callback = dmi_matched, 13862306a36Sopenharmony_ci .ident = "ASUSTeK COMPUTER INC. Q500A", 13962306a36Sopenharmony_ci .matches = { 14062306a36Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 14162306a36Sopenharmony_ci DMI_MATCH(DMI_PRODUCT_NAME, "Q500A"), 14262306a36Sopenharmony_ci }, 14362306a36Sopenharmony_ci .driver_data = &quirk_asus_q500a, 14462306a36Sopenharmony_ci }, 14562306a36Sopenharmony_ci { 14662306a36Sopenharmony_ci .callback = dmi_matched, 14762306a36Sopenharmony_ci .ident = "ASUSTeK COMPUTER INC. U32U", 14862306a36Sopenharmony_ci .matches = { 14962306a36Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), 15062306a36Sopenharmony_ci DMI_MATCH(DMI_PRODUCT_NAME, "U32U"), 15162306a36Sopenharmony_ci }, 15262306a36Sopenharmony_ci .driver_data = &quirk_asus_wapf4, 15362306a36Sopenharmony_ci }, 15462306a36Sopenharmony_ci { 15562306a36Sopenharmony_ci .callback = dmi_matched, 15662306a36Sopenharmony_ci .ident = "ASUSTeK COMPUTER INC. X302UA", 15762306a36Sopenharmony_ci .matches = { 15862306a36Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 15962306a36Sopenharmony_ci DMI_MATCH(DMI_PRODUCT_NAME, "X302UA"), 16062306a36Sopenharmony_ci }, 16162306a36Sopenharmony_ci .driver_data = &quirk_asus_wapf4, 16262306a36Sopenharmony_ci }, 16362306a36Sopenharmony_ci { 16462306a36Sopenharmony_ci .callback = dmi_matched, 16562306a36Sopenharmony_ci .ident = "ASUSTeK COMPUTER INC. X401U", 16662306a36Sopenharmony_ci .matches = { 16762306a36Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 16862306a36Sopenharmony_ci DMI_MATCH(DMI_PRODUCT_NAME, "X401U"), 16962306a36Sopenharmony_ci }, 17062306a36Sopenharmony_ci .driver_data = &quirk_asus_x55u, 17162306a36Sopenharmony_ci }, 17262306a36Sopenharmony_ci { 17362306a36Sopenharmony_ci .callback = dmi_matched, 17462306a36Sopenharmony_ci .ident = "ASUSTeK COMPUTER INC. X401A", 17562306a36Sopenharmony_ci .matches = { 17662306a36Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 17762306a36Sopenharmony_ci DMI_MATCH(DMI_PRODUCT_NAME, "X401A"), 17862306a36Sopenharmony_ci }, 17962306a36Sopenharmony_ci .driver_data = &quirk_asus_wapf4, 18062306a36Sopenharmony_ci }, 18162306a36Sopenharmony_ci { 18262306a36Sopenharmony_ci .callback = dmi_matched, 18362306a36Sopenharmony_ci .ident = "ASUSTeK COMPUTER INC. X401A1", 18462306a36Sopenharmony_ci .matches = { 18562306a36Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 18662306a36Sopenharmony_ci DMI_MATCH(DMI_PRODUCT_NAME, "X401A1"), 18762306a36Sopenharmony_ci }, 18862306a36Sopenharmony_ci .driver_data = &quirk_asus_wapf4, 18962306a36Sopenharmony_ci }, 19062306a36Sopenharmony_ci { 19162306a36Sopenharmony_ci .callback = dmi_matched, 19262306a36Sopenharmony_ci .ident = "ASUSTeK COMPUTER INC. X45U", 19362306a36Sopenharmony_ci .matches = { 19462306a36Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 19562306a36Sopenharmony_ci DMI_MATCH(DMI_PRODUCT_NAME, "X45U"), 19662306a36Sopenharmony_ci }, 19762306a36Sopenharmony_ci .driver_data = &quirk_asus_wapf4, 19862306a36Sopenharmony_ci }, 19962306a36Sopenharmony_ci { 20062306a36Sopenharmony_ci .callback = dmi_matched, 20162306a36Sopenharmony_ci .ident = "ASUSTeK COMPUTER INC. X456UA", 20262306a36Sopenharmony_ci .matches = { 20362306a36Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 20462306a36Sopenharmony_ci DMI_MATCH(DMI_PRODUCT_NAME, "X456UA"), 20562306a36Sopenharmony_ci }, 20662306a36Sopenharmony_ci .driver_data = &quirk_asus_wapf4, 20762306a36Sopenharmony_ci }, 20862306a36Sopenharmony_ci { 20962306a36Sopenharmony_ci .callback = dmi_matched, 21062306a36Sopenharmony_ci .ident = "ASUSTeK COMPUTER INC. X456UF", 21162306a36Sopenharmony_ci .matches = { 21262306a36Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 21362306a36Sopenharmony_ci DMI_MATCH(DMI_PRODUCT_NAME, "X456UF"), 21462306a36Sopenharmony_ci }, 21562306a36Sopenharmony_ci .driver_data = &quirk_asus_wapf4, 21662306a36Sopenharmony_ci }, 21762306a36Sopenharmony_ci { 21862306a36Sopenharmony_ci .callback = dmi_matched, 21962306a36Sopenharmony_ci .ident = "ASUSTeK COMPUTER INC. X501U", 22062306a36Sopenharmony_ci .matches = { 22162306a36Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 22262306a36Sopenharmony_ci DMI_MATCH(DMI_PRODUCT_NAME, "X501U"), 22362306a36Sopenharmony_ci }, 22462306a36Sopenharmony_ci .driver_data = &quirk_asus_x55u, 22562306a36Sopenharmony_ci }, 22662306a36Sopenharmony_ci { 22762306a36Sopenharmony_ci .callback = dmi_matched, 22862306a36Sopenharmony_ci .ident = "ASUSTeK COMPUTER INC. X501A", 22962306a36Sopenharmony_ci .matches = { 23062306a36Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 23162306a36Sopenharmony_ci DMI_MATCH(DMI_PRODUCT_NAME, "X501A"), 23262306a36Sopenharmony_ci }, 23362306a36Sopenharmony_ci .driver_data = &quirk_asus_wapf4, 23462306a36Sopenharmony_ci }, 23562306a36Sopenharmony_ci { 23662306a36Sopenharmony_ci .callback = dmi_matched, 23762306a36Sopenharmony_ci .ident = "ASUSTeK COMPUTER INC. X501A1", 23862306a36Sopenharmony_ci .matches = { 23962306a36Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 24062306a36Sopenharmony_ci DMI_MATCH(DMI_PRODUCT_NAME, "X501A1"), 24162306a36Sopenharmony_ci }, 24262306a36Sopenharmony_ci .driver_data = &quirk_asus_wapf4, 24362306a36Sopenharmony_ci }, 24462306a36Sopenharmony_ci { 24562306a36Sopenharmony_ci .callback = dmi_matched, 24662306a36Sopenharmony_ci .ident = "ASUSTeK COMPUTER INC. X550CA", 24762306a36Sopenharmony_ci .matches = { 24862306a36Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 24962306a36Sopenharmony_ci DMI_MATCH(DMI_PRODUCT_NAME, "X550CA"), 25062306a36Sopenharmony_ci }, 25162306a36Sopenharmony_ci .driver_data = &quirk_asus_wapf4, 25262306a36Sopenharmony_ci }, 25362306a36Sopenharmony_ci { 25462306a36Sopenharmony_ci .callback = dmi_matched, 25562306a36Sopenharmony_ci .ident = "ASUSTeK COMPUTER INC. X550CC", 25662306a36Sopenharmony_ci .matches = { 25762306a36Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 25862306a36Sopenharmony_ci DMI_MATCH(DMI_PRODUCT_NAME, "X550CC"), 25962306a36Sopenharmony_ci }, 26062306a36Sopenharmony_ci .driver_data = &quirk_asus_wapf4, 26162306a36Sopenharmony_ci }, 26262306a36Sopenharmony_ci { 26362306a36Sopenharmony_ci .callback = dmi_matched, 26462306a36Sopenharmony_ci .ident = "ASUSTeK COMPUTER INC. X550CL", 26562306a36Sopenharmony_ci .matches = { 26662306a36Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 26762306a36Sopenharmony_ci DMI_MATCH(DMI_PRODUCT_NAME, "X550CL"), 26862306a36Sopenharmony_ci }, 26962306a36Sopenharmony_ci .driver_data = &quirk_asus_wapf4, 27062306a36Sopenharmony_ci }, 27162306a36Sopenharmony_ci { 27262306a36Sopenharmony_ci .callback = dmi_matched, 27362306a36Sopenharmony_ci .ident = "ASUSTeK COMPUTER INC. X550VB", 27462306a36Sopenharmony_ci .matches = { 27562306a36Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 27662306a36Sopenharmony_ci DMI_MATCH(DMI_PRODUCT_NAME, "X550VB"), 27762306a36Sopenharmony_ci }, 27862306a36Sopenharmony_ci .driver_data = &quirk_asus_wapf4, 27962306a36Sopenharmony_ci }, 28062306a36Sopenharmony_ci { 28162306a36Sopenharmony_ci .callback = dmi_matched, 28262306a36Sopenharmony_ci .ident = "ASUSTeK COMPUTER INC. X551CA", 28362306a36Sopenharmony_ci .matches = { 28462306a36Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 28562306a36Sopenharmony_ci DMI_MATCH(DMI_PRODUCT_NAME, "X551CA"), 28662306a36Sopenharmony_ci }, 28762306a36Sopenharmony_ci .driver_data = &quirk_asus_wapf4, 28862306a36Sopenharmony_ci }, 28962306a36Sopenharmony_ci { 29062306a36Sopenharmony_ci .callback = dmi_matched, 29162306a36Sopenharmony_ci .ident = "ASUSTeK COMPUTER INC. X55A", 29262306a36Sopenharmony_ci .matches = { 29362306a36Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 29462306a36Sopenharmony_ci DMI_MATCH(DMI_PRODUCT_NAME, "X55A"), 29562306a36Sopenharmony_ci }, 29662306a36Sopenharmony_ci .driver_data = &quirk_asus_wapf4, 29762306a36Sopenharmony_ci }, 29862306a36Sopenharmony_ci { 29962306a36Sopenharmony_ci .callback = dmi_matched, 30062306a36Sopenharmony_ci .ident = "ASUSTeK COMPUTER INC. X55C", 30162306a36Sopenharmony_ci .matches = { 30262306a36Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 30362306a36Sopenharmony_ci DMI_MATCH(DMI_PRODUCT_NAME, "X55C"), 30462306a36Sopenharmony_ci }, 30562306a36Sopenharmony_ci .driver_data = &quirk_asus_wapf4, 30662306a36Sopenharmony_ci }, 30762306a36Sopenharmony_ci { 30862306a36Sopenharmony_ci .callback = dmi_matched, 30962306a36Sopenharmony_ci .ident = "ASUSTeK COMPUTER INC. X55U", 31062306a36Sopenharmony_ci .matches = { 31162306a36Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 31262306a36Sopenharmony_ci DMI_MATCH(DMI_PRODUCT_NAME, "X55U"), 31362306a36Sopenharmony_ci }, 31462306a36Sopenharmony_ci .driver_data = &quirk_asus_x55u, 31562306a36Sopenharmony_ci }, 31662306a36Sopenharmony_ci { 31762306a36Sopenharmony_ci .callback = dmi_matched, 31862306a36Sopenharmony_ci .ident = "ASUSTeK COMPUTER INC. X55VD", 31962306a36Sopenharmony_ci .matches = { 32062306a36Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 32162306a36Sopenharmony_ci DMI_MATCH(DMI_PRODUCT_NAME, "X55VD"), 32262306a36Sopenharmony_ci }, 32362306a36Sopenharmony_ci .driver_data = &quirk_asus_wapf4, 32462306a36Sopenharmony_ci }, 32562306a36Sopenharmony_ci { 32662306a36Sopenharmony_ci .callback = dmi_matched, 32762306a36Sopenharmony_ci .ident = "ASUSTeK COMPUTER INC. X75A", 32862306a36Sopenharmony_ci .matches = { 32962306a36Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 33062306a36Sopenharmony_ci DMI_MATCH(DMI_PRODUCT_NAME, "X75A"), 33162306a36Sopenharmony_ci }, 33262306a36Sopenharmony_ci .driver_data = &quirk_asus_wapf4, 33362306a36Sopenharmony_ci }, 33462306a36Sopenharmony_ci { 33562306a36Sopenharmony_ci .callback = dmi_matched, 33662306a36Sopenharmony_ci .ident = "ASUSTeK COMPUTER INC. X75VBP", 33762306a36Sopenharmony_ci .matches = { 33862306a36Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 33962306a36Sopenharmony_ci DMI_MATCH(DMI_PRODUCT_NAME, "X75VBP"), 34062306a36Sopenharmony_ci }, 34162306a36Sopenharmony_ci .driver_data = &quirk_asus_wapf4, 34262306a36Sopenharmony_ci }, 34362306a36Sopenharmony_ci { 34462306a36Sopenharmony_ci .callback = dmi_matched, 34562306a36Sopenharmony_ci .ident = "ASUSTeK COMPUTER INC. X75VD", 34662306a36Sopenharmony_ci .matches = { 34762306a36Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 34862306a36Sopenharmony_ci DMI_MATCH(DMI_PRODUCT_NAME, "X75VD"), 34962306a36Sopenharmony_ci }, 35062306a36Sopenharmony_ci .driver_data = &quirk_asus_wapf4, 35162306a36Sopenharmony_ci }, 35262306a36Sopenharmony_ci { 35362306a36Sopenharmony_ci .callback = dmi_matched, 35462306a36Sopenharmony_ci .ident = "ASUSTeK COMPUTER INC. 1015E", 35562306a36Sopenharmony_ci .matches = { 35662306a36Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 35762306a36Sopenharmony_ci DMI_MATCH(DMI_PRODUCT_NAME, "1015E"), 35862306a36Sopenharmony_ci }, 35962306a36Sopenharmony_ci .driver_data = &quirk_asus_wapf4, 36062306a36Sopenharmony_ci }, 36162306a36Sopenharmony_ci { 36262306a36Sopenharmony_ci .callback = dmi_matched, 36362306a36Sopenharmony_ci .ident = "ASUSTeK COMPUTER INC. 1015U", 36462306a36Sopenharmony_ci .matches = { 36562306a36Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 36662306a36Sopenharmony_ci DMI_MATCH(DMI_PRODUCT_NAME, "1015U"), 36762306a36Sopenharmony_ci }, 36862306a36Sopenharmony_ci .driver_data = &quirk_asus_wapf4, 36962306a36Sopenharmony_ci }, 37062306a36Sopenharmony_ci { 37162306a36Sopenharmony_ci .callback = dmi_matched, 37262306a36Sopenharmony_ci .ident = "ASUSTeK COMPUTER INC. X200CA", 37362306a36Sopenharmony_ci .matches = { 37462306a36Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 37562306a36Sopenharmony_ci DMI_MATCH(DMI_PRODUCT_NAME, "X200CA"), 37662306a36Sopenharmony_ci }, 37762306a36Sopenharmony_ci .driver_data = &quirk_asus_x200ca, 37862306a36Sopenharmony_ci }, 37962306a36Sopenharmony_ci { 38062306a36Sopenharmony_ci .callback = dmi_matched, 38162306a36Sopenharmony_ci .ident = "ASUSTeK COMPUTER INC. UX330UAK", 38262306a36Sopenharmony_ci .matches = { 38362306a36Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 38462306a36Sopenharmony_ci DMI_MATCH(DMI_PRODUCT_NAME, "UX330UAK"), 38562306a36Sopenharmony_ci }, 38662306a36Sopenharmony_ci .driver_data = &quirk_asus_forceals, 38762306a36Sopenharmony_ci }, 38862306a36Sopenharmony_ci { 38962306a36Sopenharmony_ci .callback = dmi_matched, 39062306a36Sopenharmony_ci .ident = "ASUSTeK COMPUTER INC. X550LB", 39162306a36Sopenharmony_ci .matches = { 39262306a36Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 39362306a36Sopenharmony_ci DMI_MATCH(DMI_PRODUCT_NAME, "X550LB"), 39462306a36Sopenharmony_ci }, 39562306a36Sopenharmony_ci .driver_data = &quirk_asus_x550lb, 39662306a36Sopenharmony_ci }, 39762306a36Sopenharmony_ci { 39862306a36Sopenharmony_ci .callback = dmi_matched, 39962306a36Sopenharmony_ci .ident = "ASUSTeK COMPUTER INC. UX430UQ", 40062306a36Sopenharmony_ci .matches = { 40162306a36Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 40262306a36Sopenharmony_ci DMI_MATCH(DMI_PRODUCT_NAME, "UX430UQ"), 40362306a36Sopenharmony_ci }, 40462306a36Sopenharmony_ci .driver_data = &quirk_asus_forceals, 40562306a36Sopenharmony_ci }, 40662306a36Sopenharmony_ci { 40762306a36Sopenharmony_ci .callback = dmi_matched, 40862306a36Sopenharmony_ci .ident = "ASUSTeK COMPUTER INC. UX430UNR", 40962306a36Sopenharmony_ci .matches = { 41062306a36Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 41162306a36Sopenharmony_ci DMI_MATCH(DMI_PRODUCT_NAME, "UX430UNR"), 41262306a36Sopenharmony_ci }, 41362306a36Sopenharmony_ci .driver_data = &quirk_asus_forceals, 41462306a36Sopenharmony_ci }, 41562306a36Sopenharmony_ci { 41662306a36Sopenharmony_ci .callback = dmi_matched, 41762306a36Sopenharmony_ci .ident = "Asus Transformer T100TA / T100HA / T100CHI", 41862306a36Sopenharmony_ci .matches = { 41962306a36Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 42062306a36Sopenharmony_ci /* Match *T100* */ 42162306a36Sopenharmony_ci DMI_MATCH(DMI_PRODUCT_NAME, "T100"), 42262306a36Sopenharmony_ci }, 42362306a36Sopenharmony_ci .driver_data = &quirk_asus_use_kbd_dock_devid, 42462306a36Sopenharmony_ci }, 42562306a36Sopenharmony_ci { 42662306a36Sopenharmony_ci .callback = dmi_matched, 42762306a36Sopenharmony_ci .ident = "Asus Transformer T101HA", 42862306a36Sopenharmony_ci .matches = { 42962306a36Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 43062306a36Sopenharmony_ci DMI_MATCH(DMI_PRODUCT_NAME, "T101HA"), 43162306a36Sopenharmony_ci }, 43262306a36Sopenharmony_ci .driver_data = &quirk_asus_use_kbd_dock_devid, 43362306a36Sopenharmony_ci }, 43462306a36Sopenharmony_ci { 43562306a36Sopenharmony_ci .callback = dmi_matched, 43662306a36Sopenharmony_ci .ident = "Asus Transformer T200TA", 43762306a36Sopenharmony_ci .matches = { 43862306a36Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 43962306a36Sopenharmony_ci DMI_MATCH(DMI_PRODUCT_NAME, "T200TA"), 44062306a36Sopenharmony_ci }, 44162306a36Sopenharmony_ci .driver_data = &quirk_asus_use_kbd_dock_devid, 44262306a36Sopenharmony_ci }, 44362306a36Sopenharmony_ci { 44462306a36Sopenharmony_ci .callback = dmi_matched, 44562306a36Sopenharmony_ci .ident = "ASUS ZenBook Flip UX360", 44662306a36Sopenharmony_ci .matches = { 44762306a36Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 44862306a36Sopenharmony_ci /* Match UX360* */ 44962306a36Sopenharmony_ci DMI_MATCH(DMI_PRODUCT_NAME, "UX360"), 45062306a36Sopenharmony_ci }, 45162306a36Sopenharmony_ci .driver_data = &quirk_asus_use_lid_flip_devid, 45262306a36Sopenharmony_ci }, 45362306a36Sopenharmony_ci { 45462306a36Sopenharmony_ci .callback = dmi_matched, 45562306a36Sopenharmony_ci .ident = "ASUS TP200s / E205SA", 45662306a36Sopenharmony_ci .matches = { 45762306a36Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 45862306a36Sopenharmony_ci DMI_MATCH(DMI_PRODUCT_NAME, "E205SA"), 45962306a36Sopenharmony_ci }, 46062306a36Sopenharmony_ci .driver_data = &quirk_asus_use_lid_flip_devid, 46162306a36Sopenharmony_ci }, 46262306a36Sopenharmony_ci { 46362306a36Sopenharmony_ci .callback = dmi_matched, 46462306a36Sopenharmony_ci .ident = "ASUS ROG FLOW X13", 46562306a36Sopenharmony_ci .matches = { 46662306a36Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 46762306a36Sopenharmony_ci /* Match GV301** */ 46862306a36Sopenharmony_ci DMI_MATCH(DMI_PRODUCT_NAME, "GV301"), 46962306a36Sopenharmony_ci }, 47062306a36Sopenharmony_ci .driver_data = &quirk_asus_tablet_mode, 47162306a36Sopenharmony_ci }, 47262306a36Sopenharmony_ci { 47362306a36Sopenharmony_ci .callback = dmi_matched, 47462306a36Sopenharmony_ci .ident = "ASUS ROG FLOW X16", 47562306a36Sopenharmony_ci .matches = { 47662306a36Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 47762306a36Sopenharmony_ci DMI_MATCH(DMI_PRODUCT_NAME, "GV601R"), 47862306a36Sopenharmony_ci }, 47962306a36Sopenharmony_ci .driver_data = &quirk_asus_tablet_mode, 48062306a36Sopenharmony_ci }, 48162306a36Sopenharmony_ci { 48262306a36Sopenharmony_ci .callback = dmi_matched, 48362306a36Sopenharmony_ci .ident = "ASUS ROG FLOW X16", 48462306a36Sopenharmony_ci .matches = { 48562306a36Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 48662306a36Sopenharmony_ci DMI_MATCH(DMI_PRODUCT_NAME, "GV601V"), 48762306a36Sopenharmony_ci }, 48862306a36Sopenharmony_ci .driver_data = &quirk_asus_tablet_mode, 48962306a36Sopenharmony_ci }, 49062306a36Sopenharmony_ci { 49162306a36Sopenharmony_ci .callback = dmi_matched, 49262306a36Sopenharmony_ci .ident = "ASUS VivoBook E410MA", 49362306a36Sopenharmony_ci .matches = { 49462306a36Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 49562306a36Sopenharmony_ci DMI_MATCH(DMI_PRODUCT_NAME, "E410MA"), 49662306a36Sopenharmony_ci }, 49762306a36Sopenharmony_ci .driver_data = &quirk_asus_ignore_fan, 49862306a36Sopenharmony_ci }, 49962306a36Sopenharmony_ci {}, 50062306a36Sopenharmony_ci}; 50162306a36Sopenharmony_ci 50262306a36Sopenharmony_cistatic void asus_nb_wmi_quirks(struct asus_wmi_driver *driver) 50362306a36Sopenharmony_ci{ 50462306a36Sopenharmony_ci quirks = &quirk_asus_unknown; 50562306a36Sopenharmony_ci dmi_check_system(asus_quirks); 50662306a36Sopenharmony_ci 50762306a36Sopenharmony_ci driver->quirks = quirks; 50862306a36Sopenharmony_ci driver->panel_power = FB_BLANK_UNBLANK; 50962306a36Sopenharmony_ci 51062306a36Sopenharmony_ci /* overwrite the wapf setting if the wapf paramater is specified */ 51162306a36Sopenharmony_ci if (wapf != -1) 51262306a36Sopenharmony_ci quirks->wapf = wapf; 51362306a36Sopenharmony_ci else 51462306a36Sopenharmony_ci wapf = quirks->wapf; 51562306a36Sopenharmony_ci 51662306a36Sopenharmony_ci if (tablet_mode_sw != -1) 51762306a36Sopenharmony_ci quirks->tablet_switch_mode = tablet_mode_sw; 51862306a36Sopenharmony_ci} 51962306a36Sopenharmony_ci 52062306a36Sopenharmony_cistatic const struct key_entry asus_nb_wmi_keymap[] = { 52162306a36Sopenharmony_ci { KE_KEY, ASUS_WMI_BRN_DOWN, { KEY_BRIGHTNESSDOWN } }, 52262306a36Sopenharmony_ci { KE_KEY, ASUS_WMI_BRN_UP, { KEY_BRIGHTNESSUP } }, 52362306a36Sopenharmony_ci { KE_KEY, 0x2a, { KEY_SELECTIVE_SCREENSHOT } }, 52462306a36Sopenharmony_ci { KE_IGNORE, 0x2b, }, /* PrintScreen (also send via PS/2) on newer models */ 52562306a36Sopenharmony_ci { KE_IGNORE, 0x2c, }, /* CapsLock (also send via PS/2) on newer models */ 52662306a36Sopenharmony_ci { KE_KEY, 0x30, { KEY_VOLUMEUP } }, 52762306a36Sopenharmony_ci { KE_KEY, 0x31, { KEY_VOLUMEDOWN } }, 52862306a36Sopenharmony_ci { KE_KEY, 0x32, { KEY_MUTE } }, 52962306a36Sopenharmony_ci { KE_KEY, 0x33, { KEY_SCREENLOCK } }, 53062306a36Sopenharmony_ci { KE_KEY, 0x35, { KEY_SCREENLOCK } }, 53162306a36Sopenharmony_ci { KE_KEY, 0x38, { KEY_PROG3 } }, /* Armoury Crate */ 53262306a36Sopenharmony_ci { KE_KEY, 0x40, { KEY_PREVIOUSSONG } }, 53362306a36Sopenharmony_ci { KE_KEY, 0x41, { KEY_NEXTSONG } }, 53462306a36Sopenharmony_ci { KE_KEY, 0x43, { KEY_STOPCD } }, /* Stop/Eject */ 53562306a36Sopenharmony_ci { KE_KEY, 0x45, { KEY_PLAYPAUSE } }, 53662306a36Sopenharmony_ci { KE_KEY, 0x4c, { KEY_MEDIA } }, /* WMP Key */ 53762306a36Sopenharmony_ci { KE_KEY, 0x50, { KEY_EMAIL } }, 53862306a36Sopenharmony_ci { KE_KEY, 0x51, { KEY_WWW } }, 53962306a36Sopenharmony_ci { KE_KEY, 0x55, { KEY_CALC } }, 54062306a36Sopenharmony_ci { KE_IGNORE, 0x57, }, /* Battery mode */ 54162306a36Sopenharmony_ci { KE_IGNORE, 0x58, }, /* AC mode */ 54262306a36Sopenharmony_ci { KE_KEY, 0x5C, { KEY_F15 } }, /* Power Gear key */ 54362306a36Sopenharmony_ci { KE_KEY, 0x5D, { KEY_WLAN } }, /* Wireless console Toggle */ 54462306a36Sopenharmony_ci { KE_KEY, 0x5E, { KEY_WLAN } }, /* Wireless console Enable */ 54562306a36Sopenharmony_ci { KE_KEY, 0x5F, { KEY_WLAN } }, /* Wireless console Disable */ 54662306a36Sopenharmony_ci { KE_KEY, 0x60, { KEY_TOUCHPAD_ON } }, 54762306a36Sopenharmony_ci { KE_KEY, 0x61, { KEY_SWITCHVIDEOMODE } }, /* SDSP LCD only */ 54862306a36Sopenharmony_ci { KE_KEY, 0x62, { KEY_SWITCHVIDEOMODE } }, /* SDSP CRT only */ 54962306a36Sopenharmony_ci { KE_KEY, 0x63, { KEY_SWITCHVIDEOMODE } }, /* SDSP LCD + CRT */ 55062306a36Sopenharmony_ci { KE_KEY, 0x64, { KEY_SWITCHVIDEOMODE } }, /* SDSP TV */ 55162306a36Sopenharmony_ci { KE_KEY, 0x65, { KEY_SWITCHVIDEOMODE } }, /* SDSP LCD + TV */ 55262306a36Sopenharmony_ci { KE_KEY, 0x66, { KEY_SWITCHVIDEOMODE } }, /* SDSP CRT + TV */ 55362306a36Sopenharmony_ci { KE_KEY, 0x67, { KEY_SWITCHVIDEOMODE } }, /* SDSP LCD + CRT + TV */ 55462306a36Sopenharmony_ci { KE_KEY, 0x6B, { KEY_TOUCHPAD_TOGGLE } }, 55562306a36Sopenharmony_ci { KE_IGNORE, 0x6E, }, /* Low Battery notification */ 55662306a36Sopenharmony_ci { KE_KEY, 0x71, { KEY_F13 } }, /* General-purpose button */ 55762306a36Sopenharmony_ci { KE_IGNORE, 0x79, }, /* Charger type dectection notification */ 55862306a36Sopenharmony_ci { KE_KEY, 0x7a, { KEY_ALS_TOGGLE } }, /* Ambient Light Sensor Toggle */ 55962306a36Sopenharmony_ci { KE_IGNORE, 0x7B, }, /* Charger connect/disconnect notification */ 56062306a36Sopenharmony_ci { KE_KEY, 0x7c, { KEY_MICMUTE } }, 56162306a36Sopenharmony_ci { KE_KEY, 0x7D, { KEY_BLUETOOTH } }, /* Bluetooth Enable */ 56262306a36Sopenharmony_ci { KE_KEY, 0x7E, { KEY_BLUETOOTH } }, /* Bluetooth Disable */ 56362306a36Sopenharmony_ci { KE_KEY, 0x82, { KEY_CAMERA } }, 56462306a36Sopenharmony_ci { KE_KEY, 0x85, { KEY_CAMERA } }, 56562306a36Sopenharmony_ci { KE_KEY, 0x86, { KEY_PROG1 } }, /* MyASUS Key */ 56662306a36Sopenharmony_ci { KE_KEY, 0x88, { KEY_RFKILL } }, /* Radio Toggle Key */ 56762306a36Sopenharmony_ci { KE_KEY, 0x8A, { KEY_PROG1 } }, /* Color enhancement mode */ 56862306a36Sopenharmony_ci { KE_KEY, 0x8C, { KEY_SWITCHVIDEOMODE } }, /* SDSP DVI only */ 56962306a36Sopenharmony_ci { KE_KEY, 0x8D, { KEY_SWITCHVIDEOMODE } }, /* SDSP LCD + DVI */ 57062306a36Sopenharmony_ci { KE_KEY, 0x8E, { KEY_SWITCHVIDEOMODE } }, /* SDSP CRT + DVI */ 57162306a36Sopenharmony_ci { KE_KEY, 0x8F, { KEY_SWITCHVIDEOMODE } }, /* SDSP TV + DVI */ 57262306a36Sopenharmony_ci { KE_KEY, 0x90, { KEY_SWITCHVIDEOMODE } }, /* SDSP LCD + CRT + DVI */ 57362306a36Sopenharmony_ci { KE_KEY, 0x91, { KEY_SWITCHVIDEOMODE } }, /* SDSP LCD + TV + DVI */ 57462306a36Sopenharmony_ci { KE_KEY, 0x92, { KEY_SWITCHVIDEOMODE } }, /* SDSP CRT + TV + DVI */ 57562306a36Sopenharmony_ci { KE_KEY, 0x93, { KEY_SWITCHVIDEOMODE } }, /* SDSP LCD + CRT + TV + DVI */ 57662306a36Sopenharmony_ci { KE_KEY, 0x95, { KEY_MEDIA } }, 57762306a36Sopenharmony_ci { KE_KEY, 0x99, { KEY_PHONE } }, /* Conflicts with fan mode switch */ 57862306a36Sopenharmony_ci { KE_KEY, 0xA0, { KEY_SWITCHVIDEOMODE } }, /* SDSP HDMI only */ 57962306a36Sopenharmony_ci { KE_KEY, 0xA1, { KEY_SWITCHVIDEOMODE } }, /* SDSP LCD + HDMI */ 58062306a36Sopenharmony_ci { KE_KEY, 0xA2, { KEY_SWITCHVIDEOMODE } }, /* SDSP CRT + HDMI */ 58162306a36Sopenharmony_ci { KE_KEY, 0xA3, { KEY_SWITCHVIDEOMODE } }, /* SDSP TV + HDMI */ 58262306a36Sopenharmony_ci { KE_KEY, 0xA4, { KEY_SWITCHVIDEOMODE } }, /* SDSP LCD + CRT + HDMI */ 58362306a36Sopenharmony_ci { KE_KEY, 0xA5, { KEY_SWITCHVIDEOMODE } }, /* SDSP LCD + TV + HDMI */ 58462306a36Sopenharmony_ci { KE_KEY, 0xA6, { KEY_SWITCHVIDEOMODE } }, /* SDSP CRT + TV + HDMI */ 58562306a36Sopenharmony_ci { KE_KEY, 0xA7, { KEY_SWITCHVIDEOMODE } }, /* SDSP LCD + CRT + TV + HDMI */ 58662306a36Sopenharmony_ci { KE_KEY, 0xAE, { KEY_FN_F5 } }, /* Fn+F5 fan mode on 2020+ */ 58762306a36Sopenharmony_ci { KE_KEY, 0xB3, { KEY_PROG4 } }, /* AURA */ 58862306a36Sopenharmony_ci { KE_KEY, 0xB5, { KEY_CALC } }, 58962306a36Sopenharmony_ci { KE_IGNORE, 0xC0, }, /* External display connect/disconnect notification */ 59062306a36Sopenharmony_ci { KE_KEY, 0xC4, { KEY_KBDILLUMUP } }, 59162306a36Sopenharmony_ci { KE_KEY, 0xC5, { KEY_KBDILLUMDOWN } }, 59262306a36Sopenharmony_ci { KE_IGNORE, 0xC6, }, /* Ambient Light Sensor notification */ 59362306a36Sopenharmony_ci { KE_KEY, 0xFA, { KEY_PROG2 } }, /* Lid flip action */ 59462306a36Sopenharmony_ci { KE_KEY, 0xBD, { KEY_PROG2 } }, /* Lid flip action on ROG xflow laptops */ 59562306a36Sopenharmony_ci { KE_END, 0}, 59662306a36Sopenharmony_ci}; 59762306a36Sopenharmony_ci 59862306a36Sopenharmony_cistatic struct asus_wmi_driver asus_nb_wmi_driver = { 59962306a36Sopenharmony_ci .name = ASUS_NB_WMI_FILE, 60062306a36Sopenharmony_ci .owner = THIS_MODULE, 60162306a36Sopenharmony_ci .event_guid = ASUS_NB_WMI_EVENT_GUID, 60262306a36Sopenharmony_ci .keymap = asus_nb_wmi_keymap, 60362306a36Sopenharmony_ci .input_name = "Asus WMI hotkeys", 60462306a36Sopenharmony_ci .input_phys = ASUS_NB_WMI_FILE "/input0", 60562306a36Sopenharmony_ci .detect_quirks = asus_nb_wmi_quirks, 60662306a36Sopenharmony_ci}; 60762306a36Sopenharmony_ci 60862306a36Sopenharmony_ci 60962306a36Sopenharmony_cistatic int __init asus_nb_wmi_init(void) 61062306a36Sopenharmony_ci{ 61162306a36Sopenharmony_ci return asus_wmi_register_driver(&asus_nb_wmi_driver); 61262306a36Sopenharmony_ci} 61362306a36Sopenharmony_ci 61462306a36Sopenharmony_cistatic void __exit asus_nb_wmi_exit(void) 61562306a36Sopenharmony_ci{ 61662306a36Sopenharmony_ci asus_wmi_unregister_driver(&asus_nb_wmi_driver); 61762306a36Sopenharmony_ci} 61862306a36Sopenharmony_ci 61962306a36Sopenharmony_cimodule_init(asus_nb_wmi_init); 62062306a36Sopenharmony_cimodule_exit(asus_nb_wmi_exit); 621