diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-25 18:59:01 +0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-25 18:59:01 +0400 |
commit | 3a99c6319064af3f2e18eb929f638d555dbf7a62 (patch) | |
tree | e611927f41142123dc8efed7e07a3a91151edb01 /drivers/input/sparse-keymap.c | |
parent | 1dfd166e93f98892aa4427069a23ed73259983c8 (diff) | |
parent | 49327ad2bbbaf1945d5ba431522201574219d150 (diff) | |
download | linux-3a99c6319064af3f2e18eb929f638d555dbf7a62.tar.xz |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: (75 commits)
Input: wacom - specify Cinitq supported tools
Input: ab8500-ponkey - fix IRQ freeing in error path
Input: adp5588-keys - use more obvious i2c_device_id name string
Input: ad7877 - switch to using threaded IRQ
Input: ad7877 - use attribute group to control visibility of attributes
Input: serio - add support for PS2Mult multiplexer protocol
Input: wacom - properly enable runtime PM
Input: ad7877 - filter events where pressure is beyond the maximum
Input: ad7877 - implement EV_KEY:BTN_TOUCH reporting
Input: ad7877 - implement specified chip select behavior
Input: hp680_ts_input - use cancel_delayed_work_sync()
Input: mousedev - correct lockdep annotation
Input: ads7846 - switch to using threaded IRQ
Input: serio - support multiple child devices per single parent
Input: synaptics - simplify pass-through port handling
Input: add ROHM BU21013 touch panel controller support
Input: omap4-keypad - wake-up on events & long presses
Input: omap4-keypad - fix interrupt line configuration
Input: omap4-keypad - SYSCONFIG register configuration
Input: omap4-keypad - use platform device helpers
...
Diffstat (limited to 'drivers/input/sparse-keymap.c')
-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); |