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