/*
 *  drivers/input/misc/keychord.c
 *
 * Copyright (C) 2008 Google, Inc.
 * Author: Mike Lockwood <lockwood@android.com>
 *
 * This software is licensed under the terms of the GNU General Public
 * License version 2, as published by the Free Software Foundation, and
 * may be copied, distributed, and modified under those terms.
 *
 * 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.
 *
*/

#include <linux/poll.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/spinlock.h>
#include <linux/fs.h>
#include <linux/miscdevice.h>
#include <linux/keychord.h>
#include <linux/sched.h>

#define KEYCHORD_NAME		"keychord"
#define BUFFER_SIZE			16

MODULE_AUTHOR("Mike Lockwood <lockwood@android.com>");
MODULE_DESCRIPTION("Key chord input driver");
MODULE_SUPPORTED_DEVICE("keychord");
MODULE_LICENSE("GPL");

#define NEXT_KEYCHORD(kc) ((struct input_keychord *) \
		((char *)kc + sizeof(struct input_keychord) + \
		kc->count * sizeof(kc->keycodes[0])))

struct keychord_device {
	struct input_handler	input_handler;
	int			registered;

	/* list of keychords to monitor */
	struct input_keychord	*keychords;
	int			keychord_count;

	/* bitmask of keys contained in our keychords */
	unsigned long keybit[BITS_TO_LONGS(KEY_CNT)];
	/* current state of the keys */
	unsigned long keystate[BITS_TO_LONGS(KEY_CNT)];
	/* number of keys that are currently pressed */
	int key_down;

	/* second input_device_id is needed for null termination */
	struct input_device_id  device_ids[2];

	spinlock_t		lock;
	wait_queue_head_t	waitq;
	unsigned char		head;
	unsigned char		tail;
	__u16			buff[BUFFER_SIZE];
};

static int check_keychord(struct keychord_device *kdev,
		struct input_keychord *keychord)
{
	int i;

	if (keychord->count != kdev->key_down)
		return 0;

	for (i = 0; i < keychord->count; i++) {
		if (!test_bit(keychord->keycodes[i], kdev->keystate))
			return 0;
	}

	/* we have a match */
	return 1;
}

static void keychord_event(struct input_handle *handle, unsigned int type,
			   unsigned int code, int value)
{
	struct keychord_device *kdev = handle->private;
	struct input_keychord *keychord;
	unsigned long flags;
	int i, got_chord = 0;

	if (type != EV_KEY || code >= KEY_MAX)
		return;

	spin_lock_irqsave(&kdev->lock, flags);
	/* do nothing if key state did not change */
	if (!test_bit(code, kdev->keystate) == !value)
		goto done;
	__change_bit(code, kdev->keystate);
	if (value)
		kdev->key_down++;
	else
		kdev->key_down--;

	/* don't notify on key up */
	if (!value)
		goto done;
	/* ignore this event if it is not one of the keys we are monitoring */
	if (!test_bit(code, kdev->keybit))
		goto done;

	keychord = kdev->keychords;
	if (!keychord)
		goto done;

	/* check to see if the keyboard state matches any keychords */
	for (i = 0; i < kdev->keychord_count; i++) {
		if (check_keychord(kdev, keychord)) {
			kdev->buff[kdev->head] = keychord->id;
			kdev->head = (kdev->head + 1) % BUFFER_SIZE;
			got_chord = 1;
			break;
		}
		/* skip to next keychord */
		keychord = NEXT_KEYCHORD(keychord);
	}

done:
	spin_unlock_irqrestore(&kdev->lock, flags);

	if (got_chord) {
		pr_info("keychord: got keychord id %d. Any tasks: %d\n",
			keychord->id,
			!list_empty_careful(&kdev->waitq.task_list));
		wake_up_interruptible(&kdev->waitq);
	}
}

static int keychord_connect(struct input_handler *handler,
					  struct input_dev *dev,
					  const struct input_device_id *id)
{
	int i, ret;
	struct input_handle *handle;
	struct keychord_device *kdev =
		container_of(handler, struct keychord_device, input_handler);

	/*
	 * ignore this input device if it does not contain any keycodes
	 * that we are monitoring
	 */
	for (i = 0; i < KEY_MAX; i++) {
		if (test_bit(i, kdev->keybit) && test_bit(i, dev->keybit))
			break;
	}
	if (i == KEY_MAX)
		return -ENODEV;

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

	handle->dev = dev;
	handle->handler = handler;
	handle->name = KEYCHORD_NAME;
	handle->private = kdev;

	ret = input_register_handle(handle);
	if (ret)
		goto err_input_register_handle;

	ret = input_open_device(handle);
	if (ret)
		goto err_input_open_device;

	pr_info("keychord: using input dev %s for fevent\n", dev->name);

	return 0;

err_input_open_device:
	input_unregister_handle(handle);
err_input_register_handle:
	kfree(handle);
	return ret;
}

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

/*
 * keychord_read is used to read keychord events from the driver
 */
