/* ir-register.c - handle IR scancode->keycode tables
 *
 * Copyright (C) 2009 by Mauro Carvalho Chehab <mchehab@redhat.com>
 */

#include <linux/usb/input.h>

#include <media/ir-common.h>

#define IR_TAB_MIN_SIZE	32
#define IR_TAB_MAX_SIZE	1024

/**
 * ir_seek_table() - returns the element order on the table
 * @rc_tab:	the ir_scancode_table with the keymap to be used
 * @scancode:	the scancode that we're seeking
 *
 * This routine is used by the input routines when a key is pressed at the
 * IR. The scancode is received and needs to be converted into a keycode.
 * If the key is not found, it returns KEY_UNKNOWN. Otherwise, returns the
 * corresponding keycode from the table.
 */
static int ir_seek_table(struct ir_scancode_table *rc_tab, u32 scancode)
{
	int rc;
	unsigned long flags;
	struct ir_scancode *keymap = rc_tab->scan;

	spin_lock_irqsave(&rc_tab->lock, flags);

	/* FIXME: replace it by a binary search */

	for (rc = 0; rc < rc_tab->size; rc++)
		if (keymap[rc].scancode == scancode)
			goto exit;

	/* Not found */
	rc = -EINVAL;

exit:
	spin_unlock_irqrestore(&rc_tab->lock, flags);
	return rc;
}

/**
 * ir_roundup_tablesize() - gets an optimum value for the table size
 * @n_elems:		minimum number of entries to store keycodes
 *
 * This routine is used to choose the keycode table size.
 *
 * In order to have some empty space for new keycodes,
 * and knowing in advance that kmalloc allocates only power of two
 * segments, it optimizes the allocated space to have some spare space
 * for those new keycodes by using the maximum number of entries that
 * will be effectively be allocated by kmalloc.
 * In order to reduce the quantity of table resizes, it has a minimum
 * table size of IR_TAB_MIN_SIZE.
 */
int ir_roundup_tablesize(int n_elems)
{
	size_t size;

	if (n_elems < IR_TAB_MIN_SIZE)
		n_elems = IR_TAB_MIN_SIZE;

	/*
	 * As kmalloc only allocates sizes of power of two, get as
	 * much entries as possible for the allocated memory segment
	 */
	size = roundup_pow_of_two(n_elems * sizeof(struct ir_scancode));
	n_elems = size / sizeof(struct ir_scancode);

	return n_elems;
}

/**
 * ir_copy_table() - copies a keytable, discarding the unused entries
 * @destin:	destin table
 * @origin:	origin table
 *
 * Copies all entries where the keycode is not KEY_UNKNOWN/KEY_RESERVED
 */

int ir_copy_table(struct ir_scancode_table *destin,
		 const struct ir_scancode_table *origin)
{
	int i, j = 0;

	for (i = 0; i < origin->size; i++) {
		if (origin->scan[i].keycode == KEY_UNKNOWN ||
		   origin->scan[i].keycode == KEY_RESERVED)
			continue;

		memcpy(&destin->scan[j], &origin->scan[i], sizeof(struct ir_scancode));
		j++;
	}
	destin->size = j;

	IR_dprintk(1, "Copied %d scancodes to the new keycode table\n", destin->size);

	return 0;
}

/**
 * ir_getkeycode() - get a keycode at the evdev scancode ->keycode table
 * @dev:	the struct input_dev device descriptor
 * @scancode:	the desired scancode
 * @keycode:	the keycode to be retorned.
 *
 * This routine is used to handle evdev EVIOCGKEY ioctl.
 * If the key is not found, returns -EINVAL, otherwise, returns 0.
 */
static int ir_getkeycode(struct input_dev *dev,
			 int scancode, int *keycode)
{
	int elem;
	struct ir_scancode_table *rc_tab = input_get_drvdata(dev);

	elem = ir_seek_table(rc_tab, scancode);
	if (elem >= 0) {
		*keycode = rc_tab->scan[elem].keycode;
		return 0;
	}

	/*
	 * Scancode not found and table can't be expanded
	 */
	if (elem < 0 && rc_tab->size == IR_TAB_MAX_SIZE)
		return -EINVAL;

	/*
	 * If is there extra space, returns KEY_RESERVED,
	 * otherwise, input core won't let ir_setkeycode to work
	 */
	*keycode = KEY_RESERVED;
	return 0;
}


/**
 * ir_is_resize_needed() - Check if the table needs rezise
 * @table:		keycode table that may need to resize
 * @n_elems:		minimum number of entries to store keycodes
 *
 * Considering that kmalloc uses power of two storage areas, this
 * routine detects if the real alloced size will change. If not, it
 * just returns without doing nothing. Otherwise, it will extend or
 * reduce the table size to meet the new needs.
 *
 * It returns 0 if no resize is needed, 1 otherwise.
 */
