// SPDX-License-Identifier: GPL-2.0+
/*
 * lg-laptop.c - LG Gram ACPI features and hotkeys Driver
 *
 * Copyright (C) 2018 Matan Ziv-Av <matan@svgalib.org>
 */

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

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

#define LED_DEVICE(_name, max) struct led_classdev _name = { \
	.name           = __stringify(_name),   \
	.max_brightness = max,                  \
	.brightness_set = _name##_set,          \
	.brightness_get = _name##_get,          \
}

MODULE_AUTHOR("Matan Ziv-Av");
MODULE_DESCRIPTION("LG WMI Hotkey Driver");
MODULE_LICENSE("GPL");

#define WMI_EVENT_GUID0	"E4FB94F9-7F2B-4173-AD1A-CD1D95086248"
#define WMI_EVENT_GUID1	"023B133E-49D1-4E10-B313-698220140DC2"
#define WMI_EVENT_GUID2	"37BE1AC0-C3F2-4B1F-BFBE-8FDEAF2814D6"
#define WMI_EVENT_GUID3	"911BAD44-7DF8-4FBB-9319-BABA1C4B293B"
#define WMI_METHOD_WMAB "C3A72B38-D3EF-42D3-8CBB-D5A57049F66D"
#define WMI_METHOD_WMBB "2B4F501A-BD3C-4394-8DCF-00A7D2BC8210"
#define WMI_EVENT_GUID  WMI_EVENT_GUID0

#define WMAB_METHOD     "\\XINI.WMAB"
#define WMBB_METHOD     "\\XINI.WMBB"
#define SB_GGOV_METHOD  "\\_SB.GGOV"
#define GOV_TLED        0x2020008
#define WM_GET          1
#define WM_SET          2
#define WM_KEY_LIGHT    0x400
#define WM_TLED         0x404
#define WM_FN_LOCK      0x407
#define WM_BATT_LIMIT   0x61
#define WM_READER_MODE  0xBF
#define WM_FAN_MODE	0x33
#define WMBB_USB_CHARGE 0x10B
#define WMBB_BATT_LIMIT 0x10C

#define PLATFORM_NAME   "lg-laptop"

MODULE_ALIAS("wmi:" WMI_EVENT_GUID0);
MODULE_ALIAS("wmi:" WMI_EVENT_GUID1);
MODULE_ALIAS("wmi:" WMI_EVENT_GUID2);
MODULE_ALIAS("wmi:" WMI_EVENT_GUID3);
MODULE_ALIAS("wmi:" WMI_METHOD_WMAB);
MODULE_ALIAS("wmi:" WMI_METHOD_WMBB);
MODULE_ALIAS("acpi*:LGEX0815:*");

static struct platform_device *pf_device;
static struct input_dev *wmi_input_dev;

static u32 inited;
#define INIT_INPUT_WMI_0        0x01
#define INIT_INPUT_WMI_2        0x02
#define INIT_INPUT_ACPI         0x04
#define INIT_TPAD_LED           0x08
#define INIT_KBD_LED            0x10
#define INIT_SPARSE_KEYMAP        0x80

static const struct key_entry wmi_keymap[] = {
	{KE_KEY, 0x70, {KEY_F15} },	 /* LG control panel (F1) */
	{KE_KEY, 0x74, {KEY_F13} },	 /* Touchpad toggle (F5) */
	{KE_KEY, 0xf020000, {KEY_F14} }, /* Read mode (F9) */
	{KE_KEY, 0x10000000, {KEY_F16} },/* Keyboard backlight (F8) - pressing
					  * this key both sends an event and
					  * changes backlight level.
					  */
	{KE_KEY, 0x80, {KEY_RFKILL} },
	{KE_END, 0}
};

