|
@@ -634,78 +634,141 @@ static void input_disconnect_device(struct input_dev *dev)
|
|
|
spin_unlock_irq(&dev->event_lock);
|
|
|
}
|
|
|
|
|
|
-static int input_fetch_keycode(struct input_dev *dev, int scancode)
|
|
|
+/**
|
|
|
+ * input_scancode_to_scalar() - 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 used to convert scancode stored in &struct keymap_entry
|
|
|
+ * into scalar form understood by legacy keymap handling methods. These
|
|
|
+ * methods expect scancodes to be represented as 'unsigned int'.
|
|
|
+ */
|
|
|
+int input_scancode_to_scalar(const struct input_keymap_entry *ke,
|
|
|
+ unsigned int *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;
|
|
|
+
|
|
|
+ default:
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+EXPORT_SYMBOL(input_scancode_to_scalar);
|
|
|
+
|
|
|
+/*
|
|
|
+ * Those routines handle the default case where no [gs]etkeycode() is
|
|
|
+ * defined. In this case, an array indexed by the scancode is used.
|
|
|
+ */
|
|
|
+
|
|
|
+static unsigned int input_fetch_keycode(struct input_dev *dev,
|
|
|
+ unsigned int index)
|
|
|
{
|
|
|
switch (dev->keycodesize) {
|
|
|
- case 1:
|
|
|
- return ((u8 *)dev->keycode)[scancode];
|
|
|
+ case 1:
|
|
|
+ return ((u8 *)dev->keycode)[index];
|
|
|
|
|
|
- case 2:
|
|
|
- return ((u16 *)dev->keycode)[scancode];
|
|
|
+ case 2:
|
|
|
+ return ((u16 *)dev->keycode)[index];
|
|
|
|
|
|
- default:
|
|
|
- return ((u32 *)dev->keycode)[scancode];
|
|
|
+ default:
|
|
|
+ return ((u32 *)dev->keycode)[index];
|
|
|
}
|
|
|
}
|
|
|
|
|
|
static int input_default_getkeycode(struct input_dev *dev,
|
|
|
- unsigned int scancode,
|
|
|
- unsigned int *keycode)
|
|
|
+ struct input_keymap_entry *ke)
|
|
|
{
|
|
|
+ unsigned int index;
|
|
|
+ int error;
|
|
|
+
|
|
|
if (!dev->keycodesize)
|
|
|
return -EINVAL;
|
|
|
|
|
|
- if (scancode >= dev->keycodemax)
|
|
|
+ if (ke->flags & INPUT_KEYMAP_BY_INDEX)
|
|
|
+ index = ke->index;
|
|
|
+ else {
|
|
|
+ error = input_scancode_to_scalar(ke, &index);
|
|
|
+ if (error)
|
|
|
+ return error;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (index >= dev->keycodemax)
|
|
|
return -EINVAL;
|
|
|
|
|
|
- *keycode = input_fetch_keycode(dev, scancode);
|
|
|
+ ke->keycode = input_fetch_keycode(dev, index);
|
|
|
+ ke->index = index;
|
|
|
+ ke->len = sizeof(index);
|
|
|
+ memcpy(ke->scancode, &index, sizeof(index));
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
static int input_default_setkeycode(struct input_dev *dev,
|
|
|
- unsigned int scancode,
|
|
|
- unsigned int keycode)
|
|
|
+ const struct input_keymap_entry *ke,
|
|
|
+ unsigned int *old_keycode)
|
|
|
{
|
|
|
- int old_keycode;
|
|
|
+ unsigned int index;
|
|
|
+ int error;
|
|
|
int i;
|
|
|
|
|
|
- if (scancode >= dev->keycodemax)
|
|
|
+ if (!dev->keycodesize)
|
|
|
return -EINVAL;
|
|
|
|
|
|
- if (!dev->keycodesize)
|
|
|
+ if (ke->flags & INPUT_KEYMAP_BY_INDEX) {
|
|
|
+ index = ke->index;
|
|
|
+ } else {
|
|
|
+ error = input_scancode_to_scalar(ke, &index);
|
|
|
+ if (error)
|
|
|
+ return error;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (index >= dev->keycodemax)
|
|
|
return -EINVAL;
|
|
|
|
|
|
- if (dev->keycodesize < sizeof(keycode) && (keycode >> (dev->keycodesize * 8)))
|
|
|
+ if (dev->keycodesize < sizeof(dev->keycode) &&
|
|
|
+ (ke->keycode >> (dev->keycodesize * 8)))
|
|
|
return -EINVAL;
|
|
|
|
|
|
switch (dev->keycodesize) {
|
|
|
case 1: {
|
|
|
u8 *k = (u8 *)dev->keycode;
|
|
|
- old_keycode = k[scancode];
|
|
|
- k[scancode] = keycode;
|
|
|
+ *old_keycode = k[index];
|
|
|
+ k[index] = ke->keycode;
|
|
|
break;
|
|
|
}
|
|
|
case 2: {
|
|
|
u16 *k = (u16 *)dev->keycode;
|
|
|
- old_keycode = k[scancode];
|
|
|
- k[scancode] = keycode;
|
|
|
+ *old_keycode = k[index];
|
|
|
+ k[index] = ke->keycode;
|
|
|
break;
|
|
|
}
|
|
|
default: {
|
|
|
u32 *k = (u32 *)dev->keycode;
|
|
|
- old_keycode = k[scancode];
|
|
|
- k[scancode] = keycode;
|
|
|
+ *old_keycode = k[index];
|
|
|
+ k[index] = ke->keycode;
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- __clear_bit(old_keycode, dev->keybit);
|
|
|
- __set_bit(keycode, dev->keybit);
|
|
|
+ __clear_bit(*old_keycode, dev->keybit);
|
|
|
+ __set_bit(ke->keycode, dev->keybit);
|
|
|
|
|
|
for (i = 0; i < dev->keycodemax; i++) {
|
|
|
- if (input_fetch_keycode(dev, i) == old_keycode) {
|
|
|
- __set_bit(old_keycode, dev->keybit);
|
|
|
+ if (input_fetch_keycode(dev, i) == *old_keycode) {
|
|
|
+ __set_bit(*old_keycode, dev->keybit);
|
|
|
break; /* Setting the bit twice is useless, so break */
|
|
|
}
|
|
|
}
|
|
@@ -716,53 +779,86 @@ static int input_default_setkeycode(struct input_dev *dev,
|
|
|
/**
|
|
|
* input_get_keycode - retrieve keycode currently mapped to a given scancode
|
|
|
* @dev: input device which keymap is being queried
|
|
|
- * @scancode: scancode (or its equivalent for device in question) for which
|
|
|
- * keycode is needed
|
|
|
- * @keycode: result
|
|
|
+ * @ke: keymap entry
|
|
|
*
|
|
|
* This function should be called by anyone interested in retrieving current
|
|
|
- * keymap. Presently keyboard and evdev handlers use it.
|
|
|
+ * keymap. Presently evdev handlers use it.
|
|
|
*/
|
|
|
-int input_get_keycode(struct input_dev *dev,
|
|
|
- unsigned int scancode, unsigned int *keycode)
|
|
|
+int input_get_keycode(struct input_dev *dev, struct input_keymap_entry *ke)
|
|
|
{
|
|
|
unsigned long flags;
|
|
|
int retval;
|
|
|
|
|
|
spin_lock_irqsave(&dev->event_lock, flags);
|
|
|
- retval = dev->getkeycode(dev, scancode, keycode);
|
|
|
- spin_unlock_irqrestore(&dev->event_lock, flags);
|
|
|
|
|
|
+ if (dev->getkeycode) {
|
|
|
+ /*
|
|
|
+ * Support for legacy drivers, that don't implement the new
|
|
|
+ * ioctls
|
|
|
+ */
|
|
|
+ u32 scancode = ke->index;
|
|
|
+
|
|
|
+ memcpy(ke->scancode, &scancode, sizeof(scancode));
|
|
|
+ ke->len = sizeof(scancode);
|
|
|
+ retval = dev->getkeycode(dev, scancode, &ke->keycode);
|
|
|
+ } else {
|
|
|
+ retval = dev->getkeycode_new(dev, ke);
|
|
|
+ }
|
|
|
+
|
|
|
+ spin_unlock_irqrestore(&dev->event_lock, flags);
|
|
|
return retval;
|
|
|
}
|
|
|
EXPORT_SYMBOL(input_get_keycode);
|
|
|
|
|
|
/**
|
|
|
- * input_get_keycode - assign new keycode to a given scancode
|
|
|
+ * input_set_keycode - attribute a keycode to a given scancode
|
|
|
* @dev: input device which keymap is being updated
|
|
|
- * @scancode: scancode (or its equivalent for device in question)
|
|
|
- * @keycode: new keycode to be assigned to the scancode
|
|
|
+ * @ke: new keymap entry
|
|
|
*
|
|
|
* This function should be called by anyone needing to update current
|
|
|
* keymap. Presently keyboard and evdev handlers use it.
|
|
|
*/
|
|
|
int input_set_keycode(struct input_dev *dev,
|
|
|
- unsigned int scancode, unsigned int keycode)
|
|
|
+ const struct input_keymap_entry *ke)
|
|
|
{
|
|
|
unsigned long flags;
|
|
|
unsigned int old_keycode;
|
|
|
int retval;
|
|
|
|
|
|
- if (keycode > KEY_MAX)
|
|
|
+ if (ke->keycode > KEY_MAX)
|
|
|
return -EINVAL;
|
|
|
|
|
|
spin_lock_irqsave(&dev->event_lock, flags);
|
|
|
|
|
|
- retval = dev->getkeycode(dev, scancode, &old_keycode);
|
|
|
- if (retval)
|
|
|
- goto out;
|
|
|
+ if (dev->setkeycode) {
|
|
|
+ /*
|
|
|
+ * Support for legacy drivers, that don't implement the new
|
|
|
+ * ioctls
|
|
|
+ */
|
|
|
+ unsigned int scancode;
|
|
|
+
|
|
|
+ retval = input_scancode_to_scalar(ke, &scancode);
|
|
|
+ if (retval)
|
|
|
+ goto out;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * We need to know the old scancode, in order to generate a
|
|
|
+ * keyup effect, if the set operation happens successfully
|
|
|
+ */
|
|
|
+ if (!dev->getkeycode) {
|
|
|
+ retval = -EINVAL;
|
|
|
+ goto out;
|
|
|
+ }
|
|
|
+
|
|
|
+ retval = dev->getkeycode(dev, scancode, &old_keycode);
|
|
|
+ if (retval)
|
|
|
+ goto out;
|
|
|
+
|
|
|
+ retval = dev->setkeycode(dev, scancode, ke->keycode);
|
|
|
+ } else {
|
|
|
+ retval = dev->setkeycode_new(dev, ke, &old_keycode);
|
|
|
+ }
|
|
|
|
|
|
- retval = dev->setkeycode(dev, scancode, keycode);
|
|
|
if (retval)
|
|
|
goto out;
|
|
|
|
|
@@ -1759,11 +1855,11 @@ int input_register_device(struct input_dev *dev)
|
|
|
dev->rep[REP_PERIOD] = 33;
|
|
|
}
|
|
|
|
|
|
- if (!dev->getkeycode)
|
|
|
- dev->getkeycode = input_default_getkeycode;
|
|
|
+ if (!dev->getkeycode && !dev->getkeycode_new)
|
|
|
+ dev->getkeycode_new = input_default_getkeycode;
|
|
|
|
|
|
- if (!dev->setkeycode)
|
|
|
- dev->setkeycode = input_default_setkeycode;
|
|
|
+ if (!dev->setkeycode && !dev->setkeycode_new)
|
|
|
+ dev->setkeycode_new = input_default_setkeycode;
|
|
|
|
|
|
dev_set_name(&dev->dev, "input%ld",
|
|
|
(unsigned long) atomic_inc_return(&input_no) - 1);
|