static ssize_t keychord_read(struct file *file, char __user *buffer,
		size_t count, loff_t *ppos)
{
	struct keychord_device *kdev = file->private_data;
	__u16   id;
	int retval;
	unsigned long flags;

	if (count < sizeof(id))
		return -EINVAL;
	count = sizeof(id);

	if (kdev->head == kdev->tail && (file->f_flags & O_NONBLOCK))
		return -EAGAIN;

	retval = wait_event_interruptible(kdev->waitq,
			kdev->head != kdev->tail);
	if (retval)
		return retval;

	spin_lock_irqsave(&kdev->lock, flags);
	/* pop a keychord ID off the queue */
	id = kdev->buff[kdev->tail];
	kdev->tail = (kdev->tail + 1) % BUFFER_SIZE;
	spin_unlock_irqrestore(&kdev->lock, flags);

	if (copy_to_user(buffer, &id, count))
		return -EFAULT;

	return count;
}

/*
 * keychord_write is used to configure the driver
 */
static ssize_t keychord_write(struct file *file, const char __user *buffer,
		size_t count, loff_t *ppos)
{
	struct keychord_device *kdev = file->private_data;
	struct input_keychord *keychords = 0;
	struct input_keychord *keychord, *next, *end;
	int ret, i, key;
	unsigned long flags;

	if (count < sizeof(struct input_keychord))
		return -EINVAL;
	keychords = kzalloc(count, GFP_KERNEL);
	if (!keychords)
		return -ENOMEM;

	/* read list of keychords from userspace */
	if (copy_from_user(keychords, buffer, count)) {
		kfree(keychords);
		return -EFAULT;
	}

	/* unregister handler before changing configuration */
	if (kdev->registered) {
		input_unregister_handler(&kdev->input_handler);
		kdev->registered = 0;
	}

	spin_lock_irqsave(&kdev->lock, flags);
	/* clear any existing configuration */
	kfree(kdev->keychords);
	kdev->keychords = 0;
	kdev->keychord_count = 0;
	kdev->key_down = 0;
	memset(kdev->keybit, 0, sizeof(kdev->keybit));
	memset(kdev->keystate, 0, sizeof(kdev->keystate));
	kdev->head = kdev->tail = 0;

	keychord = keychords;
	end = (struct input_keychord *)((char *)keychord + count);

	while (keychord < end) {
		next = NEXT_KEYCHORD(keychord);
		if (keychord->count <= 0 || next > end) {
			pr_err("keychord: invalid keycode count %d\n",
				keychord->count);
			goto err_unlock_return;
		}
		if (keychord->version != KEYCHORD_VERSION) {
			pr_err("keychord: unsupported version %d\n",
				keychord->version);
			goto err_unlock_return;
		}

		/* keep track of the keys we are monitoring in keybit */
		for (i = 0; i < keychord->count; i++) {
			key = keychord->keycodes[i];
			if (key < 0 || key >= KEY_CNT) {
				pr_err("keychord: keycode %d out of range\n",
					key);
				goto err_unlock_return;
			}
			__set_bit(key, kdev->keybit);
		}

		kdev->keychord_count++;
		keychord = next;
	}

	kdev->keychords = keychords;
	spin_unlock_irqrestore(&kdev->lock, flags);

	ret = input_register_handler(&kdev->input_handler);
	if (ret) {
		kfree(keychords);
		kdev->keychords = 0;
		return ret;
	}
	kdev->registered = 1;

	return count;

err_unlock_return:
	spin_unlock_irqrestore(&kdev->lock, flags);
	kfree(keychords);
	return -EINVAL;
}

static unsigned int keychord_poll(struct file *file, poll_table *wait)
{
	struct keychord_device *kdev = file->private_data;

	poll_wait(file, &kdev->waitq, wait);

	if (kdev->head != kdev->tail)
		return POLLIN | POLLRDNORM;

	return 0;
}

static int keychord_open(struct inode *inode, struct file *file)
{
	struct keychord_device *kdev;

	kdev = kzalloc(sizeof(struct keychord_device), GFP_KERNEL);
	if (!kdev)
		return -ENOMEM;

	spin_lock_init(&kdev->lock);
	init_waitqueue_head(&kdev->waitq);

	kdev->input_handler.event = keychord_event;
	kdev->input_handler.connect = keychord_connect;
	kdev->input_handler.disconnect = keychord_disconnect;
	kdev->input_handler.name = KEYCHORD_NAME;
	kdev->input_handler.id_table = kdev->device_ids;

	kdev->device_ids[0].flags = INPUT_DEVICE_ID_MATCH_EVBIT;
	__set_bit(EV_KEY, kdev->device_ids[0].evbit);

	file->private_data = kdev;

	return 0;
}

static int keychord_release(struct inode *inode, struct file *file)
{
	struct keychord_device *kdev = file->private_data;

	if (kdev->registered)
		input_unregister_handler(&kdev->input_handler);
	kfree(kdev);

	return 0;
}

static const struct file_operations keychord_fops = {
	.owner		= THIS_MODULE,
	.open		= keychord_open,
	.release	= keychord_release,
	.read		= keychord_read,
	.write		= keychord_write,
	.poll		= keychord_poll,
};

static struct miscdevice keychord_misc = {
	.fops		= &keychord_fops,
	.name		= KEYCHORD_NAME,
	.minor		= MISC_DYNAMIC_MINOR,
};

static int __init keychord_init(void)
{
	return misc_register(&keychord_misc);
}

static void __exit keychord_exit(void)
{
	misc_deregister(&keychord_misc);
}

module_init(keychord_init);
module_exit(keychord_exit);
