blob: b39e3abd6cdd458b29e7d95eb6b5841f0db399a0 [file] [log] [blame]
Jiri Slabybd28ce02008-06-25 23:47:04 +02001/*
Jiri Kosina078328d2013-06-13 12:03:49 +02002 * HID driver for Sony / PS2 / PS3 BD devices.
Jiri Slabybd28ce02008-06-25 23:47:04 +02003 *
4 * Copyright (c) 1999 Andreas Gal
5 * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz>
6 * Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc
Jiri Slabybd28ce02008-06-25 23:47:04 +02007 * Copyright (c) 2008 Jiri Slaby
Jiri Kosina078328d2013-06-13 12:03:49 +02008 * Copyright (c) 2012 David Dillow <dave@thedillows.org>
9 * Copyright (c) 2006-2013 Jiri Kosina
Colin Leitnerf04d5142013-05-27 23:41:05 +020010 * Copyright (c) 2013 Colin Leitner <colin.leitner@gmail.com>
Jiri Slabybd28ce02008-06-25 23:47:04 +020011 */
12
13/*
14 * This program is free software; you can redistribute it and/or modify it
15 * under the terms of the GNU General Public License as published by the Free
16 * Software Foundation; either version 2 of the License, or (at your option)
17 * any later version.
18 */
19
Frank Praznikad142b92014-02-20 11:36:00 -050020/*
21 * NOTE: in order for the Sony PS3 BD Remote Control to be found by
Jiri Kosina078328d2013-06-13 12:03:49 +020022 * a Bluetooth host, the key combination Start+Enter has to be kept pressed
23 * for about 7 seconds with the Bluetooth Host Controller in discovering mode.
24 *
25 * There will be no PIN request from the device.
26 */
27
Jiri Slabybd28ce02008-06-25 23:47:04 +020028#include <linux/device.h>
29#include <linux/hid.h>
30#include <linux/module.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090031#include <linux/slab.h>
Jiri Slabybd28ce02008-06-25 23:47:04 +020032#include <linux/usb.h>
Jiri Kosina40e32ee2013-05-28 11:22:09 +020033#include <linux/leds.h>
Frank Praznikd902f472014-01-27 10:17:36 -050034#include <linux/power_supply.h>
35#include <linux/spinlock.h>
Frank Praznike5606232014-01-27 10:17:37 -050036#include <linux/input/mt.h>
Jiri Slabybd28ce02008-06-25 23:47:04 +020037
38#include "hid-ids.h"
39
Frank Praznik6c79c182014-01-16 21:43:03 -050040#define VAIO_RDESC_CONSTANT BIT(0)
41#define SIXAXIS_CONTROLLER_USB BIT(1)
42#define SIXAXIS_CONTROLLER_BT BIT(2)
43#define BUZZ_CONTROLLER BIT(3)
44#define PS3REMOTE BIT(4)
Frank Praznik8ab16762014-01-16 21:42:31 -050045#define DUALSHOCK4_CONTROLLER_USB BIT(5)
46#define DUALSHOCK4_CONTROLLER_BT BIT(6)
Jiri Kosinacc6e0bb2008-10-23 12:58:38 +020047
Frank Praznikfee4e2d2014-02-18 17:22:01 -050048#define SIXAXIS_CONTROLLER (SIXAXIS_CONTROLLER_USB | SIXAXIS_CONTROLLER_BT)
Frank Praznik68330d82014-02-05 20:03:49 -050049#define DUALSHOCK4_CONTROLLER (DUALSHOCK4_CONTROLLER_USB |\
50 DUALSHOCK4_CONTROLLER_BT)
Frank Praznikfee4e2d2014-02-18 17:22:01 -050051#define SONY_LED_SUPPORT (SIXAXIS_CONTROLLER | BUZZ_CONTROLLER |\
Frank Praznik68330d82014-02-05 20:03:49 -050052 DUALSHOCK4_CONTROLLER)
Frank Praznikfee4e2d2014-02-18 17:22:01 -050053#define SONY_BATTERY_SUPPORT (SIXAXIS_CONTROLLER | DUALSHOCK4_CONTROLLER)
Frank Praznikc8de9db2014-02-20 11:36:01 -050054#define SONY_FF_SUPPORT (SIXAXIS_CONTROLLER | DUALSHOCK4_CONTROLLER)
Frank Praznik60781cf2014-01-11 15:13:15 -050055
56#define MAX_LEDS 4
Sven Eckelmann0a286ef2013-11-19 20:26:32 +010057
Simon Wood61ab44b2011-06-10 12:00:26 +020058static const u8 sixaxis_rdesc_fixup[] = {
59 0x95, 0x13, 0x09, 0x01, 0x81, 0x02, 0x95, 0x0C,
60 0x81, 0x01, 0x75, 0x10, 0x95, 0x04, 0x26, 0xFF,
61 0x03, 0x46, 0xFF, 0x03, 0x09, 0x01, 0x81, 0x02
62};
63
Mauro Carvalho Chehabe57a67d2012-12-14 20:57:34 -020064static const u8 sixaxis_rdesc_fixup2[] = {
65 0x05, 0x01, 0x09, 0x04, 0xa1, 0x01, 0xa1, 0x02,
66 0x85, 0x01, 0x75, 0x08, 0x95, 0x01, 0x15, 0x00,
67 0x26, 0xff, 0x00, 0x81, 0x03, 0x75, 0x01, 0x95,
68 0x13, 0x15, 0x00, 0x25, 0x01, 0x35, 0x00, 0x45,
69 0x01, 0x05, 0x09, 0x19, 0x01, 0x29, 0x13, 0x81,
70 0x02, 0x75, 0x01, 0x95, 0x0d, 0x06, 0x00, 0xff,
71 0x81, 0x03, 0x15, 0x00, 0x26, 0xff, 0x00, 0x05,
72 0x01, 0x09, 0x01, 0xa1, 0x00, 0x75, 0x08, 0x95,
73 0x04, 0x35, 0x00, 0x46, 0xff, 0x00, 0x09, 0x30,
74 0x09, 0x31, 0x09, 0x32, 0x09, 0x35, 0x81, 0x02,
75 0xc0, 0x05, 0x01, 0x95, 0x13, 0x09, 0x01, 0x81,
76 0x02, 0x95, 0x0c, 0x81, 0x01, 0x75, 0x10, 0x95,
77 0x04, 0x26, 0xff, 0x03, 0x46, 0xff, 0x03, 0x09,
78 0x01, 0x81, 0x02, 0xc0, 0xa1, 0x02, 0x85, 0x02,
79 0x75, 0x08, 0x95, 0x30, 0x09, 0x01, 0xb1, 0x02,
80 0xc0, 0xa1, 0x02, 0x85, 0xee, 0x75, 0x08, 0x95,
81 0x30, 0x09, 0x01, 0xb1, 0x02, 0xc0, 0xa1, 0x02,
82 0x85, 0xef, 0x75, 0x08, 0x95, 0x30, 0x09, 0x01,
83 0xb1, 0x02, 0xc0, 0xc0,
84};
85
Frank Praznikad142b92014-02-20 11:36:00 -050086/*
87 * The default descriptor doesn't provide mapping for the accelerometers
Frank Praznik58d70272014-01-20 12:27:01 -050088 * or orientation sensors. This fixed descriptor maps the accelerometers
89 * to usage values 0x40, 0x41 and 0x42 and maps the orientation sensors
90 * to usage values 0x43, 0x44 and 0x45.
91 */
Frank Prazniked19d8c2014-01-16 21:43:12 -050092static u8 dualshock4_usb_rdesc[] = {
Frank Praznik58d70272014-01-20 12:27:01 -050093 0x05, 0x01, /* Usage Page (Desktop), */
94 0x09, 0x05, /* Usage (Gamepad), */
95 0xA1, 0x01, /* Collection (Application), */
96 0x85, 0x01, /* Report ID (1), */
97 0x09, 0x30, /* Usage (X), */
98 0x09, 0x31, /* Usage (Y), */
99 0x09, 0x32, /* Usage (Z), */
100 0x09, 0x35, /* Usage (Rz), */
101 0x15, 0x00, /* Logical Minimum (0), */
102 0x26, 0xFF, 0x00, /* Logical Maximum (255), */
103 0x75, 0x08, /* Report Size (8), */
104 0x95, 0x04, /* Report Count (4), */
105 0x81, 0x02, /* Input (Variable), */
106 0x09, 0x39, /* Usage (Hat Switch), */
107 0x15, 0x00, /* Logical Minimum (0), */
108 0x25, 0x07, /* Logical Maximum (7), */
109 0x35, 0x00, /* Physical Minimum (0), */
110 0x46, 0x3B, 0x01, /* Physical Maximum (315), */
111 0x65, 0x14, /* Unit (Degrees), */
112 0x75, 0x04, /* Report Size (4), */
113 0x95, 0x01, /* Report Count (1), */
114 0x81, 0x42, /* Input (Variable, Null State), */
115 0x65, 0x00, /* Unit, */
116 0x05, 0x09, /* Usage Page (Button), */
117 0x19, 0x01, /* Usage Minimum (01h), */
118 0x29, 0x0E, /* Usage Maximum (0Eh), */
119 0x15, 0x00, /* Logical Minimum (0), */
120 0x25, 0x01, /* Logical Maximum (1), */
121 0x75, 0x01, /* Report Size (1), */
122 0x95, 0x0E, /* Report Count (14), */
123 0x81, 0x02, /* Input (Variable), */
124 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */
125 0x09, 0x20, /* Usage (20h), */
126 0x75, 0x06, /* Report Size (6), */
127 0x95, 0x01, /* Report Count (1), */
128 0x15, 0x00, /* Logical Minimum (0), */
129 0x25, 0x7F, /* Logical Maximum (127), */
130 0x81, 0x02, /* Input (Variable), */
131 0x05, 0x01, /* Usage Page (Desktop), */
132 0x09, 0x33, /* Usage (Rx), */
133 0x09, 0x34, /* Usage (Ry), */
134 0x15, 0x00, /* Logical Minimum (0), */
135 0x26, 0xFF, 0x00, /* Logical Maximum (255), */
136 0x75, 0x08, /* Report Size (8), */
137 0x95, 0x02, /* Report Count (2), */
138 0x81, 0x02, /* Input (Variable), */
139 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */
140 0x09, 0x21, /* Usage (21h), */
141 0x95, 0x03, /* Report Count (3), */
142 0x81, 0x02, /* Input (Variable), */
143 0x05, 0x01, /* Usage Page (Desktop), */
144 0x19, 0x40, /* Usage Minimum (40h), */
145 0x29, 0x42, /* Usage Maximum (42h), */
146 0x16, 0x00, 0x80, /* Logical Minimum (-32768), */
147 0x26, 0x00, 0x7F, /* Logical Maximum (32767), */
148 0x75, 0x10, /* Report Size (16), */
149 0x95, 0x03, /* Report Count (3), */
150 0x81, 0x02, /* Input (Variable), */
151 0x19, 0x43, /* Usage Minimum (43h), */
152 0x29, 0x45, /* Usage Maximum (45h), */
153 0x16, 0xFF, 0xBF, /* Logical Minimum (-16385), */
154 0x26, 0x00, 0x40, /* Logical Maximum (16384), */
155 0x95, 0x03, /* Report Count (3), */
156 0x81, 0x02, /* Input (Variable), */
157 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */
158 0x09, 0x21, /* Usage (21h), */
159 0x15, 0x00, /* Logical Minimum (0), */
160 0x25, 0xFF, /* Logical Maximum (255), */
161 0x75, 0x08, /* Report Size (8), */
162 0x95, 0x27, /* Report Count (39), */
163 0x81, 0x02, /* Input (Variable), */
164 0x85, 0x05, /* Report ID (5), */
165 0x09, 0x22, /* Usage (22h), */
166 0x95, 0x1F, /* Report Count (31), */
167 0x91, 0x02, /* Output (Variable), */
168 0x85, 0x04, /* Report ID (4), */
169 0x09, 0x23, /* Usage (23h), */
170 0x95, 0x24, /* Report Count (36), */
171 0xB1, 0x02, /* Feature (Variable), */
172 0x85, 0x02, /* Report ID (2), */
173 0x09, 0x24, /* Usage (24h), */
174 0x95, 0x24, /* Report Count (36), */
175 0xB1, 0x02, /* Feature (Variable), */
176 0x85, 0x08, /* Report ID (8), */
177 0x09, 0x25, /* Usage (25h), */
178 0x95, 0x03, /* Report Count (3), */
179 0xB1, 0x02, /* Feature (Variable), */
180 0x85, 0x10, /* Report ID (16), */
181 0x09, 0x26, /* Usage (26h), */
182 0x95, 0x04, /* Report Count (4), */
183 0xB1, 0x02, /* Feature (Variable), */
184 0x85, 0x11, /* Report ID (17), */
185 0x09, 0x27, /* Usage (27h), */
186 0x95, 0x02, /* Report Count (2), */
187 0xB1, 0x02, /* Feature (Variable), */
188 0x85, 0x12, /* Report ID (18), */
189 0x06, 0x02, 0xFF, /* Usage Page (FF02h), */
190 0x09, 0x21, /* Usage (21h), */
191 0x95, 0x0F, /* Report Count (15), */
192 0xB1, 0x02, /* Feature (Variable), */
193 0x85, 0x13, /* Report ID (19), */
194 0x09, 0x22, /* Usage (22h), */
195 0x95, 0x16, /* Report Count (22), */
196 0xB1, 0x02, /* Feature (Variable), */
197 0x85, 0x14, /* Report ID (20), */
198 0x06, 0x05, 0xFF, /* Usage Page (FF05h), */
199 0x09, 0x20, /* Usage (20h), */
200 0x95, 0x10, /* Report Count (16), */
201 0xB1, 0x02, /* Feature (Variable), */
202 0x85, 0x15, /* Report ID (21), */
203 0x09, 0x21, /* Usage (21h), */
204 0x95, 0x2C, /* Report Count (44), */
205 0xB1, 0x02, /* Feature (Variable), */
206 0x06, 0x80, 0xFF, /* Usage Page (FF80h), */
207 0x85, 0x80, /* Report ID (128), */
208 0x09, 0x20, /* Usage (20h), */
209 0x95, 0x06, /* Report Count (6), */
210 0xB1, 0x02, /* Feature (Variable), */
211 0x85, 0x81, /* Report ID (129), */
212 0x09, 0x21, /* Usage (21h), */
213 0x95, 0x06, /* Report Count (6), */
214 0xB1, 0x02, /* Feature (Variable), */
215 0x85, 0x82, /* Report ID (130), */
216 0x09, 0x22, /* Usage (22h), */
217 0x95, 0x05, /* Report Count (5), */
218 0xB1, 0x02, /* Feature (Variable), */
219 0x85, 0x83, /* Report ID (131), */
220 0x09, 0x23, /* Usage (23h), */
221 0x95, 0x01, /* Report Count (1), */
222 0xB1, 0x02, /* Feature (Variable), */
223 0x85, 0x84, /* Report ID (132), */
224 0x09, 0x24, /* Usage (24h), */
225 0x95, 0x04, /* Report Count (4), */
226 0xB1, 0x02, /* Feature (Variable), */
227 0x85, 0x85, /* Report ID (133), */
228 0x09, 0x25, /* Usage (25h), */
229 0x95, 0x06, /* Report Count (6), */
230 0xB1, 0x02, /* Feature (Variable), */
231 0x85, 0x86, /* Report ID (134), */
232 0x09, 0x26, /* Usage (26h), */
233 0x95, 0x06, /* Report Count (6), */
234 0xB1, 0x02, /* Feature (Variable), */
235 0x85, 0x87, /* Report ID (135), */
236 0x09, 0x27, /* Usage (27h), */
237 0x95, 0x23, /* Report Count (35), */
238 0xB1, 0x02, /* Feature (Variable), */
239 0x85, 0x88, /* Report ID (136), */
240 0x09, 0x28, /* Usage (28h), */
241 0x95, 0x22, /* Report Count (34), */
242 0xB1, 0x02, /* Feature (Variable), */
243 0x85, 0x89, /* Report ID (137), */
244 0x09, 0x29, /* Usage (29h), */
245 0x95, 0x02, /* Report Count (2), */
246 0xB1, 0x02, /* Feature (Variable), */
247 0x85, 0x90, /* Report ID (144), */
248 0x09, 0x30, /* Usage (30h), */
249 0x95, 0x05, /* Report Count (5), */
250 0xB1, 0x02, /* Feature (Variable), */
251 0x85, 0x91, /* Report ID (145), */
252 0x09, 0x31, /* Usage (31h), */
253 0x95, 0x03, /* Report Count (3), */
254 0xB1, 0x02, /* Feature (Variable), */
255 0x85, 0x92, /* Report ID (146), */
256 0x09, 0x32, /* Usage (32h), */
257 0x95, 0x03, /* Report Count (3), */
258 0xB1, 0x02, /* Feature (Variable), */
259 0x85, 0x93, /* Report ID (147), */
260 0x09, 0x33, /* Usage (33h), */
261 0x95, 0x0C, /* Report Count (12), */
262 0xB1, 0x02, /* Feature (Variable), */
263 0x85, 0xA0, /* Report ID (160), */
264 0x09, 0x40, /* Usage (40h), */
265 0x95, 0x06, /* Report Count (6), */
266 0xB1, 0x02, /* Feature (Variable), */
267 0x85, 0xA1, /* Report ID (161), */
268 0x09, 0x41, /* Usage (41h), */
269 0x95, 0x01, /* Report Count (1), */
270 0xB1, 0x02, /* Feature (Variable), */
271 0x85, 0xA2, /* Report ID (162), */
272 0x09, 0x42, /* Usage (42h), */
273 0x95, 0x01, /* Report Count (1), */
274 0xB1, 0x02, /* Feature (Variable), */
275 0x85, 0xA3, /* Report ID (163), */
276 0x09, 0x43, /* Usage (43h), */
277 0x95, 0x30, /* Report Count (48), */
278 0xB1, 0x02, /* Feature (Variable), */
279 0x85, 0xA4, /* Report ID (164), */
280 0x09, 0x44, /* Usage (44h), */
281 0x95, 0x0D, /* Report Count (13), */
282 0xB1, 0x02, /* Feature (Variable), */
283 0x85, 0xA5, /* Report ID (165), */
284 0x09, 0x45, /* Usage (45h), */
285 0x95, 0x15, /* Report Count (21), */
286 0xB1, 0x02, /* Feature (Variable), */
287 0x85, 0xA6, /* Report ID (166), */
288 0x09, 0x46, /* Usage (46h), */
289 0x95, 0x15, /* Report Count (21), */
290 0xB1, 0x02, /* Feature (Variable), */
291 0x85, 0xF0, /* Report ID (240), */
292 0x09, 0x47, /* Usage (47h), */
293 0x95, 0x3F, /* Report Count (63), */
294 0xB1, 0x02, /* Feature (Variable), */
295 0x85, 0xF1, /* Report ID (241), */
296 0x09, 0x48, /* Usage (48h), */
297 0x95, 0x3F, /* Report Count (63), */
298 0xB1, 0x02, /* Feature (Variable), */
299 0x85, 0xF2, /* Report ID (242), */
300 0x09, 0x49, /* Usage (49h), */
301 0x95, 0x0F, /* Report Count (15), */
302 0xB1, 0x02, /* Feature (Variable), */
303 0x85, 0xA7, /* Report ID (167), */
304 0x09, 0x4A, /* Usage (4Ah), */
305 0x95, 0x01, /* Report Count (1), */
306 0xB1, 0x02, /* Feature (Variable), */
307 0x85, 0xA8, /* Report ID (168), */
308 0x09, 0x4B, /* Usage (4Bh), */
309 0x95, 0x01, /* Report Count (1), */
310 0xB1, 0x02, /* Feature (Variable), */
311 0x85, 0xA9, /* Report ID (169), */
312 0x09, 0x4C, /* Usage (4Ch), */
313 0x95, 0x08, /* Report Count (8), */
314 0xB1, 0x02, /* Feature (Variable), */
315 0x85, 0xAA, /* Report ID (170), */
316 0x09, 0x4E, /* Usage (4Eh), */
317 0x95, 0x01, /* Report Count (1), */
318 0xB1, 0x02, /* Feature (Variable), */
319 0x85, 0xAB, /* Report ID (171), */
320 0x09, 0x4F, /* Usage (4Fh), */
321 0x95, 0x39, /* Report Count (57), */
322 0xB1, 0x02, /* Feature (Variable), */
323 0x85, 0xAC, /* Report ID (172), */
324 0x09, 0x50, /* Usage (50h), */
325 0x95, 0x39, /* Report Count (57), */
326 0xB1, 0x02, /* Feature (Variable), */
327 0x85, 0xAD, /* Report ID (173), */
328 0x09, 0x51, /* Usage (51h), */
329 0x95, 0x0B, /* Report Count (11), */
330 0xB1, 0x02, /* Feature (Variable), */
331 0x85, 0xAE, /* Report ID (174), */
332 0x09, 0x52, /* Usage (52h), */
333 0x95, 0x01, /* Report Count (1), */
334 0xB1, 0x02, /* Feature (Variable), */
335 0x85, 0xAF, /* Report ID (175), */
336 0x09, 0x53, /* Usage (53h), */
337 0x95, 0x02, /* Report Count (2), */
338 0xB1, 0x02, /* Feature (Variable), */
339 0x85, 0xB0, /* Report ID (176), */
340 0x09, 0x54, /* Usage (54h), */
341 0x95, 0x3F, /* Report Count (63), */
342 0xB1, 0x02, /* Feature (Variable), */
343 0xC0 /* End Collection */
Frank Prazniked19d8c2014-01-16 21:43:12 -0500344};
345
Frank Praznikad142b92014-02-20 11:36:00 -0500346/*
347 * The default behavior of the Dualshock 4 is to send reports using report
Frank Praznikd829674d2014-02-05 20:03:45 -0500348 * type 1 when running over Bluetooth. However, as soon as it receives a
349 * report of type 17 to set the LEDs or rumble it starts returning it's state
350 * in report 17 instead of 1. Since report 17 is undefined in the default HID
351 * descriptor the button and axis definitions must be moved to report 17 or
352 * the HID layer won't process the received input once a report is sent.
353 */
354static u8 dualshock4_bt_rdesc[] = {
355 0x05, 0x01, /* Usage Page (Desktop), */
356 0x09, 0x05, /* Usage (Gamepad), */
357 0xA1, 0x01, /* Collection (Application), */
358 0x85, 0x01, /* Report ID (1), */
359 0x75, 0x08, /* Report Size (8), */
360 0x95, 0x0A, /* Report Count (9), */
361 0x81, 0x02, /* Input (Variable), */
362 0x06, 0x04, 0xFF, /* Usage Page (FF04h), */
363 0x85, 0x02, /* Report ID (2), */
364 0x09, 0x24, /* Usage (24h), */
365 0x95, 0x24, /* Report Count (36), */
366 0xB1, 0x02, /* Feature (Variable), */
367 0x85, 0xA3, /* Report ID (163), */
368 0x09, 0x25, /* Usage (25h), */
369 0x95, 0x30, /* Report Count (48), */
370 0xB1, 0x02, /* Feature (Variable), */
371 0x85, 0x05, /* Report ID (5), */
372 0x09, 0x26, /* Usage (26h), */
373 0x95, 0x28, /* Report Count (40), */
374 0xB1, 0x02, /* Feature (Variable), */
375 0x85, 0x06, /* Report ID (6), */
376 0x09, 0x27, /* Usage (27h), */
377 0x95, 0x34, /* Report Count (52), */
378 0xB1, 0x02, /* Feature (Variable), */
379 0x85, 0x07, /* Report ID (7), */
380 0x09, 0x28, /* Usage (28h), */
381 0x95, 0x30, /* Report Count (48), */
382 0xB1, 0x02, /* Feature (Variable), */
383 0x85, 0x08, /* Report ID (8), */
384 0x09, 0x29, /* Usage (29h), */
385 0x95, 0x2F, /* Report Count (47), */
386 0xB1, 0x02, /* Feature (Variable), */
387 0x06, 0x03, 0xFF, /* Usage Page (FF03h), */
388 0x85, 0x03, /* Report ID (3), */
389 0x09, 0x21, /* Usage (21h), */
390 0x95, 0x26, /* Report Count (38), */
391 0xB1, 0x02, /* Feature (Variable), */
392 0x85, 0x04, /* Report ID (4), */
393 0x09, 0x22, /* Usage (22h), */
394 0x95, 0x2E, /* Report Count (46), */
395 0xB1, 0x02, /* Feature (Variable), */
396 0x85, 0xF0, /* Report ID (240), */
397 0x09, 0x47, /* Usage (47h), */
398 0x95, 0x3F, /* Report Count (63), */
399 0xB1, 0x02, /* Feature (Variable), */
400 0x85, 0xF1, /* Report ID (241), */
401 0x09, 0x48, /* Usage (48h), */
402 0x95, 0x3F, /* Report Count (63), */
403 0xB1, 0x02, /* Feature (Variable), */
404 0x85, 0xF2, /* Report ID (242), */
405 0x09, 0x49, /* Usage (49h), */
406 0x95, 0x0F, /* Report Count (15), */
407 0xB1, 0x02, /* Feature (Variable), */
408 0x85, 0x11, /* Report ID (17), */
409 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */
410 0x09, 0x20, /* Usage (20h), */
411 0x95, 0x02, /* Report Count (2), */
412 0x81, 0x02, /* Input (Variable), */
413 0x05, 0x01, /* Usage Page (Desktop), */
414 0x09, 0x30, /* Usage (X), */
415 0x09, 0x31, /* Usage (Y), */
416 0x09, 0x32, /* Usage (Z), */
417 0x09, 0x35, /* Usage (Rz), */
418 0x15, 0x00, /* Logical Minimum (0), */
419 0x26, 0xFF, 0x00, /* Logical Maximum (255), */
420 0x75, 0x08, /* Report Size (8), */
421 0x95, 0x04, /* Report Count (4), */
422 0x81, 0x02, /* Input (Variable), */
423 0x09, 0x39, /* Usage (Hat Switch), */
424 0x15, 0x00, /* Logical Minimum (0), */
425 0x25, 0x07, /* Logical Maximum (7), */
426 0x75, 0x04, /* Report Size (4), */
427 0x95, 0x01, /* Report Count (1), */
428 0x81, 0x42, /* Input (Variable, Null State), */
429 0x05, 0x09, /* Usage Page (Button), */
430 0x19, 0x01, /* Usage Minimum (01h), */
431 0x29, 0x0E, /* Usage Maximum (0Eh), */
432 0x15, 0x00, /* Logical Minimum (0), */
433 0x25, 0x01, /* Logical Maximum (1), */
434 0x75, 0x01, /* Report Size (1), */
435 0x95, 0x0E, /* Report Count (14), */
436 0x81, 0x02, /* Input (Variable), */
437 0x75, 0x06, /* Report Size (6), */
438 0x95, 0x01, /* Report Count (1), */
439 0x81, 0x01, /* Input (Constant), */
440 0x05, 0x01, /* Usage Page (Desktop), */
441 0x09, 0x33, /* Usage (Rx), */
442 0x09, 0x34, /* Usage (Ry), */
443 0x15, 0x00, /* Logical Minimum (0), */
444 0x26, 0xFF, 0x00, /* Logical Maximum (255), */
445 0x75, 0x08, /* Report Size (8), */
446 0x95, 0x02, /* Report Count (2), */
447 0x81, 0x02, /* Input (Variable), */
448 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */
449 0x09, 0x20, /* Usage (20h), */
450 0x95, 0x03, /* Report Count (3), */
451 0x81, 0x02, /* Input (Variable), */
452 0x05, 0x01, /* Usage Page (Desktop), */
453 0x19, 0x40, /* Usage Minimum (40h), */
454 0x29, 0x42, /* Usage Maximum (42h), */
455 0x16, 0x00, 0x80, /* Logical Minimum (-32768), */
456 0x26, 0x00, 0x7F, /* Logical Maximum (32767), */
457 0x75, 0x10, /* Report Size (16), */
458 0x95, 0x03, /* Report Count (3), */
459 0x81, 0x02, /* Input (Variable), */
460 0x19, 0x43, /* Usage Minimum (43h), */
461 0x29, 0x45, /* Usage Maximum (45h), */
462 0x16, 0xFF, 0xBF, /* Logical Minimum (-16385), */
463 0x26, 0x00, 0x40, /* Logical Maximum (16384), */
464 0x95, 0x03, /* Report Count (3), */
465 0x81, 0x02, /* Input (Variable), */
466 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */
467 0x09, 0x20, /* Usage (20h), */
468 0x15, 0x00, /* Logical Minimum (0), */
469 0x26, 0xFF, 0x00, /* Logical Maximum (255), */
470 0x75, 0x08, /* Report Size (8), */
471 0x95, 0x31, /* Report Count (51), */
472 0x81, 0x02, /* Input (Variable), */
473 0x09, 0x21, /* Usage (21h), */
474 0x75, 0x08, /* Report Size (8), */
475 0x95, 0x4D, /* Report Count (77), */
476 0x91, 0x02, /* Output (Variable), */
477 0x85, 0x12, /* Report ID (18), */
478 0x09, 0x22, /* Usage (22h), */
479 0x95, 0x8D, /* Report Count (141), */
480 0x81, 0x02, /* Input (Variable), */
481 0x09, 0x23, /* Usage (23h), */
482 0x91, 0x02, /* Output (Variable), */
483 0x85, 0x13, /* Report ID (19), */
484 0x09, 0x24, /* Usage (24h), */
485 0x95, 0xCD, /* Report Count (205), */
486 0x81, 0x02, /* Input (Variable), */
487 0x09, 0x25, /* Usage (25h), */
488 0x91, 0x02, /* Output (Variable), */
489 0x85, 0x14, /* Report ID (20), */
490 0x09, 0x26, /* Usage (26h), */
491 0x96, 0x0D, 0x01, /* Report Count (269), */
492 0x81, 0x02, /* Input (Variable), */
493 0x09, 0x27, /* Usage (27h), */
494 0x91, 0x02, /* Output (Variable), */
495 0x85, 0x15, /* Report ID (21), */
496 0x09, 0x28, /* Usage (28h), */
497 0x96, 0x4D, 0x01, /* Report Count (333), */
498 0x81, 0x02, /* Input (Variable), */
499 0x09, 0x29, /* Usage (29h), */
500 0x91, 0x02, /* Output (Variable), */
501 0x85, 0x16, /* Report ID (22), */
502 0x09, 0x2A, /* Usage (2Ah), */
503 0x96, 0x8D, 0x01, /* Report Count (397), */
504 0x81, 0x02, /* Input (Variable), */
505 0x09, 0x2B, /* Usage (2Bh), */
506 0x91, 0x02, /* Output (Variable), */
507 0x85, 0x17, /* Report ID (23), */
508 0x09, 0x2C, /* Usage (2Ch), */
509 0x96, 0xCD, 0x01, /* Report Count (461), */
510 0x81, 0x02, /* Input (Variable), */
511 0x09, 0x2D, /* Usage (2Dh), */
512 0x91, 0x02, /* Output (Variable), */
513 0x85, 0x18, /* Report ID (24), */
514 0x09, 0x2E, /* Usage (2Eh), */
515 0x96, 0x0D, 0x02, /* Report Count (525), */
516 0x81, 0x02, /* Input (Variable), */
517 0x09, 0x2F, /* Usage (2Fh), */
518 0x91, 0x02, /* Output (Variable), */
519 0x85, 0x19, /* Report ID (25), */
520 0x09, 0x30, /* Usage (30h), */
521 0x96, 0x22, 0x02, /* Report Count (546), */
522 0x81, 0x02, /* Input (Variable), */
523 0x09, 0x31, /* Usage (31h), */
524 0x91, 0x02, /* Output (Variable), */
525 0x06, 0x80, 0xFF, /* Usage Page (FF80h), */
526 0x85, 0x82, /* Report ID (130), */
527 0x09, 0x22, /* Usage (22h), */
528 0x95, 0x3F, /* Report Count (63), */
529 0xB1, 0x02, /* Feature (Variable), */
530 0x85, 0x83, /* Report ID (131), */
531 0x09, 0x23, /* Usage (23h), */
532 0xB1, 0x02, /* Feature (Variable), */
533 0x85, 0x84, /* Report ID (132), */
534 0x09, 0x24, /* Usage (24h), */
535 0xB1, 0x02, /* Feature (Variable), */
536 0x85, 0x90, /* Report ID (144), */
537 0x09, 0x30, /* Usage (30h), */
538 0xB1, 0x02, /* Feature (Variable), */
539 0x85, 0x91, /* Report ID (145), */
540 0x09, 0x31, /* Usage (31h), */
541 0xB1, 0x02, /* Feature (Variable), */
542 0x85, 0x92, /* Report ID (146), */
543 0x09, 0x32, /* Usage (32h), */
544 0xB1, 0x02, /* Feature (Variable), */
545 0x85, 0x93, /* Report ID (147), */
546 0x09, 0x33, /* Usage (33h), */
547 0xB1, 0x02, /* Feature (Variable), */
548 0x85, 0xA0, /* Report ID (160), */
549 0x09, 0x40, /* Usage (40h), */
550 0xB1, 0x02, /* Feature (Variable), */
551 0x85, 0xA4, /* Report ID (164), */
552 0x09, 0x44, /* Usage (44h), */
553 0xB1, 0x02, /* Feature (Variable), */
554 0xC0 /* End Collection */
555};
556
Jiri Kosina078328d2013-06-13 12:03:49 +0200557static __u8 ps3remote_rdesc[] = {
558 0x05, 0x01, /* GUsagePage Generic Desktop */
559 0x09, 0x05, /* LUsage 0x05 [Game Pad] */
560 0xA1, 0x01, /* MCollection Application (mouse, keyboard) */
561
562 /* Use collection 1 for joypad buttons */
563 0xA1, 0x02, /* MCollection Logical (interrelated data) */
564
565 /* Ignore the 1st byte, maybe it is used for a controller
566 * number but it's not needed for correct operation */
567 0x75, 0x08, /* GReportSize 0x08 [8] */
568 0x95, 0x01, /* GReportCount 0x01 [1] */
569 0x81, 0x01, /* MInput 0x01 (Const[0] Arr[1] Abs[2]) */
570
571 /* Bytes from 2nd to 4th are a bitmap for joypad buttons, for these
572 * buttons multiple keypresses are allowed */
573 0x05, 0x09, /* GUsagePage Button */
574 0x19, 0x01, /* LUsageMinimum 0x01 [Button 1 (primary/trigger)] */
575 0x29, 0x18, /* LUsageMaximum 0x18 [Button 24] */
576 0x14, /* GLogicalMinimum [0] */
577 0x25, 0x01, /* GLogicalMaximum 0x01 [1] */
578 0x75, 0x01, /* GReportSize 0x01 [1] */
579 0x95, 0x18, /* GReportCount 0x18 [24] */
580 0x81, 0x02, /* MInput 0x02 (Data[0] Var[1] Abs[2]) */
581
582 0xC0, /* MEndCollection */
583
584 /* Use collection 2 for remote control buttons */
585 0xA1, 0x02, /* MCollection Logical (interrelated data) */
586
587 /* 5th byte is used for remote control buttons */
588 0x05, 0x09, /* GUsagePage Button */
589 0x18, /* LUsageMinimum [No button pressed] */
590 0x29, 0xFE, /* LUsageMaximum 0xFE [Button 254] */
591 0x14, /* GLogicalMinimum [0] */
592 0x26, 0xFE, 0x00, /* GLogicalMaximum 0x00FE [254] */
593 0x75, 0x08, /* GReportSize 0x08 [8] */
594 0x95, 0x01, /* GReportCount 0x01 [1] */
595 0x80, /* MInput */
596
597 /* Ignore bytes from 6th to 11th, 6th to 10th are always constant at
598 * 0xff and 11th is for press indication */
599 0x75, 0x08, /* GReportSize 0x08 [8] */
600 0x95, 0x06, /* GReportCount 0x06 [6] */
601 0x81, 0x01, /* MInput 0x01 (Const[0] Arr[1] Abs[2]) */
602
603 /* 12th byte is for battery strength */
604 0x05, 0x06, /* GUsagePage Generic Device Controls */
605 0x09, 0x20, /* LUsage 0x20 [Battery Strength] */
606 0x14, /* GLogicalMinimum [0] */
607 0x25, 0x05, /* GLogicalMaximum 0x05 [5] */
608 0x75, 0x08, /* GReportSize 0x08 [8] */
609 0x95, 0x01, /* GReportCount 0x01 [1] */
610 0x81, 0x02, /* MInput 0x02 (Data[0] Var[1] Abs[2]) */
611
612 0xC0, /* MEndCollection */
613
614 0xC0 /* MEndCollection [Game Pad] */
615};
616
617static const unsigned int ps3remote_keymap_joypad_buttons[] = {
618 [0x01] = KEY_SELECT,
619 [0x02] = BTN_THUMBL, /* L3 */
620 [0x03] = BTN_THUMBR, /* R3 */
621 [0x04] = BTN_START,
622 [0x05] = KEY_UP,
623 [0x06] = KEY_RIGHT,
624 [0x07] = KEY_DOWN,
625 [0x08] = KEY_LEFT,
626 [0x09] = BTN_TL2, /* L2 */
627 [0x0a] = BTN_TR2, /* R2 */
628 [0x0b] = BTN_TL, /* L1 */
629 [0x0c] = BTN_TR, /* R1 */
630 [0x0d] = KEY_OPTION, /* options/triangle */
631 [0x0e] = KEY_BACK, /* back/circle */
632 [0x0f] = BTN_0, /* cross */
633 [0x10] = KEY_SCREEN, /* view/square */
634 [0x11] = KEY_HOMEPAGE, /* PS button */
635 [0x14] = KEY_ENTER,
636};
637static const unsigned int ps3remote_keymap_remote_buttons[] = {
638 [0x00] = KEY_1,
639 [0x01] = KEY_2,
640 [0x02] = KEY_3,
641 [0x03] = KEY_4,
642 [0x04] = KEY_5,
643 [0x05] = KEY_6,
644 [0x06] = KEY_7,
645 [0x07] = KEY_8,
646 [0x08] = KEY_9,
647 [0x09] = KEY_0,
648 [0x0e] = KEY_ESC, /* return */
649 [0x0f] = KEY_CLEAR,
650 [0x16] = KEY_EJECTCD,
651 [0x1a] = KEY_MENU, /* top menu */
652 [0x28] = KEY_TIME,
653 [0x30] = KEY_PREVIOUS,
654 [0x31] = KEY_NEXT,
655 [0x32] = KEY_PLAY,
656 [0x33] = KEY_REWIND, /* scan back */
657 [0x34] = KEY_FORWARD, /* scan forward */
658 [0x38] = KEY_STOP,
659 [0x39] = KEY_PAUSE,
660 [0x40] = KEY_CONTEXT_MENU, /* pop up/menu */
661 [0x60] = KEY_FRAMEBACK, /* slow/step back */
662 [0x61] = KEY_FRAMEFORWARD, /* slow/step forward */
663 [0x63] = KEY_SUBTITLE,
664 [0x64] = KEY_AUDIO,
665 [0x65] = KEY_ANGLE,
666 [0x70] = KEY_INFO, /* display */
667 [0x80] = KEY_BLUE,
668 [0x81] = KEY_RED,
669 [0x82] = KEY_GREEN,
670 [0x83] = KEY_YELLOW,
671};
672
Colin Leitnerf04d5142013-05-27 23:41:05 +0200673static const unsigned int buzz_keymap[] = {
Frank Praznikad142b92014-02-20 11:36:00 -0500674 /*
675 * The controller has 4 remote buzzers, each with one LED and 5
Colin Leitnerf04d5142013-05-27 23:41:05 +0200676 * buttons.
677 *
678 * We use the mapping chosen by the controller, which is:
679 *
680 * Key Offset
681 * -------------------
682 * Buzz 1
683 * Blue 5
684 * Orange 4
685 * Green 3
686 * Yellow 2
687 *
688 * So, for example, the orange button on the third buzzer is mapped to
689 * BTN_TRIGGER_HAPPY14
690 */
691 [ 1] = BTN_TRIGGER_HAPPY1,
692 [ 2] = BTN_TRIGGER_HAPPY2,
693 [ 3] = BTN_TRIGGER_HAPPY3,
694 [ 4] = BTN_TRIGGER_HAPPY4,
695 [ 5] = BTN_TRIGGER_HAPPY5,
696 [ 6] = BTN_TRIGGER_HAPPY6,
697 [ 7] = BTN_TRIGGER_HAPPY7,
698 [ 8] = BTN_TRIGGER_HAPPY8,
699 [ 9] = BTN_TRIGGER_HAPPY9,
700 [10] = BTN_TRIGGER_HAPPY10,
701 [11] = BTN_TRIGGER_HAPPY11,
702 [12] = BTN_TRIGGER_HAPPY12,
703 [13] = BTN_TRIGGER_HAPPY13,
704 [14] = BTN_TRIGGER_HAPPY14,
705 [15] = BTN_TRIGGER_HAPPY15,
706 [16] = BTN_TRIGGER_HAPPY16,
707 [17] = BTN_TRIGGER_HAPPY17,
708 [18] = BTN_TRIGGER_HAPPY18,
709 [19] = BTN_TRIGGER_HAPPY19,
710 [20] = BTN_TRIGGER_HAPPY20,
711};
712
Frank Praznikd902f472014-01-27 10:17:36 -0500713static enum power_supply_property sony_battery_props[] = {
714 POWER_SUPPLY_PROP_PRESENT,
715 POWER_SUPPLY_PROP_CAPACITY,
716 POWER_SUPPLY_PROP_SCOPE,
717 POWER_SUPPLY_PROP_STATUS,
718};
719
Jiri Kosinacc6e0bb2008-10-23 12:58:38 +0200720struct sony_sc {
Frank Praznikd902f472014-01-27 10:17:36 -0500721 spinlock_t lock;
Sven Eckelmann0a286ef2013-11-19 20:26:32 +0100722 struct hid_device *hdev;
Frank Praznik60781cf2014-01-11 15:13:15 -0500723 struct led_classdev *leds[MAX_LEDS];
Jiri Kosinacc6e0bb2008-10-23 12:58:38 +0200724 unsigned long quirks;
Sven Eckelmann0a286ef2013-11-19 20:26:32 +0100725 struct work_struct state_worker;
Frank Praznikd902f472014-01-27 10:17:36 -0500726 struct power_supply battery;
Colin Leitnerf04d5142013-05-27 23:41:05 +0200727
Sven Eckelmann9f323b62013-11-17 20:38:21 +0100728#ifdef CONFIG_SONY_FF
Sven Eckelmann9f323b62013-11-17 20:38:21 +0100729 __u8 left;
730 __u8 right;
731#endif
732
Frank Praznikc8de9db2014-02-20 11:36:01 -0500733 __u8 worker_initialized;
Frank Praznikd902f472014-01-27 10:17:36 -0500734 __u8 cable_state;
735 __u8 battery_charging;
736 __u8 battery_capacity;
Frank Praznik60781cf2014-01-11 15:13:15 -0500737 __u8 led_state[MAX_LEDS];
738 __u8 led_count;
Jiri Kosinacc6e0bb2008-10-23 12:58:38 +0200739};
740
Jiri Kosina078328d2013-06-13 12:03:49 +0200741static __u8 *ps3remote_fixup(struct hid_device *hdev, __u8 *rdesc,
742 unsigned int *rsize)
743{
744 *rsize = sizeof(ps3remote_rdesc);
745 return ps3remote_rdesc;
746}
747
748static int ps3remote_mapping(struct hid_device *hdev, struct hid_input *hi,
749 struct hid_field *field, struct hid_usage *usage,
750 unsigned long **bit, int *max)
751{
752 unsigned int key = usage->hid & HID_USAGE;
753
754 if ((usage->hid & HID_USAGE_PAGE) != HID_UP_BUTTON)
755 return -1;
756
757 switch (usage->collection_index) {
758 case 1:
759 if (key >= ARRAY_SIZE(ps3remote_keymap_joypad_buttons))
760 return -1;
761
762 key = ps3remote_keymap_joypad_buttons[key];
763 if (!key)
764 return -1;
765 break;
766 case 2:
767 if (key >= ARRAY_SIZE(ps3remote_keymap_remote_buttons))
768 return -1;
769
770 key = ps3remote_keymap_remote_buttons[key];
771 if (!key)
772 return -1;
773 break;
774 default:
775 return -1;
776 }
777
778 hid_map_usage_clear(hi, usage, bit, max, EV_KEY, key);
779 return 1;
780}
781
782
Jiri Kosinacc6e0bb2008-10-23 12:58:38 +0200783/* Sony Vaio VGX has wrongly mouse pointer declared as constant */
Nikolai Kondrashov73e40082010-08-06 23:03:06 +0400784static __u8 *sony_report_fixup(struct hid_device *hdev, __u8 *rdesc,
785 unsigned int *rsize)
Jiri Kosinacc6e0bb2008-10-23 12:58:38 +0200786{
787 struct sony_sc *sc = hid_get_drvdata(hdev);
788
Fernando Luis Vázquez Cao99d24902013-01-22 15:20:38 +0900789 /*
790 * Some Sony RF receivers wrongly declare the mouse pointer as a
791 * a constant non-data variable.
792 */
793 if ((sc->quirks & VAIO_RDESC_CONSTANT) && *rsize >= 56 &&
794 /* usage page: generic desktop controls */
795 /* rdesc[0] == 0x05 && rdesc[1] == 0x01 && */
796 /* usage: mouse */
797 rdesc[2] == 0x09 && rdesc[3] == 0x02 &&
798 /* input (usage page for x,y axes): constant, variable, relative */
799 rdesc[54] == 0x81 && rdesc[55] == 0x07) {
Fernando Luis Vázquez Caoa4649182013-01-15 19:40:48 +0900800 hid_info(hdev, "Fixing up Sony RF Receiver report descriptor\n");
Fernando Luis Vázquez Cao99d24902013-01-22 15:20:38 +0900801 /* input: data, variable, relative */
Jiri Kosinacc6e0bb2008-10-23 12:58:38 +0200802 rdesc[55] = 0x06;
803 }
Simon Wood61ab44b2011-06-10 12:00:26 +0200804
Frank Prazniked19d8c2014-01-16 21:43:12 -0500805 /*
806 * The default Dualshock 4 USB descriptor doesn't assign
807 * the gyroscope values to corresponding axes so we need a
808 * modified one.
809 */
810 if ((sc->quirks & DUALSHOCK4_CONTROLLER_USB) && *rsize == 467) {
811 hid_info(hdev, "Using modified Dualshock 4 report descriptor with gyroscope axes\n");
812 rdesc = dualshock4_usb_rdesc;
813 *rsize = sizeof(dualshock4_usb_rdesc);
Frank Praznikd829674d2014-02-05 20:03:45 -0500814 } else if ((sc->quirks & DUALSHOCK4_CONTROLLER_BT) && *rsize == 357) {
815 hid_info(hdev, "Using modified Dualshock 4 Bluetooth report descriptor\n");
816 rdesc = dualshock4_bt_rdesc;
817 *rsize = sizeof(dualshock4_bt_rdesc);
Frank Prazniked19d8c2014-01-16 21:43:12 -0500818 }
819
Simon Wood61ab44b2011-06-10 12:00:26 +0200820 /* The HID descriptor exposed over BT has a trailing zero byte */
821 if ((((sc->quirks & SIXAXIS_CONTROLLER_USB) && *rsize == 148) ||
822 ((sc->quirks & SIXAXIS_CONTROLLER_BT) && *rsize == 149)) &&
823 rdesc[83] == 0x75) {
824 hid_info(hdev, "Fixing up Sony Sixaxis report descriptor\n");
825 memcpy((void *)&rdesc[83], (void *)&sixaxis_rdesc_fixup,
826 sizeof(sixaxis_rdesc_fixup));
Mauro Carvalho Chehabe57a67d2012-12-14 20:57:34 -0200827 } else if (sc->quirks & SIXAXIS_CONTROLLER_USB &&
828 *rsize > sizeof(sixaxis_rdesc_fixup2)) {
829 hid_info(hdev, "Sony Sixaxis clone detected. Using original report descriptor (size: %d clone; %d new)\n",
830 *rsize, (int)sizeof(sixaxis_rdesc_fixup2));
831 *rsize = sizeof(sixaxis_rdesc_fixup2);
832 memcpy(rdesc, &sixaxis_rdesc_fixup2, *rsize);
Simon Wood61ab44b2011-06-10 12:00:26 +0200833 }
Jiri Kosina078328d2013-06-13 12:03:49 +0200834
835 if (sc->quirks & PS3REMOTE)
836 return ps3remote_fixup(hdev, rdesc, rsize);
837
Nikolai Kondrashov73e40082010-08-06 23:03:06 +0400838 return rdesc;
Jiri Kosinacc6e0bb2008-10-23 12:58:38 +0200839}
840
Frank Praznikd902f472014-01-27 10:17:36 -0500841static void sixaxis_parse_report(struct sony_sc *sc, __u8 *rd, int size)
842{
843 static const __u8 sixaxis_battery_capacity[] = { 0, 1, 25, 50, 75, 100 };
844 unsigned long flags;
845 __u8 cable_state, battery_capacity, battery_charging;
846
Frank Praznikad142b92014-02-20 11:36:00 -0500847 /*
848 * The sixaxis is charging if the battery value is 0xee
Frank Praznikd902f472014-01-27 10:17:36 -0500849 * and it is fully charged if the value is 0xef.
850 * It does not report the actual level while charging so it
851 * is set to 100% while charging is in progress.
852 */
853 if (rd[30] >= 0xee) {
854 battery_capacity = 100;
Frank Praznika43e94a2014-02-15 13:35:42 -0500855 battery_charging = !(rd[30] & 0x01);
Frank Praznikd902f472014-01-27 10:17:36 -0500856 } else {
Frank Praznikac3c9a92014-02-20 11:36:02 -0500857 __u8 index = rd[30] <= 5 ? rd[30] : 5;
858 battery_capacity = sixaxis_battery_capacity[index];
Frank Praznikd902f472014-01-27 10:17:36 -0500859 battery_charging = 0;
860 }
Frank Praznika43e94a2014-02-15 13:35:42 -0500861 cable_state = !((rd[31] >> 4) & 0x01);
Frank Praznikd902f472014-01-27 10:17:36 -0500862
863 spin_lock_irqsave(&sc->lock, flags);
864 sc->cable_state = cable_state;
865 sc->battery_capacity = battery_capacity;
866 sc->battery_charging = battery_charging;
867 spin_unlock_irqrestore(&sc->lock, flags);
868}
869
870static void dualshock4_parse_report(struct sony_sc *sc, __u8 *rd, int size)
871{
Frank Praznike5606232014-01-27 10:17:37 -0500872 struct hid_input *hidinput = list_entry(sc->hdev->inputs.next,
873 struct hid_input, list);
874 struct input_dev *input_dev = hidinput->input;
Frank Praznikd902f472014-01-27 10:17:36 -0500875 unsigned long flags;
Frank Praznik6c5f8602014-02-05 20:03:47 -0500876 int n, offset;
Frank Praznikd902f472014-01-27 10:17:36 -0500877 __u8 cable_state, battery_capacity, battery_charging;
878
Frank Praznikad142b92014-02-20 11:36:00 -0500879 /*
880 * Battery and touchpad data starts at byte 30 in the USB report and
Frank Praznik6c5f8602014-02-05 20:03:47 -0500881 * 32 in Bluetooth report.
882 */
883 offset = (sc->quirks & DUALSHOCK4_CONTROLLER_USB) ? 30 : 32;
884
Frank Praznikad142b92014-02-20 11:36:00 -0500885 /*
886 * The lower 4 bits of byte 30 contain the battery level
Frank Praznikd902f472014-01-27 10:17:36 -0500887 * and the 5th bit contains the USB cable state.
888 */
Frank Praznik6c5f8602014-02-05 20:03:47 -0500889 cable_state = (rd[offset] >> 4) & 0x01;
890 battery_capacity = rd[offset] & 0x0F;
Frank Praznikd902f472014-01-27 10:17:36 -0500891
Frank Praznikad142b92014-02-20 11:36:00 -0500892 /*
893 * When a USB power source is connected the battery level ranges from
Frank Praznik6c5f8602014-02-05 20:03:47 -0500894 * 0 to 10, and when running on battery power it ranges from 0 to 9.
895 * A battery level above 10 when plugged in means charge completed.
Frank Praznikd902f472014-01-27 10:17:36 -0500896 */
Frank Praznik6c5f8602014-02-05 20:03:47 -0500897 if (!cable_state || battery_capacity > 10)
Frank Praznikd902f472014-01-27 10:17:36 -0500898 battery_charging = 0;
899 else
900 battery_charging = 1;
901
Frank Praznik6c5f8602014-02-05 20:03:47 -0500902 if (!cable_state)
903 battery_capacity++;
Frank Praznikd902f472014-01-27 10:17:36 -0500904 if (battery_capacity > 10)
Frank Praznik6c5f8602014-02-05 20:03:47 -0500905 battery_capacity = 10;
906
Frank Praznikd902f472014-01-27 10:17:36 -0500907 battery_capacity *= 10;
908
909 spin_lock_irqsave(&sc->lock, flags);
910 sc->cable_state = cable_state;
911 sc->battery_capacity = battery_capacity;
912 sc->battery_charging = battery_charging;
913 spin_unlock_irqrestore(&sc->lock, flags);
Frank Praznike5606232014-01-27 10:17:37 -0500914
Frank Praznik6c5f8602014-02-05 20:03:47 -0500915 offset += 5;
916
Frank Praznikad142b92014-02-20 11:36:00 -0500917 /*
918 * The Dualshock 4 multi-touch trackpad data starts at offset 35 on USB
Frank Praznik6c5f8602014-02-05 20:03:47 -0500919 * and 37 on Bluetooth.
Frank Praznike5606232014-01-27 10:17:37 -0500920 * The first 7 bits of the first byte is a counter and bit 8 is a touch
921 * indicator that is 0 when pressed and 1 when not pressed.
922 * The next 3 bytes are two 12 bit touch coordinates, X and Y.
923 * The data for the second touch is in the same format and immediatly
924 * follows the data for the first.
925 */
926 for (n = 0; n < 2; n++) {
927 __u16 x, y;
928
929 x = rd[offset+1] | ((rd[offset+2] & 0xF) << 8);
930 y = ((rd[offset+2] & 0xF0) >> 4) | (rd[offset+3] << 4);
931
932 input_mt_slot(input_dev, n);
933 input_mt_report_slot_state(input_dev, MT_TOOL_FINGER,
934 !(rd[offset] >> 7));
935 input_report_abs(input_dev, ABS_MT_POSITION_X, x);
936 input_report_abs(input_dev, ABS_MT_POSITION_Y, y);
937
938 offset += 4;
939 }
Frank Praznikd902f472014-01-27 10:17:36 -0500940}
941
Simon Woodc9e4d872011-06-10 12:00:27 +0200942static int sony_raw_event(struct hid_device *hdev, struct hid_report *report,
943 __u8 *rd, int size)
944{
945 struct sony_sc *sc = hid_get_drvdata(hdev);
946
Frank Praznikad142b92014-02-20 11:36:00 -0500947 /*
948 * Sixaxis HID report has acclerometers/gyro with MSByte first, this
Simon Woodc9e4d872011-06-10 12:00:27 +0200949 * has to be BYTE_SWAPPED before passing up to joystick interface
950 */
Frank Praznikfee4e2d2014-02-18 17:22:01 -0500951 if ((sc->quirks & SIXAXIS_CONTROLLER) && rd[0] == 0x01 && size == 49) {
Simon Woodc9e4d872011-06-10 12:00:27 +0200952 swap(rd[41], rd[42]);
953 swap(rd[43], rd[44]);
954 swap(rd[45], rd[46]);
955 swap(rd[47], rd[48]);
Frank Praznikd902f472014-01-27 10:17:36 -0500956
957 sixaxis_parse_report(sc, rd, size);
Frank Praznik68330d82014-02-05 20:03:49 -0500958 } else if (((sc->quirks & DUALSHOCK4_CONTROLLER_USB) && rd[0] == 0x01 &&
959 size == 64) || ((sc->quirks & DUALSHOCK4_CONTROLLER_BT)
960 && rd[0] == 0x11 && size == 78)) {
Frank Praznikd902f472014-01-27 10:17:36 -0500961 dualshock4_parse_report(sc, rd, size);
Simon Woodc9e4d872011-06-10 12:00:27 +0200962 }
963
964 return 0;
965}
966
Colin Leitnerf04d5142013-05-27 23:41:05 +0200967static int sony_mapping(struct hid_device *hdev, struct hid_input *hi,
968 struct hid_field *field, struct hid_usage *usage,
969 unsigned long **bit, int *max)
970{
971 struct sony_sc *sc = hid_get_drvdata(hdev);
972
973 if (sc->quirks & BUZZ_CONTROLLER) {
974 unsigned int key = usage->hid & HID_USAGE;
975
976 if ((usage->hid & HID_USAGE_PAGE) != HID_UP_BUTTON)
977 return -1;
978
979 switch (usage->collection_index) {
980 case 1:
981 if (key >= ARRAY_SIZE(buzz_keymap))
982 return -1;
983
984 key = buzz_keymap[key];
985 if (!key)
986 return -1;
987 break;
988 default:
989 return -1;
990 }
991
992 hid_map_usage_clear(hi, usage, bit, max, EV_KEY, key);
993 return 1;
994 }
995
Jiri Kosina078328d2013-06-13 12:03:49 +0200996 if (sc->quirks & PS3REMOTE)
997 return ps3remote_mapping(hdev, hi, field, usage, bit, max);
998
Benjamin Tissoires6f498012013-07-24 16:53:07 +0200999 /* Let hid-core decide for the others */
1000 return 0;
Colin Leitnerf04d5142013-05-27 23:41:05 +02001001}
1002
Antonio Ospite5710fab2011-02-20 18:26:45 +01001003/*
1004 * The Sony Sixaxis does not handle HID Output Reports on the Interrupt EP
1005 * like it should according to usbhid/hid-core.c::usbhid_output_raw_report()
1006 * so we need to override that forcing HID Output Reports on the Control EP.
1007 *
1008 * There is also another issue about HID Output Reports via USB, the Sixaxis
1009 * does not want the report_id as part of the data packet, so we have to
1010 * discard buf[0] when sending the actual control message, even for numbered
1011 * reports, humpf!
1012 */
Antonio Ospite569b10a2010-10-19 16:13:10 +02001013static int sixaxis_usb_output_raw_report(struct hid_device *hid, __u8 *buf,
1014 size_t count, unsigned char report_type)
1015{
1016 struct usb_interface *intf = to_usb_interface(hid->dev.parent);
1017 struct usb_device *dev = interface_to_usbdev(intf);
1018 struct usb_host_interface *interface = intf->cur_altsetting;
1019 int report_id = buf[0];
1020 int ret;
1021
Antonio Ospite5710fab2011-02-20 18:26:45 +01001022 if (report_type == HID_OUTPUT_REPORT) {
1023 /* Don't send the Report ID */
1024 buf++;
1025 count--;
1026 }
1027
Antonio Ospite569b10a2010-10-19 16:13:10 +02001028 ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
1029 HID_REQ_SET_REPORT,
1030 USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
1031 ((report_type + 1) << 8) | report_id,
1032 interface->desc.bInterfaceNumber, buf, count,
1033 USB_CTRL_SET_TIMEOUT);
1034
Antonio Ospite5710fab2011-02-20 18:26:45 +01001035 /* Count also the Report ID, in case of an Output report. */
1036 if (ret > 0 && report_type == HID_OUTPUT_REPORT)
1037 ret++;
1038
Antonio Ospite569b10a2010-10-19 16:13:10 +02001039 return ret;
1040}
1041
Jiri Slabybd28ce02008-06-25 23:47:04 +02001042/*
1043 * Sending HID_REQ_GET_REPORT changes the operation mode of the ps3 controller
1044 * to "operational". Without this, the ps3 controller will not report any
1045 * events.
1046 */
Antonio Ospite816651a2010-05-03 22:15:55 +02001047static int sixaxis_set_operational_usb(struct hid_device *hdev)
Jiri Slabybd28ce02008-06-25 23:47:04 +02001048{
Jiri Slabybd28ce02008-06-25 23:47:04 +02001049 int ret;
1050 char *buf = kmalloc(18, GFP_KERNEL);
1051
1052 if (!buf)
1053 return -ENOMEM;
1054
Benjamin Tissoirescafebc02014-02-05 16:33:22 -05001055 ret = hid_hw_raw_request(hdev, 0xf2, buf, 17, HID_FEATURE_REPORT,
1056 HID_REQ_GET_REPORT);
Benjamin Tissoiresf204828a2013-09-11 22:12:25 +02001057
Jiri Slabybd28ce02008-06-25 23:47:04 +02001058 if (ret < 0)
Joe Perches4291ee32010-12-09 19:29:03 -08001059 hid_err(hdev, "can't set operational mode\n");
Jiri Slabybd28ce02008-06-25 23:47:04 +02001060
1061 kfree(buf);
1062
1063 return ret;
1064}
1065
Antonio Ospite816651a2010-05-03 22:15:55 +02001066static int sixaxis_set_operational_bt(struct hid_device *hdev)
Bastien Noceraf9ce7c22010-01-20 12:01:53 +00001067{
Antonio Ospitefddb33f2010-05-03 17:19:03 +02001068 unsigned char buf[] = { 0xf4, 0x42, 0x03, 0x00, 0x00 };
Benjamin Tissoires7e845d42014-02-05 16:33:23 -05001069 return hid_output_raw_report(hdev, buf, sizeof(buf),
1070 HID_FEATURE_REPORT);
Bastien Noceraf9ce7c22010-01-20 12:01:53 +00001071}
1072
Frank Praznikad142b92014-02-20 11:36:00 -05001073/*
1074 * Requesting feature report 0x02 in Bluetooth mode changes the state of the
Frank Praznik68330d82014-02-05 20:03:49 -05001075 * controller so that it sends full input reports of type 0x11.
1076 */
1077static int dualshock4_set_operational_bt(struct hid_device *hdev)
1078{
1079 __u8 buf[37] = { 0 };
1080
1081 return hid_hw_raw_request(hdev, 0x02, buf, sizeof(buf),
1082 HID_FEATURE_REPORT, HID_REQ_GET_REPORT);
1083}
1084
Frank Praznik60781cf2014-01-11 15:13:15 -05001085static void buzz_set_leds(struct hid_device *hdev, const __u8 *leds)
Colin Leitnerf04d5142013-05-27 23:41:05 +02001086{
1087 struct list_head *report_list =
1088 &hdev->report_enum[HID_OUTPUT_REPORT].report_list;
1089 struct hid_report *report = list_entry(report_list->next,
1090 struct hid_report, list);
1091 __s32 *value = report->field[0]->value;
1092
1093 value[0] = 0x00;
Frank Praznik60781cf2014-01-11 15:13:15 -05001094 value[1] = leds[0] ? 0xff : 0x00;
1095 value[2] = leds[1] ? 0xff : 0x00;
1096 value[3] = leds[2] ? 0xff : 0x00;
1097 value[4] = leds[3] ? 0xff : 0x00;
Colin Leitnerf04d5142013-05-27 23:41:05 +02001098 value[5] = 0x00;
1099 value[6] = 0x00;
1100 hid_hw_request(hdev, report, HID_REQ_SET_REPORT);
1101}
1102
Frank Praznik60781cf2014-01-11 15:13:15 -05001103static void sony_set_leds(struct hid_device *hdev, const __u8 *leds, int count)
Sven Eckelmann0a286ef2013-11-19 20:26:32 +01001104{
1105 struct sony_sc *drv_data = hid_get_drvdata(hdev);
Frank Praznik60781cf2014-01-11 15:13:15 -05001106 int n;
Sven Eckelmann0a286ef2013-11-19 20:26:32 +01001107
Frank Praznik60781cf2014-01-11 15:13:15 -05001108 BUG_ON(count > MAX_LEDS);
1109
1110 if (drv_data->quirks & BUZZ_CONTROLLER && count == 4) {
Sven Eckelmann0a286ef2013-11-19 20:26:32 +01001111 buzz_set_leds(hdev, leds);
Frank Praznikfee4e2d2014-02-18 17:22:01 -05001112 } else {
Frank Praznik60781cf2014-01-11 15:13:15 -05001113 for (n = 0; n < count; n++)
1114 drv_data->led_state[n] = leds[n];
Sven Eckelmann0a286ef2013-11-19 20:26:32 +01001115 schedule_work(&drv_data->state_worker);
1116 }
1117}
1118
Sven Eckelmannc5382512013-11-19 20:26:30 +01001119static void sony_led_set_brightness(struct led_classdev *led,
Colin Leitnerf04d5142013-05-27 23:41:05 +02001120 enum led_brightness value)
1121{
1122 struct device *dev = led->dev->parent;
1123 struct hid_device *hdev = container_of(dev, struct hid_device, dev);
1124 struct sony_sc *drv_data;
Colin Leitnerf04d5142013-05-27 23:41:05 +02001125
1126 int n;
1127
1128 drv_data = hid_get_drvdata(hdev);
Sven Eckelmann2251b852013-11-19 20:26:31 +01001129 if (!drv_data) {
Colin Leitnerf04d5142013-05-27 23:41:05 +02001130 hid_err(hdev, "No device data\n");
1131 return;
1132 }
Colin Leitnerf04d5142013-05-27 23:41:05 +02001133
Frank Praznik60781cf2014-01-11 15:13:15 -05001134 for (n = 0; n < drv_data->led_count; n++) {
Sven Eckelmann2251b852013-11-19 20:26:31 +01001135 if (led == drv_data->leds[n]) {
Frank Praznik60781cf2014-01-11 15:13:15 -05001136 if (value != drv_data->led_state[n]) {
1137 drv_data->led_state[n] = value;
1138 sony_set_leds(hdev, drv_data->led_state, drv_data->led_count);
Colin Leitnerf04d5142013-05-27 23:41:05 +02001139 }
1140 break;
1141 }
1142 }
1143}
1144
Sven Eckelmannc5382512013-11-19 20:26:30 +01001145static enum led_brightness sony_led_get_brightness(struct led_classdev *led)
Colin Leitnerf04d5142013-05-27 23:41:05 +02001146{
1147 struct device *dev = led->dev->parent;
1148 struct hid_device *hdev = container_of(dev, struct hid_device, dev);
1149 struct sony_sc *drv_data;
Colin Leitnerf04d5142013-05-27 23:41:05 +02001150
1151 int n;
Colin Leitnerf04d5142013-05-27 23:41:05 +02001152
1153 drv_data = hid_get_drvdata(hdev);
Sven Eckelmann2251b852013-11-19 20:26:31 +01001154 if (!drv_data) {
Colin Leitnerf04d5142013-05-27 23:41:05 +02001155 hid_err(hdev, "No device data\n");
1156 return LED_OFF;
1157 }
Colin Leitnerf04d5142013-05-27 23:41:05 +02001158
Frank Praznik60781cf2014-01-11 15:13:15 -05001159 for (n = 0; n < drv_data->led_count; n++) {
Simon Wood7db75042014-02-05 12:34:18 -07001160 if (led == drv_data->leds[n])
1161 return drv_data->led_state[n];
Colin Leitnerf04d5142013-05-27 23:41:05 +02001162 }
1163
Simon Wood7db75042014-02-05 12:34:18 -07001164 return LED_OFF;
Colin Leitnerf04d5142013-05-27 23:41:05 +02001165}
Colin Leitnerf04d5142013-05-27 23:41:05 +02001166
Sven Eckelmann0a286ef2013-11-19 20:26:32 +01001167static void sony_leds_remove(struct hid_device *hdev)
1168{
1169 struct sony_sc *drv_data;
1170 struct led_classdev *led;
1171 int n;
1172
1173 drv_data = hid_get_drvdata(hdev);
1174 BUG_ON(!(drv_data->quirks & SONY_LED_SUPPORT));
1175
Frank Praznik60781cf2014-01-11 15:13:15 -05001176 for (n = 0; n < drv_data->led_count; n++) {
Sven Eckelmann0a286ef2013-11-19 20:26:32 +01001177 led = drv_data->leds[n];
1178 drv_data->leds[n] = NULL;
1179 if (!led)
1180 continue;
1181 led_classdev_unregister(led);
1182 kfree(led);
1183 }
Frank Praznik60781cf2014-01-11 15:13:15 -05001184
1185 drv_data->led_count = 0;
Sven Eckelmann0a286ef2013-11-19 20:26:32 +01001186}
1187
Sven Eckelmannc5382512013-11-19 20:26:30 +01001188static int sony_leds_init(struct hid_device *hdev)
Colin Leitnerf04d5142013-05-27 23:41:05 +02001189{
1190 struct sony_sc *drv_data;
Jiri Kosina40e32ee2013-05-28 11:22:09 +02001191 int n, ret = 0;
Frank Praznik60781cf2014-01-11 15:13:15 -05001192 int max_brightness;
Frank Praznik61ebca92014-01-20 12:27:02 -05001193 int use_colors;
Jiri Kosina40e32ee2013-05-28 11:22:09 +02001194 struct led_classdev *led;
1195 size_t name_sz;
1196 char *name;
Sven Eckelmann0a286ef2013-11-19 20:26:32 +01001197 size_t name_len;
1198 const char *name_fmt;
Frank Praznik61ebca92014-01-20 12:27:02 -05001199 static const char * const color_str[] = { "red", "green", "blue" };
Frank Praznik60781cf2014-01-11 15:13:15 -05001200 static const __u8 initial_values[MAX_LEDS] = { 0x00, 0x00, 0x00, 0x00 };
Colin Leitnerf04d5142013-05-27 23:41:05 +02001201
1202 drv_data = hid_get_drvdata(hdev);
Sven Eckelmann0a286ef2013-11-19 20:26:32 +01001203 BUG_ON(!(drv_data->quirks & SONY_LED_SUPPORT));
Colin Leitnerf04d5142013-05-27 23:41:05 +02001204
Sven Eckelmann0a286ef2013-11-19 20:26:32 +01001205 if (drv_data->quirks & BUZZ_CONTROLLER) {
Frank Praznik61ebca92014-01-20 12:27:02 -05001206 drv_data->led_count = 4;
1207 max_brightness = 1;
1208 use_colors = 0;
Sven Eckelmann0a286ef2013-11-19 20:26:32 +01001209 name_len = strlen("::buzz#");
1210 name_fmt = "%s::buzz%d";
1211 /* Validate expected report characteristics. */
1212 if (!hid_validate_values(hdev, HID_OUTPUT_REPORT, 0, 0, 7))
1213 return -ENODEV;
Frank Praznik68330d82014-02-05 20:03:49 -05001214 } else if (drv_data->quirks & DUALSHOCK4_CONTROLLER) {
Frank Praznik60781cf2014-01-11 15:13:15 -05001215 drv_data->led_count = 3;
1216 max_brightness = 255;
Frank Praznik61ebca92014-01-20 12:27:02 -05001217 use_colors = 1;
1218 name_len = 0;
1219 name_fmt = "%s:%s";
Frank Praznik60781cf2014-01-11 15:13:15 -05001220 } else {
1221 drv_data->led_count = 4;
1222 max_brightness = 1;
Frank Praznik61ebca92014-01-20 12:27:02 -05001223 use_colors = 0;
1224 name_len = strlen("::sony#");
1225 name_fmt = "%s::sony%d";
Frank Praznik60781cf2014-01-11 15:13:15 -05001226 }
1227
Frank Praznikad142b92014-02-20 11:36:00 -05001228 /*
1229 * Clear LEDs as we have no way of reading their initial state. This is
Colin Leitnerf04d5142013-05-27 23:41:05 +02001230 * only relevant if the driver is loaded after somebody actively set the
Frank Praznikad142b92014-02-20 11:36:00 -05001231 * LEDs to on
1232 */
Frank Praznik60781cf2014-01-11 15:13:15 -05001233 sony_set_leds(hdev, initial_values, drv_data->led_count);
Colin Leitnerf04d5142013-05-27 23:41:05 +02001234
Sven Eckelmann0a286ef2013-11-19 20:26:32 +01001235 name_sz = strlen(dev_name(&hdev->dev)) + name_len + 1;
Colin Leitnerf04d5142013-05-27 23:41:05 +02001236
Frank Praznik60781cf2014-01-11 15:13:15 -05001237 for (n = 0; n < drv_data->led_count; n++) {
Frank Praznik61ebca92014-01-20 12:27:02 -05001238
1239 if (use_colors)
1240 name_sz = strlen(dev_name(&hdev->dev)) + strlen(color_str[n]) + 2;
1241
Jiri Kosina40e32ee2013-05-28 11:22:09 +02001242 led = kzalloc(sizeof(struct led_classdev) + name_sz, GFP_KERNEL);
1243 if (!led) {
1244 hid_err(hdev, "Couldn't allocate memory for LED %d\n", n);
Julia Lawall8cd5fcd2013-12-29 23:47:27 +01001245 ret = -ENOMEM;
Jiri Kosina40e32ee2013-05-28 11:22:09 +02001246 goto error_leds;
Colin Leitnerf04d5142013-05-27 23:41:05 +02001247 }
Jiri Kosina40e32ee2013-05-28 11:22:09 +02001248
1249 name = (void *)(&led[1]);
Frank Praznik61ebca92014-01-20 12:27:02 -05001250 if (use_colors)
1251 snprintf(name, name_sz, name_fmt, dev_name(&hdev->dev), color_str[n]);
1252 else
1253 snprintf(name, name_sz, name_fmt, dev_name(&hdev->dev), n + 1);
Jiri Kosina40e32ee2013-05-28 11:22:09 +02001254 led->name = name;
1255 led->brightness = 0;
Frank Praznik60781cf2014-01-11 15:13:15 -05001256 led->max_brightness = max_brightness;
Sven Eckelmannc5382512013-11-19 20:26:30 +01001257 led->brightness_get = sony_led_get_brightness;
1258 led->brightness_set = sony_led_set_brightness;
Jiri Kosina40e32ee2013-05-28 11:22:09 +02001259
Julia Lawall8cd5fcd2013-12-29 23:47:27 +01001260 ret = led_classdev_register(&hdev->dev, led);
1261 if (ret) {
Jiri Kosina40e32ee2013-05-28 11:22:09 +02001262 hid_err(hdev, "Failed to register LED %d\n", n);
1263 kfree(led);
1264 goto error_leds;
1265 }
1266
Sven Eckelmann2251b852013-11-19 20:26:31 +01001267 drv_data->leds[n] = led;
Colin Leitnerf04d5142013-05-27 23:41:05 +02001268 }
Colin Leitnerf04d5142013-05-27 23:41:05 +02001269
1270 return ret;
1271
Colin Leitnerf04d5142013-05-27 23:41:05 +02001272error_leds:
Sven Eckelmann0a286ef2013-11-19 20:26:32 +01001273 sony_leds_remove(hdev);
Colin Leitnerf04d5142013-05-27 23:41:05 +02001274
Colin Leitnerf04d5142013-05-27 23:41:05 +02001275 return ret;
Colin Leitnerf04d5142013-05-27 23:41:05 +02001276}
1277
Frank Praznikcad665a2014-01-11 15:13:54 -05001278static void sixaxis_state_worker(struct work_struct *work)
Sven Eckelmanna08c22c2013-11-09 19:25:57 +01001279{
Sven Eckelmann92b5c412013-11-19 20:26:28 +01001280 struct sony_sc *sc = container_of(work, struct sony_sc, state_worker);
Sven Eckelmanna08c22c2013-11-09 19:25:57 +01001281 unsigned char buf[] = {
1282 0x01,
1283 0x00, 0xff, 0x00, 0xff, 0x00,
Sven Eckelmann0a286ef2013-11-19 20:26:32 +01001284 0x00, 0x00, 0x00, 0x00, 0x00,
Sven Eckelmanna08c22c2013-11-09 19:25:57 +01001285 0xff, 0x27, 0x10, 0x00, 0x32,
1286 0xff, 0x27, 0x10, 0x00, 0x32,
1287 0xff, 0x27, 0x10, 0x00, 0x32,
1288 0xff, 0x27, 0x10, 0x00, 0x32,
1289 0x00, 0x00, 0x00, 0x00, 0x00
1290 };
Sven Eckelmann9f323b62013-11-17 20:38:21 +01001291
Sven Eckelmann0a286ef2013-11-19 20:26:32 +01001292#ifdef CONFIG_SONY_FF
Frank Praznik0bd88dd2014-01-11 15:12:42 -05001293 buf[3] = sc->right ? 1 : 0;
Sven Eckelmann9f323b62013-11-17 20:38:21 +01001294 buf[5] = sc->left;
Sven Eckelmann0a286ef2013-11-19 20:26:32 +01001295#endif
1296
Frank Praznik60781cf2014-01-11 15:13:15 -05001297 buf[10] |= sc->led_state[0] << 1;
1298 buf[10] |= sc->led_state[1] << 2;
1299 buf[10] |= sc->led_state[2] << 3;
1300 buf[10] |= sc->led_state[3] << 4;
Sven Eckelmann9f323b62013-11-17 20:38:21 +01001301
Frank Praznikfee4e2d2014-02-18 17:22:01 -05001302 if (sc->quirks & SIXAXIS_CONTROLLER_USB)
1303 hid_output_raw_report(sc->hdev, buf, sizeof(buf), HID_OUTPUT_REPORT);
1304 else
1305 hid_hw_raw_request(sc->hdev, 0x01, buf, sizeof(buf),
1306 HID_OUTPUT_REPORT, HID_REQ_SET_REPORT);
Sven Eckelmann9f323b62013-11-17 20:38:21 +01001307}
1308
Frank Praznik0bd88dd2014-01-11 15:12:42 -05001309static void dualshock4_state_worker(struct work_struct *work)
1310{
1311 struct sony_sc *sc = container_of(work, struct sony_sc, state_worker);
Frank Praznik0da8ea62014-01-16 21:42:51 -05001312 struct hid_device *hdev = sc->hdev;
Frank Praznik48220232014-02-05 20:03:44 -05001313 int offset;
Frank Praznik0da8ea62014-01-16 21:42:51 -05001314
Frank Praznikfdcf105d2014-02-05 20:03:46 -05001315 __u8 buf[78] = { 0 };
Frank Praznik48220232014-02-05 20:03:44 -05001316
Frank Praznikfdcf105d2014-02-05 20:03:46 -05001317 if (sc->quirks & DUALSHOCK4_CONTROLLER_USB) {
1318 buf[0] = 0x05;
1319 buf[1] = 0x03;
1320 offset = 4;
1321 } else {
1322 buf[0] = 0x11;
1323 buf[1] = 0xB0;
1324 buf[3] = 0x0F;
1325 offset = 6;
1326 }
Frank Praznik0bd88dd2014-01-11 15:12:42 -05001327
1328#ifdef CONFIG_SONY_FF
Frank Praznik48220232014-02-05 20:03:44 -05001329 buf[offset++] = sc->right;
1330 buf[offset++] = sc->left;
1331#else
1332 offset += 2;
Frank Praznik0bd88dd2014-01-11 15:12:42 -05001333#endif
1334
Frank Praznik48220232014-02-05 20:03:44 -05001335 buf[offset++] = sc->led_state[0];
1336 buf[offset++] = sc->led_state[1];
1337 buf[offset++] = sc->led_state[2];
Frank Praznik60781cf2014-01-11 15:13:15 -05001338
Frank Praznikfdcf105d2014-02-05 20:03:46 -05001339 if (sc->quirks & DUALSHOCK4_CONTROLLER_USB)
1340 hid_hw_output_report(hdev, buf, 32);
1341 else
1342 hid_hw_raw_request(hdev, 0x11, buf, 78,
1343 HID_OUTPUT_REPORT, HID_REQ_SET_REPORT);
Frank Praznik0bd88dd2014-01-11 15:12:42 -05001344}
1345
Sven Eckelmann0a286ef2013-11-19 20:26:32 +01001346#ifdef CONFIG_SONY_FF
Sven Eckelmann9f323b62013-11-17 20:38:21 +01001347static int sony_play_effect(struct input_dev *dev, void *data,
1348 struct ff_effect *effect)
1349{
Sven Eckelmanna08c22c2013-11-09 19:25:57 +01001350 struct hid_device *hid = input_get_drvdata(dev);
Sven Eckelmann9f323b62013-11-17 20:38:21 +01001351 struct sony_sc *sc = hid_get_drvdata(hid);
Sven Eckelmanna08c22c2013-11-09 19:25:57 +01001352
1353 if (effect->type != FF_RUMBLE)
1354 return 0;
1355
Sven Eckelmann9f323b62013-11-17 20:38:21 +01001356 sc->left = effect->u.rumble.strong_magnitude / 256;
Frank Praznik0bd88dd2014-01-11 15:12:42 -05001357 sc->right = effect->u.rumble.weak_magnitude / 256;
Sven Eckelmanna08c22c2013-11-09 19:25:57 +01001358
Sven Eckelmann92b5c412013-11-19 20:26:28 +01001359 schedule_work(&sc->state_worker);
Sven Eckelmann9f323b62013-11-17 20:38:21 +01001360 return 0;
Sven Eckelmanna08c22c2013-11-09 19:25:57 +01001361}
1362
1363static int sony_init_ff(struct hid_device *hdev)
1364{
1365 struct hid_input *hidinput = list_entry(hdev->inputs.next,
1366 struct hid_input, list);
1367 struct input_dev *input_dev = hidinput->input;
1368
1369 input_set_capability(input_dev, EV_FF, FF_RUMBLE);
1370 return input_ff_create_memless(input_dev, NULL, sony_play_effect);
1371}
1372
1373#else
1374static int sony_init_ff(struct hid_device *hdev)
1375{
1376 return 0;
1377}
Sven Eckelmann9f323b62013-11-17 20:38:21 +01001378
Sven Eckelmanna08c22c2013-11-09 19:25:57 +01001379#endif
1380
Frank Praznikd902f472014-01-27 10:17:36 -05001381static int sony_battery_get_property(struct power_supply *psy,
1382 enum power_supply_property psp,
1383 union power_supply_propval *val)
1384{
1385 struct sony_sc *sc = container_of(psy, struct sony_sc, battery);
1386 unsigned long flags;
1387 int ret = 0;
1388 u8 battery_charging, battery_capacity, cable_state;
1389
1390 spin_lock_irqsave(&sc->lock, flags);
1391 battery_charging = sc->battery_charging;
1392 battery_capacity = sc->battery_capacity;
1393 cable_state = sc->cable_state;
1394 spin_unlock_irqrestore(&sc->lock, flags);
1395
1396 switch (psp) {
1397 case POWER_SUPPLY_PROP_PRESENT:
1398 val->intval = 1;
1399 break;
1400 case POWER_SUPPLY_PROP_SCOPE:
1401 val->intval = POWER_SUPPLY_SCOPE_DEVICE;
1402 break;
1403 case POWER_SUPPLY_PROP_CAPACITY:
1404 val->intval = battery_capacity;
1405 break;
1406 case POWER_SUPPLY_PROP_STATUS:
1407 if (battery_charging)
1408 val->intval = POWER_SUPPLY_STATUS_CHARGING;
1409 else
1410 if (battery_capacity == 100 && cable_state)
1411 val->intval = POWER_SUPPLY_STATUS_FULL;
1412 else
1413 val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
1414 break;
1415 default:
1416 ret = -EINVAL;
1417 break;
1418 }
1419 return ret;
1420}
1421
1422static int sony_battery_probe(struct sony_sc *sc)
1423{
1424 static atomic_t power_id_seq = ATOMIC_INIT(0);
1425 unsigned long power_id;
1426 struct hid_device *hdev = sc->hdev;
1427 int ret;
1428
Frank Praznikad142b92014-02-20 11:36:00 -05001429 /*
1430 * Set the default battery level to 100% to avoid low battery warnings
Frank Praznikd9a293a2014-02-05 20:03:48 -05001431 * if the battery is polled before the first device report is received.
1432 */
1433 sc->battery_capacity = 100;
1434
Frank Praznikd902f472014-01-27 10:17:36 -05001435 power_id = (unsigned long)atomic_inc_return(&power_id_seq);
1436
1437 sc->battery.properties = sony_battery_props;
1438 sc->battery.num_properties = ARRAY_SIZE(sony_battery_props);
1439 sc->battery.get_property = sony_battery_get_property;
1440 sc->battery.type = POWER_SUPPLY_TYPE_BATTERY;
1441 sc->battery.use_for_apm = 0;
1442 sc->battery.name = kasprintf(GFP_KERNEL, "sony_controller_battery_%lu",
1443 power_id);
1444 if (!sc->battery.name)
1445 return -ENOMEM;
1446
1447 ret = power_supply_register(&hdev->dev, &sc->battery);
1448 if (ret) {
1449 hid_err(hdev, "Unable to register battery device\n");
1450 goto err_free;
1451 }
1452
1453 power_supply_powers(&sc->battery, &hdev->dev);
1454 return 0;
1455
1456err_free:
1457 kfree(sc->battery.name);
1458 sc->battery.name = NULL;
1459 return ret;
1460}
1461
1462static void sony_battery_remove(struct sony_sc *sc)
1463{
1464 if (!sc->battery.name)
1465 return;
1466
1467 power_supply_unregister(&sc->battery);
1468 kfree(sc->battery.name);
1469 sc->battery.name = NULL;
1470}
1471
Frank Praznike5606232014-01-27 10:17:37 -05001472static int sony_register_touchpad(struct sony_sc *sc, int touch_count,
1473 int w, int h)
1474{
1475 struct hid_input *hidinput = list_entry(sc->hdev->inputs.next,
1476 struct hid_input, list);
1477 struct input_dev *input_dev = hidinput->input;
1478 int ret;
1479
1480 ret = input_mt_init_slots(input_dev, touch_count, 0);
1481 if (ret < 0) {
1482 hid_err(sc->hdev, "Unable to initialize multi-touch slots\n");
1483 return ret;
1484 }
1485
1486 input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0, w, 0, 0);
1487 input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0, h, 0, 0);
1488
1489 return 0;
1490}
1491
Jiri Slabybd28ce02008-06-25 23:47:04 +02001492static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
1493{
1494 int ret;
Jiri Kosinacc6e0bb2008-10-23 12:58:38 +02001495 unsigned long quirks = id->driver_data;
1496 struct sony_sc *sc;
Colin Leitnerf04d5142013-05-27 23:41:05 +02001497 unsigned int connect_mask = HID_CONNECT_DEFAULT;
Jiri Kosinacc6e0bb2008-10-23 12:58:38 +02001498
Benjamin Tissoiresabf832b2013-07-24 19:38:04 +02001499 sc = devm_kzalloc(&hdev->dev, sizeof(*sc), GFP_KERNEL);
Jiri Kosinacc6e0bb2008-10-23 12:58:38 +02001500 if (sc == NULL) {
Joe Perches4291ee32010-12-09 19:29:03 -08001501 hid_err(hdev, "can't alloc sony descriptor\n");
Jiri Kosinacc6e0bb2008-10-23 12:58:38 +02001502 return -ENOMEM;
1503 }
1504
1505 sc->quirks = quirks;
1506 hid_set_drvdata(hdev, sc);
Sven Eckelmann0a286ef2013-11-19 20:26:32 +01001507 sc->hdev = hdev;
Jiri Slabybd28ce02008-06-25 23:47:04 +02001508
Jiri Slabybd28ce02008-06-25 23:47:04 +02001509 ret = hid_parse(hdev);
1510 if (ret) {
Joe Perches4291ee32010-12-09 19:29:03 -08001511 hid_err(hdev, "parse failed\n");
Benjamin Tissoiresabf832b2013-07-24 19:38:04 +02001512 return ret;
Jiri Slabybd28ce02008-06-25 23:47:04 +02001513 }
1514
Colin Leitnerf04d5142013-05-27 23:41:05 +02001515 if (sc->quirks & VAIO_RDESC_CONSTANT)
1516 connect_mask |= HID_CONNECT_HIDDEV_FORCE;
1517 else if (sc->quirks & SIXAXIS_CONTROLLER_USB)
1518 connect_mask |= HID_CONNECT_HIDDEV_FORCE;
1519 else if (sc->quirks & SIXAXIS_CONTROLLER_BT)
1520 connect_mask |= HID_CONNECT_HIDDEV_FORCE;
1521
1522 ret = hid_hw_start(hdev, connect_mask);
Jiri Slabybd28ce02008-06-25 23:47:04 +02001523 if (ret) {
Joe Perches4291ee32010-12-09 19:29:03 -08001524 hid_err(hdev, "hw start failed\n");
Benjamin Tissoiresabf832b2013-07-24 19:38:04 +02001525 return ret;
Jiri Slabybd28ce02008-06-25 23:47:04 +02001526 }
1527
Antonio Ospite569b10a2010-10-19 16:13:10 +02001528 if (sc->quirks & SIXAXIS_CONTROLLER_USB) {
1529 hdev->hid_output_raw_report = sixaxis_usb_output_raw_report;
Antonio Ospite816651a2010-05-03 22:15:55 +02001530 ret = sixaxis_set_operational_usb(hdev);
Frank Praznikc8de9db2014-02-20 11:36:01 -05001531 sc->worker_initialized = 1;
Frank Praznikcad665a2014-01-11 15:13:54 -05001532 INIT_WORK(&sc->state_worker, sixaxis_state_worker);
Frank Praznikfee4e2d2014-02-18 17:22:01 -05001533 } else if (sc->quirks & SIXAXIS_CONTROLLER_BT) {
Antonio Ospite816651a2010-05-03 22:15:55 +02001534 ret = sixaxis_set_operational_bt(hdev);
Frank Praznikc8de9db2014-02-20 11:36:01 -05001535 sc->worker_initialized = 1;
Frank Praznikfee4e2d2014-02-18 17:22:01 -05001536 INIT_WORK(&sc->state_worker, sixaxis_state_worker);
1537 } else if (sc->quirks & DUALSHOCK4_CONTROLLER) {
Frank Praznik68330d82014-02-05 20:03:49 -05001538 if (sc->quirks & DUALSHOCK4_CONTROLLER_BT) {
1539 ret = dualshock4_set_operational_bt(hdev);
1540 if (ret < 0) {
1541 hid_err(hdev, "failed to set the Dualshock 4 operational mode\n");
1542 goto err_stop;
1543 }
1544 }
Frank Praznikad142b92014-02-20 11:36:00 -05001545 /*
1546 * The Dualshock 4 touchpad supports 2 touches and has a
Frank Praznike5606232014-01-27 10:17:37 -05001547 * resolution of 1920x940.
1548 */
1549 ret = sony_register_touchpad(sc, 2, 1920, 940);
1550 if (ret < 0)
1551 goto err_stop;
1552
Frank Praznikc8de9db2014-02-20 11:36:01 -05001553 sc->worker_initialized = 1;
Frank Praznik0bd88dd2014-01-11 15:12:42 -05001554 INIT_WORK(&sc->state_worker, dualshock4_state_worker);
1555 } else {
1556 ret = 0;
1557 }
Bastien Noceraf9ce7c22010-01-20 12:01:53 +00001558
Jiri Kosina4dfdc462008-12-30 00:49:59 +01001559 if (ret < 0)
Jiri Slabybd28ce02008-06-25 23:47:04 +02001560 goto err_stop;
1561
Sven Eckelmann0a286ef2013-11-19 20:26:32 +01001562 if (sc->quirks & SONY_LED_SUPPORT) {
1563 ret = sony_leds_init(hdev);
1564 if (ret < 0)
1565 goto err_stop;
1566 }
1567
Frank Praznikd902f472014-01-27 10:17:36 -05001568 if (sc->quirks & SONY_BATTERY_SUPPORT) {
1569 ret = sony_battery_probe(sc);
1570 if (ret < 0)
1571 goto err_stop;
1572
1573 /* Open the device to receive reports with battery info */
1574 ret = hid_hw_open(hdev);
1575 if (ret < 0) {
1576 hid_err(hdev, "hw open failed\n");
1577 goto err_stop;
1578 }
1579 }
1580
Frank Praznikc8de9db2014-02-20 11:36:01 -05001581 if (sc->quirks & SONY_FF_SUPPORT) {
1582 ret = sony_init_ff(hdev);
1583 if (ret < 0)
1584 goto err_close;
1585 }
Sven Eckelmanna08c22c2013-11-09 19:25:57 +01001586
Jiri Slabybd28ce02008-06-25 23:47:04 +02001587 return 0;
Frank Praznikd902f472014-01-27 10:17:36 -05001588err_close:
1589 hid_hw_close(hdev);
Jiri Slabybd28ce02008-06-25 23:47:04 +02001590err_stop:
Sven Eckelmann0a286ef2013-11-19 20:26:32 +01001591 if (sc->quirks & SONY_LED_SUPPORT)
1592 sony_leds_remove(hdev);
Frank Praznikd902f472014-01-27 10:17:36 -05001593 if (sc->quirks & SONY_BATTERY_SUPPORT)
1594 sony_battery_remove(sc);
Frank Praznikc8de9db2014-02-20 11:36:01 -05001595 if (sc->worker_initialized)
1596 cancel_work_sync(&sc->state_worker);
Jiri Slabybd28ce02008-06-25 23:47:04 +02001597 hid_hw_stop(hdev);
Jiri Slabybd28ce02008-06-25 23:47:04 +02001598 return ret;
1599}
1600
Jiri Kosinacc6e0bb2008-10-23 12:58:38 +02001601static void sony_remove(struct hid_device *hdev)
1602{
Colin Leitnerf04d5142013-05-27 23:41:05 +02001603 struct sony_sc *sc = hid_get_drvdata(hdev);
1604
Sven Eckelmann0a286ef2013-11-19 20:26:32 +01001605 if (sc->quirks & SONY_LED_SUPPORT)
Sven Eckelmannc5382512013-11-19 20:26:30 +01001606 sony_leds_remove(hdev);
Colin Leitnerf04d5142013-05-27 23:41:05 +02001607
Frank Praznikd902f472014-01-27 10:17:36 -05001608 if (sc->quirks & SONY_BATTERY_SUPPORT) {
1609 hid_hw_close(hdev);
1610 sony_battery_remove(sc);
1611 }
1612
Frank Praznikc8de9db2014-02-20 11:36:01 -05001613 if (sc->worker_initialized)
1614 cancel_work_sync(&sc->state_worker);
Sven Eckelmann9f323b62013-11-17 20:38:21 +01001615
Jiri Kosinacc6e0bb2008-10-23 12:58:38 +02001616 hid_hw_stop(hdev);
Jiri Kosinacc6e0bb2008-10-23 12:58:38 +02001617}
1618
Jiri Slabybd28ce02008-06-25 23:47:04 +02001619static const struct hid_device_id sony_devices[] = {
Antonio Ospite816651a2010-05-03 22:15:55 +02001620 { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER),
1621 .driver_data = SIXAXIS_CONTROLLER_USB },
Jiri Kosina35dca5b2011-04-28 15:43:13 +02001622 { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER),
1623 .driver_data = SIXAXIS_CONTROLLER_USB },
Antonio Ospite816651a2010-05-03 22:15:55 +02001624 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER),
1625 .driver_data = SIXAXIS_CONTROLLER_BT },
Jiri Kosinacc6e0bb2008-10-23 12:58:38 +02001626 { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE),
1627 .driver_data = VAIO_RDESC_CONSTANT },
Fernando Luis Vázquez Caoa4649182013-01-15 19:40:48 +09001628 { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGP_MOUSE),
1629 .driver_data = VAIO_RDESC_CONSTANT },
Colin Leitnerf04d5142013-05-27 23:41:05 +02001630 /* Wired Buzz Controller. Reported as Sony Hub from its USB ID and as
1631 * Logitech joystick from the device descriptor. */
1632 { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_BUZZ_CONTROLLER),
1633 .driver_data = BUZZ_CONTROLLER },
1634 { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_WIRELESS_BUZZ_CONTROLLER),
1635 .driver_data = BUZZ_CONTROLLER },
Jiri Kosina078328d2013-06-13 12:03:49 +02001636 /* PS3 BD Remote Control */
1637 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_BDREMOTE),
1638 .driver_data = PS3REMOTE },
1639 /* Logitech Harmony Adapter for PS3 */
1640 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_PS3),
1641 .driver_data = PS3REMOTE },
Frank Praznik0bd88dd2014-01-11 15:12:42 -05001642 /* Sony Dualshock 4 controllers for PS4 */
1643 { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER),
Frank Praznik8ab16762014-01-16 21:42:31 -05001644 .driver_data = DUALSHOCK4_CONTROLLER_USB },
Frank Praznik0bd88dd2014-01-11 15:12:42 -05001645 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER),
Frank Praznik8ab16762014-01-16 21:42:31 -05001646 .driver_data = DUALSHOCK4_CONTROLLER_BT },
Jiri Slabybd28ce02008-06-25 23:47:04 +02001647 { }
1648};
1649MODULE_DEVICE_TABLE(hid, sony_devices);
1650
1651static struct hid_driver sony_driver = {
Colin Leitnerf04d5142013-05-27 23:41:05 +02001652 .name = "sony",
1653 .id_table = sony_devices,
1654 .input_mapping = sony_mapping,
1655 .probe = sony_probe,
1656 .remove = sony_remove,
1657 .report_fixup = sony_report_fixup,
1658 .raw_event = sony_raw_event
Jiri Slabybd28ce02008-06-25 23:47:04 +02001659};
H Hartley Sweetenf4254582012-12-17 15:28:26 -07001660module_hid_driver(sony_driver);
Jiri Slabybd28ce02008-06-25 23:47:04 +02001661
Jiri Slabybd28ce02008-06-25 23:47:04 +02001662MODULE_LICENSE("GPL");