xref: /freebsd/sys/dev/hid/hidbus.h (revision 4151ac9f1292b524ae3eeb6f6c9561913bbe444c)
12b4464b0SVladimir Kondratyev /*-
22b4464b0SVladimir Kondratyev  * Copyright (c) 2019 Vladimir Kondratyev <wulf@FreeBSD.org>
32b4464b0SVladimir Kondratyev  *
42b4464b0SVladimir Kondratyev  * Redistribution and use in source and binary forms, with or without
52b4464b0SVladimir Kondratyev  * modification, are permitted provided that the following conditions
62b4464b0SVladimir Kondratyev  * are met:
72b4464b0SVladimir Kondratyev  * 1. Redistributions of source code must retain the above copyright
82b4464b0SVladimir Kondratyev  *    notice, this list of conditions and the following disclaimer.
92b4464b0SVladimir Kondratyev  * 2. Redistributions in binary form must reproduce the above copyright
102b4464b0SVladimir Kondratyev  *    notice, this list of conditions and the following disclaimer in the
112b4464b0SVladimir Kondratyev  *    documentation and/or other materials provided with the distribution.
122b4464b0SVladimir Kondratyev  *
132b4464b0SVladimir Kondratyev  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
142b4464b0SVladimir Kondratyev  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
152b4464b0SVladimir Kondratyev  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
162b4464b0SVladimir Kondratyev  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
172b4464b0SVladimir Kondratyev  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
182b4464b0SVladimir Kondratyev  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
192b4464b0SVladimir Kondratyev  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
202b4464b0SVladimir Kondratyev  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
212b4464b0SVladimir Kondratyev  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
222b4464b0SVladimir Kondratyev  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
232b4464b0SVladimir Kondratyev  * SUCH DAMAGE.
242b4464b0SVladimir Kondratyev  */
252b4464b0SVladimir Kondratyev 
262b4464b0SVladimir Kondratyev #ifndef _HID_HIDBUS_H_
272b4464b0SVladimir Kondratyev #define _HID_HIDBUS_H_
282b4464b0SVladimir Kondratyev 
292b4464b0SVladimir Kondratyev enum {
302b4464b0SVladimir Kondratyev 	HIDBUS_IVAR_USAGE,
312b4464b0SVladimir Kondratyev 	HIDBUS_IVAR_INDEX,
322b4464b0SVladimir Kondratyev 	HIDBUS_IVAR_FLAGS,
332b4464b0SVladimir Kondratyev #define	HIDBUS_FLAG_AUTOCHILD	(0<<1)	/* Child is autodiscovered */
342b4464b0SVladimir Kondratyev #define	HIDBUS_FLAG_CAN_POLL	(1<<1)	/* Child can work during panic */
352b4464b0SVladimir Kondratyev 	HIDBUS_IVAR_DRIVER_INFO,
362b4464b0SVladimir Kondratyev 	HIDBUS_IVAR_LOCK,
372b4464b0SVladimir Kondratyev };
382b4464b0SVladimir Kondratyev 
392b4464b0SVladimir Kondratyev #define HIDBUS_ACCESSOR(A, B, T)					\
402b4464b0SVladimir Kondratyev 	__BUS_ACCESSOR(hidbus, A, HIDBUS, B, T)
412b4464b0SVladimir Kondratyev 
422b4464b0SVladimir Kondratyev HIDBUS_ACCESSOR(usage,		USAGE,		int32_t)
432b4464b0SVladimir Kondratyev HIDBUS_ACCESSOR(index,		INDEX,		uint8_t)
442b4464b0SVladimir Kondratyev HIDBUS_ACCESSOR(flags,		FLAGS,		uint32_t)
452b4464b0SVladimir Kondratyev HIDBUS_ACCESSOR(driver_info,	DRIVER_INFO,	uintptr_t)
462b4464b0SVladimir Kondratyev HIDBUS_ACCESSOR(lock,		LOCK,		struct mtx *)
472b4464b0SVladimir Kondratyev 
482b4464b0SVladimir Kondratyev /*
492b4464b0SVladimir Kondratyev  * The following structure is used when looking up an HID driver for
502b4464b0SVladimir Kondratyev  * an HID device. It is inspired by the structure called "usb_device_id".
512b4464b0SVladimir Kondratyev  * which is originated in Linux and ported to FreeBSD.
522b4464b0SVladimir Kondratyev  */
532b4464b0SVladimir Kondratyev struct hid_device_id {
542b4464b0SVladimir Kondratyev 
552b4464b0SVladimir Kondratyev 	/* Select which fields to match against */
562b4464b0SVladimir Kondratyev #if BYTE_ORDER == LITTLE_ENDIAN
572b4464b0SVladimir Kondratyev 	uint16_t
582b4464b0SVladimir Kondratyev 		match_flag_page:1,
592b4464b0SVladimir Kondratyev 		match_flag_usage:1,
602b4464b0SVladimir Kondratyev 		match_flag_bus:1,
612b4464b0SVladimir Kondratyev 		match_flag_vendor:1,
622b4464b0SVladimir Kondratyev 		match_flag_product:1,
632b4464b0SVladimir Kondratyev 		match_flag_ver_lo:1,
642b4464b0SVladimir Kondratyev 		match_flag_ver_hi:1,
652b4464b0SVladimir Kondratyev 		match_flag_pnp:1,
662b4464b0SVladimir Kondratyev 		match_flag_unused:8;
672b4464b0SVladimir Kondratyev #else
682b4464b0SVladimir Kondratyev 	uint16_t
692b4464b0SVladimir Kondratyev 		match_flag_unused:8,
702b4464b0SVladimir Kondratyev 		match_flag_pnp:1,
712b4464b0SVladimir Kondratyev 		match_flag_ver_hi:1,
722b4464b0SVladimir Kondratyev 		match_flag_ver_lo:1,
732b4464b0SVladimir Kondratyev 		match_flag_product:1,
742b4464b0SVladimir Kondratyev 		match_flag_vendor:1,
752b4464b0SVladimir Kondratyev 		match_flag_bus:1,
762b4464b0SVladimir Kondratyev 		match_flag_usage:1,
772b4464b0SVladimir Kondratyev 		match_flag_page:1;
782b4464b0SVladimir Kondratyev #endif
792b4464b0SVladimir Kondratyev 
802b4464b0SVladimir Kondratyev 	/* Used for top level collection usage matches */
812b4464b0SVladimir Kondratyev 	uint16_t page;
822b4464b0SVladimir Kondratyev 	uint16_t usage;
832b4464b0SVladimir Kondratyev 
842b4464b0SVladimir Kondratyev 	/* Used for product specific matches; the Version range is inclusive */
852b4464b0SVladimir Kondratyev 	uint8_t idBus;
862b4464b0SVladimir Kondratyev 	uint16_t idVendor;
872b4464b0SVladimir Kondratyev 	uint16_t idProduct;
882b4464b0SVladimir Kondratyev 	uint16_t idVersion_lo;
892b4464b0SVladimir Kondratyev 	uint16_t idVersion_hi;
902b4464b0SVladimir Kondratyev 	char *idPnP;
912b4464b0SVladimir Kondratyev 
922b4464b0SVladimir Kondratyev 	/* Hook for driver specific information */
932b4464b0SVladimir Kondratyev 	uintptr_t driver_info;
942b4464b0SVladimir Kondratyev };
952b4464b0SVladimir Kondratyev 
962b4464b0SVladimir Kondratyev #define	HID_STD_PNP_INFO					\
972b4464b0SVladimir Kondratyev   "M16:mask;U16:page;U16:usage;U8:bus;U16:vendor;U16:product;"	\
982b4464b0SVladimir Kondratyev   "L16:version;G16:version;Z:_HID"
992b4464b0SVladimir Kondratyev #define HID_PNP_INFO(table)			\
1002b4464b0SVladimir Kondratyev   MODULE_PNP_INFO(HID_STD_PNP_INFO, hidbus, table, table, nitems(table))
1012b4464b0SVladimir Kondratyev 
1022b4464b0SVladimir Kondratyev #define HID_TLC(pg,usg)				\
1032b4464b0SVladimir Kondratyev   .match_flag_page = 1, .match_flag_usage = 1, .page = (pg), .usage = (usg)
1042b4464b0SVladimir Kondratyev 
1052b4464b0SVladimir Kondratyev #define HID_BUS(bus)				\
1062b4464b0SVladimir Kondratyev   .match_flag_bus = 1, .idBus = (bus)
1072b4464b0SVladimir Kondratyev 
1082b4464b0SVladimir Kondratyev #define HID_VENDOR(vend)			\
1092b4464b0SVladimir Kondratyev   .match_flag_vendor = 1, .idVendor = (vend)
1102b4464b0SVladimir Kondratyev 
1112b4464b0SVladimir Kondratyev #define HID_PRODUCT(prod)			\
1122b4464b0SVladimir Kondratyev   .match_flag_product = 1, .idProduct = (prod)
1132b4464b0SVladimir Kondratyev 
1142b4464b0SVladimir Kondratyev #define HID_VP(vend,prod)			\
1152b4464b0SVladimir Kondratyev   HID_VENDOR(vend), HID_PRODUCT(prod)
1162b4464b0SVladimir Kondratyev 
1172b4464b0SVladimir Kondratyev #define HID_BVP(bus,vend,prod)			\
1182b4464b0SVladimir Kondratyev   HID_BUS(bus), HID_VENDOR(vend), HID_PRODUCT(prod)
1192b4464b0SVladimir Kondratyev 
1202b4464b0SVladimir Kondratyev #define HID_BVPI(bus,vend,prod,info)		\
1212b4464b0SVladimir Kondratyev   HID_BUS(bus), HID_VENDOR(vend), HID_PRODUCT(prod), HID_DRIVER_INFO(info)
1222b4464b0SVladimir Kondratyev 
1232b4464b0SVladimir Kondratyev #define HID_VERSION_GTEQ(lo)	/* greater than or equal */	\
1242b4464b0SVladimir Kondratyev   .match_flag_ver_lo = 1, .idVersion_lo = (lo)
1252b4464b0SVladimir Kondratyev 
1262b4464b0SVladimir Kondratyev #define HID_VERSION_LTEQ(hi)	/* less than or equal */	\
1272b4464b0SVladimir Kondratyev   .match_flag_ver_hi = 1, .idVersion_hi = (hi)
1282b4464b0SVladimir Kondratyev 
1292b4464b0SVladimir Kondratyev #define	HID_PNP(pnp)				\
1302b4464b0SVladimir Kondratyev   .match_flag_pnp = 1, .idPnP = (pnp)
1312b4464b0SVladimir Kondratyev 
1322b4464b0SVladimir Kondratyev #define HID_DRIVER_INFO(n)			\
1332b4464b0SVladimir Kondratyev   .driver_info = (n)
1342b4464b0SVladimir Kondratyev 
1352b4464b0SVladimir Kondratyev #define HID_GET_DRIVER_INFO(did)		\
1362b4464b0SVladimir Kondratyev   (did)->driver_info
1372b4464b0SVladimir Kondratyev 
1382b4464b0SVladimir Kondratyev #define	HIDBUS_LOOKUP_ID(d, h)	hidbus_lookup_id((d), (h), nitems(h))
1392b4464b0SVladimir Kondratyev #define	HIDBUS_LOOKUP_DRIVER_INFO(d, h)		\
1402b4464b0SVladimir Kondratyev 	hidbus_lookup_driver_info((d), (h), nitems(h))
1412b4464b0SVladimir Kondratyev 
1422b4464b0SVladimir Kondratyev /*
1432b4464b0SVladimir Kondratyev  * Walk through all HID items hi belonging Top Level Collection #tlc_index
1442b4464b0SVladimir Kondratyev  */
1452b4464b0SVladimir Kondratyev #define	HIDBUS_FOREACH_ITEM(hd, hi, tlc_index)				\
1462b4464b0SVladimir Kondratyev 	for (uint8_t _iter = 0;						\
1472b4464b0SVladimir Kondratyev 	    _iter <= (tlc_index) && hid_get_item((hd), (hi));		\
1482b4464b0SVladimir Kondratyev 	    _iter += (hi)->kind == hid_endcollection && (hi)->collevel == 0) \
1492b4464b0SVladimir Kondratyev 		if (_iter == (tlc_index))
1502b4464b0SVladimir Kondratyev 
1512b4464b0SVladimir Kondratyev int	hidbus_locate(const void *desc, hid_size_t size, int32_t u,
1522b4464b0SVladimir Kondratyev 	    enum hid_kind k, uint8_t tlc_index, uint8_t index,
1532b4464b0SVladimir Kondratyev 	    struct hid_location *loc, uint32_t *flags, uint8_t *id,
1542b4464b0SVladimir Kondratyev 	    struct hid_absinfo *ai);
155*d51e4376SVladimir Kondratyev bool	hidbus_is_collection(const void *, hid_size_t, int32_t, uint8_t);
1562b4464b0SVladimir Kondratyev 
1572b4464b0SVladimir Kondratyev const struct hid_device_id *hidbus_lookup_id(device_t,
1582b4464b0SVladimir Kondratyev 		    const struct hid_device_id *, int);
1592b4464b0SVladimir Kondratyev struct hid_rdesc_info *hidbus_get_rdesc_info(device_t);
1602b4464b0SVladimir Kondratyev int		hidbus_lookup_driver_info(device_t,
1612b4464b0SVladimir Kondratyev 		    const struct hid_device_id *, int);
1622b4464b0SVladimir Kondratyev void		hidbus_set_intr(device_t, hid_intr_t*, void *);
1632b4464b0SVladimir Kondratyev void		hidbus_set_desc(device_t, const char *);
1642b4464b0SVladimir Kondratyev device_t	hidbus_find_child(device_t, int32_t);
1652b4464b0SVladimir Kondratyev 
1662b4464b0SVladimir Kondratyev /* hidbus HID interface */
1672b4464b0SVladimir Kondratyev int	hid_get_report_descr(device_t, void **, hid_size_t *);
1682b4464b0SVladimir Kondratyev int	hid_set_report_descr(device_t, const void *, hid_size_t);
1692b4464b0SVladimir Kondratyev 
1702b4464b0SVladimir Kondratyev const struct hid_device_info *hid_get_device_info(device_t);
1712b4464b0SVladimir Kondratyev 
1722b4464b0SVladimir Kondratyev #endif	/* _HID_HIDBUS_H_ */
173