/*
 *  quickstart.c - ACPI Direct App Launch driver
 *
 *
 *  Copyright (C) 2007-2010 Angelo Arrifano <miknix@gmail.com>
 *
 *  Information gathered from disassembled dsdt and from here:
 *  <http://www.microsoft.com/whdc/system/platform/firmware/DirAppLaunch.mspx>
 *
 *  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
 *
 */

#define QUICKSTART_VERSION "1.04"

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

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

MODULE_AUTHOR("Angelo Arrifano");
MODULE_DESCRIPTION("ACPI Direct App Launch driver");
MODULE_LICENSE("GPL");

#define QUICKSTART_ACPI_DEVICE_NAME	"quickstart"
#define QUICKSTART_ACPI_CLASS		"quickstart"
#define QUICKSTART_ACPI_HID		"PNP0C32"

#define QUICKSTART_PF_DRIVER_NAME	"quickstart"
#define QUICKSTART_PF_DEVICE_NAME	"quickstart"

/*
 * There will be two events:
 * 0x02 - A hot button was pressed while device was off/sleeping.
 * 0x80 - A hot button was pressed while device was up.
 */
#define QUICKSTART_EVENT_WAKE		0x02
#define QUICKSTART_EVENT_RUNTIME	0x80

struct quickstart_button {
	char *name;
	unsigned int id;
	struct list_head list;
};

struct quickstart_acpi {
	struct acpi_device *device;
	struct quickstart_button *button;
};

static LIST_HEAD(buttons);
static struct quickstart_button *pressed;

static struct input_dev *quickstart_input;

/* Platform driver functions */
static ssize_t buttons_show(struct device *dev, struct device_attribute *attr,
			    char *buf)
{
	int count = 0;
	struct quickstart_button *b;

	if (list_empty(&buttons))
		return snprintf(buf, PAGE_SIZE, "none");

	list_for_each_entry(b, &buttons, list) {
		count += snprintf(buf + count, PAGE_SIZE - count, "%u\t%s\n",
							b->id, b->name);

		if (count >= PAGE_SIZE) {
			count = PAGE_SIZE;
			break;
		}
	}

	return count;
}

static ssize_t pressed_button_show(struct device *dev,
				   struct device_attribute *attr, char *buf)
{
	return scnprintf(buf, PAGE_SIZE, "%s\n",
					(pressed ? pressed->name : "none"));
}


static ssize_t pressed_button_store(struct device *dev,
				    struct device_attribute *attr,
				    const char *buf, size_t count)
{
	if (count < 2)
		return -EINVAL;

	if (strncasecmp(buf, "none", 4) != 0)
		return -EINVAL;

	pressed = NULL;
	return count;
}

/* Helper functions */
static struct quickstart_button *quickstart_buttons_add(void)
{
	struct quickstart_button *b;

	b = kzalloc(sizeof(*b), GFP_KERNEL);
	if (!b)
		return NULL;

	list_add_tail(&b->list, &buttons);

	return b;
}

static void quickstart_button_del(struct quickstart_button *data)
{
	if (!data)
		return;

	list_del(&data->list);
	kfree(data->name);
	kfree(data);
}

static void quickstart_buttons_free(void)
{
	struct quickstart_button *b, *n;

	list_for_each_entry_safe(b, n, &buttons, list)
		quickstart_button_del(b);
}

/* ACPI Driver functions */
static void quickstart_acpi_notify(acpi_handle handle, u32 event, void *data)
{
	struct quickstart_acpi *quickstart = data;

	if (!quickstart)
		return;

	switch (event) {
	case QUICKSTART_EVENT_WAKE:
		pressed = quickstart->button;
		break;
	case QUICKSTART_EVENT_RUNTIME:
		input_report_key(quickstart_input, quickstart->button->id, 1);
		input_sync(quickstart_input);
		input_report_key(quickstart_input, quickstart->button->id, 0);
		input_sync(quickstart_input);
		break;
	default:
		pr_err("Unexpected ACPI event notify (%u)\n", event);
		break;
	}
}

