Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Andrea.Ho and committed by
Hans de Goede
3d904005 e72457fc

+141
+6
MAINTAINERS
··· 573 573 F: Documentation/scsi/advansys.rst 574 574 F: drivers/scsi/advansys.c 575 575 576 + ADVANTECH SWBTN DRIVER 577 + M: Andrea Ho <Andrea.Ho@advantech.com.tw> 578 + L: platform-driver-x86@vger.kernel.org 579 + S: Maintained 580 + F: drivers/platform/x86/adv_swbutton.c 581 + 576 582 ADXL34X THREE-AXIS DIGITAL ACCELEROMETER DRIVER (ADXL345/ADXL346) 577 583 M: Michael Hennerich <michael.hennerich@analog.com> 578 584 S: Supported
+11
drivers/platform/x86/Kconfig
··· 193 193 If you choose to compile this driver as a module the module will be 194 194 called amd-pmc. 195 195 196 + config ADV_SWBUTTON 197 + tristate "Advantech ACPI Software Button Driver" 198 + depends on ACPI && INPUT 199 + help 200 + Say Y here to enable support for Advantech software defined 201 + button feature. More information can be found at 202 + <http://www.advantech.com.tw/products/> 203 + 204 + To compile this driver as a module, choose M here. The module will 205 + be called adv_swbutton. 206 + 196 207 config APPLE_GMUX 197 208 tristate "Apple Gmux Driver" 198 209 depends on ACPI && PCI
+3
drivers/platform/x86/Makefile
··· 24 24 # AMD 25 25 obj-$(CONFIG_AMD_PMC) += amd-pmc.o 26 26 27 + # Advantech 28 + obj-$(CONFIG_ADV_SWBUTTON) += adv_swbutton.o 29 + 27 30 # Apple 28 31 obj-$(CONFIG_APPLE_GMUX) += apple-gmux.o 29 32
+121
drivers/platform/x86/adv_swbutton.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * adv_swbutton.c - Software Button Interface Driver. 4 + * 5 + * (C) Copyright 2020 Advantech Corporation, Inc 6 + * 7 + */ 8 + #include <linux/kernel.h> 9 + #include <linux/module.h> 10 + #include <linux/input.h> 11 + #include <linux/acpi.h> 12 + #include <linux/platform_device.h> 13 + 14 + #define ACPI_BUTTON_HID_SWBTN "AHC0310" 15 + 16 + #define ACPI_BUTTON_NOTIFY_SWBTN_RELEASE 0x86 17 + #define ACPI_BUTTON_NOTIFY_SWBTN_PRESSED 0x85 18 + 19 + struct adv_swbutton { 20 + struct input_dev *input; 21 + char phys[32]; 22 + }; 23 + 24 + /*------------------------------------------------------------------------- 25 + * Driver Interface 26 + *-------------------------------------------------------------------------- 27 + */ 28 + static void adv_swbutton_notify(acpi_handle handle, u32 event, void *context) 29 + { 30 + struct platform_device *device = context; 31 + struct adv_swbutton *button = dev_get_drvdata(&device->dev); 32 + 33 + switch (event) { 34 + case ACPI_BUTTON_NOTIFY_SWBTN_RELEASE: 35 + input_report_key(button->input, KEY_PROG1, 0); 36 + input_sync(button->input); 37 + break; 38 + case ACPI_BUTTON_NOTIFY_SWBTN_PRESSED: 39 + input_report_key(button->input, KEY_PROG1, 1); 40 + input_sync(button->input); 41 + break; 42 + default: 43 + dev_dbg(&device->dev, "Unsupported event [0x%x]\n", event); 44 + } 45 + } 46 + 47 + static int adv_swbutton_probe(struct platform_device *device) 48 + { 49 + struct adv_swbutton *button; 50 + struct input_dev *input; 51 + acpi_handle handle = ACPI_HANDLE(&device->dev); 52 + acpi_status status; 53 + int error; 54 + 55 + button = devm_kzalloc(&device->dev, sizeof(*button), GFP_KERNEL); 56 + if (!button) 57 + return -ENOMEM; 58 + 59 + dev_set_drvdata(&device->dev, button); 60 + 61 + input = devm_input_allocate_device(&device->dev); 62 + if (!input) 63 + return -ENOMEM; 64 + 65 + button->input = input; 66 + snprintf(button->phys, sizeof(button->phys), "%s/button/input0", ACPI_BUTTON_HID_SWBTN); 67 + 68 + input->name = "Advantech Software Button"; 69 + input->phys = button->phys; 70 + input->id.bustype = BUS_HOST; 71 + input->dev.parent = &device->dev; 72 + set_bit(EV_REP, input->evbit); 73 + input_set_capability(input, EV_KEY, KEY_PROG1); 74 + 75 + error = input_register_device(input); 76 + if (error) 77 + return error; 78 + 79 + device_init_wakeup(&device->dev, true); 80 + 81 + status = acpi_install_notify_handler(handle, 82 + ACPI_DEVICE_NOTIFY, 83 + adv_swbutton_notify, 84 + device); 85 + if (ACPI_FAILURE(status)) { 86 + dev_err(&device->dev, "Error installing notify handler\n"); 87 + return -EIO; 88 + } 89 + 90 + return 0; 91 + } 92 + 93 + static int adv_swbutton_remove(struct platform_device *device) 94 + { 95 + acpi_handle handle = ACPI_HANDLE(&device->dev); 96 + 97 + acpi_remove_notify_handler(handle, ACPI_DEVICE_NOTIFY, 98 + adv_swbutton_notify); 99 + 100 + return 0; 101 + } 102 + 103 + static const struct acpi_device_id button_device_ids[] = { 104 + {ACPI_BUTTON_HID_SWBTN, 0}, 105 + {"", 0}, 106 + }; 107 + MODULE_DEVICE_TABLE(acpi, button_device_ids); 108 + 109 + static struct platform_driver adv_swbutton_driver = { 110 + .driver = { 111 + .name = "adv_swbutton", 112 + .acpi_match_table = button_device_ids, 113 + }, 114 + .probe = adv_swbutton_probe, 115 + .remove = adv_swbutton_remove, 116 + }; 117 + module_platform_driver(adv_swbutton_driver); 118 + 119 + MODULE_AUTHOR("Andrea Ho"); 120 + MODULE_DESCRIPTION("Advantech ACPI SW Button Driver"); 121 + MODULE_LICENSE("GPL v2");