Blame view

drivers/hid/hid-sony.c 85.9 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>
c4425c8f2   Frank Praznik   HID: sony: Update...
11
   *  Copyright (c) 2014-2016 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>
49b9ca6c6   Roderick Colenbrander   HID: sony: Perfor...
37
38
  #include <linux/crc32.h>
  #include <asm/unaligned.h>
bd28ce008   Jiri Slaby   HID: move sony qu...
39
40
  
  #include "hid-ids.h"
6c79c18c9   Frank Praznik   HID: sony: Fix sp...
41
42
43
44
45
  #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...
46
47
  #define DUALSHOCK4_CONTROLLER_USB BIT(5)
  #define DUALSHOCK4_CONTROLLER_BT  BIT(6)
35f436c31   Roderick Colenbrander   HID: sony: Treat ...
48
49
50
51
52
53
54
  #define DUALSHOCK4_DONGLE         BIT(7)
  #define MOTION_CONTROLLER_USB     BIT(8)
  #define MOTION_CONTROLLER_BT      BIT(9)
  #define NAVIGATION_CONTROLLER_USB BIT(10)
  #define NAVIGATION_CONTROLLER_BT  BIT(11)
  #define SINO_LITE_CONTROLLER      BIT(12)
  #define FUTUREMAX_DANCE_MAT       BIT(13)
cc6e0bbb4   Jiri Kosina   HID: Add support ...
55

fee4e2d52   Frank Praznik   HID: sony: Enable...
56
  #define SIXAXIS_CONTROLLER (SIXAXIS_CONTROLLER_USB | SIXAXIS_CONTROLLER_BT)
b3bca326f   Simon Wood   HID: sony: Add qu...
57
  #define MOTION_CONTROLLER (MOTION_CONTROLLER_USB | MOTION_CONTROLLER_BT)
4545ee0a7   Simon Wood   HID: hid-sony: Na...
58
59
  #define NAVIGATION_CONTROLLER (NAVIGATION_CONTROLLER_USB |\
  				NAVIGATION_CONTROLLER_BT)
68330d83c   Frank Praznik   HID: sony: Add co...
60
  #define DUALSHOCK4_CONTROLLER (DUALSHOCK4_CONTROLLER_USB |\
35f436c31   Roderick Colenbrander   HID: sony: Treat ...
61
62
  				DUALSHOCK4_CONTROLLER_BT | \
  				DUALSHOCK4_DONGLE)
fee4e2d52   Frank Praznik   HID: sony: Enable...
63
  #define SONY_LED_SUPPORT (SIXAXIS_CONTROLLER | BUZZ_CONTROLLER |\
4545ee0a7   Simon Wood   HID: hid-sony: Na...
64
65
  				DUALSHOCK4_CONTROLLER | MOTION_CONTROLLER |\
  				NAVIGATION_CONTROLLER)
12e9a6d72   Simon Wood   HID: sony: Add su...
66
  #define SONY_BATTERY_SUPPORT (SIXAXIS_CONTROLLER | DUALSHOCK4_CONTROLLER |\
4545ee0a7   Simon Wood   HID: hid-sony: Na...
67
  				MOTION_CONTROLLER_BT | NAVIGATION_CONTROLLER)
c5e0c1c49   Frank Praznik   HID: sony: Add su...
68
69
  #define SONY_FF_SUPPORT (SIXAXIS_CONTROLLER | DUALSHOCK4_CONTROLLER |\
  				MOTION_CONTROLLER)
0f3982308   Frank Praznik   HID: sony: Relax ...
70
71
  #define SONY_BT_DEVICE (SIXAXIS_CONTROLLER_BT | DUALSHOCK4_CONTROLLER_BT |\
  			MOTION_CONTROLLER_BT | NAVIGATION_CONTROLLER_BT)
60781cf48   Frank Praznik   HID: sony: Add LE...
72
73
  
  #define MAX_LEDS 4
0a286ef27   Sven Eckelmann   HID: sony: Add LE...
74

e57a67da6   Mauro Carvalho Chehab   HID: hid-sony: fi...
75

c5e0c1c49   Frank Praznik   HID: sony: Add su...
76
  /* PS/3 Motion controller */
1adf904e9   Pavel Machek   HID: sony: unders...
77
  static u8 motion_rdesc[] = {
c5e0c1c49   Frank Praznik   HID: sony: Add su...
78
79
80
81
82
  	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...
83
  	0x75, 0x01,         /*          Report Size (1),            */
8b2513c31   Simon Wood   HID: sony: PS Mov...
84
  	0x95, 0x15,         /*          Report Count (21),          */
c5e0c1c49   Frank Praznik   HID: sony: Add su...
85
86
87
88
89
90
  	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...
91
92
93
  	0x29, 0x15,         /*          Usage Maximum (15h),        */
  	0x81, 0x02,         /*          Input (Variable),           * Buttons */
  	0x95, 0x0B,         /*          Report Count (11),          */
c5e0c1c49   Frank Praznik   HID: sony: Add su...
94
  	0x06, 0x00, 0xFF,   /*          Usage Page (FF00h),         */
8b2513c31   Simon Wood   HID: sony: PS Mov...
95
  	0x81, 0x03,         /*          Input (Constant, Variable), * Padding */
c5e0c1c49   Frank Praznik   HID: sony: Add su...
96
97
98
  	0x15, 0x00,         /*          Logical Minimum (0),        */
  	0x26, 0xFF, 0x00,   /*          Logical Maximum (255),      */
  	0x05, 0x01,         /*          Usage Page (Desktop),       */
c5e0c1c49   Frank Praznik   HID: sony: Add su...
99
100
  	0xA1, 0x00,         /*          Collection (Physical),      */
  	0x75, 0x08,         /*              Report Size (8),        */
8b2513c31   Simon Wood   HID: sony: PS Mov...
101
  	0x95, 0x01,         /*              Report Count (1),       */
c5e0c1c49   Frank Praznik   HID: sony: Add su...
102
103
104
  	0x35, 0x00,         /*              Physical Minimum (0),   */
  	0x46, 0xFF, 0x00,   /*              Physical Maximum (255), */
  	0x09, 0x30,         /*              Usage (X),              */
8b2513c31   Simon Wood   HID: sony: PS Mov...
105
  	0x81, 0x02,         /*              Input (Variable),       * Trigger */
c5e0c1c49   Frank Praznik   HID: sony: Add su...
106
  	0xC0,               /*          End Collection,             */
8b2513c31   Simon Wood   HID: sony: PS Mov...
107
108
109
  	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...
110
  	0x81, 0x02,         /*          Input (Variable),           */
8b2513c31   Simon Wood   HID: sony: PS Mov...
111
  	0x05, 0x01,         /*          Usage Page (Desktop),       */
c5e0c1c49   Frank Praznik   HID: sony: Add su...
112
  	0x75, 0x10,         /*          Report Size (16),           */
8b2513c31   Simon Wood   HID: sony: PS Mov...
113
114
115
116
117
118
119
120
121
122
123
  	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...
124
  	0x09, 0x01,         /*          Usage (Pointer),            */
8b2513c31   Simon Wood   HID: sony: PS Mov...
125
126
127
128
  	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...
129
  	0x81, 0x02,         /*          Input (Variable),           */
8b2513c31   Simon Wood   HID: sony: PS Mov...
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
  	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...
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
  	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                      */
  };
