xref: /freebsd/sys/dev/hid/ps4dshock.c (revision 16079c7233be8bd6c88e3421a70c7ca87cfea370)
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 		break;
812 
813 	default:
814 		break;
815 	}
816 
817 	return (0);
818 }
819 
820 static int
821 ps4dshock_final_cb(HIDMAP_CB_ARGS)
822 {
823 	struct evdev_dev *evdev = HIDMAP_CB_GET_EVDEV();
824 
825 	if (HIDMAP_CB_GET_STATE() == HIDMAP_CB_IS_ATTACHING)
826 		evdev_support_prop(evdev, INPUT_PROP_DIRECT);
827 
828 	/* Do not execute callback at interrupt handler and detach */
829 	return (ENOSYS);
830 }
831 
832 static int
833 ps4dsacc_data_cb(HIDMAP_CB_ARGS)
834 {
835 	struct evdev_dev *evdev = HIDMAP_CB_GET_EVDEV();
836 	struct ps4dsacc_softc *sc = HIDMAP_CB_GET_SOFTC();
837 	struct ps4ds_calib_data *calib;
838 	u_int i;
839 
840 	switch (HIDMAP_CB_GET_STATE()) {
841 	case HIDMAP_CB_IS_ATTACHING:
842 		for (i = 0; i < nitems(sc->calib_data); i++) {
843 			if (sc->calib_data[i].usage == ctx.hi->usage) {
844 				evdev_support_abs(evdev,
845 				     sc->calib_data[i].code,
846 				    -sc->calib_data[i].range,
847 				     sc->calib_data[i].range, 16, 0,
848 				     sc->calib_data[i].res);
849 				HIDMAP_CB_UDATA = &sc->calib_data[i];
850 				break;
851 			}
852 		}
853 		break;
854 
855 	case HIDMAP_CB_IS_RUNNING:
856 		calib = HIDMAP_CB_UDATA;
857 		evdev_push_abs(evdev, calib->code,
858 		    ((int64_t)ctx.data - calib->bias) * calib->sens_numer /
859 		    calib->sens_denom);
860 		break;
861 
862 	default:
863 		break;
864 	}
865 
866 	return (0);
867 }
868 
869 static int
870 ps4dsacc_tstamp_cb(HIDMAP_CB_ARGS)
871 {
872 	struct evdev_dev *evdev = HIDMAP_CB_GET_EVDEV();
873 	struct ps4dsacc_softc *sc = HIDMAP_CB_GET_SOFTC();
874 	uint16_t tstamp;
875 
876 	switch (HIDMAP_CB_GET_STATE()) {
877 	case HIDMAP_CB_IS_ATTACHING:
878 		evdev_support_event(evdev, EV_MSC);
879 		evdev_support_msc(evdev, MSC_TIMESTAMP);
880 		break;
881 
882 	case HIDMAP_CB_IS_RUNNING:
883 		/* Convert timestamp (in 5.33us unit) to timestamp_us */
884 		tstamp = (uint16_t)ctx.data;
885 		sc->ev_tstamp += (uint16_t)(tstamp - sc->hw_tstamp) * 16 / 3;
886 		sc->hw_tstamp = tstamp;
887 		evdev_push_msc(evdev, MSC_TIMESTAMP, sc->ev_tstamp);
888 		break;
889 
890 	default:
891 		break;
892 	}
893 
894 	return (0);
895 }
896 
897 static int
898 ps4dsacc_final_cb(HIDMAP_CB_ARGS)
899 {
900 	struct evdev_dev *evdev = HIDMAP_CB_GET_EVDEV();
901 
902 	if (HIDMAP_CB_GET_STATE() == HIDMAP_CB_IS_ATTACHING) {
903 		evdev_support_event(evdev, EV_ABS);
904 		evdev_support_prop(evdev, INPUT_PROP_ACCELEROMETER);
905 	}
906         /* Do not execute callback at interrupt handler and detach */
907         return (ENOSYS);
908 }
909 
910 static int
911 ps4dsmtp_npackets_cb(HIDMAP_CB_ARGS)
912 {
913 	struct ps4dsmtp_softc *sc = HIDMAP_CB_GET_SOFTC();
914 
915 	if (HIDMAP_CB_GET_STATE() == HIDMAP_CB_IS_RUNNING) {
916 		sc->npackets = MIN(PS4DS_MAX_TOUCHPAD_PACKETS,(u_int)ctx.data);
917 		/* Reset pointer here as it is first usage in touchpad TLC */
918 		sc->data_ptr = sc->data;
919 	}
920 
921 	return (0);
922 }
923 
924 static int
925 ps4dsmtp_data_cb(HIDMAP_CB_ARGS)
926 {
927 	struct ps4dsmtp_softc *sc = HIDMAP_CB_GET_SOFTC();
928 
929 	if (HIDMAP_CB_GET_STATE() == HIDMAP_CB_IS_RUNNING) {
930 		*sc->data_ptr = ctx.data;
931 		++sc->data_ptr;
932 	}
933 
934 	return (0);
935 }
936 
937 static void
938 ps4dsmtp_push_packet(struct ps4dsmtp_softc *sc, struct evdev_dev *evdev,
939     int32_t *data)
940 {
941 	uint8_t hw_tstamp, delta;
942 	bool touch;
943 
944 	evdev_push_abs(evdev, ABS_MT_SLOT, 0);
945 	if (data[PS4DS_TIP1] == 0) {
946 		evdev_push_abs(evdev, ABS_MT_TRACKING_ID, data[PS4DS_CID1]);
947 		evdev_push_abs(evdev, ABS_MT_POSITION_X, data[PS4DS_X1]);
948 		evdev_push_abs(evdev, ABS_MT_POSITION_Y, data[PS4DS_Y1]);
949 	} else
950 		evdev_push_abs(evdev, ABS_MT_TRACKING_ID, -1);
951 	evdev_push_abs(evdev, ABS_MT_SLOT, 1);
952 	if (data[PS4DS_TIP2] == 0) {
953 		evdev_push_abs(evdev, ABS_MT_TRACKING_ID, data[PS4DS_CID2]);
954 		evdev_push_abs(evdev, ABS_MT_POSITION_X, data[PS4DS_X2]);
955 		evdev_push_abs(evdev, ABS_MT_POSITION_Y, data[PS4DS_Y2]);
956 	} else
957 		evdev_push_abs(evdev, ABS_MT_TRACKING_ID, -1);
958 
959 	if (sc->do_tstamps) {
960 		/*
961 		 * Export hardware timestamps in libinput-friendly way.
962 		 * Make timestamp counter 32-bit, scale up hardware
963 		 * timestamps to be on per 1usec basis and reset
964 		 * counter at the start of each touch.
965 		 */
966 		hw_tstamp = (uint8_t)data[PS4DS_TSTAMP];
967 		delta = hw_tstamp - sc->hw_tstamp;
968 		sc->hw_tstamp = hw_tstamp;
969 		touch = data[PS4DS_TIP1] == 0 || data[PS4DS_TIP2] == 0;
970 		/* Hardware timestamp counter ticks in 682 usec interval. */
971 		if ((touch || sc->touch) && delta != 0) {
972 			if (sc->touch)
973 				sc->ev_tstamp += delta * 682;
974 			evdev_push_msc(evdev, MSC_TIMESTAMP, sc->ev_tstamp);
975 		}
976 		if (!touch)
977 			sc->ev_tstamp = 0;
978 		sc->touch = touch;
979 	}
980 }
981 
982 static int
983 ps4dsmtp_final_cb(HIDMAP_CB_ARGS)
984 {
985 	struct ps4dsmtp_softc *sc = HIDMAP_CB_GET_SOFTC();
986 	struct evdev_dev *evdev = HIDMAP_CB_GET_EVDEV();
987 	int32_t *data;
988 
989 	switch (HIDMAP_CB_GET_STATE()) {
990 	case HIDMAP_CB_IS_ATTACHING:
991 		if (hid_test_quirk(hid_get_device_info(sc->hm.dev),
992 		    HQ_MT_TIMESTAMP))
993 			sc->do_tstamps = true;
994 		/*
995 		 * Dualshock 4 touchpad TLC contained in fixed report
996 		 * descriptor is almost compatible with MS precission touchpad
997 		 * specs and hmt(4) driver. But... for some reasons "Click"
998 		 * button location was grouped with other GamePad buttons by
999 		 * touchpad designers so it belongs to GamePad TLC. Fix it with
1000 		 * direct reading of "Click" button value from interrupt frame.
1001 		 */
1002 		sc->btn_loc = (struct hid_location) { 1, 0, 49 };
1003 		evdev_support_event(evdev, EV_SYN);
1004 		evdev_support_event(evdev, EV_KEY);
1005 		evdev_support_event(evdev, EV_ABS);
1006 		if (sc->do_tstamps) {
1007 			evdev_support_event(evdev, EV_MSC);
1008 			evdev_support_msc(evdev, MSC_TIMESTAMP);
1009 		}
1010 		evdev_support_key(evdev, BTN_LEFT);
1011 		evdev_support_abs(evdev, ABS_MT_SLOT, 0, 1, 0, 0, 0);
1012 		evdev_support_abs(evdev, ABS_MT_TRACKING_ID, -1, 127, 0, 0, 0);
1013 		evdev_support_abs(evdev, ABS_MT_POSITION_X, 0, 1920, 0, 0, 30);
1014 		evdev_support_abs(evdev, ABS_MT_POSITION_Y, 0, 942, 0, 0, 49);
1015 		evdev_support_prop(evdev, INPUT_PROP_POINTER);
1016 		evdev_support_prop(evdev, INPUT_PROP_BUTTONPAD);
1017 		evdev_set_flag(evdev, EVDEV_FLAG_MT_STCOMPAT);
1018 		break;
1019 
1020 	case HIDMAP_CB_IS_RUNNING:
1021 		/* Only packets with ReportID=1 are accepted */
1022 		if (HIDMAP_CB_GET_RID() != 1)
1023 			return (ENOTSUP);
1024 		evdev_push_key(evdev, BTN_LEFT,
1025 		    HIDMAP_CB_GET_UDATA(&sc->btn_loc));
1026 		for (data = sc->data;
1027 		     data < sc->data + PS4DS_NTPUSAGES * sc->npackets;
1028 		     data += PS4DS_NTPUSAGES) {
1029 			ps4dsmtp_push_packet(sc, evdev, data);
1030 			evdev_sync(evdev);
1031 		}
1032 		break;
1033 
1034 	default:
1035 		break;
1036 	}
1037 
1038 	/* Do execute callback at interrupt handler and detach */
1039 	return (0);
1040 }
1041 
1042 static int
1043 ps4dshock_write(struct ps4dshock_softc *sc)
1044 {
1045 	hid_size_t osize = sc->is_bluetooth ?
1046 	    PS4DS_OUTPUT_REPORT11_SIZE : PS4DS_OUTPUT_REPORT5_SIZE;
1047 	uint8_t buf[osize];
1048 	int offset;
1049 	bool led_on, led_blinks;
1050 
1051 	memset(buf, 0, osize);
1052 	buf[0] = sc->is_bluetooth ? 0x11 : 0x05;
1053 	offset = sc->is_bluetooth ? 3 : 1;
1054 	led_on = sc->led_state != PS4DS_LED_OFF;
1055 	led_blinks = sc->led_state == PS4DS_LED_BLINKING;
1056 	*(struct ps4ds_out5 *)(buf + offset) = (struct ps4ds_out5) {
1057 		.features = 0x07, /* blink + LEDs + motor */
1058 		.rumble_right = sc->rumble_right,
1059 		.rumble_left = sc->rumble_left,
1060 		.led_color_r = led_on ? sc->led_color.r : 0,
1061 		.led_color_g = led_on ? sc->led_color.g : 0,
1062 		.led_color_b = led_on ? sc->led_color.b : 0,
1063 		/* convert milliseconds to centiseconds */
1064 		.led_delay_on = led_blinks ? sc->led_delay_on / 10 : 0,
1065 		.led_delay_off = led_blinks ? sc->led_delay_off / 10 : 0,
1066 	};
1067 
1068 	return (hid_write(sc->hm.dev, buf, osize));
1069 }
1070 
1071 /* Synaptics Touchpad */
1072 static int
1073 ps4dshock_sysctl(SYSCTL_HANDLER_ARGS)
1074 {
1075 	struct ps4dshock_softc *sc;
1076 	int error, arg;
1077 
1078 	if (oidp->oid_arg1 == NULL || oidp->oid_arg2 < 0 ||
1079 	    oidp->oid_arg2 > PD4DSHOCK_SYSCTL_LAST)
1080 		return (EINVAL);
1081 
1082 	sc = oidp->oid_arg1;
1083 	sx_xlock(&sc->lock);
1084 
1085 	/* Read the current value. */
1086 	arg = *(int *)((char *)sc + oidp->oid_arg2);
1087 	error = sysctl_handle_int(oidp, &arg, 0, req);
1088 
1089 	/* Sanity check. */
1090 	if (error || !req->newptr)
1091 		goto unlock;
1092 
1093 	/*
1094 	 * Check that the new value is in the concerned node's range
1095 	 * of values.
1096 	 */
1097 	switch (oidp->oid_arg2) {
1098 	case PD4DSHOCK_SYSCTL_LED_STATE:
1099 		if (arg < 0 || arg >= PD4DS_LED_CNT)
1100 			error = EINVAL;
1101 		break;
1102 	case PD4DSHOCK_SYSCTL_LED_COLOR_R:
1103 	case PD4DSHOCK_SYSCTL_LED_COLOR_G:
1104 	case PD4DSHOCK_SYSCTL_LED_COLOR_B:
1105 		if (arg < 0 || arg > UINT8_MAX)
1106 			error = EINVAL;
1107 		break;
1108 	case PD4DSHOCK_SYSCTL_LED_DELAY_ON:
1109 	case PD4DSHOCK_SYSCTL_LED_DELAY_OFF:
1110 		if (arg < 0 || arg > UINT8_MAX * 10)
1111 			error = EINVAL;
1112 		break;
1113 	default:
1114 		error = EINVAL;
1115 	}
1116 
1117 	/* Update. */
1118 	if (error == 0) {
1119 		*(int *)((char *)sc + oidp->oid_arg2) = arg;
1120 		ps4dshock_write(sc);
1121 	}
1122 unlock:
1123 	sx_unlock(&sc->lock);
1124 
1125 	return (error);
1126 }
1127 
1128 static void
1129 ps4dshock_identify(driver_t *driver, device_t parent)
1130 {
1131 
1132 	/* Overload PS4 DualShock gamepad rudimentary report descriptor */
1133 	if (HIDBUS_LOOKUP_ID(parent, ps4dshock_devs) != NULL)
1134 		hid_set_report_descr(parent, ps4dshock_rdesc,
1135 		    sizeof(ps4dshock_rdesc));
1136 }
1137 
1138 static int
1139 ps4dshock_probe(device_t dev)
1140 {
1141 	struct ps4dshock_softc *sc = device_get_softc(dev);
1142 
1143 	hidmap_set_debug_var(&sc->hm, &HID_DEBUG_VAR);
1144 	return (
1145 	    HIDMAP_PROBE(&sc->hm, dev, ps4dshock_devs, ps4dshock_map, NULL)
1146 	);
1147 }
1148 
1149 static int
1150 ps4dsacc_probe(device_t dev)
1151 {
1152 	struct ps4dsacc_softc *sc = device_get_softc(dev);
1153 
1154 	hidmap_set_debug_var(&sc->hm, &HID_DEBUG_VAR);
1155 	return (
1156 	    HIDMAP_PROBE(&sc->hm, dev, ps4dsacc_devs, ps4dsacc_map, "Sensors")
1157 	);
1158 }
1159 
1160 static int
1161 ps4dshead_probe(device_t dev)
1162 {
1163 	struct hidmap *hm = device_get_softc(dev);
1164 
1165 	hidmap_set_debug_var(hm, &HID_DEBUG_VAR);
1166 	return (
1167 	    HIDMAP_PROBE(hm, dev, ps4dshead_devs, ps4dshead_map, "Headset")
1168 	);
1169 }
1170 
1171 static int
1172 ps4dsmtp_probe(device_t dev)
1173 {
1174 	struct ps4dshock_softc *sc = device_get_softc(dev);
1175 
1176 	hidmap_set_debug_var(&sc->hm, &HID_DEBUG_VAR);
1177 	return (
1178 	    HIDMAP_PROBE(&sc->hm, dev, ps4dsmtp_devs, ps4dsmtp_map, "Touchpad")
1179 	);
1180 }
1181 
1182 static int
1183 ps4dshock_attach(device_t dev)
1184 {
1185 	struct ps4dshock_softc *sc = device_get_softc(dev);
1186 	struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(dev);
1187 	struct sysctl_oid *tree = device_get_sysctl_tree(dev);
1188 
1189 	sc->led_state = PS4DS_LED_ON;
1190 	sc->led_color = ps4ds_leds[device_get_unit(dev) % nitems(ps4ds_leds)];
1191 	sc->led_delay_on = 500;	/* 1 Hz */
1192 	sc->led_delay_off = 500;
1193 	ps4dshock_write(sc);
1194 
1195 	sx_init(&sc->lock, "ps4dshock");
1196 
1197 	SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
1198 	    "led_state", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_ANYBODY, sc,
1199 	    PD4DSHOCK_SYSCTL_LED_STATE, ps4dshock_sysctl, "I",
1200 	    "LED state: 0 - off, 1 - on, 2 - blinking.");
1201 
1202 	SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
1203 	    "led_color_r", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_ANYBODY, sc,
1204 	    PD4DSHOCK_SYSCTL_LED_COLOR_R, ps4dshock_sysctl, "I",
1205 	    "LED color. Red component.");
1206 
1207 	SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
1208 	    "led_color_g", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_ANYBODY, sc,
1209 	    PD4DSHOCK_SYSCTL_LED_COLOR_G, ps4dshock_sysctl, "I",
1210 	    "LED color. Green component.");
1211 
1212 	SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
1213 	    "led_color_b", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_ANYBODY, sc,
1214 	    PD4DSHOCK_SYSCTL_LED_COLOR_B, ps4dshock_sysctl, "I",
1215 	    "LED color. Blue component.");
1216 
1217 	SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
1218 	    "led_delay_on", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_ANYBODY, sc,
1219 	    PD4DSHOCK_SYSCTL_LED_DELAY_ON, ps4dshock_sysctl, "I",
1220 	    "LED blink. On delay, msecs.");
1221 
1222 	SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
1223 	    "led_delay_off", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_ANYBODY, sc,
1224 	    PD4DSHOCK_SYSCTL_LED_DELAY_OFF, ps4dshock_sysctl, "I",
1225 	    "LED blink. Off delay, msecs.");
1226 
1227 	return (hidmap_attach(&sc->hm));
1228 }
1229 
1230 static int
1231 ps4dsacc_attach(device_t dev)
1232 {
1233 	struct ps4dsacc_softc *sc = device_get_softc(dev);
1234 	uint8_t buf[PS4DS_FEATURE_REPORT2_SIZE];
1235 	int error, speed_2x, range_2g;
1236 
1237 	/* Read accelerometers and gyroscopes calibration data */
1238 	error = hid_get_report(dev, buf, sizeof(buf), NULL,
1239 	    HID_FEATURE_REPORT, 0x02);
1240 	if (error)
1241 		DPRINTF("get feature report failed, error=%d "
1242 		    "(ignored)\n", error);
1243 
1244 	DPRINTFN(5, "calibration data: %*D\n", (int)sizeof(buf), buf, " ");
1245 
1246 	/*
1247 	 * Set gyroscope calibration and normalization parameters.
1248 	 * Data values will be normalized to 1/ PS4DS_GYRO_RES_PER_DEG_S
1249 	 * degree/s.
1250 	 */
1251 #define HGETW(w) ((int16_t)((w)[0] | (((uint16_t)((w)[1])) << 8)))
1252 	speed_2x = HGETW(&buf[19]) + HGETW(&buf[21]);
1253 	sc->calib_data[0].usage = HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_RX);
1254 	sc->calib_data[0].code = ABS_RX;
1255 	sc->calib_data[0].range = PS4DS_GYRO_RES_PER_DEG_S * 2048;
1256 	sc->calib_data[0].res = PS4DS_GYRO_RES_PER_DEG_S;
1257 	sc->calib_data[0].bias = HGETW(&buf[1]);
1258 	sc->calib_data[0].sens_numer = speed_2x * PS4DS_GYRO_RES_PER_DEG_S;
1259 	sc->calib_data[0].sens_denom = HGETW(&buf[7]) - HGETW(&buf[9]);
1260 	/* BT case */
1261 	/* sc->calib_data[0].sens_denom = HGETW(&buf[7]) - HGETW(&buf[13]); */
1262 
1263 	sc->calib_data[1].usage = HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_RY);
1264 	sc->calib_data[1].code = ABS_RY;
1265 	sc->calib_data[1].range = PS4DS_GYRO_RES_PER_DEG_S * 2048;
1266 	sc->calib_data[1].res = PS4DS_GYRO_RES_PER_DEG_S;
1267 	sc->calib_data[1].bias = HGETW(&buf[3]);
1268 	sc->calib_data[1].sens_numer = speed_2x * PS4DS_GYRO_RES_PER_DEG_S;
1269 	sc->calib_data[1].sens_denom = HGETW(&buf[11]) - HGETW(&buf[13]);
1270 	/* BT case */
1271 	/* sc->calib_data[1].sens_denom = HGETW(&buf[9]) - HGETW(&buf[15]); */
1272 
1273 	sc->calib_data[2].usage = HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_RZ);
1274 	sc->calib_data[2].code = ABS_RZ;
1275 	sc->calib_data[2].range = PS4DS_GYRO_RES_PER_DEG_S * 2048;
1276 	sc->calib_data[2].res = PS4DS_GYRO_RES_PER_DEG_S;
1277 	sc->calib_data[2].bias = HGETW(&buf[5]);
1278 	sc->calib_data[2].sens_numer = speed_2x * PS4DS_GYRO_RES_PER_DEG_S;
1279 	sc->calib_data[2].sens_denom = HGETW(&buf[15]) - HGETW(&buf[17]);
1280 	/* BT case */
1281 	/* sc->calib_data[2].sens_denom = HGETW(&buf[11]) - HGETW(&buf[17]); */
1282 
1283 	/*
1284 	 * Set accelerometer calibration and normalization parameters.
1285 	 * Data values will be normalized to 1 / PS4DS_ACC_RES_PER_G G.
1286 	 */
1287 	range_2g = HGETW(&buf[23]) - HGETW(&buf[25]);
1288 	sc->calib_data[3].usage = HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_X);
1289 	sc->calib_data[3].code = ABS_X;
1290 	sc->calib_data[3].range = PS4DS_ACC_RES_PER_G * 4;
1291 	sc->calib_data[3].res = PS4DS_ACC_RES_PER_G;
1292 	sc->calib_data[3].bias = HGETW(&buf[23]) - range_2g / 2;
1293 	sc->calib_data[3].sens_numer = 2 * PS4DS_ACC_RES_PER_G;
1294 	sc->calib_data[3].sens_denom = range_2g;
1295 
1296 	range_2g = HGETW(&buf[27]) - HGETW(&buf[29]);
1297 	sc->calib_data[4].usage =  HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_Y);
1298 	sc->calib_data[4].code = ABS_Y;
1299 	sc->calib_data[4].range = PS4DS_ACC_RES_PER_G * 4;
1300 	sc->calib_data[4].res = PS4DS_ACC_RES_PER_G;
1301 	sc->calib_data[4].bias = HGETW(&buf[27]) - range_2g / 2;
1302 	sc->calib_data[4].sens_numer = 2 * PS4DS_ACC_RES_PER_G;
1303 	sc->calib_data[4].sens_denom = range_2g;
1304 
1305 	range_2g = HGETW(&buf[31]) - HGETW(&buf[33]);
1306 	sc->calib_data[5].usage = HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_Z);
1307 	sc->calib_data[5].code = ABS_Z;
1308 	sc->calib_data[5].range = PS4DS_ACC_RES_PER_G * 4;
1309 	sc->calib_data[5].res = PS4DS_ACC_RES_PER_G;
1310 	sc->calib_data[5].bias = HGETW(&buf[31]) - range_2g / 2;
1311 	sc->calib_data[5].sens_numer = 2 * PS4DS_ACC_RES_PER_G;
1312 	sc->calib_data[5].sens_denom = range_2g;
1313 
1314 	return (hidmap_attach(&sc->hm));
1315 }
1316 
1317 static int
1318 ps4dshead_attach(device_t dev)
1319 {
1320 	return (hidmap_attach(device_get_softc(dev)));
1321 }
1322 
1323 static int
1324 ps4dsmtp_attach(device_t dev)
1325 {
1326 	struct ps4dsmtp_softc *sc = device_get_softc(dev);
1327 
1328 	return (hidmap_attach(&sc->hm));
1329 }
1330 
1331 static int
1332 ps4dshock_detach(device_t dev)
1333 {
1334 	struct ps4dshock_softc *sc = device_get_softc(dev);
1335 
1336 	hidmap_detach(&sc->hm);
1337 	sc->led_state = PS4DS_LED_OFF;
1338 	ps4dshock_write(sc);
1339 	sx_destroy(&sc->lock);
1340 
1341 	return (0);
1342 }
1343 
1344 static int
1345 ps4dsacc_detach(device_t dev)
1346 {
1347 	struct ps4dsacc_softc *sc = device_get_softc(dev);
1348 
1349 	return (hidmap_detach(&sc->hm));
1350 }
1351 
1352 static int
1353 ps4dshead_detach(device_t dev)
1354 {
1355 	return (hidmap_detach(device_get_softc(dev)));
1356 }
1357 
1358 static int
1359 ps4dsmtp_detach(device_t dev)
1360 {
1361 	struct ps4dsmtp_softc *sc = device_get_softc(dev);
1362 
1363 	return (hidmap_detach(&sc->hm));
1364 }
1365 
1366 static devclass_t ps4dshock_devclass;
1367 static devclass_t ps4dsacc_devclass;
1368 static devclass_t ps4dshead_devclass;
1369 static devclass_t ps4dsmtp_devclass;
1370 
1371 static device_method_t ps4dshock_methods[] = {
1372 	DEVMETHOD(device_identify,	ps4dshock_identify),
1373 	DEVMETHOD(device_probe,		ps4dshock_probe),
1374 	DEVMETHOD(device_attach,	ps4dshock_attach),
1375 	DEVMETHOD(device_detach,	ps4dshock_detach),
1376 
1377 	DEVMETHOD_END
1378 };
1379 static device_method_t ps4dsacc_methods[] = {
1380 	DEVMETHOD(device_probe,		ps4dsacc_probe),
1381 	DEVMETHOD(device_attach,	ps4dsacc_attach),
1382 	DEVMETHOD(device_detach,	ps4dsacc_detach),
1383 
1384 	DEVMETHOD_END
1385 };
1386 static device_method_t ps4dshead_methods[] = {
1387 	DEVMETHOD(device_probe,		ps4dshead_probe),
1388 	DEVMETHOD(device_attach,	ps4dshead_attach),
1389 	DEVMETHOD(device_detach,	ps4dshead_detach),
1390 
1391 	DEVMETHOD_END
1392 };
1393 static device_method_t ps4dsmtp_methods[] = {
1394 	DEVMETHOD(device_probe,		ps4dsmtp_probe),
1395 	DEVMETHOD(device_attach,	ps4dsmtp_attach),
1396 	DEVMETHOD(device_detach,	ps4dsmtp_detach),
1397 
1398 	DEVMETHOD_END
1399 };
1400 
1401 DEFINE_CLASS_0(ps4dsacc, ps4dsacc_driver, ps4dsacc_methods,
1402     sizeof(struct ps4dsacc_softc));
1403 DRIVER_MODULE(ps4dsacc, hidbus, ps4dsacc_driver, ps4dsacc_devclass, NULL, 0);
1404 DEFINE_CLASS_0(ps4dshead, ps4dshead_driver, ps4dshead_methods,
1405     sizeof(struct hidmap));
1406 DRIVER_MODULE(ps4dshead, hidbus, ps4dshead_driver, ps4dshead_devclass, NULL, 0);
1407 DEFINE_CLASS_0(ps4dsmtp, ps4dsmtp_driver, ps4dsmtp_methods,
1408     sizeof(struct ps4dsmtp_softc));
1409 DRIVER_MODULE(ps4dsmtp, hidbus, ps4dsmtp_driver, ps4dsmtp_devclass, NULL, 0);
1410 DEFINE_CLASS_0(ps4dshock, ps4dshock_driver, ps4dshock_methods,
1411     sizeof(struct ps4dshock_softc));
1412 DRIVER_MODULE(ps4dshock, hidbus, ps4dshock_driver, ps4dshock_devclass, NULL, 0);
1413 
1414 MODULE_DEPEND(ps4dshock, hid, 1, 1, 1);
1415 MODULE_DEPEND(ps4dshock, hidbus, 1, 1, 1);
1416 MODULE_DEPEND(ps4dshock, hidmap, 1, 1, 1);
1417 MODULE_DEPEND(ps4dshock, evdev, 1, 1, 1);
1418 MODULE_VERSION(ps4dshock, 1);
1419 HID_PNP_INFO(ps4dshock_devs);
1420