// SPDX-License-Identifier: GPL-2.0
// rc-main.c - Remote Controller core module
//
// Copyright (C) 2009-2010 by Mauro Carvalho Chehab

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <media/rc-core.h>
#include <linux/bsearch.h>
#include <linux/spinlock.h>
#include <linux/delay.h>
#include <linux/input.h>
#include <linux/leds.h>
#include <linux/slab.h>
#include <linux/idr.h>
#include <linux/device.h>
#include <linux/module.h>
#include "rc-core-priv.h"

/* Sizes are in bytes, 256 bytes allows for 32 entries on x64 */
#define IR_TAB_MIN_SIZE	256
#define IR_TAB_MAX_SIZE	8192

static const struct {
	const char *name;
	unsigned int repeat_period;
	unsigned int scancode_bits;
} protocols[] = {
	[RC_PROTO_UNKNOWN] = { .name = "unknown", .repeat_period = 125 },
	[RC_PROTO_OTHER] = { .name = "other", .repeat_period = 125 },
	[RC_PROTO_RC5] = { .name = "rc-5",
		.scancode_bits = 0x1f7f, .repeat_period = 114 },
	[RC_PROTO_RC5X_20] = { .name = "rc-5x-20",
		.scancode_bits = 0x1f7f3f, .repeat_period = 114 },
	[RC_PROTO_RC5_SZ] = { .name = "rc-5-sz",
		.scancode_bits = 0x2fff, .repeat_period = 114 },
	[RC_PROTO_JVC] = { .name = "jvc",
		.scancode_bits = 0xffff, .repeat_period = 125 },
	[RC_PROTO_SONY12] = { .name = "sony-12",
		.scancode_bits = 0x1f007f, .repeat_period = 100 },
	[RC_PROTO_SONY15] = { .name = "sony-15",
		.scancode_bits = 0xff007f, .repeat_period = 100 },
	[RC_PROTO_SONY20] = { .name = "sony-20",
		.scancode_bits = 0x1fff7f, .repeat_period = 100 },
	[RC_PROTO_NEC] = { .name = "nec",
		.scancode_bits = 0xffff, .repeat_period = 110 },
	[RC_PROTO_NECX] = { .name = "nec-x",
		.scancode_bits = 0xffffff, .repeat_period = 110 },
	[RC_PROTO_NEC32] = { .name = "nec-32",
		.scancode_bits = 0xffffffff, .repeat_period = 110 },
	[RC_PROTO_SANYO] = { .name = "sanyo",
		.scancode_bits = 0x1fffff, .repeat_period = 125 },
	[RC_PROTO_MCIR2_KBD] = { .name = "mcir2-kbd",
		.scancode_bits = 0xffffff, .repeat_period = 100 },
	[RC_PROTO_MCIR2_MSE] = { .name = "mcir2-mse",
		.scancode_bits = 0x1fffff, .repeat_period = 100 },
	[RC_PROTO_RC6_0] = { .name = "rc-6-0",
		.scancode_bits = 0xffff, .repeat_period = 114 },
	[RC_PROTO_RC6_6A_20] = { .name = "rc-6-6a-20",
		.scancode_bits = 0xfffff, .repeat_period = 114 },
	[RC_PROTO_RC6_6A_24] = { .name = "rc-6-6a-24",
		.scancode_bits = 0xffffff, .repeat_period = 114 },
	[RC_PROTO_RC6_6A_32] = { .name = "rc-6-6a-32",
		.scancode_bits = 0xffffffff, .repeat_period = 114 },
	[RC_PROTO_RC6_MCE] = { .name = "rc-6-mce",
		.scancode_bits = 0xffff7fff, .repeat_period = 114 },
	[RC_PROTO_SHARP] = { .name = "sharp",
		.scancode_bits = 0x1fff, .repeat_period = 125 },
	[RC_PROTO_XMP] = { .name = "xmp", .repeat_period = 125 },
	[RC_PROTO_CEC] = { .name = "cec", .repeat_period = 0 },
	[RC_PROTO_IMON] = { .name = "imon",
		.scancode_bits = 0x7fffffff, .repeat_period = 114 },
	[RC_PROTO_RCMM12] = { .name = "rc-mm-12",
		.scancode_bits = 0x00000fff, .repeat_period = 114 },
	[RC_PROTO_RCMM24] = { .name = "rc-mm-24",
		.scancode_bits = 0x00ffffff, .repeat_period = 114 },
	[RC_PROTO_RCMM32] = { .name = "rc-mm-32",
		.scancode_bits = 0xffffffff, .repeat_period = 114 },
};

/* Used to keep track of known keymaps */
static LIST_HEAD(rc_map_list);
static DEFINE_SPINLOCK(rc_map_lock);
static struct led_trigger *led_feedback;

/* Used to keep track of rc devices */
static DEFINE_IDA(rc_ida);

static struct rc_map_list *seek_rc_map(const char *name)
{
	struct rc_map_list *map = NULL;

	spin_lock(&rc_map_lock);
	list_for_each_entry(map, &rc_map_list, list) {
		if (!strcmp(name, map->map.name)) {
			spin_unlock(&rc_map_lock);
			return map;
		}
	}
	spin_unlock(&rc_map_lock);

	return NULL;
}

struct rc_map *rc_map_get(const char *name)
{

	struct rc_map_list *map;

	map = seek_rc_map(name);
#ifdef CONFIG_MODULES
	if (!map) {
		int rc = request_module("%s", name);
		if (rc < 0) {
			pr_err("Couldn't load IR keymap %s\n", name);
			return NULL;
		}
		msleep(20);	/* Give some time for IR to register */

		map = seek_rc_map(name);
	}
#endif
	if (!map) {
		pr_err("IR keymap %s not found\n", name);
		return NULL;
	}

	printk(KERN_INFO "Registered IR keymap %s\n", map->map.name);

	return &map->map;
}
EXPORT_SYMBOL_GPL(rc_map_get);

int rc_map_register(struct rc_map_list *map)
{
	spin_lock(&rc_map_lock);
	list_add_tail(&map->list, &rc_map_list);
	spin_unlock(&rc_map_lock);
	return 0;
}
EXPORT_SYMBOL_GPL(rc_map_register);

void rc_map_unregister(struct rc_map_list *map)
{
	spin_lock(&rc_map_lock);
	list_del(&map->list);
	spin_unlock(&rc_map_lock);
}
EXPORT_SYMBOL_GPL(rc_map_unregister);


static struct rc_map_table empty[] = {
	{ 0x2a, KEY_COFFEE },
};

static struct rc_map_list empty_map = {
	.map = {
		.scan     = empty,
		.size     = ARRAY_SIZE(empty),
		.rc_proto = RC_PROTO_UNKNOWN,	/* Legacy IR type */
		.name     = RC_MAP_EMPTY,
	}
};

/**
 * ir_create_table() - initializes a scancode table
 * @dev:	the rc_dev device
 * @rc_map:	the rc_map to initialize
 * @name:	name to assign to the table
 * @rc_proto:	ir type to assign to the new table
 * @size:	initial size of the table
 *
 * This routine will initialize the rc_map and will allocate
 * memory to hold at least the specified number of elements.
 *
 * return:	zero on success or a negative error code
 */
static int ir_create_table(struct rc_dev *dev, struct rc_map *rc_map,
			   const char *name, u64 rc_proto, size_t size)
{
	rc_map->name = kstrdup(name, GFP_KERNEL);
	if (!rc_map->name)
		return -ENOMEM;
	rc_map->rc_proto = rc_proto;
	rc_map->alloc = roundup_pow_of_two(size * sizeof(struct rc_map_table));
	rc_map->size = rc_map->alloc / sizeof(struct rc_map_table);
	rc_map->scan = kmalloc(rc_map->alloc, GFP_KERNEL);
	if (!rc_map->scan) {
		kfree(rc_map->name);
		rc_map->name = NULL;
		return -ENOMEM;
	}

	dev_dbg(&dev->dev, "Allocated space for %u keycode entries (%u bytes)\n",
		rc_map->size, rc_map->alloc);
	return 0;
}

/**
 * ir_free_table() - frees memory allocated by a scancode table
 * @rc_map:	the table whose mappings need to be freed
 *
 * This routine will free memory alloctaed for key mappings used by given
 * scancode table.
 */
