// SPDX-License-Identifier: GPL-2.0-or-later
/*
 *  HP Compaq TC1100 Tablet WMI Extras Driver
 *
 *  Copyright (C) 2007 Carlos Corbacho <carlos@strangeworlds.co.uk>
 *  Copyright (C) 2004 Jamey Hicks <jamey.hicks@hp.com>
 *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
 *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
 */

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/acpi.h>
#include <linux/platform_device.h>

#define GUID "C364AC71-36DB-495A-8494-B439D472A505"

#define TC1100_INSTANCE_WIRELESS		1
#define TC1100_INSTANCE_JOGDIAL		2

MODULE_AUTHOR("Jamey Hicks, Carlos Corbacho");
MODULE_DESCRIPTION("HP Compaq TC1100 Tablet WMI Extras");
MODULE_LICENSE("GPL");
MODULE_ALIAS("wmi:C364AC71-36DB-495A-8494-B439D472A505");

static struct platform_device *tc1100_device;

struct tc1100_data {
	u32 wireless;
	u32 jogdial;
};

#ifdef CONFIG_PM
static struct tc1100_data suspend_data;
#endif

/* --------------------------------------------------------------------------
				Device Management
   -------------------------------------------------------------------------- */

static int get_state(u32 *out, u8 instance)
{
	u32 tmp;
	acpi_status status;
	struct acpi_buffer result = { ACPI_ALLOCATE_BUFFER, NULL };
	union acpi_object *obj;

	if (!out)
		return -EINVAL;

	if (instance > 2)
		return -ENODEV;

	status = wmi_query_block(GUID, instance, &result);
	if (ACPI_FAILURE(status))
		return -ENODEV;

	obj = (union acpi_object *) result.pointer;
	if (obj && obj->type == ACPI_TYPE_INTEGER) {
		tmp = obj->integer.value;
	} else {
		tmp = 0;
	}

	if (result.length > 0)
		kfree(result.pointer);

	switch (instance) {
	case TC1100_INSTANCE_WIRELESS:
		*out = (tmp == 3) ? 1 : 0;
		return 0;
	case TC1100_INSTANCE_JOGDIAL:
		*out = (tmp == 1) ? 0 : 1;
		return 0;
	default:
		return -ENODEV;
	}
}

static int set_state(u32 *in, u8 instance)
{
	u32 value;
	acpi_status status;
	struct acpi_buffer input;

	if (!in)
		return -EINVAL;

	if (instance > 2)
		return -ENODEV;

	switch (instance) {
	case TC1100_INSTANCE_WIRELESS:
		value = (*in) ? 1 : 2;
		break;
	case TC1100_INSTANCE_JOGDIAL:
		value = (*in) ? 0 : 1;
		break;
	default:
		return -ENODEV;
	}

	input.length = sizeof(u32);
	input.pointer = &value;

	status = wmi_set_block(GUID, instance, &input);
	if (ACPI_FAILURE(status))
		return -ENODEV;

	return 0;
}

/* --------------------------------------------------------------------------
				FS Interface (/sys)
   -------------------------------------------------------------------------- */

/*
 * Read/ write bool sysfs macro
 */
#define show_set_bool(value, instance) \
static ssize_t \
show_bool_##value(struct device *dev, struct device_attribute *attr, \
	char *buf) \
{ \
	u32 result; \
	acpi_status status = get_state(&result, instance); \
	if (ACPI_SUCCESS(status)) \
		return sprintf(buf, "%d\n", result); \
	return sprintf(buf, "Read error\n"); \
} \
\
static ssize_t \
set_bool_##value(struct device *dev, struct device_attribute *attr, \
	const char *buf, size_t count) \
{ \
	u32 tmp = simple_strtoul(buf, NULL, 10); \
	acpi_status status = set_state(&tmp, instance); \
		if (ACPI_FAILURE(status)) \
			return -EINVAL; \
	return count; \
} \
static DEVICE_ATTR(value, S_IRUGO | S_IWUSR, \
	show_bool_##value, set_bool_##value);

show_set_bool(wireless, TC1100_INSTANCE_WIRELESS);
show_set_bool(jogdial, TC1100_INSTANCE_JOGDIAL);

static struct attribute *tc1100_attributes[] = {
	&dev_attr_wireless.attr,
	&dev_attr_jogdial.attr,
	NULL
};

static const struct attribute_group tc1100_attribute_group = {
	.attrs	= tc1100_attributes,
};

/* --------------------------------------------------------------------------
				Driver Model
   -------------------------------------------------------------------------- */

static int __init tc1100_probe(struct platform_device *device)
{
	return sysfs_create_group(&device->dev.kobj, &tc1100_attribute_group);
}


static void tc1100_remove(struct platform_device *device)
{
	sysfs_remove_group(&device->dev.kobj, &tc1100_attribute_group);
}

#ifdef CONFIG_PM
static int tc1100_suspend(struct device *dev)
{
	int ret;

	ret = get_state(&suspend_data.wireless, TC1100_INSTANCE_WIRELESS);
	if (ret)
		return ret;

	ret = get_state(&suspend_data.jogdial, TC1100_INSTANCE_JOGDIAL);
	if (ret)
		return ret;

	return 0;
}

static int tc1100_resume(struct device *dev)
{
	int ret;

	ret = set_state(&suspend_data.wireless, TC1100_INSTANCE_WIRELESS);
	if (ret)
		return ret;

	ret = set_state(&suspend_data.jogdial, TC1100_INSTANCE_JOGDIAL);
	if (ret)
		return ret;

	return 0;
}

static const struct dev_pm_ops tc1100_pm_ops = {
	.suspend	= tc1100_suspend,
	.resume		= tc1100_resume,
	.freeze		= tc1100_suspend,
	.restore	= tc1100_resume,
};
#endif

static struct platform_driver tc1100_driver = {
	.driver = {
		.name = "tc1100-wmi",
#ifdef CONFIG_PM
		.pm = &tc1100_pm_ops,
#endif
	},
	.remove_new = tc1100_remove,
};

static int __init tc1100_init(void)
{
	int error;

	if (!wmi_has_guid(GUID))
		return -ENODEV;

	tc1100_device = platform_device_alloc("tc1100-wmi", PLATFORM_DEVID_NONE);
	if (!tc1100_device)
		return -ENOMEM;

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

	error = platform_driver_probe(&tc1100_driver, tc1100_probe);
	if (error)
		goto err_device_del;

	pr_info("HP Compaq TC1100 Tablet WMI Extras loaded\n");
	return 0;

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

static void __exit tc1100_exit(void)
{
	platform_device_unregister(tc1100_device);
	platform_driver_unregister(&tc1100_driver);
}

module_init(tc1100_init);
module_exit(tc1100_exit);
