/*
 * ACPI driver for Topstar notebooks (hotkeys support only)
 *
 * Copyright (c) 2009 Herton Ronaldo Krzesinski <herton@mandriva.com.br>
 *
 * Implementation inspired by existing x86 platform drivers, in special
 * asus/eepc/fujitsu-laptop, thanks to their authors
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

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

#define ACPI_TOPSTAR_CLASS "topstar"

struct topstar_hkey {
	struct input_dev *inputdev;
};

struct tps_key_entry {
	u8 code;
	u16 keycode;
};

static struct tps_key_entry topstar_keymap[] = {
	{ 0x80, KEY_BRIGHTNESSUP },
	{ 0x81, KEY_BRIGHTNESSDOWN },
	{ 0x83, KEY_VOLUMEUP },
	{ 0x84, KEY_VOLUMEDOWN },
	{ 0x85, KEY_MUTE },
	{ 0x86, KEY_SWITCHVIDEOMODE },
	{ 0x87, KEY_F13 }, /* touchpad enable/disable key */
	{ 0x88, KEY_WLAN },
	{ 0x8a, KEY_WWW },
	{ 0x8b, KEY_MAIL },
	{ 0x8c, KEY_MEDIA },
	{ 0x96, KEY_F14 }, /* G key? */
	{ }
};

static struct tps_key_entry *tps_get_key_by_scancode(int code)
{
	struct tps_key_entry *key;

	for (key = topstar_keymap; key->code; key++)
		if (code == key->code)
			return key;

	return NULL;
}

static struct tps_key_entry *tps_get_key_by_keycode(int code)
{
	struct tps_key_entry *key;

	for (key = topstar_keymap; key->code; key++)
		if (code == key->keycode)
			return key;

	return NULL;
}

static void acpi_topstar_notify(struct acpi_device *device, u32 event)
{
	struct tps_key_entry *key;
	static bool dup_evnt[2];
	bool *dup;
	struct topstar_hkey *hkey = acpi_driver_data(device);

	/* 0x83 and 0x84 key events comes duplicated... */
	if (event == 0x83 || event == 0x84) {
		dup = &dup_evnt[event - 0x83];
		if (*dup) {
			*dup = false;
			return;
		}
		*dup = true;
	}

	/*
	 * 'G key' generate two event codes, convert to only
	 * one event/key code for now (3G switch?)
	 */
	if (event == 0x97)
		event = 0x96;

	key = tps_get_key_by_scancode(event);
	if (key) {
		input_report_key(hkey->inputdev, key->keycode, 1);
		input_sync(hkey->inputdev);
		input_report_key(hkey->inputdev, key->keycode, 0);
		input_sync(hkey->inputdev);
		return;
	}

	/* Known non hotkey events don't handled or that we don't care yet */
	if (event == 0x8e || event == 0x8f || event == 0x90)
		return;

	pr_info("unknown event = 0x%02x\n", event);
}

static int acpi_topstar_fncx_switch(struct acpi_device *device, bool state)
{
	acpi_status status;
	union acpi_object fncx_params[1] = {
		{ .type = ACPI_TYPE_INTEGER }
	};
	struct acpi_object_list fncx_arg_list = { 1, &fncx_params[0] };

	fncx_params[0].integer.value = state ? 0x86 : 0x87;
	status = acpi_evaluate_object(device->handle, "FNCX", &fncx_arg_list, NULL);
	if (ACPI_FAILURE(status)) {
		pr_err("Unable to switch FNCX notifications\n");
		return -ENODEV;
	}

	return 0;
}

static int topstar_getkeycode(struct input_dev *dev, int scancode, int *keycode)
{
	struct tps_key_entry *key = tps_get_key_by_scancode(scancode);

	if (!key)
		return -EINVAL;

	*keycode = key->keycode;
	return 0;
}

static int topstar_setkeycode(struct input_dev *dev, int scancode, int keycode)
{
	struct tps_key_entry *key;
	int old_keycode;

	if (keycode < 0 || keycode > KEY_MAX)
		return -EINVAL;

	key = tps_get_key_by_scancode(scancode);

	if (!key)
		return -EINVAL;

	old_keycode = key->keycode;
	key->keycode = keycode;
	set_bit(keycode, dev->keybit);
	if (!tps_get_key_by_keycode(old_keycode))
		clear_bit(old_keycode, dev->keybit);
	return 0;
}

static int acpi_topstar_init_hkey(struct topstar_hkey *hkey)
{
	struct tps_key_entry *key;

	hkey->inputdev = input_allocate_device();
	if (!hkey->inputdev) {
		pr_err("Unable to allocate input device\n");
		return -ENODEV;
	}
	hkey->inputdev->name = "Topstar Laptop extra buttons";
	hkey->inputdev->phys = "topstar/input0";
	hkey->inputdev->id.bustype = BUS_HOST;
	hkey->inputdev->getkeycode = topstar_getkeycode;
	hkey->inputdev->setkeycode = topstar_setkeycode;
	for (key = topstar_keymap; key->code; key++) {
		set_bit(EV_KEY, hkey->inputdev->evbit);
		set_bit(key->keycode, hkey->inputdev->keybit);
	}
	if (input_register_device(hkey->inputdev)) {
		pr_err("Unable to register input device\n");
		input_free_device(hkey->inputdev);
		return -ENODEV;
	}

	return 0;
}

static int acpi_topstar_add(struct acpi_device *device)
{
	struct topstar_hkey *tps_hkey;

	tps_hkey = kzalloc(sizeof(struct topstar_hkey), GFP_KERNEL);
	if (!tps_hkey)
		return -ENOMEM;

	strcpy(acpi_device_name(device), "Topstar TPSACPI");
	strcpy(acpi_device_class(device), ACPI_TOPSTAR_CLASS);

	if (acpi_topstar_fncx_switch(device, true))
		goto add_err;

	if (acpi_topstar_init_hkey(tps_hkey))
		goto add_err;

	device->driver_data = tps_hkey;
	return 0;

add_err:
	kfree(tps_hkey);
	return -ENODEV;
}

static int acpi_topstar_remove(struct acpi_device *device, int type)
{
	struct topstar_hkey *tps_hkey = acpi_driver_data(device);

	acpi_topstar_fncx_switch(device, false);

	input_unregister_device(tps_hkey->inputdev);
	kfree(tps_hkey);

	return 0;
}

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

static struct acpi_driver acpi_topstar_driver = {
	.name = "Topstar laptop ACPI driver",
	.class = ACPI_TOPSTAR_CLASS,
	.ids = topstar_device_ids,
	.ops = {
		.add = acpi_topstar_add,
		.remove = acpi_topstar_remove,
		.notify = acpi_topstar_notify,
	},
};

static int __init topstar_laptop_init(void)
{
	int ret;

	ret = acpi_bus_register_driver(&acpi_topstar_driver);
	if (ret < 0)
		return ret;

	printk(KERN_INFO "Topstar Laptop ACPI extras driver loaded\n");

	return 0;
}

static void __exit topstar_laptop_exit(void)
{
	acpi_bus_unregister_driver(&acpi_topstar_driver);
}

module_init(topstar_laptop_init);
module_exit(topstar_laptop_exit);

MODULE_AUTHOR("Herton Ronaldo Krzesinski");
MODULE_DESCRIPTION("Topstar Laptop ACPI Extras driver");
MODULE_LICENSE("GPL");
