Blame view

drivers/hid/hid-sony.c 94.1 KB
bd28ce008   Jiri Slaby   HID: move sony qu...
1
  /*
077147a30   Frank Praznik   HID: sony: Update...
2
   *  HID driver for Sony / PS2 / PS3 / PS4 BD devices.
bd28ce008   Jiri Slaby   HID: move sony qu...
3
4
5
6
   *
   *  Copyright (c) 1999 Andreas Gal
   *  Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz>
   *  Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc
bd28ce008   Jiri Slaby   HID: move sony qu...
7
   *  Copyright (c) 2008 Jiri Slaby
078328da5   Jiri Kosina   HID: fold ps3remo...
8
9
   *  Copyright (c) 2012 David Dillow <dave@thedillows.org>
   *  Copyright (c) 2006-2013 Jiri Kosina
f04d51404   Colin Leitner   HID: driver for P...
10
   *  Copyright (c) 2013 Colin Leitner <colin.leitner@gmail.com>
077147a30   Frank Praznik   HID: sony: Update...
11
   *  Copyright (c) 2014 Frank Praznik <frank.praznik@gmail.com>
bd28ce008   Jiri Slaby   HID: move sony qu...
12
13
14
15
16
17
18
19
   */
  
  /*
   * This program is free software; you can redistribute it and/or modify it
   * under the terms of the GNU General Public License as published by the Free
   * Software Foundation; either version 2 of the License, or (at your option)
   * any later version.
   */
ad142b9e4   Frank Praznik   HID: sony: Fix mu...
20
21
  /*
   * NOTE: in order for the Sony PS3 BD Remote Control to be found by
078328da5   Jiri Kosina   HID: fold ps3remo...
22
23
24
25
26
   * a Bluetooth host, the key combination Start+Enter has to be kept pressed
   * for about 7 seconds with the Bluetooth Host Controller in discovering mode.
   *
   * There will be no PIN request from the device.
   */
bd28ce008   Jiri Slaby   HID: move sony qu...
27
28
29
  #include <linux/device.h>
  #include <linux/hid.h>
  #include <linux/module.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
30
  #include <linux/slab.h>
40e32ee6e   Jiri Kosina   HID: sony: fix le...
31
  #include <linux/leds.h>
d902f4724   Frank Praznik   HID: sony: add ba...
32
33
  #include <linux/power_supply.h>
  #include <linux/spinlock.h>
d2d782fcc   Frank Praznik   HID: sony: Preven...
34
  #include <linux/list.h>
8025087ac   Frank Praznik   HID: sony: Initia...
35
  #include <linux/idr.h>
e56062305   Frank Praznik   HID: sony: add ou...
36
  #include <linux/input/mt.h>
bd28ce008   Jiri Slaby   HID: move sony qu...
37
38
  
  #include "hid-ids.h"
6c79c18c9   Frank Praznik   HID: sony: Fix sp...
39
40
41
42
43
  #define VAIO_RDESC_CONSTANT       BIT(0)
  #define SIXAXIS_CONTROLLER_USB    BIT(1)
  #define SIXAXIS_CONTROLLER_BT     BIT(2)
  #define BUZZ_CONTROLLER           BIT(3)
  #define PS3REMOTE                 BIT(4)
8ab1676b6   Frank Praznik   HID: sony: Use se...
44
45
  #define DUALSHOCK4_CONTROLLER_USB BIT(5)
  #define DUALSHOCK4_CONTROLLER_BT  BIT(6)
b3bca326f   Simon Wood   HID: sony: Add qu...
46
47
  #define MOTION_CONTROLLER_USB     BIT(7)
  #define MOTION_CONTROLLER_BT      BIT(8)
4545ee0a7   Simon Wood   HID: hid-sony: Na...
48
49
  #define NAVIGATION_CONTROLLER_USB BIT(9)
  #define NAVIGATION_CONTROLLER_BT  BIT(10)
74500cc85   Scott Moreau   HID: sony: Add ny...
50
  #define SINO_LITE_CONTROLLER      BIT(11)
cc6e0bbb4   Jiri Kosina   HID: Add support ...
51

fee4e2d52   Frank Praznik   HID: sony: Enable...
52
  #define SIXAXIS_CONTROLLER (SIXAXIS_CONTROLLER_USB | SIXAXIS_CONTROLLER_BT)
b3bca326f   Simon Wood   HID: sony: Add qu...
53
  #define MOTION_CONTROLLER (MOTION_CONTROLLER_USB | MOTION_CONTROLLER_BT)
4545ee0a7   Simon Wood   HID: hid-sony: Na...
54
55
  #define NAVIGATION_CONTROLLER (NAVIGATION_CONTROLLER_USB |\
  				NAVIGATION_CONTROLLER_BT)
68330d83c   Frank Praznik   HID: sony: Add co...
56
57
  #define DUALSHOCK4_CONTROLLER (DUALSHOCK4_CONTROLLER_USB |\
  				DUALSHOCK4_CONTROLLER_BT)
fee4e2d52   Frank Praznik   HID: sony: Enable...
58
  #define SONY_LED_SUPPORT (SIXAXIS_CONTROLLER | BUZZ_CONTROLLER |\
4545ee0a7   Simon Wood   HID: hid-sony: Na...
59
60
  				DUALSHOCK4_CONTROLLER | MOTION_CONTROLLER |\
  				NAVIGATION_CONTROLLER)
12e9a6d72   Simon Wood   HID: sony: Add su...
61
  #define SONY_BATTERY_SUPPORT (SIXAXIS_CONTROLLER | DUALSHOCK4_CONTROLLER |\
4545ee0a7   Simon Wood   HID: hid-sony: Na...
62
  				MOTION_CONTROLLER_BT | NAVIGATION_CONTROLLER)
c5e0c1c49   Frank Praznik   HID: sony: Add su...
63
64
  #define SONY_FF_SUPPORT (SIXAXIS_CONTROLLER | DUALSHOCK4_CONTROLLER |\
  				MOTION_CONTROLLER)
60781cf48   Frank Praznik   HID: sony: Add LE...
65
66
  
  #define MAX_LEDS 4
0a286ef27   Sven Eckelmann   HID: sony: Add LE...
67

4c3e82984   Frank Praznik   HID: sony: Correc...
68
69
70
71
72
73
74
  /*
   * The Sixaxis reports both digital and analog values for each button on the
   * controller except for Start, Select and the PS button.  The controller ends
   * up reporting 27 axes which causes them to spill over into the multi-touch
   * axis values.  Additionally, the controller only has 20 actual, physical axes
   * so there are several unused axes in between the used ones.
   */
1adf904e9   Pavel Machek   HID: sony: unders...
75
  static u8 sixaxis_rdesc[] = {
fb705a6dc   Antonio Ospite   HID: sony: Format...
76
  	0x05, 0x01,         /*  Usage Page (Desktop),               */
4c3e82984   Frank Praznik   HID: sony: Correc...
77
  	0x09, 0x04,         /*  Usage (Joystick),                   */
fb705a6dc   Antonio Ospite   HID: sony: Format...
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
  	0xA1, 0x01,         /*  Collection (Application),           */
  	0xA1, 0x02,         /*      Collection (Logical),           */
  	0x85, 0x01,         /*          Report ID (1),              */
  	0x75, 0x08,         /*          Report Size (8),            */
  	0x95, 0x01,         /*          Report Count (1),           */
  	0x15, 0x00,         /*          Logical Minimum (0),        */
  	0x26, 0xFF, 0x00,   /*          Logical Maximum (255),      */
  	0x81, 0x03,         /*          Input (Constant, Variable), */
  	0x75, 0x01,         /*          Report Size (1),            */
  	0x95, 0x13,         /*          Report Count (19),          */
  	0x15, 0x00,         /*          Logical Minimum (0),        */
  	0x25, 0x01,         /*          Logical Maximum (1),        */
  	0x35, 0x00,         /*          Physical Minimum (0),       */
  	0x45, 0x01,         /*          Physical Maximum (1),       */
  	0x05, 0x09,         /*          Usage Page (Button),        */
  	0x19, 0x01,         /*          Usage Minimum (01h),        */
  	0x29, 0x13,         /*          Usage Maximum (13h),        */
  	0x81, 0x02,         /*          Input (Variable),           */
  	0x75, 0x01,         /*          Report Size (1),            */
  	0x95, 0x0D,         /*          Report Count (13),          */
  	0x06, 0x00, 0xFF,   /*          Usage Page (FF00h),         */
  	0x81, 0x03,         /*          Input (Constant, Variable), */
  	0x15, 0x00,         /*          Logical Minimum (0),        */
  	0x26, 0xFF, 0x00,   /*          Logical Maximum (255),      */
  	0x05, 0x01,         /*          Usage Page (Desktop),       */
  	0x09, 0x01,         /*          Usage (Pointer),            */
  	0xA1, 0x00,         /*          Collection (Physical),      */
  	0x75, 0x08,         /*              Report Size (8),        */
  	0x95, 0x04,         /*              Report Count (4),       */
  	0x35, 0x00,         /*              Physical Minimum (0),   */
  	0x46, 0xFF, 0x00,   /*              Physical Maximum (255), */
  	0x09, 0x30,         /*              Usage (X),              */
  	0x09, 0x31,         /*              Usage (Y),              */
  	0x09, 0x32,         /*              Usage (Z),              */
  	0x09, 0x35,         /*              Usage (Rz),             */
  	0x81, 0x02,         /*              Input (Variable),       */
  	0xC0,               /*          End Collection,             */
  	0x05, 0x01,         /*          Usage Page (Desktop),       */
  	0x95, 0x13,         /*          Report Count (19),          */
  	0x09, 0x01,         /*          Usage (Pointer),            */
  	0x81, 0x02,         /*          Input (Variable),           */
  	0x95, 0x0C,         /*          Report Count (12),          */
  	0x81, 0x01,         /*          Input (Constant),           */
  	0x75, 0x10,         /*          Report Size (16),           */
  	0x95, 0x04,         /*          Report Count (4),           */
  	0x26, 0xFF, 0x03,   /*          Logical Maximum (1023),     */
  	0x46, 0xFF, 0x03,   /*          Physical Maximum (1023),    */
  	0x09, 0x01,         /*          Usage (Pointer),            */
  	0x81, 0x02,         /*          Input (Variable),           */
  	0xC0,               /*      End Collection,                 */
  	0xA1, 0x02,         /*      Collection (Logical),           */
  	0x85, 0x02,         /*          Report ID (2),              */
  	0x75, 0x08,         /*          Report Size (8),            */
  	0x95, 0x30,         /*          Report Count (48),          */
  	0x09, 0x01,         /*          Usage (Pointer),            */
  	0xB1, 0x02,         /*          Feature (Variable),         */
  	0xC0,               /*      End Collection,                 */
  	0xA1, 0x02,         /*      Collection (Logical),           */
  	0x85, 0xEE,         /*          Report ID (238),            */
  	0x75, 0x08,         /*          Report Size (8),            */
  	0x95, 0x30,         /*          Report Count (48),          */
  	0x09, 0x01,         /*          Usage (Pointer),            */
  	0xB1, 0x02,         /*          Feature (Variable),         */
  	0xC0,               /*      End Collection,                 */
  	0xA1, 0x02,         /*      Collection (Logical),           */
  	0x85, 0xEF,         /*          Report ID (239),            */
  	0x75, 0x08,         /*          Report Size (8),            */
  	0x95, 0x30,         /*          Report Count (48),          */
  	0x09, 0x01,         /*          Usage (Pointer),            */
  	0xB1, 0x02,         /*          Feature (Variable),         */
  	0xC0,               /*      End Collection,                 */
  	0xC0                /*  End Collection                      */
e57a67da6   Mauro Carvalho Chehab   HID: hid-sony: fi...
150
  };
c5e0c1c49   Frank Praznik   HID: sony: Add su...
151
  /* PS/3 Motion controller */
1adf904e9   Pavel Machek   HID: sony: unders...
152
  static u8 motion_rdesc[] = {
c5e0c1c49   Frank Praznik   HID: sony: Add su...
153
154
155
156
157
  	0x05, 0x01,         /*  Usage Page (Desktop),               */
  	0x09, 0x04,         /*  Usage (Joystick),                   */
  	0xA1, 0x01,         /*  Collection (Application),           */
  	0xA1, 0x02,         /*      Collection (Logical),           */
  	0x85, 0x01,         /*          Report ID (1),              */
c5e0c1c49   Frank Praznik   HID: sony: Add su...
158
  	0x75, 0x01,         /*          Report Size (1),            */
8b2513c31   Simon Wood   HID: sony: PS Mov...
159
  	0x95, 0x15,         /*          Report Count (21),          */
c5e0c1c49   Frank Praznik   HID: sony: Add su...
160
161
162
163
164
165
  	0x15, 0x00,         /*          Logical Minimum (0),        */
  	0x25, 0x01,         /*          Logical Maximum (1),        */
  	0x35, 0x00,         /*          Physical Minimum (0),       */
  	0x45, 0x01,         /*          Physical Maximum (1),       */
  	0x05, 0x09,         /*          Usage Page (Button),        */
  	0x19, 0x01,         /*          Usage Minimum (01h),        */
8b2513c31   Simon Wood   HID: sony: PS Mov...
166
167
168
  	0x29, 0x15,         /*          Usage Maximum (15h),        */
  	0x81, 0x02,         /*          Input (Variable),           * Buttons */
  	0x95, 0x0B,         /*          Report Count (11),          */
c5e0c1c49   Frank Praznik   HID: sony: Add su...
169
  	0x06, 0x00, 0xFF,   /*          Usage Page (FF00h),         */
8b2513c31   Simon Wood   HID: sony: PS Mov...
170
  	0x81, 0x03,         /*          Input (Constant, Variable), * Padding */
c5e0c1c49   Frank Praznik   HID: sony: Add su...
171
172
173
  	0x15, 0x00,         /*          Logical Minimum (0),        */
  	0x26, 0xFF, 0x00,   /*          Logical Maximum (255),      */
  	0x05, 0x01,         /*          Usage Page (Desktop),       */
c5e0c1c49   Frank Praznik   HID: sony: Add su...
174
175
  	0xA1, 0x00,         /*          Collection (Physical),      */
  	0x75, 0x08,         /*              Report Size (8),        */
8b2513c31   Simon Wood   HID: sony: PS Mov...
176
  	0x95, 0x01,         /*              Report Count (1),       */
c5e0c1c49   Frank Praznik   HID: sony: Add su...
177
178
179
  	0x35, 0x00,         /*              Physical Minimum (0),   */
  	0x46, 0xFF, 0x00,   /*              Physical Maximum (255), */
  	0x09, 0x30,         /*              Usage (X),              */
8b2513c31   Simon Wood   HID: sony: PS Mov...
180
  	0x81, 0x02,         /*              Input (Variable),       * Trigger */
c5e0c1c49   Frank Praznik   HID: sony: Add su...
181
  	0xC0,               /*          End Collection,             */
8b2513c31   Simon Wood   HID: sony: PS Mov...
182
183
184
  	0x06, 0x00, 0xFF,   /*          Usage Page (FF00h),         */
  	0x75, 0x08,         /*          Report Size (8),            */
  	0x95, 0x07,         /*          Report Count (7),           * skip 7 bytes */
c5e0c1c49   Frank Praznik   HID: sony: Add su...
185
  	0x81, 0x02,         /*          Input (Variable),           */
8b2513c31   Simon Wood   HID: sony: PS Mov...
186
  	0x05, 0x01,         /*          Usage Page (Desktop),       */
c5e0c1c49   Frank Praznik   HID: sony: Add su...
187
  	0x75, 0x10,         /*          Report Size (16),           */
8b2513c31   Simon Wood   HID: sony: PS Mov...
188
189
190
191
192
193
194
195
196
197
198
  	0x46, 0xFF, 0xFF,   /*          Physical Maximum (65535),   */
  	0x27, 0xFF, 0xFF, 0x00, 0x00, /*      Logical Maximum (65535),    */
  	0x95, 0x03,         /*          Report Count (3),           * 3x Accels */
  	0x09, 0x33,         /*              Usage (rX),             */
  	0x09, 0x34,         /*              Usage (rY),             */
  	0x09, 0x35,         /*              Usage (rZ),             */
  	0x81, 0x02,         /*          Input (Variable),           */
  	0x06, 0x00, 0xFF,   /*          Usage Page (FF00h),         */
  	0x95, 0x03,         /*          Report Count (3),           * Skip Accels 2nd frame */
  	0x81, 0x02,         /*          Input (Variable),           */
  	0x05, 0x01,         /*          Usage Page (Desktop),       */
c5e0c1c49   Frank Praznik   HID: sony: Add su...
199
  	0x09, 0x01,         /*          Usage (Pointer),            */
8b2513c31   Simon Wood   HID: sony: PS Mov...
200
201
202
203
  	0x95, 0x03,         /*          Report Count (3),           * 3x Gyros */
  	0x81, 0x02,         /*          Input (Variable),           */
  	0x06, 0x00, 0xFF,   /*          Usage Page (FF00h),         */
  	0x95, 0x03,         /*          Report Count (3),           * Skip Gyros 2nd frame */
c5e0c1c49   Frank Praznik   HID: sony: Add su...
204
  	0x81, 0x02,         /*          Input (Variable),           */
8b2513c31   Simon Wood   HID: sony: PS Mov...
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
  	0x75, 0x0C,         /*          Report Size (12),           */
  	0x46, 0xFF, 0x0F,   /*          Physical Maximum (4095),    */
  	0x26, 0xFF, 0x0F,   /*          Logical Maximum (4095),     */
  	0x95, 0x04,         /*          Report Count (4),           * Skip Temp and Magnetometers */
  	0x81, 0x02,         /*          Input (Variable),           */
  	0x75, 0x08,         /*          Report Size (8),            */
  	0x46, 0xFF, 0x00,   /*          Physical Maximum (255),     */
  	0x26, 0xFF, 0x00,   /*          Logical Maximum (255),      */
  	0x95, 0x06,         /*          Report Count (6),           * Skip Timestamp and Extension Bytes */
  	0x81, 0x02,         /*          Input (Variable),           */
  	0x75, 0x08,         /*          Report Size (8),            */
  	0x95, 0x30,         /*          Report Count (48),          */
  	0x09, 0x01,         /*          Usage (Pointer),            */
  	0x91, 0x02,         /*          Output (Variable),          */
  	0x75, 0x08,         /*          Report Size (8),            */
  	0x95, 0x30,         /*          Report Count (48),          */
  	0x09, 0x01,         /*          Usage (Pointer),            */
  	0xB1, 0x02,         /*          Feature (Variable),         */
c5e0c1c49   Frank Praznik   HID: sony: Add su...
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
  	0xC0,               /*      End Collection,                 */
  	0xA1, 0x02,         /*      Collection (Logical),           */
  	0x85, 0x02,         /*          Report ID (2),              */
  	0x75, 0x08,         /*          Report Size (8),            */
  	0x95, 0x30,         /*          Report Count (48),          */
  	0x09, 0x01,         /*          Usage (Pointer),            */
  	0xB1, 0x02,         /*          Feature (Variable),         */
  	0xC0,               /*      End Collection,                 */
  	0xA1, 0x02,         /*      Collection (Logical),           */
  	0x85, 0xEE,         /*          Report ID (238),            */
  	0x75, 0x08,         /*          Report Size (8),            */
  	0x95, 0x30,         /*          Report Count (48),          */
  	0x09, 0x01,         /*          Usage (Pointer),            */
  	0xB1, 0x02,         /*          Feature (Variable),         */
  	0xC0,               /*      End Collection,                 */
  	0xA1, 0x02,         /*      Collection (Logical),           */
  	0x85, 0xEF,         /*          Report ID (239),            */
  	0x75, 0x08,         /*          Report Size (8),            */
  	0x95, 0x30,         /*          Report Count (48),          */
  	0x09, 0x01,         /*          Usage (Pointer),            */
  	0xB1, 0x02,         /*          Feature (Variable),         */
  	0xC0,               /*      End Collection,                 */
  	0xC0                /*  End Collection                      */
  };
b2723eb73   Simon Wood   HID: hid-sony: Fi...
247
  /* PS/3 Navigation controller */
