Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  *  Airplane mode button for AMD, HP & Xiaomi laptops
0004  *
0005  *  Copyright (C) 2014-2017 Alex Hung <alex.hung@canonical.com>
0006  *  Copyright (C) 2021 Advanced Micro Devices
0007  */
0008 
0009 #include <linux/kernel.h>
0010 #include <linux/module.h>
0011 #include <linux/init.h>
0012 #include <linux/input.h>
0013 #include <linux/platform_device.h>
0014 #include <linux/acpi.h>
0015 #include <acpi/acpi_bus.h>
0016 
0017 MODULE_LICENSE("GPL");
0018 MODULE_AUTHOR("Alex Hung");
0019 MODULE_ALIAS("acpi*:HPQ6001:*");
0020 MODULE_ALIAS("acpi*:WSTADEF:*");
0021 MODULE_ALIAS("acpi*:AMDI0051:*");
0022 
0023 static struct input_dev *wl_input_dev;
0024 
0025 static const struct acpi_device_id wl_ids[] = {
0026     {"HPQ6001", 0},
0027     {"WSTADEF", 0},
0028     {"AMDI0051", 0},
0029     {"", 0},
0030 };
0031 
0032 static int wireless_input_setup(void)
0033 {
0034     int err;
0035 
0036     wl_input_dev = input_allocate_device();
0037     if (!wl_input_dev)
0038         return -ENOMEM;
0039 
0040     wl_input_dev->name = "Wireless hotkeys";
0041     wl_input_dev->phys = "hpq6001/input0";
0042     wl_input_dev->id.bustype = BUS_HOST;
0043     wl_input_dev->evbit[0] = BIT(EV_KEY);
0044     set_bit(KEY_RFKILL, wl_input_dev->keybit);
0045 
0046     err = input_register_device(wl_input_dev);
0047     if (err)
0048         goto err_free_dev;
0049 
0050     return 0;
0051 
0052 err_free_dev:
0053     input_free_device(wl_input_dev);
0054     return err;
0055 }
0056 
0057 static void wireless_input_destroy(void)
0058 {
0059     input_unregister_device(wl_input_dev);
0060 }
0061 
0062 static void wl_notify(struct acpi_device *acpi_dev, u32 event)
0063 {
0064     if (event != 0x80) {
0065         pr_info("Received unknown event (0x%x)\n", event);
0066         return;
0067     }
0068 
0069     input_report_key(wl_input_dev, KEY_RFKILL, 1);
0070     input_sync(wl_input_dev);
0071     input_report_key(wl_input_dev, KEY_RFKILL, 0);
0072     input_sync(wl_input_dev);
0073 }
0074 
0075 static int wl_add(struct acpi_device *device)
0076 {
0077     int err;
0078 
0079     err = wireless_input_setup();
0080     if (err)
0081         pr_err("Failed to setup wireless hotkeys\n");
0082 
0083     return err;
0084 }
0085 
0086 static int wl_remove(struct acpi_device *device)
0087 {
0088     wireless_input_destroy();
0089     return 0;
0090 }
0091 
0092 static struct acpi_driver wl_driver = {
0093     .name   = "wireless-hotkey",
0094     .owner  = THIS_MODULE,
0095     .ids    = wl_ids,
0096     .ops    = {
0097         .add    = wl_add,
0098         .remove = wl_remove,
0099         .notify = wl_notify,
0100     },
0101 };
0102 
0103 module_acpi_driver(wl_driver);