/*
 *  hotkey.c - ACPI Hotkey Driver ($Revision: 0.2 $)
 *
 *  Copyright (C) 2004 Luming Yu <luming.yu@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 <linux/proc_fs.h>
#include <linux/sched.h>
#include <linux/kmod.h>
#include <linux/seq_file.h>
#include <acpi/acpi_drivers.h>
#include <acpi/acpi_bus.h>
#include <asm/uaccess.h>

#define HOTKEY_ACPI_VERSION "0.1"

#define HOTKEY_PROC "hotkey"
#define HOTKEY_EV_CONFIG    "event_config"
#define HOTKEY_PL_CONFIG    "poll_config"
#define HOTKEY_ACTION   "action"
#define HOTKEY_INFO "info"

#define ACPI_HOTK_NAME          "Generic Hotkey Driver"
#define ACPI_HOTK_CLASS         "Hotkey"
#define ACPI_HOTK_DEVICE_NAME   "Hotkey"
#define ACPI_HOTK_HID           "Unknown?"
#define ACPI_HOTKEY_COMPONENT   0x20000000

#define ACPI_HOTKEY_EVENT   0x1
#define ACPI_HOTKEY_POLLING 0x2
#define ACPI_UNDEFINED_EVENT    0xf

#define RESULT_STR_LEN	    80

#define ACTION_METHOD	0
#define POLL_METHOD	1

#define IS_EVENT(e)       	((e) <= 10000 && (e) >0)
#define IS_POLL(e)      	((e) > 10000)
#define IS_OTHERS(e)		((e)<=0 || (e)>=20000)
#define _COMPONENT              ACPI_HOTKEY_COMPONENT
ACPI_MODULE_NAME("acpi_hotkey")

MODULE_AUTHOR("luming.yu@intel.com");
MODULE_DESCRIPTION(ACPI_HOTK_NAME);
MODULE_LICENSE("GPL");

/*  standardized internal hotkey number/event  */
enum {
	/* Video Extension event */
	HK_EVENT_CYCLE_OUTPUT_DEVICE = 0x80,
	HK_EVENT_OUTPUT_DEVICE_STATUS_CHANGE,
	HK_EVENT_CYCLE_DISPLAY_OUTPUT,
	HK_EVENT_NEXT_DISPLAY_OUTPUT,
	HK_EVENT_PREVIOUS_DISPLAY_OUTPUT,
	HK_EVENT_CYCLE_BRIGHTNESS,
	HK_EVENT_INCREASE_BRIGHTNESS,
	HK_EVENT_DECREASE_BRIGHTNESS,
	HK_EVENT_ZERO_BRIGHTNESS,
	HK_EVENT_DISPLAY_DEVICE_OFF,

	/* Snd Card event */
	HK_EVENT_VOLUME_MUTE,
	HK_EVENT_VOLUME_INCLREASE,
	HK_EVENT_VOLUME_DECREASE,

	/* running state control */
	HK_EVENT_ENTERRING_S3,
	HK_EVENT_ENTERRING_S4,
	HK_EVENT_ENTERRING_S5,
};

/*  procdir we use */
static struct proc_dir_entry *hotkey_proc_dir;
static struct proc_dir_entry *hotkey_config;
static struct proc_dir_entry *hotkey_poll_config;
static struct proc_dir_entry *hotkey_action;
static struct proc_dir_entry *hotkey_info;

/* linkage for all type of hotkey */
struct acpi_hotkey_link {
	struct list_head entries;
	int hotkey_type;	/* event or polling based hotkey  */
	int hotkey_standard_num;	/* standardized hotkey(event) number */
};

/* event based hotkey */
struct acpi_event_hotkey {
	struct acpi_hotkey_link hotkey_link;
	int flag;
	acpi_handle bus_handle;	/* bus to install notify handler */
	int external_hotkey_num;	/* external hotkey/event number */
	acpi_handle action_handle;	/* acpi handle attached aml action method */
	char *action_method;	/* action method */
};

/*
 * There are two ways to poll status
 * 1. directy call read_xxx method, without any arguments passed in
 * 2. call write_xxx method, with arguments passed in, you need
 * the result is saved in acpi_polling_hotkey.poll_result.
 * anthoer read command through polling interface.
 *
 */

/* polling based hotkey */
struct acpi_polling_hotkey {
	struct acpi_hotkey_link hotkey_link;
	int flag;
	acpi_handle poll_handle;	/* acpi handle attached polling method */
	char *poll_method;	/* poll method */
	acpi_handle action_handle;	/* acpi handle attached action method */
	char *action_method;	/* action method */
	union acpi_object *poll_result;	/* polling_result */
	struct proc_dir_entry *proc;
};