static int ir_is_resize_needed(struct ir_scancode_table *table, int n_elems)
{
	int cur_size = ir_roundup_tablesize(table->size);
	int new_size = ir_roundup_tablesize(n_elems);

	if (cur_size == new_size)
		return 0;

	/* Resize is needed */
	return 1;
}

/**
 * ir_delete_key() - remove a keycode from the table
 * @rc_tab:		keycode table
 * @elem:		element to be removed
 *
 */
static void ir_delete_key(struct ir_scancode_table *rc_tab, int elem)
{
	unsigned long flags = 0;
	int newsize = rc_tab->size - 1;
	int resize = ir_is_resize_needed(rc_tab, newsize);
	struct ir_scancode *oldkeymap = rc_tab->scan;
	struct ir_scancode *newkeymap;

	if (resize) {
		newkeymap = kzalloc(ir_roundup_tablesize(newsize) *
				    sizeof(*newkeymap), GFP_ATOMIC);

		/* There's no memory for resize. Keep the old table */
		if (!newkeymap)
			resize = 0;
	}

	if (!resize) {
		newkeymap = oldkeymap;

		/* We'll modify the live table. Lock it */
		spin_lock_irqsave(&rc_tab->lock, flags);
	}

	/*
	 * Copy the elements before the one that will be deleted
	 * if (!resize), both oldkeymap and newkeymap points
	 * to the same place, so, there's no need to copy
	 */
	if (resize && elem > 0)
		memcpy(newkeymap, oldkeymap,
		       elem * sizeof(*newkeymap));

	/*
	 * Copy the other elements overwriting the element to be removed
	 * This operation applies to both resize and non-resize case
	 */
	if (elem < newsize)
		memcpy(&newkeymap[elem], &oldkeymap[elem + 1],
		       (newsize - elem) * sizeof(*newkeymap));

	if (resize) {
		/*
		 * As the copy happened to a temporary table, only here
		 * it needs to lock while replacing the table pointers
		 * to use the new table
		 */
		spin_lock_irqsave(&rc_tab->lock, flags);
		rc_tab->size = newsize;
		rc_tab->scan = newkeymap;
		spin_unlock_irqrestore(&rc_tab->lock, flags);

		/* Frees the old keytable */
		kfree(oldkeymap);
	} else {
		rc_tab->size = newsize;
		spin_unlock_irqrestore(&rc_tab->lock, flags);
	}
}

/**
 * ir_insert_key() - insert a keycode at the table
 * @rc_tab:		keycode table
 * @scancode:	the desired scancode
 * @keycode:	the keycode to be retorned.
 *
 */
static int ir_insert_key(struct ir_scancode_table *rc_tab,
			  int scancode, int keycode)
{
	unsigned long flags;
	int elem = rc_tab->size;
	int newsize = rc_tab->size + 1;
	int resize = ir_is_resize_needed(rc_tab, newsize);
	struct ir_scancode *oldkeymap = rc_tab->scan;
	struct ir_scancode *newkeymap;

	if (resize) {
		newkeymap = kzalloc(ir_roundup_tablesize(newsize) *
				    sizeof(*newkeymap), GFP_ATOMIC);
		if (!newkeymap)
			return -ENOMEM;

		memcpy(newkeymap, oldkeymap,
		       rc_tab->size * sizeof(*newkeymap));
	} else
		newkeymap  = oldkeymap;

	/* Stores the new code at the table */
	IR_dprintk(1, "#%d: New scan 0x%04x with key 0x%04x\n",
		   rc_tab->size, scancode, keycode);

	spin_lock_irqsave(&rc_tab->lock, flags);
	rc_tab->size = newsize;
	if (resize) {
		rc_tab->scan = newkeymap;
		kfree(oldkeymap);
	}
	newkeymap[elem].scancode = scancode;
	newkeymap[elem].keycode  = keycode;
	spin_unlock_irqrestore(&rc_tab->lock, flags);

	return 0;
}

/**
 * ir_setkeycode() - set a keycode at the evdev scancode ->keycode table
 * @dev:	the struct input_dev device descriptor
 * @scancode:	the desired scancode
 * @keycode:	the keycode to be retorned.
 *
 * This routine is used to handle evdev EVIOCSKEY ioctl.
 * There's one caveat here: how can we increase the size of the table?
 * If the key is not found, returns -EINVAL, otherwise, returns 0.
 */