static void ir_free_table(struct rc_map *rc_map)
{
	rc_map->size = 0;
	kfree(rc_map->name);
	rc_map->name = NULL;
	kfree(rc_map->scan);
	rc_map->scan = NULL;
}

/**
 * ir_resize_table() - resizes a scancode table if necessary
 * @dev:	the rc_dev device
 * @rc_map:	the rc_map to resize
 * @gfp_flags:	gfp flags to use when allocating memory
 *
 * This routine will shrink the rc_map if it has lots of
 * unused entries and grow it if it is full.
 *
 * return:	zero on success or a negative error code
 */
static int ir_resize_table(struct rc_dev *dev, struct rc_map *rc_map,
			   gfp_t gfp_flags)
{
	unsigned int oldalloc = rc_map->alloc;
	unsigned int newalloc = oldalloc;
	struct rc_map_table *oldscan = rc_map->scan;
	struct rc_map_table *newscan;

	if (rc_map->size == rc_map->len) {
		/* All entries in use -> grow keytable */
		if (rc_map->alloc >= IR_TAB_MAX_SIZE)
			return -ENOMEM;

		newalloc *= 2;
		dev_dbg(&dev->dev, "Growing table to %u bytes\n", newalloc);
	}

	if ((rc_map->len * 3 < rc_map->size) && (oldalloc > IR_TAB_MIN_SIZE)) {
		/* Less than 1/3 of entries in use -> shrink keytable */
		newalloc /= 2;
		dev_dbg(&dev->dev, "Shrinking table to %u bytes\n", newalloc);
	}

	if (newalloc == oldalloc)
		return 0;

	newscan = kmalloc(newalloc, gfp_flags);
	if (!newscan)
		return -ENOMEM;

	memcpy(newscan, rc_map->scan, rc_map->len * sizeof(struct rc_map_table));
	rc_map->scan = newscan;
	rc_map->alloc = newalloc;
	rc_map->size = rc_map->alloc / sizeof(struct rc_map_table);
	kfree(oldscan);
	return 0;
}

/**
 * ir_update_mapping() - set a keycode in the scancode->keycode table
 * @dev:	the struct rc_dev device descriptor
 * @rc_map:	scancode table to be adjusted
 * @index:	index of the mapping that needs to be updated
 * @new_keycode: the desired keycode
 *
 * This routine is used to update scancode->keycode mapping at given
 * position.
 *
 * return:	previous keycode assigned to the mapping
 *
 */
static unsigned int ir_update_mapping(struct rc_dev *dev,
				      struct rc_map *rc_map,
				      unsigned int index,
				      unsigned int new_keycode)
{
	int old_keycode = rc_map->scan[index].keycode;

	/* Did the user wish to remove the mapping? */
	if (new_keycode == KEY_RESERVED || new_keycode == KEY_UNKNOWN) {
		dev_dbg(&dev->dev, "#%d: Deleting scan 0x%04x\n",
			index, rc_map->scan[index].scancode);
		rc_map->len--;
		memmove(&rc_map->scan[index], &rc_map->scan[index+ 1],
			(rc_map->len - index) * sizeof(struct rc_map_table));
	} else {
		dev_dbg(&dev->dev, "#%d: %s scan 0x%04x with key 0x%04x\n",
			index,
			old_keycode == KEY_RESERVED ? "New" : "Replacing",
			rc_map->scan[index].scancode, new_keycode);
		rc_map->scan[index].keycode = new_keycode;
	}

	if (old_keycode != KEY_RESERVED) {
		/* Possibly shrink the keytable, failure is not a problem */
		ir_resize_table(dev, rc_map, GFP_ATOMIC);
	}

	return old_keycode;
}

/**
 * ir_establish_scancode() - set a keycode in the scancode->keycode table
 * @dev:	the struct rc_dev device descriptor
 * @rc_map:	scancode table to be searched
 * @scancode:	the desired scancode
 * @resize:	controls whether we allowed to resize the table to
 *		accommodate not yet present scancodes
 *
 * This routine is used to locate given scancode in rc_map.
 * If scancode is not yet present the routine will allocate a new slot
 * for it.
 *
 * return:	index of the mapping containing scancode in question
 *		or -1U in case of failure.
 */
static unsigned int ir_establish_scancode(struct rc_dev *dev,
					  struct rc_map *rc_map,
					  unsigned int scancode,
					  bool resize)
{
	unsigned int i;

	/*
	 * Unfortunately, some hardware-based IR decoders don't provide
	 * all bits for the complete IR code. In general, they provide only
	 * the command part of the IR code. Yet, as it is possible to replace
	 * the provided IR with another one, it is needed to allow loading
	 * IR tables from other remotes. So, we support specifying a mask to
	 * indicate the valid bits of the scancodes.
	 */
	if (dev->scancode_mask)
		scancode &= dev->scancode_mask;

	/* First check if we already have a mapping for this ir command */
	for (i = 0; i < rc_map->len; i++) {
		if (rc_map->scan[i].scancode == scancode)
			return i;

		/* Keytable is sorted from lowest to highest scancode */
		if (rc_map->scan[i].scancode >= scancode)
			break;
	}

	/* No previous mapping found, we might need to grow the table */
	if (rc_map->size == rc_map->len) {
		if (!resize || ir_resize_table(dev, rc_map, GFP_ATOMIC))
			return -1U;
	}

	/* i is the proper index to insert our new keycode */
	if (i < rc_map->len)
		memmove(&rc_map->scan[i + 1], &rc_map->scan[i],
			(rc_map->len - i) * sizeof(struct rc_map_table));
	rc_map->scan[i].scancode = scancode;
	rc_map->scan[i].keycode = KEY_RESERVED;
	rc_map->len++;

	return i;
}

/**
 * ir_setkeycode() - set a keycode in the scancode->keycode table
 * @idev:	the struct input_dev device descriptor
 * @ke:		Input keymap entry
 * @old_keycode: result
 *
 * This routine is used to handle evdev EVIOCSKEY ioctl.
 *
 * return:	-EINVAL if the keycode could not be inserted, otherwise zero.
 */
static int ir_setkeycode(struct input_dev *idev,
			 const struct input_keymap_entry *ke,
			 unsigned int *old_keycode)
{
	struct rc_dev *rdev = input_get_drvdata(idev);
	struct rc_map *rc_map = &rdev->rc_map;
	unsigned int index;
	unsigned int scancode;
	int retval = 0;
	unsigned long flags;

	spin_lock_irqsave(&rc_map->lock, flags);

	if (ke->flags & INPUT_KEYMAP_BY_INDEX) {
		index = ke->index;
		if (index >= rc_map->len) {
			retval = -EINVAL;
			goto out;
		}
	} else {
		retval = input_scancode_to_scalar(ke, &scancode);
		if (retval)
			goto out;

		index = ir_establish_scancode(rdev, rc_map, scancode, true);
		if (index >= rc_map->len) {
			retval = -ENOMEM;
			goto out;
		}
	}

	*old_keycode = ir_update_mapping(rdev, rc_map, index, ke->keycode);

out:
	spin_unlock_irqrestore(&rc_map->lock, flags);
	return retval;
}

/**
 * ir_setkeytable() - sets several entries in the scancode->keycode table
 * @dev:	the struct rc_dev device descriptor
 * @from:	the struct rc_map to copy entries from
 *
 * This routine is used to handle table initialization.
 *
 * return:	-ENOMEM if all keycodes could not be inserted, otherwise zero.
 */
static int ir_setkeytable(struct rc_dev *dev,
			  const struct rc_map *from)
{
	struct rc_map *rc_map = &dev->rc_map;
	unsigned int i, index;
	int rc;

	rc = ir_create_table(dev, rc_map, from->name, from->rc_proto,
			     from->size);
	if (rc)
		return rc;

	for (i = 0; i < from->size; i++) {
		index = ir_establish_scancode(dev, rc_map,
					      from->scan[i].scancode, false);
		if (index >= rc_map->len) {
			rc = -ENOMEM;
			break;
		}

		ir_update_mapping(dev, rc_map, index,
				  from->scan[i].keycode);
	}

	if (rc)
		ir_free_table(rc_map);

	return rc;
}

static int rc_map_cmp(const void *key, const void *elt)
{
	const unsigned int *scancode = key;
	const struct rc_map_table *e = elt;

	if (*scancode < e->scancode)
		return -1;
	else if (*scancode > e->scancode)
		return 1;
	return 0;
}

