xref: /linux/drivers/hid/hid-sony.c (revision b8f0970d2c5a03f5a431d51af74dd1a0ec62fe91)
1bd28ce00SJiri Slaby /*
2077147a3SFrank Praznik  *  HID driver for Sony / PS2 / PS3 / PS4 BD devices.
3bd28ce00SJiri Slaby  *
4bd28ce00SJiri Slaby  *  Copyright (c) 1999 Andreas Gal
5bd28ce00SJiri Slaby  *  Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz>
6bd28ce00SJiri Slaby  *  Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc
7bd28ce00SJiri Slaby  *  Copyright (c) 2008 Jiri Slaby
8078328daSJiri Kosina  *  Copyright (c) 2012 David Dillow <dave@thedillows.org>
9078328daSJiri Kosina  *  Copyright (c) 2006-2013 Jiri Kosina
10f04d5140SColin Leitner  *  Copyright (c) 2013 Colin Leitner <colin.leitner@gmail.com>
11c4425c8fSFrank Praznik  *  Copyright (c) 2014-2016 Frank Praznik <frank.praznik@gmail.com>
12bd28ce00SJiri Slaby  */
13bd28ce00SJiri Slaby 
14bd28ce00SJiri Slaby /*
15bd28ce00SJiri Slaby  * This program is free software; you can redistribute it and/or modify it
16bd28ce00SJiri Slaby  * under the terms of the GNU General Public License as published by the Free
17bd28ce00SJiri Slaby  * Software Foundation; either version 2 of the License, or (at your option)
18bd28ce00SJiri Slaby  * any later version.
19bd28ce00SJiri Slaby  */
20bd28ce00SJiri Slaby 
21ad142b9eSFrank Praznik /*
22ad142b9eSFrank Praznik  * NOTE: in order for the Sony PS3 BD Remote Control to be found by
23078328daSJiri Kosina  * a Bluetooth host, the key combination Start+Enter has to be kept pressed
24078328daSJiri Kosina  * for about 7 seconds with the Bluetooth Host Controller in discovering mode.
25078328daSJiri Kosina  *
26078328daSJiri Kosina  * There will be no PIN request from the device.
27078328daSJiri Kosina  */
28078328daSJiri Kosina 
29bd28ce00SJiri Slaby #include <linux/device.h>
30bd28ce00SJiri Slaby #include <linux/hid.h>
31bd28ce00SJiri Slaby #include <linux/module.h>
325a0e3ad6STejun Heo #include <linux/slab.h>
3340e32ee6SJiri Kosina #include <linux/leds.h>
34d902f472SFrank Praznik #include <linux/power_supply.h>
35d902f472SFrank Praznik #include <linux/spinlock.h>
36d2d782fcSFrank Praznik #include <linux/list.h>
378025087aSFrank Praznik #include <linux/idr.h>
38e5606230SFrank Praznik #include <linux/input/mt.h>
3949b9ca6cSRoderick Colenbrander #include <linux/crc32.h>
4049b9ca6cSRoderick Colenbrander #include <asm/unaligned.h>
41bd28ce00SJiri Slaby 
42bd28ce00SJiri Slaby #include "hid-ids.h"
43bd28ce00SJiri Slaby 
44f1c458caSSven Eckelmann #define VAIO_RDESC_CONSTANT       BIT(0)
45f1c458caSSven Eckelmann #define SIXAXIS_CONTROLLER_USB    BIT(1)
46f1c458caSSven Eckelmann #define SIXAXIS_CONTROLLER_BT     BIT(2)
47f1c458caSSven Eckelmann #define BUZZ_CONTROLLER           BIT(3)
48f1c458caSSven Eckelmann #define PS3REMOTE                 BIT(4)
498ab1676bSFrank Praznik #define DUALSHOCK4_CONTROLLER_USB BIT(5)
508ab1676bSFrank Praznik #define DUALSHOCK4_CONTROLLER_BT  BIT(6)
5135f436c3SRoderick Colenbrander #define DUALSHOCK4_DONGLE         BIT(7)
5235f436c3SRoderick Colenbrander #define MOTION_CONTROLLER_USB     BIT(8)
5335f436c3SRoderick Colenbrander #define MOTION_CONTROLLER_BT      BIT(9)
5435f436c3SRoderick Colenbrander #define NAVIGATION_CONTROLLER_USB BIT(10)
5535f436c3SRoderick Colenbrander #define NAVIGATION_CONTROLLER_BT  BIT(11)
5635f436c3SRoderick Colenbrander #define SINO_LITE_CONTROLLER      BIT(12)
5735f436c3SRoderick Colenbrander #define FUTUREMAX_DANCE_MAT       BIT(13)
58cc6e0bbbSJiri Kosina 
59fee4e2d5SFrank Praznik #define SIXAXIS_CONTROLLER (SIXAXIS_CONTROLLER_USB | SIXAXIS_CONTROLLER_BT)
60b3bca326SSimon Wood #define MOTION_CONTROLLER (MOTION_CONTROLLER_USB | MOTION_CONTROLLER_BT)
614545ee0aSSimon Wood #define NAVIGATION_CONTROLLER (NAVIGATION_CONTROLLER_USB |\
624545ee0aSSimon Wood 				NAVIGATION_CONTROLLER_BT)
6368330d83SFrank Praznik #define DUALSHOCK4_CONTROLLER (DUALSHOCK4_CONTROLLER_USB |\
6435f436c3SRoderick Colenbrander 				DUALSHOCK4_CONTROLLER_BT | \
6535f436c3SRoderick Colenbrander 				DUALSHOCK4_DONGLE)
66fee4e2d5SFrank Praznik #define SONY_LED_SUPPORT (SIXAXIS_CONTROLLER | BUZZ_CONTROLLER |\
674545ee0aSSimon Wood 				DUALSHOCK4_CONTROLLER | MOTION_CONTROLLER |\
684545ee0aSSimon Wood 				NAVIGATION_CONTROLLER)
6912e9a6d7SSimon Wood #define SONY_BATTERY_SUPPORT (SIXAXIS_CONTROLLER | DUALSHOCK4_CONTROLLER |\
704545ee0aSSimon Wood 				MOTION_CONTROLLER_BT | NAVIGATION_CONTROLLER)
71c5e0c1c4SFrank Praznik #define SONY_FF_SUPPORT (SIXAXIS_CONTROLLER | DUALSHOCK4_CONTROLLER |\
72c5e0c1c4SFrank Praznik 				MOTION_CONTROLLER)
730f398230SFrank Praznik #define SONY_BT_DEVICE (SIXAXIS_CONTROLLER_BT | DUALSHOCK4_CONTROLLER_BT |\
740f398230SFrank Praznik 			MOTION_CONTROLLER_BT | NAVIGATION_CONTROLLER_BT)
7560781cf4SFrank Praznik 
7660781cf4SFrank Praznik #define MAX_LEDS 4
770a286ef2SSven Eckelmann 
78e57a67daSMauro Carvalho Chehab 
79c5e0c1c4SFrank Praznik /* PS/3 Motion controller */
801adf904eSPavel Machek static u8 motion_rdesc[] = {
81c5e0c1c4SFrank Praznik 	0x05, 0x01,         /*  Usage Page (Desktop),               */
82c5e0c1c4SFrank Praznik 	0x09, 0x04,         /*  Usage (Joystick),                   */
83c5e0c1c4SFrank Praznik 	0xA1, 0x01,         /*  Collection (Application),           */
84c5e0c1c4SFrank Praznik 	0xA1, 0x02,         /*      Collection (Logical),           */
85c5e0c1c4SFrank Praznik 	0x85, 0x01,         /*          Report ID (1),              */
86c5e0c1c4SFrank Praznik 	0x75, 0x01,         /*          Report Size (1),            */
878b2513c3SSimon Wood 	0x95, 0x15,         /*          Report Count (21),          */
88c5e0c1c4SFrank Praznik 	0x15, 0x00,         /*          Logical Minimum (0),        */
89c5e0c1c4SFrank Praznik 	0x25, 0x01,         /*          Logical Maximum (1),        */
90c5e0c1c4SFrank Praznik 	0x35, 0x00,         /*          Physical Minimum (0),       */
91c5e0c1c4SFrank Praznik 	0x45, 0x01,         /*          Physical Maximum (1),       */
92c5e0c1c4SFrank Praznik 	0x05, 0x09,         /*          Usage Page (Button),        */
93c5e0c1c4SFrank Praznik 	0x19, 0x01,         /*          Usage Minimum (01h),        */
948b2513c3SSimon Wood 	0x29, 0x15,         /*          Usage Maximum (15h),        */
958b2513c3SSimon Wood 	0x81, 0x02,         /*          Input (Variable),           * Buttons */
968b2513c3SSimon Wood 	0x95, 0x0B,         /*          Report Count (11),          */
97c5e0c1c4SFrank Praznik 	0x06, 0x00, 0xFF,   /*          Usage Page (FF00h),         */
988b2513c3SSimon Wood 	0x81, 0x03,         /*          Input (Constant, Variable), * Padding */
99c5e0c1c4SFrank Praznik 	0x15, 0x00,         /*          Logical Minimum (0),        */
100c5e0c1c4SFrank Praznik 	0x26, 0xFF, 0x00,   /*          Logical Maximum (255),      */
101c5e0c1c4SFrank Praznik 	0x05, 0x01,         /*          Usage Page (Desktop),       */
102c5e0c1c4SFrank Praznik 	0xA1, 0x00,         /*          Collection (Physical),      */
103c5e0c1c4SFrank Praznik 	0x75, 0x08,         /*              Report Size (8),        */
1048b2513c3SSimon Wood 	0x95, 0x01,         /*              Report Count (1),       */
105c5e0c1c4SFrank Praznik 	0x35, 0x00,         /*              Physical Minimum (0),   */
106c5e0c1c4SFrank Praznik 	0x46, 0xFF, 0x00,   /*              Physical Maximum (255), */
107c5e0c1c4SFrank Praznik 	0x09, 0x30,         /*              Usage (X),              */
1088b2513c3SSimon Wood 	0x81, 0x02,         /*              Input (Variable),       * Trigger */
109c5e0c1c4SFrank Praznik 	0xC0,               /*          End Collection,             */
1108b2513c3SSimon Wood 	0x06, 0x00, 0xFF,   /*          Usage Page (FF00h),         */
1118b2513c3SSimon Wood 	0x75, 0x08,         /*          Report Size (8),            */
1128b2513c3SSimon Wood 	0x95, 0x07,         /*          Report Count (7),           * skip 7 bytes */
1138b2513c3SSimon Wood 	0x81, 0x02,         /*          Input (Variable),           */
114c5e0c1c4SFrank Praznik 	0x05, 0x01,         /*          Usage Page (Desktop),       */
115c5e0c1c4SFrank Praznik 	0x75, 0x10,         /*          Report Size (16),           */
1168b2513c3SSimon Wood 	0x46, 0xFF, 0xFF,   /*          Physical Maximum (65535),   */
1178b2513c3SSimon Wood 	0x27, 0xFF, 0xFF, 0x00, 0x00, /*      Logical Maximum (65535),    */
1188b2513c3SSimon Wood 	0x95, 0x03,         /*          Report Count (3),           * 3x Accels */
1198b2513c3SSimon Wood 	0x09, 0x33,         /*              Usage (rX),             */
1208b2513c3SSimon Wood 	0x09, 0x34,         /*              Usage (rY),             */
1218b2513c3SSimon Wood 	0x09, 0x35,         /*              Usage (rZ),             */
122c5e0c1c4SFrank Praznik 	0x81, 0x02,         /*          Input (Variable),           */
1238b2513c3SSimon Wood 	0x06, 0x00, 0xFF,   /*          Usage Page (FF00h),         */
1248b2513c3SSimon Wood 	0x95, 0x03,         /*          Report Count (3),           * Skip Accels 2nd frame */
1258b2513c3SSimon Wood 	0x81, 0x02,         /*          Input (Variable),           */
1268b2513c3SSimon Wood 	0x05, 0x01,         /*          Usage Page (Desktop),       */
1278b2513c3SSimon Wood 	0x09, 0x01,         /*          Usage (Pointer),            */
1288b2513c3SSimon Wood 	0x95, 0x03,         /*          Report Count (3),           * 3x Gyros */
1298b2513c3SSimon Wood 	0x81, 0x02,         /*          Input (Variable),           */
1308b2513c3SSimon Wood 	0x06, 0x00, 0xFF,   /*          Usage Page (FF00h),         */
1318b2513c3SSimon Wood 	0x95, 0x03,         /*          Report Count (3),           * Skip Gyros 2nd frame */
1328b2513c3SSimon Wood 	0x81, 0x02,         /*          Input (Variable),           */
1338b2513c3SSimon Wood 	0x75, 0x0C,         /*          Report Size (12),           */
1348b2513c3SSimon Wood 	0x46, 0xFF, 0x0F,   /*          Physical Maximum (4095),    */
1358b2513c3SSimon Wood 	0x26, 0xFF, 0x0F,   /*          Logical Maximum (4095),     */
1368b2513c3SSimon Wood 	0x95, 0x04,         /*          Report Count (4),           * Skip Temp and Magnetometers */
1378b2513c3SSimon Wood 	0x81, 0x02,         /*          Input (Variable),           */
1388b2513c3SSimon Wood 	0x75, 0x08,         /*          Report Size (8),            */
1398b2513c3SSimon Wood 	0x46, 0xFF, 0x00,   /*          Physical Maximum (255),     */
1408b2513c3SSimon Wood 	0x26, 0xFF, 0x00,   /*          Logical Maximum (255),      */
1418b2513c3SSimon Wood 	0x95, 0x06,         /*          Report Count (6),           * Skip Timestamp and Extension Bytes */
1428b2513c3SSimon Wood 	0x81, 0x02,         /*          Input (Variable),           */
1438b2513c3SSimon Wood 	0x75, 0x08,         /*          Report Size (8),            */
1448b2513c3SSimon Wood 	0x95, 0x30,         /*          Report Count (48),          */
1458b2513c3SSimon Wood 	0x09, 0x01,         /*          Usage (Pointer),            */
1468b2513c3SSimon Wood 	0x91, 0x02,         /*          Output (Variable),          */
1478b2513c3SSimon Wood 	0x75, 0x08,         /*          Report Size (8),            */
1488b2513c3SSimon Wood 	0x95, 0x30,         /*          Report Count (48),          */
1498b2513c3SSimon Wood 	0x09, 0x01,         /*          Usage (Pointer),            */
1508b2513c3SSimon Wood 	0xB1, 0x02,         /*          Feature (Variable),         */
151c5e0c1c4SFrank Praznik 	0xC0,               /*      End Collection,                 */
152c5e0c1c4SFrank Praznik 	0xA1, 0x02,         /*      Collection (Logical),           */
153c5e0c1c4SFrank Praznik 	0x85, 0x02,         /*          Report ID (2),              */
154c5e0c1c4SFrank Praznik 	0x75, 0x08,         /*          Report Size (8),            */
155c5e0c1c4SFrank Praznik 	0x95, 0x30,         /*          Report Count (48),          */
156c5e0c1c4SFrank Praznik 	0x09, 0x01,         /*          Usage (Pointer),            */
157c5e0c1c4SFrank Praznik 	0xB1, 0x02,         /*          Feature (Variable),         */
158c5e0c1c4SFrank Praznik 	0xC0,               /*      End Collection,                 */
159c5e0c1c4SFrank Praznik 	0xA1, 0x02,         /*      Collection (Logical),           */
160c5e0c1c4SFrank Praznik 	0x85, 0xEE,         /*          Report ID (238),            */
161c5e0c1c4SFrank Praznik 	0x75, 0x08,         /*          Report Size (8),            */
162c5e0c1c4SFrank Praznik 	0x95, 0x30,         /*          Report Count (48),          */
163c5e0c1c4SFrank Praznik 	0x09, 0x01,         /*          Usage (Pointer),            */
164c5e0c1c4SFrank Praznik 	0xB1, 0x02,         /*          Feature (Variable),         */
165c5e0c1c4SFrank Praznik 	0xC0,               /*      End Collection,                 */
166c5e0c1c4SFrank Praznik 	0xA1, 0x02,         /*      Collection (Logical),           */
167c5e0c1c4SFrank Praznik 	0x85, 0xEF,         /*          Report ID (239),            */
168c5e0c1c4SFrank Praznik 	0x75, 0x08,         /*          Report Size (8),            */
169c5e0c1c4SFrank Praznik 	0x95, 0x30,         /*          Report Count (48),          */
170c5e0c1c4SFrank Praznik 	0x09, 0x01,         /*          Usage (Pointer),            */
171c5e0c1c4SFrank Praznik 	0xB1, 0x02,         /*          Feature (Variable),         */
172c5e0c1c4SFrank Praznik 	0xC0,               /*      End Collection,                 */
173c5e0c1c4SFrank Praznik 	0xC0                /*  End Collection                      */
174c5e0c1c4SFrank Praznik };
175c5e0c1c4SFrank Praznik 
1761adf904eSPavel Machek static u8 ps3remote_rdesc[] = {
177078328daSJiri Kosina 	0x05, 0x01,          /* GUsagePage Generic Desktop */
178078328daSJiri Kosina 	0x09, 0x05,          /* LUsage 0x05 [Game Pad] */
179078328daSJiri Kosina 	0xA1, 0x01,          /* MCollection Application (mouse, keyboard) */
180078328daSJiri Kosina 
181078328daSJiri Kosina 	 /* Use collection 1 for joypad buttons */
182078328daSJiri Kosina 	 0xA1, 0x02,         /* MCollection Logical (interrelated data) */
183078328daSJiri Kosina 
184ef916ef5SAntonio Ospite 	  /*
185ef916ef5SAntonio Ospite 	   * Ignore the 1st byte, maybe it is used for a controller
186ef916ef5SAntonio Ospite 	   * number but it's not needed for correct operation
187ef916ef5SAntonio Ospite 	   */
188078328daSJiri Kosina 	  0x75, 0x08,        /* GReportSize 0x08 [8] */
189078328daSJiri Kosina 	  0x95, 0x01,        /* GReportCount 0x01 [1] */
190078328daSJiri Kosina 	  0x81, 0x01,        /* MInput 0x01 (Const[0] Arr[1] Abs[2]) */
191078328daSJiri Kosina 
192ef916ef5SAntonio Ospite 	  /*
193ef916ef5SAntonio Ospite 	   * Bytes from 2nd to 4th are a bitmap for joypad buttons, for these
194ef916ef5SAntonio Ospite 	   * buttons multiple keypresses are allowed
195ef916ef5SAntonio Ospite 	   */
196078328daSJiri Kosina 	  0x05, 0x09,        /* GUsagePage Button */
197078328daSJiri Kosina 	  0x19, 0x01,        /* LUsageMinimum 0x01 [Button 1 (primary/trigger)] */
198078328daSJiri Kosina 	  0x29, 0x18,        /* LUsageMaximum 0x18 [Button 24] */
199078328daSJiri Kosina 	  0x14,              /* GLogicalMinimum [0] */
200078328daSJiri Kosina 	  0x25, 0x01,        /* GLogicalMaximum 0x01 [1] */
201078328daSJiri Kosina 	  0x75, 0x01,        /* GReportSize 0x01 [1] */
202078328daSJiri Kosina 	  0x95, 0x18,        /* GReportCount 0x18 [24] */
203078328daSJiri Kosina 	  0x81, 0x02,        /* MInput 0x02 (Data[0] Var[1] Abs[2]) */
204078328daSJiri Kosina 
205078328daSJiri Kosina 	  0xC0,              /* MEndCollection */
206078328daSJiri Kosina 
207078328daSJiri Kosina 	 /* Use collection 2 for remote control buttons */
208078328daSJiri Kosina 	 0xA1, 0x02,         /* MCollection Logical (interrelated data) */
209078328daSJiri Kosina 
210078328daSJiri Kosina 	  /* 5th byte is used for remote control buttons */
211078328daSJiri Kosina 	  0x05, 0x09,        /* GUsagePage Button */
212078328daSJiri Kosina 	  0x18,              /* LUsageMinimum [No button pressed] */
213078328daSJiri Kosina 	  0x29, 0xFE,        /* LUsageMaximum 0xFE [Button 254] */
214078328daSJiri Kosina 	  0x14,              /* GLogicalMinimum [0] */
215078328daSJiri Kosina 	  0x26, 0xFE, 0x00,  /* GLogicalMaximum 0x00FE [254] */
216078328daSJiri Kosina 	  0x75, 0x08,        /* GReportSize 0x08 [8] */
217078328daSJiri Kosina 	  0x95, 0x01,        /* GReportCount 0x01 [1] */
218078328daSJiri Kosina 	  0x80,              /* MInput  */
219078328daSJiri Kosina 
220ef916ef5SAntonio Ospite 	  /*
221ef916ef5SAntonio Ospite 	   * Ignore bytes from 6th to 11th, 6th to 10th are always constant at
222ef916ef5SAntonio Ospite 	   * 0xff and 11th is for press indication
223ef916ef5SAntonio Ospite 	   */
224078328daSJiri Kosina 	  0x75, 0x08,        /* GReportSize 0x08 [8] */
225078328daSJiri Kosina 	  0x95, 0x06,        /* GReportCount 0x06 [6] */
226078328daSJiri Kosina 	  0x81, 0x01,        /* MInput 0x01 (Const[0] Arr[1] Abs[2]) */
227078328daSJiri Kosina 
228078328daSJiri Kosina 	  /* 12th byte is for battery strength */
229078328daSJiri Kosina 	  0x05, 0x06,        /* GUsagePage Generic Device Controls */
230078328daSJiri Kosina 	  0x09, 0x20,        /* LUsage 0x20 [Battery Strength] */
231078328daSJiri Kosina 	  0x14,              /* GLogicalMinimum [0] */
232078328daSJiri Kosina 	  0x25, 0x05,        /* GLogicalMaximum 0x05 [5] */
233078328daSJiri Kosina 	  0x75, 0x08,        /* GReportSize 0x08 [8] */
234078328daSJiri Kosina 	  0x95, 0x01,        /* GReportCount 0x01 [1] */
235078328daSJiri Kosina 	  0x81, 0x02,        /* MInput 0x02 (Data[0] Var[1] Abs[2]) */
236078328daSJiri Kosina 
237078328daSJiri Kosina 	  0xC0,              /* MEndCollection */
238078328daSJiri Kosina 
239078328daSJiri Kosina 	 0xC0                /* MEndCollection [Game Pad] */
240078328daSJiri Kosina };
241078328daSJiri Kosina 
242078328daSJiri Kosina static const unsigned int ps3remote_keymap_joypad_buttons[] = {
243078328daSJiri Kosina 	[0x01] = KEY_SELECT,
244078328daSJiri Kosina 	[0x02] = BTN_THUMBL,		/* L3 */
245078328daSJiri Kosina 	[0x03] = BTN_THUMBR,		/* R3 */
246078328daSJiri Kosina 	[0x04] = BTN_START,
247078328daSJiri Kosina 	[0x05] = KEY_UP,
248078328daSJiri Kosina 	[0x06] = KEY_RIGHT,
249078328daSJiri Kosina 	[0x07] = KEY_DOWN,
250078328daSJiri Kosina 	[0x08] = KEY_LEFT,
251078328daSJiri Kosina 	[0x09] = BTN_TL2,		/* L2 */
252078328daSJiri Kosina 	[0x0a] = BTN_TR2,		/* R2 */
253078328daSJiri Kosina 	[0x0b] = BTN_TL,		/* L1 */
254078328daSJiri Kosina 	[0x0c] = BTN_TR,		/* R1 */
255078328daSJiri Kosina 	[0x0d] = KEY_OPTION,		/* options/triangle */
256078328daSJiri Kosina 	[0x0e] = KEY_BACK,		/* back/circle */
257078328daSJiri Kosina 	[0x0f] = BTN_0,			/* cross */
258078328daSJiri Kosina 	[0x10] = KEY_SCREEN,		/* view/square */
259078328daSJiri Kosina 	[0x11] = KEY_HOMEPAGE,		/* PS button */
260078328daSJiri Kosina 	[0x14] = KEY_ENTER,
261078328daSJiri Kosina };
262078328daSJiri Kosina static const unsigned int ps3remote_keymap_remote_buttons[] = {
263078328daSJiri Kosina 	[0x00] = KEY_1,
264078328daSJiri Kosina 	[0x01] = KEY_2,
265078328daSJiri Kosina 	[0x02] = KEY_3,
266078328daSJiri Kosina 	[0x03] = KEY_4,
267078328daSJiri Kosina 	[0x04] = KEY_5,
268078328daSJiri Kosina 	[0x05] = KEY_6,
269078328daSJiri Kosina 	[0x06] = KEY_7,
270078328daSJiri Kosina 	[0x07] = KEY_8,
271078328daSJiri Kosina 	[0x08] = KEY_9,
272078328daSJiri Kosina 	[0x09] = KEY_0,
273078328daSJiri Kosina 	[0x0e] = KEY_ESC,		/* return */
274078328daSJiri Kosina 	[0x0f] = KEY_CLEAR,
275078328daSJiri Kosina 	[0x16] = KEY_EJECTCD,
276078328daSJiri Kosina 	[0x1a] = KEY_MENU,		/* top menu */
277078328daSJiri Kosina 	[0x28] = KEY_TIME,
278078328daSJiri Kosina 	[0x30] = KEY_PREVIOUS,
279078328daSJiri Kosina 	[0x31] = KEY_NEXT,
280078328daSJiri Kosina 	[0x32] = KEY_PLAY,
281078328daSJiri Kosina 	[0x33] = KEY_REWIND,		/* scan back */
282078328daSJiri Kosina 	[0x34] = KEY_FORWARD,		/* scan forward */
283078328daSJiri Kosina 	[0x38] = KEY_STOP,
284078328daSJiri Kosina 	[0x39] = KEY_PAUSE,
285078328daSJiri Kosina 	[0x40] = KEY_CONTEXT_MENU,	/* pop up/menu */
286078328daSJiri Kosina 	[0x60] = KEY_FRAMEBACK,		/* slow/step back */
287078328daSJiri Kosina 	[0x61] = KEY_FRAMEFORWARD,	/* slow/step forward */
288078328daSJiri Kosina 	[0x63] = KEY_SUBTITLE,
289078328daSJiri Kosina 	[0x64] = KEY_AUDIO,
290078328daSJiri Kosina 	[0x65] = KEY_ANGLE,
291078328daSJiri Kosina 	[0x70] = KEY_INFO,		/* display */
292078328daSJiri Kosina 	[0x80] = KEY_BLUE,
293078328daSJiri Kosina 	[0x81] = KEY_RED,
294078328daSJiri Kosina 	[0x82] = KEY_GREEN,
295078328daSJiri Kosina 	[0x83] = KEY_YELLOW,
296078328daSJiri Kosina };
297078328daSJiri Kosina 
298f04d5140SColin Leitner static const unsigned int buzz_keymap[] = {
299ad142b9eSFrank Praznik 	/*
300ad142b9eSFrank Praznik 	 * The controller has 4 remote buzzers, each with one LED and 5
301f04d5140SColin Leitner 	 * buttons.
302f04d5140SColin Leitner 	 *
303f04d5140SColin Leitner 	 * We use the mapping chosen by the controller, which is:
304f04d5140SColin Leitner 	 *
305f04d5140SColin Leitner 	 * Key          Offset
306f04d5140SColin Leitner 	 * -------------------
307f04d5140SColin Leitner 	 * Buzz              1
308f04d5140SColin Leitner 	 * Blue              5
309f04d5140SColin Leitner 	 * Orange            4
310f04d5140SColin Leitner 	 * Green             3
311f04d5140SColin Leitner 	 * Yellow            2
312f04d5140SColin Leitner 	 *
313f04d5140SColin Leitner 	 * So, for example, the orange button on the third buzzer is mapped to
314f04d5140SColin Leitner 	 * BTN_TRIGGER_HAPPY14
315f04d5140SColin Leitner 	 */
316f04d5140SColin Leitner 	 [1] = BTN_TRIGGER_HAPPY1,
317f04d5140SColin Leitner 	 [2] = BTN_TRIGGER_HAPPY2,
318f04d5140SColin Leitner 	 [3] = BTN_TRIGGER_HAPPY3,
319f04d5140SColin Leitner 	 [4] = BTN_TRIGGER_HAPPY4,
320f04d5140SColin Leitner 	 [5] = BTN_TRIGGER_HAPPY5,
321f04d5140SColin Leitner 	 [6] = BTN_TRIGGER_HAPPY6,
322f04d5140SColin Leitner 	 [7] = BTN_TRIGGER_HAPPY7,
323f04d5140SColin Leitner 	 [8] = BTN_TRIGGER_HAPPY8,
324f04d5140SColin Leitner 	 [9] = BTN_TRIGGER_HAPPY9,
325f04d5140SColin Leitner 	[10] = BTN_TRIGGER_HAPPY10,
326f04d5140SColin Leitner 	[11] = BTN_TRIGGER_HAPPY11,
327f04d5140SColin Leitner 	[12] = BTN_TRIGGER_HAPPY12,
328f04d5140SColin Leitner 	[13] = BTN_TRIGGER_HAPPY13,
329f04d5140SColin Leitner 	[14] = BTN_TRIGGER_HAPPY14,
330f04d5140SColin Leitner 	[15] = BTN_TRIGGER_HAPPY15,
331f04d5140SColin Leitner 	[16] = BTN_TRIGGER_HAPPY16,
332f04d5140SColin Leitner 	[17] = BTN_TRIGGER_HAPPY17,
333f04d5140SColin Leitner 	[18] = BTN_TRIGGER_HAPPY18,
334f04d5140SColin Leitner 	[19] = BTN_TRIGGER_HAPPY19,
335f04d5140SColin Leitner 	[20] = BTN_TRIGGER_HAPPY20,
336f04d5140SColin Leitner };
337f04d5140SColin Leitner 
338*b8f0970dSRoderick Colenbrander /* The Navigation controller is a partial DS3 and uses the same HID report
339*b8f0970dSRoderick Colenbrander  * and hence the same keymap indices, however not not all axes/buttons
340*b8f0970dSRoderick Colenbrander  * are physically present. We use the same axis and button mapping as
341*b8f0970dSRoderick Colenbrander  * the DS3, which uses the Linux gamepad spec.
342*b8f0970dSRoderick Colenbrander  */
343*b8f0970dSRoderick Colenbrander static const unsigned int navigation_absmap[] = {
344*b8f0970dSRoderick Colenbrander 	[0x30] = ABS_X,
345*b8f0970dSRoderick Colenbrander 	[0x31] = ABS_Y,
346*b8f0970dSRoderick Colenbrander 	[0x33] = ABS_Z, /* L2 */
347*b8f0970dSRoderick Colenbrander };
348*b8f0970dSRoderick Colenbrander 
349*b8f0970dSRoderick Colenbrander /* Buttons not physically available on the device, but still available
350*b8f0970dSRoderick Colenbrander  * in the reports are explicitly set to 0 for documentation purposes.
351*b8f0970dSRoderick Colenbrander  */
352*b8f0970dSRoderick Colenbrander static const unsigned int navigation_keymap[] = {
353*b8f0970dSRoderick Colenbrander 	[0x01] = 0, /* Select */
354*b8f0970dSRoderick Colenbrander 	[0x02] = BTN_THUMBL, /* L3 */
355*b8f0970dSRoderick Colenbrander 	[0x03] = 0, /* R3 */
356*b8f0970dSRoderick Colenbrander 	[0x04] = 0, /* Start */
357*b8f0970dSRoderick Colenbrander 	[0x05] = BTN_DPAD_UP, /* Up */
358*b8f0970dSRoderick Colenbrander 	[0x06] = BTN_DPAD_RIGHT, /* Right */
359*b8f0970dSRoderick Colenbrander 	[0x07] = BTN_DPAD_DOWN, /* Down */
360*b8f0970dSRoderick Colenbrander 	[0x08] = BTN_DPAD_LEFT, /* Left */
361*b8f0970dSRoderick Colenbrander 	[0x09] = BTN_TL2, /* L2 */
362*b8f0970dSRoderick Colenbrander 	[0x0a] = 0, /* R2 */
363*b8f0970dSRoderick Colenbrander 	[0x0b] = BTN_TL, /* L1 */
364*b8f0970dSRoderick Colenbrander 	[0x0c] = 0, /* R1 */
365*b8f0970dSRoderick Colenbrander 	[0x0d] = BTN_NORTH, /* Triangle */
366*b8f0970dSRoderick Colenbrander 	[0x0e] = BTN_EAST, /* Circle */
367*b8f0970dSRoderick Colenbrander 	[0x0f] = BTN_SOUTH, /* Cross */
368*b8f0970dSRoderick Colenbrander 	[0x10] = BTN_WEST, /* Square */
369*b8f0970dSRoderick Colenbrander 	[0x11] = BTN_MODE, /* PS */
370*b8f0970dSRoderick Colenbrander };
371*b8f0970dSRoderick Colenbrander 
372e19a267bSRoderick Colenbrander static const unsigned int sixaxis_absmap[] = {
373e19a267bSRoderick Colenbrander 	[0x30] = ABS_X,
374e19a267bSRoderick Colenbrander 	[0x31] = ABS_Y,
375e19a267bSRoderick Colenbrander 	[0x32] = ABS_RX, /* right stick X */
376e19a267bSRoderick Colenbrander 	[0x35] = ABS_RY, /* right stick Y */
377e19a267bSRoderick Colenbrander };
378e19a267bSRoderick Colenbrander 
379e19a267bSRoderick Colenbrander static const unsigned int sixaxis_keymap[] = {
380e19a267bSRoderick Colenbrander 	[0x01] = BTN_SELECT, /* Select */
381e19a267bSRoderick Colenbrander 	[0x02] = BTN_THUMBL, /* L3 */
382e19a267bSRoderick Colenbrander 	[0x03] = BTN_THUMBR, /* R3 */
383e19a267bSRoderick Colenbrander 	[0x04] = BTN_START, /* Start */
384e19a267bSRoderick Colenbrander 	[0x05] = BTN_DPAD_UP, /* Up */
385e19a267bSRoderick Colenbrander 	[0x06] = BTN_DPAD_RIGHT, /* Right */
386e19a267bSRoderick Colenbrander 	[0x07] = BTN_DPAD_DOWN, /* Down */
387e19a267bSRoderick Colenbrander 	[0x08] = BTN_DPAD_LEFT, /* Left */
388e19a267bSRoderick Colenbrander 	[0x09] = BTN_TL2, /* L2 */
389e19a267bSRoderick Colenbrander 	[0x0a] = BTN_TR2, /* R2 */
390e19a267bSRoderick Colenbrander 	[0x0b] = BTN_TL, /* L1 */
391e19a267bSRoderick Colenbrander 	[0x0c] = BTN_TR, /* R1 */
392e19a267bSRoderick Colenbrander 	[0x0d] = BTN_NORTH, /* Triangle */
393e19a267bSRoderick Colenbrander 	[0x0e] = BTN_EAST, /* Circle */
394e19a267bSRoderick Colenbrander 	[0x0f] = BTN_SOUTH, /* Cross */
395e19a267bSRoderick Colenbrander 	[0x10] = BTN_WEST, /* Square */
396e19a267bSRoderick Colenbrander 	[0x11] = BTN_MODE, /* PS */
397e19a267bSRoderick Colenbrander };
398e19a267bSRoderick Colenbrander 
3999131f8ccSRoderick Colenbrander static const unsigned int ds4_absmap[] = {
4009131f8ccSRoderick Colenbrander 	[0x30] = ABS_X,
4019131f8ccSRoderick Colenbrander 	[0x31] = ABS_Y,
4029131f8ccSRoderick Colenbrander 	[0x32] = ABS_RX, /* right stick X */
4039131f8ccSRoderick Colenbrander 	[0x33] = ABS_Z, /* L2 */
4049131f8ccSRoderick Colenbrander 	[0x34] = ABS_RZ, /* R2 */
4059131f8ccSRoderick Colenbrander 	[0x35] = ABS_RY, /* right stick Y */
4069131f8ccSRoderick Colenbrander };
4079131f8ccSRoderick Colenbrander 
4089131f8ccSRoderick Colenbrander static const unsigned int ds4_keymap[] = {
4099131f8ccSRoderick Colenbrander 	[0x1] = BTN_WEST, /* Square */
4109131f8ccSRoderick Colenbrander 	[0x2] = BTN_SOUTH, /* Cross */
4119131f8ccSRoderick Colenbrander 	[0x3] = BTN_EAST, /* Circle */
4129131f8ccSRoderick Colenbrander 	[0x4] = BTN_NORTH, /* Triangle */
4139131f8ccSRoderick Colenbrander 	[0x5] = BTN_TL, /* L1 */
4149131f8ccSRoderick Colenbrander 	[0x6] = BTN_TR, /* R1 */
4159131f8ccSRoderick Colenbrander 	[0x7] = BTN_TL2, /* L2 */
4169131f8ccSRoderick Colenbrander 	[0x8] = BTN_TR2, /* R2 */
4179131f8ccSRoderick Colenbrander 	[0x9] = BTN_SELECT, /* Share */
4189131f8ccSRoderick Colenbrander 	[0xa] = BTN_START, /* Options */
4199131f8ccSRoderick Colenbrander 	[0xb] = BTN_THUMBL, /* L3 */
4209131f8ccSRoderick Colenbrander 	[0xc] = BTN_THUMBR, /* R3 */
4219131f8ccSRoderick Colenbrander 	[0xd] = BTN_MODE, /* PS */
4229131f8ccSRoderick Colenbrander };
4239131f8ccSRoderick Colenbrander 
424d03ae2e1SRoderick Colenbrander static const struct {int x; int y; } ds4_hat_mapping[] = {
425d03ae2e1SRoderick Colenbrander 	{0, -1}, {1, -1}, {1, 0}, {1, 1}, {0, 1}, {-1, 1}, {-1, 0}, {-1, -1},
426d03ae2e1SRoderick Colenbrander 	{0, 0}
427d03ae2e1SRoderick Colenbrander };
4289131f8ccSRoderick Colenbrander 
429d902f472SFrank Praznik static enum power_supply_property sony_battery_props[] = {
430d902f472SFrank Praznik 	POWER_SUPPLY_PROP_PRESENT,
431d902f472SFrank Praznik 	POWER_SUPPLY_PROP_CAPACITY,
432d902f472SFrank Praznik 	POWER_SUPPLY_PROP_SCOPE,
433d902f472SFrank Praznik 	POWER_SUPPLY_PROP_STATUS,
434d902f472SFrank Praznik };
435d902f472SFrank Praznik 
43655d3b664SFrank Praznik struct sixaxis_led {
4371adf904eSPavel Machek 	u8 time_enabled; /* the total time the led is active (0xff means forever) */
4381adf904eSPavel Machek 	u8 duty_length;  /* how long a cycle is in deciseconds (0 means "really fast") */
4391adf904eSPavel Machek 	u8 enabled;
4401adf904eSPavel Machek 	u8 duty_off; /* % of duty_length the led is off (0xff means 100%) */
4411adf904eSPavel Machek 	u8 duty_on;  /* % of duty_length the led is on (0xff mean 100%) */
44255d3b664SFrank Praznik } __packed;
44355d3b664SFrank Praznik 
44455d3b664SFrank Praznik struct sixaxis_rumble {
4451adf904eSPavel Machek 	u8 padding;
4461adf904eSPavel Machek 	u8 right_duration; /* Right motor duration (0xff means forever) */
4471adf904eSPavel Machek 	u8 right_motor_on; /* Right (small) motor on/off, only supports values of 0 or 1 (off/on) */
4481adf904eSPavel Machek 	u8 left_duration;    /* Left motor duration (0xff means forever) */
4491adf904eSPavel Machek 	u8 left_motor_force; /* left (large) motor, supports force values from 0 to 255 */
45055d3b664SFrank Praznik } __packed;
45155d3b664SFrank Praznik 
45255d3b664SFrank Praznik struct sixaxis_output_report {
4531adf904eSPavel Machek 	u8 report_id;
45455d3b664SFrank Praznik 	struct sixaxis_rumble rumble;
4551adf904eSPavel Machek 	u8 padding[4];
4561adf904eSPavel Machek 	u8 leds_bitmap; /* bitmap of enabled LEDs: LED_1 = 0x02, LED_2 = 0x04, ... */
45755d3b664SFrank Praznik 	struct sixaxis_led led[4];    /* LEDx at (4 - x) */
45855d3b664SFrank Praznik 	struct sixaxis_led _reserved; /* LED5, not actually soldered */
45955d3b664SFrank Praznik } __packed;
46055d3b664SFrank Praznik 
46155d3b664SFrank Praznik union sixaxis_output_report_01 {
46255d3b664SFrank Praznik 	struct sixaxis_output_report data;
4631adf904eSPavel Machek 	u8 buf[36];
46455d3b664SFrank Praznik };
46555d3b664SFrank Praznik 
466c5e0c1c4SFrank Praznik struct motion_output_report_02 {
467c5e0c1c4SFrank Praznik 	u8 type, zero;
468c5e0c1c4SFrank Praznik 	u8 r, g, b;
469c5e0c1c4SFrank Praznik 	u8 zero2;
470c5e0c1c4SFrank Praznik 	u8 rumble;
471c5e0c1c4SFrank Praznik };
472c5e0c1c4SFrank Praznik 
4732c159de0SRoderick Colenbrander #define DS4_FEATURE_REPORT_0x02_SIZE 37
47455a07d62SRoderick Colenbrander #define DS4_FEATURE_REPORT_0x05_SIZE 41
4752c159de0SRoderick Colenbrander #define DS4_FEATURE_REPORT_0x81_SIZE 7
47649b9ca6cSRoderick Colenbrander #define DS4_INPUT_REPORT_0x11_SIZE 78
4772c159de0SRoderick Colenbrander #define DS4_OUTPUT_REPORT_0x05_SIZE 32
4782c159de0SRoderick Colenbrander #define DS4_OUTPUT_REPORT_0x11_SIZE 78
47929b691a8SAntonio Ospite #define SIXAXIS_REPORT_0xF2_SIZE 17
480a85d67b5SAntonio Ospite #define SIXAXIS_REPORT_0xF5_SIZE 8
48141d2d425SSimon Wood #define MOTION_REPORT_0x02_SIZE 49
4829b2b5c9aSFrank Praznik 
483cdc1c021SRoderick Colenbrander /* Offsets relative to USB input report (0x1). Bluetooth (0x11) requires an
484cdc1c021SRoderick Colenbrander  * additional +2.
485cdc1c021SRoderick Colenbrander  */
486d03ae2e1SRoderick Colenbrander #define DS4_INPUT_REPORT_AXIS_OFFSET      1
487ac797b95SRoderick Colenbrander #define DS4_INPUT_REPORT_BUTTON_OFFSET    5
48880786eb9SRoderick Colenbrander #define DS4_INPUT_REPORT_TIMESTAMP_OFFSET 10
489227c011bSRoderick Colenbrander #define DS4_INPUT_REPORT_GYRO_X_OFFSET   13
490cdc1c021SRoderick Colenbrander #define DS4_INPUT_REPORT_BATTERY_OFFSET  30
491cdc1c021SRoderick Colenbrander #define DS4_INPUT_REPORT_TOUCHPAD_OFFSET 33
492cdc1c021SRoderick Colenbrander 
493510c8b7cSRoderick Colenbrander #define SENSOR_SUFFIX " Motion Sensors"
494ac797b95SRoderick Colenbrander #define DS4_TOUCHPAD_SUFFIX " Touchpad"
495ac797b95SRoderick Colenbrander 
49655a07d62SRoderick Colenbrander #define DS4_GYRO_RES_PER_DEG_S 1024
49755a07d62SRoderick Colenbrander #define DS4_ACC_RES_PER_G      8192
49855a07d62SRoderick Colenbrander 
499510c8b7cSRoderick Colenbrander #define SIXAXIS_INPUT_REPORT_ACC_X_OFFSET 41
500510c8b7cSRoderick Colenbrander #define SIXAXIS_ACC_RES_PER_G 113
501510c8b7cSRoderick Colenbrander 
5028b402c92SJiri Kosina static DEFINE_SPINLOCK(sony_dev_list_lock);
503d2d782fcSFrank Praznik static LIST_HEAD(sony_device_list);
5048025087aSFrank Praznik static DEFINE_IDA(sony_device_id_allocator);
505d2d782fcSFrank Praznik 
50655a07d62SRoderick Colenbrander /* Used for calibration of DS4 accelerometer and gyro. */
50755a07d62SRoderick Colenbrander struct ds4_calibration_data {
50855a07d62SRoderick Colenbrander 	int abs_code;
50955a07d62SRoderick Colenbrander 	short bias;
51055a07d62SRoderick Colenbrander 	/* Calibration requires scaling against a sensitivity value, which is a
51155a07d62SRoderick Colenbrander 	 * float. Store sensitivity as a fraction to limit floating point
51255a07d62SRoderick Colenbrander 	 * calculations until final calibration.
51355a07d62SRoderick Colenbrander 	 */
51455a07d62SRoderick Colenbrander 	int sens_numer;
51555a07d62SRoderick Colenbrander 	int sens_denom;
51655a07d62SRoderick Colenbrander };
51755a07d62SRoderick Colenbrander 
518f2f47c38SRoderick Colenbrander enum ds4_dongle_state {
519f2f47c38SRoderick Colenbrander 	DONGLE_DISCONNECTED,
520f2f47c38SRoderick Colenbrander 	DONGLE_CALIBRATING,
521f2f47c38SRoderick Colenbrander 	DONGLE_CONNECTED,
522f2f47c38SRoderick Colenbrander 	DONGLE_DISABLED
523f2f47c38SRoderick Colenbrander };
524f2f47c38SRoderick Colenbrander 
525b5322736SRoderick Colenbrander enum sony_worker {
526f2f47c38SRoderick Colenbrander 	SONY_WORKER_STATE,
527f2f47c38SRoderick Colenbrander 	SONY_WORKER_HOTPLUG
528b5322736SRoderick Colenbrander };
529b5322736SRoderick Colenbrander 
530cc6e0bbbSJiri Kosina struct sony_sc {
531d902f472SFrank Praznik 	spinlock_t lock;
532d2d782fcSFrank Praznik 	struct list_head list_node;
5330a286ef2SSven Eckelmann 	struct hid_device *hdev;
534ac797b95SRoderick Colenbrander 	struct input_dev *touchpad;
535227c011bSRoderick Colenbrander 	struct input_dev *sensor_dev;
53660781cf4SFrank Praznik 	struct led_classdev *leds[MAX_LEDS];
537cc6e0bbbSJiri Kosina 	unsigned long quirks;
538f2f47c38SRoderick Colenbrander 	struct work_struct hotplug_worker;
5390a286ef2SSven Eckelmann 	struct work_struct state_worker;
540d8aaccdaSFrank Praznik 	void (*send_output_report)(struct sony_sc *);
541297d716fSKrzysztof Kozlowski 	struct power_supply *battery;
542297d716fSKrzysztof Kozlowski 	struct power_supply_desc battery_desc;
5438025087aSFrank Praznik 	int device_id;
5441adf904eSPavel Machek 	u8 *output_report_dmabuf;
545f04d5140SColin Leitner 
5469f323b68SSven Eckelmann #ifdef CONFIG_SONY_FF
5471adf904eSPavel Machek 	u8 left;
5481adf904eSPavel Machek 	u8 right;
5499f323b68SSven Eckelmann #endif
5509f323b68SSven Eckelmann 
5511adf904eSPavel Machek 	u8 mac_address[6];
552f2f47c38SRoderick Colenbrander 	u8 hotplug_worker_initialized;
553b5322736SRoderick Colenbrander 	u8 state_worker_initialized;
5542a242932SFrank Praznik 	u8 defer_initialization;
5551adf904eSPavel Machek 	u8 cable_state;
5561adf904eSPavel Machek 	u8 battery_charging;
5571adf904eSPavel Machek 	u8 battery_capacity;
5581adf904eSPavel Machek 	u8 led_state[MAX_LEDS];
5591adf904eSPavel Machek 	u8 led_delay_on[MAX_LEDS];
5601adf904eSPavel Machek 	u8 led_delay_off[MAX_LEDS];
5611adf904eSPavel Machek 	u8 led_count;
56280786eb9SRoderick Colenbrander 
56380786eb9SRoderick Colenbrander 	bool timestamp_initialized;
56480786eb9SRoderick Colenbrander 	u16 prev_timestamp;
56580786eb9SRoderick Colenbrander 	unsigned int timestamp_us;
56680786eb9SRoderick Colenbrander 
567f2f47c38SRoderick Colenbrander 	enum ds4_dongle_state ds4_dongle_state;
56855a07d62SRoderick Colenbrander 	/* DS4 calibration data */
56955a07d62SRoderick Colenbrander 	struct ds4_calibration_data ds4_calib_data[6];
570cc6e0bbbSJiri Kosina };
571cc6e0bbbSJiri Kosina 
572405182c2SRoderick Colenbrander static void sony_set_leds(struct sony_sc *sc);
573405182c2SRoderick Colenbrander 
574b5322736SRoderick Colenbrander static inline void sony_schedule_work(struct sony_sc *sc,
575b5322736SRoderick Colenbrander 				      enum sony_worker which)
5762a242932SFrank Praznik {
577b5322736SRoderick Colenbrander 	switch (which) {
578b5322736SRoderick Colenbrander 	case SONY_WORKER_STATE:
5792a242932SFrank Praznik 		if (!sc->defer_initialization)
5802a242932SFrank Praznik 			schedule_work(&sc->state_worker);
581f2f47c38SRoderick Colenbrander 		break;
582f2f47c38SRoderick Colenbrander 	case SONY_WORKER_HOTPLUG:
583f2f47c38SRoderick Colenbrander 		if (sc->hotplug_worker_initialized)
584f2f47c38SRoderick Colenbrander 			schedule_work(&sc->hotplug_worker);
585f2f47c38SRoderick Colenbrander 		break;
5862a242932SFrank Praznik 	}
587b5322736SRoderick Colenbrander }
5882a242932SFrank Praznik 
589c5e0c1c4SFrank Praznik static u8 *motion_fixup(struct hid_device *hdev, u8 *rdesc,
590c5e0c1c4SFrank Praznik 			     unsigned int *rsize)
591c5e0c1c4SFrank Praznik {
592c5e0c1c4SFrank Praznik 	*rsize = sizeof(motion_rdesc);
593c5e0c1c4SFrank Praznik 	return motion_rdesc;
594c5e0c1c4SFrank Praznik }
595c5e0c1c4SFrank Praznik 
5961adf904eSPavel Machek static u8 *ps3remote_fixup(struct hid_device *hdev, u8 *rdesc,
597078328daSJiri Kosina 			     unsigned int *rsize)
598078328daSJiri Kosina {
599078328daSJiri Kosina 	*rsize = sizeof(ps3remote_rdesc);
600078328daSJiri Kosina 	return ps3remote_rdesc;
601078328daSJiri Kosina }
602078328daSJiri Kosina 
603078328daSJiri Kosina static int ps3remote_mapping(struct hid_device *hdev, struct hid_input *hi,
604078328daSJiri Kosina 			     struct hid_field *field, struct hid_usage *usage,
605078328daSJiri Kosina 			     unsigned long **bit, int *max)
606078328daSJiri Kosina {
607078328daSJiri Kosina 	unsigned int key = usage->hid & HID_USAGE;
608078328daSJiri Kosina 
609078328daSJiri Kosina 	if ((usage->hid & HID_USAGE_PAGE) != HID_UP_BUTTON)
610078328daSJiri Kosina 		return -1;
611078328daSJiri Kosina 
612078328daSJiri Kosina 	switch (usage->collection_index) {
613078328daSJiri Kosina 	case 1:
614078328daSJiri Kosina 		if (key >= ARRAY_SIZE(ps3remote_keymap_joypad_buttons))
615078328daSJiri Kosina 			return -1;
616078328daSJiri Kosina 
617078328daSJiri Kosina 		key = ps3remote_keymap_joypad_buttons[key];
618078328daSJiri Kosina 		if (!key)
619078328daSJiri Kosina 			return -1;
620078328daSJiri Kosina 		break;
621078328daSJiri Kosina 	case 2:
622078328daSJiri Kosina 		if (key >= ARRAY_SIZE(ps3remote_keymap_remote_buttons))
623078328daSJiri Kosina 			return -1;
624078328daSJiri Kosina 
625078328daSJiri Kosina 		key = ps3remote_keymap_remote_buttons[key];
626078328daSJiri Kosina 		if (!key)
627078328daSJiri Kosina 			return -1;
628078328daSJiri Kosina 		break;
629078328daSJiri Kosina 	default:
630078328daSJiri Kosina 		return -1;
631078328daSJiri Kosina 	}
632078328daSJiri Kosina 
633078328daSJiri Kosina 	hid_map_usage_clear(hi, usage, bit, max, EV_KEY, key);
634078328daSJiri Kosina 	return 1;
635078328daSJiri Kosina }
636078328daSJiri Kosina 
637*b8f0970dSRoderick Colenbrander static int navigation_mapping(struct hid_device *hdev, struct hid_input *hi,
638*b8f0970dSRoderick Colenbrander 			  struct hid_field *field, struct hid_usage *usage,
639*b8f0970dSRoderick Colenbrander 			  unsigned long **bit, int *max)
640*b8f0970dSRoderick Colenbrander {
641*b8f0970dSRoderick Colenbrander 	if ((usage->hid & HID_USAGE_PAGE) == HID_UP_BUTTON) {
642*b8f0970dSRoderick Colenbrander 		unsigned int key = usage->hid & HID_USAGE;
643*b8f0970dSRoderick Colenbrander 
644*b8f0970dSRoderick Colenbrander 		if (key >= ARRAY_SIZE(sixaxis_keymap))
645*b8f0970dSRoderick Colenbrander 			return -1;
646*b8f0970dSRoderick Colenbrander 
647*b8f0970dSRoderick Colenbrander 		key = navigation_keymap[key];
648*b8f0970dSRoderick Colenbrander 		if (!key)
649*b8f0970dSRoderick Colenbrander 			return -1;
650*b8f0970dSRoderick Colenbrander 
651*b8f0970dSRoderick Colenbrander 		hid_map_usage_clear(hi, usage, bit, max, EV_KEY, key);
652*b8f0970dSRoderick Colenbrander 		return 1;
653*b8f0970dSRoderick Colenbrander 	} else if (usage->hid == HID_GD_POINTER) {
654*b8f0970dSRoderick Colenbrander 		/* See comment in sixaxis_mapping, basically the L2 (and R2)
655*b8f0970dSRoderick Colenbrander 		 * triggers are reported through GD Pointer.
656*b8f0970dSRoderick Colenbrander 		 * In addition we ignore any analog button 'axes' and only
657*b8f0970dSRoderick Colenbrander 		 * support digital buttons.
658*b8f0970dSRoderick Colenbrander 		 */
659*b8f0970dSRoderick Colenbrander 		switch (usage->usage_index) {
660*b8f0970dSRoderick Colenbrander 		case 8: /* L2 */
661*b8f0970dSRoderick Colenbrander 			usage->hid = HID_GD_Z;
662*b8f0970dSRoderick Colenbrander 			break;
663*b8f0970dSRoderick Colenbrander 		default:
664*b8f0970dSRoderick Colenbrander 			return -1;
665*b8f0970dSRoderick Colenbrander 		}
666*b8f0970dSRoderick Colenbrander 
667*b8f0970dSRoderick Colenbrander 		hid_map_usage_clear(hi, usage, bit, max, EV_ABS, usage->hid & 0xf);
668*b8f0970dSRoderick Colenbrander 		return 1;
669*b8f0970dSRoderick Colenbrander 	} else if ((usage->hid & HID_USAGE_PAGE) == HID_UP_GENDESK) {
670*b8f0970dSRoderick Colenbrander 		unsigned int abs = usage->hid & HID_USAGE;
671*b8f0970dSRoderick Colenbrander 
672*b8f0970dSRoderick Colenbrander 		if (abs >= ARRAY_SIZE(navigation_absmap))
673*b8f0970dSRoderick Colenbrander 			return -1;
674*b8f0970dSRoderick Colenbrander 
675*b8f0970dSRoderick Colenbrander 		abs = navigation_absmap[abs];
676*b8f0970dSRoderick Colenbrander 
677*b8f0970dSRoderick Colenbrander 		hid_map_usage_clear(hi, usage, bit, max, EV_ABS, abs);
678*b8f0970dSRoderick Colenbrander 		return 1;
679*b8f0970dSRoderick Colenbrander 	}
680*b8f0970dSRoderick Colenbrander 
681*b8f0970dSRoderick Colenbrander 	return -1;
682*b8f0970dSRoderick Colenbrander }
683*b8f0970dSRoderick Colenbrander 
684*b8f0970dSRoderick Colenbrander 
685e19a267bSRoderick Colenbrander static int sixaxis_mapping(struct hid_device *hdev, struct hid_input *hi,
686e19a267bSRoderick Colenbrander 			  struct hid_field *field, struct hid_usage *usage,
687e19a267bSRoderick Colenbrander 			  unsigned long **bit, int *max)
688e19a267bSRoderick Colenbrander {
689e19a267bSRoderick Colenbrander 	if ((usage->hid & HID_USAGE_PAGE) == HID_UP_BUTTON) {
690e19a267bSRoderick Colenbrander 		unsigned int key = usage->hid & HID_USAGE;
691e19a267bSRoderick Colenbrander 
692e19a267bSRoderick Colenbrander 		if (key >= ARRAY_SIZE(sixaxis_keymap))
693e19a267bSRoderick Colenbrander 			return -1;
694e19a267bSRoderick Colenbrander 
695e19a267bSRoderick Colenbrander 		key = sixaxis_keymap[key];
696e19a267bSRoderick Colenbrander 		hid_map_usage_clear(hi, usage, bit, max, EV_KEY, key);
697e19a267bSRoderick Colenbrander 		return 1;
698e19a267bSRoderick Colenbrander 	} else if (usage->hid == HID_GD_POINTER) {
699e19a267bSRoderick Colenbrander 		/* The DS3 provides analog values for most buttons and even
700e19a267bSRoderick Colenbrander 		 * for HAT axes through GD Pointer. L2 and R2 are reported
701e19a267bSRoderick Colenbrander 		 * among these as well instead of as GD Z / RZ. Remap L2
702e19a267bSRoderick Colenbrander 		 * and R2 and ignore other analog 'button axes' as there is
703e19a267bSRoderick Colenbrander 		 * no good way for reporting them.
704e19a267bSRoderick Colenbrander 		 */
705e19a267bSRoderick Colenbrander 		switch (usage->usage_index) {
706e19a267bSRoderick Colenbrander 		case 8: /* L2 */
707e19a267bSRoderick Colenbrander 			usage->hid = HID_GD_Z;
708e19a267bSRoderick Colenbrander 			break;
709e19a267bSRoderick Colenbrander 		case 9: /* R2 */
710e19a267bSRoderick Colenbrander 			usage->hid = HID_GD_RZ;
711e19a267bSRoderick Colenbrander 			break;
712e19a267bSRoderick Colenbrander 		default:
713e19a267bSRoderick Colenbrander 			return -1;
714e19a267bSRoderick Colenbrander 		}
715e19a267bSRoderick Colenbrander 
716e19a267bSRoderick Colenbrander 		hid_map_usage_clear(hi, usage, bit, max, EV_ABS, usage->hid & 0xf);
717e19a267bSRoderick Colenbrander 		return 1;
718e19a267bSRoderick Colenbrander 	} else if ((usage->hid & HID_USAGE_PAGE) == HID_UP_GENDESK) {
719e19a267bSRoderick Colenbrander 		unsigned int abs = usage->hid & HID_USAGE;
720e19a267bSRoderick Colenbrander 
721e19a267bSRoderick Colenbrander 		if (abs >= ARRAY_SIZE(sixaxis_absmap))
722e19a267bSRoderick Colenbrander 			return -1;
723e19a267bSRoderick Colenbrander 
724e19a267bSRoderick Colenbrander 		abs = sixaxis_absmap[abs];
725e19a267bSRoderick Colenbrander 
726e19a267bSRoderick Colenbrander 		hid_map_usage_clear(hi, usage, bit, max, EV_ABS, abs);
727e19a267bSRoderick Colenbrander 		return 1;
728e19a267bSRoderick Colenbrander 	}
729e19a267bSRoderick Colenbrander 
730e19a267bSRoderick Colenbrander 	return -1;
731e19a267bSRoderick Colenbrander }
732e19a267bSRoderick Colenbrander 
7339131f8ccSRoderick Colenbrander static int ds4_mapping(struct hid_device *hdev, struct hid_input *hi,
7349131f8ccSRoderick Colenbrander 		       struct hid_field *field, struct hid_usage *usage,
7359131f8ccSRoderick Colenbrander 		       unsigned long **bit, int *max)
7369131f8ccSRoderick Colenbrander {
7379131f8ccSRoderick Colenbrander 	if ((usage->hid & HID_USAGE_PAGE) == HID_UP_BUTTON) {
7389131f8ccSRoderick Colenbrander 		unsigned int key = usage->hid & HID_USAGE;
7399131f8ccSRoderick Colenbrander 
7409131f8ccSRoderick Colenbrander 		if (key >= ARRAY_SIZE(ds4_keymap))
7419131f8ccSRoderick Colenbrander 			return -1;
7429131f8ccSRoderick Colenbrander 
7439131f8ccSRoderick Colenbrander 		key = ds4_keymap[key];
7449131f8ccSRoderick Colenbrander 		hid_map_usage_clear(hi, usage, bit, max, EV_KEY, key);
7459131f8ccSRoderick Colenbrander 		return 1;
7469131f8ccSRoderick Colenbrander 	} else if ((usage->hid & HID_USAGE_PAGE) == HID_UP_GENDESK) {
7479131f8ccSRoderick Colenbrander 		unsigned int abs = usage->hid & HID_USAGE;
7489131f8ccSRoderick Colenbrander 
7499131f8ccSRoderick Colenbrander 		/* Let the HID parser deal with the HAT. */
7509131f8ccSRoderick Colenbrander 		if (usage->hid == HID_GD_HATSWITCH)
7519131f8ccSRoderick Colenbrander 			return 0;
7529131f8ccSRoderick Colenbrander 
7539131f8ccSRoderick Colenbrander 		if (abs >= ARRAY_SIZE(ds4_absmap))
7549131f8ccSRoderick Colenbrander 			return -1;
7559131f8ccSRoderick Colenbrander 
7569131f8ccSRoderick Colenbrander 		abs = ds4_absmap[abs];
7579131f8ccSRoderick Colenbrander 		hid_map_usage_clear(hi, usage, bit, max, EV_ABS, abs);
7589131f8ccSRoderick Colenbrander 		return 1;
7599131f8ccSRoderick Colenbrander 	}
7609131f8ccSRoderick Colenbrander 
7619131f8ccSRoderick Colenbrander 	return 0;
7629131f8ccSRoderick Colenbrander }
7639131f8ccSRoderick Colenbrander 
7641adf904eSPavel Machek static u8 *sony_report_fixup(struct hid_device *hdev, u8 *rdesc,
76573e4008dSNikolai Kondrashov 		unsigned int *rsize)
766cc6e0bbbSJiri Kosina {
767cc6e0bbbSJiri Kosina 	struct sony_sc *sc = hid_get_drvdata(hdev);
768cc6e0bbbSJiri Kosina 
7694ba1eeebSMikko Perttunen 	if (sc->quirks & (SINO_LITE_CONTROLLER | FUTUREMAX_DANCE_MAT))
77074500cc8SScott Moreau 		return rdesc;
77174500cc8SScott Moreau 
77299d24902SFernando Luis Vázquez Cao 	/*
77399d24902SFernando Luis Vázquez Cao 	 * Some Sony RF receivers wrongly declare the mouse pointer as a
77499d24902SFernando Luis Vázquez Cao 	 * a constant non-data variable.
77599d24902SFernando Luis Vázquez Cao 	 */
77699d24902SFernando Luis Vázquez Cao 	if ((sc->quirks & VAIO_RDESC_CONSTANT) && *rsize >= 56 &&
77799d24902SFernando Luis Vázquez Cao 	    /* usage page: generic desktop controls */
77899d24902SFernando Luis Vázquez Cao 	    /* rdesc[0] == 0x05 && rdesc[1] == 0x01 && */
77999d24902SFernando Luis Vázquez Cao 	    /* usage: mouse */
78099d24902SFernando Luis Vázquez Cao 	    rdesc[2] == 0x09 && rdesc[3] == 0x02 &&
78199d24902SFernando Luis Vázquez Cao 	    /* input (usage page for x,y axes): constant, variable, relative */
78299d24902SFernando Luis Vázquez Cao 	    rdesc[54] == 0x81 && rdesc[55] == 0x07) {
783a4649184SFernando Luis Vázquez Cao 		hid_info(hdev, "Fixing up Sony RF Receiver report descriptor\n");
78499d24902SFernando Luis Vázquez Cao 		/* input: data, variable, relative */
785cc6e0bbbSJiri Kosina 		rdesc[55] = 0x06;
786cc6e0bbbSJiri Kosina 	}
78761ab44beSSimon Wood 
788c5e0c1c4SFrank Praznik 	if (sc->quirks & MOTION_CONTROLLER)
789c5e0c1c4SFrank Praznik 		return motion_fixup(hdev, rdesc, rsize);
790c5e0c1c4SFrank Praznik 
791078328daSJiri Kosina 	if (sc->quirks & PS3REMOTE)
792078328daSJiri Kosina 		return ps3remote_fixup(hdev, rdesc, rsize);
793078328daSJiri Kosina 
79473e4008dSNikolai Kondrashov 	return rdesc;
795cc6e0bbbSJiri Kosina }
796cc6e0bbbSJiri Kosina 
7971adf904eSPavel Machek static void sixaxis_parse_report(struct sony_sc *sc, u8 *rd, int size)
798d902f472SFrank Praznik {
7991adf904eSPavel Machek 	static const u8 sixaxis_battery_capacity[] = { 0, 1, 25, 50, 75, 100 };
800d902f472SFrank Praznik 	unsigned long flags;
80112e9a6d7SSimon Wood 	int offset;
8021adf904eSPavel Machek 	u8 cable_state, battery_capacity, battery_charging;
803d902f472SFrank Praznik 
804ad142b9eSFrank Praznik 	/*
805ad142b9eSFrank Praznik 	 * The sixaxis is charging if the battery value is 0xee
806d902f472SFrank Praznik 	 * and it is fully charged if the value is 0xef.
807d902f472SFrank Praznik 	 * It does not report the actual level while charging so it
808d902f472SFrank Praznik 	 * is set to 100% while charging is in progress.
809d902f472SFrank Praznik 	 */
81012e9a6d7SSimon Wood 	offset = (sc->quirks & MOTION_CONTROLLER) ? 12 : 30;
81112e9a6d7SSimon Wood 
81212e9a6d7SSimon Wood 	if (rd[offset] >= 0xee) {
813d902f472SFrank Praznik 		battery_capacity = 100;
81412e9a6d7SSimon Wood 		battery_charging = !(rd[offset] & 0x01);
8159fddd74aSFrank Praznik 		cable_state = 1;
816d902f472SFrank Praznik 	} else {
8171adf904eSPavel Machek 		u8 index = rd[offset] <= 5 ? rd[offset] : 5;
818ac3c9a94SFrank Praznik 		battery_capacity = sixaxis_battery_capacity[index];
819d902f472SFrank Praznik 		battery_charging = 0;
8209fddd74aSFrank Praznik 		cable_state = 0;
821d902f472SFrank Praznik 	}
822d902f472SFrank Praznik 
823d902f472SFrank Praznik 	spin_lock_irqsave(&sc->lock, flags);
824d902f472SFrank Praznik 	sc->cable_state = cable_state;
825d902f472SFrank Praznik 	sc->battery_capacity = battery_capacity;
826d902f472SFrank Praznik 	sc->battery_charging = battery_charging;
827d902f472SFrank Praznik 	spin_unlock_irqrestore(&sc->lock, flags);
828510c8b7cSRoderick Colenbrander 
829510c8b7cSRoderick Colenbrander 	if (sc->quirks & SIXAXIS_CONTROLLER) {
830510c8b7cSRoderick Colenbrander 		int val;
831510c8b7cSRoderick Colenbrander 
832510c8b7cSRoderick Colenbrander 		offset = SIXAXIS_INPUT_REPORT_ACC_X_OFFSET;
833510c8b7cSRoderick Colenbrander 		val = ((rd[offset+1] << 8) | rd[offset]) - 511;
834510c8b7cSRoderick Colenbrander 		input_report_abs(sc->sensor_dev, ABS_X, val);
835510c8b7cSRoderick Colenbrander 
836510c8b7cSRoderick Colenbrander 		/* Y and Z are swapped and inversed */
837510c8b7cSRoderick Colenbrander 		val = 511 - ((rd[offset+5] << 8) | rd[offset+4]);
838510c8b7cSRoderick Colenbrander 		input_report_abs(sc->sensor_dev, ABS_Y, val);
839510c8b7cSRoderick Colenbrander 
840510c8b7cSRoderick Colenbrander 		val = 511 - ((rd[offset+3] << 8) | rd[offset+2]);
841510c8b7cSRoderick Colenbrander 		input_report_abs(sc->sensor_dev, ABS_Z, val);
842510c8b7cSRoderick Colenbrander 
843510c8b7cSRoderick Colenbrander 		input_sync(sc->sensor_dev);
844510c8b7cSRoderick Colenbrander 	}
845d902f472SFrank Praznik }
846d902f472SFrank Praznik 
8471adf904eSPavel Machek static void dualshock4_parse_report(struct sony_sc *sc, u8 *rd, int size)
848d902f472SFrank Praznik {
849d03ae2e1SRoderick Colenbrander 	struct hid_input *hidinput = list_entry(sc->hdev->inputs.next,
850d03ae2e1SRoderick Colenbrander 						struct hid_input, list);
851d03ae2e1SRoderick Colenbrander 	struct input_dev *input_dev = hidinput->input;
852d902f472SFrank Praznik 	unsigned long flags;
853cdc1c021SRoderick Colenbrander 	int n, m, offset, num_touch_data, max_touch_data;
8541adf904eSPavel Machek 	u8 cable_state, battery_capacity, battery_charging;
85580786eb9SRoderick Colenbrander 	u16 timestamp;
856d902f472SFrank Praznik 
857cdc1c021SRoderick Colenbrander 	/* When using Bluetooth the header is 2 bytes longer, so skip these. */
85835f436c3SRoderick Colenbrander 	int data_offset = (sc->quirks & DUALSHOCK4_CONTROLLER_BT) ? 2 : 0;
8596c5f860dSFrank Praznik 
860ac797b95SRoderick Colenbrander 	/* Second bit of third button byte is for the touchpad button. */
861ac797b95SRoderick Colenbrander 	offset = data_offset + DS4_INPUT_REPORT_BUTTON_OFFSET;
862ac797b95SRoderick Colenbrander 	input_report_key(sc->touchpad, BTN_LEFT, rd[offset+2] & 0x2);
863ac797b95SRoderick Colenbrander 
864d03ae2e1SRoderick Colenbrander 	/*
865d03ae2e1SRoderick Colenbrander 	 * The default behavior of the Dualshock 4 is to send reports using
866d03ae2e1SRoderick Colenbrander 	 * report type 1 when running over Bluetooth. However, when feature
867d03ae2e1SRoderick Colenbrander 	 * report 2 is requested during the controller initialization it starts
868d03ae2e1SRoderick Colenbrander 	 * sending input reports in report 17. Since report 17 is undefined
869d03ae2e1SRoderick Colenbrander 	 * in the default HID descriptor, the HID layer won't generate events.
870d03ae2e1SRoderick Colenbrander 	 * While it is possible (and this was done before) to fixup the HID
871d03ae2e1SRoderick Colenbrander 	 * descriptor to add this mapping, it was better to do this manually.
872d03ae2e1SRoderick Colenbrander 	 * The reason is there were various pieces software both open and closed
873d03ae2e1SRoderick Colenbrander 	 * source, relying on the descriptors to be the same across various
874d03ae2e1SRoderick Colenbrander 	 * operating systems. If the descriptors wouldn't match some
875d03ae2e1SRoderick Colenbrander 	 * applications e.g. games on Wine would not be able to function due
876d03ae2e1SRoderick Colenbrander 	 * to different descriptors, which such applications are not parsing.
877d03ae2e1SRoderick Colenbrander 	 */
878d03ae2e1SRoderick Colenbrander 	if (rd[0] == 17) {
879d03ae2e1SRoderick Colenbrander 		int value;
880d03ae2e1SRoderick Colenbrander 
881d03ae2e1SRoderick Colenbrander 		offset = data_offset + DS4_INPUT_REPORT_AXIS_OFFSET;
882d03ae2e1SRoderick Colenbrander 		input_report_abs(input_dev, ABS_X, rd[offset]);
883d03ae2e1SRoderick Colenbrander 		input_report_abs(input_dev, ABS_Y, rd[offset+1]);
884d03ae2e1SRoderick Colenbrander 		input_report_abs(input_dev, ABS_RX, rd[offset+2]);
885d03ae2e1SRoderick Colenbrander 		input_report_abs(input_dev, ABS_RY, rd[offset+3]);
886d03ae2e1SRoderick Colenbrander 
887d03ae2e1SRoderick Colenbrander 		value = rd[offset+4] & 0xf;
888d03ae2e1SRoderick Colenbrander 		if (value > 7)
889d03ae2e1SRoderick Colenbrander 			value = 8; /* Center 0, 0 */
890d03ae2e1SRoderick Colenbrander 		input_report_abs(input_dev, ABS_HAT0X, ds4_hat_mapping[value].x);
891d03ae2e1SRoderick Colenbrander 		input_report_abs(input_dev, ABS_HAT0Y, ds4_hat_mapping[value].y);
892d03ae2e1SRoderick Colenbrander 
893d03ae2e1SRoderick Colenbrander 		input_report_key(input_dev, BTN_WEST, rd[offset+4] & 0x10);
894d03ae2e1SRoderick Colenbrander 		input_report_key(input_dev, BTN_SOUTH, rd[offset+4] & 0x20);
895d03ae2e1SRoderick Colenbrander 		input_report_key(input_dev, BTN_EAST, rd[offset+4] & 0x40);
896d03ae2e1SRoderick Colenbrander 		input_report_key(input_dev, BTN_NORTH, rd[offset+4] & 0x80);
897d03ae2e1SRoderick Colenbrander 
898d03ae2e1SRoderick Colenbrander 		input_report_key(input_dev, BTN_TL, rd[offset+5] & 0x1);
899d03ae2e1SRoderick Colenbrander 		input_report_key(input_dev, BTN_TR, rd[offset+5] & 0x2);
900d03ae2e1SRoderick Colenbrander 		input_report_key(input_dev, BTN_TL2, rd[offset+5] & 0x4);
901d03ae2e1SRoderick Colenbrander 		input_report_key(input_dev, BTN_TR2, rd[offset+5] & 0x8);
902d03ae2e1SRoderick Colenbrander 		input_report_key(input_dev, BTN_SELECT, rd[offset+5] & 0x10);
903d03ae2e1SRoderick Colenbrander 		input_report_key(input_dev, BTN_START, rd[offset+5] & 0x20);
904d03ae2e1SRoderick Colenbrander 		input_report_key(input_dev, BTN_THUMBL, rd[offset+5] & 0x40);
905d03ae2e1SRoderick Colenbrander 		input_report_key(input_dev, BTN_THUMBR, rd[offset+5] & 0x80);
906d03ae2e1SRoderick Colenbrander 
907d03ae2e1SRoderick Colenbrander 		input_report_key(input_dev, BTN_MODE, rd[offset+6] & 0x1);
908d03ae2e1SRoderick Colenbrander 
909d03ae2e1SRoderick Colenbrander 		input_report_abs(input_dev, ABS_Z, rd[offset+7]);
910d03ae2e1SRoderick Colenbrander 		input_report_abs(input_dev, ABS_RZ, rd[offset+8]);
911d03ae2e1SRoderick Colenbrander 
912d03ae2e1SRoderick Colenbrander 		input_sync(input_dev);
913d03ae2e1SRoderick Colenbrander 	}
914d03ae2e1SRoderick Colenbrander 
91580786eb9SRoderick Colenbrander 	/* Convert timestamp (in 5.33us unit) to timestamp_us */
91680786eb9SRoderick Colenbrander 	offset = data_offset + DS4_INPUT_REPORT_TIMESTAMP_OFFSET;
91780786eb9SRoderick Colenbrander 	timestamp = get_unaligned_le16(&rd[offset]);
91880786eb9SRoderick Colenbrander 	if (!sc->timestamp_initialized) {
91980786eb9SRoderick Colenbrander 		sc->timestamp_us = ((unsigned int)timestamp * 16) / 3;
92080786eb9SRoderick Colenbrander 		sc->timestamp_initialized = true;
92180786eb9SRoderick Colenbrander 	} else {
92280786eb9SRoderick Colenbrander 		u16 delta;
92380786eb9SRoderick Colenbrander 
92480786eb9SRoderick Colenbrander 		if (sc->prev_timestamp > timestamp)
92580786eb9SRoderick Colenbrander 			delta = (U16_MAX - sc->prev_timestamp + timestamp + 1);
92680786eb9SRoderick Colenbrander 		else
92780786eb9SRoderick Colenbrander 			delta = timestamp - sc->prev_timestamp;
92880786eb9SRoderick Colenbrander 		sc->timestamp_us += (delta * 16) / 3;
92980786eb9SRoderick Colenbrander 	}
93080786eb9SRoderick Colenbrander 	sc->prev_timestamp = timestamp;
93180786eb9SRoderick Colenbrander 	input_event(sc->sensor_dev, EV_MSC, MSC_TIMESTAMP, sc->timestamp_us);
93280786eb9SRoderick Colenbrander 
933227c011bSRoderick Colenbrander 	offset = data_offset + DS4_INPUT_REPORT_GYRO_X_OFFSET;
93455a07d62SRoderick Colenbrander 	for (n = 0; n < 6; n++) {
93555a07d62SRoderick Colenbrander 		/* Store data in int for more precision during mult_frac. */
93655a07d62SRoderick Colenbrander 		int raw_data = (short)((rd[offset+1] << 8) | rd[offset]);
93755a07d62SRoderick Colenbrander 		struct ds4_calibration_data *calib = &sc->ds4_calib_data[n];
938227c011bSRoderick Colenbrander 
93955a07d62SRoderick Colenbrander 		/* High precision is needed during calibration, but the
94055a07d62SRoderick Colenbrander 		 * calibrated values are within 32-bit.
94155a07d62SRoderick Colenbrander 		 * Note: we swap numerator 'x' and 'numer' in mult_frac for
94255a07d62SRoderick Colenbrander 		 *       precision reasons so we don't need 64-bit.
94355a07d62SRoderick Colenbrander 		 */
94455a07d62SRoderick Colenbrander 		int calib_data = mult_frac(calib->sens_numer,
94555a07d62SRoderick Colenbrander 					   raw_data - calib->bias,
94655a07d62SRoderick Colenbrander 					   calib->sens_denom);
94755a07d62SRoderick Colenbrander 
94855a07d62SRoderick Colenbrander 		input_report_abs(sc->sensor_dev, calib->abs_code, calib_data);
94955a07d62SRoderick Colenbrander 		offset += 2;
950227c011bSRoderick Colenbrander 	}
951227c011bSRoderick Colenbrander 	input_sync(sc->sensor_dev);
952227c011bSRoderick Colenbrander 
953ad142b9eSFrank Praznik 	/*
954cdc1c021SRoderick Colenbrander 	 * The lower 4 bits of byte 30 (or 32 for BT) contain the battery level
955d902f472SFrank Praznik 	 * and the 5th bit contains the USB cable state.
956d902f472SFrank Praznik 	 */
957cdc1c021SRoderick Colenbrander 	offset = data_offset + DS4_INPUT_REPORT_BATTERY_OFFSET;
9586c5f860dSFrank Praznik 	cable_state = (rd[offset] >> 4) & 0x01;
9596c5f860dSFrank Praznik 	battery_capacity = rd[offset] & 0x0F;
960d902f472SFrank Praznik 
961ad142b9eSFrank Praznik 	/*
962ad142b9eSFrank Praznik 	 * When a USB power source is connected the battery level ranges from
9636c5f860dSFrank Praznik 	 * 0 to 10, and when running on battery power it ranges from 0 to 9.
9646c5f860dSFrank Praznik 	 * A battery level above 10 when plugged in means charge completed.
965d902f472SFrank Praznik 	 */
9666c5f860dSFrank Praznik 	if (!cable_state || battery_capacity > 10)
967d902f472SFrank Praznik 		battery_charging = 0;
968d902f472SFrank Praznik 	else
969d902f472SFrank Praznik 		battery_charging = 1;
970d902f472SFrank Praznik 
9716c5f860dSFrank Praznik 	if (!cable_state)
9726c5f860dSFrank Praznik 		battery_capacity++;
973d902f472SFrank Praznik 	if (battery_capacity > 10)
9746c5f860dSFrank Praznik 		battery_capacity = 10;
9756c5f860dSFrank Praznik 
976d902f472SFrank Praznik 	battery_capacity *= 10;
977d902f472SFrank Praznik 
978d902f472SFrank Praznik 	spin_lock_irqsave(&sc->lock, flags);
979d902f472SFrank Praznik 	sc->cable_state = cable_state;
980d902f472SFrank Praznik 	sc->battery_capacity = battery_capacity;
981d902f472SFrank Praznik 	sc->battery_charging = battery_charging;
982d902f472SFrank Praznik 	spin_unlock_irqrestore(&sc->lock, flags);
983e5606230SFrank Praznik 
984cdc1c021SRoderick Colenbrander 	/*
985cdc1c021SRoderick Colenbrander 	 * The Dualshock 4 multi-touch trackpad data starts at offset 33 on USB
986cdc1c021SRoderick Colenbrander 	 * and 35 on Bluetooth.
987cdc1c021SRoderick Colenbrander 	 * The first byte indicates the number of touch data in the report.
988cdc1c021SRoderick Colenbrander 	 * Trackpad data starts 2 bytes later (e.g. 35 for USB).
989cdc1c021SRoderick Colenbrander 	 */
990cdc1c021SRoderick Colenbrander 	offset = data_offset + DS4_INPUT_REPORT_TOUCHPAD_OFFSET;
99135f436c3SRoderick Colenbrander 	max_touch_data = (sc->quirks & DUALSHOCK4_CONTROLLER_BT) ? 4 : 3;
992cdc1c021SRoderick Colenbrander 	if (rd[offset] > 0 && rd[offset] <= max_touch_data)
993cdc1c021SRoderick Colenbrander 		num_touch_data = rd[offset];
994cdc1c021SRoderick Colenbrander 	else
995cdc1c021SRoderick Colenbrander 		num_touch_data = 1;
996cdc1c021SRoderick Colenbrander 	offset += 1;
997cdc1c021SRoderick Colenbrander 
998cdc1c021SRoderick Colenbrander 	for (m = 0; m < num_touch_data; m++) {
999cdc1c021SRoderick Colenbrander 		/* Skip past timestamp */
1000cdc1c021SRoderick Colenbrander 		offset += 1;
10016c5f860dSFrank Praznik 
1002ad142b9eSFrank Praznik 		/*
1003cdc1c021SRoderick Colenbrander 		 * The first 7 bits of the first byte is a counter and bit 8 is
1004cdc1c021SRoderick Colenbrander 		 * a touch indicator that is 0 when pressed and 1 when not
1005cdc1c021SRoderick Colenbrander 		 * pressed.
1006e5606230SFrank Praznik 		 * The next 3 bytes are two 12 bit touch coordinates, X and Y.
1007cdc1c021SRoderick Colenbrander 		 * The data for the second touch is in the same format and
1008cdc1c021SRoderick Colenbrander 		 * immediately follows the data for the first.
1009e5606230SFrank Praznik 		 */
1010e5606230SFrank Praznik 		for (n = 0; n < 2; n++) {
10111adf904eSPavel Machek 			u16 x, y;
1012cdc1c021SRoderick Colenbrander 			bool active;
1013e5606230SFrank Praznik 
1014e5606230SFrank Praznik 			x = rd[offset+1] | ((rd[offset+2] & 0xF) << 8);
1015e5606230SFrank Praznik 			y = ((rd[offset+2] & 0xF0) >> 4) | (rd[offset+3] << 4);
1016e5606230SFrank Praznik 
1017cdc1c021SRoderick Colenbrander 			active = !(rd[offset] >> 7);
1018ac797b95SRoderick Colenbrander 			input_mt_slot(sc->touchpad, n);
1019ac797b95SRoderick Colenbrander 			input_mt_report_slot_state(sc->touchpad, MT_TOOL_FINGER, active);
1020cdc1c021SRoderick Colenbrander 
1021cdc1c021SRoderick Colenbrander 			if (active) {
1022ac797b95SRoderick Colenbrander 				input_report_abs(sc->touchpad, ABS_MT_POSITION_X, x);
1023ac797b95SRoderick Colenbrander 				input_report_abs(sc->touchpad, ABS_MT_POSITION_Y, y);
1024cdc1c021SRoderick Colenbrander 			}
1025e5606230SFrank Praznik 
1026e5606230SFrank Praznik 			offset += 4;
1027e5606230SFrank Praznik 		}
1028ac797b95SRoderick Colenbrander 		input_mt_sync_frame(sc->touchpad);
1029ac797b95SRoderick Colenbrander 		input_sync(sc->touchpad);
1030cdc1c021SRoderick Colenbrander 	}
1031d902f472SFrank Praznik }
1032d902f472SFrank Praznik 
1033c9e4d877SSimon Wood static int sony_raw_event(struct hid_device *hdev, struct hid_report *report,
10341adf904eSPavel Machek 		u8 *rd, int size)
1035c9e4d877SSimon Wood {
1036c9e4d877SSimon Wood 	struct sony_sc *sc = hid_get_drvdata(hdev);
1037c9e4d877SSimon Wood 
1038ad142b9eSFrank Praznik 	/*
1039ad142b9eSFrank Praznik 	 * Sixaxis HID report has acclerometers/gyro with MSByte first, this
1040c9e4d877SSimon Wood 	 * has to be BYTE_SWAPPED before passing up to joystick interface
1041c9e4d877SSimon Wood 	 */
1042fee4e2d5SFrank Praznik 	if ((sc->quirks & SIXAXIS_CONTROLLER) && rd[0] == 0x01 && size == 49) {
10438f5f0bc2SFrank Praznik 		/*
10448f5f0bc2SFrank Praznik 		 * When connected via Bluetooth the Sixaxis occasionally sends
10458f5f0bc2SFrank Praznik 		 * a report with the second byte 0xff and the rest zeroed.
10468f5f0bc2SFrank Praznik 		 *
10478f5f0bc2SFrank Praznik 		 * This report does not reflect the actual state of the
10488f5f0bc2SFrank Praznik 		 * controller must be ignored to avoid generating false input
10498f5f0bc2SFrank Praznik 		 * events.
10508f5f0bc2SFrank Praznik 		 */
10518f5f0bc2SFrank Praznik 		if (rd[1] == 0xff)
10528f5f0bc2SFrank Praznik 			return -EINVAL;
10538f5f0bc2SFrank Praznik 
1054c9e4d877SSimon Wood 		swap(rd[41], rd[42]);
1055c9e4d877SSimon Wood 		swap(rd[43], rd[44]);
1056c9e4d877SSimon Wood 		swap(rd[45], rd[46]);
1057c9e4d877SSimon Wood 		swap(rd[47], rd[48]);
1058d902f472SFrank Praznik 
1059d902f472SFrank Praznik 		sixaxis_parse_report(sc, rd, size);
106012e9a6d7SSimon Wood 	} else if ((sc->quirks & MOTION_CONTROLLER_BT) && rd[0] == 0x01 && size == 49) {
106112e9a6d7SSimon Wood 		sixaxis_parse_report(sc, rd, size);
10624545ee0aSSimon Wood 	} else if ((sc->quirks & NAVIGATION_CONTROLLER) && rd[0] == 0x01 &&
10634545ee0aSSimon Wood 			size == 49) {
10644545ee0aSSimon Wood 		sixaxis_parse_report(sc, rd, size);
106535f436c3SRoderick Colenbrander 	} else if ((sc->quirks & DUALSHOCK4_CONTROLLER_USB) && rd[0] == 0x01 &&
106635f436c3SRoderick Colenbrander 			size == 64) {
106735f436c3SRoderick Colenbrander 		dualshock4_parse_report(sc, rd, size);
106835f436c3SRoderick Colenbrander 	} else if (((sc->quirks & DUALSHOCK4_CONTROLLER_BT) && rd[0] == 0x11 &&
106935f436c3SRoderick Colenbrander 			size == 78)) {
107049b9ca6cSRoderick Colenbrander 		/* CRC check */
107149b9ca6cSRoderick Colenbrander 		u8 bthdr = 0xA1;
107249b9ca6cSRoderick Colenbrander 		u32 crc;
107349b9ca6cSRoderick Colenbrander 		u32 report_crc;
107449b9ca6cSRoderick Colenbrander 
107549b9ca6cSRoderick Colenbrander 		crc = crc32_le(0xFFFFFFFF, &bthdr, 1);
107649b9ca6cSRoderick Colenbrander 		crc = ~crc32_le(crc, rd, DS4_INPUT_REPORT_0x11_SIZE-4);
107749b9ca6cSRoderick Colenbrander 		report_crc = get_unaligned_le32(&rd[DS4_INPUT_REPORT_0x11_SIZE-4]);
107849b9ca6cSRoderick Colenbrander 		if (crc != report_crc) {
107949b9ca6cSRoderick Colenbrander 			hid_dbg(sc->hdev, "DualShock 4 input report's CRC check failed, received crc 0x%0x != 0x%0x\n",
108049b9ca6cSRoderick Colenbrander 				report_crc, crc);
108149b9ca6cSRoderick Colenbrander 			return -EILSEQ;
108249b9ca6cSRoderick Colenbrander 		}
1083405182c2SRoderick Colenbrander 
108435f436c3SRoderick Colenbrander 		dualshock4_parse_report(sc, rd, size);
108535f436c3SRoderick Colenbrander 	} else if ((sc->quirks & DUALSHOCK4_DONGLE) && rd[0] == 0x01 &&
108635f436c3SRoderick Colenbrander 			size == 64) {
1087f2f47c38SRoderick Colenbrander 		unsigned long flags;
1088f2f47c38SRoderick Colenbrander 		enum ds4_dongle_state dongle_state;
1089f2f47c38SRoderick Colenbrander 
1090405182c2SRoderick Colenbrander 		/*
1091405182c2SRoderick Colenbrander 		 * In the case of a DS4 USB dongle, bit[2] of byte 31 indicates
1092405182c2SRoderick Colenbrander 		 * if a DS4 is actually connected (indicated by '0').
1093405182c2SRoderick Colenbrander 		 * For non-dongle, this bit is always 0 (connected).
1094405182c2SRoderick Colenbrander 		 */
1095405182c2SRoderick Colenbrander 		bool connected = (rd[31] & 0x04) ? false : true;
1096405182c2SRoderick Colenbrander 
1097f2f47c38SRoderick Colenbrander 		spin_lock_irqsave(&sc->lock, flags);
1098f2f47c38SRoderick Colenbrander 		dongle_state = sc->ds4_dongle_state;
1099f2f47c38SRoderick Colenbrander 		spin_unlock_irqrestore(&sc->lock, flags);
1100f2f47c38SRoderick Colenbrander 
1101f2f47c38SRoderick Colenbrander 		/*
1102f2f47c38SRoderick Colenbrander 		 * The dongle always sends input reports even when no
1103f2f47c38SRoderick Colenbrander 		 * DS4 is attached. When a DS4 is connected, we need to
1104f2f47c38SRoderick Colenbrander 		 * obtain calibration data before we can use it.
1105f2f47c38SRoderick Colenbrander 		 * The code below tracks dongle state and kicks of
1106f2f47c38SRoderick Colenbrander 		 * calibration when needed and only allows us to process
1107f2f47c38SRoderick Colenbrander 		 * input if a DS4 is actually connected.
1108f2f47c38SRoderick Colenbrander 		 */
1109f2f47c38SRoderick Colenbrander 		if (dongle_state == DONGLE_DISCONNECTED && connected) {
1110405182c2SRoderick Colenbrander 			hid_info(sc->hdev, "DualShock 4 USB dongle: controller connected\n");
1111405182c2SRoderick Colenbrander 			sony_set_leds(sc);
1112f2f47c38SRoderick Colenbrander 
1113f2f47c38SRoderick Colenbrander 			spin_lock_irqsave(&sc->lock, flags);
1114f2f47c38SRoderick Colenbrander 			sc->ds4_dongle_state = DONGLE_CALIBRATING;
1115f2f47c38SRoderick Colenbrander 			spin_unlock_irqrestore(&sc->lock, flags);
1116f2f47c38SRoderick Colenbrander 
1117f2f47c38SRoderick Colenbrander 			sony_schedule_work(sc, SONY_WORKER_HOTPLUG);
1118f2f47c38SRoderick Colenbrander 
1119f2f47c38SRoderick Colenbrander 			/* Don't process the report since we don't have
1120f2f47c38SRoderick Colenbrander 			 * calibration data, but let hidraw have it anyway.
1121f2f47c38SRoderick Colenbrander 			 */
1122f2f47c38SRoderick Colenbrander 			return 0;
1123f2f47c38SRoderick Colenbrander 		} else if ((dongle_state == DONGLE_CONNECTED ||
1124f2f47c38SRoderick Colenbrander 			    dongle_state == DONGLE_DISABLED) && !connected) {
1125405182c2SRoderick Colenbrander 			hid_info(sc->hdev, "DualShock 4 USB dongle: controller disconnected\n");
1126f2f47c38SRoderick Colenbrander 
1127f2f47c38SRoderick Colenbrander 			spin_lock_irqsave(&sc->lock, flags);
1128f2f47c38SRoderick Colenbrander 			sc->ds4_dongle_state = DONGLE_DISCONNECTED;
1129f2f47c38SRoderick Colenbrander 			spin_unlock_irqrestore(&sc->lock, flags);
1130f2f47c38SRoderick Colenbrander 
1131405182c2SRoderick Colenbrander 			/* Return 0, so hidraw can get the report. */
1132405182c2SRoderick Colenbrander 			return 0;
1133f2f47c38SRoderick Colenbrander 		} else if (dongle_state == DONGLE_CALIBRATING ||
1134f2f47c38SRoderick Colenbrander 			   dongle_state == DONGLE_DISABLED ||
1135f2f47c38SRoderick Colenbrander 			   dongle_state == DONGLE_DISCONNECTED) {
1136405182c2SRoderick Colenbrander 			/* Return 0, so hidraw can get the report. */
1137405182c2SRoderick Colenbrander 			return 0;
1138405182c2SRoderick Colenbrander 		}
1139405182c2SRoderick Colenbrander 
1140d902f472SFrank Praznik 		dualshock4_parse_report(sc, rd, size);
1141c9e4d877SSimon Wood 	}
1142c9e4d877SSimon Wood 
11432a242932SFrank Praznik 	if (sc->defer_initialization) {
11442a242932SFrank Praznik 		sc->defer_initialization = 0;
1145b5322736SRoderick Colenbrander 		sony_schedule_work(sc, SONY_WORKER_STATE);
11462a242932SFrank Praznik 	}
11472a242932SFrank Praznik 
1148c9e4d877SSimon Wood 	return 0;
1149c9e4d877SSimon Wood }
1150c9e4d877SSimon Wood 
1151f04d5140SColin Leitner static int sony_mapping(struct hid_device *hdev, struct hid_input *hi,
1152f04d5140SColin Leitner 			struct hid_field *field, struct hid_usage *usage,
1153f04d5140SColin Leitner 			unsigned long **bit, int *max)
1154f04d5140SColin Leitner {
1155f04d5140SColin Leitner 	struct sony_sc *sc = hid_get_drvdata(hdev);
1156f04d5140SColin Leitner 
1157f04d5140SColin Leitner 	if (sc->quirks & BUZZ_CONTROLLER) {
1158f04d5140SColin Leitner 		unsigned int key = usage->hid & HID_USAGE;
1159f04d5140SColin Leitner 
1160f04d5140SColin Leitner 		if ((usage->hid & HID_USAGE_PAGE) != HID_UP_BUTTON)
1161f04d5140SColin Leitner 			return -1;
1162f04d5140SColin Leitner 
1163f04d5140SColin Leitner 		switch (usage->collection_index) {
1164f04d5140SColin Leitner 		case 1:
1165f04d5140SColin Leitner 			if (key >= ARRAY_SIZE(buzz_keymap))
1166f04d5140SColin Leitner 				return -1;
1167f04d5140SColin Leitner 
1168f04d5140SColin Leitner 			key = buzz_keymap[key];
1169f04d5140SColin Leitner 			if (!key)
1170f04d5140SColin Leitner 				return -1;
1171f04d5140SColin Leitner 			break;
1172f04d5140SColin Leitner 		default:
1173f04d5140SColin Leitner 			return -1;
1174f04d5140SColin Leitner 		}
1175f04d5140SColin Leitner 
1176f04d5140SColin Leitner 		hid_map_usage_clear(hi, usage, bit, max, EV_KEY, key);
1177f04d5140SColin Leitner 		return 1;
1178f04d5140SColin Leitner 	}
1179f04d5140SColin Leitner 
1180078328daSJiri Kosina 	if (sc->quirks & PS3REMOTE)
1181078328daSJiri Kosina 		return ps3remote_mapping(hdev, hi, field, usage, bit, max);
1182078328daSJiri Kosina 
1183*b8f0970dSRoderick Colenbrander 	if (sc->quirks & NAVIGATION_CONTROLLER)
1184*b8f0970dSRoderick Colenbrander 		return navigation_mapping(hdev, hi, field, usage, bit, max);
1185*b8f0970dSRoderick Colenbrander 
1186e19a267bSRoderick Colenbrander 	if (sc->quirks & SIXAXIS_CONTROLLER)
1187e19a267bSRoderick Colenbrander 		return sixaxis_mapping(hdev, hi, field, usage, bit, max);
11889131f8ccSRoderick Colenbrander 
11899131f8ccSRoderick Colenbrander 	if (sc->quirks & DUALSHOCK4_CONTROLLER)
11909131f8ccSRoderick Colenbrander 		return ds4_mapping(hdev, hi, field, usage, bit, max);
11919131f8ccSRoderick Colenbrander 
1192e19a267bSRoderick Colenbrander 
11936f498018SBenjamin Tissoires 	/* Let hid-core decide for the others */
11946f498018SBenjamin Tissoires 	return 0;
1195f04d5140SColin Leitner }
1196f04d5140SColin Leitner 
1197ac797b95SRoderick Colenbrander static int sony_register_touchpad(struct sony_sc *sc, int touch_count,
1198ce8efc3bSFrank Praznik 					int w, int h)
1199ce8efc3bSFrank Praznik {
1200ac797b95SRoderick Colenbrander 	size_t name_sz;
1201ac797b95SRoderick Colenbrander 	char *name;
1202ce8efc3bSFrank Praznik 	int ret;
1203ce8efc3bSFrank Praznik 
1204ac797b95SRoderick Colenbrander 	sc->touchpad = input_allocate_device();
1205ac797b95SRoderick Colenbrander 	if (!sc->touchpad)
1206ac797b95SRoderick Colenbrander 		return -ENOMEM;
1207ce8efc3bSFrank Praznik 
1208ac797b95SRoderick Colenbrander 	input_set_drvdata(sc->touchpad, sc);
1209ac797b95SRoderick Colenbrander 	sc->touchpad->dev.parent = &sc->hdev->dev;
1210ac797b95SRoderick Colenbrander 	sc->touchpad->phys = sc->hdev->phys;
1211ac797b95SRoderick Colenbrander 	sc->touchpad->uniq = sc->hdev->uniq;
1212ac797b95SRoderick Colenbrander 	sc->touchpad->id.bustype = sc->hdev->bus;
1213ac797b95SRoderick Colenbrander 	sc->touchpad->id.vendor = sc->hdev->vendor;
1214ac797b95SRoderick Colenbrander 	sc->touchpad->id.product = sc->hdev->product;
1215ac797b95SRoderick Colenbrander 	sc->touchpad->id.version = sc->hdev->version;
1216ac797b95SRoderick Colenbrander 
1217ac797b95SRoderick Colenbrander 	/* Append a suffix to the controller name as there are various
1218ac797b95SRoderick Colenbrander 	 * DS4 compatible non-Sony devices with different names.
1219ac797b95SRoderick Colenbrander 	 */
1220ac797b95SRoderick Colenbrander 	name_sz = strlen(sc->hdev->name) + sizeof(DS4_TOUCHPAD_SUFFIX);
1221ac797b95SRoderick Colenbrander 	name = kzalloc(name_sz, GFP_KERNEL);
1222ac797b95SRoderick Colenbrander 	if (!name) {
1223ac797b95SRoderick Colenbrander 		ret = -ENOMEM;
1224ac797b95SRoderick Colenbrander 		goto err;
1225ac797b95SRoderick Colenbrander 	}
1226ac797b95SRoderick Colenbrander 	snprintf(name, name_sz, "%s" DS4_TOUCHPAD_SUFFIX, sc->hdev->name);
1227ac797b95SRoderick Colenbrander 	sc->touchpad->name = name;
1228ac797b95SRoderick Colenbrander 
1229b9f7d245SRoderick Colenbrander 	ret = input_mt_init_slots(sc->touchpad, touch_count, INPUT_MT_POINTER);
1230ac797b95SRoderick Colenbrander 	if (ret < 0)
1231ac797b95SRoderick Colenbrander 		goto err;
1232ac797b95SRoderick Colenbrander 
1233ac797b95SRoderick Colenbrander 	/* We map the button underneath the touchpad to BTN_LEFT. */
1234ac797b95SRoderick Colenbrander 	__set_bit(EV_KEY, sc->touchpad->evbit);
1235ac797b95SRoderick Colenbrander 	__set_bit(BTN_LEFT, sc->touchpad->keybit);
1236ac797b95SRoderick Colenbrander 	__set_bit(INPUT_PROP_BUTTONPAD, sc->touchpad->propbit);
1237ac797b95SRoderick Colenbrander 
1238ac797b95SRoderick Colenbrander 	input_set_abs_params(sc->touchpad, ABS_MT_POSITION_X, 0, w, 0, 0);
1239ac797b95SRoderick Colenbrander 	input_set_abs_params(sc->touchpad, ABS_MT_POSITION_Y, 0, h, 0, 0);
1240ac797b95SRoderick Colenbrander 
1241ac797b95SRoderick Colenbrander 	ret = input_register_device(sc->touchpad);
1242ac797b95SRoderick Colenbrander 	if (ret < 0)
1243ac797b95SRoderick Colenbrander 		goto err;
1244ce8efc3bSFrank Praznik 
1245ce8efc3bSFrank Praznik 	return 0;
1246ac797b95SRoderick Colenbrander 
1247ac797b95SRoderick Colenbrander err:
1248ac797b95SRoderick Colenbrander 	kfree(sc->touchpad->name);
1249ac797b95SRoderick Colenbrander 	sc->touchpad->name = NULL;
1250ac797b95SRoderick Colenbrander 
1251ac797b95SRoderick Colenbrander 	input_free_device(sc->touchpad);
1252ac797b95SRoderick Colenbrander 	sc->touchpad = NULL;
1253ac797b95SRoderick Colenbrander 
1254ac797b95SRoderick Colenbrander 	return ret;
1255ce8efc3bSFrank Praznik }
1256ce8efc3bSFrank Praznik 
1257ac797b95SRoderick Colenbrander static void sony_unregister_touchpad(struct sony_sc *sc)
1258ac797b95SRoderick Colenbrander {
1259ac797b95SRoderick Colenbrander 	if (!sc->touchpad)
1260ac797b95SRoderick Colenbrander 		return;
1261ac797b95SRoderick Colenbrander 
1262ac797b95SRoderick Colenbrander 	kfree(sc->touchpad->name);
1263ac797b95SRoderick Colenbrander 	sc->touchpad->name = NULL;
1264ac797b95SRoderick Colenbrander 
1265ac797b95SRoderick Colenbrander 	input_unregister_device(sc->touchpad);
1266ac797b95SRoderick Colenbrander 	sc->touchpad = NULL;
1267ac797b95SRoderick Colenbrander }
12689154301aSDmitry Torokhov 
1269227c011bSRoderick Colenbrander static int sony_register_sensors(struct sony_sc *sc)
1270227c011bSRoderick Colenbrander {
1271227c011bSRoderick Colenbrander 	size_t name_sz;
1272227c011bSRoderick Colenbrander 	char *name;
1273227c011bSRoderick Colenbrander 	int ret;
127455a07d62SRoderick Colenbrander 	int range;
1275227c011bSRoderick Colenbrander 
1276227c011bSRoderick Colenbrander 	sc->sensor_dev = input_allocate_device();
1277227c011bSRoderick Colenbrander 	if (!sc->sensor_dev)
1278227c011bSRoderick Colenbrander 		return -ENOMEM;
1279227c011bSRoderick Colenbrander 
1280227c011bSRoderick Colenbrander 	input_set_drvdata(sc->sensor_dev, sc);
1281227c011bSRoderick Colenbrander 	sc->sensor_dev->dev.parent = &sc->hdev->dev;
1282227c011bSRoderick Colenbrander 	sc->sensor_dev->phys = sc->hdev->phys;
1283227c011bSRoderick Colenbrander 	sc->sensor_dev->uniq = sc->hdev->uniq;
1284227c011bSRoderick Colenbrander 	sc->sensor_dev->id.bustype = sc->hdev->bus;
1285227c011bSRoderick Colenbrander 	sc->sensor_dev->id.vendor = sc->hdev->vendor;
1286227c011bSRoderick Colenbrander 	sc->sensor_dev->id.product = sc->hdev->product;
1287227c011bSRoderick Colenbrander 	sc->sensor_dev->id.version = sc->hdev->version;
1288227c011bSRoderick Colenbrander 
1289227c011bSRoderick Colenbrander 	/* Append a suffix to the controller name as there are various
1290227c011bSRoderick Colenbrander 	 * DS4 compatible non-Sony devices with different names.
1291227c011bSRoderick Colenbrander 	 */
1292510c8b7cSRoderick Colenbrander 	name_sz = strlen(sc->hdev->name) + sizeof(SENSOR_SUFFIX);
1293227c011bSRoderick Colenbrander 	name = kzalloc(name_sz, GFP_KERNEL);
1294227c011bSRoderick Colenbrander 	if (!name) {
1295227c011bSRoderick Colenbrander 		ret = -ENOMEM;
1296227c011bSRoderick Colenbrander 		goto err;
1297227c011bSRoderick Colenbrander 	}
1298510c8b7cSRoderick Colenbrander 	snprintf(name, name_sz, "%s" SENSOR_SUFFIX, sc->hdev->name);
1299227c011bSRoderick Colenbrander 	sc->sensor_dev->name = name;
1300227c011bSRoderick Colenbrander 
1301510c8b7cSRoderick Colenbrander 	if (sc->quirks & SIXAXIS_CONTROLLER) {
1302510c8b7cSRoderick Colenbrander 		/* For the DS3 we only support the accelerometer, which works
1303510c8b7cSRoderick Colenbrander 		 * quite well even without calibration. The device also has
1304510c8b7cSRoderick Colenbrander 		 * a 1-axis gyro, but it is very difficult to manage from within
1305510c8b7cSRoderick Colenbrander 		 * the driver even to get data, the sensor is inaccurate and
1306510c8b7cSRoderick Colenbrander 		 * the behavior is very different between hardware revisions.
1307510c8b7cSRoderick Colenbrander 		 */
1308510c8b7cSRoderick Colenbrander 		input_set_abs_params(sc->sensor_dev, ABS_X, -512, 511, 4, 0);
1309510c8b7cSRoderick Colenbrander 		input_set_abs_params(sc->sensor_dev, ABS_Y, -512, 511, 4, 0);
1310510c8b7cSRoderick Colenbrander 		input_set_abs_params(sc->sensor_dev, ABS_Z, -512, 511, 4, 0);
1311510c8b7cSRoderick Colenbrander 		input_abs_set_res(sc->sensor_dev, ABS_X, SIXAXIS_ACC_RES_PER_G);
1312510c8b7cSRoderick Colenbrander 		input_abs_set_res(sc->sensor_dev, ABS_Y, SIXAXIS_ACC_RES_PER_G);
1313510c8b7cSRoderick Colenbrander 		input_abs_set_res(sc->sensor_dev, ABS_Z, SIXAXIS_ACC_RES_PER_G);
1314510c8b7cSRoderick Colenbrander 	} else if (sc->quirks & DUALSHOCK4_CONTROLLER) {
131555a07d62SRoderick Colenbrander 		range = DS4_ACC_RES_PER_G*4;
131655a07d62SRoderick Colenbrander 		input_set_abs_params(sc->sensor_dev, ABS_X, -range, range, 16, 0);
131755a07d62SRoderick Colenbrander 		input_set_abs_params(sc->sensor_dev, ABS_Y, -range, range, 16, 0);
131855a07d62SRoderick Colenbrander 		input_set_abs_params(sc->sensor_dev, ABS_Z, -range, range, 16, 0);
131955a07d62SRoderick Colenbrander 		input_abs_set_res(sc->sensor_dev, ABS_X, DS4_ACC_RES_PER_G);
132055a07d62SRoderick Colenbrander 		input_abs_set_res(sc->sensor_dev, ABS_Y, DS4_ACC_RES_PER_G);
132155a07d62SRoderick Colenbrander 		input_abs_set_res(sc->sensor_dev, ABS_Z, DS4_ACC_RES_PER_G);
1322227c011bSRoderick Colenbrander 
132355a07d62SRoderick Colenbrander 		range = DS4_GYRO_RES_PER_DEG_S*2048;
132455a07d62SRoderick Colenbrander 		input_set_abs_params(sc->sensor_dev, ABS_RX, -range, range, 16, 0);
132555a07d62SRoderick Colenbrander 		input_set_abs_params(sc->sensor_dev, ABS_RY, -range, range, 16, 0);
132655a07d62SRoderick Colenbrander 		input_set_abs_params(sc->sensor_dev, ABS_RZ, -range, range, 16, 0);
132755a07d62SRoderick Colenbrander 		input_abs_set_res(sc->sensor_dev, ABS_RX, DS4_GYRO_RES_PER_DEG_S);
132855a07d62SRoderick Colenbrander 		input_abs_set_res(sc->sensor_dev, ABS_RY, DS4_GYRO_RES_PER_DEG_S);
132955a07d62SRoderick Colenbrander 		input_abs_set_res(sc->sensor_dev, ABS_RZ, DS4_GYRO_RES_PER_DEG_S);
1330227c011bSRoderick Colenbrander 
133180786eb9SRoderick Colenbrander 		__set_bit(EV_MSC, sc->sensor_dev->evbit);
133280786eb9SRoderick Colenbrander 		__set_bit(MSC_TIMESTAMP, sc->sensor_dev->mscbit);
1333510c8b7cSRoderick Colenbrander 	}
1334510c8b7cSRoderick Colenbrander 
1335227c011bSRoderick Colenbrander 	__set_bit(INPUT_PROP_ACCELEROMETER, sc->sensor_dev->propbit);
1336227c011bSRoderick Colenbrander 
1337227c011bSRoderick Colenbrander 	ret = input_register_device(sc->sensor_dev);
1338227c011bSRoderick Colenbrander 	if (ret < 0)
1339227c011bSRoderick Colenbrander 		goto err;
1340227c011bSRoderick Colenbrander 
1341227c011bSRoderick Colenbrander 	return 0;
1342227c011bSRoderick Colenbrander 
1343227c011bSRoderick Colenbrander err:
1344227c011bSRoderick Colenbrander 	kfree(sc->sensor_dev->name);
1345227c011bSRoderick Colenbrander 	sc->sensor_dev->name = NULL;
1346227c011bSRoderick Colenbrander 
1347227c011bSRoderick Colenbrander 	input_free_device(sc->sensor_dev);
1348227c011bSRoderick Colenbrander 	sc->sensor_dev = NULL;
1349227c011bSRoderick Colenbrander 
1350227c011bSRoderick Colenbrander 	return ret;
1351227c011bSRoderick Colenbrander }
1352227c011bSRoderick Colenbrander 
1353227c011bSRoderick Colenbrander static void sony_unregister_sensors(struct sony_sc *sc)
1354227c011bSRoderick Colenbrander {
1355227c011bSRoderick Colenbrander 	if (!sc->sensor_dev)
1356227c011bSRoderick Colenbrander 		return;
1357227c011bSRoderick Colenbrander 
1358227c011bSRoderick Colenbrander 	kfree(sc->sensor_dev->name);
1359227c011bSRoderick Colenbrander 	sc->sensor_dev->name = NULL;
1360227c011bSRoderick Colenbrander 
1361227c011bSRoderick Colenbrander 	input_unregister_device(sc->sensor_dev);
1362227c011bSRoderick Colenbrander 	sc->sensor_dev = NULL;
1363227c011bSRoderick Colenbrander }
1364227c011bSRoderick Colenbrander 
1365227c011bSRoderick Colenbrander 
13665710fabfSAntonio Ospite /*
1367bd28ce00SJiri Slaby  * Sending HID_REQ_GET_REPORT changes the operation mode of the ps3 controller
1368bd28ce00SJiri Slaby  * to "operational".  Without this, the ps3 controller will not report any
1369bd28ce00SJiri Slaby  * events.
1370bd28ce00SJiri Slaby  */
1371816651a7SAntonio Ospite static int sixaxis_set_operational_usb(struct hid_device *hdev)
1372bd28ce00SJiri Slaby {
1373a85d67b5SAntonio Ospite 	const int buf_size =
1374a85d67b5SAntonio Ospite 		max(SIXAXIS_REPORT_0xF2_SIZE, SIXAXIS_REPORT_0xF5_SIZE);
13751adf904eSPavel Machek 	u8 *buf;
1376bd28ce00SJiri Slaby 	int ret;
1377bd28ce00SJiri Slaby 
13782e701a35SAntonio Ospite 	buf = kmalloc(buf_size, GFP_KERNEL);
1379bd28ce00SJiri Slaby 	if (!buf)
1380bd28ce00SJiri Slaby 		return -ENOMEM;
1381bd28ce00SJiri Slaby 
1382a85d67b5SAntonio Ospite 	ret = hid_hw_raw_request(hdev, 0xf2, buf, SIXAXIS_REPORT_0xF2_SIZE,
1383a85d67b5SAntonio Ospite 				 HID_FEATURE_REPORT, HID_REQ_GET_REPORT);
1384a7de9b86SLauri Kasanen 	if (ret < 0) {
1385a7de9b86SLauri Kasanen 		hid_err(hdev, "can't set operational mode: step 1\n");
1386a7de9b86SLauri Kasanen 		goto out;
1387a7de9b86SLauri Kasanen 	}
1388f204828aSBenjamin Tissoires 
1389a7de9b86SLauri Kasanen 	/*
1390a7de9b86SLauri Kasanen 	 * Some compatible controllers like the Speedlink Strike FX and
1391a7de9b86SLauri Kasanen 	 * Gasia need another query plus an USB interrupt to get operational.
1392a7de9b86SLauri Kasanen 	 */
1393a85d67b5SAntonio Ospite 	ret = hid_hw_raw_request(hdev, 0xf5, buf, SIXAXIS_REPORT_0xF5_SIZE,
1394a85d67b5SAntonio Ospite 				 HID_FEATURE_REPORT, HID_REQ_GET_REPORT);
1395a7de9b86SLauri Kasanen 	if (ret < 0) {
1396a7de9b86SLauri Kasanen 		hid_err(hdev, "can't set operational mode: step 2\n");
1397a7de9b86SLauri Kasanen 		goto out;
1398a7de9b86SLauri Kasanen 	}
1399a7de9b86SLauri Kasanen 
1400a7de9b86SLauri Kasanen 	ret = hid_hw_output_report(hdev, buf, 1);
140119f4c2baSBenjamin Tissoires 	if (ret < 0) {
140219f4c2baSBenjamin Tissoires 		hid_info(hdev, "can't set operational mode: step 3, ignoring\n");
140319f4c2baSBenjamin Tissoires 		ret = 0;
140419f4c2baSBenjamin Tissoires 	}
1405bd28ce00SJiri Slaby 
1406a7de9b86SLauri Kasanen out:
1407bd28ce00SJiri Slaby 	kfree(buf);
1408bd28ce00SJiri Slaby 
1409bd28ce00SJiri Slaby 	return ret;
1410bd28ce00SJiri Slaby }
1411bd28ce00SJiri Slaby 
1412816651a7SAntonio Ospite static int sixaxis_set_operational_bt(struct hid_device *hdev)
1413f9ce7c28SBastien Nocera {
14141adf904eSPavel Machek 	static const u8 report[] = { 0xf4, 0x42, 0x03, 0x00, 0x00 };
14151adf904eSPavel Machek 	u8 *buf;
14169b2b5c9aSFrank Praznik 	int ret;
14179b2b5c9aSFrank Praznik 
14189b2b5c9aSFrank Praznik 	buf = kmemdup(report, sizeof(report), GFP_KERNEL);
14199b2b5c9aSFrank Praznik 	if (!buf)
14209b2b5c9aSFrank Praznik 		return -ENOMEM;
14219b2b5c9aSFrank Praznik 
14229b2b5c9aSFrank Praznik 	ret = hid_hw_raw_request(hdev, buf[0], buf, sizeof(report),
1423b0dd72aaSBenjamin Tissoires 				  HID_FEATURE_REPORT, HID_REQ_SET_REPORT);
14249b2b5c9aSFrank Praznik 
14259b2b5c9aSFrank Praznik 	kfree(buf);
14269b2b5c9aSFrank Praznik 
14279b2b5c9aSFrank Praznik 	return ret;
1428f9ce7c28SBastien Nocera }
1429f9ce7c28SBastien Nocera 
1430ad142b9eSFrank Praznik /*
143155a07d62SRoderick Colenbrander  * Request DS4 calibration data for the motion sensors.
143255a07d62SRoderick Colenbrander  * For Bluetooth this also affects the operating mode (see below).
143368330d83SFrank Praznik  */
143455a07d62SRoderick Colenbrander static int dualshock4_get_calibration_data(struct sony_sc *sc)
143568330d83SFrank Praznik {
14361adf904eSPavel Machek 	u8 *buf;
14379b2b5c9aSFrank Praznik 	int ret;
143855a07d62SRoderick Colenbrander 	short gyro_pitch_bias, gyro_pitch_plus, gyro_pitch_minus;
143955a07d62SRoderick Colenbrander 	short gyro_yaw_bias, gyro_yaw_plus, gyro_yaw_minus;
144055a07d62SRoderick Colenbrander 	short gyro_roll_bias, gyro_roll_plus, gyro_roll_minus;
144155a07d62SRoderick Colenbrander 	short gyro_speed_plus, gyro_speed_minus;
144255a07d62SRoderick Colenbrander 	short acc_x_plus, acc_x_minus;
144355a07d62SRoderick Colenbrander 	short acc_y_plus, acc_y_minus;
144455a07d62SRoderick Colenbrander 	short acc_z_plus, acc_z_minus;
144555a07d62SRoderick Colenbrander 	int speed_2x;
144655a07d62SRoderick Colenbrander 	int range_2g;
144768330d83SFrank Praznik 
144855a07d62SRoderick Colenbrander 	/* For Bluetooth we use a different request, which supports CRC.
144955a07d62SRoderick Colenbrander 	 * Note: in Bluetooth mode feature report 0x02 also changes the state
145055a07d62SRoderick Colenbrander 	 * of the controller, so that it sends input reports of type 0x11.
145155a07d62SRoderick Colenbrander 	 */
145235f436c3SRoderick Colenbrander 	if (sc->quirks & (DUALSHOCK4_CONTROLLER_USB | DUALSHOCK4_DONGLE)) {
14532c159de0SRoderick Colenbrander 		buf = kmalloc(DS4_FEATURE_REPORT_0x02_SIZE, GFP_KERNEL);
14549b2b5c9aSFrank Praznik 		if (!buf)
14559b2b5c9aSFrank Praznik 			return -ENOMEM;
14569b2b5c9aSFrank Praznik 
145755a07d62SRoderick Colenbrander 		ret = hid_hw_raw_request(sc->hdev, 0x02, buf,
145855a07d62SRoderick Colenbrander 					 DS4_FEATURE_REPORT_0x02_SIZE,
145955a07d62SRoderick Colenbrander 					 HID_FEATURE_REPORT,
146055a07d62SRoderick Colenbrander 					 HID_REQ_GET_REPORT);
146155a07d62SRoderick Colenbrander 		if (ret < 0)
146255a07d62SRoderick Colenbrander 			goto err_stop;
146355a07d62SRoderick Colenbrander 	} else {
146455a07d62SRoderick Colenbrander 		u8 bthdr = 0xA3;
146555a07d62SRoderick Colenbrander 		u32 crc;
146655a07d62SRoderick Colenbrander 		u32 report_crc;
146755a07d62SRoderick Colenbrander 		int retries;
14689b2b5c9aSFrank Praznik 
146955a07d62SRoderick Colenbrander 		buf = kmalloc(DS4_FEATURE_REPORT_0x05_SIZE, GFP_KERNEL);
147055a07d62SRoderick Colenbrander 		if (!buf)
147155a07d62SRoderick Colenbrander 			return -ENOMEM;
147255a07d62SRoderick Colenbrander 
147355a07d62SRoderick Colenbrander 		for (retries = 0; retries < 3; retries++) {
147455a07d62SRoderick Colenbrander 			ret = hid_hw_raw_request(sc->hdev, 0x05, buf,
147555a07d62SRoderick Colenbrander 						 DS4_FEATURE_REPORT_0x05_SIZE,
147655a07d62SRoderick Colenbrander 						 HID_FEATURE_REPORT,
147755a07d62SRoderick Colenbrander 						 HID_REQ_GET_REPORT);
147855a07d62SRoderick Colenbrander 			if (ret < 0)
147955a07d62SRoderick Colenbrander 				goto err_stop;
148055a07d62SRoderick Colenbrander 
148155a07d62SRoderick Colenbrander 			/* CRC check */
148255a07d62SRoderick Colenbrander 			crc = crc32_le(0xFFFFFFFF, &bthdr, 1);
148355a07d62SRoderick Colenbrander 			crc = ~crc32_le(crc, buf, DS4_FEATURE_REPORT_0x05_SIZE-4);
148455a07d62SRoderick Colenbrander 			report_crc = get_unaligned_le32(&buf[DS4_FEATURE_REPORT_0x05_SIZE-4]);
148555a07d62SRoderick Colenbrander 			if (crc != report_crc) {
148655a07d62SRoderick Colenbrander 				hid_warn(sc->hdev, "DualShock 4 calibration report's CRC check failed, received crc 0x%0x != 0x%0x\n",
148755a07d62SRoderick Colenbrander 					report_crc, crc);
148855a07d62SRoderick Colenbrander 				if (retries < 2) {
148955a07d62SRoderick Colenbrander 					hid_warn(sc->hdev, "Retrying DualShock 4 get calibration report request\n");
149055a07d62SRoderick Colenbrander 					continue;
149155a07d62SRoderick Colenbrander 				} else {
149255a07d62SRoderick Colenbrander 					ret = -EILSEQ;
149355a07d62SRoderick Colenbrander 					goto err_stop;
149455a07d62SRoderick Colenbrander 				}
149555a07d62SRoderick Colenbrander 			} else {
149655a07d62SRoderick Colenbrander 				break;
149755a07d62SRoderick Colenbrander 			}
149855a07d62SRoderick Colenbrander 		}
149955a07d62SRoderick Colenbrander 	}
150055a07d62SRoderick Colenbrander 
150155a07d62SRoderick Colenbrander 	gyro_pitch_bias  = get_unaligned_le16(&buf[1]);
150255a07d62SRoderick Colenbrander 	gyro_yaw_bias    = get_unaligned_le16(&buf[3]);
150355a07d62SRoderick Colenbrander 	gyro_roll_bias   = get_unaligned_le16(&buf[5]);
150455a07d62SRoderick Colenbrander 	if (sc->quirks & DUALSHOCK4_CONTROLLER_USB) {
150555a07d62SRoderick Colenbrander 		gyro_pitch_plus  = get_unaligned_le16(&buf[7]);
150655a07d62SRoderick Colenbrander 		gyro_pitch_minus = get_unaligned_le16(&buf[9]);
150755a07d62SRoderick Colenbrander 		gyro_yaw_plus    = get_unaligned_le16(&buf[11]);
150855a07d62SRoderick Colenbrander 		gyro_yaw_minus   = get_unaligned_le16(&buf[13]);
150955a07d62SRoderick Colenbrander 		gyro_roll_plus   = get_unaligned_le16(&buf[15]);
151055a07d62SRoderick Colenbrander 		gyro_roll_minus  = get_unaligned_le16(&buf[17]);
151155a07d62SRoderick Colenbrander 	} else {
151235f436c3SRoderick Colenbrander 		/* BT + Dongle */
151355a07d62SRoderick Colenbrander 		gyro_pitch_plus  = get_unaligned_le16(&buf[7]);
151455a07d62SRoderick Colenbrander 		gyro_yaw_plus    = get_unaligned_le16(&buf[9]);
151555a07d62SRoderick Colenbrander 		gyro_roll_plus   = get_unaligned_le16(&buf[11]);
151655a07d62SRoderick Colenbrander 		gyro_pitch_minus = get_unaligned_le16(&buf[13]);
151755a07d62SRoderick Colenbrander 		gyro_yaw_minus   = get_unaligned_le16(&buf[15]);
151855a07d62SRoderick Colenbrander 		gyro_roll_minus  = get_unaligned_le16(&buf[17]);
151955a07d62SRoderick Colenbrander 	}
152055a07d62SRoderick Colenbrander 	gyro_speed_plus  = get_unaligned_le16(&buf[19]);
152155a07d62SRoderick Colenbrander 	gyro_speed_minus = get_unaligned_le16(&buf[21]);
152255a07d62SRoderick Colenbrander 	acc_x_plus       = get_unaligned_le16(&buf[23]);
152355a07d62SRoderick Colenbrander 	acc_x_minus      = get_unaligned_le16(&buf[25]);
152455a07d62SRoderick Colenbrander 	acc_y_plus       = get_unaligned_le16(&buf[27]);
152555a07d62SRoderick Colenbrander 	acc_y_minus      = get_unaligned_le16(&buf[29]);
152655a07d62SRoderick Colenbrander 	acc_z_plus       = get_unaligned_le16(&buf[31]);
152755a07d62SRoderick Colenbrander 	acc_z_minus      = get_unaligned_le16(&buf[33]);
152855a07d62SRoderick Colenbrander 
152955a07d62SRoderick Colenbrander 	/* Set gyroscope calibration and normalization parameters.
153055a07d62SRoderick Colenbrander 	 * Data values will be normalized to 1/DS4_GYRO_RES_PER_DEG_S degree/s.
153155a07d62SRoderick Colenbrander 	 */
153255a07d62SRoderick Colenbrander 	speed_2x = (gyro_speed_plus + gyro_speed_minus);
153355a07d62SRoderick Colenbrander 	sc->ds4_calib_data[0].abs_code = ABS_RX;
153455a07d62SRoderick Colenbrander 	sc->ds4_calib_data[0].bias = gyro_pitch_bias;
153555a07d62SRoderick Colenbrander 	sc->ds4_calib_data[0].sens_numer = speed_2x*DS4_GYRO_RES_PER_DEG_S;
153655a07d62SRoderick Colenbrander 	sc->ds4_calib_data[0].sens_denom = gyro_pitch_plus - gyro_pitch_minus;
153755a07d62SRoderick Colenbrander 
153855a07d62SRoderick Colenbrander 	sc->ds4_calib_data[1].abs_code = ABS_RY;
153955a07d62SRoderick Colenbrander 	sc->ds4_calib_data[1].bias = gyro_yaw_bias;
154055a07d62SRoderick Colenbrander 	sc->ds4_calib_data[1].sens_numer = speed_2x*DS4_GYRO_RES_PER_DEG_S;
154155a07d62SRoderick Colenbrander 	sc->ds4_calib_data[1].sens_denom = gyro_yaw_plus - gyro_yaw_minus;
154255a07d62SRoderick Colenbrander 
154355a07d62SRoderick Colenbrander 	sc->ds4_calib_data[2].abs_code = ABS_RZ;
154455a07d62SRoderick Colenbrander 	sc->ds4_calib_data[2].bias = gyro_roll_bias;
154555a07d62SRoderick Colenbrander 	sc->ds4_calib_data[2].sens_numer = speed_2x*DS4_GYRO_RES_PER_DEG_S;
154655a07d62SRoderick Colenbrander 	sc->ds4_calib_data[2].sens_denom = gyro_roll_plus - gyro_roll_minus;
154755a07d62SRoderick Colenbrander 
154855a07d62SRoderick Colenbrander 	/* Set accelerometer calibration and normalization parameters.
154955a07d62SRoderick Colenbrander 	 * Data values will be normalized to 1/DS4_ACC_RES_PER_G G.
155055a07d62SRoderick Colenbrander 	 */
155155a07d62SRoderick Colenbrander 	range_2g = acc_x_plus - acc_x_minus;
155255a07d62SRoderick Colenbrander 	sc->ds4_calib_data[3].abs_code = ABS_X;
155355a07d62SRoderick Colenbrander 	sc->ds4_calib_data[3].bias = acc_x_plus - range_2g / 2;
155455a07d62SRoderick Colenbrander 	sc->ds4_calib_data[3].sens_numer = 2*DS4_ACC_RES_PER_G;
155555a07d62SRoderick Colenbrander 	sc->ds4_calib_data[3].sens_denom = range_2g;
155655a07d62SRoderick Colenbrander 
155755a07d62SRoderick Colenbrander 	range_2g = acc_y_plus - acc_y_minus;
155855a07d62SRoderick Colenbrander 	sc->ds4_calib_data[4].abs_code = ABS_Y;
155955a07d62SRoderick Colenbrander 	sc->ds4_calib_data[4].bias = acc_y_plus - range_2g / 2;
156055a07d62SRoderick Colenbrander 	sc->ds4_calib_data[4].sens_numer = 2*DS4_ACC_RES_PER_G;
156155a07d62SRoderick Colenbrander 	sc->ds4_calib_data[4].sens_denom = range_2g;
156255a07d62SRoderick Colenbrander 
156355a07d62SRoderick Colenbrander 	range_2g = acc_z_plus - acc_z_minus;
156455a07d62SRoderick Colenbrander 	sc->ds4_calib_data[5].abs_code = ABS_Z;
156555a07d62SRoderick Colenbrander 	sc->ds4_calib_data[5].bias = acc_z_plus - range_2g / 2;
156655a07d62SRoderick Colenbrander 	sc->ds4_calib_data[5].sens_numer = 2*DS4_ACC_RES_PER_G;
156755a07d62SRoderick Colenbrander 	sc->ds4_calib_data[5].sens_denom = range_2g;
156855a07d62SRoderick Colenbrander 
156955a07d62SRoderick Colenbrander err_stop:
15709b2b5c9aSFrank Praznik 	kfree(buf);
15719b2b5c9aSFrank Praznik 	return ret;
1572bd28ce00SJiri Slaby }
1573bd28ce00SJiri Slaby 
1574f2f47c38SRoderick Colenbrander static void dualshock4_calibration_work(struct work_struct *work)
1575f2f47c38SRoderick Colenbrander {
1576f2f47c38SRoderick Colenbrander 	struct sony_sc *sc = container_of(work, struct sony_sc, hotplug_worker);
1577f2f47c38SRoderick Colenbrander 	unsigned long flags;
1578f2f47c38SRoderick Colenbrander 	enum ds4_dongle_state dongle_state;
1579f2f47c38SRoderick Colenbrander 	int ret;
1580f2f47c38SRoderick Colenbrander 
1581f2f47c38SRoderick Colenbrander 	ret = dualshock4_get_calibration_data(sc);
1582f2f47c38SRoderick Colenbrander 	if (ret < 0) {
1583f2f47c38SRoderick Colenbrander 		/* This call is very unlikely to fail for the dongle. When it
1584f2f47c38SRoderick Colenbrander 		 * fails we are probably in a very bad state, so mark the
1585f2f47c38SRoderick Colenbrander 		 * dongle as disabled. We will re-enable the dongle if a new
1586f2f47c38SRoderick Colenbrander 		 * DS4 hotplug is detect from sony_raw_event as any issues
1587f2f47c38SRoderick Colenbrander 		 * are likely resolved then (the dongle is quite stupid).
1588f2f47c38SRoderick Colenbrander 		 */
1589f2f47c38SRoderick Colenbrander 		hid_err(sc->hdev, "DualShock 4 USB dongle: calibration failed, disabling device\n");
1590f2f47c38SRoderick Colenbrander 		dongle_state = DONGLE_DISABLED;
1591f2f47c38SRoderick Colenbrander 	} else {
1592f2f47c38SRoderick Colenbrander 		hid_info(sc->hdev, "DualShock 4 USB dongle: calibration completed\n");
1593f2f47c38SRoderick Colenbrander 		dongle_state = DONGLE_CONNECTED;
1594f2f47c38SRoderick Colenbrander 	}
1595f2f47c38SRoderick Colenbrander 
1596f2f47c38SRoderick Colenbrander 	spin_lock_irqsave(&sc->lock, flags);
1597f2f47c38SRoderick Colenbrander 	sc->ds4_dongle_state = dongle_state;
1598f2f47c38SRoderick Colenbrander 	spin_unlock_irqrestore(&sc->lock, flags);
1599f2f47c38SRoderick Colenbrander }
1600f2f47c38SRoderick Colenbrander 
1601221399b3SFrank Praznik static void sixaxis_set_leds_from_id(struct sony_sc *sc)
16028025087aSFrank Praznik {
16031adf904eSPavel Machek 	static const u8 sixaxis_leds[10][4] = {
16048025087aSFrank Praznik 				{ 0x01, 0x00, 0x00, 0x00 },
16058025087aSFrank Praznik 				{ 0x00, 0x01, 0x00, 0x00 },
16068025087aSFrank Praznik 				{ 0x00, 0x00, 0x01, 0x00 },
16078025087aSFrank Praznik 				{ 0x00, 0x00, 0x00, 0x01 },
16088025087aSFrank Praznik 				{ 0x01, 0x00, 0x00, 0x01 },
16098025087aSFrank Praznik 				{ 0x00, 0x01, 0x00, 0x01 },
16108025087aSFrank Praznik 				{ 0x00, 0x00, 0x01, 0x01 },
16118025087aSFrank Praznik 				{ 0x01, 0x00, 0x01, 0x01 },
16128025087aSFrank Praznik 				{ 0x00, 0x01, 0x01, 0x01 },
16138025087aSFrank Praznik 				{ 0x01, 0x01, 0x01, 0x01 }
16148025087aSFrank Praznik 	};
16158025087aSFrank Praznik 
1616221399b3SFrank Praznik 	int id = sc->device_id;
1617221399b3SFrank Praznik 
1618221399b3SFrank Praznik 	BUILD_BUG_ON(MAX_LEDS < ARRAY_SIZE(sixaxis_leds[0]));
16198025087aSFrank Praznik 
16208025087aSFrank Praznik 	if (id < 0)
16218025087aSFrank Praznik 		return;
16228025087aSFrank Praznik 
16238025087aSFrank Praznik 	id %= 10;
1624221399b3SFrank Praznik 	memcpy(sc->led_state, sixaxis_leds[id], sizeof(sixaxis_leds[id]));
16258025087aSFrank Praznik }
16268025087aSFrank Praznik 
1627221399b3SFrank Praznik static void dualshock4_set_leds_from_id(struct sony_sc *sc)
16288025087aSFrank Praznik {
16298025087aSFrank Praznik 	/* The first 4 color/index entries match what the PS4 assigns */
16301adf904eSPavel Machek 	static const u8 color_code[7][3] = {
16318025087aSFrank Praznik 			/* Blue   */	{ 0x00, 0x00, 0x01 },
16328025087aSFrank Praznik 			/* Red	  */	{ 0x01, 0x00, 0x00 },
16338025087aSFrank Praznik 			/* Green  */	{ 0x00, 0x01, 0x00 },
16348025087aSFrank Praznik 			/* Pink   */	{ 0x02, 0x00, 0x01 },
16358025087aSFrank Praznik 			/* Orange */	{ 0x02, 0x01, 0x00 },
16368025087aSFrank Praznik 			/* Teal   */	{ 0x00, 0x01, 0x01 },
16378025087aSFrank Praznik 			/* White  */	{ 0x01, 0x01, 0x01 }
16388025087aSFrank Praznik 	};
16398025087aSFrank Praznik 
1640221399b3SFrank Praznik 	int id = sc->device_id;
1641221399b3SFrank Praznik 
1642221399b3SFrank Praznik 	BUILD_BUG_ON(MAX_LEDS < ARRAY_SIZE(color_code[0]));
16438025087aSFrank Praznik 
16448025087aSFrank Praznik 	if (id < 0)
16458025087aSFrank Praznik 		return;
16468025087aSFrank Praznik 
16478025087aSFrank Praznik 	id %= 7;
1648221399b3SFrank Praznik 	memcpy(sc->led_state, color_code[id], sizeof(color_code[id]));
16498025087aSFrank Praznik }
16508025087aSFrank Praznik 
1651221399b3SFrank Praznik static void buzz_set_leds(struct sony_sc *sc)
1652f04d5140SColin Leitner {
1653221399b3SFrank Praznik 	struct hid_device *hdev = sc->hdev;
1654f04d5140SColin Leitner 	struct list_head *report_list =
1655f04d5140SColin Leitner 		&hdev->report_enum[HID_OUTPUT_REPORT].report_list;
1656f04d5140SColin Leitner 	struct hid_report *report = list_entry(report_list->next,
1657f04d5140SColin Leitner 		struct hid_report, list);
16581adf904eSPavel Machek 	s32 *value = report->field[0]->value;
1659f04d5140SColin Leitner 
1660221399b3SFrank Praznik 	BUILD_BUG_ON(MAX_LEDS < 4);
1661221399b3SFrank Praznik 
1662f04d5140SColin Leitner 	value[0] = 0x00;
1663221399b3SFrank Praznik 	value[1] = sc->led_state[0] ? 0xff : 0x00;
1664221399b3SFrank Praznik 	value[2] = sc->led_state[1] ? 0xff : 0x00;
1665221399b3SFrank Praznik 	value[3] = sc->led_state[2] ? 0xff : 0x00;
1666221399b3SFrank Praznik 	value[4] = sc->led_state[3] ? 0xff : 0x00;
1667f04d5140SColin Leitner 	value[5] = 0x00;
1668f04d5140SColin Leitner 	value[6] = 0x00;
1669f04d5140SColin Leitner 	hid_hw_request(hdev, report, HID_REQ_SET_REPORT);
1670f04d5140SColin Leitner }
1671f04d5140SColin Leitner 
1672221399b3SFrank Praznik static void sony_set_leds(struct sony_sc *sc)
16730a286ef2SSven Eckelmann {
1674221399b3SFrank Praznik 	if (!(sc->quirks & BUZZ_CONTROLLER))
1675b5322736SRoderick Colenbrander 		sony_schedule_work(sc, SONY_WORKER_STATE);
1676221399b3SFrank Praznik 	else
1677221399b3SFrank Praznik 		buzz_set_leds(sc);
16780a286ef2SSven Eckelmann }
16790a286ef2SSven Eckelmann 
1680c5382519SSven Eckelmann static void sony_led_set_brightness(struct led_classdev *led,
1681f04d5140SColin Leitner 				    enum led_brightness value)
1682f04d5140SColin Leitner {
1683f04d5140SColin Leitner 	struct device *dev = led->dev->parent;
1684ee79a8f8SGeliang Tang 	struct hid_device *hdev = to_hid_device(dev);
1685f04d5140SColin Leitner 	struct sony_sc *drv_data;
1686f04d5140SColin Leitner 
1687f04d5140SColin Leitner 	int n;
1688b3ed458cSFrank Praznik 	int force_update;
1689f04d5140SColin Leitner 
1690f04d5140SColin Leitner 	drv_data = hid_get_drvdata(hdev);
16912251b85fSSven Eckelmann 	if (!drv_data) {
1692f04d5140SColin Leitner 		hid_err(hdev, "No device data\n");
1693f04d5140SColin Leitner 		return;
1694f04d5140SColin Leitner 	}
1695f04d5140SColin Leitner 
1696b3ed458cSFrank Praznik 	/*
1697b3ed458cSFrank Praznik 	 * The Sixaxis on USB will override any LED settings sent to it
1698b3ed458cSFrank Praznik 	 * and keep flashing all of the LEDs until the PS button is pressed.
1699b3ed458cSFrank Praznik 	 * Updates, even if redundant, must be always be sent to the
1700b3ed458cSFrank Praznik 	 * controller to avoid having to toggle the state of an LED just to
1701b3ed458cSFrank Praznik 	 * stop the flashing later on.
1702b3ed458cSFrank Praznik 	 */
1703b3ed458cSFrank Praznik 	force_update = !!(drv_data->quirks & SIXAXIS_CONTROLLER_USB);
1704b3ed458cSFrank Praznik 
170560781cf4SFrank Praznik 	for (n = 0; n < drv_data->led_count; n++) {
1706b3ed458cSFrank Praznik 		if (led == drv_data->leds[n] && (force_update ||
1707b3ed458cSFrank Praznik 			(value != drv_data->led_state[n] ||
1708b3ed458cSFrank Praznik 			drv_data->led_delay_on[n] ||
1709b3ed458cSFrank Praznik 			drv_data->led_delay_off[n]))) {
1710b3ed458cSFrank Praznik 
171160781cf4SFrank Praznik 			drv_data->led_state[n] = value;
1712b3ed458cSFrank Praznik 
1713b3ed458cSFrank Praznik 			/* Setting the brightness stops the blinking */
1714b3ed458cSFrank Praznik 			drv_data->led_delay_on[n] = 0;
1715b3ed458cSFrank Praznik 			drv_data->led_delay_off[n] = 0;
1716b3ed458cSFrank Praznik 
1717221399b3SFrank Praznik 			sony_set_leds(drv_data);
1718f04d5140SColin Leitner 			break;
1719f04d5140SColin Leitner 		}
1720f04d5140SColin Leitner 	}
1721f04d5140SColin Leitner }
1722f04d5140SColin Leitner 
1723c5382519SSven Eckelmann static enum led_brightness sony_led_get_brightness(struct led_classdev *led)
1724f04d5140SColin Leitner {
1725f04d5140SColin Leitner 	struct device *dev = led->dev->parent;
1726ee79a8f8SGeliang Tang 	struct hid_device *hdev = to_hid_device(dev);
1727f04d5140SColin Leitner 	struct sony_sc *drv_data;
1728f04d5140SColin Leitner 
1729f04d5140SColin Leitner 	int n;
1730f04d5140SColin Leitner 
1731f04d5140SColin Leitner 	drv_data = hid_get_drvdata(hdev);
17322251b85fSSven Eckelmann 	if (!drv_data) {
1733f04d5140SColin Leitner 		hid_err(hdev, "No device data\n");
1734f04d5140SColin Leitner 		return LED_OFF;
1735f04d5140SColin Leitner 	}
1736f04d5140SColin Leitner 
173760781cf4SFrank Praznik 	for (n = 0; n < drv_data->led_count; n++) {
17387db7504aSSimon Wood 		if (led == drv_data->leds[n])
17397db7504aSSimon Wood 			return drv_data->led_state[n];
1740f04d5140SColin Leitner 	}
1741f04d5140SColin Leitner 
17427db7504aSSimon Wood 	return LED_OFF;
1743f04d5140SColin Leitner }
1744f04d5140SColin Leitner 
1745b3ed458cSFrank Praznik static int sony_led_blink_set(struct led_classdev *led, unsigned long *delay_on,
1746b3ed458cSFrank Praznik 				unsigned long *delay_off)
1747b3ed458cSFrank Praznik {
1748b3ed458cSFrank Praznik 	struct device *dev = led->dev->parent;
1749ee79a8f8SGeliang Tang 	struct hid_device *hdev = to_hid_device(dev);
1750b3ed458cSFrank Praznik 	struct sony_sc *drv_data = hid_get_drvdata(hdev);
1751b3ed458cSFrank Praznik 	int n;
17521adf904eSPavel Machek 	u8 new_on, new_off;
1753b3ed458cSFrank Praznik 
1754b3ed458cSFrank Praznik 	if (!drv_data) {
1755b3ed458cSFrank Praznik 		hid_err(hdev, "No device data\n");
1756b3ed458cSFrank Praznik 		return -EINVAL;
1757b3ed458cSFrank Praznik 	}
1758b3ed458cSFrank Praznik 
1759b3ed458cSFrank Praznik 	/* Max delay is 255 deciseconds or 2550 milliseconds */
1760b3ed458cSFrank Praznik 	if (*delay_on > 2550)
1761b3ed458cSFrank Praznik 		*delay_on = 2550;
1762b3ed458cSFrank Praznik 	if (*delay_off > 2550)
1763b3ed458cSFrank Praznik 		*delay_off = 2550;
1764b3ed458cSFrank Praznik 
1765b3ed458cSFrank Praznik 	/* Blink at 1 Hz if both values are zero */
1766b3ed458cSFrank Praznik 	if (!*delay_on && !*delay_off)
1767b3ed458cSFrank Praznik 		*delay_on = *delay_off = 500;
1768b3ed458cSFrank Praznik 
1769b3ed458cSFrank Praznik 	new_on = *delay_on / 10;
1770b3ed458cSFrank Praznik 	new_off = *delay_off / 10;
1771b3ed458cSFrank Praznik 
1772b3ed458cSFrank Praznik 	for (n = 0; n < drv_data->led_count; n++) {
1773b3ed458cSFrank Praznik 		if (led == drv_data->leds[n])
1774b3ed458cSFrank Praznik 			break;
1775b3ed458cSFrank Praznik 	}
1776b3ed458cSFrank Praznik 
1777b3ed458cSFrank Praznik 	/* This LED is not registered on this device */
1778b3ed458cSFrank Praznik 	if (n >= drv_data->led_count)
1779b3ed458cSFrank Praznik 		return -EINVAL;
1780b3ed458cSFrank Praznik 
1781b3ed458cSFrank Praznik 	/* Don't schedule work if the values didn't change */
1782b3ed458cSFrank Praznik 	if (new_on != drv_data->led_delay_on[n] ||
1783b3ed458cSFrank Praznik 		new_off != drv_data->led_delay_off[n]) {
1784b3ed458cSFrank Praznik 		drv_data->led_delay_on[n] = new_on;
1785b3ed458cSFrank Praznik 		drv_data->led_delay_off[n] = new_off;
1786b5322736SRoderick Colenbrander 		sony_schedule_work(drv_data, SONY_WORKER_STATE);
1787b3ed458cSFrank Praznik 	}
1788b3ed458cSFrank Praznik 
1789b3ed458cSFrank Praznik 	return 0;
1790b3ed458cSFrank Praznik }
1791b3ed458cSFrank Praznik 
1792fa57a810SFrank Praznik static void sony_leds_remove(struct sony_sc *sc)
17930a286ef2SSven Eckelmann {
17940a286ef2SSven Eckelmann 	struct led_classdev *led;
17950a286ef2SSven Eckelmann 	int n;
17960a286ef2SSven Eckelmann 
1797fa57a810SFrank Praznik 	BUG_ON(!(sc->quirks & SONY_LED_SUPPORT));
17980a286ef2SSven Eckelmann 
1799fa57a810SFrank Praznik 	for (n = 0; n < sc->led_count; n++) {
1800fa57a810SFrank Praznik 		led = sc->leds[n];
1801fa57a810SFrank Praznik 		sc->leds[n] = NULL;
18020a286ef2SSven Eckelmann 		if (!led)
18030a286ef2SSven Eckelmann 			continue;
18040a286ef2SSven Eckelmann 		led_classdev_unregister(led);
18050a286ef2SSven Eckelmann 		kfree(led);
18060a286ef2SSven Eckelmann 	}
180760781cf4SFrank Praznik 
1808fa57a810SFrank Praznik 	sc->led_count = 0;
18090a286ef2SSven Eckelmann }
18100a286ef2SSven Eckelmann 
1811fa57a810SFrank Praznik static int sony_leds_init(struct sony_sc *sc)
1812f04d5140SColin Leitner {
1813fa57a810SFrank Praznik 	struct hid_device *hdev = sc->hdev;
181440e32ee6SJiri Kosina 	int n, ret = 0;
1815b3ed458cSFrank Praznik 	int use_ds4_names;
181640e32ee6SJiri Kosina 	struct led_classdev *led;
181740e32ee6SJiri Kosina 	size_t name_sz;
181840e32ee6SJiri Kosina 	char *name;
18190a286ef2SSven Eckelmann 	size_t name_len;
18200a286ef2SSven Eckelmann 	const char *name_fmt;
1821b3ed458cSFrank Praznik 	static const char * const ds4_name_str[] = { "red", "green", "blue",
1822b3ed458cSFrank Praznik 						  "global" };
18231adf904eSPavel Machek 	u8 max_brightness[MAX_LEDS] = { [0 ... (MAX_LEDS - 1)] = 1 };
18241adf904eSPavel Machek 	u8 use_hw_blink[MAX_LEDS] = { 0 };
1825f04d5140SColin Leitner 
1826fa57a810SFrank Praznik 	BUG_ON(!(sc->quirks & SONY_LED_SUPPORT));
1827f04d5140SColin Leitner 
1828fa57a810SFrank Praznik 	if (sc->quirks & BUZZ_CONTROLLER) {
1829fa57a810SFrank Praznik 		sc->led_count = 4;
1830b3ed458cSFrank Praznik 		use_ds4_names = 0;
18310a286ef2SSven Eckelmann 		name_len = strlen("::buzz#");
18320a286ef2SSven Eckelmann 		name_fmt = "%s::buzz%d";
18339446edb9SKees Cook 		/* Validate expected report characteristics. */
18349446edb9SKees Cook 		if (!hid_validate_values(hdev, HID_OUTPUT_REPORT, 0, 0, 7))
18359446edb9SKees Cook 			return -ENODEV;
1836fa57a810SFrank Praznik 	} else if (sc->quirks & DUALSHOCK4_CONTROLLER) {
1837221399b3SFrank Praznik 		dualshock4_set_leds_from_id(sc);
1838221399b3SFrank Praznik 		sc->led_state[3] = 1;
1839b3ed458cSFrank Praznik 		sc->led_count = 4;
1840b3ed458cSFrank Praznik 		memset(max_brightness, 255, 3);
1841b3ed458cSFrank Praznik 		use_hw_blink[3] = 1;
1842b3ed458cSFrank Praznik 		use_ds4_names = 1;
184361ebca93SFrank Praznik 		name_len = 0;
184461ebca93SFrank Praznik 		name_fmt = "%s:%s";
1845c5e0c1c4SFrank Praznik 	} else if (sc->quirks & MOTION_CONTROLLER) {
1846c5e0c1c4SFrank Praznik 		sc->led_count = 3;
1847c5e0c1c4SFrank Praznik 		memset(max_brightness, 255, 3);
1848c5e0c1c4SFrank Praznik 		use_ds4_names = 1;
1849c5e0c1c4SFrank Praznik 		name_len = 0;
1850c5e0c1c4SFrank Praznik 		name_fmt = "%s:%s";
18514545ee0aSSimon Wood 	} else if (sc->quirks & NAVIGATION_CONTROLLER) {
18521adf904eSPavel Machek 		static const u8 navigation_leds[4] = {0x01, 0x00, 0x00, 0x00};
18534545ee0aSSimon Wood 
18544545ee0aSSimon Wood 		memcpy(sc->led_state, navigation_leds, sizeof(navigation_leds));
18554545ee0aSSimon Wood 		sc->led_count = 1;
18564545ee0aSSimon Wood 		memset(use_hw_blink, 1, 4);
18574545ee0aSSimon Wood 		use_ds4_names = 0;
18584545ee0aSSimon Wood 		name_len = strlen("::sony#");
18594545ee0aSSimon Wood 		name_fmt = "%s::sony%d";
186060781cf4SFrank Praznik 	} else {
1861221399b3SFrank Praznik 		sixaxis_set_leds_from_id(sc);
1862fa57a810SFrank Praznik 		sc->led_count = 4;
1863b3ed458cSFrank Praznik 		memset(use_hw_blink, 1, 4);
1864b3ed458cSFrank Praznik 		use_ds4_names = 0;
186561ebca93SFrank Praznik 		name_len = strlen("::sony#");
186661ebca93SFrank Praznik 		name_fmt = "%s::sony%d";
186760781cf4SFrank Praznik 	}
186860781cf4SFrank Praznik 
1869ad142b9eSFrank Praznik 	/*
1870ad142b9eSFrank Praznik 	 * Clear LEDs as we have no way of reading their initial state. This is
1871f04d5140SColin Leitner 	 * only relevant if the driver is loaded after somebody actively set the
1872ad142b9eSFrank Praznik 	 * LEDs to on
1873ad142b9eSFrank Praznik 	 */
1874221399b3SFrank Praznik 	sony_set_leds(sc);
1875f04d5140SColin Leitner 
18760a286ef2SSven Eckelmann 	name_sz = strlen(dev_name(&hdev->dev)) + name_len + 1;
1877f04d5140SColin Leitner 
1878fa57a810SFrank Praznik 	for (n = 0; n < sc->led_count; n++) {
187961ebca93SFrank Praznik 
1880b3ed458cSFrank Praznik 		if (use_ds4_names)
1881b3ed458cSFrank Praznik 			name_sz = strlen(dev_name(&hdev->dev)) + strlen(ds4_name_str[n]) + 2;
188261ebca93SFrank Praznik 
1883f04d5140SColin Leitner 		led = kzalloc(sizeof(struct led_classdev) + name_sz, GFP_KERNEL);
1884f04d5140SColin Leitner 		if (!led) {
1885f04d5140SColin Leitner 			hid_err(hdev, "Couldn't allocate memory for LED %d\n", n);
18868cd5fcdaSJulia Lawall 			ret = -ENOMEM;
1887f04d5140SColin Leitner 			goto error_leds;
1888f04d5140SColin Leitner 		}
1889f04d5140SColin Leitner 
1890f04d5140SColin Leitner 		name = (void *)(&led[1]);
1891b3ed458cSFrank Praznik 		if (use_ds4_names)
1892b3ed458cSFrank Praznik 			snprintf(name, name_sz, name_fmt, dev_name(&hdev->dev),
1893b3ed458cSFrank Praznik 			ds4_name_str[n]);
189461ebca93SFrank Praznik 		else
18950a286ef2SSven Eckelmann 			snprintf(name, name_sz, name_fmt, dev_name(&hdev->dev), n + 1);
1896f04d5140SColin Leitner 		led->name = name;
1897221399b3SFrank Praznik 		led->brightness = sc->led_state[n];
1898b3ed458cSFrank Praznik 		led->max_brightness = max_brightness[n];
1899765a1077SFrank Praznik 		led->flags = LED_CORE_SUSPENDRESUME;
1900c5382519SSven Eckelmann 		led->brightness_get = sony_led_get_brightness;
1901c5382519SSven Eckelmann 		led->brightness_set = sony_led_set_brightness;
1902f04d5140SColin Leitner 
1903b3ed458cSFrank Praznik 		if (use_hw_blink[n])
1904b3ed458cSFrank Praznik 			led->blink_set = sony_led_blink_set;
1905b3ed458cSFrank Praznik 
19068025087aSFrank Praznik 		sc->leds[n] = led;
19078025087aSFrank Praznik 
19088cd5fcdaSJulia Lawall 		ret = led_classdev_register(&hdev->dev, led);
19098cd5fcdaSJulia Lawall 		if (ret) {
1910f04d5140SColin Leitner 			hid_err(hdev, "Failed to register LED %d\n", n);
19118025087aSFrank Praznik 			sc->leds[n] = NULL;
1912f04d5140SColin Leitner 			kfree(led);
1913f04d5140SColin Leitner 			goto error_leds;
1914f04d5140SColin Leitner 		}
1915f04d5140SColin Leitner 	}
1916f04d5140SColin Leitner 
1917f04d5140SColin Leitner 	return ret;
1918f04d5140SColin Leitner 
1919f04d5140SColin Leitner error_leds:
1920fa57a810SFrank Praznik 	sony_leds_remove(sc);
1921f04d5140SColin Leitner 
1922f04d5140SColin Leitner 	return ret;
1923f04d5140SColin Leitner }
1924f04d5140SColin Leitner 
1925d8aaccdaSFrank Praznik static void sixaxis_send_output_report(struct sony_sc *sc)
1926a08c22c0SSven Eckelmann {
19279b2b5c9aSFrank Praznik 	static const union sixaxis_output_report_01 default_report = {
192855d3b664SFrank Praznik 		.buf = {
1929a08c22c0SSven Eckelmann 			0x01,
1930ad07b7a6SScott Moreau 			0x01, 0xff, 0x00, 0xff, 0x00,
19310a286ef2SSven Eckelmann 			0x00, 0x00, 0x00, 0x00, 0x00,
1932a08c22c0SSven Eckelmann 			0xff, 0x27, 0x10, 0x00, 0x32,
1933a08c22c0SSven Eckelmann 			0xff, 0x27, 0x10, 0x00, 0x32,
1934a08c22c0SSven Eckelmann 			0xff, 0x27, 0x10, 0x00, 0x32,
1935a08c22c0SSven Eckelmann 			0xff, 0x27, 0x10, 0x00, 0x32,
1936a08c22c0SSven Eckelmann 			0x00, 0x00, 0x00, 0x00, 0x00
193755d3b664SFrank Praznik 		}
1938a08c22c0SSven Eckelmann 	};
19399b2b5c9aSFrank Praznik 	struct sixaxis_output_report *report =
19409b2b5c9aSFrank Praznik 		(struct sixaxis_output_report *)sc->output_report_dmabuf;
19419b2b5c9aSFrank Praznik 	int n;
19429b2b5c9aSFrank Praznik 
19439b2b5c9aSFrank Praznik 	/* Initialize the report with default values */
19449b2b5c9aSFrank Praznik 	memcpy(report, &default_report, sizeof(struct sixaxis_output_report));
19459f323b68SSven Eckelmann 
19460a286ef2SSven Eckelmann #ifdef CONFIG_SONY_FF
19479b2b5c9aSFrank Praznik 	report->rumble.right_motor_on = sc->right ? 1 : 0;
19489b2b5c9aSFrank Praznik 	report->rumble.left_motor_force = sc->left;
19490a286ef2SSven Eckelmann #endif
19500a286ef2SSven Eckelmann 
19519b2b5c9aSFrank Praznik 	report->leds_bitmap |= sc->led_state[0] << 1;
19529b2b5c9aSFrank Praznik 	report->leds_bitmap |= sc->led_state[1] << 2;
19539b2b5c9aSFrank Praznik 	report->leds_bitmap |= sc->led_state[2] << 3;
19549b2b5c9aSFrank Praznik 	report->leds_bitmap |= sc->led_state[3] << 4;
19559f323b68SSven Eckelmann 
195688f6576fSSimon Wood 	/* Set flag for all leds off, required for 3rd party INTEC controller */
19579b2b5c9aSFrank Praznik 	if ((report->leds_bitmap & 0x1E) == 0)
19589b2b5c9aSFrank Praznik 		report->leds_bitmap |= 0x20;
195988f6576fSSimon Wood 
1960b3ed458cSFrank Praznik 	/*
1961b3ed458cSFrank Praznik 	 * The LEDs in the report are indexed in reverse order to their
1962b3ed458cSFrank Praznik 	 * corresponding light on the controller.
1963b3ed458cSFrank Praznik 	 * Index 0 = LED 4, index 1 = LED 3, etc...
1964b3ed458cSFrank Praznik 	 *
1965b3ed458cSFrank Praznik 	 * In the case of both delay values being zero (blinking disabled) the
1966b3ed458cSFrank Praznik 	 * default report values should be used or the controller LED will be
1967b3ed458cSFrank Praznik 	 * always off.
1968b3ed458cSFrank Praznik 	 */
1969b3ed458cSFrank Praznik 	for (n = 0; n < 4; n++) {
1970b3ed458cSFrank Praznik 		if (sc->led_delay_on[n] || sc->led_delay_off[n]) {
19719b2b5c9aSFrank Praznik 			report->led[3 - n].duty_off = sc->led_delay_off[n];
19729b2b5c9aSFrank Praznik 			report->led[3 - n].duty_on = sc->led_delay_on[n];
1973b3ed458cSFrank Praznik 		}
1974b3ed458cSFrank Praznik 	}
1975b3ed458cSFrank Praznik 
19761adf904eSPavel Machek 	hid_hw_raw_request(sc->hdev, report->report_id, (u8 *)report,
19779b2b5c9aSFrank Praznik 			sizeof(struct sixaxis_output_report),
19789b2b5c9aSFrank Praznik 			HID_OUTPUT_REPORT, HID_REQ_SET_REPORT);
19799f323b68SSven Eckelmann }
19809f323b68SSven Eckelmann 
1981d8aaccdaSFrank Praznik static void dualshock4_send_output_report(struct sony_sc *sc)
19820bd88dd3SFrank Praznik {
19830da8ea65SFrank Praznik 	struct hid_device *hdev = sc->hdev;
19841adf904eSPavel Machek 	u8 *buf = sc->output_report_dmabuf;
198548220237SFrank Praznik 	int offset;
19860da8ea65SFrank Praznik 
1987c4425c8fSFrank Praznik 	/*
1988c4425c8fSFrank Praznik 	 * NOTE: The buf[1] field of the Bluetooth report controls
1989c4425c8fSFrank Praznik 	 * the Dualshock 4 reporting rate.
1990c4425c8fSFrank Praznik 	 *
1991c4425c8fSFrank Praznik 	 * Known values include:
1992c4425c8fSFrank Praznik 	 *
1993c4425c8fSFrank Praznik 	 * 0x80 - 1000hz (full speed)
1994c4425c8fSFrank Praznik 	 * 0xA0 - 31hz
1995c4425c8fSFrank Praznik 	 * 0xB0 - 20hz
1996c4425c8fSFrank Praznik 	 * 0xD0 - 66hz
1997c4425c8fSFrank Praznik 	 */
199835f436c3SRoderick Colenbrander 	if (sc->quirks & (DUALSHOCK4_CONTROLLER_USB | DUALSHOCK4_DONGLE)) {
19992c159de0SRoderick Colenbrander 		memset(buf, 0, DS4_OUTPUT_REPORT_0x05_SIZE);
200048220237SFrank Praznik 		buf[0] = 0x05;
2001b3ed458cSFrank Praznik 		buf[1] = 0xFF;
200248220237SFrank Praznik 		offset = 4;
2003fdcf105dSFrank Praznik 	} else {
20042c159de0SRoderick Colenbrander 		memset(buf, 0, DS4_OUTPUT_REPORT_0x11_SIZE);
2005fdcf105dSFrank Praznik 		buf[0] = 0x11;
2006e7ef53adSRoderick Colenbrander 		buf[1] = 0xC0; /* HID + CRC */
2007fdcf105dSFrank Praznik 		buf[3] = 0x0F;
2008fdcf105dSFrank Praznik 		offset = 6;
2009fdcf105dSFrank Praznik 	}
20100bd88dd3SFrank Praznik 
20110bd88dd3SFrank Praznik #ifdef CONFIG_SONY_FF
201248220237SFrank Praznik 	buf[offset++] = sc->right;
201348220237SFrank Praznik 	buf[offset++] = sc->left;
201448220237SFrank Praznik #else
201548220237SFrank Praznik 	offset += 2;
20160bd88dd3SFrank Praznik #endif
20170bd88dd3SFrank Praznik 
2018b3ed458cSFrank Praznik 	/* LED 3 is the global control */
2019b3ed458cSFrank Praznik 	if (sc->led_state[3]) {
202048220237SFrank Praznik 		buf[offset++] = sc->led_state[0];
202148220237SFrank Praznik 		buf[offset++] = sc->led_state[1];
202248220237SFrank Praznik 		buf[offset++] = sc->led_state[2];
2023b3ed458cSFrank Praznik 	} else {
2024b3ed458cSFrank Praznik 		offset += 3;
2025b3ed458cSFrank Praznik 	}
2026b3ed458cSFrank Praznik 
2027b3ed458cSFrank Praznik 	/* If both delay values are zero the DualShock 4 disables blinking. */
2028b3ed458cSFrank Praznik 	buf[offset++] = sc->led_delay_on[3];
2029b3ed458cSFrank Praznik 	buf[offset++] = sc->led_delay_off[3];
203060781cf4SFrank Praznik 
203135f436c3SRoderick Colenbrander 	if (sc->quirks & (DUALSHOCK4_CONTROLLER_USB | DUALSHOCK4_DONGLE))
20322c159de0SRoderick Colenbrander 		hid_hw_output_report(hdev, buf, DS4_OUTPUT_REPORT_0x05_SIZE);
2033e7ef53adSRoderick Colenbrander 	else {
2034e7ef53adSRoderick Colenbrander 		/* CRC generation */
2035e7ef53adSRoderick Colenbrander 		u8 bthdr = 0xA2;
2036e7ef53adSRoderick Colenbrander 		u32 crc;
2037e7ef53adSRoderick Colenbrander 
2038e7ef53adSRoderick Colenbrander 		crc = crc32_le(0xFFFFFFFF, &bthdr, 1);
2039e7ef53adSRoderick Colenbrander 		crc = ~crc32_le(crc, buf, DS4_OUTPUT_REPORT_0x11_SIZE-4);
2040e7ef53adSRoderick Colenbrander 		put_unaligned_le32(crc, &buf[74]);
2041e7ef53adSRoderick Colenbrander 		hid_hw_output_report(hdev, buf, DS4_OUTPUT_REPORT_0x11_SIZE);
2042e7ef53adSRoderick Colenbrander 	}
20430bd88dd3SFrank Praznik }
20440bd88dd3SFrank Praznik 
2045d8aaccdaSFrank Praznik static void motion_send_output_report(struct sony_sc *sc)
2046c5e0c1c4SFrank Praznik {
2047c5e0c1c4SFrank Praznik 	struct hid_device *hdev = sc->hdev;
2048c5e0c1c4SFrank Praznik 	struct motion_output_report_02 *report =
2049c5e0c1c4SFrank Praznik 		(struct motion_output_report_02 *)sc->output_report_dmabuf;
2050c5e0c1c4SFrank Praznik 
205141d2d425SSimon Wood 	memset(report, 0, MOTION_REPORT_0x02_SIZE);
2052c5e0c1c4SFrank Praznik 
2053c5e0c1c4SFrank Praznik 	report->type = 0x02; /* set leds */
2054c5e0c1c4SFrank Praznik 	report->r = sc->led_state[0];
2055c5e0c1c4SFrank Praznik 	report->g = sc->led_state[1];
2056c5e0c1c4SFrank Praznik 	report->b = sc->led_state[2];
2057c5e0c1c4SFrank Praznik 
2058c5e0c1c4SFrank Praznik #ifdef CONFIG_SONY_FF
2059c5e0c1c4SFrank Praznik 	report->rumble = max(sc->right, sc->left);
2060c5e0c1c4SFrank Praznik #endif
2061c5e0c1c4SFrank Praznik 
20621adf904eSPavel Machek 	hid_hw_output_report(hdev, (u8 *)report, MOTION_REPORT_0x02_SIZE);
2063c5e0c1c4SFrank Praznik }
2064c5e0c1c4SFrank Praznik 
2065decd946cSFrank Praznik static inline void sony_send_output_report(struct sony_sc *sc)
2066decd946cSFrank Praznik {
2067decd946cSFrank Praznik 	if (sc->send_output_report)
2068decd946cSFrank Praznik 		sc->send_output_report(sc);
2069decd946cSFrank Praznik }
2070decd946cSFrank Praznik 
2071d8aaccdaSFrank Praznik static void sony_state_worker(struct work_struct *work)
2072d8aaccdaSFrank Praznik {
2073d8aaccdaSFrank Praznik 	struct sony_sc *sc = container_of(work, struct sony_sc, state_worker);
2074ef916ef5SAntonio Ospite 
2075d8aaccdaSFrank Praznik 	sc->send_output_report(sc);
2076d8aaccdaSFrank Praznik }
2077d8aaccdaSFrank Praznik 
20789b2b5c9aSFrank Praznik static int sony_allocate_output_report(struct sony_sc *sc)
20799b2b5c9aSFrank Praznik {
20804545ee0aSSimon Wood 	if ((sc->quirks & SIXAXIS_CONTROLLER) ||
20814545ee0aSSimon Wood 			(sc->quirks & NAVIGATION_CONTROLLER))
20829b2b5c9aSFrank Praznik 		sc->output_report_dmabuf =
20839b2b5c9aSFrank Praznik 			kmalloc(sizeof(union sixaxis_output_report_01),
20849b2b5c9aSFrank Praznik 				GFP_KERNEL);
20859b2b5c9aSFrank Praznik 	else if (sc->quirks & DUALSHOCK4_CONTROLLER_BT)
20862c159de0SRoderick Colenbrander 		sc->output_report_dmabuf = kmalloc(DS4_OUTPUT_REPORT_0x11_SIZE,
20879b2b5c9aSFrank Praznik 						GFP_KERNEL);
208835f436c3SRoderick Colenbrander 	else if (sc->quirks & (DUALSHOCK4_CONTROLLER_USB | DUALSHOCK4_DONGLE))
20892c159de0SRoderick Colenbrander 		sc->output_report_dmabuf = kmalloc(DS4_OUTPUT_REPORT_0x05_SIZE,
20909b2b5c9aSFrank Praznik 						GFP_KERNEL);
2091c5e0c1c4SFrank Praznik 	else if (sc->quirks & MOTION_CONTROLLER)
209241d2d425SSimon Wood 		sc->output_report_dmabuf = kmalloc(MOTION_REPORT_0x02_SIZE,
2093c5e0c1c4SFrank Praznik 						GFP_KERNEL);
20949b2b5c9aSFrank Praznik 	else
20959b2b5c9aSFrank Praznik 		return 0;
20969b2b5c9aSFrank Praznik 
20979b2b5c9aSFrank Praznik 	if (!sc->output_report_dmabuf)
20989b2b5c9aSFrank Praznik 		return -ENOMEM;
20999b2b5c9aSFrank Praznik 
21009b2b5c9aSFrank Praznik 	return 0;
21019b2b5c9aSFrank Praznik }
21029b2b5c9aSFrank Praznik 
21030a286ef2SSven Eckelmann #ifdef CONFIG_SONY_FF
21049f323b68SSven Eckelmann static int sony_play_effect(struct input_dev *dev, void *data,
21059f323b68SSven Eckelmann 			    struct ff_effect *effect)
21069f323b68SSven Eckelmann {
2107a08c22c0SSven Eckelmann 	struct hid_device *hid = input_get_drvdata(dev);
21089f323b68SSven Eckelmann 	struct sony_sc *sc = hid_get_drvdata(hid);
2109a08c22c0SSven Eckelmann 
2110a08c22c0SSven Eckelmann 	if (effect->type != FF_RUMBLE)
2111a08c22c0SSven Eckelmann 		return 0;
2112a08c22c0SSven Eckelmann 
21139f323b68SSven Eckelmann 	sc->left = effect->u.rumble.strong_magnitude / 256;
21140bd88dd3SFrank Praznik 	sc->right = effect->u.rumble.weak_magnitude / 256;
2115a08c22c0SSven Eckelmann 
2116b5322736SRoderick Colenbrander 	sony_schedule_work(sc, SONY_WORKER_STATE);
21179f323b68SSven Eckelmann 	return 0;
2118a08c22c0SSven Eckelmann }
2119a08c22c0SSven Eckelmann 
2120fa57a810SFrank Praznik static int sony_init_ff(struct sony_sc *sc)
2121a08c22c0SSven Eckelmann {
2122fa57a810SFrank Praznik 	struct hid_input *hidinput = list_entry(sc->hdev->inputs.next,
2123a08c22c0SSven Eckelmann 						struct hid_input, list);
2124a08c22c0SSven Eckelmann 	struct input_dev *input_dev = hidinput->input;
2125a08c22c0SSven Eckelmann 
2126a08c22c0SSven Eckelmann 	input_set_capability(input_dev, EV_FF, FF_RUMBLE);
2127a08c22c0SSven Eckelmann 	return input_ff_create_memless(input_dev, NULL, sony_play_effect);
2128a08c22c0SSven Eckelmann }
2129a08c22c0SSven Eckelmann 
2130a08c22c0SSven Eckelmann #else
2131fa57a810SFrank Praznik static int sony_init_ff(struct sony_sc *sc)
2132a08c22c0SSven Eckelmann {
2133a08c22c0SSven Eckelmann 	return 0;
2134a08c22c0SSven Eckelmann }
21359f323b68SSven Eckelmann 
2136a08c22c0SSven Eckelmann #endif
2137a08c22c0SSven Eckelmann 
2138d902f472SFrank Praznik static int sony_battery_get_property(struct power_supply *psy,
2139d902f472SFrank Praznik 				     enum power_supply_property psp,
2140d902f472SFrank Praznik 				     union power_supply_propval *val)
2141c4e1ddf2SFrank Praznik {
2142297d716fSKrzysztof Kozlowski 	struct sony_sc *sc = power_supply_get_drvdata(psy);
2143d902f472SFrank Praznik 	unsigned long flags;
2144d902f472SFrank Praznik 	int ret = 0;
2145d902f472SFrank Praznik 	u8 battery_charging, battery_capacity, cable_state;
2146c4e1ddf2SFrank Praznik 
2147d902f472SFrank Praznik 	spin_lock_irqsave(&sc->lock, flags);
2148d902f472SFrank Praznik 	battery_charging = sc->battery_charging;
2149d902f472SFrank Praznik 	battery_capacity = sc->battery_capacity;
2150d902f472SFrank Praznik 	cable_state = sc->cable_state;
2151d902f472SFrank Praznik 	spin_unlock_irqrestore(&sc->lock, flags);
2152c4e1ddf2SFrank Praznik 
2153d902f472SFrank Praznik 	switch (psp) {
2154d902f472SFrank Praznik 	case POWER_SUPPLY_PROP_PRESENT:
2155d902f472SFrank Praznik 		val->intval = 1;
2156d902f472SFrank Praznik 		break;
2157d902f472SFrank Praznik 	case POWER_SUPPLY_PROP_SCOPE:
2158d902f472SFrank Praznik 		val->intval = POWER_SUPPLY_SCOPE_DEVICE;
2159d902f472SFrank Praznik 		break;
2160d902f472SFrank Praznik 	case POWER_SUPPLY_PROP_CAPACITY:
2161d902f472SFrank Praznik 		val->intval = battery_capacity;
2162d902f472SFrank Praznik 		break;
2163d902f472SFrank Praznik 	case POWER_SUPPLY_PROP_STATUS:
2164d902f472SFrank Praznik 		if (battery_charging)
2165d902f472SFrank Praznik 			val->intval = POWER_SUPPLY_STATUS_CHARGING;
2166d902f472SFrank Praznik 		else
2167d902f472SFrank Praznik 			if (battery_capacity == 100 && cable_state)
2168d902f472SFrank Praznik 				val->intval = POWER_SUPPLY_STATUS_FULL;
2169d902f472SFrank Praznik 			else
2170d902f472SFrank Praznik 				val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
2171d902f472SFrank Praznik 		break;
2172d902f472SFrank Praznik 	default:
2173d902f472SFrank Praznik 		ret = -EINVAL;
2174d902f472SFrank Praznik 		break;
2175c4e1ddf2SFrank Praznik 	}
2176d902f472SFrank Praznik 	return ret;
2177d902f472SFrank Praznik }
2178d902f472SFrank Praznik 
21790f398230SFrank Praznik static int sony_battery_probe(struct sony_sc *sc, int append_dev_id)
2180d902f472SFrank Praznik {
21810f398230SFrank Praznik 	const char *battery_str_fmt = append_dev_id ?
21820f398230SFrank Praznik 		"sony_controller_battery_%pMR_%i" :
21830f398230SFrank Praznik 		"sony_controller_battery_%pMR";
2184297d716fSKrzysztof Kozlowski 	struct power_supply_config psy_cfg = { .drv_data = sc, };
2185d902f472SFrank Praznik 	struct hid_device *hdev = sc->hdev;
2186d902f472SFrank Praznik 	int ret;
2187d902f472SFrank Praznik 
2188ad142b9eSFrank Praznik 	/*
2189ad142b9eSFrank Praznik 	 * Set the default battery level to 100% to avoid low battery warnings
2190d9a293a9SFrank Praznik 	 * if the battery is polled before the first device report is received.
2191d9a293a9SFrank Praznik 	 */
2192d9a293a9SFrank Praznik 	sc->battery_capacity = 100;
2193d9a293a9SFrank Praznik 
2194297d716fSKrzysztof Kozlowski 	sc->battery_desc.properties = sony_battery_props;
2195297d716fSKrzysztof Kozlowski 	sc->battery_desc.num_properties = ARRAY_SIZE(sony_battery_props);
2196297d716fSKrzysztof Kozlowski 	sc->battery_desc.get_property = sony_battery_get_property;
2197297d716fSKrzysztof Kozlowski 	sc->battery_desc.type = POWER_SUPPLY_TYPE_BATTERY;
2198297d716fSKrzysztof Kozlowski 	sc->battery_desc.use_for_apm = 0;
21990f398230SFrank Praznik 	sc->battery_desc.name = kasprintf(GFP_KERNEL, battery_str_fmt,
22000f398230SFrank Praznik 					  sc->mac_address, sc->device_id);
2201297d716fSKrzysztof Kozlowski 	if (!sc->battery_desc.name)
2202d902f472SFrank Praznik 		return -ENOMEM;
2203d902f472SFrank Praznik 
2204297d716fSKrzysztof Kozlowski 	sc->battery = power_supply_register(&hdev->dev, &sc->battery_desc,
2205297d716fSKrzysztof Kozlowski 					    &psy_cfg);
2206297d716fSKrzysztof Kozlowski 	if (IS_ERR(sc->battery)) {
2207297d716fSKrzysztof Kozlowski 		ret = PTR_ERR(sc->battery);
2208d902f472SFrank Praznik 		hid_err(hdev, "Unable to register battery device\n");
2209d902f472SFrank Praznik 		goto err_free;
2210d902f472SFrank Praznik 	}
2211d902f472SFrank Praznik 
2212297d716fSKrzysztof Kozlowski 	power_supply_powers(sc->battery, &hdev->dev);
2213d902f472SFrank Praznik 	return 0;
2214d902f472SFrank Praznik 
2215d902f472SFrank Praznik err_free:
2216297d716fSKrzysztof Kozlowski 	kfree(sc->battery_desc.name);
2217297d716fSKrzysztof Kozlowski 	sc->battery_desc.name = NULL;
2218d902f472SFrank Praznik 	return ret;
2219d902f472SFrank Praznik }
2220d902f472SFrank Praznik 
2221d902f472SFrank Praznik static void sony_battery_remove(struct sony_sc *sc)
2222d902f472SFrank Praznik {
2223297d716fSKrzysztof Kozlowski 	if (!sc->battery_desc.name)
2224d902f472SFrank Praznik 		return;
2225d902f472SFrank Praznik 
2226297d716fSKrzysztof Kozlowski 	power_supply_unregister(sc->battery);
2227297d716fSKrzysztof Kozlowski 	kfree(sc->battery_desc.name);
2228297d716fSKrzysztof Kozlowski 	sc->battery_desc.name = NULL;
2229d902f472SFrank Praznik }
2230d902f472SFrank Praznik 
2231d2d782fcSFrank Praznik /*
2232d2d782fcSFrank Praznik  * If a controller is plugged in via USB while already connected via Bluetooth
2233d2d782fcSFrank Praznik  * it will show up as two devices. A global list of connected controllers and
2234d2d782fcSFrank Praznik  * their MAC addresses is maintained to ensure that a device is only connected
2235d2d782fcSFrank Praznik  * once.
22360f398230SFrank Praznik  *
22370f398230SFrank Praznik  * Some USB-only devices masquerade as Sixaxis controllers and all have the
22380f398230SFrank Praznik  * same dummy Bluetooth address, so a comparison of the connection type is
22390f398230SFrank Praznik  * required.  Devices are only rejected in the case where two devices have
22400f398230SFrank Praznik  * matching Bluetooth addresses on different bus types.
2241d2d782fcSFrank Praznik  */
22420f398230SFrank Praznik static inline int sony_compare_connection_type(struct sony_sc *sc0,
22430f398230SFrank Praznik 						struct sony_sc *sc1)
22440f398230SFrank Praznik {
22450f398230SFrank Praznik 	const int sc0_not_bt = !(sc0->quirks & SONY_BT_DEVICE);
22460f398230SFrank Praznik 	const int sc1_not_bt = !(sc1->quirks & SONY_BT_DEVICE);
22470f398230SFrank Praznik 
22480f398230SFrank Praznik 	return sc0_not_bt == sc1_not_bt;
22490f398230SFrank Praznik }
22500f398230SFrank Praznik 
2251d2d782fcSFrank Praznik static int sony_check_add_dev_list(struct sony_sc *sc)
2252d2d782fcSFrank Praznik {
2253d2d782fcSFrank Praznik 	struct sony_sc *entry;
2254d2d782fcSFrank Praznik 	unsigned long flags;
2255d2d782fcSFrank Praznik 	int ret;
2256d2d782fcSFrank Praznik 
2257d2d782fcSFrank Praznik 	spin_lock_irqsave(&sony_dev_list_lock, flags);
2258d2d782fcSFrank Praznik 
2259d2d782fcSFrank Praznik 	list_for_each_entry(entry, &sony_device_list, list_node) {
2260d2d782fcSFrank Praznik 		ret = memcmp(sc->mac_address, entry->mac_address,
2261d2d782fcSFrank Praznik 				sizeof(sc->mac_address));
2262d2d782fcSFrank Praznik 		if (!ret) {
22630f398230SFrank Praznik 			if (sony_compare_connection_type(sc, entry)) {
22640f398230SFrank Praznik 				ret = 1;
22650f398230SFrank Praznik 			} else {
2266d2d782fcSFrank Praznik 				ret = -EEXIST;
22670f398230SFrank Praznik 				hid_info(sc->hdev,
22680f398230SFrank Praznik 				"controller with MAC address %pMR already connected\n",
2269d2d782fcSFrank Praznik 				sc->mac_address);
22700f398230SFrank Praznik 			}
2271d2d782fcSFrank Praznik 			goto unlock;
2272d2d782fcSFrank Praznik 		}
2273c4e1ddf2SFrank Praznik 	}
2274c4e1ddf2SFrank Praznik 
2275d2d782fcSFrank Praznik 	ret = 0;
2276d2d782fcSFrank Praznik 	list_add(&(sc->list_node), &sony_device_list);
2277c4e1ddf2SFrank Praznik 
2278d2d782fcSFrank Praznik unlock:
2279d2d782fcSFrank Praznik 	spin_unlock_irqrestore(&sony_dev_list_lock, flags);
2280d2d782fcSFrank Praznik 	return ret;
2281d2d782fcSFrank Praznik }
2282d2d782fcSFrank Praznik 
2283d2d782fcSFrank Praznik static void sony_remove_dev_list(struct sony_sc *sc)
2284d2d782fcSFrank Praznik {
2285d2d782fcSFrank Praznik 	unsigned long flags;
2286d2d782fcSFrank Praznik 
2287d2d782fcSFrank Praznik 	if (sc->list_node.next) {
2288d2d782fcSFrank Praznik 		spin_lock_irqsave(&sony_dev_list_lock, flags);
2289d2d782fcSFrank Praznik 		list_del(&(sc->list_node));
2290d2d782fcSFrank Praznik 		spin_unlock_irqrestore(&sony_dev_list_lock, flags);
2291d2d782fcSFrank Praznik 	}
2292d2d782fcSFrank Praznik }
2293d2d782fcSFrank Praznik 
2294d2d782fcSFrank Praznik static int sony_get_bt_devaddr(struct sony_sc *sc)
2295d2d782fcSFrank Praznik {
2296d2d782fcSFrank Praznik 	int ret;
2297d2d782fcSFrank Praznik 
2298d2d782fcSFrank Praznik 	/* HIDP stores the device MAC address as a string in the uniq field. */
2299d2d782fcSFrank Praznik 	ret = strlen(sc->hdev->uniq);
2300d2d782fcSFrank Praznik 	if (ret != 17)
2301c4e1ddf2SFrank Praznik 		return -EINVAL;
2302d2d782fcSFrank Praznik 
2303d2d782fcSFrank Praznik 	ret = sscanf(sc->hdev->uniq,
2304d2d782fcSFrank Praznik 		"%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
2305d2d782fcSFrank Praznik 		&sc->mac_address[5], &sc->mac_address[4], &sc->mac_address[3],
2306d2d782fcSFrank Praznik 		&sc->mac_address[2], &sc->mac_address[1], &sc->mac_address[0]);
2307d2d782fcSFrank Praznik 
2308d2d782fcSFrank Praznik 	if (ret != 6)
2309d2d782fcSFrank Praznik 		return -EINVAL;
2310d2d782fcSFrank Praznik 
2311d2d782fcSFrank Praznik 	return 0;
2312c4e1ddf2SFrank Praznik }
2313c4e1ddf2SFrank Praznik 
2314d2d782fcSFrank Praznik static int sony_check_add(struct sony_sc *sc)
2315d2d782fcSFrank Praznik {
23161adf904eSPavel Machek 	u8 *buf = NULL;
2317d2d782fcSFrank Praznik 	int n, ret;
2318d2d782fcSFrank Praznik 
2319d2d782fcSFrank Praznik 	if ((sc->quirks & DUALSHOCK4_CONTROLLER_BT) ||
232012e9a6d7SSimon Wood 	    (sc->quirks & MOTION_CONTROLLER_BT) ||
23214545ee0aSSimon Wood 	    (sc->quirks & NAVIGATION_CONTROLLER_BT) ||
2322d2d782fcSFrank Praznik 	    (sc->quirks & SIXAXIS_CONTROLLER_BT)) {
2323d2d782fcSFrank Praznik 		/*
2324d2d782fcSFrank Praznik 		 * sony_get_bt_devaddr() attempts to parse the Bluetooth MAC
2325d2d782fcSFrank Praznik 		 * address from the uniq string where HIDP stores it.
2326d2d782fcSFrank Praznik 		 * As uniq cannot be guaranteed to be a MAC address in all cases
2327d2d782fcSFrank Praznik 		 * a failure of this function should not prevent the connection.
2328d2d782fcSFrank Praznik 		 */
2329d2d782fcSFrank Praznik 		if (sony_get_bt_devaddr(sc) < 0) {
2330d2d782fcSFrank Praznik 			hid_warn(sc->hdev, "UNIQ does not contain a MAC address; duplicate check skipped\n");
2331d2d782fcSFrank Praznik 			return 0;
2332d2d782fcSFrank Praznik 		}
233335f436c3SRoderick Colenbrander 	} else if (sc->quirks & (DUALSHOCK4_CONTROLLER_USB | DUALSHOCK4_DONGLE)) {
23342c159de0SRoderick Colenbrander 		buf = kmalloc(DS4_FEATURE_REPORT_0x81_SIZE, GFP_KERNEL);
23359b2b5c9aSFrank Praznik 		if (!buf)
23369b2b5c9aSFrank Praznik 			return -ENOMEM;
2337d2d782fcSFrank Praznik 
2338d2d782fcSFrank Praznik 		/*
2339d2d782fcSFrank Praznik 		 * The MAC address of a DS4 controller connected via USB can be
2340d2d782fcSFrank Praznik 		 * retrieved with feature report 0x81. The address begins at
2341d2d782fcSFrank Praznik 		 * offset 1.
2342d2d782fcSFrank Praznik 		 */
23439b2b5c9aSFrank Praznik 		ret = hid_hw_raw_request(sc->hdev, 0x81, buf,
23442c159de0SRoderick Colenbrander 				DS4_FEATURE_REPORT_0x81_SIZE, HID_FEATURE_REPORT,
23459b2b5c9aSFrank Praznik 				HID_REQ_GET_REPORT);
2346d2d782fcSFrank Praznik 
23472c159de0SRoderick Colenbrander 		if (ret != DS4_FEATURE_REPORT_0x81_SIZE) {
2348d2d782fcSFrank Praznik 			hid_err(sc->hdev, "failed to retrieve feature report 0x81 with the DualShock 4 MAC address\n");
23499b2b5c9aSFrank Praznik 			ret = ret < 0 ? ret : -EINVAL;
23509b2b5c9aSFrank Praznik 			goto out_free;
2351d2d782fcSFrank Praznik 		}
2352d2d782fcSFrank Praznik 
2353d2d782fcSFrank Praznik 		memcpy(sc->mac_address, &buf[1], sizeof(sc->mac_address));
2354c70d5f70SRoderick Colenbrander 
2355c70d5f70SRoderick Colenbrander 		snprintf(sc->hdev->uniq, sizeof(sc->hdev->uniq),
2356c70d5f70SRoderick Colenbrander 			"%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
2357c70d5f70SRoderick Colenbrander 			sc->mac_address[5], sc->mac_address[4],
2358c70d5f70SRoderick Colenbrander 			sc->mac_address[3], sc->mac_address[2],
2359c70d5f70SRoderick Colenbrander 			sc->mac_address[1], sc->mac_address[0]);
23604545ee0aSSimon Wood 	} else if ((sc->quirks & SIXAXIS_CONTROLLER_USB) ||
23614545ee0aSSimon Wood 			(sc->quirks & NAVIGATION_CONTROLLER_USB)) {
23629b2b5c9aSFrank Praznik 		buf = kmalloc(SIXAXIS_REPORT_0xF2_SIZE, GFP_KERNEL);
23639b2b5c9aSFrank Praznik 		if (!buf)
23649b2b5c9aSFrank Praznik 			return -ENOMEM;
2365d2d782fcSFrank Praznik 
2366d2d782fcSFrank Praznik 		/*
2367d2d782fcSFrank Praznik 		 * The MAC address of a Sixaxis controller connected via USB can
2368d2d782fcSFrank Praznik 		 * be retrieved with feature report 0xf2. The address begins at
2369d2d782fcSFrank Praznik 		 * offset 4.
2370d2d782fcSFrank Praznik 		 */
23719b2b5c9aSFrank Praznik 		ret = hid_hw_raw_request(sc->hdev, 0xf2, buf,
23729b2b5c9aSFrank Praznik 				SIXAXIS_REPORT_0xF2_SIZE, HID_FEATURE_REPORT,
23739b2b5c9aSFrank Praznik 				HID_REQ_GET_REPORT);
2374d2d782fcSFrank Praznik 
23759b2b5c9aSFrank Praznik 		if (ret != SIXAXIS_REPORT_0xF2_SIZE) {
2376d2d782fcSFrank Praznik 			hid_err(sc->hdev, "failed to retrieve feature report 0xf2 with the Sixaxis MAC address\n");
23779b2b5c9aSFrank Praznik 			ret = ret < 0 ? ret : -EINVAL;
23789b2b5c9aSFrank Praznik 			goto out_free;
2379d2d782fcSFrank Praznik 		}
2380d2d782fcSFrank Praznik 
2381d2d782fcSFrank Praznik 		/*
2382d2d782fcSFrank Praznik 		 * The Sixaxis device MAC in the report is big-endian and must
2383d2d782fcSFrank Praznik 		 * be byte-swapped.
2384d2d782fcSFrank Praznik 		 */
2385d2d782fcSFrank Praznik 		for (n = 0; n < 6; n++)
2386d2d782fcSFrank Praznik 			sc->mac_address[5-n] = buf[4+n];
23875a144be3SRoderick Colenbrander 
23885a144be3SRoderick Colenbrander 		snprintf(sc->hdev->uniq, sizeof(sc->hdev->uniq),
23895a144be3SRoderick Colenbrander 			"%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
23905a144be3SRoderick Colenbrander 			sc->mac_address[5], sc->mac_address[4],
23915a144be3SRoderick Colenbrander 			sc->mac_address[3], sc->mac_address[2],
23925a144be3SRoderick Colenbrander 			sc->mac_address[1], sc->mac_address[0]);
2393d2d782fcSFrank Praznik 	} else {
2394d2d782fcSFrank Praznik 		return 0;
2395d2d782fcSFrank Praznik 	}
2396d2d782fcSFrank Praznik 
23979b2b5c9aSFrank Praznik 	ret = sony_check_add_dev_list(sc);
23989b2b5c9aSFrank Praznik 
23999b2b5c9aSFrank Praznik out_free:
24009b2b5c9aSFrank Praznik 
24019b2b5c9aSFrank Praznik 	kfree(buf);
24029b2b5c9aSFrank Praznik 
24039b2b5c9aSFrank Praznik 	return ret;
2404d2d782fcSFrank Praznik }
2405d2d782fcSFrank Praznik 
24068025087aSFrank Praznik static int sony_set_device_id(struct sony_sc *sc)
24078025087aSFrank Praznik {
24088025087aSFrank Praznik 	int ret;
24098025087aSFrank Praznik 
24108025087aSFrank Praznik 	/*
24118025087aSFrank Praznik 	 * Only DualShock 4 or Sixaxis controllers get an id.
24128025087aSFrank Praznik 	 * All others are set to -1.
24138025087aSFrank Praznik 	 */
24148025087aSFrank Praznik 	if ((sc->quirks & SIXAXIS_CONTROLLER) ||
24158025087aSFrank Praznik 	    (sc->quirks & DUALSHOCK4_CONTROLLER)) {
24168025087aSFrank Praznik 		ret = ida_simple_get(&sony_device_id_allocator, 0, 0,
24178025087aSFrank Praznik 					GFP_KERNEL);
24188025087aSFrank Praznik 		if (ret < 0) {
24198025087aSFrank Praznik 			sc->device_id = -1;
24208025087aSFrank Praznik 			return ret;
24218025087aSFrank Praznik 		}
24228025087aSFrank Praznik 		sc->device_id = ret;
24238025087aSFrank Praznik 	} else {
24248025087aSFrank Praznik 		sc->device_id = -1;
24258025087aSFrank Praznik 	}
24268025087aSFrank Praznik 
24278025087aSFrank Praznik 	return 0;
24288025087aSFrank Praznik }
24298025087aSFrank Praznik 
24308025087aSFrank Praznik static void sony_release_device_id(struct sony_sc *sc)
24318025087aSFrank Praznik {
24328025087aSFrank Praznik 	if (sc->device_id >= 0) {
24338025087aSFrank Praznik 		ida_simple_remove(&sony_device_id_allocator, sc->device_id);
24348025087aSFrank Praznik 		sc->device_id = -1;
24358025087aSFrank Praznik 	}
24368025087aSFrank Praznik }
24378025087aSFrank Praznik 
2438d8aaccdaSFrank Praznik static inline void sony_init_output_report(struct sony_sc *sc,
2439d8aaccdaSFrank Praznik 				void (*send_output_report)(struct sony_sc *))
244046262047SFrank Praznik {
2441d8aaccdaSFrank Praznik 	sc->send_output_report = send_output_report;
2442d8aaccdaSFrank Praznik 
2443b5322736SRoderick Colenbrander 	if (!sc->state_worker_initialized)
2444d8aaccdaSFrank Praznik 		INIT_WORK(&sc->state_worker, sony_state_worker);
244546262047SFrank Praznik 
2446b5322736SRoderick Colenbrander 	sc->state_worker_initialized = 1;
244746262047SFrank Praznik }
244846262047SFrank Praznik 
244946262047SFrank Praznik static inline void sony_cancel_work_sync(struct sony_sc *sc)
245046262047SFrank Praznik {
2451f2f47c38SRoderick Colenbrander 	if (sc->hotplug_worker_initialized)
2452f2f47c38SRoderick Colenbrander 		cancel_work_sync(&sc->hotplug_worker);
2453b5322736SRoderick Colenbrander 	if (sc->state_worker_initialized)
245446262047SFrank Praznik 		cancel_work_sync(&sc->state_worker);
245546262047SFrank Praznik }
2456d2d782fcSFrank Praznik 
2457e1bc84d0SRoderick Colenbrander static int sony_input_configured(struct hid_device *hdev,
2458e1bc84d0SRoderick Colenbrander 					struct hid_input *hidinput)
2459bd28ce00SJiri Slaby {
2460e1bc84d0SRoderick Colenbrander 	struct sony_sc *sc = hid_get_drvdata(hdev);
24610f398230SFrank Praznik 	int append_dev_id;
2462e1bc84d0SRoderick Colenbrander 	int ret;
2463bd28ce00SJiri Slaby 
24648025087aSFrank Praznik 	ret = sony_set_device_id(sc);
24658025087aSFrank Praznik 	if (ret < 0) {
24668025087aSFrank Praznik 		hid_err(hdev, "failed to allocate the device id\n");
24678025087aSFrank Praznik 		goto err_stop;
24688025087aSFrank Praznik 	}
24698025087aSFrank Praznik 
2470df848bc0SRoderick Colenbrander 	ret = append_dev_id = sony_check_add(sc);
2471df848bc0SRoderick Colenbrander 	if (ret < 0)
2472df848bc0SRoderick Colenbrander 		goto err_stop;
2473df848bc0SRoderick Colenbrander 
2474131a8a9aSFrank Praznik 	ret = sony_allocate_output_report(sc);
2475131a8a9aSFrank Praznik 	if (ret < 0) {
2476131a8a9aSFrank Praznik 		hid_err(hdev, "failed to allocate the output report buffer\n");
2477131a8a9aSFrank Praznik 		goto err_stop;
2478131a8a9aSFrank Praznik 	}
2479131a8a9aSFrank Praznik 
2480510c8b7cSRoderick Colenbrander 	if (sc->quirks & NAVIGATION_CONTROLLER_USB) {
2481e534a935SBenjamin Tissoires 		/*
2482e534a935SBenjamin Tissoires 		 * The Sony Sixaxis does not handle HID Output Reports on the
2483e534a935SBenjamin Tissoires 		 * Interrupt EP like it could, so we need to force HID Output
2484e534a935SBenjamin Tissoires 		 * Reports to use HID_REQ_SET_REPORT on the Control EP.
2485e534a935SBenjamin Tissoires 		 *
2486e534a935SBenjamin Tissoires 		 * There is also another issue about HID Output Reports via USB,
2487e534a935SBenjamin Tissoires 		 * the Sixaxis does not want the report_id as part of the data
2488e534a935SBenjamin Tissoires 		 * packet, so we have to discard buf[0] when sending the actual
2489e534a935SBenjamin Tissoires 		 * control message, even for numbered reports, humpf!
24902a242932SFrank Praznik 		 *
24912a242932SFrank Praznik 		 * Additionally, the Sixaxis on USB isn't properly initialized
24922a242932SFrank Praznik 		 * until the PS logo button is pressed and as such won't retain
24932a242932SFrank Praznik 		 * any state set by an output report, so the initial
24942a242932SFrank Praznik 		 * configuration report is deferred until the first input
24952a242932SFrank Praznik 		 * report arrives.
2496e534a935SBenjamin Tissoires 		 */
2497e534a935SBenjamin Tissoires 		hdev->quirks |= HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP;
2498e534a935SBenjamin Tissoires 		hdev->quirks |= HID_QUIRK_SKIP_OUTPUT_REPORT_ID;
24992a242932SFrank Praznik 		sc->defer_initialization = 1;
250080ecc48cSRoderick Colenbrander 
2501816651a7SAntonio Ospite 		ret = sixaxis_set_operational_usb(hdev);
250280ecc48cSRoderick Colenbrander 		if (ret < 0) {
250380ecc48cSRoderick Colenbrander 			hid_err(hdev, "Failed to set controller into operational mode\n");
250480ecc48cSRoderick Colenbrander 			goto err_stop;
250580ecc48cSRoderick Colenbrander 		}
250680ecc48cSRoderick Colenbrander 
2507d8aaccdaSFrank Praznik 		sony_init_output_report(sc, sixaxis_send_output_report);
2508510c8b7cSRoderick Colenbrander 	} else if (sc->quirks & NAVIGATION_CONTROLLER_BT) {
2509510c8b7cSRoderick Colenbrander 		/*
2510510c8b7cSRoderick Colenbrander 		 * The Navigation controller wants output reports sent on the ctrl
2511510c8b7cSRoderick Colenbrander 		 * endpoint when connected via Bluetooth.
2512510c8b7cSRoderick Colenbrander 		 */
2513510c8b7cSRoderick Colenbrander 		hdev->quirks |= HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP;
2514510c8b7cSRoderick Colenbrander 
2515510c8b7cSRoderick Colenbrander 		ret = sixaxis_set_operational_bt(hdev);
2516510c8b7cSRoderick Colenbrander 		if (ret < 0) {
2517510c8b7cSRoderick Colenbrander 			hid_err(hdev, "Failed to set controller into operational mode\n");
2518510c8b7cSRoderick Colenbrander 			goto err_stop;
2519510c8b7cSRoderick Colenbrander 		}
2520510c8b7cSRoderick Colenbrander 
2521510c8b7cSRoderick Colenbrander 		sony_init_output_report(sc, sixaxis_send_output_report);
2522510c8b7cSRoderick Colenbrander 	} else if (sc->quirks & SIXAXIS_CONTROLLER_USB) {
2523510c8b7cSRoderick Colenbrander 		/*
2524510c8b7cSRoderick Colenbrander 		 * The Sony Sixaxis does not handle HID Output Reports on the
2525510c8b7cSRoderick Colenbrander 		 * Interrupt EP and the device only becomes active when the
2526510c8b7cSRoderick Colenbrander 		 * PS button is pressed. See comment for Navigation controller
2527510c8b7cSRoderick Colenbrander 		 * above for more details.
2528510c8b7cSRoderick Colenbrander 		 */
2529510c8b7cSRoderick Colenbrander 		hdev->quirks |= HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP;
2530510c8b7cSRoderick Colenbrander 		hdev->quirks |= HID_QUIRK_SKIP_OUTPUT_REPORT_ID;
2531510c8b7cSRoderick Colenbrander 		sc->defer_initialization = 1;
2532510c8b7cSRoderick Colenbrander 
2533510c8b7cSRoderick Colenbrander 		ret = sixaxis_set_operational_usb(hdev);
2534510c8b7cSRoderick Colenbrander 		if (ret < 0) {
2535510c8b7cSRoderick Colenbrander 			hid_err(hdev, "Failed to set controller into operational mode\n");
2536510c8b7cSRoderick Colenbrander 			goto err_stop;
2537510c8b7cSRoderick Colenbrander 		}
2538510c8b7cSRoderick Colenbrander 
2539510c8b7cSRoderick Colenbrander 		ret = sony_register_sensors(sc);
2540510c8b7cSRoderick Colenbrander 		if (ret) {
2541510c8b7cSRoderick Colenbrander 			hid_err(sc->hdev,
2542510c8b7cSRoderick Colenbrander 			"Unable to initialize motion sensors: %d\n", ret);
2543510c8b7cSRoderick Colenbrander 			goto err_stop;
2544510c8b7cSRoderick Colenbrander 		}
2545510c8b7cSRoderick Colenbrander 
2546510c8b7cSRoderick Colenbrander 		sony_init_output_report(sc, sixaxis_send_output_report);
2547510c8b7cSRoderick Colenbrander 	} else if (sc->quirks & SIXAXIS_CONTROLLER_BT) {
25482078b9bbSFrank Praznik 		/*
25492078b9bbSFrank Praznik 		 * The Sixaxis wants output reports sent on the ctrl endpoint
25502078b9bbSFrank Praznik 		 * when connected via Bluetooth.
25512078b9bbSFrank Praznik 		 */
25522078b9bbSFrank Praznik 		hdev->quirks |= HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP;
255380ecc48cSRoderick Colenbrander 
2554816651a7SAntonio Ospite 		ret = sixaxis_set_operational_bt(hdev);
255580ecc48cSRoderick Colenbrander 		if (ret < 0) {
255680ecc48cSRoderick Colenbrander 			hid_err(hdev, "Failed to set controller into operational mode\n");
255780ecc48cSRoderick Colenbrander 			goto err_stop;
255880ecc48cSRoderick Colenbrander 		}
255980ecc48cSRoderick Colenbrander 
2560510c8b7cSRoderick Colenbrander 		ret = sony_register_sensors(sc);
2561510c8b7cSRoderick Colenbrander 		if (ret) {
2562510c8b7cSRoderick Colenbrander 			hid_err(sc->hdev,
2563510c8b7cSRoderick Colenbrander 			"Unable to initialize motion sensors: %d\n", ret);
2564510c8b7cSRoderick Colenbrander 			goto err_stop;
2565510c8b7cSRoderick Colenbrander 		}
2566510c8b7cSRoderick Colenbrander 
2567d8aaccdaSFrank Praznik 		sony_init_output_report(sc, sixaxis_send_output_report);
2568fee4e2d5SFrank Praznik 	} else if (sc->quirks & DUALSHOCK4_CONTROLLER) {
256955a07d62SRoderick Colenbrander 		ret = dualshock4_get_calibration_data(sc);
257068330d83SFrank Praznik 		if (ret < 0) {
257155a07d62SRoderick Colenbrander 			hid_err(hdev, "Failed to get calibration data from Dualshock 4\n");
257268330d83SFrank Praznik 			goto err_stop;
257368330d83SFrank Praznik 		}
2574c4e1ddf2SFrank Praznik 
2575e1bc84d0SRoderick Colenbrander 		/*
2576e1bc84d0SRoderick Colenbrander 		 * The Dualshock 4 touchpad supports 2 touches and has a
2577e1bc84d0SRoderick Colenbrander 		 * resolution of 1920x942 (44.86 dots/mm).
2578e1bc84d0SRoderick Colenbrander 		 */
2579ac797b95SRoderick Colenbrander 		ret = sony_register_touchpad(sc, 2, 1920, 942);
2580e1bc84d0SRoderick Colenbrander 		if (ret) {
2581e1bc84d0SRoderick Colenbrander 			hid_err(sc->hdev,
2582e1bc84d0SRoderick Colenbrander 			"Unable to initialize multi-touch slots: %d\n",
2583e1bc84d0SRoderick Colenbrander 			ret);
25842b6579d4SRoderick Colenbrander 			goto err_stop;
2585e1bc84d0SRoderick Colenbrander 		}
2586e1bc84d0SRoderick Colenbrander 
2587227c011bSRoderick Colenbrander 		ret = sony_register_sensors(sc);
2588227c011bSRoderick Colenbrander 		if (ret) {
2589227c011bSRoderick Colenbrander 			hid_err(sc->hdev,
2590227c011bSRoderick Colenbrander 			"Unable to initialize motion sensors: %d\n", ret);
2591227c011bSRoderick Colenbrander 			goto err_stop;
2592227c011bSRoderick Colenbrander 		}
2593227c011bSRoderick Colenbrander 
2594f2f47c38SRoderick Colenbrander 		if (sc->quirks & DUALSHOCK4_DONGLE) {
2595f2f47c38SRoderick Colenbrander 			INIT_WORK(&sc->hotplug_worker, dualshock4_calibration_work);
2596f2f47c38SRoderick Colenbrander 			sc->hotplug_worker_initialized = 1;
2597f2f47c38SRoderick Colenbrander 			sc->ds4_dongle_state = DONGLE_DISCONNECTED;
2598f2f47c38SRoderick Colenbrander 		}
2599f2f47c38SRoderick Colenbrander 
2600d8aaccdaSFrank Praznik 		sony_init_output_report(sc, dualshock4_send_output_report);
2601c5e0c1c4SFrank Praznik 	} else if (sc->quirks & MOTION_CONTROLLER) {
2602d8aaccdaSFrank Praznik 		sony_init_output_report(sc, motion_send_output_report);
26030bd88dd3SFrank Praznik 	} else {
26040bd88dd3SFrank Praznik 		ret = 0;
26050bd88dd3SFrank Praznik 	}
2606f9ce7c28SBastien Nocera 
26074dfdc464SJiri Kosina 	if (ret < 0)
2608bd28ce00SJiri Slaby 		goto err_stop;
2609bd28ce00SJiri Slaby 
26100a286ef2SSven Eckelmann 	if (sc->quirks & SONY_LED_SUPPORT) {
2611fa57a810SFrank Praznik 		ret = sony_leds_init(sc);
26120a286ef2SSven Eckelmann 		if (ret < 0)
26130a286ef2SSven Eckelmann 			goto err_stop;
26140a286ef2SSven Eckelmann 	}
26150a286ef2SSven Eckelmann 
2616d902f472SFrank Praznik 	if (sc->quirks & SONY_BATTERY_SUPPORT) {
26170f398230SFrank Praznik 		ret = sony_battery_probe(sc, append_dev_id);
2618a08c22c0SSven Eckelmann 		if (ret < 0)
2619a08c22c0SSven Eckelmann 			goto err_stop;
2620a08c22c0SSven Eckelmann 
2621d902f472SFrank Praznik 		/* Open the device to receive reports with battery info */
2622d902f472SFrank Praznik 		ret = hid_hw_open(hdev);
2623d902f472SFrank Praznik 		if (ret < 0) {
2624d902f472SFrank Praznik 			hid_err(hdev, "hw open failed\n");
2625d902f472SFrank Praznik 			goto err_stop;
2626d902f472SFrank Praznik 		}
2627d902f472SFrank Praznik 	}
2628d902f472SFrank Praznik 
2629c8de9dbbSFrank Praznik 	if (sc->quirks & SONY_FF_SUPPORT) {
2630fa57a810SFrank Praznik 		ret = sony_init_ff(sc);
2631d902f472SFrank Praznik 		if (ret < 0)
2632d902f472SFrank Praznik 			goto err_close;
26335f5750d2SFrank Praznik 	}
2634bd28ce00SJiri Slaby 
2635f425458eSH Hartley Sweeten 	return 0;
2636d902f472SFrank Praznik err_close:
2637d902f472SFrank Praznik 	hid_hw_close(hdev);
2638bd28ce00SJiri Slaby err_stop:
26390a286ef2SSven Eckelmann 	if (sc->quirks & SONY_LED_SUPPORT)
2640fa57a810SFrank Praznik 		sony_leds_remove(sc);
2641d902f472SFrank Praznik 	if (sc->quirks & SONY_BATTERY_SUPPORT)
2642d902f472SFrank Praznik 		sony_battery_remove(sc);
264346262047SFrank Praznik 	sony_cancel_work_sync(sc);
26449b2b5c9aSFrank Praznik 	kfree(sc->output_report_dmabuf);
2645d2d782fcSFrank Praznik 	sony_remove_dev_list(sc);
26468025087aSFrank Praznik 	sony_release_device_id(sc);
2647bd28ce00SJiri Slaby 	hid_hw_stop(hdev);
2648bd28ce00SJiri Slaby 	return ret;
2649bd28ce00SJiri Slaby }
2650bd28ce00SJiri Slaby 
2651e1bc84d0SRoderick Colenbrander static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
2652e1bc84d0SRoderick Colenbrander {
2653e1bc84d0SRoderick Colenbrander 	int ret;
2654e1bc84d0SRoderick Colenbrander 	unsigned long quirks = id->driver_data;
2655e1bc84d0SRoderick Colenbrander 	struct sony_sc *sc;
2656e1bc84d0SRoderick Colenbrander 	unsigned int connect_mask = HID_CONNECT_DEFAULT;
2657e1bc84d0SRoderick Colenbrander 
2658e1bc84d0SRoderick Colenbrander 	if (!strcmp(hdev->name, "FutureMax Dance Mat"))
2659e1bc84d0SRoderick Colenbrander 		quirks |= FUTUREMAX_DANCE_MAT;
2660e1bc84d0SRoderick Colenbrander 
2661e1bc84d0SRoderick Colenbrander 	sc = devm_kzalloc(&hdev->dev, sizeof(*sc), GFP_KERNEL);
2662e1bc84d0SRoderick Colenbrander 	if (sc == NULL) {
2663e1bc84d0SRoderick Colenbrander 		hid_err(hdev, "can't alloc sony descriptor\n");
2664e1bc84d0SRoderick Colenbrander 		return -ENOMEM;
2665e1bc84d0SRoderick Colenbrander 	}
2666e1bc84d0SRoderick Colenbrander 
2667e1bc84d0SRoderick Colenbrander 	spin_lock_init(&sc->lock);
2668e1bc84d0SRoderick Colenbrander 
2669e1bc84d0SRoderick Colenbrander 	sc->quirks = quirks;
2670e1bc84d0SRoderick Colenbrander 	hid_set_drvdata(hdev, sc);
2671e1bc84d0SRoderick Colenbrander 	sc->hdev = hdev;
2672e1bc84d0SRoderick Colenbrander 
2673e1bc84d0SRoderick Colenbrander 	ret = hid_parse(hdev);
2674e1bc84d0SRoderick Colenbrander 	if (ret) {
2675e1bc84d0SRoderick Colenbrander 		hid_err(hdev, "parse failed\n");
2676e1bc84d0SRoderick Colenbrander 		return ret;
2677e1bc84d0SRoderick Colenbrander 	}
2678e1bc84d0SRoderick Colenbrander 
2679e1bc84d0SRoderick Colenbrander 	if (sc->quirks & VAIO_RDESC_CONSTANT)
2680e1bc84d0SRoderick Colenbrander 		connect_mask |= HID_CONNECT_HIDDEV_FORCE;
2681e1bc84d0SRoderick Colenbrander 	else if (sc->quirks & SIXAXIS_CONTROLLER)
2682e1bc84d0SRoderick Colenbrander 		connect_mask |= HID_CONNECT_HIDDEV_FORCE;
2683e1bc84d0SRoderick Colenbrander 
2684e19a267bSRoderick Colenbrander 	/* Patch the hw version on DS3/4 compatible devices, so applications can
26859131f8ccSRoderick Colenbrander 	 * distinguish between the default HID mappings and the mappings defined
26869131f8ccSRoderick Colenbrander 	 * by the Linux game controller spec. This is important for the SDL2
26879131f8ccSRoderick Colenbrander 	 * library, which has a game controller database, which uses device ids
26889131f8ccSRoderick Colenbrander 	 * in combination with version as a key.
26899131f8ccSRoderick Colenbrander 	 */
2690e19a267bSRoderick Colenbrander 	if (sc->quirks & (SIXAXIS_CONTROLLER | DUALSHOCK4_CONTROLLER))
26919131f8ccSRoderick Colenbrander 		hdev->version |= 0x8000;
26929131f8ccSRoderick Colenbrander 
2693e1bc84d0SRoderick Colenbrander 	ret = hid_hw_start(hdev, connect_mask);
2694e1bc84d0SRoderick Colenbrander 	if (ret) {
2695e1bc84d0SRoderick Colenbrander 		hid_err(hdev, "hw start failed\n");
2696e1bc84d0SRoderick Colenbrander 		return ret;
2697e1bc84d0SRoderick Colenbrander 	}
2698e1bc84d0SRoderick Colenbrander 
26994f967f6dSRoderick Colenbrander 	/* sony_input_configured can fail, but this doesn't result
27004f967f6dSRoderick Colenbrander 	 * in hid_hw_start failures (intended). Check whether
27014f967f6dSRoderick Colenbrander 	 * the HID layer claimed the device else fail.
27024f967f6dSRoderick Colenbrander 	 * We don't know the actual reason for the failure, most
27034f967f6dSRoderick Colenbrander 	 * likely it is due to EEXIST in case of double connection
27044f967f6dSRoderick Colenbrander 	 * of USB and Bluetooth, but could have been due to ENOMEM
27054f967f6dSRoderick Colenbrander 	 * or other reasons as well.
27064f967f6dSRoderick Colenbrander 	 */
27074f967f6dSRoderick Colenbrander 	if (!(hdev->claimed & HID_CLAIMED_INPUT)) {
27084f967f6dSRoderick Colenbrander 		hid_err(hdev, "failed to claim input\n");
27094f967f6dSRoderick Colenbrander 		return -ENODEV;
27104f967f6dSRoderick Colenbrander 	}
27114f967f6dSRoderick Colenbrander 
2712e1bc84d0SRoderick Colenbrander 	return ret;
2713e1bc84d0SRoderick Colenbrander }
2714e1bc84d0SRoderick Colenbrander 
2715bd28ce00SJiri Slaby static void sony_remove(struct hid_device *hdev)
2716bd28ce00SJiri Slaby {
2717bd28ce00SJiri Slaby 	struct sony_sc *sc = hid_get_drvdata(hdev);
2718bd28ce00SJiri Slaby 
2719ac797b95SRoderick Colenbrander 	hid_hw_close(hdev);
2720ac797b95SRoderick Colenbrander 
27210a286ef2SSven Eckelmann 	if (sc->quirks & SONY_LED_SUPPORT)
2722fa57a810SFrank Praznik 		sony_leds_remove(sc);
2723bd28ce00SJiri Slaby 
2724ac797b95SRoderick Colenbrander 	if (sc->quirks & SONY_BATTERY_SUPPORT)
2725d902f472SFrank Praznik 		sony_battery_remove(sc);
2726ac797b95SRoderick Colenbrander 
2727ac797b95SRoderick Colenbrander 	if (sc->touchpad)
2728ac797b95SRoderick Colenbrander 		sony_unregister_touchpad(sc);
2729d902f472SFrank Praznik 
2730227c011bSRoderick Colenbrander 	if (sc->sensor_dev)
2731227c011bSRoderick Colenbrander 		sony_unregister_sensors(sc);
2732227c011bSRoderick Colenbrander 
2733227c011bSRoderick Colenbrander 	if (sc->sensor_dev)
2734227c011bSRoderick Colenbrander 		sony_unregister_sensors(sc);
2735227c011bSRoderick Colenbrander 
273646262047SFrank Praznik 	sony_cancel_work_sync(sc);
27379f323b68SSven Eckelmann 
27389b2b5c9aSFrank Praznik 	kfree(sc->output_report_dmabuf);
27399b2b5c9aSFrank Praznik 
2740d2d782fcSFrank Praznik 	sony_remove_dev_list(sc);
2741bd28ce00SJiri Slaby 
27428025087aSFrank Praznik 	sony_release_device_id(sc);
27438025087aSFrank Praznik 
2744bd28ce00SJiri Slaby 	hid_hw_stop(hdev);
2745bd28ce00SJiri Slaby }
2746bd28ce00SJiri Slaby 
2747decd946cSFrank Praznik #ifdef CONFIG_PM
2748decd946cSFrank Praznik 
2749decd946cSFrank Praznik static int sony_suspend(struct hid_device *hdev, pm_message_t message)
2750decd946cSFrank Praznik {
2751765a1077SFrank Praznik #ifdef CONFIG_SONY_FF
2752765a1077SFrank Praznik 
2753765a1077SFrank Praznik 	/* On suspend stop any running force-feedback events */
2754765a1077SFrank Praznik 	if (SONY_FF_SUPPORT) {
2755decd946cSFrank Praznik 		struct sony_sc *sc = hid_get_drvdata(hdev);
2756decd946cSFrank Praznik 
2757decd946cSFrank Praznik 		sc->left = sc->right = 0;
2758decd946cSFrank Praznik 		sony_send_output_report(sc);
2759decd946cSFrank Praznik 	}
2760decd946cSFrank Praznik 
2761765a1077SFrank Praznik #endif
2762decd946cSFrank Praznik 	return 0;
2763decd946cSFrank Praznik }
2764decd946cSFrank Praznik 
2765decd946cSFrank Praznik static int sony_resume(struct hid_device *hdev)
2766decd946cSFrank Praznik {
2767decd946cSFrank Praznik 	struct sony_sc *sc = hid_get_drvdata(hdev);
2768decd946cSFrank Praznik 
2769decd946cSFrank Praznik 	/*
2770decd946cSFrank Praznik 	 * The Sixaxis and navigation controllers on USB need to be
2771decd946cSFrank Praznik 	 * reinitialized on resume or they won't behave properly.
2772decd946cSFrank Praznik 	 */
2773decd946cSFrank Praznik 	if ((sc->quirks & SIXAXIS_CONTROLLER_USB) ||
27742a242932SFrank Praznik 		(sc->quirks & NAVIGATION_CONTROLLER_USB)) {
2775decd946cSFrank Praznik 		sixaxis_set_operational_usb(sc->hdev);
27762a242932SFrank Praznik 		sc->defer_initialization = 1;
27772a242932SFrank Praznik 	}
2778decd946cSFrank Praznik 
2779decd946cSFrank Praznik 	return 0;
2780decd946cSFrank Praznik }
2781decd946cSFrank Praznik 
2782decd946cSFrank Praznik #endif
2783decd946cSFrank Praznik 
2784bd28ce00SJiri Slaby static const struct hid_device_id sony_devices[] = {
2785bd28ce00SJiri Slaby 	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER),
2786bd28ce00SJiri Slaby 		.driver_data = SIXAXIS_CONTROLLER_USB },
2787bd28ce00SJiri Slaby 	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER),
27884545ee0aSSimon Wood 		.driver_data = NAVIGATION_CONTROLLER_USB },
27896eabaaa0SSimon Wood 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER),
27904545ee0aSSimon Wood 		.driver_data = NAVIGATION_CONTROLLER_BT },
2791c5e0c1c4SFrank Praznik 	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_MOTION_CONTROLLER),
2792b3bca326SSimon Wood 		.driver_data = MOTION_CONTROLLER_USB },
2793a4afa854SSimon Wood 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_MOTION_CONTROLLER),
2794b3bca326SSimon Wood 		.driver_data = MOTION_CONTROLLER_BT },
2795bd28ce00SJiri Slaby 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER),
2796bd28ce00SJiri Slaby 		.driver_data = SIXAXIS_CONTROLLER_BT },
2797bd28ce00SJiri Slaby 	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE),
2798bd28ce00SJiri Slaby 		.driver_data = VAIO_RDESC_CONSTANT },
2799bd28ce00SJiri Slaby 	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGP_MOUSE),
2800bd28ce00SJiri Slaby 		.driver_data = VAIO_RDESC_CONSTANT },
2801ef916ef5SAntonio Ospite 	/*
2802ef916ef5SAntonio Ospite 	 * Wired Buzz Controller. Reported as Sony Hub from its USB ID and as
2803ef916ef5SAntonio Ospite 	 * Logitech joystick from the device descriptor.
2804ef916ef5SAntonio Ospite 	 */
2805bd28ce00SJiri Slaby 	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_BUZZ_CONTROLLER),
2806bd28ce00SJiri Slaby 		.driver_data = BUZZ_CONTROLLER },
2807bd28ce00SJiri Slaby 	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_WIRELESS_BUZZ_CONTROLLER),
2808bd28ce00SJiri Slaby 		.driver_data = BUZZ_CONTROLLER },
2809bd28ce00SJiri Slaby 	/* PS3 BD Remote Control */
2810bd28ce00SJiri Slaby 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_BDREMOTE),
2811bd28ce00SJiri Slaby 		.driver_data = PS3REMOTE },
2812bd28ce00SJiri Slaby 	/* Logitech Harmony Adapter for PS3 */
2813bd28ce00SJiri Slaby 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_PS3),
2814bd28ce00SJiri Slaby 		.driver_data = PS3REMOTE },
281568a49e51SFrank Praznik 	/* SMK-Link PS3 BD Remote Control */
281668a49e51SFrank Praznik 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SMK, USB_DEVICE_ID_SMK_PS3_BDREMOTE),
281768a49e51SFrank Praznik 		.driver_data = PS3REMOTE },
28180bd88dd3SFrank Praznik 	/* Sony Dualshock 4 controllers for PS4 */
28190bd88dd3SFrank Praznik 	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER),
28208ab1676bSFrank Praznik 		.driver_data = DUALSHOCK4_CONTROLLER_USB },
28210bd88dd3SFrank Praznik 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER),
28228ab1676bSFrank Praznik 		.driver_data = DUALSHOCK4_CONTROLLER_BT },
2823cf1015d6SRoderick Colenbrander 	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER_2),
2824cf1015d6SRoderick Colenbrander 		.driver_data = DUALSHOCK4_CONTROLLER_USB },
2825cf1015d6SRoderick Colenbrander 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER_2),
2826cf1015d6SRoderick Colenbrander 		.driver_data = DUALSHOCK4_CONTROLLER_BT },
2827de66a1a0SRoderick Colenbrander 	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER_DONGLE),
282835f436c3SRoderick Colenbrander 		.driver_data = DUALSHOCK4_DONGLE },
282974500cc8SScott Moreau 	/* Nyko Core Controller for PS3 */
283074500cc8SScott Moreau 	{ HID_USB_DEVICE(USB_VENDOR_ID_SINO_LITE, USB_DEVICE_ID_SINO_LITE_CONTROLLER),
283174500cc8SScott Moreau 		.driver_data = SIXAXIS_CONTROLLER_USB | SINO_LITE_CONTROLLER },
2832bd28ce00SJiri Slaby 	{ }
2833bd28ce00SJiri Slaby };
2834bd28ce00SJiri Slaby MODULE_DEVICE_TABLE(hid, sony_devices);
2835bd28ce00SJiri Slaby 
2836bd28ce00SJiri Slaby static struct hid_driver sony_driver = {
2837bd28ce00SJiri Slaby 	.name             = "sony",
2838bd28ce00SJiri Slaby 	.id_table         = sony_devices,
2839bd28ce00SJiri Slaby 	.input_mapping    = sony_mapping,
2840ce8efc3bSFrank Praznik 	.input_configured = sony_input_configured,
2841bd28ce00SJiri Slaby 	.probe            = sony_probe,
2842bd28ce00SJiri Slaby 	.remove           = sony_remove,
2843bd28ce00SJiri Slaby 	.report_fixup     = sony_report_fixup,
2844decd946cSFrank Praznik 	.raw_event        = sony_raw_event,
2845decd946cSFrank Praznik 
2846decd946cSFrank Praznik #ifdef CONFIG_PM
2847decd946cSFrank Praznik 	.suspend          = sony_suspend,
2848decd946cSFrank Praznik 	.resume	          = sony_resume,
2849decd946cSFrank Praznik 	.reset_resume     = sony_resume,
2850decd946cSFrank Praznik #endif
2851bd28ce00SJiri Slaby };
28528025087aSFrank Praznik 
28538025087aSFrank Praznik static int __init sony_init(void)
28548025087aSFrank Praznik {
28558025087aSFrank Praznik 	dbg_hid("Sony:%s\n", __func__);
28568025087aSFrank Praznik 
28578025087aSFrank Praznik 	return hid_register_driver(&sony_driver);
28588025087aSFrank Praznik }
28598025087aSFrank Praznik 
28608025087aSFrank Praznik static void __exit sony_exit(void)
28618025087aSFrank Praznik {
28628025087aSFrank Praznik 	dbg_hid("Sony:%s\n", __func__);
28638025087aSFrank Praznik 
28648025087aSFrank Praznik 	hid_unregister_driver(&sony_driver);
28656c40065fSAntonio Ospite 	ida_destroy(&sony_device_id_allocator);
28668025087aSFrank Praznik }
28678025087aSFrank Praznik module_init(sony_init);
28688025087aSFrank Praznik module_exit(sony_exit);
2869bd28ce00SJiri Slaby 
2870bd28ce00SJiri Slaby MODULE_LICENSE("GPL");
2871