static int ggov(u32 arg0)
{
	union acpi_object args[1];
	union acpi_object *r;
	acpi_status status;
	acpi_handle handle;
	struct acpi_object_list arg;
	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
	int res;

	args[0].type = ACPI_TYPE_INTEGER;
	args[0].integer.value = arg0;

	status = acpi_get_handle(NULL, (acpi_string) SB_GGOV_METHOD, &handle);
	if (ACPI_FAILURE(status)) {
		pr_err("Cannot get handle");
		return -ENODEV;
	}

	arg.count = 1;
	arg.pointer = args;

	status = acpi_evaluate_object(handle, NULL, &arg, &buffer);
	if (ACPI_FAILURE(status)) {
		acpi_handle_err(handle, "GGOV: call failed.\n");
		return -EINVAL;
	}

	r = buffer.pointer;
	if (r->type != ACPI_TYPE_INTEGER) {
		kfree(r);
		return -EINVAL;
	}

	res = r->integer.value;
	kfree(r);

	return res;
}

static union acpi_object *lg_wmab(u32 method, u32 arg1, u32 arg2)
{
	union acpi_object args[3];
	acpi_status status;
	acpi_handle handle;
	struct acpi_object_list arg;
	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };

	args[0].type = ACPI_TYPE_INTEGER;
	args[0].integer.value = method;
	args[1].type = ACPI_TYPE_INTEGER;
	args[1].integer.value = arg1;
	args[2].type = ACPI_TYPE_INTEGER;
	args[2].integer.value = arg2;

	status = acpi_get_handle(NULL, (acpi_string) WMAB_METHOD, &handle);
	if (ACPI_FAILURE(status)) {
		pr_err("Cannot get handle");
		return NULL;
	}

	arg.count = 3;
	arg.pointer = args;

	status = acpi_evaluate_object(handle, NULL, &arg, &buffer);
	if (ACPI_FAILURE(status)) {
		acpi_handle_err(handle, "WMAB: call failed.\n");
		return NULL;
	}

	return buffer.pointer;
}

static union acpi_object *lg_wmbb(u32 method_id, u32 arg1, u32 arg2)
{
	union acpi_object args[3];
	acpi_status status;
	acpi_handle handle;
	struct acpi_object_list arg;
	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
	u8 buf[32];

	*(u32 *)buf = method_id;
	*(u32 *)(buf + 4) = arg1;
	*(u32 *)(buf + 16) = arg2;
	args[0].type = ACPI_TYPE_INTEGER;
	args[0].integer.value = 0; /* ignored */
	args[1].type = ACPI_TYPE_INTEGER;
	args[1].integer.value = 1; /* Must be 1 or 2. Does not matter which */
	args[2].type = ACPI_TYPE_BUFFER;
	args[2].buffer.length = 32;
	args[2].buffer.pointer = buf;

	status = acpi_get_handle(NULL, (acpi_string)WMBB_METHOD, &handle);
	if (ACPI_FAILURE(status)) {
		pr_err("Cannot get handle");
		return NULL;
	}

	arg.count = 3;
	arg.pointer = args;

	status = acpi_evaluate_object(handle, NULL, &arg, &buffer);
	if (ACPI_FAILURE(status)) {
		acpi_handle_err(handle, "WMAB: call failed.\n");
		return NULL;
	}

	return (union acpi_object *)buffer.pointer;
}

static void wmi_notify(u32 value, void *context)
{
	struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL };
	union acpi_object *obj;
	acpi_status status;
	long data = (long)context;

	pr_debug("event guid %li\n", data);
	status = wmi_get_event_data(value, &response);
	if (ACPI_FAILURE(status)) {
		pr_err("Bad event status 0x%x\n", status);
		return;
	}

	obj = (union acpi_object *)response.pointer;
	if (!obj)
		return;

	if (obj->type == ACPI_TYPE_INTEGER) {
		int eventcode = obj->integer.value;
		struct key_entry *key;

		key =
		    sparse_keymap_entry_from_scancode(wmi_input_dev, eventcode);
		if (key && key->type == KE_KEY)
			sparse_keymap_report_entry(wmi_input_dev, key, 1, true);
	}

	pr_debug("Type: %i    Eventcode: 0x%llx\n", obj->type,
		 obj->integer.value);
	kfree(response.pointer);
}

