/*
 * $Id: power.c,v 1.10 2001/09/25 09:17:15 vojtech Exp $
 *
 *  Copyright (c) 2001 "Crazy" James Simmons
 *
 *  Input driver Power Management.
 *
 *  Sponsored by Transvirtual Technology.
 */

/*
 * 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
 *
 * Should you need to contact me, the author, you can do so by
 * e-mail - mail your message to <jsimmons@transvirtual.com>.
 */

#include <linux/module.h>
#include <linux/input.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/tty.h>
#include <linux/delay.h>
#include <linux/pm.h>

static struct input_handler power_handler;

/*
 * Power management can't be done in a interrupt context. So we have to
 * use keventd.
 */
static int suspend_button_pushed = 0;
static void suspend_button_task_handler(void *data)
{
        udelay(200); /* debounce */
        suspend_button_pushed = 0;
}

static DECLARE_WORK(suspend_button_task, suspend_button_task_handler, NULL);

static void power_event(struct input_handle *handle, unsigned int type,
		        unsigned int code, int down)
{
	struct input_dev *dev = handle->dev;

	printk("Entering power_event\n");

	if (type == EV_PWR) {
		switch (code) {
			case KEY_SUSPEND:
				printk("Powering down entire device\n");

				if (!suspend_button_pushed) {
                			suspend_button_pushed = 1;
                        		schedule_work(&suspend_button_task);
                		}
				break;
			case KEY_POWER:
				/* Hum power down the machine. */
				break;
			default:
				return;
		}
	}

	if (type == EV_KEY) {
		switch (code) {
			case KEY_SUSPEND:
				printk("Powering down input device\n");
				/* This is risky. See pm.h for details. */
				if (dev->state != PM_RESUME)
					dev->state = PM_RESUME;
				else
					dev->state = PM_SUSPEND;
				pm_send(dev->pm_dev, dev->state, dev);
				break;
			case KEY_POWER:
				/* Turn the input device off completely ? */
				break;
			default:
				return;
		}
	}
	return;
}

static struct input_handle *power_connect(struct input_handler *handler,
					  struct input_dev *dev,
					  const struct input_device_id *id)
{
	struct input_handle *handle;

	if (!(handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL)))
		return NULL;

	handle->dev = dev;
	handle->handler = handler;

	input_open_device(handle);

	printk(KERN_INFO "power.c: Adding power management to input layer\n");
	return handle;
}

static void power_disconnect(struct input_handle *handle)
{
	input_close_device(handle);
	kfree(handle);
}

static const struct input_device_id power_ids[] = {
	{
		.flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT,
		.evbit = { BIT(EV_KEY) },
		.keybit = { [LONG(KEY_SUSPEND)] = BIT(KEY_SUSPEND) }
	},
	{
		.flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT,
		.evbit = { BIT(EV_KEY) },
		.keybit = { [LONG(KEY_POWER)] = BIT(KEY_POWER) }
	},
	{
		.flags = INPUT_DEVICE_ID_MATCH_EVBIT,
		.evbit = { BIT(EV_PWR) },
	},
	{ }, 	/* Terminating entry */
};

MODULE_DEVICE_TABLE(input, power_ids);

static struct input_handler power_handler = {
	.event =	power_event,
	.connect =	power_connect,
	.disconnect =	power_disconnect,
	.name =		"power",
	.id_table =	power_ids,
};

static int __init power_init(void)
{
	return input_register_handler(&power_handler);
}

static void __exit power_exit(void)
{
	input_unregister_handler(&power_handler);
}

module_init(power_init);
module_exit(power_exit);

MODULE_AUTHOR("James Simmons <jsimmons@transvirtual.com>");
MODULE_DESCRIPTION("Input Power Management driver");
MODULE_LICENSE("GPL");