1adf904e9   Pavel Machek   HID: sony: unders...
248
  static u8 navigation_rdesc[] = {
b2723eb73   Simon Wood   HID: hid-sony: Fi...
249
  	0x05, 0x01,         /*  Usage Page (Desktop),               */
d542176f9   Antonio Ospite   HID: sony: fix a ...
250
  	0x09, 0x04,         /*  Usage (Joystick),                   */
b2723eb73   Simon Wood   HID: hid-sony: Fi...
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
  	0xA1, 0x01,         /*  Collection (Application),           */
  	0xA1, 0x02,         /*      Collection (Logical),           */
  	0x85, 0x01,         /*          Report ID (1),              */
  	0x75, 0x08,         /*          Report Size (8),            */
  	0x95, 0x01,         /*          Report Count (1),           */
  	0x15, 0x00,         /*          Logical Minimum (0),        */
  	0x26, 0xFF, 0x00,   /*          Logical Maximum (255),      */
  	0x81, 0x03,         /*          Input (Constant, Variable), */
  	0x75, 0x01,         /*          Report Size (1),            */
  	0x95, 0x13,         /*          Report Count (19),          */
  	0x15, 0x00,         /*          Logical Minimum (0),        */
  	0x25, 0x01,         /*          Logical Maximum (1),        */
  	0x35, 0x00,         /*          Physical Minimum (0),       */
  	0x45, 0x01,         /*          Physical Maximum (1),       */
  	0x05, 0x09,         /*          Usage Page (Button),        */
  	0x19, 0x01,         /*          Usage Minimum (01h),        */
  	0x29, 0x13,         /*          Usage Maximum (13h),        */
  	0x81, 0x02,         /*          Input (Variable),           */
  	0x75, 0x01,         /*          Report Size (1),            */
  	0x95, 0x0D,         /*          Report Count (13),          */
  	0x06, 0x00, 0xFF,   /*          Usage Page (FF00h),         */
  	0x81, 0x03,         /*          Input (Constant, Variable), */
  	0x15, 0x00,         /*          Logical Minimum (0),        */
  	0x26, 0xFF, 0x00,   /*          Logical Maximum (255),      */
  	0x05, 0x01,         /*          Usage Page (Desktop),       */
  	0x09, 0x01,         /*          Usage (Pointer),            */
  	0xA1, 0x00,         /*          Collection (Physical),      */
  	0x75, 0x08,         /*              Report Size (8),        */
  	0x95, 0x02,         /*              Report Count (2),       */
  	0x35, 0x00,         /*              Physical Minimum (0),   */
  	0x46, 0xFF, 0x00,   /*              Physical Maximum (255), */
  	0x09, 0x30,         /*              Usage (X),              */
  	0x09, 0x31,         /*              Usage (Y),              */
  	0x81, 0x02,         /*              Input (Variable),       */
  	0xC0,               /*          End Collection,             */
  	0x06, 0x00, 0xFF,   /*          Usage Page (FF00h),         */
  	0x95, 0x06,         /*          Report Count (6),           */
  	0x81, 0x03,         /*          Input (Constant, Variable), */
  	0x05, 0x01,         /*          Usage Page (Desktop),       */
  	0x75, 0x08,         /*          Report Size (8),            */
  	0x95, 0x05,         /*          Report Count (5),           */
  	0x09, 0x01,         /*          Usage (Pointer),            */
  	0x81, 0x02,         /*          Input (Variable),           */
  	0x06, 0x00, 0xFF,   /*          Usage Page (FF00h),         */
2259b5bba   Simon Wood   HID: sony: Naviga...
295
296
297
298
299
300
301
302
  	0x95, 0x01,         /*          Report Count (1),           */
  	0x81, 0x02,         /*          Input (Variable),           */
  	0x05, 0x01,         /*          Usage Page (Desktop),       */
  	0x95, 0x01,         /*          Report Count (1),           */
  	0x09, 0x01,         /*          Usage (Pointer),            */
  	0x81, 0x02,         /*          Input (Variable),           */
  	0x06, 0x00, 0xFF,   /*          Usage Page (FF00h),         */
  	0x95, 0x1E,         /*          Report Count (24),          */
b2723eb73   Simon Wood   HID: hid-sony: Fi...
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
  	0x81, 0x02,         /*          Input (Variable),           */
  	0x75, 0x08,         /*          Report Size (8),            */
  	0x95, 0x30,         /*          Report Count (48),          */
  	0x09, 0x01,         /*          Usage (Pointer),            */
  	0x91, 0x02,         /*          Output (Variable),          */
  	0x75, 0x08,         /*          Report Size (8),            */
  	0x95, 0x30,         /*          Report Count (48),          */
  	0x09, 0x01,         /*          Usage (Pointer),            */
  	0xB1, 0x02,         /*          Feature (Variable),         */
  	0xC0,               /*      End Collection,                 */
  	0xA1, 0x02,         /*      Collection (Logical),           */
  	0x85, 0x02,         /*          Report ID (2),              */
  	0x75, 0x08,         /*          Report Size (8),            */
  	0x95, 0x30,         /*          Report Count (48),          */
  	0x09, 0x01,         /*          Usage (Pointer),            */
  	0xB1, 0x02,         /*          Feature (Variable),         */
  	0xC0,               /*      End Collection,                 */
  	0xA1, 0x02,         /*      Collection (Logical),           */
  	0x85, 0xEE,         /*          Report ID (238),            */
  	0x75, 0x08,         /*          Report Size (8),            */
  	0x95, 0x30,         /*          Report Count (48),          */
  	0x09, 0x01,         /*          Usage (Pointer),            */
  	0xB1, 0x02,         /*          Feature (Variable),         */
  	0xC0,               /*      End Collection,                 */
  	0xA1, 0x02,         /*      Collection (Logical),           */
  	0x85, 0xEF,         /*          Report ID (239),            */
  	0x75, 0x08,         /*          Report Size (8),            */
  	0x95, 0x30,         /*          Report Count (48),          */
  	0x09, 0x01,         /*          Usage (Pointer),            */
  	0xB1, 0x02,         /*          Feature (Variable),         */
  	0xC0,               /*      End Collection,                 */
  	0xC0                /*  End Collection                      */
  };
c5e0c1c49   Frank Praznik   HID: sony: Add su...
336

ad142b9e4   Frank Praznik   HID: sony: Fix mu...
337
338
  /*
   * The default descriptor doesn't provide mapping for the accelerometers
58d7027b7   Frank Praznik   HID: sony: Add an...
339
340
341
342
   * or orientation sensors.  This fixed descriptor maps the accelerometers
   * to usage values 0x40, 0x41 and 0x42 and maps the orientation sensors
   * to usage values 0x43, 0x44 and 0x45.
   */
ed19d8cf2   Frank Praznik   HID: sony: Map gy...
343
  static u8 dualshock4_usb_rdesc[] = {
58d7027b7   Frank Praznik   HID: sony: Add an...
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
  	0x05, 0x01,         /*  Usage Page (Desktop),               */
  	0x09, 0x05,         /*  Usage (Gamepad),                    */
  	0xA1, 0x01,         /*  Collection (Application),           */
  	0x85, 0x01,         /*      Report ID (1),                  */
  	0x09, 0x30,         /*      Usage (X),                      */
  	0x09, 0x31,         /*      Usage (Y),                      */
  	0x09, 0x32,         /*      Usage (Z),                      */
  	0x09, 0x35,         /*      Usage (Rz),                     */
  	0x15, 0x00,         /*      Logical Minimum (0),            */
  	0x26, 0xFF, 0x00,   /*      Logical Maximum (255),          */
  	0x75, 0x08,         /*      Report Size (8),                */
  	0x95, 0x04,         /*      Report Count (4),               */
  	0x81, 0x02,         /*      Input (Variable),               */
  	0x09, 0x39,         /*      Usage (Hat Switch),             */
  	0x15, 0x00,         /*      Logical Minimum (0),            */
  	0x25, 0x07,         /*      Logical Maximum (7),            */
  	0x35, 0x00,         /*      Physical Minimum (0),           */
  	0x46, 0x3B, 0x01,   /*      Physical Maximum (315),         */
  	0x65, 0x14,         /*      Unit (Degrees),                 */
  	0x75, 0x04,         /*      Report Size (4),                */
  	0x95, 0x01,         /*      Report Count (1),               */
  	0x81, 0x42,         /*      Input (Variable, Null State),   */
  	0x65, 0x00,         /*      Unit,                           */
  	0x05, 0x09,         /*      Usage Page (Button),            */
  	0x19, 0x01,         /*      Usage Minimum (01h),            */
  	0x29, 0x0E,         /*      Usage Maximum (0Eh),            */
  	0x15, 0x00,         /*      Logical Minimum (0),            */
  	0x25, 0x01,         /*      Logical Maximum (1),            */
  	0x75, 0x01,         /*      Report Size (1),                */
  	0x95, 0x0E,         /*      Report Count (14),              */
  	0x81, 0x02,         /*      Input (Variable),               */
  	0x06, 0x00, 0xFF,   /*      Usage Page (FF00h),             */
  	0x09, 0x20,         /*      Usage (20h),                    */
  	0x75, 0x06,         /*      Report Size (6),                */
  	0x95, 0x01,         /*      Report Count (1),               */
  	0x15, 0x00,         /*      Logical Minimum (0),            */
fb291cbd3   Frank Praznik   HID: sony: Correc...
380
  	0x25, 0x3F,         /*      Logical Maximum (63),           */
58d7027b7   Frank Praznik   HID: sony: Add an...
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
  	0x81, 0x02,         /*      Input (Variable),               */
  	0x05, 0x01,         /*      Usage Page (Desktop),           */
  	0x09, 0x33,         /*      Usage (Rx),                     */
  	0x09, 0x34,         /*      Usage (Ry),                     */
  	0x15, 0x00,         /*      Logical Minimum (0),            */
  	0x26, 0xFF, 0x00,   /*      Logical Maximum (255),          */
  	0x75, 0x08,         /*      Report Size (8),                */
  	0x95, 0x02,         /*      Report Count (2),               */
  	0x81, 0x02,         /*      Input (Variable),               */
  	0x06, 0x00, 0xFF,   /*      Usage Page (FF00h),             */
  	0x09, 0x21,         /*      Usage (21h),                    */
  	0x95, 0x03,         /*      Report Count (3),               */
  	0x81, 0x02,         /*      Input (Variable),               */
  	0x05, 0x01,         /*      Usage Page (Desktop),           */
  	0x19, 0x40,         /*      Usage Minimum (40h),            */
  	0x29, 0x42,         /*      Usage Maximum (42h),            */
  	0x16, 0x00, 0x80,   /*      Logical Minimum (-32768),       */
  	0x26, 0x00, 0x7F,   /*      Logical Maximum (32767),        */
  	0x75, 0x10,         /*      Report Size (16),               */
  	0x95, 0x03,         /*      Report Count (3),               */
  	0x81, 0x02,         /*      Input (Variable),               */
  	0x19, 0x43,         /*      Usage Minimum (43h),            */
  	0x29, 0x45,         /*      Usage Maximum (45h),            */
fb291cbd3   Frank Praznik   HID: sony: Correc...
404
405
  	0x16, 0x00, 0xE0,   /*      Logical Minimum (-8192),        */
  	0x26, 0xFF, 0x1F,   /*      Logical Maximum (8191),         */
58d7027b7   Frank Praznik   HID: sony: Add an...
406
407
408
409
410
  	0x95, 0x03,         /*      Report Count (3),               */
  	0x81, 0x02,         /*      Input (Variable),               */
  	0x06, 0x00, 0xFF,   /*      Usage Page (FF00h),             */
  	0x09, 0x21,         /*      Usage (21h),                    */
  	0x15, 0x00,         /*      Logical Minimum (0),            */
fb291cbd3   Frank Praznik   HID: sony: Correc...
411
  	0x26, 0xFF, 0x00,   /*      Logical Maximum (255),          */
58d7027b7   Frank Praznik   HID: sony: Add an...
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
  	0x75, 0x08,         /*      Report Size (8),                */
  	0x95, 0x27,         /*      Report Count (39),              */
  	0x81, 0x02,         /*      Input (Variable),               */
  	0x85, 0x05,         /*      Report ID (5),                  */
  	0x09, 0x22,         /*      Usage (22h),                    */
  	0x95, 0x1F,         /*      Report Count (31),              */
  	0x91, 0x02,         /*      Output (Variable),              */
  	0x85, 0x04,         /*      Report ID (4),                  */
  	0x09, 0x23,         /*      Usage (23h),                    */
  	0x95, 0x24,         /*      Report Count (36),              */
  	0xB1, 0x02,         /*      Feature (Variable),             */
  	0x85, 0x02,         /*      Report ID (2),                  */
  	0x09, 0x24,         /*      Usage (24h),                    */
  	0x95, 0x24,         /*      Report Count (36),              */
  	0xB1, 0x02,         /*      Feature (Variable),             */
  	0x85, 0x08,         /*      Report ID (8),                  */
  	0x09, 0x25,         /*      Usage (25h),                    */
  	0x95, 0x03,         /*      Report Count (3),               */
  	0xB1, 0x02,         /*      Feature (Variable),             */
  	0x85, 0x10,         /*      Report ID (16),                 */
  	0x09, 0x26,         /*      Usage (26h),                    */
  	0x95, 0x04,         /*      Report Count (4),               */
  	0xB1, 0x02,         /*      Feature (Variable),             */
  	0x85, 0x11,         /*      Report ID (17),                 */
  	0x09, 0x27,         /*      Usage (27h),                    */
  	0x95, 0x02,         /*      Report Count (2),               */
  	0xB1, 0x02,         /*      Feature (Variable),             */
  	0x85, 0x12,         /*      Report ID (18),                 */
  	0x06, 0x02, 0xFF,   /*      Usage Page (FF02h),             */
  	0x09, 0x21,         /*      Usage (21h),                    */
  	0x95, 0x0F,         /*      Report Count (15),              */
  	0xB1, 0x02,         /*      Feature (Variable),             */
  	0x85, 0x13,         /*      Report ID (19),                 */
  	0x09, 0x22,         /*      Usage (22h),                    */
  	0x95, 0x16,         /*      Report Count (22),              */
  	0xB1, 0x02,         /*      Feature (Variable),             */
  	0x85, 0x14,         /*      Report ID (20),                 */
  	0x06, 0x05, 0xFF,   /*      Usage Page (FF05h),             */
  	0x09, 0x20,         /*      Usage (20h),                    */
  	0x95, 0x10,         /*      Report Count (16),              */
  	0xB1, 0x02,         /*      Feature (Variable),             */
  	0x85, 0x15,         /*      Report ID (21),                 */
  	0x09, 0x21,         /*      Usage (21h),                    */
  	0x95, 0x2C,         /*      Report Count (44),              */
  	0xB1, 0x02,         /*      Feature (Variable),             */
  	0x06, 0x80, 0xFF,   /*      Usage Page (FF80h),             */
  	0x85, 0x80,         /*      Report ID (128),                */
  	0x09, 0x20,         /*      Usage (20h),                    */
  	0x95, 0x06,         /*      Report Count (6),               */
  	0xB1, 0x02,         /*      Feature (Variable),             */
  	0x85, 0x81,         /*      Report ID (129),                */
  	0x09, 0x21,         /*      Usage (21h),                    */
  	0x95, 0x06,         /*      Report Count (6),               */
  	0xB1, 0x02,         /*      Feature (Variable),             */
  	0x85, 0x82,         /*      Report ID (130),                */
  	0x09, 0x22,         /*      Usage (22h),                    */
  	0x95, 0x05,         /*      Report Count (5),               */
  	0xB1, 0x02,         /*      Feature (Variable),             */
  	0x85, 0x83,         /*      Report ID (131),                */
  	0x09, 0x23,         /*      Usage (23h),                    */
  	0x95, 0x01,         /*      Report Count (1),               */
  	0xB1, 0x02,         /*      Feature (Variable),             */
  	0x85, 0x84,         /*      Report ID (132),                */
  	0x09, 0x24,         /*      Usage (24h),                    */
  	0x95, 0x04,         /*      Report Count (4),               */
  	0xB1, 0x02,         /*      Feature (Variable),             */
  	0x85, 0x85,         /*      Report ID (133),                */
  	0x09, 0x25,         /*      Usage (25h),                    */
  	0x95, 0x06,         /*      Report Count (6),               */
  	0xB1, 0x02,         /*      Feature (Variable),             */
  	0x85, 0x86,         /*      Report ID (134),                */
  	0x09, 0x26,         /*      Usage (26h),                    */
  	0x95, 0x06,         /*      Report Count (6),               */
  	0xB1, 0x02,         /*      Feature (Variable),             */
  	0x85, 0x87,         /*      Report ID (135),                */
  	0x09, 0x27,         /*      Usage (27h),                    */
  	0x95, 0x23,         /*      Report Count (35),              */
  	0xB1, 0x02,         /*      Feature (Variable),             */
  	0x85, 0x88,         /*      Report ID (136),                */
  	0x09, 0x28,         /*      Usage (28h),                    */
  	0x95, 0x22,         /*      Report Count (34),              */
  	0xB1, 0x02,         /*      Feature (Variable),             */
  	0x85, 0x89,         /*      Report ID (137),                */
  	0x09, 0x29,         /*      Usage (29h),                    */
  	0x95, 0x02,         /*      Report Count (2),               */
  	0xB1, 0x02,         /*      Feature (Variable),             */
  	0x85, 0x90,         /*      Report ID (144),                */
  	0x09, 0x30,         /*      Usage (30h),                    */
  	0x95, 0x05,         /*      Report Count (5),               */
  	0xB1, 0x02,         /*      Feature (Variable),             */
  	0x85, 0x91,         /*      Report ID (145),                */
  	0x09, 0x31,         /*      Usage (31h),                    */
  	0x95, 0x03,         /*      Report Count (3),               */
  	0xB1, 0x02,         /*      Feature (Variable),             */
  	0x85, 0x92,         /*      Report ID (146),                */
  	0x09, 0x32,         /*      Usage (32h),                    */
  	0x95, 0x03,         /*      Report Count (3),               */
  	0xB1, 0x02,         /*      Feature (Variable),             */
  	0x85, 0x93,         /*      Report ID (147),                */
  	0x09, 0x33,         /*      Usage (33h),                    */
  	0x95, 0x0C,         /*      Report Count (12),              */
  	0xB1, 0x02,         /*      Feature (Variable),             */
  	0x85, 0xA0,         /*      Report ID (160),                */
  	0x09, 0x40,         /*      Usage (40h),                    */
  	0x95, 0x06,         /*      Report Count (6),               */
  	0xB1, 0x02,         /*      Feature (Variable),             */
  	0x85, 0xA1,         /*      Report ID (161),                */
  	0x09, 0x41,         /*      Usage (41h),                    */
  	0x95, 0x01,         /*      Report Count (1),               */
  	0xB1, 0x02,         /*      Feature (Variable),             */
  	0x85, 0xA2,         /*      Report ID (162),                */
  	0x09, 0x42,         /*      Usage (42h),                    */
  	0x95, 0x01,         /*      Report Count (1),               */
  	0xB1, 0x02,         /*      Feature (Variable),             */
  	0x85, 0xA3,         /*      Report ID (163),                */
  	0x09, 0x43,         /*      Usage (43h),                    */
  	0x95, 0x30,         /*      Report Count (48),              */
  	0xB1, 0x02,         /*      Feature (Variable),             */
  	0x85, 0xA4,         /*      Report ID (164),                */
  	0x09, 0x44,         /*      Usage (44h),                    */
  	0x95, 0x0D,         /*      Report Count (13),              */
  	0xB1, 0x02,         /*      Feature (Variable),             */
  	0x85, 0xA5,         /*      Report ID (165),                */
  	0x09, 0x45,         /*      Usage (45h),                    */
  	0x95, 0x15,         /*      Report Count (21),              */
  	0xB1, 0x02,         /*      Feature (Variable),             */
  	0x85, 0xA6,         /*      Report ID (166),                */
  	0x09, 0x46,         /*      Usage (46h),                    */
  	0x95, 0x15,         /*      Report Count (21),              */
  	0xB1, 0x02,         /*      Feature (Variable),             */
  	0x85, 0xF0,         /*      Report ID (240),                */
  	0x09, 0x47,         /*      Usage (47h),                    */
  	0x95, 0x3F,         /*      Report Count (63),              */
  	0xB1, 0x02,         /*      Feature (Variable),             */
  	0x85, 0xF1,         /*      Report ID (241),                */
  	0x09, 0x48,         /*      Usage (48h),                    */
  	0x95, 0x3F,         /*      Report Count (63),              */
  	0xB1, 0x02,         /*      Feature (Variable),             */
  	0x85, 0xF2,         /*      Report ID (242),                */
  	0x09, 0x49,         /*      Usage (49h),                    */
  	0x95, 0x0F,         /*      Report Count (15),              */
  	0xB1, 0x02,         /*      Feature (Variable),             */
  	0x85, 0xA7,         /*      Report ID (167),                */
  	0x09, 0x4A,         /*      Usage (4Ah),                    */
  	0x95, 0x01,         /*      Report Count (1),               */
  	0xB1, 0x02,         /*      Feature (Variable),             */
  	0x85, 0xA8,         /*      Report ID (168),                */
  	0x09, 0x4B,         /*      Usage (4Bh),                    */
  	0x95, 0x01,         /*      Report Count (1),               */
  	0xB1, 0x02,         /*      Feature (Variable),             */
  	0x85, 0xA9,         /*      Report ID (169),                */
  	0x09, 0x4C,         /*      Usage (4Ch),                    */
  	0x95, 0x08,         /*      Report Count (8),               */
  	0xB1, 0x02,         /*      Feature (Variable),             */
  	0x85, 0xAA,         /*      Report ID (170),                */
  	0x09, 0x4E,         /*      Usage (4Eh),                    */
  	0x95, 0x01,         /*      Report Count (1),               */
  	0xB1, 0x02,         /*      Feature (Variable),             */
  	0x85, 0xAB,         /*      Report ID (171),                */
  	0x09, 0x4F,         /*      Usage (4Fh),                    */
  	0x95, 0x39,         /*      Report Count (57),              */
  	0xB1, 0x02,         /*      Feature (Variable),             */
  	0x85, 0xAC,         /*      Report ID (172),                */
  	0x09, 0x50,         /*      Usage (50h),                    */
  	0x95, 0x39,         /*      Report Count (57),              */
  	0xB1, 0x02,         /*      Feature (Variable),             */
  	0x85, 0xAD,         /*      Report ID (173),                */
  	0x09, 0x51,         /*      Usage (51h),                    */
  	0x95, 0x0B,         /*      Report Count (11),              */
  	0xB1, 0x02,         /*      Feature (Variable),             */
  	0x85, 0xAE,         /*      Report ID (174),                */
  	0x09, 0x52,         /*      Usage (52h),                    */
  	0x95, 0x01,         /*      Report Count (1),               */
  	0xB1, 0x02,         /*      Feature (Variable),             */
  	0x85, 0xAF,         /*      Report ID (175),                */
  	0x09, 0x53,         /*      Usage (53h),                    */
  	0x95, 0x02,         /*      Report Count (2),               */
  	0xB1, 0x02,         /*      Feature (Variable),             */
  	0x85, 0xB0,         /*      Report ID (176),                */
  	0x09, 0x54,         /*      Usage (54h),                    */
  	0x95, 0x3F,         /*      Report Count (63),              */
  	0xB1, 0x02,         /*      Feature (Variable),             */
  	0xC0                /*  End Collection                      */
ed19d8cf2   Frank Praznik   HID: sony: Map gy...
595
  };