/* hotkey object union */
union acpi_hotkey {
	struct list_head entries;
	struct acpi_hotkey_link link;
	struct acpi_event_hotkey event_hotkey;
	struct acpi_polling_hotkey poll_hotkey;
};

/* hotkey object list */
struct acpi_hotkey_list {
	struct list_head *entries;
	int count;
};

static int auto_hotkey_add(struct acpi_device *device);
static int auto_hotkey_remove(struct acpi_device *device, int type);

static struct acpi_driver hotkey_driver = {
	.name = ACPI_HOTK_NAME,
	.class = ACPI_HOTK_CLASS,
	.ids = ACPI_HOTK_HID,
	.ops = {
		.add = auto_hotkey_add,
		.remove = auto_hotkey_remove,
		},
};

static void free_hotkey_device(union acpi_hotkey *key);
static void free_hotkey_buffer(union acpi_hotkey *key);
static void free_poll_hotkey_buffer(union acpi_hotkey *key);
static int hotkey_open_config(struct inode *inode, struct file *file);
static int hotkey_poll_open_config(struct inode *inode, struct file *file);
static ssize_t hotkey_write_config(struct file *file,
				   const char __user * buffer,
				   size_t count, loff_t * data);
static int hotkey_info_open_fs(struct inode *inode, struct file *file);
static int hotkey_action_open_fs(struct inode *inode, struct file *file);
static ssize_t hotkey_execute_aml_method(struct file *file,
					 const char __user * buffer,
					 size_t count, loff_t * data);
static int hotkey_config_seq_show(struct seq_file *seq, void *offset);
static int hotkey_poll_config_seq_show(struct seq_file *seq, void *offset);
static int hotkey_polling_open_fs(struct inode *inode, struct file *file);
static union acpi_hotkey *get_hotkey_by_event(struct
			      acpi_hotkey_list
			      *hotkey_list, int event);

/* event based config */
static struct file_operations hotkey_config_fops = {
	.open = hotkey_open_config,
	.read = seq_read,
	.write = hotkey_write_config,
	.llseek = seq_lseek,
	.release = single_release,
};

/* polling based config */
static struct file_operations hotkey_poll_config_fops = {
	.open = hotkey_poll_open_config,
	.read = seq_read,
	.write = hotkey_write_config,
	.llseek = seq_lseek,
	.release = single_release,
};

/* hotkey driver info */
static struct file_operations hotkey_info_fops = {
	.open = hotkey_info_open_fs,
	.read = seq_read,
	.llseek = seq_lseek,
	.release = single_release,
};

/* action */
static struct file_operations hotkey_action_fops = {
	.open = hotkey_action_open_fs,
	.read = seq_read,
	.write = hotkey_execute_aml_method,
	.llseek = seq_lseek,
	.release = single_release,
};

/* polling results */
static struct file_operations hotkey_polling_fops = {
	.open = hotkey_polling_open_fs,
	.read = seq_read,
	.llseek = seq_lseek,
	.release = single_release,
};

struct acpi_hotkey_list global_hotkey_list;	/* link all ev or pl hotkey  */
struct list_head hotkey_entries;	/* head of the list of hotkey_list */

static int hotkey_info_seq_show(struct seq_file *seq, void *offset)
{
	ACPI_FUNCTION_TRACE("hotkey_info_seq_show");

	seq_printf(seq, "Hotkey generic driver ver: %s\n", HOTKEY_ACPI_VERSION);

	return_VALUE(0);
}

static int hotkey_info_open_fs(struct inode *inode, struct file *file)
{
	return single_open(file, hotkey_info_seq_show, PDE(inode)->data);
}

static char *format_result(union acpi_object *object)
{
	char *buf = NULL;
	
	buf = (char *)kmalloc(RESULT_STR_LEN, GFP_KERNEL);
	if (buf)
		memset(buf, 0, RESULT_STR_LEN);
	else
		goto do_fail;

	/* Now, just support integer type */
	if (object->type == ACPI_TYPE_INTEGER)
		sprintf(buf, "%d\n", (u32) object->integer.value);
do_fail:
	return (buf);
}

static int hotkey_polling_seq_show(struct seq_file *seq, void *offset)
{
	struct acpi_polling_hotkey *poll_hotkey =
	    (struct acpi_polling_hotkey *)seq->private;
	char *buf;

	ACPI_FUNCTION_TRACE("hotkey_polling_seq_show");

	if (poll_hotkey->poll_result){
		buf = format_result(poll_hotkey->poll_result);
		if(buf)
			seq_printf(seq, "%s", buf);
		kfree(buf);
	}
	return_VALUE(0);
}