/**
 * ir_lookup_by_scancode() - locate mapping by scancode
 * @rc_map:	the struct rc_map to search
 * @scancode:	scancode to look for in the table
 *
 * This routine performs binary search in RC keykeymap table for
 * given scancode.
 *
 * return:	index in the table, -1U if not found
 */
static unsigned int ir_lookup_by_scancode(const struct rc_map *rc_map,
					  unsigned int scancode)
{
	struct rc_map_table *res;

	res = bsearch(&scancode, rc_map->scan, rc_map->len,
		      sizeof(struct rc_map_table), rc_map_cmp);
	if (!res)
		return -1U;
	else
		return res - rc_map->scan;
}

/**
 * ir_getkeycode() - get a keycode from the scancode->keycode table
 * @idev:	the struct input_dev device descriptor
 * @ke:		Input keymap entry
 *
 * This routine is used to handle evdev EVIOCGKEY ioctl.
 *
 * return:	always returns zero.
 */
static int ir_getkeycode(struct input_dev *idev,
			 struct input_keymap_entry *ke)
{
	struct rc_dev *rdev = input_get_drvdata(idev);
	struct rc_map *rc_map = &rdev->rc_map;
	struct rc_map_table *entry;
	unsigned long flags;
	unsigned int index;
	unsigned int scancode;
	int retval;

	spin_lock_irqsave(&rc_map->lock, flags);

	if (ke->flags & INPUT_KEYMAP_BY_INDEX) {
		index = ke->index;
	} else {
		retval = input_scancode_to_scalar(ke, &scancode);
		if (retval)
			goto out;

		index = ir_lookup_by_scancode(rc_map, scancode);
	}

	if (index < rc_map->len) {
		entry = &rc_map->scan[index];

		ke->index = index;
		ke->keycode = entry->keycode;
		ke->len = sizeof(entry->scancode);
		memcpy(ke->scancode, &entry->scancode, sizeof(entry->scancode));

	} else if (!(ke->flags & INPUT_KEYMAP_BY_INDEX)) {
		/*
		 * We do not really know the valid range of scancodes
		 * so let's respond with KEY_RESERVED to anything we
		 * do not have mapping for [yet].
		 */
		ke->index = index;
		ke->keycode = KEY_RESERVED;
	} else {
		retval = -EINVAL;
		goto out;
	}

	retval = 0;

out:
	spin_unlock_irqrestore(&rc_map->lock, flags);
	return retval;
}

/**
 * rc_g_keycode_from_table() - gets the keycode that corresponds to a scancode
 * @dev:	the struct rc_dev descriptor of the device
 * @scancode:	the scancode to look for
 *
 * This routine is used by drivers which need to convert a scancode to a
 * keycode. Normally it should not be used since drivers should have no
 * interest in keycodes.
 *
 * return:	the corresponding keycode, or KEY_RESERVED
 */
u32 rc_g_keycode_from_table(struct rc_dev *dev, u32 scancode)
{
	struct rc_map *rc_map = &dev->rc_map;
	unsigned int keycode;
	unsigned int index;
	unsigned long flags;

	spin_lock_irqsave(&rc_map->lock, flags);

	index = ir_lookup_by_scancode(rc_map, scancode);
	keycode = index < rc_map->len ?
			rc_map->scan[index].keycode : KEY_RESERVED;

	spin_unlock_irqrestore(&rc_map->lock, flags);

	if (keycode != KEY_RESERVED)
		dev_dbg(&dev->dev, "%s: scancode 0x%04x keycode 0x%02x\n",
			dev->device_name, scancode, keycode);

	return keycode;
}
EXPORT_SYMBOL_GPL(rc_g_keycode_from_table);

/**
 * ir_do_keyup() - internal function to signal the release of a keypress
 * @dev:	the struct rc_dev descriptor of the device
 * @sync:	whether or not to call input_sync
 *
 * This function is used internally to release a keypress, it must be
 * called with keylock held.
 */
static void ir_do_keyup(struct rc_dev *dev, bool sync)
{
	if (!dev->keypressed)
		return;

	dev_dbg(&dev->dev, "keyup key 0x%04x\n", dev->last_keycode);
	del_timer(&dev->timer_repeat);
	input_report_key(dev->input_dev, dev->last_keycode, 0);
	led_trigger_event(led_feedback, LED_OFF);
	if (sync)
		input_sync(dev->input_dev);
	dev->keypressed = false;
}

/**
 * rc_keyup() - signals the release of a keypress
 * @dev:	the struct rc_dev descriptor of the device
 *
 * This routine is used to signal that a key has been released on the
 * remote control.
 */
void rc_keyup(struct rc_dev *dev)
{
	unsigned long flags;

	spin_lock_irqsave(&dev->keylock, flags);
	ir_do_keyup(dev, true);
	spin_unlock_irqrestore(&dev->keylock, flags);
}
EXPORT_SYMBOL_GPL(rc_keyup);

/**
 * ir_timer_keyup() - generates a keyup event after a timeout
 *
 * @t:		a pointer to the struct timer_list
 *
 * This routine will generate a keyup event some time after a keydown event
 * is generated when no further activity has been detected.
 */
static void ir_timer_keyup(struct timer_list *t)
{
	struct rc_dev *dev = from_timer(dev, t, timer_keyup);
	unsigned long flags;

	/*
	 * ir->keyup_jiffies is used to prevent a race condition if a
	 * hardware interrupt occurs at this point and the keyup timer
	 * event is moved further into the future as a result.
	 *
	 * The timer will then be reactivated and this function called
	 * again in the future. We need to exit gracefully in that case
	 * to allow the input subsystem to do its auto-repeat magic or
	 * a keyup event might follow immediately after the keydown.
	 */
	spin_lock_irqsave(&dev->keylock, flags);
	if (time_is_before_eq_jiffies(dev->keyup_jiffies))
		ir_do_keyup(dev, true);
	spin_unlock_irqrestore(&dev->keylock, flags);
}

/**
 * ir_timer_repeat() - generates a repeat event after a timeout
 *
 * @t:		a pointer to the struct timer_list
 *
 * This routine will generate a soft repeat event every REP_PERIOD
 * milliseconds.
 */
static void ir_timer_repeat(struct timer_list *t)
{
	struct rc_dev *dev = from_timer(dev, t, timer_repeat);
	struct input_dev *input = dev->input_dev;
	unsigned long flags;

	spin_lock_irqsave(&dev->keylock, flags);
	if (dev->keypressed) {
		input_event(input, EV_KEY, dev->last_keycode, 2);
		input_sync(input);
		if (input->rep[REP_PERIOD])
			mod_timer(&dev->timer_repeat, jiffies +
				  msecs_to_jiffies(input->rep[REP_PERIOD]));
	}
	spin_unlock_irqrestore(&dev->keylock, flags);
}

static unsigned int repeat_period(int protocol)
{
	if (protocol >= ARRAY_SIZE(protocols))
		return 100;

	return protocols[protocol].repeat_period;
}

/**
 * rc_repeat() - signals that a key is still pressed
 * @dev:	the struct rc_dev descriptor of the device
 *
 * This routine is used by IR decoders when a repeat message which does
 * not include the necessary bits to reproduce the scancode has been
 * received.
 */
void rc_repeat(struct rc_dev *dev)
{
	unsigned long flags;
	unsigned int timeout = nsecs_to_jiffies(dev->timeout) +
		msecs_to_jiffies(repeat_period(dev->last_protocol));
	struct lirc_scancode sc = {
		.scancode = dev->last_scancode, .rc_proto = dev->last_protocol,
		.keycode = dev->keypressed ? dev->last_keycode : KEY_RESERVED,
		.flags = LIRC_SCANCODE_FLAG_REPEAT |
			 (dev->last_toggle ? LIRC_SCANCODE_FLAG_TOGGLE : 0)
	};

	if (dev->allowed_protocols != RC_PROTO_BIT_CEC)
		ir_lirc_scancode_event(dev, &sc);

	spin_lock_irqsave(&dev->keylock, flags);

	input_event(dev->input_dev, EV_MSC, MSC_SCAN, dev->last_scancode);
	input_sync(dev->input_dev);

	if (dev->keypressed) {
		dev->keyup_jiffies = jiffies + timeout;
		mod_timer(&dev->timer_keyup, dev->keyup_jiffies);
	}

	spin_unlock_irqrestore(&dev->keylock, flags);
}
EXPORT_SYMBOL_GPL(rc_repeat);

