// SPDX-License-Identifier: GPL-2.0-only
/*
 *  Driver for the LID cover switch of the Surface 3
 *
 *  Copyright (c) 2016 Red Hat Inc.
 */


#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>

#include <linux/acpi.h>
#include <linux/dmi.h>
#include <linux/input.h>
#include <linux/mutex.h>
#include <linux/platform_device.h>
#include <linux/spi/spi.h>

MODULE_AUTHOR("Benjamin Tissoires <benjamin.tissoires@redhat.com>");
MODULE_DESCRIPTION("Surface 3 platform driver");
MODULE_LICENSE("GPL");

#define ACPI_BUTTON_HID_LID		"PNP0C0D"
#define SPI_CTL_OBJ_NAME		"SPI"
#define SPI_TS_OBJ_NAME			"NTRG"

#define SURFACE3_LID_GUID "F7CC25EC-D20B-404C-8903-0ED4359C18AE"

MODULE_ALIAS("wmi:" SURFACE3_LID_GUID);

static const struct dmi_system_id surface3_dmi_table[] = {
#if defined(CONFIG_X86)
	{
		.matches = {
			DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
			DMI_MATCH(DMI_PRODUCT_NAME, "Surface 3"),
		},
	},
#endif
	{ }
};

struct surface3_wmi {
	struct acpi_device *touchscreen_adev;
	struct acpi_device *pnp0c0d_adev;
	struct acpi_hotplug_context hp;
	struct input_dev *input;
};

static struct platform_device *s3_wmi_pdev;

static struct surface3_wmi s3_wmi;

static DEFINE_MUTEX(s3_wmi_lock);

static int s3_wmi_query_block(const char *guid, int instance, int *ret)
{
	struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
	union acpi_object *obj = NULL;
	acpi_status status;
	int error = 0;

	mutex_lock(&s3_wmi_lock);
	status = wmi_query_block(guid, instance, &output);
	if (ACPI_FAILURE(status)) {
		error = -EIO;
		goto out_free_unlock;
	}

	obj = output.pointer;

	if (!obj || obj->type != ACPI_TYPE_INTEGER) {
		if (obj) {
			pr_err("query block returned object type: %d - buffer length:%d\n",
			       obj->type,
			       obj->type == ACPI_TYPE_BUFFER ?
						obj->buffer.length : 0);
		}
		error = -EINVAL;
		goto out_free_unlock;
	}
	*ret = obj->integer.value;
 out_free_unlock:
	kfree(obj);
	mutex_unlock(&s3_wmi_lock);
	return error;
}

static inline int s3_wmi_query_lid(int *ret)
{
	return s3_wmi_query_block(SURFACE3_LID_GUID, 0, ret);
}

static int s3_wmi_send_lid_state(void)
{
	int ret, lid_sw;

	ret = s3_wmi_query_lid(&lid_sw);
	if (ret)
		return ret;

	input_report_switch(s3_wmi.input, SW_LID, lid_sw);
	input_sync(s3_wmi.input);

	return 0;
}

static int s3_wmi_hp_notify(struct acpi_device *adev, u32 value)
{
	return s3_wmi_send_lid_state();
}

static acpi_status s3_wmi_attach_spi_device(acpi_handle handle,
					    u32 level,
					    void *data,
					    void **return_value)
{
	struct acpi_device *adev, **ts_adev;

	if (acpi_bus_get_device(handle, &adev))
		return AE_OK;

	ts_adev = data;

	if (strncmp(acpi_device_bid(adev), SPI_TS_OBJ_NAME,
	    strlen(SPI_TS_OBJ_NAME)))
		return AE_OK;

	if (*ts_adev) {
		pr_err("duplicate entry %s\n", SPI_TS_OBJ_NAME);
		return AE_OK;
	}

	*ts_adev = adev;

	return AE_OK;
}

