diff options
author | Andrea.Ho <Andrea.Ho@advantech.com.tw> | 2021-03-19 03:44:27 +0000 |
---|---|---|
committer | Hans de Goede <hdegoede@redhat.com> | 2021-04-07 19:46:56 +0200 |
commit | 3d904005f6869f37fcc7188f2a15872deecbb38a (patch) | |
tree | 9b9c8c9bb6d63a8b5dd5c594e5a11ffb883ab5f7 /drivers/platform/x86 | |
parent | e72457fce9c339193b8da34967ca09e901cb3ed9 (diff) |
platform/x86: add support for Advantech software defined button
Advantech sw_button is a ACPI event trigger button.
With this driver, we can report KEY_PROG1 on the
Advantech Tabletop Network Appliances products and it has been
tested in FWA1112VC.
Add the software define button support to report EV_REP key_event
(KEY_PROG1) by pressing button that could be get on user
interface and trigger the customized actions.
Signed-off-by: Andrea.Ho <Andrea.Ho@advantech.com.tw>
Link: https://lore.kernel.org/r/20210319034427.23222-1-andrea.cs97g@nctu.edu.tw
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Diffstat (limited to 'drivers/platform/x86')
-rw-r--r-- | drivers/platform/x86/Kconfig | 11 | ||||
-rw-r--r-- | drivers/platform/x86/Makefile | 3 | ||||
-rw-r--r-- | drivers/platform/x86/adv_swbutton.c | 121 |
3 files changed, 135 insertions, 0 deletions
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index dcc01dd5ded1..53973ee59bf7 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig @@ -193,6 +193,17 @@ config AMD_PMC If you choose to compile this driver as a module the module will be called amd-pmc. +config ADV_SWBUTTON + tristate "Advantech ACPI Software Button Driver" + depends on ACPI && INPUT + help + Say Y here to enable support for Advantech software defined + button feature. More information can be found at + <http://www.advantech.com.tw/products/> + + To compile this driver as a module, choose M here. The module will + be called adv_swbutton. + config APPLE_GMUX tristate "Apple Gmux Driver" depends on ACPI && PCI diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile index 60d554073749..3e364941e8a7 100644 --- a/drivers/platform/x86/Makefile +++ b/drivers/platform/x86/Makefile @@ -24,6 +24,9 @@ obj-$(CONFIG_ACER_WMI) += acer-wmi.o # AMD obj-$(CONFIG_AMD_PMC) += amd-pmc.o +# Advantech +obj-$(CONFIG_ADV_SWBUTTON) += adv_swbutton.o + # Apple obj-$(CONFIG_APPLE_GMUX) += apple-gmux.o diff --git a/drivers/platform/x86/adv_swbutton.c b/drivers/platform/x86/adv_swbutton.c new file mode 100644 index 000000000000..38693b735c87 --- /dev/null +++ b/drivers/platform/x86/adv_swbutton.c @@ -0,0 +1,121 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * adv_swbutton.c - Software Button Interface Driver. + * + * (C) Copyright 2020 Advantech Corporation, Inc + * + */ +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/input.h> +#include <linux/acpi.h> +#include <linux/platform_device.h> + +#define ACPI_BUTTON_HID_SWBTN "AHC0310" + +#define ACPI_BUTTON_NOTIFY_SWBTN_RELEASE 0x86 +#define ACPI_BUTTON_NOTIFY_SWBTN_PRESSED 0x85 + +struct adv_swbutton { + struct input_dev *input; + char phys[32]; +}; + +/*------------------------------------------------------------------------- + * Driver Interface + *-------------------------------------------------------------------------- + */ +static void adv_swbutton_notify(acpi_handle handle, u32 event, void *context) +{ + struct platform_device *device = context; + struct adv_swbutton *button = dev_get_drvdata(&device->dev); + + switch (event) { + case ACPI_BUTTON_NOTIFY_SWBTN_RELEASE: + input_report_key(button->input, KEY_PROG1, 0); + input_sync(button->input); + break; + case ACPI_BUTTON_NOTIFY_SWBTN_PRESSED: + input_report_key(button->input, KEY_PROG1, 1); + input_sync(button->input); + break; + default: + dev_dbg(&device->dev, "Unsupported event [0x%x]\n", event); + } +} + +static int adv_swbutton_probe(struct platform_device *device) +{ + struct adv_swbutton *button; + struct input_dev *input; + acpi_handle handle = ACPI_HANDLE(&device->dev); + acpi_status status; + int error; + + button = devm_kzalloc(&device->dev, sizeof(*button), GFP_KERNEL); + if (!button) + return -ENOMEM; + + dev_set_drvdata(&device->dev, button); + + input = devm_input_allocate_device(&device->dev); + if (!input) + return -ENOMEM; + + button->input = input; + snprintf(button->phys, sizeof(button->phys), "%s/button/input0", ACPI_BUTTON_HID_SWBTN); + + input->name = "Advantech Software Button"; + input->phys = button->phys; + input->id.bustype = BUS_HOST; + input->dev.parent = &device->dev; + set_bit(EV_REP, input->evbit); + input_set_capability(input, EV_KEY, KEY_PROG1); + + error = input_register_device(input); + if (error) + return error; + + device_init_wakeup(&device->dev, true); + + status = acpi_install_notify_handler(handle, + ACPI_DEVICE_NOTIFY, + adv_swbutton_notify, + device); + if (ACPI_FAILURE(status)) { + dev_err(&device->dev, "Error installing notify handler\n"); + return -EIO; + } + + return 0; +} + +static int adv_swbutton_remove(struct platform_device *device) +{ + acpi_handle handle = ACPI_HANDLE(&device->dev); + + acpi_remove_notify_handler(handle, ACPI_DEVICE_NOTIFY, + adv_swbutton_notify); + + return 0; +} + +static const struct acpi_device_id button_device_ids[] = { + {ACPI_BUTTON_HID_SWBTN, 0}, + {"", 0}, +}; +MODULE_DEVICE_TABLE(acpi, button_device_ids); + +static struct platform_driver adv_swbutton_driver = { + .driver = { + .name = "adv_swbutton", + .acpi_match_table = button_device_ids, + }, + .probe = adv_swbutton_probe, + .remove = adv_swbutton_remove, +}; +module_platform_driver(adv_swbutton_driver); + +MODULE_AUTHOR("Andrea Ho"); +MODULE_DESCRIPTION("Advantech ACPI SW Button Driver"); +MODULE_LICENSE("GPL v2"); |