LCOV - code coverage report
Current view: top level - drivers/input - sparse-keymap.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 0 114 0.0 %
Date: 2022-03-28 15:32:58 Functions: 0 8 0.0 %
Branches: 0 77 0.0 %

           Branch data     Line data    Source code
       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                 :          0 : static unsigned int sparse_keymap_get_key_index(struct input_dev *dev,
      23                 :            :                                                 const struct key_entry *k)
      24                 :            : {
      25                 :          0 :         struct key_entry *key;
      26                 :          0 :         unsigned int idx = 0;
      27                 :            : 
      28         [ #  # ]:          0 :         for (key = dev->keycode; key->type != KE_END; key++) {
      29         [ #  # ]:          0 :                 if (key->type == KE_KEY) {
      30         [ #  # ]:          0 :                         if (key == k)
      31                 :            :                                 break;
      32                 :          0 :                         idx++;
      33                 :            :                 }
      34                 :            :         }
      35                 :            : 
      36                 :          0 :         return idx;
      37                 :            : }
      38                 :            : 
      39                 :          0 : static struct key_entry *sparse_keymap_entry_by_index(struct input_dev *dev,
      40                 :            :                                                       unsigned int index)
      41                 :            : {
      42                 :          0 :         struct key_entry *key;
      43                 :          0 :         unsigned int key_cnt = 0;
      44                 :            : 
      45         [ #  # ]:          0 :         for (key = dev->keycode; key->type != KE_END; key++)
      46         [ #  # ]:          0 :                 if (key->type == KE_KEY)
      47         [ #  # ]:          0 :                         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                 :          0 : struct key_entry *sparse_keymap_entry_from_scancode(struct input_dev *dev,
      62                 :            :                                                     unsigned int code)
      63                 :            : {
      64                 :          0 :         struct key_entry *key;
      65                 :            : 
      66   [ #  #  #  #  :          0 :         for (key = dev->keycode; key->type != KE_END; key++)
                   #  # ]
      67   [ #  #  #  #  :          0 :                 if (code == key->code)
                   #  # ]
      68                 :          0 :                         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                 :          0 : struct key_entry *sparse_keymap_entry_from_keycode(struct input_dev *dev,
      83                 :            :                                                    unsigned int keycode)
      84                 :            : {
      85                 :          0 :         struct key_entry *key;
      86                 :            : 
      87   [ #  #  #  # ]:          0 :         for (key = dev->keycode; key->type != KE_END; key++)
      88   [ #  #  #  #  :          0 :                 if (key->type == KE_KEY && keycode == key->keycode)
             #  #  #  # ]
      89                 :          0 :                         return key;
      90                 :            : 
      91                 :            :         return NULL;
      92                 :            : }
      93                 :            : EXPORT_SYMBOL(sparse_keymap_entry_from_keycode);
      94                 :            : 
      95                 :          0 : static struct key_entry *sparse_keymap_locate(struct input_dev *dev,
      96                 :            :                                         const struct input_keymap_entry *ke)
      97                 :            : {
      98                 :          0 :         struct key_entry *key;
      99                 :          0 :         unsigned int scancode;
     100                 :            : 
     101         [ #  # ]:          0 :         if (ke->flags & INPUT_KEYMAP_BY_INDEX)
     102                 :          0 :                 key = sparse_keymap_entry_by_index(dev, ke->index);
     103         [ #  # ]:          0 :         else if (input_scancode_to_scalar(ke, &scancode) == 0)
     104                 :          0 :                 key = sparse_keymap_entry_from_scancode(dev, scancode);
     105                 :            :         else
     106                 :            :                 key = NULL;
     107                 :            : 
     108                 :          0 :         return key;
     109                 :            : }
     110                 :            : 
     111                 :          0 : static int sparse_keymap_getkeycode(struct input_dev *dev,
     112                 :            :                                     struct input_keymap_entry *ke)
     113                 :            : {
     114                 :          0 :         const struct key_entry *key;
     115                 :            : 
     116         [ #  # ]:          0 :         if (dev->keycode) {
     117                 :          0 :                 key = sparse_keymap_locate(dev, ke);
     118   [ #  #  #  # ]:          0 :                 if (key && key->type == KE_KEY) {
     119                 :          0 :                         ke->keycode = key->keycode;
     120         [ #  # ]:          0 :                         if (!(ke->flags & INPUT_KEYMAP_BY_INDEX))
     121                 :          0 :                                 ke->index =
     122                 :          0 :                                         sparse_keymap_get_key_index(dev, key);
     123                 :          0 :                         ke->len = sizeof(key->code);
     124                 :          0 :                         memcpy(ke->scancode, &key->code, sizeof(key->code));
     125                 :          0 :                         return 0;
     126                 :            :                 }
     127                 :            :         }
     128                 :            : 
     129                 :            :         return -EINVAL;
     130                 :            : }
     131                 :            : 
     132                 :          0 : static int sparse_keymap_setkeycode(struct input_dev *dev,
     133                 :            :                                     const struct input_keymap_entry *ke,
     134                 :            :                                     unsigned int *old_keycode)
     135                 :            : {
     136                 :          0 :         struct key_entry *key;
     137                 :            : 
     138         [ #  # ]:          0 :         if (dev->keycode) {
     139                 :          0 :                 key = sparse_keymap_locate(dev, ke);
     140   [ #  #  #  # ]:          0 :                 if (key && key->type == KE_KEY) {
     141                 :          0 :                         *old_keycode = key->keycode;
     142                 :          0 :                         key->keycode = ke->keycode;
     143                 :          0 :                         set_bit(ke->keycode, dev->keybit);
     144         [ #  # ]:          0 :                         if (!sparse_keymap_entry_from_keycode(dev, *old_keycode))
     145                 :          0 :                                 clear_bit(*old_keycode, dev->keybit);
     146                 :          0 :                         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                 :          0 : 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                 :          0 :         size_t map_size = 1; /* to account for the last KE_END entry */
     171                 :          0 :         const struct key_entry *e;
     172                 :          0 :         struct key_entry *map, *entry;
     173                 :          0 :         int i;
     174                 :          0 :         int error;
     175                 :            : 
     176         [ #  # ]:          0 :         for (e = keymap; e->type != KE_END; e++)
     177                 :          0 :                 map_size++;
     178                 :            : 
     179                 :          0 :         map = devm_kmemdup(&dev->dev, keymap, map_size * sizeof(*map),
     180                 :            :                            GFP_KERNEL);
     181         [ #  # ]:          0 :         if (!map)
     182                 :            :                 return -ENOMEM;
     183                 :            : 
     184         [ #  # ]:          0 :         for (i = 0; i < map_size; i++) {
     185                 :          0 :                 entry = &map[i];
     186                 :            : 
     187         [ #  # ]:          0 :                 if (setup) {
     188                 :          0 :                         error = setup(dev, entry);
     189         [ #  # ]:          0 :                         if (error)
     190                 :          0 :                                 return error;
     191                 :            :                 }
     192                 :            : 
     193      [ #  #  # ]:          0 :                 switch (entry->type) {
     194                 :          0 :                 case KE_KEY:
     195                 :          0 :                         __set_bit(EV_KEY, dev->evbit);
     196                 :          0 :                         __set_bit(entry->keycode, dev->keybit);
     197                 :            :                         break;
     198                 :            : 
     199                 :          0 :                 case KE_SW:
     200                 :            :                 case KE_VSW:
     201                 :          0 :                         __set_bit(EV_SW, dev->evbit);
     202                 :          0 :                         __set_bit(entry->sw.code, dev->swbit);
     203                 :            :                         break;
     204                 :            :                 }
     205                 :          0 :         }
     206                 :            : 
     207                 :          0 :         if (test_bit(EV_KEY, dev->evbit)) {
     208                 :          0 :                 __set_bit(KEY_UNKNOWN, dev->keybit);
     209                 :          0 :                 __set_bit(EV_MSC, dev->evbit);
     210                 :          0 :                 __set_bit(MSC_SCAN, dev->mscbit);
     211                 :            :         }
     212                 :            : 
     213                 :          0 :         dev->keycode = map;
     214                 :          0 :         dev->keycodemax = map_size;
     215                 :          0 :         dev->getkeycode = sparse_keymap_getkeycode;
     216                 :          0 :         dev->setkeycode = sparse_keymap_setkeycode;
     217                 :            : 
     218                 :          0 :         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                 :          0 : void sparse_keymap_report_entry(struct input_dev *dev, const struct key_entry *ke,
     235                 :            :                                 unsigned int value, bool autorelease)
     236                 :            : {
     237   [ #  #  #  # ]:          0 :         switch (ke->type) {
     238                 :          0 :         case KE_KEY:
     239                 :          0 :                 input_event(dev, EV_MSC, MSC_SCAN, ke->code);
     240                 :          0 :                 input_report_key(dev, ke->keycode, value);
     241                 :          0 :                 input_sync(dev);
     242         [ #  # ]:          0 :                 if (value && autorelease) {
     243                 :          0 :                         input_report_key(dev, ke->keycode, 0);
     244                 :          0 :                         input_sync(dev);
     245                 :            :                 }
     246                 :            :                 break;
     247                 :            : 
     248                 :          0 :         case KE_SW:
     249                 :          0 :                 value = ke->sw.value;
     250                 :            :                 /* fall through */
     251                 :            : 
     252                 :          0 :         case KE_VSW:
     253                 :          0 :                 input_report_switch(dev, ke->sw.code, value);
     254                 :          0 :                 input_sync(dev);
     255                 :            :                 break;
     256                 :            :         }
     257                 :          0 : }
     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                 :          0 : bool sparse_keymap_report_event(struct input_dev *dev, unsigned int code,
     274                 :            :                                 unsigned int value, bool autorelease)
     275                 :            : {
     276                 :          0 :         const struct key_entry *ke =
     277                 :            :                 sparse_keymap_entry_from_scancode(dev, code);
     278                 :          0 :         struct key_entry unknown_ke;
     279                 :            : 
     280         [ #  # ]:          0 :         if (ke) {
     281                 :          0 :                 sparse_keymap_report_entry(dev, ke, value, autorelease);
     282                 :          0 :                 return true;
     283                 :            :         }
     284                 :            : 
     285                 :            :         /* Report an unknown key event as a debugging aid */
     286                 :          0 :         unknown_ke.type = KE_KEY;
     287                 :          0 :         unknown_ke.code = code;
     288                 :          0 :         unknown_ke.keycode = KEY_UNKNOWN;
     289                 :          0 :         sparse_keymap_report_entry(dev, &unknown_ke, value, true);
     290                 :            : 
     291                 :          0 :         return false;
     292                 :            : }
     293                 :            : EXPORT_SYMBOL(sparse_keymap_report_event);
     294                 :            : 

Generated by: LCOV version 1.14