xref: /freebsd/sys/dev/hid/ps4dshock.c (revision c14e17a49cdd72c8c05d12fbec631c409b14b9cb)
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 #include <sys/cdefs.h>
29 __FBSDID("$FreeBSD$");
30 
31 /*
32  * Sony PS4 DualShock 4 driver
33  * https://eleccelerator.com/wiki/index.php?title=DualShock_4
34  * https://gist.github.com/johndrinkwater/7708901
35  * https://www.psdevwiki.com/ps4/DS4-USB
36  */
37 
38 #include "opt_hid.h"
39 
40 #include <sys/param.h>
41 #include <sys/bus.h>
42 #include <sys/kernel.h>
43 #include <sys/lock.h>
44 #include <sys/malloc.h>
45 #include <sys/module.h>
46 #include <sys/sx.h>
47 #include <sys/sysctl.h>
48 
49 #include <dev/evdev/input.h>
50 #include <dev/evdev/evdev.h>
51 
52 #define	HID_DEBUG_VAR	ps4dshock_debug
53 #include <dev/hid/hid.h>
54 #include <dev/hid/hidbus.h>
55 #include <dev/hid/hidquirk.h>
56 #include <dev/hid/hidmap.h>
57 #include "usbdevs.h"
58 
59 #ifdef HID_DEBUG
60 static int ps4dshock_debug = 1;
61 
62 static SYSCTL_NODE(_hw_hid, OID_AUTO, ps4dshock, CTLFLAG_RW, 0,
63 		"Sony PS4 DualShock Gamepad");
64 SYSCTL_INT(_hw_hid_ps4dshock, OID_AUTO, debug, CTLFLAG_RWTUN,
65 		&ps4dshock_debug, 0, "Debug level");
66 #endif
67 
68 static const uint8_t	ps4dshock_rdesc[] = {
69 	0x05, 0x01,		/* Usage Page (Generic Desktop Ctrls)	*/
70 	0x09, 0x05,		/* Usage (Game Pad)			*/
71 	0xA1, 0x01,		/* Collection (Application)		*/
72 	0x85, 0x01,		/*   Report ID (1)			*/
73 	0x09, 0x30,		/*   Usage (X)				*/
74 	0x09, 0x31,		/*   Usage (Y)				*/
75 	0x09, 0x33,		/*   Usage (Rx)				*/
76 	0x09, 0x34,		/*   Usage (Ry)				*/
77 	0x15, 0x00,		/*   Logical Minimum (0)		*/
78 	0x26, 0xFF, 0x00,	/*   Logical Maximum (255)		*/
79 	0x75, 0x08,		/*   Report Size (8)			*/
80 	0x95, 0x04,		/*   Report Count (4)			*/
81 	0x81, 0x02,		/*   Input (Data,Var,Abs)		*/
82 	0x09, 0x39,		/*   Usage (Hat switch)			*/
83 	0x15, 0x00,		/*   Logical Minimum (0)		*/
84 	0x25, 0x07,		/*   Logical Maximum (7)		*/
85 	0x35, 0x00,		/*   Physical Minimum (0)		*/
86 	0x46, 0x3B, 0x01,	/*   Physical Maximum (315)		*/
87 	0x65, 0x14,		/*   Unit (System: English Rotation, Length: Centimeter) */
88 	0x75, 0x04,		/*   Report Size (4)			*/
89 	0x95, 0x01,		/*   Report Count (1)			*/
90 	0x81, 0x42,		/*   Input (Data,Var,Abs,Null State)	*/
91 	0x65, 0x00,		/*   Unit (None)			*/
92 	0x45, 0x00,		/*   Physical Maximum (0)		*/
93 	0x05, 0x09,		/*   Usage Page (Button)		*/
94 	0x19, 0x01,		/*   Usage Minimum (0x01)		*/
95 	0x29, 0x0E,		/*   Usage Maximum (0x0E)		*/
96 	0x15, 0x00,		/*   Logical Minimum (0)		*/
97 	0x25, 0x01,		/*   Logical Maximum (1)		*/
98 	0x75, 0x01,		/*   Report Size (1)			*/
99 	0x95, 0x0E,		/*   Report Count (14)			*/
100 	0x81, 0x02,		/*   Input (Data,Var,Abs)		*/
101 	0x06, 0x00, 0xFF,	/*   Usage Page (Vendor Defined 0xFF00)	*/
102 	0x09, 0x20,		/*   Usage (0x20)			*/
103 	0x75, 0x06,		/*   Report Size (6)			*/
104 	0x95, 0x01,		/*   Report Count (1)			*/
105 	0x15, 0x00,		/*   Logical Minimum (0)		*/
106 	0x25, 0x3F,		/*   Logical Maximum (63)		*/
107 	0x81, 0x02,		/*   Input (Data,Var,Abs)		*/
108 	0x05, 0x01,		/*   Usage Page (Generic Desktop Ctrls)	*/
109 	0x09, 0x32,		/*   Usage (Z)				*/
110 	0x09, 0x35,		/*   Usage (Rz)				*/
111 	0x15, 0x00,		/*   Logical Minimum (0)		*/
112 	0x26, 0xFF, 0x00,	/*   Logical Maximum (255)		*/
113 	0x75, 0x08,		/*   Report Size (8)			*/
114 	0x95, 0x02,		/*   Report Count (2)			*/
115 	0x81, 0x02,		/*   Input (Data,Var,Abs)		*/
116 	0xC0,			/* End Collection			*/
117 	0x05, 0x01,		/* Usage Page (Generic Desktop Ctrls)	*/
118 	0x09, 0x08,		/* Usage (Multi-axis Controller)	*/
119 	0xA1, 0x01,		/* Collection (Application)		*/
120 	0x06, 0x00, 0xFF,	/*   Usage Page (Vendor Defined 0xFF00)	*/
121 	0x09, 0x21,		/*   Usage (0x21)			*/
122 	0x27, 0xFF, 0xFF, 0x00, 0x00,	/*   Logical Maximum (65534)	*/
123 	0x75, 0x10,		/*   Report Size (16)			*/
124 	0x95, 0x01,		/*   Report Count (1)			*/
125 	0x81, 0x02,		/*   Input (Data,Var,Abs)		*/
126 	0x05, 0x06,		/*   Usage Page (Generic Dev Ctrls)	*/
127 	0x09, 0x20,		/*   Usage (Battery Strength)		*/
128 	0x26, 0xFF, 0x00,	/*   Logical Maximum (255)		*/
129 	0x75, 0x08,		/*   Report Size (8)			*/
130 	0x95, 0x01,		/*   Report Count (1)			*/
131 	0x81, 0x02,		/*   Input (Data,Var,Abs)		*/
132 	0x05, 0x01,		/*   Usage Page (Generic Desktop Ctrls)	*/
133 	0x19, 0x33,		/*   Usage Minimum (RX)			*/
134 	0x29, 0x35,		/*   Usage Maximum (RZ)			*/
135 	0x16, 0x00, 0x80,	/*   Logical Minimum (-32768)		*/
136 	0x26, 0xFF, 0x7F,	/*   Logical Maximum (32767)		*/
137 	0x75, 0x10,		/*   Report Size (16)			*/
138 	0x95, 0x03,		/*   Report Count (3)			*/
139 	0x81, 0x02,		/*   Input (Data,Var,Abs)		*/
140 	0x19, 0x30,		/*   Usage Minimum (X)			*/
141 	0x29, 0x32,		/*   Usage Maximum (Z)			*/
142 	0x16, 0x00, 0x80,	/*   Logical Minimum (-32768)		*/
143 	0x26, 0xFF, 0x7F,	/*   Logical Maximum (32767)		*/
144 	0x95, 0x03,		/*   Report Count (3)			*/
145 	0x81, 0x02,		/*   Input (Data,Var,Abs)		*/
146 	0x06, 0x00, 0xFF,	/*   Usage Page (Vendor Defined 0xFF00)	*/
147 	0x09, 0x21,		/*   Usage (0x21)			*/
148 	0x15, 0x00,		/*   Logical Minimum (0)		*/
149 	0x26, 0xFF, 0x00,	/*   Logical Maximum (255)		*/
150 	0x75, 0x08,		/*   Report Size (8)			*/
151 	0x95, 0x05,		/*   Report Count (5)			*/
152 	0x81, 0x03,		/*   Input (Const)			*/
153 	0xC0,			/* End Collection			*/
154 	0x05, 0x0C,		/* Usage Page (Consumer)		*/
155 	0x09, 0x05,		/* Usage (Headphone)			*/
156 	0xA1, 0x01,		/* Collection (Application)		*/
157 	0x75, 0x05,		/*   Report Size (5)			*/
158 	0x95, 0x01,		/*   Report Count (1)			*/
159 	0x81, 0x03,		/*   Input (Const)			*/
160 	0x06, 0x00, 0xFF,	/*   Usage Page (Vendor Defined 0xFF00)	*/
161 	0x09, 0x20,		/*   Usage (0x20)			*/
162 	0x09, 0x21,		/*   Usage (0x21)			*/
163 	0x15, 0x00,		/*   Logical Minimum (0)		*/
164 	0x25, 0x01,		/*   Logical Maximum (1)		*/
165 	0x75, 0x01,		/*   Report Size (1)			*/
166 	0x95, 0x02,		/*   Report Count (2)			*/
167 	0x81, 0x02,		/*   Input (Data,Var,Abs)		*/
168 	0x75, 0x01,		/*   Report Size (1)			*/
169 	0x95, 0x01,		/*   Report Count (1)			*/
170 	0x81, 0x03,		/*   Input (Const)			*/
171 	0x75, 0x08,		/*   Report Size (8)			*/
172 	0x95, 0x02,		/*   Report Count (2)			*/
173 	0x81, 0x03,		/*   Input (Const)			*/
174 	0xC0,			/* End Collection			*/
175 	0x05, 0x0D,		/* Usage Page (Digitizer)		*/
176 	0x09, 0x05,		/* Usage (Touch Pad)			*/
177 	0xA1, 0x01,		/* Collection (Application)		*/
178 	0x06, 0x00, 0xFF,	/*   Usage Page (Vendor Defined 0xFF00)	*/
179 	0x09, 0x21,		/*   Usage (0x21)			*/
180 	0x15, 0x00,		/*   Logical Minimum (0)		*/
181 	0x25, 0x03,		/*   Logical Maximum (3)		*/
182 	0x75, 0x04,		/*   Report Size (4)			*/
183 	0x95, 0x01,		/*   Report Count (1)			*/
184 	0x81, 0x02,		/*   Input (Data,Var,Abs)		*/
185 	0x75, 0x04,		/*   Report Size (4)			*/
186 	0x95, 0x01,		/*   Report Count (1)			*/
187 	0x81, 0x03,		/*   Input (Data,Var,Abs)		*/
188 	0x05, 0x0D,		/*   Usage Page (Digitizer)		*/
189 	0x09, 0x56,		/*   Usage (0x56)			*/
190 	0x55, 0x0C,		/*   Unit Exponent (-4)			*/
191 	0x66, 0x01, 0x10,	/*   Unit (System: SI Linear, Time: Seconds) */
192 	0x46, 0xCC, 0x06,	/*   Physical Maximum (1740)		*/
193 	0x26, 0xFF, 0x00,	/*   Logical Maximum (255)		*/
194 	0x75, 0x08,		/*   Report Size (8)			*/
195 	0x95, 0x01,		/*   Report Count (1)			*/
196 	0x81, 0x02,		/*   Input (Data,Var,Abs)		*/
197 	0x65, 0x00,		/*   Unit (None)			*/
198 	0x45, 0x00,		/*   Physical Maximum (0)		*/
199 	0x05, 0x0D,		/*   Usage Page (Digitizer)		*/
200 	0x09, 0x22,		/*   Usage (Finger)			*/
201 	0xA1, 0x02,		/*   Collection (Logical)		*/
202 	0x09, 0x51,		/*     Usage (0x51)			*/
203 	0x25, 0x7F,		/*     Logical Maximum (127)		*/
204 	0x75, 0x07,		/*     Report Size (7)			*/
205 	0x95, 0x01,		/*     Report Count (1)			*/
206 	0x81, 0x02,		/*     Input (Data,Var,Abs)		*/
207 	0x09, 0x42,		/*     Usage (Tip Switch)		*/
208 	0x25, 0x01,		/*     Logical Maximum (1)		*/
209 	0x75, 0x01,		/*     Report Size (1)			*/
210 	0x95, 0x01,		/*     Report Count (1)			*/
211 	0x81, 0x02,		/*     Input (Data,Var,Abs)		*/
212 	0x05, 0x01,		/*     Usage Page (Generic Desktop Ctrls) */
213 	0x09, 0x30,		/*     Usage (X)			*/
214 	0x55, 0x0E,		/*     Unit Exponent (-2)		*/
215 	0x65, 0x11,		/*     Unit (System: SI Linear, Length: Centimeter) */
216 	0x35, 0x00,		/*     Physical Minimum (0)		*/
217 	0x46, 0x80, 0x02,	/*     Physical Maximum (640)		*/
218 	0x26, 0x80, 0x07,	/*     Logical Maximum (1920)		*/
219 	0x75, 0x0C,		/*     Report Size (12)			*/
220 	0x81, 0x02,		/*     Input (Data,Var,Abs)		*/
221 	0x09, 0x31,		/*     Usage (Y)			*/
222 	0x46, 0xC0, 0x00,	/*     Physical Maximum (192)		*/
223 	0x26, 0xAE, 0x03,	/*     Logical Maximum (942)		*/
224 	0x81, 0x02,		/*     Input (Data,Var,Abs)		*/
225 	0x65, 0x00,		/*     Unit (None)			*/
226 	0x45, 0x00,		/*     Physical Maximum (0)		*/
227 	0xC0,			/*   End Collection			*/
228 	0x05, 0x0D,		/*   Usage Page (Digitizer)		*/
229 	0x09, 0x22,		/*   Usage (Finger)			*/
230 	0xA1, 0x02,		/*   Collection (Logical)		*/
231 	0x09, 0x51,		/*     Usage (0x51)			*/
232 	0x25, 0x7F,		/*     Logical Maximum (127)		*/
233 	0x75, 0x07,		/*     Report Size (7)			*/
234 	0x95, 0x01,		/*     Report Count (1)			*/
235 	0x81, 0x02,		/*     Input (Data,Var,Abs)		*/
236 	0x09, 0x42,		/*     Usage (Tip Switch)		*/
237 	0x25, 0x01,		/*     Logical Maximum (1)		*/
238 	0x75, 0x01,		/*     Report Size (1)			*/
239 	0x95, 0x01,		/*     Report Count (1)			*/
240 	0x81, 0x02,		/*     Input (Data,Var,Abs)		*/
241 	0x05, 0x01,		/*     Usage Page (Generic Desktop Ctrls) */
242 	0x09, 0x30,		/*     Usage (X)			*/
243 	0x55, 0x0E,		/*     Unit Exponent (-2)		*/
244 	0x65, 0x11,		/*     Unit (System: SI Linear, Length: Centimeter) */
245 	0x35, 0x00,		/*     Physical Minimum (0)		*/
246 	0x46, 0x80, 0x02,	/*     Physical Maximum (640)		*/
247 	0x26, 0x80, 0x07,	/*     Logical Maximum (1920)		*/
248 	0x75, 0x0C,		/*     Report Size (12)			*/
249 	0x81, 0x02,		/*     Input (Data,Var,Abs)		*/
250 	0x09, 0x31,		/*     Usage (Y)			*/
251 	0x46, 0xC0, 0x00,	/*     Physical Maximum (192)		*/
252 	0x26, 0xAE, 0x03,	/*     Logical Maximum (942)		*/
253 	0x81, 0x02,		/*     Input (Data,Var,Abs)		*/
254 	0x65, 0x00,		/*     Unit (None)			*/
255 	0x45, 0x00,		/*     Physical Maximum (0)		*/
256 	0xC0,			/*   End Collection			*/
257 	0x05, 0x0D,		/*   Usage Page (Digitizer)		*/
258 	0x09, 0x56,		/*   Usage (0x56)			*/
259 	0x55, 0x0C,		/*   Unit Exponent (-4)			*/
260 	0x66, 0x01, 0x10,	/*   Unit (System: SI Linear, Time: Seconds) */
261 	0x46, 0xCC, 0x06,	/*   Physical Maximum (1740)		*/
262 	0x26, 0xFF, 0x00,	/*   Logical Maximum (255)		*/
263 	0x75, 0x08,		/*   Report Size (8)			*/
264 	0x95, 0x01,		/*   Report Count (1)			*/
265 	0x81, 0x02,		/*   Input (Data,Var,Abs)		*/
266 	0x65, 0x00,		/*   Unit (None)			*/
267 	0x45, 0x00,		/*   Physical Maximum (0)		*/
268 	0x05, 0x0D,		/*   Usage Page (Digitizer)		*/
269 	0x09, 0x22,		/*   Usage (Finger)			*/
270 	0xA1, 0x02,		/*   Collection (Logical)		*/
271 	0x09, 0x51,		/*     Usage (0x51)			*/
272 	0x25, 0x7F,		/*     Logical Maximum (127)		*/
273 	0x75, 0x07,		/*     Report Size (7)			*/
274 	0x95, 0x01,		/*     Report Count (1)			*/
275 	0x81, 0x02,		/*     Input (Data,Var,Abs)		*/
276 	0x09, 0x42,		/*     Usage (Tip Switch)		*/
277 	0x25, 0x01,		/*     Logical Maximum (1)		*/
278 	0x75, 0x01,		/*     Report Size (1)			*/
279 	0x95, 0x01,		/*     Report Count (1)			*/
280 	0x81, 0x02,		/*     Input (Data,Var,Abs)		*/
281 	0x05, 0x01,		/*     Usage Page (Generic Desktop Ctrls) */
282 	0x09, 0x30,		/*     Usage (X)			*/
283 	0x55, 0x0E,		/*     Unit Exponent (-2)		*/
284 	0x65, 0x11,		/*     Unit (System: SI Linear, Length: Centimeter) */
285 	0x35, 0x00,		/*     Physical Minimum (0)		*/
286 	0x46, 0x80, 0x02,	/*     Physical Maximum (640)		*/
287 	0x26, 0x80, 0x07,	/*     Logical Maximum (1920)		*/
288 	0x75, 0x0C,		/*     Report Size (12)			*/
289 	0x81, 0x02,		/*     Input (Data,Var,Abs)		*/
290 	0x09, 0x31,		/*     Usage (Y)			*/
291 	0x46, 0xC0, 0x00,	/*     Physical Maximum (192)		*/
292 	0x26, 0xAE, 0x03,	/*     Logical Maximum (942)		*/
293 	0x81, 0x02,		/*     Input (Data,Var,Abs)		*/
294 	0x65, 0x00,		/*     Unit (None)			*/
295 	0x45, 0x00,		/*     Physical Maximum (0)		*/
296 	0xC0,			/*   End Collection			*/
297 	0x05, 0x0D,		/*   Usage Page (Digitizer)		*/
298 	0x09, 0x22,		/*   Usage (Finger)			*/
299 	0xA1, 0x02,		/*   Collection (Logical)		*/
300 	0x09, 0x51,		/*     Usage (0x51)			*/
301 	0x25, 0x7F,		/*     Logical Maximum (127)		*/
302 	0x75, 0x07,		/*     Report Size (7)			*/
303 	0x95, 0x01,		/*     Report Count (1)			*/
304 	0x81, 0x02,		/*     Input (Data,Var,Abs)		*/
305 	0x09, 0x42,		/*     Usage (Tip Switch)		*/
306 	0x25, 0x01,		/*     Logical Maximum (1)		*/
307 	0x75, 0x01,		/*     Report Size (1)			*/
308 	0x95, 0x01,		/*     Report Count (1)			*/
309 	0x81, 0x02,		/*     Input (Data,Var,Abs)		*/
310 	0x05, 0x01,		/*     Usage Page (Generic Desktop Ctrls) */
311 	0x09, 0x30,		/*     Usage (X)			*/
312 	0x55, 0x0E,		/*     Unit Exponent (-2)		*/
313 	0x65, 0x11,		/*     Unit (System: SI Linear, Length: Centimeter) */
314 	0x35, 0x00,		/*     Physical Minimum (0)		*/
315 	0x46, 0x80, 0x02,	/*     Physical Maximum (640)		*/
316 	0x26, 0x80, 0x07,	/*     Logical Maximum (1920)		*/
317 	0x75, 0x0C,		/*     Report Size (12)			*/
318 	0x81, 0x02,		/*     Input (Data,Var,Abs)		*/
319 	0x09, 0x31,		/*     Usage (Y)			*/
320 	0x46, 0xC0, 0x00,	/*     Physical Maximum (192)		*/
321 	0x26, 0xAE, 0x03,	/*     Logical Maximum (942)		*/
322 	0x81, 0x02,		/*     Input (Data,Var,Abs)		*/
323 	0x65, 0x00,		/*     Unit (None)			*/
324 	0x45, 0x00,		/*     Physical Maximum (0)		*/
325 	0xC0,			/*   End Collection			*/
326 	0x05, 0x0D,		/*   Usage Page (Digitizer)		*/
327 	0x09, 0x56,		/*   Usage (0x56)			*/
328 	0x55, 0x0C,		/*   Unit Exponent (-4)			*/
329 	0x66, 0x01, 0x10,	/*   Unit (System: SI Linear, Time: Seconds) */
330 	0x46, 0xCC, 0x06,	/*   Physical Maximum (1740)		*/
331 	0x26, 0xFF, 0x00,	/*   Logical Maximum (255)		*/
332 	0x75, 0x08,		/*   Report Size (8)			*/
333 	0x95, 0x01,		/*   Report Count (1)			*/
334 	0x81, 0x02,		/*   Input (Data,Var,Abs)		*/
335 	0x65, 0x00,		/*   Unit (None)			*/
336 	0x45, 0x00,		/*   Physical Maximum (0)		*/
337 	0x05, 0x0D,		/*   Usage Page (Digitizer)		*/
338 	0x09, 0x22,		/*   Usage (Finger)			*/
339 	0xA1, 0x02,		/*   Collection (Logical)		*/
340 	0x09, 0x51,		/*     Usage (0x51)			*/
341 	0x25, 0x7F,		/*     Logical Maximum (127)		*/
342 	0x75, 0x07,		/*     Report Size (7)			*/
343 	0x95, 0x01,		/*     Report Count (1)			*/
344 	0x81, 0x02,		/*     Input (Data,Var,Abs)		*/
345 	0x09, 0x42,		/*     Usage (Tip Switch)		*/
346 	0x25, 0x01,		/*     Logical Maximum (1)		*/
347 	0x75, 0x01,		/*     Report Size (1)			*/
348 	0x95, 0x01,		/*     Report Count (1)			*/
349 	0x81, 0x02,		/*     Input (Data,Var,Abs)		*/
350 	0x05, 0x01,		/*     Usage Page (Generic Desktop Ctrls) */
351 	0x09, 0x30,		/*     Usage (X)			*/
352 	0x55, 0x0E,		/*     Unit Exponent (-2)		*/
353 	0x65, 0x11,		/*     Unit (System: SI Linear, Length: Centimeter) */
354 	0x35, 0x00,		/*     Physical Minimum (0)		*/
355 	0x46, 0x80, 0x02,	/*     Physical Maximum (640)		*/
356 	0x26, 0x80, 0x07,	/*     Logical Maximum (1920)		*/
357 	0x75, 0x0C,		/*     Report Size (12)			*/
358 	0x81, 0x02,		/*     Input (Data,Var,Abs)		*/
359 	0x09, 0x31,		/*     Usage (Y)			*/
360 	0x46, 0xC0, 0x00,	/*     Physical Maximum (192)		*/
361 	0x26, 0xAE, 0x03,	/*     Logical Maximum (942)		*/
362 	0x81, 0x02,		/*     Input (Data,Var,Abs)		*/
363 	0x65, 0x00,		/*     Unit (None)			*/
364 	0x45, 0x00,		/*     Physical Maximum (0)		*/
365 	0xC0,			/*   End Collection			*/
366 	0x05, 0x0D,		/*   Usage Page (Digitizer)		*/
367 	0x09, 0x22,		/*   Usage (Finger)			*/
368 	0xA1, 0x02,		/*   Collection (Logical)		*/
369 	0x09, 0x51,		/*     Usage (0x51)			*/
370 	0x25, 0x7F,		/*     Logical Maximum (127)		*/
371 	0x75, 0x07,		/*     Report Size (7)			*/
372 	0x95, 0x01,		/*     Report Count (1)			*/
373 	0x81, 0x02,		/*     Input (Data,Var,Abs)		*/
374 	0x09, 0x42,		/*     Usage (Tip Switch)		*/
375 	0x25, 0x01,		/*     Logical Maximum (1)		*/
376 	0x75, 0x01,		/*     Report Size (1)			*/
377 	0x95, 0x01,		/*     Report Count (1)			*/
378 	0x81, 0x02,		/*     Input (Data,Var,Abs)		*/
379 	0x05, 0x01,		/*     Usage Page (Generic Desktop Ctrls) */
380 	0x09, 0x30,		/*     Usage (X)			*/
381 	0x55, 0x0E,		/*     Unit Exponent (-2)		*/
382 	0x65, 0x11,		/*     Unit (System: SI Linear, Length: Centimeter) */
383 	0x35, 0x00,		/*     Physical Minimum (0)		*/
384 	0x46, 0x80, 0x02,	/*     Physical Maximum (640)		*/
385 	0x26, 0x80, 0x07,	/*     Logical Maximum (1920)		*/
386 	0x75, 0x0C,		/*     Report Size (12)			*/
387 	0x81, 0x02,		/*     Input (Data,Var,Abs)		*/
388 	0x09, 0x31,		/*     Usage (Y)			*/
389 	0x46, 0xC0, 0x00,	/*     Physical Maximum (192)		*/
390 	0x26, 0xAE, 0x03,	/*     Logical Maximum (942)		*/
391 	0x81, 0x02,		/*     Input (Data,Var,Abs)		*/
392 	0x65, 0x00,		/*     Unit (None)			*/
393 	0x45, 0x00,		/*     Physical Maximum (0)		*/
394 	0xC0,			/*   End Collection			*/
395 	0x75, 0x08,		/*   Report Size (8)			*/
396 	0x95, 0x03,		/*   Report Count (3)			*/
397 	0x81, 0x03,		/*   Input (Const)			*/
398 	/* Output and feature reports */
399 	0x85, 0x05,		/*   Report ID (5)			*/
400 	0x06, 0x00, 0xFF,	/*   Usage Page (Vendor Defined 0xFF00)	*/
401 	0x09, 0x22,		/*   Usage (0x22)			*/
402 	0x15, 0x00,		/*   Logical Minimum (0)		*/
403 	0x26, 0xFF, 0x00,	/*   Logical Maximum (255)		*/
404 	0x95, 0x1F,		/*   Report Count (31)			*/
405 	0x91, 0x02,		/*   Output (Data,Var,Abs)		*/
406 	0x85, 0x04,		/*   Report ID (4)			*/
407 	0x09, 0x23,		/*   Usage (0x23)			*/
408 	0x95, 0x24,		/*   Report Count (36)			*/
409 	0xB1, 0x02,		/*   Feature (Data,Var,Abs)		*/
410 	0x85, 0x02,		/*   Report ID (2)			*/
411 	0x09, 0x24,		/*   Usage (0x24)			*/
412 	0x95, 0x24,		/*   Report Count (36)			*/
413 	0xB1, 0x02,		/*   Feature (Data,Var,Abs)		*/
414 	0x85, 0x08,		/*   Report ID (8)			*/
415 	0x09, 0x25,		/*   Usage (0x25)			*/
416 	0x95, 0x03,		/*   Report Count (3)			*/
417 	0xB1, 0x02,		/*   Feature (Data,Var,Abs)		*/
418 	0x85, 0x10,		/*   Report ID (16)			*/
419 	0x09, 0x26,		/*   Usage (0x26)			*/
420 	0x95, 0x04,		/*   Report Count (4)			*/
421 	0xB1, 0x02,		/*   Feature (Data,Var,Abs)		*/
422 	0x85, 0x11,		/*   Report ID (17)			*/
423 	0x09, 0x27,		/*   Usage (0x27)			*/
424 	0x95, 0x02,		/*   Report Count (2)			*/
425 	0xB1, 0x02,		/*   Feature (Data,Var,Abs)		*/
426 	0x85, 0x12,		/*   Report ID (18)			*/
427 	0x06, 0x02, 0xFF,	/*   Usage Page (Vendor Defined 0xFF02)	*/
428 	0x09, 0x21,		/*   Usage (0x21)			*/
429 	0x95, 0x0F,		/*   Report Count (15)			*/
430 	0xB1, 0x02,		/*   Feature (Data,Var,Abs)		*/
431 	0x85, 0x13,		/*   Report ID (19)			*/
432 	0x09, 0x22,		/*   Usage (0x22)			*/
433 	0x95, 0x16,		/*   Report Count (22)			*/
434 	0xB1, 0x02,		/*   Feature (Data,Var,Abs)		*/
435 	0x85, 0x14,		/*   Report ID (20)			*/
436 	0x06, 0x05, 0xFF,	/*   Usage Page (Vendor Defined 0xFF05)	*/
437 	0x09, 0x20,		/*   Usage (0x20)			*/
438 	0x95, 0x10,		/*   Report Count (16)			*/
439 	0xB1, 0x02,		/*   Feature (Data,Var,Abs)		*/
440 	0x85, 0x15,		/*   Report ID (21)			*/
441 	0x09, 0x21,		/*   Usage (0x21)			*/
442 	0x95, 0x2C,		/*   Report Count (44)			*/
443 	0xB1, 0x02,		/*   Feature (Data,Var,Abs)		*/
444 	0x06, 0x80, 0xFF,	/*   Usage Page (Vendor Defined 0xFF80)	*/
445 	0x85, 0x80,		/*   Report ID (-128)			*/
446 	0x09, 0x20,		/*   Usage (0x20)			*/
447 	0x95, 0x06,		/*   Report Count (6)			*/
448 	0xB1, 0x02,		/*   Feature (Data,Var,Abs)		*/
449 	0x85, 0x81,		/*   Report ID (-127)			*/
450 	0x09, 0x21,		/*   Usage (0x21)			*/
451 	0x95, 0x06,		/*   Report Count (6)			*/
452 	0xB1, 0x02,		/*   Feature (Data,Var,Abs)		*/
453 	0x85, 0x82,		/*   Report ID (-126)			*/
454 	0x09, 0x22,		/*   Usage (0x22)			*/
455 	0x95, 0x05,		/*   Report Count (5)			*/
456 	0xB1, 0x02,		/*   Feature (Data,Var,Abs)		*/
457 	0x85, 0x83,		/*   Report ID (-125)			*/
458 	0x09, 0x23,		/*   Usage (0x23)			*/
459 	0x95, 0x01,		/*   Report Count (1)			*/
460 	0xB1, 0x02,		/*   Feature (Data,Var,Abs)		*/
461 	0x85, 0x84,		/*   Report ID (-124)			*/
462 	0x09, 0x24,		/*   Usage (0x24)			*/
463 	0x95, 0x04,		/*   Report Count (4)			*/
464 	0xB1, 0x02,		/*   Feature (Data,Var,Abs)		*/
465 	0x85, 0x85,		/*   Report ID (-123)			*/
466 	0x09, 0x25,		/*   Usage (0x25)			*/
467 	0x95, 0x06,		/*   Report Count (6)			*/
468 	0xB1, 0x02,		/*   Feature (Data,Var,Abs)		*/
469 	0x85, 0x86,		/*   Report ID (-122)			*/
470 	0x09, 0x26,		/*   Usage (0x26)			*/
471 	0x95, 0x06,		/*   Report Count (6)			*/
472 	0xB1, 0x02,		/*   Feature (Data,Var,Abs)		*/
473 	0x85, 0x87,		/*   Report ID (-121)			*/
474 	0x09, 0x27,		/*   Usage (0x27)			*/
475 	0x95, 0x23,		/*   Report Count (35)			*/
476 	0xB1, 0x02,		/*   Feature (Data,Var,Abs)		*/
477 	0x85, 0x88,		/*   Report ID (-120)			*/
478 	0x09, 0x28,		/*   Usage (0x28)			*/
479 	0x95, 0x22,		/*   Report Count (34)			*/
480 	0xB1, 0x02,		/*   Feature (Data,Var,Abs)		*/
481 	0x85, 0x89,		/*   Report ID (-119)			*/
482 	0x09, 0x29,		/*   Usage (0x29)			*/
483 	0x95, 0x02,		/*   Report Count (2)			*/
484 	0xB1, 0x02,		/*   Feature (Data,Var,Abs)		*/
485 	0x85, 0x90,		/*   Report ID (-112)			*/
486 	0x09, 0x30,		/*   Usage (0x30)			*/
487 	0x95, 0x05,		/*   Report Count (5)			*/
488 	0xB1, 0x02,		/*   Feature (Data,Var,Abs)		*/
489 	0x85, 0x91,		/*   Report ID (-111)			*/
490 	0x09, 0x31,		/*   Usage (0x31)			*/
491 	0x95, 0x03,		/*   Report Count (3)			*/
492 	0xB1, 0x02,		/*   Feature (Data,Var,Abs)		*/
493 	0x85, 0x92,		/*   Report ID (-110)			*/
494 	0x09, 0x32,		/*   Usage (0x32)			*/
495 	0x95, 0x03,		/*   Report Count (3)			*/
496 	0xB1, 0x02,		/*   Feature (Data,Var,Abs)		*/
497 	0x85, 0x93,		/*   Report ID (-109)			*/
498 	0x09, 0x33,		/*   Usage (0x33)			*/
499 	0x95, 0x0C,		/*   Report Count (12)			*/
500 	0xB1, 0x02,		/*   Feature (Data,Var,Abs)		*/
501 	0x85, 0xA0,		/*   Report ID (-96)			*/
502 	0x09, 0x40,		/*   Usage (0x40)			*/
503 	0x95, 0x06,		/*   Report Count (6)			*/
504 	0xB1, 0x02,		/*   Feature (Data,Var,Abs)		*/
505 	0x85, 0xA1,		/*   Report ID (-95)			*/
506 	0x09, 0x41,		/*   Usage (0x41)			*/
507 	0x95, 0x01,		/*   Report Count (1)			*/
508 	0xB1, 0x02,		/*   Feature (Data,Var,Abs)		*/
509 	0x85, 0xA2,		/*   Report ID (-94)			*/
510 	0x09, 0x42,		/*   Usage (0x42)			*/
511 	0x95, 0x01,		/*   Report Count (1)			*/
512 	0xB1, 0x02,		/*   Feature (Data,Var,Abs)		*/
513 	0x85, 0xA3,		/*   Report ID (-93)			*/
514 	0x09, 0x43,		/*   Usage (0x43)			*/
515 	0x95, 0x30,		/*   Report Count (48)			*/
516 	0xB1, 0x02,		/*   Feature (Data,Var,Abs)		*/
517 	0x85, 0xA4,		/*   Report ID (-92)			*/
518 	0x09, 0x44,		/*   Usage (0x44)			*/
519 	0x95, 0x0D,		/*   Report Count (13)			*/
520 	0xB1, 0x02,		/*   Feature (Data,Var,Abs)		*/
521 	0x85, 0xA5,		/*   Report ID (-91)			*/
522 	0x09, 0x45,		/*   Usage (0x45)			*/
523 	0x95, 0x15,		/*   Report Count (21)			*/
524 	0xB1, 0x02,		/*   Feature (Data,Var,Abs)		*/
525 	0x85, 0xA6,		/*   Report ID (-90)			*/
526 	0x09, 0x46,		/*   Usage (0x46)			*/
527 	0x95, 0x15,		/*   Report Count (21)			*/
528 	0xB1, 0x02,		/*   Feature (Data,Var,Abs)		*/
529 	0x85, 0xF0,		/*   Report ID (-16)			*/
530 	0x09, 0x47,		/*   Usage (0x47)			*/
531 	0x95, 0x3F,		/*   Report Count (63)			*/
532 	0xB1, 0x02,		/*   Feature (Data,Var,Abs)		*/
533 	0x85, 0xF1,		/*   Report ID (-15)			*/
534 	0x09, 0x48,		/*   Usage (0x48)			*/
535 	0x95, 0x3F,		/*   Report Count (63)			*/
536 	0xB1, 0x02,		/*   Feature (Data,Var,Abs)		*/
537 	0x85, 0xF2,		/*   Report ID (-14)			*/
538 	0x09, 0x49,		/*   Usage (0x49)			*/
539 	0x95, 0x0F,		/*   Report Count (15)			*/
540 	0xB1, 0x02,		/*   Feature (Data,Var,Abs)		*/
541 	0x85, 0xA7,		/*   Report ID (-89)			*/
542 	0x09, 0x4A,		/*   Usage (0x4A)			*/
543 	0x95, 0x01,		/*   Report Count (1)			*/
544 	0xB1, 0x02,		/*   Feature (Data,Var,Abs)		*/
545 	0x85, 0xA8,		/*   Report ID (-88)			*/
546 	0x09, 0x4B,		/*   Usage (0x4B)			*/
547 	0x95, 0x01,		/*   Report Count (1)			*/
548 	0xB1, 0x02,		/*   Feature (Data,Var,Abs)		*/
549 	0x85, 0xA9,		/*   Report ID (-87)			*/
550 	0x09, 0x4C,		/*   Usage (0x4C)			*/
551 	0x95, 0x08,		/*   Report Count (8)			*/
552 	0xB1, 0x02,		/*   Feature (Data,Var,Abs)		*/
553 	0x85, 0xAA,		/*   Report ID (-86)			*/
554 	0x09, 0x4E,		/*   Usage (0x4E)			*/
555 	0x95, 0x01,		/*   Report Count (1)			*/
556 	0xB1, 0x02,		/*   Feature (Data,Var,Abs)		*/
557 	0x85, 0xAB,		/*   Report ID (-85)			*/
558 	0x09, 0x4F,		/*   Usage (0x4F)			*/
559 	0x95, 0x39,		/*   Report Count (57)			*/
560 	0xB1, 0x02,		/*   Feature (Data,Var,Abs)		*/
561 	0x85, 0xAC,		/*   Report ID (-84)			*/
562 	0x09, 0x50,		/*   Usage (0x50)			*/
563 	0x95, 0x39,		/*   Report Count (57)			*/
564 	0xB1, 0x02,		/*   Feature (Data,Var,Abs)		*/
565 	0x85, 0xAD,		/*   Report ID (-83)			*/
566 	0x09, 0x51,		/*   Usage (0x51)			*/
567 	0x95, 0x0B,		/*   Report Count (11)			*/
568 	0xB1, 0x02,		/*   Feature (Data,Var,Abs)		*/
569 	0x85, 0xAE,		/*   Report ID (-82)			*/
570 	0x09, 0x52,		/*   Usage (0x52)			*/
571 	0x95, 0x01,		/*   Report Count (1)			*/
572 	0xB1, 0x02,		/*   Feature (Data,Var,Abs)		*/
573 	0x85, 0xAF,		/*   Report ID (-81)			*/
574 	0x09, 0x53,		/*   Usage (0x53)			*/
575 	0x95, 0x02,		/*   Report Count (2)			*/
576 	0xB1, 0x02,		/*   Feature (Data,Var,Abs)		*/
577 	0x85, 0xB0,		/*   Report ID (-80)			*/
578 	0x09, 0x54,		/*   Usage (0x54)			*/
579 	0x95, 0x3F,		/*   Report Count (63)			*/
580 	0xB1, 0x02,		/*   Feature (Data,Var,Abs)		*/
581 	0xC0,			/* End Collection			*/
582 };
583 
584 #define	PS4DS_GYRO_RES_PER_DEG_S	1024
585 #define	PS4DS_ACC_RES_PER_G		8192
586 #define	PS4DS_MAX_TOUCHPAD_PACKETS	4
587 #define	PS4DS_FEATURE_REPORT2_SIZE	37
588 #define	PS4DS_OUTPUT_REPORT5_SIZE	32
589 #define	PS4DS_OUTPUT_REPORT11_SIZE	78
590 
591 static hidmap_cb_t	ps4dshock_hat_switch_cb;
592 static hidmap_cb_t	ps4dshock_final_cb;
593 static hidmap_cb_t	ps4dsacc_data_cb;
594 static hidmap_cb_t	ps4dsacc_tstamp_cb;
595 static hidmap_cb_t	ps4dsacc_final_cb;
596 static hidmap_cb_t	ps4dsmtp_data_cb;
597 static hidmap_cb_t	ps4dsmtp_npackets_cb;
598 static hidmap_cb_t	ps4dsmtp_final_cb;
599 
600 struct ps4ds_out5 {
601 	uint8_t features;
602 	uint8_t	reserved1;
603 	uint8_t	reserved2;
604 	uint8_t	rumble_right;
605 	uint8_t	rumble_left;
606 	uint8_t	led_color_r;
607 	uint8_t	led_color_g;
608 	uint8_t	led_color_b;
609 	uint8_t	led_delay_on;	/* centiseconds */
610 	uint8_t	led_delay_off;
611 } __attribute__((packed));
612 
613 static const struct ps4ds_led {
614 	int	r;
615 	int	g;
616 	int	b;
617 } ps4ds_leds[] = {
618 	/* The first 4 entries match the PS4, other from Linux driver */
619 	{ 0x00, 0x00, 0x40 },	/* Blue   */
620 	{ 0x40, 0x00, 0x00 },	/* Red	  */
621 	{ 0x00, 0x40, 0x00 },	/* Green  */
622 	{ 0x20, 0x00, 0x20 },	/* Pink   */
623 	{ 0x02, 0x01, 0x00 },	/* Orange */
624 	{ 0x00, 0x01, 0x01 },	/* Teal   */
625 	{ 0x01, 0x01, 0x01 }	/* White  */
626 };
627 
628 enum ps4ds_led_state {
629 	PS4DS_LED_OFF,
630 	PS4DS_LED_ON,
631 	PS4DS_LED_BLINKING,
632 	PD4DS_LED_CNT,
633 };
634 
635 /* Map structure for accelerometer and gyro. */
636 struct ps4ds_calib_data {
637 	int32_t usage;
638 	int32_t code;
639 	int32_t res;
640 	int32_t range;
641 	/* Calibration data for accelerometer and gyro. */
642 	int16_t bias;
643 	int32_t sens_numer;
644 	int32_t sens_denom;
645 };
646 
647 enum {
648 	PS4DS_TSTAMP,
649 	PS4DS_CID1,
650 	PS4DS_TIP1,
651 	PS4DS_X1,
652 	PS4DS_Y1,
653 	PS4DS_CID2,
654 	PS4DS_TIP2,
655 	PS4DS_X2,
656 	PS4DS_Y2,
657 	PS4DS_NTPUSAGES,
658 };
659 
660 struct ps4dshock_softc {
661 	struct hidmap		hm;
662 
663 	bool			is_bluetooth;
664 
665 	struct sx		lock;
666 	enum ps4ds_led_state	led_state;
667 	struct ps4ds_led	led_color;
668 	int			led_delay_on;	/* msecs */
669 	int			led_delay_off;
670 
671 	int			rumble_right;
672 	int			rumble_left;
673 };
674 
675 struct ps4dsacc_softc {
676 	struct hidmap		hm;
677 
678 	uint16_t		hw_tstamp;
679 	int32_t			ev_tstamp;
680 
681 	struct ps4ds_calib_data	calib_data[6];
682 };
683 
684 struct ps4dsmtp_softc {
685 	struct hidmap		hm;
686 
687 	struct hid_location	btn_loc;
688 	u_int		npackets;
689 	int32_t		*data_ptr;
690 	int32_t		data[PS4DS_MAX_TOUCHPAD_PACKETS * PS4DS_NTPUSAGES];
691 
692 	bool		do_tstamps;
693 	uint8_t		hw_tstamp;
694 	int32_t		ev_tstamp;
695 	bool		touch;
696 };
697 
698 #define PD4DSHOCK_OFFSET(field) offsetof(struct ps4dshock_softc, field)
699 enum {
700 	PD4DSHOCK_SYSCTL_LED_STATE =	PD4DSHOCK_OFFSET(led_state),
701 	PD4DSHOCK_SYSCTL_LED_COLOR_R =	PD4DSHOCK_OFFSET(led_color.r),
702 	PD4DSHOCK_SYSCTL_LED_COLOR_G =	PD4DSHOCK_OFFSET(led_color.g),
703 	PD4DSHOCK_SYSCTL_LED_COLOR_B =	PD4DSHOCK_OFFSET(led_color.b),
704 	PD4DSHOCK_SYSCTL_LED_DELAY_ON =	PD4DSHOCK_OFFSET(led_delay_on),
705 	PD4DSHOCK_SYSCTL_LED_DELAY_OFF=	PD4DSHOCK_OFFSET(led_delay_off),
706 #define	PD4DSHOCK_SYSCTL_LAST		PD4DSHOCK_SYSCTL_LED_DELAY_OFF
707 };
708 
709 #define PS4DS_MAP_BTN(number, code)		\
710 	{ HIDMAP_KEY(HUP_BUTTON, number, code) }
711 #define PS4DS_MAP_ABS(usage, code)		\
712 	{ HIDMAP_ABS(HUP_GENERIC_DESKTOP, HUG_##usage, code) }
713 #define PS4DS_MAP_FLT(usage, code)		\
714 	{ HIDMAP_ABS(HUP_GENERIC_DESKTOP, HUG_##usage, code), .flat = 15 }
715 #define PS4DS_MAP_VSW(usage, code)	\
716 	{ HIDMAP_SW(HUP_MICROSOFT, usage, code) }
717 #define PS4DS_MAP_GCB(usage, callback)	\
718 	{ HIDMAP_ANY_CB(HUP_GENERIC_DESKTOP, HUG_##usage, callback) }
719 #define PS4DS_MAP_VCB(usage, callback)	\
720 	{ HIDMAP_ANY_CB(HUP_MICROSOFT, usage, callback) }
721 #define PS4DS_FINALCB(cb)			\
722 	{ HIDMAP_FINAL_CB(&cb) }
723 
724 static const struct hidmap_item ps4dshock_map[] = {
725 	PS4DS_MAP_FLT(X,		ABS_X),
726 	PS4DS_MAP_FLT(Y,		ABS_Y),
727 	PS4DS_MAP_ABS(Z,		ABS_Z),
728 	PS4DS_MAP_FLT(RX,		ABS_RX),
729 	PS4DS_MAP_FLT(RY,		ABS_RY),
730 	PS4DS_MAP_ABS(RZ,		ABS_RZ),
731 	PS4DS_MAP_BTN(1,		BTN_WEST),
732 	PS4DS_MAP_BTN(2,		BTN_SOUTH),
733 	PS4DS_MAP_BTN(3,		BTN_EAST),
734 	PS4DS_MAP_BTN(4,		BTN_NORTH),
735 	PS4DS_MAP_BTN(5,		BTN_TL),
736 	PS4DS_MAP_BTN(6,		BTN_TR),
737 	PS4DS_MAP_BTN(7,		BTN_TL2),
738 	PS4DS_MAP_BTN(8,		BTN_TR2),
739 	PS4DS_MAP_BTN(9,		BTN_SELECT),
740 	PS4DS_MAP_BTN(10,		BTN_START),
741 	PS4DS_MAP_BTN(11,		BTN_THUMBL),
742 	PS4DS_MAP_BTN(12,		BTN_THUMBR),
743 	PS4DS_MAP_BTN(13,		BTN_MODE),
744 	/* Click button is handled by touchpad driver */
745 	/* PS4DS_MAP_BTN(14,	BTN_LEFT), */
746 	PS4DS_MAP_GCB(HAT_SWITCH,	ps4dshock_hat_switch_cb),
747 	PS4DS_FINALCB(			ps4dshock_final_cb),
748 };
749 static const struct hidmap_item ps4dsacc_map[] = {
750 	PS4DS_MAP_GCB(X,		ps4dsacc_data_cb),
751 	PS4DS_MAP_GCB(Y,		ps4dsacc_data_cb),
752 	PS4DS_MAP_GCB(Z,		ps4dsacc_data_cb),
753 	PS4DS_MAP_GCB(RX,		ps4dsacc_data_cb),
754 	PS4DS_MAP_GCB(RY,		ps4dsacc_data_cb),
755 	PS4DS_MAP_GCB(RZ,		ps4dsacc_data_cb),
756 	PS4DS_MAP_VCB(0x0021,		ps4dsacc_tstamp_cb),
757 	PS4DS_FINALCB(			ps4dsacc_final_cb),
758 };
759 static const struct hidmap_item ps4dshead_map[] = {
760 	PS4DS_MAP_VSW(0x0020,		SW_MICROPHONE_INSERT),
761 	PS4DS_MAP_VSW(0x0021,		SW_HEADPHONE_INSERT),
762 };
763 static const struct hidmap_item ps4dsmtp_map[] = {
764 	{ HIDMAP_ABS_CB(HUP_MICROSOFT, 0x0021, 		ps4dsmtp_npackets_cb)},
765 	{ HIDMAP_ABS_CB(HUP_DIGITIZERS, HUD_SCAN_TIME,	ps4dsmtp_data_cb) },
766 	{ HIDMAP_ABS_CB(HUP_DIGITIZERS, HUD_CONTACTID,	ps4dsmtp_data_cb) },
767 	{ HIDMAP_ABS_CB(HUP_DIGITIZERS, HUD_TIP_SWITCH,	ps4dsmtp_data_cb) },
768 	{ HIDMAP_ABS_CB(HUP_GENERIC_DESKTOP, HUG_X,	ps4dsmtp_data_cb) },
769 	{ HIDMAP_ABS_CB(HUP_GENERIC_DESKTOP, HUG_Y,	ps4dsmtp_data_cb) },
770 	{ HIDMAP_FINAL_CB(				ps4dsmtp_final_cb) },
771 };
772 
773 static const struct hid_device_id ps4dshock_devs[] = {
774 	{ HID_BVP(BUS_USB, USB_VENDOR_SONY, 0x9cc),
775 	  HID_TLC(HUP_GENERIC_DESKTOP, HUG_GAME_PAD) },
776 };
777 static const struct hid_device_id ps4dsacc_devs[] = {
778 	{ HID_BVP(BUS_USB, USB_VENDOR_SONY, 0x9cc),
779 	  HID_TLC(HUP_GENERIC_DESKTOP, HUG_MULTIAXIS_CNTROLLER) },
780 };
781 static const struct hid_device_id ps4dshead_devs[] = {
782 	{ HID_BVP(BUS_USB, USB_VENDOR_SONY, 0x9cc),
783 	  HID_TLC(HUP_CONSUMER, HUC_HEADPHONE) },
784 };
785 static const struct hid_device_id ps4dsmtp_devs[] = {
786 	{ HID_BVP(BUS_USB, USB_VENDOR_SONY, 0x9cc),
787 	  HID_TLC(HUP_DIGITIZERS, HUD_TOUCHPAD) },
788 };
789 
790 static int
791 ps4dshock_hat_switch_cb(HIDMAP_CB_ARGS)
792 {
793 	static const struct { int32_t x; int32_t y; } hat_switch_map[] = {
794 	    {0, -1}, {1, -1}, {1, 0}, {1, 1}, {0, 1}, {-1, 1}, {-1, 0},
795 	    {-1, -1},{0, 0}
796 	};
797 	struct evdev_dev *evdev = HIDMAP_CB_GET_EVDEV();
798 	u_int idx;
799 
800 	switch (HIDMAP_CB_GET_STATE()) {
801 	case HIDMAP_CB_IS_ATTACHING:
802 		evdev_support_event(evdev, EV_ABS);
803 		evdev_support_abs(evdev, ABS_HAT0X, -1, 1, 0, 0, 0);
804 		evdev_support_abs(evdev, ABS_HAT0Y, -1, 1, 0, 0, 0);
805 		break;
806 
807 	case HIDMAP_CB_IS_RUNNING:
808 		idx = MIN(nitems(hat_switch_map) - 1, (u_int)ctx.data);
809 		evdev_push_abs(evdev, ABS_HAT0X, hat_switch_map[idx].x);
810 		evdev_push_abs(evdev, ABS_HAT0Y, hat_switch_map[idx].y);
811 	}
812 
813 	return (0);
814 }
815 
816 static int
817 ps4dshock_final_cb(HIDMAP_CB_ARGS)
818 {
819 	struct evdev_dev *evdev = HIDMAP_CB_GET_EVDEV();
820 
821 	if (HIDMAP_CB_GET_STATE() == HIDMAP_CB_IS_ATTACHING)
822 		evdev_support_prop(evdev, INPUT_PROP_DIRECT);
823 
824 	/* Do not execute callback at interrupt handler and detach */
825 	return (ENOSYS);
826 }
827 
828 static int
829 ps4dsacc_data_cb(HIDMAP_CB_ARGS)
830 {
831 	struct evdev_dev *evdev = HIDMAP_CB_GET_EVDEV();
832 	struct ps4dsacc_softc *sc = HIDMAP_CB_GET_SOFTC();
833 	struct ps4ds_calib_data *calib;
834 	u_int i;
835 
836 	switch (HIDMAP_CB_GET_STATE()) {
837 	case HIDMAP_CB_IS_ATTACHING:
838 		for (i = 0; i < nitems(sc->calib_data); i++) {
839 			if (sc->calib_data[i].usage == ctx.hi->usage) {
840 				evdev_support_abs(evdev,
841 				     sc->calib_data[i].code,
842 				    -sc->calib_data[i].range,
843 				     sc->calib_data[i].range, 16, 0,
844 				     sc->calib_data[i].res);
845 				HIDMAP_CB_UDATA = &sc->calib_data[i];
846 				break;
847 			}
848 		}
849 		break;
850 
851 	case HIDMAP_CB_IS_RUNNING:
852 		calib = HIDMAP_CB_UDATA;
853 		evdev_push_abs(evdev, calib->code,
854 		    ((int64_t)ctx.data - calib->bias) * calib->sens_numer /
855 		    calib->sens_denom);
856 		break;
857 	}
858 
859 	return (0);
860 }
861 
862 static int
863 ps4dsacc_tstamp_cb(HIDMAP_CB_ARGS)
864 {
865 	struct evdev_dev *evdev = HIDMAP_CB_GET_EVDEV();
866 	struct ps4dsacc_softc *sc = HIDMAP_CB_GET_SOFTC();
867 	uint16_t tstamp;
868 
869 	switch (HIDMAP_CB_GET_STATE()) {
870 	case HIDMAP_CB_IS_ATTACHING:
871 		evdev_support_event(evdev, EV_MSC);
872 		evdev_support_msc(evdev, MSC_TIMESTAMP);
873 		break;
874 
875 	case HIDMAP_CB_IS_RUNNING:
876 		/* Convert timestamp (in 5.33us unit) to timestamp_us */
877 		tstamp = (uint16_t)ctx.data;
878 		sc->ev_tstamp += (uint16_t)(tstamp - sc->hw_tstamp) * 16 / 3;
879 		sc->hw_tstamp = tstamp;
880 		evdev_push_msc(evdev, MSC_TIMESTAMP, sc->ev_tstamp);
881 		break;
882 	}
883 
884 	return (0);
885 }
886 
887 static int
888 ps4dsacc_final_cb(HIDMAP_CB_ARGS)
889 {
890 	struct evdev_dev *evdev = HIDMAP_CB_GET_EVDEV();
891 
892 	if (HIDMAP_CB_GET_STATE() == HIDMAP_CB_IS_ATTACHING) {
893 		evdev_support_event(evdev, EV_ABS);
894 		evdev_support_prop(evdev, INPUT_PROP_ACCELEROMETER);
895 	}
896         /* Do not execute callback at interrupt handler and detach */
897         return (ENOSYS);
898 }
899 
900 static int
901 ps4dsmtp_npackets_cb(HIDMAP_CB_ARGS)
902 {
903 	struct ps4dsmtp_softc *sc = HIDMAP_CB_GET_SOFTC();
904 
905 	if (HIDMAP_CB_GET_STATE() == HIDMAP_CB_IS_RUNNING) {
906 		sc->npackets = MIN(PS4DS_MAX_TOUCHPAD_PACKETS,(u_int)ctx.data);
907 		/* Reset pointer here as it is first usage in touchpad TLC */
908 		sc->data_ptr = sc->data;
909 	}
910 
911 	return (0);
912 }
913 
914 static int
915 ps4dsmtp_data_cb(HIDMAP_CB_ARGS)
916 {
917 	struct ps4dsmtp_softc *sc = HIDMAP_CB_GET_SOFTC();
918 
919 	if (HIDMAP_CB_GET_STATE() == HIDMAP_CB_IS_RUNNING) {
920 		*sc->data_ptr = ctx.data;
921 		++sc->data_ptr;
922 	}
923 
924 	return (0);
925 }
926 
927 static void
928 ps4dsmtp_push_packet(struct ps4dsmtp_softc *sc, struct evdev_dev *evdev,
929     int32_t *data)
930 {
931 	uint8_t hw_tstamp, delta;
932 	bool touch;
933 
934 	evdev_push_abs(evdev, ABS_MT_SLOT, 0);
935 	if (data[PS4DS_TIP1] == 0) {
936 		evdev_push_abs(evdev, ABS_MT_TRACKING_ID, data[PS4DS_CID1]);
937 		evdev_push_abs(evdev, ABS_MT_POSITION_X, data[PS4DS_X1]);
938 		evdev_push_abs(evdev, ABS_MT_POSITION_Y, data[PS4DS_Y1]);
939 	} else
940 		evdev_push_abs(evdev, ABS_MT_TRACKING_ID, -1);
941 	evdev_push_abs(evdev, ABS_MT_SLOT, 1);
942 	if (data[PS4DS_TIP2] == 0) {
943 		evdev_push_abs(evdev, ABS_MT_TRACKING_ID, data[PS4DS_CID2]);
944 		evdev_push_abs(evdev, ABS_MT_POSITION_X, data[PS4DS_X2]);
945 		evdev_push_abs(evdev, ABS_MT_POSITION_Y, data[PS4DS_Y2]);
946 	} else
947 		evdev_push_abs(evdev, ABS_MT_TRACKING_ID, -1);
948 
949 	if (sc->do_tstamps) {
950 		/*
951 		 * Export hardware timestamps in libinput-friendly way.
952 		 * Make timestamp counter 32-bit, scale up hardware
953 		 * timestamps to be on per 1usec basis and reset
954 		 * counter at the start of each touch.
955 		 */
956 		hw_tstamp = (uint8_t)data[PS4DS_TSTAMP];
957 		delta = hw_tstamp - sc->hw_tstamp;
958 		sc->hw_tstamp = hw_tstamp;
959 		touch = data[PS4DS_TIP1] == 0 || data[PS4DS_TIP2] == 0;
960 		/* Hardware timestamp counter ticks in 682 usec interval. */
961 		if ((touch || sc->touch) && delta != 0) {
962 			if (sc->touch)
963 				sc->ev_tstamp += delta * 682;
964 			evdev_push_msc(evdev, MSC_TIMESTAMP, sc->ev_tstamp);
965 		}
966 		if (!touch)
967 			sc->ev_tstamp = 0;
968 		sc->touch = touch;
969 	}
970 }
971 
972 static int
973 ps4dsmtp_final_cb(HIDMAP_CB_ARGS)
974 {
975 	struct ps4dsmtp_softc *sc = HIDMAP_CB_GET_SOFTC();
976 	struct evdev_dev *evdev = HIDMAP_CB_GET_EVDEV();
977 	int32_t *data;
978 
979 	switch (HIDMAP_CB_GET_STATE()) {
980 	case HIDMAP_CB_IS_ATTACHING:
981 		if (hid_test_quirk(hid_get_device_info(sc->hm.dev),
982 		    HQ_MT_TIMESTAMP))
983 			sc->do_tstamps = true;
984 		/*
985 		 * Dualshock 4 touchpad TLC contained in fixed report
986 		 * descriptor is almost compatible with MS precission touchpad
987 		 * specs and hmt(4) driver. But... for some reasons "Click"
988 		 * button location was grouped with other GamePad buttons by
989 		 * touchpad designers so it belongs to GamePad TLC. Fix it with
990 		 * direct reading of "Click" button value from interrupt frame.
991 		 */
992 		sc->btn_loc = (struct hid_location) { 1, 0, 49 };
993 		evdev_support_event(evdev, EV_SYN);
994 		evdev_support_event(evdev, EV_KEY);
995 		evdev_support_event(evdev, EV_ABS);
996 		if (sc->do_tstamps) {
997 			evdev_support_event(evdev, EV_MSC);
998 			evdev_support_msc(evdev, MSC_TIMESTAMP);
999 		}
1000 		evdev_support_key(evdev, BTN_LEFT);
1001 		evdev_support_abs(evdev, ABS_MT_SLOT, 0, 1, 0, 0, 0);
1002 		evdev_support_abs(evdev, ABS_MT_TRACKING_ID, -1, 127, 0, 0, 0);
1003 		evdev_support_abs(evdev, ABS_MT_POSITION_X, 0, 1920, 0, 0, 30);
1004 		evdev_support_abs(evdev, ABS_MT_POSITION_Y, 0, 942, 0, 0, 49);
1005 		evdev_support_prop(evdev, INPUT_PROP_POINTER);
1006 		evdev_support_prop(evdev, INPUT_PROP_BUTTONPAD);
1007 		evdev_set_flag(evdev, EVDEV_FLAG_MT_STCOMPAT);
1008 		break;
1009 
1010 	case HIDMAP_CB_IS_RUNNING:
1011 		/* Only packets with ReportID=1 are accepted */
1012 		if (HIDMAP_CB_GET_RID() != 1)
1013 			return (ENOTSUP);
1014 		evdev_push_key(evdev, BTN_LEFT,
1015 		    HIDMAP_CB_GET_UDATA(&sc->btn_loc));
1016 		for (data = sc->data;
1017 		     data < sc->data + PS4DS_NTPUSAGES * sc->npackets;
1018 		     data += PS4DS_NTPUSAGES) {
1019 			ps4dsmtp_push_packet(sc, evdev, data);
1020 			evdev_sync(evdev);
1021 		}
1022 		break;
1023 	}
1024 
1025 	/* Do execute callback at interrupt handler and detach */
1026 	return (0);
1027 }
1028 
1029 static int
1030 ps4dshock_write(struct ps4dshock_softc *sc)
1031 {
1032 	hid_size_t osize = sc->is_bluetooth ?
1033 	    PS4DS_OUTPUT_REPORT11_SIZE : PS4DS_OUTPUT_REPORT5_SIZE;
1034 	uint8_t buf[osize];
1035 	int offset;
1036 	bool led_on, led_blinks;
1037 
1038 	memset(buf, 0, osize);
1039 	buf[0] = sc->is_bluetooth ? 0x11 : 0x05;
1040 	offset = sc->is_bluetooth ? 3 : 1;
1041 	led_on = sc->led_state != PS4DS_LED_OFF;
1042 	led_blinks = sc->led_state == PS4DS_LED_BLINKING;
1043 	*(struct ps4ds_out5 *)(buf + offset) = (struct ps4ds_out5) {
1044 		.features = 0x07, /* blink + LEDs + motor */
1045 		.rumble_right = sc->rumble_right,
1046 		.rumble_left = sc->rumble_left,
1047 		.led_color_r = led_on ? sc->led_color.r : 0,
1048 		.led_color_g = led_on ? sc->led_color.g : 0,
1049 		.led_color_b = led_on ? sc->led_color.b : 0,
1050 		/* convert milliseconds to centiseconds */
1051 		.led_delay_on = led_blinks ? sc->led_delay_on / 10 : 0,
1052 		.led_delay_off = led_blinks ? sc->led_delay_off / 10 : 0,
1053 	};
1054 
1055 	return (hid_write(sc->hm.dev, buf, osize));
1056 }
1057 
1058 /* Synaptics Touchpad */
1059 static int
1060 ps4dshock_sysctl(SYSCTL_HANDLER_ARGS)
1061 {
1062 	struct ps4dshock_softc *sc;
1063 	int error, arg;
1064 
1065 	if (oidp->oid_arg1 == NULL || oidp->oid_arg2 < 0 ||
1066 	    oidp->oid_arg2 > PD4DSHOCK_SYSCTL_LAST)
1067 		return (EINVAL);
1068 
1069 	sc = oidp->oid_arg1;
1070 	sx_xlock(&sc->lock);
1071 
1072 	/* Read the current value. */
1073 	arg = *(int *)((char *)sc + oidp->oid_arg2);
1074 	error = sysctl_handle_int(oidp, &arg, 0, req);
1075 
1076 	/* Sanity check. */
1077 	if (error || !req->newptr)
1078 		goto unlock;
1079 
1080 	/*
1081 	 * Check that the new value is in the concerned node's range
1082 	 * of values.
1083 	 */
1084 	switch (oidp->oid_arg2) {
1085 	case PD4DSHOCK_SYSCTL_LED_STATE:
1086 		if (arg < 0 || arg >= PD4DS_LED_CNT)
1087 			error = EINVAL;
1088 		break;
1089 	case PD4DSHOCK_SYSCTL_LED_COLOR_R:
1090 	case PD4DSHOCK_SYSCTL_LED_COLOR_G:
1091 	case PD4DSHOCK_SYSCTL_LED_COLOR_B:
1092 		if (arg < 0 || arg > UINT8_MAX)
1093 			error = EINVAL;
1094 		break;
1095 	case PD4DSHOCK_SYSCTL_LED_DELAY_ON:
1096 	case PD4DSHOCK_SYSCTL_LED_DELAY_OFF:
1097 		if (arg < 0 || arg > UINT8_MAX * 10)
1098 			error = EINVAL;
1099 		break;
1100 	default:
1101 		error = EINVAL;
1102 	}
1103 
1104 	/* Update. */
1105 	if (error == 0) {
1106 		*(int *)((char *)sc + oidp->oid_arg2) = arg;
1107 		ps4dshock_write(sc);
1108 	}
1109 unlock:
1110 	sx_unlock(&sc->lock);
1111 
1112 	return (error);
1113 }
1114 
1115 static void
1116 ps4dshock_identify(driver_t *driver, device_t parent)
1117 {
1118 
1119 	/* Overload PS4 DualShock gamepad rudimentary report descriptor */
1120 	if (HIDBUS_LOOKUP_ID(parent, ps4dshock_devs) != NULL)
1121 		hid_set_report_descr(parent, ps4dshock_rdesc,
1122 		    sizeof(ps4dshock_rdesc));
1123 }
1124 
1125 static int
1126 ps4dshock_probe(device_t dev)
1127 {
1128 	struct ps4dshock_softc *sc = device_get_softc(dev);
1129 
1130 	hidmap_set_debug_var(&sc->hm, &HID_DEBUG_VAR);
1131 	return (
1132 	    HIDMAP_PROBE(&sc->hm, dev, ps4dshock_devs, ps4dshock_map, NULL)
1133 	);
1134 }
1135 
1136 static int
1137 ps4dsacc_probe(device_t dev)
1138 {
1139 	struct ps4dsacc_softc *sc = device_get_softc(dev);
1140 
1141 	hidmap_set_debug_var(&sc->hm, &HID_DEBUG_VAR);
1142 	return (
1143 	    HIDMAP_PROBE(&sc->hm, dev, ps4dsacc_devs, ps4dsacc_map, "Sensors")
1144 	);
1145 }
1146 
1147 static int
1148 ps4dshead_probe(device_t dev)
1149 {
1150 	struct hidmap *hm = device_get_softc(dev);
1151 
1152 	hidmap_set_debug_var(hm, &HID_DEBUG_VAR);
1153 	return (
1154 	    HIDMAP_PROBE(hm, dev, ps4dshead_devs, ps4dshead_map, "Headset")
1155 	);
1156 }
1157 
1158 static int
1159 ps4dsmtp_probe(device_t dev)
1160 {
1161 	struct ps4dshock_softc *sc = device_get_softc(dev);
1162 
1163 	hidmap_set_debug_var(&sc->hm, &HID_DEBUG_VAR);
1164 	return (
1165 	    HIDMAP_PROBE(&sc->hm, dev, ps4dsmtp_devs, ps4dsmtp_map, "Touchpad")
1166 	);
1167 }
1168 
1169 static int
1170 ps4dshock_attach(device_t dev)
1171 {
1172 	struct ps4dshock_softc *sc = device_get_softc(dev);
1173 	struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(dev);
1174 	struct sysctl_oid *tree = device_get_sysctl_tree(dev);
1175 
1176 	sc->led_state = PS4DS_LED_ON;
1177 	sc->led_color = ps4ds_leds[device_get_unit(dev) % nitems(ps4ds_leds)];
1178 	sc->led_delay_on = 500;	/* 1 Hz */
1179 	sc->led_delay_off = 500;
1180 	ps4dshock_write(sc);
1181 
1182 	sx_init(&sc->lock, "ps4dshock");
1183 
1184 	SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
1185 	    "led_state", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_ANYBODY, sc,
1186 	    PD4DSHOCK_SYSCTL_LED_STATE, ps4dshock_sysctl, "I",
1187 	    "LED state: 0 - off, 1 - on, 2 - blinking.");
1188 
1189 	SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
1190 	    "led_color_r", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_ANYBODY, sc,
1191 	    PD4DSHOCK_SYSCTL_LED_COLOR_R, ps4dshock_sysctl, "I",
1192 	    "LED color. Red component.");
1193 
1194 	SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
1195 	    "led_color_g", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_ANYBODY, sc,
1196 	    PD4DSHOCK_SYSCTL_LED_COLOR_G, ps4dshock_sysctl, "I",
1197 	    "LED color. Green component.");
1198 
1199 	SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
1200 	    "led_color_b", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_ANYBODY, sc,
1201 	    PD4DSHOCK_SYSCTL_LED_COLOR_B, ps4dshock_sysctl, "I",
1202 	    "LED color. Blue component.");
1203 
1204 	SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
1205 	    "led_delay_on", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_ANYBODY, sc,
1206 	    PD4DSHOCK_SYSCTL_LED_DELAY_ON, ps4dshock_sysctl, "I",
1207 	    "LED blink. On delay, msecs.");
1208 
1209 	SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
1210 	    "led_delay_off", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_ANYBODY, sc,
1211 	    PD4DSHOCK_SYSCTL_LED_DELAY_OFF, ps4dshock_sysctl, "I",
1212 	    "LED blink. Off delay, msecs.");
1213 
1214 	return (hidmap_attach(&sc->hm));
1215 }
1216 
1217 static int
1218 ps4dsacc_attach(device_t dev)
1219 {
1220 	struct ps4dsacc_softc *sc = device_get_softc(dev);
1221 	uint8_t buf[PS4DS_FEATURE_REPORT2_SIZE];
1222 	int error, speed_2x, range_2g;
1223 
1224 	/* Read accelerometers and gyroscopes calibration data */
1225 	error = hid_get_report(dev, buf, sizeof(buf), NULL,
1226 	    HID_FEATURE_REPORT, 0x02);
1227 	if (error)
1228 		DPRINTF("get feature report failed, error=%d "
1229 		    "(ignored)\n", error);
1230 
1231 	DPRINTFN(5, "calibration data: %*D\n", (int)sizeof(buf), buf, " ");
1232 
1233 	/*
1234 	 * Set gyroscope calibration and normalization parameters.
1235 	 * Data values will be normalized to 1/ PS4DS_GYRO_RES_PER_DEG_S
1236 	 * degree/s.
1237 	 */
1238 #define HGETW(w) ((int16_t)((w)[0] | (((uint16_t)((w)[1])) << 8)))
1239 	speed_2x = HGETW(&buf[19]) + HGETW(&buf[21]);
1240 	sc->calib_data[0].usage = HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_RX);
1241 	sc->calib_data[0].code = ABS_RX;
1242 	sc->calib_data[0].range = PS4DS_GYRO_RES_PER_DEG_S * 2048;
1243 	sc->calib_data[0].res = PS4DS_GYRO_RES_PER_DEG_S;
1244 	sc->calib_data[0].bias = HGETW(&buf[1]);
1245 	sc->calib_data[0].sens_numer = speed_2x * PS4DS_GYRO_RES_PER_DEG_S;
1246 	sc->calib_data[0].sens_denom = HGETW(&buf[7]) - HGETW(&buf[9]);
1247 	/* BT case */
1248 	/* sc->calib_data[0].sens_denom = HGETW(&buf[7]) - HGETW(&buf[13]); */
1249 
1250 	sc->calib_data[1].usage = HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_RY);
1251 	sc->calib_data[1].code = ABS_RY;
1252 	sc->calib_data[1].range = PS4DS_GYRO_RES_PER_DEG_S * 2048;
1253 	sc->calib_data[1].res = PS4DS_GYRO_RES_PER_DEG_S;
1254 	sc->calib_data[1].bias = HGETW(&buf[3]);
1255 	sc->calib_data[1].sens_numer = speed_2x * PS4DS_GYRO_RES_PER_DEG_S;
1256 	sc->calib_data[1].sens_denom = HGETW(&buf[11]) - HGETW(&buf[13]);
1257 	/* BT case */
1258 	/* sc->calib_data[1].sens_denom = HGETW(&buf[9]) - HGETW(&buf[15]); */
1259 
1260 	sc->calib_data[2].usage = HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_RZ);
1261 	sc->calib_data[2].code = ABS_RZ;
1262 	sc->calib_data[2].range = PS4DS_GYRO_RES_PER_DEG_S * 2048;
1263 	sc->calib_data[2].res = PS4DS_GYRO_RES_PER_DEG_S;
1264 	sc->calib_data[2].bias = HGETW(&buf[5]);
1265 	sc->calib_data[2].sens_numer = speed_2x * PS4DS_GYRO_RES_PER_DEG_S;
1266 	sc->calib_data[2].sens_denom = HGETW(&buf[15]) - HGETW(&buf[17]);
1267 	/* BT case */
1268 	/* sc->calib_data[2].sens_denom = HGETW(&buf[11]) - HGETW(&buf[17]); */
1269 
1270 	/*
1271 	 * Set accelerometer calibration and normalization parameters.
1272 	 * Data values will be normalized to 1 / PS4DS_ACC_RES_PER_G G.
1273 	 */
1274 	range_2g = HGETW(&buf[23]) - HGETW(&buf[25]);
1275 	sc->calib_data[3].usage = HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_X);
1276 	sc->calib_data[3].code = ABS_X;
1277 	sc->calib_data[3].range = PS4DS_ACC_RES_PER_G * 4;
1278 	sc->calib_data[3].res = PS4DS_ACC_RES_PER_G;
1279 	sc->calib_data[3].bias = HGETW(&buf[23]) - range_2g / 2;
1280 	sc->calib_data[3].sens_numer = 2 * PS4DS_ACC_RES_PER_G;
1281 	sc->calib_data[3].sens_denom = range_2g;
1282 
1283 	range_2g = HGETW(&buf[27]) - HGETW(&buf[29]);
1284 	sc->calib_data[4].usage =  HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_Y);
1285 	sc->calib_data[4].code = ABS_Y;
1286 	sc->calib_data[4].range = PS4DS_ACC_RES_PER_G * 4;
1287 	sc->calib_data[4].res = PS4DS_ACC_RES_PER_G;
1288 	sc->calib_data[4].bias = HGETW(&buf[27]) - range_2g / 2;
1289 	sc->calib_data[4].sens_numer = 2 * PS4DS_ACC_RES_PER_G;
1290 	sc->calib_data[4].sens_denom = range_2g;
1291 
1292 	range_2g = HGETW(&buf[31]) - HGETW(&buf[33]);
1293 	sc->calib_data[5].usage = HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_Z);
1294 	sc->calib_data[5].code = ABS_Z;
1295 	sc->calib_data[5].range = PS4DS_ACC_RES_PER_G * 4;
1296 	sc->calib_data[5].res = PS4DS_ACC_RES_PER_G;
1297 	sc->calib_data[5].bias = HGETW(&buf[31]) - range_2g / 2;
1298 	sc->calib_data[5].sens_numer = 2 * PS4DS_ACC_RES_PER_G;
1299 	sc->calib_data[5].sens_denom = range_2g;
1300 
1301 	return (hidmap_attach(&sc->hm));
1302 }
1303 
1304 static int
1305 ps4dshead_attach(device_t dev)
1306 {
1307 	return (hidmap_attach(device_get_softc(dev)));
1308 }
1309 
1310 static int
1311 ps4dsmtp_attach(device_t dev)
1312 {
1313 	struct ps4dsmtp_softc *sc = device_get_softc(dev);
1314 
1315 	return (hidmap_attach(&sc->hm));
1316 }
1317 
1318 static int
1319 ps4dshock_detach(device_t dev)
1320 {
1321 	struct ps4dshock_softc *sc = device_get_softc(dev);
1322 
1323 	hidmap_detach(&sc->hm);
1324 	sc->led_state = PS4DS_LED_OFF;
1325 	ps4dshock_write(sc);
1326 	sx_destroy(&sc->lock);
1327 
1328 	return (0);
1329 }
1330 
1331 static int
1332 ps4dsacc_detach(device_t dev)
1333 {
1334 	struct ps4dsacc_softc *sc = device_get_softc(dev);
1335 
1336 	return (hidmap_detach(&sc->hm));
1337 }
1338 
1339 static int
1340 ps4dshead_detach(device_t dev)
1341 {
1342 	return (hidmap_detach(device_get_softc(dev)));
1343 }
1344 
1345 static int
1346 ps4dsmtp_detach(device_t dev)
1347 {
1348 	struct ps4dsmtp_softc *sc = device_get_softc(dev);
1349 
1350 	return (hidmap_detach(&sc->hm));
1351 }
1352 
1353 static devclass_t ps4dshock_devclass;
1354 static devclass_t ps4dsacc_devclass;
1355 static devclass_t ps4dshead_devclass;
1356 static devclass_t ps4dsmtp_devclass;
1357 
1358 static device_method_t ps4dshock_methods[] = {
1359 	DEVMETHOD(device_identify,	ps4dshock_identify),
1360 	DEVMETHOD(device_probe,		ps4dshock_probe),
1361 	DEVMETHOD(device_attach,	ps4dshock_attach),
1362 	DEVMETHOD(device_detach,	ps4dshock_detach),
1363 
1364 	DEVMETHOD_END
1365 };
1366 static device_method_t ps4dsacc_methods[] = {
1367 	DEVMETHOD(device_probe,		ps4dsacc_probe),
1368 	DEVMETHOD(device_attach,	ps4dsacc_attach),
1369 	DEVMETHOD(device_detach,	ps4dsacc_detach),
1370 
1371 	DEVMETHOD_END
1372 };
1373 static device_method_t ps4dshead_methods[] = {
1374 	DEVMETHOD(device_probe,		ps4dshead_probe),
1375 	DEVMETHOD(device_attach,	ps4dshead_attach),
1376 	DEVMETHOD(device_detach,	ps4dshead_detach),
1377 
1378 	DEVMETHOD_END
1379 };
1380 static device_method_t ps4dsmtp_methods[] = {
1381 	DEVMETHOD(device_probe,		ps4dsmtp_probe),
1382 	DEVMETHOD(device_attach,	ps4dsmtp_attach),
1383 	DEVMETHOD(device_detach,	ps4dsmtp_detach),
1384 
1385 	DEVMETHOD_END
1386 };
1387 
1388 DEFINE_CLASS_0(ps4dsacc, ps4dsacc_driver, ps4dsacc_methods,
1389     sizeof(struct ps4dsacc_softc));
1390 DRIVER_MODULE(ps4dsacc, hidbus, ps4dsacc_driver, ps4dsacc_devclass, NULL, 0);
1391 DEFINE_CLASS_0(ps4dshead, ps4dshead_driver, ps4dshead_methods,
1392     sizeof(struct hidmap));
1393 DRIVER_MODULE(ps4dshead, hidbus, ps4dshead_driver, ps4dshead_devclass, NULL, 0);
1394 DEFINE_CLASS_0(ps4dsmtp, ps4dsmtp_driver, ps4dsmtp_methods,
1395     sizeof(struct ps4dsmtp_softc));
1396 DRIVER_MODULE(ps4dsmtp, hidbus, ps4dsmtp_driver, ps4dsmtp_devclass, NULL, 0);
1397 DEFINE_CLASS_0(ps4dshock, ps4dshock_driver, ps4dshock_methods,
1398     sizeof(struct ps4dshock_softc));
1399 DRIVER_MODULE(ps4dshock, hidbus, ps4dshock_driver, ps4dshock_devclass, NULL, 0);
1400 
1401 MODULE_DEPEND(ps4dshock, hid, 1, 1, 1);
1402 MODULE_DEPEND(ps4dshock, hidbus, 1, 1, 1);
1403 MODULE_DEPEND(ps4dshock, hidmap, 1, 1, 1);
1404 MODULE_DEPEND(ps4dshock, evdev, 1, 1, 1);
1405 MODULE_VERSION(ps4dshock, 1);
1406 HID_PNP_INFO(ps4dshock_devs);
1407