ad142b9e4   Frank Praznik   HID: sony: Fix mu...
596
597
  /*
   * The default behavior of the Dualshock 4 is to send reports using report
077147a30   Frank Praznik   HID: sony: Update...
598
599
600
   * type 1 when running over Bluetooth. However, when feature report 2 is
   * requested during the controller initialization it starts sending input
   * reports in report 17.  Since report 17 is undefined in the default HID
d829674d2   Frank Praznik   HID: sony: Add mo...
601
   * descriptor the button and axis definitions must be moved to report 17 or
077147a30   Frank Praznik   HID: sony: Update...
602
   * the HID layer won't process the received input.
d829674d2   Frank Praznik   HID: sony: Add mo...
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
   */
  static u8 dualshock4_bt_rdesc[] = {
  	0x05, 0x01,         /*  Usage Page (Desktop),               */
  	0x09, 0x05,         /*  Usage (Gamepad),                    */
  	0xA1, 0x01,         /*  Collection (Application),           */
  	0x85, 0x01,         /*      Report ID (1),                  */
  	0x75, 0x08,         /*      Report Size (8),                */
  	0x95, 0x0A,         /*      Report Count (9),               */
  	0x81, 0x02,         /*      Input (Variable),               */
  	0x06, 0x04, 0xFF,   /*      Usage Page (FF04h),             */
  	0x85, 0x02,         /*      Report ID (2),                  */
  	0x09, 0x24,         /*      Usage (24h),                    */
  	0x95, 0x24,         /*      Report Count (36),              */
  	0xB1, 0x02,         /*      Feature (Variable),             */
  	0x85, 0xA3,         /*      Report ID (163),                */
  	0x09, 0x25,         /*      Usage (25h),                    */
  	0x95, 0x30,         /*      Report Count (48),              */
  	0xB1, 0x02,         /*      Feature (Variable),             */
  	0x85, 0x05,         /*      Report ID (5),                  */
  	0x09, 0x26,         /*      Usage (26h),                    */
  	0x95, 0x28,         /*      Report Count (40),              */
  	0xB1, 0x02,         /*      Feature (Variable),             */
  	0x85, 0x06,         /*      Report ID (6),                  */
  	0x09, 0x27,         /*      Usage (27h),                    */
  	0x95, 0x34,         /*      Report Count (52),              */
  	0xB1, 0x02,         /*      Feature (Variable),             */
  	0x85, 0x07,         /*      Report ID (7),                  */
  	0x09, 0x28,         /*      Usage (28h),                    */
  	0x95, 0x30,         /*      Report Count (48),              */
  	0xB1, 0x02,         /*      Feature (Variable),             */
  	0x85, 0x08,         /*      Report ID (8),                  */
  	0x09, 0x29,         /*      Usage (29h),                    */
  	0x95, 0x2F,         /*      Report Count (47),              */
  	0xB1, 0x02,         /*      Feature (Variable),             */
  	0x06, 0x03, 0xFF,   /*      Usage Page (FF03h),             */
  	0x85, 0x03,         /*      Report ID (3),                  */
  	0x09, 0x21,         /*      Usage (21h),                    */
  	0x95, 0x26,         /*      Report Count (38),              */
  	0xB1, 0x02,         /*      Feature (Variable),             */
  	0x85, 0x04,         /*      Report ID (4),                  */
  	0x09, 0x22,         /*      Usage (22h),                    */
  	0x95, 0x2E,         /*      Report Count (46),              */
  	0xB1, 0x02,         /*      Feature (Variable),             */
  	0x85, 0xF0,         /*      Report ID (240),                */
  	0x09, 0x47,         /*      Usage (47h),                    */
  	0x95, 0x3F,         /*      Report Count (63),              */
  	0xB1, 0x02,         /*      Feature (Variable),             */
  	0x85, 0xF1,         /*      Report ID (241),                */
  	0x09, 0x48,         /*      Usage (48h),                    */
  	0x95, 0x3F,         /*      Report Count (63),              */
  	0xB1, 0x02,         /*      Feature (Variable),             */
  	0x85, 0xF2,         /*      Report ID (242),                */
  	0x09, 0x49,         /*      Usage (49h),                    */
  	0x95, 0x0F,         /*      Report Count (15),              */
  	0xB1, 0x02,         /*      Feature (Variable),             */
  	0x85, 0x11,         /*      Report ID (17),                 */
  	0x06, 0x00, 0xFF,   /*      Usage Page (FF00h),             */
  	0x09, 0x20,         /*      Usage (20h),                    */
  	0x95, 0x02,         /*      Report Count (2),               */
  	0x81, 0x02,         /*      Input (Variable),               */
  	0x05, 0x01,         /*      Usage Page (Desktop),           */
  	0x09, 0x30,         /*      Usage (X),                      */
  	0x09, 0x31,         /*      Usage (Y),                      */
  	0x09, 0x32,         /*      Usage (Z),                      */
  	0x09, 0x35,         /*      Usage (Rz),                     */
  	0x15, 0x00,         /*      Logical Minimum (0),            */
  	0x26, 0xFF, 0x00,   /*      Logical Maximum (255),          */
  	0x75, 0x08,         /*      Report Size (8),                */
  	0x95, 0x04,         /*      Report Count (4),               */
  	0x81, 0x02,         /*      Input (Variable),               */
  	0x09, 0x39,         /*      Usage (Hat Switch),             */
  	0x15, 0x00,         /*      Logical Minimum (0),            */
  	0x25, 0x07,         /*      Logical Maximum (7),            */
  	0x75, 0x04,         /*      Report Size (4),                */
  	0x95, 0x01,         /*      Report Count (1),               */
  	0x81, 0x42,         /*      Input (Variable, Null State),   */
  	0x05, 0x09,         /*      Usage Page (Button),            */
  	0x19, 0x01,         /*      Usage Minimum (01h),            */
  	0x29, 0x0E,         /*      Usage Maximum (0Eh),            */
  	0x15, 0x00,         /*      Logical Minimum (0),            */
  	0x25, 0x01,         /*      Logical Maximum (1),            */
  	0x75, 0x01,         /*      Report Size (1),                */
  	0x95, 0x0E,         /*      Report Count (14),              */
  	0x81, 0x02,         /*      Input (Variable),               */
  	0x75, 0x06,         /*      Report Size (6),                */
  	0x95, 0x01,         /*      Report Count (1),               */
  	0x81, 0x01,         /*      Input (Constant),               */
  	0x05, 0x01,         /*      Usage Page (Desktop),           */
  	0x09, 0x33,         /*      Usage (Rx),                     */
  	0x09, 0x34,         /*      Usage (Ry),                     */
  	0x15, 0x00,         /*      Logical Minimum (0),            */
  	0x26, 0xFF, 0x00,   /*      Logical Maximum (255),          */
  	0x75, 0x08,         /*      Report Size (8),                */
  	0x95, 0x02,         /*      Report Count (2),               */
  	0x81, 0x02,         /*      Input (Variable),               */
  	0x06, 0x00, 0xFF,   /*      Usage Page (FF00h),             */
  	0x09, 0x20,         /*      Usage (20h),                    */
  	0x95, 0x03,         /*      Report Count (3),               */
  	0x81, 0x02,         /*      Input (Variable),               */
  	0x05, 0x01,         /*      Usage Page (Desktop),           */
  	0x19, 0x40,         /*      Usage Minimum (40h),            */
  	0x29, 0x42,         /*      Usage Maximum (42h),            */
  	0x16, 0x00, 0x80,   /*      Logical Minimum (-32768),       */
  	0x26, 0x00, 0x7F,   /*      Logical Maximum (32767),        */
  	0x75, 0x10,         /*      Report Size (16),               */
  	0x95, 0x03,         /*      Report Count (3),               */
  	0x81, 0x02,         /*      Input (Variable),               */
  	0x19, 0x43,         /*      Usage Minimum (43h),            */
  	0x29, 0x45,         /*      Usage Maximum (45h),            */
fb291cbd3   Frank Praznik   HID: sony: Correc...
712
713
  	0x16, 0x00, 0xE0,   /*      Logical Minimum (-8192),        */
  	0x26, 0xFF, 0x1F,   /*      Logical Maximum (8191),         */
d829674d2   Frank Praznik   HID: sony: Add mo...
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
  	0x95, 0x03,         /*      Report Count (3),               */
  	0x81, 0x02,         /*      Input (Variable),               */
  	0x06, 0x00, 0xFF,   /*      Usage Page (FF00h),             */
  	0x09, 0x20,         /*      Usage (20h),                    */
  	0x15, 0x00,         /*      Logical Minimum (0),            */
  	0x26, 0xFF, 0x00,   /*      Logical Maximum (255),          */
  	0x75, 0x08,         /*      Report Size (8),                */
  	0x95, 0x31,         /*      Report Count (51),              */
  	0x81, 0x02,         /*      Input (Variable),               */
  	0x09, 0x21,         /*      Usage (21h),                    */
  	0x75, 0x08,         /*      Report Size (8),                */
  	0x95, 0x4D,         /*      Report Count (77),              */
  	0x91, 0x02,         /*      Output (Variable),              */
  	0x85, 0x12,         /*      Report ID (18),                 */
  	0x09, 0x22,         /*      Usage (22h),                    */
  	0x95, 0x8D,         /*      Report Count (141),             */
  	0x81, 0x02,         /*      Input (Variable),               */
  	0x09, 0x23,         /*      Usage (23h),                    */
  	0x91, 0x02,         /*      Output (Variable),              */
  	0x85, 0x13,         /*      Report ID (19),                 */
  	0x09, 0x24,         /*      Usage (24h),                    */
  	0x95, 0xCD,         /*      Report Count (205),             */
  	0x81, 0x02,         /*      Input (Variable),               */
  	0x09, 0x25,         /*      Usage (25h),                    */
  	0x91, 0x02,         /*      Output (Variable),              */
  	0x85, 0x14,         /*      Report ID (20),                 */
  	0x09, 0x26,         /*      Usage (26h),                    */
  	0x96, 0x0D, 0x01,   /*      Report Count (269),             */
  	0x81, 0x02,         /*      Input (Variable),               */
  	0x09, 0x27,         /*      Usage (27h),                    */
  	0x91, 0x02,         /*      Output (Variable),              */
  	0x85, 0x15,         /*      Report ID (21),                 */
  	0x09, 0x28,         /*      Usage (28h),                    */
  	0x96, 0x4D, 0x01,   /*      Report Count (333),             */
  	0x81, 0x02,         /*      Input (Variable),               */
  	0x09, 0x29,         /*      Usage (29h),                    */
  	0x91, 0x02,         /*      Output (Variable),              */
  	0x85, 0x16,         /*      Report ID (22),                 */
  	0x09, 0x2A,         /*      Usage (2Ah),                    */
  	0x96, 0x8D, 0x01,   /*      Report Count (397),             */
  	0x81, 0x02,         /*      Input (Variable),               */
  	0x09, 0x2B,         /*      Usage (2Bh),                    */
  	0x91, 0x02,         /*      Output (Variable),              */
  	0x85, 0x17,         /*      Report ID (23),                 */
  	0x09, 0x2C,         /*      Usage (2Ch),                    */
  	0x96, 0xCD, 0x01,   /*      Report Count (461),             */
  	0x81, 0x02,         /*      Input (Variable),               */
  	0x09, 0x2D,         /*      Usage (2Dh),                    */
  	0x91, 0x02,         /*      Output (Variable),              */
  	0x85, 0x18,         /*      Report ID (24),                 */
  	0x09, 0x2E,         /*      Usage (2Eh),                    */
  	0x96, 0x0D, 0x02,   /*      Report Count (525),             */
  	0x81, 0x02,         /*      Input (Variable),               */
  	0x09, 0x2F,         /*      Usage (2Fh),                    */
  	0x91, 0x02,         /*      Output (Variable),              */
  	0x85, 0x19,         /*      Report ID (25),                 */
  	0x09, 0x30,         /*      Usage (30h),                    */
  	0x96, 0x22, 0x02,   /*      Report Count (546),             */
  	0x81, 0x02,         /*      Input (Variable),               */
  	0x09, 0x31,         /*      Usage (31h),                    */
  	0x91, 0x02,         /*      Output (Variable),              */
  	0x06, 0x80, 0xFF,   /*      Usage Page (FF80h),             */
  	0x85, 0x82,         /*      Report ID (130),                */
  	0x09, 0x22,         /*      Usage (22h),                    */
  	0x95, 0x3F,         /*      Report Count (63),              */
  	0xB1, 0x02,         /*      Feature (Variable),             */
  	0x85, 0x83,         /*      Report ID (131),                */
  	0x09, 0x23,         /*      Usage (23h),                    */
  	0xB1, 0x02,         /*      Feature (Variable),             */
  	0x85, 0x84,         /*      Report ID (132),                */
  	0x09, 0x24,         /*      Usage (24h),                    */
  	0xB1, 0x02,         /*      Feature (Variable),             */
  	0x85, 0x90,         /*      Report ID (144),                */
  	0x09, 0x30,         /*      Usage (30h),                    */
  	0xB1, 0x02,         /*      Feature (Variable),             */
  	0x85, 0x91,         /*      Report ID (145),                */
  	0x09, 0x31,         /*      Usage (31h),                    */
  	0xB1, 0x02,         /*      Feature (Variable),             */
  	0x85, 0x92,         /*      Report ID (146),                */
  	0x09, 0x32,         /*      Usage (32h),                    */
  	0xB1, 0x02,         /*      Feature (Variable),             */
  	0x85, 0x93,         /*      Report ID (147),                */
  	0x09, 0x33,         /*      Usage (33h),                    */
  	0xB1, 0x02,         /*      Feature (Variable),             */
  	0x85, 0xA0,         /*      Report ID (160),                */
  	0x09, 0x40,         /*      Usage (40h),                    */
  	0xB1, 0x02,         /*      Feature (Variable),             */
  	0x85, 0xA4,         /*      Report ID (164),                */
  	0x09, 0x44,         /*      Usage (44h),                    */
  	0xB1, 0x02,         /*      Feature (Variable),             */
  	0xC0                /*  End Collection                      */
  };
1adf904e9   Pavel Machek   HID: sony: unders...
806
  static u8 ps3remote_rdesc[] = {
078328da5   Jiri Kosina   HID: fold ps3remo...
807
808
809
810
811
812
  	0x05, 0x01,          /* GUsagePage Generic Desktop */
  	0x09, 0x05,          /* LUsage 0x05 [Game Pad] */
  	0xA1, 0x01,          /* MCollection Application (mouse, keyboard) */
  
  	 /* Use collection 1 for joypad buttons */
  	 0xA1, 0x02,         /* MCollection Logical (interrelated data) */
ef916ef5e   Antonio Ospite   HID: sony: fix so...
813
814
815
816
  	  /*
  	   * Ignore the 1st byte, maybe it is used for a controller
  	   * number but it's not needed for correct operation
  	   */
078328da5   Jiri Kosina   HID: fold ps3remo...
817
818
819
  	  0x75, 0x08,        /* GReportSize 0x08 [8] */
  	  0x95, 0x01,        /* GReportCount 0x01 [1] */
  	  0x81, 0x01,        /* MInput 0x01 (Const[0] Arr[1] Abs[2]) */
ef916ef5e   Antonio Ospite   HID: sony: fix so...
820
821
822
823
  	  /*
  	   * Bytes from 2nd to 4th are a bitmap for joypad buttons, for these
  	   * buttons multiple keypresses are allowed
  	   */
078328da5   Jiri Kosina   HID: fold ps3remo...
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
  	  0x05, 0x09,        /* GUsagePage Button */
  	  0x19, 0x01,        /* LUsageMinimum 0x01 [Button 1 (primary/trigger)] */
  	  0x29, 0x18,        /* LUsageMaximum 0x18 [Button 24] */
  	  0x14,              /* GLogicalMinimum [0] */
  	  0x25, 0x01,        /* GLogicalMaximum 0x01 [1] */
  	  0x75, 0x01,        /* GReportSize 0x01 [1] */
  	  0x95, 0x18,        /* GReportCount 0x18 [24] */
  	  0x81, 0x02,        /* MInput 0x02 (Data[0] Var[1] Abs[2]) */
  
  	  0xC0,              /* MEndCollection */
  
  	 /* Use collection 2 for remote control buttons */
  	 0xA1, 0x02,         /* MCollection Logical (interrelated data) */
  
  	  /* 5th byte is used for remote control buttons */
  	  0x05, 0x09,        /* GUsagePage Button */
  	  0x18,              /* LUsageMinimum [No button pressed] */
  	  0x29, 0xFE,        /* LUsageMaximum 0xFE [Button 254] */
  	  0x14,              /* GLogicalMinimum [0] */
  	  0x26, 0xFE, 0x00,  /* GLogicalMaximum 0x00FE [254] */
  	  0x75, 0x08,        /* GReportSize 0x08 [8] */
  	  0x95, 0x01,        /* GReportCount 0x01 [1] */
  	  0x80,              /* MInput  */
ef916ef5e   Antonio Ospite   HID: sony: fix so...
847
848
849
850
  	  /*
  	   * Ignore bytes from 6th to 11th, 6th to 10th are always constant at
  	   * 0xff and 11th is for press indication
  	   */
078328da5   Jiri Kosina   HID: fold ps3remo...
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
  	  0x75, 0x08,        /* GReportSize 0x08 [8] */
  	  0x95, 0x06,        /* GReportCount 0x06 [6] */
  	  0x81, 0x01,        /* MInput 0x01 (Const[0] Arr[1] Abs[2]) */
  
  	  /* 12th byte is for battery strength */
  	  0x05, 0x06,        /* GUsagePage Generic Device Controls */
  	  0x09, 0x20,        /* LUsage 0x20 [Battery Strength] */
  	  0x14,              /* GLogicalMinimum [0] */
  	  0x25, 0x05,        /* GLogicalMaximum 0x05 [5] */
  	  0x75, 0x08,        /* GReportSize 0x08 [8] */
  	  0x95, 0x01,        /* GReportCount 0x01 [1] */
  	  0x81, 0x02,        /* MInput 0x02 (Data[0] Var[1] Abs[2]) */
  
  	  0xC0,              /* MEndCollection */
  
  	 0xC0                /* MEndCollection [Game Pad] */
  };
  
  static const unsigned int ps3remote_keymap_joypad_buttons[] = {
  	[0x01] = KEY_SELECT,
  	[0x02] = BTN_THUMBL,		/* L3 */
  	[0x03] = BTN_THUMBR,		/* R3 */
  	[0x04] = BTN_START,
  	[0x05] = KEY_UP,
  	[0x06] = KEY_RIGHT,
  	[0x07] = KEY_DOWN,
  	[0x08] = KEY_LEFT,
  	[0x09] = BTN_TL2,		/* L2 */
  	[0x0a] = BTN_TR2,		/* R2 */
  	[0x0b] = BTN_TL,		/* L1 */
  	[0x0c] = BTN_TR,		/* R1 */
  	[0x0d] = KEY_OPTION,		/* options/triangle */
  	[0x0e] = KEY_BACK,		/* back/circle */
  	[0x0f] = BTN_0,			/* cross */
  	[0x10] = KEY_SCREEN,		/* view/square */
  	[0x11] = KEY_HOMEPAGE,		/* PS button */
  	[0x14] = KEY_ENTER,
  };
  static const unsigned int ps3remote_keymap_remote_buttons[] = {
  	[0x00] = KEY_1,
  	[0x01] = KEY_2,
  	[0x02] = KEY_3,
  	[0x03] = KEY_4,
  	[0x04] = KEY_5,
  	[0x05] = KEY_6,
  	[0x06] = KEY_7,
  	[0x07] = KEY_8,
  	[0x08] = KEY_9,
  	[0x09] = KEY_0,
  	[0x0e] = KEY_ESC,		/* return */
  	[0x0f] = KEY_CLEAR,
  	[0x16] = KEY_EJECTCD,
  	[0x1a] = KEY_MENU,		/* top menu */
  	[0x28] = KEY_TIME,
  	[0x30] = KEY_PREVIOUS,
  	[0x31] = KEY_NEXT,
  	[0x32] = KEY_PLAY,
  	[0x33] = KEY_REWIND,		/* scan back */
  	[0x34] = KEY_FORWARD,		/* scan forward */
  	[0x38] = KEY_STOP,
  	[0x39] = KEY_PAUSE,
  	[0x40] = KEY_CONTEXT_MENU,	/* pop up/menu */
  	[0x60] = KEY_FRAMEBACK,		/* slow/step back */
  	[0x61] = KEY_FRAMEFORWARD,	/* slow/step forward */
  	[0x63] = KEY_SUBTITLE,
  	[0x64] = KEY_AUDIO,
  	[0x65] = KEY_ANGLE,
  	[0x70] = KEY_INFO,		/* display */
  	[0x80] = KEY_BLUE,
  	[0x81] = KEY_RED,
  	[0x82] = KEY_GREEN,
  	[0x83] = KEY_YELLOW,
  };