1adf904e9   Pavel Machek   HID: sony: unders...
172
  static u8 ps3remote_rdesc[] = {
078328da5   Jiri Kosina   HID: fold ps3remo...
173
174
175
176
177
178
  	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...
179
180
181
182
  	  /*
  	   * 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...
183
184
185
  	  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...
186
187
188
189
  	  /*
  	   * Bytes from 2nd to 4th are a bitmap for joypad buttons, for these
  	   * buttons multiple keypresses are allowed
  	   */
078328da5   Jiri Kosina   HID: fold ps3remo...
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
  	  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...
213
214
215
216
  	  /*
  	   * 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...
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
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
  	  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...
290
  static const unsigned int buzz_keymap[] = {
ad142b9e4   Frank Praznik   HID: sony: Fix mu...
291
292
  	/*
  	 * The controller has 4 remote buzzers, each with one LED and 5
f04d51404   Colin Leitner   HID: driver for P...
293
  	 * buttons.
09593e388   Antonio Ospite   HID: sony: fix er...
294
  	 *
f04d51404   Colin Leitner   HID: driver for P...
295
296
297
298
299
300
301
302
303
304
305
306
307
  	 * 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...
308
309
310
311
312
313
314
315
316
  	 [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...
317
318
319
320
321
322
323
324
325
326
327
328
  	[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,
  };
b8f0970d2   Roderick Colenbrander   HID: sony: Improv...
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
  /* The Navigation controller is a partial DS3 and uses the same HID report
   * and hence the same keymap indices, however not not all axes/buttons
   * are physically present. We use the same axis and button mapping as
   * the DS3, which uses the Linux gamepad spec.
   */
  static const unsigned int navigation_absmap[] = {
  	[0x30] = ABS_X,
  	[0x31] = ABS_Y,
  	[0x33] = ABS_Z, /* L2 */
  };
  
  /* Buttons not physically available on the device, but still available
   * in the reports are explicitly set to 0 for documentation purposes.
   */
  static const unsigned int navigation_keymap[] = {
  	[0x01] = 0, /* Select */
  	[0x02] = BTN_THUMBL, /* L3 */
  	[0x03] = 0, /* R3 */
  	[0x04] = 0, /* Start */
  	[0x05] = BTN_DPAD_UP, /* Up */
  	[0x06] = BTN_DPAD_RIGHT, /* Right */
  	[0x07] = BTN_DPAD_DOWN, /* Down */
  	[0x08] = BTN_DPAD_LEFT, /* Left */
  	[0x09] = BTN_TL2, /* L2 */
  	[0x0a] = 0, /* R2 */
  	[0x0b] = BTN_TL, /* L1 */
  	[0x0c] = 0, /* R1 */
  	[0x0d] = BTN_NORTH, /* Triangle */
  	[0x0e] = BTN_EAST, /* Circle */
  	[0x0f] = BTN_SOUTH, /* Cross */
  	[0x10] = BTN_WEST, /* Square */
  	[0x11] = BTN_MODE, /* PS */
  };
e19a267b9   Roderick Colenbrander   HID: sony: DS3 co...
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
  static const unsigned int sixaxis_absmap[] = {
  	[0x30] = ABS_X,
  	[0x31] = ABS_Y,
  	[0x32] = ABS_RX, /* right stick X */
  	[0x35] = ABS_RY, /* right stick Y */
  };
  
  static const unsigned int sixaxis_keymap[] = {
  	[0x01] = BTN_SELECT, /* Select */
  	[0x02] = BTN_THUMBL, /* L3 */
  	[0x03] = BTN_THUMBR, /* R3 */
  	[0x04] = BTN_START, /* Start */
  	[0x05] = BTN_DPAD_UP, /* Up */
  	[0x06] = BTN_DPAD_RIGHT, /* Right */
  	[0x07] = BTN_DPAD_DOWN, /* Down */
  	[0x08] = BTN_DPAD_LEFT, /* Left */
  	[0x09] = BTN_TL2, /* L2 */
  	[0x0a] = BTN_TR2, /* R2 */
  	[0x0b] = BTN_TL, /* L1 */
  	[0x0c] = BTN_TR, /* R1 */
  	[0x0d] = BTN_NORTH, /* Triangle */
  	[0x0e] = BTN_EAST, /* Circle */
  	[0x0f] = BTN_SOUTH, /* Cross */
  	[0x10] = BTN_WEST, /* Square */
  	[0x11] = BTN_MODE, /* PS */
  };
9131f8cc2   Roderick Colenbrander   HID: sony: Comply...
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
  static const unsigned int ds4_absmap[] = {
  	[0x30] = ABS_X,
  	[0x31] = ABS_Y,
  	[0x32] = ABS_RX, /* right stick X */
  	[0x33] = ABS_Z, /* L2 */
  	[0x34] = ABS_RZ, /* R2 */
  	[0x35] = ABS_RY, /* right stick Y */
  };
  
  static const unsigned int ds4_keymap[] = {
  	[0x1] = BTN_WEST, /* Square */
  	[0x2] = BTN_SOUTH, /* Cross */
  	[0x3] = BTN_EAST, /* Circle */
  	[0x4] = BTN_NORTH, /* Triangle */
  	[0x5] = BTN_TL, /* L1 */
  	[0x6] = BTN_TR, /* R1 */
  	[0x7] = BTN_TL2, /* L2 */
  	[0x8] = BTN_TR2, /* R2 */
  	[0x9] = BTN_SELECT, /* Share */
  	[0xa] = BTN_START, /* Options */
  	[0xb] = BTN_THUMBL, /* L3 */
  	[0xc] = BTN_THUMBR, /* R3 */
  	[0xd] = BTN_MODE, /* PS */
  };
d03ae2e10   Roderick Colenbrander   HID: sony: Remove...
412
413
414
415
  static const struct {int x; int y; } ds4_hat_mapping[] = {
  	{0, -1}, {1, -1}, {1, 0}, {1, 1}, {0, 1}, {-1, 1}, {-1, 0}, {-1, -1},
  	{0, 0}
  };
9131f8cc2   Roderick Colenbrander   HID: sony: Comply...
416

d902f4724   Frank Praznik   HID: sony: add ba...
417
418
419
420
421
422
  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 ...
423
  struct sixaxis_led {
1adf904e9   Pavel Machek   HID: sony: unders...
424
425
426
427
428
  	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 ...
429
430
431
  } __packed;
  
  struct sixaxis_rumble {
1adf904e9   Pavel Machek   HID: sony: unders...
432
433
434
435
436
  	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 ...
437
438
439
  } __packed;
  
  struct sixaxis_output_report {
1adf904e9   Pavel Machek   HID: sony: unders...
440
  	u8 report_id;
55d3b664d   Frank Praznik   HID: sony: Use a ...
441
  	struct sixaxis_rumble rumble;
1adf904e9   Pavel Machek   HID: sony: unders...
442
443
  	u8 padding[4];
  	u8 leds_bitmap; /* bitmap of enabled LEDs: LED_1 = 0x02, LED_2 = 0x04, ... */
55d3b664d   Frank Praznik   HID: sony: Use a ...
444
445
446
447
448
449
  	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...
450
  	u8 buf[36];
55d3b664d   Frank Praznik   HID: sony: Use a ...
451
  };
c5e0c1c49   Frank Praznik   HID: sony: Add su...
452
453
454
455
456
457
  struct motion_output_report_02 {
  	u8 type, zero;
  	u8 r, g, b;
  	u8 zero2;
  	u8 rumble;
  };
2c159de05   Roderick Colenbrander   HID: sony: Adjust...
458
  #define DS4_FEATURE_REPORT_0x02_SIZE 37
55a07d62d   Roderick Colenbrander   HID: sony: Calibr...
459
  #define DS4_FEATURE_REPORT_0x05_SIZE 41
2c159de05   Roderick Colenbrander   HID: sony: Adjust...
460
  #define DS4_FEATURE_REPORT_0x81_SIZE 7
49b9ca6c6   Roderick Colenbrander   HID: sony: Perfor...
461
  #define DS4_INPUT_REPORT_0x11_SIZE 78
2c159de05   Roderick Colenbrander   HID: sony: Adjust...
462
463
  #define DS4_OUTPUT_REPORT_0x05_SIZE 32
  #define DS4_OUTPUT_REPORT_0x11_SIZE 78
29b691a89   Antonio Ospite   HID: sony: Use th...
464
  #define SIXAXIS_REPORT_0xF2_SIZE 17
a85d67b54   Antonio Ospite   HID: sony: Don't ...
465
  #define SIXAXIS_REPORT_0xF5_SIZE 8
41d2d4253   Simon Wood   HID: sony: PS3 Mo...
466
  #define MOTION_REPORT_0x02_SIZE 49
9b2b5c9a7   Frank Praznik   HID: sony: Use ke...
467

cdc1c0215   Roderick Colenbrander   HID: sony: Handle...
468
469
470
  /* Offsets relative to USB input report (0x1). Bluetooth (0x11) requires an
   * additional +2.
   */
d03ae2e10   Roderick Colenbrander   HID: sony: Remove...
471
  #define DS4_INPUT_REPORT_AXIS_OFFSET      1
ac797b95f   Roderick Colenbrander   HID: sony: Make t...
472
  #define DS4_INPUT_REPORT_BUTTON_OFFSET    5
80786eb9a   Roderick Colenbrander   HID: sony: Report...
473
  #define DS4_INPUT_REPORT_TIMESTAMP_OFFSET 10
227c011b2   Roderick Colenbrander   HID: sony: Report...
474
  #define DS4_INPUT_REPORT_GYRO_X_OFFSET   13
cdc1c0215   Roderick Colenbrander   HID: sony: Handle...
475
476
  #define DS4_INPUT_REPORT_BATTERY_OFFSET  30
  #define DS4_INPUT_REPORT_TOUCHPAD_OFFSET 33
510c8b7c1   Roderick Colenbrander   HID: sony: Expose...
477
  #define SENSOR_SUFFIX " Motion Sensors"
ac797b95f   Roderick Colenbrander   HID: sony: Make t...
478
  #define DS4_TOUCHPAD_SUFFIX " Touchpad"
77b499e73   Roderick Colenbrander   HID: sony: Make D...
479
480
481
  /* Default to 4ms poll interval, which is same as USB (not adjustable). */
  #define DS4_BT_DEFAULT_POLL_INTERVAL_MS 4
  #define DS4_BT_MAX_POLL_INTERVAL_MS 62
55a07d62d   Roderick Colenbrander   HID: sony: Calibr...
482
483
  #define DS4_GYRO_RES_PER_DEG_S 1024
  #define DS4_ACC_RES_PER_G      8192
510c8b7c1   Roderick Colenbrander   HID: sony: Expose...
484
485
  #define SIXAXIS_INPUT_REPORT_ACC_X_OFFSET 41
  #define SIXAXIS_ACC_RES_PER_G 113
8b402c929   Jiri Kosina   HID: sony: initia...
486
  static DEFINE_SPINLOCK(sony_dev_list_lock);
d2d782fcc   Frank Praznik   HID: sony: Preven...
487
  static LIST_HEAD(sony_device_list);
8025087ac   Frank Praznik   HID: sony: Initia...
488
  static DEFINE_IDA(sony_device_id_allocator);
d2d782fcc   Frank Praznik   HID: sony: Preven...
489

55a07d62d   Roderick Colenbrander   HID: sony: Calibr...
490
491
492
493
494
495
496
497
498
499
500
  /* Used for calibration of DS4 accelerometer and gyro. */
  struct ds4_calibration_data {
  	int abs_code;
  	short bias;
  	/* Calibration requires scaling against a sensitivity value, which is a
  	 * float. Store sensitivity as a fraction to limit floating point
  	 * calculations until final calibration.
  	 */
  	int sens_numer;
  	int sens_denom;
  };
f2f47c385   Roderick Colenbrander   HID: sony: Suppor...
501
502
503
504
505
506
  enum ds4_dongle_state {
  	DONGLE_DISCONNECTED,
  	DONGLE_CALIBRATING,
  	DONGLE_CONNECTED,
  	DONGLE_DISABLED
  };
b53227360   Roderick Colenbrander   HID: sony: Make w...
507
  enum sony_worker {
f2f47c385   Roderick Colenbrander   HID: sony: Suppor...
508
509
  	SONY_WORKER_STATE,
  	SONY_WORKER_HOTPLUG
b53227360   Roderick Colenbrander   HID: sony: Make w...
510
  };
cc6e0bbb4   Jiri Kosina   HID: Add support ...
511
  struct sony_sc {
d902f4724   Frank Praznik   HID: sony: add ba...
512
  	spinlock_t lock;
d2d782fcc   Frank Praznik   HID: sony: Preven...
513
  	struct list_head list_node;
0a286ef27   Sven Eckelmann   HID: sony: Add LE...
514
  	struct hid_device *hdev;
ac797b95f   Roderick Colenbrander   HID: sony: Make t...
515
  	struct input_dev *touchpad;
227c011b2   Roderick Colenbrander   HID: sony: Report...
516
  	struct input_dev *sensor_dev;
60781cf48   Frank Praznik   HID: sony: Add LE...
517
  	struct led_classdev *leds[MAX_LEDS];
cc6e0bbb4   Jiri Kosina   HID: Add support ...
518
  	unsigned long quirks;
f2f47c385   Roderick Colenbrander   HID: sony: Suppor...
519
  	struct work_struct hotplug_worker;
0a286ef27   Sven Eckelmann   HID: sony: Add LE...
520
  	struct work_struct state_worker;
09593e388   Antonio Ospite   HID: sony: fix er...
521
  	void (*send_output_report)(struct sony_sc *);
297d716f6   Krzysztof Kozlowski   power_supply: Cha...
522
523
  	struct power_supply *battery;
  	struct power_supply_desc battery_desc;
8025087ac   Frank Praznik   HID: sony: Initia...
524
  	int device_id;
1adf904e9   Pavel Machek   HID: sony: unders...
525
  	u8 *output_report_dmabuf;
f04d51404   Colin Leitner   HID: driver for P...
526

9f323b681   Sven Eckelmann   HID: sony: Send F...
527
  #ifdef CONFIG_SONY_FF
1adf904e9   Pavel Machek   HID: sony: unders...
528
529
  	u8 left;
  	u8 right;
9f323b681   Sven Eckelmann   HID: sony: Send F...
530
  #endif
1adf904e9   Pavel Machek   HID: sony: unders...
531
  	u8 mac_address[6];
f2f47c385   Roderick Colenbrander   HID: sony: Suppor...
532
  	u8 hotplug_worker_initialized;
b53227360   Roderick Colenbrander   HID: sony: Make w...
533
  	u8 state_worker_initialized;
2a2429327   Frank Praznik   HID: sony: Defer ...
534
  	u8 defer_initialization;
1adf904e9   Pavel Machek   HID: sony: unders...
535
536
537
538
  	u8 cable_state;
  	u8 battery_charging;
  	u8 battery_capacity;
  	u8 led_state[MAX_LEDS];
1adf904e9   Pavel Machek   HID: sony: unders...
539
540
541
  	u8 led_delay_on[MAX_LEDS];
  	u8 led_delay_off[MAX_LEDS];
  	u8 led_count;
80786eb9a   Roderick Colenbrander   HID: sony: Report...
542
543
544
545
  
  	bool timestamp_initialized;
  	u16 prev_timestamp;
  	unsigned int timestamp_us;
77b499e73   Roderick Colenbrander   HID: sony: Make D...
546
  	u8 ds4_bt_poll_interval;
f2f47c385   Roderick Colenbrander   HID: sony: Suppor...
547
  	enum ds4_dongle_state ds4_dongle_state;
55a07d62d   Roderick Colenbrander   HID: sony: Calibr...
548
549
  	/* DS4 calibration data */
  	struct ds4_calibration_data ds4_calib_data[6];
cc6e0bbb4   Jiri Kosina   HID: Add support ...
550
  };
405182c24   Roderick Colenbrander   HID: sony: Ignore...
551
  static void sony_set_leds(struct sony_sc *sc);
b53227360   Roderick Colenbrander   HID: sony: Make w...
552
553
  static inline void sony_schedule_work(struct sony_sc *sc,
  				      enum sony_worker which)
2a2429327   Frank Praznik   HID: sony: Defer ...
554
  {
b53227360   Roderick Colenbrander   HID: sony: Make w...
555
556
557
558
  	switch (which) {
  	case SONY_WORKER_STATE:
  		if (!sc->defer_initialization)
  			schedule_work(&sc->state_worker);
f2f47c385   Roderick Colenbrander   HID: sony: Suppor...
559
560
561
562
563
  		break;
  	case SONY_WORKER_HOTPLUG:
  		if (sc->hotplug_worker_initialized)
  			schedule_work(&sc->hotplug_worker);
  		break;
b53227360   Roderick Colenbrander   HID: sony: Make w...
564
  	}
2a2429327   Frank Praznik   HID: sony: Defer ...
565
  }
77b499e73   Roderick Colenbrander   HID: sony: Make D...
566
567
568
  static ssize_t ds4_show_poll_interval(struct device *dev,
  				struct device_attribute
  				*attr, char *buf)
c607fb8d6   Antonio Ospite   HID: sony: Always...
569
  {
77b499e73   Roderick Colenbrander   HID: sony: Make D...
570
571
572
573
574
  	struct hid_device *hdev = to_hid_device(dev);
  	struct sony_sc *sc = hid_get_drvdata(hdev);
  
  	return snprintf(buf, PAGE_SIZE, "%i
  ", sc->ds4_bt_poll_interval);
c607fb8d6   Antonio Ospite   HID: sony: Always...
575
  }
77b499e73   Roderick Colenbrander   HID: sony: Make D...
576
577
578
  static ssize_t ds4_store_poll_interval(struct device *dev,
  				struct device_attribute *attr,
  				const char *buf, size_t count)
c5e0c1c49   Frank Praznik   HID: sony: Add su...
579
  {
77b499e73   Roderick Colenbrander   HID: sony: Make D...
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
  	struct hid_device *hdev = to_hid_device(dev);
  	struct sony_sc *sc = hid_get_drvdata(hdev);
  	unsigned long flags;
  	u8 interval;
  
  	if (kstrtou8(buf, 0, &interval))
  		return -EINVAL;
  
  	if (interval > DS4_BT_MAX_POLL_INTERVAL_MS)
  		return -EINVAL;
  
  	spin_lock_irqsave(&sc->lock, flags);
  	sc->ds4_bt_poll_interval = interval;
  	spin_unlock_irqrestore(&sc->lock, flags);
  
  	sony_schedule_work(sc, SONY_WORKER_STATE);
  
  	return count;
c5e0c1c49   Frank Praznik   HID: sony: Add su...
598
  }
77b499e73   Roderick Colenbrander   HID: sony: Make D...
599
600
  static DEVICE_ATTR(bt_poll_interval, 0644, ds4_show_poll_interval,
  		ds4_store_poll_interval);
c5e0c1c49   Frank Praznik   HID: sony: Add su...
601
  static u8 *motion_fixup(struct hid_device *hdev, u8 *rdesc,
b2723eb73   Simon Wood   HID: hid-sony: Fi...
602
603
  			     unsigned int *rsize)
  {
c5e0c1c49   Frank Praznik   HID: sony: Add su...
604
605
  	*rsize = sizeof(motion_rdesc);
  	return motion_rdesc;
b2723eb73   Simon Wood   HID: hid-sony: Fi...
606
  }
1adf904e9   Pavel Machek   HID: sony: unders...
607
  static u8 *ps3remote_fixup(struct hid_device *hdev, u8 *rdesc,
078328da5   Jiri Kosina   HID: fold ps3remo...
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
  			     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;
  }
b8f0970d2   Roderick Colenbrander   HID: sony: Improv...
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
  static int navigation_mapping(struct hid_device *hdev, struct hid_input *hi,
  			  struct hid_field *field, struct hid_usage *usage,
  			  unsigned long **bit, int *max)
  {
  	if ((usage->hid & HID_USAGE_PAGE) == HID_UP_BUTTON) {
  		unsigned int key = usage->hid & HID_USAGE;
  
  		if (key >= ARRAY_SIZE(sixaxis_keymap))
  			return -1;
  
  		key = navigation_keymap[key];
  		if (!key)
  			return -1;
  
  		hid_map_usage_clear(hi, usage, bit, max, EV_KEY, key);
  		return 1;
  	} else if (usage->hid == HID_GD_POINTER) {
  		/* See comment in sixaxis_mapping, basically the L2 (and R2)
  		 * triggers are reported through GD Pointer.
  		 * In addition we ignore any analog button 'axes' and only
  		 * support digital buttons.
  		 */
  		switch (usage->usage_index) {
  		case 8: /* L2 */
  			usage->hid = HID_GD_Z;
  			break;
  		default:
  			return -1;
  		}
  
  		hid_map_usage_clear(hi, usage, bit, max, EV_ABS, usage->hid & 0xf);
  		return 1;
  	} else if ((usage->hid & HID_USAGE_PAGE) == HID_UP_GENDESK) {
  		unsigned int abs = usage->hid & HID_USAGE;
  
  		if (abs >= ARRAY_SIZE(navigation_absmap))
  			return -1;
  
  		abs = navigation_absmap[abs];
  
  		hid_map_usage_clear(hi, usage, bit, max, EV_ABS, abs);
  		return 1;
  	}
  
  	return -1;
  }
e19a267b9   Roderick Colenbrander   HID: sony: DS3 co...
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
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
  static int sixaxis_mapping(struct hid_device *hdev, struct hid_input *hi,
  			  struct hid_field *field, struct hid_usage *usage,
  			  unsigned long **bit, int *max)
  {
  	if ((usage->hid & HID_USAGE_PAGE) == HID_UP_BUTTON) {
  		unsigned int key = usage->hid & HID_USAGE;
  
  		if (key >= ARRAY_SIZE(sixaxis_keymap))
  			return -1;
  
  		key = sixaxis_keymap[key];
  		hid_map_usage_clear(hi, usage, bit, max, EV_KEY, key);
  		return 1;
  	} else if (usage->hid == HID_GD_POINTER) {
  		/* The DS3 provides analog values for most buttons and even
  		 * for HAT axes through GD Pointer. L2 and R2 are reported
  		 * among these as well instead of as GD Z / RZ. Remap L2
  		 * and R2 and ignore other analog 'button axes' as there is
  		 * no good way for reporting them.
  		 */
  		switch (usage->usage_index) {
  		case 8: /* L2 */
  			usage->hid = HID_GD_Z;
  			break;
  		case 9: /* R2 */
  			usage->hid = HID_GD_RZ;
  			break;
  		default:
  			return -1;
  		}
  
  		hid_map_usage_clear(hi, usage, bit, max, EV_ABS, usage->hid & 0xf);
  		return 1;
  	} else if ((usage->hid & HID_USAGE_PAGE) == HID_UP_GENDESK) {
  		unsigned int abs = usage->hid & HID_USAGE;
  
  		if (abs >= ARRAY_SIZE(sixaxis_absmap))
  			return -1;
  
  		abs = sixaxis_absmap[abs];
  
  		hid_map_usage_clear(hi, usage, bit, max, EV_ABS, abs);
  		return 1;
  	}
  
  	return -1;
  }
9131f8cc2   Roderick Colenbrander   HID: sony: Comply...
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
  static int ds4_mapping(struct hid_device *hdev, struct hid_input *hi,
  		       struct hid_field *field, struct hid_usage *usage,
  		       unsigned long **bit, int *max)
  {
  	if ((usage->hid & HID_USAGE_PAGE) == HID_UP_BUTTON) {
  		unsigned int key = usage->hid & HID_USAGE;
  
  		if (key >= ARRAY_SIZE(ds4_keymap))
  			return -1;
  
  		key = ds4_keymap[key];
  		hid_map_usage_clear(hi, usage, bit, max, EV_KEY, key);
  		return 1;
  	} else if ((usage->hid & HID_USAGE_PAGE) == HID_UP_GENDESK) {
  		unsigned int abs = usage->hid & HID_USAGE;
  
  		/* Let the HID parser deal with the HAT. */
  		if (usage->hid == HID_GD_HATSWITCH)
  			return 0;
  
  		if (abs >= ARRAY_SIZE(ds4_absmap))
  			return -1;
  
  		abs = ds4_absmap[abs];
  		hid_map_usage_clear(hi, usage, bit, max, EV_ABS, abs);
  		return 1;
  	}
  
  	return 0;
  }
1adf904e9   Pavel Machek   HID: sony: unders...
770
  static u8 *sony_report_fixup(struct hid_device *hdev, u8 *rdesc,
73e4008dd   Nikolai Kondrashov   HID: allow resizi...
771
  		unsigned int *rsize)
cc6e0bbb4   Jiri Kosina   HID: Add support ...
772
773
  {
  	struct sony_sc *sc = hid_get_drvdata(hdev);
4ba1eeeb6   Mikko Perttunen   HID: sony: disabl...
774
  	if (sc->quirks & (SINO_LITE_CONTROLLER | FUTUREMAX_DANCE_MAT))
74500cc85   Scott Moreau   HID: sony: Add ny...
775
  		return rdesc;
99d249021   Fernando Luis Vázquez Cao   HID: clean up qui...
776
777
778
779
780
781
782
783
784
785
786
  	/*
  	 * 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 ...
787
788
  		hid_info(hdev, "Fixing up Sony RF Receiver report descriptor
  ");
99d249021   Fernando Luis Vázquez Cao   HID: clean up qui...
789
  		/* input: data, variable, relative */
cc6e0bbb4   Jiri Kosina   HID: Add support ...
790
791
  		rdesc[55] = 0x06;
  	}
61ab44beb   Simon Wood   HID: hid-sony: am...
792

c5e0c1c49   Frank Praznik   HID: sony: Add su...
793
794
  	if (sc->quirks & MOTION_CONTROLLER)
  		return motion_fixup(hdev, rdesc, rsize);
078328da5   Jiri Kosina   HID: fold ps3remo...
795
796
  	if (sc->quirks & PS3REMOTE)
  		return ps3remote_fixup(hdev, rdesc, rsize);
73e4008dd   Nikolai Kondrashov   HID: allow resizi...
797
  	return rdesc;
cc6e0bbb4   Jiri Kosina   HID: Add support ...
798
  }
1adf904e9   Pavel Machek   HID: sony: unders...
799
  static void sixaxis_parse_report(struct sony_sc *sc, u8 *rd, int size)
d902f4724   Frank Praznik   HID: sony: add ba...
800
  {
1adf904e9   Pavel Machek   HID: sony: unders...
801
  	static const u8 sixaxis_battery_capacity[] = { 0, 1, 25, 50, 75, 100 };
d902f4724   Frank Praznik   HID: sony: add ba...
802
  	unsigned long flags;
12e9a6d72   Simon Wood   HID: sony: Add su...
803
  	int offset;
1adf904e9   Pavel Machek   HID: sony: unders...
804
  	u8 cable_state, battery_capacity, battery_charging;
d902f4724   Frank Praznik   HID: sony: add ba...
805

ad142b9e4   Frank Praznik   HID: sony: Fix mu...
806
807
  	/*
  	 * The sixaxis is charging if the battery value is 0xee
d902f4724   Frank Praznik   HID: sony: add ba...
808
809
810
811
  	 * 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...
812
813
814
  	offset = (sc->quirks & MOTION_CONTROLLER) ? 12 : 30;
  
  	if (rd[offset] >= 0xee) {
d902f4724   Frank Praznik   HID: sony: add ba...
815
  		battery_capacity = 100;
12e9a6d72   Simon Wood   HID: sony: Add su...
816
  		battery_charging = !(rd[offset] & 0x01);
9fddd74a2   Frank Praznik   HID: sony: Set th...
817
  		cable_state = 1;
d902f4724   Frank Praznik   HID: sony: add ba...
818
  	} else {
1adf904e9   Pavel Machek   HID: sony: unders...
819
  		u8 index = rd[offset] <= 5 ? rd[offset] : 5;
ac3c9a940   Frank Praznik   HID: sony: Perfor...
820
  		battery_capacity = sixaxis_battery_capacity[index];
d902f4724   Frank Praznik   HID: sony: add ba...
821
  		battery_charging = 0;
9fddd74a2   Frank Praznik   HID: sony: Set th...
822
  		cable_state = 0;
d902f4724   Frank Praznik   HID: sony: add ba...
823
  	}
d902f4724   Frank Praznik   HID: sony: add ba...
824
825
826
827
828
829
  
  	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);
510c8b7c1   Roderick Colenbrander   HID: sony: Expose...
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
  
  	if (sc->quirks & SIXAXIS_CONTROLLER) {
  		int val;
  
  		offset = SIXAXIS_INPUT_REPORT_ACC_X_OFFSET;
  		val = ((rd[offset+1] << 8) | rd[offset]) - 511;
  		input_report_abs(sc->sensor_dev, ABS_X, val);
  
  		/* Y and Z are swapped and inversed */
  		val = 511 - ((rd[offset+5] << 8) | rd[offset+4]);
  		input_report_abs(sc->sensor_dev, ABS_Y, val);
  
  		val = 511 - ((rd[offset+3] << 8) | rd[offset+2]);
  		input_report_abs(sc->sensor_dev, ABS_Z, val);
  
  		input_sync(sc->sensor_dev);
  	}
d902f4724   Frank Praznik   HID: sony: add ba...
847
  }
