1bd28ce00SJiri Slaby /* 2077147a3SFrank Praznik * HID driver for Sony / PS2 / PS3 / PS4 BD devices. 3bd28ce00SJiri Slaby * 4bd28ce00SJiri Slaby * Copyright (c) 1999 Andreas Gal 5bd28ce00SJiri Slaby * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz> 6bd28ce00SJiri Slaby * Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc 7bd28ce00SJiri Slaby * Copyright (c) 2008 Jiri Slaby 8078328daSJiri Kosina * Copyright (c) 2012 David Dillow <dave@thedillows.org> 9078328daSJiri Kosina * Copyright (c) 2006-2013 Jiri Kosina 10f04d5140SColin Leitner * Copyright (c) 2013 Colin Leitner <colin.leitner@gmail.com> 11c4425c8fSFrank Praznik * Copyright (c) 2014-2016 Frank Praznik <frank.praznik@gmail.com> 12bd28ce00SJiri Slaby */ 13bd28ce00SJiri Slaby 14bd28ce00SJiri Slaby /* 15bd28ce00SJiri Slaby * This program is free software; you can redistribute it and/or modify it 16bd28ce00SJiri Slaby * under the terms of the GNU General Public License as published by the Free 17bd28ce00SJiri Slaby * Software Foundation; either version 2 of the License, or (at your option) 18bd28ce00SJiri Slaby * any later version. 19bd28ce00SJiri Slaby */ 20bd28ce00SJiri Slaby 21ad142b9eSFrank Praznik /* 22ad142b9eSFrank Praznik * NOTE: in order for the Sony PS3 BD Remote Control to be found by 23078328daSJiri Kosina * a Bluetooth host, the key combination Start+Enter has to be kept pressed 24078328daSJiri Kosina * for about 7 seconds with the Bluetooth Host Controller in discovering mode. 25078328daSJiri Kosina * 26078328daSJiri Kosina * There will be no PIN request from the device. 27078328daSJiri Kosina */ 28078328daSJiri Kosina 29bd28ce00SJiri Slaby #include <linux/device.h> 30bd28ce00SJiri Slaby #include <linux/hid.h> 31bd28ce00SJiri Slaby #include <linux/module.h> 325a0e3ad6STejun Heo #include <linux/slab.h> 3340e32ee6SJiri Kosina #include <linux/leds.h> 34d902f472SFrank Praznik #include <linux/power_supply.h> 35d902f472SFrank Praznik #include <linux/spinlock.h> 36d2d782fcSFrank Praznik #include <linux/list.h> 378025087aSFrank Praznik #include <linux/idr.h> 38e5606230SFrank Praznik #include <linux/input/mt.h> 3949b9ca6cSRoderick Colenbrander #include <linux/crc32.h> 4049b9ca6cSRoderick Colenbrander #include <asm/unaligned.h> 41bd28ce00SJiri Slaby 42bd28ce00SJiri Slaby #include "hid-ids.h" 43bd28ce00SJiri Slaby 44f1c458caSSven Eckelmann #define VAIO_RDESC_CONSTANT BIT(0) 45f1c458caSSven Eckelmann #define SIXAXIS_CONTROLLER_USB BIT(1) 46f1c458caSSven Eckelmann #define SIXAXIS_CONTROLLER_BT BIT(2) 47f1c458caSSven Eckelmann #define BUZZ_CONTROLLER BIT(3) 48f1c458caSSven Eckelmann #define PS3REMOTE BIT(4) 498ab1676bSFrank Praznik #define DUALSHOCK4_CONTROLLER_USB BIT(5) 508ab1676bSFrank Praznik #define DUALSHOCK4_CONTROLLER_BT BIT(6) 5135f436c3SRoderick Colenbrander #define DUALSHOCK4_DONGLE BIT(7) 5235f436c3SRoderick Colenbrander #define MOTION_CONTROLLER_USB BIT(8) 5335f436c3SRoderick Colenbrander #define MOTION_CONTROLLER_BT BIT(9) 5435f436c3SRoderick Colenbrander #define NAVIGATION_CONTROLLER_USB BIT(10) 5535f436c3SRoderick Colenbrander #define NAVIGATION_CONTROLLER_BT BIT(11) 5635f436c3SRoderick Colenbrander #define SINO_LITE_CONTROLLER BIT(12) 5735f436c3SRoderick Colenbrander #define FUTUREMAX_DANCE_MAT BIT(13) 58cc6e0bbbSJiri Kosina 59fee4e2d5SFrank Praznik #define SIXAXIS_CONTROLLER (SIXAXIS_CONTROLLER_USB | SIXAXIS_CONTROLLER_BT) 60b3bca326SSimon Wood #define MOTION_CONTROLLER (MOTION_CONTROLLER_USB | MOTION_CONTROLLER_BT) 614545ee0aSSimon Wood #define NAVIGATION_CONTROLLER (NAVIGATION_CONTROLLER_USB |\ 624545ee0aSSimon Wood NAVIGATION_CONTROLLER_BT) 6368330d83SFrank Praznik #define DUALSHOCK4_CONTROLLER (DUALSHOCK4_CONTROLLER_USB |\ 6435f436c3SRoderick Colenbrander DUALSHOCK4_CONTROLLER_BT | \ 6535f436c3SRoderick Colenbrander DUALSHOCK4_DONGLE) 66fee4e2d5SFrank Praznik #define SONY_LED_SUPPORT (SIXAXIS_CONTROLLER | BUZZ_CONTROLLER |\ 674545ee0aSSimon Wood DUALSHOCK4_CONTROLLER | MOTION_CONTROLLER |\ 684545ee0aSSimon Wood NAVIGATION_CONTROLLER) 6912e9a6d7SSimon Wood #define SONY_BATTERY_SUPPORT (SIXAXIS_CONTROLLER | DUALSHOCK4_CONTROLLER |\ 704545ee0aSSimon Wood MOTION_CONTROLLER_BT | NAVIGATION_CONTROLLER) 71c5e0c1c4SFrank Praznik #define SONY_FF_SUPPORT (SIXAXIS_CONTROLLER | DUALSHOCK4_CONTROLLER |\ 72c5e0c1c4SFrank Praznik MOTION_CONTROLLER) 730f398230SFrank Praznik #define SONY_BT_DEVICE (SIXAXIS_CONTROLLER_BT | DUALSHOCK4_CONTROLLER_BT |\ 740f398230SFrank Praznik MOTION_CONTROLLER_BT | NAVIGATION_CONTROLLER_BT) 7560781cf4SFrank Praznik 7660781cf4SFrank Praznik #define MAX_LEDS 4 770a286ef2SSven Eckelmann 784c3e8298SFrank Praznik /* 794c3e8298SFrank Praznik * The Sixaxis reports both digital and analog values for each button on the 804c3e8298SFrank Praznik * controller except for Start, Select and the PS button. The controller ends 814c3e8298SFrank Praznik * up reporting 27 axes which causes them to spill over into the multi-touch 824c3e8298SFrank Praznik * axis values. Additionally, the controller only has 20 actual, physical axes 834c3e8298SFrank Praznik * so there are several unused axes in between the used ones. 844c3e8298SFrank Praznik */ 851adf904eSPavel Machek static u8 sixaxis_rdesc[] = { 86fb705a6dSAntonio Ospite 0x05, 0x01, /* Usage Page (Desktop), */ 874c3e8298SFrank Praznik 0x09, 0x04, /* Usage (Joystick), */ 88fb705a6dSAntonio Ospite 0xA1, 0x01, /* Collection (Application), */ 89fb705a6dSAntonio Ospite 0xA1, 0x02, /* Collection (Logical), */ 90fb705a6dSAntonio Ospite 0x85, 0x01, /* Report ID (1), */ 91fb705a6dSAntonio Ospite 0x75, 0x08, /* Report Size (8), */ 92fb705a6dSAntonio Ospite 0x95, 0x01, /* Report Count (1), */ 93fb705a6dSAntonio Ospite 0x15, 0x00, /* Logical Minimum (0), */ 94fb705a6dSAntonio Ospite 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ 95fb705a6dSAntonio Ospite 0x81, 0x03, /* Input (Constant, Variable), */ 96fb705a6dSAntonio Ospite 0x75, 0x01, /* Report Size (1), */ 97fb705a6dSAntonio Ospite 0x95, 0x13, /* Report Count (19), */ 98fb705a6dSAntonio Ospite 0x15, 0x00, /* Logical Minimum (0), */ 99fb705a6dSAntonio Ospite 0x25, 0x01, /* Logical Maximum (1), */ 100fb705a6dSAntonio Ospite 0x35, 0x00, /* Physical Minimum (0), */ 101fb705a6dSAntonio Ospite 0x45, 0x01, /* Physical Maximum (1), */ 102fb705a6dSAntonio Ospite 0x05, 0x09, /* Usage Page (Button), */ 103fb705a6dSAntonio Ospite 0x19, 0x01, /* Usage Minimum (01h), */ 104fb705a6dSAntonio Ospite 0x29, 0x13, /* Usage Maximum (13h), */ 105fb705a6dSAntonio Ospite 0x81, 0x02, /* Input (Variable), */ 106fb705a6dSAntonio Ospite 0x75, 0x01, /* Report Size (1), */ 107fb705a6dSAntonio Ospite 0x95, 0x0D, /* Report Count (13), */ 108fb705a6dSAntonio Ospite 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */ 109fb705a6dSAntonio Ospite 0x81, 0x03, /* Input (Constant, Variable), */ 110fb705a6dSAntonio Ospite 0x15, 0x00, /* Logical Minimum (0), */ 111fb705a6dSAntonio Ospite 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ 112fb705a6dSAntonio Ospite 0x05, 0x01, /* Usage Page (Desktop), */ 113fb705a6dSAntonio Ospite 0x09, 0x01, /* Usage (Pointer), */ 114fb705a6dSAntonio Ospite 0xA1, 0x00, /* Collection (Physical), */ 115fb705a6dSAntonio Ospite 0x75, 0x08, /* Report Size (8), */ 116fb705a6dSAntonio Ospite 0x95, 0x04, /* Report Count (4), */ 117fb705a6dSAntonio Ospite 0x35, 0x00, /* Physical Minimum (0), */ 118fb705a6dSAntonio Ospite 0x46, 0xFF, 0x00, /* Physical Maximum (255), */ 119fb705a6dSAntonio Ospite 0x09, 0x30, /* Usage (X), */ 120fb705a6dSAntonio Ospite 0x09, 0x31, /* Usage (Y), */ 121fb705a6dSAntonio Ospite 0x09, 0x32, /* Usage (Z), */ 122fb705a6dSAntonio Ospite 0x09, 0x35, /* Usage (Rz), */ 123fb705a6dSAntonio Ospite 0x81, 0x02, /* Input (Variable), */ 124fb705a6dSAntonio Ospite 0xC0, /* End Collection, */ 125fb705a6dSAntonio Ospite 0x05, 0x01, /* Usage Page (Desktop), */ 126fb705a6dSAntonio Ospite 0x95, 0x13, /* Report Count (19), */ 127fb705a6dSAntonio Ospite 0x09, 0x01, /* Usage (Pointer), */ 128fb705a6dSAntonio Ospite 0x81, 0x02, /* Input (Variable), */ 129fb705a6dSAntonio Ospite 0x95, 0x0C, /* Report Count (12), */ 130fb705a6dSAntonio Ospite 0x81, 0x01, /* Input (Constant), */ 131fb705a6dSAntonio Ospite 0x75, 0x10, /* Report Size (16), */ 132fb705a6dSAntonio Ospite 0x95, 0x04, /* Report Count (4), */ 133fb705a6dSAntonio Ospite 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */ 134fb705a6dSAntonio Ospite 0x46, 0xFF, 0x03, /* Physical Maximum (1023), */ 135fb705a6dSAntonio Ospite 0x09, 0x01, /* Usage (Pointer), */ 136fb705a6dSAntonio Ospite 0x81, 0x02, /* Input (Variable), */ 137fb705a6dSAntonio Ospite 0xC0, /* End Collection, */ 138fb705a6dSAntonio Ospite 0xA1, 0x02, /* Collection (Logical), */ 139fb705a6dSAntonio Ospite 0x85, 0x02, /* Report ID (2), */ 140fb705a6dSAntonio Ospite 0x75, 0x08, /* Report Size (8), */ 141fb705a6dSAntonio Ospite 0x95, 0x30, /* Report Count (48), */ 142fb705a6dSAntonio Ospite 0x09, 0x01, /* Usage (Pointer), */ 143fb705a6dSAntonio Ospite 0xB1, 0x02, /* Feature (Variable), */ 144fb705a6dSAntonio Ospite 0xC0, /* End Collection, */ 145fb705a6dSAntonio Ospite 0xA1, 0x02, /* Collection (Logical), */ 146fb705a6dSAntonio Ospite 0x85, 0xEE, /* Report ID (238), */ 147fb705a6dSAntonio Ospite 0x75, 0x08, /* Report Size (8), */ 148fb705a6dSAntonio Ospite 0x95, 0x30, /* Report Count (48), */ 149fb705a6dSAntonio Ospite 0x09, 0x01, /* Usage (Pointer), */ 150fb705a6dSAntonio Ospite 0xB1, 0x02, /* Feature (Variable), */ 151fb705a6dSAntonio Ospite 0xC0, /* End Collection, */ 152fb705a6dSAntonio Ospite 0xA1, 0x02, /* Collection (Logical), */ 153fb705a6dSAntonio Ospite 0x85, 0xEF, /* Report ID (239), */ 154fb705a6dSAntonio Ospite 0x75, 0x08, /* Report Size (8), */ 155fb705a6dSAntonio Ospite 0x95, 0x30, /* Report Count (48), */ 156fb705a6dSAntonio Ospite 0x09, 0x01, /* Usage (Pointer), */ 157fb705a6dSAntonio Ospite 0xB1, 0x02, /* Feature (Variable), */ 158fb705a6dSAntonio Ospite 0xC0, /* End Collection, */ 159fb705a6dSAntonio Ospite 0xC0 /* End Collection */ 160e57a67daSMauro Carvalho Chehab }; 161e57a67daSMauro Carvalho Chehab 162c5e0c1c4SFrank Praznik /* PS/3 Motion controller */ 1631adf904eSPavel Machek static u8 motion_rdesc[] = { 164c5e0c1c4SFrank Praznik 0x05, 0x01, /* Usage Page (Desktop), */ 165c5e0c1c4SFrank Praznik 0x09, 0x04, /* Usage (Joystick), */ 166c5e0c1c4SFrank Praznik 0xA1, 0x01, /* Collection (Application), */ 167c5e0c1c4SFrank Praznik 0xA1, 0x02, /* Collection (Logical), */ 168c5e0c1c4SFrank Praznik 0x85, 0x01, /* Report ID (1), */ 169c5e0c1c4SFrank Praznik 0x75, 0x01, /* Report Size (1), */ 1708b2513c3SSimon Wood 0x95, 0x15, /* Report Count (21), */ 171c5e0c1c4SFrank Praznik 0x15, 0x00, /* Logical Minimum (0), */ 172c5e0c1c4SFrank Praznik 0x25, 0x01, /* Logical Maximum (1), */ 173c5e0c1c4SFrank Praznik 0x35, 0x00, /* Physical Minimum (0), */ 174c5e0c1c4SFrank Praznik 0x45, 0x01, /* Physical Maximum (1), */ 175c5e0c1c4SFrank Praznik 0x05, 0x09, /* Usage Page (Button), */ 176c5e0c1c4SFrank Praznik 0x19, 0x01, /* Usage Minimum (01h), */ 1778b2513c3SSimon Wood 0x29, 0x15, /* Usage Maximum (15h), */ 1788b2513c3SSimon Wood 0x81, 0x02, /* Input (Variable), * Buttons */ 1798b2513c3SSimon Wood 0x95, 0x0B, /* Report Count (11), */ 180c5e0c1c4SFrank Praznik 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */ 1818b2513c3SSimon Wood 0x81, 0x03, /* Input (Constant, Variable), * Padding */ 182c5e0c1c4SFrank Praznik 0x15, 0x00, /* Logical Minimum (0), */ 183c5e0c1c4SFrank Praznik 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ 184c5e0c1c4SFrank Praznik 0x05, 0x01, /* Usage Page (Desktop), */ 185c5e0c1c4SFrank Praznik 0xA1, 0x00, /* Collection (Physical), */ 186c5e0c1c4SFrank Praznik 0x75, 0x08, /* Report Size (8), */ 1878b2513c3SSimon Wood 0x95, 0x01, /* Report Count (1), */ 188c5e0c1c4SFrank Praznik 0x35, 0x00, /* Physical Minimum (0), */ 189c5e0c1c4SFrank Praznik 0x46, 0xFF, 0x00, /* Physical Maximum (255), */ 190c5e0c1c4SFrank Praznik 0x09, 0x30, /* Usage (X), */ 1918b2513c3SSimon Wood 0x81, 0x02, /* Input (Variable), * Trigger */ 192c5e0c1c4SFrank Praznik 0xC0, /* End Collection, */ 1938b2513c3SSimon Wood 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */ 1948b2513c3SSimon Wood 0x75, 0x08, /* Report Size (8), */ 1958b2513c3SSimon Wood 0x95, 0x07, /* Report Count (7), * skip 7 bytes */ 1968b2513c3SSimon Wood 0x81, 0x02, /* Input (Variable), */ 197c5e0c1c4SFrank Praznik 0x05, 0x01, /* Usage Page (Desktop), */ 198c5e0c1c4SFrank Praznik 0x75, 0x10, /* Report Size (16), */ 1998b2513c3SSimon Wood 0x46, 0xFF, 0xFF, /* Physical Maximum (65535), */ 2008b2513c3SSimon Wood 0x27, 0xFF, 0xFF, 0x00, 0x00, /* Logical Maximum (65535), */ 2018b2513c3SSimon Wood 0x95, 0x03, /* Report Count (3), * 3x Accels */ 2028b2513c3SSimon Wood 0x09, 0x33, /* Usage (rX), */ 2038b2513c3SSimon Wood 0x09, 0x34, /* Usage (rY), */ 2048b2513c3SSimon Wood 0x09, 0x35, /* Usage (rZ), */ 205c5e0c1c4SFrank Praznik 0x81, 0x02, /* Input (Variable), */ 2068b2513c3SSimon Wood 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */ 2078b2513c3SSimon Wood 0x95, 0x03, /* Report Count (3), * Skip Accels 2nd frame */ 2088b2513c3SSimon Wood 0x81, 0x02, /* Input (Variable), */ 2098b2513c3SSimon Wood 0x05, 0x01, /* Usage Page (Desktop), */ 2108b2513c3SSimon Wood 0x09, 0x01, /* Usage (Pointer), */ 2118b2513c3SSimon Wood 0x95, 0x03, /* Report Count (3), * 3x Gyros */ 2128b2513c3SSimon Wood 0x81, 0x02, /* Input (Variable), */ 2138b2513c3SSimon Wood 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */ 2148b2513c3SSimon Wood 0x95, 0x03, /* Report Count (3), * Skip Gyros 2nd frame */ 2158b2513c3SSimon Wood 0x81, 0x02, /* Input (Variable), */ 2168b2513c3SSimon Wood 0x75, 0x0C, /* Report Size (12), */ 2178b2513c3SSimon Wood 0x46, 0xFF, 0x0F, /* Physical Maximum (4095), */ 2188b2513c3SSimon Wood 0x26, 0xFF, 0x0F, /* Logical Maximum (4095), */ 2198b2513c3SSimon Wood 0x95, 0x04, /* Report Count (4), * Skip Temp and Magnetometers */ 2208b2513c3SSimon Wood 0x81, 0x02, /* Input (Variable), */ 2218b2513c3SSimon Wood 0x75, 0x08, /* Report Size (8), */ 2228b2513c3SSimon Wood 0x46, 0xFF, 0x00, /* Physical Maximum (255), */ 2238b2513c3SSimon Wood 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ 2248b2513c3SSimon Wood 0x95, 0x06, /* Report Count (6), * Skip Timestamp and Extension Bytes */ 2258b2513c3SSimon Wood 0x81, 0x02, /* Input (Variable), */ 2268b2513c3SSimon Wood 0x75, 0x08, /* Report Size (8), */ 2278b2513c3SSimon Wood 0x95, 0x30, /* Report Count (48), */ 2288b2513c3SSimon Wood 0x09, 0x01, /* Usage (Pointer), */ 2298b2513c3SSimon Wood 0x91, 0x02, /* Output (Variable), */ 2308b2513c3SSimon Wood 0x75, 0x08, /* Report Size (8), */ 2318b2513c3SSimon Wood 0x95, 0x30, /* Report Count (48), */ 2328b2513c3SSimon Wood 0x09, 0x01, /* Usage (Pointer), */ 2338b2513c3SSimon Wood 0xB1, 0x02, /* Feature (Variable), */ 234c5e0c1c4SFrank Praznik 0xC0, /* End Collection, */ 235c5e0c1c4SFrank Praznik 0xA1, 0x02, /* Collection (Logical), */ 236c5e0c1c4SFrank Praznik 0x85, 0x02, /* Report ID (2), */ 237c5e0c1c4SFrank Praznik 0x75, 0x08, /* Report Size (8), */ 238c5e0c1c4SFrank Praznik 0x95, 0x30, /* Report Count (48), */ 239c5e0c1c4SFrank Praznik 0x09, 0x01, /* Usage (Pointer), */ 240c5e0c1c4SFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 241c5e0c1c4SFrank Praznik 0xC0, /* End Collection, */ 242c5e0c1c4SFrank Praznik 0xA1, 0x02, /* Collection (Logical), */ 243c5e0c1c4SFrank Praznik 0x85, 0xEE, /* Report ID (238), */ 244c5e0c1c4SFrank Praznik 0x75, 0x08, /* Report Size (8), */ 245c5e0c1c4SFrank Praznik 0x95, 0x30, /* Report Count (48), */ 246c5e0c1c4SFrank Praznik 0x09, 0x01, /* Usage (Pointer), */ 247c5e0c1c4SFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 248c5e0c1c4SFrank Praznik 0xC0, /* End Collection, */ 249c5e0c1c4SFrank Praznik 0xA1, 0x02, /* Collection (Logical), */ 250c5e0c1c4SFrank Praznik 0x85, 0xEF, /* Report ID (239), */ 251c5e0c1c4SFrank Praznik 0x75, 0x08, /* Report Size (8), */ 252c5e0c1c4SFrank Praznik 0x95, 0x30, /* Report Count (48), */ 253c5e0c1c4SFrank Praznik 0x09, 0x01, /* Usage (Pointer), */ 254c5e0c1c4SFrank Praznik 0xB1, 0x02, /* Feature (Variable), */ 255c5e0c1c4SFrank Praznik 0xC0, /* End Collection, */ 256c5e0c1c4SFrank Praznik 0xC0 /* End Collection */ 257c5e0c1c4SFrank Praznik }; 258c5e0c1c4SFrank Praznik 259b2723eb7SSimon Wood /* PS/3 Navigation controller */ 2601adf904eSPavel Machek static u8 navigation_rdesc[] = { 261b2723eb7SSimon Wood 0x05, 0x01, /* Usage Page (Desktop), */ 262d542176fSAntonio Ospite 0x09, 0x04, /* Usage (Joystick), */ 263b2723eb7SSimon Wood 0xA1, 0x01, /* Collection (Application), */ 264b2723eb7SSimon Wood 0xA1, 0x02, /* Collection (Logical), */ 265b2723eb7SSimon Wood 0x85, 0x01, /* Report ID (1), */ 266b2723eb7SSimon Wood 0x75, 0x08, /* Report Size (8), */ 267b2723eb7SSimon Wood 0x95, 0x01, /* Report Count (1), */ 268b2723eb7SSimon Wood 0x15, 0x00, /* Logical Minimum (0), */ 269b2723eb7SSimon Wood 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ 270b2723eb7SSimon Wood 0x81, 0x03, /* Input (Constant, Variable), */ 271b2723eb7SSimon Wood 0x75, 0x01, /* Report Size (1), */ 272b2723eb7SSimon Wood 0x95, 0x13, /* Report Count (19), */ 273b2723eb7SSimon Wood 0x15, 0x00, /* Logical Minimum (0), */ 274b2723eb7SSimon Wood 0x25, 0x01, /* Logical Maximum (1), */ 275b2723eb7SSimon Wood 0x35, 0x00, /* Physical Minimum (0), */ 276b2723eb7SSimon Wood 0x45, 0x01, /* Physical Maximum (1), */ 277b2723eb7SSimon Wood 0x05, 0x09, /* Usage Page (Button), */ 278b2723eb7SSimon Wood 0x19, 0x01, /* Usage Minimum (01h), */ 279b2723eb7SSimon Wood 0x29, 0x13, /* Usage Maximum (13h), */ 280b2723eb7SSimon Wood 0x81, 0x02, /* Input (Variable), */ 281b2723eb7SSimon Wood 0x75, 0x01, /* Report Size (1), */ 282b2723eb7SSimon Wood 0x95, 0x0D, /* Report Count (13), */ 283b2723eb7SSimon Wood 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */ 284b2723eb7SSimon Wood 0x81, 0x03, /* Input (Constant, Variable), */ 285b2723eb7SSimon Wood 0x15, 0x00, /* Logical Minimum (0), */ 286b2723eb7SSimon Wood 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ 287b2723eb7SSimon Wood 0x05, 0x01, /* Usage Page (Desktop), */ 288b2723eb7SSimon Wood 0x09, 0x01, /* Usage (Pointer), */ 289b2723eb7SSimon Wood 0xA1, 0x00, /* Collection (Physical), */ 290b2723eb7SSimon Wood 0x75, 0x08, /* Report Size (8), */ 291b2723eb7SSimon Wood 0x95, 0x02, /* Report Count (2), */ 292b2723eb7SSimon Wood 0x35, 0x00, /* Physical Minimum (0), */ 293b2723eb7SSimon Wood 0x46, 0xFF, 0x00, /* Physical Maximum (255), */ 294b2723eb7SSimon Wood 0x09, 0x30, /* Usage (X), */ 295b2723eb7SSimon Wood 0x09, 0x31, /* Usage (Y), */ 296b2723eb7SSimon Wood 0x81, 0x02, /* Input (Variable), */ 297b2723eb7SSimon Wood 0xC0, /* End Collection, */ 298b2723eb7SSimon Wood 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */ 299b2723eb7SSimon Wood 0x95, 0x06, /* Report Count (6), */ 300b2723eb7SSimon Wood 0x81, 0x03, /* Input (Constant, Variable), */ 301b2723eb7SSimon Wood 0x05, 0x01, /* Usage Page (Desktop), */ 302b2723eb7SSimon Wood 0x75, 0x08, /* Report Size (8), */ 303b2723eb7SSimon Wood 0x95, 0x05, /* Report Count (5), */ 304b2723eb7SSimon Wood 0x09, 0x01, /* Usage (Pointer), */ 305b2723eb7SSimon Wood 0x81, 0x02, /* Input (Variable), */ 306b2723eb7SSimon Wood 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */ 3072259b5bbSSimon Wood 0x95, 0x01, /* Report Count (1), */ 3082259b5bbSSimon Wood 0x81, 0x02, /* Input (Variable), */ 3092259b5bbSSimon Wood 0x05, 0x01, /* Usage Page (Desktop), */ 3102259b5bbSSimon Wood 0x95, 0x01, /* Report Count (1), */ 3112259b5bbSSimon Wood 0x09, 0x01, /* Usage (Pointer), */ 3122259b5bbSSimon Wood 0x81, 0x02, /* Input (Variable), */ 3132259b5bbSSimon Wood 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */ 3142259b5bbSSimon Wood 0x95, 0x1E, /* Report Count (24), */ 315b2723eb7SSimon Wood 0x81, 0x02, /* Input (Variable), */ 316b2723eb7SSimon Wood 0x75, 0x08, /* Report Size (8), */ 317b2723eb7SSimon Wood 0x95, 0x30, /* Report Count (48), */ 318b2723eb7SSimon Wood 0x09, 0x01, /* Usage (Pointer), */ 319b2723eb7SSimon Wood 0x91, 0x02, /* Output (Variable), */ 320b2723eb7SSimon Wood 0x75, 0x08, /* Report Size (8), */ 321b2723eb7SSimon Wood 0x95, 0x30, /* Report Count (48), */ 322b2723eb7SSimon Wood 0x09, 0x01, /* Usage (Pointer), */ 323b2723eb7SSimon Wood 0xB1, 0x02, /* Feature (Variable), */ 324b2723eb7SSimon Wood 0xC0, /* End Collection, */ 325b2723eb7SSimon Wood 0xA1, 0x02, /* Collection (Logical), */ 326b2723eb7SSimon Wood 0x85, 0x02, /* Report ID (2), */ 327b2723eb7SSimon Wood 0x75, 0x08, /* Report Size (8), */ 328b2723eb7SSimon Wood 0x95, 0x30, /* Report Count (48), */ 329b2723eb7SSimon Wood 0x09, 0x01, /* Usage (Pointer), */ 330b2723eb7SSimon Wood 0xB1, 0x02, /* Feature (Variable), */ 331b2723eb7SSimon Wood 0xC0, /* End Collection, */ 332b2723eb7SSimon Wood 0xA1, 0x02, /* Collection (Logical), */ 333b2723eb7SSimon Wood 0x85, 0xEE, /* Report ID (238), */ 334b2723eb7SSimon Wood 0x75, 0x08, /* Report Size (8), */ 335b2723eb7SSimon Wood 0x95, 0x30, /* Report Count (48), */ 336b2723eb7SSimon Wood 0x09, 0x01, /* Usage (Pointer), */ 337b2723eb7SSimon Wood 0xB1, 0x02, /* Feature (Variable), */ 338b2723eb7SSimon Wood 0xC0, /* End Collection, */ 339b2723eb7SSimon Wood 0xA1, 0x02, /* Collection (Logical), */ 340b2723eb7SSimon Wood 0x85, 0xEF, /* Report ID (239), */ 341b2723eb7SSimon Wood 0x75, 0x08, /* Report Size (8), */ 342b2723eb7SSimon Wood 0x95, 0x30, /* Report Count (48), */ 343b2723eb7SSimon Wood 0x09, 0x01, /* Usage (Pointer), */ 344b2723eb7SSimon Wood 0xB1, 0x02, /* Feature (Variable), */ 345b2723eb7SSimon Wood 0xC0, /* End Collection, */ 346b2723eb7SSimon Wood 0xC0 /* End Collection */ 347b2723eb7SSimon Wood }; 348c5e0c1c4SFrank Praznik 3491adf904eSPavel Machek static u8 ps3remote_rdesc[] = { 350078328daSJiri Kosina 0x05, 0x01, /* GUsagePage Generic Desktop */ 351078328daSJiri Kosina 0x09, 0x05, /* LUsage 0x05 [Game Pad] */ 352078328daSJiri Kosina 0xA1, 0x01, /* MCollection Application (mouse, keyboard) */ 353078328daSJiri Kosina 354078328daSJiri Kosina /* Use collection 1 for joypad buttons */ 355078328daSJiri Kosina 0xA1, 0x02, /* MCollection Logical (interrelated data) */ 356078328daSJiri Kosina 357ef916ef5SAntonio Ospite /* 358ef916ef5SAntonio Ospite * Ignore the 1st byte, maybe it is used for a controller 359ef916ef5SAntonio Ospite * number but it's not needed for correct operation 360ef916ef5SAntonio Ospite */ 361078328daSJiri Kosina 0x75, 0x08, /* GReportSize 0x08 [8] */ 362078328daSJiri Kosina 0x95, 0x01, /* GReportCount 0x01 [1] */ 363078328daSJiri Kosina 0x81, 0x01, /* MInput 0x01 (Const[0] Arr[1] Abs[2]) */ 364078328daSJiri Kosina 365ef916ef5SAntonio Ospite /* 366ef916ef5SAntonio Ospite * Bytes from 2nd to 4th are a bitmap for joypad buttons, for these 367ef916ef5SAntonio Ospite * buttons multiple keypresses are allowed 368ef916ef5SAntonio Ospite */ 369078328daSJiri Kosina 0x05, 0x09, /* GUsagePage Button */ 370078328daSJiri Kosina 0x19, 0x01, /* LUsageMinimum 0x01 [Button 1 (primary/trigger)] */ 371078328daSJiri Kosina 0x29, 0x18, /* LUsageMaximum 0x18 [Button 24] */ 372078328daSJiri Kosina 0x14, /* GLogicalMinimum [0] */ 373078328daSJiri Kosina 0x25, 0x01, /* GLogicalMaximum 0x01 [1] */ 374078328daSJiri Kosina 0x75, 0x01, /* GReportSize 0x01 [1] */ 375078328daSJiri Kosina 0x95, 0x18, /* GReportCount 0x18 [24] */ 376078328daSJiri Kosina 0x81, 0x02, /* MInput 0x02 (Data[0] Var[1] Abs[2]) */ 377078328daSJiri Kosina 378078328daSJiri Kosina 0xC0, /* MEndCollection */ 379078328daSJiri Kosina 380078328daSJiri Kosina /* Use collection 2 for remote control buttons */ 381078328daSJiri Kosina 0xA1, 0x02, /* MCollection Logical (interrelated data) */ 382078328daSJiri Kosina 383078328daSJiri Kosina /* 5th byte is used for remote control buttons */ 384078328daSJiri Kosina 0x05, 0x09, /* GUsagePage Button */ 385078328daSJiri Kosina 0x18, /* LUsageMinimum [No button pressed] */ 386078328daSJiri Kosina 0x29, 0xFE, /* LUsageMaximum 0xFE [Button 254] */ 387078328daSJiri Kosina 0x14, /* GLogicalMinimum [0] */ 388078328daSJiri Kosina 0x26, 0xFE, 0x00, /* GLogicalMaximum 0x00FE [254] */ 389078328daSJiri Kosina 0x75, 0x08, /* GReportSize 0x08 [8] */ 390078328daSJiri Kosina 0x95, 0x01, /* GReportCount 0x01 [1] */ 391078328daSJiri Kosina 0x80, /* MInput */ 392078328daSJiri Kosina 393ef916ef5SAntonio Ospite /* 394ef916ef5SAntonio Ospite * Ignore bytes from 6th to 11th, 6th to 10th are always constant at 395ef916ef5SAntonio Ospite * 0xff and 11th is for press indication 396ef916ef5SAntonio Ospite */ 397078328daSJiri Kosina 0x75, 0x08, /* GReportSize 0x08 [8] */ 398078328daSJiri Kosina 0x95, 0x06, /* GReportCount 0x06 [6] */ 399078328daSJiri Kosina 0x81, 0x01, /* MInput 0x01 (Const[0] Arr[1] Abs[2]) */ 400078328daSJiri Kosina 401078328daSJiri Kosina /* 12th byte is for battery strength */ 402078328daSJiri Kosina 0x05, 0x06, /* GUsagePage Generic Device Controls */ 403078328daSJiri Kosina 0x09, 0x20, /* LUsage 0x20 [Battery Strength] */ 404078328daSJiri Kosina 0x14, /* GLogicalMinimum [0] */ 405078328daSJiri Kosina 0x25, 0x05, /* GLogicalMaximum 0x05 [5] */ 406078328daSJiri Kosina 0x75, 0x08, /* GReportSize 0x08 [8] */ 407078328daSJiri Kosina 0x95, 0x01, /* GReportCount 0x01 [1] */ 408078328daSJiri Kosina 0x81, 0x02, /* MInput 0x02 (Data[0] Var[1] Abs[2]) */ 409078328daSJiri Kosina 410078328daSJiri Kosina 0xC0, /* MEndCollection */ 411078328daSJiri Kosina 412078328daSJiri Kosina 0xC0 /* MEndCollection [Game Pad] */ 413078328daSJiri Kosina }; 414078328daSJiri Kosina 415078328daSJiri Kosina static const unsigned int ps3remote_keymap_joypad_buttons[] = { 416078328daSJiri Kosina [0x01] = KEY_SELECT, 417078328daSJiri Kosina [0x02] = BTN_THUMBL, /* L3 */ 418078328daSJiri Kosina [0x03] = BTN_THUMBR, /* R3 */ 419078328daSJiri Kosina [0x04] = BTN_START, 420078328daSJiri Kosina [0x05] = KEY_UP, 421078328daSJiri Kosina [0x06] = KEY_RIGHT, 422078328daSJiri Kosina [0x07] = KEY_DOWN, 423078328daSJiri Kosina [0x08] = KEY_LEFT, 424078328daSJiri Kosina [0x09] = BTN_TL2, /* L2 */ 425078328daSJiri Kosina [0x0a] = BTN_TR2, /* R2 */ 426078328daSJiri Kosina [0x0b] = BTN_TL, /* L1 */ 427078328daSJiri Kosina [0x0c] = BTN_TR, /* R1 */ 428078328daSJiri Kosina [0x0d] = KEY_OPTION, /* options/triangle */ 429078328daSJiri Kosina [0x0e] = KEY_BACK, /* back/circle */ 430078328daSJiri Kosina [0x0f] = BTN_0, /* cross */ 431078328daSJiri Kosina [0x10] = KEY_SCREEN, /* view/square */ 432078328daSJiri Kosina [0x11] = KEY_HOMEPAGE, /* PS button */ 433078328daSJiri Kosina [0x14] = KEY_ENTER, 434078328daSJiri Kosina }; 435078328daSJiri Kosina static const unsigned int ps3remote_keymap_remote_buttons[] = { 436078328daSJiri Kosina [0x00] = KEY_1, 437078328daSJiri Kosina [0x01] = KEY_2, 438078328daSJiri Kosina [0x02] = KEY_3, 439078328daSJiri Kosina [0x03] = KEY_4, 440078328daSJiri Kosina [0x04] = KEY_5, 441078328daSJiri Kosina [0x05] = KEY_6, 442078328daSJiri Kosina [0x06] = KEY_7, 443078328daSJiri Kosina [0x07] = KEY_8, 444078328daSJiri Kosina [0x08] = KEY_9, 445078328daSJiri Kosina [0x09] = KEY_0, 446078328daSJiri Kosina [0x0e] = KEY_ESC, /* return */ 447078328daSJiri Kosina [0x0f] = KEY_CLEAR, 448078328daSJiri Kosina [0x16] = KEY_EJECTCD, 449078328daSJiri Kosina [0x1a] = KEY_MENU, /* top menu */ 450078328daSJiri Kosina [0x28] = KEY_TIME, 451078328daSJiri Kosina [0x30] = KEY_PREVIOUS, 452078328daSJiri Kosina [0x31] = KEY_NEXT, 453078328daSJiri Kosina [0x32] = KEY_PLAY, 454078328daSJiri Kosina [0x33] = KEY_REWIND, /* scan back */ 455078328daSJiri Kosina [0x34] = KEY_FORWARD, /* scan forward */ 456078328daSJiri Kosina [0x38] = KEY_STOP, 457078328daSJiri Kosina [0x39] = KEY_PAUSE, 458078328daSJiri Kosina [0x40] = KEY_CONTEXT_MENU, /* pop up/menu */ 459078328daSJiri Kosina [0x60] = KEY_FRAMEBACK, /* slow/step back */ 460078328daSJiri Kosina [0x61] = KEY_FRAMEFORWARD, /* slow/step forward */ 461078328daSJiri Kosina [0x63] = KEY_SUBTITLE, 462078328daSJiri Kosina [0x64] = KEY_AUDIO, 463078328daSJiri Kosina [0x65] = KEY_ANGLE, 464078328daSJiri Kosina [0x70] = KEY_INFO, /* display */ 465078328daSJiri Kosina [0x80] = KEY_BLUE, 466078328daSJiri Kosina [0x81] = KEY_RED, 467078328daSJiri Kosina [0x82] = KEY_GREEN, 468078328daSJiri Kosina [0x83] = KEY_YELLOW, 469078328daSJiri Kosina }; 470078328daSJiri Kosina 471f04d5140SColin Leitner static const unsigned int buzz_keymap[] = { 472ad142b9eSFrank Praznik /* 473ad142b9eSFrank Praznik * The controller has 4 remote buzzers, each with one LED and 5 474f04d5140SColin Leitner * buttons. 475f04d5140SColin Leitner * 476f04d5140SColin Leitner * We use the mapping chosen by the controller, which is: 477f04d5140SColin Leitner * 478f04d5140SColin Leitner * Key Offset 479f04d5140SColin Leitner * ------------------- 480f04d5140SColin Leitner * Buzz 1 481f04d5140SColin Leitner * Blue 5 482f04d5140SColin Leitner * Orange 4 483f04d5140SColin Leitner * Green 3 484f04d5140SColin Leitner * Yellow 2 485f04d5140SColin Leitner * 486f04d5140SColin Leitner * So, for example, the orange button on the third buzzer is mapped to 487f04d5140SColin Leitner * BTN_TRIGGER_HAPPY14 488f04d5140SColin Leitner */ 489f04d5140SColin Leitner [1] = BTN_TRIGGER_HAPPY1, 490f04d5140SColin Leitner [2] = BTN_TRIGGER_HAPPY2, 491f04d5140SColin Leitner [3] = BTN_TRIGGER_HAPPY3, 492f04d5140SColin Leitner [4] = BTN_TRIGGER_HAPPY4, 493f04d5140SColin Leitner [5] = BTN_TRIGGER_HAPPY5, 494f04d5140SColin Leitner [6] = BTN_TRIGGER_HAPPY6, 495f04d5140SColin Leitner [7] = BTN_TRIGGER_HAPPY7, 496f04d5140SColin Leitner [8] = BTN_TRIGGER_HAPPY8, 497f04d5140SColin Leitner [9] = BTN_TRIGGER_HAPPY9, 498f04d5140SColin Leitner [10] = BTN_TRIGGER_HAPPY10, 499f04d5140SColin Leitner [11] = BTN_TRIGGER_HAPPY11, 500f04d5140SColin Leitner [12] = BTN_TRIGGER_HAPPY12, 501f04d5140SColin Leitner [13] = BTN_TRIGGER_HAPPY13, 502f04d5140SColin Leitner [14] = BTN_TRIGGER_HAPPY14, 503f04d5140SColin Leitner [15] = BTN_TRIGGER_HAPPY15, 504f04d5140SColin Leitner [16] = BTN_TRIGGER_HAPPY16, 505f04d5140SColin Leitner [17] = BTN_TRIGGER_HAPPY17, 506f04d5140SColin Leitner [18] = BTN_TRIGGER_HAPPY18, 507f04d5140SColin Leitner [19] = BTN_TRIGGER_HAPPY19, 508f04d5140SColin Leitner [20] = BTN_TRIGGER_HAPPY20, 509f04d5140SColin Leitner }; 510f04d5140SColin Leitner 5119131f8ccSRoderick Colenbrander static const unsigned int ds4_absmap[] = { 5129131f8ccSRoderick Colenbrander [0x30] = ABS_X, 5139131f8ccSRoderick Colenbrander [0x31] = ABS_Y, 5149131f8ccSRoderick Colenbrander [0x32] = ABS_RX, /* right stick X */ 5159131f8ccSRoderick Colenbrander [0x33] = ABS_Z, /* L2 */ 5169131f8ccSRoderick Colenbrander [0x34] = ABS_RZ, /* R2 */ 5179131f8ccSRoderick Colenbrander [0x35] = ABS_RY, /* right stick Y */ 5189131f8ccSRoderick Colenbrander }; 5199131f8ccSRoderick Colenbrander 5209131f8ccSRoderick Colenbrander static const unsigned int ds4_keymap[] = { 5219131f8ccSRoderick Colenbrander [0x1] = BTN_WEST, /* Square */ 5229131f8ccSRoderick Colenbrander [0x2] = BTN_SOUTH, /* Cross */ 5239131f8ccSRoderick Colenbrander [0x3] = BTN_EAST, /* Circle */ 5249131f8ccSRoderick Colenbrander [0x4] = BTN_NORTH, /* Triangle */ 5259131f8ccSRoderick Colenbrander [0x5] = BTN_TL, /* L1 */ 5269131f8ccSRoderick Colenbrander [0x6] = BTN_TR, /* R1 */ 5279131f8ccSRoderick Colenbrander [0x7] = BTN_TL2, /* L2 */ 5289131f8ccSRoderick Colenbrander [0x8] = BTN_TR2, /* R2 */ 5299131f8ccSRoderick Colenbrander [0x9] = BTN_SELECT, /* Share */ 5309131f8ccSRoderick Colenbrander [0xa] = BTN_START, /* Options */ 5319131f8ccSRoderick Colenbrander [0xb] = BTN_THUMBL, /* L3 */ 5329131f8ccSRoderick Colenbrander [0xc] = BTN_THUMBR, /* R3 */ 5339131f8ccSRoderick Colenbrander [0xd] = BTN_MODE, /* PS */ 5349131f8ccSRoderick Colenbrander }; 5359131f8ccSRoderick Colenbrander 536d03ae2e1SRoderick Colenbrander static const struct {int x; int y; } ds4_hat_mapping[] = { 537d03ae2e1SRoderick Colenbrander {0, -1}, {1, -1}, {1, 0}, {1, 1}, {0, 1}, {-1, 1}, {-1, 0}, {-1, -1}, 538d03ae2e1SRoderick Colenbrander {0, 0} 539d03ae2e1SRoderick Colenbrander }; 5409131f8ccSRoderick Colenbrander 541d902f472SFrank Praznik static enum power_supply_property sony_battery_props[] = { 542d902f472SFrank Praznik POWER_SUPPLY_PROP_PRESENT, 543d902f472SFrank Praznik POWER_SUPPLY_PROP_CAPACITY, 544d902f472SFrank Praznik POWER_SUPPLY_PROP_SCOPE, 545d902f472SFrank Praznik POWER_SUPPLY_PROP_STATUS, 546d902f472SFrank Praznik }; 547d902f472SFrank Praznik 54855d3b664SFrank Praznik struct sixaxis_led { 5491adf904eSPavel Machek u8 time_enabled; /* the total time the led is active (0xff means forever) */ 5501adf904eSPavel Machek u8 duty_length; /* how long a cycle is in deciseconds (0 means "really fast") */ 5511adf904eSPavel Machek u8 enabled; 5521adf904eSPavel Machek u8 duty_off; /* % of duty_length the led is off (0xff means 100%) */ 5531adf904eSPavel Machek u8 duty_on; /* % of duty_length the led is on (0xff mean 100%) */ 55455d3b664SFrank Praznik } __packed; 55555d3b664SFrank Praznik 55655d3b664SFrank Praznik struct sixaxis_rumble { 5571adf904eSPavel Machek u8 padding; 5581adf904eSPavel Machek u8 right_duration; /* Right motor duration (0xff means forever) */ 5591adf904eSPavel Machek u8 right_motor_on; /* Right (small) motor on/off, only supports values of 0 or 1 (off/on) */ 5601adf904eSPavel Machek u8 left_duration; /* Left motor duration (0xff means forever) */ 5611adf904eSPavel Machek u8 left_motor_force; /* left (large) motor, supports force values from 0 to 255 */ 56255d3b664SFrank Praznik } __packed; 56355d3b664SFrank Praznik 56455d3b664SFrank Praznik struct sixaxis_output_report { 5651adf904eSPavel Machek u8 report_id; 56655d3b664SFrank Praznik struct sixaxis_rumble rumble; 5671adf904eSPavel Machek u8 padding[4]; 5681adf904eSPavel Machek u8 leds_bitmap; /* bitmap of enabled LEDs: LED_1 = 0x02, LED_2 = 0x04, ... */ 56955d3b664SFrank Praznik struct sixaxis_led led[4]; /* LEDx at (4 - x) */ 57055d3b664SFrank Praznik struct sixaxis_led _reserved; /* LED5, not actually soldered */ 57155d3b664SFrank Praznik } __packed; 57255d3b664SFrank Praznik 57355d3b664SFrank Praznik union sixaxis_output_report_01 { 57455d3b664SFrank Praznik struct sixaxis_output_report data; 5751adf904eSPavel Machek u8 buf[36]; 57655d3b664SFrank Praznik }; 57755d3b664SFrank Praznik 578c5e0c1c4SFrank Praznik struct motion_output_report_02 { 579c5e0c1c4SFrank Praznik u8 type, zero; 580c5e0c1c4SFrank Praznik u8 r, g, b; 581c5e0c1c4SFrank Praznik u8 zero2; 582c5e0c1c4SFrank Praznik u8 rumble; 583c5e0c1c4SFrank Praznik }; 584c5e0c1c4SFrank Praznik 5852c159de0SRoderick Colenbrander #define DS4_FEATURE_REPORT_0x02_SIZE 37 58655a07d62SRoderick Colenbrander #define DS4_FEATURE_REPORT_0x05_SIZE 41 5872c159de0SRoderick Colenbrander #define DS4_FEATURE_REPORT_0x81_SIZE 7 58849b9ca6cSRoderick Colenbrander #define DS4_INPUT_REPORT_0x11_SIZE 78 5892c159de0SRoderick Colenbrander #define DS4_OUTPUT_REPORT_0x05_SIZE 32 5902c159de0SRoderick Colenbrander #define DS4_OUTPUT_REPORT_0x11_SIZE 78 59129b691a8SAntonio Ospite #define SIXAXIS_REPORT_0xF2_SIZE 17 592a85d67b5SAntonio Ospite #define SIXAXIS_REPORT_0xF5_SIZE 8 59341d2d425SSimon Wood #define MOTION_REPORT_0x02_SIZE 49 5949b2b5c9aSFrank Praznik 595cdc1c021SRoderick Colenbrander /* Offsets relative to USB input report (0x1). Bluetooth (0x11) requires an 596cdc1c021SRoderick Colenbrander * additional +2. 597cdc1c021SRoderick Colenbrander */ 598d03ae2e1SRoderick Colenbrander #define DS4_INPUT_REPORT_AXIS_OFFSET 1 599ac797b95SRoderick Colenbrander #define DS4_INPUT_REPORT_BUTTON_OFFSET 5 60080786eb9SRoderick Colenbrander #define DS4_INPUT_REPORT_TIMESTAMP_OFFSET 10 601227c011bSRoderick Colenbrander #define DS4_INPUT_REPORT_GYRO_X_OFFSET 13 602cdc1c021SRoderick Colenbrander #define DS4_INPUT_REPORT_BATTERY_OFFSET 30 603cdc1c021SRoderick Colenbrander #define DS4_INPUT_REPORT_TOUCHPAD_OFFSET 33 604cdc1c021SRoderick Colenbrander 605227c011bSRoderick Colenbrander #define DS4_SENSOR_SUFFIX " Motion Sensors" 606ac797b95SRoderick Colenbrander #define DS4_TOUCHPAD_SUFFIX " Touchpad" 607ac797b95SRoderick Colenbrander 60855a07d62SRoderick Colenbrander #define DS4_GYRO_RES_PER_DEG_S 1024 60955a07d62SRoderick Colenbrander #define DS4_ACC_RES_PER_G 8192 61055a07d62SRoderick Colenbrander 6118b402c92SJiri Kosina static DEFINE_SPINLOCK(sony_dev_list_lock); 612d2d782fcSFrank Praznik static LIST_HEAD(sony_device_list); 6138025087aSFrank Praznik static DEFINE_IDA(sony_device_id_allocator); 614d2d782fcSFrank Praznik 61555a07d62SRoderick Colenbrander /* Used for calibration of DS4 accelerometer and gyro. */ 61655a07d62SRoderick Colenbrander struct ds4_calibration_data { 61755a07d62SRoderick Colenbrander int abs_code; 61855a07d62SRoderick Colenbrander short bias; 61955a07d62SRoderick Colenbrander /* Calibration requires scaling against a sensitivity value, which is a 62055a07d62SRoderick Colenbrander * float. Store sensitivity as a fraction to limit floating point 62155a07d62SRoderick Colenbrander * calculations until final calibration. 62255a07d62SRoderick Colenbrander */ 62355a07d62SRoderick Colenbrander int sens_numer; 62455a07d62SRoderick Colenbrander int sens_denom; 62555a07d62SRoderick Colenbrander }; 62655a07d62SRoderick Colenbrander 627f2f47c38SRoderick Colenbrander enum ds4_dongle_state { 628f2f47c38SRoderick Colenbrander DONGLE_DISCONNECTED, 629f2f47c38SRoderick Colenbrander DONGLE_CALIBRATING, 630f2f47c38SRoderick Colenbrander DONGLE_CONNECTED, 631f2f47c38SRoderick Colenbrander DONGLE_DISABLED 632f2f47c38SRoderick Colenbrander }; 633f2f47c38SRoderick Colenbrander 634b5322736SRoderick Colenbrander enum sony_worker { 635f2f47c38SRoderick Colenbrander SONY_WORKER_STATE, 636f2f47c38SRoderick Colenbrander SONY_WORKER_HOTPLUG 637b5322736SRoderick Colenbrander }; 638b5322736SRoderick Colenbrander 639cc6e0bbbSJiri Kosina struct sony_sc { 640d902f472SFrank Praznik spinlock_t lock; 641d2d782fcSFrank Praznik struct list_head list_node; 6420a286ef2SSven Eckelmann struct hid_device *hdev; 643ac797b95SRoderick Colenbrander struct input_dev *touchpad; 644227c011bSRoderick Colenbrander struct input_dev *sensor_dev; 64560781cf4SFrank Praznik struct led_classdev *leds[MAX_LEDS]; 646cc6e0bbbSJiri Kosina unsigned long quirks; 647f2f47c38SRoderick Colenbrander struct work_struct hotplug_worker; 6480a286ef2SSven Eckelmann struct work_struct state_worker; 649d8aaccdaSFrank Praznik void (*send_output_report)(struct sony_sc *); 650297d716fSKrzysztof Kozlowski struct power_supply *battery; 651297d716fSKrzysztof Kozlowski struct power_supply_desc battery_desc; 6528025087aSFrank Praznik int device_id; 6531adf904eSPavel Machek u8 *output_report_dmabuf; 654f04d5140SColin Leitner 6559f323b68SSven Eckelmann #ifdef CONFIG_SONY_FF 6561adf904eSPavel Machek u8 left; 6571adf904eSPavel Machek u8 right; 6589f323b68SSven Eckelmann #endif 6599f323b68SSven Eckelmann 6601adf904eSPavel Machek u8 mac_address[6]; 661f2f47c38SRoderick Colenbrander u8 hotplug_worker_initialized; 662b5322736SRoderick Colenbrander u8 state_worker_initialized; 6632a242932SFrank Praznik u8 defer_initialization; 6641adf904eSPavel Machek u8 cable_state; 6651adf904eSPavel Machek u8 battery_charging; 6661adf904eSPavel Machek u8 battery_capacity; 6671adf904eSPavel Machek u8 led_state[MAX_LEDS]; 6681adf904eSPavel Machek u8 led_delay_on[MAX_LEDS]; 6691adf904eSPavel Machek u8 led_delay_off[MAX_LEDS]; 6701adf904eSPavel Machek u8 led_count; 67180786eb9SRoderick Colenbrander 67280786eb9SRoderick Colenbrander bool timestamp_initialized; 67380786eb9SRoderick Colenbrander u16 prev_timestamp; 67480786eb9SRoderick Colenbrander unsigned int timestamp_us; 67580786eb9SRoderick Colenbrander 676f2f47c38SRoderick Colenbrander enum ds4_dongle_state ds4_dongle_state; 67755a07d62SRoderick Colenbrander /* DS4 calibration data */ 67855a07d62SRoderick Colenbrander struct ds4_calibration_data ds4_calib_data[6]; 679cc6e0bbbSJiri Kosina }; 680cc6e0bbbSJiri Kosina 681405182c2SRoderick Colenbrander static void sony_set_leds(struct sony_sc *sc); 682405182c2SRoderick Colenbrander 683b5322736SRoderick Colenbrander static inline void sony_schedule_work(struct sony_sc *sc, 684b5322736SRoderick Colenbrander enum sony_worker which) 6852a242932SFrank Praznik { 686b5322736SRoderick Colenbrander switch (which) { 687b5322736SRoderick Colenbrander case SONY_WORKER_STATE: 6882a242932SFrank Praznik if (!sc->defer_initialization) 6892a242932SFrank Praznik schedule_work(&sc->state_worker); 690f2f47c38SRoderick Colenbrander break; 691f2f47c38SRoderick Colenbrander case SONY_WORKER_HOTPLUG: 692f2f47c38SRoderick Colenbrander if (sc->hotplug_worker_initialized) 693f2f47c38SRoderick Colenbrander schedule_work(&sc->hotplug_worker); 694f2f47c38SRoderick Colenbrander break; 6952a242932SFrank Praznik } 696b5322736SRoderick Colenbrander } 6972a242932SFrank Praznik 6981adf904eSPavel Machek static u8 *sixaxis_fixup(struct hid_device *hdev, u8 *rdesc, 699c607fb8dSAntonio Ospite unsigned int *rsize) 700c607fb8dSAntonio Ospite { 701c607fb8dSAntonio Ospite *rsize = sizeof(sixaxis_rdesc); 702c607fb8dSAntonio Ospite return sixaxis_rdesc; 703c607fb8dSAntonio Ospite } 704c607fb8dSAntonio Ospite 705c5e0c1c4SFrank Praznik static u8 *motion_fixup(struct hid_device *hdev, u8 *rdesc, 706c5e0c1c4SFrank Praznik unsigned int *rsize) 707c5e0c1c4SFrank Praznik { 708c5e0c1c4SFrank Praznik *rsize = sizeof(motion_rdesc); 709c5e0c1c4SFrank Praznik return motion_rdesc; 710c5e0c1c4SFrank Praznik } 711c5e0c1c4SFrank Praznik 712b2723eb7SSimon Wood static u8 *navigation_fixup(struct hid_device *hdev, u8 *rdesc, 713b2723eb7SSimon Wood unsigned int *rsize) 714b2723eb7SSimon Wood { 715b2723eb7SSimon Wood *rsize = sizeof(navigation_rdesc); 716b2723eb7SSimon Wood return navigation_rdesc; 717b2723eb7SSimon Wood } 718b2723eb7SSimon Wood 7191adf904eSPavel Machek static u8 *ps3remote_fixup(struct hid_device *hdev, u8 *rdesc, 720078328daSJiri Kosina unsigned int *rsize) 721078328daSJiri Kosina { 722078328daSJiri Kosina *rsize = sizeof(ps3remote_rdesc); 723078328daSJiri Kosina return ps3remote_rdesc; 724078328daSJiri Kosina } 725078328daSJiri Kosina 726078328daSJiri Kosina static int ps3remote_mapping(struct hid_device *hdev, struct hid_input *hi, 727078328daSJiri Kosina struct hid_field *field, struct hid_usage *usage, 728078328daSJiri Kosina unsigned long **bit, int *max) 729078328daSJiri Kosina { 730078328daSJiri Kosina unsigned int key = usage->hid & HID_USAGE; 731078328daSJiri Kosina 732078328daSJiri Kosina if ((usage->hid & HID_USAGE_PAGE) != HID_UP_BUTTON) 733078328daSJiri Kosina return -1; 734078328daSJiri Kosina 735078328daSJiri Kosina switch (usage->collection_index) { 736078328daSJiri Kosina case 1: 737078328daSJiri Kosina if (key >= ARRAY_SIZE(ps3remote_keymap_joypad_buttons)) 738078328daSJiri Kosina return -1; 739078328daSJiri Kosina 740078328daSJiri Kosina key = ps3remote_keymap_joypad_buttons[key]; 741078328daSJiri Kosina if (!key) 742078328daSJiri Kosina return -1; 743078328daSJiri Kosina break; 744078328daSJiri Kosina case 2: 745078328daSJiri Kosina if (key >= ARRAY_SIZE(ps3remote_keymap_remote_buttons)) 746078328daSJiri Kosina return -1; 747078328daSJiri Kosina 748078328daSJiri Kosina key = ps3remote_keymap_remote_buttons[key]; 749078328daSJiri Kosina if (!key) 750078328daSJiri Kosina return -1; 751078328daSJiri Kosina break; 752078328daSJiri Kosina default: 753078328daSJiri Kosina return -1; 754078328daSJiri Kosina } 755078328daSJiri Kosina 756078328daSJiri Kosina hid_map_usage_clear(hi, usage, bit, max, EV_KEY, key); 757078328daSJiri Kosina return 1; 758078328daSJiri Kosina } 759078328daSJiri Kosina 7609131f8ccSRoderick Colenbrander static int ds4_mapping(struct hid_device *hdev, struct hid_input *hi, 7619131f8ccSRoderick Colenbrander struct hid_field *field, struct hid_usage *usage, 7629131f8ccSRoderick Colenbrander unsigned long **bit, int *max) 7639131f8ccSRoderick Colenbrander { 7649131f8ccSRoderick Colenbrander if ((usage->hid & HID_USAGE_PAGE) == HID_UP_BUTTON) { 7659131f8ccSRoderick Colenbrander unsigned int key = usage->hid & HID_USAGE; 7669131f8ccSRoderick Colenbrander 7679131f8ccSRoderick Colenbrander if (key >= ARRAY_SIZE(ds4_keymap)) 7689131f8ccSRoderick Colenbrander return -1; 7699131f8ccSRoderick Colenbrander 7709131f8ccSRoderick Colenbrander key = ds4_keymap[key]; 7719131f8ccSRoderick Colenbrander hid_map_usage_clear(hi, usage, bit, max, EV_KEY, key); 7729131f8ccSRoderick Colenbrander return 1; 7739131f8ccSRoderick Colenbrander } else if ((usage->hid & HID_USAGE_PAGE) == HID_UP_GENDESK) { 7749131f8ccSRoderick Colenbrander unsigned int abs = usage->hid & HID_USAGE; 7759131f8ccSRoderick Colenbrander 7769131f8ccSRoderick Colenbrander /* Let the HID parser deal with the HAT. */ 7779131f8ccSRoderick Colenbrander if (usage->hid == HID_GD_HATSWITCH) 7789131f8ccSRoderick Colenbrander return 0; 7799131f8ccSRoderick Colenbrander 7809131f8ccSRoderick Colenbrander if (abs >= ARRAY_SIZE(ds4_absmap)) 7819131f8ccSRoderick Colenbrander return -1; 7829131f8ccSRoderick Colenbrander 7839131f8ccSRoderick Colenbrander abs = ds4_absmap[abs]; 7849131f8ccSRoderick Colenbrander hid_map_usage_clear(hi, usage, bit, max, EV_ABS, abs); 7859131f8ccSRoderick Colenbrander return 1; 7869131f8ccSRoderick Colenbrander } 7879131f8ccSRoderick Colenbrander 7889131f8ccSRoderick Colenbrander return 0; 7899131f8ccSRoderick Colenbrander } 7909131f8ccSRoderick Colenbrander 7911adf904eSPavel Machek static u8 *sony_report_fixup(struct hid_device *hdev, u8 *rdesc, 79273e4008dSNikolai Kondrashov unsigned int *rsize) 793cc6e0bbbSJiri Kosina { 794cc6e0bbbSJiri Kosina struct sony_sc *sc = hid_get_drvdata(hdev); 795cc6e0bbbSJiri Kosina 7964ba1eeebSMikko Perttunen if (sc->quirks & (SINO_LITE_CONTROLLER | FUTUREMAX_DANCE_MAT)) 79774500cc8SScott Moreau return rdesc; 79874500cc8SScott Moreau 79999d24902SFernando Luis Vázquez Cao /* 80099d24902SFernando Luis Vázquez Cao * Some Sony RF receivers wrongly declare the mouse pointer as a 80199d24902SFernando Luis Vázquez Cao * a constant non-data variable. 80299d24902SFernando Luis Vázquez Cao */ 80399d24902SFernando Luis Vázquez Cao if ((sc->quirks & VAIO_RDESC_CONSTANT) && *rsize >= 56 && 80499d24902SFernando Luis Vázquez Cao /* usage page: generic desktop controls */ 80599d24902SFernando Luis Vázquez Cao /* rdesc[0] == 0x05 && rdesc[1] == 0x01 && */ 80699d24902SFernando Luis Vázquez Cao /* usage: mouse */ 80799d24902SFernando Luis Vázquez Cao rdesc[2] == 0x09 && rdesc[3] == 0x02 && 80899d24902SFernando Luis Vázquez Cao /* input (usage page for x,y axes): constant, variable, relative */ 80999d24902SFernando Luis Vázquez Cao rdesc[54] == 0x81 && rdesc[55] == 0x07) { 810a4649184SFernando Luis Vázquez Cao hid_info(hdev, "Fixing up Sony RF Receiver report descriptor\n"); 81199d24902SFernando Luis Vázquez Cao /* input: data, variable, relative */ 812cc6e0bbbSJiri Kosina rdesc[55] = 0x06; 813cc6e0bbbSJiri Kosina } 81461ab44beSSimon Wood 815c607fb8dSAntonio Ospite if (sc->quirks & SIXAXIS_CONTROLLER) 816c607fb8dSAntonio Ospite return sixaxis_fixup(hdev, rdesc, rsize); 817078328daSJiri Kosina 818c5e0c1c4SFrank Praznik if (sc->quirks & MOTION_CONTROLLER) 819c5e0c1c4SFrank Praznik return motion_fixup(hdev, rdesc, rsize); 820c5e0c1c4SFrank Praznik 8214545ee0aSSimon Wood if (sc->quirks & NAVIGATION_CONTROLLER) 822b2723eb7SSimon Wood return navigation_fixup(hdev, rdesc, rsize); 8234545ee0aSSimon Wood 824078328daSJiri Kosina if (sc->quirks & PS3REMOTE) 825078328daSJiri Kosina return ps3remote_fixup(hdev, rdesc, rsize); 826078328daSJiri Kosina 82773e4008dSNikolai Kondrashov return rdesc; 828cc6e0bbbSJiri Kosina } 829cc6e0bbbSJiri Kosina 8301adf904eSPavel Machek static void sixaxis_parse_report(struct sony_sc *sc, u8 *rd, int size) 831d902f472SFrank Praznik { 8321adf904eSPavel Machek static const u8 sixaxis_battery_capacity[] = { 0, 1, 25, 50, 75, 100 }; 833d902f472SFrank Praznik unsigned long flags; 83412e9a6d7SSimon Wood int offset; 8351adf904eSPavel Machek u8 cable_state, battery_capacity, battery_charging; 836d902f472SFrank Praznik 837ad142b9eSFrank Praznik /* 838ad142b9eSFrank Praznik * The sixaxis is charging if the battery value is 0xee 839d902f472SFrank Praznik * and it is fully charged if the value is 0xef. 840d902f472SFrank Praznik * It does not report the actual level while charging so it 841d902f472SFrank Praznik * is set to 100% while charging is in progress. 842d902f472SFrank Praznik */ 84312e9a6d7SSimon Wood offset = (sc->quirks & MOTION_CONTROLLER) ? 12 : 30; 84412e9a6d7SSimon Wood 84512e9a6d7SSimon Wood if (rd[offset] >= 0xee) { 846d902f472SFrank Praznik battery_capacity = 100; 84712e9a6d7SSimon Wood battery_charging = !(rd[offset] & 0x01); 8489fddd74aSFrank Praznik cable_state = 1; 849d902f472SFrank Praznik } else { 8501adf904eSPavel Machek u8 index = rd[offset] <= 5 ? rd[offset] : 5; 851ac3c9a94SFrank Praznik battery_capacity = sixaxis_battery_capacity[index]; 852d902f472SFrank Praznik battery_charging = 0; 8539fddd74aSFrank Praznik cable_state = 0; 854d902f472SFrank Praznik } 855d902f472SFrank Praznik 856d902f472SFrank Praznik spin_lock_irqsave(&sc->lock, flags); 857d902f472SFrank Praznik sc->cable_state = cable_state; 858d902f472SFrank Praznik sc->battery_capacity = battery_capacity; 859d902f472SFrank Praznik sc->battery_charging = battery_charging; 860d902f472SFrank Praznik spin_unlock_irqrestore(&sc->lock, flags); 861d902f472SFrank Praznik } 862d902f472SFrank Praznik 8631adf904eSPavel Machek static void dualshock4_parse_report(struct sony_sc *sc, u8 *rd, int size) 864d902f472SFrank Praznik { 865d03ae2e1SRoderick Colenbrander struct hid_input *hidinput = list_entry(sc->hdev->inputs.next, 866d03ae2e1SRoderick Colenbrander struct hid_input, list); 867d03ae2e1SRoderick Colenbrander struct input_dev *input_dev = hidinput->input; 868d902f472SFrank Praznik unsigned long flags; 869cdc1c021SRoderick Colenbrander int n, m, offset, num_touch_data, max_touch_data; 8701adf904eSPavel Machek u8 cable_state, battery_capacity, battery_charging; 87180786eb9SRoderick Colenbrander u16 timestamp; 872d902f472SFrank Praznik 873cdc1c021SRoderick Colenbrander /* When using Bluetooth the header is 2 bytes longer, so skip these. */ 87435f436c3SRoderick Colenbrander int data_offset = (sc->quirks & DUALSHOCK4_CONTROLLER_BT) ? 2 : 0; 8756c5f860dSFrank Praznik 876ac797b95SRoderick Colenbrander /* Second bit of third button byte is for the touchpad button. */ 877ac797b95SRoderick Colenbrander offset = data_offset + DS4_INPUT_REPORT_BUTTON_OFFSET; 878ac797b95SRoderick Colenbrander input_report_key(sc->touchpad, BTN_LEFT, rd[offset+2] & 0x2); 879ac797b95SRoderick Colenbrander 880d03ae2e1SRoderick Colenbrander /* 881d03ae2e1SRoderick Colenbrander * The default behavior of the Dualshock 4 is to send reports using 882d03ae2e1SRoderick Colenbrander * report type 1 when running over Bluetooth. However, when feature 883d03ae2e1SRoderick Colenbrander * report 2 is requested during the controller initialization it starts 884d03ae2e1SRoderick Colenbrander * sending input reports in report 17. Since report 17 is undefined 885d03ae2e1SRoderick Colenbrander * in the default HID descriptor, the HID layer won't generate events. 886d03ae2e1SRoderick Colenbrander * While it is possible (and this was done before) to fixup the HID 887d03ae2e1SRoderick Colenbrander * descriptor to add this mapping, it was better to do this manually. 888d03ae2e1SRoderick Colenbrander * The reason is there were various pieces software both open and closed 889d03ae2e1SRoderick Colenbrander * source, relying on the descriptors to be the same across various 890d03ae2e1SRoderick Colenbrander * operating systems. If the descriptors wouldn't match some 891d03ae2e1SRoderick Colenbrander * applications e.g. games on Wine would not be able to function due 892d03ae2e1SRoderick Colenbrander * to different descriptors, which such applications are not parsing. 893d03ae2e1SRoderick Colenbrander */ 894d03ae2e1SRoderick Colenbrander if (rd[0] == 17) { 895d03ae2e1SRoderick Colenbrander int value; 896d03ae2e1SRoderick Colenbrander 897d03ae2e1SRoderick Colenbrander offset = data_offset + DS4_INPUT_REPORT_AXIS_OFFSET; 898d03ae2e1SRoderick Colenbrander input_report_abs(input_dev, ABS_X, rd[offset]); 899d03ae2e1SRoderick Colenbrander input_report_abs(input_dev, ABS_Y, rd[offset+1]); 900d03ae2e1SRoderick Colenbrander input_report_abs(input_dev, ABS_RX, rd[offset+2]); 901d03ae2e1SRoderick Colenbrander input_report_abs(input_dev, ABS_RY, rd[offset+3]); 902d03ae2e1SRoderick Colenbrander 903d03ae2e1SRoderick Colenbrander value = rd[offset+4] & 0xf; 904d03ae2e1SRoderick Colenbrander if (value > 7) 905d03ae2e1SRoderick Colenbrander value = 8; /* Center 0, 0 */ 906d03ae2e1SRoderick Colenbrander input_report_abs(input_dev, ABS_HAT0X, ds4_hat_mapping[value].x); 907d03ae2e1SRoderick Colenbrander input_report_abs(input_dev, ABS_HAT0Y, ds4_hat_mapping[value].y); 908d03ae2e1SRoderick Colenbrander 909d03ae2e1SRoderick Colenbrander input_report_key(input_dev, BTN_WEST, rd[offset+4] & 0x10); 910d03ae2e1SRoderick Colenbrander input_report_key(input_dev, BTN_SOUTH, rd[offset+4] & 0x20); 911d03ae2e1SRoderick Colenbrander input_report_key(input_dev, BTN_EAST, rd[offset+4] & 0x40); 912d03ae2e1SRoderick Colenbrander input_report_key(input_dev, BTN_NORTH, rd[offset+4] & 0x80); 913d03ae2e1SRoderick Colenbrander 914d03ae2e1SRoderick Colenbrander input_report_key(input_dev, BTN_TL, rd[offset+5] & 0x1); 915d03ae2e1SRoderick Colenbrander input_report_key(input_dev, BTN_TR, rd[offset+5] & 0x2); 916d03ae2e1SRoderick Colenbrander input_report_key(input_dev, BTN_TL2, rd[offset+5] & 0x4); 917d03ae2e1SRoderick Colenbrander input_report_key(input_dev, BTN_TR2, rd[offset+5] & 0x8); 918d03ae2e1SRoderick Colenbrander input_report_key(input_dev, BTN_SELECT, rd[offset+5] & 0x10); 919d03ae2e1SRoderick Colenbrander input_report_key(input_dev, BTN_START, rd[offset+5] & 0x20); 920d03ae2e1SRoderick Colenbrander input_report_key(input_dev, BTN_THUMBL, rd[offset+5] & 0x40); 921d03ae2e1SRoderick Colenbrander input_report_key(input_dev, BTN_THUMBR, rd[offset+5] & 0x80); 922d03ae2e1SRoderick Colenbrander 923d03ae2e1SRoderick Colenbrander input_report_key(input_dev, BTN_MODE, rd[offset+6] & 0x1); 924d03ae2e1SRoderick Colenbrander 925d03ae2e1SRoderick Colenbrander input_report_abs(input_dev, ABS_Z, rd[offset+7]); 926d03ae2e1SRoderick Colenbrander input_report_abs(input_dev, ABS_RZ, rd[offset+8]); 927d03ae2e1SRoderick Colenbrander 928d03ae2e1SRoderick Colenbrander input_sync(input_dev); 929d03ae2e1SRoderick Colenbrander } 930d03ae2e1SRoderick Colenbrander 93180786eb9SRoderick Colenbrander /* Convert timestamp (in 5.33us unit) to timestamp_us */ 93280786eb9SRoderick Colenbrander offset = data_offset + DS4_INPUT_REPORT_TIMESTAMP_OFFSET; 93380786eb9SRoderick Colenbrander timestamp = get_unaligned_le16(&rd[offset]); 93480786eb9SRoderick Colenbrander if (!sc->timestamp_initialized) { 93580786eb9SRoderick Colenbrander sc->timestamp_us = ((unsigned int)timestamp * 16) / 3; 93680786eb9SRoderick Colenbrander sc->timestamp_initialized = true; 93780786eb9SRoderick Colenbrander } else { 93880786eb9SRoderick Colenbrander u16 delta; 93980786eb9SRoderick Colenbrander 94080786eb9SRoderick Colenbrander if (sc->prev_timestamp > timestamp) 94180786eb9SRoderick Colenbrander delta = (U16_MAX - sc->prev_timestamp + timestamp + 1); 94280786eb9SRoderick Colenbrander else 94380786eb9SRoderick Colenbrander delta = timestamp - sc->prev_timestamp; 94480786eb9SRoderick Colenbrander sc->timestamp_us += (delta * 16) / 3; 94580786eb9SRoderick Colenbrander } 94680786eb9SRoderick Colenbrander sc->prev_timestamp = timestamp; 94780786eb9SRoderick Colenbrander input_event(sc->sensor_dev, EV_MSC, MSC_TIMESTAMP, sc->timestamp_us); 94880786eb9SRoderick Colenbrander 949227c011bSRoderick Colenbrander offset = data_offset + DS4_INPUT_REPORT_GYRO_X_OFFSET; 95055a07d62SRoderick Colenbrander for (n = 0; n < 6; n++) { 95155a07d62SRoderick Colenbrander /* Store data in int for more precision during mult_frac. */ 95255a07d62SRoderick Colenbrander int raw_data = (short)((rd[offset+1] << 8) | rd[offset]); 95355a07d62SRoderick Colenbrander struct ds4_calibration_data *calib = &sc->ds4_calib_data[n]; 954227c011bSRoderick Colenbrander 95555a07d62SRoderick Colenbrander /* High precision is needed during calibration, but the 95655a07d62SRoderick Colenbrander * calibrated values are within 32-bit. 95755a07d62SRoderick Colenbrander * Note: we swap numerator 'x' and 'numer' in mult_frac for 95855a07d62SRoderick Colenbrander * precision reasons so we don't need 64-bit. 95955a07d62SRoderick Colenbrander */ 96055a07d62SRoderick Colenbrander int calib_data = mult_frac(calib->sens_numer, 96155a07d62SRoderick Colenbrander raw_data - calib->bias, 96255a07d62SRoderick Colenbrander calib->sens_denom); 96355a07d62SRoderick Colenbrander 96455a07d62SRoderick Colenbrander input_report_abs(sc->sensor_dev, calib->abs_code, calib_data); 96555a07d62SRoderick Colenbrander offset += 2; 966227c011bSRoderick Colenbrander } 967227c011bSRoderick Colenbrander input_sync(sc->sensor_dev); 968227c011bSRoderick Colenbrander 969ad142b9eSFrank Praznik /* 970cdc1c021SRoderick Colenbrander * The lower 4 bits of byte 30 (or 32 for BT) contain the battery level 971d902f472SFrank Praznik * and the 5th bit contains the USB cable state. 972d902f472SFrank Praznik */ 973cdc1c021SRoderick Colenbrander offset = data_offset + DS4_INPUT_REPORT_BATTERY_OFFSET; 9746c5f860dSFrank Praznik cable_state = (rd[offset] >> 4) & 0x01; 9756c5f860dSFrank Praznik battery_capacity = rd[offset] & 0x0F; 976d902f472SFrank Praznik 977ad142b9eSFrank Praznik /* 978ad142b9eSFrank Praznik * When a USB power source is connected the battery level ranges from 9796c5f860dSFrank Praznik * 0 to 10, and when running on battery power it ranges from 0 to 9. 9806c5f860dSFrank Praznik * A battery level above 10 when plugged in means charge completed. 981d902f472SFrank Praznik */ 9826c5f860dSFrank Praznik if (!cable_state || battery_capacity > 10) 983d902f472SFrank Praznik battery_charging = 0; 984d902f472SFrank Praznik else 985d902f472SFrank Praznik battery_charging = 1; 986d902f472SFrank Praznik 9876c5f860dSFrank Praznik if (!cable_state) 9886c5f860dSFrank Praznik battery_capacity++; 989d902f472SFrank Praznik if (battery_capacity > 10) 9906c5f860dSFrank Praznik battery_capacity = 10; 9916c5f860dSFrank Praznik 992d902f472SFrank Praznik battery_capacity *= 10; 993d902f472SFrank Praznik 994d902f472SFrank Praznik spin_lock_irqsave(&sc->lock, flags); 995d902f472SFrank Praznik sc->cable_state = cable_state; 996d902f472SFrank Praznik sc->battery_capacity = battery_capacity; 997d902f472SFrank Praznik sc->battery_charging = battery_charging; 998d902f472SFrank Praznik spin_unlock_irqrestore(&sc->lock, flags); 999e5606230SFrank Praznik 1000cdc1c021SRoderick Colenbrander /* 1001cdc1c021SRoderick Colenbrander * The Dualshock 4 multi-touch trackpad data starts at offset 33 on USB 1002cdc1c021SRoderick Colenbrander * and 35 on Bluetooth. 1003cdc1c021SRoderick Colenbrander * The first byte indicates the number of touch data in the report. 1004cdc1c021SRoderick Colenbrander * Trackpad data starts 2 bytes later (e.g. 35 for USB). 1005cdc1c021SRoderick Colenbrander */ 1006cdc1c021SRoderick Colenbrander offset = data_offset + DS4_INPUT_REPORT_TOUCHPAD_OFFSET; 100735f436c3SRoderick Colenbrander max_touch_data = (sc->quirks & DUALSHOCK4_CONTROLLER_BT) ? 4 : 3; 1008cdc1c021SRoderick Colenbrander if (rd[offset] > 0 && rd[offset] <= max_touch_data) 1009cdc1c021SRoderick Colenbrander num_touch_data = rd[offset]; 1010cdc1c021SRoderick Colenbrander else 1011cdc1c021SRoderick Colenbrander num_touch_data = 1; 1012cdc1c021SRoderick Colenbrander offset += 1; 1013cdc1c021SRoderick Colenbrander 1014cdc1c021SRoderick Colenbrander for (m = 0; m < num_touch_data; m++) { 1015cdc1c021SRoderick Colenbrander /* Skip past timestamp */ 1016cdc1c021SRoderick Colenbrander offset += 1; 10176c5f860dSFrank Praznik 1018ad142b9eSFrank Praznik /* 1019cdc1c021SRoderick Colenbrander * The first 7 bits of the first byte is a counter and bit 8 is 1020cdc1c021SRoderick Colenbrander * a touch indicator that is 0 when pressed and 1 when not 1021cdc1c021SRoderick Colenbrander * pressed. 1022e5606230SFrank Praznik * The next 3 bytes are two 12 bit touch coordinates, X and Y. 1023cdc1c021SRoderick Colenbrander * The data for the second touch is in the same format and 1024cdc1c021SRoderick Colenbrander * immediately follows the data for the first. 1025e5606230SFrank Praznik */ 1026e5606230SFrank Praznik for (n = 0; n < 2; n++) { 10271adf904eSPavel Machek u16 x, y; 1028cdc1c021SRoderick Colenbrander bool active; 1029e5606230SFrank Praznik 1030e5606230SFrank Praznik x = rd[offset+1] | ((rd[offset+2] & 0xF) << 8); 1031e5606230SFrank Praznik y = ((rd[offset+2] & 0xF0) >> 4) | (rd[offset+3] << 4); 1032e5606230SFrank Praznik 1033cdc1c021SRoderick Colenbrander active = !(rd[offset] >> 7); 1034ac797b95SRoderick Colenbrander input_mt_slot(sc->touchpad, n); 1035ac797b95SRoderick Colenbrander input_mt_report_slot_state(sc->touchpad, MT_TOOL_FINGER, active); 1036cdc1c021SRoderick Colenbrander 1037cdc1c021SRoderick Colenbrander if (active) { 1038ac797b95SRoderick Colenbrander input_report_abs(sc->touchpad, ABS_MT_POSITION_X, x); 1039ac797b95SRoderick Colenbrander input_report_abs(sc->touchpad, ABS_MT_POSITION_Y, y); 1040cdc1c021SRoderick Colenbrander } 1041e5606230SFrank Praznik 1042e5606230SFrank Praznik offset += 4; 1043e5606230SFrank Praznik } 1044ac797b95SRoderick Colenbrander input_mt_sync_frame(sc->touchpad); 1045ac797b95SRoderick Colenbrander input_sync(sc->touchpad); 1046cdc1c021SRoderick Colenbrander } 1047d902f472SFrank Praznik } 1048d902f472SFrank Praznik 1049c9e4d877SSimon Wood static int sony_raw_event(struct hid_device *hdev, struct hid_report *report, 10501adf904eSPavel Machek u8 *rd, int size) 1051c9e4d877SSimon Wood { 1052c9e4d877SSimon Wood struct sony_sc *sc = hid_get_drvdata(hdev); 1053c9e4d877SSimon Wood 1054ad142b9eSFrank Praznik /* 1055ad142b9eSFrank Praznik * Sixaxis HID report has acclerometers/gyro with MSByte first, this 1056c9e4d877SSimon Wood * has to be BYTE_SWAPPED before passing up to joystick interface 1057c9e4d877SSimon Wood */ 1058fee4e2d5SFrank Praznik if ((sc->quirks & SIXAXIS_CONTROLLER) && rd[0] == 0x01 && size == 49) { 10598f5f0bc2SFrank Praznik /* 10608f5f0bc2SFrank Praznik * When connected via Bluetooth the Sixaxis occasionally sends 10618f5f0bc2SFrank Praznik * a report with the second byte 0xff and the rest zeroed. 10628f5f0bc2SFrank Praznik * 10638f5f0bc2SFrank Praznik * This report does not reflect the actual state of the 10648f5f0bc2SFrank Praznik * controller must be ignored to avoid generating false input 10658f5f0bc2SFrank Praznik * events. 10668f5f0bc2SFrank Praznik */ 10678f5f0bc2SFrank Praznik if (rd[1] == 0xff) 10688f5f0bc2SFrank Praznik return -EINVAL; 10698f5f0bc2SFrank Praznik 1070c9e4d877SSimon Wood swap(rd[41], rd[42]); 1071c9e4d877SSimon Wood swap(rd[43], rd[44]); 1072c9e4d877SSimon Wood swap(rd[45], rd[46]); 1073c9e4d877SSimon Wood swap(rd[47], rd[48]); 1074d902f472SFrank Praznik 1075d902f472SFrank Praznik sixaxis_parse_report(sc, rd, size); 107612e9a6d7SSimon Wood } else if ((sc->quirks & MOTION_CONTROLLER_BT) && rd[0] == 0x01 && size == 49) { 107712e9a6d7SSimon Wood sixaxis_parse_report(sc, rd, size); 10784545ee0aSSimon Wood } else if ((sc->quirks & NAVIGATION_CONTROLLER) && rd[0] == 0x01 && 10794545ee0aSSimon Wood size == 49) { 10804545ee0aSSimon Wood sixaxis_parse_report(sc, rd, size); 108135f436c3SRoderick Colenbrander } else if ((sc->quirks & DUALSHOCK4_CONTROLLER_USB) && rd[0] == 0x01 && 108235f436c3SRoderick Colenbrander size == 64) { 108335f436c3SRoderick Colenbrander dualshock4_parse_report(sc, rd, size); 108435f436c3SRoderick Colenbrander } else if (((sc->quirks & DUALSHOCK4_CONTROLLER_BT) && rd[0] == 0x11 && 108535f436c3SRoderick Colenbrander size == 78)) { 108649b9ca6cSRoderick Colenbrander /* CRC check */ 108749b9ca6cSRoderick Colenbrander u8 bthdr = 0xA1; 108849b9ca6cSRoderick Colenbrander u32 crc; 108949b9ca6cSRoderick Colenbrander u32 report_crc; 109049b9ca6cSRoderick Colenbrander 109149b9ca6cSRoderick Colenbrander crc = crc32_le(0xFFFFFFFF, &bthdr, 1); 109249b9ca6cSRoderick Colenbrander crc = ~crc32_le(crc, rd, DS4_INPUT_REPORT_0x11_SIZE-4); 109349b9ca6cSRoderick Colenbrander report_crc = get_unaligned_le32(&rd[DS4_INPUT_REPORT_0x11_SIZE-4]); 109449b9ca6cSRoderick Colenbrander if (crc != report_crc) { 109549b9ca6cSRoderick Colenbrander hid_dbg(sc->hdev, "DualShock 4 input report's CRC check failed, received crc 0x%0x != 0x%0x\n", 109649b9ca6cSRoderick Colenbrander report_crc, crc); 109749b9ca6cSRoderick Colenbrander return -EILSEQ; 109849b9ca6cSRoderick Colenbrander } 1099405182c2SRoderick Colenbrander 110035f436c3SRoderick Colenbrander dualshock4_parse_report(sc, rd, size); 110135f436c3SRoderick Colenbrander } else if ((sc->quirks & DUALSHOCK4_DONGLE) && rd[0] == 0x01 && 110235f436c3SRoderick Colenbrander size == 64) { 1103f2f47c38SRoderick Colenbrander unsigned long flags; 1104f2f47c38SRoderick Colenbrander enum ds4_dongle_state dongle_state; 1105f2f47c38SRoderick Colenbrander 1106405182c2SRoderick Colenbrander /* 1107405182c2SRoderick Colenbrander * In the case of a DS4 USB dongle, bit[2] of byte 31 indicates 1108405182c2SRoderick Colenbrander * if a DS4 is actually connected (indicated by '0'). 1109405182c2SRoderick Colenbrander * For non-dongle, this bit is always 0 (connected). 1110405182c2SRoderick Colenbrander */ 1111405182c2SRoderick Colenbrander bool connected = (rd[31] & 0x04) ? false : true; 1112405182c2SRoderick Colenbrander 1113f2f47c38SRoderick Colenbrander spin_lock_irqsave(&sc->lock, flags); 1114f2f47c38SRoderick Colenbrander dongle_state = sc->ds4_dongle_state; 1115f2f47c38SRoderick Colenbrander spin_unlock_irqrestore(&sc->lock, flags); 1116f2f47c38SRoderick Colenbrander 1117f2f47c38SRoderick Colenbrander /* 1118f2f47c38SRoderick Colenbrander * The dongle always sends input reports even when no 1119f2f47c38SRoderick Colenbrander * DS4 is attached. When a DS4 is connected, we need to 1120f2f47c38SRoderick Colenbrander * obtain calibration data before we can use it. 1121f2f47c38SRoderick Colenbrander * The code below tracks dongle state and kicks of 1122f2f47c38SRoderick Colenbrander * calibration when needed and only allows us to process 1123f2f47c38SRoderick Colenbrander * input if a DS4 is actually connected. 1124f2f47c38SRoderick Colenbrander */ 1125f2f47c38SRoderick Colenbrander if (dongle_state == DONGLE_DISCONNECTED && connected) { 1126405182c2SRoderick Colenbrander hid_info(sc->hdev, "DualShock 4 USB dongle: controller connected\n"); 1127405182c2SRoderick Colenbrander sony_set_leds(sc); 1128f2f47c38SRoderick Colenbrander 1129f2f47c38SRoderick Colenbrander spin_lock_irqsave(&sc->lock, flags); 1130f2f47c38SRoderick Colenbrander sc->ds4_dongle_state = DONGLE_CALIBRATING; 1131f2f47c38SRoderick Colenbrander spin_unlock_irqrestore(&sc->lock, flags); 1132f2f47c38SRoderick Colenbrander 1133f2f47c38SRoderick Colenbrander sony_schedule_work(sc, SONY_WORKER_HOTPLUG); 1134f2f47c38SRoderick Colenbrander 1135f2f47c38SRoderick Colenbrander /* Don't process the report since we don't have 1136f2f47c38SRoderick Colenbrander * calibration data, but let hidraw have it anyway. 1137f2f47c38SRoderick Colenbrander */ 1138f2f47c38SRoderick Colenbrander return 0; 1139f2f47c38SRoderick Colenbrander } else if ((dongle_state == DONGLE_CONNECTED || 1140f2f47c38SRoderick Colenbrander dongle_state == DONGLE_DISABLED) && !connected) { 1141405182c2SRoderick Colenbrander hid_info(sc->hdev, "DualShock 4 USB dongle: controller disconnected\n"); 1142f2f47c38SRoderick Colenbrander 1143f2f47c38SRoderick Colenbrander spin_lock_irqsave(&sc->lock, flags); 1144f2f47c38SRoderick Colenbrander sc->ds4_dongle_state = DONGLE_DISCONNECTED; 1145f2f47c38SRoderick Colenbrander spin_unlock_irqrestore(&sc->lock, flags); 1146f2f47c38SRoderick Colenbrander 1147405182c2SRoderick Colenbrander /* Return 0, so hidraw can get the report. */ 1148405182c2SRoderick Colenbrander return 0; 1149f2f47c38SRoderick Colenbrander } else if (dongle_state == DONGLE_CALIBRATING || 1150f2f47c38SRoderick Colenbrander dongle_state == DONGLE_DISABLED || 1151f2f47c38SRoderick Colenbrander dongle_state == DONGLE_DISCONNECTED) { 1152405182c2SRoderick Colenbrander /* Return 0, so hidraw can get the report. */ 1153405182c2SRoderick Colenbrander return 0; 1154405182c2SRoderick Colenbrander } 1155405182c2SRoderick Colenbrander 1156d902f472SFrank Praznik dualshock4_parse_report(sc, rd, size); 1157c9e4d877SSimon Wood } 1158c9e4d877SSimon Wood 11592a242932SFrank Praznik if (sc->defer_initialization) { 11602a242932SFrank Praznik sc->defer_initialization = 0; 1161b5322736SRoderick Colenbrander sony_schedule_work(sc, SONY_WORKER_STATE); 11622a242932SFrank Praznik } 11632a242932SFrank Praznik 1164c9e4d877SSimon Wood return 0; 1165c9e4d877SSimon Wood } 1166c9e4d877SSimon Wood 1167f04d5140SColin Leitner static int sony_mapping(struct hid_device *hdev, struct hid_input *hi, 1168f04d5140SColin Leitner struct hid_field *field, struct hid_usage *usage, 1169f04d5140SColin Leitner unsigned long **bit, int *max) 1170f04d5140SColin Leitner { 1171f04d5140SColin Leitner struct sony_sc *sc = hid_get_drvdata(hdev); 1172f04d5140SColin Leitner 1173f04d5140SColin Leitner if (sc->quirks & BUZZ_CONTROLLER) { 1174f04d5140SColin Leitner unsigned int key = usage->hid & HID_USAGE; 1175f04d5140SColin Leitner 1176f04d5140SColin Leitner if ((usage->hid & HID_USAGE_PAGE) != HID_UP_BUTTON) 1177f04d5140SColin Leitner return -1; 1178f04d5140SColin Leitner 1179f04d5140SColin Leitner switch (usage->collection_index) { 1180f04d5140SColin Leitner case 1: 1181f04d5140SColin Leitner if (key >= ARRAY_SIZE(buzz_keymap)) 1182f04d5140SColin Leitner return -1; 1183f04d5140SColin Leitner 1184f04d5140SColin Leitner key = buzz_keymap[key]; 1185f04d5140SColin Leitner if (!key) 1186f04d5140SColin Leitner return -1; 1187f04d5140SColin Leitner break; 1188f04d5140SColin Leitner default: 1189f04d5140SColin Leitner return -1; 1190f04d5140SColin Leitner } 1191f04d5140SColin Leitner 1192f04d5140SColin Leitner hid_map_usage_clear(hi, usage, bit, max, EV_KEY, key); 1193f04d5140SColin Leitner return 1; 1194f04d5140SColin Leitner } 1195f04d5140SColin Leitner 1196078328daSJiri Kosina if (sc->quirks & PS3REMOTE) 1197078328daSJiri Kosina return ps3remote_mapping(hdev, hi, field, usage, bit, max); 1198078328daSJiri Kosina 11999131f8ccSRoderick Colenbrander 12009131f8ccSRoderick Colenbrander if (sc->quirks & DUALSHOCK4_CONTROLLER) 12019131f8ccSRoderick Colenbrander return ds4_mapping(hdev, hi, field, usage, bit, max); 12029131f8ccSRoderick Colenbrander 12036f498018SBenjamin Tissoires /* Let hid-core decide for the others */ 12046f498018SBenjamin Tissoires return 0; 1205f04d5140SColin Leitner } 1206f04d5140SColin Leitner 1207ac797b95SRoderick Colenbrander static int sony_register_touchpad(struct sony_sc *sc, int touch_count, 1208ce8efc3bSFrank Praznik int w, int h) 1209ce8efc3bSFrank Praznik { 1210ac797b95SRoderick Colenbrander size_t name_sz; 1211ac797b95SRoderick Colenbrander char *name; 1212ce8efc3bSFrank Praznik int ret; 1213ce8efc3bSFrank Praznik 1214ac797b95SRoderick Colenbrander sc->touchpad = input_allocate_device(); 1215ac797b95SRoderick Colenbrander if (!sc->touchpad) 1216ac797b95SRoderick Colenbrander return -ENOMEM; 1217ce8efc3bSFrank Praznik 1218ac797b95SRoderick Colenbrander input_set_drvdata(sc->touchpad, sc); 1219ac797b95SRoderick Colenbrander sc->touchpad->dev.parent = &sc->hdev->dev; 1220ac797b95SRoderick Colenbrander sc->touchpad->phys = sc->hdev->phys; 1221ac797b95SRoderick Colenbrander sc->touchpad->uniq = sc->hdev->uniq; 1222ac797b95SRoderick Colenbrander sc->touchpad->id.bustype = sc->hdev->bus; 1223ac797b95SRoderick Colenbrander sc->touchpad->id.vendor = sc->hdev->vendor; 1224ac797b95SRoderick Colenbrander sc->touchpad->id.product = sc->hdev->product; 1225ac797b95SRoderick Colenbrander sc->touchpad->id.version = sc->hdev->version; 1226ac797b95SRoderick Colenbrander 1227ac797b95SRoderick Colenbrander /* Append a suffix to the controller name as there are various 1228ac797b95SRoderick Colenbrander * DS4 compatible non-Sony devices with different names. 1229ac797b95SRoderick Colenbrander */ 1230ac797b95SRoderick Colenbrander name_sz = strlen(sc->hdev->name) + sizeof(DS4_TOUCHPAD_SUFFIX); 1231ac797b95SRoderick Colenbrander name = kzalloc(name_sz, GFP_KERNEL); 1232ac797b95SRoderick Colenbrander if (!name) { 1233ac797b95SRoderick Colenbrander ret = -ENOMEM; 1234ac797b95SRoderick Colenbrander goto err; 1235ac797b95SRoderick Colenbrander } 1236ac797b95SRoderick Colenbrander snprintf(name, name_sz, "%s" DS4_TOUCHPAD_SUFFIX, sc->hdev->name); 1237ac797b95SRoderick Colenbrander sc->touchpad->name = name; 1238ac797b95SRoderick Colenbrander 1239*b9f7d245SRoderick Colenbrander ret = input_mt_init_slots(sc->touchpad, touch_count, INPUT_MT_POINTER); 1240ac797b95SRoderick Colenbrander if (ret < 0) 1241ac797b95SRoderick Colenbrander goto err; 1242ac797b95SRoderick Colenbrander 1243ac797b95SRoderick Colenbrander /* We map the button underneath the touchpad to BTN_LEFT. */ 1244ac797b95SRoderick Colenbrander __set_bit(EV_KEY, sc->touchpad->evbit); 1245ac797b95SRoderick Colenbrander __set_bit(BTN_LEFT, sc->touchpad->keybit); 1246ac797b95SRoderick Colenbrander __set_bit(INPUT_PROP_BUTTONPAD, sc->touchpad->propbit); 1247ac797b95SRoderick Colenbrander 1248ac797b95SRoderick Colenbrander input_set_abs_params(sc->touchpad, ABS_MT_POSITION_X, 0, w, 0, 0); 1249ac797b95SRoderick Colenbrander input_set_abs_params(sc->touchpad, ABS_MT_POSITION_Y, 0, h, 0, 0); 1250ac797b95SRoderick Colenbrander 1251ac797b95SRoderick Colenbrander ret = input_register_device(sc->touchpad); 1252ac797b95SRoderick Colenbrander if (ret < 0) 1253ac797b95SRoderick Colenbrander goto err; 1254ce8efc3bSFrank Praznik 1255ce8efc3bSFrank Praznik return 0; 1256ac797b95SRoderick Colenbrander 1257ac797b95SRoderick Colenbrander err: 1258ac797b95SRoderick Colenbrander kfree(sc->touchpad->name); 1259ac797b95SRoderick Colenbrander sc->touchpad->name = NULL; 1260ac797b95SRoderick Colenbrander 1261ac797b95SRoderick Colenbrander input_free_device(sc->touchpad); 1262ac797b95SRoderick Colenbrander sc->touchpad = NULL; 1263ac797b95SRoderick Colenbrander 1264ac797b95SRoderick Colenbrander return ret; 1265ce8efc3bSFrank Praznik } 1266ce8efc3bSFrank Praznik 1267ac797b95SRoderick Colenbrander static void sony_unregister_touchpad(struct sony_sc *sc) 1268ac797b95SRoderick Colenbrander { 1269ac797b95SRoderick Colenbrander if (!sc->touchpad) 1270ac797b95SRoderick Colenbrander return; 1271ac797b95SRoderick Colenbrander 1272ac797b95SRoderick Colenbrander kfree(sc->touchpad->name); 1273ac797b95SRoderick Colenbrander sc->touchpad->name = NULL; 1274ac797b95SRoderick Colenbrander 1275ac797b95SRoderick Colenbrander input_unregister_device(sc->touchpad); 1276ac797b95SRoderick Colenbrander sc->touchpad = NULL; 1277ac797b95SRoderick Colenbrander } 12789154301aSDmitry Torokhov 1279227c011bSRoderick Colenbrander static int sony_register_sensors(struct sony_sc *sc) 1280227c011bSRoderick Colenbrander { 1281227c011bSRoderick Colenbrander size_t name_sz; 1282227c011bSRoderick Colenbrander char *name; 1283227c011bSRoderick Colenbrander int ret; 128455a07d62SRoderick Colenbrander int range; 1285227c011bSRoderick Colenbrander 1286227c011bSRoderick Colenbrander sc->sensor_dev = input_allocate_device(); 1287227c011bSRoderick Colenbrander if (!sc->sensor_dev) 1288227c011bSRoderick Colenbrander return -ENOMEM; 1289227c011bSRoderick Colenbrander 1290227c011bSRoderick Colenbrander input_set_drvdata(sc->sensor_dev, sc); 1291227c011bSRoderick Colenbrander sc->sensor_dev->dev.parent = &sc->hdev->dev; 1292227c011bSRoderick Colenbrander sc->sensor_dev->phys = sc->hdev->phys; 1293227c011bSRoderick Colenbrander sc->sensor_dev->uniq = sc->hdev->uniq; 1294227c011bSRoderick Colenbrander sc->sensor_dev->id.bustype = sc->hdev->bus; 1295227c011bSRoderick Colenbrander sc->sensor_dev->id.vendor = sc->hdev->vendor; 1296227c011bSRoderick Colenbrander sc->sensor_dev->id.product = sc->hdev->product; 1297227c011bSRoderick Colenbrander sc->sensor_dev->id.version = sc->hdev->version; 1298227c011bSRoderick Colenbrander 1299227c011bSRoderick Colenbrander /* Append a suffix to the controller name as there are various 1300227c011bSRoderick Colenbrander * DS4 compatible non-Sony devices with different names. 1301227c011bSRoderick Colenbrander */ 1302227c011bSRoderick Colenbrander name_sz = strlen(sc->hdev->name) + sizeof(DS4_SENSOR_SUFFIX); 1303227c011bSRoderick Colenbrander name = kzalloc(name_sz, GFP_KERNEL); 1304227c011bSRoderick Colenbrander if (!name) { 1305227c011bSRoderick Colenbrander ret = -ENOMEM; 1306227c011bSRoderick Colenbrander goto err; 1307227c011bSRoderick Colenbrander } 1308227c011bSRoderick Colenbrander snprintf(name, name_sz, "%s" DS4_SENSOR_SUFFIX, sc->hdev->name); 1309227c011bSRoderick Colenbrander sc->sensor_dev->name = name; 1310227c011bSRoderick Colenbrander 131155a07d62SRoderick Colenbrander range = DS4_ACC_RES_PER_G*4; 131255a07d62SRoderick Colenbrander input_set_abs_params(sc->sensor_dev, ABS_X, -range, range, 16, 0); 131355a07d62SRoderick Colenbrander input_set_abs_params(sc->sensor_dev, ABS_Y, -range, range, 16, 0); 131455a07d62SRoderick Colenbrander input_set_abs_params(sc->sensor_dev, ABS_Z, -range, range, 16, 0); 131555a07d62SRoderick Colenbrander input_abs_set_res(sc->sensor_dev, ABS_X, DS4_ACC_RES_PER_G); 131655a07d62SRoderick Colenbrander input_abs_set_res(sc->sensor_dev, ABS_Y, DS4_ACC_RES_PER_G); 131755a07d62SRoderick Colenbrander input_abs_set_res(sc->sensor_dev, ABS_Z, DS4_ACC_RES_PER_G); 1318227c011bSRoderick Colenbrander 131955a07d62SRoderick Colenbrander range = DS4_GYRO_RES_PER_DEG_S*2048; 132055a07d62SRoderick Colenbrander input_set_abs_params(sc->sensor_dev, ABS_RX, -range, range, 16, 0); 132155a07d62SRoderick Colenbrander input_set_abs_params(sc->sensor_dev, ABS_RY, -range, range, 16, 0); 132255a07d62SRoderick Colenbrander input_set_abs_params(sc->sensor_dev, ABS_RZ, -range, range, 16, 0); 132355a07d62SRoderick Colenbrander input_abs_set_res(sc->sensor_dev, ABS_RX, DS4_GYRO_RES_PER_DEG_S); 132455a07d62SRoderick Colenbrander input_abs_set_res(sc->sensor_dev, ABS_RY, DS4_GYRO_RES_PER_DEG_S); 132555a07d62SRoderick Colenbrander input_abs_set_res(sc->sensor_dev, ABS_RZ, DS4_GYRO_RES_PER_DEG_S); 1326227c011bSRoderick Colenbrander 132780786eb9SRoderick Colenbrander __set_bit(EV_MSC, sc->sensor_dev->evbit); 132880786eb9SRoderick Colenbrander __set_bit(MSC_TIMESTAMP, sc->sensor_dev->mscbit); 1329227c011bSRoderick Colenbrander __set_bit(INPUT_PROP_ACCELEROMETER, sc->sensor_dev->propbit); 1330227c011bSRoderick Colenbrander 1331227c011bSRoderick Colenbrander ret = input_register_device(sc->sensor_dev); 1332227c011bSRoderick Colenbrander if (ret < 0) 1333227c011bSRoderick Colenbrander goto err; 1334227c011bSRoderick Colenbrander 1335227c011bSRoderick Colenbrander return 0; 1336227c011bSRoderick Colenbrander 1337227c011bSRoderick Colenbrander err: 1338227c011bSRoderick Colenbrander kfree(sc->sensor_dev->name); 1339227c011bSRoderick Colenbrander sc->sensor_dev->name = NULL; 1340227c011bSRoderick Colenbrander 1341227c011bSRoderick Colenbrander input_free_device(sc->sensor_dev); 1342227c011bSRoderick Colenbrander sc->sensor_dev = NULL; 1343227c011bSRoderick Colenbrander 1344227c011bSRoderick Colenbrander return ret; 1345227c011bSRoderick Colenbrander } 1346227c011bSRoderick Colenbrander 1347227c011bSRoderick Colenbrander static void sony_unregister_sensors(struct sony_sc *sc) 1348227c011bSRoderick Colenbrander { 1349227c011bSRoderick Colenbrander if (!sc->sensor_dev) 1350227c011bSRoderick Colenbrander return; 1351227c011bSRoderick Colenbrander 1352227c011bSRoderick Colenbrander kfree(sc->sensor_dev->name); 1353227c011bSRoderick Colenbrander sc->sensor_dev->name = NULL; 1354227c011bSRoderick Colenbrander 1355227c011bSRoderick Colenbrander input_unregister_device(sc->sensor_dev); 1356227c011bSRoderick Colenbrander sc->sensor_dev = NULL; 1357227c011bSRoderick Colenbrander } 1358227c011bSRoderick Colenbrander 1359227c011bSRoderick Colenbrander 13605710fabfSAntonio Ospite /* 1361bd28ce00SJiri Slaby * Sending HID_REQ_GET_REPORT changes the operation mode of the ps3 controller 1362bd28ce00SJiri Slaby * to "operational". Without this, the ps3 controller will not report any 1363bd28ce00SJiri Slaby * events. 1364bd28ce00SJiri Slaby */ 1365816651a7SAntonio Ospite static int sixaxis_set_operational_usb(struct hid_device *hdev) 1366bd28ce00SJiri Slaby { 1367a85d67b5SAntonio Ospite const int buf_size = 1368a85d67b5SAntonio Ospite max(SIXAXIS_REPORT_0xF2_SIZE, SIXAXIS_REPORT_0xF5_SIZE); 13691adf904eSPavel Machek u8 *buf; 1370bd28ce00SJiri Slaby int ret; 1371bd28ce00SJiri Slaby 13722e701a35SAntonio Ospite buf = kmalloc(buf_size, GFP_KERNEL); 1373bd28ce00SJiri Slaby if (!buf) 1374bd28ce00SJiri Slaby return -ENOMEM; 1375bd28ce00SJiri Slaby 1376a85d67b5SAntonio Ospite ret = hid_hw_raw_request(hdev, 0xf2, buf, SIXAXIS_REPORT_0xF2_SIZE, 1377a85d67b5SAntonio Ospite HID_FEATURE_REPORT, HID_REQ_GET_REPORT); 1378a7de9b86SLauri Kasanen if (ret < 0) { 1379a7de9b86SLauri Kasanen hid_err(hdev, "can't set operational mode: step 1\n"); 1380a7de9b86SLauri Kasanen goto out; 1381a7de9b86SLauri Kasanen } 1382f204828aSBenjamin Tissoires 1383a7de9b86SLauri Kasanen /* 1384a7de9b86SLauri Kasanen * Some compatible controllers like the Speedlink Strike FX and 1385a7de9b86SLauri Kasanen * Gasia need another query plus an USB interrupt to get operational. 1386a7de9b86SLauri Kasanen */ 1387a85d67b5SAntonio Ospite ret = hid_hw_raw_request(hdev, 0xf5, buf, SIXAXIS_REPORT_0xF5_SIZE, 1388a85d67b5SAntonio Ospite HID_FEATURE_REPORT, HID_REQ_GET_REPORT); 1389a7de9b86SLauri Kasanen if (ret < 0) { 1390a7de9b86SLauri Kasanen hid_err(hdev, "can't set operational mode: step 2\n"); 1391a7de9b86SLauri Kasanen goto out; 1392a7de9b86SLauri Kasanen } 1393a7de9b86SLauri Kasanen 1394a7de9b86SLauri Kasanen ret = hid_hw_output_report(hdev, buf, 1); 139519f4c2baSBenjamin Tissoires if (ret < 0) { 139619f4c2baSBenjamin Tissoires hid_info(hdev, "can't set operational mode: step 3, ignoring\n"); 139719f4c2baSBenjamin Tissoires ret = 0; 139819f4c2baSBenjamin Tissoires } 1399bd28ce00SJiri Slaby 1400a7de9b86SLauri Kasanen out: 1401bd28ce00SJiri Slaby kfree(buf); 1402bd28ce00SJiri Slaby 1403bd28ce00SJiri Slaby return ret; 1404bd28ce00SJiri Slaby } 1405bd28ce00SJiri Slaby 1406816651a7SAntonio Ospite static int sixaxis_set_operational_bt(struct hid_device *hdev) 1407f9ce7c28SBastien Nocera { 14081adf904eSPavel Machek static const u8 report[] = { 0xf4, 0x42, 0x03, 0x00, 0x00 }; 14091adf904eSPavel Machek u8 *buf; 14109b2b5c9aSFrank Praznik int ret; 14119b2b5c9aSFrank Praznik 14129b2b5c9aSFrank Praznik buf = kmemdup(report, sizeof(report), GFP_KERNEL); 14139b2b5c9aSFrank Praznik if (!buf) 14149b2b5c9aSFrank Praznik return -ENOMEM; 14159b2b5c9aSFrank Praznik 14169b2b5c9aSFrank Praznik ret = hid_hw_raw_request(hdev, buf[0], buf, sizeof(report), 1417b0dd72aaSBenjamin Tissoires HID_FEATURE_REPORT, HID_REQ_SET_REPORT); 14189b2b5c9aSFrank Praznik 14199b2b5c9aSFrank Praznik kfree(buf); 14209b2b5c9aSFrank Praznik 14219b2b5c9aSFrank Praznik return ret; 1422f9ce7c28SBastien Nocera } 1423f9ce7c28SBastien Nocera 1424ad142b9eSFrank Praznik /* 142555a07d62SRoderick Colenbrander * Request DS4 calibration data for the motion sensors. 142655a07d62SRoderick Colenbrander * For Bluetooth this also affects the operating mode (see below). 142768330d83SFrank Praznik */ 142855a07d62SRoderick Colenbrander static int dualshock4_get_calibration_data(struct sony_sc *sc) 142968330d83SFrank Praznik { 14301adf904eSPavel Machek u8 *buf; 14319b2b5c9aSFrank Praznik int ret; 143255a07d62SRoderick Colenbrander short gyro_pitch_bias, gyro_pitch_plus, gyro_pitch_minus; 143355a07d62SRoderick Colenbrander short gyro_yaw_bias, gyro_yaw_plus, gyro_yaw_minus; 143455a07d62SRoderick Colenbrander short gyro_roll_bias, gyro_roll_plus, gyro_roll_minus; 143555a07d62SRoderick Colenbrander short gyro_speed_plus, gyro_speed_minus; 143655a07d62SRoderick Colenbrander short acc_x_plus, acc_x_minus; 143755a07d62SRoderick Colenbrander short acc_y_plus, acc_y_minus; 143855a07d62SRoderick Colenbrander short acc_z_plus, acc_z_minus; 143955a07d62SRoderick Colenbrander int speed_2x; 144055a07d62SRoderick Colenbrander int range_2g; 144168330d83SFrank Praznik 144255a07d62SRoderick Colenbrander /* For Bluetooth we use a different request, which supports CRC. 144355a07d62SRoderick Colenbrander * Note: in Bluetooth mode feature report 0x02 also changes the state 144455a07d62SRoderick Colenbrander * of the controller, so that it sends input reports of type 0x11. 144555a07d62SRoderick Colenbrander */ 144635f436c3SRoderick Colenbrander if (sc->quirks & (DUALSHOCK4_CONTROLLER_USB | DUALSHOCK4_DONGLE)) { 14472c159de0SRoderick Colenbrander buf = kmalloc(DS4_FEATURE_REPORT_0x02_SIZE, GFP_KERNEL); 14489b2b5c9aSFrank Praznik if (!buf) 14499b2b5c9aSFrank Praznik return -ENOMEM; 14509b2b5c9aSFrank Praznik 145155a07d62SRoderick Colenbrander ret = hid_hw_raw_request(sc->hdev, 0x02, buf, 145255a07d62SRoderick Colenbrander DS4_FEATURE_REPORT_0x02_SIZE, 145355a07d62SRoderick Colenbrander HID_FEATURE_REPORT, 145455a07d62SRoderick Colenbrander HID_REQ_GET_REPORT); 145555a07d62SRoderick Colenbrander if (ret < 0) 145655a07d62SRoderick Colenbrander goto err_stop; 145755a07d62SRoderick Colenbrander } else { 145855a07d62SRoderick Colenbrander u8 bthdr = 0xA3; 145955a07d62SRoderick Colenbrander u32 crc; 146055a07d62SRoderick Colenbrander u32 report_crc; 146155a07d62SRoderick Colenbrander int retries; 14629b2b5c9aSFrank Praznik 146355a07d62SRoderick Colenbrander buf = kmalloc(DS4_FEATURE_REPORT_0x05_SIZE, GFP_KERNEL); 146455a07d62SRoderick Colenbrander if (!buf) 146555a07d62SRoderick Colenbrander return -ENOMEM; 146655a07d62SRoderick Colenbrander 146755a07d62SRoderick Colenbrander for (retries = 0; retries < 3; retries++) { 146855a07d62SRoderick Colenbrander ret = hid_hw_raw_request(sc->hdev, 0x05, buf, 146955a07d62SRoderick Colenbrander DS4_FEATURE_REPORT_0x05_SIZE, 147055a07d62SRoderick Colenbrander HID_FEATURE_REPORT, 147155a07d62SRoderick Colenbrander HID_REQ_GET_REPORT); 147255a07d62SRoderick Colenbrander if (ret < 0) 147355a07d62SRoderick Colenbrander goto err_stop; 147455a07d62SRoderick Colenbrander 147555a07d62SRoderick Colenbrander /* CRC check */ 147655a07d62SRoderick Colenbrander crc = crc32_le(0xFFFFFFFF, &bthdr, 1); 147755a07d62SRoderick Colenbrander crc = ~crc32_le(crc, buf, DS4_FEATURE_REPORT_0x05_SIZE-4); 147855a07d62SRoderick Colenbrander report_crc = get_unaligned_le32(&buf[DS4_FEATURE_REPORT_0x05_SIZE-4]); 147955a07d62SRoderick Colenbrander if (crc != report_crc) { 148055a07d62SRoderick Colenbrander hid_warn(sc->hdev, "DualShock 4 calibration report's CRC check failed, received crc 0x%0x != 0x%0x\n", 148155a07d62SRoderick Colenbrander report_crc, crc); 148255a07d62SRoderick Colenbrander if (retries < 2) { 148355a07d62SRoderick Colenbrander hid_warn(sc->hdev, "Retrying DualShock 4 get calibration report request\n"); 148455a07d62SRoderick Colenbrander continue; 148555a07d62SRoderick Colenbrander } else { 148655a07d62SRoderick Colenbrander ret = -EILSEQ; 148755a07d62SRoderick Colenbrander goto err_stop; 148855a07d62SRoderick Colenbrander } 148955a07d62SRoderick Colenbrander } else { 149055a07d62SRoderick Colenbrander break; 149155a07d62SRoderick Colenbrander } 149255a07d62SRoderick Colenbrander } 149355a07d62SRoderick Colenbrander } 149455a07d62SRoderick Colenbrander 149555a07d62SRoderick Colenbrander gyro_pitch_bias = get_unaligned_le16(&buf[1]); 149655a07d62SRoderick Colenbrander gyro_yaw_bias = get_unaligned_le16(&buf[3]); 149755a07d62SRoderick Colenbrander gyro_roll_bias = get_unaligned_le16(&buf[5]); 149855a07d62SRoderick Colenbrander if (sc->quirks & DUALSHOCK4_CONTROLLER_USB) { 149955a07d62SRoderick Colenbrander gyro_pitch_plus = get_unaligned_le16(&buf[7]); 150055a07d62SRoderick Colenbrander gyro_pitch_minus = get_unaligned_le16(&buf[9]); 150155a07d62SRoderick Colenbrander gyro_yaw_plus = get_unaligned_le16(&buf[11]); 150255a07d62SRoderick Colenbrander gyro_yaw_minus = get_unaligned_le16(&buf[13]); 150355a07d62SRoderick Colenbrander gyro_roll_plus = get_unaligned_le16(&buf[15]); 150455a07d62SRoderick Colenbrander gyro_roll_minus = get_unaligned_le16(&buf[17]); 150555a07d62SRoderick Colenbrander } else { 150635f436c3SRoderick Colenbrander /* BT + Dongle */ 150755a07d62SRoderick Colenbrander gyro_pitch_plus = get_unaligned_le16(&buf[7]); 150855a07d62SRoderick Colenbrander gyro_yaw_plus = get_unaligned_le16(&buf[9]); 150955a07d62SRoderick Colenbrander gyro_roll_plus = get_unaligned_le16(&buf[11]); 151055a07d62SRoderick Colenbrander gyro_pitch_minus = get_unaligned_le16(&buf[13]); 151155a07d62SRoderick Colenbrander gyro_yaw_minus = get_unaligned_le16(&buf[15]); 151255a07d62SRoderick Colenbrander gyro_roll_minus = get_unaligned_le16(&buf[17]); 151355a07d62SRoderick Colenbrander } 151455a07d62SRoderick Colenbrander gyro_speed_plus = get_unaligned_le16(&buf[19]); 151555a07d62SRoderick Colenbrander gyro_speed_minus = get_unaligned_le16(&buf[21]); 151655a07d62SRoderick Colenbrander acc_x_plus = get_unaligned_le16(&buf[23]); 151755a07d62SRoderick Colenbrander acc_x_minus = get_unaligned_le16(&buf[25]); 151855a07d62SRoderick Colenbrander acc_y_plus = get_unaligned_le16(&buf[27]); 151955a07d62SRoderick Colenbrander acc_y_minus = get_unaligned_le16(&buf[29]); 152055a07d62SRoderick Colenbrander acc_z_plus = get_unaligned_le16(&buf[31]); 152155a07d62SRoderick Colenbrander acc_z_minus = get_unaligned_le16(&buf[33]); 152255a07d62SRoderick Colenbrander 152355a07d62SRoderick Colenbrander /* Set gyroscope calibration and normalization parameters. 152455a07d62SRoderick Colenbrander * Data values will be normalized to 1/DS4_GYRO_RES_PER_DEG_S degree/s. 152555a07d62SRoderick Colenbrander */ 152655a07d62SRoderick Colenbrander speed_2x = (gyro_speed_plus + gyro_speed_minus); 152755a07d62SRoderick Colenbrander sc->ds4_calib_data[0].abs_code = ABS_RX; 152855a07d62SRoderick Colenbrander sc->ds4_calib_data[0].bias = gyro_pitch_bias; 152955a07d62SRoderick Colenbrander sc->ds4_calib_data[0].sens_numer = speed_2x*DS4_GYRO_RES_PER_DEG_S; 153055a07d62SRoderick Colenbrander sc->ds4_calib_data[0].sens_denom = gyro_pitch_plus - gyro_pitch_minus; 153155a07d62SRoderick Colenbrander 153255a07d62SRoderick Colenbrander sc->ds4_calib_data[1].abs_code = ABS_RY; 153355a07d62SRoderick Colenbrander sc->ds4_calib_data[1].bias = gyro_yaw_bias; 153455a07d62SRoderick Colenbrander sc->ds4_calib_data[1].sens_numer = speed_2x*DS4_GYRO_RES_PER_DEG_S; 153555a07d62SRoderick Colenbrander sc->ds4_calib_data[1].sens_denom = gyro_yaw_plus - gyro_yaw_minus; 153655a07d62SRoderick Colenbrander 153755a07d62SRoderick Colenbrander sc->ds4_calib_data[2].abs_code = ABS_RZ; 153855a07d62SRoderick Colenbrander sc->ds4_calib_data[2].bias = gyro_roll_bias; 153955a07d62SRoderick Colenbrander sc->ds4_calib_data[2].sens_numer = speed_2x*DS4_GYRO_RES_PER_DEG_S; 154055a07d62SRoderick Colenbrander sc->ds4_calib_data[2].sens_denom = gyro_roll_plus - gyro_roll_minus; 154155a07d62SRoderick Colenbrander 154255a07d62SRoderick Colenbrander /* Set accelerometer calibration and normalization parameters. 154355a07d62SRoderick Colenbrander * Data values will be normalized to 1/DS4_ACC_RES_PER_G G. 154455a07d62SRoderick Colenbrander */ 154555a07d62SRoderick Colenbrander range_2g = acc_x_plus - acc_x_minus; 154655a07d62SRoderick Colenbrander sc->ds4_calib_data[3].abs_code = ABS_X; 154755a07d62SRoderick Colenbrander sc->ds4_calib_data[3].bias = acc_x_plus - range_2g / 2; 154855a07d62SRoderick Colenbrander sc->ds4_calib_data[3].sens_numer = 2*DS4_ACC_RES_PER_G; 154955a07d62SRoderick Colenbrander sc->ds4_calib_data[3].sens_denom = range_2g; 155055a07d62SRoderick Colenbrander 155155a07d62SRoderick Colenbrander range_2g = acc_y_plus - acc_y_minus; 155255a07d62SRoderick Colenbrander sc->ds4_calib_data[4].abs_code = ABS_Y; 155355a07d62SRoderick Colenbrander sc->ds4_calib_data[4].bias = acc_y_plus - range_2g / 2; 155455a07d62SRoderick Colenbrander sc->ds4_calib_data[4].sens_numer = 2*DS4_ACC_RES_PER_G; 155555a07d62SRoderick Colenbrander sc->ds4_calib_data[4].sens_denom = range_2g; 155655a07d62SRoderick Colenbrander 155755a07d62SRoderick Colenbrander range_2g = acc_z_plus - acc_z_minus; 155855a07d62SRoderick Colenbrander sc->ds4_calib_data[5].abs_code = ABS_Z; 155955a07d62SRoderick Colenbrander sc->ds4_calib_data[5].bias = acc_z_plus - range_2g / 2; 156055a07d62SRoderick Colenbrander sc->ds4_calib_data[5].sens_numer = 2*DS4_ACC_RES_PER_G; 156155a07d62SRoderick Colenbrander sc->ds4_calib_data[5].sens_denom = range_2g; 156255a07d62SRoderick Colenbrander 156355a07d62SRoderick Colenbrander err_stop: 15649b2b5c9aSFrank Praznik kfree(buf); 15659b2b5c9aSFrank Praznik return ret; 1566bd28ce00SJiri Slaby } 1567bd28ce00SJiri Slaby 1568f2f47c38SRoderick Colenbrander static void dualshock4_calibration_work(struct work_struct *work) 1569f2f47c38SRoderick Colenbrander { 1570f2f47c38SRoderick Colenbrander struct sony_sc *sc = container_of(work, struct sony_sc, hotplug_worker); 1571f2f47c38SRoderick Colenbrander unsigned long flags; 1572f2f47c38SRoderick Colenbrander enum ds4_dongle_state dongle_state; 1573f2f47c38SRoderick Colenbrander int ret; 1574f2f47c38SRoderick Colenbrander 1575f2f47c38SRoderick Colenbrander ret = dualshock4_get_calibration_data(sc); 1576f2f47c38SRoderick Colenbrander if (ret < 0) { 1577f2f47c38SRoderick Colenbrander /* This call is very unlikely to fail for the dongle. When it 1578f2f47c38SRoderick Colenbrander * fails we are probably in a very bad state, so mark the 1579f2f47c38SRoderick Colenbrander * dongle as disabled. We will re-enable the dongle if a new 1580f2f47c38SRoderick Colenbrander * DS4 hotplug is detect from sony_raw_event as any issues 1581f2f47c38SRoderick Colenbrander * are likely resolved then (the dongle is quite stupid). 1582f2f47c38SRoderick Colenbrander */ 1583f2f47c38SRoderick Colenbrander hid_err(sc->hdev, "DualShock 4 USB dongle: calibration failed, disabling device\n"); 1584f2f47c38SRoderick Colenbrander dongle_state = DONGLE_DISABLED; 1585f2f47c38SRoderick Colenbrander } else { 1586f2f47c38SRoderick Colenbrander hid_info(sc->hdev, "DualShock 4 USB dongle: calibration completed\n"); 1587f2f47c38SRoderick Colenbrander dongle_state = DONGLE_CONNECTED; 1588f2f47c38SRoderick Colenbrander } 1589f2f47c38SRoderick Colenbrander 1590f2f47c38SRoderick Colenbrander spin_lock_irqsave(&sc->lock, flags); 1591f2f47c38SRoderick Colenbrander sc->ds4_dongle_state = dongle_state; 1592f2f47c38SRoderick Colenbrander spin_unlock_irqrestore(&sc->lock, flags); 1593f2f47c38SRoderick Colenbrander } 1594f2f47c38SRoderick Colenbrander 1595221399b3SFrank Praznik static void sixaxis_set_leds_from_id(struct sony_sc *sc) 15968025087aSFrank Praznik { 15971adf904eSPavel Machek static const u8 sixaxis_leds[10][4] = { 15988025087aSFrank Praznik { 0x01, 0x00, 0x00, 0x00 }, 15998025087aSFrank Praznik { 0x00, 0x01, 0x00, 0x00 }, 16008025087aSFrank Praznik { 0x00, 0x00, 0x01, 0x00 }, 16018025087aSFrank Praznik { 0x00, 0x00, 0x00, 0x01 }, 16028025087aSFrank Praznik { 0x01, 0x00, 0x00, 0x01 }, 16038025087aSFrank Praznik { 0x00, 0x01, 0x00, 0x01 }, 16048025087aSFrank Praznik { 0x00, 0x00, 0x01, 0x01 }, 16058025087aSFrank Praznik { 0x01, 0x00, 0x01, 0x01 }, 16068025087aSFrank Praznik { 0x00, 0x01, 0x01, 0x01 }, 16078025087aSFrank Praznik { 0x01, 0x01, 0x01, 0x01 } 16088025087aSFrank Praznik }; 16098025087aSFrank Praznik 1610221399b3SFrank Praznik int id = sc->device_id; 1611221399b3SFrank Praznik 1612221399b3SFrank Praznik BUILD_BUG_ON(MAX_LEDS < ARRAY_SIZE(sixaxis_leds[0])); 16138025087aSFrank Praznik 16148025087aSFrank Praznik if (id < 0) 16158025087aSFrank Praznik return; 16168025087aSFrank Praznik 16178025087aSFrank Praznik id %= 10; 1618221399b3SFrank Praznik memcpy(sc->led_state, sixaxis_leds[id], sizeof(sixaxis_leds[id])); 16198025087aSFrank Praznik } 16208025087aSFrank Praznik 1621221399b3SFrank Praznik static void dualshock4_set_leds_from_id(struct sony_sc *sc) 16228025087aSFrank Praznik { 16238025087aSFrank Praznik /* The first 4 color/index entries match what the PS4 assigns */ 16241adf904eSPavel Machek static const u8 color_code[7][3] = { 16258025087aSFrank Praznik /* Blue */ { 0x00, 0x00, 0x01 }, 16268025087aSFrank Praznik /* Red */ { 0x01, 0x00, 0x00 }, 16278025087aSFrank Praznik /* Green */ { 0x00, 0x01, 0x00 }, 16288025087aSFrank Praznik /* Pink */ { 0x02, 0x00, 0x01 }, 16298025087aSFrank Praznik /* Orange */ { 0x02, 0x01, 0x00 }, 16308025087aSFrank Praznik /* Teal */ { 0x00, 0x01, 0x01 }, 16318025087aSFrank Praznik /* White */ { 0x01, 0x01, 0x01 } 16328025087aSFrank Praznik }; 16338025087aSFrank Praznik 1634221399b3SFrank Praznik int id = sc->device_id; 1635221399b3SFrank Praznik 1636221399b3SFrank Praznik BUILD_BUG_ON(MAX_LEDS < ARRAY_SIZE(color_code[0])); 16378025087aSFrank Praznik 16388025087aSFrank Praznik if (id < 0) 16398025087aSFrank Praznik return; 16408025087aSFrank Praznik 16418025087aSFrank Praznik id %= 7; 1642221399b3SFrank Praznik memcpy(sc->led_state, color_code[id], sizeof(color_code[id])); 16438025087aSFrank Praznik } 16448025087aSFrank Praznik 1645221399b3SFrank Praznik static void buzz_set_leds(struct sony_sc *sc) 1646f04d5140SColin Leitner { 1647221399b3SFrank Praznik struct hid_device *hdev = sc->hdev; 1648f04d5140SColin Leitner struct list_head *report_list = 1649f04d5140SColin Leitner &hdev->report_enum[HID_OUTPUT_REPORT].report_list; 1650f04d5140SColin Leitner struct hid_report *report = list_entry(report_list->next, 1651f04d5140SColin Leitner struct hid_report, list); 16521adf904eSPavel Machek s32 *value = report->field[0]->value; 1653f04d5140SColin Leitner 1654221399b3SFrank Praznik BUILD_BUG_ON(MAX_LEDS < 4); 1655221399b3SFrank Praznik 1656f04d5140SColin Leitner value[0] = 0x00; 1657221399b3SFrank Praznik value[1] = sc->led_state[0] ? 0xff : 0x00; 1658221399b3SFrank Praznik value[2] = sc->led_state[1] ? 0xff : 0x00; 1659221399b3SFrank Praznik value[3] = sc->led_state[2] ? 0xff : 0x00; 1660221399b3SFrank Praznik value[4] = sc->led_state[3] ? 0xff : 0x00; 1661f04d5140SColin Leitner value[5] = 0x00; 1662f04d5140SColin Leitner value[6] = 0x00; 1663f04d5140SColin Leitner hid_hw_request(hdev, report, HID_REQ_SET_REPORT); 1664f04d5140SColin Leitner } 1665f04d5140SColin Leitner 1666221399b3SFrank Praznik static void sony_set_leds(struct sony_sc *sc) 16670a286ef2SSven Eckelmann { 1668221399b3SFrank Praznik if (!(sc->quirks & BUZZ_CONTROLLER)) 1669b5322736SRoderick Colenbrander sony_schedule_work(sc, SONY_WORKER_STATE); 1670221399b3SFrank Praznik else 1671221399b3SFrank Praznik buzz_set_leds(sc); 16720a286ef2SSven Eckelmann } 16730a286ef2SSven Eckelmann 1674c5382519SSven Eckelmann static void sony_led_set_brightness(struct led_classdev *led, 1675f04d5140SColin Leitner enum led_brightness value) 1676f04d5140SColin Leitner { 1677f04d5140SColin Leitner struct device *dev = led->dev->parent; 1678ee79a8f8SGeliang Tang struct hid_device *hdev = to_hid_device(dev); 1679f04d5140SColin Leitner struct sony_sc *drv_data; 1680f04d5140SColin Leitner 1681f04d5140SColin Leitner int n; 1682b3ed458cSFrank Praznik int force_update; 1683f04d5140SColin Leitner 1684f04d5140SColin Leitner drv_data = hid_get_drvdata(hdev); 16852251b85fSSven Eckelmann if (!drv_data) { 1686f04d5140SColin Leitner hid_err(hdev, "No device data\n"); 1687f04d5140SColin Leitner return; 1688f04d5140SColin Leitner } 1689f04d5140SColin Leitner 1690b3ed458cSFrank Praznik /* 1691b3ed458cSFrank Praznik * The Sixaxis on USB will override any LED settings sent to it 1692b3ed458cSFrank Praznik * and keep flashing all of the LEDs until the PS button is pressed. 1693b3ed458cSFrank Praznik * Updates, even if redundant, must be always be sent to the 1694b3ed458cSFrank Praznik * controller to avoid having to toggle the state of an LED just to 1695b3ed458cSFrank Praznik * stop the flashing later on. 1696b3ed458cSFrank Praznik */ 1697b3ed458cSFrank Praznik force_update = !!(drv_data->quirks & SIXAXIS_CONTROLLER_USB); 1698b3ed458cSFrank Praznik 169960781cf4SFrank Praznik for (n = 0; n < drv_data->led_count; n++) { 1700b3ed458cSFrank Praznik if (led == drv_data->leds[n] && (force_update || 1701b3ed458cSFrank Praznik (value != drv_data->led_state[n] || 1702b3ed458cSFrank Praznik drv_data->led_delay_on[n] || 1703b3ed458cSFrank Praznik drv_data->led_delay_off[n]))) { 1704b3ed458cSFrank Praznik 170560781cf4SFrank Praznik drv_data->led_state[n] = value; 1706b3ed458cSFrank Praznik 1707b3ed458cSFrank Praznik /* Setting the brightness stops the blinking */ 1708b3ed458cSFrank Praznik drv_data->led_delay_on[n] = 0; 1709b3ed458cSFrank Praznik drv_data->led_delay_off[n] = 0; 1710b3ed458cSFrank Praznik 1711221399b3SFrank Praznik sony_set_leds(drv_data); 1712f04d5140SColin Leitner break; 1713f04d5140SColin Leitner } 1714f04d5140SColin Leitner } 1715f04d5140SColin Leitner } 1716f04d5140SColin Leitner 1717c5382519SSven Eckelmann static enum led_brightness sony_led_get_brightness(struct led_classdev *led) 1718f04d5140SColin Leitner { 1719f04d5140SColin Leitner struct device *dev = led->dev->parent; 1720ee79a8f8SGeliang Tang struct hid_device *hdev = to_hid_device(dev); 1721f04d5140SColin Leitner struct sony_sc *drv_data; 1722f04d5140SColin Leitner 1723f04d5140SColin Leitner int n; 1724f04d5140SColin Leitner 1725f04d5140SColin Leitner drv_data = hid_get_drvdata(hdev); 17262251b85fSSven Eckelmann if (!drv_data) { 1727f04d5140SColin Leitner hid_err(hdev, "No device data\n"); 1728f04d5140SColin Leitner return LED_OFF; 1729f04d5140SColin Leitner } 1730f04d5140SColin Leitner 173160781cf4SFrank Praznik for (n = 0; n < drv_data->led_count; n++) { 17327db7504aSSimon Wood if (led == drv_data->leds[n]) 17337db7504aSSimon Wood return drv_data->led_state[n]; 1734f04d5140SColin Leitner } 1735f04d5140SColin Leitner 17367db7504aSSimon Wood return LED_OFF; 1737f04d5140SColin Leitner } 1738f04d5140SColin Leitner 1739b3ed458cSFrank Praznik static int sony_led_blink_set(struct led_classdev *led, unsigned long *delay_on, 1740b3ed458cSFrank Praznik unsigned long *delay_off) 1741b3ed458cSFrank Praznik { 1742b3ed458cSFrank Praznik struct device *dev = led->dev->parent; 1743ee79a8f8SGeliang Tang struct hid_device *hdev = to_hid_device(dev); 1744b3ed458cSFrank Praznik struct sony_sc *drv_data = hid_get_drvdata(hdev); 1745b3ed458cSFrank Praznik int n; 17461adf904eSPavel Machek u8 new_on, new_off; 1747b3ed458cSFrank Praznik 1748b3ed458cSFrank Praznik if (!drv_data) { 1749b3ed458cSFrank Praznik hid_err(hdev, "No device data\n"); 1750b3ed458cSFrank Praznik return -EINVAL; 1751b3ed458cSFrank Praznik } 1752b3ed458cSFrank Praznik 1753b3ed458cSFrank Praznik /* Max delay is 255 deciseconds or 2550 milliseconds */ 1754b3ed458cSFrank Praznik if (*delay_on > 2550) 1755b3ed458cSFrank Praznik *delay_on = 2550; 1756b3ed458cSFrank Praznik if (*delay_off > 2550) 1757b3ed458cSFrank Praznik *delay_off = 2550; 1758b3ed458cSFrank Praznik 1759b3ed458cSFrank Praznik /* Blink at 1 Hz if both values are zero */ 1760b3ed458cSFrank Praznik if (!*delay_on && !*delay_off) 1761b3ed458cSFrank Praznik *delay_on = *delay_off = 500; 1762b3ed458cSFrank Praznik 1763b3ed458cSFrank Praznik new_on = *delay_on / 10; 1764b3ed458cSFrank Praznik new_off = *delay_off / 10; 1765b3ed458cSFrank Praznik 1766b3ed458cSFrank Praznik for (n = 0; n < drv_data->led_count; n++) { 1767b3ed458cSFrank Praznik if (led == drv_data->leds[n]) 1768b3ed458cSFrank Praznik break; 1769b3ed458cSFrank Praznik } 1770b3ed458cSFrank Praznik 1771b3ed458cSFrank Praznik /* This LED is not registered on this device */ 1772b3ed458cSFrank Praznik if (n >= drv_data->led_count) 1773b3ed458cSFrank Praznik return -EINVAL; 1774b3ed458cSFrank Praznik 1775b3ed458cSFrank Praznik /* Don't schedule work if the values didn't change */ 1776b3ed458cSFrank Praznik if (new_on != drv_data->led_delay_on[n] || 1777b3ed458cSFrank Praznik new_off != drv_data->led_delay_off[n]) { 1778b3ed458cSFrank Praznik drv_data->led_delay_on[n] = new_on; 1779b3ed458cSFrank Praznik drv_data->led_delay_off[n] = new_off; 1780b5322736SRoderick Colenbrander sony_schedule_work(drv_data, SONY_WORKER_STATE); 1781b3ed458cSFrank Praznik } 1782b3ed458cSFrank Praznik 1783b3ed458cSFrank Praznik return 0; 1784b3ed458cSFrank Praznik } 1785b3ed458cSFrank Praznik 1786fa57a810SFrank Praznik static void sony_leds_remove(struct sony_sc *sc) 17870a286ef2SSven Eckelmann { 17880a286ef2SSven Eckelmann struct led_classdev *led; 17890a286ef2SSven Eckelmann int n; 17900a286ef2SSven Eckelmann 1791fa57a810SFrank Praznik BUG_ON(!(sc->quirks & SONY_LED_SUPPORT)); 17920a286ef2SSven Eckelmann 1793fa57a810SFrank Praznik for (n = 0; n < sc->led_count; n++) { 1794fa57a810SFrank Praznik led = sc->leds[n]; 1795fa57a810SFrank Praznik sc->leds[n] = NULL; 17960a286ef2SSven Eckelmann if (!led) 17970a286ef2SSven Eckelmann continue; 17980a286ef2SSven Eckelmann led_classdev_unregister(led); 17990a286ef2SSven Eckelmann kfree(led); 18000a286ef2SSven Eckelmann } 180160781cf4SFrank Praznik 1802fa57a810SFrank Praznik sc->led_count = 0; 18030a286ef2SSven Eckelmann } 18040a286ef2SSven Eckelmann 1805fa57a810SFrank Praznik static int sony_leds_init(struct sony_sc *sc) 1806f04d5140SColin Leitner { 1807fa57a810SFrank Praznik struct hid_device *hdev = sc->hdev; 180840e32ee6SJiri Kosina int n, ret = 0; 1809b3ed458cSFrank Praznik int use_ds4_names; 181040e32ee6SJiri Kosina struct led_classdev *led; 181140e32ee6SJiri Kosina size_t name_sz; 181240e32ee6SJiri Kosina char *name; 18130a286ef2SSven Eckelmann size_t name_len; 18140a286ef2SSven Eckelmann const char *name_fmt; 1815b3ed458cSFrank Praznik static const char * const ds4_name_str[] = { "red", "green", "blue", 1816b3ed458cSFrank Praznik "global" }; 18171adf904eSPavel Machek u8 max_brightness[MAX_LEDS] = { [0 ... (MAX_LEDS - 1)] = 1 }; 18181adf904eSPavel Machek u8 use_hw_blink[MAX_LEDS] = { 0 }; 1819f04d5140SColin Leitner 1820fa57a810SFrank Praznik BUG_ON(!(sc->quirks & SONY_LED_SUPPORT)); 1821f04d5140SColin Leitner 1822fa57a810SFrank Praznik if (sc->quirks & BUZZ_CONTROLLER) { 1823fa57a810SFrank Praznik sc->led_count = 4; 1824b3ed458cSFrank Praznik use_ds4_names = 0; 18250a286ef2SSven Eckelmann name_len = strlen("::buzz#"); 18260a286ef2SSven Eckelmann name_fmt = "%s::buzz%d"; 18279446edb9SKees Cook /* Validate expected report characteristics. */ 18289446edb9SKees Cook if (!hid_validate_values(hdev, HID_OUTPUT_REPORT, 0, 0, 7)) 18299446edb9SKees Cook return -ENODEV; 1830fa57a810SFrank Praznik } else if (sc->quirks & DUALSHOCK4_CONTROLLER) { 1831221399b3SFrank Praznik dualshock4_set_leds_from_id(sc); 1832221399b3SFrank Praznik sc->led_state[3] = 1; 1833b3ed458cSFrank Praznik sc->led_count = 4; 1834b3ed458cSFrank Praznik memset(max_brightness, 255, 3); 1835b3ed458cSFrank Praznik use_hw_blink[3] = 1; 1836b3ed458cSFrank Praznik use_ds4_names = 1; 183761ebca93SFrank Praznik name_len = 0; 183861ebca93SFrank Praznik name_fmt = "%s:%s"; 1839c5e0c1c4SFrank Praznik } else if (sc->quirks & MOTION_CONTROLLER) { 1840c5e0c1c4SFrank Praznik sc->led_count = 3; 1841c5e0c1c4SFrank Praznik memset(max_brightness, 255, 3); 1842c5e0c1c4SFrank Praznik use_ds4_names = 1; 1843c5e0c1c4SFrank Praznik name_len = 0; 1844c5e0c1c4SFrank Praznik name_fmt = "%s:%s"; 18454545ee0aSSimon Wood } else if (sc->quirks & NAVIGATION_CONTROLLER) { 18461adf904eSPavel Machek static const u8 navigation_leds[4] = {0x01, 0x00, 0x00, 0x00}; 18474545ee0aSSimon Wood 18484545ee0aSSimon Wood memcpy(sc->led_state, navigation_leds, sizeof(navigation_leds)); 18494545ee0aSSimon Wood sc->led_count = 1; 18504545ee0aSSimon Wood memset(use_hw_blink, 1, 4); 18514545ee0aSSimon Wood use_ds4_names = 0; 18524545ee0aSSimon Wood name_len = strlen("::sony#"); 18534545ee0aSSimon Wood name_fmt = "%s::sony%d"; 185460781cf4SFrank Praznik } else { 1855221399b3SFrank Praznik sixaxis_set_leds_from_id(sc); 1856fa57a810SFrank Praznik sc->led_count = 4; 1857b3ed458cSFrank Praznik memset(use_hw_blink, 1, 4); 1858b3ed458cSFrank Praznik use_ds4_names = 0; 185961ebca93SFrank Praznik name_len = strlen("::sony#"); 186061ebca93SFrank Praznik name_fmt = "%s::sony%d"; 186160781cf4SFrank Praznik } 186260781cf4SFrank Praznik 1863ad142b9eSFrank Praznik /* 1864ad142b9eSFrank Praznik * Clear LEDs as we have no way of reading their initial state. This is 1865f04d5140SColin Leitner * only relevant if the driver is loaded after somebody actively set the 1866ad142b9eSFrank Praznik * LEDs to on 1867ad142b9eSFrank Praznik */ 1868221399b3SFrank Praznik sony_set_leds(sc); 1869f04d5140SColin Leitner 18700a286ef2SSven Eckelmann name_sz = strlen(dev_name(&hdev->dev)) + name_len + 1; 1871f04d5140SColin Leitner 1872fa57a810SFrank Praznik for (n = 0; n < sc->led_count; n++) { 187361ebca93SFrank Praznik 1874b3ed458cSFrank Praznik if (use_ds4_names) 1875b3ed458cSFrank Praznik name_sz = strlen(dev_name(&hdev->dev)) + strlen(ds4_name_str[n]) + 2; 187661ebca93SFrank Praznik 1877f04d5140SColin Leitner led = kzalloc(sizeof(struct led_classdev) + name_sz, GFP_KERNEL); 1878f04d5140SColin Leitner if (!led) { 1879f04d5140SColin Leitner hid_err(hdev, "Couldn't allocate memory for LED %d\n", n); 18808cd5fcdaSJulia Lawall ret = -ENOMEM; 1881f04d5140SColin Leitner goto error_leds; 1882f04d5140SColin Leitner } 1883f04d5140SColin Leitner 1884f04d5140SColin Leitner name = (void *)(&led[1]); 1885b3ed458cSFrank Praznik if (use_ds4_names) 1886b3ed458cSFrank Praznik snprintf(name, name_sz, name_fmt, dev_name(&hdev->dev), 1887b3ed458cSFrank Praznik ds4_name_str[n]); 188861ebca93SFrank Praznik else 18890a286ef2SSven Eckelmann snprintf(name, name_sz, name_fmt, dev_name(&hdev->dev), n + 1); 1890f04d5140SColin Leitner led->name = name; 1891221399b3SFrank Praznik led->brightness = sc->led_state[n]; 1892b3ed458cSFrank Praznik led->max_brightness = max_brightness[n]; 1893765a1077SFrank Praznik led->flags = LED_CORE_SUSPENDRESUME; 1894c5382519SSven Eckelmann led->brightness_get = sony_led_get_brightness; 1895c5382519SSven Eckelmann led->brightness_set = sony_led_set_brightness; 1896f04d5140SColin Leitner 1897b3ed458cSFrank Praznik if (use_hw_blink[n]) 1898b3ed458cSFrank Praznik led->blink_set = sony_led_blink_set; 1899b3ed458cSFrank Praznik 19008025087aSFrank Praznik sc->leds[n] = led; 19018025087aSFrank Praznik 19028cd5fcdaSJulia Lawall ret = led_classdev_register(&hdev->dev, led); 19038cd5fcdaSJulia Lawall if (ret) { 1904f04d5140SColin Leitner hid_err(hdev, "Failed to register LED %d\n", n); 19058025087aSFrank Praznik sc->leds[n] = NULL; 1906f04d5140SColin Leitner kfree(led); 1907f04d5140SColin Leitner goto error_leds; 1908f04d5140SColin Leitner } 1909f04d5140SColin Leitner } 1910f04d5140SColin Leitner 1911f04d5140SColin Leitner return ret; 1912f04d5140SColin Leitner 1913f04d5140SColin Leitner error_leds: 1914fa57a810SFrank Praznik sony_leds_remove(sc); 1915f04d5140SColin Leitner 1916f04d5140SColin Leitner return ret; 1917f04d5140SColin Leitner } 1918f04d5140SColin Leitner 1919d8aaccdaSFrank Praznik static void sixaxis_send_output_report(struct sony_sc *sc) 1920a08c22c0SSven Eckelmann { 19219b2b5c9aSFrank Praznik static const union sixaxis_output_report_01 default_report = { 192255d3b664SFrank Praznik .buf = { 1923a08c22c0SSven Eckelmann 0x01, 1924ad07b7a6SScott Moreau 0x01, 0xff, 0x00, 0xff, 0x00, 19250a286ef2SSven Eckelmann 0x00, 0x00, 0x00, 0x00, 0x00, 1926a08c22c0SSven Eckelmann 0xff, 0x27, 0x10, 0x00, 0x32, 1927a08c22c0SSven Eckelmann 0xff, 0x27, 0x10, 0x00, 0x32, 1928a08c22c0SSven Eckelmann 0xff, 0x27, 0x10, 0x00, 0x32, 1929a08c22c0SSven Eckelmann 0xff, 0x27, 0x10, 0x00, 0x32, 1930a08c22c0SSven Eckelmann 0x00, 0x00, 0x00, 0x00, 0x00 193155d3b664SFrank Praznik } 1932a08c22c0SSven Eckelmann }; 19339b2b5c9aSFrank Praznik struct sixaxis_output_report *report = 19349b2b5c9aSFrank Praznik (struct sixaxis_output_report *)sc->output_report_dmabuf; 19359b2b5c9aSFrank Praznik int n; 19369b2b5c9aSFrank Praznik 19379b2b5c9aSFrank Praznik /* Initialize the report with default values */ 19389b2b5c9aSFrank Praznik memcpy(report, &default_report, sizeof(struct sixaxis_output_report)); 19399f323b68SSven Eckelmann 19400a286ef2SSven Eckelmann #ifdef CONFIG_SONY_FF 19419b2b5c9aSFrank Praznik report->rumble.right_motor_on = sc->right ? 1 : 0; 19429b2b5c9aSFrank Praznik report->rumble.left_motor_force = sc->left; 19430a286ef2SSven Eckelmann #endif 19440a286ef2SSven Eckelmann 19459b2b5c9aSFrank Praznik report->leds_bitmap |= sc->led_state[0] << 1; 19469b2b5c9aSFrank Praznik report->leds_bitmap |= sc->led_state[1] << 2; 19479b2b5c9aSFrank Praznik report->leds_bitmap |= sc->led_state[2] << 3; 19489b2b5c9aSFrank Praznik report->leds_bitmap |= sc->led_state[3] << 4; 19499f323b68SSven Eckelmann 195088f6576fSSimon Wood /* Set flag for all leds off, required for 3rd party INTEC controller */ 19519b2b5c9aSFrank Praznik if ((report->leds_bitmap & 0x1E) == 0) 19529b2b5c9aSFrank Praznik report->leds_bitmap |= 0x20; 195388f6576fSSimon Wood 1954b3ed458cSFrank Praznik /* 1955b3ed458cSFrank Praznik * The LEDs in the report are indexed in reverse order to their 1956b3ed458cSFrank Praznik * corresponding light on the controller. 1957b3ed458cSFrank Praznik * Index 0 = LED 4, index 1 = LED 3, etc... 1958b3ed458cSFrank Praznik * 1959b3ed458cSFrank Praznik * In the case of both delay values being zero (blinking disabled) the 1960b3ed458cSFrank Praznik * default report values should be used or the controller LED will be 1961b3ed458cSFrank Praznik * always off. 1962b3ed458cSFrank Praznik */ 1963b3ed458cSFrank Praznik for (n = 0; n < 4; n++) { 1964b3ed458cSFrank Praznik if (sc->led_delay_on[n] || sc->led_delay_off[n]) { 19659b2b5c9aSFrank Praznik report->led[3 - n].duty_off = sc->led_delay_off[n]; 19669b2b5c9aSFrank Praznik report->led[3 - n].duty_on = sc->led_delay_on[n]; 1967b3ed458cSFrank Praznik } 1968b3ed458cSFrank Praznik } 1969b3ed458cSFrank Praznik 19701adf904eSPavel Machek hid_hw_raw_request(sc->hdev, report->report_id, (u8 *)report, 19719b2b5c9aSFrank Praznik sizeof(struct sixaxis_output_report), 19729b2b5c9aSFrank Praznik HID_OUTPUT_REPORT, HID_REQ_SET_REPORT); 19739f323b68SSven Eckelmann } 19749f323b68SSven Eckelmann 1975d8aaccdaSFrank Praznik static void dualshock4_send_output_report(struct sony_sc *sc) 19760bd88dd3SFrank Praznik { 19770da8ea65SFrank Praznik struct hid_device *hdev = sc->hdev; 19781adf904eSPavel Machek u8 *buf = sc->output_report_dmabuf; 197948220237SFrank Praznik int offset; 19800da8ea65SFrank Praznik 1981c4425c8fSFrank Praznik /* 1982c4425c8fSFrank Praznik * NOTE: The buf[1] field of the Bluetooth report controls 1983c4425c8fSFrank Praznik * the Dualshock 4 reporting rate. 1984c4425c8fSFrank Praznik * 1985c4425c8fSFrank Praznik * Known values include: 1986c4425c8fSFrank Praznik * 1987c4425c8fSFrank Praznik * 0x80 - 1000hz (full speed) 1988c4425c8fSFrank Praznik * 0xA0 - 31hz 1989c4425c8fSFrank Praznik * 0xB0 - 20hz 1990c4425c8fSFrank Praznik * 0xD0 - 66hz 1991c4425c8fSFrank Praznik */ 199235f436c3SRoderick Colenbrander if (sc->quirks & (DUALSHOCK4_CONTROLLER_USB | DUALSHOCK4_DONGLE)) { 19932c159de0SRoderick Colenbrander memset(buf, 0, DS4_OUTPUT_REPORT_0x05_SIZE); 199448220237SFrank Praznik buf[0] = 0x05; 1995b3ed458cSFrank Praznik buf[1] = 0xFF; 199648220237SFrank Praznik offset = 4; 1997fdcf105dSFrank Praznik } else { 19982c159de0SRoderick Colenbrander memset(buf, 0, DS4_OUTPUT_REPORT_0x11_SIZE); 1999fdcf105dSFrank Praznik buf[0] = 0x11; 2000e7ef53adSRoderick Colenbrander buf[1] = 0xC0; /* HID + CRC */ 2001fdcf105dSFrank Praznik buf[3] = 0x0F; 2002fdcf105dSFrank Praznik offset = 6; 2003fdcf105dSFrank Praznik } 20040bd88dd3SFrank Praznik 20050bd88dd3SFrank Praznik #ifdef CONFIG_SONY_FF 200648220237SFrank Praznik buf[offset++] = sc->right; 200748220237SFrank Praznik buf[offset++] = sc->left; 200848220237SFrank Praznik #else 200948220237SFrank Praznik offset += 2; 20100bd88dd3SFrank Praznik #endif 20110bd88dd3SFrank Praznik 2012b3ed458cSFrank Praznik /* LED 3 is the global control */ 2013b3ed458cSFrank Praznik if (sc->led_state[3]) { 201448220237SFrank Praznik buf[offset++] = sc->led_state[0]; 201548220237SFrank Praznik buf[offset++] = sc->led_state[1]; 201648220237SFrank Praznik buf[offset++] = sc->led_state[2]; 2017b3ed458cSFrank Praznik } else { 2018b3ed458cSFrank Praznik offset += 3; 2019b3ed458cSFrank Praznik } 2020b3ed458cSFrank Praznik 2021b3ed458cSFrank Praznik /* If both delay values are zero the DualShock 4 disables blinking. */ 2022b3ed458cSFrank Praznik buf[offset++] = sc->led_delay_on[3]; 2023b3ed458cSFrank Praznik buf[offset++] = sc->led_delay_off[3]; 202460781cf4SFrank Praznik 202535f436c3SRoderick Colenbrander if (sc->quirks & (DUALSHOCK4_CONTROLLER_USB | DUALSHOCK4_DONGLE)) 20262c159de0SRoderick Colenbrander hid_hw_output_report(hdev, buf, DS4_OUTPUT_REPORT_0x05_SIZE); 2027e7ef53adSRoderick Colenbrander else { 2028e7ef53adSRoderick Colenbrander /* CRC generation */ 2029e7ef53adSRoderick Colenbrander u8 bthdr = 0xA2; 2030e7ef53adSRoderick Colenbrander u32 crc; 2031e7ef53adSRoderick Colenbrander 2032e7ef53adSRoderick Colenbrander crc = crc32_le(0xFFFFFFFF, &bthdr, 1); 2033e7ef53adSRoderick Colenbrander crc = ~crc32_le(crc, buf, DS4_OUTPUT_REPORT_0x11_SIZE-4); 2034e7ef53adSRoderick Colenbrander put_unaligned_le32(crc, &buf[74]); 2035e7ef53adSRoderick Colenbrander hid_hw_output_report(hdev, buf, DS4_OUTPUT_REPORT_0x11_SIZE); 2036e7ef53adSRoderick Colenbrander } 20370bd88dd3SFrank Praznik } 20380bd88dd3SFrank Praznik 2039d8aaccdaSFrank Praznik static void motion_send_output_report(struct sony_sc *sc) 2040c5e0c1c4SFrank Praznik { 2041c5e0c1c4SFrank Praznik struct hid_device *hdev = sc->hdev; 2042c5e0c1c4SFrank Praznik struct motion_output_report_02 *report = 2043c5e0c1c4SFrank Praznik (struct motion_output_report_02 *)sc->output_report_dmabuf; 2044c5e0c1c4SFrank Praznik 204541d2d425SSimon Wood memset(report, 0, MOTION_REPORT_0x02_SIZE); 2046c5e0c1c4SFrank Praznik 2047c5e0c1c4SFrank Praznik report->type = 0x02; /* set leds */ 2048c5e0c1c4SFrank Praznik report->r = sc->led_state[0]; 2049c5e0c1c4SFrank Praznik report->g = sc->led_state[1]; 2050c5e0c1c4SFrank Praznik report->b = sc->led_state[2]; 2051c5e0c1c4SFrank Praznik 2052c5e0c1c4SFrank Praznik #ifdef CONFIG_SONY_FF 2053c5e0c1c4SFrank Praznik report->rumble = max(sc->right, sc->left); 2054c5e0c1c4SFrank Praznik #endif 2055c5e0c1c4SFrank Praznik 20561adf904eSPavel Machek hid_hw_output_report(hdev, (u8 *)report, MOTION_REPORT_0x02_SIZE); 2057c5e0c1c4SFrank Praznik } 2058c5e0c1c4SFrank Praznik 2059decd946cSFrank Praznik static inline void sony_send_output_report(struct sony_sc *sc) 2060decd946cSFrank Praznik { 2061decd946cSFrank Praznik if (sc->send_output_report) 2062decd946cSFrank Praznik sc->send_output_report(sc); 2063decd946cSFrank Praznik } 2064decd946cSFrank Praznik 2065d8aaccdaSFrank Praznik static void sony_state_worker(struct work_struct *work) 2066d8aaccdaSFrank Praznik { 2067d8aaccdaSFrank Praznik struct sony_sc *sc = container_of(work, struct sony_sc, state_worker); 2068ef916ef5SAntonio Ospite 2069d8aaccdaSFrank Praznik sc->send_output_report(sc); 2070d8aaccdaSFrank Praznik } 2071d8aaccdaSFrank Praznik 20729b2b5c9aSFrank Praznik static int sony_allocate_output_report(struct sony_sc *sc) 20739b2b5c9aSFrank Praznik { 20744545ee0aSSimon Wood if ((sc->quirks & SIXAXIS_CONTROLLER) || 20754545ee0aSSimon Wood (sc->quirks & NAVIGATION_CONTROLLER)) 20769b2b5c9aSFrank Praznik sc->output_report_dmabuf = 20779b2b5c9aSFrank Praznik kmalloc(sizeof(union sixaxis_output_report_01), 20789b2b5c9aSFrank Praznik GFP_KERNEL); 20799b2b5c9aSFrank Praznik else if (sc->quirks & DUALSHOCK4_CONTROLLER_BT) 20802c159de0SRoderick Colenbrander sc->output_report_dmabuf = kmalloc(DS4_OUTPUT_REPORT_0x11_SIZE, 20819b2b5c9aSFrank Praznik GFP_KERNEL); 208235f436c3SRoderick Colenbrander else if (sc->quirks & (DUALSHOCK4_CONTROLLER_USB | DUALSHOCK4_DONGLE)) 20832c159de0SRoderick Colenbrander sc->output_report_dmabuf = kmalloc(DS4_OUTPUT_REPORT_0x05_SIZE, 20849b2b5c9aSFrank Praznik GFP_KERNEL); 2085c5e0c1c4SFrank Praznik else if (sc->quirks & MOTION_CONTROLLER) 208641d2d425SSimon Wood sc->output_report_dmabuf = kmalloc(MOTION_REPORT_0x02_SIZE, 2087c5e0c1c4SFrank Praznik GFP_KERNEL); 20889b2b5c9aSFrank Praznik else 20899b2b5c9aSFrank Praznik return 0; 20909b2b5c9aSFrank Praznik 20919b2b5c9aSFrank Praznik if (!sc->output_report_dmabuf) 20929b2b5c9aSFrank Praznik return -ENOMEM; 20939b2b5c9aSFrank Praznik 20949b2b5c9aSFrank Praznik return 0; 20959b2b5c9aSFrank Praznik } 20969b2b5c9aSFrank Praznik 20970a286ef2SSven Eckelmann #ifdef CONFIG_SONY_FF 20989f323b68SSven Eckelmann static int sony_play_effect(struct input_dev *dev, void *data, 20999f323b68SSven Eckelmann struct ff_effect *effect) 21009f323b68SSven Eckelmann { 2101a08c22c0SSven Eckelmann struct hid_device *hid = input_get_drvdata(dev); 21029f323b68SSven Eckelmann struct sony_sc *sc = hid_get_drvdata(hid); 2103a08c22c0SSven Eckelmann 2104a08c22c0SSven Eckelmann if (effect->type != FF_RUMBLE) 2105a08c22c0SSven Eckelmann return 0; 2106a08c22c0SSven Eckelmann 21079f323b68SSven Eckelmann sc->left = effect->u.rumble.strong_magnitude / 256; 21080bd88dd3SFrank Praznik sc->right = effect->u.rumble.weak_magnitude / 256; 2109a08c22c0SSven Eckelmann 2110b5322736SRoderick Colenbrander sony_schedule_work(sc, SONY_WORKER_STATE); 21119f323b68SSven Eckelmann return 0; 2112a08c22c0SSven Eckelmann } 2113a08c22c0SSven Eckelmann 2114fa57a810SFrank Praznik static int sony_init_ff(struct sony_sc *sc) 2115a08c22c0SSven Eckelmann { 2116fa57a810SFrank Praznik struct hid_input *hidinput = list_entry(sc->hdev->inputs.next, 2117a08c22c0SSven Eckelmann struct hid_input, list); 2118a08c22c0SSven Eckelmann struct input_dev *input_dev = hidinput->input; 2119a08c22c0SSven Eckelmann 2120a08c22c0SSven Eckelmann input_set_capability(input_dev, EV_FF, FF_RUMBLE); 2121a08c22c0SSven Eckelmann return input_ff_create_memless(input_dev, NULL, sony_play_effect); 2122a08c22c0SSven Eckelmann } 2123a08c22c0SSven Eckelmann 2124a08c22c0SSven Eckelmann #else 2125fa57a810SFrank Praznik static int sony_init_ff(struct sony_sc *sc) 2126a08c22c0SSven Eckelmann { 2127a08c22c0SSven Eckelmann return 0; 2128a08c22c0SSven Eckelmann } 21299f323b68SSven Eckelmann 2130a08c22c0SSven Eckelmann #endif 2131a08c22c0SSven Eckelmann 2132d902f472SFrank Praznik static int sony_battery_get_property(struct power_supply *psy, 2133d902f472SFrank Praznik enum power_supply_property psp, 2134d902f472SFrank Praznik union power_supply_propval *val) 2135c4e1ddf2SFrank Praznik { 2136297d716fSKrzysztof Kozlowski struct sony_sc *sc = power_supply_get_drvdata(psy); 2137d902f472SFrank Praznik unsigned long flags; 2138d902f472SFrank Praznik int ret = 0; 2139d902f472SFrank Praznik u8 battery_charging, battery_capacity, cable_state; 2140c4e1ddf2SFrank Praznik 2141d902f472SFrank Praznik spin_lock_irqsave(&sc->lock, flags); 2142d902f472SFrank Praznik battery_charging = sc->battery_charging; 2143d902f472SFrank Praznik battery_capacity = sc->battery_capacity; 2144d902f472SFrank Praznik cable_state = sc->cable_state; 2145d902f472SFrank Praznik spin_unlock_irqrestore(&sc->lock, flags); 2146c4e1ddf2SFrank Praznik 2147d902f472SFrank Praznik switch (psp) { 2148d902f472SFrank Praznik case POWER_SUPPLY_PROP_PRESENT: 2149d902f472SFrank Praznik val->intval = 1; 2150d902f472SFrank Praznik break; 2151d902f472SFrank Praznik case POWER_SUPPLY_PROP_SCOPE: 2152d902f472SFrank Praznik val->intval = POWER_SUPPLY_SCOPE_DEVICE; 2153d902f472SFrank Praznik break; 2154d902f472SFrank Praznik case POWER_SUPPLY_PROP_CAPACITY: 2155d902f472SFrank Praznik val->intval = battery_capacity; 2156d902f472SFrank Praznik break; 2157d902f472SFrank Praznik case POWER_SUPPLY_PROP_STATUS: 2158d902f472SFrank Praznik if (battery_charging) 2159d902f472SFrank Praznik val->intval = POWER_SUPPLY_STATUS_CHARGING; 2160d902f472SFrank Praznik else 2161d902f472SFrank Praznik if (battery_capacity == 100 && cable_state) 2162d902f472SFrank Praznik val->intval = POWER_SUPPLY_STATUS_FULL; 2163d902f472SFrank Praznik else 2164d902f472SFrank Praznik val->intval = POWER_SUPPLY_STATUS_DISCHARGING; 2165d902f472SFrank Praznik break; 2166d902f472SFrank Praznik default: 2167d902f472SFrank Praznik ret = -EINVAL; 2168d902f472SFrank Praznik break; 2169c4e1ddf2SFrank Praznik } 2170d902f472SFrank Praznik return ret; 2171d902f472SFrank Praznik } 2172d902f472SFrank Praznik 21730f398230SFrank Praznik static int sony_battery_probe(struct sony_sc *sc, int append_dev_id) 2174d902f472SFrank Praznik { 21750f398230SFrank Praznik const char *battery_str_fmt = append_dev_id ? 21760f398230SFrank Praznik "sony_controller_battery_%pMR_%i" : 21770f398230SFrank Praznik "sony_controller_battery_%pMR"; 2178297d716fSKrzysztof Kozlowski struct power_supply_config psy_cfg = { .drv_data = sc, }; 2179d902f472SFrank Praznik struct hid_device *hdev = sc->hdev; 2180d902f472SFrank Praznik int ret; 2181d902f472SFrank Praznik 2182ad142b9eSFrank Praznik /* 2183ad142b9eSFrank Praznik * Set the default battery level to 100% to avoid low battery warnings 2184d9a293a9SFrank Praznik * if the battery is polled before the first device report is received. 2185d9a293a9SFrank Praznik */ 2186d9a293a9SFrank Praznik sc->battery_capacity = 100; 2187d9a293a9SFrank Praznik 2188297d716fSKrzysztof Kozlowski sc->battery_desc.properties = sony_battery_props; 2189297d716fSKrzysztof Kozlowski sc->battery_desc.num_properties = ARRAY_SIZE(sony_battery_props); 2190297d716fSKrzysztof Kozlowski sc->battery_desc.get_property = sony_battery_get_property; 2191297d716fSKrzysztof Kozlowski sc->battery_desc.type = POWER_SUPPLY_TYPE_BATTERY; 2192297d716fSKrzysztof Kozlowski sc->battery_desc.use_for_apm = 0; 21930f398230SFrank Praznik sc->battery_desc.name = kasprintf(GFP_KERNEL, battery_str_fmt, 21940f398230SFrank Praznik sc->mac_address, sc->device_id); 2195297d716fSKrzysztof Kozlowski if (!sc->battery_desc.name) 2196d902f472SFrank Praznik return -ENOMEM; 2197d902f472SFrank Praznik 2198297d716fSKrzysztof Kozlowski sc->battery = power_supply_register(&hdev->dev, &sc->battery_desc, 2199297d716fSKrzysztof Kozlowski &psy_cfg); 2200297d716fSKrzysztof Kozlowski if (IS_ERR(sc->battery)) { 2201297d716fSKrzysztof Kozlowski ret = PTR_ERR(sc->battery); 2202d902f472SFrank Praznik hid_err(hdev, "Unable to register battery device\n"); 2203d902f472SFrank Praznik goto err_free; 2204d902f472SFrank Praznik } 2205d902f472SFrank Praznik 2206297d716fSKrzysztof Kozlowski power_supply_powers(sc->battery, &hdev->dev); 2207d902f472SFrank Praznik return 0; 2208d902f472SFrank Praznik 2209d902f472SFrank Praznik err_free: 2210297d716fSKrzysztof Kozlowski kfree(sc->battery_desc.name); 2211297d716fSKrzysztof Kozlowski sc->battery_desc.name = NULL; 2212d902f472SFrank Praznik return ret; 2213d902f472SFrank Praznik } 2214d902f472SFrank Praznik 2215d902f472SFrank Praznik static void sony_battery_remove(struct sony_sc *sc) 2216d902f472SFrank Praznik { 2217297d716fSKrzysztof Kozlowski if (!sc->battery_desc.name) 2218d902f472SFrank Praznik return; 2219d902f472SFrank Praznik 2220297d716fSKrzysztof Kozlowski power_supply_unregister(sc->battery); 2221297d716fSKrzysztof Kozlowski kfree(sc->battery_desc.name); 2222297d716fSKrzysztof Kozlowski sc->battery_desc.name = NULL; 2223d902f472SFrank Praznik } 2224d902f472SFrank Praznik 2225d2d782fcSFrank Praznik /* 2226d2d782fcSFrank Praznik * If a controller is plugged in via USB while already connected via Bluetooth 2227d2d782fcSFrank Praznik * it will show up as two devices. A global list of connected controllers and 2228d2d782fcSFrank Praznik * their MAC addresses is maintained to ensure that a device is only connected 2229d2d782fcSFrank Praznik * once. 22300f398230SFrank Praznik * 22310f398230SFrank Praznik * Some USB-only devices masquerade as Sixaxis controllers and all have the 22320f398230SFrank Praznik * same dummy Bluetooth address, so a comparison of the connection type is 22330f398230SFrank Praznik * required. Devices are only rejected in the case where two devices have 22340f398230SFrank Praznik * matching Bluetooth addresses on different bus types. 2235d2d782fcSFrank Praznik */ 22360f398230SFrank Praznik static inline int sony_compare_connection_type(struct sony_sc *sc0, 22370f398230SFrank Praznik struct sony_sc *sc1) 22380f398230SFrank Praznik { 22390f398230SFrank Praznik const int sc0_not_bt = !(sc0->quirks & SONY_BT_DEVICE); 22400f398230SFrank Praznik const int sc1_not_bt = !(sc1->quirks & SONY_BT_DEVICE); 22410f398230SFrank Praznik 22420f398230SFrank Praznik return sc0_not_bt == sc1_not_bt; 22430f398230SFrank Praznik } 22440f398230SFrank Praznik 2245d2d782fcSFrank Praznik static int sony_check_add_dev_list(struct sony_sc *sc) 2246d2d782fcSFrank Praznik { 2247d2d782fcSFrank Praznik struct sony_sc *entry; 2248d2d782fcSFrank Praznik unsigned long flags; 2249d2d782fcSFrank Praznik int ret; 2250d2d782fcSFrank Praznik 2251d2d782fcSFrank Praznik spin_lock_irqsave(&sony_dev_list_lock, flags); 2252d2d782fcSFrank Praznik 2253d2d782fcSFrank Praznik list_for_each_entry(entry, &sony_device_list, list_node) { 2254d2d782fcSFrank Praznik ret = memcmp(sc->mac_address, entry->mac_address, 2255d2d782fcSFrank Praznik sizeof(sc->mac_address)); 2256d2d782fcSFrank Praznik if (!ret) { 22570f398230SFrank Praznik if (sony_compare_connection_type(sc, entry)) { 22580f398230SFrank Praznik ret = 1; 22590f398230SFrank Praznik } else { 2260d2d782fcSFrank Praznik ret = -EEXIST; 22610f398230SFrank Praznik hid_info(sc->hdev, 22620f398230SFrank Praznik "controller with MAC address %pMR already connected\n", 2263d2d782fcSFrank Praznik sc->mac_address); 22640f398230SFrank Praznik } 2265d2d782fcSFrank Praznik goto unlock; 2266d2d782fcSFrank Praznik } 2267c4e1ddf2SFrank Praznik } 2268c4e1ddf2SFrank Praznik 2269d2d782fcSFrank Praznik ret = 0; 2270d2d782fcSFrank Praznik list_add(&(sc->list_node), &sony_device_list); 2271c4e1ddf2SFrank Praznik 2272d2d782fcSFrank Praznik unlock: 2273d2d782fcSFrank Praznik spin_unlock_irqrestore(&sony_dev_list_lock, flags); 2274d2d782fcSFrank Praznik return ret; 2275d2d782fcSFrank Praznik } 2276d2d782fcSFrank Praznik 2277d2d782fcSFrank Praznik static void sony_remove_dev_list(struct sony_sc *sc) 2278d2d782fcSFrank Praznik { 2279d2d782fcSFrank Praznik unsigned long flags; 2280d2d782fcSFrank Praznik 2281d2d782fcSFrank Praznik if (sc->list_node.next) { 2282d2d782fcSFrank Praznik spin_lock_irqsave(&sony_dev_list_lock, flags); 2283d2d782fcSFrank Praznik list_del(&(sc->list_node)); 2284d2d782fcSFrank Praznik spin_unlock_irqrestore(&sony_dev_list_lock, flags); 2285d2d782fcSFrank Praznik } 2286d2d782fcSFrank Praznik } 2287d2d782fcSFrank Praznik 2288d2d782fcSFrank Praznik static int sony_get_bt_devaddr(struct sony_sc *sc) 2289d2d782fcSFrank Praznik { 2290d2d782fcSFrank Praznik int ret; 2291d2d782fcSFrank Praznik 2292d2d782fcSFrank Praznik /* HIDP stores the device MAC address as a string in the uniq field. */ 2293d2d782fcSFrank Praznik ret = strlen(sc->hdev->uniq); 2294d2d782fcSFrank Praznik if (ret != 17) 2295c4e1ddf2SFrank Praznik return -EINVAL; 2296d2d782fcSFrank Praznik 2297d2d782fcSFrank Praznik ret = sscanf(sc->hdev->uniq, 2298d2d782fcSFrank Praznik "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx", 2299d2d782fcSFrank Praznik &sc->mac_address[5], &sc->mac_address[4], &sc->mac_address[3], 2300d2d782fcSFrank Praznik &sc->mac_address[2], &sc->mac_address[1], &sc->mac_address[0]); 2301d2d782fcSFrank Praznik 2302d2d782fcSFrank Praznik if (ret != 6) 2303d2d782fcSFrank Praznik return -EINVAL; 2304d2d782fcSFrank Praznik 2305d2d782fcSFrank Praznik return 0; 2306c4e1ddf2SFrank Praznik } 2307c4e1ddf2SFrank Praznik 2308d2d782fcSFrank Praznik static int sony_check_add(struct sony_sc *sc) 2309d2d782fcSFrank Praznik { 23101adf904eSPavel Machek u8 *buf = NULL; 2311d2d782fcSFrank Praznik int n, ret; 2312d2d782fcSFrank Praznik 2313d2d782fcSFrank Praznik if ((sc->quirks & DUALSHOCK4_CONTROLLER_BT) || 231412e9a6d7SSimon Wood (sc->quirks & MOTION_CONTROLLER_BT) || 23154545ee0aSSimon Wood (sc->quirks & NAVIGATION_CONTROLLER_BT) || 2316d2d782fcSFrank Praznik (sc->quirks & SIXAXIS_CONTROLLER_BT)) { 2317d2d782fcSFrank Praznik /* 2318d2d782fcSFrank Praznik * sony_get_bt_devaddr() attempts to parse the Bluetooth MAC 2319d2d782fcSFrank Praznik * address from the uniq string where HIDP stores it. 2320d2d782fcSFrank Praznik * As uniq cannot be guaranteed to be a MAC address in all cases 2321d2d782fcSFrank Praznik * a failure of this function should not prevent the connection. 2322d2d782fcSFrank Praznik */ 2323d2d782fcSFrank Praznik if (sony_get_bt_devaddr(sc) < 0) { 2324d2d782fcSFrank Praznik hid_warn(sc->hdev, "UNIQ does not contain a MAC address; duplicate check skipped\n"); 2325d2d782fcSFrank Praznik return 0; 2326d2d782fcSFrank Praznik } 232735f436c3SRoderick Colenbrander } else if (sc->quirks & (DUALSHOCK4_CONTROLLER_USB | DUALSHOCK4_DONGLE)) { 23282c159de0SRoderick Colenbrander buf = kmalloc(DS4_FEATURE_REPORT_0x81_SIZE, GFP_KERNEL); 23299b2b5c9aSFrank Praznik if (!buf) 23309b2b5c9aSFrank Praznik return -ENOMEM; 2331d2d782fcSFrank Praznik 2332d2d782fcSFrank Praznik /* 2333d2d782fcSFrank Praznik * The MAC address of a DS4 controller connected via USB can be 2334d2d782fcSFrank Praznik * retrieved with feature report 0x81. The address begins at 2335d2d782fcSFrank Praznik * offset 1. 2336d2d782fcSFrank Praznik */ 23379b2b5c9aSFrank Praznik ret = hid_hw_raw_request(sc->hdev, 0x81, buf, 23382c159de0SRoderick Colenbrander DS4_FEATURE_REPORT_0x81_SIZE, HID_FEATURE_REPORT, 23399b2b5c9aSFrank Praznik HID_REQ_GET_REPORT); 2340d2d782fcSFrank Praznik 23412c159de0SRoderick Colenbrander if (ret != DS4_FEATURE_REPORT_0x81_SIZE) { 2342d2d782fcSFrank Praznik hid_err(sc->hdev, "failed to retrieve feature report 0x81 with the DualShock 4 MAC address\n"); 23439b2b5c9aSFrank Praznik ret = ret < 0 ? ret : -EINVAL; 23449b2b5c9aSFrank Praznik goto out_free; 2345d2d782fcSFrank Praznik } 2346d2d782fcSFrank Praznik 2347d2d782fcSFrank Praznik memcpy(sc->mac_address, &buf[1], sizeof(sc->mac_address)); 2348c70d5f70SRoderick Colenbrander 2349c70d5f70SRoderick Colenbrander snprintf(sc->hdev->uniq, sizeof(sc->hdev->uniq), 2350c70d5f70SRoderick Colenbrander "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx", 2351c70d5f70SRoderick Colenbrander sc->mac_address[5], sc->mac_address[4], 2352c70d5f70SRoderick Colenbrander sc->mac_address[3], sc->mac_address[2], 2353c70d5f70SRoderick Colenbrander sc->mac_address[1], sc->mac_address[0]); 23544545ee0aSSimon Wood } else if ((sc->quirks & SIXAXIS_CONTROLLER_USB) || 23554545ee0aSSimon Wood (sc->quirks & NAVIGATION_CONTROLLER_USB)) { 23569b2b5c9aSFrank Praznik buf = kmalloc(SIXAXIS_REPORT_0xF2_SIZE, GFP_KERNEL); 23579b2b5c9aSFrank Praznik if (!buf) 23589b2b5c9aSFrank Praznik return -ENOMEM; 2359d2d782fcSFrank Praznik 2360d2d782fcSFrank Praznik /* 2361d2d782fcSFrank Praznik * The MAC address of a Sixaxis controller connected via USB can 2362d2d782fcSFrank Praznik * be retrieved with feature report 0xf2. The address begins at 2363d2d782fcSFrank Praznik * offset 4. 2364d2d782fcSFrank Praznik */ 23659b2b5c9aSFrank Praznik ret = hid_hw_raw_request(sc->hdev, 0xf2, buf, 23669b2b5c9aSFrank Praznik SIXAXIS_REPORT_0xF2_SIZE, HID_FEATURE_REPORT, 23679b2b5c9aSFrank Praznik HID_REQ_GET_REPORT); 2368d2d782fcSFrank Praznik 23699b2b5c9aSFrank Praznik if (ret != SIXAXIS_REPORT_0xF2_SIZE) { 2370d2d782fcSFrank Praznik hid_err(sc->hdev, "failed to retrieve feature report 0xf2 with the Sixaxis MAC address\n"); 23719b2b5c9aSFrank Praznik ret = ret < 0 ? ret : -EINVAL; 23729b2b5c9aSFrank Praznik goto out_free; 2373d2d782fcSFrank Praznik } 2374d2d782fcSFrank Praznik 2375d2d782fcSFrank Praznik /* 2376d2d782fcSFrank Praznik * The Sixaxis device MAC in the report is big-endian and must 2377d2d782fcSFrank Praznik * be byte-swapped. 2378d2d782fcSFrank Praznik */ 2379d2d782fcSFrank Praznik for (n = 0; n < 6; n++) 2380d2d782fcSFrank Praznik sc->mac_address[5-n] = buf[4+n]; 2381d2d782fcSFrank Praznik } else { 2382d2d782fcSFrank Praznik return 0; 2383d2d782fcSFrank Praznik } 2384d2d782fcSFrank Praznik 23859b2b5c9aSFrank Praznik ret = sony_check_add_dev_list(sc); 23869b2b5c9aSFrank Praznik 23879b2b5c9aSFrank Praznik out_free: 23889b2b5c9aSFrank Praznik 23899b2b5c9aSFrank Praznik kfree(buf); 23909b2b5c9aSFrank Praznik 23919b2b5c9aSFrank Praznik return ret; 2392d2d782fcSFrank Praznik } 2393d2d782fcSFrank Praznik 23948025087aSFrank Praznik static int sony_set_device_id(struct sony_sc *sc) 23958025087aSFrank Praznik { 23968025087aSFrank Praznik int ret; 23978025087aSFrank Praznik 23988025087aSFrank Praznik /* 23998025087aSFrank Praznik * Only DualShock 4 or Sixaxis controllers get an id. 24008025087aSFrank Praznik * All others are set to -1. 24018025087aSFrank Praznik */ 24028025087aSFrank Praznik if ((sc->quirks & SIXAXIS_CONTROLLER) || 24038025087aSFrank Praznik (sc->quirks & DUALSHOCK4_CONTROLLER)) { 24048025087aSFrank Praznik ret = ida_simple_get(&sony_device_id_allocator, 0, 0, 24058025087aSFrank Praznik GFP_KERNEL); 24068025087aSFrank Praznik if (ret < 0) { 24078025087aSFrank Praznik sc->device_id = -1; 24088025087aSFrank Praznik return ret; 24098025087aSFrank Praznik } 24108025087aSFrank Praznik sc->device_id = ret; 24118025087aSFrank Praznik } else { 24128025087aSFrank Praznik sc->device_id = -1; 24138025087aSFrank Praznik } 24148025087aSFrank Praznik 24158025087aSFrank Praznik return 0; 24168025087aSFrank Praznik } 24178025087aSFrank Praznik 24188025087aSFrank Praznik static void sony_release_device_id(struct sony_sc *sc) 24198025087aSFrank Praznik { 24208025087aSFrank Praznik if (sc->device_id >= 0) { 24218025087aSFrank Praznik ida_simple_remove(&sony_device_id_allocator, sc->device_id); 24228025087aSFrank Praznik sc->device_id = -1; 24238025087aSFrank Praznik } 24248025087aSFrank Praznik } 24258025087aSFrank Praznik 2426d8aaccdaSFrank Praznik static inline void sony_init_output_report(struct sony_sc *sc, 2427d8aaccdaSFrank Praznik void (*send_output_report)(struct sony_sc *)) 242846262047SFrank Praznik { 2429d8aaccdaSFrank Praznik sc->send_output_report = send_output_report; 2430d8aaccdaSFrank Praznik 2431b5322736SRoderick Colenbrander if (!sc->state_worker_initialized) 2432d8aaccdaSFrank Praznik INIT_WORK(&sc->state_worker, sony_state_worker); 243346262047SFrank Praznik 2434b5322736SRoderick Colenbrander sc->state_worker_initialized = 1; 243546262047SFrank Praznik } 243646262047SFrank Praznik 243746262047SFrank Praznik static inline void sony_cancel_work_sync(struct sony_sc *sc) 243846262047SFrank Praznik { 2439f2f47c38SRoderick Colenbrander if (sc->hotplug_worker_initialized) 2440f2f47c38SRoderick Colenbrander cancel_work_sync(&sc->hotplug_worker); 2441b5322736SRoderick Colenbrander if (sc->state_worker_initialized) 244246262047SFrank Praznik cancel_work_sync(&sc->state_worker); 244346262047SFrank Praznik } 2444d2d782fcSFrank Praznik 2445e1bc84d0SRoderick Colenbrander static int sony_input_configured(struct hid_device *hdev, 2446e1bc84d0SRoderick Colenbrander struct hid_input *hidinput) 2447bd28ce00SJiri Slaby { 2448e1bc84d0SRoderick Colenbrander struct sony_sc *sc = hid_get_drvdata(hdev); 24490f398230SFrank Praznik int append_dev_id; 2450e1bc84d0SRoderick Colenbrander int ret; 2451bd28ce00SJiri Slaby 24528025087aSFrank Praznik ret = sony_set_device_id(sc); 24538025087aSFrank Praznik if (ret < 0) { 24548025087aSFrank Praznik hid_err(hdev, "failed to allocate the device id\n"); 24558025087aSFrank Praznik goto err_stop; 24568025087aSFrank Praznik } 24578025087aSFrank Praznik 2458131a8a9aSFrank Praznik ret = sony_allocate_output_report(sc); 2459131a8a9aSFrank Praznik if (ret < 0) { 2460131a8a9aSFrank Praznik hid_err(hdev, "failed to allocate the output report buffer\n"); 2461131a8a9aSFrank Praznik goto err_stop; 2462131a8a9aSFrank Praznik } 2463131a8a9aSFrank Praznik 24644545ee0aSSimon Wood if ((sc->quirks & SIXAXIS_CONTROLLER_USB) || 24654545ee0aSSimon Wood (sc->quirks & NAVIGATION_CONTROLLER_USB)) { 2466e534a935SBenjamin Tissoires /* 2467e534a935SBenjamin Tissoires * The Sony Sixaxis does not handle HID Output Reports on the 2468e534a935SBenjamin Tissoires * Interrupt EP like it could, so we need to force HID Output 2469e534a935SBenjamin Tissoires * Reports to use HID_REQ_SET_REPORT on the Control EP. 2470e534a935SBenjamin Tissoires * 2471e534a935SBenjamin Tissoires * There is also another issue about HID Output Reports via USB, 2472e534a935SBenjamin Tissoires * the Sixaxis does not want the report_id as part of the data 2473e534a935SBenjamin Tissoires * packet, so we have to discard buf[0] when sending the actual 2474e534a935SBenjamin Tissoires * control message, even for numbered reports, humpf! 24752a242932SFrank Praznik * 24762a242932SFrank Praznik * Additionally, the Sixaxis on USB isn't properly initialized 24772a242932SFrank Praznik * until the PS logo button is pressed and as such won't retain 24782a242932SFrank Praznik * any state set by an output report, so the initial 24792a242932SFrank Praznik * configuration report is deferred until the first input 24802a242932SFrank Praznik * report arrives. 2481e534a935SBenjamin Tissoires */ 2482e534a935SBenjamin Tissoires hdev->quirks |= HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP; 2483e534a935SBenjamin Tissoires hdev->quirks |= HID_QUIRK_SKIP_OUTPUT_REPORT_ID; 24842a242932SFrank Praznik sc->defer_initialization = 1; 2485816651a7SAntonio Ospite ret = sixaxis_set_operational_usb(hdev); 2486d8aaccdaSFrank Praznik sony_init_output_report(sc, sixaxis_send_output_report); 24874545ee0aSSimon Wood } else if ((sc->quirks & SIXAXIS_CONTROLLER_BT) || 24884545ee0aSSimon Wood (sc->quirks & NAVIGATION_CONTROLLER_BT)) { 24892078b9bbSFrank Praznik /* 24902078b9bbSFrank Praznik * The Sixaxis wants output reports sent on the ctrl endpoint 24912078b9bbSFrank Praznik * when connected via Bluetooth. 24922078b9bbSFrank Praznik */ 24932078b9bbSFrank Praznik hdev->quirks |= HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP; 2494816651a7SAntonio Ospite ret = sixaxis_set_operational_bt(hdev); 2495d8aaccdaSFrank Praznik sony_init_output_report(sc, sixaxis_send_output_report); 2496fee4e2d5SFrank Praznik } else if (sc->quirks & DUALSHOCK4_CONTROLLER) { 249755a07d62SRoderick Colenbrander ret = dualshock4_get_calibration_data(sc); 249868330d83SFrank Praznik if (ret < 0) { 249955a07d62SRoderick Colenbrander hid_err(hdev, "Failed to get calibration data from Dualshock 4\n"); 250068330d83SFrank Praznik goto err_stop; 250168330d83SFrank Praznik } 2502c4e1ddf2SFrank Praznik 2503e1bc84d0SRoderick Colenbrander /* 2504e1bc84d0SRoderick Colenbrander * The Dualshock 4 touchpad supports 2 touches and has a 2505e1bc84d0SRoderick Colenbrander * resolution of 1920x942 (44.86 dots/mm). 2506e1bc84d0SRoderick Colenbrander */ 2507ac797b95SRoderick Colenbrander ret = sony_register_touchpad(sc, 2, 1920, 942); 2508e1bc84d0SRoderick Colenbrander if (ret) { 2509e1bc84d0SRoderick Colenbrander hid_err(sc->hdev, 2510e1bc84d0SRoderick Colenbrander "Unable to initialize multi-touch slots: %d\n", 2511e1bc84d0SRoderick Colenbrander ret); 25122b6579d4SRoderick Colenbrander goto err_stop; 2513e1bc84d0SRoderick Colenbrander } 2514e1bc84d0SRoderick Colenbrander 2515227c011bSRoderick Colenbrander ret = sony_register_sensors(sc); 2516227c011bSRoderick Colenbrander if (ret) { 2517227c011bSRoderick Colenbrander hid_err(sc->hdev, 2518227c011bSRoderick Colenbrander "Unable to initialize motion sensors: %d\n", ret); 2519227c011bSRoderick Colenbrander goto err_stop; 2520227c011bSRoderick Colenbrander } 2521227c011bSRoderick Colenbrander 2522f2f47c38SRoderick Colenbrander if (sc->quirks & DUALSHOCK4_DONGLE) { 2523f2f47c38SRoderick Colenbrander INIT_WORK(&sc->hotplug_worker, dualshock4_calibration_work); 2524f2f47c38SRoderick Colenbrander sc->hotplug_worker_initialized = 1; 2525f2f47c38SRoderick Colenbrander sc->ds4_dongle_state = DONGLE_DISCONNECTED; 2526f2f47c38SRoderick Colenbrander } 2527f2f47c38SRoderick Colenbrander 2528d8aaccdaSFrank Praznik sony_init_output_report(sc, dualshock4_send_output_report); 2529c5e0c1c4SFrank Praznik } else if (sc->quirks & MOTION_CONTROLLER) { 2530d8aaccdaSFrank Praznik sony_init_output_report(sc, motion_send_output_report); 25310bd88dd3SFrank Praznik } else { 25320bd88dd3SFrank Praznik ret = 0; 25330bd88dd3SFrank Praznik } 2534f9ce7c28SBastien Nocera 25354dfdc464SJiri Kosina if (ret < 0) 2536bd28ce00SJiri Slaby goto err_stop; 2537bd28ce00SJiri Slaby 25380f398230SFrank Praznik ret = append_dev_id = sony_check_add(sc); 2539d2d782fcSFrank Praznik if (ret < 0) 2540d2d782fcSFrank Praznik goto err_stop; 2541d2d782fcSFrank Praznik 25420a286ef2SSven Eckelmann if (sc->quirks & SONY_LED_SUPPORT) { 2543fa57a810SFrank Praznik ret = sony_leds_init(sc); 25440a286ef2SSven Eckelmann if (ret < 0) 25450a286ef2SSven Eckelmann goto err_stop; 25460a286ef2SSven Eckelmann } 25470a286ef2SSven Eckelmann 2548d902f472SFrank Praznik if (sc->quirks & SONY_BATTERY_SUPPORT) { 25490f398230SFrank Praznik ret = sony_battery_probe(sc, append_dev_id); 2550a08c22c0SSven Eckelmann if (ret < 0) 2551a08c22c0SSven Eckelmann goto err_stop; 2552a08c22c0SSven Eckelmann 2553d902f472SFrank Praznik /* Open the device to receive reports with battery info */ 2554d902f472SFrank Praznik ret = hid_hw_open(hdev); 2555d902f472SFrank Praznik if (ret < 0) { 2556d902f472SFrank Praznik hid_err(hdev, "hw open failed\n"); 2557d902f472SFrank Praznik goto err_stop; 2558d902f472SFrank Praznik } 2559d902f472SFrank Praznik } 2560d902f472SFrank Praznik 2561c8de9dbbSFrank Praznik if (sc->quirks & SONY_FF_SUPPORT) { 2562fa57a810SFrank Praznik ret = sony_init_ff(sc); 2563d902f472SFrank Praznik if (ret < 0) 2564d902f472SFrank Praznik goto err_close; 25655f5750d2SFrank Praznik } 2566bd28ce00SJiri Slaby 2567f425458eSH Hartley Sweeten return 0; 2568d902f472SFrank Praznik err_close: 2569d902f472SFrank Praznik hid_hw_close(hdev); 2570bd28ce00SJiri Slaby err_stop: 25710a286ef2SSven Eckelmann if (sc->quirks & SONY_LED_SUPPORT) 2572fa57a810SFrank Praznik sony_leds_remove(sc); 2573d902f472SFrank Praznik if (sc->quirks & SONY_BATTERY_SUPPORT) 2574d902f472SFrank Praznik sony_battery_remove(sc); 257546262047SFrank Praznik sony_cancel_work_sync(sc); 25769b2b5c9aSFrank Praznik kfree(sc->output_report_dmabuf); 2577d2d782fcSFrank Praznik sony_remove_dev_list(sc); 25788025087aSFrank Praznik sony_release_device_id(sc); 2579bd28ce00SJiri Slaby hid_hw_stop(hdev); 2580bd28ce00SJiri Slaby return ret; 2581bd28ce00SJiri Slaby } 2582bd28ce00SJiri Slaby 2583e1bc84d0SRoderick Colenbrander static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id) 2584e1bc84d0SRoderick Colenbrander { 2585e1bc84d0SRoderick Colenbrander int ret; 2586e1bc84d0SRoderick Colenbrander unsigned long quirks = id->driver_data; 2587e1bc84d0SRoderick Colenbrander struct sony_sc *sc; 2588e1bc84d0SRoderick Colenbrander unsigned int connect_mask = HID_CONNECT_DEFAULT; 2589e1bc84d0SRoderick Colenbrander 2590e1bc84d0SRoderick Colenbrander if (!strcmp(hdev->name, "FutureMax Dance Mat")) 2591e1bc84d0SRoderick Colenbrander quirks |= FUTUREMAX_DANCE_MAT; 2592e1bc84d0SRoderick Colenbrander 2593e1bc84d0SRoderick Colenbrander sc = devm_kzalloc(&hdev->dev, sizeof(*sc), GFP_KERNEL); 2594e1bc84d0SRoderick Colenbrander if (sc == NULL) { 2595e1bc84d0SRoderick Colenbrander hid_err(hdev, "can't alloc sony descriptor\n"); 2596e1bc84d0SRoderick Colenbrander return -ENOMEM; 2597e1bc84d0SRoderick Colenbrander } 2598e1bc84d0SRoderick Colenbrander 2599e1bc84d0SRoderick Colenbrander spin_lock_init(&sc->lock); 2600e1bc84d0SRoderick Colenbrander 2601e1bc84d0SRoderick Colenbrander sc->quirks = quirks; 2602e1bc84d0SRoderick Colenbrander hid_set_drvdata(hdev, sc); 2603e1bc84d0SRoderick Colenbrander sc->hdev = hdev; 2604e1bc84d0SRoderick Colenbrander 2605e1bc84d0SRoderick Colenbrander ret = hid_parse(hdev); 2606e1bc84d0SRoderick Colenbrander if (ret) { 2607e1bc84d0SRoderick Colenbrander hid_err(hdev, "parse failed\n"); 2608e1bc84d0SRoderick Colenbrander return ret; 2609e1bc84d0SRoderick Colenbrander } 2610e1bc84d0SRoderick Colenbrander 2611e1bc84d0SRoderick Colenbrander if (sc->quirks & VAIO_RDESC_CONSTANT) 2612e1bc84d0SRoderick Colenbrander connect_mask |= HID_CONNECT_HIDDEV_FORCE; 2613e1bc84d0SRoderick Colenbrander else if (sc->quirks & SIXAXIS_CONTROLLER) 2614e1bc84d0SRoderick Colenbrander connect_mask |= HID_CONNECT_HIDDEV_FORCE; 2615e1bc84d0SRoderick Colenbrander 26169131f8ccSRoderick Colenbrander /* Patch the hw version on DS4 compatible devices, so applications can 26179131f8ccSRoderick Colenbrander * distinguish between the default HID mappings and the mappings defined 26189131f8ccSRoderick Colenbrander * by the Linux game controller spec. This is important for the SDL2 26199131f8ccSRoderick Colenbrander * library, which has a game controller database, which uses device ids 26209131f8ccSRoderick Colenbrander * in combination with version as a key. 26219131f8ccSRoderick Colenbrander */ 26229131f8ccSRoderick Colenbrander if (sc->quirks & DUALSHOCK4_CONTROLLER) 26239131f8ccSRoderick Colenbrander hdev->version |= 0x8000; 26249131f8ccSRoderick Colenbrander 2625e1bc84d0SRoderick Colenbrander ret = hid_hw_start(hdev, connect_mask); 2626e1bc84d0SRoderick Colenbrander if (ret) { 2627e1bc84d0SRoderick Colenbrander hid_err(hdev, "hw start failed\n"); 2628e1bc84d0SRoderick Colenbrander return ret; 2629e1bc84d0SRoderick Colenbrander } 2630e1bc84d0SRoderick Colenbrander 26314f967f6dSRoderick Colenbrander /* sony_input_configured can fail, but this doesn't result 26324f967f6dSRoderick Colenbrander * in hid_hw_start failures (intended). Check whether 26334f967f6dSRoderick Colenbrander * the HID layer claimed the device else fail. 26344f967f6dSRoderick Colenbrander * We don't know the actual reason for the failure, most 26354f967f6dSRoderick Colenbrander * likely it is due to EEXIST in case of double connection 26364f967f6dSRoderick Colenbrander * of USB and Bluetooth, but could have been due to ENOMEM 26374f967f6dSRoderick Colenbrander * or other reasons as well. 26384f967f6dSRoderick Colenbrander */ 26394f967f6dSRoderick Colenbrander if (!(hdev->claimed & HID_CLAIMED_INPUT)) { 26404f967f6dSRoderick Colenbrander hid_err(hdev, "failed to claim input\n"); 26414f967f6dSRoderick Colenbrander return -ENODEV; 26424f967f6dSRoderick Colenbrander } 26434f967f6dSRoderick Colenbrander 2644e1bc84d0SRoderick Colenbrander return ret; 2645e1bc84d0SRoderick Colenbrander } 2646e1bc84d0SRoderick Colenbrander 2647bd28ce00SJiri Slaby static void sony_remove(struct hid_device *hdev) 2648bd28ce00SJiri Slaby { 2649bd28ce00SJiri Slaby struct sony_sc *sc = hid_get_drvdata(hdev); 2650bd28ce00SJiri Slaby 2651ac797b95SRoderick Colenbrander hid_hw_close(hdev); 2652ac797b95SRoderick Colenbrander 26530a286ef2SSven Eckelmann if (sc->quirks & SONY_LED_SUPPORT) 2654fa57a810SFrank Praznik sony_leds_remove(sc); 2655bd28ce00SJiri Slaby 2656ac797b95SRoderick Colenbrander if (sc->quirks & SONY_BATTERY_SUPPORT) 2657d902f472SFrank Praznik sony_battery_remove(sc); 2658ac797b95SRoderick Colenbrander 2659ac797b95SRoderick Colenbrander if (sc->touchpad) 2660ac797b95SRoderick Colenbrander sony_unregister_touchpad(sc); 2661d902f472SFrank Praznik 2662227c011bSRoderick Colenbrander if (sc->sensor_dev) 2663227c011bSRoderick Colenbrander sony_unregister_sensors(sc); 2664227c011bSRoderick Colenbrander 2665227c011bSRoderick Colenbrander if (sc->sensor_dev) 2666227c011bSRoderick Colenbrander sony_unregister_sensors(sc); 2667227c011bSRoderick Colenbrander 266846262047SFrank Praznik sony_cancel_work_sync(sc); 26699f323b68SSven Eckelmann 26709b2b5c9aSFrank Praznik kfree(sc->output_report_dmabuf); 26719b2b5c9aSFrank Praznik 2672d2d782fcSFrank Praznik sony_remove_dev_list(sc); 2673bd28ce00SJiri Slaby 26748025087aSFrank Praznik sony_release_device_id(sc); 26758025087aSFrank Praznik 2676bd28ce00SJiri Slaby hid_hw_stop(hdev); 2677bd28ce00SJiri Slaby } 2678bd28ce00SJiri Slaby 2679decd946cSFrank Praznik #ifdef CONFIG_PM 2680decd946cSFrank Praznik 2681decd946cSFrank Praznik static int sony_suspend(struct hid_device *hdev, pm_message_t message) 2682decd946cSFrank Praznik { 2683765a1077SFrank Praznik #ifdef CONFIG_SONY_FF 2684765a1077SFrank Praznik 2685765a1077SFrank Praznik /* On suspend stop any running force-feedback events */ 2686765a1077SFrank Praznik if (SONY_FF_SUPPORT) { 2687decd946cSFrank Praznik struct sony_sc *sc = hid_get_drvdata(hdev); 2688decd946cSFrank Praznik 2689decd946cSFrank Praznik sc->left = sc->right = 0; 2690decd946cSFrank Praznik sony_send_output_report(sc); 2691decd946cSFrank Praznik } 2692decd946cSFrank Praznik 2693765a1077SFrank Praznik #endif 2694decd946cSFrank Praznik return 0; 2695decd946cSFrank Praznik } 2696decd946cSFrank Praznik 2697decd946cSFrank Praznik static int sony_resume(struct hid_device *hdev) 2698decd946cSFrank Praznik { 2699decd946cSFrank Praznik struct sony_sc *sc = hid_get_drvdata(hdev); 2700decd946cSFrank Praznik 2701decd946cSFrank Praznik /* 2702decd946cSFrank Praznik * The Sixaxis and navigation controllers on USB need to be 2703decd946cSFrank Praznik * reinitialized on resume or they won't behave properly. 2704decd946cSFrank Praznik */ 2705decd946cSFrank Praznik if ((sc->quirks & SIXAXIS_CONTROLLER_USB) || 27062a242932SFrank Praznik (sc->quirks & NAVIGATION_CONTROLLER_USB)) { 2707decd946cSFrank Praznik sixaxis_set_operational_usb(sc->hdev); 27082a242932SFrank Praznik sc->defer_initialization = 1; 27092a242932SFrank Praznik } 2710decd946cSFrank Praznik 2711decd946cSFrank Praznik return 0; 2712decd946cSFrank Praznik } 2713decd946cSFrank Praznik 2714decd946cSFrank Praznik #endif 2715decd946cSFrank Praznik 2716bd28ce00SJiri Slaby static const struct hid_device_id sony_devices[] = { 2717bd28ce00SJiri Slaby { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER), 2718bd28ce00SJiri Slaby .driver_data = SIXAXIS_CONTROLLER_USB }, 2719bd28ce00SJiri Slaby { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER), 27204545ee0aSSimon Wood .driver_data = NAVIGATION_CONTROLLER_USB }, 27216eabaaa0SSimon Wood { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER), 27224545ee0aSSimon Wood .driver_data = NAVIGATION_CONTROLLER_BT }, 2723c5e0c1c4SFrank Praznik { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_MOTION_CONTROLLER), 2724b3bca326SSimon Wood .driver_data = MOTION_CONTROLLER_USB }, 2725a4afa854SSimon Wood { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_MOTION_CONTROLLER), 2726b3bca326SSimon Wood .driver_data = MOTION_CONTROLLER_BT }, 2727bd28ce00SJiri Slaby { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER), 2728bd28ce00SJiri Slaby .driver_data = SIXAXIS_CONTROLLER_BT }, 2729bd28ce00SJiri Slaby { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE), 2730bd28ce00SJiri Slaby .driver_data = VAIO_RDESC_CONSTANT }, 2731bd28ce00SJiri Slaby { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGP_MOUSE), 2732bd28ce00SJiri Slaby .driver_data = VAIO_RDESC_CONSTANT }, 2733ef916ef5SAntonio Ospite /* 2734ef916ef5SAntonio Ospite * Wired Buzz Controller. Reported as Sony Hub from its USB ID and as 2735ef916ef5SAntonio Ospite * Logitech joystick from the device descriptor. 2736ef916ef5SAntonio Ospite */ 2737bd28ce00SJiri Slaby { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_BUZZ_CONTROLLER), 2738bd28ce00SJiri Slaby .driver_data = BUZZ_CONTROLLER }, 2739bd28ce00SJiri Slaby { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_WIRELESS_BUZZ_CONTROLLER), 2740bd28ce00SJiri Slaby .driver_data = BUZZ_CONTROLLER }, 2741bd28ce00SJiri Slaby /* PS3 BD Remote Control */ 2742bd28ce00SJiri Slaby { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_BDREMOTE), 2743bd28ce00SJiri Slaby .driver_data = PS3REMOTE }, 2744bd28ce00SJiri Slaby /* Logitech Harmony Adapter for PS3 */ 2745bd28ce00SJiri Slaby { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_PS3), 2746bd28ce00SJiri Slaby .driver_data = PS3REMOTE }, 274768a49e51SFrank Praznik /* SMK-Link PS3 BD Remote Control */ 274868a49e51SFrank Praznik { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SMK, USB_DEVICE_ID_SMK_PS3_BDREMOTE), 274968a49e51SFrank Praznik .driver_data = PS3REMOTE }, 27500bd88dd3SFrank Praznik /* Sony Dualshock 4 controllers for PS4 */ 27510bd88dd3SFrank Praznik { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER), 27528ab1676bSFrank Praznik .driver_data = DUALSHOCK4_CONTROLLER_USB }, 27530bd88dd3SFrank Praznik { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER), 27548ab1676bSFrank Praznik .driver_data = DUALSHOCK4_CONTROLLER_BT }, 2755cf1015d6SRoderick Colenbrander { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER_2), 2756cf1015d6SRoderick Colenbrander .driver_data = DUALSHOCK4_CONTROLLER_USB }, 2757cf1015d6SRoderick Colenbrander { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER_2), 2758cf1015d6SRoderick Colenbrander .driver_data = DUALSHOCK4_CONTROLLER_BT }, 2759de66a1a0SRoderick Colenbrander { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER_DONGLE), 276035f436c3SRoderick Colenbrander .driver_data = DUALSHOCK4_DONGLE }, 276174500cc8SScott Moreau /* Nyko Core Controller for PS3 */ 276274500cc8SScott Moreau { HID_USB_DEVICE(USB_VENDOR_ID_SINO_LITE, USB_DEVICE_ID_SINO_LITE_CONTROLLER), 276374500cc8SScott Moreau .driver_data = SIXAXIS_CONTROLLER_USB | SINO_LITE_CONTROLLER }, 2764bd28ce00SJiri Slaby { } 2765bd28ce00SJiri Slaby }; 2766bd28ce00SJiri Slaby MODULE_DEVICE_TABLE(hid, sony_devices); 2767bd28ce00SJiri Slaby 2768bd28ce00SJiri Slaby static struct hid_driver sony_driver = { 2769bd28ce00SJiri Slaby .name = "sony", 2770bd28ce00SJiri Slaby .id_table = sony_devices, 2771bd28ce00SJiri Slaby .input_mapping = sony_mapping, 2772ce8efc3bSFrank Praznik .input_configured = sony_input_configured, 2773bd28ce00SJiri Slaby .probe = sony_probe, 2774bd28ce00SJiri Slaby .remove = sony_remove, 2775bd28ce00SJiri Slaby .report_fixup = sony_report_fixup, 2776decd946cSFrank Praznik .raw_event = sony_raw_event, 2777decd946cSFrank Praznik 2778decd946cSFrank Praznik #ifdef CONFIG_PM 2779decd946cSFrank Praznik .suspend = sony_suspend, 2780decd946cSFrank Praznik .resume = sony_resume, 2781decd946cSFrank Praznik .reset_resume = sony_resume, 2782decd946cSFrank Praznik #endif 2783bd28ce00SJiri Slaby }; 27848025087aSFrank Praznik 27858025087aSFrank Praznik static int __init sony_init(void) 27868025087aSFrank Praznik { 27878025087aSFrank Praznik dbg_hid("Sony:%s\n", __func__); 27888025087aSFrank Praznik 27898025087aSFrank Praznik return hid_register_driver(&sony_driver); 27908025087aSFrank Praznik } 27918025087aSFrank Praznik 27928025087aSFrank Praznik static void __exit sony_exit(void) 27938025087aSFrank Praznik { 27948025087aSFrank Praznik dbg_hid("Sony:%s\n", __func__); 27958025087aSFrank Praznik 27968025087aSFrank Praznik hid_unregister_driver(&sony_driver); 27976c40065fSAntonio Ospite ida_destroy(&sony_device_id_allocator); 27988025087aSFrank Praznik } 27998025087aSFrank Praznik module_init(sony_init); 28008025087aSFrank Praznik module_exit(sony_exit); 2801bd28ce00SJiri Slaby 2802bd28ce00SJiri Slaby MODULE_LICENSE("GPL"); 2803