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