Esempio n. 1
0
/**
 * ir_locate_scancode() - set a keycode in the scancode->keycode table
 * @ir_dev:	the struct ir_input_dev device descriptor
 * @rc_tab:	scancode table to be searched
 * @scancode:	the desired scancode
 * @resize:	controls whether we allowed to resize the table to
 *		accomodate not yet present scancodes
 * @return:	index of the mapping containing scancode in question
 *		or -1U in case of failure.
 *
 * This routine is used to locate given scancode in ir_scancode_table.
 * If scancode is not yet present the routine will allocate a new slot
 * for it.
 */
static unsigned int ir_establish_scancode(struct ir_input_dev *ir_dev,
					  struct ir_scancode_table *rc_tab,
					  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,
	 */
	if (ir_dev->props && ir_dev->props->scanmask)
		scancode &= ir_dev->props->scanmask;

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

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

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

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

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

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

	if (old_keycode != KEY_RESERVED) {
		/* A previous mapping was updated... */
		__clear_bit(old_keycode, dev->keybit);
		/* ... but another scancode might use the same keycode */
		for (i = 0; i < rc_tab->len; i++) {
			if (rc_tab->scan[i].keycode == old_keycode) {
				__set_bit(old_keycode, dev->keybit);
				break;
			}
		}

		/* Possibly shrink the keytable, failure is not a problem */
		ir_resize_table(rc_tab, GFP_ATOMIC);
	}

	return old_keycode;
}
Esempio n. 3
0
/**
 * ir_do_setkeycode() - internal function to set a keycode in the
 *			scancode->keycode table
 * @dev:	the struct input_dev device descriptor
 * @rc_tab:	the struct ir_scancode_table to set the keycode in
 * @scancode:	the scancode for the ir command
 * @keycode:	the keycode for the ir command
 * @resize:	whether the keytable may be shrunk
 * @return:	-EINVAL if the keycode could not be inserted, otherwise zero.
 *
 * This routine is used internally to manipulate the scancode->keycode table.
 * The caller has to hold @rc_tab->lock.
 */
static int ir_do_setkeycode(struct input_dev *dev,
			    struct ir_scancode_table *rc_tab,
			    unsigned scancode, unsigned keycode,
			    bool resize)
{
	unsigned int i;
	int old_keycode = KEY_RESERVED;
	struct ir_input_dev *ir_dev = input_get_drvdata(dev);

	/*
	 * 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,
	 */
	if (ir_dev->props && ir_dev->props->scanmask) {
		scancode &= ir_dev->props->scanmask;
	}

	/* First check if we already have a mapping for this ir command */
	for (i = 0; i < rc_tab->len; i++) {
		/* Keytable is sorted from lowest to highest scancode */
		if (rc_tab->scan[i].scancode > scancode)
			break;
		else if (rc_tab->scan[i].scancode < scancode)
			continue;

		old_keycode = rc_tab->scan[i].keycode;
		rc_tab->scan[i].keycode = keycode;

		/* Did the user wish to remove the mapping? */
		if (keycode == KEY_RESERVED || keycode == KEY_UNKNOWN) {
			IR_dprintk(1, "#%d: Deleting scan 0x%04x\n",
				   i, scancode);
			rc_tab->len--;
			memmove(&rc_tab->scan[i], &rc_tab->scan[i + 1],
				(rc_tab->len - i) * sizeof(struct ir_scancode));
		}

		/* Possibly shrink the keytable, failure is not a problem */
		ir_resize_table(rc_tab);
		break;
	}

	if (old_keycode == KEY_RESERVED && keycode != KEY_RESERVED) {
		/* No previous mapping found, we might need to grow the table */
		if (resize && ir_resize_table(rc_tab))
			return -ENOMEM;

		IR_dprintk(1, "#%d: New scan 0x%04x with key 0x%04x\n",
			   i, scancode, keycode);

		/* i is the proper index to insert our new keycode */
		memmove(&rc_tab->scan[i + 1], &rc_tab->scan[i],
			(rc_tab->len - i) * sizeof(struct ir_scancode));
		rc_tab->scan[i].scancode = scancode;
		rc_tab->scan[i].keycode = keycode;
		rc_tab->len++;
		set_bit(keycode, dev->keybit);
	} else {
		IR_dprintk(1, "#%d: Replacing scan 0x%04x with key 0x%04x\n",
			   i, scancode, keycode);
		/* A previous mapping was updated... */
		clear_bit(old_keycode, dev->keybit);
		/* ...but another scancode might use the same keycode */
		for (i = 0; i < rc_tab->len; i++) {
			if (rc_tab->scan[i].keycode == old_keycode) {
				set_bit(old_keycode, dev->keybit);
				break;
			}
		}
	}

	return 0;
}