1/* $FreeBSD$ */
2/*-
3 * SPDX-License-Identifier: BSD-2-Clause-NetBSD
4 *
5 * Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
6 * Copyright (c) 1998 The NetBSD Foundation, Inc. All rights reserved.
7 * Copyright (c) 1998 Lennart Augustsson. All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 *    notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 *    notice, this list of conditions and the following disclaimer in the
16 *    documentation and/or other materials provided with the distribution.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 */
30
31#ifndef _HID_HID_H_
32#define	_HID_HID_H_
33
34/* Usage pages */
35#define	HUP_UNDEFINED		0x0000
36#define	HUP_GENERIC_DESKTOP	0x0001
37#define	HUP_SIMULATION		0x0002
38#define	HUP_VR_CONTROLS		0x0003
39#define	HUP_SPORTS_CONTROLS	0x0004
40#define	HUP_GAMING_CONTROLS	0x0005
41#define	HUP_KEYBOARD		0x0007
42#define	HUP_LEDS		0x0008
43#define	HUP_BUTTON		0x0009
44#define	HUP_ORDINALS		0x000a
45#define	HUP_TELEPHONY		0x000b
46#define	HUP_CONSUMER		0x000c
47#define	HUP_DIGITIZERS		0x000d
48#define	HUP_PHYSICAL_IFACE	0x000e
49#define	HUP_UNICODE		0x0010
50#define	HUP_ALPHANUM_DISPLAY	0x0014
51#define	HUP_MONITOR		0x0080
52#define	HUP_MONITOR_ENUM_VAL	0x0081
53#define	HUP_VESA_VC		0x0082
54#define	HUP_VESA_CMD		0x0083
55#define	HUP_POWER		0x0084
56#define	HUP_BATTERY_SYSTEM	0x0085
57#define	HUP_BARCODE_SCANNER	0x008b
58#define	HUP_SCALE		0x008c
59#define	HUP_CAMERA_CONTROL	0x0090
60#define	HUP_ARCADE		0x0091
61#define	HUP_MICROSOFT		0xff00
62
63/* Usages, generic desktop */
64#define	HUG_POINTER		0x0001
65#define	HUG_MOUSE		0x0002
66#define	HUG_JOYSTICK		0x0004
67#define	HUG_GAME_PAD		0x0005
68#define	HUG_KEYBOARD		0x0006
69#define	HUG_KEYPAD		0x0007
70#define	HUG_MULTIAXIS_CNTROLLER	0x0008
71#define	HUG_X			0x0030
72#define	HUG_Y			0x0031
73#define	HUG_Z			0x0032
74#define	HUG_RX			0x0033
75#define	HUG_RY			0x0034
76#define	HUG_RZ			0x0035
77#define	HUG_SLIDER		0x0036
78#define	HUG_DIAL		0x0037
79#define	HUG_WHEEL		0x0038
80#define	HUG_HAT_SWITCH		0x0039
81#define	HUG_COUNTED_BUFFER	0x003a
82#define	HUG_BYTE_COUNT		0x003b
83#define	HUG_MOTION_WAKEUP	0x003c
84#define	HUG_VX			0x0040
85#define	HUG_VY			0x0041
86#define	HUG_VZ			0x0042
87#define	HUG_VBRX		0x0043
88#define	HUG_VBRY		0x0044
89#define	HUG_VBRZ		0x0045
90#define	HUG_VNO			0x0046
91#define	HUG_TWHEEL		0x0048	/* M$ Wireless Intellimouse Wheel */
92#define	HUG_SYSTEM_CONTROL	0x0080
93#define	HUG_SYSTEM_POWER_DOWN	0x0081
94#define	HUG_SYSTEM_SLEEP	0x0082
95#define	HUG_SYSTEM_WAKEUP	0x0083
96#define	HUG_SYSTEM_CONTEXT_MENU	0x0084
97#define	HUG_SYSTEM_MAIN_MENU	0x0085
98#define	HUG_SYSTEM_APP_MENU	0x0086
99#define	HUG_SYSTEM_MENU_HELP	0x0087
100#define	HUG_SYSTEM_MENU_EXIT	0x0088
101#define	HUG_SYSTEM_MENU_SELECT	0x0089
102#define	HUG_SYSTEM_MENU_RIGHT	0x008a
103#define	HUG_SYSTEM_MENU_LEFT	0x008b
104#define	HUG_SYSTEM_MENU_UP	0x008c
105#define	HUG_SYSTEM_MENU_DOWN	0x008d
106#define	HUG_SYSTEM_POWER_UP	0x008e
107#define	HUG_SYSTEM_RESTART	0x008f
108#define	HUG_D_PAD_UP		0x0090
109#define	HUG_D_PAD_DOWN		0x0091
110#define	HUG_D_PAD_RIGHT		0x0092
111#define	HUG_D_PAD_LEFT		0x0093
112#define	HUG_APPLE_EJECT		0x00b8
113
114/* Usages Digitizers */
115#define	HUD_UNDEFINED		0x0000
116#define	HUD_DIGITIZER		0x0001
117#define	HUD_PEN			0x0002
118#define	HUD_TOUCHSCREEN		0x0004
119#define	HUD_TOUCHPAD		0x0005
120#define	HUD_CONFIG		0x000e
121#define	HUD_FINGER		0x0022
122#define	HUD_TIP_PRESSURE	0x0030
123#define	HUD_BARREL_PRESSURE	0x0031
124#define	HUD_IN_RANGE		0x0032
125#define	HUD_TOUCH		0x0033
126#define	HUD_UNTOUCH		0x0034
127#define	HUD_TAP			0x0035
128#define	HUD_QUALITY		0x0036
129#define	HUD_DATA_VALID		0x0037
130#define	HUD_TRANSDUCER_INDEX	0x0038
131#define	HUD_TABLET_FKEYS	0x0039
132#define	HUD_PROGRAM_CHANGE_KEYS	0x003a
133#define	HUD_BATTERY_STRENGTH	0x003b
134#define	HUD_INVERT		0x003c
135#define	HUD_X_TILT		0x003d
136#define	HUD_Y_TILT		0x003e
137#define	HUD_AZIMUTH		0x003f
138#define	HUD_ALTITUDE		0x0040
139#define	HUD_TWIST		0x0041
140#define	HUD_TIP_SWITCH		0x0042
141#define	HUD_SEC_TIP_SWITCH	0x0043
142#define	HUD_BARREL_SWITCH	0x0044
143#define	HUD_ERASER		0x0045
144#define	HUD_TABLET_PICK		0x0046
145#define	HUD_CONFIDENCE		0x0047
146#define	HUD_WIDTH		0x0048
147#define	HUD_HEIGHT		0x0049
148#define	HUD_CONTACTID		0x0051
149#define	HUD_INPUT_MODE		0x0052
150#define	HUD_DEVICE_INDEX	0x0053
151#define	HUD_CONTACTCOUNT	0x0054
152#define	HUD_CONTACT_MAX		0x0055
153#define	HUD_SCAN_TIME		0x0056
154#define	HUD_SURFACE_SWITCH	0x0057
155#define	HUD_BUTTONS_SWITCH	0x0058
156#define	HUD_BUTTON_TYPE		0x0059
157#define	HUD_SEC_BARREL_SWITCH	0x005a
158#define	HUD_LATENCY_MODE	0x0060
159
160/* Usages, Consumer */
161#define	HUC_CONTROL		0x0001
162#define	HUC_HEADPHONE		0x0005
163#define	HUC_AC_PAN		0x0238
164
165#define	HID_USAGE2(p,u)		(((p) << 16) | (u))
166#define	HID_GET_USAGE(u)	((u) & 0xffff)
167#define	HID_GET_USAGE_PAGE(u)	(((u) >> 16) & 0xffff)
168
169#define	HID_INPUT_REPORT	0x01
170#define	HID_OUTPUT_REPORT	0x02
171#define	HID_FEATURE_REPORT	0x03
172
173/* Bits in the input/output/feature items */
174#define	HIO_CONST	0x001
175#define	HIO_VARIABLE	0x002
176#define	HIO_RELATIVE	0x004
177#define	HIO_WRAP	0x008
178#define	HIO_NONLINEAR	0x010
179#define	HIO_NOPREF	0x020
180#define	HIO_NULLSTATE	0x040
181#define	HIO_VOLATILE	0x080
182#define	HIO_BUFBYTES	0x100
183
184/* Units of Measure */
185#define	HUM_CENTIMETER	0x11
186#define	HUM_RADIAN	0x12
187#define	HUM_INCH	0x13
188#define	HUM_DEGREE	0x14
189
190#if defined(_KERNEL) || defined(_STANDALONE)
191
192#define	HID_ITEM_MAXUSAGE	8
193#define	HID_MAX_AUTO_QUIRK	8	/* maximum number of dynamic quirks */
194#define	HID_PNP_ID_SIZE		20	/* includes null terminator */
195
196/* Share unit number pool between uhid and hidraw */
197extern devclass_t hidraw_devclass;
198
199/* Declare global HID debug variable. */
200extern int hid_debug;
201
202/* Check if HID debugging is enabled. */
203#ifdef HID_DEBUG_VAR
204#ifdef HID_DEBUG
205#define DPRINTFN(n,fmt,...) do {			\
206	if ((HID_DEBUG_VAR) >= (n)) {			\
207		printf("%s: " fmt,			\
208		    __FUNCTION__ ,##__VA_ARGS__);	\
209	}						\
210} while (0)
211#define DPRINTF(...)	DPRINTFN(1, __VA_ARGS__)
212#else
213#define DPRINTF(...)	do { } while (0)
214#define DPRINTFN(...)	do { } while (0)
215#endif
216#endif
217
218/* Declare parent SYSCTL HID node. */
219#ifdef SYSCTL_DECL
220SYSCTL_DECL(_hw_hid);
221#endif
222
223typedef uint32_t hid_size_t;
224
225#define	HID_IN_POLLING_MODE()	(SCHEDULER_STOPPED() || kdb_active)
226
227enum hid_kind {
228	hid_input, hid_output, hid_feature, hid_collection, hid_endcollection
229};
230
231struct hid_location {
232	uint32_t size;
233	uint32_t count;
234	uint32_t pos;
235};
236
237struct hid_item {
238	/* Global */
239	int32_t	_usage_page;
240	int32_t	logical_minimum;
241	int32_t	logical_maximum;
242	int32_t	physical_minimum;
243	int32_t	physical_maximum;
244	int32_t	unit_exponent;
245	int32_t	unit;
246	int32_t	report_ID;
247	/* Local */
248	int	nusages;
249	union {
250		int32_t	usage;
251		int32_t usages[HID_ITEM_MAXUSAGE];
252	};
253	int32_t	usage_minimum;
254	int32_t	usage_maximum;
255	int32_t	designator_index;
256	int32_t	designator_minimum;
257	int32_t	designator_maximum;
258	int32_t	string_index;
259	int32_t	string_minimum;
260	int32_t	string_maximum;
261	int32_t	set_delimiter;
262	/* Misc */
263	int32_t	collection;
264	int	collevel;
265	enum hid_kind kind;
266	uint32_t flags;
267	/* Location */
268	struct hid_location loc;
269};
270
271struct hid_absinfo {
272	int32_t min;
273	int32_t max;
274	int32_t res;
275};
276
277struct hid_device_info {
278	char		name[80];
279	char		serial[80];
280	char		idPnP[HID_PNP_ID_SIZE];
281	uint16_t	idBus;
282	uint16_t	idVendor;
283	uint16_t	idProduct;
284	uint16_t	idVersion;
285	hid_size_t	rdescsize;	/* Report descriptor size */
286	uint8_t		autoQuirk[HID_MAX_AUTO_QUIRK];
287};
288
289struct hid_rdesc_info {
290	void		*data;
291	hid_size_t	len;
292	hid_size_t	isize;
293	hid_size_t	osize;
294	hid_size_t	fsize;
295	uint8_t		iid;
296	uint8_t		oid;
297	uint8_t		fid;
298	/* Max sizes for HID requests supported by transport backend */
299	hid_size_t	rdsize;
300	hid_size_t	wrsize;
301	hid_size_t	grsize;
302	hid_size_t	srsize;
303};
304
305typedef void hid_intr_t(void *context, void *data, hid_size_t len);
306typedef bool hid_test_quirk_t(const struct hid_device_info *dev_info,
307    uint16_t quirk);
308
309extern hid_test_quirk_t *hid_test_quirk_p;
310
311/* prototypes from "usb_hid.c" */
312
313struct hid_data *hid_start_parse(const void *d, hid_size_t len, int kindset);
314void	hid_end_parse(struct hid_data *s);
315int	hid_get_item(struct hid_data *s, struct hid_item *h);
316int	hid_report_size(const void *buf, hid_size_t len, enum hid_kind k,
317	    uint8_t id);
318int	hid_report_size_max(const void *buf, hid_size_t len, enum hid_kind k,
319	    uint8_t *id);
320int	hid_locate(const void *desc, hid_size_t size, int32_t usage,
321	    enum hid_kind kind, uint8_t index, struct hid_location *loc,
322	    uint32_t *flags, uint8_t *id);
323int32_t hid_get_data(const uint8_t *buf, hid_size_t len,
324	    struct hid_location *loc);
325uint32_t hid_get_udata(const uint8_t *buf, hid_size_t len,
326	    struct hid_location *loc);
327void	hid_put_udata(uint8_t *buf, hid_size_t len,
328	    struct hid_location *loc, unsigned int value);
329int	hid_is_collection(const void *desc, hid_size_t size, int32_t usage);
330int32_t	hid_item_resolution(struct hid_item *hi);
331int	hid_is_mouse(const void *d_ptr, uint16_t d_len);
332int	hid_is_keyboard(const void *d_ptr, uint16_t d_len);
333bool	hid_test_quirk(const struct hid_device_info *dev_info, uint16_t quirk);
334int	hid_add_dynamic_quirk(struct hid_device_info *dev_info,
335	    uint16_t quirk);
336void	hid_quirk_unload(void *arg);
337
338int	hid_get_rdesc(device_t, void *, hid_size_t);
339int	hid_read(device_t, void *, hid_size_t, hid_size_t *);
340int	hid_write(device_t, const void *, hid_size_t);
341int	hid_get_report(device_t, void *, hid_size_t, hid_size_t *, uint8_t,
342	    uint8_t);
343int	hid_set_report(device_t, const void *, hid_size_t, uint8_t, uint8_t);
344int	hid_set_idle(device_t, uint16_t, uint8_t);
345int	hid_set_protocol(device_t, uint16_t);
346#endif	/* _KERNEL || _STANDALONE */
347#endif	/* _HID_HID_H_ */
348