1adf904e9   Pavel Machek   HID: sony: unders...
848
  static void dualshock4_parse_report(struct sony_sc *sc, u8 *rd, int size)
d902f4724   Frank Praznik   HID: sony: add ba...
849
  {
d03ae2e10   Roderick Colenbrander   HID: sony: Remove...
850
851
852
  	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...
853
  	unsigned long flags;
cdc1c0215   Roderick Colenbrander   HID: sony: Handle...
854
  	int n, m, offset, num_touch_data, max_touch_data;
1adf904e9   Pavel Machek   HID: sony: unders...
855
  	u8 cable_state, battery_capacity, battery_charging;
80786eb9a   Roderick Colenbrander   HID: sony: Report...
856
  	u16 timestamp;
d902f4724   Frank Praznik   HID: sony: add ba...
857

cdc1c0215   Roderick Colenbrander   HID: sony: Handle...
858
  	/* When using Bluetooth the header is 2 bytes longer, so skip these. */
35f436c31   Roderick Colenbrander   HID: sony: Treat ...
859
  	int data_offset = (sc->quirks & DUALSHOCK4_CONTROLLER_BT) ? 2 : 0;
6c5f860d3   Frank Praznik   HID: sony: Add Du...
860

ac797b95f   Roderick Colenbrander   HID: sony: Make t...
861
862
863
  	/* Second bit of third button byte is for the touchpad button. */
  	offset = data_offset + DS4_INPUT_REPORT_BUTTON_OFFSET;
  	input_report_key(sc->touchpad, BTN_LEFT, rd[offset+2] & 0x2);
ad142b9e4   Frank Praznik   HID: sony: Fix mu...
864
  	/*
d03ae2e10   Roderick Colenbrander   HID: sony: Remove...
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
  	 * The default behavior of the Dualshock 4 is to send reports using
  	 * report 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 descriptor, the HID layer won't generate events.
  	 * While it is possible (and this was done before) to fixup the HID
  	 * descriptor to add this mapping, it was better to do this manually.
  	 * The reason is there were various pieces software both open and closed
  	 * source, relying on the descriptors to be the same across various
  	 * operating systems. If the descriptors wouldn't match some
  	 * applications e.g. games on Wine would not be able to function due
  	 * to different descriptors, which such applications are not parsing.
  	 */
  	if (rd[0] == 17) {
  		int value;
  
  		offset = data_offset + DS4_INPUT_REPORT_AXIS_OFFSET;
  		input_report_abs(input_dev, ABS_X, rd[offset]);
  		input_report_abs(input_dev, ABS_Y, rd[offset+1]);
  		input_report_abs(input_dev, ABS_RX, rd[offset+2]);
  		input_report_abs(input_dev, ABS_RY, rd[offset+3]);
  
  		value = rd[offset+4] & 0xf;
  		if (value > 7)
  			value = 8; /* Center 0, 0 */
  		input_report_abs(input_dev, ABS_HAT0X, ds4_hat_mapping[value].x);
  		input_report_abs(input_dev, ABS_HAT0Y, ds4_hat_mapping[value].y);
  
  		input_report_key(input_dev, BTN_WEST, rd[offset+4] & 0x10);
  		input_report_key(input_dev, BTN_SOUTH, rd[offset+4] & 0x20);
  		input_report_key(input_dev, BTN_EAST, rd[offset+4] & 0x40);
  		input_report_key(input_dev, BTN_NORTH, rd[offset+4] & 0x80);
  
  		input_report_key(input_dev, BTN_TL, rd[offset+5] & 0x1);
  		input_report_key(input_dev, BTN_TR, rd[offset+5] & 0x2);
  		input_report_key(input_dev, BTN_TL2, rd[offset+5] & 0x4);
  		input_report_key(input_dev, BTN_TR2, rd[offset+5] & 0x8);
  		input_report_key(input_dev, BTN_SELECT, rd[offset+5] & 0x10);
  		input_report_key(input_dev, BTN_START, rd[offset+5] & 0x20);
  		input_report_key(input_dev, BTN_THUMBL, rd[offset+5] & 0x40);
  		input_report_key(input_dev, BTN_THUMBR, rd[offset+5] & 0x80);
  
  		input_report_key(input_dev, BTN_MODE, rd[offset+6] & 0x1);
  
  		input_report_abs(input_dev, ABS_Z, rd[offset+7]);
  		input_report_abs(input_dev, ABS_RZ, rd[offset+8]);
  
  		input_sync(input_dev);
  	}
80786eb9a   Roderick Colenbrander   HID: sony: Report...
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
  	/* Convert timestamp (in 5.33us unit) to timestamp_us */
  	offset = data_offset + DS4_INPUT_REPORT_TIMESTAMP_OFFSET;
  	timestamp = get_unaligned_le16(&rd[offset]);
  	if (!sc->timestamp_initialized) {
  		sc->timestamp_us = ((unsigned int)timestamp * 16) / 3;
  		sc->timestamp_initialized = true;
  	} else {
  		u16 delta;
  
  		if (sc->prev_timestamp > timestamp)
  			delta = (U16_MAX - sc->prev_timestamp + timestamp + 1);
  		else
  			delta = timestamp - sc->prev_timestamp;
  		sc->timestamp_us += (delta * 16) / 3;
  	}
  	sc->prev_timestamp = timestamp;
  	input_event(sc->sensor_dev, EV_MSC, MSC_TIMESTAMP, sc->timestamp_us);
227c011b2   Roderick Colenbrander   HID: sony: Report...
931
  	offset = data_offset + DS4_INPUT_REPORT_GYRO_X_OFFSET;
55a07d62d   Roderick Colenbrander   HID: sony: Calibr...
932
933
934
935
936
937
938
939
940
941
942
943
944
  	for (n = 0; n < 6; n++) {
  		/* Store data in int for more precision during mult_frac. */
  		int raw_data = (short)((rd[offset+1] << 8) | rd[offset]);
  		struct ds4_calibration_data *calib = &sc->ds4_calib_data[n];
  
  		/* High precision is needed during calibration, but the
  		 * calibrated values are within 32-bit.
  		 * Note: we swap numerator 'x' and 'numer' in mult_frac for
  		 *       precision reasons so we don't need 64-bit.
  		 */
  		int calib_data = mult_frac(calib->sens_numer,
  					   raw_data - calib->bias,
  					   calib->sens_denom);
227c011b2   Roderick Colenbrander   HID: sony: Report...
945

55a07d62d   Roderick Colenbrander   HID: sony: Calibr...
946
947
  		input_report_abs(sc->sensor_dev, calib->abs_code, calib_data);
  		offset += 2;
227c011b2   Roderick Colenbrander   HID: sony: Report...
948
949
  	}
  	input_sync(sc->sensor_dev);
ad142b9e4   Frank Praznik   HID: sony: Fix mu...
950
  	/*
cdc1c0215   Roderick Colenbrander   HID: sony: Handle...
951
  	 * The lower 4 bits of byte 30 (or 32 for BT) contain the battery level
d902f4724   Frank Praznik   HID: sony: add ba...
952
953
  	 * and the 5th bit contains the USB cable state.
  	 */
cdc1c0215   Roderick Colenbrander   HID: sony: Handle...
954
  	offset = data_offset + DS4_INPUT_REPORT_BATTERY_OFFSET;
6c5f860d3   Frank Praznik   HID: sony: Add Du...
955
956
  	cable_state = (rd[offset] >> 4) & 0x01;
  	battery_capacity = rd[offset] & 0x0F;
d902f4724   Frank Praznik   HID: sony: add ba...
957

ad142b9e4   Frank Praznik   HID: sony: Fix mu...
958
959
  	/*
  	 * When a USB power source is connected the battery level ranges from
6c5f860d3   Frank Praznik   HID: sony: Add Du...
960
961
  	 * 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...
962
  	 */
6c5f860d3   Frank Praznik   HID: sony: Add Du...
963
  	if (!cable_state || battery_capacity > 10)
d902f4724   Frank Praznik   HID: sony: add ba...
964
965
966
  		battery_charging = 0;
  	else
  		battery_charging = 1;
6c5f860d3   Frank Praznik   HID: sony: Add Du...
967
968
  	if (!cable_state)
  		battery_capacity++;
d902f4724   Frank Praznik   HID: sony: add ba...
969
  	if (battery_capacity > 10)
6c5f860d3   Frank Praznik   HID: sony: Add Du...
970
  		battery_capacity = 10;
d902f4724   Frank Praznik   HID: sony: add ba...
971
972
973
974
975
976
977
  	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...
978

ad142b9e4   Frank Praznik   HID: sony: Fix mu...
979
  	/*
cdc1c0215   Roderick Colenbrander   HID: sony: Handle...
980
981
982
983
  	 * The Dualshock 4 multi-touch trackpad data starts at offset 33 on USB
  	 * and 35 on Bluetooth.
  	 * The first byte indicates the number of touch data in the report.
  	 * Trackpad data starts 2 bytes later (e.g. 35 for USB).
e56062305   Frank Praznik   HID: sony: add ou...
984
  	 */
cdc1c0215   Roderick Colenbrander   HID: sony: Handle...
985
  	offset = data_offset + DS4_INPUT_REPORT_TOUCHPAD_OFFSET;
35f436c31   Roderick Colenbrander   HID: sony: Treat ...
986
  	max_touch_data = (sc->quirks & DUALSHOCK4_CONTROLLER_BT) ? 4 : 3;
cdc1c0215   Roderick Colenbrander   HID: sony: Handle...
987
988
989
990
991
  	if (rd[offset] > 0 && rd[offset] <= max_touch_data)
  		num_touch_data = rd[offset];
  	else
  		num_touch_data = 1;
  	offset += 1;
e56062305   Frank Praznik   HID: sony: add ou...
992

cdc1c0215   Roderick Colenbrander   HID: sony: Handle...
993
994
995
  	for (m = 0; m < num_touch_data; m++) {
  		/* Skip past timestamp */
  		offset += 1;
e56062305   Frank Praznik   HID: sony: add ou...
996

cdc1c0215   Roderick Colenbrander   HID: sony: Handle...
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
  		/*
  		 * 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
  		 * immediately follows the data for the first.
  		 */
  		for (n = 0; n < 2; n++) {
  			u16 x, y;
  			bool active;
  
  			x = rd[offset+1] | ((rd[offset+2] & 0xF) << 8);
  			y = ((rd[offset+2] & 0xF0) >> 4) | (rd[offset+3] << 4);
  
  			active = !(rd[offset] >> 7);
ac797b95f   Roderick Colenbrander   HID: sony: Make t...
1013
1014
  			input_mt_slot(sc->touchpad, n);
  			input_mt_report_slot_state(sc->touchpad, MT_TOOL_FINGER, active);
cdc1c0215   Roderick Colenbrander   HID: sony: Handle...
1015
1016
  
  			if (active) {
ac797b95f   Roderick Colenbrander   HID: sony: Make t...
1017
1018
  				input_report_abs(sc->touchpad, ABS_MT_POSITION_X, x);
  				input_report_abs(sc->touchpad, ABS_MT_POSITION_Y, y);
cdc1c0215   Roderick Colenbrander   HID: sony: Handle...
1019
1020
1021
1022
  			}
  
  			offset += 4;
  		}
ac797b95f   Roderick Colenbrander   HID: sony: Make t...
1023
1024
  		input_mt_sync_frame(sc->touchpad);
  		input_sync(sc->touchpad);
e56062305   Frank Praznik   HID: sony: add ou...
1025
  	}
d902f4724   Frank Praznik   HID: sony: add ba...
1026
  }
c9e4d8775   Simon Wood   HID: hid-sony: fi...
1027
  static int sony_raw_event(struct hid_device *hdev, struct hid_report *report,
1adf904e9   Pavel Machek   HID: sony: unders...
1028
  		u8 *rd, int size)
