brintos

brintos / linux-shallow public Read only

0
0
Text · 3.0 KiB · 6b23ba7 Raw
120 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 *  adv_swbutton.c - Software Button Interface Driver.4 *5 *  (C) Copyright 2020 Advantech Corporation, Inc6 *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    0x8617#define ACPI_BUTTON_NOTIFY_SWBTN_PRESSED    0x8518 19struct adv_swbutton {20	struct input_dev *input;21	char phys[32];22};23 24/*-------------------------------------------------------------------------25 *                               Driver Interface26 *--------------------------------------------------------------------------27 */28static 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 47static 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 93static void 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 101static const struct acpi_device_id button_device_ids[] = {102	{ACPI_BUTTON_HID_SWBTN, 0},103	{"", 0},104};105MODULE_DEVICE_TABLE(acpi, button_device_ids);106 107static struct platform_driver adv_swbutton_driver = {108	.driver = {109		.name = "adv_swbutton",110		.acpi_match_table = button_device_ids,111	},112	.probe = adv_swbutton_probe,113	.remove_new = adv_swbutton_remove,114};115module_platform_driver(adv_swbutton_driver);116 117MODULE_AUTHOR("Andrea Ho");118MODULE_DESCRIPTION("Advantech ACPI SW Button Driver");119MODULE_LICENSE("GPL v2");120