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