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