f04d51404   Colin Leitner   HID: driver for P...
924
  static const unsigned int buzz_keymap[] = {
ad142b9e4   Frank Praznik   HID: sony: Fix mu...
925
926
  	/*
  	 * The controller has 4 remote buzzers, each with one LED and 5
f04d51404   Colin Leitner   HID: driver for P...
927
  	 * buttons.
09593e388   Antonio Ospite   HID: sony: fix er...
928
  	 *
f04d51404   Colin Leitner   HID: driver for P...
929
930
931
932
933
934
935
936
937
938
939
940
941
  	 * We use the mapping chosen by the controller, which is:
  	 *
  	 * Key          Offset
  	 * -------------------
  	 * Buzz              1
  	 * Blue              5
  	 * Orange            4
  	 * Green             3
  	 * Yellow            2
  	 *
  	 * So, for example, the orange button on the third buzzer is mapped to
  	 * BTN_TRIGGER_HAPPY14
  	 */
09593e388   Antonio Ospite   HID: sony: fix er...
942
943
944
945
946
947
948
949
950
  	 [1] = BTN_TRIGGER_HAPPY1,
  	 [2] = BTN_TRIGGER_HAPPY2,
  	 [3] = BTN_TRIGGER_HAPPY3,
  	 [4] = BTN_TRIGGER_HAPPY4,
  	 [5] = BTN_TRIGGER_HAPPY5,
  	 [6] = BTN_TRIGGER_HAPPY6,
  	 [7] = BTN_TRIGGER_HAPPY7,
  	 [8] = BTN_TRIGGER_HAPPY8,
  	 [9] = BTN_TRIGGER_HAPPY9,
f04d51404   Colin Leitner   HID: driver for P...
951
952
953
954
955
956
957
958
959
960
961
962
  	[10] = BTN_TRIGGER_HAPPY10,
  	[11] = BTN_TRIGGER_HAPPY11,
  	[12] = BTN_TRIGGER_HAPPY12,
  	[13] = BTN_TRIGGER_HAPPY13,
  	[14] = BTN_TRIGGER_HAPPY14,
  	[15] = BTN_TRIGGER_HAPPY15,
  	[16] = BTN_TRIGGER_HAPPY16,
  	[17] = BTN_TRIGGER_HAPPY17,
  	[18] = BTN_TRIGGER_HAPPY18,
  	[19] = BTN_TRIGGER_HAPPY19,
  	[20] = BTN_TRIGGER_HAPPY20,
  };
d902f4724   Frank Praznik   HID: sony: add ba...
963
964
965
966
967
968
  static enum power_supply_property sony_battery_props[] = {
  	POWER_SUPPLY_PROP_PRESENT,
  	POWER_SUPPLY_PROP_CAPACITY,
  	POWER_SUPPLY_PROP_SCOPE,
  	POWER_SUPPLY_PROP_STATUS,
  };
55d3b664d   Frank Praznik   HID: sony: Use a ...
969
  struct sixaxis_led {
1adf904e9   Pavel Machek   HID: sony: unders...
970
971
972
973
974
  	u8 time_enabled; /* the total time the led is active (0xff means forever) */
  	u8 duty_length;  /* how long a cycle is in deciseconds (0 means "really fast") */
  	u8 enabled;
  	u8 duty_off; /* % of duty_length the led is off (0xff means 100%) */
  	u8 duty_on;  /* % of duty_length the led is on (0xff mean 100%) */
55d3b664d   Frank Praznik   HID: sony: Use a ...
975
976
977
  } __packed;
  
  struct sixaxis_rumble {
1adf904e9   Pavel Machek   HID: sony: unders...
978
979
980
981
982
  	u8 padding;
  	u8 right_duration; /* Right motor duration (0xff means forever) */
  	u8 right_motor_on; /* Right (small) motor on/off, only supports values of 0 or 1 (off/on) */
  	u8 left_duration;    /* Left motor duration (0xff means forever) */
  	u8 left_motor_force; /* left (large) motor, supports force values from 0 to 255 */
55d3b664d   Frank Praznik   HID: sony: Use a ...
983
984
985
  } __packed;
  
  struct sixaxis_output_report {
1adf904e9   Pavel Machek   HID: sony: unders...
986
  	u8 report_id;
55d3b664d   Frank Praznik   HID: sony: Use a ...
987
  	struct sixaxis_rumble rumble;
1adf904e9   Pavel Machek   HID: sony: unders...
988
989
  	u8 padding[4];
  	u8 leds_bitmap; /* bitmap of enabled LEDs: LED_1 = 0x02, LED_2 = 0x04, ... */
55d3b664d   Frank Praznik   HID: sony: Use a ...
990
991
992
993
994
995
  	struct sixaxis_led led[4];    /* LEDx at (4 - x) */
  	struct sixaxis_led _reserved; /* LED5, not actually soldered */
  } __packed;
  
  union sixaxis_output_report_01 {
  	struct sixaxis_output_report data;
1adf904e9   Pavel Machek   HID: sony: unders...
996
  	u8 buf[36];
55d3b664d   Frank Praznik   HID: sony: Use a ...
997
  };
c5e0c1c49   Frank Praznik   HID: sony: Add su...
998
999
1000
1001
1002
1003
  struct motion_output_report_02 {
  	u8 type, zero;
  	u8 r, g, b;
  	u8 zero2;
  	u8 rumble;
  };
9b2b5c9a7   Frank Praznik   HID: sony: Use ke...
1004
1005
1006
1007
  #define DS4_REPORT_0x02_SIZE 37
  #define DS4_REPORT_0x05_SIZE 32
  #define DS4_REPORT_0x11_SIZE 78
  #define DS4_REPORT_0x81_SIZE 7
29b691a89   Antonio Ospite   HID: sony: Use th...
1008
  #define SIXAXIS_REPORT_0xF2_SIZE 17
a85d67b54   Antonio Ospite   HID: sony: Don't ...
1009
  #define SIXAXIS_REPORT_0xF5_SIZE 8
41d2d4253   Simon Wood   HID: sony: PS3 Mo...
1010
  #define MOTION_REPORT_0x02_SIZE 49
9b2b5c9a7   Frank Praznik   HID: sony: Use ke...
1011

8b402c929   Jiri Kosina   HID: sony: initia...
1012
  static DEFINE_SPINLOCK(sony_dev_list_lock);
d2d782fcc   Frank Praznik   HID: sony: Preven...
1013
  static LIST_HEAD(sony_device_list);
8025087ac   Frank Praznik   HID: sony: Initia...
1014
  static DEFINE_IDA(sony_device_id_allocator);
d2d782fcc   Frank Praznik   HID: sony: Preven...
1015

cc6e0bbb4   Jiri Kosina   HID: Add support ...
1016
  struct sony_sc {
d902f4724   Frank Praznik   HID: sony: add ba...
1017
  	spinlock_t lock;
d2d782fcc   Frank Praznik   HID: sony: Preven...
1018
  	struct list_head list_node;
0a286ef27   Sven Eckelmann   HID: sony: Add LE...
1019
  	struct hid_device *hdev;
60781cf48   Frank Praznik   HID: sony: Add LE...
1020
  	struct led_classdev *leds[MAX_LEDS];
cc6e0bbb4   Jiri Kosina   HID: Add support ...
1021
  	unsigned long quirks;
0a286ef27   Sven Eckelmann   HID: sony: Add LE...
1022
  	struct work_struct state_worker;
09593e388   Antonio Ospite   HID: sony: fix er...
1023
  	void (*send_output_report)(struct sony_sc *);
297d716f6   Krzysztof Kozlowski   power_supply: Cha...
1024
1025
  	struct power_supply *battery;
  	struct power_supply_desc battery_desc;
8025087ac   Frank Praznik   HID: sony: Initia...
1026
  	int device_id;
1adf904e9   Pavel Machek   HID: sony: unders...
1027
  	u8 *output_report_dmabuf;
f04d51404   Colin Leitner   HID: driver for P...
1028

9f323b681   Sven Eckelmann   HID: sony: Send F...
1029
  #ifdef CONFIG_SONY_FF
1adf904e9   Pavel Machek   HID: sony: unders...
1030
1031
  	u8 left;
  	u8 right;
9f323b681   Sven Eckelmann   HID: sony: Send F...
1032
  #endif
1adf904e9   Pavel Machek   HID: sony: unders...
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
  	u8 mac_address[6];
  	u8 worker_initialized;
  	u8 cable_state;
  	u8 battery_charging;
  	u8 battery_capacity;
  	u8 led_state[MAX_LEDS];
  	u8 resume_led_state[MAX_LEDS];
  	u8 led_delay_on[MAX_LEDS];
  	u8 led_delay_off[MAX_LEDS];
  	u8 led_count;
cc6e0bbb4   Jiri Kosina   HID: Add support ...
1043
  };
1adf904e9   Pavel Machek   HID: sony: unders...
1044
  static u8 *sixaxis_fixup(struct hid_device *hdev, u8 *rdesc,
c607fb8d6   Antonio Ospite   HID: sony: Always...
1045
1046
1047
1048
1049
  			     unsigned int *rsize)
  {
  	*rsize = sizeof(sixaxis_rdesc);
  	return sixaxis_rdesc;
  }
c5e0c1c49   Frank Praznik   HID: sony: Add su...
1050
1051
1052
1053
1054
1055
  static u8 *motion_fixup(struct hid_device *hdev, u8 *rdesc,
  			     unsigned int *rsize)
  {
  	*rsize = sizeof(motion_rdesc);
  	return motion_rdesc;
  }
b2723eb73   Simon Wood   HID: hid-sony: Fi...
1056
1057
1058
1059
1060
1061
  static u8 *navigation_fixup(struct hid_device *hdev, u8 *rdesc,
  			     unsigned int *rsize)
  {
  	*rsize = sizeof(navigation_rdesc);
  	return navigation_rdesc;
  }
1adf904e9   Pavel Machek   HID: sony: unders...
1062
  static u8 *ps3remote_fixup(struct hid_device *hdev, u8 *rdesc,
078328da5   Jiri Kosina   HID: fold ps3remo...
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
  			     unsigned int *rsize)
  {
  	*rsize = sizeof(ps3remote_rdesc);
  	return ps3remote_rdesc;
  }
  
  static int ps3remote_mapping(struct hid_device *hdev, struct hid_input *hi,
  			     struct hid_field *field, struct hid_usage *usage,
  			     unsigned long **bit, int *max)
  {
  	unsigned int key = usage->hid & HID_USAGE;
  
  	if ((usage->hid & HID_USAGE_PAGE) != HID_UP_BUTTON)
  		return -1;
  
  	switch (usage->collection_index) {
  	case 1:
  		if (key >= ARRAY_SIZE(ps3remote_keymap_joypad_buttons))
  			return -1;
  
  		key = ps3remote_keymap_joypad_buttons[key];
  		if (!key)
  			return -1;
  		break;
  	case 2:
  		if (key >= ARRAY_SIZE(ps3remote_keymap_remote_buttons))
  			return -1;
  
  		key = ps3remote_keymap_remote_buttons[key];
  		if (!key)
  			return -1;
  		break;
  	default:
  		return -1;
  	}
  
  	hid_map_usage_clear(hi, usage, bit, max, EV_KEY, key);
  	return 1;
  }
1adf904e9   Pavel Machek   HID: sony: unders...
1102
  static u8 *sony_report_fixup(struct hid_device *hdev, u8 *rdesc,
73e4008dd   Nikolai Kondrashov   HID: allow resizi...
1103
  		unsigned int *rsize)