c9e4d8775   Simon Wood   HID: hid-sony: fi...
1029
1030
  {
  	struct sony_sc *sc = hid_get_drvdata(hdev);
ad142b9e4   Frank Praznik   HID: sony: Fix mu...
1031
1032
  	/*
  	 * Sixaxis HID report has acclerometers/gyro with MSByte first, this
c9e4d8775   Simon Wood   HID: hid-sony: fi...
1033
1034
  	 * has to be BYTE_SWAPPED before passing up to joystick interface
  	 */
fee4e2d52   Frank Praznik   HID: sony: Enable...
1035
  	if ((sc->quirks & SIXAXIS_CONTROLLER) && rd[0] == 0x01 && size == 49) {
8f5f0bc27   Frank Praznik   HID: sony: Drop i...
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
  		/*
  		 * 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...
1046
1047
1048
1049
  		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...
1050
1051
  
  		sixaxis_parse_report(sc, rd, size);
12e9a6d72   Simon Wood   HID: sony: Add su...
1052
1053
  	} 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...
1054
1055
1056
  	} else if ((sc->quirks & NAVIGATION_CONTROLLER) && rd[0] == 0x01 &&
  			size == 49) {
  		sixaxis_parse_report(sc, rd, size);
35f436c31   Roderick Colenbrander   HID: sony: Treat ...
1057
1058
1059
1060
1061
1062
1063
1064
1065
  	} else if ((sc->quirks & DUALSHOCK4_CONTROLLER_USB) && rd[0] == 0x01 &&
  			size == 64) {
  		dualshock4_parse_report(sc, rd, size);
  	} else if (((sc->quirks & DUALSHOCK4_CONTROLLER_BT) && rd[0] == 0x11 &&
  			size == 78)) {
  		/* CRC check */
  		u8 bthdr = 0xA1;
  		u32 crc;
  		u32 report_crc;
49b9ca6c6   Roderick Colenbrander   HID: sony: Perfor...
1066

35f436c31   Roderick Colenbrander   HID: sony: Treat ...
1067
1068
1069
1070
1071
1072
1073
1074
  		crc = crc32_le(0xFFFFFFFF, &bthdr, 1);
  		crc = ~crc32_le(crc, rd, DS4_INPUT_REPORT_0x11_SIZE-4);
  		report_crc = get_unaligned_le32(&rd[DS4_INPUT_REPORT_0x11_SIZE-4]);
  		if (crc != report_crc) {
  			hid_dbg(sc->hdev, "DualShock 4 input report's CRC check failed, received crc 0x%0x != 0x%0x
  ",
  				report_crc, crc);
  			return -EILSEQ;
49b9ca6c6   Roderick Colenbrander   HID: sony: Perfor...
1075
  		}
405182c24   Roderick Colenbrander   HID: sony: Ignore...
1076

35f436c31   Roderick Colenbrander   HID: sony: Treat ...
1077
1078
1079
  		dualshock4_parse_report(sc, rd, size);
  	} else if ((sc->quirks & DUALSHOCK4_DONGLE) && rd[0] == 0x01 &&
  			size == 64) {
f2f47c385   Roderick Colenbrander   HID: sony: Suppor...
1080
1081
  		unsigned long flags;
  		enum ds4_dongle_state dongle_state;
405182c24   Roderick Colenbrander   HID: sony: Ignore...
1082
1083
1084
1085
1086
  		/*
  		 * In the case of a DS4 USB dongle, bit[2] of byte 31 indicates
  		 * if a DS4 is actually connected (indicated by '0').
  		 * For non-dongle, this bit is always 0 (connected).
  		 */
35f436c31   Roderick Colenbrander   HID: sony: Treat ...
1087
  		bool connected = (rd[31] & 0x04) ? false : true;
f2f47c385   Roderick Colenbrander   HID: sony: Suppor...
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
  		spin_lock_irqsave(&sc->lock, flags);
  		dongle_state = sc->ds4_dongle_state;
  		spin_unlock_irqrestore(&sc->lock, flags);
  
  		/*
  		 * The dongle always sends input reports even when no
  		 * DS4 is attached. When a DS4 is connected, we need to
  		 * obtain calibration data before we can use it.
  		 * The code below tracks dongle state and kicks of
  		 * calibration when needed and only allows us to process
  		 * input if a DS4 is actually connected.
  		 */
  		if (dongle_state == DONGLE_DISCONNECTED && connected) {
35f436c31   Roderick Colenbrander   HID: sony: Treat ...
1101
1102
1103
  			hid_info(sc->hdev, "DualShock 4 USB dongle: controller connected
  ");
  			sony_set_leds(sc);
f2f47c385   Roderick Colenbrander   HID: sony: Suppor...
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
  
  			spin_lock_irqsave(&sc->lock, flags);
  			sc->ds4_dongle_state = DONGLE_CALIBRATING;
  			spin_unlock_irqrestore(&sc->lock, flags);
  
  			sony_schedule_work(sc, SONY_WORKER_HOTPLUG);
  
  			/* Don't process the report since we don't have
  			 * calibration data, but let hidraw have it anyway.
  			 */
  			return 0;
  		} else if ((dongle_state == DONGLE_CONNECTED ||
  			    dongle_state == DONGLE_DISABLED) && !connected) {
35f436c31   Roderick Colenbrander   HID: sony: Treat ...
1117
1118
  			hid_info(sc->hdev, "DualShock 4 USB dongle: controller disconnected
  ");
f2f47c385   Roderick Colenbrander   HID: sony: Suppor...
1119
1120
1121
1122
  
  			spin_lock_irqsave(&sc->lock, flags);
  			sc->ds4_dongle_state = DONGLE_DISCONNECTED;
  			spin_unlock_irqrestore(&sc->lock, flags);
35f436c31   Roderick Colenbrander   HID: sony: Treat ...
1123
1124
  			/* Return 0, so hidraw can get the report. */
  			return 0;
f2f47c385   Roderick Colenbrander   HID: sony: Suppor...
1125
1126
1127
  		} else if (dongle_state == DONGLE_CALIBRATING ||
  			   dongle_state == DONGLE_DISABLED ||
  			   dongle_state == DONGLE_DISCONNECTED) {
35f436c31   Roderick Colenbrander   HID: sony: Treat ...
1128
1129
  			/* Return 0, so hidraw can get the report. */
  			return 0;
405182c24   Roderick Colenbrander   HID: sony: Ignore...
1130
  		}
d902f4724   Frank Praznik   HID: sony: add ba...
1131
  		dualshock4_parse_report(sc, rd, size);
c9e4d8775   Simon Wood   HID: hid-sony: fi...
1132
  	}
2a2429327   Frank Praznik   HID: sony: Defer ...
1133
1134
  	if (sc->defer_initialization) {
  		sc->defer_initialization = 0;
b53227360   Roderick Colenbrander   HID: sony: Make w...
1135
  		sony_schedule_work(sc, SONY_WORKER_STATE);
2a2429327   Frank Praznik   HID: sony: Defer ...
1136
  	}
c9e4d8775   Simon Wood   HID: hid-sony: fi...
1137
1138
  	return 0;
  }
f04d51404   Colin Leitner   HID: driver for P...
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
  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...
1167
1168
  	if (sc->quirks & PS3REMOTE)
  		return ps3remote_mapping(hdev, hi, field, usage, bit, max);
b8f0970d2   Roderick Colenbrander   HID: sony: Improv...
1169
1170
  	if (sc->quirks & NAVIGATION_CONTROLLER)
  		return navigation_mapping(hdev, hi, field, usage, bit, max);
e19a267b9   Roderick Colenbrander   HID: sony: DS3 co...
1171
1172
  	if (sc->quirks & SIXAXIS_CONTROLLER)
  		return sixaxis_mapping(hdev, hi, field, usage, bit, max);
9131f8cc2   Roderick Colenbrander   HID: sony: Comply...
1173
1174
1175
  
  	if (sc->quirks & DUALSHOCK4_CONTROLLER)
  		return ds4_mapping(hdev, hi, field, usage, bit, max);
e19a267b9   Roderick Colenbrander   HID: sony: DS3 co...
1176

6f4980182   Benjamin Tissoires   HID: sony: fix HI...
1177
1178
  	/* Let hid-core decide for the others */
  	return 0;
f04d51404   Colin Leitner   HID: driver for P...
1179
  }
ac797b95f   Roderick Colenbrander   HID: sony: Make t...
1180
  static int sony_register_touchpad(struct sony_sc *sc, int touch_count,
ce8efc3b5   Frank Praznik   HID: sony: Set to...
1181
1182
  					int w, int h)
  {
ac797b95f   Roderick Colenbrander   HID: sony: Make t...
1183
1184
  	size_t name_sz;
  	char *name;
ce8efc3b5   Frank Praznik   HID: sony: Set to...
1185
  	int ret;
ac797b95f   Roderick Colenbrander   HID: sony: Make t...
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
  	sc->touchpad = input_allocate_device();
  	if (!sc->touchpad)
  		return -ENOMEM;
  
  	input_set_drvdata(sc->touchpad, sc);
  	sc->touchpad->dev.parent = &sc->hdev->dev;
  	sc->touchpad->phys = sc->hdev->phys;
  	sc->touchpad->uniq = sc->hdev->uniq;
  	sc->touchpad->id.bustype = sc->hdev->bus;
  	sc->touchpad->id.vendor = sc->hdev->vendor;
  	sc->touchpad->id.product = sc->hdev->product;
  	sc->touchpad->id.version = sc->hdev->version;
  
  	/* Append a suffix to the controller name as there are various
  	 * DS4 compatible non-Sony devices with different names.
  	 */
  	name_sz = strlen(sc->hdev->name) + sizeof(DS4_TOUCHPAD_SUFFIX);
  	name = kzalloc(name_sz, GFP_KERNEL);
  	if (!name) {
  		ret = -ENOMEM;
  		goto err;
  	}
  	snprintf(name, name_sz, "%s" DS4_TOUCHPAD_SUFFIX, sc->hdev->name);
  	sc->touchpad->name = name;
b9f7d245e   Roderick Colenbrander   HID: sony: Mark D...
1210
  	ret = input_mt_init_slots(sc->touchpad, touch_count, INPUT_MT_POINTER);
ce8efc3b5   Frank Praznik   HID: sony: Set to...
1211
  	if (ret < 0)
ac797b95f   Roderick Colenbrander   HID: sony: Make t...
1212
1213
1214
1215
1216
1217
  		goto err;
  
  	/* We map the button underneath the touchpad to BTN_LEFT. */
  	__set_bit(EV_KEY, sc->touchpad->evbit);
  	__set_bit(BTN_LEFT, sc->touchpad->keybit);
  	__set_bit(INPUT_PROP_BUTTONPAD, sc->touchpad->propbit);
ce8efc3b5   Frank Praznik   HID: sony: Set to...
1218

ac797b95f   Roderick Colenbrander   HID: sony: Make t...
1219
1220
1221
1222
1223
1224
  	input_set_abs_params(sc->touchpad, ABS_MT_POSITION_X, 0, w, 0, 0);
  	input_set_abs_params(sc->touchpad, ABS_MT_POSITION_Y, 0, h, 0, 0);
  
  	ret = input_register_device(sc->touchpad);
  	if (ret < 0)
  		goto err;
ce8efc3b5   Frank Praznik   HID: sony: Set to...
1225
1226
  
  	return 0;
ac797b95f   Roderick Colenbrander   HID: sony: Make t...
1227
1228
1229
1230
1231
1232
1233
1234
1235
  
  err:
  	kfree(sc->touchpad->name);
  	sc->touchpad->name = NULL;
  
  	input_free_device(sc->touchpad);
  	sc->touchpad = NULL;
  
  	return ret;
ce8efc3b5   Frank Praznik   HID: sony: Set to...
1236
  }
ac797b95f   Roderick Colenbrander   HID: sony: Make t...
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
  static void sony_unregister_touchpad(struct sony_sc *sc)
  {
  	if (!sc->touchpad)
  		return;
  
  	kfree(sc->touchpad->name);
  	sc->touchpad->name = NULL;
  
  	input_unregister_device(sc->touchpad);
  	sc->touchpad = NULL;
  }
ce8efc3b5   Frank Praznik   HID: sony: Set to...
1248

227c011b2   Roderick Colenbrander   HID: sony: Report...
1249
1250
1251
1252
1253
  static int sony_register_sensors(struct sony_sc *sc)
  {
  	size_t name_sz;
  	char *name;
  	int ret;
55a07d62d   Roderick Colenbrander   HID: sony: Calibr...
1254
  	int range;
227c011b2   Roderick Colenbrander   HID: sony: Report...
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
  
  	sc->sensor_dev = input_allocate_device();
  	if (!sc->sensor_dev)
  		return -ENOMEM;
  
  	input_set_drvdata(sc->sensor_dev, sc);
  	sc->sensor_dev->dev.parent = &sc->hdev->dev;
  	sc->sensor_dev->phys = sc->hdev->phys;
  	sc->sensor_dev->uniq = sc->hdev->uniq;
  	sc->sensor_dev->id.bustype = sc->hdev->bus;
  	sc->sensor_dev->id.vendor = sc->hdev->vendor;
  	sc->sensor_dev->id.product = sc->hdev->product;
  	sc->sensor_dev->id.version = sc->hdev->version;
  
  	/* Append a suffix to the controller name as there are various
  	 * DS4 compatible non-Sony devices with different names.
  	 */
510c8b7c1   Roderick Colenbrander   HID: sony: Expose...
1272
  	name_sz = strlen(sc->hdev->name) + sizeof(SENSOR_SUFFIX);
227c011b2   Roderick Colenbrander   HID: sony: Report...
1273
1274
1275
1276
1277
  	name = kzalloc(name_sz, GFP_KERNEL);
  	if (!name) {
  		ret = -ENOMEM;
  		goto err;
  	}
510c8b7c1   Roderick Colenbrander   HID: sony: Expose...
1278
  	snprintf(name, name_sz, "%s" SENSOR_SUFFIX, sc->hdev->name);
227c011b2   Roderick Colenbrander   HID: sony: Report...
1279
  	sc->sensor_dev->name = name;
510c8b7c1   Roderick Colenbrander   HID: sony: Expose...
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
  	if (sc->quirks & SIXAXIS_CONTROLLER) {
  		/* For the DS3 we only support the accelerometer, which works
  		 * quite well even without calibration. The device also has
  		 * a 1-axis gyro, but it is very difficult to manage from within
  		 * the driver even to get data, the sensor is inaccurate and
  		 * the behavior is very different between hardware revisions.
  		 */
  		input_set_abs_params(sc->sensor_dev, ABS_X, -512, 511, 4, 0);
  		input_set_abs_params(sc->sensor_dev, ABS_Y, -512, 511, 4, 0);
  		input_set_abs_params(sc->sensor_dev, ABS_Z, -512, 511, 4, 0);
  		input_abs_set_res(sc->sensor_dev, ABS_X, SIXAXIS_ACC_RES_PER_G);
  		input_abs_set_res(sc->sensor_dev, ABS_Y, SIXAXIS_ACC_RES_PER_G);
  		input_abs_set_res(sc->sensor_dev, ABS_Z, SIXAXIS_ACC_RES_PER_G);
  	} else if (sc->quirks & DUALSHOCK4_CONTROLLER) {
  		range = DS4_ACC_RES_PER_G*4;
  		input_set_abs_params(sc->sensor_dev, ABS_X, -range, range, 16, 0);
  		input_set_abs_params(sc->sensor_dev, ABS_Y, -range, range, 16, 0);
  		input_set_abs_params(sc->sensor_dev, ABS_Z, -range, range, 16, 0);
  		input_abs_set_res(sc->sensor_dev, ABS_X, DS4_ACC_RES_PER_G);
  		input_abs_set_res(sc->sensor_dev, ABS_Y, DS4_ACC_RES_PER_G);
  		input_abs_set_res(sc->sensor_dev, ABS_Z, DS4_ACC_RES_PER_G);
  
  		range = DS4_GYRO_RES_PER_DEG_S*2048;
  		input_set_abs_params(sc->sensor_dev, ABS_RX, -range, range, 16, 0);
  		input_set_abs_params(sc->sensor_dev, ABS_RY, -range, range, 16, 0);
  		input_set_abs_params(sc->sensor_dev, ABS_RZ, -range, range, 16, 0);
  		input_abs_set_res(sc->sensor_dev, ABS_RX, DS4_GYRO_RES_PER_DEG_S);
  		input_abs_set_res(sc->sensor_dev, ABS_RY, DS4_GYRO_RES_PER_DEG_S);
  		input_abs_set_res(sc->sensor_dev, ABS_RZ, DS4_GYRO_RES_PER_DEG_S);
  
  		__set_bit(EV_MSC, sc->sensor_dev->evbit);
  		__set_bit(MSC_TIMESTAMP, sc->sensor_dev->mscbit);
  	}
227c011b2   Roderick Colenbrander   HID: sony: Report...
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
  	__set_bit(INPUT_PROP_ACCELEROMETER, sc->sensor_dev->propbit);
  
  	ret = input_register_device(sc->sensor_dev);
  	if (ret < 0)
  		goto err;
  
  	return 0;
  
  err:
  	kfree(sc->sensor_dev->name);
  	sc->sensor_dev->name = NULL;
  
  	input_free_device(sc->sensor_dev);
  	sc->sensor_dev = NULL;
  
  	return ret;
  }
  
  static void sony_unregister_sensors(struct sony_sc *sc)
  {
  	if (!sc->sensor_dev)
  		return;
  
  	kfree(sc->sensor_dev->name);
  	sc->sensor_dev->name = NULL;
  
  	input_unregister_device(sc->sensor_dev);
  	sc->sensor_dev = NULL;
  }
5710fabf3   Antonio Ospite   HID: hid-sony.c: ...
1342
  /*
bd28ce008   Jiri Slaby   HID: move sony qu...
1343
1344
1345
1346
   * 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 ...
1347
  static int sixaxis_set_operational_usb(struct hid_device *hdev)
bd28ce008   Jiri Slaby   HID: move sony qu...
1348
  {
a85d67b54   Antonio Ospite   HID: sony: Don't ...
1349
1350
  	const int buf_size =
  		max(SIXAXIS_REPORT_0xF2_SIZE, SIXAXIS_REPORT_0xF5_SIZE);
1adf904e9   Pavel Machek   HID: sony: unders...
1351
  	u8 *buf;
bd28ce008   Jiri Slaby   HID: move sony qu...
1352
  	int ret;
bd28ce008   Jiri Slaby   HID: move sony qu...
1353

2e701a359   Antonio Ospite   HID: sony: Coding...
1354
  	buf = kmalloc(buf_size, GFP_KERNEL);
bd28ce008   Jiri Slaby   HID: move sony qu...
1355
1356
  	if (!buf)
  		return -ENOMEM;
a85d67b54   Antonio Ospite   HID: sony: Don't ...
1357
1358
  	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...
1359
1360
1361
1362
1363
  	if (ret < 0) {
  		hid_err(hdev, "can't set operational mode: step 1
  ");
  		goto out;
  	}
f204828a1   Benjamin Tissoires   HID: sony: use hi...
1364

a7de9b867   Lauri Kasanen   HID: sony: Enable...
1365
1366
1367
1368
  	/*
  	 * 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 ...
1369
1370
  	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...
1371
1372
1373
1374
1375
  	if (ret < 0) {
  		hid_err(hdev, "can't set operational mode: step 2
  ");
  		goto out;
  	}
f204828a1   Benjamin Tissoires   HID: sony: use hi...
1376

a7de9b867   Lauri Kasanen   HID: sony: Enable...
1377
  	ret = hid_hw_output_report(hdev, buf, 1);
19f4c2ba8   Benjamin Tissoires   HID: sony: do not...
1378
1379
1380
1381
1382
  	if (ret < 0) {
  		hid_info(hdev, "can't set operational mode: step 3, ignoring
  ");
  		ret = 0;
  	}
bd28ce008   Jiri Slaby   HID: move sony qu...
1383

a7de9b867   Lauri Kasanen   HID: sony: Enable...
1384
  out:
bd28ce008   Jiri Slaby   HID: move sony qu...
1385
1386
1387
1388
  	kfree(buf);
  
  	return ret;
  }
816651a7d   Antonio Ospite   HID: sony: Apply ...
1389
  static int sixaxis_set_operational_bt(struct hid_device *hdev)
f9ce7c283   Bastien Nocera   HID: Enable Sixax...
1390
  {
1adf904e9   Pavel Machek   HID: sony: unders...
1391
1392
  	static const u8 report[] = { 0xf4, 0x42, 0x03, 0x00, 0x00 };
  	u8 *buf;
9b2b5c9a7   Frank Praznik   HID: sony: Use ke...
1393
1394
1395
1396
1397
1398
1399
  	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_...
1400
  				  HID_FEATURE_REPORT, HID_REQ_SET_REPORT);
9b2b5c9a7   Frank Praznik   HID: sony: Use ke...
1401
1402
1403
1404
  
  	kfree(buf);
  
  	return ret;
f9ce7c283   Bastien Nocera   HID: Enable Sixax...
1405
  }
ad142b9e4   Frank Praznik   HID: sony: Fix mu...
1406
  /*
55a07d62d   Roderick Colenbrander   HID: sony: Calibr...
1407
1408
   * Request DS4 calibration data for the motion sensors.
   * For Bluetooth this also affects the operating mode (see below).
68330d83c   Frank Praznik   HID: sony: Add co...
1409
   */
55a07d62d   Roderick Colenbrander   HID: sony: Calibr...
1410
  static int dualshock4_get_calibration_data(struct sony_sc *sc)
68330d83c   Frank Praznik   HID: sony: Add co...
1411
  {
1adf904e9   Pavel Machek   HID: sony: unders...
1412
  	u8 *buf;
9b2b5c9a7   Frank Praznik   HID: sony: Use ke...
1413
  	int ret;
55a07d62d   Roderick Colenbrander   HID: sony: Calibr...
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
  	short gyro_pitch_bias, gyro_pitch_plus, gyro_pitch_minus;
  	short gyro_yaw_bias, gyro_yaw_plus, gyro_yaw_minus;
  	short gyro_roll_bias, gyro_roll_plus, gyro_roll_minus;
  	short gyro_speed_plus, gyro_speed_minus;
  	short acc_x_plus, acc_x_minus;
  	short acc_y_plus, acc_y_minus;
  	short acc_z_plus, acc_z_minus;
  	int speed_2x;
  	int range_2g;
  
  	/* For Bluetooth we use a different request, which supports CRC.
  	 * Note: in Bluetooth mode feature report 0x02 also changes the state
  	 * of the controller, so that it sends input reports of type 0x11.
  	 */
35f436c31   Roderick Colenbrander   HID: sony: Treat ...
1428
  	if (sc->quirks & (DUALSHOCK4_CONTROLLER_USB | DUALSHOCK4_DONGLE)) {
55a07d62d   Roderick Colenbrander   HID: sony: Calibr...
1429
1430
1431
  		buf = kmalloc(DS4_FEATURE_REPORT_0x02_SIZE, GFP_KERNEL);
  		if (!buf)
  			return -ENOMEM;
68330d83c   Frank Praznik   HID: sony: Add co...
1432

55a07d62d   Roderick Colenbrander   HID: sony: Calibr...
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
  		ret = hid_hw_raw_request(sc->hdev, 0x02, buf,
  					 DS4_FEATURE_REPORT_0x02_SIZE,
  					 HID_FEATURE_REPORT,
  					 HID_REQ_GET_REPORT);
  		if (ret < 0)
  			goto err_stop;
  	} else {
  		u8 bthdr = 0xA3;
  		u32 crc;
  		u32 report_crc;
  		int retries;
9b2b5c9a7   Frank Praznik   HID: sony: Use ke...
1444

55a07d62d   Roderick Colenbrander   HID: sony: Calibr...
1445
1446
1447
  		buf = kmalloc(DS4_FEATURE_REPORT_0x05_SIZE, GFP_KERNEL);
  		if (!buf)
  			return -ENOMEM;
9b2b5c9a7   Frank Praznik   HID: sony: Use ke...
1448

55a07d62d   Roderick Colenbrander   HID: sony: Calibr...
1449
1450
1451
1452
1453
1454
1455
  		for (retries = 0; retries < 3; retries++) {
  			ret = hid_hw_raw_request(sc->hdev, 0x05, buf,
  						 DS4_FEATURE_REPORT_0x05_SIZE,
  						 HID_FEATURE_REPORT,
  						 HID_REQ_GET_REPORT);
  			if (ret < 0)
  				goto err_stop;
9b2b5c9a7   Frank Praznik   HID: sony: Use ke...
1456

55a07d62d   Roderick Colenbrander   HID: sony: Calibr...
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
  			/* CRC check */
  			crc = crc32_le(0xFFFFFFFF, &bthdr, 1);
  			crc = ~crc32_le(crc, buf, DS4_FEATURE_REPORT_0x05_SIZE-4);
  			report_crc = get_unaligned_le32(&buf[DS4_FEATURE_REPORT_0x05_SIZE-4]);
  			if (crc != report_crc) {
  				hid_warn(sc->hdev, "DualShock 4 calibration report's CRC check failed, received crc 0x%0x != 0x%0x
  ",
  					report_crc, crc);
  				if (retries < 2) {
  					hid_warn(sc->hdev, "Retrying DualShock 4 get calibration report request
  ");
  					continue;
  				} else {
  					ret = -EILSEQ;
  					goto err_stop;
  				}
  			} else {
  				break;
  			}
  		}
  	}
9b2b5c9a7   Frank Praznik   HID: sony: Use ke...
1478

55a07d62d   Roderick Colenbrander   HID: sony: Calibr...
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
  	gyro_pitch_bias  = get_unaligned_le16(&buf[1]);
  	gyro_yaw_bias    = get_unaligned_le16(&buf[3]);
  	gyro_roll_bias   = get_unaligned_le16(&buf[5]);
  	if (sc->quirks & DUALSHOCK4_CONTROLLER_USB) {
  		gyro_pitch_plus  = get_unaligned_le16(&buf[7]);
  		gyro_pitch_minus = get_unaligned_le16(&buf[9]);
  		gyro_yaw_plus    = get_unaligned_le16(&buf[11]);
  		gyro_yaw_minus   = get_unaligned_le16(&buf[13]);
  		gyro_roll_plus   = get_unaligned_le16(&buf[15]);
  		gyro_roll_minus  = get_unaligned_le16(&buf[17]);
  	} else {
35f436c31   Roderick Colenbrander   HID: sony: Treat ...
1490
  		/* BT + Dongle */
55a07d62d   Roderick Colenbrander   HID: sony: Calibr...
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
  		gyro_pitch_plus  = get_unaligned_le16(&buf[7]);
  		gyro_yaw_plus    = get_unaligned_le16(&buf[9]);
  		gyro_roll_plus   = get_unaligned_le16(&buf[11]);
  		gyro_pitch_minus = get_unaligned_le16(&buf[13]);
  		gyro_yaw_minus   = get_unaligned_le16(&buf[15]);
  		gyro_roll_minus  = get_unaligned_le16(&buf[17]);
  	}
  	gyro_speed_plus  = get_unaligned_le16(&buf[19]);
  	gyro_speed_minus = get_unaligned_le16(&buf[21]);
  	acc_x_plus       = get_unaligned_le16(&buf[23]);
  	acc_x_minus      = get_unaligned_le16(&buf[25]);
  	acc_y_plus       = get_unaligned_le16(&buf[27]);
  	acc_y_minus      = get_unaligned_le16(&buf[29]);
  	acc_z_plus       = get_unaligned_le16(&buf[31]);
  	acc_z_minus      = get_unaligned_le16(&buf[33]);
  
  	/* Set gyroscope calibration and normalization parameters.
  	 * Data values will be normalized to 1/DS4_GYRO_RES_PER_DEG_S degree/s.
  	 */
  	speed_2x = (gyro_speed_plus + gyro_speed_minus);
  	sc->ds4_calib_data[0].abs_code = ABS_RX;
  	sc->ds4_calib_data[0].bias = gyro_pitch_bias;
  	sc->ds4_calib_data[0].sens_numer = speed_2x*DS4_GYRO_RES_PER_DEG_S;
  	sc->ds4_calib_data[0].sens_denom = gyro_pitch_plus - gyro_pitch_minus;
  
  	sc->ds4_calib_data[1].abs_code = ABS_RY;
  	sc->ds4_calib_data[1].bias = gyro_yaw_bias;
  	sc->ds4_calib_data[1].sens_numer = speed_2x*DS4_GYRO_RES_PER_DEG_S;
  	sc->ds4_calib_data[1].sens_denom = gyro_yaw_plus - gyro_yaw_minus;
  
  	sc->ds4_calib_data[2].abs_code = ABS_RZ;
  	sc->ds4_calib_data[2].bias = gyro_roll_bias;
  	sc->ds4_calib_data[2].sens_numer = speed_2x*DS4_GYRO_RES_PER_DEG_S;
  	sc->ds4_calib_data[2].sens_denom = gyro_roll_plus - gyro_roll_minus;
  
  	/* Set accelerometer calibration and normalization parameters.
  	 * Data values will be normalized to 1/DS4_ACC_RES_PER_G G.
  	 */
  	range_2g = acc_x_plus - acc_x_minus;
  	sc->ds4_calib_data[3].abs_code = ABS_X;
  	sc->ds4_calib_data[3].bias = acc_x_plus - range_2g / 2;
  	sc->ds4_calib_data[3].sens_numer = 2*DS4_ACC_RES_PER_G;
  	sc->ds4_calib_data[3].sens_denom = range_2g;
  
  	range_2g = acc_y_plus - acc_y_minus;
  	sc->ds4_calib_data[4].abs_code = ABS_Y;
  	sc->ds4_calib_data[4].bias = acc_y_plus - range_2g / 2;
  	sc->ds4_calib_data[4].sens_numer = 2*DS4_ACC_RES_PER_G;
  	sc->ds4_calib_data[4].sens_denom = range_2g;
  
  	range_2g = acc_z_plus - acc_z_minus;
  	sc->ds4_calib_data[5].abs_code = ABS_Z;
  	sc->ds4_calib_data[5].bias = acc_z_plus - range_2g / 2;
  	sc->ds4_calib_data[5].sens_numer = 2*DS4_ACC_RES_PER_G;
  	sc->ds4_calib_data[5].sens_denom = range_2g;
  
  err_stop:
  	kfree(buf);
9b2b5c9a7   Frank Praznik   HID: sony: Use ke...
1549
  	return ret;
f9ce7c283   Bastien Nocera   HID: Enable Sixax...
1550
  }
f2f47c385   Roderick Colenbrander   HID: sony: Suppor...
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
  static void dualshock4_calibration_work(struct work_struct *work)
  {
  	struct sony_sc *sc = container_of(work, struct sony_sc, hotplug_worker);
  	unsigned long flags;
  	enum ds4_dongle_state dongle_state;
  	int ret;
  
  	ret = dualshock4_get_calibration_data(sc);
  	if (ret < 0) {
  		/* This call is very unlikely to fail for the dongle. When it
  		 * fails we are probably in a very bad state, so mark the
  		 * dongle as disabled. We will re-enable the dongle if a new
  		 * DS4 hotplug is detect from sony_raw_event as any issues
  		 * are likely resolved then (the dongle is quite stupid).
  		 */
  		hid_err(sc->hdev, "DualShock 4 USB dongle: calibration failed, disabling device
  ");
  		dongle_state = DONGLE_DISABLED;
  	} else {
  		hid_info(sc->hdev, "DualShock 4 USB dongle: calibration completed
  ");
  		dongle_state = DONGLE_CONNECTED;
  	}
  
  	spin_lock_irqsave(&sc->lock, flags);
  	sc->ds4_dongle_state = dongle_state;
  	spin_unlock_irqrestore(&sc->lock, flags);
  }
221399b36   Frank Praznik   HID: sony: Simpli...
1579
  static void sixaxis_set_leds_from_id(struct sony_sc *sc)
8025087ac   Frank Praznik   HID: sony: Initia...
1580
  {
1adf904e9   Pavel Machek   HID: sony: unders...
1581
  	static const u8 sixaxis_leds[10][4] = {
8025087ac   Frank Praznik   HID: sony: Initia...
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
  				{ 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...
1593
1594
1595
  	int id = sc->device_id;
  
  	BUILD_BUG_ON(MAX_LEDS < ARRAY_SIZE(sixaxis_leds[0]));
8025087ac   Frank Praznik   HID: sony: Initia...
1596
1597
1598
1599
1600
  
  	if (id < 0)
  		return;
  
  	id %= 10;
221399b36   Frank Praznik   HID: sony: Simpli...
1601
  	memcpy(sc->led_state, sixaxis_leds[id], sizeof(sixaxis_leds[id]));
8025087ac   Frank Praznik   HID: sony: Initia...
1602
  }
221399b36   Frank Praznik   HID: sony: Simpli...
1603
  static void dualshock4_set_leds_from_id(struct sony_sc *sc)
8025087ac   Frank Praznik   HID: sony: Initia...
1604
1605
  {
  	/* The first 4 color/index entries match what the PS4 assigns */
1adf904e9   Pavel Machek   HID: sony: unders...
1606
  	static const u8 color_code[7][3] = {
39254a13d   Roderick Colenbrander   HID: sony: DS4 us...
1607
1608
1609
1610
  			/* Blue   */	{ 0x00, 0x00, 0x40 },
  			/* Red	  */	{ 0x40, 0x00, 0x00 },
  			/* Green  */	{ 0x00, 0x40, 0x00 },
  			/* Pink   */	{ 0x20, 0x00, 0x20 },
8025087ac   Frank Praznik   HID: sony: Initia...
1611
1612
1613
1614
  			/* Orange */	{ 0x02, 0x01, 0x00 },
  			/* Teal   */	{ 0x00, 0x01, 0x01 },
  			/* White  */	{ 0x01, 0x01, 0x01 }
  	};
221399b36   Frank Praznik   HID: sony: Simpli...
1615
1616
1617
  	int id = sc->device_id;
  
  	BUILD_BUG_ON(MAX_LEDS < ARRAY_SIZE(color_code[0]));
8025087ac   Frank Praznik   HID: sony: Initia...
1618
1619
1620
1621
1622
  
  	if (id < 0)
  		return;
  
  	id %= 7;
221399b36   Frank Praznik   HID: sony: Simpli...
1623
  	memcpy(sc->led_state, color_code[id], sizeof(color_code[id]));
8025087ac   Frank Praznik   HID: sony: Initia...
1624
  }
221399b36   Frank Praznik   HID: sony: Simpli...
1625
  static void buzz_set_leds(struct sony_sc *sc)
f04d51404   Colin Leitner   HID: driver for P...
1626
  {
221399b36   Frank Praznik   HID: sony: Simpli...
1627
  	struct hid_device *hdev = sc->hdev;
f04d51404   Colin Leitner   HID: driver for P...
1628
1629
1630
1631
  	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...
1632
  	s32 *value = report->field[0]->value;
f04d51404   Colin Leitner   HID: driver for P...
1633

221399b36   Frank Praznik   HID: sony: Simpli...
1634
  	BUILD_BUG_ON(MAX_LEDS < 4);
f04d51404   Colin Leitner   HID: driver for P...
1635
  	value[0] = 0x00;
221399b36   Frank Praznik   HID: sony: Simpli...
1636
1637
1638
1639
  	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...
1640
1641
1642
1643
  	value[5] = 0x00;
  	value[6] = 0x00;
  	hid_hw_request(hdev, report, HID_REQ_SET_REPORT);
  }
221399b36   Frank Praznik   HID: sony: Simpli...
1644
  static void sony_set_leds(struct sony_sc *sc)
0a286ef27   Sven Eckelmann   HID: sony: Add LE...
1645
  {
221399b36   Frank Praznik   HID: sony: Simpli...
1646
  	if (!(sc->quirks & BUZZ_CONTROLLER))
b53227360   Roderick Colenbrander   HID: sony: Make w...
1647
  		sony_schedule_work(sc, SONY_WORKER_STATE);
221399b36   Frank Praznik   HID: sony: Simpli...
1648
1649
  	else
  		buzz_set_leds(sc);
0a286ef27   Sven Eckelmann   HID: sony: Add LE...
1650
  }
c53825190   Sven Eckelmann   HID: sony: Rename...
1651
  static void sony_led_set_brightness(struct led_classdev *led,
f04d51404   Colin Leitner   HID: driver for P...
1652
1653
1654
  				    enum led_brightness value)
  {
  	struct device *dev = led->dev->parent;
ee79a8f84   Geliang Tang   HID: use to_hid_d...
1655
  	struct hid_device *hdev = to_hid_device(dev);
f04d51404   Colin Leitner   HID: driver for P...
1656
  	struct sony_sc *drv_data;
f04d51404   Colin Leitner   HID: driver for P...
1657
1658
  
  	int n;
b3ed458c1   Frank Praznik   HID: sony: Add bl...
1659
  	int force_update;
f04d51404   Colin Leitner   HID: driver for P...
1660
1661
  
  	drv_data = hid_get_drvdata(hdev);
2251b85f3   Sven Eckelmann   HID: sony: Move L...
1662
  	if (!drv_data) {
f04d51404   Colin Leitner   HID: driver for P...
1663
1664
1665
1666
  		hid_err(hdev, "No device data
  ");
  		return;
  	}
f04d51404   Colin Leitner   HID: driver for P...
1667

b3ed458c1   Frank Praznik   HID: sony: Add bl...
1668
1669
1670
1671
1672
1673
1674
1675
  	/*
  	 * 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...
1676
  	for (n = 0; n < drv_data->led_count; n++) {
b3ed458c1   Frank Praznik   HID: sony: Add bl...
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
  		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...
1687
  			sony_set_leds(drv_data);
f04d51404   Colin Leitner   HID: driver for P...
1688
1689
1690
1691
  			break;
  		}
  	}
  }
c53825190   Sven Eckelmann   HID: sony: Rename...
1692
  static enum led_brightness sony_led_get_brightness(struct led_classdev *led)
f04d51404   Colin Leitner   HID: driver for P...
1693
1694
  {
  	struct device *dev = led->dev->parent;
ee79a8f84   Geliang Tang   HID: use to_hid_d...
1695
  	struct hid_device *hdev = to_hid_device(dev);
f04d51404   Colin Leitner   HID: driver for P...
1696
  	struct sony_sc *drv_data;
f04d51404   Colin Leitner   HID: driver for P...
1697
1698
  
  	int n;
f04d51404   Colin Leitner   HID: driver for P...
1699
1700
  
  	drv_data = hid_get_drvdata(hdev);
2251b85f3   Sven Eckelmann   HID: sony: Move L...
1701
  	if (!drv_data) {
f04d51404   Colin Leitner   HID: driver for P...
1702
1703
1704
1705
  		hid_err(hdev, "No device data
  ");
  		return LED_OFF;
  	}
f04d51404   Colin Leitner   HID: driver for P...
1706

60781cf48   Frank Praznik   HID: sony: Add LE...
1707
  	for (n = 0; n < drv_data->led_count; n++) {
7db7504a4   Simon Wood   HID: hid-sony: re...
1708
1709
  		if (led == drv_data->leds[n])
  			return drv_data->led_state[n];
f04d51404   Colin Leitner   HID: driver for P...
1710
  	}
7db7504a4   Simon Wood   HID: hid-sony: re...
1711
  	return LED_OFF;
f04d51404   Colin Leitner   HID: driver for P...
1712
  }
f04d51404   Colin Leitner   HID: driver for P...
1713

b3ed458c1   Frank Praznik   HID: sony: Add bl...
1714
1715
1716
1717
  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...
1718
  	struct hid_device *hdev = to_hid_device(dev);
b3ed458c1   Frank Praznik   HID: sony: Add bl...
1719
1720
  	struct sony_sc *drv_data = hid_get_drvdata(hdev);
  	int n;
1adf904e9   Pavel Machek   HID: sony: unders...
1721
  	u8 new_on, new_off;
b3ed458c1   Frank Praznik   HID: sony: Add bl...
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
  
  	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;
b53227360   Roderick Colenbrander   HID: sony: Make w...
1756
  		sony_schedule_work(drv_data, SONY_WORKER_STATE);
b3ed458c1   Frank Praznik   HID: sony: Add bl...
1757
1758
1759
1760
  	}
  
  	return 0;
  }
fa57a8107   Frank Praznik   HID: sony: Conver...
1761
  static void sony_leds_remove(struct sony_sc *sc)
0a286ef27   Sven Eckelmann   HID: sony: Add LE...
1762
  {
0a286ef27   Sven Eckelmann   HID: sony: Add LE...
1763
1764
  	struct led_classdev *led;
  	int n;
fa57a8107   Frank Praznik   HID: sony: Conver...
1765
  	BUG_ON(!(sc->quirks & SONY_LED_SUPPORT));
0a286ef27   Sven Eckelmann   HID: sony: Add LE...
1766

fa57a8107   Frank Praznik   HID: sony: Conver...
1767
1768
1769
  	for (n = 0; n < sc->led_count; n++) {
  		led = sc->leds[n];
  		sc->leds[n] = NULL;
0a286ef27   Sven Eckelmann   HID: sony: Add LE...
1770
1771
1772
1773
1774
  		if (!led)
  			continue;
  		led_classdev_unregister(led);
  		kfree(led);
  	}
60781cf48   Frank Praznik   HID: sony: Add LE...
1775

fa57a8107   Frank Praznik   HID: sony: Conver...
1776
  	sc->led_count = 0;
0a286ef27   Sven Eckelmann   HID: sony: Add LE...
1777
  }
fa57a8107   Frank Praznik   HID: sony: Conver...
1778
  static int sony_leds_init(struct sony_sc *sc)
f04d51404   Colin Leitner   HID: driver for P...
1779
  {
fa57a8107   Frank Praznik   HID: sony: Conver...
1780
  	struct hid_device *hdev = sc->hdev;
40e32ee6e   Jiri Kosina   HID: sony: fix le...
1781
  	int n, ret = 0;
b3ed458c1   Frank Praznik   HID: sony: Add bl...
1782
  	int use_ds4_names;
40e32ee6e   Jiri Kosina   HID: sony: fix le...
1783
1784
1785
  	struct led_classdev *led;
  	size_t name_sz;
  	char *name;
0a286ef27   Sven Eckelmann   HID: sony: Add LE...
1786
1787
  	size_t name_len;
  	const char *name_fmt;
b3ed458c1   Frank Praznik   HID: sony: Add bl...
1788
1789
  	static const char * const ds4_name_str[] = { "red", "green", "blue",
  						  "global" };
1adf904e9   Pavel Machek   HID: sony: unders...
1790
1791
  	u8 max_brightness[MAX_LEDS] = { [0 ... (MAX_LEDS - 1)] = 1 };
  	u8 use_hw_blink[MAX_LEDS] = { 0 };
f04d51404   Colin Leitner   HID: driver for P...
1792

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

fa57a8107   Frank Praznik   HID: sony: Conver...
1795
1796
  	if (sc->quirks & BUZZ_CONTROLLER) {
  		sc->led_count = 4;
b3ed458c1   Frank Praznik   HID: sony: Add bl...
1797
  		use_ds4_names = 0;
0a286ef27   Sven Eckelmann   HID: sony: Add LE...
1798
1799
1800
1801
1802
  		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...
1803
  	} else if (sc->quirks & DUALSHOCK4_CONTROLLER) {
221399b36   Frank Praznik   HID: sony: Simpli...
1804
1805
  		dualshock4_set_leds_from_id(sc);
  		sc->led_state[3] = 1;
b3ed458c1   Frank Praznik   HID: sony: Add bl...
1806
1807
1808
1809
  		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...
1810
1811
  		name_len = 0;
  		name_fmt = "%s:%s";
c5e0c1c49   Frank Praznik   HID: sony: Add su...
1812
1813
1814
1815
1816
1817
  	} 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...
1818
  	} else if (sc->quirks & NAVIGATION_CONTROLLER) {
1adf904e9   Pavel Machek   HID: sony: unders...
1819
  		static const u8 navigation_leds[4] = {0x01, 0x00, 0x00, 0x00};
4545ee0a7   Simon Wood   HID: hid-sony: Na...
1820
1821
1822
1823
1824
1825
1826
  
  		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...
1827
  	} else {
221399b36   Frank Praznik   HID: sony: Simpli...
1828
  		sixaxis_set_leds_from_id(sc);
fa57a8107   Frank Praznik   HID: sony: Conver...
1829
  		sc->led_count = 4;
b3ed458c1   Frank Praznik   HID: sony: Add bl...
1830
1831
  		memset(use_hw_blink, 1, 4);
  		use_ds4_names = 0;
61ebca937   Frank Praznik   HID: sony: Use co...
1832
1833
  		name_len = strlen("::sony#");
  		name_fmt = "%s::sony%d";
60781cf48   Frank Praznik   HID: sony: Add LE...
1834
  	}
ad142b9e4   Frank Praznik   HID: sony: Fix mu...
1835
1836
  	/*
  	 * Clear LEDs as we have no way of reading their initial state. This is
f04d51404   Colin Leitner   HID: driver for P...
1837
  	 * only relevant if the driver is loaded after somebody actively set the
ad142b9e4   Frank Praznik   HID: sony: Fix mu...
1838
1839
  	 * LEDs to on
  	 */
221399b36   Frank Praznik   HID: sony: Simpli...
1840
  	sony_set_leds(sc);
f04d51404   Colin Leitner   HID: driver for P...
1841

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

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

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

40e32ee6e   Jiri Kosina   HID: sony: fix le...
1849
1850
1851
1852
  		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...
1853
  			ret = -ENOMEM;
40e32ee6e   Jiri Kosina   HID: sony: fix le...
1854
1855
  			goto error_leds;
  		}
f04d51404   Colin Leitner   HID: driver for P...
1856

40e32ee6e   Jiri Kosina   HID: sony: fix le...
1857
  		name = (void *)(&led[1]);
b3ed458c1   Frank Praznik   HID: sony: Add bl...
1858
1859
1860
  		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...
1861
1862
  		else
  			snprintf(name, name_sz, name_fmt, dev_name(&hdev->dev), n + 1);
40e32ee6e   Jiri Kosina   HID: sony: fix le...
1863
  		led->name = name;
221399b36   Frank Praznik   HID: sony: Simpli...
1864
  		led->brightness = sc->led_state[n];
b3ed458c1   Frank Praznik   HID: sony: Add bl...
1865
  		led->max_brightness = max_brightness[n];
765a1077c   Frank Praznik   HID: sony: Use LE...
1866
  		led->flags = LED_CORE_SUSPENDRESUME;
c53825190   Sven Eckelmann   HID: sony: Rename...
1867
1868
  		led->brightness_get = sony_led_get_brightness;
  		led->brightness_set = sony_led_set_brightness;
f04d51404   Colin Leitner   HID: driver for P...
1869

b3ed458c1   Frank Praznik   HID: sony: Add bl...
1870
1871
  		if (use_hw_blink[n])
  			led->blink_set = sony_led_blink_set;
8025087ac   Frank Praznik   HID: sony: Initia...
1872
  		sc->leds[n] = led;
8cd5fcda2   Julia Lawall   HID: sony: fix er...
1873
1874
  		ret = led_classdev_register(&hdev->dev, led);
  		if (ret) {
40e32ee6e   Jiri Kosina   HID: sony: fix le...
1875
1876
  			hid_err(hdev, "Failed to register LED %d
  ", n);
8025087ac   Frank Praznik   HID: sony: Initia...
1877
  			sc->leds[n] = NULL;
40e32ee6e   Jiri Kosina   HID: sony: fix le...
1878
1879
  			kfree(led);
  			goto error_leds;
f04d51404   Colin Leitner   HID: driver for P...
1880
1881
  		}
  	}
f04d51404   Colin Leitner   HID: driver for P...
1882
1883
  
  	return ret;
f04d51404   Colin Leitner   HID: driver for P...
1884
  error_leds:
fa57a8107   Frank Praznik   HID: sony: Conver...
1885
  	sony_leds_remove(sc);
f04d51404   Colin Leitner   HID: driver for P...
1886

f04d51404   Colin Leitner   HID: driver for P...
1887
  	return ret;
f04d51404   Colin Leitner   HID: driver for P...
1888
  }
d8aaccda7   Frank Praznik   HID: sony: Refact...
1889
  static void sixaxis_send_output_report(struct sony_sc *sc)
a08c22c0d   Sven Eckelmann   HID: sony: Add fo...
1890
  {
9b2b5c9a7   Frank Praznik   HID: sony: Use ke...
1891
  	static const union sixaxis_output_report_01 default_report = {
55d3b664d   Frank Praznik   HID: sony: Use a ...
1892
1893
  		.buf = {
  			0x01,
ad07b7a6c   Scott Moreau   HID: sony: Fixup ...
1894
  			0x01, 0xff, 0x00, 0xff, 0x00,
55d3b664d   Frank Praznik   HID: sony: Use a ...
1895
1896
1897
1898
1899
1900
1901
  			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...
1902
  	};
9b2b5c9a7   Frank Praznik   HID: sony: Use ke...
1903
1904
1905
1906
1907
1908
  	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...
1909

0a286ef27   Sven Eckelmann   HID: sony: Add LE...
1910
  #ifdef CONFIG_SONY_FF
9b2b5c9a7   Frank Praznik   HID: sony: Use ke...
1911
1912
  	report->rumble.right_motor_on = sc->right ? 1 : 0;
  	report->rumble.left_motor_force = sc->left;
0a286ef27   Sven Eckelmann   HID: sony: Add LE...
1913
  #endif
9b2b5c9a7   Frank Praznik   HID: sony: Use ke...
1914
1915
1916
1917
  	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...
1918

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

b3ed458c1   Frank Praznik   HID: sony: Add bl...
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
  	/*
  	 * 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...
1934
1935
  			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...
1936
1937
  		}
  	}
1adf904e9   Pavel Machek   HID: sony: unders...
1938
  	hid_hw_raw_request(sc->hdev, report->report_id, (u8 *)report,
9b2b5c9a7   Frank Praznik   HID: sony: Use ke...
1939
1940
  			sizeof(struct sixaxis_output_report),
  			HID_OUTPUT_REPORT, HID_REQ_SET_REPORT);
9f323b681   Sven Eckelmann   HID: sony: Send F...
1941
  }
d8aaccda7   Frank Praznik   HID: sony: Refact...
1942
  static void dualshock4_send_output_report(struct sony_sc *sc)
0bd88dd3d   Frank Praznik   HID: sony: Add fo...
1943
  {
0da8ea658   Frank Praznik   HID: sony: Use st...
1944
  	struct hid_device *hdev = sc->hdev;
1adf904e9   Pavel Machek   HID: sony: unders...
1945
  	u8 *buf = sc->output_report_dmabuf;
48220237b   Frank Praznik   HID: sony: Use lo...
1946
  	int offset;
c4425c8f2   Frank Praznik   HID: sony: Update...
1947
  	/*
77b499e73   Roderick Colenbrander   HID: sony: Make D...
1948
1949
1950
1951
1952
1953
1954
  	 * NOTE: The lower 6 bits of buf[1] field of the Bluetooth report
  	 * control the interval at which Dualshock 4 reports data:
  	 * 0x00 - 1ms
  	 * 0x01 - 1ms
  	 * 0x02 - 2ms
  	 * 0x3E - 62ms
  	 * 0x3F - disabled
c4425c8f2   Frank Praznik   HID: sony: Update...
1955
  	 */
35f436c31   Roderick Colenbrander   HID: sony: Treat ...
1956
  	if (sc->quirks & (DUALSHOCK4_CONTROLLER_USB | DUALSHOCK4_DONGLE)) {
2c159de05   Roderick Colenbrander   HID: sony: Adjust...
1957
  		memset(buf, 0, DS4_OUTPUT_REPORT_0x05_SIZE);
fdcf105d3   Frank Praznik   HID: sony: Add Du...
1958
  		buf[0] = 0x05;
5caceb069   Roderick Colenbrander   HID: sony: Set pr...
1959
  		buf[1] = 0x07; /* blink + LEDs + motor */
fdcf105d3   Frank Praznik   HID: sony: Add Du...
1960
1961
  		offset = 4;
  	} else {
2c159de05   Roderick Colenbrander   HID: sony: Adjust...
1962
  		memset(buf, 0, DS4_OUTPUT_REPORT_0x11_SIZE);
fdcf105d3   Frank Praznik   HID: sony: Add Du...
1963
  		buf[0] = 0x11;
77b499e73   Roderick Colenbrander   HID: sony: Make D...
1964
  		buf[1] = 0xC0 /* HID + CRC */ | sc->ds4_bt_poll_interval;
5caceb069   Roderick Colenbrander   HID: sony: Set pr...
1965
  		buf[3] = 0x07; /* blink + LEDs + motor */
fdcf105d3   Frank Praznik   HID: sony: Add Du...
1966
1967
  		offset = 6;
  	}
0bd88dd3d   Frank Praznik   HID: sony: Add fo...
1968
1969
  
  #ifdef CONFIG_SONY_FF
48220237b   Frank Praznik   HID: sony: Use lo...
1970
1971
1972
1973
  	buf[offset++] = sc->right;
  	buf[offset++] = sc->left;
  #else
  	offset += 2;
0bd88dd3d   Frank Praznik   HID: sony: Add fo...
1974
  #endif
b3ed458c1   Frank Praznik   HID: sony: Add bl...
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
  	/* 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...
1987

35f436c31   Roderick Colenbrander   HID: sony: Treat ...
1988
  	if (sc->quirks & (DUALSHOCK4_CONTROLLER_USB | DUALSHOCK4_DONGLE))
2c159de05   Roderick Colenbrander   HID: sony: Adjust...
1989
  		hid_hw_output_report(hdev, buf, DS4_OUTPUT_REPORT_0x05_SIZE);
e7ef53adb   Roderick Colenbrander   HID: sony: Send d...
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
  	else {
  		/* CRC generation */
  		u8 bthdr = 0xA2;
  		u32 crc;
  
  		crc = crc32_le(0xFFFFFFFF, &bthdr, 1);
  		crc = ~crc32_le(crc, buf, DS4_OUTPUT_REPORT_0x11_SIZE-4);
  		put_unaligned_le32(crc, &buf[74]);
  		hid_hw_output_report(hdev, buf, DS4_OUTPUT_REPORT_0x11_SIZE);
  	}
0bd88dd3d   Frank Praznik   HID: sony: Add fo...
2000
  }
d8aaccda7   Frank Praznik   HID: sony: Refact...
2001
  static void motion_send_output_report(struct sony_sc *sc)
c5e0c1c49   Frank Praznik   HID: sony: Add su...
2002
  {
c5e0c1c49   Frank Praznik   HID: sony: Add su...
2003
2004
2005
  	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...
2006
  	memset(report, 0, MOTION_REPORT_0x02_SIZE);
c5e0c1c49   Frank Praznik   HID: sony: Add su...
2007
2008
2009
2010
2011
2012
2013
2014
2015
  
  	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...
2016
  	hid_hw_output_report(hdev, (u8 *)report, MOTION_REPORT_0x02_SIZE);
c5e0c1c49   Frank Praznik   HID: sony: Add su...
2017
  }
decd946c9   Frank Praznik   HID: sony: Save a...
2018
2019
2020
2021
2022
  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...
2023
2024
2025
  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...
2026

d8aaccda7   Frank Praznik   HID: sony: Refact...
2027
2028
  	sc->send_output_report(sc);
  }
9b2b5c9a7   Frank Praznik   HID: sony: Use ke...
2029
2030
  static int sony_allocate_output_report(struct sony_sc *sc)
  {
4545ee0a7   Simon Wood   HID: hid-sony: Na...
2031
2032
  	if ((sc->quirks & SIXAXIS_CONTROLLER) ||
  			(sc->quirks & NAVIGATION_CONTROLLER))
9b2b5c9a7   Frank Praznik   HID: sony: Use ke...
2033
2034
2035
2036
  		sc->output_report_dmabuf =
  			kmalloc(sizeof(union sixaxis_output_report_01),
  				GFP_KERNEL);
  	else if (sc->quirks & DUALSHOCK4_CONTROLLER_BT)
2c159de05   Roderick Colenbrander   HID: sony: Adjust...
2037
  		sc->output_report_dmabuf = kmalloc(DS4_OUTPUT_REPORT_0x11_SIZE,
9b2b5c9a7   Frank Praznik   HID: sony: Use ke...
2038
  						GFP_KERNEL);
35f436c31   Roderick Colenbrander   HID: sony: Treat ...
2039
  	else if (sc->quirks & (DUALSHOCK4_CONTROLLER_USB | DUALSHOCK4_DONGLE))
2c159de05   Roderick Colenbrander   HID: sony: Adjust...
2040
  		sc->output_report_dmabuf = kmalloc(DS4_OUTPUT_REPORT_0x05_SIZE,
9b2b5c9a7   Frank Praznik   HID: sony: Use ke...
2041
  						GFP_KERNEL);
c5e0c1c49   Frank Praznik   HID: sony: Add su...
2042
  	else if (sc->quirks & MOTION_CONTROLLER)
41d2d4253   Simon Wood   HID: sony: PS3 Mo...
2043
2044
  		sc->output_report_dmabuf = kmalloc(MOTION_REPORT_0x02_SIZE,
  						GFP_KERNEL);
9b2b5c9a7   Frank Praznik   HID: sony: Use ke...
2045
2046
2047
2048
2049
2050
2051
2052
  	else
  		return 0;
  
  	if (!sc->output_report_dmabuf)
  		return -ENOMEM;
  
  	return 0;
  }
0a286ef27   Sven Eckelmann   HID: sony: Add LE...
2053
  #ifdef CONFIG_SONY_FF
9f323b681   Sven Eckelmann   HID: sony: Send F...
2054
2055
2056
  static int sony_play_effect(struct input_dev *dev, void *data,
  			    struct ff_effect *effect)
  {
a08c22c0d   Sven Eckelmann   HID: sony: Add fo...
2057
  	struct hid_device *hid = input_get_drvdata(dev);
9f323b681   Sven Eckelmann   HID: sony: Send F...
2058
  	struct sony_sc *sc = hid_get_drvdata(hid);
a08c22c0d   Sven Eckelmann   HID: sony: Add fo...
2059
2060
2061
  
  	if (effect->type != FF_RUMBLE)
  		return 0;
9f323b681   Sven Eckelmann   HID: sony: Send F...
2062
  	sc->left = effect->u.rumble.strong_magnitude / 256;
0bd88dd3d   Frank Praznik   HID: sony: Add fo...
2063
  	sc->right = effect->u.rumble.weak_magnitude / 256;
a08c22c0d   Sven Eckelmann   HID: sony: Add fo...
2064

b53227360   Roderick Colenbrander   HID: sony: Make w...
2065
  	sony_schedule_work(sc, SONY_WORKER_STATE);
9f323b681   Sven Eckelmann   HID: sony: Send F...
2066
  	return 0;
a08c22c0d   Sven Eckelmann   HID: sony: Add fo...
2067
  }
fa57a8107   Frank Praznik   HID: sony: Conver...
2068
  static int sony_init_ff(struct sony_sc *sc)
a08c22c0d   Sven Eckelmann   HID: sony: Add fo...
2069
  {
fa57a8107   Frank Praznik   HID: sony: Conver...
2070
  	struct hid_input *hidinput = list_entry(sc->hdev->inputs.next,
a08c22c0d   Sven Eckelmann   HID: sony: Add fo...
2071
2072
2073
2074
2075
2076
2077
2078
  						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...
2079
  static int sony_init_ff(struct sony_sc *sc)
a08c22c0d   Sven Eckelmann   HID: sony: Add fo...
2080
2081
2082
  {
  	return 0;
  }
9f323b681   Sven Eckelmann   HID: sony: Send F...
2083

a08c22c0d   Sven Eckelmann   HID: sony: Add fo...
2084
  #endif
d902f4724   Frank Praznik   HID: sony: add ba...
2085
2086
2087
2088
  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...
2089
  	struct sony_sc *sc = power_supply_get_drvdata(psy);
d902f4724   Frank Praznik   HID: sony: add ba...
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
  	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...
2124
  }
0f3982308   Frank Praznik   HID: sony: Relax ...
2125
  static int sony_battery_probe(struct sony_sc *sc, int append_dev_id)
c4e1ddf26   Frank Praznik   HID: sony: Cache ...
2126
  {
0f3982308   Frank Praznik   HID: sony: Relax ...
2127
2128
2129
  	const char *battery_str_fmt = append_dev_id ?
  		"sony_controller_battery_%pMR_%i" :
  		"sony_controller_battery_%pMR";
297d716f6   Krzysztof Kozlowski   power_supply: Cha...
2130
  	struct power_supply_config psy_cfg = { .drv_data = sc, };
c4e1ddf26   Frank Praznik   HID: sony: Cache ...
2131
  	struct hid_device *hdev = sc->hdev;
d902f4724   Frank Praznik   HID: sony: add ba...
2132
  	int ret;
c4e1ddf26   Frank Praznik   HID: sony: Cache ...
2133

ad142b9e4   Frank Praznik   HID: sony: Fix mu...
2134
2135
  	/*
  	 * Set the default battery level to 100% to avoid low battery warnings
d9a293a95   Frank Praznik   HID: sony: Set in...
2136
2137
2138
  	 * if the battery is polled before the first device report is received.
  	 */
  	sc->battery_capacity = 100;
297d716f6   Krzysztof Kozlowski   power_supply: Cha...
2139
2140
2141
2142
2143
  	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;
0f3982308   Frank Praznik   HID: sony: Relax ...
2144
2145
  	sc->battery_desc.name = kasprintf(GFP_KERNEL, battery_str_fmt,
  					  sc->mac_address, sc->device_id);
297d716f6   Krzysztof Kozlowski   power_supply: Cha...
2146
  	if (!sc->battery_desc.name)
d902f4724   Frank Praznik   HID: sony: add ba...
2147
  		return -ENOMEM;
c4e1ddf26   Frank Praznik   HID: sony: Cache ...
2148

297d716f6   Krzysztof Kozlowski   power_supply: Cha...
2149
2150
2151
2152
  	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...
2153
2154
2155
2156
  		hid_err(hdev, "Unable to register battery device
  ");
  		goto err_free;
  	}
c4e1ddf26   Frank Praznik   HID: sony: Cache ...
2157

297d716f6   Krzysztof Kozlowski   power_supply: Cha...
2158
  	power_supply_powers(sc->battery, &hdev->dev);
a08c22c0d   Sven Eckelmann   HID: sony: Add fo...
2159
  	return 0;
d902f4724   Frank Praznik   HID: sony: add ba...
2160
2161
  
  err_free:
297d716f6   Krzysztof Kozlowski   power_supply: Cha...
2162
2163
  	kfree(sc->battery_desc.name);
  	sc->battery_desc.name = NULL;
d902f4724   Frank Praznik   HID: sony: add ba...
2164
  	return ret;
a08c22c0d   Sven Eckelmann   HID: sony: Add fo...
2165
  }
9f323b681   Sven Eckelmann   HID: sony: Send F...
2166

d902f4724   Frank Praznik   HID: sony: add ba...
2167
  static void sony_battery_remove(struct sony_sc *sc)
9f323b681   Sven Eckelmann   HID: sony: Send F...
2168
  {
297d716f6   Krzysztof Kozlowski   power_supply: Cha...
2169
  	if (!sc->battery_desc.name)
d902f4724   Frank Praznik   HID: sony: add ba...
2170
  		return;
297d716f6   Krzysztof Kozlowski   power_supply: Cha...
2171
2172
2173
  	power_supply_unregister(sc->battery);
  	kfree(sc->battery_desc.name);
  	sc->battery_desc.name = NULL;
9f323b681   Sven Eckelmann   HID: sony: Send F...
2174
  }
a08c22c0d   Sven Eckelmann   HID: sony: Add fo...
2175

d2d782fcc   Frank Praznik   HID: sony: Preven...
2176
2177
2178
2179
2180
  /*
   * 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.
0f3982308   Frank Praznik   HID: sony: Relax ...
2181
2182
2183
2184
2185
   *
   * Some USB-only devices masquerade as Sixaxis controllers and all have the
   * same dummy Bluetooth address, so a comparison of the connection type is
   * required.  Devices are only rejected in the case where two devices have
   * matching Bluetooth addresses on different bus types.
d2d782fcc   Frank Praznik   HID: sony: Preven...
2186
   */
0f3982308   Frank Praznik   HID: sony: Relax ...
2187
2188
2189
2190
2191
2192
2193
2194
  static inline int sony_compare_connection_type(struct sony_sc *sc0,
  						struct sony_sc *sc1)
  {
  	const int sc0_not_bt = !(sc0->quirks & SONY_BT_DEVICE);
  	const int sc1_not_bt = !(sc1->quirks & SONY_BT_DEVICE);
  
  	return sc0_not_bt == sc1_not_bt;
  }
d2d782fcc   Frank Praznik   HID: sony: Preven...
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
  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) {
0f3982308   Frank Praznik   HID: sony: Relax ...
2207
2208
2209
2210
2211
2212
2213
  			if (sony_compare_connection_type(sc, entry)) {
  				ret = 1;
  			} else {
  				ret = -EEXIST;
  				hid_info(sc->hdev,
  				"controller with MAC address %pMR already connected
  ",
d2d782fcc   Frank Praznik   HID: sony: Preven...
2214
  				sc->mac_address);
0f3982308   Frank Praznik   HID: sony: Relax ...
2215
  			}
d2d782fcc   Frank Praznik   HID: sony: Preven...
2216
  			goto unlock;
c4e1ddf26   Frank Praznik   HID: sony: Cache ...
2217
2218
  		}
  	}
d2d782fcc   Frank Praznik   HID: sony: Preven...
2219
2220
  	ret = 0;
  	list_add(&(sc->list_node), &sony_device_list);
c4e1ddf26   Frank Praznik   HID: sony: Cache ...
2221

d2d782fcc   Frank Praznik   HID: sony: Preven...
2222
2223
2224
2225
2226
2227
2228
2229
  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 ...
2230

d2d782fcc   Frank Praznik   HID: sony: Preven...
2231
2232
2233
2234
2235
  	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 ...
2236
  }
d2d782fcc   Frank Praznik   HID: sony: Preven...
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
  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...
2259
  	u8 *buf = NULL;
d2d782fcc   Frank Praznik   HID: sony: Preven...
2260
2261
2262
  	int n, ret;
  
  	if ((sc->quirks & DUALSHOCK4_CONTROLLER_BT) ||
12e9a6d72   Simon Wood   HID: sony: Add su...
2263
  	    (sc->quirks & MOTION_CONTROLLER_BT) ||
4545ee0a7   Simon Wood   HID: hid-sony: Na...
2264
  	    (sc->quirks & NAVIGATION_CONTROLLER_BT) ||
d2d782fcc   Frank Praznik   HID: sony: Preven...
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
  	    (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;
  		}
35f436c31   Roderick Colenbrander   HID: sony: Treat ...
2277
  	} else if (sc->quirks & (DUALSHOCK4_CONTROLLER_USB | DUALSHOCK4_DONGLE)) {
2c159de05   Roderick Colenbrander   HID: sony: Adjust...
2278
  		buf = kmalloc(DS4_FEATURE_REPORT_0x81_SIZE, GFP_KERNEL);
9b2b5c9a7   Frank Praznik   HID: sony: Use ke...
2279
2280
  		if (!buf)
  			return -ENOMEM;
d2d782fcc   Frank Praznik   HID: sony: Preven...
2281
2282
2283
2284
2285
2286
  
  		/*
  		 * 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...
2287
  		ret = hid_hw_raw_request(sc->hdev, 0x81, buf,
2c159de05   Roderick Colenbrander   HID: sony: Adjust...
2288
  				DS4_FEATURE_REPORT_0x81_SIZE, HID_FEATURE_REPORT,
9b2b5c9a7   Frank Praznik   HID: sony: Use ke...
2289
  				HID_REQ_GET_REPORT);
d2d782fcc   Frank Praznik   HID: sony: Preven...
2290

2c159de05   Roderick Colenbrander   HID: sony: Adjust...
2291
  		if (ret != DS4_FEATURE_REPORT_0x81_SIZE) {
d2d782fcc   Frank Praznik   HID: sony: Preven...
2292
2293
  			hid_err(sc->hdev, "failed to retrieve feature report 0x81 with the DualShock 4 MAC address
  ");
9b2b5c9a7   Frank Praznik   HID: sony: Use ke...
2294
2295
  			ret = ret < 0 ? ret : -EINVAL;
  			goto out_free;
d2d782fcc   Frank Praznik   HID: sony: Preven...
2296
2297
2298
  		}
  
  		memcpy(sc->mac_address, &buf[1], sizeof(sc->mac_address));
c70d5f70c   Roderick Colenbrander   HID: sony: Use DS...
2299
2300
2301
2302
2303
2304
  
  		snprintf(sc->hdev->uniq, sizeof(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]);
4545ee0a7   Simon Wood   HID: hid-sony: Na...
2305
2306
  	} else if ((sc->quirks & SIXAXIS_CONTROLLER_USB) ||
  			(sc->quirks & NAVIGATION_CONTROLLER_USB)) {
9b2b5c9a7   Frank Praznik   HID: sony: Use ke...
2307
2308
2309
  		buf = kmalloc(SIXAXIS_REPORT_0xF2_SIZE, GFP_KERNEL);
  		if (!buf)
  			return -ENOMEM;
d2d782fcc   Frank Praznik   HID: sony: Preven...
2310
2311
2312
2313
2314
2315
  
  		/*
  		 * 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...
2316
2317
2318
  		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...
2319

9b2b5c9a7   Frank Praznik   HID: sony: Use ke...
2320
  		if (ret != SIXAXIS_REPORT_0xF2_SIZE) {
d2d782fcc   Frank Praznik   HID: sony: Preven...
2321
2322
  			hid_err(sc->hdev, "failed to retrieve feature report 0xf2 with the Sixaxis MAC address
  ");
9b2b5c9a7   Frank Praznik   HID: sony: Use ke...
2323
2324
  			ret = ret < 0 ? ret : -EINVAL;
  			goto out_free;
d2d782fcc   Frank Praznik   HID: sony: Preven...
2325
2326
2327
2328
2329
2330
2331
2332
  		}
  
  		/*
  		 * 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];
5a144be39   Roderick Colenbrander   HID: sony: Use DS...
2333
2334
2335
2336
2337
2338
  
  		snprintf(sc->hdev->uniq, sizeof(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]);
d2d782fcc   Frank Praznik   HID: sony: Preven...
2339
2340
2341
  	} else {
  		return 0;
  	}
9b2b5c9a7   Frank Praznik   HID: sony: Use ke...
2342
2343
2344
2345
2346
2347
2348
  	ret = sony_check_add_dev_list(sc);
  
  out_free:
  
  	kfree(buf);
  
  	return ret;
d2d782fcc   Frank Praznik   HID: sony: Preven...
2349
  }
8025087ac   Frank Praznik   HID: sony: Initia...
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
  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...
2381
  static inline void sony_init_output_report(struct sony_sc *sc,
09593e388   Antonio Ospite   HID: sony: fix er...
2382
  				void (*send_output_report)(struct sony_sc *))
462620474   Frank Praznik   HID: sony: Use in...
2383
  {
d8aaccda7   Frank Praznik   HID: sony: Refact...
2384
  	sc->send_output_report = send_output_report;
b53227360   Roderick Colenbrander   HID: sony: Make w...
2385
  	if (!sc->state_worker_initialized)
d8aaccda7   Frank Praznik   HID: sony: Refact...
2386
  		INIT_WORK(&sc->state_worker, sony_state_worker);
462620474   Frank Praznik   HID: sony: Use in...
2387

b53227360   Roderick Colenbrander   HID: sony: Make w...
2388
  	sc->state_worker_initialized = 1;
462620474   Frank Praznik   HID: sony: Use in...
2389
2390
2391
2392
  }
  
  static inline void sony_cancel_work_sync(struct sony_sc *sc)
  {
f2f47c385   Roderick Colenbrander   HID: sony: Suppor...
2393
2394
  	if (sc->hotplug_worker_initialized)
  		cancel_work_sync(&sc->hotplug_worker);
b53227360   Roderick Colenbrander   HID: sony: Make w...
2395
  	if (sc->state_worker_initialized)
462620474   Frank Praznik   HID: sony: Use in...
2396
2397
  		cancel_work_sync(&sc->state_worker);
  }
d2d782fcc   Frank Praznik   HID: sony: Preven...
2398

77b499e73   Roderick Colenbrander   HID: sony: Make D...
2399

e1bc84d00   Roderick Colenbrander   HID: sony: Fix ra...
2400
2401
  static int sony_input_configured(struct hid_device *hdev,
  					struct hid_input *hidinput)
bd28ce008   Jiri Slaby   HID: move sony qu...
2402
  {
e1bc84d00   Roderick Colenbrander   HID: sony: Fix ra...
2403
  	struct sony_sc *sc = hid_get_drvdata(hdev);
0f3982308   Frank Praznik   HID: sony: Relax ...
2404
  	int append_dev_id;
e1bc84d00   Roderick Colenbrander   HID: sony: Fix ra...
2405
  	int ret;
bd28ce008   Jiri Slaby   HID: move sony qu...
2406

131a8a9a5   Frank Praznik   HID: sony: Preven...
2407
  	ret = sony_set_device_id(sc);
9b2b5c9a7   Frank Praznik   HID: sony: Use ke...
2408
  	if (ret < 0) {
131a8a9a5   Frank Praznik   HID: sony: Preven...
2409
2410
  		hid_err(hdev, "failed to allocate the device id
  ");
9b2b5c9a7   Frank Praznik   HID: sony: Use ke...
2411
2412
  		goto err_stop;
  	}
df848bc05   Roderick Colenbrander   HID: sony: Perfor...
2413
2414
2415
  	ret = append_dev_id = sony_check_add(sc);
  	if (ret < 0)
  		goto err_stop;
131a8a9a5   Frank Praznik   HID: sony: Preven...
2416
  	ret = sony_allocate_output_report(sc);
8025087ac   Frank Praznik   HID: sony: Initia...
2417
  	if (ret < 0) {
131a8a9a5   Frank Praznik   HID: sony: Preven...
2418
2419
  		hid_err(hdev, "failed to allocate the output report buffer
  ");
8025087ac   Frank Praznik   HID: sony: Initia...
2420
2421
  		goto err_stop;
  	}
510c8b7c1   Roderick Colenbrander   HID: sony: Expose...
2422
  	if (sc->quirks & NAVIGATION_CONTROLLER_USB) {
e534a9352   Benjamin Tissoires   HID: sony: do not...
2423
2424
2425
2426
2427
2428
2429
2430
2431
  		/*
  		 * 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!
2a2429327   Frank Praznik   HID: sony: Defer ...
2432
2433
2434
2435
2436
2437
  		 *
  		 * Additionally, the Sixaxis on USB isn't properly initialized
  		 * until the PS logo button is pressed and as such won't retain
  		 * any state set by an output report, so the initial
  		 * configuration report is deferred until the first input
  		 * report arrives.
e534a9352   Benjamin Tissoires   HID: sony: do not...
2438
2439
2440
  		 */
  		hdev->quirks |= HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP;
  		hdev->quirks |= HID_QUIRK_SKIP_OUTPUT_REPORT_ID;
2a2429327   Frank Praznik   HID: sony: Defer ...
2441
  		sc->defer_initialization = 1;
80ecc48c0   Roderick Colenbrander   HID: sony: Print ...
2442

816651a7d   Antonio Ospite   HID: sony: Apply ...
2443
  		ret = sixaxis_set_operational_usb(hdev);
80ecc48c0   Roderick Colenbrander   HID: sony: Print ...
2444
2445
2446
2447
2448
  		if (ret < 0) {
  			hid_err(hdev, "Failed to set controller into operational mode
  ");
  			goto err_stop;
  		}
d8aaccda7   Frank Praznik   HID: sony: Refact...
2449
  		sony_init_output_report(sc, sixaxis_send_output_report);
510c8b7c1   Roderick Colenbrander   HID: sony: Expose...
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
  	} else if (sc->quirks & NAVIGATION_CONTROLLER_BT) {
  		/*
  		 * The Navigation controller wants output reports sent on the ctrl
  		 * endpoint when connected via Bluetooth.
  		 */
  		hdev->quirks |= HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP;
  
  		ret = sixaxis_set_operational_bt(hdev);
  		if (ret < 0) {
  			hid_err(hdev, "Failed to set controller into operational mode
  ");
  			goto err_stop;
  		}
d8aaccda7   Frank Praznik   HID: sony: Refact...
2463
  		sony_init_output_report(sc, sixaxis_send_output_report);
510c8b7c1   Roderick Colenbrander   HID: sony: Expose...
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
  	} else if (sc->quirks & SIXAXIS_CONTROLLER_USB) {
  		/*
  		 * The Sony Sixaxis does not handle HID Output Reports on the
  		 * Interrupt EP and the device only becomes active when the
  		 * PS button is pressed. See comment for Navigation controller
  		 * above for more details.
  		 */
  		hdev->quirks |= HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP;
  		hdev->quirks |= HID_QUIRK_SKIP_OUTPUT_REPORT_ID;
  		sc->defer_initialization = 1;
  
  		ret = sixaxis_set_operational_usb(hdev);
  		if (ret < 0) {
  			hid_err(hdev, "Failed to set controller into operational mode
  ");
  			goto err_stop;
  		}
  
  		ret = sony_register_sensors(sc);
  		if (ret) {
  			hid_err(sc->hdev,
  			"Unable to initialize motion sensors: %d
  ", ret);
  			goto err_stop;
  		}
  
  		sony_init_output_report(sc, sixaxis_send_output_report);
  	} else if (sc->quirks & SIXAXIS_CONTROLLER_BT) {
2078b9bb2   Frank Praznik   HID: sony: Set th...
2492
2493
2494
2495
2496
  		/*
  		 * The Sixaxis wants output reports sent on the ctrl endpoint
  		 * when connected via Bluetooth.
  		 */
  		hdev->quirks |= HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP;
80ecc48c0   Roderick Colenbrander   HID: sony: Print ...
2497

816651a7d   Antonio Ospite   HID: sony: Apply ...
2498
  		ret = sixaxis_set_operational_bt(hdev);
80ecc48c0   Roderick Colenbrander   HID: sony: Print ...
2499
2500
2501
2502
2503
  		if (ret < 0) {
  			hid_err(hdev, "Failed to set controller into operational mode
  ");
  			goto err_stop;
  		}
510c8b7c1   Roderick Colenbrander   HID: sony: Expose...
2504
2505
2506
2507
2508
2509
2510
  		ret = sony_register_sensors(sc);
  		if (ret) {
  			hid_err(sc->hdev,
  			"Unable to initialize motion sensors: %d
  ", ret);
  			goto err_stop;
  		}
d8aaccda7   Frank Praznik   HID: sony: Refact...
2511
  		sony_init_output_report(sc, sixaxis_send_output_report);
fee4e2d52   Frank Praznik   HID: sony: Enable...
2512
  	} else if (sc->quirks & DUALSHOCK4_CONTROLLER) {
55a07d62d   Roderick Colenbrander   HID: sony: Calibr...
2513
2514
2515
2516
2517
  		ret = dualshock4_get_calibration_data(sc);
  		if (ret < 0) {
  			hid_err(hdev, "Failed to get calibration data from Dualshock 4
  ");
  			goto err_stop;
68330d83c   Frank Praznik   HID: sony: Add co...
2518
  		}
c4e1ddf26   Frank Praznik   HID: sony: Cache ...
2519

e1bc84d00   Roderick Colenbrander   HID: sony: Fix ra...
2520
2521
2522
2523
  		/*
  		 * The Dualshock 4 touchpad supports 2 touches and has a
  		 * resolution of 1920x942 (44.86 dots/mm).
  		 */
ac797b95f   Roderick Colenbrander   HID: sony: Make t...
2524
  		ret = sony_register_touchpad(sc, 2, 1920, 942);
e1bc84d00   Roderick Colenbrander   HID: sony: Fix ra...
2525
2526
2527
2528
2529
  		if (ret) {
  			hid_err(sc->hdev,
  			"Unable to initialize multi-touch slots: %d
  ",
  			ret);
2b6579d4a   Roderick Colenbrander   HID: sony: Fix er...
2530
  			goto err_stop;
e1bc84d00   Roderick Colenbrander   HID: sony: Fix ra...
2531
  		}
227c011b2   Roderick Colenbrander   HID: sony: Report...
2532
2533
2534
2535
2536
2537
2538
  		ret = sony_register_sensors(sc);
  		if (ret) {
  			hid_err(sc->hdev,
  			"Unable to initialize motion sensors: %d
  ", ret);
  			goto err_stop;
  		}
77b499e73   Roderick Colenbrander   HID: sony: Make D...
2539
2540
2541
2542
2543
2544
2545
2546
2547
  		if (sc->quirks & DUALSHOCK4_CONTROLLER_BT) {
  			sc->ds4_bt_poll_interval = DS4_BT_DEFAULT_POLL_INTERVAL_MS;
  			ret = device_create_file(&sc->hdev->dev, &dev_attr_bt_poll_interval);
  			if (ret)
  				hid_warn(sc->hdev,
  				 "can't create sysfs bt_poll_interval attribute err: %d
  ",
  				 ret);
  		}
f2f47c385   Roderick Colenbrander   HID: sony: Suppor...
2548
2549
2550
2551
2552
  		if (sc->quirks & DUALSHOCK4_DONGLE) {
  			INIT_WORK(&sc->hotplug_worker, dualshock4_calibration_work);
  			sc->hotplug_worker_initialized = 1;
  			sc->ds4_dongle_state = DONGLE_DISCONNECTED;
  		}
d8aaccda7   Frank Praznik   HID: sony: Refact...
2553
  		sony_init_output_report(sc, dualshock4_send_output_report);
c5e0c1c49   Frank Praznik   HID: sony: Add su...
2554
  	} else if (sc->quirks & MOTION_CONTROLLER) {
d8aaccda7   Frank Praznik   HID: sony: Refact...
2555
  		sony_init_output_report(sc, motion_send_output_report);
0bd88dd3d   Frank Praznik   HID: sony: Add fo...
2556
2557
2558
  	} else {
  		ret = 0;
  	}
f9ce7c283   Bastien Nocera   HID: Enable Sixax...
2559

0a286ef27   Sven Eckelmann   HID: sony: Add LE...
2560
  	if (sc->quirks & SONY_LED_SUPPORT) {
fa57a8107   Frank Praznik   HID: sony: Conver...
2561
  		ret = sony_leds_init(sc);
0a286ef27   Sven Eckelmann   HID: sony: Add LE...
2562
2563
2564
  		if (ret < 0)
  			goto err_stop;
  	}
d902f4724   Frank Praznik   HID: sony: add ba...
2565
  	if (sc->quirks & SONY_BATTERY_SUPPORT) {
0f3982308   Frank Praznik   HID: sony: Relax ...
2566
  		ret = sony_battery_probe(sc, append_dev_id);
d902f4724   Frank Praznik   HID: sony: add ba...
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
  		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...
2578
  	if (sc->quirks & SONY_FF_SUPPORT) {
fa57a8107   Frank Praznik   HID: sony: Conver...
2579
  		ret = sony_init_ff(sc);
c8de9dbb3   Frank Praznik   HID: sony: Fix wo...
2580
2581
  		if (ret < 0)
  			goto err_close;
5f5750d2e   Frank Praznik   HID: sony: Fix wo...
2582
  	}
a08c22c0d   Sven Eckelmann   HID: sony: Add fo...
2583

bd28ce008   Jiri Slaby   HID: move sony qu...
2584
  	return 0;
d902f4724   Frank Praznik   HID: sony: add ba...
2585
2586
  err_close:
  	hid_hw_close(hdev);
bd28ce008   Jiri Slaby   HID: move sony qu...
2587
  err_stop:
77b499e73   Roderick Colenbrander   HID: sony: Make D...
2588
2589
2590
2591
2592
2593
  	/* Piggy back on the default ds4_bt_ poll_interval to determine
  	 * if we need to remove the file as we don't know for sure if we
  	 * executed that logic.
  	 */
  	if (sc->ds4_bt_poll_interval)
  		device_remove_file(&sc->hdev->dev, &dev_attr_bt_poll_interval);
0a286ef27   Sven Eckelmann   HID: sony: Add LE...
2594
  	if (sc->quirks & SONY_LED_SUPPORT)
fa57a8107   Frank Praznik   HID: sony: Conver...
2595
  		sony_leds_remove(sc);
d902f4724   Frank Praznik   HID: sony: add ba...
2596
2597
  	if (sc->quirks & SONY_BATTERY_SUPPORT)
  		sony_battery_remove(sc);
a687c5765   Roderick Colenbrander   HID: sony: Fix in...
2598
2599
  	if (sc->touchpad)
  		sony_unregister_touchpad(sc);
a676bdc42   Roderick Colenbrander   HID: sony: Make s...
2600
2601
  	if (sc->sensor_dev)
  		sony_unregister_sensors(sc);
462620474   Frank Praznik   HID: sony: Use in...
2602
  	sony_cancel_work_sync(sc);
9b2b5c9a7   Frank Praznik   HID: sony: Use ke...
2603
  	kfree(sc->output_report_dmabuf);
d2d782fcc   Frank Praznik   HID: sony: Preven...
2604
  	sony_remove_dev_list(sc);
8025087ac   Frank Praznik   HID: sony: Initia...
2605
  	sony_release_device_id(sc);
bd28ce008   Jiri Slaby   HID: move sony qu...
2606
  	hid_hw_stop(hdev);
bd28ce008   Jiri Slaby   HID: move sony qu...
2607
2608
  	return ret;
  }
e1bc84d00   Roderick Colenbrander   HID: sony: Fix ra...
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
  static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
  {
  	int ret;
  	unsigned long quirks = id->driver_data;
  	struct sony_sc *sc;
  	unsigned int connect_mask = HID_CONNECT_DEFAULT;
  
  	if (!strcmp(hdev->name, "FutureMax Dance Mat"))
  		quirks |= FUTUREMAX_DANCE_MAT;
  
  	sc = devm_kzalloc(&hdev->dev, sizeof(*sc), GFP_KERNEL);
  	if (sc == NULL) {
  		hid_err(hdev, "can't alloc sony descriptor
  ");
  		return -ENOMEM;
  	}
  
  	spin_lock_init(&sc->lock);
  
  	sc->quirks = quirks;
  	hid_set_drvdata(hdev, sc);
  	sc->hdev = hdev;
  
  	ret = hid_parse(hdev);
  	if (ret) {
  		hid_err(hdev, "parse failed
  ");
  		return ret;
  	}
  
  	if (sc->quirks & VAIO_RDESC_CONSTANT)
  		connect_mask |= HID_CONNECT_HIDDEV_FORCE;
  	else if (sc->quirks & SIXAXIS_CONTROLLER)
  		connect_mask |= HID_CONNECT_HIDDEV_FORCE;
e19a267b9   Roderick Colenbrander   HID: sony: DS3 co...
2643
  	/* Patch the hw version on DS3/4 compatible devices, so applications can
9131f8cc2   Roderick Colenbrander   HID: sony: Comply...
2644
2645
2646
2647
2648
  	 * distinguish between the default HID mappings and the mappings defined
  	 * by the Linux game controller spec. This is important for the SDL2
  	 * library, which has a game controller database, which uses device ids
  	 * in combination with version as a key.
  	 */
e19a267b9   Roderick Colenbrander   HID: sony: DS3 co...
2649
  	if (sc->quirks & (SIXAXIS_CONTROLLER | DUALSHOCK4_CONTROLLER))
9131f8cc2   Roderick Colenbrander   HID: sony: Comply...
2650
  		hdev->version |= 0x8000;
e1bc84d00   Roderick Colenbrander   HID: sony: Fix ra...
2651
2652
2653
2654
2655
2656
  	ret = hid_hw_start(hdev, connect_mask);
  	if (ret) {
  		hid_err(hdev, "hw start failed
  ");
  		return ret;
  	}
4f967f6d7   Roderick Colenbrander   HID: sony: Fix me...
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
  	/* sony_input_configured can fail, but this doesn't result
  	 * in hid_hw_start failures (intended). Check whether
  	 * the HID layer claimed the device else fail.
  	 * We don't know the actual reason for the failure, most
  	 * likely it is due to EEXIST in case of double connection
  	 * of USB and Bluetooth, but could have been due to ENOMEM
  	 * or other reasons as well.
  	 */
  	if (!(hdev->claimed & HID_CLAIMED_INPUT)) {
  		hid_err(hdev, "failed to claim input
  ");
  		return -ENODEV;
  	}
e1bc84d00   Roderick Colenbrander   HID: sony: Fix ra...
2670
2671
  	return ret;
  }
cc6e0bbb4   Jiri Kosina   HID: Add support ...
2672
2673
  static void sony_remove(struct hid_device *hdev)
  {
f04d51404   Colin Leitner   HID: driver for P...
2674
  	struct sony_sc *sc = hid_get_drvdata(hdev);
ac797b95f   Roderick Colenbrander   HID: sony: Make t...
2675
  	hid_hw_close(hdev);
0a286ef27   Sven Eckelmann   HID: sony: Add LE...
2676
  	if (sc->quirks & SONY_LED_SUPPORT)
fa57a8107   Frank Praznik   HID: sony: Conver...
2677
  		sony_leds_remove(sc);
f04d51404   Colin Leitner   HID: driver for P...
2678

ac797b95f   Roderick Colenbrander   HID: sony: Make t...
2679
  	if (sc->quirks & SONY_BATTERY_SUPPORT)
d902f4724   Frank Praznik   HID: sony: add ba...
2680
  		sony_battery_remove(sc);
ac797b95f   Roderick Colenbrander   HID: sony: Make t...
2681
2682
2683
  
  	if (sc->touchpad)
  		sony_unregister_touchpad(sc);
d902f4724   Frank Praznik   HID: sony: add ba...
2684

227c011b2   Roderick Colenbrander   HID: sony: Report...
2685
2686
  	if (sc->sensor_dev)
  		sony_unregister_sensors(sc);
77b499e73   Roderick Colenbrander   HID: sony: Make D...
2687
2688
  	if (sc->quirks & DUALSHOCK4_CONTROLLER_BT)
  		device_remove_file(&sc->hdev->dev, &dev_attr_bt_poll_interval);
462620474   Frank Praznik   HID: sony: Use in...
2689
  	sony_cancel_work_sync(sc);
9f323b681   Sven Eckelmann   HID: sony: Send F...
2690

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

8025087ac   Frank Praznik   HID: sony: Initia...
2694
  	sony_release_device_id(sc);
cc6e0bbb4   Jiri Kosina   HID: Add support ...
2695
  	hid_hw_stop(hdev);
cc6e0bbb4   Jiri Kosina   HID: Add support ...
2696
  }
decd946c9   Frank Praznik   HID: sony: Save a...
2697
2698
2699
2700
  #ifdef CONFIG_PM
  
  static int sony_suspend(struct hid_device *hdev, pm_message_t message)
  {
decd946c9   Frank Praznik   HID: sony: Save a...
2701
  #ifdef CONFIG_SONY_FF
decd946c9   Frank Praznik   HID: sony: Save a...
2702

765a1077c   Frank Praznik   HID: sony: Use LE...
2703
2704
2705
  	/* On suspend stop any running force-feedback events */
  	if (SONY_FF_SUPPORT) {
  		struct sony_sc *sc = hid_get_drvdata(hdev);
decd946c9   Frank Praznik   HID: sony: Save a...
2706

765a1077c   Frank Praznik   HID: sony: Use LE...
2707
  		sc->left = sc->right = 0;
decd946c9   Frank Praznik   HID: sony: Save a...
2708
2709
  		sony_send_output_report(sc);
  	}
765a1077c   Frank Praznik   HID: sony: Use LE...
2710
  #endif
decd946c9   Frank Praznik   HID: sony: Save a...
2711
2712
2713
2714
2715
  	return 0;
  }
  
  static int sony_resume(struct hid_device *hdev)
  {
765a1077c   Frank Praznik   HID: sony: Use LE...
2716
  	struct sony_sc *sc = hid_get_drvdata(hdev);
decd946c9   Frank Praznik   HID: sony: Save a...
2717

765a1077c   Frank Praznik   HID: sony: Use LE...
2718
2719
2720
2721
2722
2723
2724
2725
  	/*
  	 * 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);
  		sc->defer_initialization = 1;
decd946c9   Frank Praznik   HID: sony: Save a...
2726
2727
2728
2729
2730
2731
  	}
  
  	return 0;
  }
  
  #endif
bd28ce008   Jiri Slaby   HID: move sony qu...
2732
  static const struct hid_device_id sony_devices[] = {
816651a7d   Antonio Ospite   HID: sony: Apply ...
2733
2734
  	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER),
  		.driver_data = SIXAXIS_CONTROLLER_USB },
35dca5b4a   Jiri Kosina   HID: add support ...
2735
  	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER),
4545ee0a7   Simon Wood   HID: hid-sony: Na...
2736
  		.driver_data = NAVIGATION_CONTROLLER_USB },
6eabaaa09   Simon Wood   HID: hid-sony: Ad...
2737
  	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER),
4545ee0a7   Simon Wood   HID: hid-sony: Na...
2738
  		.driver_data = NAVIGATION_CONTROLLER_BT },
c5e0c1c49   Frank Praznik   HID: sony: Add su...
2739
  	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_MOTION_CONTROLLER),
b3bca326f   Simon Wood   HID: sony: Add qu...
2740
  		.driver_data = MOTION_CONTROLLER_USB },
a4afa8544   Simon Wood   HID: sony: Suppor...
2741
  	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_MOTION_CONTROLLER),
b3bca326f   Simon Wood   HID: sony: Add qu...
2742
  		.driver_data = MOTION_CONTROLLER_BT },
816651a7d   Antonio Ospite   HID: sony: Apply ...
2743
2744
  	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER),
  		.driver_data = SIXAXIS_CONTROLLER_BT },
cc6e0bbb4   Jiri Kosina   HID: Add support ...
2745
2746
  	{ 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 ...
2747
2748
  	{ 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...
2749
2750
2751
2752
  	/*
  	 * 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...
2753
2754
2755
2756
  	{ 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...
2757
2758
2759
2760
2761
2762
  	/* 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...
2763
2764
2765
  	/* 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...
2766
2767
  	/* 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...
2768
  		.driver_data = DUALSHOCK4_CONTROLLER_USB },
0bd88dd3d   Frank Praznik   HID: sony: Add fo...
2769
  	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER),
8ab1676b6   Frank Praznik   HID: sony: Use se...
2770
  		.driver_data = DUALSHOCK4_CONTROLLER_BT },
cf1015d65   Roderick Colenbrander   HID: sony: Update...
2771
2772
2773
2774
  	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER_2),
  		.driver_data = DUALSHOCK4_CONTROLLER_USB },
  	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER_2),
  		.driver_data = DUALSHOCK4_CONTROLLER_BT },
de66a1a04   Roderick Colenbrander   HID: sony: Suppor...
2775
  	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER_DONGLE),
35f436c31   Roderick Colenbrander   HID: sony: Treat ...
2776
  		.driver_data = DUALSHOCK4_DONGLE },
74500cc85   Scott Moreau   HID: sony: Add ny...
2777
2778
2779
  	/* 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...
2780
2781
2782
2783
2784
  	{ }
  };
  MODULE_DEVICE_TABLE(hid, sony_devices);
  
  static struct hid_driver sony_driver = {
ce8efc3b5   Frank Praznik   HID: sony: Set to...
2785
2786
2787
2788
2789
2790
2791
  	.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...
2792
2793
2794
2795
2796
2797
2798
  	.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...
2799
  };
8025087ac   Frank Praznik   HID: sony: Initia...
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
  
  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...
2813
  	hid_unregister_driver(&sony_driver);
6c40065fc   Antonio Ospite   HID: sony: Fix a ...
2814
  	ida_destroy(&sony_device_id_allocator);
8025087ac   Frank Praznik   HID: sony: Initia...
2815
2816
2817
  }
  module_init(sony_init);
  module_exit(sony_exit);
bd28ce008   Jiri Slaby   HID: move sony qu...
2818

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