// SPDX-License-Identifier: GPL-2.0-only
/*
 * power/home/volume button support for
 * Microsoft Surface Pro 3/4 tablet.
 *
 * Copyright (c) 2015 Intel Corporation.
 * All rights reserved.
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/string.h>
#include <linux/types.h>
#include <linux/input.h>
#include <linux/acpi.h>
#include <linux/platform_device.h>
#include <acpi/button.h>

#define SURFACE_PRO3_BUTTON_HID		"MSHW0028"
#define SURFACE_PRO4_BUTTON_HID		"MSHW0040"
#define SURFACE_BUTTON_OBJ_NAME		"VGBI"

#define MSHW0040_DSM_REVISION		0x01
#define MSHW0040_DSM_GET_OMPR		0x02	// get OEM Platform Revision
static const guid_t MSHW0040_DSM_UUID =
	GUID_INIT(0x6fd05c69, 0xcde3, 0x49f4, 0x95, 0xed, 0xab, 0x16, 0x65,
		  0x49, 0x80, 0x35);

#define SURFACE_BUTTON_NOTIFY_TABLET_MODE	0xc8

#define SURFACE_BUTTON_NOTIFY_PRESS_POWER	0xc6
#define SURFACE_BUTTON_NOTIFY_RELEASE_POWER	0xc7

#define SURFACE_BUTTON_NOTIFY_PRESS_HOME	0xc4
#define SURFACE_BUTTON_NOTIFY_RELEASE_HOME	0xc5

#define SURFACE_BUTTON_NOTIFY_PRESS_VOLUME_UP	0xc0
#define SURFACE_BUTTON_NOTIFY_RELEASE_VOLUME_UP	0xc1

#define SURFACE_BUTTON_NOTIFY_PRESS_VOLUME_DOWN		0xc2
#define SURFACE_BUTTON_NOTIFY_RELEASE_VOLUME_DOWN	0xc3

MODULE_AUTHOR("Chen Yu");
MODULE_DESCRIPTION("Surface Pro3 Button Driver");
MODULE_LICENSE("GPL v2");

/*
 * Power button, Home button, Volume buttons support is supposed to
 * be covered by drivers/input/misc/soc_button_array.c, which is implemented
 * according to "Windows ACPI Design Guide for SoC Platforms".
 * However surface pro3 seems not to obey the specs, instead it uses
 * device VGBI(MSHW0028) for dispatching the events.
 * We choose acpi_driver rather than platform_driver/i2c_driver because
 * although VGBI has an i2c resource connected to i2c controller, it
 * is not embedded in any i2c controller's scope, thus neither platform_device
 * will be created, nor i2c_client will be enumerated, we have to use
 * acpi_driver.
 */
static const struct acpi_device_id surface_button_device_ids[] = {
	{SURFACE_PRO3_BUTTON_HID,    0},
	{SURFACE_PRO4_BUTTON_HID,    0},
	{"", 0},
};
MODULE_DEVICE_TABLE(acpi, surface_button_device_ids);

struct surface_button {
	unsigned int type;
	struct input_dev *input;
	char phys[32];			/* for input device */
	unsigned long pushed;
	bool suspended;
};

static void surface_button_notify(acpi_handle handle, u32 event, void *data)
{
	struct device *dev = data;
	struct surface_button *button = dev_get_drvdata(dev);
	struct input_dev *input;
	int key_code = KEY_RESERVED;
	bool pressed = false;

	switch (event) {
	/* Power button press,release handle */
	case SURFACE_BUTTON_NOTIFY_PRESS_POWER:
		pressed = true;
		fallthrough;
	case SURFACE_BUTTON_NOTIFY_RELEASE_POWER:
		key_code = KEY_POWER;
		break;
	/* Home button press,release handle */
	case SURFACE_BUTTON_NOTIFY_PRESS_HOME:
		pressed = true;
		fallthrough;
	case SURFACE_BUTTON_NOTIFY_RELEASE_HOME:
		key_code = KEY_LEFTMETA;
		break;
	/* Volume up button press,release handle */
	case SURFACE_BUTTON_NOTIFY_PRESS_VOLUME_UP:
		pressed = true;
		fallthrough;
	case SURFACE_BUTTON_NOTIFY_RELEASE_VOLUME_UP:
		key_code = KEY_VOLUMEUP;
		break;
	/* Volume down button press,release handle */
	case SURFACE_BUTTON_NOTIFY_PRESS_VOLUME_DOWN:
		pressed = true;
		fallthrough;
	case SURFACE_BUTTON_NOTIFY_RELEASE_VOLUME_DOWN:
		key_code = KEY_VOLUMEDOWN;
		break;
	case SURFACE_BUTTON_NOTIFY_TABLET_MODE:
		dev_warn_once(dev, "Tablet mode is not supported\n");
		break;
	default:
		dev_info_ratelimited(dev, "Unsupported event [0x%x]\n", event);
		break;
	}
	input = button->input;
	if (key_code == KEY_RESERVED)
		return;
	if (pressed)
		pm_wakeup_dev_event(dev, 0, button->suspended);
	if (button->suspended)
		return;
	input_report_key(input, key_code, pressed?1:0);
	input_sync(input);
}

