// SPDX-License-Identifier: GPL-2.0+
/*
 *  Intel Virtual Button driver for Windows 8.1+
 *
 *  Copyright (C) 2016 AceLan Kao <acelan.kao@canonical.com>
 *  Copyright (C) 2016 Alex Hung <alex.hung@canonical.com>
 */

#include <linux/acpi.h>
#include <linux/dmi.h>
#include <linux/input.h>
#include <linux/input/sparse-keymap.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/suspend.h>

/* Returned when NOT in tablet mode on some HP Stream x360 11 models */
#define VGBS_TABLET_MODE_FLAG_ALT	0x10
/* When NOT in tablet mode, VGBS returns with the flag 0x40 */
#define VGBS_TABLET_MODE_FLAG		0x40
#define VGBS_DOCK_MODE_FLAG		0x80

#define VGBS_TABLET_MODE_FLAGS (VGBS_TABLET_MODE_FLAG | VGBS_TABLET_MODE_FLAG_ALT)

MODULE_LICENSE("GPL");
MODULE_AUTHOR("AceLan Kao");

static const struct acpi_device_id intel_vbtn_ids[] = {
	{"INT33D6", 0},
	{"", 0},
};
MODULE_DEVICE_TABLE(acpi, intel_vbtn_ids);

/* In theory, these are HID usages. */
static const struct key_entry intel_vbtn_keymap[] = {
	{ KE_KEY, 0xC0, { KEY_POWER } },	/* power key press */
	{ KE_IGNORE, 0xC1, { KEY_POWER } },	/* power key release */
	{ KE_KEY, 0xC2, { KEY_LEFTMETA } },		/* 'Windows' key press */
	{ KE_KEY, 0xC3, { KEY_LEFTMETA } },		/* 'Windows' key release */
	{ KE_KEY, 0xC4, { KEY_VOLUMEUP } },		/* volume-up key press */
	{ KE_IGNORE, 0xC5, { KEY_VOLUMEUP } },		/* volume-up key release */
	{ KE_KEY, 0xC6, { KEY_VOLUMEDOWN } },		/* volume-down key press */
	{ KE_IGNORE, 0xC7, { KEY_VOLUMEDOWN } },	/* volume-down key release */
	{ KE_KEY,    0xC8, { KEY_ROTATE_LOCK_TOGGLE } },	/* rotate-lock key press */
	{ KE_KEY,    0xC9, { KEY_ROTATE_LOCK_TOGGLE } },	/* rotate-lock key release */
	{ KE_END }
};

static const struct key_entry intel_vbtn_switchmap[] = {
	/*
	 * SW_DOCK should only be reported for docking stations, but DSDTs using the
	 * intel-vbtn code, always seem to use this for 2-in-1s / convertibles and set
	 * SW_DOCK=1 when in laptop-mode (in tandem with setting SW_TABLET_MODE=0).
	 * This causes userspace to think the laptop is docked to a port-replicator
	 * and to disable suspend-on-lid-close, which is undesirable.
	 * Map the dock events to KEY_IGNORE to avoid this broken SW_DOCK reporting.
	 */
	{ KE_IGNORE, 0xCA, { .sw = { SW_DOCK, 1 } } },		/* Docked */
	{ KE_IGNORE, 0xCB, { .sw = { SW_DOCK, 0 } } },		/* Undocked */
	{ KE_SW,     0xCC, { .sw = { SW_TABLET_MODE, 1 } } },	/* Tablet */
	{ KE_SW,     0xCD, { .sw = { SW_TABLET_MODE, 0 } } },	/* Laptop */
	{ KE_END }
};

struct intel_vbtn_priv {
	struct input_dev *buttons_dev;
	struct input_dev *switches_dev;
	bool has_buttons;
	bool has_switches;
	bool wakeup_mode;
};

static void detect_tablet_mode(struct platform_device *device)
{
	struct intel_vbtn_priv *priv = dev_get_drvdata(&device->dev);
	acpi_handle handle = ACPI_HANDLE(&device->dev);
	unsigned long long vgbs;
	acpi_status status;
	int m;

	status = acpi_evaluate_integer(handle, "VGBS", NULL, &vgbs);
	if (ACPI_FAILURE(status))
		return;

	m = !(vgbs & VGBS_TABLET_MODE_FLAGS);
	input_report_switch(priv->switches_dev, SW_TABLET_MODE, m);
	m = (vgbs & VGBS_DOCK_MODE_FLAG) ? 1 : 0;
	input_report_switch(priv->switches_dev, SW_DOCK, m);
}

/*
 * Note this unconditionally creates the 2 input_dev-s and sets up
 * the sparse-keymaps. Only the registration is conditional on
 * have_buttons / have_switches. This is done so that the notify
 * handler can always call sparse_keymap_entry_from_scancode()
 * on the input_dev-s do determine the event type.
 */
