diff options
Diffstat (limited to 'drivers/media/rc/rc-main.c')
| -rw-r--r-- | drivers/media/rc/rc-main.c | 80 | 
1 files changed, 58 insertions, 22 deletions
diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c index 6f80c251f641..d7064d664d52 100644 --- a/drivers/media/rc/rc-main.c +++ b/drivers/media/rc/rc-main.c @@ -164,6 +164,41 @@ static struct rc_map_list empty_map = {  };  /** + * scancode_to_u64() - converts scancode in &struct input_keymap_entry + * @ke: keymap entry containing scancode to be converted. + * @scancode: pointer to the location where converted scancode should + *	be stored. + * + * This function is a version of input_scancode_to_scalar specialized for + * rc-core. + */ +static int scancode_to_u64(const struct input_keymap_entry *ke, u64 *scancode) +{ +	switch (ke->len) { +	case 1: +		*scancode = *((u8 *)ke->scancode); +		break; + +	case 2: +		*scancode = *((u16 *)ke->scancode); +		break; + +	case 4: +		*scancode = *((u32 *)ke->scancode); +		break; + +	case 8: +		*scancode = *((u64 *)ke->scancode); +		break; + +	default: +		return -EINVAL; +	} + +	return 0; +} + +/**   * ir_create_table() - initializes a scancode table   * @dev:	the rc_dev device   * @rc_map:	the rc_map to initialize @@ -285,13 +320,13 @@ static unsigned int ir_update_mapping(struct rc_dev *dev,  	/* 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", +		dev_dbg(&dev->dev, "#%d: Deleting scan 0x%04llx\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", +		dev_dbg(&dev->dev, "#%d: %s scan 0x%04llx with key 0x%04x\n",  			index,  			old_keycode == KEY_RESERVED ? "New" : "Replacing",  			rc_map->scan[index].scancode, new_keycode); @@ -334,8 +369,7 @@ static unsigned int ir_update_mapping(struct rc_dev *dev,   */  static unsigned int ir_establish_scancode(struct rc_dev *dev,  					  struct rc_map *rc_map, -					  unsigned int scancode, -					  bool resize) +					  u64 scancode, bool resize)  {  	unsigned int i; @@ -394,7 +428,7 @@ static int ir_setkeycode(struct input_dev *idev,  	struct rc_dev *rdev = input_get_drvdata(idev);  	struct rc_map *rc_map = &rdev->rc_map;  	unsigned int index; -	unsigned int scancode; +	u64 scancode;  	int retval = 0;  	unsigned long flags; @@ -407,7 +441,7 @@ static int ir_setkeycode(struct input_dev *idev,  			goto out;  		}  	} else { -		retval = input_scancode_to_scalar(ke, &scancode); +		retval = scancode_to_u64(ke, &scancode);  		if (retval)  			goto out; @@ -434,8 +468,7 @@ out:   *   * return:	-ENOMEM if all keycodes could not be inserted, otherwise zero.   */ -static int ir_setkeytable(struct rc_dev *dev, -			  const struct rc_map *from) +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; @@ -466,7 +499,7 @@ static int ir_setkeytable(struct rc_dev *dev,  static int rc_map_cmp(const void *key, const void *elt)  { -	const unsigned int *scancode = key; +	const u64 *scancode = key;  	const struct rc_map_table *e = elt;  	if (*scancode < e->scancode) @@ -487,7 +520,7 @@ static int rc_map_cmp(const void *key, const void *elt)   * 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) +					  u64 scancode)  {  	struct rc_map_table *res; @@ -516,7 +549,7 @@ static int ir_getkeycode(struct input_dev *idev,  	struct rc_map_table *entry;  	unsigned long flags;  	unsigned int index; -	unsigned int scancode; +	u64 scancode;  	int retval;  	spin_lock_irqsave(&rc_map->lock, flags); @@ -524,7 +557,7 @@ static int ir_getkeycode(struct input_dev *idev,  	if (ke->flags & INPUT_KEYMAP_BY_INDEX) {  		index = ke->index;  	} else { -		retval = input_scancode_to_scalar(ke, &scancode); +		retval = scancode_to_u64(ke, &scancode);  		if (retval)  			goto out; @@ -538,7 +571,6 @@ static int ir_getkeycode(struct input_dev *idev,  		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 @@ -570,7 +602,7 @@ out:   *   * return:	the corresponding keycode, or KEY_RESERVED   */ -u32 rc_g_keycode_from_table(struct rc_dev *dev, u32 scancode) +u32 rc_g_keycode_from_table(struct rc_dev *dev, u64 scancode)  {  	struct rc_map *rc_map = &dev->rc_map;  	unsigned int keycode; @@ -586,7 +618,7 @@ u32 rc_g_keycode_from_table(struct rc_dev *dev, u32 scancode)  	spin_unlock_irqrestore(&rc_map->lock, flags);  	if (keycode != KEY_RESERVED) -		dev_dbg(&dev->dev, "%s: scancode 0x%04x keycode 0x%02x\n", +		dev_dbg(&dev->dev, "%s: scancode 0x%04llx keycode 0x%02x\n",  			dev->device_name, scancode, keycode);  	return keycode; @@ -719,8 +751,11 @@ void rc_repeat(struct rc_dev *dev)  	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->last_scancode <= U32_MAX) { +		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; @@ -743,7 +778,7 @@ EXPORT_SYMBOL_GPL(rc_repeat);   * called with keylock held.   */  static void ir_do_keydown(struct rc_dev *dev, enum rc_proto protocol, -			  u32 scancode, u32 keycode, u8 toggle) +			  u64 scancode, u32 keycode, u8 toggle)  {  	bool new_event = (!dev->keypressed		 ||  			  dev->last_protocol != protocol || @@ -761,7 +796,8 @@ static void ir_do_keydown(struct rc_dev *dev, enum rc_proto protocol,  	if (new_event && dev->keypressed)  		ir_do_keyup(dev, false); -	input_event(dev->input_dev, EV_MSC, MSC_SCAN, scancode); +	if (scancode <= U32_MAX) +		input_event(dev->input_dev, EV_MSC, MSC_SCAN, scancode);  	dev->last_protocol = protocol;  	dev->last_scancode = scancode; @@ -772,7 +808,7 @@ static void ir_do_keydown(struct rc_dev *dev, enum rc_proto protocol,  		/* 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_dbg(&dev->dev, "%s: key down event, key 0x%04x, protocol 0x%04x, scancode 0x%08llx\n",  			dev->device_name, keycode, protocol, scancode);  		input_report_key(dev->input_dev, keycode, 1); @@ -809,7 +845,7 @@ static void ir_do_keydown(struct rc_dev *dev, enum rc_proto protocol,   * 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, +void rc_keydown(struct rc_dev *dev, enum rc_proto protocol, u64 scancode,  		u8 toggle)  {  	unsigned long flags; @@ -840,7 +876,7 @@ EXPORT_SYMBOL_GPL(rc_keydown);   * 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) +			  u64 scancode, u8 toggle)  {  	unsigned long flags;  	u32 keycode = rc_g_keycode_from_table(dev, scancode);  |