#ifdef CONFIG_PM_SLEEP
static int surface_button_suspend(struct device *dev)
{
	struct surface_button *button = dev_get_drvdata(dev);

	button->suspended = true;
	return 0;
}

static int surface_button_resume(struct device *dev)
{
	struct surface_button *button = dev_get_drvdata(dev);

	button->suspended = false;
	return 0;
}
#endif

/*
 * Surface Pro 4 and Surface Book 2 / Surface Pro 2017 use the same device
 * ID (MSHW0040) for the power/volume buttons. Make sure this is the right
 * device by checking for the _DSM method and OEM Platform Revision.
 *
 * Returns true if the driver should bind to this device, i.e. the device is
 * either MSWH0028 (Pro 3) or MSHW0040 on a Pro 4 or Book 1.
 */
static bool surface_button_check_MSHW0040(struct device *dev, acpi_handle handle)
{
	union acpi_object *result;
	u64 oem_platform_rev = 0;	// valid revisions are nonzero

	// get OEM platform revision
	result = acpi_evaluate_dsm_typed(handle, &MSHW0040_DSM_UUID,
					 MSHW0040_DSM_REVISION,
					 MSHW0040_DSM_GET_OMPR,
					 NULL, ACPI_TYPE_INTEGER);

	/*
	 * If evaluating the _DSM fails, the method is not present. This means
	 * that we have either MSHW0028 or MSHW0040 on Pro 4 or Book 1, so we
	 * should use this driver. We use revision 0 indicating it is
	 * unavailable.
	 */

	if (result) {
		oem_platform_rev = result->integer.value;
		ACPI_FREE(result);
	}

	dev_dbg(dev, "OEM Platform Revision %llu\n", oem_platform_rev);

	return oem_platform_rev == 0;
}


static int surface_button_probe(struct platform_device *pdev)
{
	struct surface_button *button;
	struct acpi_device *device;
	struct input_dev *input;
	int error;

	device = ACPI_COMPANION(&pdev->dev);
	if (!device)
		return -ENODEV;

	if (strncmp(acpi_device_bid(device), SURFACE_BUTTON_OBJ_NAME,
	    strlen(SURFACE_BUTTON_OBJ_NAME)))
		return -ENODEV;

	if (!surface_button_check_MSHW0040(&pdev->dev, device->handle))
		return -ENODEV;

	button = kzalloc_obj(struct surface_button);
	if (!button)
		return -ENOMEM;

	platform_set_drvdata(pdev, button);
	button->input = input = input_allocate_device();
	if (!input) {
		error = -ENOMEM;
		goto err_free_button;
	}

	snprintf(button->phys, sizeof(button->phys), "%s/buttons",
		 acpi_device_hid(device));

	input->name = "Surface Pro 3/4 Buttons";
	input->phys = button->phys;
	input->id.bustype = BUS_HOST;
	input->dev.parent = &pdev->dev;
	input_set_capability(input, EV_KEY, KEY_POWER);
	input_set_capability(input, EV_KEY, KEY_LEFTMETA);
	input_set_capability(input, EV_KEY, KEY_VOLUMEUP);
	input_set_capability(input, EV_KEY, KEY_VOLUMEDOWN);

	error = input_register_device(input);
	if (error)
		goto err_free_input;

	device_init_wakeup(&pdev->dev, true);

	error = acpi_dev_install_notify_handler(device, ACPI_DEVICE_NOTIFY,
						surface_button_notify, &pdev->dev);
	if (error) {
		device_init_wakeup(&pdev->dev, false);
		input_unregister_device(input);
		goto err_free_button;
	}

	dev_info(&pdev->dev, "%s [%s]\n", input->name, acpi_device_bid(device));

	return 0;

 err_free_input:
	input_free_device(input);
 err_free_button:
	kfree(button);
	return error;
}

static void surface_button_remove(struct platform_device *pdev)
{
	struct surface_button *button = platform_get_drvdata(pdev);

	acpi_dev_remove_notify_handler(ACPI_COMPANION(&pdev->dev),
				       ACPI_DEVICE_NOTIFY, surface_button_notify);
	device_init_wakeup(&pdev->dev, false);
	input_unregister_device(button->input);
	kfree(button);
}

static SIMPLE_DEV_PM_OPS(surface_button_pm,
		surface_button_suspend, surface_button_resume);

static struct platform_driver surface_button_driver = {
	.probe = surface_button_probe,
	.remove = surface_button_remove,
	.driver = {
		.name = "surface_pro3_button",
		.acpi_match_table = surface_button_device_ids,
		.pm = &surface_button_pm,
	},
};

module_platform_driver(surface_button_driver);
