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