static int hotkey_polling_open_fs(struct inode *inode, struct file *file)
{
	return single_open(file, hotkey_polling_seq_show, PDE(inode)->data);
}

static int hotkey_action_open_fs(struct inode *inode, struct file *file)
{
	return single_open(file, hotkey_info_seq_show, PDE(inode)->data);
}

/* Mapping external hotkey number to standardized hotkey event num */
static int hotkey_get_internal_event(int event, struct acpi_hotkey_list *list)
{
	struct list_head *entries;
	int val = -1;

	ACPI_FUNCTION_TRACE("hotkey_get_internal_event");

	list_for_each(entries, list->entries) {
		union acpi_hotkey *key =
		    container_of(entries, union acpi_hotkey, entries);
		if (key->link.hotkey_type == ACPI_HOTKEY_EVENT
		    && key->event_hotkey.external_hotkey_num == event){
			val = key->link.hotkey_standard_num;
			break;
		}
	}

	return_VALUE(val);
}

static void
acpi_hotkey_notify_handler(acpi_handle handle, u32 event, void *data)
{
	struct acpi_device *device = NULL;
	u32 internal_event;

	ACPI_FUNCTION_TRACE("acpi_hotkey_notify_handler");

	if (acpi_bus_get_device(handle, &device))
		return_VOID;

	internal_event = hotkey_get_internal_event(event, &global_hotkey_list);
	acpi_bus_generate_event(device, internal_event, 0);

	return_VOID;
}

/* Need to invent automatically hotkey add method */
static int auto_hotkey_add(struct acpi_device *device)
{
	/* Implement me */
	return 0;
}

/* Need to invent automatically hotkey remove method */
static int auto_hotkey_remove(struct acpi_device *device, int type)
{
	/* Implement me */
	return 0;
}

/* Create a proc file for each polling method */
static int create_polling_proc(union acpi_hotkey *device)
{
	struct proc_dir_entry *proc;
	char  proc_name[80];
	mode_t mode;

	ACPI_FUNCTION_TRACE("create_polling_proc");
	mode = S_IFREG | S_IRUGO | S_IWUGO;

	sprintf(proc_name, "%d", device->link.hotkey_standard_num);
	/*
	strcat(proc_name, device->poll_hotkey.poll_method);
	*/
	proc = create_proc_entry(proc_name, mode, hotkey_proc_dir);

	if (!proc) {
		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
				  "Hotkey: Unable to create %s entry\n",
				  device->poll_hotkey.poll_method));
		return_VALUE(-ENODEV);
	} else {
		proc->proc_fops = &hotkey_polling_fops;
		proc->owner = THIS_MODULE;
		proc->data = device;
		proc->uid = 0;
		proc->gid = 0;
		device->poll_hotkey.proc = proc;
	}
	return_VALUE(0);
}

static int hotkey_add(union acpi_hotkey *device)
{
	int status = 0;
	struct acpi_device *dev = NULL;

	ACPI_FUNCTION_TRACE("hotkey_add");

	if (device->link.hotkey_type == ACPI_HOTKEY_EVENT) {
		acpi_bus_get_device(device->event_hotkey.bus_handle, &dev);
		status = acpi_install_notify_handler(dev->handle,
						     ACPI_DEVICE_NOTIFY,
						     acpi_hotkey_notify_handler,
						     dev);
	} else			/* Add polling hotkey */
		create_polling_proc(device);

	global_hotkey_list.count++;

	list_add_tail(&device->link.entries, global_hotkey_list.entries);

	return_VALUE(status);
}

static int hotkey_remove(union acpi_hotkey *device)
{
	struct list_head *entries, *next;

	ACPI_FUNCTION_TRACE("hotkey_remove");

	list_for_each_safe(entries, next, global_hotkey_list.entries) {
		union acpi_hotkey *key =
		    container_of(entries, union acpi_hotkey, entries);
		if (key->link.hotkey_standard_num ==
		    device->link.hotkey_standard_num) {
			list_del(&key->link.entries);
			free_hotkey_device(key);
			global_hotkey_list.count--;
			break;
		}
	}
	kfree(device);
	return_VALUE(0);
}