static int ir_setkeycode(struct input_dev *dev,
			 int scancode, int keycode)
{
	int rc = 0;
	struct ir_scancode_table *rc_tab = input_get_drvdata(dev);
	struct ir_scancode *keymap = rc_tab->scan;
	unsigned long flags;

	/*
	 * Handle keycode table deletions
	 *
	 * If userspace is adding a KEY_UNKNOWN or KEY_RESERVED,
	 * deal as a trial to remove an existing scancode attribution
	 * if table become too big, reduce it to save space
	 */
	if (keycode == KEY_UNKNOWN || keycode == KEY_RESERVED) {
		rc = ir_seek_table(rc_tab, scancode);
		if (rc < 0)
			return 0;

		IR_dprintk(1, "#%d: Deleting scan 0x%04x\n", rc, scancode);
		clear_bit(keymap[rc].keycode, dev->keybit);
		ir_delete_key(rc_tab, rc);

		return 0;
	}

	/*
	 * Handle keycode replacements
	 *
	 * If the scancode exists, just replace by the new value
	 */
	rc = ir_seek_table(rc_tab, scancode);
	if (rc >= 0) {
		IR_dprintk(1, "#%d: Replacing scan 0x%04x with key 0x%04x\n",
			rc, scancode, keycode);

		clear_bit(keymap[rc].keycode, dev->keybit);

		spin_lock_irqsave(&rc_tab->lock, flags);
		keymap[rc].keycode = keycode;
		spin_unlock_irqrestore(&rc_tab->lock, flags);

		set_bit(keycode, dev->keybit);

		return 0;
	}

	/*
	 * Handle new scancode inserts
	 *
	 * reallocate table if needed and insert a new keycode
	 */

	/* Avoid growing the table indefinitely */
	if (rc_tab->size + 1 > IR_TAB_MAX_SIZE)
		return -EINVAL;

	rc = ir_insert_key(rc_tab, scancode, keycode);
	if (rc < 0)
		return rc;
	set_bit(keycode, dev->keybit);

	return 0;
}

/**
 * ir_g_keycode_from_table() - gets the keycode that corresponds to a scancode
 * @input_dev:	the struct input_dev descriptor of the device
 * @scancode:	the scancode that we're seeking
 *
 * This routine is used by the input routines when a key is pressed at the
 * IR. The scancode is received and needs to be converted into a keycode.
 * If the key is not found, it returns KEY_UNKNOWN. Otherwise, returns the
 * corresponding keycode from the table.
 */
u32 ir_g_keycode_from_table(struct input_dev *dev, u32 scancode)
{
	struct ir_scancode_table *rc_tab = input_get_drvdata(dev);
	struct ir_scancode *keymap = rc_tab->scan;
	int elem;

	elem = ir_seek_table(rc_tab, scancode);
	if (elem >= 0) {
		IR_dprintk(1, "%s: scancode 0x%04x keycode 0x%02x\n",
			   dev->name, scancode, keymap[elem].keycode);

		return rc_tab->scan[elem].keycode;
	}

	printk(KERN_INFO "%s: unknown key for scancode 0x%04x\n",
	       dev->name, scancode);

	/* Reports userspace that an unknown keycode were got */
	return KEY_RESERVED;
}

/**
 * ir_set_keycode_table() - sets the IR keycode table and add the handlers
 *			    for keymap table get/set
 * @input_dev:	the struct input_dev descriptor of the device
 * @rc_tab:	the struct ir_scancode_table table of scancode/keymap
 *
 * This routine is used to initialize the input infrastructure to work with
 * an IR.
 * It should be called before registering the IR device.
 */
int ir_set_keycode_table(struct input_dev *input_dev,
			 struct ir_scancode_table *rc_tab)
{
	struct ir_scancode *keymap = rc_tab->scan;
	int i;

	spin_lock_init(&rc_tab->lock);

	if (rc_tab->scan == NULL || !rc_tab->size)
		return -EINVAL;

	/* set the bits for the keys */
	IR_dprintk(1, "key map size: %d\n", rc_tab->size);
	for (i = 0; i < rc_tab->size; i++) {
		IR_dprintk(1, "#%d: setting bit for keycode 0x%04x\n",
			i, keymap[i].keycode);
		set_bit(keymap[i].keycode, input_dev->keybit);
	}

	input_dev->getkeycode = ir_getkeycode;
	input_dev->setkeycode = ir_setkeycode;
	input_set_drvdata(input_dev, rc_tab);

	return 0;
}

void ir_input_free(struct input_dev *dev)
{
	struct ir_scancode_table *rc_tab = input_get_drvdata(dev);

	IR_dprintk(1, "Freed keycode table\n");

	rc_tab->size = 0;
	kfree(rc_tab->scan);
	rc_tab->scan = NULL;
}
EXPORT_SYMBOL_GPL(ir_input_free);

