18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Acer Wireless Radio Control Driver
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Copyright (C) 2017 Endless Mobile, Inc.
68c2ecf20Sopenharmony_ci */
78c2ecf20Sopenharmony_ci
88c2ecf20Sopenharmony_ci#include <linux/acpi.h>
98c2ecf20Sopenharmony_ci#include <linux/input.h>
108c2ecf20Sopenharmony_ci#include <linux/kernel.h>
118c2ecf20Sopenharmony_ci#include <linux/module.h>
128c2ecf20Sopenharmony_ci#include <linux/pci_ids.h>
138c2ecf20Sopenharmony_ci#include <linux/types.h>
148c2ecf20Sopenharmony_ci
158c2ecf20Sopenharmony_cistatic const struct acpi_device_id acer_wireless_acpi_ids[] = {
168c2ecf20Sopenharmony_ci	{"10251229", 0},
178c2ecf20Sopenharmony_ci	{"", 0},
188c2ecf20Sopenharmony_ci};
198c2ecf20Sopenharmony_ciMODULE_DEVICE_TABLE(acpi, acer_wireless_acpi_ids);
208c2ecf20Sopenharmony_ci
218c2ecf20Sopenharmony_cistatic void acer_wireless_notify(struct acpi_device *adev, u32 event)
228c2ecf20Sopenharmony_ci{
238c2ecf20Sopenharmony_ci	struct input_dev *idev = acpi_driver_data(adev);
248c2ecf20Sopenharmony_ci
258c2ecf20Sopenharmony_ci	dev_dbg(&adev->dev, "event=%#x\n", event);
268c2ecf20Sopenharmony_ci	if (event != 0x80) {
278c2ecf20Sopenharmony_ci		dev_notice(&adev->dev, "Unknown SMKB event: %#x\n", event);
288c2ecf20Sopenharmony_ci		return;
298c2ecf20Sopenharmony_ci	}
308c2ecf20Sopenharmony_ci	input_report_key(idev, KEY_RFKILL, 1);
318c2ecf20Sopenharmony_ci	input_report_key(idev, KEY_RFKILL, 0);
328c2ecf20Sopenharmony_ci	input_sync(idev);
338c2ecf20Sopenharmony_ci}
348c2ecf20Sopenharmony_ci
358c2ecf20Sopenharmony_cistatic int acer_wireless_add(struct acpi_device *adev)
368c2ecf20Sopenharmony_ci{
378c2ecf20Sopenharmony_ci	struct input_dev *idev;
388c2ecf20Sopenharmony_ci
398c2ecf20Sopenharmony_ci	idev = devm_input_allocate_device(&adev->dev);
408c2ecf20Sopenharmony_ci	if (!idev)
418c2ecf20Sopenharmony_ci		return -ENOMEM;
428c2ecf20Sopenharmony_ci
438c2ecf20Sopenharmony_ci	adev->driver_data = idev;
448c2ecf20Sopenharmony_ci	idev->name = "Acer Wireless Radio Control";
458c2ecf20Sopenharmony_ci	idev->phys = "acer-wireless/input0";
468c2ecf20Sopenharmony_ci	idev->id.bustype = BUS_HOST;
478c2ecf20Sopenharmony_ci	idev->id.vendor = PCI_VENDOR_ID_AI;
488c2ecf20Sopenharmony_ci	idev->id.product = 0x1229;
498c2ecf20Sopenharmony_ci	set_bit(EV_KEY, idev->evbit);
508c2ecf20Sopenharmony_ci	set_bit(KEY_RFKILL, idev->keybit);
518c2ecf20Sopenharmony_ci
528c2ecf20Sopenharmony_ci	return input_register_device(idev);
538c2ecf20Sopenharmony_ci}
548c2ecf20Sopenharmony_ci
558c2ecf20Sopenharmony_cistatic struct acpi_driver acer_wireless_driver = {
568c2ecf20Sopenharmony_ci	.name = "Acer Wireless Radio Control Driver",
578c2ecf20Sopenharmony_ci	.class = "hotkey",
588c2ecf20Sopenharmony_ci	.ids = acer_wireless_acpi_ids,
598c2ecf20Sopenharmony_ci	.ops = {
608c2ecf20Sopenharmony_ci		.add = acer_wireless_add,
618c2ecf20Sopenharmony_ci		.notify = acer_wireless_notify,
628c2ecf20Sopenharmony_ci	},
638c2ecf20Sopenharmony_ci};
648c2ecf20Sopenharmony_cimodule_acpi_driver(acer_wireless_driver);
658c2ecf20Sopenharmony_ci
668c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("Acer Wireless Radio Control Driver");
678c2ecf20Sopenharmony_ciMODULE_AUTHOR("Chris Chiu <chiu@gmail.com>");
688c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL v2");
69