xref: /linux/drivers/hid/hid-sony.c (revision 8b2513c313612541085a19551139e68ccab13b3f)
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>
11077147a3SFrank Praznik  *  Copyright (c) 2014 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>
39bd28ce00SJiri Slaby 
40bd28ce00SJiri Slaby #include "hid-ids.h"
41bd28ce00SJiri Slaby 
42f1c458caSSven Eckelmann #define VAIO_RDESC_CONSTANT       BIT(0)
43f1c458caSSven Eckelmann #define SIXAXIS_CONTROLLER_USB    BIT(1)
44f1c458caSSven Eckelmann #define SIXAXIS_CONTROLLER_BT     BIT(2)
45f1c458caSSven Eckelmann #define BUZZ_CONTROLLER           BIT(3)
46f1c458caSSven Eckelmann #define PS3REMOTE                 BIT(4)
478ab1676bSFrank Praznik #define DUALSHOCK4_CONTROLLER_USB BIT(5)
488ab1676bSFrank Praznik #define DUALSHOCK4_CONTROLLER_BT  BIT(6)
49b3bca326SSimon Wood #define MOTION_CONTROLLER_USB     BIT(7)
50b3bca326SSimon Wood #define MOTION_CONTROLLER_BT      BIT(8)
51cc6e0bbbSJiri Kosina 
52fee4e2d5SFrank Praznik #define SIXAXIS_CONTROLLER (SIXAXIS_CONTROLLER_USB | SIXAXIS_CONTROLLER_BT)
53b3bca326SSimon Wood #define MOTION_CONTROLLER (MOTION_CONTROLLER_USB | MOTION_CONTROLLER_BT)
5468330d83SFrank Praznik #define DUALSHOCK4_CONTROLLER (DUALSHOCK4_CONTROLLER_USB |\
5568330d83SFrank Praznik 				DUALSHOCK4_CONTROLLER_BT)
56fee4e2d5SFrank Praznik #define SONY_LED_SUPPORT (SIXAXIS_CONTROLLER | BUZZ_CONTROLLER |\
57c5e0c1c4SFrank Praznik 				DUALSHOCK4_CONTROLLER | MOTION_CONTROLLER)
5812e9a6d7SSimon Wood #define SONY_BATTERY_SUPPORT (SIXAXIS_CONTROLLER | DUALSHOCK4_CONTROLLER |\
5912e9a6d7SSimon Wood 				MOTION_CONTROLLER_BT)
60c5e0c1c4SFrank Praznik #define SONY_FF_SUPPORT (SIXAXIS_CONTROLLER | DUALSHOCK4_CONTROLLER |\
61c5e0c1c4SFrank Praznik 				MOTION_CONTROLLER)
6260781cf4SFrank Praznik 
6360781cf4SFrank Praznik #define MAX_LEDS 4
640a286ef2SSven Eckelmann 
654c3e8298SFrank Praznik /*
664c3e8298SFrank Praznik  * The Sixaxis reports both digital and analog values for each button on the
674c3e8298SFrank Praznik  * controller except for Start, Select and the PS button.  The controller ends
684c3e8298SFrank Praznik  * up reporting 27 axes which causes them to spill over into the multi-touch
694c3e8298SFrank Praznik  * axis values.  Additionally, the controller only has 20 actual, physical axes
704c3e8298SFrank Praznik  * so there are several unused axes in between the used ones.
714c3e8298SFrank Praznik  */
72c607fb8dSAntonio Ospite static __u8 sixaxis_rdesc[] = {
73fb705a6dSAntonio Ospite 	0x05, 0x01,         /*  Usage Page (Desktop),               */
744c3e8298SFrank Praznik 	0x09, 0x04,         /*  Usage (Joystick),                   */
75fb705a6dSAntonio Ospite 	0xA1, 0x01,         /*  Collection (Application),           */
76fb705a6dSAntonio Ospite 	0xA1, 0x02,         /*      Collection (Logical),           */
77fb705a6dSAntonio Ospite 	0x85, 0x01,         /*          Report ID (1),              */
78fb705a6dSAntonio Ospite 	0x75, 0x08,         /*          Report Size (8),            */
79fb705a6dSAntonio Ospite 	0x95, 0x01,         /*          Report Count (1),           */
80fb705a6dSAntonio Ospite 	0x15, 0x00,         /*          Logical Minimum (0),        */
81fb705a6dSAntonio Ospite 	0x26, 0xFF, 0x00,   /*          Logical Maximum (255),      */
82fb705a6dSAntonio Ospite 	0x81, 0x03,         /*          Input (Constant, Variable), */
83fb705a6dSAntonio Ospite 	0x75, 0x01,         /*          Report Size (1),            */
84fb705a6dSAntonio Ospite 	0x95, 0x13,         /*          Report Count (19),          */
85fb705a6dSAntonio Ospite 	0x15, 0x00,         /*          Logical Minimum (0),        */
86fb705a6dSAntonio Ospite 	0x25, 0x01,         /*          Logical Maximum (1),        */
87fb705a6dSAntonio Ospite 	0x35, 0x00,         /*          Physical Minimum (0),       */
88fb705a6dSAntonio Ospite 	0x45, 0x01,         /*          Physical Maximum (1),       */
89fb705a6dSAntonio Ospite 	0x05, 0x09,         /*          Usage Page (Button),        */
90fb705a6dSAntonio Ospite 	0x19, 0x01,         /*          Usage Minimum (01h),        */
91fb705a6dSAntonio Ospite 	0x29, 0x13,         /*          Usage Maximum (13h),        */
92fb705a6dSAntonio Ospite 	0x81, 0x02,         /*          Input (Variable),           */
93fb705a6dSAntonio Ospite 	0x75, 0x01,         /*          Report Size (1),            */
94fb705a6dSAntonio Ospite 	0x95, 0x0D,         /*          Report Count (13),          */
95fb705a6dSAntonio Ospite 	0x06, 0x00, 0xFF,   /*          Usage Page (FF00h),         */
96fb705a6dSAntonio Ospite 	0x81, 0x03,         /*          Input (Constant, Variable), */
97fb705a6dSAntonio Ospite 	0x15, 0x00,         /*          Logical Minimum (0),        */
98fb705a6dSAntonio Ospite 	0x26, 0xFF, 0x00,   /*          Logical Maximum (255),      */
99fb705a6dSAntonio Ospite 	0x05, 0x01,         /*          Usage Page (Desktop),       */
100fb705a6dSAntonio Ospite 	0x09, 0x01,         /*          Usage (Pointer),            */
101fb705a6dSAntonio Ospite 	0xA1, 0x00,         /*          Collection (Physical),      */
102fb705a6dSAntonio Ospite 	0x75, 0x08,         /*              Report Size (8),        */
103fb705a6dSAntonio Ospite 	0x95, 0x04,         /*              Report Count (4),       */
104fb705a6dSAntonio Ospite 	0x35, 0x00,         /*              Physical Minimum (0),   */
105fb705a6dSAntonio Ospite 	0x46, 0xFF, 0x00,   /*              Physical Maximum (255), */
106fb705a6dSAntonio Ospite 	0x09, 0x30,         /*              Usage (X),              */
107fb705a6dSAntonio Ospite 	0x09, 0x31,         /*              Usage (Y),              */
108fb705a6dSAntonio Ospite 	0x09, 0x32,         /*              Usage (Z),              */
109fb705a6dSAntonio Ospite 	0x09, 0x35,         /*              Usage (Rz),             */
110fb705a6dSAntonio Ospite 	0x81, 0x02,         /*              Input (Variable),       */
111fb705a6dSAntonio Ospite 	0xC0,               /*          End Collection,             */
112fb705a6dSAntonio Ospite 	0x05, 0x01,         /*          Usage Page (Desktop),       */
113fb705a6dSAntonio Ospite 	0x95, 0x13,         /*          Report Count (19),          */
114fb705a6dSAntonio Ospite 	0x09, 0x01,         /*          Usage (Pointer),            */
115fb705a6dSAntonio Ospite 	0x81, 0x02,         /*          Input (Variable),           */
116fb705a6dSAntonio Ospite 	0x95, 0x0C,         /*          Report Count (12),          */
117fb705a6dSAntonio Ospite 	0x81, 0x01,         /*          Input (Constant),           */
118fb705a6dSAntonio Ospite 	0x75, 0x10,         /*          Report Size (16),           */
119fb705a6dSAntonio Ospite 	0x95, 0x04,         /*          Report Count (4),           */
120fb705a6dSAntonio Ospite 	0x26, 0xFF, 0x03,   /*          Logical Maximum (1023),     */
121fb705a6dSAntonio Ospite 	0x46, 0xFF, 0x03,   /*          Physical Maximum (1023),    */
122fb705a6dSAntonio Ospite 	0x09, 0x01,         /*          Usage (Pointer),            */
123fb705a6dSAntonio Ospite 	0x81, 0x02,         /*          Input (Variable),           */
124fb705a6dSAntonio Ospite 	0xC0,               /*      End Collection,                 */
125fb705a6dSAntonio Ospite 	0xA1, 0x02,         /*      Collection (Logical),           */
126fb705a6dSAntonio Ospite 	0x85, 0x02,         /*          Report ID (2),              */
127fb705a6dSAntonio Ospite 	0x75, 0x08,         /*          Report Size (8),            */
128fb705a6dSAntonio Ospite 	0x95, 0x30,         /*          Report Count (48),          */
129fb705a6dSAntonio Ospite 	0x09, 0x01,         /*          Usage (Pointer),            */
130fb705a6dSAntonio Ospite 	0xB1, 0x02,         /*          Feature (Variable),         */
131fb705a6dSAntonio Ospite 	0xC0,               /*      End Collection,                 */
132fb705a6dSAntonio Ospite 	0xA1, 0x02,         /*      Collection (Logical),           */
133fb705a6dSAntonio Ospite 	0x85, 0xEE,         /*          Report ID (238),            */
134fb705a6dSAntonio Ospite 	0x75, 0x08,         /*          Report Size (8),            */
135fb705a6dSAntonio Ospite 	0x95, 0x30,         /*          Report Count (48),          */
136fb705a6dSAntonio Ospite 	0x09, 0x01,         /*          Usage (Pointer),            */
137fb705a6dSAntonio Ospite 	0xB1, 0x02,         /*          Feature (Variable),         */
138fb705a6dSAntonio Ospite 	0xC0,               /*      End Collection,                 */
139fb705a6dSAntonio Ospite 	0xA1, 0x02,         /*      Collection (Logical),           */
140fb705a6dSAntonio Ospite 	0x85, 0xEF,         /*          Report ID (239),            */
141fb705a6dSAntonio Ospite 	0x75, 0x08,         /*          Report Size (8),            */
142fb705a6dSAntonio Ospite 	0x95, 0x30,         /*          Report Count (48),          */
143fb705a6dSAntonio Ospite 	0x09, 0x01,         /*          Usage (Pointer),            */
144fb705a6dSAntonio Ospite 	0xB1, 0x02,         /*          Feature (Variable),         */
145fb705a6dSAntonio Ospite 	0xC0,               /*      End Collection,                 */
146fb705a6dSAntonio Ospite 	0xC0                /*  End Collection                      */
147e57a67daSMauro Carvalho Chehab };
148e57a67daSMauro Carvalho Chehab 
149c5e0c1c4SFrank Praznik /* PS/3 Motion controller */
150c5e0c1c4SFrank Praznik static __u8 motion_rdesc[] = {
151c5e0c1c4SFrank Praznik 	0x05, 0x01,         /*  Usage Page (Desktop),               */
152c5e0c1c4SFrank Praznik 	0x09, 0x04,         /*  Usage (Joystick),                   */
153c5e0c1c4SFrank Praznik 	0xA1, 0x01,         /*  Collection (Application),           */
154c5e0c1c4SFrank Praznik 	0xA1, 0x02,         /*      Collection (Logical),           */
155c5e0c1c4SFrank Praznik 	0x85, 0x01,         /*          Report ID (1),              */
156c5e0c1c4SFrank Praznik 	0x75, 0x01,         /*          Report Size (1),            */
157*8b2513c3SSimon Wood 	0x95, 0x15,         /*          Report Count (21),          */
158c5e0c1c4SFrank Praznik 	0x15, 0x00,         /*          Logical Minimum (0),        */
159c5e0c1c4SFrank Praznik 	0x25, 0x01,         /*          Logical Maximum (1),        */
160c5e0c1c4SFrank Praznik 	0x35, 0x00,         /*          Physical Minimum (0),       */
161c5e0c1c4SFrank Praznik 	0x45, 0x01,         /*          Physical Maximum (1),       */
162c5e0c1c4SFrank Praznik 	0x05, 0x09,         /*          Usage Page (Button),        */
163c5e0c1c4SFrank Praznik 	0x19, 0x01,         /*          Usage Minimum (01h),        */
164*8b2513c3SSimon Wood 	0x29, 0x15,         /*          Usage Maximum (15h),        */
165*8b2513c3SSimon Wood 	0x81, 0x02,         /*          Input (Variable),           * Buttons */
166*8b2513c3SSimon Wood 	0x95, 0x0B,         /*          Report Count (11),          */
167c5e0c1c4SFrank Praznik 	0x06, 0x00, 0xFF,   /*          Usage Page (FF00h),         */
168*8b2513c3SSimon Wood 	0x81, 0x03,         /*          Input (Constant, Variable), * Padding */
169c5e0c1c4SFrank Praznik 	0x15, 0x00,         /*          Logical Minimum (0),        */
170c5e0c1c4SFrank Praznik 	0x26, 0xFF, 0x00,   /*          Logical Maximum (255),      */
171c5e0c1c4SFrank Praznik 	0x05, 0x01,         /*          Usage Page (Desktop),       */
172c5e0c1c4SFrank Praznik 	0xA1, 0x00,         /*          Collection (Physical),      */
173c5e0c1c4SFrank Praznik 	0x75, 0x08,         /*              Report Size (8),        */
174*8b2513c3SSimon Wood 	0x95, 0x01,         /*              Report Count (1),       */
175c5e0c1c4SFrank Praznik 	0x35, 0x00,         /*              Physical Minimum (0),   */
176c5e0c1c4SFrank Praznik 	0x46, 0xFF, 0x00,   /*              Physical Maximum (255), */
177c5e0c1c4SFrank Praznik 	0x09, 0x30,         /*              Usage (X),              */
178*8b2513c3SSimon Wood 	0x81, 0x02,         /*              Input (Variable),       * Trigger */
179c5e0c1c4SFrank Praznik 	0xC0,               /*          End Collection,             */
180*8b2513c3SSimon Wood 	0x06, 0x00, 0xFF,   /*          Usage Page (FF00h),         */
181*8b2513c3SSimon Wood 	0x75, 0x08,         /*          Report Size (8),            */
182*8b2513c3SSimon Wood 	0x95, 0x07,         /*          Report Count (7),           * skip 7 bytes */
183*8b2513c3SSimon Wood 	0x81, 0x02,         /*          Input (Variable),           */
184c5e0c1c4SFrank Praznik 	0x05, 0x01,         /*          Usage Page (Desktop),       */
185c5e0c1c4SFrank Praznik 	0x75, 0x10,         /*          Report Size (16),           */
186*8b2513c3SSimon Wood 	0x46, 0xFF, 0xFF,   /*          Physical Maximum (65535),   */
187*8b2513c3SSimon Wood 	0x27, 0xFF, 0xFF, 0x00, 0x00, /*      Logical Maximum (65535),    */
188*8b2513c3SSimon Wood 	0x95, 0x03,         /*          Report Count (3),           * 3x Accels */
189*8b2513c3SSimon Wood 	0x09, 0x33,         /*              Usage (rX),             */
190*8b2513c3SSimon Wood 	0x09, 0x34,         /*              Usage (rY),             */
191*8b2513c3SSimon Wood 	0x09, 0x35,         /*              Usage (rZ),             */
192c5e0c1c4SFrank Praznik 	0x81, 0x02,         /*          Input (Variable),           */
193*8b2513c3SSimon Wood 	0x06, 0x00, 0xFF,   /*          Usage Page (FF00h),         */
194*8b2513c3SSimon Wood 	0x95, 0x03,         /*          Report Count (3),           * Skip Accels 2nd frame */
195*8b2513c3SSimon Wood 	0x81, 0x02,         /*          Input (Variable),           */
196*8b2513c3SSimon Wood 	0x05, 0x01,         /*          Usage Page (Desktop),       */
197*8b2513c3SSimon Wood 	0x09, 0x01,         /*          Usage (Pointer),            */
198*8b2513c3SSimon Wood 	0x95, 0x03,         /*          Report Count (3),           * 3x Gyros */
199*8b2513c3SSimon Wood 	0x81, 0x02,         /*          Input (Variable),           */
200*8b2513c3SSimon Wood 	0x06, 0x00, 0xFF,   /*          Usage Page (FF00h),         */
201*8b2513c3SSimon Wood 	0x95, 0x03,         /*          Report Count (3),           * Skip Gyros 2nd frame */
202*8b2513c3SSimon Wood 	0x81, 0x02,         /*          Input (Variable),           */
203*8b2513c3SSimon Wood 	0x75, 0x0C,         /*          Report Size (12),           */
204*8b2513c3SSimon Wood 	0x46, 0xFF, 0x0F,   /*          Physical Maximum (4095),    */
205*8b2513c3SSimon Wood 	0x26, 0xFF, 0x0F,   /*          Logical Maximum (4095),     */
206*8b2513c3SSimon Wood 	0x95, 0x04,         /*          Report Count (4),           * Skip Temp and Magnetometers */
207*8b2513c3SSimon Wood 	0x81, 0x02,         /*          Input (Variable),           */
208*8b2513c3SSimon Wood 	0x75, 0x08,         /*          Report Size (8),            */
209*8b2513c3SSimon Wood 	0x46, 0xFF, 0x00,   /*          Physical Maximum (255),     */
210*8b2513c3SSimon Wood 	0x26, 0xFF, 0x00,   /*          Logical Maximum (255),      */
211*8b2513c3SSimon Wood 	0x95, 0x06,         /*          Report Count (6),           * Skip Timestamp and Extension Bytes */
212*8b2513c3SSimon Wood 	0x81, 0x02,         /*          Input (Variable),           */
213*8b2513c3SSimon Wood 	0x75, 0x08,         /*          Report Size (8),            */
214*8b2513c3SSimon Wood 	0x95, 0x30,         /*          Report Count (48),          */
215*8b2513c3SSimon Wood 	0x09, 0x01,         /*          Usage (Pointer),            */
216*8b2513c3SSimon Wood 	0x91, 0x02,         /*          Output (Variable),          */
217*8b2513c3SSimon Wood 	0x75, 0x08,         /*          Report Size (8),            */
218*8b2513c3SSimon Wood 	0x95, 0x30,         /*          Report Count (48),          */
219*8b2513c3SSimon Wood 	0x09, 0x01,         /*          Usage (Pointer),            */
220*8b2513c3SSimon Wood 	0xB1, 0x02,         /*          Feature (Variable),         */
221c5e0c1c4SFrank Praznik 	0xC0,               /*      End Collection,                 */
222c5e0c1c4SFrank Praznik 	0xA1, 0x02,         /*      Collection (Logical),           */
223c5e0c1c4SFrank Praznik 	0x85, 0x02,         /*          Report ID (2),              */
224c5e0c1c4SFrank Praznik 	0x75, 0x08,         /*          Report Size (8),            */
225c5e0c1c4SFrank Praznik 	0x95, 0x30,         /*          Report Count (48),          */
226c5e0c1c4SFrank Praznik 	0x09, 0x01,         /*          Usage (Pointer),            */
227c5e0c1c4SFrank Praznik 	0xB1, 0x02,         /*          Feature (Variable),         */
228c5e0c1c4SFrank Praznik 	0xC0,               /*      End Collection,                 */
229c5e0c1c4SFrank Praznik 	0xA1, 0x02,         /*      Collection (Logical),           */
230c5e0c1c4SFrank Praznik 	0x85, 0xEE,         /*          Report ID (238),            */
231c5e0c1c4SFrank Praznik 	0x75, 0x08,         /*          Report Size (8),            */
232c5e0c1c4SFrank Praznik 	0x95, 0x30,         /*          Report Count (48),          */
233c5e0c1c4SFrank Praznik 	0x09, 0x01,         /*          Usage (Pointer),            */
234c5e0c1c4SFrank Praznik 	0xB1, 0x02,         /*          Feature (Variable),         */
235c5e0c1c4SFrank Praznik 	0xC0,               /*      End Collection,                 */
236c5e0c1c4SFrank Praznik 	0xA1, 0x02,         /*      Collection (Logical),           */
237c5e0c1c4SFrank Praznik 	0x85, 0xEF,         /*          Report ID (239),            */
238c5e0c1c4SFrank Praznik 	0x75, 0x08,         /*          Report Size (8),            */
239c5e0c1c4SFrank Praznik 	0x95, 0x30,         /*          Report Count (48),          */
240c5e0c1c4SFrank Praznik 	0x09, 0x01,         /*          Usage (Pointer),            */
241c5e0c1c4SFrank Praznik 	0xB1, 0x02,         /*          Feature (Variable),         */
242c5e0c1c4SFrank Praznik 	0xC0,               /*      End Collection,                 */
243c5e0c1c4SFrank Praznik 	0xC0                /*  End Collection                      */
244c5e0c1c4SFrank Praznik };
245c5e0c1c4SFrank Praznik 
246c5e0c1c4SFrank Praznik 
247ad142b9eSFrank Praznik /*
248ad142b9eSFrank Praznik  * The default descriptor doesn't provide mapping for the accelerometers
24958d7027bSFrank Praznik  * or orientation sensors.  This fixed descriptor maps the accelerometers
25058d7027bSFrank Praznik  * to usage values 0x40, 0x41 and 0x42 and maps the orientation sensors
25158d7027bSFrank Praznik  * to usage values 0x43, 0x44 and 0x45.
25258d7027bSFrank Praznik  */
253ed19d8cfSFrank Praznik static u8 dualshock4_usb_rdesc[] = {
25458d7027bSFrank Praznik 	0x05, 0x01,         /*  Usage Page (Desktop),               */
25558d7027bSFrank Praznik 	0x09, 0x05,         /*  Usage (Gamepad),                    */
25658d7027bSFrank Praznik 	0xA1, 0x01,         /*  Collection (Application),           */
25758d7027bSFrank Praznik 	0x85, 0x01,         /*      Report ID (1),                  */
25858d7027bSFrank Praznik 	0x09, 0x30,         /*      Usage (X),                      */
25958d7027bSFrank Praznik 	0x09, 0x31,         /*      Usage (Y),                      */
26058d7027bSFrank Praznik 	0x09, 0x32,         /*      Usage (Z),                      */
26158d7027bSFrank Praznik 	0x09, 0x35,         /*      Usage (Rz),                     */
26258d7027bSFrank Praznik 	0x15, 0x00,         /*      Logical Minimum (0),            */
26358d7027bSFrank Praznik 	0x26, 0xFF, 0x00,   /*      Logical Maximum (255),          */
26458d7027bSFrank Praznik 	0x75, 0x08,         /*      Report Size (8),                */
26558d7027bSFrank Praznik 	0x95, 0x04,         /*      Report Count (4),               */
26658d7027bSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
26758d7027bSFrank Praznik 	0x09, 0x39,         /*      Usage (Hat Switch),             */
26858d7027bSFrank Praznik 	0x15, 0x00,         /*      Logical Minimum (0),            */
26958d7027bSFrank Praznik 	0x25, 0x07,         /*      Logical Maximum (7),            */
27058d7027bSFrank Praznik 	0x35, 0x00,         /*      Physical Minimum (0),           */
27158d7027bSFrank Praznik 	0x46, 0x3B, 0x01,   /*      Physical Maximum (315),         */
27258d7027bSFrank Praznik 	0x65, 0x14,         /*      Unit (Degrees),                 */
27358d7027bSFrank Praznik 	0x75, 0x04,         /*      Report Size (4),                */
27458d7027bSFrank Praznik 	0x95, 0x01,         /*      Report Count (1),               */
27558d7027bSFrank Praznik 	0x81, 0x42,         /*      Input (Variable, Null State),   */
27658d7027bSFrank Praznik 	0x65, 0x00,         /*      Unit,                           */
27758d7027bSFrank Praznik 	0x05, 0x09,         /*      Usage Page (Button),            */
27858d7027bSFrank Praznik 	0x19, 0x01,         /*      Usage Minimum (01h),            */
27958d7027bSFrank Praznik 	0x29, 0x0E,         /*      Usage Maximum (0Eh),            */
28058d7027bSFrank Praznik 	0x15, 0x00,         /*      Logical Minimum (0),            */
28158d7027bSFrank Praznik 	0x25, 0x01,         /*      Logical Maximum (1),            */
28258d7027bSFrank Praznik 	0x75, 0x01,         /*      Report Size (1),                */
28358d7027bSFrank Praznik 	0x95, 0x0E,         /*      Report Count (14),              */
28458d7027bSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
28558d7027bSFrank Praznik 	0x06, 0x00, 0xFF,   /*      Usage Page (FF00h),             */
28658d7027bSFrank Praznik 	0x09, 0x20,         /*      Usage (20h),                    */
28758d7027bSFrank Praznik 	0x75, 0x06,         /*      Report Size (6),                */
28858d7027bSFrank Praznik 	0x95, 0x01,         /*      Report Count (1),               */
28958d7027bSFrank Praznik 	0x15, 0x00,         /*      Logical Minimum (0),            */
290fb291cbdSFrank Praznik 	0x25, 0x3F,         /*      Logical Maximum (63),           */
29158d7027bSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
29258d7027bSFrank Praznik 	0x05, 0x01,         /*      Usage Page (Desktop),           */
29358d7027bSFrank Praznik 	0x09, 0x33,         /*      Usage (Rx),                     */
29458d7027bSFrank Praznik 	0x09, 0x34,         /*      Usage (Ry),                     */
29558d7027bSFrank Praznik 	0x15, 0x00,         /*      Logical Minimum (0),            */
29658d7027bSFrank Praznik 	0x26, 0xFF, 0x00,   /*      Logical Maximum (255),          */
29758d7027bSFrank Praznik 	0x75, 0x08,         /*      Report Size (8),                */
29858d7027bSFrank Praznik 	0x95, 0x02,         /*      Report Count (2),               */
29958d7027bSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
30058d7027bSFrank Praznik 	0x06, 0x00, 0xFF,   /*      Usage Page (FF00h),             */
30158d7027bSFrank Praznik 	0x09, 0x21,         /*      Usage (21h),                    */
30258d7027bSFrank Praznik 	0x95, 0x03,         /*      Report Count (3),               */
30358d7027bSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
30458d7027bSFrank Praznik 	0x05, 0x01,         /*      Usage Page (Desktop),           */
30558d7027bSFrank Praznik 	0x19, 0x40,         /*      Usage Minimum (40h),            */
30658d7027bSFrank Praznik 	0x29, 0x42,         /*      Usage Maximum (42h),            */
30758d7027bSFrank Praznik 	0x16, 0x00, 0x80,   /*      Logical Minimum (-32768),       */
30858d7027bSFrank Praznik 	0x26, 0x00, 0x7F,   /*      Logical Maximum (32767),        */
30958d7027bSFrank Praznik 	0x75, 0x10,         /*      Report Size (16),               */
31058d7027bSFrank Praznik 	0x95, 0x03,         /*      Report Count (3),               */
31158d7027bSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
31258d7027bSFrank Praznik 	0x19, 0x43,         /*      Usage Minimum (43h),            */
31358d7027bSFrank Praznik 	0x29, 0x45,         /*      Usage Maximum (45h),            */
314fb291cbdSFrank Praznik 	0x16, 0x00, 0xE0,   /*      Logical Minimum (-8192),        */
315fb291cbdSFrank Praznik 	0x26, 0xFF, 0x1F,   /*      Logical Maximum (8191),         */
31658d7027bSFrank Praznik 	0x95, 0x03,         /*      Report Count (3),               */
31758d7027bSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
31858d7027bSFrank Praznik 	0x06, 0x00, 0xFF,   /*      Usage Page (FF00h),             */
31958d7027bSFrank Praznik 	0x09, 0x21,         /*      Usage (21h),                    */
32058d7027bSFrank Praznik 	0x15, 0x00,         /*      Logical Minimum (0),            */
321fb291cbdSFrank Praznik 	0x26, 0xFF, 0x00,   /*      Logical Maximum (255),          */
32258d7027bSFrank Praznik 	0x75, 0x08,         /*      Report Size (8),                */
32358d7027bSFrank Praznik 	0x95, 0x27,         /*      Report Count (39),              */
32458d7027bSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
32558d7027bSFrank Praznik 	0x85, 0x05,         /*      Report ID (5),                  */
32658d7027bSFrank Praznik 	0x09, 0x22,         /*      Usage (22h),                    */
32758d7027bSFrank Praznik 	0x95, 0x1F,         /*      Report Count (31),              */
32858d7027bSFrank Praznik 	0x91, 0x02,         /*      Output (Variable),              */
32958d7027bSFrank Praznik 	0x85, 0x04,         /*      Report ID (4),                  */
33058d7027bSFrank Praznik 	0x09, 0x23,         /*      Usage (23h),                    */
33158d7027bSFrank Praznik 	0x95, 0x24,         /*      Report Count (36),              */
33258d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
33358d7027bSFrank Praznik 	0x85, 0x02,         /*      Report ID (2),                  */
33458d7027bSFrank Praznik 	0x09, 0x24,         /*      Usage (24h),                    */
33558d7027bSFrank Praznik 	0x95, 0x24,         /*      Report Count (36),              */
33658d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
33758d7027bSFrank Praznik 	0x85, 0x08,         /*      Report ID (8),                  */
33858d7027bSFrank Praznik 	0x09, 0x25,         /*      Usage (25h),                    */
33958d7027bSFrank Praznik 	0x95, 0x03,         /*      Report Count (3),               */
34058d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
34158d7027bSFrank Praznik 	0x85, 0x10,         /*      Report ID (16),                 */
34258d7027bSFrank Praznik 	0x09, 0x26,         /*      Usage (26h),                    */
34358d7027bSFrank Praznik 	0x95, 0x04,         /*      Report Count (4),               */
34458d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
34558d7027bSFrank Praznik 	0x85, 0x11,         /*      Report ID (17),                 */
34658d7027bSFrank Praznik 	0x09, 0x27,         /*      Usage (27h),                    */
34758d7027bSFrank Praznik 	0x95, 0x02,         /*      Report Count (2),               */
34858d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
34958d7027bSFrank Praznik 	0x85, 0x12,         /*      Report ID (18),                 */
35058d7027bSFrank Praznik 	0x06, 0x02, 0xFF,   /*      Usage Page (FF02h),             */
35158d7027bSFrank Praznik 	0x09, 0x21,         /*      Usage (21h),                    */
35258d7027bSFrank Praznik 	0x95, 0x0F,         /*      Report Count (15),              */
35358d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
35458d7027bSFrank Praznik 	0x85, 0x13,         /*      Report ID (19),                 */
35558d7027bSFrank Praznik 	0x09, 0x22,         /*      Usage (22h),                    */
35658d7027bSFrank Praznik 	0x95, 0x16,         /*      Report Count (22),              */
35758d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
35858d7027bSFrank Praznik 	0x85, 0x14,         /*      Report ID (20),                 */
35958d7027bSFrank Praznik 	0x06, 0x05, 0xFF,   /*      Usage Page (FF05h),             */
36058d7027bSFrank Praznik 	0x09, 0x20,         /*      Usage (20h),                    */
36158d7027bSFrank Praznik 	0x95, 0x10,         /*      Report Count (16),              */
36258d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
36358d7027bSFrank Praznik 	0x85, 0x15,         /*      Report ID (21),                 */
36458d7027bSFrank Praznik 	0x09, 0x21,         /*      Usage (21h),                    */
36558d7027bSFrank Praznik 	0x95, 0x2C,         /*      Report Count (44),              */
36658d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
36758d7027bSFrank Praznik 	0x06, 0x80, 0xFF,   /*      Usage Page (FF80h),             */
36858d7027bSFrank Praznik 	0x85, 0x80,         /*      Report ID (128),                */
36958d7027bSFrank Praznik 	0x09, 0x20,         /*      Usage (20h),                    */
37058d7027bSFrank Praznik 	0x95, 0x06,         /*      Report Count (6),               */
37158d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
37258d7027bSFrank Praznik 	0x85, 0x81,         /*      Report ID (129),                */
37358d7027bSFrank Praznik 	0x09, 0x21,         /*      Usage (21h),                    */
37458d7027bSFrank Praznik 	0x95, 0x06,         /*      Report Count (6),               */
37558d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
37658d7027bSFrank Praznik 	0x85, 0x82,         /*      Report ID (130),                */
37758d7027bSFrank Praznik 	0x09, 0x22,         /*      Usage (22h),                    */
37858d7027bSFrank Praznik 	0x95, 0x05,         /*      Report Count (5),               */
37958d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
38058d7027bSFrank Praznik 	0x85, 0x83,         /*      Report ID (131),                */
38158d7027bSFrank Praznik 	0x09, 0x23,         /*      Usage (23h),                    */
38258d7027bSFrank Praznik 	0x95, 0x01,         /*      Report Count (1),               */
38358d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
38458d7027bSFrank Praznik 	0x85, 0x84,         /*      Report ID (132),                */
38558d7027bSFrank Praznik 	0x09, 0x24,         /*      Usage (24h),                    */
38658d7027bSFrank Praznik 	0x95, 0x04,         /*      Report Count (4),               */
38758d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
38858d7027bSFrank Praznik 	0x85, 0x85,         /*      Report ID (133),                */
38958d7027bSFrank Praznik 	0x09, 0x25,         /*      Usage (25h),                    */
39058d7027bSFrank Praznik 	0x95, 0x06,         /*      Report Count (6),               */
39158d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
39258d7027bSFrank Praznik 	0x85, 0x86,         /*      Report ID (134),                */
39358d7027bSFrank Praznik 	0x09, 0x26,         /*      Usage (26h),                    */
39458d7027bSFrank Praznik 	0x95, 0x06,         /*      Report Count (6),               */
39558d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
39658d7027bSFrank Praznik 	0x85, 0x87,         /*      Report ID (135),                */
39758d7027bSFrank Praznik 	0x09, 0x27,         /*      Usage (27h),                    */
39858d7027bSFrank Praznik 	0x95, 0x23,         /*      Report Count (35),              */
39958d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
40058d7027bSFrank Praznik 	0x85, 0x88,         /*      Report ID (136),                */
40158d7027bSFrank Praznik 	0x09, 0x28,         /*      Usage (28h),                    */
40258d7027bSFrank Praznik 	0x95, 0x22,         /*      Report Count (34),              */
40358d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
40458d7027bSFrank Praznik 	0x85, 0x89,         /*      Report ID (137),                */
40558d7027bSFrank Praznik 	0x09, 0x29,         /*      Usage (29h),                    */
40658d7027bSFrank Praznik 	0x95, 0x02,         /*      Report Count (2),               */
40758d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
40858d7027bSFrank Praznik 	0x85, 0x90,         /*      Report ID (144),                */
40958d7027bSFrank Praznik 	0x09, 0x30,         /*      Usage (30h),                    */
41058d7027bSFrank Praznik 	0x95, 0x05,         /*      Report Count (5),               */
41158d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
41258d7027bSFrank Praznik 	0x85, 0x91,         /*      Report ID (145),                */
41358d7027bSFrank Praznik 	0x09, 0x31,         /*      Usage (31h),                    */
41458d7027bSFrank Praznik 	0x95, 0x03,         /*      Report Count (3),               */
41558d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
41658d7027bSFrank Praznik 	0x85, 0x92,         /*      Report ID (146),                */
41758d7027bSFrank Praznik 	0x09, 0x32,         /*      Usage (32h),                    */
41858d7027bSFrank Praznik 	0x95, 0x03,         /*      Report Count (3),               */
41958d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
42058d7027bSFrank Praznik 	0x85, 0x93,         /*      Report ID (147),                */
42158d7027bSFrank Praznik 	0x09, 0x33,         /*      Usage (33h),                    */
42258d7027bSFrank Praznik 	0x95, 0x0C,         /*      Report Count (12),              */
42358d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
42458d7027bSFrank Praznik 	0x85, 0xA0,         /*      Report ID (160),                */
42558d7027bSFrank Praznik 	0x09, 0x40,         /*      Usage (40h),                    */
42658d7027bSFrank Praznik 	0x95, 0x06,         /*      Report Count (6),               */
42758d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
42858d7027bSFrank Praznik 	0x85, 0xA1,         /*      Report ID (161),                */
42958d7027bSFrank Praznik 	0x09, 0x41,         /*      Usage (41h),                    */
43058d7027bSFrank Praznik 	0x95, 0x01,         /*      Report Count (1),               */
43158d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
43258d7027bSFrank Praznik 	0x85, 0xA2,         /*      Report ID (162),                */
43358d7027bSFrank Praznik 	0x09, 0x42,         /*      Usage (42h),                    */
43458d7027bSFrank Praznik 	0x95, 0x01,         /*      Report Count (1),               */
43558d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
43658d7027bSFrank Praznik 	0x85, 0xA3,         /*      Report ID (163),                */
43758d7027bSFrank Praznik 	0x09, 0x43,         /*      Usage (43h),                    */
43858d7027bSFrank Praznik 	0x95, 0x30,         /*      Report Count (48),              */
43958d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
44058d7027bSFrank Praznik 	0x85, 0xA4,         /*      Report ID (164),                */
44158d7027bSFrank Praznik 	0x09, 0x44,         /*      Usage (44h),                    */
44258d7027bSFrank Praznik 	0x95, 0x0D,         /*      Report Count (13),              */
44358d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
44458d7027bSFrank Praznik 	0x85, 0xA5,         /*      Report ID (165),                */
44558d7027bSFrank Praznik 	0x09, 0x45,         /*      Usage (45h),                    */
44658d7027bSFrank Praznik 	0x95, 0x15,         /*      Report Count (21),              */
44758d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
44858d7027bSFrank Praznik 	0x85, 0xA6,         /*      Report ID (166),                */
44958d7027bSFrank Praznik 	0x09, 0x46,         /*      Usage (46h),                    */
45058d7027bSFrank Praznik 	0x95, 0x15,         /*      Report Count (21),              */
45158d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
45258d7027bSFrank Praznik 	0x85, 0xF0,         /*      Report ID (240),                */
45358d7027bSFrank Praznik 	0x09, 0x47,         /*      Usage (47h),                    */
45458d7027bSFrank Praznik 	0x95, 0x3F,         /*      Report Count (63),              */
45558d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
45658d7027bSFrank Praznik 	0x85, 0xF1,         /*      Report ID (241),                */
45758d7027bSFrank Praznik 	0x09, 0x48,         /*      Usage (48h),                    */
45858d7027bSFrank Praznik 	0x95, 0x3F,         /*      Report Count (63),              */
45958d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
46058d7027bSFrank Praznik 	0x85, 0xF2,         /*      Report ID (242),                */
46158d7027bSFrank Praznik 	0x09, 0x49,         /*      Usage (49h),                    */
46258d7027bSFrank Praznik 	0x95, 0x0F,         /*      Report Count (15),              */
46358d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
46458d7027bSFrank Praznik 	0x85, 0xA7,         /*      Report ID (167),                */
46558d7027bSFrank Praznik 	0x09, 0x4A,         /*      Usage (4Ah),                    */
46658d7027bSFrank Praznik 	0x95, 0x01,         /*      Report Count (1),               */
46758d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
46858d7027bSFrank Praznik 	0x85, 0xA8,         /*      Report ID (168),                */
46958d7027bSFrank Praznik 	0x09, 0x4B,         /*      Usage (4Bh),                    */
47058d7027bSFrank Praznik 	0x95, 0x01,         /*      Report Count (1),               */
47158d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
47258d7027bSFrank Praznik 	0x85, 0xA9,         /*      Report ID (169),                */
47358d7027bSFrank Praznik 	0x09, 0x4C,         /*      Usage (4Ch),                    */
47458d7027bSFrank Praznik 	0x95, 0x08,         /*      Report Count (8),               */
47558d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
47658d7027bSFrank Praznik 	0x85, 0xAA,         /*      Report ID (170),                */
47758d7027bSFrank Praznik 	0x09, 0x4E,         /*      Usage (4Eh),                    */
47858d7027bSFrank Praznik 	0x95, 0x01,         /*      Report Count (1),               */
47958d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
48058d7027bSFrank Praznik 	0x85, 0xAB,         /*      Report ID (171),                */
48158d7027bSFrank Praznik 	0x09, 0x4F,         /*      Usage (4Fh),                    */
48258d7027bSFrank Praznik 	0x95, 0x39,         /*      Report Count (57),              */
48358d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
48458d7027bSFrank Praznik 	0x85, 0xAC,         /*      Report ID (172),                */
48558d7027bSFrank Praznik 	0x09, 0x50,         /*      Usage (50h),                    */
48658d7027bSFrank Praznik 	0x95, 0x39,         /*      Report Count (57),              */
48758d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
48858d7027bSFrank Praznik 	0x85, 0xAD,         /*      Report ID (173),                */
48958d7027bSFrank Praznik 	0x09, 0x51,         /*      Usage (51h),                    */
49058d7027bSFrank Praznik 	0x95, 0x0B,         /*      Report Count (11),              */
49158d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
49258d7027bSFrank Praznik 	0x85, 0xAE,         /*      Report ID (174),                */
49358d7027bSFrank Praznik 	0x09, 0x52,         /*      Usage (52h),                    */
49458d7027bSFrank Praznik 	0x95, 0x01,         /*      Report Count (1),               */
49558d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
49658d7027bSFrank Praznik 	0x85, 0xAF,         /*      Report ID (175),                */
49758d7027bSFrank Praznik 	0x09, 0x53,         /*      Usage (53h),                    */
49858d7027bSFrank Praznik 	0x95, 0x02,         /*      Report Count (2),               */
49958d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
50058d7027bSFrank Praznik 	0x85, 0xB0,         /*      Report ID (176),                */
50158d7027bSFrank Praznik 	0x09, 0x54,         /*      Usage (54h),                    */
50258d7027bSFrank Praznik 	0x95, 0x3F,         /*      Report Count (63),              */
50358d7027bSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
50458d7027bSFrank Praznik 	0xC0                /*  End Collection                      */
505ed19d8cfSFrank Praznik };
506ed19d8cfSFrank Praznik 
507ad142b9eSFrank Praznik /*
508ad142b9eSFrank Praznik  * The default behavior of the Dualshock 4 is to send reports using report
509077147a3SFrank Praznik  * type 1 when running over Bluetooth. However, when feature report 2 is
510077147a3SFrank Praznik  * requested during the controller initialization it starts sending input
511077147a3SFrank Praznik  * reports in report 17.  Since report 17 is undefined in the default HID
512d829674dSFrank Praznik  * descriptor the button and axis definitions must be moved to report 17 or
513077147a3SFrank Praznik  * the HID layer won't process the received input.
514d829674dSFrank Praznik  */
515d829674dSFrank Praznik static u8 dualshock4_bt_rdesc[] = {
516d829674dSFrank Praznik 	0x05, 0x01,         /*  Usage Page (Desktop),               */
517d829674dSFrank Praznik 	0x09, 0x05,         /*  Usage (Gamepad),                    */
518d829674dSFrank Praznik 	0xA1, 0x01,         /*  Collection (Application),           */
519d829674dSFrank Praznik 	0x85, 0x01,         /*      Report ID (1),                  */
520d829674dSFrank Praznik 	0x75, 0x08,         /*      Report Size (8),                */
521d829674dSFrank Praznik 	0x95, 0x0A,         /*      Report Count (9),               */
522d829674dSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
523d829674dSFrank Praznik 	0x06, 0x04, 0xFF,   /*      Usage Page (FF04h),             */
524d829674dSFrank Praznik 	0x85, 0x02,         /*      Report ID (2),                  */
525d829674dSFrank Praznik 	0x09, 0x24,         /*      Usage (24h),                    */
526d829674dSFrank Praznik 	0x95, 0x24,         /*      Report Count (36),              */
527d829674dSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
528d829674dSFrank Praznik 	0x85, 0xA3,         /*      Report ID (163),                */
529d829674dSFrank Praznik 	0x09, 0x25,         /*      Usage (25h),                    */
530d829674dSFrank Praznik 	0x95, 0x30,         /*      Report Count (48),              */
531d829674dSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
532d829674dSFrank Praznik 	0x85, 0x05,         /*      Report ID (5),                  */
533d829674dSFrank Praznik 	0x09, 0x26,         /*      Usage (26h),                    */
534d829674dSFrank Praznik 	0x95, 0x28,         /*      Report Count (40),              */
535d829674dSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
536d829674dSFrank Praznik 	0x85, 0x06,         /*      Report ID (6),                  */
537d829674dSFrank Praznik 	0x09, 0x27,         /*      Usage (27h),                    */
538d829674dSFrank Praznik 	0x95, 0x34,         /*      Report Count (52),              */
539d829674dSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
540d829674dSFrank Praznik 	0x85, 0x07,         /*      Report ID (7),                  */
541d829674dSFrank Praznik 	0x09, 0x28,         /*      Usage (28h),                    */
542d829674dSFrank Praznik 	0x95, 0x30,         /*      Report Count (48),              */
543d829674dSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
544d829674dSFrank Praznik 	0x85, 0x08,         /*      Report ID (8),                  */
545d829674dSFrank Praznik 	0x09, 0x29,         /*      Usage (29h),                    */
546d829674dSFrank Praznik 	0x95, 0x2F,         /*      Report Count (47),              */
547d829674dSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
548d829674dSFrank Praznik 	0x06, 0x03, 0xFF,   /*      Usage Page (FF03h),             */
549d829674dSFrank Praznik 	0x85, 0x03,         /*      Report ID (3),                  */
550d829674dSFrank Praznik 	0x09, 0x21,         /*      Usage (21h),                    */
551d829674dSFrank Praznik 	0x95, 0x26,         /*      Report Count (38),              */
552d829674dSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
553d829674dSFrank Praznik 	0x85, 0x04,         /*      Report ID (4),                  */
554d829674dSFrank Praznik 	0x09, 0x22,         /*      Usage (22h),                    */
555d829674dSFrank Praznik 	0x95, 0x2E,         /*      Report Count (46),              */
556d829674dSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
557d829674dSFrank Praznik 	0x85, 0xF0,         /*      Report ID (240),                */
558d829674dSFrank Praznik 	0x09, 0x47,         /*      Usage (47h),                    */
559d829674dSFrank Praznik 	0x95, 0x3F,         /*      Report Count (63),              */
560d829674dSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
561d829674dSFrank Praznik 	0x85, 0xF1,         /*      Report ID (241),                */
562d829674dSFrank Praznik 	0x09, 0x48,         /*      Usage (48h),                    */
563d829674dSFrank Praznik 	0x95, 0x3F,         /*      Report Count (63),              */
564d829674dSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
565d829674dSFrank Praznik 	0x85, 0xF2,         /*      Report ID (242),                */
566d829674dSFrank Praznik 	0x09, 0x49,         /*      Usage (49h),                    */
567d829674dSFrank Praznik 	0x95, 0x0F,         /*      Report Count (15),              */
568d829674dSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
569d829674dSFrank Praznik 	0x85, 0x11,         /*      Report ID (17),                 */
570d829674dSFrank Praznik 	0x06, 0x00, 0xFF,   /*      Usage Page (FF00h),             */
571d829674dSFrank Praznik 	0x09, 0x20,         /*      Usage (20h),                    */
572d829674dSFrank Praznik 	0x95, 0x02,         /*      Report Count (2),               */
573d829674dSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
574d829674dSFrank Praznik 	0x05, 0x01,         /*      Usage Page (Desktop),           */
575d829674dSFrank Praznik 	0x09, 0x30,         /*      Usage (X),                      */
576d829674dSFrank Praznik 	0x09, 0x31,         /*      Usage (Y),                      */
577d829674dSFrank Praznik 	0x09, 0x32,         /*      Usage (Z),                      */
578d829674dSFrank Praznik 	0x09, 0x35,         /*      Usage (Rz),                     */
579d829674dSFrank Praznik 	0x15, 0x00,         /*      Logical Minimum (0),            */
580d829674dSFrank Praznik 	0x26, 0xFF, 0x00,   /*      Logical Maximum (255),          */
581d829674dSFrank Praznik 	0x75, 0x08,         /*      Report Size (8),                */
582d829674dSFrank Praznik 	0x95, 0x04,         /*      Report Count (4),               */
583d829674dSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
584d829674dSFrank Praznik 	0x09, 0x39,         /*      Usage (Hat Switch),             */
585d829674dSFrank Praznik 	0x15, 0x00,         /*      Logical Minimum (0),            */
586d829674dSFrank Praznik 	0x25, 0x07,         /*      Logical Maximum (7),            */
587d829674dSFrank Praznik 	0x75, 0x04,         /*      Report Size (4),                */
588d829674dSFrank Praznik 	0x95, 0x01,         /*      Report Count (1),               */
589d829674dSFrank Praznik 	0x81, 0x42,         /*      Input (Variable, Null State),   */
590d829674dSFrank Praznik 	0x05, 0x09,         /*      Usage Page (Button),            */
591d829674dSFrank Praznik 	0x19, 0x01,         /*      Usage Minimum (01h),            */
592d829674dSFrank Praznik 	0x29, 0x0E,         /*      Usage Maximum (0Eh),            */
593d829674dSFrank Praznik 	0x15, 0x00,         /*      Logical Minimum (0),            */
594d829674dSFrank Praznik 	0x25, 0x01,         /*      Logical Maximum (1),            */
595d829674dSFrank Praznik 	0x75, 0x01,         /*      Report Size (1),                */
596d829674dSFrank Praznik 	0x95, 0x0E,         /*      Report Count (14),              */
597d829674dSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
598d829674dSFrank Praznik 	0x75, 0x06,         /*      Report Size (6),                */
599d829674dSFrank Praznik 	0x95, 0x01,         /*      Report Count (1),               */
600d829674dSFrank Praznik 	0x81, 0x01,         /*      Input (Constant),               */
601d829674dSFrank Praznik 	0x05, 0x01,         /*      Usage Page (Desktop),           */
602d829674dSFrank Praznik 	0x09, 0x33,         /*      Usage (Rx),                     */
603d829674dSFrank Praznik 	0x09, 0x34,         /*      Usage (Ry),                     */
604d829674dSFrank Praznik 	0x15, 0x00,         /*      Logical Minimum (0),            */
605d829674dSFrank Praznik 	0x26, 0xFF, 0x00,   /*      Logical Maximum (255),          */
606d829674dSFrank Praznik 	0x75, 0x08,         /*      Report Size (8),                */
607d829674dSFrank Praznik 	0x95, 0x02,         /*      Report Count (2),               */
608d829674dSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
609d829674dSFrank Praznik 	0x06, 0x00, 0xFF,   /*      Usage Page (FF00h),             */
610d829674dSFrank Praznik 	0x09, 0x20,         /*      Usage (20h),                    */
611d829674dSFrank Praznik 	0x95, 0x03,         /*      Report Count (3),               */
612d829674dSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
613d829674dSFrank Praznik 	0x05, 0x01,         /*      Usage Page (Desktop),           */
614d829674dSFrank Praznik 	0x19, 0x40,         /*      Usage Minimum (40h),            */
615d829674dSFrank Praznik 	0x29, 0x42,         /*      Usage Maximum (42h),            */
616d829674dSFrank Praznik 	0x16, 0x00, 0x80,   /*      Logical Minimum (-32768),       */
617d829674dSFrank Praznik 	0x26, 0x00, 0x7F,   /*      Logical Maximum (32767),        */
618d829674dSFrank Praznik 	0x75, 0x10,         /*      Report Size (16),               */
619d829674dSFrank Praznik 	0x95, 0x03,         /*      Report Count (3),               */
620d829674dSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
621d829674dSFrank Praznik 	0x19, 0x43,         /*      Usage Minimum (43h),            */
622d829674dSFrank Praznik 	0x29, 0x45,         /*      Usage Maximum (45h),            */
623fb291cbdSFrank Praznik 	0x16, 0x00, 0xE0,   /*      Logical Minimum (-8192),        */
624fb291cbdSFrank Praznik 	0x26, 0xFF, 0x1F,   /*      Logical Maximum (8191),         */
625d829674dSFrank Praznik 	0x95, 0x03,         /*      Report Count (3),               */
626d829674dSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
627d829674dSFrank Praznik 	0x06, 0x00, 0xFF,   /*      Usage Page (FF00h),             */
628d829674dSFrank Praznik 	0x09, 0x20,         /*      Usage (20h),                    */
629d829674dSFrank Praznik 	0x15, 0x00,         /*      Logical Minimum (0),            */
630d829674dSFrank Praznik 	0x26, 0xFF, 0x00,   /*      Logical Maximum (255),          */
631d829674dSFrank Praznik 	0x75, 0x08,         /*      Report Size (8),                */
632d829674dSFrank Praznik 	0x95, 0x31,         /*      Report Count (51),              */
633d829674dSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
634d829674dSFrank Praznik 	0x09, 0x21,         /*      Usage (21h),                    */
635d829674dSFrank Praznik 	0x75, 0x08,         /*      Report Size (8),                */
636d829674dSFrank Praznik 	0x95, 0x4D,         /*      Report Count (77),              */
637d829674dSFrank Praznik 	0x91, 0x02,         /*      Output (Variable),              */
638d829674dSFrank Praznik 	0x85, 0x12,         /*      Report ID (18),                 */
639d829674dSFrank Praznik 	0x09, 0x22,         /*      Usage (22h),                    */
640d829674dSFrank Praznik 	0x95, 0x8D,         /*      Report Count (141),             */
641d829674dSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
642d829674dSFrank Praznik 	0x09, 0x23,         /*      Usage (23h),                    */
643d829674dSFrank Praznik 	0x91, 0x02,         /*      Output (Variable),              */
644d829674dSFrank Praznik 	0x85, 0x13,         /*      Report ID (19),                 */
645d829674dSFrank Praznik 	0x09, 0x24,         /*      Usage (24h),                    */
646d829674dSFrank Praznik 	0x95, 0xCD,         /*      Report Count (205),             */
647d829674dSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
648d829674dSFrank Praznik 	0x09, 0x25,         /*      Usage (25h),                    */
649d829674dSFrank Praznik 	0x91, 0x02,         /*      Output (Variable),              */
650d829674dSFrank Praznik 	0x85, 0x14,         /*      Report ID (20),                 */
651d829674dSFrank Praznik 	0x09, 0x26,         /*      Usage (26h),                    */
652d829674dSFrank Praznik 	0x96, 0x0D, 0x01,   /*      Report Count (269),             */
653d829674dSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
654d829674dSFrank Praznik 	0x09, 0x27,         /*      Usage (27h),                    */
655d829674dSFrank Praznik 	0x91, 0x02,         /*      Output (Variable),              */
656d829674dSFrank Praznik 	0x85, 0x15,         /*      Report ID (21),                 */
657d829674dSFrank Praznik 	0x09, 0x28,         /*      Usage (28h),                    */
658d829674dSFrank Praznik 	0x96, 0x4D, 0x01,   /*      Report Count (333),             */
659d829674dSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
660d829674dSFrank Praznik 	0x09, 0x29,         /*      Usage (29h),                    */
661d829674dSFrank Praznik 	0x91, 0x02,         /*      Output (Variable),              */
662d829674dSFrank Praznik 	0x85, 0x16,         /*      Report ID (22),                 */
663d829674dSFrank Praznik 	0x09, 0x2A,         /*      Usage (2Ah),                    */
664d829674dSFrank Praznik 	0x96, 0x8D, 0x01,   /*      Report Count (397),             */
665d829674dSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
666d829674dSFrank Praznik 	0x09, 0x2B,         /*      Usage (2Bh),                    */
667d829674dSFrank Praznik 	0x91, 0x02,         /*      Output (Variable),              */
668d829674dSFrank Praznik 	0x85, 0x17,         /*      Report ID (23),                 */
669d829674dSFrank Praznik 	0x09, 0x2C,         /*      Usage (2Ch),                    */
670d829674dSFrank Praznik 	0x96, 0xCD, 0x01,   /*      Report Count (461),             */
671d829674dSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
672d829674dSFrank Praznik 	0x09, 0x2D,         /*      Usage (2Dh),                    */
673d829674dSFrank Praznik 	0x91, 0x02,         /*      Output (Variable),              */
674d829674dSFrank Praznik 	0x85, 0x18,         /*      Report ID (24),                 */
675d829674dSFrank Praznik 	0x09, 0x2E,         /*      Usage (2Eh),                    */
676d829674dSFrank Praznik 	0x96, 0x0D, 0x02,   /*      Report Count (525),             */
677d829674dSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
678d829674dSFrank Praznik 	0x09, 0x2F,         /*      Usage (2Fh),                    */
679d829674dSFrank Praznik 	0x91, 0x02,         /*      Output (Variable),              */
680d829674dSFrank Praznik 	0x85, 0x19,         /*      Report ID (25),                 */
681d829674dSFrank Praznik 	0x09, 0x30,         /*      Usage (30h),                    */
682d829674dSFrank Praznik 	0x96, 0x22, 0x02,   /*      Report Count (546),             */
683d829674dSFrank Praznik 	0x81, 0x02,         /*      Input (Variable),               */
684d829674dSFrank Praznik 	0x09, 0x31,         /*      Usage (31h),                    */
685d829674dSFrank Praznik 	0x91, 0x02,         /*      Output (Variable),              */
686d829674dSFrank Praznik 	0x06, 0x80, 0xFF,   /*      Usage Page (FF80h),             */
687d829674dSFrank Praznik 	0x85, 0x82,         /*      Report ID (130),                */
688d829674dSFrank Praznik 	0x09, 0x22,         /*      Usage (22h),                    */
689d829674dSFrank Praznik 	0x95, 0x3F,         /*      Report Count (63),              */
690d829674dSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
691d829674dSFrank Praznik 	0x85, 0x83,         /*      Report ID (131),                */
692d829674dSFrank Praznik 	0x09, 0x23,         /*      Usage (23h),                    */
693d829674dSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
694d829674dSFrank Praznik 	0x85, 0x84,         /*      Report ID (132),                */
695d829674dSFrank Praznik 	0x09, 0x24,         /*      Usage (24h),                    */
696d829674dSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
697d829674dSFrank Praznik 	0x85, 0x90,         /*      Report ID (144),                */
698d829674dSFrank Praznik 	0x09, 0x30,         /*      Usage (30h),                    */
699d829674dSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
700d829674dSFrank Praznik 	0x85, 0x91,         /*      Report ID (145),                */
701d829674dSFrank Praznik 	0x09, 0x31,         /*      Usage (31h),                    */
702d829674dSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
703d829674dSFrank Praznik 	0x85, 0x92,         /*      Report ID (146),                */
704d829674dSFrank Praznik 	0x09, 0x32,         /*      Usage (32h),                    */
705d829674dSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
706d829674dSFrank Praznik 	0x85, 0x93,         /*      Report ID (147),                */
707d829674dSFrank Praznik 	0x09, 0x33,         /*      Usage (33h),                    */
708d829674dSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
709d829674dSFrank Praznik 	0x85, 0xA0,         /*      Report ID (160),                */
710d829674dSFrank Praznik 	0x09, 0x40,         /*      Usage (40h),                    */
711d829674dSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
712d829674dSFrank Praznik 	0x85, 0xA4,         /*      Report ID (164),                */
713d829674dSFrank Praznik 	0x09, 0x44,         /*      Usage (44h),                    */
714d829674dSFrank Praznik 	0xB1, 0x02,         /*      Feature (Variable),             */
715d829674dSFrank Praznik 	0xC0                /*  End Collection                      */
716d829674dSFrank Praznik };
717d829674dSFrank Praznik 
718078328daSJiri Kosina static __u8 ps3remote_rdesc[] = {
719078328daSJiri Kosina 	0x05, 0x01,          /* GUsagePage Generic Desktop */
720078328daSJiri Kosina 	0x09, 0x05,          /* LUsage 0x05 [Game Pad] */
721078328daSJiri Kosina 	0xA1, 0x01,          /* MCollection Application (mouse, keyboard) */
722078328daSJiri Kosina 
723078328daSJiri Kosina 	 /* Use collection 1 for joypad buttons */
724078328daSJiri Kosina 	 0xA1, 0x02,         /* MCollection Logical (interrelated data) */
725078328daSJiri Kosina 
726078328daSJiri Kosina 	  /* Ignore the 1st byte, maybe it is used for a controller
727078328daSJiri Kosina 	   * number but it's not needed for correct operation */
728078328daSJiri Kosina 	  0x75, 0x08,        /* GReportSize 0x08 [8] */
729078328daSJiri Kosina 	  0x95, 0x01,        /* GReportCount 0x01 [1] */
730078328daSJiri Kosina 	  0x81, 0x01,        /* MInput 0x01 (Const[0] Arr[1] Abs[2]) */
731078328daSJiri Kosina 
732078328daSJiri Kosina 	  /* Bytes from 2nd to 4th are a bitmap for joypad buttons, for these
733078328daSJiri Kosina 	   * buttons multiple keypresses are allowed */
734078328daSJiri Kosina 	  0x05, 0x09,        /* GUsagePage Button */
735078328daSJiri Kosina 	  0x19, 0x01,        /* LUsageMinimum 0x01 [Button 1 (primary/trigger)] */
736078328daSJiri Kosina 	  0x29, 0x18,        /* LUsageMaximum 0x18 [Button 24] */
737078328daSJiri Kosina 	  0x14,              /* GLogicalMinimum [0] */
738078328daSJiri Kosina 	  0x25, 0x01,        /* GLogicalMaximum 0x01 [1] */
739078328daSJiri Kosina 	  0x75, 0x01,        /* GReportSize 0x01 [1] */
740078328daSJiri Kosina 	  0x95, 0x18,        /* GReportCount 0x18 [24] */
741078328daSJiri Kosina 	  0x81, 0x02,        /* MInput 0x02 (Data[0] Var[1] Abs[2]) */
742078328daSJiri Kosina 
743078328daSJiri Kosina 	  0xC0,              /* MEndCollection */
744078328daSJiri Kosina 
745078328daSJiri Kosina 	 /* Use collection 2 for remote control buttons */
746078328daSJiri Kosina 	 0xA1, 0x02,         /* MCollection Logical (interrelated data) */
747078328daSJiri Kosina 
748078328daSJiri Kosina 	  /* 5th byte is used for remote control buttons */
749078328daSJiri Kosina 	  0x05, 0x09,        /* GUsagePage Button */
750078328daSJiri Kosina 	  0x18,              /* LUsageMinimum [No button pressed] */
751078328daSJiri Kosina 	  0x29, 0xFE,        /* LUsageMaximum 0xFE [Button 254] */
752078328daSJiri Kosina 	  0x14,              /* GLogicalMinimum [0] */
753078328daSJiri Kosina 	  0x26, 0xFE, 0x00,  /* GLogicalMaximum 0x00FE [254] */
754078328daSJiri Kosina 	  0x75, 0x08,        /* GReportSize 0x08 [8] */
755078328daSJiri Kosina 	  0x95, 0x01,        /* GReportCount 0x01 [1] */
756078328daSJiri Kosina 	  0x80,              /* MInput  */
757078328daSJiri Kosina 
758078328daSJiri Kosina 	  /* Ignore bytes from 6th to 11th, 6th to 10th are always constant at
759078328daSJiri Kosina 	   * 0xff and 11th is for press indication */
760078328daSJiri Kosina 	  0x75, 0x08,        /* GReportSize 0x08 [8] */
761078328daSJiri Kosina 	  0x95, 0x06,        /* GReportCount 0x06 [6] */
762078328daSJiri Kosina 	  0x81, 0x01,        /* MInput 0x01 (Const[0] Arr[1] Abs[2]) */
763078328daSJiri Kosina 
764078328daSJiri Kosina 	  /* 12th byte is for battery strength */
765078328daSJiri Kosina 	  0x05, 0x06,        /* GUsagePage Generic Device Controls */
766078328daSJiri Kosina 	  0x09, 0x20,        /* LUsage 0x20 [Battery Strength] */
767078328daSJiri Kosina 	  0x14,              /* GLogicalMinimum [0] */
768078328daSJiri Kosina 	  0x25, 0x05,        /* GLogicalMaximum 0x05 [5] */
769078328daSJiri Kosina 	  0x75, 0x08,        /* GReportSize 0x08 [8] */
770078328daSJiri Kosina 	  0x95, 0x01,        /* GReportCount 0x01 [1] */
771078328daSJiri Kosina 	  0x81, 0x02,        /* MInput 0x02 (Data[0] Var[1] Abs[2]) */
772078328daSJiri Kosina 
773078328daSJiri Kosina 	  0xC0,              /* MEndCollection */
774078328daSJiri Kosina 
775078328daSJiri Kosina 	 0xC0                /* MEndCollection [Game Pad] */
776078328daSJiri Kosina };
777078328daSJiri Kosina 
778078328daSJiri Kosina static const unsigned int ps3remote_keymap_joypad_buttons[] = {
779078328daSJiri Kosina 	[0x01] = KEY_SELECT,
780078328daSJiri Kosina 	[0x02] = BTN_THUMBL,		/* L3 */
781078328daSJiri Kosina 	[0x03] = BTN_THUMBR,		/* R3 */
782078328daSJiri Kosina 	[0x04] = BTN_START,
783078328daSJiri Kosina 	[0x05] = KEY_UP,
784078328daSJiri Kosina 	[0x06] = KEY_RIGHT,
785078328daSJiri Kosina 	[0x07] = KEY_DOWN,
786078328daSJiri Kosina 	[0x08] = KEY_LEFT,
787078328daSJiri Kosina 	[0x09] = BTN_TL2,		/* L2 */
788078328daSJiri Kosina 	[0x0a] = BTN_TR2,		/* R2 */
789078328daSJiri Kosina 	[0x0b] = BTN_TL,		/* L1 */
790078328daSJiri Kosina 	[0x0c] = BTN_TR,		/* R1 */
791078328daSJiri Kosina 	[0x0d] = KEY_OPTION,		/* options/triangle */
792078328daSJiri Kosina 	[0x0e] = KEY_BACK,		/* back/circle */
793078328daSJiri Kosina 	[0x0f] = BTN_0,			/* cross */
794078328daSJiri Kosina 	[0x10] = KEY_SCREEN,		/* view/square */
795078328daSJiri Kosina 	[0x11] = KEY_HOMEPAGE,		/* PS button */
796078328daSJiri Kosina 	[0x14] = KEY_ENTER,
797078328daSJiri Kosina };
798078328daSJiri Kosina static const unsigned int ps3remote_keymap_remote_buttons[] = {
799078328daSJiri Kosina 	[0x00] = KEY_1,
800078328daSJiri Kosina 	[0x01] = KEY_2,
801078328daSJiri Kosina 	[0x02] = KEY_3,
802078328daSJiri Kosina 	[0x03] = KEY_4,
803078328daSJiri Kosina 	[0x04] = KEY_5,
804078328daSJiri Kosina 	[0x05] = KEY_6,
805078328daSJiri Kosina 	[0x06] = KEY_7,
806078328daSJiri Kosina 	[0x07] = KEY_8,
807078328daSJiri Kosina 	[0x08] = KEY_9,
808078328daSJiri Kosina 	[0x09] = KEY_0,
809078328daSJiri Kosina 	[0x0e] = KEY_ESC,		/* return */
810078328daSJiri Kosina 	[0x0f] = KEY_CLEAR,
811078328daSJiri Kosina 	[0x16] = KEY_EJECTCD,
812078328daSJiri Kosina 	[0x1a] = KEY_MENU,		/* top menu */
813078328daSJiri Kosina 	[0x28] = KEY_TIME,
814078328daSJiri Kosina 	[0x30] = KEY_PREVIOUS,
815078328daSJiri Kosina 	[0x31] = KEY_NEXT,
816078328daSJiri Kosina 	[0x32] = KEY_PLAY,
817078328daSJiri Kosina 	[0x33] = KEY_REWIND,		/* scan back */
818078328daSJiri Kosina 	[0x34] = KEY_FORWARD,		/* scan forward */
819078328daSJiri Kosina 	[0x38] = KEY_STOP,
820078328daSJiri Kosina 	[0x39] = KEY_PAUSE,
821078328daSJiri Kosina 	[0x40] = KEY_CONTEXT_MENU,	/* pop up/menu */
822078328daSJiri Kosina 	[0x60] = KEY_FRAMEBACK,		/* slow/step back */
823078328daSJiri Kosina 	[0x61] = KEY_FRAMEFORWARD,	/* slow/step forward */
824078328daSJiri Kosina 	[0x63] = KEY_SUBTITLE,
825078328daSJiri Kosina 	[0x64] = KEY_AUDIO,
826078328daSJiri Kosina 	[0x65] = KEY_ANGLE,
827078328daSJiri Kosina 	[0x70] = KEY_INFO,		/* display */
828078328daSJiri Kosina 	[0x80] = KEY_BLUE,
829078328daSJiri Kosina 	[0x81] = KEY_RED,
830078328daSJiri Kosina 	[0x82] = KEY_GREEN,
831078328daSJiri Kosina 	[0x83] = KEY_YELLOW,
832078328daSJiri Kosina };
833078328daSJiri Kosina 
834f04d5140SColin Leitner static const unsigned int buzz_keymap[] = {
835ad142b9eSFrank Praznik 	/*
836ad142b9eSFrank Praznik 	 * The controller has 4 remote buzzers, each with one LED and 5
837f04d5140SColin Leitner 	 * buttons.
838f04d5140SColin Leitner 	 *
839f04d5140SColin Leitner 	 * We use the mapping chosen by the controller, which is:
840f04d5140SColin Leitner 	 *
841f04d5140SColin Leitner 	 * Key          Offset
842f04d5140SColin Leitner 	 * -------------------
843f04d5140SColin Leitner 	 * Buzz              1
844f04d5140SColin Leitner 	 * Blue              5
845f04d5140SColin Leitner 	 * Orange            4
846f04d5140SColin Leitner 	 * Green             3
847f04d5140SColin Leitner 	 * Yellow            2
848f04d5140SColin Leitner 	 *
849f04d5140SColin Leitner 	 * So, for example, the orange button on the third buzzer is mapped to
850f04d5140SColin Leitner 	 * BTN_TRIGGER_HAPPY14
851f04d5140SColin Leitner 	 */
852f04d5140SColin Leitner 	[ 1] = BTN_TRIGGER_HAPPY1,
853f04d5140SColin Leitner 	[ 2] = BTN_TRIGGER_HAPPY2,
854f04d5140SColin Leitner 	[ 3] = BTN_TRIGGER_HAPPY3,
855f04d5140SColin Leitner 	[ 4] = BTN_TRIGGER_HAPPY4,
856f04d5140SColin Leitner 	[ 5] = BTN_TRIGGER_HAPPY5,
857f04d5140SColin Leitner 	[ 6] = BTN_TRIGGER_HAPPY6,
858f04d5140SColin Leitner 	[ 7] = BTN_TRIGGER_HAPPY7,
859f04d5140SColin Leitner 	[ 8] = BTN_TRIGGER_HAPPY8,
860f04d5140SColin Leitner 	[ 9] = BTN_TRIGGER_HAPPY9,
861f04d5140SColin Leitner 	[10] = BTN_TRIGGER_HAPPY10,
862f04d5140SColin Leitner 	[11] = BTN_TRIGGER_HAPPY11,
863f04d5140SColin Leitner 	[12] = BTN_TRIGGER_HAPPY12,
864f04d5140SColin Leitner 	[13] = BTN_TRIGGER_HAPPY13,
865f04d5140SColin Leitner 	[14] = BTN_TRIGGER_HAPPY14,
866f04d5140SColin Leitner 	[15] = BTN_TRIGGER_HAPPY15,
867f04d5140SColin Leitner 	[16] = BTN_TRIGGER_HAPPY16,
868f04d5140SColin Leitner 	[17] = BTN_TRIGGER_HAPPY17,
869f04d5140SColin Leitner 	[18] = BTN_TRIGGER_HAPPY18,
870f04d5140SColin Leitner 	[19] = BTN_TRIGGER_HAPPY19,
871f04d5140SColin Leitner 	[20] = BTN_TRIGGER_HAPPY20,
872f04d5140SColin Leitner };
873f04d5140SColin Leitner 
874d902f472SFrank Praznik static enum power_supply_property sony_battery_props[] = {
875d902f472SFrank Praznik 	POWER_SUPPLY_PROP_PRESENT,
876d902f472SFrank Praznik 	POWER_SUPPLY_PROP_CAPACITY,
877d902f472SFrank Praznik 	POWER_SUPPLY_PROP_SCOPE,
878d902f472SFrank Praznik 	POWER_SUPPLY_PROP_STATUS,
879d902f472SFrank Praznik };
880d902f472SFrank Praznik 
88155d3b664SFrank Praznik struct sixaxis_led {
88255d3b664SFrank Praznik 	__u8 time_enabled; /* the total time the led is active (0xff means forever) */
88355d3b664SFrank Praznik 	__u8 duty_length;  /* how long a cycle is in deciseconds (0 means "really fast") */
88455d3b664SFrank Praznik 	__u8 enabled;
88555d3b664SFrank Praznik 	__u8 duty_off; /* % of duty_length the led is off (0xff means 100%) */
88655d3b664SFrank Praznik 	__u8 duty_on;  /* % of duty_length the led is on (0xff mean 100%) */
88755d3b664SFrank Praznik } __packed;
88855d3b664SFrank Praznik 
88955d3b664SFrank Praznik struct sixaxis_rumble {
89055d3b664SFrank Praznik 	__u8 padding;
89155d3b664SFrank Praznik 	__u8 right_duration; /* Right motor duration (0xff means forever) */
89255d3b664SFrank Praznik 	__u8 right_motor_on; /* Right (small) motor on/off, only supports values of 0 or 1 (off/on) */
89355d3b664SFrank Praznik 	__u8 left_duration;    /* Left motor duration (0xff means forever) */
89455d3b664SFrank Praznik 	__u8 left_motor_force; /* left (large) motor, supports force values from 0 to 255 */
89555d3b664SFrank Praznik } __packed;
89655d3b664SFrank Praznik 
89755d3b664SFrank Praznik struct sixaxis_output_report {
89855d3b664SFrank Praznik 	__u8 report_id;
89955d3b664SFrank Praznik 	struct sixaxis_rumble rumble;
90055d3b664SFrank Praznik 	__u8 padding[4];
90155d3b664SFrank Praznik 	__u8 leds_bitmap; /* bitmap of enabled LEDs: LED_1 = 0x02, LED_2 = 0x04, ... */
90255d3b664SFrank Praznik 	struct sixaxis_led led[4];    /* LEDx at (4 - x) */
90355d3b664SFrank Praznik 	struct sixaxis_led _reserved; /* LED5, not actually soldered */
90455d3b664SFrank Praznik } __packed;
90555d3b664SFrank Praznik 
90655d3b664SFrank Praznik union sixaxis_output_report_01 {
90755d3b664SFrank Praznik 	struct sixaxis_output_report data;
90855d3b664SFrank Praznik 	__u8 buf[36];
90955d3b664SFrank Praznik };
91055d3b664SFrank Praznik 
911c5e0c1c4SFrank Praznik struct motion_output_report_02 {
912c5e0c1c4SFrank Praznik 	u8 type, zero;
913c5e0c1c4SFrank Praznik 	u8 r, g, b;
914c5e0c1c4SFrank Praznik 	u8 zero2;
915c5e0c1c4SFrank Praznik 	u8 rumble;
916c5e0c1c4SFrank Praznik };
917c5e0c1c4SFrank Praznik 
9189b2b5c9aSFrank Praznik #define DS4_REPORT_0x02_SIZE 37
9199b2b5c9aSFrank Praznik #define DS4_REPORT_0x05_SIZE 32
9209b2b5c9aSFrank Praznik #define DS4_REPORT_0x11_SIZE 78
9219b2b5c9aSFrank Praznik #define DS4_REPORT_0x81_SIZE 7
92229b691a8SAntonio Ospite #define SIXAXIS_REPORT_0xF2_SIZE 17
923a85d67b5SAntonio Ospite #define SIXAXIS_REPORT_0xF5_SIZE 8
92441d2d425SSimon Wood #define MOTION_REPORT_0x02_SIZE 49
9259b2b5c9aSFrank Praznik 
9268b402c92SJiri Kosina static DEFINE_SPINLOCK(sony_dev_list_lock);
927d2d782fcSFrank Praznik static LIST_HEAD(sony_device_list);
9288025087aSFrank Praznik static DEFINE_IDA(sony_device_id_allocator);
929d2d782fcSFrank Praznik 
930cc6e0bbbSJiri Kosina struct sony_sc {
931d902f472SFrank Praznik 	spinlock_t lock;
932d2d782fcSFrank Praznik 	struct list_head list_node;
9330a286ef2SSven Eckelmann 	struct hid_device *hdev;
93460781cf4SFrank Praznik 	struct led_classdev *leds[MAX_LEDS];
935cc6e0bbbSJiri Kosina 	unsigned long quirks;
9360a286ef2SSven Eckelmann 	struct work_struct state_worker;
937297d716fSKrzysztof Kozlowski 	struct power_supply *battery;
938297d716fSKrzysztof Kozlowski 	struct power_supply_desc battery_desc;
9398025087aSFrank Praznik 	int device_id;
9409b2b5c9aSFrank Praznik 	__u8 *output_report_dmabuf;
941f04d5140SColin Leitner 
9429f323b68SSven Eckelmann #ifdef CONFIG_SONY_FF
9439f323b68SSven Eckelmann 	__u8 left;
9449f323b68SSven Eckelmann 	__u8 right;
9459f323b68SSven Eckelmann #endif
9469f323b68SSven Eckelmann 
947d2d782fcSFrank Praznik 	__u8 mac_address[6];
9485f5750d2SFrank Praznik 	__u8 worker_initialized;
949d902f472SFrank Praznik 	__u8 cable_state;
950d902f472SFrank Praznik 	__u8 battery_charging;
951d902f472SFrank Praznik 	__u8 battery_capacity;
95260781cf4SFrank Praznik 	__u8 led_state[MAX_LEDS];
953b3ed458cSFrank Praznik 	__u8 led_delay_on[MAX_LEDS];
954b3ed458cSFrank Praznik 	__u8 led_delay_off[MAX_LEDS];
95560781cf4SFrank Praznik 	__u8 led_count;
956cc6e0bbbSJiri Kosina };
957cc6e0bbbSJiri Kosina 
958c607fb8dSAntonio Ospite static __u8 *sixaxis_fixup(struct hid_device *hdev, __u8 *rdesc,
959c607fb8dSAntonio Ospite 			     unsigned int *rsize)
960c607fb8dSAntonio Ospite {
961c607fb8dSAntonio Ospite 	*rsize = sizeof(sixaxis_rdesc);
962c607fb8dSAntonio Ospite 	return sixaxis_rdesc;
963c607fb8dSAntonio Ospite }
964c607fb8dSAntonio Ospite 
965c5e0c1c4SFrank Praznik static u8 *motion_fixup(struct hid_device *hdev, u8 *rdesc,
966c5e0c1c4SFrank Praznik 			     unsigned int *rsize)
967c5e0c1c4SFrank Praznik {
968c5e0c1c4SFrank Praznik 	*rsize = sizeof(motion_rdesc);
969c5e0c1c4SFrank Praznik 	return motion_rdesc;
970c5e0c1c4SFrank Praznik }
971c5e0c1c4SFrank Praznik 
972078328daSJiri Kosina static __u8 *ps3remote_fixup(struct hid_device *hdev, __u8 *rdesc,
973078328daSJiri Kosina 			     unsigned int *rsize)
974078328daSJiri Kosina {
975078328daSJiri Kosina 	*rsize = sizeof(ps3remote_rdesc);
976078328daSJiri Kosina 	return ps3remote_rdesc;
977078328daSJiri Kosina }
978078328daSJiri Kosina 
979078328daSJiri Kosina static int ps3remote_mapping(struct hid_device *hdev, struct hid_input *hi,
980078328daSJiri Kosina 			     struct hid_field *field, struct hid_usage *usage,
981078328daSJiri Kosina 			     unsigned long **bit, int *max)
982078328daSJiri Kosina {
983078328daSJiri Kosina 	unsigned int key = usage->hid & HID_USAGE;
984078328daSJiri Kosina 
985078328daSJiri Kosina 	if ((usage->hid & HID_USAGE_PAGE) != HID_UP_BUTTON)
986078328daSJiri Kosina 		return -1;
987078328daSJiri Kosina 
988078328daSJiri Kosina 	switch (usage->collection_index) {
989078328daSJiri Kosina 	case 1:
990078328daSJiri Kosina 		if (key >= ARRAY_SIZE(ps3remote_keymap_joypad_buttons))
991078328daSJiri Kosina 			return -1;
992078328daSJiri Kosina 
993078328daSJiri Kosina 		key = ps3remote_keymap_joypad_buttons[key];
994078328daSJiri Kosina 		if (!key)
995078328daSJiri Kosina 			return -1;
996078328daSJiri Kosina 		break;
997078328daSJiri Kosina 	case 2:
998078328daSJiri Kosina 		if (key >= ARRAY_SIZE(ps3remote_keymap_remote_buttons))
999078328daSJiri Kosina 			return -1;
1000078328daSJiri Kosina 
1001078328daSJiri Kosina 		key = ps3remote_keymap_remote_buttons[key];
1002078328daSJiri Kosina 		if (!key)
1003078328daSJiri Kosina 			return -1;
1004078328daSJiri Kosina 		break;
1005078328daSJiri Kosina 	default:
1006078328daSJiri Kosina 		return -1;
1007078328daSJiri Kosina 	}
1008078328daSJiri Kosina 
1009078328daSJiri Kosina 	hid_map_usage_clear(hi, usage, bit, max, EV_KEY, key);
1010078328daSJiri Kosina 	return 1;
1011078328daSJiri Kosina }
1012078328daSJiri Kosina 
101373e4008dSNikolai Kondrashov static __u8 *sony_report_fixup(struct hid_device *hdev, __u8 *rdesc,
101473e4008dSNikolai Kondrashov 		unsigned int *rsize)
1015cc6e0bbbSJiri Kosina {
1016cc6e0bbbSJiri Kosina 	struct sony_sc *sc = hid_get_drvdata(hdev);
1017cc6e0bbbSJiri Kosina 
101899d24902SFernando Luis Vázquez Cao 	/*
101999d24902SFernando Luis Vázquez Cao 	 * Some Sony RF receivers wrongly declare the mouse pointer as a
102099d24902SFernando Luis Vázquez Cao 	 * a constant non-data variable.
102199d24902SFernando Luis Vázquez Cao 	 */
102299d24902SFernando Luis Vázquez Cao 	if ((sc->quirks & VAIO_RDESC_CONSTANT) && *rsize >= 56 &&
102399d24902SFernando Luis Vázquez Cao 	    /* usage page: generic desktop controls */
102499d24902SFernando Luis Vázquez Cao 	    /* rdesc[0] == 0x05 && rdesc[1] == 0x01 && */
102599d24902SFernando Luis Vázquez Cao 	    /* usage: mouse */
102699d24902SFernando Luis Vázquez Cao 	    rdesc[2] == 0x09 && rdesc[3] == 0x02 &&
102799d24902SFernando Luis Vázquez Cao 	    /* input (usage page for x,y axes): constant, variable, relative */
102899d24902SFernando Luis Vázquez Cao 	    rdesc[54] == 0x81 && rdesc[55] == 0x07) {
1029a4649184SFernando Luis Vázquez Cao 		hid_info(hdev, "Fixing up Sony RF Receiver report descriptor\n");
103099d24902SFernando Luis Vázquez Cao 		/* input: data, variable, relative */
1031cc6e0bbbSJiri Kosina 		rdesc[55] = 0x06;
1032cc6e0bbbSJiri Kosina 	}
103361ab44beSSimon Wood 
1034ed19d8cfSFrank Praznik 	/*
1035ed19d8cfSFrank Praznik 	 * The default Dualshock 4 USB descriptor doesn't assign
1036ed19d8cfSFrank Praznik 	 * the gyroscope values to corresponding axes so we need a
1037ed19d8cfSFrank Praznik 	 * modified one.
1038ed19d8cfSFrank Praznik 	 */
1039ed19d8cfSFrank Praznik 	if ((sc->quirks & DUALSHOCK4_CONTROLLER_USB) && *rsize == 467) {
1040ed19d8cfSFrank Praznik 		hid_info(hdev, "Using modified Dualshock 4 report descriptor with gyroscope axes\n");
1041ed19d8cfSFrank Praznik 		rdesc = dualshock4_usb_rdesc;
1042ed19d8cfSFrank Praznik 		*rsize = sizeof(dualshock4_usb_rdesc);
1043d829674dSFrank Praznik 	} else if ((sc->quirks & DUALSHOCK4_CONTROLLER_BT) && *rsize == 357) {
1044d829674dSFrank Praznik 		hid_info(hdev, "Using modified Dualshock 4 Bluetooth report descriptor\n");
1045d829674dSFrank Praznik 		rdesc = dualshock4_bt_rdesc;
1046d829674dSFrank Praznik 		*rsize = sizeof(dualshock4_bt_rdesc);
1047ed19d8cfSFrank Praznik 	}
1048ed19d8cfSFrank Praznik 
1049c607fb8dSAntonio Ospite 	if (sc->quirks & SIXAXIS_CONTROLLER)
1050c607fb8dSAntonio Ospite 		return sixaxis_fixup(hdev, rdesc, rsize);
1051078328daSJiri Kosina 
1052c5e0c1c4SFrank Praznik 	if (sc->quirks & MOTION_CONTROLLER)
1053c5e0c1c4SFrank Praznik 		return motion_fixup(hdev, rdesc, rsize);
1054c5e0c1c4SFrank Praznik 
1055078328daSJiri Kosina 	if (sc->quirks & PS3REMOTE)
1056078328daSJiri Kosina 		return ps3remote_fixup(hdev, rdesc, rsize);
1057078328daSJiri Kosina 
105873e4008dSNikolai Kondrashov 	return rdesc;
1059cc6e0bbbSJiri Kosina }
1060cc6e0bbbSJiri Kosina 
1061d902f472SFrank Praznik static void sixaxis_parse_report(struct sony_sc *sc, __u8 *rd, int size)
1062d902f472SFrank Praznik {
1063d902f472SFrank Praznik 	static const __u8 sixaxis_battery_capacity[] = { 0, 1, 25, 50, 75, 100 };
1064d902f472SFrank Praznik 	unsigned long flags;
106512e9a6d7SSimon Wood 	int offset;
1066d902f472SFrank Praznik 	__u8 cable_state, battery_capacity, battery_charging;
1067d902f472SFrank Praznik 
1068ad142b9eSFrank Praznik 	/*
1069ad142b9eSFrank Praznik 	 * The sixaxis is charging if the battery value is 0xee
1070d902f472SFrank Praznik 	 * and it is fully charged if the value is 0xef.
1071d902f472SFrank Praznik 	 * It does not report the actual level while charging so it
1072d902f472SFrank Praznik 	 * is set to 100% while charging is in progress.
1073d902f472SFrank Praznik 	 */
107412e9a6d7SSimon Wood 	offset = (sc->quirks & MOTION_CONTROLLER) ? 12 : 30;
107512e9a6d7SSimon Wood 
107612e9a6d7SSimon Wood 	if (rd[offset] >= 0xee) {
1077d902f472SFrank Praznik 		battery_capacity = 100;
107812e9a6d7SSimon Wood 		battery_charging = !(rd[offset] & 0x01);
10799fddd74aSFrank Praznik 		cable_state = 1;
1080d902f472SFrank Praznik 	} else {
108112e9a6d7SSimon Wood 		__u8 index = rd[offset] <= 5 ? rd[offset] : 5;
1082ac3c9a94SFrank Praznik 		battery_capacity = sixaxis_battery_capacity[index];
1083d902f472SFrank Praznik 		battery_charging = 0;
10849fddd74aSFrank Praznik 		cable_state = 0;
1085d902f472SFrank Praznik 	}
1086d902f472SFrank Praznik 
1087d902f472SFrank Praznik 	spin_lock_irqsave(&sc->lock, flags);
1088d902f472SFrank Praznik 	sc->cable_state = cable_state;
1089d902f472SFrank Praznik 	sc->battery_capacity = battery_capacity;
1090d902f472SFrank Praznik 	sc->battery_charging = battery_charging;
1091d902f472SFrank Praznik 	spin_unlock_irqrestore(&sc->lock, flags);
1092d902f472SFrank Praznik }
1093d902f472SFrank Praznik 
1094d902f472SFrank Praznik static void dualshock4_parse_report(struct sony_sc *sc, __u8 *rd, int size)
1095d902f472SFrank Praznik {
1096e5606230SFrank Praznik 	struct hid_input *hidinput = list_entry(sc->hdev->inputs.next,
1097e5606230SFrank Praznik 						struct hid_input, list);
1098e5606230SFrank Praznik 	struct input_dev *input_dev = hidinput->input;
1099d902f472SFrank Praznik 	unsigned long flags;
11006c5f860dSFrank Praznik 	int n, offset;
1101d902f472SFrank Praznik 	__u8 cable_state, battery_capacity, battery_charging;
1102d902f472SFrank Praznik 
1103ad142b9eSFrank Praznik 	/*
1104ad142b9eSFrank Praznik 	 * Battery and touchpad data starts at byte 30 in the USB report and
11056c5f860dSFrank Praznik 	 * 32 in Bluetooth report.
11066c5f860dSFrank Praznik 	 */
11076c5f860dSFrank Praznik 	offset = (sc->quirks & DUALSHOCK4_CONTROLLER_USB) ? 30 : 32;
11086c5f860dSFrank Praznik 
1109ad142b9eSFrank Praznik 	/*
1110ad142b9eSFrank Praznik 	 * The lower 4 bits of byte 30 contain the battery level
1111d902f472SFrank Praznik 	 * and the 5th bit contains the USB cable state.
1112d902f472SFrank Praznik 	 */
11136c5f860dSFrank Praznik 	cable_state = (rd[offset] >> 4) & 0x01;
11146c5f860dSFrank Praznik 	battery_capacity = rd[offset] & 0x0F;
1115d902f472SFrank Praznik 
1116ad142b9eSFrank Praznik 	/*
1117ad142b9eSFrank Praznik 	 * When a USB power source is connected the battery level ranges from
11186c5f860dSFrank Praznik 	 * 0 to 10, and when running on battery power it ranges from 0 to 9.
11196c5f860dSFrank Praznik 	 * A battery level above 10 when plugged in means charge completed.
1120d902f472SFrank Praznik 	 */
11216c5f860dSFrank Praznik 	if (!cable_state || battery_capacity > 10)
1122d902f472SFrank Praznik 		battery_charging = 0;
1123d902f472SFrank Praznik 	else
1124d902f472SFrank Praznik 		battery_charging = 1;
1125d902f472SFrank Praznik 
11266c5f860dSFrank Praznik 	if (!cable_state)
11276c5f860dSFrank Praznik 		battery_capacity++;
1128d902f472SFrank Praznik 	if (battery_capacity > 10)
11296c5f860dSFrank Praznik 		battery_capacity = 10;
11306c5f860dSFrank Praznik 
1131d902f472SFrank Praznik 	battery_capacity *= 10;
1132d902f472SFrank Praznik 
1133d902f472SFrank Praznik 	spin_lock_irqsave(&sc->lock, flags);
1134d902f472SFrank Praznik 	sc->cable_state = cable_state;
1135d902f472SFrank Praznik 	sc->battery_capacity = battery_capacity;
1136d902f472SFrank Praznik 	sc->battery_charging = battery_charging;
1137d902f472SFrank Praznik 	spin_unlock_irqrestore(&sc->lock, flags);
1138e5606230SFrank Praznik 
11396c5f860dSFrank Praznik 	offset += 5;
11406c5f860dSFrank Praznik 
1141ad142b9eSFrank Praznik 	/*
1142ad142b9eSFrank Praznik 	 * The Dualshock 4 multi-touch trackpad data starts at offset 35 on USB
11436c5f860dSFrank Praznik 	 * and 37 on Bluetooth.
1144e5606230SFrank Praznik 	 * The first 7 bits of the first byte is a counter and bit 8 is a touch
1145e5606230SFrank Praznik 	 * indicator that is 0 when pressed and 1 when not pressed.
1146e5606230SFrank Praznik 	 * The next 3 bytes are two 12 bit touch coordinates, X and Y.
1147e5606230SFrank Praznik 	 * The data for the second touch is in the same format and immediatly
1148e5606230SFrank Praznik 	 * follows the data for the first.
1149e5606230SFrank Praznik 	 */
1150e5606230SFrank Praznik 	for (n = 0; n < 2; n++) {
1151e5606230SFrank Praznik 		__u16 x, y;
1152e5606230SFrank Praznik 
1153e5606230SFrank Praznik 		x = rd[offset+1] | ((rd[offset+2] & 0xF) << 8);
1154e5606230SFrank Praznik 		y = ((rd[offset+2] & 0xF0) >> 4) | (rd[offset+3] << 4);
1155e5606230SFrank Praznik 
1156e5606230SFrank Praznik 		input_mt_slot(input_dev, n);
1157e5606230SFrank Praznik 		input_mt_report_slot_state(input_dev, MT_TOOL_FINGER,
1158e5606230SFrank Praznik 					!(rd[offset] >> 7));
1159e5606230SFrank Praznik 		input_report_abs(input_dev, ABS_MT_POSITION_X, x);
1160e5606230SFrank Praznik 		input_report_abs(input_dev, ABS_MT_POSITION_Y, y);
1161e5606230SFrank Praznik 
1162e5606230SFrank Praznik 		offset += 4;
1163e5606230SFrank Praznik 	}
1164d902f472SFrank Praznik }
1165d902f472SFrank Praznik 
1166c9e4d877SSimon Wood static int sony_raw_event(struct hid_device *hdev, struct hid_report *report,
1167c9e4d877SSimon Wood 		__u8 *rd, int size)
1168c9e4d877SSimon Wood {
1169c9e4d877SSimon Wood 	struct sony_sc *sc = hid_get_drvdata(hdev);
1170c9e4d877SSimon Wood 
1171ad142b9eSFrank Praznik 	/*
1172ad142b9eSFrank Praznik 	 * Sixaxis HID report has acclerometers/gyro with MSByte first, this
1173c9e4d877SSimon Wood 	 * has to be BYTE_SWAPPED before passing up to joystick interface
1174c9e4d877SSimon Wood 	 */
1175fee4e2d5SFrank Praznik 	if ((sc->quirks & SIXAXIS_CONTROLLER) && rd[0] == 0x01 && size == 49) {
1176c9e4d877SSimon Wood 		swap(rd[41], rd[42]);
1177c9e4d877SSimon Wood 		swap(rd[43], rd[44]);
1178c9e4d877SSimon Wood 		swap(rd[45], rd[46]);
1179c9e4d877SSimon Wood 		swap(rd[47], rd[48]);
1180d902f472SFrank Praznik 
1181d902f472SFrank Praznik 		sixaxis_parse_report(sc, rd, size);
118212e9a6d7SSimon Wood 	} else if ((sc->quirks & MOTION_CONTROLLER_BT) && rd[0] == 0x01 && size == 49) {
118312e9a6d7SSimon Wood 		sixaxis_parse_report(sc, rd, size);
118468330d83SFrank Praznik 	} else if (((sc->quirks & DUALSHOCK4_CONTROLLER_USB) && rd[0] == 0x01 &&
118568330d83SFrank Praznik 			size == 64) || ((sc->quirks & DUALSHOCK4_CONTROLLER_BT)
118668330d83SFrank Praznik 			&& rd[0] == 0x11 && size == 78)) {
1187d902f472SFrank Praznik 		dualshock4_parse_report(sc, rd, size);
1188c9e4d877SSimon Wood 	}
1189c9e4d877SSimon Wood 
1190c9e4d877SSimon Wood 	return 0;
1191c9e4d877SSimon Wood }
1192c9e4d877SSimon Wood 
1193f04d5140SColin Leitner static int sony_mapping(struct hid_device *hdev, struct hid_input *hi,
1194f04d5140SColin Leitner 			struct hid_field *field, struct hid_usage *usage,
1195f04d5140SColin Leitner 			unsigned long **bit, int *max)
1196f04d5140SColin Leitner {
1197f04d5140SColin Leitner 	struct sony_sc *sc = hid_get_drvdata(hdev);
1198f04d5140SColin Leitner 
1199f04d5140SColin Leitner 	if (sc->quirks & BUZZ_CONTROLLER) {
1200f04d5140SColin Leitner 		unsigned int key = usage->hid & HID_USAGE;
1201f04d5140SColin Leitner 
1202f04d5140SColin Leitner 		if ((usage->hid & HID_USAGE_PAGE) != HID_UP_BUTTON)
1203f04d5140SColin Leitner 			return -1;
1204f04d5140SColin Leitner 
1205f04d5140SColin Leitner 		switch (usage->collection_index) {
1206f04d5140SColin Leitner 		case 1:
1207f04d5140SColin Leitner 			if (key >= ARRAY_SIZE(buzz_keymap))
1208f04d5140SColin Leitner 				return -1;
1209f04d5140SColin Leitner 
1210f04d5140SColin Leitner 			key = buzz_keymap[key];
1211f04d5140SColin Leitner 			if (!key)
1212f04d5140SColin Leitner 				return -1;
1213f04d5140SColin Leitner 			break;
1214f04d5140SColin Leitner 		default:
1215f04d5140SColin Leitner 			return -1;
1216f04d5140SColin Leitner 		}
1217f04d5140SColin Leitner 
1218f04d5140SColin Leitner 		hid_map_usage_clear(hi, usage, bit, max, EV_KEY, key);
1219f04d5140SColin Leitner 		return 1;
1220f04d5140SColin Leitner 	}
1221f04d5140SColin Leitner 
1222078328daSJiri Kosina 	if (sc->quirks & PS3REMOTE)
1223078328daSJiri Kosina 		return ps3remote_mapping(hdev, hi, field, usage, bit, max);
1224078328daSJiri Kosina 
12256f498018SBenjamin Tissoires 	/* Let hid-core decide for the others */
12266f498018SBenjamin Tissoires 	return 0;
1227f04d5140SColin Leitner }
1228f04d5140SColin Leitner 
1229ce8efc3bSFrank Praznik static int sony_register_touchpad(struct hid_input *hi, int touch_count,
1230ce8efc3bSFrank Praznik 					int w, int h)
1231ce8efc3bSFrank Praznik {
1232ce8efc3bSFrank Praznik 	struct input_dev *input_dev = hi->input;
1233ce8efc3bSFrank Praznik 	int ret;
1234ce8efc3bSFrank Praznik 
1235ce8efc3bSFrank Praznik 	ret = input_mt_init_slots(input_dev, touch_count, 0);
1236ce8efc3bSFrank Praznik 	if (ret < 0)
1237ce8efc3bSFrank Praznik 		return ret;
1238ce8efc3bSFrank Praznik 
1239ce8efc3bSFrank Praznik 	input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0, w, 0, 0);
1240ce8efc3bSFrank Praznik 	input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0, h, 0, 0);
1241ce8efc3bSFrank Praznik 
1242ce8efc3bSFrank Praznik 	return 0;
1243ce8efc3bSFrank Praznik }
1244ce8efc3bSFrank Praznik 
1245ce8efc3bSFrank Praznik static void sony_input_configured(struct hid_device *hdev,
1246ce8efc3bSFrank Praznik 					struct hid_input *hidinput)
1247ce8efc3bSFrank Praznik {
1248ce8efc3bSFrank Praznik 	struct sony_sc *sc = hid_get_drvdata(hdev);
1249ce8efc3bSFrank Praznik 
1250ce8efc3bSFrank Praznik 	/*
1251ce8efc3bSFrank Praznik 	 * The Dualshock 4 touchpad supports 2 touches and has a
1252981c5b4aSFrank Praznik 	 * resolution of 1920x942 (44.86 dots/mm).
1253ce8efc3bSFrank Praznik 	 */
1254ce8efc3bSFrank Praznik 	if (sc->quirks & DUALSHOCK4_CONTROLLER) {
1255981c5b4aSFrank Praznik 		if (sony_register_touchpad(hidinput, 2, 1920, 942) != 0)
1256ce8efc3bSFrank Praznik 			hid_err(sc->hdev,
1257ce8efc3bSFrank Praznik 				"Unable to initialize multi-touch slots\n");
1258ce8efc3bSFrank Praznik 	}
1259ce8efc3bSFrank Praznik }
1260ce8efc3bSFrank Praznik 
12615710fabfSAntonio Ospite /*
1262bd28ce00SJiri Slaby  * Sending HID_REQ_GET_REPORT changes the operation mode of the ps3 controller
1263bd28ce00SJiri Slaby  * to "operational".  Without this, the ps3 controller will not report any
1264bd28ce00SJiri Slaby  * events.
1265bd28ce00SJiri Slaby  */
1266816651a7SAntonio Ospite static int sixaxis_set_operational_usb(struct hid_device *hdev)
1267bd28ce00SJiri Slaby {
1268a85d67b5SAntonio Ospite 	const int buf_size =
1269a85d67b5SAntonio Ospite 		max(SIXAXIS_REPORT_0xF2_SIZE, SIXAXIS_REPORT_0xF5_SIZE);
12702e701a35SAntonio Ospite 	__u8 *buf;
1271bd28ce00SJiri Slaby 	int ret;
1272bd28ce00SJiri Slaby 
12732e701a35SAntonio Ospite 	buf = kmalloc(buf_size, GFP_KERNEL);
1274bd28ce00SJiri Slaby 	if (!buf)
1275bd28ce00SJiri Slaby 		return -ENOMEM;
1276bd28ce00SJiri Slaby 
1277a85d67b5SAntonio Ospite 	ret = hid_hw_raw_request(hdev, 0xf2, buf, SIXAXIS_REPORT_0xF2_SIZE,
1278a85d67b5SAntonio Ospite 				 HID_FEATURE_REPORT, HID_REQ_GET_REPORT);
1279a7de9b86SLauri Kasanen 	if (ret < 0) {
1280a7de9b86SLauri Kasanen 		hid_err(hdev, "can't set operational mode: step 1\n");
1281a7de9b86SLauri Kasanen 		goto out;
1282a7de9b86SLauri Kasanen 	}
1283f204828aSBenjamin Tissoires 
1284a7de9b86SLauri Kasanen 	/*
1285a7de9b86SLauri Kasanen 	 * Some compatible controllers like the Speedlink Strike FX and
1286a7de9b86SLauri Kasanen 	 * Gasia need another query plus an USB interrupt to get operational.
1287a7de9b86SLauri Kasanen 	 */
1288a85d67b5SAntonio Ospite 	ret = hid_hw_raw_request(hdev, 0xf5, buf, SIXAXIS_REPORT_0xF5_SIZE,
1289a85d67b5SAntonio Ospite 				 HID_FEATURE_REPORT, HID_REQ_GET_REPORT);
1290a7de9b86SLauri Kasanen 	if (ret < 0) {
1291a7de9b86SLauri Kasanen 		hid_err(hdev, "can't set operational mode: step 2\n");
1292a7de9b86SLauri Kasanen 		goto out;
1293a7de9b86SLauri Kasanen 	}
1294a7de9b86SLauri Kasanen 
1295a7de9b86SLauri Kasanen 	ret = hid_hw_output_report(hdev, buf, 1);
1296bd28ce00SJiri Slaby 	if (ret < 0)
1297a7de9b86SLauri Kasanen 		hid_err(hdev, "can't set operational mode: step 3\n");
1298bd28ce00SJiri Slaby 
1299a7de9b86SLauri Kasanen out:
1300bd28ce00SJiri Slaby 	kfree(buf);
1301bd28ce00SJiri Slaby 
1302bd28ce00SJiri Slaby 	return ret;
1303bd28ce00SJiri Slaby }
1304bd28ce00SJiri Slaby 
1305816651a7SAntonio Ospite static int sixaxis_set_operational_bt(struct hid_device *hdev)
1306f9ce7c28SBastien Nocera {
13079b2b5c9aSFrank Praznik 	static const __u8 report[] = { 0xf4, 0x42, 0x03, 0x00, 0x00 };
13089b2b5c9aSFrank Praznik 	__u8 *buf;
13099b2b5c9aSFrank Praznik 	int ret;
13109b2b5c9aSFrank Praznik 
13119b2b5c9aSFrank Praznik 	buf = kmemdup(report, sizeof(report), GFP_KERNEL);
13129b2b5c9aSFrank Praznik 	if (!buf)
13139b2b5c9aSFrank Praznik 		return -ENOMEM;
13149b2b5c9aSFrank Praznik 
13159b2b5c9aSFrank Praznik 	ret = hid_hw_raw_request(hdev, buf[0], buf, sizeof(report),
1316b0dd72aaSBenjamin Tissoires 				  HID_FEATURE_REPORT, HID_REQ_SET_REPORT);
13179b2b5c9aSFrank Praznik 
13189b2b5c9aSFrank Praznik 	kfree(buf);
13199b2b5c9aSFrank Praznik 
13209b2b5c9aSFrank Praznik 	return ret;
1321f9ce7c28SBastien Nocera }
1322f9ce7c28SBastien Nocera 
1323ad142b9eSFrank Praznik /*
1324ad142b9eSFrank Praznik  * Requesting feature report 0x02 in Bluetooth mode changes the state of the
132568330d83SFrank Praznik  * controller so that it sends full input reports of type 0x11.
132668330d83SFrank Praznik  */
132768330d83SFrank Praznik static int dualshock4_set_operational_bt(struct hid_device *hdev)
132868330d83SFrank Praznik {
13299b2b5c9aSFrank Praznik 	__u8 *buf;
13309b2b5c9aSFrank Praznik 	int ret;
133168330d83SFrank Praznik 
13329b2b5c9aSFrank Praznik 	buf = kmalloc(DS4_REPORT_0x02_SIZE, GFP_KERNEL);
13339b2b5c9aSFrank Praznik 	if (!buf)
13349b2b5c9aSFrank Praznik 		return -ENOMEM;
13359b2b5c9aSFrank Praznik 
13369b2b5c9aSFrank Praznik 	ret = hid_hw_raw_request(hdev, 0x02, buf, DS4_REPORT_0x02_SIZE,
133768330d83SFrank Praznik 				HID_FEATURE_REPORT, HID_REQ_GET_REPORT);
13389b2b5c9aSFrank Praznik 
13399b2b5c9aSFrank Praznik 	kfree(buf);
13409b2b5c9aSFrank Praznik 
13419b2b5c9aSFrank Praznik 	return ret;
1342bd28ce00SJiri Slaby }
1343bd28ce00SJiri Slaby 
1344221399b3SFrank Praznik static void sixaxis_set_leds_from_id(struct sony_sc *sc)
13458025087aSFrank Praznik {
13468025087aSFrank Praznik 	static const __u8 sixaxis_leds[10][4] = {
13478025087aSFrank Praznik 				{ 0x01, 0x00, 0x00, 0x00 },
13488025087aSFrank Praznik 				{ 0x00, 0x01, 0x00, 0x00 },
13498025087aSFrank Praznik 				{ 0x00, 0x00, 0x01, 0x00 },
13508025087aSFrank Praznik 				{ 0x00, 0x00, 0x00, 0x01 },
13518025087aSFrank Praznik 				{ 0x01, 0x00, 0x00, 0x01 },
13528025087aSFrank Praznik 				{ 0x00, 0x01, 0x00, 0x01 },
13538025087aSFrank Praznik 				{ 0x00, 0x00, 0x01, 0x01 },
13548025087aSFrank Praznik 				{ 0x01, 0x00, 0x01, 0x01 },
13558025087aSFrank Praznik 				{ 0x00, 0x01, 0x01, 0x01 },
13568025087aSFrank Praznik 				{ 0x01, 0x01, 0x01, 0x01 }
13578025087aSFrank Praznik 	};
13588025087aSFrank Praznik 
1359221399b3SFrank Praznik 	int id = sc->device_id;
1360221399b3SFrank Praznik 
1361221399b3SFrank Praznik 	BUILD_BUG_ON(MAX_LEDS < ARRAY_SIZE(sixaxis_leds[0]));
13628025087aSFrank Praznik 
13638025087aSFrank Praznik 	if (id < 0)
13648025087aSFrank Praznik 		return;
13658025087aSFrank Praznik 
13668025087aSFrank Praznik 	id %= 10;
1367221399b3SFrank Praznik 	memcpy(sc->led_state, sixaxis_leds[id], sizeof(sixaxis_leds[id]));
13688025087aSFrank Praznik }
13698025087aSFrank Praznik 
1370221399b3SFrank Praznik static void dualshock4_set_leds_from_id(struct sony_sc *sc)
13718025087aSFrank Praznik {
13728025087aSFrank Praznik 	/* The first 4 color/index entries match what the PS4 assigns */
13738025087aSFrank Praznik 	static const __u8 color_code[7][3] = {
13748025087aSFrank Praznik 			/* Blue   */	{ 0x00, 0x00, 0x01 },
13758025087aSFrank Praznik 			/* Red	  */	{ 0x01, 0x00, 0x00 },
13768025087aSFrank Praznik 			/* Green  */	{ 0x00, 0x01, 0x00 },
13778025087aSFrank Praznik 			/* Pink   */	{ 0x02, 0x00, 0x01 },
13788025087aSFrank Praznik 			/* Orange */	{ 0x02, 0x01, 0x00 },
13798025087aSFrank Praznik 			/* Teal   */	{ 0x00, 0x01, 0x01 },
13808025087aSFrank Praznik 			/* White  */	{ 0x01, 0x01, 0x01 }
13818025087aSFrank Praznik 	};
13828025087aSFrank Praznik 
1383221399b3SFrank Praznik 	int id = sc->device_id;
1384221399b3SFrank Praznik 
1385221399b3SFrank Praznik 	BUILD_BUG_ON(MAX_LEDS < ARRAY_SIZE(color_code[0]));
13868025087aSFrank Praznik 
13878025087aSFrank Praznik 	if (id < 0)
13888025087aSFrank Praznik 		return;
13898025087aSFrank Praznik 
13908025087aSFrank Praznik 	id %= 7;
1391221399b3SFrank Praznik 	memcpy(sc->led_state, color_code[id], sizeof(color_code[id]));
13928025087aSFrank Praznik }
13938025087aSFrank Praznik 
1394221399b3SFrank Praznik static void buzz_set_leds(struct sony_sc *sc)
1395f04d5140SColin Leitner {
1396221399b3SFrank Praznik 	struct hid_device *hdev = sc->hdev;
1397f04d5140SColin Leitner 	struct list_head *report_list =
1398f04d5140SColin Leitner 		&hdev->report_enum[HID_OUTPUT_REPORT].report_list;
1399f04d5140SColin Leitner 	struct hid_report *report = list_entry(report_list->next,
1400f04d5140SColin Leitner 		struct hid_report, list);
1401f04d5140SColin Leitner 	__s32 *value = report->field[0]->value;
1402f04d5140SColin Leitner 
1403221399b3SFrank Praznik 	BUILD_BUG_ON(MAX_LEDS < 4);
1404221399b3SFrank Praznik 
1405f04d5140SColin Leitner 	value[0] = 0x00;
1406221399b3SFrank Praznik 	value[1] = sc->led_state[0] ? 0xff : 0x00;
1407221399b3SFrank Praznik 	value[2] = sc->led_state[1] ? 0xff : 0x00;
1408221399b3SFrank Praznik 	value[3] = sc->led_state[2] ? 0xff : 0x00;
1409221399b3SFrank Praznik 	value[4] = sc->led_state[3] ? 0xff : 0x00;
1410f04d5140SColin Leitner 	value[5] = 0x00;
1411f04d5140SColin Leitner 	value[6] = 0x00;
1412f04d5140SColin Leitner 	hid_hw_request(hdev, report, HID_REQ_SET_REPORT);
1413f04d5140SColin Leitner }
1414f04d5140SColin Leitner 
1415221399b3SFrank Praznik static void sony_set_leds(struct sony_sc *sc)
14160a286ef2SSven Eckelmann {
1417221399b3SFrank Praznik 	if (!(sc->quirks & BUZZ_CONTROLLER))
1418fa57a810SFrank Praznik 		schedule_work(&sc->state_worker);
1419221399b3SFrank Praznik 	else
1420221399b3SFrank Praznik 		buzz_set_leds(sc);
14210a286ef2SSven Eckelmann }
14220a286ef2SSven Eckelmann 
1423c5382519SSven Eckelmann static void sony_led_set_brightness(struct led_classdev *led,
1424f04d5140SColin Leitner 				    enum led_brightness value)
1425f04d5140SColin Leitner {
1426f04d5140SColin Leitner 	struct device *dev = led->dev->parent;
1427f04d5140SColin Leitner 	struct hid_device *hdev = container_of(dev, struct hid_device, dev);
1428f04d5140SColin Leitner 	struct sony_sc *drv_data;
1429f04d5140SColin Leitner 
1430f04d5140SColin Leitner 	int n;
1431b3ed458cSFrank Praznik 	int force_update;
1432f04d5140SColin Leitner 
1433f04d5140SColin Leitner 	drv_data = hid_get_drvdata(hdev);
14342251b85fSSven Eckelmann 	if (!drv_data) {
1435f04d5140SColin Leitner 		hid_err(hdev, "No device data\n");
1436f04d5140SColin Leitner 		return;
1437f04d5140SColin Leitner 	}
1438f04d5140SColin Leitner 
1439b3ed458cSFrank Praznik 	/*
1440b3ed458cSFrank Praznik 	 * The Sixaxis on USB will override any LED settings sent to it
1441b3ed458cSFrank Praznik 	 * and keep flashing all of the LEDs until the PS button is pressed.
1442b3ed458cSFrank Praznik 	 * Updates, even if redundant, must be always be sent to the
1443b3ed458cSFrank Praznik 	 * controller to avoid having to toggle the state of an LED just to
1444b3ed458cSFrank Praznik 	 * stop the flashing later on.
1445b3ed458cSFrank Praznik 	 */
1446b3ed458cSFrank Praznik 	force_update = !!(drv_data->quirks & SIXAXIS_CONTROLLER_USB);
1447b3ed458cSFrank Praznik 
144860781cf4SFrank Praznik 	for (n = 0; n < drv_data->led_count; n++) {
1449b3ed458cSFrank Praznik 		if (led == drv_data->leds[n] && (force_update ||
1450b3ed458cSFrank Praznik 			(value != drv_data->led_state[n] ||
1451b3ed458cSFrank Praznik 			drv_data->led_delay_on[n] ||
1452b3ed458cSFrank Praznik 			drv_data->led_delay_off[n]))) {
1453b3ed458cSFrank Praznik 
145460781cf4SFrank Praznik 			drv_data->led_state[n] = value;
1455b3ed458cSFrank Praznik 
1456b3ed458cSFrank Praznik 			/* Setting the brightness stops the blinking */
1457b3ed458cSFrank Praznik 			drv_data->led_delay_on[n] = 0;
1458b3ed458cSFrank Praznik 			drv_data->led_delay_off[n] = 0;
1459b3ed458cSFrank Praznik 
1460221399b3SFrank Praznik 			sony_set_leds(drv_data);
1461f04d5140SColin Leitner 			break;
1462f04d5140SColin Leitner 		}
1463f04d5140SColin Leitner 	}
1464f04d5140SColin Leitner }
1465f04d5140SColin Leitner 
1466c5382519SSven Eckelmann static enum led_brightness sony_led_get_brightness(struct led_classdev *led)
1467f04d5140SColin Leitner {
1468f04d5140SColin Leitner 	struct device *dev = led->dev->parent;
1469f04d5140SColin Leitner 	struct hid_device *hdev = container_of(dev, struct hid_device, dev);
1470f04d5140SColin Leitner 	struct sony_sc *drv_data;
1471f04d5140SColin Leitner 
1472f04d5140SColin Leitner 	int n;
1473f04d5140SColin Leitner 
1474f04d5140SColin Leitner 	drv_data = hid_get_drvdata(hdev);
14752251b85fSSven Eckelmann 	if (!drv_data) {
1476f04d5140SColin Leitner 		hid_err(hdev, "No device data\n");
1477f04d5140SColin Leitner 		return LED_OFF;
1478f04d5140SColin Leitner 	}
1479f04d5140SColin Leitner 
148060781cf4SFrank Praznik 	for (n = 0; n < drv_data->led_count; n++) {
14817db7504aSSimon Wood 		if (led == drv_data->leds[n])
14827db7504aSSimon Wood 			return drv_data->led_state[n];
1483f04d5140SColin Leitner 	}
1484f04d5140SColin Leitner 
14857db7504aSSimon Wood 	return LED_OFF;
1486f04d5140SColin Leitner }
1487f04d5140SColin Leitner 
1488b3ed458cSFrank Praznik static int sony_led_blink_set(struct led_classdev *led, unsigned long *delay_on,
1489b3ed458cSFrank Praznik 				unsigned long *delay_off)
1490b3ed458cSFrank Praznik {
1491b3ed458cSFrank Praznik 	struct device *dev = led->dev->parent;
1492b3ed458cSFrank Praznik 	struct hid_device *hdev = container_of(dev, struct hid_device, dev);
1493b3ed458cSFrank Praznik 	struct sony_sc *drv_data = hid_get_drvdata(hdev);
1494b3ed458cSFrank Praznik 	int n;
1495b3ed458cSFrank Praznik 	__u8 new_on, new_off;
1496b3ed458cSFrank Praznik 
1497b3ed458cSFrank Praznik 	if (!drv_data) {
1498b3ed458cSFrank Praznik 		hid_err(hdev, "No device data\n");
1499b3ed458cSFrank Praznik 		return -EINVAL;
1500b3ed458cSFrank Praznik 	}
1501b3ed458cSFrank Praznik 
1502b3ed458cSFrank Praznik 	/* Max delay is 255 deciseconds or 2550 milliseconds */
1503b3ed458cSFrank Praznik 	if (*delay_on > 2550)
1504b3ed458cSFrank Praznik 		*delay_on = 2550;
1505b3ed458cSFrank Praznik 	if (*delay_off > 2550)
1506b3ed458cSFrank Praznik 		*delay_off = 2550;
1507b3ed458cSFrank Praznik 
1508b3ed458cSFrank Praznik 	/* Blink at 1 Hz if both values are zero */
1509b3ed458cSFrank Praznik 	if (!*delay_on && !*delay_off)
1510b3ed458cSFrank Praznik 		*delay_on = *delay_off = 500;
1511b3ed458cSFrank Praznik 
1512b3ed458cSFrank Praznik 	new_on = *delay_on / 10;
1513b3ed458cSFrank Praznik 	new_off = *delay_off / 10;
1514b3ed458cSFrank Praznik 
1515b3ed458cSFrank Praznik 	for (n = 0; n < drv_data->led_count; n++) {
1516b3ed458cSFrank Praznik 		if (led == drv_data->leds[n])
1517b3ed458cSFrank Praznik 			break;
1518b3ed458cSFrank Praznik 	}
1519b3ed458cSFrank Praznik 
1520b3ed458cSFrank Praznik 	/* This LED is not registered on this device */
1521b3ed458cSFrank Praznik 	if (n >= drv_data->led_count)
1522b3ed458cSFrank Praznik 		return -EINVAL;
1523b3ed458cSFrank Praznik 
1524b3ed458cSFrank Praznik 	/* Don't schedule work if the values didn't change */
1525b3ed458cSFrank Praznik 	if (new_on != drv_data->led_delay_on[n] ||
1526b3ed458cSFrank Praznik 		new_off != drv_data->led_delay_off[n]) {
1527b3ed458cSFrank Praznik 		drv_data->led_delay_on[n] = new_on;
1528b3ed458cSFrank Praznik 		drv_data->led_delay_off[n] = new_off;
1529b3ed458cSFrank Praznik 		schedule_work(&drv_data->state_worker);
1530b3ed458cSFrank Praznik 	}
1531b3ed458cSFrank Praznik 
1532b3ed458cSFrank Praznik 	return 0;
1533b3ed458cSFrank Praznik }
1534b3ed458cSFrank Praznik 
1535fa57a810SFrank Praznik static void sony_leds_remove(struct sony_sc *sc)
15360a286ef2SSven Eckelmann {
15370a286ef2SSven Eckelmann 	struct led_classdev *led;
15380a286ef2SSven Eckelmann 	int n;
15390a286ef2SSven Eckelmann 
1540fa57a810SFrank Praznik 	BUG_ON(!(sc->quirks & SONY_LED_SUPPORT));
15410a286ef2SSven Eckelmann 
1542fa57a810SFrank Praznik 	for (n = 0; n < sc->led_count; n++) {
1543fa57a810SFrank Praznik 		led = sc->leds[n];
1544fa57a810SFrank Praznik 		sc->leds[n] = NULL;
15450a286ef2SSven Eckelmann 		if (!led)
15460a286ef2SSven Eckelmann 			continue;
15470a286ef2SSven Eckelmann 		led_classdev_unregister(led);
15480a286ef2SSven Eckelmann 		kfree(led);
15490a286ef2SSven Eckelmann 	}
155060781cf4SFrank Praznik 
1551fa57a810SFrank Praznik 	sc->led_count = 0;
15520a286ef2SSven Eckelmann }
15530a286ef2SSven Eckelmann 
1554fa57a810SFrank Praznik static int sony_leds_init(struct sony_sc *sc)
1555f04d5140SColin Leitner {
1556fa57a810SFrank Praznik 	struct hid_device *hdev = sc->hdev;
155740e32ee6SJiri Kosina 	int n, ret = 0;
1558b3ed458cSFrank Praznik 	int use_ds4_names;
155940e32ee6SJiri Kosina 	struct led_classdev *led;
156040e32ee6SJiri Kosina 	size_t name_sz;
156140e32ee6SJiri Kosina 	char *name;
15620a286ef2SSven Eckelmann 	size_t name_len;
15630a286ef2SSven Eckelmann 	const char *name_fmt;
1564b3ed458cSFrank Praznik 	static const char * const ds4_name_str[] = { "red", "green", "blue",
1565b3ed458cSFrank Praznik 						  "global" };
15665607c89aSFrank Praznik 	__u8 max_brightness[MAX_LEDS] = { [0 ... (MAX_LEDS - 1)] = 1 };
1567b3ed458cSFrank Praznik 	__u8 use_hw_blink[MAX_LEDS] = { 0 };
1568f04d5140SColin Leitner 
1569fa57a810SFrank Praznik 	BUG_ON(!(sc->quirks & SONY_LED_SUPPORT));
1570f04d5140SColin Leitner 
1571fa57a810SFrank Praznik 	if (sc->quirks & BUZZ_CONTROLLER) {
1572fa57a810SFrank Praznik 		sc->led_count = 4;
1573b3ed458cSFrank Praznik 		use_ds4_names = 0;
15740a286ef2SSven Eckelmann 		name_len = strlen("::buzz#");
15750a286ef2SSven Eckelmann 		name_fmt = "%s::buzz%d";
15769446edb9SKees Cook 		/* Validate expected report characteristics. */
15779446edb9SKees Cook 		if (!hid_validate_values(hdev, HID_OUTPUT_REPORT, 0, 0, 7))
15789446edb9SKees Cook 			return -ENODEV;
1579fa57a810SFrank Praznik 	} else if (sc->quirks & DUALSHOCK4_CONTROLLER) {
1580221399b3SFrank Praznik 		dualshock4_set_leds_from_id(sc);
1581221399b3SFrank Praznik 		sc->led_state[3] = 1;
1582b3ed458cSFrank Praznik 		sc->led_count = 4;
1583b3ed458cSFrank Praznik 		memset(max_brightness, 255, 3);
1584b3ed458cSFrank Praznik 		use_hw_blink[3] = 1;
1585b3ed458cSFrank Praznik 		use_ds4_names = 1;
158661ebca93SFrank Praznik 		name_len = 0;
158761ebca93SFrank Praznik 		name_fmt = "%s:%s";
1588c5e0c1c4SFrank Praznik 	} else if (sc->quirks & MOTION_CONTROLLER) {
1589c5e0c1c4SFrank Praznik 		sc->led_count = 3;
1590c5e0c1c4SFrank Praznik 		memset(max_brightness, 255, 3);
1591c5e0c1c4SFrank Praznik 		use_ds4_names = 1;
1592c5e0c1c4SFrank Praznik 		name_len = 0;
1593c5e0c1c4SFrank Praznik 		name_fmt = "%s:%s";
159460781cf4SFrank Praznik 	} else {
1595221399b3SFrank Praznik 		sixaxis_set_leds_from_id(sc);
1596fa57a810SFrank Praznik 		sc->led_count = 4;
1597b3ed458cSFrank Praznik 		memset(use_hw_blink, 1, 4);
1598b3ed458cSFrank Praznik 		use_ds4_names = 0;
159961ebca93SFrank Praznik 		name_len = strlen("::sony#");
160061ebca93SFrank Praznik 		name_fmt = "%s::sony%d";
160160781cf4SFrank Praznik 	}
160260781cf4SFrank Praznik 
1603ad142b9eSFrank Praznik 	/*
1604ad142b9eSFrank Praznik 	 * Clear LEDs as we have no way of reading their initial state. This is
1605f04d5140SColin Leitner 	 * only relevant if the driver is loaded after somebody actively set the
1606ad142b9eSFrank Praznik 	 * LEDs to on
1607ad142b9eSFrank Praznik 	 */
1608221399b3SFrank Praznik 	sony_set_leds(sc);
1609f04d5140SColin Leitner 
16100a286ef2SSven Eckelmann 	name_sz = strlen(dev_name(&hdev->dev)) + name_len + 1;
1611f04d5140SColin Leitner 
1612fa57a810SFrank Praznik 	for (n = 0; n < sc->led_count; n++) {
161361ebca93SFrank Praznik 
1614b3ed458cSFrank Praznik 		if (use_ds4_names)
1615b3ed458cSFrank Praznik 			name_sz = strlen(dev_name(&hdev->dev)) + strlen(ds4_name_str[n]) + 2;
161661ebca93SFrank Praznik 
1617f04d5140SColin Leitner 		led = kzalloc(sizeof(struct led_classdev) + name_sz, GFP_KERNEL);
1618f04d5140SColin Leitner 		if (!led) {
1619f04d5140SColin Leitner 			hid_err(hdev, "Couldn't allocate memory for LED %d\n", n);
16208cd5fcdaSJulia Lawall 			ret = -ENOMEM;
1621f04d5140SColin Leitner 			goto error_leds;
1622f04d5140SColin Leitner 		}
1623f04d5140SColin Leitner 
1624f04d5140SColin Leitner 		name = (void *)(&led[1]);
1625b3ed458cSFrank Praznik 		if (use_ds4_names)
1626b3ed458cSFrank Praznik 			snprintf(name, name_sz, name_fmt, dev_name(&hdev->dev),
1627b3ed458cSFrank Praznik 			ds4_name_str[n]);
162861ebca93SFrank Praznik 		else
16290a286ef2SSven Eckelmann 			snprintf(name, name_sz, name_fmt, dev_name(&hdev->dev), n + 1);
1630f04d5140SColin Leitner 		led->name = name;
1631221399b3SFrank Praznik 		led->brightness = sc->led_state[n];
1632b3ed458cSFrank Praznik 		led->max_brightness = max_brightness[n];
1633c5382519SSven Eckelmann 		led->brightness_get = sony_led_get_brightness;
1634c5382519SSven Eckelmann 		led->brightness_set = sony_led_set_brightness;
1635f04d5140SColin Leitner 
1636b3ed458cSFrank Praznik 		if (use_hw_blink[n])
1637b3ed458cSFrank Praznik 			led->blink_set = sony_led_blink_set;
1638b3ed458cSFrank Praznik 
16398025087aSFrank Praznik 		sc->leds[n] = led;
16408025087aSFrank Praznik 
16418cd5fcdaSJulia Lawall 		ret = led_classdev_register(&hdev->dev, led);
16428cd5fcdaSJulia Lawall 		if (ret) {
1643f04d5140SColin Leitner 			hid_err(hdev, "Failed to register LED %d\n", n);
16448025087aSFrank Praznik 			sc->leds[n] = NULL;
1645f04d5140SColin Leitner 			kfree(led);
1646f04d5140SColin Leitner 			goto error_leds;
1647f04d5140SColin Leitner 		}
1648f04d5140SColin Leitner 	}
1649f04d5140SColin Leitner 
1650f04d5140SColin Leitner 	return ret;
1651f04d5140SColin Leitner 
1652f04d5140SColin Leitner error_leds:
1653fa57a810SFrank Praznik 	sony_leds_remove(sc);
1654f04d5140SColin Leitner 
1655f04d5140SColin Leitner 	return ret;
1656f04d5140SColin Leitner }
1657f04d5140SColin Leitner 
1658cad665a2SFrank Praznik static void sixaxis_state_worker(struct work_struct *work)
1659a08c22c0SSven Eckelmann {
16609b2b5c9aSFrank Praznik 	static const union sixaxis_output_report_01 default_report = {
166155d3b664SFrank Praznik 		.buf = {
1662a08c22c0SSven Eckelmann 			0x01,
1663a08c22c0SSven Eckelmann 			0x00, 0xff, 0x00, 0xff, 0x00,
16640a286ef2SSven Eckelmann 			0x00, 0x00, 0x00, 0x00, 0x00,
1665a08c22c0SSven Eckelmann 			0xff, 0x27, 0x10, 0x00, 0x32,
1666a08c22c0SSven Eckelmann 			0xff, 0x27, 0x10, 0x00, 0x32,
1667a08c22c0SSven Eckelmann 			0xff, 0x27, 0x10, 0x00, 0x32,
1668a08c22c0SSven Eckelmann 			0xff, 0x27, 0x10, 0x00, 0x32,
1669a08c22c0SSven Eckelmann 			0x00, 0x00, 0x00, 0x00, 0x00
167055d3b664SFrank Praznik 		}
1671a08c22c0SSven Eckelmann 	};
16729b2b5c9aSFrank Praznik 	struct sony_sc *sc = container_of(work, struct sony_sc, state_worker);
16739b2b5c9aSFrank Praznik 	struct sixaxis_output_report *report =
16749b2b5c9aSFrank Praznik 		(struct sixaxis_output_report *)sc->output_report_dmabuf;
16759b2b5c9aSFrank Praznik 	int n;
16769b2b5c9aSFrank Praznik 
16779b2b5c9aSFrank Praznik 	/* Initialize the report with default values */
16789b2b5c9aSFrank Praznik 	memcpy(report, &default_report, sizeof(struct sixaxis_output_report));
16799f323b68SSven Eckelmann 
16800a286ef2SSven Eckelmann #ifdef CONFIG_SONY_FF
16819b2b5c9aSFrank Praznik 	report->rumble.right_motor_on = sc->right ? 1 : 0;
16829b2b5c9aSFrank Praznik 	report->rumble.left_motor_force = sc->left;
16830a286ef2SSven Eckelmann #endif
16840a286ef2SSven Eckelmann 
16859b2b5c9aSFrank Praznik 	report->leds_bitmap |= sc->led_state[0] << 1;
16869b2b5c9aSFrank Praznik 	report->leds_bitmap |= sc->led_state[1] << 2;
16879b2b5c9aSFrank Praznik 	report->leds_bitmap |= sc->led_state[2] << 3;
16889b2b5c9aSFrank Praznik 	report->leds_bitmap |= sc->led_state[3] << 4;
16899f323b68SSven Eckelmann 
169088f6576fSSimon Wood 	/* Set flag for all leds off, required for 3rd party INTEC controller */
16919b2b5c9aSFrank Praznik 	if ((report->leds_bitmap & 0x1E) == 0)
16929b2b5c9aSFrank Praznik 		report->leds_bitmap |= 0x20;
169388f6576fSSimon Wood 
1694b3ed458cSFrank Praznik 	/*
1695b3ed458cSFrank Praznik 	 * The LEDs in the report are indexed in reverse order to their
1696b3ed458cSFrank Praznik 	 * corresponding light on the controller.
1697b3ed458cSFrank Praznik 	 * Index 0 = LED 4, index 1 = LED 3, etc...
1698b3ed458cSFrank Praznik 	 *
1699b3ed458cSFrank Praznik 	 * In the case of both delay values being zero (blinking disabled) the
1700b3ed458cSFrank Praznik 	 * default report values should be used or the controller LED will be
1701b3ed458cSFrank Praznik 	 * always off.
1702b3ed458cSFrank Praznik 	 */
1703b3ed458cSFrank Praznik 	for (n = 0; n < 4; n++) {
1704b3ed458cSFrank Praznik 		if (sc->led_delay_on[n] || sc->led_delay_off[n]) {
17059b2b5c9aSFrank Praznik 			report->led[3 - n].duty_off = sc->led_delay_off[n];
17069b2b5c9aSFrank Praznik 			report->led[3 - n].duty_on = sc->led_delay_on[n];
1707b3ed458cSFrank Praznik 		}
1708b3ed458cSFrank Praznik 	}
1709b3ed458cSFrank Praznik 
17109b2b5c9aSFrank Praznik 	hid_hw_raw_request(sc->hdev, report->report_id, (__u8 *)report,
17119b2b5c9aSFrank Praznik 			sizeof(struct sixaxis_output_report),
17129b2b5c9aSFrank Praznik 			HID_OUTPUT_REPORT, HID_REQ_SET_REPORT);
17139f323b68SSven Eckelmann }
17149f323b68SSven Eckelmann 
17150bd88dd3SFrank Praznik static void dualshock4_state_worker(struct work_struct *work)
17160bd88dd3SFrank Praznik {
17170bd88dd3SFrank Praznik 	struct sony_sc *sc = container_of(work, struct sony_sc, state_worker);
17180da8ea65SFrank Praznik 	struct hid_device *hdev = sc->hdev;
17199b2b5c9aSFrank Praznik 	__u8 *buf = sc->output_report_dmabuf;
172048220237SFrank Praznik 	int offset;
17210da8ea65SFrank Praznik 
1722fdcf105dSFrank Praznik 	if (sc->quirks & DUALSHOCK4_CONTROLLER_USB) {
17239b2b5c9aSFrank Praznik 		memset(buf, 0, DS4_REPORT_0x05_SIZE);
172448220237SFrank Praznik 		buf[0] = 0x05;
1725b3ed458cSFrank Praznik 		buf[1] = 0xFF;
172648220237SFrank Praznik 		offset = 4;
1727fdcf105dSFrank Praznik 	} else {
17289b2b5c9aSFrank Praznik 		memset(buf, 0, DS4_REPORT_0x11_SIZE);
1729fdcf105dSFrank Praznik 		buf[0] = 0x11;
1730fdcf105dSFrank Praznik 		buf[1] = 0xB0;
1731fdcf105dSFrank Praznik 		buf[3] = 0x0F;
1732fdcf105dSFrank Praznik 		offset = 6;
1733fdcf105dSFrank Praznik 	}
17340bd88dd3SFrank Praznik 
17350bd88dd3SFrank Praznik #ifdef CONFIG_SONY_FF
173648220237SFrank Praznik 	buf[offset++] = sc->right;
173748220237SFrank Praznik 	buf[offset++] = sc->left;
173848220237SFrank Praznik #else
173948220237SFrank Praznik 	offset += 2;
17400bd88dd3SFrank Praznik #endif
17410bd88dd3SFrank Praznik 
1742b3ed458cSFrank Praznik 	/* LED 3 is the global control */
1743b3ed458cSFrank Praznik 	if (sc->led_state[3]) {
174448220237SFrank Praznik 		buf[offset++] = sc->led_state[0];
174548220237SFrank Praznik 		buf[offset++] = sc->led_state[1];
174648220237SFrank Praznik 		buf[offset++] = sc->led_state[2];
1747b3ed458cSFrank Praznik 	} else {
1748b3ed458cSFrank Praznik 		offset += 3;
1749b3ed458cSFrank Praznik 	}
1750b3ed458cSFrank Praznik 
1751b3ed458cSFrank Praznik 	/* If both delay values are zero the DualShock 4 disables blinking. */
1752b3ed458cSFrank Praznik 	buf[offset++] = sc->led_delay_on[3];
1753b3ed458cSFrank Praznik 	buf[offset++] = sc->led_delay_off[3];
175460781cf4SFrank Praznik 
1755fdcf105dSFrank Praznik 	if (sc->quirks & DUALSHOCK4_CONTROLLER_USB)
17569b2b5c9aSFrank Praznik 		hid_hw_output_report(hdev, buf, DS4_REPORT_0x05_SIZE);
1757fdcf105dSFrank Praznik 	else
17589b2b5c9aSFrank Praznik 		hid_hw_raw_request(hdev, 0x11, buf, DS4_REPORT_0x11_SIZE,
1759fdcf105dSFrank Praznik 				HID_OUTPUT_REPORT, HID_REQ_SET_REPORT);
17600bd88dd3SFrank Praznik }
17610bd88dd3SFrank Praznik 
1762c5e0c1c4SFrank Praznik static void motion_state_worker(struct work_struct *work)
1763c5e0c1c4SFrank Praznik {
1764c5e0c1c4SFrank Praznik 	struct sony_sc *sc = container_of(work, struct sony_sc, state_worker);
1765c5e0c1c4SFrank Praznik 	struct hid_device *hdev = sc->hdev;
1766c5e0c1c4SFrank Praznik 	struct motion_output_report_02 *report =
1767c5e0c1c4SFrank Praznik 		(struct motion_output_report_02 *)sc->output_report_dmabuf;
1768c5e0c1c4SFrank Praznik 
176941d2d425SSimon Wood 	memset(report, 0, MOTION_REPORT_0x02_SIZE);
1770c5e0c1c4SFrank Praznik 
1771c5e0c1c4SFrank Praznik 	report->type = 0x02; /* set leds */
1772c5e0c1c4SFrank Praznik 	report->r = sc->led_state[0];
1773c5e0c1c4SFrank Praznik 	report->g = sc->led_state[1];
1774c5e0c1c4SFrank Praznik 	report->b = sc->led_state[2];
1775c5e0c1c4SFrank Praznik 
1776c5e0c1c4SFrank Praznik #ifdef CONFIG_SONY_FF
1777c5e0c1c4SFrank Praznik 	report->rumble = max(sc->right, sc->left);
1778c5e0c1c4SFrank Praznik #endif
1779c5e0c1c4SFrank Praznik 
178041d2d425SSimon Wood 	hid_hw_output_report(hdev, (__u8 *)report, MOTION_REPORT_0x02_SIZE);
1781c5e0c1c4SFrank Praznik }
1782c5e0c1c4SFrank Praznik 
17839b2b5c9aSFrank Praznik static int sony_allocate_output_report(struct sony_sc *sc)
17849b2b5c9aSFrank Praznik {
17859b2b5c9aSFrank Praznik 	if (sc->quirks & SIXAXIS_CONTROLLER)
17869b2b5c9aSFrank Praznik 		sc->output_report_dmabuf =
17879b2b5c9aSFrank Praznik 			kmalloc(sizeof(union sixaxis_output_report_01),
17889b2b5c9aSFrank Praznik 				GFP_KERNEL);
17899b2b5c9aSFrank Praznik 	else if (sc->quirks & DUALSHOCK4_CONTROLLER_BT)
17909b2b5c9aSFrank Praznik 		sc->output_report_dmabuf = kmalloc(DS4_REPORT_0x11_SIZE,
17919b2b5c9aSFrank Praznik 						GFP_KERNEL);
17929b2b5c9aSFrank Praznik 	else if (sc->quirks & DUALSHOCK4_CONTROLLER_USB)
17939b2b5c9aSFrank Praznik 		sc->output_report_dmabuf = kmalloc(DS4_REPORT_0x05_SIZE,
17949b2b5c9aSFrank Praznik 						GFP_KERNEL);
1795c5e0c1c4SFrank Praznik 	else if (sc->quirks & MOTION_CONTROLLER)
179641d2d425SSimon Wood 		sc->output_report_dmabuf = kmalloc(MOTION_REPORT_0x02_SIZE,
1797c5e0c1c4SFrank Praznik 						GFP_KERNEL);
17989b2b5c9aSFrank Praznik 	else
17999b2b5c9aSFrank Praznik 		return 0;
18009b2b5c9aSFrank Praznik 
18019b2b5c9aSFrank Praznik 	if (!sc->output_report_dmabuf)
18029b2b5c9aSFrank Praznik 		return -ENOMEM;
18039b2b5c9aSFrank Praznik 
18049b2b5c9aSFrank Praznik 	return 0;
18059b2b5c9aSFrank Praznik }
18069b2b5c9aSFrank Praznik 
18070a286ef2SSven Eckelmann #ifdef CONFIG_SONY_FF
18089f323b68SSven Eckelmann static int sony_play_effect(struct input_dev *dev, void *data,
18099f323b68SSven Eckelmann 			    struct ff_effect *effect)
18109f323b68SSven Eckelmann {
1811a08c22c0SSven Eckelmann 	struct hid_device *hid = input_get_drvdata(dev);
18129f323b68SSven Eckelmann 	struct sony_sc *sc = hid_get_drvdata(hid);
1813a08c22c0SSven Eckelmann 
1814a08c22c0SSven Eckelmann 	if (effect->type != FF_RUMBLE)
1815a08c22c0SSven Eckelmann 		return 0;
1816a08c22c0SSven Eckelmann 
18179f323b68SSven Eckelmann 	sc->left = effect->u.rumble.strong_magnitude / 256;
18180bd88dd3SFrank Praznik 	sc->right = effect->u.rumble.weak_magnitude / 256;
1819a08c22c0SSven Eckelmann 
182092b5c411SSven Eckelmann 	schedule_work(&sc->state_worker);
18219f323b68SSven Eckelmann 	return 0;
1822a08c22c0SSven Eckelmann }
1823a08c22c0SSven Eckelmann 
1824fa57a810SFrank Praznik static int sony_init_ff(struct sony_sc *sc)
1825a08c22c0SSven Eckelmann {
1826fa57a810SFrank Praznik 	struct hid_input *hidinput = list_entry(sc->hdev->inputs.next,
1827a08c22c0SSven Eckelmann 						struct hid_input, list);
1828a08c22c0SSven Eckelmann 	struct input_dev *input_dev = hidinput->input;
1829a08c22c0SSven Eckelmann 
1830a08c22c0SSven Eckelmann 	input_set_capability(input_dev, EV_FF, FF_RUMBLE);
1831a08c22c0SSven Eckelmann 	return input_ff_create_memless(input_dev, NULL, sony_play_effect);
1832a08c22c0SSven Eckelmann }
1833a08c22c0SSven Eckelmann 
1834a08c22c0SSven Eckelmann #else
1835fa57a810SFrank Praznik static int sony_init_ff(struct sony_sc *sc)
1836a08c22c0SSven Eckelmann {
1837a08c22c0SSven Eckelmann 	return 0;
1838a08c22c0SSven Eckelmann }
18399f323b68SSven Eckelmann 
1840a08c22c0SSven Eckelmann #endif
1841a08c22c0SSven Eckelmann 
1842d902f472SFrank Praznik static int sony_battery_get_property(struct power_supply *psy,
1843d902f472SFrank Praznik 				     enum power_supply_property psp,
1844d902f472SFrank Praznik 				     union power_supply_propval *val)
1845c4e1ddf2SFrank Praznik {
1846297d716fSKrzysztof Kozlowski 	struct sony_sc *sc = power_supply_get_drvdata(psy);
1847d902f472SFrank Praznik 	unsigned long flags;
1848d902f472SFrank Praznik 	int ret = 0;
1849d902f472SFrank Praznik 	u8 battery_charging, battery_capacity, cable_state;
1850c4e1ddf2SFrank Praznik 
1851d902f472SFrank Praznik 	spin_lock_irqsave(&sc->lock, flags);
1852d902f472SFrank Praznik 	battery_charging = sc->battery_charging;
1853d902f472SFrank Praznik 	battery_capacity = sc->battery_capacity;
1854d902f472SFrank Praznik 	cable_state = sc->cable_state;
1855d902f472SFrank Praznik 	spin_unlock_irqrestore(&sc->lock, flags);
1856c4e1ddf2SFrank Praznik 
1857d902f472SFrank Praznik 	switch (psp) {
1858d902f472SFrank Praznik 	case POWER_SUPPLY_PROP_PRESENT:
1859d902f472SFrank Praznik 		val->intval = 1;
1860d902f472SFrank Praznik 		break;
1861d902f472SFrank Praznik 	case POWER_SUPPLY_PROP_SCOPE:
1862d902f472SFrank Praznik 		val->intval = POWER_SUPPLY_SCOPE_DEVICE;
1863d902f472SFrank Praznik 		break;
1864d902f472SFrank Praznik 	case POWER_SUPPLY_PROP_CAPACITY:
1865d902f472SFrank Praznik 		val->intval = battery_capacity;
1866d902f472SFrank Praznik 		break;
1867d902f472SFrank Praznik 	case POWER_SUPPLY_PROP_STATUS:
1868d902f472SFrank Praznik 		if (battery_charging)
1869d902f472SFrank Praznik 			val->intval = POWER_SUPPLY_STATUS_CHARGING;
1870d902f472SFrank Praznik 		else
1871d902f472SFrank Praznik 			if (battery_capacity == 100 && cable_state)
1872d902f472SFrank Praznik 				val->intval = POWER_SUPPLY_STATUS_FULL;
1873d902f472SFrank Praznik 			else
1874d902f472SFrank Praznik 				val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
1875d902f472SFrank Praznik 		break;
1876d902f472SFrank Praznik 	default:
1877d902f472SFrank Praznik 		ret = -EINVAL;
1878d902f472SFrank Praznik 		break;
1879c4e1ddf2SFrank Praznik 	}
1880d902f472SFrank Praznik 	return ret;
1881d902f472SFrank Praznik }
1882d902f472SFrank Praznik 
1883d902f472SFrank Praznik static int sony_battery_probe(struct sony_sc *sc)
1884d902f472SFrank Praznik {
1885297d716fSKrzysztof Kozlowski 	struct power_supply_config psy_cfg = { .drv_data = sc, };
1886d902f472SFrank Praznik 	struct hid_device *hdev = sc->hdev;
1887d902f472SFrank Praznik 	int ret;
1888d902f472SFrank Praznik 
1889ad142b9eSFrank Praznik 	/*
1890ad142b9eSFrank Praznik 	 * Set the default battery level to 100% to avoid low battery warnings
1891d9a293a9SFrank Praznik 	 * if the battery is polled before the first device report is received.
1892d9a293a9SFrank Praznik 	 */
1893d9a293a9SFrank Praznik 	sc->battery_capacity = 100;
1894d9a293a9SFrank Praznik 
1895297d716fSKrzysztof Kozlowski 	sc->battery_desc.properties = sony_battery_props;
1896297d716fSKrzysztof Kozlowski 	sc->battery_desc.num_properties = ARRAY_SIZE(sony_battery_props);
1897297d716fSKrzysztof Kozlowski 	sc->battery_desc.get_property = sony_battery_get_property;
1898297d716fSKrzysztof Kozlowski 	sc->battery_desc.type = POWER_SUPPLY_TYPE_BATTERY;
1899297d716fSKrzysztof Kozlowski 	sc->battery_desc.use_for_apm = 0;
1900297d716fSKrzysztof Kozlowski 	sc->battery_desc.name = kasprintf(GFP_KERNEL,
1901297d716fSKrzysztof Kozlowski 					  "sony_controller_battery_%pMR",
1902314531f1SFrank Praznik 					  sc->mac_address);
1903297d716fSKrzysztof Kozlowski 	if (!sc->battery_desc.name)
1904d902f472SFrank Praznik 		return -ENOMEM;
1905d902f472SFrank Praznik 
1906297d716fSKrzysztof Kozlowski 	sc->battery = power_supply_register(&hdev->dev, &sc->battery_desc,
1907297d716fSKrzysztof Kozlowski 					    &psy_cfg);
1908297d716fSKrzysztof Kozlowski 	if (IS_ERR(sc->battery)) {
1909297d716fSKrzysztof Kozlowski 		ret = PTR_ERR(sc->battery);
1910d902f472SFrank Praznik 		hid_err(hdev, "Unable to register battery device\n");
1911d902f472SFrank Praznik 		goto err_free;
1912d902f472SFrank Praznik 	}
1913d902f472SFrank Praznik 
1914297d716fSKrzysztof Kozlowski 	power_supply_powers(sc->battery, &hdev->dev);
1915d902f472SFrank Praznik 	return 0;
1916d902f472SFrank Praznik 
1917d902f472SFrank Praznik err_free:
1918297d716fSKrzysztof Kozlowski 	kfree(sc->battery_desc.name);
1919297d716fSKrzysztof Kozlowski 	sc->battery_desc.name = NULL;
1920d902f472SFrank Praznik 	return ret;
1921d902f472SFrank Praznik }
1922d902f472SFrank Praznik 
1923d902f472SFrank Praznik static void sony_battery_remove(struct sony_sc *sc)
1924d902f472SFrank Praznik {
1925297d716fSKrzysztof Kozlowski 	if (!sc->battery_desc.name)
1926d902f472SFrank Praznik 		return;
1927d902f472SFrank Praznik 
1928297d716fSKrzysztof Kozlowski 	power_supply_unregister(sc->battery);
1929297d716fSKrzysztof Kozlowski 	kfree(sc->battery_desc.name);
1930297d716fSKrzysztof Kozlowski 	sc->battery_desc.name = NULL;
1931d902f472SFrank Praznik }
1932d902f472SFrank Praznik 
1933d2d782fcSFrank Praznik /*
1934d2d782fcSFrank Praznik  * If a controller is plugged in via USB while already connected via Bluetooth
1935d2d782fcSFrank Praznik  * it will show up as two devices. A global list of connected controllers and
1936d2d782fcSFrank Praznik  * their MAC addresses is maintained to ensure that a device is only connected
1937d2d782fcSFrank Praznik  * once.
1938d2d782fcSFrank Praznik  */
1939d2d782fcSFrank Praznik static int sony_check_add_dev_list(struct sony_sc *sc)
1940d2d782fcSFrank Praznik {
1941d2d782fcSFrank Praznik 	struct sony_sc *entry;
1942d2d782fcSFrank Praznik 	unsigned long flags;
1943d2d782fcSFrank Praznik 	int ret;
1944d2d782fcSFrank Praznik 
1945d2d782fcSFrank Praznik 	spin_lock_irqsave(&sony_dev_list_lock, flags);
1946d2d782fcSFrank Praznik 
1947d2d782fcSFrank Praznik 	list_for_each_entry(entry, &sony_device_list, list_node) {
1948d2d782fcSFrank Praznik 		ret = memcmp(sc->mac_address, entry->mac_address,
1949d2d782fcSFrank Praznik 				sizeof(sc->mac_address));
1950d2d782fcSFrank Praznik 		if (!ret) {
1951d2d782fcSFrank Praznik 			ret = -EEXIST;
1952d2d782fcSFrank Praznik 			hid_info(sc->hdev, "controller with MAC address %pMR already connected\n",
1953d2d782fcSFrank Praznik 				sc->mac_address);
1954d2d782fcSFrank Praznik 			goto unlock;
1955d2d782fcSFrank Praznik 		}
1956c4e1ddf2SFrank Praznik 	}
1957c4e1ddf2SFrank Praznik 
1958d2d782fcSFrank Praznik 	ret = 0;
1959d2d782fcSFrank Praznik 	list_add(&(sc->list_node), &sony_device_list);
1960c4e1ddf2SFrank Praznik 
1961d2d782fcSFrank Praznik unlock:
1962d2d782fcSFrank Praznik 	spin_unlock_irqrestore(&sony_dev_list_lock, flags);
1963d2d782fcSFrank Praznik 	return ret;
1964d2d782fcSFrank Praznik }
1965d2d782fcSFrank Praznik 
1966d2d782fcSFrank Praznik static void sony_remove_dev_list(struct sony_sc *sc)
1967d2d782fcSFrank Praznik {
1968d2d782fcSFrank Praznik 	unsigned long flags;
1969d2d782fcSFrank Praznik 
1970d2d782fcSFrank Praznik 	if (sc->list_node.next) {
1971d2d782fcSFrank Praznik 		spin_lock_irqsave(&sony_dev_list_lock, flags);
1972d2d782fcSFrank Praznik 		list_del(&(sc->list_node));
1973d2d782fcSFrank Praznik 		spin_unlock_irqrestore(&sony_dev_list_lock, flags);
1974d2d782fcSFrank Praznik 	}
1975d2d782fcSFrank Praznik }
1976d2d782fcSFrank Praznik 
1977d2d782fcSFrank Praznik static int sony_get_bt_devaddr(struct sony_sc *sc)
1978d2d782fcSFrank Praznik {
1979d2d782fcSFrank Praznik 	int ret;
1980d2d782fcSFrank Praznik 
1981d2d782fcSFrank Praznik 	/* HIDP stores the device MAC address as a string in the uniq field. */
1982d2d782fcSFrank Praznik 	ret = strlen(sc->hdev->uniq);
1983d2d782fcSFrank Praznik 	if (ret != 17)
1984c4e1ddf2SFrank Praznik 		return -EINVAL;
1985d2d782fcSFrank Praznik 
1986d2d782fcSFrank Praznik 	ret = sscanf(sc->hdev->uniq,
1987d2d782fcSFrank Praznik 		"%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
1988d2d782fcSFrank Praznik 		&sc->mac_address[5], &sc->mac_address[4], &sc->mac_address[3],
1989d2d782fcSFrank Praznik 		&sc->mac_address[2], &sc->mac_address[1], &sc->mac_address[0]);
1990d2d782fcSFrank Praznik 
1991d2d782fcSFrank Praznik 	if (ret != 6)
1992d2d782fcSFrank Praznik 		return -EINVAL;
1993d2d782fcSFrank Praznik 
1994d2d782fcSFrank Praznik 	return 0;
1995c4e1ddf2SFrank Praznik }
1996c4e1ddf2SFrank Praznik 
1997d2d782fcSFrank Praznik static int sony_check_add(struct sony_sc *sc)
1998d2d782fcSFrank Praznik {
19999b2b5c9aSFrank Praznik 	__u8 *buf = NULL;
2000d2d782fcSFrank Praznik 	int n, ret;
2001d2d782fcSFrank Praznik 
2002d2d782fcSFrank Praznik 	if ((sc->quirks & DUALSHOCK4_CONTROLLER_BT) ||
200312e9a6d7SSimon Wood 	    (sc->quirks & MOTION_CONTROLLER_BT) ||
2004d2d782fcSFrank Praznik 	    (sc->quirks & SIXAXIS_CONTROLLER_BT)) {
2005d2d782fcSFrank Praznik 		/*
2006d2d782fcSFrank Praznik 		 * sony_get_bt_devaddr() attempts to parse the Bluetooth MAC
2007d2d782fcSFrank Praznik 		 * address from the uniq string where HIDP stores it.
2008d2d782fcSFrank Praznik 		 * As uniq cannot be guaranteed to be a MAC address in all cases
2009d2d782fcSFrank Praznik 		 * a failure of this function should not prevent the connection.
2010d2d782fcSFrank Praznik 		 */
2011d2d782fcSFrank Praznik 		if (sony_get_bt_devaddr(sc) < 0) {
2012d2d782fcSFrank Praznik 			hid_warn(sc->hdev, "UNIQ does not contain a MAC address; duplicate check skipped\n");
2013d2d782fcSFrank Praznik 			return 0;
2014d2d782fcSFrank Praznik 		}
2015d2d782fcSFrank Praznik 	} else if (sc->quirks & DUALSHOCK4_CONTROLLER_USB) {
20169b2b5c9aSFrank Praznik 		buf = kmalloc(DS4_REPORT_0x81_SIZE, GFP_KERNEL);
20179b2b5c9aSFrank Praznik 		if (!buf)
20189b2b5c9aSFrank Praznik 			return -ENOMEM;
2019d2d782fcSFrank Praznik 
2020d2d782fcSFrank Praznik 		/*
2021d2d782fcSFrank Praznik 		 * The MAC address of a DS4 controller connected via USB can be
2022d2d782fcSFrank Praznik 		 * retrieved with feature report 0x81. The address begins at
2023d2d782fcSFrank Praznik 		 * offset 1.
2024d2d782fcSFrank Praznik 		 */
20259b2b5c9aSFrank Praznik 		ret = hid_hw_raw_request(sc->hdev, 0x81, buf,
20269b2b5c9aSFrank Praznik 				DS4_REPORT_0x81_SIZE, HID_FEATURE_REPORT,
20279b2b5c9aSFrank Praznik 				HID_REQ_GET_REPORT);
2028d2d782fcSFrank Praznik 
20299b2b5c9aSFrank Praznik 		if (ret != DS4_REPORT_0x81_SIZE) {
2030d2d782fcSFrank Praznik 			hid_err(sc->hdev, "failed to retrieve feature report 0x81 with the DualShock 4 MAC address\n");
20319b2b5c9aSFrank Praznik 			ret = ret < 0 ? ret : -EINVAL;
20329b2b5c9aSFrank Praznik 			goto out_free;
2033d2d782fcSFrank Praznik 		}
2034d2d782fcSFrank Praznik 
2035d2d782fcSFrank Praznik 		memcpy(sc->mac_address, &buf[1], sizeof(sc->mac_address));
2036d2d782fcSFrank Praznik 	} else if (sc->quirks & SIXAXIS_CONTROLLER_USB) {
20379b2b5c9aSFrank Praznik 		buf = kmalloc(SIXAXIS_REPORT_0xF2_SIZE, GFP_KERNEL);
20389b2b5c9aSFrank Praznik 		if (!buf)
20399b2b5c9aSFrank Praznik 			return -ENOMEM;
2040d2d782fcSFrank Praznik 
2041d2d782fcSFrank Praznik 		/*
2042d2d782fcSFrank Praznik 		 * The MAC address of a Sixaxis controller connected via USB can
2043d2d782fcSFrank Praznik 		 * be retrieved with feature report 0xf2. The address begins at
2044d2d782fcSFrank Praznik 		 * offset 4.
2045d2d782fcSFrank Praznik 		 */
20469b2b5c9aSFrank Praznik 		ret = hid_hw_raw_request(sc->hdev, 0xf2, buf,
20479b2b5c9aSFrank Praznik 				SIXAXIS_REPORT_0xF2_SIZE, HID_FEATURE_REPORT,
20489b2b5c9aSFrank Praznik 				HID_REQ_GET_REPORT);
2049d2d782fcSFrank Praznik 
20509b2b5c9aSFrank Praznik 		if (ret != SIXAXIS_REPORT_0xF2_SIZE) {
2051d2d782fcSFrank Praznik 			hid_err(sc->hdev, "failed to retrieve feature report 0xf2 with the Sixaxis MAC address\n");
20529b2b5c9aSFrank Praznik 			ret = ret < 0 ? ret : -EINVAL;
20539b2b5c9aSFrank Praznik 			goto out_free;
2054d2d782fcSFrank Praznik 		}
2055d2d782fcSFrank Praznik 
2056d2d782fcSFrank Praznik 		/*
2057d2d782fcSFrank Praznik 		 * The Sixaxis device MAC in the report is big-endian and must
2058d2d782fcSFrank Praznik 		 * be byte-swapped.
2059d2d782fcSFrank Praznik 		 */
2060d2d782fcSFrank Praznik 		for (n = 0; n < 6; n++)
2061d2d782fcSFrank Praznik 			sc->mac_address[5-n] = buf[4+n];
2062d2d782fcSFrank Praznik 	} else {
2063d2d782fcSFrank Praznik 		return 0;
2064d2d782fcSFrank Praznik 	}
2065d2d782fcSFrank Praznik 
20669b2b5c9aSFrank Praznik 	ret = sony_check_add_dev_list(sc);
20679b2b5c9aSFrank Praznik 
20689b2b5c9aSFrank Praznik out_free:
20699b2b5c9aSFrank Praznik 
20709b2b5c9aSFrank Praznik 	kfree(buf);
20719b2b5c9aSFrank Praznik 
20729b2b5c9aSFrank Praznik 	return ret;
2073d2d782fcSFrank Praznik }
2074d2d782fcSFrank Praznik 
20758025087aSFrank Praznik static int sony_set_device_id(struct sony_sc *sc)
20768025087aSFrank Praznik {
20778025087aSFrank Praznik 	int ret;
20788025087aSFrank Praznik 
20798025087aSFrank Praznik 	/*
20808025087aSFrank Praznik 	 * Only DualShock 4 or Sixaxis controllers get an id.
20818025087aSFrank Praznik 	 * All others are set to -1.
20828025087aSFrank Praznik 	 */
20838025087aSFrank Praznik 	if ((sc->quirks & SIXAXIS_CONTROLLER) ||
20848025087aSFrank Praznik 	    (sc->quirks & DUALSHOCK4_CONTROLLER)) {
20858025087aSFrank Praznik 		ret = ida_simple_get(&sony_device_id_allocator, 0, 0,
20868025087aSFrank Praznik 					GFP_KERNEL);
20878025087aSFrank Praznik 		if (ret < 0) {
20888025087aSFrank Praznik 			sc->device_id = -1;
20898025087aSFrank Praznik 			return ret;
20908025087aSFrank Praznik 		}
20918025087aSFrank Praznik 		sc->device_id = ret;
20928025087aSFrank Praznik 	} else {
20938025087aSFrank Praznik 		sc->device_id = -1;
20948025087aSFrank Praznik 	}
20958025087aSFrank Praznik 
20968025087aSFrank Praznik 	return 0;
20978025087aSFrank Praznik }
20988025087aSFrank Praznik 
20998025087aSFrank Praznik static void sony_release_device_id(struct sony_sc *sc)
21008025087aSFrank Praznik {
21018025087aSFrank Praznik 	if (sc->device_id >= 0) {
21028025087aSFrank Praznik 		ida_simple_remove(&sony_device_id_allocator, sc->device_id);
21038025087aSFrank Praznik 		sc->device_id = -1;
21048025087aSFrank Praznik 	}
21058025087aSFrank Praznik }
21068025087aSFrank Praznik 
210746262047SFrank Praznik static inline void sony_init_work(struct sony_sc *sc,
210846262047SFrank Praznik 					void (*worker)(struct work_struct *))
210946262047SFrank Praznik {
211046262047SFrank Praznik 	if (!sc->worker_initialized)
211146262047SFrank Praznik 		INIT_WORK(&sc->state_worker, worker);
211246262047SFrank Praznik 
211346262047SFrank Praznik 	sc->worker_initialized = 1;
211446262047SFrank Praznik }
211546262047SFrank Praznik 
211646262047SFrank Praznik static inline void sony_cancel_work_sync(struct sony_sc *sc)
211746262047SFrank Praznik {
211846262047SFrank Praznik 	if (sc->worker_initialized)
211946262047SFrank Praznik 		cancel_work_sync(&sc->state_worker);
212046262047SFrank Praznik }
2121d2d782fcSFrank Praznik 
2122bd28ce00SJiri Slaby static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
2123bd28ce00SJiri Slaby {
2124bd28ce00SJiri Slaby 	int ret;
2125cc6e0bbbSJiri Kosina 	unsigned long quirks = id->driver_data;
2126cc6e0bbbSJiri Kosina 	struct sony_sc *sc;
2127f04d5140SColin Leitner 	unsigned int connect_mask = HID_CONNECT_DEFAULT;
2128cc6e0bbbSJiri Kosina 
2129abf832bfSBenjamin Tissoires 	sc = devm_kzalloc(&hdev->dev, sizeof(*sc), GFP_KERNEL);
2130cc6e0bbbSJiri Kosina 	if (sc == NULL) {
21314291ee30SJoe Perches 		hid_err(hdev, "can't alloc sony descriptor\n");
2132cc6e0bbbSJiri Kosina 		return -ENOMEM;
2133cc6e0bbbSJiri Kosina 	}
2134cc6e0bbbSJiri Kosina 
2135b94993f6SFrank Praznik 	spin_lock_init(&sc->lock);
2136b94993f6SFrank Praznik 
2137cc6e0bbbSJiri Kosina 	sc->quirks = quirks;
2138cc6e0bbbSJiri Kosina 	hid_set_drvdata(hdev, sc);
21390a286ef2SSven Eckelmann 	sc->hdev = hdev;
2140bd28ce00SJiri Slaby 
2141bd28ce00SJiri Slaby 	ret = hid_parse(hdev);
2142bd28ce00SJiri Slaby 	if (ret) {
21434291ee30SJoe Perches 		hid_err(hdev, "parse failed\n");
2144abf832bfSBenjamin Tissoires 		return ret;
2145bd28ce00SJiri Slaby 	}
2146bd28ce00SJiri Slaby 
2147f04d5140SColin Leitner 	if (sc->quirks & VAIO_RDESC_CONSTANT)
2148f04d5140SColin Leitner 		connect_mask |= HID_CONNECT_HIDDEV_FORCE;
214950764650SAntonio Ospite 	else if (sc->quirks & SIXAXIS_CONTROLLER)
2150f04d5140SColin Leitner 		connect_mask |= HID_CONNECT_HIDDEV_FORCE;
2151f04d5140SColin Leitner 
2152f04d5140SColin Leitner 	ret = hid_hw_start(hdev, connect_mask);
2153bd28ce00SJiri Slaby 	if (ret) {
21544291ee30SJoe Perches 		hid_err(hdev, "hw start failed\n");
2155abf832bfSBenjamin Tissoires 		return ret;
2156bd28ce00SJiri Slaby 	}
2157bd28ce00SJiri Slaby 
21588025087aSFrank Praznik 	ret = sony_set_device_id(sc);
21598025087aSFrank Praznik 	if (ret < 0) {
21608025087aSFrank Praznik 		hid_err(hdev, "failed to allocate the device id\n");
21618025087aSFrank Praznik 		goto err_stop;
21628025087aSFrank Praznik 	}
21638025087aSFrank Praznik 
2164131a8a9aSFrank Praznik 	ret = sony_allocate_output_report(sc);
2165131a8a9aSFrank Praznik 	if (ret < 0) {
2166131a8a9aSFrank Praznik 		hid_err(hdev, "failed to allocate the output report buffer\n");
2167131a8a9aSFrank Praznik 		goto err_stop;
2168131a8a9aSFrank Praznik 	}
2169131a8a9aSFrank Praznik 
2170569b10a5SAntonio Ospite 	if (sc->quirks & SIXAXIS_CONTROLLER_USB) {
2171e534a935SBenjamin Tissoires 		/*
2172e534a935SBenjamin Tissoires 		 * The Sony Sixaxis does not handle HID Output Reports on the
2173e534a935SBenjamin Tissoires 		 * Interrupt EP like it could, so we need to force HID Output
2174e534a935SBenjamin Tissoires 		 * Reports to use HID_REQ_SET_REPORT on the Control EP.
2175e534a935SBenjamin Tissoires 		 *
2176e534a935SBenjamin Tissoires 		 * There is also another issue about HID Output Reports via USB,
2177e534a935SBenjamin Tissoires 		 * the Sixaxis does not want the report_id as part of the data
2178e534a935SBenjamin Tissoires 		 * packet, so we have to discard buf[0] when sending the actual
2179e534a935SBenjamin Tissoires 		 * control message, even for numbered reports, humpf!
2180e534a935SBenjamin Tissoires 		 */
2181e534a935SBenjamin Tissoires 		hdev->quirks |= HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP;
2182e534a935SBenjamin Tissoires 		hdev->quirks |= HID_QUIRK_SKIP_OUTPUT_REPORT_ID;
2183816651a7SAntonio Ospite 		ret = sixaxis_set_operational_usb(hdev);
218446262047SFrank Praznik 		sony_init_work(sc, sixaxis_state_worker);
2185fee4e2d5SFrank Praznik 	} else if (sc->quirks & SIXAXIS_CONTROLLER_BT) {
21862078b9bbSFrank Praznik 		/*
21872078b9bbSFrank Praznik 		 * The Sixaxis wants output reports sent on the ctrl endpoint
21882078b9bbSFrank Praznik 		 * when connected via Bluetooth.
21892078b9bbSFrank Praznik 		 */
21902078b9bbSFrank Praznik 		hdev->quirks |= HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP;
2191816651a7SAntonio Ospite 		ret = sixaxis_set_operational_bt(hdev);
219246262047SFrank Praznik 		sony_init_work(sc, sixaxis_state_worker);
2193fee4e2d5SFrank Praznik 	} else if (sc->quirks & DUALSHOCK4_CONTROLLER) {
219468330d83SFrank Praznik 		if (sc->quirks & DUALSHOCK4_CONTROLLER_BT) {
21952078b9bbSFrank Praznik 			/*
21962078b9bbSFrank Praznik 			 * The DualShock 4 wants output reports sent on the ctrl
21972078b9bbSFrank Praznik 			 * endpoint when connected via Bluetooth.
21982078b9bbSFrank Praznik 			 */
21992078b9bbSFrank Praznik 			hdev->quirks |= HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP;
220068330d83SFrank Praznik 			ret = dualshock4_set_operational_bt(hdev);
220168330d83SFrank Praznik 			if (ret < 0) {
220268330d83SFrank Praznik 				hid_err(hdev, "failed to set the Dualshock 4 operational mode\n");
220368330d83SFrank Praznik 				goto err_stop;
220468330d83SFrank Praznik 			}
220568330d83SFrank Praznik 		}
2206c4e1ddf2SFrank Praznik 
220746262047SFrank Praznik 		sony_init_work(sc, dualshock4_state_worker);
2208c5e0c1c4SFrank Praznik 	} else if (sc->quirks & MOTION_CONTROLLER) {
2209c5e0c1c4SFrank Praznik 		sony_init_work(sc, motion_state_worker);
22100bd88dd3SFrank Praznik 	} else {
22110bd88dd3SFrank Praznik 		ret = 0;
22120bd88dd3SFrank Praznik 	}
2213f9ce7c28SBastien Nocera 
22144dfdc464SJiri Kosina 	if (ret < 0)
2215bd28ce00SJiri Slaby 		goto err_stop;
2216bd28ce00SJiri Slaby 
2217d2d782fcSFrank Praznik 	ret = sony_check_add(sc);
2218d2d782fcSFrank Praznik 	if (ret < 0)
2219d2d782fcSFrank Praznik 		goto err_stop;
2220d2d782fcSFrank Praznik 
22210a286ef2SSven Eckelmann 	if (sc->quirks & SONY_LED_SUPPORT) {
2222fa57a810SFrank Praznik 		ret = sony_leds_init(sc);
22230a286ef2SSven Eckelmann 		if (ret < 0)
22240a286ef2SSven Eckelmann 			goto err_stop;
22250a286ef2SSven Eckelmann 	}
22260a286ef2SSven Eckelmann 
2227d902f472SFrank Praznik 	if (sc->quirks & SONY_BATTERY_SUPPORT) {
2228d902f472SFrank Praznik 		ret = sony_battery_probe(sc);
2229a08c22c0SSven Eckelmann 		if (ret < 0)
2230a08c22c0SSven Eckelmann 			goto err_stop;
2231a08c22c0SSven Eckelmann 
2232d902f472SFrank Praznik 		/* Open the device to receive reports with battery info */
2233d902f472SFrank Praznik 		ret = hid_hw_open(hdev);
2234d902f472SFrank Praznik 		if (ret < 0) {
2235d902f472SFrank Praznik 			hid_err(hdev, "hw open failed\n");
2236d902f472SFrank Praznik 			goto err_stop;
2237d902f472SFrank Praznik 		}
2238d902f472SFrank Praznik 	}
2239d902f472SFrank Praznik 
2240c8de9dbbSFrank Praznik 	if (sc->quirks & SONY_FF_SUPPORT) {
2241fa57a810SFrank Praznik 		ret = sony_init_ff(sc);
2242d902f472SFrank Praznik 		if (ret < 0)
2243d902f472SFrank Praznik 			goto err_close;
22445f5750d2SFrank Praznik 	}
2245bd28ce00SJiri Slaby 
2246f425458eSH Hartley Sweeten 	return 0;
2247d902f472SFrank Praznik err_close:
2248d902f472SFrank Praznik 	hid_hw_close(hdev);
2249bd28ce00SJiri Slaby err_stop:
22500a286ef2SSven Eckelmann 	if (sc->quirks & SONY_LED_SUPPORT)
2251fa57a810SFrank Praznik 		sony_leds_remove(sc);
2252d902f472SFrank Praznik 	if (sc->quirks & SONY_BATTERY_SUPPORT)
2253d902f472SFrank Praznik 		sony_battery_remove(sc);
225446262047SFrank Praznik 	sony_cancel_work_sync(sc);
22559b2b5c9aSFrank Praznik 	kfree(sc->output_report_dmabuf);
2256d2d782fcSFrank Praznik 	sony_remove_dev_list(sc);
22578025087aSFrank Praznik 	sony_release_device_id(sc);
2258bd28ce00SJiri Slaby 	hid_hw_stop(hdev);
2259bd28ce00SJiri Slaby 	return ret;
2260bd28ce00SJiri Slaby }
2261bd28ce00SJiri Slaby 
2262bd28ce00SJiri Slaby static void sony_remove(struct hid_device *hdev)
2263bd28ce00SJiri Slaby {
2264bd28ce00SJiri Slaby 	struct sony_sc *sc = hid_get_drvdata(hdev);
2265bd28ce00SJiri Slaby 
22660a286ef2SSven Eckelmann 	if (sc->quirks & SONY_LED_SUPPORT)
2267fa57a810SFrank Praznik 		sony_leds_remove(sc);
2268bd28ce00SJiri Slaby 
2269d902f472SFrank Praznik 	if (sc->quirks & SONY_BATTERY_SUPPORT) {
2270d902f472SFrank Praznik 		hid_hw_close(hdev);
2271d902f472SFrank Praznik 		sony_battery_remove(sc);
2272d902f472SFrank Praznik 	}
2273d902f472SFrank Praznik 
227446262047SFrank Praznik 	sony_cancel_work_sync(sc);
22759f323b68SSven Eckelmann 
22769b2b5c9aSFrank Praznik 	kfree(sc->output_report_dmabuf);
22779b2b5c9aSFrank Praznik 
2278d2d782fcSFrank Praznik 	sony_remove_dev_list(sc);
2279bd28ce00SJiri Slaby 
22808025087aSFrank Praznik 	sony_release_device_id(sc);
22818025087aSFrank Praznik 
2282bd28ce00SJiri Slaby 	hid_hw_stop(hdev);
2283bd28ce00SJiri Slaby }
2284bd28ce00SJiri Slaby 
2285bd28ce00SJiri Slaby static const struct hid_device_id sony_devices[] = {
2286bd28ce00SJiri Slaby 	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER),
2287bd28ce00SJiri Slaby 		.driver_data = SIXAXIS_CONTROLLER_USB },
2288bd28ce00SJiri Slaby 	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER),
2289bd28ce00SJiri Slaby 		.driver_data = SIXAXIS_CONTROLLER_USB },
2290c5e0c1c4SFrank Praznik 	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_MOTION_CONTROLLER),
2291b3bca326SSimon Wood 		.driver_data = MOTION_CONTROLLER_USB },
2292a4afa854SSimon Wood 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_MOTION_CONTROLLER),
2293b3bca326SSimon Wood 		.driver_data = MOTION_CONTROLLER_BT },
2294bd28ce00SJiri Slaby 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER),
2295bd28ce00SJiri Slaby 		.driver_data = SIXAXIS_CONTROLLER_BT },
2296bd28ce00SJiri Slaby 	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE),
2297bd28ce00SJiri Slaby 		.driver_data = VAIO_RDESC_CONSTANT },
2298bd28ce00SJiri Slaby 	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGP_MOUSE),
2299bd28ce00SJiri Slaby 		.driver_data = VAIO_RDESC_CONSTANT },
2300bd28ce00SJiri Slaby 	/* Wired Buzz Controller. Reported as Sony Hub from its USB ID and as
2301bd28ce00SJiri Slaby 	 * Logitech joystick from the device descriptor. */
2302bd28ce00SJiri Slaby 	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_BUZZ_CONTROLLER),
2303bd28ce00SJiri Slaby 		.driver_data = BUZZ_CONTROLLER },
2304bd28ce00SJiri Slaby 	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_WIRELESS_BUZZ_CONTROLLER),
2305bd28ce00SJiri Slaby 		.driver_data = BUZZ_CONTROLLER },
2306bd28ce00SJiri Slaby 	/* PS3 BD Remote Control */
2307bd28ce00SJiri Slaby 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_BDREMOTE),
2308bd28ce00SJiri Slaby 		.driver_data = PS3REMOTE },
2309bd28ce00SJiri Slaby 	/* Logitech Harmony Adapter for PS3 */
2310bd28ce00SJiri Slaby 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_PS3),
2311bd28ce00SJiri Slaby 		.driver_data = PS3REMOTE },
231268a49e51SFrank Praznik 	/* SMK-Link PS3 BD Remote Control */
231368a49e51SFrank Praznik 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SMK, USB_DEVICE_ID_SMK_PS3_BDREMOTE),
231468a49e51SFrank Praznik 		.driver_data = PS3REMOTE },
23150bd88dd3SFrank Praznik 	/* Sony Dualshock 4 controllers for PS4 */
23160bd88dd3SFrank Praznik 	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER),
23178ab1676bSFrank Praznik 		.driver_data = DUALSHOCK4_CONTROLLER_USB },
23180bd88dd3SFrank Praznik 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER),
23198ab1676bSFrank Praznik 		.driver_data = DUALSHOCK4_CONTROLLER_BT },
2320bd28ce00SJiri Slaby 	{ }
2321bd28ce00SJiri Slaby };
2322bd28ce00SJiri Slaby MODULE_DEVICE_TABLE(hid, sony_devices);
2323bd28ce00SJiri Slaby 
2324bd28ce00SJiri Slaby static struct hid_driver sony_driver = {
2325bd28ce00SJiri Slaby 	.name             = "sony",
2326bd28ce00SJiri Slaby 	.id_table         = sony_devices,
2327bd28ce00SJiri Slaby 	.input_mapping    = sony_mapping,
2328ce8efc3bSFrank Praznik 	.input_configured = sony_input_configured,
2329bd28ce00SJiri Slaby 	.probe            = sony_probe,
2330bd28ce00SJiri Slaby 	.remove           = sony_remove,
2331bd28ce00SJiri Slaby 	.report_fixup     = sony_report_fixup,
2332bd28ce00SJiri Slaby 	.raw_event        = sony_raw_event
2333bd28ce00SJiri Slaby };
23348025087aSFrank Praznik 
23358025087aSFrank Praznik static int __init sony_init(void)
23368025087aSFrank Praznik {
23378025087aSFrank Praznik 	dbg_hid("Sony:%s\n", __func__);
23388025087aSFrank Praznik 
23398025087aSFrank Praznik 	return hid_register_driver(&sony_driver);
23408025087aSFrank Praznik }
23418025087aSFrank Praznik 
23428025087aSFrank Praznik static void __exit sony_exit(void)
23438025087aSFrank Praznik {
23448025087aSFrank Praznik 	dbg_hid("Sony:%s\n", __func__);
23458025087aSFrank Praznik 
23468025087aSFrank Praznik 	hid_unregister_driver(&sony_driver);
23476c40065fSAntonio Ospite 	ida_destroy(&sony_device_id_allocator);
23488025087aSFrank Praznik }
23498025087aSFrank Praznik module_init(sony_init);
23508025087aSFrank Praznik module_exit(sony_exit);
2351bd28ce00SJiri Slaby 
2352bd28ce00SJiri Slaby MODULE_LICENSE("GPL");
2353