/*
 * Generic support for sparse keymaps
 *
 * Copyright (c) 2009 Dmitry Torokhov
 *
 * Derived from wistron button driver:
 * Copyright (C) 2005 Miloslav Trmac <mitr@volny.cz>
 * Copyright (C) 2005 Bernhard Rosenkraenzer <bero@arklinux.org>
 * Copyright (C) 2005 Dmitry Torokhov <dtor@mail.ru>
 *
 * 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.
 */

#include <linux/input.h>
#include <linux/input/sparse-keymap.h>
#include <linux/slab.h>

MODULE_AUTHOR("Dmitry Torokhov <dtor@mail.ru>");
MODULE_DESCRIPTION("Generic support for sparse keymaps");
MODULE_LICENSE("GPL v2");
MODULE_VERSION("0.1");

/**
 * sparse_keymap_entry_from_scancode - perform sparse keymap lookup
 * @dev: Input device using sparse keymap
 * @code: Scan code
 *
 * This function is used to perform &struct key_entry lookup in an
 * input device using sparse keymap.
 */
struct key_entry *sparse_keymap_entry_from_scancode(struct input_dev *dev,
						    unsigned int code)
{
	struct key_entry *key;

	for (key = dev->keycode; key->type != KE_END; key++)
		if (code == key->code)
			return key;

	return NULL;
}
EXPORT_SYMBOL(sparse_keymap_entry_from_scancode);

/**
 * sparse_keymap_entry_from_keycode - perform sparse keymap lookup
 * @dev: Input device using sparse keymap
 * @keycode: Key code
 *
 * This function is used to perform &struct key_entry lookup in an
 * input device using sparse keymap.
 */
struct key_entry *sparse_keymap_entry_from_keycode(struct input_dev *dev,
						   unsigned int keycode)
{
	struct key_entry *key;

	for (key = dev->keycode; key->type != KE_END; key++)
		if (key->type == KE_KEY && keycode == key->keycode)
			return key;

	return NULL;
}
EXPORT_SYMBOL(sparse_keymap_entry_from_keycode);

static int sparse_keymap_getkeycode(struct input_dev *dev,
				    unsigned int scancode,
				    unsigned int *keycode)
{
	const struct key_entry *key;

	if (dev->keycode) {
		key = sparse_keymap_entry_from_scancode(dev, scancode);
		if (key && key->type == KE_KEY) {
			*keycode = key->keycode;
			return 0;
		}
	}

	return -EINVAL;
}

static int sparse_keymap_setkeycode(struct input_dev *dev,
				    unsigned int scancode,
				    unsigned int keycode)
{
	struct key_entry *key;
	int old_keycode;

	if (dev->keycode) {
		key = sparse_keymap_entry_from_scancode(dev, scancode);
		if (key && key->type == KE_KEY) {
			old_keycode = key->keycode;
			key->keycode = keycode;
			set_bit(keycode, dev->keybit);
			if (!sparse_keymap_entry_from_keycode(dev, old_keycode))
				clear_bit(old_keycode, dev->keybit);
			return 0;
		}
	}

	return -EINVAL;
}

/**
 * sparse_keymap_setup - set up sparse keymap for an input device
 * @dev: Input device
 * @keymap: Keymap in form of array of &key_entry structures ending
 *	with %KE_END type entry
 * @setup: Function that can be used to adjust keymap entries
 *	depending on device's deeds, may be %NULL
 *
 * The function calculates size and allocates copy of the original
 * keymap after which sets up input device event bits appropriately.
 * Before destroying input device allocated keymap should be freed
 * with a call to sparse_keymap_free().
 */