static int  hotkey_update(union acpi_hotkey *key)
{
	struct list_head *entries;

	ACPI_FUNCTION_TRACE("hotkey_update");

	list_for_each(entries, global_hotkey_list.entries) {
		union acpi_hotkey *tmp=
		    container_of(entries, union acpi_hotkey, entries);
		if (tmp->link.hotkey_standard_num ==
		    key->link.hotkey_standard_num) {
			if (key->link.hotkey_type == ACPI_HOTKEY_EVENT) {
				free_hotkey_buffer(tmp);
				tmp->event_hotkey.bus_handle =
			    		key->event_hotkey.bus_handle;
				tmp->event_hotkey.external_hotkey_num =
			    		key->event_hotkey.external_hotkey_num;
				tmp->event_hotkey.action_handle =
			    		key->event_hotkey.action_handle;
				tmp->event_hotkey.action_method =
			    		key->event_hotkey.action_method;
				kfree(key);
			} else {
				/*
				char  proc_name[80];

				sprintf(proc_name, "%d", tmp->link.hotkey_standard_num);
				strcat(proc_name, tmp->poll_hotkey.poll_method);
				remove_proc_entry(proc_name,hotkey_proc_dir);
				*/
				free_poll_hotkey_buffer(tmp);
				tmp->poll_hotkey.poll_handle =
					key->poll_hotkey.poll_handle;
				tmp->poll_hotkey.poll_method =
					key->poll_hotkey.poll_method;
				tmp->poll_hotkey.action_handle =
					key->poll_hotkey.action_handle;
				tmp->poll_hotkey.action_method =
					key->poll_hotkey.action_method;
				tmp->poll_hotkey.poll_result =
					key->poll_hotkey.poll_result;
				/*
				create_polling_proc(tmp);
				*/
				kfree(key);
			}
			return_VALUE(0);
			break;
		}
	}

	return_VALUE(-ENODEV);
}

static void free_hotkey_device(union acpi_hotkey *key)
{
	struct acpi_device *dev;

	ACPI_FUNCTION_TRACE("free_hotkey_device");

	if (key->link.hotkey_type == ACPI_HOTKEY_EVENT) {
		acpi_bus_get_device(key->event_hotkey.bus_handle, &dev);
		if (dev->handle)
			acpi_remove_notify_handler(dev->handle,
						   ACPI_DEVICE_NOTIFY,
						   acpi_hotkey_notify_handler);
		free_hotkey_buffer(key);
	} else {
		char  proc_name[80];

		sprintf(proc_name, "%d", key->link.hotkey_standard_num);
		/*
		strcat(proc_name, key->poll_hotkey.poll_method);
		*/
		remove_proc_entry(proc_name,hotkey_proc_dir);
		free_poll_hotkey_buffer(key);
	}
	kfree(key);
	return_VOID;
}

static void
free_hotkey_buffer(union acpi_hotkey *key)
{
	kfree(key->event_hotkey.action_method);
}

static void
free_poll_hotkey_buffer(union acpi_hotkey *key)
{
	kfree(key->poll_hotkey.action_method);
	kfree(key->poll_hotkey.poll_method);
	kfree(key->poll_hotkey.poll_result);
}
static int
init_hotkey_device(union acpi_hotkey *key, char *bus_str, char *action_str,
		   char *method, int std_num, int external_num)
{
	acpi_handle	tmp_handle;
	acpi_status status = AE_OK;

	ACPI_FUNCTION_TRACE("init_hotkey_device");

	if(std_num < 0 || IS_POLL(std_num) || !key )
		goto do_fail;

	if(!bus_str || !action_str || !method)
		goto do_fail;

	key->link.hotkey_type = ACPI_HOTKEY_EVENT;
	key->link.hotkey_standard_num = std_num;
	key->event_hotkey.flag = 0;
	key->event_hotkey.action_method = method;

	status = acpi_get_handle(NULL,bus_str, &(key->event_hotkey.bus_handle));
	if(ACPI_FAILURE(status))
		goto do_fail;
	key->event_hotkey.external_hotkey_num = external_num;
	status = acpi_get_handle(NULL,action_str, &(key->event_hotkey.action_handle));
	if(ACPI_FAILURE(status))
		goto do_fail;
	status = acpi_get_handle(key->event_hotkey.action_handle,
				method, &tmp_handle);
	if (ACPI_FAILURE(status))
		goto do_fail;
	return_VALUE(AE_OK);
do_fail:
	return_VALUE(-ENODEV);
}

