/*
 *  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];
	/* Bit to serialize writes to this device */
#define KEYCHORD_BUSY			0x01
	unsigned long		flags;
	wait_queue_head_t	write_waitq;
};

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.head));
		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;
}

/*
 * serializes writes on a device. can use mutex_lock_interruptible()
 * for this particular use case as well - a matter of preference.
 */
static int
keychord_write_lock(struct keychord_device *kdev)
{
	int ret;
	unsigned long flags;

	spin_lock_irqsave(&kdev->lock, flags);
	while (kdev->flags & KEYCHORD_BUSY) {
		spin_unlock_irqrestore(&kdev->lock, flags);
		ret = wait_event_interruptible(kdev->write_waitq,
			       ((kdev->flags & KEYCHORD_BUSY) == 0));
		if (ret)
			return ret;
		spin_lock_irqsave(&kdev->lock, flags);
	}
	kdev->flags |= KEYCHORD_BUSY;
	spin_unlock_irqrestore(&kdev->lock, flags);
	return 0;
}

static void
keychord_write_unlock(struct keychord_device *kdev)
{
	unsigned long flags;

	spin_lock_irqsave(&kdev->lock, flags);
	kdev->flags &= ~KEYCHORD_BUSY;
	spin_unlock_irqrestore(&kdev->lock, flags);
	wake_up_interruptible(&kdev->write_waitq);
}

/*
 * 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;
	int ret, i, key;
	unsigned long flags;
	size_t resid = count;
	size_t key_bytes;

	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;
	}

	/*
	 * Serialize writes to this device to prevent various races.
	 * 1) writers racing here could do duplicate input_unregister_handler()
	 *    calls, resulting in attempting to unlink a node from a list that
	 *    does not exist.
	 * 2) writers racing here could do duplicate input_register_handler() calls
	 *    below, resulting in a duplicate insertion of a node into the list.
	 * 3) a double kfree of keychords can occur (in the event that
	 *    input_register_handler() fails below.
	 */
	ret = keychord_write_lock(kdev);
	if (ret) {
		kfree(keychords);
		return ret;
	}

	/* 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;

	while (resid > 0) {
		/* Is the entire keychord entry header present ? */
		if (resid < sizeof(struct input_keychord)) {
			pr_err("keychord: Insufficient bytes present for header %zu\n",
			       resid);
			goto err_unlock_return;
		}
		resid -= sizeof(struct input_keychord);
		if (keychord->count <= 0) {
			pr_err("keychord: invalid keycode count %d\n",
				keychord->count);
			goto err_unlock_return;
		}
		key_bytes = keychord->count * sizeof(keychord->keycodes[0]);
		/* Do we have all the expected keycodes ? */
		if (resid < key_bytes) {
			pr_err("keychord: Insufficient bytes present for keycount %zu\n",
			       resid);
			goto err_unlock_return;
		}
		resid -= key_bytes;

		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_KEYCHORD(keychord);
	}

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

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

	keychord_write_unlock(kdev);

	return count;

err_unlock_return:
	spin_unlock_irqrestore(&kdev->lock, flags);
	kfree(keychords);
	keychord_write_unlock(kdev);
	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);
	init_waitqueue_head(&kdev->write_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->keychords);
	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);