/**
 * ir_do_keydown() - internal function to process a keypress
 * @dev:	the struct rc_dev descriptor of the device
 * @protocol:	the protocol of the keypress
 * @scancode:   the scancode of the keypress
 * @keycode:    the keycode of the keypress
 * @toggle:     the toggle value of the keypress
 *
 * This function is used internally to register a keypress, it must be
 * called with keylock held.
 */
static void ir_do_keydown(struct rc_dev *dev, enum rc_proto protocol,
			  u32 scancode, u32 keycode, u8 toggle)
{
	bool new_event = (!dev->keypressed		 ||
			  dev->last_protocol != protocol ||
			  dev->last_scancode != scancode ||
			  dev->last_toggle   != toggle);
	struct lirc_scancode sc = {
		.scancode = scancode, .rc_proto = protocol,
		.flags = toggle ? LIRC_SCANCODE_FLAG_TOGGLE : 0,
		.keycode = keycode
	};

	if (dev->allowed_protocols != RC_PROTO_BIT_CEC)
		ir_lirc_scancode_event(dev, &sc);

	if (new_event && dev->keypressed)
		ir_do_keyup(dev, false);

	input_event(dev->input_dev, EV_MSC, MSC_SCAN, scancode);

	dev->last_protocol = protocol;
	dev->last_scancode = scancode;
	dev->last_toggle = toggle;
	dev->last_keycode = keycode;

	if (new_event && keycode != KEY_RESERVED) {
		/* Register a keypress */
		dev->keypressed = true;

		dev_dbg(&dev->dev, "%s: key down event, key 0x%04x, protocol 0x%04x, scancode 0x%08x\n",
			dev->device_name, keycode, protocol, scancode);
		input_report_key(dev->input_dev, keycode, 1);

		led_trigger_event(led_feedback, LED_FULL);
	}

	/*
	 * For CEC, start sending repeat messages as soon as the first
	 * repeated message is sent, as long as REP_DELAY = 0 and REP_PERIOD
	 * is non-zero. Otherwise, the input layer will generate repeat
	 * messages.
	 */
	if (!new_event && keycode != KEY_RESERVED &&
	    dev->allowed_protocols == RC_PROTO_BIT_CEC &&
	    !timer_pending(&dev->timer_repeat) &&
	    dev->input_dev->rep[REP_PERIOD] &&
	    !dev->input_dev->rep[REP_DELAY]) {
		input_event(dev->input_dev, EV_KEY, keycode, 2);
		mod_timer(&dev->timer_repeat, jiffies +
			  msecs_to_jiffies(dev->input_dev->rep[REP_PERIOD]));
	}

	input_sync(dev->input_dev);
}

/**
 * rc_keydown() - generates input event for a key press
 * @dev:	the struct rc_dev descriptor of the device
 * @protocol:	the protocol for the keypress
 * @scancode:	the scancode for the keypress
 * @toggle:     the toggle value (protocol dependent, if the protocol doesn't
 *              support toggle values, this should be set to zero)
 *
 * This routine is used to signal that a key has been pressed on the
 * remote control.
 */
void rc_keydown(struct rc_dev *dev, enum rc_proto protocol, u32 scancode,
		u8 toggle)
{
	unsigned long flags;
	u32 keycode = rc_g_keycode_from_table(dev, scancode);

	spin_lock_irqsave(&dev->keylock, flags);
	ir_do_keydown(dev, protocol, scancode, keycode, toggle);

	if (dev->keypressed) {
		dev->keyup_jiffies = jiffies + nsecs_to_jiffies(dev->timeout) +
			msecs_to_jiffies(repeat_period(protocol));
		mod_timer(&dev->timer_keyup, dev->keyup_jiffies);
	}
	spin_unlock_irqrestore(&dev->keylock, flags);
}
EXPORT_SYMBOL_GPL(rc_keydown);

/**
 * rc_keydown_notimeout() - generates input event for a key press without
 *                          an automatic keyup event at a later time
 * @dev:	the struct rc_dev descriptor of the device
 * @protocol:	the protocol for the keypress
 * @scancode:	the scancode for the keypress
 * @toggle:     the toggle value (protocol dependent, if the protocol doesn't
 *              support toggle values, this should be set to zero)
 *
 * This routine is used to signal that a key has been pressed on the
 * remote control. The driver must manually call rc_keyup() at a later stage.
 */
void rc_keydown_notimeout(struct rc_dev *dev, enum rc_proto protocol,
			  u32 scancode, u8 toggle)
{
	unsigned long flags;
	u32 keycode = rc_g_keycode_from_table(dev, scancode);

	spin_lock_irqsave(&dev->keylock, flags);
	ir_do_keydown(dev, protocol, scancode, keycode, toggle);
	spin_unlock_irqrestore(&dev->keylock, flags);
}
EXPORT_SYMBOL_GPL(rc_keydown_notimeout);

/**
 * rc_validate_scancode() - checks that a scancode is valid for a protocol.
 *	For nec, it should do the opposite of ir_nec_bytes_to_scancode()
 * @proto:	protocol
 * @scancode:	scancode
 */
bool rc_validate_scancode(enum rc_proto proto, u32 scancode)
{
	switch (proto) {
	/*
	 * NECX has a 16-bit address; if the lower 8 bits match the upper
	 * 8 bits inverted, then the address would match regular nec.
	 */
	case RC_PROTO_NECX:
		if ((((scancode >> 16) ^ ~(scancode >> 8)) & 0xff) == 0)
			return false;
		break;
	/*
	 * NEC32 has a 16 bit address and 16 bit command. If the lower 8 bits
	 * of the command match the upper 8 bits inverted, then it would
	 * be either NEC or NECX.
	 */
	case RC_PROTO_NEC32:
		if ((((scancode >> 8) ^ ~scancode) & 0xff) == 0)
			return false;
		break;
	/*
	 * If the customer code (top 32-bit) is 0x800f, it is MCE else it
	 * is regular mode-6a 32 bit
	 */
	case RC_PROTO_RC6_MCE:
		if ((scancode & 0xffff0000) != 0x800f0000)
			return false;
		break;
	case RC_PROTO_RC6_6A_32:
		if ((scancode & 0xffff0000) == 0x800f0000)
			return false;
		break;
	default:
		break;
	}

	return true;
}

/**
 * rc_validate_filter() - checks that the scancode and mask are valid and
 *			  provides sensible defaults
 * @dev:	the struct rc_dev descriptor of the device
 * @filter:	the scancode and mask
 *
 * return:	0 or -EINVAL if the filter is not valid
 */
static int rc_validate_filter(struct rc_dev *dev,
			      struct rc_scancode_filter *filter)
{
	u32 mask, s = filter->data;
	enum rc_proto protocol = dev->wakeup_protocol;

	if (protocol >= ARRAY_SIZE(protocols))
		return -EINVAL;

	mask = protocols[protocol].scancode_bits;

	if (!rc_validate_scancode(protocol, s))
		return -EINVAL;

	filter->data &= mask;
	filter->mask &= mask;

	/*
	 * If we have to raw encode the IR for wakeup, we cannot have a mask
	 */
	if (dev->encode_wakeup && filter->mask != 0 && filter->mask != mask)
		return -EINVAL;

	return 0;
}

int rc_open(struct rc_dev *rdev)
{
	int rval = 0;

	if (!rdev)
		return -EINVAL;

	mutex_lock(&rdev->lock);

	if (!rdev->registered) {
		rval = -ENODEV;
	} else {
		if (!rdev->users++ && rdev->open)
			rval = rdev->open(rdev);

		if (rval)
			rdev->users--;
	}

	mutex_unlock(&rdev->lock);

	return rval;
}

static int ir_open(struct input_dev *idev)
{
	struct rc_dev *rdev = input_get_drvdata(idev);

	return rc_open(rdev);
}

void rc_close(struct rc_dev *rdev)
{
	if (rdev) {
		mutex_lock(&rdev->lock);

		if (!--rdev->users && rdev->close && rdev->registered)
			rdev->close(rdev);

		mutex_unlock(&rdev->lock);
	}
}

static void ir_close(struct input_dev *idev)
{
	struct rc_dev *rdev = input_get_drvdata(idev);
	rc_close(rdev);
}