static int
init_poll_hotkey_device(union acpi_hotkey *key,
			char *poll_str,
			char *poll_method,
			char *action_str, char *action_method, int std_num)
{
	acpi_status status = AE_OK;
	acpi_handle	tmp_handle;

	ACPI_FUNCTION_TRACE("init_poll_hotkey_device");

	if(std_num < 0 || IS_EVENT(std_num) || !key)
		goto do_fail;

	if(!poll_str || !poll_method || !action_str || !action_method)
		goto do_fail;

	key->link.hotkey_type = ACPI_HOTKEY_POLLING;
	key->link.hotkey_standard_num = std_num;
	key->poll_hotkey.flag = 0;
	key->poll_hotkey.poll_method = poll_method;
	key->poll_hotkey.action_method = action_method;

	status = acpi_get_handle(NULL,poll_str, &(key->poll_hotkey.poll_handle));
	if(ACPI_FAILURE(status))
		goto do_fail;
	status = acpi_get_handle(key->poll_hotkey.poll_handle,
				poll_method, &tmp_handle);
        if (ACPI_FAILURE(status))
       		goto do_fail;
	status = acpi_get_handle(NULL,action_str, &(key->poll_hotkey.action_handle));
	if (ACPI_FAILURE(status))
		goto do_fail;
	status = acpi_get_handle(key->poll_hotkey.action_handle,
				action_method, &tmp_handle);
	if (ACPI_FAILURE(status))
		goto do_fail;
	key->poll_hotkey.poll_result =
	    (union acpi_object *)kmalloc(sizeof(union acpi_object), GFP_KERNEL);
	if(!key->poll_hotkey.poll_result)
		goto do_fail;
	return_VALUE(AE_OK);
do_fail:
	return_VALUE(-ENODEV);
}


static int hotkey_open_config(struct inode *inode, struct file *file)
{
	ACPI_FUNCTION_TRACE("hotkey_open_config");
	return_VALUE(single_open
		     (file, hotkey_config_seq_show, PDE(inode)->data));
}

static int hotkey_poll_open_config(struct inode *inode, struct file *file)
{
	ACPI_FUNCTION_TRACE("hotkey_poll_open_config");
	return_VALUE(single_open
		     (file, hotkey_poll_config_seq_show, PDE(inode)->data));
}

static int hotkey_config_seq_show(struct seq_file *seq, void *offset)
{
	struct acpi_hotkey_list *hotkey_list = &global_hotkey_list;
	struct list_head *entries;
	char bus_name[ACPI_PATHNAME_MAX] = { 0 };
	char action_name[ACPI_PATHNAME_MAX] = { 0 };
	struct acpi_buffer bus = { ACPI_PATHNAME_MAX, bus_name };
	struct acpi_buffer act = { ACPI_PATHNAME_MAX, action_name };

	ACPI_FUNCTION_TRACE(("hotkey_config_seq_show"));

	list_for_each(entries, hotkey_list->entries) {
		union acpi_hotkey *key =
		    container_of(entries, union acpi_hotkey, entries);
		if (key->link.hotkey_type == ACPI_HOTKEY_EVENT) {
			acpi_get_name(key->event_hotkey.bus_handle,
				      ACPI_NAME_TYPE_MAX, &bus);
			acpi_get_name(key->event_hotkey.action_handle,
				      ACPI_NAME_TYPE_MAX, &act);
			seq_printf(seq, "%s:%s:%s:%d:%d\n", bus_name,
				   action_name,
				   key->event_hotkey.action_method,
				   key->link.hotkey_standard_num,
				   key->event_hotkey.external_hotkey_num);
		}
	}
	seq_puts(seq, "\n");
	return_VALUE(0);
}

static int hotkey_poll_config_seq_show(struct seq_file *seq, void *offset)
{
	struct acpi_hotkey_list *hotkey_list = &global_hotkey_list;
	struct list_head *entries;
	char bus_name[ACPI_PATHNAME_MAX] = { 0 };
	char action_name[ACPI_PATHNAME_MAX] = { 0 };
	struct acpi_buffer bus = { ACPI_PATHNAME_MAX, bus_name };
	struct acpi_buffer act = { ACPI_PATHNAME_MAX, action_name };

	ACPI_FUNCTION_TRACE(("hotkey_config_seq_show"));

	list_for_each(entries, hotkey_list->entries) {
		union acpi_hotkey *key =
		    container_of(entries, union acpi_hotkey, entries);
		if (key->link.hotkey_type == ACPI_HOTKEY_POLLING) {
			acpi_get_name(key->poll_hotkey.poll_handle,
				      ACPI_NAME_TYPE_MAX, &bus);
			acpi_get_name(key->poll_hotkey.action_handle,
				      ACPI_NAME_TYPE_MAX, &act);
			seq_printf(seq, "%s:%s:%s:%s:%d\n", bus_name,
				   key->poll_hotkey.poll_method,
				   action_name,
				   key->poll_hotkey.action_method,
				   key->link.hotkey_standard_num);
		}
	}
	seq_puts(seq, "\n");
	return_VALUE(0);
}

