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