static void wmi_input_setup(void)
{
	acpi_status status;

	wmi_input_dev = input_allocate_device();
	if (wmi_input_dev) {
		wmi_input_dev->name = "LG WMI hotkeys";
		wmi_input_dev->phys = "wmi/input0";
		wmi_input_dev->id.bustype = BUS_HOST;

		if (sparse_keymap_setup(wmi_input_dev, wmi_keymap, NULL) ||
		    input_register_device(wmi_input_dev)) {
			pr_info("Cannot initialize input device");
			input_free_device(wmi_input_dev);
			return;
		}

		inited |= INIT_SPARSE_KEYMAP;
		status = wmi_install_notify_handler(WMI_EVENT_GUID0, wmi_notify,
						    (void *)0);
		if (ACPI_SUCCESS(status))
			inited |= INIT_INPUT_WMI_0;

		status = wmi_install_notify_handler(WMI_EVENT_GUID2, wmi_notify,
						    (void *)2);
		if (ACPI_SUCCESS(status))
			inited |= INIT_INPUT_WMI_2;
	} else {
		pr_info("Cannot allocate input device");
	}
}

static void acpi_notify(struct acpi_device *device, u32 event)
{
	struct key_entry *key;

	acpi_handle_debug(device->handle, "notify: %d\n", event);
	if (inited & INIT_SPARSE_KEYMAP) {
		key = sparse_keymap_entry_from_scancode(wmi_input_dev, 0x80);
		if (key && key->type == KE_KEY)
			sparse_keymap_report_entry(wmi_input_dev, key, 1, true);
	}
}

static ssize_t fan_mode_store(struct device *dev,
			      struct device_attribute *attr,
			      const char *buffer, size_t count)
{
	bool value;
	union acpi_object *r;
	u32 m;
	int ret;

	ret = kstrtobool(buffer, &value);
	if (ret)
		return ret;

	r = lg_wmab(WM_FAN_MODE, WM_GET, 0);
	if (!r)
		return -EIO;

	if (r->type != ACPI_TYPE_INTEGER) {
		kfree(r);
		return -EIO;
	}

	m = r->integer.value;
	kfree(r);
	r = lg_wmab(WM_FAN_MODE, WM_SET, (m & 0xffffff0f) | (value << 4));
	kfree(r);
	r = lg_wmab(WM_FAN_MODE, WM_SET, (m & 0xfffffff0) | value);
	kfree(r);

	return count;
}

static ssize_t fan_mode_show(struct device *dev,
			     struct device_attribute *attr, char *buffer)
{
	unsigned int status;
	union acpi_object *r;

	r = lg_wmab(WM_FAN_MODE, WM_GET, 0);
	if (!r)
		return -EIO;

	if (r->type != ACPI_TYPE_INTEGER) {
		kfree(r);
		return -EIO;
	}

	status = r->integer.value & 0x01;
	kfree(r);

	return snprintf(buffer, PAGE_SIZE, "%d\n", status);
}

static ssize_t usb_charge_store(struct device *dev,
				struct device_attribute *attr,
				const char *buffer, size_t count)
{
	bool value;
	union acpi_object *r;
	int ret;

	ret = kstrtobool(buffer, &value);
	if (ret)
		return ret;

	r = lg_wmbb(WMBB_USB_CHARGE, WM_SET, value);
	if (!r)
		return -EIO;

	kfree(r);
	return count;
}

static ssize_t usb_charge_show(struct device *dev,
			       struct device_attribute *attr, char *buffer)
{
	unsigned int status;
	union acpi_object *r;

	r = lg_wmbb(WMBB_USB_CHARGE, WM_GET, 0);
	if (!r)
		return -EIO;

	if (r->type != ACPI_TYPE_BUFFER) {
		kfree(r);
		return -EIO;
	}

	status = !!r->buffer.pointer[0x10];

	kfree(r);

	return snprintf(buffer, PAGE_SIZE, "%d\n", status);
}