/* class for /sys/class/rc */
static char *rc_devnode(struct device *dev, umode_t *mode)
{
	return kasprintf(GFP_KERNEL, "rc/%s", dev_name(dev));
}

static struct class rc_class = {
	.name		= "rc",
	.devnode	= rc_devnode,
};

/*
 * These are the protocol textual descriptions that are
 * used by the sysfs protocols file. Note that the order
 * of the entries is relevant.
 */
static const struct {
	u64	type;
	const char	*name;
	const char	*module_name;
} proto_names[] = {
	{ RC_PROTO_BIT_NONE,	"none",		NULL			},
	{ RC_PROTO_BIT_OTHER,	"other",	NULL			},
	{ RC_PROTO_BIT_UNKNOWN,	"unknown",	NULL			},
	{ RC_PROTO_BIT_RC5 |
	  RC_PROTO_BIT_RC5X_20,	"rc-5",		"ir-rc5-decoder"	},
	{ RC_PROTO_BIT_NEC |
	  RC_PROTO_BIT_NECX |
	  RC_PROTO_BIT_NEC32,	"nec",		"ir-nec-decoder"	},
	{ RC_PROTO_BIT_RC6_0 |
	  RC_PROTO_BIT_RC6_6A_20 |
	  RC_PROTO_BIT_RC6_6A_24 |
	  RC_PROTO_BIT_RC6_6A_32 |
	  RC_PROTO_BIT_RC6_MCE,	"rc-6",		"ir-rc6-decoder"	},
	{ RC_PROTO_BIT_JVC,	"jvc",		"ir-jvc-decoder"	},
	{ RC_PROTO_BIT_SONY12 |
	  RC_PROTO_BIT_SONY15 |
	  RC_PROTO_BIT_SONY20,	"sony",		"ir-sony-decoder"	},
	{ RC_PROTO_BIT_RC5_SZ,	"rc-5-sz",	"ir-rc5-decoder"	},
	{ RC_PROTO_BIT_SANYO,	"sanyo",	"ir-sanyo-decoder"	},
	{ RC_PROTO_BIT_SHARP,	"sharp",	"ir-sharp-decoder"	},
	{ RC_PROTO_BIT_MCIR2_KBD |
	  RC_PROTO_BIT_MCIR2_MSE, "mce_kbd",	"ir-mce_kbd-decoder"	},
	{ RC_PROTO_BIT_XMP,	"xmp",		"ir-xmp-decoder"	},
	{ RC_PROTO_BIT_CEC,	"cec",		NULL			},
	{ RC_PROTO_BIT_IMON,	"imon",		"ir-imon-decoder"	},
	{ RC_PROTO_BIT_RCMM12 |
	  RC_PROTO_BIT_RCMM24 |
	  RC_PROTO_BIT_RCMM32,	"rc-mm",	"ir-rcmm-decoder"	},
};

/**
 * struct rc_filter_attribute - Device attribute relating to a filter type.
 * @attr:	Device attribute.
 * @type:	Filter type.
 * @mask:	false for filter value, true for filter mask.
 */
struct rc_filter_attribute {
	struct device_attribute		attr;
	enum rc_filter_type		type;
	bool				mask;
};
#define to_rc_filter_attr(a) container_of(a, struct rc_filter_attribute, attr)

#define RC_FILTER_ATTR(_name, _mode, _show, _store, _type, _mask)	\
	struct rc_filter_attribute dev_attr_##_name = {			\
		.attr = __ATTR(_name, _mode, _show, _store),		\
		.type = (_type),					\
		.mask = (_mask),					\
	}

/**
 * show_protocols() - shows the current IR protocol(s)
 * @device:	the device descriptor
 * @mattr:	the device attribute struct
 * @buf:	a pointer to the output buffer
 *
 * This routine is a callback routine for input read the IR protocol type(s).
 * it is trigged by reading /sys/class/rc/rc?/protocols.
 * It returns the protocol names of supported protocols.
 * Enabled protocols are printed in brackets.
 *
 * dev->lock is taken to guard against races between
 * store_protocols and show_protocols.
 */
static ssize_t show_protocols(struct device *device,
			      struct device_attribute *mattr, char *buf)
{
	struct rc_dev *dev = to_rc_dev(device);
	u64 allowed, enabled;
	char *tmp = buf;
	int i;

	mutex_lock(&dev->lock);

	enabled = dev->enabled_protocols;
	allowed = dev->allowed_protocols;
	if (dev->raw && !allowed)
		allowed = ir_raw_get_allowed_protocols();

	mutex_unlock(&dev->lock);

	dev_dbg(&dev->dev, "%s: allowed - 0x%llx, enabled - 0x%llx\n",
		__func__, (long long)allowed, (long long)enabled);

	for (i = 0; i < ARRAY_SIZE(proto_names); i++) {
		if (allowed & enabled & proto_names[i].type)
			tmp += sprintf(tmp, "[%s] ", proto_names[i].name);
		else if (allowed & proto_names[i].type)
			tmp += sprintf(tmp, "%s ", proto_names[i].name);

		if (allowed & proto_names[i].type)
			allowed &= ~proto_names[i].type;
	}

#ifdef CONFIG_LIRC
	if (dev->driver_type == RC_DRIVER_IR_RAW)
		tmp += sprintf(tmp, "[lirc] ");
#endif

	if (tmp != buf)
		tmp--;
	*tmp = '\n';

	return tmp + 1 - buf;
}

/**
 * parse_protocol_change() - parses a protocol change request
 * @dev:	rc_dev device
 * @protocols:	pointer to the bitmask of current protocols
 * @buf:	pointer to the buffer with a list of changes
 *
 * Writing "+proto" will add a protocol to the protocol mask.
 * Writing "-proto" will remove a protocol from protocol mask.
 * Writing "proto" will enable only "proto".
 * Writing "none" will disable all protocols.
 * Returns the number of changes performed or a negative error code.
 */
static int parse_protocol_change(struct rc_dev *dev, u64 *protocols,
				 const char *buf)
{
	const char *tmp;
	unsigned count = 0;
	bool enable, disable;
	u64 mask;
	int i;

	while ((tmp = strsep((char **)&buf, " \n")) != NULL) {
		if (!*tmp)
			break;

		if (*tmp == '+') {
			enable = true;
			disable = false;
			tmp++;
		} else if (*tmp == '-') {
			enable = false;
			disable = true;
			tmp++;
		} else {
			enable = false;
			disable = false;
		}

		for (i = 0; i < ARRAY_SIZE(proto_names); i++) {
			if (!strcasecmp(tmp, proto_names[i].name)) {
				mask = proto_names[i].type;
				break;
			}
		}

		if (i == ARRAY_SIZE(proto_names)) {
			if (!strcasecmp(tmp, "lirc"))
				mask = 0;
			else {
				dev_dbg(&dev->dev, "Unknown protocol: '%s'\n",
					tmp);
				return -EINVAL;
			}
		}

		count++;

		if (enable)
			*protocols |= mask;
		else if (disable)
			*protocols &= ~mask;
		else
			*protocols = mask;
	}

	if (!count) {
		dev_dbg(&dev->dev, "Protocol not specified\n");
		return -EINVAL;
	}

	return count;
}

void ir_raw_load_modules(u64 *protocols)
{
	u64 available;
	int i, ret;

	for (i = 0; i < ARRAY_SIZE(proto_names); i++) {
		if (proto_names[i].type == RC_PROTO_BIT_NONE ||
		    proto_names[i].type & (RC_PROTO_BIT_OTHER |
					   RC_PROTO_BIT_UNKNOWN))
			continue;

		available = ir_raw_get_allowed_protocols();
		if (!(*protocols & proto_names[i].type & ~available))
			continue;

		if (!proto_names[i].module_name) {
			pr_err("Can't enable IR protocol %s\n",
			       proto_names[i].name);
			*protocols &= ~proto_names[i].type;
			continue;
		}

		ret = request_module("%s", proto_names[i].module_name);
		if (ret < 0) {
			pr_err("Couldn't load IR protocol module %s\n",
			       proto_names[i].module_name);
			*protocols &= ~proto_names[i].type;
			continue;
		}
		msleep(20);
		available = ir_raw_get_allowed_protocols();
		if (!(*protocols & proto_names[i].type & ~available))
			continue;

		pr_err("Loaded IR protocol module %s, but protocol %s still not available\n",
		       proto_names[i].module_name,
		       proto_names[i].name);
		*protocols &= ~proto_names[i].type;
	}
}