static int
get_parms(char *config_record,
	  int *cmd,
	  char **bus_handle,
	  char **bus_method,
	  char **action_handle,
	  char **method, int *internal_event_num, int *external_event_num)
{
	char *tmp, *tmp1, count;
	ACPI_FUNCTION_TRACE(("get_parms"));

	sscanf(config_record, "%d", cmd);

	if(*cmd == 1){
		if(sscanf(config_record, "%d:%d", cmd, internal_event_num)!=2)
			goto do_fail;
		else
			return (6);
	}
	tmp = strchr(config_record, ':');
	if (!tmp)
		goto do_fail;
	tmp++;
	tmp1 = strchr(tmp, ':');
	if (!tmp1)
		goto do_fail;

	count = tmp1 - tmp;
	*bus_handle = (char *) kmalloc(count+1, GFP_KERNEL);
	if(!*bus_handle)
		goto do_fail;
	strncpy(*bus_handle, tmp, count);
	*(*bus_handle + count) = 0;

	tmp = tmp1;
	tmp++;
	tmp1 = strchr(tmp, ':');
	if (!tmp1)
		goto do_fail;
	count = tmp1 - tmp;
	*bus_method = (char *) kmalloc(count+1, GFP_KERNEL);
	if(!*bus_method)
		goto do_fail;
	strncpy(*bus_method, tmp, count);
	*(*bus_method + count) = 0;

	tmp = tmp1;
	tmp++;
	tmp1 = strchr(tmp, ':');
	if (!tmp1)
		goto do_fail;
	count = tmp1 - tmp;
	*action_handle = (char *) kmalloc(count+1, GFP_KERNEL);
	strncpy(*action_handle, tmp, count);
	*(*action_handle + count) = 0;

	tmp = tmp1;
	tmp++;
	tmp1 = strchr(tmp, ':');
	if (!tmp1)
		goto do_fail;
	count = tmp1 - tmp;
	*method = (char *) kmalloc(count+1, GFP_KERNEL);
	if(!*method)
		goto do_fail;
	strncpy(*method, tmp, count);
	*(*method + count) = 0;

	if(sscanf(tmp1 + 1, "%d:%d", internal_event_num, external_event_num)<=0)
		goto do_fail;

	return_VALUE(6);
do_fail:
	return_VALUE(-1);
}

/*  count is length for one input record */
static ssize_t hotkey_write_config(struct file *file,
				   const char __user * buffer,
				   size_t count, loff_t * data)
{
	char *config_record = NULL;
	char *bus_handle = NULL;
	char *bus_method = NULL;
	char *action_handle = NULL;
	char *method = NULL;
	int cmd, internal_event_num, external_event_num;
	int ret = 0;
	union acpi_hotkey *key = NULL;

	ACPI_FUNCTION_TRACE(("hotkey_write_config"));

	config_record = (char *) kmalloc(count+1, GFP_KERNEL);
	if(!config_record)
		return_VALUE(-ENOMEM);

	if (copy_from_user(config_record, buffer, count)) {
		kfree(config_record);
		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid data \n"));
		return_VALUE(-EINVAL);
	}
	config_record[count] = 0;

	ret = get_parms(config_record,
			&cmd,
			&bus_handle,
			&bus_method,
			&action_handle,
			&method, &internal_event_num, &external_event_num);

	kfree(config_record);
	if(IS_OTHERS(internal_event_num))
		goto do_fail;
	if (ret != 6) {
do_fail:	
		kfree(bus_handle);
		kfree(bus_method);
		kfree(action_handle);
		kfree(method);
		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
				  "Invalid data format ret=%d\n", ret));
		return_VALUE(-EINVAL);
	}

	key = kmalloc(sizeof(union acpi_hotkey), GFP_KERNEL);
	if(!key)
		goto do_fail;
	memset(key, 0, sizeof(union acpi_hotkey));
	if(cmd == 1) {
		union acpi_hotkey *tmp = NULL;
		tmp = get_hotkey_by_event(&global_hotkey_list,
				internal_event_num);
		if(!tmp)
			ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid key"));
		else
			memcpy(key, tmp, sizeof(union acpi_hotkey));
		goto cont_cmd;
	}
	if (IS_EVENT(internal_event_num)) {
		kfree(bus_method);
		ret = init_hotkey_device(key, bus_handle, action_handle, method,
				 internal_event_num, external_event_num);
	} else
		ret = init_poll_hotkey_device(key, bus_handle, bus_method,
				      action_handle, method,
				      internal_event_num);
	if (ret) {
		kfree(bus_handle);
		kfree(action_handle);
		if(IS_EVENT(internal_event_num))
			free_hotkey_buffer(key);
		else
			free_poll_hotkey_buffer(key);
		kfree(key);
		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid hotkey \n"));
		return_VALUE(-EINVAL);
	}

