/*
 *  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>
 *
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or (at
 *  your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful, but
 *  WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with this program; if not, write to the Free Software Foundation, Inc.,
 *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
 *
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/types.h>
#include <acpi/acpi.h>
#include <acpi/actypes.h>
#include <acpi/acpi_bus.h>
#include <acpi/acpi_drivers.h>
#include <linux/platform_device.h>

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

#define TC1100_INSTANCE_WIRELESS		1
#define TC1100_INSTANCE_JOGDIAL		2

#define TC1100_LOGPREFIX "tc1100-wmi: "
#define TC1100_INFO KERN_INFO TC1100_LOGPREFIX

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 int tc1100_probe(struct platform_device *device);
static int tc1100_remove(struct platform_device *device);
static int tc1100_suspend(struct platform_device *device, pm_message_t state);
static int tc1100_resume(struct platform_device *device);

static struct platform_driver tc1100_driver = {
	.driver = {
		.name = "tc1100-wmi",
		.owner = THIS_MODULE,
	},
	.probe = tc1100_probe,
	.remove = tc1100_remove,
	.suspend = tc1100_suspend,
	.resume = tc1100_resume,
};

static struct platform_device *tc1100_device;

struct tc1100_data {
	u32 wireless;
	u32 jogdial;
};

static struct tc1100_data suspend_data;

/* --------------------------------------------------------------------------
				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_BUFFER &&
		obj->buffer.length == sizeof(u32)) {
		tmp = *((u32 *) obj->buffer.pointer);
	} else {
		tmp = 0;
	}

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

	switch (instance) {
	case TC1100_INSTANCE_WIRELESS:
		*out = (tmp == 3) ? 1 : 0;
		return 0;
	case TC1100_INSTANCE_JOGDIAL:
		*out = (tmp == 1) ? 1 : 0;
		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_IWUGO | 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 void remove_fs(void)
{
	device_remove_file(&tc1100_device->dev, &dev_attr_wireless);
	device_remove_file(&tc1100_device->dev, &dev_attr_jogdial);
}

static int add_fs(void)
{
	int ret;

	ret = device_create_file(&tc1100_device->dev, &dev_attr_wireless);
	if (ret)
		goto add_sysfs_error;

	ret = device_create_file(&tc1100_device->dev, &dev_attr_jogdial);
	if (ret)
		goto add_sysfs_error;

	return ret;

add_sysfs_error:
	remove_fs();
	return ret;
}

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

static int tc1100_probe(struct platform_device *device)
{
	int result = 0;

	result = add_fs();
	return result;
}


static int tc1100_remove(struct platform_device *device)
{
	remove_fs();
	return 0;
}

static int tc1100_suspend(struct platform_device *dev, pm_message_t state)
{
	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 ret;
}

static int tc1100_resume(struct platform_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 ret;
}

static int __init tc1100_init(void)
{
	int result = 0;

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

	result = platform_driver_register(&tc1100_driver);
	if (result)
		return result;

	tc1100_device = platform_device_alloc("tc1100-wmi", -1);
	platform_device_add(tc1100_device);

	printk(TC1100_INFO "HP Compaq TC1100 Tablet WMI Extras loaded\n");

	return result;
}

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

	printk(TC1100_INFO "HP Compaq TC1100 Tablet WMI Extras unloaded\n");
}

module_init(tc1100_init);
module_exit(tc1100_exit);