static int s3_wmi_check_platform_device(struct device *dev, void *data)
{
	struct acpi_device *adev = ACPI_COMPANION(dev);
	struct acpi_device *ts_adev = NULL;
	acpi_status status;

	/* ignore non ACPI devices */
	if (!adev)
		return 0;

	/* check for LID ACPI switch */
	if (!strcmp(ACPI_BUTTON_HID_LID, acpi_device_hid(adev))) {
		s3_wmi.pnp0c0d_adev = adev;
		return 0;
	}

	/* ignore non SPI controllers */
	if (strncmp(acpi_device_bid(adev), SPI_CTL_OBJ_NAME,
	    strlen(SPI_CTL_OBJ_NAME)))
		return 0;

	status = acpi_walk_namespace(ACPI_TYPE_DEVICE, adev->handle, 1,
				     s3_wmi_attach_spi_device, NULL,
				     &ts_adev, NULL);
	if (ACPI_FAILURE(status))
		dev_warn(dev, "failed to enumerate SPI slaves\n");

	if (!ts_adev)
		return 0;

	s3_wmi.touchscreen_adev = ts_adev;

	return 0;
}

static int s3_wmi_create_and_register_input(struct platform_device *pdev)
{
	struct input_dev *input;
	int error;

	input = devm_input_allocate_device(&pdev->dev);
	if (!input)
		return -ENOMEM;

	input->name = "Lid Switch";
	input->phys = "button/input0";
	input->id.bustype = BUS_HOST;
	input->id.product = 0x0005;

	input_set_capability(input, EV_SW, SW_LID);

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

	s3_wmi.input = input;

	return 0;
 out_err:
	input_free_device(s3_wmi.input);
	return error;
}

static int __init s3_wmi_probe(struct platform_device *pdev)
{
	int error;

	if (!dmi_check_system(surface3_dmi_table))
		return -ENODEV;

	memset(&s3_wmi, 0, sizeof(s3_wmi));

	bus_for_each_dev(&platform_bus_type, NULL, NULL,
			 s3_wmi_check_platform_device);

	if (!s3_wmi.touchscreen_adev)
		return -ENODEV;

	acpi_bus_trim(s3_wmi.pnp0c0d_adev);

	error = s3_wmi_create_and_register_input(pdev);
	if (error)
		goto restore_acpi_lid;

	acpi_initialize_hp_context(s3_wmi.touchscreen_adev, &s3_wmi.hp,
				   s3_wmi_hp_notify, NULL);

	s3_wmi_send_lid_state();

	return 0;

 restore_acpi_lid:
	acpi_bus_scan(s3_wmi.pnp0c0d_adev->handle);
	return error;
}

static int s3_wmi_remove(struct platform_device *device)
{
	/* remove the hotplug context from the acpi device */
	s3_wmi.touchscreen_adev->hp = NULL;

	/* reinstall the actual PNPC0C0D LID default handle */
	acpi_bus_scan(s3_wmi.pnp0c0d_adev->handle);
	return 0;
}

static int __maybe_unused s3_wmi_resume(struct device *dev)
{
	s3_wmi_send_lid_state();
	return 0;
}
static SIMPLE_DEV_PM_OPS(s3_wmi_pm, NULL, s3_wmi_resume);

static struct platform_driver s3_wmi_driver = {
	.driver = {
		.name = "surface3-wmi",
		.pm = &s3_wmi_pm,
	},
	.remove = s3_wmi_remove,
};

static int __init s3_wmi_init(void)
{
	int error;

	s3_wmi_pdev = platform_device_alloc("surface3-wmi", -1);
	if (!s3_wmi_pdev)
		return -ENOMEM;

	error = platform_device_add(s3_wmi_pdev);
	if (error)
		goto err_device_put;

	error = platform_driver_probe(&s3_wmi_driver, s3_wmi_probe);
	if (error)
		goto err_device_del;

	pr_info("Surface 3 WMI Extras loaded\n");
	return 0;

 err_device_del:
	platform_device_del(s3_wmi_pdev);
 err_device_put:
	platform_device_put(s3_wmi_pdev);
	return error;
}

static void __exit s3_wmi_exit(void)
{
	platform_device_unregister(s3_wmi_pdev);
	platform_driver_unregister(&s3_wmi_driver);
}

module_init(s3_wmi_init);
module_exit(s3_wmi_exit);
