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