cont_cmd:
	kfree(bus_handle);
	kfree(action_handle);

	switch (cmd) {
	case 0:
		if(get_hotkey_by_event(&global_hotkey_list,key->link.hotkey_standard_num))
			goto fail_out;
		else
			hotkey_add(key);
		break;
	case 1:
		hotkey_remove(key);
		break;
	case 2:
		if(hotkey_update(key))
			goto fail_out;
		break;
	default:
		goto fail_out;
		break;
	}
	return_VALUE(count);
fail_out:
	if(IS_EVENT(internal_event_num))
		free_hotkey_buffer(key);
	else
		free_poll_hotkey_buffer(key);
	kfree(key);
	ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "invalid key\n"));
	return_VALUE(-EINVAL);
}

/*
 * This function evaluates an ACPI method, given an int as parameter, the
 * method is searched within the scope of the handle, can be NULL. The output
 * of the method is written is output, which can also be NULL
 *
 * returns 1 if write is successful, 0 else.
 */
static int write_acpi_int(acpi_handle handle, const char *method, int val,
			  struct acpi_buffer *output)
{
	struct acpi_object_list params;	/* list of input parameters (an int here) */
	union acpi_object in_obj;	/* the only param we use */
	acpi_status status;

	ACPI_FUNCTION_TRACE("write_acpi_int");
	params.count = 1;
	params.pointer = &in_obj;
	in_obj.type = ACPI_TYPE_INTEGER;
	in_obj.integer.value = val;

	status = acpi_evaluate_object(handle, (char *)method, &params, output);

	return_VALUE(status == AE_OK);
}

static int read_acpi_int(acpi_handle handle, const char *method, union acpi_object *val)
{
	struct acpi_buffer output;
	union acpi_object out_obj;
	acpi_status status;

	ACPI_FUNCTION_TRACE("read_acpi_int");
	output.length = sizeof(out_obj);
	output.pointer = &out_obj;

	status = acpi_evaluate_object(handle, (char *)method, NULL, &output);
	if(val){
		val->integer.value = out_obj.integer.value;
		val->type = out_obj.type;
	} else
		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "null val pointer"));
	return_VALUE((status == AE_OK)
		     && (out_obj.type == ACPI_TYPE_INTEGER));
}

static union acpi_hotkey *get_hotkey_by_event(struct
			      acpi_hotkey_list
			      *hotkey_list, int event)
{
	struct list_head *entries;

	list_for_each(entries, hotkey_list->entries) {
		union acpi_hotkey *key =
		    container_of(entries, union acpi_hotkey, entries);
		if (key->link.hotkey_standard_num == event) {
			return(key);
		}
	}
	return(NULL);
}

/*
 * user call AML method interface:
 * Call convention:
 * echo "event_num: arg type : value"
 * example: echo "1:1:30" > /proc/acpi/action
 * Just support 1 integer arg passing to AML method
 */

static ssize_t hotkey_execute_aml_method(struct file *file,
					 const char __user * buffer,
					 size_t count, loff_t * data)
{
	struct acpi_hotkey_list *hotkey_list = &global_hotkey_list;
	char *arg;
	int event,method_type,type, value;
	union acpi_hotkey *key;

	ACPI_FUNCTION_TRACE("hotkey_execte_aml_method");

	arg = (char *) kmalloc(count+1, GFP_KERNEL);
	if(!arg)
		return_VALUE(-ENOMEM);
	arg[count]=0;

	if (copy_from_user(arg, buffer, count)) {
		kfree(arg);
		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid argument 2"));
		return_VALUE(-EINVAL);
	}

	if (sscanf(arg, "%d:%d:%d:%d", &event, &method_type, &type, &value) != 4) {
		kfree(arg);
		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid argument 3"));
		return_VALUE(-EINVAL);
	}
	kfree(arg);
	if (type == ACPI_TYPE_INTEGER) {
		key = get_hotkey_by_event(hotkey_list, event);
		if(!key)
			goto do_fail;
		if (IS_EVENT(event))
			write_acpi_int(key->event_hotkey.action_handle,
					key->event_hotkey.action_method, value, NULL);
		else if (IS_POLL(event)) {
			if ( method_type == POLL_METHOD )
				read_acpi_int(key->poll_hotkey.poll_handle,
					key->poll_hotkey.poll_method,
					key->poll_hotkey.poll_result);
			else if ( method_type == ACTION_METHOD )
				write_acpi_int(key->poll_hotkey.action_handle,
					key->poll_hotkey.action_method, value, NULL);
			else
				goto do_fail;

		}
	} else {
		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Not supported"));
		return_VALUE(-EINVAL);
	}
	return_VALUE(count);
do_fail:
	return_VALUE(-EINVAL);

}