static int intel_vbtn_input_setup(struct platform_device *device)
{
	struct intel_vbtn_priv *priv = dev_get_drvdata(&device->dev);
	int ret;

	priv->buttons_dev = devm_input_allocate_device(&device->dev);
	if (!priv->buttons_dev)
		return -ENOMEM;

	ret = sparse_keymap_setup(priv->buttons_dev, intel_vbtn_keymap, NULL);
	if (ret)
		return ret;

	priv->buttons_dev->dev.parent = &device->dev;
	priv->buttons_dev->name = "Intel Virtual Buttons";
	priv->buttons_dev->id.bustype = BUS_HOST;

	if (priv->has_buttons) {
		ret = input_register_device(priv->buttons_dev);
		if (ret)
			return ret;
	}

	priv->switches_dev = devm_input_allocate_device(&device->dev);
	if (!priv->switches_dev)
		return -ENOMEM;

	ret = sparse_keymap_setup(priv->switches_dev, intel_vbtn_switchmap, NULL);
	if (ret)
		return ret;

	priv->switches_dev->dev.parent = &device->dev;
	priv->switches_dev->name = "Intel Virtual Switches";
	priv->switches_dev->id.bustype = BUS_HOST;

	if (priv->has_switches) {
		detect_tablet_mode(device);

		ret = input_register_device(priv->switches_dev);
		if (ret)
			return ret;
	}

	return 0;
}

static void notify_handler(acpi_handle handle, u32 event, void *context)
{
	struct platform_device *device = context;
	struct intel_vbtn_priv *priv = dev_get_drvdata(&device->dev);
	unsigned int val = !(event & 1); /* Even=press, Odd=release */
	const struct key_entry *ke, *ke_rel;
	struct input_dev *input_dev;
	bool autorelease;
	int ret;

	if ((ke = sparse_keymap_entry_from_scancode(priv->buttons_dev, event))) {
		if (!priv->has_buttons) {
			dev_warn(&device->dev, "Warning: received a button event on a device without buttons, please report this.\n");
			return;
		}
		input_dev = priv->buttons_dev;
	} else if ((ke = sparse_keymap_entry_from_scancode(priv->switches_dev, event))) {
		if (!priv->has_switches) {
			dev_info(&device->dev, "Registering Intel Virtual Switches input-dev after receiving a switch event\n");
			ret = input_register_device(priv->switches_dev);
			if (ret)
				return;

			priv->has_switches = true;
		}
		input_dev = priv->switches_dev;
	} else {
		dev_dbg(&device->dev, "unknown event index 0x%x\n", event);
		return;
	}

	if (priv->wakeup_mode) {
		pm_wakeup_hard_event(&device->dev);

		/*
		 * Skip reporting an evdev event for button wake events,
		 * mirroring how the drivers/acpi/button.c code skips this too.
		 */
		if (ke->type == KE_KEY)
			return;
	}

	/*
	 * Even press events are autorelease if there is no corresponding odd
	 * release event, or if the odd event is KE_IGNORE.
	 */
	ke_rel = sparse_keymap_entry_from_scancode(input_dev, event | 1);
	autorelease = val && (!ke_rel || ke_rel->type == KE_IGNORE);

	sparse_keymap_report_event(input_dev, event, val, autorelease);
}

/*
 * There are several laptops (non 2-in-1) models out there which support VGBS,
 * but simply always return 0, which we translate to SW_TABLET_MODE=1. This in
 * turn causes userspace (libinput) to suppress events from the builtin
 * keyboard and touchpad, making the laptop essentially unusable.
 *
 * Since the problem of wrongly reporting SW_TABLET_MODE=1 in combination
 * with libinput, leads to a non-usable system. Where as OTOH many people will
 * not even notice when SW_TABLET_MODE is not being reported, a DMI based allow
 * list is used here. This list mainly matches on the chassis-type of 2-in-1s.
 *
 * There are also some 2-in-1s which use the intel-vbtn ACPI interface to report
 * SW_TABLET_MODE with a chassis-type of 8 ("Portable") or 10 ("Notebook"),
 * these are matched on a per model basis, since many normal laptops with a
 * possible broken VGBS ACPI-method also use these chassis-types.
 */
static const struct dmi_system_id dmi_switches_allow_list[] = {
	{
		.matches = {
			DMI_EXACT_MATCH(DMI_CHASSIS_TYPE, "31" /* Convertible */),
		},
	},
	{
		.matches = {
			DMI_EXACT_MATCH(DMI_CHASSIS_TYPE, "32" /* Detachable */),
		},
	},
	{
		.matches = {
			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
			DMI_MATCH(DMI_PRODUCT_NAME, "Venue 11 Pro 7130"),
		},
	},
	{
		.matches = {
			DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
			DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion 13 x360 PC"),
		},
	},
	{
		.matches = {
			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
			DMI_MATCH(DMI_PRODUCT_NAME, "Switch SA5-271"),
		},
	},
	{
		.matches = {
			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
			DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 7352"),
		},
	},
	{} /* Array terminator */
};

