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_DEV(...)                                          \
   66         (hm == NULL ? NULL : hm->dev)
   67 #define HIDMAP_CB_GET_SOFTC(...)                                        \
   68         (hm == NULL ? NULL : device_get_softc(hm->dev))
   69 #define HIDMAP_CB_GET_EVDEV(...)                                        \
   70         (hm == NULL ? NULL : hm->evdev)
   71 #define HIDMAP_CB_UDATA         (hi->udata)
   72 #define HIDMAP_CB_UDATA64       (hi->udata64)
   73 /* Special helpers for run-stage of finalizing callbacks */
   74 #define HIDMAP_CB_GET_RID(...)  (ctx.rid)
   75 #define HIDMAP_CB_GET_DATA(loc)                                         \
   76         hid_get_data(hm->intr_buf, hm->intr_len, (loc))
   77 #define HIDMAP_CB_GET_UDATA(loc)                                        \
   78         hid_get_udata(hm->intr_buf, hm->intr_len, (loc))
   79 
   80 enum hidmap_relabs {
   81         HIDMAP_RELABS_ANY = 0,
   82         HIDMAP_RELATIVE,
   83         HIDMAP_ABSOLUTE,
   84 };
   85 
   86 struct hidmap_item {
   87         union {
   88                 struct {
   89                         uint16_t        type;   /* Evdev event type */
   90                         uint16_t        code;   /* Evdev event code */
   91                         uint16_t        fuzz;   /* Evdev event fuzz */
   92                         uint16_t        flat;   /* Evdev event flat */
   93                 };
   94                 hidmap_cb_t             *cb;    /* Reporting callback */
   95         };
   96         int32_t                 usage;          /* HID usage (base) */
   97         uint16_t                nusages;        /* number of usages */
   98         bool                    required:1;     /* Required by driver */
   99         enum hidmap_relabs      relabs:2;
  100         bool                    has_cb:1;
  101         bool                    final_cb:1;
  102         bool                    invert_value:1;
  103         bool                    forbidden:1;    /* Forbidden by driver */
  104         u_int                   reserved:9;
  105 };
  106 
  107 #define HIDMAP_ANY(_page, _usage, _type, _code)                         \
  108         .usage = HID_USAGE2((_page), (_usage)),                         \
  109         .nusages = 1,                                                   \
  110         .type = (_type),                                                \
  111         .code = (_code)
  112 #define HIDMAP_ANY_RANGE(_page, _usage_from, _usage_to, _type, _code)   \
  113         .usage = HID_USAGE2((_page), (_usage_from)),                    \
  114         .nusages = (_usage_to) - (_usage_from) + 1,                     \
  115         .type = (_type),                                                \
  116         .code = (_code)
  117 #define HIDMAP_ANY_CB(_page, _usage, _callback)                         \
  118         .usage = HID_USAGE2((_page), (_usage)),                         \
  119         .nusages = 1,                                                   \
  120         .cb = (_callback),                                              \
  121         .has_cb = true
  122 #define HIDMAP_ANY_CB_RANGE(_page, _usage_from, _usage_to, _callback)   \
  123         .usage = HID_USAGE2((_page), (_usage_from)),                    \
  124         .nusages = (_usage_to) - (_usage_from) + 1,                     \
  125         .cb = (_callback),                                              \
  126         .has_cb = true
  127 #define HIDMAP_KEY(_page, _usage, _code)                                \
  128         HIDMAP_ANY((_page), (_usage), EV_KEY, (_code)),                 \
  129                 .relabs = HIDMAP_RELABS_ANY
  130 #define HIDMAP_KEY_RANGE(_page, _ufrom, _uto, _code)                    \
  131         HIDMAP_ANY_RANGE((_page), (_ufrom), (_uto), EV_KEY, (_code)),   \
  132                 .relabs = HIDMAP_RELABS_ANY
  133 #define HIDMAP_REL(_page, _usage, _code)                                \
  134         HIDMAP_ANY((_page), (_usage), EV_REL, (_code)),                 \
  135                 .relabs = HIDMAP_RELATIVE
  136 #define HIDMAP_ABS(_page, _usage, _code)                                \
  137         HIDMAP_ANY((_page), (_usage), EV_ABS, (_code)),                 \
  138                 .relabs = HIDMAP_ABSOLUTE
  139 #define HIDMAP_SW(_page, _usage, _code)                                 \
  140         HIDMAP_ANY((_page), (_usage), EV_SW, (_code)),                  \
  141                 .relabs = HIDMAP_RELABS_ANY
  142 #define HIDMAP_REL_CB(_page, _usage, _callback)                         \
  143         HIDMAP_ANY_CB((_page), (_usage), (_callback)),                  \
  144                 .relabs = HIDMAP_RELATIVE
  145 #define HIDMAP_ABS_CB(_page, _usage, _callback)                         \
  146         HIDMAP_ANY_CB((_page), (_usage), (_callback)),                  \
  147                 .relabs = HIDMAP_ABSOLUTE
  148 /*
  149  * Special callback function which is not tied to particular HID input usage
  150  * but called at the end evdev properties setting or interrupt handler
  151  * just before evdev_register() or evdev_sync() calls.
  152  */
  153 #define HIDMAP_FINAL_CB(_callback)                                      \
  154         HIDMAP_ANY_CB(0, 0, (_callback)), .final_cb = true
  155 
  156 enum hidmap_type {
  157         HIDMAP_TYPE_FINALCB = 0,/* No HID item associated. Runs unconditionally
  158                                  * at the end of other items processing */
  159         HIDMAP_TYPE_CALLBACK,   /* HID item is reported with user callback */
  160         HIDMAP_TYPE_VARIABLE,   /* HID item is variable (single usage) */
  161         HIDMAP_TYPE_VAR_NULLST, /* HID item is null state variable */
  162         HIDMAP_TYPE_ARR_LIST,   /* HID item is array with list of usages */
  163         HIDMAP_TYPE_ARR_RANGE,  /* Array with range (min;max) of usages */
  164 };
  165 
  166 struct hidmap_hid_item {
  167         union {
  168                 hidmap_cb_t     *cb;            /* Callback */
  169                 struct {                        /* Variable */
  170                         uint16_t        evtype; /* Evdev event type */
  171                         uint16_t        code;   /* Evdev event code */
  172                 };
  173                 uint16_t        *codes;         /* Array list map type */
  174                 int32_t         umin;           /* Array range map type */
  175         };
  176         union {
  177                 void            *udata;         /* Callback private context */
  178                 uint64_t        udata64;
  179                 int32_t         last_val;       /* Last reported value (var) */
  180                 uint16_t        last_key;       /* Last reported key (array) */
  181         };
  182         struct hid_location     loc;            /* HID item location */
  183         int32_t                 lmin;           /* HID item logical minimum */
  184         int32_t                 lmax;           /* HID item logical maximum */
  185         enum hidmap_type        type:8;
  186         uint8_t                 id;             /* Report ID */
  187         bool                    invert_value;
  188 };
  189 
  190 struct hidmap {
  191         device_t                dev;
  192 
  193         struct evdev_dev        *evdev;
  194         struct evdev_methods    evdev_methods;
  195 
  196         /* Scatter-gather list of maps */
  197         int                     nmaps;
  198         uint32_t                nmap_items[HIDMAP_MAX_MAPS];
  199         const struct hidmap_item        *map[HIDMAP_MAX_MAPS];
  200 
  201         /* List of preparsed HID items */
  202         uint32_t                nhid_items;
  203         struct hidmap_hid_item  *hid_items;
  204 
  205         /* Key event merging buffers */
  206         uint8_t                 *key_press;
  207         uint8_t                 *key_rel;
  208         uint16_t                key_min;
  209         uint16_t                key_max;
  210 
  211         int                     *debug_var;
  212         int                     debug_level;
  213         enum hidmap_cb_state    cb_state;
  214         void *                  intr_buf;
  215         hid_size_t              intr_len;
  216 };
  217 
  218 typedef uint8_t *               hidmap_caps_t;
  219 #define HIDMAP_CAPS_SZ(nitems)  howmany((nitems), 8)
  220 #define HIDMAP_CAPS(name, map)  uint8_t (name)[HIDMAP_CAPS_SZ(nitems(map))]
  221 static inline bool
  222 hidmap_test_cap(hidmap_caps_t caps, int cap)
  223 {
  224         return (isset(caps, cap) != 0);
  225 }
  226 
  227 /*
  228  * It is safe to call any of following procedures in device_probe context
  229  * that makes possible to write probe-only drivers with attach/detach handlers
  230  * inherited from hidmap. See hcons and hsctrl drivers for example.
  231  */
  232 static inline void
  233 hidmap_set_dev(struct hidmap *hm, device_t dev)
  234 {
  235         hm->dev = dev;
  236 }
  237 
  238 /* Hack to avoid #ifdef-ing of hidmap_set_debug_var in hidmap based drivers */
  239 #ifdef HID_DEBUG
  240 #define hidmap_set_debug_var(h, d)      _hidmap_set_debug_var((h), (d))
  241 #else
  242 #define hidmap_set_debug_var(...)
  243 #endif
  244 void    _hidmap_set_debug_var(struct hidmap *hm, int *debug_var);
  245 #define HIDMAP_ADD_MAP(hm, map, caps)                                   \
  246         hidmap_add_map((hm), (map), nitems(map), (caps))
  247 uint32_t hidmap_add_map(struct hidmap *hm, const struct hidmap_item *map,
  248             int nitems_map, hidmap_caps_t caps);
  249 
  250 /* Versions of evdev_* functions capable to merge key events with same codes */
  251 void    hidmap_support_key(struct hidmap *hm, uint16_t key);
  252 void    hidmap_push_key(struct hidmap *hm, uint16_t key, int32_t value);
  253 
  254 void    hidmap_intr(void *context, void *buf, hid_size_t len);
  255 #define HIDMAP_PROBE(hm, dev, id, map, suffix)                          \
  256         hidmap_probe((hm), (dev), (id), nitems(id), (map), nitems(map), \
  257             (suffix), NULL)
  258 int     hidmap_probe(struct hidmap* hm, device_t dev,
  259             const struct hid_device_id *id, int nitems_id,
  260             const struct hidmap_item *map, int nitems_map,
  261             const char *suffix, hidmap_caps_t caps);
  262 int     hidmap_attach(struct hidmap *hm);
  263 int     hidmap_detach(struct hidmap *hm);
  264 
  265 #endif  /* _HIDMAP_H_ */

Cache object: f71249faa905570fedd6893ebffb6bee


[ 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.