static int quickstart_acpi_ghid(struct quickstart_acpi *quickstart)
{
	acpi_status status;
	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
	int ret = 0;

	/*
	 * This returns a buffer telling the button usage ID,
	 * and triggers pending notify events (The ones before booting).
	 */
	status = acpi_evaluate_object(quickstart->device->handle, "GHID", NULL,
								&buffer);
	if (ACPI_FAILURE(status)) {
		pr_err("%s GHID method failed\n", quickstart->button->name);
		return -EINVAL;
	}

	/*
	 * <<The GHID method can return a BYTE, WORD, or DWORD.
	 * The value must be encoded in little-endian byte
	 * order (least significant byte first).>>
	 */
	switch (buffer.length) {
	case 1:
		quickstart->button->id = *(uint8_t *)buffer.pointer;
		break;
	case 2:
		quickstart->button->id = *(uint16_t *)buffer.pointer;
		break;
	case 4:
		quickstart->button->id = *(uint32_t *)buffer.pointer;
		break;
	case 8:
		quickstart->button->id = *(uint64_t *)buffer.pointer;
		break;
	default:
		pr_err("%s GHID method returned buffer of unexpected length %lu\n",
				quickstart->button->name,
				(unsigned long)buffer.length);
		ret = -EINVAL;
		break;
	}

	kfree(buffer.pointer);

	return ret;
}

static int quickstart_acpi_config(struct quickstart_acpi *quickstart)
{
	char *bid = acpi_device_bid(quickstart->device);
	char *name;

	name = kmalloc(strlen(bid) + 1, GFP_KERNEL);
	if (!name)
		return -ENOMEM;

	/* Add new button to list */
	quickstart->button = quickstart_buttons_add();
	if (!quickstart->button) {
		kfree(name);
		return -ENOMEM;
	}

	quickstart->button->name = name;
	strcpy(quickstart->button->name, bid);

	return 0;
}

static int quickstart_acpi_add(struct acpi_device *device)
{
	int ret;
	acpi_status status;
	struct quickstart_acpi *quickstart;

	if (!device)
		return -EINVAL;

	quickstart = kzalloc(sizeof(*quickstart), GFP_KERNEL);
	if (!quickstart)
		return -ENOMEM;

	quickstart->device = device;

	strcpy(acpi_device_name(device), QUICKSTART_ACPI_DEVICE_NAME);
	strcpy(acpi_device_class(device), QUICKSTART_ACPI_CLASS);
	device->driver_data = quickstart;

	/* Add button to list and initialize some stuff */
	ret = quickstart_acpi_config(quickstart);
	if (ret < 0)
		goto fail_config;

	status = acpi_install_notify_handler(device->handle, ACPI_ALL_NOTIFY,
						quickstart_acpi_notify,
						quickstart);
	if (ACPI_FAILURE(status)) {
		pr_err("Notify handler install error\n");
		ret = -ENODEV;
		goto fail_installnotify;
	}

	ret = quickstart_acpi_ghid(quickstart);
	if (ret < 0)
		goto fail_ghid;

	return 0;

fail_ghid:
	acpi_remove_notify_handler(device->handle, ACPI_ALL_NOTIFY,
						quickstart_acpi_notify);

fail_installnotify:
	quickstart_button_del(quickstart->button);

fail_config:

	kfree(quickstart);

	return ret;
}

static int quickstart_acpi_remove(struct acpi_device *device)
{
	acpi_status status;
	struct quickstart_acpi *quickstart;

	if (!device)
		return -EINVAL;

	quickstart = acpi_driver_data(device);
	if (!quickstart)
		return -EINVAL;

	status = acpi_remove_notify_handler(device->handle, ACPI_ALL_NOTIFY,
						quickstart_acpi_notify);
	if (ACPI_FAILURE(status))
		pr_err("Error removing notify handler\n");

	kfree(quickstart);

	return 0;
}