cc6e0bbb4   Jiri Kosina   HID: Add support ...
1104
1105
  {
  	struct sony_sc *sc = hid_get_drvdata(hdev);
74500cc85   Scott Moreau   HID: sony: Add ny...
1106
1107
  	if (sc->quirks & SINO_LITE_CONTROLLER)
  		return rdesc;
99d249021   Fernando Luis Vázquez Cao   HID: clean up qui...
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
  	/*
  	 * Some Sony RF receivers wrongly declare the mouse pointer as a
  	 * a constant non-data variable.
  	 */
  	if ((sc->quirks & VAIO_RDESC_CONSTANT) && *rsize >= 56 &&
  	    /* usage page: generic desktop controls */
  	    /* rdesc[0] == 0x05 && rdesc[1] == 0x01 && */
  	    /* usage: mouse */
  	    rdesc[2] == 0x09 && rdesc[3] == 0x02 &&
  	    /* input (usage page for x,y axes): constant, variable, relative */
  	    rdesc[54] == 0x81 && rdesc[55] == 0x07) {
a46491841   Fernando Luis Vázquez Cao   HID: add support ...
1119
1120
  		hid_info(hdev, "Fixing up Sony RF Receiver report descriptor
  ");
99d249021   Fernando Luis Vázquez Cao   HID: clean up qui...
1121
  		/* input: data, variable, relative */
cc6e0bbb4   Jiri Kosina   HID: Add support ...
1122
1123
  		rdesc[55] = 0x06;
  	}
61ab44beb   Simon Wood   HID: hid-sony: am...
1124

ed19d8cf2   Frank Praznik   HID: sony: Map gy...
1125
1126
1127
1128
1129
  	/*
  	 * The default Dualshock 4 USB descriptor doesn't assign
  	 * the gyroscope values to corresponding axes so we need a
  	 * modified one.
  	 */
b71b5578a   Frank Praznik   HID: sony: Remove...
1130
  	if (sc->quirks & DUALSHOCK4_CONTROLLER_USB) {
ed19d8cf2   Frank Praznik   HID: sony: Map gy...
1131
1132
1133
1134
  		hid_info(hdev, "Using modified Dualshock 4 report descriptor with gyroscope axes
  ");
  		rdesc = dualshock4_usb_rdesc;
  		*rsize = sizeof(dualshock4_usb_rdesc);
b71b5578a   Frank Praznik   HID: sony: Remove...
1135
  	} else if (sc->quirks & DUALSHOCK4_CONTROLLER_BT) {
d829674d2   Frank Praznik   HID: sony: Add mo...
1136
1137
1138
1139
  		hid_info(hdev, "Using modified Dualshock 4 Bluetooth report descriptor
  ");
  		rdesc = dualshock4_bt_rdesc;
  		*rsize = sizeof(dualshock4_bt_rdesc);
ed19d8cf2   Frank Praznik   HID: sony: Map gy...
1140
  	}
c607fb8d6   Antonio Ospite   HID: sony: Always...
1141
1142
  	if (sc->quirks & SIXAXIS_CONTROLLER)
  		return sixaxis_fixup(hdev, rdesc, rsize);
078328da5   Jiri Kosina   HID: fold ps3remo...
1143

c5e0c1c49   Frank Praznik   HID: sony: Add su...
1144
1145
  	if (sc->quirks & MOTION_CONTROLLER)
  		return motion_fixup(hdev, rdesc, rsize);
4545ee0a7   Simon Wood   HID: hid-sony: Na...
1146
  	if (sc->quirks & NAVIGATION_CONTROLLER)
b2723eb73   Simon Wood   HID: hid-sony: Fi...
1147
  		return navigation_fixup(hdev, rdesc, rsize);
4545ee0a7   Simon Wood   HID: hid-sony: Na...
1148

078328da5   Jiri Kosina   HID: fold ps3remo...
1149
1150
  	if (sc->quirks & PS3REMOTE)
  		return ps3remote_fixup(hdev, rdesc, rsize);
73e4008dd   Nikolai Kondrashov   HID: allow resizi...
1151
  	return rdesc;
cc6e0bbb4   Jiri Kosina   HID: Add support ...
1152
  }
1adf904e9   Pavel Machek   HID: sony: unders...
1153
  static void sixaxis_parse_report(struct sony_sc *sc, u8 *rd, int size)
d902f4724   Frank Praznik   HID: sony: add ba...
1154
  {
1adf904e9   Pavel Machek   HID: sony: unders...
1155
  	static const u8 sixaxis_battery_capacity[] = { 0, 1, 25, 50, 75, 100 };
d902f4724   Frank Praznik   HID: sony: add ba...
1156
  	unsigned long flags;
12e9a6d72   Simon Wood   HID: sony: Add su...
1157
  	int offset;
1adf904e9   Pavel Machek   HID: sony: unders...
1158
  	u8 cable_state, battery_capacity, battery_charging;
d902f4724   Frank Praznik   HID: sony: add ba...
1159

ad142b9e4   Frank Praznik   HID: sony: Fix mu...
1160
1161
  	/*
  	 * The sixaxis is charging if the battery value is 0xee
d902f4724   Frank Praznik   HID: sony: add ba...
1162
1163
1164
1165
  	 * and it is fully charged if the value is 0xef.
  	 * It does not report the actual level while charging so it
  	 * is set to 100% while charging is in progress.
  	 */
12e9a6d72   Simon Wood   HID: sony: Add su...
1166
1167
1168
  	offset = (sc->quirks & MOTION_CONTROLLER) ? 12 : 30;
  
  	if (rd[offset] >= 0xee) {
d902f4724   Frank Praznik   HID: sony: add ba...
1169
  		battery_capacity = 100;
12e9a6d72   Simon Wood   HID: sony: Add su...
1170
  		battery_charging = !(rd[offset] & 0x01);
9fddd74a2   Frank Praznik   HID: sony: Set th...
1171
  		cable_state = 1;
d902f4724   Frank Praznik   HID: sony: add ba...
1172
  	} else {
1adf904e9   Pavel Machek   HID: sony: unders...
1173
  		u8 index = rd[offset] <= 5 ? rd[offset] : 5;
ac3c9a940   Frank Praznik   HID: sony: Perfor...
1174
  		battery_capacity = sixaxis_battery_capacity[index];
d902f4724   Frank Praznik   HID: sony: add ba...
1175
  		battery_charging = 0;
9fddd74a2   Frank Praznik   HID: sony: Set th...
1176
  		cable_state = 0;
d902f4724   Frank Praznik   HID: sony: add ba...
1177
  	}
d902f4724   Frank Praznik   HID: sony: add ba...
1178
1179
1180
1181
1182
1183
1184
  
  	spin_lock_irqsave(&sc->lock, flags);
  	sc->cable_state = cable_state;
  	sc->battery_capacity = battery_capacity;
  	sc->battery_charging = battery_charging;
  	spin_unlock_irqrestore(&sc->lock, flags);
  }
1adf904e9   Pavel Machek   HID: sony: unders...
1185
  static void dualshock4_parse_report(struct sony_sc *sc, u8 *rd, int size)
d902f4724   Frank Praznik   HID: sony: add ba...
1186
  {
e56062305   Frank Praznik   HID: sony: add ou...
1187
1188
1189
  	struct hid_input *hidinput = list_entry(sc->hdev->inputs.next,
  						struct hid_input, list);
  	struct input_dev *input_dev = hidinput->input;
d902f4724   Frank Praznik   HID: sony: add ba...
1190
  	unsigned long flags;
6c5f860d3   Frank Praznik   HID: sony: Add Du...
1191
  	int n, offset;
1adf904e9   Pavel Machek   HID: sony: unders...
1192
  	u8 cable_state, battery_capacity, battery_charging;
d902f4724   Frank Praznik   HID: sony: add ba...
1193

ad142b9e4   Frank Praznik   HID: sony: Fix mu...
1194
1195
  	/*
  	 * Battery and touchpad data starts at byte 30 in the USB report and
6c5f860d3   Frank Praznik   HID: sony: Add Du...
1196
1197
1198
  	 * 32 in Bluetooth report.
  	 */
  	offset = (sc->quirks & DUALSHOCK4_CONTROLLER_USB) ? 30 : 32;
ad142b9e4   Frank Praznik   HID: sony: Fix mu...
1199
1200
  	/*
  	 * The lower 4 bits of byte 30 contain the battery level
d902f4724   Frank Praznik   HID: sony: add ba...
1201
1202
  	 * and the 5th bit contains the USB cable state.
  	 */
6c5f860d3   Frank Praznik   HID: sony: Add Du...
1203
1204
  	cable_state = (rd[offset] >> 4) & 0x01;
  	battery_capacity = rd[offset] & 0x0F;
d902f4724   Frank Praznik   HID: sony: add ba...
1205

ad142b9e4   Frank Praznik   HID: sony: Fix mu...
1206
1207
  	/*
  	 * When a USB power source is connected the battery level ranges from
6c5f860d3   Frank Praznik   HID: sony: Add Du...
1208
1209
  	 * 0 to 10, and when running on battery power it ranges from 0 to 9.
  	 * A battery level above 10 when plugged in means charge completed.
d902f4724   Frank Praznik   HID: sony: add ba...
1210
  	 */
6c5f860d3   Frank Praznik   HID: sony: Add Du...
1211
  	if (!cable_state || battery_capacity > 10)
d902f4724   Frank Praznik   HID: sony: add ba...
1212
1213
1214
  		battery_charging = 0;
  	else
  		battery_charging = 1;
6c5f860d3   Frank Praznik   HID: sony: Add Du...
1215
1216
  	if (!cable_state)
  		battery_capacity++;
d902f4724   Frank Praznik   HID: sony: add ba...
1217
  	if (battery_capacity > 10)
6c5f860d3   Frank Praznik   HID: sony: Add Du...
1218
  		battery_capacity = 10;
d902f4724   Frank Praznik   HID: sony: add ba...
1219
1220
1221
1222
1223
1224
1225
  	battery_capacity *= 10;
  
  	spin_lock_irqsave(&sc->lock, flags);
  	sc->cable_state = cable_state;
  	sc->battery_capacity = battery_capacity;
  	sc->battery_charging = battery_charging;
  	spin_unlock_irqrestore(&sc->lock, flags);
e56062305   Frank Praznik   HID: sony: add ou...
1226

6c5f860d3   Frank Praznik   HID: sony: Add Du...
1227
  	offset += 5;
ad142b9e4   Frank Praznik   HID: sony: Fix mu...
1228
1229
  	/*
  	 * The Dualshock 4 multi-touch trackpad data starts at offset 35 on USB
6c5f860d3   Frank Praznik   HID: sony: Add Du...
1230
  	 * and 37 on Bluetooth.
e56062305   Frank Praznik   HID: sony: add ou...
1231
1232
1233
1234
1235
1236
1237
  	 * The first 7 bits of the first byte is a counter and bit 8 is a touch
  	 * indicator that is 0 when pressed and 1 when not pressed.
  	 * The next 3 bytes are two 12 bit touch coordinates, X and Y.
  	 * The data for the second touch is in the same format and immediatly
  	 * follows the data for the first.
  	 */
  	for (n = 0; n < 2; n++) {
1adf904e9   Pavel Machek   HID: sony: unders...
1238
  		u16 x, y;
e56062305   Frank Praznik   HID: sony: add ou...
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
  
  		x = rd[offset+1] | ((rd[offset+2] & 0xF) << 8);
  		y = ((rd[offset+2] & 0xF0) >> 4) | (rd[offset+3] << 4);
  
  		input_mt_slot(input_dev, n);
  		input_mt_report_slot_state(input_dev, MT_TOOL_FINGER,
  					!(rd[offset] >> 7));
  		input_report_abs(input_dev, ABS_MT_POSITION_X, x);
  		input_report_abs(input_dev, ABS_MT_POSITION_Y, y);
  
  		offset += 4;
  	}
d902f4724   Frank Praznik   HID: sony: add ba...
1251
  }
c9e4d8775   Simon Wood   HID: hid-sony: fi...
1252
  static int sony_raw_event(struct hid_device *hdev, struct hid_report *report,
1adf904e9   Pavel Machek   HID: sony: unders...
1253
  		u8 *rd, int size)
c9e4d8775   Simon Wood   HID: hid-sony: fi...
1254
1255
  {
  	struct sony_sc *sc = hid_get_drvdata(hdev);
ad142b9e4   Frank Praznik   HID: sony: Fix mu...
1256
1257
  	/*
  	 * Sixaxis HID report has acclerometers/gyro with MSByte first, this
c9e4d8775   Simon Wood   HID: hid-sony: fi...
1258
1259
  	 * has to be BYTE_SWAPPED before passing up to joystick interface
  	 */
fee4e2d52   Frank Praznik   HID: sony: Enable...
1260
  	if ((sc->quirks & SIXAXIS_CONTROLLER) && rd[0] == 0x01 && size == 49) {
8f5f0bc27   Frank Praznik   HID: sony: Drop i...
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
  		/*
  		 * When connected via Bluetooth the Sixaxis occasionally sends
  		 * a report with the second byte 0xff and the rest zeroed.
  		 *
  		 * This report does not reflect the actual state of the
  		 * controller must be ignored to avoid generating false input
  		 * events.
  		 */
  		if (rd[1] == 0xff)
  			return -EINVAL;
c9e4d8775   Simon Wood   HID: hid-sony: fi...
1271
1272
1273
1274
  		swap(rd[41], rd[42]);
  		swap(rd[43], rd[44]);
  		swap(rd[45], rd[46]);
  		swap(rd[47], rd[48]);
d902f4724   Frank Praznik   HID: sony: add ba...
1275
1276
  
  		sixaxis_parse_report(sc, rd, size);
12e9a6d72   Simon Wood   HID: sony: Add su...
1277
1278
  	} else if ((sc->quirks & MOTION_CONTROLLER_BT) && rd[0] == 0x01 && size == 49) {
  		sixaxis_parse_report(sc, rd, size);
4545ee0a7   Simon Wood   HID: hid-sony: Na...
1279
1280
1281
  	} else if ((sc->quirks & NAVIGATION_CONTROLLER) && rd[0] == 0x01 &&
  			size == 49) {
  		sixaxis_parse_report(sc, rd, size);
68330d83c   Frank Praznik   HID: sony: Add co...
1282
1283
1284
  	} else if (((sc->quirks & DUALSHOCK4_CONTROLLER_USB) && rd[0] == 0x01 &&
  			size == 64) || ((sc->quirks & DUALSHOCK4_CONTROLLER_BT)
  			&& rd[0] == 0x11 && size == 78)) {
d902f4724   Frank Praznik   HID: sony: add ba...
1285
  		dualshock4_parse_report(sc, rd, size);
c9e4d8775   Simon Wood   HID: hid-sony: fi...
1286
1287
1288
1289
  	}
  
  	return 0;
  }
f04d51404   Colin Leitner   HID: driver for P...
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
  static int sony_mapping(struct hid_device *hdev, struct hid_input *hi,
  			struct hid_field *field, struct hid_usage *usage,
  			unsigned long **bit, int *max)
  {
  	struct sony_sc *sc = hid_get_drvdata(hdev);
  
  	if (sc->quirks & BUZZ_CONTROLLER) {
  		unsigned int key = usage->hid & HID_USAGE;
  
  		if ((usage->hid & HID_USAGE_PAGE) != HID_UP_BUTTON)
  			return -1;
  
  		switch (usage->collection_index) {
  		case 1:
  			if (key >= ARRAY_SIZE(buzz_keymap))
  				return -1;
  
  			key = buzz_keymap[key];
  			if (!key)
  				return -1;
  			break;
  		default:
  			return -1;
  		}
  
  		hid_map_usage_clear(hi, usage, bit, max, EV_KEY, key);
  		return 1;
  	}
078328da5   Jiri Kosina   HID: fold ps3remo...
1318
1319
  	if (sc->quirks & PS3REMOTE)
  		return ps3remote_mapping(hdev, hi, field, usage, bit, max);
6f4980182   Benjamin Tissoires   HID: sony: fix HI...
1320
1321
  	/* Let hid-core decide for the others */
  	return 0;
f04d51404   Colin Leitner   HID: driver for P...
1322
  }
ce8efc3b5   Frank Praznik   HID: sony: Set to...
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
  static int sony_register_touchpad(struct hid_input *hi, int touch_count,
  					int w, int h)
  {
  	struct input_dev *input_dev = hi->input;
  	int ret;
  
  	ret = input_mt_init_slots(input_dev, touch_count, 0);
  	if (ret < 0)
  		return ret;
  
  	input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0, w, 0, 0);
  	input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0, h, 0, 0);
  
  	return 0;
  }
9154301a4   Dmitry Torokhov   HID: hid-input: a...
1338
  static int sony_input_configured(struct hid_device *hdev,
ce8efc3b5   Frank Praznik   HID: sony: Set to...
1339
1340
1341
  					struct hid_input *hidinput)
  {
  	struct sony_sc *sc = hid_get_drvdata(hdev);
9154301a4   Dmitry Torokhov   HID: hid-input: a...
1342
  	int ret;
ce8efc3b5   Frank Praznik   HID: sony: Set to...
1343
1344
1345
  
  	/*
  	 * The Dualshock 4 touchpad supports 2 touches and has a
981c5b4a3   Frank Praznik   HID: sony: Update...
1346
  	 * resolution of 1920x942 (44.86 dots/mm).
ce8efc3b5   Frank Praznik   HID: sony: Set to...
1347
1348
  	 */
  	if (sc->quirks & DUALSHOCK4_CONTROLLER) {
9154301a4   Dmitry Torokhov   HID: hid-input: a...
1349
1350
  		ret = sony_register_touchpad(hidinput, 2, 1920, 942);
  		if (ret) {
ce8efc3b5   Frank Praznik   HID: sony: Set to...
1351
  			hid_err(sc->hdev,
9154301a4   Dmitry Torokhov   HID: hid-input: a...
1352
1353
1354
1355
1356
  				"Unable to initialize multi-touch slots: %d
  ",
  				ret);
  			return ret;
  		}
ce8efc3b5   Frank Praznik   HID: sony: Set to...
1357
  	}
9154301a4   Dmitry Torokhov   HID: hid-input: a...
1358
1359
  
  	return 0;
ce8efc3b5   Frank Praznik   HID: sony: Set to...
1360
  }
5710fabf3   Antonio Ospite   HID: hid-sony.c: ...
1361
  /*
bd28ce008   Jiri Slaby   HID: move sony qu...
1362
1363
1364
1365
   * Sending HID_REQ_GET_REPORT changes the operation mode of the ps3 controller
   * to "operational".  Without this, the ps3 controller will not report any
   * events.
   */
816651a7d   Antonio Ospite   HID: sony: Apply ...
1366
  static int sixaxis_set_operational_usb(struct hid_device *hdev)
bd28ce008   Jiri Slaby   HID: move sony qu...
1367
  {
a85d67b54   Antonio Ospite   HID: sony: Don't ...
1368
1369
  	const int buf_size =
  		max(SIXAXIS_REPORT_0xF2_SIZE, SIXAXIS_REPORT_0xF5_SIZE);
1adf904e9   Pavel Machek   HID: sony: unders...
1370
  	u8 *buf;
bd28ce008   Jiri Slaby   HID: move sony qu...
1371
  	int ret;
bd28ce008   Jiri Slaby   HID: move sony qu...
1372

2e701a359   Antonio Ospite   HID: sony: Coding...
1373
  	buf = kmalloc(buf_size, GFP_KERNEL);
bd28ce008   Jiri Slaby   HID: move sony qu...
1374
1375
  	if (!buf)
  		return -ENOMEM;
a85d67b54   Antonio Ospite   HID: sony: Don't ...
1376
1377
  	ret = hid_hw_raw_request(hdev, 0xf2, buf, SIXAXIS_REPORT_0xF2_SIZE,
  				 HID_FEATURE_REPORT, HID_REQ_GET_REPORT);
a7de9b867   Lauri Kasanen   HID: sony: Enable...
1378
1379
1380
1381
1382
  	if (ret < 0) {
  		hid_err(hdev, "can't set operational mode: step 1
  ");
  		goto out;
  	}
f204828a1   Benjamin Tissoires   HID: sony: use hi...
1383

a7de9b867   Lauri Kasanen   HID: sony: Enable...
1384
1385
1386
1387
  	/*
  	 * Some compatible controllers like the Speedlink Strike FX and
  	 * Gasia need another query plus an USB interrupt to get operational.
  	 */
a85d67b54   Antonio Ospite   HID: sony: Don't ...
1388
1389
  	ret = hid_hw_raw_request(hdev, 0xf5, buf, SIXAXIS_REPORT_0xF5_SIZE,
  				 HID_FEATURE_REPORT, HID_REQ_GET_REPORT);
a7de9b867   Lauri Kasanen   HID: sony: Enable...
1390
1391
1392
1393
1394
  	if (ret < 0) {
  		hid_err(hdev, "can't set operational mode: step 2
  ");
  		goto out;
  	}
f204828a1   Benjamin Tissoires   HID: sony: use hi...
1395

a7de9b867   Lauri Kasanen   HID: sony: Enable...
1396
  	ret = hid_hw_output_report(hdev, buf, 1);
19f4c2ba8   Benjamin Tissoires   HID: sony: do not...
1397
1398
1399
1400
1401
  	if (ret < 0) {
  		hid_info(hdev, "can't set operational mode: step 3, ignoring
  ");
  		ret = 0;
  	}
bd28ce008   Jiri Slaby   HID: move sony qu...
1402

a7de9b867   Lauri Kasanen   HID: sony: Enable...
1403
  out:
bd28ce008   Jiri Slaby   HID: move sony qu...
1404
1405
1406
1407
  	kfree(buf);
  
  	return ret;
  }
816651a7d   Antonio Ospite   HID: sony: Apply ...
1408
  static int sixaxis_set_operational_bt(struct hid_device *hdev)
f9ce7c283   Bastien Nocera   HID: Enable Sixax...
1409
  {
1adf904e9   Pavel Machek   HID: sony: unders...
1410
1411
  	static const u8 report[] = { 0xf4, 0x42, 0x03, 0x00, 0x00 };
  	u8 *buf;
9b2b5c9a7   Frank Praznik   HID: sony: Use ke...
1412
1413
1414
1415
1416
1417
1418
  	int ret;
  
  	buf = kmemdup(report, sizeof(report), GFP_KERNEL);
  	if (!buf)
  		return -ENOMEM;
  
  	ret = hid_hw_raw_request(hdev, buf[0], buf, sizeof(report),
b0dd72aaf   Benjamin Tissoires   HID: replace hid_...
1419
  				  HID_FEATURE_REPORT, HID_REQ_SET_REPORT);
9b2b5c9a7   Frank Praznik   HID: sony: Use ke...
1420
1421
1422
1423
  
  	kfree(buf);
  
  	return ret;
f9ce7c283   Bastien Nocera   HID: Enable Sixax...
1424
  }
ad142b9e4   Frank Praznik   HID: sony: Fix mu...
1425
1426
  /*
   * Requesting feature report 0x02 in Bluetooth mode changes the state of the
68330d83c   Frank Praznik   HID: sony: Add co...
1427
1428
1429
1430
   * controller so that it sends full input reports of type 0x11.
   */
  static int dualshock4_set_operational_bt(struct hid_device *hdev)
  {
1adf904e9   Pavel Machek   HID: sony: unders...
1431
  	u8 *buf;
9b2b5c9a7   Frank Praznik   HID: sony: Use ke...
1432
  	int ret;
68330d83c   Frank Praznik   HID: sony: Add co...
1433

9b2b5c9a7   Frank Praznik   HID: sony: Use ke...
1434
1435
1436
1437
1438
  	buf = kmalloc(DS4_REPORT_0x02_SIZE, GFP_KERNEL);
  	if (!buf)
  		return -ENOMEM;
  
  	ret = hid_hw_raw_request(hdev, 0x02, buf, DS4_REPORT_0x02_SIZE,
68330d83c   Frank Praznik   HID: sony: Add co...
1439
  				HID_FEATURE_REPORT, HID_REQ_GET_REPORT);
9b2b5c9a7   Frank Praznik   HID: sony: Use ke...
1440
1441
1442
1443
  
  	kfree(buf);
  
  	return ret;
f9ce7c283   Bastien Nocera   HID: Enable Sixax...
1444
  }
221399b36   Frank Praznik   HID: sony: Simpli...
1445
  static void sixaxis_set_leds_from_id(struct sony_sc *sc)
8025087ac   Frank Praznik   HID: sony: Initia...
1446
  {
1adf904e9   Pavel Machek   HID: sony: unders...
1447
  	static const u8 sixaxis_leds[10][4] = {
8025087ac   Frank Praznik   HID: sony: Initia...
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
  				{ 0x01, 0x00, 0x00, 0x00 },
  				{ 0x00, 0x01, 0x00, 0x00 },
  				{ 0x00, 0x00, 0x01, 0x00 },
  				{ 0x00, 0x00, 0x00, 0x01 },
  				{ 0x01, 0x00, 0x00, 0x01 },
  				{ 0x00, 0x01, 0x00, 0x01 },
  				{ 0x00, 0x00, 0x01, 0x01 },
  				{ 0x01, 0x00, 0x01, 0x01 },
  				{ 0x00, 0x01, 0x01, 0x01 },
  				{ 0x01, 0x01, 0x01, 0x01 }
  	};
221399b36   Frank Praznik   HID: sony: Simpli...
1459
1460
1461
  	int id = sc->device_id;
  
  	BUILD_BUG_ON(MAX_LEDS < ARRAY_SIZE(sixaxis_leds[0]));
8025087ac   Frank Praznik   HID: sony: Initia...
1462
1463
1464
1465
1466
  
  	if (id < 0)
  		return;
  
  	id %= 10;
221399b36   Frank Praznik   HID: sony: Simpli...
1467
  	memcpy(sc->led_state, sixaxis_leds[id], sizeof(sixaxis_leds[id]));
8025087ac   Frank Praznik   HID: sony: Initia...
1468
  }
221399b36   Frank Praznik   HID: sony: Simpli...
1469
  static void dualshock4_set_leds_from_id(struct sony_sc *sc)
8025087ac   Frank Praznik   HID: sony: Initia...
1470
1471
  {
  	/* The first 4 color/index entries match what the PS4 assigns */
1adf904e9   Pavel Machek   HID: sony: unders...
1472
  	static const u8 color_code[7][3] = {
8025087ac   Frank Praznik   HID: sony: Initia...
1473
1474
1475
1476
1477
1478
1479
1480
  			/* Blue   */	{ 0x00, 0x00, 0x01 },
  			/* Red	  */	{ 0x01, 0x00, 0x00 },
  			/* Green  */	{ 0x00, 0x01, 0x00 },
  			/* Pink   */	{ 0x02, 0x00, 0x01 },
  			/* Orange */	{ 0x02, 0x01, 0x00 },
  			/* Teal   */	{ 0x00, 0x01, 0x01 },
  			/* White  */	{ 0x01, 0x01, 0x01 }
  	};
221399b36   Frank Praznik   HID: sony: Simpli...
1481
1482
1483
  	int id = sc->device_id;
  
  	BUILD_BUG_ON(MAX_LEDS < ARRAY_SIZE(color_code[0]));
8025087ac   Frank Praznik   HID: sony: Initia...
1484
1485
1486
1487
1488
  
  	if (id < 0)
  		return;
  
  	id %= 7;
221399b36   Frank Praznik   HID: sony: Simpli...
1489
  	memcpy(sc->led_state, color_code[id], sizeof(color_code[id]));
8025087ac   Frank Praznik   HID: sony: Initia...
1490
  }
221399b36   Frank Praznik   HID: sony: Simpli...
1491
  static void buzz_set_leds(struct sony_sc *sc)
f04d51404   Colin Leitner   HID: driver for P...
1492
  {
221399b36   Frank Praznik   HID: sony: Simpli...
1493
  	struct hid_device *hdev = sc->hdev;
f04d51404   Colin Leitner   HID: driver for P...
1494
1495
1496
1497
  	struct list_head *report_list =
  		&hdev->report_enum[HID_OUTPUT_REPORT].report_list;
  	struct hid_report *report = list_entry(report_list->next,
  		struct hid_report, list);
1adf904e9   Pavel Machek   HID: sony: unders...
1498
  	s32 *value = report->field[0]->value;
f04d51404   Colin Leitner   HID: driver for P...
1499

221399b36   Frank Praznik   HID: sony: Simpli...
1500
  	BUILD_BUG_ON(MAX_LEDS < 4);
f04d51404   Colin Leitner   HID: driver for P...
1501
  	value[0] = 0x00;
221399b36   Frank Praznik   HID: sony: Simpli...
1502
1503
1504
1505
  	value[1] = sc->led_state[0] ? 0xff : 0x00;
  	value[2] = sc->led_state[1] ? 0xff : 0x00;
  	value[3] = sc->led_state[2] ? 0xff : 0x00;
  	value[4] = sc->led_state[3] ? 0xff : 0x00;
f04d51404   Colin Leitner   HID: driver for P...
1506
1507
1508
1509
  	value[5] = 0x00;
  	value[6] = 0x00;
  	hid_hw_request(hdev, report, HID_REQ_SET_REPORT);
  }
221399b36   Frank Praznik   HID: sony: Simpli...
1510
  static void sony_set_leds(struct sony_sc *sc)
0a286ef27   Sven Eckelmann   HID: sony: Add LE...
1511
  {
221399b36   Frank Praznik   HID: sony: Simpli...
1512
  	if (!(sc->quirks & BUZZ_CONTROLLER))
fa57a8107   Frank Praznik   HID: sony: Conver...
1513
  		schedule_work(&sc->state_worker);
221399b36   Frank Praznik   HID: sony: Simpli...
1514
1515
  	else
  		buzz_set_leds(sc);
0a286ef27   Sven Eckelmann   HID: sony: Add LE...
1516
  }
c53825190   Sven Eckelmann   HID: sony: Rename...
1517
  static void sony_led_set_brightness(struct led_classdev *led,
f04d51404   Colin Leitner   HID: driver for P...
1518
1519
1520
  				    enum led_brightness value)
  {
  	struct device *dev = led->dev->parent;
ee79a8f84   Geliang Tang   HID: use to_hid_d...
1521
  	struct hid_device *hdev = to_hid_device(dev);
f04d51404   Colin Leitner   HID: driver for P...
1522
  	struct sony_sc *drv_data;
f04d51404   Colin Leitner   HID: driver for P...
1523
1524
  
  	int n;
b3ed458c1   Frank Praznik   HID: sony: Add bl...
1525
  	int force_update;
f04d51404   Colin Leitner   HID: driver for P...
1526
1527
  
  	drv_data = hid_get_drvdata(hdev);
2251b85f3   Sven Eckelmann   HID: sony: Move L...
1528
  	if (!drv_data) {
f04d51404   Colin Leitner   HID: driver for P...
1529
1530
1531
1532
  		hid_err(hdev, "No device data
  ");
  		return;
  	}
f04d51404   Colin Leitner   HID: driver for P...
1533

b3ed458c1   Frank Praznik   HID: sony: Add bl...
1534
1535
1536
1537
1538
1539
1540
1541
  	/*
  	 * The Sixaxis on USB will override any LED settings sent to it
  	 * and keep flashing all of the LEDs until the PS button is pressed.
  	 * Updates, even if redundant, must be always be sent to the
  	 * controller to avoid having to toggle the state of an LED just to
  	 * stop the flashing later on.
  	 */
  	force_update = !!(drv_data->quirks & SIXAXIS_CONTROLLER_USB);
60781cf48   Frank Praznik   HID: sony: Add LE...
1542
  	for (n = 0; n < drv_data->led_count; n++) {
b3ed458c1   Frank Praznik   HID: sony: Add bl...
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
  		if (led == drv_data->leds[n] && (force_update ||
  			(value != drv_data->led_state[n] ||
  			drv_data->led_delay_on[n] ||
  			drv_data->led_delay_off[n]))) {
  
  			drv_data->led_state[n] = value;
  
  			/* Setting the brightness stops the blinking */
  			drv_data->led_delay_on[n] = 0;
  			drv_data->led_delay_off[n] = 0;
221399b36   Frank Praznik   HID: sony: Simpli...
1553
  			sony_set_leds(drv_data);
f04d51404   Colin Leitner   HID: driver for P...
1554
1555
1556
1557
  			break;
  		}
  	}
  }
c53825190   Sven Eckelmann   HID: sony: Rename...
1558
  static enum led_brightness sony_led_get_brightness(struct led_classdev *led)
f04d51404   Colin Leitner   HID: driver for P...
1559
1560
  {
  	struct device *dev = led->dev->parent;
ee79a8f84   Geliang Tang   HID: use to_hid_d...
1561
  	struct hid_device *hdev = to_hid_device(dev);
f04d51404   Colin Leitner   HID: driver for P...
1562
  	struct sony_sc *drv_data;
f04d51404   Colin Leitner   HID: driver for P...
1563
1564
  
  	int n;
f04d51404   Colin Leitner   HID: driver for P...
1565
1566
  
  	drv_data = hid_get_drvdata(hdev);
2251b85f3   Sven Eckelmann   HID: sony: Move L...
1567
  	if (!drv_data) {
f04d51404   Colin Leitner   HID: driver for P...
1568
1569
1570
1571
  		hid_err(hdev, "No device data
  ");
  		return LED_OFF;
  	}
f04d51404   Colin Leitner   HID: driver for P...
1572

60781cf48   Frank Praznik   HID: sony: Add LE...
1573
  	for (n = 0; n < drv_data->led_count; n++) {
7db7504a4   Simon Wood   HID: hid-sony: re...
1574
1575
  		if (led == drv_data->leds[n])
  			return drv_data->led_state[n];
f04d51404   Colin Leitner   HID: driver for P...
1576
  	}
7db7504a4   Simon Wood   HID: hid-sony: re...
1577
  	return LED_OFF;
f04d51404   Colin Leitner   HID: driver for P...
1578
  }
f04d51404   Colin Leitner   HID: driver for P...
1579

b3ed458c1   Frank Praznik   HID: sony: Add bl...
1580
1581
1582
1583
  static int sony_led_blink_set(struct led_classdev *led, unsigned long *delay_on,
  				unsigned long *delay_off)
  {
  	struct device *dev = led->dev->parent;
ee79a8f84   Geliang Tang   HID: use to_hid_d...
1584
  	struct hid_device *hdev = to_hid_device(dev);
b3ed458c1   Frank Praznik   HID: sony: Add bl...
1585
1586
  	struct sony_sc *drv_data = hid_get_drvdata(hdev);
  	int n;
1adf904e9   Pavel Machek   HID: sony: unders...
1587
  	u8 new_on, new_off;
b3ed458c1   Frank Praznik   HID: sony: Add bl...
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
  
  	if (!drv_data) {
  		hid_err(hdev, "No device data
  ");
  		return -EINVAL;
  	}
  
  	/* Max delay is 255 deciseconds or 2550 milliseconds */
  	if (*delay_on > 2550)
  		*delay_on = 2550;
  	if (*delay_off > 2550)
  		*delay_off = 2550;
  
  	/* Blink at 1 Hz if both values are zero */
  	if (!*delay_on && !*delay_off)
  		*delay_on = *delay_off = 500;
  
  	new_on = *delay_on / 10;
  	new_off = *delay_off / 10;
  
  	for (n = 0; n < drv_data->led_count; n++) {
  		if (led == drv_data->leds[n])
  			break;
  	}
  
  	/* This LED is not registered on this device */
  	if (n >= drv_data->led_count)
  		return -EINVAL;
  
  	/* Don't schedule work if the values didn't change */
  	if (new_on != drv_data->led_delay_on[n] ||
  		new_off != drv_data->led_delay_off[n]) {
  		drv_data->led_delay_on[n] = new_on;
  		drv_data->led_delay_off[n] = new_off;
  		schedule_work(&drv_data->state_worker);
  	}
  
  	return 0;
  }
fa57a8107   Frank Praznik   HID: sony: Conver...
1627
  static void sony_leds_remove(struct sony_sc *sc)
0a286ef27   Sven Eckelmann   HID: sony: Add LE...
1628
  {
0a286ef27   Sven Eckelmann   HID: sony: Add LE...
1629
1630
  	struct led_classdev *led;
  	int n;
fa57a8107   Frank Praznik   HID: sony: Conver...
1631
  	BUG_ON(!(sc->quirks & SONY_LED_SUPPORT));
0a286ef27   Sven Eckelmann   HID: sony: Add LE...
1632

fa57a8107   Frank Praznik   HID: sony: Conver...
1633
1634
1635
  	for (n = 0; n < sc->led_count; n++) {
  		led = sc->leds[n];
  		sc->leds[n] = NULL;
0a286ef27   Sven Eckelmann   HID: sony: Add LE...
1636
1637
1638
1639
1640
  		if (!led)
  			continue;
  		led_classdev_unregister(led);
  		kfree(led);
  	}
60781cf48   Frank Praznik   HID: sony: Add LE...
1641

fa57a8107   Frank Praznik   HID: sony: Conver...
1642
  	sc->led_count = 0;
0a286ef27   Sven Eckelmann   HID: sony: Add LE...
1643
  }
fa57a8107   Frank Praznik   HID: sony: Conver...
1644
  static int sony_leds_init(struct sony_sc *sc)
f04d51404   Colin Leitner   HID: driver for P...
1645
  {
fa57a8107   Frank Praznik   HID: sony: Conver...
1646
  	struct hid_device *hdev = sc->hdev;
40e32ee6e   Jiri Kosina   HID: sony: fix le...
1647
  	int n, ret = 0;
b3ed458c1   Frank Praznik   HID: sony: Add bl...
1648
  	int use_ds4_names;
40e32ee6e   Jiri Kosina   HID: sony: fix le...
1649
1650
1651
  	struct led_classdev *led;
  	size_t name_sz;
  	char *name;
0a286ef27   Sven Eckelmann   HID: sony: Add LE...
1652
1653
  	size_t name_len;
  	const char *name_fmt;
b3ed458c1   Frank Praznik   HID: sony: Add bl...
1654
1655
  	static const char * const ds4_name_str[] = { "red", "green", "blue",
  						  "global" };
1adf904e9   Pavel Machek   HID: sony: unders...
1656
1657
  	u8 max_brightness[MAX_LEDS] = { [0 ... (MAX_LEDS - 1)] = 1 };
  	u8 use_hw_blink[MAX_LEDS] = { 0 };
f04d51404   Colin Leitner   HID: driver for P...
1658

fa57a8107   Frank Praznik   HID: sony: Conver...
1659
  	BUG_ON(!(sc->quirks & SONY_LED_SUPPORT));
0a286ef27   Sven Eckelmann   HID: sony: Add LE...
1660

fa57a8107   Frank Praznik   HID: sony: Conver...
1661
1662
  	if (sc->quirks & BUZZ_CONTROLLER) {
  		sc->led_count = 4;
b3ed458c1   Frank Praznik   HID: sony: Add bl...
1663
  		use_ds4_names = 0;
0a286ef27   Sven Eckelmann   HID: sony: Add LE...
1664
1665
1666
1667
1668
  		name_len = strlen("::buzz#");
  		name_fmt = "%s::buzz%d";
  		/* Validate expected report characteristics. */
  		if (!hid_validate_values(hdev, HID_OUTPUT_REPORT, 0, 0, 7))
  			return -ENODEV;
fa57a8107   Frank Praznik   HID: sony: Conver...
1669
  	} else if (sc->quirks & DUALSHOCK4_CONTROLLER) {
221399b36   Frank Praznik   HID: sony: Simpli...
1670
1671
  		dualshock4_set_leds_from_id(sc);
  		sc->led_state[3] = 1;
b3ed458c1   Frank Praznik   HID: sony: Add bl...
1672
1673
1674
1675
  		sc->led_count = 4;
  		memset(max_brightness, 255, 3);
  		use_hw_blink[3] = 1;
  		use_ds4_names = 1;
61ebca937   Frank Praznik   HID: sony: Use co...
1676
1677
  		name_len = 0;
  		name_fmt = "%s:%s";
c5e0c1c49   Frank Praznik   HID: sony: Add su...
1678
1679
1680
1681
1682
1683
  	} else if (sc->quirks & MOTION_CONTROLLER) {
  		sc->led_count = 3;
  		memset(max_brightness, 255, 3);
  		use_ds4_names = 1;
  		name_len = 0;
  		name_fmt = "%s:%s";
4545ee0a7   Simon Wood   HID: hid-sony: Na...
1684
  	} else if (sc->quirks & NAVIGATION_CONTROLLER) {
1adf904e9   Pavel Machek   HID: sony: unders...
1685
  		static const u8 navigation_leds[4] = {0x01, 0x00, 0x00, 0x00};
4545ee0a7   Simon Wood   HID: hid-sony: Na...
1686
1687
1688
1689
1690
1691
1692
  
  		memcpy(sc->led_state, navigation_leds, sizeof(navigation_leds));
  		sc->led_count = 1;
  		memset(use_hw_blink, 1, 4);
  		use_ds4_names = 0;
  		name_len = strlen("::sony#");
  		name_fmt = "%s::sony%d";
60781cf48   Frank Praznik   HID: sony: Add LE...
1693
  	} else {
221399b36   Frank Praznik   HID: sony: Simpli...
1694
  		sixaxis_set_leds_from_id(sc);
fa57a8107   Frank Praznik   HID: sony: Conver...
1695
  		sc->led_count = 4;
b3ed458c1   Frank Praznik   HID: sony: Add bl...
1696
1697
  		memset(use_hw_blink, 1, 4);
  		use_ds4_names = 0;
61ebca937   Frank Praznik   HID: sony: Use co...
1698
1699
  		name_len = strlen("::sony#");
  		name_fmt = "%s::sony%d";
60781cf48   Frank Praznik   HID: sony: Add LE...
1700
  	}
ad142b9e4   Frank Praznik   HID: sony: Fix mu...
1701
1702
  	/*
  	 * Clear LEDs as we have no way of reading their initial state. This is
f04d51404   Colin Leitner   HID: driver for P...
1703
  	 * only relevant if the driver is loaded after somebody actively set the
ad142b9e4   Frank Praznik   HID: sony: Fix mu...
1704
1705
  	 * LEDs to on
  	 */
221399b36   Frank Praznik   HID: sony: Simpli...
1706
  	sony_set_leds(sc);
f04d51404   Colin Leitner   HID: driver for P...
1707

0a286ef27   Sven Eckelmann   HID: sony: Add LE...
1708
  	name_sz = strlen(dev_name(&hdev->dev)) + name_len + 1;
f04d51404   Colin Leitner   HID: driver for P...
1709

fa57a8107   Frank Praznik   HID: sony: Conver...
1710
  	for (n = 0; n < sc->led_count; n++) {
61ebca937   Frank Praznik   HID: sony: Use co...
1711

b3ed458c1   Frank Praznik   HID: sony: Add bl...
1712
1713
  		if (use_ds4_names)
  			name_sz = strlen(dev_name(&hdev->dev)) + strlen(ds4_name_str[n]) + 2;
61ebca937   Frank Praznik   HID: sony: Use co...
1714

40e32ee6e   Jiri Kosina   HID: sony: fix le...
1715
1716
1717
1718
  		led = kzalloc(sizeof(struct led_classdev) + name_sz, GFP_KERNEL);
  		if (!led) {
  			hid_err(hdev, "Couldn't allocate memory for LED %d
  ", n);
8cd5fcda2   Julia Lawall   HID: sony: fix er...
1719
  			ret = -ENOMEM;
40e32ee6e   Jiri Kosina   HID: sony: fix le...
1720
1721
  			goto error_leds;
  		}
f04d51404   Colin Leitner   HID: driver for P...
1722

40e32ee6e   Jiri Kosina   HID: sony: fix le...
1723
  		name = (void *)(&led[1]);
b3ed458c1   Frank Praznik   HID: sony: Add bl...
1724
1725
1726
  		if (use_ds4_names)
  			snprintf(name, name_sz, name_fmt, dev_name(&hdev->dev),
  			ds4_name_str[n]);
61ebca937   Frank Praznik   HID: sony: Use co...
1727
1728
  		else
  			snprintf(name, name_sz, name_fmt, dev_name(&hdev->dev), n + 1);
40e32ee6e   Jiri Kosina   HID: sony: fix le...
1729
  		led->name = name;
221399b36   Frank Praznik   HID: sony: Simpli...
1730
  		led->brightness = sc->led_state[n];
b3ed458c1   Frank Praznik   HID: sony: Add bl...
1731
  		led->max_brightness = max_brightness[n];
c53825190   Sven Eckelmann   HID: sony: Rename...
1732
1733
  		led->brightness_get = sony_led_get_brightness;
  		led->brightness_set = sony_led_set_brightness;
f04d51404   Colin Leitner   HID: driver for P...
1734

b3ed458c1   Frank Praznik   HID: sony: Add bl...
1735
1736
  		if (use_hw_blink[n])
  			led->blink_set = sony_led_blink_set;
8025087ac   Frank Praznik   HID: sony: Initia...
1737
  		sc->leds[n] = led;
8cd5fcda2   Julia Lawall   HID: sony: fix er...
1738
1739
  		ret = led_classdev_register(&hdev->dev, led);
  		if (ret) {
40e32ee6e   Jiri Kosina   HID: sony: fix le...
1740
1741
  			hid_err(hdev, "Failed to register LED %d
  ", n);
8025087ac   Frank Praznik   HID: sony: Initia...
1742
  			sc->leds[n] = NULL;
40e32ee6e   Jiri Kosina   HID: sony: fix le...
1743
1744
  			kfree(led);
  			goto error_leds;
f04d51404   Colin Leitner   HID: driver for P...
1745
1746
  		}
  	}
f04d51404   Colin Leitner   HID: driver for P...
1747
1748
  
  	return ret;
f04d51404   Colin Leitner   HID: driver for P...
1749
  error_leds:
fa57a8107   Frank Praznik   HID: sony: Conver...
1750
  	sony_leds_remove(sc);
f04d51404   Colin Leitner   HID: driver for P...
1751

f04d51404   Colin Leitner   HID: driver for P...
1752
  	return ret;
f04d51404   Colin Leitner   HID: driver for P...
1753
  }
d8aaccda7   Frank Praznik   HID: sony: Refact...
1754
  static void sixaxis_send_output_report(struct sony_sc *sc)
a08c22c0d   Sven Eckelmann   HID: sony: Add fo...
1755
  {
9b2b5c9a7   Frank Praznik   HID: sony: Use ke...
1756
  	static const union sixaxis_output_report_01 default_report = {
55d3b664d   Frank Praznik   HID: sony: Use a ...
1757
1758
  		.buf = {
  			0x01,
ad07b7a6c   Scott Moreau   HID: sony: Fixup ...
1759
  			0x01, 0xff, 0x00, 0xff, 0x00,
55d3b664d   Frank Praznik   HID: sony: Use a ...
1760
1761
1762
1763
1764
1765
1766
  			0x00, 0x00, 0x00, 0x00, 0x00,
  			0xff, 0x27, 0x10, 0x00, 0x32,
  			0xff, 0x27, 0x10, 0x00, 0x32,
  			0xff, 0x27, 0x10, 0x00, 0x32,
  			0xff, 0x27, 0x10, 0x00, 0x32,
  			0x00, 0x00, 0x00, 0x00, 0x00
  		}
a08c22c0d   Sven Eckelmann   HID: sony: Add fo...
1767
  	};
9b2b5c9a7   Frank Praznik   HID: sony: Use ke...
1768
1769
1770
1771
1772
1773
  	struct sixaxis_output_report *report =
  		(struct sixaxis_output_report *)sc->output_report_dmabuf;
  	int n;
  
  	/* Initialize the report with default values */
  	memcpy(report, &default_report, sizeof(struct sixaxis_output_report));
9f323b681   Sven Eckelmann   HID: sony: Send F...
1774

0a286ef27   Sven Eckelmann   HID: sony: Add LE...
1775
  #ifdef CONFIG_SONY_FF
9b2b5c9a7   Frank Praznik   HID: sony: Use ke...
1776
1777
  	report->rumble.right_motor_on = sc->right ? 1 : 0;
  	report->rumble.left_motor_force = sc->left;
0a286ef27   Sven Eckelmann   HID: sony: Add LE...
1778
  #endif
9b2b5c9a7   Frank Praznik   HID: sony: Use ke...
1779
1780
1781
1782
  	report->leds_bitmap |= sc->led_state[0] << 1;
  	report->leds_bitmap |= sc->led_state[1] << 2;
  	report->leds_bitmap |= sc->led_state[2] << 3;
  	report->leds_bitmap |= sc->led_state[3] << 4;
9f323b681   Sven Eckelmann   HID: sony: Send F...
1783

88f6576fa   Simon Wood   HID: hid-sony - a...
1784
  	/* Set flag for all leds off, required for 3rd party INTEC controller */
9b2b5c9a7   Frank Praznik   HID: sony: Use ke...
1785
1786
  	if ((report->leds_bitmap & 0x1E) == 0)
  		report->leds_bitmap |= 0x20;
88f6576fa   Simon Wood   HID: hid-sony - a...
1787

b3ed458c1   Frank Praznik   HID: sony: Add bl...
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
  	/*
  	 * The LEDs in the report are indexed in reverse order to their
  	 * corresponding light on the controller.
  	 * Index 0 = LED 4, index 1 = LED 3, etc...
  	 *
  	 * In the case of both delay values being zero (blinking disabled) the
  	 * default report values should be used or the controller LED will be
  	 * always off.
  	 */
  	for (n = 0; n < 4; n++) {
  		if (sc->led_delay_on[n] || sc->led_delay_off[n]) {
9b2b5c9a7   Frank Praznik   HID: sony: Use ke...
1799
1800
  			report->led[3 - n].duty_off = sc->led_delay_off[n];
  			report->led[3 - n].duty_on = sc->led_delay_on[n];
b3ed458c1   Frank Praznik   HID: sony: Add bl...
1801
1802
  		}
  	}
1adf904e9   Pavel Machek   HID: sony: unders...
1803
  	hid_hw_raw_request(sc->hdev, report->report_id, (u8 *)report,
9b2b5c9a7   Frank Praznik   HID: sony: Use ke...
1804
1805
  			sizeof(struct sixaxis_output_report),
  			HID_OUTPUT_REPORT, HID_REQ_SET_REPORT);
9f323b681   Sven Eckelmann   HID: sony: Send F...
1806
  }
d8aaccda7   Frank Praznik   HID: sony: Refact...
1807
  static void dualshock4_send_output_report(struct sony_sc *sc)
0bd88dd3d   Frank Praznik   HID: sony: Add fo...
1808
  {
0da8ea658   Frank Praznik   HID: sony: Use st...
1809
  	struct hid_device *hdev = sc->hdev;
1adf904e9   Pavel Machek   HID: sony: unders...
1810
  	u8 *buf = sc->output_report_dmabuf;
48220237b   Frank Praznik   HID: sony: Use lo...
1811
  	int offset;
fdcf105d3   Frank Praznik   HID: sony: Add Du...
1812
  	if (sc->quirks & DUALSHOCK4_CONTROLLER_USB) {
9b2b5c9a7   Frank Praznik   HID: sony: Use ke...
1813
  		memset(buf, 0, DS4_REPORT_0x05_SIZE);
fdcf105d3   Frank Praznik   HID: sony: Add Du...
1814
  		buf[0] = 0x05;
b3ed458c1   Frank Praznik   HID: sony: Add bl...
1815
  		buf[1] = 0xFF;
fdcf105d3   Frank Praznik   HID: sony: Add Du...
1816
1817
  		offset = 4;
  	} else {
9b2b5c9a7   Frank Praznik   HID: sony: Use ke...
1818
  		memset(buf, 0, DS4_REPORT_0x11_SIZE);
fdcf105d3   Frank Praznik   HID: sony: Add Du...
1819
  		buf[0] = 0x11;
824deff87   Rostislav Pehlivanov   HID: sony: Fix DS...
1820
  		buf[1] = 0x80;
fdcf105d3   Frank Praznik   HID: sony: Add Du...
1821
1822
1823
  		buf[3] = 0x0F;
  		offset = 6;
  	}
0bd88dd3d   Frank Praznik   HID: sony: Add fo...
1824
1825
  
  #ifdef CONFIG_SONY_FF
48220237b   Frank Praznik   HID: sony: Use lo...
1826
1827
1828
1829
  	buf[offset++] = sc->right;
  	buf[offset++] = sc->left;
  #else
  	offset += 2;
0bd88dd3d   Frank Praznik   HID: sony: Add fo...
1830
  #endif
b3ed458c1   Frank Praznik   HID: sony: Add bl...
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
  	/* LED 3 is the global control */
  	if (sc->led_state[3]) {
  		buf[offset++] = sc->led_state[0];
  		buf[offset++] = sc->led_state[1];
  		buf[offset++] = sc->led_state[2];
  	} else {
  		offset += 3;
  	}
  
  	/* If both delay values are zero the DualShock 4 disables blinking. */
  	buf[offset++] = sc->led_delay_on[3];
  	buf[offset++] = sc->led_delay_off[3];
60781cf48   Frank Praznik   HID: sony: Add LE...
1843

fdcf105d3   Frank Praznik   HID: sony: Add Du...
1844
  	if (sc->quirks & DUALSHOCK4_CONTROLLER_USB)
9b2b5c9a7   Frank Praznik   HID: sony: Use ke...
1845
  		hid_hw_output_report(hdev, buf, DS4_REPORT_0x05_SIZE);
fdcf105d3   Frank Praznik   HID: sony: Add Du...
1846
  	else
9b2b5c9a7   Frank Praznik   HID: sony: Use ke...
1847
  		hid_hw_raw_request(hdev, 0x11, buf, DS4_REPORT_0x11_SIZE,
fdcf105d3   Frank Praznik   HID: sony: Add Du...
1848
  				HID_OUTPUT_REPORT, HID_REQ_SET_REPORT);
0bd88dd3d   Frank Praznik   HID: sony: Add fo...
1849
  }
d8aaccda7   Frank Praznik   HID: sony: Refact...
1850
  static void motion_send_output_report(struct sony_sc *sc)
c5e0c1c49   Frank Praznik   HID: sony: Add su...
1851
  {
c5e0c1c49   Frank Praznik   HID: sony: Add su...
1852
1853
1854
  	struct hid_device *hdev = sc->hdev;
  	struct motion_output_report_02 *report =
  		(struct motion_output_report_02 *)sc->output_report_dmabuf;
41d2d4253   Simon Wood   HID: sony: PS3 Mo...
1855
  	memset(report, 0, MOTION_REPORT_0x02_SIZE);
c5e0c1c49   Frank Praznik   HID: sony: Add su...
1856
1857
1858
1859
1860
1861
1862
1863
1864
  
  	report->type = 0x02; /* set leds */
  	report->r = sc->led_state[0];
  	report->g = sc->led_state[1];
  	report->b = sc->led_state[2];
  
  #ifdef CONFIG_SONY_FF
  	report->rumble = max(sc->right, sc->left);
  #endif
1adf904e9   Pavel Machek   HID: sony: unders...
1865
  	hid_hw_output_report(hdev, (u8 *)report, MOTION_REPORT_0x02_SIZE);
c5e0c1c49   Frank Praznik   HID: sony: Add su...
1866
  }
decd946c9   Frank Praznik   HID: sony: Save a...
1867
1868
1869
1870
1871
  static inline void sony_send_output_report(struct sony_sc *sc)
  {
  	if (sc->send_output_report)
  		sc->send_output_report(sc);
  }
d8aaccda7   Frank Praznik   HID: sony: Refact...
1872
1873
1874
  static void sony_state_worker(struct work_struct *work)
  {
  	struct sony_sc *sc = container_of(work, struct sony_sc, state_worker);
ef916ef5e   Antonio Ospite   HID: sony: fix so...
1875

d8aaccda7   Frank Praznik   HID: sony: Refact...
1876
1877
  	sc->send_output_report(sc);
  }
9b2b5c9a7   Frank Praznik   HID: sony: Use ke...
1878
1879
  static int sony_allocate_output_report(struct sony_sc *sc)
  {
4545ee0a7   Simon Wood   HID: hid-sony: Na...
1880
1881
  	if ((sc->quirks & SIXAXIS_CONTROLLER) ||
  			(sc->quirks & NAVIGATION_CONTROLLER))
9b2b5c9a7   Frank Praznik   HID: sony: Use ke...
1882
1883
1884
1885
1886
1887
1888
1889
1890
  		sc->output_report_dmabuf =
  			kmalloc(sizeof(union sixaxis_output_report_01),
  				GFP_KERNEL);
  	else if (sc->quirks & DUALSHOCK4_CONTROLLER_BT)
  		sc->output_report_dmabuf = kmalloc(DS4_REPORT_0x11_SIZE,
  						GFP_KERNEL);
  	else if (sc->quirks & DUALSHOCK4_CONTROLLER_USB)
  		sc->output_report_dmabuf = kmalloc(DS4_REPORT_0x05_SIZE,
  						GFP_KERNEL);
c5e0c1c49   Frank Praznik   HID: sony: Add su...
1891
  	else if (sc->quirks & MOTION_CONTROLLER)
41d2d4253   Simon Wood   HID: sony: PS3 Mo...
1892
1893
  		sc->output_report_dmabuf = kmalloc(MOTION_REPORT_0x02_SIZE,
  						GFP_KERNEL);
9b2b5c9a7   Frank Praznik   HID: sony: Use ke...
1894
1895
1896
1897
1898
1899
1900
1901
  	else
  		return 0;
  
  	if (!sc->output_report_dmabuf)
  		return -ENOMEM;
  
  	return 0;
  }
0a286ef27   Sven Eckelmann   HID: sony: Add LE...
1902
  #ifdef CONFIG_SONY_FF
9f323b681   Sven Eckelmann   HID: sony: Send F...
1903
1904
1905
  static int sony_play_effect(struct input_dev *dev, void *data,
  			    struct ff_effect *effect)
  {
a08c22c0d   Sven Eckelmann   HID: sony: Add fo...
1906
  	struct hid_device *hid = input_get_drvdata(dev);
9f323b681   Sven Eckelmann   HID: sony: Send F...
1907
  	struct sony_sc *sc = hid_get_drvdata(hid);
a08c22c0d   Sven Eckelmann   HID: sony: Add fo...
1908
1909
1910
  
  	if (effect->type != FF_RUMBLE)
  		return 0;
9f323b681   Sven Eckelmann   HID: sony: Send F...
1911
  	sc->left = effect->u.rumble.strong_magnitude / 256;
0bd88dd3d   Frank Praznik   HID: sony: Add fo...
1912
  	sc->right = effect->u.rumble.weak_magnitude / 256;
a08c22c0d   Sven Eckelmann   HID: sony: Add fo...
1913

92b5c411a   Sven Eckelmann   HID: sony: Rename...
1914
  	schedule_work(&sc->state_worker);
9f323b681   Sven Eckelmann   HID: sony: Send F...
1915
  	return 0;
a08c22c0d   Sven Eckelmann   HID: sony: Add fo...
1916
  }
fa57a8107   Frank Praznik   HID: sony: Conver...
1917
  static int sony_init_ff(struct sony_sc *sc)
a08c22c0d   Sven Eckelmann   HID: sony: Add fo...
1918
  {
fa57a8107   Frank Praznik   HID: sony: Conver...
1919
  	struct hid_input *hidinput = list_entry(sc->hdev->inputs.next,
a08c22c0d   Sven Eckelmann   HID: sony: Add fo...
1920
1921
1922
1923
1924
1925
1926
1927
  						struct hid_input, list);
  	struct input_dev *input_dev = hidinput->input;
  
  	input_set_capability(input_dev, EV_FF, FF_RUMBLE);
  	return input_ff_create_memless(input_dev, NULL, sony_play_effect);
  }
  
  #else
fa57a8107   Frank Praznik   HID: sony: Conver...
1928
  static int sony_init_ff(struct sony_sc *sc)
a08c22c0d   Sven Eckelmann   HID: sony: Add fo...
1929
1930
1931
  {
  	return 0;
  }
9f323b681   Sven Eckelmann   HID: sony: Send F...
1932

a08c22c0d   Sven Eckelmann   HID: sony: Add fo...
1933
  #endif
d902f4724   Frank Praznik   HID: sony: add ba...
1934
1935
1936
1937
  static int sony_battery_get_property(struct power_supply *psy,
  				     enum power_supply_property psp,
  				     union power_supply_propval *val)
  {
297d716f6   Krzysztof Kozlowski   power_supply: Cha...
1938
  	struct sony_sc *sc = power_supply_get_drvdata(psy);
d902f4724   Frank Praznik   HID: sony: add ba...
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
  	unsigned long flags;
  	int ret = 0;
  	u8 battery_charging, battery_capacity, cable_state;
  
  	spin_lock_irqsave(&sc->lock, flags);
  	battery_charging = sc->battery_charging;
  	battery_capacity = sc->battery_capacity;
  	cable_state = sc->cable_state;
  	spin_unlock_irqrestore(&sc->lock, flags);
  
  	switch (psp) {
  	case POWER_SUPPLY_PROP_PRESENT:
  		val->intval = 1;
  		break;
  	case POWER_SUPPLY_PROP_SCOPE:
  		val->intval = POWER_SUPPLY_SCOPE_DEVICE;
  		break;
  	case POWER_SUPPLY_PROP_CAPACITY:
  		val->intval = battery_capacity;
  		break;
  	case POWER_SUPPLY_PROP_STATUS:
  		if (battery_charging)
  			val->intval = POWER_SUPPLY_STATUS_CHARGING;
  		else
  			if (battery_capacity == 100 && cable_state)
  				val->intval = POWER_SUPPLY_STATUS_FULL;
  			else
  				val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
  		break;
  	default:
  		ret = -EINVAL;
  		break;
  	}
  	return ret;
9f323b681   Sven Eckelmann   HID: sony: Send F...
1973
  }
d902f4724   Frank Praznik   HID: sony: add ba...
1974
  static int sony_battery_probe(struct sony_sc *sc)
c4e1ddf26   Frank Praznik   HID: sony: Cache ...
1975
  {
297d716f6   Krzysztof Kozlowski   power_supply: Cha...
1976
  	struct power_supply_config psy_cfg = { .drv_data = sc, };
c4e1ddf26   Frank Praznik   HID: sony: Cache ...
1977
  	struct hid_device *hdev = sc->hdev;
d902f4724   Frank Praznik   HID: sony: add ba...
1978
  	int ret;
c4e1ddf26   Frank Praznik   HID: sony: Cache ...
1979

ad142b9e4   Frank Praznik   HID: sony: Fix mu...
1980
1981
  	/*
  	 * Set the default battery level to 100% to avoid low battery warnings
d9a293a95   Frank Praznik   HID: sony: Set in...
1982
1983
1984
  	 * if the battery is polled before the first device report is received.
  	 */
  	sc->battery_capacity = 100;
297d716f6   Krzysztof Kozlowski   power_supply: Cha...
1985
1986
1987
1988
1989
1990
1991
1992
1993
  	sc->battery_desc.properties = sony_battery_props;
  	sc->battery_desc.num_properties = ARRAY_SIZE(sony_battery_props);
  	sc->battery_desc.get_property = sony_battery_get_property;
  	sc->battery_desc.type = POWER_SUPPLY_TYPE_BATTERY;
  	sc->battery_desc.use_for_apm = 0;
  	sc->battery_desc.name = kasprintf(GFP_KERNEL,
  					  "sony_controller_battery_%pMR",
  					  sc->mac_address);
  	if (!sc->battery_desc.name)
d902f4724   Frank Praznik   HID: sony: add ba...
1994
  		return -ENOMEM;
c4e1ddf26   Frank Praznik   HID: sony: Cache ...
1995

297d716f6   Krzysztof Kozlowski   power_supply: Cha...
1996
1997
1998
1999
  	sc->battery = power_supply_register(&hdev->dev, &sc->battery_desc,
  					    &psy_cfg);
  	if (IS_ERR(sc->battery)) {
  		ret = PTR_ERR(sc->battery);
d902f4724   Frank Praznik   HID: sony: add ba...
2000
2001
2002
2003
  		hid_err(hdev, "Unable to register battery device
  ");
  		goto err_free;
  	}
c4e1ddf26   Frank Praznik   HID: sony: Cache ...
2004

297d716f6   Krzysztof Kozlowski   power_supply: Cha...
2005
  	power_supply_powers(sc->battery, &hdev->dev);
a08c22c0d   Sven Eckelmann   HID: sony: Add fo...
2006
  	return 0;
d902f4724   Frank Praznik   HID: sony: add ba...
2007
2008
  
  err_free:
297d716f6   Krzysztof Kozlowski   power_supply: Cha...
2009
2010
  	kfree(sc->battery_desc.name);
  	sc->battery_desc.name = NULL;
d902f4724   Frank Praznik   HID: sony: add ba...
2011
  	return ret;
a08c22c0d   Sven Eckelmann   HID: sony: Add fo...
2012
  }
9f323b681   Sven Eckelmann   HID: sony: Send F...
2013

d902f4724   Frank Praznik   HID: sony: add ba...
2014
  static void sony_battery_remove(struct sony_sc *sc)
9f323b681   Sven Eckelmann   HID: sony: Send F...
2015
  {
297d716f6   Krzysztof Kozlowski   power_supply: Cha...
2016
  	if (!sc->battery_desc.name)
d902f4724   Frank Praznik   HID: sony: add ba...
2017
  		return;
297d716f6   Krzysztof Kozlowski   power_supply: Cha...
2018
2019
2020
  	power_supply_unregister(sc->battery);
  	kfree(sc->battery_desc.name);
  	sc->battery_desc.name = NULL;
9f323b681   Sven Eckelmann   HID: sony: Send F...
2021
  }
a08c22c0d   Sven Eckelmann   HID: sony: Add fo...
2022

d2d782fcc   Frank Praznik   HID: sony: Preven...
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
  /*
   * If a controller is plugged in via USB while already connected via Bluetooth
   * it will show up as two devices. A global list of connected controllers and
   * their MAC addresses is maintained to ensure that a device is only connected
   * once.
   */
  static int sony_check_add_dev_list(struct sony_sc *sc)
  {
  	struct sony_sc *entry;
  	unsigned long flags;
  	int ret;
  
  	spin_lock_irqsave(&sony_dev_list_lock, flags);
  
  	list_for_each_entry(entry, &sony_device_list, list_node) {
  		ret = memcmp(sc->mac_address, entry->mac_address,
  				sizeof(sc->mac_address));
  		if (!ret) {
  			ret = -EEXIST;
  			hid_info(sc->hdev, "controller with MAC address %pMR already connected
  ",
  				sc->mac_address);
  			goto unlock;
c4e1ddf26   Frank Praznik   HID: sony: Cache ...
2046
2047
  		}
  	}
d2d782fcc   Frank Praznik   HID: sony: Preven...
2048
2049
  	ret = 0;
  	list_add(&(sc->list_node), &sony_device_list);
c4e1ddf26   Frank Praznik   HID: sony: Cache ...
2050

d2d782fcc   Frank Praznik   HID: sony: Preven...
2051
2052
2053
2054
2055
2056
2057
2058
  unlock:
  	spin_unlock_irqrestore(&sony_dev_list_lock, flags);
  	return ret;
  }
  
  static void sony_remove_dev_list(struct sony_sc *sc)
  {
  	unsigned long flags;
c4e1ddf26   Frank Praznik   HID: sony: Cache ...
2059

d2d782fcc   Frank Praznik   HID: sony: Preven...
2060
2061
2062
2063
2064
  	if (sc->list_node.next) {
  		spin_lock_irqsave(&sony_dev_list_lock, flags);
  		list_del(&(sc->list_node));
  		spin_unlock_irqrestore(&sony_dev_list_lock, flags);
  	}
c4e1ddf26   Frank Praznik   HID: sony: Cache ...
2065
  }
d2d782fcc   Frank Praznik   HID: sony: Preven...
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
  static int sony_get_bt_devaddr(struct sony_sc *sc)
  {
  	int ret;
  
  	/* HIDP stores the device MAC address as a string in the uniq field. */
  	ret = strlen(sc->hdev->uniq);
  	if (ret != 17)
  		return -EINVAL;
  
  	ret = sscanf(sc->hdev->uniq,
  		"%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
  		&sc->mac_address[5], &sc->mac_address[4], &sc->mac_address[3],
  		&sc->mac_address[2], &sc->mac_address[1], &sc->mac_address[0]);
  
  	if (ret != 6)
  		return -EINVAL;
  
  	return 0;
  }
  
  static int sony_check_add(struct sony_sc *sc)
  {
1adf904e9   Pavel Machek   HID: sony: unders...
2088
  	u8 *buf = NULL;
d2d782fcc   Frank Praznik   HID: sony: Preven...
2089
2090
2091
  	int n, ret;
  
  	if ((sc->quirks & DUALSHOCK4_CONTROLLER_BT) ||
12e9a6d72   Simon Wood   HID: sony: Add su...
2092
  	    (sc->quirks & MOTION_CONTROLLER_BT) ||
4545ee0a7   Simon Wood   HID: hid-sony: Na...
2093
  	    (sc->quirks & NAVIGATION_CONTROLLER_BT) ||
d2d782fcc   Frank Praznik   HID: sony: Preven...
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
  	    (sc->quirks & SIXAXIS_CONTROLLER_BT)) {
  		/*
  		 * sony_get_bt_devaddr() attempts to parse the Bluetooth MAC
  		 * address from the uniq string where HIDP stores it.
  		 * As uniq cannot be guaranteed to be a MAC address in all cases
  		 * a failure of this function should not prevent the connection.
  		 */
  		if (sony_get_bt_devaddr(sc) < 0) {
  			hid_warn(sc->hdev, "UNIQ does not contain a MAC address; duplicate check skipped
  ");
  			return 0;
  		}
  	} else if (sc->quirks & DUALSHOCK4_CONTROLLER_USB) {
9b2b5c9a7   Frank Praznik   HID: sony: Use ke...
2107
2108
2109
  		buf = kmalloc(DS4_REPORT_0x81_SIZE, GFP_KERNEL);
  		if (!buf)
  			return -ENOMEM;
d2d782fcc   Frank Praznik   HID: sony: Preven...
2110
2111
2112
2113
2114
2115
  
  		/*
  		 * The MAC address of a DS4 controller connected via USB can be
  		 * retrieved with feature report 0x81. The address begins at
  		 * offset 1.
  		 */
9b2b5c9a7   Frank Praznik   HID: sony: Use ke...
2116
2117
2118
  		ret = hid_hw_raw_request(sc->hdev, 0x81, buf,
  				DS4_REPORT_0x81_SIZE, HID_FEATURE_REPORT,
  				HID_REQ_GET_REPORT);
d2d782fcc   Frank Praznik   HID: sony: Preven...
2119

9b2b5c9a7   Frank Praznik   HID: sony: Use ke...
2120
  		if (ret != DS4_REPORT_0x81_SIZE) {
d2d782fcc   Frank Praznik   HID: sony: Preven...
2121
2122
  			hid_err(sc->hdev, "failed to retrieve feature report 0x81 with the DualShock 4 MAC address
  ");
9b2b5c9a7   Frank Praznik   HID: sony: Use ke...
2123
2124
  			ret = ret < 0 ? ret : -EINVAL;
  			goto out_free;
d2d782fcc   Frank Praznik   HID: sony: Preven...
2125
2126
2127
  		}
  
  		memcpy(sc->mac_address, &buf[1], sizeof(sc->mac_address));
4545ee0a7   Simon Wood   HID: hid-sony: Na...
2128
2129
  	} else if ((sc->quirks & SIXAXIS_CONTROLLER_USB) ||
  			(sc->quirks & NAVIGATION_CONTROLLER_USB)) {
9b2b5c9a7   Frank Praznik   HID: sony: Use ke...
2130
2131
2132
  		buf = kmalloc(SIXAXIS_REPORT_0xF2_SIZE, GFP_KERNEL);
  		if (!buf)
  			return -ENOMEM;
d2d782fcc   Frank Praznik   HID: sony: Preven...
2133
2134
2135
2136
2137
2138
  
  		/*
  		 * The MAC address of a Sixaxis controller connected via USB can
  		 * be retrieved with feature report 0xf2. The address begins at
  		 * offset 4.
  		 */
9b2b5c9a7   Frank Praznik   HID: sony: Use ke...
2139
2140
2141
  		ret = hid_hw_raw_request(sc->hdev, 0xf2, buf,
  				SIXAXIS_REPORT_0xF2_SIZE, HID_FEATURE_REPORT,
  				HID_REQ_GET_REPORT);
d2d782fcc   Frank Praznik   HID: sony: Preven...
2142

9b2b5c9a7   Frank Praznik   HID: sony: Use ke...
2143
  		if (ret != SIXAXIS_REPORT_0xF2_SIZE) {
d2d782fcc   Frank Praznik   HID: sony: Preven...
2144
2145
  			hid_err(sc->hdev, "failed to retrieve feature report 0xf2 with the Sixaxis MAC address
  ");
9b2b5c9a7   Frank Praznik   HID: sony: Use ke...
2146
2147
  			ret = ret < 0 ? ret : -EINVAL;
  			goto out_free;
d2d782fcc   Frank Praznik   HID: sony: Preven...
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
  		}
  
  		/*
  		 * The Sixaxis device MAC in the report is big-endian and must
  		 * be byte-swapped.
  		 */
  		for (n = 0; n < 6; n++)
  			sc->mac_address[5-n] = buf[4+n];
  	} else {
  		return 0;
  	}
9b2b5c9a7   Frank Praznik   HID: sony: Use ke...
2159
2160
2161
2162
2163
2164
2165
  	ret = sony_check_add_dev_list(sc);
  
  out_free:
  
  	kfree(buf);
  
  	return ret;
d2d782fcc   Frank Praznik   HID: sony: Preven...
2166
  }
8025087ac   Frank Praznik   HID: sony: Initia...
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
  static int sony_set_device_id(struct sony_sc *sc)
  {
  	int ret;
  
  	/*
  	 * Only DualShock 4 or Sixaxis controllers get an id.
  	 * All others are set to -1.
  	 */
  	if ((sc->quirks & SIXAXIS_CONTROLLER) ||
  	    (sc->quirks & DUALSHOCK4_CONTROLLER)) {
  		ret = ida_simple_get(&sony_device_id_allocator, 0, 0,
  					GFP_KERNEL);
  		if (ret < 0) {
  			sc->device_id = -1;
  			return ret;
  		}
  		sc->device_id = ret;
  	} else {
  		sc->device_id = -1;
  	}
  
  	return 0;
  }
  
  static void sony_release_device_id(struct sony_sc *sc)
  {
  	if (sc->device_id >= 0) {
  		ida_simple_remove(&sony_device_id_allocator, sc->device_id);
  		sc->device_id = -1;
  	}
  }
d8aaccda7   Frank Praznik   HID: sony: Refact...
2198
  static inline void sony_init_output_report(struct sony_sc *sc,
09593e388   Antonio Ospite   HID: sony: fix er...
2199
  				void (*send_output_report)(struct sony_sc *))
462620474   Frank Praznik   HID: sony: Use in...
2200
  {
d8aaccda7   Frank Praznik   HID: sony: Refact...
2201
  	sc->send_output_report = send_output_report;
462620474   Frank Praznik   HID: sony: Use in...
2202
  	if (!sc->worker_initialized)
d8aaccda7   Frank Praznik   HID: sony: Refact...
2203
  		INIT_WORK(&sc->state_worker, sony_state_worker);
462620474   Frank Praznik   HID: sony: Use in...
2204
2205
2206
2207
2208
2209
2210
2211
2212
  
  	sc->worker_initialized = 1;
  }
  
  static inline void sony_cancel_work_sync(struct sony_sc *sc)
  {
  	if (sc->worker_initialized)
  		cancel_work_sync(&sc->state_worker);
  }
d2d782fcc   Frank Praznik   HID: sony: Preven...
2213

bd28ce008   Jiri Slaby   HID: move sony qu...
2214
2215
2216
  static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
  {
  	int ret;
cc6e0bbb4   Jiri Kosina   HID: Add support ...
2217
2218
  	unsigned long quirks = id->driver_data;
  	struct sony_sc *sc;
f04d51404   Colin Leitner   HID: driver for P...
2219
  	unsigned int connect_mask = HID_CONNECT_DEFAULT;
cc6e0bbb4   Jiri Kosina   HID: Add support ...
2220

abf832bfc   Benjamin Tissoires   HID: trivial devm...
2221
  	sc = devm_kzalloc(&hdev->dev, sizeof(*sc), GFP_KERNEL);
cc6e0bbb4   Jiri Kosina   HID: Add support ...
2222
  	if (sc == NULL) {
4291ee305   Joe Perches   HID: Add and use ...
2223
2224
  		hid_err(hdev, "can't alloc sony descriptor
  ");
cc6e0bbb4   Jiri Kosina   HID: Add support ...
2225
2226
  		return -ENOMEM;
  	}
b94993f6f   Frank Praznik   HID: sony: fix un...
2227
  	spin_lock_init(&sc->lock);
cc6e0bbb4   Jiri Kosina   HID: Add support ...
2228
2229
  	sc->quirks = quirks;
  	hid_set_drvdata(hdev, sc);
0a286ef27   Sven Eckelmann   HID: sony: Add LE...
2230
  	sc->hdev = hdev;
bd28ce008   Jiri Slaby   HID: move sony qu...
2231

bd28ce008   Jiri Slaby   HID: move sony qu...
2232
2233
  	ret = hid_parse(hdev);
  	if (ret) {
4291ee305   Joe Perches   HID: Add and use ...
2234
2235
  		hid_err(hdev, "parse failed
  ");
abf832bfc   Benjamin Tissoires   HID: trivial devm...
2236
  		return ret;
bd28ce008   Jiri Slaby   HID: move sony qu...
2237
  	}
f04d51404   Colin Leitner   HID: driver for P...
2238
2239
  	if (sc->quirks & VAIO_RDESC_CONSTANT)
  		connect_mask |= HID_CONNECT_HIDDEV_FORCE;
50764650c   Antonio Ospite   HID: sony: Use th...
2240
  	else if (sc->quirks & SIXAXIS_CONTROLLER)
f04d51404   Colin Leitner   HID: driver for P...
2241
2242
2243
  		connect_mask |= HID_CONNECT_HIDDEV_FORCE;
  
  	ret = hid_hw_start(hdev, connect_mask);
bd28ce008   Jiri Slaby   HID: move sony qu...
2244
  	if (ret) {
4291ee305   Joe Perches   HID: Add and use ...
2245
2246
  		hid_err(hdev, "hw start failed
  ");
abf832bfc   Benjamin Tissoires   HID: trivial devm...
2247
  		return ret;
bd28ce008   Jiri Slaby   HID: move sony qu...
2248
  	}
131a8a9a5   Frank Praznik   HID: sony: Preven...
2249
  	ret = sony_set_device_id(sc);
9b2b5c9a7   Frank Praznik   HID: sony: Use ke...
2250
  	if (ret < 0) {
131a8a9a5   Frank Praznik   HID: sony: Preven...
2251
2252
  		hid_err(hdev, "failed to allocate the device id
  ");
9b2b5c9a7   Frank Praznik   HID: sony: Use ke...
2253
2254
  		goto err_stop;
  	}
131a8a9a5   Frank Praznik   HID: sony: Preven...
2255
  	ret = sony_allocate_output_report(sc);
8025087ac   Frank Praznik   HID: sony: Initia...
2256
  	if (ret < 0) {
131a8a9a5   Frank Praznik   HID: sony: Preven...
2257
2258
  		hid_err(hdev, "failed to allocate the output report buffer
  ");
8025087ac   Frank Praznik   HID: sony: Initia...
2259
2260
  		goto err_stop;
  	}
4545ee0a7   Simon Wood   HID: hid-sony: Na...
2261
2262
  	if ((sc->quirks & SIXAXIS_CONTROLLER_USB) ||
  			(sc->quirks & NAVIGATION_CONTROLLER_USB)) {
e534a9352   Benjamin Tissoires   HID: sony: do not...
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
  		/*
  		 * The Sony Sixaxis does not handle HID Output Reports on the
  		 * Interrupt EP like it could, so we need to force HID Output
  		 * Reports to use HID_REQ_SET_REPORT on the Control EP.
  		 *
  		 * There is also another issue about HID Output Reports via USB,
  		 * the Sixaxis does not want the report_id as part of the data
  		 * packet, so we have to discard buf[0] when sending the actual
  		 * control message, even for numbered reports, humpf!
  		 */
  		hdev->quirks |= HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP;
  		hdev->quirks |= HID_QUIRK_SKIP_OUTPUT_REPORT_ID;
816651a7d   Antonio Ospite   HID: sony: Apply ...
2275
  		ret = sixaxis_set_operational_usb(hdev);
d8aaccda7   Frank Praznik   HID: sony: Refact...
2276
  		sony_init_output_report(sc, sixaxis_send_output_report);
4545ee0a7   Simon Wood   HID: hid-sony: Na...
2277
2278
  	} else if ((sc->quirks & SIXAXIS_CONTROLLER_BT) ||
  			(sc->quirks & NAVIGATION_CONTROLLER_BT)) {
2078b9bb2   Frank Praznik   HID: sony: Set th...
2279
2280
2281
2282
2283
  		/*
  		 * The Sixaxis wants output reports sent on the ctrl endpoint
  		 * when connected via Bluetooth.
  		 */
  		hdev->quirks |= HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP;
816651a7d   Antonio Ospite   HID: sony: Apply ...
2284
  		ret = sixaxis_set_operational_bt(hdev);
d8aaccda7   Frank Praznik   HID: sony: Refact...
2285
  		sony_init_output_report(sc, sixaxis_send_output_report);
fee4e2d52   Frank Praznik   HID: sony: Enable...
2286
  	} else if (sc->quirks & DUALSHOCK4_CONTROLLER) {
68330d83c   Frank Praznik   HID: sony: Add co...
2287
  		if (sc->quirks & DUALSHOCK4_CONTROLLER_BT) {
2078b9bb2   Frank Praznik   HID: sony: Set th...
2288
2289
2290
2291
2292
  			/*
  			 * The DualShock 4 wants output reports sent on the ctrl
  			 * endpoint when connected via Bluetooth.
  			 */
  			hdev->quirks |= HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP;
68330d83c   Frank Praznik   HID: sony: Add co...
2293
2294
2295
2296
2297
2298
2299
  			ret = dualshock4_set_operational_bt(hdev);
  			if (ret < 0) {
  				hid_err(hdev, "failed to set the Dualshock 4 operational mode
  ");
  				goto err_stop;
  			}
  		}
c4e1ddf26   Frank Praznik   HID: sony: Cache ...
2300

d8aaccda7   Frank Praznik   HID: sony: Refact...
2301
  		sony_init_output_report(sc, dualshock4_send_output_report);
c5e0c1c49   Frank Praznik   HID: sony: Add su...
2302
  	} else if (sc->quirks & MOTION_CONTROLLER) {
d8aaccda7   Frank Praznik   HID: sony: Refact...
2303
  		sony_init_output_report(sc, motion_send_output_report);
0bd88dd3d   Frank Praznik   HID: sony: Add fo...
2304
2305
2306
  	} else {
  		ret = 0;
  	}
f9ce7c283   Bastien Nocera   HID: Enable Sixax...
2307

4dfdc4646   Jiri Kosina   HID: fix error co...
2308
  	if (ret < 0)
bd28ce008   Jiri Slaby   HID: move sony qu...
2309
  		goto err_stop;
d2d782fcc   Frank Praznik   HID: sony: Preven...
2310
2311
2312
  	ret = sony_check_add(sc);
  	if (ret < 0)
  		goto err_stop;
0a286ef27   Sven Eckelmann   HID: sony: Add LE...
2313
  	if (sc->quirks & SONY_LED_SUPPORT) {
fa57a8107   Frank Praznik   HID: sony: Conver...
2314
  		ret = sony_leds_init(sc);
0a286ef27   Sven Eckelmann   HID: sony: Add LE...
2315
2316
2317
  		if (ret < 0)
  			goto err_stop;
  	}
d902f4724   Frank Praznik   HID: sony: add ba...
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
  	if (sc->quirks & SONY_BATTERY_SUPPORT) {
  		ret = sony_battery_probe(sc);
  		if (ret < 0)
  			goto err_stop;
  
  		/* Open the device to receive reports with battery info */
  		ret = hid_hw_open(hdev);
  		if (ret < 0) {
  			hid_err(hdev, "hw open failed
  ");
  			goto err_stop;
  		}
  	}
c8de9dbb3   Frank Praznik   HID: sony: Fix wo...
2331
  	if (sc->quirks & SONY_FF_SUPPORT) {
fa57a8107   Frank Praznik   HID: sony: Conver...
2332
  		ret = sony_init_ff(sc);
c8de9dbb3   Frank Praznik   HID: sony: Fix wo...
2333
2334
  		if (ret < 0)
  			goto err_close;
5f5750d2e   Frank Praznik   HID: sony: Fix wo...
2335
  	}
a08c22c0d   Sven Eckelmann   HID: sony: Add fo...
2336

bd28ce008   Jiri Slaby   HID: move sony qu...
2337
  	return 0;
d902f4724   Frank Praznik   HID: sony: add ba...
2338
2339
  err_close:
  	hid_hw_close(hdev);
bd28ce008   Jiri Slaby   HID: move sony qu...
2340
  err_stop:
0a286ef27   Sven Eckelmann   HID: sony: Add LE...
2341
  	if (sc->quirks & SONY_LED_SUPPORT)
fa57a8107   Frank Praznik   HID: sony: Conver...
2342
  		sony_leds_remove(sc);
d902f4724   Frank Praznik   HID: sony: add ba...
2343
2344
  	if (sc->quirks & SONY_BATTERY_SUPPORT)
  		sony_battery_remove(sc);
462620474   Frank Praznik   HID: sony: Use in...
2345
  	sony_cancel_work_sync(sc);
9b2b5c9a7   Frank Praznik   HID: sony: Use ke...
2346
  	kfree(sc->output_report_dmabuf);
d2d782fcc   Frank Praznik   HID: sony: Preven...
2347
  	sony_remove_dev_list(sc);
8025087ac   Frank Praznik   HID: sony: Initia...
2348
  	sony_release_device_id(sc);
bd28ce008   Jiri Slaby   HID: move sony qu...
2349
  	hid_hw_stop(hdev);
bd28ce008   Jiri Slaby   HID: move sony qu...
2350
2351
  	return ret;
  }
cc6e0bbb4   Jiri Kosina   HID: Add support ...
2352
2353
  static void sony_remove(struct hid_device *hdev)
  {
f04d51404   Colin Leitner   HID: driver for P...
2354
  	struct sony_sc *sc = hid_get_drvdata(hdev);
0a286ef27   Sven Eckelmann   HID: sony: Add LE...
2355
  	if (sc->quirks & SONY_LED_SUPPORT)
fa57a8107   Frank Praznik   HID: sony: Conver...
2356
  		sony_leds_remove(sc);
f04d51404   Colin Leitner   HID: driver for P...
2357

d902f4724   Frank Praznik   HID: sony: add ba...
2358
2359
2360
2361
  	if (sc->quirks & SONY_BATTERY_SUPPORT) {
  		hid_hw_close(hdev);
  		sony_battery_remove(sc);
  	}
462620474   Frank Praznik   HID: sony: Use in...
2362
  	sony_cancel_work_sync(sc);
9f323b681   Sven Eckelmann   HID: sony: Send F...
2363

9b2b5c9a7   Frank Praznik   HID: sony: Use ke...
2364
  	kfree(sc->output_report_dmabuf);
d2d782fcc   Frank Praznik   HID: sony: Preven...
2365
  	sony_remove_dev_list(sc);
9f323b681   Sven Eckelmann   HID: sony: Send F...
2366

8025087ac   Frank Praznik   HID: sony: Initia...
2367
  	sony_release_device_id(sc);
cc6e0bbb4   Jiri Kosina   HID: Add support ...
2368
  	hid_hw_stop(hdev);
cc6e0bbb4   Jiri Kosina   HID: Add support ...
2369
  }
decd946c9   Frank Praznik   HID: sony: Save a...
2370
2371
2372
2373
2374
2375
2376
  #ifdef CONFIG_PM
  
  static int sony_suspend(struct hid_device *hdev, pm_message_t message)
  {
  	/*
  	 * On suspend save the current LED state,
  	 * stop running force-feedback and blank the LEDS.
09593e388   Antonio Ospite   HID: sony: fix er...
2377
  	 */
decd946c9   Frank Praznik   HID: sony: Save a...
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
  	if (SONY_LED_SUPPORT || SONY_FF_SUPPORT) {
  		struct sony_sc *sc = hid_get_drvdata(hdev);
  
  #ifdef CONFIG_SONY_FF
  		sc->left = sc->right = 0;
  #endif
  
  		memcpy(sc->resume_led_state, sc->led_state,
  			sizeof(sc->resume_led_state));
  		memset(sc->led_state, 0, sizeof(sc->led_state));
  
  		sony_send_output_report(sc);
  	}
  
  	return 0;
  }
  
  static int sony_resume(struct hid_device *hdev)
  {
  	/* Restore the state of controller LEDs on resume */
  	if (SONY_LED_SUPPORT) {
  		struct sony_sc *sc = hid_get_drvdata(hdev);
  
  		memcpy(sc->led_state, sc->resume_led_state,
  			sizeof(sc->led_state));
  
  		/*
  		 * The Sixaxis and navigation controllers on USB need to be
  		 * reinitialized on resume or they won't behave properly.
  		 */
  		if ((sc->quirks & SIXAXIS_CONTROLLER_USB) ||
  			(sc->quirks & NAVIGATION_CONTROLLER_USB))
  			sixaxis_set_operational_usb(sc->hdev);
  
  		sony_set_leds(sc);
  	}
  
  	return 0;
  }
  
  #endif
bd28ce008   Jiri Slaby   HID: move sony qu...
2419
  static const struct hid_device_id sony_devices[] = {
816651a7d   Antonio Ospite   HID: sony: Apply ...
2420
2421
  	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER),
  		.driver_data = SIXAXIS_CONTROLLER_USB },
35dca5b4a   Jiri Kosina   HID: add support ...
2422
  	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER),
4545ee0a7   Simon Wood   HID: hid-sony: Na...
2423
  		.driver_data = NAVIGATION_CONTROLLER_USB },
6eabaaa09   Simon Wood   HID: hid-sony: Ad...
2424
  	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER),
4545ee0a7   Simon Wood   HID: hid-sony: Na...
2425
  		.driver_data = NAVIGATION_CONTROLLER_BT },
c5e0c1c49   Frank Praznik   HID: sony: Add su...
2426
  	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_MOTION_CONTROLLER),
b3bca326f   Simon Wood   HID: sony: Add qu...
2427
  		.driver_data = MOTION_CONTROLLER_USB },
a4afa8544   Simon Wood   HID: sony: Suppor...
2428
  	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_MOTION_CONTROLLER),
b3bca326f   Simon Wood   HID: sony: Add qu...
2429
  		.driver_data = MOTION_CONTROLLER_BT },
816651a7d   Antonio Ospite   HID: sony: Apply ...
2430
2431
  	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER),
  		.driver_data = SIXAXIS_CONTROLLER_BT },
cc6e0bbb4   Jiri Kosina   HID: Add support ...
2432
2433
  	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE),
  		.driver_data = VAIO_RDESC_CONSTANT },
a46491841   Fernando Luis Vázquez Cao   HID: add support ...
2434
2435
  	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGP_MOUSE),
  		.driver_data = VAIO_RDESC_CONSTANT },
ef916ef5e   Antonio Ospite   HID: sony: fix so...
2436
2437
2438
2439
  	/*
  	 * Wired Buzz Controller. Reported as Sony Hub from its USB ID and as
  	 * Logitech joystick from the device descriptor.
  	 */
f04d51404   Colin Leitner   HID: driver for P...
2440
2441
2442
2443
  	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_BUZZ_CONTROLLER),
  		.driver_data = BUZZ_CONTROLLER },
  	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_WIRELESS_BUZZ_CONTROLLER),
  		.driver_data = BUZZ_CONTROLLER },
078328da5   Jiri Kosina   HID: fold ps3remo...
2444
2445
2446
2447
2448
2449
  	/* PS3 BD Remote Control */
  	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_BDREMOTE),
  		.driver_data = PS3REMOTE },
  	/* Logitech Harmony Adapter for PS3 */
  	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_PS3),
  		.driver_data = PS3REMOTE },
