1 /* 2 * Generic support for sparse keymaps 3 * 4 * Copyright (c) 2009 Dmitry Torokhov 5 * 6 * Derived from wistron button driver: 7 * Copyright (C) 2005 Miloslav Trmac <[email protected]> 8 * Copyright (C) 2005 Bernhard Rosenkraenzer <[email protected]> 9 * Copyright (C) 2005 Dmitry Torokhov <[email protected]> 10 * 11 * This program is free software; you can redistribute it and/or modify it 12 * under the terms of the GNU General Public License version 2 as published by 13 * the Free Software Foundation. 14 */ 15 16 #include <linux/input.h> 17 #include <linux/input/sparse-keymap.h> 18 19 MODULE_AUTHOR("Dmitry Torokhov <[email protected]>"); 20 MODULE_DESCRIPTION("Generic support for sparse keymaps"); 21 MODULE_LICENSE("GPL v2"); 22 MODULE_VERSION("0.1"); 23 24 /** 25 * sparse_keymap_entry_from_scancode - perform sparse keymap lookup 26 * @dev: Input device using sparse keymap 27 * @code: Scan code 28 * 29 * This function is used to perform &struct key_entry lookup in an 30 * input device using sparse keymap. 31 */ 32 struct key_entry *sparse_keymap_entry_from_scancode(struct input_dev *dev, 33 unsigned int code) 34 { 35 struct key_entry *key; 36 37 for (key = dev->keycode; key->type != KE_END; key++) 38 if (code == key->code) 39 return key; 40 41 return NULL; 42 } 43 EXPORT_SYMBOL(sparse_keymap_entry_from_scancode); 44 45 /** 46 * sparse_keymap_entry_from_keycode - perform sparse keymap lookup 47 * @dev: Input device using sparse keymap 48 * @keycode: Key code 49 * 50 * This function is used to perform &struct key_entry lookup in an 51 * input device using sparse keymap. 52 */ 53 struct key_entry *sparse_keymap_entry_from_keycode(struct input_dev *dev, 54 unsigned int keycode) 55 { 56 struct key_entry *key; 57 58 for (key = dev->keycode; key->type != KE_END; key++) 59 if (key->type == KE_KEY && keycode == key->keycode) 60 return key; 61 62 return NULL; 63 } 64 EXPORT_SYMBOL(sparse_keymap_entry_from_keycode); 65 66 static int sparse_keymap_getkeycode(struct input_dev *dev, 67 unsigned int scancode, 68 unsigned int *keycode) 69 { 70 const struct key_entry *key = 71 sparse_keymap_entry_from_scancode(dev, scancode); 72 73 if (key && key->type == KE_KEY) { 74 *keycode = key->keycode; 75 return 0; 76 } 77 78 return -EINVAL; 79 } 80 81 static int sparse_keymap_setkeycode(struct input_dev *dev, 82 unsigned int scancode, 83 unsigned int keycode) 84 { 85 struct key_entry *key; 86 int old_keycode; 87 88 if (keycode < 0 || keycode > KEY_MAX) 89 return -EINVAL; 90 91 key = sparse_keymap_entry_from_scancode(dev, scancode); 92 if (key && key->type == KE_KEY) { 93 old_keycode = key->keycode; 94 key->keycode = keycode; 95 set_bit(keycode, dev->keybit); 96 if (!sparse_keymap_entry_from_keycode(dev, old_keycode)) 97 clear_bit(old_keycode, dev->keybit); 98 return 0; 99 } 100 101 return -EINVAL; 102 } 103 104 /** 105 * sparse_keymap_setup - set up sparse keymap for an input device 106 * @dev: Input device 107 * @keymap: Keymap in form of array of &key_entry structures ending 108 * with %KE_END type entry 109 * @setup: Function that can be used to adjust keymap entries 110 * depending on device's deeds, may be %NULL 111 * 112 * The function calculates size and allocates copy of the original 113 * keymap after which sets up input device event bits appropriately. 114 * Before destroying input device allocated keymap should be freed 115 * with a call to sparse_keymap_free(). 116 */ 117 int sparse_keymap_setup(struct input_dev *dev, 118 const struct key_entry *keymap, 119 int (*setup)(struct input_dev *, struct key_entry *)) 120 { 121 size_t map_size = 1; /* to account for the last KE_END entry */ 122 const struct key_entry *e; 123 struct key_entry *map, *entry; 124 int i; 125 int error; 126 127 for (e = keymap; e->type != KE_END; e++) 128 map_size++; 129 130 map = kcalloc(map_size, sizeof (struct key_entry), GFP_KERNEL); 131 if (!map) 132 return -ENOMEM; 133 134 memcpy(map, keymap, map_size * sizeof (struct key_entry)); 135 136 for (i = 0; i < map_size; i++) { 137 entry = &map[i]; 138 139 if (setup) { 140 error = setup(dev, entry); 141 if (error) 142 goto err_out; 143 } 144 145 switch (entry->type) { 146 case KE_KEY: 147 __set_bit(EV_KEY, dev->evbit); 148 __set_bit(entry->keycode, dev->keybit); 149 break; 150 151 case KE_SW: 152 __set_bit(EV_SW, dev->evbit); 153 __set_bit(entry->sw.code, dev->swbit); 154 break; 155 } 156 } 157 158 dev->keycode = map; 159 dev->keycodemax = map_size; 160 dev->getkeycode = sparse_keymap_getkeycode; 161 dev->setkeycode = sparse_keymap_setkeycode; 162 163 return 0; 164 165 err_out: 166 kfree(map); 167 return error; 168 169 } 170 EXPORT_SYMBOL(sparse_keymap_setup); 171 172 /** 173 * sparse_keymap_free - free memory allocated for sparse keymap 174 * @dev: Input device using sparse keymap 175 * 176 * This function is used to free memory allocated by sparse keymap 177 * in an input device that was set up by sparse_keymap_setup(). 178 */ 179 void sparse_keymap_free(struct input_dev *dev) 180 { 181 kfree(dev->keycode); 182 dev->keycode = NULL; 183 dev->keycodemax = 0; 184 dev->getkeycode = NULL; 185 dev->setkeycode = NULL; 186 } 187 EXPORT_SYMBOL(sparse_keymap_free); 188 189 /** 190 * sparse_keymap_report_entry - report event corresponding to given key entry 191 * @dev: Input device for which event should be reported 192 * @ke: key entry describing event 193 * @value: Value that should be reported (ignored by %KE_SW entries) 194 * @autorelease: Signals whether release event should be emitted for %KE_KEY 195 * entries right after reporting press event, ignored by all other 196 * entries 197 * 198 * This function is used to report input event described by given 199 * &struct key_entry. 200 */ 201 void sparse_keymap_report_entry(struct input_dev *dev, const struct key_entry *ke, 202 unsigned int value, bool autorelease) 203 { 204 switch (ke->type) { 205 case KE_KEY: 206 input_report_key(dev, ke->keycode, value); 207 input_sync(dev); 208 if (value && autorelease) { 209 input_report_key(dev, ke->keycode, 0); 210 input_sync(dev); 211 } 212 break; 213 214 case KE_SW: 215 value = ke->sw.value; 216 /* fall through */ 217 218 case KE_VSW: 219 input_report_switch(dev, ke->sw.code, value); 220 break; 221 } 222 } 223 EXPORT_SYMBOL(sparse_keymap_report_entry); 224 225 /** 226 * sparse_keymap_report_event - report event corresponding to given scancode 227 * @dev: Input device using sparse keymap 228 * @code: Scan code 229 * @value: Value that should be reported (ignored by %KE_SW entries) 230 * @autorelease: Signals whether release event should be emitted for %KE_KEY 231 * entries right after reporting press event, ignored by all other 232 * entries 233 * 234 * This function is used to perform lookup in an input device using sparse 235 * keymap and report corresponding event. Returns %true if lookup was 236 * successful and %false otherwise. 237 */ 238 bool sparse_keymap_report_event(struct input_dev *dev, unsigned int code, 239 unsigned int value, bool autorelease) 240 { 241 const struct key_entry *ke = 242 sparse_keymap_entry_from_scancode(dev, code); 243 244 if (ke) { 245 sparse_keymap_report_entry(dev, ke, value, autorelease); 246 return true; 247 } 248 249 return false; 250 } 251 EXPORT_SYMBOL(sparse_keymap_report_event); 252 253