The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/hid/hidmap.h

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
    3  *
    4  * Copyright (c) 2020 Vladimir Kondratyev <wulf@FreeBSD.org>
    5  *
    6  * Redistribution and use in source and binary forms, with or without
    7  * modification, are permitted provided that the following conditions
    8  * are met:
    9  * 1. Redistributions of source code must retain the above copyright
   10  *    notice, this list of conditions and the following disclaimer.
   11  * 2. Redistributions in binary form must reproduce the above copyright
   12  *    notice, this list of conditions and the following disclaimer in the
   13  *    documentation and/or other materials provided with the distribution.
   14  *
   15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   25  * SUCH DAMAGE.
   26  */
   27 
   28 #ifndef _HIDMAP_H_
   29 #define _HIDMAP_H_
   30 
   31 #include <sys/param.h>
   32 
   33 #include <dev/hid/hid.h>
   34 
   35 #define HIDMAP_MAX_MAPS 4
   36 
   37 struct hid_device_id;
   38 struct hidmap_hid_item;
   39 struct hidmap_item;
   40 struct hidmap;
   41 
   42 enum hidmap_cb_state {
   43         HIDMAP_CB_IS_PROBING,
   44         HIDMAP_CB_IS_ATTACHING,
   45         HIDMAP_CB_IS_RUNNING,
   46         HIDMAP_CB_IS_DETACHING,
   47 };
   48 
   49 #define HIDMAP_KEY_NULL 0xFF    /* Special event code to discard input */
   50 
   51 /* Third parameter of hidmap callback has different type depending on state */
   52 union hidmap_cb_ctx {
   53         struct hid_item *hi;    /* Probe- and attach-stage callbacks */
   54         int32_t         data;   /* Run-stage callbacks */
   55         uint8_t         rid;    /* Run-stage finalizing callbacks */
   56 };
   57 
   58 #define HIDMAP_CB_ARGS                                                  \
   59         struct hidmap *hm, struct hidmap_hid_item *hi, union hidmap_cb_ctx ctx
   60 typedef int hidmap_cb_t(HIDMAP_CB_ARGS);
   61 
   62 /* These helpers can be used at any stage of any callbacks */
   63 #define HIDMAP_CB_GET_STATE(...)                                        \
   64         ((hm == NULL) ? HIDMAP_CB_IS_PROBING : hm->cb_state)
   65 #define HIDMAP_CB_GET_SOFTC(...)                                        \
   66         (hm == NULL ? NULL : device_get_softc(hm->dev))
   67 #define HIDMAP_CB_GET_EVDEV(...)                                        \
   68         (hm == NULL ? NULL : hm->evdev)
   69 #define HIDMAP_CB_UDATA         (hi->udata)
   70 #define HIDMAP_CB_UDATA64       (hi->udata64)
   71 /* Special helpers for run-stage of finalizing callbacks */
   72 #define HIDMAP_CB_GET_RID(...)  (ctx.rid)
   73 #define HIDMAP_CB_GET_DATA(loc)                                         \
   74         hid_get_data(hm->intr_buf, hm->intr_len, (loc))
   75 #define HIDMAP_CB_GET_UDATA(loc)                                        \
   76         hid_get_udata(hm->intr_buf, hm->intr_len, (loc))
   77 
   78 enum hidmap_relabs {
   79         HIDMAP_RELABS_ANY = 0,
   80         HIDMAP_RELATIVE,
   81         HIDMAP_ABSOLUTE,
   82 };
   83 
   84 struct hidmap_item {
   85         union {
   86                 struct {
   87                         uint16_t        type;   /* Evdev event type */
   88                         uint16_t        code;   /* Evdev event code */
   89                         uint16_t        fuzz;   /* Evdev event fuzz */
   90                         uint16_t        flat;   /* Evdev event flat */
   91                 };
   92                 hidmap_cb_t             *cb;    /* Reporting callback */
   93         };
   94         int32_t                 usage;          /* HID usage (base) */
   95         uint16_t                nusages;        /* number of usages */
   96         bool                    required:1;     /* Required by driver */
   97         enum hidmap_relabs      relabs:2;
   98         bool                    has_cb:1;
   99         bool                    final_cb:1;
  100         bool                    invert_value:1;
  101         u_int                   reserved:10;
  102 };
  103 
  104 #define HIDMAP_ANY(_page, _usage, _type, _code)                         \
  105         .usage = HID_USAGE2((_page), (_usage)),                         \
  106         .nusages = 1,                                                   \
  107         .type = (_type),                                                \
  108         .code = (_code)
  109 #define HIDMAP_ANY_RANGE(_page, _usage_from, _usage_to, _type, _code)   \
  110         .usage = HID_USAGE2((_page), (_usage_from)),                    \
  111         .nusages = (_usage_to) - (_usage_from) + 1,                     \
  112         .type = (_type),                                                \
  113         .code = (_code)
  114 #define HIDMAP_ANY_CB(_page, _usage, _callback)                         \
  115         .usage = HID_USAGE2((_page), (_usage)),                         \
  116         .nusages = 1,                                                   \
  117         .cb = (_callback),                                              \
  118         .has_cb = true
  119 #define HIDMAP_ANY_CB_RANGE(_page, _usage_from, _usage_to, _callback)   \
  120         .usage = HID_USAGE2((_page), (_usage_from)),                    \
  121         .nusages = (_usage_to) - (_usage_from) + 1,                     \
  122         .cb = (_callback),                                              \
  123         .has_cb = true
  124 #define HIDMAP_KEY(_page, _usage, _code)                                \
  125         HIDMAP_ANY((_page), (_usage), EV_KEY, (_code)),                 \
  126                 .relabs = HIDMAP_RELABS_ANY
  127 #define HIDMAP_KEY_RANGE(_page, _ufrom, _uto, _code)                    \
  128         HIDMAP_ANY_RANGE((_page), (_ufrom), (_uto), EV_KEY, (_code)),   \
  129                 .relabs = HIDMAP_RELABS_ANY
  130 #define HIDMAP_REL(_page, _usage, _code)                                \
  131         HIDMAP_ANY((_page), (_usage), EV_REL, (_code)),                 \
  132                 .relabs = HIDMAP_RELATIVE
  133 #define HIDMAP_ABS(_page, _usage, _code)                                \
  134         HIDMAP_ANY((_page), (_usage), EV_ABS, (_code)),                 \
  135                 .relabs = HIDMAP_ABSOLUTE
  136 #define HIDMAP_SW(_page, _usage, _code)                                 \
  137         HIDMAP_ANY((_page), (_usage), EV_SW, (_code)),                  \
  138                 .relabs = HIDMAP_RELABS_ANY
  139 #define HIDMAP_REL_CB(_page, _usage, _callback)                         \
  140         HIDMAP_ANY_CB((_page), (_usage), (_callback)),                  \
  141                 .relabs = HIDMAP_RELATIVE
  142 #define HIDMAP_ABS_CB(_page, _usage, _callback)                         \
  143         HIDMAP_ANY_CB((_page), (_usage), (_callback)),                  \
  144                 .relabs = HIDMAP_ABSOLUTE
  145 /*
  146  * Special callback function which is not tied to particular HID input usage
  147  * but called at the end evdev properties setting or interrupt handler
  148  * just before evdev_register() or evdev_sync() calls.
  149  */
  150 #define HIDMAP_FINAL_CB(_callback)                                      \
  151         HIDMAP_ANY_CB(0, 0, (_callback)), .final_cb = true
  152 
  153 enum hidmap_type {
  154         HIDMAP_TYPE_FINALCB = 0,/* No HID item associated. Runs unconditionally
  155                                  * at the end of other items processing */
  156         HIDMAP_TYPE_CALLBACK,   /* HID item is reported with user callback */
  157         HIDMAP_TYPE_VARIABLE,   /* HID item is variable (single usage) */
  158         HIDMAP_TYPE_VAR_NULLST, /* HID item is null state variable */
  159         HIDMAP_TYPE_ARR_LIST,   /* HID item is array with list of usages */
  160         HIDMAP_TYPE_ARR_RANGE,  /* Array with range (min;max) of usages */
  161 };
  162 
  163 struct hidmap_hid_item {
  164         union {
  165                 hidmap_cb_t     *cb;            /* Callback */
  166                 struct {                        /* Variable */
  167                         uint16_t        evtype; /* Evdev event type */
  168                         uint16_t        code;   /* Evdev event code */
  169                 };
  170                 uint16_t        *codes;         /* Array list map type */
  171                 int32_t         umin;           /* Array range map type */
  172         };
  173         union {
  174                 void            *udata;         /* Callback private context */
  175                 uint64_t        udata64;
  176                 int32_t         last_val;       /* Last reported value (var) */
  177                 uint16_t        last_key;       /* Last reported key (array) */
  178         };
  179         struct hid_location     loc;            /* HID item location */
  180         int32_t                 lmin;           /* HID item logical minimum */
  181         int32_t                 lmax;           /* HID item logical maximum */
  182         enum hidmap_type        type:8;
  183         uint8_t                 id;             /* Report ID */
  184         bool                    invert_value;
  185 };
  186 
  187 struct hidmap {
  188         device_t                dev;
  189 
  190         struct evdev_dev        *evdev;
  191         struct evdev_methods    evdev_methods;
  192 
  193         /* Scatter-gather list of maps */
  194         int                     nmaps;
  195         uint32_t                nmap_items[HIDMAP_MAX_MAPS];
  196         const struct hidmap_item        *map[HIDMAP_MAX_MAPS];
  197 
  198         /* List of preparsed HID items */
  199         uint32_t                nhid_items;
  200         struct hidmap_hid_item  *hid_items;
  201 
  202         /* Key event merging buffers */
  203         uint8_t                 *key_press;
  204         uint8_t                 *key_rel;
  205         uint16_t                key_min;
  206         uint16_t                key_max;
  207 
  208         int                     *debug_var;
  209         int                     debug_level;
  210         enum hidmap_cb_state    cb_state;
  211         void *                  intr_buf;
  212         hid_size_t              intr_len;
  213 };
  214 
  215 typedef uint8_t *               hidmap_caps_t;
  216 #define HIDMAP_CAPS_SZ(nitems)  howmany((nitems), 8)
  217 #define HIDMAP_CAPS(name, map)  uint8_t (name)[HIDMAP_CAPS_SZ(nitems(map))]
  218 static inline bool
  219 hidmap_test_cap(hidmap_caps_t caps, int cap)
  220 {
  221         return (isset(caps, cap) != 0);
  222 }
  223 
  224 /*
  225  * It is safe to call any of following procedures in device_probe context
  226  * that makes possible to write probe-only drivers with attach/detach handlers
  227  * inherited from hidmap. See hcons and hsctrl drivers for example.
  228  */
  229 static inline void
  230 hidmap_set_dev(struct hidmap *hm, device_t dev)
  231 {
  232         hm->dev = dev;
  233 }
  234 
  235 /* Hack to avoid #ifdef-ing of hidmap_set_debug_var in hidmap based drivers */
  236 #ifdef HID_DEBUG
  237 #define hidmap_set_debug_var(h, d)      _hidmap_set_debug_var((h), (d))
  238 #else
  239 #define hidmap_set_debug_var(...)
  240 #endif
  241 void    _hidmap_set_debug_var(struct hidmap *hm, int *debug_var);
  242 #define HIDMAP_ADD_MAP(hm, map, caps)                                   \
  243         hidmap_add_map((hm), (map), nitems(map), (caps))
  244 uint32_t hidmap_add_map(struct hidmap *hm, const struct hidmap_item *map,
  245             int nitems_map, hidmap_caps_t caps);
  246 
  247 /* Versions of evdev_* functions capable to merge key events with same codes */
  248 void    hidmap_support_key(struct hidmap *hm, uint16_t key);
  249 void    hidmap_push_key(struct hidmap *hm, uint16_t key, int32_t value);
  250 
  251 void    hidmap_intr(void *context, void *buf, hid_size_t len);
  252 #define HIDMAP_PROBE(hm, dev, id, map, suffix)                          \
  253         hidmap_probe((hm), (dev), (id), nitems(id), (map), nitems(map), \
  254             (suffix), NULL)
  255 int     hidmap_probe(struct hidmap* hm, device_t dev,
  256             const struct hid_device_id *id, int nitems_id,
  257             const struct hidmap_item *map, int nitems_map,
  258             const char *suffix, hidmap_caps_t caps);
  259 int     hidmap_attach(struct hidmap *hm);
  260 int     hidmap_detach(struct hidmap *hm);
  261 
  262 #endif  /* _HIDMAP_H_ */

Cache object: 5a418a352c5942f62efa015136cc52eb


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.