/**
 * store_protocols() - changes the current/wakeup IR protocol(s)
 * @device:	the device descriptor
 * @mattr:	the device attribute struct
 * @buf:	a pointer to the input buffer
 * @len:	length of the input buffer
 *
 * This routine is for changing the IR protocol type.
 * It is trigged by writing to /sys/class/rc/rc?/[wakeup_]protocols.
 * See parse_protocol_change() for the valid commands.
 * Returns @len on success or a negative error code.
 *
 * dev->lock is taken to guard against races between
 * store_protocols and show_protocols.
 */
static ssize_t store_protocols(struct device *device,
			       struct device_attribute *mattr,
			       const char *buf, size_t len)
{
	struct rc_dev *dev = to_rc_dev(device);
	u64 *current_protocols;
	struct rc_scancode_filter *filter;
	u64 old_protocols, new_protocols;
	ssize_t rc;

	dev_dbg(&dev->dev, "Normal protocol change requested\n");
	current_protocols = &dev->enabled_protocols;
	filter = &dev->scancode_filter;

	if (!dev->change_protocol) {
		dev_dbg(&dev->dev, "Protocol switching not supported\n");
		return -EINVAL;
	}

	mutex_lock(&dev->lock);

	old_protocols = *current_protocols;
	new_protocols = old_protocols;
	rc = parse_protocol_change(dev, &new_protocols, buf);
	if (rc < 0)
		goto out;

	if (dev->driver_type == RC_DRIVER_IR_RAW)
		ir_raw_load_modules(&new_protocols);

	rc = dev->change_protocol(dev, &new_protocols);
	if (rc < 0) {
		dev_dbg(&dev->dev, "Error setting protocols to 0x%llx\n",
			(long long)new_protocols);
		goto out;
	}

	if (new_protocols != old_protocols) {
		*current_protocols = new_protocols;
		dev_dbg(&dev->dev, "Protocols changed to 0x%llx\n",
			(long long)new_protocols);
	}

	/*
	 * If a protocol change was attempted the filter may need updating, even
	 * if the actual protocol mask hasn't changed (since the driver may have
	 * cleared the filter).
	 * Try setting the same filter with the new protocol (if any).
	 * Fall back to clearing the filter.
	 */
	if (dev->s_filter && filter->mask) {
		if (new_protocols)
			rc = dev->s_filter(dev, filter);
		else
			rc = -1;

		if (rc < 0) {
			filter->data = 0;
			filter->mask = 0;
			dev->s_filter(dev, filter);
		}
	}

	rc = len;

out:
	mutex_unlock(&dev->lock);
	return rc;
}

/**
 * show_filter() - shows the current scancode filter value or mask
 * @device:	the device descriptor
 * @attr:	the device attribute struct
 * @buf:	a pointer to the output buffer
 *
 * This routine is a callback routine to read a scancode filter value or mask.
 * It is trigged by reading /sys/class/rc/rc?/[wakeup_]filter[_mask].
 * It prints the current scancode filter value or mask of the appropriate filter
 * type in hexadecimal into @buf and returns the size of the buffer.
 *
 * Bits of the filter value corresponding to set bits in the filter mask are
 * compared against input scancodes and non-matching scancodes are discarded.
 *
 * dev->lock is taken to guard against races between
 * store_filter and show_filter.
 */
static ssize_t show_filter(struct device *device,
			   struct device_attribute *attr,
			   char *buf)
{
	struct rc_dev *dev = to_rc_dev(device);
	struct rc_filter_attribute *fattr = to_rc_filter_attr(attr);
	struct rc_scancode_filter *filter;
	u32 val;

	mutex_lock(&dev->lock);

	if (fattr->type == RC_FILTER_NORMAL)
		filter = &dev->scancode_filter;
	else
		filter = &dev->scancode_wakeup_filter;

	if (fattr->mask)
		val = filter->mask;
	else
		val = filter->data;
	mutex_unlock(&dev->lock);

	return sprintf(buf, "%#x\n", val);
}

/**
 * store_filter() - changes the scancode filter value
 * @device:	the device descriptor
 * @attr:	the device attribute struct
 * @buf:	a pointer to the input buffer
 * @len:	length of the input buffer
 *
 * This routine is for changing a scancode filter value or mask.
 * It is trigged by writing to /sys/class/rc/rc?/[wakeup_]filter[_mask].
 * Returns -EINVAL if an invalid filter value for the current protocol was
 * specified or if scancode filtering is not supported by the driver, otherwise
 * returns @len.
 *
 * Bits of the filter value corresponding to set bits in the filter mask are
 * compared against input scancodes and non-matching scancodes are discarded.
 *
 * dev->lock is taken to guard against races between
 * store_filter and show_filter.
 */
static ssize_t store_filter(struct device *device,
			    struct device_attribute *attr,
			    const char *buf, size_t len)
{
	struct rc_dev *dev = to_rc_dev(device);
	struct rc_filter_attribute *fattr = to_rc_filter_attr(attr);
	struct rc_scancode_filter new_filter, *filter;
	int ret;
	unsigned long val;
	int (*set_filter)(struct rc_dev *dev, struct rc_scancode_filter *filter);

	ret = kstrtoul(buf, 0, &val);
	if (ret < 0)
		return ret;

	if (fattr->type == RC_FILTER_NORMAL) {
		set_filter = dev->s_filter;
		filter = &dev->scancode_filter;
	} else {
		set_filter = dev->s_wakeup_filter;
		filter = &dev->scancode_wakeup_filter;
	}

	if (!set_filter)
		return -EINVAL;

	mutex_lock(&dev->lock);

	new_filter = *filter;
	if (fattr->mask)
		new_filter.mask = val;
	else
		new_filter.data = val;

	if (fattr->type == RC_FILTER_WAKEUP) {
		/*
		 * Refuse to set a filter unless a protocol is enabled
		 * and the filter is valid for that protocol
		 */
		if (dev->wakeup_protocol != RC_PROTO_UNKNOWN)
			ret = rc_validate_filter(dev, &new_filter);
		else
			ret = -EINVAL;

		if (ret != 0)
			goto unlock;
	}

	if (fattr->type == RC_FILTER_NORMAL && !dev->enabled_protocols &&
	    val) {
		/* refuse to set a filter unless a protocol is enabled */
		ret = -EINVAL;
		goto unlock;
	}

	ret = set_filter(dev, &new_filter);
	if (ret < 0)
		goto unlock;

	*filter = new_filter;

unlock:
	mutex_unlock(&dev->lock);
	return (ret < 0) ? ret : len;
}

/**
 * show_wakeup_protocols() - shows the wakeup IR protocol
 * @device:	the device descriptor
 * @mattr:	the device attribute struct
 * @buf:	a pointer to the output buffer
 *
 * This routine is a callback routine for input read the IR protocol type(s).
 * it is trigged by reading /sys/class/rc/rc?/wakeup_protocols.
 * It returns the protocol names of supported protocols.
 * The enabled protocols are printed in brackets.
 *
 * dev->lock is taken to guard against races between
 * store_wakeup_protocols and show_wakeup_protocols.
 */
static ssize_t show_wakeup_protocols(struct device *device,
				     struct device_attribute *mattr,
				     char *buf)
{
	struct rc_dev *dev = to_rc_dev(device);
	u64 allowed;
	enum rc_proto enabled;
	char *tmp = buf;
	int i;

	mutex_lock(&dev->lock);

	allowed = dev->allowed_wakeup_protocols;
	enabled = dev->wakeup_protocol;

	mutex_unlock(&dev->lock);

	dev_dbg(&dev->dev, "%s: allowed - 0x%llx, enabled - %d\n",
		__func__, (long long)allowed, enabled);

	for (i = 0; i < ARRAY_SIZE(protocols); i++) {
		if (allowed & (1ULL << i)) {
			if (i == enabled)
				tmp += sprintf(tmp, "[%s] ", protocols[i].name);
			else
				tmp += sprintf(tmp, "%s ", protocols[i].name);
		}
	}

	if (tmp != buf)
		tmp--;
	*tmp = '\n';

	return tmp + 1 - buf;
}