static ssize_t reader_mode_store(struct device *dev,
				 struct device_attribute *attr,
				 const char *buffer, size_t count)
{
	bool value;
	union acpi_object *r;
	int ret;

	ret = kstrtobool(buffer, &value);
	if (ret)
		return ret;

	r = lg_wmab(WM_READER_MODE, WM_SET, value);
	if (!r)
		return -EIO;

	kfree(r);
	return count;
}

static ssize_t reader_mode_show(struct device *dev,
				struct device_attribute *attr, char *buffer)
{
	unsigned int status;
	union acpi_object *r;

	r = lg_wmab(WM_READER_MODE, WM_GET, 0);
	if (!r)
		return -EIO;

	if (r->type != ACPI_TYPE_INTEGER) {
		kfree(r);
		return -EIO;
	}

	status = !!r->integer.value;

	kfree(r);

	return snprintf(buffer, PAGE_SIZE, "%d\n", status);
}

static ssize_t fn_lock_store(struct device *dev,
			     struct device_attribute *attr,
			     const char *buffer, size_t count)
{
	bool value;
	union acpi_object *r;
	int ret;

	ret = kstrtobool(buffer, &value);
	if (ret)
		return ret;

	r = lg_wmab(WM_FN_LOCK, WM_SET, value);
	if (!r)
		return -EIO;

	kfree(r);
	return count;
}

static ssize_t fn_lock_show(struct device *dev,
			    struct device_attribute *attr, char *buffer)
{
	unsigned int status;
	union acpi_object *r;

	r = lg_wmab(WM_FN_LOCK, WM_GET, 0);
	if (!r)
		return -EIO;

	if (r->type != ACPI_TYPE_BUFFER) {
		kfree(r);
		return -EIO;
	}

	status = !!r->buffer.pointer[0];
	kfree(r);

	return snprintf(buffer, PAGE_SIZE, "%d\n", status);
}

static ssize_t battery_care_limit_store(struct device *dev,
					struct device_attribute *attr,
					const char *buffer, size_t count)
{
	unsigned long value;
	int ret;

	ret = kstrtoul(buffer, 10, &value);
	if (ret)
		return ret;

	if (value == 100 || value == 80) {
		union acpi_object *r;

		r = lg_wmab(WM_BATT_LIMIT, WM_SET, value);
		if (!r)
			return -EIO;

		kfree(r);
		return count;
	}

	return -EINVAL;
}

static ssize_t battery_care_limit_show(struct device *dev,
				       struct device_attribute *attr,
				       char *buffer)
{
	unsigned int status;
	union acpi_object *r;

	r = lg_wmab(WM_BATT_LIMIT, WM_GET, 0);
	if (!r)
		return -EIO;

	if (r->type != ACPI_TYPE_INTEGER) {
		kfree(r);
		return -EIO;
	}

	status = r->integer.value;
	kfree(r);
	if (status != 80 && status != 100)
		status = 0;

	return snprintf(buffer, PAGE_SIZE, "%d\n", status);
}

static DEVICE_ATTR_RW(fan_mode);
static DEVICE_ATTR_RW(usb_charge);
static DEVICE_ATTR_RW(reader_mode);
static DEVICE_ATTR_RW(fn_lock);
static DEVICE_ATTR_RW(battery_care_limit);

static struct attribute *dev_attributes[] = {
	&dev_attr_fan_mode.attr,
	&dev_attr_usb_charge.attr,
	&dev_attr_reader_mode.attr,
	&dev_attr_fn_lock.attr,
	&dev_attr_battery_care_limit.attr,
	NULL
};

static const struct attribute_group dev_attribute_group = {
	.attrs = dev_attributes,
};

static void tpad_led_set(struct led_classdev *cdev,
			 enum led_brightness brightness)
{
	union acpi_object *r;

	r = lg_wmab(WM_TLED, WM_SET, brightness > LED_OFF);
	kfree(r);
}

static enum led_brightness tpad_led_get(struct led_classdev *cdev)
{
	return ggov(GOV_TLED) > 0 ? LED_ON : LED_OFF;
}

static LED_DEVICE(tpad_led, 1);

