root/drivers/input/sparse-keymap.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. sparse_keymap_get_key_index
  2. sparse_keymap_entry_by_index
  3. sparse_keymap_entry_from_scancode
  4. sparse_keymap_entry_from_keycode
  5. sparse_keymap_locate
  6. sparse_keymap_getkeycode
  7. sparse_keymap_setkeycode
  8. sparse_keymap_setup
  9. sparse_keymap_report_entry
  10. sparse_keymap_report_event

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Generic support for sparse keymaps
   4  *
   5  * Copyright (c) 2009 Dmitry Torokhov
   6  *
   7  * Derived from wistron button driver:
   8  * Copyright (C) 2005 Miloslav Trmac <mitr@volny.cz>
   9  * Copyright (C) 2005 Bernhard Rosenkraenzer <bero@arklinux.org>
  10  * Copyright (C) 2005 Dmitry Torokhov <dtor@mail.ru>
  11  */
  12 
  13 #include <linux/input.h>
  14 #include <linux/input/sparse-keymap.h>
  15 #include <linux/module.h>
  16 #include <linux/slab.h>
  17 
  18 MODULE_AUTHOR("Dmitry Torokhov <dtor@mail.ru>");
  19 MODULE_DESCRIPTION("Generic support for sparse keymaps");
  20 MODULE_LICENSE("GPL v2");
  21 
  22 static unsigned int sparse_keymap_get_key_index(struct input_dev *dev,
  23                                                 const struct key_entry *k)
  24 {
  25         struct key_entry *key;
  26         unsigned int idx = 0;
  27 
  28         for (key = dev->keycode; key->type != KE_END; key++) {
  29                 if (key->type == KE_KEY) {
  30                         if (key == k)
  31                                 break;
  32                         idx++;
  33                 }
  34         }
  35 
  36         return idx;
  37 }
  38 
  39 static struct key_entry *sparse_keymap_entry_by_index(struct input_dev *dev,
  40                                                       unsigned int index)
  41 {
  42         struct key_entry *key;
  43         unsigned int key_cnt = 0;
  44 
  45         for (key = dev->keycode; key->type != KE_END; key++)
  46                 if (key->type == KE_KEY)
  47                         if (key_cnt++ == index)
  48                                 return key;
  49 
  50         return NULL;
  51 }
  52 
  53 /**
  54  * sparse_keymap_entry_from_scancode - perform sparse keymap lookup
  55  * @dev: Input device using sparse keymap
  56  * @code: Scan code
  57  *
  58  * This function is used to perform &struct key_entry lookup in an
  59  * input device using sparse keymap.
  60  */
  61 struct key_entry *sparse_keymap_entry_from_scancode(struct input_dev *dev,
  62                                                     unsigned int code)
  63 {
  64         struct key_entry *key;
  65 
  66         for (key = dev->keycode; key->type != KE_END; key++)
  67                 if (code == key->code)
  68                         return key;
  69 
  70         return NULL;
  71 }
  72 EXPORT_SYMBOL(sparse_keymap_entry_from_scancode);
  73 
  74 /**
  75  * sparse_keymap_entry_from_keycode - perform sparse keymap lookup
  76  * @dev: Input device using sparse keymap
  77  * @keycode: Key code
  78  *
  79  * This function is used to perform &struct key_entry lookup in an
  80  * input device using sparse keymap.
  81  */
  82 struct key_entry *sparse_keymap_entry_from_keycode(struct input_dev *dev,
  83                                                    unsigned int keycode)
  84 {
  85         struct key_entry *key;
  86 
  87         for (key = dev->keycode; key->type != KE_END; key++)
  88                 if (key->type == KE_KEY && keycode == key->keycode)
  89                         return key;
  90 
  91         return NULL;
  92 }
  93 EXPORT_SYMBOL(sparse_keymap_entry_from_keycode);
  94 
  95 static struct key_entry *sparse_keymap_locate(struct input_dev *dev,
  96                                         const struct input_keymap_entry *ke)
  97 {
  98         struct key_entry *key;
  99         unsigned int scancode;
 100 
 101         if (ke->flags & INPUT_KEYMAP_BY_INDEX)
 102                 key = sparse_keymap_entry_by_index(dev, ke->index);
 103         else if (input_scancode_to_scalar(ke, &scancode) == 0)
 104                 key = sparse_keymap_entry_from_scancode(dev, scancode);
 105         else
 106                 key = NULL;
 107 
 108         return key;
 109 }
 110 
 111 static int sparse_keymap_getkeycode(struct input_dev *dev,
 112                                     struct input_keymap_entry *ke)
 113 {
 114         const struct key_entry *key;
 115 
 116         if (dev->keycode) {
 117                 key = sparse_keymap_locate(dev, ke);
 118                 if (key && key->type == KE_KEY) {
 119                         ke->keycode = key->keycode;
 120                         if (!(ke->flags & INPUT_KEYMAP_BY_INDEX))
 121                                 ke->index =
 122                                         sparse_keymap_get_key_index(dev, key);
 123                         ke->len = sizeof(key->code);
 124                         memcpy(ke->scancode, &key->code, sizeof(key->code));
 125                         return 0;
 126                 }
 127         }
 128 
 129         return -EINVAL;
 130 }
 131 
 132 static int sparse_keymap_setkeycode(struct input_dev *dev,
 133                                     const struct input_keymap_entry *ke,
 134                                     unsigned int *old_keycode)
 135 {
 136         struct key_entry *key;
 137 
 138         if (dev->keycode) {
 139                 key = sparse_keymap_locate(dev, ke);
 140                 if (key && key->type == KE_KEY) {
 141                         *old_keycode = key->keycode;
 142                         key->keycode = ke->keycode;
 143                         set_bit(ke->keycode, dev->keybit);
 144                         if (!sparse_keymap_entry_from_keycode(dev, *old_keycode))
 145                                 clear_bit(*old_keycode, dev->keybit);
 146                         return 0;
 147                 }
 148         }
 149 
 150         return -EINVAL;
 151 }
 152 
 153 /**
 154  * sparse_keymap_setup - set up sparse keymap for an input device
 155  * @dev: Input device
 156  * @keymap: Keymap in form of array of &key_entry structures ending
 157  *      with %KE_END type entry
 158  * @setup: Function that can be used to adjust keymap entries
 159  *      depending on device's needs, may be %NULL
 160  *
 161  * The function calculates size and allocates copy of the original
 162  * keymap after which sets up input device event bits appropriately.
 163  * The allocated copy of the keymap is automatically freed when it
 164  * is no longer needed.
 165  */
 166 int sparse_keymap_setup(struct input_dev *dev,
 167                         const struct key_entry *keymap,
 168                         int (*setup)(struct input_dev *, struct key_entry *))
 169 {
 170         size_t map_size = 1; /* to account for the last KE_END entry */
 171         const struct key_entry *e;
 172         struct key_entry *map, *entry;
 173         int i;
 174         int error;
 175 
 176         for (e = keymap; e->type != KE_END; e++)
 177                 map_size++;
 178 
 179         map = devm_kmemdup(&dev->dev, keymap, map_size * sizeof(*map),
 180                            GFP_KERNEL);
 181         if (!map)
 182                 return -ENOMEM;
 183 
 184         for (i = 0; i < map_size; i++) {
 185                 entry = &map[i];
 186 
 187                 if (setup) {
 188                         error = setup(dev, entry);
 189                         if (error)
 190                                 return error;
 191                 }
 192 
 193                 switch (entry->type) {
 194                 case KE_KEY:
 195                         __set_bit(EV_KEY, dev->evbit);
 196                         __set_bit(entry->keycode, dev->keybit);
 197                         break;
 198 
 199                 case KE_SW:
 200                 case KE_VSW:
 201                         __set_bit(EV_SW, dev->evbit);
 202                         __set_bit(entry->sw.code, dev->swbit);
 203                         break;
 204                 }
 205         }
 206 
 207         if (test_bit(EV_KEY, dev->evbit)) {
 208                 __set_bit(KEY_UNKNOWN, dev->keybit);
 209                 __set_bit(EV_MSC, dev->evbit);
 210                 __set_bit(MSC_SCAN, dev->mscbit);
 211         }
 212 
 213         dev->keycode = map;
 214         dev->keycodemax = map_size;
 215         dev->getkeycode = sparse_keymap_getkeycode;
 216         dev->setkeycode = sparse_keymap_setkeycode;
 217 
 218         return 0;
 219 }
 220 EXPORT_SYMBOL(sparse_keymap_setup);
 221 
 222 /**
 223  * sparse_keymap_report_entry - report event corresponding to given key entry
 224  * @dev: Input device for which event should be reported
 225  * @ke: key entry describing event
 226  * @value: Value that should be reported (ignored by %KE_SW entries)
 227  * @autorelease: Signals whether release event should be emitted for %KE_KEY
 228  *      entries right after reporting press event, ignored by all other
 229  *      entries
 230  *
 231  * This function is used to report input event described by given
 232  * &struct key_entry.
 233  */
 234 void sparse_keymap_report_entry(struct input_dev *dev, const struct key_entry *ke,
 235                                 unsigned int value, bool autorelease)
 236 {
 237         switch (ke->type) {
 238         case KE_KEY:
 239                 input_event(dev, EV_MSC, MSC_SCAN, ke->code);
 240                 input_report_key(dev, ke->keycode, value);
 241                 input_sync(dev);
 242                 if (value && autorelease) {
 243                         input_report_key(dev, ke->keycode, 0);
 244                         input_sync(dev);
 245                 }
 246                 break;
 247 
 248         case KE_SW:
 249                 value = ke->sw.value;
 250                 /* fall through */
 251 
 252         case KE_VSW:
 253                 input_report_switch(dev, ke->sw.code, value);
 254                 input_sync(dev);
 255                 break;
 256         }
 257 }
 258 EXPORT_SYMBOL(sparse_keymap_report_entry);
 259 
 260 /**
 261  * sparse_keymap_report_event - report event corresponding to given scancode
 262  * @dev: Input device using sparse keymap
 263  * @code: Scan code
 264  * @value: Value that should be reported (ignored by %KE_SW entries)
 265  * @autorelease: Signals whether release event should be emitted for %KE_KEY
 266  *      entries right after reporting press event, ignored by all other
 267  *      entries
 268  *
 269  * This function is used to perform lookup in an input device using sparse
 270  * keymap and report corresponding event. Returns %true if lookup was
 271  * successful and %false otherwise.
 272  */
 273 bool sparse_keymap_report_event(struct input_dev *dev, unsigned int code,
 274                                 unsigned int value, bool autorelease)
 275 {
 276         const struct key_entry *ke =
 277                 sparse_keymap_entry_from_scancode(dev, code);
 278         struct key_entry unknown_ke;
 279 
 280         if (ke) {
 281                 sparse_keymap_report_entry(dev, ke, value, autorelease);
 282                 return true;
 283         }
 284 
 285         /* Report an unknown key event as a debugging aid */
 286         unknown_ke.type = KE_KEY;
 287         unknown_ke.code = code;
 288         unknown_ke.keycode = KEY_UNKNOWN;
 289         sparse_keymap_report_entry(dev, &unknown_ke, value, true);
 290 
 291         return false;
 292 }
 293 EXPORT_SYMBOL(sparse_keymap_report_event);
 294 

/* [<][>][^][v][top][bottom][index][help] */