/**
 * store_wakeup_protocols() - changes the wakeup IR protocol(s)
 * @device:	the device descriptor
 * @mattr:	the device attribute struct
 * @buf:	a pointer to the input buffer
 * @len:	length of the input buffer
 *
 * This routine is for changing the IR protocol type.
 * It is trigged by writing to /sys/class/rc/rc?/wakeup_protocols.
 * Returns @len on success or a negative error code.
 *
 * dev->lock is taken to guard against races between
 * store_wakeup_protocols and show_wakeup_protocols.
 */
static ssize_t store_wakeup_protocols(struct device *device,
				      struct device_attribute *mattr,
				      const char *buf, size_t len)
{
	struct rc_dev *dev = to_rc_dev(device);
	enum rc_proto protocol;
	ssize_t rc;
	u64 allowed;
	int i;

	mutex_lock(&dev->lock);

	allowed = dev->allowed_wakeup_protocols;

	if (sysfs_streq(buf, "none")) {
		protocol = RC_PROTO_UNKNOWN;
	} else {
		for (i = 0; i < ARRAY_SIZE(protocols); i++) {
			if ((allowed & (1ULL << i)) &&
			    sysfs_streq(buf, protocols[i].name)) {
				protocol = i;
				break;
			}
		}

		if (i == ARRAY_SIZE(protocols)) {
			rc = -EINVAL;
			goto out;
		}

		if (dev->encode_wakeup) {
			u64 mask = 1ULL << protocol;

			ir_raw_load_modules(&mask);
			if (!mask) {
				rc = -EINVAL;
				goto out;
			}
		}
	}

	if (dev->wakeup_protocol != protocol) {
		dev->wakeup_protocol = protocol;
		dev_dbg(&dev->dev, "Wakeup protocol changed to %d\n", protocol);

		if (protocol == RC_PROTO_RC6_MCE)
			dev->scancode_wakeup_filter.data = 0x800f0000;
		else
			dev->scancode_wakeup_filter.data = 0;
		dev->scancode_wakeup_filter.mask = 0;

		rc = dev->s_wakeup_filter(dev, &dev->scancode_wakeup_filter);
		if (rc == 0)
			rc = len;
	} else {
		rc = len;
	}

out:
	mutex_unlock(&dev->lock);
	return rc;
}

static void rc_dev_release(struct device *device)
{
	struct rc_dev *dev = to_rc_dev(device);

	kfree(dev);
}

#define ADD_HOTPLUG_VAR(fmt, val...)					\
	do {								\
		int err = add_uevent_var(env, fmt, val);		\
		if (err)						\
			return err;					\
	} while (0)

static int rc_dev_uevent(struct device *device, struct kobj_uevent_env *env)
{
	struct rc_dev *dev = to_rc_dev(device);

	if (dev->rc_map.name)
		ADD_HOTPLUG_VAR("NAME=%s", dev->rc_map.name);
	if (dev->driver_name)
		ADD_HOTPLUG_VAR("DRV_NAME=%s", dev->driver_name);
	if (dev->device_name)
		ADD_HOTPLUG_VAR("DEV_NAME=%s", dev->device_name);

	return 0;
}

/*
 * Static device attribute struct with the sysfs attributes for IR's
 */
static struct device_attribute dev_attr_ro_protocols =
__ATTR(protocols, 0444, show_protocols, NULL);
static struct device_attribute dev_attr_rw_protocols =
__ATTR(protocols, 0644, show_protocols, store_protocols);
static DEVICE_ATTR(wakeup_protocols, 0644, show_wakeup_protocols,
		   store_wakeup_protocols);
static RC_FILTER_ATTR(filter, S_IRUGO|S_IWUSR,
		      show_filter, store_filter, RC_FILTER_NORMAL, false);
static RC_FILTER_ATTR(filter_mask, S_IRUGO|S_IWUSR,
		      show_filter, store_filter, RC_FILTER_NORMAL, true);
static RC_FILTER_ATTR(wakeup_filter, S_IRUGO|S_IWUSR,
		      show_filter, store_filter, RC_FILTER_WAKEUP, false);
static RC_FILTER_ATTR(wakeup_filter_mask, S_IRUGO|S_IWUSR,
		      show_filter, store_filter, RC_FILTER_WAKEUP, true);

static struct attribute *rc_dev_rw_protocol_attrs[] = {
	&dev_attr_rw_protocols.attr,
	NULL,
};

static const struct attribute_group rc_dev_rw_protocol_attr_grp = {
	.attrs	= rc_dev_rw_protocol_attrs,
};

static struct attribute *rc_dev_ro_protocol_attrs[] = {
	&dev_attr_ro_protocols.attr,
	NULL,
};

static const struct attribute_group rc_dev_ro_protocol_attr_grp = {
	.attrs	= rc_dev_ro_protocol_attrs,
};

static struct attribute *rc_dev_filter_attrs[] = {
	&dev_attr_filter.attr.attr,
	&dev_attr_filter_mask.attr.attr,
	NULL,
};

static const struct attribute_group rc_dev_filter_attr_grp = {
	.attrs	= rc_dev_filter_attrs,
};

static struct attribute *rc_dev_wakeup_filter_attrs[] = {
	&dev_attr_wakeup_filter.attr.attr,
	&dev_attr_wakeup_filter_mask.attr.attr,
	&dev_attr_wakeup_protocols.attr,
	NULL,
};

static const struct attribute_group rc_dev_wakeup_filter_attr_grp = {
	.attrs	= rc_dev_wakeup_filter_attrs,
};

static const struct device_type rc_dev_type = {
	.release	= rc_dev_release,
	.uevent		= rc_dev_uevent,
};

struct rc_dev *rc_allocate_device(enum rc_driver_type type)
{
	struct rc_dev *dev;

	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
	if (!dev)
		return NULL;

	if (type != RC_DRIVER_IR_RAW_TX) {
		dev->input_dev = input_allocate_device();
		if (!dev->input_dev) {
			kfree(dev);
			return NULL;
		}

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

		dev->timeout = IR_DEFAULT_TIMEOUT;
		timer_setup(&dev->timer_keyup, ir_timer_keyup, 0);
		timer_setup(&dev->timer_repeat, ir_timer_repeat, 0);

		spin_lock_init(&dev->rc_map.lock);
		spin_lock_init(&dev->keylock);
	}
	mutex_init(&dev->lock);

	dev->dev.type = &rc_dev_type;
	dev->dev.class = &rc_class;
	device_initialize(&dev->dev);

	dev->driver_type = type;

	__module_get(THIS_MODULE);
	return dev;
}
EXPORT_SYMBOL_GPL(rc_allocate_device);

void rc_free_device(struct rc_dev *dev)
{
	if (!dev)
		return;

	input_free_device(dev->input_dev);

	put_device(&dev->dev);

	/* kfree(dev) will be called by the callback function
	   rc_dev_release() */

	module_put(THIS_MODULE);
}
EXPORT_SYMBOL_GPL(rc_free_device);

static void devm_rc_alloc_release(struct device *dev, void *res)
{
	rc_free_device(*(struct rc_dev **)res);
}

struct rc_dev *devm_rc_allocate_device(struct device *dev,
				       enum rc_driver_type type)
{
	struct rc_dev **dr, *rc;

	dr = devres_alloc(devm_rc_alloc_release, sizeof(*dr), GFP_KERNEL);
	if (!dr)
		return NULL;

	rc = rc_allocate_device(type);
	if (!rc) {
		devres_free(dr);
		return NULL;
	}

	rc->dev.parent = dev;
	rc->managed_alloc = true;
	*dr = rc;
	devres_add(dev, dr);

	return rc;
}
EXPORT_SYMBOL_GPL(devm_rc_allocate_device);

