1*2b4464b0SVladimir Kondratyev /*- 2*2b4464b0SVladimir Kondratyev * Copyright (c) 2019 Vladimir Kondratyev <wulf@FreeBSD.org> 3*2b4464b0SVladimir Kondratyev * 4*2b4464b0SVladimir Kondratyev * Redistribution and use in source and binary forms, with or without 5*2b4464b0SVladimir Kondratyev * modification, are permitted provided that the following conditions 6*2b4464b0SVladimir Kondratyev * are met: 7*2b4464b0SVladimir Kondratyev * 1. Redistributions of source code must retain the above copyright 8*2b4464b0SVladimir Kondratyev * notice, this list of conditions and the following disclaimer. 9*2b4464b0SVladimir Kondratyev * 2. Redistributions in binary form must reproduce the above copyright 10*2b4464b0SVladimir Kondratyev * notice, this list of conditions and the following disclaimer in the 11*2b4464b0SVladimir Kondratyev * documentation and/or other materials provided with the distribution. 12*2b4464b0SVladimir Kondratyev * 13*2b4464b0SVladimir Kondratyev * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 14*2b4464b0SVladimir Kondratyev * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15*2b4464b0SVladimir Kondratyev * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16*2b4464b0SVladimir Kondratyev * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 17*2b4464b0SVladimir Kondratyev * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18*2b4464b0SVladimir Kondratyev * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19*2b4464b0SVladimir Kondratyev * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20*2b4464b0SVladimir Kondratyev * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21*2b4464b0SVladimir Kondratyev * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22*2b4464b0SVladimir Kondratyev * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23*2b4464b0SVladimir Kondratyev * SUCH DAMAGE. 24*2b4464b0SVladimir Kondratyev */ 25*2b4464b0SVladimir Kondratyev 26*2b4464b0SVladimir Kondratyev #ifndef _HID_HIDBUS_H_ 27*2b4464b0SVladimir Kondratyev #define _HID_HIDBUS_H_ 28*2b4464b0SVladimir Kondratyev 29*2b4464b0SVladimir Kondratyev enum { 30*2b4464b0SVladimir Kondratyev HIDBUS_IVAR_USAGE, 31*2b4464b0SVladimir Kondratyev HIDBUS_IVAR_INDEX, 32*2b4464b0SVladimir Kondratyev HIDBUS_IVAR_FLAGS, 33*2b4464b0SVladimir Kondratyev #define HIDBUS_FLAG_AUTOCHILD (0<<1) /* Child is autodiscovered */ 34*2b4464b0SVladimir Kondratyev #define HIDBUS_FLAG_CAN_POLL (1<<1) /* Child can work during panic */ 35*2b4464b0SVladimir Kondratyev HIDBUS_IVAR_DRIVER_INFO, 36*2b4464b0SVladimir Kondratyev HIDBUS_IVAR_LOCK, 37*2b4464b0SVladimir Kondratyev }; 38*2b4464b0SVladimir Kondratyev 39*2b4464b0SVladimir Kondratyev #define HIDBUS_ACCESSOR(A, B, T) \ 40*2b4464b0SVladimir Kondratyev __BUS_ACCESSOR(hidbus, A, HIDBUS, B, T) 41*2b4464b0SVladimir Kondratyev 42*2b4464b0SVladimir Kondratyev HIDBUS_ACCESSOR(usage, USAGE, int32_t) 43*2b4464b0SVladimir Kondratyev HIDBUS_ACCESSOR(index, INDEX, uint8_t) 44*2b4464b0SVladimir Kondratyev HIDBUS_ACCESSOR(flags, FLAGS, uint32_t) 45*2b4464b0SVladimir Kondratyev HIDBUS_ACCESSOR(driver_info, DRIVER_INFO, uintptr_t) 46*2b4464b0SVladimir Kondratyev HIDBUS_ACCESSOR(lock, LOCK, struct mtx *) 47*2b4464b0SVladimir Kondratyev 48*2b4464b0SVladimir Kondratyev /* 49*2b4464b0SVladimir Kondratyev * The following structure is used when looking up an HID driver for 50*2b4464b0SVladimir Kondratyev * an HID device. It is inspired by the structure called "usb_device_id". 51*2b4464b0SVladimir Kondratyev * which is originated in Linux and ported to FreeBSD. 52*2b4464b0SVladimir Kondratyev */ 53*2b4464b0SVladimir Kondratyev struct hid_device_id { 54*2b4464b0SVladimir Kondratyev 55*2b4464b0SVladimir Kondratyev /* Select which fields to match against */ 56*2b4464b0SVladimir Kondratyev #if BYTE_ORDER == LITTLE_ENDIAN 57*2b4464b0SVladimir Kondratyev uint16_t 58*2b4464b0SVladimir Kondratyev match_flag_page:1, 59*2b4464b0SVladimir Kondratyev match_flag_usage:1, 60*2b4464b0SVladimir Kondratyev match_flag_bus:1, 61*2b4464b0SVladimir Kondratyev match_flag_vendor:1, 62*2b4464b0SVladimir Kondratyev match_flag_product:1, 63*2b4464b0SVladimir Kondratyev match_flag_ver_lo:1, 64*2b4464b0SVladimir Kondratyev match_flag_ver_hi:1, 65*2b4464b0SVladimir Kondratyev match_flag_pnp:1, 66*2b4464b0SVladimir Kondratyev match_flag_unused:8; 67*2b4464b0SVladimir Kondratyev #else 68*2b4464b0SVladimir Kondratyev uint16_t 69*2b4464b0SVladimir Kondratyev match_flag_unused:8, 70*2b4464b0SVladimir Kondratyev match_flag_pnp:1, 71*2b4464b0SVladimir Kondratyev match_flag_ver_hi:1, 72*2b4464b0SVladimir Kondratyev match_flag_ver_lo:1, 73*2b4464b0SVladimir Kondratyev match_flag_product:1, 74*2b4464b0SVladimir Kondratyev match_flag_vendor:1, 75*2b4464b0SVladimir Kondratyev match_flag_bus:1, 76*2b4464b0SVladimir Kondratyev match_flag_usage:1, 77*2b4464b0SVladimir Kondratyev match_flag_page:1; 78*2b4464b0SVladimir Kondratyev #endif 79*2b4464b0SVladimir Kondratyev 80*2b4464b0SVladimir Kondratyev /* Used for top level collection usage matches */ 81*2b4464b0SVladimir Kondratyev uint16_t page; 82*2b4464b0SVladimir Kondratyev uint16_t usage; 83*2b4464b0SVladimir Kondratyev 84*2b4464b0SVladimir Kondratyev /* Used for product specific matches; the Version range is inclusive */ 85*2b4464b0SVladimir Kondratyev uint8_t idBus; 86*2b4464b0SVladimir Kondratyev uint16_t idVendor; 87*2b4464b0SVladimir Kondratyev uint16_t idProduct; 88*2b4464b0SVladimir Kondratyev uint16_t idVersion_lo; 89*2b4464b0SVladimir Kondratyev uint16_t idVersion_hi; 90*2b4464b0SVladimir Kondratyev char *idPnP; 91*2b4464b0SVladimir Kondratyev 92*2b4464b0SVladimir Kondratyev /* Hook for driver specific information */ 93*2b4464b0SVladimir Kondratyev uintptr_t driver_info; 94*2b4464b0SVladimir Kondratyev }; 95*2b4464b0SVladimir Kondratyev 96*2b4464b0SVladimir Kondratyev #define HID_STD_PNP_INFO \ 97*2b4464b0SVladimir Kondratyev "M16:mask;U16:page;U16:usage;U8:bus;U16:vendor;U16:product;" \ 98*2b4464b0SVladimir Kondratyev "L16:version;G16:version;Z:_HID" 99*2b4464b0SVladimir Kondratyev #define HID_PNP_INFO(table) \ 100*2b4464b0SVladimir Kondratyev MODULE_PNP_INFO(HID_STD_PNP_INFO, hidbus, table, table, nitems(table)) 101*2b4464b0SVladimir Kondratyev 102*2b4464b0SVladimir Kondratyev #define HID_TLC(pg,usg) \ 103*2b4464b0SVladimir Kondratyev .match_flag_page = 1, .match_flag_usage = 1, .page = (pg), .usage = (usg) 104*2b4464b0SVladimir Kondratyev 105*2b4464b0SVladimir Kondratyev #define HID_BUS(bus) \ 106*2b4464b0SVladimir Kondratyev .match_flag_bus = 1, .idBus = (bus) 107*2b4464b0SVladimir Kondratyev 108*2b4464b0SVladimir Kondratyev #define HID_VENDOR(vend) \ 109*2b4464b0SVladimir Kondratyev .match_flag_vendor = 1, .idVendor = (vend) 110*2b4464b0SVladimir Kondratyev 111*2b4464b0SVladimir Kondratyev #define HID_PRODUCT(prod) \ 112*2b4464b0SVladimir Kondratyev .match_flag_product = 1, .idProduct = (prod) 113*2b4464b0SVladimir Kondratyev 114*2b4464b0SVladimir Kondratyev #define HID_VP(vend,prod) \ 115*2b4464b0SVladimir Kondratyev HID_VENDOR(vend), HID_PRODUCT(prod) 116*2b4464b0SVladimir Kondratyev 117*2b4464b0SVladimir Kondratyev #define HID_BVP(bus,vend,prod) \ 118*2b4464b0SVladimir Kondratyev HID_BUS(bus), HID_VENDOR(vend), HID_PRODUCT(prod) 119*2b4464b0SVladimir Kondratyev 120*2b4464b0SVladimir Kondratyev #define HID_BVPI(bus,vend,prod,info) \ 121*2b4464b0SVladimir Kondratyev HID_BUS(bus), HID_VENDOR(vend), HID_PRODUCT(prod), HID_DRIVER_INFO(info) 122*2b4464b0SVladimir Kondratyev 123*2b4464b0SVladimir Kondratyev #define HID_VERSION_GTEQ(lo) /* greater than or equal */ \ 124*2b4464b0SVladimir Kondratyev .match_flag_ver_lo = 1, .idVersion_lo = (lo) 125*2b4464b0SVladimir Kondratyev 126*2b4464b0SVladimir Kondratyev #define HID_VERSION_LTEQ(hi) /* less than or equal */ \ 127*2b4464b0SVladimir Kondratyev .match_flag_ver_hi = 1, .idVersion_hi = (hi) 128*2b4464b0SVladimir Kondratyev 129*2b4464b0SVladimir Kondratyev #define HID_PNP(pnp) \ 130*2b4464b0SVladimir Kondratyev .match_flag_pnp = 1, .idPnP = (pnp) 131*2b4464b0SVladimir Kondratyev 132*2b4464b0SVladimir Kondratyev #define HID_DRIVER_INFO(n) \ 133*2b4464b0SVladimir Kondratyev .driver_info = (n) 134*2b4464b0SVladimir Kondratyev 135*2b4464b0SVladimir Kondratyev #define HID_GET_DRIVER_INFO(did) \ 136*2b4464b0SVladimir Kondratyev (did)->driver_info 137*2b4464b0SVladimir Kondratyev 138*2b4464b0SVladimir Kondratyev #define HIDBUS_LOOKUP_ID(d, h) hidbus_lookup_id((d), (h), nitems(h)) 139*2b4464b0SVladimir Kondratyev #define HIDBUS_LOOKUP_DRIVER_INFO(d, h) \ 140*2b4464b0SVladimir Kondratyev hidbus_lookup_driver_info((d), (h), nitems(h)) 141*2b4464b0SVladimir Kondratyev 142*2b4464b0SVladimir Kondratyev /* 143*2b4464b0SVladimir Kondratyev * Walk through all HID items hi belonging Top Level Collection #tlc_index 144*2b4464b0SVladimir Kondratyev */ 145*2b4464b0SVladimir Kondratyev #define HIDBUS_FOREACH_ITEM(hd, hi, tlc_index) \ 146*2b4464b0SVladimir Kondratyev for (uint8_t _iter = 0; \ 147*2b4464b0SVladimir Kondratyev _iter <= (tlc_index) && hid_get_item((hd), (hi)); \ 148*2b4464b0SVladimir Kondratyev _iter += (hi)->kind == hid_endcollection && (hi)->collevel == 0) \ 149*2b4464b0SVladimir Kondratyev if (_iter == (tlc_index)) 150*2b4464b0SVladimir Kondratyev 151*2b4464b0SVladimir Kondratyev int hidbus_locate(const void *desc, hid_size_t size, int32_t u, 152*2b4464b0SVladimir Kondratyev enum hid_kind k, uint8_t tlc_index, uint8_t index, 153*2b4464b0SVladimir Kondratyev struct hid_location *loc, uint32_t *flags, uint8_t *id, 154*2b4464b0SVladimir Kondratyev struct hid_absinfo *ai); 155*2b4464b0SVladimir Kondratyev 156*2b4464b0SVladimir Kondratyev const struct hid_device_id *hidbus_lookup_id(device_t, 157*2b4464b0SVladimir Kondratyev const struct hid_device_id *, int); 158*2b4464b0SVladimir Kondratyev struct hid_rdesc_info *hidbus_get_rdesc_info(device_t); 159*2b4464b0SVladimir Kondratyev int hidbus_lookup_driver_info(device_t, 160*2b4464b0SVladimir Kondratyev const struct hid_device_id *, int); 161*2b4464b0SVladimir Kondratyev void hidbus_set_intr(device_t, hid_intr_t*, void *); 162*2b4464b0SVladimir Kondratyev int hidbus_intr_start(device_t); 163*2b4464b0SVladimir Kondratyev int hidbus_intr_stop(device_t); 164*2b4464b0SVladimir Kondratyev void hidbus_intr_poll(device_t); 165*2b4464b0SVladimir Kondratyev void hidbus_set_desc(device_t, const char *); 166*2b4464b0SVladimir Kondratyev device_t hidbus_find_child(device_t, int32_t); 167*2b4464b0SVladimir Kondratyev 168*2b4464b0SVladimir Kondratyev /* hidbus HID interface */ 169*2b4464b0SVladimir Kondratyev int hid_get_report_descr(device_t, void **, hid_size_t *); 170*2b4464b0SVladimir Kondratyev int hid_set_report_descr(device_t, const void *, hid_size_t); 171*2b4464b0SVladimir Kondratyev 172*2b4464b0SVladimir Kondratyev const struct hid_device_info *hid_get_device_info(device_t); 173*2b4464b0SVladimir Kondratyev 174*2b4464b0SVladimir Kondratyev extern devclass_t hidbus_devclass; 175*2b4464b0SVladimir Kondratyev 176*2b4464b0SVladimir Kondratyev #endif /* _HID_HIDBUS_H_ */ 177