static int __init hotkey_init(void)
{
	int result;
	mode_t mode = S_IFREG | S_IRUGO | S_IWUGO;

	ACPI_FUNCTION_TRACE("hotkey_init");

	if (acpi_disabled)
		return -ENODEV;

	if (acpi_specific_hotkey_enabled) {
		printk("Using specific hotkey driver\n");
		return -ENODEV;
	}

	hotkey_proc_dir = proc_mkdir(HOTKEY_PROC, acpi_root_dir);
	if (!hotkey_proc_dir) {
		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
				  "Hotkey: Unable to create %s entry\n",
				  HOTKEY_PROC));
		return (-ENODEV);
	}
	hotkey_proc_dir->owner = THIS_MODULE;

	hotkey_config =
	    create_proc_entry(HOTKEY_EV_CONFIG, mode, hotkey_proc_dir);
	if (!hotkey_config) {
		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
				  "Hotkey: Unable to create %s entry\n",
				  HOTKEY_EV_CONFIG));
		goto do_fail1;
	} else {
		hotkey_config->proc_fops = &hotkey_config_fops;
		hotkey_config->data = &global_hotkey_list;
		hotkey_config->owner = THIS_MODULE;
		hotkey_config->uid = 0;
		hotkey_config->gid = 0;
	}

	hotkey_poll_config =
	    create_proc_entry(HOTKEY_PL_CONFIG, mode, hotkey_proc_dir);
	if (!hotkey_poll_config) {
		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
				  "Hotkey: Unable to create %s entry\n",
				  HOTKEY_EV_CONFIG));

		goto do_fail2;
	} else {
		hotkey_poll_config->proc_fops = &hotkey_poll_config_fops;
		hotkey_poll_config->data = &global_hotkey_list;
		hotkey_poll_config->owner = THIS_MODULE;
		hotkey_poll_config->uid = 0;
		hotkey_poll_config->gid = 0;
	}

	hotkey_action = create_proc_entry(HOTKEY_ACTION, mode, hotkey_proc_dir);
	if (!hotkey_action) {
		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
				  "Hotkey: Unable to create %s entry\n",
				  HOTKEY_ACTION));
		goto do_fail3;
	} else {
		hotkey_action->proc_fops = &hotkey_action_fops;
		hotkey_action->owner = THIS_MODULE;
		hotkey_action->uid = 0;
		hotkey_action->gid = 0;
	}

	hotkey_info = create_proc_entry(HOTKEY_INFO, mode, hotkey_proc_dir);
	if (!hotkey_info) {
		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
				  "Hotkey: Unable to create %s entry\n",
				  HOTKEY_INFO));
		goto do_fail4;
	} else {
		hotkey_info->proc_fops = &hotkey_info_fops;
		hotkey_info->owner = THIS_MODULE;
		hotkey_info->uid = 0;
		hotkey_info->gid = 0;
	}

	result = acpi_bus_register_driver(&hotkey_driver);
	if (result < 0)
		goto do_fail5;
	global_hotkey_list.count = 0;
	global_hotkey_list.entries = &hotkey_entries;

	INIT_LIST_HEAD(&hotkey_entries);

	return (0);

do_fail5:
	remove_proc_entry(HOTKEY_INFO, hotkey_proc_dir);
do_fail4:
	remove_proc_entry(HOTKEY_ACTION, hotkey_proc_dir);
do_fail3:
	remove_proc_entry(HOTKEY_PL_CONFIG, hotkey_proc_dir);
do_fail2:
	remove_proc_entry(HOTKEY_EV_CONFIG, hotkey_proc_dir);
do_fail1:
	remove_proc_entry(HOTKEY_PROC, acpi_root_dir);
	return (-ENODEV);
}

static void __exit hotkey_exit(void)
{
	struct list_head *entries, *next;

	ACPI_FUNCTION_TRACE("hotkey_exit");

	list_for_each_safe(entries, next, global_hotkey_list.entries) {
		union acpi_hotkey *key =
		    container_of(entries, union acpi_hotkey, entries);

		acpi_os_wait_events_complete(NULL);
		list_del(&key->link.entries);
		global_hotkey_list.count--;
		free_hotkey_device(key);
	}
	acpi_bus_unregister_driver(&hotkey_driver);
	remove_proc_entry(HOTKEY_EV_CONFIG, hotkey_proc_dir);
	remove_proc_entry(HOTKEY_PL_CONFIG, hotkey_proc_dir);
	remove_proc_entry(HOTKEY_ACTION, hotkey_proc_dir);
	remove_proc_entry(HOTKEY_INFO, hotkey_proc_dir);
	remove_proc_entry(HOTKEY_PROC, acpi_root_dir);
	return;
}

module_init(hotkey_init);
module_exit(hotkey_exit);