static int rc_prepare_rx_device(struct rc_dev *dev)
{
	int rc;
	struct rc_map *rc_map;
	u64 rc_proto;

	if (!dev->map_name)
		return -EINVAL;

	rc_map = rc_map_get(dev->map_name);
	if (!rc_map)
		rc_map = rc_map_get(RC_MAP_EMPTY);
	if (!rc_map || !rc_map->scan || rc_map->size == 0)
		return -EINVAL;

	rc = ir_setkeytable(dev, rc_map);
	if (rc)
		return rc;

	rc_proto = BIT_ULL(rc_map->rc_proto);

	if (dev->driver_type == RC_DRIVER_SCANCODE && !dev->change_protocol)
		dev->enabled_protocols = dev->allowed_protocols;

	if (dev->driver_type == RC_DRIVER_IR_RAW)
		ir_raw_load_modules(&rc_proto);

	if (dev->change_protocol) {
		rc = dev->change_protocol(dev, &rc_proto);
		if (rc < 0)
			goto out_table;
		dev->enabled_protocols = rc_proto;
	}

	/* Keyboard events */
	set_bit(EV_KEY, dev->input_dev->evbit);
	set_bit(EV_REP, dev->input_dev->evbit);
	set_bit(EV_MSC, dev->input_dev->evbit);
	set_bit(MSC_SCAN, dev->input_dev->mscbit);
	bitmap_fill(dev->input_dev->keybit, KEY_CNT);

	/* Pointer/mouse events */
	set_bit(EV_REL, dev->input_dev->evbit);
	set_bit(REL_X, dev->input_dev->relbit);
	set_bit(REL_Y, dev->input_dev->relbit);

	if (dev->open)
		dev->input_dev->open = ir_open;
	if (dev->close)
		dev->input_dev->close = ir_close;

	dev->input_dev->dev.parent = &dev->dev;
	memcpy(&dev->input_dev->id, &dev->input_id, sizeof(dev->input_id));
	dev->input_dev->phys = dev->input_phys;
	dev->input_dev->name = dev->device_name;

	return 0;

out_table:
	ir_free_table(&dev->rc_map);

	return rc;
}

static int rc_setup_rx_device(struct rc_dev *dev)
{
	int rc;

	/* rc_open will be called here */
	rc = input_register_device(dev->input_dev);
	if (rc)
		return rc;

	/*
	 * Default delay of 250ms is too short for some protocols, especially
	 * since the timeout is currently set to 250ms. Increase it to 500ms,
	 * to avoid wrong repetition of the keycodes. Note that this must be
	 * set after the call to input_register_device().
	 */
	if (dev->allowed_protocols == RC_PROTO_BIT_CEC)
		dev->input_dev->rep[REP_DELAY] = 0;
	else
		dev->input_dev->rep[REP_DELAY] = 500;

	/*
	 * As a repeat event on protocols like RC-5 and NEC take as long as
	 * 110/114ms, using 33ms as a repeat period is not the right thing
	 * to do.
	 */
	dev->input_dev->rep[REP_PERIOD] = 125;

	return 0;
}

static void rc_free_rx_device(struct rc_dev *dev)
{
	if (!dev)
		return;

	if (dev->input_dev) {
		input_unregister_device(dev->input_dev);
		dev->input_dev = NULL;
	}

	ir_free_table(&dev->rc_map);
}

int rc_register_device(struct rc_dev *dev)
{
	const char *path;
	int attr = 0;
	int minor;
	int rc;

	if (!dev)
		return -EINVAL;

	minor = ida_simple_get(&rc_ida, 0, RC_DEV_MAX, GFP_KERNEL);
	if (minor < 0)
		return minor;

	dev->minor = minor;
	dev_set_name(&dev->dev, "rc%u", dev->minor);
	dev_set_drvdata(&dev->dev, dev);

	dev->dev.groups = dev->sysfs_groups;
	if (dev->driver_type == RC_DRIVER_SCANCODE && !dev->change_protocol)
		dev->sysfs_groups[attr++] = &rc_dev_ro_protocol_attr_grp;
	else if (dev->driver_type != RC_DRIVER_IR_RAW_TX)
		dev->sysfs_groups[attr++] = &rc_dev_rw_protocol_attr_grp;
	if (dev->s_filter)
		dev->sysfs_groups[attr++] = &rc_dev_filter_attr_grp;
	if (dev->s_wakeup_filter)
		dev->sysfs_groups[attr++] = &rc_dev_wakeup_filter_attr_grp;
	dev->sysfs_groups[attr++] = NULL;

	if (dev->driver_type == RC_DRIVER_IR_RAW) {
		rc = ir_raw_event_prepare(dev);
		if (rc < 0)
			goto out_minor;
	}

	if (dev->driver_type != RC_DRIVER_IR_RAW_TX) {
		rc = rc_prepare_rx_device(dev);
		if (rc)
			goto out_raw;
	}

	rc = device_add(&dev->dev);
	if (rc)
		goto out_rx_free;

	path = kobject_get_path(&dev->dev.kobj, GFP_KERNEL);
	dev_info(&dev->dev, "%s as %s\n",
		 dev->device_name ?: "Unspecified device", path ?: "N/A");
	kfree(path);

	dev->registered = true;

	if (dev->driver_type != RC_DRIVER_IR_RAW_TX) {
		rc = rc_setup_rx_device(dev);
		if (rc)
			goto out_dev;
	}

	/* Ensure that the lirc kfifo is setup before we start the thread */
	if (dev->allowed_protocols != RC_PROTO_BIT_CEC) {
		rc = ir_lirc_register(dev);
		if (rc < 0)
			goto out_rx;
	}

	if (dev->driver_type == RC_DRIVER_IR_RAW) {
		rc = ir_raw_event_register(dev);
		if (rc < 0)
			goto out_lirc;
	}

	dev_dbg(&dev->dev, "Registered rc%u (driver: %s)\n", dev->minor,
		dev->driver_name ? dev->driver_name : "unknown");

	return 0;

out_lirc:
	if (dev->allowed_protocols != RC_PROTO_BIT_CEC)
		ir_lirc_unregister(dev);
out_rx:
	rc_free_rx_device(dev);
out_dev:
	device_del(&dev->dev);
out_rx_free:
	ir_free_table(&dev->rc_map);
out_raw:
	ir_raw_event_free(dev);
out_minor:
	ida_simple_remove(&rc_ida, minor);
	return rc;
}
EXPORT_SYMBOL_GPL(rc_register_device);

static void devm_rc_release(struct device *dev, void *res)
{
	rc_unregister_device(*(struct rc_dev **)res);
}

int devm_rc_register_device(struct device *parent, struct rc_dev *dev)
{
	struct rc_dev **dr;
	int ret;

	dr = devres_alloc(devm_rc_release, sizeof(*dr), GFP_KERNEL);
	if (!dr)
		return -ENOMEM;

	ret = rc_register_device(dev);
	if (ret) {
		devres_free(dr);
		return ret;
	}

	*dr = dev;
	devres_add(parent, dr);

	return 0;
}
EXPORT_SYMBOL_GPL(devm_rc_register_device);

void rc_unregister_device(struct rc_dev *dev)
{
	if (!dev)
		return;

	if (dev->driver_type == RC_DRIVER_IR_RAW)
		ir_raw_event_unregister(dev);

	del_timer_sync(&dev->timer_keyup);
	del_timer_sync(&dev->timer_repeat);

	rc_free_rx_device(dev);

	mutex_lock(&dev->lock);
	if (dev->users && dev->close)
		dev->close(dev);
	dev->registered = false;
	mutex_unlock(&dev->lock);

	/*
	 * lirc device should be freed with dev->registered = false, so
	 * that userspace polling will get notified.
	 */
	if (dev->allowed_protocols != RC_PROTO_BIT_CEC)
		ir_lirc_unregister(dev);

	device_del(&dev->dev);

	ida_simple_remove(&rc_ida, dev->minor);

	if (!dev->managed_alloc)
		rc_free_device(dev);
}

EXPORT_SYMBOL_GPL(rc_unregister_device);

/*
 * Init/exit code for the module. Basically, creates/removes /sys/class/rc
 */

static int __init rc_core_init(void)
{
	int rc = class_register(&rc_class);
	if (rc) {
		pr_err("rc_core: unable to register rc class\n");
		return rc;
	}

	rc = lirc_dev_init();
	if (rc) {
		pr_err("rc_core: unable to init lirc\n");
		class_unregister(&rc_class);
		return 0;
	}

	led_trigger_register_simple("rc-feedback", &led_feedback);
	rc_map_register(&empty_map);

	return 0;
}

static void __exit rc_core_exit(void)
{
	lirc_dev_exit();
	class_unregister(&rc_class);
	led_trigger_unregister_simple(led_feedback);
	rc_map_unregister(&empty_map);
}

subsys_initcall(rc_core_init);
module_exit(rc_core_exit);

MODULE_AUTHOR("Mauro Carvalho Chehab");
MODULE_LICENSE("GPL v2");