static bool intel_vbtn_has_switches(acpi_handle handle)
{
	unsigned long long vgbs;
	acpi_status status;

	if (!dmi_check_system(dmi_switches_allow_list))
		return false;

	status = acpi_evaluate_integer(handle, "VGBS", NULL, &vgbs);
	return ACPI_SUCCESS(status);
}

static int intel_vbtn_probe(struct platform_device *device)
{
	acpi_handle handle = ACPI_HANDLE(&device->dev);
	bool has_buttons, has_switches;
	struct intel_vbtn_priv *priv;
	acpi_status status;
	int err;

	has_buttons = acpi_has_method(handle, "VBDL");
	has_switches = intel_vbtn_has_switches(handle);

	if (!has_buttons && !has_switches) {
		dev_warn(&device->dev, "failed to read Intel Virtual Button driver\n");
		return -ENODEV;
	}

	priv = devm_kzalloc(&device->dev, sizeof(*priv), GFP_KERNEL);
	if (!priv)
		return -ENOMEM;
	dev_set_drvdata(&device->dev, priv);

	priv->has_buttons = has_buttons;
	priv->has_switches = has_switches;

	err = intel_vbtn_input_setup(device);
	if (err) {
		pr_err("Failed to setup Intel Virtual Button\n");
		return err;
	}

	status = acpi_install_notify_handler(handle,
					     ACPI_DEVICE_NOTIFY,
					     notify_handler,
					     device);
	if (ACPI_FAILURE(status))
		return -EBUSY;

	if (has_buttons) {
		status = acpi_evaluate_object(handle, "VBDL", NULL, NULL);
		if (ACPI_FAILURE(status))
			dev_err(&device->dev, "Error VBDL failed with ACPI status %d\n", status);
	}

	device_init_wakeup(&device->dev, true);
	/*
	 * In order for system wakeup to work, the EC GPE has to be marked as
	 * a wakeup one, so do that here (this setting will persist, but it has
	 * no effect until the wakeup mask is set for the EC GPE).
	 */
	acpi_ec_mark_gpe_for_wake();
	return 0;
}

static int intel_vbtn_remove(struct platform_device *device)
{
	acpi_handle handle = ACPI_HANDLE(&device->dev);

	device_init_wakeup(&device->dev, false);
	acpi_remove_notify_handler(handle, ACPI_DEVICE_NOTIFY, notify_handler);

	/*
	 * Even if we failed to shut off the event stream, we can still
	 * safely detach from the device.
	 */
	return 0;
}

static int intel_vbtn_pm_prepare(struct device *dev)
{
	if (device_may_wakeup(dev)) {
		struct intel_vbtn_priv *priv = dev_get_drvdata(dev);

		priv->wakeup_mode = true;
	}
	return 0;
}

static void intel_vbtn_pm_complete(struct device *dev)
{
	struct intel_vbtn_priv *priv = dev_get_drvdata(dev);

	priv->wakeup_mode = false;
}

static int intel_vbtn_pm_resume(struct device *dev)
{
	intel_vbtn_pm_complete(dev);
	return 0;
}

static const struct dev_pm_ops intel_vbtn_pm_ops = {
	.prepare = intel_vbtn_pm_prepare,
	.complete = intel_vbtn_pm_complete,
	.resume = intel_vbtn_pm_resume,
	.restore = intel_vbtn_pm_resume,
	.thaw = intel_vbtn_pm_resume,
};

static struct platform_driver intel_vbtn_pl_driver = {
	.driver = {
		.name = "intel-vbtn",
		.acpi_match_table = intel_vbtn_ids,
		.pm = &intel_vbtn_pm_ops,
	},
	.probe = intel_vbtn_probe,
	.remove = intel_vbtn_remove,
};

static acpi_status __init
check_acpi_dev(acpi_handle handle, u32 lvl, void *context, void **rv)
{
	const struct acpi_device_id *ids = context;
	struct acpi_device *dev;

	if (acpi_bus_get_device(handle, &dev) != 0)
		return AE_OK;

	if (acpi_match_device_ids(dev, ids) == 0)
		if (!IS_ERR_OR_NULL(acpi_create_platform_device(dev, NULL)))
			dev_info(&dev->dev,
				 "intel-vbtn: created platform device\n");

	return AE_OK;
}

static int __init intel_vbtn_init(void)
{
	acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
			    ACPI_UINT32_MAX, check_acpi_dev, NULL,
			    (void *)intel_vbtn_ids, NULL);

	return platform_driver_register(&intel_vbtn_pl_driver);
}
module_init(intel_vbtn_init);

static void __exit intel_vbtn_exit(void)
{
	platform_driver_unregister(&intel_vbtn_pl_driver);
}
module_exit(intel_vbtn_exit);