68a49e51a   Frank Praznik   HID: sony: Add su...
2450
2451
2452
  	/* SMK-Link PS3 BD Remote Control */
  	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SMK, USB_DEVICE_ID_SMK_PS3_BDREMOTE),
  		.driver_data = PS3REMOTE },
0bd88dd3d   Frank Praznik   HID: sony: Add fo...
2453
2454
  	/* Sony Dualshock 4 controllers for PS4 */
  	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER),
8ab1676b6   Frank Praznik   HID: sony: Use se...
2455
  		.driver_data = DUALSHOCK4_CONTROLLER_USB },
0bd88dd3d   Frank Praznik   HID: sony: Add fo...
2456
  	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER),
8ab1676b6   Frank Praznik   HID: sony: Use se...
2457
  		.driver_data = DUALSHOCK4_CONTROLLER_BT },
74500cc85   Scott Moreau   HID: sony: Add ny...
2458
2459
2460
  	/* Nyko Core Controller for PS3 */
  	{ HID_USB_DEVICE(USB_VENDOR_ID_SINO_LITE, USB_DEVICE_ID_SINO_LITE_CONTROLLER),
  		.driver_data = SIXAXIS_CONTROLLER_USB | SINO_LITE_CONTROLLER },
bd28ce008   Jiri Slaby   HID: move sony qu...
2461
2462
2463
2464
2465
  	{ }
  };
  MODULE_DEVICE_TABLE(hid, sony_devices);
  
  static struct hid_driver sony_driver = {
ce8efc3b5   Frank Praznik   HID: sony: Set to...
2466
2467
2468
2469
2470
2471
2472
  	.name             = "sony",
  	.id_table         = sony_devices,
  	.input_mapping    = sony_mapping,
  	.input_configured = sony_input_configured,
  	.probe            = sony_probe,
  	.remove           = sony_remove,
  	.report_fixup     = sony_report_fixup,
decd946c9   Frank Praznik   HID: sony: Save a...
2473
2474
2475
2476
2477
2478
2479
  	.raw_event        = sony_raw_event,
  
  #ifdef CONFIG_PM
  	.suspend          = sony_suspend,
  	.resume	          = sony_resume,
  	.reset_resume     = sony_resume,
  #endif
bd28ce008   Jiri Slaby   HID: move sony qu...
2480
  };
8025087ac   Frank Praznik   HID: sony: Initia...
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
  
  static int __init sony_init(void)
  {
  	dbg_hid("Sony:%s
  ", __func__);
  
  	return hid_register_driver(&sony_driver);
  }
  
  static void __exit sony_exit(void)
  {
  	dbg_hid("Sony:%s
  ", __func__);
8025087ac   Frank Praznik   HID: sony: Initia...
2494
  	hid_unregister_driver(&sony_driver);
6c40065fc   Antonio Ospite   HID: sony: Fix a ...
2495
  	ida_destroy(&sony_device_id_allocator);
8025087ac   Frank Praznik   HID: sony: Initia...
2496
2497
2498
  }
  module_init(sony_init);
  module_exit(sony_exit);
bd28ce008   Jiri Slaby   HID: move sony qu...
2499

bd28ce008   Jiri Slaby   HID: move sony qu...
2500
  MODULE_LICENSE("GPL");