xref: /linux/drivers/hid/hid-sony.c (revision b9f7d245e34b1f42b5389b015962a2f022d4ece2)
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