diff options
-rw-r--r-- | drivers/input/sparse-keymap.c | 81 |
1 files changed, 65 insertions, 16 deletions
diff --git a/drivers/input/sparse-keymap.c b/drivers/input/sparse-keymap.c index 014248344763..a29a7812bd46 100644 --- a/drivers/input/sparse-keymap.c +++ b/drivers/input/sparse-keymap.c @@ -22,6 +22,37 @@ MODULE_DESCRIPTION("Generic support for sparse keymaps"); MODULE_LICENSE("GPL v2"); MODULE_VERSION("0.1"); +static unsigned int sparse_keymap_get_key_index(struct input_dev *dev, + const struct key_entry *k) +{ + struct key_entry *key; + unsigned int idx = 0; + + for (key = dev->keycode; key->type != KE_END; key++) { + if (key->type == KE_KEY) { + if (key == k) + break; + idx++; + } + } + + return idx; +} + +static struct key_entry *sparse_keymap_entry_by_index(struct input_dev *dev, + unsigned int index) +{ + struct key_entry *key; + unsigned int key_cnt = 0; + + for (key = dev->keycode; key->type != KE_END; key++) + if (key->type == KE_KEY) + if (key_cnt++ == index) + return key; + + return NULL; +} + /** * sparse_keymap_entry_from_scancode - perform sparse keymap lookup * @dev: Input device using sparse keymap @@ -64,16 +95,36 @@ struct key_entry *sparse_keymap_entry_from_keycode(struct input_dev *dev, } EXPORT_SYMBOL(sparse_keymap_entry_from_keycode); +static struct key_entry *sparse_keymap_locate(struct input_dev *dev, + const struct input_keymap_entry *ke) +{ + struct key_entry *key; + unsigned int scancode; + + if (ke->flags & INPUT_KEYMAP_BY_INDEX) + key = sparse_keymap_entry_by_index(dev, ke->index); + else if (input_scancode_to_scalar(ke, &scancode) == 0) + key = sparse_keymap_entry_from_scancode(dev, scancode); + else + key = NULL; + + return key; +} + static int sparse_keymap_getkeycode(struct input_dev *dev, - unsigned int scancode, - unsigned int *keycode) + struct input_keymap_entry *ke) { const struct key_entry *key; if (dev->keycode) { - key = sparse_keymap_entry_from_scancode(dev, scancode); + key = sparse_keymap_locate(dev, ke); if (key && key->type == KE_KEY) { - *keycode = key->keycode; + ke->keycode = key->keycode; + if (!(ke->flags & INPUT_KEYMAP_BY_INDEX)) + ke->index = + sparse_keymap_get_key_index(dev, key); + ke->len = sizeof(key->code); + memcpy(ke->scancode, &key->code, sizeof(key->code)); return 0; } } @@ -82,20 +133,19 @@ static int sparse_keymap_getkeycode(struct input_dev *dev, } static int sparse_keymap_setkeycode(struct input_dev *dev, - unsigned int scancode, - unsigned int keycode) + const struct input_keymap_entry *ke, + unsigned int *old_keycode) { struct key_entry *key; - int old_keycode; if (dev->keycode) { - key = sparse_keymap_entry_from_scancode(dev, scancode); + key = sparse_keymap_locate(dev, ke); if (key && key->type == KE_KEY) { - old_keycode = key->keycode; - key->keycode = keycode; - set_bit(keycode, dev->keybit); - if (!sparse_keymap_entry_from_keycode(dev, old_keycode)) - clear_bit(old_keycode, dev->keybit); + *old_keycode = key->keycode; + key->keycode = ke->keycode; + set_bit(ke->keycode, dev->keybit); + if (!sparse_keymap_entry_from_keycode(dev, *old_keycode)) + clear_bit(*old_keycode, dev->keybit); return 0; } } @@ -159,15 +209,14 @@ int sparse_keymap_setup(struct input_dev *dev, dev->keycode = map; dev->keycodemax = map_size; - dev->getkeycode = sparse_keymap_getkeycode; - dev->setkeycode = sparse_keymap_setkeycode; + dev->getkeycode_new = sparse_keymap_getkeycode; + dev->setkeycode_new = sparse_keymap_setkeycode; return 0; err_out: kfree(map); return error; - } EXPORT_SYMBOL(sparse_keymap_setup); |