static void kbd_backlight_set(struct led_classdev *cdev,
			      enum led_brightness brightness)
{
	u32 val;
	union acpi_object *r;

	val = 0x22;
	if (brightness <= LED_OFF)
		val = 0;
	if (brightness >= LED_FULL)
		val = 0x24;
	r = lg_wmab(WM_KEY_LIGHT, WM_SET, val);
	kfree(r);
}

static enum led_brightness kbd_backlight_get(struct led_classdev *cdev)
{
	union acpi_object *r;
	int val;

	r = lg_wmab(WM_KEY_LIGHT, WM_GET, 0);

	if (!r)
		return LED_OFF;

	if (r->type != ACPI_TYPE_BUFFER || r->buffer.pointer[1] != 0x05) {
		kfree(r);
		return LED_OFF;
	}

	switch (r->buffer.pointer[0] & 0x27) {
	case 0x24:
		val = LED_FULL;
		break;
	case 0x22:
		val = LED_HALF;
		break;
	default:
		val = LED_OFF;
	}

	kfree(r);

	return val;
}

static LED_DEVICE(kbd_backlight, 255);

static void wmi_input_destroy(void)
{
	if (inited & INIT_INPUT_WMI_2)
		wmi_remove_notify_handler(WMI_EVENT_GUID2);

	if (inited & INIT_INPUT_WMI_0)
		wmi_remove_notify_handler(WMI_EVENT_GUID0);

	if (inited & INIT_SPARSE_KEYMAP)
		input_unregister_device(wmi_input_dev);

	inited &= ~(INIT_INPUT_WMI_0 | INIT_INPUT_WMI_2 | INIT_SPARSE_KEYMAP);
}

static struct platform_driver pf_driver = {
	.driver = {
		   .name = PLATFORM_NAME,
	}
};

static int acpi_add(struct acpi_device *device)
{
	int ret;

	if (pf_device)
		return 0;

	ret = platform_driver_register(&pf_driver);
	if (ret)
		return ret;

	pf_device = platform_device_register_simple(PLATFORM_NAME,
						    PLATFORM_DEVID_NONE,
						    NULL, 0);
	if (IS_ERR(pf_device)) {
		ret = PTR_ERR(pf_device);
		pf_device = NULL;
		pr_err("unable to register platform device\n");
		goto out_platform_registered;
	}

	ret = sysfs_create_group(&pf_device->dev.kobj, &dev_attribute_group);
	if (ret)
		goto out_platform_device;

	if (!led_classdev_register(&pf_device->dev, &kbd_backlight))
		inited |= INIT_KBD_LED;

	if (!led_classdev_register(&pf_device->dev, &tpad_led))
		inited |= INIT_TPAD_LED;

	wmi_input_setup();

	return 0;

out_platform_device:
	platform_device_unregister(pf_device);
out_platform_registered:
	platform_driver_unregister(&pf_driver);
	return ret;
}

static int acpi_remove(struct acpi_device *device)
{
	sysfs_remove_group(&pf_device->dev.kobj, &dev_attribute_group);
	if (inited & INIT_KBD_LED)
		led_classdev_unregister(&kbd_backlight);

	if (inited & INIT_TPAD_LED)
		led_classdev_unregister(&tpad_led);

	wmi_input_destroy();
	platform_device_unregister(pf_device);
	pf_device = NULL;
	platform_driver_unregister(&pf_driver);

	return 0;
}

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

static struct acpi_driver acpi_driver = {
	.name = "LG Gram Laptop Support",
	.class = "lg-laptop",
	.ids = device_ids,
	.ops = {
		.add = acpi_add,
		.remove = acpi_remove,
		.notify = acpi_notify,
		},
	.owner = THIS_MODULE,
};

static int __init acpi_init(void)
{
	int result;

	result = acpi_bus_register_driver(&acpi_driver);
	if (result < 0) {
		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error registering driver\n"));
		return -ENODEV;
	}

	return 0;
}

static void __exit acpi_exit(void)
{
	acpi_bus_unregister_driver(&acpi_driver);
}

module_init(acpi_init);
module_exit(acpi_exit);