/* Platform driver structs */
static DEVICE_ATTR_RW(pressed_button);
static DEVICE_ATTR_RO(buttons);
static struct platform_device *pf_device;
static struct platform_driver pf_driver = {
	.driver = {
		.name = QUICKSTART_PF_DRIVER_NAME,
		.owner = THIS_MODULE,
	}
};

static const struct acpi_device_id quickstart_device_ids[] = {
	{QUICKSTART_ACPI_HID, 0},
	{"", 0},
};

static struct acpi_driver quickstart_acpi_driver = {
	.name = "quickstart",
	.class = QUICKSTART_ACPI_CLASS,
	.ids = quickstart_device_ids,
	.ops = {
			.add = quickstart_acpi_add,
			.remove = quickstart_acpi_remove,
		},
};

/* Module functions */
static void quickstart_exit(void)
{
	input_unregister_device(quickstart_input);

	device_remove_file(&pf_device->dev, &dev_attr_pressed_button);
	device_remove_file(&pf_device->dev, &dev_attr_buttons);

	platform_device_unregister(pf_device);

	platform_driver_unregister(&pf_driver);

	acpi_bus_unregister_driver(&quickstart_acpi_driver);

	quickstart_buttons_free();
}

static int __init quickstart_init_input(void)
{
	struct quickstart_button *b;
	int ret;

	quickstart_input = input_allocate_device();

	if (!quickstart_input)
		return -ENOMEM;

	quickstart_input->name = "Quickstart ACPI Buttons";
	quickstart_input->id.bustype = BUS_HOST;

	list_for_each_entry(b, &buttons, list) {
		set_bit(EV_KEY, quickstart_input->evbit);
		set_bit(b->id, quickstart_input->keybit);
	}

	ret = input_register_device(quickstart_input);
	if (ret) {
		input_free_device(quickstart_input);
		return ret;
	}

	return 0;
}

static int __init quickstart_init(void)
{
	int ret;

	/* ACPI driver register */
	ret = acpi_bus_register_driver(&quickstart_acpi_driver);
	if (ret)
		return ret;

	/* If existing bus with no devices */
	if (list_empty(&buttons)) {
		ret = -ENODEV;
		goto fail_pfdrv_reg;
	}

	/* Platform driver register */
	ret = platform_driver_register(&pf_driver);
	if (ret)
		goto fail_pfdrv_reg;

	/* Platform device register */
	pf_device = platform_device_alloc(QUICKSTART_PF_DEVICE_NAME, -1);
	if (!pf_device) {
		ret = -ENOMEM;
		goto fail_pfdev_alloc;
	}
	ret = platform_device_add(pf_device);
	if (ret)
		goto fail_pfdev_add;

	/* Create device sysfs file */
	ret = device_create_file(&pf_device->dev, &dev_attr_pressed_button);
	if (ret)
		goto fail_dev_file;

	ret = device_create_file(&pf_device->dev, &dev_attr_buttons);
	if (ret)
		goto fail_dev_file2;

	/* Input device */
	ret = quickstart_init_input();
	if (ret)
		goto fail_input;

	pr_info("ACPI Direct App Launch ver %s\n", QUICKSTART_VERSION);

	return 0;
fail_input:
	device_remove_file(&pf_device->dev, &dev_attr_buttons);

fail_dev_file2:
	device_remove_file(&pf_device->dev, &dev_attr_pressed_button);

fail_dev_file:
	platform_device_del(pf_device);

fail_pfdev_add:
	platform_device_put(pf_device);

fail_pfdev_alloc:
	platform_driver_unregister(&pf_driver);

fail_pfdrv_reg:
	acpi_bus_unregister_driver(&quickstart_acpi_driver);

	return ret;
}

module_init(quickstart_init);
module_exit(quickstart_exit);