int sparse_keymap_setup(struct input_dev *dev,
			const struct key_entry *keymap,
			int (*setup)(struct input_dev *, struct key_entry *))
{
	size_t map_size = 1; /* to account for the last KE_END entry */
	const struct key_entry *e;
	struct key_entry *map, *entry;
	int i;
	int error;

	for (e = keymap; e->type != KE_END; e++)
		map_size++;

	map = kcalloc(map_size, sizeof (struct key_entry), GFP_KERNEL);
	if (!map)
		return -ENOMEM;

	memcpy(map, keymap, map_size * sizeof (struct key_entry));

	for (i = 0; i < map_size; i++) {
		entry = &map[i];

		if (setup) {
			error = setup(dev, entry);
			if (error)
				goto err_out;
		}

		switch (entry->type) {
		case KE_KEY:
			__set_bit(EV_KEY, dev->evbit);
			__set_bit(entry->keycode, dev->keybit);
			break;

		case KE_SW:
			__set_bit(EV_SW, dev->evbit);
			__set_bit(entry->sw.code, dev->swbit);
			break;
		}
	}

	dev->keycode = map;
	dev->keycodemax = map_size;
	dev->getkeycode = sparse_keymap_getkeycode;
	dev->setkeycode = sparse_keymap_setkeycode;

	return 0;

 err_out:
	kfree(map);
	return error;

}
EXPORT_SYMBOL(sparse_keymap_setup);

/**
 * sparse_keymap_free - free memory allocated for sparse keymap
 * @dev: Input device using sparse keymap
 *
 * This function is used to free memory allocated by sparse keymap
 * in an input device that was set up by sparse_keymap_setup().
 * NOTE: It is safe to cal this function while input device is
 * still registered (however the drivers should care not to try to
 * use freed keymap and thus have to shut off interrups/polling
 * before freeing the keymap).
 */
void sparse_keymap_free(struct input_dev *dev)
{
	unsigned long flags;

	/*
	 * Take event lock to prevent racing with input_get_keycode()
	 * and input_set_keycode() if we are called while input device
	 * is still registered.
	 */
	spin_lock_irqsave(&dev->event_lock, flags);

	kfree(dev->keycode);
	dev->keycode = NULL;
	dev->keycodemax = 0;

	spin_unlock_irqrestore(&dev->event_lock, flags);
}
EXPORT_SYMBOL(sparse_keymap_free);

/**
 * sparse_keymap_report_entry - report event corresponding to given key entry
 * @dev: Input device for which event should be reported
 * @ke: key entry describing event
 * @value: Value that should be reported (ignored by %KE_SW entries)
 * @autorelease: Signals whether release event should be emitted for %KE_KEY
 *	entries right after reporting press event, ignored by all other
 *	entries
 *
 * This function is used to report input event described by given
 * &struct key_entry.
 */
void sparse_keymap_report_entry(struct input_dev *dev, const struct key_entry *ke,
				unsigned int value, bool autorelease)
{
	switch (ke->type) {
	case KE_KEY:
		input_report_key(dev, ke->keycode, value);
		input_sync(dev);
		if (value && autorelease) {
			input_report_key(dev, ke->keycode, 0);
			input_sync(dev);
		}
		break;

	case KE_SW:
		value = ke->sw.value;
		/* fall through */

	case KE_VSW:
		input_report_switch(dev, ke->sw.code, value);
		break;
	}
}
EXPORT_SYMBOL(sparse_keymap_report_entry);

/**
 * sparse_keymap_report_event - report event corresponding to given scancode
 * @dev: Input device using sparse keymap
 * @code: Scan code
 * @value: Value that should be reported (ignored by %KE_SW entries)
 * @autorelease: Signals whether release event should be emitted for %KE_KEY
 *	entries right after reporting press event, ignored by all other
 *	entries
 *
 * This function is used to perform lookup in an input device using sparse
 * keymap and report corresponding event. Returns %true if lookup was
 * successful and %false otherwise.
 */
bool sparse_keymap_report_event(struct input_dev *dev, unsigned int code,
				unsigned int value, bool autorelease)
{
	const struct key_entry *ke =
		sparse_keymap_entry_from_scancode(dev, code);

	if (ke) {
		sparse_keymap_report_entry(dev, ke, value, autorelease);
		return true;
	}

	return false;
}
EXPORT_SYMBOL(sparse_keymap_report_event);

